pax_global_header00006660000000000000000000000064125761131450014517gustar00rootroot0000000000000052 comment=f9c98baa0a968451f4f8c78a74249c41e61d1966 nipype-0.11.0/000077500000000000000000000000001257611314500131025ustar00rootroot00000000000000nipype-0.11.0/.coveragerc000066400000000000000000000002251257611314500152220ustar00rootroot00000000000000[run] branch = True source = nipype include = */nipype/* omit = */nipype/external/* */nipype/workflows/* */nipype/fixes/* */setup.py nipype-0.11.0/.gitattributes000066400000000000000000000000441257611314500157730ustar00rootroot00000000000000nipype/COMMIT_INFO.txt export-subst nipype-0.11.0/.gitignore000066400000000000000000000004411257611314500150710ustar00rootroot00000000000000/build /dist /nipype.egg-info /MANIFEST /nipype/build /nipype/nipype.egg-info /doc/_build /doc/users/examples /doc/api/generated *.pyc *.so .project .settings .pydevproject .idea/ /documentation.zip .DS_Store nipype/testing/data/von-ray_errmap.nii.gz nipype/testing/data/von_errmap.nii.gz nipype-0.11.0/.mailmap000066400000000000000000000015751257611314500145330ustar00rootroot00000000000000Ariel Rokem arokem Cindee Madison cindeem <> Cindee Madison cindeem Chris Filo Gorgolewski filo Chris Filo Gorgolewski Krzysztof Gorgolewski Erik Ziegler erikz Michael Waskom mwaskom Michael Waskom mwaskom Gael Varoquaux GaelVaroquaux Gael Varoquaux GaelVaroquaux Daniel Ginsburg danginsburg Colin Buchanan colinbuchanan nipype-0.11.0/.travis.yml000066400000000000000000000036751257611314500152260ustar00rootroot00000000000000cache: - apt language: python python: - 2.7 env: - INSTALL_DEB_DEPENDECIES=true - INSTALL_DEB_DEPENDECIES=false before_install: - if [ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh; else wget http://repo.continuum.io/miniconda/Miniconda3-3.6.0-Linux-x86_64.sh -O miniconda.sh; fi - chmod +x miniconda.sh - "./miniconda.sh -b" - export PATH=/home/travis/miniconda/bin:$PATH - if $INSTALL_DEB_DEPENDECIES; then sudo rm -rf /dev/shm; fi - if $INSTALL_DEB_DEPENDECIES; then sudo ln -s /run/shm /dev/shm; fi - if $INSTALL_DEB_DEPENDECIES; then bash <(wget -q -O- http://neuro.debian.net/_files/neurodebian-travis.sh); fi - if $INSTALL_DEB_DEPENDECIES; then travis_retry sudo apt-get install -qq --no-install-recommends fsl afni elastix; fi - if $INSTALL_DEB_DEPENDECIES; then travis_retry sudo apt-get install -qq fsl-atlases; fi - if $INSTALL_DEB_DEPENDECIES; then source /etc/fsl/fsl.sh; fi install: - conda update --yes conda - conda create -n testenv --yes pip python=$TRAVIS_PYTHON_VERSION - source activate testenv - if [ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]; then pip install ordereddict; fi - conda install --yes numpy scipy nose traits networkx dateutil - pip install nibabel - pip install python-coveralls - pip install nose-cov - pip install https://github.com/RDFLib/rdflib/archive/master.zip - pip install https://github.com/trungdong/prov/archive/rdf.zip - python setup.py install script: - nosetests --with-doctest --with-cov --cov nipype --cov-config .coveragerc --logging-level=INFO after_success: - coveralls --config_file .coveragerc deploy: provider: pypi user: satra password: secure: OCO0FXb4f+pH4Uw7zWCIRp3qOJ1t7rhky4K8MjNU8tyVCJgd6O/Bv8GJgceS0LktPodlAAjB8SxAhTORPAQZ1D/44PJYy3NQIisvej1zjLpaA9TEGfl6W7MqhDpRyMHW+cnSi/n84SAmdr+Z4vOxScDHdwr13EPmGyOIlHMAGnE= on: tags: true repo: nipy/nipype branch: master distributions: "sdist bdist_wheel" nipype-0.11.0/CHANGES000066400000000000000000000623611257611314500141050ustar00rootroot00000000000000Release 0.11.0 (September 15, 2015) ============ * API: Change how hash values are computed (https://github.com/nipy/nipype/pull/1174) * ENH: New algorithm: mesh.WarpPoints applies displacements fields to point sets (https://github.com/nipy/nipype/pull/889). * ENH: New interfaces for MRTrix3 (https://github.com/nipy/nipype/pull/1126) * ENH: New option in afni.3dRefit - zdel, ydel, zdel etc. (https://github.com/nipy/nipype/pull/1079) * FIX: ants.Registration composite transform outputs are no longer returned as lists (https://github.com/nipy/nipype/pull/1183) * BUG: ANTs Registration interface failed with multi-modal inputs (https://github.com/nipy/nipype/pull/1176) (https://github.com/nipy/nipype/issues/1175) * ENH: dipy.TrackDensityMap interface now accepts a reference image (https://github.com/nipy/nipype/pull/1091) * FIX: Bug in XFibres5 (https://github.com/nipy/nipype/pull/1168) * ENH: Attempt to use hard links for data sink. (https://github.com/nipy/nipype/pull/1161) * FIX: Updates to SGE Plugins (https://github.com/nipy/nipype/pull/1129) * ENH: Add ants JointFusion() node with testing (https://github.com/nipy/nipype/pull/1160) * ENH: Add --float option for antsRegistration calls (https://github.com/nipy/nipype/pull/1159) * ENH: Added interface to simulate DWIs using the multi-tensor model (https://github.com/nipy/nipype/pull/1085) * ENH: New interface for FSL fslcpgeom utility (https://github.com/nipy/nipype/pull/1152) * ENH: Added SLURMGraph plugin for submitting jobs to SLURM with dependencies (https://github.com/nipy/nipype/pull/1136) * FIX: Enable absolute path definitions in DCMStack (https://github.com/nipy/nipype/pull/1089, replaced by https://github.com/nipy/nipype/pull/1093) * ENH: New mesh.MeshWarpMaths to operate on surface-defined warpings (https://github.com/nipy/nipype/pull/1016) * FIX: Refactor P2PDistance, change name to ComputeMeshWarp, add regression tests, fix bug in area weighted distance, and added optimizations (https://github.com/nipy/nipype/pull/1016) * ENH: Add an option not to resubmit Nodes that finished running when using SGEGraph (https://github.com/nipy/nipype/pull/1002) * FIX: FUGUE is now properly listing outputs. (https://github.com/nipy/nipype/pull/978) * ENH: Improved FieldMap-Based (FMB) workflow for correction of susceptibility distortions in EPI seqs. (https://github.com/nipy/nipype/pull/1019) * FIX: In the FSLXcommand _list_outputs function fixed for loop range (https://github.com/nipy/nipype/pull/1071) * ENH: Dropped support for now 7 years old Python 2.6 (https://github.com/nipy/nipype/pull/1069) * FIX: terminal_output is not mandatory anymore (https://github.com/nipy/nipype/pull/1070) * ENH: Added "nipype_cmd" tool for running interfaces from the command line (https://github.com/nipy/nipype/pull/795) * FIX: Fixed Camino output naming (https://github.com/nipy/nipype/pull/1061) * ENH: Add the average distance to ErrorMap (https://github.com/nipy/nipype/pull/1039) * ENH: Inputs with name_source can be now chained in cascade (https://github.com/nipy/nipype/pull/938) * ENH: Improve JSON interfaces: default settings when reading and consistent output creation when writing (https://github.com/nipy/nipype/pull/1047) * FIX: AddCSVRow problems when using infields (https://github.com/nipy/nipype/pull/1028) * FIX: Removed unused ANTS registration flag (https://github.com/nipy/nipype/pull/999) * FIX: Amend create_tbss_non_fa() workflow to match FSL's tbss_non_fa command. (https://github.com/nipy/nipype/pull/1033) * FIX: remove unused mandatory flag from spm normalize (https://github.com/nipy/nipype/pull/1048) * ENH: Update ANTSCorticalThickness interface (https://github.com/nipy/nipype/pull/1013) * FIX: Edge case with sparsemodels and PEP8 cleanup (https://github.com/nipy/nipype/pull/1046) * ENH: New io interfaces for JSON files reading/writing (https://github.com/nipy/nipype/pull/1020) * ENH: Enhanced openfmri script to support freesurfer linkage (https://github.com/nipy/nipype/pull/1037) * BUG: matplotlib is supposed to be optional (https://github.com/nipy/nipype/pull/1003) * FIX: Fix split_filename behaviour when path has no file component (https://github.com/nipy/nipype/pull/1035) * ENH: Updated FSL dtifit to include option for grad non-linearities (https://github.com/nipy/nipype/pull/1032) * ENH: Updated Camino tracking interfaces, which can now use FSL bedpostx output. New options also include choice of tracker, interpolator, stepsize and curveinterval for angle threshold (https://github.com/nipy/nipype/pull/1029) * FIX: Interfaces redirecting X crashed if $DISPLAY not defined (https://github.com/nipy/nipype/pull/1027) * FIX: Bug crashed 'make api' (https://github.com/nipy/nipype/pull/1026) * ENH: Updated antsIntroduction to handle RA and RI registrations (https://github.com/nipy/nipype/pull/1009) * ENH: Updated N4BiasCorrection input spec to include weight image and spline order. Made argument formatting consistent. Cleaned ants.segmentation according to PEP8. (https://github.com/nipy/nipype/pull/990/files) * ENH: SPM12 Normalize interface (https://github.com/nipy/nipype/pull/986) * FIX: Utility interface test dir (https://github.com/nipy/nipype/pull/986) * FIX: IPython engine directory reset after crash (https://github.com/nipy/nipype/pull/987) * ENH: Resting state fMRI example with NiPy realignment and no SPM (https://github.com/nipy/nipype/pull/992) * FIX: Corrected Freesurfer SegStats _list_outputs to avoid error if summary_file is undefined (issue #994)(https://https://github.com/nipy/nipype/pull/996) * FIX: OpenfMRI support and FSL 5.0.7 changes (https://github.com/nipy/nipype/pull/1006) * FIX: Output prefix in SPM Normalize with modulation (https://github.com/nipy/nipype/pull/1023) * ENH: Usability improvements in cluster environments (https://github.com/nipy/nipype/pull/1025) * ENH: ANTs JointFusion() (https://github.com/nipy/nipype/pull/1042) * ENH: Added csvReader() utility (https://github.com/nipy/nipype/pull/1044) * FIX: typo in nipype.interfaces.freesurfer.utils.py Tkregister2 (https://github.com/nipy/nipype/pull/1083) * FIX: SSHDataGrabber outputs now return full path to the grabbed/downloaded files. (https://github.com/nipy/nipype/pull/1086) * FIX: Add QA output for TSNR to resting workflow (https://github.com/nipy/nipype/pull/1088) * FIX: Change N4BiasFieldCorrection to use short tag for dimensionality (backward compatible) (https://github.com/nipy/nipype/pull/1096) * ENH: Added -newgrid input to Warp in AFNI (3dWarp wrapper) (https://github.com/nipy/nipype/pull/1128) * FIX: Fixed AFNI Copy interface to use positional inputs as required (https://github.com/nipy/nipype/pull/1131) * ENH: Added a check in Dcm2nii to check if nipype created the config.ini file and remove if true (https://github.com/nipy/nipype/pull/1132) * ENH: Use a while loop to wait for Xvfb (up to a max wait time "xvfb_max_wait" in config file, default 10) (https://github.com/nipy/nipype/pull/1142) Release 0.10.0 (October 10, 2014) ============ * ENH: New miscelaneous interfaces: SplitROIs (mapper), MergeROIs (reducer) to enable parallel processing of very large images. * ENH: Updated FSL interfaces: BEDPOSTX and XFibres, former interfaces are still available with the version suffix: BEDPOSTX4 and XFibres4. Added gpu versions of BEDPOSTX: BEDPOSTXGPU, BEDPOSTX5GPU, and BEDPOSTX4GPU * ENH: Added experimental support for MIPAV algorithms thorugh JIST plugins * ENH: New dipy interfaces: Denoise, Resample * ENH: New Freesurfer interfaces: Tkregister2 (for conversion of fsl style matrices to freesurfer format), MRIPretess * ENH: New FSL interfaces: WarpPoints, WarpPointsToStd, EpiReg, ProbTrackX2, WarpUtils, ConvertWarp * ENH: New miscelaneous interfaces: AddCSVRow, NormalizeProbabilityMapSet, AddNoise * ENH: New AFNI interfaces: Eval, Means, SVMTest, SVMTrain * ENH: FUGUE interface has been refactored to use the name_template system, 3 examples added to doctests, some bugs solved. * API: Interfaces to external packages are no longer available in the top-level ``nipype`` namespace, and must be imported directly (e.g. ``from nipype.interfaces import fsl``). * ENH: Support for elastix via a set of new interfaces: Registration, ApplyWarp, AnalyzeWarp, PointsWarp, and EditTransform * ENH: New ANTs interface: ApplyTransformsToPoints, LaplacianThickness * ENH: New Diffusion Toolkit interface: TrackMerge * ENH: New MRtrix interface: FilterTracks * ENH: New metrics group in algorithms. Now Distance, Overlap, and FuzzyOverlap are found in nipype.algorithms.metrics instead of misc. Overlap interface extended to allow files containing multiple ROIs and volume physical units. * ENH: New interface in algorithms.metrics: ErrorMap (a voxel-wise diff map). * ENH: New FreeSurfer workflow: create_skullstripped_recon_flow() * ENH: Deep revision of workflows for correction of dMRI artifacts. New dmri_preprocessing example. * ENH: New data grabbing interface that works over SSH connections, SSHDataGrabber * ENH: New color mode for write_graph * ENH: You can now force MapNodes to be run serially * ENH: Added ANTS based openfmri workflow * ENH: MapNode now supports flattening of nested lists * ENH: Support for headless mode using Xvfb * ENH: nipype_display_crash has a debugging mode * FIX: MRTrix tracking algorithms were ignoring mask parameters. * FIX: FNIRT registration pathway and associated OpenFMRI example script * FIX: spm12b compatibility for Model estimate * FIX: Batch scheduler controls the number of maximum jobs properly * FIX: Update for FSL 5.0.7 which deprecated Contrast Manager Release 0.9.2 (January 31, 2014) ============ * FIX: DataFinder was broken due to a typo * FIX: Order of DataFinder outputs was not guaranteed, it's human sorted now * ENH: New interfaces: Vnifti2Image, VtoMat Release 0.9.1 (December 25, 2013) ============ * FIX: installation issues Release 0.9.0 (December 20, 2013) ============ * ENH: SelectFiles: a streamlined version of DataGrabber * ENH: new tools for defining workflows: JoinNode, synchronize and itersource * ENH: W3C PROV support with optional RDF export built into Nipype * ENH: Added support for Simple Linux Utility Resource Management (SLURM) * ENH: AFNI interfaces refactor, prefix, suffix are replaced by "flexible_%s_templates" * ENH: New SPM interfaces: - spm.ResliceToReference, - spm.DicomImport * ENH: New AFNI interfaces: - afni.AFNItoNIFTI - afni.TCorr1D * ENH: Several new interfaces related to Camino were added: - camino.SFPICOCalibData - camino.Conmat - camino.QBallMX - camino.LinRecon - camino.SFPeaks One outdated interface no longer part of Camino was removed: - camino.Conmap * ENH: Three new mrtrix interfaces were added: - mrtrix.GenerateDirections - mrtrix.FindShPeaks - mrtrix.Directions2Amplitude * ENH: New FSL interfaces: - fsl.PrepareFieldmap - fsl.TOPUP - fsl.ApplyTOPUP - fsl.Eddy * ENH: New misc interfaces: - FuzzyOverlap, - P2PDistance * ENH: New workflows: nipype.workflows.dmri.fsl.epi.[fieldmap_correction&topup_correction] * ENH: Added simplified outputname generation for command line interfaces. * ENH: Allow ants use a single mask image * ENH: Create configuration option for parameterizing directories with hashes * ENH: arrange nodes by topological sort with disconnected subgraphs * ENH: uses the nidm iri namespace for uuids * ENH: remove old reporting webpage * ENH: Added support for Vagrant * API: 'name' is now a positional argument for Workflow, Node, and MapNode constructors * API: SPM now defaults to SPM8 or SPM12b job format * API: DataGrabber and SelectFiles use human (or natural) sort now * FIX: Several fixes related to Camino interfaces: - ProcStreamlines would ignore many arguments silently (target, waypoint, exclusion ROIS, etc.) - DTLUTGen would silently round the "step", "snr" and "trace" parameters to integers - PicoPDFs would not accept more than one lookup table - PicoPDFs default pdf did not correspond to Camino default - Track input model names were outdated (and would generate an error) - Track numpds parameter could not be set for deterministic tractography - FA created output files with erroneous extension * FIX: Deals properly with 3d files in SPM Realign * FIX: SPM with MCR fixed * FIX: Cleaned up input and output spec metadata * FIX: example openfmri script now makes the contrast spec a hashed input * FIX: FILMGLS compatibility with FSL 5.0.5 * FIX: Freesurfer recon-all resume now avoids setting inputs * FIX: File removal from node respects file associations img/hdr/mat, BRIK/HEAD Release 0.8.0 (May 8, 2013) =========================== * ENH: New interfaces: nipy.Trim, fsl.GLM, fsl.SigLoss, spm.VBMSegment, fsl.InvWarp, dipy.TensorMode * ENH: Allow control over terminal output for commandline interfaces * ENH: Added preliminary support for generating Python code from Workflows. * ENH: New workflows for dMRI and fMRI pre-processing: added motion artifact correction with rotation of the B-matrix, and susceptibility correction for EPI imaging using fieldmaps. Updated eddy_correct pipeline to support both dMRI and fMRI, and new parameters. * ENH: Minor improvements to FSL's FUGUE and FLIRT interfaces * ENH: Added optional dilation of parcels in cmtk.Parcellate * ENH: Interpolation mode added to afni.Resample * ENH: Function interface can accept a list of strings containing import statements that allow external functions to run without their imports defined in the function body * ENH: Allow node configurations to override master configuration * FIX: SpecifyModel works with 3D files correctly now. Release 0.7.0 (Dec 18, 2012) ============================ * ENH: Add basic support for LSF plugin. * ENH: New interfaces: ICC, Meshfix, ants.Register, C3dAffineTool, ants.JacobianDeterminant, afni.AutoTcorrelate, DcmStack * ENH: New workflows: ants template building (both using 'ANTS' and the new 'antsRegistration') * ENH: New examples: how to use ANTS template building workflows (smri_ants_build_tmeplate), how to set SGE specific options (smri_ants_build_template_new) * ENH: added no_flatten option to Merge * ENH: added versioning option and checking to traits * ENH: added deprecation metadata to traits * ENH: Slicer interfaces were updated to version 4.1 Release 0.6.0 (Jun 30, 2012) ============================ * API: display variable no longer encoded as inputs in commandline interfaces * ENH: input hash not modified when environment DISPLAY is changed * ENH: support for 3d files for TSNR calculation * ENH: Preliminary support for graph submission with SGE, PBS and Soma Workflow * ENH: New interfaces: MySQLSink, nipy.Similarity, WatershedBEM, MRIsSmooth, NetworkBasedStatistic, Atropos, N4BiasFieldCorrection, ApplyTransforms, fs.MakeAverageSubject, epidewarp.fsl, WarpTimeSeriesImageMultiTransform, AVScale, mri_ms_LDA * ENH: simple interfaces for spm * FIX: CompCor component calculation was erroneous * FIX: filename generation for AFNI and PRELUDE * FIX: improved slicer module autogeneration * FIX: added missing options for BBRegsiter * FIX: functionality of remove_unnecessary_ouputs cleaned up * FIX: local hash check works with appropriate inputs * FIX: Captures all stdout from commandline programs * FIX: Afni outputs should inherit from TraitedSpec Release 0.5.3 (Mar 23, 2012) ============================ * FIX: SPM model generation when output units is in scans Release 0.5.2 (Mar 14, 2012) ============================ * API: Node now allows specifying node level configuration for SGE/PBS clusters * API: Logging to file is disabled by default * API: New location of log file -> .nipype/nipype.cfg * ENH: Changing logging options via config works for distributed processing * FIX: Unittests on debian (logging and ipython) Release 0.5 (Mar 10, 2012) ========================== * API: FSL defaults to Nifti when OUTPUTTYPE environment variable not found * API: By default inputs are removed from Node working directory * API: InterfaceResult class is now versioned and stores class type not instance * API: Added FIRST interface * API: Added max_jobs paramter to plugin_args. limits the number of jobs executing at any given point in time * API: crashdump_dir is now a config execution option * API: new config execution options for controlling hash checking, execution and logging behavior when running in distributed mode. * API: Node/MapNode has new attribute that allows it to run on master thread. * API: IPython plugin now invokes IPython 0.11 or greater * API: Canned workflows are now all under a different package structure * API: SpecifyModel event_info renamed to event_files * API: DataGrabber is always being rerun (unless overwrite is set to False on Node level) * API: "stop_on_first_rerun" does not stop for DataGrabber (unless overwrite is set to True on Node level) * API: Output prefix can be set for spm nodes (SliceTiming, Realign, Coregister, Normalize, Smooth) * ENH: Added fsl resting state workflow based on behzadi 2007 CompCorr method. * ENH: TSNR node produces mean and std-dev maps; allows polynomial detrending * ENH: IdentityNodes are removed prior to execution * ENH: Added Michael Notter's beginner's guide * ENH: Added engine support for status callback functions * ENH: SPM create warped node * ENH: All underlying interfaces (including python ones) are now optional * ENH: Added imperative programming option with Nodes and caching * ENH: Added debug mode to configuration * ENH: Results can be stored and loaded without traits exceptions * ENH: Added concurrent log handler for distributed writing to log file * ENH: Reporting can be turned off using config * ENH: Added stats files to FreeSurferOutput * ENH: Support for Condor through qsub emulation * ENH: IdentityNode with iterable expansion takes place after remaining Identity Node removal * ENH: Crashfile display script added * ENH: Added FmriRealign4d node wrapped from nipy * ENH: Added TBSS workflows and examples * ENH: Support for openfmri data processing * ENH: Package version check * FIX: Fixed spm preproc workflow to cater to multiple functional runs * FIX: Workflow outputs displays nodes with empty outputs * FIX: SUSAN workflow works without usans * FIX: SGE fixed for reading custom templates * FIX: warping in SPM realign, Dartel and interpolation parameters * FIX: Fixed voxel size parameter in freesurfer mri_convert * FIX: 4D images in spm coregister * FIX: Works around matlab tty bug * FIX: Overwriting connection raises exception * FIX: Outputs are loaded from results and not stored in memory for during distributed operation * FIX: SPM threshold uses SPM.mat name and improved error detection * FIX: Removing directory contents works even when a node has no outputs * FIX: DARTEL workflows will run only when SPM 8 is available * FIX: SPM Normalize estimate field fixed * FIX: hashmethod argument now used for calculating hash of old file * FIX: Modelgen now allows FSL style event files Release 0.4.1 (Jun 16, 2011) ============================ * Minor bugfixes Release 0.4 (Jun 11, 2011) ========================== * API: Timestamp hashing does not use ctime anymore. Please update your hashes by running workflows with updatehash=True option NOTE: THIS IS THE DEFAULT CONFIG NOW, so unless you updatehash, workflows will rerun * API: Workflow run function no longer supports (inseries, createdirsonly). Functions used in connect string must be pickleable * API: SPM EstimateContrast: ignore_derivs replaced by use_derivs * API: All interfaces: added new config option ignore_exception * API: SpecifModel no longer supports (concatenate_runs, output_specs). high_pass_filter cutoff is mandatory (even if its set to np.inf). Additional interfaces SpecifySPMModel and SpecifySparseModel support other types of data. * API: fsl.DTIFit input "save" is now called "save_tensor" * API: All inputs of IdentityInterfaces are mandatory by default. You can turn this off by specifying mandatory_inputs=False to the constructor. * API: fsl FILMGLS input "autocorr_estimate" is now called "autocorr_estimate_only" * API: fsl ContrastMgr now requires access to specific files (no longer accepts the result directory) * API: freesurfer.GLMFit input "surf" is now a boolean with three corresponding inputs -- subject_id, hemi, and surf_geo * ENH: All commandline interfaces display stdout and stderr * ENH: All interfaces raise exceptions on error with an option to suppress * ENH: Supports a plugin interface for execution (current support for multiprocessing, IPython, SGE, PBS) * ENH: MapNode runs in parallel under IPython, SGE, MultiProc, PBS * ENH: Optionally allows keeping only required outputs * ENH: New interface: utility.Rename to change the name of files, optionally using python string-formatting with inputs or regular expressions matching * ENH: New interface: freesurfer.ApplyMask (mri_mask) * ENH: New FSL interface -- SwapDimensions (fslswapdim) * ENH: Sparse models allow regressor scaling and temporal derivatives * ENH: Added support for the component parts of FSL's TBSS workflow (TBSSSkeleton and DistanceMap) * ENH: dcm2nii interface exposes bvals, bvecs, reoriented and cropped images * ENH: Added several higher-level interfaces to the fslmaths command: - ChangeDataType, Threshold, MeanImage, IsotropicSmooth, ApplyMask, TemporalFilter DilateImage, ErodeImage, SpatialFilter, UnaryMaths, BinaryMaths, MultiImageMaths * ENH: added support for networx 1.4 and improved iterable expansion * ENH: Replaced BEDPOSTX and EddyCurrent with nipype pipelines * ENH: Ability to create a hierarchical dot file * ENH: Improved debugging information for rerunning nodes * ENH: Added 'stop_on_first_rerun' option * ENH: Added support for Camino * ENH: Added support for Camino2Trackvis * ENH: Added support for Connectome Viewer * BF: dcm2nii interface handles gzipped files correctly * BF: FNIRT generates proper outputs * BF: fsl.DTIFit now properly collects tensor volume * BF: updatehash now removes old result hash file Release 0.3.4 (Jan 12, 2011) ============================ * API: hash values for float use a string conversion up to the 10th decimal place. * API: Iterables in output path will always be generated as _var1_val1_var2_val2 pairs * ENH: Added support to nipy: GLM fit, contrast estimation and calculating mask from EPI * ENH: Added support for manipulating surface files in Freesurfer: - projecting volume images onto the surface - smoothing along the surface - transforming a surface image from one subject to another - using tksurfer to save pictures of the surface * ENH: Added support for flash processing using FreeSurfer * ENH: Added support for flirt matrix in BBRegister * ENH: Added support for FSL convert_xfm * ENH: hashes can be updated again without rerunning all nodes. * ENH: Added multiple regression design for FSL * ENH: Added SPM based Analyze to Nifti converter * ENH: Added increased support for PyXNAT * ENH: Added support for MCR-based binary version of SPM * ENH: Added SPM node for calculating various threshold statistics * ENH: Added distance and dissimilarity measurements * BF: Diffusion toolkit gets installed * BF: Changed FNIRT interface to accept flexible lists (rather than 4-tuples) on all options specific to different subsampling levels Release 0.3.3 (Sep 16, 2010) ============================ * API: subject_id in ModelSpec is now deprecated * API: spm.Threshold - does not need mask, beta, RPV anymore - takes only one image (stat_image - mind the name change) - works with SPM2 SPM.mat - returns additional map - pre topological FDR * ENH: Added support for Diffusion toolkit * ENH: Added support for FSL slicer and overlay * ENH: Added support for dcm2nii * BF: DataSink properly handles lists of lists now * BF: DataGrabber has option for raising Exception on getting empty lists * BF: Traits logic for 'requires' metadata * BF: allows workflows to be relocatable * BF: nested workflows with connections don't raise connection not found error * BF: multiple workflows with identical nodenames and iterables do not create nestsed workflows Release 0.3.2 (Aug 03, 2010) ============================ Enhancements ------------ - all outputs from nodes are now pickled as part of workflow processing - added git developer docs Bugs fixed ---------- * FreeSurfer - Fixed bugs in SegStats doctest Release 0.3.1 (Jul 29, 2010) ============================ Bugs fixed ---------- * FreeSurfer - Fixed bugs in glmfit and concatenate - Added group t-test to freesurfer tutorial Release 0.3 (Jul 27, 2010) ========================== Incompatible changes -------------------- * Complete redesign of the Interface class - heavy use of Traits. * Changes in the engine API - added Workflow and MapNode. Compulsory name argument. Features added -------------- * General: - Type checking of inputs and outputs using Traits from ETS_. - Support for nested workflows. - Preliminary Slicer and AFNI support. - New flexible DataGrabber node. - AtlasPick and Threshold nodes. - Preliminary support for XNAT. - Doubled number of the tutorials. * FSL: - Added DTI processing nodes (note that TBSS nodes are still experimental). - Recreated FEAT workflow. * SPM: - Added New Segment and many other nodes. - Redesigned second level analysis. nipype-0.11.0/CONTRIBUTING.md000066400000000000000000000031241257611314500153330ustar00rootroot00000000000000## Contributing pull-requests (PRs) * All work is submitted via Pull Requests. * Pull Requests can be submitted as soon as there is code worth discussing. Pull Requests track the branch, so you can continue to work after the PR is submitted. Review and discussion can begin well before the work is complete, and the more discussion the better. The worst case is that the PR is closed. * Pull Requests should generally be made against master * Pull Requests should be tested, if feasible: - bugfixes should include regression tests - new behavior should at least get minimal exercise * Use a descriptive prefix for your PR: ENH, FIX, TST, DOC, STY, REF (refactor), WIP (Work in progress) * After submiting the PR, include an update to the CHANGES file: prefix: description (URL of pull request) * `make specs` * do: `make check-before-commit` before submitting the PR. This will require you to either install or be in developer mode with: `python setup.py install/develop`. ## Contributing issues When opening a new Issue, please take the following steps: 1. Search GitHub and/or [Neurostars](neurostars.org) for your issue to avoid duplicate reports. Keyword searches for your error messages are most helpful. 2. If possible, try updating to master and reproducing your issue, because we may have already fixed it. 3. OS and version 4. Nipype version 5. Output of: `import nipype; nipype.get_info()` 6. Versions of underlying tools (e.g., ANTS, FSL, SPM, etc.,.) 7. Any script, or output log, in a gist (gist.github.com) 8. When applicable, and where possible, pointers to relevant data files. nipype-0.11.0/INSTALL000066400000000000000000000002441257611314500141330ustar00rootroot00000000000000.. -*- rst -*- rest mode for emacs .. _development-quickstart: For installation instructions see documentation: http://nipy.org/nipype/ or doc/users/install.rst nipype-0.11.0/LICENSE000066400000000000000000000030041257611314500141040ustar00rootroot00000000000000Copyright (c) 2009-2014, NIPY Developers All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the NIPY Developers nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. nipype-0.11.0/MANIFEST.in000066400000000000000000000003761257611314500146460ustar00rootroot00000000000000include INSTALL include LICENSE include MANIFEST.in include README include THANKS include Makefile include build_docs.py include setup_egg.py include doc/documentation.zip include nipype/COMMIT_INFO.txt recursive-include doc * recursive-include tools * nipype-0.11.0/Makefile000066400000000000000000000040721257611314500145450ustar00rootroot00000000000000# Makefile for building distributions of nipype. # Files are then pushed to sourceforge using rsync with a command like this: # rsync -e ssh nipype-0.1-py2.5.egg cburns,nipy@frs.sourceforge.net:/home/frs/project/n/ni/nipy/nipype/nipype-0.1/ PYTHON ?= python NOSETESTS ?= nosetests .PHONY: zipdoc sdist egg upload_to_pypi trailing-spaces clean-pyc clean-so clean-build clean-ctags clean in inplace test-code test-doc test-coverage test html specs check-before-commit check zipdoc: html zip documentation.zip doc/_build/html sdist: zipdoc @echo "Building source distribution..." python setup.py sdist @echo "Done building source distribution." # XXX copy documentation.zip to dist directory. # XXX Somewhere the doc/_build directory is removed and causes # this script to fail. egg: zipdoc @echo "Building egg..." python setup.py bdist_egg @echo "Done building egg." upload_to_pypi: zipdoc @echo "Uploading to PyPi..." python setup.py sdist --formats=zip,gztar upload trailing-spaces: find . -name "*[.py|.rst]" -type f | xargs perl -pi -e 's/[ \t]*$$//' @echo "Reverting test_docparse" git checkout nipype/utils/tests/test_docparse.py clean-pyc: find . -name "*.pyc" | xargs rm -f clean-so: find . -name "*.so" | xargs rm -f find . -name "*.pyd" | xargs rm -f clean-build: rm -rf build clean-ctags: rm -f tags clean: clean-build clean-pyc clean-so clean-ctags in: inplace # just a shortcut inplace: $(PYTHON) setup.py build_ext -i test-code: in $(NOSETESTS) -s nipype --with-doctest test-doc: $(NOSETESTS) -s --with-doctest --doctest-tests --doctest-extension=rst \ --doctest-fixtures=_fixture doc/ test-coverage: $(NOSETESTS) -s --with-doctest --with-coverage --cover-package=nipype \ --config=.coveragerc test: clean test-code html: @echo "building docs" make -C doc clean html specs: @echo "Checking specs and autogenerating spec tests" python tools/checkspecs.py check: check-before-commit # just a shortcut check-before-commit: specs trailing-spaces html test @echo "removed spaces" @echo "built docs" @echo "ran test" @echo "generated spec tests" nipype-0.11.0/README.rst000066400000000000000000000105321257611314500145720ustar00rootroot00000000000000======================================================== NIPYPE: Neuroimaging in Python: Pipelines and Interfaces ======================================================== .. image:: https://travis-ci.org/nipy/nipype.png?branch=master :target: https://travis-ci.org/nipy/nipype .. image:: https://circleci.com/gh/nipy/nipype/tree/master.svg?style=svg :target: https://circleci.com/gh/nipy/nipype/tree/master .. image:: https://coveralls.io/repos/nipy/nipype/badge.png :target: https://coveralls.io/r/nipy/nipype .. image:: https://www.codacy.com/project/badge/182f27944c51474490b369d0a23e2f32 :target: https://www.codacy.com/app/krzysztof-gorgolewski/nipy_nipype .. image:: https://img.shields.io/pypi/v/nipype.svg :target: https://pypi.python.org/pypi/nipype/ :alt: Latest Version .. image:: https://img.shields.io/pypi/dm/nipype.svg :target: https://pypi.python.org/pypi/nipype/ :alt: Downloads .. image:: https://img.shields.io/pypi/pyversions/nipype.svg :target: https://pypi.python.org/pypi/nipype/ :alt: Supported Python versions .. image:: https://img.shields.io/pypi/status/nipype.svg :target: https://pypi.python.org/pypi/nipype/ :alt: Development Status .. image:: https://img.shields.io/pypi/l/nipype.svg :target: https://pypi.python.org/pypi/nipype/ :alt: License Current neuroimaging software offer users an incredible opportunity to analyze data using a variety of different algorithms. However, this has resulted in a heterogeneous collection of specialized applications without transparent interoperability or a uniform operating interface. *Nipype*, an open-source, community-developed initiative under the umbrella of NiPy, is a Python project that provides a uniform interface to existing neuroimaging software and facilitates interaction between these packages within a single workflow. Nipype provides an environment that encourages interactive exploration of algorithms from different packages (e.g., SPM, FSL, FreeSurfer, AFNI, Slicer, ANTS), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is creating a collaborative platform for neuroimaging software development in a high-level language and addressing limitations of existing pipeline systems. *Nipype* allows you to: * easily interact with tools from different software packages * combine processing steps from different software packages * develop new workflows faster by reusing common steps from old ones * process data faster by running it in parallel on many cores/machines * make your research easily reproducible * share your processing workflows with the community Documentation ------------- Please see the ``doc/README.txt`` document for information on our documentation. Website ------- Information specific to Nipype is located here:: http://nipy.org/nipype Support and Communication ------------------------- If you have a problem or would like to ask a question about how to do something in Nipype please submit a question to `NeuroStars.org `_ with a *nipype* tag. `NeuroStars.org `_ is a platform similar to StackOverflow but dedicated to neuroinformatics. All previous Nipype questions are available here:: http://neurostars.org/t/nipype/ To participate in the Nipype development related discussions please use the following mailing list:: http://mail.python.org/mailman/listinfo/neuroimaging Please add *[nipype]* to the subject line when posting on the mailing list. Nipype structure ---------------- Currently Nipype consists of the following files and directories: INSTALL NIPYPE prerequisites, installation, development, testing, and troubleshooting. README This document. THANKS NIPYPE developers and contributors. Please keep it up to date!! LICENSE NIPYPE license terms. doc/ Sphinx/reST documentation examples/ nipype/ Contains the source code. setup.py Script for building and installing NIPYPE. License information ------------------- We use the 3-clause BSD license; the full license is in the file ``LICENSE`` in the nipype distribution. There are interfaces to some GNU code but these are entirely optional. All trademarks referenced herein are property of their respective holders. Copyright (c) 2009-2015, NIPY Developers All rights reserved. nipype-0.11.0/THANKS.rst000066400000000000000000000055261257611314500146340ustar00rootroot00000000000000.. -*- mode: rst -*- Code contributors ----------------- Contributors to Nipype include but are not limited to: .. hlist:: * Aimi Watanabe * Alexander Schaefer * Alexandre Gramfort * Anisha Keshavan * Ariel Rokem * Ben Acland * Basile Pinsard * Brendan Moloney * Brian Cheung * Charl Linssen * Chris Filo Gorgolewski * Chris Steele * Christian Haselgrove * Christopher Burns * Cindee Madison * Claire Tarbert * Colin Buchanan * Daniel Ginsburg * Daniel Haehn * Daniel Margulies * Dav Clark * David Welch * Drew Erickson * Erik Kastman * Félix C. Morency * Gael Varoquaux * Hans Johnson * Janosch Linkersdörfer * Januzz * Jarrod Millman * Jeff Lai * Jessica Forbes * John Salvatore * Lijie Huang * Michael Hallquist * Michael Hanke * Michael Notter * Michael Waskom * Nolan Nichols * Oliver Hinds * Oscar Esteban * Rosalia Tungaraza * Satrajit Ghosh * Sharad Sikka * Stephan Gerhard * Erik Ziegler * Valentin Haenel * Xiangzhen Kong * Xu Wang * Yannick Schwartz * Yaroslav O. Halchenko For full most up to date list see `Ohloh `__. Other contributors ------------------ .. hlist:: * Matthew Brett * Michael Castelle * Philippe Ciuciu * Yann Cointepas * Mark D'Esposito * Susan Gabrieli * Brian Hawthorne * Tim Leslie * Fernando Perez * Tyler Perrachione * Jean-Baptiste Poline * Alexis Roche * Denis Riviere * Gretchen Reynolds * Jonathan Taylor * Bertrand Thirion * Bernjamin Thyreau * Mike Trumpis * Karl Young * Tom Waite We would also like to thank `JetBrains `__ for providing `Pycharm `__ licenses. Funding ------- Satrajit Ghosh work on this project was partially funded by NIBIB R03 EB008673 (PI: Ghosh and Whitfield-Gabrieli) and by the `INCF `__ through a contract with TankThink Labs, LLC. Chris Burns was supported by NIMH grant 5R01MH081909-02 (PI: Desposito). Hans Jonson was supported by `2 U54 EB005149 - 06 Core 2b Huntington's Disease - Driving Biological Project `__, `S10 RR023392 Enterprise Storage In A Collaborative Neuroimaging Environment `__, `R01 NS040068 Neurobiological Predictors of Huntington's Disease `__, and `UL1 TR000442 University of Iowa Clinical and Translational Science Program `__. nipype-0.11.0/Vagrantfile000066400000000000000000000047421257611314500152760ustar00rootroot00000000000000VAGRANTFILE_API_VERSION = "2" $script = < {% endblock %} nipype-0.11.0/doc/_templates/indexsidebar.html000066400000000000000000000023341257611314500213350ustar00rootroot00000000000000{% block nipypelinks %}

{{ _('Links') }}

{% endblock %} nipype-0.11.0/doc/_templates/layout.html000066400000000000000000000033551257611314500202150ustar00rootroot00000000000000{% extends "!layout.html" %} {% set title = 'Neuroimaging in Python - Pipelines and Interfaces' %} {% set short_title = 'Nipype' %} {% block extrahead %} {{ super() }} {% endblock %} {% block header %} {% endblock %} {% block relbar1 %}{% endblock %} {% block relbar2 %}{% endblock %} {% block sidebar1 %}{{ sidebar() }}{% endblock %} {% block sidebar2 %}{% endblock %} {% block footer %} {{ super() }} {% endblock %} nipype-0.11.0/doc/_templates/navbar.html000066400000000000000000000010501257611314500201370ustar00rootroot00000000000000 Home · Quickstart · Documentation · Citation · NiPy nipype-0.11.0/doc/_templates/sidebar_versions.html000066400000000000000000000031351257611314500222350ustar00rootroot00000000000000{% block versions %}

{{ _('Versions') }}

ReleaseDevel
0.11.0{{ version }}
Download Github
{% endblock %} nipype-0.11.0/doc/about.rst000066400000000000000000000017651257611314500155240ustar00rootroot00000000000000.. _about: ===== About ===== Citation -------- .. admonition:: Reference Gorgolewski K, Burns CD, Madison C, Clark D, Halchenko YO, Waskom ML, Ghosh SS. (2011). Nipype: a flexible, lightweight and extensible neuroimaging data processing framework in Python. Front. Neuroimform. 5:13. `Download`__ __ paper_ :: @article { Gorgolewski2011, title = "Nipype: a flexible, lightweight and extensible neuroimaging data processing framework in python.", year = "2011", author = "Krzysztof Gorgolewski and Christopher D Burns and Cindee Madison and Dav Clark and Yaroslav O Halchenko and Michael L Waskom and Satrajit S Ghosh", journal = "Front Neuroinform", volume = "5", month = "08", doi = "10.3389/fninf.2011.00013", pubmed = "21897815", url = "http://dx.doi.org/10.3389/fninf.2011.00013", issn = "1662-5196"} .. include:: links_names.txt .. include:: ../THANKS.rst nipype-0.11.0/doc/api/000077500000000000000000000000001257611314500144205ustar00rootroot00000000000000nipype-0.11.0/doc/api/index.rst000066400000000000000000000001401257611314500162540ustar00rootroot00000000000000.. _api-index: ### API ### :Release: |version| :Date: |today| .. include:: generated/gen.rst nipype-0.11.0/doc/changes.rst000066400000000000000000000002111257611314500160030ustar00rootroot00000000000000:tocdepth: 2 .. _changes: ================= Changes in Nipype ================= .. include:: ../CHANGES .. include:: links_names.txt nipype-0.11.0/doc/conf.py000066400000000000000000000202411257611314500151450ustar00rootroot00000000000000# emacs: -*- coding: utf-8; mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set fileencoding=utf-8 ft=python sts=4 ts=4 sw=4 et: # # nipype documentation build configuration file, created by # sphinx-quickstart on Mon Jul 20 12:30:18 2009. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os nipypepath = os.path.abspath('..') sys.path.insert(1,nipypepath) import nipype # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. sys.path.append(os.path.abspath('sphinxext')) # -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = ['sphinx.ext.todo', 'sphinx.ext.pngmath', 'sphinx.ext.inheritance_diagram', 'sphinx.ext.graphviz', 'sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.pngmath', 'sphinx.ext.autosummary', 'numpy_ext.numpydoc', 'matplotlib.sphinxext.plot_directive', 'matplotlib.sphinxext.only_directives', 'IPython.sphinxext.ipython_directive', 'IPython.sphinxext.ipython_console_highlighting' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8' # The master toctree document. master_doc = 'index' # General information about the project. project = u'nipype' copyright = u'2009-15, Neuroimaging in Python team' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = nipype.__version__ # The full version, including alpha/beta/rc tags. release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y, %H:%M PDT' # List of documents that shouldn't be included in the build. unused_docs = ['api/generated/gen'] # List of directories, relative to source directory, that shouldn't be searched # for source files. exclude_trees = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Sphinxext configuration --------------------------------------------------- # Set attributes for layout of inheritance diagrams inheritance_graph_attrs = dict(rankdir="LR", size='"6.0, 8.0"', fontsize=14, ratio='compress') inheritance_node_attrs = dict(shape='ellipse', fontsize=14, height=0.75, color='dodgerblue1', style='filled') # Flag to show todo items in rendered output todo_include_todos = True # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. html_theme = 'sphinxdoc' # The style sheet to use for HTML and HTML Help pages. A file of that name # must exist either in Sphinx' static/ path, or in one of the custom paths # given in html_static_path. html_style = 'nipype.css' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". html_title = 'nipy pipeline and interfaces package' # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # Content template for the index page. html_index = 'index.html' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. html_sidebars = {'**': ['gse.html','localtoc.html', 'sidebar_versions.html', 'indexsidebar.html'], 'searchresults' : ['sidebar_versions.html', 'indexsidebar.html'], 'version' : []} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {'index': 'index.html'} # If false, no module index is generated. #html_use_modindex = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. html_show_sourcelink = False # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = '' # Output file base name for HTML help builder. htmlhelp_basename = 'nipypedoc' # -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' # The font size ('10pt', '11pt' or '12pt'). #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('documentation', 'nipype.tex', u'nipype Documentation', u'Neuroimaging in Python team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # Additional stuff for the LaTeX preamble. #latex_preamble = '' # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_use_modindex = True # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'http://docs.python.org/': None} exclude_patterns = ['interfaces/generated/gen.rst', 'api/generated/gen.rst'] nipype-0.11.0/doc/devel/000077500000000000000000000000001257611314500147465ustar00rootroot00000000000000nipype-0.11.0/doc/devel/architecture.rst000066400000000000000000000073451257611314500201730ustar00rootroot00000000000000====================================== Architecture (discussions from 2009) ====================================== This section reflects notes and discussion between developers during the start of the nipype project in 2009. Design Guidelines ----------------- These are guidelines that the core nipype developers have agreed on: Interfaces should keep all parameters affecting construction of the appropriate command in the "input" bunch. The .run() method of an Interface should include all required inputs as explicitly named parameters, and they should take a default value of None. Any Interface should at a minimum support cwd as a command-line argument to .run(). This may be accomplished by allowing cwd as an element of the input Bunch, or handled as a separate case. Relatedly, any Interface should output all files to cwd if it is set, and otherwise to os.getcwd() (or equivalent). We need to decide on a consistent policy towards the maintinence of paths to files. It seems like the best strategy might be to do absolute (os.realpath?) filenames by default, allowing for relative paths by explicitly including something that doesn't start with a '/'. This could include '.' in some sort of path-spec. Class attributes should never be modified by an instance of that class. And probably not ever. Providing for Provenance ------------------------ The following is a specific discussion that should be thought out an more generally applied to the way we handle auto-generation / or "sourcing" of settings in an interface. There are two possible sources (at a minimum) from which the interface instance could obtain "outputtype" - itself, or FSLInfo. Currently, the outputtype gets read from FSLInfo if self.outputtype (er, _outputtype?) is None. In the case of other opt_map specifications, there are defaults that get specified if the value is None. For example output filenames are often auto-generated. If you look at the code for fsl.Bet for example, there is no way for the outfile to get picked up at the pipeline level, because it is a transient variable. This is OK, as the generation of the outfile name is contingent ONLY on inputs which ARE available to the pipeline machinery (i.e., via inspection of the Bet instance's attributes). However, with outputtype, we are in a situation in which "autogeneration" incorporates potentially transient information external to the instance itself. Thus, some care needs to be taken in always ensuring this information is hashable. Design Principles ----------------- These are (currently) Dav Clark's best guess at what the group might agree on: It should be very easy to figure out what was done by the pypeline. Code should support relocatability - this could be via URIs, relative paths or potentially other mechanisms. Unless otherwise called for, code should be thread safe, just in case. The pipeline should make it easy to change aspects of an analysis with minimal recomputation, downloading, etc. (This is not the case currently - any change will overwrite the old node). Also, the fact that multiple files get rolled into a single node is problematic for similar reasons. E.g. - node([file1 ... file100]) will get recomputed if we add only one file!. However, it should also be easy to identify and delete things you don't need anymore. Pipelines and bits of pipelines should be easy to share. Things that are the same should be called the same thing in most places. For interfaces that have an obvious meaning for the terms, "infiles" and "outfile(s)". If a file is in both the inputs and outputs, it should be called the same thing in both places. If it is produced by one interface and consumed by another, same thing should be used. Discussions ----------- .. toctree:: :maxdepth: 1 filename_generation nipype-0.11.0/doc/devel/cmd_interface_devel.rst000066400000000000000000000176061257611314500214540ustar00rootroot00000000000000.. _interface_devel: =============================== How to wrap a command line tool =============================== The aim of this section is to describe how external programs and scripts can be wrapped for use in Nipype either as interactive interfaces or within the workflow/pipeline environment. Currently, there is support for command line executables/scripts and matlab scripts. One can also create pure Python interfaces. The key to defining interfaces is to provide a formal specification of inputs and outputs and determining what outputs are generated given a set of inputs. Defining inputs and outputs =========================== In Nipype we use Enthought Traits to define inputs and outputs of the interfaces. This allows to introduce easy type checking. Inputs and outputs are grouped into separate classes (usually suffixed with InputSpec and OutputSpec). For example: .. testcode:: class ExampleInputSpec(TraitedSpec): input_volume = File(desc = "Input volume", exists = True, mandatory = True) parameter = traits.Int(desc = "some parameter") class ExampleOutputSpec(TraitedSpec): output_volume = File(desc = "Output volume", exists = True) For the Traits (and Nipype) to work correctly output and input spec has to be inherited from TraitedSpec (however, this does not have to be direct inheritance). Traits (File, Int etc.) have different parameters (called metadata). In the above example we have used the ``desc`` metadata which holds human readable description of the input. The ``mandatory`` flag forces Nipype to throw an exception if the input was not set. ``exists`` is a special flag that works only for ``File traits`` and checks if the provided file exists. More details can be found at :doc:`interface_specs`. The input and output specifications have to be connected to the our example interface class: .. testcode:: class Example(Interface): input_spec = ExampleInputSpec output_spec = ExampleOutputSpec Where the names of the classes grouping inputs and outputs were arbitrary the names of the fields within the interface they are assigned are not (it always has to be input_spec and output_spec). Of course this interface does not do much because we have not specified how to process the inputs and create the outputs. This can be done in many ways. Command line executable ======================= As with all interfaces command line wrappers need to have inputs defined. Command line input spec has to inherit from CommandLineInputSpec which adds two extra inputs: environ (a dictionary of environmental variables), and args (a string defining extra flags). In addition input spec can define the relation between the inputs and the generated command line. To achieve this we have added two metadata: ``argstr`` (string defining how the argument should be formated) and ``position`` (number defining the order of the arguments). For example .. testcode:: class ExampleInputSpec(CommandLineSpec): input_volume = File(desc = "Input volume", exists = True, mandatory = True, position = 0, argstr="%s") parameter = traits.Int(desc = "some parameter", argstr = "--param %d") As you probably noticed the ``argstr`` is a printf type string with formatting symbols. For an input defined in InputSpec to be included into the executed commandline ``argstr`` has to be included. Additionally inside the main interface class you need to specify the name of the executable by assigning it to the ``_cmd`` field. Also the main interface class needs to inherit from :class:`nipype.interfaces.base.CommandLine`: .. testcode:: class Example(CommandLine): _cmd = 'my_command' input_spec = ExampleInputSpec output_spec = ExampleOutputSpec There is one more thing we need to take care of. When the executable finishes processing it will presumably create some output files. We need to know which files to look for, check if they exist and expose them to whatever node would like to use them. This is done by implementing ``_list_outputs`` method in the main interface class. Basically what it does is assigning the expected output files to the fields of our output spec: .. testcode:: def _list_outputs(self): outputs = self.output_spec().get() outputs['output_volume'] = os.path.abspath('name_of_the_file_this_cmd_made.nii') return outputs Sometimes the inputs need extra parsing before turning into command line parameters. For example imagine a parameter selecting between three methods: "old", "standard" and "new". Imagine also that the command line accept this as a parameter "--method=" accepting 0, 1 or 2. Since we are aiming to make nipype scripts as informative as possible it's better to define the inputs as following: .. testcode:: class ExampleInputSpec(CommandLineSpec): method = traits.Enum("old", "standard", "new", desc = "method", argstr="--method=%d") Here we've used the Enum trait which restricts input a few fixed options. If we would leave it as it is it would not work since the argstr is expecting numbers. We need to do additional parsing by overloading the following method in the main interface class: .. testcode:: def _format_arg(self, name, spec, value): if name == 'method': return spec.argstr%{"old":0, "standard":1, "new":2}[value] return super(Example, self)._format_arg(name, spec, value) Here is a minimalistic interface for the gzip command: .. testcode:: from nipype.interfaces.base import ( TraitedSpec, CommandLineInputSpec, CommandLine, File ) import os class GZipInputSpec(CommandLineInputSpec): input_file = File(desc="File", exists=True, mandatory=True, argstr="%s") class GZipOutputSpec(TraitedSpec): output_file = File(desc = "Zip file", exists = True) class GZipTask(CommandLine): input_spec = GZipInputSpec output_spec = GZipOutputSpec cmd = 'gzip' def _list_outputs(self): outputs = self.output_spec().get() outputs['output_file'] = os.path.abspath(self.inputs.input_file + ".gz") return outputs if __name__ == '__main__': zipper = GZipTask(input_file='an_existing_file') print zipper.cmdline zipper.run() Creating outputs on the fly =========================== In many cases, command line executables will require specifying output file names as arguments on the command line. We have simplified this procedure with three additional metadata terms: ``name_source``, ``name_template``, ``keep_extension``. For example in the :ref:`InvWarp ` class, the ``inverse_warp`` parameter is the name of the output file that is created by the routine. .. testcode:: class InvWarpInputSpec(FSLCommandInputSpec): ... inverse_warp = File(argstr='--out=%s', name_source=['warp'], hash_files=False, name_template='%s_inverse', ... we add several metadata to inputspec. name_source indicates which field to draw from, this field must be the name of a File. hash_files indicates that the input for this field if provided should not be used in computing the input hash for this interface. name_template (optional) overrides the default ``_generated`` suffix output_name (optional) name of the output (if this is not set same name as the input will be assumed) keep_extension (optional - not used) if you want the extension from the input to be kept In addition one can add functionality to your class or base class, to allow changing extensions specific to package or interface .. testcode:: def self._overload_extension(self, value): return value #do whatever you want here with the name Finally, in the outputspec make sure the name matches that of the inputspec. .. testcode:: class InvWarpOutputSpec(TraitedSpec): inverse_warp = File(exists=True, desc=('Name of output file, containing warps that ' 'are the "reverse" of those in --warp.')) nipype-0.11.0/doc/devel/filename_generation.rst000066400000000000000000000132041257611314500214730ustar00rootroot00000000000000========================== Auto-generated filenames ========================== In refactoring the inputs in the traitlets branch I'm working through the different ways that filenames are generated and want to make sure the interface is consistent. The notes below are all using fsl.Bet as that's the first class we're Traiting. Other interface classes may handle this differently, but should agree on a convention and apply it across all Interfaces (if possible). Current Rules ------------- These rules are for fsl.Bet, but it appears they are the same for all fsl and spm Interfaces. Bet has two mandatory parameters, ``infile`` and ``outfile``. These are the rules for how they are handled in different use cases. 1. If ``infile`` or ``outfile`` are absolute paths, they are used as-is and never changed. This allows users to override any filename/path generation. 2. If ``outfile`` is not specified, a filename is generated. 3. Generated filenames (at least for ``outfile``) are based on: * ``infile``, the filename minus the extensions. * A suffix specified by the Interface. For example Bet uses *_brain* suffix. * The current working directory, os.getcwd(). Example: If ``infile`` == 'foo.nii' and the cwd is ``/home/cburns`` then generated ``outfile`` for Bet will be ``/home/cburns/foo_brain.nii.gz`` 4. If ``outfile`` is not an absolute path, for instance just a filename, the absolute path is generated using ``os.path.realpath``. This absolute path is needed to make sure the packages (Bet in this case) write the output file to a location of our choosing. The generated absolute path is only used in the ``cmdline`` at runtime and does __not__ overwrite the class attr ``self.inputs.outfile``. It is generated only when the ``cmdline`` is invoked. Walking through some examples ----------------------------- In this example we assign ``infile`` directly but ``outfile`` is generated in ``Bet._parse_inputs`` based on ``infile``. The generated ``outfile`` is only used in the cmdline at runtime and not stored in ``self.inputs.outfile``. This seems correct. .. sourcecode:: ipython In [15]: from nipype.interfaces import fsl In [16]: mybet = fsl.Bet() In [17]: mybet.inputs.infile = 'foo.nii' In [18]: res = mybet.run() In [19]: res.runtime.cmdline Out[19]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/foo_brain.nii.gz' In [21]: mybet.inputs Out[21]: Bunch(center=None, flags=None, frac=None, functional=None, infile='foo.nii', mask=None, mesh=None, nooutput=None, outfile=None, outline=None, radius=None, reduce_bias=None, skull=None, threshold=None, verbose=None, vertical_gradient=None) In [24]: mybet.cmdline Out[24]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/foo_brain.nii.gz' In [25]: mybet.inputs.outfile In [26]: mybet.inputs.infile Out[26]: 'foo.nii' We get the same behavior here when we assign ``infile`` at initialization: .. sourcecode:: ipython In [28]: mybet = fsl.Bet(infile='foo.nii') In [29]: mybet.cmdline Out[29]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/foo_brain.nii.gz' In [30]: mybet.inputs Out[30]: Bunch(center=None, flags=None, frac=None, functional=None, infile='foo.nii', mask=None, mesh=None, nooutput=None, outfile=None, outline=None, radius=None, reduce_bias=None, skull=None, threshold=None, verbose=None, vertical_gradient=None) In [31]: res = mybet.run() In [32]: res.runtime.cmdline Out[32]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/foo_brain.nii.gz' Here we specify absolute paths for both ``infile`` and ``outfile``. The command line's look as expected: .. sourcecode:: ipython In [53]: import os In [54]: mybet = fsl.Bet() In [55]: mybet.inputs.infile = os.path.join('/Users/cburns/tmp/junk', 'foo.nii') In [56]: mybet.inputs.outfile = os.path.join('/Users/cburns/tmp/junk', 'bar.nii') In [57]: mybet.cmdline Out[57]: 'bet /Users/cburns/tmp/junk/foo.nii /Users/cburns/tmp/junk/bar.nii' In [58]: res = mybet.run() In [59]: res.runtime.cmdline Out[59]: 'bet /Users/cburns/tmp/junk/foo.nii /Users/cburns/tmp/junk/bar.nii' Here passing in a new ``outfile`` in the ``run`` method will update ``mybet.inputs.outfile`` to the passed in value. Should this be the case? .. sourcecode:: ipython In [110]: mybet = fsl.Bet(infile='foo.nii', outfile='bar.nii') In [111]: mybet.inputs.outfile Out[111]: 'bar.nii' In [112]: mybet.cmdline Out[112]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/bar.nii' In [113]: res = mybet.run(outfile = os.path.join('/Users/cburns/tmp/junk', 'not_bar.nii')) In [114]: mybet.inputs.outfile Out[114]: '/Users/cburns/tmp/junk/not_bar.nii' In [115]: mybet.cmdline Out[115]: 'bet foo.nii /Users/cburns/tmp/junk/not_bar.nii' In this case we provide ``outfile`` but not as an absolue path, so the absolue path is generated and used for the ``cmdline`` when run, but ``mybet.inputs.outfile`` is not updated with the absolute path. .. sourcecode:: ipython In [74]: mybet = fsl.Bet(infile='foo.nii', outfile='bar.nii') In [75]: mybet.inputs.outfile Out[75]: 'bar.nii' In [76]: mybet.cmdline Out[76]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/bar.nii' In [77]: res = mybet.run() In [78]: res.runtime.cmdline Out[78]: 'bet foo.nii /Users/cburns/src/nipy-sf/nipype/trunk/nipype/interfaces/tests/bar.nii' In [80]: res.interface.inputs.outfile Out[80]: 'bar.nii' nipype-0.11.0/doc/devel/gitwash/000077500000000000000000000000001257611314500164145ustar00rootroot00000000000000nipype-0.11.0/doc/devel/gitwash/branch_list.png000066400000000000000000000320611257611314500214140ustar00rootroot00000000000000‰PNG  IHDRyU¬”Ä pHYs  šś IDATxí]\TÇÖ˙/»ěҢ€,lŘcLě-ŁFźúŚ1ďĹó˝bĚSS^˘‰‰Qc‹˝ FÔhěŠF‰Ř+˘€R¤łKŮĆ~gîî‚ » čĚvďťzćÎś9sfî]‘žxŕp8§›§˛WĽSŽG€# Ŕ•<ŽG€#đ#Ŕ•üSĚ\Ţ5ŽG€#Ŕ•<—ŽG€#đ# ±¶oąąąČÎΆJĄßłµ=žź#Ŕŕ<^DÖś®ÉČČ€R©„D"‘đ˙xÉĺ­q8Ž€5XlÉ3 ž)xGGG®Ü­Açĺp8Ő€ĹJžąhĎwÓT#ÇxÓŽGŔ ,Ţxe>x8ŽG f!`±’gÖ;óĂóŔŕp85‹Ý5¬KÖ¸i4 233QPP`Uąš]IJŮhooWWWŘÚÚ–LäwŽG š°JÉ[J#SđÉÉÉđôôD@@¤R©ĄEkl>Öç””áh)Wň5–ŤśpŽŔS‡@•(yfÁ3_Ż^˝§°ň:Ä;ëŻBˇSř………ĺeĺńŽGŕ±!`•’·Ô]Ă\4Ě‚;ÄN"YŠŐłď3G€#đř°xăŐ’‚{\4ea"‹ůuYŔđ8ŽG Z¨KľZzň„5Ę-ů'Ś!śŽŔ3Š@•XňĎ(–ĽŰŽGŕ‰C š-y-bOîĆÖÝH. #šv®yn0^zľ ěž8¨¬#¨*,ů¬„‹8Ťô< ô¶ö¨‚ĐÖ Qýg—tHľ€çFňuµ¨Ç”;5&ńŮZř6oŤÚöćŤ*qýĚ Hüš# d‚y¦Ç~­LĽŽëYŽhŰÜb [W?¸ýç€ú¶.!ę|%tR'Ř—ŞHŻV"5+ĚĹčŕę^”ţŕâA\FKôn]Ç–+/ë÷Ť$$i&-dnŤĐĚjů2Čfn­fhćăh1ˇ†±vĆQëáŇ0ˇˇKÉŽĹŐUkƇ |5•޸ôŘ3w > Ď,ŃdÄľp,đŹ]żľ ď)5ë¦R±‚ŃżýŚ-§“drg9˝~‡´ĆëoG]YuⓇ3›Ăq®ůX|őŞ”ń§°,,¦Ž€oőĎ@d=ä#rófD±‡¶/č0gr[čM‡źňďagx8Ôíkaö°FPkM eă™|z+¶Äřáµ1Pb®(;ű_ŽM:·;O·Bë/@¬˘I˝Âš”Ř·l.µ€Q2äćŇó)¬Ś.‹żXż±30Ľ© Ť)c"°pí!žc×CŽ^ŁĆŁWóÚprÖâč**8 ¶Ú [®Ě Içv!ü´˘Ě*őm&ŕ«nPite¦—©Wá"Éćź!µđńWU 0ÜŘ· N&Ő™ĆÚí„Xś=&MEW§2›zR#­Rň•ى‚[ŰŠ|Čř0ą{}ÜŹŘąkŽAż˙ „ů#Vf“5¶®ç¶ ^Öŕ9ĽýúPÔŁWéi’Ľq`~Ú}żFv»=} ©XTöčůúôôi ;ň´™HNż {79lséHiµŃUÜ]{6.™F‹Űq-ńĽŻÄ ÉŠ•ŃÜöt*ĘÁÎjĄIí—5żŇdŢEú]wÔr¶‡:'ŹžĚKZw-‘Ь-u†#)lŤJ>óâď8­’cň`HDąĐ«Ňq+ć6.FD:5ÝÜEG© Qśu‹×‚—5Ŕ+SG§ŕÂ×lÇŃMah<÷mÔóďŽ^'±vĂ|>±*Ô‹Öu푹%[’m;Śť1­ť]±BËśá UY§ä©5‰ś,q{Uđ÷ÁéÍ_·¦ż1őťeÂIąä‹{±`ĺďŘżr)ĽfĽŹ‡bş١' Ń*%_™Ö©VcLCđŮŰ#áI`´oŰškńep7=ÇŹv,ÂśąkgŚé>~>z{€P&vĎ|˝óš ~ďôoLÚŻÎFŘU†Ľ7ýK ÷wíŃo@+\Z4÷-ÇŇIm‘uóľţlN'˛¶śŃaÄdĽ5ą?Ľ=R±wÉ,X¶˘Zđ é†OĎ7±ĚQyX=ŔÁđëDOSĽýîPÔŐ©ˇČRBCcµvűţčy W™ţőˇWdáŇ0üv2VĐgN^-0hä4u·….ĺ~ŮßĆH?s×3DđjŃ;şâÄößq#S©[ĆĽ6őÉDM:ŽđŰr„6ĘÇţߢ ”ą!¤ď`á&ví;‰ bźoűáGJˇĹíÓqĎßÎŢwńóš“`/ŔX=g>şŽ‹6vńŘąu®$+©24 Śa/U©%lĂű­zŁ6fnŔcËĂüٸ0íEilRчžĚ{Ć·ü¤‹Ř±ĺ €‰L^ű Ŕs­Ľ‘HVüÚ“ ʉϿÍEŹ&yř#ZŠ‘S†Ŕ›\! ł-‘Yč5öU´r ŻZ…văơť§®\Ţ@ť€°•űáŢ.)ű‘ÝęUô5v@ËčŁ˙xŞű·Č8řöŤ­Ůh1ľýěZO@kGšdł G«©u[h ă{tCč_j”1ô˙ŢB(ydňs]0zL >[y±É"4¬c‡Ž/vÁŃőaÖ´GS›<#S]Uů͸!˘±čę)'7I¶pRÍô:˝F‰,u!´Y·°{k8Î'/Hž†ôĆ~á*ÖăÁąplż] ÝüŘą' ÁŻľ%KŇ*†ń7 [·âB˘úOŤ&Ć ˘éđŘëRK|4c$Ľ„±–IcŤZńë„7Ǧă›őQ8r1 A]eX»·ý`t¨ŻPúÁ9¬Y{ŢŔďÚ´„Ő=@ÄŻ»đÇ•ČähÖŞúő5ĐÉd)춦Ś5ŚZmžŢ´ńŤ†`DoˇľňäĐDŻĄßŐ·ńŞQi Ç”©ł±~Ď1ÜLČÄ ĎâěŮłŘ>µŤµdţi¦ŕYdÄšYč7~=r‰qůÉ'…ř\C}"-âŹŔ™3ÇGKMÓ}D8ć΋đxŕ¶B eôzôý>öEÇ Ż_ČĚŚŁĺî'đď_Q%6ĽŢź0ĎjŐg">j'fŚ=±´yđ8C~M7€K÷¨GĘ47Ű ŕČâéýć|űQ8ID8żi¶“‚wďĐŁGö†8é 6ü°7•4^r’‘‘€“ű#Ă;ťšą ĺʬX†ë6ľčÚ©)ÔŃXµţ4@RˇĘş‹äضçőč‚68łó¬ŢyňŔ.n艄¨í8Lxô:¤^‰Ĺ•T-ťh€Ę >O//¸ąĺaëŹq%Ă}FŚ@żOÜ<†•'°fkĐ×·¦ô&%rë÷ß…-Ó|Ą 2uŇI|µôWRđäľ:Míď!bűRl˝ś‰]-¸‘U‘>őęŔŰ]„Ś”óHÉs¤şÔ¸zî23îŕ*ů”íb˘pO‘OyÝpeówĺň†-1’’±g?®kśáăă'Ł›‹yá"Ö`ĹžóČôę‰!=ÉVćAť;Ô«ö]ˇ× €”ą}Ŕ|:÷,ül \dó vöEËŔžňŁ€Ü~ůj 2’Ó„,ô˝–C {˙Ćp§sײ`WĘ—o^WU\ëA2źš¬´Lal˛ß±ČČȅެú‚;X¶`-Α7ĄëW0¬{=Ü9ł‡¬ě“P?óŇHnŁ#Ś<ś ®Ź›°?!1{Vý‹çă0)ÝFý†"ÄËR3!Ôç§!‘*qî /k a¬çÔ¸-Ň´’pĺ:t2[dÝIĆť<2l üĐe§żIăŇ^’đŻ mt€ľí\p#Šč\w:˘Sť‡Ś»yptv(¬ľ›9"ČíĄx”Z‹yµYňŽ­‡ŕµ ĺXMV )Đůôo íGÍħWîI|±,Z~qúĚŰ©G—`č{Ë ŹžŹ·^B^lî%“™ßPéâ{?ü{î;čŘŇ{?ź*Ô+"˙˙–Ť˙†nď'xĺłýŔŮEĽ Áü3Śą~řdăZ i’Ź ÓGcţ±LĚ_÷'úĎę!”}ÔGĄYň6b8’’­— P]@g±ĐÚ×A‘™NFĂi„ßPŁ~źixw` iĄÔÂŰ/Ü…çR0ŐßP®îs˙ÂűCšŇr>÷Ţ_űž˝1{ćÔŇká“>›@,w ‹Ç e˝;}꓏7Č->ІßĹŰ}ęC—{W>Z‰«wr0"Đ…@¦?ą>ę´ŔČ—R0çç3č˙ú84PÝŔaň0°[TíŰŁ–ÍRD*9ř /Wó(+'Ť0Ó3…®ĚGóľč»#V"ŞĂ<´2łä W#ę7’ZŻ|řýč…Pwn‡ßľť#/`ÔG/`Pć5,=Ő ŻŤ~˘Ś3pŇ_ÁĹŰč’Š»IT”Úą{9ŇöÍKßpďE$–\W•Ë›–ˇŢ8·‰™“»”zÜŘ&Ą\:ň Ö¦‰»ő(Ě ™V…¬|5ĺ(ÚEëë&%×[iSµ dhhc•h2¬W +[Ď–xiŚä…*r­"áěšDn ýî@tAm컣 ŤŁs i° ńE3C`r'e"ěëŮĄZk‡ł‡ óÔ!$ČC?śŤçĽl )hşÎ«°h÷>\ĘěOŁÜv7#Č  ĺ-¶±šňb±sénśLˇÇÄ™ŢĆš<ú…;]1’ůÉ÷Ł.¸^ma¬©M8Q⎺n"2Ő(d;Ă2¶Ž°ŘF$`®—ë˘÷XežŰ‡ó*ú˝ű5úÖ—A«éf+đý®ßŁę­¶bÚ×5¬Öé¬>‰¤9ěĐ Z+řa•’/ęk%\DŢşć \8m;÷ ""q™˘6†Y2z9^pŃhĐŤ}©˝pâĆ·ç«řWĐ2üDş˙ř‰Ű¤ä-ă~X…Iˇ®$đ©8ţŔPnň§˙DC;‚ač§ŘÝć5äëí!MŢb¬4Ű–|‚ZJ]Ž0lgžż†,ô€eNËi+7'Y/ą$42˛®Ę ´¤¤1OFJ–Ü´…/t*%˛s)˛V„ň˝©ˇ—§ͱ¦Aľ$ŔąČRÚŁŤgeË Rđd“»ĆŢâ8ňaR{"0EŇľ2˛öČŞĘ3¸×ę7¨Mő+ťĄ†#µČ¨’˝ŤqPĄĘ§O=ĺ#× ŁśjK<ńŢ>펦ÍŃ*d0^ôyŔ)Ĺ’MEŞ®’‚ŽZ 1‘ßnÂŽeÇĐę­zdééÉnŁ "J0’­†ÝkVSGh0SÓIVDvyd˝Ů‘RQAD–˛ščVˇZ†§®ÝCAĂ$$<б“=ţYú٤Çö2 ×,Ú;( ´GĂ&Đqo˝ MŢD–(éO¬ú=µkŮ"ŻN)î#‡âĄ¬Š$Ü')qfőY ‡lzcuZ̶,É^yyš |ţTťŃ>´ †ŤŹáχ`ĚÜpˇż˝ŕëŰ´g™2ńíäŢ˙îëč3đ=*ÁÍ LJßÝŤ4 Q_bČ?ĆĄ"ËűtB‡…Äč5Ó0lętŚčǤč0°ŻĐäľEs°óÔeÄ‘ew3ŠŽt­:ÄloÚ±o űz-Ń€(ŽüůgDÝËB~Nö®ÝF® whꌅQşsTŢę eNŽş€\*›p‰Ü‘¸źś‚ř›×h=źéI˛ňÉB´şňżV Ôp¦JśĐcDż˘ĘDĚ$W]`°DöáÇđ?Éę‹Ăé]+±pçźSŰ‘ –&< ů0h?ăôÍű¤¶i€Öpg¶¨G{!ÎhÜŔŽÝ’¤-ů5x=š7BîŇĚ•%ˇŐ–>Ď„ńďěşíHW¬fŮĹRćSáî*C«‡ŠÂ˝+ç…,ööäűĄçR¶…mĂÎßčxŕ#¸ťmtahłGşSjKGMµl;öńĆŻ˛şR»IsJą‡e?íEj.ą¶bNâ—_I#Č» Łż¬hĄSšßŚwzµ=úŽ ĘŻ»IiíGüď4đˇŁű~š‡ŤGÎ".é˝hbQĆăF2Ť6ůsč^OF‹_6ňH"¶âčÍÚě=‚%»o qěĂż}'a ,ű:˝‡;÷ă«o6ăň•TňĂ“R·±Ąôřő÷+´Áí‹w c™˘)X ‡V çŇÝd-”ŘleÉą'¸„bMŘWxÁĎ ”ńWŁ‹|ňÝ_ű ëŢbÚÝ #ż Ăk=Ř"Ьő3ÂĆČíE,Üý)Ň:ÄwčűřŔž}•‡“‡P Ô‡„ÖŹý sG1mü3Ď ʰĄ/Óé…&·cľ@›žNśD3, zLžŹźÇ’ŹŐ‚` N–ć±ńÁ˙MŽ†ä ĽppÖ¬Z…ÍżźÚą Ć}0=ëJ‘ŻŞ…“‡ .ů“]ţľůţDĄČ:ötň  *ňËł`KŠUĎŢä»eľ'_™wZfȧ'eRtMé6é©<óŮҤ"ě°ň¬rúfÁλ1|éúňľŐ8ś×#Cüˇşü;-ř oÄ…LglÝH”-“'Kq*7őŐŽő“YëfmÚxcL¨Ź@łŚüŮ,­n×±čßÚ±G6áÇ ±ůh4¤Ťűbú«­Éz×Áą®忇°ź– QGÚx˘U3U\ÍęËÉVúMü…:CÚ2Ą_ŤŤ×#y“—«ÎęKаe”xAtŰÔĹHéĹbëˇ8aÁĽŻ¶^Ť„ŐćŤŰIńižĆ®–21ľłoŁ řŕě>ěÜ{'NŕýGFžŔÝ\[áĉ:ĺ®ŕnjÝҋʰ•!+˙ţIŞŘé%1ąËjĎÎŻ'ƿرGđÓüođăĆCPÚ`ęôáÓ„X "žPy™©ĽQÎe «Ď®Q t†ęú6śdŰlĄú$ńę˙{ăea¬ĹśŘ5Ë—ă·‹Ä9<Ů1%Ĺa,ÜzJ• ť‡ő˘Ăžt|uŮX¶ýžÔgcÄĆ-ŻżÜ v©‘Xţă,ZłŹrÖĹŘŹ˙‰zÄßnCŃŽćŽëűÖŕ{1î”JőÓ¸ŇÓ‘ÍŠäPp镢˝,ĽXąÚčÓ‚kń/=xđÁÁKŮ‚ŞˇLMFf3Ą${zĂŐ`•(ޤł˝Ř’ŐâSĎó!_nvjŞđ¨ż«k©Ł5%jyř†µý@‘[{Ş×űázłRˇ ?©]-ox:O×TĂާŻTŇąĹJb©ŚN„Ň9ćG;Đ;űťÉŹJł9ŮČgç)¤dýѦŚZ+ł§čYhrłťŻĄ49Ü)BM©9ěˇr»ČÝÝ S+¦0l¬ĘänKéH]ş¶f×,÷CĺE2¸ąÓÎ#mÄfoX]R:ËśžCÇLÉ_)st˘'ëJI›\ŞäćŹé!7ú­˛fTŠLĂĂ9Śđ*6prsŁÍ{5ÇË)a™ }–Ů PčĂÁ¶6ZÚЦ>8І&QW@Çůčő”*˘ Đž6édb(3ŇčČ"ml»¸ĂѶî3„#ڶŽ.ôm-aýhŢŔĄÖ,ż9/ţb’ŃZŽ„'˝Ž alî]ŽUÇđÎ!7n’%—W7őą¬Ŕh>¶bv§wĂÜą/ÁÎŚ¦˛ňWvś¤OÓ3r×Ú’Đž*_ É“··ě”Y–pZćáň9·%9Ďäś\®np c®*ÚĽU°ńT*野 ssH>IdíŚ2+)@ÔÖőHk1/6°xŔ6Kµ…’ug:JITĐoIiŁĎÄwv^"źöŔÄ2¸Ő˘ńJ’——eŘ0†dŽVŘÚ9’Ś9®ŃB:MgOËa)’Ë˝µJÉK~ˇD™§’µFÉ—YI ŽdJžýxHŐÄd•ذµ,YXZrŤ<e]ćÝápjU˘äYż™˘ËÍeo.á#ŔŕpŞ «”ň˛óŞoaެ­9ëC4v(; Ô±XřéĎHD±ňÓËđę›ăĐŇŁ"bĘ©ł‚čĽŘpĚ^-§łŁ<˛*¨˘ěä¬óřř«HLűě Ô˛Ü?ľ ’îÝŮPßĆ˙fýŽqźOź1˝ěŠ_l^üq|÷Óäŕ—úcÔż&ˇmE‚ ĘÇÖć@=ţ#ŚiŞĂĺ‹Iđo粖“˘<ěůt.Ôc?ÁĐrA”wźĎY[L‡!ÔĆŔrdĚ,źu—YŘřŃWđzg6zy䬯ćźĎ…dŇlĽŕW5rh˝Oę8!şľůtšżö ú74Mfz˘ą}Y=Ő!ţŇ%Zˇ®Ă2Ę"ó1ÄYĄäË_eѨK;%(řnăßĂ‹PĄ\Šď6ŕ§ßăż—U¤8Nć‹×'Ť‡1.)jVk&â‹WĘ€FĹa#{Ä+D:(!Ăŕiď˘ÉN›¨­‹±nŮAĚú°ĺ*ac/ô:"L$-K1+ ü«¨M[ŕÓ˙řPĹŞ¬Dܸv»»„Ú‘6ĆĐ­XľăfżX~EŹ-%ďSďńxűą@ČT)Ř·b6->&˙­{˝]_›xÓôw°~ËŚ úÍË҇˛†ţEbIąxëđÚ»ďTţÖîĹżÚS¦÷“F©‡ĽÜrŞ´“›pѧ?F’‚/“WzôŰs~úťż 'Ó$řWü»ĺžÔqBt©uş’<2ÓeŹ1ÎmÜ‚üIMńJ9˙ß…¬¦”·JÉ[jÉ«rR!r4ös‡ž’u¨ÝăÇtDZ\_Łö1µO$žX‡ŐWęŕßoôsÎ5,ůń,úOëŽ?˙Ť“O`ëă*čđ1úÔUbĎĘ8Żęî>fú7ŃC*ĘÁöEß"=)Ť°?ĆL›€–î¤őMˇD@/CťÚ. ş Z5ńơýh©¦řăëM™ă®˘ţÄŃ9űVo‹,>©G+Ľ2ik©q|Í \9Bl‘ ˇ#§bpŰ:4]ĆĘ%Ż˘fä;éU4"e#RÇŇ…§‘¤[ĹĽ1ąęPűyńg°bĺv$’Ë™â'ŚëoÇ<ś_‹-‘qŐ˝ĆaBź@a’(ęFĘ lżëMőÔ¦†ôH»]އ‚”‡ĐG¨7éö<Ô_ďAüfŐoÍçĄ#ž:ĐÁż.l>űÚč˙ęXäD@yuľ‹pĆ;Ż÷‚$ńľ]vC§OB \= —Á~Ř$Ř?mO`˙úU k–ěìi=łw67`ոۼگ!Ä2=Nl_‚č´$?ÝGż‰ţ-ÝMđŃ·-ńL8—ćą«iW`Ůú#$ hě‰\} ĆŤhŽčťŹćt‰ŰyĎ˝1Q˙”rxĺŠ Ń·ý«ŰšÂƉŔ(öÁč˘ üô¨ů÷šLAO„ú5€GÚ¬^¶Ý0ťšcüÔˇČţígD˛‚+WŁĂ§˘aYĆK‚U>y·%˙öuۡ1r°ňłŹ0߉ĎâGÜ=|*ň,_?Ůń'q;W„śŰ'§ŻCî®ßżű6C1Ľ9)ë€~čŘŔQkżÇńĚ Ľ3óSĽ1¸ŽoXŹ8ٍ}şăŁ™ďˇŹ{Öď˝U’FR‚R‘ż®^µ+Öbů’ůřî@†t„ś:ŁQ¤ Ť|Ŕđ‰xÎű~؉ŕ)bŢĽ™xŢá"6ş#Ěm9÷‘ăQď„I=ÝpjËd"ëľß€Ě6/cćÜ1¤N 6¬üChźÉŽwç‰ůţDÔą}ײ W\Ć‚ĹŰá=ôMĚťű>şÚÇÂĺ'w ›#30îĂyűŢËH>ĽGi0Ç:7ő)&¸ÓDÁâ˝»ŽÂ‡ď˝‰^Ô ¦č‹ňş6G'YÎÇçÇ™ńíúŤ8třp‰˙;wď–™·¨NłňVĹ9ř㹎Żú~±›vŔůž58žµë '.÷ČgťzăóńÇÔ§ÉÇâŹ.f×"ö„ľ¨Ż•ÍóôH|»ášŹz“pî‡ÜłWs%9ńóJO“[ŠČţdĹł6ĘĺÜѱť.\+˙ÇĘ«'iśńJOtŇ= %dOT č ĄNŤ«·!ŹĆÚĽys1¶ém¬]w톎@k*ĐŻ?ŘüY˘léşžňű*±äa[“>˙/oÝÄŤ›¸y6‘GwÂŁÓ«Ţ3„ě~ÄĄ5ĂŤ$IC' öeŢôhe‡-ד'˝C YűśŰ8v’\.Lô’Ż UL; lYşˇ]ÚbÜŰ˙OR[f–Kҍ뵳8´`oůT‰)žSxéY´É©ŘYٰA¤¤¤@«Ő ýµ··‡źŻo‰¶„„Jů°G·‰łĐ2ń®ßŚAĚŤ3´Z9‚Íî]1czg„`'bâR ż™9­ľb˘ď"Y{ đj[=.3Í.¦5ˇ»É…u“Ka1ušŚ6µ™¶+>|«ÔÎ6řńgt?ř9Rź;ő‚l˙6$ĺéÁŘU:~ž°gŮ6CY<Źż¸÷Á€ÖŢ´˘ňĆđˇŤA $H=*äU^ęâmxKYĆÖËâ%I¤dŕd+ËÄ˙±ňę 'r)fYy–<Ĺ zBo×z"¤Ý€•ŠÎn>3úŐ…ÔA gď’:Âj޸ÂgďŞJ,ů¸Ł+±toĽ·@Ď~Ă1ĺy>˛Ň"Ż!‡\śÓqh/YÂ~/`Äŕ–¸vô^•ŁSKď"˝ĆƆégJLă„y[صž†ťXLw,‚‚–¬A/–6fgŔŹľé‚MÍÚ·AP›6hݦ†OCΤDß7Xt¬–_K.‘o—oÄ™űJ¸4iŤ¶¤÷Y–f …9xčŢFl0ş¦i@ C'«—‰˘4¦FYĽĚ‘T˝âiJeů%‰ ]÷GŻ>ťŕZ»->ţ:w¬„¨ťXĽđ8źohËX«‡ˇło!Ňě^H§†QéĽě^bk S14jÔ"›2ó–UŢš¸ĽřŁřö‡4Q6FÇžý0öőđů†Ń tIů®hŃɧ÷ď'Ë˝^yĄ?D—Žb˙ákěĂŇHĄiţҲ˝ R±Úű°1DSŠ‘?äNĹĺ3»¦Ë˘PĎ ”¤xťěŔ«C&7Č–Ř˝b^±Ęőz[Á5oźĹł`Ç®Y(Çî'Żž¤qR #@"3eĹ39oűň:a0Ľ4÷°cíR|ąřh~/9fËÁ¸DťOi«”Ľ 1™4Tđďěb‹¸żŕh,-)ŻN•‰;·ď ŁS˘·CëŽ>ż§ćđkŇę¤kČ5GWą1P9ÖL¦€¬-4Ł˝×‹—c ŁČ”ó0Q2 Ć(čç­Ś4±…ťéÚřÍŞ©‘” ef&˛2Ópaď^Á˘öw·ÚZ¤:Ô9¨xKĽúň@tnV  d-P5f™Ě®‰,φ´bHÇ•´ ×â†/±hýyş.IŰdÁFęHÔ)áŮ8]»t‡â<ŽśË@őç‹EŃhÚĄ&ľ9 ”7=—¦•˘~éáŮ !TWn"ß,®.Ť¦4*o+#ÖšîK}׫[Ě‚wqq1üL©ôňĘYo/wAzňlŠř­ŠV?q ÉóoתřkP¸5B}ďFh OÂŐtg„4!_:ŁIĆo⡶Ŕ éŚâÂ%¤Sş.- _~żÓŤ‚`â˝±d±\Pć}4¦ł¸ňxîÔšöiNâJMóŞx„mąH[;¤źŰX!Żě]˝H梑¬,Ł]ÖsZŘ˝--YJÄ—{\Ľ yBĆI ,0MâŮÉÉÂŘMIKFJr ŠXž‰ŤłżÄ4Bż—'ŕÝĄç@Ëđ¤ fËÁöY‰'›Čň`€­âü.äŁ~)a¶­řОűaÄ´çA+(xwŁucWÚŚ#6Íî¶o!řČMmHčÂAîŃź›°˝Ý ô7 —~Ú„Y*l7rĽĹäĂ٢Řr'i°#ĹMYLő0s߉Ď»]&ZôŢ4ů_ ăěĹ™,C»ş-áG˝˙›y™ĘËP?ŔŠ?ÁŢ é`ô’)^T/µ+¶m€ńĂ‚ńÓ¦†Mň±ť }Ţľt0YRÚ;ß#k|Š0wÂ$žÎ)ܵźÍĂ™a®0—ˇ–^…Ť ÷ŕăĆ!řę"ĚźyZ¨Ď=x:ůHq¸ ţäBČhöˇ“RĄĹkĂľžlńĆöLÂúł í¸ęNNđlT!ŻD® ĐśÜoÉů:ęgńĘî!^QžËć%ĐbFbŃĺcăŐ4N_Š[5ëqm÷rú/Ží8fŚp#Ń»˘{ß@,ýĺKUűţ“ĆĽ®uô8µi)Z<Íě‹Ë>kW˙Ćkll,ä$äÖ]~.˛ň 7Š«Ó_CY­VCLĘČ0TÔP(éŢŢ fcÇ’,ČËÜÉTî*´ˇÉχ Y˝ĹCµŚ*čˇ/…ZÂç‘ůŚE. ť:rubşĆ‹ěô,˛@dpő(«5~=÷ž{BČŇ-'$ú‹şáó 4‘>)A—oŘ# ĺ*/Ńg+¤ 6µŽĽÔ€0s§hÄö“‘đ÷ĂĂ<×*bpě˛=z·“Üëż~†uφ5Ł;]ĽK*ŕ.ńf-NÁôącČ<¨iáaĚ*{śX.?‹tŤW¸Éż¤…If¬©ďiĘ[%–Ľ {G¸Ń? %ggSŽŠżmIÁł`(/%cĘüľâňÖçÂŵ¸ )xIżÔ^Řř­0źPąmăśW\ŻÎîĹC˝8ŢX¦Ţ˙„™ v!%d ‡MiĆo]6U`ä ăąůRÉŐvKĘŘÍ˝x’¸oP&–˛Kd4ˇ˛}ŮżT×CÍ=Ěs¶kráČzś8s nɸJ›đŢđ7¶WŻ€z˝Ç Ń' ™ŢŮ‘¨‡‚[ŽŇéť÷ŕFi•ÓŹ‡©Â‡1cŤ=˛VŽk·±w%]c(QL¶4”‹ď­©ńéÉk•%ďähPŘOO÷k^O”éé°qĄóÝeé f1+čPHYGJj^W«ťb˝: ·oĹ#ť|ëľA-ŕăTčĺ“©S¦C)6·,ÍóęEĚ’»»Z´ú3/ÉŻ9Ö Ŕ•Ľ5hńĽŽG †!PĄîš†'—#ŔŕÖxIEND®B`‚nipype-0.11.0/doc/devel/gitwash/branch_list_compare.png000066400000000000000000000246671257611314500231370ustar00rootroot00000000000000‰PNG  IHDRşL‚©4sRGB®ÎébKGD˙˙˙ ˝§“ pHYs  šśtIMEÚ0žŢ IDATxÚíÝy|uţřń×4I“4mz= -Zh©‚ ŕrÉ!Šş  ¸JUP\WPpńZQů Ţ TVXE[ůRŽŞP,Š-Đč‘6MŇóű#éEąeńý|< Ítćó™Ľ'™yĎg>óB!„â2¤¨ŞŞJ„B!ÄĺĆOB „B!$ŃB!„â„VB „¸Ö’cX]*SĚ&ŤD!Ä˙^˘kÍ]Áă3WBH^xe á€5÷ ź™ÎŔ‰Żs{’ €’­ 2÷; SßOŚď¸—»â%f®ĚC%űgĽL·P –śĹ<9;Ŕ[F\/=:‹J…÷ˤŰăd«qɲł­€>#n§{ôJ ăŤ÷×Bi9qýRxˇ¸|ÉĂ3ľ"˘çýLş#Á›ŔRBćŞÜÚ’Ę2×’?şĂ—Áž#ű!„?Ńí:°ąßd’úź­Ľ0ŔŘŕoů™ë(S GĘDVÎ"=w ŮÖŢt08€zt­fĂŽ˝T8Bů©Ú÷čÄ®ĚmµeT8ôÍlžÚämŐ±—Ůč7ée†&d+ qÉ0Ó©G i+óY0e_†ÇsĹUťň7’˘ĚµsŮ]ľK9NWí´ęüMd: ¸G #ľenz6™{-ŚJ2źvŮ7!„ř5ÎyÔ…N·roßl›>âëÍGj§«”°6c/¨$·iCűö-A)bíŹuó¨Zw¸ Ŷ‹­Ű·RL,]Ú…7(ß®ˇÍ‹‹#..Ž6ńm0d q©‰:•éFÓ-!{ń>2Ó—0{ú“ĽVݵöTö¬őöËżňŠxâŰ·`í·Űj;@ťŽě„B\¨snѵ: $ŽĽŹ¶3ČHŰ\;Ý“ż•Ěr”"ć>ý·ÚéŮ«ŔÚóvŔŰ/¬U" J‹RÓQ#†Ú¸ęČî÷2ţ–hŮ*B\˛l]ńŮ´ăŢIĎ ßńě?űÍ,0źb)Ős€µĘAĚ9SȬÝQl ·˛'‰gîp+ű!„5ŃUU; qŚŰŤ)fŐ%´ëh?ä~ÄűÖý{[‹ÖńÓ±[ P«ŃGÓ.r‹ ´} !„żß1\F]B!„—%éş „B!$ŃB!„B]!„B!$ŃB!„B]!ÄĺĘmĄ¸ €ceös_Är݇Ę~łU°ě%· J¶…B\´!ÄďeŔ€¤§§7ţŁł€/çIˇÖ.;Ń×ŢĘŕg-Óy|ßďkGbËßdK÷n Ăч„¨Ö˛Á„B]!„řőoZMat/śjÝÍ˙IçPŇZęęć)ßż‘Ż×n§ÂĄŮC®Á¤Ńă:śĹ˛Ei«ÔŇ®ç­ôJl‚۲ź´˙®ĺ°ÍEh«kÜż&Ożúš…•  ˘ý č‘‚˝`;_®ÚD….˙*7ĆDŤl!„¸ H×…óávSisbŻöH,„řMą(.¨˘Ub4Š)’hl¶úóXůqőÂo¸“Sî Iá~ĘŻBŃhŔi§Mź ëÓ’=ë·`ˇŚ˙[Ľ:bě}wvx#_˙X€ýP;Ž·`DĘڏ® »2¶c÷°bĹ& W fÄŔÎŮBqąÝstxű>ů˛r0E°ě±x~› Ąn ¬Ř€ &fšúK¬Ĺźę˘Â˘ ŃřZRU&­«Ó Ô´®šč~Ç`;Âć )R!PÝ´Q]éîv3Ň9QŇš| ŢUž˝ˇĺP© C×î ć(G¶˙HáˇĂ`l‹çřaJŐ6ÜÓ9Đ˝ÝfľqÉ&BË´čžS.ZĆ[5I. ü–-ş¶ž·“±©;ůô€Cb-ţś1±Fě6§÷µ«<—ŽĐ€z]ÜŤńßď<„ŰIl·ŰűĄÔ|g7 ĂYUŠ[5âŞ*ĺřńRÜÁmą*.â­«ůzőU¸‰lÓ nl6 hőµé´Gz-!„$ş.*6_’•ÔŠĄOţV­ą€QG_ŮAzi`^ţF8ňý6¬*Ř‹ °H`ý+ÎJŽcfĐđÁ\ÓˇĺĄN´šSgĄÚ°(ŚŘěĐ^˝zĐÜžĎ/'lŘJOÔa{]K$%¸ť` Ž÷^ö—X9śoC'_E!„¸,śuw®V[X¸ô‡ŃŃůĘPňłóŐáj4‘r[;nĐ—đîŠĂl*ňÄřŰŰqC”‡o–ďáĘ?n‰Á¤TńĹűŘaŕ¨(ż±Ů)jô°qÍnVuѦ} ÚVńćĆR Şš7eÂíńt ©ÉϬůzon© \ŕúuiĹ}74äT±ř‹}äTCpxż±[)ď|‘ŹhšÜŠ:™qáőŻN`WáşţIÜŁk°6®Ç™˙ívú^ÚËůr–˝"0ś±~ß6 ‹˙»ŹĹą6Ę…ŕÝÚErOß"«Ľeç©€™™»ŕhsFwŃńág9R ×ßԞ͵޸¤ďfU± }XSÜś˛]űyok%ú 37'jXôő!˛tÍY9ˇ5&ĺÖMKHôuCiwŕS>ţ`ßExý<ÖF›Ŕ VĽ˙>¨FBÍ {Öo檞'ďČ´hü˘x] –/~źďdč=ŃňŰP‘±ś÷w€1(\{ŘT~-;d“öŮű¬«ůžk¤YWńŰóx<ś8q‚ňňr Ć !,, ?żso§UTUUĎ8‡íţżÝäžkř3뉫)XüŻńN™öČőô WqýßĎ÷Ä®O捾§ju±`Ö&ć[O·ÂÁ,–L46Ţ™µŤĎO5_«VÝÉgł6űĘ ĺ“©í Ů·—A‹ŹyçiĂę±±|żť1k*xęÁëą)ĽaXąo7Cź8©‚0–MmÉÇg¬?Cu˙|5›ő§lľjÂĽŰáţS•ýD8˙đĹ|ôČ.<ŻoĹÔŚĄŹµĺŕ×›ylkuĂřš±ô±čłŻ›|_ÄŕŚĂ‹ŕĆRVb0dđ;ĺß«,vt&: 8ťntşÓ'Ą»•J·“ÉP×5ÁnĹćŇc Ô‚Ó‰ÓO‡N.«›&đ4ő !ÄŻwüřq<&“I‚qžTUĄŞŞ ???š6mzÎËť}Ź®Ą6)Rt&žŢ–q­ę·źyjT[îk靦RMÖ'=n¨i­UY·ËŔÝ%ľdUË_:źţâżż])íęűL¨Š…ꋎpëţÚD®[ç8>”̸6ľëśóYvXĂuW›|őUpЦRWY—±p 8p¨Ş6ńě޸©306އGÓÜ·Jýű¶ĺĂ[QyÖúÝTćÖ&ą=ohË’‰ťx¤ą7äJuĄÍâxDóÚ˛{öŚçĂÚR/ć§Š‹Š:üµ đ -‚’Dů9¬›—& ć3$›ĚŢ$8c’ ŕg0a®—äÖL3jk ¨-Kk2K’+„¸¨, FŁQqEÁh4b±XÎkąóę‰Öż[njMí,~7Źr†Ţ–ÄMmڏü+˙QA]‚IOޱŘđs ®ëMlŮY (A×`7ß|±ťĄ…`Đy[jN8MĽř@Űş7Đ„×î!xř¶2Vü§PÉ«pŕż·˘vľN-ôś8î¦UK#üâmáĚŘeařUa°ŢŠŞ¸ŘqÄJě‘ú7{Y9x˘’ÝyŢË’›aĘĎçĎ 1šĽG>›ŐÍ-ąŠˇńfš(pnB\¸†5kÎ^˙bygd(żäY15ś]Ĺě8^w#›Î_OB›š(G9 ´iF\„śç˙:¸#Źw<¬Y|đ¬ë6*:Tľ5B!ÄďČívŁ( g».NźěşÝç×Xw^‰n‹&ľţ«AÄ*°hę»Ęî>y$3·\éĎúťŐ¨Ĺedň}©·Ĺ´—p Š‹ü}6rë%uŠęá„§nă«z-:_˙ŐŁý¨.JmuőÍ]±»ŃşWąĐ†‡1€|ŇěěBN÷€)ѱĺTó}v1}ő÷í`Ćĺ8Á>k5Ô»äźWĺO]]§PΩ~?Ť†ďÖěgQ±(8uP•}˛sé+häĆ+k <§uB!„¸ÜťW˘[›)ő’3N?ÔVÇnÍ`çŔĘ+˙âKőŚ N ü˙xfÄŐh.“^2‰.Š‘×šřb}]_€Q]›ť5ĐŐőZ/ť§ÉíÚw‹˘ů¦ýUTć.ŢĘÜúŐŞZ"˝íÄ!±MHŕXí¨ɱ&ôŁŁBíŤb˝®<{Uű…Ô˙‹·™UUĘ5k3Í+«9Zďý¸ÜNřşg|ľlźĹĘ”¦Dwť‹ ţŻĆÝNŽ‹ _!ç!ţ(χĘwB\îž-•~¨çkĚ1(Jăýă /ĽŔÔ©SQ…űďż­VKź>}NQ‚‹5ĎĄđZF„uĺ;Z“ţÁ§¬y÷ ,˙fćVşž×-ĆúSNóˇŐhO9_B‡ÚQ5~ńgĆm@ÍP¶&ďč'ŻjÖB˘{kzś´°ÓÇuáşš.«Ć„×üŃHÇ `¤K żÚi˝ZźĄM_ő«ˇö˝ťCýí{Ć3 fk5Š?éD°ęťbÁ÷Ą`432ˇ.&ŠŐ…Scćé[‘PŻXsx(wÔŚvˇóĆEç»C\E¶~׆sŤŤB!~?ľÝÓýS…O?ý´Á?€W_}•ââbt:o‚4ţ|VŻ^ݸŚăy#ُ•Ĺ+ć0~ü$}>ť0ŕÇ%›qę5ĎNç±a˝éÝ»7˝űŚa^F.ŞŞb;ÎÄqŹńü+Ď1¦wo†Ťyž•+yîîaôv7łVîBUUö­śÍă&3ă•ÉôîÝ›[|…-…6TUĺxv:“ÇôńNó 7@U+I›ńNy…ŮSne\ęTŰ>?®vŢMŰuƸÔ˙Çy¶čž}Ý_«ş”§^ŮE–Í“âůřŽßĽŠňVJŞÝ ŃnüÝ›ćĎ\ż‡ă'ްyü đ4+ç˛;±« Őh0řű’p·“Â2˝–@Ý˙dl„¨ŻfÝ›ż•`q™“ÝĆöîŮCdTÔi˙ţ׿ţ•O?ý»ÝŢ`€ÉdbĘ”)ÄÄÄ`09r$ .l0 5g!CţäRY0ţJŞ*¬¸T@Ő`2ˇ-[ÍŤ'SN"ă§ÝĘŃŹfđß<¸ë­ŚŇ,cČÂғ”»<¤ţ'€~ŁGSöÍ"¶”$3÷Űą¸ŹĺáÔ˝(ˇŰĎFę’ Ŕp>]3i}ď'7¤ĎMëĹw/N#­4–ąisÉzt©{%”ˇOĎ$ţ›ű™µ5»žyśÍ©Ľ“v»ßZNĘÁgŤaaAm۵;ç_Ä® n2–oçůźmµ÷QŤĽľéE©)¸‰‰ŕ?đ{ćúýhÚäěM¨ZŽFsitD6ŃýOÇF!„>Â`đ^WľóÎ;Y°`v»UUŃét' ·ĺ»BěŻCuU{“\ĹMU•…?mˇ •1sŢćţ®Á8;˛á¶©dî(fl7o#Ű„Ź^ăľä}üôźL¶&Oŕ_OŚeŻů'ĆĚŤżŃ×µ"–7?™ëCÜ´±ÝÄ3+wQ˘™ČSŻ}/•ě6Şťžß<ž±ë‚qí"“ϬB!Ä9/vr’{ď˝÷2ţüeÔoŃ­Ŕđ×ŔËĎ0gĂÇĽ´Á;ő†”×™:(Ť#Św˙±“‡_]Ę?&ü€ÎwżÂ¤žQ¸¶y“Lo›°†& (zď t#'˙şyá lPb<ď)®h_ĆČčwXś6Ť!i‚Z¶™}yŢ–h%@5śqo=OÉßźeZĘ]„ÜřwÔ­ËzÖř¨—ÜÍhBá#7Ł ńç!7Ł5¶{÷n"##Oű÷űŋcłŮj9r$‹/`äČ‘ 毙·qv§Ĺă˛á¨va jFH ·Ó†Őę}Ě—NqQU­‚.f!ůä“cힲ<Ő‰â§% @Źâ©˘ĽÜÇS7_µŞA«óCăWŤĄÜŽ»ćoŐ•”Ö>•¶KÝ ÖrV¨rˇ*ǨBG—ŐBąęˇ¦­V‡»Ş‚rŹOýU«.ĹZť.ü´:üüy~:kmń ąĺzŠ7.gÎôť<ňú«tŇ ŹčĘQ*ú\3U=Âěął™řć\Ě2†BqIůđĂ ¸¤×Qߤ­4Z\•¸<—~L]˘ë.fŐż?`yVž7Ëď1š±czäg}Áű©iŁśĐ‡ńŤ„ősIW@ÉśÍ{Q“y¨_Ý­jŽ«xésxjŇ LJÝëÉOŢȶo˛E‰F—ű?ىí6ś‡Rú¸KvđďŮ©dŮIčŃě -|eX·9gP¦€!˘)Ź<@;kĎľ–‰˘Ŕło4ĺŮGÁÁďxoÎrË <ˇ7÷<8‚ł°°náű,ĘĚ%$¦qŐeÚ7#o Óf¬ôži©ř«ľÇń:ŠŘU¦2`ňă ŤÓ ö‹gď3Ůţ‹…ęµÉşóYřňG8â[Rř}&ů„3äîŰĐn]ĆňmĹčc{đäÄ1„W˛w?ÜĐ;‰«çđńˇpZ–n"3· }Bž|t$1j>©/ľOě“écG>ó^Z@ÂŘ‘ě{o 0ëoňäż%A[Ŕ—óßă«mE¨!1Ü>z7ulîRÖ-JeQ¦÷ÁÉÉ7ŹcÜ-ť%ŘUyY|4ďc~*˛>ś>w>ČČî1l]Á»­¤Xz\KѱîšpQ+™‹ßeaĆ>ÚLáţŰşa’ćß„ŰZF±Ĺ†14śCĂłkÁ^ňÝQ$FťCAeěέ¤Mb4őGr¶ÎĄÂÜŠ泏ďl-ŘËQ˘/ŇŐ!„řßs.]¬VëĄ˙>\NŞ˙ŔžŹ_5ĽXî’Y–UÎđ‰“™<á/۰%YĹ`Ďáíyé´ţÓ§ŽŁun3fKčW«Ş¨=č“Üp( —˝ś˘ÜrÜJĂ×.śîŰKvfΞc™<áfŠł–đ\ęVTĎfMy‡MŽ$R&¤‘—Anm‹2hqŰx¦NťČuúmĽýö׸ÓÜ7ˇź+0”fńôŚk;ŚI“ĆŃ"?צ-˘7Ys¦ńń†|úÜ3Ž[ÚW˛­ô§x‚±>n(sçÎĺÍIP•ş§™¨ú`ÚęŇć/bknßĚ[H™C×Ö  Ő^ÉŢü<˛ÖüHÇ»Ç1$ľš•©sY^‘ĚřqĂ ÎŰŔĚ/sp[óŮľ±ŕ˛%?+ŤÜţLHąăŢ Ţ^šęŞdoQ1…•n߇±’ÜÂ<ňl&®ÜU5pĂĐD,,}v:+sšrĎß'qWr5ËŢťĘę%[>cŃ c&MeRJ˛żšËüm–“żŠ|ůŇ<~Ň÷bŇÔ©¤ôoĆšo±Ă UV0}îJô×ŢĂ„»®$sm&ą?oç¶/~žk3lÂd&ŹČ®´Tž˙4Gö~ż{ÁVR?ţŚU߮⳱˝¸áĺ‡ă»Ö˛~Oéąć<Ćwë÷4šl9śĂŇs;…/Ý»Śť…˛a„Büa~U‹n“«ď枎ńôH Ća#ěŘSÉ5sč05ż’ű^žĚőĹZ‚ŁĂą2t–«®%ńäV_‘Ć×ZűP jňí×čČäQůç'Ů÷4±W5đČłăé`‚®Éaě}řUď‚Á‰Śý0]{vÄPmˇmëÖl´â2EŃăšýŕĎ bŘżôltă™”A„±“ďbŰôEě,čCÎ6;Wß˙#»…ťQ?ČÇéăá:éµB8íÚ«dnËdîLďŁô0tĂdlŘ|©řŢşŤ˙'C;‡ánvŮyěŃ‘$éÁŘcďą­®vŁ)ŐÔaüsL?4€˙ž˙ă=g]YÚ“ĘÖ@bŹ.„.ÚF—>ťŃç­ ­ FLO÷Ôöʰď»i¬űţÚřEŹ˘ŐÓşŰH^ mOY`ăŹÎŐ÷ÜEǤkIÖRbŹ•‡8´)†3eTw4ŔLC9OĽłG._¬)ĄŰř ęÄ1uX/|łëťIŇŞű«¸řqŐŹ´č9’›ÍXsżâă›h—ŇŁvüjŤ>v­ć“Ł.*ŞŚtč?”k[‡€»Ś¬Żżć§‚J ˇmč;ôF˘5ţp”UËRxĚFh»ž ë•FcŔ_Łâ*Ř̲Ěô®ăV@»ž·Ň+± ö‚í|ąjş@ü«ÜĄŹŚBÔĐh4x<üüü$Ŕăń ŃśßqĺW%şZllś3™…öş %¤S,·ôH`Á’Ůl[„$0ěÎŃtP\Ţd°Úuö˛k.˙ű„†7©ý=¬e°C¶Î t!ÚT“ÔEŃÉV@ă§Ądűç<ľčÝşBCüѨ`w¶šGăéQČbÚ¸¬ős@…NAuťi#˘Cţ!űĆ +IDATá<®(8¬ u›Bď”éŚę…Ł ‹§ĎăÓŚLęÓ`ŢjU!Đčí`÷=łOqŞ WĐę Ťú;c›Vµ}ŚOžG©×űŘ_©)Ď;ÓŠo,yńo,©Wn¸ÓEÜM÷ĐmóLĚĆ "ą#ďNnôţl–}¤NYDM¶˘F ŁŠśme®jQ»~FďIŤęvaA!R[÷± OL‚eű)ń€Ir˘ ç>Ć1§‘+bĽ]bL­Đ¸ŹP Ô˘H§7Ѥd3KWŻ"úľQT~űŰ4×rwJ[ň×.âëe›ąox8.Ő†ˇí`FuŻdůňďŮ×µ–ă”5qáňŻ˘´´NďäÚĘŤ,_ż…N W’¶b†.]É7Ë×c—-#„µ‚©ŞŞÂd2I0.@UUÁÁÁ'ŃŐ5šÓĘWo/boŇpž}=Qfřň©Çů®ťâ‚PJŐ6ÜÓ9Đ˝ÝfľqɦBÚĆťđp ),”n]"44”đđđ‹čŞeěű9]@]Behâ}†qËŃD™MlYĘWeâtâ<ş–3×2zęëôJ茮8‹ôějиÁ®bł–`Uix©Ú ™¬Ëą•›[á˝y[ ô&ob¦űÚ/ČşńIş™Ž˛ôă­(ÉŁi©Ö˛"=‡Gµĺ—Ő_‘ ´\NhJTó0(ŢÁâŹwˇ„FŕP@ďU±RRĺ&"®-¬ů­űĐ/ÁÄÖĹ&˝5‰«B!cá z=3’°’ďřxCßó®ĆJié9ÜwS[¬3Y[†EźÓňŐĘů_ËW 4SŕĐľ8:´á‡ϡL©—«eĚ+!)¶=ĘŇ3łéx{g¬ą«9w9Ý&\I×Í/ňöŽ>ĽřúH’şöä@ú2ňOα­TŐ@lëćuÖÍ˙7Ą¨Ř«ˇMűÔ%˙a]ß©\|”ÔY(Dŕ hÁ5ˇ¶ Ť^So'ʑÒĎňášÁŇmá×2D«Óáđ] qĎÇFpŁŃ5ęźLůůk1™śv©h]JŹš0Úwm?*c ·+.Ü*hN’N«óîq:\6 hőµ-ů Ťűó!ÄźźźÍ›7§yóćŚßÉ9%şfTVľ?›•ő¦…ô™Č˝ýÚłvĺlĆ­ôńtKaÓ†TöÜţOnŽßȢg‘oţ«†O& 3‰˝bIK[ŔÓţa Z’ú20&•łźd%zňZä“:íQRHfâ˝˝Đaň¨f|2›‡–ŞPĐŁ!¶ëŤ„|łéŹ ˇslËŕ•Ĺyľ{S2xáiłßĂ_÷ľČ‚™Sj/áyl z3­źHa˙ÔyL4Ă—EB„˙YMµîB±>n0‡ěgöňŮl[î‹[çáŚęvŇBZ̨赚ĺ}[§ţýíŞ±ń´Ż51Ü1Ľ3–ĽĂŁi@H`GŻŐ ‰3Ş,{í9ZĚzÇ& dĘ;s˝ó=R¸·Wł"˛ć1íaßű&–”±­Ôçw }#WđÉôGůIčD¬~ó¦/aÖóׂŮ,ń$‹€#`oN¨Á̰'Ć‘3uÓ}•Ş‘=6¦ł|-UC ÎĆ÷›óHęŐ’˘ĂĹÚ¦ÁđyŤ÷Xh‰ąürŞt nFµVˇ¸E'z$š±XË6ŃĄ}8JµóĽVÁß îMě/ëA»+‡ómčd_.„âô«ě°”bui3ŁÁŤŐjÇ`2ˇ,%EX &sĚő:`:´zý)ưuSQRŽŞ®7ż•ĄO=Φk&ńŻaÍ9Qć¦IąÁ˛nk '¬Öp,·•’ăô!aôŕ¶ZqLč5ŕq8piµřű:5;,Ą”ąTĂöu[)=aEŽů°u[+8aµÖDxŘďÓ/Ça±`ECŮÔ(Ćčőľ7騢¸ÜŽÁÜ`â‚Ü=a'ǵ^Y–’㸴!„™őŕ®ĆęŇ`ĎŰȦŁaÜŘ+ =P˛uSć„đúÜ‘ľ–[ĄĹĺ8Mš™‘®ąż wŮn>ýt=• ¨„pÓ=#hYŻnÁĆ%¬ŘQ7ęBd§›ąĄk ěĹ;X˛l#6Ĺ{îŰečh:‡eŃ’ĂÜzwOLŘÉśż÷ŤĄŐľ/Ř7ŚîšX¶'ŽQZó çOĎ{FÁOꑶ٬¶ŽŔöÝŁî FÍ#€ÓÓÓe !„¸ôÝ‹ĎĘâqʱ¦Ç#Ľ?¦l±˙–ś<9ű;ÂŻČő‡Yž–Mü°I<9(A‚sŃł];evŚA!čOsá´[©ĆÉPŻc´Ű‰ĹZŤŃdB÷+Ď<\V 6M A†ĆŻ%ŃB!‰nĂ#7ů[3)íD·8łl±˙ĹąYdnÜÉáR' =naPgą†-$ŃB!‰®B]!„B]!„B!NEF/B!„’č !„B!‰®B!„’č !„BńŰ:ë“Ńöďß/Q—ťÖ­[˙!őĘ÷I!„řýŽá2ę‚B!„¸,I×!„B!‰®B!„’č !„B!‰®B!„’č !„B!‰®B!„DW!„BIt…B!„¸”ý h«E$IEND®B`‚nipype-0.11.0/doc/devel/gitwash/configure_git.rst000066400000000000000000000057631257611314500220050ustar00rootroot00000000000000.. _configure-git: =============== Configure git =============== .. _git-config-basic: Overview ======== Your personal git_ configurations are saved in the ``.gitconfig`` file in your home directory. Here is an example ``.gitconfig`` file:: [user] name = Your Name email = you@yourdomain.example.com [alias] ci = commit -a co = checkout st = status -a stat = status -a br = branch wdiff = diff --color-words [core] editor = vim [merge] summary = true You can edit this file directly or you can use the ``git config --global`` command:: git config --global user.name "Your Name" git config --global user.email you@yourdomain.example.com git config --global alias.ci "commit -a" git config --global alias.co checkout git config --global alias.st "status -a" git config --global alias.stat "status -a" git config --global alias.br branch git config --global alias.wdiff "diff --color-words" git config --global core.editor vim git config --global merge.summary true To set up on another computer, you can copy your ``~/.gitconfig`` file, or run the commands above. In detail ========= user.name and user.email ------------------------ It is good practice to tell git_ who you are, for labeling any changes you make to the code. The simplest way to do this is from the command line:: git config --global user.name "Your Name" git config --global user.email you@yourdomain.example.com This will write the settings into your git configuration file, which should now contain a user section with your name and email:: [user] name = Your Name email = you@yourdomain.example.com Of course you'll need to replace ``Your Name`` and ``you@yourdomain.example.com`` with your actual name and email address. Aliases ------- You might well benefit from some aliases to common commands. For example, you might well want to be able to shorten ``git checkout`` to ``git co``. Or you may want to alias ``git diff --color-words`` (which gives a nicely formatted output of the diff) to ``git wdiff`` The following ``git config --global`` commands:: git config --global alias.ci "commit -a" git config --global alias.co checkout git config --global alias.st "status -a" git config --global alias.stat "status -a" git config --global alias.br branch git config --global alias.wdiff "diff --color-words" will create an ``alias`` section in your ``.gitconfig`` file with contents like this:: [alias] ci = commit -a co = checkout st = status -a stat = status -a br = branch wdiff = diff --color-words Editor ------ You may also want to make sure that your editor of choice is used :: git config --global core.editor vim Merging ------- To enforce summaries when doing merges (``~/.gitconfig`` file again):: [merge] log = true Or from the command line:: git config --global merge.log true .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/development_workflow.rst000066400000000000000000000173751257611314500234370ustar00rootroot00000000000000.. _development-workflow: ==================== Development workflow ==================== You already have your own forked copy of the nipype_ repository, by following :ref:`forking`, :ref:`set-up-fork`, and you have configured git_ by following :ref:`configure-git`. Workflow summary ================ * Keep your ``master`` branch clean of edits that have not been merged to the main nipype_ development repo. Your ``master`` then will follow the main nipype_ repository. * Start a new *feature branch* for each set of edits that you do. * If you can avoid it, try not to merge other branches into your feature branch while you are working. * Ask for review! This way of working really helps to keep work well organized, and in keeping history as clear as possible. See |emdash| for example |emdash| `linux git workflow`_. Making a new feature branch =========================== :: git branch my-new-feature git checkout my-new-feature Generally, you will want to keep this also on your public github_ fork of nipype_. To do this, you `git push`_ this new branch up to your github_ repo. Generally (if you followed the instructions in these pages, and by default), git will have a link to your github_ repo, called ``origin``. You push up to your own repo on github_ with:: git push origin my-new-feature In git >1.7 you can ensure that the link is correctly set by using the ``--set-upstream`` option:: git push --set-upstream origin my-new-feature From now on git_ will know that ``my-new-feature`` is related to the ``my-new-feature`` branch in the github_ repo. The editing workflow ==================== Overview -------- :: # hack hack git add my_new_file git commit -am 'NF - some message' git push In more detail -------------- #. Make some changes #. See which files have changed with ``git status`` (see `git status`_). You'll see a listing like this one:: # On branch ny-new-feature # Changed but not updated: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: README # # Untracked files: # (use "git add ..." to include in what will be committed) # # INSTALL no changes added to commit (use "git add" and/or "git commit -a") #. Check what the actual changes are with ``git diff`` (`git diff`_). #. Add any new files to version control ``git add new_file_name`` (see `git add`_). #. To commit all modified files into the local copy of your repo,, do ``git commit -am 'A commit message'``. Note the ``-am`` options to ``commit``. The ``m`` flag just signals that you're going to type a message on the command line. The ``a`` flag |emdash| you can just take on faith |emdash| or see `why the -a flag?`_ |emdash| and the helpful use-case description in the `tangled working copy problem`_. The `git commit`_ manual page might also be useful. #. To push the changes up to your forked repo on github_, do a ``git push`` (see `git push`). Asking for code review ====================== #. Go to your repo URL |emdash| e.g. ``http://github.com/your-user-name/nipype``. #. Click on the *Branch list* button: .. image:: branch_list.png #. Click on the *Compare* button for your feature branch |emdash| here ``my-new-feature``: .. image:: branch_list_compare.png #. If asked, select the *base* and *comparison* branch names you want to compare. Usually these will be ``master`` and ``my-new-feature`` (where that is your feature branch name). #. At this point you should get a nice summary of the changes. Copy the URL for this, and post it to the `nipype mailing list`_, asking for review. The URL will look something like: ``http://github.com/your-user-name/nipype/compare/master...my-new-feature``. There's an example at http://github.com/matthew-brett/nipy/compare/master...find-install-data See: http://github.com/blog/612-introducing-github-compare-view for more detail. The generated comparison, is between your feature branch ``my-new-feature``, and the place in ``master`` from which you branched ``my-new-feature``. In other words, you can keep updating ``master`` without interfering with the output from the comparison. More detail? Note the three dots in the URL above (``master...my-new-feature``). .. admonition:: Two vs three dots Imagine a series of commits A, B, C, D... Imagine that there are two branches, *topic* and *master*. You branched *topic* off *master* when *master* was at commit 'E'. The graph of the commits looks like this:: A---B---C topic / D---E---F---G master Then:: git diff master..topic will output the difference from G to C (i.e. with effects of F and G), while:: git diff master...topic would output just differences in the topic branch (i.e. only A, B, and C). [#thank_yarik]_ Asking for your changes to be merged with the main repo ======================================================= When you are ready to ask for the merge of your code: #. Go to the URL of your forked repo, say ``http://github.com/your-user-name/nipype.git``. #. Click on the 'Pull request' button: .. image:: pull_button.png Enter a message; we suggest you select only ``nipype`` as the recipient. The message will go to the `nipype mailing list`_. Please feel free to add others from the list as you like. Merging from trunk ================== This updates your code from the upstream `nipype github`_ repo. Overview -------- :: # go to your master branch git checkout master # pull changes from github git fetch upstream # merge from upstream git merge upstream/master In detail --------- We suggest that you do this only for your ``master`` branch, and leave your 'feature' branches unmerged, to keep their history as clean as possible. This makes code review easier:: git checkout master Make sure you have done :ref:`linking-to-upstream`. Merge the upstream code into your current development by first pulling the upstream repo to a copy on your local machine:: git fetch upstream then merging into your current branch:: git merge upstream/master Deleting a branch on github_ ============================ :: git checkout master # delete branch locally git branch -D my-unwanted-branch # delete branch on github git push origin :my-unwanted-branch (Note the colon ``:`` before ``test-branch``. See also: http://github.com/guides/remove-a-remote-branch Several people sharing a single repository ========================================== If you want to work on some stuff with other people, where you are all committing into the same repository, or even the same branch, then just share it via github_. First fork nipype into your account, as from :ref:`forking`. Then, go to your forked repository github page, say ``http://github.com/your-user-name/nipype`` Click on the 'Admin' button, and add anyone else to the repo as a collaborator: .. image:: pull_button.png Now all those people can do:: git clone git@githhub.com:your-user-name/nipype.git Remember that links starting with ``git@`` use the ssh protocol and are read-write; links starting with ``git://`` are read-only. Your collaborators can then commit directly into that repo with the usual:: git commit -am 'ENH - much better code' git push origin master # pushes directly into your repo Exploring your repository ========================= To see a graphical representation of the repository branches and commits:: gitk --all To see a linear list of commits for this branch:: git log You can also look at the `network graph visualizer`_ for your github_ repo. .. include:: links.inc .. rubric:: Footnotes .. [#thank_yarik] Thanks to Yarik Halchenko for this explanation. nipype-0.11.0/doc/devel/gitwash/following_latest.rst000066400000000000000000000014761257611314500225320ustar00rootroot00000000000000.. _following-latest: ============================= Following the latest source ============================= These are the instructions if you just want to follow the latest *nipype* source, but you don't need to do any development for now. The steps are: * :ref:`install-git` * get local copy of the git repository from github_ * update local copy from time to time Get the local copy of the code ============================== From the command line:: git clone git://github.com/nipy/nipype.git You now have a copy of the code tree in the new ``nipype`` directory. Updating the code ================= From time to time you may want to pull down the latest code. Do this with:: cd nipype git pull The tree in ``nipype`` will now have the latest changes from the initial repository. .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/forking_button.png000066400000000000000000000314441257611314500221620ustar00rootroot00000000000000‰PNG  IHDR]Vl8EŔ pHYs  šś IDATxí]|TĹöţv7›Ý´M‡„N]&„O ¨Ř ‚X˙‚(ú¤("‚}€`@z!Ň!@¨$†’ I6»ÉöÝ˙™{wÓHĹ ™ń—˝w§ĎwÎ|sćĚ,JlŔG€#ŔŕÔŇi…7Âŕp8śtą"p8D€“n ‚Í›âp8śtąp8D€“n ‚Í›âp8śtąp8DŔ©ŰŞSMY­VÜşu jµşNŤ»:ëĺĺHĄĺŰ÷;ƇęЦš­Ł22“đ{şwG(7oŢ#77·»ÓŔ}Z+»6žźź/®źź_ąŁĽź1ć8”+ú{2±˛2+ß”¸'‡öĎčTnn.\\\ţť˝‡z)‘HÜ~…űcŽCEŇż÷Ň++3î^¸K˛łX,`B`«UC€áĆđ«(Üďs*Ň€{/˝22ă–î˝'7Ţ#ŽGŕ>F€“î},\>´ŇČËËĂ«ŻľŠĺË— »‘ŇsÝż±/^űăˇvŕî…»„;s+p×Âť[ěîcFşĚ5ÁnGČd2Íć{VVŐŤĂ™3g°hŃ"A0“'OF»víîٱ߹öÔnÉŠdĆ-ÝÚ•ŹĐzzz:¶mۆ9sćě=33łÂžéݬCż~ý0~UˇŐreő$!nőm…ĺď,WŽěŔŽ#q(ĎëšgďŰÝëÇťőžÝŚX¶l™P844´\K7nÝ'– ă˘USÖ˝Űý__­äÎú\]Ą ĆÎę\˛d 222ĘĹ@h[źô/ŽAżaă±îdrů]3\Ä»TnüJ¦ź„ĂëýŃoüŞ8äaÓ»%ę&Ľ‡ľţ5ÎÜ2—_Ť¤VNß«ŇnéV­Şä­„Ą«Ńh°aĂ9rţţţ0`€0vďŢŤM›6 ýé§ź.óڙ٦z$“şÂ])‡Fg,°Z¤n.P:Ů 3UĄÓ•Č+1áô7s°Bňőo ›±ô‰ał÷MáĺMý0V˝•9€¬ĆEG¤Óéđí·ßâęŐ«3f úôéS`ĺ–fť ůBqź¶]ŃŢ_Ľú—w3ţ4&k%ÇdAG»=ÝĘpS‚„„*­V999;w.ŚFc$Ěâ˙ć›o0}út¸şşčNANj̈́›B§ăá!@ö<ŤE~‚Đ=«ŃÖąŚĺ—úžGĺ ‚~ĘÄúőJ¨k6hubCˇ}ź@#şđ“S1»đŢÔöŘ˙ă@H­ŽŽÔÂł’ú^¬gČŚ“n1´jîË•+Wź"› AAA5kŘ˝S6ůű÷ďŹĎ>ű |oŻ˝öZ¶lYö¤`Ý–Ü>•ö,Ŕ´u©hÖ Ř˝ëĽőŔÄ™ź˘}Ć&|˛đ~4ĂšÄ`ć{óa{h¦Ťi‹˝_}‚UęÎóĺ(dí]†ŮłĂDŐ7ę4ă'ľăî™X®fm­Ŕű Z`ÖÝżťňÍóµzd Ţš0Ô¤¶/źđ{qŮ«!ĆLś‰qý‚í)5ű(J¸/Ľđ‚°Ŕ1ű+Ťp‹öîĹ©Kđ|K+¬ÉbŐ§žĆŹÓ>Ćşł9BÖc>ĂGăúÁS‡ďŢťôfDNÇţD‹™?Ŕ](§€fě[<kĎÝŔc¦c\ÍÜŐwviÁ‚prr\*씝6v†ÉTţęěJŮ%m‡ăżłźÔbĹů%/á•ĺQ8—`„[ÜBLÝjŔ´o?@ eöýw26؆cŢ»EĆ'6Węť  şáÓů_˘ĄŐB8'áÓźÁ^m6@m¸˛_ĎšđA‡'|ňń„%=s§}‰]±jô8HŤGýǦ`âŁŔwgŔđŻiřŕ©ĐÇíŔ»S¶bČśy Ż8ąę|µb7r$*ôů&¦Śľćtěřá+ĚŮ|NčcçăđÎ;#pí—Ź‹ëűřžP”:ŠĘGJ+ź•ç¬.™2«. ÷˝÷ŢĂ”)S••…'ź|RHcď_}őŽ=Zń6P(QřˇKż‚ŘŘUďN€śäř|úN¸6®ŹŘ¤lŽĽEäqb’ńçĆsĐ!»öśE˛S0nlÇ"\íCo૯Bvn>ýlB{áo6IBŃ˝s#Î-ĆF¸!#đćŘľ=° ď̇D*βÄÉč˙ţ84ÉIĆęĎ!ÁVóë<łč.#\¶¨iµZÁĘe?`©(l÷ ¦6 Ó>üÎŮŽ›š«;ä pOřoʼnUźăťĺ— %/ÇÄŕř®Í8. D/8˨÷Řöă»vŇnŻâ­'[ÂUH¨¨őż—ţĘ+݇†ĚwÍĆĘ–-đ_|ń…@´l1bńźţ9&Nś(rY-Ú47{=ŃQ‡±/ň˛ÍWĺ[n4’b˘`vq‡‰=ýb,b®¨ˇpu&=©\°Iâp`g8öíŮ‹Í+V!‚JJš@©ŹĆGc?ExF(>1JOâË ď 2/s˙óˇ@¸ŹŹ~λvářąÄäHŕŞ4ârl.Ó»í-¦,Ĩc‘#U"~ĂT|´bBÇ˝Ź©zŕDŘ—LrKŮó“@¸ŤźŤď§ŽÄŮ]+đÍÖd·)®ďž®ŠJŹ©¬‘×ü («'÷Y<3nʲ JZLé‹ćeÖ›E;ě)yčc3Qi˛XŠÖÁĘŠ†Yc,^őşąçA˙ç>,Î#Elů ž%âüíÂIś—_›ÉŽĆ™HśŁB#˙ý <šńő$ŤŕW»|ú,®S.‰‡ ˇF çšqFőž{Ľ-.-ř’Răű…ˇ—§=şźFެ”Š?„zGżăzy˘ĂÍă˙s> 2Č­ą0ŠťŰ.ĺł‚dˇËSrĚ%«b>\fá1—‚ĂÂeŰigggĽýöŰĺ’ŚŁ®Ü¸hÄçąÁ¦MEžń(ňp†Ź]ŚĎ_î«© ÷ŤÄ¶C`zµłPĚç__c÷gŹA ~±‘ś˘ÂđU%µť€%äă•YtČ5”îšq´ËžŐĂéÓ!¦kl—Ĺ;HdiL׿—ą\.äľ8>n±÷Ä0Śy:Ě ŻaPK%ţ:`#"ň€łDJ.ś])‹ęb‹Ť#P|ŃŔÚcěń¶l,ť:ĄhŚŐćčŐ‚NB"C^~.n,"NGśŔ.zc2řjb7XƶĹ“ % ^ćô.Ą Ôn›JŹ?DKVfĘĆć,´—´óô/S‡)]·.˝Ű`ÔëÓńě: ‘2= ő]˘§EŞÄX„‚E>ŠŹ´H‚ý•“îíÜőÇ{ Xşt©`qíÜąŚćĎź/űéđž={„~xxxŕÍ7ßDűöíoŰ*|ęÁ‹Ô]k÷=˛&Łč‡t’‹˘e“ANń:Ťł¨ŕÁÁm¶j>:E–ö”O![ń¦N>Eµ…ŕ‘üqóÔwřpţJx… Á›ĎöCź­§qťÍḬűlRRňőĺč4TĆ‹¬ ňk ÂŻÉŚr ôŃ‚TşŇ˘ŁŰRF0rúŹ,z«©pîÜ9pGŤ%¸ń4oŢĚo~ęÔ)ôîÝű¶®dßžűn Ć…* XŠ攝DĄ4TČa3ë É'­§XJB%Qů±ęˇÖj`.đKPžË‹°9ęi ŞŮM&[°Yp¸Ř{yq,ý¶ĐřY¬\0*9a=ę!Čß°a°ŹON:`ËĎAB,•l"–®€m°ťÓŹűW ›—r˘~ĹŁcçaÇÎÓý¤h|ř4$ę” Ůăď`Bo3‚Ýó±– {Ře 5;¨ŐQ#m.ś™ć“Ź81ş0’˝IĽ "'S3Ľ3~Ě^ĐfČÓah†#1Ń8˝m˛°kSśp`rGZ¨Ř(D}×ĘwĂo¨ôo5+ůŇűp_Ć +9[ÍKůcÖ;9ź1czőę…¤¤$Á­püřq>|ě*OJJŠĆ\ ÂuX*Ž:e> QŹě…ë+ßĆŚµá8˛c1>[ő©f(hî^Ě de 7Ň6´éŃŻ÷ű=‚.]Äéaë6íÉ yăę_Bz÷áϡg#3.Ń7 Í1P-FbM‰&'c3áĐz…ą ¶ŕô>î5Ľ<ë( /^Ç K¨’j(ǸO1wŮźŽ|e=Ů?6”ťM~A ěßq`—l—Ń©S'!ŽąXYJ­ĂN&&“¦<µđŹ©Ő9ČsoVCÔŇĎńëÁÓ_=맨s-? !:bsÓ"Ž“á. ťŚÝŰż†˝Ď›´™´/µÍRô…ДƫÇQĐ‘Çńť=Ë‹s¤ OťŇNÇÁŤüáSĎŢ.€V“‹M>Ś‘tŕ×°}ŘżúÁeş"±_^‹ę5^ĐľÁžMNÖ¸.W ř6C'ŠË:źep[Á°Č¶)ÚůČoÁ˘ĺŰ mĐ]h ——ÎĂúc'°ú›˙‚q˝Ě&˛iI>Ű7`ßń=řáëp!šöxhŢVEφ2€ćH°GĂa{T*ŽĎ{ӾߊVC&ăÇď&ő¤iɲv.¦ďĹp)2†’ńbĄrŇ-—»Ë—Y±ĚçĆükĚâ:ţĽđÇNŐgĎžŤ &y @¬L±  ÁW?}@+ÁÖďČç8w4¤ĺsщ¬‹…fF‰ 'ŕÚ˛3úS9HF›@O4í)äđŻPZMhÔý1QĚž™Ł0řŐ p÷˘ĽQ!E/GýŔ زö`ňsađň&^~Č—ĂfâÝ«ďÁXľh4|]DŐ7pT‘íöľ”čZµŤŠŠÂćÍ›…z/^ŚÔÔTÄÇÇ î†đđđ˛˙53ű‰‰“ĉ,Ä"{e[CĽłđ}´Ą#ĆůĽ‹™+N!ٱvr_b\ \*w2˛l%7=úâÓgŰ›„aáÎdaRí.ŁÂçź^H7n\AŽŇâ ‹ľŢ—Ć$ň ›-‚ ÂLj,´đ::SúžycúŢr67Š'×nApč_A˝¸+YĺĚ'AŃâ“>Éśáó0|1ާWâĺgÇ`ΆH<öÎ'x*äAüß_ČţëIS°"ü†PNřđĹkc’ŻoÁÇ“f!»“Ř#&Çľo,Ä‹t(±ręË3i"mŹáă7ŃÚ{č 5ľ5 ĎN\Dó"Ń›R"G˝"úž_ĚgRŘdUŢřż2V´Ş—ůÍŠśŢ–SÖqIź=Ű?¶r2’eţ¶ŰȶD]R‰…®ÝŘhűe†“w ĽpMyhŤZ©=ĄĎ#«Ďh•ÂÝÓ“&»‰¬6-¬¤P*/wň;Růě\Ř\=i»&…UŻZg&˙ś&‹3|ü=)łLČ5@mĺĺh`“+ §­ť‚Ľę =žŮóRąĽ\ÚV;ąĂÓŤZËˡľP˙ŠőĄÄ J|MKKCHHH‰Řâ_+ń믿^PhőęŐ•©˘ÄłrĺJ@JúŮ…Ä>K ĆŕgO©BCž‰–.gşňGţZ¬´-Ld•yz‰ó ÎcW´ qĎ!Üîžp‘Ka1h‘›_ţvőďâPtüEű^Öűš5k„ÁmééŠ+d4FAwJd`´i•»ŔÇť®ĹŮČÖgţ]–7׏,ĚĹőŻ )ÜH/ťén¨§”@í1 Ą¤ÓŇ7Čś ×ë!wń†—;ą¬ŚäÖÉÓCF­·Čáďqă{ŹEĆ«ËńűË-É­ĂpµÂĹÇ®÷ŃíZ¤t¸+č˘IFç zčşmł źvAFZX­Ô†…äéAňT’Îh‡“O"”;Ń÷l Ő\v¨HfśtËĆîoĄT†J6Pé–ĚSćwRr™ýĆ€M¸vSfÎŞ%ő’Ň’U#Ú …Ĺ‹.,VJ~CÚ4—š·°TĺŢ*R\VKe0f÷RŮŮŻżţ*,^l×Ŕ2FF?üđą˘qÓćdŃÓ_‘_fŢ–­"*’'Ýo˘v(J¶Žž”çHăĎ*VZ`E·Â˝<ńů^îá?´olëz˙[wG8 7ÇŇňZ¸ß1ć8”'ý{3­22ă–î]’; aü˙‘Vu€n żŠÂýŽ1ǡ" ¸÷Ň+#3~{á.ÉŤ­xěÓq9˙.5s_VëíMż˘ëvě6Gyá~ÇăPžôďÍ´ĘČŚ“î˝);Ţ+ŽGŕ>E |Sâ>4G€#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-8éÖňĽ]ŽG N"ŔI·NŠťš#Ŕ¨-śâăăk«mŢ.G€#Ŕ¨s8yyyŐąAós8ÚB€»j yŢ.G€#P'p˛Ůlurŕ|ĐŽG 6ŕ–nm ÎŰäpę,śtë¬čůŔ9Ú@€»juŢ&G€#Pgŕ–nť=8G€#PpŇ­ Ôy›Ž@ťE€»ę¬čůŔ9Ú@€[şµ:o“#Ŕ¨łpK·ÎŠžś#Ŕ¨ ¸Ą[¨ó69:‹€lĘ”)Ó«:úڏó¸’fD}$U-\‹ůOîÁé›îhZßÍŢ #ňr4ČŐ›á˘t.čYĆů?p"Í­Hľ‚¤»ţbѦŕÂ…x¤e¦!-­đ/_˘‚—›Ó]ożx¤DE"QxR5|łä\ĂÉóiđnŕůÔgĚ8Ź]‡Óܢ>döň:­jŤpv“]9kMž–Dź‰ÂM‹üT…úĄMŠĆĹŘtČĽýQ R›qçĎ!1pËÇůsq°xűÁĂ”óç ¨çeÉɦK/Ěçěm8ćŕčö04†ŹsaŁyF śíĺ,YW°c˙uµ DMkYa—Iߢ#đGřźwŹgňSp&"Vďúđ(‚OaźŞ˙­ęîRŽ“aˇď…Ž_7…Ě`Â?â‡Ä·"°lÇQôk\Nȸr+~Ů[L»ăÍWˇÍ^w•ţĽ ŤC¦ˇ…ÜěČQ#OCj$6lŤ(µ­=†ăĄíQ8}KÍV}‘6"öŕd×đuSL–ę«›j2dFaÇŽó¨×ís4‡Ö*ծŞĄpˇÝ‹xÖUĽěkŘ´ügśM3ŘkńĹŕńŻ˘[ KíÉÓś‰­[¶@Űŕ)Ěx»l&!Íź#żýŠc ZʧŕĹN0łkŻ"lĂVš C§DŇHtňÁ`Ű1üľĺ2^ęÔ$XŠL6]Â1ĘwVČ7˘ą ćR~Ňźtp vGxcĘłççĂh+8·f6¶$wÇ'Óž‚‚*•Ş<‘vr 66jŽŃ=«(‹* ®ŚĚjě_ţ%ŠňS(0hqŠ<Š- úá˝×űĂłŚ’'Zw#[öDžt@cÂĐŽĎß©ł˘˛wä^pq§j=]ŕFĘ^¸vVÔTm¦qlÓ2!žÄ VŢ€1a?ď&Âm€áď|€wžë ¤žÄ°óĐ€\šôE?V­9§;BčoŚŐI´3zŽýß~ó ľ˘żYS' g#%RNüŽ˙ťČ¨QĚťHÖž.npĄ…ŞşłP§3Ü”.p®"ÎŮçw#ÂŕŃĂ ‹ÖŚÓV„Űî©×đ“ǢnbűâŐH2IkOžň†čh-ő*´D"Â\Ń'"†—…¤K)P8‹6şöĆ5˘T kßöđéđ/Śź0 ĂŰŐRéJ±„‘‹ ä%&›KË' ňą”fĄéâđŰţ4„ŽxMäRX­ůHMÁˇí+±%žř_啇čeňTKÄl\‡tŮťě;ŘYßáĚ®ýP÷ÚaÜŠ9„ő€<=4/}Đkđ |’ŽýŽMçĺńÚP©[°îDú??|e°¤_ŔĎ«OˇËá0üqľíŃHsK<Đűé1TO=š•$_ŞšőÉjłÂF“öÂľőŘq,^ ÷€v2b(ZűŠ“”ÉkÇ–}¸”¦Ąr 4n݆=26…`QÇ`ÓÚmBşGŁÎčÓ*s[ŘČ‚ËÁÉÍ•“'-/@ŮńEttł /ă2ŽDˇzđ%ĽöD;őyxńťa¶` "®ęŃ,DYKňT˘U«8śŤk·$褰!űúawUŻžé1‘H—v„»ÍŚ”ż® µmá}Ú1Řv˙ý´0‰–©‘ ’ÝoĂ‘ď×/öwŁ|„|í}%‚śD¤ĹϨ=›ˇ•4Ć€^őaŃ唫W¬Ą81ť‚Śíröŕa4ޱ ›OÜ›Ý<`p4]´Ň»ń®>Ź-—Č%ÔtŢ®'`Ň!'WÇčÍŽ'çă|tśú5€9ç*ÖŻŘ ß.!H?´ęŁ1~@S$DěÇîĂg¦!˘ąĐůˇ'0°ok8[2°ç×mČ h —´śŽ× \ňčČ˙ŕÁ ÷ĚNmĂňŘ“şe â­1rÜH´°sIYv§PTŃľ¸˝Cę!,Ůz ¦ Ţ>b0Z+Óq`ő÷8ť-±ś4‹ú&’5IČ’*i…ë5f^GVB>ÜT®0§Ă×K6áz ˙°§ĐÚ%‡6.Áďs…ĚQż/·ÓăC1bpO’Ná—…{`•0(wĘ•ł¤Đ­đPkŚ:ÔęR6űÓFنÎhBĂĐöd‰ä":šâҤ%زy%ĘŰy\ěđ]ý4“eBDGÂĘţĚŢiďK$•ťÄÚË[đýÚHUuÂđ1#еŢ-#|ÖźÍ"«Ô„¬ôłHĎw#ëČË‘‘ČÎş†Ë©(ɇ—wа׎A#?čS“{h'\¶˘×Ă}¤Đŕ(YŤQŽ™Y0F Îü6‰p}„Q#…,őÖ|ż±4_`IšĹ‰P•č7t8†ô F- ‹×ť•ií.–Î_‹i&„öMŤg±ó@LAí—ÖýPiySăpŤ¤Ő­wmŮőĐ$‘QM»¶†Ő”ŹÜ|rU¸{ ňKHÎÜIµ%Ďú-C„1Ć\ˆśtóúĹ˰)Âč˙W2P… ¬Md¨,řa#âÓT:ňQx“ ň9ߦ÷Z\»¬s÷'ĐLfA>ť[ŔĄ5&MźŤoĚÂŁ´W'ďQń B× ’"˘ q©1't™ÉÂ"Ţçń®‘Q”KşY°Ë·yáßyŔUîDš–„C;÷"Ú¤B OÇ/;Éčóč€áǡgg¬ĹÁd ¤Ć\ÄÄ'!ęŘś2´ÁÓĎ<ńÎŽe q1·pUązü’ýşbŔCíaĚŠÁŞ•'iůVĽĘ»#K×ĆxM¬ 4)7„Öžń zű[Ń­[s„ÍŮ@v†)]´BKKS*읤ĺVF6fIŃVbs&ĺ4á莽”!÷Č´6öě‚sg üŹsx¶[¤9ÚlÍ0pđ#đ3čѡ‘–lĚ€ÖÉ Jł¦Ŕg­äĺçAâŃŢR3 F3d„µMâKäd…Yìu¶ŕ‹°‘Xťlr_´˘­udŇMČ»!?żf|»…ý`ýI—ŤďFŔ©(ÄĄg"W$ ęŽ©Sź‡?YJÝÚ¶€rŢlŢsçt‚űÖś§‰Üłk&R©0É,ábś»µE<=á;ÍÜ$b˛TvÁű_ľ€F2+Ô­¬¶ô(ŇrĄx Čżoo!+a[ŚÁŹżŤI[ąĐ.Đ˙·`öE¦ŁC/3aŞÄ ÷§â‰±ďĘIDATF6őÝ`»ú!vdĺŔŮÝI‡÷#Ť:ńÄŰÓńT ZT=„ÝßÍŔľ$&{Úö¦+-Oł^#X…A>¤c Ě01x(`6Ř1“Ę ˘\Ěg/‘IkMžňŔ¦"ÝŠŤJ¬Ł/.\˘E˝K[4iî†@ę_ÄĄ,ô훉hZ5T=:Ŕ‹d™f?Ę’Đä47Řn@{óm…FŮďL-\-¸yM4X>'6icâ‰Tr9lthćđĺJˇGN}g†ůr…˙¨˘öŢ>\‰Äuó#¨O¬ě/¨÷.ĽŘd˘ëŠí'Ť:F¸6$űŤvgËp&ţ7Ú0üeÚąŮ;¤j?źľB;W*s=ül˝ńɇ#ám5ÁĐĄ>ţúd ţŠż…aŤěFަ~0 ţ”Ţ­‰ >ź·‡Ďe"4XPŁG^ÇűCŰÂf1‘Ľf`ŮŃDäą=ýŤ˛ůÍEf@ľąę‰Łý@ş6 Ň1X?{2ö6C«mŃuĚkh¤„ŢDi±Ą¦i/–Ó( ;›ŁHÂö•˙Ł#¬¤$·2h)óaQz#°1ťhfĹăˉ °YK´éŘĎOěŹ ňi»m,Đ?-’ă(‚aołĐak—&©Â*"™‚ŐŃ·ÚH‘IŘú+q0<Ó”R ŽŚ5˙ÔÝ$ ! ˝…—ëČ/č˙Hw"\4ä~1‘߯u›@9L·GĐAeñ+ÉĐ7KE’ÄÝ{¸ŕäńKȲú!:Ő†ŕaˇPŘŚ°ɡе®Úě\:1oJŰÝŁ`óŢ©…oČĄcu ­ŰÁbĐBťGz·BWZľőČç $^!g˘67: Ěc tîÓÎf˛É áŃq$&űĆáĐú_p=ÉIéB-ţ4ÍĺÎ"ĹŐ{ ›8Wč¶’É#zlB„Z%ŰÖRhEěk5ć!Gk Ă4ęí(ŐF'4 ¤ÔŇůÍŞe}-‰.«­üPuK—VÔÂ`s@|ú^+D=Žłç.ŕôáxúŰŽ.#ßÂŕ6˝)­E©iŹ* ĄiŁÉÁ,<›ýâĢF¦–ڡÓ)ŹVjq%|°;-®PhÂţk&v!_ޱ㊾„?ăéoScĽđţ‹ …¬0HTŇ#â[ Tµc¦v$zÚľé-¨O¬ËFd3ł[ 7PŃ·˛ÚŠŚS.#!ĐźUq—ĂŇeÍ8p›´ŕĆŤ4š€Ťč«”F`#˘µ˘čI ĹľŠ÷HŘ»Úvöñ“çq6RMdŠÇű×ÉăŰq*Ň—HX‚gČ÷k1d m°úmTŹ­@R’)[ X“‹ř vŠÁđ©çI2!ĺdý”0Ë’ž¬yĂŤpĚţvź;0¸Úö iÜf" ŽY˛i™d±‘ÉâDÓ!źYٔӬ3®â–§ÝP’gçJČ“Ęĺ¦Ý{%!r°P]öőPN“Ť!CÚV¦ÚÇÁ:X[ň¤iŹŕ¦ěŤAxx2őŰ«ČBĎAóvͰoWöf«›:4UÁl$Ý+Š"R„ˇgCéoŕÚ¦ĺ¸Řń-4p/ÔH†gQÝacfANDf5Ń.Äţ],ŞŰ$ –&ć&ńÓˇ&]Ą 9Ůă BÁ»óÁć ™™ą°5$Ű•úĐí_xůaÜIă6ÎƢĂĚŐBóőKČm&ß=é?ĺŤßą«OgQĽ!x¸E=ě ­:Ǹssµ…s…^6'»_“ę3YĚ0ŇůI!6Â€Ś‰ŔľÄa­Kĺ°Ám|„žTőŁę¤[0hjŠ:žB‡4»RšâĄ§GâŃgĆB¦ŤĹź/AT˘}ő۰!ˇI©iCŰ‹+Ś\F“Ž®ŃŘlÄĆpJUćŤw â]»ŕµqOҤ"ĺ˘ týŕ:¸Y~˛,„‡­„®Ó óF‘Ż"íř/óűĨehE–@Á m“Ň‹:ĘH—Mh{ůřQ}±¸šlDňˇ1ë7ţR4ep&˙mqŕŮ+C[ĹD/•ŁÇ]ŽV q[ŐĆÄîxęĂN¦«-lH©7É”¤ *–ń±©49ű€vý0µiú›˙ü{= ˙úîhNľĂ=ë)BŃ !~2rHÉXX»B=4΂űägyXó§ý•˘FH¶…§8Ý üE  +ťŔ§EÇP Ś›ő_Đ-("Cv|±Ä‹TÎÍšůŕŘ©KHŇS_ěXf&±­›äY8°vEĺäIąëµ †íř9h dýP]Ęz Č:.ž˝†'ž¤M;ĹÓDë±-ŰÄ‹cc‹wMË“ş ˙ć­ˇěƉ„YĂrµÂm¦řŠß‘ď×_ŚĎ*” ++ŕĚpýčCtJߍ‰ßîÄҰ ů,ůłY{°’U!ČĎaßöĆĹeŔҲ^ń4{F&G»Ľôęă4ĘčŃY\X…źĂc ŃiľGŇ%hŘŁTV:@đk¦ví i׬Z6e7ČwŘął°Ő2VÁĺÚ¤ŁP߉ź~©äčr“°kŐäŃbřhݦ’ś‘r\TnÄ]ÄÎ_fc˙-jĚxůV4hŰŠ&sVü´‹üĹj\?µa„ą$NĐÄ'WRždt;łËň$dĄLV;Ü[ GYJG~Âö¨4d%źĹšG¨ę&čFÖŁ…üřtě]kň”ů#X)‚:‡ÂŐjÜ_ź`´pgxý!$7ŘUŢۤyž`X{úARôďŘ™@cż=caŚ‹ů&ĹŻN%Č…Ĺ:ć°ăé(h6“WŃŚ€"ĚăHĽ[O—ćŘż éÇE,ő3NĹ^'«7—OíÂĽď6‹'[şKöUčŽDt’˙ ±‰Ä?gcńŚźč J™töAĂ`V»>rV»­:»~^O÷_$čÚ™Ü9匉µgѧ—ÉoĄáZNuIU·ti Ş$3KB;fA4¤“ě.AÄúĄpTëÓ#z5Acót9EńĄ¤YĄ* ˘<ëŽHóSI_4!4ŐK¬×°Ďh Ęţv†˙†…ábĹÎ-źÄäŃ!3iŃç™Gđךpüöó’‰!¸ç hçE–YqÚăÚ´…äÄ\#It ľ[”Í0věcX´ňüň=łp)>Ś)/Đé)mťőä'd–ۆ?Ô>€ęb–]y⫨ŽO›M\žŐ1‡±»phđmŐOÓ}ËP/+ů^5h5p4ú©WŕĎ]«pa—زO§§ńÖ &ä6Č…Yꏡ*\»ä‚6Ád˝g#¸UŕZ,)#a=MpÇčIăĆHO›Íäeߙ²4Čbř+C±fŮlZö˝Đ [äz?? =ü¤ČíŤćű®ăđÚďÁ¤ ŹćčŮŮÇĎ^ŔüŤ]1ó©Ç1ö1 VţŽ%ß… ĺÉ•“š˘ TwôŮWVWNžň€ćt…®^MĹ@oZĺčńÜ+Č\ĽŚÚ_"´oŁ_đ=ýŃ4w1#—¬ÇÚ’§0PxŁEKwDǚѵ]ąŘŹSŠmď¨3ŮhÚň'RĽT*ꀓŚ…ë™ɂĄµ#źnä…•8ńËtyŤîśS`ůŤ×QZŃ–ăüᓸ9dŕ2ł’»`ă9“żťä+¸„ÄLś>M‡Îˇ áLźšćëeM„†˝źÇK®ű±vGv‡]+hRŃęQĽŃφ—Ć’Ź™é¨UĐO6fÁ•dU˘Cżž8˛ń8~ž+Îeßö=Ń9‹Üť×c[§˙÷©ĆČŤKA› !´ô†6w沸tÉőĆ‚Ű Ö^ýîŃĺBéüf±;„ňW5H«^ІáîăC?K4 ëÝ(čNiŚdQ8)T źÓ¬FnŽšüŤĺ¤YEŤŤě©ň†‚¶,tżH樗ů.éĆŽ]®tp˘"W])ÉÎÖ ŢýrAŻĄ5µ›*Ňé`…9ĂÉą^|PZěţf>N·‹ŮĂ›"ĎnNH­f:tcë™ţŤüˇ DťE÷)ćěęYŘ~«fÎ|JMr+sjQUôËČ/QxŔ×CôuÍbĄ“Ő|M.ô •[Đ“ĎÎÉÍŢ´ą"2ÍQ“˙J((‹§/ÜäDÔYY‚ËEîćI?vĂX0&)<|}ŕlŇŕV®AlŽäéăKż”ň éZJד_Ö –|-Śf'¨üŔDbĘË·Yt`&ˇëwV…+|ĽUtKÄ‚’•ł§'YwZ:H˘ň4™ŮŰ*á ĚJ %ĺÖÜĘ‚™nTNž@ňźËđóaWĽ;ű%xĐ1űpaÎ×ĂLóČÍżĽÉU¤Sg ň®My::çęĺWÚčÔY:ČŇ”*_ÁwY(˛ëČš÷%pYśĆćFďrZ<˛Äb’Ź7ɇ~?M®ôă˘eĹöhŞdťÂěE{ĐçŤixĚ×*čµ#Ťť ¨hSId‘Î3}ŃĆnĂ·ëÎcä´oŃK•Ź[95w?]ěÍsĄé€NÓ Wď‚9ŻŃ‘žşÓŽô„îŃOQÓŮˇŻžÜ‚Ž2V2Ěrň‰W”‰ýᏠk3řt@ ť-äę݂ɢł˘X;ćąÂĂl :Ú+“ßJÝ™˘\Ú›äúőëĹů©´\•Śs"Ç´”&žŤ¶·&ł}/o/[^š”@¨ů‹[¨Žf%”Î~Ćę5Óę[,ĐA™\¸żGŤFăm„˲”—feK'\V–d"k®Tđir›¨MÖn©é¬ .MĆż;8ăÝÍsu*Â$TV–YéŽŘä‹‘poýo kíJ ˘U-Öro~Z p/gRUk×iKJ„f$«ööůŔŇhńł.kÖj)$\ö]”'ĺq°0‹t„Jʲ Ő7NGAę^ěÄ„¶ďv}° ôź&OŐń LżjÓ_DŚÎUXĘŞÓ’(c3Ľţ|WÚşhkŹpYI™Ý®`e )V‰2dĐíąüčÖ 3YÝB˝Ąé^Ů5 )ĺqXE‹%W«Ą[¬ć{ň ťŁ{ŃżÖDWҲ4â}Ŕ˛şéěá •“·˛ézTY™x|­# UŞŕC·5[ä˛:T§ĺIî/_wrČ­ápM•”„~XäëĺL[ęěÂ,ĄäűÇE1w™ą<őĎűš›$!!sJM ÍŰŕp8„@µş8˘ŽG€#P>Uż2V~}<•#ŔŕpĘA€[şĺ€Ă“8Ž@u#Ŕ-ÝęF”×ÇŕpĘA€[şĺ€Ă“8Ž@u#ŔI·şĺőq8rŕî…rŔáIŽG şřd-Ní$Íú„IEND®B`‚nipype-0.11.0/doc/devel/gitwash/forking_hell.rst000066400000000000000000000021451257611314500216130ustar00rootroot00000000000000.. _forking: ========================================== Making your own copy (fork) of nipype ========================================== You need to do this only once. The instructions here are very similar to the instructions at http://help.github.com/forking/ |emdash| please see that page for more detail. We're repeating some of it here just to give the specifics for the nipype_ project, and to suggest some default names. Set up and configure a github_ account ====================================== If you don't have a github_ account, go to the github_ page, and make one. You then need to configure your account to allow write access |emdash| see the ``Generating SSH keys`` help on `github help`_. Create your own forked copy of nipype_ =========================================== #. Log into your github_ account. #. Go to the nipype_ github home at `nipype github`_. #. Click on the *fork* button: .. image:: forking_button.png Now, after a short pause and some 'Hardcore forking action', you should find yourself at the home page for your own forked copy of nipype_. .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/git_development.rst000066400000000000000000000003121257611314500223270ustar00rootroot00000000000000.. _git-development: ===================== Git for development ===================== Contents: .. toctree:: :maxdepth: 2 forking_hell set_up_fork configure_git development_workflow nipype-0.11.0/doc/devel/gitwash/git_install.rst000066400000000000000000000011111257611314500214510ustar00rootroot00000000000000.. _install-git: ============= Install git ============= Overview ======== ================ ============= Debian / Ubuntu ``sudo apt-get install git-core`` Fedora ``sudo yum install git-core`` Windows Download and install msysGit_ OS X Use the git-osx-installer_ ================ ============= In detail ========= See the git_ page for the most recent information. Have a look at the github_ install help pages available from `github help`_ There are good instructions here: http://book.git-scm.com/2_installing_git.html .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/git_intro.rst000066400000000000000000000010361257611314500211440ustar00rootroot00000000000000============== Introduction ============== These pages describe a git_ and github_ workflow for the nipype_ project. There are several different workflows here, for different ways of working with *nipype*. This is not a comprehensive git_ reference, it's just a workflow for our own project. It's tailored to the github_ hosting service. You may well find better or quicker ways of getting stuff done with git_, but these should get you started. For general resources for learning git_ see :ref:`git-resources`. .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/git_links.inc000066400000000000000000000060601257611314500210740ustar00rootroot00000000000000.. This (-*- rst -*-) format file contains commonly used link targets and name substitutions. It may be included in many files, therefore it should only contain link targets and name substitutions. Try grepping for "^\.\. _" to find plausible candidates for this list. .. NOTE: reST targets are __not_case_sensitive__, so only one target definition is needed for nipy, NIPY, Nipy, etc... .. git stuff .. _git: http://git-scm.com/ .. _github: http://github.com .. _github help: http://help.github.com .. _msysgit: http://code.google.com/p/msysgit/downloads/list .. _git-osx-installer: http://code.google.com/p/git-osx-installer/downloads/list .. _subversion: http://subversion.tigris.org/ .. _git cheat sheet: http://github.com/guides/git-cheat-sheet .. _pro git book: http://progit.org/ .. _git svn crash course: http://git-scm.com/course/svn.html .. _learn.github: http://learn.github.com/ .. _network graph visualizer: http://github.com/blog/39-say-hello-to-the-network-graph-visualizer .. _git user manual: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html .. _git tutorial: http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html .. _git community book: http://book.git-scm.com/ .. _git ready: http://www.gitready.com/ .. _git casts: http://www.gitcasts.com/ .. _Fernando's git page: http://www.fperez.org/py4science/git.html .. _git magic: http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html .. _git concepts: http://www.eecs.harvard.edu/~cduan/technical/git/ .. _git clone: http://www.kernel.org/pub/software/scm/git/docs/git-clone.html .. _git checkout: http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html .. _git commit: http://www.kernel.org/pub/software/scm/git/docs/git-commit.html .. _git push: http://www.kernel.org/pub/software/scm/git/docs/git-push.html .. _git pull: http://www.kernel.org/pub/software/scm/git/docs/git-pull.html .. _git add: http://www.kernel.org/pub/software/scm/git/docs/git-add.html .. _git status: http://www.kernel.org/pub/software/scm/git/docs/git-status.html .. _git diff: http://www.kernel.org/pub/software/scm/git/docs/git-diff.html .. _git log: http://www.kernel.org/pub/software/scm/git/docs/git-log.html .. _git branch: http://www.kernel.org/pub/software/scm/git/docs/git-branch.html .. _git remote: http://www.kernel.org/pub/software/scm/git/docs/git-remote.html .. _git config: http://www.kernel.org/pub/software/scm/git/docs/git-config.html .. _why the -a flag?: http://www.gitready.com/beginner/2009/01/18/the-staging-area.html .. _git staging area: http://www.gitready.com/beginner/2009/01/18/the-staging-area.html .. _tangled working copy problem: http://tomayko.com/writings/the-thing-about-git .. _git management: http://kerneltrap.org/Linux/Git_Management .. _linux git workflow: http://www.mail-archive.com/dri-devel@lists.sourceforge.net/msg39091.html .. _git parable: http://tom.preston-werner.com/2009/05/19/the-git-parable.html .. _git foundation: http://matthew-brett.github.com/pydagogue/foundation.html .. other stuff .. _python: http://www.python.org .. |emdash| unicode:: U+02014 nipype-0.11.0/doc/devel/gitwash/git_resources.rst000066400000000000000000000034421257611314500220260ustar00rootroot00000000000000.. _git-resources: ================ git_ resources ================ Tutorials and summaries ======================= * `github help`_ has an excellent series of how-to guides. * `learn.github`_ has an excellent series of tutorials * The `pro git book`_ is a good in-depth book on git. * A `git cheat sheet`_ is a page giving summaries of common commands. * The `git user manual`_ * The `git tutorial`_ * The `git community book`_ * `git ready`_ |emdash| a nice series of tutorials * `git casts`_ |emdash| video snippets giving git how-tos. * `git magic`_ |emdash| extended introduction with intermediate detail * The `git parable`_ is an easy read explaining the concepts behind git. * Our own `git foundation`_ expands on the `git parable`_. * Fernando Perez' git page |emdash| `Fernando's git page`_ |emdash| many links and tips * A good but technical page on `git concepts`_ * `git svn crash course`_: git_ for those of us used to subversion_ Advanced git workflow ===================== There are many ways of working with git_; here are some posts on the rules of thumb that other projects have come up with: * Linus Torvalds on `git management`_ * Linus Torvalds on `linux git workflow`_ . Summary; use the git tools to make the history of your edits as clean as possible; merge from upstream edits as little as possible in branches where you are doing active development. Manual pages online =================== You can get these on your own machine with (e.g) ``git help push`` or (same thing) ``git push --help``, but, for convenience, here are the online manual pages for some common commands: * `git add`_ * `git branch`_ * `git checkout`_ * `git clone`_ * `git commit`_ * `git config`_ * `git diff`_ * `git log`_ * `git pull`_ * `git push`_ * `git remote`_ * `git status`_ .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/index.rst000066400000000000000000000003451257611314500202570ustar00rootroot00000000000000.. _using-git: Working with *nipype* source code ====================================== Contents: .. toctree:: :maxdepth: 2 git_intro git_install following_latest patching git_development git_resources nipype-0.11.0/doc/devel/gitwash/known_projects.inc000066400000000000000000000027031257611314500221560ustar00rootroot00000000000000.. Known projects .. PROJECTNAME placeholders .. _PROJECTNAME: http://neuroimaging.scipy.org .. _`PROJECTNAME github`: http://github.com/nipy .. _`PROJECTNAME mailing list`: http://projects.scipy.org/mailman/listinfo/nipy-devel .. numpy .. _numpy: hhttp://numpy.scipy.org .. _`numpy github`: http://github.com/numpy/numpy .. _`numpy mailing list`: http://mail.scipy.org/mailman/listinfo/numpy-discussion .. scipy .. _scipy: http://www.scipy.org .. _`scipy github`: http://github.com/scipy/scipy .. _`scipy mailing list`: http://mail.scipy.org/mailman/listinfo/scipy-dev .. nipy .. _nipy: http://nipy.org/nipy .. _`nipy github`: http://github.com/nipy/nipy .. _`nipy mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel .. ipython .. _ipython: http://ipython.scipy.org .. _`ipython github`: http://github.com/ipython/ipython .. _`ipython mailing list`: http://mail.scipy.org/mailman/listinfo/IPython-dev .. dipy .. _dipy: http://nipy.org/dipy .. _`dipy github`: http://github.com/Garyfallidis/dipy .. _`dipy mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel .. nibabel .. _nibabel: http://nipy.org/nibabel .. _`nibabel github`: http://github.com/nipy/nibabel .. _`nibabel mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel .. marsbar .. _marsbar: http://marsbar.sourceforge.net .. _`marsbar github`: http://github.com/matthew-brett/marsbar .. _`MarsBaR mailing list`: https://lists.sourceforge.net/lists/listinfo/marsbar-users nipype-0.11.0/doc/devel/gitwash/links.inc000066400000000000000000000001611257611314500202250ustar00rootroot00000000000000.. compiling links file .. include:: known_projects.inc .. include:: this_project.inc .. include:: git_links.inc nipype-0.11.0/doc/devel/gitwash/patching.rst000066400000000000000000000076651257611314500207610ustar00rootroot00000000000000================ Making a patch ================ You've discovered a bug or something else you want to change in nipype_ .. |emdash| excellent! You've worked out a way to fix it |emdash| even better! You want to tell us about it |emdash| best of all! The easiest way is to make a *patch* or set of patches. Here we explain how. Making a patch is the simplest and quickest, but if you're going to be doing anything more than simple quick things, please consider following the :ref:`git-development` model instead. .. _making-patches: Making patches ============== Overview -------- :: # tell git who you are git config --global user.email you@yourdomain.example.com git config --global user.name "Your Name Comes Here" # get the repository if you don't have it git clone git://github.com/nipy/nipype.git # make a branch for your patching cd nipype git branch the-fix-im-thinking-of git checkout the-fix-im-thinking-of # hack, hack, hack # Tell git about any new files you've made git add somewhere/tests/test_my_bug.py # commit work in progress as you go git commit -am 'BF - added tests for Funny bug' # hack hack, hack git commit -am 'BF - added fix for Funny bug' # make the patch files git format-patch -M -C master Then, send the generated patch files to the `nipype mailing list`_ |emdash| where we will thank you warmly. In detail --------- #. Tell git_ who you are so it can label the commits you've made:: git config --global user.email you@yourdomain.example.com git config --global user.name "Your Name Comes Here" #. If you don't already have one, clone a copy of the nipype_ repository:: git clone git://github.com/nipy/nipype.git cd nipype #. Make a 'feature branch'. This will be where you work on your bug fix. It's nice and safe and leaves you with access to an unmodified copy of the code in the main branch:: git branch the-fix-im-thinking-of git checkout the-fix-im-thinking-of #. Do some edits, and commit them as you go:: # hack, hack, hack # Tell git about any new files you've made git add somewhere/tests/test_my_bug.py # commit work in progress as you go git commit -am 'BF - added tests for Funny bug' # hack hack, hack git commit -am 'BF - added fix for Funny bug' Note the ``-am`` options to ``commit``. The ``m`` flag just signals that you're going to type a message on the command line. The ``a`` flag |emdash| you can just take on faith |emdash| or see `why the -a flag?`_. #. When you have finished, check you have committed all your changes:: git status #. Finally, make your commits into patches. You want all the commits since you branched from the ``master`` branch:: git format-patch -M -C master You will now have several files named for the commits:: 0001-BF-added-tests-for-Funny-bug.patch 0002-BF-added-fix-for-Funny-bug.patch Send these files to the `nipype mailing list`_. When you are done, to switch back to the main copy of the code, just return to the ``master`` branch:: git checkout master Moving from patching to development =================================== If you find you have done some patches, and you have one or more feature branches, you will probably want to switch to development mode. You can do this with the repository you have. Fork the nipype_ repository on github_ |emdash| :ref:`forking`. Then:: # checkout and refresh master branch from main repo git checkout master git pull origin master # rename pointer to main repository to 'upstream' git remote rename origin upstream # point your repo to default read / write to your fork on github git remote add origin git@github.com:your-user-name/nipype.git # push up any branches you've made and want to keep git push origin the-fix-im-thinking-of Then you can, if you want, follow the :ref:`development-workflow`. .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/pull_button.png000066400000000000000000000311351257611314500214740ustar00rootroot00000000000000‰PNG  IHDR~\iÉŢu pHYs  šś IDATxí]|TĹÖ˙oß”MHH€ ˇ„–P¤KTôĺ,€˘"ĘS, Ođ‰řŔ§‚}€%"]zďť„HR’@©›dűîwćŢ˝ÉfIBB$a&żÝ{ďÔ3˙sćĚ™3s72đŔŕp8÷ ňű¦§ĽŁŽG€# Ŕ?ŽG€#pź!Ŕ˙}ĆpŢ]ŽG€#Ŕ?—ŽG€#pź!Ŕ˙}ĆpŢ]ŽG€#Ŕ?—ŽG€#pź! ¬ýµŰíHKKCVVVučNąűPŁF řűűC./y>çx•bpŚËŹÝßU’óěVäeŐá˙Í›7Á”™——×­=ĽObŘëyyy‚Ň(±×Żá)6‘c\,4÷lçYѬ)Ů4,şĚ=›ťť Ź{Ž®Ę$H&“ 0,n8^·C¨čtŽqѸÜ˱śgEs§Z¸zl6Ůě~?†Ăâvău;„ŠOçŹÍ˝šÂyv+gŞ…Ĺk·x G€#Ŕŕ‡Ŕ}Żř÷ěŮ©S§âÔ©SÂŞˇ8 xyň$ľűî;¶wß}­Zµ*—ř¸.6.O[ŃB$É´ÜÓ r)›ÉťÄ»›BńúčŐ? Z}|?˘·ĚìĐřę©ŕ˘qu'ň.=ËIXHéG.AźÖ0[ŠäráÖďgcÇŽN,Y˛Dx_čłĎ>ăźkđńńřĆ®ŁGŹĆ ËĎŚĚüŕůˇS˙Nđ3^Ƕ˝QXöŮ+PmŔćŢůY+ô†úďĘëęˇřËł\ŮK_,?~\ř°ű‘#GBˇPN$,ţĚĆŐě"†¸EŘźř úůAÉÇ~ǧłľGLVs<ŇYĘŻěŔÄ™›ŕR7ď†>řŚŮ'—,Ćîo<5ú#Ľ3( fča0¨`ˇ9—·ÍĂĚUI ¶l>‚őş`ÂŚOĐ»a彣páÂ0e‚Ś™3g‚ťýgxôéÓź~ú©°Zb>é1cĆ iÓ¦E*(O§Ą_€Ëť)óŢť…ä:Ťá8·G|ĐĺŮ <Ě ó'ţęg>Ää!Aź>; Ýńů¬Đoś‡©áÉxýËéMŰŤ9łgáHĽľÁí0tĚŰčaŮ‚.I FřpěĚź3W6bάŻÄ|Íű`ü„ńx´Ŕh‹üs &îއýĶ?×ŢEëKÂ+î–˝X4ţ|aµÉdŽ#,0śŮÉ+‹ĺöVC‹ÁSđůȦ°ŮłńÓĐľřţÚÄŰ˙q˙‡?đ$ľú`Ľ —0oÂtžśŠń$WR spŇ-ÍĐ.÷Ë𑵊ąłţv›Žřőxč3‘šk§‡Ń;~ÂŚO– –ňÖëú>ú`4Â|•H>ŽOg, ±ŚO5Eâ… ô›4}±ďLZŹ'ćĚĹ &^ř‹xůŮz`ęĽ h‚«Xńĺl,ŮCŤăŮÉbM8Ö´łřvć—XIĹů:Ć?˙–˝? ‚ öă$ĚŻ?c{Ő+čÇ]ş“ŚD•J___Lš4 ˙ú׿hÜ„5 &Ož ö ËË^˘d źĺg|tUţ"¶Żâ?źż5ńyâÉź0pÜwXş&٦<ŚÄÓ[ńŻŹ?G›W¨ßĂirToV|ô)ö{<†Ż¦Á•ĺ3đďmŔŰßLA»Śmxsâ <ôág>ü6'Ő@Ů9l>ś€ŕ.#0}ÚH4tĹ…x-w}ľ_î™Ň_·nťŔ Ć şuë˘~ýú1búöí{‹Ň‡őÖ®#…Ň`4–|ó†ÓęÍŃĐ(č6yž˙ŕ{Äf¶ŔđŃmń×^g°“][lč?Ľ2ăwaÎgs xřqt”'`ýśoqŃŞ‚!!§îC¦McĘÄĆÁ–¨ZxçŤţČL8‚Ϧm‚E)*©î»ueî/f…JÖĚŕÁĄ˙Ţ{ď žžžŽÇ{LhžÝĎž=ĚWZĄ§Ë€ó±8Ľy3˙ń6ž Αđéř3Ýź”L¶¬Ť‚ه?wÇ öč$ZM¸°sĽŃ¬^ ¦Śź…ŁúľţŐ tɉŔ’)ź"­NKtoď+Đ©w+ÚNŕµ7ćŇo‡ŃG@łźŹź‡2§Ř_Ű ż>ňŰŢtĹ‚Ę@™YŻ˝öš``0…Ŕ”<›\™"aJ‚)Ď¬Ę &ůŠĂ57íâ®"ęČ&˘IĐ! €ŻR´s±=o€‡§°Ö±ń8ź)— ´ĹŐV8Ţ‘xk÷ěÂÖmâÇe…ÄĐ:žäÎü #Hé§ôxӧڇâp8Ćżú˛Rh,Ľ·@ #Ţ膣kw ňź)Ó@ĺČ¤É ™r-­„e0gśG|ě)Ř<ěXőáH,ŮťŚ?™Žńýĺř}ÖXr.»ćLŔÚÓzŚý|¦<«Ăć%ź`ăU Â:·Ů\@‹‡ŃľQ <5•gżJtPPŢxCÔŚvß°aĂ|Ý!ŤR~–§p0ÁHÖ?[áiµB[&xŃI0fÁh’íČĚ0Ś›2OÇcĹgŻÔÖĆŕâ®H¶çŕĚÖ]H }r6Ń€äÓ[“ʆÍë#=ć("ŽlATŕ“÷D ÄYŽi\„«úÝ܇ĘC¬pŻ+ô‰Ů*ĐĹUĚŇŮ úć›oťźí‘GÁ+ŻĽ’˙ĚfköqťˇłNlÇaj¤AŻ6 “!”ÔCÔ˘ő¸1jň"÷ e‡/řďtňĹ íôńJ!ŽšÂř˙}‰W[^BäŠ8Őr<>o$b}"1b PłĎddpyC#WŔ.”©ŹË?E'ď\÷lÇ‚\´Zزó\m4±r·og“n±…Yžâđr·2®yŮ^ű» /&ŕěšź×*şS¤–Y|!ÚśŕÔi¦Ťč„ÜÖ&¬µrEž|¦vŻ9‡#' ˘eçČŔ™H\Ž|‡=‰ĆŤ0iö;Ř‘†řÓű@F%!¨_ËAÚm6ť2břKý ?ţ ( #ľůăşů`H».ÍҢ¦‡ť ţ#ćăÓ‘Ýő`6Öżľ”¬fO‡¤ôź< ͨOÔzŇde źłđđ/m Č„<@Π¶so˙ΛXyłÉ’ÉĹĂîKŠcéîˇÁs30oáO›IşZőčM}5§ R”-AnÉJŔiz$äĘHlY3°"ňç÷1jî^ě8‡ÎýĆA:¨ ëGßî¶Z¨‘µE¬_EřĆrr¸•ŠV $ń1Wéú€,PęßT?M†!ý1v\wř¶¨Ź'ź˙¦_w :ţţ\˝—db5n¨ţŔ»íM°Q^&SZ š,™®h×®ť Knq7’„ÎűĄm±P?€´ČĂüÚ…Á3ďPBK2}’G“6I©jwęMFç:,ú`*üLŃŠ©ł§ŕ<Ą†Žě-đ‰Ľr$PjZaY Ď4çlţ/,y&qň-[$e]Ôußľ}'ABľŇW«Ő‚Ňg§yĂL&“ ¸•%1/ż®ĚHüĆĚ}˙§0—üŢ č3wňSJż­;ŽFÎc ß~1{NěÄż?\ę‚ 8ř\"ŕ`‡}H`śăŇ5‰%zf40>Š•-‰|ÚŠy–Jw-©<ëË–-1}úttëÖ ńńń‚‹çđáĂŘż?ŘqĂ7niĚÍ#)}÷‰Óˇ¨úd:Ň—á­żâصřhÚ¤níá)öU8űäě‡DŻ_«NâŇ—"Âzö@—vMĹ$Y/ô ­Śkg߲ßCC0¨[mÄźev= ÚLgÁ!KĩٱĐÖ®#_<*Jz¦Pp•.– ŐËŚA"Ó©á)(5§ŤK—Ňń@Ë0±Mm´ëĐ×ţŽĹ?_@­‡şń‹ć~‡}'v ٶáçU8´k ľßÍ~Z„(ň®Ťľt—n@ť–ĐPuáß/Áů›7đí 1řfĂM |ó_7®ŁP>1Ý/…°fŔůłG›n, »ń őK¨ „/)_QW©KcAĘĂtłňهÝKńĹĺ—°EÔVĚűţG,]0Ă>\!důD6±]4}.öś>Žĺ_ĚFĄ¶ «MX5GŻfNY {Ý;·’šÁŔG›Ŕa1 ˘ÉZ*,×RćŔf-ŞżĹĎNˇ°súlff–*ŰČe0ĚŇgJź1Ś)»âÂŤ#Űŕ3˝Ú6€fKGłˇčűĹzěܰ W&}Ž9ŁcŇâpĽ˙NA-ę‚[˛ŠXP˘&ÉąĚ[´‚¶¤u.lNwÎËÂ}áM=Ů]ÚčgTĚšgľh†Sú§Oź„şgĎž`&Űôeůؤ) |áş4xnÎwH{ó ü±n>X'¦öź¸ݵő†5Ý!¸Č‹Q(0¬MĐ·ł"Źd ]H001ßżţýĐ\k©a/<Ľá[§`0->BkGŕ8.ĆТVU‹oߏĆ[Â1㥓˛l&ľIUĐFŮűËľB[ßËđ"^°¶.®Wž"ę.=Ľřâ‹řᇄREĹIi®WĄŇiM“b–¬6WW/Śź§.Ç×ďMDývˇT”~ąÖkÉgŤ ÷Ž;DY˝(4(Ş«sĺy#îjŽŹ™Ż¤á“ź¦âąe”‰pťđÝh´nŁĂ—/Ä?˙Wx,°jĽ[ ŔĐź±|ë\LÜڰúdĹ1ąŻ‹qßĚ@ę„)2j8ËŠ}'`ěăť‘Ł|›§ü†‰Ăv ń¨˙(Ć j™Ć:/Ř}ßâĹZaŘ;ľ,˘ŹTĚwżî(¶ĚíćpDá÷ĹQBU2Z‹}°d.†µ­s^_|÷~Ţř÷jĽ?^4í‡IÁaĚAç'ÁÂŻvˇWűř>‹®T×aÇSčâ ‹Iô)¸ę Ö–4Ć$^+0ĂËÍÜąŁ^ý=…™´NŃşs§ ""]şt–ÓĚg:eĘa3—Y«Lé»űNÝËłgĄ‡/tZ9llvž4Ŕ”đńÓAAslnf6L4‰ŘÔľ¬Á–˛b°äf"^đő˘ť}şĎ±¨áSĂ »™Y9P{ů“].ýś´ĂŁĽŐäž {µ'Ĺ›írxÓ)ŞŽ‘帬¤V _“’’ßcáŘÂO%áU8§čcîć“\LdŇ—VHîe =S9SnLé¨H'?lć<čsiĄM?_Âć\dĺš!W{`Ež_hi=lŇ3=ŕ§ÓŔa3"+›|ş$ĐVr—yřŔ›üňĚW*'¶9' ąVňijiQ«€đ4ši#Í*‡Ž,cň„=YČ#^ßvŃ–’ÔŻ;Ĺřő×_—Ş*Őő—_~;^ëd*/ÔđVĂîÄĎ=ť=«•¦m–§¸|,ľ:ń«Z(ţŇ cóë—ÄŕŇÖĹóq8Ą@€,‹Óo]ŠÜČŇâUŮôW…ö8ĆUK…iä<+Ś{Ş?űí ö˙fďç˙ąËÉ0`XÜ.pĽn‡PńéăⱹWS8ĎnĺLµ8ÎÉftv\+Łŕ¨Â­=˝büüü„c­ěNIăU:%§qŚKĆç^Lĺ<»•+ŐBńßÚ-Ăŕp8Ĺ!P˛iX\)Ďŕp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇWüĺĂŤ—âp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇWüĺĂŤ—âp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇWüĺĂŤ—âp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇWüĺĂŤ—âp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇWüĺĂŤ—âp8U®ř«,ë8áŽG |pĹ_>Üx)ŽG€#Pe੿ʲŽÎŕpʇ€ňňĺËĺ+ÉKq8Ž@•D@YŁFŤ*I8'š#Ŕŕpʇwő”7^Š#ŔŕTY”‡ŁĘĎ çp8˛#Ŕ-ţ˛cĆKp8*ŤWüUš}śxŽG€#Pv¸«§ěńŽG J#Ŕ-ţ*Í>NP{@)#mé°qç57 Bĺ"hC<á›jE@ O>ŤŚÇ§ĎĆ"ÓŞC€Ź:żź9ńѸ /ť1g.Áćť%§O_…¦V´Îţä0$ăt¤3źÔŮüDé&˙Ü S݆đWT`3k–A-•sprëNdŐl€íßgłÓ.áŔÎť8x"g˘/!Eo.0žĄnUŘŐ†+§ŹáZ®jűUĽŚW™Ľ˘*@ą\=¦ÄSXµţX‘ť¬Űe(^ŘŞ˘Člé0áTř:íř2ľhä“ĹVquSM¦Ô(lÜxµ:}†Ć0Á^¦Ús°uŃ*śiő žóÔ 7ă Ö,ůI&g-51xěkč乏/’Žţ‚Őőcxß2¶S&˘Ü2[qyďZěHňAÍ©˘‘Âö#É‘›°z[Pw¦żŮ őśďß~Ć!} _lH2pmýÂ0Řq¬;ŹW۶q6—_1\=Dů"„|Ă+`-â'Bâ÷ţ‚-Çü0é9Tyy0ŰĹ "™…u ťńŃÔAĐ•jˇÎ>€ź—{`Ć„‡ápmČ­Wwë1ţĐXĽő¬X˝ZM9˝0t´ö§¸Š$ăQ«6âh§@<ÔÜFsĹĘxE“Ëë»÷(źŮ¤mŇ®/}„˙|ů%fÓgć”7еž7Žü˙IAÝv÷APzľ^đÔTĽ­¬ęTĂKëuŃĘ8˝ÇL: Ú,{+N¬Z*(ýVĆŕăw_BnâĎ+oˇŠAxbPSĬţÉŠň¬-Ę‹łˇB‰_zÄeĘ úhĆ• qB…Žë—ŞĐŠü´$㲞˘Cz˘eÇgđćř‰ÚŞ´ZOŠ$Ś<< rcĽGÓű†ĎĂŚϧÖp żíLBËaĎ J»=‰Wc°ďĎeXGżîđń†ŹÎ ô­{ÚÔŘô—±ReŚŃk¸şUTú>íńĆg_bţúĚ›‹ŹF>-ńrĺOG`‘V'ů¬%­°|<|࡮xŻ y-U rYü’ѦňöÝf†Éd…LYÇľÓĚy8ą™–ăŹ€ÎdAZĚ>¬\µ If‚EíŹn‡ˇ˙A°$Ăâ_NˇÍł/Ł[°liQřyĹNxvyC;Sćě[¶×>ŤŢÚSX÷—ݰmç1äd¨ÓęqĽ<ô!x1Ě>d4Ůvş:ŠmS`Ś- ‡ţÜ˝—É6tµ›ˇçŔAx¨ˇŻś5żnŔą¤čęµCĎfy9ŘňÚA–¬7NnĂĘ­‡Î kjă‘aĎâá&5…˛…żR°nőhŰĽ‚6^6䦜Çh3|zc´‚Ő‹WŢ‚©ó×á)±0;ôBýŤ‹±öHĆwŇÁäb9®»bźj…4§ c›uɰżŽÓńhjÁtó/śżnFżšč“®!‰ÔmH›¦PÝ<Źm돣ÍÓĎŁ‰E"TÄČ”|ż­ŢŤĽ€®xĄŹvm8#äk]S&đÉ•ú¨­k‘#«ŹţÝjĂfȆ%ďV,ý•âÄ\2večĐH‹¤s›°ä`"änfVÔÚbŰl8µâl#Ąß Ç@ {ş/|3c±éG˛ş™wŰ|‹ľţg“,hŮç42G`Ó®|lĚ7öaáúC°wÇĐaŃ\›Ś]T߉ 7"¨„9ń®’ěÔ=ŚÜ$Fčăă‘Nńm:6‡Ý’‡ě!ócĘ)Ě˙v5.“ëč©gűBgNČϧV¸ă”+çőPw€… yF+ŕѧÍÂćĎD_š‹ÉËáëŇťäă ®ČEć–z×ÍqL’Á§ËhĺI´fëĄ/¶ç@“ă1ű«ŹĐĘ[IxŹ}›¶!ÚâşuëB•Ľ?m"A÷ †‚®ÁVDěú{lÂĘĹ”yńçcۡtôxúčbÁą]?céa6ŐJZIbvb×y-z=ŢÁ=¬\ŚŁŠd­ôry×đáW)Ęiń‹h‰Š_ęµ_˝:Ŕń(\JNEŢćS€OgL™ň"VtjŃÚął°k†uëIľmvź˝űúHĽtU¨B–…e_hŻ^¬šîˇµŕ¸&*ÁoÍÂăM6ěčhG§NŤ>g WĂCaBžU˛|A˝žč× Ř_ ‹I+,N,°šśÉ‰~Ę•F)2…\°ju~ţ]8…kÖGP›´^AŤÎâwĺÍÔŽ9ʛƇ‘u–Úm†ĐúŤˇ %ĹěĚO6B\tiâÖ­-‡%ITą2ęŠĚr¶*ŇÇĆÜďÖCŻm·§˝Ž&¤ o^ fů”2fą»ě’“p™»FĄ‚6r%ßľśěÝĚtzf›ĄdQ ’ĹOQ‡2™“ hZŰŁK•wV©“&™v˘Ő@t™aař ˛ŢiZ­†™Vµž~ Ýj‰śOëařdt’®íNC×}đ,üěÚ×ĆĹŹââĺ4<R›úÄdL‹§ß˙'úÔSĂÔĄ9äs>ǡ­Çaî÷,¬Jm{|řĹ˨CLN]3>^| évÔM.˝\Ţ5|xĹU wn’s˘IŤ,ü®—!đ‘Τô-ĐgčIő©Ń<4öĹ Ĺţš·n€ÝŰŁČ Ô±1f4čŇÉGOâJ˘~ÉŇöéŽFľ\¶©ÎVčDĘŘś“A®<Éç)¬€IaćR$1tX¦¤6{Źy Î_ŔŻ?îŔ•¸x$§çŇ ¤;6¤\K€CÓ=;Ű!k¶e×ÖŘ–pMhBT—®1X9ë]l Ał&-ĐqÄ4 ÖžĂ|Yj:/;›ęőő°· ©PĂ“üÍ‚bdٱIΛLMţöÜĘQjÔbÍ ‹=‡«)7‘M´7„@ÂÄÖ >Ť‹™GÚ'´5jŃ4–ęîa‘ĄbůwáTm |Š”ľ9™Ů 9!mĘ»@ äwťÜ+đ¨Ű€VJű…h-7ŚĄiÄ˝’˛>;űëë©$ \¤V&×·¦/Ô>:¤ź=C+:ŚjoxŇF‡™˛´ëŮj«ŮčÚ<‹wk^Âľ•?áęµHO“@˛”4ńF‡LÓ ťëi`Ô§#ϢBŤ•©‘j9ąÓtťş“Ň·BźN.1˙`x32hűף›ŇÉ%eä#€;˛ř~˘Ą" [®_O"ó• ˘ś”©ÄŮF’‘‚G<3Âî¨Ű´%°}3NDDâM CűőÇ%Rü‘'N!ŕ˘=ŰÂÓn†…&hŕEBĎą,G)L!¸X‚p(©ĺ*®ÍT¬˘Mą3TTĐ-Âş˘Ťí¶6S)#n¤édą)iHć±v¨«ÁL \<©ˇ®ÓźĽ× ÇFDäśŘ™>˘ýłobp¨żHŹó;;é¦x'#%nŁşČ‹Á‚Jˇ$̆‡9‰În°YŚĹÉi™íoP.á™e«ŚŕÓ 1Y¦çpr÷>Ü̦ oHęĽ ^ŤBˇsśĂᇑ@„´jßr«ąĐé)’ßlĽŽ+k–ŕl›7QWčSćg]ú-uČŮ9°[¬…ÓÇÁ‰…á Ő‘óľ°üIîÂU.d+)ö/«'ĐŞ j‡—FwŹ—¶«›ńţüí$@20Ź–Hź•V~$‹ÔĎË›ţ‹'Ň)^‡ć­ÂĐ«I-lß}V ”z'ü‰&hÖ`ĺűÂbi…Ă.›¸2b¸Ń JÚ+Wő"ąlR*ądŐđŔ ›f$Heş bÉ”)D—˛ú‹{±ĺ2E=Đ uä ůĽyS/ ,ÖoÂeÚ@tř6G‘† ĄÚý+·ŃFk 4©UÍZë°{-"i·kŰČÇKľpq ‚ĎŽ u9yG; býôí ÁYR›µ˛˙”~«¦ŕßS&Ňćđ@tmÄĽěÔ€ÂMBHygźCĽ‘ju¶“/.ŁYž„ŁkńżíÉčňŘł4cć|:Ť(>*Ž6mµŠBÖjÚ&¨lčM4X©.m­ş‚…v6‚\[lSś)ůŞŕ÷oŮ"jűeŇg±ŮGě“Ô×ʸú4@¨¸|ä˛d:tjH.*š˝‚ŃŠ Цx=Ĺ·j ů4$eĎ%ňz FNţ˙÷8Ńź‚EágD׎ĐńKę·( Ô_§kěŇĄšČ©F÷~JeYý.iÖĚ7!Ů%Ţ5O…ß«ęˇcmň'lŶżň„Nł6ěćˇńÜ”‚lö$ôÉŠfD9Âh¬Pş3°;©oŇć˙őĂkJ-—RY~uę‘Ę’ź{¬?‰$ZĄżžÜ¶;÷ěŔöí۱yŐŹřú×$Â:ĽúÚŁ¤ę˘K;ŕĚrü¸;zCbwŻÄdčŇ >v¬v„†Q š6at܆šÍBDČ—Ü*XMľÓTcKţVÔG×ÚôÓŞ. >ö,âoü…“;~Ágżž&MÖ~Ľ»)­Ą?lFRv®_ŹđÓä;r›1ńgÖbKÔ5$’_5::×É«ŕEËuZs»…ZG)&rťĐŠMńn‚.Á@ęđgTŇ"đËŇT˘:5ňÍ,öÓJV¶C‚`—ÁîRí]ĽőEhi~ 2ß¶hěk'ź5ŁÉ!Íh߆Ĺk[˘‰żť&„˘xBű4äúvŔÖ>E˙MW©ďBÉbľ<ěÔiîř±R+ŇUŞĹ–—)ÜÖ$K»ň‚ě'ČĎ®…3±ţp­S‘đ˙ÎÁ’ëbŚö7Ř\ž‡Ř8’›ýX0ý: ©Ž<;+Kň#;‡Yóv#Ť^đ;żű7Áňé҆ÜZtBZáŃŐXją,˘8Źş(§«G0Sł[ ˝ŇîŚgčbI©äŇŮ żÜçČâââ¤ńT&(dt ¦¦îV‹Ënł Oź ŁtÂ…NAŁFňá*˝üQÇĎ“üątj#+Ç)ĚäeŃĐ&¨Ž âLdČľSxŔßĎ 2K.Ҳ ]ť?tj ŇÓôÎrrčjúCmŃ#-ŰâĽĎˇ{Ú.±M9d¤Ô,deů8_ł7ć¤Ă,÷‚mÄfÜĚ$ëŠŇi3Oă(lÎÚI ÉIńëÓŇɆ×Đ» ą‚5¬$şëĐĎP‡ť™E§R C°g1~Üď‰wf˝ ß)kžVşz֟Ɲϥ7csb7ŕ?żźĆłS˙n>yHËĚ«TĹĎčSh‰ŢjŘé$R:;oî ż.<‘ŃŞ¦¦ŹfÚŚÔ;Ľč^EaÉpiŕWSGJ›6#łíĐŃĎ>°|Ůn±¶ôăőÝVô7•Ţ Ő„Ô p•ĂÇźxL{.é´ˇ)ŔkKŔł~„bĐ$|đčČ&ž°ŤÔĘ rµ'ísĐĆ;% Ť'É*ű© ;mĘćAĄó†ŤőÓ¬‚?őßęŇgš…¬ĆÓ~„›Ý’Ě<|}=péŹ)řţLW|>}LI©°R˝T/ů’ť‘M}t•wI–4mP{Ą•ËĘÄŠ·uo" »víZĄ …’,7:tď`J×ę¦!ď6%µ)§ E¶ gł˛e4é)ZŽËŮF,{  ŁMX%Ł×FtÎ8W2•ÔąĐőÇý‹3§- żÎ^ y/·ňpQP2ZúSyĘf·°ŤRşˇźCŘ1.Ž6Ž˙ŚęĽŚä˛Ůá>ÖÍÁŞřîöĎî´™^˛l$ţďÔཹoˇž9‹Ü"ělĚß$Crră±#Ş6’R $’3•’6§iXiEG’ â•­_cYd;Ěš=Ú“3×!Ők-N¶Šér©ä˛˛<úţAŕŽ|üeÉfµ•L't*Ié3ÚJjÓN ßB«I§;Č…!)}V–)|‹…ÎÜKX¤K°ć÷§ĄĎň*ęŕ‰şăú‰(Č˝E×Xą. †‡´0˛eÄ Ę‚×_ěHÇ9rîĄĎđLo˙Ď"Ć@–´P1ß9ŽĘDç—^@}­$r˙>ĄĎdF #ĄUú¬É™PFPúB„xęKI+\;ŃĹ&{’&{eTú¬¶RÉ%ËČĂ}Ť@ĄYü÷3ĘrrźřÓ)¦|wE1`Čhđ׬ˇ&—RFĄý\C1¤T~4ą†jÔô†%3ť&˝’lgzéÍ߲Ľ dŃQÉę´şšäÎ4#-ßťYťzÇűr/! »zőjIŁě^˘•ÓÂŕp8€@É+ë h€WÁŕp8÷ĺ:ÎyouSĂŕp8eA€[üeA‹çĺp8ŐnńW&ň.p8˛ Ŕ-ţ˛ Ĺór8j€WüŐ€‰Ľ ŽG ,pWOYĐây9Ž@5@€[üŐ€‰Ľ ŽG ,ü?‡V#ú9}nýIEND®B`‚nipype-0.11.0/doc/devel/gitwash/set_up_fork.rst000066400000000000000000000036771257611314500215030ustar00rootroot00000000000000.. _set-up-fork: ================== Set up your fork ================== First you follow the instructions for :ref:`forking`. Overview ======== :: git clone git@github.com:your-user-name/nipype.git cd nipype git remote add upstream git://github.com/nipy/nipype.git In detail ========= Clone your fork --------------- #. Clone your fork to the local computer with ``git clone git@github.com:your-user-name/nipype.git`` #. Investigate. Change directory to your new repo: ``cd nipype``. Then ``git branch -a`` to show you all branches. You'll get something like:: * master remotes/origin/master This tells you that you are currently on the ``master`` branch, and that you also have a ``remote`` connection to ``origin/master``. What remote repository is ``remote/origin``? Try ``git remote -v`` to see the URLs for the remote. They will point to your github_ fork. Now you want to connect to the upstream `nipype github`_ repository, so you can merge in changes from trunk. .. _linking-to-upstream: Linking your repository to the upstream repo -------------------------------------------- :: cd nipype git remote add upstream git://github.com/nipy/nipype.git ``upstream`` here is just the arbitrary name we're using to refer to the main nipype_ repository at `nipype github`_. Note that we've used ``git://`` for the URL rather than ``git@``. The ``git://`` URL is read only. This means we that we can't accidentally (or deliberately) write to the upstream repo, and we are only going to use it to merge into our own code. Just for your own satisfaction, show yourself that you now have a new 'remote', with ``git remote -v show``, giving you something like:: upstream git://github.com/nipy/nipype.git (fetch) upstream git://github.com/nipy/nipype.git (push) origin git@github.com:your-user-name/nipype.git (fetch) origin git@github.com:your-user-name/nipype.git (push) .. include:: links.inc nipype-0.11.0/doc/devel/gitwash/this_project.inc000066400000000000000000000002561257611314500216070ustar00rootroot00000000000000.. nipype .. _nipype: http://nipy.org/nipype .. _`nipype github`: http://github.com/nipy/nipype .. _`nipype mailing list`: http://mail.scipy.org/mailman/listinfo/nipy-devel nipype-0.11.0/doc/devel/index.rst000066400000000000000000000010231257611314500166030ustar00rootroot00000000000000.. _developers-guide-index: ================= Developer Guide ================= :Release: |version| :Date: |today| Since nipype is part of the NIPY_ project, we follow the same conventions documented in the `NIPY Developers Guide `_. For bleeding-edge version help see `Nightly documentation `_ .. toctree:: :maxdepth: 2 writing_custom_interfaces gitwash/index architecture provenance software_using_nipype .. include:: ../links_names.txt nipype-0.11.0/doc/devel/interface_specs.rst000066400000000000000000000541341257611314500206440ustar00rootroot00000000000000.. _interface_specs: ======================== Interface Specifications ======================== Before you start ---------------- Nipype is a young project maintained by an enthusiastic group of developers. Even though the documentation might be sparse or cryptic at times we strongly encourage you to contact us on the official nipype developers mailing list in case of any troubles: nipy-devel@neuroimaging.scipy.org (we are sharing a mailing list with the nipy community therefore please add ``[nipype]`` to the messsage title). Overview -------- We're using the `Enthought Traits `_ package for all of our inputs and outputs. Traits allows us to validate user inputs and provides a mechanism to handle all the *special cases* in a simple and concise way though metadata. With the metadata, each input/output can have an optional set of metadata attributes (described in more detail below). The machinery for handling the metadata is located in the base classes, so all subclasses use the same code to handle these cases. This is in contrast to our previous code where every class defined it's own _parse_inputs, run and aggregate_outputs methods to handle these cases. Which of course leads to a dozen different ways to solve the same problem. Traits is a big package with a lot to learn in order to take full advantage of. But don't be intimidated! To write a Nipype Trait Specification, you only need to learn a few of the basics of Traits. Here are a few starting points in the documentation: * What are Traits? The `Introduction in the User Manual `_ gives a brief description of the functionality traits provides. * Traits and metadata. The `second section of the User Manual `_ gives more details on traits and how to use them. Plus there a section describing metadata, including the metadata all traits have. * If your interested in more of a *big picture* overview, `Gael wrote a good tutorial `_ that shows how to write a scientific application using traits for the benefit of the generated UI components. (For now, Nipype is not taking advantage of the generated UI feature of traits.) Traits version ^^^^^^^^^^^^^^ We're using Traits version 3.x which can be install as part of `EPD `_ or from `pypi `_ More documentation ^^^^^^^^^^^^^^^^^^ Not everything is documented in the User Manual, in those cases the `enthought-dev mailing list `_ or the `API docs `_ is your next place to look. Nipype Interface Specifications ------------------------------- Each interface class defines two specifications: 1) an InputSpec and 2) an OutputSpec. Each of these are prefixed with the class name of the interfaces. For example, Bet has these specs: - BETInputSpec - BETOutputSpec Each of these Specs are classes, derived from a base TraitedSpec class (more on these below). The InputSpec consists of attributes which correspond to different parameters for the tool they wrap/interface. In the case of a command-line tool like Bet, the InputSpec attributes correspond to the different command-line parameters that can be passed to Bet. If you are familiar with the Nipype 0.2 code-base, these attributes are the same as the keys in the opt_map dictionaries. When an interfaces class is instantiated, the InputSpec is bound to the ``inputs`` attribute of that object. Below is an example of how the ``inputs`` appear to a user for Bet:: >>> from nipype.interfaces import fsl >>> bet = fsl.BET() >>> type(bet.inputs) >>> bet.inputs. bet.inputs.__class__ bet.inputs.center bet.inputs.__delattr__ bet.inputs.environ bet.inputs.__doc__ bet.inputs.frac bet.inputs.__getattribute__ bet.inputs.functional bet.inputs.__hash__ bet.inputs.hashval bet.inputs.__init__ bet.inputs.infile bet.inputs.__new__ bet.inputs.items bet.inputs.__reduce__ bet.inputs.mask bet.inputs.__reduce_ex__ bet.inputs.mesh bet.inputs.__repr__ bet.inputs.nooutput bet.inputs.__setattr__ bet.inputs.outfile bet.inputs.__str__ bet.inputs.outline bet.inputs._generate_handlers bet.inputs.outputtype bet.inputs._get_hashval bet.inputs.radius bet.inputs._hash_infile bet.inputs.reduce_bias bet.inputs._xor_inputs bet.inputs.skull bet.inputs._xor_warn bet.inputs.threshold bet.inputs.args bet.inputs.vertical_gradient Each Spec inherits from a parent Spec. The parent Specs provide attribute(s) that are common to all child classes. For example, FSL InputSpecs inherit from interfaces.fsl.base.FSLTraitedSpec. FSLTraitedSpec defines an ``outputtype`` attribute, which stores the file type (NIFTI, NIFTI_PAIR, etc...) for all generated output files. InputSpec class hierarchy ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Below is the current class hierarchy for InputSpec classes (from base class down to subclasses).: ``TraitedSpec``: Nipype's primary base class for all Specs. Provides initialization, some nipype-specific methods and any trait handlers we define. Inherits from traits.HasTraits. ``BaseInterfaceInputSpec``: Defines inputs common to all Interfaces (``ignore_exception``). If in doubt inherit from this. ``CommandLineInputSpec``: Defines inputs common to all command-line classes (``args`` and ``environ``) ``FSLTraitedSpec``: Defines inputs common to all FSL classes (``outputtype``) ``SPMCommandInputSpec``: Defines inputs common to all SPM classes (``matlab_cmd``, ``path``, and ``mfile``) ``FSTraitedSpec``: Defines inputs common to all FreeSurfer classes (``sbjects_dir``) ``MatlabInputSpec``: Defines inputs common to all Matlab classes (``script``, ``nodesktop``, ``nosplash``, ``logfile``, ``single_comp_thread``, ``mfile``, ``script_file``, and ``paths``) ``SlicerCommandLineInputSpec``: Defines inputs common to all Slicer classes (``module``) Most developers will only need to code at the the interface-level (i.e. implementing custom class inheriting from one of the above classes). Output Specs ^^^^^^^^^^^^ The OutputSpec defines the outputs that are generated, or possibly generated depending on inputs, by the tool. OutputSpecs inherit from ``interfaces.base.TraitedSpec`` directly. Traited Attributes ------------------ Each specification attribute is an instance of a Trait class. These classes encapsulate many standard Python types like Float and Int, but with additional behavior like type checking. (*See the documentation on traits for more information on these trait types.*) To handle unique behaviors of our attributes we us traits metadata. These are keyword arguments supplied in the initialization of the attributes. The base classes ``BaseInterface`` and ``CommandLine`` (defined in ``nipype.interfaces.base``) check for the existence/or value of these metadata and handle the inputs/outputs accordingly. For example, all mandatory parameters will have the ``mandatory = True`` metadata:: class BetInputSpec(FSLTraitedSpec): infile = File(exists=True, desc = 'input file to skull strip', argstr='%s', position=0, mandatory=True) Common ^^^^^^ ``exists`` For files, use ``nipype.interfaces.base.File`` as the trait type. If the file must exist for the tool to execute, specify ``exists = True`` in the initialization of File (as shown in BetInputSpec above). This will trigger the underlying traits code to confirm the file assigned to that *input* actually exists. If it does not exist, the user will be presented with an error message:: >>> bet.inputs.infile = 'does_not_exist.nii' ------------------------------------------------------------ Traceback (most recent call last): File "", line 1, in File "/Users/cburns/local/lib/python2.5/site-packages/nipype/interfaces/base.py", line 76, in validate self.error( object, name, value ) File "/Users/cburns/local/lib/python2.5/site-packages/enthought/traits/trait_handlers.py", line 175, in error value ) TraitError: The 'infile' trait of a BetInputSpec instance must be a file name, but a value of 'does_not_exist.nii' was specified. ``hash_files`` To be used with inputs that are defining output filenames. When this flag is set to false any Nipype will not try to hash any files described by this input. This is useful to avoid rerunning when the specified output file already exists and has changed. ``desc`` All trait objects have a set of default metadata attributes. ``desc`` is one of those and is used as a simple, one-line docstring. The ``desc`` is printed when users use the ``help()`` methods. **Required:** This metadata is required by all nipype interface classes. ``usedefault`` Set this metadata to True when the *default value* for the trait type of this attribute is an acceptable value. All trait objects have a default value, ``traits.Int`` has a default of ``0``, ``traits.Float`` has a default of ``0.0``, etc... You can also define a default value when you define the class. For example, in the code below all objects of ``Foo`` will have a default value of 12 for ``x``:: >>> import enthought.traits.api as traits >>> class Foo(traits.HasTraits): ... x = traits.Int(12) ... y = traits.Int ... >>> foo = Foo() >>> foo.x 12 >>> foo.y 0 Nipype only passes ``inputs`` on to the underlying package if they have been defined (more on this later). So if you specify ``usedefault = True``, you are telling the parser to pass the default value on to the underlying package. Let's look at the InputSpec for SPM Realign:: class RealignInputSpec(BaseInterfaceInputSpec): jobtype = traits.Enum('estwrite', 'estimate', 'write', desc='one of: estimate, write, estwrite', usedefault=True) Here we've defined ``jobtype`` to be an enumerated trait type, ``Enum``, which can be set to one of the following: ``estwrite``, ``estimate``, or ``write``. In a container, the default is always the first element. So in this case, the default will be ``estwrite``:: >>> from nipype.interfaces import spm >>> rlgn = spm.Realign() >>> rlgn.inputs.infile >>> rlgn.inputs.jobtype 'estwrite' ``xor`` and ``requires`` Both of these accept a list of trait names. The ``xor`` metadata reflects mutually exclusive traits, while the requires metadata reflects traits that have to be set together. When a xor-ed trait is set, all other traits belonging to the list are set to Undefined. The function check_mandatory_inputs ensures that all requirements (both mandatory and via the requires metadata are satisfied). These are also reflected in the help function. ``copyfile`` This is metadata for a File or Directory trait that is relevant only in the context of wrapping an interface in a `Node` and `MapNode`. `copyfile` can be set to either `True` or `False`. `False` indicates that contents should be symlinked, while `True` indicates that the contents should be copied over. ``min_ver`` and ``max_ver`` These metadata determine if a particular trait will be available when a given version of the underlying interface runs. Note that this check is performed at runtime.:: class RealignInputSpec(BaseInterfaceInputSpec): jobtype = traits.Enum('estwrite', 'estimate', 'write', min_ver='5', usedefault=True) ``deprecated`` and ``new_name`` This is metadata for removing or renaming an input field from a spec.:: class RealignInputSpec(BaseInterfaceInputSpec): jobtype = traits.Enum('estwrite', 'estimate', 'write', deprecated='0.8', desc='one of: estimate, write, estwrite', usedefault=True) In the above example this means that the `jobtype` input is deprecated and will be removed in version 0.8. Deprecation should be set to two versions from current release. Raises `TraitError` after package version crosses the deprecation version. For inputs that are being renamed, one can specify the new name of the field.:: class RealignInputSpec(BaseInterfaceInputSpec): jobtype = traits.Enum('estwrite', 'estimate', 'write', deprecated='0.8', new_name='job_type', desc='one of: estimate, write, estwrite', usedefault=True) job_type = traits.Enum('estwrite', 'estimate', 'write', desc='one of: estimate, write, estwrite', usedefault=True) In the above example, the `jobtype` field is being renamed to `job_type`. When `new_name` is provided it must exist as a trait, otherwise an exception will be raised. .. note:: The version information for `min_ver`, `max_ver` and `deprecated` has to be provided as a string. For example, `min_ver='0.1'`. CommandLine ^^^^^^^^^^^ ``argstr`` The metadata keyword for specifying the format strings for the parameters. This was the *value* string in the opt_map dictionaries of Nipype 0.2 code. If we look at the ``FlirtInputSpec``, the ``argstr`` for the reference file corresponds to the argument string I would need to provide with the command-line version of ``flirt``:: class FlirtInputSpec(FSLTraitedSpec): reference = File(exists = True, argstr = '-ref %s', mandatory = True, position = 1, desc = 'reference file') **Required:** This metadata is required by all command-line interface classes. ``position`` This metadata is used to specify the position of arguments. Both positive and negative values are accepted. ``position = 0`` will position this argument as the first parameter after the command name. ``position = -1`` will position this argument as the last parameter, after all other parameters. ``genfile`` If True, the ``genfile`` metadata specifies that a filename should be generated for this parameter *if-and-only-if* the user did not provide one. The nipype convention is to automatically generate output filenames when not specified by the user both as a convenience for the user and so the pipeline can easily gather the outputs. Requires ``_gen_filename()`` method to be implemented. This way should be used if the desired file name is dependent on some runtime variables (such as file name of one of the inputs, or current working directory). In case when it should be fixed it's recommended to just use ``usedefault``. ``sep`` For List traits the string with witch elements of the list will be joined. ``name_source`` Indicates the list of input fields from which the value of the current File output variable will be drawn. This input field must be the name of a File. Chaining is allowed, meaning that an input field can point to another as ``name_source``, which also points as ``name_source`` to a third field. In this situation, the templates for substitutions are also accumulated. ``name_template`` By default a ``%s_generated`` template is used to create the output filename. This metadata keyword allows overriding the generated name. ``keep_extension`` Use this and set it ``True`` if you want the extension from the input to be kept. SPM ^^^ ``field`` name of the structure refered by the SPM job manager **Required:** This metadata is required by all SPM-mediated interface classes. Defining an interface class --------------------------- Common ^^^^^^ When you define an interface class, you will define these attributes and methods: * ``input_spec``: the InputSpec * ``output_spec``: the OutputSpec * ``_list_outputs()``: Returns a dictionary containing names of generated files that are expected after package completes execution. This is used by ``BaseInterface.aggregate_outputs`` to gather all output files for the pipeline. CommandLine ^^^^^^^^^^^ For command-line interfaces: * ``_cmd``: the command-line command If you used genfile: * ``_gen_filename(name)``: Generate filename, used for filenames that nipype generates as a convenience for users. This is for parameters that are required by the wrapped package, but we're generating from some other parameter. For example, ``BET.inputs.outfile`` is required by BET but we can generate the name from ``BET.inputs.infile``. Override this method in subclass to handle. And optionally: * ``_redirect_x``: If set to True it will make Nipype start Xvfb before running the interface and redirect X output to it. This is useful for commandlines that spawn a graphical user interface. * ``_format_arg(name, spec, value)``: For extra formatting of the input values before passing them to generic ``_parse_inputs()`` method. For example this is the class definition for Flirt, minus the docstring:: class FLIRTInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='-in %s', mandatory=True, position=0, desc='input file') reference = File(exists=True, argstr='-ref %s', mandatory=True, position=1, desc='reference file') out_file = File(argstr='-out %s', desc='registered output file', name_source=['in_file'], name_template='%s_flirt', position=2, hash_files=False) out_matrix_file = File(argstr='-omat %s', name_source=['in_file'], keep_extension=True, name_template='%s_flirt.mat', desc='output affine matrix in 4x4 asciii format', position=3, hash_files=False) out_log = File(name_source=['in_file'], keep_extension=True, requires=['save_log'], name_template='%s_flirt.log', desc='output log') ... class FLIRTOutputSpec(TraitedSpec): out_file = File(exists=True, desc='path/name of registered file (if generated)') out_matrix_file = File(exists=True, desc='path/name of calculated affine transform ' '(if generated)') out_log = File(desc='path/name of output log (if generated)') class Flirt(FSLCommand): _cmd = 'flirt' input_spec = FlirtInputSpec output_spec = FlirtOutputSpec There are two possible output files ``outfile`` and ``outmatrix``, both of which can be generated if not specified by the user. Also notice the use of ``self._gen_fname()`` - a FSLCommand helper method for generating filenames (with extensions conforming with FSLOUTPUTTYPE). See also :doc:`cmd_interface_devel`. SPM ^^^ For SPM-mediated interfaces: * ``_jobtype`` and ``_jobname``: special names used used by the SPM job manager. You can find them by saving your batch job as an .m file and looking up the code. And optionally: * ``_format_arg(name, spec, value)``: For extra formatting of the input values before passing them to generic ``_parse_inputs()`` method. Matlab ^^^^^^ See :doc:`matlab_interface_devel`. Python ^^^^^^ See :doc:`python_interface_devel`. Undefined inputs ---------------- All the inputs and outputs that were not explicitly set (And do not have a usedefault flag - see above) will have Undefined value. To check if something is defined you have to explicitly call ``isdefiend`` function (comparing to None will not work). Example of inputs ----------------- Below we have an example of using Bet. We can see from the help which inputs are mandatory and which are optional, along with the one-line description provided by the ``desc`` metadata:: >>> from nipype.interfaces import fsl >>> fsl.BET.help() Inputs ------ Mandatory: infile: input file to skull strip Optional: args: Additional parameters to the command center: center of gravity in voxels environ: Environment variables (default={}) frac: fractional intensity threshold functional: apply to 4D fMRI data mask: create binary mask image mesh: generate a vtk mesh brain surface nooutput: Don't generate segmented output outfile: name of output skull stripped image outline: create surface outline image outputtype: None radius: head radius reduce_bias: bias field and neck cleanup skull: create skull image threshold: apply thresholding to segmented brain image and mask vertical_gradient: vertical gradient in fractional intensity threshold (-1, 1) Outputs ------- maskfile: path/name of binary brain mask (if generated) meshfile: path/name of vtk mesh file (if generated) outfile: path/name of skullstripped file outlinefile: path/name of outline file (if generated) Here we create a bet object and specify the required input. We then check our inputs to see which are defined and which are not:: >>> bet = fsl.BET(infile = 'f3.nii') >>> bet.inputs args = center = environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} frac = functional = infile = f3.nii mask = mesh = nooutput = outfile = outline = outputtype = NIFTI_GZ radius = reduce_bias = skull = threshold = vertical_gradient = >>> bet.cmdline 'bet f3.nii /Users/cburns/data/nipype/s1/f3_brain.nii.gz' We also checked the command-line that will be generated when we run the command and can see the generated output filename ``f3_brain.nii.gz``. nipype-0.11.0/doc/devel/matlab_interface_devel.rst000066400000000000000000000072441257611314500221460ustar00rootroot00000000000000.. matlab_interface_devel: =========================== How to wrap a MATLAB script =========================== This is minimal script for wrapping MATLAB code. You should replace the MATLAB code template, and define approriate inputs and outputs. Example 1 +++++++++ .. testcode:: from nipype.interfaces.matlab import MatlabCommand from nipype.interfaces.base import TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File import os from string import Template class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True) out_file = File('cmatrix.mat', usedefault=True) class ConmapTxt2MatOutputSpec(TraitedSpec): out_file = File(exists=True) class ConmapTxt2Mat(BaseInterface): input_spec = ConmapTxt2MatInputSpec output_spec = ConmapTxt2MatOutputSpec def _run_interface(self, runtime): d = dict(in_file=self.inputs.in_file, out_file=self.inputs.out_file) #this is your MATLAB code template script = Template("""in_file = â€$in_file'; out_file = â€$out_file'; ConmapTxt2Mat(in_file, out_file); exit; """).substitute(d) # mfile = True will create an .m file with your script and executed. # Alternatively # mfile can be set to False which will cause the matlab code to be # passed # as a commandline argument to the matlab executable # (without creating any files). # This, however, is less reliable and harder to debug # (code will be reduced to # a single line and stripped of any comments). mlab = MatlabCommand(script=script, mfile=True) result = mlab.run() return result.runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs Example 2 +++++++++ By subclassing **MatlabCommand** for your main class, and **MatlabInputSpec** for your input and output spec, you gain access to some useful MATLAB hooks .. testcode:: import os from nipype.interfaces.base import File, traits from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec class HelloWorldInputSpec( MatlabInputSpec): name = traits.Str( mandatory = True, desc = 'Name of person to say hello to') class HelloWorldOutputSpec( MatlabInputSpec): matlab_output = traits.Str( ) class HelloWorld( MatlabCommand): """ Basic Hello World that displays Hello in MATLAB Returns ------- matlab_output : capture of matlab output which may be parsed by user to get computation results Examples -------- >>> hello = HelloWorld() >>> hello.inputs.name = 'hello_world' >>> out = hello.run() >>> print out.outputs.matlab_output """ input_spec = HelloWorldInputSpec output_spec = HelloWorldOutputSpec def _my_script(self): """This is where you implement your script""" script = """ disp('Hello %s Python') two = 1 + 1 """%(self.inputs.name) return script def run(self, **inputs): ## inject your script self.inputs.script = self._my_script() results = super(MatlabCommand, self).run( **inputs) stdout = results.runtime.stdout # attach stdout to outputs to access matlab results results.outputs.matlab_output = stdout return results def _list_outputs(self): outputs = self._outputs().get() return outputs nipype-0.11.0/doc/devel/provenance.rst000066400000000000000000000016211257611314500176400ustar00rootroot00000000000000================ W3C PROV support ================ Overview -------- We're using the the `W3C PROV data model `_ to capture and represent provenance in Nipype. For an overview see: `PROV-DM overview `_ Each interface writes out a provenance.json (currently prov-json) or provenance.rdf (if rdflib is available) file. The workflow engine can also write out a provenance of the workflow if instructed. This is very much an experimental feature as we continue to refine how exactly the provenance should be stored and how such information can be used for reporting or reconstituting workflows. By default provenance writing is disabled for the 0.9 release, to enable insert the following code at the top of your script:: >>> from nipype import config >>> config.enable_provenance() nipype-0.11.0/doc/devel/python_interface_devel.rst000066400000000000000000000035501257611314500222230ustar00rootroot00000000000000.. python_interface_devel: =========================== How to wrap a Python script =========================== This is a minimal pure python interface. As you can see all you need to do is to do is to define inputs, outputs, _run_interface() (not run()), and _list_outputs. .. testcode:: from nipype.interfaces.base import BaseInterface, \ BaseInterfaceInputSpec, traits, File, TraitedSpec from nipype.utils.filemanip import split_filename import nibabel as nb import numpy as np import os class SimpleThresholdInputSpec(BaseInterfaceInputSpec): volume = File(exists=True, desc='volume to be thresholded', mandatory=True) threshold = traits.Float(desc='everything below this value will be set to zero', mandatory=True) class SimpleThresholdOutputSpec(TraitedSpec): thresholded_volume = File(exists=True, desc="thresholded volume") class SimpleThreshold(BaseInterface): input_spec = SimpleThresholdInputSpec output_spec = SimpleThresholdOutputSpec def _run_interface(self, runtime): fname = self.inputs.volume img = nb.load(fname) data = np.array(img.get_data()) active_map = data > self.inputs.threshold thresholded_map = np.zeros(data.shape) thresholded_map[active_map] = data[active_map] new_img = nb.Nifti1Image(thresholded_map, img.get_affine(), img.get_header()) _, base, _ = split_filename(fname) nb.save(new_img, base + '_thresholded.nii') return runtime def _list_outputs(self): outputs = self._outputs().get() fname = self.inputs.volume _, base, _ = split_filename(fname) outputs["thresholded_volume"] = os.path.abspath(base + '_thresholded.nii') return outputs nipype-0.11.0/doc/devel/software_using_nipype.rst000066400000000000000000000101721257611314500221240ustar00rootroot00000000000000.. _software_using_nipype: ===================== Software using Nipype ===================== Configurable Pipeline for the Analysis of Connectomes (C-PAC) ------------------------------------------------------------- `C-PAC `_ is an open-source software pipeline for automated preprocessing and analysis of resting-state fMRI data. C-PAC builds upon a robust set of existing software packages including AFNI, FSL, and ANTS, and makes it easy for both novice users and experts to explore their data using a wide array of analytic tools. Users define analysis pipelines by specifying a combination of preprocessing options and analyses to be run on an arbitrary number of subjects. Results can then be compared across groups using the integrated group statistics feature. C-PAC makes extensive use of Nipype Workflows and Interfaces. BRAINSTools ----------- `BRAINSTools `_ is a suite of tools for medical image processing focused on brain analysis. Brain Imaging Pipelines (BIPs) ------------------------------ `BIPs `_ is a set of predefined Nipype workflows coupled with a graphical interface and ability to save and share workflow configurations. It provides both Nipype Workflows and Interfaces. BROCCOLI -------- `BROCCOLI `_ is a piece of software for fast fMRI analysis on many core CPUs and GPUs. It provides Nipype Interfaces. Forward ------- `Forward `_ is set of tools simplifying the preparation of accurate electromagnetic head models for EEG forward modeling. It uses Nipype Workflows and Interfaces. Limbo ----- `Limbo `_ is a toolbox for finding brain regions that are neither significantly active nor inactive, but rather “in limbo”. It was build using custom Nipype Interfaces and Workflows. Lyman ----- `Lyman `_ is a high-level ecosystem for analyzing task based fMRI neuroimaging data using open-source software. It aims to support an analysis workflow that is powerful, flexible, and reproducible, while automating as much of the processing as possible. It is build upon Nipype Workflows and Interfaces. Medimsight ---------- `Medimsight `_ is a commercial service medical imaging cloud platform. It uses Nipype to interface with various neuroimaging software. MIA --- `MIA `_ MIA is a a toolkit for gray scale medical image analysis. It provides Nipype interfaces for easy integration with other software. Mindboggle ---------- `Mindboggle `_ software package automates shape analysis of anatomical labels and features extracted from human brain MR image data. Mindboggle can be run as a single command, and can be easily installed as a cross-platform virtual machine for convenience and reproducibility of results. Behind the scenes, open source Python and C++ code run within a Nipype pipeline framework. OpenfMRI -------- `OpenfMRI `_ is a repository for task based fMRI datasets. It uses Nipype for automated analysis of the deposited data. serial functional Diffusion Mapping (sfDM) ------------------------------------------ 'sfDM '_ is a software package for looking at changes in diffusion profiles of different tissue types across time. It uses Nipype to process the data. The Stanford CNI MRS Library (SMAL) ----------------------------------- `SMAL `_ is a library providing algorithms and methods to read and analyze data from Magnetic Resonance Spectroscopy (MRS) experiments. It provides an API for fitting models of the spectral line-widths of several different molecular species, and quantify their relative abundance in human brain tissue. SMAL uses Nipype Workflows and Interfaces. tract_querier ------------- `tract_querier `_ is a White Matter Query Language tool. It provides Nipype interfaces. nipype-0.11.0/doc/devel/writing_custom_interfaces.rst000066400000000000000000000002331257611314500227560ustar00rootroot00000000000000.. _writing_custom_interfaces: .. toctree:: :maxdepth: 2 interface_specs cmd_interface_devel matlab_interface_devel python_interface_devel nipype-0.11.0/doc/documentation.rst000066400000000000000000000021421257611314500172510ustar00rootroot00000000000000.. _documentation: ============= Documentation ============= .. htmlonly:: :Release: |version| :Date: |today| Previous versions: `0.10.0 `_ `0.9.2 `_ .. container:: doc2 .. admonition:: Guides .. hlist:: :columns: 2 * User .. toctree:: :maxdepth: 2 users/index .. toctree:: :maxdepth: 1 changes * Developer .. toctree:: :maxdepth: 2 api/index devel/index .. admonition:: Interfaces, Workflows and Examples .. hlist:: :columns: 2 * Workflows .. toctree:: :maxdepth: 1 :glob: interfaces/generated/*workflows* * Examples .. toctree:: :maxdepth: 1 :glob: users/examples/* * Interfaces .. toctree:: :maxdepth: 1 :glob: interfaces/generated/*algorithms* interfaces/generated/*interfaces* .. include:: links_names.txt nipype-0.11.0/doc/images/000077500000000000000000000000001257611314500151145ustar00rootroot00000000000000nipype-0.11.0/doc/images/nipype_architecture_overview2.png000066400000000000000000007646421257611314500237230ustar00rootroot00000000000000‰PNG  IHDR¨ĐĎr—sBIT|d pHYsppŇÝĄtEXtSoftwarewww.inkscape.org›î< IDATxśěÝwśUůÇńĎł›BHHB’Đ‹@!`Ŕ"˘ Ą(, E@”"E ‚@”Şt©Á(ŇĄ0¤§Pˇ„FĘîóűăĚMٽ˝ě~߯׼˛ÓÎ<{3;wž9gÎ1w§ł26îɢeźĆm`Ć`đ!Ŕ`0°`5 RDDDDD$?KpćĐÄ[8oo˝­oĐÔň÷zóőZX*ël Ş-X-šš÷Ŕř đś>µŽIDDDDD¤ žĆ™D“MňŐgN­u0Ĺč Ş-Yo(­Ý÷ß řĐ\ëDDDDDDjč ĚîÄýVzĎľĎiŚÄݎT[°Ţ@šşť ô¨u<""""""uh n?ń>3¨u iČŐXou7‹Ű‰@ßZÇ#"""""ŇîÂýDď3űąZ’¦ˇTĂšY<|îg::ĘÇ|đÇp{x‹&Ţ{x oz‹Ţ>żr‹”Á{=»Ósá`¬ŰzQÇŻ~v¶6Čł¤V°«ij9Ő{˝ţfĺ.NĂ$¨¶dýőimľŘ.ŹÍßÂěĽővzŻó€óÔňJÇ'"""""R+¶hčÖXó^¸ďŚÉc—E`ß÷Ţ3Ż­tl…hŐ–l°#­~+0¨ťÍ–aţgĚ˙BŻ7&7ĘKŔ""""""ĺdK†®GKóŢŕÇcŚě`ó_Ó{öOo­Jp¨űŐ ?ôLŮÄÁݧąé_mćŚ*†&"""""R·Ś­z°pÁá§ŰŮô.–ö8ŔĽüQµbKS· ŞaM,ú+°·łŮ=ťä«Ď|şj‰4ű`ăľôX~ćÇ«§lö-­_ńľŻż\ÍŘâę2A5¶ęÁ˘·{¦lň>fßôŐgŢ]͸DDDDDD•-Ţ`0îvMŮäCZm_cćcŐŚ+[}&¨‹6¸|BĘęétă+ŢsÖkU JDDDDD¤ÁÖ̢ażŽMŮä}ş±}­ň­¦Z´=¶hŘqí$§gIŻ•śŠÎńď=+“s-MŘd-V0ÉŢŰlŤjÇuVj‹†îMšV×UďR""""""ŤĚ– KkÓmŔŕ„ŐwŇ{öŢŐÎżę¦ŐŚÜšn 99ý©÷žu˘’S‘ňđ^Ż?IsóŽŔÜ„Ő_fѰ_V;¦ş¨AµyöŁÇŠÉŔĆ «ŻőŢł®vL""""""]->Ž&îz$¬=Č{ĎĽ®Z±ÔG j÷ç’śśţ‡ŢMß©v8""""""]…Ż1ëQĚŽHY{‘Íľfµb©y‚j Öß#) } ó}śW=(‘.ÄWźyp~ÂŞ5éć?«V5oâk‹‡ßŚóŐŘâeďä«Ďž\“ DDDDDDşhšĐvśÔĄ47oę«˝6«Ň1Ô´Ő– ›ś\¬äTDDDDD¤zoˇĄőŔŠŘŞž´´ü˘1Ô¶‰okÓŻ–Χµ:żĽ¬â}_ł?%¬:Čo0ŞŇÇŻY‚j‹7ŘřtÂŞs|Ť7ŢŻv<""""""xÓ™ cK ÷¤ ƲŞ] Şű± K_§wÓUŹEDDDDDDđŢŻ˝C+ç%¬ÚŐ߲’Ç®I‚jŽč|&aŐ©ęµWDDDDD¤Ć–,ů-0·Íň&ß»’‡­M jwßč[ú˝g˙µáČ*ľöÜ…¸Ol»Â*š Ć“Äę0ß‹6ŁŰřßo­E8"ťŤ™5C€~@_ gÂf/ąű[U LDDDDGSÓí¸ź[:Ć– ]Ď{˝ţf%YőŐظ'Îî +&U;‘ÎÄĚß>Śút°ËQŔ+—4&_}ćT[4üu`hÖbŁĹö.®Ä1«_şxůg5bK—°zË˝UŹĄBĚl[`PÂŞąî>µÚńHçffÍŔéŔŹ€^µŤFDDDD:óI¸™»¬3%¨­ţ¬ÍŇ{ť7W=–Ę9Ř7aůťŔWŞ‹tbfÖ ¸_ëXDDDD¤r»82¶t{oł5|ŕ Ę}¸ĽęŰĎPÍÔĽ·™Ů`Ó„Użr÷yŐŽ§‹ą%§""""R)˝×~Eď~ôĎZڝދ¶ž,÷᪟ C–ŞŮkcŰŢ+†K%¨bf;‡´łÉl`đ:°(aýôJÄ%""""ť‡óÔrcřłŔÎąkš“ňş’U5A5Ě`Řŕ6+ÜÔ“¨HáŽKYţđ#wż«šÁH§Ő6_kI¬x,YukPŃ=¶´…Ţ3Ű+"©Ě¬'°GÂŞV`_w˙_•C‘ÎkN²Š$¨M•(4•őJú%ŢŃř§"Űč‘°üV%§""""RfmTóΠ¶&ýjŢ+R¸­S–O«j""""Ň$ĺlť AMú%\ ŞHÖJY®ż')·NÚÄ×}`ÂR˝*R¸)Ëő÷$""""eÖô~ÂÂ5*r¤JÚKXÖRĺD:ŐS–ë}niXŐUŞÂĚš€AŔ0`MÂx¤ďŻ»űÇµŚ­̬°v4­Eô]ŕ]wŻ–±Ĺ™Y`0°aäyŔ,`Ž»{-cKbfC€uľ@` đA4Í­—óËĚš ˙÷Ł©/°XĽáîUmmfk{N. ś“sÝýjĆĹ3pÎőeŐĐĹŃôáZ±´Úq‰HצµŽ™™'&¬z×Ý/OŘľ/pp(0 Ú é°ÄĚ&W“LىäÖ†ŹLŮô3›W@Ń—¸űüBă‰bę|řb4 kgŰ9ŔÝŔ]Ŕ]cĆĘÜřLÂŞ˙s÷g¶ßř°ˇý~Rë‚ĎšŮÓŔá ëF§„˛ź™}˘p?r÷‹;Ř&çzŔřhlFűÍ9–›ŮŕßŔ?Ýýľ|ŽSŃßËvŔçŁéS$˙ d¶˙xx¸xÂÝËÖ˘#ú{Üř°;!LŰö Vť“wW"1ŚäŻ_ĆC;ŘĹÍl.đ?ŕ‰hşĎÝ–;6‘ «fŤ-~pNÎBg˘÷™•tްĚě`ß„UwşűW (§X‘°jş»o•µ]7ŕ,ŕŇ›~&™ śčî7°fV©“f„»Ď,0–Őc€~EóMŕ4B˛^tóŘ(i?7aŐwż*k»O—›çQěç˙G/WŠ7Ü=591ł‘Ŕ7;¶JŰ.OOţćo)ĺómOÔZ`?Â˙ă%5¸ řSˇça,ž5€ESź"Šś\[Žô(Q>ř>Đ«Äâ–’čÜýµRc‘Ć`‹Fl ­OÇĎňŢł6(÷±ŞýŞ”™™ N˘°äB-ăőfvvŮ«3;x8›â’SµZ—SÍlxąb‹3ł&3;¸źü’SH®U­(3ű2đ*á3-59…Pëz0)J”ĘĘĚĆjAo ´äB3ëźFS±ńJřü~NqÉ)ŔpŕŻŔQsꢙŮg€ qJMN‰Ęř*ĄÖ""""‰” 603Ű”PCµc‰Eý¬Ń’T3;¸–T”Ă6Ŕăf¶m™Ę‹»8h.`źZü}–#‰I˛đ¤™mP®Íě[„„żćÉ’ż!<ěX»LĹnO8'ó} Źé „ÚÎAeŠGDDD¤âôj2ł~Ŕ$ʇąŚĐ\q.ˇnÚy'3r’™ýÝÝ/k e5{ľ řv›.ţKř >$Ôf &$˘=Rö ۞黲psôů.+%3;ťPKŮ‘ŔK„Î> śkj)×/%†¬Xş×űw°éRÂ9ů.0źđ.ď`kŇß•~EzręŔß G’:äŠŢYýp*°eBMńÇąűňWÄď{wJY”ůsý,!iK:Öl`çĘ2B'6­)ĺ]T`l'ćůőw`d>‹‹RĘߣÄr÷Ź>ă›MÇ­Čr¶&4?OбĄŘĎ€đ^ě˘v>ß»Ť‹(·;!ą˙/0±€ýľÜN,ŻŰPV!IM+ďÜ<Ëé|śRĆŻK87š=ßěYę9¬I“&Mš4ijś‰…lŰ&Ź[8lf%ŽĄwPßăŔ§Ü}j>{oq7ŕí”M&”+°r2łţ„Ză¤sv2°­»˙;ßň<88$e“#˘ŢlËérŕ+^ß˝ź>lćîű»űăî^T/˛î> ř4đź„ŐMŔQ…–őÖ{éť]LHĐ îőŘÝ—»ű îľ ˇ¨|âY—Đëo’%ýţi1´şűYŔ)›gfůÔ`~ä¦Ö׹ű ůĆ“ß$w˙,áÝV‘˛S‚ÚŘŢöŤ’ÎĽąű‹ĐËpµŐó9™Ö3ďÎ%Ä""""RJP×e(ă)Ëű–ˇě˛†^Iş!_Nz p1¦“ÜĚ·Ôuž×ůزU27aY!ťP}&eůźÝ˝ĄđpŠŤ{š”\/˘ă!~ 1…Đ<<®ŁsňĄ”ĺŮFĄ…$"""RYµ1­ ô\[ޤwPˇŽT` ’;˘yˇŘNh’¸»›Ů«´#v‹‹žRâţu'·s#Ây˛F4ő wlܸ¤^eózż7zç2­yďů”QfŁIn.;ÍË3v.z6łY´íô¨Łs2-It÷ĺe('íuŤ2”].i‰IZío)ŢMXÖĎĚşąűŠ"ËśVJ@ő Úd?ŕó„qH‡Ó~2šŻ|„lNH€ă–S›Ő<'çŇ6AŤ?DÉáî3ÍěďŔž «żN¶ą¸7ęĚJDDD¤ć” 6¦´wĚ •–t5—©ürX7eůÍlfôsv˛dí,ëh}˙”c ą‰j>’š 73ŰžĚěBe^Č7AMKČ^-gŤeŇÎÉŻšŮ碟ËuN&uÄ´š™­îîIÍ3N>KzÇHýŁ 3{x0~ëĂJXEDD¤V” 6¦Ąµ Š’nĐaUÓŇjX‹âÔ†kF ˇr0ňÔ”¦i63Ëcřť´s ­‰zĄĄĹÓŹ<›-—ÁZ$żź €»O7ło†“ęžGyź¦#Ěě%ŕ~ŕ&ŕ!Ť{*"""Ő˘N’¤Ţ%˝ZmIďOćkQ٢¨‚hÜ×{èT29-DÚ9P®–…އs2©Éswż…Pű=«ň7'$©łĚě§Ń ‘ŠR ŞÔ»jŐHUJGµu#ę1ů˙hśÍÂ{µ˙fł ďî~L¨Ů_–˛ßőŔfE†–6®g-š÷Bť“îţ¨™m |8QD1ëšzofG»ű ĺŚQDDD$›T©wi5OŻV)†Z5%­¶ Ŕ¸”u/ż®+¦÷W3+ĄYz˝ő6ťvN>NHŘ«aaľşűRŕfv!ˇFu_`<°%…Ő’®7łíÝýřB‚É—T©w¤,żĂÝQŐH:13ëśť˛úŕ w/ĄąrZTůHKPK)łiçäMî~~U#)@ô®ďýŃ„™ v&Ś1ű9BšŹăĚě=w˙e%â‘®Mď J˝KKFV5ŠÎog`PÂň—KLNˇ´÷6ÓδŢt+­Sś“îţž»ßćî?t÷­€!Ŕ7«é¸ŐŔéf¶A…C‘.H ŞÔ»´Ţs7­jťß^)ËÓÁp&2ł”Öăň)Ë׏Ćh­¶NyNşűwżĆÝż lśBz2Ţ8®Jˇ‰H˘UęÝc)Ë·Źzś•ňŘ*eůťe(»˝N—:äî3€´q9K*»HiçäNf¶ZU#©w˙ČÝ϶ŢIŮlĎ*†$"""]„T)‡)Ëó±]îţđvÂŞnŔnĄ–/+%5—]âîIź}ˇĆ—ˇŚ‡S–§ŐüVŇd`~ÂňŐ ťuîţ&pHĘę‘Qí¸HŮ(A•rHëQt­2•_Ęň#ĘTľ„Ză–”Z¨™ő Ľ×Xާ,˙ş™­S†ňóćî-Ŕ)«Żb(Őraˇ$IçŤHŃ” J9,HYľv™ĘOwq3ëT5V5””Ś0ł¤Ž“ ±?Éť/ęf’Ç=íImŢ…L;'żbfŰW5’ s÷„a†’”ÜJBDDD$›T)‡÷R–—%Au÷żO§¬ľŘĚj5fg’ö¸u±FÍ?]ěţŮÜýŕ/)«lfŁËqśÜĽ˛n˘™­^Í`*)‚(­‡â·Ş‹t~JPĄžKY^Î÷ĎJYľp}t]Vf¶^ąË¬ciÉÖ÷Š)ĚĚš€?ĺěe÷·@kÂňnŔ5fVµagÜ˝Ht[ŕŞč3(«|ÎÉ ś·źz',źďî G#"""R%¨R˙MYţe3ۢLǸ¸?eÝ—€űĘĐ3of˙Gyz°m÷¤,˙Ş™M(¤ 3ë\ |µä¨˛¸űËŔE)«73łŤK9†™}ĘĚň}göZŕ‰”uűw›YYŢŃ4łĎ›Ů=¤7-Îö¨™Ý\ަĆfÖ¸8eő¤RˉS‚*ĺđ<đjÂrž4łłĚlS3KŞ…É‹»;á}Ć)›|xĆĚŽ7ł‚ÇÜ4łÍÍě3ű/ˇś/ѵţ>î"˝ł« Íěč(ńl—™Ť!ô¸űŤ¬ĹŢNŮ…ú1éIáHŕi3űy!çš™ő6łÍěAŕQ`§|ö‹:KÚx3e“ÝçäŃĹ4ů5ł­Ěět3{žđáóyîÚLx8đ¤™=afÇS«jf›wŁR6Ikr-"""R´˛7‹”®ÇÝÝĚţ ś›°şpJ4afiÍwr÷7Ú9Îűf¶đ8ÉM×ÎNŤj›žŢ>Z€~@_`ÂŤ÷h`{ ¤š·F}¶~–°ş7đŕh3ű=0x…06iÂgůiBRôEÚ&ö§{“žčçr3ŰJň;νŁăcf˙ţĹű.áčô†c€±Ŕî„!bЉgŽ™íCHĘ“Ć@]ŹđŮťĹóP{ćśtÂůŘŹpţfÎɱ¤ż÷Y±Ńô;3› < Lžćšé.6ł>„ά[ßƵSî î~oâɡUĘĺ"ŕŰ„wBŰÓ7š’tx>şűłf6¸Ťd$éO¨mÝżŁň$ÇŻIć¦)ë7&·ąg+×2ßAxxď’Ł‹¸űf¶3ˇÖ7-‰Mĺî“ÍlWBOĂiÍĚ«O #VWâî{ŢŁo\G׏oFÍłËĘÝ_v ˝ąoUąűŁ„Ů'kK INź ´tPçH"""RJPĄlÜýY°$W<®f9Ź5řp80«ĚĹ/nN(sąuĎÝ_%Ô˛M)ˇ„&Ýźs÷´1rKćîďź!Ľ—ú~™Š]NzŹĆĹóˇ©ó1”˙AÍÇŔŤŔ©ylű?BÓár˙çŔgÜý2—-"""˛’T)+w˙ŔÝ#4uüpˇ&í5Â{€—ńX+Ü}"ˇééwÉ$C’Ź÷€żß†¸űWÝ=­gŰNÍÝgŢ?üúNp‚E„^fÇąűŮŃP,ĺîKÝýĚlđBMđ:„×&ĽăĽHĎ$ô>ý,đ€»—«6)žµçäg€őYuNö'ÔÖgbz‹p>>Ls÷éeŚa=Âç±áΆŃń{:ŽZ,¦ 9M¦čďBDDDlŃmˇőéŘâYŢ{Öe?–TISÍUM|EDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© JPEDDDDD¤.(A‘ş UDDDDDDę‚T© Ýj@µ™YOŔj‡HZÝ}Y­¨”Nť šY° °0.úw˝š%"""""R3{x43ąűô‡T6ť6A5łÍ€›€OÔ:‘2Ú0šľ`f¸ű[5ŤŞ :e‚jfßţ ôxxŚđ„aĐR»čDDDDDDŠÖMhş°điŕi3;ĐÝď«al%ëT Ş™ppt´č5ŕ«îţLí˘)«ÉŔD3űp °pŹ™ťěîçÖ2¸Rt¶^|żÍŞäô.ŕ“JNEDDDD¤łr÷Ł-F›€sĚl÷ÚFUĽN“ šYŕWŃěUŔžî>Żv‰Tž»żŚţ-şŔĚzÔ0¤˘ušř°6đ>pĽ»{Ťă© w_,6Ž«mDĹé Ş™m ÍţL5§"""""ŇŐ¸ű+Ŕď˘ŮSĚlp-ă)F§HPŻÍŔsŔe5ŽEDDDDD¤V~ĽCŃdźÇR°Î’ fĆ:˝ßÝ[k‰HŤ¸ű"ŕßŃě'Ú۶u¶őŮšF!"""""R{Ó˘.AmřqPͬ702šU‚*"E3łŐ˛f[Ý}Y e5Ů˝ç-S ©GfÖťđš îţq Ă‘ňhص3Ô nŕŔôÇ"" ĘĚš%YÓýîżľ™ýÁĚî5łWĄ±ň.sČ"ĺňO˛ÎU3ëUăxDD¤t™µŻ™ ­i$jřT`ÍčߏÜ}aM#é¤ĚląµÇşű E–u4°GÖ˘ŰÜ}b)ńŐš™ťüX˝Ö±H~ĚlOBWüíqBWýď“GÜýő ‡']™p#Đ7kq đőRîsĚě ›µ Ŕ ŔŔîľ<Ďcěšµč1w?łpE¤tŮŁšô®YEč ŞTŢn@Ϭů~%”µ%đ…¬ů˙•PVÍ™ŮŔYµŽC 6”Üó0_nf÷çşű}eŽ©`f¶!đ“¬E¸űŤµŠGĘâłŔ~ Ë÷®(±Üµ‹Řď3»śpÎ/č`Ű‘äţ]-)âx"ŇĹu†&ľ""5af}€ßd-j.v6FdM·T=@©vî5ł ŁwŤkiđý¬içÚ†#ephĘň UŤb•uźÓĚl»Ĺ "]jPEDžĚšĎçťöĎC˛ćŻt÷ď”5*©–÷€G–ŻlL¸IŹ;Ф¬dó IDATđ=zDă’.ÄĚúű¦¬ŢÉĚ6q÷—Ęt¸G€÷cËş¨mHn«€ €ŮNîŢĐ-_D¤ľ)A˘vw(p·‘±ůĘŽTßłîľwÚJ3 ś |›P‹šq¸™Ý\Í}ĄSřÝ›ř+ŔFYóď»—ĂĎÜýßI+˘–űçĂłV ţ„jęE¤‚jÝ4ID¤‘ŤÍżY“(¤âÜ}Ž»JroĚ'W;é´˛›÷:!a]šµě[QŹăĺî­î~ áU…˙ĆVďdfź®t "Ňu)A)Ţz±ůE5‰BŞĆÝŻnŤ-ţ´™•Ňqf¶ýŽç#î>¸3kŮŠëÜ«(îľ„4Ż­úrµb‘®GM|E¤®™Y_V=Lku÷Źbë7>Gč•uMŕBł¸űÜý폕=ĂŠřf֝ܮÚăďhőŤ•‘±¨Ła̬ˇ‰ńBO›}ąŔăŔTw÷Ľ~‘Ue®dj[’>»!„Ö#Ľců1pż»ß­oÖČÚeitÚٿ Ř…Đ3óú„›Ř×€'ÝýŮbëNčzŁh_'Ô@ßÓď·]Bî{‚ÍŔX óąeî Ü˝ĄĐYr‡.ZůůgťgkÄvë‘rf,v÷eĆ1ř"0 XĚ&ś+ŻRVJůkţ†7$śűÍ„a}^îu÷9–×îym3E8÷zţΞv÷ĹEţ*ĄŠw‚ô—čß«Że-?¸«*î>ŐĚžĆe-ţTµŽ/"]ŹT©w/Łźg˝ef›ç:*Jj âföWŕ'î>·ŁD7µŮc†= ěŰlOÚÖžeKKʾܔrÜ~„wĘľOűcľmfż.r÷Ąíl—m2°iôó‡DăF›ŮքއwĄíg7(ŃF˙ÉZw!pLTĆŃŔ „ü6Ěě.ŕÇńd3JLJčXhPĘľ÷G”#ů©¤´ÖÉúů÷ŔaYó? $µ…ú3đ­¬ůC€ż$ś«ŮľMiľ \–ĎÁÍl]ŕw„ä¨GĘ6˙Ž)¦ă3Ű8‡đ7śÚlŐĚNv÷ň,záÜϸ8:*kŕ `ł”}ç›Ů/€ßEďĄWEôwńͬE‹~ţ!Îśc_6łîţ^µâž'7A]'mC‘R©‰Ż43;xŠĐÔ-í:f„›űGĚ,Ţ·.ŮŔËŔ‰´źśBHć~ ľt!JPE¤ˇŮ€ż˛Ş©­3€{ŁăÍ`7n(Óx•ďdMńšĚwcë3ÓÇ żÇř(ćµc«VnÜŻţGňďó¨™mJĚě‹ŔDr{ ]B¨ů}hˇăď…‹ ˝{f,$Ô6Oˇíç±p·™őŚnöď&ÔÚf|Dęâi ŢětpS•“„| Ąm ¤ů™Ü}*ą5ĎŰ1~ä7^Yóq÷ěó(sn}Űo1Éç`fʧůę„÷ł‡Ö™ÜGhŃo®Ľp[Ô´ąCfv>đsÚžk˙&ţ–ân.ňoů÷„V Ë ř´jBřă"ŽS¬´ć˝WÇćÓĆJ­”řC±ů‰[‰”Ti$ý 5 Í„äćP ż»Źt÷Ď»űHBRt{lżť˝a–ÄÝďv÷A™‰p3ťí“Ů볦IŮEď^Kîű¬ËĂľîţIw?ĐÝ·żgp}Ô,0_˝‰˝ŚÓÍű¸űÖî>ŚĐĽwb;eěCfŕa`«(ŢťÜý“@BłßěfBbp*ˇ& B“ĹM ˙w;»űhB äٱămKn×z±e²wbóń&˝…֢Ʒ˙SćwoÉ:żŰîĘ”s03]GÇn#Ô-'ôPĽ¶»q÷]Ý}óhÝbű ~ŇQÁf¶đĂŘâW€OÜ}wwßËÝ×!$ĘOĶÝ+źă$ěstôós„ëAwßÖÝwq÷„Ή^Ťíw†™­Uŕ± ffďřfĽMěÚâîĎÓ˛mmfŁ+[–ř9?ßEDĘF Ş4’ľ„&xĎ۸ű•ńŽÜý=w߇¶5ß®Ny9‡Ü€ç_r÷‰ńÎ\Üýw?•PŁ–]C9ŠÂjxzjşŢ>çîgąűKŮďŮąű»îţp;edšôţř¬»OĎî¸ÉÝW¸űoď\f;8%úůÂďúRlßeî~ !qÎvőçG±ůĺ„fÓŮn ·vó€jÇ‘›üŰÝź/8Ęâ %tXµ»˙2ţ®Ł»/v÷ŇvxťCĚĚHaf«—Ć?gJĽ°čýĺ]Ą˛ťifć˙ë04ú÷O„‡HŹĆ;-s÷§”ÍĘZÜ8 €ăë[äÖČ_—Ň©VMjQŁÖń‰ă§Š”Ti4­Ŕ·Ý}fŰťNî{‚ă ¬q¬3@čě&ŰŹÜýŢöös÷kďĆe;şßéw¨Ŕ}˛ýři˝Ň^En Ëš„Zď‡Üýěz#ľÜf¨źĘ7±«3ű!ˇÇŮl÷Ç{|Žšă^•µ¨7á}Î|ÄkO۫ծ”㢦Ęí9ČN^‡š §9ÜÎu{ą{R[`ĺçxąµ›=€Ł:-î%ŕ¨ö:‹ŢůŚ˙Ťíš´m™uÔĽ7ă:r['hfńžÄË*ŞAľŚĐň"Ű•<®tmJPE¤Ń\îîńăŰp÷Ě{©=Mkí rß-|Đô6 Ľ3š1ĐQľžcUĎ ĹúqG˝›FĂÜ_ ßQáî>Źđ®j†šúÖŚ››Ů$BRwVĘ®—’űq‡Í|:Gú¸9ßXËäawďđ<‰†cą&¶¸˝Î’ľ›źŘ^ršuśÚ&Žß.đýäĹkMS\AnXPçO…2łÉí´iZÚőÍðYŮM×ö®P\}˘Ő^$ •í^wŹ·) 3#"Ť&ŢÜŻ=3bóëjkéÓ±ůóň—ŇÝß5ł+ÉmBűiňŻÍ¸ ÚËŽĚ먦7Ëë±ůyÔČeĚŠÍMÜŞĽF™Ů Ë×"ŚĎŮ+aŔŻÝýѤîţ˛™ÝKF`´™}2jNš&Ţ9ŇŐíŐúUH!˝'ýŤµaf˝ Mh3–çpś«3YUŰŘšĐÁVG˙—ĎAÜ}‰™˝ÍŞßŁŇ=€Ç›éĆ›ńĆ]MîC©C)ěšífďě¨0’˛ĎŰŃ+µH!” ŠHŁyˇ€mßÍ×ĂĐ;Ćć)p˙GČMPăĺµ§Ď.I!c]ΉͿ\Ŕľń˙·~ě[¬ţŔř¶o!ĽKg6îbV%¨nîŰKPëˇyo%ţƶ#w8™×Üý­|âî›Ůr;Ú‘üÔ |0ó«Óf3[=Ş-.«čťÜŻg-j!w8™$“˝g†ĄÚŐ̆ş{üP> m™đ<°Ô:ED¤bÔÄWDÉBwł€íăÍÓjÁŞ"Ă1^#Ż-ěH|<Âáě[ęŤe!IćĽö­«˙·ĺ„&·;şű©y$>w’›Ä`f}’6Lčé!w±¤h‹SH‚šď˙Uü<-ôĽOÚ'ßsżĐϰZçß×Č?÷ž¨oŞčťÜěî&ÚľÓ^nŻzçăîÓ+|,Ő ŠHC‰ŹůŘ‘RšłVB˙ŘüwOď±=ńu@žű-ň®±JO:Ű˙ěKŮ·ć$Äń1!öw€©Ŕdw˙0ßBÝ˝ĹĚţ ś-ęCč,éO ›?6_‹ÚS(ěď,ß˙«řy?ŹóQěąßá{®1Ő:˙âÍ{Ó:GŠ»šÜšö fÖQçcIî§íxł-„!ĽćZLLž/ńŐ‘‚(A‘|Ä{l]­„˛â˝N¶ŰáN'oţ8·2âă®ffÝÜ}EâÖ«,ÖMf»¦»{Écĺ¦ř3aŘĚwî÷%¨ ť#˝GŰŽ¦YĽ'ćbĆŃŚďS7˝;ĘĚF’ű>z+áo9ßsp«~˙‘„ćéĆéî®ábD¤î(A‘|ĚVĎš/ĺ]ÎřľńN::łŹbóë$nŐľucó瑜J ąű3»ťĐ¤`Ś™ŤŽuő-rü\•oçY bAl>~ç#ľOĽĚF2ܡ[š€+K,ďÁR©zUDňožYLb•żÉ,¤égŁ‹7 íefkXưŘ|ˇÍžĄ6.ŽÍÇ;CĘžw’›7˛řy?ŹóŃ)Î}3«Ä{Ł_«§ń‚EDJˇUDňď©słÄ­ňłUewZQMgĽ“§B:9‚¶7éĹt6#UćîŰůĐŃĐ+ŮNäŽŃű€»Ň©T#(¶ŁööiÔsWĘ?tŇę@Ąš¨‹T•TÉÇă±ůB†6YÉ̶˘í!ń˛;»řď;®Ŕýwę <©_—dýĽp@ôs)CË,ŹÍ7'nU{“É}—}¤™ Îwg3[ŤÜqTˇqĎýxçHçĆ-t:2V΄ʅ,"R=JPE$Çć?efĹ4Ń; 6˙rGĂ*tBńĎň¸hř™EÍă7ˇńň¤~ýČOó{ ť#Ín/ Ěx „µŠŚ­˘Ü}0%kQwŕŠ8„ÜW >¦•!´ŞŠţż÷Ž-ţł»Ď,t"ôć»(«śͬ”Ö-""uA ŞäăAŕŐ¬yÎ)¤3[8:¶¸”NAŐµŔ’¬ůáŔţyî{ ąc2Îî*S\RaŃđ4×g-Úř=ąť#]Y`çHo†ĘT|„wYlţ|Ţ›4łfŕ'±ĹWą{ĽwńFp ą=™O)v¬Ű(éź[Żťi8JPE¤CîŢ ü.¶ř@3;9źýÍlÂŤTöÍčb:_G0r÷5Ů.0łťŰŰĎ̦íMú…îoâ)ő-ŢYRvg9N’&oŃßfv-ę§Ě¬Üď7–˵ä­Ô¸ŐĚâăŻ5í˝Ř0kń2ࢊDXyńňşË»66˙Í|[dÔ+%¨"’݉´mNú 3{ĐĚľhf«Çw0łafö#ŕ9`tlőQîţ~…b­w?^ĎšÜkf‡Çk”Ěl-3; ř+ą5/Oż­x¤RVŃĐ2˙IY}ź»żš˛®=ٵhÍŔfv´™íjf[šŮ¦YSüđŞq÷Ĺ´}ßvWŕI3Ő”`ÁŔŔ×cűś\äçTSf¶5ą×ÁVŕ†‹˝ČľŽľXb™""5ĄUDň5§;ܦľż řĐĚ^3ł)fö¬™Í!ô˛ů[ >”ĘîŢ›÷+›z~Üq{:ŃůĐĚž3ł[Íěeŕ=ŕ”XoßPíiÊעfŇ9R¶_;ĆîHŕŔż‡^ČšökłwąűŔŻc‹7žćGĽî&$]ÓbŰŢDčT¨ĹkOt÷·J)0şÜÔÁqDDŠTÉ›»żIxo.é˝Ç%G†’IznˇćôŘŠŮ Üý1` ~Úl ěl”°ët`\#Ö ÉJ7Ňv Ďw€;Š),j‰0˛ÉÝO$´"żCÚ›đŔkw`Í„]˙ŕî^ŮËĎĚzĹÇ›ç+ŢLxŹčµ ‘†¤UD âîóÜ}ŕóŔý´˝ÉL28éî¬d|ŤÄݧjŹÎ Ô”¶g6p°­»Ď®tlR9îţ1pklńĄÔ»ű­„?nž$Śą[— ąűąŔÖ„‹Űű˝[ Í|?ĺîGEďÜ6˘/šňg,n)SŮŹ’;&lwŕŕ2•-"RuVÍ‘¶hřIÄ{ţt&zźY‡]¦ŮîŔÝŔ|wOíhAD*ĂĚúšámI¨őX“PS:ŹP+ôŕąF¬ő¨&3k"|ŽŰšD÷% Ą1xÄÝź©axRffö°i4ëŔ†î>ن!ŐŚ™ő%<đÚpî7ďŢÓţ§»ĎmgwIu@7/šÝÜÝ_(©ĽE#¶…Ö§c‹gyďY”Rnőô&"%q÷…Ŕ˝Ń$EŠj†‹&éÄĚlV%§÷tŐäŔÝ?˘|µ‰""ŇŕÔÄWDD¤şâď`_X“(DDDęT‘*1łÍ=ł=Kr§c"""]’T‘*0łŢ„ž[łż{Ą÷łEDDVŃ;¨"""`f_Ö#|׎gmňaȉ(A©ŚăϤ¬[|ÍÝWT/‘ú§&ľ"""Ő58Ŕݧ×:‘zŁT‘ĘxčýĽAčé˛hx&‰Q‚*""Rî~d­ci4jâ+""""""uA ŞÔ%¨""""""R” ŠH]P‚*""""""uA ŞÔ%¨""""""R” ŠH]P‚*""""""uˇ[­čěĚĚjîˇşŽÔ]GD¤TŤz©%¨`f«ý’Vu0/"ůqŕ] µťőm~Žß Őó„™ z&­ę`^Dňł—˛.~mHĽŽÔů5¤X›äk„Ąü,"…™,IY×đבZQ‚Zf¶°+0l4×4(‘ÎođL4MîŢĎZꔤ: _µţr0ł&`7`V]G†Ô2&‘.báú1řp/Đ’µ>~Éľ–ÔŐMfôPkOÂőc40 č]ËDş€ŕÂ5äiŕ~ŕů¬őIIjâu¤Ö×z˘µfÖ8ř Y ©™Ń·oßšĹ%Ňٵ´´°páÂŢŔ¸h‚PŁz40‰ä„4éçš9Ůŕ*ŕÓŮË{ôčAŻ^˝ŞŽH—±dÉ–-[6Ř#šľ̤ăkG›^µşÁ4ł}€Ku˛—÷éÓ‡ćf=/©”Ź>ú¨ŮÝ·¶ľIHXü‚ĐJ##éşQ7÷"őF j‘Ělp5đ 3cŻ˝öbܸqŚ3†ŃŁGÓŻ_R _)—Ůłg3uęT¦L™Â?ţńžzꩵ€ Ť>$÷âßJňÍeΗC5żĚěűŔo> ŕë_˙:cĆŚaĚ1lµŐVtë¦K´HĄ¬X±‚çž{Ž)S¦0eĘnĽńF>řŕť€ÉŔ)Ŕ´ ÉĽbY^őL3ë\ đÉO~’Ýwß}ĺ˝Č°aĂŞ†H—5ţü•÷"Ź>ú(wÜqGł»˙řđ}ŕżŃ¦ńëEÚ=IMvŐ «ćďo‹†źś“łĐ™č}f^t™f»wóÝ˝ić}Ěq„*ü#FŚŕňË/g—]v©ĆˇE$Akk+çź>'ź|2ü1Ŕ«Ŕ瀅„ ~ ą_ ŮYë€ęÜ\šŮyŔń{ď˝7—\r  ŞôaE$ĹŰożÍGÁí·ßžYt pé׎´M ň×3ëL6YmµŐ8űěł9öŘcijŇ "µňŔpŘa‡1cĆ €ĺŔ>Ŕ“$_;˛ďM˛Ż%@é×čVć=űÍÝý…’Ę[4b[h}:¶x–÷žµA)ĺ&ŃU¬@QHW=>ř`¦M›¦äT¤Ćššš8ţřăyć™gŘ|óÍ6Îz«ESO ĐťĐz¤9šŚp-\ů.YĄ{»4łńŔqÝşuăšk®á¶ŰnSr*Rc â¶Űnăšk®É´^8Ř…Uבž´˝Ž4eMFŻ#ŔŻM6ß|sžyćŽ?ţx%§"5¶Ë.»0mÚ4>ř`׉‹€„ëHöµ¤ą÷#ńkI—îy[W˛Âťl´Ĺ[pŮe—ѧOźZÇ#"‘M7Ý”kŻ˝6ssy0ˇó˛Ő …d1ÄŐě/ r_ fÖ¸°N8:¨‡‘"tĐAśp nGč ·7áZ’yŕŐöU ˘×‘χwëÖŤkŻ˝–M7Ý´‡‘"ôéÓ‡Ë.»Ś-¶Ř`ŕTV݇d?8Oş±¬©Ë&©JP `f;G755qĹWĐłgŇ"RKŁFŤĘľąü%0čM™ĚL’ÚŤÜ›ËjÔ€ü±Ĺ[pÚi§U x)Ői§ť–ąą\8U×ě›ĚL’šąŽ$¶Č(73ëIx?ÖN8áFŤU©C‰H‘zöěÉW\‘iŐpˇCÇ5Xő°+űˇyZ’ tÍ$U jaľŘwľóĆŽ[ëXD$Ĺi§ťĆСCcľ„/†ěĚřCb HěpŃEé!—HťęŮł']tQfv7ÂŘćk°ę:’ąÁĚ~ŘU­›Ë€áC‡ŐC.‘:6věXľóťď@¸|‰ÜëHć^$óę@ć^$s?’yŘt˝$U jaĆě¶ŰnµŽCDÚŃłgOĆŹź™Ý–đĄORă jö—BEn.Íl0¤WŻ^ěĽóÎĺ*VD*`çťwÎ ő´0čO¸Žd®!Ů-2’j@*uʵŔřńăőK¤Îeĺ [îE2IjÚu$Ó?F›ű‘®D jž˘›ÔQ€jOE@Ößéć„Ëě$5ţĄĐ¶_ •¸>Ž=z´†©sÝşucôčŃ™ŮO°ęć2;IÍ®EÍÜ\¶ye Ěµc@÷""Ť ëďt°&ą÷#ńćńëTéĐĆ@ßÁłţúë×:éŔöŰoźůqCÚ&¨ń›Ëî´ssYFcb±‰HËú[Í<čęKŰ]iבJÝ\~2›Ô©ő×_źÁC¸NlDî˝Č„kČę´}] Íu¤+5óŐ#üü 4čµHČú[íCř2ČľyĚ\ä;Ű(ë Ůc±‰HËú[ČŞëHöë°ęzŃ’5e®%™›Ë˛Ś‰Ý ®‹MDęذaĂ3g„\b>ą˛22׌¤ëGŮ®!ŤB jţşĚS ‘NĆIjv/›°j챩9ZŢÄŞÁłK"ÜXę:"Ňşłę:’IN3‰ićÚ±ś¶ Şg¶-ă.iL˝µ¦ŮÉiö˝ČňčßĚ|Et5%¨yčJUę"ťšâe'§™›ĘĺŃ´,ëç„/Ž.ůĄ "‰ş®#Ů5§Ů7•Ůב.˙ţ$ZŤĐś7;9ÍľY–ősüay—zĐĄUDş‚Ő˘35˘Ů_K ď~,Łťˇ"ĘD7«"Ť©™Pű‘”śf®#KŁź—±ę:˘]"’ŃUבLíhü˛”Ü{‘Ěu¤KQ‚*"ťťľ`USšŐ_“űěĂi§ťĆ!Cň.˙‡?ü!'N,(¦ţýűłńĆłÉ&›°É&›°Ç{°ŐV[u¸ß›oľÉ†nŘfůi§ťĆĎ~öł‚bH˛Ë.»đřăŹç,ŰrË-™2eJÉeKjBš}S™ôsÝÝXvu›oľ93fĚ([y;ďĽ3˙ú׿Úݦµµ•믿žßüć7<˙üó©7WÍÍÍ >śŁŽ:ŠüŕôěŮ3Żnąĺ:č •óGy$çťw^ţż„TRö}@Ň5$)IŐk]܇~ȸqăRŻU `íµ×ćŤ7Ţ`ѢE9ëÜťkŻ˝–Űożť§žzŠÍ6۬!—ÝĄ—^Ú&9hję’]ádţ†“®I‰iü~¤KP‚*7mÚ4N=őT&Mš”×ösçÎeâĉüĺ/ácŽáÄOdÍ5×ěpż+VüřťwŢáťwŢá‘Gŕä“Oć#ŽŕĚ3ĎěđIÇşîşëJNPß|óMzč!⯔ű wżĐ·—¤Jť[ştiY˙.–-[Öîú[o˝•ÓN;ŤéÓ§wXVKK Ż˝öÇ<ż˙ýď9ýôÓ9äChnnîpżěßiĹŠů/Ő’T;šöľiC^KĆŹĎî»ď”č-ě IDAT^RÇ/S4ŤďCÉINÍŚ˝÷Ţ›cŹ=–m¶Ů&ç=Ě÷Ţ{Ź_|‘ .¸€›oľyĺ}Ŕ˘E‹řú׿ΓO>Éj«­ÖćőîöŰoĎ™?÷ÜsůĆ7ľÁ°aĂjQÍœώZ_t9JPĄ˘¦M›Ć;ěŔ’%KÚ¬33 DďŢ˝™={v››Ă%K–đ«_ýŠ[ną…©S§˛ĆkT<Ţ––.şč"®żţzîşë.¶ß~ű‚öź>}:Ó§OgË-·,:†ě/%)›řE>^Ă‘”*Y••.ĽđBŽ9ćÄuÝşucذa,]ş”9sć´iŢřúëŻsŘa‡ńđĂsŐUWU!Z©¤Ä4­ĺE|»†1věXN:é¤Z‡Ń)śţů9çűôéĂý÷ßĎvŰm—¸ýŔ8p ăĆŤcÚ´iě˝÷Ţ+“ŰiÓ¦qÜqÇqÉ%—T%örúß˙ţ·ňçm¶Ů†O<±†ŃÔ•¤ë‡–ŁU*hÁ‚ě·ß~9Ééj«­Ćˇ‡Ę÷ľ÷=6Ůdzőę„f,sćĚaęÔ©śsÎ9<öŘc+÷yĺ•W8üđĂąöÚk :ţÁÜn˘¸bĹ fĚÁK/˝ÄäÉ“sj-Ţ˙}&LŔÓO?MŹ= :îŤ7ŢČ™gžYĐ>Ůţö·ż˝Ż´+ß ~—˙bhT§ťvÚĘkJ1ŇžćOž<™˙řÇ9ˆ ÂńÇĎľűî˰aĂVÖŚ.[¶ŚŮłgóŻý‹_ţň—ĽńĆ+÷ąúę«Ůu×]9řŕ‹ŽQj®ëtqW^yeÎü5×\“šśĆm˝őÖüíocܸq+ďO&NśČąçžŰp˝ßΛ7oĺĎźýěgkIÝČ÷úĐeďG” JĹ~řáĽôŇK+ç7Ţxczč!Üf[3cČ! 2„=÷Ü“»îş‹Ż}ík+“Űë®»Ž]wÝ• &ä}ü}öه}÷Ý7ŻmgĚÁO~ňnąĺ–•Ëžţy~ůË_rúé§ç}L€n¸ˇčőÍ7ßĚIÎĄbŇ.ř]ň‹ ł8öŘcóz }ôűí·_N Ź<+ŻĽ2ńáUŹ=ŘhŁŤŘhŁŤ8ôĐC9űěł9묳V®?â#Ř~űíŮd“MʧT]Z+Ś.{C)ą/^śó:Ŕf›mĆ^{íUPcĆŚářăŹçśsÎÂĂügžy†ńăÇ—5Öję˘ďť&iďÓ.ŃY"±xńbnĽńĆ•ó}űöĺÎ;ďLLN“|éK_âŹücβsĎ=·¬1f1b7ß|3_ýęWŰ3źwŔ˛kj_~ůež~úé˘âČnŢ»ÖZk±îşëUŽ”Ç>ȬYłVÎŹ;–+®¸"Ż–={öäĚ3Ďd˙ý÷_ąláÂ…\|ńʼnUDęÇÓO?MKKËĘůťvÚ©¨rvŢyçśů©S§–—H#P ŞTDüÂĽ×^{±é¦›TĆ„ ¸îşëVöüöĘ+ݰpáŠCs饗ňŻý‹Ź>úť°ĽňĘ+öś7věX.\¸ňFöĆodÔ¨Q˙¦›nZůóľűîËÝwß]p"R>“'OΙ?ćcňî‘7ă˛Ë.ăÎ;ď\Ů"D7ŇŐ<÷Üs<÷Üs¬»îşě˛Ë.@¨Ľá†řă˙Č‹/ľH÷îÝ™¤SĘ”Ä*Hzz:?‹O_+ .ü0%%Ý»wÇĽyó 5rrrđÇŔĹĹĎź?$?$$NNNrŤSiîÜą>}ú 88Xi=é}ć‘‘‘EÎi¬ŁŁ]]]čęę–›U˝ěělxzz2ĆiIÁqćĎźŹîÝ»Ë5NĄąrĺ şvíĘ¬Ě e„ …ćż&ĘZA%Jé™ĂË—/ă‡~PYNŹ=(ŔZZĄ˙••—([m۶EŁFŤđôéSů«¨‚Ż+˝·oßľ…ćK$˘ô155Ebb"_ľté<==U–ł|ůr,Y˛„/ŐĐ%/ż˙ţAAA|Y[[&&&011‘ůßHKKťťcéëëăŰożEëÖ­annŽ»wďâúőë8uęźć)66NNNŠŠBíÚµę2ţ|Lź>ť9fooŹ: U«VČĚĚÄŤ7pćĚÄÇÇČ.4irrr¦ä±´´DłfÍIî)S¦`űöí0a|}}+ô80bÄĆĂD__&&&|LŽü‘ž ĆçĎźíÚµc&ŕĺącűűűcÓ¦M̱Nť:ÁÉÉ ¶¶¶HIIADDNž<‰×Ż_Čźđőő…X,†ŻŻŻ {ظq#VŻ^Í—utt`bb‚ZµjQ0'5C*Q*Hφ„„ŔŰŰ]»vUIŽH$*ó¤Ô·oßfĘŞä4őööć]{÷íۇĄK— rç‘çŢK„ú±´´dögMś8ÎÎÎ*0ÓÔÔ¤I'‚@ľ‡‘źź8ŽCŁFŤ„A)\üí·ßă´]»vصk7nĚëßż?ŕÂ… 4hoH&%%!00۶m“+űĺË—X°`_ÖŐŐĹâĹ‹1nÜ8ć·Űßß™™™ř駟Ÿ3gĽ˝˝Ń¨Q#ŮšššXĽx1zőęĹż}ű6† †©S§bÔ¨Qđđđ@۶m+Ôř°fÍţYÉĂĂÓ§O‡ŁŁ#SgĆŚLýő›oľQş*::›7oćˆ††Xż~=ăĄVŔëׯ1bÄ>×,Çq@Ďž=ahh¨ô"##ń×_Z´h3fŔËË‹ Ór¨D©ŕęę ===~ö,//®®®puuĹĉáîî^.÷_Ý˝{W&€‰*ŞŹŹ?đ&&&ââĹ‹‚ö¬Iş÷šTčňń%ѧOěŮł‡/?ţćććđóóĂ„ ЬY35jG%ϡC‡ř˝†Ş˛lŮ24lŘPiť·[###„……ˇ~ýú ë&&&bĹŠ|ąuëÖ¸té’BoŞ:ŕćÍ›hÖ¬ż˛¶cÇŚ3FĆ€€ŮłgăăÇŹ|ůŻżţ‚‡‡‡\ŮzzzŘĽy3LLLř´/ŮŮŮ8q">,·Ť‡‡ćÍ›‡™3gň+»$''cîÜą;w. ŃąsgtëÖ ®®®°´´TŘ'ĺă´wďŢ ď˝¨ňĎCZZZ8ţ?~ÄŔ™|‡Ě,ma´jŐŠY=–LµŁ Éč˝ýúő«P3©ń%ăíí-ó`›ťťŤÍ›7ŁE‹čŃŁvďŢŤ””5iH%ËŁGŹpäČ‘"˝RSS]C$a۶mJŤS9s&żÍGCC6l(t«Ź±±1ł×“ă8ěرC¦ŢđÇđe///…Ć©´NlŕčŃŁHKKSX?((˙ý·RĂ=55‡Âرcaee… đ+’Ę 4Ŕ–-[JTfhh(Nź>Í—úé'…Ć©$Ë–-cr`ďÜąSĐö,mmměÝ»—ŚÓr¨D©ńË/ż`Ŕ€rĎÝż&L@Ó¦MQŻ^= 2»ví⣿•%999Ř˝{7š4i„h€+V¨l,Jşçţő×_…ţ¸$$$ŕęŐ«rŰ!???ôéÓGĺWAtQEěÚµK®'Çq8yň$ÚµkŁeË–>AAAŘ»w/Ž=ZnĆ!źˇŞH~&¶¶¶…ň’HçžżtéRˇ[´Š’Żž(Č@%Jť &`Ě1Řż?¶nÝŠ‹/2n´ŇÜľ}·oßƲeËĐŞU+Ś7C‡Uyăzttt‘uvrr† ŠÔ¶E‹Läľ˝{÷*5PĄÝ{i>A”?ôőő±uëVüöŰořăŹ?°gĎ™tZ’äää ,, aaa9s&zőę…‰'ŇQî0`-ZTŞ×(,·8Ŕ+Tž°¶±±á÷Gr‡””…ŞŞ˛[´hÁ”_˝zĄR{MMM8::ÂŃŃAAAČÎÎĆĄK—pöěYś8qBîóKLL Úµk‡«WŻÂÜÜ\Ąë•4•+WfV¨K ÉĎÄŮŮYĄ¶666LYGž*“DŮB*Q&čęębĐ A4h>~ü‹/âÜąs8{ö,"##e‚Ť#FŕرcŘąs'ôôôJUĎęŐ«cáÂ…5jT±‚8y{{cöěŮ€`Íš5r#&$$0ůRÉ˝— ŠŽ‹‹K‘RQµlŮRpÝÚµkcÚ´i6m’““qţüyś={gϞųgĎä¶ÉËËĂ‘#GpôčQ,Z´Hîţ|‚řšb<|ř)«š@Ú3JÚEVŇ:qâD±2H§§S]]]tíÚ]»vĹ‚ p˙ţ}ěÚµ +V¬`ôNNNƤI“pŕŔb]ݏX[[—x ËwďŢáíŰ·|yÆ L4ßÂŢs*Ä%ZČD ˇČ@%Ęś*UŞ {÷îčŢ˝;ŕýű÷ ĂŮłgqěŘ1Ţ%G’ÇŁcÇŽ¸té’ŕĽa­Zµ*4„H$BÍš5ѬY34kÖ ...022Rý¦¤đńńá ÔwďŢ!44=zô©·˙~~P555Eűöí‹}m‚řZ9zôh‰ď‰RF­Zµđý÷ßăűďż<{ö gĎžEhh(ţů礧§3őĹb1¦L™‚ääd&'*A|mqS•^AUä+I#2))‰ů˙ĚËË+V0˘’ŢÚ´iSĚ›7ŁGŹĆČ‘#qňäIţÜÁqńâEµ>/”†›±ôçť››‹ÜÜÜ"Ë+ě3144TÉ…([Č@%ÔNőęŐáéé OOO¬Zµ —/_Ć–-[°eËfeőćÍ›X¶l™Â¤ŘŇĚ1}űö--µ•ҤIŘÚÚ"&&@ľ›Ż"µĘżE›† bÄ1b˛łłqěŘ1¬^˝áááL˝ŕŕ` 0 TöpDE@ČoťôŠXq]JyjůĆŠ¤űŻŞČ\Kr+SĄJ•Šôű^Ż^=8píÚµĂÝ»wůăgĎžU«ZĎ*Ňź·±±q±ĽćŞT©˘ô|yLuHü?d ĺ ‘H¸¸¸`Ě1~ü¸Ôä×€”¦AĚozddd±äIß»C±äIňôéÓ“U\Jó3!*d %NÆ ™ryž9,m$Ýv˙ţűo|üřą÷DE@r,{óć Ţż_,yŇc™˘ÜĐAćććLTî?ţřCpŰĎź?ŁiÓ¦044„ˇˇ!† "SGŇЉ‰QÉ\˝z5/»zőę2«şşşL*đđpś9sF°|i²Ź«‚çŤÂęgˇ¤‘üLNž<©RúžŔŔ@ţ3155-vdeB˝J”8Ň®-Ĺť9”6pKrć°´‘4<333qüřqlp¤úő뫜Ť ŇGz˛-**ŞXň$Ç2MMMŘŮŮKA|ÉhkkcŕŔ|ůĚ™3ĚÄ®2věŘ -- iiičŐ«—LťÁCSS“/Ď›7OĐ–¤śś,Z´—maa!3VŔřńă™r@@>|ř HI=z„={öđe‘H$7G¨tŕ"!Ţf«V­ÂëׯUÖ©´:t(˙ţóçĎ‚óńľyókÖ¬á?ggçROKH”.d %ŽĄĄ%3P®[·‰‰‰E–'ł"íŐlذ!ÚµkÇ— Ü|% Ôţýű“{/A”C¤s5Nź>˝Č{ę߼yĂ<0¶lŮúúúĹŇŹ ľt~ýőW&?©»»{ˇFęť;w0eĘľl`` ×@mŢĽ9~řáľ|čĐ!Ś9Ri´_Žă0jÔ(Ľxń‚?ćëë+·®żż?LLLřň˝{÷`cc#łŞŚwďŢÁĂĂńŢčßżżÜtZÖÖÖLyëÖ­JeÇÇÇcńâĹ‚u) ÜÜÜ|·+V¬ŕSö)"''ľľľĚŠ©˘Ď„¨8J”8&&&L€ ĚĚL)ÇŘńăÇ÷KKKfŔŻH®˘?~wîÜ!÷^‚¨ôëצ¦¦|ůĘ•+Ř´iS‘dÍť;—1n+ŇDA¨ 333Ś7Ž/§¦¦˘[·n8|ř0˛łł™şÇaßľ}čÖ­ă>?qâDĆČ•dÎś9¨\ą2_ źźźÜ=ńńń0`¶mŰĆ«WŻžLśŚŞT©‚ß˙ť™€ŽŹŹG—.]€ .ŕĺË—2“^ÇááÇ2e ¬¬¬Ď‹fÍš!$$DîőÚ¶mË”CBB°aĂą“jáááh۶-Ţ˝{Wh:–˛fѢELźÍ™3'NDJJŠLÝ{÷îÁĂĂqź¶µµ•;!AT,Č@%J…   f€ů믿о}{•öŁĆÄÄŕűďżgf3ýýýKTϲŔŰŰ›ď‹ěělĆ…ĄAĘe™ ľ&tuu™•  ň÷÷WiÓÚµk±rĺJľ¬ŁŁ#wOA˛L›6ŤŮ:”žžOOOT«V ...7nú÷ď+++řřř ))‰Żëĺĺ…Yłf)”]Ż^=™ó{öě™™4h€bÔ¨QčÜą3,--™`‡zzzřűďż•¦˝4hÖ®]Ëă8+V¬@ÇŽQ·n]čëëĂÖÖööö¨_ż>ttt`mmŤß˙ť‰ąQµjU:tHˇçEÝşuáęęĘ=z4„L™2;v„««+^ż~ ---Ćŕ.ŘŮŮɤäY¶ljŐŞ+++ 6 C‡…‹‹ lllĘ׫U«Ž=ʤô#*&”•(š7oŽü+V¬ŕŹ]˝z­[·ĆěŮłńÍ7ß qăĆ022bÚĺĺĺáĆŤX·nöíŰÇĚöëד&M*ł{() ö^ľ|ÁźëßżżşÔ"BţţţŘľ};˘ŁŁůc7nÄŮłg1oŢ<4oŢ2«YYY8věÖ®]+ăŇ·zőj&·2Ž9Rähż666X˛dI‘ÚDyˇzőꊊ‚żż?ţüóOţxNN._ľĚ˙¶JÓąsglßľ˝Đ-4°¶¶ĆđáĂ™•×řřxěŢ˝[něÜą­[·.T˙ŃŁGŁV­Z@||ĽĚůŹ?âöíŰJe888ŕ÷߇•••Ňz;vě@«V­śśĚ»~ýşÜô|•*U¦M›dŚÚňŔš5kвeK ++‹?ţčŃ#… 5kÖÄ‘#G`ffVVjĄ¨D©±lŮ2dffbóćÍü±ĚĚLfEÂĐĐČÍÍERR^ż~-w˙GÓ¦M ÝOQžńńń‘ű#Jî˝Qľ©RĄ BCCŃĄKÄÄÄđÇźüýý1ţüŇV— T˘WŻ^ĄľgoČ!%âÖ>|řp :>DTT"##ńôéS››ĂÚÚMš4łł3“žF(őë×Çůóçńţý{^vTT*UŞkkkX[[ĂŢŢőęŐ+’îUŞTÁŚ30cĆ <~ügÎśABBRRRđćÍÂÜÜćććhذ!,,,Št­ĆŤcßľ}‰‰ÁĺË—‹çĎźŁZµj¨[·.<<<(Ŕúúú‚7mßľ]e] ř矊Ԯyó掎FJJ "##‰[·nˇZµjügâŕŕ€š5k ’7iҤ é‰÷5B*QŞD"Lž<~~~;w.<ČěQ„–– €_~ůÍš5t-KKKfPč€UtttkIGĎ“¦Nť:1b3kęééYčuśśśřŔňÂŘÄ׌ăÎĄ­­]j×222–-[0zôh,X°ˇˇˇ‚ň Ö¨QăÇŹÇŹ?ţ5jZßÄÄ„[ŠCË–-KDA”'444ФI4iŇ„÷b(IŞWŻŽ.]ş^µ, Ť7fr~–¶¶¶°µµ-Ők”&&&pww‡»»»şU!Ę2P‰2ˇvíÚXłf VŻ^Ť›7oâÂ… HJJBJJ ŢżŹÚµkó3‡ććć°˛˛’ŮźZ(Ą;`166V)T<lذAĺëěŰ·Oĺ6ńµ ™°¬pppŔ‘#GťťŤsçÎńłű)))ČÎΆ™Îżé¬ IDAT™3–Y[[3QB ŁS§N*Ź-Ań%A*Q¦D"´mŰV&:ADEBWW={öDĎž=Ő­ AA|QPš‚ ‚ ‚ ˘\@*AAAQ. • ‚ ‚ ‚(JAAA” Č@%‚ ‚ ‚ Ęd AAAĺ2P ‚ ‚ ‚ r¨AAADą€ T‚ ‚ ‚ ˘\@*AAAQ. • ‚ ‚ ‚(JAAA” Č@%‚ ‚ ‚ Ęd AAAĺ2P ‚ ‚ ‚ r¨AAADą€ T‚ ‚ ‚ ˘\ Ąn‚ ‚ ŠĎű÷ď±aĂľlbb‚aÆ©QŁ/‡„„„……áÁřüů36l1cƨ[-‚(Č@%‚ ‚ ŠÍ›7o0uęTľlccCj 0wî\,X°ŮŮŮü1ccc2P‰/2Pż >|wďŢńĺ¦M›˘ZµjjÔčË!##±±±HHH€‘‘lll`hh¨nµ˘Äąsç222ř˛­­-ŞT©˘FŤľŇŇŇđŕÁĽző &&&hٲ%ôôôÔ­Aĺ­[·bćĚ™ęV Ę2Pż ~ţůg9r„/źÄÝ»wńâĹ T­ZÖÖÖ°¶¶FőęŐËTŹ—/_"""qqq077‡……,--ˇ­­]"ňďÝ»‡¤¦¦˘S§N°µµ-ą|üř>Dll,’’’`jjŠúőëŁ~ýú¨WŻ^±ĺ§¤¤ŕĆŤŹŹG«V­ĐŞU+T®\ąX29ŽĂăÇŹů~±°°€……5j‘HTlť‰ň¨AAD™2lŘ0\ľ|@ľ ˙O?ý Ĺś9sd¶Ů€††üüü0wî\™™Éśź1cöďßHJJâŹ'''ŁI“&|YňzňŽŽĆĚ™3qăĆ FN&&&?~<ĆŽ‹5j(˝Ď/^ŔŐŐ•/ź?¦¦¦ČČČŔčŃŁ±{÷n>ş÷ś9s ˇˇ///ě :”OűUŁF ľ˙¤ÉÉÉÁâĹ‹±qăFĽxń‚‰.I«V­đăŹ?Â××:::JďC’¤¤$Lž</^D\\sNKK -Z´@ÇŽ¤R´á#GŽ`ĹŠŚŚDZZšĚykkkLš4 VI_˘âAKB„\rrrđüůsÜľ}™™™jÓC,ăÁHHH€X,.qůéé鉉ÁłgĎJ\vŮŮٸ{÷.ž•¨lŽădňß–ź>}Âť;w’’R˘r‰Ż‹ěěl?ţĚ\űóçĎŕ8~~~صk—Ě”ťťÍ×ŤŹŹgÎIöŮŁGŹä^ďâĹ‹hÝş5fĚ„„Ąc^tt4† †¶mŰ"==]é}půňe´iÓ»ví’1NüľŽŽŽĆŠ+`mmŤż˙ţ»P™ąąą2e úôéóçĎË5Nü-ŁFŤBÓ¦M™íÄ—­ ~…Ü»w+W®hkkcŐŞUüąbíÚµ8wî?¨‰D"Ô­[ÝşuĂěŮłĺÎZ&''cÖ¬Y 3°„„„đŃpĄŻ'Ź3gÎŕźţADD˘˘˘xYGG–––:t(FŽ BďuăĆŤ|îłÎť;ĂÇÇđčŃ#Lš4 GŹŕÇĆÇ€1ZďŢ˝‹ŃŁGóĺ!C†ŔŃŃQî5?|ř€%K– ""±±±‹‹ăŤk‘H„š5kÂĆĆcĆŚAź>} ©©Yč}HrëÖ-üů矸~ý:"""ř‡ĘFŤˇ]»v°··Ç€`jj*X&Çqصk.\¸€›7oâöíŰüC°lllđż˙ýŢŢŢ6\?Q˛\ąr۶mcŢĽyňŤťÝ»wcíÚµ¸ző*__CCfffřöŰo1cĆ ąłę>Dpp0€|·:I‚±gĎ™ë)âСC8{ö,"""pëÖ-Ţ@®RĄ š6mŠQŁFađŕÁĐŐŐ-ô^—,Y‚'Ožúôéwww@TT&LŔŹoVVVŤŤĹ¬YłřÔ’“G—/_fĆ‘ź~úIaŕ§×Ż_cѢE¸uëbcc™U ÔŞU mÚ´Á¸qăŕć榲ŰŰĺË—qŕŔܸq‘‘‘ČĚĚ„H$‚µµ5ěííaoo???•Ü)sssńÇŕĘ•+Ŕýű÷ů /†††hÓ¦ ~úé'|űí·ä¦GȰbĹ ńĺzőęÁŃŃ‘źčHHHŕĎ}úô  @TTT‰ąüćääŔßß[·n•9gddccc#ĎĘĘŠă8Žł˛˛týS§NÉ˝^HHWŁF ÁăHÓ¦Mą¸¸¸BE‹qššš‚úGŢç$Ź/^p...‚ômҤ )X_u˛lٲ˝źř Ŕ[¬°Ŕ ă Đ€€fĚ0 ‹üŤG4¤ŕ^˝zĄŽ.QĘÇ™ĎÚĆĆFa]WWWľ^·nÝ8mmm×®];îáÇL]±XĚmÚ´‰300`ä/]ş”©÷ůóg.++‹ËĘĘâ†Ę׫S§<++‹űüůłŚ>ÁÁÁŚlmmmnÁ‚\||<_'==ť;}ú4׼ys¦®––wçÎą÷ůôéS¦î˘E‹ř÷şşşÜČ‘#ą•+Wr{÷îĺž\__ÝşuCDD† ĆĎÍÍĹřńăÝëÔ©SÎÎÎxţü96nÜńăÇĂŰŰ›T §ô>Kmmm…çîÜąččhľÜşukś:u ť:u’ŃÁÔÔÓ§Odž ă ő bVŹçÍ›‡őëףuëÖ|_‹D"¸¸¸ŕÚµkĚĘfbb"¶lŮ"#3**Š÷Śň#ťßľ}~~~022âŹ×¬YÄíŰ·ńÍ7ßđÇ_˝z…ąsç*Ô™¨¸J 00w­đőőExx8ŇŇŇ>`۶m¨U«_?77—qSň]qNś8'NČ<Ěňç \j%ÉËËC·nÝÍţŐ«WÇÂ… qöěY$''ăć͛ذaŚ+Ç‚ đűďż şO±XŚ~ř·nÝT®\nnnřá‡ř` ‹/ću• ¨`ggÇ?qâ„LŞ+W®`Ýşu̱=zŕرcŤŤEjj*âââpńâELš4‰qIŠ‹‹Ă´iÓ”ę>eĘć‡DGG&LŔÁńňĺK<|ř„ÓnĆŚ “+óŐ«WčÜą3ă:cee…5kÖŕĘ•+xýú5ţý÷_ŁA|ťśśřúúâÜąsJu&ľ.FŤ…{÷îČź¬ąrĺ ŇŇŇđęŐ+Ľ˙«V­BµjŐřú™™™řńǶ¶¶ü˙آE‹s’˙›®Ĺ’dff˘S§N¸sç¬Nť:Fxx8RRRpőęU¬^˝Í›7çëĹb`×®]‚î3''^^^xţü9 jŐŞčŮł'żő6oŢĚë*éĘÜ˝{wf±łłcd:t‡ćËčßż?Nź>ŤÇŹ#-- Oź>Ĺůóç1fĚčééńucbb°xńbĄş6 ŕËU«VĹÔ©SqěŘ1$%%áŢ˝{ŘłgÓ?ÇÁßß÷ďß—+óŢ˝{pwwgöôµiÓ7nÄŤ7’’‚łgĎbáÂ…011á뤧§ĂĂĂůĽŻ›ŞU«bÝşuJß 6Ś™<ʉ‰)‘k/Z´Ů+˝jŐ*´iÓFa}]]]¬_żÍš5㏝?^Đď˘X,†±±1öîÝË<[é=™żüň PIľľľĚ6IW’k×®1cÓŔ•.hiia÷îÝĚ$Á‰'dę¬ôAGG;wî”»8R@­Zµ°{÷nčëëóÇ–/_NűÜżDJcYVńŇ0ąř–&Eqń-xijjrË—/W(űÉ“'\•*Uřú"‘KMM•[WÚÝw÷îÝJőŢ´iSżS§N\BB‚ÜşąąąÜěŮł7}}}.11Qn}IßęŐ«óďÇŤÇ%''+ŐKÂ%swwWZ·_ż~Ě=Ěś9Siý®Zµj|ýćÍ›+¬űüůs®RĄJ|]…n¶b±XĆMşsçÎrëúűű3ő†ÎeddČ­›šš*ă†ÓĽysąnRĺrń-Eqń‰DĽ»ÚÎť;Ęľ~ý:ăZj``Ŕ‰ĹbąuĄÝ}Ă”ę=gΦ~ź>}¸·oßĘ­›••ĹŤ?^°«¤‹Żä82sćL…ă`fff|ýˇC‡*­+yÜşuë”Ög\ţ]]]ÖŤŕ?' ß}÷ćÍ›rë~ţü™óóóctńőő•[÷Űożeęr999rë&%%q=zôďË3äâ«EuńŔÍ™3GĐ5ÜÝÝů6 ëŤ1‚q1UÄ»wď¸Ę•+óuÝÜÜéÁqwîÜ9ć‚‚‚dęH»řŕţůçAň˙ý÷_¦]hh¨Âşäz÷îÍż$]d•Ѹqc^ţŔĺÖ‘ţż˝qă† ŮŽŽŽ|›FŤ1ç.^ĽXhß)bńâĹLŰC‡ n«ČĹWő­ €áÇ+ ąŢ¨Q#đeŽăδ©BVV\ Č_‰=zô¨ÂÜ\ššš5kŁkFFfĚQčµŢżčׯV­ZĹĚć—‚•# żŻfĎž­´ľŤŤ ° ČwŃűřńŁÜşłfÍBNN_>zô(şté"·®H$¢E‹Đ®];ţŘůóçeÜŽccc—]]]±yóffEF’jŐŞaçÎťčСěîݻشi“’»$ľţű!D`` ¨°ž˝˝=Ě—ÓÓÓF˘T…””Ć“ÂÖÖű÷ďWţAWW+W®dţ_˝zUč $đ˙ăȸqă0gÎfU¸¸HŽ#ÎÎÎ2ž*ŇtčĐÝ»wçËŇL›6Ť˙ś455¦p…HKK ëׯGăĆŤůcűöícĆ!ř÷߯Aá·ß~S˛V­Z8|ř0*,,¬T‚ĹŹ~ýú Şgll\˘×˝sçŘÇŰŰ[pŰNť:1«y˙ţűoˇmŚŤŤŃŁGŐ”€§§'>Ěż$]d!‹ů€nĘtýurrB۶mé4qâDřűűĂßßnnnüׯ_gęŞŇď˝zőbĘBúť¨XJ@GGG'í^[đ VV¬XÁDë\ąr%3Ř+â×_eŚŘcÇŽ ş^ŁFŤì$‹Ĺxűö-ŞU«†jŐŞ ŽPŮŞU+F†Ľ°ę÷ďßÇŽ;ř˛łł3:vě¨T®––ďjX€´]PPrssäţk×®-T_‘H„őë×3źň\¶‰Ż###Lś8±ĐzŇnč%1ŽĚź?źO‘Pđ=mzůňĺŚ)ôűlgg‡ĄK—MYĽyóqD-[¶äß+ę˰°0ś>}š/{zz*Ś\€žž3™P¦C’_~ů…_˝zuA}R©R%¬_żž9Fă 6TËuĄ'Éśśś·‰D°±±áËB\Ž űß++^Ľx &š^ćÇŚ űöí_Ł˙ţXż~=ÖŻ_ʵk×2ĎF’ýn``€-Z–keeŸ&—”«7Q~ |ľýö[…+–’ČK/S\$šęÔ©OOOAíôőőáăăĂ?Ą¤¤ 66ÖÖÖJŰMś8±DW<€ü}bBf Ą’_644” J l•[’îÝ»3}!„I˛ßÝÜÜdR(˘iÓ¦pvvćÓj\ľ|b±XiXzâëŔ××U«V-´^iŚ#’yŰ´i#řłvíÚđđđŔîÝ»·oßFjj* •¶ BĄJ•Š®°ŚŤŤ‘ššŞr;!ăä˙;™˝żŠčŮł'ł7711‘OOOgâx{{ËM$Ź:ŔŇŇ’@ĄŐ˘víÚ…î—,-$ % >|XĄU}Iď'!ąD%ă[”999¸w˘sçÎ RWb«ÉĹA˛ß y°H˘§§Ç§šĂ•¨8J6NJ‚śŁ€jł–»r介f J4P'éééĚʨ"$D"ľűî;AňÍĚĚţř$%%1yQú˝Ŕ@MKKClllą™&Ô‡••• z%ť˙2//Oź>ĺËÎÎÎ*µ·µµĺ T±Xڏşş*mS^ľďÉÉÉ8xđ`ˇő?~ĚżŻQŁSvvv ÇI™€ęý޲eKţőáÇ‚&/!…¤ˇ$‹ Z¨ŚĽĽkkk3{3Ë’ÔÔTDEEáÂ… 8sć ®]»Ć»ę+Cr)©ŐÉÉE k*ý.˝• TB]Ľxń˘Dĺeff*ý­˛Ť©¨<ţăĆŤ+4uś‰‰ ŕŕŕ€U«V)őKHH`ʦ¦¦ĹÖ“ă¸íw!ž$DĹ‚ TBiHďŇäńăÇ̆ůuëÖɤjQ…ÂfĐŞU«V"ka$''ół–ŃŃŃŠŠ’ąWˇH>X–Ƭ% ÜÝO4sI%óĐR¤ Ąąsç+/^a:‚ö·—/^0cHTTźÚFUĘbQK4ŽęBňČŘŘK–,)–ĽĘ•+WĄ"ńâĹ těŘńńńĚńJ•*ˇM›6ptt„annÎźßşu«RU:—µä~Ô˘"‰P§NŢřµ··Çرc‹,O]îáDéA*ˇ¶ýŇn#ĹĄ°Ë’ŚÚ+Ź›7o" €Ď)« 4mÚ•+WVš›ă8Ću±¤,˺߉Ż/e)ĚP*íq$,, |ľfEhiiˇE‹ČËËĂíŰ·Ö{÷~ýú%˘gY÷;A”’™™™2dú”)ţţţŚqjaaéÓ§cŔ€Jsˆ´ÇHQ'ĘäÉ-0Puuu+lżĄ¨„ÚVÔąsçbaŞD€+i:„ţýű#//Oć\­ZµxWGGG´mŰU«VĹĆŤ•¨"‘UŞTá]ĄˇQé~ďßż±fŐµrFdÜB=<<Š•†Â¢¸*™ 6(L-SŻ^=~ÄÁÁvvv¨RĄ fĎž­Ô@­\ą2D"ďÁQZăČŕÁ‹µżÜ{ u!i€eeeáÍ›7%žĘ¦´‰ŤŤĹ‰'řrÆ qíÚµŮŰ+§D5)) aaa|ącÇŽü3CăĆŤqţüyYő%2P µ!=+çëë‹#F¨I›˘óčŃ# 0€1N›4i‚I“&ˇk׮ŠťoiiÉç +ÉYKI¦M›Ć¤Ľ!Š„´A9věXôěŮSMڝ˗/˸¸µiÓ'ND§NťP·nÝ"É­\ą2ęÖ­Ëď÷*­qdÉ’%ĄľşLĄôw9<<\pNV±Xڵk×ň{Á[µj…Nť:•´Š…Él#úĺ—_§…EŔ544„‘‘Ţľ} 8{ö¬`˝¶mŰƤŁzöě˙^˛ßđôéSÁ± ^ż~ÍDwss+7Áë’ TBmÔ«W:::ü ˇôFüŠÂŇĄK™€G#FŚŔ† JÄĺ±qăĆE6Pß˝{ÇGí«T©jÔ¨ÁË”$!! T˘Â"ý}®¨3ń‹-bRJMź>˝X{i%±´´,˛úúők~ňMWW—_é”×ďd [[[čęęň)K–/_.Ř@=xđ ĆŹĎ—8P*:Ć«WݞdnVe$$$J“×®];~…öćÍ›8wîştéRh»“'OňďëׯĎě}m×®˙^,cŐŞUX¶l™ ˝—.]ŠE‹Č÷6“4|‰/J^H¨ f¶,::ZĄö)))ŽŽć_ňÜkË‚3gÎđďMLL°fÍAƩ5YYY¸˙ľ ťÄb1,--ajj SSSćTzĹ©°˝nŇ<ţśďsˇúDiall̸›Şú}NLLäżĎęLö.9Ž4oŢżţú« vŇŃĚĺ!iLĆÇÇăÍ›7‚dřđuęÔáÇ‘ůóçË• ¨ŢďŹ=âű]:e A”%ĆĆĆĚoäĹ‹ůëĘČĚĚÄś9sřrµjŐŕááQ*:†ôŢň¸¸¸BŰĹbŚ5JüYłf1ĺ… řńâĹ‹¸pá_–NoŐ©S'tîÜ™/Ż_żž đ8 IDATÉi­çĎź35ťťťK,:9Q~ •P+’yIŹ?.hP-ŔŰŰ­[·FëÖ­áĺĺMMÍŇPQ)Ç!11‘/ŰŰŰˤaQ„˛}cHçm]ľ|ą Ůׯ_Ç»wďřr‡ř÷zzzĚ`ľaĂA©*€üýkíÚµăű}öěŮ‚ÚDi"ů˛sçN&(2Äb1şvíĘź˙÷ż˙•–ŠJyűö-˛˛˛ř˛“““ŕýśBĆ‘ćÍ›óďsss±zőjA˛CCC™±Ar177gö®ŻYłFL ?Ňą­­-ß華%˘đţý{ĄżsS§NEőęŐůňäÉ“•z0deeˇoßľ¸sçĚËË«XÁŠ´Ôşuë”ŢoBBľűî;f…PôĐÁÁ}úôáˡˇˇčßż?3nIňęŐ+ 2„ń ‘é{ńâĹüX—ťťŤďľű‡V¨wbb"\]]ńáĂţŘ AÖ'*.d jeňäÉüűĽĽyňű÷ď/´ž§§'ł‡uűöí‚Üq6oŢĚ”%,¶ß_Ľx!8¬ţşuëóľľľ‚ÚDi2eĘţ}FF¦Oź.¨Ýľ}űË—Ő5Žčéé1lBÇ‘fĺUC† á]ü|cRŃĄ$’ăH$Bűöíů˛––řrTT¶mŰ&Hď%K–đúúťř˛‘ôdúřń#Ž;ĆŻúIŻţUŻ^Ó¦McŽÍś9nnnXĽx1._ľŚ·oß"22+W®DăĆŤqúôiľ®••U±ÓÓ Ć#íÂ… čŐ«n޼ɉź>}BTT–,Y‚ćÍ›ËÍ•zęÔ)fŇ]’ůóç3}zŕŔ´oß+V¬Ŕ•+Wđöí[DDD 88M›6e"}:Tnl€¶mŰÂŰŰ›/çää ˙ţđőőĹÚµkqűöm¤¤¤ŕňĺË ‚µµ5#·WŻ^9r¤ =ETČ@%JeQ#Ń·o_ľĽ˙~ 0@©ŰÚÇ™ PďNË–-ů÷…}ű6zőę…÷ďß3Ç%g ĐÖÖf\ý˛łłŃ»wo¤¤¤(”âÄ „„„đĺ† Ęđ÷÷g\ô¦M›Ć¸ď)’;uęTľlhh=z(mC%…˛tFžžžprrâË«WŻĆ¸q㔺 Ý¸qy°ŃŇŇB˙ţýKFYŃŐŐ…••_—¤ąrĺ úôéĂz€üq¤ZµjL ’7oŢ oßľĚ*„4üńÔÉɉYa€ŔŔ@&˰aĂd&Ǥپ};‚ů˛……łŤ J éí,žžž066FÍš51sćL™ú?ýô&LŔx/ś>}pqq±±1ěěěđÓO?áĺË—|ť5jŕرc2˙e‰††¶oßÎLtť:u m۶EĺʕѠAčééˇM›6řůçź‘žžmmmĚť;—1Ěł˛˛Đ A8::ʤĚkÖ¬öîÝ‹ŞU«ňÇ"##gggĂŢŢ“&MbĽX4h ÔűkÍš5Śktnn.öěŮ˙ýď°µµE­Zµŕââ‚ 0ż¶¶¶ŘłgŹÚRśĄ }ŞD©sőęUĄç.\Č$ľßż?zőę…C‡1†Xff&‚áââÂ;v¬Ś+lY"ůp•™™‰>}ú0n?¤§§cÚ´i°łłĂdÎKÎĆJâëëË<¸vípôčQĆŤ7##łgĎfÜpD"c¬ ­­-cNź>#GŽÄ™3gśäädLš4 žžžĚÄApp°`wf‚(.×®]Sz~ńâĹLyÍš5đööĆńăÇc/55sćĚA×®]™ďůěŮłQłfÍ’UZř÷Ż^˝Bż~ý<ČĽ}űcÇŽ…‹‹‹Ü•E+ŞăĆŤc"ź>žńNkٲ%nܸéÓ§cüřńĚoy^^®]»†ÔÔT™kxyy!""‚™WĆ€pőęUƨ•ĆČČÇŽòeË=Shjjbřđá8}ú4ôőőéAT@8Ž+ł2Ě~A†ÇĽŇÍÖK&ŕ€Z*:˘˙^]p\yĄwďŢÜ}ÁŕNž<)·ŢÉ“'™z'Nś$?::šiwčĐ!ąőŇŇŇ8‘HÄ×ÓĐĐŕěěě¸Ás={ö”ŰfĹŠś––#żŕŐ¸qcÎĚĚŚ‘YđęŢ˝;—››«Pçľ}űňu---Ýg|[www…őRSSą 0z‰D"ÎÎÎŽóńńáúôéĂYXX0úróćÍcŽp~~~ÜćÍ›e®qíÚ5ÎÔÔTn˙XXX(쟀€…z‹ĹbnذarejjjrÍš5ăLLLäž˙ůçźUęKuđęŐ«}s°Ŕ,đ+€‰†č  €–¨ €Ę´hqĹG4ţ»6·lŮ2ut‰ ěíí™Ď:&&Fn˝-[¶0ő˘ŁŁÉ?qâÓîęŐ«rëĹĆĆ2ő´´´8gggnĐ AśźźźÜ6Ó¦M“ű ‰8kkk®Nť:rżĎŠäŕääÄ×íС ű,ŔĚĚŚo;tčP…ő^ĽxÁUŻ^]ćž9___ÎĂĂ‘€«]»67}útćXŤ5¸#Fpţů§Ě5Nť:ĹŞÜ?‹-R¨÷§Oź¸ďľűNn;mmm®E‹ś‘‘‘ÜóË—/W©/ŐÁ˛eË ô}ŕ/{l°Ŕ3Ś0@ONš0` Ŕ€.ňł&h”Ŕ8˘ ÷ęŐ+ut‰R>~üČť?žݸqCaÝ[·nńő®_ż.ř÷ďßçŰ)?  ĺllldľ{łgĎVÚ.11‘›={6÷ÝwßqőęŐcžgĚÍÍ9.44TľYYYLźĽ|ůR𽦦¦2mßż_h›—/_r#GŽä6lČihhđş7jÔóööćV­ZĹĺää0m/^Ěéęęňu+W®Ěť={Vé=s>>>\ăĆŤůqW$qććć\Ďž=ą3gξϢ˘˘¸źţ™suueĆ mmm®I“&ÜŔą»wďŞ,WÝH}}}Ń®];âÚµkrÝ555áăăyóć1A›/Ź‘#G2Á,jŐŞ%·^«V­ń víÚ‚äKŹ?őęŐ“[OCCűöí···JŃ˝ÝÝÝÉ“'ăŇĄKró~jhh GŹří·ßТE‹Be>Ý»w&Źź&LŔ»Ęö?ŮŻ_?´iÓr¨éęę˘eË–!!Šbaa™śfňČÎÎĆ­[·…jŐŞˇI“&°¶¶fR?…””DFFâŃŁG033µµ5,,, ­­],ąeMRRRÁCđgGä"55 ŔGżńŔ»˙ţ¦H űżúąÄÄ\Ě˙Ć€őF.[¶Ś‰€J(ćóçĎ8wîž={†ĽĽ<šš˘A°łłÔţýű÷ŠŠÂ˝{÷`jj kkk4nÜşşşĄ¬yńHMMĺÇ‘ÜÜ\ŘŮ١E‹Ě~}I=z„K—.!33–––°µµ4i‘‘Á瀭Ył&š4i++«b§ËHLLDdd$âââаaCX[[ŁaÆjIV–/_Ž &Ŕs7‘?ž|Bţ8’˙G Ć‚q$ůă̧˙ÚŚ#\1Ç oT{őę•ŕ‰!‚ Ô‡ŁŁcA…$!LČFţ‘˙)xICţŘ’‰ü±¦`Čň’®+‰ ˙“ M9Ž“ €˘˘Ě†­q”Ôá8N/ÎĽ8rĺA+¨D©ˇˇˇ.]ş K—.Ejo``€:ȤH)ďčëëĂÎÎNđtýúőáçç§ňutuuáŕŕŔW) LLLŕîîÎŻ„:ŃÖÖ†››[‘ŰWŻ^˝Xăş044Té˙ŰŇҲHZôőőŃľ}{&…LIP·n]&(AA…˘řAAAĺ2P ‚ ‚ ‚ r¨AAADą€ T‚ ‚ ‚ ˘\@*AAAQ. • ‚ ‚ ‚(JAAA” Č@%‚ ‚ ‚ Ęd ţ{÷Eµ˙qü= -!t. RéĘ• Š  ü¸,(‚˘˘^Q°pŐ‹bá*x \{Q,`ĄWP:ŇBK/óűc3Éěěn˛)Ű’ĎëyöÉîÎěĚIűÎůžsć JPEDDDDD$,(A‘° Őééééˇ.‡řÁöżj†˛Š#"ÄöżšĘr8dâH¤°ýŻć„˛‘D Ş˙6ć¦M›ČČČuYD¤k×®µžž e96‚[ŮD$Ś…iŮ Š#"‘ ##M›6Y/O„˛,‘D Ş˙NŰ222X·n]¨Ë""…Xľ|ąőô—͡ęU] ne‘0VHW,±?‚a%(ŽD‚uëÖY[ÉäŽ~p°ÇŽpńRJP‹F•K‘áŁbYXđt%óW cűöí9r$€§‘’:räŰ·o×°<{ĎGA i0’U%¨"˘€şHA1"ŘŤ^aG jŃ,xůĺ—ÉĚĚ uYDć 6°dÉëĺŃÜŻÎ@ďěů0˝l+mŔ:€éÓ§ŕđ"RZl˙ŁÇÉżwĚWń¶Í×{%µ `É’%lذ!‡‘Ň™™ÉË/żl˝Lň±›=~řŞŹ”;JP‹ć5`×úőëyüńÇC]ń"++‹aÆYŤH»Ľ'źľÔ@_4iëׯŔáE¤¤ÖŻ_ϤI“¬—›sżz«Hâe›SiÇ‘ťŔë™™™ 6ڬ,oŁE$Ôüqë:ź‚«>RXC9xĆ™rI Ş˙Lŕ00'OžĚš5kB\$qzę©§X˝z5@*®I‰Š›śRŔ{%ń5đšUąÔh ‘đâřßܲmvĆ“śÜ‡iűčáy&0řsőęŐ<őÔS:Ťך5keeeńĺ—_Ň®];^zé%LÓ4qU*á_BęĽ8X_ĹŤ1 Ř»zőj:wîĚĉ9~üxO+"ľ?~ś‰'ŇąsgűŚ•¸ąĽU&ł˝¦aôÇMÓ¬Y˛ú<‡@tîŁP¸×ýdŐęÖ­KÇŽéر#őęŐ DQD0M“m۶±rĺJÖŻ_Ojj޵é°פ&đłp ŻIĂu/Č©Ü}Źáš¸ )÷ůÉÜm©@zîgň*śf1fn WŁ`4PW©ü’»gśqť:u˘]»vT©RĄ8§?¤ĄĄ±~ýzV®\Éüíß{®F.{rš•űČŔRpĹäÇ$\±çdîöÔÜýłČŹ#”0ŽäÇ‘Š@eŕ\ŕ %@LL íÚµŁS§N4oŢśüđ#álűöí8p€Îť;S±bĹ—HüqčĐ!V­ZĹŞU«8|ř°őv&®[Śöäľ¶'¤™¸ę©ä×EŽă^9ŽkYš\ő– Űçý®‹†Q“üÉ™Z™¦ąą ý =^ňéí!Çyă.łę®¦%9®×s)Aőëö‹Bň/ 1@3ŕ! ;ó‹Hˇ¬ ţŔsčťuAČ$żby ×ŕůIŞU±LĆuA°Të%­XB~ĹŇŢĐ ôĆgáŠ1"\9¸bŔfňG_Xďçź ZËd\ńŠ#VĹňů ŞłbY *¸âGůu‘*@ ŕNŕ˙€„â_DJ,8«+ ÷ŃľËOâY9gcyEl,ŹäUˇ˘sóŮŚÇuqh´ĂUɬ†ëâQü i®D—ÜŻjÖ ˝h\ ¸†f¬‰©äô ŰűÎáxVĹ2Óö5ü¤5öŹsx ”°Ó4ÍÜĘĄŻˇ‚ßkqő¨ž´NĂUů¬H~ ‰&?vŘc‰„V\ –ŕú»ÔËČ«hU slŰĽýźf:¶‡őž·8’7<ݏɩó^Ř\•ŘŔŰ@c ĐWL±ę"pŐC¬(Ž„“:äŽČĂŐó–²˙˛ČŻ‹8owŢbdŐA ‹#ľ†ú–JPýçn:hýÁíÂu‘[TÇŐŁ‹«âbŻh:/ş0„Nm Wîó5Ŕö–EJĆ™P:‡÷fß3jŘ“T{OG îEu¶¨ÚËŚë~•?q5zUŞâŠ#UpĹ{Q˘ę=rź˙ü²HÉřşÖŰ+“ÎbŻ\ÚăH '8ńv?¬5ů°řW ©†+†Ä’_±Ď•¨†Źä'¨ëq]Ż$2Ů˙\ţÄ{C—ó^ÔrA jŃxkQµW~Óq”J¸_ Űçś˝©ş(„–˝§Ă ™|]¬J›ő˙™j{Ř“TgďG {>ś ]ö$ş2ůqÄŠ!öďËŢjč µlÇsĹ‘Čĺ-ŽŘ˙?SqŹ#iäĺőC *–ŚÄ°Çëţ6k(˛U±â…ý3j0/ö|ëw)‘Ç×u>÷äÔG¬Dµ ‘ĺ†T?xą(xKP}%§8ö··Zę˘zö €u‘D&*–Ö=¨)x^Üîń p{ďi4…7r¶ĎY1ÇGÔĐz™ŽçŠ#‘©°$ë˙ÓšĽ¤ ĘĄőŮ`Ä{¬ó§ˇ<ĎÄT 5{‚j]$ňÖXn%¦…ŐEĽ&¨ĄÔXö” Ťóľű\E\\öű< Ü+ĘŢ.Ş\†–ý`%1yśç„VĄ-WĺŇ^Á´÷~ا|Ô𼂆řÚc}řťýűqóŐ˝ĐKw2 ĐÇH «ĚörÚ— ±'§öŢkčŻ=‰UCWčĄ9ž+ŽDž‚*–ö۬Ţ{‚jż·Ými*ű±KąçĂ9˘ËŠ!xĆđĽÎZ‘@#şÂ‡}$†ő÷%‘Ĺy}÷– Z·$ŰöŰŽ şU ÜP‚ZtŢÔ(ÇÜ{N­ —3AUďGčŐ°=OĂ5µ·D_Kűű°«réěAő6,/PCj¬ˇ\î jW*ť÷¦zëý°•ŕHq<ĎŞ\Z=¨Î8íĂ6K^Pď÷ˇZ˝¨VĽłý·ö±7¦W"żˇKł‡űlôÖšÜ9 …á-Aµ×E¬Ćr%¨ą” úÉÇ}¨öĘĄ=°;{F¬?Hë‚P÷„V…Đ±Żťk-["‘ĂyA°÷(XŢJP­ĘĄŐ“j=÷vďX@.>âH6®˙{+ŽŘTç$OöŠĄ–ڧĎG"‹ŻŠĄ}™*{C—Uą´uŢ&ŚűĆś÷ ‚g˘iďaµ×E*‘?bĂ^ÁËW {‚z5tEo÷°Ű˙˙|5{›l­\ß JP‹Ë~s®Sĺ¬ Ű/ö{ÇěśŘ+¤ş WmŰódŕh¨ "ĹVPŞ˝‘Č9{žsß`Ďç¬\zkä˛WŽ˝M|âm˘$P ¶“ŽçŠ#‘Ĺt<·79{?ěŤ]Î媬˙×PÄgąó{p6ri}ĺđcż—ÝZ›W"‡ý˙ÝŠö˙A_KUŮĘ˝ÝZn’R;%¨EPŔ=dn»á^ą´ţťÉ©†ř†{Ĺ2×EA"‹ŻVK+Ŕ;[.­anö…˛ť˝y˙×l±´—ň{@śI¶óž1çmâzÎTĹ‘ČâkŻ·%\¬ŰvśqÄžś´bi«‹XeŤÂý¶ <ă=AµŹä˛×E” †–=A=ŽâH¤)hŻ·$ŐŢčUĐ2Uĺ®÷” –„·äÔţľő‡X‘üŐ9śĆ9¤F„ೡQ‚ąś“$9{QłlŹLÇWŻCň 0„B*—ľ†e’?¬×Š!ÎŢSU,CG jäó6ĂŢĐĺ+†X \Îä4 Ť\Ž8âl÷ÖXW‘ü†.ű Íâ>” F>{Ây-·ęÎ:·ş=–”KJP‹ČËEÁY±t^(¬ŠĄł×Ô>¤tAű,y©hHM¤ň5´ĆyaČv<·/´{= IRíLk­ÔLÜ+”ÎYŔGB+Ůń\q$2yŤálěňC‚–śÚŹmŐe óµ—ßy«€;Ľ5”ëVŁĐsŢŞ8™śqÄ Š!ÎQ\m,wJP‹ÁG’jU0ť­–ÖĚzΙ~ť˝]‚Ë>ű¦–™‰LÎŔťcűęmČŻł…Ňc(M0xIR˝ő†8c·áxş˙4ô´ĚLäóvŞŻŰ|ĹPV*í#HĽMŘhĹg ±S{‚ Š#ˇŕ\fFq$˛8˙ß˝Ĺg,±?w6ŚąR“SP‚Zl>’Tű´îVŇęLP˝U*u!űš ÜV‰<ކ×8/ŢŢw»ë‚P@qN~bŹ/Ţî;U -g‚Ş8ŮĽÝ2`ŹöĄ¨Ľ6p…0†x&¨Qä'¨özn3 /Y¶çÖRF™ĽÝ2ŕ­âŚ!‰#áH j pap&ŞÎ¤TSą‡űkň ‰\¦—ŻöUű×°¸RÁĎŐŰp<ĹĐĘt!˝8’TČďĄńÖ¨e-'Ţă‰_¶ăąâHä*JńaGĽő¦Ú»ě“<*Ž„űďÄš€K"“·z†3f(1-€ÔRR@˘ jĄ gΊe–Ż%"ykĹtß!L.^b(ŽD Ĺ‘˛«ĐaGěĺV oöż!Ĺ‘˛%bę"áB j)+ ’i˙j§ Dh9[łĽ-$‘ĄĐ Î{ŮüŚ#Š!ˇ—ăx®8ůĘbQ]$Ľ9‡•+ŽD6żâC8Ç‘PR‚ Ţţŕ•ÍĽ]PńÍůó×‰äŕďg‰Řď,ĆŮ IDATŻ Ó奈Q‘ (h8¨”‘G‚M jé3ü†ávAĐďHÂťţFĂŹâDýŤ†G›â”kÎuŻDDDDDDDBB Ş„%¨""""""” ŠHXP‚*""""""aA Ş„%¨""""""” ŠHX( ޵±Qŕ^""""""ÖĘB‚ş?÷kuĂ0j‡´$""""""ˇ×ŔöühČJQ e!AÝ dĺ>oĘ‚„vą_š¦y0¤%)˘OPMÓ̶äľlʲ„+AÝŇRCÄ'¨ą¬|»÷)ű” †ŘşÜŻ—†Q%¤% Ă0ę=s_® eYŠŁ¬$¨˙’Ó€q!.‹H¨LŞű€C\–" n‚j§<Ţ3¨YâĂšć^`bîËń†a4-é1EDDDDD"‰açCs_Ţgš¦gţU9f¬—w3JĺŘÁîAÝç彆Ąt쩸&KŞĽbFŐR:®HX3 Łđ`ß›¦ůVéÜmŮËR;ľMpÔhĂ3A5J'AÍťÍ÷ŽÜ—Ë ĂhYÇ W†atVăZŐ$ ¸łtĎ`zËŮĽu>–XpT#Ęó›0˝făĹbšćbŕf h ¬0 c¸aŐKë""""""áŔ0Śę†aÜ |4Ž˙gšćş‚?YÔyËŮĽt>–‚ 8¨OUjí'ů‰«ŰŮk$5ŻaÖÚvĽ4NašćlĂ0VďÍٸ†ü®Çő‹[d—Ćą¤Lhn{ŢÝ0Ś´•DD"•} î‹ ĂHYID$Rµ°=żÚ0ŚR©K™Učś´!żÓqpĄiš;pΠő ¦i⸾OÜô őÜŢ4ŤÖfÜÎßJő<†Q\ D—ć±EDDDDDÂD&0kšfz N`$ź¶čăx÷:łęÎŇ»Ď5Wp{PČن{‚ež”j‚jšćqŕĂ0nşçĺ>šáŢ+ĺ[ ®áá!"RUżĺ>ß‹kŮ3‘˘¨y+[lĂuˇ/ٸ&‡ý řXešf`Gšśá‘A™ea/€Á6LÎq{/‡Ky8ťišÉŔ·ą7†atĂőŹ đ¨iš3BY‰<†aôćľišćˇ,ŹDĂ0fŁr_ö0M3 łŁŠ‡qŞi+ šylÎŘó{™ jˇÇ[ őjŠ„ĂčĺÝ_Í?÷âtÁOPͨy@ŽăÝF¤497če‘<Ţ2ŤOu¶ '¨fŐía˛ĚcC—»,""""""❑Ҵ]<6Dg—ťOĽĽ§UDDDDD$lđś`v1{WꌡIPs˘˝eÜ퍔¦‚^ń”cŢäńžÉg&[«4$ ŞYmű`łçsJđK#""""""vFjÓ˙õâ…cé9¶…¦Őĺu/ď]d$7ą$Ř#šó /›öP5ţ›@ž;t jŐ¬iŔ~/[ž20B™8‹”_)MF-˝l™`˛23§Y"hňg Źzn1Î!ąÉőA/H9gĐ(Ókž¶žŞ»çúüˇí©ŚÝý*°ĹË–ÇŤŁgVvqDDDDDDʵSîxnČąßÄĚ ôéCš šYDxŮÔĘoi¨ŻHp)Műa0Á˦ŻÍŞ»Ł !OÍťcňł—M—‘ÜdrĐ $"""""RÎ'Oo‰iľŤgŽhb÷«!OPâN ĂË–űŤäÓt?ŞH€ÇO«ETÎg@ ŹŤ&łĚŘťk‚U–°HPÍŘ]«Ŕĺcó+Fjă®A-H9``DS÷€3˝l]F\Ô`–',Tłęî×ÁxÎ˦*äD}f¤žîąH¬‹AŁXRšĽ \äeóźüźÉŽ´`–)lTŞîşŚ/Ľl‰''ç;#ů´‚^&‘2ĆHkŢ„ä ?`rĄ—Í© 4cwîvąÂ*A51łÉlö˛ą2đ†‘|ÚÍî+"""""R<ĆÉ&';kĐÁë¦y“ë6Ěŕ »DϬµí8Ů9—qČÇ.÷‘Üä3­“*"""""R4FĘi·e| Ä{ßG͸Ýď·TůÂ.A0«ďůť¬śîŔ&»\F匍Fr“›Ô›*"""""R0#ąq;#ąÉLf˝ě’…iÜiĆîz,Řeł Űäά±{镺źűŘĄ1Ż’Üd˝‘rÚ€`–MDDDDD$iÍ›ɧ˝QkŔčçc·ŁĆ%fÜÎéA-śa› µ?AŐÝ—S ŘílL>3RNűŢ8yZŹ`•MDDDDD$\§Î7’›mź`ć|BÜžMĚě XDDDDD$ŚŤĎ$:z —cp>…Ýiňi1×›u7ź R ö ŞĹ¬şk®‘ÜxD=ô.`×ÓÁĽø‡ä&‡ šÎó;Lc/¦±ŹĚ űĚÚżźVąEDDDDDJ“A§Š¤îO€JŤČ6bťDGµÓźCÄ0ˇęž™fśéׂĹ0Ă«<~1’›\<Ć9Ĺ;§0Ť}łÓ8^şĄ“ňej-ţq許Žkě mD$⼛ĎÍGş0«ÎĎ\]ő`K$"‘ćşCçđYjS66ü‚Ó*¤‡¶@– * €F@=Ŕ(ĆQ’1ÍçHM›bÖ;xŞTËWJ"¦Őάş{‘ńÉM®s"MŠvâŔ< ŚłŠők•˛Ł–mÔCýčs0(^ه”_u˘íĎ»ëş""EVĎGbŚľŠ#ŮĚ&ĘxÔ¬şk?qˇ.Žoa=IRALĚłę®9T­|p7°?űłEDDDDDĘĂ`ÎĆ4Úšq»F™±;÷‡ş@…‰ČT;“ßÓ©ĘóŔóFjăFĆL.ăB|M¨$"""""R6m>#‡Ď¨¶ű'3'Ô*ŠOPíĚ=3€ơř8bbű`ä\†aśE 1hÄ„¸""""""%•öa˛Ăřžś¬ĎĚj{·†ş`%Q¦T»Ü›~?Ę}ä1Žť^“ 9ąÉŞ‘9CSB «3›đSún®úmh $"ç—´¶Ŕ?sź?ÇĹ•7„¶@"qV§ß$°;ënęGiOńÂ01ĚcŔ> s1{˙21łB]ŞŇ‘łřŠ”Ă0ş?羼Í4͡,ŹDĂ0ú s_ö3Mó‹P–GD"Źa3€Qą/¦y ”ĺ Ąť$IDDDDDDĘ%¨""""""” ŠHXP‚*""""""aA Ş„%¨""""""” ŠHXP‚*""""""aA Ş„%¨""""""” ŠHXP‚*""""""aA Ş„%¨""""""” ŠHXP‚*""""""aˇB¨ P†a„ş â“ýwcčwU¶™¦i†ş šżË°· ¸Ôz®ßW٦8"A úH©1$” €aQ@e_› y-ÁUĹöĽŞ‚H‘@zŰĽľv^đĂů"aFE|ÇhĹ‘đ’,µ˝V‰ Yą'ź1ÜăHÇW]Ä[|P ?öxâH¤HÇ3fŕ彬‹„ЎźIɆŃčś tÚq!-”HŮwX ¬ÁŐő ®D|_L/ŰÂââ`F7 ůq¤ŇB‰”mŮŔV\qd5°XfŰî-Ž>¶…<ކ \„+~Xq¤A(Ë$RśÖ᪋¬ľöÚ¶›^ž‡m]$\(A-Ă0˘±Ŕżqőľ‰HčěFßÚŢsV(M/ďĺď‚€hFđ Đ?Řç ѸŔ,ö‘ăx/ä1Ŕ0Ś ×€&ˇ8żäÉ&Sq5‚÷şýyXÄ‘p˘µ Ă8xčpÁĐłgOştéB—.]ŹŹmEĘ0Ó4ůý÷ßY±bË—/gѢElٲ\Aţ`Š{đĎq<ÇńÜ:vĐ‚˘aW/ubcc8p ]ştˇk×®tčĐ*UŞv)¦´´4Ö¬YòeËXľ|9ź~ú))))G{swͱ}uĆ’V0s{MźnŚ-ZpÉ%—ĐĄK:wîĚ™gž‰ne ś˛|ůr–/_Î’%KXş4ďnŹĺŔ­Ŕř®‹řŚ#ĺ=IU‚Z †at–Uăăăůď˙Ë?ţńŹPK¤ÜĘĚĚdâĉLž<™¬¬,€Ť@_ň“ÔÇĂt<ú…Á0ŚGGzöěÉěŮłiŢĽy O+">l۶Ť#F°dÉë­§)xŹŮř®lŹ#†aT~ÚW¨Px€ &P±bĹ@žVD đá‡2zôh<®ŰŽ.Ö⊠ö¸á¬“Řă Pľ“T%¨EdFe\÷»ť=pŕ@fĎžMť:uB],V­ZĹ•W^ÉŽ;fâfcŻPZ_łmŻť˝"@`/ †at~ŠŠŠŠ~ţůçąýöŰŐË!LÓäĹ_ä®»î"'''ř?\÷•9c‡=ž„¤±Ë0ڧ±§ź~:ďż˙>;v Ô©D¤Ž9Â#řôÓOÁuź{? ďu{ ±×G€ň›¤*A-"Ă0&ă›5kƆ ŤŐ$k"áä矦GŹääää×âjPĘ&ĆÎ,Űkg˘đ$5·×c5Đęî»ďfęÔ©Ą} )ˇ{˙üç?ŰA¸zBśqÄC¬8”Ć.Ă0ş?DEEEýđĂtďŢ˝´O!"%’’B۶mŮľ};¸n=z÷şG&žőŻŤ]ĺ1IŤ u"‰aç÷†ÁěŮł•śŠ„ˇîÝ»3fĚpĹ·)@-\łjWĹ5m ®Ą*ášÖ?:w_ë‘ו učţ´jÖ¬“&M ŔáE¤¤&MšDłfÍš÷ŐpĹ+ŽTÁG¬ĺ *?¬G@ä.Aő:5fĚ%§"a(66–Ůłg[ŁŁFťÉŻ‹XËUÁU©„+–Xő·R×ÄU‚Z4C€čˇC‡’겓&M˘AŕšŃ˛PW3Ď$ŐŞ`zMRŕz€éÓ§«‘K$LĹĆĆ2}útëe\1¤:7vŮăH +—]ł4h F.‘0–ČСCÁ.Ç=ŽÄ➤Zu{’Znó´rűŤSG€Ë.»,Ôĺ‘ÄĆĆÚ‘Ú5đž¤ZçE! •KĂ0ęŤ+W®LďŢ˝Kë°"˝{÷¦rĺĘő€ÓpĹ+†X˝ 1¸÷~D“CUÇę ®ĘŻąD›-gh Ô$?I­†IŞĺŻU jŃś ĐĄK—P—CD aű?µ. Ö…ÁŞçmž×$µuhßľ=•*iéd‘pV©R%Ú·oo˝l‡+†Ř»¬$Ő^ą´’Ô@V.;ę""‘ŔöÚĎşŐ`ěşHŘS‚ę'Ă0ÎjĆÇÇÓ´iÓPGD ѵkWëisň+•ö‹‚Uą´őŤ"°C};:Ę&"aĚöżÚ Wü°bIž•Ëď#+Eťe‘0Ő´iSâăăÁ+¬ú5ĂŮ`îk4FąëE­ęDżś~úéˇ.‡řÁöżZ ×ĹŔř­ oźňÝ9Ý{Ă0ŚRšEŻ‘Łl"Ćl˙«ńäÇű„HεQť3¶ýJ,·‚ď(›HD:pŕ;věŕřńăyď5kÖŚłÎ:+„Ą*}§ź~şµ.ę߀“¸Ď}aŹ#ÎşHTî¶R‹!‘B Ş˙ĘM«…Hcŕęé°†ÍX˙ËÖ˘ŮÖ#+wűrnk–¨®ŠĄâHdŞ«±Ë>üÎ^©ô¶”•µPŞ ]!’““Y˝z5›7o&))‰“'OR»vm¨_ż> śqĆĺę–Źź~ú‰qăƱjŐ*RSS=¶Ź7Ž'ź|2% ŠXňă5ŠŐŞ‹x[Â* ]‘@ ŞĘS—şHdŕBă-9µ.ąç…ˇÜ]DÄ« ¸*—ö{bš‰+†Ř×6Ě& bȤI“8qb‰ŹłlŮ2Î9çśR(QŮfš&|đŻĽň ß|ó ŮŮŮîËyçťGbb"˝ző˘sçÎT¬X1HĄ ®‘#G2kÖ¬P#”ŞŕŞŹŘ“ÓňcýQ®ş” JČ:týű÷sěŘ1 Ă !!„„ŞU«ę˘IŮQĎäÔŞP¦“?ü7“ŔŢ?¦Ć®2âäÉ“ěŮł‡¤¤$233‰ŹŹ§~ýúÔ®]µi–IpÝłnŽgU*ÓqÝšžű°Ż­ň†®¬¬,ŇÓÓK|śrP'.±;v0lŘ0–.]ę÷gRRRXĽx1‹/Ęnâ{ď˝ç59­]»¶[}ŻV­ZÁ,V°UÂGŔ˝ˇ<ťüúH:ůőçÚĘĺćźP Ş]NN_~ů%oĽń?ţř#{öěńş_LL Mš4áď˙;‰‰‰$&&ҨQŁBŹ˙ôÓOóő×_¸ŹaÄÄÄP˝zu5jD·nÝčŃŁ‡ßq۶mÜ~űí^·˝üňË4iŇÄŻă8-Z´©S§zĽ_­Z5Ţ˙ýbS0pU!8ž˝Ri%§öÉM<. ĺĄŐ2Ň<đŔ¬Ył¦Dlj‰áăŹ?.tżŐ«W3{ölľůć¶lŮâµÂ^±bE4h@×®]éŐ«‰‰‰´jŐŞĐcĎź?ßľî&:t`ňäÉEűF$˘đŚ#ÖČ çšĘΙ|K…Fs…·-[¶Đ«W/öďßďu»Ő_ąreŽ;ƱcÇĽîW/3éééŚ;6ďuTTO=ő·Ür Ő«WaÉ‚®"®xál(ݤ‘_±ßJEţhŚrC ŞŐęŐ«ąé¦›Xż~}ˇű¦¦¦˛e˶lŮ’×ęvć™g˛qăĆď×ذa‹-*rŮ*W®ĚW\Á„ hѢEűž{K$bD‘?‰š=f8ăs†U±Jĺţ±Ç’víÚ•É!¤ˇôâ‹/ňǸ˝÷ÄOđŔřüLť:učׯýúőăé§źfٲeĽđ er¤íŰ·»˝îŮłgJrV©«±Ü?śÉi –»‹JP a«X–Ë?ŇňĂ?0dČŹ^ćÍ›3|řpZ¶lIăĆŤIHH %%…C‡±fÍ~ţůgľřâ ’’’Š}îłÎ:Ëë»?˙ü“ß˙ÝmzspőÜŢrË-TŞT‰oĽ±ČçűăŹ?řá‡čŃŁG‘>7wîÜ€%ß’đŁÉďá°÷xŘ·;‡ř–&Ĺ‘kÚ´i‘{zbcc˝ľčĐ!z÷î표֮]›áÇsîąçҤI5jDVVIIIlذeË–ńĹ_°{÷îb– ‹!Qxöz¨Qüď˙s{=|řđ“SoşvíĘ›oľINNNá;Gg‚Ú A•$ä Ľ×Gěo˝§ĺî–#%¨p999ÜqÇnÉiLL sçÎĺ˙ţď˙ŠŠňřL‹-čŃŁwŢy'™™™|űí·Ěś9“O?ý´ČçżâŠ+4i’ĎíëÖ­ăî»ďć»ďľs{˙öŰo§_ż~ÖËjذ!iii=z€×_˝Č ę믿ž÷Ľm۶lذˇHź—YAŢz8Ro#©Bî˝÷^î¸ăŽR9ÖC=d­]—gҤIÜsĎ=ÄÄÄxýLçÎť>|8«V­âŐW_ĺŤ7Ţ(•ňHHy‹!ÎX˘žŹr())Éă>ř#FűxŢęD‘îđáĂnŻËb/±ź|ŐC j(‡Ŕ4‡5%¨pżüň ëÖ­Ë{Ĺ˙ţ÷?ě×ç+V¬Hź>}čÓ§»ví*őŔvÎ9çđí·ß2f̦M›–÷~rr2Ď?˙|É­ĄRĄJ <8o’“÷Ţ{Ź^xÁgĎŚÓ˛eËŘĽysŢëaÆqď˝÷ń;‘XÁÝříçĽ@\ĘŐĹ%Ň%''3wî\·÷ĆŹĎ>č÷1:věHÇŽ™4iR™ě)g¬˙_{CVAŤ\†—Ď–™űÇ6mÚÄÖ­[ó^˙ýď§Nť:yŻúé'Ţ˙}¶oßÎţýűÉĘĘâŚ3Îŕ˝÷Ţ+đ¸[¶laÁ‚üôÓO:tŁGŹRµjUâăăéر#—]v;v,qů7nÜČÂ… ůĺ—_8|ř0IIIT«VŤřřxştéÂe—]F»víü:Öźţéö:::šöíŰ—¸Śľ¬X±Âíś}űöĄJ•*~}öäÉ“n“H6nܸŔźçĘ•+Ů»woŢë>}úäŐkrrrřúëŻůřăŹŮ˝{7ű÷ďÇ0 şwďÎäÉ“Ýć°˙­üüóϤĄĄyśŻeË–´lٲŔď!##ĄK—˛páB¶lŮ‘#GHNN¦nÝş4jÔŢ˝{s饗úŐą`ůí·ßزeKŢëóĎ?źzőęĺ˝ţĺ—_xď˝÷Řľ};űöí#33“ÓO?ťŹ>úČďsä˛b˝ľáíáÜŻü1MSŹä˙‘ôĚ®]»šR4=ô‰ë˘lf·nÝzľˇC‡şťďÁôësÉÉÉfóćÍÝ>۶m[Żű®YłĆmż¦M›š+W®t{oîÜą~—yÔ¨Qyź«Qنą}űv·cŐ¬YÓďc‰Ëţýű­ź_đđđ0xx¸ ¸čôÚMx :®™ő¬{B łdq$ x0§NťŠI™tŃEąýŻL›6­TŽ;oŢ<·ăVŞTÉLOO/•c{3}út·óőîÝ;`ç˙Mť:ŐúťěŢŢ^^žFC€K€®@K 1PĂ5 JŢÄIfÉâH4p 0÷ďßď×÷đ裏şým]}őŐ%ţąŚ7Îíß}÷ťiš¦ąjŐ*óěłĎvŰf=ŞWŻîóxk×®5űôéăősÎGĎž=Í•+W«ÜË–-3/¸ŕżÎsÉ%—6l(ô«WŻvűśafrrr±ĘçŹ+®¸Âí|{öěńűł7ntűěu×]WŕţC† qŰÇŽ¦išć—_~i6iŇÄëĎ­m۶ććÍ›ýú;Ź<ňϲdee™łfÍ26lXčqŞT©bŢ˙ýćńăÇýúą8ë©‹/6MÓU×k۶­×sÄÄÄřulÓ4Í®]»Zź[ ĽĚfĎŹc›Á@"p.pШ‰kíÔJąqÄ(I‰”GŮG agÇŽnŻ;uꢒ,66ÖăžÓ 6pňäIż>ß±cGÚ´i“÷Ú>d· iiiĽóÎ;y݇ âsř ”sŻŻ{<¤śsĆ­víÚ•çai’Ď[ď¨3v”ËŰŢ|óMşwďÎŻżţęu»ŻQÓ¦MăÜsĎő{’Ŕ%K–pŢyçńÖ[o©|O<ńÝşuó{ŤŇE‹ŃĄK>űěł÷kѢ…۰\Ó4ýZ© RM™2…K.ąÄç=ö-rěŘ1.ľřbnľůföíŰWčţiiiL™2…óĎ?ߣ‡Ű_ďĽóÝşuóy»U żOçĐ]gŻ)Ží历řJŔ9gŻ´ 7gź}¶Ç{t[Dş Æ Ë›:ý›oľa÷îÝ…®‰úńÇ»MÔ4lŘ0˙ ,ţrxgĄŇŰE Ü^$˛â–MA‰iąŽ#kÖ¬á ##p­Ý}öŮgÓ¶m[ Ă`۶m¬X±Âăs˙ú׿8q˘Ű{qqqüýď§uëÖ´hŃ‚˛nÝ:ľű Ë222¸ţú뉍ŤeĐ A…–ď®»îâ…^p{ŻFŤôčŃÖ­[sÖYg±oßľĽóXóI¤¦¦2xđ`-ZDďŢ˝˝;66–ÓO?Ým™»îş‹ü‘ ĘV5{áÂ…Ś?ŢęѧV­Z´mŰ–łĎ>›ŚŚ 6oŢLRRŐ«WçꫯÎűÜúőëůí·ßň^÷ěŮ“„„ŹăŰů-IIIôčŃM›6ą˝ßĽysştéBëÖ­IHH`Ó¦M¬]»–%K–ä%Ź7n$11‘U«Vi˝Őőë×óĐC‘žž¸ţ&Ű´iC›6mŽŽf۶müôÓO~ŻÎ†­‚bIąR¶ţs$,5oŢÜíµý^ËpÓ¸qcŹ÷üíA¸ţúëŐ÷ěŕ IDAT?~űŚß~űÍëŇ/ˇćś \ÁĐ_őë×§o߾̟?(|MÔ˝{÷şM$ ŢÓ ńđËĺ…@<9[ňwíÚĹ;ďĽĂ!CBT" 3ő †uŮşu+˙ůĎüŢżzőęy3Sű’žžN\\ .ô9˝}Ň™äädnşé&·íS¦LáľűîóyŽ:uęđŃG1jÔ(^~ůeŽ=ĘäÉ“ó&(t:zô(·Ýv›Ű{3fĚŕ–[nńyž„„.\Č5×\Ă»ďľ Ŕţýűyîąç|Nš8yňd>ýôSţú민÷Ö­[G˙ţý©WŻ={ö¤WŻ^tďŢť¶mŰFlĎjzz: 6äË/żô:â ÜĎ%őÖ[ońÉ'źä˝®QŁk×®ĄiÓ¦>?sá…˛fÍÚ´i“7 ű›oľÉرcýžĽ*==ťŘŘX,XŕsÍÖRř>˝ÍĐ[ngíuŠĚ˙‰(Î{NSSS0`Ď>ű, Q©ĽsŢ;cF‘аaĂňÔÂÖDť3gNŢP”ččhŻ­‘"|-[¶$..ŽS§Nĺ˝7jÔ(>ś·N˛H$ZłfŤÇ˛(9í´Ó MPîĽóNż—W{ýő×Ý–éŐ«WŢí1…yňÉ'ů裏ň>˙ÚkŻ1qâDjŐŞĺ±ďK/˝ä6 jŕŔ&§Ă0:u* ,ČűüK/˝ÄĂ?ěuŽÚµk3sćL®ĽňJ233ݶ:t>ř€>ř€*UŞĐ±cGÎ?˙|ąřâ‹#*a}ä‘G|&§ĄmĘ”)nŻ_|ńĹ“SK˝zőxňÉ'Ýţnź{î9ćĚ™ă÷ąożývźÉ©ž&I’€ëر#×]wťŰ{۶mcĐ A´k׎ű pâĉ•ĐĺرcĚš5Ëí˝öíŰW¤ă 0ŔmPA“%Ů·őéÓ‡† é\"âîĎ?˙díÚµ~?|MôQąre&Ožěöމ'¸óÎ;iŢĽ9ŁFŤâí·ßf˙ţýÁř¶DÂZµjŐüN0ÁŐ‹i7}útż‡ÁÖŞU‹{îą'ďuJJ K–,ńşďĚ™3Ý^żřâ‹~—±An˝ŻIII,[¶ĚçţdíÚµ…&éiiiüřăŹL™2…K/˝”ĆŤóŘcŹ‘śśěwŮBĄiÓ¦=ßâ\˘đĽóÎó¨Kdذan·j|ńĹ~6..ŽűďżßďýĄô)A• xţůç˝Ţë±aĂžyć.»ě2jÖ¬IëÖ­ąńĆ™9s&7n Zů˛łłąăŽ;<*›Ĺéá­T©×^{mŢë÷Ţ{Ź””Źý~üńG~˙ý÷Ľ×Á ú"eŮ“O>I‡ü~´®éí·ßąwď^^~ůe®˝öZ6lH“&M¸âŠ+xć™gřůçź=zPDĘşP»vmżö=|ř°Űő˝A´nÝşHçs®ÝémšíŰ·łgĎžĽ×-[¶,đ^UÎóăŹ?¸ëÖ­Yşt)sć̡_ż~~­OzŕŔ}ôQÎ<óLľűî»"•/Ř®ąć*V¬”s9ľ&©ňĹ0 :tč÷úСCë±úr饗R·nÝ"ťOJ—T Š:uę°|ůr.»ě2źű¦ÉożýĆś9s¸őÖ[i۶-gžy&“'Ov›ĺ¶4effňÝwßqîąçňć›oşm«QŁcĆŚ)Öqí÷’žn÷\†›˘üžK*żż]»vůőąÓO?˝Čç’Ň9Ţ%âťvÚiĚź?ź÷ßźI“&ą ÝđĺŹ?ţŕÁäąçžă™gžńX§Ô˙űß˙Ľ¶zţůçźěÜą“¬¬,ŹmQQQĚž=Űë=-ţ8÷Üsi۶mŢúYŻżţ:×_}Ţö”””ĽÉŔŐ*YąrĺbťKD§ZµjĽđ ÜpĂ Ś?ž%K–xŤv‡ć?˙ů/˝ô˙üç?ů÷ż˙Q÷IŮV±bEjÖ¬YŞÇôçľ@‹łáć»ďľŁ}űöyK—ŘżúzĎzmIJJ*ô<óçĎ/ňy˛łłÝŽá\~Ş0±±±\~ůĺy Đééé,[¶Śyóć1oŢ<¶lŮâ¶ff&C‡eíÚµ+ „`&nÎßß]wÝEĄJ•|ţľ¬ŻöçÎż o'Ţ(A =]1%讼ňJ®ĽňJöěŮĂçźÎüůóY˛d‰Űd$N‡fذayC‚‹b÷îÝ>ď3ó¦FŤĚś9“üăE:ŹÓ°aø÷Ţ{Ď5Q?úč#·‰4{ŻHé9r$—^z©ßű{[ZĘ›Nť:±xńbŽ;Ć_|Áüůóůꫯňf‰ô&==ťÉ“'łbĹ ćÍ›ç×p?‘HTŘzßvÎĺ9Ű­ÎóÁđĘ+Ż„]ŁV°î?…ŔüťřűűÓ,íˇ§UÂBTT-[¶¤eË– :”ěělćϟϽ÷Ţë¶ř5¸P2dß2´nÝš¶mŰş˝gqqqÔ¬Y“ĆŤÓ©S'Î=÷ÜR˝ÔŻ_ź~ýú1oŢ<€Ľu×®]|űí·yű©÷T$r5nÜĆŤ3hĐ ¦OźÎŠ+;v,K—.uŰoîÜąŚ5ŠóĎ??D% Î[gĆŤÇ­·ŢZ˘cz»v;ë“&Mr›Ŕ°8Ľ-1SR <ůä“nËߤĄĄ±jŐŞRŹĄť`R­ZµÜzĽ×¬YSâˇéšř(r(A•°ÍŔéŰ·/W\qEŢş˘ŕjU›;w.wÝu—_Ç4hĎŵmذay ę¶mŰřţűďůöŰoó.*Tp»7UD"[çÎťY˛d ˙ú׿8q˘Ű¶éÓ§+A•rĎą¶řŽ;ŠtkqĎłsç΀ś§4x[oóŔ^÷u.ÇSŘ=ńvűöí+ZÁB(>>Ţ-A=|ř0íŰ·a‰$4‹Ż„µĘ•+3kÖ,Ź×pźŠÝŇż·5Q_{í5Ţx㍼×ýúőŁ~ýúˇ(šĐ#Ź<â1t?Râ–H µjŐĘíőňĺËrž+Vä<ĄˇYłf‰gzzş×}«V­ęöÚW"ëŤ}i»pײeK·×ú;‘đ¤UÂ^ýúőąŕ‚ ÜŢógŞ÷pŕ\uÎś9lßľ=ďµÖ>)›˘ŁŁ=&Z;pŕ€ĎJ§HyqŢyçąÍZżsçNż—˙(ŠÄÄD·¤oăĆŤ>|¸ÔĎS¶oßî1üÖŮl©QنŰkűK…ŮĽysŃ "^xˇŰk5đ•/JP%"8ń¶Ď€îěI¨}ĘúşuëŇż˙PID‚Ŕ· ˛b—H ÄÄÄpńĹ»˝WÜ5Ç R»vm·!őYYYüóź˙,őó”o˝ľÖ=ăŚ3Ü^űłN-¸fĹ Ç™}éׯźŰň\_}őUŢ-SRö)A•ŕśŃ·¸ë“†B‡h×®ťÇű×^{mPgÄ‘ŕ:räŰkĂ0J}ýI‘HôĐCą˝ţěłĎxď˝÷Jý<?ü°Űëąsç˛hѢR=Çľ}ű3fL‘z2í8ŕńóhٲĄĎuP;tčŕözĆŚ¤¦¦zž‡z( 3JăĆŤąńĆÝŢ=z´ůĘ %¨ś÷Ž4jÔ(D%)o3őjxŻHٶrĺJ·×ńńńn="ĺU·nݸúę«ÝŢ»ůć›yá…ÜF$++‹·ß~›~ýúůÜç’K.á’K.q{ďšk®á•W^ń{FŰŚŚ ^ýuěłÓ¦MŁyóć >śĄK—ú}ě_ý•Ë.»Ěc­ö‚f5îÖ­›[čСCL0Áç9333y衇={¶_e '˙ú׿Ü:$öîÝË…^č[ ˛˙~ĆŹĎłĎ>"J€(A•€űüóĎůóĎ?‹ýů/żü’uëÖą˝wŃE•´XAuÇwä-ľ˙~8 ŮčDÂŘňĺËY»vm±?żcÇŢ˙}·÷śĂEĘłYłfqöŮgç˝>yň$wÝu;vä­·ŢbíÚµ¤¤¤äm7M“ß˙ťwß}—áÇ“Ŕµ×^[č˙é[o˝ĺ6\6))‰[ną…îÝ»óŢ{ď±aĂ·Čśś6oŢĚ[o˝ĹСC‰ŹŹç¦›nbÓ¦Mž'##×^{Ťž={ҬY3FŽÉ«ŻľĘĘ•+Ů˝{7'OždçÎťüđĂĽůć›\z饴mŰ–Ő«W»§}űöÜ~űí>Ďí±üłĎ>K˙ţýY˛d IIIdee±qăFŢzë-şwďÎOî*V¬HBBB¨‹!"~Z»v-ŁFŤbŔ€Ü}÷ÝôęŐËc–M_ţúë/.˝ôR:äöţu×]˘ŠD¤¸¸8-ZÄŕÁÝîÁ\·n]Ţ˙ŠaÔŻ_źŚŚ Nś8Q¤%U,µk×櫯ľbĐ Alذ!ďýeË–ĺőâZçIOOçĉ~÷âú˛sçNf͚ŬYłŠôąłĎ>›/ľř˘Đ‘cÇŽĺí·ßfăĆŤyď-X°€ ®:Gff¦ŰgÎ?˙|¦NťĘąçž[¤2…Zßľ}yçťw¸é¦›HNN\Ť3gÎdćĚ™€kŇ:uępâÄ Nť:ĘâJ)Q‚*A‘žžÎŚ31cí۷窫®âüóϧS§NÄĆĆşí›’’Š+:u*óćÍsk?~< 4fńE¤śš7oóćÍŁqăĆ\sÍ5\pÁtëÖÍmů(pőžlÝş•_|‘7ŢxĂăž°~ýúŃ·o_żĎ»}űv}ôŃb•ů¬łÎr›=\$\5jÔĄK—ňŕňß˙ţ—´´4·í¦i¸ŚJ•*UčÝ»wˇçiÖ¬żüň cÇŽeÖ¬YÉ[a牍ŤĄWŻ^^·ŐŞU‹›oľ™O>ů¤ŘłGEEqŰm·ńÄOP˝zőB÷ŻT© .ä /ôştŚóű4hŻżţz±ď“ µ+ŻĽ’V­Z1jÔ(~úé'Źíééé®ńÚ¸qcÎ9çś@QJ™T şµk×ć É‰ŽŽ¦nÝşÔ­[—¨¨(öîÝKRR’ĎĎ^uŐU<řŕÁ*Ş{öěaĘ”)L™2pőĘÔ­[—ŘŘXöďßĎÁ}ŢÖ®];·őŹý±cÇ{ě±b•ő˛Ë.S‚*yš6mę6´ÓŰěŇEŐ¬Y3·c–dňŻĘ•+óěłĎ2věX¦M›ĆçźΆ |ţ?Ő­[—‹.şÁÓŻ_?âââü:Oll,˙ýď7nÓ¦McáÂ…Ű­_ż>}úôađŕÁ\rÉ%ÄÄÄxÝŻZµjĽňĘ+Ě1~ř%K–đý÷ßłzőjŹ ťßwëÖ­4h×^{­Ç켅ůŰßţĆęŐ«™:u*ŻĽň {öěńا[·nÜzë­y“ %%%ąýŢśkĹ:µnÝÚm˙*UŞ©ŚçßKíÚµ‹|Ś6mÚđăŹ?ňő×_3kÖ,/^ěłA B… śyć™ 8ÁÓąsçŹ}úé§»•/’&â,«” JŔµhтʕ+{]˙/;;›żţú‹żţú«ŔcT¬X‘űďżźÇ{Śččč@UDpµ¸×ŞUËgŮŃŁG ¬|Z† ‹/ľX¬ ™Hi¸ńĆ=fC-©[ną…[nąĄTŹŮ Ažxâ žxâ <Č®]»8rä©©©ÔŻ_ź аaC·5T‹ă´ÓNă™gžá™gžáŔěŢ˝›#GŽ––FBB 6¤ATŞT©HÇŤŽŽ¦gĎžn‰ÎˇC‡Ř¶mÇŽăÔ©SÄÄÄPŁF âăăiŢĽy‰ë3qqqL0 &°eËöěŮĂÉ“'IHH iÓ¦ŁÍš6mZ¤őD­c—ÔČ‘#9rd‰ŹĐ»woz÷îŤišlÝş•C‡qäČ*V¬÷»«WŻžŰ}«…1b#FŚ(•ňIéP‚*7nÜ8FŹÍçź΢E‹řţűďٶm›_ź­_ż>W_}5·Ýv-[¶ pIED\úőëÇÁůć›o?>ß˙=ëׯ÷¸ĺŔ›ŞU«2pŕ@FŽIbbbŕ +RĆÄÇÇđó$$$t~zőęQŻ^˝€ß®E‹´hŃ"(ç †a”»ďą}8qâ›6mâ·ß~cďŢ˝?~śôôtŞU«FŤ5řŰßţF›6mhٲe‘{ynżýögî)/” JHX­Łľ& 7Ő«W§[·ntëÖ-ÔE)ł´Ş„%¨""""""” ŠHXP‚*""""""aA Ş„%¨""RlZIDJB1DDś” ŠHžéÓ§s÷ÝwűÜľeËî˝÷^úôéC ¨\ą2-Z´ŕňË/gţüůA,©8}űí·ôíŰ—)S¦řý™#GŽĐ·o_®şę*·÷ď˝÷^úöíËňĺËK»RĆegg3dČ>ůäźű|řᇌ1‚®]»ć­#Ü©S'FŤĹöíŰXZqzä‘GŠüż˙á‡Ň·o_ţűß˙ć˝wčĐ!úöíËŕÁQL)ă” ŠýőăÇŹ§U«VŰLÓdÚ´itčĐçž{ŽŻľúŠ™™ÉÖ­[™7o  gĎžśř Dß…”†J•*qÎ9çжmŰPE"P…P@DDBoÇŽĽüňËÜ˙ýÄÄĸm۸q#Ó¦M#::š˙üç?ÜqÇnŰ;wîś÷:t(~ř!ź~ú) ć· Ąčµ×^ u$Mź>ť˝{÷rĎ=÷xl{ňÉ'Ůľ};Ť7fţüů´k×.o[ŁFŤhÔ¨ýúőŁ˙ţ|ţůçŚ9’Pąrĺ`~ RJęׯĎÚµkC] ‰PęA&L€aÉ'Ŕ1cČÎÎćĆoôşÝrÍ5×ЬY3€B{?rrrHMM-VYSRR|nKKK#33łHÇKKKó9QKNNNçó¶˙ńăÇ‹t~Kzz:~ď_”rRq~ćĹýÝKř:~ü8“'Oćâ‹/¦M›6nŰvíÚĹÓO? Ŕ«Żľę–ś:=ôĐC;v¬Đᡩ©©äääଦi’––ćsű©S§Š|Ě‚ţSSSÉÎÎöűX©©©–Ż §Nť*ŇÄSáGŠú3ĎĚĚ$+++@Ą‘PS‚*"RÎmܸ‘·ß~›!C†ŕ¶í‡~ŕŰoż%::šx ŔăDGG3qâDşvíĘáÇ=¶›¦É /ĽŔyçťGµjŐ‹‹ŁE‹ >śŁGŹzěżrĺJyöŮgIMMĺöŰoçĚ3ϤjŐŞ4iŇ„Űn»-Ż‚2uęTÚ·oOµjŐ‰‰ˇS§N,]şÔ㉉‰\wÝuĽđ tîÜ™jŐŞQ»vmúőëÇľ}űřúëŻąŕ‚ ¨QŁFŢůfĚáőűNNNćľűîŁM›6ÄĆĆRłfMŞV­ĘyçťÇ»ďľë±˙ŻżţJbb"Ź?ţx^9zôčAŤ5‰‰ˇU«VĽ÷Ţ{>ĎuçťwŇŞU+ââ⏏gŔ€¬YłĆëţĹuď˝÷’Č/żü’÷žý÷0eĘşwďžWîvíÚńŮgźů<ć—_~Iź>}¨[·.qqqtëÖŤGy¤H÷ĚJřzöŮg9zô¨×ŢÓ)S¦ššJ×®]ąč˘‹ ś¦M›RµjUš5kƸqă0M“śśţýďÓ¦Mââ≉ˇGʬZµĘk97mÚÄŔiҤ U«V%&&†şuërýő×ó믿zě?mÚ4ůé§źHJJâ–[nˇeË–T«VŤŞU«Ňż¶lŮâő\ëÖ­cŔ€ÔŻ_ꏏ8Z¶lů˙ěťwXTG×ŔKQĄ[‘bAě Ť±7"Š˘ĆKÔŁŃÄXň%j4*FĹŘc7ľ¬ń51–Ř64¨`$¤Î÷ŢÖÝEl€Żó{ž}”9wfν»{öž;gÎáóĎ?çŃŁGąľ7ĎCbb"-Z´ cÇŽZí´hŃ‚łgĎňĎ?˙ĐŻ_?\]]U˝ýüü &ĘĘĚĚdâĉŞÝ¶łłŁk×®,\¸Pďoä F!_ąĽÍ“W+@xzz ‰DRř‰‹‹€Ň€M@° XĚ~Fý€.@sŔ¨”¬sŔ04âĺěŃ“ąE```A\Ś7Nbůňĺ:˛Ůłg @x{{żÔ>ť:uRŢakk+\]]…FŁ€prrgÎśŃęłsçN^˝z ///aaa!Z¶l)J–,©ŽóŃG‰ľ}ű @Ô®][Ô«WO••(QBÜĽySkL@T¬XQŚ9R‹† ŠęŐ««}jÖ¬)fÎś)LLLDůňĺ…···011Qĺ[¶lŃ/66V8;;«r+++Qąreőo@Ě™3G«ĎŃŁG z÷î-&Nś(4Ť¨QنhÖ¬™022RűmܸQ«_TT”¨Qن*/Y˛¤pppPϵ_ż~}úôÉóű#agg§ŐŢŞU+ß˙]çý4hřć›o„‘‘‘¨]»¶hҤ‰ú>j4±cÇťyĆŹŻž›ŤŤŤ¨^˝şz]MMMĹš5kň¬s~¨\ďkŔF`-°Xü||ô:Ťę€`”ĚČŢReô ě1pqqqqI âćć&4ŤHNNÖ‘˝óÎ;żüňËKÍqâÄ Qľ|yő;P©R%aooŻţÝĄK‘’’˘ŐGů^Lž¬¶oÝşUË©2dČČČBd–<<< üüü´Ć2dD™2eÄéÓ§Eff¦B;wî?üP˝Ůʉâ ÚŮŮ +++±sçNU«ŢĚ7kÖL«_Ź= ěííĹ_ýĄ¶?}ÓţşT{{{aoo/8 Ę˘ŁŁŐkÔ±cG­±ţúë/KKK­÷éÁęçËĚĚLDFFćYďüB:¨yCů999é•+Î[ÎĎíó’™™©> iÚ´©‰‰Qeýő—:G@@€V?Ĺ!â‰ă¨|GăââDíÚµµĺ3žž®Ú,@Ü»wOOqPѤIq÷î]!„ÉÉɢ˙ţެH‘"b×®]jż}űö©˛ 6¨íYYYęC·ž={Š7n¨˛‹/ŞˇĆŽ«u^Šjoo/7n¬őy8|ř°ę€Ď›7Omżwďž°˛˛/^ś ЦM?~ĚĽyóňEÉ«gßľ}T©REGÇýű÷pvv~á9VŻ^Í… (Y˛$»víÂÁÁA•µjŐŠ_~ůČNƤ̗ &Mš¤~Gs~Ż!;Sy… 011á‹/ľŔÔÔ0lG&L€­­-m7ľřâ Uöî»ďҦMőď-Zŕéé©3^LL ·oßĆÔÔ”€€Ę—/ŻĘÜÜÜ5j€Ápݤ¤$Ö­[§µ=ŁI“&´oß@+Lzúôé$&&R©R%věŘAٲe055ečСŚ=Zﯔ”Ö­[‡ťťŤ†6mÚ¨v%§Ţaaa¬X±‚âĹ‹óŰożQąreUVŁF ¶mۆ……0B-yłŞD"‘ĽĹDGG“žžŽ­­­zŁ“[·n`eeőÂs=z”¤¤$ŞT©B§Nťtä–––ôď߀;včČ­¬¬čÚµ«V[ůňĺqrr oßľ:}çÓPŤÜútëÖM§ĽŠˇńöîÝKJJŠŢ}wÉÉÉjC R  ÓÖ˘E ť>»wďFA«V­´k…Zµji9şŻSSS˝ĄôéIHH%J”Đ{®ź~ú)Ż^YIľpĺĘ@żŞŘkkëžcçÎť|ňÉ':™Ćüüü(_ľ< ?~\ŻĽxńâZmĘw©hѢôęŐKKfccCőęŐývÄŃŃooo­¶:uęP¬X1>úč#ť>úěHůňĺIIIááÇzx%y!ҦMŐćDů>ćśKą†ŁGʦH‘":}† ¦:寝RD _ď-[¶™™‰żżżú 2'ŽŽŽęo‹´#˙Č23‰Dňčż±„ěz—/_&**ę…çPV ęÔ©cp•ŻnÝş@vą›§qssĂĚĚL§]Y ©S§ŽA™!rëó<ăĺĽÉBÉ™3g8|ř0۶mSB3őR¦LJ”(‘§ą._ľ d'1DÆ ŐP…YłféM43{öl˝7¨yÁĹĹEďM¬>˝ÇĄ\ąrlذAďx7oŢx©Ď¤`QśP}Q9W»®_żŽ˝˝ý ͡ŘĹV<Ť±±1îîîÄÄÄčµ#ą}Żťťťő:Ϲّڵkë•?ŻŃh4Zö-55•sçÎÂľ}űضm›AŔ°íÎíűhČŽ”*U ggg­އňő×_ë[»vm5ÚăEpuuŐŰž›ŢBÖ­[§·źâĐ^ż~ý…u’¤*‘H$o1J†ĘJ•*é•WŻ^ť?ţř#ĎOĄ…Lź>ťĚĚL|||¨Qنzłčččh°ź"{o.V­ZĹ’%K8{ö,III@v rk¨ †ŤŤMžçP®K^®aN~˙ýwöěŮŁÓ>cĆŚvPźGoĺsséŇ%z÷îťë±oâ{/ÉF±#J™©ś”(Q‚ňĺËCdd$őë×ćx/^ä·ß~CŁŃ0räHŚŚŚÔĚ®9C`źFůĽi;’““;v,{÷î%<<\u¶¬¬¬prrŇ ›šĽ®J'$$¨öIߊ«‚“““–š’’˘†OçÄÇÇçĄÔ±#Ë—/fŤć7í˝—čG:¨‰Dň٬ŕé+ P­Z5 »ÄHzzú3ĂżBBBÔ=‡:tţ˝É­>¨RŢŕéĐÚÂÎ# ˛Ăl»w·7őęŐŁX±b››żp=Ăś”.]Čý>xđ@§můňĺzKG(aŻĺóU«V-~řá‡\ŹŐh4!ňm/­äŐń,;R˝zubbb8zô(ţţţĎoéŇĄLź>ťjŐŞ©{0mmmą}ű¶ędéăM´#˙üómÚ´!44”"EŠĐ¶m[|}}iҤ ŐŞUcëÖ­:[^+++Š-Jjj*÷ďß×˝şvÄÖÖVŻl¨˙ë@ ÍţěłĎ´öőę#çŢdÉ›‹tP%‰ä-FI¬ˇ„>MÓ¦M111!&&†+V0pŕŔ\ÇSöZ[[S«V-ŕßżÜVČ”ŐCa_…‘{÷·nÝĘ»ďľűÚćR®ˇˇú€†dą­¸ćĘű…ŹŹŹšxJňżĹłě··7»víbńâĹŚ3F}ŕb?˙ü@+WĺĘ•ąté’Ţđ]…7ŃŽlŢĽ™ĐĐP8wîÜs­,>FFFT¨P‹/iĐ6<}}ŤŤŤ©ZµękŃ)ݏşş˛cÇRSSńőő-P]$ůL’THٸqŁVÁó¦NťĘÔ©SźŢ“Yłf©ý^gřTff¦:ĎËrňäI¦NťĘ®]»^fÚ\ľ|™É“'łtéŇW>v~r˙ţ}¦NťĘěŮł Z•<‘’’B@@ŃŃŃ­Šä)”§ÍQQQ¤¦¦ęČ]]]1b“&MâöíŰÇş}ű¶jźZ·n­î%RŐ«·ďÚµk¨Yłć žIţsŕŔ˛˛˛¨Qن^çôĉŻdőŔÝÝ€   ˝+HŹ?Vłü&ÜÜÜ011!))‰˝ÇL0˝űÜ$oŠ1ä >WWW5”5·˝Ůüń.\ĐZ-Slˇ=×®]S3’żIvdďŢ˝@vň'}ÎéÁ_Ů\ŠYĽx±^ůźţipĽ Q~C”lŃO“ššJÓ¦MqqqáŔů©šä5!ÔBHTT}úô!--Mm;věcĆŚaĚ1 4(×›D…ĐĐP†®ö3”&ýU™™©Î“ŰO^8|ř0cĆŚá·ß~{EÚeóůçźăććĆ·ß~ËÜąs_éŘůÍť;w3f 'N,hUň„ąą9Ű·ogěر­Šä)J—.M… ČĘĘ2¸Ďtܸq8;;M 8{ö¬Î1wîܡU«VDDDPĽxq¦M›¦ĘÜÝÝiÝş5iii >\§äĘĘ•+9zô(/µ§)ż±°°˛oŚďŢ˝«%KIIŃúĽż¬]ôńńÁÍÍŤ„„†Ş•ŃSÁčŃŁ‰ŹŹ©9^¶¶¶ęŞű°aĂtB”CBB4iQQQjöNÉ›‡’tGIfó4E‹eţüů,[¶ŚîÝ»«Ůis˛sçNüüü€ě‡\ÝşuSeC† ÁĚĚŚżţúK§Ujj*Ç'33“Nť:řŠßó Ř}ĺQ.]ş¤î˙|Y¨Ö®]ËÖ­[µd˙üóŹş=ٰńţűďăŕŕ@dd¤ŢűžńăÇsäČ’’’rM$'ysj!dܸq”+WÎŕžŚŚ 6mÚôĚq eL|–/_ŽFŁá˝÷Ţ{ĺcżNYľ|9&&&Ěť;÷ąVˇ ’źţŤFĂ'ź|RĐŞĽ4#FŚ`íÚµ„††´*’§hٲ%`xőŁX±b,_ľ˘˘˘hذ!Ť5bčСŚ3†ćÍ›Sľ|yÎť;ŔĚ™3Őz‚ “'O¦H‘"¬_żž&Mš0mÚ4/^Ě{ď˝§–|ůć›ožúWhذ!%K–$99ćĚ™ĂÎť;™9s&5kÖ$88XÝ;5ţ|­rĎ‹‘‘?ţř#Ť†•+WŇ´iS¦L™B`` mÚ´áçźÖ ‡,LŚ7[[[Ž;Fýúő=z4K—.ĄgĎžxyy‘‘‘ŻŻ/;v,hU%/H˝ző°´´äĘ•+©Ö­[«ĐćÍ›qqqˇS§N|˙ý÷ 4jŐŞŃľ}{RSS±µµeéŇĄZű‘Ë—/Ď—_~ @Ż^˝řđĂY˛d 4nÜ­[·bffĆäÉ“_˙ żB:wî do0`7ndÓ¦MŚ1wwwuŻç±cÇŘż?ÉÉÉ/}8věÇŽSeďĽó»víbáÂ…Lź>ťŻżţš7n0kÖ¬žĎĎĎŹm۶ńţűst3ôë׏1cĆ,9Q”.]š3gÎĐ«W/Ž;F@@€*322˘˙ţĚ™3獲gmŚŤŤiٲ%żýöZĄer@›6mřřăŹ‰ŠŠbűöílßľ]•k4>üđC¦M›¦·Fć”)S(S¦ ß|ó «V­bŐŞUŞĚÍÍŤ   j×®ýęOđ5âççÇ×_ÍĚ™3Y¶lË–-˛ż#FŚ`üřńÔ¨Q¨¨(Ľ˝˝ ĆÓÓó…ç[˝z5j]Ă"EаqăFÎź?ŻeË |đ–––ôë׏]»vimł··ç§ź~zăO$†ŃĽŠ˙e4˙>ľk üĺéé©uSđŞńőőeßľ}ܸqC+ ÝĽyó2dŢŢŢ\ąr…ŘŘXnŢĽ©&&xšĐĐPÜÝÝiܸ1·oßćęŐ«ěŢ˝›Ö­[ż”~Ë—/§˙ţôîÝ›5kÖ¨íiii-Z€¬¬¬—ĘÂČ#řôÓOŐ —eÝşuôîÝ___¶lŮňJĆĚ~ţůgľüňKĚÂ… Zť—fîÜą|ńĹ:tHŻó*ąuëeË–H¶@$IŔ} ¸÷äßDŕđxüäř Č/h0źŘ °¨®222¨^˝:™™™\ąr噎Bdd$aaa„……‘śśL•*UpssŁNť:ĎL‚“’’©S§ !116lřF­ś>Mbb"ż˙ţ;—.]˘téŇÔ­[OOOŚŚŚHNNf۶m„……ѡC5jôŇóÝżźŕŕ`Nžâââ8yň$gĎžĹÚÚšşuëRż~}˝ő’ßÂÂÂ8pŕ7oޤzőę4jÔH-ŰŦM›ČĚ̤_ż~/\K6'‘‘‘;vŚË—/S§Nš4i˘÷ˇ@aăţýűś8q‚233©Zµ*mÚ´)Ô™›5j¤<Đ=Ü"Ű&<&ŰF<äß{ĺ~$‘lŰňl[ŁŘ‘, ˛ IľžD>#WP ÇŽcëÖ­ >ÜŕÍČČfΜɆ řâ‹/ô§ěĎđ÷÷gŢĽyçĽ}ű6óçĎ',,Ś«WŻbaaŁŁ#ţţţřřř¨7Ş>dúôéęŢłsçÎ1~üx*T¨ŔG}ôĚs;~ü8AAA\şt‰›7oRŞT)ÜÜÜ|¸ş·äi6lŘŔŢ˝{9{ö,ĄK—¦AôěŮS}ę|÷î]ćĚ™Ł®Pť:uŠńăÇSµjUzőęĄęmaaÁČ‘#uĆŹ`őęŐ„„„KőęŐ©WŻÖ ILL$00úöíË… Ř´i“şźŁZµj|ýő×zo€“““Y°`‡"::+++\]]ůěłĎô)ďׯß}÷ŁGŹćđáÆŢ6I>cbbÂĉéŐ«żýö›Öľ/}T¬X‘Š+ŞˇiĎąą9Íš5ŁYłf/ŞnˇĂĘĘŠ>}úč•+VŚž={ľŇů¬­­ißľ=íŰ·ĄăľnŚŤŤiĐ  4(hU$ŻFŤŃĄK-ZÄwß}gđ÷˛÷¤zxxŕááńBs•-[–wß}÷µfÎÎoŞWŻnđA“łłłš¬îUˇŘń7 kkkÚ¶mK۶m ZÉëD!_ąĽČ^őĐ­áéé)^ýúő€8|ř°ŽlîÜą­ZµÇŹ€hҤ‰Á±ŞT©"4Ť‰‰•+W€Ř˝{·Ö1żýö›°µµ€Ţ—źźźČĘĘB«÷ooo!„©©©j›ŇGařđáÂČČČŕ<+V¬Đ:~ćĚ™}űöŐŰÇĂĂC\»ví™×4%%Eo˙:uę!„ŽŽ€ptt48†˘{ff¦Ú6~üxĺË—‹±cÇ @cccuŽš5kŠääd­±’““Ĺ| W'KKK±eË!„/^Ô{L—.]„BܸqCÂŢŢ^Gß5kÖ%Jčí_ż~}ťëvýúu///qňäIaii)aff¦ö311űöíÓę%ôÎŁŃhÄ/żü˘÷zöěŮS",,Ěŕ5ÄĹĹ)ú¤›€ `°üŚú]€ć€;P( Xć€)`Ě““y=±!FOćŻőÜ_„¬¬,ááá‘«]‘HŢ6;r جV €ź€ď€/€>@G 1Ppě€Ů FŻŔŽ“˝Ú"âââ â’äĘ… „‘‘‘;wnA«"‘<==;rX¬–s€)Ŕ(`ĐlŁ>Ppl  Č;˘y;ň¦Ľä†ŹB„’jüYáN 6ÄĹĹ…ŁGŹŁ#˙űďżą|ů2Mš41X°8!!ľ}űrďŢ=:uęÄ–-[‹‹ăرcL0€M›6±sçNJ–,Ixx8?ţř#ť:u"<<ś•+WćŞëćÍ› $++‹ożý–Çüˇ>ůüěłĎ´2R*¬\ą’+VđÉ'źµk×X°`%J”P÷3=‹˘E‹ÎŚ3hŐŞáááŻ,ĚwŢĽyĚť;—uëÖ‘””DLL qţüyťTîÇgŐŞU”*UŠ   bbbضm]»v%)) ???âăă©PˇááájĐž={žëj8d—µxď˝÷xđŕ~ř!ÁÁÁÄÇÇłcÇÜÜÜ8uę]şt!++K§ott4íŰ·§wďŢÄĆĆ’””Ä˙ű_jŐŞEFF_}ő•Öń}űöĺć͛ԫWŹ 6póćMöďßOďŢ˝B0lŘ0ťĚ¦đo}ş={ö<×µ–Ľ^4 S¦LáČ‘#ZűC%‰$ŻTŻ^ť?üYłféýť‘H$’Ľ ÔBBDDQQQŘŘŘP˛dÉgďďďŹB'Ő:ü›˝×ßßß`˙Ó§Os˙ţ},,,Xľ|9ľľľ”)S†FŤ©Ň5㪉‰ U«VUöôaiiIŐŞUźY^qşŰ¶mˤI“hÖ¬eĘ”ˇcÇŽ,Y˛„âĹ‹“śś¬·ĽĹăÇŹůúëŻY°`¸¸¸đÉ'źpŕŔŚŤŤ9~ü¸Nšô§Ńh4T­Z•rĺĘP˘D ŞV­Š‹‹K®ýňĘ©S§X˝z5={öÄÜÜś2eĘđĺ—_޵ŰÎś9Ł{őęU–.]Љ‰ ű÷ďÇßß:wîĚĆŤquu%++‹­[·R¤HŞV­Şî±¶¶¦jŐŞ8(Ś3€˛rĺJ<==)UŞíÚµăČ‘#”,Y’ĐĐP­ýĂ ×®]ŁE‹,\¸˛eËbjjŠŹŹŹę$ź;wŽŚŚ ű˝QBtůĺşwďNąrĺđňňbŢĽy+VŚÇŹkťż‚tP /íÚµŁE‹Ěś9ł U‘H$o(ăÇŹçĆŤ2žD"ya¤ZHPÁĽ&‹Pö4éČÖŻ_Ź‘‘Ý»w7ŘżFŤüůçźěßż_ŻC¬8)))yŇÇü1ţů'K–,Ń‘ŮŰŰckkkpžbĹŠ1zôhťvŐůÖç ç'U«VŐ»OÉ„šóĽ–,Y˘–S¨V­šÖńFFFLś8OOOµ(źĹÍ›7Ů»w/&&&üß˙ýźŽÜÎÎN­1i¨ĚŽľý¬Ęध§«jjjŞZË2))IëxâăăIHHŔËËKgśťťątéŇ+I&‘HŢNd’¤B‚R/ŻjÝşu©\ą2'NśŕÚµkjÖ»ż˙ţ›+W®ŕĺ奮vęŁlٲ:ňŚŚ Îť;Çž={žş›Wô%ĘIJJâřńălܸ‘ččh}=<<°łłÓ+ëÜą3k×®}agîUQ«V-˝íććć:m—.]0IągĎž/•LE)^ąreśśśôÓşuk&L@dd¤^ąľ„Uú’QYYYQ·n]BBBčÚµ+}úôá> ~ýú¨µőˇ<üx™š’ׇŤŤ 666­†D"yqvv.h$ÉŚ\A-$ÄĹĹŮuĽňŠľUÄśŮ{źEff&K–,aŕŔÔŻ_źâĹ‹S·n]FŽÉŁGŹžGý\‰‹‹cňäÉřűűăęęŞf`[´hQ®ĺ,r ĂU~ü®]»öĘô|r{đ4WŻ^0č<ľ,ĘřąÝ(sÇÄĨ«ˇ –––ąf]|š   üüüxřđ!óçϧqăĆŘŘŘĐŁGNś8a°_É’%±˛˛âŃŁGo}}^‰D"‘H$‰6ŇA-$(µ•°ÉĽ /ĚwÆ áçç—kß;wîжm[Č’%KŹŹ§oßľ,_ľśđđp˝!˘/‘#G¨[·.ß~ű-6lŔĆƆѣGłuëVâăă ®@ą&XP®×ó8TŻç©÷š––€©©ékŃEqöórÝ”,i9yŢÚµ•+WfăĆŤDDD0räH*W®ĚÇٸq#žžž´lŮŇŕ*©˘ăłęmJ$‰D"‘HŢ.do!A)¶}ůňĺ<÷©]»6U«VĺĚ™3\ąr…GŹqĺĘĽ˝˝źYô~ćĚ™ěÝ»WWWV¬XAăĆŤµ”çuV 1pŕ@nÝşEďŢ˝™”kah|ř÷ş9;;ż2GŮŮŮ™iÓ¦1mÚ4âăăY¶l3fĚ`ßľ}Ś;–eË–iĎ(^Ľx?`H$‰D"‘.äňE!A }´WQó’˝Wa÷îÝŚ=šwŢyGÇ!}{;cbb§H‘"Ě1CÇ9}üř1±±±ű‡„„\S˛÷V­ZőĄőHNNÖYQ8{öě+ţÝ_Ľ˙~˝ň_ý• *Đ­[·_ŮŰa0ôy×®]ZşĽ(ÇŽcôčŃĚź?_«˝téŇŚ3FM˛sęÔ)ťľĘ^Y塌D")x.^ĽXŕ[&$É›Kff&ÁÁÁ:‰%’A:¨…ŕß›÷Ľ’ÓA]ż~=ĆĆĆĎ ďHLL4(‹ŚŚdÝşuĎĄ‡>že¤-ZÄíŰ· ĘSSSůá‡tÚŹ9ÂúőëŃh4 <řĄtTVđîŢ˝«Sö$++ë•f3íŰ·/FFFé}ˇ”öhܸzć6 IDAT±ŽLźóü4eË–ĄcÇŽdff޵lsŻÖQíßż˙óŞŻĹÇ ŕË/żäÎť;:re?¬ľ•`ĺ3®/–D")ţřăš7oÎăÇŹ Z‰DňbllĚ!CřöŰo ZÉ˙ŇA-$8::Rąre’’’ž+»iµjŐ¨Ył&çĎźçęŐ«x{{穎ŞâMž<™­[·ňđáCbbbXşt)Ť7Včś?žĚĚLµź˛g0<<ś‡ćşg¶J•*ŘÚÚ’––Ć!C&--ŤđđpFŚÁ#Ôcő­TÚÚÚ˛`Á>úč#:Dhh(´iÓ†¬¬,zôčAŤ5ňvˇ `kk«&9r$6lŕŃŁGüý÷ßtîÜ™°°0µéËR»vmz÷îMzz:Mš4aĹŠ\˝z•Ť7ҡCÎź?Ź……C‡Uű({F/\¸@rrň3÷(Oš4 ŤFĂĘ•+éŮł'ŕúőëѰaCîŢ˝K˝zőr-A”<==)Y˛$ééétéŇ…]»vqăĆ <Čwß}Çś9sô®+Îk«V­^J‰DňęřřăŹILLdîÜą­ŠD"yC1bżüň‹ŚĆĽ4ŇA-D´lŮxń0_Č[x/@@@DDDŕë닥Ą%ŽŽŽ|üńÇxyyń×_°qăF¬¬¬HMM M›6pöěY,--i×®ťÁ9LLLX˛d &&&lŢĽ™ĆŤcffFőęŐ™?>|÷Ýw@öębŹ=´úOť:~ýőWš7oŽ»»;#FŚ %%???–.]ú\×ÉsćĚÁŘŘłgĎâďďOńâĹ©S§ÇŹ篿ţ˘|ůňŻd€ ŕďďĎť;wčׯ®®®ôčŃ;vP˘D –-[¦µŻ¶}űöh4Ž9BńâĹu®ŃÓxxx°iÓ&¬­­Yż~=-Z´ B… ôęŐ‹ččhš5kĆÖ­[_zʱĄĄ%Ë–-ĂĚĚŚŁGŹŇ®];śśśđňňbҤI¤§§3xđ`  ÓWů|KU")ů„Ĺ‹Dóć͵d]»vĄFŤzë~ţůç4mÚ€ čČWŻ^Mrr2îîîj[™2egÎś9?~śÄÄDęÔ©CëÖ­éÜą3óçĎgÓ¦MXYY©+yĺĘ•căĆŤlذ¨¨(Z´hdg¦Ý·o ť`©k×®ś;wŽyóćF±bŨ[·.˝ző˘ZµjÜ»wŹ””Ž?NýúőlçááAµjŐčŰ·/kÖ¬áČ‘#\şt‰ÚµkÓĽysşwďţ\NVË–-Ů·oźŢŐeBCC™7oáááXZZҸqcüüü¨\ą2‹-âÁZgűöí‹———Açµ}űöěŰ·OgőµD‰Ń«W/8ŔŮłg±±±ˇfÍš|úé§”+WNëřĘ•+łnÝ:6oŢLll,Mš4˛KµěŰ·Ź"EŠčĚݵkWęŐ«Çşuë8sć ±±±Ô¬YOOOúô飾— eĘ”aßľ}6ű÷ďGˇ5_çÎť‰ŚŚdáÂ…„……˝˝=•*U⣏>RĂÖs’ČÎť;iŐŞ•şgV"‘†Ęś9sřé§ź4iRA«#‘HŢ0LMMůâ‹/;v,ß|óM®•$’ÜĐäeoŰŰŚć_/¨%đ—§§'ÁÁÁŻmľ^˝z±mŰ6nܸ­­ík›G")fĚÁ×_ÍÉ“'ŐŻ‹[·n)ÉÇŇm@¤É@pHî=ů7x<?9>Č˛Ä Ě'vD,ňĺ—_ľđą˝©¤¦¦rěŘ1¬­­©S§Ź=âČ‘#>|KKK4hŔ;C“a:))‰J—.MµjŐHJJbóćÍDFFęěSŹŽŽ&88XŤň¨]»6Mš4ÁĘĘĘ ^III>|ŕŕ`ěěěđňňÂÝÝťÄÄDΞ=KٲeŐŐ>|%JPŻ^=RSSůăŹ?8tčS§NĄhѢę¸/^ääÉ“\ľ|™ÇŹăŕŕ€———އ7111\˝zWWW¸xń"‡"""wwwZ¶l©fgŹŤŤUpYZZâííÍ;C÷Üî߿ϖ-[¸víÉÉɸ¸¸Đşuk ćüüüŘąs'ĎĚ˙60kÖ,†p8M¶=I%ŰŽ<ä_;˘ŘĹŽ<$ŰΤ>éŁŘń’vĸ XĹĹĹ˝•ÉćnܸADDUŞTˇ\ąrÄÄÄpŕŔBCC©Zµ*Ť5˘Zµj:ý®^˝JLL µjŐÂÎÎŽ+W®D­ZµčŇĄ‹zś‚S§N•+W¨\ą2µk×Ö©vđ4×®]ăСC\¸p:uęТE Ę–-ËĺË—‰ŤŤĹÝÝ]]dŤŤĺňĺËTŞT GGGbcc ˘xńâ 8P3++‹ýű÷sńâE"""(^Ľ8NNNtéŇ{{{BBBHJJ˘I“&!8věGŹ%##C-˙¦<Ś>}ú4ÁÁÁDFFâě쌿żżÁĎShh( ** *UŞD×®])Q˘„α 8::âííͶmŰ ^Ż·‰FŤqüřq€CŔ-˛mÂc˛mÄCţ˝QîGɶ-ŹČ¶5ŠÉ2!ŰäëIä7J=DůŇ˙"ű¦R´„§§§xť\ľ|Y)S¦ĽÖy$’ü&##C899‰îÝ»çË|qqqd;™›€ `°üŚú]€ć€;P( Xć€)`Ě“z/ňzbCŚžĚ-óĺ6˘˘˘ š7o.._ľ,Ę—/ŻĽGęëťwŢ·nÝŇęwěŘ1^˝z‰ČČHQ˛dI2eʨÇdee‰éÓ§ SSSť1Ë—//Ž9˘W§Ó§O ť>{öě€čŰ·ŻzüÝ»w ęÖ­+îßż/ŞU«¦öIJJBńčŃ#1lŘ0add¤3. |||DjjŞ–3fĚ€={¶>}şNGGG-ţüóOaii©#;v¬Îą­\ąRX[[ëkll,ľúę+˝×c۶măĆŤËÓ{úżN`` rÝ®µŔ `đđđĐč4ŞN€=P0#;bÍčŘc˛ofE\\\A\’gęÔ© ,K–,Ńű=űż˙ű?‘••ĄŐočС[·n‹/VŹ>|¸zĚť;wDçÎťő~o;wî,îŢ˝«W§3fččQ´hQ±mŰ61hĐ ť;wŞÇĎ›7ObÚ´i⯿ţ&&&;vTŹ Ť7Ö«‹™™™?ľŽ 4€ŚŚŢŢŢ:ýŢ{ď=‘žž.ľüňKY‰%ÄŃŁGµĆKOOďż˙ľĐh4:ÇŰŰŰkťSNúôé#ţě7ô-ŔÓÓSąnőŔj`)0Ś=Čö7ęUŔ°Š<±#š—±#oĘK†ř2\]]0`sçÎ嫯ľzeµ*%’‚fÓ¦MÜĽyS†J¸yó&^^^¤¤¤0zôhÜÝÝ9{ö,‹-âčŃŁĽóÎ;„……i­F|OOOµOXXÍš5#99™-Zŕďą9Ű·ogńâĹĘo˝dffŇ«W/ÂĂĂ)W®M›6UCŕÇŽËĎ?˙LńâĹéŇĄ ^^^‘˝š±nÝ:¶mŰĆŹ?ţ¨7ŰöÂ… ąvíS¦LˇYłfěÜą“ păĆ Ţyçâââčر#C† áöíŰĚź?źŁGŹŔŔŐr^'Nś`Ŕ€dddĐąsgÚ´iC±bĹŘłgAAAĚ1† ęä-PVžvďŢÍřńăźë}•Hň“Ő«WsäČ<<ŁiÓ¦ÄĹűlŮ2şuë–k˝ö+W®0eʲ˛˛pww§m۶¤¤¤Đ±cG®_żNĺĘ•ńńńˇaÆDFF˛{÷nöďßĎ!ChŢĽąŢd‘ť;wFÁşuë°µµeĹŠ¬YłFÝ2ËřńăiÝş5{÷îeţüůÜşu‹‘#Grřđauś±cÇňź˙ükkküýýiÖ¬QQQlٲ…Ó§OóŢ{ďqůňeťżśväU•”Ľe´‡\Ř_äó ŞBÜĽyS››‹U«V˝öą$’üÂÓÓS|üńÇů6ź\A-|(+¨€°±±çĎź×’_ĽxQ”)SF]ITPVPQ®\9©ŐďĆŤÂĚĚLbýúőZ˛ŚŚ ńŢ{ď @xyyiÉzô衮*dddhÉFŤĄÎ©oĹŠÁÁÁ:çioo/˝‘0#GŽ€hŐŞ•V»˛‚ +V”5nÜXK– Š)"±iÓ&µý«Żľ€đööÖѡ]»v|đŽ,##Cšš uEřmF® >”T@´k×N¤¤¤hÉ.\¨®`ĆÄĨíĘ ŞňťONNÖę7{öl­%‹ŽŽV#>,X ¶ß»wOŤhزe‹Vź„„áîî®Î©o•'Q#÷ďß×ę»{÷n5ÚáĘ•+Z˛´´4Q±bEĹ‹kÉ”TsssqďŢ=˝2@Ěš5KK¶téRue633SmW˘K~ůĺ­ăoÝşĄÚťíŰ·‹§ €đőőŐ‘˝ŤČÔçÉ,ľ…rĺʱeËą˙Gň?CJJ }űö}Ąue%o6C† ŃyňďććĆ7ß|ü[ři–/_N… ´ÚćĎźĎăÇŹńööÖÉtmllĚ´iÓ055ĺŔś˙üsť>J饻wďęłD‰:çł\Sż~ý´dÖÖÖx{{ëŚčŻ7zŰűöí Ŕőë×Ő%###ĽĽĽtú„……Ú%·râŕŕ fŔľxń"ťôCAÓ¦Mu˛gXXXäZF ţ- –ccc¦L™Â”)StDEE1kÖ¬\ÇěСĹŠÓjË™ \_ c}µškÖ¬ d‡ O0UV©R%|}}ŐěďOŁdŘŽ‹‹ËUW‰¤ qww§zőęze}ô]Ëýi<==±°°ĐjKNNVę*×§Ř—k×®©Ą÷”î†lO—.]t~ĺ¤J•*z«Ô­[—©S§ę¤*‘H$’|ĹŘŘŠ+ę•ŮŘب« O{wvvÖŮ— ŮŮ9˝7J ŠL322ň™} ĘŚŚŚ¨T©’AůÝ»wůý÷ß™8q"ÝşuŁB… ¸¸¸d°@ńâĹ_J®đő×_Ó¦MRRR?~ŔÎÎŽÖ­[3sćL’’’ ö+Q˘ĄK—&++‹Ű·oçy>‰DA:¨‰D"ÉWĚĚĚrM§„Ö>kčĆ111ČýĆKé{˙ţ}­±s룯„‚‚™™™^g˛¸ąąáăăĂ÷ßϡC‡¨]»6“'OfţüůÇ|•XXX°k×.BCCéßż?E‹%44”ŮłgSŁF |}}9wîśŢľĘµJNNÎ]%’ÁŇŇŇ Ě ývDq¶žĺĽ˛#ąŮŠÜô4$ËĚĚdôčŃT«VŤ?üŔŔ@âăăéÖ­żüň ď˝÷^®zľ*š5kFDD6l iÓ¦$''łgĎľúę+śśś;v¬N¤‹‚rn)))ů˘«ä é J$‰$_yôč˙üóŹ^YVV–şďÉÉÉ)Oă)+™7nÜ0xŚâŞě_UVXS’ËĺfCôí÷•Hň‚tP%‰D’ď=z”>ř@ÝĂuűöm>úč#¶mۆ‘‘“'OÎóXľľľ4hĐ€ű÷ďÓ˛eKőć(33“Í›7ÓżFŹ­î!ł´´TK@ 0€íŰ·«+©ÁÁÁtëÖŤ"EŠčd·Ě %{îš5k´2>zôQŁFńŰoż†ËCĽ*”¬ĹÓ¦MÓZş|ů2ź}ö‰‰‰”,YR§ÔĎÝ»wIHHŔŃŃQ§Ľ…DRŘ9r$+W®$-- !§Oź¦Yłf/uëÖĹÜÜśÔÔT†®>üKOOçŕÁjhŻľlćŠ Ö'“Hň‚tP%‰D’ŻŘÚÚňţűďłzőjJ–,Iąrĺ(UŞżţú+ĆĆĆR»víçséŇĄTŞT‰Ó§OSĄJ°±±ÁĎĎŹĐ˝{w†ŞŐçÓO?ĹÇLJ¤¤$:uę„­­-ĄK—¦qăĆT¬X‘#FP˛dÉ<ëńÁPµjU’““©U«•+W¦nÝşŘŰŰ3{öl¦L™‚••ŃŃŃxzzrôčŃç:ĎĽ2}út,--ąxń"uęÔˇT©R888ŕććĆşuëÔńśáÇđoFdyc))ětěŘ'''úöí‹••öööÔŻ_ź+W®ŕččČŻżţŞóůÎ 777ćĚ™C‘"E9s&ÖÖÖT¬XćĚ™™™ ,ĐÉŢ˝hŃ" ĆŮŮ'''¬¬¬řꫯ>>„„„0jÔ(&OžL™2e %!!€ĆŤ3nÜ8şté˘3¦©©)ăĆŤcܸqzĂž»víʸqă¨WŻžÚćââÂß˙ÍŔ©X±" ÄÇÇăââÂ|ŔąsçhÝşµÎX»wďČ·,ˇÉ‹âęęʉ'8p NNNÜżWWWúőëÇéÓ§qww×:ľC‡Ś7NŤ.Đǧź~ĘŃŁGéÖ­NNN\ż~'''şwďNpp0 ĐéS«V-Îś9C˙ţýqvvćÖ­[Ô«WŹE‹1jÔ(ő;ž3YP ~ßš6mĘđööĆ‚łgĎbiiÉ7ß|ĂŮłgůá‡čÚµ+YYYś8qBí7pŕ@ĆŤ§·–‡‡ăĆŤ3Xłő»ďľcܸqZ!»ź~ú);vě U«VŘŰŰ«e{jÖ¬ÉäÉ“9uę”ެČ{öěˇ\ąrzëVK$yAŁoä_4ŤćÉ[yzzľĐľ$‰D’żÜşu‹˛eˤۀ H’$ŕ>Ü{ňo"đx<~r|d‰4OěX äË/ż|ás{S‰ŽŽĆŮŮ™RĄJݶgdd(H=žâ2H;"‘Ľ ddd¦üYěHˇF:¨y'¸öřńcBCC Z‰Dň Nś8ˇü÷~Aęń! Ą›D")ÄäÁާ^ůÁ)vD"y ĺńăǧ1rR IDATÉ€ľ°‡ü´o ŇA}>äÍĄDň†pňäIĺż9o,ĹS˙>Íëţˇ8¤_˝z•„„„×8ŤD"yY¸ző*d‡ĺ%ćĺć懳z´lÜ˙łwŢŃ–Őţ63 Q`ČA@’HfČ CPPQő‰Šx*` ¨u»Ďé>§O¸w~ßZ˝î=Ő•:íŞ]µk—b@i2ČU$?Ňżóµâ*µ×śzę©Ěť;·ßuB0uęT&Ožśţ|&ů úf3Ýj^nswN9ĺ”.d/„¨‹SN9wxˇµcÍdEłgť\0yňd¦NťÚ…ě…u0wî\N=őÔôgvTÚsţoÖ™ď‚ZŤ_Ź_ýőśp ý®‹"‡yóćqŔ¤&5Ź/3Ľ1Č;ň: ÝhŽ8ꨣ¸ë®»ş˝˘Sîşë.Ž:ę¨ôgŞćɢs˝PRďΚ9s&póćÉďŠČ 'śZ:Ěʉ’7PŢŹe‡Ôň8aôă €ŁŹ>š)S¦ô·FBaśtŇI\uŐUf+oĄśrÚËÎĺ߀3Őąb0ÉäzB`ćĚ™qÄzčˇiPÚ ¤ÄŤBё׹¬ŁQČćńEŕ‰«ŻľšI“&q÷Ýw×˝˘Sîľűn&MšÄŐW_ a+őЧĆň¤ŮŕÔ+Gž!(©zčˇqÄ©B-„č3gťu;î¸cúM>ÂĐ W‘őVž )ęŹĚHA­Fú’\óä“O˛ďľű˛÷Ţ{3mÚ´>WMů—+®¸‚M6Ů„ăŽ;Žąsç:Á$ďqĘ)¤qăţíNp–đ1ŕ©+®¸‚Ť7ŢN8A[X Ń'ć̙à 'śŔĆoĚW\A9˝ŕu3Ż397sĚËüÍĘ’”nÉ“żÇĎť;wŢqÇÇ&›l’Ö]ѦM›ĆŢ{ďÍľűîË“O> đ4p[r:6áÍĘŚX~Ä3©óť’j‰Ń33‚2ż0Xü7AY]ŘĚXk­µŘ|óÍŮ|óÍ™0aB˙*,Ä(ÇÝąçž{¸á†¸á†xć™Ô/7hěHÎ"t:_!ěŤúRáź*ŁŮµ ÝhâőlŮ:>EŘoůn‚ Y‚ Ľ.B! Ň|ĐKŃ9Eßč¬Ě‘'K˛r¤ŰNňÖærä!B'÷f‚ YśĐĎP_$+G@rD:ÉóôťµÂČ“!©l)’#Ů|G=RP«‘ç$!m˛¦?3RFÓY’4­5BT#vF’ýNÓŮÓŮ„o3>ň”ÔôűÎć×ŃěiN]c“źX‰žAPFS9b™tó(ž É!Ú!OŽÄËě2t†45ÁË誵céîžĚ˘ĆqŮŢlÇw&ůr$˝¦±tIŽQŤ<Ăő…ôŰLĺG*KŇA®XAÍŰzfÔ#µ9ŤBž‚šľp©ůoVđg;Ëc)nÔ Ńyy潩YMzu.Ó<şU×T9Cľr:ގYŽ2éR™“te—€dťíPfżÓl;źĘěß<9’öşŮ±ĚšÉ‘¬¬HĺZşt •/2ů˘âľHŃ`y¶/’§¤*¨óy/HA­Jâ6~Ă;–ŮÎevöc3“†ŚëťůČ“wi_d&ŤKڞ×3‹Ću¨ÍĚ|…í1/ó7¶pČΠľĚĐ`WÖŁh ę|Ôęä)¨ DG*ŕăÖ<UŤ‚őP´n,6ńM;—±‚;Ię–IMÖ|ŘhčŠeHĽţ-ë()OŽ!:#ŻŤĎΠĆćy©’š×±¬ÝŮZÁ’Łt5OŽÄ%©ÓĆě Ş,1„¨ŹfŽł]i$•!ÍfPĄ Š| …´s9›Ću`ń Ϋ u,ÓAŁ–BÔKŃĚG¶QČ*©=ošt.Sů1‹F‡H±yá‚4*¨é,*ČC:HŹRYUPÓŮŹ<92+·Ű\)Er$íSÄViýÓľ,1„¨ź<ë†ŘÄ7kŤ‘·Ž}ľ^ RPŰ%öĚŤ Blr“*§Ůµc±9p^Ă †B|b!Ż?Ť…¬™oިĆ|sgO»| q2>—UPłËXŽ tI†QL39’·}Kv‹™™™żŮí!ú)CŚár$ŢŢ"5ďm6X.9"D9Šdäo•·MUv »fO¤ V šý€á¦zď–>uZ7šA˘>bßxj¶9+ó{NćÖ tqÄ2[ßxëĽ%©ršur"„čŚěŕP3%5{¤çzұŚÖłg;Ăs ®#vÂŻ?•‰Żőtĺ É‘Â}”ç§ŮS‚Ú qÇrŤ/SĽţ4»f¬Őš5B”ĂŁ˙ăo0«¤ĆĘjúŢĚiׄ¨s9Ź ˛˛$oí,†+§š=˘sĘ΢Ćűžg•ŇĽőëŻ}Ó]–#ń€ůśĚ˙©Ě*©cľD höT2DrÉ‘ĽYÔĽľH¬śÖľ~}¤!µ"9#—ńěGܨÍ&_1meŢ+„¨F‘‚šuRý;7Š“íÔu·˘Í•ÔĽ‘×"oáń¨’#B´Olž—×Á,’%± öfÖ#-3OŽdëÔ‚++C´ÍŚő’gć›§¨ÉaĘéü6{ `óá5×B´]Dě ët ď˙lĽ4=9˙ !Ză9óĚ}łÎ“ňF){eÚű‘‰eHVfä nĹń_!DyŠäH,C˛ťĚ<ŇSĺ4§/R$CâľHŃ2#É!Ú#¶č‚FŮšÇ˙geČ|­ś‚ÔŽhŇ0dÖx¦ŁŐڇ!ŞŃĘaR¶“˙ź»´— BÁ` —!±ŰlĆCrDňä}ď±|ČSXł˛ŁoťĘH†Ŕpů÷Cňś"©/"Dg´rää÷CâţČ|Żś‚ÔŽÉiň„~ÜP¤ń˛…őđyĘjŢ1”¸B1GI…FE5ţ›•’!BÔO,G˛ŠhŢßľv*Űč‹Äł¦’#BÔKl•‘§T_d‚Z-ŢHA˘;™ę……€> Ă’#BôX^¤˙ç |5&<9Rdľ+“^!şK[r¤ß2dP‚Z#LPC DżČSL# l˘¨ćýBtÉ!D'´”!0xr¤źHAíM”Ő†h]Żó'-ŰHh$G„č’!BNr¤HAí!% !DÍŚ–@2Dţ!9"„č„Ń"CzT!„B!„Á­Ł!„B!„ÝG ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B@ ŞB!„B`lż+ 3Űźüśéî“›Ä]Ř,4ŐÝďëbőÄŔĚŢš zÚÝŻďW}Ff¶°Q&čw¨_őB!„čćîý®ĚěA`µäç4w_©IÜ=żf‚ľěîßęfýÄŕcfăW2A—şűÎýŞĎhÂĚö~› ú¬»˙¸_őB!„č2ń`Ěl_3›™9®íwť„˘—ŮA‘<§ĽÖ‹ňzĄu*!„}Ů‚föh$gŮ:Ěwj”gŢńŠ™M7ł{Íě<3;ÚĚ6kťűke|&ĘďoťÔY 2ńlĆ e~/ŘŻŠ!:ĂĚnačľÇÝ÷čg}Fc©OZ”×@™ŮŕöLĐ­îľOżę#„/x'g)·?đ?仍r¶ńŔ`M`wŕkfv=p»_×"mÜ.Śk§˘bpŃ ŞBô†u3Çš}®‹,ŚĆ÷cőľÖF1?đŃ‚đŹ$ţ$úÁŔUfvPźĘ‚fPE»Ü |'óűš~UDů„ŰiüćţÝŻŠ!„ą$N÷v/8˝*°+đĎšŠű)pW6–0·6°-°XćÜŕD3{ÜÝĎŞ©b„!U´…»ß Ůďz1żŕî˙ţÓďz!„ń| ¦śOŁÂző)¨g»{a^‰˛ü]࿲ÁŔ÷Íěoî>ł¦z„L|…B!„Čš÷Î>LË„íefKő˘"îţ»8=:µ2°o/ę )¨B!„BĚŮvŔ:™  Üý1Ä…hśŃě‡OGa»ő¸b@‰ď('DďÖ–^®~çîÓŰĚw`ëLĐî>µBú1Ŕ6ŔŰ€ eE Âé ŕrŕ\w ÍúÁ\e ÂŢ®«Ë®˙©äx¸ ¸ĆÝ_ÍÉc=Â}K™ęîw´Q—%ť2AĎąűäśúľ+ô”»_ĺńA```ńä¦LsÎu÷yU땿 ° °%áy, Ľ <–·Lužě ś×%×±}twf®Ł”gU3[Ř.4ĹݧdÎŻ™”µ!ÁSáŔ“Ŕ'Ýýľ‚<߼•ŕÄhĺäX xžđnţ›đn^V¦žf¶=ÁK!4.nf{5Iú°»ßĺµ 01tł»ßߪQË;ŢÇŐe‘Ç Ďřŕŕę˛Ďa~ÄĚÖ"Č®í rui`áýúđw˙W‰|v$Ľ_ń`ńR-ŢŹÜý¦ůŹ&dáZ„wqaÂ7÷0p!pž»?Ó*ŻLžŃčäëRw>9gŔ›˝ ď׊„k»ŐÝ÷o’çR„ďî-Y=—Ôó>‚l¸ŘÝ_.[Ďś2"tv÷Lęż á›~¸8ËÝ_Lâ.ÄKiÇ%Ë[”đ­í–”7ŕz:đÁ|ňüôŢ•Ěs3†ö*¸0˝'É˝ß؇ˇ{˙CíÜYí¶÷™ňW"Ľ÷;+îáÂ{p.pą»Ďí ŚńIţé;»,ÁCëtÂłşpßžŞçę„ö-ĺFw¸BúÝ ß ŔLw?żdşeýŻ5ĎmU‚çÚ§×óˇ]˝ČÝď-[ź8 úý›Ěßâx=ŰkŰÝź1ł«hüö6­»3[Śđ\Ö&<“Ő}‘§z6S 2çö˘|D—qwz l˙®vMŕ’(}|ĚľŚMŇ<9÷X‹ü÷ŚňúR…ş˝ ”›ŐÍ ”ß«UČ{‚RrK‰üÓăশĽ¶‹â]×ćs<4Ęç»9qĆEq.OÂ-I˙r‹k¸XżÍúíÜPň^Í!tj·)Čk|˙’Ěu‘Üëfů_¬W˛Ţo‰Ň~# _8§IŁ|Ţś@PöËľ3·{–¨ăeňĚżĎÉkż(Îg*<ăeď3K–˙đÍveWťđů¨nçvףĽćULż>đ%ďáŐEßI&ż˛ß]|ü˘Eľă€­Vy˝ Ś/yNŽŇoš„oKčÔĺ•ńHA^‹_'(R­ę9=ą¦qm<÷]{[ä˙a{ 6Ůs“+”µAf?[âšž#řrX¨dŢżŤŇŻ•„oFP›•ő0J˙‘ŠuËÖiZÉűőý’ďuz<@‰6ĄÓ#ůć^Ě”ű,°pćüŤQ˝6nŁŚŁ<ŢZ!í±QÚ' âĹ;żDŢKäÍÓžË4ŕăÝ~.:ržWż+ ŁÉĂiSA%Ě>_ἄ0˛Űuřv…zĄÇ3´ččeň˙Vů;đ`A~±˘[IXłl§m°vNĽa jÖLŃŠŹ')©ÜeĘüy›÷ë°‚<‡)¨I9«÷Ŕ:%ę?LA6 Ě6ËË(źo¶yć_mQÇľ+¨„­'ۨĂÓ˝–yő•°FkvĹ{8řX“™˛_ÎkRŹZ¶mJĚD˙ČđM̧ž˙=I]^OxĆë›®M$Ů„Áµ,3IwŢłe€Ť ĘŮrŠ™Íp÷ßçdýOÂ30ťżB¸G×îËş„vg{`‚Â×ÎRŽ5’kZ9:uˇÝ˝0cşA–f—Čě\Ó›[]SÄöŔĎí„ďú–¤Ěô}ÜŽFo­ß2łËÝýş×´/Aa϶‘s ×y{rM Ěg·ŁŃôű«f6Çݿޢ ţJx®Yž&ČÁk 3~Ű&e¬’‰łaĎĚÍ˝Cóĺ:H–.ý‘F3ěy„vŕrÂŕës„6nŐäŘŠŢî‹]dŢ›rp»~R‹râÔô»{řtAšeŁßżŽňpŕD`ś´ă OqüŻ·¨ç†›8ßKÁRäÝHŰ9QşÉ-ĘÇđYëÇ€˙j’f_†›75«gř j*_ź Ŕ¬– üN‹ŇťWâ}Z—FSP'(öąVD%ůxĺř`‡Šß·Ö˛›%' 4Ä& śÓ˘ŚžĚ –/eËąXŁDţ;ż>QĄ^U‚lĎÖďž‚xŤâµěSDé;™AŤ-rż=*Ě Eqź6)Q—Í€“ha)ĄŁ;Gß+ ŁÉĂ©¨ 2\i|آEšeľćŔ©_A˝-Š9-:ő„ŃáŘTů+q—ŽâťVăsřq”÷GK¦[–FĄä ÖO1\AMŹh­d˙4JÓŞ±ŢśáĘ`é5ÄIc Âc5=ľSâ:N‰ŇüąEüXAMŹ/TĽ–e*Ć7†›,T"]ŻÔ Łřw3ĐQő÷ú`xö‚™Z;Ç—˘Ľš*¨„N÷#QšŻ•¬÷÷ŁtżjvŻŁ¸í(¨źŤň,_"Ýj4Â͡I§šá Şf&–¬ç–9é?ß"Ťda6Ílšř'ȉ -ľuB{g˘;ąEşř˝zXŞÄ˝X‡ĆAĽ™Ŕ MâÇ ŞfM[ ¬Ĺ÷|N‰4WEiN§… OŇýw”îĘ&q—b¸…S€1-ĘŘ?ç>Ľ­Iü^)¨_‹Ę٬J9Ý>ľśĺ¨‚xď‰âĺŕ7)§-•°7kü\‹ęXEAýX÷]ý~:JĽý®€Ž&§ş‚zA˙Ű%ËŮ)G(Ô¦ ćä?xcÉşĄ}„śŽ3Ád6^m‹Ú &YŮĽŻ)™î°˛Ď|ő2Î š¤]“Ć˙é-âź•svŤ÷*OA˝ŹN@Ł»ŮëxĽEü<őÚş®ĄEŮKÓčă’iz¦ Lłq_6ěĹ˝é½Λa©ëhĄ îű´čŘK®‹v÷—¦ë) Ě…»Án4®;ý»»ź[!ýI„µ©)o«v:a˝|K’­^Ţ[&­‡µ™'DÁqŰ’˛3ŤëV§ĚËđç;eًƵůgşűe҇0‹RĺŢ_âî˙(÷ĎŃčßű/yÉípť‹ÄůAXĎšĺsÉž–uqrô;Vbv˘Ń1H;űś]Z!î#Ńď"Ľ=Ťßý•55Íčä:&äĆĘç wż BüNÉ*¨‹+ ;FżŮ—ZŚ`’˝ň˛űÎ>OXQ…8ţvą±:gRôűâ*‰Ý}6Á±QĘ:É`Vţěĺ÷'ÝŚˇý$!ě-ý÷’i!luňRć÷*f–÷Ýmýţµ»ÇťÔ\’xżŞP§IŃďŞ÷~Ť ńĆÉŞeč–lŤĺÇ%ĘĆSČyďÍlqÂÚŔ”YTŘsÓÝŻ xe}-KÂŢęý$ŰYř^˛§î ĐĘ9RL|ţŁ”}™yö L˘ÜMXoü†;滑°lˇâţáńf¶`nL10 ʇ#:głč÷”Šé»˛±™-Ap¶ĄęLÎmŃď¸óA˘Śg=/.Ünf?7łIf{1­Ęź ćG)J6/"V`V±Ľ+0ÄťŹ%rc Wî«tpÚáYw˛u´×({yÜW!n.f¶@ňľaf§›Ů?Íě3űŹ™Ý”=ٞĽ®Óňë ™EX'ô Ăńś IDATÁän´0™ŕ‰Ľť#öÚŚ­hô~zU2;T…X®ľľbú˛Ä ŔmäŃn]sga ew,Ű›’Ě®Ĺßů°ö€áłUęÁ™RYęľ÷cî ¸*‹Ądk˘đg•ţ»Ýýń ĺŕîOĐ8#żzN´Íhě>\v–6CËľAŹą0úýqŕ.3;8ńňÜ’6á]™ ™g…¸űżhěG®mfŰĹŻ™Ó]+”:¸”`.śňŕ~3ű’™˝±¦2DÍh›™ŃClŇ7F­x¨®ŠD,OăČŘóîţBĹ<Ś~Ż+(…WdĘ[`fű ŕE3›Lp+~ľ»ßTĄî>ËĚ~Ip†ÁSçľŔiq\3[xw&čq‚ŮX¦VŚ˙bô»H!Ź;>7çĆŞŹ˛[ꤔ˝Ž<ŞvB_#Mý"a¸ZD/bÉvËŻ™řßîŐ¶®tf¸űí$l1¨w(·L&Rů’ýŰ,Ě3˙Ç&lu×ő×f6·Dݲ㵲u­ňÝĹßV;íÎC4ÎĽĺ}ݱI7ŰĂŐŁß +<*Ýűĺ˘<ĘŢű*íDYŮżK+T|ďÓż‹gňČĽ«ë]h–gOq÷‹ĚěLŕ}™ŕµŞO4ł»{c_Fč‡Ôµ…J+ţ‹ˇ­ 8R,Ó;Ť°S@Ę4.wŞ“§ ł©?u÷«ëĚŘÝo7łďÖ<§¬DX^p¬™=HPbŻ x¸ž–“Ťč1RPGKGż+5Čîţ¤™Í¤ŃüŞâzŐŃĺ6Ţî~•™}€°ž*nđ'l©đNÂ>pŹü´‚˛ú3ŕ†F}?IŽ‚Jp¬’m NMLčŞPvNUâŽ[·Ȳ¦uđp;‰ĚlEÂV>tXţ ¬AŤźńł}©ĹČ'ľŹ¨fržÇb¦/"®W§ď2”Żk™·ńŕcâ4qžĽńf©Ş –Ş—™-LŁ"Í×v–Ąě˝ď†|ŤßűĹéüšň®§WďBŻ90C™·fsÝäř$0×Ě®!lYurbęÝ-Şš÷¦śNđü›öyö1łŰŮ<‰áëşç–M!¶>cfźv÷ó뮏™m lżÇĚŢ•?‡š_ ؇jk´!lSóĎŠij%q8ůE3ű=Á3üŰÉźě0‚ď‰Ŕ§Íě îűA=@ ęč!ĺÉőâZD2Üéě@q˝Úq$łJôűąf‘ł™##“őďŢLpüw(Ć_ ((»—¨ËORP!Ś„śů;Gş°ČS^źx*ú=(f©ýâ`•Ó§€=ÜýşV Gžq=IJë‡TpđV@ĺA”V¸űŚČúe°>Á I'TY;^–n´y3Oç”Se†®ěú۸ě—ćǝʆJk>k&ľ¦żŃŘƵCŢýˉźkĘĽ uPyŔŔÝ/.IúV»»ú ›ää·pž™˝Ł˘÷í2ä97úxů@uu`p÷ýĚl,ˇ_řVÂsŮ‚á3«Ëż3łĹÝ˝ŞŃ!RPGq\UŘwËilBş˛™Ť)»UCBÜY(m–šlgs'ÁkŰX†ĺ{Ěp˛Łg»™Ů§Jˇó k®Ňu:2ł#2ć9ť:Gę6q§s<Ďö¬Ö<Â~m˙)бVęSń3n§ă'†ßÇ5Ű]űÚ¦3ô-Źw÷Ř“ę ËîŐÚČŁL{đDô»Şś+Ą şűl3{ŽĆ¦±î^uíý ż÷ëv齏ź[;ÄĘö bątß7±˛i{űšdćîÉ‘ú¨Řřa/Ë)fö¦şĚJ“mťâ­|:e{3[{„żăé¶U—$f¶$a‚áý„Yâ¬ĹńföĎ›lőČ‹ďč!öÚ[µSÚNGˇ ŹŃhÖ;†ň SâşUőP äîW»ű— Ž-ţEůp‰<ćѨtľŽ Ěňś#MË)ŁßÜýÎ۲gľŔĚ–¦q­Ţ” Ę) ®‚ú ŤßÜšmě'+†Ë™~{mF\×-űR‹ÖÄőlG))ÓÄßqŐouťÖQ^#^[7¨÷ľ,wѨЭmfÝđP?·vú eűńňť*Δ֤F˙î>ÝÝ˙ŕîď x€ÎÖmEŞyoĹ»h\—ű2ˇ}¨zÄŠ'[Î $îţĽ»źăîď'ô ˛\‹1|˙xŃe¤ Žn~‡,Ë;ë¬LJ˘ĐĹ[\”]ű˛Wô»co‰»Ó¸¦°¬c‘Si\חΚîOŁs¤_ ÷Ôx „w$٬ó#±ŇVzĆÉĚVˇú¬L¶#ҵ{žX'Äß×ęÜ@ă·ĺĚlýn”ȉ¬L©ş–.ާrRGę×Dż·IöJ‘¬§Ë*µłČ˙ncýŹ'4eĘKŁVÄ[uMŞvŕp÷§hÜ Îľ/jĺLĄŃňk‚™•Ţ'8QšwŠ‚ă÷+%Ţľ¦ĘţzâV"ńV{l\‡ł”X‘<ÚÝWŻz{Fů|ŘĚĹ)`í$–w‡EÁöŁ.ó3RPG7Ó8âł%•Îd&©“5 ­ÇˇBga7řĎŁâFčE$Î ˛nú—0ł–îýÝ}:đ§LĐvfö&Í{Í9RĘ­4îń7úM€F ±×Ä* ʎú¨zÖŰiéNy›śýţlŮoNĄ1^vR‹Ězˇ®ęŕo4ÎzíŰĂ= KăîŹĐ8Ë58¨BGDż/w÷<'`—,XRV#lµQ†Pmf7ŢBěŁfďK>ŇŻé¸d-eÝ\ý>ĽBÚ˙¦Ńňăď«{Oô{ŁÜXů|ˇBÜvđWŻ#Ódő­™ yŔÚĚîjŕĚĽG#ńséÖÖ˘)¨Ł„¤3őË(ř°’ł¨‘ďe®.~Ep»ž˛:%: f¶đĺ(řî^Ëž­f6ŽĆĆ`6-0eřIôű×4š‘ťďîí¸Íď*îîŔńQđwͬŞŮőh 6…ťXf6ŮĚ6˘„9xŮ÷vńdóônqŤVë_­ł3ŰĆĚŽĚÖ™˙€p,ŤŠß.fÖ-󶬼`fńö%…¸űí4Ja=Ű ZGü8úý™dýWSĚl=ŕ˝QđÉyq“ö0 üş™˝ˇEoľŃŞ.QY×ѨhŤ!Üű‘< t"Ť;¬Ő…râç÷N3k9SefK¶ Éňł&ľ-¦Ň¸u۶fÖŇŰĚŢěĐ*^‡ÄćäÓkĘ÷#4öń/s÷GŰÉ(é7śÇ[׌6â ęz.˘$RPG?˘±Ă˝=đ‡f#źfvÝix^#1úyüs3+ěä›Ů˘„×›3ÁóhÜ4:˙p3;ÎĚŞ] ,’ů}e"[âîWѸžsbeĐś#eůpGć÷ŇŔefVjťV˘ĽąuĚÁ&yÖŮ÷ĺ3Ł…$×}íÉÎŘÁB•™ŁJ$Ž9ţ' >ÚĚŽ(3hefK™Yěđ+fá{LŹ*ł#wż…á+df‡%\-1ł1fö^3keů‘}?ĆfŞđU;áë&ÖĄ0ł×›ŮĚ¬Š‰kUN#ř&HY¸ĘĚÖ(Ź™mL¦ŃjáV†Ďôeů.Ťűź®üËĚbłĐ´ŚIÓŕŐn]ŃŠ#iôĐĽ)Á+k鵬fö3;ŮĚúnŃ’´Ůߌ‚7łăͬô^ľf¶‹™]P´ŢÝ/®Ě&.nfękf«%i˛y>CÁ`ERÎ\†[•ź(şEĺěËđč¦Ůd3ű@ ±eŢ\^ĄĚ&ěýît«”8ýž]d­ 3;ŰĚ>iaK®2ń!|ÓYęz.˘,î®c@‚©‘gŽ—Hóé(ŤWo–Nâ,lMčiś ŰS¤żkQΞQ_j†ś/dŹ“ î×—Lâ­‘\÷râ~łIţéLÇ\‚ đ' f<ă˘xc ëiNĎÉŻŠĎçŔś<śĐ)S1ŻqQ—WL˙Í(ýÎ-âż‘0BžM3ř>ÁÉÇ™¸Ż#Y‚°ŢËĂ ňĺyIĹëřN”ţÍMâľ%ŠűŤ6ľ±ĺ<ż3 3Ž–ů^&˙KXłśľg×VĽç&éâoó»„Ů€3Ç.9é÷‹Ň~¦Äőť‘s}×'ßŘŇŃw±á[<… č<Ý"ď/EůŢWőţ—|FźŹĘ9·ĽŢĺ5ŻDš… ëQăűx{ňţl ,–‰oŔł}?'xEuŕĹĺl™SĆeŔq9ďÇŽyĽ?'ŹŮ„íqv%şZ&ţb„ĚC ťţyIšĎ7©çÉQţ›¶ńŢš)+=¦ÚŻŤ Šč‚É=9"yłqg”(g·äúž9Á±ŃŻ ëĚ~•üÎÖçcQšÉ%Ęúxνř6°3aÝcöŢ/A€=‚ KŇň?ޤŚßFůŻUážż!J{z‹řü%çšIŢÁ­€Ą˘4+–}Ź`š¦YˇI9kÖzÇmŃW Nü& n@h×§ĺÔiď׿MÎ;w7ÁÇĹŞÉő®NčŰü.çf‚śţžÖ¤Ś´MťNřNެoBră>ŃT`Ávĺ[&˙7çĽ‡Ż«!ß›Ł|.÷`ď­ť–ťSĆ!Qç7‰{gçyÂw˙nŕő9ń– ČôŁĽ§ËÔ} :Z<ă~W@G“‡Óž‚jSßX€§ óý‰đφĎ"46YˇR«‚š¤YŹ`ćXT·g ÎyŇ`Śm’÷±éfFëoOţĆ Bzü¨ŤçłaĆ:ÎëkmäŐS5IłS“{>‹°¦çą‚óŁBAMňůż‚k|…Đ™•sî6ďůŻ›ĽăŮă÷9iŰQPÇg7)çů仓sN ęPşĺ Ćš=łÇ |±B”MÔ¤ś?–|?~Ń$ŹŹ1\ĆÇďőŁ  Ę]UP“|f¸Â/7ą†™TLönňLňŽc ŞŮ°ó*\Sł˛^Nľ·—›Ä5Iłh‰wň) ̫Mâ*¨I9»7ą'ł®ŔfŹ#+ÜřÝŤËÉ»¶5ßvVFAŤŹ€űëŻóú Nhk'¶+ۢzü:Ęűěšň="Ę÷¦‚xŞ ć}Ź$ç‹úB3·×]­™řŽ2<|Ťź l*ďŃét„0».é)`Oëhş]·)·ęWćś6†ö’Ë2‹ ěçÍ=âmJ?–ŕş}ýäoüÎĎw÷Ď6É;w‰ĐaČ2—ákwż”đ<ňžý8B§Ľhmج‚đ‘Č'r·á^¤Ě>çîßił¬CJř+­"Ö‡ýy÷&.ç™-.Ař.ň>µzƱ9}Ç޵w‚0 ö-ŠźÝň„ýóĚű^e¸ł¸<$X1Ěl±w˙%aÝ\‘WęńŔJű¸ŹĆ%]ÁÝO" Âć­íZ„|O×÷»ą{l®Ů¬ś?›ÓúýśĽ×Ă6dńö%/äÄĎ+ë$Â{Rä¬gÂ÷¶HÁů©4:îë+îţ˛»ďK[E{Ś.Cpú¶`Îąy+€¦ňÎÝĎ'ě š··ć8Â`pĚłŔţîţífyGBÎ#6ŮźB°T¸żBţE}”Ĺ Šîş4:vJąŘÁÝăÝ*“¬]Ź×jwjŢ›’Zä¤lŐ©¬­‹dkŚŐňgAţÜçîOö¸ѸĄĐgÝ=ö>\6ݱ„{?0H0ˇw¤™˛3°$Î…Ö"ĽKKÚíi„kj{Ŕ"*c‚Yň˛%o:đ×č?‘ckľßg JĎ˝u}Éw7ˇ~Č"„A×iŔÔVa˘K$Ž—fčą,N°’xâîŁÉBlÄ"U6I¶fy€ˇ‘ä‡Ő“+!F-‰§ŃÓ“źłu+šÂ 1$ť×« ł,)[&łŇB!z€Ö  Ń>źĄŃĚéD)§b>!»UÇ©RNĹ(â4*§ŹRĽžW!D‚*DŮ Ŕ§2AĎ2|ŻW!F+éúÓW Űď1pŮÂe÷wNâoFŘÖ'Ë/j\(„˘RP…¨H˛éřht:r˛»żŘ§* Ń3/‘×ö‹=<ădMAcI`Ş™ýÓĚŢcfąkĚěufv<Á9ĘŠ™S'ö žB!2h Ş-0łwĽţˇó˛9Ťžn6©/„b4’ &>ž šCp„ó`ľ2ÁIÎň9É_!l11j·OBAEŰĚŃšő÷ś› ě#ĺT!ž±ŻË«·÷ađu»BB!†#_!Úg ˇsMż+"„bĎöżr{†Ţ ¬%ĺT!ú‡L|…h™MvO~Î!¬Kş¸\ű !Äŕ“ěńĽ)°aoÍe {xN®©sŹM!„í#U!„B!Ä@ _!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„T!„B!„ÁŘ~W`$`fKë&ÇzŔ*Ŕâ9Ç‚ýŞŁB!„bDăŔ+Ŕ‹Ńńpp0¸ĎÝçô«’ÝĆÜ˝ßu(Ěl °9°srl,ß×J !„B!D`6pp-p1p‰»?Úß*Ő‡TŔĚVŢ ěL–ěk…„B!„˘¸XrT]–98řŤ»ßXoőşĎ|§ šŮ/ű|3ć·wS #wSÝý•nÖS!„B!kĎÔÎ:ÉßM€•K$żř9đ‹‘˘żĚ7 Ş™m|x7`Ńć7—&ÇĺîţBoj(„B!„ĺ0łµť~s&ŃÜoÎSŔ€ąűóÝŻ]űŚzŐ̶ŽvoízŕtŕLw˘'B!„BšHôžý€÷ ˘=üř®»?׫şUaÔ*¨f¶paŤiŢŚéĂŔiŔéî~W/ë&„B!„ÝŔĚĆ»"XŹŽË‰688ÍL!u j˛M̧cČ÷Ć{/đ-¢a95B!„BŚJĚěőŔŔŔB9Q®>íî7÷´bMU Ş™m ü†°wiĚťŔ±Ŕî>·§B!„B>af+‡ź"x Î28 8b&đFŤ‚jfď!(§‹F§žţř‰S!„B!ÄüŠ™­|Ř'çôŔŢî>˝·µjd~^fö?ŔźhTN8XÇÝ$ĺT!„B1?ăűľŔ® Ó,;×›Yž5jĎŃ3¨f6ř5aOÓ,÷r÷k{^)!„B!„pgJ‡ßĆdN˝ |ŘÝ˙Ň—zŤT5™ž>Ř<:u1°Ź»?ŰűZ !„B!ÄČÁĚŢ ś Ľ.ěŔ×€czíĺwD*¨f¶A9]!:őCŕ î>§÷µB!„B‘‡™­ü°ntę,`wĄWuqkPÍl?ŕ2•ÓŮŔ'Ýý`)§B!„BQwź l\ťÚ¸ŇĚVíU]F”‚jf‡żĄqźéŔ®îţ‹ţÔJ!„B!F6îţ<đ‚—ß,›×™Ů꽨Ç1ń5ł·§Q©ľx—»?Đ—J !„B!Ä(ĂĚö~, ľŘÖÝ_ęjŮ#AA5łő€k%3Áöëö B!„Bů 3Ű8X.|đžn:Nx_3[а`7«ś^FđÔ+ĺT!„B!jĆÝŻŢ ĚĚďEŘ–¦k ô Ş™ŤÎŢ’ ľŘŇÝźęO­„¨†™ýxSΩ=uĹĚ^lMŘĆiE` `q:Ôú—»^Cő„™˝ řqΩsÜý˝®ŹBz0ł§GÁďw÷3»QŢŘndZ#'Шśľě)ĺTŚ06#({1÷ý™Ů[€Ă]»ýĚÖQ„#%€sÂďčuE„BÔ‡»˙ÎĚ6ŽČ˙ĘĚîv÷×]ŢŔuSĚěcŔ!™ '¬9˝­OUŞ„™­@°ŃÎă«î~QMĺŚ.ĆDů†»ź[GYIy‹ĺśú˝»źTW9˘·ŮBŔ÷˙îw]ÄčÂĚŢŐ‡˘Oq÷SúP®B1ů2Á"pŹä÷xŕŻf¶…»?^gA© šŮöŔÉQđWÝýŻý¨O;¸űăf¶Á<2f ŘŘľÉů=ZT3[ŘĄŕôńu”!úĆiŔűú] 1*Y–°ŻZŻ9że !„Łwźgf˙Ep\»~Ľ đ3ŰÉÝ_­«¬s’df˦ѥńÜýŘ>U©&„OޱŚŐĄS&„o”x'®I-ÎŻ›×A‘2|»»OŻ© ŃCĚl‚ÉFł€{fęW&X´:šÍč !„BŠ»ß ěĚÉŇ̶««Ś2ń5łe‚žör÷}ŞR§L.7ŕÍ„˝\ŰĆĚĆŰ–ş#P‡—­"ur y‹ţ°;°FNř3Ŕî~_Ő ÍlÉÖ±„B!ÄHÄÝ/1łĂď%AüÄĚ6s÷9M’–b`ÔÄŮOĽîôKîţH?ęSî>ŐĚVĘ9=‰T`"ů‹ňĘęHA5ł7Ëśľ´“ĽE_١ ü„v”S!*rZóľ©‹y‹|¦“˙LŻéuE„Btť˙"č#3¤´¶ÍŔ(¨ŔçZp p=0<0^| 'ĽŐÚŃ2äĺń,›w«,ĐúӑΖáżëi-Ä|‰/« IDAT»ďßď:úp÷{€ýű]!„Ý'qšô‚Ó$K‚żnfgşűŁťä=kPÍliŕ2Aó€Ď¸űĽ>U©N&„olfŻë0ď<Ąń§@ěEëŤfV4űY–Iá·şűÓć-úÇj9aLëuE„B!ÄČÁÝ˙ü2´đ•Nó•0ś5UýĄ»_߯ĘÔL‘ůë„u¨mafcČwFsđŻśđNgQµţtt’ç¬ëiwźŐóš!„B‘Ć—ś)5łĽm6KÓwŐĚ'(¨)ł€cúTťÚq÷»Ç Nw˘4n,…˝JfżĽÎ˛Ěl] Č°ÖźŽlňfń_îy-„B!ÄĂÝź~ ZřB'yö]Aţ›ĆYśÓÜýá~U¦KL.źÔAžyiŻK6ÉÍSPë. ‚)h^Ybä0¦ßB!„#š“€2żL–p¶E_ť$™Y¬aϾݧęt“É/W1›Ů’îţ|yćͦΊ®&ÜËěó]ßĚ–msżŇIá7»ű3çZbf‹;[</, ĚžLŽ ÝýćvË© 3[ x'đz‚gć•% [˛<Óé˘pQŤdK›] ű´.GxŹ&fÓwč>ŕźî~Gżę)Ff6‘ żVV%X™Ľ< <\\– ö˘>äÓę„ý—%Ȧǒă&ŕoŁŐ|?ńł°°&CĎÄ ĎăIŕ*ŕ|w˘ÇőšělLx&é1ŕőx:087q2%„#wÎĚ~|9 Z řpT»öí x·őĚqZ?ëÓĹë\;şÎě±GůŤžĎÉk—LśërÎż·Íú?VP÷ď·™ß{€‹ &ÉE÷%>~¬ZÓ39™sĽ'ç^°¶wn‹:nYPÖ5ń_×á5lJčç]Ç‹Ŕ~™¸ÇÄ+ş–Ľ¸ńqXA˝Ö-Čóüšžť%Ďä2`v…wčA‚Kôĺ;(űÔ‚{±y›ů}­ÉýýI›y®LčüĆůýŁŽűßF}>RôLúQź‚:^Yđ ‹â-BX’rsÉwî%ŕ;Ŕ’]Ş÷X őIͰŢĺłDÁő_X±>[äsbĹ|>WĎţ9qwÎ.) ćçvů}ź<—kiÝndŹ©ç"‹ôű›ĐˇC‡ŽŞa‚ौL›Śk'Ż~›řîý>ľ/µč2Ţ|ę¤6˛Ü„СČ2›Ć˝ćj1ó5łuŁńy\Z1Ż-Íě ŕĎ„™‡+$_ 8¸ËĚţ7™}턱ŔB9ÇkßD2cz1p:đVZ›Ä[‹óµaf»žńŞ ż†9Ŕľî~z&ɸśx 5)"/n|ôÜ<ŘĚv$8;ťŕd¬ŠČjĺâ3űJbÁQ•+Čż»¶‘„÷ŞčţîŢfž»ÖÄů]Ůf~óEĎŕ5Ěl}Âög'•ĚwQŕpÂ;·Kmµ őŮř7paP¨ ˇ7›ŮŁsy×_EFC‘yůŚ«O‘|~MćŮ"fö+‚Âąĺdľ«›Ěě[ëÔ:sł1fö1ŕnÂsŮŠjK©Öţ¸Ų̋»~BŃM<¬EÍî…=6ű2}SPÍl9Bç,ĺ?î~kżęÓ&„Oj#ŻĽ4×»ű+™ßu­Cݱ |^AąŮ§ tžçá*Ś'Ś0_gf«vW!f¶+a–¤čús“u©:Ť…}ř;ŤžŻSžvt÷ózQ—^bf_"|G[DmĹb„Nŕ•‰ŞÂĹá••ŹÄAÜM˘¬nfkVÍ·I]Šę.Z`fű”Óő[Ĺ-`đ3{gMőy?AţnŘf‹§›ŮOͬßŐ•1łµ Uű·™ĹŔ‘föóş®?Yk5™°űĘf·đK3űEâ±_!F żŤ~Ç“‘ĄčgĂô~G<ÓŻŠôÉá›Y<ÚŠ<Ąé˛č÷•%2ËúÉz*L*żÉÝź+“™}ř1őľoëW%łµbfëLĆŞŢ«®Ofv4ÁĚ4o¶ŕ.`wż±Űőč%88¶ć¬7'(©k”MŕîyëĶ7łf3ŇyěHëYźvfÝňŇ<ŚŞ÷˘WŮŰ#‹tŐBŔ媓úĽ—ШCqůŤ{<‰"x>đ¦˛űđůN3IdČŐt>óqŕś6­=„˘ç¸űµ4ö“ölCĎé«“¤¬F=ř}ż*Ň#ŠĚaÇ;˙(“I2Ú»CΩŐÝź5łŰh4E3B§řĎeĘJT>ąLb3;”ć 9g"î'tW$4öű«¤]¸ÄĚ6ôöś?ĺ±půł“7˙ÇŽ7–Mę¶a&Łk3¨f6řPdöu°§;­şŚüú’ö"A nEŻö*>†Ć­¨bfĚüÎî'Ě"/Nx‡&”m“´6áÚŘÝ_(s1°V6Ř–jfďe”Ď]_”Í0Ů*oöf˛»Ď-›ŹxŤu3>řtAIş™°Ćf&AlĽ‹b“Ű…_ŮNž,Ř©‚™mžÔ§¨íž üřp;AV-@x˙7öŢĄ? )ÖKc3 ޞ<\D0Áś°ß’‡Q»;Q¬Đcfç¸ű˝íT(±äą†ŕ ­[ĎĺĘLýƞ˖çVEÖ{Ö ŘNý„˘üŽŕëB»÷^Ęő+‡čÓ"ÚUht đ÷~/ěíŃu?Bľc„ă*ä±iNúŮDÎ<’¸'ĺÄ=©BYkÔ×)á܉Đ!jćg2°f‹<"xe-Ęçě6žĹ1y=so ¬Ň"ż-• Îuä$‰ ,ź×äú˙,Üć;™—ßľçµ9I¶! b]űąE÷=“ÇXŕČďâŻ*Ôiź‚<ţ·âµÝҤ>éń$`ňütA>uňL;|>Rt}ýŞSNŻ/¨ăýŃď»¶ČËkĎ6y®ďhŁŽăhîśéJ`ýůl#“ŠęzYĹ:nSĎÉó9´äóxř"°P‹ü6"8,*şwżió˝›Ü÷˘|ŻmőľdňÚ…0PP”×{Ú©Ł:tôú`¸ţPYĎë—‰ďNŃďżôĄ˝grAř¤ yěöow)'ĽÓu¨EqçFŞ 1łqG6EfŹ?vr÷űšĺăîóÜý‡„u‡EŰěefi–OVËü˙$°•»ĆÝiQĎy¶1łϱh‘ů‰‡H3ë.»ßŮ"Ó˙˘™Ź˙u÷··şďî>ÇÝżMé.2KßßĚŢU˛j—nLisÜdíëQđ†×oYĘ;äiV­?mŹŐ3˙źBđÔ}Qł8ť0SůbA´Ź¶Q—#(~~ĽŮKlĄäî·¬Sţ” ~]őé«gţżŘĚÝOđ[ů¸ű-„o㪂({·c‚| Wňř6°}«÷%ĹÝ/&(ř˙,ň‹dÝşB 4¶Ěş%´CŐőôý2ńŤÔKúR‹Ţ3™°=FĚff¶¸»uf˛LĘ ‹×ź¦ä)‘Ů2îţt›eAXÚjďÖ}űľĺńŕO†YĘŕîw&žk/#nĹcfżs÷9eólÁ3gCSjĘŻ2föFÂĚéësN;p¨»Ż·µę)ű3Ü”6ĺ‡î^iíś»ßhfo'(kăs˘ üµD>O™ŮÍoÚY¶0ł%Ľś©đÎ 7ąľŽ`ţ·wž:ějJbţ?)çÔăe—~`fÝ2[üŹ»_Wc~?w÷OUIŕî7ŮQŔ÷sNżÓĚ–r÷gËä• ÖZpú|ŕ#îűhV·ą‰ßĺްG”żŇűp»űËfö!ŕ‚ÉY–EßÝŻĘć—ř*8˛ŕô×ÜýëeóĘÔńĄd ě_ w€µ4aMjŢű$„ĆĹ Ş.Ađűńݞ‰AA}ŔÝčS=zÍä‚đ1„í¦žWÍĚ(±ţ4ĹÝź0ł»h\e„ÉŮ­*K±ŰKK¤=¨ üQŕÓU”ÓwżŮĚľü(çôŞŔ» ëGëŕó}VNw (KKĺś~ř»×u­Ęg §RÜYoŠ»_cfÇLĽcÖ7ł·¸ű…%˛şá ę‚‚ř%ŇçÍt^ Lc¸‚ş aËŠVlJčÄćĺ;¨ü¤Ků~‡ đ×Áť„}9ŰáG„™Ďx ô‚„e”Ěç}äĚÍ$ČÓĘë‹Ý}–™}Š0Ę]u~2ř`ĺ4ĹÝď7łS ¦đ1;PAA%ç­ë˙k;ĘiŠ»Ď4ł÷žKÜGűś™ý°ĆX!„čÓč„ng*(¨=7ńMĽÝ­ž š_fOÓ)ď"sÄI%˛ŘáĐy4ßß°-3_3{ĹΉ&·H;Řşŕôaîţr«ň›đSŕ¶‚sív"c®r÷ľy•6ł} ŽŁň”Óg·Śvĺ4Ůć獧q÷Ydlçî­î˙h čşŰÝĎď$ăd˝îɧw7ł<Î1—hĹ´ě<&tńÖ6/׺űÝŔCŃąE)đÉR¤ Î7€]ŕ~J}·`rAx<źK˛5Ř–§«ĚřQÚKô€đÓ_OřŢbÖ7łKć±?ů2ú÷­ü*T ĎRň­¨„b H|ădgLcýŻ)ýPP׋~Ďo{óM.߬„„I9aEëOSňfP7Lö’kF‘yďżK¬±+z ĎhÇ-‡łf®UĘ.ËLť‡ô3[ ŮëóňÍĆţCŘăôÎŢÖ¬o=ÇÓkĘ˙÷ ß'‚™n‘2đ‰@ž éú%IňÉËÝ=Uxóf<›ÎĚ&ëĽ=ďq÷[ÔGó·*k; (Z?Ľ\Éô Âoq÷ŰۨO‰Ó¤›:ͧG<áaŹ˝¶IžgžÎXň­Vň(jë´ląČkk‹ś2 !Ä qCć˙ĹÍlĄ˛ űˇ f×CÎ%ě}9?Q4c<–& O˛ţ4Ď™ESŐÝf¸9cQ^Y&„7ťńNöë,ęP•ÚëµîţůŠ7t® ŢâîŻtG%’MŘϢxŻĎ :§ő®Vý#™ÁŚ=ܦü˝Ž2Ďż˙.8]f¶ŠMgwn‘®hýiJž×ĎV¦ĂŰ˝Ähö´3ŠäLŠ–u”ő[´?fť–EŢmŤ:ž„-ßňhůLgdŰćśšMţ·ŰÉ`nŢţ–I„bĐą+ú]´Gř0ú=ú@‡kÉF6/j'5Iş°Lśĺ:)•ÖˇšŮš§CyLnQÖ›&‰yÔ9J_”WËŮŻôtFßĚ–!('ď)ň+žłyŰŤV6'k™9@Ç3FţSľUÉôE jˇ™o2Đ”§Ŕf;¶yJĺV-LŹGäúSw·.EŢU«7®•IÖˇć z•UP‹Ľˇ×)Ooie čřy$Y•y&Ä»§ ý™ÇsÂĆ3r¶BĚßLŤ~ÇV´…ôÔ‹oŇ9[;TWc3ŇLŘČ=¦Čl¨čÜ­%=^|¸Ă˛ (Í2Ápo•)Ź”ÜÚ¦,EťłN× ¶íp¤ Ö ¬7]§ŕü×Ýýk˝«ÎŔPô §´Úď°"EďPŃ;s-a-[< Ól¶s†›v>EFAp÷ÇÍě6g‘ǬÎ-Č7ŻLG3¨ťR´onU^ař wĽŐIńŔdJť[őÍcyEę|y”y&E3łÍl˙ä˙ě2 kÖę|‘9Ü2„­Đ„bi{µ×Ű̬FăţRP™hf‹Ě–ĺ)Ť­Öź6‹·Q“}ř&äsc‰˝Z‹Fvk‘®*Efsy[1TˇĚ–uq1ůkžćţ?{÷ćFuőqü{Ö ŰÔĐ{'ÔÄtšé$$„„$”ĐBBg)†$` „˛ô $`B'„ŞB7f„Ţ{Ť1¶ĎűÇ­F»3ZiW«‘´żĎóčYéÎhćX+kućŢ{®»˙­Ž±4’´ßa­ßCiÇ«¨wÂÝż6łű€-»lZÔĚ–Ť u•”HŢ•°ěŇťtćĽ j4w=iäŔÝýĂäčĄBőüšrţ©T,©ř¤W2†kr•VúíOI•ŢEDQ<׫d? űµ†ëde|Jűč ŰţçîTqľJ %%µAeóO!=Á«t}ąJ )ł­ëűFueJűŔ˝f–67µŐĄ˝‡ĘýÎ{#í=YMˇ“‰@ŇÜęŤ*m®I÷ĎŔW’ÖMچŇ?ÜĄ9­ŔRR‚ú5µ«x*ŮJ»0“VŚ®7Ô#WązOŤifń\ŻâµŢ´]{Fdjd<éóPGFë,ôeţiAŇ—Őo›ŮśŃ˛-ŁSž˙p—ҤőJŐşę`Úń>ŻŃZ«őđkŕ=ŕ€„m‹’ÔMŁu ’¬ßC÷Ôş»›ŮÝŔŹşlú0ŠŇĄlzZ^¦«;čľlŇ&ŔU…f6°JÂs' °ĘĎ­,í˙CĄU€+ˇŞ°•K›Ż{>pzťbxŁNçé«x®Wń…Őz'¨â[”6źsaŤµŰcmµHPź&ôôÄ+B¶ë7őp.¨lx/Ô/ąHfUëa ýÉÝý@3›ŚIŘ>?0ŢĚ6s÷´%QZQÚď°ÖCëj5×őNş'¨†ůö” –[7ńNŕw ÇŚŰäá~ŢŰ:’ ŮAň´ŹŢęZYZŇĄ%¨łş{łTC©—^%¨őâŰu.Í€˝Â ëK» :şpÇĚ–'yRqUĂ÷˘‰ĘIk¦Ćϵ8axi’J $Aú—űĄŁe†jeŮ”öf)öŃÉÝŹ¤{"R07p—™­SDz–ö;Lűť÷VÚęŢ$¨I:R3N÷ŢĐž–y€îs—ě2?YóO[_ZµéoŐđ]+FKş´u©şF!"ŇâąŢ JëÄÔ;Aízľ®K+ 4ăSÚG§Ü/xŢÝ»Vĺ­DOóPÓzOżîŻđiKÍ ,Sá1*±jJ{S^Áv÷ăCR6Ď ÜffiU—[MÚďpˇ”"A˝5ŞĘó'Š–“IşŘ´ž™ćą®týP~˛Ü“ô)/Ű×3‘VĄ5C=ĚCÝ0Zf$é‹CŻÔ¨şmŇPÝ ÍlQ míÍJ矤͏ÝĘĚćNŮVŤťSÚ'SZ”¦)ąűĹŔĎH^.gp­™%ĺi%iďˇícŁ úâ)íďÓ»aâisI71łą€Őş´Wş LŇ26ó.Đ(AÜ}*p]ĘćýjpŠjpŚć_)í»YÚ:â""R!%¨ŮźŇ>šäŢÓ—ÝýÍ>ś/męč”ý§˙©ňWĽđűŕ¨*ŹUÂĚ~“˛ůbwŻĺâő™q÷«€I˙ž!Ŕ•f–´LQ«¸ä}6ŇçęVÄĚ–&ôR'ůkÔ[wx&aÓšŔvt˙¬}¨’e`˘X’’ßÍHNP?&$µŇZţ’Ňľµ™mŃŰšŮöhxoo\ $Í _çXDDZŽÔěĄőN®|/ˇ˝·Ă{ ’ÔUmSöČÝż¬ćŃşŞ—¦lŢ7ŞLÜ[§Đ}ą"ó6ĎîĂqŽ»ßHř˝$˝ţ€‹ÍlŹúFUQ—ÖktDÔăß[gŇ˝`„„řÜ>7©çr0Éš+™Z&yi»Ł!ŇBÜýnŇ Đťß›˙f¶pNź ˘š §Ąlţ…™í]ĎxDDZŤÔěŤOiJrŇŘ×őş'ĘăJz/żŞô îţ镱»R‚Ú˘Üýŕ’”ÍËO™Ůˇf–4Â3›=şĐ÷_Jk<\»Hw˙؉ä‚vC€+ĚěěrżŹžŮ3ŰĘĚňŔ“@+Oëé48ë_lÓ ˙Ä˝îîŻÖŕ|÷U°ßWô­*î‘ŔŔŠ ŰV&F=Zs÷nޢĺ6Ž%}I€vw±q6s· űđö÷EĂZnJs÷ŰÍěP҇űîKň{ˇ6ĂS= Á7łĹ5#¨¶%¬-"2 (Am ă©,AíëđŢ‚Jއ<Uěwźjf;za“†cŽ~ofŹ/ďľh-HHJ“ćŮĹ]ĺîîmŚÍÄÝ7łŃ¤Í;&JRʍodýÇÝ'Eďˇ[YvIčY˙™M^!|ឍđZřF§ůKT”Şî¤çµ7˝śwŇs‚ÚŚ˝§Ij©Ďë„6w˙ŘĚ6"ü-H«; ˇ0×vr&aÚD·‹;­§Űw?=Z“8mĎŔŃí“čoÝűŔ'„×wöhźy#CjQé^D¤©)Am ă+ÜŻV ę„?ŚC{Řo|_OäîOŮú„cá”݌𥾧/ö]ý™ôŠľ-ÉÝź6ł ÉHRa”ĂÍl8p`oŞŃ6"w˙OÔ{|3É˝Çz‰Ö‰nŐ8ŮÝÓ†ýöĆť„/˘ĺTS ©ŕ.ÂśnëáÜŇâÜýŐ(I˝ Xş‡úŘŮÝď4ł´˙Wźőář†»`fOj/”ű»:Şš,"Ň#ÍAm=ĚCŤ«I‚Uĺ}¤‚]{5˙4á|Oß­đś•ĺîű ÄŠĄîţaßË)»ěüĹĚZć˙·»? ¬ †¨žDŢ^Η„÷ţFŔşŃgrÔp÷5v"y]äŢř°üŐÚîţÝSD¤ˇioă8Źň_0^¨ńů.Ł|OĎ;î^n{Ő˘/ć—šŮ5„â[–P™·ÜӀǀ˙®s÷‰5 ç.’«/ţŻFÇŹű+asW˝žß a­P3Űřé›V&”9Ě1t6šT-¸IĹšú|ĹÝgŮĺŔ÷ ďˇ-I˙‚ ažÝŠďˇ§űGN$ýĐm}8îE¤' ˙íĂqűŰD’ßő´G˙Îý-”ˬ IDATieŁSÚ­g­ĚÝ?CC¦ED*˘9¨"""TTŮĚć7łs Ë IŘe:éĂ~EDDúťŞřŠ4—9€1Ŕ3{ ¸°ÖďŁIËr™Ů<ŔúŔćŔ.Ŕđ2Ç>ĆÝË­ť,""ŇŻ” Š4ŻŐ˘f6řĚFXosÖ Źu Ąk•‹ÔťT‘Ö1"şUëŕ×ŃÚÔ"""™ŃT‘ëŕ7îľ—»OĎ:ő Š4Ź#ÇíC{­—Çy8řł»O®Ql"""}¦UDD¤I¸űłŔqŔqŃr3kD·ĺ€Ą€Ĺ sOGŞô~ |L—ú:p0ŢÝź©ô"""=S‚*""Ň„Üý3ŕÎč&""Ň4UDDDDDD‚TiJPEDDDDD¤!(A‘† UDDDDDD‚TiJPEDDDDD¤!(A‘† UDDDDDD‚Tił@DjÇ̆sóźłE›>/ÜÜ}FFቔĄU¤ÁŮ0`Y`)`vB’żÍšĐ60?0˛‚ăIHVż –¸–ą}AHv_^p÷Żjó/)ĄU$#f¶°<đÍčV¸żý;ü~xt›ŻĎťifŻĎĎF?źžu÷wkˇ HJPEú‘™Í,Cr":{?źľĐ ĹžWëă1Ű=»K[Ĺ7Ů$WŕEwźÚÇóŠČ U¤F̬ X ŘŘXXśŢő†~<|DeĂp?~ =˙+w/I€ÍĚC€“†÷t›XłLĚłkF·¸™föđ4pp0ŃÝgVúbČŔ U¤—˘„oeBBş°!帮¦/Ó˝×ń9w˙ ńlVn»»;a>éŔ;Ő?:Ç|”önK’ţyŇm_ČEmźŮxB˛z·»?Ý›xDDDD¤µ(A©‚™-KHH IéĽ<íCş$ Ńíew˙şźBíîţ>đ>p_Ľ=ŞĽ4݇1;áPs?nŮ{ŔÝ„„ő.w©źţ """"ŇŔ” Š”af‹Qš.ŇĂS&QĆúˇ7ôă~ ˛D‰öłŃ­„™ÍMHX×$ĽŽŇ}ţíüŔO˘fö:Ą ë›ýĽ4 %¨"1QOŕV„ˇ¨zË™ÜO”HŹjťŃRîţá5ş8ĂĚ«SLü×#TŽ[ Ř%şaf/Ö›€ąűôúD/""""ő¤U0ł5ť =xó”Ůuđ Ĺ„ô!wźÖ˙¶Ž(źÝN4łˇŔ:Öµˇ]ž¶ltŰ xßĚ®ţîîŹŐ-péwJPeŔ2łEźÓĺSv›÷DDDD”ľ¨IK0ł!föKÂ:śWRÚŁa}ŇżŁ%Ýý·îţ\}Ł”ţâîϸű` ``đy—ÝÖ$Ľ7ž1łÝ˘%…DDDD¤(A•¦ffĂŁy‰/Đec›§ć•ţXŔÝ÷p÷{ÜÝ3UęŔÝgşű]îľ°ax÷­„jĚË/šŮľf6KˇŠH%¨Ň”Ělv3;x8 X4¶y p°„»oíîWąű—„)r÷)î~ą»oIčY=“đŢ(X 8xŐĚ3łŮ2SDDDDb” JS1łąÍěXÂ<Ň?ÖÄ,µ-áîi]L)p÷7Ýý@B˘z"á˝R0?a©š×Ěě3űF!ŠJPĄIŮBfv*!1ý0glóGŔďĹÝýHw˙ ‹ĄńE…•Ć‹GÇ6ϵ˝ff'›ŮYÄ("""2)A•†ffKšŮź—‘±Íďí„Äô8w˙4‹Ąů¸ű§î~,!Q= x/¶yVBőçWĚě3[<‹EDDD"%¨ŇĚl~3»xŘŰüđB5ŢSÝ}r1Jós÷/ÜýÂĐßý(]¦fŕ×Ŕ fvA´îŞô#%¨ŇPĚl™í <ě Žm~ř%°¬»źëîS3QZ»Ou÷?K{ŞB öž3ł_iU‘ţŁ/ZŇ0ĚlmŕaBeŐ9b›ž$,ł‚»_äî_gź´>w˙ÚÝ˙ |ř9đżŘ湀ó€ͬë:»""""RJP%sQeŢó€Uc›Ţvľ-33“eŔq÷î~°2a-Őwc›×&DóSçL<€ôŠTÉŚ»†óî X´i:Đ,ďîW»»gŁ l\NčQ= mj#ĚO}ÎĚvÎ*>‘VŁU2afŁ€űżsÇ6Ý Śr÷CÝý‹L‚éÂÝ'ąűŔŔ±Mó›Ů˝f¶r6щ´%¨RWf6»™ť <|'¶é}`gwßĐÝźÎ&:‘ňÜ}"đ]BŹ˙G±M돛Y‡™ÍšIp""""-@ ŞÔŤ™íDλ?0(jž ś|ÓÝ/É*6‘JEĂ~ …”ţ † ž5ł˛ŠODDD¤™)A•~gf+Ů]ŔeŔ±M€5Ý}_w˙4›čDzÇÝ?r÷=u‰±M W›Ůmf¶l6щ4'%¨ŇŻĚl—÷ŤbÍ{ë¸űc™&R#îţanęŔ¤Ř¦Í€'ÍěW™&"""Ň„” Jż0ł9ÍěZŕL`hÔěŔ…„áĽç«:Ż´ŠhYšł€ĺ+b›†ç™ŮUf6{6щ4%¨Rsf¶đ8đXółŔzîľ»»Md"ýËÝßq÷ť€M€—b›~ ćéLi0îţ°:py¬yqŕ>3;ÄĚ,›ČDDDD‹Té3›Č'ŁćÉŔ®îľ›»OÉ,8‘äî_¸űĎ€˝€/Łć!@pSôJDDDd@S‚*U3łők›~/Öüˇ×ôâl˘iî~°6ˇ˛uÁÖ„!żëe•HcP‚*‹†ôŽĆ‹Ä6ýŤ0ßô™Li2îţ$°ˇÂuÁ"ŔÝf6FC~EDDd R‚*1łˇ„ůs'˘ć/€_¸űîţeę“E¤wźěî;ż$TĽ†0\ţ`ś™ N}˛H‹R‚*=2łY óMkţ/amÓKł‰J¤5¸űEŔZ„Ę×;×›Ůl˘ɆT)ËĚćî6‹5_¬íîĎe•Hk‰*^Ż ü3ÖĽ5p‡™}#›¨DDDDęO ޤ2ł%€ćĘśüĚݧf“H«Š*_˙řK¬ů;„ĄhI~–HkQ‚*‰Ělŕ~`ąXóQî~€»{Fa Q1Ş…2:·ˇ ąűLw˙pl¬yEŕ?f¶BFa‰ÔŤTéĆĚÖî IŇ `Ow?!»¨ŽčŔŮfv¸™ ©Ç9Íl)3»Ř´ç“ňÜýh`_`fÔ´(ˇ'uťě˘éJPĄ„™mÜĚ5M~äîÍ.ŞéŔ‰ŔÍě{ýµě™}ĂĚţ@(Đł pMśGŞçîç?¦EMswšŮVŮE%"""Ňż” J'3ŰťP¤e–¨é3` wż>»¨¬ë Ż˙ňŔ˙/D=ŞóŐâŕf¶ľ™] Ľ  ®q÷/jq|© wżšP,©đ{ÜhfżČ.*‘ţŁU0ł#żR\ăô]`wż7»¨®¨Ő•±¦Ą =ŞošYŢĚ5łu*lf‹šŮŽfv–™=CÂý3BbZpQ­â—Úq÷;€ŃŔQÓ`ŕb3;$ł DDDDú‰‚ࢡŁgűÇš_6w÷W˛‰J"〽»´ !ô¨m=ţŇĚţ|ĚŰo°™ĺy€E€…{8×+„¤U»?jfë†ß/Đafó‡«p™´ %¨XÔűv1až[ÁcŔVîţ~6QI»?hfĎß,łŰp`ő„öA“ŘJ\¬$§±ąű fö]ŕV`•¨ůP`>3ŰĂݧgťHmhďefmŔe”&§wŁ•ś6”qu8‡.THs÷w€ €űbÍ»—G˙§EDDDššľĐ \g;Ä_Cč9ý<Łx$Ů%—é/ăÝýŐ~>‡Ô» lÜkŢ8+›DDDDjG ędfż~kşŘŃݧĄ±¦5šŮŚB’”3 ¸’Ňäôb`ÉĽÓˇäTd`É;Żĺť]€Q„ Ł.Şź‘3öÍ.2i6JP[Ś™µ—ć˙îîÎŮĆŐŕ“€kkpi`î~>đűXÓŔEff)O©ÖqŔ¶ŃýŔAyg׼wΑ(ďf\ B‘ćqpUěńŃŃşČ"˝’3§ĹšÎČ;dŹ4´ÝGŁűsGg‹4 %¨-"* s Ĺ Š÷»{=«`I˝ŚëĂs_p÷űk4>wź ě <5 .7łů˛‹JšÜŔŠŃý7(˝0*"Ň)š‹ľˇ Ŕž9cą C’& µŮ Šy٦źşűô좒ţâîŃű5Q5yr÷iŔO(_¸4šł.R­öŘýŁóNŹEdŕĘ;Ź—ESú"ŇŤľś´†±„Éč®PíâîoeŹôżq˝xÎL°o€ÜýUÂşt›GfŤ4«ś±2°LôđEtŃKD*36v»ś)‘tł@úĆĚ6§ôKf‡»ßśU’e(U(Ä9¶ íţbŤŽ»ĄUŰ×ţÝÓ“rĆ0Br?"Ö|1ĹaÓ=9Ř)ş˙(4F‚J((yit˙%`™ľ,Jxo–OŘüOÂký qçl‹4$ ńmf68Źâďk"᪫îţ6áJ|’qu EšŰA„Ď;΋¦4Ĺ)^t˙_–T¬Ý?Ţ-]Ă#ßCé\żu+|ކ”&§[äŚJ‡üÇWHű›Ô ."99xŞž´*%¨Íá@ŠĂuľ~Í)—Đö)a)‘Eź)?§řĹvUŕ×ŮE$R•bŐŢTëO‰~ÖlŢw´üO|ôCĄ j|]íÂZ± ŁzzbÎXŠŇu-[2AÍ ›Ćš&‡kŁ‹Â"5ˇ!ľ ÎĚ! ›)8ÝÝźÎ*iX7_R\ŕJwźšQ<Ň„Üýi3;đ… ŕ83ű‡»ż[îy"ŤÎ& |Źâ:®µ4ŃGM{°ŽŰwëE÷ż›3,ďxĎ)$¨3 sŇ=Ţ xĽ‡çĆ{O'˙©"Öf˛xěţ×Ŕ–y/ľ›3¨oH"­G jă;Ý86ĂX¤AąűWfö°N¬y\FáHsKřbş0ĐAčYiJ6qčľŔá„÷tťăQŕp5íÎţ:G•îĎ |x6mçś±8°Bôđ ŕjJÔžŠ¦ĹÔń•ejBńőŤ®É©Ô†Ôff[PZ~ţwźśU<™ë°‘Ŕ‚„!GsSĂ!Q­ŕšťąîŇÇB‚:bo]¶ ŇaßĎ:®&âŔ‡„…Äߥ}`ţ_s÷Éfv P(Âö33ű«»ŹĎ0,‘^±‰CN'|ß™Lí ( Ö"Tâ=‹ŇęąYzř-zĽ.eTJ‡÷ŢÝf棯“3ćĚ;ź–yţ±ű-9Ľ722v˙“̢iqJP”™ ţkşŮÝŻKŰżeuŘj„$ýŻîJ‚®n‘…)­"(Őę°§sxŻˇÝźČ:śzr÷šŮ­„%gÎ1łQîţuąç‰4 _ľëüř®ŹšöY­O`‡®@ču\Ń&ÝŘGM»«Öç¨VŢ™ž3ĆŰDMë+ó”x‚z{Ţů,gLľCxý6ĄxŃŞDÎXX2ÖT6AÍC •†W"ü]o#\üđDOC‘sĆ\„Ńďçť)Q⍣xßţ•÷ÎTËółĆš>%Ě. ź'¶mhÎX"öř“ĽÓ«÷WÎ…đZ¬H(Ŕ4x¸7ďe{ľĄXÁ˙ĂhţqÚľsR\B諼óN™}Sq03ďĽ^éżE¤” 6®Ă)–Bź ě—a,ő×a çć ‰daĺčö[:ěf`/ÚÔ’=ű*R#|i:89ÓDŞ·fôó˛ţHN|Ô´glâĐńŔfŃů2OP#wPš &ĘC€M˘‡S U€n%$|†ů¦-mď=}#-ˇĘm„%kţ©ó4_ĘżÍ;W¦Ĺ üŽđy°}Îx–Đă;lźŻsĆ!yçě2ÇéßúŔ-{Iź!Ľ.K“Üóľ đJ—¸ŽŻô|Ń9‡ľßýžbŇÝuź'€#ňÎż6_FXFÂçóáeNw!áb?ŔG9cŢ2¶%,™đ0a”€HݨŠo2łĄ€1±¦Üýĺ¬â©»Űx%§Ň8ľ<˝7w8)Öô{3[4«xDz©0dJŮ˝ú®ćŐxkŕŽŘýĺrĆĽ)ű­Kq(đ˝yçËč~Ľ'tKŇő¸ĽLÎX@čĹ-WDhi੶qa”Ľőd8a˝Őů»´Ę{ýrĆşŔÍ“Ó˙–ëe쫜±á"੤$§‘o·äŚ–üą!v RäŚA„悹)_ťyëŘ}­ u§µ1ť ĚÝŇkŃa Ňa7Šű”ű°ÉÂŔ8:ě&:lÁ¬©“?…‹c# EŰD¤ äť˙oÇšľ›˛k<ůĽ5vĹy– ĺŚo§<żěüÓś1_tÜŐcÍ׿ óý.ˇ1Ţóşđ—”óĹEq Ů)±c|HH8{”3Ö!ôś†ö> l”w>żL(őSÂČ®‚Wbí?®­ä|Ń9—ŤÎą\¬yđÂßŃŔ!@|ÔÎB»¸c÷żť3Ňţ6­E÷ďU'í%Áń%¨RwâŰ`Ěěű”~0ě; Ö<í°ĹÓs•ĹO€÷€(®Ó&R mŔĽ„«űs–Ů/L ĂÖŁÝ_«Kdq÷©f¶?Źš¶7ł-Ý=i¨™4ž; ‰ „žŇöILPóÎŚśq'đٍi+Â\ŰN9c~B…`“ă˝¶§KE÷§űç˝[ňů@ÎG†şCÔ¶[θ=ď\‘üOÂôö.‹ćŁ. ,™wzś3ź3Ö"ü› =Č–Žéžw>0ä8gŚöŠ6}ÜĂPär. 8źős`·Ľw©x¸'g\ť»Lţ6gÜ‘wîŤb{!g› IDATóÝ<*FŐ)úť­=<Ýź•äâGJP%sJP„™-OoPpŚű¨ÚaË’ük°íľ-íţnťŁ ÚýMÚ}+`wÂ{˛«“é°%Ú[Š»żk:ÂĚ–NŰ_DCŢy:‡hÖč˛Kěéq9c!9-Lĺ¸Čĺ˝ß iŚŽÝż2ďT2ŤëÂŘ}Łôux?ş?7Ąs}!ü #&ď  B—y¨9c`µčá{ѱEęN jă8:+Ö=IXđ»µuXp0"aë.´ű¸ú$’˘Ý/$íčj$ĺ×l%§Q,@2KôXD_ĽµsoTٵ07qÉóGˇ´µ3áŚzńVŠ~AiâS°Lě~5«Ä÷]¶Ě~Ż”Ů–dnÂżó±¶‘„ą±őRők͉Ť'÷ËƶͤX'şWóŤĎ?˝¸?öx“.űnM±őŤŃ±EęN j0łµ)Îp`wźžaHő˛ Ékł]J»kX‰4–vż¸*aËFtXjy˙VáîÓ€ßÄš¶5łrËHcHLP Ă>çŠî?JďŤ÷¸­O1™ą;Ą(Q|(ę«=‡Ú)ž¸Íťş|ZĹ1!ôšv=Ţw«Ćî´q-{( 0ÖfaD—ą,S¸Ł+ě­kmĚĘfĚěĽbü>‡úc}޵–N±ă€pć0O/öpŠ……ŮŰpfă.öňËńs¶ cj4ĽËy…ĂüąE]ąÓlQfDCʦ0žŁë\I¶Ý?¤ĂŽ‚bĹČČ6tŘ Ú}F]ăÉĆńżÄüĐĚ–wW3‘F•w>ĎÉé<9céĽóĹ‘[^ Žhé–ű€M)Îü'ĄÉnZ‚ú)ˇb,Ŕ˘U„˝xě~ŇEÁľř;đKB¤Í€ůáŔ¸ś±^?kíúýf1ŕá ź›úšäť/sĆíŔ¶„ďö›Öeí:Ľ7~żpbB‚»!ŵ`o©pn¬HżPjöâ=·»ű„Ě"©ŻQ”Îp%4iŤ¶ętŘHŚ‹1âë9śy0n)ąŤH^¨:Ńp6ÄůWçsŰş-ť=ăUŚ=hë¶@×ýţŚq ÎżřŚßVtěé%Żßžµ·j3ČuĆ0 óeCřŁßő˘Ć<„őřZž»ßKńę{ailńädíś1‚b1śOč9IŠ÷°®–3fVŤż MO¤Ş)(·DĘ1úęM`׼3#ZgßضďĐĎ«'D˝—źĹš*zM˘ĘĽń?é5)©ćýÜ4Övgě~üýPřď,Ń4+É”Ô ™Ů7)ćú‡¬bÉ@Ň•ÔGh÷¤J©Ő:Xçtíˇ°ń㊏jü¤ŹqőżĹG¨¸¸§Úz=Ç8’ÓlŐžwÚýcş,VY,ˇ­UĹ?«v2kýJĆ"M.>4-B2V(ĚxGŢéiôGîŻ .,/ó5ps…q‰ô %¨ŮCńwđowż'Ë`ęl„¶·ű|ÔÓl`ŕś“ËěYřőĆZĎCÝÇÚ`Śö9ľţ¶ĎŔ80śż1Öf©ŕY™É8ĆÚĐžw•HŇ"đ '´µ$wżx$z8­‹*Ňč˘8‡q-BŁ‚róOČ;OďDżEeĂ{!Ě_-ťł’çĄ9ÝźJ™áÇ5ňkŠCog! őíĎďÇăc÷wĚ•,Ůéôá÷Y"ďĽk_*gl ť#Ťî貯SěQD(€W¸ĐxwT5X$3JP3bfK?‹5 ¤ŢS(ÎI‰ëű0ž™śHx_źXv&ü'úů F” I6+›Şć}DňzŤăżž0\k9F°{…Ďú#ř]?FŐj>Hh›+ˇ­•Ĺ?łv5ł“ ‹4›¨Ân!Y\•ŇĺEzLP#…DtQŠ˝m3(:ÚŐ”~^ţ1géőOrĆR”V ż9ď”ű[Ţgyç =Ö´ĄëŇ×Úů‹N ˇ‡ď9cm`‡XÓ?ĘĚ“ŤóŤ7i ˇx۱űŢ+™S‚šťĂ)©zÔÝűű aŁ”ĐÖsˇžrNµ5 “üg2„ËĘîë<Ľ@[ÉÚţ…á˝×Đ×8ëăďŃĎů‡%˝Öó2… Ćśb«Ąî+qI_,ˇ­•Ý<ÝFé<i<…„d˘Ę­„ˇźoVřüx"[č}¤Ěň4äť/ˇäâçŔÝ9ë>â$glNč,Śü™Dť>WňÎß(­Z{lÎXľźÎő.pJ¬iÇśqCÎş_äĚ;.ţľĽ eë_Äëx¬ýśNiOvAćŔꄞݱż~™w^©"ľľÚxAq¨ďşĚĎíŤcă kho Ľ˝& Ó VV‰=g2°STÜ)QŢy&gĽ,kžÔ ťw^KŘ÷áĽ×`ş•H©5íj~ ]­ę»Óma憢=›ÉUŃ˝ąřĽĚ0ßil̼ɡÜŰCĂé°«ÉcGâl¬Śł° ĆAĚä:ězN˛9ŽpĆ´± łr9ĆĹ{ )¬ěĂ ţK‡•ŻŇ{żMał±Ů}őbťŻĹĘŚä÷e÷/çTŰ…©<ś ě¬Fřb˛'ĆąĚŕq:líÔçźb»2 WčWvÁą€Iü‹đE&ÝI6vÇ8„PÉpeś€ă™ÎtXĄĂžĄgWS,Ö1‚~®€)"˝—wžş¬8AÍ;RZŕ*HP#żN€ÎdoVÂ0ăC˝ÉXá;éŔyçź•ĆV ů0˘(ŢŰ»6ý4Ô7Jz·ţJ±&Ć\„Ą_Ž $óńäôŔšyﬠ^N× ŕI&ҶixŻ4%¨uffó{ÇšNpwOŰ_*4“M) µ=ç0$â ”­ć†÷:WAż«śŮy,ănś]ÉĆŔ¶GŠlÇ ’ňöĄś“qvÇř9mŚ~A¨Đ p8§ZůDŇ:˙¸‡łmö˛űNă7çÎɶFŮý“śjżÂ‡1?0č¶vÄ8‡0Ěč›Ŕýśbë'<˙Gćä|üg+ś_c›zţłmx€\‹ł ˇšáA„‹Ałĺ;"ĺ(Rwź ü1Öô3›3«xD¤Gç†{ŢCŇZţ˘kwĹž;đ`%OĘ;žwŽ"TŁý đV—]¦–Żú%°BŢË÷ĄX ϔٯŕ˝ŘţÝŠ uq&aTHa˙Ť» ˝}'¶íŃîOÂ’y÷Än‰#’ňÎ×ygOBOę%tŻm0™p`G`ŐĽWôo¸ŞËůo*łďµ]ö­ëE‘4â[z ô<\ťa,­Ă;×ńz“ýť˛űĆ…žĂ18ßg¬íÝmhk‡Ť¤°6X[çPĆd'Ú\ ćçQ%j{‚łíF¦r+Ć:8c8ÉĆq¸żžňo{(ş.;©l@(AźlŚD‡ýŠđÇj0ÇX[­âˇľaXîŃy_eßă0Ź˙1˝šSě Ś<0'ĆąŚµU9ÚĂz˘§ŰpśÓ˘}ßĆ͡^,Ł?Ö.`çEŻY˛Ż8Xgwő c[ď Ă. |ńŘă·śn—pwý’$Ő»8š°üěŔ~Ŕq™F$"‰ňÎŃ}|ţąŔą}xţsŔŻrĆÜ„5¤'ďĆ—éáççTqÎ;(ß‹ßwĹ‹śIŰo¦‡%X˘!¸Ł«ďQ`çśa„×cࣼ÷®pdŢ™PéůóÎí”.A$ŇÔZGf6ĄŐéNt÷ţŰ0mý,?7ł«¶Îˇ­s2˛sݰ¸mžçO»Z a#BĎź38eě!ţ!p ž¸ÔNÁ ś}cÉi°źO˘­sIŹYÜ9§§»ééÚý:§`Q¶~h—ä4jőűń΄|eF°g,Öŵq˙X’śíÓÉA„*ĘÝuŘ|ŔQŃŁk»$§A»Oö \•ÉŚ˛…&¤Bîţ5”,ét€™ŤĚ*iy磼ó\Ţy§Ňä´•E˝Ěäťgz›śŠ´ %¨őµĹ9t݆tH_Ťµ6 ÉŤó|UĎ=Řźž‹% ó-Tď-ß{ p_K»/ĚdFpżXfĎBď,eÖ`˝ˇ[’V<Ď˝†59ßK=KXf§p®%ĘÄS4ťýbĂ‹*#Wb‹(ž—9¤ĚˇY8:‹5¬ŰŮnlÝűšAü-ńążö/0.HÜÖĆ:ŔČ(†ËSĎßîďCçžuS÷“j]Hń˝67°O†±$©dMčF>ľČ€ˇ!ľubfCbM'G=ŇW#™‡ÂĹK/w_ĆŐ„ÂŰ1Ö†vk=Éć`[0ł‚µŕhźÚyżĂćĂXç›8+D=™«ĆöL›ŮŐÓeĎἀ±…!­iB•Ţ…(.Ö]Ţ˙(šKz0ggŰjěç_Ą>g¬µ12*ÇojZů*â˝`‡.NqHeů‘6""Ň#%¨ő“#Ě+€0>ą—Hz#ž|}Vőłgpř0#ŘśÂ\Í6~@¶ú‡ůseŽPŞĂFzčćé¸TL *ĘôZŮ­mĽevĆÚ,%Iqśwľ•%¨‡řőtŘĺ„y8+2Ťc€1©űcŠ˙şňq‡^Ĺ,k-ÄW~=ľAĽ•˛*ű ®ÔBr:„0§˘ąŽQśmŔ"ŃŁnË€ TJPëgçŘýKÝS ©ŢLftV·¨’o5÷§9ŐžĆY ăÇTë¬Ţ[yďé©ö'JçĽüs;Ćv„Ňúé,±WµČ;‡“9É=°˘ăU7×yű1Ťpĺd»Ž!ÝŞ._ń%qÂę˛=O0†D÷’âNę-šÁÔÄ=¬óőI5Cç-%Ý•Şąűd3»’âđŢťQ‚*őŇîoŃaók˝÷|Ô´7lâĐŁźąsÖ›ěĎű¨iŐ$ż+¦&Ěžč—¨DDšÔ:––‰ĎÔÜÓZ*]TşňžÂŇc\ lÇŮ6Ś/•!l8ΕŁĂöĄśOăĹ×ü‡1ţA—ýŠĹF¦&Ô‹÷p¶Ĺ˘źźtVÂMâĚ‹N啍ňŹŁŞľ×hcÓŮ&19<Ú§Ňao‹`=Ć Ĺ[üuyXŠboBš´í…9żmĚä·ćĺ{bĄż\B1AÝÎĚćp÷ęG5ôÎ#ŔVÄT5í$›8ô ÂZŮ‹Ą<·/îŞ29(,çőíţEŤciZJPëă'ĐŮkô”»?že0-çp˙ŚűŽ3oŻŽ1“«iăX`v¦˛Cźđ˙ăŢ*’ť˘ź_2ťu9<勹±BlŘďpBUŮ®ń,ß­­ Ěů\1z4±lDÖůzĽ]vż$í~v)đs`…˛k†q`Ųó:ò=KEŹ^Žmy XXłmvöóI‰Ďocé”Áy/ÄöY“rC…OłUaLçuóę_IĺîŮ‹Ŕ2„˘1;˘©‡‡ ę^tŘ´ű§… >jÚWP¦€Z˝uŘ``˙čŃ„,Ci4Şâ[ńá˝ę=í…á§ ÷ęŮaŽibŐĆ)$›VĹđ^ý|>59=ÍĹY©óqHP»3¶çdKî-ÉŹ).Ér]j4gŰěŔlŃŁŢ­÷9ťý)VgM]ŽbeÜĹŮYů8ÉľÖ¶’Ř ÷35eéŮ6 ëçu3 @(:ć–_óŹÎmS¸Ť0OŚ9ĹJ×mkm|EĹÄĽÔţ2pFôüuč`l´üPŚ39cţhżsËV–Ţş„bšőĚlÉ,‘¤Ý?öŠíJ‡O‡ Í2¤n:¬ŤŰźP9ŕpÚýĺrOh4Ä·˙Ĺ{îr÷ŢődIOnv椕h穪Ź0«Î ת˝™˙gďľĂ#«ë·Źżďě&Ű‘ŢDzYZ–Ą÷"E~HPz°`C U”& ”GzGéE@z—eŇĄI¤ě.ěd“ĎóÇ9Ůśd“ÝÍdfÎdć~]WČ™ďś9soŘťĚgľíé+AΚ¸š «0˝śVťîËş4 lH°ÉüË7éšKÓ{8glKqš. Yivm‚ďĄů:hŕ»´Ěd~źX/=šÄHîží?Go-q#­şŘ«ßsŠI´ę'ŔŔ—čäZuâ!:iDlěK˛hSbß´řMÓ8UűÓŔ}Ŕ;9MçŇÉ˝yŇ^ŮMHćŞö=Ďx4Ç3…oüŚÎ¶ä4]M'ĎŃŔbĐőa‘¸›Iüˇčź‰ő+"^•ô°!ɢW{á"«”–¸‰Vť|—dUéhŐˇŔ´D~+ĺ¶jÉëĎItďÁ|pvn™ĚĚŞ” Ô2’$’ů{].Ę+K͛̌ás’yoëCęÁń ­zśî…+2Ľçd^c¦łc?f8›‹ô{NK\E«>ţLŇÓů‚ôZXéM‚Ýi‰űgxüań8żŃftpbA‚ďŁ+"?€ř%Ám}>˙A1‰“5žFÎ$™÷˝6ÁÚé"QY×3Š=9Ä+i—ŃĹ$*¸@µJk‰ďŃŞ ó]‰dÁ¤NZőÉ|őJŹśXX…î÷\’§ĐâQff˝ą@-ŻMé’8řkŽYjŰ11…VÝě |8w†sFń S9ń`ź×Gé§ŰŁą®Ďs‚SŁIöĽë¶Kt;ňkmŤŘ™doÎF‚O1Ť+82> U?榳źĹ|‚OĚţŚaw’žĂŐ€w`8çń“ř°ßźErýŇ^K®ęăúÉPWÍćâIGÄ˙řµľŘ"my¨ĎóZâNNŃ*4°;b`‚á×ë™Ě5…~źç§ńÇi)ĆpÉ0ëĹH>lxÉ\Ę(ćˇ!ýŘמ·ÉĎw7Ző˙6D¬D˛(Ó€—éäb /HR~W‘Ě ,#i˝čűďŚY9´ÄźiŐťŔď€-H¦V¬~ͶɅdŇČčĆYź;¦’Ľvţ–řgI®hfV\ –WvHä_#bĆŐZ­tÄŻv6ĄUKŇŻö¸?YöŘ™^㸸c¦ç§ÎâţŰ ź^ľ.-Ń»WtFÉJ¸—¤_ěťî7ú/–čcíˇ1đá­‡ĆĐOaź•,UüđŮcb IqsF÷NaV˙!)”á΢3Ř DÄÇ’n¤{eë˝čďC łri‰×iU°ÉčţGôါŮdäpÚĎ˙ćlĽöőďż$[ŕŮŐ{/ŤÎÜ’Ô“źĆ#ç -yÇ©¸ăÔ€ř5É" ßćŰNfůiô\hĚ{˘š™™Ů,ą@-I‹_É4yőŢJáŔ«Ŕˇś®…óŽSQŁŮX8'ť‡i–§ěkßW%Í—[333\ –Çt˙lŰ"bŕ[žXńŠI4°'p ÓX=ď8"ľJđUTä"CbQŕLFsXi™ \DL {Ţ_#°[ŽqĚĚĚlđ"Iĺ±cćŘ˝§yři<ÄP\5ôřŰ ß'”(‰Y©\ śśř}ŽYĚĚ̬ʹµÄ$ͬ™ię{/M3łúpućxI#sKbfffUĎjémDwĎôk˝öâ43«#ń2đzzs$°^ŽqĚĚ̬ʹ@-˝Í2Çwĺ–Â̬zd_ 7ë÷,333«{.PKĎŞ™YOŮ} ] š™™YżĽHR IšX-Óäµ ©­é‹Ŕx`e’!‡68ĽL^ŚćBäśÇŞĎÝ™ă5%Í“rKcfffUËjimBwŻôóńNŽY,CmMëß'™˙¶TÎqj٧jkz¸8'š Sódů‹·$˝,Oň{g#ŕ–|S™™™Y5ňßŇňđŢ*ٶ¦ŃjkúÉ–3{ââ´Üć6NžP[Óšł8ßę‡çˇš™™Ů,ą@--¨U$í5}ř śăÔŁ±ŔĂjk:QmMĂňcąsjfffłäµD$-¬Ţ ŕžüŇÚšÖ Ye™ĽłÔąaŔQŔ9y±ÜÝMňÚ°Z:gßĚĚ̬ĎA-ťlŹŔ“ńAnIęśÚšFŁgrÚk$‹úü·™j\#É‚S«#ú9çµ5ÝÍ…k+ËŞID| é)’ż' $sö˙šk(333«:.PKÇĂ{«Çńt÷fgµ'gEsÁ…i‰©­©Ř8“ľţ稭éh.Ľ_ŮdVEî˘{ĄóÍpjfff˝xoé¸@­jkjéă®kDsá8§ĺÍ…öh.ÜŚÎč㔀ßT6•Uď‡jfff3ĺµ$-,™ŢśÜ—[;dŢcV°{4žĘ!OÝI·–9ľça襁¦/T6‘U‘űH^#VLçî›™™™Mçµ46Í?źć–ÄÖ飭5š ŹWą@Ľěü)÷ š™ÍZvem¨fff6ť ÔA$`ŮL“ T3łYsŞ™™™őÉęŕ,tm‘0…î•)Í̬Żź§ÇsHZ4Ď0fffV=\ Nö“˙#Âűmš™ÍBDt/ešÜ‹jfff€ ÔÁňIffĹńJľfff6áyâĽĹŚ™Yq<ŐŞ†¤ą€…EŇď]Ç›“ C?(ď¤_o÷ő=">«|z3łÚâup\ š™ÇŞĺFR#°)°đ5`±Ů|čJł¸î3Ŕué×Oý138¨ăŐ̬8Ů­f<Ä×ĘNŇśŔWIŠŇm€/”áiVJż~Ľ%éz’bőžh/Ăó™™Ő¨E’4šžź¸ş@53›}Ů×ĚĹ%ŤňđH+5I#€˝Ż›M39ýS’ˇşoĄßßĆ˙ţ4Ňsřoď!Á˝ ŢEŇŻŹ%Ý \×—âĎffV«\ oY@éń›19Ď0ffCIDüOŇűŔü$ŻĄËOĺ›Ęj…¤…ŃŮą IDAT`ŕ—$[ÂőĺCŕfŕŕÎř¨Źë|ÍĆsÎ ü°=°0&s÷€ÝÝ%=÷ĚöČ̬ŽxßâyxŻ™ŮŕxŻ•ś¤-'€‹±8} 8 ŘX "öŽkú*N*">‹"b'`>’ą­çďö:u-ŕnI7KZe°ĎkfVk\ ĎŞ™Ůŕd_;—É-…ŐIă$Ýü X-s×$’žÔ±±lD´DÄ}ŃQ®,ńyDÜ’ ^8čĚś¶ Đ&é|I_*W3łˇĆjńćĎż—[ 3łˇ+űÚ9wn)lH“ôeI—€ŻdîjÎ–ŽźGÄsyä‹Îx8"ľ¬J2¤¸K°/đ˘¤S%•cá&3ł!ĹjńćĚš[ 3łˇ+űÚ9gżg™ő#ÎŰF2ß´k].VFDŐ|ĎDÄöŔŔ™»F‡$­K83ł*áµx.PÍĚÇŞMŇŹ[čŮű~;0>"vŹWňI6kń`Dl@˛ Ň3™»–‘´M>ÉĚĚňçµx.PÍĚÇŞ ¤&Iç§ĂŇć˙‹­"bb~é&"n öű`ZÚ<p٤–Ü‚™™ĺČjń\ š™ Ž TIówűgšźÖŠ[ňI58éŐÓ-Ňćŕ×’.H÷r53«.P‹7GćŘŞ™ŮŔe_;çč÷,3 Ý’ĺ1`ĂLó Ŕşńr źç+é>Ş˝Ű‡Ąs^Ë""îÖţ™iއdKšËőĽffŐĆjńÜjf68îAµŮ"iSŕ!`‰LóIŔQęßÁŰOJ: ¬)钞ڲΠŤWużfš×ţ!i©r>·™Yµžw€!ĚŞ™Ůŕ¸@µY’´4p Ý˝ěS€oEÄ•ezĘ‹€+÷qßîezÎé"b˛¤ť_ǬNü%ŕzI땡 73«*îA-ž T3łÁqj3%iN’aĽó¤M–±8%"ž çĘş]žIď+»Hě t¦Í+—HR˙Ź43ú\ ARĐ”irjf6pžjýJç^ŚM›:Ý*T$^4›meWGfš¶~Yéff•äµ8ŮOú;"bJnIĚ̆®lÚ iLnI¬ťD2´Ëaqk…žűş{.IŹ/©Đs÷§özîŁ$í–G3łJpZśl:)·ffCXD´S3MćkHÚ8<ÓtaDśV©çŹ·I¶łérgÚ–—G3·˙ź¤5ň cfVN.P‹ăů§ffĄáy¨Ö¤5ó2MßÉ!ĘEýW\D|켕6Ť®“´p~©ĚĚĘĂjq\ š™•† T›NR#p02mzřzDLí˙Qes-I˙Ôô8Wń°đYÚ´(đÇü™™•‡·™)Nv1¨ffĹóBI–ő= kżĎ)Ŕöńź˘ŻÖŞyHö2ť Ť_ĂüÇňvč|÷¶ŁuĐ‹çđ:đ$-Ĺ­]ŹKÚźdń(€m%m÷ 6ś™YµpZ÷ š™•†{P ľĄĚŃ™¦SŠ^±·UŰ­ŔňÉtő^Ó/Ěuzé UŹ?¤%&ôÁqą¤]H†üś ¬SÂ|ffąrZ¨5B›VťńLŚ+2¨kMĐ|ëĆgł>»Čçhk<´-°4đr4Ö,×s™U TërÝ=ťď_©UÎ%YT¨Ë»@Q˝°/5ësh)’żçëŹŇŞĂi‰ßqťŁH¶ś¬-i§řK sš™ĺĆjq˛?·iąĄ°ÁóŇÉV ňŤ±&ŽŘŤaŤg2zřŞt/bQRjk:t,Év€—Ęń"üžÄ̆łŠđ8ťżüiŔWhŐ’ŔÉé­_Đű¦8-‹–č¤%&W“ÔŔçÓŞE\íXşLZŽž˝ĆffC– Ôâ¸@µÄÉ·áćĬ”\ Ö9IËßĘ4ťî‘;P»’ą˙N*E¶˛i‰Nŕ ŕ`I`˝^"Ý—őw™¦c$Ť)M@3łüx8Uq\ Ö8Mlü9č}ƵźK[Ón› } hCş VýüMĐhh:± 1íHM1‰q…#=¬QŚl<1XxâćhnżŁÇs>Ő´:ú \Ś´ťűCĂ‹D< KľD4´®‰#>ŁaŘďcµ)očź#Vˇłs{B+,„xń$cÚ˙Ë̸=žµ$ѱ%Áć 1Ŕłt ű}ŚźňúŚçŽüŃąÁŠŔ[ŹŇŮ~^Ś/ę ¤Yo.PídşßŹL®*ň:«§ß˙FKt :UąµÄÓĹ’¶$É~wW9ř6Éžźż,YF3ł¸µ8.PkťôcÄľ<Ůx!ÄĄŔ®DlFÄtvNĐSŤ›Đ0z Šď’ěG°ŠďruňoKF¬Ŕ¨ĆÇż¶ćľ ş]O6ýA¨űß`+Ł8ś`:;Żmq(b ß%"Y<$Ř7ą=m~µ5ţŚŽ@č`sÄJŔżgRăš ŃdčɦźĐŮń/‚?ÍŔ8†M{QO6n:ýĽ—4BmMÓŮyÁţóŰ"ΦˇńMőĺŇ˙ŕ­ą@­c’ć%Yě§Ëɇ{EX1ýŢ6¸Tőtú}Ĺ™žŐŹřîaÍĐł'ÚĚlHrZ¨őam‚őľÉGí đYűÜßcčÔ/bÜä·Łą07"YŕBĂÇFsaîŘ%:„hK±?¦ą}áh.¬ÎÔö¸‘ŕ»<ŮxŔŚO‡!bcŕ4´7}ŽäMWˇ}©h.ĚÍ…6=9b%Đ/‘> ScŁą°Íí ¬ <ŚĄˇqď®+뉦uN˝GëFsa9š ‹ěŚ t…îQŇ“ńéđĂ€=!n€öEc\a|4ćFŚCťŢ ŢJÁj}Ű–d%Z€EÄť¸VW/l1‹+ĺĄk$Ę`F´ť—ąÎ’’V\$3ł|ą@-Τ̱ ÔZ¦Îcµ©WĹ&ńy¬źńżöź’¬:şÖ,;±qOÄęŔ…1®pF×ßX;>ˇsÚw€N‚§„Ý^§©}ß×~_4ΊUg˛’e'«ŹŇ‡ĹęSź"b\áqŕüäĎŔrÓĎĆŹqx¬Zx4=ż3Ć.Ý |ħ(ff%á9¨ĹÉ~Ęß$©)" ąĄ±ňiěx({36‰ijkzXR/iD_ó;§Sşqzp—Ú4wŹű†ńđ8°sŤX‚ě–1OÄŘŮűűă¦^NŻ äőO}‘iĂW­î‘Đ][Áśí3ĚńŠć©ŰLżFRxŽBť·P`ř ů~+h}Xřűěd5ëĂ˝n»µŽHE2˙˛Ëµye©×[¤ÇŰăy¨f6„ą@-BDL‘ÔA÷°¤9rŚdĺ >ʱńa÷LI˙;čż@EKC€¸gňDË-PŐđň€b>«y( ?€`¤•ˇqÉ^›÷ @÷h8s7Îôź™Ö ZšB;AăNýžZf YÍzÉŽ@™ťą%±°Óôˇż…#6¤sÚżŐÖôŁ?Î>%b»X+<÷ÚĂjýZ,süTźg%ŕK@đť§DsáfşWSߪÔ× ěĎrŃÜR™ ‚{P‹çµ& :ŹCŃsˇ"âTşWiîílĐ´3ý˙X­đGµŤřŃ@ĐI˛çéjSźŃłOˇqo`h { Ý͸ÂUAŹUKźGtŢÓĎóţ´é*Â@4·ßˇ'F¬BC|´ Ä{Ŕ%Đ~a4ÇGjk4żžŐ16&%Ź)ś§ #ďfXÇ® ŐDL`ę´?ĆÚńÉôkŹŹ)ŔŢšŘx! _!:Ç‚‡x’¦içőłÂ±Ů@¸@­_‹dŽß.ăó¬–~!š ĺ|ÍşŘ#ó|yÉţ,] šŮäµx.Pk@¬úŮ«Ŕ±3´7·źÚďcš 3Î÷˘yęŐôšk îizŢŚŹču޸“Ŕ“ýŢżZáŹ}¶Ż>ő9ŕŕ~˛žŐgűřĎ_NśU¦$Wűßń^§V.Pë×™ăâ§9ĚZ×>Đď—ń9 űďU~Ůźĺ"ýžefVĹ<Ä·x“2Ç.PÍĚ.űÚ9©ßł¬U޵Ţd–.PÍlHrZĽŹ2Ç_Ě-…™ŮĐ•}íü¤ßł¬¦¤[ĚĚźi*gj˝Éţ,=Ä×̆$¨ĹűWćxŮ~Ď23łţd_;˙ť[ «´é~˙15ÂóŮKČC|ÍlČsZĽ2ÇËç–ÂĚlčZ.sü|n)¬Ň˛…“{OK+;Äw~I^kÄ̆¨Ĺ˨Kű—€™Ůě“4X<ÓôBçZÍ©ÔIu'">>Ko6Đógmf6$¸@-RD|t K,ťc3łˇfYşý×Ă<ëĘÜ™ăŹú=ËŠ•ý™~!·ffErŻß༬›/Ź{ĚĚfWŹá˝’ćÖ:Ęńĺ˙#Ůlz/sĽ`n)j¤z.@ő^çš™U+¨Ó»@53łŮ“}Í|!˝}{ąžL@'e*€găkZŽĎ]’ݱüvĚâ|1 ŃŔ ŢBx+”ň™źî˙1í”˙W3ł’s:8^(É̬8˝ Ô§•€aCř«™/ńµsź’ó,?áY~Ňusy‰`Ƣv ń¬$ Źiĺ˙Ô…ěÖ2ďDDä–Ä̬H.P'[ ®[ 3łˇ'[ >źĎćf(H÷Íík ιǟt0ŤOß{žĂOÄőşć 7 o–úçU§˛=Ňo÷{–™Ys:8îA53+NvŞçďφtmnsi·sg¤7˙÷\vz±×’´Ý«8/‚ ÔRqjfC^îC††¸—č~ł0ź¤yň cf6Hšřbzłx%Ç8–Źěö2ž‡Z:Ůźĺ[ąĄ03¨ŕµL“{QÍĚf-űZů˛çÖĄlďޢýže•ýYşŐ̆$¨÷bćŘŞ™Ů¬yxŻąµ<<Ä×̆<¨ç…’Ě̦÷ ľV^ÍŻ—[Š’.˘µV¦éµś˘™ Š ÔÁóBIffÓcßÜRXžnËoč5Jb}`ľôřcŕáł™Íęŕą@53÷ Öąxx9˝9 ضLOŐ5żyT™®ßĄkW„<çSď9ľ%"ÚsKbf6.P/űćjétŤ™™ő!}Ť\:Óäµ~]ź9ޡ߳§«‡~eµ5•ó÷óŘ^Ď—‡í3Ç×÷{–™Y•s:Hń6đIzł X5Ç8ffŐnU 1=~?">Č3ŚĺęşĚń–’F–á9&SŃŔŹĘp}ÔÖ4?p`zó‘r<Ç,3H«KĄ7Ű[óČafV Ăg}ŠÍ†Ż¦Ç›’üB43łmš9~ ·V ŢćĆ[7–ň ˘ą0YmMÇ'§Ş­i!ŕJ’˝wc—ź Ř8ždîçKŔźyÍbe{ ď‰Oú=Ó̬ʹµ4îĘo–[ 3łę—}ŤĽ«ßł¬ćED'= Ňr óýđ’ĺ&˙>ä×ëŔĹŔ’$…önŃ\R¦?ìdvŢkfCš ÔŇČľÉÚH’{¦ÍĚzI_7Ę4ą@µě0߯•c‡h.tFsag`ŕQŕó^ţUŕŹŔJŃ\xĽ„םm’VĎ4ÝG3łRq!Um$źĆ~Xśćˇ™U±5H^#ŢŤgó cUá` ÉŃůIŠČb‡ÉNNż÷ąeM4..R[Óp`^@E>O—)Ń\ěPÚŃé÷É3=kćZ2ÇODĸ–™Yî\ –@DtJş—î!6›áŐ̬·ěđŢ»sKaU#">—ôŕ´éxI—GÄgE\î)’žÄq3}ÎćÂ4ŕÝ"®_Íé÷§Šy°¤Ąďfš~3čDff9óßŇńµÄ›t­nŰŞ1too4`'ßEË#xăĺ#¸rÁ9Xcüéś±Ě|śüܡÜXÄĺ>¤% ĹfI ¬–H†C›™Ő ¨%/IzřÉŞz·ĺ›ĘĚ,wŇ˝Ňčż"âÍ<ĂXőŠ›%Ý lJ2żňIëGÄ“E_´%&3}Fß;T“Ţ›ÄÇ´Äîiá&IO<˙ѡ, ęˇI;ÇfšÎŠW+őüff•ŕ!ľĄçífĚĚzňüS=HVăÜ ióôo›,Šx“T™-m$­N˛ňo×ÂHŹGVâąÍĚ*Éjéą@53ëɪͶxŘř,mZ¸¶š¶o‹©±?p3đ ¤Ëů|’®F§Mo;FÄÔr>Ż™Y\ –^öÍ×8I_Ě-‰™YÎŇ×ŔqéÍŔ $ŮlÇoešÖţSś~EÄYŔ÷€%m_Žç4¸Žd H¶¦Ů."ţSŽç33Ë› ÔKçVý+˝Ůl•c3łĽmE÷ďš§#âý<ĂŘĐW'fšö–tX^yú÷‘Ě™=ZŇ1’4«Ç Đźé^d,€}#bb‰źĂ̬j¸@-Ź›3Ç{ć–˘ţ´÷Ń6ĹSXV_?˙ľţ?YíÚ+s|sżg™őíç$˝‡]N–ôýĽÂô'"Ţ6–!Ž\ôŞÁ]$ —t°[¦ůř¸z°×63«f.PË#»1řVŐ´¸CŤ{®Ź¶fµ5 «xë˛Fm}ý˛$iA`ËLÓEýťkÖ—’zźJ›€3%ť#©±˙GV^D|{÷‘ĚK]¶ŘkIš‡d€2Í×Ç .Ą™YősZéĐ›®ÍƇÓóÓO+ź§Iö„Ë ŚÍ!‹%ú*P'T<…ĺewş·3{<"üá„ XşźřvŔ‹™ćď·Kš7źTý‹ß?n•ôŐ>^ŇXŕ1`óLó]Ŕ>iÁnfVÓ\ –ĎĹ™ă˝sKQG˘ąP űSö¬+ťĹ@mM«“ yëíńJg±Üd_ű.î÷,łYk·gš7“´R.ˇf""î¶N’tÄě>NҶŔĂŔҙ泭"bJiSš™U'¨ĺs еy÷ęŐř ´F=ŘGŰ·ÔÖ´uĹ“Ô1µ55çÓÝ{Öĺ3Ŕ‹{ÔI«ÍéÍvŕňăX Ź€m€ßeš—N »ŞŻĽ¸JŇ™ť/ép’­dćJ›¦EÄ÷#bZyÓš™U¨e’näý÷LÓ^ýťk%ő{ŕó>Ú/P[“WT®µ5Í \¬ÚÇÝçEsÁ˝ő!Ű{z›WďµRŽ88î×ć®—tĽ¤Ńý?şň"brD|äą$-ŮűI KşřÝďË>¶Ś?T.­™YupZ^ŮAöäźw™Esáe’U{[¸MmMV[ÓšjkYáh5OmM_V[Ó·€gťú8ĺŕČʦ˛H^ű_’ôI˝Goä*"NŽî´9€¤/H:x řfćôgµ#Â{›Y]ŞŞđt-0 díMéŮ«jĺńŕëŔş}Ü·_ú5MmMĎoW2XŤ ¬Ě3“s:}Łą0ą2‘,g_NŹ?nĚ1‹Ő¨¸_ŇZŔ $ŻAü˝;ř©¤źEÄ5ąě%"şMú«¤W€őŢ‹<ÝěźT< ™Y•pZF1YŇ_€}Ҧ˝qZvŃ\čT[Ó>$óQűŰu8ÉšUúąßJë„h.Üźw«ěđŢ+#bjnI¬¦EÄk’Ć“¬ęű ş_ó—®–ôpD5ôF¦Ł¨Öć&Y•8ëŕ¨řkĹ™™U9-żěжŻWŰüZÍ…‘ô >w–:÷)đíh.›w« Is;fš<Ľ×Ę*"Ú#âL’•o d繯Ü%éIß—´XĄóIZIŇĎH¶B»€dDU—v’©+»853K¸@-ż{€7Ňă9H†žZ¤óQ7&ŮŹîłśăÔŁ;•Łąđ§ĽXEí ŚJŹ_އň cő#">ŤźË:2wo ś Ľ!éqIGKZą9”XWŇ©’^$)L ¬9íS’ß˝€HzVÍĚ ¨eťŔĄ™&Żć[AŃ\čŚćÂo±$oî"™gĄ×AňFěB``Ëh.Ľžo$ËÁ>™cď}jďDÄ·I¦p\ßÇ)ă€JzYŇi’¶–4VŇÜ}ľt±Ł$m+éŕ-ŕ!ŕP`Ů^§·“¬6żtDśW_ţ éű}n3łZä9¨•qеQ÷W$-’nCcÍ…×HW÷U[“H†‚­L˛ŔŹ NŚhó2őMŇ—ŤŇ› TËQD<ěö”~ŘX˝×iK‘ڞůiW¤)$ ču}}ř·¤IaZX$s<«©;íŔ˝$ĹňµńVďś’Ö.“´:Éާž·mfuËj¤ż|Ö éµŢhÍ7UýŠćB,ë˙RŢYĚjĚ^€Ňă#â•<ĂDÄÓ$Ł;ŽOç nGR¬n4őńŃ$Ă„—É´­ ě:€§ý¸•¤(˝%">žEĆŹ$mK2ŇçI;ůl3«Wâ[9Ů…Böé÷,3ł!H’čązŻG˛ŞoFÄٱɊż»—÷HzţjɰŢg[óEÄ®qů¬ŠÓL¶Î8Šd«´{%őµUš™YÍsjĺ\ś4+KÚ:"nË9“™Y©lO÷|»Ď«rĚb6Ké^ŁW¦_Hj%Ć»đM’‘Ď“ ů}‹îáżoďĄëM”*×Ő’^®”tZDśWŞk›™ .P+$"ţ+é`ż´éhédý IDATŔŞ™ŐŠźeŽĎźÝ^#łjí$sę»VßGŇ|ŔkqAs<•ÎK˝2ť—úă4›™YÍóßĘúĐő)ëú’6Î3Ś™Y)HÚŠdŽ=$ĂOÍ1ŽYM­I¶Iű»¤rŽdfV.P+("^¤ç°·ŁóĘbfVBŮײK"⵼‚Ő’čC€?HZcVŹ13ę\ VŢIt/ÂđIkçĆĚl0$mlŢě$)bf%—,čt©$ď§nf5Íj…EÄ?3M?ëď\3ł! Ű{zMDĽ[łO|t€¤ßJ–w&3łrpšŹ_fŽż&iµÜ’™IŇZŔéÍNĚ1ŽYÍ‹÷ÍIv¸]ŇĽ9G23+9¨9wdšŽĘ+‹™Ů dG€ÜOĺ–ĬNDÄ´řp)đ ?ä6łZă5?Ů^Ôť%-ź[’|ôµş*žÂĚŠ"iUŕk™¦_öw®™•^DüظFŇ7óÎcfV*.Ps÷¤7¨ż^ÔŹúhóP%*ćîŁmrĹSäëgt¨tgD<–głzŹ?’ô+I~_gfCž_Čň•íqŘ]Ň’ą%©Ľwúh[¨â)ĚŠłHmoUĚĚŞ– Ôęp%đRz<řmŽY*éŕÝ>ÚO¤U+T:ŚŮLµj,pl÷Ľ\QŮ0ąůÉHHF~\›c3›‰ř<"öî&Ů/uąĽ3™™Í¨U ":€C2M»HÚ2Ż<ӟ̕ém$p%­ZşÂ‰ĚúÖŞeHŠĐ}Ü{ -Qó[ĚHú°]¦ét™U±8ř1p‹¤˙Ë;Ź™Ů¬¸@­qpS¦éLI}˝®--q=pQ÷¬ Îř3-µ?SŇ(ŕŚLÓ5é*äf6DÄ]ŔW€$ý,ď¦Uű·Ň÷ßÉÍ€‰´ę5ŕa’y«ďťËhő XX‡î‚¬/Ó€oĄĂÔkZ:oí°LÓqé,f6ÄDÄ`WI‡“ĚKýzÍżÇ0ł!Çjőů5°7IęH’ÄmrMT -q'­Ú8X°źł–`ćEY%Ľ ěGKÜ™w 9hJŹźNĎ1‹™•@Dś"éIŕvIß‹;ňÎdfÖĹC|«LDLľźiúޤŻç•§˘’ą|+Q?+˘ÚĐs°R=Ě;´ °E¦é –W3+ť¸ Řh•Ô’w3ł..P«PúIćŐ™¦Óëf®HK|@KěěL2Ś×¬ĽěLKěFK|wJ4=·Ľş8"îË+Ź™•^DĽ¬¬'éŇtA43ł\ą@­^?!YŚŕKŔ/rĚRy-ń`ŕgŔ9§±úő8p°Búw˛ž ,šš_3+—ě<Ü/ińś#™YťóÔ*oI:hM›~"é˘x&ÇX•Ő''ŃŞĹ5…I±™đö3˝Üú<ľţcűşo‘ąř×ÖËsoă0:*ťkŕżŔ€w€Çh©ĎĹ€$­L˛ob—Ł#âÝĽňYyĄ{ź © ¸KŇqOďó$ŤŚĎ+ĐĚęŠ Ôęö;`_`e 8Ř8Ď@ąi‰××óŽQí¶‘ÎéęKŔŇtňËď;DÄsgCÇŮt˙~xřCŽY̬B"âFI˙®‘tnDüľë>Ió‘Śjň6SfVVâ[ĹŇĹHĘ4m$iŻĽňŘó2°;ý´{}ŕQI+äÉŞť¤˝ Ó›ťŔ÷"Â[:™Ő‰xžäwĹV’Η4"˝k]ŕé 3ł˛qZĺ"â~ŕ˘LS«¤ąóĘcCKD\A˛Źě{™ćĄ€‡%mžO*«VékËŻ3MçEÄcyĺ1ł|DÄÇŔvŔ[Ŕ˝’~J2˛â¬<ł™Yís:4J˛H Ŕ$CÍfKD< ¬ <›iž¸MŇů¤˛*uÉk $óqŹĚ1‹™ĺ(":#âh’­&›¤wm$i÷Ü‚™YÍs:DÄ{ŔQ™¦˝%í›S‚"â5`=ŕöLópŕŹ’~-ÉŻuNŇ~@v Ááńa^y̬jŚ&Y0«UŇśy„1łÚç7ĄCÇ9Ŕ­™ŰgIZ1Ż06ô¤C¶ţŹäďRV đ—şŮk×f i,pf¦éşřs^yĚ,’6”t É4ŁŢ‹j.L˛•™YÉą@"Ň%ŕ÷&™É'šWySmß#™K”]řfŕ>I‹ä“Ěň"i4p5Ék ŔkŔ~ą2łjńp%ɇăí}Ü˙#I+U6’™Ő¨CHş5Č®0}Ë•I挙 HDü–¤(ťśi^xLRs>©,'gŇ˝5Q;đÍřh&ç›YŹ#âÂ؆d˙ń€;č~2¸0Ż|fV»ĽęHú9pRÚt€¤»#â˛WŇăńbŽ™lŠ6Ik“©«§Íc€ë$µ¤=­VŇ˝p˙işŢ˙żÍjT«6.–ěĄűüü+É×kÂÄ·Y(Őš§ĐŞŃÍúT3«U.P‡ ´çŁŤ¤ÇkŕJIëDÄÔ|ÓŮPoKÚ¸”dŘ/$Ă˙#iyŕ1-·€VréÜő«H>Ś€¤÷ÂóNÍjQ«Öî$yĎ÷!pđ4ÝCu‹¶Ä<ÉW ,l,\H«ĆĐĹc̬Fą@˘"âż’vî&¦Ó ü8(×`6$EÄI;§¬ęŰĺ;ŔR’vIW¶Úp°JzÜ5ďô9ć1łrhUp>Éű˝€]Şvm«Fżľ śJ«n˘%ŢČ9•™ĺŔ‹$ aq?đ‹LÓ÷$í’WÚŇMŮľ d{L·’´d>ɬ”$íN˛ŘI—#"âŃĽňYYm¬| ěVµĹ)@K|ü¤ww`˙|™Y^\ }'ËÜţ“¤Ąň cC_Dü‰d~sv%×±ŔŁ’ÖÍ'••‚¤ĺ€s3M7DÄoňĘcfe7>ý~-ńf®IfGKL®KoŤźŮ©fV»\ qéţ¨{o§M_ ™ŹÚ”_*ę"âďŔşŔ+™ćů»$íšO* I#IćťÎ‘6˝ě›[ 3«„ĄÓďĎçšb`ţ™~_z¦g™YÍrZ"â}`7şt˝ĎëĚ5ĹŔŇď~ŹjV§üŹżFDÄ}Ŕ1™¦KÚ3ŻÎb°"`RcAmŤ7M?q“ßžőĚĚşyoŤŠŰź§M‹·Kš7żTV+"âU’mhîĚ47’ěĂ{Ş$ż¶äDŇ$sŃJ›¦ŰFÄsůĄ2łj˘'F¬Jg<¬OyŢ 6vD…čYÍS†ë›Y sj ‹űÓ=+˙B2m’áľ›GÄä|ÓŮP§‹pť|;sסŔ2’öŚ)ů¤«O’ćn–I›¦߇óKefU§!ţŚŁS˛záźAić¦k‚>|:u!Ň—(4žLĎUÄÍĚfĘ˝5."®§ç/†µżHjĚ)’ŐßZčąĎŢŽŔ}’Î'YýI·üą—i> "nÎ)’™U!=Şą€5čÔľ±úÔ§JUśÄřhŹŐÚďž6m]Şk›Y}pZ"â˙?Ë4m\ ©4 "X݋ӀŻŮžůńŔc’šóIU?Ň!Ő—›fšŹ sŠdfŐŞ±i ’ý¬ ±úÔrý2ýľxźĂĚj Ô:'gdšvNĎ)ŽŐ ´·~Cŕ­LóbŔý’¶Í'UÝ8Ř)sű·qj^a̬Š5D×{żňn7ŐŮcTŤ™ŮlsZ_&ٱˏ$•W«=1‘důÄLóŔő’Î'Um“t<=‡ń_ ’S333łAqZG""€˝;2Í'J:0§HV"â-’žÔ2Í Ŕo%ť-É‹ł•¤?Ď4ý Ř/ý·nfff6ä¸@­3ŃN2WđńLó9’ľÝĎCĚ,]%zGŕ7˝îúÉJŇsU>UmI‹Óě°ý;Ą˙ĆÍĚĚ̆$¨u("&Ű/¦M Ŕą’ŽÎ/•ŐščŚC€ď’lwŇeKŕ!IKä‘«H:ř=ÉB'ü[ŢĆŰG™™™ŮPçµNEÄűŔŔż2Í'H:Ă«űZ)EÄą$|śi^ xTŇ:ů¤š$ “t.ý0é9ŕ+ńßśb™™™™•Ś Ô:Żë2Í?.“Ô”O*«Eq°đj¦yŕnIßĚ'ŐĐ’îsz5Ž˙°ADĽ‘O*333łŇrZçŇžÔM;3Í»7Iš#źTV‹"âY’~Ę4Ź.÷đň™KçěţŤd^o—[Í#âĂ|R™™™™•ž T#">ţ¸2ÓĽIďÖ|ů¤˛Z”~ ˛py¦Y$ĂË/rĎýŚ$-Ü lśiľŘ."¦ä“ĘĚĚ̬<\ QvÎĚ4Ż<(éËů¤˛ZS#bwŕř^wíÜ)iŢbU%IKÍ™ćÓ€}"bZߏ2333ş\ Út骫?¤çľŠË‘¬¸şrN±¬FEÄ1ŔžŔÔLó†$‹'-źOŞę!iIqşTÚŔaŃâ}NÍĚ̬Vą@µDÄ/IbéH›î—´~~©¬EÄĄŔć@vÚĄ‡%mšOŞüĄö{€Ó¦iŔ~ńëÜB™™™™U€ TëSDü Řř$ŮăôćüR™™™™UŽ T›©čZ=ô?iÓpŕĎ’ÎđŠ«VJńÉ"çőşë0ŕIŁ+źŞ2$Ť”tpÝŻËoFÄĂů%3333«,¨6Kń$°đR¦ů‡$‹'-Ő÷ŁĚ."¦EÄ$Eig殯÷JZ8źdĺ#i9ŕ˙łwßarVĺÇżwştAŠ€4A!HŻŇ‰ô"HQTA‚áHS"ŠŠH•ZčHďÍ€ UŠô^¤%!ąś3ě»Ën˛;;3ďÎĚ󹮹föĽíŮdwgž÷śóś»Ý ÍŹ+ĺµcC!„ÚF$¨ˇWl?KJRo*4/üSŇVĺDZU.´iţeŲ¤ żK•UíIÚx(~O7‘zN_('ŞB!„ňD‚zÍöŔÚŔatônÍ\ édIĂz<8„>˛})°đrˇy^ŕvI•UmHšFŇ_€s€ésó$ŕPŇśÓ·ĘŠ-„BˇL‘ †>ÉkĄ ¬CÇĽT€ź–Y¨”ŔBK˛ý©ÂďŘBóôŔĺ’~VNTý#i1ŕ`×Bó+¤Äô0Ű“ş?2„BˇőE‚ŞbűF`8pCˇyiŕAIß)'ŞĐŠlż¬ \Qhü.÷Ü.'˛ľ“´p?đőBóuŔpŰ7uT!ÔФAäWSé.MS·ë qe©¬qu»Fˇ%E‚Şfű5`=ŕ``bnž8WŇ)’¦.-¸ĐRll ü®Ë¦źWJšńóG ’¦•tp&0]nžüXßöëĄBh/ß÷ đ0i§Úˇn×1; ţY·k„ZҲÍ-G§ĽčB+±}ФgHI_Ąçôk¤ ż›Řľ§Ľč:“´3p2P\Ăő*`Ç(„B(Íôă˙ʆ, Ú ó¨ĺÔU^4ĘKŹ;·vç!´HPCÍŘ~CŇŔţŔŻH?_ÓgKZŘ;Ő ˇ_l_'i%` 0nţ"pł¤ťl_PZp€¤™€âđą ŔŔq¶]J`!„x!Ź6×Řa›€×CZ€I™eżO‘Çíáăď¬É9Cm%ÔPSů÷ŃyČďąŔCŇĐFĹ"i I·gĐ99˝ X:’ÓB žÉĎ‹–Eß|-??3Ů˝B-+ÔP7yŽÝŕ§Ŕ»…Më˙’t¸TÇ÷ˇ-ŘţŘ8˘Ë¦ë%ÍZĎëKš^ұ¤µZW+lzřˇíMmżSĎBˇćç5Ą9KŤ¤7Fi©b;Ŕe†B(O$¨ˇ®śś ,F* T1 8xTŇR‚ -#˙śLJJÇ6­Ü-i‘z\WŇŔcŔH:¦L8 XÔö_ęqÝB襧HĺţÎ(Í^r<=Ąa¤ąűK+7 BYbjhĽfꎒNţ,‘7-\!ér`ϸLHh¶Ď’ôp Pé9]”¤nnűćZ\GŇB¤ĄnÖď˛é!ŕ'¶Ł0Hˇ|#ý Ł´p+i:ÄŁŚŇeŔŁŔ'ĄĆÖa0i®ősŰ~ŚôsĄEB(U$¨ˇˇlßš—ŁŮ 8„Tĺ`c`mIGŁlŹďé!LŽíŰrń¤+éw53pť¤ÝlW}W^ŇÔ¤*Őű“FTĽüp’í‰Őž?„jn¤ďb”6NľL*ZŘo§Ţ/sLŚé‡Mů^x؇‘>µ&g !4ĄHPCĂŮţ%é<ŕx`ËĽiZŕHROëOmßPVڎąŮţʤ‹I˝*Cž–‡űŘץ^ňJżľŇeÓąŔ>¶_égŘ!„P#}Łô5ŇüÎHÇŞZVfüD´ýßůę ď1ͦ_ăˇ×?€e~ÇŠGmŔă;,ĂUFř2pp #ýj•ç!´HPCilżl%i=ŕ$ŇPLH˝^×K:řąí—ËŠ14/Űďäź­S€] ›ö–´íʧtIóż6ď˛éq`wŰ7Ö*ćB¨›‘ţ8;?Ş"iŕB`4°Ďl‡¤#/¦ůw<Ź‹v<Ź{€ĂlÇ1!„ŞE‘¤P:Ű×’ĘĘBç91ŰOJ:Vj‚ęaŔ±=Áö÷ýHĹ‹*¶n™ÜĎ•¤/I:ž”“ÓŹ€Ą"9 !´ I‹·çŮŢ«8ťÁösŔ*Ŕ|ŔI3—eˇD‚Űăl˙ŠT<éʦéHRź•t’¤ůJ 045Űdž’Th^¸WŇ’Ĺ}%Í/éŇ|{‘†žW\ ,nűč'Bh’Ö%˝7ďŢSurŰźŘţp9pg®7B} jPl?c{°đߦ©Ý§%ť&iáR MËöh`u 8Wt^ŕvIJZTŇé¤%vŁs¤g¶7‹JÓ!„v"é§Ŕ(`˝ŢTB·} °3p¤ë]ˇE‚$Ű— ?ţSŘ4đ=ŕqIçJúzń…ćdű~`yŇr03cHë™îDçąůOß'­iZěŮ!„–&i¤?«ÚţĎ”Ž©°}iČďÎ’ţ ih˝â !´žHPĂ€e{|J´(°=iݶŠAŔw€‡$]*ią2b ÍÇö ¤NwšE犖Ű‹Ů>Íö„†BĄĘsHŻĆ‘FŹĽ××sŘ~Xř¸YŇܵŤ2„ĐŞ"A ží‰¶ĎľNú{_ał€MHs Ż•´Z1†ć!iuRĘ•»Ů|iMŢá¶Ď‹J”!„v“‹!ÝN7Ĺú*żď ü–TnŤ…Bha‘ †¦áäRŰßÖné˛Ëş¤7ŔŰňň"!|FŇú’nn&ÝŐ/ş XŰö ¶Żčë©!„Đ $­ĂŠ!UĂöEŔ·“$íS«ó†ZS$¨ˇ)ŮľŢö¤^°«şl^¸FŇ’ö4[Ă ‚¤9$í%i,p5égŁčJ`%ŰkŮţGă# !„!C:Ž^Cę+ŰŹ++Iş@ŇôµľFˇ5D‚šší;mo,MZ<Ľ8$siŕDŕeI—KÚRҰîÎZ‡¤©%m#éJŕ%ŕx`©Â.“€ HĂxGŘľ«Ś8Ca (CA‹!ő•í˙ŮŢx€´͢őşVˇyE‚Z‚í±¶·N>-lžŠ4´čBŕUI’ÔÝüĂФ”¬&éTŕUŕ<`C:Wäý”ôł±¸íml?ôů3…BűčR iŁjŠ!UĂöo€˝«$mŢk†šG$¨ˇĄŘ~"/>°/đŻ.»ĚDZşćvI˙‘t¨¤Ż4:ÎP’‘t8đ iNň÷/tŮm,đs`ŰßłýDĂ !„§P éüţCŞFžV±°ź¤_KÜČ뇮HPCK˛ýŠíQ¶—$ ő=x­Ën ‡OKşCŇnůnrŔ$Í*é'’îžćď˛Ű+¤…ĺ—´˝´íămwý˙!„¶ÔĄҟˊ#/űµ03p­¤ŮËŠ%„0pD‚Z^ţűs`nҰĎ󀏻ě¶p đŠ¤‹$móUŽ<Żt3I—/'ËwŮí#ŕ`}`^ŰűÚîÚBm-Cú-u*†ÔW¶ÇŮŢ ř;p‡¤o–Sˇ\C¦ĽK­!_ş¸ZŇŚŔVŔŽŔޤőT†[äÇ'’î$-Ar#pźí Ľ IšŠ”€® ¬EŞüŘÝ “–Ť9¸Řö˙c!4ICH…ViÔ|Ó޲}𤇀żK:®ĚžÝBą"A mÉöűŔ_żJšŘ!?.ě65)9Z 8ř0ŻŁYIX˙Ůč9;­*Ď=ú˙Ţ+ÓMćÇł€łm˙·ţ†BóĘÓW.%Cď]¶´p®¤ĺIC?);®BcE‚ÚžíçH čá’V$%Ş#€y»ě:iřčúůë÷$ÝBGÂú/ŰnHĐMN’€%éč!]ŤĎ7ęężŔŔ™¶ď­o„!„Đr1¤ŃŔ ÍĐ+iű-Ië“Ţ—o“´ĄíçËŽ+„Đ8‘ †P×ÄĽ ř‰¤…ččŃ[ŁËî_6΀7%ÝLNXm?Ţ ›@NHĄăßs `Ö)ö*É˙Ť¶ź©gŚ!„Đjr1¤??°}SŮńô–íIŔ/%Ý Ü(éǶŻ+;®BcD‚Bl? < ü@Ňt$X«“ŞÍl™HzźTeö ŇÔĘë§ZuČ’¤iHä#%¤ĹÇ S8ümŇ|ŇJBúXý" !„Ö&iwŕGŔúůý¬éŘľLŇż‹$-#•Bh}‘ †ĐK¶%Íßů˝¤A¤ĺk* ë*Ŕô]™X.?Š&Iú/ ëg ¬í—ę÷ÔFî ť‡Ď' ‹’ÖźUĎGwň?ŕV:zIĘwÍC!Ti Cę+ŰOĺy©§—Jڱٿ§ÂäE‚Br"ő@~›«Î.GGÂşÝWť…´ĽÓüů±^q¤€'IIë“Ŕ[¤D®ÇG+ çŘgÂc6`Rş}›ú IDAT“/`Ô“O€;Č=¤Ŕý¶?íOě!„:4K1¤ľ˛ý!°­¤˝»$mmű‘˛ă !ÔG$¨!Ô@NďĚŹ#ňěéčY,yťÜBäÓ“ŞŮ~Ł·×–4ŽŽ„uƦĄ$ý5żž\ňYëő^ß űˇÍĎDBBőŃlĹŞaűxI—I:ČöąeÇB¨˝HPC¨ś=™W·Iš…î×…€©Ş¸Ü°ü­KűśŔ.UśŻ7&ćç~.µývť®BˇÍZ ©¶o•´*pa^ŠfdÜü ˇµD‚Bĺ®R-ř3ą×u:×I=˘]{<§/<ŞQX“€č~ńŔ{Ŕłt$˘ĎĆ‚B(_+Cę+Ű/KZř-©ĘďÖ¶_-9¬BŤD‚‘ľ§ňcĚ”öĎĹŠ¦Ąűa»Ó^Cωge뇵ü^B!ÔW«Cę«<µfIŰ·KÚÉöeÇBčżHPChRąÔţ‡ůwŽCˇM´j1¤jŘ>[Ňż€ó$ýŃö‰eÇBčźZ  !„Bu&iŕvŕBŰ?kçä´ÂöCŔŠŔş’Α4mŮ1…Ş j!„B´6pđSŰ*;žÄö»Ŕ·IĹ ď”´PÉ!…Ş j!„—‹!O*†ÔŇ•z«ĺä0ŕ@ŕ:Iß.;¦BßĹÔB!„*C:´YŰCކí«roóE’ľ b{RŮq…z'zPC!„ \ é`"°a$§˝gű`eŕËŔUy ňB5„Ba€ÉĹn#CÚ3Š!őťíŹmď\Ü%ié˛c !LY ń !„BŕłőĄgćľ”««KZxx)?ż Ľ”‹óÔ:޵S€Ä|Óţł}˛¤ %aűô˛c !ô,ÔB!´I3#Hó;çć¦ęá5z8ĎÇt$¬—·ŘžPe\?~L*†ôt5çźgű.I+çKZŘÓöř˛ă !|^$¨!„Bh ’ć66Ö†Őŕ´Ó_ÉŹUÝw%]EJVݶýA/b‹bHufűµÜ;ýŕVI[Ú~±ě¸BťE‚B!„–•çrnFJJ—4…C>^ĄŁWtnŕżŔżH=¬s‘†ţÎ|‘î?KÍl—ă$ý”¬^nűµnbś¸xŚT )ć›Ö‰íO}$mCJRżèCX"A !„BË‘ôŕH`kzNJ_.®'%ˇ/Ż—$‘t(đ\wó% f'%« ‘† Źf-ě6 Ř0?N”ô{ŕhŰďäs,ŚN˛}J•ßnč#ŰçKz¸@Ňé¶Ź-;¦B j!„Z†¤ŮŃý|ŇGI˝™—Řvµ×ʉěků1–´îć``5RŻí&Ŕ|…C¦öv•ttŽĺDŕ‡¶o¬6ŽPŰŹJZ8CŇEŔ÷l˙Żě¸Bhw‘ †BˇéIšŘř0c—Í÷—ÚţO=ăČĂsoĘŹ=%-C^Ľ-iž*ŔĚŔ1Ŕŕ ŕćzĆzfű}I›ű“–˘ŮŇöăeÇB;‹uPC!„Đ´$ –´+đpť“Ó‡Hs:W°}\˝“ÓîŘ~ŔöÁŔb¤^ÝW ›§"ě+iĂFÇ'G“np\%i‹˛c ˇťE‚B!„¦$iRďč_H…‹*žvľaűęBűś\śç|ŕqŕ. XĄ÷ëŔ•’.’4]ń°}=i9ˇý%“‡k‡,ÔB!4IË÷Ëšßöµ}v±ŘQŮr1¤Ű lŻDîű[`\a·-€;$Í×Í)BŘţ/° 0 p}žÓBh HPC!„ĐT$mÜĚ™›  |Ĺö ¶Ç—\7$} ¸ ŘłR©×ö[¶÷!lŞX ¸OŇĘŤŹ4Řg{Wŕ\ŇĽÔĺËŽ)„v j!„š‚¤A’~ śEZľŕ#`+Űż°ý~yŃuOŇO€ßtW©7÷ŘmJJ´ćn”ô˝FĹ>Ďö_HŭΖôŁ˛ă ˇ]D‚B!„OŇ ¤žĆý Í/+Űľ¸ś¨z&i¤“H|WµýTOűć"=‡[ććˇŔi’Ž‹ąĺ±}°"°Ą¤żIšşěBhu‘ †Ba@“47©°Đ· ÍwËŮ[‡ë­#IÝ´ÉĂu‹mźű,%i&ŕjRŹč¶ßíÍus˘˝2đ|ˇůçŔHŚĘcűM`=ŕUŇáů»î#ixĂ ˇeE‚B!„KŇ4ŔeŔ…ćÓ5mżV§ËnüSŇ‘¤ »«H:†TwµBl_öčď¤bHŰŢ#Ż‹Úk¶–Ëç¨Xřk5ßH¨ Űm@ZĘč&IëwŮĺTI_-!´Zβ!„BŚÓé¨Ôk`_ŰÇŐůšg»‘ uuVáőQŔÜŔ đY1¤??ěnľioŮ~CŇZŔ)Ŕ.ąy;IŹÚ>ŞÚó†ţł}‰¤IZŽ”°ÎAúYů#i™šB?Dj!„$I[šm@rŠí;§»Ůt—í§slË;kKZRŇŹI‰j·ĹŞa°+0şĐ|„¤Mú{îĐ?¶ź ÍKý:p9đR§Ďę’v*3¶ZA$¨!„Bp$mVhş8Ľ!ś5…¶HźŁ×*ń®2ąbH}eŰŔŽ@ež­Heż^«k„ęŘţŔöÖŔŰ@1)=VŇ,%…BK5„BФĄHĂl+…ŠvÎ [ŁśEDz/ăós|Ű’ŠUĚEJTkźíM€×sÓôŔĺ’fŻőµBďĺ‚Y{ŰwŮ4;đëB ˇeD‚B!„CҤa“Óĺ¦WMlÔČ8l? ÜVhşŇöŰ’¦Žéć5G%í'iĆÇRY+u|nš¸XŇTµĽNčťü3zđ[ş˙,˝«¤•U­#ÔB! $góĺ×ă€ÍlżXR,gvóz?`žnö}¸¸ř ÖŘľřQˇiURžĐ`¶_·˝°,p4đD—]DŞęĹHC¨Büâ„Ba@´°nˇé¶ď®ö|#Ä``6:† ÷É’śvëĂěň)hü*ÜűŔ—őŁeAtŚäŐřÁLűŹiřňĹKňçëgfĺJç#şżâÄ1ćŤjb°ý7I_#­Ť đ3I°ýüäŽ S0JÓ3ôő0ËKŔ‰Ŕ‰›źÁ˘w<ÇFď|ĚF&˛8đŐ™¦á/ŚŇUFeŕMFöm™˘ZA$¨!„B(ť¤A¤j¨gÚî®PŃŤß'UŔ]¶Úćĺ{<ËoĆCľŔ˛˙}‡]3 «0;1'[ťŠ™66čClď÷ÇŽ1×WÖľ¤áÄKĂH˝¨;Tqžö6JC퀅¨ň&FĹčB™¤§ß„ßß˙xŠť_x—ťçť©ęÓ~Ä(ÝĘHßÔźřBh&‘ †Ba ŘžŽuGÇ÷ő#ÄL¤jżk×*¨Żr,S1źđ"_d–ăr¦aţţśrf``ťâOŔOĆI˝=Řö$I*|WŇq¶ÇNî¸P0J37“n`ÔÜBłÁ y1 Iý+›5-°đFé˙éŇÚB$¨!„B(•¤©éĽ„ĚÉą0P_ý”śN °<T=Lr–45óNX´˙«ÜL ľlě<™cí5Ű×JşX‹Ôó÷`˝ţ×FN %§ďż®^®Ç…Uß/;XŘ ŘřŁtGô¤†v j!„ʶ…‘ŢŽęë Fum󗛌1W×&´yksšä]ŕŕęâ`RrtäqţóRϵp/)A]WŇ:¶«2Ü^Fi>:†DoÍH_[f8Sp p Łt°1ixw$¨ˇĺEßB!”FŇĚ@±ĚolżUĹ©ľťź/­]rZWG˙¦ÖčëÁ¶ď' g®řŤ¤~ÍŁlËćç§xrZôűüĽěd÷ ˇED‚B!„2ý’4/Rďâ Užgéü|Kż#j€1f"pkţréÉí;źα]ăj•.ńgJŤ˘ožÎĎł3JĂJŤ$„5„BĄ4Ś4łâPŰUyşŮňósý ޱ^ĎĎłMvŻŘ~ řKˇégýލő5{/słÇÂE‚B!„˛¬ Lź_ż śVb,ÍęÂëe%Í]Z$!„P‘ †Bˇ,›^_aűÓ÷ ݲýđĎüĄč‹BM)ÔB!4ś¤AtN¦.)+–Pü·Ű¤´(Bˇ"A !„BVľ_Ä)Ő+&¨kIšˇ´HBˇźbÔB!”ˇ8Ľ÷Űź”I“łý¤˙_†ëÓy šĐK;tZ`-`8óŁűk<đoŕF˙ú”vˇÝE‚B’4 0C—ÇĽŔÂŔ,ŔL¤˛ô•»č˙ëćńA×6Ű7î»!´ąb‚Ă{űď`d~˝ ‘ ö™Ć] 8 ŻN—ř@c‡îíáăO­ÓůCh ‘ †0@HšX4?fäó‰čôŔŕ:Ĺ0‘îŮ÷€gÇ'€'lÇ]ŕBU$-Nşˇ0¸˛ÄpZĹĄt$¨JE§zOc‡.\LGŞ(} éýŻ†Ë“Ţ×˙˘±C_÷đń—×čÜ!´śHPCh IC…čśV^Ď<™Ce0©÷u¦)í(ér˛J!qž¶=ľžA†šŢ…×7Ű~·´HZÇ]Ŕk¤y˝3“ćřŢ^jDÍĺpRrúO`˙V-O®±C§ţ|85„D‚BHšř*źOD v˝źčÜÓ9#ť‡%ý>·Ăç{a»{LŐÇëW>­ĐĄ}˘¤gů|âúoŰoöń!„Ö´`áu$Q5`{’¤;ÍrÓ‚Äżm_¬śźŻur ŕáă'hěĐ}I ę‚;tN˙j­ŻB+5„4 °©°ÂZ¤ä´Ż&ĎŃ‘Đ= ĽE÷óG˙g{\—öŽ®|m{Ď>~Ăč9yť X„Ž„{~z®>ÔKĽ°Q—k< Ü·Ř~§/1†ZĆ\…×/•EëyĄđúKĄEŃśľśź«×<|ü+;ô=ŕ ůz‘ †ĐŤHPC¨B.áż éR¤Ň{Ł84¶8D¶Ôˇ±9áGš{3Y9™]Ž„µřÜđŕ%ňc`’¤7‘ÖŰl×jľOa`+&O/—Eë)ţ[F‚:°őö3Cm'Ôz!WÍ]‰Ž„tY&˙űcŕ)ş™ŁiűŤúF[9™}$?:ÉĹžŠsk+CśżBç7äAŔ2ů1řTŇ˝tô°ŢËN„вŠ=¨‘ ÖNô †š^$¨!tCŇT¤Š{•„t`Řű7)±ş‰Tôăíş9@ĺ꾯·Ű» ^XĽËˇCH7V>‘t ë˝Q‘2„ć'IŔś…¦â[;ĹdîҢ!„~5„,WŘÝŘXv ‡@¨ŤbÂ˙rŹ{… jhZJ6—t?p5)-şŘÓömßĺö[ź“[lźÔľ-p]—ÝV®‘tź¤Í$uW0+„P¶'ŇąpO 󭝨Bhz‘ †¦#i¤€G‹e ›'KŰŢŔö…¶Ç•g(źíŹmźg{=`iŇĎƤÂ.Ë’ćłţKŇw% .#ÎÚP ó­Źb‚=¨!„¦ jh’†Iúđ$©¸ŃW ›?ÍmKŘŢĘöŘ2b —í±¶·ľFZŠfbaóŔŮŔ’~ ih1†ĐFŠĹ{"A­ťâBhz‘ †OŇt’öžţHšcX1ř°íťl?^FڎyŘ~ĚöŽŔ"¤ąÉă ›żüxFŇ^’¦íî!„~‹Ôú!ľ!„¦ j°$Í$é`RUÖQt~ăýřđŰ?˛ýl1†ćeűŰ?$%Ą'6Ď <'éŔĽtCˇvŠÉÓ’ĄEŃzľ^x jˇ)E‚IňPŢgIKÂĚZŘü>p40żí˝mÇpčŰ/Úţ0?đŕ…Íł“–®yFŇ÷ŁR5ssáőF’¦*+V!i!Ňt€ Ŕ%†BU‹5 (’–î& ĺť©°é-ŕ`ŕ˶´ýFwLJP-ŰŻŰŢř2pU—Íł§wHŢđŕBh=·‘ţ®Cú[żz‰±´ŠM Żo¶Ýu™­Bh ‘ †!ç=¸X®°é5`$)1=Âö»ĄÚ‚¤!¤Ó {ŘeEŕ~I'Hš±q‘…ĐZňR3c M›•K )ţ^VZÍ«Rá}HťŻS©?q˛{…ĐĆ"A Ą“´đđ:~&''Šgűòâ íAŇ,ŔµŔŹ»lú©Gżňáe0°'©âďvŤ‹0„–SLP7‰!ôŐ“4'°Bˇéň˛bibOäç&»W?hěĐŻÓ&­HBčF$¨ˇ4’ľ&éVŕt`ŽÂ¦;elďC”B#Hú*©÷~­Bóŕ‡ą×O€ĺű ŰçΑtc>>„ĐK’6Ž*4ÍMçŃ3ˇo6¦ă3ݶ_(3&u}~>Lc‡Ö|*‡Ćť8%yź‡ŹŻÖסUÔ{Cź#izŕPŕgtţ|Řř›m—ZhC’6Ί•zß¶°}kĄÁöý’V~Hú`=sŢ´&đ¤ă€ĂmÔČCh>ůfÎńŔzŔ˝¤ą¨«ćÍ›ĺ¶Đw1Ľ·˙6ćÔءĎÔčÜC…€©HK›u©B(54”¤­ß’î–WL" 9ŔöŰĄÚ’¤˝céđ(đíî–.˛= 8EŇĹů¸‘>těl'i/Ű—Ô=řš¤™H7&w^vÎv¦s‚z@ á5µ<ľ8ú#†÷VÁĂÇż«±CW!}Y›´Y­=ěâáă¬ĂąCh‘ ††´p°N—M?¶wÍCĂHJšWşK—Mc€íl˙ďóGuČU¤w–t*đ:Öś-é*`ŰĎÔ6ňš‹¤Á¤Q‡“ćŢműĽý RÍÁŔ˘’Ö°}sIá6«]H=tĎŰ[f0ÍĚĂÇ?¬Ł±C熓~fka<đoŕ #ÄB‚HPC]IFZf_:Ţ@Ţţ{ĄBhIłŁUşl:†Ô‹ßëźGŰ·Kúi¸úˇt|ŮXKŇŻIĆÇ÷;𚌤µ€ß‘nŕŚFv™`űMIW’ćPüšę‹Ô|śźg©ňř2L›ź?žě^=Č˝§ż,4ťŢ߀xřřËŽ#„vE’BÝäEĂď"˝y“Ó3EmźÉih$I_'Íq+&§ă€ťlďWÍĎŁíOm,\XŘ45)i˝]ŇŐGBs‘´€¤ŃŔ?HŐJײ˝EwĂćłčXrcyI[Tyé‡ós3[Z6??<Ů˝z¶/0[~ýp\ż#j}ďäç/–EßT I~DzĎ ˇĄE‚ęBŇ6ŔŔŇ…ćG€Őmďdűőr" íJŇ&¤ Ńóš_Ö´}fĎoű%Ű[“Šż??Ľ7N¦n!Öˇ÷9g„2Běśź›ÎcŞ™7ú¤ďŕiŇšÍaĘ&-68źQZ˘äxz6JĄ‘~Ż Ť@ ˇĺĹÔP3’. ¨xŘŢöőÝBýHššT‘ń»]6Ťv´ýa=®k{đ I7“>PĚš7í¬$iŰ˙©ÇµCh¤ĽôŇ Ŕ7k˝m?Ö×óŘ~YŇńŔąéPIg÷e٦1f±#p#i¤ÄuŔ#Äăt !|4µuţú1Ňß…>Éď·?(4h{B˙Ăk#mFéűŔݤQ^Ź0J//÷÷Ô“Ě A˘VS—†¦ŽTnB\OÇ:Ş!´´HPCMHúđg`†BóMŔwmżRNTˇťĺáo—ËwŮt8pH#ÖÚµ}•¤á¤uV+ó^—! ůÝŐö…=ÂŔő1Ď‘ć?‹tóç)`„í+űyÚß*ţÎĚE*>vt_N0Ć<áFń4G-@J$÷N¬Eďťí÷%Nę‘řĄ¤+m÷©€Đó°Í1=đ `Ňď]ŐŢâ¦^áÂÍĘçÍĹÖ˙ěÇ©&’zMcŞú7ËE¤¶*4ý˘ń´Ż‘ţ7°Ł4é&ĆLŐžęÔ{Yíź/±ţËpň óńRŤ"4đ,p?#{?’ „V t"t\LÚźÎwC—ŽőşšW^Űô`©Bó«¤^ÓˉŞ}uýý˛]ź{ąś¤­HsŃŠÝ/›Úľż” 2Iëgłš˙ lcű©îŹ a`Fóî,˙í^ŕK|ç˝—řű"µ.x—çh?,›ž'Íٖש†¤yË3m_R ĂIĹ *Ă>ÇŘţv±„ĎÖůý-©îŔV¶ß*9¤m„¨ŚŞ»gŚ«^R*4 I§ĐąkŰźLé¸W< 4IŰ÷Ó99˝Éi(C.Ôr(©đH19˝řfŮÉ)€íkIs´o)4/ <‡É‡0ŕH.éćOxńoÓ0«p?Ă9çŐzTcĎkď@ÖđeR±Ň‹‹Ů~X X[Ň)UV®š¤/’F†T’ÓWI•’C $Í \MŤ¸n$§!ÔN$¨ˇO$M-éOŔßéo:‘TMp=ŰŻ•\h[’¦%%¦‡Đy(ßąŔj¶ű]ü˘Vr,ß"Í!« ź87čťşÇCh Iłçż÷ LÍ<»¬Č­ĚŘiő°Úł}'ťď¸Ż üˇ®íĄĽŚËƤú*I_hÄus‚>/7Ť#Ť y±×ťIZŚÔ“=Úöî¶?-;¦ZI$¨ˇ×$-ÜC*bQń đ-ۇÇ|ÓPIó·ŃyN–lo×›ˇ$Ťf{˘íIk¦{ˇvî‘4_÷G†P’¦’ôsRńŁíÀžŠ—4*ۧÇšľ/égŤşţääßß=I˝™·ĺ÷Ćzű°Ráë]mßÓ€ë†.$mŚv·UuC¨HPCŻHZ ¸X˛Đ|°”í[ş?*„ú’´˛ś¨zĎö ¤aň7š—îđÚ|ˇeIÚx„”^ ,jűW¶«©4Ű_ż ˇ¬8NŇş%ÄŃ-Ű'ű×KZ±^ב´°sˇéŰg×ëzˇg’F’j=¬cűć’Ă ˇeE‚¦HŇę¤9ss榉Ŕ/őBáŠĐž$mÜLÇĎ%Ŕ•m7¬§§żlż ¬MꥪŚB‡Ô3łRʆPC’“t5))}źô{ôÝ2‡ćQ9ß!M ś/©_ËĆÔ’í«MÓsm†š’´ pLˇi p@­Ż&OŇ0Ig– [ĹöłeÇB+‹5L–¤ÍI‹ŻWćŮ|Lš÷rT#Ö‘ ˇ+I$Mކ[śŻy'©ÚçCĺDV=Ű“lJ¦\YrffŕI#J ,ĚĎ9 IDAT´Xůţ^6ÎEšBHZ¸8Áö/ÚďF­*ÔĐ-I“Š2T~F^V(wŐCű‘4?©—tăBó$`_ŰßËËS4˝<§{u:ÖŠB>ř‹ň˘ ­DŇšŔŔ;€%lď?“źĽ|ŮŞ¤5Ť+~ ŚÎ7®J—çénCZ»őIłőő’ľLú?ŮĽĐüitČ35 4ôJîĄ?ŘÖöyeÇB;‰5t’‡OžüŞĐü°’í—VŰ‘ô»U†,^skI?hä5{KŇŞŔ˝¤ĹĐ+Ţľm{T9QŐO¦Ľ2©w«â7’Ž(=FˇůHZ@ŇĹŔŤ¤÷˙ulojű?%‡Ö+¶–#U“ŻŘ”TTěËĺDŐ™“_§’†"/ÖŰcóßąű輾řů¤›Ă/uT¨µ<ĽúHŕg¤eĘ(;¦ÚM$¨á3yťµsÝ Íw“ ĽPNTmëMŕQIHšŞž’´¸¤>Ý4ĄýMŇ.Ŕ Ŕě…ćg€m_UNTő—‹p¬Lę=©ř9p¦¤!ĺDš‘¤éóîÇ€5€źĂsé¦bűŇ÷P¬b»$pꤵJ Ş¶Ď ť#é[“Ű7'D?ţAÇß9ŰţNI”ŰR”T¨nŤ\Ä.„Đ`‘ $Í\l]hľŠ´ĆéŰÝę¨Rč(ŕqIűJš} Çô‰¤5$ť<¬Ü‘çzU{ľš.XźçČýř+0´°éfR—–ďŃĎU˛× %čŰ—Kš¶” BÓȉώŔ¤%[ţ,lűdŰËŤ®z¶?±˝i.zĄ`ĐěŔ?$]&ińň˘ë‡ëoś i×îö‘´é&Ô€ĘÍČĘRYG4$Đ|¶ÖűíŔm¶w˛=nJÇ„ę#Ô€¤9Hú‹wyĎ6±ýQ)Aµ9ŰĎ“ţO$-3đ˘¤ó$Ť4S5çÍKIě%é1RoéÖ¤9ŽgTo^Źô{ŐßÍůľ@ZNaď.›ţ¬kű­Z]k Ë#7Šs 6n”4k9Q….˙NŢEú˝~”ÔcşG+Ýp´ýŇßâÜŮŤ‡%ť&ižr"ë`ű)R…ßďJ:FŇ HĹw$Ý@ZO|éÂ!ĎÓdKeµIknŘŠÓFBh61L¬Íĺ;†× šŹö‹juĄ;T˛b(©Ç6Ŕ$I˙nĆoťć`IZ X‰´~[OE;>.¨&Č<'ňDRŃ•~“´pPś»5ŘËöIµ¸Fł±=^ŇvŔëŔžąyyŕvIëĆüP!éKŔŻI=í˙!ÝhĽĽÜ¨ęÇö’ľAúž·ČÍI7̶•ô{ŕhŰď”ăŰ’Öţ \#é=R¬Ĺůä€S€ĂÚéÜ@‡Wďldűń˛ă !D‚ÚÖ$-Aşc8gn2©"ęqĺE .N¦ëfŰ R!ŤĄşŮVq}®u™í÷¦Ľ[·vľIç^ŚŞä9dłšß¶jĆůrµ”oýLŇkŔ‘ąy1ŕNIëµĂçĐ3ISű†˝îü®UŞ[ONžš°Ą¤H7XWÉ›¦ö~ éŕBŰŹ6:ľÜkúMŇÇk‘č “ć˙˙2Şô6VžË"°0©×ş´›!„Îbo›ĘŻŁ#9ťěÉéŔ‘‡vŽnĐĺŞŢ›ç.˙:Ůëj•=śë'ŔµtNNź–o÷ä´ČöQŔ®¤^eHĹ<®“4_yQ…2IÚ‚TéW¤dgaŰÇ´CrZdűnŰ«›ţ=*f‘ô”¤Q’V© ·­IĂ$m(éĎŔË¤ąŤ»Ń99˝—´|̶‘ś6Vžq=éłĎú‘ś†0°D‚Ú†ňÚl×_ĘM“?»çŁBIŞžÚŻnVTă :nrĚ-ék}=¤!’N&őGu\¬`űÉ*ckY¶˙JZ'±RÄcnR’sRۤĄ$Ý\DZô›¶żoűµ’C+UŇüuŕ‡t¬'\±©§ů6ŕUI•ômIÓô÷ş’f”ôI瑦]\ üřb—]"-a2 ďáAňűÔŔ9¶ÖĚĂBhU1Ä·ÍHšŽTťwŃÜô)°µíkĘ‹*LĆMŔ ¤y¤őrN5oĐy®č^]š7éĂ9f! éíş<ĉŔĎăCĎl_žçĄ^HşŮ¸(pĄ¤oŮţ°ÜčB=ĺŠŢ‡“’ź—€mmź7ůŁÚKţŰńIç»nč¬JçĎ=łçm»–ô&©·óĄüür—ݧćĘŹ/uyž+źŻ§˙n _\d{’¤KË$-dűř}ëa2$m ědűö˛ă !t/Ô6’×ÓMZčŇÜ—]mŹ)/Ş09ůCĚ٤yeőRm/íoéĽü ¤őđŢś°ż‚Îş&»ŰţK•1µŰŁóĐčSrÓňŔE’6¶=ˇÄĐBäżá?ţFú];&Ş­÷,˙Űśś$if`CŇŕő »Š”`ÎÎäçö÷Ĺ+¤żq—˙čşl‰í˙JZ 8OŇ"Ŕ¶?­ŃµC’¶ÖĘ•ňCT ńmąŇęéŔş…ćýňbâa`;łŽç~ĐvŻ{<+$­|»›MKçZS:~}ŕn:'§oëDrÚ7¶˙DJX*ÖNËżóˇEHÚřéĆеŔb¶Ťä´÷lżcűŰ[“*šo@şąór /óoŕh``nŰ»ŮľŞ§55m˙Ź´4ÎŇš®'@Ň4’ΖVŤä4„/zPŰÇńŔv…ŻŹł}lYÁ„Ţłý¸¤{IU k­Ď7(rĺĂÉ G;Řy2ÇďMŞ´Y,ň(đmŰĎö5ž¶—ôE`÷Ü´=đ0˛Ľ¨B-HZ”ôű¶i)§Uchb˙ĺR×äÇŹ%ÍHšËýĄüčúz.Ň”®C€; ®ć†AŽĽ§¤ź·JÚÄösýú’ć.®ŤĺóBh‘ ¶I 2TśE*˝šÇÔ>Aťś[Ĺq?ľ:™íŰK:"/ýđIC?’ć{Ť¶Ë= ˇz{’†'nťżŢGŇ«±č|s’4©gü§ŔۤĘÍł=©ÔŔZ”í÷÷é\ý·Ń1ś$é?Ŕ ’v°}WY±´IËçűŰľ¨ěxB˝C|[ś¤]€Ł MW»Ä]ĦsPë%#®¶ýF_ČĹY™ÂnIŐ}»wźONŹ6‰ä´˙râ˛đŹBó1’v()¤PI$í‘ ¶°\­îĎ…¦»I¬ŁC“±ý6©ŘF-U3˙řŇš‚S˛˝¤U$}ť´Ţߪ…íăHUşk'[Ü x 7‰4uň˘ ˝%i Ň0ŢSHŻżf{ßܻڄí«{I:¸ěxšIľÁs,i‰ˇUl˙łěB} j‹ĘÉÁytĚóű7°QÔhjµ,–ôihmŻINfŘs$m Ü Ě_Řö°¦ízj[ą7zŕ©Ü4„TŮwůň˘ “#i~I’–•š XĎöƶźšÂˇˇEŮ~XXRŇY’†•Ó@— L]ĚJŞÔűzÉ!…Ş j Ę‹P_Tôçíň˘ 5p5iń÷Z8/÷¶őʼnôíoĆ|¤ů?ÓÚĆËĹÜŞúĘC·×#-s0-©BčbĺEş’4ť¤#HóżEް”íëĘŤ, ¶?&Í)4/u¶’C°$- Ü\o{—*ŢßBH$¨-FŇ|¤%*Ă0ß&%§/–U¨…Ľ®ĺßktş> ď•´ ť‡čöúĐÂëѤ!W/TqžĐGą"ňúŔ{ąiVŕZI_*/ŞiŮŻ<7řI`ŕ4`aŰ'ĆŚPää@௤ żq“© Ië>÷ěcűweÇBčżHP[H^ÄýRY|€ŹHĂzK«Jj®Ăbł}_ow–4 ©Q\liűĂ~ž'ôí‡IëŐ~’›ćΓ4¸çŁB=Iú&péwů1`¸íÝmżUnda ł}:đc`ڤµJgŔ´'i¦őcäA­#ÔÖňk 2Ďl)!¸»ÄxBŤŮ~x¤ź§ékq¤ý€yűyÍőčýüŐPC¶o¶*•»W~U^DíIŇ—$ťA*~4;°™íµm÷÷÷9´ Ű·ć—˙^R[˙=•4TŇ©Ŕ†Ŕʶź,;¦BíD‚Ú"rĹŢźšËĺęC멦únĹ$ŕěŢŚ˙˘×űěTŔź$$)ţî4íKI7°*´^Yń´IĂ$<l,ž˙OBč“\8kURĄôc$iJÇ´Is–ÓzŹ4Jě˝)Bh2ńA±ä$âôBÓŤ¤ĺ@Bk:Xĺ±7Ř~©űŹ˘ŁŘV 8¸&ŔŤu0©¤˙‹łb>j}IÚś4Ś÷ŕbŇz¦ż¶=®ÜČB3Ë×%őÄ_,iÚ’CjIK‘ţŽýŐö>¶«}/ ! `‘ 6ą<ďô|`ćÜô:đÝX[˛uŮ~¸ľĘĂ{Ýű*iu`«*Ż39ëc%Ť¨ĂąCňąm7sÓěŔą1µö$-)éFRRú*°Ľíťóďnýf{Ľíď÷7Kš«ěęMҤb{;ĺ9ą!„ jó;X!żžlź×O ­­šaľ˙.éÍŽyî U\Ł·ć®t›¤jއ*äjŢ;Ń1u5ŕ°ň"j-’f“ôGŕA``{Ňü¸^% ˇ/l Ü’{[N®z}p°F,SB답‰ĺ¨âĽÓŁmWŰłšËĄt,Ň[ćuőză@#>ě¬BZ:á*I#$ mŔ5Űší«č\•ů€ĽLC¨’¤!’öžv&Ý8\Ôö9¶=ŮCč'Ű‘n†\Ôj#Sňđĺ ĹŐb™˛ÚC$¨M*Ď;=Žu&o)/˘ĐH¶?!˝i÷EŻz]%ÍDăç0o˙ĎŢ}ÇÉUŐ˙˝w“ I@Š „*R… ŇQ¤CXЍ "¨?D)Q©B¤)„&Eņ |) ‚ AĄ E¤JďH'¶źßçnöîf¶ÍÎĚťŮy?Ź<ćÎť;ç~f“ÜťĎ=ç|W/Hú•¤Mk|ţfspS¶Ýü¦†V¤í{IK]\ ¬GyI%«Ą¸ Ř 86»YŇđ˛ď97wGÄ1Łč̬6ś 6 IŁ€‹€Ĺ˛]/źu±€¦3”aľŹ‘nb Ć`ńˇ‡3lł€ë+; 8Ó9Ŕg€W˛]ďĂóQ‡DŇ%] ü™´Îěć±{Dđ5`˝řG±‘™ADĽ ěDŞô~Ą¤÷ŇIú2đ ŇZÁŞ›`f#‹Ô#iGŕÜ®©Ůś2kN âÎd{§µ¸ë>ť´ľę ±EDü<"^«Áy-'"®NÍí:\ŇÖEĹSĎ$µHÚ‡4ĎôŕL`•8×UÓ­žDÄÜ8čţ)éýĹF48’Z%ťě l÷“™Ă j‘´=çťŢLZôÝš×ůt÷€őĺ†řď@ IÚ…´Lµ<ś¬ëFÄÉYUY+ÖaŔ­Ův đ[ĎGí)[réN৤e=ÖĘÖ`jˇ2łš‰3I˙żŻ“´Ń@ÇIҢ¤áň〭#⥂C2ł9Amąy§ďÍv˝ |&›KfM*"3·tŔąŞ’Ć§T$¨ž^Î!-µ±RD÷WáüZŇEÇSŠ¤Ő€Ë#bźěšdfMĚ jă l’{ţĄ¬ ‚YĂwßapŐ~>P™px¸ŘűGÄMĽÇ ”öůRn×ÇIĂX›’¤ń’Ž Ť*8X;"®.62łˇ‹{IsĚ–tdŃńäIÚ¸ 8 "Î*:3«NP@Vjý¨Ü®3"Ⲣⱺó{R"ZĘĄńFoΆs1ĚćľděI*v´gD\ĺţĆ‘]SÎČíúľ¤Ą‹Š§J>Ć˝«ĚŕŃ÷÷őşhťÝĆĎ.ŔrO/Ŕ„˙VŽiL:Űć/Ď‘îć?ÜÔĽUhTőá›ŔV¤Ęµ«’Š´ťPhD$é¤.+żŤg‹ŤĘ¬¶"âzI“€?I:5"~‘]Ň7#âG}Ľ˝O’VŤ{íű p<𹸵ô;ÍĚ'¨uJŇĘŔwr»ŽŹÇ §píb ŕ“ŔÎŔ–Ŕb#Ş?ďeóŢ»ú˝+ľk±kőwČhŇM€†YC™Ů.ţ \\Ň4ĺĐĺřݤ)Ů®#$ý6«ö۰$}8ťôăVüeŮš\D<$éŁŔ%’>HşY’Ö~ éOńÔ`ŰËэȦ d#uŽ#UĂţXD'iýA6s8°,°đ]ŕFŕ–ř\DĽ[áÍls‚Zg˛;ާĺv]Ôl뵋ńŔł% ÇlIŕÜvqQ»[t0µ×ţ/vů‘¤†řHÚ¸‡4¤w©Ňá9Ćf}ű°<Ý5ś:Đ›$}8$·ë8ŕĽt¬™YĎA­?G“î@BŞĘzp±Ô\»X¸Xg€Cßţ°i~iŃ˝^Ŕý/ľĹ#?śĆZ—ßχy™´oý¦Ýpy^ď:h»U™tͬ °đĽ¶éűąçKë3ýSkÓ5úëSLÔâŮ˙îîarS}÷1łTËB†’ĄgÉňu#bzͨS’ÚHŐj»zMS5´]| (őE÷5`׎ŕď5Élžv±5p °P‰—?Ýô7/kD‘tđůěécŔ#bNq¬@rĽ;©çôาÖq4›v±đjöôÁŽ`µ"ă±!Ş•_›•óö§^#ţ ë/lšö=˙&¬q2|l%Ľ9lú~Đ rŃ~=|…Éáßű#P»X ćÝĽ¸µ#بČx¬ú$ý„´lU—±©ęíÔúđş“Ó×C ŚĄ¦ÚĹhJŻł6ŘĂÉ©­#¸®]ěIZĎŻ÷´ŰĹeŃ4ş&»’ć–­|–4°&˛őÍâ•=ţ("šĺço6tSµ.©:Z“ÖWtá˘ĺó?Űs_mĎÍě¶V*ŃÓ±<°&°20Ť©ú“㢠´kf Č jÁ$µŇ3!=3"ţWT<řéRo‡t©u0fĄtW´‹ĂôzieŇżáş™“YMńBv7tr¶ëpIż­E…NIź#­cş4đ ŕČhŠBUfe›ŞŃŔy¤ät:°7“ăŢJ4=ˇŤäMŐŔĎI—ÎaŞţÎäć)ifÝ\$©xź%€Tŕôc©©vŃJZ˛˘·[;‚3jŹŮN"}Áëíđěßrł8čžł°[5O&i}I7‘Şw˙X/"öqrj6(Űk3€OT*9­ŠÉńi9ŻEIKŢYr‚Z I˘g‚ö“&ë=ÝśŇ7ażSë@ĚŇđÝ/M>Zăp Ď“z0»QŤóHZJŇŻ€[I˝¦{DÄć®[`6$Χ19/2A™ďżËž•*śhfMŔ j±vV϶ß%őL4“O”Ř÷·Žŕ5ŹÄzŘB,°˝°…< /v~c‰—J­8’ťóćÝN”´cĄ–4&+¨÷0©ŇŃŔęqqĄÎaÖDşFhÝ_hCÓµ¤U©é?fÖüĺłXůž‡_F4Ý\‹]Kě«ú˛»…:á/‘JěßÝ=ދͧ]ěK*d0kl}q?ë°¶‹M€Sł§§w5+ôĐ.~GZÇîúŽz±­ťĹ‡;áÇăa€QĐŮ.ţś ŘëŠŕáJĆÝ`.6íµoŕŕb)DD<™Uôí‚w0ě*ş’v%ݨ[ ¸řnD<=ÜvÍšXWGDŐç‰WP×ďWw˘5)˙ç/¤I¤µű őDśT`85×.V »rq—.Żöą/ ŢŚT0bC`Ďz {gÇn|ô­Ëôoź;ľ¦‰ś``Ă€U‡úŢ]ÄŇťpYršiž X‚îĎ4®"Á6®?Á|U+WjKLN$UŰŘXŇ–ĺ6$i-Iב~¶Ż›DÄžNNÍĚĚšŹÔâä{OOI1–)±ď‘ŽŕŮť˙şěqü8Ř×AŰ‹Ĺ"-j0 v íÍłÇ—Ż„ /ĚÚé„Hsýt xm#8§ĐŔęLGđ i ĐŢ–Żu,EŠG€ü°Ű!ĎE•ô^Ig“ŠO­ | Ř "n®L”fffÖhś @ŇŔ&ŮÓNJŻ:Ň•*ŽT«äşTZć®9O+lťx—îáÇ}&¨“Äş ;\Q‘őájĄ+Áęś _č.ę®kňáĽ})őoµÔM—‘îş{“·”´ń`Ţ$i”¤o’F| |0"΋Fú?cfffćµůž†‹#˘€ĄKě«ŮÜqđw˛"/ŃO‚J® pK¤^E€5wË•:X)9“µŰP븼/Ű|ŕęŕ•B©Ąţ­6]‚÷—ĺv Ř‹*i[ŕŕ Ň˙Ă5#âĐxł:Qš™™Y#q‘¤“´°Uö4€ă §H‹•Ř÷R­N~qđV»¸•4ź´ĎU°]¶9m\7:ýťiNęE=·Ä[>ÖµŃ×öŐîÎbq`µ€Ą:áÁŕ;b^UÔůě.ĆΆ13`ö5ÁŰSDË­°±`ŃQpűeÁ |d¶ŁIóoy âÚŕőmÄ ¦‚QmŮgžů ±@×ůÓv—ĹR-éł-Ö÷/_óć*Î3IŚc&ÂGÇüE;ĐçÝ],8¦Í†WgĂ«cŕ+cŕ•Ůđ*Yěëv3:}Á”Ĺöíâ?‚ç¦ě„˙Ě€·v?Ţ])1îŇ ;uťçö´ü|ކ“şŽ™AéĎ8ľ—óä­0z°ńZeDÄťŔŐą]=zQ%˝GŇɤ¤tcŕŔD'§fĹŃô¶ĹI5Ž"ýżś,Yˇ?ËnÄź\Łém­µú\f62¸µ†$­Cę=čҬ˝§uA©‡ó€ÎÔ‹ÚŁđMgwúĘp{¶} ©úňÖŁó˝ž[Qă»çĎ7Ľ·]ׇӝśżüX‹ÔűöéVŘ|'ńą+‚ľľĽ·Ě„ Čík‹t·şOۉńŁÓ2 ›‘zżŐś™˝üižíxŇ5a.đéŔ{O%´#üRđĹ®}O)ÍÓ\X@đő°íŽâ“WFJň[ŕšąi9¶€mI?Űžmç×€-ß”ˇk Î?_Ě(^«Šăéţ˙˛›¤Ő€‡HËĐO1ńcŕčxµÍ,ç Rµ÷—Hu0¦Są›Äm¤b‡zgN®PŰfÖś ÖVľgáš¸Ł°HŚ·á¶ńđ&°P6µGňŮî€ksĂFŻ! ‰ZhBzĎő]ÇŹőȆšöžş“Ř“îż˙Ç;áóW7L-·§ęĄgfó@»ŤXőÚŕőao-%řđëlů—µ® îęësî,ĆŤNóg?–BăëŃ=<ą#xoă_¶ řוŃc©™~µĂˇ‘%§÷öĽ2¸ŇđŰ 09ŕX`%Áo?"&ŢĚľ,xł]L¶Ë†RŇëg¶ °F×sÁ˝Ď˝‹X:˛ĺš.lĚVYq¤ż“ľ”¶ľŚ.Cú»ą80"î/0D3Ëhz[đéěéçbâ¬ëú;ľL×jzŰk¤kÁŢ8A5ł!đß‘´ đÉܮ㊊ŒiÁśČLőZŰ4Žş)¤žľ®ýĎÁŤd˝‹ťóWóíŢ;łţѵs’đě雳aĂ®äŕč ł#ř…`Źl×’ ôÝ»> ţlEp~GpJGđĄľ>ăîbl¤µM?tüż|r:\“Ä‘z…žudÉ)ŔÁě+‚f»ÖĺščZ÷vÍIęą.ngwďéËŮăű{Ĺž“˛ÍŮłŕŞa Žü5mŇÍš]"b['§fueeŇt9¤éŐŇU‡aŤ~Ź23ëĹ jíěI÷Ďűö¸ˇČ`lž®;Çkvx'őÖµAĎőŽ`v6żőJPŐ˝ţé —3şöŹJű—8ĺšŕĹR\\©Ş)_ÝBĄG8śÔ_AĄ.»‹±3ŕňlhěÜ€˝® Îč}C!Ř…¬č’ŕ‹wJ÷ü„4ä“€}»öŹJÉ3-ioľímłăI†Lgú,ůcÚłc¦őŃăl5×÷fO[s"âň~ŢbfĹhËçĆÄYóž« ®)ţ®ifCâ‹Fíě•ŰţuaQXąBIš™ EtíďšOwďe1ßš—] 뇶SZšeŠh!ë…UŻá˝íÚnÍ%d}čZ˛Łm¬Tę€Vxp€6,đvňşuñWôľ2ĚűlęçłM ćĐÝĂąÂÎJ•y/ žó†'wULFBd±·Ŕ_7gç— fkÎnťí÷đŢúż¶íŐçQffff}p‚Z’Ö%´öćE†c9W÷“ŠůĐŇsoW‚:_áž–\Ú–Í‹Ľ Öčśż@ŇR]Łŕ‰ţâiÍj¬VęÁ`ÖÍÝ^ąIÁ—vQU–Aéúlo_ó†â–ÝźMsáą—şzٶÎ}v€‰¤ůµďľ7ćz–çÍCÍz¦ÇŃÚs-N+ÎoaŢR@ëIňĐ>333'¨µ±wnűŞř_a‘Ř|DŞ›Jb'± YďĄz.źŔÁĂdÉVt÷č},;ţĹ«ŕîüń‘­ő Ěą$č÷ď~Nn-XĄrý˝Í¸,xs R…Üó˛íćVˇH…ş?[ÉaË˝”ülęNP» Ö‡Ă}oĽKwO÷„ť•÷č®Ţ{[‰^n+@D—ŰuAQ±Xź®|dwŃÝĹyfĚ…’s…#ëYíšwŞl¨kŔµDŻcźĚ6GőµÎi—–lÝŐě}Ăą‘ńNŔ.YĄ®äîk;ŞôzŁĂĐőŮ–ę÷(@ąĎFwá#.ţ<ťł]öŘ• ^°~ü tĎCŤîů§Ţ[_ÎĎm^’Ď™™Ů ů‹CőmGZ:ŕUŇrVGZş¸ń3`uş‹]ß׺š­Y‚°J6ź˛äüÓlߣąígŢë-ë•,)ŕš+#őţ¶Ŕ>Š6 ~>IĽ§ÜvKčúlc»ćăö#˙Ů^ęőZ×üŐm˛ŞÇ›DÖ»}tĐ©îj“[µ‹ŐÉzą[ť Ö›K7˛íe)±<™™™Y_ś V_~xďĹQ2á±âdĂCďPbÚµ\Ě|Ă{»ĚIëÎZ:ag˛ÄŮ=‡7=çŚî6@8źĘg˙Lüą"F·‹ý€ßeoyŁ+÷ôđe·~ęĎ·QŞ:<—3‡dO—™··‹őş^ß]ŚÝQpz¶ëé€{·sU0SÝ?Ď®÷_—?&+Nő$@dĂć;=Ľ·^ýx<Ű^G™™™NP«-?´ÍĹ‘ęX \O˛ @ô3Ľ·KkŻÖz\o&UÖ]&ŕşᕝĿ–JóőÎ&ÖÚźľ<ş—›©”Žŕ>Á ŮÓeÇŔ©j÷÷'ť¤Ąqîh/¶‹é3ŕ Á1@kÖÓşkGđj©v:{-ÓŇ+A…î9©™gŻĘz…­ľDDĐóšçaľfff6(NP«DŇJdË–d~ST,6°lé–yÉNďäł”őҰݮJ»ď΀öw|GpzŔG€›HkE.°.)1}'ŕW-°îĺQş'¶Ʀőţěé˙›$v¨D»Wß>ÜKę)^XĽ.řŃ\Ři¨s)cŕ*ş×Đ|â˛ŕ‘‡ÍKZ.ď]1ŮęJ>AÝRŇ2…Ebfff cTŃŚ`ź‡4„¸1"íď`+^Gô¸ˇ0 lŘěâCyĎ•Á˝Ŕ¦“ÄĄŠÁ+´Ŕssál^k_±íCšÇŮŻ+"­Ú—‹YŔš}Ľw«~â>Źî5UűŠńźŔÚYUă5;ađL üg0óił5bű˝&]\\8P[VĽxXŇÍŔƤ›ˇ{’zÚÍĚĚĚúäµz<Ľ×ú”-_3=ű3˘dÉčíEÇauá|R‚ éščŐĚĚĚúĺ!ľU iŕŮÓ™”¨ZjfÖ~Gšw °¦¤Ś™™™Ő?'¨Ő±Wn»#"J…13ɲkßą]{őu¬™™™8A­–IąmG2łf–żNęó(3333ś V\V˝wůěéJ,•afÖDţJ÷Nt5_333ëŹÔĘŰ2·}{DĽUX$ff‹7éY4k‹˘b133łúçµňň ęß ‹Â̬~䯅[öy”™™™5='¨•—ďp‚jfćŐ¬žĚÎ[5˝­šßGgŹQĹsŮ䵂$­,•=}¸©ŔpĚĚęĹM¤%·VČćę›Y1!Í lZĹó|<{| Šç0łhTŃŚ0ůž›#âÝÂ"13«ń®¤›ča˛%đßC2kZ1qÖLMo»řp±¦·Cš'ŢYˇS´ŰGdĎ/ŞP»fÖ$ś V–çźZeMŐDŕ@`]`L™­ĽÜśČäxąRˇ™ Ńßč™ ţĽŔXĚšÝţŔz¤U~RĹóÜü Ší›ŮäµB$µ›çv9Aµá™Ş󀓳7Ëlii`7ŕ.¦j}&Çó• ĐlHţ›m»’ŻYbâ¬ç4˝mŕűŔÖŔű©Ü´Ż9¤a˝NމłfU¨]3kNP+g`±lű-ŕ¶c±F7U­ŔąŔ'7 łµ€ż1U/§źnxfe¸Ťtm\XJŇęńź‚c2kZ1qÖkŔ7‹ŽĂ̬7IŞśüđŢFÄś>Ź4ŘZŔ+HNó~EşSnVsŮ5ńźą]®ćkV}]k±/RhCłdöXî¨!3kpNP+ÇóO­’&ĎT´ĹÉń°SUî\Vłáňr3fµuwö¸YˇQ ÍFŮăż ŤÂĚ ă!ľ iđŃÜ.'¨VqšŢ6ŘX¸ŹCž®Š‰łćÔTE3Ľüµńă’^#ѬzţĚÖdŞľĆäřiŃőkŞ6>ź=»¦ČP̬8NP+c}`ˇlűU`z±Ř¤émÇű‘*">ŮÇa_ÎÖô¶Ăcâ¬ßÔ*6ł!NşF.Jšł?¸«ĐĚF˛ÉńSu2p(đ¦j3ŕŕA*·¬L%,O*žvé»éŐLŽKŠ ÉĚŠâµ2ň)ŻŹzşč[Óô¶‰¤äs˝8뱎ÝčĐô¶Kb⬵Ďl°"˘SŇő¤ő!];ť šU×ŃŔR¤ß#ź§»‡˛^Ý@ŠŐĚš”ç V†çźZ5}řĹ@É)@Lśu ©Íg«•Yy<Ő¬–&Ç,&Ç—€vRďéSGTĘ+Ŕ_€Ż›39^(83+{P‡I’€Ťs»¦‹ŤX+C8ţn`•*Ĺb6\ůkä&…EaÖl&Ç•Ŕ•E‡af6÷ ßrŔ¸lű]Ŕëú™™őí?¤k%Ŕ˘’ŢWd0fffV_ś ߪąí‡=˙Ô̬oŮ5ň‘ܮՊŠĹ†lVnŰËU™ŮP-Űž]XV÷ś _>A}°°(ĚĚGţZąjźGY]éfofO—,23kHËć¶_,, «{NP‡Ď Ş™ŮĐ<”Űvjcy&{Ű®>×d63+eąÜöó…EauĎ ęđ9A53÷ 6®ÇsŰ„™5¤ősŰO…Ő='¨Ă÷ÁÜö…Ea#YهpĽ˛÷Ő+'¨ŤëšÜv{aQY#Ú)·}MźGYÓs‚: ’ĆËçv=Ô×±fĂp#°óŽß´ŞY˝Ę'¨+Jj+,ŞËrŰ»¶ ˙ݙـÚŇHËć<ŃÜ]d/5ÓŘľEšß|88¬Đ̬®dsÔ˙¬íz8ą°€¬a8A÷ Z5}‰4Oă>¦ęŕťR˝3›ŃcGÓ_Żč{­€K3*ĄYy\É·uw´‹ýHsäm‹tDż×#3kYĎé%ŔfŮ®·€ť;‚7Š‹Ę…ç ŹT«žÉńđQ`_ŕ>ҢÖ=ţÜů4m~€e…™ßÍ*s;y±Äq×Ű19öcrtđIĚJq‚Úŕ:‚_gćv} ¸®]¬XPHfVÚĹŽŔmt'§ťŔžÁ˝ĹEeŤÄ=¨e’´ÝsgŃsńrłĘH ĺ?˛?=Hú4đ`Dü `EiYR2{ZDĽÜűxł:ó(©`W+°¤%#â…‚c˛ˇ;TôäĐěůÇ€ŰĹOw÷™™ŐL»h6ŽÎ»ĽěŐ\^H`Öś –/Ç˙‘peT« I-ŔŔMq{×ţxZŇ`˛¤kóŻ™Ő›%éqŕŮ®U'¨ ¦#čkwżĆŁoßhʤ: O‘Fux$‡Yăk&K&­×ţľ^Ç<|˘#¸ŻĆ±Ys‚Z>H˛š“´ p0đËxş÷ë1 8AŇg%­ÔZk0"ţ• ˇ™ĹË÷Ď‘UŃ;tc|¸®#đ÷ «˙’(_ţËÔ›…Ea#ž¤Og ő˝ńФďHúwD\WůÍĘ–żv:A:‚;;‹ŽĂjCę8řŔřö)÷Çäó ČĚ’‡ř–Ď ŞU•’€§"â’rۉÎ8h“´ź$U.Jłaq‚jfff=8A-ß‚ąm'¨VQ’ĆGŠŰ*ŃfD\ü"é=oVůkç‚}efffMĂ jůÜjU!i9R1¤S*†4Tńđŕ IkV˛mł2¸ŐĚĚĚzp‚Z>'¨Vq’6vŽŹŐ8GDĚ)Ŕ†’v«Ć9ĚÉ Ş™™™őŕµ|NP­˘˛dq™8k°•z‡#"~ '¨VY1¤ý§‡S ©qppڤ%kyn3ś š™™Y/NPËç"I6l’ĆG—WŞŇPEÄóŔ1ŔŢ’6)"kZNPÍĚ̬'¨eČ*¬ćvNPmČ$-  śOKD̉“Ą$}±ČX¬©äŻťc%µ‰™™™Ő'¨ĺÉßéźł ‹Ä’¤őé.†ôvŃńtɆß.é(Ic‹ŽÇFĽ·€ü|k÷˘š™™59'¨ĺńüS+›¤]ĺ"âěZCŞř7pp¨¤ŹŤ\Ůż˙ü '¨fffMÎ jyś ÚeĹöž«u1¤ˇŠ7HóR·•´}ÁáŘČćy¨fff6ŹÔň¸@’ IV é0੸µčx#’ł% É× «†ü5tÁ>Ź233ł¦ŕ/śĺqŞ š¤e€€3Š.†TŽř+pp´¤E‹ŽÇF÷ š™™ŮPr: Câ &Ç· ŢáT¶¬P„Öŕ$µAʎó^¶Ë̬`ٵůFRmŤÁż5đĽÔ@ßq¬®9A-Oţ. ýt Y &?);1ííŕx¸‘Y|¬"íŐB ŰŇÉď*Ú¦¸„ąěPŃ6­‘ĺ{OçFÄŚÂ"13ł.ß#BüŰ ŹżŤô}xjŐ"˛¦âµ نü|DóyVAÜSá6˘…Ć©t´ Ţ­p›ďâ©Ö-ítď©™YÁ$-  ÜJP#â ŕLŕó’>^Ĺđ¬Iř‹bůŢ„yUMž/0«Ľ:™  »Ű6 ř"ę)׳´´žkĎxşÄ‹ť„˙Ď™ĺxţ©™Y}ů08nď;88KŇÚŃYńȬiřËrůŢ϶Ý:BişŃWCśziŕwÄ&tÎąؤęÁ™5>'¨ffuBŇű€/÷GÄź‡ňŢxEŇŻ€€ťK+ˇ5 '¨ĺs%ßfŁÖAü;&Î>y0‡ëfýޱŁ=ŹÎlpś š™ŐŹýIŁSćűCJPżT'¨ĺs‚Ú „€ą>~&ÁŘę…c6Â8A5łš’´ đz^Ž?ćŽ lěH*ôpbD<Đ«­•]Öl×Cń§ç|/°'=§ ÝWőă'U˛§wDÄu’Ćű›em= \ śĂŞ!©ři-ó Ëi#"n“ô0°q6̷ҵ<¬I8A-źT3łáq‚jfµ¶2p ÝןŃŔUŔ$­ś¬Ľ\lě.i˸9×Ö¶Y[­¤%ł.ćKPµłăşÔ¶ě%Tŕ(`µě¸3%=üř0p7p ©Xç:ŔÉŔv’vŽwńůű˛1°$đŻxbí\ |ř$TĽŘ¤5 Wń-_ţËÔ{ ‹Â̬q寝NPͬę"bzD, DÄŔ´®×$íÜBęŔŮ»“’Őkéµ.hDś FÄXŕş~Î9-"ËťóŢbś÷8°>p'é;űJ±^D“#b`K`Cŕ×CüQô¶cöxë0Űą%{ÜyíXs‚Z>÷ š™ Ź{Pͬ´H:ř)đ+`˝řKDĚ…y˨ěBJZkmcŕQ`óx˛÷‹1ŤT=wWI‹ă1_±ĂH_“˘r&EÄŰýs)i¨rű0Îóţěńáa´AD<ĽCę…^}8mYór‚ZľsŰ ‹Â̬q寝Ż…™5»™Ŕ§"â´˘)ášxĄż"⤤pŮaśgĹěńĺa´ŃĄ«ŤĄ*Đ–5!'¨ĺ{0·˝jaQ™5®涇u×ŢĚlţZŞúnłČ†wŐ¨D‚úżěq8CŽ­‰9A-źT3łáÉ_;ěó(33«¦üĐĺ*ĐŢěńµ ´eMČ jů:łí%%-\d0ffŤDŇű€E˛§sG Ç̬ieE ćdOŻ@“]môÎ˙éîŃgĐŞżŃ:zÜ€ďŠx–h9 äkâýŔ•• łŞ‚Z+Ú˘hĹIş%ŢkfV?î"%¨Ikľ–km x6"Ţ­D`Ö|ś ϤŇä«UÜő{˙ëĚ>8nX­ťˇ% ¶$8˘"ŃŐ‚¸Ťąěüµ‚­N"8µ‚íYăĘ÷ >PXfÖP$-GZf;ŕ:ŕôxĽĐ ’×I=‡ý’´°pgŐ#š»łť ˛Ç›†ŮŽ51ĎAJ©Ţć,`¦ęNÓŘaµu˛>Ŕl.!řߎG+` ?AěÍTm ҰÚ:ScŞ/+±0—W&@kpîA5łrś ¬ | 8ŻĐhşÝ¬+iˇľ´3)©^°fQ ŢĄ¤N›JN~đ±ěńŠá‡dÍĘ=¨Ăău¤::fqš¶`.g2——8Y˙EĚ·p÷ŚŮ,Ć·ńN--ŽX 8†o—R8ç IDATsfu®°Éń§č ‚ÓĘB çK6kŁ;–FÓßÂÜŤř,űÄě*ElŤĹ Ş™ ‰¤ŃŔ¶˝vTŇ{˛B?ic!ཹ]cŃ’&öń–Ç#b0Őh/~)é 1ď;¤µł×>\¬,–í°÷|IĆmŔYlĎEÄ %>Ďű€ĄIťN$­ <s{ŰźxZŇŤŔfŔ–¤DzH$ŤvfŕŐ†Á ęđ<”Ű^YRKDtöy´5–â`ONÓXć°:-´ő>dÜřĆ%ěĽĚÂŢöiHî@±ýWŇÁŔ9Ŕ&’n%%+“nČ˝|-"Εt7°Köçâüç‘´đÇ\ÓźÍţĚ–´pDĽ“;vŕ©ě<dŽŽ(ćN%%¨{QF‚ ěŚΉWËxżŕuX˛»Mo“ţ3.¬€KjŹ<Ĺ;Ŕżúzů¬ąEŇŽ‡_ĹJqa #«ťďĆż{ďĘ~‰ÎŚŇEˇĚú¶"Ý__/Ő+`fÖ‡ýHó7·ţül°oŚ·$­ĂĐ*Ő><„ö*é.ŕ+¤¤4H4Ź.‹·˛CżLćŰIświhďéEĎć“Óě|ďf=¦ËćvϦźď,¸”4˘e7I–‘d~…ô™N+óüf€ÔJxX7Ű^'¨M)"®”ôaIgŚäžtI"ݡ˝3"n,:kHŢkfe‰W€“ł?ĺĽ˙?Ŕ*TĎöoc€U"âŽ~^›;Đű{˙ZG:"BŇŔHó{Źě{%mFšzA“YŮ\$iř<ŐżŽĘćaŚ8Ůđ¨ŁKťśÚ0¸‚Ż™YŠ?WßěŻŕS G3ŁŞ5÷ źT›'ö=,égńlŃ1UФ˝“ňĹĚĘŕTł:'iŕsC|[~É˝C%}qď˙NÖiĹúpđuŃS-i]Ňë)®7aĂçuřň_®ĽŞoK:8PŇ´č«đBĂ´9đ!ŕű ZđÉęI>AuŞY}úđC`‘2ßż*C»qŁ“ÓúŹJú*P˛z Ż’ 3[˝¨¬™xďđąŐćťq*°¦¤IEÇ3’öŽłśśZ…ä‡řşŐ¬EÄKŔ”ť®řfŤÎeż‰AUňŤÇ#âȡ.mcÖ'¨Ă—_jfiIď),«;ń`¦¤/ËPI-éPŕčxldČ®‘KgOçRˇâfVgQ›QżĚę8™9A®¬dxľrď¦EĹbő)"ţ Ü,é»’bX˝¤Ĺ4Ü]t<6˘äŻ‘ő^ ŢĚęGDĚŞňiŢŽ¨ň9̬8A­Śiąí- ‹ÂęVDÜü’Táwá˘ă鏤µ€}€c#âŢă±'ŤśÖçQfV"âjŕĘ*žâűţ]cfyNP+ăoąm'¨VR6źçŕ€¬"nÝ‘´#°ADśłŠŽÇF¤ü5ňo}efőä``vÚ}řQÚ5łćµ2ň˝%-ZX$V×"bfDL’´IŃńäIÚx7"~Yt,62IZ = ŕúâ˘1łÁŠj%’ED5_3k`NP+ [벫@ đń⢱Fg$}˛čX$Ť•t4pm6_Ö¬Z>N÷ďť»#âĆbfCs,Pɡ¸Ž«*Řž™ŤNP+ÇĂ|mH"âŹŔs’ö/*Iˇ§GÄĂEĹaMĂĂ{ÍTDĽYˇćfSýâKfÖ ś VŽT˛¸ řł¤#%Ť©ĺą%m ěť}ń0«6'¨fŤíŔ]hç¬đČfV’ÔĘąž4§ ` IK‹5ř/i­ąĂ%-Q‹sJú °|Dśťµ8§57I€Őł§s€Ž™•!ű}qŕ0›y RpĚl„r‚Z!Ů\Şüz‘[‹5žxŤ4żçË’VčřrIj•4x<"~W­ó•ż&Ţo‰™•-"ţ\<Ś&Žđ¨3ëŹÔĘňz¨V¶?6‘´UĄŰĎÖ_ť\·Tş}łxxŻŮČńŕť2Ţ7ť4LŘ̬ONP+ËóPmŘ"âŔIźŻT›’>H*Hq|D<]©v͆Ŕ ŞŮOSËxë·<­ÄĚ⵲ţĚͶW’´B‘ÁXăĘJď˙[ŇÁ’†ő˙TŇ6ŔÖqLD”sÇŰlX$­¬=ť ÜX`8fV?†rĂóâlx°™Yżś VPDĽÜ‘Űĺ^T+[DÜüřž¤ńĺ´!é+Ŕ8§˘Á™ MţZx‹o”5ľ|w‡ż|»ŠáŮâµň<Ě×*&"žN&KZ@Ň‚}/IŮc›¤ŁHÉ@GM‚5뛇÷šŤ@q!pÓ =)"ž¬v.[ĆcФ%c€GÄ}5 Ö¬´üµĐ ŞŮČň-ş—Ů+ĺ)ŕ¤Ĺbf#€ÔĘ»‘4Ç `I«ŚŤ ѧź>Géâ?$}Qř&ptDĽ\ĂÍJĘn¦LČžľ ÜZ`8fVaqp^?‡|'lf6(NP+,›[•_Âă“EĹb#‹¤ŹűŁ€$m—{mcŕóŔ{€ŻŁY {ä¶oŮ…EbfŐr8Pjmă"â˘ZcfŤmTŃŚP6϶÷N(0kt'iYZY3NB/żÍ'_ɆW?ŔNŻżË…3Ž×^­-°óśĽ˛âbüe›U¸~ÇŐY“µ=bp3“ăí"?†5­ürI(, ćÍŃţ° ° ©gwi ¬"dfÖĂkŔB˝ö-"Éën› OŻĎĎO×EÄăEUMNP«ă"ŕT`4°š¤ő#âö‚c˛Fs’VĄ•©´°ÁmX|A8/őG=˙ĐKĽöć,Yh ­?ŢŤ§–^—€Ĺ€Ýzµ4X‹©ş·ů6G{¨•Ő†¤Í€•˛§ďż/(Ž5ý€]H‰©™ŐĆZE`6RIş¸8;"ţWt<•äµ "âeIW‘ľ ě 8AµˇiႇÇgŮ/ŢęýňsŰăjë4-Ă\Îg_ήdfýŘ+·}YDĽ^Ë“gkQOÉâđ”33IÖÉţ"édŕ´¬°fĂó/ěę9?·ýIŁ ‹ÄĎiZŘ’1L)•śŮAń b bźág60Ic€Ýs»ÎďëŘ*ťŕAŕ řwť™™Ť\ď!­öđp6r©áąµz:HăĹv./4"kť¬ÜĆńFĹÚ<$ţÁT­Í™Ă1sŕ7 ËÎŔ"Ůö Ŕ_jqRImŔ9Ŕ—ű9ěmŕnŕyŇśžáß2ł.‹ &Í-:łB¤\b`9`ől_o€żJÚ?"~^Ăř*Î j•DÄ,IżľžíÚ '¨6Xťő»®\ů^)yQ3«´üđŢ˙‹9Ő>a–ś^Mé5¨4öRq‰w«Ź™™YĄeëŢď|•Tř/Ż ř™¤ĺ"âčšW!NP«ë|şÔť$-Ż5&Ý=f:cÄňýwScâě›j›Yo’– ŤéR«á˝çR:9ťLŽŐ(33łŞç€s%ýŚ´”ۉŔű{ö=IŹDÄµŽŻś VQDÜ,éa` k>ÖąĹFeŤFwŤŢ餙ËýÜĘGÝŁŐbíx±6šÍç3t˙~ą/"îŞö %}›4ß´·)Ŕ”¨Î33łdż×.Ę łţhďuČĎ$=·Ö>şáq‚Z}ß϶÷Ć Ş •ôEŕÔ8ó˛Aý€înŰąŁöN©n`f}Ú;·]őŢSI«2˙zÓěż©öůÍĚĚŠoHÚř ô(†9ř­¤Ő#bv1ѕǕ «ď7—pSI+őw°Ů|B‹ÓŹář§ˇe‰*FdÖ'I«Ó='¦“tW·ÚN`ţ®G9953łfő¦î\×ëĄĐ=ݰa8A­˛xřgn×^}jf6äŻq×EÄłŐ<™¤Ť€Ýzíîă«y^33łz’#ü4đtŻ—Ž’´P!•Í jm䇸}ľ°(ĚĚŞH’čyŤ«Eq¤z=źL®ÁyÍĚĚęJVŚuJŻÝKjC4 '¨µń{ kI•%mRd0ffU˛iŤ6Hk‹ţ©š'“4Ôk÷/"˘˙bbfff#×yŔ#˝öíZ@es‚Zń/păaľf6ĺŻmŚU>ßćŔ"˝öý˛Ęç433«[ŮPßŢËËl%iÁ"â)‡ÔÚÉuűLŁŤ73돤EOĺvŐbxďÖ˝ž? Ü^óš™™ŐłK{=lVD ĺp‚Z;×ĎdŰ‹ű‹™YĄtÝť} Vs®Đëů ^ďÔĚĚš]DÜĽŃkwďß™uË jŤDÄ\`jn×!’ĆŹ™YĄdÆľ•ŰuRŤĹĄ{=®ç433k˝'öţťY·ś ÖÖąŔKŮöű€Ż‹5 Ĺ´°îŕßk@<^µxĚć·°X¶ý,đ«ťw©^Ďť š™™%˝'öţťY·z/lnU3$ťFZTŕŰ’~łŠŚËę\'çҢ?ë®ŃŁQË=}'Dgl‰Řś1ł˙_ #´&–Ť98·kjD̬ŃéÇôzţzŤÎkffVďz˙Něý;łn9A­˝łďćˇ. |řYˇŁÔŘq5Ź˘^‰9Ŕx€řđ¬;uWŰ6Hű|˝ź÷-ş µ®kĚzkľ×§¨Ťńt2ąU‹»y´•Ř׬?ׯKfŰ/?-0333kpNPk,"Ţt&pT¶ë˙łwŢa’TU~ ,,,Hλ䜔 "I®T>1`EA‰"*A‚"I%łD•$"Ů@ÎKÎ9‡ÝóýqŞ™Ű5ŐÝŐ“Ş§çĽĎSĎLÝşuëTŐ­ę:÷ž°Ż¤“2Ő‘D‘)ŢüC.E§ň×3 ËńŤg_›b«ľű_`÷~µ9–í1.e7{o@dŮ,XPöĚKQ1’fľ›ý|RËAAĐĹ„j5 Ľ‘ýżđŮ e©Š"uŘŘĆ:Ú›§0=§r„6©Ďm©Y8J_Â8 ăř”r$łPAŮeÝÎ.ŔÂŮ˙Żŕ"AA}&fP+ŔĚ^ôŕ;YŃ~’ţ8ÂŇ#)¨‹OÓM¶k*YĎ›ěÇ,ěŚ8ś#ąú¬ŁNŸc7ľkW ¤#‘Ib4šÚG”‚*i:`ߤč83 Đ`Ä‘E±®}O˝jfÓŞ”'‚`¸ juěĚ, | 8§R‰†–‡€÷©ďsë˙¨D˘Nă@{÷O‰>ĘťĚdţÁ ďŕą?GźĎţ8¦BY†’öćĘV4łăŞ”'č;’ÜŹ[˝…Gł~»Rˇ‚ K‘4Ř4):ŔĚňą>. L|+ÂĚžNJŠ~P•,U0Ůx¸¦`Ó'‡Z– h“­ Ę®śl…żş’ěŁ|ż¤č·föBUň CvĹóĆî l_±,ĂIIęź_ţŔ°2=î)ךY×(§’f–t¤EŞ–e0‘ô1IߨZŽnDŇ’’~Z˛îô’ľ-i­&ŐÖĄçÝą'˝‹.!Ôjů)P XłŞ¤-«¦Î/(Űy’;ä’A &‰qŔŽ›.jY*f`ąě˙w€#+”%AHZ@Ň™Ŕߥ«–Ř<ů˙˛Ę¤`$m Ü…DuĄµť¤ů%ý¸ X¦jyş Ic$ Ü|ĽDýőŰ€Ł!ľPP+ĹĚNOŠöŻJ–Š8ČűÝÎ ě],AP†}qľ.Ş@–*I->N2ł"źň P˛ś»÷ŕćĺťÂfÉ˙—W&Ĺ"iŕ<Š}í»I3â}©hŔ1č?—âß´-ónff»×+¶PÁđ!Ôę9¨TX[ŇFU 3”L6§xćé;“TĆ#*c’Ź›ĺąp˛ŤśI™ĄÇjŮęű¸%HĐç§dËĄË2śµj!jHš79xÔĚî®RždŽŞ¦f«Z.föAŞ{=ďÎS€HkÖĄtĄŮĆpÂĚî—ôgzF„\YˇHCÍ€OP?X28w’Ř`˛E°‰ z&‰™ń…1ąMÓaţăÔźďéföHe’ SĚlźŞe„Ť€ŃŮ˙]1{ťŚ™ť ś]µÁŕ3¨ťÁŹé1uÝHŇU 3”L6îN-Ř´đűIę{n• &‰Qx]Ą`ó©Yd~iëd«Óp ©¤ć˝]ăAP5ˇ vfv;pnRtś¤™Ş’§ö^,(ß8/‚&U1IĚL¶-Řü"#Čo\ŇĚŔ±IŃ™fv_UňAP ô>´)‚ ÂÄ·sŘŘĎ-¸/pP• “Ť'&‰đč|źÜ ¸~’Ři˛qűĐKŚT&‰U?âyŠóĽl7’|OµtŻa¦ÚG$}—­>efÔŮź­Ţaf×eĺsŕ©i&á÷cŕY<âęEŔ…fön‹ă§mßmf×dĺK_Ö^Ás|ŢüŢĚŠómoĚź­ľbfg–Řg4đŤčv3űg˛} <`O>ŕĘŠ’ľš¬źgfĎ´?#đYÜ2g `1`*đ<~~W›Ůó­dMÚ\ ­Ţ`fŻ”Řgq|°ëŁŔÂř˝{x ¸¸ČĚţS˘ťą©4ű‡™µ´ä´~ jśQË!)i~ŤVĎíşŁ¤ÚµyÖĚ>P—´=×á3»:+_ďKëŕ}éUŕ>ŕVĽ/µLK%é“ŔŮę«fvF‰}¦ľśÝif˙H¶×úţ ą]—ĎőĄ Š‚że}é3ôôĄĹééKĐÓ—žk%k_ČÎo`ýěřKŕţ´ĎS€«łă?އ¶?ڧú[X9kÖîCŔ%Ŕůför“ýWÖĚVçJ6Í™»¶7˙ľ’­§}`’¤%˛˙ß2łS’c¬AO €SͬÎ5ë{ç÷ϮݦŔxÔćůńŢŹWn7ŕ_öîú nîż8ţ\ż„ŕ:¸Ä̦<ł<{AĚlČ\é˛dYe(Źßé đýäÚĽ ,QµLCąLÄľ9łËÔ‰Řɱ…«–3–î^&bă'b§OĦ5éŹ_­ZΡ\đów“÷Ó·«–)“kJî7eXÜŕÁDćkÔą0©ó«¬ěÓ¸BcM–€MZ˙˘¤ţďđÁáÚŤÚ}8 ݢíë’}î/y=ĆćŽu\nűĹ-Îą¶¬SĐö·€§Kěűp00}I™ż™ě»‹şójq}kË9Ŕ˘-ÚűHnźÝKĘĽnżĹ“mK–ĽĆ7ĺÚĐjß×C[ť_Ţ;R˙îh´ĽŚ-ŮÚŞÝńÉ”Q ÚÉă7Zľ—ő“2uźĎăÇąíóȱS~˙¬ßÜâXo*yÝľ<Ѣ͛đčÄůgvń2Ç€>s~î¸'Ĺqs2ź“a¦2ű…‰ogq>ę>RüË er&ż~Ö`ó(ŕ˙€‡&‰+'‰oMËORçDt †'“ĬY_Úk’¸˙Ŕß ú?:Ů8~č$ě~EO0˙á?Á"i/\ÉעęâŔĹ’6,Ű4p"ü*ý&š«73°p~–îĄă‘´7®Í[˘úXŕŕ/’ĘX—•ň?•´ţĚ|šrnUźn•´A‰şť†€ßâ×qş¤Ľ¨/} ¸(sčx$} ř>ŘĐŠYđÁ€łKöĄ2ÇßOK¸X‰ę3{Wd‘¦›µ»p#nÁ׊9đś×ç —ű iy\9ýH‹ŞcpËĹcJ´y >¸·@‹Ş«ăvůYâ aâŰAŮ»’v§Ç—e3IŰ™G-L6ľ7IÜüšžâ”é ł€Iâ ŕŕ˝!r0Ť÷FŹbt\ŹćŚĆ?6ĘţĐľě6Ů zu-™9j-ý•_7ł÷+i$˛P3‘›†G±ĽLY7g[źžwć Ŕ!YY+¶ĄGé} źůą¸X˙p=€žÖ[âAöďóŮ´Ď/ńYß©˙xĽ8+Y°öO–éd۸‚qn-ÜDz{`WzL>·ĆgF~ŰHĚĚócŮęóxꋢzËă>ěiÚ–—đűw°4nůEzLŁç.“´Ž™ý»‘ĚłŔײ˙·ÄŁë×ř!~žµzŤŘšžľô6=}évĽ/m†+µľ´®t}Ş˘·ĹŻń٨÷©żŞń@íźL‰;*Ůö$=}©fRľ°~k}é“ŔnŮ1űڤUđg®6húRÖćĺřýx7-ÝŘ>۱6°nťWÔîZřs•~kÝťµ};~ž«ŕýó+I»źÄÍW·Î5y9ŢżÁôZşŔÇđ™Ď7ŕď±Z[kKĎdÍ[E˛·ÁL¸F­_ކźóxz›ŤpłßÔ$ywIGšŮcE fy‚Ę_-7em­…ßűĹđtFżčçyŚ8BAí0ĚěJIgŇă rڤËĚěő*ĺJ&ż›$îĂ,ćoU­,3Ş8bU¨Űýŕq`‡ÉĆżŞd(‘4őf'[â Ëdďv5ł[’m?ÎţHĎGěz’V2ł˙µhű_X`+3»9Ůö_ŕż’ţŠ›Š-”•o'iC3»ŞŹçÓfv)|w4UPo7łFÖ ;Ós-Ö4ł§suîţ.é|\‘¬ÍúíC÷!­ l]afÓň$ŤţL˝rz3°™MÉÉ0YŇqřýŰ$+ź 8WŇŠCńűoîC{|&űÜÔ+¨gŮC%š©őĄ§­ÍěĆd[ľ/ŐüŮ·‘´‰™ý­_'P3» ľÝ٢/ŐfżÇűŇ“ą:Wf}éęűRżT|ö˝8ó`]ëťs÷!ŕIÂçY˛ňoJ:ŘĚęRöI śI˝rúSŕ@3{')»·*ř=Ěłö.ÚJŇîfö«ZĹl0ĺßYű_ĄGA}ˇÁµ­ő·×¨WP'`%[ŢÂó˙>÷ĽţNŇBř,rm6t:|@°W 9Ióâî5Ţö2łĽUŃ5’~‹?Ó[RoQ” L|;“˝ń€ŕřAŐ‰R “Ťkqźpß  ¨‚Wń©ĄGšršq=D/áľCA5Ľ|6§ś~€y0˘źćŠËÎr°EN9MŰľř\®¸‘;F§šČž\ ś~@¦´śž-&iŃ&možüß(˙é§ĺ’őű€őrĘi*ĂłřŚb:4ź…nLĚ)§)1;劏(ŞŰA¤}éÔĺôĚě ŕ”¤hŃ,8Ö@˙Âĺ4=ţp3Ü3ăłyyľDO 4€łĚlßśrš¶{wÖN„l˙Ěš`8đ3;±h0É< Ô'rĹŤŢťSďfńĺ´ÖîËx0»B ‹ 9ˇ v ćQÄLŠö”´bUňTĹdăŤÉơřěč‘Ôż`0y ˙hZ|˛ńăÉĆ›­vč6$­Śű1ŐŘĎ)2ePŠßŮ-ę\’[˙PɶĎ7ł˙6«`é÷ę¤č#’:Ňr%›iM­o–hT7á—řďîÎŔş47e­ůźýłŻĺÖh-˘+gĎű抿Őlźä"3kúAn‘:MËłJyµăČfZJŠĘ(›ż˘ľ/µ¶€ĄŰ<ţ©¸yő®¸r[d&ľgň˙‹Ôżë ÉfŮÓŮĂůđ¸ťÎ#´PËúl:ŐëÝ™ů§çű -bĹG ÚŻ´¤Á„‚Úą‡›Ä€›b˙ZRŁ -]ÍdăůÉĆwqó‹uqeőßçN ‚ľđ"ާŽŔÓ",8ŮŘg˛Q:íD7‘˝k~MŹYŇ͸ß\Py峼ćl%ŰţQë*@ü¬CG`fŻŃă n’ĽgłßP3»ĹĚ1łÓÍěz3+ô}ËĚ—ĎV˙[43›‘Z3)şřKIŮŻŁ^é]XŇ2Ťęw ‡–¬7\úŇ›@šçS’ľÝ˘/Ý–ëKýŕ|$ůI‡eéM˙!3;ŔĚN6łk-—IҲÔĎž^iĺS,ĺc˘lTX«ł¸2oâÜ€ôýY\jęMöŹ-soÍěrÜ75hđAíPĚlޤŻăľÂóRýpr•rUÉdcp}¶0IĚŹâÍCŘřŔ}´ÖóüíGĆÔš ŁţĄůŘvź |«Ő,ĚHa*>úôdŁéĚĆdW\Q‡,E‘iT0¤L)QçIőD;×’hÄeR›tSÚPÄźĆs+×ůNîK‡[Ńô`©lů6đV®/Mŕă˙÷_>)[7#˙đ®¤ë’ă7ôQÍČ›Sď*é“mČ36ůˇ†µ:‡)%뽜[ŤřŐČ÷Ńvžëvß#žPP;źď᡼?„tNOş h™Ý)iM:ĄŤ}Ű©>¨Oćć°úr¦tAK˛Čâ?¬)I:CŇL»#”ěÝňĺ¤č»Y$ ZÓĽşY0 "ŇîŽä΂J}ظź‰nÄ:Ŕ‰ŔÝY~Č"Ö˘GYĽŇĚĺšž%·Ţî3”÷k.ćőíQK]:˝/ݬŽ>ú;ÍűŇÚxš˘»%­Ó¤^;ÇĎ˝» p!nÉĐ•p3äű%ůö–őM/Kľżwí×7cLn˝·˛NVŕ;’Ž~!đ;<ůóř Âé’Vk02ud#¸;IşOYT îđY`Ľ¤­3E6Ád‘OO§gŕňfvj…"CC޵ '˙·Š¬^v|ĐRUdJäiŔiYĂMq3ÝM)6+] ¸LŇfv_n[˙SčIWŁYĘš"ňő[˝ź+żÎíöĄE’˙;ţłľt:ţ 6ő}©Č {p©¤µJÝ–9ľáQçKš·úŘ ÷W.ęcóggyf˙‘”çL¶Çó»ö•AĎÓŰ!Ľ’[_ňľá ·®¤„‚: ČĚŞľŠ'Ť›Äś€+AP 3;DŇ}¸[mćtmŕFI“ĚěÎę¤ :€é1·{›Ţi2ş3Ű ÷Mi”Vž2˙ät¶¤•‚Z&HÔGĆ4ĚězŚQř¬éöŔ¶ÔűŽĂspçsż–ń?Ďś2ˇ°VcňőóĘ[~F¨S®s;}iő3yE})=ϲł~Cbť ęţřcŃ7íK©_ćlx_ĐďµĚ˛ĺślAŇjŔv™ iZĄp×°40R•`Ş™Ý0ňu)ySáPP‘0ń&dÉ­÷IŠ>#i8&đ*ÄĚţ„›ü¦ăë3—`"é+Ŕ§“˘oǀšťŮ˝ńąő{ 꼑ü?®`{C Ç̦™Ůuf¶'ţńřuę˘Ii}IsáćÂY3Ë|´ăvÔ|~Ůü‡q޸S®ó"m¤ĂË÷»˘ýô<Ë*¨CPĘśšŮ·đYáŻĐ¤/ ’ ·™Ů~f¶$·$őŁ^7›q­‘źÍý0A®Ď­/]X«ĄR‘@(¨Ă3;7ď¨q¬¤˘ŕAĐl¤tMę?˘f&Kj™¬;č.$­Ś§ŕ¨q–™_•<Á3‹¤ŤKÖÝ9·^(*5śˇ¤ź{Y?˝Rľd’¶”ôIWIz,›­kܨóÜJ©Ć¸Ěě˝ĆÇéůfj6{ pőyş·””LÓHö™’˘7éŚ)?C[VA-›¤Ż>{3Qź§»äÖ‹úRzžÓI*ăë8 ç(ió¤/=žY4nÔ9zeflNA,Ť¤µ%ýBŇ’•´|«}Ě척ՄԜ:ßź6/;° ivIwHşRŇI#ě›áj ő;ß3 śÖIK[–PÝJ(¨ĂŹ]é‰6đç’/í ř€,ĄÂ:ŔĄIńtŔq’~YćĄ $ŤĹsěŐ”¨’Ś lUAŇ|ôäxĚĚn.¨šWžšÎd¦¶źi)ˇ“ŹdÜhVm><ÚýÇp3ĽÍÔË“Ćux“zßş´Ťfţ§5_Ássr~ݤ {P? x±™ĺgLó>„-gg$m@˝s3Ę^ç"(!Ë<Ô»°š2ł¨ĎCűaü۲ ßÄÓÝlíÓČtő­ä˙V&čoĺÖËš¬)föő)KŇ{ Ąh/ R@(¨ĂŽĚďŕÓôŚâ,ü¦:‰‚áJdëŔ/r›v.–4Đ‘ţ‚Îă·ô|ô˝lÁ×F$ëKÚˇŃFIÓGQĹňČŐóć{·8öŐZJd©,Ň(ÂŤĚ9ϧ>j桭Ţg’ÖMŠn«ĺôĚf—j ę»ŔU%Ä=’zhŹVř%­@oEö¤|˝,ĺĐ”¤čc™bŁvçÁăV”%ô¦łŮu$5TłÁĎŁđ4?5Žn?µÝľ´i·%ŮńRŨŃ9^@˝ąěÁ­fä%-L}Nĺ›Y_#1_C˝ňw˛ö›ő3vŹgţ×)?ÍŻKߢÝŐď&EÓđ­E¤¦ţ­úOľżÍ_X«38śúwËŃ "%#i”¤©wź J ę0ÄĚn˘ţGlgIźŻHś`cfS3¬Ý©É¦ÍpżÔńUČ >’ľě}ŰĚţS••JŕecI_“´¤¤kŠ™˝§â¨±pa#óHI+áŠHŞ4Ąfď«Đăżyť™Ąß…Ů˝¸"Vc đIßj ĂŽř,bjBz’™52'NNIJ•˘Úň'›ńkĐ—k p¤ŹIš)Ń­ř٤ úŇśŔÔźúplvN§^‰ÜIŇO3ËŹ´ÝE%ý84+ęËy~LŇîI_š>¸ ©·~­ Ý«˛ň €TĆcŠę–Á̦âסĆ\řrˇYĽ¤ĹđŮű4PSŃńĎÄS/ĄíţORáLޤmp‹«ôĽNͬ±ŠHŻí,’Ž•´’¤Ą%-”«űbný;™iőxI«6hż˛ßČ#’˘Ů 23đ‰’ćĘž“đľ~=™‚v0ł![€}ńĹÚ˛ĘPżŰ|”¸v-ß–«Z¦X†ď‚ű˝ś{FźÖ®Z¶Xü^Ż›0ÖîóYUËÔÇó’ëŻ_­Z¦’r?Č|m:&u^hŁíg“ý.nP碤ÎűŮR[7c;ř® ¤×ři`…2ś’ŰÇpÓß«ńŹ÷Űđ±Ú¶«sç{\“¶/,h»¶ěÔ›3wť-;ć5ř¬äáxDóŕ MZď<`TŇÖ÷“mű´q/FÓ“5˙^˝W`Ď+¨s+0K“¶çĹgöňűÝťÝ߿ᦳµňiř dZwńm/Öä?›«›~‡ĽŹ[wĄ}é|ŕçŔµÔżsj×aĄ×đ¤}éVęűďµŮý«­˙şIŰç´][vNęÍÜߢ/ť”;ß—.LűRß37Čx#pjvüń¤÷runĆ4hw>zżC O9s®ťŚ›çë\ĚĐDć}š\Ű_śß; ęNĆ&uśŰ>Á±wĘŐ٤äu>.·ßŘő¦Îjr~ůĺzrçÖ–…úÓ'Úč;ççŽ{ňP7'Ăń9f*µß  ęŔ^Ď9r/—;˝b‰ĄĚ,<”{Nß&ůđ‹ex/xš»“ű{?0[Őrőń\ňWˇ ¶Ż >l’}DµúĐş_B†·”üx».«vRÖLA] ĎGXÔÖŹru—Ă겒†+=crí\ťloŞPČ;#®D´#É”řĂÓŠ)©ůĺ]Ü·uˇ\yˇ‚šµť˙XO—ą’zéđK¸oâó%dşPâçn*yÝ®ÇgS塙‚ş ˝ekËáąşËŕŃ”ŰąŹ“ó}©ďŚů€űÚ<ţőé˝jĐîĽŔżÚl÷"`ćíΉ“íuAý˝šoŤ¤^ĺ jVw4>0Č/w+żĚ•Éo.ĂXA ßaŚ™˝D˝?ęňř}ÂĚîÂ#ü¦QţfÄM¶n#…@Đąü˙صŢÁĚúŔ#čĚěoŔôNŁPăŕŰř‡â”í˝űs~źĆąRÇgY6Čę—•ő6`">°’gŮ\Ý»đ/ßžlŇě4üť·•™mef•f‘|kć”O™Ů˙ĘĘšÉđŽ™í‚Ůů+őţk)ďá‘W75ł/›ű™¶jűl`e\a(j×đ™ÔµĚě—íČŤĂ9†Ţ)m wťs2]…űć#ĹÖxźÉ]ÝĚn%DöťłîÖôtjOŕ ë›Ůó­ÚLÚţî«y_Áć|_şźYŢ3;^#¦áĎŃ6f6)íKýÁĚžĆ\vĄ¸ď§üř°n«ëa.¨ěfĽĎ4âjŕŁfö ë¸+ßî x`§k 6/WP˙hüçcA“ţVföž™}·F: źÉ z7‡ţ°jöÎťě>ŤŢA¬‚ʴۡ9´/>âPcU ź§~#i/ę}]>gf¬Jž`ř#iFŕwôNT˙'`×2OAç‘ůĄAWv7łFA.:IS¨Ď§ř5‹9-‘t=Ń@_0łą’mËŕł”óŕâ·›(ę˱Fá Ţ’¸żÖó¸•Ćż¬ďcjm/ŽT™Š›É>eîłWTw4ŢWĘ–yđ™Řç€ĚěŮű-JO„Ó{ĚsI÷GćqxťůđȱĎâJŰťŮG}_ŰťŘ kw~ďn5łGű)ď,¸ßĺ‡đ{÷¨™˝’l?Ř*[}ŮĚćH¶-ŤGť xř_?űŇÚ¸?íěř¬­/Ţ÷6Ú^ XWžlŇ—¦ÇűŇÂôîK7Zď€DJvÉŽ˝0~Ď_ÇďOżîyPk`nÜßô)ŕaŕáFĎH‰6çËä+oŹ›Ů; ęÎż+ćĆgäëĎsŃ)H:‹žôQŻYźŇőá¸éó pŠ™}~(ŽťČp<őŕÇ”ů† µKt!‘üEőa3+ ‚ŇHú!p0őNţ7[öŹp0°dbn˘'Ě_̬aäÖá@(¨}Ł™‚íĐLA ‚nCҸ˛ŢÖ€¤›č‰0}·™őšE †ł‚&ľÝĂçńQXđQŻ?KÓ¸z´ĆĚĹMŇ—ÉZŔŤ%Ł9€zňťÖ”ÓqóŁ ‚ Ęq𦤻EäΓYa¤i ţ>(’uˇ v ™Oꏺ2đ—Ě%úŚ™ý7KgLĹÓĐlQŤTAY$Í€§¨ŤŘ†ßiA´Ď“Ŕ ¸_ěY^ßVěŹGţ­Ń(uT jaf7ŕA)jL~m‚ţbž{w 2+žî›ŐH´"{öOÁUÔŘ; 4AAy&'˙/üş‘µ˘¤%N˝µŇ˝Ä j)bv­Ë0łŁ2ůŻfE˙‡aا:©‚nŔĚ•´žŕ{bV<pl ă›ý T 8Çâ&Ú¬›ŮŻŞ&‚ †1?Ĺ]ęfÉÖw¶–tî:óžşg1ü·wŢdß÷ń ¦d˛ˇ v'»ăжÍÖż+éY3;˛B™‚.ŔĚ^“ôI LĆă&˝Ďáyď.5ł·Ş’s8 jcfŻJÚ¸·‡źŹě»‰™ý«Zé‚nŔĚţ*imĎ/'ĹË7JZŻxŻ@Ň&ŔUŔÜYŃ{Ŕ.f–ź•‚ ‚ Ö„‚`fż>ĽťŤ.“´MuRÝ™ýX x0)ž ř»¤ť«‘Şs‘ôiŕb`lVôđI3;˝:©‚ ‚ ‡P|€™](iS< ÍěŔLŔ_$}ÍĚN¬Vş ›0ł{%­ ś |4+ž8UŇŇŔÍĚ*°C´î'^L|hf7V'Ut’„¦ÖxŰĚŢnT?č^$-‡Ž[_><ÜbfĎV)[PŽ,uÚ)Íěĺ&Ő.'fP:Ěě:\ax2+š8AŇŞ“*čFĚěÜő”ܦge?V#I‡ÇŃóž~ X/”Ó ř€—’Ąc~§ÂŻ~h4·¤Ë;ßűÇă–'ëV(^ iś¤9›T9śäyŽŠ#›PP^ŮíŔ:Ŕ}IńŹ$ý"±‚ÁĚŢ5łĎăşŇÓíń´GóU"X…H%é·řGVŤ»€uĚěžŠÄ ‚ ’–Ę¦Ş–ĄŰ‘4p đń&Őî"q‚&Húp/°tŐ˛ĂPPBĚě|äńć¤řŔ’FW#UĐ­dş¶ŢLŠ×n’´R5R =’fţě–_ŹĎś>^ŤTA”AŇaŔí4W‚ă‹x˝”ńď–;€§¨Źu 1’“t p0oŐňÇPP†ŮóŔFŔIńg€‹%ÍQŤTA·bfçŕ5ĆÓMŞFŞˇCŇ\Ŕĺx°˛›ŮKŐHAě‡űŇCĂjąőóŮf¶˘™-`fS‹v †ŚŤé‰3Ą 5hŠ™˝LÎLŠ7ţ-i­j¤ ş3»ź9ýOR<¸@Ň·«‘jđ‘´>~Îij§S€­Íě­j¤ ‚ čhIţ88ŇaÍ!Ŕ„dyµZq‚* 5h‰™˝ěü")^¸VŇŢá— $™)ëzŔ…Iń(ŕhIÇKęščărľŹç8]0Ůt°«™˝_ŤdAĎÂÉ˙Äűrxcf/šŮ”dń‘üG2ˇ Ą0gOŕ ôř ŽŽ.”ôˇĘ„ ş3{Ř8*·é+ŔĄ’fz©Is—?ĆŁe?[_0ł}âÇ9‚ )3'˙‡Dt]3 föI7â\–ËŠ'˙‘ô3»ľ:é‚nÂ̦ß‘tđk|@`ŕ_’&™Ů° €!iŕ `¤řN`3»«©‚*‘4+°$°8îÇř8pă@ĺőĚ,>Šç ˝ÝĚ(±ĎŚŔ*ŔÜ@-=ÄËŔ3Ŕmföîȵ ~ަ÷›Ů“Mw*ßölŔGđçě}ÜôňŕßŮ{şÝ¶„ß“%€ń™ĽĎwšŮ3!oI9f>śÉ2k&ĂăŔÂTXŇ<Ŕ†ŔÓY›Ąňzf×g%ÜĚu¶L¦»Íě©&űŚÁźŐ ř@ç˝ř¬ň{}”}tÖŢzÇ@ öJš€G!žx _ ëg Ł1ł![€}ńTµe•ˇ<~,z/gNĘÝĎ÷€ďŞZľXşkÁu˝ëoĎëW-[›ç1 ř!ţ±śžË–o¸-řBzżZµL}8‡Ő?ô Ă?ŹfĎęţ˙Ř}8˛A{w'u¶ĚĘÂgҶŻ6,ذđWüC7/Smy¸X»ĹůÍ—Čótíwřp[¶o> Lߢí…rűš•/ ś Ľ]Đö[xL…ĺčţźś[ţ8éyoěłznŰô¸"raö;šţ¦ž ,\pÜŮđ L˙¦5ąOOg}hÁç±s"ĎÍIůŮý(jűŕgŔ%ŻŐܸźáóMä˝ř0SÁţóä®ŰÔdżwrŰţŰDŽőłk]Ô? ˙­9 X´Ä9MJŽygV6?puNľ·đÖ9ł:ßIö;'yöľ

—ű–Ü3ps“öŹ``ź;łţ1fŢOççÚ>y Ţ{mĘp|N†^Ďvá~C,d(¨]¶ŕ?jůŮ%Ŕ\UËKw-řčýýąľö°KŐ˛•”^üŁ?•˙5`§Şe® Ă\AĹse6úHI—§đĄOĘNhĐf:łMÁďnş|#·ďŕ%eJ—›śăąş«ă®!eÚ˝µIŰ˝T<őH#Ĺ#]Ţ>7÷đĚ’ç˛y˛Ď:ąm3áů<‹ö›LČsŠ’fË+ H$m~%©;w;řCɶź$§8´żÍ•žüň0°d®ŤůÚŘ˙©ƶqN†+b{´8Żí’úĎcp%»Q{ă˛ýJĘŻfÇ3&´’éy`µ¬Ť(VfóËMŔ -ÎcA+aÍ–^eřlt™}ÍíwLnű¸&ňÎ…••óUŕ3-®ÁnIýGđg ?Ó°ż˶huü7ż¬ĚS€Ąúů~¶ jřýÂĚN“t3đg`Ŭx Üä÷łföŹę¤ ş 3»OŇšŔąôD»ť8EŇŇŔţ–˝ ; IÄ?°jü7齯©‚*‘t$°w®ř-ŕVü˙#ŔbYů|řŕF)Á„ĺńű"ŢĹÍĚkň,\G˝Ůąáy=Áßqä ą¶’t™™ÝXB¦ďâ9ŹkÜ \‰+/ŕfz5źě €«$mlĺĚr?ŤĎžÖx ÔzX7­1ř˝¤˙šŮí%ÚnÄ+ř, Ôçy|;ŰVăť&m|Ć©8®5ł‡k+’¶ĂgܧKęĽß§ÇđűZ3Eś3©3pš¤ VÎěó8ŕóÉú»ř˝š ź!L™//G™yđEŔ,Ińă¸"÷,® OŔű|-čâxŕjIËšY-šë4z®5řlT-–Ę»Ôűˇ>›“a pžß=ĺ]<‚úŔĘx?©µ9pś¤Ĺͬlůńç®óôăѸuÄ&ŮzM9y—Ôť˙ÍŰ";ź“}ÄŻßâąöWöÄgúz!i^üŮźŰtţě?‡żĂMRSöΞýż%eFĎ}÷˝/âłťdí¶Móäz÷·Úűó |@/}Ě ś)i3űYÉCýŘ5Yoö Ěś+ią˘ďĚHR#˙ ŚÇďUíX˙ĄĎŔČaµčAíŇ ť»żďăć%aňË€-řŹyѨć_“–u>R>5'ëo(9ŠKÓë;%w]‡Ĺ *ţ!šĘ=-ë'Łső–ÄM8‹F×ËĚ ¦&ş˙Ââďâ¶gçöËŹ´_@n+©»q\iP7?šĘ¶}Aý5đĚ´î1 ÚÎĎ Ö–—Żcső'´}ÎŢ×R3ôžA­Ý§·€sđŮĚC{đh޵ý>„Ô§űţ€‚™&ü=ą˝M ˙ŻLé jj2|>č<}RwYzĎv°q¶ĎKęĽ ü0]A˝qe1mó’Ď˙Ą-îÍ9ąvßöfĚŐGďoľÜ ÝírmÖLő_NÇgĺ~’ÉşY˛ßA úîŮô6ă݆ަ˛µ~đţť56©?89W˙UĚâfäiÝËi`Ź+ř7äë7ąî_ÎŐ]§IÝ–3¨řoęuązŻă)ÓçęÎś¤u§“·\˝ôŘ’äýŚ??/¸›”čďeň6zňďÖCűńN¶3¨C-d(¨]ľ;ŇŰ„ár`îŞe‹Ą»Üß9ď{u0Ő˛eňÍ‡Ď Ąň˝‚ĎšV._7, CWîĘ}mÓ¤ţ“VÍ IDATŠMŮĘ(¨µĄ—|îckĄ\ýČ}¸ě?7îOVŰg*ć¸+¨ŻiŇöüŔŁąş^&¤+¨ĎŇÄÔźYI߯PŇGŻÄ˝-ő!Hoµ&Çř\=QŻţ ·OËWܧ0Ýçď ę}Ą@¦+É šäöůC®~/e?;‡´ź4T8“{šš/ßݤ^CT”Ęů°V 9vÎő“7)đc¤^A­-ŹĘŐ›•¬T°ß±MäŮŁ ţ4`˝ő§§Ţ%Ŕ€5 ęMČŐů0K‹k3nĺ‘î7_ş­ î”«ó-üÉńAątźg(̦^A­-WŃÄ<šŢĺç6xҢ¦Ď->+ž>÷´zΛ´5lÔH3 (fvn˘őߤřă¸ÉďÖŐHt#föS`[zŇ›ÇÜ$iĺj¤r$}6LŠoĹ}‡ţ\ŤTA‡đ |ô˝Ć9fv^ŁĘfö>Řר™çŮ©í¦fžźĚm>ÔĚš™¤bfĎáł5FQoBŰŚ_šŮ-MÚ~ řQR4=°{ɶ÷˛&‘kÍě6|–ŞĆl¸eŐěifSŇsŇÜžé}zź™kŠ™]@ołŘ2ĽŹű(73ţ®$ŐXˇ ÎňřĚoŤ;›Ô<ö9xżx0‹&Ýňfî?2łZČqîşTc PÖĚ÷‹föb®˝©Ö<ÚëSŔ÷›l?J9ÓĚ®+Şśő›SrĹ‹TýDnýpó4o 177=3WukáŁ&5ΓtqćŹý&ű°_Í­±pť¤üď #iIÇ}űćI6‡ŹË´8Á€˛MňÍ´·)ŮËŻúxĽĂJÔ9Ź`ynŢxYɶĘ­Ź+¬UĎëôÎo\ÄđYÔežçWp˙ĚVÜ–[/«´ OšŮÉ%ę}źé<řa+E"!˝Oł5¬UĎyfÖęCúmÜdşYŰyĄę Y “fěŽG5_ÖĚ&µ,iF–j(őď} ʦ[†ZÄőź-±Ď-fvyÉöSÎ5ł7m4ł×©h˙]iĆăąőĽo*xPËń€m'áćŘex8·^¶_őIKâľŐ5ţMý B3ňĘ™{yž™ÝѬBÖ7KŠęŘúg ŁŇú ˇ ‚™˝mf_ĂV¤ÎÝ[wJ:`FE 6#˛ţcUc,pľ¤˝†BI3Kú1>kşQ˛é%ŕSföÍٰÁ@Ň(ܲĆ]­”€„ÓűpČ·đŕ9M1ł{ĚěŹfv°™ífĺs@ć¤YKěs®™˝PB¦÷đŔ:5•Ô(řLŤër3ŽŤx$·>Tł?Ť(\ 3»ÚĚN0ł}Ěě6Ú=ůż¬"qoÉz©ň[t˙˘>xŃÇ$m)ić˘ÍěËl€ő©(uJY…×ĚîÇM}‡âQkśŤ›ó9P&•AW’÷}›ŻÍýŰ ćSÚ‡)űşŘbs˝·€›qÓľ/âJë!mĘnZW–ĺÖű˘hużÄ#¨~¸Áöçđô"?Çýťç˘śă ’ ţb÷ <÷f3%gŕ"IőóĐů(Äeü¤Sň}°Ő,}_ý+ó7”´ţlŽâçóm<°ŘđT, ű ™€=ä[Ƕą»÷r@Éžc€…ńgŕZ?J:x(äë4ÂÄ7¨3{ŘZŇD<Ý„lÓrŔŐ’NľcfÍF[ !fvµ¤µp_§%łâ9żJúJɨ™HZ˙ŕŰ!·é~< }_˘6ťĹÍôNËĐľ~đçMĚ*»cTnP˘Íf¦˘gQŻ>‚+:˙ţÜ›O“ŃÇÔ‹¶Qw‘Üúţ=ô<­EĘŤx Ťë2—šü~UűŘ~@6€79[´°9žOtő‚]”t•™]ÓÇCćźą @ÓȬőSžëŁI–’í<ęă'<ü ďS×ăąh§ćöË÷)1řÝËvĚă;â^<+âćďŰâ–yČž«‡LČ Ô RĚěâ,-Ç~ř\-˛ďç€OH:8>" }ÁĚî—´&žWŻ–“tŕ’–ök)/űţ:ž~#yř1đłţ¤@:3;“Ţąýšń™ČÚě{i5«;X'Rop°«yÖfäMîĘJ鏂Z…YaGĄg;4)zĎťZ&eJzź:ę»ĎĚţüř™¤EqEuoęÍĘżôUAÍ÷™Ľ’ŇŠ|ývÍň;ťßPo~°“™µ29îËłß_Šîĺ­mě?>·Ţ÷ŇĚnÇ-łjĎŔ¶ř3°@RíŔŐC/]u„‰oP9YJšp‡ü+’Mă€c‡$íŮ(w4ĂĚ^6ŁwÔÁ}ł‹úUµpoÜç(ę•Ó‹ĺł°üˇśĄÉR§¤i(VĘ‚’”aP"žKZ–úȤĎź-ˇśBŹeBŤ2ĘO«(¨)©ë+ôÎ_:’ŘŽúŠÓĘ(§YÄéńIŃ*¨r–ôqIy ”:Ěě3; ÷{NgëŰé3yňÖŤLŁ{‘Ą…JëżEߢiw$Ů»gí¤č5`»Ę)ôíŮď/ýą—3ă&ł5žĚľ ťäŘTҧ›ŐÍžŁéý ¬Đ`—®%Ô c0łűÍl3`{ęów-§3"éűňÄŰAP3{ĎĚľ„Ďҧ/ýO×Jš@Ҹ,Ň#Ŕ‘ÔŹâ?lť%Í.}5rś‘ü?#đV;d3ů-ëő‘ü,ĺ_ËäßËLŽ7Í—ůHý”Zç’$ł|Ř8)š< ,iR3ČžQĘß§˛nĄ~†l(fşRÎÁS¨\ś^ć÷ŰĚî¦>…H«`6Íř7ő¦ˇ;¶,oG<Ű@ŤKĚěÍF•‡!ů>uu™g,ôŘĂ3˛źŠ·dYe(ŹËđ_đčnřČźĺ–wńÓKV-g,ťąKáąÜŢ+č?÷ăůGW-g,Ąďç”Ü=üjŐ2µ!űh|F&ß‹–§ńĽľiŮQ Ú}1©sAIYćĹ?ÜňÇť†+ÉĎl»Ü‘ďĎm/Űď*ÜÄąĚy? ¬ŐDî…rő-yľ“rűí4@÷ô»MÎe˙¤Ţ:ąm_.Ůţ'´ýNö,ĽQ°í4\QMËv)hű+ą: Ż{nż?¤ű5¨#|¨Ě=O—ńüŇež˙KKČşîŮŽ Oë7is»\ý‰%ŻŰAąý-±Ď Iý‡KÔź/wŚĂ ęĚŽűG=űOâĎ`~Ű}Ŕ*x¬ZŮeMîý˝M®ďĽIÝcrŰĆ59·CűĐźîVjŇćnąúk—Ľ—'ĺöSëpvźĺúńN:?×ŢÉ}m«2ź“a¦2űĹ j0¬0łwÍě\Ńظ+Ů<ظGŇ™ňü^A€¤U%ý ¸=MýeîÄg©–1łß[—Ť’ť‰yŕ®Oáý±QĐ­÷pc%zű ˝Ň»zźeyWÚň)„+©yÜk¸˙éfvž/±Ć'%ÍŢâp×ăąţZůT] ¬if7´¨×I‰¬ŃźH´ŮEřL`ŢoxÜ& ¤ňŤyg<8˫ɶťű+K;Ąî‚Ď"•‰ >«ż†yŔ¤’ă—¸éří%ŞOĂ?îWµˇ5RĚg÷&Ń;B®đ iîĺ7#€›Ůp3č›Ô‚ ćÚ7|píńü¶Ś†î-äţ!>8đ`‰ęď§1Ok4ääžW[TŻqţĽ«eÍ.¤ŁňaAYĚ“Fź.éŹŔ6x„ËšÇ(ŕ3Ŕg$݆żÎ4łŽČy ™oňŽřŹBŃ`Ĺ­¸©âůŮŹG 9fv pJ6 ¶2Dd*>;tUö‰¤Ąr»6RPJONÓŇ5ĚěfI«ăAl&â9'ŕ~PĎăWg™+©q ő…óRÜ®čX÷KZ·XŘ.;ÎhücóNŕ·fvs ±_Ą>ŕMŮ\™÷ĺöŹV33I_Ć?,'ŇHć1|ö‹d==~é\Žfö;IĆÝ>Ś_»EńYÔç˛ă\ŠĎžOÍöy/óź53UŇtµí·ädj¤Pä97Al%÷Ŕ~’ŽľŠ÷ő…€…ńYĽńYü«đwňŤŤÚJ8&Űę#ž6“ăoŮł¶9>#˝®„ÍŚĎ> ü 8ÉĚ-Ńä]Ô_·űĘČAďś–Mź™ŚßŃŁ–I‘ň:ő˛*ڙҶ®¤m­éyögĆźý{éyöźIvý őýdn r›Ů#ŮóţyÜ4}.ü~?–ý­qő×áíf'gfçHşř$®dŻ™µ=>óýŢźNÉÉÝ[©ż^Ź•ŘÜLúľŇč{Â<ŽEłgŕ%ü¸’ňĎ@עˇü.Ëü"R;ěUłQ č7’¶ŔŐu 6żŹ‡ą? ˙ánúâ †'ň\g[ă3›RśRá:ŕ03»¬`[0Ś4…úhź_3łă+gP‘´!ţáRcW3;ą"qJ#ięcüŘĚ+eNA!é|`«¤č3űüËp<ő>µcĘ|Ç jĐ5ŮĄŔĄ’6Ŕ}6§GA™ŃžĽ*é/řĚę?bölx“ĄLř>Sş-šňßÇgŽ2ł˛ł,A0ŕHÚ źE¸¸×Ě®l±KŤ|ÔÇŰT° ‚ čBA şŽLউ‰çl¸iŮńT5§§™YYÓś ´,>Sú9ÜD¦0ń:ŤEńäHZÉĚšúÄe0éôSUůRAÁ`A’‚®ĹĚž6łŁÍl\A=ŠŢţăý{%Ý iwIst$’ć–ôMI7ăľ?ß§·rúđ3`3ű°™ĘiĐAä}+ż[X«žŁđŔp5&ś8AAĐY„‚ŚĚěfö\™Ů8x+WmMŕ—ŔS’Ηô%I‹ ±¨AIKHÚMŇEx‹cqÉ”7p˙âMEĚě{fvç‹e¸x8Yß9Ëşz6S €¤QYŽĽ €o'őź~84˘AÁĐ&ľÁ"‹Zx9ž~V<‚ä.ŔxXuđh’[e ’Ĺ“\ \ifOäŰ I áIŇkK#óÝix„ľSsÍěőˇ‘0úNQu7ŕb<Ú$x`Ż­w$=Žż ÷oô›xË2) ‚`X j0b1ł×đ$ă´îϸ3°t®ę"xxôĎHşŹ…őj3Ëç¤ Ú@ŇšKÓ[]`€ß,Q_x’śš-S†i„Ń ‚ ‚ 5*"SčĚ–KŇm’fĹý=?Dos۱eEufĚňęM€_§ś©đëŔ‹¸_ěktúAAAĐ‹PP ÉÁŰúÓF–˛bÖlőµ,BhAAt,ˇ A—’)¤/V-GAA”e°§AAAA)BA ‚ ‚ ‚ :‚0ń ‚ ‚Š´/ÍűZ3;Łbq†5’Ćâé»Ţ4łűŞ”§j$Í,–­ľnfôŁ­ńÜŢď™Ůťý•/$- ŚÉVď7ł7Ş”§ ’ö&›ŮäŞĺéVb5‚ *@Ň÷€Ă-€+*§Řřw¶ü´Q%I‹JÚcČ¤ŞŽ]čąöł­ “¶~×϶‚In¦§_Í^­DĄYř đăŞéfBA ‚ ‚!FŇÖřÎŰŔ§ĚěůŠEęVOţż9żQŇ ’öîţź˝űŽ—Ł*˙8ţy’ˇJ¨Ň{‘"˘"MPé]éEQPÁ˘ţ”˘‚(*(""ĹBoR¤ô.EŞô) -’<ż?ά{vîĚlßŮ{ď÷ýzÍ+{gΞyvďîÍ !1‹Ďůp;a‚¬·ŁýSOĽľٞ?Č)÷ÓÔyVI_&:~pNôó„VĹô{ţí‚×7&©'.?=ů >–z}NH—É©k˨ÜÁŔNÔ~×'RM®+ŰłŔl9őmť*űpň»‘0ĆÇţSÇiQ™2ŽĎJí 'üMĽ¸ŠĐÚ;ľŕ˝Ü9*÷5ŕKÔňţ IDAT~Ç_¦ö3î„ďČŘ‚:çŽĘľRößŔ‚8• 6¤TmÚ´iÓÖ‘ŤÁ“ îĹxrť˛źN]<] ¬*óŃä"µR¦­$ŘŽÚ¤÷ôřś„Ë©^$Ç-kôÁű»AĎŃţ±„.—EÇJöÍĚžŞgďÔçé/ŔB©2›.č+e6(xO+eŽ&$3’:·O>'Gĺż•źĐ:>_ŞÎŹ’€JąÉŔ¨Śso‘zNHWŠĘ,\+Ł®ĺŁ2/gMč¶úż‹uB0"*389*s/0˛Ťß÷ČÔűđˇEnTTffŕ×Q™GŃ9ő}>*7%u|Ëčű1Ř6ŁŽ]Sż?n>U‰ ř0á†Rüű›7'¦8±x…Đ-|\ŞĚĆÔţ Ľ6§®8ąľ0y ď’Üp ´VnIř~WĘnžQלT“ŮŔvź‡ďPű÷$ëýz(:ľ~ęŘÂß˝Ęń‰ĺ¨ĚH¬Ýq“us^˙Ż˘2$˙ľ ě,”Cř^z^\©:ÇDĺŢëÖß¶v7” 6¤TmÚ´iÓÖ‘ŤÁ“ Ćđ™ MRnaŚiĄěď Ę.Ač*XI.fo1¶…¨mŤ8°ŚrFh˝ßď©ä\ô÷řýŤ“»­šÉ…háˇĹ3îűÍ‚óm•{(§ĚĎŁ2ď$Ä[甝@µ•q‰ATv9j/ţWË(ó“Ôďéj2BB2·ěžQfŹčřĹÇä‚?'öK˘˛u»HÔsPTĎĹ Ęţ-*›Ůb™|¶ďŹĘí[ŠÚÖĹćÔ'ĂNHDgÍ(7x&*wTF™ř†Ë«Ŕ˛Żo·¨ě»dß°¸*ŰyďpiTîŔŚă›DÇO/ëč¨ÜŮ©că©íń0[ęř!©×´YÁy‹Ę>LFoB‹züúď"Ł'@R6âđŐ:źĂ89îŘP‹Nn âUłřŠt‰™­ ¬–ü8‘Đj•ç§Ŕ˘Éă ­™Üý ŕÔäÇ9ę´âw„VăÓľĺÉUEę||3µű~wżĹóvR˝kăI~îĘ©ă$ŞËĐüÉÝs×§u÷« ˛Ë%áťs`wwż §Ęť©vą<ÇÝ˙^pî‡ cT+f®sî7+Q0łY c;+~ŕîÔ©űčńrąĄr$ű›F»~šWŔĂlˇoF»Ú]ľ¤SęÍ2[ŔšŮ „Ůz!™ Şsćľ÷f6‚p^qyArŠ»ăîóŚÝŠNš\/íz2ăxśü‹g9˝;zĽdĆń˘÷îëTW8ÇÝó’˙ЇI%´đyMěK5¸ÄÝ˙Y§ü“„äżŢ9/ ştČR„®Ü'f[†pcă‹YOL’ U˘]Çzń,°÷DŹ—Jt÷]Ý}vÂŤŤă ęÚĎ 7Ś–˘:ł0Ŕ÷Ýýßä["züźŚăń,Ç;šŮ.Ég.íß„„q>Â$E±˘ďë·©~¦.t÷ÄŠ»żKíű™ţŻDmňřmwĎz]ńwŕ‰‚rłS͡¦şđK)AéžOFŹŻ*(· ˇű„–ÉF–ny6zĽlłűPm¸ĘÝď)*ś/ÚJ_O4Y:eÁäÇ©„®šńń9©^t~d­=»sôř|o` jßűeRÇ–ŁÚëŔ7¨w˙Ŕݧ¦÷›ŮX3[ÔĚÖ'´ôUęžBź[’j‹ř„$«HÜ’´hęĽc¨má»3ul»čŘńuÎSi±­Ä»tNb“+IüwvťĐŔ9ťęk\$‰;ŻÜˇŃ®?Eçz‰0!Ő”ôó+n.@hűmť°â÷|áĽBî>%놖™Ť7ł%“ĄcŽeµŠĆ7Ţ~źwľä÷–ł´Ű­ňr3€{Ílł¸Źşű+źéĚ5ůýîűM^¬)q™ţ;żţ7Sň*In4ÔKĐ+â¤˙Ť¬^'Ň­*""Ň-+E-L_/ffO7pбŃăiM„V±yôřŚź3[ô¸ZPă‹Ýe´:”jţ@VHí{żaďýřčq:‰/Šď­Óbó?f¶,!Y^‘0.uŢd›-ç)Źe\Ççľ<«›iJ|ˇťNŔ>B§ đ¤×®ků™ÔsĎl0ßś7ůwz őkf(®ř™5RÇŃăÜ_hf÷şäĎ•ě~Źú]—ă÷ü,w3·d0!z<9«@’,®Eřl.Nxß*ź‰Ľî¤Źf싿W»ű;q-Eµ;ókîţ|ş€»OKÖ{˝š0é„ĎÉßÍě>B—ŰłózŠ$ňZĺW˘ú™zŤâá±řs^g7~ý—Ő镲Ő ĎxńZ°sEŹs»Kë” ŠtÇĘT/&'f]đEâ®ił‘ź”äyą™Â]Elŕ9#¨¶VľM”¤lívďCH*ć˘öâłé÷>ŽéňzONĆržBm·ŕ,OZ­M~ľ-ŁL#ămcq Ţ ęJżwé®”‹ĐśtËo#Ňçüpf©|ŻŐIśţHuĚ8„őJë݉ߧ{c±čń€÷Á̶~IŞE;Ĺ“s-A5©¬÷y¸¨N\Eżďę‰Ý7łOĆ/ďBB˘úWŕ03ŰŰÝoH?7Ż]ůĚ˝Oµ[5ÔŽU}ÄÝÓÉfžĺŁÇé ń÷ż#Ż?éq!MR‚*""ŇqwłÜîłI˛¸P´ëBwÔf\Ódůů©¶MÄR±6ŐVŰ{š¸€ě¦z$ĹÇł¶…¨¶°N¦ţż,énĂ5­EOLĆż^ |(Ůőˇ›ňCÉö0aÖ×gÝ}˛™ÝJ5qą5ŁĘzďGÚ:Ń㇚¨+NHŻ ;9*RÔ"™'NHݧ:QUŁŠĆâbf‹?Jížs`Éâ÷éţÜRUńĚÇR1lśEőú|!‰«|!t/žĐ·ÖÖ|2zp\V'®z7{ţ'iQŢÓĚľ ěIőďÉRŔuf¶Ź»˙!őÔř˝ş/5f6no´×QűwöůčŘ8ŞÉ«Öę-Ňđë§vśwéC†"%¨"""Ý·Ä˝TPnNŞ])m`‚¤vĄűcÎÂŔ.žiźŹ—Ţ˝7ą8Ť/xł.뵊ÄÝ-_s÷CŰŚi ˇ% B››¸™ŮhBrWINovMfhΫ;nÝK'$ٍť±´n«8aŮŠô¸ç˘÷.~ß.q÷şcP; ž-ů*w?˘S›Ůě„%V&¤lf'ĺŤ?M&7‹[đžiŕtńç+Łş–ΤzmţÂÇy݀פšľÁŔ.ľńAĎ70¶ş™DÜý`_3;8 ŮĆţľgf×»űă9çH_çŤ?KcÖ&ü킬Ç7W'¬— a¶ŕ˘.»éŘę˝ţ8AmöćŚ4@“$‰tGś ľQPn2µăëv—4ł5Ěl#3[ĹĚĆ×+źáE ť3éš·G´«Z –¤:ţl2[Ł :ţp µËłTÄăÇJş12łO›Ů†f¶˘™ĄÇ®BµËăťuş”nJµËô›ŔúyÉibKŞ72^w÷ÇRÇW˘v\ra7q3[řDňă š‰•că©N3ÚŮ~!ڬhäó:§™mcfź0łf»ćfťłnf6«™mkfk™Ůbĺf",×RI4ďˇ:ţq>ÂĚÁyVŁöZ:ťŕ¦ĎµŐ3¨maß“ęgçźîľK^ršoÝ^gFâ Č.JŤ1oćőĎJµŰnÖç=.;†ÚAJP»@ ŞHw4” &ILÜşQ8#Ż™ÍM¸°˝ś0-˝ŚC]ÉĹlś e­Ç;ý\z *©ń–čq+Çýîž5AÎóT'VMíxÔĚlEB«çU„%7Ň7ęµčĆâßŰĺ98ĹgŤ˙]#őóebߣڒ~IjmĚxr©‡2&×ivé# Iŕ-Ŕ(źĄŮsś Ü”ś?ωŔÉăW€­Ýě+Jş‹fůXęç…2KUĹk źíîńkŠ?R ąđĄhWş{v:¶zß×x&âgÝýcc“ďŐţ„ĺ—ö§6‘­‘Ěţ×T˝±ř;™Ž)n}°üNš™­Fř]Uü9U¤™×ż:Őśč‘:ËmLőoá˝î^Ô;FZ¤UDD¤;âa4E ü*Úu°»§´řóđĺ¬ó™Ů83ű3µK#Aęó1AP˝›Xőn¬ÄűÍúŽ$çý0đĺh×ůŃăř3uwşÇ»?Lu\őHŕ÷Io‘ô9–%ô`¨ôvLŞvňY¬tëţ€ÚŮ‚ł4tc)ůťT–çzź0NXş@“$‰tGś ć­]€»ßbf'ű%»Ž3łÍ ÝIß#\@}j˘;ř\Ö›ÉEÔNT“‚órÎ9ŃĚŽIv­O¸8{É̦Q]âYÂÎĘĬĺZfv‹^gş5Łb}`ÝJŔs9ĺ eL”uQ_ăěcf"´\ÝäîqËÇź­"ş9^hfçZg&´mAµËëS„÷ľ¦Űv26Żň=ß@׿ۓmMÂŘŃ[Íě8Âűk„î‘_$tw|›pC˘rQž>÷,T[Śo&\č śgfç&Że4°°YôÔăr&†jä‚}Âř»™“ŐüËĚÎ$´Ś-lGm—éŁÜýčśşµa|ŕXBÂsŻ™ýŤ0ľx `kŞż€ßş{zf^,,“r*Őßé î~rŞŘ™„nÂKóz6Ő1Ő•ßIŽý”8¸89¶µÝbOu÷_fĽ¶żßOε$p_ňyx°”Ěš„÷üCŔÓ„ÖČJóô‚x‚ ÇëŚe…ú-‡źŁ:Ćú3»ŚđY»—ĐŁc BKyeŚęůî~}Î9ň>S_LÎ?đ)ŕ3ű-a\đ\„^{Rý;ó2°uĆ:µq2ü€»ż—sľ¬ŘŠZPw¦:Îű.GµĄűUB«ý1î~]Ákť«p-bBO‘JŮ'ĽvmÖŘ©ÎXý{Ż]>G:Ě’ě¶7'3;Ú™ÔVu÷Â˙8EDD˛ŮÓÔ.qńUw?±¤p0ł±„®™#ł=®Vç)éçႪ—Ř•ĚĚö$$J÷¸űęEĺ¨okÂEţÖî^8[i§$]‚Ý‹—}I—źxĂĂDJ=‘Lţ2+đJQbŘB˝sZ†$mťdfł’ąÜ}F˝ň:笄›/4úűíĐy/ĄşŽěŽî~fęřŔČv’s Ë;9đß^˝źÍHĆşÎKXC83±íŔ9FţNöú]•»"Âđ8á˙›ÉŔ’îţjńłĘgfn|Uśćî{ô8† 7\+Ćzý.×jAéwźbf+K›Ůf.2=ÜAîĘfvˇ5óÂX±˘Äeóčń8ý—­-yăT;® …¬¨|KăcŰá»Ü©z‹ÖáíäyޢţŚŐť>çŰ„A˝Vo"©¶ŹîţrýRĺń°üĐS]>ÇűÔ.1T†ý©Ţ =h0$§ťT‘îą’ Ž#t‰Ë\î¤{Qíž÷6pFVˇ¤»aĺü4ŕ¤vNšĚpşđ5w·ťşDĘbf‹RýţĽî-ÎL,ý/ů]W–şŔÝŰú(ŤŃ23"""Ý·¦×©,SĽÄĹžI×Ěf¶!aąŽĘřŻ3ÜýéVOhfÇܓ߷ZŹH[O[]‡X‡€Y€ç 7ö¤Ô‚*""Ň=ׯĆČ­Cu,gŮ~MĺÂŇ#ĎŮ}„qVË„,K59˝Ź01J;Ţ6u÷ËÚ¬G¤lŤ.K"™íLg<ŘŞĚą†µ ŠtI23ďéÉŹźK&>*ť»źKW55Ů5'!QÝ›°ćgް$Ó9%‡4ě(Aé"wŘĚ&z-u|†Öv¸űóŔáÉ&" p÷˝ËŽAşj*°nň¸«K3I¶^'¨SS?ŹéńůEDDzÎÝ'–Ô— Íčë%~‘t®÷~#OęőÔôÚXf ‘A/Îő¦4şxŮ ęřź_DDDDDDş/ÎőžhŻěU-¨""ŇŞwS?ĎUJ"""ý'ýbú˙Ě^s˝·}’T¬^Jý<)Qôźô˙‰é˙3{aP$¨o¤~ž»Ç瑡#ýźí‚ĄD!""ŇG’5·ű!AŤs˝ÉŤ>©× ę„o+–ęńůEDdčx2őóşf6˛”HDDDúÇš„u\cé˙3»ĘĚfć‹vý§Ńçö4Au÷)ŔsŃ®ezy~Rţ‘úy.`í2é#[Ą~~¸ąÇ1,ťúůŃFźŘëT¨ .¸HŁnŇë‹~ĄŚ@DDDú™ŤvMíţG˛ľk/ ÚuĽ™Í—[RDD$G˛žÚE©Ý_0ł5ĘGDD¤| X µď‚âH÷”4 *ŔŠ%Ä ""CĂqŔôčgŽ5łQ%Ĺ#""R 3[88µűiŕĽŢGS“ăÍ _Ç &îKýĽ^ 1ČŕvŻüş÷Ń”ĂĚĆ3pýÓöş{o2‹đşŃ®Gš‰ˇŚővjŠýt 1ČĐq ˙Ş™ý Ś`DDDzÉĚfţ¬š:tđ—ŢGÄĘŔ<ŃĎ×6óäž'¨îţ>µłH­afłö:Üý`źŚC?1łSÍltŻcé3[¸ Ř26;p}3O.+AMgŃź-% JţŹě®LËç›ŮmföµänłČ bÁÇÍěŕ1ŕH`öT±éŔWÝýĘžČ˙–ą‰ÇźŢçîŻ7UG­ľf6x;Ůő ° »OĎ–H±db†‡fôÍó"đ2đas‘~d„ńś &[ŃĐČIŔî~E/Ëbf;ĆĂVĺîé™…‹ë(§[2Ů ŔľŃ®MÜýňR‚‘!ĹĚ6ţ|¨ěXDDDzŕ_”Ű­3»Ř$Úµ˛»?ĐLeuńřsęçÝJ‰BDD†w˙;°pj!‘ˇë)`W`ő>HNçĄvčćýÍ&§Pb‚ęî·R»`ëVf6ľ¬xDDdhq÷·ÜýP`qŕ ŕÂbá"""Ůŕ"ÂD€Ë¸űźÝ˝ţŰ0nĹ­TRZ_3;84Úu€»˙ޤpDDd3ł ŔÇ ăxćĆ•”H>Ţ Ě™đ"đ pł»O)5Ş”dĺ“]3€…ÝýŦë*9A]śĐŠZ™Čâ9` w˙ ´ DDDDDD¤af¶pA´ë2wß´•şĘŠ»? śíZŤEL~úůČV+*µŔĚVîŽv=,Ű'ý¨EDDDDD$‡™}×]ý§»Ż›WľžR[PÜý ^^f)`ǒ‘Ćý0őóOŰ©¬ôT3[ ¸)ÚőˇUKô!3Űř[´ë.w_Łť:KoAp÷›©m^8¤¤pDDDDDD¤€™Í“Úýă¶ëí‡T3[¸“욬âî˙./*I3łc€oF».w÷MÚ­·/ZPÜý1ŕçŃ®QŔo“5uDDDDDD¤ŮG€ŻG»ŢKýܲľIPGOF?Żü¨¤XDDDDDD$bfłg+Žt÷':Rżtń­0łM€KŁ]|ŢÝĎ+)$‘aĎĚF—E»Vr÷©ť8Gżµ âî—żŽvpş™­RRH""""""†dĆÉé`ÇN%§Đ‡-¨đżĚürŕ3Ńîg5Ü}b9Q‰ Of¶đ§ÔîÜý¬Nž§ďZPÜ}:°=ˇą¸âĂŔůf6şś¨DDDDDD†3űpbj÷O:ťśBź¶ VŮ2ŔíŔěŃîSÜýK%…$"""""2lŮÂŔťŔ„h÷Ŕ¶Ţ…d˛/[P+ÜýQBKęôh÷žfv@I!‰ f6 p!µÉé}Ŕ®ÝHNˇĎTwżřNj÷Ńf¶eń uÉĐĘ3€Ő˘Ý-Üýťnť·ďTw?8%Ú5’0őŔ’B’Ěl^ŕZ`›h÷űŔ6îţlWĎÝĎcPcI đ©Ôˇ3€˝;9µ±Čp”,ďya’Ú؞ŷăE *€»żl\ź:´+p™Íßó DDDDDD†3۸™Úät:đő^$§0Tw°6jzŠă5;Í죽ŹJDDDDDdđ˛ŕPŕl`–čĐŔFî~|Ďb,]|ÓĚl?ŕ8`T´{ ˇéůĚr˘<Ělp°męĐ#ŔćîţźžĆ3XT3Ű€ĺĎ•:tđ#wź>đY""""""bf‹–‘ůHęĐeŔŽîţfŻcT]|ÓÜýB÷އS‡ľÜffkô>*‘ţefŁĚě[Ŕý LNŹ&´śö<9…AŢ‚Zafă3ŤS‡fľďîŻ÷<0‘>bfk'+ĄMľěî§÷>ŞŞAÝ‚Z‘d÷›˛ýŘ`ŕQ3Ű×ĚĆô<8‘’™ŮfvđO&§/땝śÂiAŤ™Ů:„;+f~ 88ŃÝßîi`""""" ‚ÁL IDAT"=ff+ß¶F¦Ď ¬ňwźÔëز ąBźj`ŕP`ÖŚ"ŻżţčîĎő04‘®23Ö#äD[–Qě.ŕ«î~WC«kH&¨f¶ đ3`GŢ-pŕŕĎŔąî>ą‡á‰tLŇZş °3°PN±źżw÷˝Š­QC:A­0ł%€ď»ŁsŠ˝GNůŔ5îţdŹÂiš™Í|ŘŘŠ3ňĆž~üÉݧö Ľ– ‹µ"iQ=ŘĄNń§k+kŞeŢ’n» K«źÖĆŐyę#Ŕ‘Ŕ_Ý}ZWě€a• VŮÜ„A»źhâ©/ŹŹooo&˙ľĽßŮHEDDDDdĚŚOţť X€”.EýF¶Š·óCŻíÇ®Ľy†e‚Kş˙îěDřĹ‹ 6Wgąű»%ÇÓ’aź ĆĚl`ýh[¸ÜDDDDDD2Mî®®n¬IiL j3[XX&Ú–ć*3.6fćÇy”0žôŃd»ŰÝß*1®®P‚Ú3›ťĐ/|aťŐJ_ń¬5WEDDDDDę™FßćÂŇĘżŻ»ű°™ëF Şô…e """"""JPEDDDDD¤O(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/(A‘ľ UDDDDDDú‚Té JPEDDDDD¤/Ś*;€ˇĘĚFKËƧ¶ŮYŃM‘ˇč}ŕM`rňoĽ=<č^2w/;†AĎĚć>¬¬lËcËŚKDDDDDúÚKŔż“íŕwźVjT%R‚Ú33`U`S`BrŞ–Pi×$ŕJŕ2ŕrwźXr<=ĄµAf6†nl ĚWnD"""""2Ä9pp)pˇ»ßWr<]§µ3[Řřa,i٦Źšę_ ¶˙ůäd{ ŃąhEDDDD¤Oڎ:÷LĺßŮ9€ĄĂçm˛ÎŰ€€sÜ}jçBíJP3$]x?ěGčÂ[ŻűîŔŤŔťTűŽ?2T?4"""""Ň>3›—¨®”lë‹7đÔ˙~ďîOw-Ŕ(AŤŮH`ŕ{„x‹Ľ\NhnżÚÝßęnt"""""2Ô™Ů2„F˛M€u€ŃĹg~čîô Ľ®S‚š0łÍ€źfâÍóp p»ßŰ“ŔDDDDDdX2łY €€mČOVg§Őç{^W űŐĚÖ~¬›SÄ«€ßw÷齊MDDDDDŔĚ&ćĹŮřpN±)ŔŻ€źąűä^ĹÖIĂ6A5ł__,ŁČk„~Ý'ąű˝ŚMDDDDD$‹™Ť ¬.˛/°QN±×€Cßşű š”uX&¨f¶#aö«93żéîoö40‘™ŮšŔŃŔ§rŠÜěîîĎô.Şö «ŐĚć~ lźqŘżßw÷g{H‹Ělkŕ(Âň5ioű»ű©= ŞEĂ&A5łĎ&8Z ăđ Ŕ·ÝýîŢF%"""""Ň>3› ř đ#`žŚ"_v÷˙ö4°& ůŐĚFĆš~#ăđ ş› """""R$é5zaćß´‰ŔÎî~uoŁjÜNPÍlvŕŕ3‡ŻöLý±EDDDDDaf;†7¦çÝ™ěçî'ő>ŞúF”@·Ů˘Ŕ- LNßľ|ZÉ© Eî~&°"pEęĐ(ŕ÷fvt2#p_’-¨föqŕ"`ŢÔˇíÝýˇŢG%"""""Ň{f¶p,0SęĐ…„.żďö>ŞlC.A5łíS™S‡ţAHNµtŚ +f¶.p>0WęĐ=ŔćîţbďštŰaf{c`rz<°™’SŽÜýŕăŔc©C«7™ŮB˝Źj !Ó‚jf»ZNă¤{:p€»_JP""""""}ÄĚć$´¤®—:ô8°®»żÔó "C"A5ł/FF»ßľŕî——•H˙IÖL= Ř#uč!`˝2×Jô Ş™m śKŤŞb °qŇŚ-""""""33B’şWęĐ}„O^ď}TĎÝ·ëúąC‚š¬Ńs°v´ű-BrúH9Q‰H?1ł+¨3Q1ÁÝ'ö:Ělŕ…ŚC—ąű¦˝ŽGŔĚn>•qh6w»×ń Vfvđ˝ÔîíÝýěnžwT7+ď ý¨MNöč÷äÔĚĆ10î^řŻ»ß]ÂyEDş"Y÷şÓIŔ•­×Óĺ‹ R˙¬|.ÚwĽ™]ëîŻvë¤}ź šŮ"Ŕ‘©Ý§ş{zä~´0py çý°q çé–Ný-}ŰĚî%,@~#p‰ş€‹ äî3Ělŕ!`Îd÷‡€ß;vëĽ}ź  vÜéËŔ·JŠEDšdfK{fşIëK f%ôlYř&đ˛™ýřµş‚‹Ôr÷—Íě[Ŕź˘Ý;ŮYî~a7ÎŮ× Ş™í |&µ{_wŁŚxD¤%‹ßÍŘ?†°Ö–H™ć~|ŮĚöv÷‹ĘHDD¤ź¸ű©f¶µ]}gf7t#/ëŰuPÍlnŕ—©Ýg÷r‘X6>\hf?/;‘>ôe žhn>ŕ¨nś¨oTŕűÔN˙đő’b‘áá@3;¨ě DDDú‰»?ËŔq{šŮ˛ť>W_vń5ł… 3÷Ćbă¶ţŐĄşßíR˝"ýl7`lĆţ®Í2'}aw?-ď ™ŤĆó# Ůą Îź™ŮýîţŹŽF*˝ňy˛żďô:‘!ćw„ë­5“źG?¶íäIú2A%ŚO«ř7{2H˝äîO—„ČPáôźdI™IÉöŕŻfö]ŕW„D5‹?7ł+µ$Íŕăî/—ČPäîžüz}´{3ű»ßŃ©óô]_3[Ř=µűşH‘Np÷‰îľ#áfhž•čâú"""‘»ß@XŇ2öłNžŁďTB3ńČčç[5«˘tš»­©­UDDd ďýĽľ™}¶S•÷U‚jfkĆfĆ.#ľLĎ9¶ž™Ťîe0"""ýÎÝ˙ś™Ú}D§ęď·1¨¤~ľÜÝ˙YJ$2(ŮXÂň•í}`"đ_ŕżew 7ł™“łT¶YuĽ<íž´ÁĚF~§ów'&Ű«î>­ÄđH­…€Ł 3Łż <ëî^ôܡĚÝ3ł€OgGXé¦ŢF5¸™ŮěŔüŔ„ńĽ//şűäRë‘db® „ďÚ\Ŕ„ďŰsîţ^ă0``n`6`VŕÂDŠďŻćĂĐ*iĹ퀙’źW7łµÝýĆv+î›ŐĚć#ĚĽ;¤ŚX†:3[ Ř>çđ˝î~EÎ1ř!!K{8ľ•˙“‹ěµM€Ťĺ ŠO2ł+Ë€ż»űëÍžŻĹřÖ"Ěú`5 z*Ů+Ŕ}Ŕ5Ŕ•É©fÎwPFýŻ»űIÍÔ“S÷X`˙ŚCOąűYĎŰX#ÚµtNŃ5̬™wşű5çý°xơ_»{Gf¶6ł©~öÖ˘úG9í3»¸¸ĚÝěĐů—`ŕßI€ŰÝýşŚň‹{;‹’…´‰föÂ:Ó—v"ÎAč*˛T€…{@˛ú˘‡Žw÷·3ö7[˙^„*±éîţ‹vëNę_řB˛-‘SćMB—ęS˛.`ĚěsŔŞO=ÍÝ_j"–ťÉţ˝ýŇÝ?h˘žď2đ;“ů÷ŐĚf#Lşµ'°:ŮŢ3łëKďÁ”FciTňťß…đy^˝ÎS>0łç « ÜÜLZĄ¤UD ąűfváď^Ĺ×¶TÜ˝/6ŕG„ĘvKŮ1uŕ5-›zMń¶f‰qapsV\ď+uŕ˙WđÚżÔB}#˝€ç ę-Ú&ş‹ŹíŇ{:†°4R«ńU¶Ç€€y<ď´Ś:ďĐkš''Ć«ę<ď¸6߼íŘ:ç˝"çyóvŕ˝Xř{±˙X¦ql–S˙/RĺćKÎ9ŁÉ8ŻVéĆw¤Ż=/ćÝ;P÷¶ő­ÎsČyŢĄMĆpMN= tčýűwFÝďw ŢóZřN<|"U׉9e›ú˙’pq”UϬMÖ“őýy4Uf$đcÂâőÍĽţç€]:řýXžđ7°Ůď|Öö"áĆ^OľŰÚ´iĽ°JęďÇŔ‚íÖŰcP“n_Ií>ľŚX†ź¨] ˙ ĄŤÎ6łq­Öofk“?;ć_ÝýŹMÖ·đ đÂĹP+fŽMĆ:wŚ™}x‚đ™m5ľŠĄ€ŁwŔĄdf6ĘĚŽ $‡­Ú xĐĚ~af#ë–nCŇ‚ýŻäśY-¦EÖnIZ˛†“˘®öéVGIŮ.ŔĂŔ6-<}ŕ3űVgŁę3[¸ŽpC¶Ů˙3Î0łźw ŽďľóźĄůď|–ů = DD yčůĹŔś®i}‘ ţs›?úůeŕś’bÜýżŔNdO˛,pB+őšŮ<Ŕߨť‰ąâqšüĐšŮnŔ•ILť°0pť™m҉ĘĚěPŕlÚOLĄĎŮ,Ŕ…„nÎťH*GßÎ1ł™;PßŃ÷eBŐŚ.NÝá"Ż«6„qí’bf»Ö'ź­Ťjf~ifżęLT˝“t·ż—0䤚YËݬÍěhÂęEźa‘núMęç/·;Á`żŚAýzę瓼‰q"ŇwżÁĚĎ8Ľ»™]çî§5Z_2!Ăid'kSíÝý­&ęűđ“:Ĺfş®˝Hb4ˇ{ăĘ„ !˛Ś.2ł-Ýý˛FăIĹ68Ć–ˇx řaâ¦7 ­ąsK˘Ö™ľ”$§Wź¨SôuBWĹĘř¸7Sć,xÎÖŔfö9ďŕ„)f¶&pŮ7ßNb|•đů_€âĎŢhŕ3[Á;0ţq(z/^íYD2ŢűŠorOî^ ümž‡Đj¸Ż=ľ‘ŚŮ’ń¦&ćKű€đ˙ŃÄäç „ŁE-›ß6ł‹˝É‰E’ßĂ·ë›DčNüJ˛M"üß8žĐ0°íÝd9źđ·ľrý?/a>‚?·\cô]^Ô`ţ˛ăęĐkëË1¨©G&ÉŠńm`Ů&ę:°ŕőî×d\;ÔĺŔť„‰žćĚyţh`CBkR^˙mőłF¸c]ß›„é¶×FÔłabŤsă+Ď? Á8úq ęX`ŽhËß÷ŰTązŰĚuÎ۱1¨IlEżß« %ŤĘůěm ÜR§ŽcZ+o ę_˙9d}?–ő>Bč)ńA'cěÖVăî¨űőo[çąĂj *ádrÁűő,°;0>çůsűţţ¦?ŻyďA?ŤA}¸ µopVňý—QĎü„ž Ţ·G‘MÄ6KĆwľ˛M!Ü@ݨ^ť„ÄyQÂ$'QýhF'>wÚ´içžą±­úúŕ’zAg–S_[ß'¨Iś­+YqŢO 'Ü\ČŞăÜ&ăY*ąXÉŞkˇ%¶™ú¶Ł6ů‹·«[xż6Ëąp©l'ÓZR4Ž0ŃŇÓ â5ŁžŤrę)śô¨…x;’ ź+řÝNöi°ž„›6YżŁĘEíú-|öňb«ůÎ5úş ě9őLféä祉ßoŢkÝ˝u?PP˙Šuž;ÜÔ˘ÉÂNĄÁ$¨6:ńX?%¨ţŢk4XßŔ­umÜDlŰäÔ1ذŤĎÉxÂ’˙éÄçN›6mĂc#´šNŤţÍ ŤÇ~šž\ˇőć`i‰»żBX†"kZů•€ÂńAf6'a±Ţ¬10OfßmH˛<Í™dw9zXÍ –8Éâîç–|™šqxf&„I^ëédw×rŕ›îľ—»OĚ8^/ÎwÜýB×ßł›}ľ´/™°íäśĂÓťÜý÷ŤÔĺî3<,á±áł1ŕtŔ»0iұŔçý şűäOr3ľŕŘ`fźVĚ9ü’wh‰ ˇŔĚ6'˛°Ó€/z]Â=¬˝-ˇ—Ë`ua&â;)ěî“7ěžĎ)ňĹ&νeÎţ=Üýę&ę©áîoşűqä/&"2@rÍ˙í1`«Vë+5A5ł% c+Ţ"t7.3ł—»°ť×J0î~-aŞü,{'kôĺ9…ĐU5íBkç¤&BŮ’°vhÚŰŔ¦îţduýŹ»ßL &KŢţ,ű’?ľđŔä?ö¶¸ű4wĎšaYşo;Â8ą,ßw÷¦ż_î~*ˇ«m–ĹčlxđmOng6ĘĂŞgćnů?~—Ś%<¶ HËúCÔ~9űöjás÷>aśRÓ7ôúŔkŔ6îŢÔewźLXJ,ËffÖčÜ Yk€O%LěÖ6×:¨"ŇĽóS?oŰjEe· ¦/Ě.u÷¬V®ˇh.B×ÚNosµÓá„)ółś”ÜP¨afß ˙öŕ¤u¦ćě?ÔÝďo˛®î~Ëľşă<¸%7)ňfíý?ocfqwźBţÚŔk5r¤§ąűËm<˙&Â,źi‹ŮÜmÔŰWĚld2ű齄®˙y.s÷› Ž7»‘=´á^wo·çÓéäw{íGĎ’ßă ®$™ż(çđę V36cß,­E$"Ň>KX¦×Dݢ•şJKPÍl!ÂäS€ËK GÉî.dŹG] 8ŔĚĆf-ĚZçčyZkÉÉSó—¤+X'\Bčzś¶VĎÝ8g˙Ő§6$¬›ł˙uÂç¦]çďä[Żő˙ˇť''ß׬&.ëWËšŮzŰf¶ť™ígf§Z˛Ď"Ě\šçň»aWy7oţŇnĹÉÍ˝Á4˙ÄźZm1ŽÜ“łżŃ±źYCgVLćI)Ë©ź[ĆTf ęfÔŢŤ˝ÂÝó.ޤ‡’»áycćľff[şľ-‘q|:°c2Fłň<ďXËş»żKX˘&m­d×"y ĚďÚ‹JúDŢřyť¸A’ü}ËVo˝Őz&˙jł]™łŚď@ÝÝr0ahBŢv5áćŔńŔ®dŻÓ›FdęßÝ xĘëęť×جôEM?Ë ÓŚvżkŹfěś“Lö&"R†ôßňĎ&CäšŇč`ünřTęç‹K‰˘<'Ö0ë´§:TϡŔ:É–v&Ů-§?jĄ[ś™Ť%»kÓTŕľfë«ă?Ŕ'Sű*c‚3»HšŮ d/ĘpCçB“ĺ%‰·uđ·fĚnôÜŤşŁC]ĚßČŮßĎ j'˝ěíîęÍIĆźfuó~x˘C§yĐs§ěˇGő8p{ęi÷»v%°iĆţ €;Ěě'ŔůmŚIiš»?cf÷ÖZC¸ÁŮTnPf‚šľ »ą”(Ęs˛»wâ?ą®p÷éf¶#ˇU&ťĺ%§WG¶xĘUsę}¬ c;ł&§€°îgŢľUrö?Ţbk±ô‘äîŢb9‡óş˝¶"Ż•sQ3›ŚUmE§fA}+gÖ˛OCÍ? kŞ>]v }hŃśý˙ęTäîďšŮč˙ĺMŢr÷÷:QOÎţFżk§&6ś=ăŘ*„µ7łKÉě?“D""ÝvŐBÎ×˙ Ş™MŹv˝ć‹äs÷ÍlWÂŘŕzÝ__viăbeBÎţĄĚěéäqCÖăF÷ĺ]M“wLcO‡†9 ŽeuĄkŐ#ubh5Amf)§"yăęú˝U«Uďş#ť\§Ö¦\yă;Ý čú?Aí‹ďš»O2łQĽNůRŔ7“mŞ™ÝBqţ&ŕ «‘.ą…ÚeÉŇ˝ë*«5h'»ĐIąűfvaśWžŔÎÉ"˝­Ę»š™ě5V»ˇ(AÍ‹/Ż›– .Y­ďw¸Őaˇ‹`Ö źŮ—Z¬·-:CŐ BWÔÉÉöaúíŔmM®Ó<\ĺÝŔÉklŐ`ř]ôÍwÍݝ̾WĹÇë'Ŕfv'ˇuőŻîţx—‘áç–ÔĎMc*ë®x:Đ[K‰Bu$Pt‘ţKwż¶ÍsôĂĚy]—!?ľÁpA%őĺ]€wô÷›tW3çp^’,Ĺöpw+ŘFşűśîľ¨»ÄÝ7s÷ĂÜýJN¦µOąűŢŔ·iľ÷ĹL„Ć‚CÇĚě63ŰşÉED %Ce^ŚvM0łĹsŠg*+AM· *AíoÇRĽľÚfV”Ü5˘ß/Îó^ßÜM—¶äÍ0×j—Ű"yꙦgą鑼5€;Ý KłĎ¶ŔÝŹ–~Kë7 ÖÎî4łĺ:› [éÜ®©nľ=ďâ›LĎÖ:¸Ł×qHcĚlg`Ď:ĹV~ěßĆ©ňĆÂ3y1”-ŻełÓ“gŤ—îţ"°ź™lKX·{]`ţ&«Zť¤îŕîťX˙YD†§[‹*>Aë]—1uIj[ r÷·KCę0łĄ,ţ 3»ÖÝ[]ďőśýwąű.-ÖŮIy ęPľ ŞădÉ»ofÖ©És’žcsOîÄ9Dr´Óu3÷űŃFťY†ňßÓžH&>:=Ů*˙ŹŻ ¬GX‚&oBÂŘ8ŕl3[ĎÝŐ€ "­HĎ/´b3O.ă4ÝYł÷ö!3ś ĚÚÄÓN1ł…[YB Rß±Ô®aT1ř*Őę=đ73kĄe>omŇĄűd҆çsöŻQr|YăóZčš5O‡ę &SsŽ­ÜÁóäŐ5µ wyc“‹Ć˙7ŁťďóC9ű—ďŔüŮ<4ßUšäî¸ű±îľ °źíŕ9>×äąeřČëâ˝@ęnz‘ô wĺě/Jnš±S‡ę‘&ąűy„€łčĆ´*ťă5ÜđˇTůźd†ĺłČ«ô°SŞ•çŔżłŞÎ0ł˘ńvY®ÎŮ˙ĄNu#kÓŤ9ű÷5ł‘=Ť¤jbĆ>ŁÍn©f6‚üdŞYyËĚݡú;%/IÜŔĚÚîzÜüÉKú• JÖw˛‡Z4kăÔqMÎţ“˙;ZffsŰ´S‡´íŇśýĂi¨‡tV:Çkxj ębŃăŔ3%Ä ŮŽ"˙néî^33iőüđnFů „$µ™ĎŘŮ„ĎDÚ"Ŕ^MÔÓ-yÓc/ ěÜË@"÷ĺě˙T›őnIíwµy jż]ř\MörG#€˝;P˙ľ9űß®ę@ý2¸uĺô°8s IDAT»śÜ\ٱť:#ű»<áfe;ˇscmĄ5Y7›ˇ˙zşČŕ18Ô¤E-ţOč9wĎ[\zČĚ6ľ™sřŘĽőĐÜý!ŕë9ĎŰř^Ł1¸űc„$5ËáI TiÜý6ň[QŹiˇĹ¸ňĆM¶ÜíÎĚĆŇÚ8â<Żćěďäě¸ms÷Éäß„8ČĚlµîd©‡Ľ‹řÓ’sËđ–÷]ŢĐĚćjŁŢźĐĆřÓŠd9¸żäţ‘™-ÔJ˝f¶đµ–“NY&g˙‹=ŤBD†’Á‘ s¦~ÎëŇ$=”L qjÎá;ď=ßÝO!˙Âĺ03k¦ŕ'dOF47p±™uzÝ=šL<~žłnB‹q§fĐmÔ-9űW3łV'·ř5M®WUÄÝ_!;I]ÉĚúm"¦ĽeĆ'¶Ň•ŰĚfN!;Ipŕ7ÍÖ)COŇC幌C3ßoĄN3ŰŘłť¸R~Eödvă«ĚlŢf*Kľ˙—RΚ얙ÍffmOž•˛^Îţ§:|>Ňy^Ăk]÷:AMOÜ’µT‰ôP˛$ĚßKĤ˝ ěĐ`+÷WČ^Óv$a陆ZÜýßŔ‰9‡Wn7łĺ©«3[ÉĚNiâi—Wć۸ĆĚZ[iÁćf¶Q#ĺÝýIňÇ/ţ®™uiÍl„™ý–ît§Îęľ8řNÎŐ2w8?çđf„µ~^V(›w.ůcOĎt÷f>2´ĺµŕďof6S‘™íF¸1Ň1ÉgőśĂË7›ŮşŤÔef[˙¤vm`ő¨jĚ’ŔsföłŤŹ˙8ů=ˇ.n·~¶Ňy޸FźŘë»–éŔ†s‚ş©™-×ĹúŻq÷¬»ńi‡“ńĽw’Őĺîo˙?{ggSÝ?đ÷™ÍڱoŮ—˛Ż…É."{ô’ZżžŠ¤¤žçˇ¤H´H§D˘Č’Ą¤}‹0d cźaĚ|ś{ĎÜsîąŰĚť™;ăó~˝ÎëŢsÎ÷śóť{ç~ľźĎ÷űY4MëüXë•F_ˇíäĎ˝€µ°Ź˝Ş üŞiÚ$ŕ=Çęśß8ÜĐş=\îď©ţĄJ)ĄiZoŕwôŘS+Ť€=š¦Ť>QJÝôł_…‡Đăkˇ»[ďg·f8žkĄ4đ٦i}•RžVZťĎżŹů3?KđâDvőôkšV ]éÝ śQJŮ­ g&Ń?»Ő ~@MÓ*ĄţđvMÓjłđ\¦ćâÚ(™‰}XDşÉŕ3ożǤÔëŔŁ.‡“€‚S‚ężčňÓÎˢ"°FÓ´Ečź+•Rç]úV h<X3˝oCźČę„>Ţ äG÷n¦iÚ·čá1ß:rCř…c˛­=đ9î çńś¨iÚ0ĄÔD?iZwô˛vF`,şËŰsš¦ý€> ˙ ş+Áyô‚÷ůĐđÂčmëőďý^óĐżsš¦=äx®ťŰf1ŕŕeMÓľCO€óđ7p](€žn»>şqŮŠ´˙gĎa_ŹővôUŤĺŔ`/şá‹Z]Ai`ąîzŮO«Ĺiéă8ŔÎş©Ćk’¦ig;Ă~şRęŤ őÇ#J©ż5M{XäˇIS`—¦iËĐ•Â]ŔIÇą’č Ł+âŢľÓÇ\•wAPJĐ4möFZ şűś¦i_ż˘ËĽ0t™Sý®î“„OĂ€t{ź8äsW`-ö%p4ôń§ €¦i‰č5^ ă9ö2z½yzlzúśĂÉ…>éÚ¸¦iÚZô±s °ýłż.S ˇŻX—@—cýŃ“zâiĄTBĆu]„N¶1PĹĹ7Dp¸ÍĆŢXۉ®ĚŚRjަi-ŃK+ojš¶A)婞žë}ÎhšÖXçBđŃŔŽ-SQJmrř qŹ­vR=űk02ŔzëK˘¦iŹđě¶?ţ—ŤQčŠËďAčž~CĄâ5M{}•Ö‘€§ŕô$Š Ą”sµj öźi.Jx€$”RËÓŃE!çňčµw=ąnÖ&°2R“•RÓ4MK“L·C)uPÓ´čFŞŻäpŃxţ[@_Ů}D)ő‡÷yO™Ŕ3ąŃ'íĘ %هÜřË4ĄÔAé• ·*ÖĘ~»řfv ެ †ŽŇ/˙ĂŢ…ń*ĐS)•ŽG Ä>±B0×ßDGJ©ŁčîÇź§Ł/†Rj-ĐH"ˇ”ÚľJ’Ţ•†›ŔłJ©ŻŇß+7&źeŔ}3ĄÔ‡č«:~»€űAĐŐ‘XLÜPJĹ] A¸ťÓ»"č8˛®7V§ă6űJ)gśŁ§Ä?’ĺ:ýbśŽžĚ¨Ž‚pk ”JF×{śř˝‚šŐI’ěj Ď(t70;žNoŇGÉŚ‡±Oxqđq÷JPJőA_‘őT'0­¤ źÖ8>«zčŮ}ĺ u8’†ľ|#™ÖÉ…cŔ}J©÷Óx˝W”Nô>zŤß ”R €†¤O w˛]_„{ 9ĄÔ&ô¬Şi-ń‘žC źżqđiA)ő§RŞúoúH—žF—™ő•R»\Ž{ň’ŐĚ%ŕ¸ĎVs袔z1r‚3pµőBÖ@µĆźůĚ/G†ĹW=śž­”šŚç(Ą~Ĺs|k/GŚ_ ÷űÝŐ·+°űRţpX†ëT^)ŐZ)ĺ©DŽż}‹WJ G7ľ'“6Ąňđ#ú¬u ĄÔ7iěËôzvłŃ p8ľşy—c%6CQJÍVJUFODô z–ŰÝčźŰeüďw¦ ”ÚîPÂ;?X˙RĐKuTJµ±(ă‚ŕĄÔvô¸Ň×đßŰ(Ý;ćnĄÔ'Ô57żé č“9ĐeŮ~ôßóô ď?˘{PtJ+Ą†;j«şbçŐsS)%“Ů.(Ą)ĄĘuĐó1¬&}nĐż ×i®®”ň{/‚\m=MÓ4kŽ[´Ěś$Ó4m0ÖĺĐKJ©q™Ö!Ç iZnt§%şaXČeSčJŃôÄDűĐ“í¶f䊂K˙jˇÇ|ÖFOFT”ÔŚ¸WŃ•‰Ž~mÖÚ(kéí3cf[ôdS…Ń“GťţBź_…žůQĘ;ř‰¦iEHMFSý{-‚ţw8‡ž4éGŕ;Ą”] XAđ‡Ľk‰[Xý˙­ úĘâqôßóô˛EÁp ÎtJË%Ü)íVJ­.sNĹşSÝŁ§’c+‡îą‹ß}ě‰v ˙Ďüě§A:š¦ÁśŚ-Ćź0B1PAAČRĄ®ě<8f)ĄÍäî‚ A ­jf»ř ‚ ‚ Xéĺářo™Ú A!ËUA„,Ă‘ŮÝS˛şź2ł/‚ BÖ#Ş ‚ YÉxěKĚü®”Ú–ŮťA˛1PAAđMÓ´ Ţk0ČĂéőA!ű Ş ‚ ĐPÓ´ď5M»/­7ĐtFÓ=4ůř<­÷A˛/b  ‚ ‚(÷k5M۬iÚ š¦•÷ç"MÓÂ4MëüŽ^ăŐÓjěŔ`—ŢA˛YÝAA˛-őŰ[Žr[€ť¤ÖÖĐëSîFŻ_ťßÇ=?PJ-ɨ ‚ ˇŤ¨‚ ‚ ňŽ­{:îń?ŕ˙‚ŃA!{".ľ‚ ‚ d5 ­”zD)u=«;#‚ db  ‚ ‚ç€Aş—ľîVJ˝¤{ ‚ ŮqńAÁo”RU4M« t €r~Ţâ&đđ#đ…RjgFôSAČž*‚ BŔ(Ąöűśűš¦ĺnwlE€X 7p}Őő·‡ý—ý¨»{łÁę:€¸î[_ŻÇcŽ×S¸ y…ýgm§ŮóŘŢÓç+†ÝIěpŤ.7Ęĺ€"¤NNĺb1Ë «q=H2A…Y.ŘM‚Y÷Ż:ÚĹŁËŹ8trĹr__«ćá¸ÇkDv·i”#E0ë ů0Ëoú‡ëk®»›„YvXuoűˇËcŔI ĹroŃA„l¨BPńc ĐĐŤM§ŕ/ëŘʸĽ–&pˇ,˘ܨµăú`á4ZăH5^ťű—]ÚŰłžö˝ ĆqIŘ"d'ü” Ś·a–e\öKŁOpe©Šjzą@ޱz̲š+ 71Ë«ęŻâéSáŮ!dü”#1冫üpŹÉŔnz#ұĺKç}n'0ëVYďŇ>PÄ®Ťé®BzUH3^‚"@5ě…i `¦t0k‰*86O\"u 8NŞţĆ]ůôőŢNŁU)|(‘a@Uô•ϲ¸+ŽĄŃ¸śNÇVŰĂůdtO ;r؇>QćŹëÓpµ~g"7„¬Ć‹ÉTǬ{¸Ę"™ŇÁ¬%‚ÔżŰWĐĺ…sĺŐiÄĆÇ˝év†ŞWD–ţ!Şŕ^‚@= ľËV.łú•ÍÉÔplv¶şl[Đg<í ×Wë !F«Ąx‘Pł ą ÝWđN8PʱÝcsţ° ]vlvĽîÁĽęęM–Ř!rCČ2<Č‘<č2Ă)?ꕍäDˇNôĹ„jÎź!U÷pngçětç«č BşUđŤĐČÔĹlŚŢA& š¦‘;wnbbbČť;·ió÷ëq€„„®]»flÖ}Ź%$$’b ő ÎŮŢÎ.ÇŽj°n¶ˇŻÄÚ Ţ”Oż („@ńbŢŮ­Kú]Ůü"222MrĂîXtt4ׯ_O—Üp=výúőŚř“ŁĐ?ßşŔăŽc ŔĚ_űHMçMé‘B&b#Gb€:č˛ăntYR•ŔâÄÓÚbbbŇ%7\Ź………MąvíZFé Ĺ€vŽÍÉ_'Í·çń-;D–!Ş`` b€;Iť‘Ľ¨B ŃŃŃ”)S†˛eËR¶lYÓű˛eËRştibcC{AĺÚµküő×_ÄĹĹ™¶cÇŽď‚ń¨ňŽ­›c_ˇ»âüNꀱťÔ+®†Şő˝Ż¤* ÄG𫴠ćɬz@ˇŚx~ѢEM2Ă*CŠ-JDDčw)))ś;wÎ$/¬2äÔ©SÁPBc€†ŽÍÉUô‰.WĄó ©ň—˘iEä†&,˙3QčîíNŮQÝŰ(č?䨨(J—.íQ†”)S†E||Ľ›ÜpÝ?qâ7oú[ĺĆ+ 8„.CVË€łrK˘iÚ̡1J)ź%ŮÄ@˝qŠť[+Ň™9·\ąrÔŻ_źúőëS·n]*V¬HéŇĄ‰Š Ę“ăIJJ⯿ţâСClÝş•Í›7łyófţüóĎtßŘ€®h.EO‚ l6ĽĽűA#ő¤ 9‹Q†űŘ č‚Kšf˘ŁŁ©S§Ž!CjŐŞEąrĺ(RäVČg.^ĽČŃŁGŮłgŹ!?¶nÝ Ăőş’ąř˝,x–!vŻÖ÷ú‘·.r¤0Đ}bë~Ň™ýşdÉ’†ü¨WŻ•*U˘L™2·ÄV0HNNćĉ>|ؤ8p€tţL“Ń'»ľul’>Äú^? ˛$$UđŠË€ŕ\ĺčŚî敦iĂRĄJsE2c8ţ<[¶l1‹Í›7—ž[n#ŐXÝ…ý@ámŔp}µľ×Č@‘c°ĄŃ@ktůŃ˝ÜKŔDEEQ«V-“ü¨YłfH»áfWRRR8pŕ€I~üţűď\»v-­·Ľü€®hşzg8Ý?ü1Z­ďő"7r,.r¤şüč4EOö0ĹŠsÓAJ”(¤Ţ ®\ştÉd°nŢĽ™C‡Ąç–{Ń'ĽľE_eMFt‹¨‚Ž! ÝuĄU˝Ďm·Ýć6/^<Č˝áďż˙6 ›7oćĉiąŐQRŠ_ĐW[˝¬2PÜXŚŇBčĆhg -fŘŤ zőę†ě¸ű]»¶xVd!ÉÉÉěݻ׿ýö;vě 1ѧÎ`% ř ]~,EĎ<¨˘i}Żą‘íq‘#uIő´đT6É#… ¦^˝z&¤L™2ÁěŞ ńńńnçGŹMË­N˘ë Ë€učŮÇťá˘äÄ@c@Č…ľĘátßő{•#22’¦M›Ň¨Q#c (]ştőV&'Ož4ŚŤ7ňăŹ?răĆŤ@nqXŽ>P¬BOžâ Ľ xy5!EhŚUŽâŋӦMîľűnęׯϝwŢILLVŐĽü%))‰]»vĘćŞU«Ň˛J˛ŤTW`§w†ťěŔć˝ë«ČŚě…C†DÍHť÷Űš ŁQŁF4iŇÄĐA*TđVN\Ξ=kČŹM›6±zőę@=5.ˇëK¤zg’ŤőÇ1(ԽГůEľ|ůh×®ť;wć @ŐM!ą|ů2ß˙=‹-bٲeÄÇÇry"ş’9=v$…ÔÂźBf4ł .Fin 7đ$ş,ń›ęŐ«Óąsg:wîL n‰„#·»wďfѢE,Z´ß~ű-Đ8´CŔ,`6© Rěä6ď]_ Dn„.9R ]y(čďµ111´mŰ–Îť;Ó±cGŠ-šQÝ2‘„„V®\ɢE‹X˛d gÎśń}Q*IčćÓŃWV“1ËOz^^ D–db Ţ˘hšnř{]éŇĄéÔ©ť;w¦yóćân—Ăąyó&ëׯ7”Í#GŽrů.`&0=ţĚŐXMË̦ Y‡‹aZ]©|đkv*<<śĆŤFiĹŠ3¨—B¨pňäI–,Y¢E‹XµjU µ[Ż O0gtuŐ@äFč iZĐ]†4÷÷ş˘E‹Ň±cG:wîL۶mĹË"‡“’’Â/żübč ű÷ďäňCč:Čç@<î“ĺiÖA@äIF#ę-„C±¬ľŇ1?k Ö®]ŰP(ëŐ hDČaěرĂ(¶lŮâďe—ůŔ§Ŕ>R U»A®$…¬Ş†ůŽîľ;=·Ď%ĎŘŘXc•ŁC‡’íćĘ•+,_ľśE‹±téRÎź?ďďĄŰŃWDć×đOÁô(7Dfd Rx±ů•”˘RĄJ†Ҹqc‚^V]Č&ěßżźE‹±xńb6nÜčo‰˝DôÉ®OŃ“+YőcWAtLC Ô[Ç Pxx=’G"""¸ďľűŚ•ŇňĺËgB/…ěĆńăÇYĽx1‹-ň7nUˇÇ™M@_]M±ŮuÁI˝ą ‚KlŘ#ŔËŔľ®ąí¶ŰxđÁéÜą3­[·–r ‚ÉÉɆwĆâĹ‹ý-‹ux}Uő*ţÉl^ő‘™‚C†”^Bź÷ęzĄi 64ŚŇjŐŞeF7…lĆ™3gřöŰoY´h?üđ ţ\¶lDtF ÔL †iÆ yňÉ'éŇĄ  ú"\şt‰%K–đŃG±~ýz_Í𺡺}0pƉ¤Ká$‚E †ill,˝{÷ćŃGĄQŁFO*ÄÎť;™3gÓ§OçÜąsľšź¦`o¨z’ŘĽę;"32 MÓĘá§aZĄJ† BŻ^˝$ăż×®]ăűďżçăŹ?fĹŠţÄ˝˙ĽŤŮPuŐCĽ­®bój ň$8šCŃ4­:đ*> ÓţńŹ0tčPqß‚ÂÎť;™2e sćĚáęŐ«Ţš*ôzď ŞÎÁÁ_c›W}G4ăâĘŰ? Ó*UŞ0tčPú÷ďOţüů3Ł‹Bćúőë|ůĺ—Lť:•M›6ůj~ŠîţëŚswMŠb§`byo r#xhšV‰Ă4""‚Îť;3tčPZ¶l™iýr.äĂ?dĆŚţ„ü„>Yţ ˘„b ć04MË Śţ‰ľúaKĄJ•2dŹ>ú¨¬– ÂĄK—5kS§Neßľ}Ţš¦ '1 \@< ţ¬ŞČ ă´đp—§vtęÔ‰ˇC‡ŇŞU«Lëźpk±uëV¦NťĘçźîË}ď0 ˝Ě„«ü°S2˝Ę ‘éCÓ´\ŔpôUSŹľý%K–dĐ A<ńÄ”,Y2Óú'Ü:$$$0wî\¦NťĘćÍ›}5_ ŚN“*Cěôo†Şč AD Ô‚C±ě LÄKí°š5k2zôhşwď..xB¦ ”bѢEŚ3†m۶ykzxXÜ$đAB Ő4â€˙ 'QłőşŚŚ¤_ż~ĽüňËRcPČ4Ξ=ËŰożÍ”)S¸r劷¦? ŻÚĹ!†j¦ŁiZ ôíŞžÚT¨P‘#GŇż"##3ŻsÂ-ÍŹ?ţČčŃŁY·nť·f—ŃÝ~gŁ—«qę!)6Ż˘d0i5P%…ZˇiZôŮźx0NkÔ¨ÁĽyóرc=zôăTČ44MŁK—.lÝş•… rçťwzjZü˝„I4˱Eşlč.¨áč˛Čąi–͵ňďÇgÓŘ‹žť×MľGFF2pŕ@öďßĎ'ź|"Ć©©)R„qăĆqřđa†Nž<Ëu·Öϱ讥N™áŹÜ0™á?š¦Ó4m°Ći… 6mű÷ďçńÇăTČTš7oÎÚµkY˝z5M›6őÔ,/ú*ę"ôšŢN$ŠTYâMy"hš6=#jG»óŐŞUcîÜąěر‡zH S!˰޵k×öÔ´ zĄ'0©ÖÂ9HŘ  „W4ťÂŔ·č3Ć·YŰ„‡‡‹a*„ VCŐC ĚÜč±ÓËĐ'şü‘¶“[ŽßČ /hšÖ˝|X?»óeË–ĂTZ´hÁşuëXąr%Mš4ńÔ¬đ5đş<ń¦¸Ę« $ 5‹Ń4-ZÓ´OĐłć¶žŹŤŤĺí·ßfÇŽôęŐKę† !«ˇ:qâDňćÍk×,ş«Ţ{@AtCŐ:›˙+ŞÎgËń9Ô¶ص©_ż>żţú«¦BČá4T÷ěŮĂŘţűÔ@ŹIí€ű*«Ěđd¨ÜpGÓ´pMÓƢ{ną%˛ŚŚdřđáěÝ»W S!ähŐŞ6l`Îś9Üv›ŰÜ,čň`(0(AŞ‘ęŻ,$‹k' q¸ôţ ´;ߥKöîÝËżţő/""<ćI„,%<<śţóźěÝ»—nÝşyjÖTÁ}5ŐŰáq&óV ˙ `=ćřňĺËÇäɓٴiuëÖÍôţ ‚ż”/_žĄK—2ţ|O‰vňˇOvĺ&UnŘÉ1RýDÓ´˘Ŕr`–Ď  I“&lÝş•qăĆ‘;·Űüą „ }úôaßľ} 2ÄÓBNcôŐÔ»R'Ë}ąýzŐADždb fš¦µA_őpÓË–-Ë’%KX¸p!eĘxĚ“$!E©RĄX°`K–,ˇ\97{ ô2'_˘Ç—9@ UMÓ"OŃ??=SôL IDATô{÷îĺé§źŻ !ŰĐŁGöíŰÇłĎ>k÷«ŃÝŘ‹bŻ\z›ŕ’É-4M«‹®¸Ąď.X° ü1ëׯ§fÍš™ß9AH `ęÔ©lܸ‘:uęŘ5)ĚzáŮHµĆą['˝@&˝2Ń\˛MÓÚ˘'Crs§éС۶mŁcGŰPTAy:věČŽ;čŇĄ‹ÝéXôZe­ŃWCŐ׊]|*pk š¦Es€G­çbbb9s&óćÍ“’B¶$oŢĽLš4‰+VP´hQ»&Ť€™@a̲úb• F*š¦ŐAĎ”ě6ްaC¶oßÎOÍĄK—(\¸0E‹ĄB… T«V-(ĎYąrĄQăŞOź>­ź={–Í›7sćĚÎś9CDDĺË—7¶ ĄŹž8sć ÇŹ篿ţâřńăÜĽy“˘E‹R¬X1j×®M‘"E2ôůˇĘ[o˝ĹČ‘#INN¶žJ^67űÎ×›Ž×dĚéὕ–r~ xMÓÂĎ€ŢÖswÜq ,đ4s,ŮŽăÇŹóĐCńË/żŘťŢ†îâ~]^Xe‡µ<Ťłś¸ČŤś.3¬hšVXžmÝÄСCy÷Ýw‰ŠŠĘüŽ B0{öl̵k׬§0Ýí×U˙p•%veňni$-¤µĚ J©LŰĐă\żÔ™ůü¬Ţ€ű€«–Ď@)RD­X±B…;wîT PĹ‹·ţM[ٲeŐСCŐľ}űŇőĽFŤ)@EDD¨‹/úlĺĘ5aÂŐ¸qc汚¦©6mڨŋ«ääätőŃ•ŁGŹŞ7ŢxCUŞTÉëç¦îąç5věXď÷ýOž<©rĺĘÔ­gĎžAűűýeÍš5ę¶Űnłűl®˙4îBO†R(”BĎF[ČäAźÔq–ޱ͸§BŕwžQ›ăďťe÷?Ö©S'uáÂźßĹkŻ˝fű1}úô@ľR7ćĚ™ăvĎ’%K¦ëžň÷ß›ž?qâDź×ÄÇÇ«„„ŹçË”)cÜoĐ A¶m^~ůeż±±±ŞD‰ŞjŐŞŞAŞ]»vjĚ1ę·ß~KóßťÓąqă†zúé§=É×-@ô’(·ŁŻG7ľ xn1Ş*~ß™±ŐÓÖĎ1wîÜjÎś9ÁúʂƨQŁLżź`éI&L0Ý÷üůóAąŻšěرCU¬XŃN~¤ × ż=Ü®¦C©”vŃAś˛$7·°’Ö 8bůÜŁýş.“;y˨Žá˛őR¬X1µgĎJ\˝zU=őÔS*<<Ü«áeÝ"##Ő /Ľ ®^˝đ3Ďź?o<ŻiÓ¦^ۦ¤¤¨©S§ú4śí¶ *¨ ¤őŁQJ)µ˙~Ő®];ĄiZŔĎ/X° zóÍ7ŐÍ›7}>çäÉ“ßß×ÖĄK—týíiĺŹ?ţPĄJ•˛ëS"ú*Hcôl´µń¬l潕ôLČnźáŁŹ>ę÷Ä˨QŁl˙/Ú¶më÷wiG‡ÜîY¸pátÝ3PţţűoÓóß~űmŹmSRRÔŚ3T±bĹÔńăÇ=¶+V¬qżض>|xP~›­[·V»wďN÷çSůď˙ëéłŰ®\V*˘ĎÔ—đ!7n9#( ś´~~±±±jÝşuÁű˘‚ő·őý÷ßĺľoľů¦éľb ć|Îś9ŁŞWŻn'?R€áčeń\u;€˛d‰3nő–ŇAŇş‘FUbP3GB“Ůč30… fĺĘ•As‘ IIIôčŃ)S¦ŘąeEńâĹmSÍ'%%1~üxşuëFRRR@Ďýᇌçµk×Îc»ÄÄDzőęĹСC9uę”ŰůB… QŁF *W®lë¦třđazôčÁ«ŻľęüáÄgź}Fť:uřţűďÝ®Ź D‰Ô¬Y“ZµjQ¬X17wířřx†NŹ=¸~ýzŔĎĎ®T¬X‘5kÖŘĹEćFˇ ˙hËćâ+ĂoŽŽ-Ó4íŕëń~ýú1}úôt'BZ˝z5çÎťKÓµçĎźgĹŠéz~fňÇĐ´iS Ŕ™3g˛ş;+W®¤qăĆlذ!«»’ĽôŇKüűß˙¶;uĐűÄkž˛r:09NVxáSô ?ŘŘX–-[FÓ¦Mł¨K‚9-Z”U«VQąreë) Ý@˝ŤÔĽNŻ OŮÂĄM& µK2‡ŃX˛ő(P€+VP«V­,ę’=Ď?˙<ß}÷ť±F÷îÝyć™g¨Zµ*EŠAÓ4RRR8yň$Ű·ogěر&Ąjůňĺ <éÓ§űýÜĺË—ďďż˙~Ű6WŻ^ĄM›6lܸŃtĽrĺĘ 6ŚöíŰSľ|yăxJJ GŽaöěŮ|đÁś>}Đ˝Ţxă ¶oßÎüůóýŽ·ů裏2dÉ0 §wďŢôčŃÖ­[»Ąâ?sć K—.eĘ”)lٲĹ8ţÍ7ßĐłgO-Zä׳îĽóNž|ňIżŰŰ‘•u0+UŞÄęŐ«iŢĽąurˇ đ$đ>žËD¸%%pbŮW *-3!¦i…Ńë$›xä‘G1cFP˛ôŢĽy“… ňřăŹ|í‚ žĘJ–/_ÎO?ý”a÷ć™g¨^˝şí9Ą—.]âüůóś?ž-[¶đűďżç/^ĽHĎž=Ů»w/ůóçϰ>fW^~ůe’““=z´őÔ`ŕWŕ^&Ż\Hq7dDN’V4MÖÜąsóí·ßrß}÷eQŻ!s)^Ľ8«V­˘Yłfüůçź®§ ˙Ćŕ>‘ĺI†€.?Â0ë!9NÉ22y™÷–sńEĎ8xÓőďWëׯWˇĆ©S§Ttt´ŃϵqăFż®ť={¶ÉĺUÓ4µk×.żź]˛dIşËsJJŠm›>}ú\3˘˘˘ÔäÉ“ýr—MLLTĎ?˙Ľ›{Ç#üęߏ?ţ¨"""L×6kÖĚď¸Ű””őÉ'ź¨ČČHÓ=ľţúkŹ×X]|łĘ=7ŘlٲĹís@đ#Ń•¨č.żőHŤ )‡î˘V?ÝöTüţÓ»9ţ–/¬˙·÷Ýwź_˙÷V¬.ľ®.¬iuómٲĄq×ßH¨şřNž<ŮÔΛ‹ďĹ‹U||ĽŠŹŹW×®]łm“^7Äyóćąý^|ńĹ€îq«1pŕ@;W˝}ŮѨî¦W=ž˝şšsLjŽwĎCwUĽbýĽćĎźÜ/%Č(ßÄÄDăwďQçr&‡V °“!ďí\tú@-Rsc8u§,ąeCŽŮßĐCÓ´0ôtřá®ÇGŚÁ˝÷Ţ›%}ňĆěŮłILLM¬őŢ{ďqĎ=÷řuí#Ź<Â#Ś}Ąożý¶_×îÜą“'Nжm[Ű,ĆÓ¦Mă˙űź±ź/_>Ö®]ËÓO?Mxx¸[{+ąrĺbüřńL™2ĹÔ~üřńn+˛Včׯ7oŢ4ŽőěŮ“+VPĄJźĎĐ4Ťňůçź›Ž˙ë_˙rţ€oęÖ­k·˘ĂĐÝŕ­®ľQ¤ľÜlRo3Ül:»Č›7/3gÎôë˙ŢÝ»w7ާĹÍ÷Ô©SüřăŹFż6lî>…ůňĺŁ@(P€ß¤‡zI“&™ŽÍž=›”«s€ŕäÝwßµó©‚}éo®ľŢVYs Ł—÷2xä‘GčŃŁGu'ëÉ•+—ń».P @ČUN2–ňĺË3yňd»SĐ Pk <»2xvňĉüC1P3–Đg^ îşë.;ĺ<$Ř˝{·ń^Ó4şuëĐőŻľúŞI‰[»v­_×}˙ý÷Ć{;÷ŢÄÄDFŤe:6cĆ żŤgW†Ę /Ľ`ě'''Óżnܸáńš·Ţz‹¸¸8cżL™2Lź>=M©ř{ôčA×®]ŤýÇł~ýú€ď“Ý1b„Ý÷W¸÷şdÖBÚ~+›ŮŮHuô}ő¸ĺţřcÓ±>ř€ÉµĎrÂYÇÇ«S©ĚîňÂŽÁÖüq†×u®_żn’v2(11Ńđ(łĘ…sçαzőjâââ¸téE‹ĺÎ;ď¤qăĆiÎ pěŘ1ÖŻ_ĎÉ“'Ť{Ţ~űí4oŢÜ-·E ś}ÚtÍ;ďĽăÖĆW Ş?ełyäÓ5i)3“Ö89kŚü§ź~j:żiÓ&ă\TT”RJ—·%J”0]§išęÚµ«­ěݵk—ęŮł§×şŃ•+WV˙űß˙ŠËKHHPďĽóŽŞRĄŠÇűV¨PA}öŮgA­E}ěŘ1»ďuĐ}˛«zLjmto¦˛č™lťr#ĺ"TČôlŽżď’ëgSŁFŤ }ö™AV–™9r¤qľoßľJ)}LîŃŁ‡]¨%J¨?ü0 ˙ńĄK—ŞzőęyüÝDGG«~ýú©¸¸8żď™¨¦L™˘ŞU«ćSćŐŻ__-Y˛Äëý\ż§®4qâDCwsnůňĺSď˝÷žßý ^|ńE»Ďez¸@7 Đ ˝ M=t¤˘C–8u|ä0$r Ä{šŢ ¬M˝zőLűŹ?ţ8ńńńÝă®»î˘S§N4mÚ”5já}‘~őęŐ†{­]y™sçαsçNcżzőę4hĐ  >ŮѱcGÓjČ’%KL«:Nľřâ Ó~Ďž=Óýl€uëÖńÍ7ß0tčPnżýö Ü3;2dȻíHuďµnv.6Ţ2˙fW˘ĐKgT®\™-ZýAÝşu3V¶qóýňË/ť=zôđů[Ľł˙~ÓľŻ•Ó§OÓ¦MNž|~ýúѬY3·Uě´Rşti:tč`=\(Ť9LŔUvřŠË)üÝH5<ŘmAUđ“Í›7S»vmľúę+ŹYËOž<ÉŕÁyřᇭžAn$%%ŃŻ_?:tč`Ęđo%11‘Ď>űŚŞU«ú•ő˙đáĂÔ®]›§žzŠ˝{÷úlżyóf|đAĆŚăł­“ůóç3lŘ0·Đ¨K—.y — E dçÁÓ’ÔÜžô|»úćDą’iš8|ÎMvĺĘ•óZß3čßż?ůňĺ3ö·mŰF… 3f ýőW†<Ó5ţÔîóYż~˝ˇ4nÜ8(ĎŤŤŤ5ą_˝zŐHöâĘ7ß|cĽ ůď0»ŃŞU+»şdŃżSˇ´«GfMT`Sfťâ@}˝=S Á Aě/H'… ˘uëÖĆţüůóýşÎŐ˝÷˙řGĐűl:wîLçÎť©]»¶éřý÷ßośłNŇe7oŢtSR}%`6lǤV}űö5í˙÷ż˙ĺůçź7)Ź•+WćŃGeâĉĽđ 4oŢÜWżbĹ î˝÷^Ă­ŘŽ¸¸8ęׯĎÖ­[Ťc  S§NŚ=šI“&ńä“OšB"6lŘ@ßľ}Mr==ŘLüj@%>ž{ď˝—ÇŠ)ÂŕÁ;v,~ř!ŁFŤâá‡vs~ăŤ78tčĎĎ">>žgžq+Émü Ůa,pĺŽ;î U«Vn‡1ëÖÍ©źŘMvĺ䤍™ŠLygw¸î4oŢ<(ő 3’Ľyó2uęT“ňpńâE^{í5^{í5jŐŞEűöíi×®Ť78ĚgĽjľ|ůhÔ¨‘Űůß~űÍ´Ě,ˇŤ76ÍH=zÔtţęŐ«¦ŘתU«R´hŃ =_Đcéš5kfPŃăČ"IuI’Ż®ď­ŻÎ¶ÖÁ!8špćr‡ő@›6m2ěa˝ző2ę;łů.\Řcűő;K—.MÓ¦M3¬oÁbÁ‚Ľ˙ţű&kúôé”*U*«şŔţóS€ŇĄKSŁF ŹíoܸaL´hт޽{S§NVŻ^ÍňĺËMžK–,áĺ—_6öĂĂĂyýő×y饗ÜV~űí7zôča$…Ű˝{7Ź=öGĄxčСF\čqˇ_|ń…ŰçůĘ+ŻĐ­[7~ýőW@˙.>ţřă x5kÖĚîp t2łÜ°n®çsZŞ)“ZÝşuMĐ‚˙¸f*ăŤ7ÜŞ\ľ|Ů$C¦L™âŃX;v,K–,1ö«U«Ć'ź|b;˙ŃGńěłĎrăĆ RRRxüńÇ©WŻž­çŐkŻ˝f’# bâĉ¶±ó'Ožä©§ž2Ü8ź’’b*˙şqh—ÎyýÖ­[iĐ QČţ«ŻľbÆ nĄŃ–,YÂŇĄKŤýV­Z±|ůrŰq T©R|óÍ7Üy睆Lź5kVP ÔŘŘXJ”(auuľ }’ËU‰Ľ‰Y~¸Ş®rĂIv– ×m4Hoň+fÎśi› 1oŢĽ|ůĺ—4nÜ]»vđÓO?ńǸ%,;u꯿ţş±_˛dI~ţůgʉ«ž|ňIŞV­JË–-IIIáŇĄKĽöÚk|öŮg¦v‰‰‰|úé§Ć~ăĆŤ™:uŞG˝¬D‰|öŮgT©RĹ0j—-[ćǧ 3nÜ8† KM2ꑍŤŤ~®ˇW8gŐ)K"0˧,Éi^™Ž¨AƱŚ_}p4Č.*Ŕ3ĎýôS–-[Ćľ}ű<¶?sć S§NeÚ´iüóź˙dôčŃ>j_ń§€[’¦`¨Ö$$VcŘşzP§N٬…Sy{˙í·ßfYü[Vă!LntĹŃą:ę"I’H]E Ç~pČ®I`d†üčŐ«—a zsóݱc‡‘|ŁrĺĘ·ě˙­'\WGĄD‰Ě›7Źččhźm5jäłî?ü`Ú;v¬_ýčŐ«ăÇŹ7bKW®\ÉÍ›7 /—7nÜ۵kçWňşA•*U¨ZµjĐ\«mdH ©˛Ă©TFZ6§±›ŘĘ®rĂI,IłSůŹP¤˙ţ>ŰX ťK—.ąµqMBWştixŕżž˙ŘcŹęŤ7Xµj˝{÷6ηhŃ‚„„âââ8tčߥë\ű쯚Ӽf<ŚŻą1ëÉřÖAśzHN’%Y†¨Ă·GÜe jÔ¨Á„ 0aGŹeůňĺ¬X±‚U«VŮfxLJJâí·ßfýúő¬\ąŇŁQwýúuÖ¬Y豝ĺĘ•łmgT]gÓ‹U[WT­űÎ ţçWL'ž˛şRľ|yŹ+Íţ޵V>lwř"©+NCŐ90Dŕ99m‚‚lČםŁGŹ’śś°} tęÔ‰Ľşůş®ž>üđĂÖź[ MÓh×®ź|ň‰ßˇţÄă»zŔ*TČTWŐWÚ¶mk¨W®\aűöíĆdÄďż˙nRľ›4iâ×}Ë—/ĎčŃŁýj62$łRéšqÓą‘ÝËxtj  ä¬ŕ'žtW¬FVőÜąs&ʆ@BvęÔ©¦iĆÄöO?ýd2PAݧ|űí·űĺ•póćM~űí7¶mŰf:–””äł^qzBŤBúůtąŕ:ŃałŮÉçD9dY’eš1\΢'{0ây˛3ĺĘ•cĐ A 4ääd~ýőWV¬XÁŠ+řĺ—_LĄ 6mÚD÷îÝŤ€z+ëׯ7Ęşx3ş¬1§}ľ¸xń˘iß:›_¶lYÓľuE5łąóÎ;ůđĂł´ÁÁ­‡’€+¤ úp—ÍuP°śł[ É®I`$%%qäČî¸Ă-wRĐČ“'<đ€‘LČ“›Ż¸÷¦źÜąsS¸paęÔ©ĂÝwßMŻ^˝|fíµR¦Lźm\Ă 3±*ŰGŹ5 Tki”÷ŚB)e7ľž'Uą´NjyS,]Ý|ł«ěpr¸ÓąăO†VÁ3ţüŹ[=N¬y<öíŰgĘ^˝gĎž€&ů"##Ť{ú;ᒒ‘#GŘłgű÷ď7¶-[¶pőęU·öţx 3H(ŕA?ŹÇ]±Ę×lŕžJÍäY’%D,i¤˙ÄĹ@uť5Ë „‡‡Ó¨Q#5jÄčŃŁŮłg#GŽ4eĹu®´Ú¤đö˽ܡ5qQz°FVµtéҦËS§Nů}ďŃŁG›âA¬¬ZµĘš5î–ĹĆuÜ9séLzd5R]K»Ug='F&˝l˘nÚä®]»2Ô@ÝuËi ÚąůnÚ´ÉPŚîşë.ŞV­šˇýÉŽ,X°€–-[ÚžÓ4ŤŘŘŘ ÔŚ-T¨×óJ)Ó„^z TWëd]V¨Gʵ‹ůu¨v\VâŐë"›Č ;Žŕb úSSđL‰%Ň}ëűž={Ҭz›¬ŹŹŹç>ŕ믿fďŢ˝¶5ŢÓ· ďŮ›ď HŔ¬[Řé ţL;ŃČ>:HH jĆ FPÎÚµk9vě_łŢŮ‘ęŐ«łpáB†jZĺ›:uŞW5::ÚS™·™6l`Ŕ€Aéó† LűV·ččhJ•*eĹ$..ÎmeŐ×ěvv\ż~] TŕěŮł¦É çˇ>E\ IDATH54=mžLg-§l·‚j™ŕr3PgĎží3ÁMzéС±±±\˝zŐÖÍWVO}ë3éI0đUćëúőë$'§ÎÓř2h­Xă˛\u*«r轉5Y“OŞťqšcÂĹ@MJJbćĚ™^˶WŻ^†ęęćűÓO?őňš4iâ—'?xZ ´ŤŕNÁ‚ wÜ@őYe·kI ë ń±cÇŇÖÁt˛lŮ2»1f3©q_n9‰­ŔoŔÝÎsçÎe„ Yşâ}+S°`AÓľRĘvb<-,^Ľ—^zÉŘ cĚ1üă˙đb•­·š÷éG}d=třÝń>-2$'č!Aú}O¤Ó];vŚqăĆeQwĽS˝zuă}RR’ťŰĄß¸f¤µ«ęOýSWyäÓţoĽ‘®•Ë—/3~üxÓ±ľ}űÚ¶­WŻž©®ëöíŰ™8qbšź-¤ňî»ďÚ)Í[1ÇŹ‚»±ęúŢ:ä¤Aa!`J=věŘ ĆaŰŃ®];Ă˝óćÍ›¦Ú¨NŇăŢkťů·&+ł#«”eW\W5Ź=ę×jµk×ěÂ5jÔ0ťó×@UJѸqc:tčŔSO=ŲeËük×®ńŻýËz8Ý@ď“\Ţ Ňś$CL3€‰‰‰ ><«úrËS­Z5Óä¶kÝô2yňdÓţěŮł5j”ĎĽÖňz7oŢ ZźBť Ő$\ظíÚM|ç䉭A ÔŚeúlŚÁ1cřý÷ß=4Ď:¬q cÇŽ H™qĎŻżţjě[3S&''±—eĘ”1ĆžhÝşµ)Žuűöí<˙üó÷ÍÉŕÁM†Q Ľ¦M·Ć“Ž1"ÝË­4ر{÷n^~ůeëaEŞr ţś6PÜfş¸páŹ=öX†ÎrGGGÓ©S'cÁ‚(ĄŚäI<ôĐCiľżuÁuýúői~ž«÷CN^1p-˙’`Š!öĆĺË— wnĐĺ¸kҤš5kšJ€}ýő×~}Žż˙ţ;7ndٲeLť:5 Ň]V†Î¬‡÷ŁgŃ÷—śľÚ1=×ŕ“O>aéŇĄYÔť[›‚ š&w6nÜčf zâŔ”+WŽ{ď˝—>}ú¸ý–űí7ă}ˇB…ü ÁPJąÉÖ[E79uę¶;µŮî ĺDN•'™Š¨ËI`Şë¤¤$úöíÔzžÁ }űö&cqÓ¦Mž~Ľ^yá…L®łÖężüň‹‘`Ăßšžš¦1}útSÜÓäÉ“ŽçMIIá™gžáóĎ?7Ž………ńţűď{˝îńÇ7%–¸qă­Zµâ›oľ čů  ˙7ß|“·Ţz+ŕks ^~›Ń3ř:±jĽĘË9籜fmLƲŠúĂ?0uęTÍ«rłrĺJľűî;Ă˝·U«V-Z4Í÷¶¨»víňĐRçĆŤĚ™3'ÍĎł’;wnÓ~NvîŮł§i˙ŐW_őKť0a‚).«GʦóaaatëÖÍŘßąs§_ňđË/ż4ŢGDDđŕúĽĆŽ~ř)S¦X'«]öý‘ĘňšÓHţc=řřăŹűm ÁĹU¶^ĽxŃďŤ˙ţ÷żÄĹĹńÓO?ńůçź›ôˇ””SŐ€2eĘřJ6{ölNź>m:v«¨O<ń„]ěé€5fŔ—ŢaGN•'™Š¨Ď«€)żűîÝ»8p`šV(3 MÓ9r¤éŘ´iÓh֬۷o÷yý©S§čׯÓ§§z5—,YŇÍuÖßň2VĘ•+ÇŰożm:öúëŻÓłgO·dvěŰ·ŹöíŰ»ŁcÇŽĺî»ďöp•NXX_}ő•É]ůüůótíÚ•ÇÜ®LŠ L›6Ť*UŞ0bÄ“‹˛¦inJsNćąçžłó"8üŕxo;v¤V­Z/^śÜąssúôi:Äš5kX¶l™I°EEE1{öl·täN5""‚Ö­[ÔżAqůňe†n(XóçĎgÉ’%ôěٓΝ;sçťwRĽxqRRR8uę›7ofÁ‚|óÍ7n3Æ ó{ö˛\ąr,_ľśxŔ¤„Mź>ťéÓ§S·n]:uęD… (S¦ ąrĺâĉÄĹűjŐ*Ö¬YcW«Ź˛eË2sćLÓŕ≭[·ň裏úŐ_o :” řn<˙üóv+Ö ř¸Ž÷Á9(¤ŕ}€ě?8¸ö˙[`.`¸#\»vŤ¶m۲rĺĘ )E×®]ŤŚźN—řččhşvíš®{-Z”‡zČ(Çý÷ßĎűďżOÆ ÝőlÍš5üç?˙aőj}Q,wîÜA©çgÍ‚üÔSOń˙÷ÜvŰmäĎźź-Z¤űˇÄ”)S¨WŻžáą2iŇ$¶lŮÂG}dЉ»pá“'Oćµ×^3MžN0J•*ąÝ·víÚ<űěłFą}űöQ·n]fÎśI۶mŤĄź|ň Ç7dpěV@}G‹-ě ác€3-»'âËH͉ÎżéIŕWŔXvűî»ďčŮł'óćÍłMŠL0/ľř"ŕëúôéC›6m2 GS¨P!Ţ{ď=迏‡~+V0nÜ8“wĘĄK—8q"oĽń†1!ƸqăÜôĆ&Mšnľ7nÜ {÷î|ńĹnőŹ/]şÄ´iÓxůĺ—m=ůÎź?´xˇČ[o˝ĺÉűî[ô ŕŕ®KxŇA¬úHNÓC˛ĄT¦mŔĚ_ŕĚ|~&ü}®YFťEÁsą1Řü2D…ÉÉÉŞ_ż~ŢV­|nQQQjîÜąn÷>sćŚŇ4MŞI“&iîăwß}§ňçĎźćţĹÄĨɓ'§éŮÇŹW-[¶L×稰°05`ŔuáÂŹĎ:yňdşźc·Ů}7™Á /Ľŕ©O€ŃčŢŻ///ĎĎ +XŹ˘iť6Ŕ˝@] P(ň9~sążASm˛ÂÓf‘‘@4(üeýě ( 6oŢě÷w0jÔ(Óő;wîôŘöűďżwű®şwďîőţ­[·6Ú.\Řc»M›6©°°0·ű*THU®\YĹÄÄŽ?ńÄŞ}űöĆţ;ďĽăvĎż˙ţŰtÍŰożműě .¨đđpŰ˙Ĺúőë›Ú+VĚ87`ŔŰű >ÜtŹďż˙Ţëg”V6mÚdzÎ×_í÷µ+V¬P±±±noÁ‚UóćÍUĄJ• Ůěş :Ôë}UóćÍmeě=÷ÜŁ5jä&«ĂÂÂÔŇĄKţűăââÔí·ßn÷˝]&9äÇ(`$0řđ,0Ř!;zč5Ęk·%r#/De'™áşaNÜâÔA˘×»˙ůnÝş©¤¤¤€żŹĚŔúŰJë6qâDÓ}ß|óMÓůóçĎ»={äČ‘¦6ÉÉÉ>ű{ŕŔÓ5Ó§O÷Řö˙ţď˙lűZ¦LŐşukU§N79¨)S¦ŘŢ/>>^•)SĆÔ6**JµnÝZ ř€§ź~Ú«ËUfƬYłřöŰo}fłŁiÓ¦l۶Í6@˙‡~pţłäŢkĄ]»vlŢĽ™Ç{ŚččhżŻË•+˝{÷fÇŽ<ýôÓizv©RĄXµjsçÎĄiÓ¦Ż~GFF2`ŔöîÝ˧ź~jJ4’SIIIáůçźwËśěŕöqcÎßMŠË–첥¸Ľú3‹©ŔôÍN(ôŘÜţXŔ\¸p6mÚ°qăĆ ?´U«V)RÄt,˝î˝N4hŔ§ź~ęöű=ţ<0y 2$M«mžČź??3f̰­ĄĽwď^˛çżwÚ´iĂÚµk©X±˘éx||â»ďľăĘ•+€®«mٲ…1cĆPştiă§gKNcâĉn /üXÓ‰»ĘO:«,±nvz~ăl$O˛qńÍX\˙AoŹź&ëlĘ”)ěŮł‡/ľřÂTk.+éСmÚ´aĺĘ•,]ş”ĄK—ÚÖ4=Ö´K—.tďŢť-Zx4ÚŇjGĹŠ™>}:oľů&ü1 .äĎ?˙t‹eË›7/•*U˘wďŢôďßßMáN+˝ző˘WŻ^>|ŮłgłdÉ>l›x˘PˇB´jŐŠvíÚŃľ}{J”(á×3˘˘˘Ü˛+«‹cFröěYúôéĂŠ+ěN˙ĚCňžOĂM<¶C6ÂŞh;·í@oŕ \\őâăăiŢĽ9ďĽóŽ)VÔŽ *ţ§ěŠ˝;‰`ذaüđI‡ĽŢżNť:F\›ŻÉ—ţýűÓ˛eKĆŹĎ×_mrŰŚŚŚäŕ©§ž2\ójŐŞe¸ř–)SĆí~‘‘‘¦żÍ®Ť“ľ}ű’'OŢ}÷]věŘÁĄK—(Z´(eË–ĺÜąs†śhܸ1ńńńT­ZŐö^·ß~»éąUc2_ľ|¦ç*ËęŐ«ÇŢ˝{™5ksçÎeÆ ¦Ä*áááÔ¨QŇŻ_?·Z§žŠŠâăŹ?fČ!Lš4‰+VpňäIă|tt4•*U˘[·˙gďĚ㣨ď˙˙Ü’p†ű„CP@gŔADŕÄ›‚¶ZŻZŢí·b©¶UEŞ˘PDi bń‚*V!ÜAä;r„„óűcv63łźą6›Íîćó|<ć1÷ěg7™×űř\×ń裏RŻ^=Oĺ^˛d ·Ýv[ ‰˛Ž ŕÔ‘{ˇR;DÁi™`Oša…YCC­ŐąCŃ?˙ůO.¸ŕ-Z”ĨIĚďV¨č0P%úç&&»Âf­t“Ś®WŻžá'[?uęTnĽńFţú׿’““Æ  ÍëëׯĎŮgźÍ„ :ujP0kćâ‹/ćÇä…^`îÜąěŮłÇPůŃ´iS®ĽňJ&Mšdáî»ďč|qq1%%%$''Îë˙ŃŇ%Í-EEELž<Ůj ˝¨‰­{‘y± LÍ>ŮŹŃŹÚRíř"Ěű|ľßÔzLQ”čś4D|•oŻľąŻľÉ^Ô u¨ůŢłÎ:‹… ¦&Îś9ĂáÇ9|ř0§Nť˘eË–´mŰÖÖÉŐłvíZNś8ĎçăŇK/Ö`T•ÂÂBvěŘĎçŁC‡®ť¬pQTTÄž={8zô(-[¶¤uëÖ†Ńöj«WŻć†n°š#q;j U†µA(ő/gP H pZ·ˇöń>í?wĆ}F4fjPMúˇ×­©^2p!đ6Ş–?~<Żżţşëw2ZP…źţ™ššJ»ví‚úŻW'Ő˘GŃLii)ůůů:tf͚Ѯ];ˇŁ ‡ćŕÁÔ«WŹNť:…ôŰ–——óÄOđüóĎ‹jµ+PkNżĂ^;ôşQ$XŠ©Ô‘nD˝fqđA4y `ľ755•·ß~›¬¬¬•V˘çôéÓäççSPP@۶m…óČ{ˇ´´”Ý»wsňäIZ´hA›6m\Ťî/l۶ŤëŻżžÍ›7‹NDµŁ§±öAĘpöANcÔMKôÉóńAŞźĎ· č ;TOQ”b‹Ë+ď“jxsźT-H} ¸Ü|Ýşuůă˙Č 5kGL"đADµCeŔCŔs¨ß_?Ó§O§gĎžV]3$’¨e×®]Ś9’›nşÉ*8Ý üëŕTźč˛Ň‘⺪Ä2@­~ĚĆB3gPk“§'Í7­Ył†ňë_˙Úę%“H˘†“'Oň›ßü†XÍĎYŠÚ_ě?AQźS‘Q8Ł[›kJEMib}p«—Ţ˙µ™^YVVĆôéÓ9ďĽóX˛dIdJ,‘Toľů†ţýűóŕZ%VvŻ»±o’'Ň˝nµĂҡŚ1ͰC䀗ٶÂ2ß°}űv†θqă8xđ`$Ë*‘x¦´´”çźž=z°téRŃ%¨!-BŐ»ŕÔ\Ş_Ě>“–#=‰2@­^ě:\k˙Ř7 c ĽĽśżýíotďŢťůóç:ĎK$Ń€˘(|đÁtďŢť—^zÉj4ęĂŔëŔ·Úm8¦N¦ŮŃŚ×OĚÁ©Vűˇý>'P§ĺyÉĚŔîÝ»ÉĘĘâÚkŻeçÎť+´Dâ–Ç3eĘ.şč"6nÜhuŮ*Ô&y'°ÄD߼Wżčű‡™ËxÓ =v-ą´ßěkŕ:@ŘdkÁ‚tëÖŤ3f@“H˘‰Ź?ţ>}úđŘcŹYÍ•]Ľ‰Úň‚SQX”Zů µAK"Ž P«›fzV5!ŰQçw|ßÎŔţýűąůć›ÉČČ`áÂ…q9 ‚$¶P…ŋӯ_?ĆŽËŢ˝{­.]‡šĄ×2ôn’6"Ł`U b5ŢĹTćҡ‰žą Łö›,@ť«m·č™‹/¦k×®Lś8QŞ’¨ŕđáĂüö·żĄS§NĚš5Ë*{őűcŚ}CÍ6T¤%şĹ¬V‰-ÇŇÁiîÔąbß@ý} ?~ś{ď˝—®]»ňĆoČ@U|öŮg\zéĄ 6ŚĽĽ<«ËľGmyˇŤÖ(JŰu°óCDµ§˛yojd°Ş1Ňż'QűÜ… 6 //Ź›nş‰^˝zńţűďË@Uqôéµ×^ˆ ¬.ýµźÇÄC¸‹L+'ÓÎ8X FO/‡•ciţ­6Qűč•RZZĘś9sd *©Qôé´iÓó2šPPk;^Au0E–Ő»Pb±Ř5ń ŇŤXJj9 ˙^Vy)ęŘE8i˝čA;wîä—żüĄ T%5ĘçźÎe—]ĆСCůňË/­.;ĚŢNaß'ŰʦZi‰›$ą8Ň“!Gń­FFÓÓŹĚ©ť3¨‡:ßáD˙¶ŚŚ yäĆŽkłJ" 7ĄĄĄ,Z´iӦ٥ ŠöJÔÁ´°Pő‰}Ť ~Îbݶ•‘+gÓgślNÓ FíH˘R7ôÚ‘‚:bŢT żŐgÔ­[—[o˝•_˙ú×dddTÇ×HüôÓOĚ1W_}Ő*(Ő8|ě'8¸5QŐ7·Óë~„ÍÓצš§•ŃŞpc®Ő…6>HކhÓßŐEŐ$TýHĆ jĺ„Ćť:u⡇â–[n©µÓ©I"CEE999üéObĺĘ•v—–Łú+ĆčÔ=Ŕ š}Ń”2ĄXעŞz*rš™(Dŕdšç$ł R5głp/0ŘŻ–-[r×]w1yňd:věöď!©˝ěÝ»—×^{ŤŮłg“źźow©äˇ6Ĺ;¦;fŐ×ĂŞĎ©ľÖÔ*0µ NăĆ0¸HpYé†~ą ¸ hm÷Y—\r ÷Üs×_}Dç•Ä7Š˘đź˙ü‡™3g˛téR§qN˙ÖP9˛¬SÍ©¨öTݧMÇĚÁiLNGĺD4…•¶hAj+`0ÂťFŤ1aÂîąçzöěY ßDR[9|ř0sćĚáµ×^sÓęg;ę¸.ú.EÚÚ®iŻSí©Ů1÷E5'Čă.ŮUd€ĄX8™˘yÉD5"Úr.p+p 6jBBW_}5S§Neřđám“DâžĎ>űŚ3fťťm5𑆂Úo%Ż;¦­í2–˘Á4ń· LE}Pµg ű}IJq°Ő)HժɨsĄ^\ŹępZŇşuk&NśČäÉ“IOOű÷‘ÔŽ=Ęß˙ţwfÍšĹöíA3!™9…:ŇÔ÷Ľk‡Y7DÉ-«ŕ4n’Z"L•­1Ü$ʵĄ=ęhżW`¨\zéĄL™2E&»$Uâ믿fćĚ™,\¸’’ +fv+¨ÁɱKk‹Č˙ ¶ć8‚o<éI(Č5J±Č`ş­I5Šs€›‹° T:věČő×_OVV]tuęÔ ç×’ÄŠ˘đő×_łdÉ-ZĶmÂnІ[đ*TЏťaĐ;š˘ZÓZe\´ÂĐ’[VŽeŠn»>jkŚ18ŞuęÔáňË/gĚ1Ś=š´´´0~+Iů䲳łůđĂťšđj”٦_ ¦z±3 vŁnÚŤĽiÎXÖšŕTæ¤ÁÚaŐ CŻőP›ţ^…ęp:Ňż˛˛˛ČĘʢWŻ^ařV’x`ÇŽ,Y˛„ěělľřâ §ÖÇP@rÚi‡ążş›ÚŽZéPzôADZbÖ”v¨>Č`˙ľ-Ť5bÄdeeqőŐWÓ¤I“đ|1ILSZZĘĘ•+ÉÎÎfÉ’%ěŢ-„ŢŚ‚:č—x Lí‚SM#D r»ô­·âş%FUjă nk«7vMm¬Ś„v¬90 µŮMK7eIIIáĘ+Ż$++‹‘#GŇşµm×4IśqřđaţýťÍňĺË­ć Q¬ő/'1mmeô5Ú &NóŠS«‘„SDÄ‹q!ÁĄŻ«IşkΆýp¨Ńčرc X˝ôŇKILtu›$P…ÜÜÜ@P겖Ô÷ňGÔ ô‚ű§»u(ÝŚ´)k;„¤:ů ©¨ţÇ•¨A«#‰‰‰\vŮedee1zôh:tčŕ|“$n(,,$''‡ěěl–/ IDAT-[ĆńăÇÝŢz uÚşµ¨I®P|§ą•"Jr™[aÄ­RUd€ĺڶ¶ REŞŢ0—LT#Ń[÷|[¸ŕ‚ Îf×®]«ň%QʶmŰĺW_}ĺ¶–TˇÝAĄSYn:g6 ćA¬2–úŕÔ<0’×9Ok…a±†¨»€ŢŮÔłÍPkUů·]Ń´iS®ąć˛˛˛¸ęŞ«hذaľĄ$9sć ź}öY ĄĹľ}űĽÜ^„:eÉ ŔĚ«vşuĂ*±Ąż·Ö§`›(éU‹.ý˘é‰vľjÂĽż˙~WôéÓ'ŕôíŰ7ÔŻ'‰böîÝđAV¬XÁ™3gśoŞd7Ş~䡾Ç^S7Á©9HŐÎëG굪9Ő—)îőÄ 2@Ťl‚T'ˇďb j†¤-p)jŤH\«çž{.YYYŚ5Š’’Ú•Ô(EEE¬]»–eË–‘ťťÍ÷ßďő-Ŕ&ŕî¸S3»~n ŢŐšÖşŕTĂC_2mđ$‘n’\uMKT'3u€%W$''sůĺ—“••Ĺ•W^ÉŮgźňw•Ô,Ą}ô'NśđrűÔŃ4ó¨t*Ýj‡ąŻ©U?1+‡Ň)©U+S —>hG} jĺ‡hÇ›Ł&şúťńध§Zwťţů˛)pŚRVVĆĆŤ>ČÚµk˝>â0Ş˛ŐѰÓQ‚K›ĆN” ·ŇłbNrŐZ$Td€#x4Vµ©fˇ7Ú’Úě·Đ膇¬fbb"=zô 333°ôęŐKte”””°iÓ&rssYłf ąąąäĺĺy©%Udw[ýKîśŮ č·Eµćš‘)2V©ČÁ4÷ő¨5†ÁeęÔ]@ä`šµC nĎA X3€^ĘÚĽysú÷ďoĐ92pôqčĐ!rss Ëţýű˝>ć$ŞvlAmu! JµmýűkUÓá¶¶Ł”ŕŔÔŞIo­N5BđAô /»@UN»¶)•>Hw˙9·ĺ¤K—.dff2`Ŕ233éŰ·ŻlĄe”——óý÷ßôcăĆŤnIÓŁ{¨ÔæsÚÚÎQ0&¸Ü&ČEŰćŔT_k*SŹČ5†pa ´Pô™L'#a¤jKCÔ&8}€¨#zz"))‰ŚŚ ĂŮłgOŮ-B”••ńÝwßŃÜÜ\6mÚDiii(Ź+Aí¶uŔÓşsvÁM`j6 "Ă`HőÍhDÍň¬"¨u†Á&HuÓźĚ*XŐŻő-7uĎj‡Ú… uÚ ĎóXµnÝÚ ™™™´iÓĆëc$!RPPŔÚµk ÎäO?ýęăˇęÇ`b˝Đoۦvµ¦ek†Űš‘nÔ:Í0ăŕصč˛Ň‘˙aöCę=QŐž@#ŻĺNHH [·n€533“>}úČÖ^˘˘˘‚~řÁ ëׯ÷2–…žRÔ–[Q»ťÔťóâSs­©U×"+_ÄŞŻi­O‡Š Pc BälZőQµ2ÚZ_«Ň ŐŮě…‡>gfRRRčÝ»·ÁáěŢ˝»śÖ¦ŠTTT°eË–€Xłf 6lđš•4SHe-é*ű”š…Ö‹siWóaUsj6V©SíG­5 .T·Ş•†őFď¬6A T3Pçi9KŐ®]»  µE O•µ………¬[·ÎŕLş“Ôµ?”ĹY;Ěşaî L­šâ‰I7Ąą Z¸Z¦fú¤ÚŐ¦Zi‰YWô×u¤.jë ͱťöĘŽÄÄDzöěi¨iÍČČ n]Ç $6(ŠÂöíŰ ú±nÝ:ŻÍýÍśB F· §Zv]¤#ÚÚkrÜ)AîVG̵¦Ň  Ć . „U&Ól$śŚ…(HŐ?«=jÍj/\N;aGýúőéÝ»7]şt!==ťöíŰÖíŰ·§qăĆUý¸ŕĉěŮł‡Ý»wÖŰ·ogÆ śn(**bĎž=A˛sçNÖŻ_ϱcÇÂń1G¨LjíÁťÁ¶_˙^ëßs§ŔÔIO¬tÄ)É%őÄ%2@ŤQ, „¶vr6­NłÁ9š"głjź‘N¨F˘=NN=Ť76 łIKK‹ůľ®ĄĄĄěÝ»W€jë0‰żžb`żŮç_Žco ôŰn2•˘lĄĂ HőŁâYËć4 C-1ěU‘łiÖ «@5Á}:ŞvhúŃÚ.,Ô©S‡¶mŰé‡~ݲĄ«Y·˘šcÇŽYjÇîݻٷo_¨Íű­PPkE÷Q©#{©9ÓŤvß[·©“C)Ň«¤–­nÔvÍ0ăÂé~@6s jĄ'úkô÷™u$•`Äss`;4h`©Ú:Ö› ———ł˙~Câʬ!GŽq~7Π&Â5 ه±Ąż“^’[nµÄÜ2K¤%v .»ľ¦Ňń Pc—ÂÎŮ´ĘhZŻfGSo$ë–¨˙\š±HŞM˝}>­[·ŠôôtRSS©_żľp©WŻžđxJJ Á?­3§Oꦍ¨˘˘"öŐrúôiŽ?nČDćççSQQáüaˇS‚jôi•5ŕľŮŚŰ&4˘lĄ(8µ2v™J»ćĽ28µÁcK «@ŐÉÁ´ Rµµţą ¦%U3´Ŕ5 USŞTKbG˝zőHKK hH۶miĐ ĄVXéI(ÍËËËmµÂęÜĎ?˙lp «Ř”Î őc?j’ Ľk‡gŇMpŞvČÖ!˘b®QuJ‹tFԢˬ#uP»!µGőCŇ©†Äą™–-[Ö¦M›şö=ôçCńAŠ‹‹]űÚö‰' Ińýű÷{,Ń+Ą¨#ěę5ä0‘őAě‚S'-1'Ç­SéT Ć!d2Ý8ś˘Ĺl 64vgŚAkę*QUíéóůÄlHˇ8}út8šĹ…Íčk6áś•4Ż«Ăą´«=-"Ł`LeĆŇ#!j‡S’Ë*Ńe•ܲr0Í‹µY°´¦ů—ćTcĐ ‰‰‰–ÉŻ’’ˇłčqŽżHqśŕÖÚŔhUŐ«ľĄnśI/ÚaŐŇB¶¶tD[›}Q°j—ärŁ%úĎŃ/-¨LšW{â·5¦RKj FBż­Ďdš_đÄFÂ*łieějEějFvŁv‚×gY}¨ýGšRép6ńo§ú·e5'Ő€‚ę$jč1˙ZżśÂŘqľن4Ŕčč}Í [?ů(ćÁ~Ç1T]9†ęŁ„ęhk·>]‚Ë©ĆÔ­¦H$†‘j"¨ k#ˇĎpškFĚMoĘ{»ŕÔ«ł)r<}¨ťäŹ»07íű%Répš ‡v\X!Ńj őÎŁ^ř üërÓ}Vµ\úíęv,í ‚ă`eśjKÍFÁüť*i<áP›ę¤ú—^CĚZ`çpÚ重ʻąů±ą)a)jßČ|‚őCűŽő1ę†Y?řËŤ‰0ő*&8qĄßŤ ëfŰΉÔď›ßI§–UŃ 7úaĄWŇ™¬f<ú VŞ^OÜřˇč•bnŠ\ŠúíF¬u0&˝D:’Lôú ¨ßńĆ€Ó¬#e¦űĽř Ú¶— ÔJC´msrÜM‚<ńâý.RKj F16FBßäFżďĂh$|ł™fQ ;Ł(¸ß)P ł(Côç˙;é ‡~ť@𼍉OŹažM´@đDđeŹöćć¸9ă¨ý]D„âLj몑Ó'2 v†ÁÍbv`ÍĺF!x¨ 1ŞzçR{żE¦h 5Áe¬Š‚VłYęśíőď‹ô¬çkÔkH"F éI"•‰)«ŃfÝ/ümDT§vtĂ*©eWÓa§N"r$eB«©b Ş˝Żz±ę·ęŐ %Yn§#e¨ţÇa˙÷˛ňA|Tj…•ßaĄ%Işcu© ś˝h…•?bN~knuDŰöšßUó;lÖ7‰.Żľ•ŽxLAęIM"ÔŔÁŃÔ3 MőŰ"ÇĐ«Á°Ëbş­Uµ3ŘěźAl8ôkó6.Ž;]çV¤ĽŻĄyߪ–Ôʱ´2^ŚŐ˝vµžSF!\„ŘĂĘÁ4żăvÚáäT†;É% ZEŰZM%uC´ouĚË5nţź­t]´_ŐDV(şáśzId‰ž%rfeB+ p‘,Şf-±Ó;˙ĂÍb•đ˛ TÍ:˘í˝ž”¬áÖŃuŐéhŰvÁ¨yßK@ęUGĽ,҉Sd€#¸p4µ}ł°šU‘ˇđâxÚ¨nŐPN'ÇŚ‚î¬: ŻĆÁÉą´2ˇ:–át.í „U0ę%C)2 ÂßL…ę!ÄšQ°š€„X˝ďvá&@uŇ ·µŞVÉ.«ZLÇÍŰvÇÜśłűż—v¸ŐŻşŞvxŃ 'í0÷ĘDjFİI–[Ş^_^‚Vó9+ ±Ňs°ęĹÁa‡m»cvç«ËŃÖ^ýŹpů " ±Ňł†xInÉŔ4ĆjŚB Šnۨš…Ú­±°:fçhš÷í˛™ˇ »LfU …‘6ćLĄYŚE†@´ďälZsr*í˛”20Ť<Ş Ö ˝©ŹítŔ)©eçTzŃ; ÁáŘk…ÓľDšmµoĄn5ÄJ7ěJ+'ĐM j@ŞßF°mü¤fÔúßÝaÔpŃ;WAđ;ę”ňŞ!^ĺŇ1n‡”Zi‰•â¨Ú]ăEG¤ĂČ5F±0 v6ÍN§•Ă)rüśF/ŽĄů•ŁЎ¨J63\ĆÁŤaGPj6NÁ©‡Ó)¨Ă^Ki˘Ş^;ôŰ^M7záäTş RÝ«Nš!Ňóľ[GÓɉ4ď[˝;nµĂě ‰tĂmpíp“Č9”ÂßNęFôŕ2a®s›ř˛Ň“pú!NAŞY3Ľ¬Žał-ÚwK$|+{)-q”J-‰Cd€x¬UŁĂ©ßw°şÉvz]DĆ!\*¦ăćcVűv8ýv¸S7K7‹“° €ťR‘!F!Š©bmS°ęV3ŞŞn5ĂIC°Y[íŰQ©—ŐIĽ8Ź^R©1J|0ꇝŠ_á58 w í>ŘżźN~ťž¸Ń Ń5˘gą HĄGČ5ŽpéljÇÜ ŻA«#"şĆĘ8„âpšż“‡ÓĽm>f%fvbhĺ\ę·ť á%hµ @ťR+§ŇÖ €4 ŃŽĂô4莉‚UýľŐ{j÷ľ‡˘^[^ťKýÚéŐľö›Yí{Ń/jUKŻşa§nśH‘†¨¤fÄađA|X¬UŃ'ťq Śť4D;Žé86k»mŃ1«ßŃ|.> ˝˙ŐĄ#沙żŐo`ü±¤žÄ2@ŤSBhzbgS´Ú /F$”ŔÔ­“édĽ:™Úoeµďät…âd:‰µťŔ»~§ ÔĘ©”!Ž©¦D—›wÚK¬*©ť†ż‹]€ęV74ěôBtĚɡôâXzq.í4ÄJ?¬4Ä\v«ďlüˇ¤nÄ[ÂŤž¸őCĚĺ}'óvĺA©%q PkU0`-¶NN¨S“·N«—Ĺ®Ľ¸8愝aóbĽ§sNMcěĘh÷}Ť?4qŤůďë˛fŐědjkŻÎ¦—@3T=•Ínm·m‡˝Đ¶CŐ7I(7mUH©ađA´µ¤&ü«ňšŹc:'Úádź«Ë Őń˘'vßĂĽ]yPjIÜ!ÔZŠK‡Sď`Z9›ćµČH÷˝^Ż•Cż¶:&Ú·ĂŤiµĹXxąÖɉt2ŇHlqŃ ŘÎą´Z»y÷ťÎ‡zźUYDeµŰvÂɱÔo»u.­Ž‡COĚ×Y•ĎüDűR7$Şŕ4ĹęU3ĽÜc÷yć2asL´o‡ý0Ż«ŞˇŢ`ŰnmŢ6 ő$ľ‘ްt8A,fˇßvr@ťR·çě®}ľŰmÇ­D0\Φ~Űm`étN´-Z›·EűęAi $ŞY;©v×»Y›·Ýěýď`µmuĚ«^„[?¬Ę(ÚWJݸŔăÔyúmQŔjµ§ĎáÖ•Ĺn‹ăˇč~ŰŤ/N}m‹ÖćmŃľzPjI­B¨’ <4ç3 °ĺPÖnʉÖn·EűNŘ j(†B[»=ĘÚ©ÜĆŇH<â±)0şs"GSżŞVŘť E7śÎą!ÜÚáU+BŐ ©’`Ł#`°Bčúá´Ĺq»-ÚwÂé}ôę{hëph‡-±Ő ©%µ Jń`,‚nŐnŃß.Řv{>™I‘ĹÉ猦yßÎ`Žąy/Â/ťJIÄC˛KťW˝s«!ˇě{!śÚáEKBŮíOJíT#đAôŰnôĂí9ó¶hßę"ĺ„rĚíľń¤Ô‰ Jx„ŕŁj‹âĺ«ňH-‘xE¨’jÁJŚ<6ͱ30"GÓy·„łyM¨×zuLĹJ# ‰qBt6ÍÇťO«ű#ˇŘ|ľ×kâ µC_DŔApŢíąŞ\«'ę|Z" 2@•D—F#pąÝŁ´[ÎŰaŐÎ+Uą?¤{ĄÔ&ěţßìnß+§™¤nH$&Ś>ţ|¨Z"}‰Ä J˘7b˘±ýŘ*Ü[mHá—HÜ…ÚáĄO~X‘Ú!‘„FtBĎŁň}•:"‰d€*‰ĽŠ¦Ť1 ş4„â€Kă"Ĺ^"©YŞQ; ·ą<&"¨|R7$’č˘uÄ-ÂňI-‘Ä"2@•Ä$! żŐ*ŢnĘ* Dy˘YGB)›Ô‰¤fŁ–„ýöZ6©#’h@¨’¨# BN§3śxíGgĽY ‰Ä5RG,n–:"‘x"NµDę$Ş‘ޤFAđ˝LőP¨Ż[RLűő€ H·ś¬Ďx(ź—Ü\ďf$ÓĘ‹Ą±ÔBŞAGô×ÔˇR/ôڡ߯‹ŞšnhK±iŰ-5Ş# µDRű¨fńá¬#É@ ö:r÷µ«áÖ‘ k¤ŽHŞ JŞ•ú&í€ö@şÝ Ł›ĹŢ„Ö SńË 6šˇ8-Ř?ěń/»}¨FÇŚ—áë]Í;fő;K#!‰BĐ‘ -ކh:Ňh€X?ę ÖIa*ľ‚Q3DÚˇß/ö˘j¦''-ž[U :'ú­ĄŽHâÇĄhNĄ?˘-ŤpÖm;%e÷Łů"V>~˙$Şvčµäŕ™"ŃŽëqą\ú$’°"TIŘp!ţ @KŚbß޴߆čiSŐ5 ń~cĐ*Zň©vłp› ‡Űy`ÇĄł)‰5\:‘M°×‘v¨µ›Ń€VRŐŮ …cuc/•‰°˝¨É°2ÝőŠi;”yaĄŽHb—:RcŕiÖ‘t˙5ŃB U x‹¨Ôł†hÚrZw˝Č'±ÚwÔZ"qŹ P%!a#ţ €ľ@7Äbź‘F>ÔÚßV@‹kJPťK˝Řl6 fAÍΦӶČPHgSuŘčH"ĐČ:PéZ·nMjj*őë×.őęŐł°­­ÓŇҨ[7Zş’ŮSZZĘľ}űŘ˝{7{ö쮏;VŐŹIDM ônő;äa4ߥ8­úµ+GS‰&G˛•:2µF#5ÜźYŻ^=ŇŇŇ,u$==ť „űc«EQ8x𠥆ěŮł‡üü|Âđvô/×i ü±†d#pJwŢJOôÚ!VI•1ýŻ´ 8=+Üź™H»ví„úˇiKÓ¦±S!{ôčQ[d˙ţý”••9?Čž–Ŕp˙˘q€ŕG¨Ô «$«$şÔ‘Ú/’WźĎ÷[଺CŹ)Šň|Ä 1`zÉϲ€kP @•HJJ 8ŤVAhăĆŤ«ú11ĹÉ“'m ĆŢ˝{).ö2+…%ŨÎ倣°"ă`ŔÚmW”ơ֣ӒÖŔ(`$p1ˇ  Nť:´mŰÖŇiLOO§eËjŻ8‰*Îś9ĂŢ˝{…˘m†ăŁĘQ[l|ŠŞ#_űŹ™uĂm­«y»ň Ô‘ZŹNGęĂPkü‡ öCŻ2-Z´°MbťuÖY$$$„ăŁb‚ňňr8¤úőáÇĂőq{€˙˘ęȧ'ľĽ$ÓÍŰ•ĄŽD>źoĆw¸ž˘(ŽŽ® Pk:€ÚWi4j`Ú­*ĎmŢĽ9™™™Ą_ż~¤§§Sőů­kŠ˘°˙~Ö­[Çš5kČÍÍ%77—C‡UőŃ;eŔRŕ¨M…‹Á¶~mŢÖ—_‡Z‚NKşˇjČhTM ŮĂ«_ż>}úôaŔ€-éŇĄ ‰‰˛±ŹW ظqc@CrssŮľ}{U{5éµŐÉ,Bę¤ čt¤jrk4pUčžČyçťgđIzôččŢ#qOQQß}÷ąąąź$//ŹňňňŞ<¶XŞ#Ë€źqŻ!RGb  J,Ń€TáŤjZ‡ňĽ&MšĐżřwěŘ1<…•ůé§źNćš5kX»vmUš ĹčdžÂÚÉ´«!A°]yP‡¸ĂŻ% Ŕ…T&·ěF„´$))‰Ţ˝{4dŔ€śwŢyÔ©#ÇX«. X»v­ÁŮÜ˝{w¨Ź+>Gu0s°v2Ý­ćíĘRGâťOŇ•ĘäÖ„ÜJHH {÷îéßż?}úôˇ^=9ĆZuQTTÄúőë >É?üj· ÔîZý˙±°&ľ¤ŽÔ2@•á7ÍQ›ŰŤFm2ă©#VŁFŤčׯź!íÜął¬­aEaűq›–h IDATöí†ZÖuëÖqňäIŻŹ*V˘†Ź€TŠż•‘@°Ť`[_^ibżŽÔ®DŐ‘‘¨µ®ILL¤GŹ@433“ŚŚ ’’’ŞˇÄ/:tČPËš››Ëţýű˝>¦Xęd.Cu2őšaÖl¶AęHܡKn]@er««Çgpîąçü‘ľ}űĆL˙ňx¦°°uëÖ’_;věĺQ?R¬®Áľµ—S]ęH T 0ť©ĚJ^ڇi_Ú·oĎČ‘#ąđ ÉĚ̤k×®2Ť***زe ąąą|óÍ7,[¶Ś]»vyzę`9¨Ća+ÁÎĄ~¬ „y[= CLŕב–T&·®ÄCżôÔÔT®şę*.ľřb233eŤFŚqŕŔrssY˝z5999¬]»Öë#¶Q©#kPű­ÚŐŠx VĄŽÄşä–ľĺ–ëäVRRC† áŠ+®tŞmăVÄ2GŹ $˝V¬XÁŠ+(--őňè‰óe¨­5´.NZ‚ÍÚ€Ô’ęG¨µżHĆwŁĄ®éŐ«cĆŚ!++‹~ýúUG%5ÄĆŤÉÎÎfńâŬ_żŢë퀿 Î˝ZA°aĐöÁŮ@†!úđů| ¨SLAu(]wţLKKcôčŃŚ3†ÁÇĚčŰgöîÝĐ‘•+Wzu2÷oď 6Ö4ĂKŔŠ`[= u$ęđű$çˇú#·®ŁĘÔÔTFŚÁ1c1b„ HăăÇŹłlŮ2/^ĚG}äu ·Ŕ{¨>É÷5ÄK“`:Qd€Z ńŽŔ$ŕ.\ÎV§N.ąä’@PÚ©S§j,Ą$ZŘ˝{7ŮŮŮdggłrĺJ/ĂËo˘ÖŚčU;Ň0D=~i ܆ęPşîSš‘‘AVVYYYdffVW%QÄńăÇYşt)ŮŮŮäääpâÄ ··–˘:˙èn_Ö¤ŽÔ<>ź/ ¸5Áu™ŰűÚµkĐ‘!C†ČäV-ŕĚ™3|ţůç,^Ľ%K–xíVđ?Tů7j7%‘OâĄv5€Ô‘đ#ÔZ„ߡĽŐŚŔĹŔőë×gřđádee1räHš7Żňě’ćرc'ÓeßUřÚ|Ok¶gçhJĂĄřu¤7p0ŁfÖ©S‡‹/ľ8Ü:űěł«»’(ćĚ™3|úé§dggłdÉ8ŕöÖďQkUçŁŇ&ҧ>đúu©#‘ÇçóµCMnMÚ¸ą§GŹÉĚĚ”]‰j1Š˘°fÍš@+ŤĽĽ<··ţ ĚCőIR©N tŰć2I 2@­řĘQŔS¨ŢŰҲeKFŤEVVW^yĄě&RRRÂgź}ĆâĹ‹ůđĂÝ:™ßÓQűéU+!Ě(ÁŻ#˝Pud •“Ł ©_ż>Æ #++‹QŁFÉä–D˘(¬^˝šĹ‹“ťťÍ÷ßďć¶ĂŔ+Ŕ[TŞnśLŰćňH©f|>ßYŔoQ[q%Ű]›ŔE]Ä1c3f ť;wŽH%±ÇŹ?ţVżúę+***śn)FíBđ7 ±?âĄf5€Ô‘Ş#Ô8FWcú4`ŰŽ.))‰ë®»ŽÉ“'3hĐ Z5é´¤ę(ŠÂW_}Ĺ믿ÎÂ… ).vÔ<Ô@5ŐŘ«VN¦~­/‹4 aÄŻ#='ëqLĚ”)S5j”LnI<łuëVć̙ÛoľÉáÇť.?„¨ÎEE¤%nűš:~|>_[ŕÔZÓ»k»uëĆÝwßÍřńăiŮŇU/$‰$ŔˇC‡7ołfÍbëÖ­N—źFŐWP5Ĺkň\ęH5 Ô8Ĺçó žÚ]×±cG&MšÄ]wÝE«Vžf€H„9r„7ß|“Yłf±}űv§Ë7>F5 zĂ ÁÓ®6DżVw¤Q >źď<Ôӱئ©©©Üzë­L™2…îÝ»G¬|’řĄ¤¤„>ř€W_}•U«V9]žĚ@u2K¨Ô‘Ł)ŐăóůZŹ÷`Ó% nÝşŚ3†)S¦0dČ•Oß|úé§Ľúę«dgg;ŤˇQ„Ú…`&pŁO"ęš$u¤‘jśáóůÚApŔꮾúj¦L™Â#dm©¤ZP…ĺË—3sćLţýď;5·ů/đ˙€X+ă€`­•A…đů| QkLŔfDŢ>}úpĎ=÷0~üx9§ ¤ÚŘ´iłfÍâťwŢqę÷ľ xu0”rěµDß:lL©#ˇáÝű.T˙ͲŤZZ“'Ofâĉ´iăŞ+ŞDâ™ýű÷3{öl^ýu§Á•ŽĎ˙@ťOŐ¬%n’^ Ő*!Ô8Á? Ţý¨NĄĐSôů|\{íµ<őÔSôęŐ+˘ĺ“ÔnňňňxöŮgy˙ý÷íŐŕUÔěĺiŚFÁ­aiBĆßśw đW ÝęşĚĚLžzę)Fޱ˛I$‡fúôéĽňĘ+ś:uĘîŇ˙‡ZłjÖ§&Ŕ¶HqŹĎç닪ĺX]“žžÎď~÷;îĽóN’’’"W8I­¦¤¤„ŮłgóüóĎłoß>»Kס&ÎżCŐ -XőŇ:dÂ+$B Pe•[áóů.C}‘¦!NµŔtýúő,Z´H§’sŢyç±`Á6oŢĚM7ÝdUkźŚšdYŽ:§fŠ˙X2ę|˝uQkó:ş%A·řtKźęŃźĎ× Xü‹ŕ433“?ü5kÖČŕTqZ´hÁóĎ?ĎÎť;yřᇩ_żľŐĄ×źwő©Ômi‰HC¤ŽxÄçó5öů|Ö`ś¦ĄĄ1cĆ ~üńGîľűnśJ"Jrr2÷Ţ{/Ű·oçĺ—_¦]»vV—öCťâę) •>‰YGě4¤ŽDYř›Ď<ŤšáţĂŹ5Šgź}–>}úD˛h‰-yyy<ůä“,Z´ČQ›Ů” f.ÍMmÜÖ„™K1>źď&ŕ  ˇč|FF˙÷˙'RITńóĎ?ó /đňË/sćĚ«ËVżAů׬#eű—YŐ„ZŚĎçë ,„Cí¶nÝš'žx‚‰'’śl;xŻD1´ŐgžyĆn`¶Ý¨S«}‡QGôzâą…—Ôkd jŚâóůZ Ž€ú‚ŕ´}űö,Y˛„%K–ČŕTuśwŢy|đÁ|ôŃGvÓ܆:WY:jćRź˝¬‹uöҲ6Őç§:ľS,âóů}>ß‹ŔÁi řÓźţÄşuëdp*‰:ZµjĹôéÓŮ´i¶şěb`1ęHöf1kI"Ö5©˛ÄźĎw đ‚ŕÔçó1yňd¶lŮÂÔ©Sep*‰*´Ő­[·2qâD«ąuŰ׽–8µĘ©#ŐŽ PkźĎw>°f>—Č>H^^ŁFŤŠ|á$ >śożý–ÇÜŞ™W?ÔŚüEŤ‚] *Ť‚ >źŻ j3ČD糲˛ČËË㡇"1Ńrś$‰¤ĆéÚµ+źţ9o˝ő-Z´]ŇuľĂ[pÖł–Č ŐźĎW×çóiSýµąÎČČ`ŐŞUĚš5‹&MšDľ€‰Kš5kĆěŮłůâ‹/čŮł§č’Ô֜ύ°R5±Jś:^d€ZCř|ľ;QGׯ_?rss™>}şQS3¤¤¤đűß˙žŤ7r饗Š.iÚüTď\ę Čą”ýRmđů|Pű­ýŕíÚµ LvŢľ}ĚH$QËm·ÝĆ–-[¸őÖ[E§“P»Ă<Ź:V×VRGLř|ľÖŔJ`Şů\RRÓ¦McÝşu\xá…‘/śD"_|1ëׯgÚ´iVµý7ˇ&dÚ˘N›dn•aU›jŮ*Ł6ëH¸‘j ŕóů&˘:ęAUMS¦L᫯ľ˘wďŢ‘/DşuëĆçźÎoű[Q›Dŕ1Ô U3ˇ4±©őÎĄĎçë‡:U[óąˇC‡˛~ýzFŹů‚I$a yóćĽýöŰĽőÖ[V(Ť˘r@AsÂK¨ÖÁđ’ÎĄ7ŁO čłcÇŽ|ůĺ—<ňČ#˛ő…$&ILLä‘GaŐŞUtěŘQtI0hŤ˝Žu¶îŞŤ:RČA’"ŚĎç»xSr aÆĽţúëŚ7.âeÚ˛e ÇŽ«–g8PÎĎZ‹ÉÎÎć¶ŰnăřńăćS ŞsůOŕ PŞ[—éÖ˘”,=©-ř|ľ^Ŕç¨#ęŹóŘcŹńěłĎR§Nťj-Ă®]»8xđ``żgĎž4l<6Sii)k×®uőLźĎG hܸ1©©©4jÔ(fôcďŢ˝ěÝ»7°ţůç[ő’xäŰożĺ†n`ëÖ­˘Óˇ6Ő+FŐ MKĚ:˘ ¤$üÝş6éHÔî}ÍçFŽÉÜąsiÚ´iä A6oŢĚ'ź|ž={ČĎĎçäÉ“4oŢśV­ZŃąsgFŚAZZZ•?§ĽĽśoľů†•+WrŕŔňóó9sć -[¶¤eË–ôčŃ«®şŠfÍš9?LÇúőë)))Ô`,333¤ň•””°~ýúŔ~‹-čŇĄKHĎŠV 0aË–-ťŢÜ Pé‹čóŔl˘Aˇęˇ’„˘([€ßbt,ÉĎŻéµ9A™é7Pşuë¦äĺĺ)5Ĺ•W^i5Úa•—ÂÂÂű^’č`۶mJFF†č˙Łřęý€ž@W ´Aťľ ęŔ?úi&„5"JĽçŐ˝ç?›ĎĆŤ+K–, Űß͉{îąÇđů«V­^·oßľőĂçó)ť;wV¦L™˘¬^˝:bßMÄŃŁG•ŻľúĘňü“O>i({IIIK˙*7ÜpŐ˙ĘżQQĘzÝPůIGmaĐÂŻ#Ťü:’"Đ‘ZĄ%ţßâkŃ;÷Ç?ţQ©¨¨ß/Ę8sćŚ2}út%--Í•őéÓGY°`AHźuěŘ1ĺ7żůŤŇ¬Y3ÇĎ©S§Ž2xđ`ĺż˙ýŻëçwčĐ!p“&MB*Ł˘(ĘÎť; eůĹ/~ňł˘™ŠŠ ĺ™gžQ|>źčođp%0č tş Wg-¦@c*[nhµ¬µRGÜ,Ŕ.ÓďśâćľŘHMÇţ9NßEý'Đ˝{wV®\I÷îÝk¦`I5ÓĄKV¬X!…Ú‡š´ŚÚÜ×Üä×ssßxoZăéSTC qăĆ,_ľ<îTS…íŰ·óꫯ2pŕ@nĽńFNś8ń2Ľůć›tíÚŐ*ó.‰Ť5â˝÷Ţă–[nťľ‚}·«ţíµ®™žj»lŕ|Óq^{í5«îqÁćÍ›ÉČČࡇ2´x°cÆ üâżŕňË/gßľ}®?+''‡sĎ=—_|‘ŁGŹ:^_^^Ί+4h·Ür §OźvýYwř|>ž|ňI^yĺŃéó€PO˝Ob7gjTÝĐ´j‰ŽT7˛SAđů|ŤQç‚4üŢçśsź~ú)­ZµŞ™‚I$˘Yłf|ňÉ' :”Ť7ęO%ŹŰ€CŘO1#ú ݶŞAPüi»8ä ÔšĺŤ5⣏>âüóĎ·¸%~x˙ý÷ٱc+W®ŚČr\rÉ%üď˙«öĎ’8“Ŕ›oľÉ™3gxď˝÷̧ÇąŔzěF˛Ónı–< 1üŰßţĆ/ůË(NdرcÇçŔ†ăŤ5˘C‡śuÖY4kÖŚňÓO?±wď^JKK×}ţůç >ś/ľř±éóĘ•+ąîşë(.6¶dlŢĽ9ééé´k׎ °wď^vďŢÍţýű©¨¨4gďľű.,^ĽXö˙­îąç***¸ďľű̧ú7ó Ö‘–”ůď«Đ­˙ąÚŕ“Tňż>2ücűk:uęÄgź}F۶Aă›Dś9sćpęÔ)Űkľţúkî¸ăŽŔţí·ßÎŁŹ>ęřl9 ±DŁyóć|ňÉ'\~ůĺlŢĽYŞ ę)Ďáb´Mµ"Hő®vŤţXÆ ÉÉɉ©Ń5 ÄkŻ˝fyľ¸¸‚‚Ž=Ęţýű™3gŽ!©±víZžzę)¦Oź^íe­¨¨Ái”Q§NŢ}÷]Îś9Ăżţő/ý)-Ů5(Ä[€ ‰Güýן5ź>}:÷Ţ{o ”(rŚ?Ţśž{îą<účŁL0A8=ÚĎ?˙Ě /ĽŔĚ™3µ™ß}÷ăÇŹ'''ÇňsŠŠŠ¸á† Áé…^Čď~÷;®ąćaíô¶mŰxöŮg™?~ P]şt)Ź?ţ8Ó¦M ů;K¬ą÷Ţ{)//çţűď7źş u Čmبĺţµâż&(H•„@„Ű!׺>¨Ŕµ¦ď¬4hĐ@ůᇔXâÓO?5|‡ßüć75]$Iڞk×.ĄqăƢţ®.§˛?Yp.ĐhGe­/™6=MPźT% Ţ˙p-ţď_hţÍţńŹ„ůŻăžPű ^}őŐž?kňäɆg$&&*¬ęWp¤´´Ôđą˙ď˙ý?ËkeÔČRRR˘ôďß_¤#˙®†—Qű“uÎFíßŢu€1s_˛¸îŰî×ËMćßěľűî ÷ź'ęXąrĄá;÷čŃC9~ü¸«{żůć%99Ůp˙7ß|cyýË/żl¸vÔ¨QJyyą«Ďš;wnżxřđaËëeÔŞc¶/ţe;0µOę Ôćđ}PűĄjý۵q2Rk“Žx]}PŁźĎ—Ě4˙ÓźţÄ9çśS%’Hjž:đ—żüEtj2jmj ŢçIŐg3}w}?ţ‚”¸ńĆůĹ/~QCʼn,3gÎ$###°_VVĆÂ… k°D’š&))‰wŢy‡””ó©a¨‰­Ô>dɸëŹZ¦źąő· еk×ZQCgÖ‹·ß~›ĆŤ»şwŕŔĽř⋆c/żü˛ĺőďż˙~`;%%…yó湍ü–[naňäÉýS§N1gÎW÷JBcúôéś}öŮćĂg×쏧 ‘cdT2@­^nŔÔ_lذaL™2Ą†Š#‘DwÜq‡hŽÎ¨ý˘Ě†@ËJęťK«ůČân~TźĎש?Ö¶m[^}őŐ*QäIHHŕÁ4űâ‹/j¨4’hˇ{÷îüáťşŁ~MršŰP#ćőCĂ?0ŇÝúc‰‰‰Ěť;—zőęŐP©"Ç?üŘnÖ¬ýúőót˙ťwŢiH†äććZ^«źéüóϧQŁF–׊:uŞaßí4]’Đhذ!ożý¶(‰pĆ×ô:b¤Úľ&qŹěZ˝LŇď$''×ęLرcÇČÉÉaŐŞUěŢ˝›cǎѬY3ÚµkÇ A6l«9×Ö®]Ëž={u ©=zPRRÂG}Ä’%K8xđ Ýşucüřńôďßßň9+V¬ ''‡;vpčĐ!ZµjEßľ}ąőÖ[i×® ö7ٶm NZ.‰–śśśŔ***hÝş5ćÚkŻĄE‹žË\]<đŔ,X°€5kÖč_Ľ:§ˇČ9tšň绋~íĂQ» řőŻÍŔk¦4F?wEE…çQŠSRR4hË—/'11‘ăÇŹSVV&Ŕ¨°°ĐđY^ÉČČ m۶8p€ääd~ţůgĎĎxă’K.aҤIĚš5K¸%jW#Q6Âě{ö+0őCŤ‰n‡\kú ˘Wm0zăÇŹWb•ŞôA-..Vžxâ «~‡ĄaÆĘÓO?­ś>}ÚöyăÇŹÜóđĂ+'OžT $|ć´iÓ‚î˙â‹/”~ýúY–#11QyöŮg•˛˛2ĺÁ ź8q˘°<-[¶ \sçťwşúMî»ďľŔ=őë×wĽ>//Oąćškśś*媫®Rľűî;Weî¸ăŃ÷xuDÎëPkB†˘öIíô@ť—,c?2}Ô¸éűá˙NőżOZZšRVVVOD˛Ş˘(ĘöíŰ Ďéׯ_ŕÜĚ™3 çćÍ›çúąĎ=÷\ŕľäädĺčŃŁĘÔ©Sß5@9yňdŕ9˘>¨˙ůĎ”sÎ9ÇöYYYĘŃŁG]•5??_ąőÖ[•ÄÄDŰg¦ĄĄ)o˝ő–ăóúöí¸gţüůJyyą2mÚ4%))ÉňŮ 4Pž{î9×}ę"ąßž™Ź:ç Ŕ(Ôľd—˘Îq¨őmď€:OŞ«~dJhB¨ °X˙ű$$$(;wî ˙#Jąé¦› ˙źţąçg;vĚŐÜîÝ»w7Ř÷={öxţ¬Ă‡+§NťrĽNöA [¶lÍŹşÜŚFMô\†Ú'UëŰމĘyRµyŰëĹŁŽ„˛ ű FwšLš4It]\łwď^ČsĎ=gČ*Š8yň$O?ý4 b˙ţý®?ăWżú˙ýď…çĚSoĚ›7ʎC‡˛nÝ:Ëç•••ńä“Or×]wą.Cu’““Ă€Xşt©ăµ}ôäß˙ţwJVuĚM™ü Föd‹EÔDĎËhť±ÄHÔ@<ŔÝwßíXkŹF~6Ô Ź7ÎĐüîÝwßuýÜwŢy'°=zôhW­8Ü0{ölFŚhaEvv6^x!'Ož´˝îË/ż$##ąsçRVVf{íŢ˝{ąýöŰ™0aBĐ4VTTT0aÂ}ôQÎś9cyÝ©S§xâ‰'˘FĆŽ+ú»]FĄŽôÄ©O{~Äj—źĎ×S7aÆѱcÇš)P půĺ—öo˝őVľţúkOĎHMMuŐ\W˙YEEEŚ;ÖQĚ4oŢśúőë{şGR5şvíĘСC͇{Ł&°D˘÷Eô]ŹD#U‰42@­ü˙|†¶ ]»vĺ˛Ë.«ˇŐ  >śM›6ŽĄ¦¦ňĐC±páB6mÚÄÂ… yřá‡IMM \łfÍ.żürNś8ář_|ńoľůf`ż^˝zç˝}űö 4(pîÓO?e„ çëÎ;ď$''‡ŁGʞvíZţüç?ß·ß~Ű“Ł[|ůĺ—Ś=Ú0 ĐE]ÄŚ3řňË/Y˝z53gÎdĚ1ó§NťbĚ11ŃGŻ˙ţ 0Ŕ|¸Ć>§ćĹ®˙XĽŽÔ©S'®ç)´ă?˙ůŹa_ßä·I“&†w`ůňĺäçç;>ó›oľ1ôM»ýö۸ţúëy饗řóź˙l¸~ذaĽôŇKĹ®í˝÷ŢKEE‰‰‰\ýőĽţúë,[¶Ś3fpíµ×®Ýşu+Ź=öĺł6mÚÄČ‘# MýştéÂ3Ď<òeËذaoľů&wŢy§ˇŐĽyó0a‚ăďęŕ}˙řÇ?hÚ´)żúŐŻ5kďľű.“&M˘S§N†ëßzë-ľýö[WĎ®nRRR¸ĺ–[̇ۢÖbÔĹ8@’“–ŘŁôÄÔM ¶%ĚoąĺĂśó{öěá /äꫯćý÷ß4u÷ßżˇéď×_M÷îÝąí¶Űř裏SÖH˘Á1 ¨5¤N>‰h°$s?ÔXב"ű Vťő;\pAM•ŁĆ¸÷Ţ{ÉËË ě÷éÓ‡>ř€Îť+šŚŚ ĆŽˤI“¸ţúëÁěÖ­[™2eŠc€¨e@»wďÎłĎ>ËŐW_MII Ë—/Ççóú™”––&dNJJbćĚ™†Z€¦M›ŇŻ_?˛˛˛5jß˙˝+'·ş8věăĆŤ Ô–Ô­[—_|‘©S§úĎ 0€)S¦đĆopď˝÷RRRByy9ăÇŹç»ďľs=RaM1pŕ@s˙±ć¨‚Ż5©Đ-ĺ‚E;®Í?¦őůęGKřjCTбcG“U[X±bEĐÜ©ćA¶î¸ă,X@yy9 ,ŕ׿ţµísçÎťŘnÓ¦ Ç`Č! 2„˛˛2ĂŕLÍ™gÉŮgźÍ’%K‚ú†ßsĎ=,X°€qăĆŽÍź?źżţőŻAu”••1věXCşn¸9sćŢíŢ˝{sűí·3~üxĆŤǡC‡X´hŻĽňŠă—Ú\łcÇŽeĆŚ´lŮ2pîć›o¦¤¤„ˇC‡˛jŐŞŔń™3g2sfĐ@ő5Â…^Čßţö7ý!ę …{p§#ĺşó TjHLꇆ_G:›ŹÇŇÜÉá ^˝z,Z´+®¸"0f¨-”rrr¨S§\pW]uC† aŕŔÔ­[7¤ĎęŇĄ Ż˝öšÁż(//gîܹ̝;—””ĚđáĂ2d®GůµŁ¤¤Äj„|GŽ=ZĺĎŹ,úd·Bě“čýł†čuD[Čľ¨.p;äZŃ5ŁR¦˙®Ď<óŚËxíşiÓ&%!!!p}»víűS*mÚ´ Üăóů”ĽĽĽ ëô}P%))IٸqŁíłçĚ™c¸çᇶ˝~ßľ}JJJŠážH÷AýĂţ xýš?ľáž_|ŃUyj’:ľr IDAT_|QÔěaÔ'ďDí˙qjµˇŔE@_ÔůČ´ľ-0ö! ꋪD6xYüĺţR˙» 6¬zţ!‰>¨GŽö_2dHеĺĺĺJzzzŕšĚĚLŰg—””(Í›7\˙ĐC]S•yPëׯŻl߾ݶ ×]wťážµk×]3{ölĂ5#Fڰ}¦˘(ʆ  úۦMĄ¸¸8č:}T@éÜąłđ:ŤC‡ô®U«VŽe‰ß|óŤHG^î&·PŮŹěJÔ9Rµ~íťQçGŐ÷!Ó÷EŤŮ>íţ2ż ˙]ęŐ«WM…čçăŹ?VŇŇŇD˙+AďďСC•?üáĘ–-[Bú¬7ŢxCiÔ¨‘ăg5mÚTÉĘĘR^~ůee˙ţýž>Cß5śKměŞ(ŠRQQäűË©Ŕ/Ű€_ Î‘:uŽT­_ű9TŽŹˇÍ×^ëű˘"ű FţleGLÍiĚÍŁâť×_Ý0zÝSO=ĺŘź˘QŁF<ýôÓ}EQ1c†ăgÝ˙ýôęŐËöšýë_í””” )+ĚśuÖY5ÚÇŞ˘˘‚W^y%°ßŁG~÷»ß9Ţ7nÜ8C“Ůh©Ý°C_Ł®ŁŞ ×Ő­Í‹›ůÇÍjb´™Żar6‹ß*¦ČËËăţűď·\&MšÄŐW_MŻ^˝HKK ężŢ°aCóH‹€:Ím·ÝŘĎÍÍ5L÷`fٲe9r$°Ż5ď ÷ÜsŹhn=ăÇŹ7ěďŰ·/čýwőů|<˙üóŽźÝ»woC“×ňÁ8Ţ÷ç?˙ٶŮr‹- Ł”8>3RXŘŘ–Tę„HCět$žú´„ٶů#z®¸â ľýö[yäŰѨ‹ŠŠřôÓOyüńÇéÖ­}űö 4wË]wÝĹćÍ›ąóÎ;mýź‚‚˛łłąďľűHKKcČ!¬\ąŇÓgIÂĎç˝-¨Ô +=Ńźsěv$qF¨ŐC’ů@mgLĎgź}Řnßľ=wÜq‡«űîşë.:tčŘ˙üóĎďąęŞ«lĎńÉ'źöÇŽKëÖ­mîPyôŃGĂŇě&6nÜČű#GŽg/bÔ¨QíüŃ0ýF4˘ÜFG•"o6 n AL]0m,~«b×®]üőݵ\fĎžMNN›7oę«Ő¸qcŢ˙}Î=÷\áłÍA¦]}óŢţýű‡}Š&']‚©17ł;věëׯě_{íµŽÉ8Ťgź}Ö°ďFKݏâ Çkôe.--Ťšţt6VkIaĺ\šuD[b^CL|’ÚćŹIMMeÚ´iěŰ·Ź>ř€»îş+0Ĺ’6l`üřń 2„;v¸ţ¬:0gÎöďßĎß˙ţwnĽńFŰ)Â***X±bf„ žűĆ&''‡´$%ą­µť5ë(qn5§˛¤†„ P«‡ťć»víŞbÔ ………†ľ§˝zőr\%&&Ň»wďŔţ÷ßď8úŻÝ\§ ÎŞÉŇĘą5“žžN۶m]]nĚyéĂlž«ŐëH…‘F›ÖÄ1ÄŞ— 50h‰Ĺo÷Ô­[—oĽ‘Ő«WŰ~ť;w6 Ś6oŢ<­‰‘ŁGŹFĹwí)¨s4;ѦMĂľYëVŻ^mh‰ŇŻ_?ן߾}{Ce'hŢĽ9 4p|®9¨v3]$°°±Tę‚•žFńŤ‹d—.ŃeĐ‘ÚäŹŘ‘””Äő×_ĎoĽÁž={řöŰoyńŹꪫ,ř+V0dČŔ\ěnIMMĺŽ;îŕ˝÷ŢăСC|ýő×<óĚ3\|ńĹ–ţŃĽyó¸ćšk $ÚѤIŠ‹‹CZěZ›Ô6vVÓ}ęUG4b˝UWÄ$UE¨sĽŹÚd´Á94ĽeŻo^ˇ( ůůů–ý¤¤¤8tđŕAĂ~zzşë˛tčĐAŘ쮺ٽ{·aâĉÜ}÷Ý®î5OAˇŻ‰ŤFĂďźNSiĘ ®á°ÁW?XR¬r˛ µź ü­bŽFŤŮ6}MJJ"55•ĆŤÓĄK2334h«V –¤M;µsçNV­ZĹ%—\b¸ć˝÷Ţ Śćť””d¬(\čG&·ÂÜBĂL‡CKµ‘ťt@ßrĹs[^^î©LŐ…C€ZUśtÄě\j:‚n‹zb¨ň;rä'Ož¤aÆ5Už¨¤GŹôčŃx€’’ľřâ –/_Î;ďĽcđ#vďŢÍČ‘#ٰaˇÄ śţůśţů<ůä“ňŮgź‘““Ăüůó SN}őŐWLš4‰yóć…ĺ;JěůůçźE•"˘D—Ó"Ň‘X÷G"ЬA #¦lÁ lذ!ÂĄ©9Ěý’Ľ:UfçőđáĂ–×Ú5•Ѩj€Z›ő9r„üü|W‹ľ_DW?1Účˇ: ¨ 45`e‹ąÖ#–3–†šŹ;v8Ηí\zéĄlذÁrY˝z5ü1‹-bÚ´i®›äkŚ;Öŕx‹šůę›÷Ž9’ćÍ›WíK G3Js“ߪ$ű µ±fŞă7$6ö(ÁZâ¤#˘šÓXź¶*¨J¨6ů$ˇśśĚW\Á /ĽŔŽ;xć™g Áč¦M›řđĂĂňYŤ7fĚ1ĽöÚkěÚµËĐ—`Á‚µ¶őL¤ř# ¶čŇëW-“†Hś‘jőŕľ×XµjU­iBa®ÁóÚ·Á\‹`×ďN›óÔŽŞô#uWúađ«J´ô±sçNV¬Xa>ü3ÁN˘Ů0ئzbÎ(ś_Ž”””ČLş 4`ěرý… ć>޶m›ˇąku4ď áÔҤ¤$[-Ś˝«EQ óaű)J î &Ň‘xw,·üýď݉rÔ8˘&˙NÔ«WŹ'ź|’?ţńʆăďĽóNŘ?«yóćĽőÖ[Ü|óÍcĚź?ßół$ޱx/!Ös ęFKâAO"‚ P«ŹąćŻżţzM”#â4iŇİďµyłůz/µ'"Ě5^ĘăµyŻŮˇ´Â)h47 \łŁchĄ ¦óńś‚Zú•ţŔ{ď˝g[7žąé¦›čŢ˝;Í›7çâ‹/ů9<đ€Áź0W:sńĹsÎ9çššęş[Žß˙ţ÷†ýÚRÁQ“äççłhŃ"óáÝT¶ę2z$ňIDľHĽř$E¨ŐÇ*Lµożý¶ëÎyčöŞ8U>źĎ0a|(›ôęźďĄ,VčkÜ|§źĚżˇEł“¦¸¸X”­<l#ŘA+OÎe!°@`ăĆŤ|ůĺ—5TśŘŕŇK/ĄK—.}˝Óˇźnĺć›ov=€[M`ÖľŞhiU}ŃŚ`:2XëßŐ`ZgŘ9”ńŕ`ÎÖď‰jťă’‚‚¶lŮÂŃŁGYż~=ĄĄĄ!='))É0Ú·Öż[#%%…íŰ·óăŹ?RXXČęŐ«C.sÇŽ Şüüüź%qÇěŮłE˙k°:í|Ijőb0GŽá‘G©©˛DŚ-ZúnnŮÔşČýőéééÔ­[·JĺÉČČ0ôIűţűďm®®DQWˇ~&·Şy$3摉˝ô:yň$©yQ$yüńÇEý‹s©DŔ*HŐoÇ|“^Ľf>pß}÷…ědŐôµ¨K—.Ą¬¬Śm۶Ţ˙hnŢ Á:ŕEK ýďťćdŤU>üđC˛łłÍ‡DMvé 5‰šâ>@­ đôÓOGý4dá {÷îíââbŢ˙ýźĄő}ĽEźµaĂ6oŢŇçś>}ÚČŽ×÷7ZŘąs'Ó¦M3> |gq‹UËMb+4ĄÚ‘ę˙oďĚì(Îľ}ŰŠbEpEpŁ DŸ#F‰ FE}óşÄ qIxóiÔD0nźź¨ Q#›˘ FÔ ((qayAePEf†e¦ľ?zúLźšęíěs湯«Ż®®Ţę ôŻžç©-»<…3Ło‚x iMÎbĹ;kć’%K’şŘ1sćĚ$rřđái—ĄiÓ¦śx≉ăiÓ¦Er<ź{îąH µk×.‘Žâ nÝş•… ^Óż˙¤ńb“'OŽěüţ÷żgżýöŁeË–zčˇiEqłĹ›oľÉ˝÷ŢkfWäˇ8…Îbś(n]ĆâĹüáČSq^xaâúî»ď7o^’#sôŃG‡®)jŽŮ šd(ě»ďľrČ!‰ă©S§˛~ýúH÷Ţu×]IAŞLhiˇ±yóf.˝ôRŰ©`mśTI3†}˙ý÷\|ńĹy*Nî0˙ďßqÇ)M6÷ţűď'uµíŃŁGč»~÷»ßĄ,ž:uj’ŢŘŢ%d†ššFŤeű?±·%h–5»|$Y‘Zk.ľřâ˘ű1zôč¤ă("­µćć›oNĘ;űěł3RžË.»,‘Ţąs'wŢygŕő555Üzë­‘žíťHéÓO? íŠs×]w…ŽUmßľ=gžyfŇsďľűîв¬[·ŽtÜvěŘAuuuč:±ą¦ĽĽś‹.şČfěĎ#yĽĄůFirM± kqř&L(ČŕCˇ°˙ţűsę©§&ާOźÎ´iÓÇćL™6š4i’4I[>fÄľä’KéĘĘJn»í¶Đ{ľţúkî»ďľÄqË–-2dHVĘ—OĆŽ[o–vśń–¶{^˝(FťÂý˝ÂY/ÁÜąs‹~\űÉ'źLßľ}ÇK—.Ą¬¬,t¨Ť—Í›7'}‹lW¸Ś=:É&9s&—_~y¬/K–,á†nHďľűîI“& ™ĺž{î©·ö<Îđš7Bn55Ĺ´Kl6 >y‚8¨ŮçŻ@Ň˙üµk×RVVVĐł«¦ËOúSŽ?ţřÄńâĹ‹ąč˘‹|Çŕ–——3räH>účŁDŢI'ťToýÂT:thRkÉcŹ=fkÁś‰Ž~ó›ß°dÉ’HĎöN˛˛cÇ®ąć_g|ňäÉL0!Ňso¸á†¤śŰn»-p&ż-[¶0xđŕ¤˙WW^ye¤™ŽsĹŽ;8çśsřâ‹/ĚS_îŔJ?GTă¬'fćŮ*ó9 ť÷¤Euu5#Fڰý-…ZĽÝ|źyćŢyçš7oŮŕóX˛dIλÎ_~ůĺI˝4yäţüç?ű–cŐŞU 2$IkŻşę*Ú´i“ő˛ć’ńăÇóŹüĂĚ®¦=¸¤'¶ë:›z3÷Ś7ŽŮłgçˇ8ąăÎ;ďLŞO_ýuşvíĘĂ?ŘšZSSĂ?ţńŽ=öؤîş ˛wŰm·zö‡zŁŽ:ŠéÓ§:ŞŰ·oçľűîăÄOLZyĚ1I dŽ—^z‰›nşÉĚÖ8:Rĺ9NeŇ@ÔěŁ_[˝™óćÍcřđá]N¤Đxę©§’ůOž<™cŽ9†§žzŠ+VPSSĂŠ+2e Çs S§NM\Űľ}{ž|ňÉŚ-}ФI¦NťšX›°şşšk®ą†‘#GňÚkŻQ^^Îwß}ÇěŮł0`@¬ň¨QŁhÝşuâxęÔ© 4—_~™5kÖ°rĺJžţy̨QŁŘ±cG¤ń$}űöeüřń‰ăĘĘJFŽÉyçťÇkŻ˝Ć¦M›ĐZłnÝ:yäŽ>úč$ż˙ţŚ3&ňďČ6»víâśsαB;i8-„~ŃHÓ¨ 3,‹­rĐŔťŔGŢĚ/żü’SN9…µk×ć§TÎđáÆÝĆŤ­ögśqF˝‰Čü𮧼7o?ţńŹąúę«=zt˝őŠłA»víxâ‰'ZX]]Íő×_ĎŕÁ™1c6l`×®],^Ľű￟޽{' !čŰ·o˝A:&LŕöŰo·ťzp»'ůi‡™Ž˘'ĹÄŕQoĆŽ;8묳ř׿ţ•§"eźÓN;ŤżýíoIy_ý5—^z):t`Đ A\sÍ5üĎ˙ü÷Ţ{/7Ţx##FŚ`ď˝÷ćÜsĎMš%şK—.KĚ\sÍ5őZW—-[ĆđáĂéСgťużýíoąű뮻říoËĎ~ö3Ú·oϸqă’Ö?0`@Ń}ż…Â«ŻľĘ#’–!«e!ő×öÓ’c‡5Cîô…Ĺűr p=0É{rÎś9śsÎ9<÷ÜsiOT|đÁĚš5‹aÆ%wéŇĄ\pÁ4kÖĚÚŐµS§N<űěłěż˙ţ-O÷îÝ™1cgžyf"b:eʦL™BÓ¦M©©©Ij•čŮł'źţ9[·nő{$ŕ,qŐUW%µŚÎť;—ąsçZŻďÖ­'NdŕŔˇeţýďĎĆŤ™4©îżÎ3Ď<Ă3Ď<8ł ZÄ•ŁŽ:ŠYłf%ň|S]]ÍČ‘#m“™Ľ xgKňsHÍ­˙ŠÁű¬…ÖZ×®…jNµ¸ §ŰQ‰{ýŞU«8ĺ”SxóÍ7Ůwß}sZÖB§¤¤„óĎ??éűx“# 0€E‹%ŽçĎźĎüůΊŁFŤJßž-Î8ă |đAĆŚCuµÓÓűĺ—_ćĺ—_üµô„NŕŮgź-ŞúĺľűîăĆo´ťú¤v{ ¨M7L ±éHÓĽżë&ŕ 1ËOUUC‡eÎś9ôë×/OEĚ.cÇŽeÇŽÜtÓMI=Ť¶oßÎś9s3gNč3zôčÁ´iÓBW8q"Íš5ăHÎňĂ?đ /D*ďi§ťĆsĎ={ýc!śyóćQVVFUU•yę[ś Ž_°Üϱm~˝1„H jŃuŢŤ­r{ř›yŹë0ĺ"źú÷ďĎ;34ĚĹ4¨š6mĘ9çśĂ‡~ČqÇ—•ň 8·Ţz+i< 8”×90`/żüräŠáŹü#7ß|3%%%םqĆĽőÖ[‘»ë4iŇ„‰'ňČ#ŹPZZZďĽéś¶lŮ’+ŻĽ’×^{­ŢŠůbëÖ­üüç?·uÇXP»Ů*Ó5·#m‹^zźéýFŢßó p1Žłš`ĺĘ•śtŇI‘g¨nLx»ů‚łtËŕÁ#ßçťw2lŘ0ëąO>ůÄšź ~ýë_óĘ+ŻĐ˝{÷zçL-Ým·Ý¸á†xóÍ7éرc®ŠU´ÖÜqÇŚ7Îvz-0ĂĽ…ŕŕ–ź¦ł“ ÎoŮś $M°mŰ6N?ýt^|ńĹĽ,Ś7ŽĄK—rÖYgĹţ˛űî»ó§?ý‰>ř R¨¦M›r˙ý÷ł`Á‚ŘkŻ–––ňä“OňĘ+Ż]×üB`Ú´i 2„ŠŠ óÔV[Ý­_ĂśS?›ÄŰş*-¨)"-¨ŮĹüŹ=hŽ1äĹ_¤Oź><˙üóôęŐ+÷ĄŚŔAÄ-·Ü’8ŽaíÚµ+sćĚáťwŢaúôéĽů曬[·Ž-[¶PZZJçÎťéׯŁGŹ®·f©Ť#FĐĄKöÜsĎŘżĄWŻ^,X°€3fđôÓOóá‡ňő×_Óľ}{zöěÉE]DYYY¬g*Ą¸ýöŰ=z4O>ů$łgĎfŐŞUTTTбcGúôéĂ/ůK 8Ąű÷Śâ_rÉ%śţů<÷ÜsĽţúë,^ĽŤ7RUUĹČÁĚGÁĺ—_^P­hË–-ăĚ3Ďô[ă}ŔŰß7Šsş«v«öě˝Fe1Wîoz¸g«„†ŻX±‚cŹ=–Ç{,c“‹qĆg$µ"ř}»mÚ´IŇŽ®]»f˝l^úöíKiiib2ť_üâ±Z›5kĆłĎ>ËÓO?Í+ŻĽÂ† hŐŞť:uJZkőä“ON’Ĺř5˙6aąđńÇ3sćLfĎžÍ{ď˝ÇW_}Eee%ť:u˘sçÎ < .¸ iů+?.»ě26lŘô[‚8î¸ă’Ęś ú»ďľă—żüĄźăô%ŽQąŕ!~:b:§ANjCtAňoY f‰ţî?üđC‡妛nâ¶Űn«7“u1pŔđüóĎóí·ß2{ölfĎžÍgź}ƦM›Ř´iěłĎ>”––Ň˝{wÎ<óL ”4aZTúöíËŰożÍÚµkyńĹ™3g_~ů%ß|ó ›6m˘şşšŇŇRöÝw_z÷îÍ#8ńÄ#;ĎăĆŤK4p¤ÓcŞm۶Ißu1Î\SSĂÍ7ßĚ„ lcřËÇqZPtÄŐ›-Ö««ˇęF^PąÔYĄÔ 8łČąÜ¨µŽ6cLAŐY(ć"ŕMqŚÉćŔźqZA’hٲ%“&MŞńňG‡ŘĽy3ŕĚÎ÷đÇÜ!¸<˙üóüęWżňë"˝…˝đ‘;q Ďí8TZ¶ŞÚó;jŻß‰˝5¤Á–qµÄ«#gă ¨gÉü×ý&L(¨ ˛ňŧź~Ę‘G™8^˛dIŇZ…Baóá‡M¶ŚŁî·m3$]ŮA°ŽTQ_GĽ-" JG ž–x푦8:rđPŻ[ĎŔ™2eJhwVA(t6oŢĚůçźď7ôjđ˙wf*[pËuH]{Äk“T`×WKl=4”ޤRjp€'«•Öş^ßj“â Ť6ü&śJ5‰ŞŞ*.ľřbFŹkúsA($***¸öÚk9űěłýśÓđwNý˘”A[X÷Ľ‡Ďpďq ÎÄR×`Y§í®»îbŕŔ2Ă/$Mx6`ŔqNZk&MšDż~ý‚śÓ'HvNٶśúéHĐř±bŔ¦ąźçáĚđ›Ä«ŻľJďŢ˝yăŤ7rYFAČ(óćÍŁOź>AÎéăř;§fĐÜÝvz¶ ›Ä6ěH€8¨&`ŞYaŢÜŚaIâŃGĺ°ĂKL„# …éÓ§sřá‡sĎ=÷ŘN×ŕtéť˝ Ť÷1§e3+‚z-ŢtŹVúŢĎçSWą&xăŤ78â#¸óÎ;­i5¶nÝĘäÉu±Ŕ+ŻĽ2ŹĄ˘ňŃGŃż®¸â Ű$&‹ÇpZ,Ľßşß1? ńęmČ@1–6ü?Ŕ`ŕCóâ/żü’“O>™QŁF%-}"…ÎĆŤąđ ůéOĘęŐ«m—¬6Öőčň:¨;ńwRşú 15űőaǸÜ`Ţ´aĂÎ;ď< ÄĘ•+sX\AĎŞU«6lÇgÍš5¶K¶âtˇYP{Öµ×ěRăÝü*›sZLř9©ďĂpşM'QYYÉÍ7ßĚQGĹ믿žË˛ćťíŰ·sá…&Zń8ŕ†šçR A”——sÝu×ѧOźÄšµŐ8c&§á|˙~ΩiLş[ŽM–侣!şĽżĹ;fßýÍ_çÖŶ'OžĚa‡ĆĂ?śóµ€!555<đŔtëÖ-h9 ÷pl’ojÓSCüśT÷y Žj,ÄAÍ.aÂ.śĺYŔ|ŰćĚ™CŹ=?~<ß˙˝íAČĺĺĺÜqÇqÄĚś9Óď˛Ő8QJ×ső« l­;,iwĄ‹o1TQţ^€_â˝ę±|ůr Ŕ/~ń‹˘íöűńÇsîąçróÍ73jÔ(;ě0¦M›–8?nܸ˘śđĄ¨©©áÉ'źäđĂç/ů‹uÉ` Îúťn Ć6ć4¨ŐÔÔŹ )ý°8ÔAN}p NŻúëo|ű-—^z)ýű÷çß˙ţwö -)ňöŰosüńÇ3věXżŐ1v˙^ÂľözcjËÍ`—ßP0´¤şr†L’”%|&9iŠhFÝD'-pÖ4l\Śvł=łm۶\sÍ5\}őŐ)Í^+ÄG&I˛S^^Îý÷ßĎÝwßͦM›ü.Ű ü §…ĎjíÉó¶\x JďD¶Í;1’[‰X»Ő4ÔĘ `˛$›Ž´Z'ăŚs·®/ŇĽys.ĽđB~÷»ßqĐAŮ.i¬^˝š<Đzî裏ć˝÷ŢŁY3™¸ľ¨©©áé§źć¶ŰncůňĺA—.ÂY/Ů]Ľ2jË5 ŁčČěăQ“Ő†¨%†Ž€Ł®Mâťx­9Ž=RŽłňŔŃ~Ď=őÔSąőÖ[‹vÝTˇáđöŰosë­·ňÚkŻ]öÎ,ř®Ńbfä2dÓ?-qĎŮze­¨ RGRE&I*lĚHŻŮ§Ý5Ć'?¬}ń¶lŮÂ-·ÜÂAÄí·ß.) 9§ĽĽś &pĐAqăŤ79§Ë€űqzÎiÔÖ·Bđî˝Kż®4EŃňaŕ7^ל¸a0g†ßDZL ´sçN}ôQşuëĆčŃŁ‹¦EµcÇŽÖY‹»víĘ?˙ůOqN ×1=â#9rdsú5N«éLęĆ›Ćé}á5*mZÖ‚šDC5*Ťą1Ü˝ů÷3»0.ÇYmŕvśÖëzĚť;—ţýű3hĐ ż.Ů‚UŢ~űmȉ'žäśnĂi5}Ç9 ŞOýƬŰôÄ\= ,ŔŐčśÓtÔ,ˇőĂťćÝŤZş- %ŔO€kýüžß®];®¸â .»ě2öß˙lýŚFÍ_˙ú×Äbνzőâg?űYžK”ÖŻ_ĎC=ÄĉśR€ďq&Br>5 ˘0Őë„z#•ŰIŽRÚZ<¬ÝózeˇőĂ«#nŹŚ-éü7ÎRVš7oÎČ‘#ąâŠ+čŰ·oV~C®¸îşë?>«Wݦ´´”˛˛2®ľújÚ¶m›ď˘ Ŕ¶±â•¸ IDATmŰ2e ÷ÜsK—. ştđţ˝/˘:¨^CŇ«#¶Ą©{a@ĂÖĺ]¤×ľ ž©#®–´ö®Ä™HÉűś$N;í4®şę*N?ýtéN/dŤššfÍšĹ}÷Ý6·‚ĆY5ŔÖűÂM›C\{ÂĎ1µŮ$fWß ±ě ZGR!ŐTqPłHH…`®ičuRÝJˇ θ˛łńéö ΂đC‡eěر 8ä× BęĽńĆLš4‰^xÁo\Ëvś ŢĆj?ŇěBfTšŽ©Í9-ZŁ|u$(ŘĺuR]-9ěô®cŽ9†1cĆpŢyçĄµč» xY¶l<đŹ?ţxŘ\ 5Ŕ'Ŕk8Á.°”¶Öż ŁŇtPMçÔ¶ćiŃuÉ š9©®Žô.ŽzĎAÄĺ—_ÎĹ_L‡˛đK„ĆČ7ß|ĂŁŹ>Ęß˙ţwżYy˝¬ÂŃ‘µµÇaÁr›sęönôĚý‚ĺaÎiŃčH\ÄA-PZ?Ľ‚×I5ŤË`/ś®żĂÖAďëÚµ+cƌᢋ.’V!%¶nÝĘO<Á¤I“řôÓOĂ.wÓw¨żä»·U~łâ™­§aÝiŠŢ¨„”‚]¦qY‚äúÎĚáĄAďk×®]tcĆŚˇK—.™ý1BŁ`×®]Ě1‰'F™AÚuLß$y|»÷k5uŤJŰD&¦vŘ‚\6±N’T ZěňΑѼvďj7p^Ź<\T¸¤¤„sÎ9‡±cÇrüńÇgöÇŤ†wß}—‰'ňěłĎ˛}űö°ËWáôľXU{¦#Q&D –‡uď-*‰‹8¨J@…`›4Éś8É40Ű#€ˇ„8Ş%%% 8˛˛2†Jii =*4r6mÚÄĚ™3™1cŻĽň •••a·ÄqLýşâyÇMúµžzŁ—î5a-§EYÄv™'™ZŇ8 gI‰}BŢɱÇKYYeeetďŢ=ŁżI(.***;w.Ó§OgćĚ™aĂ ľcjöŔđsN´$ę±b×v…ÎK€c€‘ŔaaďíŇĄ Çgذaôë×Oş ľÔÔÔ0ţ|fĚÁ´iÓX±bE”ŰVÍ1µŮ#~sŻýwěiŃőćJqP ]ô‚ŚKoĹŕ¦Űá8©§á´®†˝_ŚLˇ+V¬`úôéLź>ťůóçSSS~“łžé"ç4Č1ők5 ZźĐ¬ ˘NhRôF%„»‚tÄ>ŕn­€S€!@¤é|=ôĐ„Žôďß_ŚLŤ7&‚[sçÎŤÜç{ţ'ŔĺNZÁÎiŽë%Ű´ÄĎ9uźéu‚‹VGŔěŠę¤Úě‘@_śµŹö<Ó—˝÷Ţ›!C†PVVĆ©§žJëÖńvˇŕ nÍš5‹oľů&ĘmX3ă*Ož»Ň‘  —ٵ×Ď sN˝ĺ)J-‰‚8¨NŠNŞÍQőî[Ç€D¨ ŮČěׯźućKˇřĐZł`Á‚„S2I‰ÉŔB`)öIKĽio«©ŮÚáŽď0[Nfí Z»Q8§.!:b.áŐŻ“ÚÂH·şăt˙=ľöÚP:tčŔ!C>|¸™ŤŚĺË—'täÝwߍÜřxřÎ7×15ljů•¶™żÍ —źsę-OQjI„`—é¤úÎM-écŹüŘ#JYZµjĹ©§žJYYC† áG?úQş?Oh lܸ‘Yłf1}úô8Á-pfĺý'Xľ…h:böľđ.m4Ô(h°E­#QµŔ1*vRÍńd¶îzŢ­9°?N‹ę‰ŔîQËĺ™Ă† cĐ AbdUUUĽúę«Ě1™3gňŐW_ĹşÇ|źh­aŮÚ´đµßءÎ)weŁ%5HGü¶v8­Ş€Č–˘™ĹMMM ďľűnÂ) YłÔ¤'°µ§•Ăűm†¸l­¦~Ωźcę˝Ć4(ťsęĂIµé9ÉÜZý€SČŘ›4i 'ś@YYÆ Ł[·néüDˇYľ|93fĚ`úôéĽóÎ;q‚[kpě‘%$/ˇ%Ŕĺ7©šźsję‰wQ”±ëŤBG˘ĐPÔëŻCÚhT°VîŢÖ˝Ć[)¸“řŢ®|­>8]nŽ"d¬Ş—–-[2pŕ@† Ć 'śŔá‡.­« Śšš–/_λďľËĚ™3™3g۶m‹óí8]f–ᬷŁ6?¬+ŻźAiëBc3*mN©wVĽ°ńŤŞ2褚3üš­ 6=ńjI9šC \ĽFćO~ňzöěIË–-S˙±B^X»v-ď˝÷/˝ôłfÍbăĆŤqnŻĆqF—á8§[=碸ĚŢ~:bÓťŘ\Ţ6mk'{Ë&:bś›:d“¸ŰŔq83wŽSľnÝş%ş÷éÓ‡víÚĄô;…üńÝwß±hѢD÷ÝÁ-€ 8:˛đŠPŽřőľŇ‘ €ą÷š(ÁňFĄ#aXÔ–ZëĐŮ®rí ^ ÜëÉşMk}KÎ PDpRÍÉ“‚˘—6cÓ=ß 'şy8NĹĐ g’ĄČ´nÝšŁŹ>šľ}ű&¶®]»Ę¸łAkÍĘ•+Y¸pabűđĂŮşukřÍÉlĄÎ!ý‚şČdÔÓ°±¦AFĄÍ «µs ˇ=2Âzex^~Ҹţ`śŔW/śŢ‘iÖ¬Gy$}úôIčČQGE‹-âţl!Klذ!IG.\×!…äŕÖJęÖ„pc2ŞAiÓ›žŘtD‚\":©~sS3L=ńnÍpzeôÁ zu­}nd9äúöí›Đ’>}ú°Ç‘z 9ŕ‡~`ѢE,\¸0±˙ěłĎâ>¦†şŕÖrś.Ľ.Q‡Ĺ –G±I‚ZMĹ9 A)ő5u=˛4Đ4Ęß&×ęhŕaOÖ_´Ö×ĺ¬BLăŇśĺ×ÖeĎtNÍJÁÝÄ©zÓČtiÓ¦M=§őĐC•µWsŔçźžd@~đÁak ±Gü—ë°;Łî>®cj«Ěîx¦qiŽ3ŤĄ„ĆWÄĐŰw?ńÓď}? ző%¦‘ ТE zôč‘Đ>}úpä‘GŇĽy¤áŻBlܸ1É€\¸p!ëׯOőqŢŕÖç8ß*řëÔ˙ŽýÓ ńÓł žß&âśzś{g Ź˘#a6‰÷ľ68Żž8몖¤Pnşté’¤#˝{÷f÷Ý#ŹrR¤ĽĽś>ř IGV¬XAŠźĎvś Örŕ nyÓaŽ©wĚzXËÜňłIjŚ÷ŠŽ ”ÚF]oÎJ­u¤žťąvPϦx˛ŇZ_–łŚKł«žY)Ř*[+ŞY)¸­˛{ăT˝€CHÁČtŮsĎ=éÝ»w’ÓzđÁ§ú8X˝zu’ąhŃ"ľýöŰt©q¬v»Ü}kś3÷aÝď˘8¦A‘Ę J hŚ8§tüŤË0ÓołéČ8C záôÖHąY´¤¤„ž={&éH÷îÝeA|űí·őZF×®]~c0é·lZb›L-LGüZK J۸u1*‰Ý»ËOGĚŢQu¤g˘¶^8C RnmҤ ÝşuKŇ‘^˝zÉüiPQQÁâĹ‹“tdůňĺqÇŹšlĹqF—á·ÂznyÓ5FÚωŞ#ć8ő°`ąYoyµŽ(ĄšP¸ؤµŢ;Ň˝9vP‡3˙üóLĽĆ n-ĹŃ’o=ůŢkR půM¦–) ę}!:bâ¤úŮ$ޡH¦VÄqR˝zrŽŽEČZÍQhÚ´)‡~8x UK:věب{oěÜą“uëÖŐÓ5kÖ°jŐ*–.]JuuuřÂůGCĽÁ-SGŔ_CÂzpą‚td—‘ A®(Ąv'y‚5Zë"Ý›cőŕ5OÖt­őđś ‰`\FuTmF¦Í°lnÜç}Vęf> vëěW{>cě¶Űnő* 3ÝP#žUUUVÇÓ›W^^žé×Vă´l¬÷l_ă?Óť»ŹÚő.Ě1µ­Kh~Űxż–ŽŔФ2p‰¨#¶á~¦MGl{Ó°ônűP§#ťq– ČčlI-Z´ cÇŽľl§Nťh۶m&_™3víÚĹúőë}Yk×®eóćÍ™~­Ćq@˝:˛˙%aĚ˝źCÇ15güŽ˘#aŽ©okŽx‰Ń»ËfŹřéHž:äŐ§¶8Ă“:{¶´_^š4iBii©U?ÜôŹ~ôŁ ÓZłqăĆ@ůꫯŇm µ±G;ÖQ§%ĺ;¤Ţtś@ąÍ1Í´ŽH+”RĄ8˙\–i­ŹtoŽÔcž¬×´ÖsV€%¦qiëfcëţkvďµE-mNjSăů^§µ3ŽĂÚ (%ĂN«É^{íE§NťŘ˙ýiÓ¦ ­[·¦U«V´nÝ:i‹š×˛eËzŚÖšŞŞ****¨¬¬¤˘˘"i‹šW^^ž@F\`:j°;Ł;˝?Í’Ş‚ŚIŻ!TBď×]&¬ĹÔŻ;ŻT!Dě•d`úi„mČ€-ŘĺŐ݆¸i×iuµd?R{‡6mÚ$ ͶmۦĄ!nžm˘¸;vÔÓ…8ân_}őkÖ¬aÆ Ů0Mľ#ـ܀łĽ”ź~¸űTŤI[€Ëoh@*:eňŃ‘bÎý†"…Ů$¦=8·iI;ęčťq쓬<-))IĂ:tč’~ůÍš5«÷ž]»vĄ¬ŢüM›6±fÍÖ­[Çöíˇ¦¦Ë6ýđjÉVÂuÄÝÇéuáŕĘ„ŽĂ‹l.Ń‘(ĄĹ™<Ďe‘Öşo¤{sě |âÉZ µ>>g(pRh1+† Ę!ĚAŤâ¨z7×iőVűĆXÖlŁ”˘eË–‰–ŮĘĘJ*++SÔź+jpÖ ő ˙WDsFÝ˝źA4Ž#Č 'f«ĚkMgׯĄC*‚HQGlKÓŘ´$ŞŽř9Ş^-qmĄ$ëHÇÚ÷,%%% ÓŐ‘ uË&[¨Óu8Îh…ç|¦śŇ(­Ą©ę­×…_€ËÝ›ĺw2DG‰ˇ#QZTăčHMâgŹNk'-)čnXÍ›7§uëÖ”””PUUEee%;wî ż1żT¬#ës¶Ć¸˝-Ri-͆ŽDm1-‰RŞđˇ'ë-­őO"Ý›cuś±,.+µÖ]rV€€ĄR€ú­ ~ăĘl­!~‘L3ßϸ4źk«Ür´Ŕ1.;á8«ípşç´ĹY¸[đ§ GäÝíęZ4Ü+j4ŇÝgşđ«ü*[Kkµń›qkű=ÎT‘Đwď§#ć·îŐ‚0c2JŔËlQ5߯jď݇şVWGÚ»y~‡Pź]ÔiČ’»ëşÎ¨MGĽé0g4Ě15żqŻ–ě˛¤Ăt$Ş1)e†‰ˇ#A-Ş™°IâĎ˝e連#q–Ůsµd 8^Ôŕ´€ş:ňŽ-˛žşe_˘č»Ň”(˝·âËŁŘ$¦ŽµZuDKÂPJ ^ődÍŇZŤroýţŮe=ÎX·K×J©¦Zë‚=ç ÷?»Q1Ř>€ö~äM¨űĐšzö»¨odÚ*‹ '5Js'NSţgÔŻĽZâTí©36Űz¶=)Ţ Ă{ŰľĘr_&R[ŕgP†UAĆĄ_ŕ­Ě2HEatÄŐ ÷Ř›¤!^‰Ł©;58ÁL×Đt·ć8Úánm-[A·ľ¦ĆéJçu@Íô6ę;©:¤î±í; pŮŚJ?çÔĎIµÝkę•”Y$‚=âę‡"YKÜ´WKšP_C‚tĦ!¶ž~öH§ęk`ÉZŇÇćđżL»$Łăĺ o@Ü´EľÇ±WL»/®=bę‰T˙’úÎ+–=Ô× ż´mó:™Ţ59mi3@n#]ń¦loÚ/¨Ĺ& Ó’(vHÜŕVdÇDKRÄtP?‹zc>TÓ{>řWĘŃ`HÁQőV ćř˛jăŘĎČŚşůµ¦zŹÍ2Ř*ż(¦-ĎM»‚ É•„Ĺ Šj¦ń̆1‘ŚR „“qśÓ0árHśR©rL ŽŞ-ŘĄ°kH-ićs]T3NĐ+LCÜô. ’üéřkI¦těӒ¸®Lh‰ź1é甊A™b C2U3ŕĺgŹřéBÜ€y&^a:âî«©®“Š–ä[GÜtT»$,°ej÷ŘωÚzj»6Č!M)Ŕ˘#iŇ ZPÍÂ’‡24Hb:ŞxŇfĹ`:Śq Í ĘĂV4őĽł)éU 6ç•€˝™¶‡ĺű‘ c2jŕgPÚ*S¬*żŠÁ挆’~‘I©ňL ±6 1ŤĚ8N«ß5~†ĄźŁÔUCŠEGĽé8ZÇ)ŤbTĺĹ5$Ý ‰©)¶ż•hIHÁQŤ˘%~dw„9¨™ žÇ ˘c¤mú -‰Ş#ŢŠ‘GCâ¶DGІ@4;$ŠM¦Qm’¨ZbË#$Ť‘Τę§)av‰í{ ˛âŘ#ql’°÷¦¬# Z’#úÇďÄą9_ëżÍ§ÎA8qP3JgŐ{ěgdzÓ~śj…‘ c2¬őŁ Ë ă2¨BR9¤c0ú9Ĺ~e¶ý>3ídHĐŕÉ@ĐËfd†éGş’ŽcÚÄSöT ˨:áƤąŇ‘(ßtTG5Ş†Ä hĄ¤# ZŇЉaʏy~ß]žiI=É”–řŮ&Qöf:ڍúaîö¨Aó¸Z¦Q´KÚö÷¨ËÉ5¦ËĎË—úp•çř„<•ŁQˇëžÍČ»VcÉóé¨ĆgŞÎh”Ę J§RđÁtŤĘ8FfXUěÝ|ż˛ý.3ídHP´ÄtVÁţíŮľĎ0c3ÓZ’ŠQWGlÇ^RŃw¤)aßz>dÂpŚbDŠ1ŮHIÓYu÷Q4$ú‘ -±•9Ęźcóďc;ŽŞ#ŢtÝČ—–ŘĘlţ~Ń‘B)U äÉúXçůlAő"jŽadšétŚÍ¨Fhş×’ĆHŰňüŽý*oÚ//nĄĹŕŚ{Mč‡Uh¶ż“)@Ł#E#3cÓ›¦q‚XQz_¤bPĆŐo^¦¤Ł!qő"NhŽX˙˘#ŤŹ4tüżŃ¨¶I&ő$®]bŰűĺŮŽ AG˘jFÔˇBA¶ź"6Iáb¶žľ÷ß%/ŞÖzŤRj=°_mÖ~J©ÎZë5ů(Oc%•ß>ŞÁEĐă^V6b¤mDĘ0g/Š@Gň¨×`IŰöAéşL©„ZRĐö­Úľqó8ÓúĹ  Ë3Ó6‚¶(úáîÓŐ…8×ů˝ÓV¶ t]¦čP‹ů!¤·—™6ż=?=‰˘açŁ\g+G*:b;öGGĚĽ8:t.Îućyż2…•?ůG‹Ž"iŤ?…üµ ‚ÓŠz¶ç¸? jžhdš•Dݨ˘Ą2‰úڰ˛ĄŁŕW1„hQŤ˝(ÇqŇAĺ±ýŽzH% „ŃČLşĹ˝Ô{[Ŕ>G6č\‡4:âM‡9Żqt"•sf^XŮĚt˘#BŇ|ůŮ&ů´Klű ´í8(:âMGŃo:[¶H'TśŇ†ÉŹŤăŘó ’:š§˛ŚLfhĆ5:ŁîăŢ5m;#n…ŕMGŮÇą6h”¶ם @H“F¦y.Óúaîłĺfʰ4ŹĂÖlęIPÚv\wBtDH“/MÝ÷EGly©jF¦Ňlë7W3ŇŃŃ‘"G)µpŚ'«x/îsňé ľüĹs$oŞÖząRj Đ˝6k` Žă*06áQAxĎ9®aÇ™rDłaXúĺÇ58S=*—sRÄ_Č3)čH˝G¸·Y®Í„v4t‰s.ę»’OŠŽ@Ă ŃśVČž ’+-É”ŽÇYŐ-)2Î2Ž˙™ĘCňŮ‚ Nˇ»{ŽG j$EcÓĎqM<ÂrO:yqÎÇ%Ş1ť©Ľ¨ďá ičřkI6N^śóqIEGlůq Ő(ď tâŰ$éčHP~ŘąTIĹnH×&‰¤˘%Ĺ‹RjŕO–^HéYůü˘”:řŔ“µ (ŐZWç©HB–±Tˇ·¤y>ę5Ů ĘÇ•ŞAjżX„_h$ÄÔŃ‘8/ ¶I YG }-QJťLńd˝§µ>.•gĺµUkýˇRę ęs휼žżR Ů$L°"F9mçD?ŽH†U™Ü”ź#˘/ÁßčH„EG!®Ž@tÎO2©#qź—ńgŽf÷ŢçS}Pľ»ř‚ÓÍ÷:ĎńůÚhIÁMÜš©"dč9©˝\Ä^ŇFtDtDŇ%Ęw”e- µÝ{O7˛S yîâ  ”:žä\+€ŽZë-y*’P¤¤Đ•'%DÔˇxɕހh‰ +˘#B±ˇ”ş¸×“ő­uŻTź—÷T­ő»J©ŹµY­_÷äŻTB1""-BşŽ‚.˘#B1QpąÂČ~(ťg6 ż$'ÜoŹÍetIAAAÍ  ‹çř`r:,őIŔŰĄ÷Pś+‚ ‚ ‚ &WÇŹk­ËÓy`A8¨Zë ŕ1#Űl*AAA ĄÔˇ$Oޤ‰é>· ÔZ&‘ä<­őěLľ  T­ő§Ŕd#űŻJ©ÝňQAAA„ĆŚRęL`‘mĎL›‚tPkTyŽĆńŘAAA„ˇ”jL2˛˙©µ^éw¬Şµ^ Üjd˙F)Ő?ĹAAAh¬Ü ”zŽ®ÎĆ‹TÇłfĄTS`ĐÇ“ýż@O­u•ý.AAA!(Ą/Ů—j­ÎĆű ¶@k] \ ěôdwĹ™ÚXAAAČJ©=€ŤěWłĺśB;¨Z돨żĚ̵J©óQAAA„FÂ߀ý=ÇĺŔŻłů‚wPkąřÄsÜxV)Ő1OĺAAA(Z”RWŮ7h­Weő˝…<Ő‹Ręŕß@sOöŕ$­őöü”JAAˇ¸PJýxťdßkp˛Î˛ŮPZPŃZż\kdÜź‡â‚ ‚ ‚ µ˝Tź#Ů9ý™mç  µľxÜČ­”ş,ĺAAA(”R-€ç}<Ů;źk­×ĺ˘ ĘA­ĺr`‘‘÷WYUAA!-ţŽÓKŐ˵Zë·rU€3Ő‹RŞ3°ŘŰ“˝ µţ ?ĄAAAh(Ąî®6˛'k­Gĺ´ ŃAPJť ĚĹ™Ń×ĺ[ś»ĺ§T‚ ‚ ‚  ĄÔŕz#{đc­uU.ËŇ»ř µţp)ŕő°ŰŻ*Ąşç§T‚ ‚ ‚  ĄÔ­ÔwN?ĘríśBvP´Ö˙řŤ‘˝7đšRŞkŠ$‚ ‚ ‚Đ PJ]ÜbdŻĹ:™“I‘L´  µž\gd—Ż+ĄŽĚC‘AAA ĄÔ Ŕ#{=pŠÖzUîKäĐŕT­ő_€ßŮ+ĄĺˇH‚ ‚ ‚ ‡RŞąRęŕOĆ©Ť8-§+óP¬Eá h­˙ÜndH”›‡" ‚ ‚ ‚  J©vŔËŔ%Ć©ÍŔ@­ő˛Ü—*™˘qP´ÖăńFvS`˘Rę>ĄTSËm‚ ‚ ‚ EŤRęŕŕăÔ:ś–ÓŹs_Şú4Řef‚PJť<”§^.ÔZoÎ}©AAArŹRjđ °—qęC`hľ&D˛QT-¨.Zë©8‘oŚSŹ•R§çľT‚ ‚ ‚ ąC)ŐJ)u0—úÎé ŕÄBrNˇHT­ő|ŕx`©qj_ŕ%ĄÔß•R»ĺľd‚ ‚ ‚ ŮE)Őř¸ PĆé{€3µÖŰr^°ŠÖAĐZô^±śľ řŹRŞnK%‚ ‚ ‚”RÍ”R·ŕŚ7=Ě8˝¸\k}­Öş&÷Ą §¨T­őŕtśČAĄqúŕMĄÔJ©}r^8AAA„ ˇ”,nš§}µÖćş\q(ĘI’üPJu&ÇYN—˙¸»›şAAAl(ĄzNłś®&ĐZďĚiÁR Q9¨µKÍÜÜ4·\˛ˇöÜ˙ŐZWç˛l‚ ‚ ‚ QQJun.ŔŢ;öqV1YÓ‚ĄAŁsP]”R˝€p&R˛± ¸xRk]žł‚ ‚ ‚ ‚  ”ęŚ.ZZ.Ůü ݵ®ČaŃҦŃ:¨.J©ł?‡ú\˛xx@kýIÎ &‚ ‚ ‚P‹RŞp6Žcę7Ń«ĆYďôwµĆ68˝  ”jŽ3«ďx`ď€Kßfi­żÍEŮAAAhĽÔöü<¸„`_ĺ_Ŕk­ć¤`YBTJ©6ŔăĚř»GŔĄŐ8Ó6żă¬JËŞ ‚ ‚ iŁ”j †gCnůp“ÖúĄl—-jA)µ;Î@ă±@Ź·¬^Ć™şůŕ“ÚĺmAAA¬(Ąp0pdíÖ8ű¸R/;çIZë·˛ZČ#jJ©qŐŘgýőcµÎ*đ°řřŢłýäą‚ ‚ ‚ ¤E °§eŰ 8Ç!=hă™_Źh­żĘhi qP#˘”Ú ~Lý…oAAA2Í7ŔKŔ 8Ă ‹z)LqPS@)µ'0§_řé@‡ü–HAA„"b10 gΛ÷´ÖŤ¦×Ą8¨i˘”jôÁi˘wűŹ·ĎgąAAA(xj€Ď©ř)đ–Öz]^K•GÄAÍJ©}qŐî8ÓA»}ÎŰzöm€&ů*Ł ‚ ‚ Yc;usĎl1Ň«qŇĄZëĘĽ•°ů˙ŻČ´±Ď@™yIEND®B`‚nipype-0.11.0/doc/images/nipype_architecture_overview2.svg000066400000000000000000003472351257611314500237310ustar00rootroot00000000000000 image/svg+xml (Command-line programs) (Matlab functions) (Command-line programs) SPM Interface Uniform Python API FSL Interface FreeSurfer Interface Interfaces Idiosynchratic, Heterogeneous APIs SPM FSL FreeSurfer Workflow Engine Workflow - inputs/outputs setting- graph transformations (e.g., iterable expansion) .run() Workflow (Map)Node Interface MultiProc Linear S/OGE IPython Torque SSH Execution Plugins nipype-0.11.0/doc/index.rst000066400000000000000000000041121257611314500155060ustar00rootroot00000000000000.. list-table:: * - .. image:: images/nipype_architecture_overview2.png :width: 100 % - .. container:: Current neuroimaging software offer users an incredible opportunity to analyze data using a variety of different algorithms. However, this has resulted in a heterogeneous collection of specialized applications without transparent interoperability or a uniform operating interface. *Nipype*, an open-source, community-developed initiative under the umbrella of NiPy_, is a Python project that provides a uniform interface to existing neuroimaging software and facilitates interaction between these packages within a single workflow. Nipype provides an environment that encourages interactive exploration of algorithms from different packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, Slicer_), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is creating a collaborative platform for neuroimaging software development in a high-level language and addressing limitations of existing pipeline systems. *Nipype* allows you to: * easily interact with tools from different software packages * combine processing steps from different software packages * develop new workflows faster by reusing common steps from old ones * process data faster by running it in parallel on many cores/machines * make your research easily reproducible * share your processing workflows with the community .. admonition:: Reference Gorgolewski K, Burns CD, Madison C, Clark D, Halchenko YO, Waskom ML, Ghosh SS. (2011). Nipype: a flexible, lightweight and extensible neuroimaging data processing framework in Python. Front. Neuroinform. 5:13. `Download`__ __ paper_ .. tip:: To get started, click Quickstart above. The Links box on the right is available on any page of this website. .. include:: links_names.txt nipype-0.11.0/doc/interfaces/000077500000000000000000000000001257611314500157725ustar00rootroot00000000000000nipype-0.11.0/doc/interfaces/.gitignore000066400000000000000000000000131257611314500177540ustar00rootroot00000000000000/generated nipype-0.11.0/doc/interfaces/index.rst000066400000000000000000000002501257611314500176300ustar00rootroot00000000000000.. _interface-index: ######################### Interfaces and Algorithms ######################### :Release: |version| :Date: |today| .. include:: generated/gen.rst nipype-0.11.0/doc/links_names.txt000066400000000000000000000120421257611314500167120ustar00rootroot00000000000000.. This (-*- rst -*-) format file contains commonly used link targets and name substitutions. It may be included in many files, therefore it should only contain link targets and name substitutions. Try grepping for "^\.\. _" to find plausible candidates for this list. .. NOTE: reST targets are __not_case_sensitive__, so only one target definition is needed for nipy, NIPY, Nipy, etc... .. _nipy: http://nipy.org .. _`NIPY developer resources`: http://nipy.org/devel .. _`Brain Imaging Center`: http://bic.berkeley.edu/ .. _nitime: http://nipy.org/nitime/ .. _nibabel: http://nipy.org/nibabel/ .. _nipype: http://nipy.org/nipype/ .. _ConnectomeViewer: http://www.connectomeviewer.org/viewer/ .. _NeuroDebian: http://neuro.debian.net/ .. Documentation tools .. _graphviz: http://www.graphviz.org/ .. _Sphinx: http://sphinx.pocoo.org/ .. _`Sphinx reST`: http://sphinx.pocoo.org/rest.html .. _reST: http://docutils.sourceforge.net/rst.html .. _docutils: http://docutils.sourceforge.net .. Licenses .. _GPL: http://www.gnu.org/licenses/gpl.html .. _BSD: http://www.opensource.org/licenses/bsd-license.php .. _LGPL: http://www.gnu.org/copyleft/lesser.html .. Working process .. _pynifti: http://niftilib.sourceforge.net/pynifti/ .. _nifticlibs: http://nifti.nimh.nih.gov .. _nifti: http://nifti.nimh.nih.gov .. _`nipy sourceforge`: http://nipy.sourceforge.net/ .. _sourceforge: http://nipy.sourceforge.net/ .. _`nipy launchpad`: https://launchpad.net/nipy .. _launchpad: https://launchpad.net/ .. _`nipy trunk`: https://code.launchpad.net/~nipy-developers/nipy/trunk .. _`nipy mailing list`: http://projects.scipy.org/mailman/listinfo/nipy-devel .. _`nipy bugs`: https://bugs.launchpad.net/nipy .. Code support stuff .. _pychecker: http://pychecker.sourceforge.net/ .. _pylint: http://www.logilab.org/project/pylint .. _pyflakes: http://divmod.org/trac/wiki/DivmodPyflakes .. _virtualenv: http://pypi.python.org/pypi/virtualenv .. _git: http://git.or.cz/ .. _flymake: http://flymake.sourceforge.net/ .. _rope: http://rope.sourceforge.net/ .. _pymacs: http://pymacs.progiciels-bpi.ca/pymacs.html .. _ropemacs: http://rope.sourceforge.net/ropemacs.html .. _ECB: http://ecb.sourceforge.net/ .. _emacs_python_mode: http://www.emacswiki.org/cgi-bin/wiki/PythonMode .. _doctest-mode: http://www.cis.upenn.edu/~edloper/projects/doctestmode/ .. _bazaar: http://bazaar-vcs.org/ .. _subversion: http://subversion.tigris.org/ .. _nose: http://somethingaboutorange.com/mrl/projects/nose .. _`python coverage tester`: http://nedbatchelder.com/code/modules/coverage.html .. Other python projects .. _numpy: http://www.scipy.org/NumPy .. _scipy: http://www.scipy.org .. _ipython: http://ipython.scipy.org .. _`ipython manual`: http://ipython.scipy.org/doc/manual/html .. _matplotlib: http://matplotlib.sourceforge.net .. _ETS: http://code.enthought.com/projects/tool-suite.php .. _`Enthought Tool Suite`: http://code.enthought.com/projects/tool-suite.php .. _python: http://www.python.org .. _mayavi: http://mayavi.sourceforge.net/ .. _sympy: http://code.google.com/p/sympy/ .. _networkx: http://networkx.lanl.gov/ .. _pythonxy: http://www.pythonxy.com/ .. _EPD: http://www.enthought.com/products/epd.php .. _Traits: http://code.enthought.com/projects/traits/ .. _Anaconda: https://store.continuum.io/cshop/anaconda/ .. _Canopy: https://www.enthought.com/products/canopy/ .. Python imaging projects .. _PyMVPA: http://www.pymvpa.org .. _BrainVISA: http://brainvisa.info .. _anatomist: http://brainvisa.info .. Not so python imaging projects .. _matlab: http://www.mathworks.com .. _spm: http://www.fil.ion.ucl.ac.uk/spm .. _eeglab: http://sccn.ucsd.edu/eeglab .. _ANTS: http://stnava.github.io/ANTs/ .. _AFNI: http://afni.nimh.nih.gov/afni .. _FSL: http://www.fmrib.ox.ac.uk/fsl .. _FreeSurfer: http://surfer.nmr.mgh.harvard.edu .. _voxbo: http://www.voxbo.org .. _Slicer: http://slicer.org .. _Camino: http://web4.cs.ucl.ac.uk/research/medic/camino/pmwiki/pmwiki.php .. _Camino2Trackvis: http://camino-trackvis.sourceforge.net/ .. _MRtrix: http://www.brain.org.au/software/mrtrix/index.html .. _MNE: https://martinos.org/mne/index.html .. General software .. _gcc: http://gcc.gnu.org .. _xcode: http://developer.apple.com/TOOLS/xcode .. _mingw: http://www.mingw.org .. _macports: http://www.macports.org/ .. _Vagrant: http://www.vagrantup.com/ .. _Docker: http://www.docker.io/ .. _Virtualbox: https://www.virtualbox.org/ .. Functional imaging labs .. _`functional imaging laboratory`: http://www.fil.ion.ucl.ac.uk .. _FMRIB: http://www.fmrib.ox.ac.uk .. Other organizations .. _enthought: http://www.enthought.com .. _kitware: http://www.kitware.com .. General information links .. _`wikipedia FMRI`: http://en.wikipedia.org/wiki/Functional_magnetic_resonance_imaging .. _`wikipedia PET`: http://en.wikipedia.org/wiki/Positron_emission_tomography .. Mathematical methods .. _`wikipedia ICA`: http://en.wikipedia.org/wiki/Independent_component_analysis .. _`wikipedia PCA`: http://en.wikipedia.org/wiki/Principal_component_analysis .. Nipype Paper .. _paper: http://www.frontiersin.org/Neuroinformatics/10.3389/fninf.2011.00013/abstract nipype-0.11.0/doc/make.bat000066400000000000000000000056171257611314500152650ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation set SPHINXBUILD=sphinx-build set ALLSPHINXOPTS=-d _build/doctrees %SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (_build\*) do rmdir /q /s %%i del /q /s _build\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% _build/html echo. echo.Build finished. The HTML pages are in _build/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% _build/dirhtml echo. echo.Build finished. The HTML pages are in _build/dirhtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% _build/pickle echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% _build/json echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% _build/htmlhelp echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in _build/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% _build/qthelp echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in _build/qthelp, like this: echo.^> qcollectiongenerator _build\qthelp\nipype.qhcp echo.To view the help file: echo.^> assistant -collectionFile _build\qthelp\nipype.ghc goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% _build/latex echo. echo.Build finished; the LaTeX files are in _build/latex. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% _build/changes echo. echo.The overview file is in _build/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% _build/linkcheck echo. echo.Link check complete; look for any errors in the above output ^ or in _build/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% _build/doctest echo. echo.Testing of doctests in the sources finished, look at the ^ results in _build/doctest/output.txt. goto end ) :end nipype-0.11.0/doc/quickstart.rst000066400000000000000000000023261257611314500165760ustar00rootroot00000000000000.. _quickstart: ========== Quickstart ========== Downloading and installing ========================== .. toctree:: :maxdepth: 1 users/install users/vagrant Beginner's guide ================ Beginner's tutorials (IPython Notebooks). `Available here`__ Michael Notter's Nipype guide. `Available here`__ Dissecting Nipype Workflows. `Available here`__ Introductory slides [older]. `Available here`__ __ https://github.com/mwaskom/nipype_concepts __ http://miykael.github.com/nipype-beginner-s-guide/index.html __ http://slideviewer.herokuapp.com/url/raw.github.com/nipy/nipype/master/examples/nipype_tutorial.ipynb?theme=sky __ http://satra.github.com/intro2nipype User guides =========== .. toctree:: :maxdepth: 1 users/interface_tutorial users/pipeline_tutorial users/plugins users/debug Developer guides ================ .. toctree:: :maxdepth: 1 devel/writing_custom_interfaces devel/gitwash/index .. include:: links_names.txt Useful links for beginners =========================== Getting started with Python - Tutorials. `Available here`__ Python for Beginners `Available here`__ __ http://www.codecademy.com/en/tracks/python __ https://www.python.org/about/gettingstarted/ nipype-0.11.0/doc/searchresults.rst000066400000000000000000000125201257611314500172700ustar00rootroot00000000000000.. This displays the search results from the Google Custom Search engine. Don't link to it directly. Search results ============== .. raw:: html

Loading
nipype-0.11.0/doc/sphinxext/000077500000000000000000000000001257611314500157015ustar00rootroot00000000000000nipype-0.11.0/doc/sphinxext/README.txt000066400000000000000000000007551257611314500174060ustar00rootroot00000000000000=================== Sphinx Extensions =================== We've copied these sphinx extensions over from nipy-core. Any edits should be done upstream in nipy-core, not here in nipype! These a are a few sphinx extensions we are using to build the nipy documentation. In this file we list where they each come from, since we intend to always push back upstream any modifications or improvements we make to them. * From numpy: * numpy_ext * From ipython * ipython_console_highlighting nipype-0.11.0/doc/sphinxext/autosummary_generate.py000077500000000000000000000166231257611314500225260ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: r""" autosummary_generate.py OPTIONS FILES Generate automatic RST source files for items referred to in autosummary:: directives. Each generated RST file contains a single auto*:: directive which extracts the docstring of the referred item. Example Makefile rule:: generate: ./ext/autosummary_generate.py -o source/generated source/*.rst """ import glob, re, inspect, os, optparse, pydoc from autosummary import import_by_name try: from phantom_import import import_phantom_module except ImportError: import_phantom_module = lambda x: x def main(): p = optparse.OptionParser(__doc__.strip()) p.add_option("-p", "--phantom", action="store", type="string", dest="phantom", default=None, help="Phantom import modules from a file") p.add_option("-o", "--output-dir", action="store", type="string", dest="output_dir", default=None, help=("Write all output files to the given directory (instead " "of writing them as specified in the autosummary:: " "directives)")) options, args = p.parse_args() if len(args) == 0: p.error("wrong number of arguments") if options.phantom and os.path.isfile(options.phantom): import_phantom_module(options.phantom) # read names = {} for name, loc in get_documented(args).items(): for (filename, sec_title, keyword, toctree) in loc: if toctree is not None: path = os.path.join(os.path.dirname(filename), toctree) names[name] = os.path.abspath(path) # write for name, path in sorted(names.items()): if options.output_dir is not None: path = options.output_dir if not os.path.isdir(path): os.makedirs(path) try: obj, name = import_by_name(name) except ImportError, e: print "Failed to import '%s': %s" % (name, e) continue fn = os.path.join(path, '%s.rst' % name) if os.path.exists(fn): # skip continue f = open(fn, 'w') try: f.write('%s\n%s\n\n' % (name, '='*len(name))) if inspect.isclass(obj): if issubclass(obj, Exception): f.write(format_modulemember(name, 'autoexception')) else: f.write(format_modulemember(name, 'autoclass')) elif inspect.ismodule(obj): f.write(format_modulemember(name, 'automodule')) elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj): f.write(format_classmember(name, 'automethod')) elif callable(obj): f.write(format_modulemember(name, 'autofunction')) elif hasattr(obj, '__get__'): f.write(format_classmember(name, 'autoattribute')) else: f.write(format_modulemember(name, 'autofunction')) finally: f.close() def format_modulemember(name, directive): parts = name.split('.') mod, name = '.'.join(parts[:-1]), parts[-1] return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name) def format_classmember(name, directive): parts = name.split('.') mod, name = '.'.join(parts[:-2]), '.'.join(parts[-2:]) return ".. currentmodule:: %s\n\n.. %s:: %s\n" % (mod, directive, name) def get_documented(filenames): """ Find out what items are documented in source/*.rst See `get_documented_in_lines`. """ documented = {} for filename in filenames: f = open(filename, 'r') lines = f.read().splitlines() documented.update(get_documented_in_lines(lines, filename=filename)) f.close() return documented def get_documented_in_docstring(name, module=None, filename=None): """ Find out what items are documented in the given object's docstring. See `get_documented_in_lines`. """ try: obj, real_name = import_by_name(name) lines = pydoc.getdoc(obj).splitlines() return get_documented_in_lines(lines, module=name, filename=filename) except AttributeError: pass except ImportError, e: print "Failed to import '%s': %s" % (name, e) return {} def get_documented_in_lines(lines, module=None, filename=None): """ Find out what items are documented in the given lines Returns ------- documented : dict of list of (filename, title, keyword, toctree) Dictionary whose keys are documented names of objects. The value is a list of locations where the object was documented. Each location is a tuple of filename, the current section title, the name of the directive, and the value of the :toctree: argument (if present) of the directive. """ title_underline_re = re.compile("^[-=*_^#]{3,}\s*$") autodoc_re = re.compile(".. auto(function|method|attribute|class|exception|module)::\s*([A-Za-z0-9_.]+)\s*$") autosummary_re = re.compile(r'^\.\.\s+autosummary::\s*') module_re = re.compile(r'^\.\.\s+(current)?module::\s*([a-zA-Z0-9_.]+)\s*$') autosummary_item_re = re.compile(r'^\s+([_a-zA-Z][a-zA-Z0-9_.]*)\s*.*?') toctree_arg_re = re.compile(r'^\s+:toctree:\s*(.*?)\s*$') documented = {} current_title = [] last_line = None toctree = None current_module = module in_autosummary = False for line in lines: try: if in_autosummary: m = toctree_arg_re.match(line) if m: toctree = m.group(1) continue if line.strip().startswith(':'): continue # skip options m = autosummary_item_re.match(line) if m: name = m.group(1).strip() if current_module and not name.startswith(current_module + '.'): name = "%s.%s" % (current_module, name) documented.setdefault(name, []).append( (filename, current_title, 'autosummary', toctree)) continue if line.strip() == '': continue in_autosummary = False m = autosummary_re.match(line) if m: in_autosummary = True continue m = autodoc_re.search(line) if m: name = m.group(2).strip() if m.group(1) == "module": current_module = name documented.update(get_documented_in_docstring( name, filename=filename)) elif current_module and not name.startswith(current_module+'.'): name = "%s.%s" % (current_module, name) documented.setdefault(name, []).append( (filename, current_title, "auto" + m.group(1), None)) continue m = title_underline_re.match(line) if m and last_line: current_title = last_line.strip() continue m = module_re.match(line) if m: current_module = m.group(2) continue finally: last_line = line return documented if __name__ == "__main__": main() nipype-0.11.0/doc/sphinxext/ipython_console_highlighting.py000066400000000000000000000067321257611314500242240ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """reST directive for syntax-highlighting ipython interactive sessions. """ #----------------------------------------------------------------------------- # Needed modules # Standard library import re # Third party from pygments.lexer import Lexer, do_insertions from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer, PythonTracebackLexer) from pygments.token import Comment, Generic from sphinx import highlighting #----------------------------------------------------------------------------- # Global constants line_re = re.compile('.*?\n') #----------------------------------------------------------------------------- # Code begins - classes and functions class IPythonConsoleLexer(Lexer): """ For IPython console output or doctests, such as: .. sourcecode:: ipython In [1]: a = 'foo' In [2]: a Out[2]: 'foo' In [3]: print a foo In [4]: 1 / 0 Notes: - Tracebacks are not currently supported. - It assumes the default IPython prompts, not customized ones. """ name = 'IPython console session' aliases = ['ipython'] mimetypes = ['text/x-ipython-console'] input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)") output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)") continue_prompt = re.compile(" \.\.\.+:") tb_start = re.compile("\-+") def get_tokens_unprocessed(self, text): pylexer = PythonLexer(**self.options) tblexer = PythonTracebackLexer(**self.options) curcode = '' insertions = [] for match in line_re.finditer(text): line = match.group() input_prompt = self.input_prompt.match(line) continue_prompt = self.continue_prompt.match(line.rstrip()) output_prompt = self.output_prompt.match(line) if line.startswith("#"): insertions.append((len(curcode), [(0, Comment, line)])) elif input_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, input_prompt.group())])) curcode += line[input_prompt.end():] elif continue_prompt is not None: insertions.append((len(curcode), [(0, Generic.Prompt, continue_prompt.group())])) curcode += line[continue_prompt.end():] elif output_prompt is not None: insertions.append((len(curcode), [(0, Generic.Output, output_prompt.group())])) curcode += line[output_prompt.end():] else: if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item curcode = '' insertions = [] yield match.start(), Generic.Output, line if curcode: for item in do_insertions(insertions, pylexer.get_tokens_unprocessed(curcode)): yield item #----------------------------------------------------------------------------- # Register the extension as a valid pygments lexer highlighting.lexers['ipython'] = IPythonConsoleLexer() nipype-0.11.0/doc/sphinxext/numpy_ext/000077500000000000000000000000001257611314500177315ustar00rootroot00000000000000nipype-0.11.0/doc/sphinxext/numpy_ext/__init__.py000066400000000000000000000000001257611314500220300ustar00rootroot00000000000000nipype-0.11.0/doc/sphinxext/numpy_ext/docscrape.py000066400000000000000000000361011257611314500222470ustar00rootroot00000000000000"""Extract reference documentation from the NumPy source tree. """ import inspect import textwrap import re import pydoc from StringIO import StringIO from warnings import warn class Reader(object): """A line-based string reader. """ def __init__(self, data): """ Parameters ---------- data : str String with lines separated by '\n'. """ if isinstance(data,list): self._str = data else: self._str = data.split('\n') # store string as list of lines self.reset() def __getitem__(self, n): return self._str[n] def reset(self): self._l = 0 # current line nr def read(self): if not self.eof(): out = self[self._l] self._l += 1 return out else: return '' def seek_next_non_empty_line(self): for l in self[self._l:]: if l.strip(): break else: self._l += 1 def eof(self): return self._l >= len(self._str) def read_to_condition(self, condition_func): start = self._l for line in self[start:]: if condition_func(line): return self[start:self._l] self._l += 1 if self.eof(): return self[start:self._l+1] return [] def read_to_next_empty_line(self): self.seek_next_non_empty_line() def is_empty(line): return not line.strip() return self.read_to_condition(is_empty) def read_to_next_unindented_line(self): def is_unindented(line): return (line.strip() and (len(line.lstrip()) == len(line))) return self.read_to_condition(is_unindented) def peek(self,n=0): if self._l + n < len(self._str): return self[self._l + n] else: return '' def is_empty(self): return not ''.join(self._str).strip() class NumpyDocString(object): def __init__(self, docstring, config={}): docstring = textwrap.dedent(docstring).split('\n') self._doc = Reader(docstring) self._parsed_data = { 'Signature': '', 'Summary': [''], 'Extended Summary': [], 'Parameters': [], 'Returns': [], 'Raises': [], 'Warns': [], 'Other Parameters': [], 'Attributes': [], 'Methods': [], 'See Also': [], 'Notes': [], 'Warnings': [], 'References': '', 'Examples': '', 'index': {} } self._parse() def __getitem__(self,key): return self._parsed_data[key] def __setitem__(self,key,val): if not self._parsed_data.has_key(key): warn("Unknown section %s" % key) else: self._parsed_data[key] = val def _is_at_section(self): self._doc.seek_next_non_empty_line() if self._doc.eof(): return False l1 = self._doc.peek().strip() # e.g. Parameters if l1.startswith('.. index::'): return True l2 = self._doc.peek(1).strip() # ---------- or ========== return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1)) def _strip(self,doc): i = 0 j = 0 for i,line in enumerate(doc): if line.strip(): break for j,line in enumerate(doc[::-1]): if line.strip(): break return doc[i:len(doc)-j] def _read_to_next_section(self): section = self._doc.read_to_next_empty_line() while not self._is_at_section() and not self._doc.eof(): if not self._doc.peek(-1).strip(): # previous line was empty section += [''] section += self._doc.read_to_next_empty_line() return section def _read_sections(self): while not self._doc.eof(): data = self._read_to_next_section() name = data[0].strip() if name.startswith('..'): # index section yield name, data[1:] elif len(data) < 2: yield StopIteration else: yield name, self._strip(data[2:]) def _parse_param_list(self,content): r = Reader(content) params = [] while not r.eof(): header = r.read().strip() if ' : ' in header: arg_name, arg_type = header.split(' : ')[:2] else: arg_name, arg_type = header, '' desc = r.read_to_next_unindented_line() desc = dedent_lines(desc) params.append((arg_name,arg_type,desc)) return params _name_rgx = re.compile(r"^\s*(:(?P\w+):`(?P[a-zA-Z0-9_.-]+)`|" r" (?P[a-zA-Z0-9_.-]+))\s*", re.X) def _parse_see_also(self, content): """ func_name : Descriptive text continued text another_func_name : Descriptive text func_name1, func_name2, :meth:`func_name`, func_name3 """ items = [] def parse_item_name(text): """Match ':role:`name`' or 'name'""" m = self._name_rgx.match(text) if m: g = m.groups() if g[1] is None: return g[3], None else: return g[2], g[1] raise ValueError("%s is not a item name" % text) def push_item(name, rest): if not name: return name, role = parse_item_name(name) items.append((name, list(rest), role)) del rest[:] current_func = None rest = [] for line in content: if not line.strip(): continue m = self._name_rgx.match(line) if m and line[m.end():].strip().startswith(':'): push_item(current_func, rest) current_func, line = line[:m.end()], line[m.end():] rest = [line.split(':', 1)[1].strip()] if not rest[0]: rest = [] elif not line.startswith(' '): push_item(current_func, rest) current_func = None if ',' in line: for func in line.split(','): if func.strip(): push_item(func, []) elif line.strip(): current_func = line elif current_func is not None: rest.append(line.strip()) push_item(current_func, rest) return items def _parse_index(self, section, content): """ .. index: default :refguide: something, else, and more """ def strip_each_in(lst): return [s.strip() for s in lst] out = {} section = section.split('::') if len(section) > 1: out['default'] = strip_each_in(section[1].split(','))[0] for line in content: line = line.split(':') if len(line) > 2: out[line[1]] = strip_each_in(line[2].split(',')) return out def _parse_summary(self): """Grab signature (if given) and summary""" if self._is_at_section(): return summary = self._doc.read_to_next_empty_line() summary_str = " ".join([s.strip() for s in summary]).strip() if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str): self['Signature'] = summary_str if not self._is_at_section(): self['Summary'] = self._doc.read_to_next_empty_line() else: self['Summary'] = summary if not self._is_at_section(): self['Extended Summary'] = self._read_to_next_section() def _parse(self): self._doc.reset() self._parse_summary() for (section,content) in self._read_sections(): if not section.startswith('..'): section = ' '.join([s.capitalize() for s in section.split(' ')]) if section in ('Parameters', 'Returns', 'Raises', 'Warns', 'Other Parameters', 'Attributes', 'Methods'): self[section] = self._parse_param_list(content) elif section.startswith('.. index::'): self['index'] = self._parse_index(section, content) elif section == 'See Also': self['See Also'] = self._parse_see_also(content) else: self[section] = content # string conversion routines def _str_header(self, name, symbol='-'): return [name, len(name)*symbol] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): if self['Signature']: return [self['Signature'].replace('*','\*')] + [''] else: return [''] def _str_summary(self): if self['Summary']: return self['Summary'] + [''] else: return [] def _str_extended_summary(self): if self['Extended Summary']: return self['Extended Summary'] + [''] else: return [] def _str_param_list(self, name): out = [] if self[name]: out += self._str_header(name) for param,param_type,desc in self[name]: out += ['%s : %s' % (param, param_type)] out += self._str_indent(desc) out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += self[name] out += [''] return out def _str_see_also(self, func_role): if not self['See Also']: return [] out = [] out += self._str_header("See Also") last_had_desc = True for func, desc, role in self['See Also']: if role: link = ':%s:`%s`' % (role, func) elif func_role: link = ':%s:`%s`' % (func_role, func) else: link = "`%s`_" % func if desc or last_had_desc: out += [''] out += [link] else: out[-1] += ", %s" % link if desc: out += self._str_indent([' '.join(desc)]) last_had_desc = True else: last_had_desc = False out += [''] return out def _str_index(self): idx = self['index'] out = [] out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.iteritems(): if section == 'default': continue out += [' :%s: %s' % (section, ', '.join(references))] return out def __str__(self, func_role=''): out = [] out += self._str_signature() out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Returns', 'Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_section('Warnings') out += self._str_see_also(func_role) for s in ('Notes','References','Examples'): out += self._str_section(s) for param_list in ('Attributes', 'Methods'): out += self._str_param_list(param_list) out += self._str_index() return '\n'.join(out) def indent(str,indent=4): indent_str = ' '*indent if str is None: return indent_str lines = str.split('\n') return '\n'.join(indent_str + l for l in lines) def dedent_lines(lines): """Deindent a list of lines maximally""" return textwrap.dedent("\n".join(lines)).split("\n") def header(text, style='-'): return text + '\n' + style*len(text) + '\n' class FunctionDoc(NumpyDocString): def __init__(self, func, role='func', doc=None, config={}): self._f = func self._role = role # e.g. "func" or "meth" if doc is None: if func is None: raise ValueError("No function or docstring given") doc = inspect.getdoc(func) or '' NumpyDocString.__init__(self, doc) if not self['Signature'] and func is not None: func, func_name = self.get_func() try: # try to read signature argspec = inspect.getargspec(func) argspec = inspect.formatargspec(*argspec) argspec = argspec.replace('*','\*') signature = '%s%s' % (func_name, argspec) except TypeError, e: signature = '%s()' % func_name self['Signature'] = signature def get_func(self): func_name = getattr(self._f, '__name__', self.__class__.__name__) if inspect.isclass(self._f): func = getattr(self._f, '__call__', self._f.__init__) else: func = self._f return func, func_name def __str__(self): out = '' func, func_name = self.get_func() signature = self['Signature'].replace('*', '\*') roles = {'func': 'function', 'meth': 'method'} if self._role: if not roles.has_key(self._role): print "Warning: invalid role %s" % self._role out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''), func_name) out += super(FunctionDoc, self).__str__(func_role=self._role) return out class ClassDoc(NumpyDocString): extra_public_methods = ['__call__'] def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, config={}): if not inspect.isclass(cls) and cls is not None: raise ValueError("Expected a class or None, but got %r" % cls) self._cls = cls if modulename and not modulename.endswith('.'): modulename += '.' self._mod = modulename if doc is None: if cls is None: raise ValueError("No class or documentation string given") doc = pydoc.getdoc(cls) NumpyDocString.__init__(self, doc) if config.get('show_class_members', True): if not self['Methods']: self['Methods'] = [(name, '', '') for name in sorted(self.methods)] if not self['Attributes']: self['Attributes'] = [(name, '', '') for name in sorted(self.properties)] @property def methods(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if ((not name.startswith('_') or name in self.extra_public_methods) and callable(func))] @property def properties(self): if self._cls is None: return [] return [name for name,func in inspect.getmembers(self._cls) if not name.startswith('_') and func is None] nipype-0.11.0/doc/sphinxext/numpy_ext/docscrape_sphinx.py000066400000000000000000000171741257611314500236510ustar00rootroot00000000000000import re, inspect, textwrap, pydoc import sphinx from docscrape import NumpyDocString, FunctionDoc, ClassDoc from nipype.external import six class SphinxDocString(NumpyDocString): def __init__(self, docstring, config={}): self.use_plots = config.get('use_plots', False) NumpyDocString.__init__(self, docstring, config=config) # string conversion routines def _str_header(self, name, symbol='`'): return ['.. rubric:: ' + name, ''] def _str_field_list(self, name): return [':' + name + ':'] def _str_indent(self, doc, indent=4): out = [] for line in doc: out += [' '*indent + line] return out def _str_signature(self): return [''] if self['Signature']: return ['``%s``' % self['Signature']] + [''] else: return [''] def _str_summary(self): return self['Summary'] + [''] def _str_extended_summary(self): return self['Extended Summary'] + [''] def _str_param_list(self, name): out = [] if self[name]: out += self._str_field_list(name) out += [''] for param,param_type,desc in self[name]: out += self._str_indent(['**%s** : %s' % (param.strip(), param_type)]) out += [''] out += self._str_indent(desc,8) out += [''] return out @property def _obj(self): if hasattr(self, '_cls'): return self._cls elif hasattr(self, '_f'): return self._f return None def _str_member_list(self, name): """ Generate a member listing, autosummary:: table where possible, and a table where not. """ out = [] if self[name]: out += ['.. rubric:: %s' % name, ''] prefix = getattr(self, '_name', '') if prefix: prefix = '~%s.' % prefix autosum = [] others = [] for param, param_type, desc in self[name]: param = param.strip() if not self._obj or hasattr(self._obj, param): autosum += [" %s%s" % (prefix, param)] else: others.append((param, param_type, desc)) if autosum: out += ['.. autosummary::', ' :toctree:', ''] out += autosum if others: maxlen_0 = max([len(x[0]) for x in others]) maxlen_1 = max([len(x[1]) for x in others]) hdr = "="*maxlen_0 + " " + "="*maxlen_1 + " " + "="*10 fmt = '%%%ds %%%ds ' % (maxlen_0, maxlen_1) n_indent = maxlen_0 + maxlen_1 + 4 out += [hdr] for param, param_type, desc in others: out += [fmt % (param.strip(), param_type)] out += self._str_indent(desc, n_indent) out += [hdr] out += [''] return out def _str_section(self, name): out = [] if self[name]: out += self._str_header(name) out += [''] content = textwrap.dedent("\n".join(self[name])).split("\n") out += content out += [''] return out def _str_see_also(self, func_role): out = [] if self['See Also']: see_also = super(SphinxDocString, self)._str_see_also(func_role) out = ['.. seealso::', ''] out += self._str_indent(see_also[2:]) return out def _str_warnings(self): out = [] if self['Warnings']: out = ['.. warning::', ''] out += self._str_indent(self['Warnings']) return out def _str_index(self): idx = self['index'] out = [] if len(idx) == 0: return out out += ['.. index:: %s' % idx.get('default','')] for section, references in idx.iteritems(): if section == 'default': continue elif section == 'refguide': out += [' single: %s' % (', '.join(references))] else: out += [' %s: %s' % (section, ','.join(references))] return out def _str_references(self): out = [] if self['References']: out += self._str_header('References') if isinstance(self['References'], six.string_types): self['References'] = [self['References']] out.extend(self['References']) out += [''] # Latex collects all references to a separate bibliography, # so we need to insert links to it if sphinx.__version__ >= "0.6": out += ['.. only:: latex',''] else: out += ['.. latexonly::',''] items = [] for line in self['References']: m = re.match(r'.. \[([a-z0-9._-]+)\]', line, re.I) if m: items.append(m.group(1)) out += [' ' + ", ".join(["[%s]_" % item for item in items]), ''] return out def _str_examples(self): examples_str = "\n".join(self['Examples']) if (self.use_plots and 'import matplotlib' in examples_str and 'plot::' not in examples_str): out = [] out += self._str_header('Examples') out += ['.. plot::', ''] out += self._str_indent(self['Examples']) out += [''] return out else: return self._str_section('Examples') def __str__(self, indent=0, func_role="obj"): out = [] out += self._str_signature() out += self._str_index() + [''] out += self._str_summary() out += self._str_extended_summary() for param_list in ('Parameters', 'Returns', 'Other Parameters', 'Raises', 'Warns'): out += self._str_param_list(param_list) out += self._str_warnings() out += self._str_see_also(func_role) out += self._str_section('Notes') out += self._str_references() out += self._str_examples() for param_list in ('Attributes', 'Methods'): out += self._str_member_list(param_list) out = self._str_indent(out,indent) return '\n'.join(out) class SphinxFunctionDoc(SphinxDocString, FunctionDoc): def __init__(self, obj, doc=None, config={}): self.use_plots = config.get('use_plots', False) FunctionDoc.__init__(self, obj, doc=doc, config=config) class SphinxClassDoc(SphinxDocString, ClassDoc): def __init__(self, obj, doc=None, func_doc=None, config={}): self.use_plots = config.get('use_plots', False) ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config) class SphinxObjDoc(SphinxDocString): def __init__(self, obj, doc=None, config={}): self._f = obj SphinxDocString.__init__(self, doc, config=config) def get_doc_object(obj, what=None, doc=None, config={}): if what is None: if inspect.isclass(obj): what = 'class' elif inspect.ismodule(obj): what = 'module' elif callable(obj): what = 'function' else: what = 'object' if what == 'class': return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, config=config) elif what in ('function', 'method'): return SphinxFunctionDoc(obj, doc=doc, config=config) else: if doc is None: doc = pydoc.getdoc(obj) return SphinxObjDoc(obj, doc, config=config) nipype-0.11.0/doc/sphinxext/numpy_ext/numpydoc.py000066400000000000000000000130611257611314500221420ustar00rootroot00000000000000""" ======== numpydoc ======== Sphinx extension that handles docstrings in the Numpy standard format. [1] It will: - Convert Parameters etc. sections to field lists. - Convert See Also section to a See also entry. - Renumber references. - Extract the signature from the docstring, if it can't be determined otherwise. .. [1] https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt """ import sphinx if sphinx.__version__ < '1.0.1': raise RuntimeError("Sphinx 1.0.1 or newer is required") import os, re, pydoc from docscrape_sphinx import get_doc_object, SphinxDocString from sphinx.util.compat import Directive import inspect def mangle_docstrings(app, what, name, obj, options, lines, reference_offset=[0]): cfg = dict(use_plots=app.config.numpydoc_use_plots, show_class_members=app.config.numpydoc_show_class_members) if what == 'module': # Strip top title title_re = re.compile(ur'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*', re.I|re.S) lines[:] = title_re.sub(u'', u"\n".join(lines)).split(u"\n") else: doc = get_doc_object(obj, what, u"\n".join(lines), config=cfg) lines[:] = unicode(doc).split(u"\n") if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \ obj.__name__: if hasattr(obj, '__module__'): v = dict(full_name=u"%s.%s" % (obj.__module__, obj.__name__)) else: v = dict(full_name=obj.__name__) lines += [u'', u'.. only:: html', ''] lines += [u' %s' % x for x in (app.config.numpydoc_edit_link % v).split("\n")] # replace reference numbers so that there are no duplicates references = [] for line in lines: line = line.strip() m = re.match(ur'^.. \[([a-z0-9_.-])\]', line, re.I) if m: references.append(m.group(1)) # start renaming from the longest string, to avoid overwriting parts references.sort(key=lambda x: -len(x)) if references: for i, line in enumerate(lines): for r in references: if re.match(ur'^\d+$', r): new_r = u"R%d" % (reference_offset[0] + int(r)) else: new_r = u"%s%d" % (r, reference_offset[0]) lines[i] = lines[i].replace(u'[%s]_' % r, u'[%s]_' % new_r) lines[i] = lines[i].replace(u'.. [%s]' % r, u'.. [%s]' % new_r) reference_offset[0] += len(references) def mangle_signature(app, what, name, obj, options, sig, retann): # Do not try to inspect classes that don't define `__init__` if (inspect.isclass(obj) and (not hasattr(obj, '__init__') or 'initializes x; see ' in pydoc.getdoc(obj.__init__))): return '', '' if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return if not hasattr(obj, '__doc__'): return doc = SphinxDocString(pydoc.getdoc(obj)) if doc['Signature']: sig = re.sub(u"^[^(]*", u"", doc['Signature']) return sig, u'' def setup(app, get_doc_object_=get_doc_object): global get_doc_object get_doc_object = get_doc_object_ app.connect('autodoc-process-docstring', mangle_docstrings) app.connect('autodoc-process-signature', mangle_signature) app.add_config_value('numpydoc_edit_link', None, False) app.add_config_value('numpydoc_use_plots', None, False) app.add_config_value('numpydoc_show_class_members', True, True) # Extra mangling domains app.add_domain(NumpyPythonDomain) app.add_domain(NumpyCDomain) #------------------------------------------------------------------------------ # Docstring-mangling domains #------------------------------------------------------------------------------ from docutils.statemachine import ViewList from sphinx.domains.c import CDomain from sphinx.domains.python import PythonDomain class ManglingDomainBase(object): directive_mangling_map = {} def __init__(self, *a, **kw): super(ManglingDomainBase, self).__init__(*a, **kw) self.wrap_mangling_directives() def wrap_mangling_directives(self): for name, objtype in self.directive_mangling_map.items(): self.directives[name] = wrap_mangling_directive( self.directives[name], objtype) class NumpyPythonDomain(ManglingDomainBase, PythonDomain): name = 'np' directive_mangling_map = { 'function': 'function', 'class': 'class', 'exception': 'class', 'method': 'function', 'classmethod': 'function', 'staticmethod': 'function', 'attribute': 'attribute', } class NumpyCDomain(ManglingDomainBase, CDomain): name = 'np-c' directive_mangling_map = { 'function': 'function', 'member': 'attribute', 'macro': 'function', 'type': 'class', 'var': 'object', } def wrap_mangling_directive(base_directive, objtype): class directive(base_directive): def run(self): env = self.state.document.settings.env name = None if self.arguments: m = re.match(r'^(.*\s+)?(.*?)(\(.*)?', self.arguments[0]) name = m.group(2).strip() if not name: name = self.arguments[0] lines = list(self.content) mangle_docstrings(env.app, objtype, name, None, None, lines) self.content = ViewList(lines, self.content.parent) return base_directive.run(self) return directive nipype-0.11.0/doc/users/000077500000000000000000000000001257611314500150105ustar00rootroot00000000000000nipype-0.11.0/doc/users/caching_tutorial.rst000066400000000000000000000153221257611314500210640ustar00rootroot00000000000000 .. _caching: =========================== Interface caching =========================== This section details the interface-caching mechanism, exposed in the :mod:`nipype.caching` module. .. currentmodule:: nipype.caching Interface caching: why and how =============================== * :ref:`Pipelines ` (also called `workflows`) specify processing by an execution graph. This is useful because it opens the door to dependency checking and enable `i)` to minimize recomputations, `ii)` to have the execution engine transparently deal with intermediate file manipulations. They however do not blend in well with arbitrary Python code, as they must rely on their own execution engine. * :ref:`Interfaces ` give fine control of the execution of each step with a thin wrapper on the underlying software. As a result that can easily be inserted in Python code. However, they force the user to specify explicit input and output file names and cannot do any caching. This is why nipype exposes an intermediate mechanism, `caching` that provides transparent output file management and caching within imperative Python code rather than a workflow. A big picture view: using the :class:`Memory` object ======================================================= nipype caching relies on the :class:`Memory` class: it creates an execution context that is bound to a disk cache:: >>> from nipype.caching import Memory >>> mem = Memory(base_dir='.') Note that the caching directory is a subdirectory called `nipype_mem` of the given `base_dir`. This is done to avoid polluting the base director. In the corresponding execution context, nipype interfaces can be turned into callables that can be used as functions using the :meth:`Memory.cache` method. For instance if we want to run the fslMerge command on a set of files:: >>> from nipype.interface import fsl >>> fsl_merge = mem.cache(fsl.Merge) Note that the :meth:`Memory.cache` method takes interfaces **classes**, and not instances. The resulting `fsl_merge` object can be applied as a function to parameters, that will form the inputs of the `merge` fsl commands. Those inputs are given as keyword arguments, bearing the same name as the name in the inputs specs of the interface. In IPython, you can also get the argument list by using the `fsl_merge?` synthax to inspect the docs:: In [10]: fsl_merge? String Form:PipeFunc(nipype.interfaces.fsl.utils.Merge, base_dir=/home/varoquau/dev/nipype/nipype/caching/nipype_mem) Namespace: Interactive File: /home/varoquau/dev/nipype/nipype/caching/memory.py Definition: fsl_merge(self, **kwargs) Docstring: Use fslmerge to concatenate images Inputs ------ Mandatory: dimension: dimension along which the file will be merged in_files: None Optional: args: Additional parameters to the command environ: Environment variables (default={}) ignore_exception: Print an error message instead of throwing an exception in case the interface fails to run (default=False) merged_file: None output_type: FSL output type Outputs ------- merged_file: None Class Docstring: ... Thus `fsl_merge` is applied to parameters as such:: >>> results = fsl_merge(dimension='t', in_files=['a.nii.gz', 'b.nii.gz']) INFO:workflow:Executing node faa7888f5955c961e5c6aa70cbd5c807 in dir: /home/varoquau/dev/nipype/nipype/caching/nipype_mem/nipype-interfaces-fsl-utils-Merge/faa7888f5955c961e5c6aa70cbd5c807 INFO:workflow:Running: fslmerge -t /home/varoquau/dev/nipype/nipype/caching/nipype_mem/nipype-interfaces-fsl-utils-Merge/faa7888f5955c961e5c6aa70cbd5c807/a_merged.nii /home/varoquau/dev/nipype/nipype/caching/a.nii.gz /home/varoquau/dev/nipype/nipype/caching/b.nii.gz The results are standard nipype nodes results. In particular, they expose an `outputs` attribute that carries all the outputs of the process, as specified by the docs. >>> results.outputs.merged_file '/home/varoquau/dev/nipype/nipype/caching/nipype_mem/nipype-interfaces-fsl-utils-Merge/faa7888f5955c961e5c6aa70cbd5c807/a_merged.nii' Finally, and most important, if the node is applied to the same input parameters, it is not computed, and the results are reloaded from the disk:: >>> results = fsl_merge(dimension='t', in_files=['a.nii.gz', 'b.nii.gz']) INFO:workflow:Executing node faa7888f5955c961e5c6aa70cbd5c807 in dir: /home/varoquau/dev/nipype/nipype/caching/nipype_mem/nipype-interfaces-fsl-utils-Merge/faa7888f5955c961e5c6aa70cbd5c807 INFO:workflow:Collecting precomputed outputs Once the :class:`Memory` is set up and you are applying it to data, an important thing to keep in mind is that you are using up disk cache. It might be useful to clean it using the methods that :class:`Memory` provides for this: :meth:`Memory.clear_previous_runs`, :meth:`Memory.clear_runs_since`. .. topic:: Example A full-blown example showing how to stage multiple operations can be found in the :download:`caching_example.py <../../examples/howto_caching_example.py>` file. Usage patterns: working efficiently with caching =================================================== The goal of the `caching` module is to enable writing plain Python code rather than workflows. Use it: instead of data grabber nodes, use for instance the `glob` module. To vary parameters, use `for` loops. To make reusable code, write Python functions. One good rule of thumb to respect is to avoid the usage of explicit filenames apart from the outermost inputs and outputs of your processing. The reason being that the caching mechanism of :mod:`nipy.caching` takes care of generating the unique hashes, ensuring that, when you vary parameters, files are not overridden by the output of different computations. .. topic:: Debuging If you need to inspect the running environment of the nodes, it may be useful to know where they were executed. With `nipype.caching`, you do not control this location as it is encoded by hashes. To find out where an operation has been persisted, simply look in it's output variable:: out.runtime.cwd Finally, the more you explore different parameters, the more you risk creating cached results that will never be reused. Keep in mind that it may be useful to flush the cache using :meth:`Memory.clear_previous_runs` or :meth:`Memory.clear_runs_since`. API reference =============== The main class of the :mod:`nipype.caching` module is the :class:`Memory` class: .. autoclass:: Memory :members: __init__, cache, clear_previous_runs, clear_runs_since ____ Also used are the :class:`PipeFunc`, callables that are returned by the :meth:`Memory.cache` decorator: .. currentmodule:: nipype.caching.memory .. autoclass:: PipeFunc :members: __init__ nipype-0.11.0/doc/users/config_file.rst000066400000000000000000000174661257611314500200240ustar00rootroot00000000000000.. _config_file: ======================= Configuration File ======================= Some of the system wide options of Nipype can be configured using a configuration file. Nipype looks for the file in the local folder under the name ``nipype.cfg`` and in ``~/.nipype/nipype.cfg`` (in this order). If an option will not be specified a default value will be assumed. The file is divided into following sections: Logging ~~~~~~~ *workflow_level* How detailed the logs regarding workflow should be (possible values: ``INFO`` and ``DEBUG``; default value: ``INFO``) *filemanip_level* How detailed the logs regarding file operations (for example overwriting warning) should be (possible values: ``INFO`` and ``DEBUG``; default value: ``INFO``) *interface_level* How detailed the logs regarding interface execution should be (possible values: ``INFO`` and ``DEBUG``; default value: ``INFO``) *log_to_file* Indicates whether logging should also send the output to a file (possible values: ``true`` and ``false``; default value: ``false``) *log_directory* Where to store logs. (string, default value: home directory) *log_size* Size of a single log file. (integer, default value: 254000) *log_rotate* How many rotation should the log file make. (integer, default value: 4) Execution ~~~~~~~~~ *plugin* This defines which execution plugin to use. (possible values: ``Linear``, ``MultiProc``, ``SGE``, ``IPython``; default value: ``Linear``) *stop_on_first_crash* Should the workflow stop upon first node crashing or try to execute as many nodes as possible? (possible values: ``true`` and ``false``; default value: ``false``) *stop_on_first_rerun* Should the workflow stop upon first node trying to recompute (by that we mean rerunning a node that has been run before - this can happen due changed inputs and/or hash_method since the last run). (possible values: ``true`` and ``false``; default value: ``false``) *hash_method* Should the input files be checked for changes using their content (slow, but 100% accurate) or just their size and modification date (fast, but potentially prone to errors)? (possible values: ``content`` and ``timestamp``; default value: ``content``) *keep_inputs* Ensures that all inputs that are created in the nodes working directory are kept after node execution (possible values: ``true`` and ``false``; default value: ``false``) *single_thread_matlab* Should all of the Matlab interfaces (including SPM) use only one thread? This is useful if you are parallelizing your workflow using MultiProc or IPython on a single multicore machine. (possible values: ``true`` and ``false``; default value: ``true``) *display_variable* What ``DISPLAY`` variable should all command line interfaces be run with. This is useful if you are using `xnest `_ or `Xvfb `_ and you would like to redirect all spawned windows to it. (possible values: any X server address; default value: not set) *remove_unnecessary_outputs* This will remove any interface outputs not needed by the workflow. If the required outputs from a node changes, rerunning the workflow will rerun the node. Outputs of leaf nodes (nodes whose outputs are not connected to any other nodes) will never be deleted independent of this parameter. (possible values: ``true`` and ``false``; default value: ``true``) *try_hard_link_datasink* When the DataSink is used to produce an orginized output file outside of nipypes internal cache structure, a file system hard link will be attempted first. A hard link allow multiple file paths to point to the same physical storage location on disk if the condisions allow. By refering to the same physical file on disk (instead of copying files byte-by-byte) we can avoid unnecessary data duplication. If hard links are not supported for the source or destination paths specified, then a standard byte-by-byte copy is used. (possible values: ``true`` and ``false``; default value: ``true``) *use_relative_paths* Should the paths stored in results (and used to look for inputs) be relative or absolute. Relative paths allow moving the whole working directory around but may cause problems with symlinks. (possible values: ``true`` and ``false``; default value: ``false``) *local_hash_check* Perform the hash check on the job submission machine. This option minimizes the number of jobs submitted to a cluster engine or a multiprocessing pool to only those that need to be rerun. (possible values: ``true`` and ``false``; default value: ``true``) *job_finished_timeout* When batch jobs are submitted through, SGE/PBS/Condor they could be killed externally. Nipype checks to see if a results file exists to determine if the node has completed. This timeout determines for how long this check is done after a job finish is detected. (float in seconds; default value: 5) *remove_node_directories (EXPERIMENTAL)* Removes directories whose outputs have already been used up. Doesn't work with IdentiInterface or any node that patches data through (without copying) (possible values: ``true`` and ``false``; default value: ``false``) *stop_on_unknown_version* If this is set to True, an underlying interface will raise an error, when no version information is available. Please notify developers or submit a patch. *parameterize_dirs* If this is set to True, the node's output directory will contain full parameterization of any iterable, otherwise parameterizations over 32 characters will be replaced by their hash. (possible values: ``true`` and ``false``; default value: ``true``) *poll_sleep_duration* This controls how long the job submission loop will sleep between submitting all pending jobs and checking for job completion. To be nice to cluster schedulers the default is set to 60 seconds. *xvfb_max_wait* Maximum time (in seconds) to wait for Xvfb to start, if the _redirect_x parameter of an Interface is True. Example ~~~~~~~ :: [logging] workflow_level = DEBUG [execution] stop_on_first_crash = true hash_method = timestamp display_variable = :1 Workflow.config property has a form of a nested dictionary reflecting the structure of the .cfg file. :: myworkflow = pe.Workflow() myworkflow.config['execution'] = {'stop_on_first_rerun': 'True', 'hash_method': 'timestamp'} You can also directly set global config options in your workflow script. An example is shown below. This needs to be called before you import the pipeline or the logger. Otherwise logging level will not be reset. :: from nipype import config cfg = dict(logging=dict(workflow_level = 'DEBUG'), execution={'stop_on_first_crash': False, 'hash_method': 'content'}) config.update_config(cfg) Enabling logging to file ~~~~~~~~~~~~~~~~~~~~~~~~ By default, logging to file is disabled. One can enable and write the file to a location of choice as in the example below. :: import os from nipype import config, logging config.update_config({'logging': {'log_directory': os.getcwd(), 'log_to_file': True}}) logging.update_logging(config) The logging update line is necessary to change the behavior of logging such as output directory, logging level, etc.,. Debug configuration ~~~~~~~~~~~~~~~~~~~ To enable debug mode, one can insert the following lines:: from nipype import config, logging config.enable_debug_mode() logging.update_logging(config) In this mode the following variables are set:: config.set('execution', 'stop_on_first_crash', 'true') config.set('execution', 'remove_unnecessary_outputs', 'false') config.set('logging', 'workflow_level', 'DEBUG') config.set('logging', 'interface_level', 'DEBUG') .. include:: ../links_names.txt nipype-0.11.0/doc/users/debug.rst000066400000000000000000000051771257611314500166420ustar00rootroot00000000000000.. _debug: ========================== Debugging Nipype Workflows ========================== Throughout Nipype_ we try to provide meaningful error messages. If you run into an error that does not have a meaningful error message please let us know so that we can improve error reporting. Here are some notes that may help debugging workflows or understanding performance issues. #. Always run your workflow first on a single iterable (e.g. subject) and gradually increase the execution distribution complexity (Linear->MultiProc-> SGE). #. Use the debug config mode. This can be done by setting:: from nipype import config config.enable_debug_mode() as the first import of your nipype script. .. note:: Turning on debug will rerun your workflows and will rerun them after debugging is turned off. #. There are several configuration options that can help with debugging. See :ref:`config_file` for more details:: keep_inputs remove_unnecessary_outputs stop_on_first_crash stop_on_first_rerun #. When running in distributed mode on cluster engines, it is possible for a node to fail without generating a crash file in the crashdump directory. In such cases, it will store a crash file in the `batch` directory. #. All Nipype crashfiles can be inspected with the `nipype_display_crash` utility. #. Nipype determines the hash of the input state of a node. If any input contains strings that represent files on the system path, the hash evaluation mechanism will determine the timestamp or content hash of each of those files. Thus any node with an input containing huge dictionaries (or lists) of file names can cause serious performance penalties. #. For HUGE data processing, 'stop_on_first_crash':'False', is needed to get the bulk of processing done, and then 'stop_on_first_crash':'True', is needed for debugging and finding failing cases. Setting 'stop_on_first_crash': 'False' is a reasonable option when you would expect 90% of the data to execute properly. #. Sometimes nipype will hang as if nothing is going on and if you hit Ctrl+C you will get a `ConcurrentLogHandler` error. Simply remove the pypeline.lock file in your home directory and continue. #. One many clusters with shared NFS mounts synchronization of files across clusters may not happen before the typical NFS cache timeouts. When using PBS/LSF/SGE/Condor plugins in such cases the workflow may crash because it cannot retrieve the node result. Setting the `job_finished_timeout` can help:: workflow.config['execution']['job_finished_timeout'] = 65 .. include:: ../links_names.txt nipype-0.11.0/doc/users/function_interface.rst000066400000000000000000000132561257611314500214160ustar00rootroot00000000000000.. _function_interface: ====================== The Function Interface ====================== Most Nipype interfaces provide access to external programs, such as FSL binaries or SPM routines. However, a special interface, :class:`nipype.interfaces.utility.Function`, allows you to wrap arbitrary Python code in the Interface framework and seamlessly integrate it into your workflows. A Simple Function Interface --------------------------- The most important component of a working Function interface is a Python function. There are several ways to associate a function with a Function interface, but the most common way will involve functions you code yourself as part of your Nipype scripts. Consider the following function:: def add_two(val): return val + 2 This simple function takes a value, adds 2 to it, and returns that new value. Just as Nipype interfaces have inputs and outputs, Python functions have inputs, in the form of parameters or arguments, and outputs, in the form of their return values. When you define a Function interface object with an existing function, as in the case of ``add_two()`` above, you must pass the constructor information about the function's inputs, its outputs, and the function itself. For example, :: from nipype.interfaces.utility import Function add_two_interface = Function(input_names=["val"], output_names=["out_val"], function=add_two) Then you can set the inputs and run just as you would with any other interface:: add_two_interface.inputs.val = 2 res = add_two_interface.run() print res.outputs.out_val Which would print ``4``. Note that, if you are working interactively, the Function interface is unable to use functions that are defined within your interpreter session. (Specifically, it can't use functions that live in the ``__main__`` namespace). Using External Packages ----------------------- Chances are, you will want to write functions that do more complicated processing, particularly using the growing stack of Python packages geared towards neuroimaging, such as Nibabel_, Nipy_, or PyMVPA_. While this is completely possible (and, indeed, an intended use of the Function interface), it does come with one important constraint. The function code you write is executed in a standalone environment, which means that any external functions or classes you use have to be imported within the function itself:: def get_n_trs(in_file): import nibabel f = nibabel.load(in_file) return f.shape[-1] Without explicitly importing Nibabel in the body of the function, this would fail. Alternatively, it is possible to provide a list of strings corresponding to the imports needed to execute a function as a parameter of the `Function` constructor. This allows for the use of external functions that do not import all external definitions inside the function body. Hello World - Function interface in a workflow ---------------------------------------------- Contributed by: Hänel Nikolaus Valentin The following snippet of code demonstrates the use of the function interface in the context of a workflow. Note the use of ``import os`` within the function as well as returning the absolute path from the Hello function. The `import` inside is necessary because functions are coded as strings and do not have to be on the PYTHONPATH. However any function called by this function has to be available on the PYTHONPATH. The `absolute path` is necessary because all workflow nodes are executed in their own directory and therefore there is no way of determining that the input file came from a different directory:: import nipype.pipeline.engine as pe from nipype.interfaces.utility import Function def Hello(): import os from nipype import logging iflogger = logging.getLogger('interface') message = "Hello " file_name = 'hello.txt' iflogger.info(message) with open(file_name, 'w') as fp: fp.write(message) return os.path.abspath(file_name) def World(in_file): from nipype import logging iflogger = logging.getLogger('interface') message = "World!" iflogger.info(message) with open(in_file, 'a') as fp: fp.write(message) hello = pe.Node(name='hello', interface=Function(input_names=[], output_names=['out_file'], function=Hello)) world = pe.Node(name='world', interface=Function(input_names=['in_file'], output_names=[], function=World)) pipeline = pe.Workflow(name='nipype_demo') pipeline.connect([(hello, world, [('out_file', 'in_file')])]) pipeline.run() pipeline.write_graph(graph2use='flat') Advanced Use ------------ To use an existing function object (as we have been doing so far) with a Function interface, it must be passed to the constructor. However, it is also possible to dynamically set how a Function interface will process its inputs using the special ``function_str`` input. This input takes not a function object, but actually a single string that can be parsed to define a function. In the equivalent case to our example above, the string would be :: add_two_str = "def add_two(val):\n return val + 2\n" Unlike when using a function object, this input can be set like any other, meaning that you could write a function that outputs different function strings depending on some run-time contingencies, and connect that output the the ``function_str`` input of a downstream Function interface. .. include:: ../links_names.txt nipype-0.11.0/doc/users/grabbing_and_sinking.rst000066400000000000000000000237761257611314500217000ustar00rootroot00000000000000.. _grabbing_and_sinking: ================================== DataGrabber and DataSink explained ================================== In this chapter we will try to explain the concepts behind DataGrabber and :ref:`DataSink `. Why do we need these interfaces? ================================ A typical workflow takes data as input and produces data as the result of one or more operations. One can set the data required by a workflow directly as illustrated below. :: from fsl_tutorial2 import preproc preproc.base_dir = os.path.abspath('.') preproc.inputs.inputspec.func = os.path.abspath('data/s1/f3.nii') preproc.inputs.inputspec.struct = os.path.abspath('data/s1/struct.nii') preproc.run() Typical neuroimaging studies require running workflows on multiple subjects or different parameterizations of algorithms. One simple approach to that would be to simply iterate over subjects. :: from fsl_tutorial2 import preproc for name in subjects: preproc.base_dir = os.path.abspath('.') preproc.inputs.inputspec.func = os.path.abspath('data/%s/f3.nii'%name) preproc.inputs.inputspec.struct = os.path.abspath('data/%s/struct.nii'%name) preproc.run() However, in the context of complex workflows and given that users typically arrange their imaging and other data in a semantically hierarchical data store, an alternative mechanism for reading and writing the data generated by a workflow is often necessary. As the names suggest DataGrabber is used to get at data stored in a shared file system while :ref:`DataSink ` is used to store the data generated by a workflow into a hierarchical structure on disk. DataGrabber =========== DataGrabber is an interface for collecting files from hard drive. It is very flexible and supports almost any file organization of your data you can imagine. You can use it as a trivial use case of getting a fixed file. By default, DataGrabber stores its outputs in a field called outfiles. :: import nipype.interfaces.io as nio datasource1 = nio.DataGrabber() datasource1.inputs.base_directory = os.getcwd() datasource1.inputs.template = 'data/s1/f3.nii' results = datasource1.run() Or you can get at all uncompressed NIfTI files starting with the letter 'f' in all directories starting with the letter 's'. :: datasource2.inputs.base_directory = '/mass' datasource2.inputs.template = 'data/s*/f*.nii' Two special inputs were used in these previous cases. The input `base_directory` indicates in which directory to search, while the input `template` indicates the string template to match. So in the previous case datagrabber is looking for path matches of the form `/mass/data/s*/f*`. .. note:: When used with wildcards (e.g., s* and f* above) DataGrabber does not return data in sorted order. In order to force it to return data in sorted order, one needs to set the input `sorted = True`. However, when explicitly specifying an order as we will see below, `sorted` should be set to `False`. More useful cases arise when the template can be filled by other inputs. In the example below, we define an input field for `datagrabber` called `run`. This is then used to set the template (see %d in the template). :: datasource3 = nio.DataGrabber(infields=['run']) datasource3.inputs.base_directory = os.getcwd() datasource3.inputs.template = 'data/s1/f%d.nii' datasource3.inputs.run = [3, 7] This will return files `basedir/data/s1/f3.nii` and `basedir/data/s1/f7.nii`. We can take this a step further and pair subjects with runs. :: datasource4 = nio.DataGrabber(infields=['subject_id', 'run']) datasource4.inputs.template = 'data/%s/f%d.nii' datasource4.inputs.run = [3, 7] datasource4.inputs.subject_id = ['s1', 's3'] This will return files `basedir/data/s1/f3.nii` and `basedir/data/s3/f7.nii`. A more realistic use-case ------------------------- In a typical study one often wants to grab different files for a given subject and store them in semantically meaningful outputs. In the following example, we wish to retrieve all the functional runs and the structural image for the subject 's1'. :: datasource = nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']) datasource.inputs.base_directory = 'data' datasource.inputs.template = '*' datasource.inputs.field_template = dict(func='%s/f%d.nii', struct='%s/struct.nii') datasource.inputs.template_args = dict(func=[['subject_id', [3,5,7,10]]], struct=[['subject_id']]) datasource.inputs.subject_id = 's1' Two more fields are introduced: `field_template` and `template_args`. These fields are both dictionaries whose keys correspond to the `outfields` keyword. The `field_template` reflects the search path for each output field, while the `template_args` reflect the inputs that satisfy the template. The inputs can either be one of the named inputs specified by the `infields` keyword arg or it can be raw strings or integers corresponding to the template. For the `func` output, the **%s** in the `field_template` is satisfied by `subject_id` and the **%d** is field in by the list of numbers. .. note:: We have not set `sorted` to `True` as we want the DataGrabber to return the functional files in the order it was specified rather than in an alphabetic sorted order. DataSink ======== A workflow working directory is like a **cache**. It contains not only the outputs of various processing stages, it also contains various extraneous information such as execution reports, hashfiles determining the input state of processes. All of this is embedded in a hierarchical structure that reflects the iterables that have been used in the workflow. This makes navigating the working directory a not so pleasant experience. And typically the user is interested in preserving only a small percentage of these outputs. The :ref:`DataSink ` interface can be used to extract components from this `cache` and store it at a different location. For XNAT-based storage, see :ref:`XNATSink ` . .. note:: Unlike other interfaces, a :ref:`DataSink `'s inputs are defined and created by using the workflow connect statement. Currently disconnecting an input from the :ref:`DataSink ` does not remove that connection port. Let's assume we have the following workflow. .. digraph:: simple_workflow "InputNode" -> "Realign" -> "DataSink"; "InputNode" -> "DataSink"; The following code segment defines the :ref:`DataSink ` node and sets the `base_directory` in which all outputs will be stored. The `container` input creates a subdirectory within the `base_directory`. If you are iterating a workflow over subjects, it may be useful to save it within a folder with the subject id. :: datasink = pe.Node(nio.DataSink(), name='sinker') datasink.inputs.base_directory = '/path/to/output' workflow.connect(inputnode, 'subject_id', datasink, 'container') If we wanted to save the realigned files and the realignment parameters to the same place the most intuitive option would be: :: workflow.connect(realigner, 'realigned_files', datasink, 'motion') workflow.connect(realigner, 'realignment_parameters', datasink, 'motion') However, this will not work as only one connection is allowed per input port. So we need to create a second port. We can store the files in a separate folder. :: workflow.connect(realigner, 'realigned_files', datasink, 'motion') workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.par') The period (.) indicates that a subfolder called par should be created. But if we wanted to store it in the same folder as the realigned files, we would use the `.@` syntax. The @ tells the :ref:`DataSink ` interface to not create the subfolder. This will allow us to create different named input ports for :ref:`DataSink ` and allow the user to store the files in the same folder. :: workflow.connect(realigner, 'realigned_files', datasink, 'motion') workflow.connect(realigner, 'realignment_parameters', datasink, 'motion.@par') The syntax for the input port of :ref:`DataSink ` takes the following form: :: string[[.[@]]string[[.[@]]string] ...] where parts between paired [] are optional. MapNode ------- In order to use :ref:`DataSink ` inside a MapNode, it's inputs have to be defined inside the constructor using the `infields` keyword arg. Parameterization ---------------- As discussed in :doc:`mapnode_and_iterables`, one can run a workflow iterating over various inputs using the iterables attribute of nodes. This means that a given workflow can have multiple outputs depending on how many iterables are there. Iterables create working directory subfolders such as `_iterable_name_value`. The `parameterization` input parameter controls whether the data stored using :ref:`DataSink ` is in a folder structure that contains this iterable information or not. It is generally recommended to set this to `True` when using multiple nested iterables. Substitutions ------------- The `substitutions` and `substitutions_regexp` inputs allow users to modify the output destination path and name of a file. Substitutions are a list of 2-tuples and are carried out in the order in which they were entered. Assuming that the output path of a file is: :: /root/container/_variable_1/file_subject_realigned.nii we can use substitutions to clean up the output path. :: datasink.inputs.substitutions = [('_variable', 'variable'), ('file_subject_', '')] This will rewrite the file as: :: /root/container/variable_1/realigned.nii .. note:: In order to figure out which substitutions are needed it is often useful to run the workflow on a limited set of iterables and then determine the substitutions. .. include:: ../links_names.txt nipype-0.11.0/doc/users/images/000077500000000000000000000000001257611314500162555ustar00rootroot00000000000000nipype-0.11.0/doc/users/images/componentarchitecture.png000066400000000000000000004614061257611314500234030ustar00rootroot00000000000000‰PNG  IHDRżżĆ@':/iCCPICC Profilexc``2ptqre``ČÍ+) rwRŚR`żŔŔÁŔÍ Ě`Ě`ť\\ŕŕĂyůy© |»ĆŔଠ2 UŽ Ź+ą ¨¨ęĄ¤'300ŮŮĺ%@qĆ9@¶HR6˝Ä. rОůŇ!ě+ v„ýÄ.z¨ć H}:ÍÄb'AŘ2 vIjČ^çü‚ʢĚôŚ#Ç”ü¤T…ŕĘâ’ÔÜbĎĽäü˘‚ü˘Ä’Ô Zű@ş! A!¦ahiiˇ Ą"ŠqźÁáË(v!†°(ą´¨ Ęcd2f` ÄG1G‚Á)Ë„I/Ăţ©15C}†}sĂŻPoćłĺé pHYsgźŇR IDATxěť ĽMUűÇ_ł ‘ Q M†ŠŢŠĘJ(Íi¤á-SIT^ßJT*IˇyĘTh.EEBáźBř˙Î}XíÎ9÷8÷Ţ3ě}ÎwóŮ÷ŮĎ^{íg}÷ü;k(´cÇŽ1A€ @€ äB p.~Ü€ @€ @!¨'ś€ @€ @ Ô“XtX@€ @€PO8 @€ @€@,¨'±č°€ @€  žp@€ @€ XPObŃa @€ @@=ဠ@€ @± žÄ˘Ă:@€ @€ €zÂ9@€ @€b@=‰E‡u€ @€ @ő„s€ @€ Ä"€z‹ë @€ @€ę ç @€ @Eő$ÖA€ @€ ÔÎ@€ @€ ‹ęI,:¬ @€ @¨'ś€ @€ @ Ô“XtX@€ @€PO8 @€ @€@,¨'±č°€ @€  žp@€ @€ XPObŃa @€ @@=ဠ@€ @± žÄ˘Ă:@€ @€ €zÂ9@€ @€b(k%ë @'°cÇWŻmÎHŹüQť. @HB… …eéQŻÓk‡mË" „@=I8R2„ 0‰$R(‰ô 0„@  č†,}‰$Ź-e‚@  žň°4 Dp‡3”F¶M.˝Íď<¶¨t[ĺüa‹ÎŹ@ !¦ŚŘ}8Ňiűr~fŰÜ»ÖëIH„d@Ŕ@=q(0 @ ÓnbsW6[Ô¶GĚŘľ}»Kc†Kćg€B Rě°›ł×Ż[±5…Ý“ĺIH d@ Ná·ˇ87# @ŔěeÚ;·¨ä±I‹Î0}dךżk ČY9#_Ö#“á ü°{lTÄśn.#Ěó¸\2yĚv«0 uO Í!@Ŕwś>i(V݆˘wkKµ 1VEMŹ€ňDŔn‘›ČŻI·k3”ŔŚČąnÔ… –?2<€Kő$±<É €RD@oĚÚ“wn‹zŰ6ŐĂ ·čR:ŹĄw~3¢Źę KĂ" äŹ@¤ęaúr 3l1lnş‰Ý¨‹)˘µ‘7m9ó#€z„E@$˝1»—f’HL%±ąŠ$cîÜą3gÎüꫯ֭[÷×_Éé6qeŽô¸U€ <‘2‡y$‹”+Wî€hѢE«V­Š/.żM f—ął"ˇÍ™Ľ8ÉČZQÚ¬eAÁ!@ LŕđÎM"‘G“l›ś˝m۶ɓ'Ź9ňűďżD €˘¨PˇBż~ýÎ?˙ü’%KZĹÉ%VëÄćÚĘűhU?iÓ¦MńâĹU'EmvÔʼnµÜ)V¬šęX(Öx‡ŢO8y ‚ îIAč±- ¤Ť€ý(éÄ&˝F»Iť(¬¦M›"ť¤íđ°c@I& ­D˝źh'sćĚquíA`Ďę›$ů=˛Ž@Ѭ+1† €đę&V˝(»7f˝C/]şT~ Äđ‚> Ä"pđÁkő·ß~«;żjšČ¶Ú%zL¨˛‰ž Z4ýĹĆâČ:@ >¨'ńq" ř†€©'6×˱[”mż7ţúëŻ ¶jŐŞľ ™@ @ ńě>Ż{ľičz¨ÍŽćZÔΤ›mJâwOŽ€@–@=ɲNq!“€Ţ€¸ćnrş‰Ţ’­ÇvAż@ĘPbµfY‰€â"`÷yÝö·l٢Ú%Öé‰ZôhŇöz^č!éDs­51E~ęˇÄ—D€@ú=‰@‚€|IŔé&ť[ 3ô–,Ź/K@P€ xşçŰť?ěq`‹na‹ÎŹ@ NÔ=‰É @ ýĽoĆŠF‹Ş˘_­ÍŽŐ=Ń/ZL¬D@)! éDw~Ő7ŃCÁZîäÔ> Í\}­JI,ěČdÔ=ÉäŁKŮ d*÷lż7j. ĹŮnm¦źrA€€—€µĺ´gł-O/(l@  ¨{Rzl @)" ×_÷¬÷cMVßÄ gKC1%Ea±@H7=ěćŻMdknŠÍ­ËXŐCQî9B×'é>hě$@Ý“@6‚† ##ŞěěPÖi(îýJ€ $šhŇSŔ +›A6wĘ îIŠł;@Č?ÓJr^’˙žÉ©7fűáQső~˘uůß[B€@ č)`ý^)jZ,V¬ćö,ps«„¨’, ŕ/Ô=ń×ń @ź€^Ž-±^Žek’avü™€MŔ{ó7ŰŠ#;Đĺ"x@Ŕo¨{â·#B<€ +˝ »É„Ő:ŃälŐ=ѢŇäš+ @ ł螯;żî˙Ş]˘Çő{˘"šíž<2ë°S¤uOŇť]B€@>¸_{¶śiäcl@A$ ˇDaG}Či%rkX@b†ü@€ş'~8 Ä@»'ŕ"Á˝ k3ŮVĺ$T %gň®Ý}ľ¤€ Đ=_ę‰n˙Ş{˘ąňh˛29[~MA.(±Ci&@Ý“4v@q°Wa÷¬wełÍg&$ Ě#ö pO«“˘ň:O敝A)#€z’2Ôě€ňOŔ^|µ˝÷—Cď۰l˝%kŇʞóż'¶„ @Đ=_w~{¸ç‚®öěsşµ€â!€z%Ň@€€_čÝ×Bq†í…Ř;÷K¸Ä@É'ŕ˝˙‡=lç^gňĂa€@f@=ÉĚăJ© d$°÷c·ö“cF–ťBA€@nr{8żąmŽ€@<POâˇD@đ#˝ +,ď;±×öcÄÄ@‰&`wţ¨O„DďŠü ¬&€z’Ő‡źÂC:Ż\âl{‡zŃ€â$`÷wówŹ87' x žÄC‰4€ ŕ;aďĘ.>÷öě<€ …r{Ld! Š $„ęIB0’  @€ @Kő$c- UĽő´©~’U‡žÂB°Űľ»ů;2€Hő$0É € @€ $€z’•"A€ @€ @¨' „IV€ @€ d Ô“ <¨ € @€ @=I L˛‚ ¤P˙t˛d @ Ëđ@ɲNq!H¨'‰¤I^€ TöÖëťŰîĽŮIŤĚ!@Ŕ‡Ľ Ďë1ۇa  ¨':X„ @€ @€@ ž¤:»„ @€ @ @POt°€ @€ 4@=Itv @€ @€@€ žč`* @€ @i €z’čě€ @€ @= ĐÁ"T@€ @€Ň@ő$ ĐŮ% @€ @"€z E¨€ @€ ¤ęI łK@€‚HŕđĂŻmŞ^˝úqÇwóÍ7oܸŃ[®'ź|RÉ›7oîu&Öž2eŠvqŘa‡ąl>ř`yžţyç‰ÓHA´qFB2@€€ őaL„@€|H`Æ ˙÷˙ś+V¬xăŤ7yä‘×^{­^˝z–fóćÍZĄ­"7I”gëÖ­ÚEůňĺ]†ä–-[ś'N#ŃĆ É @>$€zâĂBH€ ř—@ďŢ˝ äâűóĎ?żüňË÷Ţ{ďľűîűţűďĎ>űlŮEŠQUąęŞ«*W®ě§Ŕ¸đ ůĺ§ŕĿǴDx¤„ ¤—ęIzůłw@€F`Ż˝ö Ó&9äîÝ»×®][ZÉĽyóŢ˙ýcŽ9FĄR›ť¤6ۉ nČ!Qý»u¦%ÚÝFE@€€OĐď‰Oa@€ l={ö´|öŮgfěرc۶mŰ·owÓ˘&[”ţüů/˝ôŇĘ•+]‚HCIŢyçť·ß~;¬S•Č”.[íB»¶EµÇYż~ýożýf‹żţúë[o˝Ą e„ĺ­v­m-`­ýꫯ^|ńEÍ]ća9hń÷ßź={öš5k"Wá šęI ÁC€ ŕ+V,^Ľ¸˘‘č`1=öŘcE‹mĐ -ŞG-j’¸pĺ•WŞEŹŞ{téŇeżýö;á„~úé§°’,]şô¨ŁŽRU—¶m۶k×Nť›´nÝzÉ’%aÉÂkÔ¨ˇ]Lś8Ńüę vď˝÷îŐ«—ä’Îť;+·öíŰ+Cĺvć™g:)G‰Ă˘•§QŁFÚöŁŹ>zá…*UŞTż~ý®]»j.[őkÂöűóĎ?źxâ‰ĺĘ•S˝›ŞU«Ş‡Ý‡zhęÔ©eË–=őÔSĂł@Zîî0 @~$đĹ_X_­tPěřÎ:ë,u1[łfMÉި˛`Áő5«qs>ţřc©¶í믿~Úi§IňP2éüńÇś9sfÎś)=eňäÉmÚ´‰˝‹°µŞŢ˘ ?˙üó–-[J¬‘ ˘h'LP¦L™|0,qŘâťwŢůÔSOU©Rĺ”SNQýU-Y·n]‡TqƵ`Z¶l™”ť~řˇPˇB‡zč>ű죵_|±śŞŤ˘®aÂňd€ 8Ô= Ü!#`@€üE@-Y$|śţů K•;¬Ó“!J:ąăŽ;ľýöŰG}tîÜą .ÜcŹ=~üńÇaÆŮV›6mşŕ‚ $ť¨ XuIűřăŹK1Q—´Ş¨˘¦4RU4ÔNŚü#Wik×®ť6mÚ¬Yłž~úiÉ(ęÝVÉĆŤ'u#2˝×#‘EŤ’¤¶(†W^yEµNTťD±=ńÄ.ٵ×^+é¤V­Z{hѢEJöÝwß©˘Ę»ďľ«41Zú¸0 @>'€zâóDx€ ř‹€j…HzpS·nÝT/CÇŞżX*¤B… ±#VŰő/ëŇhŰŰn»M‹<đ€Ť,mE2„ÎŚ=şD‰–˛X±bjŹ#ĺB:ZĸÍă4î˝÷^µ¬q‰űöí+[˝˘¨ÚsF54Źä7(˛˘˛š/’`,˝ęÎ<˙üófHáí»ďľćTśÚJ­™˘ć‰€ 8¨';d @€@: ¨†t7I8P— HzÁřńă/żüňݧ~@ÔÂĹ›LMx´¨%ę“UĆ”)S4?ăŚ3¤x“©_•cŹ=VuDâőďÖVlޱâMÖ°aĂÂ…CďŞĚâőGÚ҉,Ą[Ő¸qcď†3fĚТ†jÚ´©K#C͂ԵŠ× @.ú= î±#r@€Ň@@5/ÂşAÝsĎ=Ő׉¦ŇĄKÇĐ–L}‘¨żUu+«žbŹ<ňHëV˝ś¨9OXĘU«VÉŁVqcýZITŮD}ÁĘ–_}ťh𚯿ţZzD ŠŞÁn4JN©RĄÂüi\´ć9d'2†Ĺ‹G:ń@€‚H€^cxÔ€ xçťw¢衇äѸ6ÖÉČa‡¦Ĺçž{.,ٶmŰÔ+ŠĆµŃ(Âa«Ň¸¨_´÷7ß|sőęŐŢ0$Íž=ŰëÁ† —ęIpŹ‘C€ H™ŘFŐ±čçÎť;räHŮ7ŢxŁy4ě±j Ěš5kĚ1®„Ű·ożţúë5âŹú—íŢ˝»ó§ÝĐh>ÁGĐž{îążýö›ĹŁŢm;uę¤j2iŹ @ !@Ëť„`$@€ /UéÖ­›Ć÷mѢŲeË^~ůeIЏ_ż~–…Úď úhĹŠăÝYňÓ©—éA:txőŐWŐć¨yóć?üđZ'©s (҉vŰsJňcd€ ‚@=)(A¶‡ @y"đ / 0ŕí·ßž3gŽmŘĄKőëUTĄ~ýú_|ń9“%k۶í#$¦äiw)H|Ě1ÇH.‘ú#‰Gbşe9ꨣęüůóĄžÄ9s âd€ |@=É7:6„ @ »,]ş4O>?gŠÜDăřŞ—ŤLűůçźżĺ–[u«®pŐśÇy0 @Á%€zÜcGä€ ‰@™2e¬oĎ A*@–I“&©WÝ÷Ţ{oůňĺŐŞUÓxĚ 4°ľcsߎ5€ Ŕ@= ̡"P@€M@R‚N Ň:9S3$+@€€öO(D@€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP € @€ @=ńŃÁ @€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP € @€ @=ńŃÁ @€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP € @€ @=ńŃÁ @€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP € @€ @=ńŃÁ @€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP € @€ @=ńŃÁ @€ @€|Hőć… @€ @đÔ B @€ @Ŕ‡PO|xP €ţA PÎ$—ŢąĄózd˙cc @ xV\ŻÇlůť‘H(" `¨' Jv€ @€ dÔ“ ; € @€ @=I0P˛ @€ @ Ă ždŘĄ8€ @€ $ęI‚’ @€ @Fő$Ă(Ĺ Đ P€ ě!Ŕm?{Ž5%…@  ž¤>»† „`Ę„ˇ$#@Á$ŕ4głD ř”ę‰O aA€@<Ľ˘‰Ůš.zşmÝş5žH@%`÷yÝóÝýß â}4´h„ řę‰ !A€Ŕî „˝+{7(UŞ”WŻ^íubC€@†°űĽÝó#‹ă1™ Ý@=Ů-"@€€_¸Wa3¬Ž‰lűáQQš˝Ď>űČţňË/ý7q@€@Ř}ľJ•*öPĐô8Đd»’a~7OBd dÔ“,:Ř€@ćpďÄÎPëŐ«§ůś9s~ţůçĚ+2%‚ رcÇ´iÓdÔŻ_ß=Ľ” $–ęIby’ $—€ŢŚm‘?*†~pĚ™ŞV­Z˝zu˝X?đŔÉŤ†Ü!@ M&OžĽjŐŞ=öŘŁqăĆ»n˙á•Mä·čÜR0ü IDATł#MÁ˛[@  ždÂQ¤ €2ž€ýśŁî÷F{‡>ůä“•xÔ¨Q+W®Ś±« @ 6mÚ4hĐ E~ÜqÇ•,YRw~÷!”ěöQDÄ ¤ŚęIĘPł#@(÷Bl†˝Gťë5şYłfµk×ţăŹ?şt颗ěíŤ!@ŔgÎ9眯żţş\ąrROL4Źú8°ç…Ĺn |V‚Dő$HG‹X!@@ô¬weCaoĂEб·g7—碋.*S¦Ě| wk:@áĚ ţüóĎ^˝z=űěłE‹íÓ§OéŇĄuç·ç‚{x¶63ĘN) ô@=I/ö@% ·deaďʚۤ×ĺJ•*éĹZMâgĎž}衇Ž;vűöíÝŰC€@úĽüňËMš4yę©§$‘źyć™uëÖu÷|N(‘ťľŮ3 ± ©S˝Ś- L! áC¬m۶iľuëV-nٲE‹6߸qă_ýĄąVégIMj­ŁIĆŠ+ĆŚcuOŞU«Ö©S'˝yËŞ’)l( L& űĽz‡ýôÓO§L™˛dÉUőMÎ;& –(Q˘X±beË–Ő\• 5×˝]Šh®µšË)UĹćZ4µy%“Ďʤ@=IZ2† ÄđŞ'JL=Ń\ú4Íťz˛yófŻz"[˝źĚš5ëťwŢ‘Ľ’¸Č €RM@"ČŃGÝľ}űňĺË«łXé#Ĺ‹7ÝDЉ©'jŃŁUJ¤¤8ÝDN٨'©>`ě™E hf‡Ň@€@&°_ Ý/‡2ô6, E/ÄŞ“˘—c^‹ŇS4ÉS“śm۶=ꨣ>ůä“eË–­YłFŐR”Ŕ­5d–2“ńŞl:úÁYZ }é*ülVµŔtěô5Đ_řĄş*~ŻŹp}´= ˝´ekŇ}^bď˝÷®U«VŁFŤÔS¬D7éąIOM^‰Är°L4(†|BőÄ'‚0 @ ?ôV­ÉŢŚÍ›ë5Ú&˝||đÁ 4ĐG‘¤kţcŐXLg‘Ó"@FÉĎ‘Hč6?üđĂÜąső«\÷ÚkŻcŽ9F˝Ř$td–Dş &Ož¬Ş^’˝Ž?ţx]’IÜYr˛Ö`.~řˇŞ­IiŐ DÍý4†ßŢÉýw®FXŔÝ-]¶ÎŐ.‘!YD*‰ŮZ´)솯Em«IkxâýÍ đ%Zîřň° ü“€ MVaDßfšĽ˝źH‘˘Źm%­É~:¶ąŞ0hRů•@N·ą©'–­ň×>mn†ł˙ KI$°~ýú÷Ţ{O˝ŐhŞuß´iSum oˇ$î’¬“@`ÝşuPt}rČ!-Z´HÂ’žĄn ęhcáÂ…P´3©x6:gcbч¤Ž]¸9Žü!Ă*’H4‘â*H@Ѥş'ŇÄeČ_ŞT)Ąôöubmv”Fj•ć–ˇÍÝ[r2žęIĆb @ HČĐd2‡´ŮDdčóL“dŮÖw¬50Ý$¤ŁäLrZ2ĺ ‡W=QVZ+F–­ŢŞĺ1dÎČ‚ľ/ľQçĎź˙ńÇ »>uôŐ­ŹU}üř>pŚN@Ő7^yĺ­Ső“zőęEOä{Żn‹/^´h‘n) ¶bĹŠętŁfÍšľ<0:!ĂëňWô’IŮGJ2ŐťdŢĽy|đ í°jŐŞmÚ´ACI {©ĘÍtÍMC1őD‹’H475Ä*›ŘÜ4ť`V÷ÄÔi%J)[›h•2QbÍĺ”G“v¤ĹOV€@ö@=ÉžcMI!€ Eo‡-šnbs}ŇxŐ“0E‹š\ÓMäQn.+eľS5Ůő'Ŕ°ú7ß|óú믫ˇ‡˘®RĄĘqÇÇGi `¬`u1Mś8Q•PöÜsĎ .¸@bĄöý:UŹ’$ Ew[˝zőcŹ=Vs߀%gx'ElUE$h˘µ˛ĄŚ¸IšÔMň[M“¨ę‰ä%ĐÜ2D= ŔŮ@đ1ÔB đŞ'RC´hs'ŽČc5M47C«Ě°U’KL7Ń\źvÚ\sÓPvÉ&4Űů'ô¤-­^˝zęÔ©K–,ŃÔ˝¨t“ć͛۷MŇöIĆ©& úD÷ÜsĎĎ?˙¬ŃRúôéŁ/ŘTGčýýţűďoľů¦Ş˘čľˇĽŐ(I§.JA0K±Í˝ŠSOä”bbň‡I'RC¬î‰ek2ÝÄę›HOQbŰD«lCeâUO -ŰBŮLő$›Ź>e‡ 0¦ž8ÉC‹6I‘aJh"§MJ UúŕŃÜ)&¦›X†^őDvŔĐ*\}ľúę«ú_śőIÓŞU+uŤˇ/ź@‚`ă% 1Âďşë.É(ę1äôÓOŹw3§Ű°aÎai(ş±(R Ł{ 'ě»ďľţŽÚżŃ™€bséNěĐýA‹AäŃÜ©'f8őDЉRŞÇÍM1‘Ç2q›[¶šű—‘Aľ'€zâűCD€€ °‹€}¨h®Żn›K‘!DsŮŇAdËĐÜ&“Ndk•‰,˛•Ř4ËDe¨WmËV{“±kźüM$ˇž1cĆK/˝dăvŘaúśf4âD"öe^ę řŢ{ďŐeŐ»wo‰eľŚ1?A­]»V'łF×¶;†ú9>ůä“Ő+J~ňĘîmtű8Ó„7WM­Ň$eÄ&'ŁhQЉ%0 EĄTm.żćZÔÜ&ŮŮMšŇC"€zR |l @©$ ±C»3ÉĂ 2¬ňšô‰n˘‰łM1‘S‰MCŃ*˝Ł›nâ2´˛ČŻ)•ĺĘ’}iě’ &¨&‚Ę[ŁFŤ^˝zŐŻ_?KĘN1ŐJkҤIúĐ4h:Î$ «V­ŇđĚ ,Đ}Cźč-[¶ěÜąsĺĘ•3©ŚÉ.‹¸i67±Ăć:adŘÜ„§žŘ˘VÉp­u´(ÝÄ6Qn¦ˇXVZÔ$;Ůe!@  ždđÁĄh€2Ť€‰;T0“?Lř0qD-šb"Ź›ä±ÉÔŮ–LąŮćň(C-Úä¨iŃŮ!đÝwß=öŘcŞ€ LĘ—/ßłgĎöíŰóS¤AÜvÔ¨Qďż˙ľN€;SB… A,BŚż˙ţű'ź|RŠŇčÜVg(ÝşuŁ^U b¶JІKc¶Ý¤ČŻąśšË©I†&ŻŚ"[~©$ň禛(ÓMĽ»sűĹ€ 'Ô“8A‘ €ŇOŔä ›Kň¦žČ#żtÍÍ0[sSL4—­d6—ˇI)U6­˛Ęf¤żäŤ@ÝCč“ň•W^^}Űč7ů=z¨{‚ŔŔóO@]ź\}őŐ’ŇęÖ­{Űm·é|Č^~ÝR Ť7N#p+@}ŘźtŇI§ťvĂoÇ8\NΡ{Ż“9BbÉ®7"iţńdçLN›”Ě\:Ł”L¶ćf[.…ˇU1‚a ŘPObóa- řŽ€É67áCs-ÚälšL=Ń*˝—›b"§Ą4ÝÄ´Í-MŚŇZĘ Xĺ% š>/ĽđÂرc˙řăů[·n}饗Ň%„QÚ?ţřăE]ô믿včĐaŕŔ™Jŕ“O>3fĚG}¤ŞQ‰”îÝ»—+W.SË›×rĹ–0LţPžN ‘üá&­•íćfHFQbÍ]2¶ąĺ#[žĽĆIz@aPO€°@~' ™C!zçDL 1Dóp˛krN©'¶J›kĄ6±IN—ˇ^~3Ü<ŇăVaD5k–Ć©ýᇴJCş^uŐU‡rHd2űě>}úč'÷ĽćCúl 0`Ŕ€)S¦¨Yť0űî»oĆůŐW_•TôÍ7ߨ¤ę1W—†ĆęVŁžŚ/xž h’‡6 3¤Č#żČI«ĚiÉl[y,˝ĺćć2 ä›ęIľŃ±! ¤“€ôíŢ«z8Ź“N´ÖlšL1qŠ6×Zůő¶­ąmî-’śŢEěÜlŢĽůńÇ=zôďż˙®4ÖĄEµjŐrKŹ:gÎ8ă őrĐA=űěłŮPCw—^zéľűîÓč<:ŞT©rĹWh\žŚě=7ţ3Üdoz vOÖÜDfŰÜ´’ßNżé&^ĹÄm¨śÍöî€@ţ žäŹ€@š ´áć2śíGś?R7Qr¶ŰYńÄŠdémUš „ÝżöÚkÇ_ľ|ą‚mܸńСC›4i„Ŕ‰1ÍV­Zuâ‰'®]»öä“O–ô–ćhRµ{Ý…&Nś¨ZZ+W®Ô>÷Űo?ŤCÔµkW}˙§*íGú‡ Čě°ąťb¶ć6É/C›{Őó¸M´Öű죶jŚŔ‡ §GüćĎźŻĘęÎYăďôíŰ7ţ žrË–-O<ń„4”5kÖ¨,µk×îßżż†7ζZş]DŢ1Ěăü2śJâl—F†&ăć’ ©—¤ý„!~@Ŕ'PO|r €ňC@‡6łąmo’‡wî8IĹy,™Ţ­Í°Ľsů˝‹ŘFŕ§ź~şőÖ[ź|ňIń)Y˛äe—]¦ńSčâ„Ó#ĆŹŻĘşźyć™öíŰç#‡ŕnňçź>üđĂŇPÔgJQż~ý믿^ ß‚[˘|DUÚ0§ćÎPζhsď˘lŻn¶I>Bb@ą@=ÉŤ ~@HuĂé ¶ĘťSErUÂlKVć¨Î°4Yµ¨î*xŕŰn»Íş8QĹaÆ©őAVA °‰% őäŃG-W®Ü;ďĽS§NťÄfî˙Üt)©á’ú”ýĺ—_íˇ‡Ş*]íÚµóä ‰ĐĎȬś?L.QJóX·ÖünnZł™C(8Ô“‚3$@đ§t8CaɶɅ¨Eç×»µ[k~—ĚŇx±Őçĺ A¬ĎKun2jÔ¨fÍš$°uëÖŽ;Ş X˝zőf̡a} a7ß°aĂ]wÝőŕš.ŮĽyó›nş©eË–A,KžbŽ8Ěăő˶E›+˙G¨=Žó8ŰëÉS$$† °[¨'»ED@'8Cq;qÄ•ÁÖzÓŘŞ0Oä†.‡,4-Ztíµ×ľ˙ţű*»Ć—Őw]Ź=řJÉÂ3!IEV÷R Ô‘Şú‘Ő} P­ZµtÇĹţ!d Ô“l9Ň”€ M›6©ą„uq˘~Î<óĚ˙ţ÷ż|•ĺ† ˛ |ňÉ'j/¦wÔçöŰoOöî‚•˙ĽyóÔ±îŰoż­°%n^~ůĺR9+UެR- @= âQ#f@€@ÂLś8QŐL–/_®[´hˇ.NôËÂr'#ä‹ŔsĎ=wÚi§iÓ &ôěŮ3_ydňF3gÎT[žYłf©ę&檜‰†N™|Č) ŕ¨'>8„@Hůóç«‹“9sćhçęCAőM4°N:aźB@ÝŁŢ|óÍŞ^1{öě Ż7JÉăv˝ňĘ+P\Äh‹rĺĘI˝âŠ+Ę–-w$„ <@=É,’B€2ŔĘ•+Uů_ˇŞ‹ýpÝż˙˙üç?%K–ĚŚŇQŠĚ  Qf:wî&ŐĹÉ!‡’Ée¦lYOŕěłĎ~üńÇ+V¬¨dkÔ¨‘ő<ň ŕ»ďľ»ńĆŐGҶmŰ4ŹF5Öb˝zőň™›AČt¨'™~„) d.Ůłg_uŐUú€T8ŕuq˘ß3·¸” ; üůçźju˘3_ČĽ÷Ţ{ĄJ•Mľ ,Y˛ä†n4i’¤XµŠęÝ»·ŐH*߲! L%@ż'™zd) d2ýhÜ˝{wű€,W®śt“Ď>ű é$“9eóP·/ĽđB•*U/^¬vjž5y&P·n]ő&óŃGuęÔI•PÔśGŐO.˝ôŇ~ř!Ďy± Ś&@Ý“Ś>Ľ€2ŽŔďż˙>bÄ;ďĽS?żë‡âóĎ?_gTŞT)ă J °Şu˘¦jęąCW„ĆçŢMjVÇA@Őy¬e”VcBKCéßżżTŞ86%  Ě'€z’ůÇB€@fŘľ}űřńă ´zőj•¨]»vęâ¤QŁF™Q:J|x衇.ľřâÂ… O›6­C‡ůČM" H–Ň}fćĚ™ZĄVQýúőűĎţŁ!{"Sâ UPO˛ępSX@*}ɨ‹“… Şx †×Q5ű †¸!8—\rÉ>Xľ|ůůóçëŇH\ĆŮžÓ[o˝uýő×Ďť;W 4ú5×\َŽdd;Ęd1 Ş'ę×*‹ŹE‡ ,"đí·ß^wÝu“'OV™Őʼn:tĽâŠ+Š+–E(jZ h4–´î7;WËť¶mŰŞĺ:hŢĽyeË–ÝͬΠ©S§j žE‹i#U?QCžË.»¬téŇyÉ´€2„€_ÔŻâµ s¤Gţ¨Î 9,€ đŻýöŰo˙ýďďľűî-[¶¨mÂ…^8tčPŤŇ ¤Ś@Té$ŇéőxíÔÄąfÍš&Mš¨—SUČzńĹS@jŠ™®˝č•űąçžÓÍçóĎ?W •+WVß(]t‘úîMWHě€@ZřK=1A$LŃb'-¤Ř) @ eÔĹɸqㆠňÓO?i§ęâDMu6l˛Řb0yÂ+Rx=^ŚL»JÝťj*uĄ¬ĘYÆ Klćä&ş)M0Alżůć-î»ďľşAť{îąÔăô€˛‡@zÔ“HAÄ<^•ÄĄń:u`ÂŁz˛çřQR@Č<ęâDŐă?ţřcMý8Üzë­;vĚĽbR"ß*„9ť\âő˶ÉM‹f;Ă­J¸ńÄOôîÝ[;R37FďN8^ËđŻżţŇĆçkůňĺňÔŞUKuRzőęĄńż’´G˛… ŕéTOś)”Ř*ç7^ΆĎüaN!@#°lŮ2ýr>eĘE®^05«ŞÇóÓnŕŽcĐŽŞtÓ»J¶-Ú\Ąv‹^Źs¦‹z6Ő`ŢeĘ”Q_§ÔŐJpµ%ÔhG(zŐŞUÚK˝zőT'ĺ´ÓNsÇ=y»&g@i$"őÄ NqŐTůµ¨I÷\ÍÍăťç¬Üą6*,%ęÇ @_ýőŽ;îĐĐ!ęSżâžsÎ9dĐ@»Ś 2ęg°˝§i®IĄV_<šŰ˘ŮnŃ–ŇĂćZLř´m۶ăŹ?^ĹÔ©SgÁ‚{íµWÂwA†ŽŔ¦M›î»ďľQŁF­]»VNŤž®:)Śćř`@™G ťę‰IRIśöáULĚ6ÝDÜťő¸˘®Ĺ @đ-=ďÔâ@żâÚF>|¸~ËőmŔ– śęVXÓJätF ĹŇXV‘ó°śµ¸~ýző «‘ŞŽ;_~™%‰›[>ż˙ţű]wÝĄ*?żüň‹Ňţ-·Ü"řąĄÇ@ ¸’®ž8]Ăä[t¶ SOô[[UCbŰĘkwŰ0¸Ç€Č!@ k H1éŃŁÇ—_~)úµ\#{ě±YK‚ű„€).'|„aş‰[+ż&-ÚÜůe8[™›íö’@ă“O>9ꨣţřă5äQwË Ě™¬r# éä¶Űn»çž{$¦(M‹-ÔaS«V­rKŹ€@ ¤A=1ÄÍĄ›ś©'ręćű /Ľů曟~ú©ŘĽys±3 @+Ű< IDATČlE‹Ý{ď˝4hĐşuënÝşi–yd§h’#ˇ„4”°ILäqó$!Ň»ę†C™kž={&i/dF@r°ŞŃ=đŔjÔŁU,LmyŽ<ňȰd,B($Ş'V%ÄÍť\b†*8ĹÄlÝgŐŐ˝÷Ţ«¶ßĄIŘ€ @ ¨oc ^{őŐWKOqş‰j;cа„ŐF‘Ç””dSĚútßcŹ=fĎž}řá‡'cä•€ş’ůGyDťË*ÁÉ'ź|ÓM7vŘaQă„  )UO¬‘Ž©'’NlQsMß}÷ÝYgťőĹ_]í:µŐăWÓ¦M«T©R¶lŮŃ$T@€ %6nܨjÂô±Ş /^ĽXĄÖ›ŰřńăŹ8âÓM4—tâULĽJJ˛k čő˛sçÎÓ¦M«^˝ú|P©RĄ,9.>)¦†4–hňřăŹkcëSO=Uc«¦’OÂ# @ů DőD-äęž„4’śbͰŠ'˛e|őŐW]ştQ/_+VĽîşë:těĽ"ňÁM @€b7wžúąXşti‰%ĆŤ§ÎŹM@1őÄl˝Ý™’˘ą˛˛—=łcä\UŞÎܬY3˝gŞI< ţ]ůŰö›oľQwNĎ<óŚŢůu¬{őę5dČ8 ą± ôH…zâÚěnbЉćňK:Q ÉO˙üs5¤RφzůWw9jäuýő׫NPjöÎ^ $Š@RÔWßDQšJ"ŹM¬ÍŽćšäďׯߤI“öŰożg&>Sľ|ůDŚ| ÄčpB˝}öěŐóňË/Źšó‚ úőí§UŹŤ}¬~ýúQÓäćś:uę[GTŻQ]?Oą4Ż˝öÚ°›†i§ň,\´°xńân•ŻŚW_}UqF†¤ŞU«Ş)˘~j;äC"äĂóüóĎąaČA4éąIůŘ<©›¨Ďď“O:Y7výş;ýĺéeĘ”‰ş»S»ťúăŹ?F®*UŞT­ZµŽhrÄŮgź­~ \}ʵo×^‹×^{m×Sş:? ŕC[·n˝ŕü >üđĂC=TMf¤•¸I·D‰&úr6Ăć*‚ 7OR‰$ĺtęÔI/˘?üđ\¤˝ín ,Z´H˘‰†‘VJ=Óűôé3pŕ@=(w»! ř„@¨ćd &©$6éŃĺ&˝döŮgę]ÜvűmH')8ěů& úĎš6˙™ë0XjŘlitŤçu/ęXNŰţţ[hC›äĐ€¤“=JíˇŹęB˙ ˝^űs˛ŕ­ěŢą‚×0´/OąWĎ^wŢqg>‚ď{Eß‹.ĽH?Ůąmu#•msçô‰ˇ’ţß˙ýź¬[·îő×_Ď-* féĄäěŐ«WĎ™3çľ{ďëtr'ŐFônni¶l ő>Čř™€ÄÓ;îĽCb¨şA™2eJ臲ś~îÜ»ź˝ ¦¸Şă<|řpíô˛Ë.Ó}&Ĺ{gwŽ€:Ž•’ĄC †]ztj¤U,U›}ŐCwi0 ř™@Ńdç}ż×óR‹šŰÔćúĘŇ$[ěhí 'śĐ¨QŁdDBž€@ xŕgő>kď {»h?ýäSý†©ß$UłC#88żźŤ§źyÚ[áBť)~óő7Ď>ű¬:xě±Ç?âđ6mÚä)ţąsçŞćĹ9çž“§­Ň•řĹ_Ô®‹+ú×Öż¦MťvĘ)§ÄDż_xŃ….§—b˘ź%źšđ”k4pĐ“žÔOÖ. ęĂNí2FŹ­w<˝ŕ©˛‰˝šˇ»ş.mÍmr…Ңł“a 4Hwýb§‘•ŐlµjŐ’±ňڇ€0~ë­·Ţ}÷]ŐCŃpH·Ýv›F8ľęŞ«4`ż¤Ć4€@ $·î‰ž—6ysp¶Ô“7ŢxC…?Ą[¬—ě4Ňa×€@j4nܸ˙ţ\řw…ęź~ţI»® A% ҉˘­QنŞÉ¸I-í{ťŮKĂ ¨e˘ÖĘH Ě´ěeÉ’%Ş#Łďź+®¸BĚź?_"HŚHÔ-‚%CM˝:tč Ď›ëú_§­>ůäż#F¬‚|KŔŮ}ôŃGşŘ[ß®÷Áť?§ą—C)+…ú˛ŐłF!IŰ•b›˛ý˛Ł¨Z·n=kÖ,µâiҤ‰ę$ŞržęxXvÔô8!ř@Ő÷hô>8e»J(_ýµj¶—,YRű1@ ' 6~Ů «^9ëž úúĹIó°7f-*Ťî@Č޲K/awڰŔÔ6dö¬ŮĎN|V_éÖ1JX‚ß~űMűU7ůŐśdĆŚúĽ—­ŞÂň»—3ŐěP>aßůJŁź(őXÔśĂv´ŰĹrĺ˵lŮRÉ–~łTs…¤\la›˙ńÇZĄą;ţú®P´rnݲ5,±•lćĚ™ę•(2ÍnYĹyŚ"söz¬âIÓfM{ô衻şVMź6Ý› N[ě-Ą†is’A~#°Ď>űÔ«WOQ-\¸Đę{_uĂ÷.¦,řŇĄKëN%E~ŢĽyęA6eűeG1H7W§ięŇK•ĐŐyÖŕÁĄˇÜyçť›6mб« ¤‹@RZîx cĎH÷¤´$ÍU'˙űďżWJ=b@ÎK ™D k—®kÖ¬yvŇłę(ôĆ!7:=˘\ąrcKM ­°zsŇÚš5kN›>mٲeęůÂüÚęơţV]ݱŇ_?xĆ;3,ćŞ~Ţyç]ré%ŢneĎ:ó,}~?účŁŇ†*•äĽóĎS­`uO«é-íŢűîzăĐ÷Ţ{O÷"e˘şýô—’{ď=÷Ş•Ť9ĺWµó‘ŁF° IĄĘ•”•Ý ‰Úď(íΒßMúśčر㺵ë.˝ôRýf«ŘlŐŐW]-cÄGś|ňÉ.ńŞW 0@4t;5g×®]ov“wěĎ8YĹyŚÜ®# }©©Žüť;uVúEQ=ţN™:Ĺ[™(r«¨ž˝öÚËÚţüöëoQŕ„A@uî4ŘŤŢôtʞv¶îĄ˛íťĐ{łJY‰ôe>qâÄăŹ?~ěرę×¶oßľ)Ű5;ŠA@ĎŻ.]ş¨Űř›nşI§Í5×\sűí·«]Źşřő>ŮcäŔ*@©!ŕş'z"†M*†óč ŞIďŮ6é[Bk+T¨š˘˛@ ]ĆŹeż+őUÜľ}ű-[¨#XÉ(÷ąX•P"CŇx+-Z´°ß-ÍÖ˘5‰_ąre·S»I:Ů»âŢOěxţç7kŢLŻăFˇwďŢş±„ĺ¶hń"5‘`ˇ×ô"…˙îDC{?ďÜóŢ˙ý#Ž8˘Í±mô¤şwýĎ5˙Q?µj¨ŻFűrJŘUnęueÔČQaŮćuQ™k“Zµk©j±"qA‹‘ýŞęGZI'ZuŇÉ'5lŘPĄ¶Ż ł+WŞěö«čÎ9çUQ…çÎ]:k­ŇH#˙;ŇĄÉ+«<#·3fÍśµ~ýzU9ů÷ż˙-O‡Ž4_¶t™·żŰ°Mr[”v¦nS´Vcĺ–? ŕjw© U-Î^ůě Ps˝J)Ö\kÝűˇ3RP®víÚéË\;Ň'şWNÁŮE<ô|TŐEŤ&ˇ0$r©N¨şřUźhZŚ|¸Ç“!i $@ëžŘROJ«źis{|şG©Š”–’’úč]©B5<ŤÄ Zl“<ďy„ ęńĘ«®´á~óĘ*OÇČŚlk¶Ó®}»RĄKińcŽ‘ eÇWäĂ綨G†N URť'G~Dn)ńCţ'`‚µŢúôʧc˝ěi’ˇ·AöŠ(C‘-*Ktĺ•WJ­Ö#ăôÓOW˛ę˛*•{g_1čç=ÇĎ<óĚGyD} ča}ţůçŹ1BuRÎ8ă ;ablÎ*@É&ŕş'.\= 5iŃ Íť†bŠÍ]z @ pŔzű1éDŬ[·nłfÍdh0šřK­Š ŻĽňŠŇß:âV'ťhQcŮ\vůe2¤•„ýBĄöAcÇ…Şg{ĄŰŁ:©5éD‹ oźŞˇš&z‡v҉­UâŃ«ĺfóáÆk°÷_Żz-[´ĽyřÍZ«üő hÉZ·jm(LU1§î¶(mĹ<±çp҉RÚVęqĹŠZĚ«|#u+َ´S×°¨D‰úuW)GşŐËśTńÇ’ˇŞI­ŽiŐí”nę/V‰/żürőą@ XtgÓmŮ^ůě=P¶{!´˛Ř‹bŠË5fĚŐÝÓ@ąj0"‘:Ĺ{gw± ¨Eż:¦Q÷ęĄJ•*ú…ŁWŻ^jr«Fľöq{sÖBH¤¨'^ĹÄB·§wnOÓ䌜!˙Pë’°źŚ$ (<× J<ˇÎ™3GÉÔJĹŞx79ôCµ¨Nć¤txýz-v’Ť×Ż_·Zµnĺő¨ş‡UďĂjťŘŞ˛{–5Ă$ oú¨¶Äť)žIŐaô‘ ”jóôÓO[•-+^ě¸ăŹ“ámĽŁf8zŹ×ŢŐÓJÔĚ˝NÁ üXÚ‡%PŁů`•ďc¤ ;şź«ąÓQGĺ‚´Ć;ŞÎ#•Ä9˝†ZčxPMQe©0J nSnąő–ž˝zzcC% ?§žxm+ŽîîŤ1ĹTKCµvÔ—ązŹRĎY)Ţ;»‹‡€Ž‘~ĎĐŻ,Ş„˘fţúU@ŁM«˝­tůx6'  dHpËŻ$ěžf¸ßĽJ2ŠDž€@2DVßČm/‘)ői–X-;äŃÝ ĚcQ5xµVÝ»F¦‘Sżu«QG*Ţ:Ř5kŐŚL,OĺĘ•% xW+ZL‹z“ö:ťm"[Ě͸úš«÷(ą‡[[¨pˇ}÷Ý·Nť:ŐŞUsN3TMăąIĎ}řá‡RL Î믽®UŇYÔmjXâČĹĘU*{U%4c i>XĺűYł5SíŐPË#›¶ţµU„ŚşéUCž]îż˙ŞŢ㎠IHn*]¦´ji’€âś€@  čć)őD÷+Ý ĚÇnVî-Ń ¨E©lÂŁö›“'OV›Jő#«*Šę‡;Ш35x˝- 8P} ÜqÇwß}·~iPµĐ#Ź<ň–[ni۶m¦–šrAľ%`őÄ[NŻhb҉w®ç¨˝é±!?(_ľĽúéX˙ës ŇU$)_®|XÓJÂśy]üaĹÚDÂGä†ęnCőD~Ýđëďżýî]&1¸U{– uż9©kŮHgüžSO=5jU—Č?üpuď˘^ń4~s÷îÝu·|ăŤPß(q6ŰQ‹¤Č<˝ž|°Ęß1úň‹/żúň+íZCNjňĆ`öŰo˝­P"3WłŁ={D¦ÇdÝÜĽď~f«öś˝Ú‹bË+ÁúŢ{ď˝řâ‹Ő-—ęjôÜ4Ă®cĐłU]źôë×oäČ‘÷ÝwßÜąsŐ>Tu0‡޲e˲ €@b čSa·ˇŘsŃÍő° {Žî6@>!`u">ZüQnń|ńŶ*˛ÇŠB˙J@Ź€&Lüö{”l·lŮ"éD{ßwż}s ĎëOH<Ţ ójë÷Ő“N őob=ĹęÇ´ź~úIu.\ϲ±3Ümüů`µŰ<نdOToĄSĤA‘´ÉźţůćoFÝ' ńôâgż–ąWA{ô.¦Bź>}¤ž(Ξ={ŞŁŤôĂŢcPű©'jř©ˇ¦ŐÁ–útWÝĆŽ;Şëßز€@˘$Ąî‰÷ˇfë!ŞiëÖ­úÚ‘‘¨b lĽfţüůß}÷ťzÖP=”ČÝ©‚śjÁˇţŢ"×ÜS˝F¨k’ĺ߇Úď„M_}Şţ i˙ýö7Ă˙s©'hůh¬_k¶óďăţ­fŢ ‰<5¬t'ź>}şV-}DFľô›Ą:4ęßDťŞD®Ĺd<©j°Ł{…ę›ŘöZh‹éĺpĎ=÷|úé§łgĎîÜąóĽyóĘ–ÝŮăUzŁbďąPŰ˙ýď×^{­*žŚ;V=ŽięÚµ«*§¨gŮܶÂ@ !’[÷ÄBÔŁQ†ćŢş'~x^&„ ™@ K¸ĆęÉ"˛ČęÎM@ĘlŰc#×&ÄcťĹŞ?TŤ×–ˇő!§ŢO*V ď`%,ĄëPG%Ň]QU3¬ŮŽjo$*ĽÔ°š9s¦uőjőh"?ţ„ăĺ”č¶f͚ȵx Ś'`ď~öúg¶Y¶Ę.Ĺ_Ă˝«Ő ÔXąľŠÍ?”ü‰Ž×C=$ľwďŢęfK}«í•*ą_Sü0ń@™A )ę‰ř ÄubŁ8{#·îB¬ XŻ·vjX˝ř‹ŠD}¸¨sܨ!ŮřAzh\ž¨ pB™MŔ˝ďɰÉűBčŢe¤—Ş3čó[Ź0Ő•»ńĆÓ {Źź€Ş»Ž?ţłĎ>;ýôÓµ•†·kذˇQRňńgBJ@ńHĽzbŹ@{"ZާŁ×Ös4ţ@I ¤—€z`9j¤:ÔĐUęJVcÖĽ˙ţű?ýYâź’Íjú´éş“K̲ć9ąfkżůćë'·dř!Ś$ ×?ﻟną)&~¸ë÷€«®şJŞ1Ş3däÉŕB5nÜřĄ—^ŇčoŞ}©ßTxŕ8ŕꫯ¶ź(2¸ŕ H%BzH$pö I$şsiqóćÍZ”­/Ůš4¦Ť7ęłG#·Kě7~\c +@ ŮÖţĽvńG‹5€±.mI’NôŽ’ěťşüĄ˝ŞR®¨oţss˝úő´kI nm° @ŞAŁQ3óPÔČuĎ\±b…*ţěż˙ţjÚ5M g&±ŠQLVA~#póđ›źyćµĺ<űěłu‹VŁ ’˘[™l͵¨ZńâĹĄĹŰ\N (ZLoAôĘzüńÇk,ů:uęč;Ü›KoHě=TGőúëŻ÷Ýwµ­ÚŔjŚž˙üç?˛'Y±  /Źąă~Rđţ†`NÍ%¦h2mEFb…o©°!¤Pç¬íŰ·Oę.bd®—lé5šb¤ Ä*Ý­żŰ3Î8#·€ő˝Qe*cXĺĆ? ŕgşËą·>{ń“Ç&¶˝1ĘéfldýĽ©z%űWßżu›Ö™Q"J@ ’€÷%ĐŮ2,Ą3"7L‹G5ÔD^ýő¤%vš˙ţ÷ż5Nźz>ôĐCýőWő¬^fGŤĄúď ÉźL ,$őÄŤŢą‘•Ń$ O2Š x lücŁ:»˝öÚk(˙…^öĘęŢđ°!$Š€˝ *7{ÔK ĺě}EtiµÓ‚çÓ¨QŁqăĆ)źŰożý©§ž*x†äFęÚ|áÂ…ŞR¤^Ěׯ_ßż˙ÚµkßsĎ=j›Ć¨Ř5 PIQO˘˛pOGgDM†€@fض}›z}zĺĺWÔó®úŮíŇĄKf——ŇAŮLŔűÖçµ}ÎDťvúhd<Á%°Ç{¨wU?Q+­ňĺËüńÇť;wnÖ¬™†[ nˇH*T«'I- ™C€ @ N<ńÄáÇ+ĂK/˝T#ŕ&0g˛ň2eĘÜpĂ ŇP ${Á‚Çü1Çóî»ďú!ńÄőë׿袋–/_žîĐŘ?  VOŇPv @€ ”¸ňĘ+Ď:묿ţúë´ÓNűţűďS˛Ov’f 6ś•ý,ŃĄ@éŇĄ( eČ!{îąçÂ… O<ńÄŁŹ>úí·ßNQěH(˘ Í- ™y«Ŕym %Ň#TgBg—™N@]…1¶'rmŘćI]ô^^Űvé‘?Ş3©A’yz]D:˝ŻťzbŢëÂk[$ńxR3{Ě‘—F¤G(ĽNŻJŢ«Ěk[üńxň]Ň#F,^ĽřťwŢéÔ©ÓÜąs÷ÚkŻ|gņ©!y†ÇöD®Ť'ÎrĺĘÝtÓM}űö5jÔ}÷Ý7gÎśvíÚ{챪©¤qŻăɡ€iĽ§˝×¶l#=ňGu0 6÷?Č3<ŇŁRxť^Ű˙,x„WOrC`×|ä•éÉ-ü(ÝJÂN6ç Ö]ƕ†%l± ¬Ř1čLËí’ÉÍ#·4®r—Ś3\0‘· I%`×W°.Ą|qš3\V‘·*OFáÂ…ź~úé#ʆ˙÷ż˙]{íµMĆŽűJÎÔµk×aÆ|đÁ§áN`g(OŮ6ąüµh~ç±EŮV9آócd ďy®BŮ9é´ň:ż łmî]ëőd %W ©'.hgŘŤ tU{T-hŇa ůs&3"‡ s \†(Č›…óx ;_ íŘő–ęůrÉ F>¶Őµ°órăRRţ;{öéń¬Ä„@ž D^ ćq~Űwl×Ü{)éŰĎNE—,Ď;.đŔŽí_Kîĺ˝Ld{ÝnŁ:ÝZ ä•@䵺hţ) č•3$Gî:mw>§|&”ÄYv»Ľo}î˛r†˛’í]t™GuşµńˇV5 Ô Š>’5ŇJ÷îÝăŮŠ4©!őа]»U2"OçqÉ °†¸ÖIŇżµč™0a‚zÖ€M:U4fSÝşu ’sä¶ŠÜMn­yĽ%•Gk˝Ž%6żŰ#óDžŇvbxý: ´¨)ě|'ó€Ä.‘ßŐ;BŢą•Gž3ç1Ż?!{×o~[g~›‡3ň KĂ"â'`§Sn7ókz=ÍąĎG?eČЇ–Ľ; …NăPš]÷&€n1ţ¨\Jw„]Z4Ź®&wŐŘłÓë7{§ÇeşËßĹĽËÇ_äź@ŚSÝ{-xíťż JNŃĄ¤sYr&wŇz›ťďřĽ—Ë_ąí|éŚy))™wó°´J±yó KŔ"ňDŔN§¨'Ľ9wÎsLÎ##ô Ň™ěy*iżvfşdňť§’Ř{yŻ÷đr śÇâw~[Ś F T(ož‘iâńśtŇI×\sÍwÜqŮe—Ő©SçC‰g+Ň$›€ÜÜÎ[ókn“‚‘ˇą˝Şm۶Íë—m牥q‰Ýb9?›Ç)…^˛őŹ  "`ßlQ3ËíRÚ¶#ô^«w\ťŠˇ4ˇ,Bç¤Ě¨ů$Đv))gyÜ멢p—’íÔŇ˙˝Ő?CńVZůç– gˇ« —Sč2Q.÷TRBM9:~ȰI>yô°(śŠK)ĎĹ۵»šd­ą»˝¶máŇěĘŕmøňµ f;üńoĽŃ«W/ °R±bĹ|eĂF & SŰN€Č|í¬˙ű˘°×ł]éLŁ×¶–Ě2‘˝k}ţ˙ÖŻ_âĉľá†¦L™˘ćůä\ Ďľűî›ď|an“ňô^ ĆD‰ŁîË2‰ş gf° ˛,vŞ{ŻóDÎu’Č™Ićyü«žŘ5ěť‹~čŢҸšňzPH›@äyy)…®M»žV¶d»| K>ÉąâäŚa‘űW= T‡Á ˇk>GF±‹_‰eHă˙đżýöŰ 6üő×_rî|1 2†ĺÍ"’O ç¦ú+T¨D‰•*UŞWŻŢ‘GY­Z5íŰŞ)śóΩ)úý9'µťö ĽéX†š˙=YM“9RÁČ˙ý÷ßk¨Ĺ%K–¬_·~Ë–-ˇ”&>r)%˙La»!°ëRR˛˘ĹŠîU~/ŐŠoÚ´éA ’Ç.ĄĐ;®ÎUÍv˝Ëš‘Řë(tYا׮ëbű¶pÝdýúő™ňóĎ?_˝zőź›ţÜą WÓnŽ1«SBŔs)é}·LŮ2Ő÷Ż~Řá‡59˘‰®¬Đł*g*Ľ˝°*r™­X“lĹgó”}'ŚÖ9Cv¤nňÓO?©÷Ö?üpĹŠ7nô&öć+żw1véŇĄőĐ_·nÝ)§ś’ŔlÉ*!˘žĆv¶—,Y˛jŐŞjrŐľ}űš5kjwö|ŃZť-¶ˇ>=,±ť?ć,``zś˝öÚkłfÍ’†2sćĚ»îşkĚ1ęX˝ĚĆ3¶÷ —­5™aAjQ/xĘů«ŻľŇiąós)âü·Ä, ›‘@äil=&4đö 1¶[µjUĽxq;ům­łućhrÎ ŘmĚQġÝn#.B!Ó\çÖ­[5˙óĎ?µ([ß`˛5mÚ´Is=ĂŢ}÷]ŤyޤI“qăÇyóTZôΕOŽ"ßNÝ$G;Ů)¬ęvöĆëo<öŘc?ţřŁ7lřź@óćÍ/ęs‘””T’ó ą4…]¸HÎBčöúúôŔfď¶tŢ‹ČŮ˙¨˝•Ł›lŰžó“]č˘ IcóŃGí6s@ŔWjŐŞĄzέZ· µ‰Ëądţź˝ó€“ٶţ¸;Ć6˝w0%Ôz3ť€éÝÔ„ˇzSbB˙C轆^Lďb:±é ¦8ˇ™îň˙jŢ®NžŮݛݛ˝›ÝűÉţĚi4Ň“ôŰ÷Fš§§'·‰•­ŠÄD‰Ć§Ý˝řX—ąuˇh频ŢÄ‹ÚĆ1źŤąôŇK1Ú·Ďą\aĄĆ 0?Ţ~‡í7ß|sľůý„Ř L]»Ř˘"e‘&) 4)÷”‡ś8ä†nŘd“MطҧOź)§ś‚={öD›ĐŁG>Mą’‚x2 çĘ-|žŽE2"vµ“»čłÁŤ+qK˙řăŹ9öć›o– ĆŔÔmµ 8M4؆Ŕ˘6 Ŕ¨1v%ŃŹH´¸UAĽÚşÂüŚ ěĺ1b‰&GpŔSM5•ĺŐ‰„×P"[0‰ Ž ÜrË-+da-Š j~úé÷ŰożÝvŰŤ7ąI¬nâŕßá–e“‚đZmuyËßÚÄŢ­Ăc]âćŞnP´ŕŇ'MbUá裎~íµ×ČŔđĚ©é¨cĐĎÖjŹ0XŽfěá‡FýO /”m¶ŮćŻ{üµgŹž¦@±7W÷JrÓÔÂ`L ÁřHTžú«R˘N&0ńt2ĺÂÄI?˙ňó™gśy÷ÝwS„zWYe\dĂí´ÓN[ˇ =Ŕ¸qăPš#GL1ůĺZ˛Ü€ĺ8°€Y&b#:×B$ň4äEŚĚ&Dµ‰Ĺťôp‰ľßě›Í„‰ří·ÝÎÚkd[l±ĹÖ[o˝ů曯´„!7ŕŐ1cĆŚ5jذacÇŽĄyŘEžtňI .¸ bîmůVDzť˘Á‚+ü•…úiOLШŤϮ¶zgŹłĺż›öZ ý­äTmŻ˝öB—ĐĆŘŢT~ţ¶ *Ń«ÉDŁŠZKe˝ë®»`ćW^y…‡3Ě0Ă!‡˛÷Ţ{ó™·“âŻDRĽ\0ů8ľË.»Ľđ dĐç (T‹@rgžyđyĚ1Ű^P,pK-v5YČD"Şmyćůó«=±W€ „vĺ-`~nž­“żűî»˙ý`FzćĘGqÄ>űěĂâF扠¨|đ–™×]wô—_~ů!' ±…8^4^1vµwPx%šŤ©ˇ(!AˇŇĆZ2đŠQ荑ٍ‘||żŰ–˘:u\d…@¶|÷Ýw˙ڶŤłĎ1ű§ź1Çśs`„Â?˙˝“&@ ×ô˘ŽG&JwăQ4gĺjńłÎ<ëÖ[oĺË•¬ň-łĚ2Ä„@C ă®’ODTüL¨Ž;ţ¸W\AX\ » 2iöIŁ_vŤ‰Rť´'ˇÚčF›‰xd:N0Áň‹†I‚ërŢČpŞG]qŬ·#N"Šć'pg»Ň/"™ôŢĆŠŠąŮoĽÁYf™…ŻžÝwßťI#śOŠÉ…IŤD¤xŃ`Ť™U:6ęs)“źŁ“ ‡ 4q—\rÉÚkŻ «{ˇ°¸IWäÄěĘm çú“·`Ż€Â«ľ÷˘ŕ^'04rGděWc9&ŐÉK,F]¬T'yű)ŐžĘĚ7ß|×^{-#"oÖχţcč„ńĽ”ŕncůČ<$š:˝áäˇ2e{j%"‘ęÄ‘čSÝożţvüqÇŁ:Á̄ݶ^xˇT'iŕUžü 0őÔSźp ¬Şqúăgź~vča‡~˙Ý÷ă'¸Á† §pŹ‚ĄČâŞE.Ňu#”?G$˛:qŇj©ŤÂ5W_ę„ůÁСCń¶ ŐI:t•+/0ýÝi§ťFŽąîşë˘‹<öcßyűăs7 Ź>účË/ż,¬ÇO š†€MŐľúę+ĚOŠ|W0úđśIÄ‹E2G˛śT…ďXt([qĘŰożÍ,ŽŁd±Łai?žŹ©]źK™˙"hřaâĽóÎ+X)F«VĆů6ű §Lu’vţ9ňĄ=±Î,@ândvę÷2šč °y)|6ć3s›´˙ţű·3^ŞNÔ Ľ¸c] ńGyÔ+ áv˙Ňq" ¸kęŕŢS‘=µ·Yl´Ýŕ±ÇD)5˘ĘŘ?ŁÎřö»o˝!n(qCŠ ä˘ Sé:•(îů‰ 1˛é‘‡ŰËgžyćt$•KävŘł˘đĘüâ‹/"J°şÍÄś2Rë["p—şöÇ×BÄŹhÖ*ƲçwÜA$uý:9q?UĂňÝóžEŕI žQëŤáż–cŚŮËĂ;üáţgĎÖ—H'żôŇK4CsĽz˙ť™ľ _ý5ž4ĚüAđBÁËŮŔi7ąh‡ß"ŹÚ“ežą‚ľŰËÍV_}őUň°Ŕ(ß–íŔ"Ş˘Ý4hu±’ŕwň®qŚ…‚ß“ę÷ďŘ ‹r±‰Ż‘ýmüo_|ţŽÄ0˝Ű` Ú­›ŞHÔ%—\’ôť×F˝ćĆŽbđJA(Şo‡+Qq$‹C’‘9j$ôLŠ«'¬B Ź0:l¸á†´ ź>“±ĽSź¸Pł(ŐÜ['‚Q0ął+3u SČJkĆVÓ ` †›Lży~4>ô—¦!•IęęׯGgđq„–„SVt([l±…é¨ĎĄLp‘rřaâ™gžá=ľ™í]ÝţĂDą¦f•žGí‰{éŘ9; (†ľ¬#5 éŃü$e…‚č< €ócLŽáöŃŁGóöAÜŐ[€—ĘÓż†,§VÜÍĹ}ůµhd>úř#:ÎÎv9ʨ "°řâ‹Cí“Ńź D…$úcUاźi$ÓTZ%űjĂ…3A*’LNŮ×€.’d LiđTžBŔDéÓŃź2-všĂh35ÂçÓ‹jE©ćŽ· gEA6Ń3éFĚ1×ä°fxU0=~ŞöţűďŰřbWcQ®&v›žl 9­ ŞŁçŘDÎę1bg °Żďx,"]ŁR ŘŞHUŘ0ńÁ¸a"bH{3âР¤*˛ąÍśG퉛њ}t—Éľ#»77n€Î6Űlą…U µ!`\ ‡ŰŰÇ©NL˘ĺîÂÇ^””†ľ{mEëü Óśp…`¤@áu&QJŁň4"%D©0ÓŚ†•H0śx¤_ t’•°Ąo¤(’M› J6KĐŔÔܢ6W@ŔX‹H8ng& ‚IcK˘Tˇ˛ŠŹ¨×Ć27śEÁµj ¸€d°"ŠzĆcß~ű­ńžgĹ+ý’—ăÎ *+O"b˙Â…–X3đrÄGŕhŰm·5˝‰$˘<„z’ Ćcěń„ M(Ś/C‰0ţ̦ľŽ¦’í‰8pŁ)©!Îx̨Ś*ËÂoż˛Łę7ö®ŠŐŽFOő Ś0®¶}Ž×Ç;˙Ő~‰Ńprś^l‚6‹%+Č’üł* NY‰R âÍ€qu×#QbŕpóK/>6Ĺ-oŇŠq z!r·&JN’ś26n’¦ćŕőÂ#P%śđ«ăv8íľ¨Ľ0I1ńRă‹·%⩪D0Ľ¸Eö_V—d°-«lŚÇ`=ă@®N&Šú ŘŐ¸4ĆŔi(·šÇÓôčë%…–XŔĺ°ĂC“AID«¨*CđĂBÁ«Řˇđ‚`ěęoŤŤŰXiĎ‹öüÁŕ(ܶ$G ÜFSŢ„LU z#`¶ĐpĽ[Í‹ŽűÎ7 cĺf¸"®|A„şBô×ÝFłÝĘDôT44ŽáťBŢÉ‘qľ(ŐuÎĄ ĺ{Z|nqW€P)&,Č—' 'B pÓß"Ď›ř«ďžĄř۬"!Y_iq2XôMUĄ˘#*#űtéM¸ZAcŃĘDjxę9?¬Ĺ'úµ§ú*"jCŢ3®óLF4n$cű…ŻĹF7®čM|Ü?ťĽáşőBŔ„ÂřĐÇ­˛fâĆĽŘž€©‡Ő‰=˙˘ă Ü$µ`zâťbuĽ»Ż×Ď.şB DeÜ"Ć„®hmy9Ă“®Ý&v›8ˇë„î]şOě2Ń:Ljxę[íĺĄÂű+"J $J5EšÇí,Qwź€GRPÜ5RŁ8™B”ş»U„r˘dé\)R‘(ą”(ͤ˛M ˇş%0<Ó/BĎ=%“ ŚG$b™b9ł‚ úž ŐE-6|q5y´[ײȍWVU‹Žh7Ť?Y0ţç–­8CădźŘ*ĺ  eÔČăEŔGĽ\DáÔ(Hé‘ČřÍĎ Ń0C®vE4¨.”n3Šl{‘†ZNmO|ÓŁ—Dařd’Ę­S˘ČřĤH3"ŕř< Ž˙Ł ËűĄsh:ArzĘfÄO}ŠśîŠ8©&mČ @‘]4Q•(µR•Í?p;c™µÖŤ!UZoeŐM׎h”ä Í‚ ęC1+|E'Ć„6¸8ŽŚBş˘Ůçňµń:âŮ×$ŠB <ö6†-‹IGůěŤú$/¶'ü˘i©˙®łßŔ^ü)S•ŃÔîj0nG#‹¦–8W$Ă);ĚŠw€R^§â†Lţ™’$šeş™®KpĂ*Áqa{˘ój~ĺm8F Ö:şE‹‚Č{qmdA¬ ş&uźÔuR‹őV‰>u%VĐIQq˙Ä ĄuďŔ)©y€ëń–Ős|OşŰ3ľ J¦FěŇÍé/ ĹMµ›ôµČ`”bsB­CÍ")Ę"`ŚgS57ĘtëćÇ•t‚.ę K…‚8)nvW x?!±•‹¤(Ťh>wxL„Űž={Ł’bÜČI)]ľqRsÝ7$Łî\pč×ĺ]Ô8?šZÚěŔä>Ŕót×®5÷۬ ‘×QÖLS…@ţđÜNÄ…Z=ž„=…ŚÝzi2i ó(.šŹvŤŇ IDATH„ 4ŹÖA/íŮ__©(%퉿ęňĚď9ĐxŇsf;CäëĄ=Ä Ö0"íÜU×™Ďâ†FóńaľlOlmÜ®ö ŕŠ&Ő-›O,¨Tť”â°Ý™yT}obxŃŔöhgíícqn-¸×PôŻŇ‚y!Kd~â$¦`râTç¬aĽŰ ×Ä0ŞkBÖgČp˙")pž"R7¤tŤf™nip’;”§L5EGÎnT ‚»•W•Ü đ9«Ú¶śîŘ?âů“ś1— `•u0ÂPµIŤ!ř8 ă6ëšEOTB–ńy>tL‰Ł­ČÍéžu+Q©é™QnU"ČPyµ żÁ˙^(,¸…b‡çŰZ¨ç©LŽlOĽ¸†’KŚdß>Iô‘<Á¨¶,ŕEą‚ Ŕ˙6üůH$^^’Ű#WĽPrr©!Ő‹KńI"JÍ€@4`x†w=2ţŹDŁ Q?‰—ëŻĎ+ä˛ü-ŹĘ/GVéB ±(Ś‘Ńň‚$E}đâă%"Ű®y˛>â ťO±q3ŰzEMT@ ä@χ>BÁ0^NµŹ¬Ţ}_W2R-}ĺ5#0Ů÷Ëä"P’ok®¨c ćČö˝”ÇÂCL #4‹ä.Dë‡üuSX!ĐĽ8S‘ń8ÄŘľG·˝Ü“ŽP^ü#‹Ř#»†˘ŢkČ‘&łęŇžŘvşm.ŕĎíDşvé:©W‹,…ŇŃŞ@‘ążřőą€D1B]i6~ęŤ( ó;K®â‚ĽDQ”¦˘PNČ5Łékô7EA¶'™c.‚­"€8Ř2»1ˇgK+Č-‘ú‰CX‹Ź› ¤":îÄé*ÚxŢŤ‘íűěłý÷ßź”ĺ—_ţĐC ).„€Č Ł=1ĹU2-ňĺwÔ†ş!ZW9ÎĎÔŘĘŃłŕčăuë‹ ŽD Čŕ“Ť Y4(&Ą,@Ť|#I“A:śçcBí–Ogši&öěłĎ^xá…ůla{¶Ş_ż~tëÖ +•ÝvŰ-üíP0}óÍ7}úôąęŞ«şwďŢž­Ş¶®°Ů1n¬–T†ůĂ–„-̰ ‘ĺ0–óŚç#ĺň7hzĂhO_5[! „€B 3#°ôŇK<?üđ1cƤ‡[|ÜqÇď˝÷^¬Ć,˙űß˙lżŹĹŃ;üöŰo$bF.ß~ű-‰±=5ä‰ňţ/ö‘óĺ—_Ţwß}(z{ě1vĐÄęĺÖ¨Q)ń±cÇŢ}÷Ý#GŽLfó)ß˙}¬˘•VZéŕ&Ă#Ź<â÷ď\sÍ5wÝu‰ěrZpÁ}qE„€ůA@Ú“üüj‰B@! „@"pĆgĚ8ăŚčlgJ«=DŁaši¦Yd‘E6Ůd“X`Ž9ć2d×tĽđ 3Ě0Ă1Ç)vî_vŮe?˙üs"„G}ÔW–džyć!qőŐW÷‰DpŕJ"ľEřŕE]4bÄĽĂöíŰsŹóĎ?ź˛ŘŚ …Ů}÷݉/şč˘Ä/»ě2âl°W C¸Z0M vˇ<ůä“Ĺä.¦=áä`KaWŃÇĽÄKp6¶$§śr ¨}Ę)§Ä¶ĺ¬łÎň-rÜqÇQ/:vťtŇI±§ÜŢzë­Żó믿bfBHfŔöÄŇŮżĂ9;d8ďĽó0±IćTŠB 'äB{‚Ĺ 7Ě .j†Č?%Ç%Pů˙ůÔÂ\!PRp\˘<+çęwRc“¦LZš!©LÚÓv"¨EPF|đÁ%µ F;ÄĎ9çś?ţńŹľRöÝuÔQÜ^~ůĺ>11í ÚżÝĆ´'›nş)™qebEľűî»çꛑuÖY‡”—^zéĆo$‚?W´6–‡+›tŽ?ţx"4)f~2ýôÓCm…VbŠ)|~ąé¦›¶Ţzkü° …ÁđħÇ"x?aĂ‘%˛AiŰm·ŤehôŰ y8CRŤŽŞÚßč443çB{â9Ŕ t×.Q´8mmI×TÖĄHS#ŕD€˙#i(öÔÝLt_s^"ŠOâ[2D™‹’T,:9ŮxaÝ fBŔD KAj =3!j‘¤âŮ<Ą:nŇdBTGŮ\ Ń˙Rĺ”&š ăă|ë›I’ĄŰSŹ>űz!^¨+ŞĆ§©G˝ő ÉI˝Ç{,”ŮĹ3jÔ¨’U<őÔS˙ýďQ˛l±Ĺ± lŐ!­I'˛>'Y§žzj¶üŘ1ĆŘ›`‡‚¦ăŔ$Ź÷‡‚Je„ č>Ř,CúC=ŚřĂŘĽăIY„ÚyçťŮ1¦řř 7Ü€m ŞvůôdäÓO?}÷Ýw-ý•W^aP2OnSŚA8ä@â–bOĂGYuÄSöŁěo-’Uu˘#Ň#2ˇ• Sš3{¤‡C9…€B@! „€¨:čşë®űĎţ[VöŃ„ŽTŤćŰożM¤wďŢćE5¬ĎrňóňŃGˇ ů8žJÖ^{í[nąýČ*«¬BEśĹá f,hUĐP`Ű‚3Z6ËPÄoŰ1ĆRK-ĺéř‰8Fˇę·Ţz+< Ç\®řl>ňĚ3ϰ Ő )ßăÓ“:‚ †ćáS–Váx倸ä’K’9•"„€Č ů˛=É (j†B@! „€Č´_|1úlL$é›] Gă$ţőݎq ČŹ?ţ,čSB×'¶m‡Ós¨wµŐVC b.QĚé‰ĺ¤ŕűďżĎuöŮg÷D|¤_ż~fcb®g}zĎž=}<Ś|öŮg4Ň(ź}öŮffđń3Ď<Ó”88v9ôĐCIÇe,_|E„€yC@Ú“Ľý"jŹB@! „@Ó"Ŕ:{ď˝7ÝcWË_|ë'†¤,¶ŘbŻ•čAbĄÂ[Îć®ěť1G'hOH8p WR0 aßĐśsÎig“XR?B:˙)ś†Cdľůć‹Zą UÁéě]wÝ…C”5»í¶ŢO’ehŔGA:{|8—ß(ř ĺ–†Ř¸”ĚŻ! „@ö$ż‚Ú „€B@!ĐYŕNĆŔÄÜ‘„Ý^hˇ…¸Ĺ‚mB,,˛Č"¨9}úô ‹ÄâłÍ6îKđT‚_X,Mfši&t1äńÚ,>Ľy•µ-9ŢIH˝?vŰż˙0˝\|ŁŤ6Úf›m0®ÁE.^iŃ’ŕý$–™xěčeNGţż˙ű?žâz–3(őůçźł§)–_·B@ś íIN~5C! „€B S ŔvvĺĐU| <űěłaźÍůŠŰŐ>â¸bôĹ·kX2ng8Űłë1ď*‹/ľř,łĚ‚뼢PĘoŰ!nÎb9źxôčŃ1‚TjĐtÄ•Ľőž\–Yf™żýíoäAUôú믇™9<Č”2ěŮÁŁ­=Â3 ~Oß|óÍXŻ„ůďlsĚ10Çr‡‡óIL†ąçž›ŁŁ† RyG[HŞrÜy0pĺlzÚ9ö¤sţîęµB@! „@‡!€ŤĆ–[nIő1…ö&&˙˛áľž7ß|ÓÎŻůóź˙ŚM‡µ{Ş©¦"‚ŮŘîÓŚâöíX~ĚOŘMö¤WŻ^fŠbéśďłÄK°Óg÷Ýw?AqŹ‚ †<|ÍZÎŞ®'žx"ľT°4ˇÍÔkeqĹ‘CÄwÚi'@ ’ …ťMÇ>RĽS!đÓO?ˇ@ÄŁpŘk<ď ź|ň Š?Űü…oă°Hš8>•9ÍŠC»}f,ł,řE„€G@Ú…"B@! „€B ť8çśs؆“¬lčСz`$‚I~@Đ)ě°Ă,Ľó•3‘P‘] ĹQ4Ž†Â“ÂŽ%z;ř&¦=!_†xNÁţĹçgË ^Ů>sď˝÷Ré>űěÁ_•oĽ1~O 4ČgNᔟłÎ:‹üÄc;třŢqÇѤ`DcŹBjśÓŚăX¬WřlŢu×]igřTq!đšDNȆcaÔ¨äŚíÓc…Šđ·ťôuňśŇžtrP÷…€B@! :T$˙řÇ?’“ÎĆ4cĆŚá_Ô%ědAµqňÉ'c¸Ů/‚ż3ß ż9µG§°—8>PÂík­µ–e·íX Jöq1G&Łé`s Ł:9á„°Uńűq,sú+ö5ćűśIŚQÉÇLqúURs´ęŞ«îąçždŕ–3†ŇW¤śť馛.őaÉ%—Üzë­QDžqĆ 0bÄü%w(ÔÍA G‡ÔŞJ…€B@! „@s#€çTB…>˛S†Ě€«×;î¸u đ ËţĚL0'IćĽóÎ;ÉđŐW_á†6|ʶŰą&â!˘‚A.WpňĘŞţË/żĚÖ ľKq•Ň·oßń‘#GĆRěvż($ÝsĎ=>ńę(řŰ’;§ąä#% rl·Ývć7‡łŞVXa…ďľűŽśX?qVw¬Č÷ßĎN7;r›Iůq„AV¨ť´‚äňÉ'{÷cÔě:8÷Ap°źâ(+|?űíu–E$Žś©ÔvŰQNť±ů»J9š%+Rb‡#ç§o „€B@! „ŔĽQht+„VłĄÉŔ§&BšĚĘ#ňŔŚ3Îâ';lű7n‚ÝačôÂF˛k ŐG;wÜql(»˙ţűí)® Üc—śĎŹťNěđo±ŔÚe—].ľřb´>üłoŽ]i>/BěA[nąĺ|Ę5×\C,Ĺ@óî»ď6O@ĐDďsĺ•WĆ´-ľ "yC`˛ß>oŤS{„€B@! „€B@T@ŕŤ7Ţ@uB;Ř{Ă 7$Ž^#Vdřđá¨NHDK‚- ţbMmańP 9věX ľžzę)śíĽóÎ8ÂJ…ăxĚÂĹ“ecŰÓPť¬˛Ę*˙űßÉÉŮŢŘga˙ÂŢ7źÍ"¸("{±W\‘˝i*4Ů—g§SĹ2ë6źH{’ĎßE­B@! „€B@J €ŔďĎn»íF&Ľ˘ Ĺ b&$č>pľé¦›¸E…1˙üósČń}÷Ý×§ORp*D|Í5×ô™qŇĚ)Tlť{衇.żüň_|qß}÷ĺ)¶'ţ\*vëPű¶›=ńħťv9ń„Łeś×˘± Dž&ÔPĘ`xÂV 6ÖQ7·<˝âŠ+°—ńŮÉ3Ňžäů×QŰ„€B@! „€BŔ!€;a4>lľůćłĚ2 >zđËSś›{ lOФ XÁ籎Í2vnĎńO“˘Â‰‰O·R¸zď˝÷,ńđĂGKÂ~ś˝öÚËgĂ͵ăČüöŹś{îąfc‰¦‘a“ŃűďżfS<·ČďIn5L! „€B@!  °C‡„o¬śĹyĆö(l¨ąč˘‹ŘĽĂIO–h¦(¸nÝj«­’b)(Aě@+źľŘb‹YÜoŚY )áaá–˛ŘéĂYČ1Ë4’Vy‚D ‰Ô:ř¬ ÓĎ-Ňžäö§QĂ„€B@! „€B €ľHĚĂ«G„3kp Bť…©ÚöČ|ńĹاßÜ ŕëłľxąČsĚ;݇=>¦é`GĄ0-±-<V•$bÚ“·Ţz+|4óĚ3Ç˙FĎ‚˘ççź6šafĹ󉀴'ůü]Ô*! „€B@! „€hA€M:)}¬®ĽňĘóĚ3ĎG}tŰm·í±Ç~OĘm;%oiG—.¶×mČlłÍ¦[ÜNâ!ÝŽ+NfVJ! ż' ôc©©B@! „€B@!Đ č5¶ß~{2™§XćČôoĽq+%ŁÇ1#‘d‘i§ť–D”21×°–ÓNö™oľů‚­Ň 3+žO¤=Éçď˘V ! „€B@! „@ŤöäńÇ˙ꫯL‡‚—Ů)§ś˛Fr“[`Lňî»ďNţÄÝ˝ňĘ+\9˝8ůH) Ť€vîdđó±Q «°wŢyë¬yçť9™i¦™2 ŰůHŕqú>a†`çűńŰÚc‰!«¸1[tŃEµ˛ŃVfRůvA@/|!Đ.ŚÖ<•0Ěá,sÔ¨Q8_Ŕ#Ăâ‹/Ţ»wďćéžz"ꀓ"üŹpNđ­·Ţj§íx·˛mŻ ÄŮ §sJń€B‚ĚÇ|đAR6Ř`0]ń&@@¶'mú9¤Šó˝qD„öqýő×ßf›m–_~y­łÎ:Ź<ňHŚôż˙ýovĐ%Ž‹l”ŁĎ>űlXuŚĎ|Ćg„ŹbńĂ;Ěçd6{»=ćcČĽđ ÇŇ;öGÓ bBŔk¨rg;¶ťŞ˝Ţ”ĎáůúëŻ}KŞĂ< +®¸˘/ž>ňĂ?Xí “éKµCN–SxŤ°í–ÉôŻżţÚ5ŞŠ¶ Ŕ ß©ÂőĐCmK9/Űž/| y9g5/ /ľřâJ+­ÔŻ_?OÝn»í6Ůd“ĺ–[nÖYgĺ¤v"¤ˇPż<ř•ŔŹćťwŢYż*DY´órrâ‰'Ž=vĹélŚšů")i?Ë™Ľ=î¸ăHĽâŠ+îąç˙ô·ß~gř¨dśSĘÉüÍ7ß”|Új⦛nJŻQâ¶šłŞ ~ÎĐ ¤ďČđ¤*čš,s91ńnXĹ:^­â 1'^é1´Ú[ŐQ–$Ȣ˛sŔ”|Zs"Ťać5ÂÄ­¨ OjF˛Ý Â~1~NŢš˙vkR;WÔž/| yíü㪺l`ŚűÇ?ţÁô— ĽíyĎłÄý»ßýŽ­ĽI.˝ôR±ôťmĄUQŁ…LD«*˘ĚB =`m›ł‡MϸÓN;%§I¦Oa)šIZrń»rS9~%sNĚa xłÍ62dČľűî»ôŇKß{|töŮg'««LPOóŹ€vîÔţťvÚiśăŤŐÖżţő/ĚŔP˝-Ś*ąE!ň÷ż˙ťĄŕµ×^;VÇsĎ=‡DůDλ˘Č…^řÚkŻ :t•UVůÓźţäźZ„˝sożýöB -Kç–ej2˝N)tůűďż§kŮŇç81âC›ŁÚłĄ,j ŠŇ+x&÷Tł¶?,ěď{ŕĆŤ—mŐĎ?˙-™ą éŚyČy´h"ĐŞ$+Çg¶8ĂBJ,[ŹŃmŔ–náWc\ŕµĚ{ž—›w ś’shCĘśXM˘4gĂ6oűm·Ý4lľç!Ĺ«›&±Ł;Ö5>óH?äC|z’c+żđ)†Ç*câkŻѧ!Ż{äçžbzč!ÚĂ,…O»r ăĄ}ě±ÇbśÂâąĎSRúěiš™/Pöß YşgÖÄ Â:_X‘Ż‘Ć/Ěcůĺ S[şfP\t·ß~; sţi‡4F•6˛=©ńGdaŔřE&«pl˝ńëĚF‘OBUÔÍP…!'FŠQg K8ţřăCš¤p»ŐV[±2¦×Çť’ůcĐĄw| ˘z`˛‹É\AűŢc,gč%ÎDŮÔ=ú>–xë–k^ĺôc+żđ«â±’TnI쩆< y1–ČŰ­_0CmQˇmŚ&vęG2OLú,Cú™ůyó°ßqĄ5Úaňý÷ߏ‚ő?˙ů“Ŕ°ĆÓO?ťIë[(ô™Î=ţřăĽ7X‡§Ś|C o7Xî…Ëř" ŇĂ?<4Űl·f¨˘ćC@Ú“ÚSTś‡Ĺuą˘CáH9´›ŐE}€9†ťCά8s_ćŻ(JpqjOĐض´'XSÇJU{Ë1:,/ \ŘpĂ ­,ţ\0čŕ.ÖС°úA:š¶đ°.íŤÓŘ­¨NPg°/×&d(Ghę^@Úx3Ě3;ÇůÇvZfŢhXź˘¬áŤüV;Ł/űsOxX:Ú>MY<ôÚFq†mrŇB(Xqvú@űs6ătŤDt@ôŽ>BĎWËöŘcʎ™|u3? Ūе6ř”‚ë’eůěőqŠa˛®ô)č1ŹBهr„R#GŽäU€PpZl‰RďľűîCĂrĐAÁ–Ä=ĺjŮ2)>Ľx?0g ÉrŞ„ý˘%źß¨N8 ĺ/+kć]¨N0²7€%ň©Ś…ţçwß}wľx«•qß;E* €:8<ŕ0̉94ŹGkŚJFÂ:Ďď˝JĎ9)sÂź¨Nŕ>|cŘ/Ŕ^nV¶Y'¨mŢ™äŘ’/üjy¬$&ľŮi"ň4äĄá“ĚcÖ»l¨ŕ@˝ró’Ň—~fe”Qť0żâ%`·hęYcRÇČËa"aíĽ78O€ÉˇÍ÷}1Ńbb¤aNĹ…@ű ŔZ/ź!V>GbN*ۧ ŞĄ)ĐÎťÚVD‘/sóÔČ©7(L<²ţĚwž–ËٰśË‰Y>0Ŕ0:27e1 s•đĐbß8Ô ź,\3tůDTűUš“źŘ–şŻ:gnqe#@ąÝIV#+ŘżŔç–_ËbřD×C›ńobJ_ß0<Ľ ł`ö™ýŁ0Â*9YâU'd`Ů„+PřĚěôjöéř-?<âc„‰PWľ lüfłWťÎwřQGEŰ® ůAŤÜ Č]ŘČšĹ0$Ňö8 Á«®şĘT'PCLĹYSâ5°eJńÁ˘„· ŻŻ:ˇhxi'/>¬ šŇ– ®˝Ę¬µ|ß"ÂhělňjeĽB—őČ#€7ÉŢ–;1‘) Ż/TĂ^u’žsŇç´Áūլť¨Ď0§Â-%*~ßňŞ")9¶ZKbRU«,ł†Ľ@S‘vCŔ^Ôě•‹ŐČě}:É`žÂĚIéK?ł2:(ÜC-Š]łóe,¶hÇl Ç+~©ŚuDvRC„µ„°IŠ vC€oMQ  Ľä’Kj[h·ÖŞ˘B@¶'mú±Yr813]LŃepđ0S:ڱá'`[ÚžŃ+VÇ 7ÜK±[Śđů†÷őa>°Ia}•Ł—=ňŰvÂś5ÇyËx»#ÂćUŢ5(&X=¨@–ožršş5-3ćLÄyŠ?ćßž:&˙‘é“‘ŕŔ2–ŽIËŁŹ>Jb¨™˛lab;žp3ÁŔo. źzę)vR`ż‡Ç–M`ç[‘žNŮ—ĆŔéŔ[ć^X=$0×\sĹkĂ‘6Ţ˘Ş‹ ĚřŚ@oXYvj`Ë”âcVi±NaĄ…™ ‰^|Lvx˝đyfĆđw“ctÁ¤W+ă!)ĹË!ŔƨPcfłÍ†>…7^Eü-‘ôś“>'ŠxĚúÎ:ë,öNnľůć¦wăýiúµ°öŞâ)9¶ZKbRU«Č¬!OC^µ<ÓÎůY|˘Ć¤ &ëU,Ý%Pŕ®(LOJ_ú™•ŃaĘ›Y±…ăD&c(wL?b9q°˛™Cb^ÇÔ+l’âB Ý`VĆ‚D»U§Š:Ňž´ő·fЉq„ŮG°Ą…]¦¸ÓC?‚U˶ <(Pb#ĘСCC âÍžRěů1—¨Đ–âŃž 11oލilRKz…Ré1ŹŹŤ‘؆ á ¶U cĆĄmbĚˆG[RŘD¦ă!Ľm5¤|…bĺŽŰlAc#1UëĐä ;¸PńZk$?Vě#„Úů’¤ăţĐNiOZý9Ú-fi´lÖžÄ0ŰŽŔl1‚|›‘’FvŞbËŞÄǶ˘41ńác)ÖRh$/źŘ;ŠÄСZŹAˇŰ’ yGUQňQ,eVě *ý -}N¬îíSĂŘB˘PĂX O(U±\¬ĺܦ,^-Ź%1IV]9ECž†ĽĘŇáOYBŔx6éç›76»DĂć±Íą¤ťcé«<łňı§öq‹ŕn ×űµ1|„Úć±±śiÁXÝ ! ňŹ€´'YţF 20_ÄfŹ!,íâ ‘S ÂjpŘ‘ţłĐ„,Ą®pýÓV(cšÁŔ†µ¤ĎÓ–ŤsŐR@—Á J)VŞ %‹űQěiĚDĄdKÄĐŽ)‚߬DAT$ĚćqzâKů]E¶%Á§Ç"ö•ČZzÉóz,s¬ť1 şmRŠa¶Ý©M|j`Ë”âeŢBXŔy®ĆŠ1,Фřľ›řT–ťdÜÓW$’?zzÎIź“·+§Čă];gŢę<0ÚÇď'1ë¤dżbŠ9ź!Ůx˙ČGjŕ±4d=ý’‘Úd¶®MŐWň—ę´‰8̢ďhOXÝ ·ŘâÍ)Ĺ!,ĺ&6%Ĺ$ ›yâIí ŹP đŠđ‹eNÚY{"Š! š iOjü51a`˘‰#t6}$I°Ě`†+,DPvÄ´'ÉüiR0áȶö°yíI¶Űvh@86§iŹĺÁÂś#l7łôç‘’AŁdzĺDxó ‹ý8łÄÁŚ©®1ŃžřÖzwżˇ$YsŹ©áV2OrKHÉlJĚí/†ĺúî˛\†’éubK&µXñKs›ÚX´ş#´'ľµ&>•e§~2^%¦A =ç¤ĎI˝¬uŁôÇ&źŃ =.‡qΊ%®µ±«°ŽMŮšŁP¶CxĚKAŔ}žú5UCžYCŔ´'śPţä“OVP_2Ă,7%h)ŮĚS‹©H,Űj"ţxDK¬M |EŠ! iOjüĄX ŕ\OvĄ–Ôž@,m1ˇLšÄ×Xe—.lŇA{b›wđJ ť¬¶íÔÜ$Ôě–ç&ÜX“Ćčŕu’ĂÂmJ± nm-…Ó|.ľřâ0[lÓ}Ćl~VŃcűnXf§,‹$¬¦Ú0OŮd#)k;ŚjkgŘ6ĹŰĂ űX'¶d· ŞŢ<ĚącűcâcëŠŢ€+ě'UaÝĆţvtµu’ń°:Ĺ«B =ç¤ĚÉ»ŘFĘ4ŢꜼCŔu‡ă(M©ŘˇöÄľ‘’–&ŢqU±ĚőGjhLĺ"őkކĽĘČw§ă!NÉÁQkí łA&`)ńIÉfž.ábjS¬NĚ!K,ÝQD!ĐÜčĚť_ó˛ÁWÇ‹/ľX’źî¶ÇÔłd†Ů…ÎB"fś'ťtöìKp´G t˛-b[‡’^*±»aˇ›Ýé¸k©ˇF[KYqĹceů2$…ĎfKGKent٤ËÉéE„P¤/µÔR\Ůą;Ě‚DÜÔÓH¬ÓcĹu›:D 3„ĄNli˛WÇT'|ßânö{ńáč+n14·óňĐCqN9§ˇ|ä¶N2e…ÚHĎ9)s˘é†a8Ó'ćdź'‘4Ňľ—’šćĂ–cbůć›o†)ŐĆÇęÔT yŐňLÓçÇ5‡…ÓÍaÆÝqÇ%űË gź}ö)ů¨dbJ6óeÍł¸ż%bkŮHžôöfSĽ)`ů–-ZÉŔ̢9o”éDv|Ą•V˘mţhś‘skoěj[#…Í;¤Â#;«%XC~vUS©-–×P\Eꇀ´'5b‹_=¶PS]pŁÂ·IäëŲĹ2ÔvËŽB ,Ú®bxb{Ĺm¶^śp ,DZĘ}ŃEů~±€“€™aă]¬¶v˛Ü 5ľßK†“ă »`˛}żNX'¶4Ůá3Ŕ|ű‘YÎí˛[/>¤`Z‚´ţőŻőÚ?ýô“MŮŃ~Úü¸N2îۦHµ¤çś”9™˘ŮJ2{0ĂĆphšRüţS†[”Î~«F+ÉłĚB"iâąĺ1 yi~>ĺ©8bÉřśđË/ż„á˘ű‰V^!ž~feD8™ŘÎò[ľŤ˙ńŹ·1˘BEzÔ”Ŕ,C&Z< ™‡łäÉĘeGőťeÚĆĎŔ\‹[sÎXm“b¤¬ăµ‘JY5_+8¸d«¬ĎOuaw|ş"Ž€vîÔřŕË“ t“Ě 9‹ !.ÇůbAe`6̬ăˇFÉö›MJ łšŢj«­jl}Š­ľúęĽŃ80lóŠ\sÍ5™syä‘Çw`X `kĂ×ëĽI©çŇK/E']C…CËŠ çŃg0ßś(h¸rĂ9 ˇűî»/§ńń”=ůśµ|ÓM7ńęˇ=ü|(rL•BdťuÖ±Ú9껜ř˘‡† ^Tř™ĐéŇZľ°Qݎ‘*ұÔ,†pHlź—ďČL3ÍÄdÔßfAv öé§źÂoLyŮÎm=ŘG'Ľ‹8Ł ĺ§H˘ĂE“8bÄ IÖ[o=<ńa*pಠăÜsĎeŔF40dăśNÚ"z%>Ů'hÝŻ“Śq]kC =ç¤ĚyĘ)§đ…Ƨ•đ**ăô„!ŚS®ŃŁá|ĘÚ SÁ?Ż˝öu+ŻĽňčŃŁŮÄŠť˛mY"Ë-ŹiČ«Ť?U*X3c ‰ďd&Zč,DŹ)SMŰtĽŰn»ÁĄ¶>ÔjĄ)gV~|Ä$ŤE;,¦»´cą8‡‘‘"y|a«U+C3!Ŕkßü¦Y§ŘżŹ8âĽĂÚ"¶§Ĺ‡«âČ@˙ţý}b&ĆHÎÎŔzIfQ1šUAQL ”š ­ŃŮF´Ç{đ F0‚(2Ž×Ľq —ň¨˘Î8ă ´0¦Aßv†9:ły¦é|ő1˘ŰŽ<éňí‡eŠ?ú‡źÇ ¸Ěô˝cťŁ[±1a!Ĺ>\y„őéŃGÍ<§Ľ>§" „@‡amřŕd]ⲕÝÔ-a~d»í¶Ă´Ęö͡±Ź^üˇ`BŘýŽö„6đaĚ4Ů9űŰyŹY«ú zá]Ż F•2ŇsNĘśhźQLăÉ Ť ÁăŚ]ÉŮgźÍWśĄŘ©gĽH™.›nřvbQş-Úç“Ç4äyNP¤C`’Ă)Çx?AëMś`-aLa 퉩QŇ4/ĺĚĘkOn»í6VËŘňŚ.ŐčŁHĹBM>bÓ ÝÄyŕ˝đđPFtjěÜaZÎD‚cÚšL{žťv޶óhY7·äÜmfŘ8l" ČSp,¦¸˘Ąć–8–TÄ ,ősĹJśI<çѲ {ů—ă#‚\­ qň§Ô„ń~üéGP„ë/?˙§2ë¨Ě´°wȰń5“b1™EVłq˛Čę.ůČXż~ýj&ó‚ü4ś‚Éb#ăkhYĂÄéÂ,Yd‘L^4¸cŔnśßťu€5dŕô)L#Uŕ÷ÄĂE ź…,ąłđNĘýdŔ4Ž©˙ěłĎŽ6 “uOˇĂ#¬)˝ţúëţËźńč½zöš˘7_ľS ÜáÖ…îҵ[W>fpńČ•ILř+€•%ź8é—_A~sRčÄ”"ţéçç_xţúë®ç°$l|:Ľďml@Ł!ŚÇ‹‚ÓpbŚ—9[ň[?ýôÓ*Ó&4p‘!ŚîCšüüŘŇŁ8 ?ŁĺÔľőń6ţîĺŠó‘Ŕ.s¸ŢS:)˘kČKź)űtďŃ}Š^Sp%ńA %„ČDÉبÄ0DÄ…˘!GH±Ś+Ş' q*‘ľrMŞSzzÎI““­:Ľ™ţb3ŚM%o$ŢĄÉ–ş9F=^¶äńş•dÎjSrČcť|ČĂ®CW~h ?űöëËoͰëD©O¤ÉB|%â O66!D$ž|ŇÉě´ĺc›o*2SŠĚžP)Î<«/g1ŚÄoB$s…É$/77žýöjh®8§'…7ťăŰţ2X-“×–ź>"t¬đc‰J”ĎWżź®Z‚­Î¬¨ËľŤÍN“}L€šĺŠ’/„jĐčůmކ®™‰.ĚĂް4[|ή¶ń…«Ť/mě¸Íî¸"ö‰Ä•‘afG˘—~,ŇQŁůĘđs‰ŐbóKŔŽ’P{âűe#/«Ľ,súD")_ŘŹ#ţ|(á+ś¸’–#ď3iaćĎ0„î =–ŚMöÇ\ý#‹°ŚŠ€ŕńĐyË-·@ĚŻ ůüŕ)–ŔYŠŽÍ…J’sŠŘ›Ť Ŕ‹ť§‹ĐµŘfşĘ݇1&‹Äčˇř~¨‘zAŔż}EĽ©Á“ R‰­¨Df€ŕ:ÖҸeÁ›Só Ă#´ ‹´1nÍ٨‚Şí=OGěmońP"hˇŤUwHqŮžd;–Ť d@«H0<0r$[Ęô'”ć‡2ů´¶Ţz„XY„Ą[,‘[0ľ ÉGa ł@B˘x Đ(bÎŽĆżÎ[~@ ‚–Š čSŘ‹—±m¶ŮĆWÁ Ç.»ěz#B%ˇ=†*|Y6|ÜŇZŚť‰°K€#óPÄđb•Śv‰ÜT¤¤=©4B@! „€B@ř$†úŔk"ößö𹎎ívO(A0Ů{ď˝Q˛52ÄŐ_ű¦:á©=ÂHd 6@k@q\˘OA™‚q 'E ë§Ftî!‘ qĚsŘŁŠ6ŤeQ#b1;[ř±ÉĹ×›W@T Â#Ú€(–âXˇ’ŧ龭łaU q”•%×Ř Ś)Öâ¸5Ŕú ÓZ4GěĽĆĘ—ŇÇĂýň­ÂŹőlú…‡2ě}č):vsc‚2ËgS¤ZP®ˇ°Š! „€B@! „@§E˙¦XI°Yđłf8°ÄÎqĂV “áÇcÓž XAí2dČ]wÝŐoĚáô T'Áߢ™˘@ ęŹwŢyM []<ĺĘ´¨NpţJ{Ľ{vĄ±Ă—ĆcşŽ…Ke öÍV!±ś´Ůô/8łG)»OÉφ¶đ ÁńڞżĹ`Ő ”Đ•x¶ ‰R 5ĘYgť:ťekyčŻ7“ᨠO®¸â ¬oСx˛ŠT‹@Cn7޶“Ę/„€B@! „€mD€­.;MÇkâ ă "üˇĹx8f7(']†ŞŞĆ"«ťO¶ă J˘9ăźbx’< GŞa‹sF„9¦MIf¶6¶ŕ˙m5ć[$ĚFł1ëŕäA45%ťČ†™“ńűS>Içjk-OµÝORS°7A9ĹqhŁÂt⦯ÁÔ…ŤQř“¶§¸Śe·TWeř‹1lyÂtĹ«E@Ú“jS~! „€B@!Đśूżćě›z•C‡ő*čńMŽWňE]G§%Éă›w°|ŰăąśĐb”̆3‘r;JlgJ#‚š#fgQ’`˙n1`I*hP( ¸A7Á)6ŐjOđ#‹WW¬f°ň8őÔSĂ}cEđę‚7N‘«şdŤťř ޶’=ů䓱mAé‰ý…ZĄ°‰ŐČžť1cĆnGŠĺIŢr@G˙  Â3K˙ţý“ÚŢý¦mɱý;a:q64YJÉfÄ2ë¶íÄMŚÚNQ„€B@! „€B Ó"`źú+®¸b t"¤ łĄ'oŤţPbŞ||ňÉ')‰YóÂ^›Gy$VÇSYcén/ĽđBv$‘|8µ§dζw?$kÎb.yX2í''fťuÖ°âuB@Ú“:+˛B@! „€ÍŔ;ďĽĂ ¬Î8㌠;ě°ĂŠ§Ç®ľBÎ6>âÜV*şőÖ[ŰH§Bń;3*’'}T(RůQ;´ąrô´}°Ť$W]uUX݉'žhGö¤Ńž…Ź?ţřńÇ÷DĐJlĽńĆv›†ĺÄädđŕÁÄ:č /ľřÂSĂí+ŇĘ-62ąřô ‘Ç{lź}ö!Ăßţö·=öŘŁ\ÎŞşonJLáR’ »ź–Xb ¶ íľűîˇě_Î?˙|ŠsĚ1% *1sÎÍ%ˇ IDAT¤=ÉRB@! „€h68Yµk W_}uąîńEwíµ×3~].[&éřA ˘_ý5j%‰pÄ,U”t¸P2xË-·p,{ÂÄvhsXťâ…ßůTŤ®łŽŁŹ>šÓ|Q({ě±{íµ^9ĆŽ»ďľűľôŇKš‡ŁNó!ę’vŘáČ#ŹÄĐ%§ä¬·Ţz¤_tŃE•ő!qŽ Â:ă•W^ACô8Фm±,»ě˛éµ(M (ăŮ„#“yáiUÝ7ô8ČKŇ:j¸¤=űěł97çŢ{ďĄý¨oN:é¤M7ÝdĐĎ4hPŘYĹ뇀üžÔ[QB@! „€hBřĂ#9SuŹJ“Öő±@_€ŇéĂ —¸9đŔÓ´Ő ů±1Áś ŇÁ+šŽ1ć4ß4DČáż–łśY™YÄTŐ}„׳ß}÷ňb62ÉƬ±ĆĎ>ű,ç ±q‰î[ěeN8ᄣŽ:Jnb“Ő)EÚ“:+˛B@! „€Mź|Ď?˙üŤ7ŢČwW˛{¤“Čjö /Ľ|šmJúólëm µFls[úŰ4eůŞ/÷a_˛Ź|Ďcî±çž{"l9YiĄ•ĐžXNľAŁ‚öÁT'›oľyą=8ŘYpŕ1IŽFKčˇ@Č€8sçő×_÷4GŽ6Ł$Í™fšéŽ;îřđñyÁ,côÁĆ´° ń©Ý˘ŕóŘáÇţ¶\$}÷ˇ@3ľüňK(ă†vţůç'Ĺ»Äă˝eÔ¨Qč’@ď§ź~ZrÉ%Ů×·oß0[¬µá#Š„·Š×†€´'µá¦RB@! „€ť|”Óž°§€Őu@á4ÓrÚÖŤ l`™m¶ŮYd®11'Î4ÓLĂÂ2_•d~ăŤ7ȉ©Kl…™ldŔŞß҉“âożúę++áÖß˙ţ÷öÍé+býď ЧźH„âÔNdşé¦‹ŐfłxÔŹŇák™…ô~řśÄ9Q•VŮ©«±6{˛ě†ŕcĎB¶BĐ`:óC‘OS‘G€Ý:„X3řeQ/ĆËÝb‚rË0Kb‰inŮ d‚ŇdncžôÝďÝ»7*·Z]Ź=ĐZÍ© uB@~Oę¬Č ! „€B@4!믿>‡›ľ…X÷†Î駬‡łH{Äí#8‚„%ôŤ6Úź śsÎ9˙ô§?±Á!ĚŚg‡f%÷Űn»ŤŐň…^ż\‰łćä,ľ¦ĚÚ…t¶0p‹; *˘|]˛Ď*=mă/ˡ!TÁ^źbäI'ŕ–"ö(Ľmµ#hŽ bf&Ď=÷q˙µkł‘EĺD#YZße—]Ř›€ŹOŚPQ…•¦‡%,Ą¸B C¤=ÉL‘B@! „€hrX%FĺA'Ů€몥lµŐVXXÄa©±Á<óĚ3hOpúxđÁŻşęŞ6lŘZk­žŁaqîK~üDŕ#ł_ż~˙ýďQÜŕő F9v‹ćw›ě>ŕŠĎ´ß˙=ĘšSO=5–ł¶Ű4ÁĚ˙—ô”*,NgËU‡’SŚqVYe•ż˙ýď;ďĽs˙ţýi˙ +¬pűí·ÇJŐ KŚŽn…€5 íI  ©B@! „@'E€­([o˝5ť÷F۶ö„zbč\zéĄl`AA€ÇŮsÎ9—¸˝Ä%Ů8 kŽX~¬EĐ}°g‡“k8h«śh˛¦Âq?F×’Řz`Er˙ý÷C„óYQťđCF>ýôÓX-5ܦé–2÷Ýwź;‚! ńË.»¬d]ěÖ9ůä“Ů%„űĎ'žxâ´ÓN»üňËQĐ`n†¸Ţ¤ËaÁša ‰(.„€¨ iOjĂMĄ„€B@! :)X‘ ËŔ „ý5´!¨*đtPrŰ.!gśqFśhboâ‹°yÇ\$-JHżęŞ«ĚWůŮ·b®P7řâĺ"ôľ0QLüë_˙ÂŃć-gžyfą"éÓ«íHeʇ~8Z¶2q­Ď‰_ŚëŻżß+č€Î?˙|źN¤-°„tB@Ô€€´'5€¦"B@! „€ť4 śśJ˙Cóżm§$.ĄŕĆuŰm· źr„*§·’’ÜéłÓN;ái5ĚŚ/Un1` “qNfĹÂ%Lg×jR8°#LŻ-^mG*×ňĐC‘sdcŮpsk˛Ä@©–}Ý ! j@@gîÔšŠ! „€B@tjŘĽĂ.4&l< (ŘbCÄ6ő”†c°Ş@iÂy«śśŠű€JfF KÇÚ…”rů}ć\ĐÇ}ÄŽó :źŇĆHúŽT¨Ósř‚żŘd6´'?üpĚ*§fX’ô•"„€¨iOŞELů…€B@! :;xEe[ úĽ´r ĚŁŹ>Ši š ‹) 9ńŰzÝu×y±ś‰Ăů2O=őš”dÓ•$Ó[M)©=áÜb úŞËiU5CÁj;R®.Ňß˙}®ě-JŰLşµo˛!…ša ‰(.„€¨ É k#ˇRB@! „€B S!Đ«W/<›ŇeŰĽSyŰj \Ą\rÉ%řs=î¸ăĐp$0{vp;óĚ3C B ˝dJ,CąŰ’*˛ˇ…*WĘұ(©śˇ†ŽT h^]&Mšs kElO~dB 5ĂQ\!P˛=© 7•B@! „€čÔ°I‡blóέ·Ţ ĺ¶í<řŕś#3Ô'ź|ržyć Qc÷JxŰöxĚQ|÷Ýw‰ŘÂľŠ¤ĄIl›ŚĎé#Ůvd@‚ö„ć 0Ŕ×b'"ÂéűtÝ ! : ŮžtňŞW! „€B Ŕ+¶$üńI'ťôß˙ţ—cz9§dLy1ÇsÄT'h+>ů䊠A(Y°†DÔ41Ť #×\s ¤hˇDmA„“’c ËVˇŇl;‚óÝEY„ęPBĹ*O45$bł{¤[! „@G! íIG!Żz…€B@! =zlľůćtí ×r†'<˛í'čY8ŐŘwM„ÜCJ†Ú“ß~űm‹-¶řő×_­"n9 ŤBsĎ=÷®»îj‰8j!ňóĎ?‡j‹ˇC‡Ţ}÷Ý–ˇÜµŞŽŹ’Ź>ú6”#Č>&]qĹ÷ÜsŹĎCţÁsĹ›,‡űtE„€‹€´'‹żjB@! „€hTLcb[mµUąn¬˝öÚóÎ;/OQ—ě°ĂGyäę«ŻŽˇ Ż·Ţz¤_tŃEgśqFąâUĄcáňěłĎbäBEűďż? +ŻĽ’ 2(J¦žzj#…ĂÚVXř{ěÁńĆôböŮg?ôĐC·ÜrKüąT¨®ŞŽĐGH}úé§(k’g[-Ô¸Î:ë Ç4hĐf›m6dČ}÷ÝĎ»÷Ţ{/­=űěłĺč¤ÂϡGB@´3Ňž´3ŕŞN! „€B I@A€&‚Î,ľřâ‹.şhą^a…c6Îŕ•sŽ9äVĎ?˙üńÇ?ĺ”Sr†ńyçťW®xUék¬±¦ŘžPÚ‡×_Ç´¨NÖ\sÍę Źúfřđá¸náŔ =÷Ü= )a¶XĽŞŽpúŹYŽĐ»Ç{,FĘß6ěđçŢŰn»í裏>÷Üs_{í5ŽXśUW]ŐgSD!ĐáČkl‡˙j€B@! „@Ţ@÷‘Ü_Ó­[7;&Özě)b™±§xőŐWź~úiNüĹ{ërË-7ĹSP o©śXŚŽť5FÄ<ˇÄr‹m!L/—sÇwÄđŻ«/żü26/T‘<čwši¦á”ĺ˙ýď/˝ôöhL ŰeĂÖ¤š;BSďĽóNś° š±ă‡II¶™ P¨“<đ@Zűć›o‚Ă’K.i¦:i:›„%,Ą¸B C¤=ÉL‘B@! „€Ą`S ć„ŘcÔ¦ąĄ·ĺµÎ˘P™ČôÓOżÖZkUΓ|ZUGŘDH‰ĄĚ8ăŚl "ÄŇu+„€ČÚą“źßB-B@! „€B@! ň€´'yüUÔ&! „€B@! „€B ?H{’źßB-B@! „€B@! ň€üžäńWQ›„€B@! „@UpŔŰn»-DŞ*ĄĚB@!iORĄlB@! „€B żpZ !żíSË„€ Ž€vî4ř¨ć ! „€B@! „€uF@Ú“:,ňB@! „€B@! „@# íI×(48’jľhoJ Ž%rmďÖ¨>!ĐČ”—ŘE˘ÔČż«ÚŢ4eRs†¤2iŹjȇ3$Um/”_d‹@C3s.´'ţ÷0(ݵK-N[[Ň5•ő`)ŇÔ8ŕ·HŠ=u7ÝÜל—â“řß– Qć˘$‹NN6^X÷B ™0čRšBĎLZ$©’ŠÄ¤É„¨ʍ¸8˘˙Íú"Ę!`üośoyL’,ÝreŰ’îë…Hˇ®śO'Ňú*+jCŔ8°[77©ň[Š= ůbý­EÚX‹Š ™ĐЇ)ÍÁ™ůŇžÔđ#©B@! „€B@! ꊀ´'u…WÄ…€B@! „€B@†G@Ú“†˙ Ő! „€B@! „€B ®H{RWxE\! „€B@! „€hxF{Ňnfž_ÔvGŔqľwúšE펞‚čdd>‚d.ťěQw?‚d;0ŐGćB]CTDůáĆü´DĽŃih&šô‹Ła´'“˘P`D}ýuZ‰ěgĄŽń»LʰߎžWŤd)ChE*<@ŠśźE3c‚)QĘTŃČ7‘4ů$Ű©†žÇ„ÚĎ×k Ą"B B–‹qc Ô˛*¶$laVôEGT@ŔX®eđ_Ę4ࣆўđ{ŘOŇ€ «ÉB v"ľ/~ÖN¦Ą¤ä¨ Ĺ: NŽ2]‰Če)ťć§PG/G®1t2©P7öŁÖw(ůáĆü´¤CUŢ‘ř7łŹtdkęPw޵'÷âŐŢ\»wď?ýôSI!Đ‘üřăŹTď8¶/r>cţ¶´,FÁHJ”Ú©Ęć/JŽó#*´6şicË'“¦HT{ôča450µ[Ď“‰RÄú…f!J5w6”A‹KkS«EŔ„–Kň!)ŐRË$É–hŽ— ¶"Ň*冉-[%Ň@ň«=q/ ű—€łoźľ¤}öŮg‰'JŤŤŔ1cč@ßľŽĂcˇ-ď ’eI´Š$J1¨uŰTĄP™RMWKĘHďÝ»w·nn<•4U¨ň6Dɵ>ҡ íÓ“ 2اOűV” ¶ĎoŃ™k1ˇčׯ_„r,šĚ™UŠŐXR§šj*j‘Ddµč”CŔ$Âř-™§‹&37DJľ´'-řFă±MFIdDěÖŐ5•dg™eâ/ĽđBC@¬F ”Ś5ę—_~a5c†f0Y€Ű[„"úHó·.‚@” Ĺ m”˝ř­čn"zN˛˘˘&JŁGʶ_bJ †Ŕĉ_zé%=ËĚł DĽßŤˇÄÝš(ąń$’ ’*|űYž–Śn *aXbhŠĘvďŃ}¦™f‚˛¦ă5·5ŚĄgžećHNśř¸)Y÷Âě±0HŇ˝Şź»z'^‰xˇfčśm¶Ů .¬b¨?UceŚ ,ĄÉąŐÝUC>UŢXÔnő:Ů,ƉĚ9眤K"RaŞLm@Ŕx ~3΄¬H0’^:<ß¶ˇŞ\Í—öHü[ĆMlÝýä)QZ˙ţýÉöfr˘!˛@ŕ¶ŰnĚ<óĚSÁ´E@ZŹ}΂$q‰îśíɬłÎJĄwÜqG= ! žzꩯľúŞWŻ^sĎ=·±şg~±©lqBëUnzŤx‘Ja˘LŮůź«IqeRz*v˘Ý{ď˝´vů0®Or~R×~Ĺe°8˘9yŚâ‹.ş( ÖőWqc°…Z¨gĎžž÷€ĹâĆŠvµÄ:!«Âj·ş||‘E!®ĎĄ:ý"křab±Ĺ3ŢăcĹ0Ą pË‹öÄŕPď§—¸˙ ÜŘĚ?úśţŞŰTSOĹk‹ §śrJüę‚ďż˙ţ˙ţď˙üa™?°¬çţEÜno/ ^@,âÇcčS|Nů⎤3@q´]čŢŤęČđĎţó·ß~óD Ť€ ‹/ľxŻ)zĆ DZDˇ¨;):^p|Çc)”—ŁÂÝGbä¤u™?,CŮ›oľůí·ßöD ŤŔąçžË†ö馛nľţóÁďđą3`ôrE|ËŤJ>Cµ“8_j2´gŃŐÉ`´äľęŞ«’Y2čS$süTm•UV‰ף©Z4ł˘.Ď•~V?ˇđU„őZ ÓN;í’K.I}.eÎ "č°aóŰ…^¸ČzS,/>sćá)·g$/Úßg€.Ä‹íÖ˙¶ő`ŕŔ¤_}őŐO>ů¤/«h\Ž>úč/żürĆg\z©ĄM Â/4ß// >âĹ">ŹXwM~ą%ľü—gďî{ď˝wÚi§Ĺ(čV4"·ß~;«ĺĚk×Xc 8܆ ĎóľG<±¸ŹřG%#±lܤĄ.]çšk®ßýîw&LŘwß}Ů:T’…@!đᇞ|ňÉ4xŤ5×°9±ń|\šŠł5žÖµw1úŚţP/1L^j©Ą$uý:9q›Şa´»ŇJ+CĆřĐđ±GĆ–uB¬\ľ=Č,ńM6Ů„čs©Nż‚ČúabĐ Aá0a|čń)Ç®>CcEr§=>/ů-żVnkć]»Í9לK/˝4¬Í6Űěý÷ßo,ĐŐZ!CŕňË/?űěłI\wÝu{ôŚĽ¸3ęlďÔöż(1 %o‹yŁżĹâţíf#kď){Ż˝öÚ?ꨣîĽóÎ’t”(˙üç?¦µË/żü 3ÎP0<‰ÖĚĂÇ—Cśh¤ęZ¤pŚr;I´ŻÇąHTť´vď¶ö:k#ż÷ß˙!‡’Ь2 Ľ"đí·ßnĽńĆ\ŮĘÎňµ &P6v8Ů)ĘE\źR‡N9éK„B«ŠĐ™nľůćě§ ÖáÉ.~޶ŐV[ÁfEľků›ŕĐtăK­Đ&«kiJ1†JEŹ>—jĹXĺ*!ŕ‡ ŘŚIW‘éZţ&Y´ąĆy–#í n†uK<ňë‹sV7OíÚm 7ŔCŘرcůÁdŇ8,§–N†CÚ!CvÝuWRW[mµ…~·śn/Çö.ö?*mSÖ(ZââdĹ´VÖŤČŠűZ–Zz©e—[Ö×óÎ;ŻE% F@`ذa+ŻĽň¸qăć›oľk ŚŠ·ŰxŢ„ ’‡‚¦ŢzfRS˛—V–G®T$†…ĚZĄş™gžyÓM6%çé§źľË.»ŕş$A% ś#đÎ;ď0ł9r$–‰[o˝uŹî‘Nż &îŠ@YG aăNq.—a­JZ$ykĂ×ŮgźŃ#§d0CüE*śŞýéOúýď×yž ůÓóŚš-€MŇ·şh’okáöŰoŹ 0}.eű+š&¦™fš=öŘŹŤ1öó<éŮŐGxÔĐćH{Ž6m×\ťD‡¸ß€Éiô^p\»wë=Eď­·Ůó9ĽňŮąÓN;ᩡ 5ľS!0~üř{îąg™e–Á”Ž/7`ąŐW_ťI*ĚířŰF˝HSč9ßIűzsÁE*Ľ|‚ÇVČ P"’ĄW•®żŢú‹/±8Ď{ď˝7»y}ôQm=0śum^yĺÖś™Ô˛)ťiâć[lŢłGĎżÝ!;ŽÝáű(HÜIOqđvÉĺe)ö”[ÇÇMZ©± 9ZgÝuxtĹW°řŞ«®ÂˇZC`¨F ŕpS,§–Xb &TSO=ővŰo7Í´Ó8©!DWA<óG’T•H-/J5Ă UG¸d0:BËâ®uŚfÝş10`Ŕ–[nI\2XÄLkG 6Ucž¶ŃFÁf𛱜ç@‹DÜÚ±v[{őeJ†d-Ní´‡xŘž¨ŤÝ{÷î˝çž{˛·TźKeŕTru„Ă^±öŮgŽ 5q…n´Ű$»VW_ţr÷Č_“lZë vٰŤĚĹ×űŇëŃw™ű=şw›fęivĽĂ}÷ŢÇůaLR ĚV—]vY¦śrĘvMM đż˙ýŹC‚üq"Ür2ČZk­ĹnmÔîĚéOÜ·žmÎ) ą3ˇ(F(‹âC+nO–H÷I®Ňž˝znô§Ťfžić'žxbřđák®ą&GńˇF™cŽ9đ:–¦*ĺíŹŔ?üŔ(ţěłĎÚţMŘűřŇÄdŃńvńkĘ1$Pd řaĄp“®Ýľ Ů-Y$Ť8uu™Ô…8Ő.»Ě˛Ě'†Ý=ŚýŔ¨őY“aÂ=ďĽóâSÍTůCŕ×_ĺÜú×^{íůçź·ÖqúŰĆ6ž~şém@‚Ă]Źir˛ÔbRďn9ŤYÄI\Pýó×ä‘îcq"vÝu×IëýŁ41ýŘTŤaeÓM7]qĹů ńLâ9¶´«ń'׺âăkń‘¨î‚X #ůč>ýôÓď·ß~7Ţx#®ĎĄşţ(ML܆ ľ¸ýŘá˛ăŽ;2·Íŕ:XθÎóˇçLi|2Öž€¸€c!•„©\şËÉ0<)ŚŁ‘:–Ůň۸ˇqB7–ĘÇwĎŇâÄ yťm°ÁlĘ}ęé§>úđ#ťË•\)ąE˝ Ç‚üńŹd`łˇÎŢ;.Îżčeä>ú˘˙& ţjsÖr]#ۤ.Ĺ#B˘˝oŘ’xRÄ- ST ü5Đ’\ŕŮgž}ăŤ7ľřâ N.(G_éB WŔŇýçďżŇŠ+ˇ:‡“ îOw7Í5V'BđcŠ}ôŮ××Jˇk4¨M,Dz"bÝ+Oš8‰+¨˛\9Ţu·?ďöâ /ľüň˨xěĚ×JUč™Č ô®°Â .´ #”"‚ S¤<ŐŤů%ÇË”¨d?Lč’é¤ŘŁŘ5™“ Nî&N´śV)Wc2hͤ "Ë•ł3=ôPÖ8ż“4É`UĄ¤D€Ťĺ–[ŽU%ľť4DÁXŽ«—’cf»MYQúl%łŻË×5Á}Ä2µŁaÖHÚ‹z±Oź>Űn»-;ňxŕ†ÓçRz´•3‰¦L¬T±…mŠ)¦0‰ŕjâ`Ś+1őüé96I°±R2Öž$;oHYzJÔČĆ"žŤÄ ÎÄ”«űöă—¦Á…?Ľ˛&tď1ˇÇÄ™1ŁţćëoF:š­}?˙ô3o Ţ”˘j"-WHsÇkÇĄ)´Ž§běĂŕÁDŞőÜĘa¬ĺf•…2ÇĎÁ Ç-Ż~SőøcöŮfďŰŻŻqu¤/q{ĽnŃ ,ŹĆ#˘,HP‘r°­!\ Fv§DqÁ*rÚ“î=n!8í4Óâů’©ó§ź}ŠĺÇ~ä$cňř@âîj"$9Jó3Dyđ‚Aŕ×—e\ZĚ&—&/J‡ąe¨ž˛Ď”,2Ď9ÇśSO35śĚgžcl.Řp9.w|n™Éď"EGZ‘:‘Jß—›P,éČŰ—dT rÁ-Ô¨š+S ć©K.µäçźÎŞţwß~‡(1$%E‰ĚNš40Ąý%ş0ľŁ“Ľr¤.Ôą3–Ą#»AĆq2‹Í>bŃć»y0Ň+G˘TŕóHž€Ý‚II„‹Ę([ËĆ+—ňO­HxĄ%´Ť`:„‹wůíĘ›–ů=ĂŮčŃŁ?účŁoľů†7°É ]ÉiĂYńŐ)Ň€ť¬›10隸Řa±‹ 6Ż|ř®ĺbE¬¸żÖ@_Wsµŕ[ćLąžwŢywÝuW>”>řŕĆ&›á#&&á5Ű.P#Żn^2Ľm˛Ą\ŽgYR×TSM,aÜťbIA JĄľ}ű†ŹŇÄťěĎ?˙śŇ¤xíýżÎ4ô;6ěD«g*^Ştą˙ţ\[ÔëE&ó\G~â\CőńŽí]&µ×]{’˛•ö#Yfâ“X8ʦ¨ëčcĎ~†IÝťí q~)ćO ě¨N`bŮxÍńQŠ<°0Č˙ÄI'Św:rBŢĺĘ•˛UĘĂźŽů"^Eyç ô8ÖőŤłD IDAT ŃôÔ˝}śV¤;ěĘ{‡8śl)îAqžę^@ŃśĐ^@Ćü^"\$zµŃń S#J.%ú0s ŢhH„«" ő"¬Ő“sBŹ ]'ve8áĺȤÝ%˘4‰š€ą?rR$Qň¨§ŠĽőÖ[#˙3’yŇ”Ş€2EŔ–n44&üE4H€i‘ŞP”;rUĐBşh4~sőqDĎUw-ÖbµG\at®…€ĚEC‚@uN|&·=ˇ8u‘a™ĐmB݉˝#ćN”ĆO(H÷^‘"Qň §‹0$=ňđ#Ľ¦V_cőt%”Ë!»k¤@$ ăx9ş">Dśě”ZZw=r™-”đNśEG»E”ÜMńÖU\k0"\'“ÁčC‘V¤/’A†'ZN=vuÝéÖŤ‘ÎÖ~ćťw^>ZČĂ-t‚Ňm&Ôjm¦Ę50ŽS‹ˇŔŰŃ4 žg’F ßŢÄÝřĄ8Y·˛ůH‘XáŻAĂMV…¤buY3BąZęT'<" )_L(Së#<âJ;‘ ®QŢ,…‚Ě‚ ŚŹÜ“eH:ß}÷Ý 7Ü@×_}şćĽé¦›ľţúkRŔ×™áŁ4qŔÁ­Đ 80[-‚ÎŤ„”ZgťuŇäo•`ý2q7jńěÍ­űl‰ř0‰X9ÍËE¬xȨÖrźRżŽÔ•r^´'a'˙ź˝ó€·¬(ň˙ŔDA˘"0Ă€€˘.(‚d%-I0FXDő/čHXaA$ 9‰’ŁŔ‚(…@¬ÂÄ™ů»çÖë9çÜóî»éÝw_ő̧_uuuuwťŞsşëvL:¬çâřŰH°Ć Gf›3Ć2ťs朳ϫTf›>[”Î †żłÍâř•Ek©%ţŔ^ ŞŃ€´§@’$‘!¶‘â.•â’ÄČ CĘ8`eÄ mD†’$ŞË 1s0 [ĄŰ!A¨QÁ€ Ýř/ÔĐĐ—8Ć_$ĆdVÄ–(PC ¦µ3ćÄzâĆ„™ÁM1Sť1öťŮ‚;RVfVcÖdR™8R@ŕ<7ĄAUÂ4\€™R0źÄ{>ŰcĂĐe ŁÄ`j”_?†D>$ 6F" Ďř(§ó™ h™¬mxgLŘ[JGZü&ˇ,őg6ă/ŰqSjđ)ڧ*ŔMiPąˇ„˘0`JAqĂ?–k…¸ömŔ”ÂVť°ú$ü ˙ÉŤź$}/˘ f–Ř`Ń}2hcZ$ .U,0Ú ±0¨01MĄĹt„\ć‡Rf†ˇXôŞ÷It @śŮ †$jăĂ[ëĹ{YA“r¦O¸‰† 9ŠQ$¦ŔÄhŚ0xĹĹkhôűŇś¬TUSśŐUűi0±‚,…/s`ŚE(® Óؒ͵“RO?ýôwÜŔÁ1&LhšĎ ˛Ôz¶"âjĎän>aXUÄăÎĺ6’äGŽ]cE ÉĄçAzýŘcŹ=řŕźůĚgĄď2: X Ĺ6‹ L0×IÍ Â_Ô iť ¦1Ü]îZ‡Şë­ů0b HÖťÔä‹Ü1ŕ ďđ‰ ßý2“Ź«NxđÂS'ü2Ç9fÎü'ČKăQFş3p¤Š‚(cVY˛CŇí ¶Aěxă´¤/:Ô©NHť‚¸j/ŕâ}ačÉ6NE É?ĆŞ!&}aŞP(kjoŰ ˘;†>„ÜřhJűcY`5LädAmĆ…Š0*%¦nXQ;10ŽHZ…q‘4 ‹ą°ČhJŕÝšBă‘C&*l•ňP)Ó[Yɢ֣˘€|ĽAiĘ'«Aťĺ4‘˙„9¤5_I(­)üŤcMę­|ë5'¬})Ô^üeJŕ1¨c>Ńo<}ětřă eĺjaE ˙˘ŹŇM 5x˛”BČnJJOÚKl¦DŢB`dJÁj>T7MüˇĚ!`M2«đą+cˇlř¬Ĺ@2ü­4%Q6«.4ŁăDŇlŽ@c1Y …źËfÁĂ„™ĹP*©J=î' čáÔ/ÁÄŇ ľ/ŔÄAé“ şDMlę—2†łĹÚ+Căi-aŔFRM FJ˙‰łéRíSE’@ĂLů) lAY$áFÜtp1\uŐUp`Ő 'Č4Íg¨źy抰΅'•–Ĺu²aX{’ËM)+`yOXŮ`q®†Ŕ{‰3śiݵŤKíOłô|‰ ŕK‘P!’f éŻl „\fŐCŐR̤ qđ,ú4Ľ­®IVňĺ!É“‚Í“ĹCŇŕUdj-0d¶đł(š?î“wćx‡"Á•‚{eLvŠü&­Ľ†WJÝŻc R,ÇkhPřj\ÓWŞ"L´4Ľ_âţŕąćž‹\b0¸rŃX-€ŠąAă|L :ÇľŐíŮŚ1qĆF"nvŔĚôE„??’Ć O,bq8Z=;s† ¬LŃ|/XP„ wkŞ~–‹#p7%“É @ÔÜl⇽…ő;cçqĽ†-5WďbJ ÁĚĄqe)čÉ%„"ŃŤEŐbžUQż)F¦É!LŔđU˘R Q—FĄ$˙‘ĹFŠđ Y3Âb0Ę &ţĹŕ¦T_öĺ9śĂEOÁM©\@eXÄ„ýA‡Ł)ˇźÁ4âžÉđťÇ ykaOBó1˘8*M-čYdüů+*kBó8xRćه[0hŁŤ´Ň1@rŁ!× x(ů„ FąŔŮ`f‰ţ9kţŤĽ’(Ť–")–>Ł*¨:010ÚĚ;G1i`ń¤LQ “,ŕ ¬ZÚ+µVŤWLE4 Ľt›V‰&­2ąÄ˛L€¤Ĺ˛bŘši´Řxö]qĹÄśPąůć›#˘6^śµ!/·Ürą“M^~ůeđH !ŕÉĺ6Čź=ąřĂđž4Xśëi¨‹KŁ˙üç?sECµt™L zP/±t†§†¸¤ŢŇybÖAŔ"É /J+"¶Ä9 Ë˝kcuÝSb5Z‚«č€đŘ0]š`xŔ|ݵjš\ľŢ:%łöé8Kfňă^H2Ĺă­¨U&Á—§Äw +j÷¬˘ôDdĹ\ÇÔ“Şą¨­’ŚHĂUŁU­C™őgsČ‚š‡?Š‚Öל0Eń€h8@L)Č3 éČ:°Ź&¦ó±±č&Ă|°|‘XM0ś¸s‡Ů °ö3]´Şć‹h¸ýC( #v>-ýÓ«®ô„·˝Ô^úKd8ŰĚ ř®ÇĹqażńAąăô.1µŹŰ?ĹGHµ]Aű&,żŇw„ÄXĚ;Šţ8X˸ŢÉÎŽ k!ă7),8™~Č–žD$ÄŞ×?LĘ?%)qSJĹŇŚ]@u9Ú„~—2wdÍuľµ€VËW" &IᢠŁ0žm†đń*˛Y™l2bí Ŕ{Xq0Ŕ a˛“H~ ’U¬Ń1}/”Á4SŠA’ °ľ&),Ő"e.S0€ŽJĎřÓ4Yş ŚJ[ÔBş#…‡€,bIJb’·Ĺ"`Č #RËnü)î éśtB-Źoܸqt?­_-ąĐB 1ó·dăgßBŚ7¤ńâ$Ůe—qßZk­eŹŻń»F)qŃBzBlV@E"I°4,©EH©¬Ó~`B×:ŇąŠşí=±žäħ¤Ĺ|’qŕţ࣍íéiaŇ< V[ɶ!řř±rŽ·kGÉĆă-Ńň;$ÄĽ ţźÉżq™CĚۡ›o˝Ć›×”¦Ű:Ɖ©ěs†žüăŐó 9ĂP~Ä !#m&„ĘŤëN˛ çCŁ8đŠ/ Ĺ©R<śĺCÔOsVŹY3ç6BAbř‡©ŕµ+ fĚ´ßĚ)+Ńk"&Á¦˘_&m€Ăő$Ŕ'‹ŹŤ›R=ńúڦ˘˙X@íüX1‚ †młĄ[öQ€Q0ÉČÍ\śŞ(m@ŠLńé3ĄPż ¦Ŕţ›pęV<`kĚô1sĎ57ö“™sÍűÖXvşQ)TŔ˛ť×>O2%˙0Ą2oÖÚ‡›RL:âhJ|‡€eDᛤébř‰1Ś«´ú$ś~R Pň‘ dsĆ]0AíźXÁSˇńVUSÂÍ€©{!V;1(µ <şˇYIzÁJĚ_0x€4&)†Š© Ŕjt ż%`Ú@@»€ő±âK»ř˛Ëb7b}eôY!bč3µ?‘qĐa€v S¬S‹“¤vb*˘UBJźÉ…’FŇćp±F\o‚!€–E`8c/Ä`ÜJË/żür–ZPŃĉ»|ÝŚ¶íL0˝9ą.čĐ:ž1ÍÝÝ6~üxËq°đ)V‘«QIĽ'×^{-ËUž~úéW\±”fx‘ô[@Ł€y‚¨4-"I  lÄÂ(–±€¬ŮAöW¬Śóđö´ĹÚ»á=‘¤Š _Dć0&ed/Ź4ĹjOkÂË FMśÜ…«yHęKŠŕ8±÷ô^ČUäÉz@ÎdˇôXB=ǧ0Ĺ@â= ›­ň–Á04 ă—O/&9M $d%jĘźÖ2T8°S ńŘË`s0 ż…ĂŤşđ‰đ”ueż—[ŃIĚ ­žSµ .~OÉĄ âˇ¶gŇó|%g7ĄĆźľtVôÁoRŰąö’…)F¶2(đh˛Čڏ7Ţ€RĘŚ¦ÄŃäí!šmv†žxU’#{ &5{tDâś f|”™÷$NßT‹›R©´‹HžµnJEáÔĂ Ťd)NM -& ´do˝ů6Ec Ť}ĹĐ „¨űőŞ3<ô &–l€Ěś˛‚Q0:΀Cf>^µÍ;dkĆ \3=šh’Y@7Ô`‚Ô)ŤőM‘^Ł9ä+ČPŔ¤e#§…ď‚dT51ÍŁUh2Ť”ć+0×EůÉ… €<&˛Š€V M7ţ®»îşé¦›(ľĂ;,łĚ2Mói®ŕ”)S(ČI+t9ÇA·í€D>M߀[΋e… ËOŘ’“«˘4I.PżńĆ9@÷ă˙x)Íđ"Ń e@O, .0ÄAd`ŢQ·áíWŰkď†÷DO"ź*…NP©{ä2âä1„ó)ß †ż 4ÁDĆł ŹŠŰ ÂŻ ŮŮŃĽ řÁb˝Â+`ćýH–ý`ŢĘë íĎ Ç"dZČĂň_ů|RRŃ×~â N“”ß‘˘˝‚y#^+&×&}dAC Ę­Rł‚ę&…JŁç+ĚÜ´®$~2ŃX+άbb†žÄTÇÜŽ— YÁ”ây YئIř+®n‰ç"ž,1’wSj\PKB Źş*ď 0bŻď4q0¨cJŔä’ !NIf>”šůđĺlŁ…6ҵë^‡ÁŔŔ•5’:+ ŢągÎMlIbJŘN ‰ż‡Ŕ×(€š<)Bh¤1Nٵ'<7ĄĆ•q}4%ţęk"[&Âw;©ŤMÉż`>U1=WĂ SzuÚ«ÔBAQfµÇˇąÁˇ=Ťˇj‘c\`h1†NŚů‹n`\$‰ů™2ri0±ŕhsY[AŤ5Ç©FĽPú@lýŚÎŁ]Áú˛čGuÁÄĘŤTŃŃH™ŔđW¬:*&Ş€żŞă‹CĹ&Nk§1`čV 10V@Rˇý C™@+ńřăŹs[0L6Űl3ÎIčf  4€9«µ¸´„ŐjĚ /\ĚmĽťK/˝´Ľ'Ť3áĆbĽ'=ôĐ믿ޠϥńö´Nij€ÚŔPšlaşF-" `3 ČÄJÄ­7˛8tÉ{BW%¸ŕ'’Ď?˙|Qc´Ä|ěăÎV0ŕóTBVž„y pp”Ě\ŞşÚ ¨zFŕĆwź ęą đ¸ZŇu¬‚QT5Ąçšâ¤,ę^ö :‹2"Ćl„Ę·Śłâő+Ňg˝hB´;ŚbłP›ď™Y-Ť*K ĎŕőÖ3“ŠHdü+xµe&ô8XRÍ ×~0w;jü)đô!FÚnJ M/p3Ž^ň&30ĺÓ—sOâçń+«Y©`eŃÍĶÁ–ddˇAµ¶ÄoPfSlAác żŘ’ž$#˝PĽFÂĹ"bT\1Ť #™÷[ʼnHĐ~hôN€@łA0ÄĐC,€"‘“ }}E E˘K¨„`č@0BÍ;O|RŚ8ĎîHŠęT­B‡IĐ*2 µŚ4śX:Ą`â#&F)Î$‡ÚÜ?˙ůĎůaűźřÄżřE1*“VčŮ.ôĆopžëřńăéTŽŐ /„Wď 3ÁMÄăĆŤ»óÎ;ź~úéĆ™pZĘÇ>ö±?ţńʬĘŮn»íš¨´sEě1X.IĎ-ćŐjAH©1‰ ©¤Ú ÜąĆw™sGćĂ&tLp’¬’čňĺ"+îpZvŮeAJ˛Đ3¬Ěf›1‰µó¨ůZřE‘Ë Ŕ°±<ţ~Đ ÷ěÔN9 ßŃ8Ů o8T•ý+VB-C)XŮQhśĘď9óÍ7ß(ér+Ý´·‹Ąůšż…× XĆ_żŃa`ćPň3źý¸đˇ /ˇěaćPÁ@Äą^S- (yt‘Ű:p`Sľ±ńnťé3Ţžýí°hëŽ_žA{(eë9) f¦90ÁjOaC:“?[á+릔“L1i ¬,%ĄŔšĹ…‰_m E&ł’qĚBÍ„d;‰Ĺ1%čkMl¶JJíaȇ Lř<ĹY1Y2ź9ߎk!ą˛ŞfAPűÝ[4 2 (ÇtÇÔMÉdR@3Ó,%‰ő5á/ęJ,­VĐ˙  O’"™)‰q Vż¬Ţ˙ý$ÇŤG±‹Fôile‹€Č°ŮšZK’ âś B†—-±~l× eč‚  ĆĘ€b3Ó7@ŁÔŠĄźŔŇpÓy0čH‹É’-C bEŔťšŘR ĚQcbj·¤Ů)`”_ĺWŔ(ĐsÄ`,–EČ[ăsIĂ®×9ćc^yĺl˙€ĐRÁ"YG1ZxÂîâĆ^M˙ú׿T;G±č‡üćóá‚°2$&[mµŢ“[o˝őë_˙ş†…ÍŐŢĆR9-U’€ )@Ç€ĄiĨ–b‚”ŤXF!bŕŔeÖĐĆ–«ŽxOč ‚R—HnÖI’Č‹Z~ůĺ|đA®ßsĎ=-7ř¶gkG·âŽw _÷B¬Đq§Ćß Â `&w5ź4Ś®őfHł˛Z&€Â˙ä$ŔTL°Š±ťŇ–\Ť#;Ƥyĺ2Śx˛¤Ţ) 5ťCYÉŻ!˙n±¬4!8`#X ·gÍĽ˘ńCyÍ^đ¤ŹÓL‰·a0"ý^73ű AÍb·Ł R… yş) .­Ú€3číś ¨(Y ®“Ô 2›Â˛ř‡äk(JŢŚY)(‹ íjUŕ b¶°’K+$ÉŇ`3Ŕ¨1¨1s`oáçîP{\ IÁó©Ů`fJđvšUňąTđťˇcÜ”r‚)KÖ1%He8A'ď p6ÖîŃ`=ÁŠ,ĚjIú>•Ô{óÍ73‰bRÁâv˛c%YS PIJÍŠRY,EEiI´ÄBŁ.IŮ ¦Š…OcȬ,x})1A]@,ĺ Îľ/`kŢCéqÄ…H”bąŚI7…F˝VťÚ VˇÉ 4Ź6×RÁ(€ŃЎÉ7+EśŔŐáţçřQśTřĂ6ľĄĄšçPsĺş]e•Uxą˛Ď>ű,ÜĽ 8¸¤HŁŻHę‡îEFlZ© Lł>ő©O-ľřâlůÁ˛ŃFĄYĂ› Hc†Z0JĄX4Še˘ĎĹĂŐ»Nԛתë@Râ€+źIÖ^=믿>Ţ“łĎ:›#…´Ľ“R*X±{<^*zvĺ  ŕÄoJL2üŞ7&¸Qt˛& ö"¨!ZeÍ30 a`^4ď~Ď» é€IŔtŢ0)˝tÂ8? łd,Ź gő †ŚČlCFË‚† ţ¤Ő¬\©´ÁŞ”ˇ0ÖD˝řJ0*˛X«K4ýÓﲝ`e1PIZ]E‚"Ň1sÎU»sÇM©LUi•r"“&‚7Š«Cđ¤ŕaŹĂÚ€Ôę-Ę$!’ 2Ŕ–µ(ŕ $6•VRÄ´!ĂÇe,Áâĺ;Đ€_źÚ÷8L\Ă%Sć_‹]Ylő–eŽ^Ü»ćyťGÎţUާ©˘ćhȲ@–ěCÁá$źdí{DR«şä‹”ő‰-ăÁ(üqÇĽîşëB¬V¤ę¬ zž6ÉđÄÖl$¬‚AĹC…7¤˛H‚O?d|ÎdnÄ ÎŐ&ˇI“ŹP H‹ę5µŔ‚’Ä„đe©Ťťëă’~bĐp(Uś* \ŻŇVđTAq)§ŞCŰhH;6?D4OÓ%Há5şS, Ĺa(„ŠćUäžqĆxN©ńĐC•sˇ‚O‡˛p‹<üđĂ0_sÍ5‹ëud,˘€l©Ą–*4Ţ*Ę.¸ŕ‚0ä ­Ci°ěÖ[o}ě±Ç^yĺ•lkj°H'ȤEĄśĄTÄč¦K¤Żt˛Ě Ňř‹‰*2di˝#Ůfď Ý–\”Xc©8 XmµŐ.˝ôҧžzjҤIGuT‘ŚŃ°ń„ž@’9ëN`ËóS~úS“Ö1(zĘ8B…,4ŁęmGłbçq"Lćcy$h3 HE뉑ĺ@>L#XG\HEV€‰őOpĂ6ىeëŐŇž*ăďć0Ä(è7îčÁ4hF° ř‹nřlĆŔ¤TćS"“dEĄ”ŞČµY™ľ#v7ĄR¨6%,@ &ÍćL)žÎ4::É ř –• d·¬áĆŠd>ÁRâ0#8ôă/âúÉĐ0žČ”db”­¶7ĄŇgĄO?ŇsS*•OPËJ=K˘â€Ř49•L&@á߀)+YA eęÔr 'L™2…źťůeU”Ĺv‚§ŞĐÔÉęa(dERVÁăt@VFG€oYJ׫|unEAĎę) Haę5)hý¬ŚŠSs9‘8‹RÉzuoÍ  `%i’XďLeˇ˙fäBI,J˛ ‘T4µžQÜrË-'ťt÷ßN<©ŕĐѬ{ď˝—Ł9“uüřńĹŠ´öDx®+nń#ňˇ}ŁOxÝqšI±®zÍ7ßüä“Oćp–x`/ß‘’Ôk¤tĆ´bÁŕ 0€\¨WĹČĹ·>,ŁRŚř$ÉY#_ô€U'‡~ř5W_sÔ‘G}{ßoCŻRY<6XµN% ŚJĂ–ÓŚ…̬źĂŕ@­ťxr)BY†LĺÇRmöX@¸i‡eďâH| R]ZžépÇgÉÚýxCS0š \ XqŤHF”h{ä?\•Šó„¶ĹĂ—uh€@Ě™3łŰ)•ţA‘`6Sľ‘Ć8 çÚ ž˛›RăĘ Ő˝&„ň‡H«¦D*2Ś%xŁź8 q*4ÍŹ†•1¬}ˇ”¬ŽU<ŁŃ¤ł6łRcç3gřĐPO͔‹OV|‹ŠcS4ţ8”ô¸ž´Fš'â¦TODE|¦˙˛‚ ŁÁDF–°>C2úŽie01 L"CÁâöë‹}üqÇůË_ĆľkÉŘŹ¤Š[ŐŃq3LHs ¦#Ib>X˛ ń!ĆÜ,č]ˇ¤ę‚€`°ę&WŻ'űR¦B-Đ_ŕôű"5F“…—J V)0Á*Üią© Ĺ´0jt0"Y„´ť$mŔĚâÔp ž6›a˝xôŃG:č 9 uxĎC˝ďľűhw—^ĘĆ–rYxBžÔţÖ‚EČĚ8'HsĐLÁ»)ĺ$SLU!Ł˘`RSâkľq˛ĚŽnŕÔXŐ•˛¦:6zT]”Aç©‹qHr*s4} ćMiúŘđ{8‹áź2­¤Š§H‡sĐBĘM)'™bRęDśf)i1@°BPčđ-0“MŇü’*.Z±â`ž{öąkŻ»öŚÓĎ`˙?ÉĎţó[nąeâ•+HV¨ĹĽ6đšµ…0É«.N p$K0±Žr`&L-äĘ*IćY†‰ü˛¤¦H‡űFz¸R'ëIa–~BC2ű|'ľ8ŃXŇ"9Řřw :ă,˝ĄUBŞyĚÔ*şC!6Ł€RĄtş$8ÇŮŘŢ<űěł^ Ž>ţřău'šĺv6mŰa¨tťuÖ)]śČaj> ýZßJ µď†SrKëŞŕ̉¶lnşçž{.ĽđBO”]ČBCxľ©:Q©˝]M…RXB–(‰Í(ŠĹU¸?BśJµŻ+29™%ć@ ’Ŕ>4ÖJř%Hťřµ×^ă~© .¸€ł‹ŐtšĂÓă|RÓMačÓd ‹UÓľ÷?'¤ńŚpĐďýę˙Î·Ż‡ą·RE2ÍJakK)Ňr‹@©ţ§ČF`±M)‹9¦Z/ĽđKF9clÉ%—¬¦ôÜ ő?ĹÔaf‰SQݞŠ&bęÁ”MłŠÉAëu‚TÜ7Éh•ňŠ+®â’ŠúźĂ¤Éz0c9Ţl/˝ô’Şćý†ßdĺ•WƱĹtbžZCŕ©3Č&f´MR1üm‚ZÝ LIÖ””dŘIqĹÂTÇ«ŚÁôźRe¦wJ§<š™b6,ń1%‰»¤®›>0˙"ČOó Q–ĄÝáZâsÎ9‡ůÚ%—\2\'ĹZĂ®ľúę]wÝ•ŕoĽńFCŔÉZ&BHązńt }Đď‚K`x%ŔWÂđ¶Ákw ôřÝĺŹüct¤?şŔů‹źüä'W_}őůçźź1^t•ĚÍ 5ŔL ˙4ζ1a 4(aţ a$ISIĺĆśĄUŁŇÚÓÜďpH5H;’&KKĄ0šţY,ba¬,€śRţť†ÓęÔfa¬ýĹ@«Rٱ¨©×Š}áôS\'Ô8yňä•VZ©HĐe §Pc˝…'O<ń˝ă˝„ż wđá¶Ţ<śřřĂpčăF·­¶ÚŠ+SXŻÇţť-¶ŘbHeŰNśjQN-‚ÜŇ@“Ě( P X˛íÍ.†ńžXgrň•ô‰řĽa®ŁĐ|\YË´üňËł8…S‘_}őUđZŠ);‡ą~UP-fäĄIk d4&GląTH€+Ą™ěáNĆ?ZAćYîĺ^ŐI¸ĺJ1•ć˛J•?E¦°Ę1ŕAŞ;9ţžTx ń s<‡´JěĄî j)A ĎR¤ĺ M#‡©N·&Ĺ–Câ7a~Ît}HťŘ$€ Hý # gi’‘I Ř(ÂôŁa_|q–ës"Žăş\Č•Í%smhüđĂŔ¬=Qs˝`FFž_¦™Ą4ą"&ńž@Ăa+MpC€Gy$[.yä@;hu"HőGUĆł”@:¦8‡'ie•Ő7q›˝'©R#tşeď+ÖHŚ4Qeh0B–LL–ľÄ$) IJá4NŤßž đ™!s@unŽxt&>çµe…[Ë}´Ą4BłŠAů7HPÔ|aŠxcŘ\–w@ď:^€nJ*C#š_J#dEÖ U• h†1 Çł^dŐą9VŁ3ÉŚťŽó”Ý”Q€RsČ,Ň€Ňb 4`ă…,ď ’ŔÄ‚“TĐŔ" {-¨1¤r­4Y,"ŚbLɬI@.)ţ†´ęŠËr $PT:•C’F±zŤęć(‹4Ă+ź´µŔŇd!¬…$é€ŢČälŔiÂo««®şęqLJiçč‡%Éá#ÔËąK‹.şhiä=Q_8ă¶-ͦ:ęúÓźţÔ7Öż°g‡ËwN:é¤cŽ9¦´ÍÝA¦šŁK1BZ€`ĹiÁÓť.tł–ލ»‰R/úÇeĹÇA°Ź((ń‰@ 0yO I 0˛môRLLR$ NzxŃTç¦|F3Ěó˘űŚ„8ým4ˡ‘ľ7ř˛(’5‚i¤CĄ)š@#žőđVă F9jŚľcPnJŤč@Ń(ŠĄŠ4E ĄJ‘En­`Šú_Ä=ĽŐ>(QŽZ€ŞôťÇę¦Ô4˘˙Ą4)’aIĹĽÄ€’‘ÔŕÍbćCáŤ,7Š~i¬–‹!ÜŤôĄ”¦˘lše–`p)ĂęÜŇ"ŽAHµ˘´Ů" `4J¦Č6˛aÔ*ÔŘš'¤évšK™pq±ýVJYďĽóÎ,—Xb‰%¸î-{Ĺ"Ă‚a'ő®·ŢzĽjJ ď 玓‹÷¤YiŮzHNź%‹=AÜÂââzdőđ{ě±Ţ“sĎ=÷°Ăký zµ ŠŻxú”U®Ń ¬4iÄÖ8˘ :â=1ibo|% Búí”5ňeEîěĘ!LÎ{=VŠ‡Ĺ˛ŕś†ŠYE®g5"˝\ů8µqUÓä^19âęÜqŰ“ŐĆRťŰöĆô%CyO]¸)µţ|«ŤĄ:·őÚ«9TKun5gĎ•Ü{ŇFM¨6rEŔÍFŔňžđZ#‹HůM –ß2ąâ@ÁVG@ZěT‘0fqF`\Ťőđ92OöŤL%r=*âSL ç öT2m'°Ô[Hŕ4—fç’iGŠvńýď˙Ş«®béÓ~()ńđÂňžl°ÁĽdJ[Ân#đş“dܸqőČJËÖC.´ĐB°Â/Ă~Ňu×]·Y=•˘8ôâ#žměQŽü‹R,Rć zr”H ď5aHĚ3Éç¨4á´ÓNë©s»ńŚŕÂŕ=łöÚkóz)ę*VŻScxYqžc®kĹ" b>ţńŹSőý÷ß˙™Ď|¦Á")Ů7ľńŤÝwßý„NŕćŮv5)ĺß:Ü›­j˝_Mshł÷DňMcZFR/%*«€gĽü&$ő5ż YŔä˱RôžŔˇéž{Á%Ŕs’a'ę7XÄÉ\.˘0"|ÚÝ”ŠÂqŚK q Č˙ČřŘM©qˇ5GÉHŚ‚#s`ŤÖIňB#ćĺF’i H®“Ô{ÄGśI¬–ćÚ™+%†9dš” %vŘ%ШÖůę\ë>÷ď¶Űn$ąj‡sO ß ŔŤ7ŢH3ÖXcŤů曯´=¸W¸¨W“ĘvmŰQE˙öo˙vÉ%—°ö„7[iŐŐČwÜń€ŕÎăkŻ˝vŁŤ6Ş&öÜ^@›˝'Ĺ.a(nĹ|;ĺ(á›J `Yć= …ś÷„şÜ{RxŰ1<2x2ęťťŤmďŁ3t tAĽë¨…/·›R¤íUô±tX,C7ĄN?e›S ``Ŕ¨@1I^hÄČií 0Äd”٤8P\@§Űďü].vIŕ™gžŮj«­Ţ|óMb®(nŰvńąţúëaµţúë×cřř㏓Œ:Â…;őČšŔă=ˇ÷7Q–"ü 0qâÄźţô§?˙ůĎÝ{Ňś »\ŞŢűÖâăPĐ÷’ʍ’ę*>>˘Ŕŕ(&Iś®:ÉyOR&]–Ú¨ŞŽçEůíŁęą{gŰ.Śž”›RŰeë G•´Ś‹›R§ź;Bf¬ĄÁ±‚xCH“$ćÍĆ+X>’ ÁH’E¨ńČĽ'JvşÎß%ŕhQŻżţ:·Ă<űěł’Ęć,·E†m/~ÓM7Áółźýl=ÎňžheJ{˝'ěܡŇ|‰*ďşz ¨Ŕłsçg?űŮo~ó›©S§Ž?ľ‚ŇłzAôžĐ=ű.ňÉ”ł8~@C¬ď+^}ž‰Pś2é"pę=Q®Ĺ:$śý0$ęPÎÖ%0$ o*ĺ¦4·÷±s0Rç„lśm †×I^eB’Ä?,ż‰bůJ4ş#†FAEI¦¬"\.ž•‹#îąçžEYäŇK/íÁ-“ś9ňüóĎłńSźúT=˛5†,^SÄíőžŚ7§Ě´iÓzč!Ž€­×€ ürË-·á†r/×?qÄ”žŐ č÷„ŻŁőŤĎ¤\!†Đç“u%|A ¸EŔŕ7ᣠ1b†G`ä1‘K˛dOa,é@%ŔCűĚ›¸«ŤÍpV.‘.ýNΛÍMi¤?Jo˙đJ@cw† nJ}éXX¤)śyGj· ĂČY °‚\*ĐC ,Ŕt´#ÎÜ%ŕhE‡rWębŃ^x!'†´ÂŞCeµm‡űkä[/­EkO{’Ű^ď o06ďÜzë­lŢiÎ{B“öÜsOĽ'§žzę¤I“ünŇ'Ř;ČŽxOŠÝÓ7’Řś)ř;ř¦’Ä3BŚMš$ÄĐ^>čÁÄ_@Ddb˝Ži]< |žKëÜśK`ÔJ#˘ď”›Ň¨Őďx[$ źľ›R[„Yʉ>ýää`aôB3WIÁÄŔ Ţ JR@ĹëŐëx—€K §$Ŕy¨śK“Ž=öX®łé©¶Yc=ôJyO^{í5ŕözO`ČćĽ'÷ÝwßöŰoo­°ńĆŹ?žť;çśsÎ׿ţő!•uâ.K #Ţ}hĺÝLŻřdë«)G ßT[NB.ô8ML-€uâ IáĂ€`bJa!‹#v  hśĘéyçť·‰â^Ä%ŕô“ď77%W —@+Đa± 'Ü”ZciYłY®a4~ŻáC80ň†6ż x9MCŁ`E`bÜ[u¸\˝#vÄě°ĂL¬ľő­oíşë®˝Ó°´%Ě%ń\€©8ô„Ü'ź|’řĺ—_&n»÷¤Ĺci/I®.ŢożýŘĽăŢŇˡ#Ţ“\‡ůF‚‘SCßKTDIľ¦¸HŤ€%qđ¦ÄqÁi"d®Š4 Ašt¸E čńń€üó%éĹGą0"$ŔKĎMi”k‚wżE ȧϷÉM©EIćŠësźCZ’\^_$óZKa ę„'‹¤r“4ĆŮ—€K %đŇK/mľůć˙üç?7Ř`ŁŽ:Ş[¨&Ý}÷ÝŻĽňĘűŢ÷>ťŢZÚNλ}őŐWÉŇÚ“%—\˛”¬i¤ŞćŇâ¦9Ppçťwf™Ď˝÷Ţ{űí·sőr+¬ĽlG%ĐA‘Öz>śŔ¸6ô)%Ć+ż§ŮćąEAĘB¬=;PŠ‚Áb¨¤Ç’€¦|¬=ń»!;$ag;J$ ™ĺ¦4Jž¸włCĐa±Ś"Ü”:$á”­Ćr0 #Ö O–e 6ŠxÄćF%ÁŠÓęv ¸zAożýö6ŰlóÄO,»ě˛çźľć˝Đ°blŰŽ^JE0Ú¶ó|ŕŻý뢋.ÚöűÚ>ň‘ŹP;'×â¦y˙űß_Ú†A‘8€¶Űn»SN9…«‹Ý{2¨¸†‘ Ţ“bŻŇĎ$J&?t=8E˘[„X&ŠÇ"Ä‚E[‹µ8¦˝ĐSă1éçľö2wn.Ń#˝ëÜ”FĎ÷žvH¶öÄżJ’p‘­Fi,/ ‚˝Ü+ň’Ĺ&‚‹Ěăp ôš8Äôć›o~ď{ß{Ůe—-¸ŕ‚˝ÖĽ´=ć=I‘9XŢü&xOÚľm‡ş8çu…VŕŇbŽmÚ{6ďŕ=át^1‹-¶X®žě tĐ{’~&ĺň° _V’¬.Ńďrk<¤U'IE“’ŁĘ ö¸˝3‹źÍŰî©mo;ť›K Ç%`kOÜ”züIyóz\:BQ„›RGźTnGR‹ Đ8A&P,8 ˘±¸Ł˝pć.—ŔP%Ŕڇɓ'cĽżüĺ/q µx7éßxăŤ;=‘÷DGeuÂ{BŘĽ÷„c7Úh٦%°ňĘ+Żąćš·Ývň×a˝Młň‚ť“@˝'őÍ4ÍÂ8ń}čł*'źaó†hĎŽ’Ä9@|„Ly:Üv đ4MÇ˝'údâŕĐ7Ő<ňŚ€ÖH4&‹€\K@)\Ó}QökŤz4üÖç׏÷ë#ö~uG¶öÄM©;÷ZúUvRGq=—‡†sTm€ůPŔ¶\Ń “‹Izp ¸zG¬ŃřŇ—ľÄµ§_űÚ×öÝwßŢiX˝–hŰçÚÖ#^kOčÉyOZżvGMÝzë­ŮłóĚ3Ď\|ńĹ_üâ«űĺąĂ"Ž{O*ze_S€ŕ#‰>â´’řSDLRÄ) p®T.ד­HŔ“ ‰Záće]ŁVnJŁöŃ{ÇŰ+űĐ^ţÎMĐ++' ŤÁ dé(iŹCIr2ÇÇ“.—@ŻI€[i6Űlłżýíoźţô§YűĐkÍ+mO#‡žPPŢ“iÓ¦wČ{˘kw}ôQÖ´˛«”ź«wŰm·I“&±Ę˝'Ą}Ř‘]ňžŘ·S@ęě`iIa!ŕ â%&ŁÉIMřғ풀ŹCżś·‹­óq Ś6 hď77ĄŃö轿핀3ómrSjŻ`Snúô§`!Ó,`%§4)&G“cëI—€K`Ř%ŔŐ\řňĐC}đĽč˘‹´ÄoŘ[UÝÜ=÷Üs4믿~%—.żüňËĽřâ‹Äňž,ľřâ‹,˛UÜ˙ý«®şjE{ÍúŹ˙řŹC=ô–[nůÓźţ´ŇJ+ Jď]–@—Ľ'Ą˝Jż¬x@R'Y$«¬’Ŕ)™e•ňwd[$`űY©-lť‰K`´IŔMi´=qďo‡$`#:TŃhf«÷UN9¤˝ÓR<°‚•%i°.—@oJŕ€¸âŠ+ŘyÉ%—ŕčÍFćZuÓM7qÇČňË/ŹÇ'—•&yä’l‡yîąç–^zé4·Ť0gľ^sÍ5}Ң÷„c\¶Új« .¸€ĺ''śpB[č¬Ú"áńžäľ¬ôD>‘4N»^Y)ŇáîH@ă_{Ňi{-},_{ŇÇ×»ÖM řÚ“nJ»^]¤ž‘“âëqpĽKŔ%Đ#8묳Ž8âsúé§Ż˛Ę*=ŇŞA›ˇm;Ő·íŔDŰvđ°p 0kjX!2(çćŘĽ÷„kwš+ž–âĆhĽ'gź}öO~ňîŤNłv Ź÷¤^·+>·ĄYîR©'ɶă‘é#h{EÎĐ%Đ÷pSęűGěěŽÜ”:-ç łŠN7Ďů»\­KŕÎ;ďÜu×]áĂąŰ:Ă®qҡ' /Ľ0 cŰNçŢTí:8–v®łÎ:ýčGŮtÚi§í˝÷Ţ]©WÔzĹ{’Şr Úw  *˘ ô8X ­_Î[äćĹ]ŁVÚe€Aą)ŤZđŽ·EfA´…­3)•Ŕ†dĄép ô¬¸ŰeË-·|óÍ7Ů*ňŁý¨gŰYlŘ /Ľđŕň‚Zo˝őŠą)FkOćťw^:ôDŐéŕX\iíMĂ,?ářŘăŹ?~Ż˝öň÷pÓběDÁ^ńž4Ý7×§¦E×`AIX@ĄśĚ%ŕČI@-ÉOČÉĆ“.!HŔMiÂrR—€KŔ%PGŻżţú[lÁi űŘÇŘĽ3˛Ćů,<átö-´ĐBuú—ˇ{ě1 yŰ;ę=áv˝ňĘ+S¦LYf™eŞ[5hîöŰo˙ťď|‡K|Ř ´á†Jď]“Ŕě]«É+r ¸\.—€KŔ%ŕp ¸\.a—Ŕĉął†s@.˝ôŇ÷Ľç=ĂŢž!5 ÁCOੵ'o˝őpG˝'śÉĄ+r88vH})%ć‰ěĽóÎdqvl)#‡Kî=.É{˝.—€KŔ%ŕp ¸\.—€K Ű8äCÎ=÷\î}żđ ;w MçzuăŤ7ÂĽú®bŢ~űíżţőŻÓ¦M#î¨÷ţÚĽÓ–cá¶Ç{° čĘ+Ż|â‰'Hzč ôĘÎťęăKŞs{D”ýÚ ź{ŕ ýÚGď—K  aPnJ]¶WŃÇpSę…‡[˝Čż:·Úďmp ´.¦§'ŤlÚ”Ş r-1gÄ"ăŽ;níµ×n]Ýá`r›:u*»cXë±ÖZk˛´ ţóźůd°ŽăŮgź…`É%—¬G_-±RćEdŽ…ůrË-Çžť«®şŠÇtřᇫs̰H WĽ'iç‹j]Ä@_ŠLů8Ü HÎÄ>ĺk‹<ťÉ¨•€›Ň¨}ôŢńöJŔ>F´—żsËI ÁIEd9ćžt ô“ś›4H†d lIJˇ19s¬é;ěço}ë[»ě˛‹áG m;«Żľú»ßýîjaâ=ˇ_úЇäĽ'C’[#ňŃÚ“¶ěÜQußřĆ7đžśrĘ)“&Mz×»ŢŐHś¦ÓNďIŞî‚ëaR|©D%(-ĺČF$ Ů2Hť>}z#ôNăp ”J@¦Dě¦T*Gş”€9MÜ””XsdŐó ĺ €^qÂ[µ§psŤńR.a‘€´şXµđĹÜ"†˛EdS¬BRŰii4áK/˝´Ůf›ýóź˙Ü` Ž:ę¨zőöľ(%{ů_wÝu´m;ĐÉRŚŽŚýŕ?řűß˙ž"K,±„1A2)%IB®ăELŽ —äša0O>ů䫯ľ:˙üóçr›Hn˛É&ăÇŹg­Í9çśĂ95Mpđ"m—ŔđxO‚¦Ďś™vF) 4)˛,Ťśn‹Ü{Ň1:“Ń,}°yˇů”o4«÷˝u ¸)µ.ĂA9”ÎrH%‰ 6TS2‡Q.Č/c7U IDATAëu—@ŹH@JkŠm­2L€Ć˘'™Ăꦗ Íä,ĽŐ+»SĚ! [o˝5sűe—]öĽóΛ}ö=ţRŤ·.¤ÝI¸é¦›@rW1ź’9’ä=yßűŢfá…žk®ąô)•X*+ă |Š©/¸ŕ‚ăĆŤăŽ>Ygťuę‘5ŽçqúÉţűďě±Çş÷¤qąu”˛«Ţ“˘~ Cm0F ­,áM …7 @“ć:ܢôßyçťYyq—Ŕh–€›Ňh~úŢ÷6JŔ>F´‘ął’Jg sxÍľ ó‹$¤)©Ńš»¨]˝#âT"ť€¤ąĄxR °ž1–U”ZŤi–ÁĂÖ’{îąç­·ŢĘš_˙ú×ď}ď{éKŃ’¬hRŰłRÉ…śbţô§?˝đ óĚ3×ë+@Ů´xÚ6]¸1HV @źvYť5ů@#Ř„ ¶Ĺ"i9Í;môžŔ§Éxď˝÷ŢqÇźţô§sŐy˛űč’÷ÄtZ±:Ś=XRHý0+;F¨˛’E1ŐĂ)Óśxţys˘óR.IŔŢinJ®.V$ŕ¦ÔŠô/kó‡´FbÄđzJ2Á`0&Ľ0Ű(ÎX)Ë’¸ş,tâÂ4Cęš" Źę ĄĹX.4IŠ)†9|=)â…1<@†“GO>ůdŕłĎ>›s@0^`3á\”4VĄąíBJ2&ÁçmŰYsÍ5ÇŽkŢ“´1˘FŢuď °\—ɲ@‘¶dĘPl!PŚńžp(oŹ>aá̶Űn{ę©§ru±{OŠď>¦KŢu ĺS°$@ –]Iˇ-& í$@ÓâE8Ąq¸u HřĽnô†jťˇsp ŚN Ř{ĚMit*€÷ş]0˙Ł›R»DZĘǦLI|%ĽÖĺ7Ń-ý‘VôÂC¦QśŠ—ÖčH—@7%N+ ¬öXR€}ĘŐT Ör%MáSF“ЧIŕ Q–Č CqłAÂsż/»?Č=ě°Ă¸ĆE•‹ŔŠ4Ţ’eëI“€ŕ" ákŰÎşë®KŇ(Ő€bňé§ź&ëÍ7ß$Ć{A*1ş†ŘBš,픥xC¶÷Ú±eŃŢ“_ýęWUłŘb‹Y] ‹:î=‘Ó7Á¦ń Ŕ[Ňŕ§žzŠuYŻżţş•‚Fe‹’‚¦tL[$đ·żý >?ü°nVo Ogâ…Đ Ü™ç¦4 źľwąŤĐ>ö7ŢxĂM©ŤR-˛*N„±‰Éąçž{ˇ…bź˙śsÎ ^Ä’ÂĂśqšđé€ L±^ǸÚ.i]Ş{Ŕ Ô  C2ťt¤°hP]€o|R&)[ů׿ţőÚkŻqţHp“dBÄĽR1°×¤Ů‹đlÁ)0eĘ.Ů˙vŰmÇ.Ôee¤dĄô–K_ÄM1ÎJ6Ă–˛ŠĐ©*%¦UäJȆGVżýíoÁݱĆtD‰EÉśń2yäAĚąo˝őKT śwŢy_|qÜ(Ö‹´Ë9¤eQVYđ׫ €`ôGttíÎ<@ű)nřV€•W^™ţŢ~űí“'OÖUÓ­pó˛-J ű) E.ĹĄĐRnČLËd č–!1‰3Î8!Ń?ţńŹ ¶žĺp ¸\.—€KŔ%0ěŕŇPFöL̸ËéźćĚ4H+¨µ`Ŕ {㽣Aš3ݰÎjęAŇć ‚s+¨˛ąRĘO˛¸fĺŻ1đ3 áĹ_|ĄČ$Ö"Rüž÷Ľ‡“JxR,°Ŕ,CřŔ>đţ÷żź×ŢLł©ĚŢf›mÚ´i,6yôŃGW]uŐË.»Ś[oEcVI3„Q%s"Íź#Ή1•m*R­.#zĹ÷ÜsÝAěßán_ć‘gbxîąçŞ$ň¦âÎ…ĺ–[îc1Ě7ß|tVŇ ť&IĂÜJ*1Ih'ÍCě4ď#ůH Ýęß_ţň—Ľci<ýĺ5Ű*;/ß‚:č=1c y©Ţc Âă7á"îď˙űöSęËóÍ?_ ˝ó˘m€×˙őú"‹,âϢ ŇtŁX˙řű?řUdŢůć]tŃEG±Ľë.V%ŔŹŠ}ćŻ —Zz©VyyůÖ$ŔéüşűÎŰ١ňÜÖyČ!‡°3ź!©…©M°fiÜZCĽ´K`@ą 24ăfŇa`Ă—"¶X4$Ů´…up¬*e6ËĽťŃ2«Q iu ÷ż(Đ VIX1aS¤Jf™Ě›đˇ0Á^f™e&LŔĹ:„ŁŹ>ú¤“NÂĂrőŐWăm‘URF–† Śx‘¬ç5ĄJĺb•­#:eI†Jë%@xşlęľ0üăyĂÜrË- ůë˘yKŔQB ď(DZ¤łôŇKł˛}@Üŕ”ŕ ·b¤S™”Ć’"&^{íµY đ‹_üɶÚżÔRK=˙üó\pÁ6ŰlӞΤ9 tÜ{˘7Ť3 ‘y @ł~ó›ßěľűîĽwćsŽ­ż°ő†mČAĘîZk·Ôî˙ą;t|đÁ[nµe{9;7—Ŕ¨’{VŹ:ň¨Í·ŘüĐCU÷ÎşÚ+~lÜö+Ű2Ě˝öşkŰËŮą5!Fw>řŕu×^wîąçňs+ÓŚI“&íşë®Ě@€5±Ůü5QEŕ{4QŻq Ô“Ó ˛lúť5űRpŽRH1ĚIż˙ýËcÂFzKH¸°–Ă5xG‘d…H“Ôb‡zŤ/âYOÁş•ż˙ýď¬Ę'đňË/ăÄaŐ…b6ŞË‚ˇv 퓟ü$nMŽäXiĄ•ŘĂ$¦' Ň<ÂČ6ÓÜ”F°XW2€Š.Ś<&x ®˝öÚ+ŻĽňć›of9ŹŐÂ$‘ľ0[\qĹq+,ąä’ÄČ\=22p»˙ĺ/á\bîlćir‹ ž/#řđ‡?Śe«­¶bUŠDˇľ[ ŤyRLVFI®$Ć1%\0ĚA3‡~xĘżE›w~üăăčŃÉ/-róâMK +°5ËŚÄŚ@01/Lâë_˙:d«­¶Ú¤OÂiÚtĽ KŔ%ŕp ¸\.—@w$ŔlŐ鄝vÚéđ#żä×—°ŽĂľő­o1®cÖˇ O Ä ühH` 5ßčNk˝–ţ“€´H1˝¬XÓ )›tOH˘\R<÷Ýwlb.OaiINně‘aëÇňË/żÂ +p SwyLXőŁl=‰›€E%„jV,nĹŤBŔ#đČ#Źp^!g}ˇ O Ć;€'…€ĺ˛řůČ‚@@DĚâ[†X4) Á‚W–Ĺ8“L~D#JyLôPđn°Î‚Ë•Őđű¬żţúěÜY}őŐqťĐr ¶,ńČ)=BĂ/†_áÜ}÷Ý8‚ \NÄcý⿸őÖ[㎡§’Śü&´ ‹_LäŞG`„DĽÔ‚ň¤uµď¶ŰnúKkŮD÷[gčš“@˝'i¤U`ĚŁK/˝” ¸Č]xá…÷Úk/ŢĂňđJüG 8Ô~ň“źpŮ /4ŽĐBVŃMuV>:ĄžZ̵±€…ő>HŇđ­´PěÜ9ýôÓQë ťCč÷Dj$ A˝h±ŤÄü‹• Ŕł'wŰm·őK(šxx^Ä%ŕp ¸\.—@OI`ÎąćÜcŹ=8ý䬳ÎÚe—]Xl˘!żÖj|¨o5×Ň ¤tŢŐSýňà ٤94@şd€’†dşĚüÂđĚ8 ĆiÂI‹ĚŇď¸ăMOŕĂy%ňłCdű8,UÇky–ĺ@ ¤ÄTď ?lł‡Ł^X|Aŕ‚dÜ(ř[ÖYg[8†Í°Y€~˙ oÝ3°žb·&„1ŕeŕ'OžĚJ ´ń;ßů—ѲŘä€7nÜpuadŐË‚‘冦l¬Iá_îčáĐŤď}ď{«¬˛Ę˙ű˙˙”dŽëéŔ °ô Dzrť +Y¸őŻË[–^zéޛ𳷦žyć™›m¶kRčNÚAőTŢV°Ó˘íýŇyR¬âvę¶3w†J Íçž`'T©Ř @Ý îÇđŐqŤÄ-ž¬şÔĎ®‡ŢăĆ%`O“·C㥜˛TĹ Š)&…K‹w™šO «Ň"¦ŁŤéKć3gdŻG7ĄÖźoŃXRL ·^×P9¤Ć’ÂâSÄ •żÓ3˘Ü”ZW†RcI‘)<¤ę4şc¤Ç Ź‚¦ů¬#x”đ,‚¦«RŰś¸Ç%`6.ÍA7„!VV É«€Ŕ°kÂe®Ź<ňúČ ‰ FńzĽ×˝Ü<¤Çţ+P8ĎHf 'CDÂěúFćlVś=Şř‡‡E‰™˛gęśsÎ!ąţúëĂmdí™ÂÄ1(śfňµŻ} 5cůĚĎ~öłŤ7Ţ^ň*CÄh#ß.´ĐBxîđqm2@ ÖK ąŔ…P¬şúę«ql~řá0ójnĄ4ö°*ʦ4)\Q¤żłÚě=É ‹ç„a*˝ć,“ŁďNr¸ęíNď:TË̸î¬CĚű•mßżbÜ”†¤şQ Ź¶4¤‚ŁśŘíh”+@±űöć1 HăR tßšxF6ęĐ—fÓBó›tżaĄňqdJR mhNK»Ŕ°äüóĎ?účŁ9mĘů曏“Gů‰~„ =Ř©‘Ű$–ŠpŐ G“pčĆ1Çsůĺ—ł&…°ÖZkqfĘ'>ń ž˝“iků‰:«'őÚkŻíľűî=É|đÁ¬jŃŹ0\’ÄyÁ"Ö7±# ç‡dëä]ÚCפ˘}răŤ7˛Ü‰«Ż…ock9;ď ,®ęŮíNměoO±ę”÷Ä^mę-6 ńŐ$¤+P†$ $E ś&r ž™lę’ĎRcF±¤4czx‚٧×Íő47ţSr¶1…kŢ#"%Î(“ á‹ćšTŻŹUOÖJ1!·S TĂä µö÷>€IPnJŤ<,3 S‚3ôVDIU—"i@4ŇüT˙ .ĄÖddŞ1—l°ŁŠŚýEPnJŤşÓWU`ézL<2ŽJÁĹŔZ Nîŕ`¶˝´ŘŚá-ľČ"‹p1ĘĆů#x‚X•ł˙ţűłö„žňŠŕjaĽ'‹Öć¤z^ď]júݦI‘?ĐĐy„ŻcP N™·(µ­´…)˛¸Ĺ–ô`ńŽxOxxąç‡& I LďĽöíQu™|›$Lř )Ŕ’öŠËrŔ$ )ÍĎÍ”J }‰Ŕ0)0ŰĚŕ>1w°ĺ–˛í&rٍcJˇń_IÓÍfŹş$"b^€#˘ÁĂŰȢQcřĚġ2[ϚҀQD$íŔD#J“&íR¤ĺ:€´ ŔM©}0“1âś)ÇŽ‚)ńbOĽýłơqžaĚW[/OaÄXĆ:ĺč‘ęA żÄ© &fqĎ=÷° „{a!ădSňd!€˙ß5%ůđ‡?ĚŤEܕõľ7ÜpĂM7ÝôĄ/}‰•¬RÁ_g{aSŐß˙ţw.ńá”đ,šĐrŚ®µłCŃAŕpé5‹h¸—ť ËĽÖxO¨o‘©1Iđ-6FÜpKáŠBá©—=Dâ™VFɨWµµ €R–,Ň‹|M±Tźa:â=‘Ś>ÁŢqE€ÜAĄ™Ň6Ě@2Îń OE°Í’µ1k˝Š¬T=ÇKJ‚uTH âU~ë«˝0EĆ‹Oď bÉÖŠ€Ř ¦Ţ®hFiVŞę¤0…ˇ"€YL)äÍâńIk1&)Ňáś$%l.ד©¤)Ćŕ̢5É"0%ĺ*‰„€bLZľ¤ oŹćEXȢ)<˙ĘBĘĽ,ßqcđćK ţUjDPţR˛ä›”}\˘ˇâPĹ3áz2ĘRî5$Ďą±Ö CbHĐvWřš¨FďßT+Fs 1Ii‘Áś(ÁŚťÝ:ĐĚ;<cĘv5Ś^9_Ď9đőä“OĆqŔ9˛{îąçr )ŹSfiĆÎÉ©\Üë„ő¸Wđą _cŰ_3×`łSŚmbÜÄ]Ët\ďL])Ë!»h¬ĆüÔ­(j„ôĽŘ á-7—„‘‚üęWżŠß ×!;ˇV_}uáŤK6ŘŠ")lčťBŁęČ2| Ôç4#nł÷$}Náˇ%'MĐ+Ź…vÄ Š 6P*ŕř/Í‚żFLnJPR]3zU¦ŹQ ›¦żÓčóęci ҵň7FÉŔ”aëô™AžĽ°^C€vöŕąp µńĄ#†ˇ‚Ú[•r1&%Ë6SLČŽôŠórp;ĘK¤$^Pń=ć¦T"ťŞaS "ĺ8ŢŮL L0ťšż0*oćRé‚)…&Ĺ ‡ž~dAFM>¸5ĺ%’OŰ&87ĄĽhJÓeÖ$C Ç»˛š e2 ޵ř0¤˝Ş„dim9¤~őiţF>YńĐ Ű\-žě HŁ$ŠQi‘0$ lŐ9đŔą8…á6böMř žĂ®Ë.»,~“o~ó›lfůÝď~wČ!‡p* ^-–f°D‚% .¸ŕő×_ßg®‰ß§á˛k騣Žz˙űßĎ̨ë¸qăćśsÎW_}őńÇçÂct• WLŇžš0JŤ!Rö¦áźâŘ]Ľ6ZËĄRĐęµÜP®5&ebŢËP€€ĹÔbpĘĽ2G3˛’möžä:ź=ęÚžA/>bŕ}šÔcĆ`qâKĎOO5®™JŠ2#«9\ ™ňx§ć„RHę1ńĽtl~!߉‚ócŕUH†%í]#¤˝q¤śJę%5űŮ‹>Ő‘'µŞ”q )Lă?=â QfJŹĺ2«X¬,é@©0"đČŮM©T>ł ¦D®YM R:™N˙‚AˇŇ씋!#šÂłÔ;XBElIsA‚‘A™q‰&Ä5ű2Ś€´Î ă¦T(__„sS*Ȧ€Ě”( 1SĘ’Ń˙hYłĎ=SâC˝4Vpˇî€€@Ł>ěB ±…Ň‚Ž @ÔM´8Ő ÍÉĹę‰9;©8Ţ9•ó¤“NúÔ§>5d5RúČ-ŃwŢy'óy–˘päÇŽ;îČumđË}žN=řŔĎ>÷,K—E MfJ4«ńĚšzűż—ŕbJ\é¦ÔĐîęůL‰Q>{–Zj©Ź®ôѰ÷!~‰ňÎ>ŰěÚż3flt_F[”`%ý\Ń Ě»P&P@YÁÄ<«ď%Ş`éIP—ZЬM üČĎ­:h,Çť°c ďĺ3â:țǴĹ[pĐ çŞâ:ˇ ÜmŚceÄőeH >ě°Ăţüç?ăË`Î%—\ÂAKv‡M.ý^1CĆ~ďb·űÇŔ÷Óźţô×vú~ÔxĆlÁÇÁď…kąW±~ 2–46>Ś6 H‹¤ ¨‡%Ń`Ô†y .¸€{a™űńă÷ŚđŰţh×ČęďK,Ç„ź7ţůĎrÉń¶Űn;˛ÚßDkyrtî<đČ#Źüŕ?8öŘcuô Ô\©:oT`%©E€bT]őB™Z„ %ąz 6xĺ•W¦NťĘâb~°á‡O<&M´ßŠ0+ÁŤ‚÷‡ÜÎtŚ IDATmĆÇŔć#ö^…vÇ™ë IZe±XŮ!/"h Ň*%ipŹńžčˇŞçö€łĎfíŹ>ĄĄŇˇHŠŘÖ^Ó)“Ř:ž4ů$NŤâĹ Ç­˛Ę*l9ăÁ§Lv ôŽxŻýĺ/ÁĎ;ŽĹŤ^xáľűî»ĆškŚť}lěĹŠâđV ?üý·×Š Ä’ýĄ šëD¦&3fr˛ ·Ösô1Ľ…)™ŐV[ŤŹżí\=%Ćd¬‰ăÎóżř˘‹ŻĽâJNžß~‡íłź>fźžĚś©Ż»ŕŕL©}ˇ9$–UŃ5QZ,ŔL‰¤}€ůş=ňđ#‡z(ăńç«4nÜ8>O´¤˘Ďr —‘>űěł,2}ňÉ'uóčç>÷ą}÷Űż$ö‚VX‡Bód>¬McÉÎu, Ř“Ä@ڧUAĂy*300ý×{’"`rAYĎ?˙<żgŘ…S†¤ÚĚš—\ăY–…„—1¤gŤ‰B\q2fU[Ź’ýeőb |XŕůT ąź(°÷Šµź„Źüă¸TÔ Ť˛€ŐrŠÁ(Ś:kYÖf0ôW4†ěY ýŢu^Ź\ݶÇĎOa’Ąr1äfôńŻ^©`¤@ÄěĐaĺCg(7ŢxcvB˛*ŚSĘÖ‘.ž’Ŕ´iÓđ›Lš4‰)޻ˮ»ě°ĂüÎÇ‹U:¬áixéŘú“hzé_=ĹŢM‰ůžBşzK/ôăŹ?ţĽsĎ žrĚęß˙ýßÝY©czP XxȦß[o˝•áőĂ?Ěď“óĽ{žŕÝă€l źöđuž%4bJ0kpmł'’6UŰ™ă 7˛|—ńCö?ł"†pf©Ň.^•#ňźýěggśqƵ×^Ëpü°˙> şlO>ŞĚG*|”ÁaOqĽ«Ţ”šR°–$ČR„ ”‚K9ôިĽ]ÍKŔž»i…t@C} Kä7aQ9c$vC@ŔˇßůÎwšŻŘKvQśrrńĹłC„9±w±ća®jĺ•W>č X{ÂH€cti ;$ŘG/!=Ú΋ÎvśŁíj±Ě8}O’d=Ă;×Řžë řpdŻb<xLZ'’#n$ÉşąQřˇ—]ü¬ź%&<óĚ3ś:r«řpl->¦Ţ묳^u*L[˘—„XťÍ&5¤őůn” ¬é¦0Â4ŇÔá˘É<=íŞ^Ď[o=|W$‰yý±B@Ţ-¶ýpk1ŢýéOĘ~­ÓĎ8=mĄH*ÖŞ~—2‰ż~'ëÍ·öŰżű~żŤ`™ě€H™8ěŔ.öß˙ŁŹ>šÖrÉŮľđ…±sď ÷żő…!‘˘— Äŕí`fDO šď#Š˙dMÄÜ[qĘ©§śućY0Ô? Ž=¸Fšň±Ë›âCÎ5~’ÖsÉ‚0%ş%$p#¦TłˇSbÉ—Ž´Ů0»ßÝý;÷ 7Űlł3Ď<Ó—nŤ4%ňö Ü}÷Ý|Śńŕ8ńÄçďüsŚť_I0Ą°ţ†ÓQjë%…IĹwđŹfćŔݬc˝~üdxŤ_ž$13+řđ‹(ĹI™¤ î č5J_Ň÷'I˝Q3_ —ąMě&Ö$üË_ţrˇď{Áă§8&ŢxľX7Ô÷ýÍuq+n¸ˇ™źO®»î:Vö± …M‘Ś®yŃ…—g ”ŇKm6‹Ŕ đ_pµ3+ńV°PÝřS–K‹Ř¶¦€Ď‚Ő.–ŰQ?&żN±…U Vľ`§V#žÜ(kŻ˝ög>óŽĐRőVWg‰!^ł Ă`ÜD¬Ř˝´í‰ú&=6Ŕđ`„T\-‹đź~ť¨-[aTŞŔ–\'( şĹ ˘j>žëčM ŕŹ˙ß˙ý_®scĆőóc>aŮ ĽpeĽbfŚáž°˘/‰®3nˇÁ–'‚-?‘_’Wł\'ěPÝi§ťZ¨Ă‹ş†SLŇŘ—Ëŕ[nąĺçüb‡íw 5lŘ!žmělá§ňx OH¶dK¦”T<Ď !ţGľP'Nä&Lx8Ĺáu»š•ŔŞ«®Š…ˇđ”)SpDń?GLź-l·!čL‰á~0¤A>KaˇT i‹@( ç4Ëáľ—@NHJO7jO Ěą°¸NđŻqÉÎç?˙ůľKßtu ¸N8HĄ }Ó©Ć;ÂŘžőm´d¶îâ=á0¶ĂĂ^}Ľô4H@ŐÁË"pšpÎ.'Îţß˙ýźđdˇ˙x%>űŮĎňËs„áZŽśe5„]wÝ•Vá cGŇm·Ý†{G»ţi9,fĺ›Ç€…nâCIgé±Čz‚zY˝€oł÷Äކi·…$FdŠô~̉€\ø6Ű>„¸@š‚„©S§jÎl\ĂRß”d)2™`ř`8`ë­·Ö`ŚŽ3$Ł×X70 8Ť‘ ýU XqʎSĂ;uŘzNŇ0B¦Éś,"mtťdž8!˛éź~7?ăô3=+K7ÝtÓ\qOşF˘Ž<ňH–˝±±qŞĆÚ`#K1Ł kÜ@'k–3ŕĚ0qń 0ýćĘßđ9‹_ř±–Nâču ° nA.e@ĂőÉ0_|f>5×<ÉFúŁRpËń ¦ZsKN™2…qxÜ‘Ś*aë4.^–ëĂ÷Űo?Zxę©§šŞ'¦Í"DŐWI¶ŁXť5Ŕ0˝,o[‡$`şŢŁq@Ô¬öó*Ó0Ľ'T}Ę)§đ~‡Úŕl;!sÎ9‡}™´óÎ;w‚˙HáÉŃ'4U繲çL’ÜÎĂňN™e™~08M8dwęÔ©ě‘áä–śô ë$÷đ‰¬ľúęt„E(dËHxŽp‹pP gŇá…çüŕ;î¸_m t3OMŢ^Ą@®®^HvÄ{Rě<]͉©´óV05~ŽłőŘ^>cć;o‰8礗Ą¬éYŕ€Éo|ă´™[NíýňÎôw0k<&‚ÁJ “±ÔëŁĺ  od„ĆX¨&\úc·»×ăéx—ŔH‘€> 7\?őđÉŠ>ýlGL@†„5Č@+ş6@S;t9R‰?ńUż ¦ÄbUQ«ŕćY.$Ľ',ç"VG˘äFbR}YS°Žěs”­É*öÎ,‚” %jź0˲XÖ1}#ôY§ŻPS')1 O8®R§Ărj'GôŤFIG¸…€žr–ߨ:,¶řp×[o=\! @ČbKSuî'G_qĹ_ůĘWX]röŮg“ä|%á4a1ř¸q㊠G†ĂqwŰm7Öˇp%"?&­±ĆH€ťwśOĘ:ΧăčY~ß"Čä±wBř¸Ä /‹}_črúęč tÄ{’뛺Ý2GCŇľĘaqtü‰€3á‘0űŰŮýU,â—Ŕ•k©h9 ŢxŹ?I (|©5ŃGř`Fá_Ť3ŰĺWŐMđô".”‡–qÚ<Ă~Ő‘Â×IÍ”ř¬´ŇfŮcfDŃ))ż ż±Ŕ–Ş­0÷˛.ž’ŔüóĎĎŕž&Ý{Ď˝ś/Ôľć‹oĺĂÔJŮž’Ź7f¨°G/€8čTaá pĆ'lXŕ‡ëˇVáôĂ+¶¨ÜyçťřMFůÂ=Ö\°(•=ămb(¸Řϲ÷Ţ{#(h0Ç×€‡ú€`n;ĽŹŻŤµ/¶Řb{챣0:Úe—]řŤ–>âe• ţ56+™»D*˝ ěÍÚذÖYuĂ{B+%k®IÄ0)@.Űŕvz'›7†9_§"ë©S§BŹôÓR»Fş8YŠď îXV<¬7© ,°‹`LÔbh¤ł˘¤”L)Ľžä‚ ¨¦L™ ·*p°S# ťĆ%0"$ŔeüŕCS§<>…OFĐu9ăďŢč<A{ľ‘É”róĆŔ5¬•;ŕžzę)Xů‡©y:Í’€TzĘÔ),;AߥöÄŮ÷e0S™bő:…GĽ©­K€GS‰ I±~‹ľúę«9ů›EOüLť×zÝłr`.Ç‚_]łf¤¸e–›_E9iҤŚĆ &É”ĺč‡jň•VZ 2ćXM9"rĎ;ď<ÚąńĆ#şÜâcbPŤ`‹‡Î1:śĘÁ\ <đ@čWXa…ľé$·DˇÉŇ|üJč6ëMp2ÎG>luaeß…^Č>—¦«čý‚¬uŕ}.<ćŚÜCűŰß°&n :ůä“ńˇČę-Ö:^ _ ¤b{‡ Wß»ä=±îI,YçIöŰ  Ś î•ĽBA¦|ĺĹë™Ŕ9ÍA}´ťUmö‚Ŕ€ !ú˛Ł8F©YŇŔx%XWíw7Ą‘©)ŢęÁ% Ä?^ÉL)Q43%XLăËPĘŚIÄČT_ű×k ýáé¦ÁźŤSŚ( HĄY€±HŰŐ|yň3¸SJMoD ŔŰ~ 2P,íâEĘ‹*™XN0ˇýuGŽĚŮ8€Ŕ!í_.­ŹĆK/˝$Jö–ŇT ™R6ŘN-0Oć0Ń}ö٧†!€ŚIcŠą0÷ĹĐř/}éK­wˇĹÇ$ÁęńĄ1ťSupap´ TÓvň”ˇdž"[ąÖNíáöwN|â‰'XË©şxp8v°ţ#¨,˝ţö·żý裏žzę©ěKzá…xë®».î6¬^^’ôU†mŃßj@ďt¶ŰŢ;2W1AH^Y'zKżČ#…pĺ‘Ň+fÔălBs ˙$0ďĽóŇ)~ ±S~ÂĎ}™6óˇhĘ—šL*‡Yđ‘4l+ż.‘ůwŢ|+üä⦔ Đáţ€L‰%!öůŔ¦XA0¨Ú.L$ ißS|€ÇÄĹ_ÉoďpÖ' ÎoĽţ†Ęş5Ą2t¸$ Szű­đŹ Źqˇ0%ţEďdj2ĹŽ3üł`1×1},T1‚ÎÄ·hxÇ2˝Ąz˝ő‡A°*–źĺ™huG&Z+QZ×ůçź_ŠoÉBk®ąć®»îJ9p˙+ţ”ĺ—_>EŽP[Ř~ÎnśDííBÓŹé«_ý*'¶Z¸ďľű¸Eř›ßü&Ż#ÇĚŁímjŽŰ&›l" Nś)?üáń›pFěp]<śk^—“¬&cK>”ăŽ;×aň8sF#LśĆ%0r%0‹ň“¨)żR˝” ˘¬gőŤrj@ŇćB4IŢkŻ˝şŕ‰^uŐU,7s—®+yńĹoĽńFövúŚEv‹uÔQnđ:Ŕ!´“ŁÓZhˇv5¸ĹÇÄ’úhdN 9yD÷´«µE>\š#$ZŤß„[ś9OŞH6Ş0ÜK¸űî»?ţřăÜ.„× Wčj/U©‹Dď â‘R·˝'ÝÖ;Ô¦P cr”sš7lĎr Śt ŕapľĆř‘OS¶ĚńÇďŮ΀ &nR€ ÖDŕ†`Mo…ßâGş¬Ľý.  íهăťp5 BpN¦!8?ę~SdJ"ÇúĂG}b™*µT4Ăł\#]¨}fJń–ÍÔĚ0×H﬷żíĐ‹ÔÔ$*¤ź—ëEĘÜňž{îaĺÂĉŰކ"CaRÍöĽsŮeC#™úrFšËĎăÜîÇQ.˝O w)˝`şIg™“lŰC(HEĹRTÄÜ~ňäÉ,aAG‘§0ě€`ó»B¸,–]'E2šJŐTJ‘.żüňűďż?GFcpÝpĂ ĹŁ@r”ŐɻツŐV[­šlHąÍ=¦A«Řn»íDĂq$·BŔ4ů’¸=*§K°eŤČFÂ’K.ŮJ3z°,71s»ëP¶Ýv[¬€{ŽY˛Ä€·ëPQÚ0Y‰‹’XŤB—{×CŢ“´çČBI¤#ą9,bJŰć°K Ó@ŰUEp&Ęâą?˛ łŽFšaÄÁ‚‚ëFg ¬;il„ąÓ¸z\˙ź˝;Öî¨ęF/^żňz żkRN „BqDQe†(E$ sa2b€@” @1I HĘ ?8•7ŽE@!(heaÝëçý=Ď˙śővö3śç<ĂyĎĐýľŐgíµ»{wݧ{ď^˙^˝ZG ß“m˝Îĺ±ńµýˇY°[Ąm#űĘ©˘ŠX°¨ž¬Kŕ€I`ěË_ť3‚třŃĐÚ¶^D°ćôę? ¤ U_BŚŢ¤ăpőŐW»ä á¦7˝éTĆ Á¦î ɶţ;$k+§  ;Ů­e˘ťĎŠ/@(·\:†Ö-f&h;wĐ?ţă?ždß÷}ßÇÂePsĄáłŮáŻ*Éb‚Xţćoţ¦-&ň€<ŔÉ&\´:ŰE•nr“›đ3đ{Ç;ŢQQńţĆoüźť÷»ßýŢúÖ·V9Ö˙ůďd Áq)¨čŰľíŰYćÓKW`?g4Řßö¶·1ł‘Goto˛~tÁ[aôˇ4NţqlÔ~AO"šcB­îŤ^Ąř#ńeťďżţ·5sÁÍă(˛ţč.MK F"ă` Śţć%2"śş:fĄíŔ™äH/ń±ĽK ź\<J˙ՇҦĚ^ţń”€!0Z©0€ňQŁ%ľŚ©E†’Ä,rŤ2ŽV>FðŁë˙ďzÓëăŮćţě. H@owóŃWCČe «Ś…<ť°Zô"¶Ň1F¨ Ł÷çvĺ‚óPö¦ťľ@ń¬ß˙ýߏUH=—˙Ž~đö<čAR»â/M@%¬«3uQBč;ÝéNłJsŞëŁő(zµĂ_śůú°‡=Ě^đÇýď˙Ż|ĺ+ÉĹNÇfÇú8m€…ĂnÁP—Ľä%JÖ´Aáö§đńńŐŻ~•ă !w9aq0ÍG?úQ^ó•ď{ßËä$É>ôˇÁžŘ¶\zéĄO{ÚÓÂLĚY©-0—_~9¸ÄşĽ˝8ŽĘmíe—]&M•ąÍUW]őó?˙ó¬iŕGm!;Ňź˙üçĄYď92k˙™ô=ż8ý\Uýľ'ź|ňŽíZ1A6Ýçd9,Ź„–źĂ7a{6Ú§GŞřŽwĽĂţť'=éIďyĎ{ôů+®¸B_Ę\+źÁČÝohü‘+ňÜ`ďëĽŰýrҰ0#…éMÍ@Ç©Äc"‰ aqĎů#ţˇ§gďÜ.C!Ţ×"!C`4ső/!zÚx„Ěj®„•** ľ·ŠţGPî¬:żKŕH`ÔŰ먑mĂ“ |eFCe>ô1N—q4Ę8ÚäďČ‚k{Ú›;\č;ŇëMč( čđz»XlŻ2”¶FÂx8 }eÄ“a4Z2p¶ iĆäő˘ÉŚťs8$ĐţĚŢÉ‚ţ“š Ą]p”¬&Ç@cĎÚ>uóN¶íäÖžŐ$zöłźM,¶Ď ęŃl–#.cňgögŮécOA'îÚ¤ăL\¬Ä€­ě¶ ň2* J‚Ł!přËŻýÚŻ\˘dGĂŘQjKŘ‘ö;Ć4¦­ŇŽąL°ôĎÄľ†č*śzę©ö:ŮJçŚG3s ™ë°t2gHÉ;uK×e®îéĆčă¨ŐÜN JâÇĚĄ Dö…ŐeU’‰Vąď)fťÖÁFΫ¶űfpkW—ö 1űň]sÍ5ڎ1?ѵoż9F=QđzIÜ»zâ‰×ŚžÔ+r‰ŞË’™ił˛1RG˛ÉĄ¨řXâNu : l™CŹ:ý(dXieŤŻ‡ŔVú±éV˛§ŔQ™ăC'ĽŢ .cĐĎGźŚ|AĆÝ>÷FC`[ĺ;–z65JŰă/Ł##—zvî~§KŕŕK`ŰsĐö`ÚúvčüőˇY±‘[ĺô ŢŠrÜÇŮóë3Ű?ůčú_˙E1«>'{٨ĺÖşkS F^Eö˛&yď­»ßýîEu>SXÄX–w—˝ á±"™<©>"a^{íµ)0±­@Öö[Ž]?.YÜ Lx‰W—wżűÝmúé:şč[ľĺ[vLĽŰK˙LÔď75dŕ4%O‡Ážžđ„'ě¶&K¤ĎáÄ%ź%JH–µxşyÝë^§'č<€$ý‡… ›&»˝Ś;°EÄ?ŽKbPUÇáŰYÖňuĹ—˝ěe7şŃŤXr=đĽůÍoţ]ßő],§đŰd‹Óú°ťJJcĘäw·Ł§°’©oŹĄ´x•)÷×Îť­ééx’ĺ•ZŞŢH|Ŕ¦î÷dđ3öËĂ%/‚zAdŘqPaôš˙»ÁĎ6WŰJ2KŁ˘ĆŢOęí3bŽĎ ŐC—Ŕá•€~žO†?ęôß8šŁkîľÁXë»Ađßß0g$ŤnʆIţMB %4ţŐČĂŰŤzËĆý_·|‰Ú>˙M˙ýMŁpţMéÝĺôş÷ŹQ„#˝6ÇďRť*Dé–ńĺY7MPöh’¬9,›óýáqď|ç;U‰› ᦟ>(źşSon{ŰŰnŮĐa)>ĚlqšęśÓ U˙żű»ż»Ĺ-nQ…LZôÄ5,/'“;J˛Ç։ʾQÖ.vť,’~Wi–ţ™îr—»đ¦Ń>‹šą°§bçąHɧ­Ěâ4O7,’l×Ňř¸ůŢďý^[´¸łáéšć¬čŘÝbYĂ~däçfŰÓ îE/z‘‡˛ľŃÇt{gÜčę“f& VLŁřr“§ßínw;ńÄ˙ň/˙’aËůçźĎxä oxC™5-X`’ŮëÁĽ÷˝ďÍDčá8?Çv®éŘîć:cb„wËvÜŐsLĽţţ˝ŕw‘lüî5M…±â¸‹ě=i—ŔA“€Ďžžžx¤¸›~¬Ł%ٱ´U¸1µŽ{]űUㆡ-‘šşüč[´­ są_ĄĐëŐ%° lÍÁĆ31Ĺm ¨5Ü‹8ü¨—dqf8u‰p|iáá•Ħd}›iÇJĐ“:mgWĎ]Q7Îł>ő©O…ŕŁdÎÓ“Ě%“inxĂ’#…Á™Ę“/}éKIđżĆa˛śÝž^\z˛M2?Yâg<ţńŹźÚŔ=cg•|–{îęžnáĽřĹ/öôK.ąä)OyJŞÁÖiô„›Љ˝ZL™ę¤j{ÄxuĆÓínw»sÎ9gąöÚQĄo2Âb‡rúé§óĹ6*č$@‰’˝:— \îtâ)kŢąłś€ą´ß[5L´/téŃô·ą5ČŐ/»Ťôó­>_ZźwBţŹß N[%  LsÇŮG#h4ĽF)ŤĐzCş&%0ęđŐŰÇëśAŁ[ă2™qŔ‘L0h2 Ńl±bŠŇ-""ë—‡KŁs¬ËŹľ ŁQSµmHĺp5ş·f=ő•ćM›ËÄşPÍvčE4Źüěg?»ž/\Jv…pÁݧ[´ĺ8ŕfáF ×rđ-ł<´×Ô:]ŕ#IIQť YLͦĹTáŐŻ~µťSCP¤9… nŮź‡©$^âr-?ÓĎ]=KbŻĐŇE6’}O7|âčWη.čDviRY˘nÚĹĂŽŚŻzŐ« :qÉŢçąĎ}.‚í‰xéŔř €ÂęĢBˇŢ IDATXgžy¦ŁĽ.Ú 9Ţ$â íëeéçîqˇ'śę†¸^ű·&ĽÇx;6¬'č8¸ m°c«Ógć:žĽjWł8Ęޤą^ [Łx׌žŇC—Ŕá•ŔÖ§ckÄŚ†UŤ€&i}.§Jbtk{¤Ś •˛]ÎEÝŚkŞě:óĐH`ŰďÉÖŹ€ŐĘÜ­ËNt ´Řę<ÍóWb‘8G“ĐäŰ\{@óÉzűŰßŢćž>śúˇJ¶ Ě×u'-Mě”Y˝Şö§dńüSŰF(U¦­|—D)Í–śěß©!Ů‚ëŠÁ­ö’)Jŕ­¦ť‚N4»u§ ˙rŕ±§|á _hźµ.z‰źi]Ź^±ś„'ÔĄËY‹§F"*ŕ ěA5–>#\źdÄÄÎh°7JůěYÄÎ6Zщ¬C‘(Nt^ ¶wŢbÁCČ«aئ]yÁ Ú¸ŢËý‚žěŘÔ$Ĺ}‰c˝] —¶˙$0ęä×WŇfŐqrŕLry%Č”W"ăó­Ń´m-R#e~K·rĺOJÓă±4Šćgďw»´ŇńGC)ŕţö@Řú;nú@·±W~$3ő«hAśô±÷}éçţç){ď{ßű>úŃŹÚÂkĂ,i8ŁÄ­Żýëí®„—ľôĄYŘź•+üŘłĐ'ç8éŚSOčÉďýŢďUiśJXçwÉC§ŘRż“†éŹyĚcZď$ęo'ŽVé+ď,‚KQ:óŐW_ýÚ׾¶Ňř-·paÓD ŠşµqË[ŢR2'×.’x‰4‹˙LKľą,ä©đś±«Ç™ăéFi S@äÚkŻÍozÓ›ÍOó‚v1Ä0v%ö»9ôz.żüňŚâ¶ž»řĄ#tWéĺĂĄqШĐý6!ď–ĹK^.ĺ7-—mďr™ónIb CŮ»G÷'u ' lőůĚD{éUŞsě…2žß»\ĄĐž·K`K †’Ďjó1YµŇŁb·?M}(­*Íž˙€H`ÜëGŔaHÝ{5÷ŁęĺY=Ę! jóÇ‹ěeĄ™ZÜńŽw%xč}îsź9§±Đ3ť¨ú‘Ź|䬳Îr.…V.ĹŢ©=ĆçT›?w?÷ąĎ`8Ô|ýë_?™pŁ(%ŽVá>–ÝÁďüÎďH +É& {d^ůĘWr`ibB‚ÉŇäźř×-üžČ¸ČYË”ůç<ç9üV<ö±Źµ¤˙?ńŽ=âCÔ)žuĹWdÎd çpT† ŽšĚIłĘ­Ĺ¦Už˛ŢĽ€¶lF›zFŇ‚ĎZÝÓMíDcŻ48LJ 'Ď]šZ±sź.~›ŰÜfŽ‹ślÇ›ZÚ®lŻŚ/Ç ]xá…—^z©—†Q „ÄU 'Ż”ż$®k!özR/Đ|źÍw5s4ńk’>Űa®Ąń˝.ý)QůTr«˙׍ĆÉŚp˝ îx˛›B˛l8DŰĘŚ:{ťĚ›ýX:đŲŮfăÁšŔ:ÖËşľFcg»·ű”„ŰŚ“ëgj®’¦Ń«Ńw*Ű‚ŚĐmK–&g'°h T8SĂßřƸk­účł3K†Ŕ7Ţ`ËrmnÚŚ¤™_ĄµÖĄvŕ%0ęN™Ř7?¦öŚĽ˙ýďżě˛Ëö=!Ї>ôˇAOv´ą€Y<đt°CUeTíłĎ>űâ‹/.źŻł~ţJîwżűBx'É6Š©)m bZÂĄġúžwŢyOúÓ+=gźĚdÔŮ~Ťl pËîKôŚGÔů—ůV·şČ& !…l(¨Ŕ”zÖâDrq»»x–ݦ\ügÚmÉJOág%ÁâcauO7'ťtŇč]ýß˙ Ęw´ŤŐĽÉ[NúĎŔŇD‚Áć A^řÍiłŁ=(ç^ĂC·–»Ô·I猾G<â¸(Î7H™ę,Ś_'Ł˝ÜɵżĐ“¶ĆZ>š›Ž?Ő-żÓ]GSy#,×ö©y§2—+˙ä®›děŘX¦ŚÜ\%™/ÍSźúT.ŻÚ\ÖsžřÄ'Ú :pÉ&ĺßřFS™ŤÎ<ÚšM:šŢmź5dfń—xÄqĎňŁ?úŁźţô§çWăŃŹ~ôE]4?ÍÁ˝ë¸ ‡#2Â7'{ć3źI‹8¸mYcÍgNĆ2śĆjđ׋:˛¸×˝îĹüá]ďz“„ Éáíă0(ś7ÍI‡šŇL~‘-„¨¤w…“P(iĚC˛ńa°çÔSOőu<ĹÚćżüËż”.}Ýu× Ň(óüóχ•YĽO8áž)r Q›’-Ă_˙ő_Ű&ĂZ„Ů}Oj2i5C’m® *čüĺ8p`áAíá)Ä;^BOTŔ )jÎ’hÇôó¬ř3-áŻôeă0żV»˝Ë HÔn3¶é.!\,Gřômo-čéĆŹ«#Yřŕ?ř‡<¤-H×^˘A- ˛á¨ná ödĹšĆ!ÄsĐ@µzŘĂf\°´ŞV$ôđ3Î8Utő×ýמÄS&'5%Ű€˛µz°b{6—}ôŢŮ~óDُX›{p/ąKŕřJ@·ßîůtţUj4(!E®RŕĚk9ÚGbÇPľČ&  SÖ ¬¤ÁéŃ˙úŻ˙jÁ‡Ő.˘ŁÝˇ ě\mtz·Ř:ŰćWŁěcÖnˤżŢhŐŃwéPÝoÇľ–mĚűVZ¦eÔŁŘDłžű™¶?CÇşú:†Ň±ň;Ő%0–u+Ú{{¨ęţ”ŤőŹ»Ýínw˝ë]ť,^I›}čĺ“ÉěßüÍßlž`Źx:Iz3 É/ţâ/ÚÔCn“ĐÉd±“Öö"Yr¦Ď*Љ’yĐ}ŐUWM>čhrě7Ńp°ŕ*Í_‹§›ŘÄ#I»¤÷ÉO~T7¨[śű@@j«ÎżřĹÉuśč{ňž{îąíAK@křżôKżŚcPţŇ—ŞŞ@€ć5×\SNO(>ŮľMâ„cß©Ąź47ăţµ=T› 6-‹Áűe—Ŕ~Ŕ¸ßŻS1ëăhőź•ßďÚA:YZlw­J=ň‘Ź´eCňk^óš (1޵ ;Ťmä±0e`˛„ÎY»Făh­Ç¸¸u̵7y•m›üă?«„ÁÂ׬d”Ó}Í˙Ő_ýŐÚ„ŤV»ĆđdŁę…z X®PŤĹˇ¤±é°šíźŃşŐ‰!?ź­I6-âąö@´h•JÚ&Ă>¨ÄŔg•rV¬îé†Y%gß8nqŕe2ć$Ľßä&7±g°jx˙űßß6™ěńáÁ‹ýG¶ś?řÁţ­ßú­J†ŕ/™EĚ_üĹ_°Žá0ČąBl®Ąa ‚Y{pţk)>•[ž €˘MĽ=ň…ÍĐơ­ęéž\ŻÍý“}=qô‹Ă&=š•ŽÓÇŇ2ť‡ă·xđš“Ů {EŽÜ8ckˇźźg?űŮbFą㱢,`eNiýÖ’Ř«~Ȇ’ Ő%e~ŔłĹyŢć¶ `ńěŐh:Ŕ"ęU_XÁM’<4ýPŔ±őőŢ÷ľ·o¨ý­w¸Ă&X]ř!=áqŹ0ŚYp¬KE?5ŘOŹŚc`°ÂŔQëu\ÝÓŤfŃłžő,@ EP >PśîÄŞEO8$ćý—ĺb<Âň1ěT®vč‰Y®]ZR˛Ů,/ČfČŚDc 6Z˘Ąół0ł‚žŘmÄŹ¬žćĄÁK¬u2će"z"üůĹîęîÁDOvŐÄž¸K K K`Ď%‰÷Ěźţéźnˇ“ŞĹ/üÂ/0k–KÖŃ“K'-ńµŻ}ͬ%ĆV–°SYuŚţ“†čáÜŃY‰b[nőśÖ-’ł{ř?ó™ĎpPľŞXŘUĬw0OUxĚŹie™`Ů dÍJÍł“ÎŚĐŠ–Id­V™óIP˛z„r¸ŚoËIgx‹Č¤ŠęD—Ŕ”@t›AĂ13Ö»´DAýööđJá™uÖľ•A9ýr?HŔ{•c×+ŻĽ’ůŢGO|"ŮOůQ(ü‹˙4Ü SÓŻîé†÷“K.ąÄYK˙řÇů-ć§ĆbÉÔgťvÚiÜŁŘăĐűX}}.-«Č;Ho‹«ÝIô0¶Řfüî¸1mPČâ—N/vô’ĺIć0'ź|rľÚľň!ę#ľxK¤Üď~O–hRĎŇ%Đ%Đ%pÜ%ßôÉ©5ńęö;’85Agv ěs °Ív$ŤĂ5!6˙ۙϞ¶Në4±C ŠÁˇĄH«Çúü\€?hׂ)•lˇ)F1ĚŹ=Ń’—˝/}éKU 7rŞd®8!Ěçđ…ň4ÄŮ%ă/űşŦú­o}+LÓě0^ń¸¦C3«˘8 ¤ Ŕ_ěę7´¶Ć“Qu‘dóeREu˘KŕJ ¸Ib(Ip'ßC !ţđ‡{pfęĹĘ<‚;¸Mć_ĺmŢa]{p[±zÍ}’řcµ‘s¦W/P FÇęžnś]Ŕş49 :IU F ‰m>,SüqŹ{\qvEČľ#t˘ŔI4‚NňhN|¬¨CűÜI™´w4ťţźžź†ÔÁÜúÜ ĆÚnpŻüj0eá"ă«c—8tA mX%n!AlŮ|9•#v>,W«TĎ˝GxůË_î{aĂc,÷č©űŕ1&çĚéö|‹pűµj´slżýŘÇ>Ć8zç¤ű …—Wµ*ňĎ˙üĎ 7µB»ÜÍË'ź­őֺ۞¬Wž˝´..Ă/đÇ"JWjáA-NÔ(~ď}ď{­–›ú˛>ţńʏÜýîw?ü"ë-fv2¦ŕ)á ŕ§\&ńłn3ěŹýŘŹ±€ăÉňČŠqß6ÜŢ$‡7 Ǣ LöĚ”ěyäř,(Řľ­ůz+6ň˝`$őęWżz˝%o®4Ăjs…o˘äL<ě« 8ŇĆúa.Ţ›xzGO6!Ő^f—@—@—Ŕ dőhâ 5 ‰Ył”ŽžL‘Tg Ě1Ô:v%ś’Řç2«9‘jń”Ęá<ȲÉ(OĚ4(Áq ľHHOVŁ}´%©ö˛čůą’ŚŤFhń„ĘŰiNq)¶w˘KŕĐK  Iš AĐm»¤Ţ°+[7vÉŢD\śâ;¤„úÎwľ“Nn=˙±Ź}ě+^ńŠUŔÓC/ö˝i §T<Á1[pZ­—łCp'źË}8SDÓžÔ>™ňp®ľúęle}ĺ+_ÉËř!hŃţlBŢ*>îŚR˝O\2^—őzA«Ľ÷‰»a¶ď˘UÚŐŃ“U¤×óv t t L‘€˝ ćynđťóÂA"z íżň+żň‰O|bp«_v h d‡šcą*ŐŠ[‹§”ؤP"|öłźýă?ţcfĆ< }á _0Cµú4Üż˙űżĎŞÉŽ|–çćd¦h€›řůźĚÂĐf’Ů9]]­ á„0Ń´!š& ćdě®ÁxÚi§ńUÄüÓ÷ŞNžPŢ>´Ó›€ź‰+“˝„&ŃKó řQl…xüőžűˇůçŠŰö+nkü˛›¨Ň>)“"7=ľÎŰ>ýôÓ÷I­e5‚ÓYuż6¤±ál®á=Ůśl÷EÉưÁĚó‚Ő3 (ű空ܾ¨kŻD—Ŕa‘Ó}Ë,ZcnŃşŘlŰçD—f„-łÓ]]9ĺ×&—I;mšluÉŠńâ)Y˛€HntŁ9Nř»żű»Ť)!3T®[ßţö·;ĺÇ=˘ĂȰu•2¸µă%Cš€o(ßĎ“-b>ćXĘľľŁ{‚.zdÄĄBti%ší‰Ff,PbŤ"öˇ´Śśˇ}×»ŢŐt((öîń^ä\Ř>łÝ›Ć`ĐÉGNŇůô§?ť'úÉśYòőG|oőI|„ë({-ťPöÔ§>uÁ=ˇ{Óśő>Lď{ߦďڎů€ţzź{KóNpž‘†›(ń~ŔWĐsKĽvfpíÂ:XęF §żă;ľŰŽ‹xĽ»ýíoOa»Ç=îńţ÷żĐ‹„N đZ´Ý”ۧAKëIZćÁap·.™=űŞ%ĺ _řÂâw˘KŕK@‡Ď©®öiĎzq˙Ţďý ]‡řÇęM[Żr8%ĽcňCăüăÂ7%O\<%/Ë2>éIOj«Jărü‚e8ÂÇN é(oyË[ÚŚ»Ą©˛Ř20Čč#뫪bo}ë[·úe—@—Ŕ ëEÎĐÔ|sÂw\ßL·˝ím=âŤo|ŁĎÓţ9Oě·V‘ŤÔ đä“O&jGNh­T0 ·ťźüä'ÉźYĐ­nu«IčÄsľĆUŤ—© —ů*5Ů·yżúŐŻŢë^÷şćškŕűŚŽ1¤îăÎřËş…ŐÁśĽ÷? ł_yH«~¨s%Q D.7]ĄŽžlZÂǧ|˝‡G˝'<á _ţň—YG;9ě§~ę§b&Í]%äţ’K.ikţ0&ěăĎ˙üĎßö¶·ńsÎíS›Ĺ„5éíA5„Ú[-ÍĂźCć’Ňâa{«Ó]‡X^xˇÖ9Ę”§ÁҶÔWÖ¶ťč–÷ąĎ}Ú[hSŔOÍ甌ý˛K`?H d¨Éąçžk®Şô·ű·Ď|ć3]BŢ©@ĹSúIĎݲm;U Â~{ń­o}kGü |éć"#¬K›Ën_-óîo–f7»m•ßGvĂÝěmÖ數]G\4gző‡ÂG‘ä’ľŔęDlD öÄULó¶vńX 4ô, 2;ďĽó¨îTtćőz›ĎćîĘ+ŻôŽ5“ůЇ>ä÷˛ËÜh•¶?%V´;>Tv^Ţ$ó:=| «:ç/–ś)DY<ŰQ& &Ř:ŔWú¬ô$˛D=­m#\pÁŔ3—†AĘ\ú)ďxÇ;:aÚ温ĎbĹiĘ*±e?Kňz_~—ô›R6§fŮ3{Ţ50XIâÂP¦>tţÝ©Yć0űÎť9Â9Ŕ·xŃł#Ô‡çňË/‡ĐĚÓžK€ČÓžö4CqŇ]ĄíľIŐrÖײ°@ăCŰđ|ßűŢ·îśĺ˙|ÎÖ÷Ęމ.Ă'; ř´(mŁ/Ź|ü輢ÄĄaxć™gÚÎŮq$f.™qĹXqęÝÎěŘ'đ±Óó ČjĂdËǬ ’@p<ďyĎ«z.ŇĚ[J_.«Í>aflźűÜç>řÁ:óXQüĄ@¶–Ö >ň‘ŹśuÖYô(ł:‡˝B˛C^–^šö8^ź˙üçsTiÖÄQCř^QĎ˝âŠ+Ě«Eťčč%mđäŘ_łSZMgçŽ%˝™Đ‹ź(Pý§ô%„1ţ‡<iÔ_{íµŹ|ä#­[€5ˇ*É5«&ťżŁHŰ&ťóĎ??5ťŮŃ^­ßůťßącŢ© ,č‚¶á\Q¶Ůˇ”n25ýAaúİ:ů«żú+"ňá3Ů[oÍaV΀łŠ5ź´D=yÓň¶*9®ÎtÔ‡,i ŚSӻ˰Żęë^÷şżřĹ%sJ%¸šfdŮ:gči¸•> äŕ0]%ŕŃd56ÁńeWě-nq ń:É[˘âM<]™=Ů`Źs±9ěŔʎж*ô7ßťL6žDOôĹö(VÍnFćy·»Ýí +ôź—vłIËíłĐơ)¦‘ćąfŇ»ý˛KŕpKŔŁ:Zowtź˝oBµ×ŔqňŽ©^q:Ń%ph$`zm*ÉĆÄvwó¶´Ë—ĹDÜ1ĆÖ–«Ą ¦¤G_L-ë™s·Ů/şč˘ö«Ä‘ˇó8L7-“Jćë#×Ĺ_Ü® TöĹ łC+Ű43Q!ů\ ŞőÍw‹‹±§<š–TĂKaĆDÓ|ÜňNČn;zť`Ľ[üCHC[َ%¬¸t׸\†óC?ôCŚ#¸/¬O0 Xśŕ¶óo (‘n‚°¶ě +ś%CÂÇ<ć1ÜN­ř,?ŠB”ěÄ4Űěĺ<č§đŔĐď˙űnzÓ›Z'Ë"ŮŠRd÷»ßŤó =hŔ\ZWxöłź]L@•± !jŕ‹Ů&ÚŘ©V™uP±!&łźTp¤‰+»•ěZ•’ΨŁ“—1čIĘÁ±Zoi†xę©§ZŇhËßťťďŮü Ä›D@çˇan®=ŮślŹ[Éz9¸Ń㡡“•`éä0Č‹ĂđTE9q€Ę @o 6“ÖueĹîZu7 Ůł`[ý˛KŕŔI`ěŞňwUm;üŕŰ ë›ÄÝ„Ń:<5lŇý¤b}“„]•ßw ¬W9Ex‘2M•j¦2™žťsócú F=Ż>%K§dş ńŮ2” ‹áÝvúÁäŰ>˝Ź çR˝|ˇ¤xčŕÄţk˛&á­SoYÍľßýî÷—ă@µŁ­yú ĺ|™ ÷Ë..4’" pÄe@4A%öÎÁ,M©ô%Ů­Iď´YÓ^Ttp­Ó^ě“ő®č˘^P `LęčĚTÉI y/Xάdŕl_Ş>Őť)"ĄTôYYö-źaţ9çścń˝‰ćřH­˝Ş~Ţv}ď|@çţ?˙ç˙,ë’¤„*úléü* sL’ m!ľČ­%Ě&YËŔĆ)?ę§QöžłľüÖoýÖ*| ˛?ýéO˙“?ůö_¬TšµÚâAú¤‰ôśIČÚźŰŘŃ“V‡„®n°@'‡M¶Š2«Ý}ňÖ,ŽąŻ[ŢŞzŞOZ%ó38ąŘĽ3‰ždŰ»JFÔ•Ą]GJđJ_ ú©¶÷Ćq M ‹aÁ”Öš˛Ü4żL“»ÝínóÓ,q×:¶ťAÂy{–..HɆ$“ IDATŔ2V'ć“M˘ÁM‚`2E)ôX ý”$±BÜJťô a×Óôµ…2ٞ;{Ĺ+^a ŚbůQ€Cůk2N˙…_řŘń˛5°)˛Ő®×ŐdĘżż°f+Żo{ĘSžňO\Wů{P€žqe¬B?ÚŁ˝˘yă¬:s§`ů9Ő®T¶¶4?(ôÇú÷=i“m†bEś gy¨Ér;~ ťTŹ`«b„J¶艍E z3»®:ě1Ń˝Ćî±Ŕ÷âq>ěgĘ|–Ú[ýöňšĺ©¤MYtFŽ5óÁ ÎŽë Éś—Ă·+ źRڏ xöfY@¨[ťčččččččč8:ä‘i¤ę!„ť$4fW¤Ł…¦4 řEČ儱Úr416¶ăĎ2ž˝Ě(¬ŔOΊŹÎO0«ĄTß .¸ŕNwşč„ç5;f´ č$`(ÄŚŹe.wTŽ1vĐďrŠĎ ’YčD_ĺĐ€ŤĆ† ˛ZpŰάźź[.Áµíśdí-†¸lý¬Ę[’o“ÍhÚâÉMl\ާ„ŕlĹIOč;ßůÎ[{yŮŃ“˝”öŢ=‹1‡,Ż+áý„GŢ(—¨ńĆő¬=8ňÚÝ7(z€™…‹ˇĹűI{WŻcF.ĚÉ:zŇJ¦Ó]]]]]]]GGť.©Ë(.& EL/M řGz˛ ›lýÍą<ÁPZš#?łV+|¬QĄ°ŕâw¸K7 x"ë0Jş#ţ,lt2Ągć`÷SŽ9Űhç¤PěVö“·¨/xÁ ě‚ŮčCW,ÜÎV= ÖOş»Ů´Ő ‡_ä3ŐĂ‚máÄ$ÓIx‘,–˝A-ĄŤç•>ŰT­ŁŰÇMlń‹PC«ňF\q6Dpˢ9NΆńĺ’µ4Îŕrí•é;wÖ.Ň}Q <^…Nč0ČA'‚š9ŹŠ=3{9Ű|±&ëjGb@ĘÜâsČ( ö…x`®ě6ďŘFnóNěPÂ϶·*Y'şşşşşşşşޏ˘ŢŔ/‰KN,ĽU0S•@ŚăBľâ1ăsËdU RbVĚËĆ·ű·S˙¸o˙űż˙{6®.«ëśŮyÁ©ÄćĚöů ŚMüBOö˛Â2cD@'w¤ 磛wĽšSŇŇö˛&óźĹqŠ˝üĺ/§ş«;&Fp°ąp8ŔüĽKߵ׆ź/úÚrÎŹ Şwż*«šÜ¶ĂÍ-"©žńâYŇł¬˘Q÷Úőň8ÍŁ3IřÍ´}•Ót–Jś¦ŻîKxqůčĄ9Ű5ĆÓIB /m•”=YEzű:ŻĂ-Óűß˙~çTuzß`ĘŰĆbęŕ€I~NqźÚ*^jł0„‡sCŽŮ|˝0üł°«ýASÝ™]]]]]]]]]4śjí.—b*P.ĹąŠM\ŃîĘE©CT( …•Š[ b"‹[…ž„Ć´^Í݆”4F{¬,Ú`·‚ Lz cmŮ…ąkUňp´eV'ä@2ěǧşJÜ´řxď{ßËĹÉ>°- wühđ¦á—ÝôÓw,˙ _ř‚í9pĄŻ~ő«ŰŁÂ´!+Ív9Ů zŰ‚°«m; öÇŻ}íkŽőuňihG¤Ć®šÚ|CŔoŃŢâ¶–.iaž•'DÄ @-vÁ=Zjł¬ťö°ŔoüňŃë'0f ůAđĐINj‚żĆ*uôdŤÂÜwE1j„( jfŘŰí ŕ€Źx8Ź€‘ĹwĄ­7lµ…HôN&ŽÜĎľIŕe:dÁą$ ä–٧ ćÂ˙P[~§»şşşşşşşޞ˘Ě$6ŐŚ((H‚KH·(ϡ“€ŞV ˘hę\nHä’×-qňĆă,Ą«řŽ&ąĺ-o‰ď 0ĹĘźŤ<‹_üb3ç;ŢńŽTbx Ď”íëĎÄnTÁe!71´âOvĽË(ž¶Â¸TÁěťĂÇýŘÆőĐq©Ď,6Y9ţĎ˙üO°6¬ç°WŇÍ\ęB”)Hś]`1X{%ˇ':6;‹EJ¶CGLɤȆ5«é“· v$ßÖ6~|Ů"ŃíÁ°ę.šTH. Ä”Gi¸G1¬>>/yÉK^ůĘW˛$Şôk'Ô‡AĐJW1´ŤôĽąl‰µ?}P`GO9´—Ć,CŕÝzÇ”cía«łľÓňG?úŃ Ć%¤ŕ =±y'čIť¶łDQ=K—@—@—@—@—@—@—@—Ŕˇ”='íB„hR1ĄŘáŇ]qôŐÄ8#ŕdhMţJěBŚ#NvśBL¨y)'xŠ4sµ@c}ńşë®¦°›ćz)„Z„ˇđr*X&Ü•ÁŢüĘZGŐýÄ'>!ŮŤâą ű°V:9řŕpŔ10 '%Ů`š¬-$?űł?Ë´Şß:ŘśÄ`"ÎĐáîŔ±MyŠť_pđ.„“ž©wńKŚ´úSN9Ĺ‚ôz«Ä ‡VĹjAüŢ7¨¸‡ŻaV§uŘđär ‘(tLKčNDśöm80·4ÔbX5¦˙řÇKĚŮĺzĺŇřâ‰9ŚnŔü‡đŤtQôčUŇ )čMÔ$evôds˛=n%?ůÉO6ží”{Öłž5Y °:””ËbďĐz2™~AŽÁćÇrŚ÷)H6TŇÚ]s –Ó“u t t t t t t t J D« 2B˙ ˇĄˇÓ$s‹¦*„vK@'äRJhHá&nIďÖ †žH %w] ’yŠUCŞ&;k—&±űÜíz€ŞXl˛«]áôCŠ´ŤBvő~˙ü^šĆ¬†‡@Ë Qű8ŞžěkdÇ}1Ź/qĂŢđiO{ýśžňú׿žo‡Ú~#~y'µ ě(ĄőVRU0Ŕ±?ĺĂţ°n |ýÄi2lLę'– ?wő%ŢOÜĺŚăôÓO×Ö»ď)ŰvK´`KA9đ‹ĎIƸƣŮű8 Ä1:4»Y‰5YđPÇ*Mp˝ęUŻÚzb0˛7Đ@‚8[©˘}„N¬ÚËY Y‚ßŃ“%„¶ßłŢş2ŻČSѵ‡ď2EqŽŻÎşckjcÔÁłŐ ž§¬«ü^N—@—@—@—@—@—@—@—Ŕ!“@” żv™—š@RP©FÁPbZŽ”Ń`[ `Ę‹/ >µ'*nŁq”&Až’Ä.ÝŠŔ§7ĆC„”_˙ú×!‚µ@ź´ŻA`¬Q`@…ţžďů*˝@ßÁTal%¨¬v±š7řdżIŐ3 D…©ŁLl¨ľű :©Úr=óKă÷aň–·ĽEëř¤sŃ8 PÖá@•°#ÁČb’ŔQŁ_ą˛°n8餓č5~A}#˝ČÝęN= bB™"O* ČŻ_…¬HP¦<â¸řŽÔ˙á|ÖľVpŽă§@üîďţîÔ]T0¸Ç=îqv6X’_±Ő“Ů :{—ěbĸĆ(Î@&ś6ČË”Pt“%ŻÂéčÉ*Ňۧyo{ŰŰŞźXŽË™jZXÍąßzüŰŔüÄ»ĂćosĹ>ä!YcὨĂ'6J #M;Ľ'[Çĺ•M§|€›djâ%8™¬sşşć%ó<ź†Ż”CÉ~f‹{]h]]]ÇQőAGxG ÔTőe łő&·S™ĽÁđă#DR!¶'ř8E Ů›¦‹%vWś»áRpŮĆ.sK,°ˇ¶ xâ‰'ćŇ›Öäą‚•B¶*ě#„0UŰÜTÁhBh †Z©^â"´QÍ­h N=ÔăB#8žPÁsëRi¤ţâo~´Ľ :Q7Ф'ŃĘľO6>^x!44ó؆ő5ăpĺ•Wޤf:z•hĄ™đÁR±—ú-h2ą±*ě ˛/¦…K”ăW`Kb©¨ěcňŁű…Â%"=ˇ/ˇu[fT ¸Ă4ćřŔZÜǨ@‡Ž¶F8&­X$ÖĎA„R¦{¨>ăR3ăśa˛çř-&o­ÂŃóáGžî§dŕŁëŔ‚Khi—žî"ä'ç2¨ßq•úTŢŽž”(ÁÇŇĄ—^ 54’°cÇ`Ű6»Ôr~T•ăâöÖŠ´­ěQtę·•×–Íi+Řłn ŘrÉ,Ó"É ™\ pźĄşĹĐ1ď^Üë}Vů‡†_žvÚiw¸Ă¸[źß(¦°łyĐ«“ň~ŕě‹öŁ,n,:˙ýîŢH`ÖP2G´"d–ýíUďę‹/ľŘ±8ť*+śßěHő1ťš Ě>”ć§ßęXPíÇ˝T Ó455Š™4E·Ĺ&ŤÓT$ł"–˝b‰•)1"±[‚ňSZŇŕ¤LHÍÜ›ł8řtr/X gBtu±[±Xiëą 3Ć ţ/î-B¨§€.‘Şp‚Ź0˙7~ă7ěBÚD}6Q¦_” p%KŕĽrXŽŮI Ăa·Ď%Ú8I`Rő ŤczVä†P&ščZ"ý$ŹK'áťÄgÂÇÂ9ľś€@pv[™AzßOyĐ4ŕďÍ%Ď•` Ď2“ĂP(ě›läˇ`F8šđ@ŚăđWą4 ĚE)­z8˙µ~#żHB~¦Ŕ%hÁÄîVb• ĚÉŰŃ“9Â9¨·€ĺ<éô^1Î!‡šSŠN8á/M™m€Ô0«™ŻŃşÚitqTťÍsgą)Z×ăz9ZěJřßᣧµ´ŠÂ>ţź¦YI°TÎş .ć6Ś·c«%zřnű¦+źIŇŽO±´eńĘšXĄ4ıęUśNě LJŞm™ČDÇâ$Úş c¶ĐćÍ™GozÓ›:L6˙÷íCiľ|úÝ.%µG!č¨)0(Fb—bĘ-e5"—±@‘€Š%nmO|ăpÇö$ib5 „6H)ŕ¨Fâ–.ľÖ›HaFޏîŇ?a(¶Ďj%­J‘ňŰXömőđz5YÍ˝Ŕ+a.d¦MZb‚JŠHĺ®>±‘yîsź» ˙m56G›´pŞX~íš1E¤ŕĨÄ\±,ö&DGný×mzI\T!żL #éµ*w+÷'ň¬µť$}‰á­ÇĆ61”/ÎSĚ]+ýDśžl=1ĺË !5ÔEi6s9ů‡łäŞó§ö8ÓÚŇ‹y8éUŁřâĹi88„Pü SšîJ¶{ŘìóĹŘ$?™8—~>?±ß¨\ć7Mň;®XźAöë ąÁ˝~yp%` 1`A’×%ÓeˇÚ6Ąć“i¨óCúĐ 'vńÔ;Ń%0€Ż¸%qď>ý°nyqóýn%ŽcĎ.¸ŕ[Os×+žá‰×·˘žô¤'˝öµŻ­\ťXُXąÚ ˝Ć2{Q•Ŕԡ䉬˝çÝe‡ĚĽŮ‚)Ej´›7“mGL…D¤‰ó«U—H» ‹ážĂ˘{j>Yi0Hië°8 ʰĽíëĽ"łă[ÚôܸX_I«ńŮ}„,Ěżë]ďbeŁnVĺń™Ű­):Ú|ţĚ3Ďl Yš6?ŽĹ,üĐ+ř±_ť_-—ő Şs…Ą+°cĆŽžě(˘š€%OKŽŕfoÂ}”Mt¦Ńóň'˛E Ó<CŘUSy Źň6•Xh9ˇÁ3Éěś#+'śégśq†›Âĺ—_čäGń+>ÂT=™cs/î×˝îupč;ßůÎm‚NŻE‡iFµě˙B¦% nçťwžą˛·={ZóŶ!wąË]`+śíY‹;묳 ’íÝNŻE}(­EŚ˝#"ÚΠĄĄ¸FůĂ/éKb膺.%ĆÇ)Űtâq¦-w'hĹ&q '{â.:!J褫yč4!tŇŕ„ĐŔâ ZşŰËh†J+ˇ•¬ęq)3OL¬VsXI•Ř$ŠňąŰçčôL/ŮGX“łO™ć“ĽŠu›„8A«#çü‚b’H5ť!qډËś“]§3ŹďqŹ{ĽôĄ/ĺÍ ~¦Ĺ¨fJe÷±xĆS2Ňáe,b‚Í |PsŽ{<ó™ĎdćĂÇĄPŹs·%ë1ĹY…0Ď·©ÜüÄĚß>t;ŞTŚlÇöÄoWaű§ŰúŐňó©ĽŕGŻR™YyŹÖř™%…Ċˇó÷lâć÷¦íO Ľđ…/T1&U=ž†}Ř\:ŽnťTĆ„TA«4ĆzâÓ«ö]Tóš °÷­Śź"[(˝msu‰f$>o]?Hc'-ÔßÖMŢÖ˝Šň=°Ď‚»2KRĐĚţáԓ釳oľĎ3ŔúÉůąÍúP•5žŻ-GdNPß›Í'ŠÁšýFV®Üµ†1N}Š&¨ŹĘ[~a";5Mg®K“CIÉ—\r‰­ŕWľň•č$ĎeśČűŐk^óŁŕË_ţr<ĂU•BŰO®—2K‘r0$K/Ő+ô —†žÉ˘m›ąL9ڍuŽ\‡č3UřŠ#±ĘŮq(-×{-Ň1X,ݏ=°ĄúĄ:Ń%°´ňŐó5)EČČŞŇđÂń}ϸĂÄńÚA$}ńq%ŕĄ(Ŕ.źÝ`%n%ĄX‚”Sś$.ľgḋ¨ô!śˇ+Fě6¨•,â•]MpÔA<~ě°Z‹’2ę.ÄüG~äG*ďŃ!žóśçXQöa2­"Bós‹uщ+ŕ'ŕ )1Á$óÄ2ű,ňrĘŔÓSŘbXś°ĎĄĚ¨ĺĚşdĽż+ű}6łŠšĘ‘Tźśš`–ňĹç—0†!–ä•ć+?+Ë®ř¦÷đ&+©r™!“$Ńů¶Ť™ó3ÍůÉvUŤEwôd)ő4]]k“«jŐÍo~óÖżfü«yF0”©;á„ř˛ňM¶ ś`&Źé`řÖ®¸â px%šKc)ň¨žĺ!ĺĘ]QŞ&,ćüóĎŮË^¦±ŁŘ(ú”¦„ł+ÄÇŐN:újN¤J±âXq}.ĹjNyâĐ]Őł¶¤Ňyłł©R"ěďĺI‹ě[îŇgŚĺ—u•6Í®hy=ÝoÁTRĆ´š1*‚mš=˝™+Źçš”|ň_SČW­HĐĄÓZćÚ´őé®ÚxOJxŮe—‰ýp:ü¬öhĆ »`BO )§ź~şžVąL\žţô§ł¤°ěSĚôR»ŁÍDRťˇ ?>óÝŔ¤ę—ôö¨Ű, [Éĺž ĄÝö^5Á ^ROŤ5ÖĽCŞÉ»%úPÚ­Äzú.¨©‰ë[±Pö|nÄîŇ‘ŕp‚řîŕDżµL]t8bßâĐ!ŮC'öÄđë®ÂŃyhÝuYA!ˇżčâ"¤)zĚžiŻ{Âe )~[ [iZęFÝőrłlóËżüËÓźtŘąń˝čEŚř@±äR÷Đ—Ľíu$„Źť€NŔ!˛Ĺ$Ě9żo›î«= ÓS±¶˝pknfÁ˛ŕărę©§—ił°öć|ä#1ýkNÚÁ)§śB’‚mYÔŻŕ'‡V üüvŇÔçWóK ~Ģ]®˝¶=Y»H{]]ó$@ér;®Ľ+]N•·yŐW­“…pŔ¤×ů"bž|ňÉtE gěvŃۡ*|ŕŰô”CoäkŻ˝VbfÖŕ8T>îÓčZ+í8tBžk™ Zş_Wö§<ĺ)ňBçsË’ľ:řTP;źđ„'xőJÚ˝âݰ·BŔüüź93Śb‡ŞcŰĘK…íxlĘ€,ľ(¬<8ß[0Ş\űWŤ“Q´Ú@¶Ŕv†b Z˛TŐHilČEĽ¬{4Đo!/;L»E*e'Ö%©C ŚVó9[šÝ…Çť{îąmM]€ĺ:ߊź`śţ ±iÎlçÜ› ´éÍá, P#Ló/ţâ/8$˛v¤VŚSît§;éíş.šąŻnŁcTöUF⮆҂˝—E'bŞž—Ăąt]MśZŐ^‘X°2}(­(çžýI ĘO4XB´'ʢŇK“ô4[ŻŻäJ2„€ ń†{kĺ–8ĺ7qKvĚ”/N]ÚsĂ ‘”Uá$ČeKW‚"Z_]"Bˢ.Sí‹®g±–j̲ŞüŁFXݱl`îdcŞé·ňŁ'Ž.g$屎.Q#t śěC(D2LŇF$±É¤)śów¸Mřąq°Pgĺn 7Zż´ęC¶ľ{Ţóž7»ŮÍ€#ůQĆżŇő˘úÉňëDć„Ч¬÷ňz“ˇőÝKëč蔯Z3 #T—Éôs8TzŞť×%`˘îř†Qăy,7Q ¶{L<ĹK>ÂÔP±Nő¶ŠnAtB“´ŠžO¦ÝÖg,Đ“Ął^ýęW{"mÓ˘DµĘ@˝ôôz›ŕŰEŁr 0ŘäĂ#LŮć°oťÜâ·`MckŹ2)®¶cHS寅°‰Ă|‹áIyS·zĂđ„=Ş˝Tq˘d÷Ó5Ôź@ mnAŻľęŞ«ü6’ř®Ą>˝’Ŕśˇ$ÍnG3(Љ+©¶ţi˙6ĺŇK/m}<+_g6ăyţóźo¦â É4Śź9kn†mq—íiĐ`D‹žěŮPZ¤÷2ő t˘9ĚOĽOÔ\…a—eü…łzX¤2}(­.ç^Â!@Ţ*AB‡ŽŠďRt!ř|»ôˇAň~ë{„ĺ66ą›Ľá-/:Ć)—-]I8%¨ôu™_ˇ˝ Ťßs~¬Ľ‹$@„‘8ĺ´±b#uĆŻ¦ÁmY•’Ě9çśdÜLďěłĎf~bNeĺ §,Š(Mť0rË/ąr›ŢĹ Ż»h2OJt‚9ËH>1óx3±Úç IĎ=˛?Á áDgĘĘ%M¬>MeąÚ5«4–Ůgku’ß«ěMÜÍO&±źLړ߮‹źĎs9xôŠ—Łr{čččŘ řŔP!LĄn!¦i’¬î'DbĘ۬ËÁ­6»2Ű\sč¤LQˇ+o˛Ł¤¬6†HĂiďú8]áŠăßţí߸?ó±€Ý39Ě/ĐWĂ^N‰ea˙Âc~úMßµ™rÎřś¤cDn‘¸ňs”<]†I¶BîŠŃIcÂăť[aFěhw­ZZ yvĬO:é$óR˦[şĎËBA”L­ĆNLw™Š›E°=‰<É0#7"ă1ĂŃĆőůÖöĽ6'„n{˛9Ůö’»ş† H›qËŐBRÄ„ˇµćśvm‘›ŐĂŕ¦/–#EŢ÷ľ÷ĺźşëÍۢřöXo·óĹ­JŘÂËÝWżÝłtv{8'' ¦9î$©§#¸.÷Ih9\á |ňĂôŐApě20áŃđ3Î8#[™’’Ů ÇmQ@.*ZÎ|üÁx¤MC7V=Ő®úÄSo)>{mJ3 [ĄÜe dęÖŢęôŠ?”ľ«Ńd(éđFMŰáSC{Ż:’íflťŞÚl'+†Rn±¨Ş4ڦŔŁĹßłˇ´cď5 Yo©X ĚŞ!‹ĹRm©}(µÂét—ŔH oÄ^Pž(n t>F$s‰öyĘ-1Ą+Ěđ-ş„SÖu«MdR PqÝU“dI•Â'Ľ^TĆ ÝĆęś[ř“!-ÂQqńsK=“7UR`ęŁÎnQÔ327|ÄâË<,^P´Y8ő|âźhň`F'ŤGŰŰËÚ˘ć ɧ"° nËUÇÇyĚŰ[Eß÷ľ÷µ“”‚m_s1wKPÎMT^˙ú×Ű-nZĄoÄşQ€H´w©‚§Dćd+¤cH†&dÁŤĚ‰:´ŇÜu‰/°Ç Xýb‡bUŹY4/{$óGwq•ş¸ |„`ůŇŰ0™+čÉŔ¬]†k›ŘË×ĺ¬Í¨>‡mâł+Ę·B eŘBźśµ/`r(»sęÖA”M‰­l´—ŚAXE¶P-g>͡ť«IěKćÓeŁPŐÇľÍ~”Aiź˙üçql2đűĺŠ3”R2™·GJÍ\ݲ Ű IDATĐŤ©C ÓDÄX0šZô„Yr[f†ÎÔŃtĽ†ŇŽ˝×HŚî19šôsC^‚4łĄöçît—Ŕq‘@)±íWÉ Š«>bt*†öRŠ~+–Ţ-Ý»ŤČ› >¦ĽáŁSTŢčdÄą‹)¤%Ś[Ě”YwóôJŹ?+T--}.SĹGMňPDhLo0Č/cXĚzčTľµ(Ž´@Éžuâ‰'‚|Ů?ő©Ońmsf±Č®¤=Y†xŻKi|lÉâ·0O0çá DŕÜ­ÝFdÇ"«–ÁôlPç!J3X ¤Yä҆bč ×'d8RµÇAő¤&ˇ@?ýHúăSŤ\ihł ÍDK‰Ě]¦E$‹Ř˛“5›†>ń‰OřQ€YĚOŚ/vµ •ňbĚ`ŮäóUŻz ¨?°ĚŐy!$Ă„ńď°eËÓţůĆ?×(ň»$u{&–Žžě™¨űşşľˇV!blR‰3T°Bq¦ě?-[=ŕqĂ—[ďM‡őN&ŽŢŘÄ#ÍäŮ«ÉčEΔůŕ?XĹâN p.ÎÂ"uvvŕ’Ń/Zv(łC©,{FřŢyĂb@?7»ŮÍ äzHÖ„Julję^“CM ĎüL!4Aŕú€dbKJ8ř>¬bAbEą+ Qlľ¶[Ö˘›G§1ÚOÄ Ĺ6–=Â?‰·žcśUrĐXÚMćѤ$†F!»,۲e".«t˛ý..Ĺ!Š6:6ÔŇ%Ç҆jÓ‹íč8Üđ®LťÄŃî,ČÂ/EĹ—ľ]ßHĂ*–ń°Pűkx'™´ͱ#ő™O9^¦wuątvß îT=‹çu{;m˛nď˝ ‚žL;ÉÔ3í-ýą˝ç[Ĺ9óĚ3Ů»Ö%˘{ËźEďXúÔ™CŘÍëĐ–©ĺřěMĺwćŇ5”ü¸,¬Yß3'›U>¤Ë»ľÄM|$yMÄÓÓÖ8švěTyôdĽˇˇäAÚ8  ´Ł©ĄÉźŁsşŽŻĽI:­Z}ĐT©1o„SĐZĹ^Ś8©m˛Ptr)‹K ”!Nö¤q7|=­Ň „Ü ]—)łn…·!‰[Ú'9áW±Ň¤žő\„ŮĹHY[Ł=Y§ŕúťßY&±¶ ·°§ĐüĹNµgy ŻŻoK=ăI*ß—jÄÄîoZď[“źUjUeî–PaŽđŮđúVFë!K“K˝"÷”t!â%p?q:›Ľ”-Uj‰ÓÁ¤ÔŘ«ÂcsNNńÔüú8p¶ZzĐ49ˇÝm÷IzËf¶zůˇŮ\“•Z™·pz?2o$"MŔ·ŻFë'MĽ .CČ. Ĺo~©ŠClH=Ů`{±]]S$P¶ťľť­ĺżĂ†}QčiLßđ†7LÉů ß`ď.čÄ­řˇôŮórô}‚ßs,2ČâüT ţqąĚL‚^]Ű LîsiďΡ0eżĚ ™U –ĂhVh9k§}äĚ™LѬ± ś{l‹©-Ë̵?÷8k(‹©!ôÄćphă`'W f0lý‘•ý;•&„U˛űa4mh(i Ń4@O,$¶#´ĄAÇč—]ÇKĄ Ą¦¨gT©h­8ˇéW8ą‹‘4áăÔe–CÝ­Â[~›R‚A á’13–p¤ßľ9ÝĄŐýŠ."yŹ(Jůˇ5!™Ř™2źmłq_UOÜ‘Ů'k-tR%đ˛Ďʉ HôÄěîşë®“ \‰Wb„™že$ÇۧŘö֞Ѥ=!ł—&p¨č:Oâ(ç«zš)DÔdKň„ěR±ôîšÇ˛=I!q}"Ť`E2ŠhÓ ŚĎ~öłLr`O(ᬳÎ*Ů^dĄ-«{&–u=ȧó=ďy?Á@“˛;¶ VcÍ"H†H›—ňä˛lO$ŽŐ‰ž#=GšÄ8ĮûL@ iKëjZ•łµ?°®Ź,ÁĐqÉűJěF>iÔ¦ú}U·ýPoCŘy—ĎrżĹ 'śŕyŮL¶%8„ý'”ÚŞx{+´m±90őĆ7ľqV3ĽCsÜĚ$Ú’˝µ2θ™,vo8QJ^=šu€¸ťE-X R^}őŐ¬ÄçŮ)< ˛Ćdq5_¶m±¦ m|5ťÁÜň;˝şf %% ­ľ=ŐvĽO>‹Ń“i ľÍ;&ü‚:¤™Ü ˝¬’`ŇĎ ĺ\®}(ÁŹ0Mç^™ňîAŁÚGôˇÔJŁÓ]‹K`¬4 # UX^tQ®J%vŐ gđ…J€¦­%MizuIĺk™ˇÝmů.1+ĺ|˘ÍŰŇ“%¸«z©Lš§ň_üâÍ ¬ó[mZ\’”Q€“ŤJăűÎ č;Ţńv%a–Â<+ËsžóéY¦T!{Ldĺc§o—8˘‹Đp?©¶„d8%pD~ŽÄá'}ňÖO,AB8ŰW[Í~Á%<€‚Bü^ ‡ÓO?ÝľQ3X‡ÓY8\b–¸Ç"ő8?7P îc–î”艞qűˇú!„ą™wşĄ–XíeK—Č3tío„éŇŁ3Ć+޶wôd$dCČú[ąq¶Ęn*gŁ9?Ŕu;á˙ t“rń[!WćŰßţöĹł$%oŘşQÝmޤ?ŕ°JL)ťßđĺĘ_1˝šd)¬XΊٍp: ×›âu¶bc7‘ťu˘bËH=âĽóÎóIóĺđÁp~pëĚK™˝ÉţáJĚ{H­şpˇö´~ŕ)<6,y»tq•‰,ČPĆÚ:8'Ă|‰ŽtÚi§±ň°Ęa7í»)V9 hłćÓ>hhÓ BhŽog=NőžűÜç2‚  úvżë’Ŕ¬ˇÄ«=Ćž%±ČĆx¤úE!PĆ…bşĆî:•±h]Čč{ĚcSs_·ě]ϱßXWµW)gíCIerF• Ŕ»Ţő®Ş›~»‰‹«üYDJł$Óů]ł$PZS3á"ĐB´¬(`SéÜ*ť-z]Ô9±ŕV´ľ"Ú4ą%¶<.±XhŚË¸^”4×cM\ĚJ“ÂóPőIľTL¬-Bž˝‡ń+7Kz;ň3ë¶Ŕlę;X÷J^6&ľ 1`Äá8ö±p1łwîŇĚ(Ď<ěałphéĄ:-! …A2· ¤W‹śIL@gŁÓŰc"Äm=×N÷ť;#‘Z3Ń?÷Üs#_Kvöˇ…~ó›ß¬ď†Äz°ŐJ9¸»ČĄąe\¬ô Ý•ÉŔˇ8 ę“°`úÉd—]vYNµŞ ;śL°—{˙Lâ/ĽđB¶my.|Šd¦îĚßËŠy{xď}J;xxŹ}g[×+Ĺqi”7 Ďí>ĂĐĚg=ëYô:«%”%ş_śx˝^tŃE€í ë÷¸TĹĎA!ÔU|}­m%µŘâĽMż@«&ó ź§ú}ŕPCG&ł4Í-řT3z2¨©®>ż4wÉŠÓ 0“2}Yďv·»°Îď˝Óř–Ŕ^w|âüć"V“€Yľť,Pl¤b+ä<ćśHwĹWŕ5żś~wW5”bD<ůÉO6,[Yů1€‰Ţ¨PKs2 Ŕôđh¸<ŃlCbžM×LÝ +ÓŽń ./^oăă8Óme˛öˇ¤pCF…y·8'Â0AňNÍJÍ·_[MÓ}(mZ½üĂ*ösď…¦™¦ÄâĐą §Rş4ůŻ™s¤ÜJ˛‚®Ň*q[uB܆äj9şŞZ|!őˇ­ŕ{Ą+'LüřÖD¬*ű„‰–ů†Ý%6NŇY ň?ó3?»÷ˇ/÷[bˇŔ¶*ŰůhÝ . >ĺ”S|tć›Ŕ°”4‘U—ktŕíT˝Âj'ZÝń Šť<¸FhÉD*V"%aáV‰Ý­0ŁŢg5].|q‚¤I9ĚdKÓNá&ľ;ľÚh“a24­…‚1Ť¨ K`­Q°đłP”ö&¨’ó1+´®ÁÄD”-tĚ×ÓĄŚHU2BFăIBpP)bGG† Lű“XśŚč䣅'.!lZ&=ůłCÓ}Íl((ч€¶ÚÍÜhŔwéđQÝh’ż8‡úäéíűây7‘’F§Xžź-ďo˘ü]•i.kQ=›5’‘Y śkíGŠěŞVIĚŤ‚aťźFÁf‰ŽrŠ™ćčCʇ§WRvŤY †'Y xÚBĂÉVť6 “Q«âP•wŹCn)ç·~ë·¦Ű6ďžŃĆÔg>óö\Đ„ ľ.^;CŞ ¸ä‰Ýqń*™Ž@ 8ş7Ą #ׄfďŃŐ)rýkË®ÝBbŽťôJłx3{Ę93”äşôŇK­ďY-„ĺő–Ĺ’4éőe¶ŃnvűŃŹ~”Ŕ•]ąÔŃ©ĚŮmz.ŇÖd˝‰ˇ¤iŚ×ś}Ę *`ňj ágś1§2şŐ‡Ň†Ű‹=:hßWˇŁŻ†öę3ýHŔAĚ6cô7‚Šr›[QqŰ”áTĆ–ĐíeŽąDHm+Šţ/v™Ş˘i8Q&˝ů=eŞvłřÓéó^† ]3Bj|Jň5ˇÇš sKďDž@#1dçüóϧůS”,Ś žho±ÇĽ…UÂŕä®EŰNŻŘŇ)}׬č¨-C5Jw‰”/¦ĎGČâÜĘ „»;;Zž…p7?S*)ŁdI0J7NĐĆ„ )`ę'ăcKz5dFj6+ŁŞ‚Q@YB¶4%¤dçѰűKQÄ‚é%9+P’f‰X58(đ۱vxŘMśUz„J25šA8:†XĤŽËŔ8¤Z<îâDěIV‰ 7Qfb…'¨RU˝ÍG=1žńŚgř Ěś&ĄLźůřÇ?Î*É+`ň.>&ä/'WO&8pSťY[íĎšłŚá~¨¸Ť±€i.˝w?ÔçŐy§^c:vÔż¶ň–2lŰ!X0Ę5×\cµj&LuW&Ł÷©Ď-1¨„,>ÔĆSm™hßraŔti60ÉôŃňfhů+f÷NéK_zöŮg{WřZQĎ”˙›żů›jnĄ"Đɬ}7^SB[%´á`O“Eć9 ˘ZT~«.Í`)OźŐj%ĺT9E؞î.€şöĎ€­J&bţPŇR'[02”L}ĚoĽŢO<ńDrŞاX`4ŽôI?±ˇdčM®.úIŠ‚oşSř=ˇ7«S-8Jł¤&“˝×ŚÍ% źVćŻWÍAĄÎVÍç}(ÍNżŐ%pĽ$ĐľčĚóUŁŢQnˇZ~q0ŁÜâ´t.+YҤ„şĺ2ś©D’ĺÖ®â¶9ŃŇ5JđĹŠÍ%Ĺ-ŽĬéÓâO§•}DÄfnŹy—3™ˇ" ć`LYž¶˛t‚ “X“=‡ű˛¨3ŔIÁ„G9ŐGÓűSÚBZĆ3ä–ą4mk‰Ę) Ä%]ÚܦDÂAŚ/™Ő>­ŁöWʤĎďfňJ¦˘sén>ó«éÚÓQ ŚS,±j%AřB ¬f$fŚďsĆÚZBýMeäL¶[»bĆ|ň”¬ům`íB&@Ńřs©Úp%§p@Ź˘Ô _đPq„¦»8I‘†“Ž0PpÜRaq±Ň"ŢÄnáj5zđv‡ĎĺÔšŻ—yÔŃUL.™+OŞ[máÎ{a*z˘ÇÇE"“¶Y艞M‹``böÉtÍÄÔďťßĎ`ŕĹźšqťN GÎůuç”6™ËŁPN¦€ űw<đBsŚ^AQú´ěęŁ;˘ÔWŐf*Ö>EzĂ č(ÂHÓÝ:Żi­#:…0-c4Ţć-Úśč Tły@U5ߋèNe”C8^sj…ăą$UHž}5Q3{6ăW«Aµ•W+´E9VVmk§ÝŃ9S˙AzµbńÎ^€ýaą§(ŇŘYCŘ­ŕő1ČŢ/çKŔş·Ş•ŢIô$}'¬ióË©»ŢăÜn Ĺه„~. *¦CćĐ“ÁKウ',~ÓÉĽjöU}6ÝŢă^ţŽCI }}„YcmĐ—Ząí˙opwź\nb(EP>čű¤Ť}(퓢Wă0I ťďˇÍ LÜč$¨¸ä0δ•ŃÄrŔĎeŇÔ-ÄÔG´ v¤Ő$•Q”Ůu Ä‘Q5R“đÍ+\şEżp×üáSP˝Ş<Ë;«MŮŇě5Xg€„ŘŹ ŮŹ-ç3âsźűT•8‹q«ťLoxđ­«>9ÂCmźs Ę$ÇÔ˙„Nđňĺí’ł(VŐ,ĹCµŤp´÷Č,áh4š… + Ą(đ63BٵÝk› Eb1Č„ż żľözűŔČäň3%%(Äf/z›3ÁFp"G{˛TÖ(Rrš=q«Ł'%“Ĺ Zż'“h/ˇ§ěč >”z7čččXE“JNôŢ›Q›ĂLţëV›«Ş4•ŮŢ-:Äd}Šź˘R=LŐ2ŚŽ¶Y ¤ˇĹŕÇÎ=%ě66ďµl)—5Ѭ•J°e˙{úE™áŰŘÎ…Ď&ډ]Ş’ukk˘Ş-ËńBOŘz¤2ŃĆÉJ :1ţřj‹p~nĺ2ż>NäŹĆ-?A{Ë&%5“žân ĄĂ™!LŕĹĽĆĐbč&*Siv$@0–˘)StLŞÍKL©d da[H +:ý4Łzi¸%&éTF–qÂQTśbâ s)¦s%–¸hŕHbéCÓ…ŃŇL UTK#¤ŁŞŚNšăjGq­7ÁőtËő˝˙K|ędp> üÔÚBělĐ”°ËhŃc#Űv '“gîxOĺGKë±XKá'ź|2uťľ =á^ĚA™wě‘3uËwr-RZ[y,Ŕ uâ Şö"r*É §],ëÚÄE{Ç jběA1–¶^f˘ňô’u°H ÔŁĹđĚüň—ż<Đ÷ F;Kś$N2¸’÷)•Ľŕ‚ 0¦,ýŕ sŔluöJbWB÷ÜEČlÔ"ś&p 8;#ŔVv ů*HŘ{<µa'~L®şę*pL ôۢ ©aR諦Ř*†Ńx ·¨J%čÄ ×ü¸A–>ÝüdŽ ú­.ůčCiľ|úÝ...I ĚѸr+úpâ6{éÉu«ÉZ:—“ś¶´Ĺé¶VÔ“dŚöžGV ›@HcұĘ Ąąşé4&=…]ůŕn.3ýŽjŤŁ˝˛°Ź0EźšžJK¶•ej˛Í1‰Kő”Ďě},°­h¤ ŹkwĹÚ’{ůÝDD¶ \ !’’1…y &e¤Ý@ďłrLéěĘ#Vi#dÁ×_hw«…b"¨€ĺj*Ś`±Ű4@áő›Â#Ş•j„Ŕ‘_NĹřč\şëR,ŕćŚUŐÝ7‰i‰ĽWČe’ĄĚdlź8zđ6ŽZśkaî6ď–Čv›íp¤gď ! 9Íäú"3ŠJĆ’—щcoĹ,B塇ŮB ť¸KQ+ŞR.Bě¶4öQ°€2ÖĐ˙@9"†[Ľ:-ňÄÓ@ :Q”ŁXĹP*¦7ÎPśÓŚPÉÂ;\zÉ$^4-BnÍ Rf·t¦-Ęë)PŹ$őI!6ółtt‚vąË]î‚Ů&śaT{»…#Ürb GWĂb" dž4ÁBŮ[~§”@ŽĎđ_0}OÖ%Đ%0U}(MKgv t t lNĄĽEuĚeK'Ş`bóĆĺB˘Ř<%Ms‰ČłBT“ă–u`řPw!”IÚ;Ţń0ÁÔ,ń®]‡ëq¶(™9żÍňSÓSěă9±˛LM¶9&3y(_zRO‰«Ť…‰ ¦†1x2ŠRÂň3{jvëçťwłt sKČÎUÖ¸űş×˝ÎĄőÂüdőč5E«µHoŃÚjş >ÍśvÚi{ř|tŇ«“ŹéżŞ—~¨/!@bjN°ŚŘ†¸,sN ~Ž“˙DhE!dIŢÜM y N6N?'t~ŐsY˛Ş_ś˝$Ž´íIěšňr™%t6fާeł@Q·Ą%ÉjŰÎÔ\^L·XXA"1k¤ ĚşÜmi6uÚŇôN€±#?Zw!m‚5Ň¦Ý 1ş»VÇK„@޶˝´Ďővćë>:éźµMÖŇěMĽŃX…LúŤOf;ěŮZ»Ç޵cOiŢň6攏 Â- ËÚÎă}'´OGş:ŹßÚ‹xp«_.",o‘ô=M—@—ŔT ôˇ4U,ťŮ%Đ%Đ%°´ĽWĺM<«łĐÁ­IÎ A.L–ÄmL§“W,¸•`rŰ^Ęŕc·«¶ óčôSeÓ{:ykjÍBś9yśÖş)7…Lż-ýÂl–·;ľ-ĐÔťŤ9Ží*‡’m˛ŤŇHí”!(Ź#˝<AČĄ,ÄŇDŚß†üÖhˇV…)‰ěŮSU‚ţ8U¤óo´-ó ·!Č jáź—_PŹ–Š3p«ČŚbTRŘęI×·= _L I6ʰŠŹ¦uŠCAŠÓŇ0”ä’,@IŇWF…äA8 ęV—šŹž/„MÜ=ŇčI0ޞD%_Ýz1ˇNKcĹzV–đ9ŕđşˇŔŰô,OĄósÍş»`i7›¶7'B¬?f•ż>A?îČ’-f ¬Č<2jś žxĘ)§ 8ó/ăd×IF“É0Ť7Ż6ŻČ=ń$÷ŕ”‰ éŮáiŁ“÷‹ŔV…q @Ę.Űy]=YĹ*r˛ĚÎéččččččččX\t{‰Łá‡`xn˛ma’r ',^T›Ňú«ŐMz݇ĺČ#‡˛Y‘…8/FbŰäź\ÖG%fÁÍŔ¤JŢÓ™ŔÄ1‡d*F™TÚçnŽţó?˙s…ŰĆBM@&@$q1[y&1•S2k´Žxík_ýŽÂ4ˇDÜő®w¨B›kË‚%«0Kl9ů  `vÉů&űiü"j\CÉč@Á/đq„$XH‚0CcşTšdˇa%8UTrá !%×Ü•lR±ľˇdG=‰ĹA ŁN•2ĺÂBíçřÇî2Ö`:ů¤ÉCe§~s®Q›}ô!6đWNO*ÍâÄ®J› Ů{âq@âĹĘ [F IDAT:?eÁ d#Ěö2NŢĽ- :EM5^đ›’ß7Żő*|ÇęIé=ČŢÇv'ÎŔůÇü” †p/{ŮËü”U"z¶ĚNw t t t t t t t n Đë śä ¬~YŠ}´JŞ&Žbë2Ę'}•»P‹¸6/Ťž(‡ňᚢ(ˇZáŕQ[GYvA·xéM›ôÍŐ3]OÓfĆ)Đ–©k˝m!›Łťăˇđ“N:‰ ä‰Łr´>‚¦ŔŁ.ih@ô)Şg)wµ…XčŘŞăr?ÍqŠ7aIÄă$’ĺ7ĺ÷ŚBÍŃm4!`G„!„CBh|!śbş%ľ¸0w“'ü$-¤w—ŹŁßH­Đř¸HűHŁ'Î|!ôěľ›#}™ÓUá‹ě˛ 'ó·í(Ǣi#ś¶ËYĆío{//Ý…Ë%/ üđs7¸µŰŇb‘1($'~źxý=4»şś%´[V^@»zÜÔÄÁ‰řHRrłhlĐä«'»4~>áłźý,¤ě}ď{źŽu Ż1ĚóáÜV&€T{’q{·Ó]]]]]]]]]›–@0qžh_ôäŹţčŹúЇ®Rľ3VđčOËÉ\Rm>Ëw¤MCś˛ŮgoB1±ęĚż©,ôóÉEkGöó«găÉü Ţ…ŚÄ‡€ónJPc`dËěX~Ł“F…ĹĄŚaRĺÔ6¸‰óIDÎŁ,X}’ĚÚłš;ştŃEÁĹ(;ěPŔd\"hx@ċ⌎Ň"¨GŔŽ #˛'{řaćnĺ 3—ˇ=¨4qąÜ'B«j°»ę˝"aůĽS¦M:Đ“lޱˇCĘ9Űv y°ÝbŐ– Ţk/¤w[ÚÔýŤńx2€¬€d“–&Sź˛HsöqłäőęđťÖ}ôś2SÔT´ČvľdÜ-¶ím"áG ˛ćEĎ^QĐ|H9ěŚď%ç.g0§üĽ=[źµs*Üou ě7 pńĂŻ÷ďSO"ÜoµíőéŘ·čCißţ4˝b]GY[Ř©!@VÔBíÄgt?Çî~RÎ0Á†‘É[Ç‹źµ,Ęă4iăŕ#8™ę»¤Ř»D”‹ç>÷ąŮř|AS%8^mYýą~SN[0ÔhăSÖ´P»Ŕ+:ŚÖ%QřHřBvčHź4â––8—íÝdĤiřh±Ë0ëÖęm_Ą„}ç¬ŇÝ慀ʒc«ćç˝ë]ďĘľ2÷âżŘö6h«÷Ѭ,Ńçů $ýâ~ţüËÝ–f§‰Ţß–ÉĂ`Ŕ)—NíÝů4µJHó@ĽÎĎ8ënüą˛T’Ů#Ťł•wŔĎśT‰ nĄ˝L::¤\:[Ç‹>çŐ-Ţ+ŇĄ“‰9p)ľź268‹{ş­ĽťčŘđ©Wr·Ű÷Ň~¨|ŻC—Ŕţ‘@Jűç·č5é8š(ő˛r °@ ś˝rőŐWM± Zť qŹX‚B$$±ÄŤÉ‰jXjŘđ:±ůč’K.¤8_0(˙ ^‚E,ůłzá _ČmŤŁy ýöo˙¶ćň Á8BkxÄJh/ŃIŚ/ ĄЍKśmŮ39!Ăb"öˇHŹ4zrç;ßŮOnČ ™óóč§žzŞĐńĂwcâh tŠËśVK‰×Śú§â ąMÜŇ‹—–\L'čBâ\öĽ[C|ŕ KíĹ dŔô¦jĺřކęrW„Ś”IŕŹ}ěc˙ă?ţ#yŐl¶Ë©đŽgŞiIrŮĂëh`ĺ–˝6Ľ– ž÷Ľç%ĺâq0/^© GY 43V¬ŇXôXo4i¶íłťč8X0ôÄÚţz°ŞÝkŰ%°ß$ЇŇ~űEz}ş·Z…ż”LZF)tW1ȡťĆn±Ěiu&Ë«4‰¬(J t1:…8Á ßňł,ĚUxŔäĂEz ëű§<ĺ)Ă9:·Řˇśţů6gÝď~÷#öJ\pĎÔÁ]Vů8zPč\â„»| ÇĄ-Z.…ş•rR‚B„pB^ Â,¦ĹVÚŢ~ÜĹ{¤Ń»őŘ«sśQî]çüALb‚ń‡‘€ń˘Ď?ýéO_dă>©sŻF—Ŕ>”@JűđGéUę8:0ÁÖŘR2CyĹ·ýĽĺž‚ă2™ä =˘¦.xŠ%Ţ >_®»î:;}8LqśŽo§˘Šr=ĂM‰ßôcűX]W•h¬¬N¬"[̶L ˛9€ „H¬ĚFBňŘ‘¸8m‚0ĂIQéźEGţaŠ×Őś •s¤Ń2˝Ç=î!^ÄžŤ2ź TýYN’ň#¸đĐEŘwÁí •á;ßůNL¨ôŇ€„ŽŕąĆ`mAL†ĹKK^62<›B"‡pÄţĘÖ5ţ^÷ş×dá‹p`Ú® úЇĽwŚŇłĎ>Ű9śE˛O¦a`ň§ú§ ^¸Őť"ůţď˙ţJožV0–c÷1ËeĚ)§śb\šédüŞ«®ť°=s˛ÚĂĎŻĆŻ YqhšxAd4ÜOŻÉlöŞzt›{ßűŢ-łÓ]NO~ň“ˇş±˙:p•ďîŘ?čCi˙ü˝&]‡RĄ^1Ňk··?„®8iŘž;ť— íăPĘdÁFAFť)1Ťž $"¤ÔlŰ üxB°7ź™üĹ_ě–…pšZ–u|Üd2 Ć€÷\ŞĘd‚p¬ŕZÚOJęL›L é’Tż©\m) RY/§ĚN]fnóŕ8j‹Đäŕô%¨ń.ś˙aí<6&1aZ’K‹ŮŚmMţOtB.Kź@řEž‚ŔWgöÄôäúŤvŐ„Ť&>lvG»–=˙pD{jZW ÉŚL™~Âś\3x„.;Hěg¶·Äŕ„cÝΙçĆIrA@*ĆLěč0!| „W[ŇčŻí#/Í6”ůüç?ż ŐJćŇ %’ٱ{űFč±:§©k>ďůŚĐI©®>””Ŕ†Ô°őňç<Ëwađ,ź]GË×ŘGżos›ŰÔ—W­¤ńIr’šCë§ü>”&»Îéč8î¨Iţ€piV ľűÝď~ĺ•WZ„đćŔĘă^罯€ĹQúMţNwşS;Y˘Ä™hL MbT3˘M:PŘÁ,gW­đťĘYb–#ł äŐÓŚ1%· ”J2ĆçťŔ-S5F"¦‚ćĐćüÂ+^ńŠsÎ9gWUš“ŘÉ*¤ą¤´ ŔCMŞů €é¤GɧV 1Á3üÄuË]ąĆ ŹE-gNeţöîÎҢĘ0Ń€ş‚ ˘˘2"FŚ(*¨€Š%ł®˘ăŔ° ęšÝE1đ ŃĹ5`^WÁ,0˘`ΊŔđ=őţo׼sowOO÷ížŰ3U=żšS§ňąuŢŞ:uęÔ¤EmčŇB;2H«( /;Ą1ţ<†57T adG7„¤ !‡‚s/­f´|äjp†»Ńl;ۡÍíP#}ă¬n‡ŁAějOČŤFÍłFęşů}ôŃÓ.˛ç]oË8 ŘĹe5@ľyĚ1Ç0il.I9f7×ęŁHúЇČJ°<€–V&!““‘&=!YfmˇĺJ :¦ĎŠŘDzčˇ&?“™IŔhq@‹]U#Eł$&ć0U«…ČC»2˘şÜ˙˘li’űâżX‹5Ż8I ŠU…­˘ZhNç‘ČHÖI IŢA›”lŃěKHšBAż˘Ł i‘ËŻ~ő«:ç-…&})‰îC˘›«są¤V7`˘ŔÜY YfŢbqs6VĚ$tCV˘ÎJÄ=Śůy Ť˘b­ËĚňĚg>“ćfĹŢÚCN!Ůé•Ćýą¶ćÔ4śâX2HLí~®ŹĽ);%4VŞ”l@Ł@ŁŔR`Ő~´¬(|ľ8ç$ő#ůHÖHž§ťŔö/v“HóÍj±´ć!%A'A«8.B€ …o­E÷ÜĘÍíËŞŃŤŰÂ[ëŇÍLғص­Â e=©ń–taü¬Icť)č ÂúÍV¤l4ďĽ1Ę4xňX5pÎ UmhEV ÄAĎ`řއ‰ź¦Vżˇ…řčĂóní’e\uâşdUNZE†‚_—jÖ¤5¬µgb)ŕójŔř‚¸˘5±ŤÜćyiěLSăŹx„m’/őé§źC6}j&ĄŚč„ęS˘čIItb˛$!kżË]îb`xÜ1%˛Z‚i5 ĺ›—8ńfČ PëË)’…}śC9„čÄw†tV@ZAtB˝…˝ŁHfÄÓN;ŤŚ˛o9%)Ů?Ň;:5Ú‘ľéMo"čˇ×Ƭ˛Ľ®°™˝(ŞxWKG’‹oÚŁ'ĘĄ3›C‡'I–P–šZ“ÂŐG6xĄŔY }F‡7$#RŞuŞAHÔH7Š+Zβ*UÎJОž3Čé’¨Ńĺ͇<ä!ę˘ŘčŘđÍo~s­+ )fqF§a4“é…Yq’EęŻk¶x’6 Ö¶´ĄUł7Vޤh@Ł@ŁŔDQ [P+„l;ůN;a¬=r÷ś°>ĹDµiŁă–^ĚšjŤ>őűË*v˘úĽşĆ.:ɡL_ݤ6ɉ}‹O‹˝Š @ŕ.Ź)ŐO\cIL¬'rë…s‚Š`1¬|ŞÓŽńśIÁŐ1¦ŐcšÍĎxŻ8ř$†źÖŤ«ÁKPÎ*ę/Ae“Y…-“k;ďz×»ÜÔ̶VM,¬Ťúl´&­mr{lŠ0<†íŰ5p\ ~9tqÔ4@›ĂfI”Łfb DsRín‹ăqjhÎśé°Ż(P ĚôwÜq•°„ôA¨ĺĘŚ˘,4ňrŤ4u2®é]‡1ŰdÚŕ1ŁŻyvqöo.ţP ±÷“7:/Ć•Ůşć ŠěĂŠÇŔłŮ‹Őjú#Ä"‚ňşďŞ1ö~Žß?ó™Ď$—98—śíWÍÓŕňŞ;nî¦i°6ôkŃA†ĺ‡¤*ý4 Ţp(0GVBŃáí¶™Łµ‘ĄžŃ踌N“e+!w¶öŞJ" g%<•Öđó:zĹÖŽt˛˘5şŽÄ_X×č %\©ťVÉRyä‘Íľ/xÁ t ×äo¬´áŚüÖÓFeAl>ëĆ5;UH{T.›ŐŔ6´q®O˛K@ĂaĚčBeYôzŢŤ4)ŞdwÂäĚ,ä"kC ÎôÄY‘Ľ[ˇ9$ł¸ęëĎ»öˇŚ„Nάµ E ˛  w˝ë]ICú±šd™3­KúŃ«ĹZUösŤ vµÜ- ŐÝß±ev±(#0c ¬"~žńĎŹNJŕę'™”C.¦¨q5{ńĘiŇ“B[K.7Ąí¦ŹĐ­äő†>˛öŔÎęúЇ®7ťZ?:BqŁçÓ]ĽXŁ»‘»¦é¦™É<ęÖUµ3BÎB0!–mŕzÍGĐ,ű(éŁ~ňĺ/Ů•TÓ€ôőŢm˛ wD§%Ł)Mh§îőúʉ\b¦‘"¸I.“enźŤž íĽóΚa¦IĘ:wńÔ«m4ˇ” éO’1-°P ˘ ßE3Öa÷Ýw_łZEĚĺ:ĺz©Sßŕ “sd%ÄŢ‘XŚAtšĎ•zF—w" ?"ËČ;ĆÂJěŻk€#!ëÝRT=ĘJN m!Ұj÷„M7ă¬ö‚§}°ŚŽ §±RČŇüFF ¤@¶ťV÷źV łA­x÷/, µČ´Žd8—"Ѷ¸˛ró w×ҧŘr…}I·Q(2’JłĆ.=‘7é†Ó˛ľjđ´ť2Ń.¤čáĐËd!ŤeĽę*Ý„qéŰ’oőčül¦EÝ´µĚ©=ĄĎ˛s(c®í8$“¬Uµ’élöń¶¦=ů䓇 kěÂZ™Î %ŐNÖsj{”Ś€i©lĆŻ#°?±ŕ:8+ý޶Ą/a°VXúŠ'ŞFvćl9FUî'Ş‘­1Bź ç–MëdB~Ž~3Ţ}Žű×J#8l±Źbä(QŇřô÷“yŹÍĎę¨!3k?*/v;â6I“»çm,W†Ě7P%M뫨ÔBčXi«†Qj€}H€)ĽŹ[4ôűĹÖzDa¤&N-ÎϱPXXjŹŻ=\ŕę+ß.Ô»y±"°ÁR`ެ„>ĆŇĐđĆMđľCÔ#=Äb–¤±Ś>VbŢŐ ŞżÓ|†e%ňgŹýô¸‰˛‰ŹCťMŹ|:}+ő)ÖŕFFuHţb\ö«ZĹ÷áŠďŚÄÜ÷@ÄŔyÉĹý'@d܇\p^‡Q5EEbtÇWĄ‰ů©ľšYh ›\8GMľŘ!EíŐ]Ç’Yfcź | WäÄ+î~Ň­0)0Ś54ŻŐŇř!9Ü•¶¶ě?saHBá÷˘ŞIgł_—3~Ćő?8–pbçţQý铌šĚbhĘôŰŕÄŃüľë®»Ňât˝ťę´yÓ<‹ŕH*eŽSXńb‡~—~ÉËnŇ“ÁOf3ÜöĂËnř®“ű¬ŃĘď:iX«”tcć|Íţ‚]P•žĐ!ěč§ŚÄaô–©4~qÓů‹ň•餺ź=0‘Ę(¦Š-†b™)qOhB.ă”[ÉćÔˇ4 ÍUmDďFÓףöŘÁş­c©ÄQlŮcŹ=Xiq…u‹-¶Íé‰[ ŁQ łˇQ`ެ„,CĂŰÚ.GRÓr“Ő-éITBĆČJšáÄŇE›°v®vه~8Ľ?´€ 7MËJň†›+ ‘±Ö!˛?MŔ} űU_9ß.KÜwBîQ˛3JDNráÂďw„"°HF÷™Ą3_ôk§ămÁCÍc—ĘZ…sZGĚ,|Väó¸ĆBđ͇ô~"—˘h8Ňť¤˘kµŁ4‹Zş˘ČÍ DB.ÄA“Ŕť€ßřĆ7Rf”Ć…šľrż…c­ô\„!ńq`Ú"I©Ĺş¶ŁmŻCş'ҸXÔ!Ecsź …rq=Q«ĺ,ŕę·{˛Žî\äa€Ďń$ńSŞCĂŔ!lEúĹkŰR–ܤ'KIíVWŁ@ŁŔ"R`t˧2s éI_ɰJjS˘ 9­PŚśĹlęĆ©B¤g –?­ôÄlW ěŁŐŮ7ş&ŔÖRm•{7fPfGl˙úyĎT˛é4qcns8S«%}­µ‹h4c‡ć4C^'!ýĽaR`ެ„8CŁ(¬d©TŻĹő hA,8FVRů Q]/¬iŹëýžŻ5z"qcĄţĎŃŕFFeJßX.ěŔť´d;XQűr“ 3°MÇÁ5z(4úş‹G 2&Ř\ަĽPĺަĆŰiŤŹ,^ł×¶ VMŃ^áłRgµć §w3#¬W8ĹĐŢ>Íö唺r¦5íom[µĆô.ĽÓ—žäÚNîőŚ–Ŕđż6SĄůŐŻ~ĺçCLN2˛#ďHşĺ4ŽV4;†]Ů]†"o"ŚŁ Ť°•ňFr—B†h>{ÉË(v­‡é2ę[kjŁ@ŁŔE*Śč÷:ĘłO‡QŃ̦®źĚƤÉíý<ôKv(™ S‹Qä(F#Ůh°ĺSs*$&ěoYĘśxâ‰9î°îĘ5ŠJ0SPF‚62ťĎ°Ěâéb đ2‘ˇ\Îs`ú/%hÁ ‡ d% ¦j¶O´ÜM+)áD'ÎQ‰Khť˙9„ôňŽŘQĆĹô›7 ÜXiâ´¨FFuBߥęl›#F$X%&H 82 _Hç(gžy¦ýöb[-P‹Żt^3¤ob›MíÂ+fÄ(”ݲdě_{H7ć·ó7ˇ0GČ„ż‹śl·YYŮŇ+ÍŞ,*˝Vw4|QĆĆ>űülř%°Ć‹5®g<ăŐ®Üb˙ ‘hsť+)•|îsźË Ł™jgń×í¦[gńłJIâ4˘˛^ť)ű¸đ.Ş3@zŚ­s‘4U«K]‚€ ÇUű$”Ó¤'“đ+´64 4 ڱ§Đ/Č”I63tż źś“öj1¤‘0ąß4ÜOxަÎé¬Ň›5çŃ{dŔŐ Ň*°Ňb­b­0ôc] 8 N8á癳O:é¤ĚjµĚÖ]T…ŐZW&śóf%*ÄV¨z7-7…GĆĹJjÉ Ž”™ť4Zď°ĂŃ…i¬4á¬5ŻQ Q`\¨áŐE_tŇ LVyľśsL7e0’]$ ăV®ĎPU ć&#đĺ'× źhYEűŐĹ’‚q!ĺč8c.VVîrÖłcv~˝Ąř†7ĽAŐöů?vţq¤'48¬Ýn^<“«ŁÝ4WŇq>硷IJ§I(6» Ż 8sf>µlsŠ!??¨Bhß8HĐÁŃęĆŽaćĎ+KJo;˘aä#ŞÖ…Ŕ!oŕľ?ö–¬“›ôdť˝UÚ(Đ(0~ ÄTdż\Š…‚TKfżÜ›ů•\ĂLĐϦĆÉ— %8´ŕČ)zM̆–CśČ®ŇuÜë^÷şýdôKiŔfúřyĂjq@Ń/ÁŠ]4ćŮú &•˛Ăź9¸źĄÁ ćÍJvá‘!‹whč‹ň>ÎÂYIQá&"ȡß(5V"K 6 4 ¬OčËM8~4Mމ ż QŔT6ܡţ@á˘j@Ś…>ľŔ´?Xĺ`~Uo<ôăsmYÝñÔ2{!Läz¸‡@Ä„|®ŤeĘË^ö2ú)‘ˇŘök•ëKŠ"â!Nš˝ĚńĆć(«ľĽS_Ű™{-.\“¶d8Ň;ôĐCe4wĎń$oîµL›RŐžłEŻYí(‰¤q‘›T1ʸ&âi›±®Mz˛®(ßęmh3|Ę™łŞ…š _úŇ— š°+rZ€´ž*©Ż?­Čţť.ŁĎůÜç>7]v“–Üááx®şŔ3ŇîYś9š‹ĎҵłLŘ)Öü­„Ŕăši˛Ąt¬1$˛šQ‘˝+Kl©‘Î9çxťÇŇač-ˇš ćÍJ¨ät‘OŃÉ•h.»Y@óY“ő1üÂYI!á&«·Zŕ…/|!Ő*@cĄ>YÜ(Đ(°ŢP /7éĂťĄxD'UV€ÄÄ2'ů`¬FťV©vm)Ć ‰÷bĽ1lfŤáްĺŤO4;ŁÚą¶ĄŤ%˝Őů‚Ó)sU_úČ.JżâŻ c·źÉâŕ^ú"=±$ŁBbťF_ĆńC] őťH cw(JPFš~tp5 ;šlĽ!änVÎßásCŇÁÔIJüń¶a]•Ö¤'ëŠň­ŢFF1S€Ş…›ź¤O{ÚÓÎ=\ĺ˝OÓĘI9„V¨¬÷QÚ2Čď|ç;W’.•”ó„'<¨ÔPg™Ćë™q IDAT‰˘JÝÇA„ž¤ęZăü€ĆJóŁ[ËŐ(Đ(°Ř¨‹ź)â’HL @rnHz"Hëġ‘§ĐXeňڏŮkeGy$EÔµmv„/ÖKÖ]Ž,cM 5+4¦a]µ¦ iWźÇÚX`YW"žzygŤ×vůQ)Xáťö×ńAî_{iqÚ‹¤Lj1iÚeµťô„«($)đń#@Yڬ«2Ű‹ĹëŠň­ŢFF1SŔs¤±âî,ÚGśVHl+Ôj(¤ř×ŕ`°p‡ĹNĚëz˛ł"6­4Äů¶+BŠ:ďĽóĽĚju˘(Ćäů®ÚÖbGMo&Ę9Ľ9›şKfä5|b;Íśç<ÄI[\IK(µŔ+¦íˇ×OLÉĹżK°Ö NŘqĐDůsHÁÄť#"z®#őł7xĄŔY efޢ¬Ô‰Ź8⬄ˇŚgÜ•«!’.•ě\büăOW٢Ťňyĺ‹QµqRKQ©·ąˇÚ§=kÝf›m†X¬±Ň(é¦Q Q`]Q B“ľŻ%‚ä&ľ/Xä&v°`>g+ –Ě©ďűŕÓ@a2Ă7“Ôŕhghů4KO]p&s!7±Ş’ëYŇŻó(fě\&2qx dßâŤH…üťDi‰ŰF±ŃDé’¸ź†e–ˇc­~cü@îi­Ç‰˝°CÎŐŹµôŤ&&1Š~ÔbĂ#zgź}¶g$#˝˛@őăν OIšŁÎç¨6Ó_6®HIЬnĺJ…N“ŞôÄ]x˝ë¶„vsgÝŇżŐŢ(Đ(°Ě(@AÎgß"¦Ő>ůÉOš!ÜZ^ý±–ú÷˙w"7 –WË[k—;+-÷_°µżQ Q`ťS ňËŹśůŰšúŽ|„‹˝XRÎVÜ5aĘń0eŘXŹ˘Ęçô np:ŮôŽv“ ›y˘˛J˙`‰NŇ]¦8Ł Ž \,Ą˙Ëíé˘bĽ|”ňs‹g–ş¨p’’ř¤q…‡4˛k<$!Uň !ĎRÂbDo4h”LpcŘpV•ń P"­3„†Üb´d)Ëlş'KIíVWŁ@ŁŔň¦eŞ•V zШ)˛öúë_˙šÖ‰7çL!Ţ!ű_^=Ôr÷zڏň•ŻĽĽZŢZ»¬)ĐXiY˙|­ńŤŤBkÎîT{rČo×J¤ɇ$L±ŹŤ„EJ±.6##ŚÄ,žX 0řmsî!OürČ!ô2Ž:ę¨5Cţ®T3Ç`ś®-F/Ľď“'~ú…łIÇő1cËOW…Ý:cé›0şgýi&u_uôFöPĆE ˛Ü÷ň—żś"Ź‘Ćťo†¸ MŚ·EmĂޤ'KLđV]Ł@ŁŔň¦qő„ů•ÖÚú–N0\ç©eŘô‚!Ďe×ňeAŢÖČŮ)ĐXivú´ŘFFFY(Đß‘’}ĐůIoă .H°ś”¶¸ŇÄ &j˛ě¸ăŽ6ꌦٔзe˙›‚ŞĹŹŐŽ«=îkxÓĐŰjRÎŇČeEAqăŔÔ˛fłT&¶ĺÎů &¤…d7Ô—“ÄâUşH%›Őţçţ§iť,y—]±Ť•ćý“5Vš7éZĆFFqQ ň›Ő*(‰¸ÄúÄžžó±Ęţ6 |‰óÎN4PP´ÇM%.ďž0¨Ď°EŢ8łigߣě†x^m˝1—fúűŔ>@ND¬OŚâFĚeÖqýFë_9†Š[E_üâÝ!bĹ«.ťMĐŘ3׏î7éÉúń;¶^4 l¸°,XĘÚBč:·Ü‰n&#ýYî˝hí+Í›’Ť•ćMş–±Q Q`~ őŃÖ”8~ö¨đ>鉭 b!#:!.Gë$Ú(|i*LÓ„ …9|WE8fbÝÓ‘€ş§jf·)+Ůňr¨Á†ť6 ěż˙ţěČ.ýÚryQ¬¶– [ŇľŚZ'bŤ‚!ą‰”uXÖ\ËXO„@Ë÷h-ohhhhhhhhhhX lYălV§uvłD'ü8»\\‘r% &HĘl=őBACól•˝őľž‰NBvÇ;ޡ§űŰß\áˇ_ĽŔźcÉîĄd=˝ŕ‚ ˘¸.jNťĐ¤“ŞpëMšîÉzđ#¶.4 4 4 4 4 4 4 4 4 4 lX ěĐa;UB@v§ŮÇÖÍ*ڤÔ|‰ĄG÷$éůRR%Y’—Ůżüĺ/Lă{spË-·”`˝tFtOŘ;묳öŰo?öP<*´^ötŚťňnŁŇ>1~2´řER2eôD¬!j ‚4đ¸1¶a)‹jş'KIíVWŁ@Ł@Ł@Ł@Ł@Ł@Ł@Ł@Ł@Ł@ŁŔbQ [Sľýę‹4„O儤 ±!ă˘r? \ŰůŃŹ~sę©§^űÚ×^¬vOFąî+˝ď}ďŰf›mÍe+w25Ń­`PűĽâI\'6ö&şkٸ‰ž„ɵĽrűĆ7ĄVቩ–« j-™–|æ@a˙ĘQÁŞ_›(@7)ň‡čÔĹ”ů2@W®d]˝ŘˇZ°Q`˝˘@7čőhŔé[8a€KĚŔď÷˝ ¦Ň„‰’hPFb%¨ ÖĎÜŕFőŽ˙Ĺźó•A‚+ţŻ­wDhj@ ®ě–…ÄYň ;âĘĺśÍ7w‡Ĺĺ.w9{ÝË_ţň‚°śŘ$€Iz×XXµĐkÓ2;Ý{“ĽÂă ’ľöµŻe\ěĺŻg"”‘—žÄah FŽRnňL˝aĽÜ»?Ň“ĺNÄÖţFFFFFFFFFFFuK"G™:`«pTH†ühš@FĽ"q„/0âěcł öÚΓźüäu۵Ą¬ý÷¸ÇźřD;˙Ç<ć1˙űß—˛ęeWůš6ĆEPRýeב96¸IOćH¨–¬Q Q Q Q Q Q Q Q Q Q Q`˛()É!ő“HI""á ň©™P-éP.ŽŁo¨x±çśsă©đo~ó›•?YÝ^äÖ{ě±ěˇz­ůĹ/~ń"WµĽ‹˙ŐŻ~ĄŚ GÁdČŹ0ĄßĂĺ.^iŇ“ţŻŮŕFFFFFFFFFFFĺJ!1Š`´NŞF  JU5VĘZ`ŕmsoĺ9ĎyÎöŰoż\É1ßv»ÁtüńÇËýĘWľňĽóΛo1K”ŹHâ‡?üá)§śÂęíWżúU&~—¨âŤ6ĘăD[o˝u˝§Ł1O ,YŰŁ˘&=Y ޶2–Ó M"(éËJ(žP*áÓ1‰«AŠ'đŚ,̦ţáŘn»í?üđ%ęĂ„UłĎ>űxÇÍť˝čEslÚ?ţńŹ«tî­o}ëLY<ĺ“4_˙ú×kš[ßúÖAůڰÜýîw×€\©é+@x±÷Ţ{oµŐV׿ţő8ŕ€>đŠň¤ôřłźý¬&[<ŕ[ßú–ÂŻu­kń PKbý$5®g˘ťjŇ“ü˛ÍohhhhhhhhhhX(0*L‰ ±H˘rµ' )Łr" >ő©Ońźýěg“ެ™W"79á„Î?˙ü9ŕí^Že¦ô^NR†šćŹücC>  ę?7ąÉMľűÝďÖôţűż˙›¬ä´ÓN“Ý«]vŮĺNwşS'ź|ňŤo|ă÷ľ÷˝CYĆdçk_űš2ÝrŠ „ź*†ä&CÁń6c)K[žŇ“ ëÚÝRއV×DP >g°¸­)Ő4^Z\·Ň×1–j€7VZÇ?t«~ (°TÜ´]iU4 ¬Ç ř«ŇA"’(•đ G˘lR/é’Źχ‡ůĆ7ľażí¶Űzčˇë1ąÖŘ5ÂÝvŰŤ(äŤo|ă/<ÁÁĚÖLu'ťtŇa‡ć×üÉO~rČ!‡ô.ďz×»î}ď{˙ö·żĄĸďź˙üç/}éKźůĚg~ţóź“|‘¶üőŻ•eTć˛đvÖÎ<óL·„ĽÜ¤ Un’ŘKFýšw™ËFz’OŔ2ĄrkvŁŔĽ)PFţXeĄĽć60 Ś};cn`?HëîrĄ@ťAĆ;1-Wr´v7 L<2ý…s+ "‰ „OĽL|Q0Qň‘~ Űlł UŽ'>ń‰lŁöńväIOz˙ /¬Č+_ůĘűďż˙ ^đ‚Xô¨xŔ{ŢóžąčVPÍ Áégś;ěÓđo6“ěąçžsĎ8Ć”č¦˙üç?ŮńM±ŻyÍk÷˝ď}éžĚTŁ-LÉŠĄ2ÁgĘ;<ó·~eÚI·Ľĺ-ç’~ýH3YŇ“pláaťÄ•DWĘ4ŤŰ xWÂÖŹß ő˘Q  BveŃ€'BćsF{`i:\Ď›N¶˘¦´]â.ß »Cމ’őŞW˝*<{T.Fş˛ĽÍoX( b›­·)ĽÓíě…ˇ*+•mß*žš±ËIł*áŞBJöîTOŢÍ6ßlË­¶üĂď˙ Ţ&=™‘-bR ¬´ő6ݬÔńRá#SSçÂS=Nŕ—aG[“ÖO őČAřśÚOĆĽ‘¤$–čŔ¤ńä­Ät.ćM”O|â÷ş×˝hš¸´bĹŠk^óšżüĺ/Ď=÷Üßüć7Ď{ŢóŢö¶·ą„’ ]­B˝/ůË™GŤ~ĘŻxE–;Cő¦ ß6L{P`¬Y„,Ô[úiáľŕ»ďľű’ž¨}Ú—yöŮgť¨Č>‚D´ŤČłÔnCqä‘GÎ’`Q‘ŕÜö¶·e°VQc} –źQWË,éÉ4¤¬s˛_¤[ěJ ů_üâýë_gű7MƆjXnřŕ?¨É׸Ć5¨„¬úĘlĽŃ`yÚM{óîSż@…$čvĺżüËżüéO:ýôÓ‰Őç]xËŘ(0Q°ßűţ÷żołźˇ^h0ęËL˛@WĘś*-ĺ+pűí·˙Úďżöˇ}Č×ËoŮ&„¶RąÓľbűݨ/ë°ľ›v¶f4 4 LK¶ݒ/ç:Áş°ěë›D€"»¤ą¶ăˇÜi‹]#Ň=ĆJ A”đ†7Ľ!7ą`ČGž˙üçŁě·ß~CaXńuŹŰßţöŻýëo~ó›k§\®íĽóťď<ú裝öÝńŽw$vŮqÇGŰŕašôw4 fÚ»-Ó¦śÉŚŐŹu®vgÚ”i=›5Sö_+ĽFŔoçSîŕX·łb+‹EN2Z笱„EJ@ë$×vîz×»öç…ú+ô‘iC0‹Ôž%+vâ¤'ÓRĽ¬vý9í(ěľÉ6WÝĆ“k=÷ąĎ]2bµŠŹf5ăYů7»ůÍC˝íái?@ł7f+9ś: ŽÍĂIĺôp“ŤMNôî^űÚ×6éÉěôl±ËĆłÖî°ĂW¸â2Ú“Hă7ux^9eööypPZ‡*łRçnqó[|í«_;ńÄ˙íßţmË-·ś˝´Ű(°,(pę©§ZkŃĘfÄĐx7ŇÍĆ˙ŔMé ä˛čTkdŁŔ†Ip(.&±!WšţřÇ?&°pYćf7»YĹŻđţ÷ż˙ĽóÎó^Ď)§śrĄ+]©ćőâĎłžő,ţÓźţtOĂETIy ۨRş†CŁĆJÍĺLń‘Ź|äîp‡;ßůÎŢ—ńöÍ+^ńŠ[ěákpĽŔ[lÁ´Ç˙v®¶yö*Lrł§ŤĄ_CđTńTfX-ˇ.ŚF.ŕüŕ?fJOqgÇŞÎĘĎšé€-Şa–ţđ‡S·Fßu·]Í™2ÜÓq@e„Ú©ÄÖ`&śä&C˘\l{ĄŮ3íüçŇŁżýío’ąž3mbÇާťv­ŠťvÚ) ,?ţńŹY9ÍÓf|ěc[fäŤ6úŐŻ~ĹĘ´i{+®«Ě±Š‡<ä!Ä=Ó&vf9“ô„~ű¸ý\ä#~ ®o Đ"'i\ZzkkT“r“€ĚŻ™/?q —É"~đŐŻťĹÔ¨eLô¤Ň M=ÁBߍʛäx;ëŕ2o˛ń¦›lş˙űżéŤoňŠ•;uď}ď{›”JŔ,/ ř†úPúÝŕ7¸Ă®wČř_ő2ܻݯü‹X$Đšú™-^ÉŇýsö*LTţëÎ÷ĽËž?ůéO~öÓź9«§lI¸ľ¦‚[|ŁŔ$R€aą}öŮÇôŤď·ĎýşQŢI §F;¶ SŽX›ó2uĽsÉĆ—„Źd ş¬téĘKopĂě¶Űnź˙üçúЇZ;ö•o'‘^­MŤ3PŔ|D±×űXćŔÜâňE¦Ţ 3™A8Ă>$8Ca Ý(Đ(0A¬˙©É”îIż}”(aÜ~íă× ö #ŻTKĽ­ĂĘÉuXEÝóž÷ěX_áuţŃÇÁ$&JB.Yđz×»žşÖĘdÉ<Úć™á™d.ýŇV¬Xá;2n?±ÓŹęĂ|?üpćf:č r™~ÔB`j‰¤HÄ:÷ąĎ}ĘdĐMŮS$8ę/¤şIË;ů&­Y«µ';F+Ő(ŤfÉşÉ&î}pŕ®ă:6÷NŇý×U{H«eoFIĄ€Ű›>jΫ™×2%0 E,čë“Pü˛ËëX`lť Ą“›tUmr™Í/sĐ™Ű\Rő vŹ‘ٱU× jX| X@¸&}«[ÝĘZÍáĚA<Žë`ňîÔ¬Š$%Ś4&nR¸nńÜşń&ŠWË]ďvWDV*‡z(ĺŢ™NŢź$­†FyRŔó˘dčďz×»Śmoa^wűëŰ…›˛ë|Ejž•´lŤŤKMNZ2¸Ö NőUýäŕSO9•MăG<âv}._™ő1ęGÉ2ýi[ł'–d%´"}Ę™†rħťćOŽ]îň—+{Jí-ßź {Čŕśb”™»Ź.đRXIvâE¦Â m<¨¨»é&Wú—+aĄ~ŕĚP˝řĹ/>î¸ă´‡”š>^ł93•[Ě:¦€uŹż{Č,ŰǦšĹÍ~űď·őU¶.ś´YÇ5’eĽw~jŘDǤ85+‘Ý"3©äâ”›é‰ߡ6ŮlŁÍ°Ňć—nN˙…mbý“N:é=ďy+w¸iűí·§ Y i®Q`ň(@Ţçľăß|ŕŮĆXDÝ˙÷żţ×/¬´ fęŘ©›žę‡Ě¸™Yiň:ÝZÔ(°Q ’‘t8px6p|«Ä,#ăXČňO^űv*lžřuĽÁƧvŰlç{ď˝7ÝĚľąÓ\‡ą^§ÜŃ˙U|”ň&n &Ž5>˘Řˇd5hmŕWóBOĎ/űŘs! )$Ý^€žIQč-oy‹z)äŽKŻ\Ťn$)“¦-ŁÂô_ü¦ŁÎşČ+[ڬµ˛Rš‚ÇNŠ%.p˛¤'Î6}eILY餔őoął“Ă:Őż«nsUčľ“ –ѤkKLÁV]ŁŔB(pµ«]ŤÝÖo°c7¬Ë"Ő°ŚpPç2Ă©%@ ®±ŢAúîěťÜDpŞČÂLţTd¦T饛\zůË]޶óěďśm×GľĂ·Ć*Z‚F ˇ€|n˝ó­éRev0ÚĂVe¬‡•¦ŢŮŠÜdŽ{˝ÂJSü'o¸ ă`ź”\čŇK‹ďołMďx§;®X±Âb‘Šďť›*µf4 ¬‘ÖÁôyŮîqV2¤»©i yĎO9…•âćČKk¬ľ%hhX łLańSˇ`0ä0´űŇ'ŮL{8“ăÓŹřÂľ@ášU˛/wî%/yÉńÇĎŽIŞřÍo~¨–Pk˝ž(ŽřŠ ŕ«3*=Ůe—]Ę\=ť[ŕsĹ)2Y.ĽđÂéjX84tÝţüóĎw=ĘŠ˝o%­!şr¶¦çn9´đ&Ň»ˇH?ťä˱P·Ň‡“Âę˙ŐÚ®ÁĺLôÄú´3˙ě¬/KUsY’v}ćo$Ľdĺ%d].§‚î׹'ĆĽ™#}ĚénóîĐŻűXH3•Ř\ŁŔ(0őM¨-E—ŹH'ž°6ůľ̤'`‡ŐĆŞďšUkń­\§÷ĘçĆ÷§Űâ‚ěä/eőZ/µM}›jFYIŢěńeǶńJ¨T]đ2^ĽůĹ…..&Qđv—P”˙ĂJb#B)ŚÓž€)†j]ő'hŔx(Љ:RTFő@öIÇJXĆ  a¨(pç0q™ËŤa˙¤,ă~JýDh.¬¤jCť/=€S‹yç’ŤV]…S¦Š¤I{ Cm˛1^ăă‹2+mĽQš”©lÓHO ‹u˛Čt0%čÖ™Y [)Ť(03+´F/¶0ńŕ‡Â/ť®Ö€¦ţ ˛ŚóűńN.´wÓSaĄŽABlp\Ł}Ł@ŁŔäS łOü21uňbş5ÖÄćŃ;ůG=ęQ22/:틨®ŘP‹8öŘc=śšň#=qŇđŮĎ~–±°™*užç*ĐL±‹ŤĎő˘±\cSY*ôp§Ë;$&R±/Ł|?"•“§?ýé>Ń ¬Îý)÷tŘ Ůb‹-N®~ő«Gë¤ď›.˛â  R&߼ ëÇě0)Ň“ˇß5$†Dn,-ا{·yüf}OHňťőYËbzßxeYďRH)%\şÉĹ] Č_YÔNí÷* ¶ąF…S ŽŰU‚ݲµŚŘěÝ:!!Z6qe'7ĆuIZÂrP‚ŻMůŕ”‚Ä”˙»OĎÜ›š,ŇËn·VÚÓ•Y€®ĚÂ8q›nRd”8nٞ?Üř’˛Ş.üâľő/ő®„»×Ćé6xr}x ×ţo?ęĐ]üđB–®żuş'*ć°RţĂ>SlUĆu—ÇX÷Ż„:Hł„ÖŞ}X&YřĄđnzJ ů–ž@Đ1áýĄE^"ÖâŕŽóʇpV*˝kÓZý-ńÚP Žs@e%–†cfź"Bá:&‚ńüÂ@ţu“…4rŐÁ•†×¦E-mŁ@ŁŔDP ®Ü†W3´Ď;ŚókĄh—ČëF‰Íö´…°úźŻ ŕ¶·˝-ł¬Őľüĺ/źEzňŢ÷ľ7*Ó–ąŘHÖ!TqŤk\cöŠÜ ®ôś)ĺž{î9šĆĄ™ŇĎŽ÷\¦5Ďť&Ň%ôw…gĹŠců2źuÖYĚń˛ąKß„˝X˘żZ\™4:W¦ŹŢ&E˝qýfŹbú±Ë ž é ˛"˝Á4ŘŞMÔO#–4ËŠł¬;—źˇřNő/Ţtó•ĺ ź^´9ź $7ĚËa{'ît*'Şlţ%µ˙ĆL첌ͲU*#´lŰĘžŞ[­ÉĆŞĘżěĺ.+ö2—˝ŚANKń¤ˇw0ż¬_;'o)«s)łĚŇhi83j\eϦ.»µ|µµ«¨q]RnŔP0‘ ż”­ť“ňÍŠŇJ™¨.Ý(7¬Ô1Pá#N\sŤ‹CŚů `5tlÔqSnîŘé&oś‚‰Ŕ—˝ĚeŤ[,VŽDDO)ˇŕ,±~â§˝Öč„*3ő@é1`ŔÎSŮńŻ\ęÁDXAÉ> =®‘·°’¨ňŕUáµü)0ÜÔçÇĆM3ý żp „›2řW±RTH(pmľ9¤!]´O!úë ™°LIťq®­DĚâżŐ—ˤbŢŕVBŁ@ŁŔ¸(PVkS®L>ÝŃW™†˘Ĺß™ŹM0<Í›ç·ćц«\ĺ*6đ„/'ź|2eöq§ťv%”Ħx8†˘<Ă(.¤ŚäŘČĺ‘ŘOŤZ óš*şţőŻż4Ő­m-ŰuÎýšµÍ8Kú·żýí,ű˛˘â1ifzéÝ”ĹUĎ™ŞcC#ę'™GLCş'ÓŽ„YjźŘ¨ ’ž„F•˛öoeăםőA¨‹Wű@Ćů8“ýJ·sČ\6Úؤ®"*)ç+EhR‚›”…l€‚-ç|ĹĄşć7 , ŘHL2žłá+õ“´Ćjľ)ŕ2»5hÁ’t»µd/~ŠЬ;˝Ńľ(mŕdÄ%\ĽÔŇ;*żčź幢u.WX,›ÁÂ/®üŘřEZłJ’2ZkĂ4 چ®bĘîq†([¸hťž ;M)sá¦^HáˇpVWŔTSĄ‰L bN˛¸A“JŁe¦FLÁ[XZC ˘SŕÂAE˛äČ_iŰĘ"˛„ä·‰©P§ąĹ¤ŔÔđťúźBb'”ď ć&|TôNşż)ţ…ÁŚX®Žů @ěžrł­ěFFEˇŔŞ™(‹˝•+mĂŐÄČĹĽë;ćc>ř`ľpŔ'śpB˙1ť?˙ůĎĎxĆ3>ůÉO*ü>÷ąO­Â»0o{ŰŰ\yŔđÂľđČ#Źě?úăq™#Ž8ÂkßťéÍŕsĎ=·|¦fp>eý7’gH5ÚŐŃ ŮΖh}‰Łô”§<%ŻX±â~÷»łâe:Řlp¬ r™ dj@Ŕ,żËr$ؤHOBÖźŐe—.Ż,ݰk·– ţ‚˘6»hł‹/şX, ĺcäre1uésÍ^Ń@)«Óŕ$żS 7×(°8Č®JŮYqfse\—5h÷ćŽĹ)O€ CÍOçä>:ŽřJ,C(ť+gćťxEh0ţĂ Ý Qyˇö#^;76Ůh“2ţ±KY˙öVşę-śâ¨|ŁrT®A‹e’’‹6żŚ$¬$ Ç”cóÎTJ‘Qfă×ř¨’ľă¦@ĆęŞáÚťlŰŮÂ|܉+˛“NßÄ`¦’ ˇžó|Ĺ•ěÝnP«±LŻ &ę0ľ´¬ wt†„ ńfdĹ|l7=‰-ÂzłÖĄ+‹ýňK.ÁČ|-čśtš'EôXřĘźr /qŤ•zÄoŕx)0ĘJ†tČx¸ĂÔ;\Ý5v đ”1Ě7aá‚L[a˘řa%Eqăm|+­Q Q`ĽĚ9]ˇeňé\źyŻw˝ëÁdüĺ/é >’r.ľ ;§ź~ú;ßůÎSO=őcűŘMozÓťvÚIĆsÎ9‡U”?žúÔ§>ň‘ʬĄůöĐt m!9ú裩˘01+#k#gź}¶›#RJżÇ{Ěthv­ę0?ď®ŢÔ×řŇ—ľ$‹KFk›qŮĄ÷Ľô!‡3^óŮsĎ=MĚĺň‰´âě\|Τŕç+ÓDO¶b^Čü’î`0ܲŁĆh'Ez˛ZËLÂ9$ďíńŕBńŽň¶“›yŠĂ»î·Áüîűd_gAjY¬@‹ŃŤ/.Z(e·8%:É µ~,V«·ĆAşv\µšě4˘Ë‡Ł;ë+‘"˝-§yľ,!=@Ă/EMéB§Ř`ݱ±’Ő-+YşfŐ*đ¸řZ5e•ą´ĘŃ8·ńĘbR+uć7ş¤ěZ%¦ŇĄ¤ĆMkü Z‚R ¶˛’Ń[vkťî ¤Ak ÚŰĹÉ8« ;ÍŹň_Ď^ęÍ)îţćÚÂnIb ŕJyS"ÍŘT§[hO8EâÂCRŐ“Î63Í.fą:Á y >â$k¬4×_ˇĄ›/Ę8ĚďNŤŢ°Re" ÂGČ_ř•é ă)YÂOiBäŹx­Xiľ]hůi¨LG>»'¬˝˛űéOşŻ˛Vµ{ęEŢŁŽ:ĘK:Ţćjv/éŘźWL€[ßúÖD6/~ń‹Y?ńě#KÔŽ;îHc…ô$b”ˇŚKüŃŹ~ôă˙Ř70n— ĆuRY•źě­o}«Ú ΋Ą°SfN_!@fŠL3ů&”8 ŇÁuңŨtĄ'čk)é·)+ˋ˶ ś]Řsň­[ËÎsłMŚS<ąxł˘oR’­\IĆŹÝ‹TÎŃż[ŻóL‰Z¦­Ě śů@”!Úą2\m­ş•¦5(él¶|üwo[ź‚ĄâÉVŻ`€ďŽ,ńK°+f.DN2ąrM!…#6)Ě%;vŕ绯L4ƦlçŘ\š°RŮéuĘ\R*\śMßT9siOKÓ(°¶Čΰ7â StŇ“đÁŕ Ľc“ÂJťů†ěý ň“#»Ű*Çď&’µ`%Í "á" Ţd-hs¸•Îař’Q1kęáĂ\˛YQNÉĂU8¨$-˙Ň ľ€bkKź–ľQ`Ž(Ţżăś <ač?łR7× řĹĂUĹöÉ”`R°›¶ŚvCšĎÉĹ­-+ͱµ-YŁ@ŁŔşĄĄŹ3Î8ăŁý輥'ÚĎR†k8L™˛Â$*ĺ/“>Ěrů…"k;ĎyÎsh©|ë[ßrU‡˘“ťwŢ9a´uh®¤Š2“6ĘiČ®ŇĚŢZňŠWĽ‚ýÔ1> EéÚ›Ţô¦g>ó™řĂ´Ç ćă d“‚…o…?ş'Q<á[‰q˘ř¦sD\7Q ĽĚń'ˇł lĂ$JOú]Ş[вťcβĽB˛‚q€%ęp=ýöüü<đ‘›XČ•(± H–~E n żUGŻőjYkć¨|ęsâC´<•>pV±ůč$‹˝âT™ i¤Š /t›4, ä”Vؤ7TTŠGÂ/|ąřř ’±ˇ˙tŰ<”¶VµĽŤłPŔđĂ8I`důpŘ$ľŕ€•0”'W;™ dq†8ç?Y:±KÄ%µŔYęť%Ş4©hf)ܱQ‘ÝCb%Ë~2ĎTi{w‹¦|ŠÎd‘šż“ž€ńѦťT&ÎRu‹j7ŚOy3řqDeĄÂ)S®đKçđŃ@tұŹxčA*ÓH7Ú ŚcbšwŹZĆFF±P ŚÜ1t÷•čřú–·Ľ%é‰7n^ýęWăýyWdw}«Î­U öá7ďÜZĺZÔÄ,ŕ*ßzăüóĎg ÷őŻýóź˙ü»Ýín‹ZéŇníńÁ~đ/xÁWżúU52Kn•ýőÁ'=Śşnş(^f‡3E·TŻ—ÓÄdIOú 쬻ĚîNEş[<Öšćň˛ôÜ$‹Đ˛0vT>8Üs©<ʬĽÔo,1g4đ-^‹ő“©c·ÝŚĆěý–fh¶Z6 ďĘ„§śŤ“ńěËQż,Ł!ßyźm|ůI[6ĹFCÉUţ+%"fü™¨šX,PRsĄîUD7t‚.b»“|śS*˝¸•«š_¤*ŮćMYsXŤ•ÔÝ;)oÜ4ÓoŃđóŁŔjÜ4ĹJŠ2bëĆ/  ËđŤdřľJꉒ#ĄţŐŐ„ŚĹ€P·ŚÄś|fś"M™nş‰§‚ůĐ‹›Y©S7ÓÉM:eWFÇEŤ•fý ZäB(0ÄJŠ28ů…•Ŕťî Lux¤8B’Nő+Ő) %Y¸Ś_ÜÔD'j!íly–†Ćí*+ÜąUóQ7-RŮb‹-\“ůřÇ?>Ţg\–¦Źă­ĺ§?ý)Y’2ow»ŰQ‡9÷Üs?˙ůĎďµ×^·żýí©ÉÜűŢ÷ouKVšťaš˝čE1KhĄGîOůÔÓ71~) Ĺ·‘’ëđÝ´Q¬€ *ÓA†Ůżd][ÔŠ&Kz’®8Ů„Ümý ¤wt ťÖÉFSmëúNŇXžÚ ŮřlđH\’Ąm©bjťÚö{…ÍŤŹ«-R[•ľ#ÝnÍ(5†}b-_÷†±ĎMÁt®$Ť+Pץ¤Î)0půo®ć5Ô{mIk<ÇćjÇ/eS×ÉJJSq MŻŽÝĆ8ĹĘ”+őO±Rö%®ąFQ`7M 7 BCş˛xŔ8ťxqŔVső5PÂP}f,|1ĹslbXI°I˛ĘXÓńE7#•ńŻ=pđ…Q(lmVvŞ™Ź<– 3őůH!mbšăŹŇ’Í‘«±’qÚ)pÉkdĂqa0`ĄLJť?Ĺ:S9 /MÍPslPKÖ(Đ(0IŔĚš–`°éڤŕSźúÔßřĆ&=yó›ßlľö3S ýq˙…H…17›Üĺń<ÍţűďOâ0I?ělmařÝď~÷qÇç^•tD7»ŮÍČM®p…+‹”Ź˙Ü´N¤Lâ2yd‘¨óÓ Ăl¶6-ź¸) Äd´8”5@T6%—ń" Éělą™(żDV¨®ĐRńK“j]§Âdy*KŕˇEęP§Űšu -8 ”•ăĚ.âŹ2»ÉiđI)űąîęÁÔťsX ř ˛ř$ ¦¶Au)p¦škŘK0HŮ™·ě§§äB—$Ś“Zđ‹Úa6żdsě@(‰e”ÇÉ+jŕş·BúĄőáĆJ}j4xŽť•˛ĺË`ć±ürx>ĄŇŐgśđ6s®Wb±BA fń_T™ˇ•IfŘ'>A…LqB‡ď2aiĆ•čGb‡2+•ô€d—¸ÍJ3ľˇDŮą)ú&*0VŤŰľźa\},&  đÝ&Wq¦¦)'4¶˙&áͰťKËÂÎÁ€ÍJCÝwßťôÄSÁŢ^™ý9› ęę"4ĺoűŰŢđŻX±‚Î…;) ‰ Ë ßűŢ÷QÎ<óL†W;ě07zýčG»r´­[‘^ň1щ7‰JV˘Á·ąÍmň¤ŽO}IhkőZ‚`˘x"#'qŇ‹4„2˘˛Ż ĚWQü±ucť4YŇ“QRdP(NĎş“¤”&űUKŃÎ ŠX6PĘ2´§`bµZŽđş“ňD•cŔ)'f üď«1„iÁF5RŔŘ3r†ľ«-[úÎĐí6{E|Ň}aň}ɨöéťŮ+ A˘RAů[SŔÔ=Ĺb¨b¬aărCklĽiy„Ďé‘÷AřÚVřâ’bh°§t·­č$, jgËĽS ŚôŐ]܇eĘĺ¦X)!ü‚}Â;˘ Ŕëv~…ŐşYc}ˇŚTÚ—ÚK+¦öź€Âť9ˇb˘‹éó)^€”ľ3xRć°H$»´ĹëĎE«şěŇ—4Í5 ¬ 22‡r”A;ĺđP˛°†ě3Ä5ý`$•˛7Xwl8UfűżQ Q`YP Lś¦‚g|¶Űn;÷wč&sĚ1y„eYtpěŤ$:ń Ą *'ĺű× ř0”5ČPH—ČP[}mçH"čˇěłĎ>ő:Ď7ľńŤ|ŕďyĎ{Řâ ‰¶ÜrK-¤rB eż~‚âŕ!űľ (~u‚rĹĎčŞăjěżĹ„8ąŇ“é]褡e™9Řő ®žwÓ?©ŠŤ_F3 »S^‚Y¤"´ŚüÁ)źEY˘¶ő脌Ŕő°«© Îéd€5uTŚĎ T13Ůű"˝\ÉťŤ_·FMúůŃK^ űXm(ÔńPX#’mTi¸\+Ó…eŔ\)g 5nšßŹŇrÍ……aşŹ6SČ’ÁŚ3‚)ŚÓý…•r¨ŢßőuĽÔ%éV<ĄĽÎÍĄöˇ4©Ň'‹Trá.PS3]ŕhAöń‘TJ^rMńQ…ÚÄ„"Í-&fbĄÂ SZgtZáŞÂ<Ĺ|Ľ©mCÁ^đc 5×(Đ(°l)P8ş[…â÷ţ6؝ғN8á©O}ęŤo|ăeŰżů7üŹüŁ”ĺ×}B„J%„Jˇ¬âŢâ·`#†ĺg?űŮW:çÝßÜŕűî»ď}ď{ß]vŮ…HbţŤoÎüă_řÂX„%7ńÜrŠńű^ďz×Óťk_űÚůąa¨“€ő…†©vO`4ž¬¤ĘPKƉ eč#XëšoŰ':ß$JO~f—v3ô¦eŐi*AśßI+«Ń¨tKYpŃ=é–§ńaúŔpů-Ü(0n ˘ŠśŞÜ­5!}V ľ úč”őg·0u¸W–¬S_I <µBí5ÇĆ–JVwř…މăqĘ'áÉŠâIwĘ],8Řʸ:+Ő ňäŠ[˝ějX, q*TżĎJ‡Řgµ`gĐgޤU…̱Ń2ö©˝d!ÍYąÉŽ v–&r¬\ŘŤ„Ą»łź©j”•&vŽÍhÉBŚ%¬ş)&ěĽAËIP Ń™-y»i+é«h®Q Q`YP pq7™bóLmÁÄĎl›M7á›ßü&»§ź~ú˛čÚxéaťßýîwîÝa‡Lń(S©(dDCŹÔp˙űßÉ)D!LqŻçeť#‰ @Ům·ÝîxÇ;ŢáwŘj«­ĆŰČ~iżţőŻIL>÷ąĎ±kKŚsŃE%Vł)iˇŽä ‰IôMř:¨µńĹFn’ű;‘ŞŔprU‡,ˇŚ\MKj‰úŤ\îđäJOęj˛˝Ó@)łuç¬A‡áýBÎjŐďSŕŕeČ5ôkAaZ°Q`!0҆˛gÄfV8ɢťďKýĘZ ÓťÔ’“˝g’˛ŽóApęŘ\Ć0HĘIz‘ˇPJ,)§«ňőL˛ŕ+™°†~ß(ľęúĺ0_Bh˛ýöŰ«TŰňËęBś zÁ‰ŠĘôDlú "Dz—ź˘2lŔĘÔ€ři‰¨~“ÖxĄ'łÓÚl“ lť¦~’:dłńWB‘•tKP§5AJN\ŕ›ß(°@ } ä€nłĄ ߔР“ŐŞOOI3µrMTM/¸¶nPű§”ěľcťŮU,ĐY‡%Cˇ™QăjŹUM©˘Č]sU Ź,ĺ7×(°` dÜ*f(ĽPFpĆ™ž fJěô}LX©ŹĚ_[§XY ű5»öŕť8HěÖ¨)W{¬ŞÇJ)-‰kiCÁŠo@ŁŔü(Đ®W󻉩ĎJb««ěÓź¶ÄjIßź_ĂZ®FFuBU >%…ÁăqVˇ‘›ÚŰŘßĺ.w!=yžŔŽě5ŻyÍuŇ楯”ČăŕFŠť‹\M!—&ĺ3ŘźµĄçD‘,Üđ†7ÜqÇ™DˇŠrÁvüéO"Uáúş<Ęń Ď5: ­ŕhđ•CŁ1qt[aQŽ˙űßOKM®~ő«űá”úqµßĎĘĺç& ‰ eZ鉔Ń:‰/ˇI˛¤´:rÔUÝ´m[?“+= }ý€¬AÁ€˘ M|ŇiŁ”`A ~‹K6.$˝2Ŕ?HÚý×ĎŰÇ7¸Q`žčNęúy3€aň5IT…96Ďf0¶ÄJŢYő« nÁ®bä.»ľîrA)Ű×~uVŇ)Ó*ń`.­¨ŔŞŕTŢ`šß(° ڰ’Ňvőť[EX©¤°›ˇ ¬Á´§rÁĽ›Wk´$Â%;±OgŇh5Ö ŔŐ›•đW¦«¤áč·d€iÜÔ'JBކ ¨c8xÁ8A@eśUÄ(]¬`Í ůŤŤË‚aŢ: Ţ­÷ě„ĹÚ›ÝęĽ×^{}űŰß>ďĽóHěůE-‹ţ.°‘Gy¤^aÜéNw"ĹđaŚCD+ź_é ŕ˛0€Ď‘e\őŞWH@Bęá6‘ ź]oúúmçŞI×96ŢoA»Ä#Ęd.%|Ž@$-Ô< *ś`ýe0‚̤{RĄ*zť4UzHQý*2śřićŘťĺ’lrĄ'ˇ¸q†”•ú€26íčPş•(X‚ře ;Ýň´ćšćWi‹ÔiŇPóĄŔŕs1ś=ż ([ş’Ě—‹ż* ¸şÜ¤_V˛÷1s“+µÓÖ—źi‹ÉŮҰm~ŕřš×ĽćźřÄŃG}ě±ÇN`ÇۤO<ńuŻ{ť2ďv·»1zĄŚČMř¨4ř|l˘‘Gx¬çZ׺VÍ Rń~01 GÓDĘ‹;—ĽůřXh ‰ ±ÎŻxEpż%iX|éUʬ>žíš´ IDAT .˝§kUJ"qDE|±’qIcÔĽ‰J0ĺ×AUŰŁv0ýs“+=éÓz”ú0F›Iť_¦ťPĹŻ(WĆh˛[ËÖrJşW˛7×(0& ŚÔZpör &YľnewNTÍ^1}d-j@­%ĺ”ÂJS"ßJřŐX©c´A–Vj|´ŔĄe˘ŔĐ(íÇf/©D’aĄ$¨ŚSł¨ř~9 ‡űµ %2”Ž©ĂÚV4;â’Ţ´3:15nZřOÓJčS Ô>\Çdş5nĺ”LĹWdÉ2•l¨¨lhX.G›hY˛ lÓnh^“ ;dw@đ€śtŇI/}éK]HyřĂľ\ú;Źv~öłź}ÔŁ%#s'®Ţ B„ hjŔpÄ1‘ ŔÁ#řđI0 ŔŐOŃ$(¶:Ŕ~šŠVŚ6$ČO{4ĚŚ ĚŻ],62‘ęĂDVJ:Ţď~ż„~µ €´°ßŕő žtéI~=c¨b †ZĺéŇEżÔ’”ó¶Č ÁtG|%ÁęĂq=űu[w–ŁĂ©búŔ`ÍÚ} ÷µŇÔš¦Â}Ěű2T”ÁźZ*ľrJ0üĘJ©ş&Lö~“F1ýŘ7 ¬-ęȬëČ fśÚăU$|˘*fHp!~żüŚü`âĂ9ĘJjO‚U;Ř©%×T¨ýß(°P ô‡kĘę׊éOLŇL›,QÉŐüFFĺEĘÔ€¬<ů&ťÂí Óß!G’bźěQ^—wHóÇ\íjW»Ď}ú>ÇÖz`hź}öˇ˛Ă;ěşë®HÁU!â4„V ěČ6kdNçWŃIä)Un’(:%5%Ú*D/Y`AĹ ÓwÁ×JđĄńŐ kg‚`€`Ä%ŐÄéN:%¸jšŔëxŤM±|)S`őÚP¸ßňő žtéÉÉí«)s”Ç_Ĺď"‡Žř2vk®4 ,śuV@™Ł»Ł Č~š…W=®ú­Ş¬”ÂKÔ+Őď{ĆŐ’VÎNă­ ąž[ö¬„şc¤AżVç¦ĘAču˝Ťó§@ÇIe-^j.¬TĎżâ–łQ Q`R)ĎB|[ß6ĆÚkol'ĎäŔ6ü‚(lv°ÍAĺCúĐÝď~÷Iíß<ŰĺŮš»Ţő®úH×ćŢ÷ľ7٧ă|¤ŕ#T|Č-5«( ÝŞô†çŁ6_T`ŮÜ0ST$*UW&íÉO¸úś`\÷«L–ŔGëD§Ŕńk2‰ ¬F@ߥ µI35{=Ă/'éI˙Ş?C\‚}x&Ě´+˛Ťcˇ@«CĄŤâű><”qěAu U×gź>śŞG1łăÇŢŕVŕHˇ!Ú§ŔhTÓ‡űąN]ýűĚ҇Sű(fvüb´ą•ąˇQ ?>‡ú>mTه‡ň¶`Ł@ŁŔr¤@šĎŮ ë‚M2ࢋ.ŰBÇK /hćĘäµß~ű¦śsÎ9^2v‘çţ÷żżŘőĂ}ĺ+_ąç=ďÉx+Íš:Ud‰p˘šé‰(˝őC ‚V‹đ«Ž ˇ‰`Ĺ$Ž$%ÁřĹ*'Ô†é»ŕůĽÚńÁµUEÁ$M`ÁHCŞ_;#V˛ŠI–`R 4µ´ ĂT—VőŰĽ^ÂËIz2ŢŔ/=Ţ[iŤ m€?zëňbP ±ŇbPµ•Ů(Đ(Đ(Đ(0Dţtu6ĚöĆöóâŰZ“# śrĘ)ßýîw÷ß˙WżúŐ^2*9?ň‘Źüĺ/ń>ÎȰ+ pzÍ‘€ŁšM*Ýô\"‚` H@¸ŕCLÁHOŞ/qä,JH, €?­“ >µ5¬b‚Ź_Ű)—ľ€Ó/>’ßďZ0ŐW—\üŔč"‹7mk×W䲗žô°>Ľľţ`­_Ť‹D>űôáEŞ®Ű(°ľR Ď>}x}íoëWŁ@Ł@Ł@ŁŔäS ó?[÷l€íía˛§t h3Ż/¶Ó|±6óq2rě‰pŔnî|ýë_âźčYßW˝ęU¤*“Oi[¨kŻxĹ+žńŚg®sťë ťčŽľ#‹§mČG%B‡PFČh”€>ńđŐ‡ŚÉÉ Y€qÎo$8Áü‚‚ůůű~Ěr˛s:Â×ÇÄʨ›ÉoTXĚŻ€ —đáÓÂőŢ_öŇ“őţjlhhhhhhhhhh ˛ďµ9·g¶“Ě–Sń‰ÍľşúvÚ˛ě˝÷Ţ[mµŐgśńú׿ţ _ř»ßýîßřĆciŰRrÁrČ!§ź~şJwÚi'7wČ 8ýŐSĘâ #7—%ňQisd"| «ô YäËXv@…SZ#¤¨řúcÁT8ż]ý).JĎĎLŕD%ż&H02&o0ń¬pmŇ4éÉős·Î6 4 4 4 4 4 4 4 4 4 lp°őŐçřlŮH×í4 é€d6üI3älőďt§;młÍ6îĽPBŮy睏;î8Ďń %›äŕ˙÷|đÁżţőŻI öÜsO]Dë$ľ`tOň|o4P"O©ŇTęä…°.GBzÂćGzŇÇ©HLr%{Ö‡aęŻX0żLÄńëď(L$ úIŁŹüt*ČřÁ‹J!|ř~Ő‰‚ 2Ŕâ7éÉňC·n6 4 4 4 4 4 4 4 4 4 4 Lł·F~śÝ2€o#mçč;H‰ŻýëÓÝ8í´Ó~úÓź>ö±Ź=ů䓏?ţř›Üä&Nß_ţň—®ęśxâ‰ÚąőÖ[{}yŰm·Ő;ťŠrđ1Ŕ# ?´"V¨b@`>ÉHČ=~RĆŹÜ$QJîň Ľ>éRŚ\}ĽŕS—Š‚Ż~L`Q~€~Tđ0€Z€ &͆ßoφ7éɆö‹·ţ6 4 4 4 4 4 4 4 4 4 l¸°%Îć@ýoGŤ‘C˛n㓌ě@˛úF3(_ţň—?˙ůĎüăżůÍo~Řa‡=˙ůĎżň•Ż<Äýç?˙IGć…/|!±šw«[Ýj÷Ýw§`˘;:[ťŇ4á‹Bx 8ÝŹJ„!Ždč .’~dtOęŤľÉ é”şŠ Ä!Z˘úLŤÁ¨·ÄĎ/X«UJÎoÇŹKT…%H–dOQü“=pÚÄď·sC€›ôdCř•[¨[_[hűvA@âl›mŕŐŮ]Űö'XŁ$#V¸Ýínw˝ë]ď3źůĚąçžK<ń®w˝ë#Žxüă˙/˙ň/Bnr“wĽăÇsĚ~đM˘l˛Ç{\űÚ×ÖťôEďjOőH0"5™2"%*q˘T_Ţřˇ!ŞĆ…ÚÁK YS‚kŢŠ fČŻĄęÄjLđ|0dżm“¦ßl0—,}_vý­HĘŠjŐ7Ŕž·.7 Ě›ŻyÍkv˝Ă®{ßgďą”pżűŢo§›îôĹ/~1‰˝ń&ďřŔąä].iŢűŢ÷ęăű°®ĽŘT˝đ ýjţťzę©3őń¬3ĎJšsÎ9g¦4 żĽ(püqÇç7}ÝĽn¦–3;—4Cţn»î¶˙~ű?ýéOgNo(ďZ}@†ň¶`Ł@Ł@Ł@Ł@ŁŔ¸(`Kg‡¬Ě©ĐŕĆGŮaŻ®~b7ÎŮ`Ç%–@A0đŠ+úЇŢő®wő"Ď˙řÇ—Ľä%ô;ô }ôŁ%PWłçX޵÷ă÷¸í¶ŰŽ" щ§wÝuW†ZnzÓ›jp:’ĆwÝZŐŻkßđ«“śBIdŇ®ř¤ěÉX[X+WK«-‘=j25*@mam<ŘĎLÄm›ń0Gjo8ÉšîɆó[·žŽŤţăÂ?ýéOľPs)1‚äš’ę ĽůsąoąŢ¸Ů…ĺcďć“{Ň?ţńʧţ”j™l ¨ęWÓ‘^řĎ™şsŃĹ%M=F)ĺ´řŃNM›¬!—ŚÎÓó›ľď}ď{üż>Ţ2b´öŚ˝Q<Ś…#QÚGNűČ#ń#Ž<˘¦Y«HÍŐ€FFFFF…S sYVnăŰ0CÚW ZÉđ-tł‹NĄ0‚q’™%᫟\|š$ôPÎ<óLz('uî׸ĆCňűÝď~w¸ĂěóŢ‘iKĐ…Ż}íkţđ‡ÝÓůŢ÷ľ—4ڰ0qâMb=â4>ćK¨śDâŕŞîI`Q0 ę/;:¤ý‚`NĄ|u…Ş|Ds˘˘Ť’Ä$U|ż#2ö1.5u®bšÇ‡ PżâÁÚ™¦ö}é;ôŕâŹdŐ%Ş+¸ąJĹ»µ‚4 4 ô)°ăŽ;>ěŕ‡m}•­űČŻţ÷˙÷oűۡ?´ćZ¨:Ú©Ú»¬ |îsźűío»Ůć›]|ŃĹěó[Ţć6·™Ą%ď>éÝWĽâkëĹ|˙ďyĎ{~řĂţçţç­wľő{ěQcĐ(Đ(Đ(Đ(Đ(0 °gN3ě·íŰů06Ě6ád€ ÁŘůsŮůG”Ŕ|¬,0đ0I&ٵŮ;ěpţůç;H I1“ľ˘sڎPNąç=ďéÍăŢđ†cŮś˙čG?˘iBôcűŘ\i3k,Ş}“*ţĐGQüHRŕ0qŕLJ t¬©ŇđąPIEľîsđ`€äO˛!X‚š WÓ$8äwĄ~/°Ř´D®T“4Z[áD%eb×ě“eČl®O&=éSŁÁŤ‹NňxnŃ«ŮŔ*hTÝŔ~đĄčîűß÷~ŐěłĎ>_ůňW~ň“ź|čš]zrÝë^·oŹö2+z{ď˝÷ADařío{“ž,ĹĎÖęhhhh쟥"ďŕëö;Űxâlżk‚ȤäŔ$&±xR}b…ČYd‘€Ă'ą¸Öµ®EPňă˙ Ĺ„H©“F'§jVHnyË[R ąŮÍnf•ř:׹Ε®tĄYzđ÷ż˙ýgťóLňwľóťłÎ:ë«_ýęď˙űšEăŻyÍkÜxPŮŁ9Dy‚h_0ę$1k"=d\´N‚‘X‚dású.Ż%ŕ‡hꋬ)* &Ař ‚}L‚CľŠ¸ t‚©€– Á5¶FŐ±Á÷‹…I°ůŁhŇ“Qš4LŁŔ‚(pŢyç]pţ7Ýé¦>ÁŁůzF&=úarĐ}öwÎţĹ/~±ýŠíIĘgzěíwżűÝ÷żWDřŰ^c[Ă6ŰlSkaË9ů¦›mÚ?O¬éíŻů+řŠWş˘ ŔÔuéĘKk’)íÜsĎ%ˇß~űíó%­eV@Ťßţö·˙»ß_k»kŃ~ěokššá ţ˛—ą," µä˘^Dm¤¶đ[ßú–yôîwż{ĄĆßţú·sľ{Î/ńËËoqů«_ýę7şŃŤ´¶–ź^şQ™‡Ľ6÷Ç?üŃĽ»ůe6ź…Şsov­e1?űěł5üć·¸ąąĽ_ĹLťę§™%»dţóźW^˛ň WĽ‚IÝ‚ˇ ë†Ü൫çś}Îe/wYxżrźŞ5Y’WNčÜÎ’&)go•+-˙Űßén¸i,˝ßËĎmt)yhTÔ¬‘4 ·¸Â.5Ŕ 2´Ś㡏ź…YúÉFad<ăÓgŔÓ1fîî ŻĂé§źţ¬Łź5-SŹfŻ+oyĺ;ŢńŽt–řVäL€aüÝsľk9xń%cíŰŻĐŁ™7|Ł@Ł@Ł@Ł@ŁŔ)0şä‰ł0ăLL®‘‰XfŔpę• ’o…ɇŚ0 Ż4ňZ’MPE±Î”€n¦™Îjů7żůŤéű ťëwÄ ÓŘbÉśÎ)śÄDJÎZÂĚŢOXuWąĘUiČ_\ŇÎ84@¸ú˘+ >> .±|éE'@{ŞS{N) #@)ôę0ü*=ďâ`¸’´©´ ôaČ5¬C*„Ď/A?8\ 47Ez’ź¤ď§ú`ňűÍÔ †oXľ°Gzýë^o¨ ľÂDé˙öÂęK Ď{îól_?|Ú‡k)ŔŃĎ>úŚOťQ1>ŮŹxÄ#Z0ßT¤ý!{“nrÚ—V$qţ1Çłĺ–[ÂĽń otGüéĎ|Z 5 ŕ”SNyŃ _d*e*ş˙ľ÷§Ůřž“ßCXŁ=eSÚ9ÓŐk˙ăµZŢĎkzcüň˙ľôi÷űG>â1ŹyLĹ ő`eÝŤS3e0÷ż˙ý_đo/ČgćSg|ęĂŹ¸ő­oýŻűʧ<ů)_úŇ— Ď<ëL›RYéü˙ď˙‘&$/˙jW»ÚŁýč=řAÁČűůĎľÂ}żď}ď;-UçŢě¸Hľ%ÂQĎ8ęßřFĘ7ßâ·@c ™:•Ř5f—ěa}řŢúÖ·{Ďţó-/ü:l¤Ą„Źťţ±ç>÷ą ň­`ŚLç<€ńÝ—űŇ?üá‚Ö.n&?ýO?ü)‡˙ßŰŰŢV­ĚťK«”fhí±ÇÇľôXŁâÓg|ş.îł÷}X’ëŃ9˛Ŕ=ďqO˘"\°ç]öě7ţŘcŽ5c~ösžü™Ąź}f¬„ Ň:ĚXĹP¤'xĆgÜă÷M<;ćŞW+o hv–23%Ć58´orÔÉ8ˇŰQ÷éNiYą™š´··”µh‰pD0'2â~0˘ŕÁ˛[¬‚IOŔŃF„wVńëÎY{g9ąśÍpłĐYů˘śU«CDkĹ­·ŢZŐů”öu’A)ůÖŇšj©É‹Ç—@7!ă"C‰/Ř$«EÁ($i!@0M­‹A0§µŕ [Ó(a_łĚČ"*m7@0_[“×5 .‰Sě®ý?#Ć,=©?猶Fő”Ż>ţŐ^DÓ92oŞd_ůĘW9řľ¤cÚ®“ľ3~ţ/Ďßz›­©úËţÍo~ók_ýÚ›ßüć/ţďÉJ|©“ńĺŻxů»Ţů.˛ŰÚÝřFżţŐŻmç>űŮĎxŔď˙űČď}ß˝IOĚ@_ţň—oűŰ÷«ł…ĽŰÝî&{ĹŰźöáÓÔ ˙÷üťö#1Ęăű¸“ţßI+V¬H2űä‡=ěażýÍoI^4ďš×şć7żˇßÔ_ěţăAę=ôĐCézÜö¶·Ąó˝ď~ʶÍL5>óYϬ•(Ź<ó¨gFtB7!QÇ{ě»ßőn_đ»ßăî+¶_ńóó~ţőŻ}ťfĘ‹_übÓŘţě/µľ«­&!°míŐ®zµdňçŢ졌㠒őŽQŮyçťžŘ$SĚyđ|ÜqÇí˛Ë.Ş›ĄSsÉ^üŐŻ}Ő&?ëM7ČÎČÔ¤!pżé÷řý™_9“ęěCüW÷*ŹkvíyË›ß"Hc–ř̦mA'Ö¦BŇ_¬U«”ŁłçţđÜ[ÝúVŰ^}Űď~÷»´śŚ:ŁâyĎ{^jź; ÔÖ®X#łĚ^B4Š1”IŤö/…Ćç\Ţ™‡ô$‘×[1Ëş„2ľłj¤rrŰ]n{ąË^ď0…óÔ#źú»ßţîÁyđě­m±Ťë0HÜzĐ—Ö…FĺE¬§ÁŐ·3é lÎů$ŮáNzË3É,<’W¬Śđ9YŔRÂóë>FP˛‚ŠĆÁ@’¶ •Y¤•pu„&$jä´­ú˘`¤ŚX;aީ̀‰Hů‚\`Y¤đˇş*Rď8AľÖrew‘•.'Č\'oŤťHáI  @ü>¦¦T'8É*`óçN1KOć^qKŮ(°>QŔ•–Nű¸Ç>ń‰OĚ'‰ôäÉOzrU멿ǽę8˘ęoyë[L!Ićů[:ßúć·N<ńć?üá4‰NöĂ·»ýí’LáŢ ¦?rę{O%ă°ÇË6ʬ¤/=ˇ’ 1˛Ř &c|›XZG}t®áŘ>ô!µŐ·K|Ň“ź”4Żzĺ«NČőO>ĺäÚĽ˝čE'˝ű$Qp€©%)ŰvŰm%sí(c^rĚ;ßůNj/ŢÇé_W!A˘ĂžtŘđ×"$¦.ˇ@Í—;ßůÎÉÎ×©ŻžőUZ ‘ž¤U»Üvéźü”'{y®¦ćŢ졌ł‰«hśN›ćżüĹŢĂ@”/Đsżý÷CdSµ–Gqä'?ůIRš8&ě™:5ÇěµRŻęEĎyîs(‰¤.·EŢü¦7K@łÉ{Ii˘ęO|â4ìBŕíđßú–·?üpćxó›~ć3źyÚSź¦ýđuú_ŰV‘P¦Ąj´űî»§ĎzÖł>ř˛*˘p"?Č9˛@˛ĎĹź łĚROD®í$Ů˝îu/ÜńąĎ}Î)™WgÉŰŹrtö‘Ź|ä>ö?{îąg?j&Ç´X$ázű‰oŻQoŰŰ_ö˛—á>čý…QMĐ€FFFFF…P ëŐLń`.›ů,Ŕ\]ć-ZR]Ű˙‹…'é0OEJˇ_x°ĹŔŽ+utň>Ś*úç|jTTż›©ťŻđľź Ů$_ŰřĘäçťťČM˘{–@lß%ŁĽ5{­%€ÂEU:@Ö¶ő[@€Ľ5q2ęrĹ 5c?×PšR¨ÁÚ¶ŠT¸5Š©Q Ą@“žŚŇ¤a֚٣R 9ě°Ăjf6&IR¨NTĚ(ŕl˙Łý(üKŽyI•Mzˇă O|Â+˙ý•¶Ä$>ĺywŤ¦†3üZ•Ĺý×µ— Hňą>ţńŹŰ0׏» Ż3“ľHEzÝÇsLý¶’ĽĐ† `##ĄŃ1ůź˙){?dúÍ#Ů9ĺäS쫵żä¨gUE'ri éÉ…^čh]á)“Ż1D'Ź}ěc+Ć>___ú˘±‘ž0ËRSÎXŰfϥ̤ˇvÁÍ1ý 'ś@˘D˘ńěg?ŰÄś\€˙÷ßm·Ý¨ę ő^{í5Sik›˙ë„˙Š ,eŇ.Aę=öÜŁŠNૠz{ěľUY«G=úQîL™¤Ą|äŁYŰă·đCÓI©ŔÚ¶JćBŞčDđˇ}(鉅ÔĎ~ţ3Łeî,ĐoĆěđ™e¦Bhr‰˘ŞĂ‚]ŇÜó^÷<ţřă­?ú‘ŹÎ¤ ňÂ{aý•ĺ:÷Gç~çŰßÉŞ*Ö#ąŠ°Łő’×@îr»˘‹T‰!u0%üůOf?ĄâĐ(Đ(Đ(Đ(Đ(0F dóß"Áz€K0łş`řq&D)ÁD!˘"qĂ$ ßň’ąIŠ•@Ć!é‰4JźZú~ż› Oú-QKu€5†oFäć×›;D†_š8xźÓŕZ pĘçsÚYŰK”.€s‰­@đü’ŘŠ¬ÁQ ›¨űČ *pŰM°ó IDAT§bŽ[vڧţéSąĺ´N:–S¨“‹ř’%máŘĽvůć'?F2ú pJÇé/9Ä3­ni§?‹ĐÖ¶ť\ÄŽz’)3ě3˛ęÁUťÂ?űéĎđ ůb;Ýę‹ö\D­ ¬0b• Éß.V÷Đá®˙!č "Ć‹6NµŔN`”ťvŢé~őčćmÓíS–:·p. †)ŮLŽŁŚ~ lęÔ–˙EěĺbŘ ±<‡,^cÄޱU†M[POř‹-*ËN[öÇô¨Dň؋õÖ7Uf*ŐR¬“âŰÎöşçž{.b%«óŘş˙'eŞôK@€f…wmF}Ś? Ř q3ŠĂ& S'ČĹMŚMVĹŚ ±s»çľŹM±š{‚Ť'-“¤óńÄNÜžŤ“$®ŔA $‰éR ŽK’#ĆI\şIlJ–›@Ęâ!NkTÁ›Đvi =°LśíIµöŔvFw¶GlíŃ[°äč6{Ô˝ÚŘ%ë-c즬(yB€ťMÓ„’ţ.=ů)OňüăűzuVD_Řq§ypýőCß–˛|Ĺr–É\}ÍŐĽÖ”w¬Řf•eśÇsĚi§źĆď~Ž~ÔkŽB=ůĘ—żÂüč3Á»ŹaŮť´ía´’ÖÓ±Ó=Öžtü“¬čďwręw˛= §“% äR†‰0<@~ţó˝‰Ó Óęö´Z˝0ÓmŘÉ‚ň˝•>·®uc`ŢŐ;TĆłłLç(¨lxúőCĵcË@Q`çťv.ődŚ^M%“U¦u T­ŽÁ+~;ž/–N-’lČçűß˙ţţ\<ěÂÓ.Đ«2\†ťą?•µELW_}őšŹ®ůęż•ŻÍÍÂÎ˙S„Î8óŚÎĚŻ-¶f ĚCŚúřÍĂĎĹ.I ä Í#}ěŢE»I,Ŕ@ŕŘŕčEŘŚ0©Ő­$ŁM˛*fXB.YxMIV YbWś>$®îaĐxâ^6ÚŇ™~ő$žV7ˇ‡T'®@ÝTO\Ťs\ěę /{lcVűčV›Ŕ€g±Ű˛˘&“@©üé¸_aËŐ!Xň¸•‡ŘN1Ôú<µţŮn˝5;~gŮ ˙ŮMĹ)Ľ’ăÖ[neGXŢËóČoYľ|ů†RŹać?ľć}˝Ěăŕ=/Y¶Ó?ń¤× ˙ ŮR”[ÚĐR3·ŘÚFN–˙Ăr ĐůĂ–¶řů‹y÷÷ą[ľy ęÉto0Óęö^Í$ eŠ[/Łޡ{ŕlęńOčí#;0̰:m"˝Ąĺ‡ýp˙®|=ČeÁńw~bJö/1˱äŹŃ«-~+¦u TO:;t<#^,ťZLÔbÎC9„Ín;ąwŻ˝›—±®§v†îIr÷=vGŻaÝ/·FýĽí¶Űx={îžřŽŻýÔµ¨ź3iÜş€$ á2ÖJŚrÁ0&vÂMćĆ:Qđs˙"Fb¨8Š ŁŮĘĹčWO8~B :‰AڧÓá:4~”d 1p¶ş 6ž(&ńÓgäĘÇŹAg…jŐIćXŁâN÷FI¦ú(%-3o l ő¤ľp ůĺ éd™”Ŕ"P[K2ĄżŁž°a*Űa 9™ČýŃ˝˝ő;ťPł0ž±Ű3ČBšˇ5tvC`âo!pg:óŚ3oşé&6łäýŻą¦(łdÉDŢĽĂ&ŮäČ#Źě´?J2Ý«É5m•ţăţ‹źó2Z^ĎÜúÇłůĂ;Ym±b劶…:ř7m™~{«u»˙ĐĺáöĚ –Ąđ=kŻg•?ó xmó†:ţJΰ:íěľ{ď«E űŕčď3) l}ą6ótV×)ňAŰüxĐAp–Ň“«?ql$ Ę @ŕÁ¦d+ť`ăÇY1­áÄCőřŰbGĹHŘéIbgDŽź»jb˛đă©8UR>1Yqb¤YŽ‹AHgĘčôÍääŘěb»ÓŢđ­Űřµă($ůRflšćswh[–Ŕ\`oöYŕ(yUG{8Ţ-ÂŁQëéŘĚĚÇĂĆ™L'édń®Su]5…uŃEńüĎ!Ţ[ţţ“šVőj§5N:é$’zYŤ’,ćÖ2_ Qď9ţ^QgJ^wÝu_űÚ×âá;ÉŠ°¶çńĎĽWi§âŃ/Şdď.4Ţ÷”Xąvę)§Vk1¦u±TÝď}÷{™đuôQŹľm§r1{EÎřŇM_b*r›5›uU‹-˘¶4jŰůŐ/…0„çy{?ŻőkK`A`–ýdߥő‘líqvR¨Ë6F© Č 8٤Ä1…©‚!P˛JRi•‹”ˇXë,ŤŁ Dő ns«bĺ–'šH’ŐŚxŇ’t8=LĎ;1çĹG_çî×@E`NVîä«60ć«Y~¦µóĽ÷›˙ý O8x_€ę¨†ć3ŢJËŰpx‰ ŹâĽ‡š q tđÂţ€Ě ü©:ĎqćYgľýoß~Ë-·óWÇtđA¨Škď^Ë®<ĺvŘayZŁ:Ż}ýÄÇ?Á‚‹×żîő¬ŮY´ç˘xđŽ˙¸EäžşlłHn9GqÄ5×\€‚ßyeěTťé÷sµľç˝ď9áoN`ŞÂëţňuĽÄ‡{]e* Ú?ďaíŻ2žç ox›>ÜqÇ@8ôĐCŮg—7.{챜s%Č卼€Ą}^*Äó3/ff‹Í·ľő­Ľť¤sĐŃ»ÍZ Vy€úřăŹď42óäž{îy '  ­X±YŤŮž†--˛jfĺą+źô¤'ŐQúOjZŐ«ťÖŕsżţ ëů.ťüΓ™ÚđÜ˝źË ‘oëŰčz5gťu RţŐGľú‹7~‘·S’éN<đ°iË‹>äŕ»îĽ ŁJÎĽWm±Gż(Ľdé$ú˙ÚŁ_»˙ţű?đŔßůÎwýĽüĺ/çETŐň´.–Ş•‰6ĽŠĎ˘śÁ‹Ő==ôo†B÷é䎝<ĺÔSNů»S¸Ŕ×­]ÇŃŮ ě·ëvvMZĽxńŇĂz3P X@5săăµSüzęÉ$Éţxťť]•ŔvO€ –s¬ż]apÍă'&dą ‰ÁĂ]$1~úO=űďĎ~ŽĽú—]?N?ýtön¸÷Ţ{SË„ť)Y•SWס/úđĘ•+Ů)–IŐćSvyʲeËx6.OŚ#_s$şö«Uć5t Śd‚É5×^łěÔelQëwxp}÷ďćAzÄF¶XŚ×ß˙ý—_~9ĘBÄ…§=ýi\xÁ+^ń ö7ĺÁřŞ+Żb•¨'ĽÜ„çü‡~]ਣŹŘř´ş]65ç‰'ť¸ç3÷\ąb%ň!M˝đE/dşÄ>‹7Ű‹dŕIŤ^}ŞN^ré%_|ńÇ?öqt"BŠń<ĂwiѢEm­Ź|ä#|{/˙çŤę6Żg>ăŚ3:č ŠˇÁUá™÷ŞšŠ1â%@aŢÁtţůçźsÎ9l'”í9 öĺeqY«žL÷bˇĺßýßďľđ…ŢB*vâęKÇúă:•z¨'¬ršEőőçěsÎľđ‚ ą!긬!BäbZ ,\ <ů°b”˝ŔřÍol9…8±ËX§f'%0±ęRĺꎝŰ%“Uc }p˙Ŧ!ę ¸°G4!YęIlrŁ›Wů9Ĺęč19qvB%é vâŇMđĐ«”IW±©Ř‰S€$ĐO §#ö{Çöä«ĎUDČŢËěĹ›yÎئýئ?M°Ő%ßZţč׿±âŘݰ˘¶¦śđ Ç÷|ßçď›í0Gě j={7pEüö‘߲¤bŻ˝öbrÇŔş¬/¸÷G÷2)z§wb×ĎĹű,řRX®ŻżčĹ4{ĺUW"% ljZNţÎĎĆąí±hŹl?1­ęŁFťY»ví~˙‡ýöŰŹ­LS…°đ‚tR«“ |ß}÷q ¤'Ü˙†4ľĹnóÄV©§žşŮäť! Ž‘Ĺ˘'–„žđřŢ^$Ě&ŘČT'5bőmĆÉ0\Ďz¨"ꡌ )ĚL>‚Ľ¦ěűď×Űő›·|łť)gć˝ęôaôK€Ż K·vÝuW®ľť¦*9âĹRĺ·­ÁRťuß]Ç+śy kٸ'¶m—<şĆ ŔÂş#?‚i}o{ŰŰPŔk“fÝsµ’$ćÇśźn&32LŚ30cŃ*ŔܨGĹÄ"vpSĆ“n”OfŁ”żTŚŘŐZŚ”ěÄü8ŕ!´şF~1â‰Ýę ůII•šiRĹ⏶’ZmkÉíÄ$ €Ŕě«'4ĘuÂŔ°›Ë …$1IçJ=aäMç‡>ô!Vî°őĂ•W^9đ!ĐĎISşŢűž÷˛ ăÓ×zŚęR…;7 ‚NŢ™9M¶;áŃ}ďçíýěg?»=q~śßü¦7łíë7ťE›Ą- H ź?Şď:ů],mCÜ\µj<1sŤ€\ő„ąQO ŃPřyáń†ÖxŚéoSŹ$° đL—ŁÇ(Ťgô‘x°ń´‚Hě<b'YńGoťNŞcW#ü,$‰‡$q~%0âÄHŔOŔ®xŁç‰J’¸ S˝ăIVď`›ćÄá){ŰHŹ™ňOvcłÉ=qľsi ›ďh8î¸ăXÄ΢6#Ľđ Yď=öˇ­( „÷°ą˘·şçMo~“L†`eĘ#żyä€Rf˛X ĹĆ=¬Ťb•Vť/kŁňŽ'Ö•´?ćU@C@K€?•±ÍŇ RČńÇϤ’Ψą¤ý1imĆŤm˛mV[؆ęÂŚÁĄJ ?ÄČ1°ąŘ‰[ %BIĘ´: ĹJCÁN ńT2Nâ6¤ctBé&ĺ§W´0•?Ĺ(€‘29bm´%ÍT˝™á«O#Qą‰r©Ô ڦś{Â<<, G:ąŕ‚ HňÖLÖ~żä%/™yOlA“Iŕę«®^»ní÷˙óűëÖ­cÍůç>˙ąüAo2ilń¬/˝äRćžÔ*ˇ-–ß^ ÜyçťoyË[~˙»ßł1đᇾăN;˛Ňç7ă?ř’Ęe»ŚÍ>¶×s÷Ľ$ Y!Ŕ–Uď[ő>6ść©é„-“2ë$qÍ=!ÉóL»r'“ęť{2+ź‚ŤH`® p”ĆQŤü3Ď<Ƈ8'aSjăż©H"M%IÜ ‘9pFÝ îýŠIĘŁŢbDÍI­˛S Ně$cK C`NÔ“č‹QO٧ ”D.A:©ő;䢞# \vŮeĽ‚ţ˝ŕ/`řÎ{ŘlĚ©(ť̤†8˙Ľóݏâ ʰ›,oĆť•O†ŃÜíŻZuî*^ŇÔžÎ~űď·zőj‡[&Ú@`;¶pf·Ż/˙Ű—™r“˛Ň ·ŚŇM0H2…§ö=áنU<Ä(&<˝D=ilŞ} H`>رQ˙Ř$|”3=ĎSa+—ŕŻ*­ťoÚ©$ęF%cGďhă+Oô‘üĽT ä–n‚]UŞq !°5Ô.ôB¤“ROđ°C!YLg±oĽ‘× p™ é±Y€$  H@óŤ˘ÉŃGÍźľG:ę Ô„ü™{ÝDődľ}öGŁh…’Ř<ôQ=qÚiu“ŘřK4é·S+ţ˛cDé(gI$xĘĆ qb~gZ'v*¶şI9S˛ZÖŔs˘žäÚ@Á¨ˇ›Pę It“Š™–ÂŰIPŠÂ›2đéşY€$  H@ŰŹ(»ě˛ ď‡âŐăĽĎ‹i&H$QOJ*D=á/Ŕ™‚żÔś<şĐg‘›mx:ZŹ@«¤¤…ŇMH&7FI'm•˛1řAH™NO˘q¤vrc$+6?#ýąÎŹL§Vç&%°EłżkěT‡¬Ż5_ëţŔwšŔ=xÉ’%‡z(ÚJŢËĂTW 1L.Ĺ©Ž˘_€$  H`v dđVC8$rY’2‚ť%9 äúxńP—.ÇÝîŮš$0ßô_é%|D!¦Ď±S8žśO|ť3â—¤<Őx â )CŁŤ«®†fB`–Ő“|GÓˇ|ĹąŹâä ŕěi$Ź{÷]’”äŻ`š Y\38 ĆI7clrăo/3ęÖ5VĆLXXW€$  H ĂAQ6C8lٲ„q61N4”šZ‚‡@ÎT©` â„:„Ř% …K ?őŁÁ‰äi®}FĂ®dk´öę@uÜňĐv'‰“ś·†eő¤s¤úânř÷î¸\HíM”$_e<Ü\©Ëć˛ÄÜkŁ•ËĺDŚ“2äĆĆI¨cµv95$  H@€Ć Pă·ÔÍ(›16’ıg ‡3ˇFzäV ›şÄŐě}łŠ$° t~FŇç8yvĂČ\y(PĎtmöd«Í~b8§ň·ŤhK`&ćD=É·b î”Ü5é( !W~„î˛x"ťŚ“'J 1sO ÔjĂLÎÜş€$  H@[$Ŕڱ\Bl¦–dF’Y' ä𳡠ă=ü8±‰k %)*9â¦&{˙n±€\×ýWwĺę\H–Ýýý­ĄJë秦mG[łK`NԺȗŔ÷>ßc´ŹňăĚMgT•öžŠ€Bč&©HSř‰ ´C\ţŮ%bk€$  H@Č(®ŤQ@Hf"I¤lśÄ1Ń•Ťź$ĺ6Âi\ÚŔäČoçË]ŮťÓźĘß)Frô’ýuőH`şfY=É×·bn™„\ÜDé_äŹt”’ ń#Žp»mc˛HgÍu 1ŇÉéžłĺ%  H@€†`F L r‰ŃM°¶‘̬“š{ Ž\BfťÔÜ“ŇVŇĹŞŮbxgĚ•€¶\řu"­]N Ěgł¬ž´§Z×7Wdb„bn™”Ęs7%Ʀq•ˇ$gU$»µ°Ű#jK@€$  Ě ŚÁ 4Č ń[b’QOJpF©8eä÷ZŮ0 ŚMńĚJWmD€$°Ěąz’{dÄl7QTbn·ř‘Hp&ĆŹÁiG7!fÖ Î#‰Ý [‘‡€$  H@“Fu#§Ě8-JGäbÄ‘Äd1ś#ÎÜ“()Ä #D=Iś±«ÁIŁęůJ@ŔÂ%0‡ęI pwÄ ćΊđÁý21·ŐÜ8ŃDȢ  F’Ä”$.ő„ZhĄŞĚQŚ%  H@€f‘@†p4[b†jh"‰IFa\‡ťdÂőT“ ŰÇb'ILĘŇÔ,vŐ¦$  H@[ŔÜŞ'uwäNŮ9™ńGÉÝ´Łž$‹+ť¤şęI‡ŞI H@€$0+ĹĄťĄzD!FÁ‰MŚz•$žH'Ä„KL.şŚYé§ŤH@€¶9QO¸#Vďą5¶Gî  šâ1Y)LŚźŰ-qB `§zâ:ɲ5$  H@€fB ČŃÉ ‘<Čáie†mdefqO2Ů(P!-Ä d’i|&]µ®$  H`«ő¤ż÷ąGć~Yą$#`ŕÄćnŠB’8óMR ä•č&‘KÚ¸ÚÔ€$  H@ É2*#n%ŹAp&”n’d«žl*ŇűwC{ŹţŤmV:i#€$ ­C`NÔnŤô>ęFl’Ü2ŰSÂŹ2R˛IĘG1ˇ$vv<˘žÔ!Úf§rvĘ”€$  H@(5`›ĘÓjĄžP+6qB<Ř”oăT'¦}Ęr 2글$ ůI`NÔ“śjn‡č u_ěÜ2ń'DgIIbîµÄ&N†’Ćqˇ9R Ă3âd÷{h§*ö·©G€$°€ĚůÜ“°(Ł5b×$JFOicʸďwš*Ę•U H@€$ ń0b¤ŚÍR,ŠIü­OĘĐZŚ6žęú%  H@ó“ŔÖž{Rrű¬»/ˇťuR·[üč)m˛‰Ar‰;~“€$  H@Ó%P®ţŠÉŞ9&h=ŘIĆÝß H@ŔB$°mD”ŽVě¨dfť„cśÜw«dżQÄ+«<€$  H@ăč>â)FhÄ„:D;÷$ÎĘ-Ł kH@€m6÷¤Ĺ”* HçÎJ˛uVnżVŇďiŰ×–€$  H@ť@ şRĄ“Śł´’¶YJ,Ü–Ń–€$  ,DŹÎěض˝oĺŹÖNŻđô;+kŰöÜŁK@€$ í’ŔT:HümîTöv‰Ĺ“’€$ É$0/枌‚ľ˝+Wy$•ţ* ! H@€$0!C¬!YcČ*€$ A`ľĚ=Y°ě¤$  H@€$  H@H`‡ UUUđů|ąűř|>TUUˇ˘˘ ččč@MM mţ\!„¶PVV‰D‚šš”——aD"444Čm'{¬)---()ÉJëęę‚ÇăASSjjjĐÖÖ†¦¦&”••ŰüąBZ5Č„tpĺĺĺČÍÍE~~>Š‹‹QRR‚’’”––˛ËnŐŐŐ¨©©Aeee»fÔÖÖ†şş:455ˇŻŻą›ě>###ššÂÂÂ:::íš‘BH×$•JQXXśś6«“ĹĹĹěÇUUUrMq{QTT„¶¶6444 ©©ůÜ©ŻŻ###››ĂÜÜŞŞŞí–‘ňŹ®bMw••…ŚŚ ˛łłĺf|•””š5 M?×ĐĐ€şş:tttŔç󡦦]]]vöWII ZZZrZš-niVY6˘.›….//‡D"X,FEEjjjP]]-×°?ŰÄ766˛ßŹĎçŁgĎž033ąą9,,,`ii [[[ŘÚÚÂŇҲŮČ>|ČůÇŹłEÝĐĐ–––lłŘ´ ZXXŔÔÔzzz?“7SVV†ĽĽ<ą›üü|vP@(˘¤¤ ¬¬ +++ŘÚÚÂÚÚöööpttÄ€`hhČń3!„Ňš¤R)222””¶N¦ĄĄˇ     sssąÁUKKKšš˛őłGŹÍ};“††łuR("//OnP 33‰ŔÓ\666°±±­­-úôéggg8::6kň !/‡dBZQCCîßżŹ»wď")) IIIHLLDaa!ŔÔÔöööěČŻ¬ůłµµ…®®.Çé;†ňňr[[[öăŢ˝{CEE…ëřśc999r52==éééxřđ!ŞŞŞ ¨¨[[[ôďßÎÎÎpvv†««+,--ąŽOH‡G 2!o 77±±±ŹŹGuu5455áččČ&''' 0úúú\GîÔJJJpďŢ=$''ł)))¨ŞŞ‚†† wwwxxxŔÍÍ ććć\G&„n­±±)))‰‰A\\RRR •JajjĘvĘjĄŁŁ#ťwű†AFF;H/«•Ź=Bcc#ĚĚĚŘ:éîîŽÁÓĹ6 y5Č„Ľ‚ĽĽ<\ąr¸ví„B!”••1`ŔąĆĚÎÎ<Źë¸Ý‚T*ĹŁGŹä*Q__Źž={bäČ‘=z4|}}ajjĘu\Bé҆Á˝{÷+W®ŕÖ­[‰DĐŃŃa›2777¸ąąÁČČë¸Ý†D"ÁÝ»w!‡<~üŠŠŠ0`|}}1zôhx{{wę%ę„´j y±XŚ¶Đ§¤¤@SSÇÇČ‘#áéé‰B]]ťë¨¤‰ššÜąs111ŚŚÄőë×QUU…~ýú±ľľľt@!­@(ââĹ‹¸rĺ ®^˝ŠââbôěŮľľľ6lÜÜÜŕŕŕ@ÇLaa!˘ŁŁqĺĘÜąsĘĘĘđňňÂčŃŁáçç‡ÁÓ˙év¨A&äeee8{ö,ÂÂÂŽşş:xxx°Ť•‡‡ťëÚÉÔ××C °±±±PQQźź‚‚‚0a„N4BiO<@hh(ÂÂÂpűömčééaÄl­´··ç:"yEĄĄĄ¸ví»R.-- >NNNXąr%ćÎťKo-BéVňňňđÝwßáŔ‰D4i‚1věX(((pŹp(55?˙ü3~ůĺ”””`üřńX»v-ĽĽĽ¸ŽFH« ™tŐŐŐŘłgľűî;cŢĽyX¶l Äu4ŇĹÇÇc÷îÝ8|ř0ŚŤŤ±jŐ*,Y˛„VBş´ôôtl۶ ‡‚ˇˇ!V®\‰yóćÁŘŘëh¤©ŻŻÇéÓ§ńĂ?ŕćÍ›>|86lŘ???®ŁňF¨A&]^CCvî܉-[¶ ¦¦ďĽó>üđCzŹ\ňRrrrđí·ßâçźźĎǦM›đî»ďŇąv„.Ą°°ëׯǑ#GĐ«W/¬]»óçϧŐ3äĄÜ¸q[·nĹĹ‹1dČ|˙ý÷4ŁL:-Z#Cş´ččh 2«WŻĆâĹ‹‘••…ożý–šcňŇ,,,°cÇdff"88«V­‚››bbb¸ŽF!o¬ˇˇ˙ůĎŕŕŕ€+W®ŕŕÁxđŕ–,YBÍ1yiÆ Ă… pűömčęęÂŰŰ .Dqq1×ŃyeÔ “.I"‘`éŇĄđöö†‘‘’’’°uëVpŤtRFFFřúëŻqďŢ=`čСx÷Ýw!‘H¸ŽF!Ż%55nnnXµj–-[†””Ěž=ŠŠŠ\G#ť”««+ÂĂĂqôčQ\ľ|ööö á:!Ż„dŇĺ<~ü^^^ ĹŃŁGNďÇHZŤ._ľŚß~ű ÇŹ‡··7˛˛˛¸ŽE!Ż$,, îîîPWWÇ˝{÷°uëVhhhp‹tÓ§OÇ_ý…ŕŕ`Ěť;ďż˙>ęë빎EČKˇ™t)ׯ_ÇŕÁ·oßĆôéÓ9NDşŞ™3gâĎ?˙Dcc#ڍ¨(®#BČKŮĽy3¦NťŠyóć!22\G"]¦¦&ľűî;ś8qŔčŃŁQZZĘu,Bţ5Ȥ˸~ý:€ččhXYYq‰tq˝{÷Ć­[·ŕç燱cÇâćÍ›\G"„Z·nľţúk}šŽŐH‡E3ȤKXĽx1\\\°{÷î6˙{ăĆ Lž<<***:t(ÜÝÝaee___ś={¶Ő÷Y\\ŚC‡aćĚ™3gNłÇ˝˝˝áííÝęűíhŽ?ŽéÓ§ł?űŤ7âöíŰrŰTWW㫯ľÂ‚ Ú-ŹÇĂž={Đż,Y˛¤ÝöK!/K(bĹŠřţűďŰĽ9¦:Éťż«“ŤŤŤřěłĎ0oŢ<¬[·S¦LÁůóçŰ%›™™Îź?Ź7n`ßľ}í˛OB^ CH'wüřqFGG‡)((h·}VTT0±cDz÷ŐŐŐ1›6mb0{öěiŐý•””07nÜ`0ăÇŹoö¸——3tčĐVÝgGUYYÉ`†Ţě± .0‹-zîĎ©­ĺĺĺ1ÚÚÚLhhh»ď›B^dćĚ™ĚĉŰmT'ąó˘:ątéR&00‘JĄ Ă0Ě“'OsssćŇĄKí–ďСCŚSVVÖnű$äUĐkŇéąşşbÔ¨Qřć›oÚuż<ăÇŹÇąsçäî·łłT*Ezzz»íł»yŃϡ±±JJJśýśVŻ^Ť›7oŇű$B:ŚôôtŘŰŰ#66C† i·ýRťäNK?‡»wďbĐ Apsscď˙ôÓO‚´Ë˛g©T ;;;Ľűî»XµjU›ďŹWEK¬I§–••…;wî`Ú´i\GaőęŐ 999\Ç趸~˙Π  ÄĆĆB(ršBdBCCaiiŮ®Íń‹PťäĆľ}ű ĄĄŐě÷`Ô¨QHKKCddd»äPPPŔäÉ“qňäÉvŮ!ŻŠdŇ©%$$\\\8Nň”D"ARRúőë×ě± ((S¦L““~řáąÇĄR)6nÜO>ů+V¬Ŕ!Cř·űĚĘʶmŰZÜgmm-ţńŹ`ٲepvvŹÇ™™Ľ˝˝‘ššŠ'N`öěŮ3gRRR0zôhhhh`âĉ¨®®~î>“’’đÁ`۶mpssęëëqńâE,\¸sçÎEDD UUU <=J*•"** ďĽóćÍ›‡Ű·oĂÇÇjjjđ÷÷‡X,FDD55µNwĹËAîÜąĂqByęŢ˝{T'©N"** ¶¶¶Íf‰mmm×®]űŰďŃZ\\\p÷îÝvŰ!Ż„ë5Ţ„Ľ‰FEE…“}ŁÉyNR©”ILLdüüü---&22RnŰüü|ĆŘŘąrĺ Ă0 “””Äđx<ąs°¶oßÎ 8ýÜÝÝť2dČs÷É0OĎ犌Śdlll–^Î+V¬`†a¬¬,†Çă±ű¨®®fŽ;Ć`lllŤ72ŃŃŃĚűďżĎ`¶mŰöÜçŢżćÉ“' Ă0ŚX,fĆŤÇD"ćĘ•+ ĆĚĚŚůî»ďÄÄDćÇdÔÔÔ===&??ź)..f:Ä`zőęĹěŢ˝›©¨¨`ľüňKŔlßľť)//gvěŘÁ`ľüňËţžőwŹ·5&$$„łýBHSĚŰożÝîűĄ:ٱꤦ¦&ăëëŰ,kMM  ]GNť:Ĺ`$I»í“—E 2éÔ"""ljO}}}ĆÍÍŤQSSc/ľř‚ÉĎĎo¶í{ď˝Ç888ČÝ×§O¶(3 Ălٲ…7nűůřńăUUŐfűl©ń h±đëčč0~~~ěçŽŽŽŚ˛˛2űąT*eČmSRRÂ`¦OźţÜ箢˘Âś8q‚ýĽéĹ=0ţţţrŰË ř_|!·]Ó‹·7űZ‘HÄ`fÍš%÷ý:r,{˛|řđ6ŰwS›6m€Ř.ű#äUQL:=¬^˝o˝ő§o÷Ţ{ąąąX˛d‰Üc#GŽDaa!>,w˙Ž;PRRřţűďŃ·o_v汥ePŻęňĺË¨ŻŻÇéÓ§ńůçźcúôéŻý˝JKKŮĺy»víĚ›7.\\Ľxńą_{óćM(((`öěŮŻ˝˙Ž.;;ożý6Ö¬YÓnŁđ„ň˛>üđChhh 88¸UęËë :Émť\´hJJJš]ů[ ŔĆĆ>>>m¶o™Ă‡c˙ţýŘąsg»Ľç2!ŻdŇ%|üńÇčŰ·/FŤ…ĽĽĽ6ßźl¤÷Ů‘říŰ·ĂŮ١ˇˇŘ˝{7{˙†  ˘˘‚Ĺ‹ă˝÷ŢĂîÝ»1gÎOßx:J.píÚ5ś>}Ź=đôśÖŚŚ 444hy•¬ ?{~ŮüůóńÇ`íÚµřôÓOńÝwßáŇĄKě÷hé{ĘÎç’=&ăââ‚•+WöîÝËžłdccŕéyf2 (++cF›6mš5kЧO˙;¨izpSSSŕé[€Č´´ťH$vFáY˛ÜĎÎB´%ˇPŃŁGĂŮŮ›7on·ýBČËRVVĆńăÇqĺĘ,]ş´ÍO]ˇ:Ůń꤫«+–/_ŽO?ý”­‘µµµřůçźńď˙ mŰ„……aÉ’%řć›o0pŕŔ6Ý!o„»ëŇşĘËËWWWĆÜÜś‰ŤŤmłýܸq™:u*€QTTdţőŻ1 ěă÷ďßgÔŐŐeeefíÚµLMM Ă0 sáÂĆÉɉQQQalmm™˝{÷Ę}ßýű÷3ZZZŚsńâEfßľ} źĎgüüüŘŘXć>`0zzzĚáljDÂD"fďŢ˝Ś¶¶6€Y·n“““Ă~ĎÍ›73ŞŞŞ ąŰś9sŞŞ*fíÚµ ĆŔŔ€9zô(#‰?üŔččč0gÎśaż—»»;óé§ź2 óôęîîîĚçźÎL™2…ů裏ĆĆFąÇ-ZÄĚ1qwwg¶nÝĘHĄR†až^…ó“O>a0†††ĚŮłg™ňňrfÆ FCC9qâS^^În§««Ë„„„0ÇŹg‚‚‚ڞ˛2ł~ýz&>>žÍxëÖ-ö92GŽaŇÓÓ[ů7@^tt4cnnÎ 2„)//oÓ}BČ›şqăĂç󙀀¦¬¬¬ÍöAu˛cÖÉĆĆF櫯ľbfÎśÉ|řá‡Ěś9słg϶ňo€<©TĘ|óÍ7Ś˘˘"łaÆ6Ý!­Ç0í8ÍBH«¨¨ŔÜąsŽü‹-â:g°iÓ&˛ŁÖ ‰‰żż˙ Żľů&x<ĆŹŹsçεÉ÷ďHöěŮ+VŔßßGŽ‘»Ú*!„tTńńń ‚ŠŠ BCCáěěĚu$NPťl{UUUXĽx1BCC±}űv¬X±‚ëH„ü-ZbMşś>}ëׯÇŇĄK1uęTą·očN¦M›†ččhą%]JJJ033k•+vgŮŮŮ »ヒŹ>ú§Nť˘ćŇi¸şşâöí۰´´„§§'¶nÝĘÉ[@qŤędŰşté „ČČHDDDPsL: jI—ĂăńđńÇăŇĄKHLL„ŁŁ#ľúę«nWüŹýű÷#-- ŮŮŮ Ĺś9säÎűjM˛ó­d˙v5uuuřňË/Ń·o_$''#<<›6m˘ ŤB:###„‡‡cÆ زe ú÷ďŹË—/s«]QťlŮŮŮ:u*ĆŽ gggÜąsÆ ă:!/Źë5Ţ„´ĄÚÚZfË–-Śşş:ckkËěßżź©««ă:V»HMMeĆŹĎhii1ĘĘĘLßľ}™őë×3m˛żěělöü/MMMf۶mĚăÇŹŰd_í­¶¶–Ů·occcĂđů|ć‹/ľ`jkkąŽE!­"++‹™2e €™0aĂu¤vAu˛uĺĺĺ1«V­bř|>cggÇ\Ľx‘ëH„Ľ:™t ŮŮŮřä“O¬^˝‹-‚şş:×ŃH&‹±oß>lßľ;w.6oŢŚž={rŤBZÝĄK—đé§ź"&&#GŽÄ† ŕëëËu,ŇÁeffâ›oľÁ §§‡Ő«Wă˝÷ŢŠŠ ×Ńy-Ô “n%;;Ű·oÇľ}ű ©©‰ŕŕ`,X°\G#Hjj*<ýű÷Łşş‹/ĆęŐ«aaaÁu4Bis‘‘‘řňË/qůňe 4K—.ŬYł ŁŁĂu4ŇAHĄR\şt @XX,--±fÍCUU•ëx„ĽjI·TTT„ź~ú ŔăÇŹáăăŕŕ`Ěś9“f•»©ęęj?~ű÷ďGTTlll°`Á,]şĆĆĆ\Ç#„v÷çźbçÎť8qâ1cĆ ,\¸>>>tí…n*++ űöíáC‡  1bÄ,]şÓ¦M’’×ńiÔ “nM*•âęŐ«Ř·o ˘˘‚±cÇbęÔ©€––×Iެ¬ÄůóçŠóçĎŁˇˇÓ¦MĂ‚ 0jÔ(((Đu !D$á·ß~ĂÁ+++L™2S¦LÁСCéoe—‘‘“'OâÔ©SŤŤ…‰‰ ‚ ®ăŇę¨A&ä˙•––âÔ©S EDDŔ××S¦LÁرcannÎqBŇrssqáÂś:u ŕńx=z4¦NťŠI“&A__źë„ŇaÝżˇˇˇ ĂÝ»wŃŁGLš4 “'OưaĂ ˇˇÁuDň†¤R)pîÜ9„††âŢ˝{011Á¤I“„ŃŁGCQQ‘ë„´j iH$ÂůóçqňäI\şt •••čŰ·/FŤ___Ś1şşş\Ç$/ˇ¬¬ ‘‘‘¸rĺ ®\ą‚ÔÔThkkcěر ˘•„ňš222ŘĺŘŘX(**ÂÓÓ“­•nnn´ě¶“HKKĂŐ«Wk×®ˇ¤¤˝{÷fW xyyŃJŇmPLČßhhh€@ `¬ŘŘX466ÂĹĹžžžpww‡»»;ěě츎J<|řqqq‰‰ABB‚ÜAŰčŃŁáîîNm„ŇŠšFFDDŕÁĐŇŇÂСCáććwwwxxxĐ*ť ¶¶wďŢ…@ €@ ŔÍ›7! ahh‘#GbôčŃđőőĄĺӤۢ™WT]]Ť¨¨(\˝z±±±¸s窫«ahhwww¸ąąÁĹĹÎÎΰ˛˛˘ ™´†a™™‰¤¤$Ü»wŹ-ô%%%ĐĐĐ€««+<==1bÄřřřв?BiGąąąŔŤ7 đ×_A*•ÂŢŢž­•ÎÎÎpvv¦¦ą ŐÖÖ"%%ÉÉÉŹŹGll,P[[ SSSxxxŔËË ŁFŤ‚‹‹ Íj yc HJJBLL ;sůđáCHĄRhiiÁŃŃýű÷‡łł3aooOç3ż†a››‹´´4$''#)) III¸˙>D"ЧOv†ÂÓÓNNN4CL!Hee%[#âââPXX077‡““ú÷ď'''ôë×¶¶¶t*Ó+¨««Cff&ţúë/ąZ™––†††đů|¸¸¸ŔĂĂpwwGĎž=ąŽMH‡D 2!m@,#%%÷îÝĂýű÷‘””„ÄÄDÔŐŐacc[[[ą›……,--Áçó9~íK,C("''Ź=jv“H$€=z°3˛[ż~ýşÝĎ‹Bş‚˘˘"$&&")) ÉÉÉHLLDJJ Äb1ŔĐĐ­Źvvv°±±Aď޽ѳgOt»˘d· IDATĐââbäçç###C®F¦§§C(˘±±ŠŠŠ°±±aśśś0`ŔX[[Óě0!/‰dBÚQqq1ŇŇŇ––Ć6Yˇ+--e·ÓŐŐ…ąą9ttt`ooKKKŔČČr·ŽúľÍ555())aoĹĹĹxňä ! ńđáCTTT ''ě×éëëË X[[ĂÎÎööö044äđBikR©™™™lă—žžŽGŹ!-- ¨­­((( GŹlm´··‡‰‰ LMM›ŐI{Ő劊 ٤¤ĄĄĄ())Á“'O  ‘źźŹÔÔTTTT //Ź,VPP€ĄĄ%¬­­› ´ŰŮŮuŘăB: j é JKKŮYÔÜÜ\ś;wüń €úúzâÉ“'xö%Ëçóĺše ččč@MM ĐÖÖfď—mŻŞŞĘ~=ŹÇk¶Ś­ĽĽ\n?µµµě~uu5jjjPYY‰ęęjH$TTT şşb±-ň˛í›îÇĐĐ=zô€©©)®_ż[[[,[¶ ÖÖÖěě9ť‹F!¤%R©ąąąlóřçźb÷îÝĐŃŃ••ňňňPPP€ŞŞŞf_«ŁŁ###ččč@SSjjjĐÖÖnö±˛˛2€§ŐMŻ!˘ŞŞ*·Z©ˇˇ"‘Hn"‘ ž^´L"‘ ¦¦Fîăňňr¶V–””°Ű7ÝŹˇˇ!,,,`dd„đđp888`ĹŠ°¶¶†™™¬¬¬äę8!¤uQLHÓŘŘőë×cűöíŘĽy3>ţřc¶H3 #7+ŰtÄą¤¤b±b±ĺĺĺH$‹Ĺ¨¨¨@MM ۰6-ŕ@ËE^KKKnéš’’űVH|>ęęęĐŃџχšštuuÁçóĺšuŮM__źý¸éÁĆőëׄ޽{ăôéÓt^6!„—vţüyĚš5  @XXÜ ŁÚÚÚfőńÉ“'xňä *++!‰ ‘H ‰š}ÜĐĐ©T*·˛ xz*löhypąé´®®.ÔÔÔŔçóĺ>ÖŃц††\}444„ˇˇ!  ©©)÷=Ż]»†éÓ§ĂĘĘ §Nť‚……Ek˙( !Ď ™¤ŞŞ ożý6._ľŚ`Ö¬Y\GjSééé0a*++qć̸şşr‰BH·cǬ^˝sçÎĹîÝ»»üljzz:QVV†°°0¸»»s‰.ŤÎÖ'¤ČÉÉŹŹ®^˝Úĺ›c°±±ALL śśśŕăă'Np‰BHU__Ź%K–`ŐŞUřňË/qŕŔ.ß˙«• Â#Âu$Bş4ĹO>ůä®CŇÝĹÇÇcôčŃPQQÁŐ«WáěěĚu¤v٦¦†·Ţz EEEXłf 0lŘ0z˙hB!¬ŇŇRLś8ááá8vě.\Ču¤vĄŞŞŠ™3g˘˛˛«W݆D"Á¨QٍVŇh‰5! ĂÜąs1tčP;v :::\GâĚ®]»°bĹ Lź>ű÷šב!„p,55'ND]]Îś9p‰S‡Â;$„„4;o™ňfh‰5!úúëŻ1mÚ4Ěź?üńG·nŽŕÝwßĹůóçqńâEŚ1\G"„¡đđpxzzÂČČ Ű7Ç0ţ|\˝z^^^ČĚĚä:!] 5Č„p ®®ÁÁÁř裏đĂ?ŕÇ”»jtw6fĚDGGŁ´´nnnHHHŕ:!„üřăŹ?~<pőęUp©ĂđňňB\\áî¨(®#ŇePLH;+--…źźNž<‰łgĎâź˙ü'ב:ÄĆĆÂÎÎ>>>8uęב!„´“††Ľ÷Ţ{Xľ|9>ůäüňË/tĘM zö쉛7oÂÇÇľľľŘ»w/בéč"]„´Ł´´4Ś5 Ož<Á•+W0tčP®#uXęęęxűí·! ±nÝ:¨©©ÁŰŰ›ëX„BÚPYY‚‚‚pöěY„„„`ٲet!ŞPQQÁŚ3P__ŹŐ«W٬¬ cĆŚ‚Íňşč"]„´“ëׯ#((¶¶¶8}ú4-{ß˙=V­Z…ŮłgcĎž=Ýâm=!¤»IKKC`` D"Nź> WWW®#u*GŹEpp0† †ß˙şşş\G"¤S˘á%BÚÁľ}űŕçç???DFFRsüŠV®\‰łgĎâÔ©SđőőEQQב!„´˘k×®ÁĂĂ‹‹Łćř5Ěś9QQQHNN†‡‡ŇŇҸŽDH§D 2!mH*•bÍš5X˛d Ö®]‹_ýęęę\Çę”ĆŤ‡ččhäććÂĂĂÉÉÉ\G"„Ň ~ţůgřűűcÔ¨QŠŠ‚™™ב:-WWWÄĹĹAWWîîî¸|ů2בét¨A&¤ŤTWWcÚ´iř÷ż˙ŤĂ‡ăłĎ>Łó¨ŢŁŁ#âââ`nn///ś?žëH„B^Scc#>üđCĽóÎ;X·nŽ;FČ­ŔĚĚ ‘‘‘7nđß˙ţ—ëH„t*t‘.BÚ@^^üýý‘óçĎc„ \Gę2ř|>ćĚ™ôôt¬_żZZZđôôä:!„W ‰„ăÇŹăČ‘#Xľ|9 "·"%%%AYYkÖ¬A^^ĆŽ EEE®ŁŇáŃEşie 8q"455qîÜ9ŘŘŘp©Ëúć›o°nÝ:,\¸;w˛2ב!„üŤĚĚLLś8%%%8uęÜÝÝąŽÔĄť>}sćĚÁŕÁqüřqr‰Ť–XŇŠÂÂÂŕăă~ýú!66–šă6¶zőj„……á÷ßÇ1cPZZĘu$B!/póćM¸ąąAYYqqqÔ·I“&!::Ź?†‡‡îßżĎu$B:4j i%ß|ó ¦M›†9sćŕŹ?ţ€ŽŽבş…ŔŔ@ÜĽy™™™pssCjj*ב!„´ŕŕÁđőő…··7˘˘˘`iiÉu¤nĂŮŮqqq055…§§'Îť;Çu$B:,j yCőőőX˛d ÖŻ_ŹíŰ·c×®]PRRâ:V·2`ŔĂÓÓááá\G"„ň˙¤R)Ö®]‹ŕŕ`|đÁ8yň$455ąŽŐíáĘ•+1c&OžŚm۶q‰‰ÎA&ä ”••aúôéřő×_1qâD®#uk‰‹/ĆŃŁGńý÷ßă˝÷Ţă:!„tkUUU3g.^Ľ={ö`ŢĽy\G"ľ˙ţ{¬Zµ łgĎĆž={ ŞŞĘu$B: šć"ä5Ą§§c„ ¨ŞŞBTT\\\¸ŽÔí©©©áČ‘#čŰ·/–/_Ž””üđĂ4ŁO!ČÎÎF`` ňóóooo®#‘˙·rĺJôíŰ3gÎDZZBCCabbÂu,B:ZbMČk¸~ý:ÜÜÜ ­­Ť?˙ü“šă„Çăᣏ>±cÇpčĐ! ¬¬ŚëX„Ň­ÄÄÄŔÝÝŤŤŤŤŤĄć¸ň÷÷Gll,ž>nnn¨®®F\\ŐÉ.`ÄH$pssCll,בiWÔ ňgĎž…ŹŹúôéččhŘŘŘp‰´‚Yłf!22wďŢ…——233ąŽD!ťŇ‰'ŕăă'''ÄÄÄPťěBlllŤAaäČ‘ á:!í†dBZ°cÇL™2łfÍÂ…  §§Çu$ŇŠÜÝÝeee¸ąąáćÍ›\G"„Nalٲ3fĚŔ˘E‹đÇ@WW—ëX¤•ikkăôéÓXľ|9ćĚ™őë×C*•r‹6Gç ŇDCC–/_Ž={ö૯ľÂęŐ«ąŽDÚPUUćÍ›‡óçĎc÷îÝtń5Bů‰ .ÄńăÇńď˙ďľű.בH;8|ř0–.] üňË/turŇĄQLČ˙+++ìYłŤ#GŽ`ňäÉ\G"í@*•⣏>ÂW_}…5kÖ`ëÖ­PP Ĺ5„ň¬‚‚Lž<>ÄŃŁG1fĚ®#‘vŤ   ăôéÓôţ֤ˢ™ééé0aŞŞŞpöěY¸¸¸p‰´ł¦Łă!!!ĐÔÔä:!„t  „ššÎś9®#…B"''ˇˇˇđńńá:!­Ž¦IH·wóćMxxx@CC€šănjŢĽy@ll,Ľ˝˝‘ťťÍu$BéNť:ŘÚÚ"66–šănĚŇŇ7oŢÄđáĂáë닟ţ™ëH„´:jI·öË/żŔ××>>>¸~ý:ĚĚ̸ŽD8äííŤŘŘX466ÂÝÝ111\G"„N}ýő×:u*Ţ~űm\şt úúú\G"ÓĐĐŔńăDZvíZĽóÎ;Xąr%ąŽEH«ˇ™tK Ă`óćÍ7oV¬X'N@CCëX¤čÝ»7˘ŁŁáęęŠQŁFá×_ĺ:!„´»ÚÚZ,X°}ôľýö[üôÓOPVVć:é x<>űě3üţűďŘłgP^^Îu,BZťLşťšš#,, »víÂÂ… ąŽD: ĆĆF¬Ył;věŔ† °eËđx<®cBH›+**ÂÔ©S‘ß˙ăĆŤă:éŔâăă1yňdhhhŕĚ™3°··ç:!o„fI·RPP€#Fŕňĺ˧ć<—˘˘"ľýö[ěŮł۶mĂŚ3P]]Ýâ¶ Ă >>ľťBHëKNN†‡‡rssMÍ1ů[®®®ĐŐŐ…‡‡._ľüÜm?~ŚĘĘĘvLGȫٙt)7nÜxîcIIIpwwGYYbcc1|řđvLF:«Ĺ‹ăňĺ˸ző*†ŽÜÜÜfŰĽ˙ţűőőőřÇ?ţýű÷㫯ľÂęŐ«9NJş‚Ó§OcÎś9puuʼn'đí·ßb۶mJĄPVVĆŕÁqëÖ-ş¶é¨A&]®]»đĎţR©JJJ000@ll,¶mۆź~ú [·nĹš5k¸ŽIş€††|đÁ8|ř0x<ŞŞŞŘ·· ˘Oé¨&L€đđpÔ××CII AAAŘąs'¦NťŠřřx„„„ 00ë¤ IJJ¤I“P]]Ť˘˘"ąÇx<:„ąsçr”ŽçŁ™tz%%%°¶¶–»č˛˛2455QWW‡#GŽ`Ę”)&$]ŤH$ A••Ĺ.“áńxřĺ—_đöŰos”ŽBäýńÇ0a‚Ü} 000€şş:Îś9C+_H›¸téĆŹßě}’y<ôőőńčŃ#čęęr”Ž–Ń9ȤÓ۸q#jjjäî«ŻŻ‡H$ÂŔiDś´*ŮyTŹ?nÖˬ\ą’®ŇIéjkkńĎţŠŠŠr÷KĄRcýúőÔ“6‘““Ůłg·řĂ0¨¨¨Ŕ¦M›Ú9!ŹdŇ©%$$`Ďž=-6* ŽŽĆĆŤ9HFşŞőë×ăÂ… ěyÇĎbĺĺĺřěłĎÚ9!„4·}űv…Âf3xŔÓYĽ•+WB pŚteb±¨¬¬lńwxzś¶sçN$$$´s:B^Ś–X“N‹axyy!>>ţą3y2?˙ü3/^ÜNÉHWµ˙~,Z´čĄ¶UTTDrr2Ú8!„´,;;ööö¨­­}î6ŠŠŠ000@||<,,,Ú1骆Á´iÓú·Ű*))aŕŔtíŇaĐ 2é´~űí7‚żmŽ`É’%¸zőj;¤"]™››–.] ===đx<())=w[,]ş´ÓBĽ>řR©ô…Ű466˘¨¨C‡…X,n§d¤+«««żż?úöí ŹeeĺçnŰĐЀ۷oăŕÁíżA3ȤSŞŞŞ‚ŤŤ Š‹‹ńĽ_aeeeÔ××ĂŮŮË–-ĂěŮłˇŁŁÓÎIIWT__ŹóçĎcďŢ˝¸páx<[ü]|MMMŽ“Bş‹úúzôíŰŹ?nvţ§ěoTĎž=±xńbĚź?={öä()é.†ATTöďߏ'N ¦¦†\žţ^.Z´»víâ8)!Ô “çhhh€H$Bee%Äb1Äb1ęëëQUU%·ťH$jÖ¤ęčč@Aá«÷UUUÁçóŮ·^ŇŃŃźĎíQę´´48::ĘŤ@*))A*•bĚ1X´h&Mš•×úţ„Ľ®řřxNyެ¬Ś­Ź•••Í^ł ‘Hš˝Ë‚şş:ÔÔÔäî“˝Ćttt ®®>ź˙FŻ»íŰ·cÝşuló!«ÉŞŞŞ1c.\:ç“p˘¦¦ˇˇˇŘ·o®_żöXňĎ?˙ÄŕÁ_řőĺĺĺ`b±µµµě1«Ě‹. &«±ĎÓ´öµ¤é1®ěřVAA]ˇ¨ĄĄőÂÓŻHç@ r7 ‘H  ‘——‡üü|”””ŕÉ“'xňä JJJPTT„ââbD"”——żđ@Ľ5ńx<čęęBCCZZZ044„ŚŚŚ`ddCCCöfnnŽž={BWW^^^‰‰‘_¶lćĎź33ł6ĎMş·úúz”––˘¬¬ ĄĄĄ¨¬¬„H$BEEŞ««!‹QZZФ¤$$%%!//0pŕ@466˛Ť°¬ˇ-++ăňéĽMMM(++ł ·ěŕ@OOĐĐĐ`ÁdźkkkC[[|>ÚÚÚĐ××go|>źë§Djkk‘““ÜÜ\˘¸¸­“˛‹‹‹Q^^ŽŠŠ ĹâfMo[‘ &ëčč@WWW®6ŔĐĐFFF066†ąą9,,,đäÉöb[˛%ÔžžžX˛d ¦M›F«YH»‰DÍęĄX,FUUĘËË!‹QTT„řřx¤¤¤°uŃŐŐ•m~ź×wtĎ6ϲc^MMMđů|hjjBWW|>|>:::ĐŇҟχ††ôôô ­­ ===čëëCOOOnň‰´-j»€ÚÚZÄŁGŹ  ‘••…śśäää ¨¨ÝVAAˇĹâjdd---čéé±/VmmmąkÓ2Ůl“LK#č˛?n˛Q;ŮE±XŚŠŠ TUUA$Éł'‰„ý^jjjěçvvvđööĆČ‘#ѧOŘŮŮŃLy% (..FQQňňňŘŹKKKQZZŠ’’ąâ^ZZúÜ­­­Í6…:::ĐÔÔd_7EEEhhhŔ¸qă ĄĄEEEhkkřßhôßÍÜľĘ,đł^eöYÖŔËLšľ¦e+FdłbµµµěkşŞŞ ŐŐŐě粏e+QZÍWSSc‹żěÖôs###ŔČȦ¦¦čŃŁťI^Ymm-ŇŇŇ––†ôôt…Bdggł5˛  @nűgk¤lŕVvŔ*«‘ĎÜO˙4}żá–fŁdŻ1™ĆĆFö}ÓËËËQSS±XĚľŽjjjPYY‰˛˛2ąÚŘôߦTTTPWW¸¸¸`Ô¨Qpww‡ťťlmmĺj6!/«ĽĽ(**Baa! غشN6ý·Ą‹¨*))AKK‹]MŘ´fÖÔÔ ''¶¶¶8p ÔÔÔ ¦¦uuuąş){ťµôĐň* YŁú<˛cÖ–4}­OgÂ%‰Üý˛z÷ěcR©‰D‹ĹrµR¶ ĄéŞÍ–čęę¶X+őôôŘżS=zô€‰‰ ŚŤŤaddÔěýĎÉˡ੬¬Dbb"’’’p˙ţ}¶ŕgeeA*•BAA–––°´´DĎž=aaaž={˘gĎž°´´„™™ŚŚŚ:Ý’ŞŞŞ*…Bdffâ‹/ľ`˙ B("##mš aooĎ6Ěýű÷‡‹‹ ĚÍÍ9~¤=544 ??YYYČÎÎF^^۰EţŮ‹Ľ©««ĂČČrE§Ą‚$»iiiÉća¦Ó˝ţZ‹D"Aeeeł©ç}^ZZĘÎÚ5ĄĄĄĹţ-ëŃŁLMMadd XZZÂÂÂVVVÔHwCĺĺĺHHH@bb"RSSŮcˇPřÜiaa^˝zÁÂÂfff066îtł4R©EEEČÉÉAdd$Ž;†Ţ˝{CQQQn0@ö3čŮł'ěěě`gg‡ľ}űÂÉÉ .../lH×UPPŔeee±ÍoQQŠŠŠźźŹââbą¦QAA­•Mg8ź­•Ďާ­­M§ż˝ŮŔ´¬fľ¨^6ý¸¨¨Hî˙‰Ç㱍˛‰‰ zôčcccŔĚĚ ˝ző‚ĄĄ%ĚÍÍ_xĄńî䪴´111HHH@BBîŢ˝‹ŚŚ 0 CCCôë×vvv°··g˙í®#ĂR©Bˇ>DZZ>|ČŢ233!•Jadd 8...puu…˝˝=×ŃÉk‹Ĺxôč?~ڬ¬,…Bö–••…üü|vĆREE¦¦¦055…±±±\S%›•422‚™™´´´8~fäYµµµěAšlć˘éDząśśą™pCCCvPÖÉ mmmallĚáł"o*77qqqHHHŔ˝{÷ĚĚL€©©);H*»ŮŰŰĂĆƦË×Čç ÂÉVšÉj¤lđ 55………€Ţ˝{ĂĹĹýű÷Ç€ŕććFËť\mm-222‘‘Á6ÁŮŮŮr« e •좒ĆĆĆě ¤±±1[;eËVŇĚdÇTQQÁj °°P®^#??yyyěĘ248´´´DŻ^˝`kkŰíШAî >|ččhDEE!&&©©©kkk¶©“ݨ`˝ĽŞŞ*$&&Ę 4$''C"‘ŔŘŘC‡ĹСCáéé‰!C†ĐZRUU…GʵxËÍÍe·311ag›®}nbbŇéf„Čë)//Gvv6˛łłĺfΚ®$-ůÓÖÖ†­­mł›ťťLLL8~&¤©ĆĆF$''#** ŃŃѸu벳łˇ¤¤„>}ú°+…dµŇČČëČťJAA’’’p÷î]¶V>|řŤŤŤ°˛˛‚··7<==1tčP899QcÔÁČŚ›Ţ222ŘSîdď­ŻŻĎĘVŰ4@477§ŮÝn„a@("''‡­™˛É†ěělČýţ<[/mllşě€35Č)((ŔĹ‹qńâE\»v EEEĐŇŇb‹——ÜÜÜ^zé&yy ¸˙>nܸI‹/ IDATö`K]]žžž;v,ĆŽKoŐN*++q˙ţ}$%%!99÷ďßGJJ {^ ’’;‚Ů´‰±µµEŻ^˝ž{ž!Ď’JĄČÍÍmqĐ%##ťÖÔÔDź>}ŕěěŚ~ýúˇ˙ţpttd/|DÚ^jj*"""páÂDEEA$ÁČČžžž6l<==1hĐ zý·±XŚřřxDGG#::111(..†––|||0nÜ8řűűĂÎÎŽë¨ÝFEERRRśś,W+óóó<}›KKKK¶iiÚÄX[[żđ„´¤ľľ999lťLOOGzz:űąěôFmmmŘŰŰł5ÓŮŮąÓ×LjۉT*Ĺ­[·páÂ\Ľx ĐĐĐŔčŃŁ1fĚx{{ÓČ,‡„B!nŢĽ‰«WŻâŇĄK …°°°Ŕرcáç燱cÇŇňŰ7$•J‘ššŠ»wď˛WxNIIÁăÇŹ<˝ř„““śśśĐŻ_?¶¸[YYŃĚ>iHKKĂŁGŹššĘ„feexz!4'''8::˘˙ţčßż?HWănb±—/_fŽ?~ řűűcäČ‘đôô¤Ób8öđáCÄÄÄ ""(((€••;¨|8ĽĽĽzÜh .U ##ß|ó öíۇěělxyy!$$óćÍŁŁŁŘá±N*++ĂÁ±oß>ś8q1c–,Y‚‰'ňő­x0lýüůóŚŚD\\Îť;‡‚‚hhhŔĂĂC(Ľ˝˝áęęĘ#%Xźp÷î]$$$(Ýd2tttđä“OÂ××ăÇŹÇ1cřr™˙ݎˇ'OžÄwß}‡Ă‡٦¦&LŔĽyóĚ?Ő×K•””ŕ·ß~Ăţýű---Lź>Ď?˙<&LŔyň˙“Ëĺ‹‹Ă©S§‡óçĎŁ´´:::đňňň¤ŹŹśťťů}c}J~~>„ΠÄÄDˇ­čćć†#F`Ě1;v,¬¬¬DŤ• ä.R__Źb۶m€/^ŚÖ‡(aaaŠŠ‚““–/_Žçꦦ¦b‡×męë둜śŚččhDFF ×:88 >>>đńń——Wźź5–1"Âőë×qîÜ9$$$ >>çĎźáÉ'źÄ¸qă0nÜ8ôŠ!f]©°°ß}÷ľţúkÜşu ăĆŤChh(‚«cçăŕŢ˝{8pŕ GGG!Oöë×OěđşUUUÎś9ččhDEEáÜąs¨­­…›››09¨··7Ź:aŹ-ĹhĂ„„ś={gĎžEUU\\\(Üú÷ďß­qqüŞŞŞđŐW_á?˙ůrss1uęT¬\ą“&Mâžż>.-- ۶mĂ÷ߏšš,Z´o˝őěííĹM%ŠŠŠpřđa:tŃŃŃÉd°łłC`` žzę)ÂÎÎNě0ëQĘËËqúôiDEE!** ÉÉÉH$đőőĹ´iÓ0kÖ, :Tě0U&##~ř!~üńGčééańâĹxůĺ—ąăř1‘žž.äÉŞŞ*,\¸o˝őśśśÄMe222pŕŔ9rńńń¨©©««+ĆŤ‡ŔŔ@Ś;fffb‡ÉXŹt˙ţ}ś={QQQŽŽF||<Ş««áęęŠÉ“'cćĚ™Py‡Č©şş˙ýď±iÓ&”——cĺĘ•Xąreź-ŽXë*++ŽM›6áÎť;xţůçńöŰo÷‰ë„nŢĽ‰âŔŤŤ…ŽŽŽp ý¸qăŕŕŕ vŚő*2™ ýőNž<‰C‡!++  ¬Ył ˙>ŃązýúulذáááprrÂşuëÂץ>¦ŞŞŞ°wď^|üńǸqă-Z„wß}·O䆆ÄÇÇăСC8xđ ŇŇŇ`mmŤ3f`âĉ\3ösdd$~˙ýw$%%ÁÄÄÓ¦MĂĚ™3¤šYÄ:mďŢ˝dccC:::ôÚkŻQ~~ľŘ!± ¶¶–ľýö[˛··'MMMzăŤ7¨˛˛Rě°:-??ź>úč#ňđđ daaA/ľř">|ŞŞŞÄʱ>ĺüůóôî»ď’§§§°ż­ZµŠ’’’ÄíˇÓ‹/ľHęęę4xđ`ÚłgŐ×׋ë!ęęęč‡~ gggRWW§+VPII‰Řa=”ÄÄDZąr%YXXrww§·ß~›Îť;G b‡ÇXꔕ•E_~ů%Mś8‘455I[[›¦OźN?˙ü3ŐÔÔtŮv¸@î„ěělš>}:I$z饗(77WěXt˙ţ}úâ‹/ČŘŘčäÉ“b‡Ô®úúz:~ü8Í›7Ź444ČÔÔ”Ö®]K111ܸe¬›Ü¸q¶lŮBC‡%4|řpúď˙KĄĄĄb‡Ö!?ýôYZZ’ĄĄ%ýđĂTWW'vH¬‡Ş­­Ą]»vQ˙ţýÉĘĘŠ~ţůg±Cę™LF[·nĄaÆ Eń–-[čĆŤb‡ĆŘcG&“ŃŢ˝{iúô餦¦Fô÷ż˙ť®^˝úČëćąöěŮC†††äěěL§Nť;Ö äääĐś9sH"‘Đ‹/ľHŐŐŐb‡ÔLYY}ôŃGdooO‰„iĎž==2VĆ'qqq´dÉŇÓÓ#}}}zá…(--Mě°Z$“É(88$ ˝đ ˝öŚ ë~÷îÝŁĄK—’D"ˇŮłg“L&;¤]Ľx‘ž{î9ŇŃŃ!}}}zńĹéĚ™3b‡Ĺű˙îŢ˝Kďż˙>9::  ýű÷?ôI.ŰŃĐĐ@o˝őIĄRzăŤ7H.—‹ëe~ůĺ211ˇ€€*,,;""*//§ţóźdbbB†††ôĆoPFF†Řa1ĆšÉd´mŰ6Íť;—´µµi÷îÝb‡Ăz±ôôt4h9::Šžüżűî;˛˛˛"cccÚ°a‹c¬}őőő´oß>ruu%MMMZ»v­čCŻOź>M¦¦¦äďďĎ—±G–››K~~~dffF111˘Ć’——GK–,!©TJ~~~ôÇđuĹŚő2ééé´xńb’JĄ4lŘ0:}út‡źŰű§ĘT"ÂŇĄK…ßy]´h‘Ř!±^ĚŮŮńńń°¶¶Ćĉ‘““Óí1Ü˝{S¦LÁ˛eË0{öl\»v ďĽóLLLş=ĆXçHĄRĚ›7/^Ä矎đđpxxx ""B”x.\¸€éÓ§#((‘‘‘°´´%ÖwXZZ"::O=ő¦M›†ÔÔTQâŘ»w/\]]qęÔ)ěŮłgÎśÁÔ©S!‘HD‰‡1öpśťťńÝwß!%%ććć;v,^yĺTWW·ű\ţ™§V|úé§ř׿ţ…“'OÂÇÇGěpz…ęęjhkk‹FŹ&—Ë1~üxhkk#""jjjݲ݄„ĂŔŔ»v킿ż·l—1U«««ĂŮłg‘™™‰ĐĐP±Ăé6………Xµj~ýőW|ôŃGxýő×»mŰ2™ Æ żż?vďŢÝmDZގsdÇÔ××ă™gžÁůóç‘””##ŁnŰî믿ŽĎ?˙«V­ÂĆŤUóó1ډŕqÍ•ŤíŢ˝k×®…~űí7ŘÚÚ¶ľ°ŞNk÷f·nÝ"mmmúńÇUľ­††Ú¸q#9::’››éëëRSSëłËd2ú׿ţE~~~4cĆ ±Ăé´ŠŠ Ú¸q#-^Ľ¸Ű¶™““CôŐW_uËöâăăÉĐĐfÎśŮŁŻťú÷ż˙Maaa]şÎQŁFѨQŁšÝ_SSCŻĽň ­Ył† D«V­ęŇí*ś8q‚,X@H]]ťĆŽKcÇŽ%wwwňöö¦7ŢxŁÇNĽ$¶Ö>»ĆňóóéŤ7Ţ 4mÚ4•Ć#Ʊ˘#>űě3RWW§ýë_ݶÍ+VаaĂşĺgß8GЧ®®ŽŢ{ď=zöŮgiÝşuLüńG·l»˛˛’<<˙üs@ďľűn—l«+¨rÝŞĐUűp[Ż[¬cEG}üńÇdaaˇňźÉY¶lYł¬*qŽGRR łgĎ*Ýż~ýz4hP·MX5iŇ$zńĹUşŤË—/“––9rDĄŰé ś+9W> UćĘžrĚ訢˘"˛µµĄM›6µř8OŇŐÄďż˙Ž~ýúuŰ5š………HJJBqq±ŇýŻĽň ňóó»%†ÎHKKĂÓO?Ťšš±Céb];§®®Ž©S§âŔ*ŰFff&öî݋͛7÷řkżţúk|ţů瀭[·vęąóťĽqăF§¶ˇŞ8ŕoű¦L™‚Ť7"++KĄŰ{Ý=Y{Ż»§ďCŻżţ:´µµ±sçN•mpđŕA«lMqŽÇŽ;```Đl–ńăÇăÚµkŽŽî–8fÎś‰‚T8]Î'ź|‚ŔŔ@L™2EeŰč*ś+9WŠ­µ×ÝSŽŐŻ_?¬_ż[¶liń3义””¸»»wŰl…ăÇŹGqq1ĆŤ‡ôôtáţ1cĆŕ©§ž444ŕôéÓXľ|9ž{î9$&&bôčŃĐÖÖĆäÉ“!—ËńçźbذaĐÖÖƤI“PZZŞ´ťk×®!44kÖ¬ÁÔ©SŚŚŚŚfń´µ\]]6oŢŚĽĽ<$&&"88ß~ű­ŇóŁŁŁáéé mmmL›6 ­ľöÔÔTĽúę«řřăŹáëë ÔÖÖâرcXşt)ž}öYüůçźđöö†––Ľ˝˝‘Řeď‰Ř<<ó-[¶Đ°aĂ„żýüüČÇÇGř»˛˛’ÜÝÝéË/żî>|8ŮŰŰ·ąŢ¶îWČÍÍ%ôÜsĎ [XXPDDĄ¦¦’D"ˇoľů¦ÍuväyŹň:Ú˙,Z{;şo·őŮUWWÓđáĂéłĎ>î;xđ`łx[‹ˇłß٦Ä:VtÔ›oľ©ôş»ÚŐ«W @·mć)NŽÔ××oqh{UU … ¶wWşpá®AW ÚłgŹĘÖßU8Wr®ěÉą˛§3:٦¦†ĐŻżţÚě1.›xíµ×Č××·[·Y^^N«WŻ&©TJČßßź˛˛˛š-€‚‚‚„ż Mžř@ią‡yOšĆ.FŁwóćÍJÚ®¶oß>ŇŇŇę–™fV}}=ą»»See%=řŢčččťť]łFpuu5 77·fëií3ś:uj‡“ţ† hĘ”)ÂßÓ¦MSęŔřż˙ű?˛´´Tšěl˙ţý´lٲvăhď;¦8HĎš5‹V­ZE...JË <†Úć:;ňĽGy m}í˝ŹÝ·[úě>úč#255ĄÚÚZáľű÷ď7‹·­ć{ÔŃÇĹöôÓOÓĽyóT¶ţââb@'NśPŮ6ZÂ9ňîĚ‘R©”¦NťÚ,¦††Ąc•Ş?~ś$‰J'´tqqˇőë׫lý]sĺś+{n®ě)njθ|ů2 Ë—/7{ڇX7áď/B.—wŰ6őőő±uëVś9sC‡Ĺ™3g0jÔ¨ŻŻj|ś‰‰ €׳6^TVV ÷9rJë2džxâ ś^|ńEdggcҤIJŹ7~]¸xń˘Ňýóžô±±±*ţ<}útččč <<\eŰxTüńFŹ ]]]ľ7!!!ČĘĘ¡C‡”–ŐŇŇ 8°ĂëďĚĄďĽóŽ9‚ĘĘJěر7oŢÄýű÷…ÇüńG¸ąąA*ýßasîܹؾ}{‡·ŃĹńFń{ꇆ\.ÇË/ż,ܬ¬¬`hhŘćz:ňĽ®xm}í˝Ź@Çöí–>»°°0xzz*=_SSłS1<Ě÷¨7ČĎĎÇ‘#GđÜsĎ©l&&&puuE\\śĘ¶ŃΑݟ#őôôP__ß,¦ÚÚZ€A«qwĄ¸şş ď—*,^Ľ»wďîŃ×’r®|€seĎÍ•=ĺŃŰ·oÇ“O>Ůâu.›6mtuuńóĎ?«|[Š/Ť‚ŻŻ/1kÖ,dgg·x=DcmMÓĐĐ üż¸¸¸Ĺ .•&>éčrťŃŇúvďŢŤ &`űöípvvĆÇÜćşĚÍÍ(ż¶¦:úž­¨¨ÇŽSicVGGď˝÷Ö­[‡ëׯ«l;Źâ믿ĆéÓ§1bÄᦸä‹/ľčöxľúę+,Y˛“'OnÖľuëVł}¶«(®ůńőőäääŔŃŃ_ýµp‹ŠŠj·0éČóTů:Úz[Ň‘}xpÍXă"Ł+cčÍęëë±téRřůů©üZĘgź}{öěQé¤I ś#ĹË‘öööÉdÍ–Q\§>^¸]şt ŽŽŽŚŚÄ•+Wş-ž÷ß6lŔwß}[[ŰfŹëéé!))©ŮqˇľľľYŻog)öůóçxpvŕĘ•+ÍĎDÔć§ŽÁäĘ•+QZZŠ]»v©t;çH1sd@@@‹3+f;vě#oŁ=»víBee%–/_®ŇíčëëăűďżÇW_}…wß}·[::sĺ˙p®ěąą˛'3:꯿ţBpp0VŻ^-LšÖČ-xőŐWQ__Ź5kÖ¨t;xóÍ7›ÝŻ:ŇUg=fÍš…Ű·oăŇĄKJ÷_»vMéç::şśD"iqEG ömŰxîąçpôčQŔ±cÇZ}nLL ¤R)BCCjŰ=űcǰuëV|öŮg*oĚJĄRüňË/čßż?|}}{Ô,‚Š^˦¤R)V®\  ă=ăŹňťTřĎţ!C†@OOš­oĚ1(//ÇĆŤ•îßşu«ĐËü0qüţűďصkŢ˙}ˇwxܸqČĎĎÇ?ü ´ěż˙ýoaÖŇ–¶Ő‘ç=ĘëhĽ˙¶¦˝÷±%Ý·™™‰á>EOză†ÎĂÄtÍ÷¨;ĺççă©§žÂŃŁGńÇtË™rCCClÚ´ ŻĽňJłâµ«qŽ/G.[¶ ÷îÝk6;ńŮłgáččŃŁG?ň6Ú’ššŠW^y}ôQ»Ăe»Âرc†Ź>ú ,@yyąĘ·ŮQś+ŕ\ŮłsĄŘÇŚŽÚ¶m&Nś9sćŕ“O>i}A•_ÝKť;wŽ455[ťů¸+¤§§Ząr%Éĺráţ˙űż˙#SSSĘĚĚî«««k6ن\.'ôÔSOµą\aa!ŮŮŮѬYł„ꎊŠ"[[[a†ĚÎ,geeEVVV”••Eű÷ď.üo<‰âľ‰'*˝ćĐŠ+ČÝÝťjjj„mŁŃŚžČĆÆЋ‹‰¨´´”ÜÝÝéÍ7ßě’÷Dˇ¶¶VŃł;ÄÇÇ“ˇˇ!ýóź˙ě–í)Čĺrzć™gH*•Ň+ŻĽ"Lô!–’’222˘{÷îµřxNN ===á»§ř¬ĆŹßlů¦ßI…‰'ş˙ľp_eee‹ßMSSSŇŐŐĄČČH:pŕ999ú믿čĆŤ”””DÚÚÚÂd6ź|ň Í™3‡~ůĺ—6ăPL€Óx˙ "ş{÷.­[·Ž´´´š}.\¸@ššš¤®®N+W®¤m۶Qhh(}ňÉ'mn«#Ď{Ř×Aôżý·­Ď˘˝÷±#űvkź]\\©««“ĹÄÄPqq1mٲEísßľ}íĆ 8îvć{DÔýÇŠö„‡‡Sż~ýČŮŮ™®\ąŇíŰúé§iŔ€-N–ŐU8GŠ›#׬YCsćĚ^kuu5yyyŃüAŞtűöm˛µµĄůóç«t;-ů믿Č‚ěíí•&E çJΕ˝)WŠuĚčĚĚLš2e IĄRÚ°ack¸@nCXX©©©ŃoĽˇ4‹]W©©©!555@FFF4věXňőőĄ™3gŇŐ«W…ĺ iýúő€ĚĚĚčđáĂ$“Éč­·ŢŚ?˙ü3Éd2a9ccc ľŮŮŮBS¦Lˇż˙ýď´téRşuëVł:˛Ü_|AzzzäééIŃŃŃôć›o Ż!<<śĘËË…Ř •v???zď˝÷čA‚÷óóŁ÷ßźfĎžMożý¶đ>+[¶lÍź?źüüYó@ IDATühăĆŤÂëéŠ÷$66–Ö­['¬c÷îÝtăĆŤ.ű|›:räPhhh»;¦Ş|˙ý÷dbbBÖÖÖ´cÇ•|ŻŰséŇ%=z4 üă”››«ôřť;whÆ €P`` ýöŰo´jŐ*@´yófĄç5ţN&%%Qyy9mßľť ˝ůć›tçÎşté­]»VřľîŢ˝› ‰hçÎťd``@...těŘ1Ú±céęęҤI“(??ź$ť#F¦¦&ą¸¸4űi€¦qDGGÓĽyó©©©Q`` Ť?ž<==ÉÍÍŤ–/_ŢęOć=z”ÜÜÜHSS“śśśhűöímn«ŁĎ{סŕççGĎ=÷\›źE{ďc{űvkźťÂ‘#GČÝÝť455ÉÓÓ“"##iČ!ôᇠǪÖbptt>ŹŽ|ŹşűXŃ–¤¤$ $‰DB+W®¤ŠŠ Q⨬¬¤#F­­-%&&Şdś#ĹÍ‘őőő´iÓ& ˇ×^{Ť-ZD‡î˛Ď·%‰‰‰dmmM˘uäćçç ljٳg‹ŇEÄą’seďË•b3ÚS^^Nożý6éččĐŕÁ)66¶CĎăąű÷ď'š5k•——‹ÎcíLťßŰlÝş•ÔÔÔčĺ—_Všv_ yyy´rĺJRWW§ˇC‡RXXXłź‰`LUúÚľÝ])88$ Ť1‚Îś9#vHTVVFS§NŠ-Ö}úâ~¤hoÍ1ĘĘĘćŽ=Jîî®NˇˇˇtéŇ%±CbŹ‘ľ¸Źw§ââbÚ°aőë×ŹŚŤŤiË–-JgŮŰĂ× ·cîÜąŽŽĆŮłgáëë«4žź±öäççcÁ‚X»v-6oŢŚm۶5›¶ż»őďß_~ů%RSS1lŘ0,^Ľ ÂűᅬśśQccŚýOuu5ÂÂÂ0nÜ8x{{#;;żţú+âââTúqe``€C‡ᥗ^ÂĽyó°jŐ*”••‰ëeJKK±bĹ Ěź?«V­ÂożýÖ#~&((ÉÉÉřţűďqńâE¸»»câĉؿ—LŇÄëzçÎťĂňĺËaooŹO?ý«V­Âőë×ńú믷řSW­áą|}}qîÜ9ŘŰŰcěرX˝z57TH1ůާ×W%"®]»ŕęꊳgĎâčŃŁxőŐWĹK‰‹‹ vďŢŤ´´4Ě›7[·n…ťťfÎś‰C‡őŞÉŠXďĐöíîššŠ5kÖŔĆĆK—.…ąą9Nś8ÄÄD«|rżÎPSSçź~а°0ěßż®®®8pŕ€Řaői}i?úĺ—_ŕęęŠ_ýáááŘĽys›?EŐݤR).\””>|zzz …µµ5^{í5¤¦¦Š"ëúŇ>ŢŠ‹‹ńź˙üđóóĂŮłgńÁ 33ď˝÷úőë×ů•Şîävß´gĎ277'Ú¶m[§N׳öeeeŃ«ŻľJH__ź>ţřcĄ‰XzS§NŃčŃŁI*•ŇÚµk{ÍĐüššÚż?‘T*%kkkZ˝z5ť>ž&MšD‰„–.]Úę$T=Qnn.mÚ´‰LČÇLJ>řŕ‚ÍşD_ŮÇU­  €věŘAłfÍ"---222˘—_~ąËćÄŕů!ŇęŐ«ISS“ěííiűöí˘_WĘÄCO=ő”0ChonŢľ}›6nÜHľľľ$‘HČÄÄ„BCCi˙ţý˝¦ŕg¬'«ŻŻ§ŘŘXúÇ?ţA "dggGűŰßčÔ©Sb‡÷H"##ÉĎĎŹĐôéÓ)!!AěXqîÜ9š:u* QŁFQtt´Ř!=´††:uę­Ył†HČŃŃ‘^{í5ŠŠŠâą=ëb´yóf  555Ň××§ąsçRXXŇ/t QűEô^$;;|đvíÚkkk¬Zµ Ď?˙üĂťĘg˝Rmm-:„Żľú ‘‘‘=z46lŘĐŁ~ýQĺääŕŕÁ8x𠢢˘ •J€ŔŔ@Ś7ľľľ˘_WÍXopíÚ5DEE!::‘‘‘ČĎχ»»;‚1kÖ, >\ě»Ô‘#G°~ýz$&&bâĉX±bfĚŃŁ†Đ2Ő«««ĂáDZmŰ6ś¦OźŽ5kÖ`üřńb‡¦RĄĄĄ8vě"##…k×®A___©`~ňÉ'ą`f ŔÍ›7•’űť;w`bb‚ŔŔ@búôéppp;L•;zô(ľüňK=zÖÖÖxńĹń /ŔÚÚZěĐ )ňäöíŰ‘——‡)S¦ŕoű[ź+Ś[’••…#GŽ ** §NťB~~>,,,0věXŚ3† fĆZ——‡S§N!::ýő®\ąřűűcĚ1 ‚ŹŹ¤RŐOˇĹr’ËĺŘ»w/¶mۆóçĎĂŐŐóçĎGHH\\\ÄŹ=˘ââbüöŰořé§ź sss,[¶ Ë—/Ç€ÄOwîÜQ:#–™™ ]]] 6 >>>đńńŻŻ/śśśÄ•1•şwďÎť;‡ÄÄDś;w ČĎχ‘‘‘Đ  „§§g·$÷ž(33ß|ó vî܉˘˘"Ś?óćÍĂś9sxäUQTT$äÉččh››céŇĄx饗0pŕ@±ĂÍ•+W„βS§Nˇ  FFF>|¸+˝˝˝ë÷=^JKKqţüy$$$ !!‰‰‰¸}ű6´µµ1bÄᤋźź´´´ş=>.U$)) {÷îĹţýűqűömxzzbţüů3gË˝Haa!Ž=Šýű÷ăřńăĐÔÔÄŚ3‚iÓ¦ACCCě{”ĚĚLÄĆĆ Brr2ŞŞŞ`bb___řřř`ذađđđ€Ăc[(°Ţ­  ©©©¸xń˘Üoܸ©T gggˇcČĎĎO>ů$)n˘¦¦GŽÁľ}űđű ̄şşZ(–§M›KKK±Cdť——‡ß˙?˙ü3""" ŁŁ™3gbŢĽy:u*çÉ&W®\A||Ľ+/]ş„ÚÚZXXXó°aĂŕćć{{{Ε¬W+**Bjj*RSS‘„„¤§§`oo/´ýüüŕă㣲aÓťÁ˛ŠÎś9ź~ú ?˙ü3rrr`ooŹ   L0&L€‘‘‘Řa˛˙ŻľľçÎťĂŃŁGqěŘ1ś?ÚÚÚ BHH¦Oź]]]±Ăě5jkkqéŇ%ˇ€Ë—/Łľľ:::puu…»»;\]]áááWW×Çöl<ëyJKKqůňe\şt —.]ÂĺË—‘’’‚˘˘"€­­-|}}áíí ??? >śŹçťTUU%tBţţű館¬„——&Mš„I“&!  Sż]ÉTݦ¦1118věţüóO$''COOÓ§OÇüůó±ĂěUŞ««‘śś,‰‰‰HKKCCCôôô0dȸąą)ĺL;;;±ĂfLIăśyůňe\ľ|©©©(((XYYÁŰŰ[1áăă333‘ŁnČÝššŠăÇŹăرc‰‰ACCFŚQŁFaäČ‘5j5ëF÷ďßÇůóçŘŘXÄÄÄ ¸¸®®®nŢĽ‰k×®áúőëÂ-##CřNš`čСpss››† www>Vw±ššÄĆĆâäÉ“8věPxŔßß#GŽÄ# ŻŻ/v¨Ź•ňňrś={qqq‹‹CLL är9ĽĽĽ„I“&aäȑܑŃĹärąR®Ľté®\ą"—ŚŚŚŕââ'''8::bĐ AB®ě©Eëýär9®_żŽ›7o6Ë™ŮŮŮţ—3ySѱcnn.rôDz***ÄĹĹáâĹ‹¨ŻŻ‡‹‹ üýýáďď///¸ąąqÖ7oŢÄ… ŘŘX$$$ŕţýű8p FŹŤ±cÇ"((¶¶¶b‡űŘ)++ ć´´4dddŕúőë¸uëjjjfffB`Đ A°··Ç€`kk ;;;Q®Sa=[CCňňň••%Ü'őěěl444@"‘ŔÖÖVř~9;;ĂÝÝC‡ĺăHňňňČČHś9siiiPSS§§'FŽ ___xxx`Č!<Ś·‹ÔÖÖâĘ•+HIIABBNź>ŤÔÔT444m“ńăÇcҤI˝Ş±Ű—”••áĘ•+¸té®^˝ŠëׯăÚµk¸yó&îßżŕAGłŁŁ#áääŘÚÚbŔ€°łłăN&ÖŞÚÚZäää ++ ·oßFvv6nܸ!äĚ»wď¤R)  ”3Č666"żŠGÇrRQQřřxÄĹĹ!66ńńń(++şş:\\\ŕĺĺ///xzzbđŕÁ<µ 2™ ¸xń"’““‘śśŚK—.ˇ¬¬ đđđŔČ‘#€QŁFő‰ťąŻŞŻŻoVÔ(™™™¨ŞŞ–µ´´„­­-lmm1pŕ@ŘŮŮ [ZZÂŇŇ’‡Č÷!µµµ(,,D^^îŢ˝‹¬¬,ÜąswîÜAff&˛łł‘““ÚÚZ€ššlll”δ4ľqGdĎVXX3gÎg2Ďź?ą\MMM¸ąąÁÓÓBŽäY˛Űv÷î]¤§§#%%ÉÉÉHIIÁĺË—QSS]]] >\Č“#GŽ„©©©Ř!ł6îÜąÓ,W޸q·nÝBYY™°¬±±±'9ŇÎÎ €ĄĄ%ú÷ďĎźw$—Ë‘źź/äĚ;wîŕöíŰBŢĚĘĘB^^šššJE°b´‚˘ÓĄ/ź”ŕąSśńT$/Ĺ-++  §§' CuvvĆŕÁáää;;;XZZöůId2˛łł…b)##éééČČČ®w066LŠ777 Ö‡ …‘â@ź••…ěěldee!77uuuÂňúúú°˛˛B˙ţýaaakkk››+Ýgjj SSSđKݬ¬¬ ĹĹĹ())A~~> źźŹÜÜ\ //yyy(,,ös333ˇSDŃđS4úěěě`eeĹ?AÖ‡Ô××###©©©¸pá‚Päĺääx°Ż;;;cĐ A4hĐc—#Źž¸~ý:ŇÓÓ…\yíÚ5TTTlll„Î…aÆÁÓÓNNN|ěëcĘĘĘťť-ślś+ďÜąěělTWW ËkjjÂÂÂB(-,,`ee !w*ň¤©©)w>‹ ¶¶%%%())Á˝{÷PXXÜÜ\äç磰°999(((@AArss…}xĐaliiŮb'‰b´ĄĄĺcűSd\ ÷BĹĹĹHOOŠAE˛ËČČn°¶¶†Š/ż™™,,,`nn333ôëׯGőŠŠŠ„Ű˝{÷PPP ÷hÜËUYY ŕÁ0Ź ťŤŻ_µ··÷1ŃŐ××#77yyyBÁĄHM /™LÖěůFFFB# _ż~Bc@ńݎˇ!ŚŤŤˇ«« ===ÂĐĐzzzĐÓÓ{¬&m’Ë娬¬Dyy9ĘĘĘPYY‰ĘĘJ”––˘ĽĽ(.. ŕ¦˙/))QęĚmmmôďß_h)F(kІ›­­-O Ä<č4S\¦Ń¸ ĽvíšRŽ´´´„6660`€-,,ĐŻ_?™™ő¸ďUUU•óóó…†qVVrrrZěÔÖÖňbÓŽuľ^•)(ЩÑ-\………ÍŽŐZZZJąŃÄĤYľÔ×ׇžžŚŤŤ…i`` äĚž¶Ż©R]]ťR®”ËĺÉd¨¨¨@ee%***”rcă˙+ţ-//o¶^SSÓV;4ĚÍÍ…|jiiÉĆmŕąihhŠGE!©H”Šż Q__Żô<XXXŔŘŘBC_Ńč×ŐŐů:::JĂ544”®e©©© WŕAq˘Ö#—Ë!—ËQVV†ňňrˇ1]ZZŠŠŠ !á+†v(ŔĘĘJ©W«qŃßׇy°îS]]ŤÂÂBÜ»wŻY×řľĆŹ•——C&“ˇ­C©ôôô «« €ˇˇ!ÔÔÔ„}J]]Ś|H$ĐÓÓSí ĄĄŐj/}Ó}Sˇń>Ř”"A+‘ĐIP^^Žşş:Üżrą (--đŕLD}}˝PWTT´űčëëĂŔŔ@h(5n45mT)îł°°€ˇˇa«ëd¬3„ˇřŠłfŠ<©ř·¨¨H’Ż §§'ËŠýŘĐĐúúúĐŐŐ…ľľ>ŚŚŚ •J•öcĹ>ŻPRR˘ô·b_SěcË娨¨@YY™+9˛qŽäasss!'0@©č·łłŤŤMź?cÎş)ĺĘ–Š·¦˙* :ą\Ţęz% ŚŤŤ…BZOOR©Th@]]ÚÚÚĐŃŃiń1…Örb[Ź5Îsy¬´´ ¨ŞŞBuuµRNmú˘},“ÉPYY)\/ŢEŰşµŽ†–:!9“GHv .CŠ$ŰřLmAAJKK…d,—ËQRR˘TÔ®“nÜx¨®®Vş´­ĆŽŽŽPl7mXčééÁĚĚ ćććBľâĆ“Ż°Ţ ńŮÓŇŇRˇx,++Sjä* PEAYYY‰ššĄÎ%EşéţÖôďĆŤě–(ď-iÚxoZśkjjBOOOh¸˙k(:Ó „ý¸ńYôĆťmŚő2™ ………J#™˙Wśé)//WęčUěĎŠ%…–ŐM÷G]]]hii ű˘700:­őőő…"]1úK‘3y˙b˝MII‰R«"gĘĺraÄ‘bßj«člé1EGnKÚzLŃyÝ’¦űnG vĹcŠ˘·é3Eză3ë\䊏 dÖ%$ °páB±CaŚ1Ćz”ĐĐP@XXČ‘0ĆkŹ·aŚ1ĆcŚ1ĆŔ2cŚ1ĆcŚ1€ dĆcŚ1Ćc ČŚ1ĆcŚ1Ć.cŚ1ĆcŚ1\ 3ĆcŚ1Ćc¸@fŚ1ĆcŚ1ĆpĚcŚ1ĆcŚŕ™1ĆcŚ1ĆŔ2cŚ1ĆcŚ1€ dĆcŚ1Ćc ČŚ1ĆcŚ1Ć.cŚ1ĆcŚ1\ 3ĆcŚ1Ćc¸@fŚ1ĆcŚ1ĆpĚcŚ1ĆcŚŕ™1ĆcŚ1ĆŔ2cŚ1ĆcŚ1€ dĆcŚ1Ćc ČŚ1ĆcŚ1Ć.cŚ1ĆcŚ1\ 3ĆcŚ1Ćc¸@fŚ1ĆcŚ1ĆpĚcŚ1ĆcŚŕ™1ĆcŚ1ĆŔ2cŚ1ĆcŚ1€ dĆcŚ1Ćc ČŚ1ĆcŚ1Ć.cŚ1ĆcŚ1\ 3ĆcŚ1Ćc¸@fŚ1ĆcŚ1ĆębŔzź””ÔÖÖ6»˙Ö­[8ţĽŇ}...ĐÓÓë®ĐcŚ1QeggŁ  @éľââbh–#-,,0`Ŕ€n‹Ť1ĆXű$DDbÁz—ŮłgăŔZ¶´´†††*Ž1ĆëÂĂĂÚˇeðpáBGÄc¬3x5ë´ ´»ŚT*ŤI“¸8fŚ1öX™5k–J–eŚ1Ö=¸@fť6cĆ ččč´ą áĺ—_î¦cڱžAOOóćÍşzëW±©««cŢĽy| cŚő@\ łNÓŐŐĹÓO? Ť6—™:uj7FĹcŚő ‹-B}}}«Ź×××cѢEÝcڱŽâ™=”… ¶8Qhhh`îÜąĐŇŇęć¨cŚ1ńÁŔŔ ŐÇ ÔŤ1Ćë(.ŮC™0aŚŚŚZ|¬¶¶¶Ă”0Ćc}Ť¦¦&ćĎźßâH+ Ěź?ššš"DĆc¬=\ ł‡˘ˇˇ… ¶üűőë‡ńăÇ‹cŚ1Ö3<óĚ3-Ž´Ş­­Ĺ3Ď<#BDŚ1Ć:‚ döĐZf­ˇˇĐĐP¨©©‰cŚ1&ľŔŔ@››7»ßÜÜÝcڱá™=´QŁFÁÚÚZéľÚÚÚý cŚ1Ö—IĄR<űěłJC©555ńěłĎB*ĺćcŚőT|„fM"‘ 44T)ůŰÚÚbÄ"FĹcŚő .DMMŤđwMM .\(bDŚ1ĆÚĂ2{$Ť“ż††/^ ‰D"rTŚ1Ćř†;;;áo;;; >\Äcڵ‡ döHĽĽĽŕääŕÁđę‘#bŚ1ĆzŽ%K–@CCX˛d‰Řá0ĆkČě‘)ľ““ÜÝÝĹ †1ĆëAZÖÖÖňđjĆëÔĹ€uż’’Ŕýű÷!—Ëeee¨ŻŻo¶LkĘËËQWW044ŘŰŰc˙ţýÂ2FFFmND˘§§§tý˛by čëëôőő[ü))ĆcL*++QSS"‚L&TWWŁŞŞŞŮ2­iś_KIIAJJ @WWZZZ­®CSSzzzÂß:::ĐÖÖC"‘4[†1ĆŘŁ“‰űꆆČd2Čd2”””@&“ˇ˘˘ŐŐŐ(--…\.Çýű÷QRR"$l™L†ęęjČĺr”––˘şş•••hhh@ii) ŞŞ ŐŐŐ"żş‡'•JaddŕŤE!m``mmm@__ÚÚÚ044„žž´µµadd]]]hkkĂŘŘ066†‘‘ŚŤŤ…cڱžŻ¬¬ ĄĄĄB®¬¨¨@EEĘËËQ]]Ťňňr!o–••ˇ˛˛R)‡VWW …Ż˘s¸®®ĺĺĺ"ż˛Gc``uuu¨««ĂŔŔ`bbmmmčččůNWW†††ĐÖÖn1‡ęëëĂŘŘX¸)ÖĹcŹ .UD.—ٍ¨(,,DQQŠŠŠ„˘·Ą[ii)ĘĘĘZ\źD"±±±P6NtFFFĐÖÖ†žžžRŇS<€ Žť©mďĚmăő@\\FŽ)üÝ‘ĆFÓłÔ2™ D„ššTVVhąń˘čąW,WVV†ęęęvH­őö+ŢĎĆ7Eńlll ™™)Ýú÷ď/Ľ·Ś1Ć:§®®NČ‹EEEČĎĎGaaˇ#ŔŤ;Śe2Z\gG:H9ÔÄÄDxކ†F‹ť°Ŕ˙ÎÔjiiAWWWŘV{gnݞłł î+--mőµÍĎR·wf[±ľÚÚZTTTË):Čw¬7îLośC[{-ŤóaÓ|©¸ßÜÜJąR]ť*2Ćz.;ˇ¤¤999¸{÷.rss‘““ŁTü˘  EEE͆VikkĂĚĚ &&&JĹWK7###Ą$¤ŻŻßć0,Ö1Š3ęĺĺĺmvR4˝Ż¤¤EEEÍ ~ ŤfEsă˙ŰŘŘŔÚÚÖÖÖčßż?˙î%c¬O«®®FNNŽRž,,,D~~ľR1\XXââbĄçJĄR!G¶•[şéééńYÎ.˘č\n-6í¬P,ŁČ“M ~SSS››7Ë•ććć°˛˛RĘ“<š‹1ÖSpŚ…SNN233…¤~çÎäĺĺ!++ ąąą¸{÷®ŇőGşşş°˛˛jńŔßR"Pś©e˝×ýű÷…^Ó‘Š3 Ť˙ďŢ=áąęęęčßż?lmmaii‰ŔŇҶ¶¶°¶¶ĆŔ1pŕ@îaŚőH%%%ČĚĚÄť;wťťŤĽĽ<áß;wî 77·ĹcžąąyłĽŘŇ™F333ţ‰Ŕ^Ž”rbQQňňňšuŽ(N$äçç s™@ż~ý`ee%äE[[[ˇ¶µµ…˝˝˝pćź1ĆTé±)sss‘™™©t»uënÝş…¬¬,aS[…LăŢN>Hłö´t6%;;[č€iÚń"‘H`ee…'žxöööÍnä Ëc*Q^^ŽĚĚLÜĽySČŹŤóĄb> @ąQäIkkk5Ă:ĄľľůůůÍNL´Őńbdd$äDŘŰŰ+ĺLIŔë }Ş@.))AFF®^˝ŠôôtávóćMa‚*MMMŘŮٵX€<ńİ´´ä¤ÎşUII ˛˛˛”:n7TC»ŐÔÔ`ccggg8;;cČ!>YYYĐŇŇÂđáĂáďďŹQŁFÁßß–––b‡ËŘc«ˇˇW®\A\\âââpćĚddd@]]žžžđööÎzń0QĆş†âňEçňůóçqńâEÔŐŐÁŮŮţţţ9r$FŽ WWWľdʱ>ŞŰ äššÄĹĹáĉ8yň$’““ů€ĂXp÷î]ĄFxRRjkkáŕŕ€±cÇbňäÉ8q"LMMĹ•±>--- GŹEDDbbbPZZ SSSřűű ťW>>>ĐÓÓ;TĆmťĐ Ŕ¤I“0iŇ$¸¸¸*c¬‹¨´@ľqăNž<‰cÇŽ!""•••đňň„ ŔCVëŞŞŞ¸¸8DFF⯿ţBmm-|}}1aÂL™2ľľľ<ޱGTZZŠ?˙ü'NśŔ‰'™™ KKKLž<cĆŚżż?\\\xN ĆzĆ—ţő×_8~ü8ňňň`ooŹ   Lž<ăĆŤ‘‘‘ء2ĆR—Č.\@XX<ëׯĂÜÜ'NÄĉÄĂ6ëeär9bbbpěŘ1=ziii055ĹäÉ“±`Áń„?ŚuP~~>~úé'üňË/‹‹T*E@@‚‚‚0qâDxzzrAĚX/BDHNNĆńăÇqňäIÄÄÄ ˇˇŁFŤÂÜąs1ţ|XXX&c¬ş¤@ľqăöîÝ‹đđp\˝z... Á´iÓ0|řp2ÍXrűömś8qű÷ďGdd$ŚŚŚđôÓO#44ŁGŹćýť±&ĘĘĘpŕŔ„‡‡ăĎ?˙„ˇˇ!ćĚ™ŕŕ`ňőĂŚő!ŔˇC‡đË/ż ˘˘'NÄÂ…  ±CdŚµăˇ dą\ް°0ěÜąńńń°±±Á‚ °páB<ůä“]'c¬ĘÍÍĹľ}űŽsçÎÁÖÖ‹-Š+`gg'vxډ*** _ý5> 6mBCC1eĘž5ž±ÇŔýű÷qäČ„……áČ‘#€™3gbĹŠ;v¬ČŃ1ĆZÓéą  ź~ú)ľýö[Čĺr„„„`ńâĹ;v,ź9bě1výúu„‡‡ăŰożEnn.‚±nÝ:řřřcݦ®®{öěÁ§ź~ŠÔÔTŚ=Ë–-ĂěŮłů§ {Ś•––â·ß~ĂÎť;qúôixxxŕď˙;žy樫«‹c¬‘Č2™ 7nÄ—_~ }}}¬]»/ĽđĚĚĚT#c¬©««ĂŻżţŠO?ýgĎžĹôéÓńţűďĂÓÓSěĐS"ž={đŢ{ď!++ ‹-š5kŕĺĺ%vhڱ&)) źţ9ÂÂÂ`ooŹ÷Ţ{Ď<ó Ď?ŔXѡSľß}÷śťť±sçNlذ·nÝ›oľÉĹ1c¬uuuĚź?ńńń8zô( ŕííŤ5kÖ ¬¬Lěđër/^ĨQŁđüóĎ#00éééŘąs'ÇŚ±=ůä“řî»ďžžŽŃŁGăŮgźĹčŃŁ‘šš*vhŚ1´S Ëd2Ěź?/ĽđBBBpíÚ5Ľúę«ĐŃŃé®řXPWW‡ŘŘX„……‰J—ꫯ«' B||<ţűß˙âÇ„··7’’’Ä‹±.óĹ_ŔĎĎR© Řľ};žxâ ±ĂbݬŻć“ľúşz ěÜą‰‰‰¨««ŻŻ/ľüňK±Ăbě±×jśźźŹŔŔ@ÄĹĹ!""[·n…±±qwĆÖ&"¦M›ŕääwww@"‘@]] ˘Ĺ€€€€f÷×ÖÖbíÚµxĺ•WŕěěŚŐ«Wwh}żţú+ćÍ›‰D‰D‚Ý»w·ąüŽ; ‘H ĄĄ…őë×ăĆŤő: đÖ[o! {÷îíđó ńý÷ß#$$‹-z¤Tˇ/˝®ĘĘJlÚ´ K–,;”I$,]ş)))xâ‰'0zôhś8qBě°{$D„5kÖŕŐW_Ĺ;˙Ż˝;ŹjęL˙ţ †%(‚P+ "ŕRA©¸‹xÔŇŃÚ©čqÔq«S×*¶ŁĄs”N­ÇµťNG§učXuśşT©u«U¨¶ î‚SV•} @Hžßţr‡K¢UđůśĂ1ys—罢Ď}—Ľ÷ŹÄ… lę°D8OÇy˛u:J˝´Z-ţô§?aÖ¬Y‰‰ATT”°`–ąFbb"Ţyç,]şË—/ÇS~ +cěq*•Š‚) €ňňňŚmbr7n$GGGJKK#"˘ŞŞ*Z±b üü|“Ĺ5tčP6lAy\\ :”Îť;G“&Mjő1+++     f· &4bÄÇ ĽZ­–Đĉ[˝OII ]¸pá±÷kKˇ^'Ož¤ąsçšM<-Ńjµ´xńb˛±±ˇäädS‡ĂŘ[·nuęÔ‰Nś8aęPšÄyŇ8Γ­×ę5ţ|šk_,--MÂc‘H$Řľ};JJJkÚcć"66łfÍBDD„©CiçICś'ź/˙űßaooođ¸ÁQŁFáŢ˝{8ţĽikÁĉńŰßţ±±±¦…±ç’Aůřńă°°°0űÄ?jÔ(”––bäČ‘HKKʇŽŃŁGCŁŃ !!sćĚÁĚ™3qúôi 46664h~ţůgŃńŇŇŇđꫯ"** ýúőömŰ ÎYZZŠĹ‹cÉ’%={6ĆŚŰ·o źgggcÓ¦MčÓ§ŹPöŻý ŃŃŃP©THMMEtt46nܢ˘"Lž<‰aaaHNNTUUaéŇĄđ÷÷GVV–čüóćÍNž<‰»wďŠ>ËÉÉAVVFŤŐä5»wďfĚ·Ţz ‘‘‘xĺ•Wžžn°]YY,X€E‹áí·ßĆ{ď˝gôx­ąf-Ńétřᇰ`ÁĚš5 ?˙ü3^~ůeČd2Ś?5558}ú4‚!“É0nÜ8TTTm˝jkk±xńb,\¸H$pssCXX233[cíJă!ĺżüĺ/äááaŠŃěÇ’ťťM/ľř" ™LF›6m˘úúzásĄRIgÎś!äććF}ô]ż~ťvíÚE2™Śśśś„ďWçĺĺQ×®]…)Y7nÜ ‰DBź~ú©pĽęęj  ]»v e$///""Ş««ŁóçĎ“ŹŹą¬F§“\.7řžŐG}Dńńńű­\ą’Đď˙{ŃçkÖ¬ˇ={ö4y®śśrvv¦łgĎ eS§NĄÎť;SFF†P¦V«iŕŔ´mŰ6ˇěČ‘#ÇlÍ5k*–†ŠŠŠčóĎ?'ô /Đ'ź|BG(22’6oŢLĺĺĺ´uëV@qqqf[Ż·Ţz‹úöíKDŹ~G% ‹¶iîŐŐŐtŕŔ@>>>ôÇ?ţ‘iéŇĄ€6mÚdô:¶tťÍŃĘ•+iĐ A¦±Ç’™™IčĘ•+¦ĄEś'9Ošc˝Ú2OÚŮŮýšJĄ"ôĆo4yÝMíÇ$”••eęP{îd¨cÇŽ‘ĄĄ%)•JSÄóX”J%-Y˛„,,,…††RNNŽh4~üxQ™>lܸ‘Ţ|óMňóómăëë+üND´~ýzęÖ­iµZˇěŕÁ4wî\Ń~‘‘‘­Nüús[XXĐ/żü"”Ť7Žjjj ö'z”č¤R)Éd2*,,$"˘ššň÷÷'µZÝäąfĎžM>>>˘˛Ű·oŠŽŽĘ>üđCęÜą3i4ˇ¬¶¶Öŕ­ąfÍŐ»1!Ľ/**2ř»S*•€^ýuł­—ŁŁ#Ť7Nxß·o_˛˛˛mÓŇ9t:§¤¤„Đ´iÓ ÎŮ\<ć,22’~÷»ß™: Ć‹FŁ!;;;Ú»wŻ©CiΓś'Í­^m™'-,,(22Ň ýţS¦L1řĚ\ěŮł‡ěěěDťZڱ¶!m<˘=z`۶mx÷Ýw[?mvvvرcfÎś‰9sć )) Æ ĂO?ýWWWa;©T\ÍéÓ§cůňĺ¸víŕرc€…  Űtď޵µµÂűýű÷Ł_ż~°°ř߬ô©S§bęÔ©˘c7žĆÓ’eË–áăŹ?ĆŽ;°uëVdggĂÝÝ˝ÉgM{xxŕµ×^Ă—_~‰Ý»wă˝÷ŢC||<¦M››&ĎsâÄ ŠĘüýýŃłgO|÷ÝwBY||<E×ĚÚÚÚŕx­ąfŹ«áwiťśś˙îěěě@4ÝČÜę%“É““#ĽwwwG]]ÝcťC˙;dee%|Ţąsg@MMM«â0w·nÝ©S§pńâES‡ÂŘc‘JĄ3gvěŘččhübn8Orž4·zµež”ËĺĐjµ1h4€˝˝}«bnkŤ;wîÄÂ… ŰÝ:#ŚuĆZ͇&kkkJHHhë{«ÔŐŐ”©T*š2e  µk× ĺ0Ň©ŃhMť:•¤R)Ť9˛ŮsZYYQxxx‹±Mś8ń±zƉ¦L™BTYYI~řˇhTĂýő’““ uíÚ•T* ˙üsŃ6­9GkŻGk>37ůůůäççgÖSŰkNaa!uëÖŤ-Zd¶«ŕržä<Ů0sŞW[ćÉ€€2dÁľ………Ŕ,Ą¤ÓéhţüůÔ˝{wł~š c™Á"]…%K–`Ę”)8pŕŔÓkŤ?%ź~ú©hÁŕQŹäÎť;Ŕ`aŽĆô‹Wřűű nßľmđPv"BUU€G˝)))P©T˘m´ZíŻę €•+W˘˛˛{÷îEbb"FŚŃěö Ŕ#PXXyóćˇOź>˘‘cÜÜÜpďŢ=r‰Dwwwὕ••Ń…;kÍ5k ćVŻeË–aÝşuذaÖŻ_ʏ¸8Ěš5멞Ł=űĺ—_kkk|ňÉ'¦‡±'âââ‚ýű÷cďŢ˝7oŢŻÎĎçIΓzćVŻ¶Ě“aaaFWG׏`‡‡‡·úXmˇ¶¶sçÎĹľ}ű°˙~ł~š c™Ń2lŢĽË—/ÇôéÓńć›ošŐ*zŢŢމ‰1(wtt>oÎĹ‹aaa3fFމ‚‚|ńŢí¶nÝŠ’’ŹVýT*•řŕDŰěرCŞó¤^~ůe <qqqčŰ·ŻÁô3ýô úúzˇlĺĘ•M‰jÍ#+¦L™‚ěělÜĽyST~ďŢ=ĽňĘ+Âű°°0dee‰¦ľęt:%ŞÖ\łć”––L©zćVŻďľűŤGŽÁ† 0mÚ4m~í9Ú«řřx 0 …gĎž5Ű©mڵFxx8ľůć:tÆ 3hŚšçIΓzćVŻ¶Ě“sçÎEII ®_ż.*ż|ů2|||đňË/·úXĎÚť;w‚Çăĉ>|¸©CběůŐŇóˇC‡ČÉɉ<==éŕÁO{ű‰¤ĄĄZĽx±h‘Žőë×SçÎťE+ţ www*--%"˘ŠŠ  a›«WŻ’µµ5IĄRZĽx1}üńÇ4cĆ Ú˛e‹°MJJ Éd2ań‹-[¶Đ«ŻľJ˙ţ÷żE±Ť;–Pmm­PV]]MhěرMÖéË/ż$tçÎĎô«¦¦ĄĄ e:ťŽ|}} ¦ł•••ň˘˘"ňôô¤)S¦SĎť;G=zô ââba»ÄÄD’JĄäííM/^¤ŇŇRÚĽył°ĘéZ}ÍôSô&L`P'Z´hŐ××,>RSSChôčŃB™±íĚ­^Ý»w§€€Z˝z5ĹĆĆŇ–-[(!!A´hMKç0v|µZmt!ť†Ű[ÄÜşu‹ĆŚC‰„–-[&,’ĂXGđË/żĐ AČÚÚšbbbĚfKΓś'͵^mť'ßzë-zőŐW…ş«Őj ˘oľůĆ 6SP*•´zőj˛¶¶¦ŃĘâŚ1Óh±LôhąýŮłg“D"ˇAѱcÇžu\ÍŞ««#KKK@ŽŽŽN/˝ôMž<Ů q !C†ĐÜąséµ×^Ł!C†Đ|`𽱓'ORż~ýČÚÚšzőęEź}ö™Áy)$$„¬­­ÉĎĎŹ>,|¦T*éłĎ>#@111t˙ţ}şyó&-[¶Lußľ}FżS˘T*Ť>ň&>>žBBB…„„ĐW_}%|ö׿ţ•ţóź˙ďŹ?N“'O&deeEk×®ýG›››KÓ§O§ &ĐŞU«hÎś9”™™ipÎ'NP@@Y[[S`` ť={–üýý)..N´}s×,##–/_NČÉɉľřâ QĂhČ!ôţűďSQQĹĆĆrvv¦cÇŽQyy9˝óÎ;€är9:tĘËË…í ĹÇÇ ‡ćTŻőëדŤŤ ý4\)´ąsTUUŃš5kuéŇ…ľúę+R*•´bĹ áwččŃŁÂq.]ş$lďěěLűöí­ôjJiii4sćL’JĄL‰‰‰¦‰±gBŁŃĐöíŰIˇP‹‹ mÚ´Éä eΓŹpžä<©ŐjéĎţ3Mź>ťV¬XAŃŃŃ&żŹ%zôűüÁłł3) Úąs§hqĆé´Ş¬—śśL“'O&‰DBýű÷§żýíoŹY07h'‹=z”vîÜię0ŘŻ Ńh(&&FÔÔh4tá²µµ5admëÜąsE–––äççG˙üç?E#ŚuTĹĹĹ´víZ˛łłŁÎť;Óš5k(;;ŰÔaµó$k+ś'‰˛˛˛hőęŐäääDöööôî»ďRII‰©ĂbŚ5ĐäwŤ0`Ž9‚«WŻbŕŔřĂţ€=z`áÂ…řţűď…練ÇCDصk˘ŁŁM ű¦NťŠÄÄD„†† eR©nnn-~߯˝ËČČŔĆŤѧOŚ9%%%Řż?nÝş…3fűÂXGŐĄKÄĹĹ!++ «V­B||<Ľ˝˝‰}űöuřEřž%ΓĂóš'•J%öíۇ &ŔÇÇ_~ů%VŻ^Ť¬¬,lذAxDcĚ<<Ń]k`` öěŮśś¬[·)))1bĽĽĽđöŰo#55őiÇůDô‹‚üÚĹAž•AÁ×ףGŹFhh¨°x kźRSS‘śśŚ={öŕŢ˝{ČÉÉÁáÇÝ!Wl.((ŔöíŰŠ^˝za÷îÝ@JJ ľ˙ţ{Lť:•ĆěąÔĄK¬]»8xđ lmm1ţ|tíÚŻżţ:Ž=j6+_sždméyĘ“µµµřúëŻ1}út¸şşbÁ‚Ëĺ8xđ 233Ă cĆĚŐÓŠNOO§ŘŘXňőő%Ô»woZľ|9}űí·¤R©žÖiZ-''GřŚťťmÚ´I´(‰9ŠŠ"zăŤ7D‹•°öéîÝ»4qâD˛··'+++ň÷÷§µk׊ž˝Ůžét:JIIˇM›6ѨQŁČŇŇ’śśśhîÜątöěYžFÍX3ĘËËiĎž=4věX˛´´¤Îť;ÓŚ3čóĎ?§ĽĽ<“ÄÄy’µµŽž'óňňhďŢ˝4}útR(diiIăĆŤŁüăT^^nęđc­$!jôą§ 99GŽABB’““!“ÉޱcÇb„ đóó{Ú§dŚ=%%%8}ú4€üü|xyy!""‘‘‘7nlllL&cíJ~~>ľţúk$$$ŕĚ™3¨®®FPP"""0nÜ8 :ÖÖÖ¦“1Ö‚şş:\Ľx§NťÂ©S§šš ą\ŽŃŁG#""QQQ->›1f~žIąˇââbś9sFtíáá°°0„††bčС „T*}–a0ĆZ!##‰‰‰HJJÂĄK—păĆ îŕběję;$$C‡Ehh(O-fĚLTTT )) IIIHLLÄŹ?ţ(ęŕ?~ő^Ţż_ôyQQ‘h?™LgggtíÚ]»vÝtëÖMxíääGGG( nř1ŤFňňráGźĐő ď‹‹‹QPP |'^O.—ĂĂĂ®®®ÂŤcŹ=DŁ/AßáĐ\ntrr2xĎÓčc7Ű‘†I®áë¦z„˙%ʆŤÍ†ŤI}­­­55-//GSż ŹgLĂF¸1öööJĄÂ{©T*ڏ»I±µµ¦"+ H$ŘÚÚÂÖÖ …BřÜÉÉI8wă^¨1Ć:.c3†*** V«Q]]ŤĘĘJ¨ŐjˇŃX__/Ę}•••Đjµ¨ŻŻ“Ć:gőZęŐ7^Ťiߌ±±±A§NťDeúܧďěţ—K---…U™ő s}^m<ăL&“t¨·Ô!ÎcĎn 3ĆcŚ1ĆcxHŤ1ĆcŚ1Ć7cŚ1ĆcŚ1Ü@fŚ1ĆcŚ1Ćp™1ĆcŚ1ĆükyÖLi!IEND®B`‚nipype-0.11.0/doc/users/images/proc2subj2fwhm.png000066400000000000000000001573251257611314500216550ustar00rootroot00000000000000‰PNG  IHDRű‹ĹŢcbKGD˙˙˙ ˝§“ IDATxśěÝyXŤé˙đwĺh—ĄĐJ+ĄěJd«„A”mĆޢżË0cŚ™/Ă0c73˘”u3”,CFa˛TÖ‘­–ŠŇ®:Ď:—& ŁzZŢŻë:×ç<ťű}Ž.s?çsîGNDDDDDDDDDDDD/‘;Ő=, Q, QMÄ@DD5ëŮłg(..FQQrrr ňňňPVVV鸊ç^¦®®Ž&M*˙Ż˘yóć““šš”””ЬY3¨©©A"‘Ôř{!""""Ş)ĄĄĄČĎĎÇóçĎQ\\Śüü|‚€śśśJÇ•••!//ŻŇcrrrhŢĽyĄÇ$ ÔÔÔdĎ)++CII -Z´¨ń÷BDDT]X@ "ޤR)?~Ś´´4<~üŮŮŮČÎÎĆÓ§O‘ťťŤĚĚLŮýüüüJEÚ˘  €fÍšAUUjjjhŐŞ•ěÖ˛eK´jŐ ZZZhٲ%´´´ «« ]]](**ÖZF""""jřŠ‹‹‘‘‘ôôtŮ<933łĘşbî\PP€çĎźŁĽĽĽÖ2ľ\Lxy©Yeݶm[čęę˘M›6—çFDDT»ä„.7%"˘ZWPP€ÄÄDÜ»wIIIHKKCzz:222’’‚ÇŹŁ´´TvĽ˛˛rĄ/č_>ŮPSSCóć͡¤¤•J÷544 ///;ayŮ«ş ţŮ• •J‘›› ČËËCqq1ňňň*ÝĎĎĎG~~~•“ł¬¬,dggË~ľ‚––ttt ŻŻčęęÂČČFFF011AëÖ­«űă&"""˘zěÉ“'˛ysRR’lŢśššŠŚŚ dffV:^CCŁŇó/Aݦ¦555¨««CII ęęę•îWüüË_ÜżŞŰ ˘{áe z*ćĐ………(..FNNNĄűyyyxúô)˛˛˛••Uiýň‚ ‰D‚¶mŰVš7ŔĐĐĆĆĆ011ŠŠJuÜDDÔȱ€@DTK¤R)’’’¸¸8ŮIOBB=z———ťTśčëëC[[úúú˛•GőůÄ ¬¬ ™™™UNô^.šÜżĹĹĹ€fÍšÁŘŘXvRÔˇCXYYˇS§NUŠ DDDDÔ0!..111ŹŹ—-¶ILL”m¤¤¤CCCŮĽYOOŻĘÂ--­*‹dę“ÂÂB`bb‚Îť;ĂĘĘ VVVčŃŁôőőĹŽODDDDď %%WŻ^ĹÍ›7ŘŘXÜ»wĺĺĺPSS™™™lÎ\1o666†®®.äääÄŽ/ş’’Üż‰‰‰HHH¨4‡NJJByy9TUUŃ©S'ŮÜąsçÎčŃŁ‡¬Ë‚čuX@ "zOĺĺĺ‹‹CTT"""péŇ%ÄĹĹA*•B[[[6A·˛˛‚ĄĄ%:uęÄ}˙ß HJJBll¬ě#;ÉÔŃŃŤŤ z÷î ôěŮŞŞŞbÇ&""""ü˝uçĺË—%»edd@AA¦¦¦˛ąłĄĄ%:wî CCC ŢCqq1âââ+[ŘtóćM<|ř 077‡ŤŤ lmmaccsss(((›ęŢ‘ ¸qăBCC† . //˛/­­­­amm ---±ă6ĹĹŸ~ý:˘˘˘péŇ%DDDŕÁPPP@—.]ŕččŘŮŮŐë- ę“ÂÂBś;waaa ĂŤ7P^^CCCôîÝÖÖÖčÝ»7şvíĘí)kŃ“'OŞrrssˇ®®;;;888ŔŃŃť;wf‡¨‘cč-¤¦¦"$$aaa8}ú4233a``GGGôďßÖÖÖčر#'×uĚăÇŹ…‹/",, ×®]D"Aź>}ŕŕŕ'''ôěŮ“oDDDDŐD\ąrţů'BCC˛˛2tëÖ ŽŽŽčÓ§lllĐşuk±ŁŇKAŔť;w…đđp„††"55ZZZppp€† ===±ŁQ-cč5âăă„C‡áĘ•+hѢ([Énff&vDzGOź>Ĺ™3g†ĐĐP$$$@OOŁGʆ‹‹ ú÷ď_Ż/˛GDDD$†˛˛2üő×_8tč>Ś´´4ššÂŃŃŽŽŽ8p Z¶l)vLzGwďŢ•u]ź9s999čŮł'\]]áââ‚:‘j DD/ILLÄîÝ»qŕŔÜľ}›_.7pńńń8tč‚‚‚pĺĘ´lŮÎÎÎ2e ČÎ"""˘×§OźĆ/żü‚ŁGŹâéÓ§čŮł'ĆŚŃŁGóË妬¬ ááá ’‰,,,0věXLť:ĆĆĆbG$"˘Â5zĹĹĹ ÄŽ;púôičëë㣏>Â1c¸˝M#’ššŠŕŕ`üú므±±1ÜÝÝ1}útčččʍNČČČŔöí۱sçN$&&ÂÎÎ&LŔčŃŁą˝M#!.]ş„C‡aßľ}HOO‡˝˝=ÜÜÜ0fĚ(**Š‘Ş DÔhedd`ýúőرcňňň0jÔ(¸ąąačС——;‰čÎť;ضm~ůĺdggcřđářâ‹/ЧO±Ł‰âüůóX˝z5Ž?ŽV­ZaÚ´ipwwGÇŽĹŽF"*//ÇÉ“'€ŁGŹB]]îîî?>´µµĹŽGDDŐ€"jt±zőjěÚµ ššš;w.¦NťĘ ąQĄĄĄ8|ř06mÚ„óçĎcŔ€XĽx1śśśÄŽFDDDT+BBB°jŐ*„‡‡Ł_ż~;w.FŽ ‰D"v4Şcž˙üsŠŤŢ—ŘQŁńřńcŮ*©°°0üôÓOHJJ‚ X< W’H$;v,Îť;‡żţú ĘĘĘ2d¬­­qńâE±ăŐóçĎŁWŻ^řŕ ŞŞŠđđp„‡‡ĂŐŐ•ĹzĄÖ­[cáÂ…HLLĦM›đçźÂĚĚ xňä‰Řńč?bĽ˛˛2üôÓO˛ÂÁÎť;Ź3f iÓ¦bÇŁz˘˙ţ8qâ®\ą‚ćÍ›ĂÎÎîîîČĚĚ;Qµyňä ¦OźŽţýűŁU«V¸ző*Ž?Ž~ýú‰Ťę EEEx{{#>>Ű·oÇ©S§ĐˇClŢĽR©TěxDDôޏ…5hwîÜÁĉqëÖ-Ěź?K–,ŞŞŞŘ±¨8pŕćĎźŹüü|üüóĎ4i’Ř‘ŢËž={đé§ź˘YłfXż~=ĆŚ#v$jňóó±bĹ lذ–––Ř·o:tč v,""zKě@ ˘ëСC°±±˛˛2nܸU«V±x@Őfܸq¸}ű6ÜÜÜ0eĘĚ™3ĄĄĄbÇ""""zgĄĄĄřä“O0mÚ4xxxŕÖ­[,PµQSSĂ÷ߏččh(**ÂÚÚGŽ;˝%¨Aúć›o0fĚLť:gĎžEÇŽĹŽD ššÖŻ_ŹbÇŽpppŔÓ§OĹŽEDDDôÖ˛˛˛0hĐ ěŢ˝X»v-ÔÔÔÄŽE ąą9Ξ=‹É“'côčŃřß˙ţ'v$""z ÜÂśE‹aÆ ضm¦Nť*vj$nßľŤŃŁGC]]aaaĐĐĐ;ŃĺććbĐ A(((ŔáÇąč†jÍÎť;áí퍅 bĹŠbÇ!"˘7`”;vŕăŹ?FPP†.vjd2220`Ŕ››ăđáĂ““;Ń+ ‚€#F 11gĎžE۶mĹŽDŤĚáÇ1~üx.ü""Şă¸…5©©©řôÓO±qăĆ/„‡‡côčŃ““CÓ¦MŃ·o_ŘŘŘ }űöpttÄŃŁG«}ĚĚĚLěÚµ &LŔäÉ“«üđCÖÚąž? :'Nśđ÷č–/_ŽĺË—ĂĎĎ3f̨¶ńž>}Š[·nˇ˙ţ>|8Ž;Véůľ}űBNNçĎźŻ¶1몼Ľ<4kÖ  ŔŮłg+=‚" ŕ•źSmŘ˝{7ćĎźŹ{÷îˇyóćµ>>Ń›<{ö ¦¦¦Ř¸qă+ż\Ż ś;‹çMsgoooŘ·o_­ŚGDDď†"jaff†ČČHôęŐ«ÖĆ•““{ĺ ‰©©)¤R)kmĚĆćMźCyy9š4i"Úç$•JajjŠ™3gbÁ‚µ>>Ń›¬]»[·nĹÝ»w!/_{pî,žW}ׯ_G÷îÝkkkŮăË–-ĂŢ˝{_+[rFDDŔÎÎ 022ŞńńčÝp #"j‚‚‚ ŻŻ_«Ĺ7i×®ŇŇŇÄŽŃh)((:ľĽĽţřcXYYANN:::°łłĂť;wpđŕALš4 “'OF\\ ŞŞŠ‘#G˘  ŕµcĆĆĆbŢĽyX˝z5¬­­Ń±cG”––"$$îîî2e BCCŃłgO(**˘gĎž˛ýVĄR)Îť;oooLť:W®\Aż~ý ¤¤„!C† °°ˇˇˇčÖ­”””ŕää„ÜÜÜýę’®]»âúőëbÇ """ŞâĆŤčŇĄ‹Ř1pî,ćÜůÜąs011©Ňe`bb8sćĚżľFuéŢ˝;˘ŁŁkm<""zQŕěě,Lś8±ÖÇ >\AJĄBLLŚŕää$¨«« gĎž­těÇ…Ö­[ aaa‚ Bll¬ '''řůůÉŽY»v­Đ­[7Ůźmll„^˝z˝vLA„/^gĎžŚŤŤ…Wýłţé§ź ť:uA’““999ŮÂďż˙.ŚŤŤ…%K–/^ćĚ™#VŻ^ýÚ÷Ţąsg!++KA(,,† &äĺĺ aaaAGGGXż~˝#lŢĽYPRRZ´h!<|řPČĚĚvíÚ%Úµk'lÝşUČÍÍV®\)>řŕaíÚµBNNްaĂ€°rĺĘ7~˙ôoĎ×´ŕŕ`€P\\,Z"""˘***‡®ő±9w®[sg555ÁŃѱJÖŠß‘Ú<żú裏„QŁFŐÚxDDôöŘ@D B۶mńčŃ#QĆŽ€ŤŤ TTTеkW 0wďŢĹ€*·bĹ ´lŮöööKKK™™UZIUTT„¶mŰĘţ¬©©ůŻ«¨$  €:Ľňů]»vAWW``` ÜĽy ˘˘‚±cÇŚŤŤ±|ůrŘÚÚâ›oľ\ľ|ůµăŢąsGÖÖ¬¬¬ŚąsçBMMMöţ¬¬¬0oŢţřcŮM[[Íš5“łdÉ?~@RRJJJŢ*Çë.p¦¤¤„””ŮźuuuŃľ}ű*?'‘HdʵlŮŔß'Ż3xđ`Ś?3fĚ@jj*śśś*=ߤI“Jž0a€ż[ć_öňő Z´hQĺgŐÔÔÔî Lu‡ťťťŘ1ŞčׯÎť;'ĘŘś;×ťąłŞŞ*ĘËË«<^ZZ PWW˙×ר%%%¸téú÷ď_+ăŃ»a„ŃŁGŁI“&Řżż(ăËËËă—_~A«V­°zőęWîš‘‘ccclÝşUv;sć .^ĽXé8Lź>C† ‘‘Ń{g[´hîܹ˗/C*•")) K–,yď×Ýłgáďď333¬^˝úŤÇkiiř{××yÓĹŹßôsuMVV‚áćć&v"""˘*ÜÝÝŚśśQĆçÜąn̝۷o˙Ęߊë'ššţëkT‡ß~ű ĘĘĘ=zt­ŚGDDď†"jÔÔÔ°hŃ",]şĎź?%ŽŽ¶oß©TŠ)S¦ŕéÓ§•žoŢĽ9âââ BĄÇA@~~>€ż[µ—/_Žť;wBOOŻZrÍť;_ý5V¬Xoľů+W®”µ@ż555śűě3!::Zöü­[·eeeA"‘_|ń…PTT$‚ ś8qB°´´š6m*ţţţ•^wűö킺şşĐ±cG!$$DTTT'''!22R7ož@hѢ…°{÷nˇ¸¸XČËËüýý…fÍš „E‹ iii˛×üć›oEEE@ĄŰäÉ“…üü|á‹/ľ­Zµ~űí7!//O?ľ@ĐĐĐŽ9"{-aٲe‚ ÁĆĆFX±b…ŕââ"|őŐWByyyĄç<<<„ńăÇ 666ÂŞU«©T*‚ dff K—.šššÂŃŁG…śśańâĹAUUU8xđ ““#;®yóćÂŢ˝{…®®®A"‘_~ůĄpőęUYĆ .ČŢ“¦¦¦°gĎ!11±š*“JĄÂš5kańâĹ5:QuZ´h‘ФIaíÚµ56çÎuwî\^^.|˙ý÷„ „ůóç “'OŽ=ZÍż•=}úT6l ¦¦&ś?ľFÇ""˘÷''µĽ<“¨\˝z®®®hÚ´)‚‚‚`ee%v$Q”••á믿†łłłl…SYY"""0dČÖȸrrr>|8Ž;V#Ż_—äççĂÓÓAAAX»v->ýôS±#˝“M›6aÁ‚;v,üýýe[56ś;׼¸şş˘¬¬ AAAčŢ˝»Ř‘č_đDÔ őčŃW®\ľľ>lmm±jŐ*Y›rc2věX\Ľx±R{t“&M ŁŁ###“5 'OžD÷îÝqöěY„††˛x@DDDőŇś9sŠÓ§OŁ{÷î8uę”Ř‘DÁąsÍyńâV®\ [[[´oßW®\ań€¨ž`,---üůçźXĽx1–/_ŽÎť;7ş“ˇččh\˝zŰ·oGBBRRR„É“'cëÖ­52fiiiĄ˙6D)))3f † +++\»v ýű÷;Ń6`Ŕ\»v ť:u‚““ĆŤ‡ÔÔT±cŐ*ÎťkĆÉ“'aii‰•+WbÉ’% ¦¦¦Ř±č-±€@D Z“&M°xńbÜąsprrÂČ‘#)v´ZqňäI 8sçÎE§Nť0tčP\ąrÁÁÁ°łł«öńRSSńĹ_.^Ľ5kÖ 99ąÚÇËDZpáB››#66!!! „ŽŽŽŘŃŢ›®®.‚‚‚püřqDGGĂÂÂ_|ń?~,v´ZÁąsőŠŔ#d‹nâââđĺ—_ň‚ÉDDő Ż@DŤĘÉ“'±lŮ2DDD`Đ AXĽx1ĹŽEuÜýű÷±fÍěر-Z´ŔÂ… 1{öl4mÚTěhDDDD5˘¤¤?ýôÖ­[‡śśxxx`Á‚hßľ˝ŘѨŽ;uęV®\‰łgϢOź>Xşt),v,""úŹŘ@DŤĘ!CpńâEś9sMš4ÁŕÁŃŁGřúú"77WěxT‡HĄRś8qăÇŹ‡™™BBB°aĂÜżóćÍcń€4EEE,X°÷ďßÇşuëđÇŔĚĚ ăÇŹÇÉ“'!•JĹŽHuHnn.¶lŮ‚îÝ»ĂÉÉ M›6ĹŮłgqáÂę9v QŁvůňeřřřŕŕÁ(//ÇřńăáîîŽ~ýúANNNěx$‚ääd`×®]HMMĹŔáĺĺ…±cDzݚ­˛˛28pľľľ‡ľľ>ÜÜÜŕîî±ă‘AŔąsçŕďďŹBAAăĆŤĂěٳѣG±ăQ5a@^^~ýőWěÜąhßľ=\\\ŕâ₾}űB^ž [ YRRŚČČH´mŰnnnpss±±±Řńę”ÄÄDřűűc÷îÝxôčz÷î WWW¸¸¸ŔČČHěxTĘËËqńâEáСCHNN†­­-ÜÝÝńá‡BMMMěDDTÍX@ "ú‡[·nÉ&Äׯ_G›6m0jÔ(Ś=ýű÷‡ŞŞŞŘé=IĄRDGGăرc ÂŤ7жm[Ś5 ®®®ppp€‚‚‚Ř1‰ę´ňňr„……!00GŽÁŁGŹĐ­[7Ś=#FŚ@×®]ą§(((@xx8‚Ś'Ož [·npuuĹرcѱcG±#Q bč ’’’Ś   DFFBAA¶¶¶°··‡ŁŁ#¬­­ą­M=‘€Ó§O#44gÎśAvv6 eť&}úôá .Ń$•JqáÂăСC¸˙>4551hĐ 888ŔÁÁ&&&bǤ·PVV†¨¨(„……!,, ‘‘‘(//ŻÔibhh(vL""Ş%, ˝ĄgĎžáěŮł Chh(âă㡮®Žľ}űÂÚÚ666čÝ»7Z¶l)vÔFݤ¤ׯ_GTT˘˘˘pţüy¤¦¦V:‰uttäöDDDDD5äŢ˝{˛/ Oź>Ťěěl´k×}úôAďŢ˝acc®]»BQQQ쨍^vv6"##qéŇ%DEEáÂ… ČĎχąą9ěííáŕŕ€AˇyóćbG%""°€@DôĄ§§#44ááኊÂíŰ·!•JaffX[[ĂĘĘ VVV,*Ô ’’ÄĹĹáćÍ›¸ző*"##qýúuĽxńm۶…­­-úôé{{{:çăô IDAT¶Ń‰ bűČÓ§OăÂ… ¸xń"žnßľŤ›7o"66±±±HHH@YYTTTеkWôíŰfffŘ·o¤R)LMMáââÂn""""‘ČËËŁ[·nČËËĂőëב›› uuuôë×:t@TT¶mۆÂÂB4iŇfff•ćÎ;v„ˇˇ! ď ''÷îÝ“-´ąqănŢĽ‰ŚŚ @›6mĐłgOdeeˇeË–đđđŔ§ź~ ===‘“Q]Ă"˘˙ŕúőëđőőĹľ}űPVV†qăĆÁËË }űö­tÜ“'Od+|nŢĽ‰ÄĹš°° ©© ŔÔÔĆĆĆ044„Ú¶mŰ讯™™‰‡")) ÷îݓݑššŠňňr(((ŔŘŘXvBiii‰.]şŔČȨRwAZZŕďďŹôôt8::ÂŰŰÎÎÎH$"ľK"""˘Ć#;;»ví¶mŰpçÎŘŘŘŔËË &L€ŞŞŞě¸ňňr$%%!&&F¶X$&&III˛9 LLL`dd$›CA[[ZZZ"ľËÚWZZŠÇŹ#%%E6wNLL”Íźł˛˛ŞŞŞ°°°Íť+:¤[·n HMMĹÖ­[€¬¬,8;;cÖ¬Yppp€śśśo‘ęŢR~~>~űí7řúúâňĺË077‡··7¦L™ňN[IĄRÜż_6ÉŻč'$$ )) %%%ţ^©Ő¦MčééA[[[VTĐÖÖF«V­ŞÜję­ż—ÜÜ\dff";;Oź>Evv6˛˛˛ššŠ‡"55ČČČ@qq1€żß»ľľ~Ą“Ă— -ĘĘĘo=~yy9Ž?___„„„@KK îîîđôôäĹßj€ ‡źźˇ¤¤„I“&ÁËË ]şty§×***BBBBĄĹ%·ôôtHĄR€’’ttt ««+›?ëëëCSSłŇśYSS5ń¶ß[YY™lľüňíáÇ•ćÍéééxüř±ě˝+**ÂČȦ¦¦•ćÍĆĆĆhßľý[máůâĹ ÂÇÇçĎźG‡0sćLLź>˝Î~^DDT;X@ "ú7nÜ€źźöîÝ‹ââbŚ;ŢŢŢčׯ_µŹ%•J‘žž.űr=-- éééČČČť0ňňňH$PSSşş:””” ®®^é~łfÍ*Í—_ľ‰y݇ÜÜ\ěÚµ >>>ŹŹGßľ}1{öl¸şşÖČb""Ş›X@ "zÉÍ›7áçç‡Ý»wُ¸...đööƀ͠rrrŘ»w/&Nś(v”ZńŕÁl۶ ;věŔăÇŹ1lŘ0xyyařđáuv[(""""±Őv·A]´oß>Lš4 ýkApúôiřřřŕđáĂĐÔÔ„‡‡Ľ˝˝ąř†¨¨ľ7"˘zި¨»wť¬¬¬pâÄ |őŐWHIIÁŻżţŠ6šâAcÔľ}{|÷ÝwHNNĆďż˙ŽŇŇR¸¸¸ }űöXşt)ŇŇŇÄŽHDDDT'‚€żţú “&M‚®®.ľýö[ŘŰŰ#::‘‘‘pwwo4ĹĆDNN Ä0cĆ lßľFFFpqqÁźţŮŕ‹(DDŤ DÔhÝľ}sçÎ…žž<==ˇŁŁĐĐPÜ˝{ .DëÖ­ĹŽHµH"‘`Ě18yň$îŢ˝‹I“&aË–-hßľ=śťťńÇ ĽĽ\ěDDDDµ.;;ëׯ‡……ÄÄDřřř ==›7o®3[QÍÓÓÓĂňĺË‘’’‚_~ůŮŮŮ2d:věŤ7ʶ}""˘†"jTJJJ°oß>ôďß8zô(.\ÔÔTüţűďppp`·ÁŘŘß˙=RSS±oß>`äČ‘022ÂňĺË‘‘‘!vD"""˘Ĺnz‰D‚?üáá቉˝˝=ľţúkčęębĆŚŽŽ;"U¨QŹŹÇ‚  ««‹éÓ§CKK 'OžDBB-Z„6mÚ‘ę ¦M›büřń C||<ĆŹŹź~ú íÚµ‹‹ BBB •JĹŽIDDDTmŘm@ďĘĘĘ [¶lAZZ~řá\¸pÝşuCź>}°wď^”””‘Ţ DÔ`•””`˙ţý°··‡ąą91oŢ<$''#00NNN—ç?ôvLMM±fͤ¦¦b÷îÝČÉÉÁ|ccc¬\ąŹ=;"ŃÂnŞřż˙ű?Üşu aaaĐŃŃÁôéÓa``€Ĺ‹#99YěDDôđ›3"jpîÝ»‡Ď?˙úč#ś9sqqqpuuĹşuë```€±cÇâÔ©SěJ ""˘zÝTäää`ooŹâÁđööĆÎť;allŚQŁFáäÉ“Ľč2Q=Â5ĄĄĄ8pŕaff†ß~ű łgĎFJJ :„aÆ±Ű€Ş]ÇŽ±nÝ:ddd`űöíxňä śśś`ff†~řOž<;"Q%ě6 ÚTń;–śśŚ˝{÷"77C‡E‡°~ýz<{öLěDDô/řmŐkIIIřňË/ˇŻŻŹŹ>ú***8rä’’’đÍ7ß@GGGěÔ(**bňäÉÇ­[·0bÄüđĂĐ××Ç„ púôi®˛""""Q±Ű€Ä$‘H0aÂś={±±±pttÄŇĄKˇ§§OOO\»vMěDDô, Q˝SZZŠ   2¦¦¦ŘłgĽ˝˝q˙ţ}9r#FŚ€‚‚‚Ř1©‘˛°°ŔĆŤ‘žžŽm۶!-- čСÖ®]‹ĚĚL±#Q#ÁnŞ‹,--áăă´´4¬^˝čŃŁlmm±gĎ^t™¨ŽaęŤ`É’%h׮ƍ!99Ë–-ľľľŘ‰d”••1uęT\¸p±±±2dV¬X}}}Lś8gĎžeWŐvP}ЬY3Ěž=·nÝÂéÓ§ˇ§§čëëcѢExđŕ؉, QW^^Žŕŕ`|đÁ066ĆŽ;ŕî¤$?~ŁFŤb·Őy–––řé§ź‘‘-[¶ ))  ‚……ÖŻ_ʧOźŠ‘ę9vP}6hĐ 8p<Ŕ¬Ył°gĎĂŮŮ!!!JĄbG$"j´X@ ˘:)55˙űß˙Đ®];Ś3R©T6ˇ\±bÚµk'vD˘w¦˘˘777DFFâúőë4h–-[L™2çÎť;"Ő3ě6 †DGGK—.Ű˙~äĺĺaذačСÖ­[Ç…7DD"`ęŚňňr;v #GŽ„ˇˇ!|}}1uęT$$$ $$®®®H$bÇ$Ş]»v•ťÜ˙üóϸsçú÷ďŹNť:aÓ¦Mxöě™Ř‰¨Žb·5t‰ăĆŤĂ™3gpëÖ-899aٲe˛mŽ®^˝*vD"˘F"]zz:ľýö[ÂŮŮĹĹĹŘż?RSS±rĺJ‰‘¨Ć¨©©ÁÓÓ—/_ĆŐ«Wagg‡%K–@WWÓ¦MĂŋŎHDDDu» ¨1˛°°ŔćÍ›‘žžŽuëÖ!** ={ö„ŤŤ vďŢÍ‹.Ő0HR©'NśŔčŃŁŃ®];lŢĽ}ôîŢ˝‹S§Naěرě6 F§{÷îđőőEFF6lŘ€ŘŘXôíŰVVVŘĽy3rssĹŽHDDDµŚÝDSWWÇĚ™3qóćMś9síŰ·‡§§'ôôôđĹ_ŕţýűbG$"jX@ ˘Z•‘‘ďľűFFF>|8ž?Ž˝{÷"%%?üđLLLÄŽH$:uuux{{ăÚµk¸télll°hŃ"čččŔĂĂQQQbG$""˘Ćn˘×8p ~űí7$''ă˙ţď˙°wď^`Ä8qâ/şLDTŤX@ ˘'•JqňäIŚ3í۷dž 0věXÜąs§OźĆ„  ¨¨(vL˘:©WŻ^đ÷÷GZZÖ¬Y«WŻ˘wďŢčÖ­¶lŮ‚çĎź‹‘Ş » ŢŤ¶¶6ţ÷ż˙áţýűřý÷ßQXXáÇĂÔÔk×®Evv¶Ř‰ę=¨Ć<~ü«V­‚©©)†Ь¬,ěÜąéééX»v-ĚĚĚÄŽHTohhh`Ö¬YŽŽFDDşuë†Ď>ű şşş1c®\ą"vD"""úŹŘm@ô~$ ĆŚÓ§OăćÍ›řŕ°|ůrčëëĂÍÍ —/_;"Q˝ĹU+AŠqăĆA__k×®…łł3âââđ×_aâĉě6 zO˝{÷ĆöíŰńđáC¬\ą‘‘‘čŐ«zôč???äçç‹‘ţ» j†……~úé'ŮE—Ż^˝ kkkŘŘŘ`çÎť(..;"Q˝ÂU‹'Ož`őęŐ033ĂŕÁńđáC -- 6l€ąąąŘ‰ |ňÉ'ŤŤĹůóçaii‰ąsçBGGü1®_ż.vD"""úvŐ555Ěś9111ř믿`hh///čééaáÂ…HJJ;"Q˝Ŕýg‚ ŕĚ™3ř裏```€U«Vaذa¸yó&Îź?Ź)S¦@YYYěDŤBßľ}±k×.¤ĄĄaůňĺG÷îÝammŤ€€v%‰ÝDâęßż?öďߏ””Ě™3ű÷©)†Ž?ţř]&"zčťeggcÝşu077‡˝˝=—.];"QťÁ˝ŃÓ§O±qăFXXX`Ŕ€¸wď6oŢ,[5Őąsg±#ŃżhŐŞ>űě3Üľ}§OźFűöí1sćLhkkăÓO?ĹÍ›7ĹŽHDDTď±Ű€¨~ęر#~üńG¤ĄĄaăĆŤ¸~ý:lllĐ«W/lßľť‹n¨Ńc^éÂ… :u*ôôôđÍ7ß`Ŕ€¸ví˘˘˘ŕááÁUSDőśś „_ý)))řꫯpâÄ XYYÁÎÎ{öěá Ń;`·QᦦoooܸqçÎť‰‰ fÎś)»čň˝{÷ÄŽHD$ H&''?ýô,--agg‡[·naÓ¦MČČČŔ–-[Đ­[7±#Q5iÝş5.\»wď"44:::đđđ€žžćÍ›‡Ű·o‹‘¨Îb·QĂfgg'[t3ţ|ěßż:tŔ°aĂpěŘ1^t™‘‘‘pssŽŽ/^ [[[\ľ|WŻ^ĹŚ3 ¦¦&vD"Ş!rrrpppŔďż˙ŽÔÔT,\¸GŽ‘m[¶oß>”””“Htě6 j|Ú´iŻľú <ŔÁQVVgggă‡~ŕE—‰¨Q`¨‘ĘÍÍ…ŹŹşté[[[DGGcÝşuHOOǶmŰĐłgO±#Q-kÓ¦ -Z„„„ś}:tuu±`ÁÄÇÇ‹‘¨Ö±Ű€ŕââ‚S§NáöíŰ5jV­Z===Lť:QQQbG$"Ş1, 52—/_†§§'tuu±páBôěŮ‘‘‘¸~ý:fÎś‰fÍš‰‘D&//'''"99óćÍC`` ĚÍÍaooŹýű÷ł+4vŃëtčĐ7nDzz:~üńGÄĆƢwďŢčŮł'xM1"jpX@ jňňňŕëë‹îÝ»ĂÚÚ—.]Â?ü€ŚŚ ŔĆĆFěDTGikk㫯ľBbb"ţřăhhh`ňäÉ000Ŕçź΋ÉQÂn"z[ŞŞŞđňňÂőë×qţüy™™aöěŮĐŐŐĹgź}†„„±#U °k×®ÁŰŰ:::7o:wîŚ . &&łgφ†††Ř‰¨ž——ǰaĂpčĐ!¤¤¤`öěŮŘż?ĚĚĚŕčč ´´TěDDDďŚÝDôľúöí‹}űö!99 ,ŔÁѱcG :GŽAyyąŘ‰ţ39A±CQőÉĎĎÇţýűáëë‹+W®ŔÂÂŢŢŢ2e Z´h!v<ŞcbbbŞ|éŰłgO¬X±C‡­ôxÇŽyňL•”——ăĉđőőʼn' ©© 777Ě1FFFbÇ#""zŁěělěÚµ ۶mĂť;w`cc///L0sŞ˘  wîÜ©ôXHH–,Y‚+W®Tz\"‘ sçεŹęňňr=z[¶lÁ©S§Đ®];xyyÁÓÓZZZbÇ#"z', 5ŃŃŃđóóĂŢ˝{ńâĹ Ś;ŢŢްłł;Őa...~«csssyŤ z­ÔÔTřűű# >„ŁŁ#Ľ˝˝1räHH$±ăř»Ű <<~~~ „’’&Mš///nODoôüůó·îŕ=z4:Tɨľ¸{÷.¶lŮ‚ť;w˘¨¨ăƍìYł`kk+v4"˘·Â-Śę±ÂÂBlßľ˝{÷F·nÝpćĚ,]şéééŘłg‹ôŻ>üđĂ=¦â‚ş,Đ›čëëcٲeHNNFPP0nÜ8´k×K–,ÁÄŽHDDŤŻm@ď«Yłfprr‚ĽüżŤň6slj<ĚḚ̌aä§§ăçźĆÍ›7ѧOtďŢţţţ(,,;"ѱ¨ŠŤŤ…ŻŻ/~ůĺĂŐŐ^^^0`äääÄŽGőHaa!455QTTôÚcäää—ZLF Arr2¶mۆ;vŕŃŁG2dĽ˝˝1bÄ(((Ź8vPu;tčĆŚ7}Ť˘¬¬Ś¬¬,¨¨¨Ôb2Şo"""°yóf/‘H0aÂěŮł§–“Q}•™™ řúú"%%ƬYł¸ŕ†ęnaDTÇĹĹĹaÎś9ĐŐŐ…——ôôô†řřx,X°€Ĺzo'N|mń@"‘`ěر,Đ{‘H$puuEHH0uęTřúúÂĐĐ#GŽÄ±cÇP^^.vL""ŞÇAŔ_ý…I“&AWWß~ű-ěííŤČČH¸»»łx@ďMQQcÇŽ}íőťJKK1qâÄZNEő™––ľüňK$&&"88rrrpqq‘‘V®\‰'Ož‘DuQII 8???ś;wĆĆĆ1cÜÜÜĐşuk±ăQSZZ ---äććľňů?˙ü®ĺTÔĐ•––âđáĂđőőEXXôôôŕéé čęꊏę vPm;uęśśś^ůś††233_[` z Řşu+věŘÂÂBŚ3łgĎFź>}ÄŽFDŤ DuČť;w°mŰ6ěÜąyyypvv†··7Ţęb]D˙Ő¬Yłŕďď_ĄˇU«Vxüř1Űg©FÝ»wOöo_vv6FŚooo 2„˙ö5ůůůřůçź±hѢ·:ž×6 1•——ŁM›6ČÎήô¸D"§§'|||DJF Maa!~ýőWřřřŕÚµkčÚµ+fÍš…‰'˛@JDµŠgĺD"+))ÁŻżţŠAÁ‡Âgź}†””|¦M›ňÚT§ ‚¤ĄĄš6mŠ9sć`őęŐ"'ŁĆB*•âŹ?ţ€ŹŹţüóOčęęÂŰŰžžžŻś#§¦¦ÂŔŔ`ccăÇŹŁeË–µ›ę).s&zO~~~9r$äĺĺ!‘HŕççWĺÄÄD,Z´úúú˛ý Ź=Šű÷ďcÉ’%,Pť0qâDYń@"‘`Ú´i,č1qâDüő×_‹‹łł3Ö®] }}}Ś7ˇˇˇřçZ¨¨(äçç|||ŕâ₢˘"1âŃ+ěŢ˝C† Aaaˇ¬xĎž=Ă÷ߏI“&AWWß~ű-ěííŤČČH¸»»łx@u‚śś¦M›&ŰĆčŋܾj•ĽĽ>ăÇŹÇúőëa``€‰'âüůó•Ž÷óó“ýľ^»v ˝{÷FJJŠщ¨bŃ$ľúę«*mÖxüř1äĺĺqäČřúú",, :::đđđ€§§'ôôôDJMôf¦¦¦¸wď &&VVV"'"ŞŞ¨¨„ŻŻ/.\¸xyyaÚ´ihÝş5¦OźŽ}űöÉ®ëѤItéŇ'Nś€–––Č鉷ożýK—.­RüţŢ[^"‘ K—.ě6 :/66ť;wđ÷őśDNDŤ]QQ‘ě˘ËWŻţ?{çŐµµńw†ŢAPi‚""‘f,ŤDŚM0ę5ąńFcŞŢÄ›r5UobL÷zŤh5QŁ‘ÁBGiŇĄwYß~sÂH”™3Ŕţ=Ď<3sćĚŮ딵ßsöZ{ď…ÝoĐ IDATD¸ąąá…^Ŕ’%K`gg'3ń·ššŚŚŚpöěYöĚÇ`0 0AKK V­Z…B"‘Čü&Śřřx”••aîÜąxţůçȆĐ`(=|đ6oŢĚ‚†ÔÔT|÷ÝwŘ·oššš®7Ť555™™áěŮł7nOÖ2 ĆĐĄ­­ Ď?˙<öîÝŰeđ@Š@ @vv6lllhńpH“o¶nÝŠ·ß~›os Ž+W®`×®]8xđ „B!ššš:Ő˝ŞŞŞĐÔÔDDDüüüx˛”Á` XŃ+ZZZĐŘŘÚÚZ´´´ ®®PSSÓ©˝®®N¦+2pOôôôd–©¨¨@__Ŕ˝±Ş544 ŻŻmmmhhhČqoŤŞŞ*ăňĺËťöřkżÖ­[‡ż˙ýďÜ8 †<©ŻŻG[[Z[[ŃĐĐ"Buu5÷{CCC§U)mmmÜp/%%%Xż~=üq<˙üóîŤéÚSöź‘‘÷YężjjjĐŐŐíô;!/šššđ믿âß˙ţ7ňóó!‹;­ŁŞŞ ]]]ś8q˘ÓćʄD"AMM š››ŃÔÔÄimSSš››eÖ•ęóýv‚L__***ĐÔÔ„––ôőőˇˇˇŃIź Ćiooç««ADhllDKK €żü¸;¤şÝ:::PWWďň·űď«őôô ŞŞ hkkC(ÂŔŔŕavKnÔŐŐ!$$çÎťë˛~îšš^{íµN˝| yó0úűý÷ßăěŮłřňË/ajjĘô—ˇtTTT`ňäÉČÉÉé˛ţ …PQQÁ°xńb,|0 hiiAuuµĚ˝oUUU§ukkk;ígǶ§ŽHźSĄĎ°FFF|öe0†*,€0„hiiAqq1ŠŠŠP^^ŽŞŞ*TVVvzI—K»Ş”‘‘÷ 4lŘ0îedd$ó}ذa011……LMMĺ|ČËËĂĚ™3‘››ŰăC¤ĄĄÁÁÁAn¶0&mmm2~V[[‹şş:ÔÔÔ ˇˇŤŤŤ¨©©A]]ĐĐĐ€ęęjîł´ÁAÚŕĎ—> şşşPSSănʤţmddččč@WWÜw}}}.°¨ŻŻ/ă÷ÚÚÚ|ďC qpp@fff·Ů­***ÜCҢE‹äfˇ´´ĹĹĹ())餱÷żQ__˙ŔFEy!őICCCčččtŇY©ţĂÄÄ#GŽ„ĄĄ%kü`(=‰DĆďęęęPUUĹi®TŃĐĐ€ššÔ××s>) t$Ü\¸_{µµµˇ§§hkkCGGĐŐŐí¤˝FFFĺó………5k˛łł{]żuśL™Áč L Y:µŐ˙ůĎđŇK/ÉĹŽ»w¤%%%¨¨¨ŕ|˛«÷úúzÔÔÔ ĄĄ…{îU4şşşĐĐĐŕ4QÚŐ±=JúŮŘئ¦¦055…±±1/ö2ň† ­­­ČÍÍĹíŰ·qűömâÎť;())Aaa!WIwDzŇUĽ´qNz3َˇ™žŇmÜcŻĄĄMMM™eŇ,Žűmnhh™ž ŁËÍÍÍhllěö†OzÓבáÇs7V¦¦¦°°°€ĄĄ%ĆŚ1cĆ`ôčŃő0rőęUĚš5 µµµĽąTSSĂşuë°cÇŽ>—Ă8´··ŁĽĽeee\`®¬¬Ś»6ďŢ˝ŰéEš­x?úúú\Łąô&EúÝČČ{¨×ÓÓ“É 000€P(|`ć_z\ştI&;»·˝€ż2*Ą™!{BH{'Ië––.@R__ßeŔ¤®®®Ë,ĐÔÔěTuü>|řpššbřđá033ĂČ‘#ˇĄĄŐí1` |.^Ľ©S§>p=ifŕ矎 6ôą"Bqq1rrrpűömäććrz[ZZĘ˝w쥦¦¦Öc0\Ú×±!AÚĐ'Í\ěĘŹ»ęá×]ćł4ŕ(ͤ¬®®Fkk+×pŇŇŇÂ5žv•Xp÷î]™žMŔ˝Ś­ŽzkjjŠQŁFÁÚÚcĆŚŤŤŤŇeB3.b±eee(//Gqq1÷ů~˝­ŞŞÂÝ»wQUUŐéš•˘­­Íů—4P­ŁŁĂ5âu j …ÂNĵřţߤH—w…Ôż»C°čŠűłˇďĎ’‹Ĺ¨­­íň7齵T{;J¤AirCW=mĄcf÷Ô2räHN‹‹‹1}úôn÷ł':¤´Ů° ~PVý•Ţ;3ýe(#kÖ¬Áž={z űç?˙‰>ř SOšž(**â|2//%%%\{”ô˝cđ] t©!Ňw]]]™ž:]µMÉ;ŇŐ]őŘíŘ“°«uuuhiiAmm­Śovđč¨×ššš055…ąąąŚZ[[côčѰ±±™™YŻŹ-ˇ,°Â˘µµ7oŢDjj*233qűömîćéÎť;ÜPBĆĆĆ\ŁyÇ ËŇŇ’kX711Qęa‚úBKK ***¸@IÇŔIii) PTTÄM$ aaaÁÝXŮŘŘŔŢŢ?~<ÔÔÔ:•‰Ĺ‹Ł­­­Ë‡©®Đ××GII k°€´··Ł¸¸yyyČĎĎGQQ fMH-:VˇZZZ>|8ŚŤŤe˛…zę=٧§×ewJ†,ÍÍͨ­­í6‹¬« cyyy§‡-===››sF333 >–––5j,--1zôhć·”+Vŕ—_~éő’@ ŔK/˝„Ď?˙ĽËFľüü|¤ĄĄ!--ŤÓŰśśäććrŤwššš°¶¶ćt¶+Ý5334™‚‰(--íô`xżîJďK† &Łą¶¶¶ptt„““kÜ`¸wŹ{çÎ"//EEE(..ćt·´´” ŇwÔ] Ś1˘ËĆA©ßß(ˇŻŻĎ†Öë%­­­śöŢß`Ň]#ĘÝ»wQ^^ŢiÓ®PUU…şş:tuuąÄ iĂQKK –.]Šçž{N{ĘP6ţv†é/ăa¨©©ˇˇaźţ# ŠÝ»wsm#‰ąąąHOOGzz:—¸* HýRCCŁFŤ‚™™ĚÍÍąwiş4©k°eéWTT ¬¬ŚńCú^RRÂ}/((ŕ‚(ššš\0aôčŃ3f ŕŕŕ€1cĆô)xĂ`( @PB$ nŢĽ‰¤¤$¤¦¦"-- ©©©ČĘĘB{{;ÔÔÔ0věXŘŘŘpYő?ł›®©©©áD®ăŤ¨ôŐÖÖ555ŘÚÚÂŮŮpvvĆŮłgńý÷ß÷¸m…B…B÷˛˛% öíۇĺË—+b÷} ±±ŮŮŮ\†DAA÷ĘËËCqq1—ń®®®333™™aÄ2ŤÎŇ áÇĂÜÜ|Đ<  &ZZZ¸›ą˛˛2®K»ôł4TXX(Ó“ÂÄÄ–––°˛˛‚µµ5÷ŮĘĘ ¶¶¶1bŹ{Ĺ芪Ş* 6 ¸9A"‘<0đ;|řpěŢ˝7oŢä47--ŤËJ5jT'­•~677—ďŽ PZ[[‘——×IsoßľŤěěl.CÓÂÂNNNprr‚ŁŁ#śťťáććĆ‚xŚĘĘJ®ńO$(,,ä>—””p ®±AÚ“¬ăg©îš™™±{^%E,٤¤GŹĺzJ{ÖÔÔpAţ˛˛˛Nç~Ô¨QÜËĘĘŠ đKëÝÁ’ŸGii)®_żŽ””¦żýÓ_FGvďŢÝm V @UU•kĂ "Ĺbî9XEEK–,AVVŇÓÓŃŘŘ@+++nd©_J_ććć¬ń»wîÜáF‘ŢIۨ @DĐŃŃá\áčč777Ś=šď]` qXA ČÉÉABBD"‘ÚÚZ¨©©aüřń\C¶ôÝÖÖ¶Ë,yĆĂÓÖÖ†¬¬,™€MZZŇÓÓą ¨©©A[[ĆĆĆ044„¶¶6FŚ---hiiqÝŢĄ“c999aĘ”)<ďÝФľľŮŮŮ]ľîܹí'ÍR’>¨ZYYÉ<¸šššr7UŚÁMuu5ňóó‘źźŹ‚‚äççsŤ[Ňž(ŇĚv}}}ŘÚÚvzŤ7¦¦¦<ďÉФ¨¨'Nś@cc#ššš¸á8¤“ Ţßý¸ˇˇÍÍÍ2ÁKKK899Éh®ë%$ žžŽ””™÷šš¨ŞŞÂŮŮžžžđđđ€——\]]Ů˝Ź’SVV†ěěldee!''GFw+++ÜËj433ăłŇŕlÇFcV‡-Z[[QXXČénAAA§ďŇá_„B!FŤĹi®4ŁZúbs#)7UUU2ĎĽ (((XYYuzćeú+ţM¤÷ÂŇwéçśś¤§§ăÖ­[\O–ŽC YXX`éŇĄpuu…““ŘĂr˘ľľééé\;”Ô?sss!‘H`bb™—µµ5ßf3†,€ `Äb1®_żŽóçĎ#::/^Dee%ÔŐŐáććOOOxyyÁĂĂL¬y¤µµČĎĎGjj*!‰păĆ ´¶¶ÂŘŘ“'OF@@üýýáęęÚí8· ůQ[[‹ÔÔT$''#%%… ţ”””¸×=ŢÚÚşS#Ż­­-¬­­;Í×Á`t‡D"Áť;wş Jĺääp=tuu1~üx¸¸¸ŔŃŃ‘»á¶´´äy†&‰‰ALL Îź?Źěěl€­­-<==áéé 777ŘŮŮÁŔŔ€e4óL~~>§·"‘ ¨ŞŞ‚şş:<<<ŕďď___Lť:•›ď…ˇX ––†¤¤$¤ĄĄ!%%7oŢäĆÜ×ÔÔ”ŃܱcÇběر°µµ…ĄĄ%»·eô™úúz.(upŞ  €Kö±°°€—Uíěě '''ÖÍ˝Ń_OOO¸»»łs¤0ýütl‹:wî.^ĽŠŠ ¨©©ÁÉÉI¦aÚĹĹ…őFQšššśśĚ%‹D"¤¦¦˘˝˝ÇÇäÉ“9˙tsscmR ąÁ ŕúő늊BLL bccQ]] KKK`ňäÉ,˛?ŔhmmERRD".\¸€sçΡ°°†††6m€ &đmę B"‘ ##×®]Crr2’““‘––†ÜÜ\€ˇˇ!śťťáěě GGG®ábôčŃĚ· ˇ¤¤YYYČÎÎFFFĐĘËËpo˘jic†««+\]]áîîÎ2&ű™’’ś9s†k´ČÉÉ®®.¦NťŠ©S§ÂÇÇžžž}–ÁŇžšńńń‰‰ÁŤ7  áĺĺ___Lź>ľľľ, ÜĎÔŐŐáęŐ«HJJâęł””nř kkk8::ÂĹĹvvvśî˛á Фµµ•šE:̆ôzíęZurr‚»»;Y#K?ĂôwđÁôw`#‘Hččhś?±±±¨­­………üýýńŘcŹqmQě,š››qăĆ D"\şt çΝÝ;w```€©S§ÂĎĎţţţđôôd÷dŚ~ä@ss3˘ŁŁŽpidĐÖÖ–o3ýHvv6—]ŤÂÂBXYY!00ÁÁÁđ÷÷g˘ÜGňňň ‰Ďuu®­­…––×µŮŮŮ®®®pttĨQŁř6™Áč’šš®á-99™ë1SQQ!ÓUÜŰŰ^^^pvv†ŞŞ*ßf(®]»†'N <<"‘ÚÚÚÜÍłźźĽĽĽŘ1DTUUáÂ… ŽŽFLL ’’’ ©©‰Yłf!00AAA9r$ßf(š››qýúu.ëT$!##‰#GŽä4—eu3]ő–IKKCcc#tttŕîî///®¸­­-khé#L‡L•źşş:üńÇŚŚDdd$JJJ0zôhÎ'}}}1věXľÍdČěělÄĆĆríRąąą055E`` ćÎť‹ŮłgłŢCŚG‚ú‰††üţűď8|ř0Îś9ććfLš4 óçĎGPPśśśř6‘ˇ@RSSŽđđpÄÇÇCKK 3gÎĢE‹đÄO°î€÷ŃŢŢŽÄÄDDEEáŇĄK¸rĺ ĘĘĘ ¦¦WWW®aŐÓÓ“eŚ1 wîÜABB‚Ě«şşZZZ8q"Ľ˝˝ąĚ.ÖP' !66żţú+ÂĂĂQPPaţüůđőő…şş:ßf2Dyy9Nž<‰đđpüńÇ¨ŻŻ‡§§'BBB +++ľMT:Š‹‹ąĚřřx¤¤¤ ­­ #FŚŕSĄď¬11öh•‘€ë×ŻŁ©© †††đôôÄcŹ=Ćeç˛{vYţ2:ÂôW9(//ÇÁńűďżăüůó___Ě›7óçĎgÉ«C”ěěl„‡‡ăĉŤŤřůůaÁ‚X¶lŚŤŤy¶1Đ`„G@"‘ ::aaa8|ř0ÚÚÚ„ŕŕ`Ě›7&&&|›ČPĘËˉcÇŽ!22ęęęX´hV®\ __ß!9AŻtüĹDEE!66uuu°±±ÁÔ©Sáĺĺ///L0|›Ë`("Bvv6®\ą‚„„\ľ|‰‰‰ "Lś8‘m(Ź={ëÖ-ěÝ»Ŕ­[·ŕáá%K–°@=ٵµçÎťĂńăÇqčĐ!”——ĂĎĎ+V¬ŔâĹ‹‡¬ď”––rĂŠÄÄÄ ##ÚÚÚ4i7¬——ëÍÇ’´··#%%… (ÄĹĹ!%%ęęęđńńáz‘űřř Ů€Ó_Ć`ú«Xšššpüřq„……áôéÓĐÖÖĆO<ŔŔ@Ěš5 zzz|›ČP"jkkqćĚ;v ÇŹGcc#ćÎť‹ĐĐPĚź?ČjŁo°ÂCPQQŻżţ»wďF~~>{ě1¬\ąK–,Á°aĂř6ʎÄTVVâ—_~AXXâââ`ee…çž{/Ľđ 8UTT <<ÇŹGLL Ş««aeeĚ1ţţţ,K…Á¸Źşş:ÄĆĆ"::ŃŃѸ~ý:Ľ˝˝  ú÷ööv>|_~ů%._ľŚQŁFá©§žÂŞU«`ooĎ·y %F,ăôéÓŘ·oŽ;X˛d ^yĺ•A?OQ{{;bccqěŘ1ś9siiiĐŇŇâ2«ŕííÍ2…Śn¨¨¨Ŕąsçččh¤ĄĄA]]“&MBPP,X€qăĆńm¦\aúËxX†˛ţĘ›””|ńĹ8tč׼|ůr±F`FŻhjjBxx8ÂÂÂpęÔ)hkkcٲeXż~=ů6ʎİBČĚĚÄ矎ź~ú şşşXłf ţö·ż±1äEVVöěŮďż˙MMMXąr%6lŘ;;;ľMë7rrrpěŘ1üţűď¸xń"´´´0gÎĚ™3°±±áŰDc@Q]]ŤóçĎăĚ™38~ü8ňóó1nÜ8,X°!!!xě±ÇMݦÚÚZüđĂŘąs'îܹŋăąçžC@@Ŕ ŮG†â¨©©ÁáÇńŐW_áúőë>}:^}őUĚ›7oĐŚy^WW‡S§NqÝŐ«ŞŞ0qâDaúôéđńńa˝úڇ¤¬¬ çΝßţ‰đđpÁÁÁÁÁÁX°`|||Ť61ýeô'CAĺ áôéÓرcÎś9Ľđ xę©§Ř04ŚG˘˘˘żüň víÚ…ĚĚLĚš5 Żľú*fÎśÉü“Ńb<¬¬,Z´h …B?~<}ýő×ÔĐĐŔ·YŚABCC}ýő×dkkKBˇ-ZDYYY|›őĐ”––Ň'ź|B®®®€FŚA˙űß)<<śšššř6ŹÁT$&&Ňżţő/rssăümÝşutőęUľM{hęęęhóćÍ¤ŻŻOzzz´aĂĘÍÍĺŰ,Ć âĚ™34wî\äččHGŽáۤ‡¦ĄĄ…Ă`([·nŃöíŰąĆ úî»ď¨¦¦†oÓz…X,¦Ý»w“™™ŇÇ<`lg LRSSé©§ž"@@ţţţ*đ–žžNŻľú*Ť1‚TTThÁ‚ô믿2źa0x ;;›¶mŰ&Łż_}őUWWómZŻ`úËP4YE\\ůűű“@  §žzŠRRRř6‰1DHJJ’ńĎÄÄDľMb( ,€Đ {÷î%211ˇ]»vQ[[ß&1†mmm´k×.îúŰ·oß&uKmm-}ňÉ'4zôhN`ÂÂÂ¨ąą™oÓŚ!ÍĄK—hŐŞU¤ŁŁCşşşôÜsĎQFFßfuKjj*Mś8‘TUUiíÚµT^^ηIŚ!D\\Mš4‰„B!­YłFi{™ŠĹbúő×_iňäɀƎK~ř!Ýąs‡oÓ Ć˙séŇ%zöŮgIWW—´´´hĹŠ”śśĚ·YÝÂô—Á'EIuu5=óĚ3$Č××—âââř6‰1D‘ú§@  gžy†–,€p?uuu´jŐ*ôňË/ pĆŕŁŞŞŠ^~ůe´jŐ*ĄşˇŞ««Łwß}—ŚŚŚH__źŢxă şyó&ßf1Śű¨®®¦oľů†ĆŹOBˇ–-[¦tC¤íŮł‡´µµięÔ©”ššĘ·9Ś!ŠD"ˇýű÷“±±19;;SZZß&qĹbÚłgŤ7Ž„B!-Y˛„˘˘˘Ř †SWWG?üđąşş’@  ŕŕ`ĄË˛fúËP”YÍĺË—iĚ1dnnΆŹa( GŽ!SSS˛±±ˇ+W®đmGXˇdooOǧ“'OňmADDdllLNNNJŃH˙ż˙ýŹëâĽeËެ¬äŰ$ńÄb1űě3RSSŁyóćQYYßć02”••Ńś9sHMMŤľřâ ľÍađ ü?ÉÉÉ4räHš6m›tގtŇ”)SČÔÔ”· ˇÂÂBš3g©¨¨°.Î ĆĄ­­Ťľýö[1bY[[ÓŮłgy±Ł©©‰fĎžMĆĆĆtúôi^l`0şŁ­­ŤŢ|óMôÝwßńbCCC­[·ŽÍž=›e3‰DB +++211ˇ_~ů…;ţ2”eĐ_>xăŤ7HUU•>űě3Ö»ˇ´H$Ú¶m©¨¨Đ¦M›ř6‡Á*ď˝÷Ţ{┕•Á××'NDxx8† Ć·IŠććf¨ŞŞňmĆ F__Ë–-ĂůóçńĹ_ 44::: +?!!3fĚ@cc#Ž;†5kÖ@[[[aĺ3ň˘˝˝qqqŤŤ…««+ßćȡPOOO¬Zµ 7nÜŔŰoż LžŘľ};>üđC:tűŰß ř6i@ÁüRqLž<ŽŽŽxăŤ7```ľÍb(ľ#Ę@`` ůřř(tŚy‰DB}ôŤ;–śťťIWW—ŠŠ ‰Ĺb…Ůń°TWWÓż˙ýoňńńˇůóçómNŻ8xđ -^Ľšš˝ýöŰ” łN}}=}ôŃG´rĺĘn·Ó›uäECCÂŹůĺË—I__ź‚©®®Naĺö•;vô{w×)S¦Đ”)S:-ommĄ—_~™ÖŻ_OăĆŤŁuëÖőkąRţřăZ¶l UUUňóó#???rqq!OOOzăŤ7”zb\>éîÜu¤´´”Ţxă @rµ‡ĎzŁ'ľřâ RUUĄ˙űß +S:ć˛"Ç‚fš«x¤ąíííôţűďÓ3ĎŹŹ'555 ShąĚ/OÝ+o………‘šš‰D"…—ÍŕŹ!@8tčéééQ^^žBËýŕČŔŔ€233‰čžżúę«€JJJjK_HII!˘{˘“——§†·ţ¤¶¶–źź_§ßNžűlŹűÔ›uäMnn.éééѱcÇä^Vyy9ŤEĂŁ§ IDAT9’BCC•ţfbüřńôŘcŹ=ô˙Ą×vG&OžÜĺĂđ‡~H“'O&"˘ččč~˝qąßŽşş:@łfÍ’YžžžN+V¬ UUUzë­·ęáł«}î/äąíŢĐÝą»±XÜŻţÜŐ~+C˝Ń$úí·ßä^VUUÓ?ü ÷˛:Â4—zŇÜçźž‚ąş«˘˘‚,,,: ©Á·˙H$š>}:…††Ę˝¬ÖÖVš8q"Mš4‰jkkĺ^ŢŁÂt—énG”Iw{[żđM\\éęęŇÖ­[ĺ^Óßľ1ő·7şŞ >¤Hýĺ±XLîîîr ÷óK~čŹűbeđM)ëÖ­#6ěÖbČ&L@ożý¶Â˵°° ÇĽÓň… Ňőë×nOo¸xń"-\¸PfŮ@«´‰z¶ą˝˝ýűÔ›uäÍĆŤÉÝÝ]î儆†ŇÔ©S©˝˝]îe= ţů'©««JLLěó˙»ş¶{ÂŮŮY.çż;;zşŢľüňK@˙ú׿úĄ¬ţ@žŰ–ýĺĎ=í·2Ô=ńé§źŇ#¨şşZ®ĺlٲ…ěíídšË]Ů|őęU@ńńń2Ëß{ď=7n\§ľý'11‘„B!eeeɵś­[·’••UUUɵśţ€é.ÓÝGAžşŰ×ú…o"""H]]ťŇÓÓĺZÓßŢ3őWJOşŞL>¤(ýĺß˙ťtuuéîÝ» /›ů%<Ę}±2ů&Ń˝dS]]]:~ü¸BËeđ‡â\TBŇŇŇpýúu,]şTáe———ăęŐ«¨¬¬”YţňË/Ł´´Táö<ŚŚ ,Z´­­­|›"WTTTúeyŠk×®!##CneäććâçźƶmŰ”bź{âŰożĹ—_~ Řąsgźţű0×ö­[·úT†Ľě€—^z sçÎĹG}„üü|ą–Ĺ÷¶•™í·˛űĐkŻ˝MMMü÷ż˙•k9żüň ž|ňI…Ž÷ 0ÍU6vďŢ ===xyyÉ,ź>}:˛˛˛#łśo˙™8q"ĆŤ‡źţYne´´´ŕ?˙ůŢ}÷]Ę­śţ‚é.Ó]ľénżűZżđM`` üüü°}űvą–Ăô·w ęIW•ɇˇż|±˙~Ěť;——ů7™_*˝ő9eňM011ÁěŮł¦Đrü1¤‰‰‰ĐĐĐ€‹‹‹ÂËž>}:*++€ĚĚLnąŻŻ/fĚH$ŤŤĹš5k°bĹ D"L›6 ššš={6qöěY¸»»CSSłfÍBMMŤL9YYY Ĺúőë1oŢ<„„„ŕćÍ›ťěéi˝öövl۶ %%%‰D Á?ü ó˙¸ąąASS¨ŻŻďvß“““ńĘ+ŻŕÓO?…··7ěííŃÖÖ†S§NaőęŐxć™gpöěYxzzBCCžžž‰DývLÎÎÎPWW王<8}ú4 ”~‚µ’’”••aÍš5prrÂ/żü‚»wďvZO$á•W^ÁŞU«páÂŚ=ľľľÝ^ŰyyyřôÓOáččČmăçźĆňĺËŃÔÔ„ëׯcůňĺřŕÜ»67oŢŚ÷Ţ{ëׯ‡——’’’dl¨¬¬ÄÚµkńâ‹/bŐŞUxüńÇ‘––Ö+ë‰5kÖ ˝˝‡â–effâ‰'žŔÂ… áěěŚ/ľřŔýą»˙őç~tu.¦OźŢăqěmŃÝą“RUU…5kÖŕ…^ŔoĽwß}·Ó:=ťËľ^GˇPŮłg#22Rne477#55r+Ł;ć*—ćĆĆĆÂÖÖ¶ÓD¶¶¶€čččnCŃxzzâęŐ«rŰ~||<***(·2ú ¦»Lw•YwbýÄô—éŻŇ<ó*›É[ůB$ujVĚ/•Ë/{ësĘć›Ŕ=˙LLLTxą žŕ» ź|óÍ7dllĚKŮyyy4nÜ8@šššôé§źv&¦ĽĽśöîÝKČÚÚšľýö[Ş©©ˇ?üĐĽyóhűöíT]]M;vě ôá‡r˙ĎĎĎ'ŠŠŠâ–-^Ľ† F999}^]t·@666ôÉ'źPQQ}üńÇ€¶oßŢíľ»şşREE566ŇÜąs©®®ŽţüóO@ćććôůçźSRRíÚµ‹455ą ”őt·}ů˝·ëČcccúć›oä¶ýŹ>úlmmĺ¶ýţbëÖ­´gĎ"úkXŹ>úHfťĽĽ§lľIDôŐW_‘‰‰‰ÂËeđĂ 9r„„B!577óR~]]˝řâ‹$ =öŘc”źźßi=4gÎî{yy9 ŮłgËl -[¶Ś[¶jŐ*;v¬Ě¶ŇŇŇ-_ľĽĎëuWiwśd®ŞŞŞ“÷Ł®®N‡ćľwśđĺţý""®ňýŕdÖ{cŇÝ~ôĺ÷Ţ®#OI Đďż˙.·2LýÂ7ďĽó9::ĘműLű¶Ţ`ÖßŢü®l>$oýĺ ggç>ĎĄÓź0żĽ‡2řeo}NŮ|“č­·Ţ"777…—Ëŕ‡!=„‘ŻŻ/„B!Îť;ÇKůşşşŘąs'âââŕä䄸¸8L™2ĄËqç:ŽShddPUU•Ů444pË"##acc#łŚ3gÎśéózݡ¦¦Ć}–ŽŰŰS·±™3gâÉ'źÄß˙ţw`Ö¬Y2żwÜ/Ü7nÜYţ0Çd°pţüy¨¨¨`Ú´ir+#((ZZZ8pŕ€ÜĘxTNś8iÓ¦A[[Ŕ˝ëoéŇĄČĎĎÇńăÇeÖŐĐĐX[[÷zű÷wě‰Í›7#22 Ř˝{7rrrĐŇŇÂýţË/żŔŮŮYfěŮĹ‹ăÇěuÝŃŘŘ000„‡‡Ł±±˙řÇ?¸—™™ôőő{ÜNoţ×űŃÓąxĐqzWGtuîöďß777™˙«««÷Ɇ‡ąŽĄĄĄŚŚÄŠ+äV†ŠŠ |}}y>‚i®ňh®ŽŽÄbq§ĺmmm==˝nC‘´··ăâĹ‹đ÷÷—[NNNpwwďM'LwďÁtWyuw Ő/­­­ cúű˙0ýĺ˙™W™|HúË3fĚ@TToĺ3żTżě­Ď)“oJůóĎ? đrü0¤ĆĆĆXĽx1ľůć…–+up)ŢŢމDX°` şű´#=Mz$‘H¸Ď••• ˘NëŚ;Vfœޮ׺ڞ”}űöáńÇÇŹ?ţ;;;|úé§=nkřđád÷í~z{L »víÂŇĄKĺ:é’––Ţ˙}lܸŮŮŮr+çQřöŰo‹I“&qŻřřxŔW_}Ąp{ľţúk¬Zµ łgĎît#tűöíNľß_HÇ öööaěرřöŰoąWtt4.]şÔăvzó?yžŽcWô¦ŽîŤ3Ýń&ł?mČĹb¬^˝>>>rý˙ř~ţůç‡Ö–‡i®ňiîčŃŁQ]]ÝiątśŘqăĆ=pŠD:yŁô!R^l۶ ;wîTĘ1ÚĄ0Ý˝Ó]ĺŐÝVżĽöÚk "¬[·N®ĺ0ýeúŰ[”ɇĄż|đŹü—/_VřřńĚ/•Ď/{ësĘä›Ŕ˝y<đ /(´\ éĽ˙ţű8yň$"""Vć÷ß/3Y hjjr^ýRŽąą9˛˛˛:-°°°čózý…®®.Nź>Ť˝{÷BKK 7ně1‹JZ!:88ô»-‘#GŽŕĚ™3]NB×߼řâ‹pwwÇś9spűömą—×rssQSS¤¤$\ľ|™{Ą¤¤`ěŘ±ŠŠBZZšÂěŮşu+¶lŮ‚˙ýď°´´ěô»ŽŽ®^˝Š¦¦&™ĺb±¸S¦__‘úŇ“O> ŕ^öEZZZ§›'"ę1#Ł7˙“ç~>Ž]ŃŰ:BMM­Ë‰»úÆJ[[–/_ŽřřxěŢ˝»OŮżĂÂ… áää„ 6ȵśŽ0ÍU>Íť:u*nÝşŐiy~~>ŔĎĎOne÷•ňňrlÚ´ ›7oć˛ÉäĹŚ3đ /`áÂ…ŤŤ•kYÓÝż`ş«Ľş;Pę"ÂŰożŤďż˙{÷î•{ýÂô—éooQR¤ţň˝˝=V­Z…µkעµµUaĺ2żT>żě­Ď)‹o÷zĎ­YłĎ=÷ěěěV._†|ÁÎÎď˝÷–/_Žääd…”iccM›6uZ.íÝ_Ů® ,@^^RRRd–gee!$$¤Ďë ‚.»Lő†ĘĘJNĄ=>V¬X“'ONť:Őí/\¸ˇPĐĐЇ*{0‘””„Ő«Wăý÷ßWH„Y(â·ß~ĂČ‘#áíí­TY‘ŇLµű …X»v-€ŢgC>ʵ-ĺ?˙ů ŁŁť¶çë닺ş:|ôŃG2ËwîÜÉe‚<ŚŘłg¶nÝĘeH ´´?ýô“Ěş;věŔÝ»w»-«7˙{”ýčXtÇŽcWô¶Ž:u*rssqáÂn™4+¤căÍĂŘôĎu¤HJKK1cĆ śű쳸{÷.—Ĺ-%>>cÇŽ•ëđ|}ˇ©© !!!°´´ÄúőëRćgź}† `ćĚ™řţűďRfoaş{¦»Ę­»ˇ~©­­Ĺ“O>‰íŰ·ăçźVML™ţöeđ!>ô—¶mۆââb¬^˝ZaŁ&0żT>żě­Ď)oő^ݍ¨x`Ć CqÓ-(/‰„.\H#FŚ k׮ɽĽĚĚL@k×®ĄĆĆFnů;ďĽCÆ ŁÜÜ\nY{{{§IZ Í1ŁÇőĘËËÉĘĘŠ,X@‰„˘ŁŁÉŇŇ’›yľ/ë™™™‘™™ĺççÓˇC‡¸IĐ:N\#]6sćL™}5j˝đ DDäââB­­­\ŮhűöíDtoR ެ¬$"˘ššrqqˇM›6őË1©­­%äççw˙i!"˘¶¶6Đĺä4}YGD"211ˇeË–qçIQ466ŇSO=EBˇ^~ůenňDľ¨ŞŞ"ş{÷n—żŇŃŃá®aéy›>}z§őďż¶ĄĚś9“PKK ·¬ˇˇˇËk|ذa¤­­MQQQôűďż“­­- óçĎÓ­[·čęŐ«¤©©ÉM¦ôŮgźŃOĐiýÝ—ëżzŁ;8@ĆĆĆdggGiii /?,,Ś„B!íرCîe1ÍUNÍ]ż~==ńÄÜ1hnn¦ &Љ':­Ë‡˙ÔŐŐŃôéÓÉŇŇ’ V.Ń˝űŇ÷ßź„B!RaaˇBËď ¦»Lw’îöĄ~Q4'Ož$+++255Ą .(Ľ|¦żL‰¬«|úźúË"‘´µµ)44TfÂyyÁüR9ý˛·>Ç·ľµ¶¶ŇSO=E”””¤2Ę ü?ÍÍÍ4ţ|ŇŐŐĄ={öȵ¬ÖÖVRQQ!d``@~~~äííMÁÁÁ”žžÎ­W^^Nď˝÷  §ęęjzë­·¸‡´Ă‡Suu5·žˇˇ!íßżź«P héŇĄ4wî\zýő×iőęŐtűöíN6őf˝ŻľúŠtttČÍÍŤbbbhÓ¦MÜ>8p€ęęę8Űôőőenä}||čý÷ß'˘{łŹŹmÝş•.\Hożý6‰Ĺb™ßž}öYzňÉ'ÉÇLJ>úč#nĺ:tžxâ @jjjôĎţ“9/^ĽH7nä¶˝oß>şuë–Ě1čÍ:ň`Ďž=¤­­M!!!2fŠfďŢ˝dddDććć´{÷nîĽ)’””š6m 7ß|“Š‹‹e~/,,¤-[¶@ţţţtôčQZ·nwî·mŰ&óżŽ×öŐ«W©®®Ž~üńGŇ××'´iÓ&*,,¤””Ú°awÝďŰ·ŹĘËˉčż˙ý/ééé‘˝˝=ť:uŠvďŢMÚÚÚ4kÖ,*--%˘{Ň“&M"uuu˛··§#GŽČŘ~ż111´dÉ@***äďďOÓ§O'777rvv¦5kÖĐőë×»¨ŽčîÜI‰ŚŚ$RWW'777ŠŠŠ"úđĂą:Ż;ĆŽËťŹŢ\GRřŞ7şâęŐ«äďďO€Ö®]KőőőĽŘADôí·ß’P(¤U«VÉ5(É4W95W,ÓÇLK—.ĄW_}•–/_Nááᝎţ“śśLööödiiIr-«'Îź?Ovvv¤««K›7o¦şş:^ě`şËtw énoëE’ššJAAA\ ¨¬¬Ś7[ţmý퍮ňĺCʢżŠ&66– hҤI2 řň€ůĄrúeo}ŽO}ËÉÉ!222˘¸¸8…”ÉP.Xˇmmm´qăFrżˇbt äŰ ĄˇľľžV­ZEBˇ6nܨ¬„QRRBk×®%UUUrrr˘ýű÷S{{;ßf1†¬Žx8D"…„„@  I“&)ÍM_DD“łł3/=!†:Ěź:# ŘO›6M)2˙é“O>!CCC>|8mÝş•Ş««ů6‹1„`őÄŁ‘””DO?ý4©¨¨»»;ť>}šo“é/ß0żęŚ˛éŻ˘IOO'WWW244”éaĆPĚ/»çŕÁdhhH&L ĚĚLľÍađÄźˇ#ŞŞŞřř㏎¸ąąáčŃŁ|›Ĺ˘=znnn8qâNž<‰Ź?ţŞŞŞ|›…‘#Gb×®]HNN†»»;V®\‰qăĆaëÖ­(**âŰ<ń˙477c˙ţý€§§' päČ\şt “&MâŰ<@`` ®]»###xxx`óćÍ=N8Ę`Č‹ěěl,\¸«WŻĆK/˝„¨¨(ąLŢ×W´´´đć›o"++ kÖ¬ÁöíŰaee…5kÖ@$ńmÁč‚––üúëŻ9s&ÜÜÜśśŚ°°0D"Ěš5‹oó0ýe(ĘŞżŠĆŢŢńńńxúé§±hŃ",[¶ ŮŮŮ|›ĹâdggcńâĹxňÉ'±|ůrÄĹűI“‡0,€Đ¸q㼼Ľ°hŃ"ŕÚµk|›5č‘N'}Ş\»v X´hĽ˝˝qýúuĄyŘč˝˝=öíŰ‡ŚŚ ,Y˛;wî„••‚qüřń5™,c`ŔęŢ‘śśŚőë×Ă«WŻĆđáĂńÇ@$!$$€oe5j˘˘˘°eËěÚµ vvvřď˙«°Éä†*ĚźîQ]]Ť×_NNN¸yó&Ξ=«4űŽ`Ë–-ČËËĂ|€¸¸8xyyÁŐŐ;wîDee%ß&2!¬žčÉÉÉذaĚÍÍńĚ3Ď@GG‘‘‘¸qă–-[ˇPą˝™ţňó«{ ýU$šššŘµkÂĂĂ‘śś '''Ľţú먮®ćŰ´AóKYŞŞŞ8˙LOOÇéÓ§±sçNhjjňmOřîˇěÄĹĹѤI“H(ҲeËH$ńmŇ $??ź^yĺ@şşşôé§źĘ}ü?e#>>ž–,YBBˇP©†é-­­­tčĐ!š3g …B277§_|‘Îś9ĂMTÄ`<,¬Žč™ÔÔTúŕČĂĂ˝˝=m۶Ť| P^^Î ‘ćććFű÷ďgő‡`ţDTZZJďĽó“‰‰ íÚµK)† ě "‘žţy200 ˇ={öps0Ź«'zGRRmÝş•ÜÝÝ9ýýř㏙ţ2ş„ůŐŕĐ_EĐÖÖF»ví"266¦Í›7wšŃ?0żü‹˘˘"zë­·ČĐĐů'Ł""ţÂ"ÂáÇńÉ'ź 11~~~xőŐW¤t™$Ś…D"ADD¶oߎŘŘXxzzâÍ7ßÄâĹ‹•.K¸/äççăŔ8zô(`hhyóć!$$sćĚ®®.ß&2‰D‚Ë—/ăرc8zô(˛˛˛`ee… `ńâĹđőőĺŰÄG"-- [¶lÁáÇaff†őë×ăů矇ľľ>ߦ18iiiřüóϬ[·ëׯ‡ˇˇ!ߦ=4ŤŤŤří·ßpüřqś:u MMM2e ‚‚±cÇňm"1h‹ĹŤŤĹńăÇqěŘ1äääŔÚÚšÓßiÓ¦ńmâ#Áô—!/Łţ*‚ęęj|ůĺ—řć›oPUU…eË–aÆ 0aߦ1×®]ĂŽ;đ믿bذaxńű~ýzčééńmC‰`„>ŤĎ>ű 'Ož„­­-–/_Ž•+WÂĘĘŠoÓŰ·o#,, {÷îĹíŰ·„×_}Ŕ?ttEQQŽ;†cÇŽ!::BˇS§N…żż?ŕíí=¤»Ş2˝%++ ŃŃщ‰ATTJKKáââ‚,X°|›ŘďäĺĺaçÎťřá‡Ë–-Chh(¦M›6 ¬ ĹR__ŹŁGŹâ§ź~Âźţ {{{lذ+V¬t]±›››…cÇŽ!<<ĹĹŰ··G@@üüüŕď#Gňm&1` "¤¤¤ŕÜąs‰‰Att4ŞŞŞ0qâD#88xP6ä1ýeôCIĺMKK 8€;v 99ľľľ ĹâĹ‹1lŘ0ľÍc @*++qčĐ!„……áÂ… pssĂ+ŻĽ‚eË–ACCoóJ <$™™™řî»ďđ믿˘¸¸Ó¦MĂĘ•+±hŃ"đmC ©©©ÁÁ†ŘŘX™™áé§źĆsĎ=‡ńăÇómžB¨©©Á©S§…ččhdeeAWWW& 0qâDP`0äää &&†k°(,,„‘‘üýýáď  ŘŘŘđm¦B¨­­ĹO?ý„˝{÷B$ÁĆơˇˇX±blmmů6ʎ„ĹbDGGă§ź~ÂŃŁGŃÖÖ†ŕŕ`¬^˝łgĎ `‰ 8uębbbpůňe477ĂŃŃ‘«G|}}Y@Áč€D"Azz:°?wî***0räHî^uŢĽy5jߦ*¦żŚľÂôWţDEEá˙űw|çÍ›‡ĺË—#005ü2z¤ĄĄ ĂÉ“'ˇ¦¦†'žx+W®ÄôéÓů6ʎä°Â#"‹ńÇ`˙ţý8räţţţFPPĐąądtM~~>"""püřqś;w*** ÁŠ+0cĆ ¨¨¨đm"ŻĘdTçććB[[îîîđňň‚——Ľ˝˝Ů cĐs÷î]\ąr"‘W®\ABBJKKa``___ŔßßnnnC~čĽŚŚ üôÓOŘż?ňóó1aÂaţüůđôôňÇg(ÓĐĐ€?ţř@yy9¦NťŠĺË—céŇĄC>ÁŁąą—/_ć2©Ąkkkx{{ĂËË žžžđđđ`Ă•0† yyy‰DHHH@BBQSSĂ |}}áďďGGGľM妿Śî`úË řý÷ßqŕŔś>}şşş9s&áÇóm"C (++Cdd$"""pćĚ466bÖ¬Y EHH´µµů6‘1@`„~¤®®‘‘‘ÇÉ“'QYY wwwaöěŮđöö†ššßf2äH[[®\ą‚S§N!""ׯ_ǰaĂ0oŢ<Ěź?óćÍcă˙÷@nn§f˘¶ IDAT..^ĽČ5 ^ż~MMM022â7ÜÝÝáęę ö Â”••!997nÜŕ,nÝşˇP;;;.pćăă‰'ů@cwH$\Ľxááá8~ü8233ajjŠ   ÂĎĎFFF|›É3YYYřóĎ?qüřqDGGC,cÚ´i?>,X€1cĆđm˘ŇŇÜÜŚřřxNs››+SyzzÂŐŐ...066ćŰd㡑H$¸}ű6RRRpíÚ5$$$@$ˇ¬¬ jjjpuuĺ®ůÇ{Ś z€é/`ú«l”——ăřńă8qâ×Hěĺĺ…ůóçcćĚ™¬—˙˘˝˝"‘gĎžEDD ­­ŤYłf!00óçĎgÁ%ĆCÁrB,ăÂ… \>##:::$mmmHII‘iÜHMM…X,†––áââGGG¸şşÂŃŃ‘őúa( 555HMMEJJ RRRššŠ¤¤$TTT,--áíí OOOřřřŔĂĂeh=YYYGDDbcc!‘Hŕââ Ő2mÚ4Ö:ČČČŔůóçą,ú˘˘" 6 sćĚApp0ćĚ™Ăü訨¨ŕVĄďĹĹĹ€‘#GÂŮŮNNNprrâ>łăÍP6ňňň––ĆioJJ ŇÓÓŃŘءP{{{xzzr{7776ěÇ#ŔôwhŔôwŕĐŇŇ‚sçÎ!""‘‘‘¸uëtuu1yňdřúúÂĎĎ^^^¬Ţ$´´´ŕĘ•+8wîbccqéŇ%Ô××ĂÖÖóćÍC`` üýýYŰ#ă‘aQXXȉíůóçqóćMhkksĂ´H»ŚłˇZ”›ěěl™‡ę„„455ÁÎÎŽ ůűűĂ‚oS-ÍÍÍHOOç “““‘ššŠĽĽ<€ˇˇ!ěíí1nÜ8ŘŮŮÁÖÖ–{ňl=c°ŃŇŇ‚śśdee!;;›{ÝĽy“»&ŤŚŚ¸Ć6iËć•/ ¸xń"§ąW®\X,†ŁŁ#´ńôô„››»™VbîŢ˝ ‘H„ÄÄD$$$ >>ĹĹĹ066ĆÔ©S___6´—ś)++“iMMMEjj*Ş««ŁFŤę¤·Ň›$“!/***8Íí¨Á™™™¨©©Ś=ŽŽŽ2/GGGhiińlýŕ…éďŕ€éďŕ"//Ź ţś?YYYĐŇŇ‚‡‡ç“°łłcçSÉ‘H$ČĚĚDbb"çŁ"‘ÍÍͰłłŻŻ/÷˛¶¶ćŰ\Ć x˘¨¨111¸tépăĆ ´´´ŔČČH¦Ë¸ŁŁ#ĆŹĎn°Lkk+222žžÎ 3’ŞŞ*hjjrÝś§L™™™ńmň§¶¶– (dddŕćÍ›ČÎÎĆíŰ·ŃÚÚ 011á5ĆŤ‡ŃŁGcÔ¨Q°´´„••ËÂ`tB"‘ ¤¤ůůůÜ«c    ‰–––Üőegg899ÁŇŇ’ďÝň444 ..Žk̉D¸{÷.ÔŐŐáęę OOO¸»»ĂŮŮlčCDČËËCFF’’’pőęU$$$ ''¶¶¶đňň‚ŹŹüýýáěěĚp•€ÂÂB¤ĄĄ!99™™™¸uënÝşĹŐ‹`aa!P°˛˛‚••FŤsss6´'Ł[ęëë‘źźŹ‚‚"''GFkkkššš°µµ…ŤŤ ĆŤ{{{®wŞžžĎ{Á`ú«Ü0ýšăüůó¸páqăĆ 466BOOîîî2mQööö¬.剺ş:ddd -- 7nÜ@bb"®]»†şş:hkkc„ đôôäz–°6)†Ľa%ˇ­­ III‰DÜ+-- ­­­PUUĹرcáěěĚÝŰŮŮÁĆƆu|DŞ««‘““ĚĚL¤¦¦r™í999hoo‡şş:ąnÎ^^^pvvfĽ±XÜ©ŃWš­–››‹¦¦&n]SSSXZZÂŇŇÖÖÖ°˛˛âľ›ššÂÔÔ”M24hkkCyy9JJJpçÎäç磰°………ČÍÍEAAŠŠŠĐÖÖPQQ……ĆŤÇ2m·oß–éQvőęU.kŐÜÜŽŽŽptt„““ěííakk 333ž-¸´´´ //YYYHKKCjj*ŇŇŇžžŽúúz÷2†=<!222äY冏322 Ńhäß©žw˝ĽĽŕááOOO´iÓFλÎÎÎpqqa;­€’’9÷ććć"-- YYYČĘĘ’óoff&222••%÷cŔÚÚÚ`I;;88(¸wÔď ó/5´ŞŞ*$%%áÂ… 8ţ<pîÜ9$$$Č?é{©ýčСüüüŕíí ŹVßÖh4r_499×®]“‰‰‰HJJBYYŔŃŃQ§P#Rýýý[uűFĆ„f¨˛˛III:âÚ Ú3vlllŕëë OOOů§ŹŹÜÝÝ厖öĂŘ/•T^^ŽÜÜ\˝ÇÍ›7‘šš*8I?KJJäßurr’6 |˛ĂI†h4¤§§###C–:ĆŐ¦µż{GGGy`ĂŐŐUţŢI?ŕääŘÚÚÂÁÁ°µµ…­­m«:˨¤¤ĹĹĹ(,,DAAŠ‹‹Q\\Śüü|˘¨¨HţÎKÚ˙ľuë–N±¸}`ëéé)8Ig’HPŇ€”ŻŻ/݉L5ĘĚĚÄ•+Wôňmbb"ŇŇŇ J©T*ůďI;ď¶iÓ®®®z9×ÖÖVá=«›ˇś›““Ł—o322ä„€ĄĄ%Úµk§—oĄŮĂÍaßIr~ÍĚĚDvv¶^ޕΓµŮŰŰëĺZíźÎÎΰ··‡ŤŤ ěěě ćŕÖ4ŕQZZŠââb   @ÎĹyyy(..–sŻv®•~J˙V«Ő:Żinnwwwť‰Ős±Ô6şąą)´çÔ0˙2˙’ń‘fĚk«¤‡T¬nźi(}˝˝˝Ń¦MřřřŔĂĂCţ^jŹI5—Kę‹JgÖĄĄĄ!##Cţ™™™©óyřřřčCĄGÇŽy "2z, ´@ąąąň¬{C©©©¸yó¦ÎŕşÄÎÎNnŔ­¬¬`gg;;;XZZÂŃŃÖÖÖ°˛˛‚“““\­ŢĐ›››ëÍ`(,,ÔŘ“:}UUUČĎĎGYYJKK‘źźµZŤ˘˘"ˇ¬¬LnśĄS,µŮŘŘŔÍÍÍ`ˇDJRľľľÍ&!QóUVV†ěěläää<¨¨ŢůÎÍÍEaa!ňňňP[Sloo[[[ŘŘŘČÇ҇ôťÔţŢIßO[[[ť˘ ĄĄeŤ—‚^§:ŤF#_g¸şĘĘJĘĎ…rEúΫŐj”””ČßsŕöYŤF.ŐůŘŮŮé :ାĚĂĂł©ŃI—¨)ßJťCťňß«µµ5śťťĺď©˝˝=,--áŕŕů-Őż×ŔíBĄö5‰Ą|Ş­¨¨HľWaa!ÔjµÉ´ľăQvvvň˝-aaa!çÁŔß߯ “ű§Ú×´Ż,Đš®@­ ÔhćĚ™زe‹Â‘µl[·nĹś9sjťMLDDDw&77ضmfÎś©t8DÔ>űě3<óĚ38q╇Č(đÜ6"""""""˘j~ţůg™™aěرJ‡BDMä‰'ž@ßľ}±páBNÎ!ú/ŞŮµkFŚÁË”µ"¦¦¦řä“OpôčQ|ýő×J‡CdX@ """""""ҢV«ń믿bâĉJ‡BDM,88 .ÄŠ+““Łt8DŠcHËPPP€I“&) )ŕő×_‡JĄÂË/ż¬t(DŠcHËŹ?ţŕŕ`řůů) )ŔÁÁ6lŔ_|#GŽ(‘˘X@ """""""ú/!~úé'<řŕJ‡BD š={6FŤ…… ˘˛˛RépĂŃýő×_HIIÁ”)S”…¶iÓ&\¸p}ô‘ҡ)†"""""""˘˙ŠŠŠ‚ŹŹ‚•…ÖµkW,_ľ«V­BjjŞŇá)‚"""""""˘˙Úµk&MšĄC!"#đĘ+ŻŔŐŐË–-S:"E°€@DDDDDDDŕúőëř믿0iŇ$ĄC!"#ammŤŤ7"""ŃŃŃJ‡CÔäX@ """""""đÓO?ÁÖÖ#GŽT:"2"<đ¦NťŠE‹A­V+Q“bŔţóŚ?–––J‡BDFć>@zz:Ţzë-ĄC!jR, Q«WXXŕÁT:"2Bm۶ĹĘ•+ńÖ[oáĘ•+J‡CÔdX@ """"""˘Vď—_~Aee% DTŁĄK—˘S§NxöŮg•…¨É°€@DDDDDDD­^TT† ĄC!"#ĄR©đńÇă×_ĹŽ;”‡¨I°€@DDDDDDD­šFŁÁîÝ»1qâDĄC!"#wß}÷áŃGĹŇĄKQTT¤t8DŤŽ"""""""jŐ:„ÜÜ\Lž˝ÖmZ kkkÔ¸ŢĚĚ ť:u‡~Ř„QQKWYY‰÷ß!!!ň™ŐÇÍŽ;¦DhDw„j0ăĆŤ˝˝}Ťëííí1nܸ&ڍe˛´´ÄŚ3 R© ®Ż¨¨ŕý†ţKşçAMLMMńĂ?°đND &66:tŔ˛eËPRR‚ŠŠ ˝m,,,pôčQ˘#ş3, P±°°@XXÁÁ •J…°°0XXX(QË3gÎpttÄčŃŁ›8""""ădeeSSĂĂ&&&řŕĐÄQQKUYY‰7Ţxׯ_Żőže8räHFFtwX@ 5{öl={¶µLŁFŤ‚«««Ţr•J…‡z¨ĆłZ+++x*• S¦LÁ‚ ŠZ*sssěÚµ Ë—/Żu;!âââj-2¨AŤ1îîîzËÝÝÝ1bĦ¨…233Ăś9sô Ľ|‘.GGG!t–™™™ÁĂĂ_}ő•BQQKfff†őë×ăß˙ţ7T*ĚĚĚ nW\\Ś„„„&ŽŽčΰ€@ ĘÔÔ?ü°ÎĄŠ,,,đđĂ×xĘ(ÝťYłféťůçííŤ!C†(‘ń±˛˛Ň+ !°cÇ899)µsçÎĹáÇáââbđ aSSSÄĹĹ)QýqD—ÜC=„ňňrůyyy9gB5‚řúúĘĎ-,,0gÎśZoIDDÔÚXYYˇ˛˛R~njjŠ×_!!! FED­Ĺ€ŹŔŔ@››ë¬333㍔Éč±€@ ®oßľđóó“źűůůˇoßľ FDDDÔ2™ŕŃG•g3±hODD¤ĎÁÁAţ·JĄÂđáñbĹ #"˘ÖĆŰۇFxx¸ÎdźŠŠ >|XÁČęĆ5ŠÇ{ *• *• Ź=öŇáµXáááňeŚ:uę„Ţ˝{+‘q±¶¶pűĚ{{{lÝş•—Ř%˘&gee…ożýëÖ­©©©Ü%$$ ¤¤DáčjĆŚIŤâˇ‡BEEoäHDDÔČĐ©S'`ŃžČ+++@UU¶mۆ6mÚ(µfË—/ÇĎ?˙ ššBŁŃŕřńăJ‡ET#óş7ˇ–N­VË•ÎÂÂBTVVBĽĽŤÓ§O,--accSëë8::ęĚqrr‚‰‰ ĚÍÍaoo°±±ĄĄeývČHhçSCůWRPPŤFSăëTTT ¨¨H~Ţ®];\ąrŘľ};€Ű—7ŞëĆÖÖÖň   ›_Ą|¬ť‰îUYYJKKü/˙UďoŢK˙S›Ô˙Ľví`äČ‘055ELLŚĽ űźDÔnÝşŕÇńť;wĆwß}‡§žz ©©©řä“O`bbRg»&˝Nměěě ްYR˝ź ýܶ¶¶[[[XXXÔů~Ôň™!„ŇAPÍÔj5ňňňźź/? ˇV«QPP 4ÝşuK(((€Z­Faa!Š‹‹ĺ×j.4g†đśśś`ii [[[ŘŰŰĂŇŇňźłłł|0éŕŕKKKŘŰŰĂŃŃŽŽŽprr‚ŁŁ#‰ZŤFüü|äĺĺÉą·¸¸ĄĄĄČĎχZ­FQQŠŠŠ V«‘źźŹŇŇR”••!//jµĹĹĹr®54@ŇÜ*0Ô•[mmmaii '''XYYÁÚÚŽŽŽ°µµ•󮣣ŁÎő©‰HRN“úž5ö/ĄíŢŞŞ*ńH žöAť“““ŢżÝÜÜŕááWWW¸ąąÁŐŐ•Ĺ""TUUáćÍ›rΕţť››«—wµ‹óRľ&ő×>8V©T:łw´gIů·¶Ů=ŇëÖ¦zžŽŤŤĹŕÁĺçÚť—šTĎuĺ×ââb”——묿“Á$©ŕb4óÉŮŮY§CQ=KyÖÍÍ nnnpwwgńHKYY™śłłł‘ťť­×˙ĚĎĎÇ­[·ôňaM3_ÍĚĚę5!K;Gw–˙¤ő™™Ő¸źÚýŘšHýĎśśĂĎĎOg˝FŁAAAβúć?íőŐëšđWÓY†Ňŕšvťťťáęę www¸»»Ëy‘ĹjÍĘĘĘ““#˙gee!''G§Ť«ŢJŹÚŽ—ťśś`aaˇ7^[@»m24ůFjO˙ók4|űí·xüńÇël×ęsV@]g)Tď'h·…†&AŐ46§Ý¶Ő·ŔbąąąNW˝/P[?€gJ7 îRff&233qăĆ dff"--M§HpóćMdggăćÍ›z¦¦¦pss“¤/öóę ÚĎë:‰îśt ™vr14¸$-ÓN<·nÝBNNŽ^ÂŢŢ^nФĆMj輽˝ááá___xzzÂÓÓSˇ='"2~ůůůHMMEFFŇŇŇ™™‰¬‚ńżÂ IDAT¬,˝Bôł:9ďÖ'×J­NNN°±±©óŇ{tçňňňPRRb0×ĐŇžl‘““#wj$zť éßnnnđńńA›6mŕíí ///ů‰¨Y©ŞŞBff¦śÓÓÓ‘‘‘ˇW,—úźŇŔŽÄĚĚLŻ˙YWÁVűQ×D2şsŇÄ9C}MCąŻz?őćÍ›zE;;;¸şşÂĂĂC§ďéęę ///ť<čááÁ›H“QÓh4ňX[zz:ŇÓÓĺɸŐÇÝrrrt.í ÜwsuuŐ9ţŻi`şz(őX”kxRˇ˘zűg¨Ý3´<''Go2’………ÜÖIĹUí~€——ĽĽĽäöŻ®IZd Ő"99)))ČČČ,RSSu Ú§ ŮÚÚÂŰŰ[/IK3´—I?µg Ró'„ĐKdÚ3~Ş/OKKÓ9°W©Tđôô” ŐúűűĂĎĎŹ•U"jQÔj5’““qăĆ ť|[ý§ö`±ĄĄ%<==ḵ†Š¶,ş·<ĹĹŵćY©Ŕ$-ËĚĚ„ö!Ż4"u$Ľ˝˝Ń¦MřřřŔËË íÚµ——Ź×¨Ńĺĺĺ!99ׯ_Ż1feeéĚÚtpp@›6môň]ő3˘Ąő... î!5CýOí™×ÚËŇÓÓu&6š››ĂÓÓÓ`lÓ¦ Ú¶m ˙:ďĄDt7233‘’’‚´´4y¬M{˛PFF233u&i:99ÁÓÓSg XűŘ_»í“ţM-SQQ‘|ĽŻÝÖUźĚ­Ý¨ţ·$µyÚmź4×¶m[řřř°YM«+ äää 99Y~$%%é<ĎÍÍ•·µµµE۶máááQëO^«‹îFQQ‘\2ô3++ ׯ_×)4¸şşÂĎĎţţţđ÷÷Gűöíáçç‡víÚÁĎĎ®®® î‘®ââb$%%Éą6%%IIIňĎŚŚ yP×ŇŇRo@×P‡–ťşČĘĘ’ólM+íBĄĄĄ<€"=Úµk'˙Ű××—3r‰¨NŇ@™”˙¤>¨ô\űľŽŽŽućAžGwĄ¤¤¤Î<ššŞsI'GGG9Pzxxx(¸GdŚ*++‘––&·uR»'ő’““u&ąąąé äVoĄgŤÓÝ’Îf‘ÎdŃ>«E*XIgąKĹz333x{{Ëmź4'ýl×®]«ű›l‘„śś\şt /^ÄĄK—půňe\şt ‰‰‰ňiM&&&đňňŇ€ŐN†, 1(..Ö)rU/€Ą§§Ëöööhßľ=şté‚.]ş sçÎčÖ­:wîĚâ5Š˘˘"9Ď^ľ| ¸|ů2®^˝Šśśy;777ů Kę€Ją—P2•••ČČČĐ›d" ţiwzÍĚĚŕăăÎť;ëĺÜvíÚ±¸@ÔŠdffęő=/^Ľ¤¤$˝6ĂĎĎíŰ·—űśR^ôőőea€ŚBII ®_ż®ÓďLIIÁµkלśŚ´´4ůňIÖÖÖčСś µó!‹ -Wee%®]»&·wRŰwůňe¤¦¦Ę°–––:®Úý^V’ŚŠB.úKĹ.©í“–iß[ÂÝÝ:tŰ>©ýëÜąsť÷±hŽšmAŁŃŕęŐ«8}ú´Ţ …4`accŁóŮľ}{ťÁŠşn:BÔ”——ëTőu:/ŇŤq\]]ŃĄKtíÚUţN cÇŽµŢśŚRRRpîÜ9\¸pA§ŁpăĆ ·/ĹÖˇCąŤéСΌ5婥ČĚĚÔT‘:Ě/^DZZ€Ű×bmßľ˝\PčŇĄ zô耀Ţđ™¨™Ş¨¨@BBÎť;§7YM:‹ŔÁÁAgA;ň¬%j)***šš*Ď.ŻŢ˙”Î`pttÔ)(téŇ={öD×®]yif"77gÎśABB‚|üéŇ%\»vMľ¬·ŹŹŹü˙Ü©S'ťâ¨———Â{@Ô° túRűWŰ÷Bj{öě‰öíŰ+ĽwŻYrssŹ3gÎŕĚ™38uęÎź?Ź’’››Ł]»v:IIꨵmŰVéЉ%„ŔŤ7tű¤B[RR*++acc=z wďŢ@@@‚‚‚x­T˘Vި¨çÎťĂéÓ§qúôi9ďćĺĺÚ¶m«7ăşK—.śqM„ŰßC9÷ŇĄKňcűöíĺ|   tęÔ‰Ĺ|"#’žž.ç?©zţüy”——ĂÂÂB§`®ť===•ťHqĎČILL”żCRQ]ę{˘M›6J‡Ţj•——ăÂ… 8{ö¬|üćĚy˘‹‹‹ÎY&-}¦5ŃÝĐ>3çâĹ‹rűwĺʤ¤¤@ôęŐKîHí`s¸ßŚŃ˛łłqôčQ;v 'NśŔ™3gšš đňňŇI0čŢ˝;Ď$ ş ĺĺĺ8ţĽNaîôéÓČČČp»b>}ú`Đ A0`ÜÝÝŽšRaa!Ž?ŽŘŘXśzHH €"88XŃËż5iˇ˛˛qqqŽŽĆŢ˝{qüřq”––ÂĂĂC4húőëÇŽDFD{–˛TěËÎΆµµ5ú÷ďŹŃŁGcôčŃ0`8Ś„gĎžELL bbbđÇ ??ööö0`€śwČAI"#"„ŔĹ‹qěŘ1y€óěŮłĐh4čС† †1cĆ`ôčŃśHT‡˛˛2>|111Ř·oâăăQQQ??? 8PěŰ·/oäIdDĘĘĘtŠ}GŹĹőë×ĺbßČ‘#1fĚ 2VVVJ‡kT.\¸ ˙k÷Űűőë§ÓđőőU:T"2 °°ţů§|užcÇŽ!33VVVčÓ§FŤ…ŃŁGcĐ AMzEžF/ \Ľx111ŽŽĆďż˙Žüü|tďŢŁGŹ–®:4fDÔqäČ9r{÷îEBBĺą1cĆ sçÎJ‡IÔŞ¤ĄĄÉ97&&đőőEhh(† ‚Aˇ{÷î,ô53ĹĹĹrGâŕÁ8pŕJKK(çܡC‡ÂĆĆFéP‰%„@||Ľ>VVV:t¨\X ‚‰‰‰Ňˇ6©ôôtěÝ»Wn÷RSSѦMŚ5 C† AHHyĺ˘f,)) GŽÁ±cǰoß>ś={6666l<ˇ7  QŰż/ TUUáŕÁŚŚÄîÝ»‘’’OOO„††ĘŤ:+ťD-ĎŤ7-\fggŁ]»v0aÂĂĂ1tčPšš*&Q‹ŹDEEáÜąs°··Ç#äśŰ˝{wĄC$˘V^^Ž?ţřC.ž>>1cÂĂĂÂ6čś;wŔĄK—ĐąsgĚś9ăÇŹGHHgµ2ąąąŘ·o˘˘˘đăŹ?˘¨¨ŁFŤBxx8¦Nť ĄC$jP•••Ř»w/"""°sçNbذa>}:ĆŽËł`‰ZˇK—.á·ß~Ă?ü€ÂÁÁS§NEXXBCC›ýńńéÓ§‰ČČH\ľ|]ştÁŚ30nÜ8„„„(zmt"RVBB˘ŁŁ±sçN}ú( µZŤ_~ůEž™¨V«1věXĚ›7“&Mjö(ÔşĹÇÇăóĎ?ÇöíŰ‘››‹Á#<<3fĚ@›6m”ŹŚDFFvěŘÄĆĆÂĹĹ3gÎÄ“O>‰Ţ˝{+^˝Ą§§ăË/żÄ–-[€Ž;",, aaaÍj?¨édddŕ‡~@DD> GGGL›6 O>ů$ pׯ{W„˝{÷âÝwßĹ/żü___Ě›7áááčÖ­Ű]BD­CBB"""đĺ—_"55&LŔ˛eË0bÄĄC#2J§NťÂ»ďľ‹ŘÚÚâ‘GÁ¬Ył0`ŔžÉCDµ*--ĹîÝ»±yófüüóĎhÓ¦ ,X€E‹ÁŮŮYéđęĄŞŞ ;věŔűᅬ#GŽ gĎž?>fÎśÉKăQťnܸíŰ·ăË/żÄąsç0dČ,Y˛Ó§O7ÚKě=zďĽóvíÚggg<účŁGßľ}•Ťš‘ôôtěر_ý5ţúë/ôíŰ‹/ĆěŮłďř¬„;* üúëŻX˝z5Ž=ŠĐĐP<űěłxđÁy3F"şcŤ»víÂĆŤ±˙~ <˙üç?1jÔ(ĄC#2 ýőVŻ^Ť¨¨(ʉŢÚÚZéШJNNĆgź}†Ď>ű •••xć™gđ /ŔÉÉIéĐ B`ëÖ­řç?˙‰Ë—/cĆŚX´h† ¦thDÔL8p›6mÂ÷ߏ®]»bĺĘ•7šI9Ŕš5k°˙~ 4‹/ĆÔ©SüZćDÔú;v ›6mÂwß}¬X±Ź?ţx˝ĎN®Wą511'Nĸqăŕćć†#GŽ &&“'Ofń€îŠ™™¦NťŠ}űö!66ÎÎÎ Ĺ´iÓ¨txDŠÉÉÉÁüůóŃŻ_?ddd`×®]ř믿0oŢ<č®ůűűcíÚµHJJÂß˙ţw|ţůçčÜą3>ýôS4Ŕ-ŃT\\ŚÇ{ Ć… ÁâÝ“áÇ#22çĎźG˙ţý1gÎ <ţů§˘q%%%aÚ´i1bLMM±˙~ÄĆĆbÖ¬Y,Q8p 6oŢŚ+W®ŕŔ’%K„ß~ű­^ż_gá_˙ú‚‚‚píÚ5ěßżQQQ ąçŔ©ů©¬¬Äü-[¶(Jj©űŐś 4?ýôöěŮ‹/"88›7oV:,˘&ŔŔ@DGGăŰożĹŃŁGńŕͬ(j-5/µÔýjněíí±bĹ \ľ|Ź>ú(/^ŚqăĆ!==]éĐ Ńh°fÍ 2VVV‹‹ĂW_}….]ş(5±–š3Zę~57]»vĹ7ß|ăÇŹĂĘĘJ>^ŁŃ4y,ß~ű-‚‚‚€={ö &&†—÷mĄZjűĐR÷«ąňóóĂG}„sçΡk×®7n.\’’’ÚQÔ ŞŞJ,[¶LššŠ_|Q”——×´©˘ŞŞŞÄ›oľ):vě(zőę%ěěěaff&4Ťbq 2D 2DoyyyąX˛d‰XĽx±čÜąłX´hQ˝^ďűďż3f̱yóćZ·˙â‹/aaa!V­Z%®\ąrWű!ÉĚĚ/Ľđ‚ xŕz˙^VV–ř׿ţ%ÂÂÂÄś9sî)†ĆĐ’ö«¨¨HĽůć›âŃG˝§m”VVV&–/_.LMMĹ /Ľ ŞŞŞ”‰¨I|öŮgÂĚĚLĚš5KÜşuKépô0ßĆ|[?-eż*++Ĺš5kÄĂ?,V¬X!¦L™"vďŢmpŰćs…"..NtéŇE´mŰVś;wNép¨+))“&MÖÖÖbÓ¦MFy Č\hsaý´¤ýŞ+ÇÝIľTZUU•ظqٰ˛˛S§NĄĄĄMöľ/ľř˘011Ď?˙Ľ(++k’÷˝Sl÷ c»W?-eżęۦ5§¶O˛}űváââ"(nŢĽYăv5ţńŹ+++ńĂ?4J€ ĺŤ7ŢŽŽŽââĹ‹BۉěůçźDFF†bq <Ř`c¶víZ1xđ`!„ű÷ď'N¬÷kČŤYďŢ˝kÝ688X#FڏłŔkˇŃhîřKź““#uęTŻ@DµëŐ«×=ýń~~~€Ř»wŻÁm~˙ýw1qâÄFů˘ÝíkË—ľ&-aż*++댧>Ű“¨¨(aff&:¤t(DŤ&))IŘŘŘ÷Ţ{OéPjĹ|«ŹůöÎ5çý:yň¤ Ž;¦ł|őęŐ˘sçÎz Í-çŞŐj1lŘ0Şt(Ô }ňÉ'ÂÁÁAś?^éPjĹ\¨Źąđε„ýŞ-ÇÝiľ4&gĎžöööâłĎ>kÔ÷Ů·oÇÜ Ű=ăÔś÷«ľmZsnű„¸}¶H»víÄłĎ>kp˝Á{ ¬Zµ O<ńĆŹohµQÉÎÎĆÉ“'‘››«ł|É’%ČĚĚT(Şš]˝zőž_cÉ’%€ 6\˙á‡béŇĄ÷ü>ÔĽÔç†ćÍí¦ç>ř žxâ Ľúę«J‡BÔhÖ®]‹}»Í|«Źů¶uůňË/aooŹţýűë,5j._ľŚß˙]gys˹غu+:„ýű÷+µ"ĺĺĺxíµ×đÖ[oˇ{÷îJ‡S+ćB}Ě…­Sm9îNóĄ1éŮł'Ö®]‹5kÖ ĽĽĽŃŢçŐW_ĹSO=Ĺ1·FŔvŹZ}Ű´ćÜö€‡‡ľţúk|öŮgHIIŃ[ŻW@ČČČŔÁ1kÖ¬& đ^Ť5 ąąą9r$.^Ľ(/6lBCCQQQ_~ůóćÍĂĂ?Śôë×–––čׯŽ?®óz/^Ä´iÓ0uęTôęŐ |đŢ{ćććbáÂ…xć™gđŘcŹaôčŃ8ţĽĽ>99ëÖ­CŹ=äe۶mĂÜąsQZZŠřřxĚť;oĽń˛łł1iŇ$`čС8qâ ¨¨K–,A÷îÝ‘””¤óţŹ?ţ8°gĎ$$$č¬KIIARRFŤUăgvůňeĚ™3‹/Ć„ 0eĘ\ştIo»[·ná©§žÂÓO?Ť^x«V­2řzőůĚęRUU…C‡á©§žÂ#Ź<‚ăÇŹăľűî••îż˙~””” &&ÁÁÁ°˛˛Âرc‘źźo´űĄV«±páB,X°011··7†Šk×®Őůjµ;věŔś9s0wî\ś?ˇˇˇ°µµĹĉQ\\\ďXš»đđpüţűďČĘĘR:˘F±}űv„‡‡+Fťo™oŤqżš2ß:tť:uŇ»©y§Nť E şűřř`čĐˇŚŚT:jE<ôôt„……)Jť ™ ŤqżŚ­ďŮÜóĺěŮł‘––†Ă‡7Ęë߸qüńfĎžÝ(ŻßĐŘî±Ý3Ćý2Ć>@soű`ÄpssĂÎť;őWV?%áĚ™3€¸páBŁźŃ’““EçÎťaee%Ö­['*++ĺő………bďŢ˝€đööďľű®8}ú´Ř´i“°˛˛ÎÎÎ"==]!DzzşđđđOS:sćŚ011źţąüzĹĹĹ" @lÚ´I^Ö·o_Ń®];!Äí¶üţűď˘cÇŽÂŔÇkđô››7o [[[˝kł˝űî»bË–-zż/„Ë–-ÄO<ˇł~ĹŠ⫯ľŞń˝RRR„›››Ř·oźĽlĆŚÂĹĹE$&&ĘËĘĘĘDßľ}Ĺ| /űńÇő^ł>źYM±hËÎÎß|óŤ üýýŧź~*ňóóĹÚµk1aÂńÎ;\<ńŢ{ď bíÚµF»_‹/={öBÜţ511ÁÁÁ:ŰÔöĹĹĹ"22R;v˙řÇ?Dll¬X˛d‰ Ö­[gđs¬ës®ď6Ćäüůó€8sćŚŇˇ58µZ-LLLÄÎť;•ĄN̷̷Ƹ_M™oíěě žÂ_ZZ*‡zHo]sËąB1kÖ,1eĘĄĂ VdëÖ­BĄR)z3Îúb.d.4Ćý2¶ľçÝäKc˘Ńh„ąąąŘ¶m[ŁĽţ‰'qůňĺFyý†ĆvŹíž1î—1öš{Ű' ˙űßő–ë}ŰŠŠŠ„µµµřţűď›$°†PXX(žyćajj*A‰””ťműďż_g™ôĄxăŤ7„B,Z´HtëÖMg›®]»Ę”B±rĺJѦMťÜíŰ·‹ůóçëüŢ„ ęÝIďmjj*®^˝*/;v¬ŢÍ+¤×LIIćććÂĘĘJdee !„())Ý»weee5ľ×cŹ=&:v쨳L ť;w®Ľěí·ß...˘˘˘B^¦V«ő^ł>źYmű]1nÜ8ůyvv¶Ţ˙]aaˇ fÍše´űĺčč(ĆŽ+?ďŮł§P©T:ŰÔőUUU€ÎëäääbćĚ™zďY[}şQ^ż  @XXX4‹ D¶{l÷ŚmżŚ±ĐÜŰ>!n˙ŤŰŮŮéÖ„ÂŐŘÚÚâ‘GÁúőë1yňäfqýV;;;lܸ?ü0ćÍ›‡#GŽ`Č!řóĎ?áéé)ogn®»»áááxîąçpęÔ)@TT`Á‚ň6^^^P«Őňóďľű˝ző‚©é˙®ţ4cĆ Ě1C絫ź˛R—ĄK—â“O>ÁĆŤńŢ{ď!99>>>°¶¶6¸}۶m†­[·âăŹ?ĆŞU«°eËĚś9–––5ľĎĎ?˙Ś   ťeÝ»wGűöí-/۲e ‚‚‚t>3 ˝×«Ďgv§´˙ćśťťčţßŮŮŮ€Î)Eƶ_VVV:× óńńŃ»†b]ď!ý ©T*y˝‹‹  ¤¤¤^q4w•••Xż~={ě1ŘŘŘ(QŁX´hÖ­[‡Ĺ‹ĂŃŃQépjĹ|Ë|klűŐ”ůÖÖÖŤF/†ŠŠ €˝˝}˝b6f»wďFBBćĎźŻt(ÔŠbČ!xóÍ7ńő×_+Nť ™ ŤmżŚ­ďŮÜóĺ[o˝…aÆ!  Q^ßŢŢŹ=öÖŻ_ʉ'r̍ힼŚížq¶{őmÓš{Ű7n„¦Oź®żŇPĹ!##Cxxx ő]˘ËËËő–•––ŠÉ“' âĺ—_–—Ă@ŐŞ˘˘B3fĚBann.FŽYë{ŞT*1|řđ:c{ŕî¨*„“'O˘  @ĽýöŰ:§i˙ľD:őÍĂĂC”––Šţýű‹ŚŚŚZßËÜÜÜŕ)5ŁGŹÖ©ÖYZZęTájzÍú|f5ĹRßíęłĚŘöKŞ´ÇĹĹ ŤF#:uę$ľůćťmęóőý<ęłîN¶1ŤF<ńÄÂÓÓSçĄ)++AAAâţűď×›c,o™oµă0¦ýjĘ| ¨÷»YYY€XłfM˝ă6F§OźnnnâŐW_U:j…ţüóOaaaˇsÉcĂ\Č\¨‡1í—±ő=ď&_ äáBIDAT‹÷ß_XXX'N4ęű¤ĄĄ www±`ÁŁľ|Ű=¶{ÚqÓ~c 9·}B%T*•ŚŚ4¸^ď&Ęŕéé‰|óÍ73gŽŃÎvţüóĎunâÜ®B}ôŃG wł“꤂tďŢŕää„óçĎCˇłťEEEnW”Nž<‰ŇŇRťm4Í=U`ٲe(((Ŕ×_ŤŘŘXŚ1˘Öíűôé#F ++ Ź?ţ8zôčˇSý5ÄŰŰ—/_Ö[nbbůąJĄ2x3”ęęó™5cŰŻĄK—âŐW_ĹëŻżŽ•+WbíÚµxä‘Gô=Z˛’’Ě™3[¶lAdddť×DÍ™ĄĄ%¶oߎřřxŚ;™™™J‡¤‡ů–ůVblűŐ”ůvčС¸zőŞŢriöÓđáĂëýZĆfďŢ˝>|8\ăŤîSż~ýđńÇcéŇĄXąr%ŞŞŞ”Is!sˇÄŘöËŘúžÍ1_j4üă˙ŔsĎ=‡O?ý}úôiÔ÷óňňBdd$6oŢŚŮłgm˙źíŰ=‰±í—1öšcŰ'ůüóĎ1uęT,[¶ 3gÎ4¸ŤÁpűÎËżýö~űí7ôíŰWďÎéĆ C‡x饗ô–K—€čСC­żřđaššbÎś9€‘#G"33›7oÖŮî˝÷ŢCNN€Űwš/,,Ä›oľ©łÍĆŤĺÓRîÖ}÷݇ţýűcíÚµčŮł§Ţ)YŇ©0•••ň˛eË–¸}šĐŇĄKë|ŹÉ“'#99gĎžŐY~ůňeL™2E~>tčP$%%áđáĂň2é@^űËWźĎ¬6ąąąz§Ý cŰŻččhTTTŕÇÄ믿nđ xŻďŃRĹĹĹ!88ŃŃŃří·ß0lŘ0ĄC"jtť;wĆáÇ‘™™‰ŔŔ@ěÚµKét0ß2ßJŚmżš2ßÎź?9998}ú´ÎňcÇŽˇcÇŽ¸ďľűęýZƢ´´+V¬ŔرcńŕbűöíÍâR Ô2Íź?›7oĆşuë0jÔ($%%)’ćBćB‰±í—±ő=›[ľĽrĺ Fމ 6ŕŰożĹßţö·&yß#F &&űöíCpp0bcc›ä}ďŰ=¶{cŰ/cě4·¶˛łł1}út<ýôÓxíµ×ôľw:ę:…áúőë"44TššŠyó扴´´zźţĐŘ.^Ľ(… ę\öaĺĘ•ÂĹĹE$%%ÉË‘››+„"??_—^zIŢ毿ţÂÜÜ\,\¸P|ňÉ'bÎś9bÆ ň6'OžVVVň E6lŘ ¦M›¦wÓé1cĆB­VËËŠ‹‹1fĚ÷iëÖ­€¸pá‚Ţşk×® @÷cUUU˘k×®z§xÝşuKĐ[žťť-üüüÄäÉ“ĺËSíßż_řúúŠ›7oĘŰĹĆĆ sssѡCqřđa‘››+Ţyç@x{{˧´Ôç3“N[?~ĽŢ>µmŰV<ýôÓB!*++ŞÝĐĄ¤¤Dˇˇˇň2CŰŰ~yyy‰€€ńâ‹/ŠŐ«W‹ 6_~ůEçôÄşŢĂĐë—•• @˙ćDÚŰşiËťlŁ”´´41oŢŰ(!99Y<óĚ3ÂÚÚZřůů‰­[·ő˝WšÂţýűEpp°033=ôb óímĚ·Ě·ŤFĽőÖ["<<\<˙üóbîÜą"**Joߍ5çj4)‚‚‚Śrr‘D­VË[WWWńÚkŻÉRJa.ĽŤąą°>9®ľůR ąąąbÍš5ÂĹĹE899‰ 6ŠŠ ĄĂ?üđčÔ©“°°°O<ń„¸rĺŠŇ!±Ýű/¶{l÷ęۦsŰ'Äíż˙wŢyGxyyÝńDŤz$%%%âĂ?ľľľBĄR‰Yłf‰ŢUĐM h7±Űµk—ř裏”îAEE…x饗Dll¬Î˛ kkk#3.aaaBĄR ???ńŃG‰ŇŇRĄĂ"2ŤFl۶M1f̱sçNQYY©thµbľĄ¦Â|[999býúő˘C‡ÂÔÔTĚš5Kś:uJé°ę”““#V®\)śťť…ťťťxúé§Ĺ™3g”«NĚ…ÔT ëďôéÓbÁ‚ÂÎÎN¸¸¸Ő«W‹śśĄĂҡV«Ĺ˙ýß˙‰Nť: 3331qâD±gĎŁľŃ˛„í5¶{w.!!A,Y˛D899 {{{±|ůň;žDTă= ±¶¶ĆłĎ>‹«WŻâ«ŻľBRR† †=z`Íš5uŢ@…j'„Ŕ¦M›0wî\ĄCˇ{0cĆ ÄĆĆbĐ Aň2sssx{{×yŤŔ–îüůóXłf zôčáÇăĆŤř׿ţ…Ë—/cѢE°˛˛R:D"ŁajjŠYłfáÔ©SŘ˝{7,,,0}útřűűăůçźÇ±cÇônEőĂ|Ű20ßÖ®¤¤Ű·oÇĚ™3áëë‹7Ţx“&MBBB¶mۆŔŔ@ĄC$Ş“‹‹ Ö¬Yääd¬]»ű÷ďG@@BBBđŢ{ďáĆŤJ‡Řl1¶ Ě…µ»~ý:Ţ{ď=„„„ 00Ŕ[o˝…¤¤$¬Zµ ...J‡¨ĂÂÂŹ?ţ8‰ŇŇRL0;vÄ‹/ľh”÷&mNŘîµ l÷ę'55~ř!†ŠîÝ»c÷îÝxĺ•W””„őë×ĂËËëŽ^Ďün‚°°°ŔÜąs1wî\ÄÇÇcË–-řú믱zőj!,, áááčرăÝĽ|“n´rŻ7\i,ýúőCaa!|||0|řpů†4Ô<ĹÇÇăćÍ›řꫯpß}÷ÁŇŇÇŹÇúőëńé§ź*^“»|ů2"##3gÎŔßß3gÎÄÖ­[Ń»woĄĂ#2z&&&?~<ĆŹŹk×®aëÖ­Ŕ{gvíÚ!,, 3gÎDż~ý”•ů–š󭾲˛2ěŮł‘‘‘ŠŠByy9ĆŚO?ýÓ§O‡­­­Ň!Ý{{{<űěłxć™gpđŕAl۶ k×®ĹňĺË1xđ`„……aĆŚwÜn Ě…Ô” őĄ§§cűö파Dll,\]]1}útĽýöŰ6lŢŤsŤ‘™™¦M›†iÓ¦áŇĄKŘşu+"##±~ýz´oßaaa Cź>}”Ű=jZl÷j–žžŽ;v`űöířăŹ?ŕěěŚ)S¦`ŐŞU …©éťG «ˇN‡¨ŞŞ±±±bÉ’%ÂÇÇGÁÁÁ⥗^{÷îUěŇ$)))ňułěěěÄşuëtnôb ¦Nť*,--ĹC=¤sjžÄ< ěíí…JĄÝ»w/żü˛ČČČP:´&QZZ*˘ŁŁĹ‹/ľ(z÷î-___ńÜsωŘŘXŢ߀¨ś;wN¬ZµJtëÖM:t‹-;wîyyyMó-5µÖžo%W®\ź|ň‰>}şpppćććâţűď_~ůĄŃ]š¨!UTT_~ůEĚ›7O8;; SSS1tčPńÚk݉ŘŘXE®iÎ\HMŤąđv[+Ö¬Y#† "LMM…‹‹‹?ľřő×_Ťâţ ĺôéÓâŐW_Ő9ţúé§Ĺ÷߯Ř}bŘîQSc»÷?âСCbŐŞUbĐ AÂÔÔT8;;‹yóć‰={öňňň{/!ţúUUU8|ř0~ţůgDGG#>>VVV:t(ĆŚ1cĆ 00°YT~‰¨vBś:u ŃŃщ‰ÁˇC‡ V«Ś1cĆŕŔŕÁď­ŇIDµ:uę~úé'DGGăČ‘#¨ŞŞB˙ţýĺśsó»:éŚLnn.öďߏččhDGG#11nnn ĹčŃŁ1eʸąą)&Q“*//GLL öěŮ$$$ŔŃŃ#GŽ”saçÎť•“ČĄK—äţçţýű‘źźŹnÝşaĚ10aBCCˇR©”łQť>}QQQ‰‰All,4 úöí‹ŃŁGcôčŃĄu}}˙z᪂D•Dq˘Ńš¶ŃL;}‘¦˙u2ťéLë%I›ŕ%QDä"ąÉĺy‘gďěĂEcMĐřýĚśÁp49]kďµö>ÔńîÝ;¬ŻŻcee«««ŘÜÜ„N§Ă?ü€§Oźâ—_~Áââ"őDŠp8,óŕłgĎH$ŕrąđřńc,//cyy>äűo]…BýőVVV°¶¶†••„ĂaŘív™ź>} —ËŐéKí|>Źß~űM}>L&ľýö[ó–––ŕt:;}©Dt ŮlŻ^˝’ńomm ŃhŁŁŁ˛YřôéSÜąsçł_Ëi 4ÚŮŮÁóçĎĺ7  §§łłł2°=~ü^Ż—“!˘ŞV«ŘŮŮÁęę*VWW±˛˛‚·oߢZ­bzzZ6ţůgLOOwúr‰¨…H$‚gĎžá÷ßÇÚÚ677Q­Vq÷î]™s———±°°˝^ßéË%şŃ’É$^ĽxˇiҧÓiMđ§ź~ÂŹ?ţłŮÜéË%şęő:^ż~Ť_ýU6âÂá0t:e\ZZş2ďáGt“˝˙^“_ż~Ťłł3ŚŤŤÉbř“'O°°°Ŕ»Z´ŹÇńüůsüńÇX[[“ßC§Ó)ëmKKKX\\D§/—đˇţööí[űÖÖÖ°˝˝-çîbĽňäÉĚÎÎ~ńëëHˇQ"‘+«DG%›ÍÂl6cnn xđŕćçç1??›ÍÖéK&úę¤R)ĽyóŘŘŘŔëׯ±µµ…|>«ŐŞY˝Ľ´´ÄD×T.—ĂË—/ee}}Ńh:ť3332׊ăK¬f şi*• ü~żĚ·"÷†B!twwcffFI–——q˙ţ}ôôôtú˛‰ľ‡‡‡rqĚúú:^ľ|‰Bˇ«ŐŠůůyÍÜóÁ,°}Ůl›››đů|ręóůÉd`2™đÝwßiŠÝ\=˙ď‰]˘Ţ¶˛˛"ÇŹGÖÜDěóx<\ĚKô% ř|>ř|>ű¶¶¶P,aµZńčŃ#Ů0xôčŃ•¸{Ŕ•h 4ŞŐjŘŢŢĆźţ)żˇ>ź±X ŕv»ep[XXŔÔÔ¦§§y $˘OÉd4 P(p8źźÇÂÂćç籸¸ű÷ďsAô xůňĄf CCCřć›ođŕÁĚÍÍaff^Ż—MD˘OP­V±żżŹ@ €íímů;¶˝˝Ťb±˝^ŹŮŮYY¤\XXŔ÷ß«ŐÚéK'şQÎÎΰ±±WŻ^ɱń›7oJĄĐŐŐŹÇ# sssrţi2™:}éDW^>ź—óOńűĺóů°»»‹z˝Ž[·niw>Äüü<ßżë3‹FŁxńâ…Św›››đűý¨T*čëëĂěě¬l,ĚĚĚ`jj n·›u˘KH&“xűö-¶··e .ŤśN§fŃÂÇŻěÝx®dˇťX,¦i(lll`kk ĺr0::ŠééiyLMMÁëőÂăńđ¶ tŁ”ËeěîîâÝ»wr°ć÷űá÷űqttME Ń4°Űíľz"ş 2™ŚĚµjł1›Íl6›, x˝^™w§¦¦¸R“nśh4Šťťť¦śű÷ßËqŞÓ锓uBÎ ŃŐupp É…>źOŘşşş066&sˇČ‡SSSŕď6Ý(•JÁ`@@ćCżßŹ@ €ÔëuôööÂëőĘ†ą‡ŽŤŤuúňé˙•J%lmmi=ęb^Á Çű"öÝ»w^Ż###ľz˘ÎČĺr2Ţ©ó€@ €ţů4Mąąą9oÝşŐá«˙tתĐJµZĹŢŢžLTâ?Éď÷# ÉD5>>ŽÉÉILLLŔívcbb‡Óéä¶pşV*• "‘ööö°żż/÷÷÷ ±··‡jµŠîînŚŤŤijâ㉉ ţÜŃĄjE~ż;;;8;;¸\.™sŐĽëv»1>>ÁĐáWAt9©TJćY5÷†B!d2€Ĺbi™s§§§a±X:ü*čżpvv†ÝÝ]™˙DÁ`gg‘H Óéŕńx099‰ńńqÍ199‰‘‘‘+ąş¨ťZ­†ŁŁ#ěííÉü'Á vwwĺ8Đétjňź8<t:]‡_ ýétZ3öW‹ĄęčîÝ»2Ö‰z›˙s÷2]W…BÁ`ˇPˇPHÎ ö÷÷ńţý{ąHWä~5öÝ»wÓÓÓpą\×ţ=[®}á<ĹbQÜvww5‰®X,z{{árą4:—Ë…ŃŃQÜąs###p8äŃQ«Ő‹Ĺptt„H$‚h4Šp8Ś`0(T8FĄRŤFͤD,´ŚFc‡_ÝŤ+Ďvww5ĹV1ąčęęÂČȦ±ŕrąŕrąŕp8ä#wŇ—’ÍfqxxX,†p8ŚŁŁŁ¦fA«ź_‘wĹÄŔëőÂáptřŐQ'©«ý~żfü~pp w$éőz¸ÝÝn—yĐn·_űb]őzńxŃhTćĂĆ"Ůy?ż“““rîÉť¨7O,Ó4SE‘5 "Ť˘V«ř°[­[¸Ýn8ťNMÝmhh¨Ă݆nš|>/ën‘HDÎÔH$äçŰl6™ł'&&ŕńx4‹tżć݇_uá"ęQ=öööppp '‹ĐÓÓ‡Ă;wî`ttT9ń±ĂáŔíŰ·qűöm&Lj)›Íâřřńxńx\'q?Çb1T«Uůu‹cccśśÔL2Äăččh_ѧ9o÷ÁÁâń¸ćóoßľ­i(8ťNŚŚŚČ Ćđđ0†‡‡9Ń –Ęĺ2’ɤ̻ęÄ@HÄc>ź—_§×ë122"'ÜACD˙•V+¸Ő9h(Âéé©ü|ťN'óźšĹŁŁŻŻŻŻŚ®ŞÓÓS™c±XŰ<ŹÇĺîŕCˇWä<î ˇ˙Eą\ĆÁÁŚqęťBˇĺÂ^ŕĂ-’Äx_ĚÔĆŞ{CCCŚ{ÔÖŮŮŽŹŹ‘L&‘H$‰DäBˇx<Žp8ŚX,†H$ŇT÷µŰíš&—şŁĆívßčĹ7şp‘|>/kc˘ĹŢH$‚t:­ů:Á ˘© Šây»ÝŽÁÁAX­VŘl6X­V&ák˘V«áää©T '''H§ÓÇă8>>–G2™lz®T*iţ›ÍÖÔŚ…1µPf6›;ôJ‰ľśrąŚx<.› b`§Npc±b±ÔˇKOOOSŽm—{­V«rąśĚ·'''šÜŹÇeŁ@}Nť '¤˘§6¦Ô *wQ'ĺrইšĹźĹű &“Ić;»Ý.óžČâ91˙Äŕŕ w8\őzétZćÁt:ŤD"D"!çžj«…YŕĂ´óň xda–ľ¤T*ĄYT©Ć;5î© VŕCÜkŚq"ŞńPŤyV«•·qľf2™ NNNděńNÄ?5&“IÄb±¦y€^Ż×4˘ÔĆĽşPÜn·óçăl ü …‚ěę«É»UYźG4=·€Üű-KŰů§šM&Ěf3, ŚF#úűűŃßßÁ É‘ôQ±X”óËb±(知RIćHq^,Lkw4Ă€·Ôkś{ ÁáphžyĐáppa]k§§§2î©ăĆů€úŘŞîÖßß/cśŐš›Őj…Ńh„ĹbŮl†Á`€ÍfÁ`±PÔâHKŤ}ĄR ą\ą\ĺrétZžWăžÚ$PŹT*Őňß Ć›FbYc ¤˙PŻ×q||¬YAp^ÁZýĺ999AˇPĐl·oG=QäčííEooŻ r"ŠĎíîîÖśo5ěďď?÷ŤŹÎ;vv†\.×ökËĺrSWYŕĂ-€*•ŠÜĐî|ĄR‘Mb±(?÷Ć&µQyQ‘^P˙žVZÍTjśjĄŐÂĄVÍ µ‘ˇ6GDmîScźzž®/6¨ ÷ĽQ6¨ DDDDDDDDDDDÔ„ """""""""""jň$=“DG¸˝˛IEND®B`‚nipype-0.11.0/doc/users/images/smoothrealignconnected.png000066400000000000000000000265721257611314500235350ustar00rootroot00000000000000‰PNG  IHDR˝µË !ťbKGD˙˙˙ ˝§“ IDATxśíÝy\Íůţđ×I%-"ˇĹhTiQh˛”%3–ÜC˛DŚ,ĂŠ’dk0Évg¦1M2ˇŇ2CcD÷E *&Š‹ČĹER*­źßÝľ·ÓzNťúVçý|<<šó=źĎ÷óţž3yű|żźEŔc „B¤€ ßB!m…’!„©AIŹBÔ ¤G!DjPŇ#„"5dkĆüůóů…B„yóćńéŕę$˝jaaam‡Č‚qúôiěر â;ŇBô}QĚž=›ďH'Ń`Ňł··oË8DvăĆ ŔřńăaeeĹs4¤Ąčű$„´%z¦G!DjPŇ#„"5(éB‘”ô!„H Jz„B¤%=B!R’!„©AIŹ +..Ćľ}ű0fĚŘÚÚÂÖÖÖÖÖŘ·oŠ‹‹…ĘFEEÁÎÎrrrpssCBB‚P???››C ŔŇŇáááضmTTT`dd333¨ŞŞÂĚĚ  ‚˘˘"¶mŰÖ†WOHűÖŕätBř˛łł1eĘ™™áĚ™3PUUĽ}ű«WŻĆ#pîÜ9hii—»wďŽŃŁGcĎž=uÎąlŮ2ŘŘŘ࣏>BXXtttpűöm8;;Ă××rrr@kkküţű朗/-)H0ęé"!ĺĺĺřěłĎ ŁŁŔŔ@.ဪŞ*1`ŔL›6 ĺĺĺÜ{***eeĺĎ=`ŔŔ| *ÁmÝş•KxőéÖ­ĽĽĽZtM„t6”ô‘ŔŔ@\ż~˝ŃDăĺĺ…””Šuî.]şddŞ~eçÎť‹~ýú5YođŕÁppp«-B:3Jz„HHHH455ajjÚ`ccchjj"44´Em\ÖĐаEmŇ™PŇ#DBnŢĽ }}ý&Ëééé!55µ ""„ÔFIŹ ÉËË’’R“ĺ”””——×Bj٤G„¨ŞŞ˘¨¨¨Ér………čŃŁGDD©Ť’!bnnŽ4YîáÇ033:&++‹ĘĘĘë””” k×®-Ž‘iGIŹ ™;w.˛łłqűöíËÜľ}9993gŽĐń~ýú!''§ÁzYYYĐŃŃ‘X¬„H+Jz„HČ‚ 0lŘ0lÝşµÁ2žžž°°°ŔÂ… …ŽOť:iiiČĚ̬·ŢÉ“'akk+Ńx ‘F”ô‘999DFFâŢ˝{Xşt) ¸÷ňóó±dÉdff"22˛˛Â‹!mٲZZZ6m’““ąă8xđ Nś8ww÷Ű®SłMBH]”ô‘ mmm$%%ÁŔŔS§NĺÖŢ´łł‘‘®\ąMMÍ:őúöí‹””L0sçÎEź>} ŁŁKKK}:ßčŃŁaii‰?üź|ň Îś9#ń6_ľ|‰ŔŔ@888ŔŃѱÎűVVV°˛˛’x»„B×â¤gooŹ€€Ŕ¨QŁŕĺĺ…áÇĂÁÁ»Ĺ’žžˇzcÇŽ…żż? ,, łgĎni(ő3f Ž;0apíÚ5ddd`Ô¨QřěłĎđÓO?I´Í.]ş@WWaaaőNBfŚI´=B!˘‘Č3˝†V‰ďÓ§€Şçű÷ďG||ĽĐűýű÷€VŠÝ˝{w˙[´¨t°cÇčëë×»ťKK¨©©ÁÚÚşÁ÷ę|„BZ_› d9~ü8ŔÉÉ ďŢ˝ăŽWŹ`«^9ž:::xúô)oíBi;m’mĆŹŹŤ7"33k×®m‹&Eňţý{¤ĄĄađŕÁuŢ»wď>˙üsĚ1ĆĆĆ8tčĐű•••đđđŔ¶m۰zőjXXXŕÖ­[M¶ůřńcx{{×ŰfII V®\‰+VŔÄÄZZZ°˛˛ÂÝ»wůóçĂŃŃwîÜÁ„  ¤¤;;;6ŘfZZ\]]áí퍏?ţ BYYÎź?Ź/ľř ,Ŕ… 0|řptíÚÇGJJ wťqqqXľ|9.\””X[[CAA“&MBQQ.\¸sss(((`âĉxűöm“ź!„đˇÍFoîر/^ÄO?ý„3f`Ę”)mŐtŚ1¤§§ă˙ţď˙P\\\g´ÜóçĎ1fĚ„„„ŔĆĆééé055…˘˘"–.] 8pࢢ˘păĆ Ŕ#ŕě쌤¤¤Ű-++Ă_ý???<|ř°Îű6lŔĺË—‘žžŽ¬¬,|řá‡ĐĐĐ@||<ŠŠŠ––†ŕŕ`čéé!$$^^^ šC‡ŕëëŰŕhAGGG\Ľx˝zőÂW_}…™3g˘¤¤ňňň8zô(´´´0tčP=zqqqX·n&Nś;wî@VVŹ=‚źźttt0zôhś={ß˙=ÜÝÝaooÄĆĆâčŃŁpuu…ŻŻ/6mÚ$Öwâŕŕ±ęB¸Ú쾢¬¬,‚ˇ˘˘‚%K– 77·­šć\ąr–––PTT„™™ĆŽ‹ű÷ďcěرB弼Ľ ¦¦U{ őöŠ‹‹ˇˇˇÁ˝VWWo˛§'''‡±cÇbŕŔőľmmmUĎ;Śôôt€˘˘"7,]OO;wîÄČ‘#áéé Bšk»{÷.bccT §wqq˛˛2w}&&&puu…‰‰ V®\‰Ý»wăÍ›7€şş:·zˇˇ!–/_ŽîÝ»sÉż˘˘ëÖ­ŞŞ*śťť@¤/!„đˇMçééęęÂ×× ,ŔĘ•+qňäɶl#GŽÄożý†O>ů111(((J\ŐŞ§1¬X±‚;¦©©)4í˘z4jaa!Nž<‰ĚĚĚ:Ó2"ę=®  €¬¬,îµ¶¶6JKKëÔ“““㎩©©@Ł«űúé§={6ľřâ xzzbâĉBď×^ÄÁÁ®®®¸yó¦ĐńšzöěY§nő@¦Ćnµ6$44”¦q5ô;C¸Ú|‰ŁŁ#ÚćI¨4sâÄ ôęŐ ŢŢމ‰©S&;;zzz8|ř0÷'&&‰‰‰Bĺ|}}±hŃ"Lš4 şşş-ŽÍÍÍ wďŢErr2*++‘™™YgŞGs?~ź|ň üýýa``ooďFËWŻüŃŘŞ˙5`mŤŐ#„>ń˛"‹ŻŻ/±jŐ*>š‡––0mÚ4,X°·nÝâzLĐŁGÜąsŚ1ˇa2ĆPXXeeexyyáűďżÇDÚ8T...ČÍÍ…——LLL°k×.ŘŰŰ·řĽĘĘĘŽŽĆ±cÇŕâ₍7BMMŤ»Y[ő@CCĂ·M!íI«öô***„~VSQQApp0ňóó[łůF}öŮgXµjž={Ć=źŞ6~üxĽxń‚›Ô^íŔxýú5ŕŕÁ044ä^íklŽýë_(++Cdd$ĽĽĽZ”đrssą[Ł?üđ`áÂ…8wîŕüůó ÖŤŹŹ‡ŚŚ ćĎźßěö !¤=’HŇ«^Ů˝ć<xňä =§Şfii‰;vH˘ů&U÷\j'Yŕ×_ĹáÇąăîîî——‡łł3V­Z…ÇsˉUO¤gŚáÚµk‰‰Add$·yh\\233Q^^ ţ[}Őɨćó: jăŮłg±qăFlßľű÷ďGtt4wŽúÎYý±ú˝jfffpqqřűű٬¬ @Ő  ęůfµÔÔTĽyó†űڶlŮ‚ 6pnęűÇKqq1€ŞiŐúG!„´¬–   VĎáEDD°Ď?˙ś`rrrlÓ¦Měúőë,((Ť1‚`666,..®NÝŠŠ 6~üx‘ŰbŚ1777 ŢóŐçňĺËlćĚ™ ëŇĄ [·nKMMĺŢż}ű6ëÖ­“““c7ndĹĹĹŚ1ĆÎť;ÇŚŤŤ™ĽĽ<Ó××gţţţBç `***lĐ AěüůóěČ‘#LQQ‘Mś8‘]˝z•ąşş2¬gĎžěرcěýű÷¬  €ůűűłîÝ»3ĚÍÍŤ=}ú”;§§§'ëÚµ+ ôÇŃŃ‘˝{÷Žmܸ‘`˝zőbˇˇˇ¬  €­]»–`ŞŞŞě·ß~ăÎeiiɶoßÎc ł´´d^^^lĆŚlóćͬ˘˘Bč˝%K–°Ůłg3KKK¶{÷nVYYÉcěĺË—l۶m SWWggÎśayyyĚÝÝť`JJJ,""‚ĺĺĺqĺzôčÁ‚‚‚¸sHňű$Ň â; Ň ´8éµµÎú—dYYsssc‰‰‰BÇ._ľĚşuëÖjí`S§Nmµó7Ął~źD˛(éIˇýôÚ‰Yłf!11Qč¶Ł¬¬,´´´$22”t^ĺĺĺHHH@PPߡŇîQŇk'RSSqýúu ##YYYřő×_áčč(ôĽQ’ŞźóU˙”vqK¨˙üç?pww‡••BBBÄ®_VV¬Yłřűß˙ îµ6őŮŇQPŇk'˘ŁŁ1nÜ8¸¸¸ŔČČ“'OFJJ Nź>Ý*Ń>yň7nPµŰöŢ˝{ńřńc‰·Ó‘tÄ-ˇúôéÓ˘]B|||śśŚC‡ÁĎĎŹtVűZ›úlé(hçôvbŕŔřý÷ß۬˝>řű÷ďÇţýű۬ÍöN”-ˇÚŁ–ěRĚŤH7nĆŤ îµ6őŮŇQPOŹ)VßÂç„tfÔÓ#JJJ ‚‚‚đćÍ8;;ĂŃŃşşş¸xń"€Ş-ˇ6mÚĆ222°téR¬Ył†«_YY OOOČĘĘ"77W®\Á‘#G`jjÚh»Ź?Fhh(~ţůgÜąsGč˝’’¸şş˘˛˛ HOO‡¦¦&tuuáďďŹôôtś:u îîîřꫯpőęUŘŘŘŕäÉ“B+ú4?Ľyónnn‘‘˛˛2ĹţCBBpöěY#55ŽŽŽ044ÄćÍ›˝Ö†4wZZ ©©‰äççăîÝ»bÇMH‹ŐÎISH[çű|üř1Űşu+ŔLMM™‡‡srrbŁGŹfŚ1–““ĂúôéĂţřăĆciiiL 0???î>>>ĚÜÜś{miiÉ,,,„ÚA­iĄĄĄ,66–éééŐű»±zőjfddÄĹ(¸6 YXXŔôôô‡‡KLLdkÖ¬a··7wQâ˙ţ=6l;tčw,22˛ŮSOÄ˝ÖúÚ%nSSSöęŐ+ĆcEEElĘ”)bÇ©˘˘Â¦M›&4­‡qQŇ#Ľ÷ű|˙ţ=ŔŚŤŤëĽ·jŐ*6hĐ ˇcäcŚíÜąSč/Ü©S§˛®]» Ői(ŘÚÚÖű»ˇŞŞĘ&NśČ˝622brrrÜëĘĘJ@¨Ěëׯfoo/Vüß|ó SSSceeeܱ’’‰%˝j ]k}ĺE‰[^^žEDDpŻŁŁŁĹŽsѢEĚĆƆÉË˳˗/‹Uźjt{“t(]»vđżĺŕjęč[B‰PP† "´Ą“ĽĽĽHń‹Cś­|D‰»©í­Dńé§źbŢĽyXąr%V­Z…›7oŇ–CDl”ôH§‘ťť kkë&ç5úúú"&&Ŕ©S§đď˙»EíşąąÁŐŐÉÉÉ6l233±e˱Ď#Jü÷îÝ«łé1ßD‰űřńă3güýýqâÄ lßľ6lhV{«V­Â?ü€;wîŔČȨąa)EIŹt}K(Qâ—““Ăýű÷%·¤·¸Ű[5¦_ż~€śśJzDl4et}K(Qâ·˛˛Â_ý…řřxîýę]7O“çE‰[Üí­S}ëXAAˇą!)F==ҡToˇT˝µQMîî„łł3’’’`bb‚řřx :´Ţ-ˇňóó…¶„ŇÖÖF˙ţý4˝%TÍçhNNNPWWGee%ˇ˘˘###|úé§‘‘yK(Qâ÷ôôÄ… ŕää„cÇŽađŕÁPµ”]xx¸ČI·úybí-®şÖ†¶Ë%n|ůĺ—““«w{+q<ţ„6~&DdµG¶ĐčMŇ–Äů>ţřc())áŇĄKčŇĄ ß!‘N€zz„viË–-ČČČ@jj*%<"1”ô!íÎ/żüooo@__źďpH'B·7 !íĘíŰ·1räH,^Ľ‡â;ŇÉPŇ#„´oŢĽĄĄ%444pá¡} ‘Z‘…Ň.`Ę”)`Ś!""‚iôLŹ»˘˘"Lź>Ďž=Ăĺ˗ѧOľC"ť%=BŻŠ‹‹aooŹ´´4\ľ| ŕ;$҉QŇ#„đ&77űŰß™™‰ţóź4ť´:Jz„^üő×_2e ĘËË‘ČŰNóDşĐ@BH›;{ö,†Jx¤MQŇ#„´™˛˛2¸ąąÁÎÎvvvŤŤEďŢ˝ů‹Hş˝Iiׯ_DzeËp˙ţ};v ŽŽŽ|‡D¤őô!­ęÝ»wpuuĹ# ¤¤„ëׯSÂ#Ľˇž!¤U”––âđáĂŘ˝{7JKKńăŹ?bńâĹ|‡F¤%=BD#00»wďĆË—/±bĹ ¸»»C]]ťďС¤G‘ڬ¬,řúúÂßß………XĽx16oŢ mmmľC#„C NBš-77żţú+‚qéŇ%hiiáË/żÄ˛e˨gGÚ%ęéBÄ’––†óçĎăüůó‹‹C×®]1}útDFFbҤI““ă;DBD==BHŠŠŠpëÖ-\˝z ŹŹÇóçĎŃŻ_?Lž<“'O†­­-şuëĆw¨„„’!Ż^˝Â™™‰ŕîÝ»HMMĹýű÷QQQ]]]Ś5 VVV°˛˛‚‘‘ß!Ň,”ôé䊋‹ńěŮ3äääŕéÓ§ČÎÎĆÓ§OńôéS.ÉĺççC @[[zzzĐ×ׇ±±1ĚĚĚ`jj 555ľ/‰ ¤GH–››‹ĚĚL.‘ĺääŕÉ“'ČÉÉÁłgĎťťŤ7oŢäĺ塡ˇ~ýúAKK ÚÚÚřđá«« }}}čęęBAAç+"¤uQŇ#¤ťËËËĂ­[·‘‘ÁőĚŞćĺĺúöíË%4MMMhkks˙ÝŻ_?hhh oßľ<_ !ü٤GH;R\\Śk×®!!!IIIHKKĂŁGŹ ##p=˛Ú?ůť’!<ެ¬Äőë׹)ÉÉɨ¨¨ŔŕÁ1räH 6 fff011ˇÄFPŇ#„III AXX˛łłˇŻŻŹÉ“'cҤI5j !¤•PŇ#¤Ťäĺĺ! ‡FFFŚŤŤ1wî\Ěž=úúú|‡GT Yie™™™đööƉ' ++‹Ĺ‹cńâĹ055ĺ;4B¤őôi%Ďž=ĂÎť;qôčQčččŔŐŐ ,€˛˛2ߡ"µ¨§G„•––b÷îÝřć›oĐ»wo|˙ý÷X´hdeé׍ľŃo!!‹+VŕŮłgŘľ};Ö¬YyyyľĂ"„ü— ßŇ”••aíÚµ°±±ŇÓÓ±~ýzJx„´3ÔÓ#¤…?~Ś9sćŕÎť;8qâćÍ›ÇwH„POʉ‰ąą9ŢżŹ””Jx„´s”ôi¦ĐĐPL™2vvv¸rĺ >úč#ľC"„4’!ÍpđŕAĚ›7ëÖ­ĂĎ?˙L»ŇAĐ3=BÄäăă777|űí·Xąr%ßáBÄ@“Ó źźľüňKřúúbůňĺ|‡CÝŢ$DD!!!Xąr%öěŮC ŹŠzz„ŕĘ•+7nÖ®]‹Ý»wó!¤™(éŇ„śś >8uęß!Bš‰’!Ť(--…ŤŤ ^ż~Ť«WŻBUU•ď!-@Ł7 i„››ŇÓÓ)áŇIPŇ#¤ńńń8tčŽ9‚Ań!Dčö&!ő(,,Ä!C`hh3gÎđ!DBhĘ!őŘ´iŢĽyü‘ďP!D==BjIIIĄĄ%†ľĂ!„´ŔęŐ«aeeĹ˝¦ž!50ĆđŐW_ᣏ>BRRßáđ&-- áááxőęߡ Öď3<<YYYÂ!„óóĎ?ł.]ş°]»v1iţőpsscX\\ߡ Öď :F==Bţ+??nnnX¶lÝÖ$¤“˘¤GČíÚµ eeeŘąs'ߡBZ %=BĽxńß~ű-6oŢŚ^˝zń!¤•PŇ#ŔîݻѳgO¬X±‚ďP!­Vd!RďŮłgřńÇáăănÝşń!¤QOŹH˝Żżţ}űöĹŇĄKů…Ňʨ§G¤ZNNŽ9‚ďľűňňň|‡CieÔÓ#RÍ××˝ző‚““S›¶{{{ČËËĂĂĂ))) …©©)LLLPRR"TďŇĄK°±±@ €……ÂÂÂÚ4nB::JzDj˝{÷ß}÷V®\Ůć˝<{{{FŤ/// >¸pá ==BőĆŽ @XXfϞݦqŇŃQŇ#RëčŃŁ(//ÇĘ•+yi_EE ¬¬,tĽOź>mmměßżńńńBď÷ďßh=!Í@IŹHĄĘĘJüă˙ŔâĹ‹ˇ¦¦Ćw8ő:~ü8ŔÉÉ ďŢ˝ăŽËĘV=Š—‘ˇ__BÄEż5D*EGG#33«WŻć;”Ť?7nDff&Ö®]Ëw8„t ”ôT:věĆŤ}}}ľCiÔŽ;`ii‰ź~ú çÎťă;B:bł9dee ,Y˛ąąą|‡DH‡FIŹHť°°0téŇ3gÎä;‘čęęÂ××999Ľ ş!¤ł ÉéDę;v źţ9”””řEdŽŽŽŽŽĆ‰'0}útľĂ!¤Ă˘ž‘*YYYHHHč·6kóőő…®®.V­ZĹw(„tX”ôT‰ŽŽFĎž=1věXľCiPEE…ĐĎj***F~~>aŇ)PŇ#R%** “'OF—.]ř 4žřŕUźýÖ­[!''×`ťnÝşÁËË«E×PŇ#R"55€’^+zůň%nܸQg}Đ5kÖŕĹ‹|Ç—ČgŇBBB ©© SSÓËCSSˇˇˇX˛dIłŰŞýÝ5ĆĐаŮí!R`Ó¦MlčС"— b¤ţO\\śČźŮăÇŹŮG}Ä0ćííÍĘËË…ĘĽ|ů’2LGG‡>|˝}ű–íÚµ‹`¶¶¶ĚÇLJĺĺĺ±0l×®]\ý¬¬,¦®®Î.^ĽČ›5kSSSc™™™b—Ŕ¦Nť*#¦««Ëľůć–ťťÍöěŮĂ0źŻÝÔÔ”˝zőŠ1ĆXQQ›2e +((`üńŔ´´´ŘţýűŮ­[·Ř÷ßĎXĎž=YNNN‹?Q¸ąą‰ý}Ş««3kkë&ËYYY±Ţ˝{ «ďs­­©ô#Ę9š€ Łž‘ yyyPWW»^JJJ+DÓţ}÷ÝwřůçźĹŞÓżܸq›6m‚ŻŻ/6lŘ€S§N!44”{vŁ®®Ž… ÂÉÉ †††Xľ|9`éŇĄpwwGEEÖ­[ j`««+nݺŵáéé UUUˇÉů;vě@DD<==ąÝćE-×}}}lذ°|ůr¸ąą5ú˙ÂÝ»w‹™3g˘[·npqq˛˛2lll&&&puuĺţ»´´®®®€»»{‹>“Ö’——'ҢěJJJČËËkőx$…’‘ EEEÜCrĆRRR`aaŃd˝aƵvhí’††Fłę)++ăŰożĹ‚ đĹ_ŕĘ•+=z4’““Ń·o_ˇ˛5—‚ëŮł'€Şýkž ącQQQužËbŔ€ř׿ţ%vą†ÔPŃŁGu—‹«éÓO?ĹěŮłńĹ_ŔÓÓ'Nzżću€\]]qóćMˇăÍůLZ‹ŞŞ*ŠŠŠš,WXXČ}F d!RŁúąŇÁńńÇ㯿ţâ7 N¤¬¬LčőÇŚ””L›6 Ož<ÁˇC‡­ßŘZ¨5§äćć˘ę®•0===ˇ4˘–G}ç«vüřq|ňÉ'đ÷÷‡Ľ˝˝=WďŢ˝ Ń©˘~&­ĹÜÜ“Ö"''‡ČČHÜ»wK—.ĺ¶ÂŞľ†%K– 33‘‘‘užYnٲZZZ6m’““ąă8xđ Nś8ww÷Ű®SłMIˇ¤G¤B×®]!##Sç9@ Ŕś9sÚĺäéŽdŔ€čŇĄ |}}ˇ©©‰qăĆÁŇŇ©©©HHHŕne˝zőŠ›ěś’’‚ß˙oßľĺŽ]˝zżüňKťcÁÁÁ`ŚA]] PPPŔÔ©S±~ýz?~qqqčŐ«ʍĺ6oŢŚüü|ŘŮ١wďŢ\ŻćÚµk Á»wď°}űvîXDDWWKK‹đ“––kkk|ýő×X¶l6oŢĚŤÖŞn÷­_ż8q"ćÍ›‡]»vIä3iMÚÚÚHJJ‚¦NťĘ­˝igg###\ąršššuęőíŰ)))0aćÎť‹>}ú@GG–––xňä ąçšµEDDm»µ~ýzÉţĂ´E“ éŢżĎČdeeëť‹&''Ç&LŔ*++ą:Őóô¤Usću‘úAóÍZJZżOÔ3OŹzz¤ÓóđđŔÇ´RVV†&G܉ÂĘĘ VVVÍŞ[VV¬Yłřűß˙^ď9_ľ|‰ŔŔ@888ŔŃѱĹ1"M(é‘N-..>>>MŽŇ¬¬¬ÄćÍ›‘””Ô˘öX n7ůřř 99‡‚źź˛˛˛ę=g—.] ««‹°°°5)XU?ç«=Ąđ‡&§“N‹1†ŻżţŔ˙ć<55`ćĚ™uFü‰ŁöŢaâćž}Ť7ăĆŤ«÷śjjj°¶¶nv;¤mŚéÓ§s NËÉÉA •ݍ¨Ŕ‹/„nK>äĄ]Ň:>řŕěßżŚ1`ýúő”đÚJz¤ÓűđĂáě쌼yóIIIضmFŤĹ µ–——Pu*<</^»ťÇŹĂŰŰPµęDDDćĎźGGGÜąs&L€’’ěě츥¤BBBŕččââb¤¦¦ÂŃŃ‘ëˇÖ>§(îÝ»‡Ď?˙3fĚ€±±q“«ˇ"UxPCH»QPPŔΞ=Ë\\\ľľ~ť‘ť˘*--e±±±LOOŹ«WXXȦ§§Ç<<>C‡Ą9b„€zz„HÄ»wďpäČ\»v °uëVÜżźŰĆ&)) aaax÷î·ĄĘŐ«WqćĚÜľ}›7oćĘť8qŻ^˝Ş÷śĎž=ĂŁGʰaĂîÇŹç©™™"##1hĐ řűűcßľ}?~<Ö®]ۦź!í•€ŐľůOApp0ćĎźßę[·´W›6mž={×ě´Iű!­ß§@ @PPć͛ǣž!„©AIŹBÔ ¤G!DjPŇ#„"5(éB‘”ô!„H šśNH#ÄYěą3˘Ú;ú>iž!őĘĘĘâ&…B:.KKKôďßź{MIŹBÔ gz„B¤%=B!R’!„©AIŹBÔř®^MT5A}IEND®B`‚nipype-0.11.0/doc/users/images/smoothrealignunconnected.png000066400000000000000000000107731257611314500240740ustar00rootroot00000000000000‰PNG  IHDRÓ=öÇëbKGD˙˙˙ ˝§“°IDATxśíÝ{L×đď OWńEE« ‚’Š«ô‡ZŚ*>ŃřHŤ´ľj µĽT´mj)±hŠŠőA©-JÔJ}`×ĆwĄVZ@E‚tpĎď~ĚŹaY†\Ď'™˝sçŢ;3{8ËÜ™E "cŚ1ƚ̨µŔcŚ˝é8™2Ćc2q2eŚ1ĆdâdĘcŚÉÄÉ”1Ć“ɸn ­1ĆŢ*AAAHOOoöv9~ÓżúâW+™€żż?‚‚‚ZdPŤqýúuDGG·Ůń±Ćy[Ďgpp°^Űo«Çóm=߆ęm=źşâ·ŢdŔŔ@˝¨)Nź> ppph“ăcŤó¶žĎęµ}Ž_ÖŢÖó©+~yΔ1Ć“‰“)cŚ1&'SĆcL&N¦Ś1ĆLśLcŚ1™8™2Ćc2q2eŚ1ĆdâdĘcŚÉÄÉ”1Ć“‰“)cŚ1&'SĆcL&N¦Ś1ĆLśLcŚ1™8™2Ćc2q2eŚ1Ćdâdúyţüyk1ĆX=d%Ó 00‚ ŔÔÔ‘‘‘P©TŘ·o\\\ śťťńâĹ Évżţú+ĆŤAŕćć†ýű÷ËÚ‰W!"lܸ €łł3¬¬¬ ŚŤŤˇŃhôÖosyôčÖ­[‡‘#GbĆŚ­=ś6ăŮłgHLLÄ1cŕëë ___xxx 11Ďž=“ÔÍĘĘÂäÉ“!LLL3gÎHęl۶ ®®®JĄ@ll,A€••śśś0lŘ0‚…BaÆÁÁÁíŰ·‡ ŤŤmÁ˝om=~Ož< q|ŁGʆR©Dż~ý0aÂ:t¨Ůű,--EZZfÎś‰­őîîîpwwoö~ß6żTJOOŻ[¬ÓăÇŹ Ť;VR^RRB­ZµJk»›7oĘĎĎop_§Nť"ŃŕmÖŻ_O …‚ňňňčÉ“'´rĺJ@wďŢmp;-íĘ•+DD¤Ńh¨  €Đ¤I“ZyTÍ«)ç“čöíŰäââBˇˇˇTVV&–—••Qhh(ą¸¸ĐíŰ·%ŰčzźÖvăĆ @˙ţű/ĹÄÄĐÂ… ©˘˘B¬S÷<”——S@@ĹÄÄ4xüAAAÔŕúŤahńűčŃ#@'NË***(**ŠĐ¶mŰÜVCÜżźNž<©3ŢŢ{ď==ztłöů¦âř•’}™×ĘĘ ĐˇCIy÷îÝ˝zőBRRNź>-Yokk čŰ·ŻÜ!ĽRrr2ÜÜÜ0pŕ@€ĄĄ%€»wďęµď¦ĘÍÍETT@ńX1 ŞŞ S¦LAßľ}‘––…B!®S(HKKC˙ţýáç燪Ş*qť®÷imýű÷ôéÓ@ő±Ź‰‰‰‰‰Îm,,,'kźZS[ŹßŽ;Úµk'–™`íÚµ0`6nÜجýY[[ĂĂĂCçú3gÎh Öp†żzź3ݵk`îÜąxňä‰Xnll\=#ýˇ´´üńćĚ™cÇŽařđá033ĂđááR©šíčĂ÷ߏž={ÂĹĹEgť!C† gϞطoź¬ľj®f4„ŁŁŁ¬ľÚŞÖŽ_]ž?ŽË—/cđŕÁZëňňň0uęT`Č!řňË/%ë5 "##‹ĄK—ÂÍÍ —.]zmźŹŹŻ·Ď/^`É’%XĽx1śťť!lllŕîîŽëׯ###ÁÁÁ Áµk×0~üxXZZbňäÉxúô©Î> -† :~ë^÷E#ç\ę»]»ś¨˛˛’”J% ¬¬,­ő Ő”kôôÎ;ď277§řřxŞŞŞ’Ô)--Ą´´4@}űöĄ””zôčmŘ°ŻŻ/%$$PYYmŢĽ™Đ† Äí ©k×®ôË/żeÓ§O'kkkÉśRCëŐw<ťť}ńĹtçÎÚ¸q# „„ťűîââB÷îÝ#˘ęąR«Őtüřq@666”””D—.]˘ŻżţšĚÍÍ©sçÎT\\,ű4DSÎg×®]ÉĂĂăµőÜÝÝ©[·n’2]ďÓşu^·^îÜu[š3­Ů¦­ĆoÝńi4ştéyyy‘••ĺääHęS÷îÝéřńăDDtůňeA2·š@®®®âkĄRInnn:ű$Şž§ÍÉÉ!{{űz÷{éŇĄäääDDŐżsAűxúô)íßżź˝˝=EFFRnn.-[¶ŚP||ĽÎ}oË1Ěń[§íú:kî`$ŞľaÁĘĘŠzöěI÷ďß×ZßM FµZM~ř!5jÖ;ŢÚ7:”––ňöö–´€fÍš%–Í›7Źěíí%m]»vŤPHHHŁëéJ¦^^^âë‡jŤŁ.SSSĘČČ_gggKÚ«˝_D$Ôúőë%őšrL˘)çÓŘŘX2]Ľ˝˝ÉÄÄDRÖÖ±9bü kkk1b™››“‘‘­_żžŠ‹‹µę†……‘¤lĐ Ab˘#"Z·nůřřŻ'MšDfffZ}ÖwL|}}ëÝo…B!‰O'''ÉűOŁŃhĹđýű÷ ęÜ÷¶ĂżR-6áagg‡äädcÉ’%-Ő-€ęI믾ú gĎž…““Ξ=‹ŃŁG×;gZűF‡Îť;ř˙üPM[$—f˛˛˛`gg'iÇŃŃýű÷ÇŃŁG]O—Úéť:u€W^ć}˙ý÷1cĆ ,Z´EEEđňň’¬Ż˝_Äy‹/JĘ›rLôEˇP ĽĽüµőž>}*#&_kĆ/Ś5 gϞŨQŁ Ńh V«ŃŁG­z‡Byy9/^,.={öod€ČČHdeeáéÓ§Řľ};ňóóµ˙ŃE„zËÍÍÍQXX(ľîŐ«úőë§µ]í¶¶¶€Wľź -† 9~[ôî„„„`ßľ}Ř»wŻŢű«¬¬”Ľ1bT*üüüPTT¤5—RWí7`]µźQ}đŕŞ?ôHŮŰŰKn|jh˝Ć¨Ż˝»ví„ ššŠ">>ţ•muëÖ ^ůümCʉľ¸şşâďż˙~m˝›7obذa’˛×=[üâĹ ™™Éَjéř­ËČČ»wďF—.]Ź'NhŐąsçěíí‘’’".'Nś@nn®¤^rr2ćÍ›ooo­¸MëׯăÜąsĐh4ČĎĎGdd¤ěv -† 9~[üVĽäädŘŮŮ!,,Lď}m۶MrÓPý rëÖ­Şďśm666¸qă†Vą čŐ«WŁë5—: ;;iii°°°@xx8RSSuÖŻąů -ßL3{ölÜąsWŻ^ŐYçęŐ«(..ƬYł$ĺ˝{÷Fqq±Îí őţ¨Ç›®%ă·>666رc4 ćĚ™Łő!´S§N¸víšÖ‡L"ŻâÄĹĹaÝşuřî»ďt·gC,_ľQQQ‹‹Ctt46lŘ€ĐĐPŮíZ rüę-™ľ|ůRňł†••öěŮÇŹë«k‘ťť"""´ĘkžmjŽO¤ŕç燂‚\ąrER~ăĆ řűű7şž ZÇ­ˇVóÍ7ßBCCqřđaŔ‘#Gtn{úôi!88¸I}·„9sćŕÝwßELLŚÎ:ŃŃŃpssÓúe6iŇ$\ľ|ůůůőn·wď^řúú6ëxßTm!~u™2e ÂÂÂpűöm,Z´H˛ÎÓÓ%%%Řąs§¤|óć͸˙>`Ë–-ptt„ĄĄ%í}lŠŁGŹ˘˛˛™™™‹‹C```“Ű2ä6äř•ťLŐj5íą»˘˘"Ě#ÔP*•X»v­Ü®_ËŢŢDXXä+Ş`mmŤŹ>úH,«ď—GÍ6µż·ľzŃŃѰµµEdd¤ř‰8''UUU’K= ­×ŁG\ĽxEEEČČČ«öe뚲şĎŁ6 Ë—/¤¦¦ŠŰŘŰۨž{ŞqáÂ<|řđřńcDEEá“O>Á Ad}111Aff&ňňň°hŃ"ńýWł ,@~~>233µć“˘˘˘`cc???ś;wN,W«Őزe vďŢŤŐ«Wë컬¬L¬o(Úrü˙˙K«nňNHH€łł3~řᤤ¤ĺ«W݆©©).\°°0¤¤¤_ XóW á÷ßlj'™™)^v>>4fĚJLL¤gĎžéÜ®¤¤„–-[FöööÔ­[7˛µµ%GGGZąrĄřB}8@~~~€ŚŤŤiŐŞUtôčŃFŹ›¨íÜÍŰÖă÷äÉ“4mÚ4@íÚµŁŹ?ţ.\¸ ®żző*YXX‰‰ …‡‡‹çýđáĂ4dČ255ĄPjjޤÝ;v••988Đ‘#GhűöíÔľ}{ňňň˘ß~űŤV¬XA¨sçδsçNzţü9©ŐjJMMĄŽ;ŠűpëÖ-±Íččh233#üď+k–zňä …‡‡ęŇĄ íŰ·ŹÔjµřµ¦ …‚~üńG±­7%†9~ĄšĺŃ–"çä1)4Ă-âr˝­çł­$Ó–f¨ç»˛˛’"""(77WRvňäI˛°°Đ[ż­Æz>_§ŐŤaŚ1C4}útäććJ.żĂĆƦŮîË`mźńë«0CS3S÷Ń!ĆXă]¸p÷îÝĂŽ;ŕáá333¨T*lÚ´I2źŰś8†ŰţËô-STT„đđpŐ˙ťfÓ¦M(((hĺQ1öćĘÎÎĆţó,_ľNNN8q"T*<¨—˙}Ę1Ü6ń_¦o™>}ú )) III­=Ć Â AđÓO?µXĂm˙eĘcŚÉÄÉ”1Ć“‰“)cŚ1&'SĆcL&N¦Ś1ĆLśLcŚ1™8™2Ćc2q2eŚ1ĆdâdĘcŚÉÄÉ”1Ć“‰“)cŚ1&WÝ˙Ɇ:˙Ü–^xiţEź˙Ď”^xŃďR_üj}Ńýţýűë1Ćš™­­­^ÚĺřeL˙ę‹_áźfcŚ1ÖDĎ™ňťSeB"""""R+R """"˘šc!ODDDD¤†XČ©!ňDDDDDj…<‘Ň’:5N=zôŔ•+W¤ŽADDĺ={6üüü¤ŽADc!OjÝşuŁý˘?~Ş®O˘ęqss“:5>>Ę"ľ<-Z´€ŻŻď+-•ĹBž¨‰ ÄĺË—+-ž}}}…ŔŔŔM[SS ˇńâëcâĉh×®]•ă˝ůć›0aBŤćEDD•c!ODÔÄěÝ»ćććprrŞp››#((č•ćŐąsçjkgg÷Jó"""U,䉚k×®ˇS§NUgccčččHDDDő…<Q“––}}ý*‡Ó××GZZZ$""˘úŔBž¨‰122BNNN•ĂeggĂŘظQ}`!ODÔÄ8;;#..®ĘáîÝ»‡nÝş©tÓŇŇBIII…ăäççCGGç•3Ń«c!ODÔÄLś8‰‰‰¸uëV…ĂÜşu Ź?Ćű￯ҽ]»vxüřq…ă=xđVVVu–•jŹ…<Q3yňdôčŃ>>>łbĹ ¸¸¸ŕĂ?Té>räHܸqńńń厷oß>Ś1˘NóQí°'"jb´µµqŕŔÄĆĆbćĚ™ČĚĚTöËČČŔôéÓŹ@KKőßË—/‡……Ţyç\ştIŮ=33›6m®]»°téŇ ç­8y¶ô<‰¨~°'"j‚,--qńâEtîÜ#GŽÄ#0bÄŚ5 ööö8wîĚÍÍˌ׶m[DEEÁÓÓ'N„™™¬¬¬ŕęꊇ"22mÚ´)wžˇˇˇ:u* 22_|ńÂÂÂęs1‰š5­Ş!""uÔ˘E |ńĹřâ‹/j4ž™™6mÚ„M›6ŐhĽqăĆaܸq5‡jŹ[ä‰Ô y"""""5ÄBžH ±'""""RC,ä‰ÔŻZCDŤBTTlll¤ŽAÔ襤¤ŔŃŃQęDÔp‹<‘ây"jzöě‰đđp©c5zîîîRG ˘F‚[ä‰Ô y"""""5ÄBžH ±'""""RC,ä‰Ô y"""""5ÄBžęDQQ"""°{÷n©Ł5 ,ä©N„„„ŔËË 2™ rąË–-CTT‚‚‚ŕää™LGGGäç竌÷çźbĐ AÉdpqqAppp˝ä;sć Ţ}÷]eľ~ýúÁŐŐŻżţ:Ţzë-:t¨Î癜śŚŔŔ@L0ŢŢŢeú»ąąÁÍÍ­ÎçKęO_;Oź>ĹŇĄKáć憽{÷ÖxüÂÂB,X°óçĎGçÎťńé§ź(»¬Uµ QsÂBžę„——}űö…ŻŻ/zöě‰ & ,, póćM,[¶LeĽ`űöí€ŕŕ`Ś?ľ^ňőďß;věxzz""".\ŔÝ»wŃ·o_Ś=۶m«ÓyjjjÂÚÚÁÁÁHKK+Ó_Q§ó٦C_;fffXłfM­Ç_ż~=.]ş„Í›7cëÖ­xđŕ€˛ËZUŰ5',ä©Î Tş›™™,--±aĂś={VĄ‡VVVőšŻeË–^ ÚÚÚřć›oĐ©S§W*BĘcjjZé#""Ę´ ľŻ ŤÚĄěŮł&&&€âŕÁĘ.kUmCDÔś°§łsçNŔ”)S••Ąě®ĄĄŕŐŠ€Weee…GŹI6˘ćîŢ˝{RG "R;,ä©Áxxx`ńâĹŹŹÇ˘E‹¤ŽŁ”——‡7nŕÍ7ß,Ó/66cÇŽĹ1cŕŕŕ€Í›7«ô/))Á˛e˰rĺJĚ›7...¸~ýz•óLHHŔÚµkËťg~~>ćĚ™YłfÁŃŃ2™ pssCLL BCC1iŇ$x{{ăöíŰđôô„ľľ>FŤ…ěěě çyăĆ ,\¸k×®EŻ^˝`kk‹ÂÂB=zÓ¦MĂäÉ“†ž={BGG={öDTT”r9ĂĂĂńÉ'źŕĂ?DTTÜÝݡ««‹ˇC‡"''aaapvv†®®.† ‚ôôô*ŰAťEEEaáÂ…:u*Ξ=‹×_ RöW÷×NUů 55ź|ň fĎžŤ/ľř>>>Őm>Ą˝{÷ÂŰŰąąąŽŽ†··7ľýöŰ*—µ"Uĺ.ď}@D¤¶Q9ÜÜÜÄěŮłk<1räČr» !DaaˇpuuÄ‘#GĘôŻÉ|ÜÜÜ^)_II‰¸~ýş2d044§OźVöńăÇÂĚĚLüńÇB!nܸ!d2™Řşu«rőë× gggĺsWWWáââRá<…˘  @ś>}ZŘŘŘ”»ÜóćÍöööB!„L&SÎ#;;[ ÂĆĆF,[¶LDFFŠůóç bíÚµ.»“““HIIB‘““#†.233Ĺü! ±aĂqýúu±eˡ««+LLLÄăÇŹErr˛ „•••đ÷÷ééébŐŞU€1b„Xż~˝HKK7nÄŞU«Ş^!ĄÚ¨6ëS* ÂÇÇGNNNbٲebĘ”)˘_ż~BőíT'^^žčŃŁ‡ŘĽył˛Ű*ü ¨JM—µĽůT'wyďuăââ"455…¶¶¶ĐŇŇĆĆƢWŻ^bíÚµâţýűRÇ#˘ÄBžĘU_…ĽBÜ»wO sssńěŮł2ý«;źÚň¦¦¦˘WŻ^BWWWhhhożýV<~ü¸Ě°sçζ¶¶*Ýşté˘,”„â˙ř‡J!0räHˇŁŁSfžĺµÉ#Ę]n###1dČĺs{{{ˇ­­­|^RR"¨ óěŮ3@xyyU¸ěrą\„††*ź;vL%ăСCU†Wäß~ű­ĘpÆ S>ONN.3nff¦ Ţ˙ý łĽLÝ y!^˛„C™~ęţÚ©NţďľűNššŠÂÂBe·üüü:+ä*ZÖň†ŻNîĘŢę˘oßľÂÓÓSĚ›7O 2DŘŘŘMMM!“É„L&C† ·nÝ’:&5­şßĆOT9kkkřůůaňäÉ3göíŰ× óďÓ§<·Ţz §NťBff&^{íµ2Ă).I9kÖ,e7sss•Kh*®Â“ťťŤ}űö!>>ľĚ%6+"“ÉĘí®«««Ľbđâ$á‚‚‚2ăikk+»™ššrrr*śßŕÁ1~üxL›6 +V¬Ŕ!CTú+ÎUP0a.\k×®©t/}˛°âäÄŇă*Nv®ě0ź¦@GG@ů'i«űk§:ůwďŢŤ®]»Ş¬{ą\^­ü5QѲ–§:ą«z¨ tîÜYĺ°ˇĚĚLüüóĎđńńÁÉ“'ѵkWlŢĽsćĚ‘0)Ő7ň$ ooo;v »ví»ďľŰŕó×ĐĐŔ®]»ŕä䄵k×bČ!đđđP&11îîîđ÷÷ŻtZ~~~8uę6nÜ_ýwîÜyĄlK–,ÁÂ… qéŇ%ôčŃńńńXľ|ů+Mxq˛ńűᅬíŰ·c×®]řúëŻńĺ—_V8|›6mĽ8–»"Ą‹ú—U6^S§îŻťę䏍ŤĹ€^%nť«NîšľÔ…ˇˇ!>űě3|ôŃG9s&BBBđŮgź!##K–,‘:Őň$???DFFbîÜą’ĚßÂÂxçťw0yňd\ż~]ąuŚŤŤqűöm!T¶ !ťť řúúbË–-‹‹ľľ~ťäZ°`ž?___8::bŐŞUđňňzĺéŕرcرc,X€Ĺ‹ĂÔÔ3fĚ(wxĹÉŞvvvŻ<ďćFÝ_;ŐÉŻ­­Ť˙üç?u’»®T'wMßęĆŔŔ{÷îE۶m±}űv|őŐWčŐ«—ʉŘDÔtđŞ5T‹Uţ*bĎž=ČČČ"`ôčŃ;w.ţúë/Ěś9SĄź‡‡ž|*Çî*¸şşâ›oľ©˙přßć—8¬_żŽŽŽřĺ—_TvÉ/]şrą3fĚŔÜąsáďﯼ%Ľâ¸h!.\¸€S§NáŔ‹‹„‡‡#>>EEEĘ?ĚDńĹúňě”)Sđď˙‹/Ć×_Ť 6ŕرcĘi”7MĹ1ŔŠ~ ÝşuĂ‚ Ű·oGaa!ŔĆĆŔ‹ó˘ŁŁ‘ššŞlŁĺË—ăË/żD—.]”˙,77Ŕ‹Kx*TôĂ­©Q´µ˘ JS÷×NuňŻX±ZZZ2e """ššŠŤ7xńZ ©fKţďřüňŠÍň–µ˘¶©NîŞŢM…L&żż?îÝ»‡ĚĚLĺ´‰¨‰‘č$[jäjzŐšĐĐP1věX@hkk‹ż˙ýďâňĺËb÷îݢwďŢ€4h/3nqq±đđđ¨Q>Ôđ*'gÎśď˝÷ž 455Ĺçź.˘ŁŁ•ýoÝş%Z´h!´µµĹâĹ‹Enn®Bß˙]888ą\.:uę$¶oß®2Ý€€ahh(lmmĹŃŁGĹO?ý$ôôôÄ!CÄůóçĹÂ… abb"věŘ!ňňňDff¦Řľ}»hٲĄ –,Y"=z¤śćŠ+„ŽŽŽ ňđööYYYbńâĹ€hŐŞ• ™™™bѢE€022TNËŐŐU|ýő×Ę6suuľľľbĚ1⫯ľĹĹĹ*ý¦Oź.ĆŹ/\]]ĹęŐ«EII‰âĹŐiV®\)Ö­[‹C‡‰´´4±téR@čëë‹ĐĐP‘––¦ÎŘŘXěŢ˝[9Ťş\źR‹‹‹sçÎUľŢ×­[WćĘGęţÚ©*żB9rD8:: ą\.şví*Nž<)ěěěÄŞU«Ş}Ä›7oŠ (3ěÜąS$''W¸¬ńńńĺ¶MusWö>P5ů|7nśppp(s5"jdBH´”5www8::ÂĎĎOę(ĺ’ÉdpssCxx¸ÔQęTQQ–/_ŽŃŁG+·áÜąsĘ/Ő™L†‘#GâđáĂő2ýęĚż)®Ď†$Ők‡^M>źwíÚ…Ź?ţąąą‰‰Qîa#˘¦‡Ö5"ăĆŤCdd¤Ę®~---XXXŔÚÚZÂdÔŘ5Ć׎âäŇĘżýö›$Ůš‹ 77ŚŚ”:Ő1^µ†¨‰ŽŽFJJ ŕîîDEEaÝşuU^ʰ¶Ç +ţ’z’âµS•—Ď—ˇ†×ľ}{XYYA.—#""}ô‘Ô‘¨q‹==BňDM y"j ĐŁG©c5zúúú5>%%B´iÓ¦ž‘TXČ5a±±±ĐŇŇ›oľ)u"Şc,䉚¨¤¤$¤ĄĄA&“ŐřY"jüx;QB°'j‚¸Ež¨‰:ţÁ‡~¨¨(¸»»CWWC‡ENNÂÂÂŕěě ]]] 2ééé*9*Zöüüü*3aÝşuHJJBTTŢ}÷]l۶­Ęv),,ÄŃŁG1mÚ4Lž<aaačŮł'tttĐłgODEEU«í+[Ż•ŤWźíVU›TöZ«lynܸ… bíÚµčŐ«lmm«lçšŘ±cŚŤŤ1tčP™™Őé´‰¨DĺpssłgĎ–:F…777©cP©ÉúLHH>>>€prrË–-S¦LýúőBńřńcaff&ţřă!„7nÜ2™LlÝşU9Ťőë× gggĺsWWWáââR&ÓČ‘#•Ď ÄéÓ§…ŤŤŤ(ďŁsŢĽyÂŢŢ^™Q&“)瑝ť-‚acc#–-[&"##Ĺüůó±víZ!„ÉÉÉ"00PVVVÂßß_¤§§‹U«V bÄbýúő"--MlܸQ«V­Rf¨lŮ«›ˇĽeŻJff¦řăŹ?aaa!6lŘ ®_ż.¶lŮ"tuu…‰‰‰xüřqĄm_Őz­lťŐg»UÖ&•ŤWŐň899‰””!„999břđáŐnoWWWakk+~řá‘””T¦~~ľhÝşµĐÔÔżýö[µ§KDꇅ<•‹…<5¤š®ĎĽĽ<@888”é7wî\akk«Ň­K—.Ę"[!ţńʍN#GŽ:::e2•WĚŽ1˘ÜBŢČČH 2DůÜŢŢ^hkk+ź—””*Ă<{öL^^^eć=lŘ0ĺóääd@ :TŮ-33Sďż˙~µ—˝şjZČ—ŻtF!„˛pţöŰo…•·}e뵺ë¬>ÚM1í—ۤŞń*[ą\.BCC•ĎŹ;VfЏşşŠöíŰ SSSabb"ţüóO•ţˇˇˇBSSStěŘQW{şD¤~xůI"R;:::++«2ý:5k–˛›ąą9ňóó•Ď—-[ČÎÎĆľ}űŻŇż22™¬ÜîşşşxđŕňąĄĄĄĘ1ŐŠń´µµ•ÝLMM999e¦§©©©üßÄÄ ĄőżŹlĺ2(Tµě5ÍPĄ3Ŕ„ °páB\»v @ĺm_Ůz­î:«Źv«HUăU¶<Ćřńă1mÚ4¬X±C† ©t^Ąikkăí·ßĆ÷ߏٳgă>Ŕţóčéé¶lŮą\ŽO?ý<‚–¨)c!ODMJbb"ÜÝÝáďď_ép~~~8uę6nÜ_ýwîÜyĄů.Y˛ .ÄĄK—ĐŁGÄÇÇ×ŮUNJ§/+))Qţ_ÝeoHmÚ´ šł¶m_Óńę»Ý^Ą˝wî܉÷ßŰ·oÇ®]»đő×_ăË/ż¬Ń4Z´hm۶ˇ}űöŘąs'>ůäDEEáÔ©SĐ××Ç´iÓjś‹Ô y"jRŚŤŤqűöm!T¶ž !ťť řúúbË–-‹‹ľľ~ťĚwÁ‚xţü9|}}áččU«VÁËË«N¦]]ŐYö†¦8©ÔÎÎjÝöő±ÎjŰnŻŇŢ8věvěŘ `ńâĹ055ĹŚ3j”][[}űöEdd$>ůä|űí·ËĺX´hŚŤŤk4-"R?ÜçFDMЇ‡žŐnçŇJJJ „ŔŇĄKˇ©©‰%K–ŔČȨVÓ""5#Í9¶ÔŘńŞ5Ôj˛>ăââÄÜąsˇ­­-Ö­[§Ľ´ˇÂďż˙.„\.ť:uŰ·oWé …­­­8zô¨řé§ź„žžž2d8ţĽX¸pˇ LLLÄŽ;D^^žČĚĚŰ·o-[¶Ä’%KÄŁGŹ”Ó\±b…ĐŃŃTŢŢŢ"++K,^ĽX­ZµAAA"33S,Z´HFFFâŕÁ"99Y¬\ąR­[·‡iiibéŇĄ€Đ×סˇˇ"--M9ś±±±Ř˝{·())©tŮ«›A!ţőŻ }}}ѵkWqĺĘ•­GWWW1}út1~üxáęę*VŻ^­ĚVYŰŰŘŘ//Ż ×keëěÖ­[őÖn µIEăUő:U´•ŻŻŻ3fŚřꫯŞ}…™—?źťťťĹÔ©S•ë6++«ÚëŚÔ›L!îg© www8::ÂĎĎOę(ĺ’ÉdpssCxx¸ÔQ¨¨űú,**ÂňĺË1zôhĺVŐ˘˘"ś;wNyC˘ć@&“aäČ‘8|ř°ÔQš´ŇźĎyyyhٲ%¬¬¬pďŢ=IrXI‡Ö˝˘qăĆ!55«WŻVvÓŇŇ‚……¬­­%LV7Şs’ě®]» ˝,<<%%%‹‹‹‹ ‹x˘f†…<Ń+ŠŽŽFJJ ŕîîDEEaÝşuŤęRµ•••Uĺ0………*©aBCCB2'ÝQÓǫֽ˘cÇŽaŕŔX°`ěíí1lŘ0DEEá·ß~›››ÔńęÝDZxńb@dd$Ö­[‡„„‰S5}Ďž=CPP áăă[[[©#Qăy"˘WÔĄK—f}\xűöí±aĂlذAę(ÍʢE‹PTT[[Ű:»ů©ňDDDj&33»w†Nś8ˇrC*"j>XČ©™!€víÚI‡$ÂËORąěěě#u ""ŞŔ°aĂ”w…%˘ć‰…<•ëÔ©SHII‘:•ňË/ż`ßľ}044DFF†ÔqHb,ä‰ÔŔž={0iŇ$hii!%%FFFRG""‰ńň“DDDŤ\XXĽ˝˝!“ÉpőęUńD€'»5j'OžÄСC!„ŔŢ˝{áŕŕ u$"j$¸Ež¨‘úůçźńÖ[oˇ¤¤K–,Áűďż/u$"jDXČÚô|J IDAT52B¬X±Ó¦M}ôVŻ^-u,"jdx˛+Q#’ťťŤ3f $$ĹĹĹ:t(Ž=*u,"j„XČ5WŻ^ĹĉńŕÁäćć˘WŻ^¸pá‚Ô±¨‘âˇ5DDDB`óćÍčÓ§rrr››‹ž={˛'˘J±'""’ĐăÇŹ1jÔ(üíoC×®]ńđáCtďŢ—.]’:5r,ä‰$PRR‚-[¶ŔÎÎ111čŰ·/.^Ľwww\ľ|YęxD¤XČ5°k×®ˇOź>X¸p!fĎž SSSś9săĆŤĂ™3g¤ŽGDj‚…<QIIIÁ矎ž={B[['NśŔŽ;péŇ%|úé§ ‘:"©ŢŮ•¨žeggcóćÍX·när9¶lŮ‚7ß|C† A~~>¶nÝŠ™3gJ“Ô ·ČŐ“˘˘"üřăŹxăŤ7°zőj,X°÷îÝCbb"ú÷ď™L†óçĎł'˘Záy""˘:–““ź~ú 7nÄ_ý…YłfaůňĺĐÓÓĂ€…Îť;#""­[·–:.©)n‘'""Ş#)))řúëŻaee…%K–ŕí·ßFll,6oŢŚ™™áňĺË={6bccYÄŃ+áy""˘WtăĆ řűűă矆žžćÎť‹O?ý­[·F^^†ŠăÇŹĂŔŔGŽÁ°aäŽLDM€L!¤ADD¤nrss„­[·âÜąs°µµĹś9s0mÚ4čëë¶mۆůóç#77#GŽÄ/żüą\.qr"j*XČ5°§Oź";;[ůÜŇŇ’Ĺťąxń"věŘ]»v!//ăĆŤĂĚ™3•'Ż@tt4ĆŤ‡{÷îÁÔÔ»wďćVx"Şs,ä‰^ÁÓ§OńűďżăÎť;ŹŹGRR’’’––†¬¬,˘¸¸PťŹ[E!¨©© mmmčééA__-[¶„±±1Z·nŤvíÚÁÎÎčÖ­Z¶lYŻËHŔ­[·°wď^!..ööö>}:¦L™SSSĺp ŚĂ‡ăţýűhßľ=ĆŽ‹‰'ÂŐŐµĚ8.\Ŕgź}†¨¨(€››vîÜŮŕŻ"jžXČýźśślذ{÷îEll,Š‹‹ˇĄĄ+++ 0|đ<==ĄŽYm·oßFxx8˘ŁŁqăĆ $$$ %%yyyĘaôôô`ff†Nť:ˇ[·npss§§' $LŢpbccqňäI„……ářńăČÉÉ‹‹ FŤ…‘#G˘[·neĆ)**·ß~ $%%ASSÇÇÖ­[ann.ÁRQsĹBžš˝-[¶ŔĎĎ111())AË–-áćć†éÓ§cěرRÇ«sÇ©S§Ť»wď"11ŮŮŮĘ­řrদ¦xýő×ńć›o˘_ż~đôôTű-Í 8yň$Nť:…?ţř‰‰‰033‡‡† †#FŔĚ̬Üq‚‚°qăF\ľ|EEE055Ĺ”)Sŕëë ==˝^""ňDÔLÝżźţ9Ž9‚üü|čëëă­·ŢÂW_}©ăIćúőë8yň$.^ĽŰ·oăŃŁGHOOGQQ€Çă•9L§WŻ^ĐĐh\÷,((ŔŐ«WqîÜ9\¸p‘‘‘xđফŤ1`Ŕ 4 ‚˝˝˝ň$ăŇňňňŕď{÷"::ËĺčÓ§|||ŕáá!ÁRý y"jV"##1gÎ\»v 2™ öööX±bĽĽĽ¤ŽÖ¨=}úÇŹÇ… pőęŐ ÓiÓ¦ Ţxă ŘŮ١GŹpssŤŤM˝ç+..Ćţó\˝z—/_ĆůóçqůňeäççĂÚÚ}úô««+úő뇮]»BSSłĚ4ňňň„ýű÷ăâĹ‹xúô)„hѢśťťńé§źbâĉőľ,DDŐĹBžš…S§Naúôé¸˙>´´´0zôhüřăŹFAŐŁ8LçĚ™3¸|ů2îŢ˝‹¤¤$deeˇ¤¤Ŕ‹Kj¶hŃ­Zµ‚ĄĄ%¬¬¬”Ĺľ““j4ĎôôtÜąs×®]ĂŐ«W•çäääŔÔÔÎÎÎpqqQďm۶-3ŤË—/ăرc@LL ?~ŚÜÜ\€¶¶¶ňĽąsçÂŮŮůŐЍ°'˘&-::“&MÂíŰ·!—Ë1sćL¬_żşşşRGkňRRRpöěY\Ľx·nÝÂýű÷ńôéS¤§§Ł  @YčP^3_OOOy‰N}}}hiiAÜÜ\¤¤¤ 99Ďź?››ĂĆĆoĽń¬­­ahhV­Z!)) %%%xřđ!=z„ÄÄD¤¤¤ ==YYY(((Pž ТE ĺaBýúőĂđáĂY¸‘Ú`!OŻ$-- ČĘĘBvv6 ššŠ‚‚dgg+oĽ¸NZZšrÜââbddd(ź!33Sů\1ŤşÔ˘E •NqĽoiĐÖÖV>—ËĺĘŰ­+C&“©ô344„–––Ę4KĎO15ڬ¬,Ś7ÇŹ‡¦¦&&MšđŤČ“'OpěŘ1ś?7oŢDbb"ŇŇŇťťŤüü|e±-“É”—ţ¬ę+KńÓĐĐP^ŰßŔŔ­[·F›6mĐľ}{XYYˇ{÷î:t(_D¤ÖXČ7S999xţüy™Gjj*ž?ŽgĎž)oB“››‹ĽĽ<ĺV´ĚĚLäää ??żĚtutt”[Ôärą˛ -]ÄĘd2+ÇyąÖŇŇ‚ˇˇˇňyy…ti™™™ĘńŞ«°°YYY*ÝŇÓÓU¶*–[ˇ¤¤éééĘçiiiB¨L«ô—Š”^ĹŹĹŹĹß–-[BSSFFFĘöŃĐĐP¶Ł‰‰ ŔÄÄDŮžĄ‡322R^;üĺölVŻ^ â­·ŢBPPoĚÓŔrss‘””„ÇŹăŃŁGxôčE\\âăăq÷î]ÄĹĹáŢ˝{¸wďRRRĽ(`:tč+++´oß:tPnĺj۶-^{í5>@’yyŻBu÷&”ţÁ‘››[ᏏŇçP(¦÷ňyQüxPěePPěU¨íóĘ(ö|TĄĽ˝(©©©*Ď«:Ě+55UŮ>•í•166Vî5Qě100€®®n™âĽ˘‡âÇIŹ…|{đŕbbbpăĆ ÄÄÄŕćÍ›¸sçŇÓÓˇˇˇKKKtęÔIůP/ÚˇCéD/9ţ<Śěěl|ôŃGXż~˝ĘIŐĄ ŕŇĹńËç2ÔôyE缊ňÎexůđ¤ňÎQěńPě©(]¬+~¸Ľ|75 ,äëIAAnŢĽ‰+W®ŕęŐ«¸ző*nßľŤôôtČĺrŘŮŮÁÖÖ°łłťťlll ŁŁ#ut"µ°eËĚ›7::: Ĺ#¤ŽDDDÔ XČ×ââbÜĽy¸|ů2®^˝Š›7o˘°°–––čŢ˝;śťťáääGGGX[[CKKKęŘDjkęÔ© D‡pőęUî­""˘f‰…|-¤§§ăÜąs8wî"##qáÂdffÂŇŇ˝{÷FŹ=ŕěěŚîÝ»ó®‘Du¨¤¤}úôÁĹ‹1hĐ ś8q‚'RQłĹBľrssqöěYüńÇ ĂŐ«Wˇˇˇ®]»˘oßľčÓ§úőë‡:H•¨ÉĘÉÉŁŁ#âăă±páBlذAęHDDD’b!_!®\ą‚cÇŽ!,, çÎťCAAşwďOOOxzz˘oßľ•ޤęNJJ ěí표śŚuëÖáóĎ?—:‘äXČ˙ź‚‚ś:u ŔáÇńđáCtęÔ Ć[o˝…ň8\" ¤¤¤ S§NČĚĚD`` Ľ˝˝ĄŽDDDÔ(4ëB>77‡ÂţýűqôčQdeeÁŐŐďĽóFŹ ;;;©#5k)))čÜą3ŇÓÓńË/żŕťwŢ‘:QŁŃě ůââbś8q{öěÁożý†ĽĽ< :ďľű.Ţ~űm´mŰVęD„E|—.]––†ýű÷ăÝwß•:QŁŇl ůččh (()))pssĂĉ1~üx2CÔČŔĘĘ Oź>EPPĆŤ'u$""˘F§I_ĚŻ0CÔH•””ŔŮŮIIIřé§źXÄU Iňqqqđ÷÷ÇĎ?˙ڬ¬,Ś;kÖ¬A˙ţýĄŽFDUčׯnßľŤŻľú Ó¦M“:QŁŐ¤ ůk×®á»ďľCpp0:tč€Ď?˙Ó§OçM™ÔÄĚ™3qţüy|üńÇđőő•:QŁÖ$Ž‘?{ö,VŻ^Ťß˙]»vĹ’%K0nÜ8hjjJŤŞ) Ó§O‡««+Îź?/u""˘FO­ďm~ţüyxzzÂÝÝ8|ř0®\ą‚ &°'R#—.]ÂĚ™3aff†3gÎH‡H-¨ĺů{÷îaůňĺŘ·oÜÝÝáëë www©cQ-ÁÔÔąąąřá‡ĐŞU+©#5:666čŢ˝»J7µ:FţůóçXµj~řátěŘű÷ďÇ1c¤ŽEDŻ`ҤIČĚĚĚž=[â4DDDŤÓěŮłáçç§ŇMm­Ů»w/ěěě°cÇlܸ7oŢdO¤ćnßľŤôčŃ!|đQÉc÷îÝ€Ő«WKž…>úŃ\_˙nnnĺ~Ź6úB>!!#GŽÄ¤I“0věXÜ˝{sćĚ––ZíL ˘rĚž=2™ ˙ď˙ý?©Ł©ťF[Č !đĎţŹŹÇ™3gđăŹ?ÂČČHęhDTľŻ‰jˇQňĎž=èQŁđ·żý ‹-Bttt…»H=ůřř@ďľűNę(DDDj©ŃźŽ>řÚÚÚ8{ö,zőę%u$"Şc†ĄĄ%zôčH‰Hí4š-ňŠ-s BĎž=qĺĘńDMÔţýű‘źźŹ &H…Hm5Š-ňř裏‚µk×bÁ‚ÉdRÇ"˘z˛uëV”””đĘSDDDŻ@ňB>-- cÇŽĹŐ«WqěŘ1xxxH‰ęŃłgĎCCCôéÓGę8DDDjKŇCk}EEEĐĐĐ@Ź=¤ŽCŐ°sçNŔ”)S••Ąě®¸»¶†FŁąřQłÓ źŔ)))’““a``€-Z4ÔlŤ $$111RGˇ:Đ\×gHH®\ąR«q“’’pçÎäĺĺˇK—.uśŚę“––öěŮCCCLź>Ďź?—:ˇ¶ČŻYłżţú+ŕ—_~››[C̶QŮłg&Mš„>řK–,‘:˝˘ćş>ÝÝÝk=ndd$är9YČ«!kkkřůůaňäÉ3göíŰ'u$"˘fŻŢ·ČŞĎYQ#‰7Ţx`cc#qŞ-???X[[cîÜąRG!"jöę­ONNĆčŃŁŃ»woüóź˙¬ŻŮ‘(((Ŕ•+W`aammm´iÓFęHT…ââb•ż †††Řłg222¤EDDĄÔK!_\\Ś>řÚÚÚ U^oš§›7o˘  zzzh۶-d2™Ô‘č˙dff€Ę5âŕáÇ^śŘý2WWW|óÍ7őŽ*U/…ĽŹŹΞ=‹ĐĐPÔÇ,HŤDGGĂĐĐ………077—:ýźýű÷cęÔ©^ú´téR\ąr{öěÁĉ3fĚ(sWWXĽx1<<<2.˝¤Î7•˙űß˙ĆŞU«°uëVtďŢ˝®'ODj(::ÎÎÎHJJ‚………Ôqč˙Ľ÷Ţ{xď˝÷ĘtďŢ˝;>řŕJÇŐĐĐŔÉ“'ë+UCťn‘ŹŹŹ‡··7¦NťZëĆQÓsőęUtëÖ ©©©066–:Q“Pg…|AAĆŹŹŽ;bË–-u5Ůj ——d2är9–-[†¨¨(ÁÉÉ 2™ ŽŽŽČĎĎWďĎ?˙Ä A “Éŕââ‚ŕŕŕĎNÔÔÝşu vvvČČČ€žžžÔqš„:+ä}||‹ŕŕ`IîÜęĺĺ…€€@ßľ}áë닞={b„  đâ„»eË–©Ś7`ŔlßľŚńăÇ7lp˘&.99©©©°łłC^^ ĄŽDDDÔ$ÔI!˙çźbÝşuŘ´i:uęT“¬E``` ŇÝĚĚ `ii‰ 6”9q«C‡++«HIÔĽÄÄÄ:wĽ<čęęJś¨ixĺB>-- S¦LÁčŃŁ1}úôşČTovîÜ 2eŠĘĄÖ—ÇÔШ÷Ý5;111022‚ąą9ŇÓÓ%ŮcGDDÔ˝ňUkćÎť‹‚‚l۶­.ňÔ+,^Ľ«WŻĆ˘E‹°uëV©#5ywďŢEçÎťššš•ËBź¨ ÷ďß—:5ŻTČ˙úëŻŘ»w/Ž=ŠV­ZŐU¦zőÍ7ßŕäɓضmĆŚáÇK‰¨I»˙>:věŕĹaoąąąĘ~˙ýďqüřq 6 xµ+""˘¨u!ź‘‘Ď>ű Ó¦MĂ!Cę2S˝ŇŇŇž={Đ­[7Lź>7oŢ„©©©Ô±š¬ ˙ţ^ľVPP€ű÷ďĂ××Wy‚zBB`ҤIh×®ťdY‰ÔÁíŰ·qčĐ!©cQ#PëB~éŇĄ(,,ÄÚµkë2O°¶¶†źź&OžŚ9sć`ßľ}RG"j˛îßżŹ?ü ­­ŤbÝşuĘsRd2„€YłfÁÍÍM˛¬Dę`Ďž=,ä‰@- ůóçĎăÇÄÎť;Ővk¶··7Ž;†]»váÝwß•:Q“”ťťŤäädČĺrL™2W®\††Š‹‹Q\\ BŕéÓ§'%""R?5.䋊ŠđÉ'ź`đŕÁUŢ»±óóóCdd$ćÎť+u˘&Iq©×YłfASS%%%()))3ÜŁGŹ:‘Ú«ńőđź˙ü~~~ő‘§^(¶ü)ţ*bĎž=ČČČ"Q“–śśŚQŁFJJJPXXXîp,ä‰jˇF…|ff&|||0oŢ3ŐĘ{g÷Ţ{ŻL÷îÝ»Wy,ż††NžS^ő=.µ¦řý[­B~Ó¦M033äI“^y†T}«WŻĆš5kpäČܸqIIIX´hŠ‹‹‘śś,uĽ Ýşu вeKL™2.\P‹ !11˝{÷Ćőë×qčĐ!9rGŽÁáÇqýúuôî݉‰‰ĘáGڎü˘íׯÖ¬Y~ýú©LóăŹ?FHH 88^^^^śňüůsÜşu ŃŃŃwwwDGG#&&Ďž=Ă1cęuy322вeKĺó×_°°°P)ć ę5‡:ŇÔÔ„µµ5‚‘––V¦żâ&ZŤ‰™™™ňçÚXż~=.]ş„Í›7cëÖ­Ę=5//kUmCŐăďďŹýë_µ_ńY_ZEŻËŠÖm](ťcđŕÁضm`Đ A8}ú4Nź>ŤëׯcçÎťxňä đŐW_Őę=TŢ2וúśvuT§=^ő=^ž†Zî¦úý[e!ź––|ńĹ•^y‚ęžźź\\\Đąsg€ľľ>ľ˙ţ{Ś3¦ŃnÁŚŚŚÄňĺËĽ¸cg‡$NÔxaôčѰ˛˛B`` Ęą&FFF DÇŽńÎ;ď¨Gnhh000¨pÚ;v´oßŔ‹¶÷ńń©tZ‹-ŕëëűJËT•— yčС"""Đľ}{îá«„©©)ÜÝÝ+ěQîÉűRSܱ·6öěŮŔŔqđŕAe—µŞ¶ˇŞť´¦4KKKDDDŔĘĘŠHéŢ˝{RGh6üýýńĎţđĂ?ÔhÜÚ|Ö×Çş­íwÎgź}†áÇcőęŐŐŢ3PźßoÍő»ł!—»)˙Vů €iÓ¦ˇE‹Ż<3ŕŇÇáÇëdZęäöíŰ5gĐ A8zô(<<<Ś.]şú÷ďŻ}óçĎGll,<==TáŻÜ7n ććć EFFnܸ?ţřÁÁÁ(,,Ä”)S°dÉܸqŽŽŽđ÷÷GĎž=ë¤MęĂŢ˝{ann''§ ‡qpp€ąą9‚‚‚0}úôZĎëĺuW;;»Zϧ*/_ˇ¦´×^{ 8p îÜąSoęSTTvďŢŤÔÔTĚ1ŢŢް¶¶V^+66˙űß!„ŔÝ»w1sćLĚź?_9~II V¬X---<ţçÎťĂO?ýTék„źţąĚgK~~>.\¨|ÜĽyććć°¶¶ĆöíŰqóćMüúëŻÉdXşt)>űě3ś? Âľ}ű ŻŻŻśVUů 55K–,†Ć˙oďîăjĽ˙?€żN÷*TjsłĹ:6µnHŁypL|%lĂń•싹Ý×Ę6z¤G¶¤ÜĎ×bCHläľ/†IcúnąFş1I©¨PáýűŁßąÖŃąąNťîßĎÇŁ‡ÇąÎuóţÜ\źëă:źësŔŇŇććć:çăöíŰqŕŔ<~üiiiđ÷÷‡““ćĎźŻ1­ęh‹[UűrőęUťănŞîŢ˝‹{÷îaÚ´iXµjâăă…víÚ)­§Ş~ŰŰŰăő×_WŮÖ«*+Me+¦ţ 44())ÁíŰ·±rĺJĽńĆZŻ9šL›6 ‡ÂÎť;ńŮgźP_o´]ßÄś'µM‡¦¶F]>:99‰şfšŰ1縦˛ÔµŐ…f}ý% Îś9C‰„nŢĽ©i5Q233 @‹˙[˛d‰NyöúëŻ233ŁČČHzúô©Ň:yyy´iÓ&@ť;w¦uëÖŃ(""‚аaĂ(**ŠŠŠŠ(&&†PDD„°}VVŮÚÚŇO?ý$,óőő%JOO×y=4|řpĄ}ýő×tçÎúꫯEEE©M»››ĺççŃŁGŹhčСT\\LÇŽ#Ô±cGŠŽŽ¦ .Đš5kČĚĚŚ¬­­)''§Öy"ĆÖ­[u.O[[[’ÉdZ×ëׯŮŮŮ)-S•Ż/Ňr:‹Ú‡ŘfĚ!z}­y”——'ś§NťŞU|ő)33“ľüňK@nnnJ'N¤ľ}űQNN˝ôŇKtěŘ1""şxń"I$Zż~˝°Ź¨¨(rww>{zzRŻ^˝”Žóbą•——Ó‰'H*•Ş,óŮłg“łłłŁD"ŽQZZJ €¤R)…††RJJ }úé§€"##…ý‰˙É“'äááA+V¬–%&&Ö¸®éšVUÇ·ŞöĄ)©IűS•\.§ďľűŽV®\©r_Úę·>ĘJ[ý/--%WWWZłfŤ°ĚĂĂşté˘qżš–+äää >k«75­oµI‘ö˛P—ŹbŻ™šĘNě9®.]ë‘|ý}aßš6š2e yyyŐęŔ ŠŽ|ll,Ą¦¦¶¸?ą\^ن·¸¸>ůä200 Ô§OĘĘĘŞ¶ňńń>+:GC† QÚ;v¬°ěŁŹ>"©TŞ´Ż+W®ň÷÷×y=uyoooásaaaµ8^dbbB»ví>'%%)íŻjşHč/^ĽXi˝šä‰5iHŚŚŚ”âQgČ!dll¬´¬±7$ęŘŰۋʣ .4ąŽ€Ę—í999 3ĹÔôÜ©ęČ‘#¨¨¨@bb"ärąđ‚]‰‰ż_ż~ČČČPš{Zq窡Ę]LÜş¶/ÍĹÚµkńŃGU[n``€™3g€čDŐ¦­WĐV˙ű÷ďŹââb,Y˛DiůŞU«PQQQă8öďߏďľűrą\¸3-¦Ţ¨:–íj“ŽŞ×EujŇŽ˝fŠ=ÇkÚ–éŁ‰ŃśŻż*;ňYYY¸yó&ĽĽĽę;ö˙¤R)öěŮYłf)ý/>** 666ř÷ż˙-,SśUOĹ6Ož<Ѹ^xx8ěíí*ś”'NśŔÓ§O…1oş¬×ľ}{ś?ŮŮŮصk—Đ)+ŕď·xľŘ8őčŃ€ŘŘXa©T čӧʰnZZ Tţ,†ąsç StÖ&Oꊱ±1qíÚ5|üńÇ(..ľ{řđ!&OžŚôôt$&&VφŽ;bÄ8wîś°Ľ¸¸Ë—/G\\BBBÔ[ńö˪ǬÂĎöÍ‘bzÍď´@HHLLL0eĘĚš5 ëÖ­żż?€żÇŠΞ=‹ăÇŹ#117nÜś:u éééÂţUý¬«î<š8q"8€yóćaáÂ…ŽŽFRR’°UűTܬ:]¨řÓÍMś8§OźFaa!bbbTžŁŠ7ЎżŞŞÓ˘*­ęňFLÜÚڗ樨¨ëׯÇ| ňűqăĆ6oŢ,t@5ŐďŰzUeĄ®lµŐ˙ ŔĚĚ ‹-¸qăŤ?üöööÂóMŞâPÜ ŻzÝ*‡ÁĂ××aaa3gŽđťzŁęXb¶«i:€żŻ‹šĘB[>ÚŻ™ęĘNě9®)Ĺ}]ꑾ5ë믪'cřá222˘ÇŹ×ę ŰŞłÖ4µY)ôE×§¬ËËËÉĐĐP۶méťwޡ޽{ÓűďżOüń‡°^^^-X°€­­-íŰ·ŹŠŠŠ($$„……íÚµ‹ŠŠŠ„ő¬¬¬hëÖ­ôüůs""ĘÎÎ&???:t(}ţůç4iŇ$şuëVµÄ¬·zőj˛°° îݻӉ'(88XHömۨ¸¸X­M›6´sçNa[OOOZ¸p!U>áíééIrąśFŤEóçĎžřW|7yňd3f yzzŇ’%K„ôč#Oô]žU=zô"##I&“ŃСCičСԿZ¶l™Ćs.77—>ýôS’JĄdggGöööäääDsć̦ŇSeçÎť4bÄ@FFFôůçźÓ‘#GtŽ›H÷YkÜÝÝiŢĽyZ×kŠíĂŤ7hÖ¬Y€ŚŤŤiéŇĄ”““Ł´ÎˇC‡ČĹĹ…LLL¨k×®«ôýĆŤ©uëÖäččH‡¦ 6ąą9y{{Ó™3g(((µµ5mŢĽ™žŐvŢ_ö7ča§Új©ĺ©kG~Đ A4uęT­ëµôöA_***(88RRR”–ýüóĎÔŞU«ŚŚéSKmXÍ4†k¦>µÔúŻÓô“iiiZß,X_úőëJăłÄި¨Ŕ_|"¡C‡ŕííŤŐ«WWŰg^^<ÂŘŘqqqúKc-µµµđs.«{ľľľ(,,T‹kdd„Ž;ęíą]©{{sUqqqJĎÚ0ĆGeGţŻżţ¦djhD¤ÓĽ´UEEEáÜąs8}ú4FŤ…ččh•ű444„řßFN1ćńĹ±Ź¬q˛¶¶Ć­[·:Ś#-- ůůůظq#d2LMM‘ššŠĄK—ę<­žľhšń1V·řšŮü©|ŘőÎť;u>ç©X§Oź®ŃÝxضm›đ `ďŢ˝*÷icc™LVű`YťĘÎÎĆĽyó)))Xşt)2338*¦‰ŤŤ :Ś#))  @`` śťťáăăÔÔTěŮłGř%’1Ö2đ5łe¨vGţÉ“'¸˙>Ú·oßńčŐÍ›7ynífäŐW_Ett´đË kü:uę„Ű·o7t-F·nݰ˙ţ†1Öđ5łe¨vG^1 YŐ·Š6”ĚĚLDFFâÍ7ßPŰ®]»0~üxřűűăĘ•+4h,,,đŢ{´°}űvřűűăńăÇHKKżż?/^¬rźb\»v |đFŤ¬X±B˙‰e¬ęŇĄ îÝ»'ś›Ś1ĆÓźjwäŰ´iÓqTSQQŚŚ ¬_ż7oŢP9×7a۶mJĄŘľ};är9věŘ+V`íÚµřâ‹/0nÜ8Ś7[·nEŹ=„‡WUíS›»wď˘˙ţŘľ};K—.ÁÍÍ ćććřřăŹë,ýŚ5Š,322ŕěě¬u}???™™ŐuXŚ5iüÜcLˇÚyĹC  ý`„±±1Ţy祗››Ă××@ĺK<-Z„>}ú <<”&ę»Omär9lll0pŕ@€‹‹ Ţxă ľ+Ď]ştĄ^333qôčŃŠ1Ćk>TÎZÓľ}{dgg×w,*˝8cŤâsŐˇ?666ţ~{ś®űÔdßľ}€éÓ§ Ë:tč AbŚ©gaa×^{ ż˙ţ;Ţ}÷]$''C&“©;żcÇ~(“1-¶mۆńăÇ7tڱF@eGľK—.ČČȨçP§;wî@&“5ŘÔmŚ5u={öÄ˙ţ÷?lذAřń_ý…ĚĚL~ť1Ć«•ÓOľţúë¸~ýz}ÇŇ(YYYáĘ•+ "ĄĺDÄăˇgĎž8vě¦L™‚§OźżxŤ1ĆÓ•y™L†Ó§OăůóçőOŁăĺĺ…ÜÜ\lŢĽYiyLL îßżß@Q1Ö4a˙ţýŐ†˝UTT 66¶˘bŚ1Ćš•y///âüůóőO5ĺĺĺJ˙*îčUýO†bĽşâ;ŕďńňŠí4íSÝ~ $$&&&2e fÍš…uëÖÁßßxXc\ż~HMMUyS ##żüňKDĆcŚ5*;ň]»v…››~řá‡úŽGPRR‚ 6ŕěŮł€/żüׯ_Ghh(ŕ×_EBBJJJ8sć öíۇ˗/cţüůÂzqqqČĎĎWąĎżţú ·nÝÂÜąs…}lٲEřĎAŹ=GGGÄĆĆbٲeđňňÂś9sę5?kJŽ9'''dee©ťËŘظÚ/]Ś1ĆOĺĂ®0yňdDFFbáÂ…044¬Ď–––T9D…1Ć´qqqÁéÓ§ńý÷ßĂÚÚZéEn@ĺCćIIIŤj(CCC888 !!EEEŐľq*ÚćęňĺË BŁĂyÂkl4väÍÍͱjŐ*„††"--­ľbbŚ5#‰¸yó&¦NťZm¸ŤD"ÁŢ˝{0Be666Édjż?}ú4’““ë1˘ú—’’‚°°°†ŁQá}ŠĄK—âîÝ»HMMĹČ‘#ńí·ßjÍ—ŠŠ >|“&M„ pôčQĽőÖ[055Ĺ[o˝…ÔÔTQyŻ©\5mW—ů¦-O4Ő5Méąxń"‚‚‚‰Ţ˝{ĂŃŃQk>3ĆX5$Ň˝{÷¨k×®äááAwďŢ»™ 33“đ˙ń_˙›1c†Îçż:ůůů4iŇ$aß§NťŐ–|ůĺ—€ÜÜÜ(44”&NśH}űö%"˘śśz饗čرcDDtńâE’H$´~ýzaQQQäîî.|öôô¤^˝z) >\ř\^^N'Nś ©TJ@ő¦söěŮäěě,Ä(‘H„c”––RBB ©TJˇˇˇ”’’Bź~ú) ČČH""ĘËËŁM›6ęÜą3­[·Ž=zô†*:ż·nÝJhÉ’%˘·a¬ąh©őż_ż~*Żż"ńOneggĂÇÇeeeHLL„łłłŘMńčŃ#8p@ôúúRXX+W® )) řä“OĐ©S§zʱćB*•˘gĎžzÝgbb"Fމ“'O˘˙ţZ×/++™™\\\pńâEĄď>ůä;v üń‡°ĚŃŃFFF¸té@.—#%%Ľűî»8zô(ž]XÖˇCámÍ„7D—––">>éééJßk˘jM033Sjo:uę¤4¦Z±]Ő™{lllTŢčxQŐńY[[€ŇC–––B´Ą]×jâĹ÷řůů!((çĎź 9ď5•«Ř2«‹|SGŰvšŇ3xđ`Ś3“&MBxx¸čNŕăŠRq®nIDATă#ŚÔ‡°°0ÄÇÇ###CÔú xĺ•Wôv|ĆXĂSüÇýńăÇŐľ Abb"¦L™‚_ý®®®HNNFĎž=…±ĘD„łgĎâřńăxřđ!nܸ8uę:uę{{{ĘĂ/ăŢËËË•nLś8¶¶¶xţü9ĚÍÍŃşuk8;;cđŕÁ000PúĹPA1–şęŤEg±j§Q‘ÎŞvŞZO[ÚĹĆĐľ}{ś?ŮŮŮ8{ö,|}}«ĺ:iii(,,„µµ5>|°°0Ěť;Ýşu 9ď_~ůeĄôVĄ­Ěe[ů¦.OÄć·ŞôÄĆĆbĆŚ066†T*ôéÓGt>3Ćs¨ŐRyy9ĹÇÇÓ?ţń244¤¶mŰŇ?˙ůOŠ‹‹ŁÜÜ\˝#99™$‰Ć)ň H.—ëĺxڱşĄžVĚô“7nÜ Yłf266¦ĄK— S*:t\\\ČÄÄ„şvíJ±±±Jßoܸ‘Z·nMŽŽŽtřđaÚ°a™››“··7ť9s†‚‚‚Y[[ÓćÍ›éÉ“'T\\L±±±Ô¦M@ÁÁÁtűömaźááádjjZ­-ň÷÷§’’š7o víÚŃŽ;¨¸¸ćĚ™C¨m۶´wď^ĘËËŁ ˛µµĄ}űöQQQ…„„˛°° ]»vQQQ‘°ž••mÝş•ž?®1íbc "Z˝z5YXXP÷îÝé·ß~]ŽČÓÓ“&OžLcĆŚ!OOOZ˛d‰›¦Ľ—JĄ4zôhµĺŞ©Ě._ľ\gů¦ .OÔm§­ž*ňJ.—Ó¨QŁhţüůôěŮ3QůÜR§ßcڍĺÖ˝L?©«ÜÜ\üřăŹŘż?~ţůg”––ÂÁÁîîîčŃŁÜÜÜŕćć†Nť:U›é@“ŇŇRLť: *‡ÔcĐ A8xđ Ú&cŤGVV:wîŚS§Nˇ_ż~ ŽÎž>}а°0Ľ˙ţűÂ]Ő§Oźâ—_~^HÔÔtÚJ¦›–:ýc@Ë­˙z™~RW/żü2fĚ3f ĽĽçÎťĂůóç‘––†={ö@.— ?y¶k×vvv°łł­­­Đ±öě>|ČËËCvv¶06ľuëÖ(--Uú™ŘČČíŰ·Çöí۹ϫľľľ(,,Ä’%K„eFFFčرcÍčĄOb’Ť‹‹«‡HcŚUU§ůŞLLLĐ·o_ôíŰWXöôéSüůçźČČČ@~~>ňňň——‡ÜÜ\”””ŔČČÖÖÖ°µµôîÝŻĽň ěííŃąsgÜĽy#GŽT:ŽaeeU_IcڵpiiiČĎĎÇĆŤ!“É`jjŠÔÔT,]ş´QMYS%%%Z×QL÷«ř—1ĆXÝ«·ŽĽĘÁÉÉI–LW...0aâăă…‹Ç7ß|#Ľ\†1ĆęCRR>űě3âÉ“'čÚµ+Fމ={öp6gŮŮى‰¤¤¤`éŇĄ3fŚĘ!1ĆÓźíČëĂňĺ˱uëVŔżţő/Lš4©#bڵ4ÝşukŃăÂ_}őUDGGóű:c¬žŐjůĆŔĆĆ;vě@·nݰfÍš†‡1ĆcڱzŃäďČ•šyyyˇU«V  c¬vî܉śśś†±FíěŮł€‹/bçÎť  cő«ĄÖ˙ääd¸şşV[^§ÓO2ĆŠé'cŚ1¦ÚŚ3ŞM?ÉyĆcŚ1Ćš &?Fž1Ćcڱ–;ňŚ1ĆcŚ5AÜ‘gŚ1Ćc¬ âŽ`__ `tar.gz `__] Development: [`zip `__ `tar.gz `__] `Prior downloads `_ To check out the latest development version:: git clone git://github.com/nipy/nipype.git Install ------- The installation process is similar to other Python packages. If you already have a Python environment setup that has the dependencies listed below, you can do:: easy_install nipype or:: pip install nipype Debian and Ubuntu ~~~~~~~~~~~~~~~~~ Add the `NeuroDebian `_ repository and install the ``python-nipype`` package using ``apt-get`` or your favorite package manager. Mac OS X ~~~~~~~~ The easiest way to get nipype running on Mac OS X is to install Anaconda_ or Canopy_ and then add nibabel and nipype by executing:: easy_install nibabel easy_install nipype From source ~~~~~~~~~~~ If you downloaded the source distribution named something like ``nipype-x.y.tar.gz``, then unpack the tarball, change into the ``nipype-x.y`` directory and install nipype using:: python setup.py install **Note:** Depending on permissions you may need to use ``sudo``. Testing the install ------------------- The best way to test the install is to run the test suite. If you have nose_ installed, then do the following:: python -c "import nipype; nipype.test()" you can also test with nosetests:: nosetests --with-doctest /software/nipy-repo/masternipype/nipype --exclude=external --exclude=testing All tests should pass (unless you're missing a dependency). If SUBJECTS_DIR variable is not set some FreeSurfer related tests will fail. If any tests fail, please report them on our `bug tracker `_. On Debian systems, set the following environment variable before running tests:: export MATLABCMD=$pathtomatlabdir/bin/$platform/MATLAB where, $pathtomatlabdir is the path to your matlab installation and $platform is the directory referring to x86 or x64 installations (typically glnxa64 on 64-bit installations). Avoiding any MATLAB calls from testing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On unix systems, set an empty environment variable:: export NIPYPE_NO_MATLAB= This will skip any tests that require matlab. Dependencies ------------ Below is a list of required dependencies, along with additional software recommendations. Must Have ~~~~~~~~~ Python_ 2.7 Nibabel_ 1.0 - 1.4 Neuroimaging file i/o library NetworkX_ 1.0 - 1.8 Python package for working with complex networks. NumPy_ 1.3 - 1.7 SciPy_ 0.7 - 0.12 Numpy and Scipy are high-level, optimized scientific computing libraries. Enthought_ Traits_ 4.0.0 - 4.3.0 Dateutil 1.5 - .. note:: Full distributions such as Anaconda_ or Canopy_ provide the above packages, except Nibabel_. Strong Recommendations ~~~~~~~~~~~~~~~~~~~~~~ IPython_ 0.10.2 - 1.0.0 Interactive python environment. This is necessary for some parallel components of the pipeline engine. Matplotlib_ 1.0 - 1.2 Plotting library `RDFLib `_ 4.1 RDFLibrary required for provenance export as RDF Sphinx_ 1.1 Required for building the documentation `Graphviz `_ Required for building the documentation Interface Dependencies ~~~~~~~~~~~~~~~~~~~~~~ These are the software packages that nipype.interfaces wraps: FSL_ 4.1.0 or later matlab_ 2008a or later SPM_ SPM5/8 FreeSurfer_ FreeSurfer version 4 and higher AFNI_ 2009_12_31_1431 or later Slicer_ 3.6 or later Nipy_ 0.1.2+20110404 or later Nitime_ (optional) Camino_ Camino2Trackvis_ ConnectomeViewer_ .. include:: ../links_names.txt nipype-0.11.0/doc/users/interface_tutorial.rst000066400000000000000000000142431257611314500214310ustar00rootroot00000000000000.. _interface_tutorial: ======================= Tutorial : Interfaces ======================= Specifying options ------------------ The nipype interface modules provide a Python interface to external packages like FSL_ and SPM_. Within the module are a series of Python classes which wrap specific package functionality. For example, in the fsl module, the class :class:`nipype.interfaces.fsl.Bet` wraps the ``bet`` command-line tool. Using the command-line tool, one would specify options using flags like ``-o``, ``-m``, ``-f ``, etc... However, in nipype, options are assigned to Python attributes and can be specified in the following ways: Options can be assigned when you first create an interface object: .. testcode:: import nipype.interfaces.fsl as fsl mybet = fsl.BET(in_file='foo.nii', out_file='bar.nii') result = mybet.run() Options can be assigned through the ``inputs`` attribute: .. testcode:: import nipype.interfaces.fsl as fsl mybet = fsl.BET() mybet.inputs.in_file = 'foo.nii' mybet.inputs.out_file = 'bar.nii' result = mybet.run() Options can be assigned when calling the ``run`` method: .. testcode:: import nipype.interfaces.fsl as fsl mybet = fsl.BET() result = mybet.run(in_file='foo.nii', out_file='bar.nii', frac=0.5) Getting Help ------------ In IPython_ you can view the docstrings which provide some basic documentation and examples. .. sourcecode:: ipython In [2]: fsl.FAST? Type: type Base Class: String Form: Namespace: Interactive File: /Users/satra/sp/nipype/interfaces/fsl/preprocess.py Docstring: Use FSL FAST for segmenting and bias correction. For complete details, see the `FAST Documentation. `_ Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import anatfile Assign options through the ``inputs`` attribute: >>> fastr = fsl.FAST() >>> fastr.inputs.in_files = anatfile >>> out = fastr.run() #doctest: +SKIP Constructor information: Definition: fsl.FAST(self, **inputs) .. sourcecode:: ipython In [5]: spm.Realign? Type: type Base Class: String Form: Namespace: Interactive File: /Users/satra/sp/nipype/interfaces/spm/preprocess.py Docstring: Use spm_realign for estimating within modality rigid body alignment http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=25 Examples -------- >>> import nipype.interfaces.spm as spm >>> realign = spm.Realign() >>> realign.inputs.in_files = 'functional.nii' >>> realign.inputs.register_to_mean = True >>> realign.run() # doctest: +SKIP Constructor information: Definition: spm.Realign(self, **inputs) All of the nipype.interfaces classes have an ``help`` method which provides information on each of the options one can assign. .. sourcecode:: ipython In [6]: fsl.BET.help() Inputs ------ Mandatory: in_file: input file to skull strip Optional: args: Additional parameters to the command center: center of gravity in voxels environ: Environment variables (default={}) frac: fractional intensity threshold functional: apply to 4D fMRI data mutually exclusive: functional, reduce_bias mask: create binary mask image mesh: generate a vtk mesh brain surface no_output: Don't generate segmented output out_file: name of output skull stripped image outline: create surface outline image output_type: FSL output type radius: head radius reduce_bias: bias field and neck cleanup mutually exclusive: functional, reduce_bias skull: create skull image threshold: apply thresholding to segmented brain image and mask vertical_gradient: vertical gradient in fractional intensity threshold (-1, 1) Outputs ------- mask_file: path/name of binary brain mask (if generated) meshfile: path/name of vtk mesh file (if generated) out_file: path/name of skullstripped file outline_file: path/name of outline file (if generated) .. sourcecode:: ipython In [7]: spm.Realign.help() Inputs ------ Mandatory: in_files: list of filenames to realign Optional: fwhm: gaussian smoothing kernel width interp: degree of b-spline used for interpolation jobtype: one of: estimate, write, estwrite (default=estwrite) matlab_cmd: None mfile: Run m-code using m-file (default=True) paths: Paths to add to matlabpath quality: 0.1 = fast, 1.0 = precise register_to_mean: Indicate whether realignment is done to the mean image separation: sampling separation in mm weight_img: filename of weighting image wrap: Check if interpolation should wrap in [x,y,z] write_interp: degree of b-spline used for interpolation write_mask: True/False mask output image write_which: determines which images to reslice write_wrap: Check if interpolation should wrap in [x,y,z] Outputs ------- mean_image: Mean image file from the realignment realigned_files: Realigned files realignment_parameters: Estimated translation and rotation parameters Our :ref:`interface-index` documentation provides html versions of our docstrings and includes links to the specific package documentation. For instance, the :class:`nipype.interfaces.fsl.Bet` docstring has a direct link to the online BET Documentation. FSL interface example --------------------- Using FSL_ to realign a time_series: .. testcode:: import nipype.interfaces.fsl as fsl realigner = fsl.McFlirt() realigner.inputs.in_file='timeseries4D.nii' result = realigner.run() SPM interface example --------------------- Using SPM_ to realign a time-series: .. testcode:: import nipype.interfaces.spm as spm from glob import glob allepi = glob('epi*.nii') # this will return an unsorted list allepi.sort() realigner = spm.Realign() realigner.inputs.in_files = allepi result = realigner.run() .. include:: ../links_names.txt nipype-0.11.0/doc/users/joinnode_and_itersource.rst000066400000000000000000000120431257611314500224350ustar00rootroot00000000000000.. _joinnode_and_itersource: ==================================== JoinNode, synchronize and itersource ==================================== The previous :doc:`mapnode_and_iterables` chapter described how to fork and join nodes using MapNode and iterables. In this chapter, we introduce features which build on these concepts to add workflow flexibility. JoinNode, joinsource and joinfield ================================== A :class:`nipype.pipeline.engine.JoinNode` generalizes MapNode to operate in conjunction with an upstream iterable node to reassemble downstream results, e.g.: .. digraph:: joinnode_ex "A" -> "B1" -> "C1" -> "D"; "A" -> "B2" -> "C2" -> "D"; "A" -> "B3" -> "C3" -> "D"; The code to achieve this is as follows: :: import nipype.pipeline.engine as pe a = pe.Node(interface=A(), name="a") b = pe.Node(interface=B(), name="b") b.iterables = ("in_file", images) c = pe.Node(interface=C(), name="c") d = pe.JoinNode(interface=D(), joinsource="b", joinfield="in_files", name="d") my_workflow = pe.Workflow(name="my_workflow") my_workflow.connect([(a,b,[('subject','subject')]), (b,c,[('out_file','in_file')]) (c,d,[('out_file','in_files')]) ]) This example assumes that interface "A" has one output *subject*, interface "B" has two inputs *subject* and *in_file* and one output *out_file*, interface "C" has one input *in_file* and one output *out_file*, and interface D has one list input *in_files*. The *images* variable is a list of three input image file names. As with *iterables* and the MapNode *iterfield*, the *joinfield* can be a list of fields. Thus, the declaration in the previous example is equivalent to the following: :: d = pe.JoinNode(interface=D(), joinsource="b", joinfield=["in_files"], name="d") The *joinfield* defaults to all of the JoinNode input fields, so the declaration is also equivalent to the following: :: d = pe.JoinNode(interface=D(), joinsource="b", name="d") In this example, the node "c" *out_file* outputs are collected into the JoinNode "d" *in_files* input list. The *in_files* order is the same as the upstream "b" node iterables order. The JoinNode input can be filtered for unique values by specifying the *unique* flag, e.g.: :: d = pe.JoinNode(interface=D(), joinsource="b", unique=True, name="d") synchronize =========== The :class:`nipype.pipeline.engine.Node` *iterables* parameter can be be a single field or a list of fields. If it is a list, then execution is performed over all permutations of the list items. For example: :: b.iterables = [("m", [1, 2]), ("n", [3, 4])] results in the execution graph: .. digraph:: multiple_iterables_ex "A" -> "B13" -> "C"; "A" -> "B14" -> "C"; "A" -> "B23" -> "C"; "A" -> "B24" -> "C"; where "B13" has inputs *m* = 1, *n* = 3, "B14" has inputs *m* = 1, *n* = 4, etc. The *synchronize* parameter synchronizes the iterables lists, e.g.: :: b.iterables = [("m", [1, 2]), ("n", [3, 4])] b.synchronize = True results in the execution graph: .. digraph:: synchronize_ex "A" -> "B13" -> "C"; "A" -> "B24" -> "C"; where the iterable inputs are selected in lock-step by index, i.e.: (*m*, *n*) = (1, 3) and (2, 4) for "B13" and "B24", resp. itersource ========== The *itersource* feature allows you to expand a downstream iterable based on a mapping of an upstream iterable. For example: :: a = pe.Node(interface=A(), name="a") b = pe.Node(interface=B(), name="b") b.iterables = ("m", [1, 2]) c = pe.Node(interface=C(), name="c") d = pe.Node(interface=D(), name="d") d.itersource = ("b", "m") d.iterables = [("n", {1:[3,4], 2:[5,6]})] my_workflow = pe.Workflow(name="my_workflow") my_workflow.connect([(a,b,[('out_file','in_file')]), (b,c,[('out_file','in_file')]) (c,d,[('out_file','in_file')]) ]) results in the execution graph: .. digraph:: itersource_ex "A" -> "B1" -> "C1" -> "D13"; "C1" -> "D14"; "A" -> "B2" -> "C2" -> "D25"; "C2" -> "D26"; In this example, all interfaces have input *in_file* and output *out_file*. In addition, interface "B" has input *m* and interface "D" has input *n*. A Python dictionary associates the "b" node input value with the downstream "d" node *n* iterable values. This example can be extended with a summary JoinNode: :: e = pe.JoinNode(interface=E(), joinsource="d", joinfield="in_files", name="e") my_workflow.connect(d, 'out_file', e, 'in_files') resulting in the graph: .. digraph:: itersource_with_join_ex "A" -> "B1" -> "C1" -> "D13" -> "E"; "C1" -> "D14" -> "E"; "A" -> "B2" -> "C2" -> "D25" -> "E"; "C2" -> "D26" -> "E"; The combination of iterables, MapNode, JoinNode, synchronize and itersource enables the creation of arbitrarily complex workflow graphs. The astute workflow builder will recognize that this flexibility is both a blessing and a curse. These advanced features are handy additions to the Nipype toolkit when used judiciously. nipype-0.11.0/doc/users/mapnode_and_iterables.rst000066400000000000000000000127171257611314500220510ustar00rootroot00000000000000.. _mapnode_and_iterables: ============================================ MapNode, iterfield, and iterables explained ============================================ In this chapter we will try to explain the concepts behind MapNode, iterfield, and iterables. MapNode and iterfield ====================== Imagine that you have a list of items (lets say files) and you want to execute the same node on them (for example some smoothing or masking). Some nodes accept multiple files and do exactly the same thing on them, but some don't (they expect only one file). MapNode can solve this problem. Imagine you have the following workflow: .. digraph:: mapnode_before "A" -> "B" -> "C"; Node "A" outputs a list of files, but node "B" accepts only one file. Additionally "C" expects a list of files. What you would like is to run "B" for every file in the output of "A" and collect the results as a list and feed it to "C". Something like this: .. digraph:: mapnode_after "A" -> "B1" -> "C"; "A" -> "B2" -> "C"; "A" -> "B3" -> "C"; "A" -> "Bn" -> "C"; The code to achieve this is quite simple :: import nipype.pipeline.engine as pe a = pe.Node(interface=A(), name="a") b = pe.MapNode(interface=B(), name="b", iterfield=['in_file']) c = pe.Node(interface=C(), name="c") my_workflow = pe.Workflow(name="my_workflow") my_workflow.connect([(a,b,[('out_files','in_file')]), (b,c,[('out_file','in_files')]) ]) assuming that interfaces "A" and "C" have one input "in_files" and one output "out_files" (both lists of files). Interface "B" has single file input "in_file" and single file output "out_file". You probably noticed that you connect nodes as if "B" could accept and output list of files. This is because it is wrapped using MapNode instead of Node. This special version of node will (under the bonnet) create an instance of "B" for every item in the list from the input. The compulsory argument "iterfield" defines which input should it iterate over (for example in single file smooth interface you would like to iterate over input files not the smoothing width). At the end outputs are collected into a list again. In other words this is map and reduce scenario. You might have also noticed that the iterfield arguments expects a list of input names instead of just one name. This suggests that there can be more than one! Even though a bit confusing this is true. You can specify more than one input to iterate over but the lists that you provide (for all the inputs specified in iterfield) have to have the same length. MapNode will then pair the parameters up and run the first instance with first set of parameters and second with second set of parameters. For example, this code: :: b = pe.MapNode(interface=B(), name="b", iterfield=['in_file', 'n']) b.inputs.in_file = ['file', 'another_file', 'different_file'] b.inputs.n = [1,2,3] b.run() is almost the same as running :: b1 = pe.Node(interface=B(), name="b1") b1.inputs.in_file = 'file' b1.inputs.n = 1 b2 = pe.Node(interface=B(), name="b2") b2.inputs.in_file = 'another_file' b2.inputs.n = 2 b3 = pe.Node(interface=B(), name="b3") b3.inputs.in_file = 'different_file' b3.inputs.n = 3 It is a rarely used feature, but you can sometimes find it useful. In more advanced applications it is useful to be able to iterate over items of nested lists (for example [[1,2],[3,4]]). MapNode allows you to do this with the "nested=True" parameter. Outputs will preserve the same nested structure as the inputs. Iterables ========= Now imagine a different scenario. You have your workflow as before .. digraph:: iterables_before "A" -> "B" -> "C"; and there are three possible values of one of the inputs node "B" you would like to investigate (for example width of 2,4, and 6 pixels of a smoothing node). You would like to see how different parameters in node "B" would influence everything that depends on its outputs (node "C" in our example). Therefore the new graph should look like this: .. digraph:: foo "A" -> "B1" -> "C1"; "A" -> "B2" -> "C2"; "A" -> "B3" -> "C3"; Of course you can do it manually by creating copies of all the nodes for different parameter set, but this can be very time consuming, especially when there are more than one node taking inputs from "B". Luckily nipype supports this scenario! Its called iterables and and you use it this way: :: import nipype.pipeline.engine as pe a = pe.Node(interface=A(), name="a") b = pe.Node(interface=B(), name="b") b.iterables = ("n", [1, 2, 3]) c = pe.Node(interface=C(), name="c") my_workflow = pe.Workflow(name="my_workflow") my_workflow.connect([(a,b,[('out_file','in_file')]), (b,c,[('out_file','in_file')]) ]) Assuming that you want to try out values 1, 2, and 3 of input "n" of the node "B". This will also create three different versions of node "C" - each with inputs from instances of node "C" with different values of "n". Additionally, you can set multiple iterables for a node with a list of tuples in the above format. Iterables are commonly used to execute the same workflow for many subjects. Usually one parametrises DataGrabber node with subject ID. This is achieved by connecting an IdentityInterface in front of DataGrabber. When you set iterables of the IdentityInterface to the list of subjects IDs, the same workflow will be executed for every subject. See :doc:`examples/fmri_spm` to see this pattern in action. .. include:: ../links_names.txt nipype-0.11.0/doc/users/mipav.rst000066400000000000000000000015711257611314500166620ustar00rootroot00000000000000.. _mipav: ================================ Using MIPAV, JIST, and CBS Tools ================================ If you are trying to use MIPAV, JIST or CBS Tools interfaces you need to configure CLASSPATH environmental variable correctly. It needs to include extensions shipped with MIPAV, MIPAV itself and MIPAV plugins. For example: In order to use the standalone MCR version of spm, you need to ensure that the following commands are executed at the beginning of your script: .. testcode:: # location of additional JAVA libraries to use JAVALIB=/Applications/mipav/jre/Contents/Home/lib/ext/ # location of the MIPAV installation to use MIPAV=/Applications/mipav # location of the plugin installation to use # please replace 'ThisUser' by your user name PLUGINS=/Users/ThisUser/mipav/plugins export CLASSPATH=$JAVALIB/*:$MIPAV:$MIPAV/lib/*:$PLUGINS nipype-0.11.0/doc/users/model_specification.rst000066400000000000000000000107571257611314500215540ustar00rootroot00000000000000.. _model_spec: =================================================== Model Specification for First Level fMRI Analysis =================================================== Nipype provides a general purpose model specification mechanism with specialized subclasses for package specific extensions. General purpose model specification =================================== The :class:`SpecifyModel` provides a generic mechanism for model specification. A mandatory input called subject_info provides paradigm specification for each run corresponding to a subject. This has to be in the form of a :class:`Bunch` or a list of Bunch objects (one for each run). Each Bunch object contains the following attribules. Required for most designs ------------------------- - conditions : list of names - onsets : lists of onsets corresponding to each condition - durations : lists of durations corresponding to each condition. Should be left to a single 0 if all events are being modelled as impulses. Optional -------- - regressor_names : list of names corresponding to each column. Should be None if automatically assigned. - regressors : list of lists. values for each regressor - must correspond to the number of volumes in the functional run - amplitudes : lists of amplitudes for each event. This will be ignored by SPM's Level1Design. The following two (tmod, pmod) will be ignored by any Level1Design class other than SPM: - tmod : lists of conditions that should be temporally modulated. Should default to None if not being used. - pmod : list of Bunch corresponding to conditions - name : name of parametric modulator - param : values of the modulator - poly : degree of modulation An example Bunch definition:: from nipype.interfaces.base import Bunch condnames = ['Tapping', 'Speaking', 'Yawning'] event_onsets = [[0, 10, 50], [20, 60, 80], [30, 40, 70]] durations = [[0],[0],[0]] subject_info = Bunch(conditions=condnames, onsets = event_onsets, durations = durations) Alternatively, you can provide condition, onset, duration and amplitude information through event files. The event files have to be in 1,2 or 3 column format with the columns corresponding to Onsets, Durations and Amplitudes and they have to have the name event_name.run e.g.: Words.run001.txt. The event_name part will be used to create the condition names. Words.run001.txt may look like:: # Word Onsets Durations 0 10 20 10 ... or with amplitudes:: # Word Onsets Durations Amplitudes 0 10 1 20 10 1 ... Together with this information, one needs to specify: - whether the durations and event onsets are specified in terms of scan volumes or secs. - the high-pass filter cutoff, - the repetition time per scan - functional data files corresponding to each run. Optionally you can specify realignment parameters, outlier indices. Outlier files should contain a list of numbers, one per row indicating which scans should not be included in the analysis. The numbers are 0-based. SPM specific attributes ======================= in addition to the generic specification options, several SPM specific options can be provided. In particular, the subject_info function can provide temporal and parametric modulators in the Bunch attributes tmod and pmod. The following example adds a linear parametric modulator for speaking rate for the events specified earlier:: pmod = [None, Bunch(name=['Rate'], param=[[.300, .500, .600]], poly=[1]), None] subject_info = Bunch(conditions=condnames, onsets = event_onsets, durations = durations, pmod = pmod) :class:`SpecifySPMModel` also allows specifying additional components. If you have a study with multiple runs, you can choose to concatenate conditions from different runs. by setting the input option **concatenate_runs** to True. You can also choose to set the output options for this class to be in terms of 'scans'. Sparse model specification ========================== In addition to standard models, :class:`SpecifySparseModel` allows model generation for sparse and sparse-clustered acquisition experiments. Details of the model generation and utility are provided in `Ghosh et al. (2009) OHBM 2009. `_ .. include:: ../links_names.txt nipype-0.11.0/doc/users/nipypecmd.rst000066400000000000000000000047441257611314500175430ustar00rootroot00000000000000.. _nipypecmd: ============================================================ Running Nipype Interfaces from the command line (nipype_cmd) ============================================================ The primary use of Nipype_ is to build automated non-interactive pipelines. However, sometimes there is a need to run some interfaces quickly from the command line. This is especially useful when running Interfaces wrapping code that does not have command line equivalents (nipy or SPM). Being able to run Nipype interfaces opens new possibilities such as inclusion of SPM processing steps in bash scripts. To run Nipype Interafces you need to use the nipype_cmd tool that should already be installed. The tool allows you to list Interfaces available in a certain package: .. testcode:: $nipype_cmd nipype.interfaces.nipy Available Interfaces: SpaceTimeRealigner Similarity ComputeMask FitGLM EstimateContrast FmriRealign4d After selecting a particular Interface you can learn what inputs it requires: .. testcode:: $nipype_cmd nipype.interfaces.nipy ComputeMask --help usage:nipype_cmd nipype.interfaces.nipy ComputeMask [-h] [--M M] [--cc CC] [--ignore_exception IGNORE_EXCEPTION] [--m M] [--reference_volume REFERENCE_VOLUME] mean_volume Run ComputeMask positional arguments: mean_volume mean EPI image, used to compute the threshold for the mask optional arguments: -h, --help show this help message and exit --M M upper fraction of the histogram to be discarded --cc CC Keep only the largest connected component --ignore_exception IGNORE_EXCEPTION Print an error message instead of throwing an exception in case the interface fails to run --m M lower fraction of the histogram to be discarded --reference_volume REFERENCE_VOLUME reference volume used to compute the mask. If none is give, the mean volume is used. Finally you can run run the Interface: .. testcode:: $nipype_cmd nipype.interfaces.nipy ComputeMask mean.nii.gz All that from the command line without having to start python interpreter manually. .. include:: ../links_names.txt nipype-0.11.0/doc/users/pipeline_tutorial.rst000066400000000000000000000036421257611314500212770ustar00rootroot00000000000000.. _pipeline_tutorial: ===================== Tutorial : Workflows ===================== This section presents several tutorials on how to setup and use pipelines. Make sure that you have the requirements satisfied and go through the steps required for the analysis tutorials. Essential reading ================= .. toctree:: :maxdepth: 1 :glob: tutorial_101 tutorial_102 tutorial_103 mapnode_and_iterables grabbing_and_sinking Beginner's guide ================ By Michael Notter. `Available here`__ __ http://miykael.github.com/nipype-beginner-s-guide/index.html Example workflows ================= .. toctree:: :maxdepth: 1 :glob: examples/* Requirements ============ All tutorials - Release 0.4 of nipype and it's dependencies have been installed Analysis tutorials - FSL_, FreeSurfer_, Camino_, ConnectomeViewer and MATLAB_ are available and callable from the command line - SPM_ 5/8 is installed and callable in matlab - Space: 3-10 GB Checklist for analysis tutorials ================================ For the analysis tutorials, we will be using a slightly modified version of the FBIRN Phase I travelling data set. Step 0 ~~~~~~ Download and extract the `Pipeline tutorial data (429MB). `_ (checksum: 56ed4b7e0aac5627d1724e9c10cd26a7) Step 1. ~~~~~~~ Ensure that all programs are available by calling ``bet``, ``matlab`` and then ``which spm`` within matlab to ensure you have spm5/8 in your matlab path. Step 2. ~~~~~~~ You can now run the tutorial by typing ``python tutorial_script.py`` within the nipype-tutorial directory. This will run a full first level analysis on two subjects following by a 1-sample t-test on their first level results. The next section goes through each section of the tutorial script and describes what it is doing. .. include:: ../links_names.txt nipype-0.11.0/doc/users/plugins.rst000066400000000000000000000270301257611314500172250ustar00rootroot00000000000000.. _plugins: ==================== Using Nipype Plugins ==================== The workflow engine supports a plugin architecture for workflow execution. The available plugins allow local and distributed execution of workflows and debugging. Each available plugin is described below. Current plugins are available for Linear, Multiprocessing, IPython_ distributed processing platforms and for direct processing on SGE_, PBS_, HTCondor_, LSF_, and SLURM_. We anticipate future plugins for the Soma_ workflow. .. note:: The current distributed processing plugins rely on the availability of a shared filesystem across computational nodes. A variety of config options can control how execution behaves in this distributed context. These are listed later on in this page. All plugins can be executed with:: workflow.run(plugin=PLUGIN_NAME, plugin_args=ARGS_DICT) Optional arguments:: status_callback : a function handle max_jobs : maximum number of concurrent jobs max_tries : number of times to try submitting a job retry_timeout : amount of time to wait between tries .. note:: Except for the status_callback, the remaining arguments only apply to the distributed plugins: MultiProc/IPython(X)/SGE/PBS/HTCondor/HTCondorDAGMan/LSF For example: Plugins ======= Debug ----- This plugin provides a simple mechanism to debug certain components of a workflow without executing any node. Mandatory arguments:: callable : A function handle that receives as arguments a node and a graph The function callable will called for every node from a topological sort of the execution graph. Linear ------ This plugin runs the workflow one node at a time in a single process locally. The order of the nodes is determined by a topological sort of the workflow:: workflow.run(plugin='Linear') MultiProc --------- Uses the Python_ multiprocessing library to distribute jobs as new processes on a local system. Optional arguments:: n_procs : Number of processes to launch in parallel, if not set number of processors/threads will be automatically detected To distribute processing on a multicore machine, simply call:: workflow.run(plugin='MultiProc') This will use all available CPUs. If on the other hand you would like to restrict the number of used resources (to say 2 CPUs), you can call:: workflow.run(plugin='MultiProc', plugin_args={'n_procs' : 2} IPython ------- This plugin provide access to distributed computing using IPython_ parallel machinery. .. note:: We provide backward compatibility with IPython_ versions earlier than 0.10.1 using the IPythonX plugin. Please read the IPython_ documentation to determine how to setup your cluster for distributed processing. This typically involves calling ipcluster. Once the clients have been started, any pipeline executed with:: workflow.run(plugin='IPython') SGE/PBS ------- In order to use nipype with SGE_ or PBS_ you simply need to call:: workflow.run(plugin='SGE') workflow.run(plugin='PBS') Optional arguments:: template: custom template file to use qsub_args: any other command line args to be passed to qsub. max_jobname_len: (PBS only) maximum length of the job name. Default 15. For example, the following snippet executes the workflow on myqueue with a custom template:: workflow.run(plugin='SGE', plugin_args=dict(template='mytemplate.sh', qsub_args='-q myqueue') In addition to overall workflow configuration, you can use node level configuration for PBS/SGE:: node.plugin_args = {'qsub_args': '-l nodes=1:ppn=3'} this would apply only to the node and is useful in situations, where a particular node might use more resources than other nodes in a workflow. .. note:: Setting the keyword `overwrite` would overwrite any global configuration with this local configuration:: node.plugin_args = {'qsub_args': '-l nodes=1:ppn=3', 'overwrite': True} SGEGraph ~~~~~~~~ SGEGraph_ is an execution plugin working with Sun Grid Engine that allows for submitting entire graph of dependent jobs at once. This way Nipype does not need to run a monitoring process - SGE takes care of this. The use of SGEGraph_ is preferred over SGE_ since the latter adds unnecessary load on the submit machine. .. note:: When rerunning unfinished workflows using SGEGraph you may decide not to submit jobs for Nodes that previously finished running. This can speed up execution, but new or modified inputs that would previously trigger a Node to rerun will be ignored. The following option turns on this functionality:: workflow.run(plugin='SGEGraph', plugin_args = {'dont_resubmit_completed_jobs': True}) LSF --- Submitting via LSF is almost identical to SGE above above except for the optional arguments field:: workflow.run(plugin='LSF') Optional arguments:: template: custom template file to use bsub_args: any other command line args to be passed to bsub. SLURM ----- Submitting via SLURM is almost identical to SGE above except for the optional arguments field: workflow.run(plugin='SLURM') Optional arguments:: template: custom template file to use sbatch_args: any other command line args to be passed to bsub. SLURMGraph ~~~~~~~~~~ SLURMGraph_ is an execution plugin working with SLURM that allows for submitting entire graph of dependent jobs at once. This way Nipype does not need to run a monitoring process - SLURM takes care of this. The use of SLURMGraph_ plugin is preferred over the vanilla SLURM_ plugin since the latter adds unnecessary load on the submit machine. .. note:: When rerunning unfinished workflows using SLURMGraph you may decide not to submit jobs for Nodes that previously finished running. This can speed up execution, but new or modified inputs that would previously trigger a Node to rerun will be ignored. The following option turns on this functionality:: workflow.run(plugin='SLURMGraph', plugin_args = {'dont_resubmit_completed_jobs': True}) HTCondor -------- DAGMan ~~~~~~ With its DAGMan_ component HTCondor_ (previously Condor) allows for submitting entire graphs of dependent jobs at once (similar to SGEGraph_ and SLURMGraph_). With the ``CondorDAGMan`` plug-in Nipype can utilize this functionality to submit complete workflows directly and in a single step. Consequently, and in contrast to other plug-ins, workflow execution returns almost instantaneously -- Nipype is only used to generate the workflow graph, while job scheduling and dependency resolution are entirely managed by HTCondor_. Please note that although DAGMan_ supports specification of data dependencies as well as data provisioning on compute nodes this functionality is currently not supported by this plug-in. As with all other batch systems supported by Nipype, only HTCondor pools with a shared file system can be used to process Nipype workflows. Workflow execution with HTCondor DAGMan is done by calling:: workflow.run(plugin='CondorDAGMan') Job execution behavior can be tweaked with the following optional plug-in arguments. The value of most arguments can be a literal string or a filename, where in the latter case the content of the file will be used as the argument value:: submit_template : submit spec template for individual jobs in a DAG (see CondorDAGManPlugin.default_submit_template for the default. initial_specs : additional submit specs that are prepended to any job's submit file override_specs : additional submit specs that are appended to any job's submit file wrapper_cmd : path to an exectuable that will be started instead of a node script. This is useful for wrapper script that execute certain functionality prior or after a node runs. If this option is given the wrapper command is called with the respective Python exectuable and the path to the node script as final arguments wrapper_args : optional additional arguments to a wrapper command dagman_args : arguments to be prepended to the job execution script in the dagman call block : if True the plugin call will block until Condor has finished prcoessing the entire workflow (default: False) Please see the `HTCondor documentation`_ for details on possible configuration options and command line arguments. Using the ``wrapper_cmd`` argument it is possible to combine Nipype workflow execution with checkpoint/migration functionality offered by, for example, DMTCP_. This is especially useful in the case of workflows with long running nodes, such as Freesurfer's recon-all pipeline, where Condor's job prioritization algorithm could lead to jobs being evicted from compute nodes in order to maximize overall troughput. With checkpoint/migration enabled such a job would be checkpointed prior eviction and resume work from the checkpointed state after being rescheduled -- instead of restarting from scratch. On a Debian system, executing a workflow with support for checkpoint/migration for all nodes could look like this:: # define common parameters dmtcp_hdr = """ should_transfer_files = YES when_to_transfer_output = ON_EXIT_OR_EVICT kill_sig = 2 environment = DMTCP_TMPDIR=./;JALIB_STDERR_PATH=/dev/null;DMTCP_PREFIX_ID=$(CLUSTER)_$(PROCESS) """ shim_args = "--log %(basename)s.shimlog --stdout %(basename)s.shimout --stderr %(basename)s.shimerr" # run workflow workflow.run( plugin='CondorDAGMan', plugin_args=dict(initial_specs=dmtcp_hdr, wrapper_cmd='/usr/lib/condor/shim_dmtcp', wrapper_args=shim_args) ) ``qsub`` emulation ~~~~~~~~~~~~~~~~~~ .. note:: This plug-in is deprecated and users should migrate to the more robust and more versatile ``CondorDAGMan`` plug-in. Despite the differences between HTCondor and SGE-like batch systems the plugin usage (incl. supported arguments) is almost identical. The HTCondor plugin relies on a ``qsub`` emulation script for HTCondor, called ``condor_qsub`` that can be obtained from a `Git repository on git.debian.org`_. This script is currently not shipped with a standard HTCondor distribution, but is included in the HTCondor package from http://neuro.debian.net. It is sufficient to download this script and install it in any location on a system that is included in the ``PATH`` configuration. .. _Git repository on git.debian.org: http://anonscm.debian.org/gitweb/?p=pkg-exppsy/condor.git;a=blob_plain;f=debian/condor_qsub;hb=HEAD Running a workflow in a HTCondor pool is done by calling:: workflow.run(plugin='Condor') The plugin supports a limited set of qsub arguments (``qsub_args``) that cover the most common use cases. The ``condor_qsub`` emulation script translates qsub arguments into the corresponding HTCondor terminology and handles the actual job submission. For details on supported options see the manpage of ``condor_qsub``. Optional arguments:: qsub_args: any other command line args to be passed to condor_qsub. .. include:: ../links_names.txt .. _SGE: http://www.oracle.com/us/products/tools/oracle-grid-engine-075549.html .. _OGE: http://www.oracle.com/us/products/tools/oracle-grid-engine-075549.html .. _Soma: http://brainvisa.info/soma/soma-workflow/ .. _PBS: http://www.clusterresources.com/products/torque-resource-manager.php .. _LSF: http://www.platform.com/Products/platform-lsf .. _HTCondor: http://www.cs.wisc.edu/htcondor/ .. _DAGMan: http://research.cs.wisc.edu/htcondor/dagman/dagman.html .. _HTCondor documentation: http://research.cs.wisc.edu/htcondor/manual .. _DMTCP: http://dmtcp.sourceforge.net .. _SLURM: http://slurm.schedmd.com/ nipype-0.11.0/doc/users/saving_workflows.rst000066400000000000000000000070171257611314500211530ustar00rootroot00000000000000.. _saving_workflows: =================================================== Saving Workflows and Nodes to a file (experimental) =================================================== On top of the standard way of saving (i.e. serializing) objects in Python (see `pickle `_) Nipype provides methods to turn Workflows and nodes into human readable code. This is useful if you want to save a Workflow that you have generated on the fly for future use. To generate Python code for a Workflow use the export method: .. testcode:: from nipype.interfaces.fsl import BET, ImageMaths from nipype.pipeline.engine import Workflow, Node, MapNode, format_node from nipype.interfaces.utility import Function, IdentityInterface bet = Node(BET(), name='bet') bet.iterables = ('frac', [0.3, 0.4]) bet2 = MapNode(BET(), name='bet2', iterfield=['infile']) bet2.iterables = ('frac', [0.4, 0.5]) maths = Node(ImageMaths(), name='maths') def testfunc(in1): """dummy func """ out = in1 + 'foo' + "out1" return out funcnode = Node(Function(input_names=['a'], output_names=['output'], function=testfunc), name='testfunc') funcnode.inputs.in1 = '-sub' func = lambda x: x inode = Node(IdentityInterface(fields=['a']), name='inode') wf = Workflow('testsave') wf.add_nodes([bet2]) wf.connect(bet, 'mask_file', maths, 'in_file') wf.connect(bet2, ('mask_file', func), maths, 'in_file2') wf.connect(inode, 'a', funcnode, 'in1') wf.connect(funcnode, 'output', maths, 'op_string') wf.export() This will create a file "outputtestsave.py" with the following content: .. testcode:: from nipype.pipeline.engine import Workflow, Node, MapNode from nipype.interfaces.utility import IdentityInterface from nipype.interfaces.utility import Function from nipype.utils.misc import getsource from nipype.interfaces.fsl.preprocess import BET from nipype.interfaces.fsl.utils import ImageMaths # Functions func = lambda x: x # Workflow testsave = Workflow("testsave") # Node: testsave.inode inode = Node(IdentityInterface(fields=['a'], mandatory_inputs=True), name="inode") # Node: testsave.testfunc testfunc = Node(Function(input_names=['a'], output_names=['output']), name="testfunc") def testfunc_1(in1): """dummy func """ out = in1 + 'foo' + "out1" return out testfunc.inputs.function_str = getsource(testfunc_1) testfunc.inputs.ignore_exception = False testfunc.inputs.in1 = '-sub' testsave.connect(inode, "a", testfunc, "in1") # Node: testsave.bet2 bet2 = MapNode(BET(), iterfield=['infile'], name="bet2") bet2.iterables = ('frac', [0.4, 0.5]) bet2.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} bet2.inputs.ignore_exception = False bet2.inputs.output_type = 'NIFTI_GZ' bet2.inputs.terminal_output = 'stream' # Node: testsave.bet bet = Node(BET(), name="bet") bet.iterables = ('frac', [0.3, 0.4]) bet.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} bet.inputs.ignore_exception = False bet.inputs.output_type = 'NIFTI_GZ' bet.inputs.terminal_output = 'stream' # Node: testsave.maths maths = Node(ImageMaths(), name="maths") maths.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'} maths.inputs.ignore_exception = False maths.inputs.output_type = 'NIFTI_GZ' maths.inputs.terminal_output = 'stream' testsave.connect(bet2, ('mask_file', func), maths, "in_file2") testsave.connect(bet, "mask_file", maths, "in_file") testsave.connect(testfunc, "output", maths, "op_string") The file is ready to use and includes all the necessary imports. .. include:: ../links_names.txt nipype-0.11.0/doc/users/select_files.rst000066400000000000000000000073251257611314500202120ustar00rootroot00000000000000.. _select_files: ========================== The SelectFiles Interfaces ========================== Nipype 0.9 introduces a new interface for intelligently finding files on the disk and feeding them into your workflows: :ref:`SelectFiles `. SelectFiles is intended as a simpler alternative to the :ref:`DataGrabber ` interface that was discussed previously in :doc:`grabbing_and_sinking`. SelectFiles is built on Python `format strings `_, which are similar to the Python string interpolation feature you are likely already familiar with, but advantageous in several respects. Format strings allow you to replace named sections of template strings set off by curly braces (`{}`), possibly filtered through a set of functions that control how the values are rendered into the string. As a very basic example, we could write :: msg = "This workflow uses {package}" and then format it with keyword arguments:: print msg.format(package="FSL") SelectFiles only requires that you provide templates that can be used to find your data; the actual formatting happens behind the scenes. Consider a basic example in which you want to select a T1 image and multple functional images for a number of subjects. Invoking SelectFiles in this case is quite straightforward:: from nipype import SelectFiles templates = dict(T1="data/{subject_id}/struct/T1.nii", epi="data/{subject_id}/func/epi_run*.nii") sf = SelectFiles(templates) SelectFiles will take the `templates` dictionary and parse it to determine its own inputs and oututs. Specifically, each name used in the format spec (here just `subject_id`) will become an interface input, and each key in the dictionary (here `T1` and `epi`) will become interface outputs. The `templates` dictionary thus succinctly links the node inputs to the appropriate outputs. You'll also note that, as was the case with DataGrabber, you can use basic `glob `_ syntax to match multiple files for a given output field. Additionally, any of the conversions outlined in the Python documentation for format strings can be used in the templates. There are a few other options that help make SelectFiles flexible enough to deal with any situation where you need to collect data. Like DataGrabber, SelectFiles has a `base_directory` parameter that allows you to specify a path that is common to all of the values in the `templates` dictionary. Additionally, as `glob` does not return a sorted list, there is also a `sort_filelist` option, taking a boolean, to control whether sorting should be applied (it is True by default). The final input is `force_lists`, which controls how SelectFiles behaves in cases where only a single file matches the template. The default behavior is that when a template matches multiple files they are returned as a list, while a single file is returned as a string. There may be situations where you want to force the outputs to always be returned as a list (for example, you are writing a workflow that expects to operate on several runs of data, but some of your subjects only have a single run). In this case, `force_lists` can be used to tune the outputs of the interface. You can either use a boolean value, which will be applied to every output the interface has, or you can provide a list of the output fields that should be coerced to a list. Returning to our basic example, you may want to ensure that the `epi` files are returned as a list, but you only ever will have a single `T1` file. In this case, you would do :: sf = SelectFiles(templates, force_lists=["epi"]) .. include:: ../links_names.txt nipype-0.11.0/doc/users/spmmcr.rst000066400000000000000000000021561257611314500170470ustar00rootroot00000000000000.. _spmmcr: ==================================== Using SPM with MATLAB Common Runtime ==================================== In order to use the standalone MCR version of spm, you need to ensure that the following commands are executed at the beginning of your script: .. testcode:: from nipype.interfaces import spm matlab_cmd = '/path/to/run_spm8.sh /path/to/Compiler_Runtime/v713/ script' spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True) you can test by calling: .. testcode:: spm.SPMCommand().version If you want to enforce the standalone MCR version of spm for nipype globally, you can do so by setting the following environment variables: *SPMMCRCMD* Specifies the command to use to run the spm standalone MCR version. You may still override the command as described above. *FORCE_SPMMCR* Set this to any value in order to enforce the use of spm standalone MCR version in nipype globally. Technically, this sets the `use_mcr` flag of the spm interface to True. Information about the MCR version of SPM8 can be found at: http://en.wikibooks.org/wiki/SPM/Standalone nipype-0.11.0/doc/users/tutorial_101.rst000066400000000000000000000153671257611314500200020ustar00rootroot00000000000000.. _tutorial_101: ============ Pipeline 101 ============ A workflow or pipeline is built by connecting processes or nodes to each other. In the context of nipype, every interface can be treated as a pipeline node having defined inputs and outputs. Creating a workflow then is a matter of connecting appropriate outputs to inputs. Currently, workflows are limited to being directional and cannot have any loops, thereby creating an ordering to data flow. The following nipype component architecture might help understanding some of the tutorials presented here. .. image:: images/componentarchitecture.png :width: 600 px My first pipeline ================= Although the most trivial workflow consists of a single node, we will create a workflow with two nodes: a realign node that will send the realigned functional data to a smoothing node. It is important to note that setting up a workflow is separate from executing it. **1. Import appropriate modules** .. testcode:: import nipype.interfaces.spm as spm # the spm interfaces import nipype.pipeline.engine as pe # the workflow and node wrappers **2. Define nodes** Here we take instances of interfaces and make them pipeline compatible by wrapping them with pipeline specific elements. To determine the inputs and outputs of a given interface, please see :ref:`interface_tutorial`. Let's start with defining a realign node using the interface :class:`nipype.interfaces.spm.Realign` .. testcode:: realigner = pe.Node(interface=spm.Realign(), name='realign') realigner.inputs.in_files = 'somefuncrun.nii' realigner.inputs.register_to_mean = True This would be equivalent to: .. testcode:: realigner = pe.Node(interface=spm.Realign(infile='somefuncrun.nii', register_to_mean = True), name='realign') In Pythonic terms, this is saying that interface option in Node accepts an *instance* of an interface. The inputs to this interface can be set either later or while initializing the interface. .. note:: In the above example, 'somefuncrun.nii' has to exist, otherwise the commands won't work. A node will check if appropriate inputs are being supplied. Similar to the realigner node, we now set up a smoothing node. .. testcode:: smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') Now we have two nodes with their inputs defined. Note that we have not defined an input file for the smoothing node. This will be done by connecting the realigner to the smoother in step 5. **3. Creating and configuring a workflow** Here we create an instance of a workflow and indicate that it should operate in the current directory. .. testcode:: workflow = pe.Workflow(name='preproc') workflow.base_dir = '.' **4. Adding nodes to workflows (optional)** If nodes are going to be connected (see step 5), this step is not necessary. However, if you would like to run a node by itself without connecting it to any other node, then you need to add it to the workflow. For adding nodes, order of nodes is not important. .. testcode:: workflow.add_nodes([smoother, realigner]) This results in a workflow containing two isolated nodes: .. image:: images/smoothrealignunconnected.png **5. Connecting nodes to each other** We want to connect the output produced by the node realignment to the input of the node smoothing. This is done as follows. .. testcode:: workflow.connect(realigner, 'realigned_files', smoother, 'in_files') Although not shown here, the following notation can be used to connect multiple outputs from one node to multiple inputs (see step 7 below). .. testcode:: workflow.connect([(realigner, smoother, [('realigned_files', 'in_files')])]) This results in a workflow containing two connected nodes: .. image:: images/smoothrealignconnected.png **6. Visualizing the workflow** The workflow is represented as a directed acyclic graph (DAG) and one can visualize this using the following command. In fact, the pictures above were generated using this. .. testcode:: workflow.write_graph() This creates two files graph.dot and graph_detailed.dot and if graphviz_ is installed on your system it automatically converts it to png files. If graphviz is not installed you can take the dot files and load them in a graphviz visualizer elsewhere. You can specify how detailed the graph is going to be, by using "graph2use" argument which takes the following options: * hierarchical - creates a graph showing all embedded workflows (default) * orig - creates a top level graph without expanding internal workflow nodes * flat - expands workflow nodes recursively * exec - expands workflows to depict iterables (be careful - can generate really large graphs) **7. Extend it** Now that you have seen a basic pipeline let's add another node to the above pipeline. .. testcode:: import nipype.algorithms.rapidart as ra artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') artdetect.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 0.5 art.inputs.zintensity_threshold = 3 workflow.connect([(realigner, artdetect, [('realigned_files', 'realigned_files'), ('realignment_parameters','realignment_parameters')] )]) .. note:: a) How an alternative form of connect was used to connect multiple output fields from the realign node to corresponding input fields of the artifact detection node. b) The current visualization only shows connected input and output ports. It does not show all the parameters that you have set for a node. This results in .. image:: images/threecomponentpipe.png :width: 650 px **8. Execute the workflow** Assuming that **somefuncrun.nii** is actually a file or you've replaced it with an appropriate one, you can run the pipeline with: .. testcode:: workflow.run() This should create a folder called preproc in your current directory, inside which are three folders: realign, smooth and artdetect (the names of the nodes). The outputs of these routines are in these folders. .. include:: ../links_names.txt .. glossary:: pipeline Connected series of processes (processes can be run parallel and or sequential) workflow (kind of synonymous to pipeline) = hosting the nodes node = switching-point within a pipeline, you can give it a name (in the above example e.g. realigner), a node usually requires an or several inputs and will produce an or several outputs interface = specific software (e.g. FSL, SPM ...) are wrapped in interfaces, within a node instances of an interface can be run modules for each interface the according modules have to be imported in the usual pythonic manner nipype-0.11.0/doc/users/tutorial_102.rst000066400000000000000000000117451257611314500177770ustar00rootroot00000000000000.. _tutorial_102: ============ Pipeline 102 ============ Now that you know how to construct a workflow and execute it, we will go into more advanced concepts. This tutorial focuses on :class:`nipype.pipeline.engine.Workflow` :class:`nipype.pipeline.engine.Node` and :class:`nipype.pipeline.engine.MapNode`. A workflow is a **directed acyclic graph (DAG)** consisting of nodes which can be of type `Workflow`, `Node` or `MapNode`. Workflows can be re-used and hierarchical workflows can be easily constructed. 'name' : the mandatory keyword arg ================================== When instantiating a Workflow, Node or MapNode, a `name` has to be provided. For any given level of a workflow, no two nodes can have the same name. The engine will let you know if this is the case when you add nodes to a workflow either directly using `add_nodes` or using the `connect` function. Names have many internal uses. They determine the name of the directory in which the workflow/node is run and the outputs are stored. .. testcode:: realigner = pe.Node(interface=spm.Realign(), name='RealignSPM') Now this output will be stored in a directory called *RealignSPM*. Proper naming of your nodes can be advantageous from the perspective that it provides a semantic descriptor aligned with your thought process. This name parameter is also used to refer to nodes in embedded workflows. iterables --------- This can only be set for Node and MapNode. This is syntactic sugar for running a subgraph with the Node/MapNode at its root in a ``for`` loop. For example, consider an fMRI preprocessing pipeline that you would like to run for all your subjects. You can define a workflow and then execute it for every single subject inside a ``for`` loop. Consider the simplistic example below, where startnode is a node belonging to workflow 'mywork.' .. testcode:: for s in subjects: startnode.inputs.subject_id = s mywork.run() The pipeline engine provides a convenience function that simplifies this: .. testcode:: startnode.iterables = ('subject_id', subjects) mywork.run() This will achieve the same exact behavior as the for loop above. The workflow graph is: .. image:: images/proc2subj.png :width: 650 px Now consider the situation in which you want the last node (typically smoothing) of your preprocessing pipeline to smooth using two different kernels (0 mm and 6 mm FWHM). Again the common approach would be: .. testcode:: for s in subjects: startnode.inputs.subject_id = s uptosmoothingworkflow.run() smoothnode.inputs.infile = lastnode.output.outfile for fwhm in [0, 6]: smoothnode.inputs.fwhm = fwhm remainingworkflow.run() Instead of having multiple ``for`` loops at various stages, you can set up another set of iterables for the smoothnode. .. testcode:: startnode.iterables = ('subject_id', subjects) smoothnode.iterables = ('fwhm', [0, 6]) mywork.run() This will run the preprocessing workflow for two different smoothing kernels over all subjects. .. image:: images/proc2subj2fwhm.png :width: 650 px Thus setting iterables has a multiplicative effect. In the above examples there is a separate, distinct specifymodel node that's executed for each combination of subject and smoothing. iterfield --------- This is a mandatory keyword arg for MapNode. This enables running the underlying interface over a set of inputs and is particularly useful when the interface can only operate on a single input. For example, the :class:`nipype.interfaces.fsl.BET` will operate on only one (3d or 4d) NIfTI file. But wrapping BET in a MapNode can execute it over a list of files: .. testcode:: better = pe.MapNode(interface=fsl.Bet(), name='stripper', iterfield=['in_file']) better.inputs.in_file = ['file1.nii','file2.nii'] better.run() This will create a directory called ``stripper`` and inside it two subdirectories called ``in_file_0`` and ``in_file_1``. The output of running bet separately on each of those files will be stored in those two subdirectories. This can be extended to run it on pairwise inputs. For example, .. testcode:: transform = pe.MapNode(interface=fs.ApplyVolTransform(), name='warpvol', iterfield=['source_file', 'reg_file']) transform.inputs.source_file = ['file1.nii','file2.nii'] transform.inputs.reg_file = ['file1.reg','file2.reg'] transform.run() The above will be equivalent to running transform by taking corresponding items from each of the two fields in iterfield. The subdirectories get always named with respect to the first iterfield. overwrite --------- The overwrite keyword arg forces a node to be rerun. The `clone` function -------------------- The `clone` function can be used to create a copy of a workflow. No references to the original workflow are retained. As such the clone function requires a name keyword arg that specifies a new name for the duplicate workflow. .. include:: ../links_names.txt nipype-0.11.0/doc/users/tutorial_103.rst000066400000000000000000000072511257611314500177750ustar00rootroot00000000000000.. _tutorial_103: ============ Pipeline 103 ============ Modifying inputs to pipeline nodes ================================== Two nodes can be connected as shown below. .. testcode:: workflow.connect(realigner, 'realigned_files', smoother, 'infile') The connection mechanism allows for a function to be evaluated on the output field ('realigned files') of the source node (realigner) and have its result be sent to the input field ('infile') of the destination node (smoother). .. testcode:: def reverse_order(inlist): inlist.reverse() return inlist workflow.connect(realigner, ('realigned_files', reverse_order), smoother, 'infile') This can be extended to provide additional arguments to the function. For example: .. testcode:: def reorder(inlist, order): return [inlist[item] for item in order] workflow.connect(realigner, ('realigned_files', reorder, [2, 3, 0, 1]), smoother, 'infile') In this example, we assume the realigned_files produces a list of 4 files. We can reorder these files in a particular order using the modifier. Since such modifications are not tracked, they should be used with extreme care and only in cases where absolutely necessary. Often, one may find that it is better to insert a node rather than a function. Distributed computation ======================= The pipeline engine has built-in support for distributed computation on clusters. This can be achieved via plugin-modules for Python_ multiprocessing or the IPython_ distributed computing interface or SGE/PBS/Condor, provided the user sets up a workflow on a shared filesystem. These modules can take arguments that specify additional distribution engine parameters. For IPython_ the environment needs to be configured for distributed operation. Details are available at :ref:`plugins`. The default behavior is to run in series using the Linear plugin. .. testcode:: workflow.run() In some cases it may be advantageous to run the workflow in series locally (e.g., debugging, small-short pipelines, large memory only interfaces, relocating working directory/updating hashes). Debugging ========= When a crash happens while running a pipeline, a crashdump is stored in the pipeline's working directory unless the config option 'crashdumpdir' has been set (see :ref:config_options). The crashdump is a compressed numpy file that stores a dictionary containing three fields: 1. node - the node that failed 2. execgraph - the graph that the node came from 3. traceback - from local or remote session for the failure. We keep extending the information contained in the file and making it easier to troubleshoot the failures. However, in the meantime the following can help to recover information related to the failure. in IPython_ do (``%pdb`` in IPython_ is similar to ``dbstop`` if error in Matlab): .. testcode:: from nipype.utils.filemanip import loadflat crashinfo = loadflat('crashdump....npz') %pdb crashinfo['node'].run() # re-creates the crash pdb> up #typically, but not necessarily the crash is one stack frame up pdb> inspect variables pdb>quit Relocation of workdir ===================== In some circumstances, one might decide to move their entire working directory to a new location. It would be convenient to rerun only necessary components of the pipeline, instead of running all the nodes all over again. It is possible to do that with the :func:`~nipype.pipeline.engine.Pipeline.updatehash` function. .. testcode:: workflow.run(updatehash=True) This will execute the workflow and update all the hash values that were stored without actually running any of the interfaces. .. include:: ../links_names.txt nipype-0.11.0/doc/users/vagrant.rst000066400000000000000000000031321257611314500172030ustar00rootroot00000000000000.. _debug: ====================== Running Nipype in a VM ====================== .. tip:: Creating the Vagrant VM as described below requires an active internet connection. Container technologies (Vagrant_, Docker_) allow creating and manipulating lightweight virtual environments. The Nipype_ source now contains a Vagrantfile to launch a Vagrant_ VM. Requirements: * Vagrant_ * Virtualbox_ After you have installed Vagrant and Virtualbox, you simply need to download the latest Nipype source and unzip/tar/compress it. Go into your terminal and switch to the nipype source directory. Make sure the Vagrantfile is in the directory. Now you can execute:: vagrant up This will launch and provision the virtual machine. The default virtual machine is built using Ubuntu Precise 64, linked to the NeuroDebian_ source repo and contains a 2 node Grid Engine for cluster execution. The machine has a default IP address of `192.168.100.20` . From the vagrant startup directory you can log into the machine using:: vagrant ssh Now you can install your favorite software using:: sudo apt-get install fsl afni Also note that the directory in which you call `vagrant up` will be mounted under `/vagrant` inside the virtual machine. You can also copy the Vagrantfile or modify it in order to mount a different directory/directories. Please read through Vagrant_ documentation on other features. The python environment is built using a `miniconda `_ distribution. Hence `conda` can be used to do your python package management inside the VM. .. include:: ../links_names.txt nipype-0.11.0/doc/version.rst000066400000000000000000000001061257611314500160630ustar00rootroot00000000000000.. _version: .. htmlonly:: :Release: |version| :Date: |today| nipype-0.11.0/examples/000077500000000000000000000000001257611314500147205ustar00rootroot00000000000000nipype-0.11.0/examples/README000066400000000000000000000002621257611314500156000ustar00rootroot00000000000000A dataset for use with these scripts can be downloaded from the nipype website. At the time of writing, it's at: http://nipy.sourceforge.net/nipype/users/pipeline_tutorial.html nipype-0.11.0/examples/dmri_camino_dti.py000077500000000000000000000263421257611314500204250ustar00rootroot00000000000000#!/usr/bin/env python """ ================= dMRI: Camino, DTI ================= Introduction ============ This script, camino_dti_tutorial.py, demonstrates the ability to perform basic diffusion analysis in a Nipype pipeline:: python dmri_camino_dti.py We perform this analysis using the FSL course data, which can be acquired from here: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz Import necessary modules from nipype. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.camino as camino import nipype.interfaces.fsl as fsl import nipype.interfaces.camino2trackvis as cam2trk import nipype.algorithms.misc as misc import os # system functions """ We use the following functions to scrape the voxel and data dimensions of the input images. This allows the pipeline to be flexible enough to accept and process images of varying size. The SPM Face tutorial (fmri_spm_face.py) also implements this inferral of voxel size from the data. """ def get_vox_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() voxdims = hdr.get_zooms() return [float(voxdims[0]), float(voxdims[1]), float(voxdims[2])] def get_data_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() datadims = hdr.get_data_shape() return [int(datadims[0]), int(datadims[1]), int(datadims[2])] def get_affine(volume): import nibabel as nb nii = nb.load(volume) return nii.get_affine() subject_list = ['subj1'] fsl.FSLCommand.set_default_output_type('NIFTI') """ Map field names to individual subject runs """ info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.engine.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" # This needs to point to the fdt folder you can find after extracting # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz datasource.inputs.base_directory = os.path.abspath('fsl_course_data/fdt/') datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ An inputnode is used to pass the data obtained by the data grabber to the actual processing functions """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["dwi", "bvecs", "bvals"]), name="inputnode") """ Setup for Diffusion Tensor Computation -------------------------------------- In this section we create the nodes necessary for diffusion analysis. First, the diffusion image is converted to voxel order. """ image2voxel = pe.Node(interface=camino.Image2Voxel(), name="image2voxel") fsl2scheme = pe.Node(interface=camino.FSL2Scheme(), name="fsl2scheme") fsl2scheme.inputs.usegradmod = True """ Second, diffusion tensors are fit to the voxel-order data. """ dtifit = pe.Node(interface=camino.DTIFit(),name='dtifit') """ Next, a lookup table is generated from the schemefile and the signal-to-noise ratio (SNR) of the unweighted (q=0) data. """ dtlutgen = pe.Node(interface=camino.DTLUTGen(), name="dtlutgen") dtlutgen.inputs.snr = 16.0 dtlutgen.inputs.inversion = 1 """ In this tutorial we implement probabilistic tractography using the PICo algorithm. PICo tractography requires an estimate of the fibre direction and a model of its uncertainty in each voxel; this is produced using the following node. """ picopdfs = pe.Node(interface=camino.PicoPDFs(), name="picopdfs") picopdfs.inputs.inputmodel = 'dt' """ An FSL BET node creates a brain mask is generated from the diffusion image for seeding the PICo tractography. """ bet = pe.Node(interface=fsl.BET(), name="bet") bet.inputs.mask = True """ Finally, tractography is performed. First DT streamline tractography. """ trackdt = pe.Node(interface=camino.TrackDT(), name="trackdt") """ Now camino's Probablistic Index of connectivity algorithm. In this tutorial, we will use only 1 iteration for time-saving purposes. """ trackpico = pe.Node(interface=camino.TrackPICo(), name="trackpico") trackpico.inputs.iterations = 1 """ Currently, the best program for visualizing tracts is TrackVis. For this reason, a node is included to convert the raw tract data to .trk format. Solely for testing purposes, another node is added to perform the reverse. """ cam2trk_dt = pe.Node(interface=cam2trk.Camino2Trackvis(), name="cam2trk_dt") cam2trk_dt.inputs.min_length = 30 cam2trk_dt.inputs.voxel_order = 'LAS' cam2trk_pico = pe.Node(interface=cam2trk.Camino2Trackvis(), name="cam2trk_pico") cam2trk_pico.inputs.min_length = 30 cam2trk_pico.inputs.voxel_order = 'LAS' trk2camino = pe.Node(interface=cam2trk.Trackvis2Camino(), name="trk2camino") """ Tracts can also be converted to VTK and OOGL formats, for use in programs such as GeomView and Paraview, using the following two nodes. For VTK use VtkStreamlines. """ procstreamlines = pe.Node(interface=camino.ProcStreamlines(), name="procstreamlines") procstreamlines.inputs.outputtracts = 'oogl' """ We can also produce a variety of scalar values from our fitted tensors. The following nodes generate the fractional anisotropy and diffusivity trace maps and their associated headers. """ fa = pe.Node(interface=camino.ComputeFractionalAnisotropy(),name='fa') trace = pe.Node(interface=camino.ComputeTensorTrace(),name='trace') dteig = pe.Node(interface=camino.ComputeEigensystem(), name='dteig') analyzeheader_fa = pe.Node(interface= camino.AnalyzeHeader(), name = "analyzeheader_fa") analyzeheader_fa.inputs.datatype = "double" analyzeheader_trace = analyzeheader_fa.clone('analyzeheader_trace') fa2nii = pe.Node(interface=misc.CreateNifti(),name='fa2nii') trace2nii = fa2nii.clone("trace2nii") """ Since we have now created all our nodes, we can now define our workflow and start making connections. """ tractography = pe.Workflow(name='tractography') tractography.connect([(inputnode, bet,[("dwi","in_file")])]) """ File format conversion """ tractography.connect([(inputnode, image2voxel, [("dwi", "in_file")]), (inputnode, fsl2scheme, [("bvecs", "bvec_file"), ("bvals", "bval_file")]) ]) """ Tensor fitting """ tractography.connect([(image2voxel, dtifit,[['voxel_order','in_file']]), (fsl2scheme, dtifit,[['scheme','scheme_file']]) ]) """ Workflow for applying DT streamline tractogpahy """ tractography.connect([(bet, trackdt,[("mask_file","seed_file")])]) tractography.connect([(dtifit, trackdt,[("tensor_fitted","in_file")])]) """ Workflow for applying PICo """ tractography.connect([(bet, trackpico,[("mask_file","seed_file")])]) tractography.connect([(fsl2scheme, dtlutgen,[("scheme","scheme_file")])]) tractography.connect([(dtlutgen, picopdfs,[("dtLUT","luts")])]) tractography.connect([(dtifit, picopdfs,[("tensor_fitted","in_file")])]) tractography.connect([(picopdfs, trackpico,[("pdfs","in_file")])]) # ProcStreamlines might throw memory errors - comment this line out in such case tractography.connect([(trackdt, procstreamlines,[("tracked","in_file")])]) """ Connecting the Fractional Anisotropy and Trace nodes is simple, as they obtain their input from the tensor fitting. This is also where our voxel- and data-grabbing functions come in. We pass these functions, along with the original DWI image from the input node, to the header-generating nodes. This ensures that the files will be correct and readable. """ tractography.connect([(dtifit, fa,[("tensor_fitted","in_file")])]) tractography.connect([(fa, analyzeheader_fa,[("fa","in_file")])]) tractography.connect([(inputnode, analyzeheader_fa,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(fa, fa2nii,[('fa','data_file')])]) tractography.connect([(inputnode, fa2nii,[(('dwi', get_affine), 'affine')])]) tractography.connect([(analyzeheader_fa, fa2nii,[('header', 'header_file')])]) tractography.connect([(dtifit, trace,[("tensor_fitted","in_file")])]) tractography.connect([(trace, analyzeheader_trace,[("trace","in_file")])]) tractography.connect([(inputnode, analyzeheader_trace,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(trace, trace2nii,[('trace','data_file')])]) tractography.connect([(inputnode, trace2nii,[(('dwi', get_affine), 'affine')])]) tractography.connect([(analyzeheader_trace, trace2nii,[('header', 'header_file')])]) tractography.connect([(dtifit, dteig,[("tensor_fitted","in_file")])]) tractography.connect([(trackpico, cam2trk_pico, [('tracked','in_file')])]) tractography.connect([(trackdt, cam2trk_dt, [('tracked','in_file')])]) tractography.connect([(inputnode, cam2trk_pico,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(inputnode, cam2trk_dt,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) """ Finally, we create another higher-level workflow to connect our tractography workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial can is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ workflow = pe.Workflow(name="workflow") workflow.base_dir = os.path.abspath('camino_dti_tutorial') workflow.connect([(infosource,datasource,[('subject_id', 'subject_id')]), (datasource,tractography,[('dwi','inputnode.dwi'), ('bvals','inputnode.bvals'), ('bvecs','inputnode.bvecs') ]) ]) """ The following functions run the whole workflow and produce a .dot and .png graph of the processing pipeline. """ if __name__ == '__main__': workflow.run() workflow.write_graph() """ You can choose the format of the experted graph with the ``format`` option. For example ``workflow.write_graph(format='eps')`` """ nipype-0.11.0/examples/dmri_connectivity.py000077500000000000000000000646701257611314500210430ustar00rootroot00000000000000#!/usr/bin/env python """ ============================================= dMRI: Connectivity - Camino, CMTK, FreeSurfer ============================================= Introduction ============ This script, connectivity_tutorial.py, demonstrates the ability to perform connectivity mapping using Nipype for pipelining, Freesurfer for Reconstruction / Parcellation, Camino for tensor-fitting and tractography, and the Connectome Mapping Toolkit (CMTK) for connectivity analysis:: python connectivity_tutorial.py We perform this analysis using the FSL course data, which can be acquired from here: * http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz This pipeline also requires the Freesurfer directory for 'subj1' from the FSL course data. To save time, this data can be downloaded from here: * http://dl.dropbox.com/u/315714/subj1.zip?dl=1 A data package containing the outputs of this pipeline can be obtained from here: * http://db.tt/1vx4vLeP Along with `Camino `_, `Camino-Trackvis `_, `FSL `_, and `Freesurfer `_, you must also have the Connectome File Format library installed as well as the Connectome Mapper. These are written by Stephan Gerhard and can be obtained from: http://www.cmtk.org/ Or on github at: CFFlib: https://github.com/LTS5/cfflib CMP: https://github.com/LTS5/cmp Output data can be visualized in the ConnectomeViewer ConnectomeViewer: https://github.com/LTS5/connectomeviewer First, we import the necessary modules from nipype. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.camino as camino import nipype.interfaces.fsl as fsl import nipype.interfaces.camino2trackvis as cam2trk import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.cmtk as cmtk import nipype.algorithms.misc as misc import inspect import os.path as op # system functions import cmp # connectome mapper """ We define the following functions to scrape the voxel and data dimensions of the input images. This allows the pipeline to be flexible enough to accept and process images of varying size. The SPM Face tutorial (fmri_spm_face.py) also implements this inferral of voxel size from the data. We also define functions to select the proper parcellation/segregation file from Freesurfer's output for each subject. For the mapping in this tutorial, we use the aparc+seg.mgz file. While it is possible to change this to use the regions defined in aparc.a2009s+aseg.mgz, one would also have to write/obtain a network resolution map defining the nodes based on those regions. """ def get_vox_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() voxdims = hdr.get_zooms() return [float(voxdims[0]), float(voxdims[1]), float(voxdims[2])] def get_data_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() datadims = hdr.get_data_shape() return [int(datadims[0]), int(datadims[1]), int(datadims[2])] def get_affine(volume): import nibabel as nb nii = nb.load(volume) return nii.get_affine() def select_aparc(list_of_files): for in_file in list_of_files: if 'aparc+aseg.mgz' in in_file: idx = list_of_files.index(in_file) return list_of_files[idx] def select_aparc_annot(list_of_files): for in_file in list_of_files: if '.aparc.annot' in in_file: idx = list_of_files.index(in_file) return list_of_files[idx] """ These need to point to the main Freesurfer directory as well as the freesurfer subjects directory. No assumptions are made about where the directory of subjects is placed. Recon-all must have been run on subj1 from the FSL course data. """ fs_dir = op.abspath('/usr/local/freesurfer') subjects_dir = op.abspath(op.join(op.curdir,'./subjects')) fsl.FSLCommand.set_default_output_type('NIFTI') """ This needs to point to the fdt folder you can find after extracting http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz """ data_dir = op.abspath('fsl_course_data/fdt/') fs.FSCommand.set_default_subjects_dir(subjects_dir) subject_list = ['subj1'] """ An infosource node is used to loop through the subject list and define the input files. For our purposes, these are the diffusion-weighted MR image, b vectors, and b values. The info dictionary is used to provide a template of the naming of these files. For instance, the 4D nifti diffusion image is stored in the FSL course data as data.nii.gz. """ infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', subject_list) info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) """ A datasource node is used to perform the actual data grabbing. Templates for the associated images are used to obtain the correct images. The data are assumed to lie in data_dir/subject_id/. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" datasource.inputs.base_directory = data_dir datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.base_directory = data_dir datasource.inputs.sort_filelist = True """ FreeSurferSource nodes are used to retrieve a number of image files that were automatically generated by the recon-all process. Here we use three of these nodes, two of which are defined to return files for solely the left and right hemispheres. """ FreeSurferSource = pe.Node(interface=nio.FreeSurferSource(), name='fssource') FreeSurferSource.inputs.subjects_dir = subjects_dir FreeSurferSourceLH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceLH') FreeSurferSourceLH.inputs.subjects_dir = subjects_dir FreeSurferSourceLH.inputs.hemi = 'lh' FreeSurferSourceRH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceRH') FreeSurferSourceRH.inputs.subjects_dir = subjects_dir FreeSurferSourceRH.inputs.hemi = 'rh' """ Since the b values and b vectors come from the FSL course, we must convert it to a scheme file for use in Camino. """ fsl2scheme = pe.Node(interface=camino.FSL2Scheme(), name="fsl2scheme") fsl2scheme.inputs.usegradmod = True """ FSL's Brain Extraction tool is used to create a mask from the b0 image """ b0Strip = pe.Node(interface=fsl.BET(mask = True), name = 'bet_b0') """ FSL's FLIRT function is used to coregister the b0 mask and the structural image. A convert_xfm node is then used to obtain the inverse of the transformation matrix. FLIRT is used once again to apply the inverse transformation to the parcellated brain image. """ coregister = pe.Node(interface=fsl.FLIRT(dof=6), name = 'coregister') coregister.inputs.cost = ('corratio') convertxfm = pe.Node(interface=fsl.ConvertXFM(), name = 'convertxfm') convertxfm.inputs.invert_xfm = True inverse = pe.Node(interface=fsl.FLIRT(), name = 'inverse') inverse.inputs.interp = ('nearestneighbour') inverse_AparcAseg = pe.Node(interface=fsl.FLIRT(), name = 'inverse_AparcAseg') inverse_AparcAseg.inputs.interp = ('nearestneighbour') """ A number of conversion operations are required to obtain NIFTI files from the FreesurferSource for each subject. Nodes are used to convert the following: * Original structural image to NIFTI * Parcellated white matter image to NIFTI * Parcellated whole-brain image to NIFTI * Pial, white, inflated, and spherical surfaces for both the left and right hemispheres are converted to GIFTI for visualization in ConnectomeViewer * Parcellated annotation files for the left and right hemispheres are also converted to GIFTI """ mri_convert_Brain = pe.Node(interface=fs.MRIConvert(), name='mri_convert_Brain') mri_convert_Brain.inputs.out_type = 'nii' mri_convert_WMParc = mri_convert_Brain.clone('mri_convert_WMParc') mri_convert_AparcAseg = mri_convert_Brain.clone('mri_convert_AparcAseg') mris_convertLH = pe.Node(interface=fs.MRIsConvert(), name='mris_convertLH') mris_convertLH.inputs.out_datatype = 'gii' mris_convertRH = mris_convertLH.clone('mris_convertRH') mris_convertRHwhite = mris_convertLH.clone('mris_convertRHwhite') mris_convertLHwhite = mris_convertLH.clone('mris_convertLHwhite') mris_convertRHinflated = mris_convertLH.clone('mris_convertRHinflated') mris_convertLHinflated = mris_convertLH.clone('mris_convertLHinflated') mris_convertRHsphere = mris_convertLH.clone('mris_convertRHsphere') mris_convertLHsphere = mris_convertLH.clone('mris_convertLHsphere') mris_convertLHlabels = mris_convertLH.clone('mris_convertLHlabels') mris_convertRHlabels = mris_convertLH.clone('mris_convertRHlabels') """ An inputnode is used to pass the data obtained by the data grabber to the actual processing functions """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["dwi", "bvecs", "bvals", "subject_id"]), name="inputnode") """ In this section we create the nodes necessary for diffusion analysis. First, the diffusion image is converted to voxel order, since this is the format in which Camino does its processing. """ image2voxel = pe.Node(interface=camino.Image2Voxel(), name="image2voxel") """ Second, diffusion tensors are fit to the voxel-order data. If desired, these tensors can be converted to a Nifti tensor image using the DT2NIfTI interface. """ dtifit = pe.Node(interface=camino.DTIFit(),name='dtifit') """ Next, a lookup table is generated from the schemefile and the signal-to-noise ratio (SNR) of the unweighted (q=0) data. """ dtlutgen = pe.Node(interface=camino.DTLUTGen(), name="dtlutgen") dtlutgen.inputs.snr = 16.0 dtlutgen.inputs.inversion = 1 """ In this tutorial we implement probabilistic tractography using the PICo algorithm. PICo tractography requires an estimate of the fibre direction and a model of its uncertainty in each voxel; this probabilitiy distribution map is produced using the following node. """ picopdfs = pe.Node(interface=camino.PicoPDFs(), name="picopdfs") picopdfs.inputs.inputmodel = 'dt' """ Finally, tractography is performed. In this tutorial, we will use only one iteration for time-saving purposes. It is important to note that we use the TrackPICo interface here. This interface now expects the files required for PICo tracking (i.e. the output from picopdfs). Similar interfaces exist for alternative types of tracking, such as Bayesian tracking with Dirac priors (TrackBayesDirac). """ track = pe.Node(interface=camino.TrackPICo(), name="track") track.inputs.iterations = 1 """ Currently, the best program for visualizing tracts is TrackVis. For this reason, a node is included to convert the raw tract data to .trk format. Solely for testing purposes, another node is added to perform the reverse. """ camino2trackvis = pe.Node(interface=cam2trk.Camino2Trackvis(), name="camino2trk") camino2trackvis.inputs.min_length = 30 camino2trackvis.inputs.voxel_order = 'LAS' trk2camino = pe.Node(interface=cam2trk.Trackvis2Camino(), name="trk2camino") """ Tracts can also be converted to VTK and OOGL formats, for use in programs such as GeomView and Paraview, using the following two nodes. """ vtkstreamlines = pe.Node(interface=camino.VtkStreamlines(), name="vtkstreamlines") procstreamlines = pe.Node(interface=camino.ProcStreamlines(), name="procstreamlines") procstreamlines.inputs.outputtracts = 'oogl' """ We can easily produce a variety of scalar values from our fitted tensors. The following nodes generate the fractional anisotropy and diffusivity trace maps and their associated headers, and then merge them back into a single .nii file. """ fa = pe.Node(interface=camino.ComputeFractionalAnisotropy(),name='fa') trace = pe.Node(interface=camino.ComputeTensorTrace(),name='trace') dteig = pe.Node(interface=camino.ComputeEigensystem(), name='dteig') analyzeheader_fa = pe.Node(interface=camino.AnalyzeHeader(),name='analyzeheader_fa') analyzeheader_fa.inputs.datatype = 'double' analyzeheader_trace = pe.Node(interface=camino.AnalyzeHeader(),name='analyzeheader_trace') analyzeheader_trace.inputs.datatype = 'double' fa2nii = pe.Node(interface=misc.CreateNifti(),name='fa2nii') trace2nii = fa2nii.clone("trace2nii") """ This section adds the Connectome Mapping Toolkit (CMTK) nodes. These interfaces are fairly experimental and may not function properly. In order to perform connectivity mapping using CMTK, the parcellated structural data is rewritten using the indices and parcellation scheme from the connectome mapper (CMP). This process has been written into the ROIGen interface, which will output a remapped aparc+aseg image as well as a dictionary of label information (i.e. name, display colours) pertaining to the original and remapped regions. These label values are input from a user-input lookup table, if specified, and otherwise the default Freesurfer LUT (/freesurfer/FreeSurferColorLUT.txt). """ roigen = pe.Node(interface=cmtk.ROIGen(), name="ROIGen") cmp_config = cmp.configuration.PipelineConfiguration(parcellation_scheme = "NativeFreesurfer") cmp_config.parcellation_scheme = "NativeFreesurfer" roigen.inputs.LUT_file = cmp_config.get_freeview_lut("NativeFreesurfer")['freesurferaparc'] roigen_structspace = roigen.clone('ROIGen_structspace') """ The CreateMatrix interface takes in the remapped aparc+aseg image as well as the label dictionary and fiber tracts and outputs a number of different files. The most important of which is the connectivity network itself, which is stored as a 'gpickle' and can be loaded using Python's NetworkX package (see CreateMatrix docstring). Also outputted are various NumPy arrays containing detailed tract information, such as the start and endpoint regions, and statistics on the mean and standard deviation for the fiber length of each connection. These matrices can be used in the ConnectomeViewer to plot the specific tracts that connect between user-selected regions. """ creatematrix = pe.Node(interface=cmtk.CreateMatrix(), name="CreateMatrix") creatematrix.inputs.count_region_intersections = True createnodes = pe.Node(interface=cmtk.CreateNodes(), name="CreateNodes") createnodes.inputs.resolution_network_file = cmp_config.parcellation['freesurferaparc']['node_information_graphml'] """ Here we define the endpoint of this tutorial, which is the CFFConverter node, as well as a few nodes which use the Nipype Merge utility. These are useful for passing lists of the files we want packaged in our CFF file. """ CFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="CFFConverter") giftiSurfaces = pe.Node(interface=util.Merge(8), name="GiftiSurfaces") giftiLabels = pe.Node(interface=util.Merge(2), name="GiftiLabels") niftiVolumes = pe.Node(interface=util.Merge(3), name="NiftiVolumes") fiberDataArrays = pe.Node(interface=util.Merge(4), name="FiberDataArrays") gpickledNetworks = pe.Node(interface=util.Merge(1), name="NetworkFiles") """ Since we have now created all our nodes, we can define our workflow and start making connections. """ mapping = pe.Workflow(name='mapping') """ First, we connect the input node to the early conversion functions. FreeSurfer input nodes: """ mapping.connect([(inputnode, FreeSurferSource,[("subject_id","subject_id")])]) mapping.connect([(inputnode, FreeSurferSourceLH,[("subject_id","subject_id")])]) mapping.connect([(inputnode, FreeSurferSourceRH,[("subject_id","subject_id")])]) """ Required conversions for processing in Camino: """ mapping.connect([(inputnode, image2voxel, [("dwi", "in_file")]), (inputnode, fsl2scheme, [("bvecs", "bvec_file"), ("bvals", "bval_file")]), (image2voxel, dtifit,[['voxel_order','in_file']]), (fsl2scheme, dtifit,[['scheme','scheme_file']]) ]) """ Nifti conversions for the parcellated white matter image (used in Camino's conmap), and the subject's stripped brain image from Freesurfer: """ mapping.connect([(FreeSurferSource, mri_convert_WMParc,[('wmparc','in_file')])]) mapping.connect([(FreeSurferSource, mri_convert_Brain,[('brain','in_file')])]) """ Surface conversions to GIFTI (pial, white, inflated, and sphere for both hemispheres) """ mapping.connect([(FreeSurferSourceLH, mris_convertLH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHsphere,[('sphere','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHsphere,[('sphere','in_file')])]) """ The annotation files are converted using the pial surface as a map via the MRIsConvert interface. One of the functions defined earlier is used to select the lh.aparc.annot and rh.aparc.annot files specifically (rather than i.e. rh.aparc.a2009s.annot) from the output list given by the FreeSurferSource. """ mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) """ This section coregisters the diffusion-weighted and parcellated white-matter / whole brain images. At present the conmap node connection is left commented, as there have been recent changes in Camino code that have presented some users with errors. """ mapping.connect([(inputnode, b0Strip,[('dwi','in_file')])]) mapping.connect([(b0Strip, coregister,[('out_file','in_file')])]) mapping.connect([(mri_convert_Brain, coregister,[('out_file','reference')])]) mapping.connect([(coregister, convertxfm,[('out_matrix_file','in_file')])]) mapping.connect([(b0Strip, inverse,[('out_file','reference')])]) mapping.connect([(convertxfm, inverse,[('out_file','in_matrix_file')])]) mapping.connect([(mri_convert_WMParc, inverse,[('out_file','in_file')])]) """ The tractography pipeline consists of the following nodes. Further information about the tractography can be found in nipype/examples/dmri_camino_dti.py. """ mapping.connect([(b0Strip, track,[("mask_file","seed_file")])]) mapping.connect([(fsl2scheme, dtlutgen,[("scheme","scheme_file")])]) mapping.connect([(dtlutgen, picopdfs,[("dtLUT","luts")])]) mapping.connect([(dtifit, picopdfs,[("tensor_fitted","in_file")])]) mapping.connect([(picopdfs, track,[("pdfs","in_file")])]) """ Connecting the Fractional Anisotropy and Trace nodes is simple, as they obtain their input from the tensor fitting. This is also where our voxel- and data-grabbing functions come in. We pass these functions, along with the original DWI image from the input node, to the header-generating nodes. This ensures that the files will be correct and readable. """ mapping.connect([(dtifit, fa,[("tensor_fitted","in_file")])]) mapping.connect([(fa, analyzeheader_fa,[("fa","in_file")])]) mapping.connect([(inputnode, analyzeheader_fa,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) mapping.connect([(fa, fa2nii,[('fa','data_file')])]) mapping.connect([(inputnode, fa2nii,[(('dwi', get_affine), 'affine')])]) mapping.connect([(analyzeheader_fa, fa2nii,[('header', 'header_file')])]) mapping.connect([(dtifit, trace,[("tensor_fitted","in_file")])]) mapping.connect([(trace, analyzeheader_trace,[("trace","in_file")])]) mapping.connect([(inputnode, analyzeheader_trace,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) mapping.connect([(trace, trace2nii,[('trace','data_file')])]) mapping.connect([(inputnode, trace2nii,[(('dwi', get_affine), 'affine')])]) mapping.connect([(analyzeheader_trace, trace2nii,[('header', 'header_file')])]) mapping.connect([(dtifit, dteig,[("tensor_fitted","in_file")])]) """ The output tracts are converted to Trackvis format (and back). Here we also use the voxel- and data-grabbing functions defined at the beginning of the pipeline. """ mapping.connect([(track, camino2trackvis, [('tracked','in_file')]), (track, vtkstreamlines,[['tracked','in_file']]), (camino2trackvis, trk2camino,[['trackvis','in_file']]) ]) mapping.connect([(inputnode, camino2trackvis,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) """ Here the CMTK connectivity mapping nodes are connected. The original aparc+aseg image is converted to NIFTI, then registered to the diffusion image and delivered to the ROIGen node. The remapped parcellation, original tracts, and label file are then given to CreateMatrix. """ mapping.connect(createnodes, 'node_network', creatematrix, 'resolution_network_file') mapping.connect([(FreeSurferSource, mri_convert_AparcAseg, [(('aparc_aseg', select_aparc), 'in_file')])]) mapping.connect([(b0Strip, inverse_AparcAseg,[('out_file','reference')])]) mapping.connect([(convertxfm, inverse_AparcAseg,[('out_file','in_matrix_file')])]) mapping.connect([(mri_convert_AparcAseg, inverse_AparcAseg,[('out_file','in_file')])]) mapping.connect([(mri_convert_AparcAseg, roigen_structspace,[('out_file','aparc_aseg_file')])]) mapping.connect([(roigen_structspace, createnodes,[("roi_file","roi_file")])]) mapping.connect([(inverse_AparcAseg, roigen,[("out_file","aparc_aseg_file")])]) mapping.connect([(roigen, creatematrix,[("roi_file","roi_file")])]) mapping.connect([(camino2trackvis, creatematrix,[("trackvis","tract_file")])]) mapping.connect([(inputnode, creatematrix,[("subject_id","out_matrix_file")])]) mapping.connect([(inputnode, creatematrix,[("subject_id","out_matrix_mat_file")])]) """ The merge nodes defined earlier are used here to create lists of the files which are destined for the CFFConverter. """ mapping.connect([(creatematrix, gpickledNetworks,[("matrix_files","in1")])]) mapping.connect([(mris_convertLH, giftiSurfaces,[("converted","in1")])]) mapping.connect([(mris_convertRH, giftiSurfaces,[("converted","in2")])]) mapping.connect([(mris_convertLHwhite, giftiSurfaces,[("converted","in3")])]) mapping.connect([(mris_convertRHwhite, giftiSurfaces,[("converted","in4")])]) mapping.connect([(mris_convertLHinflated, giftiSurfaces,[("converted","in5")])]) mapping.connect([(mris_convertRHinflated, giftiSurfaces,[("converted","in6")])]) mapping.connect([(mris_convertLHsphere, giftiSurfaces,[("converted","in7")])]) mapping.connect([(mris_convertRHsphere, giftiSurfaces,[("converted","in8")])]) mapping.connect([(mris_convertLHlabels, giftiLabels,[("converted","in1")])]) mapping.connect([(mris_convertRHlabels, giftiLabels,[("converted","in2")])]) mapping.connect([(roigen, niftiVolumes,[("roi_file","in1")])]) mapping.connect([(inputnode, niftiVolumes,[("dwi","in2")])]) mapping.connect([(mri_convert_Brain, niftiVolumes,[("out_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file","in1")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file_mm","in2")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_length_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_label_file","in4")])]) """ This block actually connects the merged lists to the CFF converter. We pass the surfaces and volumes that are to be included, as well as the tracts and the network itself. The currently running pipeline (dmri_connectivity.py) is also scraped and included in the CFF file. This makes it easy for the user to examine the entire processing pathway used to generate the end product. """ CFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) mapping.connect([(giftiSurfaces, CFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, CFFConverter,[("out","gifti_labels")])]) mapping.connect([(gpickledNetworks, CFFConverter,[("out","gpickled_networks")])]) mapping.connect([(niftiVolumes, CFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, CFFConverter,[("out","data_files")])]) mapping.connect([(creatematrix, CFFConverter,[("filtered_tractographies","tract_files")])]) mapping.connect([(inputnode, CFFConverter,[("subject_id","title")])]) """ Finally, we create another higher-level workflow to connect our mapping workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial can is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ connectivity = pe.Workflow(name="connectivity") connectivity.base_dir = op.abspath('dmri_connectivity') connectivity.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,mapping,[('dwi','inputnode.dwi'), ('bvals','inputnode.bvals'), ('bvecs','inputnode.bvecs') ]), (infosource,mapping,[('subject_id','inputnode.subject_id')]) ]) """ The following functions run the whole workflow and produce graphs describing the processing pipeline. By default, write_graph outputs a .dot file and a .png image, but here we set it to output the image as a vector graphic, by passing the format='eps' argument. """ if __name__ == '__main__': connectivity.run() connectivity.write_graph(format='eps') """ The output CFF file of this pipeline can be loaded in the `Connectome Viewer `_. After loading the network into memory it can be examined in 3D or as a connectivity matrix using the default scripts produced by the Code Oracle. To compare networks, one must use the MergeCNetworks interface to merge two networks into a single CFF file. Statistics can then be run using the Network Brain Statistics (NBS) plugin Surfaces can also be loaded along with their labels from the aparc+aseg file. The tractography is included in the file so that region-to-region fibers can be individually plotted using the Code Oracle. """ nipype-0.11.0/examples/dmri_connectivity_advanced.py000077500000000000000000000636141257611314500226650ustar00rootroot00000000000000#!/usr/bin/env python """ ============================================= dMRI: Connectivity - MRtrix, CMTK, FreeSurfer ============================================= Introduction ============ This script, connectivity_tutorial_advanced.py, demonstrates the ability to perform connectivity mapping using Nipype for pipelining, Freesurfer for Reconstruction / Segmentation, MRtrix for spherical deconvolution and tractography, and the Connectome Mapping Toolkit (CMTK) for further parcellation and connectivity analysis:: python connectivity_tutorial_advanced.py We perform this analysis using the FSL course data, which can be acquired from here: * http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz This pipeline also requires the Freesurfer directory for 'subj1' from the FSL course data. To save time, this data can be downloaded from here: * http://dl.dropbox.com/u/315714/subj1.zip?dl=1 The result of this processing will be the connectome for subj1 as a Connectome File Format (CFF) File, using the Lausanne2008 parcellation scheme. A data package containing the outputs of this pipeline can be obtained from here: * http://db.tt/909Q3AC1 .. seealso:: connectivity_tutorial.py Original tutorial using Camino and the NativeFreesurfer Parcellation Scheme www.cmtk.org For more info about the parcellation scheme .. warning:: The ConnectomeMapper (https://github.com/LTS5/cmp or www.cmtk.org) must be installed for this tutorial to function! Packages and Data Setup ======================= Import necessary modules from nipype. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.mrtrix as mrtrix import nipype.algorithms.misc as misc import nipype.interfaces.cmtk as cmtk import nipype.interfaces.dipy as dipy import inspect import os, os.path as op # system functions from nipype.workflows.dmri.fsl.dti import create_eddy_correct_pipeline from nipype.workflows.dmri.camino.connectivity_mapping import select_aparc_annot from nipype.utils.misc import package_check import warnings from nipype.workflows.dmri.connectivity.nx import create_networkx_pipeline, create_cmats_to_csv_pipeline from nipype.workflows.smri.freesurfer import create_tessellation_flow try: package_check('cmp') except Exception, e: warnings.warn('cmp not installed') else: import cmp """ This needs to point to the freesurfer subjects directory (Recon-all must have been run on subj1 from the FSL course data) Alternatively, the reconstructed subject data can be downloaded from: * http://dl.dropbox.com/u/315714/subj1.zip """ subjects_dir = op.abspath(op.join(op.curdir,'./subjects')) fs.FSCommand.set_default_subjects_dir(subjects_dir) fsl.FSLCommand.set_default_output_type('NIFTI') fs_dir = os.environ['FREESURFER_HOME'] lookup_file = op.join(fs_dir,'FreeSurferColorLUT.txt') """ This needs to point to the fdt folder you can find after extracting * http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz """ data_dir = op.abspath(op.join(op.curdir,'exdata/')) subject_list = ['subj1'] """ Use infosource node to loop through the subject list and define the input files. For our purposes, these are the diffusion-weighted MR image, b vectors, and b values. """ infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', subject_list) info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) """ Use datasource node to perform the actual data grabbing. Templates for the associated images are used to obtain the correct images. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" datasource.inputs.base_directory = data_dir datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ The input node and Freesurfer sources declared here will be the main conduits for the raw data to the rest of the processing pipeline. """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["subject_id","dwi", "bvecs", "bvals", "subjects_dir"]), name="inputnode") inputnode.inputs.subjects_dir = subjects_dir FreeSurferSource = pe.Node(interface=nio.FreeSurferSource(), name='fssource') FreeSurferSourceLH = FreeSurferSource.clone('fssourceLH') FreeSurferSourceLH.inputs.hemi = 'lh' FreeSurferSourceRH = FreeSurferSource.clone('fssourceRH') FreeSurferSourceRH.inputs.hemi = 'rh' """ Creating the workflow's nodes ============================= Conversion nodes ---------------- A number of conversion operations are required to obtain NIFTI files from the FreesurferSource for each subject. Nodes are used to convert the following: * Original structural image to NIFTI * Pial, white, inflated, and spherical surfaces for both the left and right hemispheres are converted to GIFTI for visualization in ConnectomeViewer * Parcellated annotation files for the left and right hemispheres are also converted to GIFTI """ mri_convert_Brain = pe.Node(interface=fs.MRIConvert(), name='mri_convert_Brain') mri_convert_Brain.inputs.out_type = 'nii' mri_convert_ROI_scale500 = mri_convert_Brain.clone('mri_convert_ROI_scale500') mris_convertLH = pe.Node(interface=fs.MRIsConvert(), name='mris_convertLH') mris_convertLH.inputs.out_datatype = 'gii' mris_convertRH = mris_convertLH.clone('mris_convertRH') mris_convertRHwhite = mris_convertLH.clone('mris_convertRHwhite') mris_convertLHwhite = mris_convertLH.clone('mris_convertLHwhite') mris_convertRHinflated = mris_convertLH.clone('mris_convertRHinflated') mris_convertLHinflated = mris_convertLH.clone('mris_convertLHinflated') mris_convertRHsphere = mris_convertLH.clone('mris_convertRHsphere') mris_convertLHsphere = mris_convertLH.clone('mris_convertLHsphere') mris_convertLHlabels = mris_convertLH.clone('mris_convertLHlabels') mris_convertRHlabels = mris_convertLH.clone('mris_convertRHlabels') """ Diffusion processing nodes -------------------------- .. seealso:: dmri_mrtrix_dti.py Tutorial that focuses solely on the MRtrix diffusion processing http://www.brain.org.au/software/mrtrix/index.html MRtrix's online documentation b-values and b-vectors stored in FSL's format are converted into a single encoding file for MRTrix. """ fsl2mrtrix = pe.Node(interface=mrtrix.FSL2MRTrix(),name='fsl2mrtrix') """ Distortions induced by eddy currents are corrected prior to fitting the tensors. The first image is used as a reference for which to warp the others. """ eddycorrect = create_eddy_correct_pipeline(name='eddycorrect') eddycorrect.inputs.inputnode.ref_num = 1 """ Tensors are fitted to each voxel in the diffusion-weighted image and from these three maps are created: * Major eigenvector in each voxel * Apparent diffusion coefficient * Fractional anisotropy """ dwi2tensor = pe.Node(interface=mrtrix.DWI2Tensor(),name='dwi2tensor') tensor2vector = pe.Node(interface=mrtrix.Tensor2Vector(),name='tensor2vector') tensor2adc = pe.Node(interface=mrtrix.Tensor2ApparentDiffusion(),name='tensor2adc') tensor2fa = pe.Node(interface=mrtrix.Tensor2FractionalAnisotropy(),name='tensor2fa') MRconvert_fa = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert_fa') MRconvert_fa.inputs.extension = 'nii' """ These nodes are used to create a rough brain mask from the b0 image. The b0 image is extracted from the original diffusion-weighted image, put through a simple thresholding routine, and smoothed using a 3x3 median filter. """ MRconvert = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert') MRconvert.inputs.extract_at_axis = 3 MRconvert.inputs.extract_at_coordinate = [0] threshold_b0 = pe.Node(interface=mrtrix.Threshold(),name='threshold_b0') median3d = pe.Node(interface=mrtrix.MedianFilter3D(),name='median3d') """ The brain mask is also used to help identify single-fiber voxels. This is done by passing the brain mask through two erosion steps, multiplying the remaining mask with the fractional anisotropy map, and thresholding the result to obtain some highly anisotropic within-brain voxels. """ erode_mask_firstpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_firstpass') erode_mask_secondpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_secondpass') MRmultiply = pe.Node(interface=mrtrix.MRMultiply(),name='MRmultiply') MRmult_merge = pe.Node(interface=util.Merge(2), name='MRmultiply_merge') threshold_FA = pe.Node(interface=mrtrix.Threshold(),name='threshold_FA') threshold_FA.inputs.absolute_threshold_value = 0.7 """ For whole-brain tracking we also require a broad white-matter seed mask. This is created by generating a white matter mask, given a brainmask, and thresholding it at a reasonably high level. """ bet = pe.Node(interface=fsl.BET(mask = True), name = 'bet_b0') gen_WM_mask = pe.Node(interface=mrtrix.GenerateWhiteMatterMask(),name='gen_WM_mask') threshold_wmmask = pe.Node(interface=mrtrix.Threshold(),name='threshold_wmmask') threshold_wmmask.inputs.absolute_threshold_value = 0.4 """ The spherical deconvolution step depends on the estimate of the response function in the highly anisotropic voxels we obtained above. .. warning:: For damaged or pathological brains one should take care to lower the maximum harmonic order of these steps. """ estimateresponse = pe.Node(interface=mrtrix.EstimateResponseForSH(),name='estimateresponse') estimateresponse.inputs.maximum_harmonic_order = 6 csdeconv = pe.Node(interface=mrtrix.ConstrainedSphericalDeconvolution(),name='csdeconv') csdeconv.inputs.maximum_harmonic_order = 6 """ Finally, we track probabilistically using the orientation distribution functions obtained earlier. The tracts are then used to generate a tract-density image, and they are also converted to TrackVis format. """ probCSDstreamtrack = pe.Node(interface=mrtrix.ProbabilisticSphericallyDeconvolutedStreamlineTrack(),name='probCSDstreamtrack') probCSDstreamtrack.inputs.inputmodel = 'SD_PROB' probCSDstreamtrack.inputs.desired_number_of_tracks = 150000 tracks2prob = pe.Node(interface=mrtrix.Tracks2Prob(),name='tracks2prob') tracks2prob.inputs.colour = True MRconvert_tracks2prob = MRconvert_fa.clone(name='MRconvert_tracks2prob') tck2trk = pe.Node(interface=mrtrix.MRTrix2TrackVis(),name='tck2trk') trk2tdi = pe.Node(interface=dipy.TrackDensityMap(),name='trk2tdi') """ Structural segmentation nodes ----------------------------- The following node identifies the transformation between the diffusion-weighted image and the structural image. This transformation is then applied to the tracts so that they are in the same space as the regions of interest. """ coregister = pe.Node(interface=fsl.FLIRT(dof=6), name = 'coregister') coregister.inputs.cost = ('normmi') """ Parcellation is performed given the aparc+aseg image from Freesurfer. The CMTK Parcellation step subdivides these regions to return a higher-resolution parcellation scheme. The parcellation used here is entitled "scale500" and returns 1015 regions. """ parcellation_name = 'scale500' parcellate = pe.Node(interface=cmtk.Parcellate(), name="Parcellate") parcellate.inputs.parcellation_name = parcellation_name """ The CreateMatrix interface takes in the remapped aparc+aseg image as well as the label dictionary and fiber tracts and outputs a number of different files. The most important of which is the connectivity network itself, which is stored as a 'gpickle' and can be loaded using Python's NetworkX package (see CreateMatrix docstring). Also outputted are various NumPy arrays containing detailed tract information, such as the start and endpoint regions, and statistics on the mean and standard deviation for the fiber length of each connection. These matrices can be used in the ConnectomeViewer to plot the specific tracts that connect between user-selected regions. Here we choose the Lausanne2008 parcellation scheme, since we are incorporating the CMTK parcellation step. """ parcellation_name = 'scale500' cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" createnodes = pe.Node(interface=cmtk.CreateNodes(), name="CreateNodes") createnodes.inputs.resolution_network_file = cmp_config._get_lausanne_parcellation('Lausanne2008')[parcellation_name]['node_information_graphml'] creatematrix = pe.Node(interface=cmtk.CreateMatrix(), name="CreateMatrix") creatematrix.inputs.count_region_intersections = True """ Next we define the endpoint of this tutorial, which is the CFFConverter node, as well as a few nodes which use the Nipype Merge utility. These are useful for passing lists of the files we want packaged in our CFF file. The inspect.getfile command is used to package this script into the resulting CFF file, so that it is easy to look back at the processing parameters that were used. """ CFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="CFFConverter") CFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) giftiSurfaces = pe.Node(interface=util.Merge(9), name="GiftiSurfaces") giftiLabels = pe.Node(interface=util.Merge(2), name="GiftiLabels") niftiVolumes = pe.Node(interface=util.Merge(3), name="NiftiVolumes") fiberDataArrays = pe.Node(interface=util.Merge(4), name="FiberDataArrays") gpickledNetworks = pe.Node(interface=util.Merge(2), name="NetworkFiles") """ We also create a workflow to calculate several network metrics on our resulting file, and another CFF converter which will be used to package these networks into a single file. """ networkx = create_networkx_pipeline(name='networkx') cmats_to_csv = create_cmats_to_csv_pipeline(name='cmats_to_csv') NxStatsCFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="NxStatsCFFConverter") NxStatsCFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) tessflow = create_tessellation_flow(name='tessflow', out_format='gii') tessflow.inputs.inputspec.lookup_file = lookup_file """ Connecting the workflow ======================= Here we connect our processing pipeline. Connecting the inputs, FreeSurfer nodes, and conversions -------------------------------------------------------- """ mapping = pe.Workflow(name='mapping') """ First, we connect the input node to the FreeSurfer input nodes. """ mapping.connect([(inputnode, FreeSurferSource,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode, FreeSurferSource,[("subject_id","subject_id")])]) mapping.connect([(inputnode, FreeSurferSourceLH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode, FreeSurferSourceLH,[("subject_id","subject_id")])]) mapping.connect([(inputnode, FreeSurferSourceRH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode, FreeSurferSourceRH,[("subject_id","subject_id")])]) mapping.connect([(inputnode, tessflow,[("subjects_dir","inputspec.subjects_dir")])]) mapping.connect([(inputnode, tessflow,[("subject_id","inputspec.subject_id")])]) mapping.connect([(inputnode, parcellate,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode, parcellate,[("subject_id","subject_id")])]) mapping.connect([(parcellate, mri_convert_ROI_scale500,[('roi_file','in_file')])]) """ Nifti conversion for subject's stripped brain image from Freesurfer: """ mapping.connect([(FreeSurferSource, mri_convert_Brain,[('brain','in_file')])]) """ Surface conversions to GIFTI (pial, white, inflated, and sphere for both hemispheres) """ mapping.connect([(FreeSurferSourceLH, mris_convertLH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHsphere,[('sphere','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHsphere,[('sphere','in_file')])]) """ The annotation files are converted using the pial surface as a map via the MRIsConvert interface. One of the functions defined earlier is used to select the lh.aparc.annot and rh.aparc.annot files specifically (rather than e.g. rh.aparc.a2009s.annot) from the output list given by the FreeSurferSource. """ mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) """ Diffusion Processing -------------------- Now we connect the tensor computations: """ mapping.connect([(inputnode, fsl2mrtrix, [("bvecs", "bvec_file"), ("bvals", "bval_file")])]) mapping.connect([(inputnode, eddycorrect,[("dwi","inputnode.in_file")])]) mapping.connect([(eddycorrect, dwi2tensor,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(fsl2mrtrix, dwi2tensor,[("encoding_file","encoding_file")])]) mapping.connect([(dwi2tensor, tensor2vector,[['tensor','in_file']]), (dwi2tensor, tensor2adc,[['tensor','in_file']]), (dwi2tensor, tensor2fa,[['tensor','in_file']]), ]) mapping.connect([(tensor2fa, MRmult_merge,[("FA","in1")])]) mapping.connect([(tensor2fa, MRconvert_fa,[("FA","in_file")])]) """ This block creates the rough brain mask to be multiplied, mulitplies it with the fractional anisotropy image, and thresholds it to get the single-fiber voxels. """ mapping.connect([(eddycorrect, MRconvert,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(MRconvert, threshold_b0,[("converted","in_file")])]) mapping.connect([(threshold_b0, median3d,[("out_file","in_file")])]) mapping.connect([(median3d, erode_mask_firstpass,[("out_file","in_file")])]) mapping.connect([(erode_mask_firstpass, erode_mask_secondpass,[("out_file","in_file")])]) mapping.connect([(erode_mask_secondpass, MRmult_merge,[("out_file","in2")])]) mapping.connect([(MRmult_merge, MRmultiply,[("out","in_files")])]) mapping.connect([(MRmultiply, threshold_FA,[("out_file","in_file")])]) """ Here the thresholded white matter mask is created for seeding the tractography. """ mapping.connect([(eddycorrect, bet,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(eddycorrect, gen_WM_mask,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(bet, gen_WM_mask,[("mask_file","binary_mask")])]) mapping.connect([(fsl2mrtrix, gen_WM_mask,[("encoding_file","encoding_file")])]) mapping.connect([(gen_WM_mask, threshold_wmmask,[("WMprobabilitymap","in_file")])]) """ Next we estimate the fiber response distribution. """ mapping.connect([(eddycorrect, estimateresponse,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(fsl2mrtrix, estimateresponse,[("encoding_file","encoding_file")])]) mapping.connect([(threshold_FA, estimateresponse,[("out_file","mask_image")])]) """ Run constrained spherical deconvolution. """ mapping.connect([(eddycorrect, csdeconv,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(gen_WM_mask, csdeconv,[("WMprobabilitymap","mask_image")])]) mapping.connect([(estimateresponse, csdeconv,[("response","response_file")])]) mapping.connect([(fsl2mrtrix, csdeconv,[("encoding_file","encoding_file")])]) """ Connect the tractography and compute the tract density image. """ mapping.connect([(threshold_wmmask, probCSDstreamtrack,[("out_file","seed_file")])]) mapping.connect([(csdeconv, probCSDstreamtrack,[("spherical_harmonics_image","in_file")])]) mapping.connect([(probCSDstreamtrack, tracks2prob,[("tracked","in_file")])]) mapping.connect([(eddycorrect, tracks2prob,[("outputnode.eddy_corrected","template_file")])]) mapping.connect([(tracks2prob, MRconvert_tracks2prob,[("tract_image","in_file")])]) """ Structural Processing --------------------- First, we coregister the diffusion image to the structural image """ mapping.connect([(eddycorrect, coregister,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(mri_convert_Brain, coregister,[('out_file','reference')])]) """ The MRtrix-tracked fibers are converted to TrackVis format (with voxel and data dimensions grabbed from the DWI). The connectivity matrix is created with the transformed .trk fibers and the parcellation file. """ mapping.connect([(eddycorrect, tck2trk,[("outputnode.eddy_corrected","image_file")])]) mapping.connect([(mri_convert_Brain, tck2trk,[("out_file","registration_image_file")])]) mapping.connect([(coregister, tck2trk,[("out_matrix_file","matrix_file")])]) mapping.connect([(probCSDstreamtrack, tck2trk,[("tracked","in_file")])]) mapping.connect([(tck2trk, creatematrix,[("out_file","tract_file")])]) mapping.connect([(tck2trk, trk2tdi,[("out_file","in_file")])]) mapping.connect([(inputnode, creatematrix,[("subject_id","out_matrix_file")])]) mapping.connect([(inputnode, creatematrix,[("subject_id","out_matrix_mat_file")])]) mapping.connect([(parcellate, creatematrix,[("roi_file","roi_file")])]) mapping.connect([(parcellate, createnodes,[("roi_file","roi_file")])]) mapping.connect([(createnodes, creatematrix,[("node_network","resolution_network_file")])]) """ The merge nodes defined earlier are used here to create lists of the files which are destined for the CFFConverter. """ mapping.connect([(mris_convertLH, giftiSurfaces,[("converted","in1")])]) mapping.connect([(mris_convertRH, giftiSurfaces,[("converted","in2")])]) mapping.connect([(mris_convertLHwhite, giftiSurfaces,[("converted","in3")])]) mapping.connect([(mris_convertRHwhite, giftiSurfaces,[("converted","in4")])]) mapping.connect([(mris_convertLHinflated, giftiSurfaces,[("converted","in5")])]) mapping.connect([(mris_convertRHinflated, giftiSurfaces,[("converted","in6")])]) mapping.connect([(mris_convertLHsphere, giftiSurfaces,[("converted","in7")])]) mapping.connect([(mris_convertRHsphere, giftiSurfaces,[("converted","in8")])]) mapping.connect([(tessflow, giftiSurfaces,[("outputspec.meshes","in9")])]) mapping.connect([(mris_convertLHlabels, giftiLabels,[("converted","in1")])]) mapping.connect([(mris_convertRHlabels, giftiLabels,[("converted","in2")])]) mapping.connect([(parcellate, niftiVolumes,[("roi_file","in1")])]) mapping.connect([(eddycorrect, niftiVolumes,[("outputnode.eddy_corrected","in2")])]) mapping.connect([(mri_convert_Brain, niftiVolumes,[("out_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file","in1")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file_mm","in2")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_length_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_label_file","in4")])]) """ This block actually connects the merged lists to the CFF converter. We pass the surfaces and volumes that are to be included, as well as the tracts and the network itself. The currently running pipeline (dmri_connectivity_advanced.py) is also scraped and included in the CFF file. This makes it easy for the user to examine the entire processing pathway used to generate the end product. """ mapping.connect([(giftiSurfaces, CFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, CFFConverter,[("out","gifti_labels")])]) mapping.connect([(creatematrix, CFFConverter,[("matrix_files","gpickled_networks")])]) mapping.connect([(niftiVolumes, CFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, CFFConverter,[("out","data_files")])]) mapping.connect([(creatematrix, CFFConverter,[("filtered_tractographies","tract_files")])]) mapping.connect([(inputnode, CFFConverter,[("subject_id","title")])]) """ The graph theoretical metrics are computed using the networkx workflow and placed in another CFF file """ mapping.connect([(inputnode, networkx,[("subject_id","inputnode.extra_field")])]) mapping.connect([(creatematrix, networkx,[("intersection_matrix_file","inputnode.network_file")])]) mapping.connect([(networkx, NxStatsCFFConverter,[("outputnode.network_files","gpickled_networks")])]) mapping.connect([(giftiSurfaces, NxStatsCFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, NxStatsCFFConverter,[("out","gifti_labels")])]) mapping.connect([(niftiVolumes, NxStatsCFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, NxStatsCFFConverter,[("out","data_files")])]) mapping.connect([(inputnode, NxStatsCFFConverter,[("subject_id","title")])]) mapping.connect([(inputnode, cmats_to_csv,[("subject_id","inputnode.extra_field")])]) mapping.connect([(creatematrix, cmats_to_csv,[("matlab_matrix_files","inputnode.matlab_matrix_files")])]) """ Create a higher-level workflow ------------------------------ Finally, we create another higher-level workflow to connect our mapping workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ connectivity = pe.Workflow(name="connectivity") connectivity.base_dir = op.abspath('dmri_connectivity_advanced') connectivity.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,mapping,[('dwi','inputnode.dwi'), ('bvals','inputnode.bvals'), ('bvecs','inputnode.bvecs') ]), (infosource,mapping,[('subject_id','inputnode.subject_id')]) ]) """ The following functions run the whole workflow and produce a .dot and .png graph of the processing pipeline. """ if __name__ == '__main__': connectivity.run() connectivity.write_graph() nipype-0.11.0/examples/dmri_dtk_dti.py000077500000000000000000000153511257611314500177370ustar00rootroot00000000000000#!/usr/bin/env python """ ================================== dMRI: DTI - Diffusion Toolkit, FSL ================================== A pipeline example that uses several interfaces to perform analysis on diffusion weighted images using Diffusion Toolkit tools. This tutorial is based on the 2010 FSL course and uses data freely available at the FSL website at: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz More details can be found at http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/fdt/index.htm In order to run this tutorial you need to have Diffusion Toolkit and FSL tools installed and accessible from matlab/command line. Check by calling fslinfo and dtk from the command line. Tell python where to find the appropriate functions. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.diffusion_toolkit as dtk import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import os # system functions from nipype.workflows.dmri.fsl.dti import create_eddy_correct_pipeline """ Confirm package dependencies are installed. (This is only for the tutorial, rarely would you put this in your own code.) """ from nipype.utils.misc import package_check package_check('numpy', '1.3', 'tutorial1') package_check('scipy', '0.7', 'tutorial1') package_check('networkx', '1.0', 'tutorial1') package_check('IPython', '0.10', 'tutorial1') """ Setting up workflows -------------------- This is a generic workflow for DTI data analysis using the FSL Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``dwis1`` and ``dwis2``. Each subject directory contains each of the following files: bvec, bval, diffusion weighted data, a set of target masks, a seed file, and a transformation matrix. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``dwi`` or ``bvals``). These fields become the output fields of the ``datasource`` node in the pipeline. Specify the subject directories """ subject_list = ['subj1'] """ Map field names to individual subject runs """ info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.engine.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" # This needs to point to the fdt folder you can find after extracting # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz datasource.inputs.base_directory = os.path.abspath('fsl_course_data/fdt/') datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Setup for Diffusion Tensor Computation -------------------------------------- Here we will create a generic workflow for DTI computation """ computeTensor = pe.Workflow(name='computeTensor') """ extract the volume with b=0 (nodif_brain) """ fslroi = pe.Node(interface=fsl.ExtractROI(),name='fslroi') fslroi.inputs.t_min=0 fslroi.inputs.t_size=1 """ create a brain mask from the nodif_brain """ bet = pe.Node(interface=fsl.BET(),name='bet') bet.inputs.mask=True bet.inputs.frac=0.34 """ correct the diffusion weighted images for eddy_currents """ eddycorrect = create_eddy_correct_pipeline('eddycorrect') eddycorrect.inputs.inputnode.ref_num=0 """ compute the diffusion tensor in each voxel """ dtifit = pe.Node(interface=dtk.DTIRecon(),name='dtifit') """ connect all the nodes for this workflow """ computeTensor.connect([ (fslroi,bet,[('roi_file','in_file')]), (eddycorrect,dtifit,[('outputnode.eddy_corrected','DWI')]) ]) """ Setup for Tracktography ----------------------- Here we will create a workflow to enable deterministic tracktography """ tractography = pe.Workflow(name='tractography') dtk_tracker = pe.Node(interface=dtk.DTITracker(), name="dtk_tracker") dtk_tracker.inputs.invert_x = True smooth_trk = pe.Node(interface=dtk.SplineFilter(), name="smooth_trk") smooth_trk.inputs.step_length = 0.5 """ connect all the nodes for this workflow """ tractography.connect([ (dtk_tracker, smooth_trk, [('track_file', 'track_file')]) ]) """ Setup data storage area """ datasink = pe.Node(interface=nio.DataSink(),name='datasink') datasink.inputs.base_directory = os.path.abspath('dtiresults') def getstripdir(subject_id): return os.path.join(os.path.abspath('data/workingdir/dwiproc'),'_subject_id_%s' % subject_id) """ Setup the pipeline that combines the two workflows: tractography and computeTensor ---------------------------------------------------------------------------------- """ dwiproc = pe.Workflow(name="dwiproc") dwiproc.base_dir = os.path.abspath('dtk_dti_tutorial') dwiproc.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,computeTensor,[('dwi','fslroi.in_file'), ('bvals','dtifit.bvals'), ('bvecs','dtifit.bvecs'), ('dwi','eddycorrect.inputnode.in_file')]), (computeTensor,tractography,[('bet.mask_file','dtk_tracker.mask1_file'), ('dtifit.tensor','dtk_tracker.tensor_file') ]) ]) if __name__ == '__main__': dwiproc.run() dwiproc.write_graph() nipype-0.11.0/examples/dmri_dtk_odf.py000077500000000000000000000157111257611314500177270ustar00rootroot00000000000000#!/usr/bin/env python """ ==================================== dMRI: HARDI - Diffusion Toolkit, FSL ==================================== A pipeline example that uses several interfaces to perform analysis on diffusion weighted images using Diffusion Toolkit tools. This tutorial is based on the 2010 FSL course and uses data freely available at the FSL website at: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz More details can be found at http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/fdt/index.htm In order to run this tutorial you need to have Diffusion Toolkit and FSL tools installed and accessible from matlab/command line. Check by calling fslinfo and dtk from the command line. Tell python where to find the appropriate functions. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.diffusion_toolkit as dtk import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import os # system functions from nipype.workflows.dmri.fsl.dti import create_eddy_correct_pipeline """ Confirm package dependencies are installed. (This is only for the tutorial, rarely would you put this in your own code.) """ from nipype.utils.misc import package_check package_check('numpy', '1.3', 'tutorial1') package_check('scipy', '0.7', 'tutorial1') package_check('networkx', '1.0', 'tutorial1') package_check('IPython', '0.10', 'tutorial1') """ Setting up workflows -------------------- This is a generic workflow for DTI data analysis using the FSL Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``dwis1`` and ``dwis2``. Each subject directory contains each of the following files: bvec, bval, diffusion weighted data, a set of target masks, a seed file, and a transformation matrix. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``dwi`` or ``bvals``). These fields become the output fields of the ``datasource`` node in the pipeline. Specify the subject directories """ subject_list = ['siemens_hardi_test'] """ Map field names to individual subject runs """ info = dict(dwi=[['subject_id', 'siemens_hardi_test_data']], bvecs=[['subject_id','siemens_hardi_test_data.bvec']], bvals=[['subject_id','siemens_hardi_test_data.bval']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.engine.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" # This needs to point to the fdt folder you can find after extracting # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz datasource.inputs.base_directory = os.path.abspath('data') datasource.inputs.field_template = dict(dwi='%s/%s.nii') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Setup for ODF Computation -------------------------------------- Here we will create a generic workflow for ODF computation """ compute_ODF = pe.Workflow(name='compute_ODF') """ extract the volume with b=0 (nodif_brain) """ fslroi = pe.Node(interface=fsl.ExtractROI(),name='fslroi') fslroi.inputs.t_min=0 fslroi.inputs.t_size=1 """ create a brain mask from the nodif_brain """ bet = pe.Node(interface=fsl.BET(),name='bet') bet.inputs.mask=True bet.inputs.frac=0.34 """ correct the diffusion weighted images for eddy_currents """ eddycorrect = create_eddy_correct_pipeline('eddycorrect') eddycorrect.inputs.inputnode.ref_num=0 hardi_mat = pe.Node(interface=dtk.HARDIMat(),name='hardi_mat') odf_recon = pe.Node(interface=dtk.ODFRecon(),name='odf_recon') """ connect all the nodes for this workflow """ compute_ODF.connect([ (fslroi,bet,[('roi_file','in_file')]), (eddycorrect, odf_recon,[('outputnode.eddy_corrected','DWI')]), (eddycorrect, hardi_mat,[('outputnode.eddy_corrected','reference_file')]), (hardi_mat, odf_recon, [('out_file', 'matrix')]) ]) """ Setup for Tracktography ----------------------- Here we will create a workflow to enable deterministic tracktography """ tractography = pe.Workflow(name='tractography') odf_tracker = pe.Node(interface=dtk.ODFTracker(), name="odf_tracker") smooth_trk = pe.Node(interface=dtk.SplineFilter(), name="smooth_trk") smooth_trk.inputs.step_length = 1 """ connect all the nodes for this workflow """ tractography.connect([ (odf_tracker, smooth_trk, [('track_file', 'track_file')]) ]) """ Setup the pipeline that combines the two workflows: tractography and compute_ODF ---------------------------------------------------------------------------------- """ dwiproc = pe.Workflow(name="dwiproc") dwiproc.base_dir = os.path.abspath('dtk_odf_tutorial') dwiproc.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,compute_ODF,[('dwi','fslroi.in_file'), ('bvals','hardi_mat.bvals'), ('bvecs','hardi_mat.bvecs'), ('dwi','eddycorrect.inputnode.in_file')]), (compute_ODF,tractography,[('bet.mask_file','odf_tracker.mask1_file'), ('odf_recon.ODF','odf_tracker.ODF'), ('odf_recon.max','odf_tracker.max') ]) ]) dwiproc.inputs.compute_ODF.hardi_mat.oblique_correction = True dwiproc.inputs.compute_ODF.odf_recon.n_directions = 31 dwiproc.inputs.compute_ODF.odf_recon.n_b0 = 5 dwiproc.inputs.compute_ODF.odf_recon.n_output_directions = 181 if __name__ == '__main__': dwiproc.run() dwiproc.write_graph() nipype-0.11.0/examples/dmri_fsl_dti.py000077500000000000000000000224751257611314500177460ustar00rootroot00000000000000#!/usr/bin/env python """ ============== dMRI: DTI, FSL ============== A pipeline example that uses several interfaces to perform analysis on diffusion weighted images using FSL FDT tools. This tutorial is based on the 2010 FSL course and uses data freely available at the FSL website at: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz More details can be found at http://www.fmrib.ox.ac.uk/fslcourse/lectures/practicals/fdt/index.htm In order to run this tutorial you need to have fsl tools installed and accessible from matlab/command line. Check by calling fslinfo from the command line. Tell python where to find the appropriate functions. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import os # system functions from nipype.workflows.dmri.fsl.dti import create_eddy_correct_pipeline,\ create_bedpostx_pipeline """ Confirm package dependencies are installed. (This is only for the tutorial, rarely would you put this in your own code.) """ from nipype.utils.misc import package_check package_check('numpy', '1.3', 'tutorial1') package_check('scipy', '0.7', 'tutorial1') package_check('networkx', '1.0', 'tutorial1') package_check('IPython', '0.10', 'tutorial1') """ Setting up workflows -------------------- This is a generic workflow for DTI data analysis using the FSL Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``dwis1`` and ``dwis2``. Each subject directory contains each of the following files: bvec, bval, diffusion weighted data, a set of target masks, a seed file, and a transformation matrix. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``dwi`` or ``bvals``). These fields become the output fields of the ``datasource`` node in the pipeline. Specify the subject directories """ subject_list = ['subj1'] """ Map field names to individual subject runs """ info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']], seed_file = [['subject_id','MASK_average_thal_right']], target_masks = [['subject_id',['MASK_average_M1_right', 'MASK_average_S1_right', 'MASK_average_occipital_right', 'MASK_average_pfc_right', 'MASK_average_pmc_right', 'MASK_average_ppc_right', 'MASK_average_temporal_right']]]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """ Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.engine.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" # This needs to point to the fdt folder you can find after extracting # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz datasource.inputs.base_directory = os.path.abspath('fsl_course_data/fdt/') datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz', seed_file="%s.bedpostX/%s.nii.gz", target_masks="%s.bedpostX/%s.nii.gz") datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Setup for Diffusion Tensor Computation -------------------------------------- Here we will create a generic workflow for DTI computation """ computeTensor = pe.Workflow(name='computeTensor') """ extract the volume with b=0 (nodif_brain) """ fslroi = pe.Node(interface=fsl.ExtractROI(),name='fslroi') fslroi.inputs.t_min=0 fslroi.inputs.t_size=1 """ create a brain mask from the nodif_brain """ bet = pe.Node(interface=fsl.BET(),name='bet') bet.inputs.mask=True bet.inputs.frac=0.34 """ correct the diffusion weighted images for eddy_currents """ eddycorrect = create_eddy_correct_pipeline('eddycorrect') eddycorrect.inputs.inputnode.ref_num=0 """ compute the diffusion tensor in each voxel """ dtifit = pe.Node(interface=fsl.DTIFit(),name='dtifit') """ connect all the nodes for this workflow """ computeTensor.connect([ (fslroi,bet,[('roi_file','in_file')]), (eddycorrect, dtifit,[('outputnode.eddy_corrected','dwi')]), (infosource, dtifit,[['subject_id','base_name']]), (bet,dtifit,[('mask_file','mask')]) ]) """ Setup for Tracktography ----------------------- Here we will create a workflow to enable probabilistic tracktography and hard segmentation of the seed region """ tractography = pe.Workflow(name='tractography') tractography.base_dir = os.path.abspath('fsl_dti_tutorial') """ estimate the diffusion parameters: phi, theta, and so on """ bedpostx = create_bedpostx_pipeline() bedpostx.get_node("xfibres").iterables = ("n_fibres",[1,2]) flirt = pe.Node(interface=fsl.FLIRT(), name='flirt') flirt.inputs.in_file = fsl.Info.standard_image('MNI152_T1_2mm_brain.nii.gz') flirt.inputs.dof = 12 """ perform probabilistic tracktography """ probtrackx = pe.Node(interface=fsl.ProbTrackX(),name='probtrackx') probtrackx.inputs.mode='seedmask' probtrackx.inputs.c_thresh = 0.2 probtrackx.inputs.n_steps=2000 probtrackx.inputs.step_length=0.5 probtrackx.inputs.n_samples=5000 probtrackx.inputs.opd=True probtrackx.inputs.os2t=True probtrackx.inputs.loop_check=True """ perform hard segmentation on the output of probtrackx """ findthebiggest = pe.Node(interface=fsl.FindTheBiggest(),name='findthebiggest') """ connect all the nodes for this workflow """ tractography.add_nodes([bedpostx, flirt]) tractography.connect([(bedpostx,probtrackx,[('outputnode.thsamples','thsamples'), ('outputnode.phsamples','phsamples'), ('outputnode.fsamples','fsamples') ]), (probtrackx,findthebiggest,[('targets','in_files')]), (flirt, probtrackx, [('out_matrix_file','xfm')]) ]) """ Setup data storage area """ datasink = pe.Node(interface=nio.DataSink(),name='datasink') datasink.inputs.base_directory = os.path.abspath('dtiresults') def getstripdir(subject_id): import os return os.path.join(os.path.abspath('data/workingdir/dwiproc'),'_subject_id_%s' % subject_id) """ Setup the pipeline that combines the two workflows: tractography and computeTensor ---------------------------------------------------------------------------------- """ dwiproc = pe.Workflow(name="dwiproc") dwiproc.base_dir = os.path.abspath('fsl_dti_tutorial') dwiproc.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,computeTensor,[('dwi','fslroi.in_file'), ('bvals','dtifit.bvals'), ('bvecs','dtifit.bvecs'), ('dwi','eddycorrect.inputnode.in_file')]), (datasource,tractography,[('bvals','bedpostx.inputnode.bvals'), ('bvecs','bedpostx.inputnode.bvecs'), ('seed_file','probtrackx.seed'), ('target_masks','probtrackx.target_masks') ]), (computeTensor,tractography,[('eddycorrect.outputnode.eddy_corrected','bedpostx.inputnode.dwi'), ('bet.mask_file','bedpostx.inputnode.mask'), ('bet.mask_file','probtrackx.mask'), ('fslroi.roi_file','flirt.reference')]), (infosource, datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (tractography,datasink,[('findthebiggest.out_file','fbiggest.@biggestsegmentation')]) ]) if __name__ == '__main__': dwiproc.run() dwiproc.write_graph() nipype-0.11.0/examples/dmri_group_connectivity_camino.py000066400000000000000000000144311257611314500235700ustar00rootroot00000000000000""" ================================================== dMRI: Group connectivity - Camino, FSL, FreeSurfer ================================================== Introduction ============ This script, dmri_group_connectivity_camino.py, runs group-based connectivity analysis using the dmri.camino.connectivity_mapping Nipype workflow. Further detail on the processing can be found in :doc:`dmri_connectivity`. This tutorial can be run using:: python dmri_group_connectivity_camino.py We perform this analysis using one healthy subject and two subjects who suffer from Parkinson's disease. The whole package (960 mb as .tar.gz / 1.3 gb uncompressed) including the Freesurfer directories for these subjects, can be acquired from here: * http://db.tt/b6F1t0QV A data package containing the outputs of this pipeline can be obtained from here: * http://db.tt/kNvAI751 Along with Camino, Camino-Trackvis, FSL, and Freesurfer, you must also have the Connectome File Format library installed as well as the Connectome Mapper. * Camino: http://web4.cs.ucl.ac.uk/research/medic/camino/pmwiki/pmwiki.php?n=Main.HomePage * Camino-Trackvis: http://www.nitrc.org/projects/camino-trackvis/ * FSL: http://www.fmrib.ox.ac.uk/fsl/ * Freesurfer: http://surfer.nmr.mgh.harvard.edu/ * CTMK: http://www.cmtk.org/ * CFF: sudo apt-get install python-cfflib Or on github at: * CFFlib: https://github.com/LTS5/cfflib * CMP: https://github.com/LTS5/cmp Output data can be visualized in ConnectomeViewer, TrackVis, and anything that can view Nifti files. * ConnectomeViewer: https://github.com/LTS5/connectomeviewer * TrackVis: http://trackvis.org/ The fiber data is available in Numpy arrays, and the connectivity matrix is also produced as a MATLAB matrix. Import the workflows -------------------- First, we import the necessary modules from nipype. """ import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fs # freesurfer import os.path as op # system functions import cmp from nipype.workflows.dmri.camino.group_connectivity import create_group_connectivity_pipeline from nipype.workflows.dmri.connectivity.group_connectivity import (create_merge_networks_by_group_workflow, create_merge_group_networks_workflow, create_average_networks_by_group_workflow) """ Set the proper directories -------------------------- First, we import the necessary modules from nipype. """ fs_dir = op.abspath('/usr/local/freesurfer') subjects_dir = op.abspath('groupcondatapackage/subjects/') data_dir = op.abspath('groupcondatapackage/data/') fs.FSCommand.set_default_subjects_dir(subjects_dir) fsl.FSLCommand.set_default_output_type('NIFTI') """ Define the groups ----------------- Here we define the groups for this study. We would like to search for differences between the healthy subject and the two vegetative patients. The group list is defined as a Python dictionary (see http://docs.python.org/tutorial/datastructures.html), with group IDs ('controls', 'parkinsons') as keys, and subject/patient names as values. We set the main output directory as 'groupcon'. """ group_list = {} group_list['controls'] = ['cont17'] group_list['parkinsons'] = ['pat10', 'pat20'] """ The output directory must be named as well. """ global output_dir output_dir = op.abspath('dmri_group_connectivity_camino') """ Main processing loop ==================== The title for the final grouped-network connectome file is dependent on the group names. The resulting file for this example is 'parkinsons-controls.cff'. The following code implements the format a-b-c-...x.cff for an arbitary number of groups. .. warning:: The 'info' dictionary below is used to define the input files. In this case, the diffusion weighted image contains the string 'dwi'. The same applies to the b-values and b-vector files, and this must be changed to fit your naming scheme. This line creates the processing workflow given the information input about the groups and subjects. .. seealso:: * nipype/workflows/dmri/mrtrix/group_connectivity.py * nipype/workflows/dmri/camino/connectivity_mapping.py * :doc:`dmri_connectivity` The purpose of the second-level workflow is simple: It is used to merge each subject's CFF file into one, so that there is a single file containing all of the networks for each group. This can be useful for performing Network Brain Statistics using the NBS plugin in ConnectomeViewer. .. seealso:: http://www.connectomeviewer.org/documentation/users/tutorials/tut_nbs.html """ title = '' for idx, group_id in enumerate(group_list.keys()): title += group_id if not idx == len(group_list.keys()) - 1: title += '-' info = dict(dwi=[['subject_id', 'dti']], bvecs=[['subject_id', 'bvecs']], bvals=[['subject_id', 'bvals']]) l1pipeline = create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, info) # Here we define the parcellation scheme and the number of tracks to produce parcellation_scheme = 'NativeFreesurfer' cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = parcellation_scheme l1pipeline.inputs.connectivity.inputnode.resolution_network_file = cmp_config._get_lausanne_parcellation(parcellation_scheme)['freesurferaparc']['node_information_graphml'] l1pipeline.run() l1pipeline.write_graph(format='eps', graph2use='flat') # The second-level pipeline is created here l2pipeline = create_merge_networks_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir) l2pipeline.run() l2pipeline.write_graph(format='eps', graph2use='flat') """ Now that the for loop is complete there are two grouped CFF files each containing the appropriate subjects. It is also convenient to have every subject in a single CFF file, so that is what the third-level pipeline does. """ l3pipeline = create_merge_group_networks_workflow(group_list, data_dir, subjects_dir, output_dir, title) l3pipeline.run() l3pipeline.write_graph(format='eps', graph2use='flat') """ The fourth and final workflow averages the networks and saves them in another CFF file """ l4pipeline = create_average_networks_by_group_workflow(group_list, data_dir, subjects_dir, output_dir, title) l4pipeline.run() l4pipeline.write_graph(format='eps', graph2use='flat') nipype-0.11.0/examples/dmri_group_connectivity_mrtrix.py000066400000000000000000000165111257611314500236500ustar00rootroot00000000000000""" ================================================== dMRI: Group connectivity - MRtrix, FSL, FreeSurfer ================================================== Introduction ============ This script, dmri_group_connectivity_mrtrix.py, runs group-based connectivity analysis using the dmri.mrtrix.connectivity_mapping Nipype workflow. Further detail on the processing can be found in :doc:`dmri_connectivity_advanced`. This tutorial can be run using:: python dmri_group_connectivity_mrtrix.py We perform this analysis using one healthy subject and two subjects who suffer from Parkinson's disease. The whole package (960 mb as .tar.gz / 1.3 gb uncompressed) including the Freesurfer directories for these subjects, can be acquired from here: * http://db.tt/b6F1t0QV A data package containing the outputs of this pipeline can be obtained from here: * http://db.tt/elmMnIt1 Along with MRtrix, FSL, and Freesurfer, you must also have the Connectome File Format library installed as well as the Connectome Mapper (cmp). * MRtrix: http://www.brain.org.au/software/mrtrix/ * FSL: http://www.fmrib.ox.ac.uk/fsl/ * Freesurfer: http://surfer.nmr.mgh.harvard.edu/ * CTMK: http://www.cmtk.org/ * CFF: sudo apt-get install python-cfflib Or on github at: * CFFlib: https://github.com/LTS5/cfflib * CMP: https://github.com/LTS5/cmp Output data can be visualized in ConnectomeViewer, TrackVis, Gephi, the MRtrix Viewer (mrview), and anything that can view Nifti files. * ConnectomeViewer: https://github.com/LTS5/connectomeviewer * TrackVis: http://trackvis.org/ * Gephi: http://gephi.org/ The fiber data is available in Numpy arrays, and the connectivity matrix is also produced as a MATLAB matrix. Import the workflows -------------------- First, we import the necessary modules from nipype. """ import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fs # freesurfer import os.path as op # system functions import cmp from nipype.workflows.dmri.mrtrix.group_connectivity import create_group_connectivity_pipeline from nipype.workflows.dmri.connectivity.group_connectivity import (create_merge_network_results_by_group_workflow, create_merge_group_network_results_workflow, create_average_networks_by_group_workflow) """ Set the proper directories -------------------------- First, we import the necessary modules from nipype. """ subjects_dir = op.abspath('groupcondatapackage/subjects/') data_dir = op.abspath('groupcondatapackage/data/') fs.FSCommand.set_default_subjects_dir(subjects_dir) fsl.FSLCommand.set_default_output_type('NIFTI') """ Define the groups ----------------- Here we define the groups for this study. We would like to search for differences between the healthy subject and the two vegetative patients. The group list is defined as a Python dictionary (see http://docs.python.org/tutorial/datastructures.html), with group IDs ('controls', 'parkinsons') as keys, and subject/patient names as values. We set the main output directory as 'groupcon'. """ group_list = {} group_list['controls'] = ['cont17'] group_list['parkinsons'] = ['pat10', 'pat20'] """ The output directory must be named as well. """ global output_dir output_dir = op.abspath('dmri_group_connectivity_mrtrix') """ Main processing loop ==================== The title for the final grouped-network connectome file is dependent on the group names. The resulting file for this example is 'parkinsons-controls.cff'. The following code implements the format a-b-c-...x.cff for an arbitary number of groups. .. warning:: The 'info' dictionary below is used to define the input files. In this case, the diffusion weighted image contains the string 'dti'. The same applies to the b-values and b-vector files, and this must be changed to fit your naming scheme. The workflow is created given the information input about the groups and subjects. .. seealso:: * nipype/workflows/dmri/mrtrix/group_connectivity.py * nipype/workflows/dmri/mrtrix/connectivity_mapping.py * :doc:`dmri_connectivity_advanced` We set values for absolute threshold used on the fractional anisotropy map. This is done in order to identify single-fiber voxels. In brains with more damage, however, it may be necessary to reduce the threshold, since their brains are have lower average fractional anisotropy values. We invert the b-vectors in the encoding file, and set the maximum harmonic order of the pre-tractography spherical deconvolution step. This is done to show how to set inputs that will affect both groups. Next we create and run the second-level pipeline. The purpose of this workflow is simple: It is used to merge each subject's CFF file into one, so that there is a single file containing all of the networks for each group. This can be useful for performing Network Brain Statistics using the NBS plugin in ConnectomeViewer. .. seealso:: http://www.connectomeviewer.org/documentation/users/tutorials/tut_nbs.html """ title = '' for idx, group_id in enumerate(group_list.keys()): title += group_id if not idx == len(group_list.keys()) - 1: title += '-' info = dict(dwi=[['subject_id', 'dti']], bvecs=[['subject_id', 'bvecs']], bvals=[['subject_id', 'bvals']]) l1pipeline = create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, info) # Here with invert the b-vectors in the Y direction and set the maximum harmonic order of the # spherical deconvolution step l1pipeline.inputs.connectivity.mapping.fsl2mrtrix.invert_y = True l1pipeline.inputs.connectivity.mapping.csdeconv.maximum_harmonic_order = 6 # Here we define the parcellation scheme and the number of tracks to produce parcellation_name = 'scale500' l1pipeline.inputs.connectivity.mapping.Parcellate.parcellation_name = parcellation_name cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" l1pipeline.inputs.connectivity.mapping.inputnode_within.resolution_network_file = cmp_config._get_lausanne_parcellation('Lausanne2008')[parcellation_name]['node_information_graphml'] l1pipeline.inputs.connectivity.mapping.probCSDstreamtrack.desired_number_of_tracks = 100000 l1pipeline.run() l1pipeline.write_graph(format='eps', graph2use='flat') # The second-level pipeline is created here l2pipeline = create_merge_network_results_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir) l2pipeline.inputs.l2inputnode.network_file = cmp_config._get_lausanne_parcellation('Lausanne2008')[parcellation_name]['node_information_graphml'] l2pipeline.run() l2pipeline.write_graph(format='eps', graph2use='flat') """ Now that the for loop is complete there are two grouped CFF files each containing the appropriate subjects. It is also convenient to have every subject in a single CFF file, so that is what the third-level pipeline does. """ l3pipeline = create_merge_group_network_results_workflow(group_list, data_dir, subjects_dir, output_dir, title) l3pipeline.run() l3pipeline.write_graph(format='eps', graph2use='flat') """ The fourth and final workflow averages the networks and saves them in another CFF file """ l4pipeline = create_average_networks_by_group_workflow(group_list, data_dir, subjects_dir, output_dir, title) l4pipeline.run() l4pipeline.write_graph(format='eps', graph2use='flat') nipype-0.11.0/examples/dmri_mrtrix_dti.py000077500000000000000000000243411257611314500205010ustar00rootroot00000000000000#!/usr/bin/env python """ ======================= dMRI: DTI - MRtrix, FSL ======================= Introduction ============ This script, dmri_mrtrix_dti.py, demonstrates the ability to perform advanced diffusion analysis in a Nipype pipeline:: python dmri_mrtrix_dti.py We perform this analysis using the FSL course data, which can be acquired from here: * http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz Import necessary modules from nipype. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.mrtrix as mrtrix #<---- The important new part! import nipype.interfaces.fsl as fsl import nipype.algorithms.misc as misc import os, os.path as op # system functions fsl.FSLCommand.set_default_output_type('NIFTI') """ This needs to point to the fdt folder you can find after extracting * http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz """ data_dir = op.abspath(op.join(op.curdir,'exdata/')) subject_list = ['subj1'] """ Use infosource node to loop through the subject list and define the input files. For our purposes, these are the diffusion-weighted MR image, b vectors, and b values. """ infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', subject_list) info = dict(dwi=[['subject_id', 'data']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) """ Use datasource node to perform the actual data grabbing. Templates for the associated images are used to obtain the correct images. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" datasource.inputs.base_directory = data_dir datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ An inputnode is used to pass the data obtained by the data grabber to the actual processing functions """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["dwi", "bvecs", "bvals"]), name="inputnode") """ Diffusion processing nodes -------------------------- .. seealso:: dmri_connectivity_advanced.py Tutorial with further detail on using MRtrix tractography for connectivity analysis http://www.brain.org.au/software/mrtrix/index.html MRtrix's online documentation b-values and b-vectors stored in FSL's format are converted into a single encoding file for MRTrix. """ fsl2mrtrix = pe.Node(interface=mrtrix.FSL2MRTrix(),name='fsl2mrtrix') """ Tensors are fitted to each voxel in the diffusion-weighted image and from these three maps are created: * Major eigenvector in each voxel * Apparent diffusion coefficient * Fractional anisotropy """ gunzip = pe.Node(interface=misc.Gunzip(), name='gunzip') dwi2tensor = pe.Node(interface=mrtrix.DWI2Tensor(),name='dwi2tensor') tensor2vector = pe.Node(interface=mrtrix.Tensor2Vector(),name='tensor2vector') tensor2adc = pe.Node(interface=mrtrix.Tensor2ApparentDiffusion(),name='tensor2adc') tensor2fa = pe.Node(interface=mrtrix.Tensor2FractionalAnisotropy(),name='tensor2fa') """ These nodes are used to create a rough brain mask from the b0 image. The b0 image is extracted from the original diffusion-weighted image, put through a simple thresholding routine, and smoothed using a 3x3 median filter. """ MRconvert = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert') MRconvert.inputs.extract_at_axis = 3 MRconvert.inputs.extract_at_coordinate = [0] threshold_b0 = pe.Node(interface=mrtrix.Threshold(),name='threshold_b0') median3d = pe.Node(interface=mrtrix.MedianFilter3D(),name='median3d') """ The brain mask is also used to help identify single-fiber voxels. This is done by passing the brain mask through two erosion steps, multiplying the remaining mask with the fractional anisotropy map, and thresholding the result to obtain some highly anisotropic within-brain voxels. """ erode_mask_firstpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_firstpass') erode_mask_secondpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_secondpass') MRmultiply = pe.Node(interface=mrtrix.MRMultiply(),name='MRmultiply') MRmult_merge = pe.Node(interface=util.Merge(2), name="MRmultiply_merge") threshold_FA = pe.Node(interface=mrtrix.Threshold(),name='threshold_FA') threshold_FA.inputs.absolute_threshold_value = 0.7 """ For whole-brain tracking we also require a broad white-matter seed mask. This is created by generating a white matter mask, given a brainmask, and thresholding it at a reasonably high level. """ bet = pe.Node(interface=fsl.BET(mask = True), name = 'bet_b0') gen_WM_mask = pe.Node(interface=mrtrix.GenerateWhiteMatterMask(),name='gen_WM_mask') threshold_wmmask = pe.Node(interface=mrtrix.Threshold(),name='threshold_wmmask') threshold_wmmask.inputs.absolute_threshold_value = 0.4 """ The spherical deconvolution step depends on the estimate of the response function in the highly anisotropic voxels we obtained above. .. warning:: For damaged or pathological brains one should take care to lower the maximum harmonic order of these steps. """ estimateresponse = pe.Node(interface=mrtrix.EstimateResponseForSH(),name='estimateresponse') estimateresponse.inputs.maximum_harmonic_order = 6 csdeconv = pe.Node(interface=mrtrix.ConstrainedSphericalDeconvolution(),name='csdeconv') csdeconv.inputs.maximum_harmonic_order = 6 """ Finally, we track probabilistically using the orientation distribution functions obtained earlier. The tracts are then used to generate a tract-density image, and they are also converted to TrackVis format. """ probCSDstreamtrack = pe.Node(interface=mrtrix.ProbabilisticSphericallyDeconvolutedStreamlineTrack(),name='probCSDstreamtrack') probCSDstreamtrack.inputs.inputmodel = 'SD_PROB' probCSDstreamtrack.inputs.maximum_number_of_tracks = 150000 tracks2prob = pe.Node(interface=mrtrix.Tracks2Prob(),name='tracks2prob') tracks2prob.inputs.colour = True tck2trk = pe.Node(interface=mrtrix.MRTrix2TrackVis(),name='tck2trk') """ Creating the workflow --------------------- In this section we connect the nodes for the diffusion processing. """ tractography = pe.Workflow(name='tractography') tractography.connect([(inputnode, fsl2mrtrix, [("bvecs", "bvec_file"), ("bvals", "bval_file")])]) tractography.connect([(inputnode, gunzip,[("dwi","in_file")])]) tractography.connect([(gunzip, dwi2tensor,[("out_file","in_file")])]) tractography.connect([(fsl2mrtrix, dwi2tensor,[("encoding_file","encoding_file")])]) tractography.connect([(dwi2tensor, tensor2vector,[['tensor','in_file']]), (dwi2tensor, tensor2adc,[['tensor','in_file']]), (dwi2tensor, tensor2fa,[['tensor','in_file']]), ]) tractography.connect([(tensor2fa, MRmult_merge,[("FA","in1")])]) """ This block creates the rough brain mask to be multiplied, mulitplies it with the fractional anisotropy image, and thresholds it to get the single-fiber voxels. """ tractography.connect([(gunzip, MRconvert,[("out_file","in_file")])]) tractography.connect([(MRconvert, threshold_b0,[("converted","in_file")])]) tractography.connect([(threshold_b0, median3d,[("out_file","in_file")])]) tractography.connect([(median3d, erode_mask_firstpass,[("out_file","in_file")])]) tractography.connect([(erode_mask_firstpass, erode_mask_secondpass,[("out_file","in_file")])]) tractography.connect([(erode_mask_secondpass, MRmult_merge,[("out_file","in2")])]) tractography.connect([(MRmult_merge, MRmultiply,[("out","in_files")])]) tractography.connect([(MRmultiply, threshold_FA,[("out_file","in_file")])]) """ Here the thresholded white matter mask is created for seeding the tractography. """ tractography.connect([(gunzip, bet,[("out_file","in_file")])]) tractography.connect([(gunzip, gen_WM_mask,[("out_file","in_file")])]) tractography.connect([(bet, gen_WM_mask,[("mask_file","binary_mask")])]) tractography.connect([(fsl2mrtrix, gen_WM_mask,[("encoding_file","encoding_file")])]) tractography.connect([(gen_WM_mask, threshold_wmmask,[("WMprobabilitymap","in_file")])]) """ Next we estimate the fiber response distribution. """ tractography.connect([(gunzip, estimateresponse,[("out_file","in_file")])]) tractography.connect([(fsl2mrtrix, estimateresponse,[("encoding_file","encoding_file")])]) tractography.connect([(threshold_FA, estimateresponse,[("out_file","mask_image")])]) """ Run constrained spherical deconvolution. """ tractography.connect([(gunzip, csdeconv,[("out_file","in_file")])]) tractography.connect([(gen_WM_mask, csdeconv,[("WMprobabilitymap","mask_image")])]) tractography.connect([(estimateresponse, csdeconv,[("response","response_file")])]) tractography.connect([(fsl2mrtrix, csdeconv,[("encoding_file","encoding_file")])]) """ Connect the tractography and compute the tract density image. """ tractography.connect([(threshold_wmmask, probCSDstreamtrack,[("out_file","seed_file")])]) tractography.connect([(csdeconv, probCSDstreamtrack,[("spherical_harmonics_image","in_file")])]) tractography.connect([(probCSDstreamtrack, tracks2prob,[("tracked","in_file")])]) tractography.connect([(gunzip, tracks2prob,[("out_file","template_file")])]) tractography.connect([(gunzip, tck2trk,[("out_file","image_file")])]) tractography.connect([(probCSDstreamtrack, tck2trk,[("tracked","in_file")])]) """ Finally, we create another higher-level workflow to connect our tractography workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ dwiproc = pe.Workflow(name="dwiproc") dwiproc.base_dir = os.path.abspath('dmri_mrtrix_dti') dwiproc.connect([ (infosource,datasource,[('subject_id', 'subject_id')]), (datasource,tractography,[('dwi','inputnode.dwi'), ('bvals','inputnode.bvals'), ('bvecs','inputnode.bvecs') ]) ]) if __name__ == '__main__': dwiproc.run() dwiproc.write_graph() nipype-0.11.0/examples/dmri_preprocessing.py000066400000000000000000000126171257611314500211770ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ =================== dMRI: Preprocessing =================== Introduction ============ This script, dmri_preprocessing.py, demonstrates how to prepare dMRI data for tractography and connectivity analysis with nipype. We perform this analysis using the FSL course data, which can be acquired from here: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz Can be executed in command line using ``python dmri_preprocessing.py`` Import necessary modules from nipype. """ import os # system functions import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as niu # utility import nipype.algorithms.misc as misc import nipype.pipeline.engine as pe # pypeline engine from nipype.interfaces import fsl from nipype.interfaces import ants """ Load specific nipype's workflows for preprocessing of dMRI data: :class:`nipype.workflows.dmri.preprocess.epi.all_peb_pipeline`, as data include a *b0* volume with reverse encoding direction (*P>>>A*, or *y*), in contrast with the general acquisition encoding that is *A>>>P* or *-y* (in RAS systems). """ from nipype.workflows.dmri.fsl.artifacts import all_fsl_pipeline, remove_bias """ Map field names into individual subject runs """ info = dict(dwi=[['subject_id', 'dwidata']], bvecs=[['subject_id', 'bvecs']], bvals=[['subject_id', 'bvals']], dwi_rev=[['subject_id', 'nodif_PA']]) infosource = pe.Node(interface=niu.IdentityInterface(fields=['subject_id']), name="infosource") # Set the subject 1 identifier in subject_list, # we choose the preproc dataset as it contains uncorrected files. subject_list = ['subj1_preproc'] """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`~nipype.pipeline.engine.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name='datasource') datasource.inputs.template = "%s/%s" # This needs to point to the fdt folder you can find after extracting # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz datasource.inputs.base_directory = os.path.abspath('fdt1') datasource.inputs.field_template = dict(dwi='%s/%s.nii.gz', dwi_rev='%s/%s.nii.gz') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ An inputnode is used to pass the data obtained by the data grabber to the actual processing functions """ inputnode = pe.Node(niu.IdentityInterface(fields=["dwi", "bvecs", "bvals", "dwi_rev"]), name="inputnode") """ Setup for dMRI preprocessing ============================ In this section we initialize the appropriate workflow for preprocessing of diffusion images. Artifacts correction -------------------- We will use the combination of ``topup`` and ``eddy`` as suggested by FSL. In order to configure the susceptibility distortion correction (SDC), we first write the specific parameters of our echo-planar imaging (EPI) images. Particularly, we look into the ``acqparams.txt`` file of the selected subject to gather the encoding direction, acceleration factor (in parallel sequences it is > 1), and readout time or echospacing. """ epi_AP = {'echospacing': 66.5e-3, 'enc_dir': 'y-'} epi_PA = {'echospacing': 66.5e-3, 'enc_dir': 'y'} prep = all_fsl_pipeline(epi_params=epi_AP, altepi_params=epi_PA) """ Bias field correction --------------------- Finally, we set up a node to correct for a single multiplicative bias field from computed on the *b0* image, as suggested in [Jeurissen2014]_. """ bias = remove_bias() """ Connect nodes in workflow ========================= We create a higher level workflow to connect the nodes. Please excuse the author for writing the arguments of the ``connect`` function in a not-standard style with readability aims. """ wf = pe.Workflow(name="dMRI_Preprocessing") wf.base_dir = os.path.abspath('preprocessing_dmri_tutorial') wf.connect([ (infosource, datasource, [('subject_id', 'subject_id')]) ,(datasource, prep, [('dwi', 'inputnode.in_file'), ('dwi_rev', 'inputnode.alt_file'), ('bvals', 'inputnode.in_bval'), ('bvecs', 'inputnode.in_bvec')]) ,(prep, bias, [('outputnode.out_file', 'inputnode.in_file'), ('outputnode.out_mask', 'inputnode.in_mask')]) ,(datasource, bias, [('bvals', 'inputnode.in_bval')]) ]) """ Run the workflow as command line executable """ if __name__ == '__main__': wf.run() wf.write_graph() nipype-0.11.0/examples/dmri_tbss_nki.py000077500000000000000000000115051257611314500201260ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ========================= dMRI: TBSS on NKI RS data ========================= A pipeline to do a TBSS analysis on the NKI rockland sample data """ from nipype.workflows.dmri.fsl.dti import create_eddy_correct_pipeline from nipype.workflows.dmri.fsl.tbss import create_tbss_non_FA, create_tbss_all """ Tell python where to find the appropriate functions. """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import os # system functions fsl.FSLCommand.set_default_output_type('NIFTI') """ You can get the data from: http://fcon_1000.projects.nitrc.org/indi/pro/eNKI_RS_TRT/FrontPage.html """ dataDir = os.path.abspath('nki_rs_data') workingdir = './tbss_example' subjects_list = ['2475376', '3313349', '3808535', '3893245', '8735778', '9630905'] gen_fa = pe.Workflow(name="gen_fa") gen_fa.base_dir = os.path.join(os.path.abspath(workingdir), 'l1') subject_id_infosource = pe.Node(util.IdentityInterface(fields=['subject_id']), name='subject_id_infosource') subject_id_infosource.iterables = ('subject_id', subjects_list) datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['dwi', 'bvec', 'bval']), name='datasource') datasource.inputs.base_directory = os.path.abspath(dataDir) datasource.inputs.template = '%s/session2/DTI_mx_137/dti.%s' datasource.inputs.template_args = dict(dwi=[['subject_id', 'nii.gz']], bvec=[['subject_id', 'bvec']], bval=[['subject_id', 'bval']]) datasource.inputs.sort_filelist = True gen_fa.connect(subject_id_infosource, 'subject_id', datasource, 'subject_id') eddy_correct = create_eddy_correct_pipeline() eddy_correct.inputs.inputnode.ref_num = 0 gen_fa.connect(datasource, 'dwi', eddy_correct, 'inputnode.in_file') bet = pe.Node(interface=fsl.BET(), name='bet') bet.inputs.mask = True bet.inputs.frac = 0.34 gen_fa.connect(eddy_correct, 'pick_ref.out', bet, 'in_file') dtifit = pe.Node(interface=fsl.DTIFit(), name='dtifit') gen_fa.connect(eddy_correct, 'outputnode.eddy_corrected', dtifit, 'dwi') gen_fa.connect(subject_id_infosource, 'subject_id', dtifit, 'base_name') gen_fa.connect(bet, 'mask_file', dtifit, 'mask') gen_fa.connect(datasource, 'bvec', dtifit, 'bvecs') gen_fa.connect(datasource, 'bval', dtifit, 'bvals') datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.join(os.path.abspath(workingdir), 'l1_results') datasink.inputs.parameterization = False gen_fa.connect(dtifit, 'FA', datasink, 'FA') gen_fa.connect(dtifit, 'MD', datasink, 'MD') if __name__ == '__main__': gen_fa.write_graph() gen_fa.run() """ Here we get the FA list including all the subjects. """ tbss_source = pe.Node(interface=nio.DataGrabber(outfiles=['fa_list', 'md_list']), name='tbss_source') tbss_source.inputs.base_directory = datasink.inputs.base_directory tbss_source.inputs.template = '%s/%s_%s.nii' tbss_source.inputs.template_args = dict(fa_list=[['FA', subjects_list, 'FA']], md_list=[['MD', subjects_list, 'MD']]) tbss_source.inputs.sort_filelist = True """ TBSS analysis """ tbss_all = create_tbss_all() tbss_all.inputs.inputnode.skeleton_thresh = 0.2 tbssproc = pe.Workflow(name="tbssproc") tbssproc.base_dir = os.path.join(os.path.abspath(workingdir), 'l2') tbssproc.connect(tbss_source, 'fa_list', tbss_all, 'inputnode.fa_list') tbss_MD = create_tbss_non_FA(name='tbss_MD') tbss_MD.inputs.inputnode.skeleton_thresh = tbss_all.inputs.inputnode.skeleton_thresh tbssproc.connect([(tbss_all, tbss_MD, [('tbss2.outputnode.field_list', 'inputnode.field_list'), ('tbss3.outputnode.groupmask', 'inputnode.groupmask'), ('tbss3.outputnode.meanfa_file', 'inputnode.meanfa_file'), ('tbss4.outputnode.distance_map', 'inputnode.distance_map')]), (tbss_source, tbss_MD, [('md_list', 'inputnode.file_list')]), ]) if __name__ == '__main__': tbssproc.write_graph() tbssproc.run() nipype-0.11.0/examples/fmri_ants_openfmri.py000077500000000000000000001400161257611314500211600ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ============================================= fMRI: OpenfMRI.org data, FSL, ANTS, c3daffine ============================================= A growing number of datasets are available on `OpenfMRI `_. This script demonstrates how to use nipype to analyze a data set:: python fmri_ants_openfmri.py --datasetdir ds107 """ from nipype import config config.enable_provenance() from nipype.external import six from glob import glob import os import nipype.pipeline.engine as pe import nipype.algorithms.modelgen as model import nipype.algorithms.rapidart as ra import nipype.interfaces.fsl as fsl import nipype.interfaces.ants as ants from nipype.algorithms.misc import TSNR from nipype.interfaces.c3 import C3dAffineTool import nipype.interfaces.io as nio import nipype.interfaces.utility as niu from nipype.workflows.fmri.fsl import (create_featreg_preproc, create_modelfit_workflow, create_fixed_effects_flow) from nipype import LooseVersion from nipype import Workflow, Node, MapNode from nipype.interfaces import (fsl, Function, ants, freesurfer) from nipype.interfaces.utility import Rename, Merge, IdentityInterface from nipype.utils.filemanip import filename_to_list from nipype.interfaces.io import DataSink, FreeSurferSource import nipype.interfaces.freesurfer as fs version = 0 if fsl.Info.version() and \ LooseVersion(fsl.Info.version()) > LooseVersion('5.0.6'): version = 507 fsl.FSLCommand.set_default_output_type('NIFTI_GZ') imports = ['import os', 'import nibabel as nb', 'import numpy as np', 'import scipy as sp', 'from nipype.utils.filemanip import filename_to_list, list_to_filename, split_filename', 'from scipy.special import legendre' ] def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average/float(idx + 1), img.get_affine(), img.get_header()) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- name : name of workflow (default: 'registration') Inputs: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target Outputs: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space """ register = pe.Workflow(name=name) inputnode = pe.Node(interface=niu.IdentityInterface(fields=['source_files', 'mean_image', 'anatomical_image', 'target_image', 'target_image_brain', 'config_file']), name='inputspec') outputnode = pe.Node(interface=niu.IdentityInterface(fields=['func2anat_transform', 'anat2target_transform', 'transformed_files', 'transformed_mean', 'anat2target', 'mean2anat_mask' ]), name='outputspec') """ Estimate the tissue classes from the anatomical image. But use spm's segment as FSL appears to be breaking. """ stripper = pe.Node(fsl.BET(), name='stripper') register.connect(inputnode, 'anatomical_image', stripper, 'in_file') fast = pe.Node(fsl.FAST(), name='fast') register.connect(stripper, 'out_file', fast, 'in_files') """ Binarize the segmentation """ binarize = pe.Node(fsl.ImageMaths(op_string='-nan -thr 0.5 -bin'), name='binarize') pickindex = lambda x, i: x[i] register.connect(fast, ('partial_volume_files', pickindex, 2), binarize, 'in_file') """ Calculate rigid transform from mean image to anatomical image """ mean2anat = pe.Node(fsl.FLIRT(), name='mean2anat') mean2anat.inputs.dof = 6 register.connect(inputnode, 'mean_image', mean2anat, 'in_file') register.connect(stripper, 'out_file', mean2anat, 'reference') """ Now use bbr cost function to improve the transform """ mean2anatbbr = pe.Node(fsl.FLIRT(), name='mean2anatbbr') mean2anatbbr.inputs.dof = 6 mean2anatbbr.inputs.cost = 'bbr' mean2anatbbr.inputs.schedule = os.path.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch') register.connect(inputnode, 'mean_image', mean2anatbbr, 'in_file') register.connect(binarize, 'out_file', mean2anatbbr, 'wm_seg') register.connect(inputnode, 'anatomical_image', mean2anatbbr, 'reference') register.connect(mean2anat, 'out_matrix_file', mean2anatbbr, 'in_matrix_file') """ Create a mask of the median image coregistered to the anatomical image """ mean2anat_mask = Node(fsl.BET(mask=True), name='mean2anat_mask') register.connect(mean2anatbbr, 'out_file', mean2anat_mask, 'in_file') """ Convert the BBRegister transformation to ANTS ITK format """ convert2itk = pe.Node(C3dAffineTool(), name='convert2itk') convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(mean2anatbbr, 'out_matrix_file', convert2itk, 'transform_file') register.connect(inputnode, 'mean_image',convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template This is currently set to perform a very quick registration. However, the registration can be made significantly more accurate for cortical structures by increasing the number of iterations All parameters are set using the example from: #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh """ reg = pe.Node(ants.Registration(), name='antsRegister') reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[100, 30, 20]] reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = True reg.inputs.initial_moving_transform_com = True reg.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']] reg.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]] reg.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]] reg.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]] reg.inputs.sampling_percentage = [0.3] * 2 + [[None, None]] reg.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01] reg.inputs.convergence_window_size = [20] * 2 + [5] reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]] reg.inputs.sigma_units = ['vox'] * 3 reg.inputs.shrink_factors = [[3, 2, 1]]*2 + [[4, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True] * 3 reg.inputs.use_histogram_matching = [False] * 2 + [True] reg.inputs.winsorize_lower_quantile = 0.005 reg.inputs.winsorize_upper_quantile = 0.995 reg.inputs.args = '--float' reg.inputs.output_warped_image = 'output_warped_image.nii.gz' reg.inputs.num_threads = 4 reg.plugin_args = {'qsub_args': '-pe orte 4', 'sbatch_args': '--mem=6G -c 4'} register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image_brain', reg,'fixed_image') """ Concatenate the affine and ants transforms into a list """ pickfirst = lambda x: x[0] merge = pe.Node(niu.Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target """ warpmean = pe.Node(ants.ApplyTransforms(), name='warpmean') warpmean.inputs.input_image_type = 0 warpmean.inputs.interpolation = 'Linear' warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' register.connect(inputnode,'target_image_brain', warpmean,'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') """ Transform the remaining images. First to anatomical and then to target """ warpall = pe.MapNode(ants.ApplyTransforms(), iterfield=['input_image'], name='warpall') warpall.inputs.input_image_type = 0 warpall.inputs.interpolation = 'Linear' warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' register.connect(inputnode,'target_image_brain',warpall,'reference_image') register.connect(inputnode,'source_files', warpall, 'input_image') register.connect(merge, 'out', warpall, 'transforms') """ Assign all the output files """ register.connect(reg, 'warped_image', outputnode, 'anat2target') register.connect(warpmean, 'output_image', outputnode, 'transformed_mean') register.connect(warpall, 'output_image', outputnode, 'transformed_files') register.connect(mean2anatbbr, 'out_matrix_file', outputnode, 'func2anat_transform') register.connect(mean2anat_mask, 'mask_file', outputnode, 'mean2anat_mask') register.connect(reg, 'composite_transform', outputnode, 'anat2target_transform') return register def get_aparc_aseg(files): """Return the aparc+aseg.mgz file""" for name in files: if 'aparc+aseg.mgz' in name: return name raise ValueError('aparc+aseg.mgz not found') def create_fs_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- name : name of workflow (default: 'registration') Inputs:: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.target_image : registration target Outputs:: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space """ register = Workflow(name=name) inputnode = Node(interface=IdentityInterface(fields=['source_files', 'mean_image', 'subject_id', 'subjects_dir', 'target_image']), name='inputspec') outputnode = Node(interface=IdentityInterface(fields=['func2anat_transform', 'out_reg_file', 'anat2target_transform', 'transforms', 'transformed_mean', 'transformed_files', 'min_cost_file', 'anat2target', 'aparc', 'mean2anat_mask' ]), name='outputspec') # Get the subject's freesurfer source directory fssource = Node(FreeSurferSource(), name='fssource') fssource.run_without_submitting = True register.connect(inputnode, 'subject_id', fssource, 'subject_id') register.connect(inputnode, 'subjects_dir', fssource, 'subjects_dir') convert = Node(freesurfer.MRIConvert(out_type='nii'), name="convert") register.connect(fssource, 'T1', convert, 'in_file') # Coregister the median to the surface bbregister = Node(freesurfer.BBRegister(registered_file=True), name='bbregister') bbregister.inputs.init = 'fsl' bbregister.inputs.contrast_type = 't2' bbregister.inputs.out_fsl_file = True bbregister.inputs.epi_mask = True register.connect(inputnode, 'subject_id', bbregister, 'subject_id') register.connect(inputnode, 'mean_image', bbregister, 'source_file') register.connect(inputnode, 'subjects_dir', bbregister, 'subjects_dir') # Create a mask of the median coregistered to the anatomical image mean2anat_mask = Node(fsl.BET(mask=True), name='mean2anat_mask') register.connect(bbregister, 'registered_file', mean2anat_mask, 'in_file') """ use aparc+aseg's brain mask """ binarize = Node(fs.Binarize(min=0.5, out_type="nii.gz", dilate=1), name="binarize_aparc") register.connect(fssource, ("aparc_aseg", get_aparc_aseg), binarize, "in_file") stripper = Node(fsl.ApplyMask(), name ='stripper') register.connect(binarize, "binary_file", stripper, "mask_file") register.connect(convert, 'out_file', stripper, 'in_file') """ Apply inverse transform to aparc file """ aparcxfm = Node(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), name='aparc_inverse_transform') register.connect(inputnode, 'subjects_dir', aparcxfm, 'subjects_dir') register.connect(bbregister, 'out_reg_file', aparcxfm, 'reg_file') register.connect(fssource, ('aparc_aseg', get_aparc_aseg), aparcxfm, 'target_file') register.connect(inputnode, 'mean_image', aparcxfm, 'source_file') """ Convert the BBRegister transformation to ANTS ITK format """ convert2itk = Node(C3dAffineTool(), name='convert2itk') convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(bbregister, 'out_fsl_file', convert2itk, 'transform_file') register.connect(inputnode, 'mean_image',convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template This is currently set to perform a very quick registration. However, the registration can be made significantly more accurate for cortical structures by increasing the number of iterations All parameters are set using the example from: #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh """ reg = Node(ants.Registration(), name='antsRegister') reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[100, 30, 20]] reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = True reg.inputs.initial_moving_transform_com = True reg.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']] reg.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]] reg.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]] reg.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]] reg.inputs.sampling_percentage = [0.3] * 2 + [[None, None]] reg.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01] reg.inputs.convergence_window_size = [20] * 2 + [5] reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]] reg.inputs.sigma_units = ['vox'] * 3 reg.inputs.shrink_factors = [[3, 2, 1]]*2 + [[4, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True] * 3 reg.inputs.use_histogram_matching = [False] * 2 + [True] reg.inputs.winsorize_lower_quantile = 0.005 reg.inputs.winsorize_upper_quantile = 0.995 reg.inputs.float = True reg.inputs.output_warped_image = 'output_warped_image.nii.gz' reg.inputs.num_threads = 4 reg.plugin_args = {'qsub_args': '-pe orte 4', 'sbatch_args': '--mem=6G -c 4'} register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image', reg,'fixed_image') """ Concatenate the affine and ants transforms into a list """ pickfirst = lambda x: x[0] merge = Node(Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target """ warpmean = Node(ants.ApplyTransforms(), name='warpmean') warpmean.inputs.input_image_type = 0 warpmean.inputs.interpolation = 'Linear' warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' warpmean.inputs.args = '--float' #warpmean.inputs.num_threads = 4 #warpmean.plugin_args = {'sbatch_args': '--mem=4G -c 4'} """ Transform the remaining images. First to anatomical and then to target """ warpall = pe.MapNode(ants.ApplyTransforms(), iterfield=['input_image'], name='warpall') warpall.inputs.input_image_type = 0 warpall.inputs.interpolation = 'Linear' warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' warpall.inputs.args = '--float' warpall.inputs.num_threads = 2 warpall.plugin_args = {'sbatch_args': '--mem=6G -c 2'} """ Assign all the output files """ register.connect(warpmean, 'output_image', outputnode, 'transformed_mean') register.connect(warpall, 'output_image', outputnode, 'transformed_files') register.connect(inputnode,'target_image', warpmean,'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') register.connect(inputnode,'target_image', warpall,'reference_image') register.connect(inputnode,'source_files', warpall, 'input_image') register.connect(merge, 'out', warpall, 'transforms') """ Assign all the output files """ register.connect(reg, 'warped_image', outputnode, 'anat2target') register.connect(aparcxfm, 'transformed_file', outputnode, 'aparc') register.connect(bbregister, 'out_fsl_file', outputnode, 'func2anat_transform') register.connect(bbregister, 'out_reg_file', outputnode, 'out_reg_file') register.connect(bbregister, 'min_cost_file', outputnode, 'min_cost_file') register.connect(mean2anat_mask, 'mask_file', outputnode, 'mean2anat_mask') register.connect(reg, 'composite_transform', outputnode, 'anat2target_transform') register.connect(merge, 'out', outputnode, 'transforms') return register """ Get info for a given subject """ def get_subjectinfo(subject_id, base_dir, task_id, model_id): """Get info for a given subject Parameters ---------- subject_id : string Subject identifier (e.g., sub001) base_dir : string Path to base directory of the dataset task_id : int Which task to process model_id : int Which model to process Returns ------- run_ids : list of ints Run numbers conds : list of str Condition names TR : float Repetition time """ from glob import glob import os import numpy as np condition_info = [] cond_file = os.path.join(base_dir, 'models', 'model%03d' % model_id, 'condition_key.txt') with open(cond_file, 'rt') as fp: for line in fp: info = line.strip().split() condition_info.append([info[0], info[1], ' '.join(info[2:])]) if len(condition_info) == 0: raise ValueError('No condition info found in %s' % cond_file) taskinfo = np.array(condition_info) n_tasks = len(np.unique(taskinfo[:, 0])) conds = [] run_ids = [] if task_id > n_tasks: raise ValueError('Task id %d does not exist' % task_id) for idx in range(n_tasks): taskidx = np.where(taskinfo[:, 0] == 'task%03d' % (idx + 1)) conds.append([condition.replace(' ', '_') for condition in taskinfo[taskidx[0], 2]]) # if 'junk' not in condition]) files = sorted(glob(os.path.join(base_dir, subject_id, 'BOLD', 'task%03d_run*' % (idx + 1)))) runs = [int(val[-3:]) for val in files] run_ids.insert(idx, runs) json_info = os.path.join(base_dir, subject_id, 'BOLD', 'task%03d_run%03d' % (task_id, run_ids[task_id - 1][0]), 'bold_scaninfo.json') if os.path.exists(json_info): import json with open(json_info, 'rt') as fp: data = json.load(fp) TR = data['global']['const']['RepetitionTime']/1000. else: task_scan_key = os.path.join(base_dir, subject_id, 'BOLD', 'task%03d_run%03d' % (task_id, run_ids[task_id - 1][0]), 'scan_key.txt') if os.path.exists(task_scan_key): TR = np.genfromtxt(task_scan_key)[1] else: TR = np.genfromtxt(os.path.join(base_dir, 'scan_key.txt'))[1] return run_ids[task_id - 1], conds[task_id - 1], TR """ Analyzes an open fmri dataset """ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, task_id=None, output_dir=None, subj_prefix='*', hpcutoff=120., use_derivatives=True, fwhm=6.0, subjects_dir=None, target=None): """Analyzes an open fmri dataset Parameters ---------- data_dir : str Path to the base data directory work_dir : str Nipype working directory (defaults to cwd) """ """ Load nipype workflows """ preproc = create_featreg_preproc(whichvol='first') modelfit = create_modelfit_workflow() fixed_fx = create_fixed_effects_flow() if subjects_dir: registration = create_fs_reg_workflow() else: registration = create_reg_workflow() """ Remove the plotting connection so that plot iterables don't propagate to the model stage """ preproc.disconnect(preproc.get_node('plot_motion'), 'out_file', preproc.get_node('outputspec'), 'motion_plots') """ Set up openfmri data specific components """ subjects = sorted([path.split(os.path.sep)[-1] for path in glob(os.path.join(data_dir, subj_prefix))]) infosource = pe.Node(niu.IdentityInterface(fields=['subject_id', 'model_id', 'task_id']), name='infosource') if len(subject) == 0: infosource.iterables = [('subject_id', subjects), ('model_id', [model_id]), ('task_id', task_id)] else: infosource.iterables = [('subject_id', [subjects[subjects.index(subj)] for subj in subject]), ('model_id', [model_id]), ('task_id', task_id)] subjinfo = pe.Node(niu.Function(input_names=['subject_id', 'base_dir', 'task_id', 'model_id'], output_names=['run_id', 'conds', 'TR'], function=get_subjectinfo), name='subjectinfo') subjinfo.inputs.base_dir = data_dir """ Return data components as anat, bold and behav """ contrast_file = os.path.join(data_dir, 'models', 'model%03d' % model_id, 'task_contrasts.txt') has_contrast = os.path.exists(contrast_file) if has_contrast: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', 'task_id', 'model_id'], outfields=['anat', 'bold', 'behav', 'contrasts']), name='datasource') else: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', 'task_id', 'model_id'], outfields=['anat', 'bold', 'behav']), name='datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '*' if has_contrast: datasource.inputs.field_template = {'anat': '%s/anatomy/T1_001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt'), 'contrasts': ('models/model%03d/' 'task_contrasts.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], 'bold': [['subject_id', 'task_id']], 'behav': [['subject_id', 'model_id', 'task_id', 'run_id']], 'contrasts': [['model_id']]} else: datasource.inputs.field_template = {'anat': '%s/anatomy/T1_001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], 'bold': [['subject_id', 'task_id']], 'behav': [['subject_id', 'model_id', 'task_id', 'run_id']]} datasource.inputs.sort_filelist = True """ Create meta workflow """ wf = pe.Workflow(name='openfmri') wf.connect(infosource, 'subject_id', subjinfo, 'subject_id') wf.connect(infosource, 'model_id', subjinfo, 'model_id') wf.connect(infosource, 'task_id', subjinfo, 'task_id') wf.connect(infosource, 'subject_id', datasource, 'subject_id') wf.connect(infosource, 'model_id', datasource, 'model_id') wf.connect(infosource, 'task_id', datasource, 'task_id') wf.connect(subjinfo, 'run_id', datasource, 'run_id') wf.connect([(datasource, preproc, [('bold', 'inputspec.func')]), ]) def get_highpass(TR, hpcutoff): return hpcutoff / (2 * TR) gethighpass = pe.Node(niu.Function(input_names=['TR', 'hpcutoff'], output_names=['highpass'], function=get_highpass), name='gethighpass') wf.connect(subjinfo, 'TR', gethighpass, 'TR') wf.connect(gethighpass, 'highpass', preproc, 'inputspec.highpass') """ Setup a basic set of contrasts, a t-test per condition """ def get_contrasts(contrast_file, task_id, conds): import numpy as np import os contrast_def = [] if os.path.exists(contrast_file): with open(contrast_file, 'rt') as fp: contrast_def.extend([np.array(row.split()) for row in fp.readlines() if row.strip()]) contrasts = [] for row in contrast_def: if row[0] != 'task%03d' % task_id: continue con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], row[2:].astype(float).tolist()] contrasts.append(con) # add auto contrasts for each column for i, cond in enumerate(conds): con = [cond, 'T', ['cond%03d' % (i + 1)], [1]] contrasts.append(con) return contrasts contrastgen = pe.Node(niu.Function(input_names=['contrast_file', 'task_id', 'conds'], output_names=['contrasts'], function=get_contrasts), name='contrastgen') art = pe.MapNode(interface=ra.ArtifactDetect(use_differences=[True, False], use_norm=True, norm_threshold=1, zintensity_threshold=3, parameter_source='FSL', mask_type='file'), iterfield=['realigned_files', 'realignment_parameters', 'mask_file'], name="art") modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") modelspec.inputs.input_units = 'secs' def check_behav_list(behav, run_id, conds): from nipype.external import six import numpy as np num_conds = len(conds) if isinstance(behav, six.string_types): behav = [behav] behav_array = np.array(behav).flatten() num_elements = behav_array.shape[0] return behav_array.reshape(num_elements/num_conds, num_conds).tolist() reshape_behav = pe.Node(niu.Function(input_names=['behav', 'run_id', 'conds'], output_names=['behav'], function=check_behav_list), name='reshape_behav') wf.connect(subjinfo, 'TR', modelspec, 'time_repetition') wf.connect(datasource, 'behav', reshape_behav, 'behav') wf.connect(subjinfo, 'run_id', reshape_behav, 'run_id') wf.connect(subjinfo, 'conds', reshape_behav, 'conds') wf.connect(reshape_behav, 'behav', modelspec, 'event_files') wf.connect(subjinfo, 'TR', modelfit, 'inputspec.interscan_interval') wf.connect(subjinfo, 'conds', contrastgen, 'conds') if has_contrast: wf.connect(datasource, 'contrasts', contrastgen, 'contrast_file') else: contrastgen.inputs.contrast_file = '' wf.connect(infosource, 'task_id', contrastgen, 'task_id') wf.connect(contrastgen, 'contrasts', modelfit, 'inputspec.contrasts') wf.connect([(preproc, art, [('outputspec.motion_parameters', 'realignment_parameters'), ('outputspec.realigned_files', 'realigned_files'), ('outputspec.mask', 'mask_file')]), (preproc, modelspec, [('outputspec.highpassed_files', 'functional_runs'), ('outputspec.motion_parameters', 'realignment_parameters')]), (art, modelspec, [('outlier_files', 'outlier_files')]), (modelspec, modelfit, [('session_info', 'inputspec.session_info')]), (preproc, modelfit, [('outputspec.highpassed_files', 'inputspec.functional_data')]) ]) # Comute TSNR on realigned data regressing polynomials upto order 2 tsnr = MapNode(TSNR(regress_poly=2), iterfield=['in_file'], name='tsnr') wf.connect(preproc, "outputspec.realigned_files", tsnr, "in_file") # Compute the median image across runs calc_median = Node(Function(input_names=['in_files'], output_names=['median_file'], function=median, imports=imports), name='median') wf.connect(tsnr, 'detrended_file', calc_median, 'in_files') """ Reorder the copes so that now it combines across runs """ def sort_copes(copes, varcopes, contrasts): import numpy as np if not isinstance(copes, list): copes = [copes] varcopes = [varcopes] num_copes = len(contrasts) n_runs = len(copes) all_copes = np.array(copes).flatten() all_varcopes = np.array(varcopes).flatten() outcopes = all_copes.reshape(len(all_copes)/num_copes, num_copes).T.tolist() outvarcopes = all_varcopes.reshape(len(all_varcopes)/num_copes, num_copes).T.tolist() return outcopes, outvarcopes, n_runs cope_sorter = pe.Node(niu.Function(input_names=['copes', 'varcopes', 'contrasts'], output_names=['copes', 'varcopes', 'n_runs'], function=sort_copes), name='cope_sorter') pickfirst = lambda x: x[0] wf.connect(contrastgen, 'contrasts', cope_sorter, 'contrasts') wf.connect([(preproc, fixed_fx, [(('outputspec.mask', pickfirst), 'flameo.mask_file')]), (modelfit, cope_sorter, [('outputspec.copes', 'copes')]), (modelfit, cope_sorter, [('outputspec.varcopes', 'varcopes')]), (cope_sorter, fixed_fx, [('copes', 'inputspec.copes'), ('varcopes', 'inputspec.varcopes'), ('n_runs', 'l2model.num_copes')]), (modelfit, fixed_fx, [('outputspec.dof_file', 'inputspec.dof_files'), ]) ]) wf.connect(calc_median, 'median_file', registration, 'inputspec.mean_image') if subjects_dir: wf.connect(infosource, 'subject_id', registration, 'inputspec.subject_id') registration.inputs.inputspec.subjects_dir = subjects_dir registration.inputs.inputspec.target_image = fsl.Info.standard_image('MNI152_T1_2mm_brain.nii.gz') if target: registration.inputs.inputspec.target_image = target else: wf.connect(datasource, 'anat', registration, 'inputspec.anatomical_image') registration.inputs.inputspec.target_image = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz') registration.inputs.inputspec.target_image_brain = fsl.Info.standard_image('MNI152_T1_2mm_brain.nii.gz') registration.inputs.inputspec.config_file = 'T1_2_MNI152_2mm' def merge_files(copes, varcopes, zstats): out_files = [] splits = [] out_files.extend(copes) splits.append(len(copes)) out_files.extend(varcopes) splits.append(len(varcopes)) out_files.extend(zstats) splits.append(len(zstats)) return out_files, splits mergefunc = pe.Node(niu.Function(input_names=['copes', 'varcopes', 'zstats'], output_names=['out_files', 'splits'], function=merge_files), name='merge_files') wf.connect([(fixed_fx.get_node('outputspec'), mergefunc, [('copes', 'copes'), ('varcopes', 'varcopes'), ('zstats', 'zstats'), ])]) wf.connect(mergefunc, 'out_files', registration, 'inputspec.source_files') def split_files(in_files, splits): copes = in_files[:splits[0]] varcopes = in_files[splits[0]:(splits[0] + splits[1])] zstats = in_files[(splits[0] + splits[1]):] return copes, varcopes, zstats splitfunc = pe.Node(niu.Function(input_names=['in_files', 'splits'], output_names=['copes', 'varcopes', 'zstats'], function=split_files), name='split_files') wf.connect(mergefunc, 'splits', splitfunc, 'splits') wf.connect(registration, 'outputspec.transformed_files', splitfunc, 'in_files') if subjects_dir: get_roi_mean = pe.MapNode(fs.SegStats(default_color_table=True), iterfield=['in_file'], name='get_aparc_means') get_roi_mean.inputs.avgwf_txt_file = True wf.connect(fixed_fx.get_node('outputspec'), 'copes', get_roi_mean, 'in_file') wf.connect(registration, 'outputspec.aparc', get_roi_mean, 'segmentation_file') get_roi_tsnr = pe.MapNode(fs.SegStats(default_color_table=True), iterfield=['in_file'], name='get_aparc_tsnr') get_roi_tsnr.inputs.avgwf_txt_file = True wf.connect(tsnr, 'tsnr_file', get_roi_tsnr, 'in_file') wf.connect(registration, 'outputspec.aparc', get_roi_tsnr, 'segmentation_file') """ Connect to a datasink """ def get_subs(subject_id, conds, run_id, model_id, task_id): subs = [('_subject_id_%s_' % subject_id, '')] subs.append(('_model_id_%d' % model_id, 'model%03d' %model_id)) subs.append(('task_id_%d/' % task_id, '/task%03d_' % task_id)) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_warp', 'mean')) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_flirt', 'affine')) for i in range(len(conds)): subs.append(('_flameo%d/cope1.' % i, 'cope%02d.' % (i + 1))) subs.append(('_flameo%d/varcope1.' % i, 'varcope%02d.' % (i + 1))) subs.append(('_flameo%d/zstat1.' % i, 'zstat%02d.' % (i + 1))) subs.append(('_flameo%d/tstat1.' % i, 'tstat%02d.' % (i + 1))) subs.append(('_flameo%d/res4d.' % i, 'res4d%02d.' % (i + 1))) subs.append(('_warpall%d/cope1_warp.' % i, 'cope%02d.' % (i + 1))) subs.append(('_warpall%d/varcope1_warp.' % (len(conds) + i), 'varcope%02d.' % (i + 1))) subs.append(('_warpall%d/zstat1_warp.' % (2 * len(conds) + i), 'zstat%02d.' % (i + 1))) subs.append(('_warpall%d/cope1_trans.' % i, 'cope%02d.' % (i + 1))) subs.append(('_warpall%d/varcope1_trans.' % (len(conds) + i), 'varcope%02d.' % (i + 1))) subs.append(('_warpall%d/zstat1_trans.' % (2 * len(conds) + i), 'zstat%02d.' % (i + 1))) subs.append(('__get_aparc_means%d/' % i, '/cope%02d_' % (i + 1))) for i, run_num in enumerate(run_id): subs.append(('__get_aparc_tsnr%d/' % i, '/run%02d_' % run_num)) subs.append(('__art%d/' % i, '/run%02d_' % run_num)) subs.append(('__dilatemask%d/' % i, '/run%02d_' % run_num)) subs.append(('__realign%d/' % i, '/run%02d_' % run_num)) subs.append(('__modelgen%d/' % i, '/run%02d_' % run_num)) subs.append(('/model%03d/task%03d/' % (model_id, task_id), '/')) subs.append(('/model%03d/task%03d_' % (model_id, task_id), '/')) subs.append(('_bold_dtype_mcf_bet_thresh_dil', '_mask')) subs.append(('_output_warped_image', '_anat2target')) subs.append(('median_flirt_brain_mask', 'median_brain_mask')) subs.append(('median_bbreg_brain_mask', 'median_brain_mask')) return subs subsgen = pe.Node(niu.Function(input_names=['subject_id', 'conds', 'run_id', 'model_id', 'task_id'], output_names=['substitutions'], function=get_subs), name='subsgen') wf.connect(subjinfo, 'run_id', subsgen, 'run_id') datasink = pe.Node(interface=nio.DataSink(), name="datasink") wf.connect(infosource, 'subject_id', datasink, 'container') wf.connect(infosource, 'subject_id', subsgen, 'subject_id') wf.connect(infosource, 'model_id', subsgen, 'model_id') wf.connect(infosource, 'task_id', subsgen, 'task_id') wf.connect(contrastgen, 'contrasts', subsgen, 'conds') wf.connect(subsgen, 'substitutions', datasink, 'substitutions') wf.connect([(fixed_fx.get_node('outputspec'), datasink, [('res4d', 'res4d'), ('copes', 'copes'), ('varcopes', 'varcopes'), ('zstats', 'zstats'), ('tstats', 'tstats')]) ]) wf.connect([(modelfit.get_node('modelgen'), datasink, [('design_cov', 'qa.model'), ('design_image', 'qa.model.@matrix_image'), ('design_file', 'qa.model.@matrix'), ])]) wf.connect([(preproc, datasink, [('outputspec.motion_parameters', 'qa.motion'), ('outputspec.motion_plots', 'qa.motion.plots'), ('outputspec.mask', 'qa.mask')])]) wf.connect(registration, 'outputspec.mean2anat_mask', datasink, 'qa.mask.mean2anat') wf.connect(art, 'norm_files', datasink, 'qa.art.@norm') wf.connect(art, 'intensity_files', datasink, 'qa.art.@intensity') wf.connect(art, 'outlier_files', datasink, 'qa.art.@outlier_files') wf.connect(registration, 'outputspec.anat2target', datasink, 'qa.anat2target') wf.connect(tsnr, 'tsnr_file', datasink, 'qa.tsnr.@map') if subjects_dir: wf.connect(registration, 'outputspec.min_cost_file', datasink, 'qa.mincost') wf.connect([(get_roi_tsnr, datasink, [('avgwf_txt_file', 'qa.tsnr'), ('summary_file', 'qa.tsnr.@summary')])]) wf.connect([(get_roi_mean, datasink, [('avgwf_txt_file', 'copes.roi'), ('summary_file', 'copes.roi.@summary')])]) wf.connect([(splitfunc, datasink, [('copes', 'copes.mni'), ('varcopes', 'varcopes.mni'), ('zstats', 'zstats.mni'), ])]) wf.connect(calc_median, 'median_file', datasink, 'mean') wf.connect(registration, 'outputspec.transformed_mean', datasink, 'mean.mni') wf.connect(registration, 'outputspec.func2anat_transform', datasink, 'xfm.mean2anat') wf.connect(registration, 'outputspec.anat2target_transform', datasink, 'xfm.anat2target') """ Set processing parameters """ preproc.inputs.inputspec.fwhm = fwhm gethighpass.inputs.hpcutoff = hpcutoff modelspec.inputs.high_pass_filter_cutoff = hpcutoff modelfit.inputs.inputspec.bases = {'dgamma': {'derivs': use_derivatives}} modelfit.inputs.inputspec.model_serial_correlations = True modelfit.inputs.inputspec.film_threshold = 1000 datasink.inputs.base_directory = output_dir return wf """ The following functions run the whole workflow. """ if __name__ == '__main__': import argparse defstr = ' (default %(default)s)' parser = argparse.ArgumentParser(prog='fmri_openfmri.py', description=__doc__) parser.add_argument('-d', '--datasetdir', required=True) parser.add_argument('-s', '--subject', default=[], nargs='+', type=str, help="Subject name (e.g. 'sub001')") parser.add_argument('-m', '--model', default=1, help="Model index" + defstr) parser.add_argument('-x', '--subjectprefix', default='sub*', help="Subject prefix" + defstr) parser.add_argument('-t', '--task', default=1, #nargs='+', type=int, help="Task index" + defstr) parser.add_argument('--hpfilter', default=120., type=float, help="High pass filter cutoff (in secs)" + defstr) parser.add_argument('--fwhm', default=6., type=float, help="Spatial FWHM" + defstr) parser.add_argument('--derivatives', action="store_true", help="Use derivatives" + defstr) parser.add_argument("-o", "--output_dir", dest="outdir", help="Output directory base") parser.add_argument("-w", "--work_dir", dest="work_dir", help="Output directory base") parser.add_argument("-p", "--plugin", dest="plugin", default='Linear', help="Plugin to use") parser.add_argument("--plugin_args", dest="plugin_args", help="Plugin arguments") parser.add_argument("--sd", dest="subjects_dir", help="FreeSurfer subjects directory (if available)") parser.add_argument("--target", dest="target_file", help=("Target in MNI space. Best to use the MindBoggle " "template - only used with FreeSurfer" "OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz")) args = parser.parse_args() outdir = args.outdir work_dir = os.getcwd() if args.work_dir: work_dir = os.path.abspath(args.work_dir) if outdir: outdir = os.path.abspath(outdir) else: outdir = os.path.join(work_dir, 'output') outdir = os.path.join(outdir, 'model%02d' % int(args.model), 'task%03d' % int(args.task)) derivatives = args.derivatives if derivatives is None: derivatives = False wf = analyze_openfmri_dataset(data_dir=os.path.abspath(args.datasetdir), subject=args.subject, model_id=int(args.model), task_id=[int(args.task)], subj_prefix=args.subjectprefix, output_dir=outdir, hpcutoff=args.hpfilter, use_derivatives=derivatives, fwhm=args.fwhm, subjects_dir=args.subjects_dir, target=args.target_file) #wf.config['execution']['remove_unnecessary_outputs'] = False wf.base_dir = work_dir if args.plugin_args: wf.run(args.plugin, plugin_args=eval(args.plugin_args)) else: wf.run(args.plugin) nipype-0.11.0/examples/fmri_freesurfer_smooth.py000077500000000000000000000544441257611314500220660ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ====================================== fMRI: surface smooth - FreeSurfer, SPM ====================================== This tutorial illustrates how to perform surface-based smoothing of cortical data using FreeSurfer_ and then perform firstlevel model and contrast estimation using SPM_. A surface-based second level glm illustrates the use of spherical registration and freesurfer's glm functions. Preparing environment ===================== Step 0 ------ In order to run this tutorial you need to have SPM_ and FreeSurfer_ tools installed and accessible from matlab/command line. Check by calling mri_info from the command line. Step 1 ------ Link the *fsaverage* directory for your freesurfer distribution. To do this type: :: cd nipype-tutorial/fsdata ln -s $FREESURFER_HOME/subjects/fsaverage cd .. Defining the workflow ===================== """ import os # system functions import nipype.algorithms.modelgen as model # model generation import nipype.algorithms.rapidart as ra # artifact detection import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.io as nio # i/o routines import nipype.interfaces.matlab as mlab # how to run matlab import nipype.interfaces.spm as spm # spm import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine """ Preliminaries ------------- Set any package specific configuration. Setting the subjects directory and the appropriate matlab command to use. if you want to use a different spm version/path, it should also be entered here. These are currently being set at the class level, so every node will inherit these settings. However, these can also be changed or set for an individual node. """ # Tell freesurfer what subjects directory to use subjects_dir = os.path.abspath('fsdata') fs.FSCommand.set_default_subjects_dir(subjects_dir) # Set the way matlab should be called mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") # If SPM is not in your MATLAB path you should add it here mlab.MatlabCommand.set_default_paths('/software/spm8') """ Setup preprocessing workflow ---------------------------- """ preproc = pe.Workflow(name='preproc') """ Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True """ Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = pe.Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' """ Use :class:`nipype.interfaces.freesurfer.BBRegister` to coregister the mean functional image generated by realign to the subjects' surfaces. """ surfregister = pe.Node(interface=fs.BBRegister(),name='surfregister') surfregister.inputs.init = 'fsl' surfregister.inputs.contrast_type = 't2' """ Use :class:`nipype.interfaces.io.FreeSurferSource` to retrieve various image files that are automatically generated by the recon-all process. """ FreeSurferSource = pe.Node(interface=nio.FreeSurferSource(), name='fssource') """ Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert the brainmask generated by freesurfer into the realigned functional space. """ ApplyVolTransform = pe.Node(interface=fs.ApplyVolTransform(), name='applyreg') ApplyVolTransform.inputs.inverse = True """ Use :class:`nipype.interfaces.freesurfer.Binarize` to extract a binary brain mask. """ Threshold = pe.Node(interface=fs.Binarize(),name='threshold') Threshold.inputs.min = 10 Threshold.inputs.out_type = 'nii' """ Two different types of functional data smoothing are performed in this workflow. The volume smoothing option performs a standard SPM smoothin. using :class:`nipype.interfaces.spm.Smooth`. In addition, we use a smoothing routine from freesurfer (:class:`nipype.interfaces.freesurfer.Binarize`) to project the functional data from the volume to the subjects' surface, smooth it on the surface and fit it back into the volume forming the cortical ribbon. The projection uses the average value along a "cortical column". In addition to the surface smoothing, the rest of the volume is smoothed with a 3d gaussian kernel. .. note:: It is very important to note that the projection to the surface takes a 3d manifold to a 2d manifold. Hence the reverse projection, simply fills the thickness of cortex with the smoothed data. The smoothing is not performed in a depth specific manner. The output of this branch should only be used for surface-based analysis and visualization. """ volsmooth = pe.Node(interface=spm.Smooth(), name = "volsmooth") surfsmooth = pe.MapNode(interface=fs.Smooth(proj_frac_avg=(0,1,0.1)), name = "surfsmooth", iterfield=['in_file']) """ We connect up the different nodes to implement the preprocessing workflow. """ preproc.connect([(realign, surfregister,[('mean_image', 'source_file')]), (FreeSurferSource, ApplyVolTransform,[('brainmask','target_file')]), (surfregister, ApplyVolTransform,[('out_reg_file','reg_file')]), (realign, ApplyVolTransform,[('mean_image', 'source_file')]), (ApplyVolTransform, Threshold,[('transformed_file','in_file')]), (realign, art,[('realignment_parameters','realignment_parameters'), ('realigned_files','realigned_files')]), (Threshold, art, [('binary_file', 'mask_file')]), (realign, volsmooth, [('realigned_files', 'in_files')]), (realign, surfsmooth, [('realigned_files', 'in_file')]), (surfregister, surfsmooth, [('out_reg_file','reg_file')]), ]) """ Set up volume analysis workflow ------------------------------- """ volanalysis = pe.Workflow(name='volanalysis') """ Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") modelspec.inputs.concatenate_runs = True """ Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} """ Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} """ Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") volanalysis.connect([(modelspec,level1design,[('session_info','session_info')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), ]) """ Set up surface analysis workflow -------------------------------- We simply clone the volume analysis workflow. """ surfanalysis = volanalysis.clone(name='surfanalysis') """ Set up volume normalization workflow ------------------------------------ The volume analysis is performed in individual space. Therefore, post analysis we normalize the contrast images to MNI space. """ volnorm = pe.Workflow(name='volnormconimages') """ Use :class:`nipype.interfaces.freesurfer.MRIConvert` to convert the brainmask, an mgz file and the contrast images (nifti-1 img/hdr pairs), to single volume nifti images. """ convert = pe.Node(interface=fs.MRIConvert(out_type='nii'),name='convert2nii') convert2 = pe.MapNode(interface=fs.MRIConvert(out_type='nii'), iterfield=['in_file'], name='convertimg2nii') """ Use :class:`nipype.interfaces.spm.Segment` to segment the structural image and generate the transformation file to MNI space. .. note:: Segment takes longer than usual because the nose is wrapped behind the head in the structural image. """ segment = pe.Node(interface=spm.Segment(), name='segment') """ Use :class:`nipype.interfaces.freesurfer.ApplyVolTransform` to convert contrast images into freesurfer space. """ normwreg = pe.MapNode(interface=fs.ApplyVolTransform(), iterfield=['source_file'], name='applyreg2con') """ Use :class:`nipype.interfaces.spm.Normalize` to normalize the contrast images to MNI space """ normalize = pe.Node(interface=spm.Normalize(jobtype='write'), name='norm2mni') """ Connect up the volume normalization components """ volnorm.connect([(convert, segment, [('out_file','data')]), (convert2, normwreg, [('out_file', 'source_file')]), (segment, normalize, [('transformation_mat', 'parameter_file')]), (normwreg, normalize, [('transformed_file','apply_to_files')]), ]) """ Preproc + Analysis + VolumeNormalization workflow ------------------------------------------------- Connect up the lower level workflows into an integrated analysis. In addition, we add an input node that specifies all the inputs needed for this workflow. Thus, one can import this workflow and connect it to their own data sources. An example with the nifti-tutorial data is provided below. For this workflow the only necessary inputs are the functional images, a freesurfer subject id corresponding to recon-all processed data, the session information for the functional runs and the contrasts to be evaluated. """ inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'subject_id', 'session_info', 'contrasts']), name='inputnode') """ Connect the components into an integrated workflow. """ l1pipeline = pe.Workflow(name='firstlevel') l1pipeline.connect([(inputnode,preproc,[('func','realign.in_files'), ('subject_id','surfregister.subject_id'), ('subject_id','fssource.subject_id'), ]), (inputnode, volanalysis,[('session_info','modelspec.subject_info'), ('contrasts','contrastestimate.contrasts')]), (inputnode, surfanalysis,[('session_info','modelspec.subject_info'), ('contrasts','contrastestimate.contrasts')]), ]) # attach volume and surface model specification and estimation components l1pipeline.connect([(preproc, volanalysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters'), ('volsmooth.smoothed_files', 'modelspec.functional_runs'), ('art.outlier_files', 'modelspec.outlier_files'), ('threshold.binary_file', 'level1design.mask_image')]), (preproc, surfanalysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters'), ('surfsmooth.smoothed_file', 'modelspec.functional_runs'), ('art.outlier_files', 'modelspec.outlier_files'), ('threshold.binary_file', 'level1design.mask_image')]) ]) # attach volume contrast normalization components l1pipeline.connect([(preproc, volnorm, [('fssource.orig','convert2nii.in_file'), ('surfregister.out_reg_file','applyreg2con.reg_file'), ('fssource.orig','applyreg2con.target_file')]), (volanalysis, volnorm, [('contrastestimate.con_images', 'convertimg2nii.in_file'), ]) ]) """ Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1', 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Set preprocessing parameters ---------------------------- """ l1pipeline.inputs.preproc.fssource.subjects_dir = subjects_dir l1pipeline.inputs.preproc.volsmooth.fwhm = 4 l1pipeline.inputs.preproc.surfsmooth.surface_fwhm = 5 l1pipeline.inputs.preproc.surfsmooth.vol_fwhm = 4 """ Experimental paradigm specific components ----------------------------------------- Here we create a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names], )) return output """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrasts = [cont1,cont2] """ Set up node specific inputs --------------------------- We replicate the modelspec parameters separately for the surface- and volume-based analysis. """ modelspecref = l1pipeline.inputs.volanalysis.modelspec modelspecref.input_units = 'secs' modelspecref.time_repetition = 3. modelspecref.high_pass_filter_cutoff = 120 modelspecref = l1pipeline.inputs.surfanalysis.modelspec modelspecref.input_units = 'secs' modelspecref.time_repetition = 3. modelspecref.high_pass_filter_cutoff = 120 l1designref = l1pipeline.inputs.volanalysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1designref = l1pipeline.inputs.surfanalysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1pipeline.inputs.inputnode.contrasts = contrasts """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Workfow` to create a graph-based execution pipeline for first level analysis. """ level1 = pe.Workflow(name="level1") level1.base_dir = os.path.abspath('volsurf_tutorial/workingdir') level1.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,l1pipeline,[('func','inputnode.func')]), (infosource,l1pipeline,[('subject_id','inputnode.subject_id'), (('subject_id', subjectinfo), 'inputnode.session_info')]), ]) """ Store the output ---------------- Create a datasink node to store the contrast images and registration info """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('volsurf_tutorial/l1out') datasink.inputs.substitutions = [] def getsubs(subject_id): subs = [('_subject_id_%s/'%subject_id,'')] return subs # store relevant outputs from various stages of the 1st level analysis level1.connect([(infosource, datasink,[('subject_id','container'), (('subject_id', getsubs), 'substitutions') ]), (l1pipeline, datasink,[('surfanalysis.contrastestimate.con_images','contrasts'), ('preproc.surfregister.out_reg_file','registrations'), ]) ]) """ Run the analysis pipeline and also create a dot+png (if graphviz is available) that visually represents the workflow. """ if __name__ == '__main__': level1.run() level1.write_graph(graph2use='flat') """ Level2 surface-based pipeline ----------------------------- Create a level2 workflow """ l2flow = pe.Workflow(name='l2out') l2flow.base_dir = os.path.abspath('volsurf_tutorial') """ Setup a dummy node to iterate over contrasts and hemispheres """ l2inputnode = pe.Node(interface=util.IdentityInterface(fields=['contrasts', 'hemi']), name='inputnode') l2inputnode.iterables = [('contrasts', range(1,len(contrasts)+1)), ('hemi', ['lh','rh'])] """ Use a datagrabber node to collect contrast images and registration files """ l2source = pe.Node(interface=nio.DataGrabber(infields=['con_id'], outfields=['con','reg']), name='l2source') l2source.inputs.base_directory = os.path.abspath('volsurf_tutorial/l1out') l2source.inputs.template = '*' l2source.inputs.field_template = dict(con='*/contrasts/con_%04d.img', reg='*/registrations/*.dat') l2source.inputs.template_args = dict(con=[['con_id']],reg=[[]]) l2source.inputs.sort_filelist = True l2flow.connect(l2inputnode, 'contrasts', l2source, 'con_id') """ Merge contrast images and registration files """ mergenode = pe.Node(interface=util.Merge(2, axis='hstack'), name='merge') def ordersubjects(files, subj_list): outlist = [] for s in subj_list: for f in files: if '/%s/'%s in f: outlist.append(f) continue print outlist return outlist l2flow.connect(l2source,('con', ordersubjects, subject_list), mergenode, 'in1') l2flow.connect(l2source,('reg', ordersubjects, subject_list), mergenode, 'in2') """ Concatenate contrast images projected to fsaverage """ l2concat = pe.Node(interface=fs.MRISPreproc(), name='concat') l2concat.inputs.target = 'fsaverage' l2concat.inputs.fwhm = 5 def list2tuple(listoflist): return [tuple(x) for x in listoflist] l2flow.connect(l2inputnode, 'hemi', l2concat, 'hemi') l2flow.connect(mergenode, ('out', list2tuple), l2concat, 'vol_measure_file') """ Perform a one sample t-test """ l2ttest = pe.Node(interface=fs.OneSampleTTest(), name='onesample') l2flow.connect(l2concat, 'out_file', l2ttest, 'in_file') """ Run the analysis pipeline and also create a dot+png (if graphviz is available) that visually represents the workflow. """ if __name__ == '__main__': l2flow.run() l2flow.write_graph(graph2use='flat') nipype-0.11.0/examples/fmri_fsl.py000077500000000000000000000525221257611314500171040ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ========= fMRI: FSL ========= A workflow that uses fsl to perform a first level analysis on the nipype tutorial data set:: python fmri_fsl.py First tell python where to find the appropriate functions. """ import os # system functions import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model generation import nipype.algorithms.rapidart as ra # artifact detection """ Preliminaries ------------- Setup any package specific configuration. The output file format for FSL routines is being set to compressed NIFTI. """ fsl.FSLCommand.set_default_output_type('NIFTI_GZ') """ Setting up workflows -------------------- In this tutorial we will be setting up a hierarchical workflow for fsl analysis. This will demonstrate how pre-defined workflows can be setup and shared across users, projects and labs. Setup preprocessing workflow ---------------------------- This is a generic fsl feat preprocessing workflow encompassing skull stripping, motion correction and smoothing operations. """ preproc = pe.Workflow(name='preproc') """ Set up a node to define all inputs required for the preprocessing workflow """ inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'struct',]), name='inputspec') """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') preproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the middle volume of the first run as the reference """ extract_ref = pe.Node(interface=fsl.ExtractROI(t_size=1), name = 'extractref') """ Define a function to pick the first file from a list of files """ def pickfirst(files): if isinstance(files, list): return files[0] else: return files preproc.connect(img2float, ('out_file', pickfirst), extract_ref, 'in_file') """ Define a function to return the 1 based index of the middle volume """ def getmiddlevolume(func): from nibabel import load funcfile = func if isinstance(func, list): funcfile = func[0] _,_,_,timepoints = load(funcfile).get_shape() return (timepoints/2)-1 preproc.connect(inputnode, ('func', getmiddlevolume), extract_ref, 't_min') """ Realign the functional runs to the middle volume of the first run """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True), name='realign', iterfield = ['in_file']) preproc.connect(img2float, 'out_file', motion_correct, 'in_file') preproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) preproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') """ Extract the mean volume of the first functional run """ meanfunc = pe.Node(interface=fsl.ImageMaths(op_string = '-Tmean', suffix='_mean'), name='meanfunc') preproc.connect(motion_correct, ('out_file', pickfirst), meanfunc, 'in_file') """ Strip the skull from the mean functional to generate a mask """ meanfuncmask = pe.Node(interface=fsl.BET(mask = True, no_output=True, frac = 0.3), name = 'meanfuncmask') preproc.connect(meanfunc, 'out_file', meanfuncmask, 'in_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file'], name = 'maskfunc') preproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') preproc.connect(meanfuncmask, 'mask_file', maskfunc, 'in_file2') """ Determine the 2nd and 98th percentile intensities of each functional run """ getthresh = pe.MapNode(interface=fsl.ImageStats(op_string='-p 2 -p 98'), iterfield = ['in_file'], name='getthreshold') preproc.connect(maskfunc, 'out_file', getthresh, 'in_file') """ Threshold the first run of the functional data at 10% of the 98th percentile """ threshold = pe.Node(interface=fsl.ImageMaths(out_data_type='char', suffix='_thresh'), name='threshold') preproc.connect(maskfunc, ('out_file', pickfirst), threshold, 'in_file') """ Define a function to get 10% of the intensity """ def getthreshop(thresh): return '-thr %.10f -Tmin -bin'%(0.1*thresh[0][1]) preproc.connect(getthresh, ('out_stat', getthreshop), threshold, 'op_string') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file'], name='medianval') preproc.connect(motion_correct, 'out_file', medianval, 'in_file') preproc.connect(threshold, 'out_file', medianval, 'mask_file') """ Dilate the mask """ dilatemask = pe.Node(interface=fsl.ImageMaths(suffix='_dil', op_string='-dilF'), name='dilatemask') preproc.connect(threshold, 'out_file', dilatemask, 'in_file') """ Mask the motion corrected functional runs with the dilated mask """ maskfunc2 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file'], name='maskfunc2') preproc.connect(motion_correct, 'out_file', maskfunc2, 'in_file') preproc.connect(dilatemask, 'out_file', maskfunc2, 'in_file2') """ Determine the mean image from each functional run """ meanfunc2 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc2') preproc.connect(maskfunc2, 'out_file', meanfunc2, 'in_file') """ Merge the median values with the mean functional images into a coupled list """ mergenode = pe.Node(interface=util.Merge(2, axis='hstack'), name='merge') preproc.connect(meanfunc2,'out_file', mergenode, 'in1') preproc.connect(medianval,'out_stat', mergenode, 'in2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask constituting the mean functional """ smooth = pe.MapNode(interface=fsl.SUSAN(), iterfield=['in_file', 'brightness_threshold','usans'], name='smooth') """ Define a function to get the brightness threshold for SUSAN """ def getbtthresh(medianvals): return [0.75*val for val in medianvals] def getusans(x): return [[tuple([val[0],0.75*val[1]])] for val in x] preproc.connect(maskfunc2, 'out_file', smooth, 'in_file') preproc.connect(medianval, ('out_stat', getbtthresh), smooth, 'brightness_threshold') preproc.connect(mergenode, ('out', getusans), smooth, 'usans') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file'], name='maskfunc3') preproc.connect(smooth, 'smoothed_file', maskfunc3, 'in_file') preproc.connect(dilatemask, 'out_file', maskfunc3, 'in_file2') """ Scale each volume of the run so that the median value of the run is set to 10000 """ intnorm = pe.MapNode(interface=fsl.ImageMaths(suffix='_intnorm'), iterfield=['in_file','op_string'], name='intnorm') preproc.connect(maskfunc3, 'out_file', intnorm, 'in_file') """ Define a function to get the scaling factor for intensity normalization """ def getinormscale(medianvals): return ['-mul %.10f'%(10000./val) for val in medianvals] preproc.connect(medianval, ('out_stat', getinormscale), intnorm, 'op_string') """ Perform temporal highpass filtering on the data """ highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') preproc.connect(intnorm, 'out_file', highpass, 'in_file') """ Generate a mean functional image from the first run """ meanfunc3 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc3') preproc.connect(highpass, ('out_file', pickfirst), meanfunc3, 'in_file') """ Strip the structural image and coregister the mean functional image to the structural image """ nosestrip = pe.Node(interface=fsl.BET(frac=0.3), name = 'nosestrip') skullstrip = pe.Node(interface=fsl.BET(mask = True), name = 'stripstruct') coregister = pe.Node(interface=fsl.FLIRT(dof=6), name = 'coregister') """ Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity and/or movement. """ art = pe.MapNode(interface=ra.ArtifactDetect(use_differences = [True, False], use_norm = True, norm_threshold = 1, zintensity_threshold = 3, parameter_source = 'FSL', mask_type = 'file'), iterfield=['realigned_files', 'realignment_parameters'], name="art") preproc.connect([(inputnode, nosestrip,[('struct','in_file')]), (nosestrip, skullstrip, [('out_file','in_file')]), (skullstrip, coregister,[('out_file','in_file')]), (meanfunc2, coregister,[(('out_file',pickfirst),'reference')]), (motion_correct, art, [('par_file','realignment_parameters')]), (maskfunc2, art, [('out_file','realigned_files')]), (dilatemask, art, [('out_file', 'mask_file')]), ]) """ Set up model fitting workflow ----------------------------- """ modelfit = pe.Workflow(name='modelfit') """ Use :class:`nipype.algorithms.modelgen.SpecifyModel` to generate design information. """ modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") """ Use :class:`nipype.interfaces.fsl.Level1Design` to generate a run specific fsf file for analysis """ level1design = pe.Node(interface=fsl.Level1Design(), name="level1design") """ Use :class:`nipype.interfaces.fsl.FEATModel` to generate a run specific mat file for use by FILMGLS """ modelgen = pe.MapNode(interface=fsl.FEATModel(), name='modelgen', iterfield = ['fsf_file', 'ev_files']) """ Use :class:`nipype.interfaces.fsl.FILMGLS` to estimate a model specified by a mat file and a functional run """ modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True, mask_size=5, threshold=1000), name='modelestimate', iterfield = ['design_file','in_file']) """ Use :class:`nipype.interfaces.fsl.ContrastMgr` to generate contrast estimates """ conestimate = pe.MapNode(interface=fsl.ContrastMgr(), name='conestimate', iterfield = ['tcon_file','param_estimates', 'sigmasquareds', 'corrections', 'dof_file']) modelfit.connect([ (modelspec,level1design,[('session_info','session_info')]), (level1design,modelgen,[('fsf_files', 'fsf_file'), ('ev_files', 'ev_files')]), (modelgen,modelestimate,[('design_file','design_file')]), (modelgen,conestimate,[('con_file','tcon_file')]), (modelestimate,conestimate,[('param_estimates','param_estimates'), ('sigmasquareds', 'sigmasquareds'), ('corrections','corrections'), ('dof_file','dof_file')]), ]) """ Set up fixed-effects workflow ----------------------------- """ fixed_fx = pe.Workflow(name='fixedfx') """ Use :class:`nipype.interfaces.fsl.Merge` to merge the copes and varcopes for each condition """ copemerge = pe.MapNode(interface=fsl.Merge(dimension='t'), iterfield=['in_files'], name="copemerge") varcopemerge = pe.MapNode(interface=fsl.Merge(dimension='t'), iterfield=['in_files'], name="varcopemerge") """ Use :class:`nipype.interfaces.fsl.L2Model` to generate subject and condition specific level 2 model design files """ level2model = pe.Node(interface=fsl.L2Model(), name='l2model') """ Use :class:`nipype.interfaces.fsl.FLAMEO` to estimate a second level model """ flameo = pe.MapNode(interface=fsl.FLAMEO(run_mode='fe'), name="flameo", iterfield=['cope_file','var_cope_file']) fixed_fx.connect([(copemerge,flameo,[('merged_file','cope_file')]), (varcopemerge,flameo,[('merged_file','var_cope_file')]), (level2model,flameo, [('design_mat','design_file'), ('design_con','t_con_file'), ('design_grp','cov_split_file')]), ]) """ Set up first-level workflow --------------------------- """ def sort_copes(files): numelements = len(files[0]) outfiles = [] for i in range(numelements): outfiles.insert(i,[]) for j, elements in enumerate(files): outfiles[i].append(elements[i]) return outfiles def num_copes(files): return len(files) firstlevel = pe.Workflow(name='firstlevel') firstlevel.connect([(preproc, modelfit, [('highpass.out_file', 'modelspec.functional_runs'), ('art.outlier_files', 'modelspec.outlier_files'), ('highpass.out_file','modelestimate.in_file')]), (preproc, fixed_fx, [('coregister.out_file', 'flameo.mask_file')]), (modelfit, fixed_fx,[(('conestimate.copes', sort_copes),'copemerge.in_files'), (('conestimate.varcopes', sort_copes),'varcopemerge.in_files'), (('conestimate.copes', num_copes),'l2model.num_copes'), ]) ]) """ Experiment specific components ------------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1'] #, 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Use the get_node function to retrieve an internal node by name. Then set the iterables on this node to perform two different extents of smoothing. """ smoothnode = firstlevel.get_node('preproc.smooth') assert(str(smoothnode)=='preproc.smooth') smoothnode.iterables = ('fwhm', [5.,10.]) hpcutoff = 120 TR = 3. firstlevel.inputs.preproc.highpass.suffix = '_hpf' firstlevel.inputs.preproc.highpass.op_string = '-bptf %d -1'%(hpcutoff/TR) """ Setup a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. Other examples of this function are available in the `doc/examples` folder. Note: Python knowledge required here. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)) return output """ Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ['Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]] cont2 = ['Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]] cont3 = ['Task','F', [cont1, cont2]] contrasts = [cont1,cont2] firstlevel.inputs.modelfit.modelspec.input_units = 'secs' firstlevel.inputs.modelfit.modelspec.time_repetition = TR firstlevel.inputs.modelfit.modelspec.high_pass_filter_cutoff = hpcutoff firstlevel.inputs.modelfit.level1design.interscan_interval = TR firstlevel.inputs.modelfit.level1design.bases = {'dgamma':{'derivs': False}} firstlevel.inputs.modelfit.level1design.contrasts = contrasts firstlevel.inputs.modelfit.level1design.model_serial_correlations = True """ Set up complete workflow ======================== """ l1pipeline = pe.Workflow(name= "level1") l1pipeline.base_dir = os.path.abspath('./fsl/workingdir') l1pipeline.config = {"execution": {"crashdump_dir":os.path.abspath('./fsl/crashdumps')}} l1pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (infosource, firstlevel, [(('subject_id', subjectinfo), 'modelfit.modelspec.subject_info')]), (datasource, firstlevel, [('struct','preproc.inputspec.struct'), ('func', 'preproc.inputspec.func'), ]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': l1pipeline.write_graph() outgraph = l1pipeline.run() #l1pipeline.run(plugin='MultiProc', plugin_args={'n_procs':2}) nipype-0.11.0/examples/fmri_fsl_feeds.py000077500000000000000000000126611257611314500202520ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ================= fMRI: FEEDS - FSL ================= A pipeline example that data from the FSL FEEDS set. Single subject, two stimuli. You can find it at http://www.fmrib.ox.ac.uk/fsl/feeds/doc/index.html """ import os # system functions import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model generation from nipype.workflows.fmri.fsl import (create_featreg_preproc, create_modelfit_workflow, create_reg_workflow) from nipype.interfaces.base import Bunch """ Preliminaries ------------- Setup any package specific configuration. The output file format for FSL routines is being set to compressed NIFTI. """ fsl.FSLCommand.set_default_output_type('NIFTI_GZ') """ Experiment specific components ------------------------------ This tutorial does a single subject analysis so we are not using infosource and iterables """ # Specify the location of the FEEDS data. You can find it at http://www.fmrib.ox.ac.uk/fsl/feeds/doc/index.html feeds_data_dir = os.path.abspath('feeds/data') # Specify the subject directories # Map field names to individual subject runs. info = dict(func=[['fmri']], struct=[['structural']]) """ Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = feeds_data_dir datasource.inputs.template = '%s.nii.gz' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True preproc = create_featreg_preproc(whichvol='first') TR = 3. preproc.inputs.inputspec.fwhm = 5 preproc.inputs.inputspec.highpass = 100/TR modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") modelspec.inputs.input_units = 'secs' modelspec.inputs.time_repetition = TR modelspec.inputs.high_pass_filter_cutoff = 100 modelspec.inputs.subject_info = [Bunch(conditions=['Visual','Auditory'], onsets=[range(0,int(180*TR),60),range(0,int(180*TR),90)], durations=[[30], [45]], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)] modelfit = create_modelfit_workflow(f_contrasts=True) modelfit.inputs.inputspec.interscan_interval = TR modelfit.inputs.inputspec.model_serial_correlations = True modelfit.inputs.inputspec.bases = {'dgamma': {'derivs': True}} cont1 = ['Visual>Baseline','T', ['Visual','Auditory'],[1,0]] cont2 = ['Auditory>Baseline','T', ['Visual','Auditory'],[0,1]] cont3 = ['Task','F', [cont1, cont2]] modelfit.inputs.inputspec.contrasts = [cont1,cont2,cont3] registration = create_reg_workflow() registration.inputs.inputspec.target_image = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz') registration.inputs.inputspec.target_image_brain = fsl.Info.standard_image('MNI152_T1_2mm_brain.nii.gz') registration.inputs.inputspec.config_file = 'T1_2_MNI152_2mm' """ Set up complete workflow ======================== """ l1pipeline = pe.Workflow(name= "level1") l1pipeline.base_dir = os.path.abspath('./fsl_feeds/workingdir') l1pipeline.config = {"execution": {"crashdump_dir":os.path.abspath('./fsl_feeds/crashdumps')}} l1pipeline.connect(datasource, 'func', preproc,'inputspec.func') l1pipeline.connect(preproc, 'outputspec.highpassed_files', modelspec, 'functional_runs') l1pipeline.connect(preproc, 'outputspec.motion_parameters', modelspec, 'realignment_parameters') l1pipeline.connect(modelspec, 'session_info', modelfit, 'inputspec.session_info') l1pipeline.connect(preproc, 'outputspec.highpassed_files', modelfit, 'inputspec.functional_data') l1pipeline.connect(preproc, 'outputspec.mean', registration, 'inputspec.mean_image') l1pipeline.connect(datasource, 'struct', registration, 'inputspec.anatomical_image') l1pipeline.connect(modelfit, 'outputspec.zfiles', registration, 'inputspec.source_files') """ Setup the datasink """ datasink = pe.Node(interface=nio.DataSink(parameterization=False), name="datasink") datasink.inputs.base_directory = os.path.abspath('./fsl_feeds/l1out') datasink.inputs.substitutions = [('fmri_dtype_mcf_mask_smooth_mask_gms_mean_warp', 'meanfunc')] # store relevant outputs from various stages of the 1st level analysis l1pipeline.connect(registration, 'outputspec.transformed_files', datasink, 'level1.@Z') l1pipeline.connect(registration, 'outputspec.transformed_mean', datasink, 'meanfunc') """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': l1pipeline.run() nipype-0.11.0/examples/fmri_fsl_reuse.py000077500000000000000000000231511257611314500203030ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ========================= fMRI: FSL reuse workflows ========================= A workflow that uses fsl to perform a first level analysis on the nipype tutorial data set:: python fmri_fsl_reuse.py First tell python where to find the appropriate functions. """ import os # system functions import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model generation import nipype.algorithms.rapidart as ra # artifact detection from nipype.workflows.fmri.fsl import (create_featreg_preproc, create_modelfit_workflow, create_fixed_effects_flow) """ Preliminaries ------------- Setup any package specific configuration. The output file format for FSL routines is being set to compressed NIFTI. """ fsl.FSLCommand.set_default_output_type('NIFTI_GZ') level1_workflow = pe.Workflow(name='level1flow') preproc = create_featreg_preproc(whichvol='first') modelfit = create_modelfit_workflow() fixed_fx = create_fixed_effects_flow() """ Add artifact detection and model specification nodes between the preprocessing and modelfitting workflows. """ art = pe.MapNode(interface=ra.ArtifactDetect(use_differences = [True, False], use_norm = True, norm_threshold = 1, zintensity_threshold = 3, parameter_source = 'FSL', mask_type = 'file'), iterfield=['realigned_files', 'realignment_parameters', 'mask_file'], name="art") modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") level1_workflow.connect([(preproc, art, [('outputspec.motion_parameters', 'realignment_parameters'), ('outputspec.realigned_files', 'realigned_files'), ('outputspec.mask', 'mask_file')]), (preproc, modelspec, [('outputspec.highpassed_files', 'functional_runs'), ('outputspec.motion_parameters', 'realignment_parameters')]), (art, modelspec, [('outlier_files', 'outlier_files')]), (modelspec, modelfit, [('session_info', 'inputspec.session_info')]), (preproc, modelfit, [('outputspec.highpassed_files', 'inputspec.functional_data')]) ]) """ Set up first-level workflow --------------------------- """ def sort_copes(files): numelements = len(files[0]) outfiles = [] for i in range(numelements): outfiles.insert(i,[]) for j, elements in enumerate(files): outfiles[i].append(elements[i]) return outfiles def num_copes(files): return len(files) pickfirst = lambda x : x[0] level1_workflow.connect([(preproc, fixed_fx, [(('outputspec.mask', pickfirst), 'flameo.mask_file')]), (modelfit, fixed_fx, [(('outputspec.copes', sort_copes), 'inputspec.copes'), ('outputspec.dof_file', 'inputspec.dof_files'), (('outputspec.varcopes', sort_copes), 'inputspec.varcopes'), (('outputspec.copes', num_copes), 'l2model.num_copes'), ]) ]) """ Experiment specific components ------------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1'] #, 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Use the get_node function to retrieve an internal node by name. Then set the iterables on this node to perform two different extents of smoothing. """ inputnode = level1_workflow.get_node('featpreproc.inputspec') inputnode.iterables = ('fwhm', [5.,10.]) hpcutoff = 120. TR = 3. inputnode.inputs.highpass = hpcutoff/(2*TR) """ Setup a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.modelgen.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. Other examples of this function are available in the `doc/examples` folder. Note: Python knowledge required here. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names])) return output """ Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ['Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]] cont2 = ['Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]] cont3 = ['Task','F', [cont1, cont2]] contrasts = [cont1,cont2] modelspec.inputs.input_units = 'secs' modelspec.inputs.time_repetition = TR modelspec.inputs.high_pass_filter_cutoff = hpcutoff modelfit.inputs.inputspec.interscan_interval = TR modelfit.inputs.inputspec.bases = {'dgamma':{'derivs': False}} modelfit.inputs.inputspec.contrasts = contrasts modelfit.inputs.inputspec.model_serial_correlations = True modelfit.inputs.inputspec.film_threshold = 1000 level1_workflow.base_dir = os.path.abspath('./fsl/workingdir') level1_workflow.config['execution'] = dict(crashdump_dir=os.path.abspath('./fsl/crashdumps')) level1_workflow.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (infosource, modelspec, [(('subject_id', subjectinfo), 'subject_info')]), (datasource, preproc, [('func', 'inputspec.func')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': #level1_workflow.write_graph() level1_workflow.run() #level1_workflow.run(plugin='MultiProc', plugin_args={'n_procs':2}) nipype-0.11.0/examples/fmri_nipy_glm.py000077500000000000000000000246751257611314500201460ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ =================== fMRI: NiPy GLM, SPM =================== The fmri_nipy_glm.py integrates several interfaces to perform a first level analysis on a two-subject data set. It is very similar to the spm_tutorial with the difference of using nipy for fitting GLM model and estimating contrasts. The tutorial can be found in the examples folder. Run the tutorial from inside the nipype tutorial directory:: python fmri_nipy_glm.py """ from nipype.interfaces.nipy.model import FitGLM, EstimateContrast from nipype.interfaces.nipy.preprocess import ComputeMask """Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.interfaces.matlab as mlab # how to run matlab import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.rapidart as ra # artifact detection import nipype.algorithms.modelgen as model # model specification import os # system functions """ Preliminaries ------------- Set any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Set the way matlab should be called mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") """The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Preprocessing pipeline nodes ---------------------------- Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True compute_mask = pe.Node(interface=ComputeMask(), name="compute_mask") """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = pe.Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name = "smooth") smooth.inputs.fwhm = 4 """ Set up analysis components -------------------------- Here we create a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)) return output """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrasts = [cont1,cont2] """Generate design information using :class:`nipype.interfaces.spm.SpecifyModel`. nipy accepts only design specified in seconds so "output_units" has always have to be set to "secs". """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") modelspec.inputs.concatenate_runs = True modelspec.inputs.input_units = 'secs' modelspec.inputs.output_units = 'secs' modelspec.inputs.time_repetition = 3. modelspec.inputs.high_pass_filter_cutoff = 120 """Fit the GLM model using nipy and ordinary least square method """ model_estimate = pe.Node(interface=FitGLM(), name="model_estimate") model_estimate.inputs.TR = 3. model_estimate.inputs.model = "spherical" model_estimate.inputs.method = "ols" """Estimate the contrasts. The format of the contrasts definition is the same as for FSL and SPM """ contrast_estimate = pe.Node(interface=EstimateContrast(), name="contrast_estimate") cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrast_estimate.inputs.contrasts = [cont1,cont2] """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ l1pipeline = pe.Workflow(name="level1") l1pipeline.base_dir = os.path.abspath('nipy_tutorial/workingdir') l1pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,realign,[('func','in_files')]), (realign, compute_mask, [('mean_image','mean_volume')]), (realign, coregister,[('mean_image', 'source'), ('realigned_files','apply_to_files')]), (datasource, coregister,[('struct', 'target')]), (coregister, smooth, [('coregistered_files', 'in_files')]), (realign, modelspec,[('realignment_parameters','realignment_parameters')]), (smooth, modelspec,[('smoothed_files','functional_runs')]), (realign, art,[('realignment_parameters','realignment_parameters')]), (coregister, art,[('coregistered_files','realigned_files')]), (compute_mask,art,[('brain_mask','mask_file')]), (art, modelspec,[('outlier_files','outlier_files')]), (infosource, modelspec, [(("subject_id", subjectinfo), "subject_info")]), (modelspec, model_estimate,[('session_info','session_info')]), (compute_mask, model_estimate, [('brain_mask','mask')]), (model_estimate, contrast_estimate, [("beta","beta"), ("nvbeta","nvbeta"), ("s2","s2"), ("dof", "dof"), ("axis", "axis"), ("constants", "constants"), ("reg_names", "reg_names")]) ]) if __name__ == '__main__': l1pipeline.run() nipype-0.11.0/examples/fmri_openfmri.py000077500000000000000000000466401257611314500201430ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ============================ fMRI: OpenfMRI.org data, FSL ============================ A growing number of datasets are available on `OpenfMRI `_. This script demonstrates how to use nipype to analyze a data set:: python fmri_openfmri.py --datasetdir ds107 """ from nipype import config #config.enable_provenance() from nipype.external import six from glob import glob import os import nipype.pipeline.engine as pe import nipype.algorithms.modelgen as model import nipype.algorithms.rapidart as ra import nipype.interfaces.fsl as fsl import nipype.interfaces.io as nio import nipype.interfaces.utility as niu from nipype.workflows.fmri.fsl import (create_featreg_preproc, create_modelfit_workflow, create_fixed_effects_flow, create_reg_workflow) fsl.FSLCommand.set_default_output_type('NIFTI_GZ') def get_subjectinfo(subject_id, base_dir, task_id, model_id): """Get info for a given subject Parameters ---------- subject_id : string Subject identifier (e.g., sub001) base_dir : string Path to base directory of the dataset task_id : int Which task to process model_id : int Which model to process Returns ------- run_ids : list of ints Run numbers conds : list of str Condition names TR : float Repetition time """ from glob import glob import os import numpy as np condition_info = [] cond_file = os.path.join(base_dir, 'models', 'model%03d' % model_id, 'condition_key.txt') with open(cond_file, 'rt') as fp: for line in fp: info = line.strip().split() condition_info.append([info[0], info[1], ' '.join(info[2:])]) if len(condition_info) == 0: raise ValueError('No condition info found in %s' % cond_file) taskinfo = np.array(condition_info) n_tasks = len(np.unique(taskinfo[:, 0])) conds = [] run_ids = [] if task_id > n_tasks: raise ValueError('Task id %d does not exist' % task_id) for idx in range(n_tasks): taskidx = np.where(taskinfo[:, 0] == 'task%03d' % (idx + 1)) conds.append([condition.replace(' ', '_') for condition in taskinfo[taskidx[0], 2]]) files = glob(os.path.join(base_dir, subject_id, 'BOLD', 'task%03d_run*' % (idx + 1))) run_ids.insert(idx, range(1, len(files) + 1)) TR = np.genfromtxt(os.path.join(base_dir, 'scan_key.txt'))[1] return run_ids[task_id - 1], conds[task_id - 1], TR def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, task_id=None, output_dir=None, subj_prefix='*'): """Analyzes an open fmri dataset Parameters ---------- data_dir : str Path to the base data directory work_dir : str Nipype working directory (defaults to cwd) """ """ Load nipype workflows """ preproc = create_featreg_preproc(whichvol='first') modelfit = create_modelfit_workflow() fixed_fx = create_fixed_effects_flow() registration = create_reg_workflow() """ Remove the plotting connection so that plot iterables don't propagate to the model stage """ preproc.disconnect(preproc.get_node('plot_motion'), 'out_file', preproc.get_node('outputspec'), 'motion_plots') """ Set up openfmri data specific components """ subjects = sorted([path.split(os.path.sep)[-1] for path in glob(os.path.join(data_dir, subj_prefix))]) infosource = pe.Node(niu.IdentityInterface(fields=['subject_id', 'model_id', 'task_id']), name='infosource') if len(subject) == 0: infosource.iterables = [('subject_id', subjects), ('model_id', [model_id]), ('task_id', task_id)] else: infosource.iterables = [('subject_id', [subjects[subjects.index(subj)] for subj in subject]), ('model_id', [model_id]), ('task_id', task_id)] subjinfo = pe.Node(niu.Function(input_names=['subject_id', 'base_dir', 'task_id', 'model_id'], output_names=['run_id', 'conds', 'TR'], function=get_subjectinfo), name='subjectinfo') subjinfo.inputs.base_dir = data_dir """ Return data components as anat, bold and behav """ datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', 'task_id', 'model_id'], outfields=['anat', 'bold', 'behav', 'contrasts']), name='datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '*' datasource.inputs.field_template = {'anat': '%s/anatomy/highres001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt'), 'contrasts': ('models/model%03d/' 'task_contrasts.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], 'bold': [['subject_id', 'task_id']], 'behav': [['subject_id', 'model_id', 'task_id', 'run_id']], 'contrasts': [['model_id']]} datasource.inputs.sort_filelist = True """ Create meta workflow """ wf = pe.Workflow(name='openfmri') wf.connect(infosource, 'subject_id', subjinfo, 'subject_id') wf.connect(infosource, 'model_id', subjinfo, 'model_id') wf.connect(infosource, 'task_id', subjinfo, 'task_id') wf.connect(infosource, 'subject_id', datasource, 'subject_id') wf.connect(infosource, 'model_id', datasource, 'model_id') wf.connect(infosource, 'task_id', datasource, 'task_id') wf.connect(subjinfo, 'run_id', datasource, 'run_id') wf.connect([(datasource, preproc, [('bold', 'inputspec.func')]), ]) def get_highpass(TR, hpcutoff): return hpcutoff / (2 * TR) gethighpass = pe.Node(niu.Function(input_names=['TR', 'hpcutoff'], output_names=['highpass'], function=get_highpass), name='gethighpass') wf.connect(subjinfo, 'TR', gethighpass, 'TR') wf.connect(gethighpass, 'highpass', preproc, 'inputspec.highpass') """ Setup a basic set of contrasts, a t-test per condition """ def get_contrasts(contrast_file, task_id, conds): import numpy as np contrast_def = np.genfromtxt(contrast_file, dtype=object) if len(contrast_def.shape) == 1: contrast_def = contrast_def[None, :] contrasts = [] for row in contrast_def: if row[0] != 'task%03d' % task_id: continue con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], row[2:].astype(float).tolist()] contrasts.append(con) # add auto contrasts for each column for i, cond in enumerate(conds): con = [cond, 'T', ['cond%03d' % (i + 1)], [1]] contrasts.append(con) return contrasts contrastgen = pe.Node(niu.Function(input_names=['contrast_file', 'task_id', 'conds'], output_names=['contrasts'], function=get_contrasts), name='contrastgen') art = pe.MapNode(interface=ra.ArtifactDetect(use_differences=[True, False], use_norm=True, norm_threshold=1, zintensity_threshold=3, parameter_source='FSL', mask_type='file'), iterfield=['realigned_files', 'realignment_parameters', 'mask_file'], name="art") modelspec = pe.Node(interface=model.SpecifyModel(), name="modelspec") modelspec.inputs.input_units = 'secs' def check_behav_list(behav): from nipype.external import six out_behav = [] if isinstance(behav, six.string_types): behav = [behav] for val in behav: if not isinstance(val, list): out_behav.append([val]) else: out_behav.append(val) return out_behav wf.connect(subjinfo, 'TR', modelspec, 'time_repetition') wf.connect(datasource, ('behav', check_behav_list), modelspec, 'event_files') wf.connect(subjinfo, 'TR', modelfit, 'inputspec.interscan_interval') wf.connect(subjinfo, 'conds', contrastgen, 'conds') wf.connect(datasource, 'contrasts', contrastgen, 'contrast_file') wf.connect(infosource, 'task_id', contrastgen, 'task_id') wf.connect(contrastgen, 'contrasts', modelfit, 'inputspec.contrasts') wf.connect([(preproc, art, [('outputspec.motion_parameters', 'realignment_parameters'), ('outputspec.realigned_files', 'realigned_files'), ('outputspec.mask', 'mask_file')]), (preproc, modelspec, [('outputspec.highpassed_files', 'functional_runs'), ('outputspec.motion_parameters', 'realignment_parameters')]), (art, modelspec, [('outlier_files', 'outlier_files')]), (modelspec, modelfit, [('session_info', 'inputspec.session_info')]), (preproc, modelfit, [('outputspec.highpassed_files', 'inputspec.functional_data')]) ]) """ Reorder the copes so that now it combines across runs """ def sort_copes(files): numelements = len(files[0]) outfiles = [] for i in range(numelements): outfiles.insert(i, []) for j, elements in enumerate(files): outfiles[i].append(elements[i]) return outfiles def num_copes(files): return len(files) pickfirst = lambda x: x[0] wf.connect([(preproc, fixed_fx, [(('outputspec.mask', pickfirst), 'flameo.mask_file')]), (modelfit, fixed_fx, [(('outputspec.copes', sort_copes), 'inputspec.copes'), ('outputspec.dof_file', 'inputspec.dof_files'), (('outputspec.varcopes', sort_copes), 'inputspec.varcopes'), (('outputspec.copes', num_copes), 'l2model.num_copes'), ]) ]) wf.connect(preproc, 'outputspec.mean', registration, 'inputspec.mean_image') wf.connect(datasource, 'anat', registration, 'inputspec.anatomical_image') registration.inputs.inputspec.target_image = fsl.Info.standard_image('MNI152_T1_2mm.nii.gz') registration.inputs.inputspec.target_image_brain = fsl.Info.standard_image('MNI152_T1_2mm_brain.nii.gz') registration.inputs.inputspec.config_file = 'T1_2_MNI152_2mm' def merge_files(copes, varcopes, zstats): out_files = [] splits = [] out_files.extend(copes) splits.append(len(copes)) out_files.extend(varcopes) splits.append(len(varcopes)) out_files.extend(zstats) splits.append(len(zstats)) return out_files, splits mergefunc = pe.Node(niu.Function(input_names=['copes', 'varcopes', 'zstats'], output_names=['out_files', 'splits'], function=merge_files), name='merge_files') wf.connect([(fixed_fx.get_node('outputspec'), mergefunc, [('copes', 'copes'), ('varcopes', 'varcopes'), ('zstats', 'zstats'), ])]) wf.connect(mergefunc, 'out_files', registration, 'inputspec.source_files') def split_files(in_files, splits): copes = in_files[:splits[0]] varcopes = in_files[splits[0]:(splits[0] + splits[1])] zstats = in_files[(splits[0] + splits[1]):] return copes, varcopes, zstats splitfunc = pe.Node(niu.Function(input_names=['in_files', 'splits'], output_names=['copes', 'varcopes', 'zstats'], function=split_files), name='split_files') wf.connect(mergefunc, 'splits', splitfunc, 'splits') wf.connect(registration, 'outputspec.transformed_files', splitfunc, 'in_files') """ Connect to a datasink """ def get_subs(subject_id, conds, model_id, task_id): subs = [('_subject_id_%s_' % subject_id, '')] subs.append(('_model_id_%d' % model_id, 'model%03d' %model_id)) subs.append(('task_id_%d/' % task_id, '/task%03d_' % task_id)) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_warp', 'mean')) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_flirt', 'affine')) for i in range(len(conds)): subs.append(('_flameo%d/cope1.' % i, 'cope%02d.' % (i + 1))) subs.append(('_flameo%d/varcope1.' % i, 'varcope%02d.' % (i + 1))) subs.append(('_flameo%d/zstat1.' % i, 'zstat%02d.' % (i + 1))) subs.append(('_flameo%d/tstat1.' % i, 'tstat%02d.' % (i + 1))) subs.append(('_flameo%d/res4d.' % i, 'res4d%02d.' % (i + 1))) subs.append(('_warpall%d/cope1_warp.' % i, 'cope%02d.' % (i + 1))) subs.append(('_warpall%d/varcope1_warp.' % (len(conds) + i), 'varcope%02d.' % (i + 1))) subs.append(('_warpall%d/zstat1_warp.' % (2 * len(conds) + i), 'zstat%02d.' % (i + 1))) return subs subsgen = pe.Node(niu.Function(input_names=['subject_id', 'conds', 'model_id', 'task_id'], output_names=['substitutions'], function=get_subs), name='subsgen') datasink = pe.Node(interface=nio.DataSink(), name="datasink") wf.connect(infosource, 'subject_id', datasink, 'container') wf.connect(infosource, 'subject_id', subsgen, 'subject_id') wf.connect(infosource, 'model_id', subsgen, 'model_id') wf.connect(infosource, 'task_id', subsgen, 'task_id') wf.connect(contrastgen, 'contrasts', subsgen, 'conds') wf.connect(subsgen, 'substitutions', datasink, 'substitutions') wf.connect([(fixed_fx.get_node('outputspec'), datasink, [('res4d', 'res4d'), ('copes', 'copes'), ('varcopes', 'varcopes'), ('zstats', 'zstats'), ('tstats', 'tstats')]) ]) wf.connect([(splitfunc, datasink, [('copes', 'copes.mni'), ('varcopes', 'varcopes.mni'), ('zstats', 'zstats.mni'), ])]) wf.connect(registration, 'outputspec.transformed_mean', datasink, 'mean.mni') wf.connect(registration, 'outputspec.func2anat_transform', datasink, 'xfm.mean2anat') wf.connect(registration, 'outputspec.anat2target_transform', datasink, 'xfm.anat2target') """ Set processing parameters """ hpcutoff = 120. preproc.inputs.inputspec.fwhm = 6.0 gethighpass.inputs.hpcutoff = hpcutoff modelspec.inputs.high_pass_filter_cutoff = hpcutoff modelfit.inputs.inputspec.bases = {'dgamma': {'derivs': True}} modelfit.inputs.inputspec.model_serial_correlations = True modelfit.inputs.inputspec.film_threshold = 1000 datasink.inputs.base_directory = output_dir return wf """ The following functions run the whole workflow. """ if __name__ == '__main__': import argparse defstr = ' (default %(default)s)' parser = argparse.ArgumentParser(prog='fmri_openfmri.py', description=__doc__) parser.add_argument('-d', '--datasetdir', required=True) parser.add_argument('-s', '--subject', default=[], nargs='+', type=str, help="Subject name (e.g. 'sub001')") parser.add_argument('-m', '--model', default=1, help="Model index" + defstr) parser.add_argument('-x', '--subjectprefix', default='sub*', help="Subject prefix" + defstr) parser.add_argument('-t', '--task', default=1, #nargs='+', type=int, help="Task index" + defstr) parser.add_argument("-o", "--output_dir", dest="outdir", help="Output directory base") parser.add_argument("-w", "--work_dir", dest="work_dir", help="Working directory base") parser.add_argument("-p", "--plugin", dest="plugin", default='Linear', help="Plugin to use") parser.add_argument("--plugin_args", dest="plugin_args", help="Plugin arguments") args = parser.parse_args() outdir = args.outdir work_dir = os.getcwd() if args.work_dir: work_dir = os.path.abspath(args.work_dir) if outdir: outdir = os.path.abspath(outdir) else: outdir = os.path.join(work_dir, 'output') outdir = os.path.join(outdir, 'model%02d' % int(args.model), 'task%03d' % int(args.task)) wf = analyze_openfmri_dataset(data_dir=os.path.abspath(args.datasetdir), subject=args.subject, model_id=int(args.model), task_id=[int(args.task)], subj_prefix=args.subjectprefix, output_dir=outdir) wf.base_dir = work_dir if args.plugin_args: wf.run(args.plugin, plugin_args=eval(args.plugin_args)) else: wf.run(args.plugin) nipype-0.11.0/examples/fmri_slicer_coregistration.py000077500000000000000000000105141257611314500227100ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ===================================== fMRI: Coregistration - Slicer, BRAINS ===================================== This is currently not working and will raise an exception in release 0.3. It will be fixed in a later release:: python fmri_slicer_coregistration.py """ #raise RuntimeWarning, 'Slicer not fully implmented' from nipype.interfaces.slicer import BRAINSFit, BRAINSResample """Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import os # system functions """ Preliminaries ------------- Confirm package dependencies are installed. (This is only for the tutorial, rarely would you put this in your own code.) """ from nipype.utils.misc import package_check package_check('numpy', '1.3', 'tutorial1') package_check('scipy', '0.7', 'tutorial1') package_check('networkx', '1.0', 'tutorial1') package_check('IPython', '0.10', 'tutorial1') """The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1', 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', 'f3']], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Preprocessing pipeline nodes ---------------------------- Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True coregister = pe.Node(interface=BRAINSFit(), name="coregister") coregister.inputs.outputTransform = True coregister.inputs.outputVolume = True coregister.inputs.transformType = ["Affine"] reslice = pe.Node(interface=BRAINSResample(), name="reslice") reslice.inputs.outputVolume = True pipeline = pe.Workflow(name="pipeline") pipeline.base_dir = os.path.abspath('slicer_tutorial/workingdir') pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,coregister,[('func','movingVolume')]), (datasource,coregister,[('struct','fixedVolume')]), (coregister,reslice,[('outputTransform', 'warpTransform')]), (datasource,reslice,[('func','inputVolume')]), (datasource,reslice,[('struct','referenceVolume')]) ]) if __name__ == '__main__': pipeline.run() pipeline.write_graph() nipype-0.11.0/examples/fmri_spm.py000077500000000000000000000373331257611314500171220ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ============== fMRI: SPM, FSL ============== The fmri_spm.py integrates several interfaces to perform a first and second level analysis on a two-subject data set. The tutorial can be found in the examples folder. Run the tutorial from inside the nipype tutorial directory:: python fmri_spm.py Import necessary modules from nipype.""" import os # system functions from nipype import config #config.enable_provenance() from nipype.interfaces import spm, fsl # In order to use this example with SPM's matlab common runtime # matlab_cmd = ('/Users/satra/Downloads/spm8/run_spm8.sh ' # '/Applications/MATLAB/MATLAB_Compiler_Runtime/v713/ script') # spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True) import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.rapidart as ra # artifact detection import nipype.algorithms.modelgen as model # model specification import nipype.interfaces.matlab as mlab """ Preliminaries ------------- Set any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Tell fsl to generate all output in uncompressed nifti format fsl.FSLCommand.set_default_output_type('NIFTI') # Set the way matlab should be called # import nipype.interfaces.matlab as mlab # how to run matlab # mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") # In case a different path is required # mlab.MatlabCommand.set_default_paths('/software/matlab/spm12b/spm12b_r5918') """The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1', 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Preprocessing pipeline nodes ---------------------------- Now we create a :class:`nipype.interfaces.io.DataSource` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = pe.Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' """Skull strip structural images using :class:`nipype.interfaces.fsl.BET`. """ skullstrip = pe.Node(interface=fsl.BET(), name="skullstrip") skullstrip.inputs.mask = True """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize = pe.Node(interface=spm.Normalize(), name = "normalize") normalize.inputs.template = os.path.abspath('data/T1.nii') """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name = "smooth") fwhmlist = [4] smooth.iterables = ('fwhm',fwhmlist) """ Set up analysis components -------------------------- Here we create a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names])) return output """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrasts = [cont1,cont2] """Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") modelspec.inputs.concatenate_runs = False modelspec.inputs.input_units = 'secs' modelspec.inputs.output_units = 'secs' modelspec.inputs.time_repetition = 3. modelspec.inputs.high_pass_filter_cutoff = 120 """Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.timing_units = modelspec.inputs.output_units level1design.inputs.interscan_interval = modelspec.inputs.time_repetition level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} """Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} """Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") contrastestimate.inputs.contrasts = contrasts contrastestimate.overwrite = True contrastestimate.config = {'execution': {'remove_unnecessary_outputs': False}} """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ l1pipeline = pe.Workflow(name="level1") l1pipeline.base_dir = os.path.abspath('spm_tutorial/workingdir') l1pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,realign,[('func','in_files')]), (realign,coregister,[('mean_image', 'source'), ('realigned_files','apply_to_files')]), (datasource,coregister,[('struct', 'target')]), (datasource,normalize,[('struct', 'source')]), (coregister, normalize, [('coregistered_files','apply_to_files')]), (normalize, smooth, [('normalized_files', 'in_files')]), (infosource,modelspec,[(('subject_id', subjectinfo), 'subject_info')]), (realign,modelspec,[('realignment_parameters','realignment_parameters')]), (smooth,modelspec,[('smoothed_files','functional_runs')]), (normalize,skullstrip,[('normalized_source','in_file')]), (realign,art,[('realignment_parameters','realignment_parameters')]), (normalize,art,[('normalized_files','realigned_files')]), (skullstrip,art,[('mask_file','mask_file')]), (art,modelspec,[('outlier_files','outlier_files')]), (modelspec,level1design,[('session_info','session_info')]), (skullstrip,level1design,[('mask_file','mask_image')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), ]) """ Setup storage results --------------------- Use :class:`nipype.interfaces.io.DataSink` to store selected outputs from the pipeline in a specific location. This allows the user to selectively choose important output bits from the analysis and keep them. The first step is to create a datasink node and then to connect outputs from the modules above to storage locations. These take the following form directory_name[.[@]subdir] where parts between [] are optional. For example 'realign.@mean' below creates a directory called realign in 'l1output/subject_id/' and stores the mean image output from the Realign process in the realign directory. If the @ is left out, then a sub-directory with the name 'mean' would be created and the mean image would be copied to that directory. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('spm_tutorial/l1output') def getstripdir(subject_id): import os return os.path.join(os.path.abspath('spm_tutorial/workingdir'),'_subject_id_%s' % subject_id) # store relevant outputs from various stages of the 1st level analysis l1pipeline.connect([(infosource,datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (realign,datasink,[('mean_image','realign.@mean'), ('realignment_parameters','realign.@param')]), (art,datasink,[('outlier_files','art.@outliers'), ('statistic_files','art.@stats')]), (level1design,datasink,[('spm_mat_file','model.pre-estimate')]), (level1estimate,datasink,[('spm_mat_file','model.@spm'), ('beta_images','model.@beta'), ('mask_image','model.@mask'), ('residual_image','model.@res'), ('RPVimage','model.@rpv')]), (contrastestimate,datasink,[('con_images','contrasts.@con'), ('spmT_images','contrasts.@T')]), ]) """ Setup level 2 pipeline ---------------------- Use :class:`nipype.interfaces.io.DataGrabber` to extract the contrast images across a group of first level subjects. Unlike the previous pipeline that iterated over subjects, this pipeline will iterate over contrasts. """ # collect all the con images for each contrast. contrast_ids = range(1,len(contrasts)+1) l2source = pe.Node(nio.DataGrabber(infields=['fwhm', 'con']), name="l2source") # we use .*i* to capture both .img (SPM8) and .nii (SPM12) l2source.inputs.template=os.path.abspath('spm_tutorial/l1output/*/con*/*/_fwhm_%d/con_%04d.*i*') # iterate over all contrast images l2source.iterables = [('fwhm',fwhmlist), ('con',contrast_ids)] l2source.inputs.sort_filelist = True """Use :class:`nipype.interfaces.spm.OneSampleTTestDesign` to perform a simple statistical analysis of the contrasts from the group of subjects (n=2 in this example). """ # setup a 1-sample t-test node onesamplettestdes = pe.Node(interface=spm.OneSampleTTestDesign(), name="onesampttestdes") l2estimate = pe.Node(interface=spm.EstimateModel(), name="level2estimate") l2estimate.inputs.estimation_method = {'Classical' : 1} l2conestimate = pe.Node(interface = spm.EstimateContrast(), name="level2conestimate") cont1 = ('Group','T', ['mean'],[1]) l2conestimate.inputs.contrasts = [cont1] l2conestimate.inputs.group_contrast = True """As before, we setup a pipeline to connect these two nodes (l2source -> onesamplettest). """ l2pipeline = pe.Workflow(name="level2") l2pipeline.base_dir = os.path.abspath('spm_tutorial/l2output') l2pipeline.connect([(l2source,onesamplettestdes,[('outfiles','in_files')]), (onesamplettestdes,l2estimate,[('spm_mat_file','spm_mat_file')]), (l2estimate,l2conestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': l1pipeline.run('MultiProc') l2pipeline.run('MultiProc') nipype-0.11.0/examples/fmri_spm_auditory.py000077500000000000000000000345211257611314500210360ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ========================== fMRI: SPM Auditory dataset ========================== Introduction ============ The fmri_spm_auditory.py recreates the classical workflow described in the `SPM8 manual `_ using auditory dataset that can be downloaded from http://www.fil.ion.ucl.ac.uk/spm/data/auditory/:: python fmri_spm_auditory.py Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.matlab as mlab # how to run matlab import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model specification import os # system functions """ Preliminaries ------------- """ # Set the way matlab should be called mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") """ Setting up workflows -------------------- In this tutorial we will be setting up a hierarchical workflow for spm analysis. This will demonstrate how pre-defined workflows can be setup and shared across users, projects and labs. Setup preprocessing workflow ---------------------------- This is a generic preprocessing workflow that can be used by different analyses """ preproc = pe.Workflow(name='preproc') """We strongly encourage to use 4D files insteead of series of 3D for fMRI analyses for many reasons (cleanness and saving and filesystem inodes are among them). However, the the workflow presented in the SPM8 manual which this tutorial is based on uses 3D files. Therefore we leave converting to 4D as an option. We are using `merge_to_4d` variable, because switching between 3d and 4d requires some additional steps (explauned later on). Use :class:`nipype.interfaces.fsl.Merge` to merge a series of 3D files along the time dimension creating a 4d file. """ merge_to_4d = True if merge_to_4d: merge = pe.Node(interface=fsl.Merge(), name="merge") merge.inputs.dimension="t" """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' segment = pe.Node(interface=spm.Segment(), name="segment") """Uncomment the following line for faster execution """ #segment.inputs.gaussians_per_class = [1, 1, 1, 4] """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize_func = pe.Node(interface=spm.Normalize(), name = "normalize_func") normalize_func.inputs.jobtype = "write" normalize_struc = pe.Node(interface=spm.Normalize(), name = "normalize_struc") normalize_struc.inputs.jobtype = "write" """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name = "smooth") """`write_voxel_sizes` is the input of the normalize interface that is recommended to be set to the voxel sizes of the target volume. There is no need to set it manually since we van infer it from data using the following function: """ def get_vox_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() voxdims = hdr.get_zooms() return [float(voxdims[0]), float(voxdims[1]), float(voxdims[2])] """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. """ if merge_to_4d: preproc.connect([(merge, realign,[('merged_file', 'in_files')])]) preproc.connect([(realign,coregister,[('mean_image', 'target')]), (coregister, segment,[('coregistered_source','data')]), (segment, normalize_func, [('transformation_mat','parameter_file')]), (segment, normalize_struc, [('transformation_mat','parameter_file'), ('modulated_input_image', 'apply_to_files'), (('modulated_input_image', get_vox_dims), 'write_voxel_sizes')]), (realign, normalize_func, [('realigned_files', 'apply_to_files'), (('realigned_files', get_vox_dims), 'write_voxel_sizes')]), (normalize_func, smooth, [('normalized_files', 'in_files')]), ]) """ Set up analysis workflow ------------------------ """ l1analysis = pe.Workflow(name='analysis') """Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") """Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} """Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} threshold = pe.Node(interface=spm.Threshold(), name="threshold") """Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") l1analysis.connect([(modelspec,level1design,[('session_info','session_info')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), (contrastestimate, threshold,[('spm_mat_file','spm_mat_file'), ('spmT_images', 'stat_image')]), ]) """ Preproc + Analysis pipeline --------------------------- """ l1pipeline = pe.Workflow(name='firstlevel') l1pipeline.connect([(preproc, l1analysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters')])]) """Pluging in `functional_runs` is a bit more complicated, because model spec expects a list of `runs`. Every run can be a 4D file or a list of 3D files. Therefore for 3D analysis we need a list of lists and to make one we need a helper function. """ if merge_to_4d: l1pipeline.connect([(preproc, l1analysis, [('smooth.smoothed_files', 'modelspec.functional_runs')])]) else: def makelist(item): return [item] l1pipeline.connect([(preproc, l1analysis, [(('smooth.smoothed_files',makelist), 'modelspec.functional_runs')])]) """ Data specific components ------------------------ In this tutorial there is only one subject `M00223`. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. """ # Specify the location of the data downloaded from http://www.fil.ion.ucl.ac.uk/spm/data/auditory/ data_dir = os.path.abspath('spm_auditory_data') # Specify the subject directories subject_list = ['M00223'] # Map field names to individual subject runs. info = dict(func=[['f', 'subject_id', 'f', 'subject_id', range(16,100)]], struct=[['s', 'subject_id', 's', 'subject_id', 2]]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s%s/%s%s_%03d.img' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Experimental paradigm specific components ----------------------------------------- Here we create a structure that provides information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. """ from nipype.interfaces.base import Bunch subjectinfo = [Bunch(conditions=['Task'], onsets=[range(6,84,12)], durations=[[6]])] """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('active > rest','T', ['Task'],[1]) contrasts = [cont1] # set up node specific inputs modelspecref = l1pipeline.inputs.analysis.modelspec modelspecref.input_units = 'scans' modelspecref.output_units = 'scans' modelspecref.time_repetition = 7 modelspecref.high_pass_filter_cutoff = 120 l1designref = l1pipeline.inputs.analysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1pipeline.inputs.preproc.smooth.fwhm = [6, 6, 6] l1pipeline.inputs.analysis.modelspec.subject_info = subjectinfo l1pipeline.inputs.analysis.contrastestimate.contrasts = contrasts l1pipeline.inputs.analysis.threshold.contrast_index = 1 """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ level1 = pe.Workflow(name="level1") level1.base_dir = os.path.abspath('spm_auditory_tutorial/workingdir') level1.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,l1pipeline,[('struct', 'preproc.coregister.source')]) ]) if merge_to_4d: level1.connect([(datasource,l1pipeline,[('func','preproc.merge.in_files')])]) else: level1.connect([(datasource,l1pipeline,[('func','preproc.realign.in_files')])]) """ Setup storage results --------------------- Use :class:`nipype.interfaces.io.DataSink` to store selected outputs from the pipeline in a specific location. This allows the user to selectively choose important output bits from the analysis and keep them. The first step is to create a datasink node and then to connect outputs from the modules above to storage locations. These take the following form directory_name[.[@]subdir] where parts between [] are optional. For example 'realign.@mean' below creates a directory called realign in 'l1output/subject_id/' and stores the mean image output from the Realign process in the realign directory. If the @ is left out, then a sub-directory with the name 'mean' would be created and the mean image would be copied to that directory. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('spm_auditory_tutorial/l1output') def getstripdir(subject_id): import os return os.path.join(os.path.abspath('spm_auditory_tutorial/workingdir'),'_subject_id_%s' % subject_id) # store relevant outputs from various stages of the 1st level analysis level1.connect([(infosource, datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, datasink,[('analysis.contrastestimate.con_images','contrasts.@con'), ('analysis.contrastestimate.spmT_images','contrasts.@T')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': level1.run() level1.write_graph() nipype-0.11.0/examples/fmri_spm_dartel.py000077500000000000000000000504351257611314500204530ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ================= fMRI: DARTEL, SPM ================= The fmri_spm_dartel.py integrates several interfaces to perform a first and second level analysis on a two-subject data set. The tutorial can be found in the examples folder. Run the tutorial from inside the nipype tutorial directory:: python fmri_spm_dartel.py Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.workflows.fmri.spm as spm_wf # spm import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.rapidart as ra # artifact detection import nipype.algorithms.modelgen as model # model specification import os # system functions """ Preliminaries ------------- Set any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Tell fsl to generate all output in uncompressed nifti format fsl.FSLCommand.set_default_output_type('NIFTI') # Set the way matlab should be called #mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") #mlab.MatlabCommand.set_default_paths('/software/spm8') """ Setting up workflows -------------------- In this tutorial we will be setting up a hierarchical workflow for spm analysis. This will demonstrate how pre-defined workflows can be setup and shared across users, projects and labs. Setup preprocessing workflow ---------------------------- This is a generic preprocessing workflow that can be used by different analyses """ preproc = pe.Workflow(name='preproc') """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = pe.Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' """Skull strip structural images using :class:`nipype.interfaces.fsl.BET`. """ skullstrip = pe.Node(interface=fsl.BET(), name="skullstrip") skullstrip.inputs.mask = True """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Normalize and smooth functional data using DARTEL template """ normalize_and_smooth_func = pe.Node(spm.DARTELNorm2MNI(modulate=True), name='normalize_and_smooth_func') fwhmlist = [4] normalize_and_smooth_func.iterables = ('fwhm',fwhmlist) """Normalize structural data using DARTEL template """ normalize_struct = pe.Node(spm.DARTELNorm2MNI(modulate=True), name='normalize_struct') normalize_struct.inputs.fwhm = 2 preproc.connect([(realign,coregister,[('mean_image', 'source'), ('realigned_files','apply_to_files')]), (coregister, normalize_and_smooth_func, [('coregistered_files','apply_to_files')]), (normalize_struct,skullstrip,[('normalized_files','in_file')]), (realign,art,[('realignment_parameters','realignment_parameters')]), (normalize_and_smooth_func,art,[('normalized_files','realigned_files')]), (skullstrip,art,[('mask_file','mask_file')]), ]) """ Set up analysis workflow ------------------------ """ l1analysis = pe.Workflow(name='analysis') """Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") modelspec.inputs.concatenate_runs = True """Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} """Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} """Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") """Use :class: `nipype.interfaces.utility.Select` to select each contrast for reporting. """ selectcontrast = pe.Node(interface=util.Select(), name="selectcontrast") """Use :class:`nipype.interfaces.fsl.Overlay` to combine the statistical output of the contrast estimate and a background image into one volume. """ overlaystats = pe.Node(interface=fsl.Overlay(), name="overlaystats") overlaystats.inputs.stat_thresh = (3,10) overlaystats.inputs.show_negative_stats=True overlaystats.inputs.auto_thresh_bg=True """Use :class:`nipype.interfaces.fsl.Slicer` to create images of the overlaid statistical volumes for a report of the first-level results. """ slicestats = pe.Node(interface=fsl.Slicer(), name="slicestats") slicestats.inputs.all_axial = True slicestats.inputs.image_width = 750 l1analysis.connect([(modelspec,level1design,[('session_info','session_info')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), (contrastestimate,selectcontrast,[('spmT_images','inlist')]), (selectcontrast,overlaystats,[('out','stat_image')]), (overlaystats,slicestats,[('out_file','in_file')]) ]) """ Preproc + Analysis pipeline --------------------------- """ l1pipeline = pe.Workflow(name='firstlevel') l1pipeline.connect([(preproc, l1analysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters'), ('normalize_and_smooth_func.normalized_files', 'modelspec.functional_runs'), ('art.outlier_files', 'modelspec.outlier_files'), ('skullstrip.mask_file', 'level1design.mask_image'), ('normalize_struct.normalized_files', 'overlaystats.background_image')]), ]) """ Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1', 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """We need to create a separate workflow to make the DARTEL template """ datasource_dartel = pe.MapNode(interface=nio.DataGrabber(infields=['subject_id'], outfields=['struct']), name = 'datasource_dartel', iterfield = ['subject_id']) datasource_dartel.inputs.base_directory = data_dir datasource_dartel.inputs.template = '%s/%s.nii' datasource_dartel.inputs.template_args = dict(struct=[['subject_id','struct']]) datasource_dartel.inputs.sort_filelist = True datasource_dartel.inputs.subject_id = subject_list """Here we make sure that struct files have names corresponding to the subject ids. This way we will be able to pick the right field flows later. """ rename_dartel = pe.MapNode(util.Rename(format_string="subject_id_%(subject_id)s_struct"), iterfield=['in_file', 'subject_id'], name = 'rename_dartel') rename_dartel.inputs.subject_id = subject_list rename_dartel.inputs.keep_ext = True dartel_workflow = spm_wf.create_DARTEL_template(name='dartel_workflow') dartel_workflow.inputs.inputspec.template_prefix = "template" """This function will allow to pick the right field flow for each subject """ def pickFieldFlow(dartel_flow_fields, subject_id): from nipype.utils.filemanip import split_filename for f in dartel_flow_fields: _, name, _ = split_filename(f) if name.find("subject_id_%s"%subject_id): return f raise Exception pick_flow = pe.Node(util.Function(input_names=['dartel_flow_fields', 'subject_id'], output_names=['dartel_flow_field'], function = pickFieldFlow), name = "pick_flow") """ Experimental paradigm specific components ----------------------------------------- Here we create a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)) return output """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrasts = [cont1,cont2] # set up node specific inputs modelspecref = l1pipeline.inputs.analysis.modelspec modelspecref.input_units = 'secs' modelspecref.output_units = 'secs' modelspecref.time_repetition = 3. modelspecref.high_pass_filter_cutoff = 120 l1designref = l1pipeline.inputs.analysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1pipeline.inputs.analysis.contrastestimate.contrasts = contrasts # Iterate over each contrast and create report images. selectcontrast.iterables = ('index',[[i] for i in range(len(contrasts))]) """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ level1 = pe.Workflow(name="level1") level1.base_dir = os.path.abspath('spm_dartel_tutorial/workingdir') level1.connect([(datasource_dartel, rename_dartel, [('struct', 'in_file')]), (rename_dartel, dartel_workflow, [('out_file','inputspec.structural_files')]), (infosource, datasource, [('subject_id', 'subject_id')]), (datasource,l1pipeline,[('func','preproc.realign.in_files'), ('struct', 'preproc.coregister.target'), ('struct', 'preproc.normalize_struct.apply_to_files')]), (dartel_workflow, l1pipeline, [('outputspec.template_file', 'preproc.normalize_struct.template_file'), ('outputspec.template_file', 'preproc.normalize_and_smooth_func.template_file')]), (infosource, pick_flow, [('subject_id', 'subject_id')]), (dartel_workflow, pick_flow, [('outputspec.flow_fields', 'dartel_flow_fields')]), (pick_flow, l1pipeline, [('dartel_flow_field', 'preproc.normalize_struct.flowfield_files'), ('dartel_flow_field', 'preproc.normalize_and_smooth_func.flowfield_files')]), (infosource,l1pipeline,[(('subject_id', subjectinfo), 'analysis.modelspec.subject_info')]), ]) """ Setup storage results --------------------- Use :class:`nipype.interfaces.io.DataSink` to store selected outputs from the pipeline in a specific location. This allows the user to selectively choose important output bits from the analysis and keep them. The first step is to create a datasink node and then to connect outputs from the modules above to storage locations. These take the following form directory_name[.[@]subdir] where parts between [] are optional. For example 'realign.@mean' below creates a directory called realign in 'l1output/subject_id/' and stores the mean image output from the Realign process in the realign directory. If the @ is left out, then a sub-directory with the name 'mean' would be created and the mean image would be copied to that directory. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('spm_dartel_tutorial/l1output') report = pe.Node(interface=nio.DataSink(), name='report') report.inputs.base_directory = os.path.abspath('spm_dartel_tutorial/report') report.inputs.parameterization = False def getstripdir(subject_id): import os return os.path.join(os.path.abspath('spm_dartel_tutorial/workingdir'),'_subject_id_%s' % subject_id) # store relevant outputs from various stages of the 1st level analysis level1.connect([(infosource, datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, datasink,[('analysis.contrastestimate.con_images','contrasts.@con'), ('analysis.contrastestimate.spmT_images','contrasts.@T')]), (infosource, report,[('subject_id', 'container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, report,[('analysis.slicestats.out_file', '@report')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': level1.run(plugin_args={'n_procs': 4}) level1.write_graph() """ Setup level 2 pipeline ---------------------- Use :class:`nipype.interfaces.io.DataGrabber` to extract the contrast images across a group of first level subjects. Unlike the previous pipeline that iterated over subjects, this pipeline will iterate over contrasts. """ # collect all the con images for each contrast. contrast_ids = range(1,len(contrasts)+1) l2source = pe.Node(nio.DataGrabber(infields=['fwhm', 'con']), name="l2source") # we use .*i* to capture both .img (SPM8) and .nii (SPM12) l2source.inputs.template=os.path.abspath('spm_dartel_tutorial/l1output/*/con*/*/_fwhm_%d/con_%04d.*i*') # iterate over all contrast images l2source.iterables = [('fwhm',fwhmlist), ('con',contrast_ids)] l2source.inputs.sort_filelist = True """Use :class:`nipype.interfaces.spm.OneSampleTTestDesign` to perform a simple statistical analysis of the contrasts from the group of subjects (n=2 in this example). """ # setup a 1-sample t-test node onesamplettestdes = pe.Node(interface=spm.OneSampleTTestDesign(), name="onesampttestdes") l2estimate = pe.Node(interface=spm.EstimateModel(), name="level2estimate") l2estimate.inputs.estimation_method = {'Classical' : 1} l2conestimate = pe.Node(interface = spm.EstimateContrast(), name="level2conestimate") cont1 = ('Group','T', ['mean'],[1]) l2conestimate.inputs.contrasts = [cont1] l2conestimate.inputs.group_contrast = True """As before, we setup a pipeline to connect these two nodes (l2source -> onesamplettest). """ l2pipeline = pe.Workflow(name="level2") l2pipeline.base_dir = os.path.abspath('spm_dartel_tutorial/l2output') l2pipeline.connect([(l2source,onesamplettestdes,[('outfiles','in_files')]), (onesamplettestdes,l2estimate,[('spm_mat_file','spm_mat_file')]), (l2estimate,l2conestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), ]) """ Execute the second level pipeline --------------------------------- """ if __name__ == '__main__': l2pipeline.run() nipype-0.11.0/examples/fmri_spm_face.py000077500000000000000000000450011257611314500200670ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ===================================== fMRI: Famous vs non-famous faces, SPM ===================================== Introduction ============ The fmri_spm_face.py recreates the classical workflow described in the `SPM8 manual `_ using face dataset that can be downloaded from http://www.fil.ion.ucl.ac.uk/spm/data/face_rep/:: python fmri_spm.py Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.interfaces.matlab as mlab # how to run matlab import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model specification import os # system functions """ Preliminaries ------------- Set any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Set the way matlab should be called mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") # If SPM is not in your MATLAB path you should add it here # mlab.MatlabCommand.set_default_paths('/path/to/your/spm8') """ Setting up workflows -------------------- In this tutorial we will be setting up a hierarchical workflow for spm analysis. It one is slightly different then the one used in spm_tutorial2. Setup preprocessing workflow ---------------------------- This is a generic preprocessing workflow that can be used by different analyses """ preproc = pe.Workflow(name='preproc') """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") slice_timing = pe.Node(interface=spm.SliceTiming(), name="slice_timing") """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' segment = pe.Node(interface=spm.Segment(), name="segment") segment.inputs.save_bias_corrected = True """Uncomment the following line for faster execution """ #segment.inputs.gaussians_per_class = [1, 1, 1, 4] """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize_func = pe.Node(interface=spm.Normalize(), name = "normalize_func") normalize_func.inputs.jobtype = "write" normalize_struc = pe.Node(interface=spm.Normalize(), name = "normalize_struc") normalize_struc.inputs.jobtype = "write" """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name = "smooth") """`write_voxel_sizes` is the input of the normalize interface that is recommended to be set to the voxel sizes of the target volume. There is no need to set it manually since we van infer it from data using the following function: """ def get_vox_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() voxdims = hdr.get_zooms() return [float(voxdims[0]), float(voxdims[1]), float(voxdims[2])] """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. """ preproc.connect([(realign,coregister,[('mean_image', 'target')]), (coregister, segment,[('coregistered_source','data')]), (segment, normalize_func, [('transformation_mat','parameter_file')]), (segment, normalize_struc, [('transformation_mat','parameter_file'), ('bias_corrected_image', 'apply_to_files'), (('bias_corrected_image', get_vox_dims), 'write_voxel_sizes')]), (realign, slice_timing, [('realigned_files', 'in_files')]), (slice_timing, normalize_func, [('timecorrected_files', 'apply_to_files'), (('timecorrected_files', get_vox_dims), 'write_voxel_sizes')]), (normalize_func, smooth, [('normalized_files', 'in_files')]), ]) """ Set up analysis workflow ------------------------ """ l1analysis = pe.Workflow(name='analysis') """Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") """Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") """Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} threshold = pe.Node(interface=spm.Threshold(), name="threshold") """Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") def pickfirst(l): return l[0] l1analysis.connect([(modelspec,level1design,[('session_info','session_info')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), (contrastestimate, threshold,[('spm_mat_file','spm_mat_file'), (('spmT_images', pickfirst), 'stat_image')]), ]) """ Preproc + Analysis pipeline --------------------------- """ l1pipeline = pe.Workflow(name='firstlevel') l1pipeline.connect([(preproc, l1analysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters')])]) """Pluging in `functional_runs` is a bit more complicated, because model spec expects a list of `runs`. Every run can be a 4D file or a list of 3D files. Therefore for 3D analysis we need a list of lists and to make one we need a helper function. """ def makelist(item): return [item] l1pipeline.connect([(preproc, l1analysis, [(('smooth.smoothed_files',makelist), 'modelspec.functional_runs')])]) """ Data specific components ------------------------ In this tutorial there is only one subject `M03953`. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. """ # Specify the location of the data downloaded from http://www.fil.ion.ucl.ac.uk/spm/data/face_rep/face_rep_SPM5.html data_dir = os.path.abspath('spm_face_data') # Specify the subject directories subject_list = ['M03953'] # Map field names to individual subject runs. info = dict(func=[['RawEPI', 'subject_id', 5, ["_%04d"%i for i in range(6,357)]]], struct=[['Structural', 'subject_id', 7, '']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/s%s_%04d%s.img' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Experimental paradigm specific components ----------------------------------------- Here we create a structure that provides information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. """ from nipype.interfaces.base import Bunch """We're importing the onset times from a mat file (found on http://www.fil.ion.ucl.ac.uk/spm/data/face_rep/) """ from scipy.io.matlab import loadmat mat = loadmat(os.path.join(data_dir, "sots.mat"), struct_as_record=False) sot = mat['sot'][0] itemlag = mat['itemlag'][0] subjectinfo = [Bunch(conditions=['N1', 'N2', 'F1', 'F2'], onsets=[sot[0], sot[1], sot[2], sot[3]], durations=[[0], [0], [0], [0]], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)] """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cond1 = ('positive effect of condition','T', ['N1*bf(1)','N2*bf(1)','F1*bf(1)','F2*bf(1)'],[1,1,1,1]) cond2 = ('positive effect of condition_dtemo','T', ['N1*bf(2)','N2*bf(2)','F1*bf(2)','F2*bf(2)'],[1,1,1,1]) cond3 = ('positive effect of condition_ddisp','T', ['N1*bf(3)','N2*bf(3)','F1*bf(3)','F2*bf(3)'],[1,1,1,1]) # non-famous > famous fam1 = ('positive effect of Fame','T', ['N1*bf(1)','N2*bf(1)','F1*bf(1)','F2*bf(1)'],[1,1,-1,-1]) fam2 = ('positive effect of Fame_dtemp','T', ['N1*bf(2)','N2*bf(2)','F1*bf(2)','F2*bf(2)'],[1,1,-1,-1]) fam3 = ('positive effect of Fame_ddisp','T', ['N1*bf(3)','N2*bf(3)','F1*bf(3)','F2*bf(3)'],[1,1,-1,-1]) # rep1 > rep2 rep1 = ('positive effect of Rep','T', ['N1*bf(1)','N2*bf(1)','F1*bf(1)','F2*bf(1)'],[1,-1,1,-1]) rep2 = ('positive effect of Rep_dtemp','T', ['N1*bf(2)','N2*bf(2)','F1*bf(2)','F2*bf(2)'],[1,-1,1,-1]) rep3 = ('positive effect of Rep_ddisp','T', ['N1*bf(3)','N2*bf(3)','F1*bf(3)','F2*bf(3)'],[1,-1,1,-1]) int1 = ('positive interaction of Fame x Rep','T', ['N1*bf(1)','N2*bf(1)','F1*bf(1)','F2*bf(1)'],[-1,-1,-1,1]) int2 = ('positive interaction of Fame x Rep_dtemp','T', ['N1*bf(2)','N2*bf(2)','F1*bf(2)','F2*bf(2)'],[1,-1,-1,1]) int3 = ('positive interaction of Fame x Rep_ddisp','T', ['N1*bf(3)','N2*bf(3)','F1*bf(3)','F2*bf(3)'],[1,-1,-1,1]) contf1 = ['average effect condition','F', [cond1, cond2, cond3]] contf2 = ['main effect Fam', 'F', [fam1, fam2, fam3]] contf3 = ['main effect Rep', 'F', [rep1, rep2, rep3]] contf4 = ['interaction: Fam x Rep', 'F', [int1, int2, int3]] contrasts = [cond1, cond2, cond3, fam1, fam2, fam3, rep1, rep2, rep3, int1, int2, int3, contf1, contf2,contf3,contf4] """Setting up nodes inputs """ num_slices = 24 TR = 2. slice_timingref = l1pipeline.inputs.preproc.slice_timing slice_timingref.num_slices = num_slices slice_timingref.time_repetition = TR slice_timingref.time_acquisition = TR - TR/float(num_slices) slice_timingref.slice_order = range(num_slices,0,-1) slice_timingref.ref_slice = int(num_slices/2) l1pipeline.inputs.preproc.smooth.fwhm = [8, 8, 8] # set up node specific inputs modelspecref = l1pipeline.inputs.analysis.modelspec modelspecref.input_units = 'scans' modelspecref.output_units = 'scans' modelspecref.time_repetition = TR modelspecref.high_pass_filter_cutoff = 120 l1designref = l1pipeline.inputs.analysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1designref.microtime_resolution = slice_timingref.num_slices l1designref.microtime_onset = slice_timingref.ref_slice l1designref.bases = {'hrf':{'derivs': [1,1]}} """ The following lines automatically inform SPM to create a default set of contrats for a factorial design. """ #l1designref.factor_info = [dict(name = 'Fame', levels = 2), # dict(name = 'Rep', levels = 2)] l1pipeline.inputs.analysis.modelspec.subject_info = subjectinfo l1pipeline.inputs.analysis.contrastestimate.contrasts = contrasts l1pipeline.inputs.analysis.threshold.contrast_index = 1 """ Use derivative estimates in the non-parametric model """ l1pipeline.inputs.analysis.contrastestimate.use_derivs = True """ Setting up parametricvariation of the model """ subjectinfo_param = [Bunch(conditions=['N1', 'N2', 'F1', 'F2'], onsets=[sot[0], sot[1], sot[2], sot[3]], durations=[[0], [0], [0], [0]], amplitudes=None, tmod=None, pmod=[None, Bunch(name=['Lag'], param=itemlag[1].tolist(), poly=[2]), None, Bunch(name=['Lag'], param=itemlag[3].tolist(), poly=[2])], regressor_names=None, regressors=None)] cont1 = ('Famous_lag1','T', ['F2xLag^1'],[1]) cont2 = ('Famous_lag2','T', ['F2xLag^2'],[1]) fcont1 = ('Famous Lag', 'F', [cont1, cont2]) paramcontrasts = [cont1, cont2, fcont1] paramanalysis = l1analysis.clone(name='paramanalysis') paramanalysis.inputs.level1design.bases = {'hrf':{'derivs': [0,0]}} paramanalysis.inputs.modelspec.subject_info = subjectinfo_param paramanalysis.inputs.contrastestimate.contrasts = paramcontrasts paramanalysis.inputs.contrastestimate.use_derivs = False l1pipeline.connect([(preproc, paramanalysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters'), (('smooth.smoothed_files',makelist), 'modelspec.functional_runs')])]) """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ level1 = pe.Workflow(name="level1") level1.base_dir = os.path.abspath('spm_face_tutorial/workingdir') level1.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,l1pipeline,[('struct', 'preproc.coregister.source'), ('func','preproc.realign.in_files')]) ]) """ Setup storage results --------------------- Use :class:`nipype.interfaces.io.DataSink` to store selected outputs from the pipeline in a specific location. This allows the user to selectively choose important output bits from the analysis and keep them. The first step is to create a datasink node and then to connect outputs from the modules above to storage locations. These take the following form directory_name[.[@]subdir] where parts between [] are optional. For example 'realign.@mean' below creates a directory called realign in 'l1output/subject_id/' and stores the mean image output from the Realign process in the realign directory. If the @ is left out, then a sub-directory with the name 'mean' would be created and the mean image would be copied to that directory. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('spm_auditory_tutorial/l1output') def getstripdir(subject_id): import os return os.path.join(os.path.abspath('spm_auditory_tutorial/workingdir'),'_subject_id_%s' % subject_id) # store relevant outputs from various stages of the 1st level analysis level1.connect([(infosource, datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, datasink,[('analysis.contrastestimate.con_images','contrasts.@con'), ('analysis.contrastestimate.spmT_images','contrasts.@T'), ('paramanalysis.contrastestimate.con_images','paramcontrasts.@con'), ('paramanalysis.contrastestimate.spmT_images','paramcontrasts.@T')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': level1.run() level1.write_graph() nipype-0.11.0/examples/fmri_spm_nested.py000077500000000000000000000433421257611314500204610ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ========================== fMRI: SPM nested workflows ========================== The fmri_spm.py integrates several interfaces to perform a first and second level analysis on a two-subject data set. The tutorial can be found in the examples folder. Run the tutorial from inside the nipype tutorial directory:: python fmri_spm_nested.py Import necessary modules from nipype.""" import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.interfaces.matlab as mlab # how to run matlab import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.rapidart as ra # artifact detection import nipype.algorithms.modelgen as model # model specification import os # system functions """ Preliminaries ------------- Set any package specific configuration. The output file format for FSL routines is being set to uncompressed NIFTI and a specific version of matlab is being used. The uncompressed format is required because SPM does not handle compressed NIFTI. """ # Tell fsl to generate all output in uncompressed nifti format fsl.FSLCommand.set_default_output_type('NIFTI') # Set the way matlab should be called #mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodesktop -nosplash") #mlab.MatlabCommand.set_default_paths('/software/spm8') """ Setting up workflows -------------------- In this tutorial we will be setting up a hierarchical workflow for spm analysis. This will demonstrate how pre-defined workflows can be setup and shared across users, projects and labs. Setup preprocessing workflow ---------------------------- This is a generic preprocessing workflow that can be used by different analyses """ preproc = pe.Workflow(name='preproc') """Use :class:`nipype.interfaces.spm.Realign` for motion correction and register all images to the mean image. """ realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = pe.Node(interface=ra.ArtifactDetect(), name="art") art.inputs.use_differences = [True, False] art.inputs.use_norm = True art.inputs.norm_threshold = 1 art.inputs.zintensity_threshold = 3 art.inputs.mask_type = 'file' art.inputs.parameter_source = 'SPM' """Skull strip structural images using :class:`nipype.interfaces.fsl.BET`. """ skullstrip = pe.Node(interface=fsl.BET(), name="skullstrip") skullstrip.inputs.mask = True """Use :class:`nipype.interfaces.spm.Coregister` to perform a rigid body registration of the functional data to the structural data. """ coregister = pe.Node(interface=spm.Coregister(), name="coregister") coregister.inputs.jobtype = 'estimate' """Warp functional and structural data to SPM's T1 template using :class:`nipype.interfaces.spm.Normalize`. The tutorial data set includes the template image, T1.nii. """ normalize = pe.Node(interface=spm.Normalize(), name = "normalize") normalize.inputs.template = os.path.abspath('data/T1.nii') """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = pe.Node(interface=spm.Smooth(), name = "smooth") fwhmlist = [4] smooth.iterables = ('fwhm',fwhmlist) preproc.connect([(realign,coregister,[('mean_image', 'source'), ('realigned_files','apply_to_files')]), (coregister, normalize, [('coregistered_files','apply_to_files')]), (normalize, smooth, [('normalized_files', 'in_files')]), (normalize,skullstrip,[('normalized_source','in_file')]), (realign,art,[('realignment_parameters','realignment_parameters')]), (normalize,art,[('normalized_files','realigned_files')]), (skullstrip,art,[('mask_file','mask_file')]), ]) """ Set up analysis workflow ------------------------ """ l1analysis = pe.Workflow(name='analysis') """Generate SPM-specific design information using :class:`nipype.interfaces.spm.SpecifyModel`. """ modelspec = pe.Node(interface=model.SpecifySPMModel(), name= "modelspec") modelspec.inputs.concatenate_runs = True """Generate a first level SPM.mat file for analysis :class:`nipype.interfaces.spm.Level1Design`. """ level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} """Use :class:`nipype.interfaces.spm.EstimateModel` to determine the parameters of the model. """ level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} """Use :class:`nipype.interfaces.spm.EstimateContrast` to estimate the first level contrasts specified in a few steps above. """ contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") """Use :class: `nipype.interfaces.utility.Select` to select each contrast for reporting. """ selectcontrast = pe.Node(interface=util.Select(), name="selectcontrast") """Use :class:`nipype.interfaces.fsl.Overlay` to combine the statistical output of the contrast estimate and a background image into one volume. """ overlaystats = pe.Node(interface=fsl.Overlay(), name="overlaystats") overlaystats.inputs.stat_thresh = (3,10) overlaystats.inputs.show_negative_stats=True overlaystats.inputs.auto_thresh_bg=True """Use :class:`nipype.interfaces.fsl.Slicer` to create images of the overlaid statistical volumes for a report of the first-level results. """ slicestats = pe.Node(interface=fsl.Slicer(), name="slicestats") slicestats.inputs.all_axial = True slicestats.inputs.image_width = 750 l1analysis.connect([(modelspec,level1design,[('session_info','session_info')]), (level1design,level1estimate,[('spm_mat_file','spm_mat_file')]), (level1estimate,contrastestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), (contrastestimate,selectcontrast,[('spmT_images','inlist')]), (selectcontrast,overlaystats,[('out','stat_image')]), (overlaystats,slicestats,[('out_file','in_file')]) ]) """ Preproc + Analysis pipeline --------------------------- """ l1pipeline = pe.Workflow(name='firstlevel') l1pipeline.connect([(preproc, l1analysis, [('realign.realignment_parameters', 'modelspec.realignment_parameters'), ('smooth.smoothed_files', 'modelspec.functional_runs'), ('art.outlier_files', 'modelspec.outlier_files'), ('skullstrip.mask_file', 'level1design.mask_image'), ('normalize.normalized_source', 'overlaystats.background_image')]), ]) """ Data specific components ------------------------ The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, ``s1`` and ``s2``. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii. Below we set some variables to inform the ``datasource`` about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (``struct`` or ``func``). These fields become the output fields of the ``datasource`` node in the pipeline. In the example below, run 'f3' is of type 'func' and gets mapped to a nifti filename through a template '%s.nii'. So 'f3' would become 'f3.nii'. """ # Specify the location of the data. data_dir = os.path.abspath('data') # Specify the subject directories subject_list = ['s1', 's3'] # Map field names to individual subject runs. info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") """Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The ``datasource`` attribute ``iterables`` tells the pipeline engine that it should repeat the analysis on each of the items in the ``subject_list``. In the current example, the entire first level preprocessing and estimation will be repeated for each subject contained in subject_list. """ infosource.iterables = ('subject_id', subject_list) """ Now we create a :class:`nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The :class:`nipype.pipeline.NodeWrapper` module wraps the interface object and provides additional housekeeping and pipeline specific functionality. """ datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Experimental paradigm specific components ----------------------------------------- Here we create a function that returns subject-specific information about the experimental paradigm. This is used by the :class:`nipype.interfaces.spm.SpecifyModel` to create the information necessary to generate an SPM design matrix. In this tutorial, the same paradigm was used for every participant. """ def subjectinfo(subject_id): from nipype.interfaces.base import Bunch from copy import deepcopy print "Subject ID: %s\n"%str(subject_id) output = [] names = ['Task-Odd','Task-Even'] for r in range(4): onsets = [range(15,240,60),range(45,240,60)] output.insert(r, Bunch(conditions=names, onsets=deepcopy(onsets), durations=[[15] for s in names], amplitudes=None, tmod=None, pmod=None, regressor_names=None, regressors=None)) return output """Setup the contrast structure that needs to be evaluated. This is a list of lists. The inner list specifies the contrasts and has the following format - [Name,Stat,[list of condition names],[weights on those conditions]. The condition names must match the `names` listed in the `subjectinfo` function described above. """ cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrasts = [cont1,cont2] # set up node specific inputs modelspecref = l1pipeline.inputs.analysis.modelspec modelspecref.input_units = 'secs' modelspecref.output_units = 'secs' modelspecref.time_repetition = 3. modelspecref.high_pass_filter_cutoff = 120 l1designref = l1pipeline.inputs.analysis.level1design l1designref.timing_units = modelspecref.output_units l1designref.interscan_interval = modelspecref.time_repetition l1pipeline.inputs.analysis.contrastestimate.contrasts = contrasts # Iterate over each contrast and create report images. selectcontrast.iterables = ('index',[[i] for i in range(len(contrasts))]) """ Setup the pipeline ------------------ The nodes created above do not describe the flow of data. They merely describe the parameters used for each function. In this section we setup the connections between the nodes such that appropriate outputs from nodes are piped into appropriate inputs of other nodes. Use the :class:`nipype.pipeline.engine.Pipeline` to create a graph-based execution pipeline for first level analysis. The config options tells the pipeline engine to use `workdir` as the disk location to use when running the processes and keeping their outputs. The `use_parameterized_dirs` tells the engine to create sub-directories under `workdir` corresponding to the iterables in the pipeline. Thus for this pipeline there will be subject specific sub-directories. The ``nipype.pipeline.engine.Pipeline.connect`` function creates the links between the processes, i.e., how data should flow in and out of the processing nodes. """ level1 = pe.Workflow(name="level1") level1.base_dir = os.path.abspath('spm_tutorial2/workingdir') level1.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource,l1pipeline,[('func','preproc.realign.in_files'), ('struct', 'preproc.coregister.target'), ('struct', 'preproc.normalize.source')]), (infosource,l1pipeline,[(('subject_id', subjectinfo), 'analysis.modelspec.subject_info')]), ]) """ Setup storage results --------------------- Use :class:`nipype.interfaces.io.DataSink` to store selected outputs from the pipeline in a specific location. This allows the user to selectively choose important output bits from the analysis and keep them. The first step is to create a datasink node and then to connect outputs from the modules above to storage locations. These take the following form directory_name[.[@]subdir] where parts between [] are optional. For example 'realign.@mean' below creates a directory called realign in 'l1output/subject_id/' and stores the mean image output from the Realign process in the realign directory. If the @ is left out, then a sub-directory with the name 'mean' would be created and the mean image would be copied to that directory. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('spm_tutorial2/l1output') report = pe.Node(interface=nio.DataSink(), name='report') report.inputs.base_directory = os.path.abspath('spm_tutorial2/report') report.inputs.parameterization = False def getstripdir(subject_id): import os return os.path.join(os.path.abspath('spm_tutorial2/workingdir'),'_subject_id_%s' % subject_id) # store relevant outputs from various stages of the 1st level analysis level1.connect([(infosource, datasink,[('subject_id','container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, datasink,[('analysis.contrastestimate.con_images','contrasts.@con'), ('analysis.contrastestimate.spmT_images','contrasts.@T')]), (infosource, report,[('subject_id', 'container'), (('subject_id', getstripdir),'strip_dir')]), (l1pipeline, report,[('analysis.slicestats.out_file', '@report')]), ]) """ Execute the pipeline -------------------- The code discussed above sets up all the necessary data structures with appropriate parameters and the connectivity between the processes, but does not generate any output. To actually run the analysis on the data the ``nipype.pipeline.engine.Pipeline.Run`` function needs to be called. """ if __name__ == '__main__': level1.run('MultiProc') level1.write_graph() """ Setup level 2 pipeline ---------------------- Use :class:`nipype.interfaces.io.DataGrabber` to extract the contrast images across a group of first level subjects. Unlike the previous pipeline that iterated over subjects, this pipeline will iterate over contrasts. """ # collect all the con images for each contrast. contrast_ids = range(1,len(contrasts)+1) l2source = pe.Node(nio.DataGrabber(infields=['fwhm', 'con']), name="l2source") # we use .*i* to capture both .img (SPM8) and .nii (SPM12) l2source.inputs.template=os.path.abspath('spm_tutorial2/l1output/*/con*/*/_fwhm_%d/con_%04d.*i*') # iterate over all contrast images l2source.iterables = [('fwhm',fwhmlist), ('con',contrast_ids)] l2source.inputs.sort_filelist = True """Use :class:`nipype.interfaces.spm.OneSampleTTestDesign` to perform a simple statistical analysis of the contrasts from the group of subjects (n=2 in this example). """ # setup a 1-sample t-test node onesamplettestdes = pe.Node(interface=spm.OneSampleTTestDesign(), name="onesampttestdes") l2estimate = pe.Node(interface=spm.EstimateModel(), name="level2estimate") l2estimate.inputs.estimation_method = {'Classical' : 1} l2conestimate = pe.Node(interface = spm.EstimateContrast(), name="level2conestimate") cont1 = ('Group','T', ['mean'],[1]) l2conestimate.inputs.contrasts = [cont1] l2conestimate.inputs.group_contrast = True """As before, we setup a pipeline to connect these two nodes (l2source -> onesamplettest). """ l2pipeline = pe.Workflow(name="level2") l2pipeline.base_dir = os.path.abspath('spm_tutorial2/l2output') l2pipeline.connect([(l2source,onesamplettestdes,[('outfiles','in_files')]), (onesamplettestdes,l2estimate,[('spm_mat_file','spm_mat_file')]), (l2estimate,l2conestimate,[('spm_mat_file','spm_mat_file'), ('beta_images','beta_images'), ('residual_image','residual_image')]), ]) """ Execute the second level pipeline --------------------------------- """ if __name__ == '__main__': l2pipeline.run('MultiProc') nipype-0.11.0/examples/frontiers_paper/000077500000000000000000000000001257611314500201225ustar00rootroot00000000000000nipype-0.11.0/examples/frontiers_paper/smoothing_comparison.py000066400000000000000000000200251257611314500247340ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ =========================== Paper: Smoothing comparison =========================== """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.nipy as nipy import nipype.interfaces.utility as util import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model specification import nipype.workflows.fmri.fsl as fsl_wf from nipype.interfaces.base import Bunch import os # system functions preprocessing = pe.Workflow(name="preprocessing") iter_fwhm = pe.Node(interface=util.IdentityInterface(fields=["fwhm"]), name="iter_fwhm") iter_fwhm.iterables = [('fwhm', [4, 8])] iter_smoothing_method = pe.Node(interface=util.IdentityInterface(fields=["smoothing_method"]), name="iter_smoothing_method") iter_smoothing_method.iterables = [('smoothing_method',['isotropic_voxel', 'anisotropic_voxel', 'isotropic_surface'])] realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True isotropic_voxel_smooth = pe.Node(interface=spm.Smooth(), name="isotropic_voxel_smooth") preprocessing.connect(realign, "realigned_files", isotropic_voxel_smooth, "in_files") preprocessing.connect(iter_fwhm, "fwhm", isotropic_voxel_smooth, "fwhm") compute_mask = pe.Node(interface=nipy.ComputeMask(), name="compute_mask") preprocessing.connect(realign, "mean_image", compute_mask, "mean_volume") anisotropic_voxel_smooth = fsl_wf.create_susan_smooth(name="anisotropic_voxel_smooth", separate_masks=False) anisotropic_voxel_smooth.inputs.smooth.output_type = 'NIFTI' preprocessing.connect(realign, "realigned_files", anisotropic_voxel_smooth, "inputnode.in_files") preprocessing.connect(iter_fwhm, "fwhm", anisotropic_voxel_smooth, "inputnode.fwhm") preprocessing.connect(compute_mask, "brain_mask", anisotropic_voxel_smooth, 'inputnode.mask_file') recon_all = pe.Node(interface=fs.ReconAll(), name = "recon_all") surfregister = pe.Node(interface=fs.BBRegister(),name='surfregister') surfregister.inputs.init = 'fsl' surfregister.inputs.contrast_type = 't2' preprocessing.connect(realign, 'mean_image', surfregister, 'source_file') preprocessing.connect(recon_all, 'subject_id', surfregister, 'subject_id') preprocessing.connect(recon_all, 'subjects_dir', surfregister, 'subjects_dir') isotropic_surface_smooth = pe.MapNode(interface=fs.Smooth(proj_frac_avg=(0,1,0.1)), iterfield=['in_file'], name="isotropic_surface_smooth") preprocessing.connect(surfregister, 'out_reg_file', isotropic_surface_smooth, 'reg_file') preprocessing.connect(realign, "realigned_files", isotropic_surface_smooth, "in_file") preprocessing.connect(iter_fwhm, "fwhm", isotropic_surface_smooth, "surface_fwhm") preprocessing.connect(iter_fwhm, "fwhm", isotropic_surface_smooth, "vol_fwhm") preprocessing.connect(recon_all, 'subjects_dir', isotropic_surface_smooth, 'subjects_dir') merge_smoothed_files = pe.Node(interface=util.Merge(3), name='merge_smoothed_files') preprocessing.connect(isotropic_voxel_smooth, 'smoothed_files', merge_smoothed_files, 'in1') preprocessing.connect(anisotropic_voxel_smooth, 'outputnode.smoothed_files', merge_smoothed_files, 'in2') preprocessing.connect(isotropic_surface_smooth, 'smoothed_file', merge_smoothed_files, 'in3') select_smoothed_files = pe.Node(interface=util.Select(), name="select_smoothed_files") preprocessing.connect(merge_smoothed_files, 'out', select_smoothed_files, 'inlist') def chooseindex(roi): return {'isotropic_voxel':range(0,4), 'anisotropic_voxel':range(4,8), 'isotropic_surface':range(8,12)}[roi] preprocessing.connect(iter_smoothing_method, ("smoothing_method", chooseindex), select_smoothed_files, 'index') rename = pe.MapNode(util.Rename(format_string="%(orig)s"), name="rename", iterfield=['in_file']) rename.inputs.parse_string = "(?P.*)" preprocessing.connect(select_smoothed_files, 'out', rename, 'in_file') specify_model = pe.Node(interface=model.SpecifyModel(), name="specify_model") specify_model.inputs.input_units = 'secs' specify_model.inputs.time_repetition = 3. specify_model.inputs.high_pass_filter_cutoff = 120 specify_model.inputs.subject_info = [Bunch(conditions=['Task-Odd','Task-Even'], onsets=[range(15,240,60), range(45,240,60)], durations=[[15], [15]])]*4 level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} level1design.inputs.timing_units = 'secs' level1design.inputs.interscan_interval = specify_model.inputs.time_repetition level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") contrastestimate.inputs.contrasts = [('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5])] modelling = pe.Workflow(name="modelling") modelling.connect(specify_model, 'session_info', level1design, 'session_info') modelling.connect(level1design, 'spm_mat_file', level1estimate, 'spm_mat_file') modelling.connect(level1estimate,'spm_mat_file', contrastestimate, 'spm_mat_file') modelling.connect(level1estimate,'beta_images', contrastestimate,'beta_images') modelling.connect(level1estimate,'residual_image', contrastestimate, 'residual_image') main_workflow = pe.Workflow(name="main_workflow") main_workflow.base_dir = "smoothing_comparison_workflow" main_workflow.connect(preprocessing, "realign.realignment_parameters", modelling, "specify_model.realignment_parameters") main_workflow.connect(preprocessing, "select_smoothed_files.out", modelling, "specify_model.functional_runs") main_workflow.connect(preprocessing, "compute_mask.brain_mask", modelling, "level1design.mask_image") datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name = 'datasource') datasource.inputs.base_directory = os.path.abspath('data') datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = info = dict(func=[['subject_id', ['f3','f5','f7','f10']]], struct=[['subject_id','struct']]) datasource.inputs.subject_id = 's1' datasource.inputs.sort_filelist = True main_workflow.connect(datasource, 'func', preprocessing, 'realign.in_files') main_workflow.connect(datasource, 'struct', preprocessing, 'recon_all.T1_files') datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('smoothing_comparison_workflow/output') datasink.inputs.regexp_substitutions = [("_rename[0-9]", "")] main_workflow.connect(modelling, 'contrastestimate.spmT_images', datasink, 'contrasts') main_workflow.connect(preprocessing, 'rename.out_file', datasink, 'smoothed_epi') main_workflow.run() main_workflow.write_graph() nipype-0.11.0/examples/frontiers_paper/workflow_from_scratch.py000066400000000000000000000160721257611314500251060ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ===================== Workflow from scratch ===================== """ import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.spm as spm # spm import nipype.pipeline.engine as pe # pypeline engine import nipype.algorithms.modelgen as model # model specification from nipype.interfaces.base import Bunch import os # system functions """In the following section, to showcase NiPyPe, we will describe how to create and extend a typical fMRI processing pipeline. We will begin with a basic processing layout and follow with extending it by adding/exchanging different components. Most fMRI pipeline can be divided into two sections - preprocessing and modelling. First one deals with cleaning data from confounds and noise and the second one fits a model based on the experimental design. Preprocessing stage in our first iteration of a pipeline will consist of only two steps: realignment and smoothing. In NiPyPe Every processing step consist of an Interface (which defines how to execute corresponding software) encapsulated in a Node (which defines for example a unique name). For realignment (motion correction achieved by coregistering all volumes to the mean) and smoothing (convolution with 3D Gaussian kernel) we will use SPM implementation. Definition of appropriate nodes can be found in Listing 1 (TODO). Inputs (such as register_to_mean from listing 1) of nodes are accessible through the inputs property. Upon setting any input its type is verified to avoid errors during the execution.""" realign = pe.Node(interface=spm.Realign(), name="realign") realign.inputs.register_to_mean = True smooth = pe.Node(interface=spm.Smooth(), name="smooth") smooth.inputs.fwhm = 4 """To connect two nodes a Workflow has to be created. connect() method of a Workflow allows to specify which outputs of which Nodes should be connected to which inputs of which Nodes (see Listing 2). By connecting realigned_files output of realign to in_files input of Smooth we have created a simple preprocessing workflow (see Figure TODO).""" preprocessing = pe.Workflow(name="preprocessing") preprocessing.connect(realign, "realigned_files", smooth, "in_files") """Creating a modelling workflow which will define the design, estimate model and contrasts follows the same suite. We will again use SPM implementations. NiPyPe, however, adds extra abstraction layer to model definition which allows using the same definition for many model estimation implemantations (for example one from FSL or nippy). Therefore we will need four nodes: SpecifyModel (NiPyPe specific abstraction layer), Level1Design (SPM design definition), ModelEstimate, and ContrastEstimate. The connected modelling Workflow can be seen on Figure TODO. Model specification supports block, event and sparse designs. Contrasts provided to ContrastEstimate are defined using the same names of regressors as defined in the SpecifyModel.""" specify_model = pe.Node(interface=model.SpecifyModel(), name="specify_model") specify_model.inputs.input_units = 'secs' specify_model.inputs.time_repetition = 3. specify_model.inputs.high_pass_filter_cutoff = 120 specify_model.inputs.subject_info = [Bunch(conditions=['Task-Odd','Task-Even'], onsets=[range(15,240,60), range(45,240,60)], durations=[[15], [15]])]*4 level1design = pe.Node(interface=spm.Level1Design(), name= "level1design") level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} level1design.inputs.timing_units = 'secs' level1design.inputs.interscan_interval = specify_model.inputs.time_repetition level1estimate = pe.Node(interface=spm.EstimateModel(), name="level1estimate") level1estimate.inputs.estimation_method = {'Classical' : 1} contrastestimate = pe.Node(interface = spm.EstimateContrast(), name="contrastestimate") cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) contrastestimate.inputs.contrasts = [cont1, cont2] modelling = pe.Workflow(name="modelling") modelling.connect(specify_model, 'session_info', level1design, 'session_info') modelling.connect(level1design, 'spm_mat_file', level1estimate, 'spm_mat_file') modelling.connect(level1estimate,'spm_mat_file', contrastestimate,'spm_mat_file') modelling.connect(level1estimate,'beta_images', contrastestimate,'beta_images') modelling.connect(level1estimate,'residual_image', contrastestimate,'residual_image') """Having preprocessing and modelling workflows we need to connect them together, add data grabbing facility and save the results. For this we will create a master Workflow which will host preprocessing and model Workflows as well as DataGrabber and DataSink Nodes. NiPyPe allows connecting Nodes between Workflows. We will use this feature to connect realignment_parameters and smoothed_files to modelling workflow.""" main_workflow = pe.Workflow(name="main_workflow") main_workflow.base_dir = "workflow_from_scratch" main_workflow.connect(preprocessing, "realign.realignment_parameters", modelling, "specify_model.realignment_parameters") main_workflow.connect(preprocessing, "smooth.smoothed_files", modelling, "specify_model.functional_runs") """DataGrabber allows to define flexible search patterns which can be parameterized by user defined inputs (such as subject ID, session etc.). This allows to adapt to a wide range of file layouts. In our case we will parameterize it with subject ID. In this way we will be able to run it for different subjects. We can automate this by iterating over a list of subject Ids, by setting an iterables property on the subject_id input of DataGrabber. Its output will be connected to realignment node from preprocessing workflow.""" datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=['func']), name = 'datasource') datasource.inputs.base_directory = os.path.abspath('data') datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = dict(func=[['subject_id', ['f3','f5','f7','f10']]]) datasource.inputs.subject_id = 's1' datasource.inputs.sort_filelist = True main_workflow.connect(datasource, 'func', preprocessing, 'realign.in_files') """DataSink on the other side provides means to storing selected results to a specified location. It supports automatic creation of folder stricter and regular expression based substitutions. In this example we will store T maps.""" datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.abspath('workflow_from_scratch/output') main_workflow.connect(modelling, 'contrastestimate.spmT_images', datasink, 'contrasts.@T') main_workflow.run() main_workflow.write_graph() nipype-0.11.0/examples/howto_caching_example.py000066400000000000000000000027501257611314500216250ustar00rootroot00000000000000""" =========================================== HOWTO: Using caching without using Workflow =========================================== Using nipype in an imperative way: caching without workflow Note that in the following example, we are calling command-lines with disk I/O that persists across runs, but we never have to worry about the file names or the directories. The disk location of the persistence is encoded by hashes. To find out where an operation has been persisted, simply look in it's output variable:: out.runtime.cwd """ from nipype.interfaces import fsl fsl.FSLCommand.set_default_output_type('NIFTI') from nipype.caching import Memory import glob # First retrieve the list of files that we want to work upon in_files = glob.glob('data/*/f3.nii') # Create a memory context mem = Memory('.') # Apply an arbitrary (and pointless, here) threshold to the files) threshold = [mem.cache(fsl.Threshold)(in_file=f, thresh=i) for i, f in enumerate(in_files)] # Merge all these files along the time dimension out_merge = mem.cache(fsl.Merge)(dimension="t", in_files=[t.outputs.out_file for t in threshold], ) # And finally compute the mean out_mean = mem.cache(fsl.MeanImage)(in_file=out_merge.outputs.merged_file) # To avoid having increasing disk size we can keep only what was touched # in this run #mem.clear_previous_runs() # or what wasn't used since the start of 2011 #mem.clear_runs_since(year=2011) nipype-0.11.0/examples/nipype_tutorial.ipynb000066400000000000000000001330021257611314500212110ustar00rootroot00000000000000{ "metadata": { "_draft": { "nbviewer_url": "gisting : nipype.ipynb\r\n" }, "name": "nipype_tutorial" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Dissecting Nipype Workflows\n", "\n", "
\n", "Nipype team | contact: satra@mit.edu | nipy.org/nipype\n", "
\n", "(Hit Esc to get an overview)\n", "
[Latest version][notebook] | [Latest slideshow][slideshow]\n", "\n", "[notebook]: http://nbviewer.ipython.org/urls/raw.github.com/nipy/nipype/master/examples/nipype_tutorial.ipynb\n", "[slideshow]: http://slideviewer.herokuapp.com/url/raw.github.com/nipy/nipype/master/examples/nipype_tutorial.ipynb" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Contributors\n", "\n", "http://nipy.org/nipype/about.html#code-contributors\n", "\n", "# Funding\n", "\n", "- 1R03EB008673-01 from NIBIB, Satrajit Ghosh, Susan Whitfield-Gabrieli\n", "- 5R01MH081909-02 from NIMH, Mark D'Esposito\n", "- INCF\n", "\n", "# Conflict of interest\n", "\n", "
\n", "Satrajit Ghosh: TankThink Labs, LLC\n", "
" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# What is Nipype?\n", "\n", "
\n", "\n", "
\n", "Figure designed and created by: Arno Klein (www.mindboggle.info)\n", "
\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Make life a little easier\n", "\n", "\n", "\n", "Poline _et al._ (2012)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Many workflow systems out there\n", "\n", "- [BioImage Suite](http://www.bioimagesuite.org/)\n", "- [BIRN Tools](https://wiki.birncommunity.org/x/LgFrAQ)\n", "- [BrainVisa](http://brainvisa.info)\n", "- [CambaFX](http://www-bmu.psychiatry.cam.ac.uk/software/)\n", "- [JIST for MIPAV](http://www.nitrc.org/projects/jist/)\n", "- [LONI pipeline](http://pipeline.loni.ucla.edu)\n", "- [MEVIS Lab](http://www.mevislab.de)\n", "- [PSOM](http://code.google.com/p/psom/)\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Solution requirements\n", "\n", "Coming at it from a developer's perspective, we needed something\n", "\n", "- lightweight\n", "- scriptable\n", "- provided formal, common semantics\n", "- allowed interactive exploration\n", "- supported efficient batch processing\n", "- enabled rapid algorithm prototyping\n", "- was flexible and adaptive\n", "- part of an ecosystem" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Python ecosystem\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Existing technologies\n", "\n", "**shell scripting**:\n", "\n", " Can be quick to do, and powerful, but only provides application specific \n", " scalability, and not easy to port across different architectures.\n", "\n", "**make/CMake**:\n", "\n", " Similar in concept to workflow execution in Nipype, but again limited by the\n", " need for command line tools and flexibility in terms of scaling across\n", " hardware architectures (although see [makeflow](http://nd.edu/~ccl/software/makeflow).\n", "\n", "**Octave/MATLAB**:\n", "\n", " Integration with other tools is *ad hoc* (i.e., system call) and dataflow is\n", " managed at a programmatic level. However, see [PSOM](http://code.google.com/p/psom/) which offers a nice\n", " alternative to some aspects of Nipype for Octave/Matlab users.\n", "\n", "**Graphical options**: (e.g., [LONI Pipeline](http://pipeline.loni.ucla.edu), [VisTrails](http://www.vistrails.org/))\n", "\n", " Are easy to use but reduces flexibility relative to scripting options." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#Nipype architecture\n", "\n", "" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "notes" } }, "source": [ "* **Interface**: Wraps a program or function\n", "\n", "- **Node/MapNode**: Wraps an `Interface` for use in a Workflow that provides\n", " caching and other goodies (e.g., pseudo-sandbox)\n", "- **Workflow**: A *graph* or *forest of graphs* whose nodes are of type `Node`,\n", " `MapNode` or `Workflow` and whose edges represent data flow\n", "\n", "* **Plugin**: A component that describes how a `Workflow` should be executed" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Software interfaces\n", "\n", "Currently supported (5-2-2013). [Click here for latest](http://www.mit.edu/~satra/nipype-nightly/documentation.html)\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "Most used/contributed policy!\n", "\n", "Not all components of these packages are available." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "skip" } }, "source": [ "# Workflows\n", "\n", "- Properties:\n", "\n", " - processing pipeline is a directed acyclic graph (DAG)\n", " - nodes are processes\n", " - edges represent data flow\n", " - compact represenation for any process\n", " - code and data separation" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Execution Plugins\n", "\n", "Allows seamless execution across many architectures\n", "\n", " - Local\n", "\n", " - Serial\n", " - Multicore\n", "\n", " - Clusters\n", "\n", " - HTCondor\n", " - PBS/Torque/SGE/LSF (native and via IPython)\n", " - SSH (via IPython)\n", " - Soma Workflow" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Learn Nipype concepts in 10 easy steps\n", "\n", "\n", "1. Installing and testing the installation \n", "2. Working with interfaces\n", "3. Using Nipype caching\n", "4. Creating Nodes, MapNodes and Workflows\n", "5. Getting and saving data\n", "6. Using Iterables\n", "7. Function nodes\n", "8. Distributed computation\n", "9. Connecting to databases\n", "10. Execution configuration options" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 1. Installing Nipype\n", "\n", "## Scientific Python:\n", "\n", "* Debian/Ubuntu/Scientific Fedora\n", "* [Canopy from Enthought](https://www.enthought.com/products/canopy/)\n", "* [Anaconda from Contnuum Analytics](https://store.continuum.io/cshop/anaconda/)\n", "\n", "## Installing Nipype:\n", "\n", "* Available from [@NeuroDebian](http://neuro.debian.net/pkgs/python-nipype.html),\n", " [@PyPI](http://pypi.python.org/pypi/nipype/), and\n", " [@GitHub](http://github.com/nipy/nipype)\n", " \n", " - pip install nipype\n", " - easy_install nipype\n", " - sudo apt-get install python-nipype\n", "\n", "* Dependencies: networkx, nibabel, numpy, scipy, traits\n", "\n", "## Running Nipype ([Quickstart](http://nipy.org/nipype/quickstart.html)):\n", "\n", "* Ensure underlying tools are installed and accessible\n", "* Nipype **is a wrapper, not a substitute** for AFNI, ANTS, FreeSurfer, FSL, SPM,\n", " NiPy, etc.,." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Step 1. Testing nipype" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```\n", "$ ipython notebook\n", "```" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import nipype\n", "\n", "# Comment the following section to increase verbosity of output\n", "nipype.config.set('logging', 'workflow_level', 'CRITICAL')\n", "nipype.config.set('logging', 'interface_level', 'CRITICAL')\n", "nipype.logging.update_logging(nipype.config)\n", "\n", "nipype.test(verbose=0) # Increase verbosity parameter for more info" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "If all goes well you will see an OK:\n", "\n", " ----------------------------------------------------------------------\n", " Ran 2497 tests in 68.486s\n", "\n", " OK (SKIP=13)\n", "\n", "The number of tests and time will vary depending on which interfaces you have installed on your system." ] }, { "cell_type": "code", "collapsed": false, "input": [ "nipype.get_info()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Environment and data setup\n", "\n", "Setting up your Ipython notebook environment and download some data to play with" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%pylab inline" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "# Some preliminaries\n", "import os\n", "cwd = os.getcwd()\n", "tutorial_dir = '/software/temp/nipype-tutorial/ohbm/'\n", "if not os.path.exists(tutorial_dir):\n", " os.mkdir(tutorial_dir)\n", "os.chdir(tutorial_dir)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "import urllib\n", "required_files = ['ds107/sub001/BOLD/task001_run001/bold.nii.gz',\n", " 'ds107/sub001/BOLD/task001_run002/bold.nii.gz',\n", " 'ds107/sub001/anatomy/highres001.nii.gz',\n", " 'ds107/sub044/BOLD/task001_run001/bold.nii.gz',\n", " 'ds107/sub044/BOLD/task001_run002/bold.nii.gz',\n", " 'ds107/sub044/anatomy/highres001.nii.gz'\n", " ]\n", "base_url = 'http://openfmri.aws.amazon.com.s3.amazonaws.com/'\n", "for filepath in required_files:\n", " file_location = os.path.join(tutorial_dir, filepath)\n", " if not os.path.exists(file_location):\n", " print('Retrieving: ' + file_location)\n", " os.makedirs(os.path.dirname(file_location))\n", " urllib.urlretrieve(base_url + filepath, file_location)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 2. Working with interfaces" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import nipype.algorithms" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.fsl import DTIFit\n", "from nipype.interfaces.spm import Realign" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Finding interface inputs and outputs and examples" ] }, { "cell_type": "code", "collapsed": false, "input": [ "DTIFit.help()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "Realign.help()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Creating a directory for running interfaces" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import os\n", "from shutil import copyfile\n", "library_dir = os.path.join(tutorial_dir, 'as_a_library')\n", "if not os.path.exists(library_dir):\n", " os.mkdir(library_dir)\n", "os.chdir(library_dir)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Executing interfaces" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.freesurfer import MRIConvert\n", "convert = MRIConvert(in_file='../ds107/sub001/BOLD/task001_run001/bold.nii.gz',\n", " out_file='ds107.nii')\n", "print(convert.cmdline)\n", "results = convert.run(terminal_output='none') # allatonce, stream (default), file" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "results.outputs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Other ways" ] }, { "cell_type": "code", "collapsed": false, "input": [ "convert = MRIConvert()\n", "convert.inputs.in_file='../ds107/sub001/BOLD/task001_run001/bold.nii.gz'\n", "convert.inputs.out_file='ds107.nii'\n", "convert.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "convert = MRIConvert()\n", "convert.run(in_file='../ds107/sub001/BOLD/task001_run001/bold.nii.gz',\n", " out_file='ds107.nii')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": true, "input": [ "convert.inputs" ], "language": "python", "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#### Look at only the defined inputs" ] }, { "cell_type": "code", "collapsed": false, "input": [ "results.inputs" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Experiment with other interfaces\n", "\n", "For example, run realignment with SPM" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.spm import Realign\n", "results1 = Realign(in_files='ds107.nii',\n", " register_to_mean=False).run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "And now use FSL" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.fsl import MCFLIRT\n", "results2 = MCFLIRT(in_file='ds107.nii', ref_vol=0,\n", " save_plots=True).run()" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Now we can look at some results" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print results1.runtime.duration, results2.runtime.duration\n", "subplot(211);plot(genfromtxt('ds107_mcf.nii.gz.par')[:, 3:]);title('FSL')\n", "subplot(212);plot(genfromtxt('rp_ds107.txt')[:,:3]);title('SPM')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### if i execute the MCFLIRT line again, well, it runs again!" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 3. Nipype caching" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.caching import Memory\n", "mem = Memory('.')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Create `cacheable` objects" ] }, { "cell_type": "code", "collapsed": false, "input": [ "spm_realign = mem.cache(Realign)\n", "fsl_realign = mem.cache(MCFLIRT)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Execute interfaces" ] }, { "cell_type": "code", "collapsed": false, "input": [ "spm_results = spm_realign(in_files='ds107.nii', register_to_mean=False)\n", "fsl_results = fsl_realign(in_file='ds107.nii', ref_vol=0, save_plots=True)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "subplot(211);plot(genfromtxt(fsl_results.outputs.par_file)[:, 3:])\n", "subplot(212);plot(genfromtxt(spm_results.outputs.realignment_parameters)[:,:3])" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "spm_results = spm_realign(in_files='ds107.nii', register_to_mean=False)\n", "fsl_results = fsl_realign(in_file='ds107.nii', ref_vol=0, save_plots=True)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# More caching" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from os.path import abspath as opap\n", "files = [opap('../ds107/sub001/BOLD/task001_run001/bold.nii.gz'),\n", " opap('../ds107/sub001/BOLD/task001_run002/bold.nii.gz')]\n", "converter = mem.cache(MRIConvert)\n", "newfiles = []\n", "for idx, fname in enumerate(files):\n", " newfiles.append(converter(in_file=fname,\n", " out_type='nii').outputs.out_file)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "os.chdir(tutorial_dir)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 4: Nodes, Mapnodes and workflows\n", "\n", "**Where:**" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.pipeline.engine import Node, MapNode, Workflow" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Node**:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "realign_spm = Node(Realign(), name='motion_correct')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Mapnode**:\n", "\n", "" ] }, { "cell_type": "code", "collapsed": false, "input": [ "convert2nii = MapNode(MRIConvert(out_type='nii'),\n", " iterfield=['in_file'],\n", " name='convert2nii')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# \"Hello World\" of Nipype workflows" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Connect them up:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "realignflow = Workflow(name='realign_with_spm')\n", "realignflow.connect(convert2nii, 'out_file',\n", " realign_spm, 'in_files')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "convert2nii.inputs.in_file = files\n", "realign_spm.inputs.register_to_mean = False\n", "\n", "realignflow.base_dir = opap('.')\n", "realignflow.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Visualize the workflow" ] }, { "cell_type": "code", "collapsed": false, "input": [ "realignflow.write_graph()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.core.display import Image\n", "Image('realign_with_spm/graph.dot.png')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "realignflow.write_graph(graph2use='orig')\n", "Image('realign_with_spm/graph_detailed.dot.png')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 5. Getting and saving data\n", "\n", "### Instead of assigning data ourselves, let's *glob* it" ] }, { "cell_type": "code", "collapsed": false, "input": [ "os.chdir(tutorial_dir)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.io import DataGrabber, DataFinder\n", "ds = Node(DataGrabber(infields=['subject_id'], outfields=['func']),\n", " name='datasource')\n", "ds.inputs.base_directory = opap('ds107')\n", "ds.inputs.template = '%s/BOLD/task001*/bold.nii.gz'\n", "ds.inputs.sort_filelist = True\n", "\n", "ds.inputs.subject_id = 'sub001'\n", "print ds.run().outputs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "ds.inputs.subject_id = 'sub044'\n", "print ds.run().outputs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Multiple files\n", "\n", "### A little more practical usage" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ds = Node(DataGrabber(infields=['subject_id', 'task_id'],\n", " outfields=['func', 'anat']),\n", " name='datasource')\n", "ds.inputs.base_directory = opap('ds107')\n", "ds.inputs.template = '*'\n", "ds.inputs.template_args = {'func': [['subject_id', 'task_id']],\n", " 'anat': [['subject_id']]}\n", "ds.inputs.field_template = {'func': '%s/BOLD/task%03d*/bold.nii.gz',\n", " 'anat': '%s/anatomy/highres001.nii.gz'}\n", "ds.inputs.sort_filelist = True\n", "ds.inputs.subject_id = 'sub001'\n", "ds.inputs.task_id = 1\n", "print ds.run().outputs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "# Connecting to computation" ] }, { "cell_type": "code", "collapsed": false, "input": [ "convert2nii = MapNode(MRIConvert(out_type='nii'),\n", " iterfield=['in_file'],\n", " name='convert2nii')\n", "\n", "realign_spm = Node(Realign(), name='motion_correct')\n", "realign_spm.inputs.register_to_mean = False\n", "\n", "connectedworkflow = Workflow(name='connectedtogether')\n", "connectedworkflow.base_dir = opap('working_dir')\n", "connectedworkflow.connect(ds, 'func', convert2nii, 'in_file')\n", "connectedworkflow.connect(convert2nii, 'out_file', realign_spm, 'in_files')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Data sinking\n", "\n", "###Take output computed in a workflow out of it." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.io import DataSink\n", "sinker = Node(DataSink(), name='sinker')\n", "sinker.inputs.base_directory = opap('output')\n", "connectedworkflow.connect(realign_spm, 'realigned_files',\n", " sinker, 'realigned')\n", "connectedworkflow.connect(realign_spm, 'realignment_parameters',\n", " sinker, 'realigned.@parameters')\n", "connectedworkflow.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### How to determine output location\n", "\n", " 'base_directory/container/parameterization/destloc/filename'\n", " \n", " destloc = [@]string[[.[@]]string[[.[@]]string]...] and\n", " destloc = realigned.@parameters --> 'realigned'\n", " destloc = realigned.parameters.@1 --> 'realigned/parameters'\n", " destloc = realigned.parameters.@2 --> 'realigned/parameters'\n", " filename comes from the input to the connect statement." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#Step 6: *iterables* - parametric execution\n", "\n", "**Workflow + iterables**: runs subgraph several times, attribute not input" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ds.iterables = ('subject_id', ['sub001', 'sub044'])\n", "connectedworkflow.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "#Putting it all together\n", "\n", "### iterables + MapNode + Node + Workflow + DataGrabber + DataSink" ] }, { "cell_type": "code", "collapsed": false, "input": [ "connectedworkflow.write_graph()\n", "Image('working_dir/connectedtogether/graph.dot.png')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Step 7: The Function interface\n", "\n", "### The do anything you want card" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.utility import Function\n", "\n", "def myfunc(input1, input2):\n", " \"\"\"Add and subtract two inputs\n", " \"\"\"\n", " return input1 + input2, input1 - input2\n", "\n", "calcfunc = Node(Function(input_names=['input1', 'input2'],\n", " output_names = ['sum', 'difference'],\n", " function=myfunc),\n", " name='mycalc')\n", "calcfunc.inputs.input1 = 1\n", "calcfunc.inputs.input2 = 2\n", "res = calcfunc.run()\n", "print res.outputs" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#Step 8: Distributed computing\n", "\n", "### Normally calling run executes the workflow in series" ] }, { "cell_type": "code", "collapsed": false, "input": [ "connectedworkflow.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### but you can scale very easily\n", "\n", "For example, to use multiple cores on your local machine" ] }, { "cell_type": "code", "collapsed": false, "input": [ "connectedworkflow.run('MultiProc', plugin_args={'n_procs': 4})" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### Or to other job managers\n", "\n", "- connectedworkflow.run('PBS', plugin_args={'qsub_args': '-q many'})\n", "- connectedworkflow.run('SGE', plugin_args={'qsub_args': '-q many'})\n", "- connectedworkflow.run('LSF', plugin_args={'qsub_args': '-q many'})\n", "- connectedworkflow.run('Condor')\n", "- connectedworkflow.run('IPython')\n", "\n", "### or submit graphs as a whole\n", "\n", "\n", "- connectedworkflow.run('PBSGraph', plugin_args={'qsub_args': '-q many'})\n", "- connectedworkflow.run('SGEGraph', plugin_args={'qsub_args': '-q many'})\n", "- connectedworkflow.run('CondorDAGMan')\n", "\n", "### Current Requirement: **SHARED FILESYSTEM**" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "### You can also set node specific plugin arguments" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "- node.plugin_args = {'qsub_args': '-l nodes=1:ppn=3', 'overwrite': True}\n" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#Step 9: Connecting to Databases" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from os.path import abspath as opap\n", "\n", "from nipype.interfaces.io import XNATSource\n", "from nipype.pipeline.engine import Node, Workflow\n", "from nipype.interfaces.fsl import BET\n", "\n", "subject_id = 'xnat_S00001'\n", "\n", "dg = Node(XNATSource(infields=['subject_id'],\n", " outfields=['struct'],\n", " config='/Users/satra/xnat_configs/nitrc_ir_config'),\n", " name='xnatsource')\n", "dg.inputs.query_template = ('/projects/fcon_1000/subjects/%s/experiments/xnat_E00001'\n", " '/scans/%s/resources/NIfTI/files')\n", "dg.inputs.query_template_args['struct'] = [['subject_id', 'anat_mprage_anonymized']]\n", "dg.inputs.subject_id = subject_id\n", "\n", "bet = Node(BET(), name='skull_stripper')\n", "\n", "wf = Workflow(name='testxnat')\n", "wf.base_dir = opap('xnattest')\n", "wf.connect(dg, 'struct', bet, 'in_file')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.io import XNATSink\n", "\n", "ds = Node(XNATSink(config='/Users/satra/xnat_configs/central_config'),\n", " name='xnatsink')\n", "ds.inputs.project_id = 'NPTEST'\n", "ds.inputs.subject_id = 'NPTEST_xnat_S00001'\n", "ds.inputs.experiment_id = 'test_xnat'\n", "ds.inputs.reconstruction_id = 'bet'\n", "ds.inputs.share = True\n", "wf.connect(bet, 'out_file', ds, 'brain')" ], "language": "python", "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "wf.run()" ], "language": "python", "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "#Step 10: Configuration options\n", "\n", "[Configurable options](http://nipy.org/nipype/users/config_file.html) control workflow and node execution options\n", "\n", "At the global level:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype import config, logging\n", "\n", "config.enable_debug_mode()\n", "logging.update_logging(config)\n", "\n", "config.set('execution', 'stop_on_first_crash', 'true')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "At the workflow level:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "wf.config['execution']['hash_method'] = 'content'" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Configurations can also be set at the node level." ] }, { "cell_type": "code", "collapsed": false, "input": [ "bet.config = {'execution': {'keep_unnecessary_outputs': 'true'}}" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "wf.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Reusable workflows" ] }, { "cell_type": "code", "collapsed": false, "input": [ "config.set_default_config()\n", "logging.update_logging(config)" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.workflows.fmri.fsl.preprocess import create_susan_smooth\n", "\n", "smooth = create_susan_smooth()\n", "smooth.inputs.inputnode.in_files = opap('output/realigned/_subject_id_sub044/rbold_out.nii')\n", "smooth.inputs.inputnode.fwhm = 5\n", "smooth.inputs.inputnode.mask_file = 'mask.nii'\n", "\n", "smooth.run() # Will error because mask.nii does not exist" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "from nipype.interfaces.fsl import BET, MeanImage, ImageMaths\n", "from nipype.pipeline.engine import Node\n", "\n", "\n", "remove_nan = Node(ImageMaths(op_string= '-nan'), name='nanremove')\n", "remove_nan.inputs.in_file = opap('output/realigned/_subject_id_sub044/rbold_out.nii')\n", "\n", "mi = Node(MeanImage(), name='mean')\n", "\n", "mask = Node(BET(mask=True), name='mask')\n", "\n", "wf = Workflow('reuse')\n", "wf.base_dir = opap('.')\n", "wf.connect(remove_nan, 'out_file', mi, 'in_file')\n", "wf.connect(mi, 'out_file', mask, 'in_file')\n", "wf.connect(mask, 'out_file', smooth, 'inputnode.mask_file')\n", "wf.connect(remove_nan, 'out_file', smooth, 'inputnode.in_files')\n", "\n", "wf.run()" ], "language": "python", "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "## Setting internal parameters of workflows" ] }, { "cell_type": "code", "collapsed": false, "input": [ "print(smooth.list_node_names())\n", "\n", "median = smooth.get_node('median')\n", "median.inputs.op_string = '-k %s -p 60'" ], "language": "python", "metadata": { "slideshow": { "slide_type": "-" } }, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "wf.run()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Summary\n", "\n", "\n", "- This tutorial covers the concepts of Nipype\n", "\n", " 1. Installing and testing the installation \n", " 2. Working with interfaces\n", " 3. Using Nipype caching\n", " 4. Creating Nodes, MapNodes and Workflows\n", " 5. Getting and saving data\n", " 6. Using Iterables\n", " 7. Function nodes\n", " 8. Distributed computation\n", " 9. Connecting to databases\n", " 10. Execution configuration options\n", "\n", "- It will allow you to reuse and debug the various workflows available in Nipype, BIPS and CPAC\n", "- Please contribute new interfaces and workflows!" ] }, { "cell_type": "code", "collapsed": false, "input": [ "import os\n", "basedir = '/Users/satra/Dropbox/WORK/notebooks/'\n", "if os.path.exists(basedir):\n", " os.chdir(basedir)" ], "language": "python", "metadata": { "slideshow": { "slide_type": "skip" } }, "outputs": [] } ], "metadata": {} } ] }nipype-0.11.0/examples/rsfmri_vol_surface_preprocessing.py000066400000000000000000001226021257611314500241320ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ==================================== rsfMRI: ANTS, FS, FSL, SPM, aCompCor ==================================== A preprocessing workflow for Siemens resting state data. This workflow makes use of: - ANTS - FreeSurfer - FSL - SPM - CompCor For example:: python rsfmri_preprocessing.py -d /data/12345-34-1.dcm -f /data/Resting.nii -s subj001 -o output -p PBS --plugin_args "dict(qsub_args='-q many')" or python rsfmri_vol_surface_preprocessing.py -f SUB_1024011/E?/func/rest.nii -t OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz --TR 2 -s SUB_1024011 --subjects_dir fsdata --slice_times 0 17 1 18 2 19 3 20 4 21 5 22 6 23 7 24 8 25 9 26 10 27 11 28 12 29 13 30 14 31 15 32 16 -o . This workflow takes resting timeseries and a Siemens dicom file corresponding to it and preprocesses it to produce timeseries coordinates or grayordinates. This workflow also requires 2mm subcortical atlas and templates that are available from: http://mindboggle.info/data.html specifically the 2mm versions of: - `Joint Fusion Atlas `_ - `MNI template `_ """ import os from nipype.interfaces.base import CommandLine CommandLine.set_default_terminal_output('allatonce') from dicom import read_file from nipype.interfaces import (spm, fsl, Function, ants, freesurfer) from nipype.interfaces.c3 import C3dAffineTool fsl.FSLCommand.set_default_output_type('NIFTI') from nipype import Workflow, Node, MapNode from nipype.interfaces import matlab as mlab mlab.MatlabCommand.set_default_matlab_cmd("matlab -nodisplay") # If SPM is not in your MATLAB path you should add it here # mlab.MatlabCommand.set_default_paths('/software/matlab/spm12') from nipype.algorithms.rapidart import ArtifactDetect from nipype.algorithms.misc import TSNR from nipype.interfaces.utility import Rename, Merge, IdentityInterface from nipype.utils.filemanip import filename_to_list from nipype.interfaces.io import DataSink, FreeSurferSource import numpy as np import scipy as sp import nibabel as nb imports = ['import os', 'import nibabel as nb', 'import numpy as np', 'import scipy as sp', 'from nipype.utils.filemanip import filename_to_list, list_to_filename, split_filename', 'from scipy.special import legendre' ] def get_info(dicom_files): from dcmstack.extract import default_extractor """Given a Siemens dicom file return metadata Returns ------- RepetitionTime Slice Acquisition Times Spacing between slices """ meta = default_extractor(read_file(filename_to_list(dicom_files)[0], stop_before_pixels=True, force=True)) return (meta['RepetitionTime']/1000., meta['CsaImage.MosaicRefAcqTimes'], meta['SpacingBetweenSlices']) def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ import numpy as np import nibabel as nb average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average/float(idx + 1), img.get_affine(), img.get_header()) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename def bandpass_filter(files, lowpass_freq, highpass_freq, fs): """Bandpass filter the input files Parameters ---------- files: list of 4d nifti files lowpass_freq: cutoff frequency for the low pass filter (in Hz) highpass_freq: cutoff frequency for the high pass filter (in Hz) fs: sampling rate (in Hz) """ from nipype.utils.filemanip import split_filename, list_to_filename import numpy as np import nibabel as nb out_files = [] for filename in filename_to_list(files): path, name, ext = split_filename(filename) out_file = os.path.join(os.getcwd(), name + '_bp' + ext) img = nb.load(filename) timepoints = img.shape[-1] F = np.zeros((timepoints)) lowidx = timepoints/2 + 1 if lowpass_freq > 0: lowidx = np.round(lowpass_freq / fs * timepoints) highidx = 0 if highpass_freq > 0: highidx = np.round(highpass_freq / fs * timepoints) F[highidx:lowidx] = 1 F = ((F + F[::-1]) > 0).astype(int) data = img.get_data() if np.all(F == 1): filtered_data = data else: filtered_data = np.real(np.fft.ifftn(np.fft.fftn(data) * F)) img_out = nb.Nifti1Image(filtered_data, img.get_affine(), img.get_header()) img_out.to_filename(out_file) out_files.append(out_file) return list_to_filename(out_files) def motion_regressors(motion_params, order=0, derivatives=1): """Compute motion regressors upto given order and derivative motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic) """ import numpy as np out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) out_params = params for d in range(1, derivatives + 1): cparams = np.vstack((np.repeat(params[0, :][None, :], d, axis=0), params)) out_params = np.hstack((out_params, np.diff(cparams, d, axis=0))) out_params2 = out_params for i in range(2, order + 1): out_params2 = np.hstack((out_params2, np.power(out_params, i))) filename = os.path.join(os.getcwd(), "motion_regressor%02d.txt" % idx) np.savetxt(filename, out_params2, fmt="%.10f") out_files.append(filename) return out_files def build_filter1(motion_params, comp_norm, outliers, detrend_poly=None): """Builds a regressor set comprisong motion parameters, composite norm and outliers The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices detrend_poly: number of polynomials to add to detrend Returns ------- components_file: a text file containing all the regressors """ import numpy as np import nibabel as nb from scipy.special import legendre out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) if detrend_poly: timepoints = out_params.shape[0] X = np.empty((timepoints, 0)) for i in range(detrend_poly): X = np.hstack((X, legendre( i + 1)(np.linspace(-1, 1, timepoints))[:, None])) out_params = np.hstack((out_params, X)) filename = os.path.join(os.getcwd(), "filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files def extract_noise_components(realigned_file, mask_file, num_components=5, extra_regressors=None): """Derive components most reflective of physiological noise Parameters ---------- realigned_file: a 4D Nifti file containing realigned volumes mask_file: a 3D Nifti file containing white matter + ventricular masks num_components: number of components to use for noise decomposition extra_regressors: additional regressors to add Returns ------- components_file: a text file containing the noise components """ from scipy.linalg.decomp_svd import svd import numpy as np import nibabel as nb import os imgseries = nb.load(realigned_file) components = None for filename in filename_to_list(mask_file): mask = nb.load(filename).get_data() if len(np.nonzero(mask > 0)[0]) == 0: continue voxel_timecourses = imgseries.get_data()[mask > 0] voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0 # remove mean and normalize by variance # voxel_timecourses.shape == [nvoxels, time] X = voxel_timecourses.T stdX = np.std(X, axis=0) stdX[stdX == 0] = 1. stdX[np.isnan(stdX)] = 1. stdX[np.isinf(stdX)] = 1. X = (X - np.mean(X, axis=0))/stdX u, _, _ = svd(X, full_matrices=False) if components is None: components = u[:, :num_components] else: components = np.hstack((components, u[:, :num_components])) if extra_regressors: regressors = np.genfromtxt(extra_regressors) components = np.hstack((components, regressors)) components_file = os.path.join(os.getcwd(), 'noise_components.txt') np.savetxt(components_file, components, fmt="%.10f") return components_file def rename(in_files, suffix=None): from nipype.utils.filemanip import (filename_to_list, split_filename, list_to_filename) out_files = [] for idx, filename in enumerate(filename_to_list(in_files)): _, name, ext = split_filename(filename) if suffix is None: out_files.append(name + ('_%03d' % idx) + ext) else: out_files.append(name + suffix + ext) return list_to_filename(out_files) def get_aparc_aseg(files): """Return the aparc+aseg.mgz file""" for name in files: if 'aparc+aseg.mgz' in name: return name raise ValueError('aparc+aseg.mgz not found') def extract_subrois(timeseries_file, label_file, indices): """Extract voxel time courses for each subcortical roi index Parameters ---------- timeseries_file: a 4D Nifti file label_file: a 3D file containing rois in the same space/size of the 4D file indices: a list of indices for ROIs to extract. Returns ------- out_file: a text file containing time courses for each voxel of each roi The first four columns are: freesurfer index, i, j, k positions in the label file """ from nipype.utils.filemanip import split_filename import nibabel as nb import os img = nb.load(timeseries_file) data = img.get_data() roiimg = nb.load(label_file) rois = roiimg.get_data() prefix = split_filename(timeseries_file)[1] out_ts_file = os.path.join(os.getcwd(), '%s_subcortical_ts.txt' % prefix) with open(out_ts_file, 'wt') as fp: for fsindex in indices: ijk = np.nonzero(rois == fsindex) ts = data[ijk] for i0, row in enumerate(ts): fp.write('%d,%d,%d,%d,' % (fsindex, ijk[0][i0], ijk[1][i0], ijk[2][i0]) + ','.join(['%.10f' % val for val in row]) + '\n') return out_ts_file def combine_hemi(left, right): """Combine left and right hemisphere time series into a single text file """ import os import numpy as np lh_data = nb.load(left).get_data() rh_data = nb.load(right).get_data() indices = np.vstack((1000000 + np.arange(0, lh_data.shape[0])[:, None], 2000000 + np.arange(0, rh_data.shape[0])[:, None])) all_data = np.hstack((indices, np.vstack((lh_data.squeeze(), rh_data.squeeze())))) filename = left.split('.')[1] + '_combined.txt' np.savetxt(filename, all_data, fmt=','.join(['%d'] + ['%.10f'] * (all_data.shape[1] - 1))) return os.path.abspath(filename) def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- name : name of workflow (default: 'registration') Inputs:: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target Outputs:: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space """ register = Workflow(name=name) inputnode = Node(interface=IdentityInterface(fields=['source_files', 'mean_image', 'subject_id', 'subjects_dir', 'target_image']), name='inputspec') outputnode = Node(interface=IdentityInterface(fields=['func2anat_transform', 'out_reg_file', 'anat2target_transform', 'transforms', 'transformed_mean', 'segmentation_files', 'anat2target', 'aparc' ]), name='outputspec') # Get the subject's freesurfer source directory fssource = Node(FreeSurferSource(), name='fssource') fssource.run_without_submitting = True register.connect(inputnode, 'subject_id', fssource, 'subject_id') register.connect(inputnode, 'subjects_dir', fssource, 'subjects_dir') convert = Node(freesurfer.MRIConvert(out_type='nii'), name="convert") register.connect(fssource, 'T1', convert, 'in_file') # Coregister the median to the surface bbregister = Node(freesurfer.BBRegister(), name='bbregister') bbregister.inputs.init = 'fsl' bbregister.inputs.contrast_type = 't2' bbregister.inputs.out_fsl_file = True bbregister.inputs.epi_mask = True register.connect(inputnode, 'subject_id', bbregister, 'subject_id') register.connect(inputnode, 'mean_image', bbregister, 'source_file') register.connect(inputnode, 'subjects_dir', bbregister, 'subjects_dir') """ Estimate the tissue classes from the anatomical image. But use spm's segment as FSL appears to be breaking. """ stripper = Node(fsl.BET(), name='stripper') register.connect(convert, 'out_file', stripper, 'in_file') fast = Node(fsl.FAST(), name='fast') register.connect(stripper, 'out_file', fast, 'in_files') """ Binarize the segmentation """ binarize = MapNode(fsl.ImageMaths(op_string='-nan -thr 0.9 -ero -bin'), iterfield=['in_file'], name='binarize') register.connect(fast, 'partial_volume_files', binarize, 'in_file') """ Apply inverse transform to take segmentations to functional space """ applyxfm = MapNode(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), iterfield=['target_file'], name='inverse_transform') register.connect(inputnode, 'subjects_dir', applyxfm, 'subjects_dir') register.connect(bbregister, 'out_reg_file', applyxfm, 'reg_file') register.connect(binarize, 'out_file', applyxfm, 'target_file') register.connect(inputnode, 'mean_image', applyxfm, 'source_file') """ Apply inverse transform to aparc file """ aparcxfm = Node(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), name='aparc_inverse_transform') register.connect(inputnode, 'subjects_dir', aparcxfm, 'subjects_dir') register.connect(bbregister, 'out_reg_file', aparcxfm, 'reg_file') register.connect(fssource, ('aparc_aseg', get_aparc_aseg), aparcxfm, 'target_file') register.connect(inputnode, 'mean_image', aparcxfm, 'source_file') """ Convert the BBRegister transformation to ANTS ITK format """ convert2itk = Node(C3dAffineTool(), name='convert2itk') convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(bbregister, 'out_fsl_file', convert2itk, 'transform_file') register.connect(inputnode, 'mean_image',convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template This is currently set to perform a very quick registration. However, the registration can be made significantly more accurate for cortical structures by increasing the number of iterations All parameters are set using the example from: #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh """ reg = Node(ants.Registration(), name='antsRegister') reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[100, 30, 20]] reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = True reg.inputs.initial_moving_transform_com = True reg.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']] reg.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]] reg.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]] reg.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]] reg.inputs.sampling_percentage = [0.3] * 2 + [[None, None]] reg.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01] reg.inputs.convergence_window_size = [20] * 2 + [5] reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]] reg.inputs.sigma_units = ['vox'] * 3 reg.inputs.shrink_factors = [[3, 2, 1]]*2 + [[4, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True] * 3 reg.inputs.use_histogram_matching = [False] * 2 + [True] reg.inputs.winsorize_lower_quantile = 0.005 reg.inputs.winsorize_upper_quantile = 0.995 reg.inputs.float = True reg.inputs.output_warped_image = 'output_warped_image.nii.gz' reg.inputs.num_threads = 4 reg.plugin_args = {'qsub_args': '-l nodes=1:ppn=4'} register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image', reg,'fixed_image') """ Concatenate the affine and ants transforms into a list """ merge = Node(Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target """ warpmean = Node(ants.ApplyTransforms(), name='warpmean') warpmean.inputs.input_image_type = 3 warpmean.inputs.interpolation = 'Linear' warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' warpmean.inputs.args = '--float' warpmean.inputs.num_threads = 4 register.connect(inputnode,'target_image', warpmean,'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') """ Assign all the output files """ register.connect(reg, 'warped_image', outputnode, 'anat2target') register.connect(warpmean, 'output_image', outputnode, 'transformed_mean') register.connect(applyxfm, 'transformed_file', outputnode, 'segmentation_files') register.connect(aparcxfm, 'transformed_file', outputnode, 'aparc') register.connect(bbregister, 'out_fsl_file', outputnode, 'func2anat_transform') register.connect(bbregister, 'out_reg_file', outputnode, 'out_reg_file') register.connect(reg, 'composite_transform', outputnode, 'anat2target_transform') register.connect(merge, 'out', outputnode, 'transforms') return register """ Creates the main preprocessing workflow """ def create_workflow(files, target_file, subject_id, TR, slice_times, norm_threshold=1, num_components=5, vol_fwhm=None, surf_fwhm=None, lowpass_freq=-1, highpass_freq=-1, subjects_dir=None, sink_directory=os.getcwd(), target_subject=['fsaverage3', 'fsaverage4'], name='resting'): wf = Workflow(name=name) # Rename files in case they are named identically name_unique = MapNode(Rename(format_string='rest_%(run)02d'), iterfield=['in_file', 'run'], name='rename') name_unique.inputs.keep_ext = True name_unique.inputs.run = range(1, len(files) + 1) name_unique.inputs.in_file = files realign = Node(interface=spm.Realign(), name="realign") realign.inputs.jobtype = 'estwrite' num_slices = len(slice_times) slice_timing = Node(interface=spm.SliceTiming(), name="slice_timing") slice_timing.inputs.num_slices = num_slices slice_timing.inputs.time_repetition = TR slice_timing.inputs.time_acquisition = TR - TR/float(num_slices) slice_timing.inputs.slice_order = (np.argsort(slice_times) + 1).tolist() slice_timing.inputs.ref_slice = int(num_slices/2) # Comute TSNR on realigned data regressing polynomials upto order 2 tsnr = MapNode(TSNR(regress_poly=2), iterfield=['in_file'], name='tsnr') wf.connect(slice_timing, 'timecorrected_files', tsnr, 'in_file') # Compute the median image across runs calc_median = Node(Function(input_names=['in_files'], output_names=['median_file'], function=median, imports=imports), name='median') wf.connect(tsnr, 'detrended_file', calc_median, 'in_files') """Segment and Register """ registration = create_reg_workflow(name='registration') wf.connect(calc_median, 'median_file', registration, 'inputspec.mean_image') registration.inputs.inputspec.subject_id = subject_id registration.inputs.inputspec.subjects_dir = subjects_dir registration.inputs.inputspec.target_image = target_file """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = Node(interface=ArtifactDetect(), name="art") art.inputs.use_differences = [True, True] art.inputs.use_norm = True art.inputs.norm_threshold = norm_threshold art.inputs.zintensity_threshold = 9 art.inputs.mask_type = 'spm_global' art.inputs.parameter_source = 'SPM' """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. """ wf.connect([(name_unique, realign, [('out_file', 'in_files')]), (realign, slice_timing, [('realigned_files', 'in_files')]), (slice_timing, art, [('timecorrected_files', 'realigned_files')]), (realign, art, [('realignment_parameters', 'realignment_parameters')]), ]) def selectindex(files, idx): import numpy as np from nipype.utils.filemanip import filename_to_list, list_to_filename return list_to_filename(np.array(filename_to_list(files))[idx].tolist()) mask = Node(fsl.BET(), name='getmask') mask.inputs.mask = True wf.connect(calc_median, 'median_file', mask, 'in_file') # get segmentation in normalized functional space def merge_files(in1, in2): out_files = filename_to_list(in1) out_files.extend(filename_to_list(in2)) return out_files # filter some noise # Compute motion regressors motreg = Node(Function(input_names=['motion_params', 'order', 'derivatives'], output_names=['out_files'], function=motion_regressors, imports=imports), name='getmotionregress') wf.connect(realign, 'realignment_parameters', motreg, 'motion_params') # Create a filter to remove motion and art confounds createfilter1 = Node(Function(input_names=['motion_params', 'comp_norm', 'outliers', 'detrend_poly'], output_names=['out_files'], function=build_filter1, imports=imports), name='makemotionbasedfilter') createfilter1.inputs.detrend_poly = 2 wf.connect(motreg, 'out_files', createfilter1, 'motion_params') wf.connect(art, 'norm_files', createfilter1, 'comp_norm') wf.connect(art, 'outlier_files', createfilter1, 'outliers') filter1 = MapNode(fsl.GLM(out_f_name='F_mcart.nii', out_pf_name='pF_mcart.nii', demean=True), iterfield=['in_file', 'design', 'out_res_name'], name='filtermotion') wf.connect(slice_timing, 'timecorrected_files', filter1, 'in_file') wf.connect(slice_timing, ('timecorrected_files', rename, '_filtermotart'), filter1, 'out_res_name') wf.connect(createfilter1, 'out_files', filter1, 'design') createfilter2 = MapNode(Function(input_names=['realigned_file', 'mask_file', 'num_components', 'extra_regressors'], output_names=['out_files'], function=extract_noise_components, imports=imports), iterfield=['realigned_file', 'extra_regressors'], name='makecompcorrfilter') createfilter2.inputs.num_components = num_components wf.connect(createfilter1, 'out_files', createfilter2, 'extra_regressors') wf.connect(filter1, 'out_res', createfilter2, 'realigned_file') wf.connect(registration, ('outputspec.segmentation_files', selectindex, [0, 2]), createfilter2, 'mask_file') filter2 = MapNode(fsl.GLM(out_f_name='F.nii', out_pf_name='pF.nii', demean=True), iterfield=['in_file', 'design', 'out_res_name'], name='filter_noise_nosmooth') wf.connect(filter1, 'out_res', filter2, 'in_file') wf.connect(filter1, ('out_res', rename, '_cleaned'), filter2, 'out_res_name') wf.connect(createfilter2, 'out_files', filter2, 'design') wf.connect(mask, 'mask_file', filter2, 'mask') bandpass = Node(Function(input_names=['files', 'lowpass_freq', 'highpass_freq', 'fs'], output_names=['out_files'], function=bandpass_filter, imports=imports), name='bandpass_unsmooth') bandpass.inputs.fs = 1./TR bandpass.inputs.highpass_freq = highpass_freq bandpass.inputs.lowpass_freq = lowpass_freq wf.connect(filter2, 'out_res', bandpass, 'files') """Smooth the functional data using :class:`nipype.interfaces.spm.Smooth`. """ smooth = Node(interface=spm.Smooth(), name="smooth") smooth.inputs.fwhm = vol_fwhm wf.connect(bandpass, 'out_files', smooth, 'in_files') collector = Node(Merge(2), name='collect_streams') wf.connect(smooth, 'smoothed_files', collector, 'in1') wf.connect(bandpass, 'out_files', collector, 'in2') """ Transform the remaining images. First to anatomical and then to target """ warpall = MapNode(ants.ApplyTransforms(), iterfield=['input_image'], name='warpall') warpall.inputs.input_image_type = 3 warpall.inputs.interpolation = 'Linear' warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' warpall.inputs.reference_image = target_file warpall.inputs.args = '--float' warpall.inputs.num_threads = 1 # transform to target wf.connect(collector, 'out', warpall, 'input_image') wf.connect(registration, 'outputspec.transforms', warpall, 'transforms') mask_target = Node(fsl.ImageMaths(op_string='-bin'), name='target_mask') wf.connect(registration, 'outputspec.anat2target', mask_target, 'in_file') maskts = MapNode(fsl.ApplyMask(), iterfield=['in_file'], name='ts_masker') wf.connect(warpall, 'output_image', maskts, 'in_file') wf.connect(mask_target, 'out_file', maskts, 'mask_file') # map to surface # extract aparc+aseg ROIs # extract subcortical ROIs # extract target space ROIs # combine subcortical and cortical rois into a single cifti file ####### # Convert aparc to subject functional space # Sample the average time series in aparc ROIs sampleaparc = MapNode(freesurfer.SegStats(default_color_table=True), iterfield=['in_file', 'summary_file', 'avgwf_txt_file'], name='aparc_ts') sampleaparc.inputs.segment_id = ([8] + range(10, 14) + [17, 18, 26, 47] + range(49, 55) + [58] + range(1001, 1036) + range(2001, 2036)) wf.connect(registration, 'outputspec.aparc', sampleaparc, 'segmentation_file') wf.connect(collector, 'out', sampleaparc, 'in_file') def get_names(files, suffix): """Generate appropriate names for output files """ from nipype.utils.filemanip import (split_filename, filename_to_list, list_to_filename) out_names = [] for filename in files: _, name, _ = split_filename(filename) out_names.append(name + suffix) return list_to_filename(out_names) wf.connect(collector, ('out', get_names, '_avgwf.txt'), sampleaparc, 'avgwf_txt_file') wf.connect(collector, ('out', get_names, '_summary.stats'), sampleaparc, 'summary_file') # Sample the time series onto the surface of the target surface. Performs # sampling into left and right hemisphere target = Node(IdentityInterface(fields=['target_subject']), name='target') target.iterables = ('target_subject', filename_to_list(target_subject)) samplerlh = MapNode(freesurfer.SampleToSurface(), iterfield=['source_file'], name='sampler_lh') samplerlh.inputs.sampling_method = "average" samplerlh.inputs.sampling_range = (0.1, 0.9, 0.1) samplerlh.inputs.sampling_units = "frac" samplerlh.inputs.interp_method = "trilinear" samplerlh.inputs.smooth_surf = surf_fwhm #samplerlh.inputs.cortex_mask = True samplerlh.inputs.out_type = 'niigz' samplerlh.inputs.subjects_dir = subjects_dir samplerrh = samplerlh.clone('sampler_rh') samplerlh.inputs.hemi = 'lh' wf.connect(collector, 'out', samplerlh, 'source_file') wf.connect(registration, 'outputspec.out_reg_file', samplerlh, 'reg_file') wf.connect(target, 'target_subject', samplerlh, 'target_subject') samplerrh.set_input('hemi', 'rh') wf.connect(collector, 'out', samplerrh, 'source_file') wf.connect(registration, 'outputspec.out_reg_file', samplerrh, 'reg_file') wf.connect(target, 'target_subject', samplerrh, 'target_subject') # Combine left and right hemisphere to text file combiner = MapNode(Function(input_names=['left', 'right'], output_names=['out_file'], function=combine_hemi, imports=imports), iterfield=['left', 'right'], name="combiner") wf.connect(samplerlh, 'out_file', combiner, 'left') wf.connect(samplerrh, 'out_file', combiner, 'right') # Sample the time series file for each subcortical roi ts2txt = MapNode(Function(input_names=['timeseries_file', 'label_file', 'indices'], output_names=['out_file'], function=extract_subrois, imports=imports), iterfield=['timeseries_file'], name='getsubcortts') ts2txt.inputs.indices = [8] + range(10, 14) + [17, 18, 26, 47] +\ range(49, 55) + [58] ts2txt.inputs.label_file = \ os.path.abspath(('OASIS-TRT-20_jointfusion_DKT31_CMA_labels_in_MNI152_' '2mm_v2.nii.gz')) wf.connect(maskts, 'out_file', ts2txt, 'timeseries_file') ###### substitutions = [('_target_subject_', ''), ('_filtermotart_cleaned_bp_trans_masked', ''), ('_filtermotart_cleaned_bp', '') ] regex_subs = [('_ts_masker.*/sar', '/smooth/'), ('_ts_masker.*/ar', '/unsmooth/'), ('_combiner.*/sar', '/smooth/'), ('_combiner.*/ar', '/unsmooth/'), ('_aparc_ts.*/sar', '/smooth/'), ('_aparc_ts.*/ar', '/unsmooth/'), ('_getsubcortts.*/sar', '/smooth/'), ('_getsubcortts.*/ar', '/unsmooth/'), ('series/sar', 'series/smooth/'), ('series/ar', 'series/unsmooth/'), ('_inverse_transform./', ''), ] # Save the relevant data into an output directory datasink = Node(interface=DataSink(), name="datasink") datasink.inputs.base_directory = sink_directory datasink.inputs.container = subject_id datasink.inputs.substitutions = substitutions datasink.inputs.regexp_substitutions = regex_subs #(r'(/_.*(\d+/))', r'/run\2') wf.connect(realign, 'realignment_parameters', datasink, 'resting.qa.motion') wf.connect(art, 'norm_files', datasink, 'resting.qa.art.@norm') wf.connect(art, 'intensity_files', datasink, 'resting.qa.art.@intensity') wf.connect(art, 'outlier_files', datasink, 'resting.qa.art.@outlier_files') wf.connect(registration, 'outputspec.segmentation_files', datasink, 'resting.mask_files') wf.connect(registration, 'outputspec.anat2target', datasink, 'resting.qa.ants') wf.connect(mask, 'mask_file', datasink, 'resting.mask_files.@brainmask') wf.connect(mask_target, 'out_file', datasink, 'resting.mask_files.target') wf.connect(filter1, 'out_f', datasink, 'resting.qa.compmaps.@mc_F') wf.connect(filter1, 'out_pf', datasink, 'resting.qa.compmaps.@mc_pF') wf.connect(filter2, 'out_f', datasink, 'resting.qa.compmaps') wf.connect(filter2, 'out_pf', datasink, 'resting.qa.compmaps.@p') wf.connect(bandpass, 'out_files', datasink, 'resting.timeseries.@bandpassed') wf.connect(smooth, 'smoothed_files', datasink, 'resting.timeseries.@smoothed') wf.connect(createfilter1, 'out_files', datasink, 'resting.regress.@regressors') wf.connect(createfilter2, 'out_files', datasink, 'resting.regress.@compcorr') wf.connect(maskts, 'out_file', datasink, 'resting.timeseries.target') wf.connect(sampleaparc, 'summary_file', datasink, 'resting.parcellations.aparc') wf.connect(sampleaparc, 'avgwf_txt_file', datasink, 'resting.parcellations.aparc.@avgwf') wf.connect(ts2txt, 'out_file', datasink, 'resting.parcellations.grayo.@subcortical') datasink2 = Node(interface=DataSink(), name="datasink2") datasink2.inputs.base_directory = sink_directory datasink2.inputs.container = subject_id datasink2.inputs.substitutions = substitutions datasink2.inputs.regexp_substitutions = regex_subs #(r'(/_.*(\d+/))', r'/run\2') wf.connect(combiner, 'out_file', datasink2, 'resting.parcellations.grayo.@surface') return wf """ Creates the full workflow including getting information from dicom files """ def create_resting_workflow(args, name=None): TR = args.TR slice_times = args.slice_times if args.dicom_file: TR, slice_times, slice_thickness = get_info(args.dicom_file) slice_times = (np.array(slice_times)/1000.).tolist() if name is None: name = 'resting_' + args.subject_id kwargs = dict(files=[os.path.abspath(filename) for filename in args.files], target_file=os.path.abspath(args.target_file), subject_id=args.subject_id, TR=TR, slice_times=slice_times, vol_fwhm=args.vol_fwhm, surf_fwhm=args.surf_fwhm, norm_threshold=2., subjects_dir=os.path.abspath(args.fsdir), target_subject=args.target_surfs, lowpass_freq=args.lowpass_freq, highpass_freq=args.highpass_freq, sink_directory=os.path.abspath(args.sink), name=name) wf = create_workflow(**kwargs) return wf if __name__ == "__main__": from argparse import ArgumentParser, RawTextHelpFormatter defstr = ' (default %(default)s)' parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) parser.add_argument("-d", "--dicom_file", dest="dicom_file", help="an example dicom file from the resting series") parser.add_argument("-f", "--files", dest="files", nargs="+", help="4d nifti files for resting state", required=True) parser.add_argument("-t", "--target", dest="target_file", help=("Target in MNI space. Best to use the MindBoggle " "template - " "OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz"), required=True) parser.add_argument("-s", "--subject_id", dest="subject_id", help="FreeSurfer subject id", required=True) parser.add_argument("--subjects_dir", dest="fsdir", help="FreeSurfer subject directory", required=True) parser.add_argument("--target_surfaces", dest="target_surfs", nargs="+", default=['fsaverage5'], help="FreeSurfer target surfaces" + defstr) parser.add_argument("--TR", dest="TR", default=None, type=float, help="TR if dicom not provided in seconds") parser.add_argument("--slice_times", dest="slice_times", nargs="+", type=float, help="Slice onset times in seconds") parser.add_argument('--vol_fwhm', default=6., dest='vol_fwhm', type=float, help="Spatial FWHM" + defstr) parser.add_argument('--surf_fwhm', default=15., dest='surf_fwhm', type=float, help="Spatial FWHM" + defstr) parser.add_argument("-l", "--lowpass_freq", dest="lowpass_freq", default=0.1, type=float, help="Low pass frequency (Hz)" + defstr) parser.add_argument("-u", "--highpass_freq", dest="highpass_freq", default=0.01, type=float, help="High pass frequency (Hz)" + defstr) parser.add_argument("-o", "--output_dir", dest="sink", help="Output directory base", required=True) parser.add_argument("-w", "--work_dir", dest="work_dir", help="Output directory base") parser.add_argument("-p", "--plugin", dest="plugin", default='Linear', help="Plugin to use") parser.add_argument("--plugin_args", dest="plugin_args", help="Plugin arguments") args = parser.parse_args() wf = create_resting_workflow(args) if args.work_dir: work_dir = os.path.abspath(args.work_dir) else: work_dir = os.getcwd() wf.base_dir = work_dir if args.plugin_args: wf.run(args.plugin, plugin_args=eval(args.plugin_args)) else: wf.run(args.plugin) nipype-0.11.0/examples/rsfmri_vol_surface_preprocessing_nipy.py000066400000000000000000001247021257611314500251740ustar00rootroot00000000000000#!/usr/bin/env python """ ==================================== rsfMRI: ANTS, FS, FSL, NiPy, aCompCor ==================================== A preprocessing workflow for Siemens resting state data. This workflow makes use of: - ANTS - FreeSurfer - FSL - NiPy - CompCor For example:: python rsfmri_preprocessing.py -d /data/12345-34-1.dcm -f /data/Resting.nii -s subj001 -o output -p PBS --plugin_args "dict(qsub_args='-q many')" or python rsfmri_vol_surface_preprocessing.py -f SUB_1024011/E?/func/rest.nii -t OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz --TR 2 -s SUB_1024011 --subjects_dir fsdata --slice_times 0 17 1 18 2 19 3 20 4 21 5 22 6 23 7 24 8 25 9 26 10 27 11 28 12 29 13 30 14 31 15 32 16 -o . This workflow takes resting timeseries and a Siemens dicom file corresponding to it and preprocesses it to produce timeseries coordinates or grayordinates. For non-Siemens dicoms, provide slice times instead, since the dicom extractor is not guaranteed to work. This workflow also requires 2mm subcortical atlas and templates that are available from: http://mindboggle.info/data.html specifically the 2mm versions of: - `Joint Fusion Atlas `_ - `MNI template `_ """ import os from nipype.interfaces.base import CommandLine CommandLine.set_default_terminal_output('allatonce') from dcmstack.extract import default_extractor from dicom import read_file from nipype.interfaces import (fsl, Function, ants, freesurfer,nipy) from nipype.interfaces.c3 import C3dAffineTool fsl.FSLCommand.set_default_output_type('NIFTI_GZ') from nipype import Workflow, Node, MapNode from nipype.algorithms.rapidart import ArtifactDetect from nipype.algorithms.misc import TSNR from nipype.interfaces.utility import Rename, Merge, IdentityInterface from nipype.utils.filemanip import filename_to_list from nipype.interfaces.io import DataSink, FreeSurferSource import nipype.interfaces.freesurfer as fs import numpy as np import scipy as sp import nibabel as nb imports = ['import os', 'import nibabel as nb', 'import numpy as np', 'import scipy as sp', 'from nipype.utils.filemanip import filename_to_list, list_to_filename, split_filename', 'from scipy.special import legendre' ] def get_info(dicom_files): """Given a Siemens dicom file return metadata Returns ------- RepetitionTime Slice Acquisition Times Spacing between slices """ meta = default_extractor(read_file(filename_to_list(dicom_files)[0], stop_before_pixels=True, force=True)) return (meta['RepetitionTime']/1000., meta['CsaImage.MosaicRefAcqTimes'], meta['SpacingBetweenSlices']) def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average/float(idx + 1), img.get_affine(), img.get_header()) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename def bandpass_filter(files, lowpass_freq, highpass_freq, fs): """Bandpass filter the input files Parameters ---------- files: list of 4d nifti files lowpass_freq: cutoff frequency for the low pass filter (in Hz) highpass_freq: cutoff frequency for the high pass filter (in Hz) fs: sampling rate (in Hz) """ out_files = [] for filename in filename_to_list(files): path, name, ext = split_filename(filename) out_file = os.path.join(os.getcwd(), name + '_bp' + ext) img = nb.load(filename) timepoints = img.shape[-1] F = np.zeros((timepoints)) lowidx = timepoints/2 + 1 if lowpass_freq > 0: lowidx = np.round(float(lowpass_freq) / fs * timepoints) highidx = 0 if highpass_freq > 0: highidx = np.round(float(highpass_freq) / fs * timepoints) F[highidx:lowidx] = 1 F = ((F + F[::-1]) > 0).astype(int) data = img.get_data() if np.all(F == 1): filtered_data = data else: filtered_data = np.real(np.fft.ifftn(np.fft.fftn(data) * F)) img_out = nb.Nifti1Image(filtered_data, img.get_affine(), img.get_header()) img_out.to_filename(out_file) out_files.append(out_file) return list_to_filename(out_files) def motion_regressors(motion_params, order=0, derivatives=1): """Compute motion regressors upto given order and derivative motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic) """ out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) out_params = params for d in range(1, derivatives + 1): cparams = np.vstack((np.repeat(params[0, :][None, :], d, axis=0), params)) out_params = np.hstack((out_params, np.diff(cparams, d, axis=0))) out_params2 = out_params for i in range(2, order + 1): out_params2 = np.hstack((out_params2, np.power(out_params, i))) filename = os.path.join(os.getcwd(), "motion_regressor%02d.txt" % idx) np.savetxt(filename, out_params2, fmt="%.10f") out_files.append(filename) return out_files def build_filter1(motion_params, comp_norm, outliers, detrend_poly=None): """Builds a regressor set comprisong motion parameters, composite norm and outliers The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices detrend_poly: number of polynomials to add to detrend Returns ------- components_file: a text file containing all the regressors """ out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) if detrend_poly: timepoints = out_params.shape[0] X = np.empty((timepoints, 0)) for i in range(detrend_poly): X = np.hstack((X, legendre( i + 1)(np.linspace(-1, 1, timepoints))[:, None])) out_params = np.hstack((out_params, X)) filename = os.path.join(os.getcwd(), "filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files def extract_noise_components(realigned_file, mask_file, num_components=5, extra_regressors=None): """Derive components most reflective of physiological noise Parameters ---------- realigned_file: a 4D Nifti file containing realigned volumes mask_file: a 3D Nifti file containing white matter + ventricular masks num_components: number of components to use for noise decomposition extra_regressors: additional regressors to add Returns ------- components_file: a text file containing the noise components """ imgseries = nb.load(realigned_file) components = None for filename in filename_to_list(mask_file): mask = nb.load(filename).get_data() if len(np.nonzero(mask > 0)[0]) == 0: continue voxel_timecourses = imgseries.get_data()[mask > 0] voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0 # remove mean and normalize by variance # voxel_timecourses.shape == [nvoxels, time] X = voxel_timecourses.T stdX = np.std(X, axis=0) stdX[stdX == 0] = 1. stdX[np.isnan(stdX)] = 1. stdX[np.isinf(stdX)] = 1. X = (X - np.mean(X, axis=0))/stdX u, _, _ = sp.linalg.svd(X, full_matrices=False) if components is None: components = u[:, :num_components] else: components = np.hstack((components, u[:, :num_components])) if extra_regressors: regressors = np.genfromtxt(extra_regressors) components = np.hstack((components, regressors)) components_file = os.path.join(os.getcwd(), 'noise_components.txt') np.savetxt(components_file, components, fmt="%.10f") return components_file def rename(in_files, suffix=None): from nipype.utils.filemanip import (filename_to_list, split_filename, list_to_filename) out_files = [] for idx, filename in enumerate(filename_to_list(in_files)): _, name, ext = split_filename(filename) if suffix is None: out_files.append(name + ('_%03d' % idx) + ext) else: out_files.append(name + suffix + ext) return list_to_filename(out_files) def get_aparc_aseg(files): """Return the aparc+aseg.mgz file""" for name in files: if 'aparc+aseg.mgz' in name: return name raise ValueError('aparc+aseg.mgz not found') def extract_subrois(timeseries_file, label_file, indices): """Extract voxel time courses for each subcortical roi index Parameters ---------- timeseries_file: a 4D Nifti file label_file: a 3D file containing rois in the same space/size of the 4D file indices: a list of indices for ROIs to extract. Returns ------- out_file: a text file containing time courses for each voxel of each roi The first four columns are: freesurfer index, i, j, k positions in the label file """ img = nb.load(timeseries_file) data = img.get_data() roiimg = nb.load(label_file) rois = roiimg.get_data() prefix = split_filename(timeseries_file)[1] out_ts_file = os.path.join(os.getcwd(), '%s_subcortical_ts.txt' % prefix) with open(out_ts_file, 'wt') as fp: for fsindex in indices: ijk = np.nonzero(rois == fsindex) ts = data[ijk] for i0, row in enumerate(ts): fp.write('%d,%d,%d,%d,' % (fsindex, ijk[0][i0], ijk[1][i0], ijk[2][i0]) + ','.join(['%.10f' % val for val in row]) + '\n') return out_ts_file def combine_hemi(left, right): """Combine left and right hemisphere time series into a single text file """ lh_data = nb.load(left).get_data() rh_data = nb.load(right).get_data() indices = np.vstack((1000000 + np.arange(0, lh_data.shape[0])[:, None], 2000000 + np.arange(0, rh_data.shape[0])[:, None])) all_data = np.hstack((indices, np.vstack((lh_data.squeeze(), rh_data.squeeze())))) filename = left.split('.')[1] + '_combined.txt' np.savetxt(filename, all_data, fmt=','.join(['%d'] + ['%.10f'] * (all_data.shape[1] - 1))) return os.path.abspath(filename) def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- name : name of workflow (default: 'registration') Inputs:: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target Outputs:: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space """ register = Workflow(name=name) inputnode = Node(interface=IdentityInterface(fields=['source_files', 'mean_image', 'subject_id', 'subjects_dir', 'target_image']), name='inputspec') outputnode = Node(interface=IdentityInterface(fields=['func2anat_transform', 'out_reg_file', 'anat2target_transform', 'transforms', 'transformed_mean', 'segmentation_files', 'anat2target', 'aparc', 'min_cost_file' ]), name='outputspec') # Get the subject's freesurfer source directory fssource = Node(FreeSurferSource(), name='fssource') fssource.run_without_submitting = True register.connect(inputnode, 'subject_id', fssource, 'subject_id') register.connect(inputnode, 'subjects_dir', fssource, 'subjects_dir') convert = Node(freesurfer.MRIConvert(out_type='nii'), name="convert") register.connect(fssource, 'T1', convert, 'in_file') # Coregister the median to the surface bbregister = Node(freesurfer.BBRegister(), name='bbregister') bbregister.inputs.init = 'fsl' bbregister.inputs.contrast_type = 't2' bbregister.inputs.out_fsl_file = True bbregister.inputs.epi_mask = True register.connect(inputnode, 'subject_id', bbregister, 'subject_id') register.connect(inputnode, 'mean_image', bbregister, 'source_file') register.connect(inputnode, 'subjects_dir', bbregister, 'subjects_dir') """ Estimate the tissue classes from the anatomical image. But use aparc+aseg's brain mask """ binarize = Node(fs.Binarize(min=0.5, out_type="nii.gz", dilate=1), name="binarize_aparc") register.connect(fssource, ("aparc_aseg", get_aparc_aseg), binarize, "in_file") stripper = Node(fsl.ApplyMask(), name ='stripper') register.connect(binarize, "binary_file", stripper, "mask_file") register.connect(convert, 'out_file', stripper, 'in_file') fast = Node(fsl.FAST(), name='fast') register.connect(stripper, 'out_file', fast, 'in_files') """ Binarize the segmentation """ binarize = MapNode(fsl.ImageMaths(op_string='-nan -thr 0.9 -ero -bin'), iterfield=['in_file'], name='binarize') register.connect(fast, 'partial_volume_files', binarize, 'in_file') """ Apply inverse transform to take segmentations to functional space """ applyxfm = MapNode(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), iterfield=['target_file'], name='inverse_transform') register.connect(inputnode, 'subjects_dir', applyxfm, 'subjects_dir') register.connect(bbregister, 'out_reg_file', applyxfm, 'reg_file') register.connect(binarize, 'out_file', applyxfm, 'target_file') register.connect(inputnode, 'mean_image', applyxfm, 'source_file') """ Apply inverse transform to aparc file """ aparcxfm = Node(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), name='aparc_inverse_transform') register.connect(inputnode, 'subjects_dir', aparcxfm, 'subjects_dir') register.connect(bbregister, 'out_reg_file', aparcxfm, 'reg_file') register.connect(fssource, ('aparc_aseg', get_aparc_aseg), aparcxfm, 'target_file') register.connect(inputnode, 'mean_image', aparcxfm, 'source_file') """ Convert the BBRegister transformation to ANTS ITK format """ convert2itk = Node(C3dAffineTool(), name='convert2itk') convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(bbregister, 'out_fsl_file', convert2itk, 'transform_file') register.connect(inputnode, 'mean_image',convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template This is currently set to perform a very quick registration. However, the registration can be made significantly more accurate for cortical structures by increasing the number of iterations All parameters are set using the example from: #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh """ reg = Node(ants.Registration(), name='antsRegister') reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = [[10000, 11110, 11110]] * 2 + [[100, 30, 20]] reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = True reg.inputs.initial_moving_transform_com = True reg.inputs.metric = ['Mattes'] * 2 + [['Mattes', 'CC']] reg.inputs.metric_weight = [1] * 2 + [[0.5, 0.5]] reg.inputs.radius_or_number_of_bins = [32] * 2 + [[32, 4]] reg.inputs.sampling_strategy = ['Regular'] * 2 + [[None, None]] reg.inputs.sampling_percentage = [0.3] * 2 + [[None, None]] reg.inputs.convergence_threshold = [1.e-8] * 2 + [-0.01] reg.inputs.convergence_window_size = [20] * 2 + [5] reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 2 + [[1, 0.5, 0]] reg.inputs.sigma_units = ['vox'] * 3 reg.inputs.shrink_factors = [[3, 2, 1]]*2 + [[4, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True] * 3 reg.inputs.use_histogram_matching = [False] * 2 + [True] reg.inputs.winsorize_lower_quantile = 0.005 reg.inputs.winsorize_upper_quantile = 0.995 reg.inputs.float = True reg.inputs.output_warped_image = 'output_warped_image.nii.gz' reg.inputs.num_threads = 4 reg.plugin_args = {'sbatch_args': '-c%d' % 4} register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image', reg,'fixed_image') """ Concatenate the affine and ants transforms into a list """ merge = Node(Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target """ warpmean = Node(ants.ApplyTransforms(), name='warpmean') warpmean.inputs.input_image_type = 3 warpmean.inputs.interpolation = 'Linear' warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' warpmean.inputs.args = '--float' warpmean.inputs.num_threads = 4 warpmean.plugin_args = {'sbatch_args': '-c%d' % 4} register.connect(inputnode,'target_image', warpmean,'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') """ Assign all the output files """ register.connect(reg, 'warped_image', outputnode, 'anat2target') register.connect(warpmean, 'output_image', outputnode, 'transformed_mean') register.connect(applyxfm, 'transformed_file', outputnode, 'segmentation_files') register.connect(aparcxfm, 'transformed_file', outputnode, 'aparc') register.connect(bbregister, 'out_fsl_file', outputnode, 'func2anat_transform') register.connect(bbregister, 'out_reg_file', outputnode, 'out_reg_file') register.connect(reg, 'composite_transform', outputnode, 'anat2target_transform') register.connect(merge, 'out', outputnode, 'transforms') register.connect(bbregister, 'min_cost_file', outputnode, 'min_cost_file') return register """ Creates the main preprocessing workflow """ def create_workflow(files, target_file, subject_id, TR, slice_times, norm_threshold=1, num_components=5, vol_fwhm=None, surf_fwhm=None, lowpass_freq=-1, highpass_freq=-1, subjects_dir=None, sink_directory=os.getcwd(), target_subject=['fsaverage3', 'fsaverage4'], name='resting'): wf = Workflow(name=name) # Rename files in case they are named identically name_unique = MapNode(Rename(format_string='rest_%(run)02d'), iterfield=['in_file', 'run'], name='rename') name_unique.inputs.keep_ext = True name_unique.inputs.run = range(1, len(files) + 1) name_unique.inputs.in_file = files realign = Node(nipy.SpaceTimeRealigner(), name="spacetime_realign") realign.inputs.slice_times = slice_times realign.inputs.tr = TR realign.inputs.slice_info = 2 realign.plugin_args = {'sbatch_args': '-c%d' % 4} # Comute TSNR on realigned data regressing polynomials upto order 2 tsnr = MapNode(TSNR(regress_poly=2), iterfield=['in_file'], name='tsnr') wf.connect(realign,"out_file", tsnr, "in_file") # Compute the median image across runs calc_median = Node(Function(input_names=['in_files'], output_names=['median_file'], function=median, imports=imports), name='median') wf.connect(tsnr, 'detrended_file', calc_median, 'in_files') """Segment and Register """ registration = create_reg_workflow(name='registration') wf.connect(calc_median, 'median_file', registration, 'inputspec.mean_image') registration.inputs.inputspec.subject_id = subject_id registration.inputs.inputspec.subjects_dir = subjects_dir registration.inputs.inputspec.target_image = target_file """Quantify TSNR in each freesurfer ROI """ get_roi_tsnr = MapNode(fs.SegStats(default_color_table=True), iterfield=['in_file'], name='get_aparc_tsnr') get_roi_tsnr.inputs.avgwf_txt_file = True wf.connect(tsnr, 'tsnr_file', get_roi_tsnr, 'in_file') wf.connect(registration, 'outputspec.aparc', get_roi_tsnr, 'segmentation_file') """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. """ art = Node(interface=ArtifactDetect(), name="art") art.inputs.use_differences = [True, True] art.inputs.use_norm = True art.inputs.norm_threshold = norm_threshold art.inputs.zintensity_threshold = 9 art.inputs.mask_type = 'spm_global' art.inputs.parameter_source = 'NiPy' """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. """ wf.connect([(name_unique, realign, [('out_file', 'in_file')]), (realign, art, [('out_file', 'realigned_files')]), (realign, art, [('par_file', 'realignment_parameters')]), ]) def selectindex(files, idx): import numpy as np from nipype.utils.filemanip import filename_to_list, list_to_filename return list_to_filename(np.array(filename_to_list(files))[idx].tolist()) mask = Node(fsl.BET(), name='getmask') mask.inputs.mask = True wf.connect(calc_median, 'median_file', mask, 'in_file') # get segmentation in normalized functional space def merge_files(in1, in2): out_files = filename_to_list(in1) out_files.extend(filename_to_list(in2)) return out_files # filter some noise # Compute motion regressors motreg = Node(Function(input_names=['motion_params', 'order', 'derivatives'], output_names=['out_files'], function=motion_regressors, imports=imports), name='getmotionregress') wf.connect(realign, 'par_file', motreg, 'motion_params') # Create a filter to remove motion and art confounds createfilter1 = Node(Function(input_names=['motion_params', 'comp_norm', 'outliers', 'detrend_poly'], output_names=['out_files'], function=build_filter1, imports=imports), name='makemotionbasedfilter') createfilter1.inputs.detrend_poly = 2 wf.connect(motreg, 'out_files', createfilter1, 'motion_params') wf.connect(art, 'norm_files', createfilter1, 'comp_norm') wf.connect(art, 'outlier_files', createfilter1, 'outliers') filter1 = MapNode(fsl.GLM(out_f_name='F_mcart.nii.gz', out_pf_name='pF_mcart.nii.gz', demean=True), iterfield=['in_file', 'design', 'out_res_name'], name='filtermotion') wf.connect(realign, 'out_file', filter1, 'in_file') wf.connect(realign, ('out_file', rename, '_filtermotart'), filter1, 'out_res_name') wf.connect(createfilter1, 'out_files', filter1, 'design') createfilter2 = MapNode(Function(input_names=['realigned_file', 'mask_file', 'num_components', 'extra_regressors'], output_names=['out_files'], function=extract_noise_components, imports=imports), iterfield=['realigned_file', 'extra_regressors'], name='makecompcorrfilter') createfilter2.inputs.num_components = num_components wf.connect(createfilter1, 'out_files', createfilter2, 'extra_regressors') wf.connect(filter1, 'out_res', createfilter2, 'realigned_file') wf.connect(registration, ('outputspec.segmentation_files', selectindex, [0, 2]), createfilter2, 'mask_file') filter2 = MapNode(fsl.GLM(out_f_name='F.nii.gz', out_pf_name='pF.nii.gz', demean=True), iterfield=['in_file', 'design', 'out_res_name'], name='filter_noise_nosmooth') wf.connect(filter1, 'out_res', filter2, 'in_file') wf.connect(filter1, ('out_res', rename, '_cleaned'), filter2, 'out_res_name') wf.connect(createfilter2, 'out_files', filter2, 'design') wf.connect(mask, 'mask_file', filter2, 'mask') bandpass = Node(Function(input_names=['files', 'lowpass_freq', 'highpass_freq', 'fs'], output_names=['out_files'], function=bandpass_filter, imports=imports), name='bandpass_unsmooth') bandpass.inputs.fs = 1./TR bandpass.inputs.highpass_freq = highpass_freq bandpass.inputs.lowpass_freq = lowpass_freq wf.connect(filter2, 'out_res', bandpass, 'files') """Smooth the functional data using :class:`nipype.interfaces.fsl.IsotropicSmooth`. """ smooth = MapNode(interface=fsl.IsotropicSmooth(), name="smooth", iterfield=["in_file"]) smooth.inputs.fwhm = vol_fwhm wf.connect(bandpass, 'out_files', smooth, 'in_file') collector = Node(Merge(2), name='collect_streams') wf.connect(smooth, 'out_file', collector, 'in1') wf.connect(bandpass, 'out_files', collector, 'in2') """ Transform the remaining images. First to anatomical and then to target """ warpall = MapNode(ants.ApplyTransforms(), iterfield=['input_image'], name='warpall') warpall.inputs.input_image_type = 3 warpall.inputs.interpolation = 'Linear' warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' warpall.inputs.reference_image = target_file warpall.inputs.args = '--float' warpall.inputs.num_threads = 2 warpall.plugin_args = {'sbatch_args': '-c%d' % 2} # transform to target wf.connect(collector, 'out', warpall, 'input_image') wf.connect(registration, 'outputspec.transforms', warpall, 'transforms') mask_target = Node(fsl.ImageMaths(op_string='-bin'), name='target_mask') wf.connect(registration, 'outputspec.anat2target', mask_target, 'in_file') maskts = MapNode(fsl.ApplyMask(), iterfield=['in_file'], name='ts_masker') wf.connect(warpall, 'output_image', maskts, 'in_file') wf.connect(mask_target, 'out_file', maskts, 'mask_file') # map to surface # extract aparc+aseg ROIs # extract subcortical ROIs # extract target space ROIs # combine subcortical and cortical rois into a single cifti file ####### # Convert aparc to subject functional space # Sample the average time series in aparc ROIs sampleaparc = MapNode(freesurfer.SegStats(default_color_table=True), iterfield=['in_file', 'summary_file', 'avgwf_txt_file'], name='aparc_ts') sampleaparc.inputs.segment_id = ([8] + range(10, 14) + [17, 18, 26, 47] + range(49, 55) + [58] + range(1001, 1036) + range(2001, 2036)) wf.connect(registration, 'outputspec.aparc', sampleaparc, 'segmentation_file') wf.connect(collector, 'out', sampleaparc, 'in_file') def get_names(files, suffix): """Generate appropriate names for output files """ from nipype.utils.filemanip import (split_filename, filename_to_list, list_to_filename) import os out_names = [] for filename in files: path, name, _ = split_filename(filename) out_names.append(os.path.join(path,name + suffix)) return list_to_filename(out_names) wf.connect(collector, ('out', get_names, '_avgwf.txt'), sampleaparc, 'avgwf_txt_file') wf.connect(collector, ('out', get_names, '_summary.stats'), sampleaparc, 'summary_file') # Sample the time series onto the surface of the target surface. Performs # sampling into left and right hemisphere target = Node(IdentityInterface(fields=['target_subject']), name='target') target.iterables = ('target_subject', filename_to_list(target_subject)) samplerlh = MapNode(freesurfer.SampleToSurface(), iterfield=['source_file'], name='sampler_lh') samplerlh.inputs.sampling_method = "average" samplerlh.inputs.sampling_range = (0.1, 0.9, 0.1) samplerlh.inputs.sampling_units = "frac" samplerlh.inputs.interp_method = "trilinear" samplerlh.inputs.smooth_surf = surf_fwhm #samplerlh.inputs.cortex_mask = True samplerlh.inputs.out_type = 'niigz' samplerlh.inputs.subjects_dir = subjects_dir samplerrh = samplerlh.clone('sampler_rh') samplerlh.inputs.hemi = 'lh' wf.connect(collector, 'out', samplerlh, 'source_file') wf.connect(registration, 'outputspec.out_reg_file', samplerlh, 'reg_file') wf.connect(target, 'target_subject', samplerlh, 'target_subject') samplerrh.set_input('hemi', 'rh') wf.connect(collector, 'out', samplerrh, 'source_file') wf.connect(registration, 'outputspec.out_reg_file', samplerrh, 'reg_file') wf.connect(target, 'target_subject', samplerrh, 'target_subject') # Combine left and right hemisphere to text file combiner = MapNode(Function(input_names=['left', 'right'], output_names=['out_file'], function=combine_hemi, imports=imports), iterfield=['left', 'right'], name="combiner") wf.connect(samplerlh, 'out_file', combiner, 'left') wf.connect(samplerrh, 'out_file', combiner, 'right') # Sample the time series file for each subcortical roi ts2txt = MapNode(Function(input_names=['timeseries_file', 'label_file', 'indices'], output_names=['out_file'], function=extract_subrois, imports=imports), iterfield=['timeseries_file'], name='getsubcortts') ts2txt.inputs.indices = [8] + range(10, 14) + [17, 18, 26, 47] +\ range(49, 55) + [58] ts2txt.inputs.label_file = \ os.path.abspath(('OASIS-TRT-20_jointfusion_DKT31_CMA_labels_in_MNI152_' '2mm_v2.nii.gz')) wf.connect(maskts, 'out_file', ts2txt, 'timeseries_file') ###### substitutions = [('_target_subject_', ''), ('_filtermotart_cleaned_bp_trans_masked', ''), ('_filtermotart_cleaned_bp', ''), ] substitutions += [("_smooth%d" % i,"") for i in range(11)[::-1]] substitutions += [("_ts_masker%d" % i,"") for i in range(11)[::-1]] substitutions += [("_getsubcortts%d" % i,"") for i in range(11)[::-1]] substitutions += [("_combiner%d" % i,"") for i in range(11)[::-1]] substitutions += [("_filtermotion%d" % i,"") for i in range(11)[::-1]] substitutions += [("_filter_noise_nosmooth%d" % i,"") for i in range(11)[::-1]] substitutions += [("_makecompcorfilter%d" % i,"") for i in range(11)[::-1]] substitutions += [("_get_aparc_tsnr%d/" % i, "run%d_" % (i + 1)) for i in range(11)[::-1]] substitutions += [("T1_out_brain_pve_0_maths_warped", "compcor_csf"), ("T1_out_brain_pve_1_maths_warped", "compcor_gm"), ("T1_out_brain_pve_2_maths_warped", "compcor_wm"), ("output_warped_image_maths", "target_brain_mask"), ("median_brain_mask", "native_brain_mask"), ("corr_", "")] regex_subs = [('_combiner.*/sar', '/smooth/'), ('_combiner.*/ar', '/unsmooth/'), ('_aparc_ts.*/sar', '/smooth/'), ('_aparc_ts.*/ar', '/unsmooth/'), ('_getsubcortts.*/sar', '/smooth/'), ('_getsubcortts.*/ar', '/unsmooth/'), ('series/sar', 'series/smooth/'), ('series/ar', 'series/unsmooth/'), ('_inverse_transform./', ''), ] # Save the relevant data into an output directory datasink = Node(interface=DataSink(), name="datasink") datasink.inputs.base_directory = sink_directory datasink.inputs.container = subject_id datasink.inputs.substitutions = substitutions datasink.inputs.regexp_substitutions = regex_subs #(r'(/_.*(\d+/))', r'/run\2') wf.connect(realign, 'par_file', datasink, 'resting.qa.motion') wf.connect(art, 'norm_files', datasink, 'resting.qa.art.@norm') wf.connect(art, 'intensity_files', datasink, 'resting.qa.art.@intensity') wf.connect(art, 'outlier_files', datasink, 'resting.qa.art.@outlier_files') wf.connect(registration, 'outputspec.segmentation_files', datasink, 'resting.mask_files') wf.connect(registration, 'outputspec.anat2target', datasink, 'resting.qa.ants') wf.connect(mask, 'mask_file', datasink, 'resting.mask_files.@brainmask') wf.connect(mask_target, 'out_file', datasink, 'resting.mask_files.target') wf.connect(filter1, 'out_f', datasink, 'resting.qa.compmaps.@mc_F') wf.connect(filter1, 'out_pf', datasink, 'resting.qa.compmaps.@mc_pF') wf.connect(filter2, 'out_f', datasink, 'resting.qa.compmaps') wf.connect(filter2, 'out_pf', datasink, 'resting.qa.compmaps.@p') wf.connect(registration, 'outputspec.min_cost_file', datasink, 'resting.qa.mincost') wf.connect(tsnr, 'tsnr_file', datasink, 'resting.qa.tsnr.@map') wf.connect([(get_roi_tsnr, datasink, [('avgwf_txt_file', 'resting.qa.tsnr'), ('summary_file', 'resting.qa.tsnr.@summary')])]) wf.connect(bandpass, 'out_files', datasink, 'resting.timeseries.@bandpassed') wf.connect(smooth, 'out_file', datasink, 'resting.timeseries.@smoothed') wf.connect(createfilter1, 'out_files', datasink, 'resting.regress.@regressors') wf.connect(createfilter2, 'out_files', datasink, 'resting.regress.@compcorr') wf.connect(maskts, 'out_file', datasink, 'resting.timeseries.target') wf.connect(sampleaparc, 'summary_file', datasink, 'resting.parcellations.aparc') wf.connect(sampleaparc, 'avgwf_txt_file', datasink, 'resting.parcellations.aparc.@avgwf') wf.connect(ts2txt, 'out_file', datasink, 'resting.parcellations.grayo.@subcortical') datasink2 = Node(interface=DataSink(), name="datasink2") datasink2.inputs.base_directory = sink_directory datasink2.inputs.container = subject_id datasink2.inputs.substitutions = substitutions datasink2.inputs.regexp_substitutions = regex_subs #(r'(/_.*(\d+/))', r'/run\2') wf.connect(combiner, 'out_file', datasink2, 'resting.parcellations.grayo.@surface') return wf """ Creates the full workflow including getting information from dicom files """ def create_resting_workflow(args, name=None): TR = args.TR slice_times = args.slice_times if args.dicom_file: TR, slice_times, slice_thickness = get_info(args.dicom_file) slice_times = (np.array(slice_times)/1000.).tolist() if name is None: name = 'resting_' + args.subject_id kwargs = dict(files=[os.path.abspath(filename) for filename in args.files], target_file=os.path.abspath(args.target_file), subject_id=args.subject_id, TR=TR, slice_times=slice_times, vol_fwhm=args.vol_fwhm, surf_fwhm=args.surf_fwhm, norm_threshold=2., subjects_dir=os.path.abspath(args.fsdir), target_subject=args.target_surfs, lowpass_freq=args.lowpass_freq, highpass_freq=args.highpass_freq, sink_directory=os.path.abspath(args.sink), name=name) wf = create_workflow(**kwargs) return wf if __name__ == "__main__": from argparse import ArgumentParser, RawTextHelpFormatter defstr = ' (default %(default)s)' parser = ArgumentParser(description=__doc__, formatter_class=RawTextHelpFormatter) parser.add_argument("-d", "--dicom_file", dest="dicom_file", help="a SIEMENS example dicom file from the resting series") parser.add_argument("-f", "--files", dest="files", nargs="+", help="4d nifti files for resting state", required=True) parser.add_argument("-t", "--target", dest="target_file", help=("Target in MNI space. Best to use the MindBoggle " "template - " "OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz"), required=True) parser.add_argument("-s", "--subject_id", dest="subject_id", help="FreeSurfer subject id", required=True) parser.add_argument("--subjects_dir", dest="fsdir", help="FreeSurfer subject directory", required=True) parser.add_argument("--target_surfaces", dest="target_surfs", nargs="+", default=['fsaverage5'], help="FreeSurfer target surfaces" + defstr) parser.add_argument("--TR", dest="TR", default=None, type=float, help="TR if dicom not provided in seconds") parser.add_argument("--slice_times", dest="slice_times", nargs="+", type=float, help="Slice onset times in seconds") parser.add_argument('--vol_fwhm', default=6., dest='vol_fwhm', type=float, help="Spatial FWHM" + defstr) parser.add_argument('--surf_fwhm', default=15., dest='surf_fwhm', type=float, help="Spatial FWHM" + defstr) parser.add_argument("-l", "--lowpass_freq", dest="lowpass_freq", default=0.1, type=float, help="Low pass frequency (Hz)" + defstr) parser.add_argument("-u", "--highpass_freq", dest="highpass_freq", default=0.01, type=float, help="High pass frequency (Hz)" + defstr) parser.add_argument("-o", "--output_dir", dest="sink", help="Output directory base", required=True) parser.add_argument("-w", "--work_dir", dest="work_dir", help="Output directory base") parser.add_argument("-p", "--plugin", dest="plugin", default='Linear', help="Plugin to use") parser.add_argument("--plugin_args", dest="plugin_args", help="Plugin arguments") args = parser.parse_args() wf = create_resting_workflow(args) if args.work_dir: work_dir = os.path.abspath(args.work_dir) else: work_dir = os.getcwd() wf.base_dir = work_dir if args.plugin_args: wf.run(args.plugin, plugin_args=eval(args.plugin_args)) else: wf.run(args.plugin) nipype-0.11.0/examples/smri_ants_build_template.py000066400000000000000000000110671257611314500223500ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ =============================================== sMRI: Using new ANTS for creating a T1 template =============================================== In this tutorial we will use ANTS (old version aka "ANTS") based workflow to create a template out of multiple T1 volumes. 1. Tell python where to find the appropriate functions. """ import os import nipype.interfaces.utility as util import nipype.interfaces.ants as ants import nipype.interfaces.io as io import nipype.pipeline.engine as pe # pypeline engine from nipype.workflows.smri.ants import ANTSTemplateBuildSingleIterationWF """ 2. Download T1 volumes into home directory """ import urllib2 homeDir=os.getenv("HOME") requestedPath=os.path.join(homeDir,'nipypeTestPath') mydatadir=os.path.realpath(requestedPath) if not os.path.exists(mydatadir): os.makedirs(mydatadir) print mydatadir MyFileURLs=[ ('http://slicer.kitware.com/midas3/download?bitstream=13121','01_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13122','02_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13124','03_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13128','01_T1_inv_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13123','02_T1_inv_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13125','03_T1_inv_half.nii.gz'), ] for tt in MyFileURLs: myURL=tt[0] localFilename=os.path.join(mydatadir,tt[1]) if not os.path.exists(localFilename): remotefile = urllib2.urlopen(myURL) localFile = open(localFilename, 'wb') localFile.write(remotefile.read()) localFile.close() print("Downloaded file: {0}".format(localFilename)) else: print("File previously downloaded {0}".format(localFilename)) input_images=[ os.path.join(mydatadir,'01_T1_half.nii.gz'), os.path.join(mydatadir,'02_T1_half.nii.gz'), os.path.join(mydatadir,'03_T1_half.nii.gz') ] input_passive_images=[ {'INV_T1':os.path.join(mydatadir,'01_T1_inv_half.nii.gz')}, {'INV_T1':os.path.join(mydatadir,'02_T1_inv_half.nii.gz')}, {'INV_T1':os.path.join(mydatadir,'03_T1_inv_half.nii.gz')} ] """ 3. Define the workflow and its working directory """ tbuilder=pe.Workflow(name="ANTSTemplateBuilder") tbuilder.base_dir=requestedPath """ 4. Define data sources. In real life these would be replace by DataGrabbers """ datasource = pe.Node(interface=util.IdentityInterface(fields= ['imageList', 'passiveImagesDictionariesList']), run_without_submitting=True, name='InputImages' ) datasource.inputs.imageList=input_images datasource.inputs.passiveImagesDictionariesList=input_passive_images datasource.inputs.sort_filelist = True """ 5. Template is initialized by a simple average """ initAvg = pe.Node(interface=ants.AverageImages(), name ='initAvg') initAvg.inputs.dimension = 3 initAvg.inputs.normalize = True tbuilder.connect(datasource, "imageList", initAvg, "images") """ 6. Define the first iteration of template building """ buildTemplateIteration1=ANTSTemplateBuildSingleIterationWF('iteration01') tbuilder.connect(initAvg, 'output_average_image', buildTemplateIteration1, 'inputspec.fixed_image') tbuilder.connect(datasource, 'imageList', buildTemplateIteration1, 'inputspec.images') tbuilder.connect(datasource, 'passiveImagesDictionariesList', buildTemplateIteration1, 'inputspec.ListOfPassiveImagesDictionaries') """ 7. Define the second iteration of template building """ buildTemplateIteration2 = ANTSTemplateBuildSingleIterationWF('iteration02') tbuilder.connect(buildTemplateIteration1, 'outputspec.template', buildTemplateIteration2, 'inputspec.fixed_image') tbuilder.connect(datasource, 'imageList', buildTemplateIteration2, 'inputspec.images') tbuilder.connect(datasource, 'passiveImagesDictionariesList', buildTemplateIteration2, 'inputspec.ListOfPassiveImagesDictionaries') """ 8. Move selected files to a designated results folder """ datasink = pe.Node(io.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.join(requestedPath, "results") tbuilder.connect(buildTemplateIteration2, 'outputspec.template',datasink,'PrimaryTemplate') tbuilder.connect(buildTemplateIteration2, 'outputspec.passive_deformed_templates',datasink,'PassiveTemplate') tbuilder.connect(initAvg, 'output_average_image', datasink,'PreRegisterAverage') """ 8. Run the workflow """ tbuilder.run() nipype-0.11.0/examples/smri_ants_registration.py000066400000000000000000000056311257611314500220700ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ================================== sMRI: Using ANTS for registration ================================== In this simple tutorial we will use the Registration interface from ANTS to coregister two T1 volumes. 1. Tell python where to find the appropriate functions. """ import os import urllib2 from nipype.interfaces.ants import Registration """ 2. Download T1 volumes into home directory """ homeDir=os.getenv("HOME") requestedPath=os.path.join(homeDir,'nipypeTestPath') mydatadir=os.path.realpath(requestedPath) if not os.path.exists(mydatadir): os.makedirs(mydatadir) print mydatadir MyFileURLs=[ ('http://slicer.kitware.com/midas3/download?bitstream=13121','01_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13122','02_T1_half.nii.gz'), ] for tt in MyFileURLs: myURL=tt[0] localFilename=os.path.join(mydatadir,tt[1]) if not os.path.exists(localFilename): remotefile = urllib2.urlopen(myURL) localFile = open(localFilename, 'wb') localFile.write(remotefile.read()) localFile.close() print("Downloaded file: {0}".format(localFilename)) else: print("File previously downloaded {0}".format(localFilename)) input_images=[ os.path.join(mydatadir,'01_T1_half.nii.gz'), os.path.join(mydatadir,'02_T1_half.nii.gz'), ] """ 3. Define the parameters of the registration """ reg = Registration() reg.inputs.fixed_image = input_images[0] reg.inputs.moving_image = input_images[1] reg.inputs.output_transform_prefix = 'thisTransform' reg.inputs.output_warped_image = 'INTERNAL_WARPED.nii.gz' reg.inputs.output_transform_prefix = "output_" reg.inputs.transforms = ['Translation', 'Rigid', 'Affine', 'SyN'] reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.1,), (0.2, 3.0, 0.0)] reg.inputs.number_of_iterations = ([[10000, 111110, 11110]]*3 + [[100, 50, 30]]) reg.inputs.dimension = 3 reg.inputs.write_composite_transform = True reg.inputs.collapse_output_transforms = False reg.inputs.metric = ['Mattes'] * 3 + [['Mattes', 'CC']] reg.inputs.metric_weight = [1] * 3 + [[0.5, 0.5]] reg.inputs.radius_or_number_of_bins = [32] * 3 + [[32, 4]] reg.inputs.sampling_strategy = ['Regular'] * 3 + [[None, None]] reg.inputs.sampling_percentage = [0.3] * 3 + [[None, None]] reg.inputs.convergence_threshold = [1.e-8] * 3 + [-0.01] reg.inputs.convergence_window_size = [20] * 3 + [5] reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 3 + [[1, 0.5, 0]] reg.inputs.sigma_units = ['vox'] * 4 reg.inputs.shrink_factors = [[6, 4, 2]] + [[3, 2, 1]]*2 + [[4, 2, 1]] reg.inputs.use_estimate_learning_rate_once = [True] * 4 reg.inputs.use_histogram_matching = [False] * 3 + [True] reg.inputs.initial_moving_transform_com = True print reg.cmdline """ 3. Run the registration """ reg.run() nipype-0.11.0/examples/smri_antsregistration_build_template.py000066400000000000000000000157251257611314500250100ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ====================================================== sMRI: Using new ANTS for creating a T1 template (ITK4) ====================================================== In this tutorial we will use ANTS (new ITK4 version aka "antsRegistration") based workflow to create a template out of multiple T1 volumes. We will also showcase how to fine tune SGE jobs requirements. 1. Tell python where to find the appropriate functions. """ import os import nipype.interfaces.utility as util import nipype.interfaces.ants as ants import nipype.interfaces.io as io import nipype.pipeline.engine as pe # pypeline engine from nipype.workflows.smri.ants import antsRegistrationTemplateBuildSingleIterationWF """ 2. Download T1 volumes into home directory """ import urllib2 homeDir=os.getenv("HOME") requestedPath=os.path.join(homeDir,'nipypeTestPath') mydatadir=os.path.realpath(requestedPath) if not os.path.exists(mydatadir): os.makedirs(mydatadir) print mydatadir MyFileURLs=[ ('http://slicer.kitware.com/midas3/download?bitstream=13121','01_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13122','02_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13124','03_T1_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13128','01_T1_inv_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13123','02_T1_inv_half.nii.gz'), ('http://slicer.kitware.com/midas3/download?bitstream=13125','03_T1_inv_half.nii.gz'), ] for tt in MyFileURLs: myURL=tt[0] localFilename=os.path.join(mydatadir,tt[1]) if not os.path.exists(localFilename): remotefile = urllib2.urlopen(myURL) localFile = open(localFilename, 'wb') localFile.write(remotefile.read()) localFile.close() print("Downloaded file: {0}".format(localFilename)) else: print("File previously downloaded {0}".format(localFilename)) """ ListOfImagesDictionaries - a list of dictionaries where each dictionary is for one scan session, and the mappings in the dictionary are for all the co-aligned images for that one scan session """ ListOfImagesDictionaries=[ {'T1':os.path.join(mydatadir,'01_T1_half.nii.gz'),'INV_T1':os.path.join(mydatadir,'01_T1_inv_half.nii.gz'),'LABEL_MAP':os.path.join(mydatadir,'01_T1_inv_half.nii.gz')}, {'T1':os.path.join(mydatadir,'02_T1_half.nii.gz'),'INV_T1':os.path.join(mydatadir,'02_T1_inv_half.nii.gz'),'LABEL_MAP':os.path.join(mydatadir,'02_T1_inv_half.nii.gz')}, {'T1':os.path.join(mydatadir,'03_T1_half.nii.gz'),'INV_T1':os.path.join(mydatadir,'03_T1_inv_half.nii.gz'),'LABEL_MAP':os.path.join(mydatadir,'03_T1_inv_half.nii.gz')} ] input_passive_images=[ {'INV_T1':os.path.join(mydatadir,'01_T1_inv_half.nii.gz')}, {'INV_T1':os.path.join(mydatadir,'02_T1_inv_half.nii.gz')}, {'INV_T1':os.path.join(mydatadir,'03_T1_inv_half.nii.gz')} ] """ registrationImageTypes - A list of the image types to be used actively during the estimation process of registration, any image type not in this list will be passively resampled with the estimated transforms. ['T1','T2'] """ registrationImageTypes=['T1'] """ interpolationMap - A map of image types to interpolation modes. If an image type is not listed, it will be linearly interpolated. { 'labelmap':'NearestNeighbor', 'FLAIR':'WindowedSinc' } """ interpolationMapping={'INV_T1':'LanczosWindowedSinc','LABEL_MAP':'NearestNeighbor','T1':'Linear'} """ 3. Define the workflow and its working directory """ tbuilder=pe.Workflow(name="antsRegistrationTemplateBuilder") tbuilder.base_dir=requestedPath """ 4. Define data sources. In real life these would be replace by DataGrabbers """ InitialTemplateInputs=[ mdict['T1'] for mdict in ListOfImagesDictionaries ] datasource = pe.Node(interface=util.IdentityInterface(fields= ['InitialTemplateInputs', 'ListOfImagesDictionaries', 'registrationImageTypes','interpolationMapping']), run_without_submitting=True, name='InputImages' ) datasource.inputs.InitialTemplateInputs=InitialTemplateInputs datasource.inputs.ListOfImagesDictionaries=ListOfImagesDictionaries datasource.inputs.registrationImageTypes=registrationImageTypes datasource.inputs.interpolationMapping=interpolationMapping datasource.inputs.sort_filelist = True """ 5. Template is initialized by a simple average in this simple example, any reference image could be used (i.e. a previously created template) """ initAvg = pe.Node(interface=ants.AverageImages(), name ='initAvg') initAvg.inputs.dimension = 3 initAvg.inputs.normalize = True tbuilder.connect(datasource, "InitialTemplateInputs", initAvg, "images") """ 6. Define the first iteration of template building """ buildTemplateIteration1=antsRegistrationTemplateBuildSingleIterationWF('iteration01') """ Here we are fine tuning parameters of the SGE job (memory limit, numebr of cores etc.) """ BeginANTS = buildTemplateIteration1.get_node("BeginANTS") BeginANTS.plugin_args={'qsub_args': '-S /bin/bash -pe smp1 8-12 -l mem_free=6000M -o /dev/null -e /dev/null queue_name', 'overwrite': True} tbuilder.connect(initAvg, 'output_average_image', buildTemplateIteration1, 'inputspec.fixed_image') tbuilder.connect(datasource, 'ListOfImagesDictionaries', buildTemplateIteration1, 'inputspec.ListOfImagesDictionaries') tbuilder.connect(datasource, 'registrationImageTypes', buildTemplateIteration1, 'inputspec.registrationImageTypes') tbuilder.connect(datasource, 'interpolationMapping', buildTemplateIteration1, 'inputspec.interpolationMapping') """ 7. Define the second iteration of template building """ buildTemplateIteration2 = antsRegistrationTemplateBuildSingleIterationWF('iteration02') BeginANTS = buildTemplateIteration2.get_node("BeginANTS") BeginANTS.plugin_args={'qsub_args': '-S /bin/bash -pe smp1 8-12 -l mem_free=6000M -o /dev/null -e /dev/null queue_name', 'overwrite': True} tbuilder.connect(buildTemplateIteration1, 'outputspec.template', buildTemplateIteration2, 'inputspec.fixed_image') tbuilder.connect(datasource, 'ListOfImagesDictionaries', buildTemplateIteration2, 'inputspec.ListOfImagesDictionaries') tbuilder.connect(datasource, 'registrationImageTypes', buildTemplateIteration2, 'inputspec.registrationImageTypes') tbuilder.connect(datasource, 'interpolationMapping', buildTemplateIteration2, 'inputspec.interpolationMapping') """ 8. Move selected files to a designated results folder """ datasink = pe.Node(io.DataSink(), name="datasink") datasink.inputs.base_directory = os.path.join(requestedPath, "results") tbuilder.connect(buildTemplateIteration2, 'outputspec.template',datasink,'PrimaryTemplate') tbuilder.connect(buildTemplateIteration2, 'outputspec.passive_deformed_templates',datasink,'PassiveTemplate') tbuilder.connect(initAvg, 'output_average_image', datasink,'PreRegisterAverage') """ 9. Run the workflow """ tbuilder.run(plugin="SGE") nipype-0.11.0/examples/smri_cbs_skullstripping.py000066400000000000000000000022471257611314500222520ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ ======================================== sMRI: USing CBS Tools for skullstripping ======================================== This simple workflow uses SPECTRE2010 algorithm to skullstrip an MP2RAGE anatomical scan. """ import nipype.pipeline.engine as pe from nipype.interfaces.mipav.developer import JistIntensityMp2rageMasking, MedicAlgorithmSPECTRE2010 wf = pe.Workflow("skullstripping") mask = pe.Node(JistIntensityMp2rageMasking(), name="masking") mask.inputs.inSecond = "/Users/filo/7t_trt/niftis/sub001/session_1/MP2RAGE_INV2.nii.gz" mask.inputs.inQuantitative = "/Users/filo/7t_trt/niftis/sub001/session_1/MP2RAGE_UNI.nii.gz" mask.inputs.inT1weighted = "/Users/filo/7t_trt/niftis/sub001/session_1/MP2RAGE_T1.nii.gz" mask.inputs.outMasked = True mask.inputs.outMasked2 = True mask.inputs.outSignal = True mask.inputs.outSignal2 = True skullstrip = pe.Node(MedicAlgorithmSPECTRE2010(), name="skullstrip") skullstrip.inputs.outStripped = True skullstrip.inputs.xDefaultMem = 6000 wf.connect(mask, 'outMasked', skullstrip, 'inInput') wf.run()nipype-0.11.0/examples/smri_freesurfer.py000066400000000000000000000034631257611314500205020ustar00rootroot00000000000000#!/usr/bin/env python """ ================ sMRI: FreeSurfer ================ This script, smri_freesurfer.py, demonstrates the ability to call reconall on a set of subjects and then make an average subject:: python smri_freesurfer.py Import necessary modules from nipype. """ import os import nipype.pipeline.engine as pe import nipype.interfaces.io as nio from nipype.interfaces.freesurfer.preprocess import ReconAll from nipype.interfaces.freesurfer.utils import MakeAverageSubject subject_list = ['s1', 's3'] data_dir = os.path.abspath('data') subjects_dir = os.path.abspath('amri_freesurfer_tutorial/subjects_dir') wf = pe.Workflow(name="l1workflow") wf.base_dir = os.path.abspath('amri_freesurfer_tutorial/workdir') """ Grab data """ datasource = pe.MapNode(interface=nio.DataGrabber(infields=['subject_id'], outfields=['struct']), name='datasource', iterfield=['subject_id']) datasource.inputs.base_directory = data_dir datasource.inputs.template = '%s/%s.nii' datasource.inputs.template_args = dict(struct=[['subject_id', 'struct']]) datasource.inputs.subject_id = subject_list datasource.inputs.sort_filelist = True """ Run recon-all """ recon_all = pe.MapNode(interface=ReconAll(), name='recon_all', iterfield=['subject_id', 'T1_files']) recon_all.inputs.subject_id = subject_list if not os.path.exists(subjects_dir): os.mkdir(subjects_dir) recon_all.inputs.subjects_dir = subjects_dir wf.connect(datasource, 'struct', recon_all, 'T1_files') """ Make average subject """ average = pe.Node(interface=MakeAverageSubject(), name="average") average.inputs.subjects_dir = subjects_dir wf.connect(recon_all, 'subject_id', average, 'subjects_ids') wf.run("MultiProc", plugin_args={'n_procs': 4}) nipype-0.11.0/examples/tessellation_tutorial.py000066400000000000000000000067021257611314500217300ustar00rootroot00000000000000#!/usr/bin/env python """ ================================================= sMRI: Regional Tessellation and Surface Smoothing ================================================= Introduction ============ This script, tessellation_tutorial.py, demonstrates the use of create_tessellation_flow from nipype.workflows.smri.freesurfer, and it can be run with:: python tessellation_tutorial.py This example requires that the user has Freesurfer installed, and that the Freesurfer directory for 'fsaverage' is present. .. seealso:: ConnectomeViewer The Connectome Viewer connects Multi-Modal Multi-Scale Neuroimaging and Network Datasets For Analysis and Visualization in Python. http://www.geuz.org/gmsh/ Gmsh: a three-dimensional finite element mesh generator with built-in pre- and post-processing facilities http://www.blender.org/ Blender is the free open source 3D content creation suite, available for all major operating systems under the GNU General Public License. .. warning:: This workflow will take several hours to finish entirely, since smoothing the larger cortical surfaces is very time consuming. Packages and Data Setup ======================= Import the necessary modules and workflow from nipype. """ import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.cmtk as cmtk import nipype.interfaces.io as nio # Data i/o import os, os.path as op from nipype.workflows.smri.freesurfer import create_tessellation_flow """ Directories =========== Set the default directory and lookup table (LUT) paths """ fs_dir = os.environ['FREESURFER_HOME'] lookup_file = op.join(fs_dir,'FreeSurferColorLUT.txt') subjects_dir = op.join(fs_dir, 'subjects/') output_dir = './tessellate_tutorial' """ Inputs ====== Create the tessellation workflow and set inputs Here we will choose Gifti (gii) as the output format, because we want to able to view the surface in ConnectomeViewer. In you intend to view the meshes in gmsh or Blender, you should change the workflow creation to use stereolithographic (stl) format. """ tessflow = create_tessellation_flow(name='tessflow', out_format='gii') tessflow.inputs.inputspec.subject_id = 'fsaverage' tessflow.inputs.inputspec.subjects_dir = subjects_dir tessflow.inputs.inputspec.lookup_file = lookup_file """ We also create a conditional node to package the surfaces for ConnectomeViewer. Simply set cff to "False" to ignore this step. """ cff = True if cff: cff = pe.Node(interface=cmtk.CFFConverter(), name='cff') cff.inputs.out_file = 'Meshes.cff' """ Outputs ======= Create a datasink to organize the smoothed meshes Using regular-expression substitutions we can remove the extraneous folders generated by the mapnode. """ datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = 'meshes' datasink.inputs.regexp_substitutions = [('_smoother[\d]*/', '')] """ Execution ========= Finally, create and run another pipeline that connects the workflow and datasink """ tesspipe = pe.Workflow(name='tessellate_tutorial') tesspipe.base_dir = output_dir tesspipe.connect([(tessflow, datasink,[('outputspec.meshes', '@meshes.all')])]) """ If the surfaces are to be packaged, this will connect the CFFConverter node to the tessellation and smoothing workflow, as well as to the datasink. """ if cff: tesspipe.connect([(tessflow, cff,[('outputspec.meshes', 'gifti_surfaces')])]) tesspipe.connect([(cff, datasink,[('connectome_file', '@cff')])]) tesspipe.run() nipype-0.11.0/examples/test_spm.py000066400000000000000000000053401257611314500171320ustar00rootroot00000000000000import nipype.pipeline.engine as pe from nipype.interfaces import spm from nipype.interfaces import fsl from nipype.algorithms.misc import Gunzip import os in_file = "feeds/data/fmri.nii.gz" split = pe.Node(fsl.Split(dimension="t", output_type="NIFTI"), name="split") split.inputs.in_file = os.path.abspath(in_file) stc = pe.Node(interface=spm.SliceTiming(), name='stc') stc.inputs.num_slices = 21 stc.inputs.time_repetition = 1.0 stc.inputs.time_acquisition = 2. - 2./32 stc.inputs.slice_order = range(21,0,-1) stc.inputs.ref_slice = 10 realign_estimate = pe.Node(interface=spm.Realign(), name='realign_estimate') realign_estimate.inputs.jobtype = "estimate" realign_write = pe.Node(interface=spm.Realign(), name='realign_write') realign_write.inputs.jobtype = "write" realign_estwrite = pe.Node(interface=spm.Realign(), name='realign_estwrite') realign_estwrite.inputs.jobtype = "estwrite" realign_estwrite.inputs.register_to_mean = True smooth = pe.Node(interface=spm.Smooth(), name = 'smooth') smooth.inputs.fwhm = [6, 6, 6] workflow3d = pe.Workflow(name='test_3d') workflow3d.base_dir = "/tmp" workflow3d.connect([(split, stc, [("out_files", "in_files")]), (stc, realign_estimate, [('timecorrected_files','in_files')]), (realign_estimate, realign_write, [('modified_in_files','in_files')]), (stc, realign_estwrite, [('timecorrected_files','in_files')]), (realign_write, smooth, [('realigned_files','in_files')])]) workflow3d.run() gunzip = pe.Node(Gunzip(), name="gunzip") gunzip.inputs.in_file = os.path.abspath(in_file) stc = pe.Node(interface=spm.SliceTiming(), name='stc') stc.inputs.num_slices = 21 stc.inputs.time_repetition = 1.0 stc.inputs.time_acquisition = 2. - 2./32 stc.inputs.slice_order = range(21,0,-1) stc.inputs.ref_slice = 10 realign_estimate = pe.Node(interface=spm.Realign(), name='realign_estimate') realign_estimate.inputs.jobtype = "estimate" realign_write = pe.Node(interface=spm.Realign(), name='realign_write') realign_write.inputs.jobtype = "write" realign_estwrite = pe.Node(interface=spm.Realign(), name='realign_estwrite') realign_estwrite.inputs.jobtype = "estwrite" smooth = pe.Node(interface=spm.Smooth(), name = 'smooth') smooth.inputs.fwhm = [6, 6, 6] workflow4d = pe.Workflow(name='test_4d') workflow4d.base_dir = "/tmp" workflow4d.connect([(gunzip, stc, [("out_file", "in_files")]), (stc, realign_estimate, [('timecorrected_files','in_files')]), (realign_estimate, realign_write, [('modified_in_files','in_files')]), (stc, realign_estwrite, [('timecorrected_files','in_files')]), (realign_write, smooth, [('realigned_files','in_files')])]) workflow4d.run()nipype-0.11.0/examples/workshop_dartmouth_2010.py000066400000000000000000000231621257611314500217030ustar00rootroot00000000000000""" ================================ Workshop: Dartmouth College 2010 ================================ First lets go to the directory with the data we'll be working on and start the interactive python interpreter (with some nipype specific configuration). Note that nipype does not need to be run through ipython - it is just much nicer to do interactive work in it. .. sourcecode:: bash cd $TDPATH ipython -p nipype For every neuroimaging procedure supported by nipype there exists a wrapper - a small piece of code managing the underlying software (FSL, SPM, AFNI etc.). We call those interfaces. They are standarised so we can hook them up together. Lets have a look at some of them. .. sourcecode:: ipython In [1]: import nipype.interfaces.fsl as fsl In [2]: fsl.BET.help() Inputs ------ Mandatory: in_file: input file to skull strip Optional: args: Additional parameters to the command center: center of gravity in voxels environ: Environment variables (default={}) frac: fractional intensity threshold functional: apply to 4D fMRI data mutually exclusive: functional, reduce_bias mask: create binary mask image mesh: generate a vtk mesh brain surface no_output: Don't generate segmented output out_file: name of output skull stripped image outline: create surface outline image output_type: FSL output type radius: head radius reduce_bias: bias field and neck cleanup mutually exclusive: functional, reduce_bias skull: create skull image threshold: apply thresholding to segmented brain image and mask vertical_gradient: vertical gradient in fractional intensity threshold (-1, 1) Outputs ------- mask_file: path/name of binary brain mask (if generated) meshfile: path/name of vtk mesh file (if generated) out_file: path/name of skullstripped file outline_file: path/name of outline file (if generated) In [3]: import nipype.interfaces.freesurfer as fs In [4]: fs.Smooth.help() Inputs ------ Mandatory: in_file: source volume num_iters: number of iterations instead of fwhm mutually exclusive: surface_fwhm reg_file: registers volume to surface anatomical surface_fwhm: surface FWHM in mm mutually exclusive: num_iters requires: reg_file Optional: args: Additional parameters to the command environ: Environment variables (default={}) proj_frac: project frac of thickness a long surface normal mutually exclusive: proj_frac_avg proj_frac_avg: average a long normal min max delta mutually exclusive: proj_frac smoothed_file: output volume subjects_dir: subjects directory vol_fwhm: volumesmoothing outside of surface Outputs ------- args: Additional parameters to the command environ: Environment variables smoothed_file: smoothed input volume subjects_dir: subjects directory You can read about all of the interfaces implemented in nipype at our online documentation at http://nipy.sourceforge.net/nipype/documentation.html#documentation . Check it out now. Using interfaces ---------------- Having interfaces allows us to use third party software (like FSL BET) as function. Look how simple it is. """ import nipype.interfaces.fsl as fsl result = fsl.BET(in_file='data/s1/struct.nii').run() print result """ Running a single program is not much of a breakthrough. Lets run motion correction followed by smoothing (isotropic - in other words not using SUSAN). Notice that in the first line we are setting the output data type for all FSL interfaces. """ fsl.FSLCommand.set_default_output_type('NIFTI_GZ') result1 = fsl.MCFLIRT(in_file='data/s1/f3.nii').run() result2 = fsl.Smooth(in_file='f3_mcf.nii.gz', fwhm=6).run() """ Simple workflow --------------- In the previous example we knew that fsl.MCFLIRT will produce a file called f3_mcf.nii.gz and we have hard coded this as an input to fsl.Smooth. This is quite limited, but luckily nipype supports joining interfaces in pipelines. This way output of one interface will be used as an input of another without having to hard code anything. Before connecting Interfaces we need to put them into (separate) Nodes and give them unique names. This way every interface will process data in a separate folder. """ import nipype.pipeline.engine as pe import os motion_correct = pe.Node(interface=fsl.MCFLIRT(in_file=os.path.abspath('data/s1/f3.nii')), name="motion_correct") smooth = pe.Node(interface=fsl.Smooth(fwhm=6), name="smooth") motion_correct_and_smooth = pe.Workflow(name="motion_correct_and_smooth") motion_correct_and_smooth.base_dir = os.path.abspath('.') # define where will be the root folder for the workflow motion_correct_and_smooth.connect([ (motion_correct, smooth, [('out_file', 'in_file')]) ]) # we are connecting 'out_file' output of motion_correct to 'in_file' input of smooth motion_correct_and_smooth.run() """ Another workflow ---------------- Another example of a simple workflow (calculate the mean of fMRI signal and subtract it). This time we'll be assigning inputs after defining the workflow. """ calc_mean = pe.Node(interface=fsl.ImageMaths(), name="calc_mean") calc_mean.inputs.op_string = "-Tmean" subtract = pe.Node(interface=fsl.ImageMaths(), name="subtract") subtract.inputs.op_string = "-sub" demean = pe.Workflow(name="demean") demean.base_dir = os.path.abspath('.') demean.connect([ (calc_mean, subtract, [('out_file', 'in_file2')]) ]) demean.inputs.calc_mean.in_file = os.path.abspath('data/s1/f3.nii') demean.inputs.subtract.in_file = os.path.abspath('data/s1/f3.nii') demean.run() """ Reusing workflows ----------------- The beauty of the workflows is that they are reusable. We can just import a workflow made by someone else and feed it with our data. """ from fmri_fsl import preproc preproc.base_dir = os.path.abspath('.') preproc.inputs.inputspec.func = os.path.abspath('data/s1/f3.nii') preproc.inputs.inputspec.struct = os.path.abspath('data/s1/struct.nii') preproc.run() """ ... and we can run it again and it won't actually rerun anything because none of the parameters have changed. """ preproc.run() """ ... and we can change a parameter and run it again. Only the dependent nodes are rerun and that too only if the input state has changed. """ preproc.inputs.meanfuncmask.frac = 0.5 preproc.run() """ Visualizing workflows 1 ----------------------- So what did we run in this precanned workflow """ preproc.write_graph() """ Datasink -------- Datasink is a special interface for copying and arranging results. """ import nipype.interfaces.io as nio preproc.inputs.inputspec.func = os.path.abspath('data/s1/f3.nii') preproc.inputs.inputspec.struct = os.path.abspath('data/s1/struct.nii') datasink = pe.Node(interface=nio.DataSink(),name='sinker') preprocess = pe.Workflow(name='preprocout') preprocess.base_dir = os.path.abspath('.') preprocess.connect([ (preproc, datasink, [('meanfunc2.out_file', 'meanfunc'), ('maskfunc3.out_file', 'funcruns')]) ]) preprocess.run() """ Datagrabber ----------- Datagrabber is (surprise, surprise) an interface for collecting files from hard drive. It is very flexible and supports almost any file organisation of your data you can imagine. """ datasource1 = nio.DataGrabber() datasource1.inputs.template = 'data/s1/f3.nii' datasource1.inputs.sort_filelist = True results = datasource1.run() print results.outputs datasource2 = nio.DataGrabber() datasource2.inputs.template = 'data/s*/f*.nii' datasource2.inputs.sort_filelist = True results = datasource2.run() print results.outputs datasource3 = nio.DataGrabber(infields=['run']) datasource3.inputs.template = 'data/s1/f%d.nii' datasource3.inputs.sort_filelist = True datasource3.inputs.run = [3, 7] results = datasource3.run() print results.outputs datasource4 = nio.DataGrabber(infields=['subject_id', 'run']) datasource4.inputs.template = 'data/%s/f%d.nii' datasource4.inputs.sort_filelist = True datasource4.inputs.run = [3, 7] datasource4.inputs.subject_id = ['s1', 's3'] results = datasource4.run() print results.outputs """ Iterables --------- Iterables is a special field of the Node class that enables to iterate all workfloes/nodes connected to it over some parameters. Here we'll use it to iterate over two subjects. """ import nipype.interfaces.utility as util infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="infosource") infosource.iterables = ('subject_id', ['s1', 's3']) datasource = pe.Node(nio.DataGrabber(infields=['subject_id'], outfields=['func', 'struct']), name="datasource") datasource.inputs.template = '%s/%s.nii' datasource.inputs.base_directory = os.path.abspath('data') datasource.inputs.template_args = dict(func=[['subject_id','f3']], struct=[['subject_id','struct']]) datasource.inputs.sort_filelist = True my_workflow = pe.Workflow(name="my_workflow") my_workflow.base_dir = os.path.abspath('.') my_workflow.connect([(infosource, datasource, [('subject_id', 'subject_id')]), (datasource, preproc, [('func', 'inputspec.func'), ('struct', 'inputspec.struct')])]) my_workflow.run() """ and we can change a node attribute and run it again """ smoothnode = my_workflow.get_node('preproc.smooth') assert(str(smoothnode)=='preproc.smooth') smoothnode.iterables = ('fwhm', [5.,10.]) my_workflow.run() """ Visualizing workflows 2 ----------------------- In the case of nested workflows, we might want to look at expanded forms of the workflow. """ nipype-0.11.0/nipype/000077500000000000000000000000001257611314500144065ustar00rootroot00000000000000nipype-0.11.0/nipype/COMMIT_INFO.txt000066400000000000000000000004141257611314500167510ustar00rootroot00000000000000# This is an ini file that may contain information about the code state [commit hash] # The line below may contain a valid hash if it has been substituted during 'git archive' archive_subst_hash=f9c98ba # This line may be modified by the install process install_hash= nipype-0.11.0/nipype/__init__.py000066400000000000000000000046211257611314500165220ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from info import (LONG_DESCRIPTION as __doc__, URL as __url__, STATUS as __status__, __version__) from utils.config import NipypeConfig config = NipypeConfig() from utils.logger import Logging logging = Logging(config) from distutils.version import LooseVersion from .fixes.numpy.testing import nosetester class _NoseTester(nosetester.NoseTester): """ Subclass numpy's NoseTester to add doctests by default """ def _get_custom_doctester(self): return None def test(self, label='fast', verbose=1, extra_argv=['--exe'], doctests=True, coverage=False): """Run the full test suite Examples -------- This will run the test suite and stop at the first failing example >>> from nipype import test >>> test(extra_argv=['--exe', '-sx']) #doctest: +SKIP """ return super(_NoseTester, self).test(label=label, verbose=verbose, extra_argv=extra_argv, doctests=doctests, coverage=coverage) try: test = _NoseTester(raise_warnings="release").test except TypeError: # Older versions of numpy do not have a raise_warnings argument test = _NoseTester().test del nosetester def _test_local_install(): """ Warn the user that running with nipy being imported locally is a bad idea. """ if os.getcwd() == os.sep.join( os.path.abspath(__file__).split(os.sep)[:-2]): import warnings warnings.warn('Running the tests from the install directory may ' 'trigger some failures') _test_local_install() # Set up package information function from pkg_info import get_pkg_info as _get_pkg_info get_info = lambda: _get_pkg_info(os.path.dirname(__file__)) # Cleanup namespace del _test_local_install # If this file is exec after being imported, the following lines will # fail try: del Tester except: pass from pipeline import Node, MapNode, JoinNode, Workflow from interfaces import (DataGrabber, DataSink, SelectFiles, IdentityInterface, Rename, Function, Select, Merge) nipype-0.11.0/nipype/algorithms/000077500000000000000000000000001257611314500165575ustar00rootroot00000000000000nipype-0.11.0/nipype/algorithms/__init__.py000066400000000000000000000003561257611314500206740ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Package contains pure python neuroimaging algorithms Exaples: artifactdetect """ __docformat__ = 'restructuredtext' nipype-0.11.0/nipype/algorithms/icc.py000066400000000000000000000111071257611314500176670ustar00rootroot00000000000000from numpy import ones, kron, mean, eye, hstack, dot, tile from scipy.linalg import pinv from ..interfaces.base import BaseInterfaceInputSpec, TraitedSpec, \ BaseInterface, traits, File import nibabel as nb import numpy as np import os class ICCInputSpec(BaseInterfaceInputSpec): subjects_sessions = traits.List(traits.List(File(exists=True)), desc="n subjects m sessions 3D stat files", mandatory=True) mask = File(exists=True, mandatory=True) class ICCOutputSpec(TraitedSpec): icc_map = File(exists=True) session_var_map = File(exists=True, desc="variance between sessions") subject_var_map = File(exists=True, desc="variance between subjects") class ICC(BaseInterface): ''' Calculates Interclass Correlation Coefficient (3,1) as defined in P. E. Shrout & Joseph L. Fleiss (1979). "Intraclass Correlations: Uses in Assessing Rater Reliability". Psychological Bulletin 86 (2): 420-428. This particular implementation is aimed at relaibility (test-retest) studies. ''' input_spec = ICCInputSpec output_spec = ICCOutputSpec def _run_interface(self, runtime): maskdata = nb.load(self.inputs.mask).get_data() maskdata = np.logical_not(np.logical_or(maskdata == 0, np.isnan(maskdata))) session_datas = [[nb.load(fname).get_data()[maskdata].reshape(-1, 1) for fname in sessions] for sessions in self.inputs.subjects_sessions] list_of_sessions = [np.dstack(session_data) for session_data in session_datas] all_data = np.hstack(list_of_sessions) icc = np.zeros(session_datas[0][0].shape) session_F = np.zeros(session_datas[0][0].shape) session_var = np.zeros(session_datas[0][0].shape) subject_var = np.zeros(session_datas[0][0].shape) for x in range(icc.shape[0]): Y = all_data[x, :, :] icc[x], subject_var[x], session_var[x], session_F[x], _, _ = ICC_rep_anova(Y) nim = nb.load(self.inputs.subjects_sessions[0][0]) new_data = np.zeros(nim.get_shape()) new_data[maskdata] = icc.reshape(-1,) new_img = nb.Nifti1Image(new_data, nim.get_affine(), nim.get_header()) nb.save(new_img, 'icc_map.nii') new_data = np.zeros(nim.get_shape()) new_data[maskdata] = session_var.reshape(-1,) new_img = nb.Nifti1Image(new_data, nim.get_affine(), nim.get_header()) nb.save(new_img, 'session_var_map.nii') new_data = np.zeros(nim.get_shape()) new_data[maskdata] = subject_var.reshape(-1,) new_img = nb.Nifti1Image(new_data, nim.get_affine(), nim.get_header()) nb.save(new_img, 'subject_var_map.nii') return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['icc_map'] = os.path.abspath('icc_map.nii') outputs['sessions_F_map'] = os.path.abspath('sessions_F_map.nii') outputs['session_var_map'] = os.path.abspath('session_var_map.nii') outputs['subject_var_map'] = os.path.abspath('subject_var_map.nii') return outputs def ICC_rep_anova(Y): ''' the data Y are entered as a 'table' ie subjects are in rows and repeated measures in columns One Sample Repeated measure ANOVA Y = XB + E with X = [FaTor / Subjects] ''' [nb_subjects, nb_conditions] = Y.shape dfc = nb_conditions - 1 dfe = (nb_subjects - 1) * dfc dfr = nb_subjects - 1 # Compute the repeated measure effect # ------------------------------------ # Sum Square Total mean_Y = mean(Y) SST = ((Y - mean_Y) ** 2).sum() # create the design matrix for the different levels x = kron(eye(nb_conditions), ones((nb_subjects, 1))) # sessions x0 = tile(eye(nb_subjects), (nb_conditions, 1)) # subjects X = hstack([x, x0]) # Sum Square Error predicted_Y = dot(dot(dot(X, pinv(dot(X.T, X))), X.T), Y.flatten('F')) residuals = Y.flatten('F') - predicted_Y SSE = (residuals ** 2).sum() residuals.shape = Y.shape MSE = SSE / dfe # Sum square session effect - between colums/sessions SSC = ((mean(Y, 0) - mean_Y) ** 2).sum() * nb_subjects MSC = SSC / dfc / nb_subjects session_effect_F = MSC / MSE # Sum Square subject effect - between rows/subjects SSR = SST - SSC - SSE MSR = SSR / dfr # ICC(3,1) = (mean square subjeT - mean square error) / (mean square subjeT + (k-1)*-mean square error) ICC = (MSR - MSE) / (MSR + dfc * MSE) e_var = MSE #variance of error r_var = (MSR - MSE)/nb_conditions #variance between subjects return ICC, r_var, e_var, session_effect_F, dfc, dfe nipype-0.11.0/nipype/algorithms/mesh.py000066400000000000000000000353541257611314500200770ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: ''' Miscellaneous algorithms for 2D contours and 3D triangularized meshes handling Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) ''' import numpy as np from numpy import linalg as nla import os.path as op from ..external import six from .. import logging from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File, BaseInterfaceInputSpec) from warnings import warn iflogger = logging.getLogger('interface') class WarpPointsInputSpec(BaseInterfaceInputSpec): points = File(exists=True, mandatory=True, desc=('file containing the point set')) warp = File(exists=True, mandatory=True, desc=('dense deformation field to be applied')) interp = traits.Enum('cubic', 'nearest', 'linear', usedefault=True, mandatory=True, desc='interpolation') out_points = File(name_source='points', name_template='%s_warped', output_name='out_points', keep_extension=True, desc='the warped point set') class WarpPointsOutputSpec(TraitedSpec): out_points = File(desc='the warped point set') class WarpPoints(BaseInterface): """ Applies a displacement field to a point set given in vtk format. Any discrete deformation field, given in physical coordinates and which volume covers the extent of the vtk point set, is a valid ``warp`` file. FSL interfaces are compatible, for instance any field computed with :class:`nipype.interfaces.fsl.utils.ConvertWarp`. Example ------- >>> from nipype.algorithms.mesh import WarpPoints >>> wp = WarpPoints() >>> wp.inputs.points = 'surf1.vtk' >>> wp.inputs.warp = 'warpfield.nii' >>> res = wp.run() # doctest: +SKIP """ input_spec = WarpPointsInputSpec output_spec = WarpPointsOutputSpec _redirect_x = True def _gen_fname(self, in_file, suffix='generated', ext=None): import os.path as op fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, fext2 = op.splitext(fname) fext = fext2+fext if ext is None: ext = fext if ext[0] == '.': ext = ext[1:] return op.abspath('%s_%s.%s' % (fname, suffix, ext)) def _run_interface(self, runtime): vtk_major = 6 try: import vtk vtk_major = vtk.VTK_MAJOR_VERSION except ImportError: iflogger.warn(('python-vtk could not be imported')) try: from tvtk.api import tvtk except ImportError: raise ImportError('Interface requires tvtk') try: from enthought.etsconfig.api import ETSConfig ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) except ValueError: iflogger.warn(('ETS toolkit could not be set to null')) import nibabel as nb import numpy as np from scipy import ndimage r = tvtk.PolyDataReader(file_name=self.inputs.points) r.update() mesh = r.output points = np.array(mesh.points) warp_dims = nb.funcs.four_to_three(nb.load(self.inputs.warp)) affine = warp_dims[0].get_affine() voxsize = warp_dims[0].get_header().get_zooms() vox2ras = affine[0:3, 0:3] ras2vox = np.linalg.inv(vox2ras) origin = affine[0:3, 3] voxpoints = np.array([np.dot(ras2vox, (p-origin)) for p in points]) warps = [] for axis in warp_dims: wdata = axis.get_data() if np.any(wdata != 0): warp = ndimage.map_coordinates(wdata, voxpoints.transpose()) else: warp = np.zeros((points.shape[0],)) warps.append(warp) disps = np.squeeze(np.dstack(warps)) newpoints = [p+d for p, d in zip(points, disps)] mesh.points = newpoints w = tvtk.PolyDataWriter() if vtk_major <= 5: w.input = mesh else: w.set_input_data_object(mesh) w.file_name = self._gen_fname(self.inputs.points, suffix='warped', ext='.vtk') w.write() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_points'] = self._gen_fname(self.inputs.points, suffix='warped', ext='.vtk') return outputs class ComputeMeshWarpInputSpec(BaseInterfaceInputSpec): surface1 = File(exists=True, mandatory=True, desc=('Reference surface (vtk format) to which compute ' 'distance.')) surface2 = File(exists=True, mandatory=True, desc=('Test surface (vtk format) from which compute ' 'distance.')) metric = traits.Enum('euclidean', 'sqeuclidean', usedefault=True, desc=('norm used to report distance')) weighting = traits.Enum( 'none', 'area', usedefault=True, desc=('"none": no weighting is performed, surface": edge distance is ' 'weighted by the corresponding surface area')) out_warp = File('surfwarp.vtk', usedefault=True, desc='vtk file based on surface1 and warpings mapping it ' 'to surface2') out_file = File('distance.npy', usedefault=True, desc='numpy file keeping computed distances and weights') class ComputeMeshWarpOutputSpec(TraitedSpec): distance = traits.Float(desc="computed distance") out_warp = File(exists=True, desc=('vtk file with the vertex-wise ' 'mapping of surface1 to surface2')) out_file = File(exists=True, desc='numpy file keeping computed distances and weights') class ComputeMeshWarp(BaseInterface): """ Calculates a the vertex-wise warping to get surface2 from surface1. It also reports the average distance of vertices, using the norm specified as input. .. warning: A point-to-point correspondence between surfaces is required Example ------- >>> import nipype.algorithms.mesh as m >>> dist = m.ComputeMeshWarp() >>> dist.inputs.surface1 = 'surf1.vtk' >>> dist.inputs.surface2 = 'surf2.vtk' >>> res = dist.run() # doctest: +SKIP """ input_spec = ComputeMeshWarpInputSpec output_spec = ComputeMeshWarpOutputSpec _redirect_x = True def _triangle_area(self, A, B, C): A = np.array(A) B = np.array(B) C = np.array(C) ABxAC = nla.norm(A - B) * nla.norm(A - C) prod = np.dot(B - A, C - A) angle = np.arccos(prod / ABxAC) area = 0.5 * ABxAC * np.sin(angle) return area def _run_interface(self, runtime): try: from tvtk.api import tvtk except ImportError: raise ImportError('Interface ComputeMeshWarp requires tvtk') try: from enthought.etsconfig.api import ETSConfig ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) except ValueError: iflogger.warn(('ETS toolkit is already set')) r1 = tvtk.PolyDataReader(file_name=self.inputs.surface1) r2 = tvtk.PolyDataReader(file_name=self.inputs.surface2) vtk1 = r1.output vtk2 = r2.output r1.update() r2.update() assert(len(vtk1.points) == len(vtk2.points)) points1 = np.array(vtk1.points) points2 = np.array(vtk2.points) diff = points2 - points1 weights = np.ones(len(diff)) try: errvector = nla.norm(diff, axis=1) except TypeError: # numpy < 1.9 errvector = np.apply_along_axis(nla.norm, 1, diff) if self.inputs.metric == 'sqeuclidean': errvector = errvector ** 2 if (self.inputs.weighting == 'area'): faces = vtk1.polys.to_array().reshape(-1, 4).astype(int)[:, 1:] for i, p1 in enumerate(points2): # compute surfaces, set in weight w = 0.0 point_faces = faces[(faces[:, :] == i).any(axis=1)] for idset in point_faces: fp1 = points1[int(idset[0])] fp2 = points1[int(idset[1])] fp3 = points1[int(idset[2])] w += self._triangle_area(fp1, fp2, fp3) weights[i] = w result = np.vstack([errvector, weights]) np.save(op.abspath(self.inputs.out_file), result.transpose()) out_mesh = tvtk.PolyData() out_mesh.points = vtk1.points out_mesh.polys = vtk1.polys out_mesh.point_data.vectors = diff out_mesh.point_data.vectors.name = 'warpings' writer = tvtk.PolyDataWriter( file_name=op.abspath(self.inputs.out_warp)) writer.set_input_data(out_mesh) writer.write() self._distance = np.average(errvector, weights=weights) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self.inputs.out_file) outputs['out_warp'] = op.abspath(self.inputs.out_warp) outputs['distance'] = self._distance return outputs class MeshWarpMathsInputSpec(BaseInterfaceInputSpec): in_surf = File(exists=True, mandatory=True, desc=('Input surface in vtk format, with associated warp ' 'field as point data (ie. from ComputeMeshWarp')) float_trait = traits.Either(traits.Float(1.0), traits.Tuple( traits.Float(1.0), traits.Float(1.0), traits.Float(1.0))) operator = traits.Either( float_trait, File(exists=True), default=1.0, mandatory=True, desc=('image, float or tuple of floats to act as operator')) operation = traits.Enum('sum', 'sub', 'mul', 'div', usedefault=True, desc=('operation to be performed')) out_warp = File('warp_maths.vtk', usedefault=True, desc='vtk file based on in_surf and warpings mapping it ' 'to out_file') out_file = File('warped_surf.vtk', usedefault=True, desc='vtk with surface warped') class MeshWarpMathsOutputSpec(TraitedSpec): out_warp = File(exists=True, desc=('vtk file with the vertex-wise ' 'mapping of surface1 to surface2')) out_file = File(exists=True, desc='vtk with surface warped') class MeshWarpMaths(BaseInterface): """ Performs the most basic mathematical operations on the warping field defined at each vertex of the input surface. A surface with scalar or vector data can be used as operator for non-uniform operations. .. warning: A point-to-point correspondence between surfaces is required Example ------- >>> import nipype.algorithms.mesh as m >>> mmath = m.MeshWarpMaths() >>> mmath.inputs.in_surf = 'surf1.vtk' >>> mmath.inputs.operator = 'surf2.vtk' >>> mmath.inputs.operation = 'mul' >>> res = mmath.run() # doctest: +SKIP """ input_spec = MeshWarpMathsInputSpec output_spec = MeshWarpMathsOutputSpec _redirect_x = True def _run_interface(self, runtime): try: from tvtk.api import tvtk except ImportError: raise ImportError('Interface ComputeMeshWarp requires tvtk') try: from enthought.etsconfig.api import ETSConfig ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) except ValueError: iflogger.warn(('ETS toolkit is already set')) r1 = tvtk.PolyDataReader(file_name=self.inputs.in_surf) vtk1 = r1.output r1.update() points1 = np.array(vtk1.points) if vtk1.point_data.vectors is None: raise RuntimeError(('No warping field was found in in_surf')) operator = self.inputs.operator opfield = np.ones_like(points1) if isinstance(operator, six.string_types): r2 = tvtk.PolyDataReader(file_name=self.inputs.surface2) vtk2 = r2.output r2.update() assert(len(points1) == len(vtk2.points)) opfield = vtk2.point_data.vectors if opfield is None: opfield = vtk2.point_data.scalars if opfield is None: raise RuntimeError( ('No operator values found in operator file')) opfield = np.array(opfield) if opfield.shape[1] < points1.shape[1]: opfield = np.array([opfield.tolist()] * points1.shape[1]).T else: operator = np.atleast_1d(operator) opfield *= operator warping = np.array(vtk1.point_data.vectors) if self.inputs.operation == 'sum': warping += opfield elif self.inputs.operation == 'sub': warping -= opfield elif self.inputs.operation == 'mul': warping *= opfield elif self.inputs.operation == 'div': warping /= opfield vtk1.point_data.vectors = warping writer = tvtk.PolyDataWriter( file_name=op.abspath(self.inputs.out_warp)) writer.set_input_data(vtk1) writer.write() vtk1.point_data.vectors = None vtk1.points = points1 + warping writer = tvtk.PolyDataWriter( file_name=op.abspath(self.inputs.out_file)) writer.set_input_data(vtk1) writer.write() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self.inputs.out_file) outputs['out_warp'] = op.abspath(self.inputs.out_warp) return outputs class P2PDistance(ComputeMeshWarp): """ Calculates a point-to-point (p2p) distance between two corresponding VTK-readable meshes or contours. A point-to-point correspondence between nodes is required .. deprecated:: 1.0-dev Use :py:class:`ComputeMeshWarp` instead. """ def __init__(self, **inputs): super(P2PDistance, self).__init__(**inputs) warn(('This interface has been deprecated since 1.0, please use ' 'ComputeMeshWarp'), DeprecationWarning) nipype-0.11.0/nipype/algorithms/metrics.py000066400000000000000000000631661257611314500206130ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: ''' Image assessment algorithms. Typical overlap and error computation measures to evaluate results from other processing units. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) ''' import os import os.path as op import nibabel as nb import numpy as np from math import floor, ceil from scipy.ndimage.morphology import grey_dilation from scipy.ndimage.morphology import binary_erosion from scipy.spatial.distance import cdist, euclidean, dice, jaccard from scipy.ndimage.measurements import center_of_mass, label from scipy.special import legendre import scipy.io as sio import itertools import scipy.stats as stats from .. import logging from ..utils.misc import package_check from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File, InputMultiPath, OutputMultiPath, BaseInterfaceInputSpec, isdefined) from ..utils.filemanip import fname_presuffix, split_filename iflogger = logging.getLogger('interface') class DistanceInputSpec(BaseInterfaceInputSpec): volume1 = File(exists=True, mandatory=True, desc="Has to have the same dimensions as volume2.") volume2 = File( exists=True, mandatory=True, desc="Has to have the same dimensions as volume1." ) method = traits.Enum( "eucl_min", "eucl_cog", "eucl_mean", "eucl_wmean", "eucl_max", desc='""eucl_min": Euclidean distance between two closest points\ "eucl_cog": mean Euclidian distance between the Center of Gravity\ of volume1 and CoGs of volume2\ "eucl_mean": mean Euclidian minimum distance of all volume2 voxels\ to volume1\ "eucl_wmean": mean Euclidian minimum distance of all volume2 voxels\ to volume1 weighted by their values\ "eucl_max": maximum over minimum Euclidian distances of all volume2\ voxels to volume1 (also known as the Hausdorff distance)', usedefault=True ) mask_volume = File( exists=True, desc="calculate overlap only within this mask.") class DistanceOutputSpec(TraitedSpec): distance = traits.Float() point1 = traits.Array(shape=(3,)) point2 = traits.Array(shape=(3,)) histogram = File() class Distance(BaseInterface): """Calculates distance between two volumes. """ input_spec = DistanceInputSpec output_spec = DistanceOutputSpec _hist_filename = "hist.pdf" def _find_border(self, data): eroded = binary_erosion(data) border = np.logical_and(data, np.logical_not(eroded)) return border def _get_coordinates(self, data, affine): if len(data.shape) == 4: data = data[:, :, :, 0] indices = np.vstack(np.nonzero(data)) indices = np.vstack((indices, np.ones(indices.shape[1]))) coordinates = np.dot(affine, indices) return coordinates[:3, :] def _eucl_min(self, nii1, nii2): origdata1 = nii1.get_data().astype(np.bool) border1 = self._find_border(origdata1) origdata2 = nii2.get_data().astype(np.bool) border2 = self._find_border(origdata2) set1_coordinates = self._get_coordinates(border1, nii1.get_affine()) set2_coordinates = self._get_coordinates(border2, nii2.get_affine()) dist_matrix = cdist(set1_coordinates.T, set2_coordinates.T) (point1, point2) = np.unravel_index( np.argmin(dist_matrix), dist_matrix.shape) return (euclidean(set1_coordinates.T[point1, :], set2_coordinates.T[point2, :]), set1_coordinates.T[point1, :], set2_coordinates.T[point2, :]) def _eucl_cog(self, nii1, nii2): origdata1 = nii1.get_data().astype(np.bool) cog_t = np.array(center_of_mass(origdata1)).reshape(-1, 1) cog_t = np.vstack((cog_t, np.array([1]))) cog_t_coor = np.dot(nii1.get_affine(), cog_t)[:3, :] origdata2 = nii2.get_data().astype(np.bool) (labeled_data, n_labels) = label(origdata2) cogs = np.ones((4, n_labels)) for i in range(n_labels): cogs[:3, i] = np.array(center_of_mass(origdata2, labeled_data, i + 1)) cogs_coor = np.dot(nii2.get_affine(), cogs)[:3, :] dist_matrix = cdist(cog_t_coor.T, cogs_coor.T) return np.mean(dist_matrix) def _eucl_mean(self, nii1, nii2, weighted=False): origdata1 = nii1.get_data().astype(np.bool) border1 = self._find_border(origdata1) origdata2 = nii2.get_data().astype(np.bool) set1_coordinates = self._get_coordinates(border1, nii1.get_affine()) set2_coordinates = self._get_coordinates(origdata2, nii2.get_affine()) dist_matrix = cdist(set1_coordinates.T, set2_coordinates.T) min_dist_matrix = np.amin(dist_matrix, axis=0) import matplotlib.pyplot as plt plt.figure() plt.hist(min_dist_matrix, 50, normed=1, facecolor='green') plt.savefig(self._hist_filename) plt.clf() plt.close() if weighted: return np.average( min_dist_matrix, weights=nii2.get_data()[origdata2].flat ) else: return np.mean(min_dist_matrix) def _eucl_max(self, nii1, nii2): origdata1 = nii1.get_data() origdata1 = np.logical_not( np.logical_or(origdata1 == 0, np.isnan(origdata1))) origdata2 = nii2.get_data() origdata2 = np.logical_not( np.logical_or(origdata2 == 0, np.isnan(origdata2))) if isdefined(self.inputs.mask_volume): maskdata = nb.load(self.inputs.mask_volume).get_data() maskdata = np.logical_not( np.logical_or(maskdata == 0, np.isnan(maskdata))) origdata1 = np.logical_and(maskdata, origdata1) origdata2 = np.logical_and(maskdata, origdata2) if origdata1.max() == 0 or origdata2.max() == 0: return np.NaN border1 = self._find_border(origdata1) border2 = self._find_border(origdata2) set1_coordinates = self._get_coordinates(border1, nii1.get_affine()) set2_coordinates = self._get_coordinates(border2, nii2.get_affine()) distances = cdist(set1_coordinates.T, set2_coordinates.T) mins = np.concatenate( (np.amin(distances, axis=0), np.amin(distances, axis=1))) return np.max(mins) def _run_interface(self, runtime): nii1 = nb.load(self.inputs.volume1) nii2 = nb.load(self.inputs.volume2) if self.inputs.method == "eucl_min": self._distance, self._point1, self._point2 = self._eucl_min( nii1, nii2) elif self.inputs.method == "eucl_cog": self._distance = self._eucl_cog(nii1, nii2) elif self.inputs.method == "eucl_mean": self._distance = self._eucl_mean(nii1, nii2) elif self.inputs.method == "eucl_wmean": self._distance = self._eucl_mean(nii1, nii2, weighted=True) elif self.inputs.method == "eucl_max": self._distance = self._eucl_max(nii1, nii2) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['distance'] = self._distance if self.inputs.method == "eucl_min": outputs['point1'] = self._point1 outputs['point2'] = self._point2 elif self.inputs.method in ["eucl_mean", "eucl_wmean"]: outputs['histogram'] = os.path.abspath(self._hist_filename) return outputs class OverlapInputSpec(BaseInterfaceInputSpec): volume1 = File(exists=True, mandatory=True, desc='Has to have the same dimensions as volume2.') volume2 = File(exists=True, mandatory=True, desc='Has to have the same dimensions as volume1.') mask_volume = File(exists=True, desc='calculate overlap only within this mask.') bg_overlap = traits.Bool(False, usedefault=True, mandatory=True, desc='consider zeros as a label') out_file = File('diff.nii', usedefault=True) weighting = traits.Enum('none', 'volume', 'squared_vol', usedefault=True, desc=('\'none\': no class-overlap weighting is ' 'performed. \'volume\': computed class-' 'overlaps are weighted by class volume ' '\'squared_vol\': computed class-overlaps ' 'are weighted by the squared volume of ' 'the class')) vol_units = traits.Enum('voxel', 'mm', mandatory=True, usedefault=True, desc='units for volumes') class OverlapOutputSpec(TraitedSpec): jaccard = traits.Float(desc='averaged jaccard index') dice = traits.Float(desc='averaged dice index') roi_ji = traits.List(traits.Float(), desc=('the Jaccard index (JI) per ROI')) roi_di = traits.List(traits.Float(), desc=('the Dice index (DI) per ROI')) volume_difference = traits.Float(desc=('averaged volume difference')) roi_voldiff = traits.List(traits.Float(), desc=('volume differences of ROIs')) labels = traits.List(traits.Int(), desc=('detected labels')) diff_file = File(exists=True, desc='error map of differences') class Overlap(BaseInterface): """ Calculates Dice and Jaccard's overlap measures between two ROI maps. The interface is backwards compatible with the former version in which only binary files were accepted. The averaged values of overlap indices can be weighted. Volumes now can be reported in :math:`mm^3`, although they are given in voxels to keep backwards compatibility. Example ------- >>> overlap = Overlap() >>> overlap.inputs.volume1 = 'cont1.nii' >>> overlap.inputs.volume2 = 'cont2.nii' >>> res = overlap.run() # doctest: +SKIP """ input_spec = OverlapInputSpec output_spec = OverlapOutputSpec def _bool_vec_dissimilarity(self, booldata1, booldata2, method): methods = {'dice': dice, 'jaccard': jaccard} if not (np.any(booldata1) or np.any(booldata2)): return 0 return 1 - methods[method](booldata1.flat, booldata2.flat) def _run_interface(self, runtime): nii1 = nb.load(self.inputs.volume1) nii2 = nb.load(self.inputs.volume2) scale = 1.0 if self.inputs.vol_units == 'mm': voxvol = nii1.get_header().get_zooms() for i in xrange(nii1.get_data().ndim-1): scale = scale * voxvol[i] data1 = nii1.get_data() data1[np.logical_or(data1 < 0, np.isnan(data1))] = 0 max1 = int(data1.max()) data1 = data1.astype(np.min_scalar_type(max1)) data2 = nii2.get_data().astype(np.min_scalar_type(max1)) data2[np.logical_or(data1 < 0, np.isnan(data1))] = 0 max2 = data2.max() maxlabel = max(max1, max2) if isdefined(self.inputs.mask_volume): maskdata = nb.load(self.inputs.mask_volume).get_data() maskdata = ~np.logical_or(maskdata == 0, np.isnan(maskdata)) data1[~maskdata] = 0 data2[~maskdata] = 0 res = [] volumes1 = [] volumes2 = [] labels = np.unique(data1[data1 > 0].reshape(-1)).tolist() if self.inputs.bg_overlap: labels.insert(0, 0) for l in labels: res.append(self._bool_vec_dissimilarity(data1 == l, data2 == l, method='jaccard')) volumes1.append(scale * len(data1[data1 == l])) volumes2.append(scale * len(data2[data2 == l])) results = dict(jaccard=[], dice=[]) results['jaccard'] = np.array(res) results['dice'] = 2.0*results['jaccard'] / (results['jaccard'] + 1.0) weights = np.ones((len(volumes1),), dtype=np.float32) if self.inputs.weighting != 'none': weights = weights / np.array(volumes1) if self.inputs.weighting == 'squared_vol': weights = weights**2 weights = weights / np.sum(weights) both_data = np.zeros(data1.shape) both_data[(data1 - data2) != 0] = 1 nb.save(nb.Nifti1Image(both_data, nii1.get_affine(), nii1.get_header()), self.inputs.out_file) self._labels = labels self._ove_rois = results self._vol_rois = ((np.array(volumes1) - np.array(volumes2)) / np.array(volumes1)) self._dice = round(np.sum(weights*results['dice']), 5) self._jaccard = round(np.sum(weights*results['jaccard']), 5) self._volume = np.sum(weights*self._vol_rois) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['labels'] = self._labels outputs['jaccard'] = self._jaccard outputs['dice'] = self._dice outputs['volume_difference'] = self._volume outputs['roi_ji'] = self._ove_rois['jaccard'].tolist() outputs['roi_di'] = self._ove_rois['dice'].tolist() outputs['roi_voldiff'] = self._vol_rois.tolist() outputs['diff_file'] = os.path.abspath(self.inputs.out_file) return outputs class FuzzyOverlapInputSpec(BaseInterfaceInputSpec): in_ref = InputMultiPath( File(exists=True), mandatory=True, desc='Reference image. Requires the same dimensions as in_tst.') in_tst = InputMultiPath( File(exists=True), mandatory=True, desc='Test image. Requires the same dimensions as in_ref.') weighting = traits.Enum('none', 'volume', 'squared_vol', usedefault=True, desc=('\'none\': no class-overlap weighting is ' 'performed. \'volume\': computed class-' 'overlaps are weighted by class volume ' '\'squared_vol\': computed class-overlaps ' 'are weighted by the squared volume of ' 'the class')) out_file = File('diff.nii', desc='alternative name for resulting difference-map', usedefault=True) class FuzzyOverlapOutputSpec(TraitedSpec): jaccard = traits.Float( desc='Fuzzy Jaccard Index (fJI), all the classes' ) dice = traits.Float( desc='Fuzzy Dice Index (fDI), all the classes' ) diff_file = File(exists=True, desc='resulting difference-map of all classes, using the chosen weighting' ) class_fji = traits.List( traits.Float(), desc='Array containing the fJIs of each computed class' ) class_fdi = traits.List( traits.Float(), desc='Array containing the fDIs of each computed class' ) class FuzzyOverlap(BaseInterface): """Calculates various overlap measures between two maps, using the fuzzy definition proposed in: Crum et al., Generalized Overlap Measures for Evaluation and Validation in Medical Image Analysis, IEEE Trans. Med. Ima. 25(11),pp 1451-1461, Nov. 2006. in_ref and in_tst are lists of 2/3D images, each element on the list containing one volume fraction map of a class in a fuzzy partition of the domain. Example ------- >>> overlap = FuzzyOverlap() >>> overlap.inputs.in_ref = [ 'ref_class0.nii', 'ref_class1.nii' ] >>> overlap.inputs.in_tst = [ 'tst_class0.nii', 'tst_class1.nii' ] >>> overlap.inputs.weighting = 'volume' >>> res = overlap.run() # doctest: +SKIP """ input_spec = FuzzyOverlapInputSpec output_spec = FuzzyOverlapOutputSpec def _run_interface(self, runtime): ncomp = len(self.inputs.in_ref) assert( ncomp == len(self.inputs.in_tst) ) weights = np.ones( shape=ncomp ) img_ref = np.array( [ nb.load( fname ).get_data() for fname in self.inputs.in_ref ] ) img_tst = np.array( [ nb.load( fname ).get_data() for fname in self.inputs.in_tst ] ) msk = np.sum(img_ref, axis=0) msk[msk>0] = 1.0 tst_msk = np.sum(img_tst, axis=0) tst_msk[tst_msk>0] = 1.0 #check that volumes are normalized #img_ref[:][msk>0] = img_ref[:][msk>0] / (np.sum( img_ref, axis=0 ))[msk>0] #img_tst[tst_msk>0] = img_tst[tst_msk>0] / np.sum( img_tst, axis=0 )[tst_msk>0] self._jaccards = [] volumes = [] diff_im = np.zeros( img_ref.shape ) for ref_comp, tst_comp, diff_comp in zip( img_ref, img_tst, diff_im ): num = np.minimum( ref_comp, tst_comp ) ddr = np.maximum( ref_comp, tst_comp ) diff_comp[ddr>0]+= 1.0-(num[ddr>0]/ddr[ddr>0]) self._jaccards.append( np.sum( num ) / np.sum( ddr ) ) volumes.append( np.sum( ref_comp ) ) self._dices = 2.0*np.array(self._jaccards) / (np.array(self._jaccards) +1.0 ) if self.inputs.weighting != "none": weights = 1.0 / np.array(volumes) if self.inputs.weighting == "squared_vol": weights = weights**2 weights = weights / np.sum( weights ) setattr( self, '_jaccard', np.sum( weights * self._jaccards ) ) setattr( self, '_dice', np.sum( weights * self._dices ) ) diff = np.zeros( diff_im[0].shape ) for w,ch in zip(weights,diff_im): ch[msk==0] = 0 diff+= w* ch nb.save(nb.Nifti1Image(diff, nb.load( self.inputs.in_ref[0]).get_affine(), nb.load(self.inputs.in_ref[0]).get_header()), self.inputs.out_file) return runtime def _list_outputs(self): outputs = self._outputs().get() for method in ("dice", "jaccard"): outputs[method] = getattr(self, '_' + method) #outputs['volume_difference'] = self._volume outputs['diff_file'] = os.path.abspath(self.inputs.out_file) outputs['class_fji'] = np.array(self._jaccards).astype(float).tolist(); outputs['class_fdi']= self._dices.astype(float).tolist(); return outputs class ErrorMapInputSpec(BaseInterfaceInputSpec): in_ref = File(exists=True, mandatory=True, desc="Reference image. Requires the same dimensions as in_tst.") in_tst = File(exists=True, mandatory=True, desc="Test image. Requires the same dimensions as in_ref.") mask = File(exists=True, desc="calculate overlap only within this mask.") metric = traits.Enum("sqeuclidean", "euclidean", desc='error map metric (as implemented in scipy cdist)', usedefault=True, mandatory=True) out_map = File(desc="Name for the output file") class ErrorMapOutputSpec(TraitedSpec): out_map = File(exists=True, desc="resulting error map") distance = traits.Float(desc="Average distance between volume 1 and 2") class ErrorMap(BaseInterface): """ Calculates the error (distance) map between two input volumes. Example ------- >>> errormap = ErrorMap() >>> errormap.inputs.in_ref = 'cont1.nii' >>> errormap.inputs.in_tst = 'cont2.nii' >>> res = errormap.run() # doctest: +SKIP """ input_spec = ErrorMapInputSpec output_spec = ErrorMapOutputSpec _out_file = '' def _run_interface(self, runtime): # Get two numpy data matrices nii_ref = nb.load(self.inputs.in_ref) ref_data = np.squeeze(nii_ref.get_data()) tst_data = np.squeeze(nb.load(self.inputs.in_tst).get_data()) assert(ref_data.ndim == tst_data.ndim) # Load mask comps = 1 mapshape = ref_data.shape if (ref_data.ndim == 4): comps = ref_data.shape[-1] mapshape = ref_data.shape[:-1] if isdefined(self.inputs.mask): msk = nb.load( self.inputs.mask ).get_data() if (mapshape != msk.shape): raise RuntimeError("Mask should match volume shape, \ mask is %s and volumes are %s" % (list(msk.shape), list(mapshape))) else: msk = np.ones(shape=mapshape) # Flatten both volumes and make the pixel differennce mskvector = msk.reshape(-1) msk_idxs = np.where(mskvector==1) refvector = ref_data.reshape(-1,comps)[msk_idxs].astype(np.float32) tstvector = tst_data.reshape(-1,comps)[msk_idxs].astype(np.float32) diffvector = (refvector-tstvector) # Scale the difference if self.inputs.metric == 'sqeuclidean': errvector = diffvector**2 if (comps > 1): errvector = np.sum(errvector, axis=1) else: errvector = np.squeeze(errvector) elif self.inputs.metric == 'euclidean': errvector = np.linalg.norm(diffvector, axis=1) errvectorexp = np.zeros_like(mskvector, dtype=np.float32) # The default type is uint8 errvectorexp[msk_idxs] = errvector # Get averaged error self._distance = np.average(errvector) # Only average the masked voxels errmap = errvectorexp.reshape(mapshape) hdr = nii_ref.get_header().copy() hdr.set_data_dtype(np.float32) hdr['data_type'] = 16 hdr.set_data_shape(mapshape) if not isdefined(self.inputs.out_map): fname,ext = op.splitext(op.basename(self.inputs.in_tst)) if ext=='.gz': fname,ext2 = op.splitext(fname) ext = ext2 + ext self._out_file = op.abspath(fname + "_errmap" + ext) else: self._out_file = self.inputs.out_map nb.Nifti1Image(errmap.astype(np.float32), nii_ref.get_affine(), hdr).to_filename(self._out_file) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['out_map'] = self._out_file outputs['distance'] = self._distance return outputs class SimilarityInputSpec(BaseInterfaceInputSpec): volume1 = File(exists=True, desc="3D/4D volume", mandatory=True) volume2 = File(exists=True, desc="3D/4D volume", mandatory=True) mask1 = File(exists=True, desc="3D volume") mask2 = File(exists=True, desc="3D volume") metric = traits.Either(traits.Enum('cc', 'cr', 'crl1', 'mi', 'nmi', 'slr'), traits.Callable(), desc="""str or callable Cost-function for assessing image similarity. If a string, one of 'cc': correlation coefficient, 'cr': correlation ratio, 'crl1': L1-norm based correlation ratio, 'mi': mutual information, 'nmi': normalized mutual information, 'slr': supervised log-likelihood ratio. If a callable, it should take a two-dimensional array representing the image joint histogram as an input and return a float.""", usedefault=True) class SimilarityOutputSpec(TraitedSpec): similarity = traits.List( traits.Float(desc="Similarity between volume 1 and 2, frame by frame")) class Similarity(BaseInterface): """Calculates similarity between two 3D or 4D volumes. Both volumes have to be in the same coordinate system, same space within that coordinate system and with the same voxel dimensions. .. note:: This interface is an extension of :py:class:`nipype.interfaces.nipy.utils.Similarity` to support 4D files. Requires :py:mod:`nipy` Example ------- >>> from nipype.algorithms.metrics import Similarity >>> similarity = Similarity() >>> similarity.inputs.volume1 = 'rc1s1.nii' >>> similarity.inputs.volume2 = 'rc1s2.nii' >>> similarity.inputs.mask1 = 'mask.nii' >>> similarity.inputs.mask2 = 'mask.nii' >>> similarity.inputs.metric = 'cr' >>> res = similarity.run() # doctest: +SKIP """ input_spec = SimilarityInputSpec output_spec = SimilarityOutputSpec _have_nipy = True def __init__(self, **inputs): try: package_check('nipy') except Exception, e: self._have_nipy = False super(Similarity,self).__init__(**inputs) def _run_interface(self, runtime): if not self._have_nipy: raise RuntimeError('nipy is not installed') from nipy.algorithms.registration.histogram_registration import HistogramRegistration from nipy.algorithms.registration.affine import Affine vol1_nii = nb.load(self.inputs.volume1) vol2_nii = nb.load(self.inputs.volume2) dims = vol1_nii.get_data().ndim if dims==3 or dims==2: vols1 = [ vol1_nii ] vols2 = [ vol2_nii ] if dims==4: vols1 = nb.four_to_three( vol1_nii ) vols2 = nb.four_to_three( vol2_nii ) if dims<2 or dims>4: raise RuntimeError( 'Image dimensions not supported (detected %dD file)' % dims ) if isdefined(self.inputs.mask1): mask1 = nb.load(self.inputs.mask1).get_data() == 1 else: mask1 = None if isdefined(self.inputs.mask2): mask2 = nb.load(self.inputs.mask2).get_data() == 1 else: mask2 = None self._similarity = [] for ts1,ts2 in zip( vols1, vols2 ): histreg = HistogramRegistration(from_img = ts1, to_img = ts2, similarity=self.inputs.metric, from_mask = mask1, to_mask = mask2) self._similarity.append( histreg.eval(Affine()) ) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['similarity'] = self._similarity return outputs nipype-0.11.0/nipype/algorithms/misc.py000066400000000000000000001441051257611314500200710ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: ''' Miscellaneous algorithms Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__)) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) ''' import os import os.path as op import nibabel as nb import numpy as np from math import floor, ceil from scipy.ndimage.morphology import grey_dilation from scipy.ndimage.morphology import binary_erosion from scipy.spatial.distance import cdist, euclidean, dice, jaccard from scipy.ndimage.measurements import center_of_mass, label from scipy.special import legendre import scipy.io as sio import itertools import scipy.stats as stats from nipype import logging import warnings import metrics as nam from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File, InputMultiPath, OutputMultiPath, BaseInterfaceInputSpec, isdefined, DynamicTraitedSpec, Undefined) from nipype.utils.filemanip import fname_presuffix, split_filename iflogger = logging.getLogger('interface') class PickAtlasInputSpec(BaseInterfaceInputSpec): atlas = File(exists=True, desc="Location of the atlas that will be used.", mandatory=True) labels = traits.Either( traits.Int, traits.List(traits.Int), desc=("Labels of regions that will be included in the mask. Must be\ compatible with the atlas used."), mandatory=True ) hemi = traits.Enum( 'both', 'left', 'right', desc="Restrict the mask to only one hemisphere: left or right", usedefault=True ) dilation_size = traits.Int( usedefault=True, desc="Defines how much the mask will be dilated (expanded in 3D)." ) output_file = File(desc="Where to store the output mask.") class PickAtlasOutputSpec(TraitedSpec): mask_file = File(exists=True, desc="output mask file") class PickAtlas(BaseInterface): """Returns ROI masks given an atlas and a list of labels. Supports dilation and left right masking (assuming the atlas is properly aligned). """ input_spec = PickAtlasInputSpec output_spec = PickAtlasOutputSpec def _run_interface(self, runtime): nim = self._get_brodmann_area() nb.save(nim, self._gen_output_filename()) return runtime def _gen_output_filename(self): if not isdefined(self.inputs.output_file): output = fname_presuffix(fname=self.inputs.atlas, suffix="_mask", newpath=os.getcwd(), use_ext=True) else: output = os.path.realpath(self.inputs.output_file) return output def _get_brodmann_area(self): nii = nb.load(self.inputs.atlas) origdata = nii.get_data() newdata = np.zeros(origdata.shape) if not isinstance(self.inputs.labels, list): labels = [self.inputs.labels] else: labels = self.inputs.labels for lab in labels: newdata[origdata == lab] = 1 if self.inputs.hemi == 'right': newdata[floor(float(origdata.shape[0]) / 2):, :, :] = 0 elif self.inputs.hemi == 'left': newdata[:ceil(float(origdata.shape[0]) / 2), :, :] = 0 if self.inputs.dilation_size != 0: newdata = grey_dilation( newdata, (2 * self.inputs.dilation_size + 1, 2 * self.inputs.dilation_size + 1, 2 * self.inputs.dilation_size + 1)) return nb.Nifti1Image(newdata, nii.get_affine(), nii.get_header()) def _list_outputs(self): outputs = self._outputs().get() outputs['mask_file'] = self._gen_output_filename() return outputs class SimpleThresholdInputSpec(BaseInterfaceInputSpec): volumes = InputMultiPath( File(exists=True), desc='volumes to be thresholded', mandatory=True) threshold = traits.Float( desc='volumes to be thresholdedeverything below this value will be set\ to zero', mandatory=True ) class SimpleThresholdOutputSpec(TraitedSpec): thresholded_volumes = OutputMultiPath( File(exists=True), desc="thresholded volumes") class SimpleThreshold(BaseInterface): """Applies a threshold to input volumes """ input_spec = SimpleThresholdInputSpec output_spec = SimpleThresholdOutputSpec def _run_interface(self, runtime): for fname in self.inputs.volumes: img = nb.load(fname) data = np.array(img.get_data()) active_map = data > self.inputs.threshold thresholded_map = np.zeros(data.shape) thresholded_map[active_map] = data[active_map] new_img = nb.Nifti1Image( thresholded_map, img.get_affine(), img.get_header()) _, base, _ = split_filename(fname) nb.save(new_img, base + '_thresholded.nii') return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["thresholded_volumes"] = [] for fname in self.inputs.volumes: _, base, _ = split_filename(fname) outputs["thresholded_volumes"].append( os.path.abspath(base + '_thresholded.nii')) return outputs class ModifyAffineInputSpec(BaseInterfaceInputSpec): volumes = InputMultiPath( File(exists=True), desc='volumes which affine matrices will be modified', mandatory=True ) transformation_matrix = traits.Array( value=np.eye(4), shape=(4, 4), desc="transformation matrix that will be left multiplied by the\ affine matrix", usedefault=True ) class ModifyAffineOutputSpec(TraitedSpec): transformed_volumes = OutputMultiPath(File(exist=True)) class ModifyAffine(BaseInterface): """Left multiplies the affine matrix with a specified values. Saves the volume as a nifti file. """ input_spec = ModifyAffineInputSpec output_spec = ModifyAffineOutputSpec def _gen_output_filename(self, name): _, base, _ = split_filename(name) return os.path.abspath(base + "_transformed.nii") def _run_interface(self, runtime): for fname in self.inputs.volumes: img = nb.load(fname) affine = img.get_affine() affine = np.dot(self.inputs.transformation_matrix, affine) nb.save(nb.Nifti1Image(img.get_data(), affine, img.get_header()), self._gen_output_filename(fname)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['transformed_volumes'] = [] for fname in self.inputs.volumes: outputs['transformed_volumes'].append( self._gen_output_filename(fname)) return outputs class CreateNiftiInputSpec(BaseInterfaceInputSpec): data_file = File(exists=True, mandatory=True, desc="ANALYZE img file") header_file = File( exists=True, mandatory=True, desc="corresponding ANALYZE hdr file") affine = traits.Array(desc="affine transformation array") class CreateNiftiOutputSpec(TraitedSpec): nifti_file = File(exists=True) class CreateNifti(BaseInterface): """Creates a nifti volume """ input_spec = CreateNiftiInputSpec output_spec = CreateNiftiOutputSpec def _gen_output_file_name(self): _, base, _ = split_filename(self.inputs.data_file) return os.path.abspath(base + ".nii") def _run_interface(self, runtime): hdr = nb.AnalyzeHeader.from_fileobj( open(self.inputs.header_file, 'rb')) if isdefined(self.inputs.affine): affine = self.inputs.affine else: affine = None data = hdr.data_from_fileobj(open(self.inputs.data_file, 'rb')) img = nb.Nifti1Image(data, affine, hdr) nb.save(img, self._gen_output_file_name()) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['nifti_file'] = self._gen_output_file_name() return outputs class TSNRInputSpec(BaseInterfaceInputSpec): in_file = InputMultiPath(File(exists=True), mandatory=True, desc='realigned 4D file or a list of 3D files') regress_poly = traits.Range(low=1, desc='Remove polynomials') class TSNROutputSpec(TraitedSpec): tsnr_file = File(exists=True, desc='tsnr image file') mean_file = File(exists=True, desc='mean image file') stddev_file = File(exists=True, desc='std dev image file') detrended_file = File(desc='detrended input file') class TSNR(BaseInterface): """Computes the time-course SNR for a time series Typically you want to run this on a realigned time-series. Example ------- >>> tsnr = TSNR() >>> tsnr.inputs.in_file = 'functional.nii' >>> res = tsnr.run() # doctest: +SKIP """ input_spec = TSNRInputSpec output_spec = TSNROutputSpec def _gen_output_file_name(self, suffix=None): _, base, ext = split_filename(self.inputs.in_file[0]) if suffix in ['mean', 'stddev']: return os.path.abspath(base + "_tsnr_" + suffix + ext) elif suffix in ['detrended']: return os.path.abspath(base + "_" + suffix + ext) else: return os.path.abspath(base + "_tsnr" + ext) def _run_interface(self, runtime): img = nb.load(self.inputs.in_file[0]) header = img.get_header().copy() vollist = [nb.load(filename) for filename in self.inputs.in_file] data = np.concatenate([vol.get_data().reshape( vol.get_shape()[:3] + (-1,)) for vol in vollist], axis=3) if data.dtype.kind == 'i': header.set_data_dtype(np.float32) data = data.astype(np.float32) if isdefined(self.inputs.regress_poly): timepoints = img.get_shape()[-1] X = np.ones((timepoints, 1)) for i in range(self.inputs.regress_poly): X = np.hstack((X, legendre( i + 1)(np.linspace(-1, 1, timepoints))[:, None])) betas = np.dot(np.linalg.pinv(X), np.rollaxis(data, 3, 2)) datahat = np.rollaxis(np.dot(X[:, 1:], np.rollaxis( betas[1:, :, :, :], 0, 3)), 0, 4) data = data - datahat img = nb.Nifti1Image(data, img.get_affine(), header) nb.save(img, self._gen_output_file_name('detrended')) meanimg = np.mean(data, axis=3) stddevimg = np.std(data, axis=3) tsnr = meanimg / stddevimg img = nb.Nifti1Image(tsnr, img.get_affine(), header) nb.save(img, self._gen_output_file_name()) img = nb.Nifti1Image(meanimg, img.get_affine(), header) nb.save(img, self._gen_output_file_name('mean')) img = nb.Nifti1Image(stddevimg, img.get_affine(), header) nb.save(img, self._gen_output_file_name('stddev')) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['tsnr_file'] = self._gen_output_file_name() outputs['mean_file'] = self._gen_output_file_name('mean') outputs['stddev_file'] = self._gen_output_file_name('stddev') if isdefined(self.inputs.regress_poly): outputs['detrended_file'] = self._gen_output_file_name('detrended') return outputs class GunzipInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True) class GunzipOutputSpec(TraitedSpec): out_file = File(exists=True) class Gunzip(BaseInterface): """Gunzip wrapper """ input_spec = GunzipInputSpec output_spec = GunzipOutputSpec def _gen_output_file_name(self): _, base, ext = split_filename(self.inputs.in_file) if ext[-2:].lower() == ".gz": ext = ext[:-3] return os.path.abspath(base + ext[:-3]) def _run_interface(self, runtime): import gzip in_file = gzip.open(self.inputs.in_file, 'rb') out_file = open(self._gen_output_file_name(), 'wb') out_file.write(in_file.read()) out_file.close() in_file.close() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = self._gen_output_file_name() return outputs def replaceext(in_list, ext): out_list = list() for filename in in_list: path, name, _ = split_filename(op.abspath(filename)) out_name = op.join(path, name) + ext out_list.append(out_name) return out_list def matlab2csv(in_array, name, reshape): output_array = np.asarray(in_array) if reshape: if len(np.shape(output_array)) > 1: output_array = np.reshape(output_array, ( np.shape(output_array)[0]*np.shape(output_array)[1], 1)) iflogger.info(np.shape(output_array)) output_name = op.abspath(name + '.csv') np.savetxt(output_name, output_array, delimiter=',') return output_name class Matlab2CSVInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='Input MATLAB .mat file') reshape_matrix = traits.Bool( True, usedefault=True, desc='The output of this interface is meant for R, so matrices will be\ reshaped to vectors by default.' ) class Matlab2CSVOutputSpec(TraitedSpec): csv_files = OutputMultiPath( File(desc='Output CSV files for each variable saved in the input .mat\ file') ) class Matlab2CSV(BaseInterface): """Simple interface to save the components of a MATLAB .mat file as a text file with comma-separated values (CSVs). CSV files are easily loaded in R, for use in statistical processing. For further information, see cran.r-project.org/doc/manuals/R-data.pdf Example ------- >>> from nipype.algorithms import misc >>> mat2csv = misc.Matlab2CSV() >>> mat2csv.inputs.in_file = 'cmatrix.mat' >>> mat2csv.run() # doctest: +SKIP """ input_spec = Matlab2CSVInputSpec output_spec = Matlab2CSVOutputSpec def _run_interface(self, runtime): in_dict = sio.loadmat(op.abspath(self.inputs.in_file)) # Check if the file has multiple variables in it. If it does, loop # through them and save them as individual CSV files. # If not, save the variable as a single CSV file using the input file # name and a .csv extension. saved_variables = list() for key in in_dict.keys(): if not key.startswith('__'): if isinstance(in_dict[key][0], np.ndarray): saved_variables.append(key) else: iflogger.info('One of the keys in the input file, {k}, is not a Numpy array'.format(k=key)) if len(saved_variables) > 1: iflogger.info( '{N} variables found:'.format(N=len(saved_variables))) iflogger.info(saved_variables) for variable in saved_variables: iflogger.info( '...Converting {var} - type {ty} - to\ CSV'.format(var=variable, ty=type(in_dict[variable])) ) matlab2csv( in_dict[variable], variable, self.inputs.reshape_matrix) elif len(saved_variables) == 1: _, name, _ = split_filename(self.inputs.in_file) variable = saved_variables[0] iflogger.info('Single variable found {var}, type {ty}:'.format( var=variable, ty=type(in_dict[variable]))) iflogger.info('...Converting {var} to CSV from {f}'.format( var=variable, f=self.inputs.in_file)) matlab2csv(in_dict[variable], name, self.inputs.reshape_matrix) else: iflogger.error('No values in the MATLAB file?!') return runtime def _list_outputs(self): outputs = self.output_spec().get() in_dict = sio.loadmat(op.abspath(self.inputs.in_file)) saved_variables = list() for key in in_dict.keys(): if not key.startswith('__'): if isinstance(in_dict[key][0], np.ndarray): saved_variables.append(key) else: iflogger.error('One of the keys in the input file, {k}, is\ not a Numpy array'.format(k=key)) if len(saved_variables) > 1: outputs['csv_files'] = replaceext(saved_variables, '.csv') elif len(saved_variables) == 1: _, name, ext = split_filename(self.inputs.in_file) outputs['csv_files'] = op.abspath(name + '.csv') else: iflogger.error('No values in the MATLAB file?!') return outputs def merge_csvs(in_list): for idx, in_file in enumerate(in_list): try: in_array = np.loadtxt(in_file, delimiter=',') except ValueError, ex: try: in_array = np.loadtxt(in_file, delimiter=',', skiprows=1) except ValueError, ex: first = open(in_file, 'r') header_line = first.readline() header_list = header_line.split(',') n_cols = len(header_list) try: in_array = np.loadtxt( in_file, delimiter=',', skiprows=1, usecols=range(1, n_cols) ) except ValueError, ex: in_array = np.loadtxt( in_file, delimiter=',', skiprows=1, usecols=range(1, n_cols-1)) if idx == 0: out_array = in_array else: out_array = np.dstack((out_array, in_array)) out_array = np.squeeze(out_array) iflogger.info('Final output array shape:') iflogger.info(np.shape(out_array)) return out_array def remove_identical_paths(in_files): import os.path as op from nipype.utils.filemanip import split_filename if len(in_files) > 1: out_names = list() commonprefix = op.commonprefix(in_files) lastslash = commonprefix.rfind('/') commonpath = commonprefix[0:(lastslash+1)] for fileidx, in_file in enumerate(in_files): path, name, ext = split_filename(in_file) in_file = op.join(path, name) name = in_file.replace(commonpath, '') name = name.replace('_subject_id_', '') out_names.append(name) else: path, name, ext = split_filename(in_files[0]) out_names = [name] return out_names def maketypelist(rowheadings, shape, extraheadingBool, extraheading): typelist = [] if rowheadings: typelist.append(('heading', 'a40')) if len(shape) > 1: for idx in range(1, (min(shape)+1)): typelist.append((str(idx), float)) else: for idx in range(1, (shape[0]+1)): typelist.append((str(idx), float)) if extraheadingBool: typelist.append((extraheading, 'a40')) iflogger.info(typelist) return typelist def makefmtlist(output_array, typelist, rowheadingsBool, shape, extraheadingBool): fmtlist = [] if rowheadingsBool: fmtlist.append('%s') if len(shape) > 1: output = np.zeros(max(shape), typelist) for idx in range(1, min(shape)+1): output[str(idx)] = output_array[:, idx-1] fmtlist.append('%f') else: output = np.zeros(1, typelist) for idx in range(1, len(output_array)+1): output[str(idx)] = output_array[idx-1] fmtlist.append('%f') if extraheadingBool: fmtlist.append('%s') fmt = ','.join(fmtlist) return fmt, output class MergeCSVFilesInputSpec(TraitedSpec): in_files = InputMultiPath(File(exists=True), mandatory=True, desc='Input comma-separated value (CSV) files') out_file = File('merged.csv', usedefault=True, desc='Output filename for merged CSV file') column_headings = traits.List( traits.Str, desc='List of column headings to save in merged CSV file\ (must be equal to number of input files). If left undefined, these\ will be pulled from the input filenames.') row_headings = traits.List( traits.Str, desc='List of row headings to save in merged CSV file\ (must be equal to number of rows in the input files).') row_heading_title = traits.Str( 'label', usedefault=True, desc='Column heading for the row headings\ added') extra_column_heading = traits.Str( desc='New heading to add for the added field.') extra_field = traits.Str( desc='New field to add to each row. This is useful for saving the\ group or subject ID in the file.') class MergeCSVFilesOutputSpec(TraitedSpec): csv_file = File(desc='Output CSV file containing columns ') class MergeCSVFiles(BaseInterface): """This interface is designed to facilitate data loading in the R environment. It takes input CSV files and merges them into a single CSV file. If provided, it will also incorporate column heading names into the resulting CSV file. CSV files are easily loaded in R, for use in statistical processing. For further information, see cran.r-project.org/doc/manuals/R-data.pdf Example ------- >>> from nipype.algorithms import misc >>> mat2csv = misc.MergeCSVFiles() >>> mat2csv.inputs.in_files = ['degree.mat','clustering.mat'] >>> mat2csv.inputs.column_headings = ['degree','clustering'] >>> mat2csv.run() # doctest: +SKIP """ input_spec = MergeCSVFilesInputSpec output_spec = MergeCSVFilesOutputSpec def _run_interface(self, runtime): extraheadingBool = False extraheading = '' rowheadingsBool = False """ This block defines the column headings. """ if isdefined(self.inputs.column_headings): iflogger.info('Column headings have been provided:') headings = self.inputs.column_headings else: iflogger.info( 'Column headings not provided! Pulled from input filenames:') headings = remove_identical_paths(self.inputs.in_files) if isdefined(self.inputs.extra_field): if isdefined(self.inputs.extra_column_heading): extraheading = self.inputs.extra_column_heading iflogger.info('Extra column heading provided: {col}'.format( col=extraheading)) else: extraheading = 'type' iflogger.info( 'Extra column heading was not defined. Using "type"') headings.append(extraheading) extraheadingBool = True if len(self.inputs.in_files) == 1: iflogger.warn('Only one file input!') if isdefined(self.inputs.row_headings): iflogger.info('Row headings have been provided. Adding "labels"\ column header.') prefix = '"{p}","'.format(p=self.inputs.row_heading_title) csv_headings = prefix + '","'.join(itertools.chain( headings)) + '"\n' rowheadingsBool = True else: iflogger.info('Row headings have not been provided.') csv_headings = '"' + '","'.join(itertools.chain(headings)) + '"\n' iflogger.info('Final Headings:') iflogger.info(csv_headings) """ Next we merge the arrays and define the output text file """ output_array = merge_csvs(self.inputs.in_files) _, name, ext = split_filename(self.inputs.out_file) if not ext == '.csv': ext = '.csv' out_file = op.abspath(name + ext) file_handle = open(out_file, 'w') file_handle.write(csv_headings) shape = np.shape(output_array) typelist = maketypelist( rowheadingsBool, shape, extraheadingBool, extraheading) fmt, output = makefmtlist( output_array, typelist, rowheadingsBool, shape, extraheadingBool) if rowheadingsBool: row_heading_list = self.inputs.row_headings row_heading_list_with_quotes = [] for row_heading in row_heading_list: row_heading_with_quotes = '"' + row_heading + '"' row_heading_list_with_quotes.append(row_heading_with_quotes) row_headings = np.array(row_heading_list_with_quotes, dtype='|S40') output['heading'] = row_headings if isdefined(self.inputs.extra_field): extrafieldlist = [] if len(shape) > 1: mx = shape[0] else: mx = 1 for idx in range(0, mx): extrafieldlist.append(self.inputs.extra_field) iflogger.info(len(extrafieldlist)) output[extraheading] = extrafieldlist iflogger.info(output) iflogger.info(fmt) np.savetxt(file_handle, output, fmt, delimiter=',') file_handle.close() return runtime def _list_outputs(self): outputs = self.output_spec().get() _, name, ext = split_filename(self.inputs.out_file) if not ext == '.csv': ext = '.csv' out_file = op.abspath(name + ext) outputs['csv_file'] = out_file return outputs class AddCSVColumnInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='Input comma-separated value (CSV) files') out_file = File('extra_heading.csv', usedefault=True, desc='Output filename for merged CSV file') extra_column_heading = traits.Str( desc='New heading to add for the added field.') extra_field = traits.Str( desc='New field to add to each row. This is useful for saving the\ group or subject ID in the file.') class AddCSVColumnOutputSpec(TraitedSpec): csv_file = File(desc='Output CSV file containing columns ') class AddCSVColumn(BaseInterface): """Short interface to add an extra column and field to a text file Example ------- >>> from nipype.algorithms import misc >>> addcol = misc.AddCSVColumn() >>> addcol.inputs.in_file = 'degree.csv' >>> addcol.inputs.extra_column_heading = 'group' >>> addcol.inputs.extra_field = 'male' >>> addcol.run() # doctest: +SKIP """ input_spec = AddCSVColumnInputSpec output_spec = AddCSVColumnOutputSpec def _run_interface(self, runtime): in_file = open(self.inputs.in_file, 'r') _, name, ext = split_filename(self.inputs.out_file) if not ext == '.csv': ext = '.csv' out_file = op.abspath(name + ext) out_file = open(out_file, 'w') firstline = in_file.readline() firstline = firstline.replace('\n', '') new_firstline = firstline + ',"' + \ self.inputs.extra_column_heading + '"\n' out_file.write(new_firstline) for line in in_file: new_line = line.replace('\n', '') new_line = new_line + ',' + self.inputs.extra_field + '\n' out_file.write(new_line) return runtime def _list_outputs(self): outputs = self.output_spec().get() _, name, ext = split_filename(self.inputs.out_file) if not ext == '.csv': ext = '.csv' out_file = op.abspath(name + ext) outputs['csv_file'] = out_file return outputs class AddCSVRowInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): in_file = traits.File(mandatory=True, desc='Input comma-separated value (CSV) files') _outputs = traits.Dict(traits.Any, value={}, usedefault=True) def __setattr__(self, key, value): if key not in self.copyable_trait_names(): if not isdefined(value): super(AddCSVRowInputSpec, self).__setattr__(key, value) self._outputs[key] = value else: if key in self._outputs: self._outputs[key] = value super(AddCSVRowInputSpec, self).__setattr__(key, value) class AddCSVRowOutputSpec(TraitedSpec): csv_file = File(desc='Output CSV file containing rows ') class AddCSVRow(BaseInterface): """Simple interface to add an extra row to a csv file .. note:: Requires `pandas `_ .. warning:: Multi-platform thread-safe execution is possible with `lockfile `_. Please recall that (1) this module is alpha software; and (2) it should be installed for thread-safe writing. If lockfile is not installed, then the interface is not thread-safe. Example ------- >>> from nipype.algorithms import misc >>> addrow = misc.AddCSVRow() >>> addrow.inputs.in_file = 'scores.csv' >>> addrow.inputs.si = 0.74 >>> addrow.inputs.di = 0.93 >>> addrow.inputs.subject_id = 'S400' >>> addrow.inputs.list_of_values = [ 0.4, 0.7, 0.3 ] >>> addrow.run() # doctest: +SKIP """ input_spec = AddCSVRowInputSpec output_spec = AddCSVRowOutputSpec def __init__(self, infields=None, force_run=True, **kwargs): super(AddCSVRow, self).__init__(**kwargs) undefined_traits = {} self._infields = infields self._have_lock = False self._lock = None if infields: for key in infields: self.inputs.add_trait(key, traits.Any) self.inputs._outputs[key] = Undefined undefined_traits[key] = Undefined self.inputs.trait_set(trait_change_notify=False, **undefined_traits) if force_run: self._always_run = True def _run_interface(self, runtime): try: import pandas as pd except ImportError: raise ImportError(('This interface requires pandas ' '(http://pandas.pydata.org/) to run.')) try: import lockfile as pl self._have_lock = True except ImportError: from warnings import warn warn(('Python module lockfile was not found: AddCSVRow will not be' ' thread-safe in multi-processor execution')) input_dict = {} for key, val in self.inputs._outputs.items(): # expand lists to several columns if key == 'trait_added' and val in self.inputs.copyable_trait_names(): continue if isinstance(val, list): for i, v in enumerate(val): input_dict['%s_%d' % (key, i)] = v else: input_dict[key] = val df = pd.DataFrame([input_dict]) if self._have_lock: self._lock = pl.FileLock(self.inputs.in_file) # Acquire lock self._lock.acquire() if op.exists(self.inputs.in_file): formerdf = pd.read_csv(self.inputs.in_file, index_col=0) df = pd.concat([formerdf, df], ignore_index=True) with open(self.inputs.in_file, 'w') as f: df.to_csv(f) if self._have_lock: self._lock.release() # Using nipype.external.portalocker this might be something like: # with pl.Lock(self.inputs.in_file, timeout=1) as fh: # if op.exists(fh): # formerdf = pd.read_csv(fh, index_col=0) # df = pd.concat([formerdf, df], ignore_index=True) # df.to_csv(fh) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['csv_file'] = self.inputs.in_file return outputs def _outputs(self): return self._add_output_traits(super(AddCSVRow, self)._outputs()) def _add_output_traits(self, base): return base class CalculateNormalizedMomentsInputSpec(TraitedSpec): timeseries_file = File( exists=True, mandatory=True, desc='Text file with timeseries in columns and timepoints in rows,\ whitespace separated') moment = traits.Int( mandatory=True, desc="Define which moment should be calculated, 3 for skewness, 4 for\ kurtosis.") class CalculateNormalizedMomentsOutputSpec(TraitedSpec): moments = traits.List(traits.Float(), desc='Moments') class CalculateNormalizedMoments(BaseInterface): """Calculates moments of timeseries. Example ------- >>> from nipype.algorithms import misc >>> skew = misc.CalculateNormalizedMoments() >>> skew.inputs.moment = 3 >>> skew.inputs.timeseries_file = 'timeseries.txt' >>> skew.run() # doctest: +SKIP """ input_spec = CalculateNormalizedMomentsInputSpec output_spec = CalculateNormalizedMomentsOutputSpec def _run_interface(self, runtime): self._moments = calc_moments( self.inputs.timeseries_file, self.inputs.moment) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['skewness'] = self._moments return outputs def calc_moments(timeseries_file, moment): """Returns nth moment (3 for skewness, 4 for kurtosis) of timeseries (list of values; one per timeseries). Keyword arguments: timeseries_file -- text file with white space separated timepoints in rows """ timeseries = np.genfromtxt(timeseries_file) m2 = stats.moment(timeseries, 2, axis=0) m3 = stats.moment(timeseries, moment, axis=0) zero = (m2 == 0) return np.where(zero, 0, m3 / m2**(moment/2.0)) class AddNoiseInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='input image that will be corrupted with noise') in_mask = File(exists=True, desc=('input mask, voxels outside this mask ' 'will be considered background')) snr = traits.Float(10.0, desc='desired output SNR in dB', usedefault=True) dist = traits.Enum('normal', 'rician', usedefault=True, mandatory=True, desc=('desired noise distribution')) bg_dist = traits.Enum('normal', 'rayleigh', usedefault=True, mandatory=True, desc=('desired noise distribution, currently ' 'only normal is implemented')) out_file = File(desc='desired output filename') class AddNoiseOutputSpec(TraitedSpec): out_file = File(exists=True, desc='corrupted image') class AddNoise(BaseInterface): """ Corrupts with noise the input image Example ------- >>> from nipype.algorithms.misc import AddNoise >>> noise = AddNoise() >>> noise.inputs.in_file = 'T1.nii' >>> noise.inputs.in_mask = 'mask.nii' >>> noise.snr = 30.0 >>> noise.run() # doctest: +SKIP """ input_spec = AddNoiseInputSpec output_spec = AddNoiseOutputSpec def _run_interface(self, runtime): in_image = nb.load(self.inputs.in_file) in_data = in_image.get_data() snr = self.inputs.snr if isdefined(self.inputs.in_mask): in_mask = nb.load(self.inputs.in_mask).get_data() else: in_mask = np.ones_like(in_data) result = self.gen_noise(in_data, mask=in_mask, snr_db=snr, dist=self.inputs.dist, bg_dist=self.inputs.bg_dist) res_im = nb.Nifti1Image(result, in_image.get_affine(), in_image.get_header()) res_im.to_filename(self._gen_output_filename()) return runtime def _gen_output_filename(self): if not isdefined(self.inputs.out_file): _, base, ext = split_filename(self.inputs.in_file) out_file = os.path.abspath('%s_SNR%03.2f%s' % (base, self.inputs.snr, ext)) else: out_file = self.inputs.out_file return out_file def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self._gen_output_filename() return outputs def gen_noise(self, image, mask=None, snr_db=10.0, dist='normal', bg_dist='normal'): """ Generates a copy of an image with a certain amount of added gaussian noise (rayleigh for background in mask) """ from math import sqrt snr = sqrt(np.power(10.0, snr_db/10.0)) if mask is None: mask = np.ones_like(image) else: mask[mask > 0] = 1 mask[mask < 1] = 0 if mask.ndim < image.ndim: mask = np.rollaxis(np.array([mask]*image.shape[3]), 0, 4) signal = image[mask > 0].reshape(-1) if dist == 'normal': signal = signal - signal.mean() sigma_n = sqrt(signal.var()/snr) noise = np.random.normal(size=image.shape, scale=sigma_n) if (np.any(mask == 0)) and (bg_dist == 'rayleigh'): bg_noise = np.random.rayleigh(size=image.shape, scale=sigma_n) noise[mask == 0] = bg_noise[mask == 0] im_noise = image + noise elif dist == 'rician': sigma_n = signal.mean()/snr n_1 = np.random.normal(size=image.shape, scale=sigma_n) n_2 = np.random.normal(size=image.shape, scale=sigma_n) stde_1 = n_1/sqrt(2.0) stde_2 = n_2/sqrt(2.0) im_noise = np.sqrt((image + stde_1)**2 + (stde_2)**2) else: raise NotImplementedError(('Only normal and rician distributions ' 'are supported')) return im_noise class NormalizeProbabilityMapSetInputSpec(TraitedSpec): in_files = InputMultiPath(File(exists=True, mandatory=True, desc='The tpms to be normalized')) in_mask = File(exists=True, desc='Masked voxels must sum up 1.0, 0.0 otherwise.') class NormalizeProbabilityMapSetOutputSpec(TraitedSpec): out_files = OutputMultiPath(File(exists=True), desc="normalized maps") class NormalizeProbabilityMapSet(BaseInterface): """ Returns the input tissue probability maps (tpms, aka volume fractions) normalized to sum up 1.0 at each voxel within the mask. .. note:: Please recall this is not a spatial normalization algorithm Example ------- >>> from nipype.algorithms import misc >>> normalize = misc.NormalizeProbabilityMapSet() >>> normalize.inputs.in_files = [ 'tpm_00.nii.gz', 'tpm_01.nii.gz', \ 'tpm_02.nii.gz' ] >>> normalize.inputs.in_mask = 'tpms_msk.nii.gz' >>> normalize.run() # doctest: +SKIP """ input_spec = NormalizeProbabilityMapSetInputSpec output_spec = NormalizeProbabilityMapSetOutputSpec def _run_interface(self, runtime): mask = None if isdefined(self.inputs.in_mask): mask = self.inputs.in_mask self._out_filenames = normalize_tpms(self.inputs.in_files, mask) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['out_files'] = self._out_filenames return outputs class SplitROIsInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='file to be splitted') in_mask = File(exists=True, desc='only process files inside mask') roi_size = traits.Tuple(traits.Int, traits.Int, traits.Int, desc='desired ROI size') class SplitROIsOutputSpec(TraitedSpec): out_files = OutputMultiPath(File(exists=True), desc='the resulting ROIs') out_masks = OutputMultiPath(File(exists=True), desc='a mask indicating valid values') out_index = OutputMultiPath(File(exists=True), desc='arrays keeping original locations') class SplitROIs(BaseInterface): """ Splits a 3D image in small chunks to enable parallel processing. ROIs keep time series structure in 4D images. >>> from nipype.algorithms import misc >>> rois = misc.SplitROIs() >>> rois.inputs.in_file = 'diffusion.nii' >>> rois.inputs.in_mask = 'mask.nii' >>> rois.run() # doctest: +SKIP """ input_spec = SplitROIsInputSpec output_spec = SplitROIsOutputSpec def _run_interface(self, runtime): mask = None roisize = None self._outnames = {} if isdefined(self.inputs.in_mask): mask = self.inputs.in_mask if isdefined(self.inputs.roi_size): roisize = self.inputs.roi_size res = split_rois(self.inputs.in_file, mask, roisize) self._outnames['out_files'] = res[0] self._outnames['out_masks'] = res[1] self._outnames['out_index'] = res[2] return runtime def _list_outputs(self): outputs = self.output_spec().get() for k, v in self._outnames.iteritems(): outputs[k] = v return outputs class MergeROIsInputSpec(TraitedSpec): in_files = InputMultiPath(File(exists=True, mandatory=True, desc='files to be re-merged')) in_index = InputMultiPath(File(exists=True, mandatory=True), desc='array keeping original locations') in_reference = File(exists=True, desc='reference file') class MergeROIsOutputSpec(TraitedSpec): merged_file = File(exists=True, desc='the recomposed file') class MergeROIs(BaseInterface): """ Splits a 3D image in small chunks to enable parallel processing. ROIs keep time series structure in 4D images. Example ------- >>> from nipype.algorithms import misc >>> rois = misc.MergeROIs() >>> rois.inputs.in_files = ['roi%02d.nii' % i for i in xrange(1, 6)] >>> rois.inputs.in_reference = 'mask.nii' >>> rois.inputs.in_index = ['roi%02d_idx.npz' % i for i in xrange(1, 6)] >>> rois.run() # doctest: +SKIP """ input_spec = MergeROIsInputSpec output_spec = MergeROIsOutputSpec def _run_interface(self, runtime): res = merge_rois(self.inputs.in_files, self.inputs.in_index, self.inputs.in_reference) self._merged = res return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['merged_file'] = self._merged return outputs def normalize_tpms(in_files, in_mask=None, out_files=[]): """ Returns the input tissue probability maps (tpms, aka volume fractions) normalized to sum up 1.0 at each voxel within the mask. """ import nibabel as nib import numpy as np import os.path as op in_files = np.atleast_1d(in_files).tolist() if len(out_files) != len(in_files): for i,finname in enumerate(in_files): fname,fext = op.splitext(op.basename(finname)) if fext == '.gz': fname,fext2 = op.splitext(fname) fext = fext2 + fext out_file = op.abspath('%s_norm_%02d%s' % (fname,i,fext)) out_files+= [out_file] imgs = [nib.load(fim) for fim in in_files] if len(in_files)==1: img_data = imgs[0].get_data() img_data[img_data>0.0] = 1.0 hdr = imgs[0].get_header().copy() hdr['data_type']= 16 hdr.set_data_dtype(np.float32) nib.save(nib.Nifti1Image(img_data.astype(np.float32), imgs[0].get_affine(), hdr), out_files[0]) return out_files[0] img_data = np.array([im.get_data() for im in imgs]).astype(np.float32) #img_data[img_data>1.0] = 1.0 img_data[img_data<0.0] = 0.0 weights = np.sum(img_data, axis=0) msk = np.ones_like(imgs[0].get_data()) msk[ weights<= 0 ] = 0 if not in_mask is None: msk = nib.load(in_mask).get_data() msk[ msk<=0 ] = 0 msk[ msk>0 ] = 1 msk = np.ma.masked_equal(msk, 0) for i,out_file in enumerate(out_files): data = np.ma.masked_equal(img_data[i], 0) probmap = data / weights hdr = imgs[i].get_header().copy() hdr['data_type']= 16 hdr.set_data_dtype('float32') nib.save(nib.Nifti1Image(probmap.astype(np.float32), imgs[i].get_affine(), hdr), out_file) return out_files def split_rois(in_file, mask=None, roishape=None): """ Splits an image in ROIs for parallel processing """ import nibabel as nb import numpy as np from math import sqrt, ceil import os.path as op if roishape is None: roishape = (10, 10, 1) im = nb.load(in_file) imshape = im.get_shape() dshape = imshape[:3] nvols = imshape[-1] roisize = roishape[0] * roishape[1] * roishape[2] droishape = (roishape[0], roishape[1], roishape[2], nvols) if mask is not None: mask = nb.load(mask).get_data() mask[mask > 0] = 1 mask[mask < 1] = 0 else: mask = np.ones(dshape) mask = mask.reshape(-1).astype(np.uint8) nzels = np.nonzero(mask) els = np.sum(mask) nrois = int(ceil(els/roisize)) data = im.get_data().reshape((mask.size, -1)) data = np.squeeze(data.take(nzels, axis=0)) nvols = data.shape[-1] roidefname = op.abspath('onesmask.nii.gz') nb.Nifti1Image(np.ones(roishape, dtype=np.uint8), None, None).to_filename(roidefname) out_files = [] out_mask = [] out_idxs = [] for i in xrange(nrois): first = i * roisize last = (i+1) * roisize fill = 0 if last > els: fill = last - els last = els droi = data[first:last, ...] iname = op.abspath('roi%010d_idx' % i) out_idxs.append(iname+'.npz') np.savez(iname, (nzels[0][first:last],)) if fill > 0: droi = np.vstack((droi, np.zeros((fill, nvols), dtype=np.float32))) partialmsk = np.ones((roisize,), dtype=np.uint8) partialmsk[-fill:] = 0 partname = op.abspath('partialmask.nii.gz') nb.Nifti1Image(partialmsk.reshape(roishape), None, None).to_filename(partname) out_mask.append(partname) else: out_mask.append(roidefname) fname = op.abspath('roi%010d.nii.gz' % i) nb.Nifti1Image(droi.reshape(droishape), None, None).to_filename(fname) out_files.append(fname) return out_files, out_mask, out_idxs def merge_rois(in_files, in_idxs, in_ref, dtype=None, out_file=None): """ Re-builds an image resulting from a parallelized processing """ import nibabel as nb import numpy as np import os.path as op import subprocess as sp if out_file is None: out_file = op.abspath('merged.nii.gz') if dtype is None: dtype = np.float32 # if file is compressed, uncompress using os # to avoid memory errors if op.splitext(in_ref)[1] == '.gz': try: iflogger.info('uncompress %i' % in_ref) sp.check_call(['gunzip', in_ref], stdout=sp.PIPE, shell=True) in_ref = op.splitext(in_ref)[0] except: pass ref = nb.load(in_ref) aff = ref.get_affine() hdr = ref.get_header().copy() rsh = ref.get_shape() del ref npix = rsh[0] * rsh[1] * rsh[2] fcdata = nb.load(in_files[0]).get_data() if fcdata.ndim == 4: ndirs = fcdata.shape[-1] else: ndirs = 1 newshape = (rsh[0], rsh[1], rsh[2], ndirs) hdr.set_data_dtype(dtype) hdr.set_xyzt_units('mm', 'sec') if ndirs < 300: data = np.zeros((npix, ndirs)) for cname, iname in zip(in_files, in_idxs): f = np.load(iname) idxs = np.squeeze(f['arr_0']) cdata = nb.load(cname).get_data().reshape(-1, ndirs) nels = len(idxs) idata = (idxs, ) try: data[idata, ...] = cdata[0:nels, ...] except: print(('Consistency between indexes and chunks was ' 'lost: data=%s, chunk=%s') % (str(data.shape), str(cdata.shape))) raise hdr.set_data_shape(newshape) nb.Nifti1Image(data.reshape(newshape).astype(dtype), aff, hdr).to_filename(out_file) else: hdr.set_data_shape(rsh[:3]) nii = [] for d in xrange(ndirs): fname = op.abspath('vol%06d.nii' % d) nb.Nifti1Image(np.zeros(rsh[:3]), aff, hdr).to_filename(fname) nii.append(fname) for cname, iname in zip(in_files, in_idxs): f = np.load(iname) idxs = np.squeeze(f['arr_0']) for d, fname in enumerate(nii): data = nb.load(fname).get_data().reshape(-1) cdata = nb.load(cname).get_data().reshape(-1, ndirs)[:, d] nels = len(idxs) idata = (idxs, ) data[idata] = cdata[0:nels] nb.Nifti1Image(data.reshape(rsh[:3]), aff, hdr).to_filename(fname) imgs = [nb.load(im) for im in nii] allim = nb.concat_images(imgs) allim.to_filename(out_file) return out_file # Deprecated interfaces ------------------------------------------------------ class Distance(nam.Distance): """Calculates distance between two volumes. .. deprecated:: 0.10.0 Use :py:class:`nipype.algorithms.metrics.Distance` instead. """ def __init__(self, **inputs): super(nam.Distance, self).__init__(**inputs) warnings.warn(("This interface has been deprecated since 0.10.0," " please use nipype.algorithms.metrics.Distance"), DeprecationWarning) class Overlap(nam.Overlap): """Calculates various overlap measures between two maps. .. deprecated:: 0.10.0 Use :py:class:`nipype.algorithms.metrics.Overlap` instead. """ def __init__(self, **inputs): super(nam.Overlap, self).__init__(**inputs) warnings.warn(("This interface has been deprecated since 0.10.0," " please use nipype.algorithms.metrics.Overlap"), DeprecationWarning) class FuzzyOverlap(nam.FuzzyOverlap): """Calculates various overlap measures between two maps, using a fuzzy definition. .. deprecated:: 0.10.0 Use :py:class:`nipype.algorithms.metrics.FuzzyOverlap` instead. """ def __init__(self, **inputs): super(nam.FuzzyOverlap, self).__init__(**inputs) warnings.warn(("This interface has been deprecated since 0.10.0," " please use nipype.algorithms.metrics.FuzzyOverlap"), DeprecationWarning) nipype-0.11.0/nipype/algorithms/modelgen.py000066400000000000000000001052531257611314500207310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ The modelgen module provides classes for specifying designs for individual subject analysis of task-based fMRI experiments. In particular it also includes algorithms for generating regressors for sparse and sparse-clustered acquisition experiments. These functions include: * SpecifyModel: allows specification of sparse and non-sparse models Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from copy import deepcopy import os from nibabel import load import numpy as np from scipy.special import gammaln from nipype.interfaces.base import (BaseInterface, TraitedSpec, InputMultiPath, traits, File, Bunch, BaseInterfaceInputSpec, isdefined) from nipype.utils.filemanip import filename_to_list from .. import config, logging from nipype.external import six iflogger = logging.getLogger('interface') def gcd(a, b): """Returns the greatest common divisor of two integers uses Euclid's algorithm >>> gcd(4, 5) 1 >>> gcd(4, 8) 4 >>> gcd(22, 55) 11 """ while b > 0: a, b = b, a % b return a def spm_hrf(RT, P=None, fMRI_T=16): """ python implementation of spm_hrf see spm_hrf for implementation details % RT - scan repeat time % p - parameters of the response function (two gamma % functions) % defaults (seconds) % p(0) - delay of response (relative to onset) 6 % p(1) - delay of undershoot (relative to onset) 16 % p(2) - dispersion of response 1 % p(3) - dispersion of undershoot 1 % p(4) - ratio of response to undershoot 6 % p(5) - onset (seconds) 0 % p(6) - length of kernel (seconds) 32 % % hrf - hemodynamic response function % p - parameters of the response function the following code using scipy.stats.distributions.gamma doesn't return the same result as the spm_Gpdf function :: hrf = gamma.pdf(u, p[0]/p[2], scale=dt/p[2]) - gamma.pdf(u, p[1]/p[3], scale=dt/p[3])/p[4] >>> print spm_hrf(2) [ 0.00000000e+00 8.65660810e-02 3.74888236e-01 3.84923382e-01 2.16117316e-01 7.68695653e-02 1.62017720e-03 -3.06078117e-02 -3.73060781e-02 -3.08373716e-02 -2.05161334e-02 -1.16441637e-02 -5.82063147e-03 -2.61854250e-03 -1.07732374e-03 -4.10443522e-04 -1.46257507e-04] """ p = np.array([6, 16, 1, 1, 6, 0, 32], dtype=float) if P is not None: p[0:len(P)] = P _spm_Gpdf = lambda x, h, l: np.exp(h * np.log(l) + (h - 1) * np.log(x) - (l * x) - gammaln(h)) # modelled hemodynamic response function - {mixture of Gammas} dt = RT / float(fMRI_T) u = np.arange(0, int(p[6] / dt + 1)) - p[5] / dt hrf = _spm_Gpdf(u, p[0] / p[2], dt / p[2]) - _spm_Gpdf(u, p[1] / p[3], dt / p[3]) / p[4] idx = np.arange(0, int((p[6] / RT) + 1)) * fMRI_T hrf = hrf[idx] hrf = hrf / np.sum(hrf) return hrf def orth(x_in, y_in): """Orthoganlize y_in with respect to x_in >>> orth_expected = np.array([1.7142857142857144, 0.42857142857142883, \ -0.85714285714285676]) >>> err = np.abs(np.array(orth([1, 2, 3],[4, 5, 6]) - orth_expected)) >>> all(err < np.finfo(float).eps) True """ x = np.array(x_in)[:, None] y = np.array(y_in)[:, None] y = y - np.dot(x, np.dot(np.linalg.inv(np.dot(x.T, x)), np.dot(x.T, y))) if np.linalg.norm(y, 1) > np.exp(-32): y = y[:, 0].tolist() else: y = y_in return y def scale_timings(timelist, input_units, output_units, time_repetition): """Scales timings given input and output units (scans/secs) Parameters ---------- timelist: list of times to scale input_units: 'secs' or 'scans' output_units: Ibid. time_repetition: float in seconds """ if input_units==output_units: _scalefactor = 1. if (input_units == 'scans') and (output_units == 'secs'): _scalefactor = time_repetition if (input_units == 'secs') and (output_units == 'scans'): _scalefactor = 1./time_repetition timelist = [np.max([0., _scalefactor * t]) for t in timelist] return timelist def gen_info(run_event_files): """Generate subject_info structure from a list of event files """ info = [] for i, event_files in enumerate(run_event_files): runinfo = Bunch(conditions=[], onsets=[], durations=[], amplitudes=[]) for event_file in event_files: _, name = os.path.split(event_file) if '.run' in name: name, _ = name.split('.run%03d' % (i+1)) elif '.txt' in name: name, _ = name.split('.txt') runinfo.conditions.append(name) event_info = np.atleast_2d(np.loadtxt(event_file)) runinfo.onsets.append(event_info[:, 0].tolist()) if event_info.shape[1] > 1: runinfo.durations.append(event_info[:, 1].tolist()) else: runinfo.durations.append([0]) if event_info.shape[1] > 2: runinfo.amplitudes.append(event_info[:, 2].tolist()) else: delattr(runinfo, 'amplitudes') info.append(runinfo) return info class SpecifyModelInputSpec(BaseInterfaceInputSpec): subject_info = InputMultiPath(Bunch, mandatory=True, xor=['subject_info', 'event_files'], desc=("Bunch or List(Bunch) subject specific condition information. " "see :ref:`SpecifyModel` or SpecifyModel.__doc__ for details")) event_files = InputMultiPath(traits.List(File(exists=True)), mandatory=True, xor=['subject_info', 'event_files'], desc=('list of event description files 1, 2 or 3 column format ' 'corresponding to onsets, durations and amplitudes')) realignment_parameters = InputMultiPath(File(exists=True), desc="Realignment parameters returned by motion correction algorithm", copyfile=False) outlier_files = InputMultiPath(File(exists=True), desc="Files containing scan outlier indices that should be tossed", copyfile=False) functional_runs = InputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), mandatory=True, desc=("Data files for model. List of 4D files or list of list of 3D " "files per session"), copyfile=False) input_units = traits.Enum('secs', 'scans', mandatory=True, desc=("Units of event onsets and durations (secs or scans). Output " "units are always in secs")) high_pass_filter_cutoff = traits.Float(mandatory=True, desc="High-pass filter cutoff in secs") time_repetition = traits.Float(mandatory=True, desc=("Time between the start of one volume to the start of " "the next image volume.")) # Not implemented yet #polynomial_order = traits.Range(0, low=0, # desc ="Number of polynomial functions to model high pass filter.") class SpecifyModelOutputSpec(TraitedSpec): session_info = traits.Any(desc="session info for level1designs") class SpecifyModel(BaseInterface): """Makes a model specification compatible with spm/fsl designers. The subject_info field should contain paradigm information in the form of a Bunch or a list of Bunch. The Bunch should contain the following information:: [Mandatory] - conditions : list of names - onsets : lists of onsets corresponding to each condition - durations : lists of durations corresponding to each condition. Should be left to a single 0 if all events are being modelled as impulses. [Optional] - regressor_names : list of str list of names corresponding to each column. Should be None if automatically assigned. - regressors : list of lists values for each regressor - must correspond to the number of volumes in the functional run - amplitudes : lists of amplitudes for each event. This will be ignored by SPM's Level1Design. The following two (tmod, pmod) will be ignored by any Level1Design class other than SPM: - tmod : lists of conditions that should be temporally modulated. Should default to None if not being used. - pmod : list of Bunch corresponding to conditions - name : name of parametric modulator - param : values of the modulator - poly : degree of modulation Alternatively, you can provide information through event files. The event files have to be in 1, 2 or 3 column format with the columns corresponding to Onsets, Durations and Amplitudes and they have to have the name event_name.runXXX... e.g.: Words.run001.txt. The event_name part will be used to create the condition names. Examples -------- >>> from nipype.interfaces.base import Bunch >>> s = SpecifyModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.high_pass_filter_cutoff = 128. >>> info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]],\ durations=[[1]]), \ Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], \ durations=[[1]])] >>> s.inputs.subject_info = info Using pmod: >>> info = [Bunch(conditions=['cond1', 'cond2'], \ onsets=[[2, 50],[100, 180]], durations=[[0],[0]], \ pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]),\ None]), \ Bunch(conditions=['cond1', 'cond2'], \ onsets=[[20, 120],[80, 160]], durations=[[0],[0]], \ pmod=[Bunch(name=['amp'], poly=[2], param=[[1, 2]]), \ None])] >>> s.inputs.subject_info = info """ input_spec = SpecifyModelInputSpec output_spec = SpecifyModelOutputSpec def _generate_standard_design(self, infolist, functional_runs=None, realignment_parameters=None, outliers=None): """ Generates a standard design matrix paradigm given information about each run """ sessinfo = [] output_units = 'secs' if 'output_units' in self.inputs.traits(): output_units = self.inputs.output_units for i, info in enumerate(infolist): sessinfo.insert(i, dict(cond=[])) if isdefined(self.inputs.high_pass_filter_cutoff): sessinfo[i]['hpf'] = \ np.float(self.inputs.high_pass_filter_cutoff) if hasattr(info, 'conditions') and info.conditions is not None: for cid, cond in enumerate(info.conditions): sessinfo[i]['cond'].insert(cid, dict()) sessinfo[i]['cond'][cid]['name'] = info.conditions[cid] scaled_onset = scale_timings(info.onsets[cid], self.inputs.input_units, output_units, self.inputs.time_repetition) sessinfo[i]['cond'][cid]['onset'] = scaled_onset scaled_duration = scale_timings(info.durations[cid], self.inputs.input_units, output_units, self.inputs.time_repetition) sessinfo[i]['cond'][cid]['duration'] = scaled_duration if hasattr(info, 'amplitudes') and info.amplitudes: sessinfo[i]['cond'][cid]['amplitudes'] = \ info.amplitudes[cid] if hasattr(info, 'tmod') and info.tmod and \ len(info.tmod) > cid: sessinfo[i]['cond'][cid]['tmod'] = info.tmod[cid] if hasattr(info, 'pmod') and info.pmod and \ len(info.pmod) > cid: if info.pmod[cid]: sessinfo[i]['cond'][cid]['pmod'] = [] for j, name in enumerate(info.pmod[cid].name): sessinfo[i]['cond'][cid]['pmod'].insert(j, {}) sessinfo[i]['cond'][cid]['pmod'][j]['name'] = \ name sessinfo[i]['cond'][cid]['pmod'][j]['poly'] = \ info.pmod[cid].poly[j] sessinfo[i]['cond'][cid]['pmod'][j]['param'] = \ info.pmod[cid].param[j] sessinfo[i]['regress']= [] if hasattr(info, 'regressors') and info.regressors is not None: for j, r in enumerate(info.regressors): sessinfo[i]['regress'].insert(j, dict(name='', val=[])) if hasattr(info, 'regressor_names') and \ info.regressor_names is not None: sessinfo[i]['regress'][j]['name'] = \ info.regressor_names[j] else: sessinfo[i]['regress'][j]['name'] = 'UR%d' % (j+1) sessinfo[i]['regress'][j]['val'] = info.regressors[j] sessinfo[i]['scans'] = functional_runs[i] if realignment_parameters is not None: for i, rp in enumerate(realignment_parameters): mc = realignment_parameters[i] for col in range(mc.shape[1]): colidx = len(sessinfo[i]['regress']) sessinfo[i]['regress'].insert(colidx, dict(name='', val=[])) sessinfo[i]['regress'][colidx]['name'] = 'Realign%d' % (col + 1) sessinfo[i]['regress'][colidx]['val'] = mc[:, col].tolist() if outliers is not None: for i, out in enumerate(outliers): numscans = 0 for f in filename_to_list(sessinfo[i]['scans']): shape = load(f).get_shape() if len(shape) == 3 or shape[3] == 1: iflogger.warning(("You are using 3D instead of 4D " "files. Are you sure this was " "intended?")) numscans += 1 else: numscans += shape[3] for j, scanno in enumerate(out): colidx = len(sessinfo[i]['regress']) sessinfo[i]['regress'].insert(colidx, dict(name='', val=[])) sessinfo[i]['regress'][colidx]['name'] = 'Outlier%d'%(j+1) sessinfo[i]['regress'][colidx]['val'] = \ np.zeros((1, numscans))[0].tolist() sessinfo[i]['regress'][colidx]['val'][int(scanno)] = 1 return sessinfo def _generate_design(self, infolist=None): """Generate design specification for a typical fmri paradigm """ realignment_parameters = [] if isdefined(self.inputs.realignment_parameters): for parfile in self.inputs.realignment_parameters: realignment_parameters.append(np.loadtxt(parfile)) outliers = [] if isdefined(self.inputs.outlier_files): for filename in self.inputs.outlier_files: try: outindices = np.loadtxt(filename, dtype=int) except IOError: outliers.append([]) else: if outindices.size == 1: outliers.append([outindices.tolist()]) else: outliers.append(outindices.tolist()) if infolist is None: if isdefined(self.inputs.subject_info): infolist = self.inputs.subject_info else: infolist = gen_info(self.inputs.event_files) self._sessinfo = self._generate_standard_design(infolist, functional_runs=self.inputs.functional_runs, realignment_parameters=realignment_parameters, outliers=outliers) def _run_interface(self, runtime): """ """ self._sessioninfo = None self._generate_design() return runtime def _list_outputs(self): outputs = self._outputs().get() if not hasattr(self, '_sessinfo'): self._generate_design() outputs['session_info'] = self._sessinfo return outputs class SpecifySPMModelInputSpec(SpecifyModelInputSpec): concatenate_runs = traits.Bool(False, usedefault=True, desc="Concatenate all runs to look like a single session.") output_units = traits.Enum('secs', 'scans', usedefault=True, desc="Units of design event onsets and durations (secs or scans)") class SpecifySPMModel(SpecifyModel): """Adds SPM specific options to SpecifyModel adds: - concatenate_runs - output_units Examples -------- >>> from nipype.interfaces.base import Bunch >>> s = SpecifySPMModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.output_units = 'scans' >>> s.inputs.high_pass_filter_cutoff = 128. >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.concatenate_runs = True >>> info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], \ durations=[[1]]), \ Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], \ durations=[[1]])] >>> s.inputs.subject_info = info """ input_spec = SpecifySPMModelInputSpec def _concatenate_info(self, infolist): nscans = [] for i, f in enumerate(self.inputs.functional_runs): if isinstance(f, list): numscans = len(f) elif isinstance(f, six.string_types): img = load(f) numscans = img.get_shape()[3] else: raise Exception('Functional input not specified correctly') nscans.insert(i, numscans) # now combine all fields into 1 # names, onsets, durations, amplitudes, pmod, tmod, regressor_names, # regressors infoout = infolist[0] for j, val in enumerate(infolist[0].durations): if len(infolist[0].onsets[j]) > 1 and len(val) == 1: infoout.durations[j] = (infolist[0].durations[j] * len(infolist[0].onsets[j])) for i, info in enumerate(infolist[1:]): #info.[conditions, tmod] remain the same if info.onsets: for j, val in enumerate(info.onsets): if self.inputs.input_units == 'secs': onsets = np.array(info.onsets[j]) +\ self.inputs.time_repetition * \ sum(nscans[0:(i + 1)]) infoout.onsets[j].extend(onsets.tolist()) else: onsets = np.array(info.onsets[j]) + \ sum(nscans[0:(i + 1)]) infoout.onsets[j].extend(onsets.tolist()) for j, val in enumerate(info.durations): if len(info.onsets[j]) > 1 and len(val) == 1: infoout.durations[j].extend(info.durations[j] * len(info.onsets[j])) elif len(info.onsets[j]) == len(val): infoout.durations[j].extend(info.durations[j]) else: raise ValueError('Mismatch in number of onsets and \ durations for run {0}, condition \ {1}'.format(i+2, j+1)) if hasattr(info, 'amplitudes') and info.amplitudes: for j, val in enumerate(info.amplitudes): infoout.amplitudes[j].extend(info.amplitudes[j]) if hasattr(info, 'pmod') and info.pmod: for j, val in enumerate(info.pmod): if val: for key, data in enumerate(val.param): infoout.pmod[j].param[key].extend(data) if hasattr(info, 'regressors') and info.regressors: #assumes same ordering of regressors across different #runs and the same names for the regressors for j, v in enumerate(info.regressors): infoout.regressors[j].extend(info.regressors[j]) #insert session regressors if not hasattr(infoout, 'regressors') or not infoout.regressors: infoout.regressors = [] onelist = np.zeros((1, sum(nscans))) onelist[0, sum(nscans[0:i]):sum(nscans[0:(i + 1)])] = 1 infoout.regressors.insert(len(infoout.regressors), onelist.tolist()[0]) return [infoout], nscans def _generate_design(self, infolist=None): if not isdefined(self.inputs.concatenate_runs) or \ not self.inputs.concatenate_runs: super(SpecifySPMModel, self)._generate_design(infolist=infolist) return if isdefined(self.inputs.subject_info): infolist = self.inputs.subject_info else: infolist = gen_info(self.inputs.event_files) concatlist, nscans = self._concatenate_info(infolist) functional_runs = [filename_to_list(self.inputs.functional_runs)] realignment_parameters = [] if isdefined(self.inputs.realignment_parameters): realignment_parameters = [] for parfile in self.inputs.realignment_parameters: mc = np.loadtxt(parfile) if not realignment_parameters: realignment_parameters.insert(0, mc) else: realignment_parameters[0] = \ np.concatenate((realignment_parameters[0], mc)) outliers = [] if isdefined(self.inputs.outlier_files): outliers = [[]] for i, filename in enumerate(self.inputs.outlier_files): try: out = np.loadtxt(filename, dtype=int) except IOError: out = np.array([]) if out.size > 0: if out.size == 1: outliers[0].extend([(np.array(out) + sum(nscans[0:i])).tolist()]) else: outliers[0].extend((np.array(out) + sum(nscans[0:i])).tolist()) self._sessinfo = self._generate_standard_design(concatlist, functional_runs=functional_runs, realignment_parameters=realignment_parameters, outliers=outliers) class SpecifySparseModelInputSpec(SpecifyModelInputSpec): time_acquisition = traits.Float(0, mandatory=True, desc="Time in seconds to acquire a single image volume") volumes_in_cluster=traits.Range(1, usedefault=True, desc="Number of scan volumes in a cluster") model_hrf = traits.Bool(desc="model sparse events with hrf") stimuli_as_impulses = traits.Bool(True, desc="Treat each stimulus to be impulse like.", usedefault=True) use_temporal_deriv = traits.Bool(requires=['model_hrf'], desc="Create a temporal derivative in addition to regular regressor") scale_regressors = traits.Bool(True, desc="Scale regressors by the peak", usedefault=True) scan_onset = traits.Float(0.0, desc="Start of scanning relative to onset of run in secs", usedefault=True) save_plot = traits.Bool(desc=('save plot of sparse design calculation ' '(Requires matplotlib)')) class SpecifySparseModelOutputSpec(SpecifyModelOutputSpec): sparse_png_file = File(desc='PNG file showing sparse design') sparse_svg_file = File(desc='SVG file showing sparse design') class SpecifySparseModel(SpecifyModel): """ Specify a sparse model that is compatible with spm/fsl designers References ---------- .. [1] Perrachione TK and Ghosh SS (2013) Optimized design and analysis of sparse-sampling fMRI experiments. Front. Neurosci. 7:55 http://journal.frontiersin.org/Journal/10.3389/fnins.2013.00055/abstract Examples -------- >>> from nipype.interfaces.base import Bunch >>> s = SpecifySparseModel() >>> s.inputs.input_units = 'secs' >>> s.inputs.functional_runs = ['functional2.nii', 'functional3.nii'] >>> s.inputs.time_repetition = 6 >>> s.inputs.time_acquisition = 2 >>> s.inputs.high_pass_filter_cutoff = 128. >>> s.inputs.model_hrf = True >>> info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], \ durations=[[1]]), \ Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], \ durations=[[1]])] >>> s.inputs.subject_info = info """ input_spec = SpecifySparseModelInputSpec output_spec = SpecifySparseModelOutputSpec def _gen_regress(self, i_onsets, i_durations, i_amplitudes, nscans): """Generates a regressor for a sparse/clustered-sparse acquisition """ bplot = False if isdefined(self.inputs.save_plot) and self.inputs.save_plot: bplot=True import matplotlib matplotlib.use(config.get("execution", "matplotlib_backend")) import matplotlib.pyplot as plt TR = np.round(self.inputs.time_repetition * 1000) # in ms if self.inputs.time_acquisition: TA = np.round(self.inputs.time_acquisition * 1000) # in ms else: TA = TR # in ms nvol = self.inputs.volumes_in_cluster SCANONSET = np.round(self.inputs.scan_onset * 1000) total_time = TR * (nscans - nvol) / nvol + TA * nvol + SCANONSET SILENCE = TR - TA * nvol dt = TA / 10.0 durations = np.round(np.array(i_durations) * 1000) if len(durations) == 1: durations = durations*np.ones((len(i_onsets))) onsets = np.round(np.array(i_onsets) * 1000) dttemp = gcd(TA, gcd(SILENCE, TR)) if dt < dttemp: if dttemp % dt != 0: dt = float(gcd(dttemp, dt)) if dt < 1: raise Exception("Time multiple less than 1 ms") iflogger.info("Setting dt = %d ms\n" % dt) npts = int(np.ceil(total_time / dt)) times = np.arange(0, total_time, dt) * 1e-3 timeline = np.zeros((npts)) timeline2 = np.zeros((npts)) if isdefined(self.inputs.model_hrf) and self.inputs.model_hrf: hrf = spm_hrf(dt * 1e-3) reg_scale = 1.0 if self.inputs.scale_regressors: boxcar = np.zeros((50.0 * 1e3 / dt)) if self.inputs.stimuli_as_impulses: boxcar[1.0 * 1e3 / dt] = 1.0 reg_scale = float(TA / dt) else: boxcar[(1.0 * 1e3 / dt):(2.0 * 1e3 / dt)] = 1.0 if isdefined(self.inputs.model_hrf) and self.inputs.model_hrf: response = np.convolve(boxcar, hrf) reg_scale = 1.0 / response.max() iflogger.info('response sum: %.4f max: %.4f' % (response.sum(), response.max())) iflogger.info('reg_scale: %.4f' % reg_scale) for i, t in enumerate(onsets): idx = int(np.round(t / dt)) if i_amplitudes: if len(i_amplitudes) > 1: timeline2[idx] = i_amplitudes[i] else: timeline2[idx] = i_amplitudes[0] else: timeline2[idx] = 1 if bplot: plt.subplot(4, 1, 1) plt.plot(times, timeline2) if not self.inputs.stimuli_as_impulses: if durations[i] == 0: durations[i] = TA * nvol stimdur = np.ones((int(durations[i] / dt))) timeline2 = np.convolve(timeline2, stimdur)[0:len(timeline2)] timeline += timeline2 timeline2[:] = 0 if bplot: plt.subplot(4, 1, 2) plt.plot(times, timeline) if isdefined(self.inputs.model_hrf) and self.inputs.model_hrf: timeline = np.convolve(timeline, hrf)[0:len(timeline)] if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: #create temporal deriv timederiv = np.concatenate(([0], np.diff(timeline))) if bplot: plt.subplot(4, 1, 3) plt.plot(times, timeline) if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: plt.plot(times, timederiv) # sample timeline timeline2 = np.zeros((npts)) reg = [] regderiv = [] for i, trial in enumerate(np.arange(nscans)/nvol): scanstart = int((SCANONSET + trial * TR + (i % nvol) * TA) / dt) scanidx = scanstart+np.arange(int(TA/dt)) timeline2[scanidx] = np.max(timeline) reg.insert(i, np.mean(timeline[scanidx]) * reg_scale) if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: regderiv.insert(i, np.mean(timederiv[scanidx]) * reg_scale) if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: iflogger.info('orthoganlizing derivative w.r.t. main regressor') regderiv = orth(reg, regderiv) if bplot: plt.subplot(4, 1, 3) plt.plot(times, timeline2) plt.subplot(4, 1, 4) plt.bar(np.arange(len(reg)), reg, width=0.5) plt.savefig('sparse.png') plt.savefig('sparse.svg') if regderiv: return [reg, regderiv] else: return reg def _cond_to_regress(self, info, nscans): """Converts condition information to full regressors """ reg = [] regnames = [] for i, cond in enumerate(info.conditions): if hasattr(info, 'amplitudes') and info.amplitudes: amplitudes = info.amplitudes[i] else: amplitudes = None regnames.insert(len(regnames), cond) scaled_onsets = scale_timings(info.onsets[i], self.inputs.input_units, 'secs', self.inputs.time_repetition) scaled_durations = scale_timings(info.durations[i], self.inputs.input_units, 'secs', self.inputs.time_repetition) regressor = self._gen_regress(scaled_onsets, scaled_durations, amplitudes, nscans) if isdefined(self.inputs.use_temporal_deriv) and \ self.inputs.use_temporal_deriv: reg.insert(len(reg), regressor[0]) regnames.insert(len(regnames), cond + '_D') reg.insert(len(reg), regressor[1]) else: reg.insert(len(reg), regressor) # need to deal with temporal and parametric modulators # for sparse-clustered acquisitions enter T1-effect regressors nvol = self.inputs.volumes_in_cluster if nvol > 1: for i in range(nvol-1): treg = np.zeros((nscans/nvol, nvol)) treg[:, i] = 1 reg.insert(len(reg), treg.ravel().tolist()) regnames.insert(len(regnames), 'T1effect_%d' % i) return reg, regnames def _generate_clustered_design(self, infolist): """Generates condition information for sparse-clustered designs. """ infoout = deepcopy(infolist) for i, info in enumerate(infolist): infoout[i].conditions = None infoout[i].onsets = None infoout[i].durations = None if info.conditions: img = load(self.inputs.functional_runs[i]) nscans = img.get_shape()[3] reg, regnames = self._cond_to_regress(info, nscans) if hasattr(infoout[i], 'regressors') and infoout[i].regressors: if not infoout[i].regressor_names: infoout[i].regressor_names = \ ['R%d'%j for j in range(len(infoout[i].regressors))] else: infoout[i].regressors = [] infoout[i].regressor_names = [] for j, r in enumerate(reg): regidx = len(infoout[i].regressors) infoout[i].regressor_names.insert(regidx, regnames[j]) infoout[i].regressors.insert(regidx, r) return infoout def _generate_design(self, infolist=None): if isdefined(self.inputs.subject_info): infolist = self.inputs.subject_info else: infolist = gen_info(self.inputs.event_files) sparselist = self._generate_clustered_design(infolist) super(SpecifySparseModel, self)._generate_design(infolist = sparselist) def _list_outputs(self): outputs = self._outputs().get() if not hasattr(self, '_sessinfo'): self._generate_design() outputs['session_info'] = self._sessinfo if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['sparse_png_file'] = os.path.join(os.getcwd(), 'sparse.png') outputs['sparse_svg_file'] = os.path.join(os.getcwd(), 'sparse.svg') return outputs nipype-0.11.0/nipype/algorithms/rapidart.py000066400000000000000000000726711257611314500207540ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ The rapidart module provides routines for artifact detection and region of interest analysis. These functions include: * ArtifactDetect: performs artifact detection on functional images * StimulusCorrelation: determines correlation between stimuli schedule and movement/intensity parameters Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ import os from copy import deepcopy from warnings import warn from nibabel import load, funcs, Nifti1Image import numpy as np from scipy import signal import scipy.io as sio from nipype.external import six from ..interfaces.base import (BaseInterface, traits, InputMultiPath, OutputMultiPath, TraitedSpec, File, BaseInterfaceInputSpec, isdefined) from ..utils.filemanip import filename_to_list, save_json, split_filename from ..utils.misc import find_indices from .. import logging, config iflogger = logging.getLogger('interface') def _get_affine_matrix(params, source): """Return affine matrix given a set of translation and rotation parameters params : np.array (upto 12 long) in native package format source : the package that generated the parameters supports SPM, AFNI, FSFAST, FSL, NIPY """ if source == 'FSL': params = params[[3, 4, 5, 0, 1, 2]] elif source in ('AFNI', 'FSFAST'): params = params[np.asarray([4, 5, 3, 1, 2, 0]) + (len(params) > 6)] params[3:] = params[3:] * np.pi / 180. if source == 'NIPY': # nipy does not store typical euler angles, use nipy to convert from nipy.algorithms.registration import to_matrix44 return to_matrix44(params) #process for FSL, SPM, AFNI and FSFAST rotfunc = lambda x: np.array([[np.cos(x), np.sin(x)], [-np.sin(x), np.cos(x)]]) q = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0]) if len(params) < 12: params = np.hstack((params, q[len(params):])) params.shape = (len(params),) # Translation T = np.eye(4) T[0:3, -1] = params[0:3] # Rotation Rx = np.eye(4) Rx[1:3, 1:3] = rotfunc(params[3]) Ry = np.eye(4) Ry[(0, 0, 2, 2), (0, 2, 0, 2)] = rotfunc(params[4]).ravel() Rz = np.eye(4) Rz[0:2, 0:2] = rotfunc(params[5]) # Scaling S = np.eye(4) S[0:3, 0:3] = np.diag(params[6:9]) # Shear Sh = np.eye(4) Sh[(0, 0, 1), (1, 2, 2)] = params[9:12] if source in ('AFNI', 'FSFAST'): return np.dot(T, np.dot(Ry, np.dot(Rx, np.dot(Rz, np.dot(S, Sh))))) return np.dot(T, np.dot(Rx, np.dot(Ry, np.dot(Rz, np.dot(S, Sh))))) def _calc_norm(mc, use_differences, source, brain_pts=None): """Calculates the maximum overall displacement of the midpoints of the faces of a cube due to translation and rotation. Parameters ---------- mc : motion parameter estimates [3 translation, 3 rotation (radians)] use_differences : boolean brain_pts : [4 x n_points] of coordinates Returns ------- norm : at each time point displacement : euclidean distance (mm) of displacement at each coordinate """ if brain_pts is None: respos = np.diag([70, 70, 75]) resneg = np.diag([-70, -110, -45]) all_pts = np.vstack((np.hstack((respos, resneg)), np.ones((1, 6)))) displacement = None else: all_pts = brain_pts n_pts = all_pts.size - all_pts.shape[1] newpos = np.zeros((mc.shape[0], n_pts)) if brain_pts is not None: displacement = np.zeros((mc.shape[0], n_pts / 3)) for i in range(mc.shape[0]): affine = _get_affine_matrix(mc[i, :], source) newpos[i, :] = np.dot(affine, all_pts)[0:3, :].ravel() if brain_pts is not None: displacement[i, :] = \ np.sqrt(np.sum(np.power(np.reshape(newpos[i, :], (3, all_pts.shape[1])) - all_pts[0:3, :], 2), axis=0)) # np.savez('displacement.npz', newpos=newpos, pts=all_pts) normdata = np.zeros(mc.shape[0]) if use_differences: newpos = np.concatenate((np.zeros((1, n_pts)), np.diff(newpos, n=1, axis=0)), axis=0) for i in range(newpos.shape[0]): normdata[i] = \ np.max(np.sqrt(np.sum(np.reshape(np.power(np.abs(newpos[i, :]), 2), (3, all_pts.shape[1])), axis=0))) else: newpos = np.abs(signal.detrend(newpos, axis=0, type='constant')) normdata = np.sqrt(np.mean(np.power(newpos, 2), axis=1)) return normdata, displacement def _nanmean(a, axis=None): """Return the mean excluding items that are nan >>> a = [1, 2, np.nan] >>> _nanmean(a) 1.5 """ if axis: return np.nansum(a, axis) / np.sum(1 - np.isnan(a), axis) else: return np.nansum(a) / np.sum(1 - np.isnan(a)) class ArtifactDetectInputSpec(BaseInterfaceInputSpec): realigned_files = InputMultiPath(File(exists=True), desc="Names of realigned functional data files", mandatory=True) realignment_parameters = InputMultiPath(File(exists=True), mandatory=True, desc=("Names of realignment parameters" "corresponding to the functional data files")) parameter_source = traits.Enum("SPM", "FSL", "AFNI", "NiPy", "FSFAST", desc="Source of movement parameters", mandatory=True) use_differences = traits.ListBool([True, False], minlen=2, maxlen=2, usedefault=True, desc=("Use differences between successive motion (first element)" "and intensity paramter (second element) estimates in order" "to determine outliers. (default is [True, False])")) use_norm = traits.Bool(True, requires=['norm_threshold'], desc=("Uses a composite of the motion parameters in " "order to determine outliers."), usedefault=True) norm_threshold = traits.Float(desc=("Threshold to use to detect motion-rela" "ted outliers when composite motion is " "being used"), mandatory=True, xor=['rotation_threshold', 'translation_threshold']) rotation_threshold = traits.Float(mandatory=True, xor=['norm_threshold'], desc=("Threshold (in radians) to use to detect rotation-related " "outliers")) translation_threshold = traits.Float(mandatory=True, xor=['norm_threshold'], desc=("Threshold (in mm) to use to detect translation-related " "outliers")) zintensity_threshold = traits.Float(mandatory=True, desc=("Intensity Z-threshold use to detection images that deviate " "from the mean")) mask_type = traits.Enum('spm_global', 'file', 'thresh', desc=("Type of mask that should be used to mask the functional " "data. *spm_global* uses an spm_global like calculation to " "determine the brain mask. *file* specifies a brain mask " "file (should be an image file consisting of 0s and 1s). " "*thresh* specifies a threshold to use. By default all voxels" "are used, unless one of these mask types are defined."), mandatory=True) mask_file = File(exists=True, desc="Mask file to be used if mask_type is 'file'.") mask_threshold = traits.Float(desc=("Mask threshold to be used if mask_type" " is 'thresh'.")) intersect_mask = traits.Bool(True, desc=("Intersect the masks when computed from " "spm_global.")) save_plot = traits.Bool(True, desc="save plots containing outliers", usedefault=True) plot_type = traits.Enum('png', 'svg', 'eps', 'pdf', desc="file type of the outlier plot", usedefault=True) bound_by_brainmask = traits.Bool(False, desc=("use the brain mask to " "determine bounding box" "for composite norm (works" "for SPM and Nipy - currently" "inaccurate for FSL, AFNI"), usedefault=True) global_threshold = traits.Float(8.0, desc=("use this threshold when mask " "type equal's spm_global"), usedefault=True) class ArtifactDetectOutputSpec(TraitedSpec): outlier_files = OutputMultiPath(File(exists=True), desc=("One file for each functional run containing a list of " "0-based indices corresponding to outlier volumes")) intensity_files = OutputMultiPath(File(exists=True), desc=("One file for each functional run containing the global " "intensity values determined from the brainmask")) norm_files = OutputMultiPath(File, desc=("One file for each functional run containing the composite " "norm")) statistic_files = OutputMultiPath(File(exists=True), desc=("One file for each functional run containing information " "about the different types of artifacts and if design info is" " provided then details of stimulus correlated motion and a " "listing or artifacts by event type.")) plot_files = OutputMultiPath(File, desc=("One image file for each functional run containing the " "detected outliers")) mask_files = OutputMultiPath(File, desc=("One image file for each functional run containing the mask" "used for global signal calculation")) displacement_files = OutputMultiPath(File, desc=("One image file for each functional run containing the voxel" "displacement timeseries")) class ArtifactDetect(BaseInterface): """Detects outliers in a functional imaging series Uses intensity and motion parameters to infer outliers. If `use_norm` is True, it computes the movement of the center of each face a cuboid centered around the head and returns the maximal movement across the centers. Examples -------- >>> ad = ArtifactDetect() >>> ad.inputs.realigned_files = 'functional.nii' >>> ad.inputs.realignment_parameters = 'functional.par' >>> ad.inputs.parameter_source = 'FSL' >>> ad.inputs.norm_threshold = 1 >>> ad.inputs.use_differences = [True, False] >>> ad.inputs.zintensity_threshold = 3 >>> ad.run() # doctest: +SKIP """ input_spec = ArtifactDetectInputSpec output_spec = ArtifactDetectOutputSpec def __init__(self, **inputs): super(ArtifactDetect, self).__init__(**inputs) def _get_output_filenames(self, motionfile, output_dir): """Generate output files based on motion filenames Parameters ---------- motionfile: file/string Filename for motion parameter file output_dir: string output directory in which the files will be generated """ if isinstance(motionfile, six.string_types): infile = motionfile elif isinstance(motionfile, list): infile = motionfile[0] else: raise Exception("Unknown type of file") _, filename, ext = split_filename(infile) artifactfile = os.path.join(output_dir, ''.join(('art.', filename, '_outliers.txt'))) intensityfile = os.path.join(output_dir, ''.join(('global_intensity.', filename, '.txt'))) statsfile = os.path.join(output_dir, ''.join(('stats.', filename, '.txt'))) normfile = os.path.join(output_dir, ''.join(('norm.', filename, '.txt'))) plotfile = os.path.join(output_dir, ''.join(('plot.', filename, '.', self.inputs.plot_type))) displacementfile = os.path.join(output_dir, ''.join(('disp.', filename, ext))) maskfile = os.path.join(output_dir, ''.join(('mask.', filename, ext))) return (artifactfile, intensityfile, statsfile, normfile, plotfile, displacementfile, maskfile) def _list_outputs(self): outputs = self._outputs().get() outputs['outlier_files'] = [] outputs['intensity_files'] = [] outputs['statistic_files'] = [] outputs['mask_files'] = [] if isdefined(self.inputs.use_norm) and self.inputs.use_norm: outputs['norm_files'] = [] if self.inputs.bound_by_brainmask: outputs['displacement_files'] = [] if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['plot_files'] = [] for i, f in enumerate(filename_to_list(self.inputs.realigned_files)): (outlierfile, intensityfile, statsfile, normfile, plotfile, displacementfile, maskfile) = \ self._get_output_filenames(f, os.getcwd()) outputs['outlier_files'].insert(i, outlierfile) outputs['intensity_files'].insert(i, intensityfile) outputs['statistic_files'].insert(i, statsfile) outputs['mask_files'].insert(i, maskfile) if isdefined(self.inputs.use_norm) and self.inputs.use_norm: outputs['norm_files'].insert(i, normfile) if self.inputs.bound_by_brainmask: outputs['displacement_files'].insert(i, displacementfile) if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['plot_files'].insert(i, plotfile) return outputs def _plot_outliers_with_wave(self, wave, outliers, name): import matplotlib.pyplot as plt plt.plot(wave) plt.ylim([wave.min(), wave.max()]) plt.xlim([0, len(wave) - 1]) if len(outliers): plt.plot(np.tile(outliers[:, None], (1, 2)).T, np.tile([wave.min(), wave.max()], (len(outliers), 1)).T, 'r') plt.xlabel('Scans - 0-based') plt.ylabel(name) def _detect_outliers_core(self, imgfile, motionfile, runidx, cwd=None): """ Core routine for detecting outliers """ if not cwd: cwd = os.getcwd() # read in functional image if isinstance(imgfile, six.string_types): nim = load(imgfile) elif isinstance(imgfile, list): if len(imgfile) == 1: nim = load(imgfile[0]) else: images = [load(f) for f in imgfile] nim = funcs.concat_images(images) # compute global intensity signal (x, y, z, timepoints) = nim.get_shape() data = nim.get_data() affine = nim.get_affine() g = np.zeros((timepoints, 1)) masktype = self.inputs.mask_type if masktype == 'spm_global': # spm_global like calculation iflogger.debug('art: using spm global') intersect_mask = self.inputs.intersect_mask if intersect_mask: mask = np.ones((x, y, z), dtype=bool) for t0 in range(timepoints): vol = data[:, :, :, t0] # Use an SPM like approach mask_tmp = vol > \ (_nanmean(vol) / self.inputs.global_threshold) mask = mask * mask_tmp for t0 in range(timepoints): vol = data[:, :, :, t0] g[t0] = _nanmean(vol[mask]) if len(find_indices(mask)) < (np.prod((x, y, z)) / 10): intersect_mask = False g = np.zeros((timepoints, 1)) if not intersect_mask: iflogger.info('not intersect_mask is True') mask = np.zeros((x, y, z, timepoints)) for t0 in range(timepoints): vol = data[:, :, :, t0] mask_tmp = vol > \ (_nanmean(vol) / self.inputs.global_threshold) mask[:, :, :, t0] = mask_tmp g[t0] = np.nansum(vol * mask_tmp)/np.nansum(mask_tmp) elif masktype == 'file': # uses a mask image to determine intensity maskimg = load(self.inputs.mask_file) mask = maskimg.get_data() affine = maskimg.get_affine() mask = mask > 0.5 for t0 in range(timepoints): vol = data[:, :, :, t0] g[t0] = _nanmean(vol[mask]) elif masktype == 'thresh': # uses a fixed signal threshold for t0 in range(timepoints): vol = data[:, :, :, t0] mask = vol > self.inputs.mask_threshold g[t0] = _nanmean(vol[mask]) else: mask = np.ones((x, y, z)) g = _nanmean(data[mask > 0, :], 1) # compute normalized intensity values gz = signal.detrend(g, axis=0) # detrend the signal if self.inputs.use_differences[1]: gz = np.concatenate((np.zeros((1, 1)), np.diff(gz, n=1, axis=0)), axis=0) gz = (gz - np.mean(gz)) / np.std(gz) # normalize the detrended signal iidx = find_indices(abs(gz) > self.inputs.zintensity_threshold) # read in motion parameters mc_in = np.loadtxt(motionfile) mc = deepcopy(mc_in) (artifactfile, intensityfile, statsfile, normfile, plotfile, displacementfile, maskfile) = self._get_output_filenames(imgfile, cwd) mask_img = Nifti1Image(mask.astype(np.uint8), affine) mask_img.to_filename(maskfile) if self.inputs.use_norm: brain_pts = None if self.inputs.bound_by_brainmask: voxel_coords = np.nonzero(mask) coords = np.vstack((voxel_coords[0], np.vstack((voxel_coords[1], voxel_coords[2])))).T brain_pts = np.dot(affine, np.hstack((coords, np.ones((coords.shape[0], 1)))).T) # calculate the norm of the motion parameters normval, displacement = _calc_norm(mc, self.inputs.use_differences[0], self.inputs.parameter_source, brain_pts=brain_pts) tidx = find_indices(normval > self.inputs.norm_threshold) ridx = find_indices(normval < 0) if displacement is not None: dmap = np.zeros((x, y, z, timepoints), dtype=np.float) for i in range(timepoints): dmap[voxel_coords[0], voxel_coords[1], voxel_coords[2], i] = displacement[i, :] dimg = Nifti1Image(dmap, affine) dimg.to_filename(displacementfile) else: if self.inputs.use_differences[0]: mc = np.concatenate((np.zeros((1, 6)), np.diff(mc_in, n=1, axis=0)), axis=0) traval = mc[:, 0:3] # translation parameters (mm) rotval = mc[:, 3:6] # rotation parameters (rad) tidx = find_indices(np.sum(abs(traval) > self.inputs.translation_threshold, 1) > 0) ridx = find_indices(np.sum(abs(rotval) > self.inputs.rotation_threshold, 1) > 0) outliers = np.unique(np.union1d(iidx, np.union1d(tidx, ridx))) # write output to outputfile np.savetxt(artifactfile, outliers, fmt='%d', delimiter=' ') np.savetxt(intensityfile, g, fmt='%.2f', delimiter=' ') if self.inputs.use_norm: np.savetxt(normfile, normval, fmt='%.4f', delimiter=' ') if isdefined(self.inputs.save_plot) and self.inputs.save_plot: import matplotlib matplotlib.use(config.get("execution", "matplotlib_backend")) import matplotlib.pyplot as plt fig = plt.figure() if isdefined(self.inputs.use_norm) and self.inputs.use_norm: plt.subplot(211) else: plt.subplot(311) self._plot_outliers_with_wave(gz, iidx, 'Intensity') if isdefined(self.inputs.use_norm) and self.inputs.use_norm: plt.subplot(212) self._plot_outliers_with_wave(normval, np.union1d(tidx, ridx), 'Norm (mm)') else: diff = '' if self.inputs.use_differences[0]: diff = 'diff' plt.subplot(312) self._plot_outliers_with_wave(traval, tidx, 'Translation (mm)' + diff) plt.subplot(313) self._plot_outliers_with_wave(rotval, ridx, 'Rotation (rad)' + diff) plt.savefig(plotfile) plt.close(fig) motion_outliers = np.union1d(tidx, ridx) stats = [{'motion_file': motionfile, 'functional_file': imgfile}, {'common_outliers': len(np.intersect1d(iidx, motion_outliers)), 'intensity_outliers': len(np.setdiff1d(iidx, motion_outliers)), 'motion_outliers': len(np.setdiff1d(motion_outliers, iidx)), }, {'motion': [{'using differences': self.inputs.use_differences[0]}, {'mean': np.mean(mc_in, axis=0).tolist(), 'min': np.min(mc_in, axis=0).tolist(), 'max': np.max(mc_in, axis=0).tolist(), 'std': np.std(mc_in, axis=0).tolist()}, ]}, {'intensity': [{'using differences': self.inputs.use_differences[1]}, {'mean': np.mean(gz, axis=0).tolist(), 'min': np.min(gz, axis=0).tolist(), 'max': np.max(gz, axis=0).tolist(), 'std': np.std(gz, axis=0).tolist()}, ]}, ] if self.inputs.use_norm: stats.insert(3, {'motion_norm': {'mean': np.mean(normval, axis=0).tolist(), 'min': np.min(normval, axis=0).tolist(), 'max': np.max(normval, axis=0).tolist(), 'std': np.std(normval, axis=0).tolist(), }}) save_json(statsfile, stats) def _run_interface(self, runtime): """Execute this module. """ funcfilelist = filename_to_list(self.inputs.realigned_files) motparamlist = filename_to_list(self.inputs.realignment_parameters) for i, imgf in enumerate(funcfilelist): self._detect_outliers_core(imgf, motparamlist[i], i, cwd=os.getcwd()) return runtime class StimCorrInputSpec(BaseInterfaceInputSpec): realignment_parameters = InputMultiPath(File(exists=True), mandatory=True, desc=('Names of realignment parameters corresponding to the functional ' 'data files')) intensity_values = InputMultiPath(File(exists=True), mandatory=True, desc='Name of file containing intensity values') spm_mat_file = File(exists=True, mandatory=True, desc='SPM mat file (use pre-estimate SPM.mat file)') concatenated_design = traits.Bool(mandatory=True, desc='state if the design matrix contains concatenated sessions') class StimCorrOutputSpec(TraitedSpec): stimcorr_files = OutputMultiPath(File(exists=True), desc='List of files containing correlation values') class StimulusCorrelation(BaseInterface): """Determines if stimuli are correlated with motion or intensity parameters. Currently this class supports an SPM generated design matrix and requires intensity parameters. This implies that one must run :ref:`ArtifactDetect ` and :ref:`Level1Design ` prior to running this or provide an SPM.mat file and intensity parameters through some other means. Examples -------- >>> sc = StimulusCorrelation() >>> sc.inputs.realignment_parameters = 'functional.par' >>> sc.inputs.intensity_values = 'functional.rms' >>> sc.inputs.spm_mat_file = 'SPM.mat' >>> sc.inputs.concatenated_design = False >>> sc.run() # doctest: +SKIP """ input_spec = StimCorrInputSpec output_spec = StimCorrOutputSpec def _get_output_filenames(self, motionfile, output_dir): """Generate output files based on motion filenames Parameters ---------- motionfile: file/string Filename for motion parameter file output_dir: string output directory in which the files will be generated """ (_, filename) = os.path.split(motionfile) (filename, _) = os.path.splitext(filename) corrfile = os.path.join(output_dir, ''.join(('qa.', filename, '_stimcorr.txt'))) return corrfile def _stimcorr_core(self, motionfile, intensityfile, designmatrix, cwd=None): """ Core routine for determining stimulus correlation """ if not cwd: cwd = os.getcwd() # read in motion parameters mc_in = np.loadtxt(motionfile) g_in = np.loadtxt(intensityfile) g_in.shape = g_in.shape[0], 1 dcol = designmatrix.shape[1] mccol = mc_in.shape[1] concat_matrix = np.hstack((np.hstack((designmatrix, mc_in)), g_in)) cm = np.corrcoef(concat_matrix, rowvar=0) corrfile = self._get_output_filenames(motionfile, cwd) # write output to outputfile file = open(corrfile, 'w') file.write("Stats for:\n") file.write("Stimulus correlated motion:\n%s\n" % motionfile) for i in range(dcol): file.write("SCM.%d:" % i) for v in cm[i, dcol + np.arange(mccol)]: file.write(" %.2f" % v) file.write('\n') file.write("Stimulus correlated intensity:\n%s\n" % intensityfile) for i in range(dcol): file.write("SCI.%d: %.2f\n" % (i, cm[i, -1])) file.close() def _get_spm_submatrix(self, spmmat, sessidx, rows=None): """ Parameters ---------- spmmat: scipy matlab object full SPM.mat file loaded into a scipy object sessidx: int index to session that needs to be extracted. """ designmatrix = spmmat['SPM'][0][0].xX[0][0].X U = spmmat['SPM'][0][0].Sess[0][sessidx].U[0] if rows is None: rows = spmmat['SPM'][0][0].Sess[0][sessidx].row[0] - 1 cols = spmmat['SPM'][0][0].Sess[0][sessidx].col[0][range(len(U))] - 1 outmatrix = designmatrix.take(rows.tolist(), axis=0).take(cols.tolist(), axis=1) return outmatrix def _run_interface(self, runtime): """Execute this module. """ motparamlist = self.inputs.realignment_parameters intensityfiles = self.inputs.intensity_values spmmat = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False) nrows = [] for i in range(len(motparamlist)): sessidx = i rows = None if self.inputs.concatenated_design: sessidx = 0 mc_in = np.loadtxt(motparamlist[i]) rows = np.sum(nrows) + np.arange(mc_in.shape[0]) nrows.append(mc_in.shape[0]) matrix = self._get_spm_submatrix(spmmat, sessidx, rows) self._stimcorr_core(motparamlist[i], intensityfiles[i], matrix, os.getcwd()) return runtime def _list_outputs(self): outputs = self._outputs().get() files = [] for i, f in enumerate(self.inputs.realignment_parameters): files.insert(i, self._get_output_filenames(f, os.getcwd())) if files: outputs['stimcorr_files'] = files return outputs nipype-0.11.0/nipype/algorithms/tests/000077500000000000000000000000001257611314500177215ustar00rootroot00000000000000nipype-0.11.0/nipype/algorithms/tests/__init__.py000066400000000000000000000001621257611314500220310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/algorithms/tests/test_auto_AddCSVColumn.py000066400000000000000000000015111257611314500246020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import AddCSVColumn def test_AddCSVColumn_inputs(): input_map = dict(extra_column_heading=dict(), extra_field=dict(), in_file=dict(mandatory=True, ), out_file=dict(usedefault=True, ), ) inputs = AddCSVColumn.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AddCSVColumn_outputs(): output_map = dict(csv_file=dict(), ) outputs = AddCSVColumn.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_AddCSVRow.py000066400000000000000000000015041257611314500241160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import AddCSVRow def test_AddCSVRow_inputs(): input_map = dict(_outputs=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), ) inputs = AddCSVRow.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AddCSVRow_outputs(): output_map = dict(csv_file=dict(), ) outputs = AddCSVRow.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_AddNoise.py000066400000000000000000000016271257611314500240560ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import AddNoise def test_AddNoise_inputs(): input_map = dict(bg_dist=dict(mandatory=True, usedefault=True, ), dist=dict(mandatory=True, usedefault=True, ), in_file=dict(mandatory=True, ), in_mask=dict(), out_file=dict(), snr=dict(usedefault=True, ), ) inputs = AddNoise.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AddNoise_outputs(): output_map = dict(out_file=dict(), ) outputs = AddNoise.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_ArtifactDetect.py000066400000000000000000000035201257611314500252500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.rapidart import ArtifactDetect def test_ArtifactDetect_inputs(): input_map = dict(bound_by_brainmask=dict(usedefault=True, ), global_threshold=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), intersect_mask=dict(), mask_file=dict(), mask_threshold=dict(), mask_type=dict(mandatory=True, ), norm_threshold=dict(mandatory=True, xor=['rotation_threshold', 'translation_threshold'], ), parameter_source=dict(mandatory=True, ), plot_type=dict(usedefault=True, ), realigned_files=dict(mandatory=True, ), realignment_parameters=dict(mandatory=True, ), rotation_threshold=dict(mandatory=True, xor=['norm_threshold'], ), save_plot=dict(usedefault=True, ), translation_threshold=dict(mandatory=True, xor=['norm_threshold'], ), use_differences=dict(maxlen=2, minlen=2, usedefault=True, ), use_norm=dict(requires=['norm_threshold'], usedefault=True, ), zintensity_threshold=dict(mandatory=True, ), ) inputs = ArtifactDetect.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ArtifactDetect_outputs(): output_map = dict(displacement_files=dict(), intensity_files=dict(), mask_files=dict(), norm_files=dict(), outlier_files=dict(), plot_files=dict(), statistic_files=dict(), ) outputs = ArtifactDetect.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_CalculateNormalizedMoments.py000066400000000000000000000015321257611314500276500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import CalculateNormalizedMoments def test_CalculateNormalizedMoments_inputs(): input_map = dict(moment=dict(mandatory=True, ), timeseries_file=dict(mandatory=True, ), ) inputs = CalculateNormalizedMoments.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CalculateNormalizedMoments_outputs(): output_map = dict(moments=dict(), ) outputs = CalculateNormalizedMoments.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_ComputeMeshWarp.py000066400000000000000000000020631257611314500254460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.mesh import ComputeMeshWarp def test_ComputeMeshWarp_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), metric=dict(usedefault=True, ), out_file=dict(usedefault=True, ), out_warp=dict(usedefault=True, ), surface1=dict(mandatory=True, ), surface2=dict(mandatory=True, ), weighting=dict(usedefault=True, ), ) inputs = ComputeMeshWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeMeshWarp_outputs(): output_map = dict(distance=dict(), out_file=dict(), out_warp=dict(), ) outputs = ComputeMeshWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_CreateNifti.py000066400000000000000000000015471257611314500245660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import CreateNifti def test_CreateNifti_inputs(): input_map = dict(affine=dict(), data_file=dict(mandatory=True, ), header_file=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), ) inputs = CreateNifti.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CreateNifti_outputs(): output_map = dict(nifti_file=dict(), ) outputs = CreateNifti.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_Distance.py000066400000000000000000000016711257611314500241210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import Distance def test_Distance_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), mask_volume=dict(), method=dict(usedefault=True, ), volume1=dict(mandatory=True, ), volume2=dict(mandatory=True, ), ) inputs = Distance.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Distance_outputs(): output_map = dict(distance=dict(), histogram=dict(), point1=dict(), point2=dict(), ) outputs = Distance.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_FuzzyOverlap.py000066400000000000000000000017661257611314500250540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import FuzzyOverlap def test_FuzzyOverlap_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_ref=dict(mandatory=True, ), in_tst=dict(mandatory=True, ), out_file=dict(usedefault=True, ), weighting=dict(usedefault=True, ), ) inputs = FuzzyOverlap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FuzzyOverlap_outputs(): output_map = dict(class_fdi=dict(), class_fji=dict(), dice=dict(), diff_file=dict(), jaccard=dict(), ) outputs = FuzzyOverlap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_Gunzip.py000066400000000000000000000014131257611314500236350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import Gunzip def test_Gunzip_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), ) inputs = Gunzip.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Gunzip_outputs(): output_map = dict(out_file=dict(), ) outputs = Gunzip.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_ICC.py000066400000000000000000000015411257611314500227610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.icc import ICC def test_ICC_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), mask=dict(mandatory=True, ), subjects_sessions=dict(mandatory=True, ), ) inputs = ICC.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ICC_outputs(): output_map = dict(icc_map=dict(), session_var_map=dict(), subject_var_map=dict(), ) outputs = ICC.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_Matlab2CSV.py000066400000000000000000000014151257611314500242210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import Matlab2CSV def test_Matlab2CSV_inputs(): input_map = dict(in_file=dict(mandatory=True, ), reshape_matrix=dict(usedefault=True, ), ) inputs = Matlab2CSV.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Matlab2CSV_outputs(): output_map = dict(csv_files=dict(), ) outputs = Matlab2CSV.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_MergeCSVFiles.py000066400000000000000000000016671257611314500247720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import MergeCSVFiles def test_MergeCSVFiles_inputs(): input_map = dict(column_headings=dict(), extra_column_heading=dict(), extra_field=dict(), in_files=dict(mandatory=True, ), out_file=dict(usedefault=True, ), row_heading_title=dict(usedefault=True, ), row_headings=dict(), ) inputs = MergeCSVFiles.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MergeCSVFiles_outputs(): output_map = dict(csv_file=dict(), ) outputs = MergeCSVFiles.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_MergeROIs.py000066400000000000000000000013651257611314500241630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import MergeROIs def test_MergeROIs_inputs(): input_map = dict(in_files=dict(), in_index=dict(), in_reference=dict(), ) inputs = MergeROIs.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MergeROIs_outputs(): output_map = dict(merged_file=dict(), ) outputs = MergeROIs.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_MeshWarpMaths.py000066400000000000000000000020031257611314500251000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.mesh import MeshWarpMaths def test_MeshWarpMaths_inputs(): input_map = dict(float_trait=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_surf=dict(mandatory=True, ), operation=dict(usedefault=True, ), operator=dict(mandatory=True, ), out_file=dict(usedefault=True, ), out_warp=dict(usedefault=True, ), ) inputs = MeshWarpMaths.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MeshWarpMaths_outputs(): output_map = dict(out_file=dict(), out_warp=dict(), ) outputs = MeshWarpMaths.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_ModifyAffine.py000066400000000000000000000015531257611314500247260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import ModifyAffine def test_ModifyAffine_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), transformation_matrix=dict(usedefault=True, ), volumes=dict(mandatory=True, ), ) inputs = ModifyAffine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ModifyAffine_outputs(): output_map = dict(transformed_volumes=dict(), ) outputs = ModifyAffine.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_NormalizeProbabilityMapSet.py000066400000000000000000000014561257611314500276430ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import NormalizeProbabilityMapSet def test_NormalizeProbabilityMapSet_inputs(): input_map = dict(in_files=dict(), in_mask=dict(), ) inputs = NormalizeProbabilityMapSet.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NormalizeProbabilityMapSet_outputs(): output_map = dict(out_files=dict(), ) outputs = NormalizeProbabilityMapSet.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_P2PDistance.py000066400000000000000000000020371257611314500244400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.mesh import P2PDistance def test_P2PDistance_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), metric=dict(usedefault=True, ), out_file=dict(usedefault=True, ), out_warp=dict(usedefault=True, ), surface1=dict(mandatory=True, ), surface2=dict(mandatory=True, ), weighting=dict(usedefault=True, ), ) inputs = P2PDistance.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_P2PDistance_outputs(): output_map = dict(distance=dict(), out_file=dict(), out_warp=dict(), ) outputs = P2PDistance.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_PickAtlas.py000066400000000000000000000016551257611314500242440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import PickAtlas def test_PickAtlas_inputs(): input_map = dict(atlas=dict(mandatory=True, ), dilation_size=dict(usedefault=True, ), hemi=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), labels=dict(mandatory=True, ), output_file=dict(), ) inputs = PickAtlas.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PickAtlas_outputs(): output_map = dict(mask_file=dict(), ) outputs = PickAtlas.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_Similarity.py000066400000000000000000000016301257611314500245100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.metrics import Similarity def test_Similarity_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), mask1=dict(), mask2=dict(), metric=dict(usedefault=True, ), volume1=dict(mandatory=True, ), volume2=dict(mandatory=True, ), ) inputs = Similarity.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Similarity_outputs(): output_map = dict(similarity=dict(), ) outputs = Similarity.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_SimpleThreshold.py000066400000000000000000000015551257611314500254760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import SimpleThreshold def test_SimpleThreshold_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), threshold=dict(mandatory=True, ), volumes=dict(mandatory=True, ), ) inputs = SimpleThreshold.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SimpleThreshold_outputs(): output_map = dict(thresholded_volumes=dict(), ) outputs = SimpleThreshold.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_SpecifyModel.py000066400000000000000000000023611257611314500247470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.modelgen import SpecifyModel def test_SpecifyModel_inputs(): input_map = dict(event_files=dict(mandatory=True, xor=['subject_info', 'event_files'], ), functional_runs=dict(copyfile=False, mandatory=True, ), high_pass_filter_cutoff=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_units=dict(mandatory=True, ), outlier_files=dict(copyfile=False, ), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, xor=['subject_info', 'event_files'], ), time_repetition=dict(mandatory=True, ), ) inputs = SpecifyModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SpecifyModel_outputs(): output_map = dict(session_info=dict(), ) outputs = SpecifyModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_SpecifySPMModel.py000066400000000000000000000025401257611314500253260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.modelgen import SpecifySPMModel def test_SpecifySPMModel_inputs(): input_map = dict(concatenate_runs=dict(usedefault=True, ), event_files=dict(mandatory=True, xor=['subject_info', 'event_files'], ), functional_runs=dict(copyfile=False, mandatory=True, ), high_pass_filter_cutoff=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_units=dict(mandatory=True, ), outlier_files=dict(copyfile=False, ), output_units=dict(usedefault=True, ), realignment_parameters=dict(copyfile=False, ), subject_info=dict(mandatory=True, xor=['subject_info', 'event_files'], ), time_repetition=dict(mandatory=True, ), ) inputs = SpecifySPMModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SpecifySPMModel_outputs(): output_map = dict(session_info=dict(), ) outputs = SpecifySPMModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_SpecifySparseModel.py000066400000000000000000000032461257611314500261300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.modelgen import SpecifySparseModel def test_SpecifySparseModel_inputs(): input_map = dict(event_files=dict(mandatory=True, xor=['subject_info', 'event_files'], ), functional_runs=dict(copyfile=False, mandatory=True, ), high_pass_filter_cutoff=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_units=dict(mandatory=True, ), model_hrf=dict(), outlier_files=dict(copyfile=False, ), realignment_parameters=dict(copyfile=False, ), save_plot=dict(), scale_regressors=dict(usedefault=True, ), scan_onset=dict(usedefault=True, ), stimuli_as_impulses=dict(usedefault=True, ), subject_info=dict(mandatory=True, xor=['subject_info', 'event_files'], ), time_acquisition=dict(mandatory=True, ), time_repetition=dict(mandatory=True, ), use_temporal_deriv=dict(requires=['model_hrf'], ), volumes_in_cluster=dict(usedefault=True, ), ) inputs = SpecifySparseModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SpecifySparseModel_outputs(): output_map = dict(session_info=dict(), sparse_png_file=dict(), sparse_svg_file=dict(), ) outputs = SpecifySparseModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_SplitROIs.py000066400000000000000000000014551257611314500242170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import SplitROIs def test_SplitROIs_inputs(): input_map = dict(in_file=dict(mandatory=True, ), in_mask=dict(), roi_size=dict(), ) inputs = SplitROIs.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SplitROIs_outputs(): output_map = dict(out_files=dict(), out_index=dict(), out_masks=dict(), ) outputs = SplitROIs.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_StimulusCorrelation.py000066400000000000000000000017671257611314500264240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.rapidart import StimulusCorrelation def test_StimulusCorrelation_inputs(): input_map = dict(concatenated_design=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), intensity_values=dict(mandatory=True, ), realignment_parameters=dict(mandatory=True, ), spm_mat_file=dict(mandatory=True, ), ) inputs = StimulusCorrelation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_StimulusCorrelation_outputs(): output_map = dict(stimcorr_files=dict(), ) outputs = StimulusCorrelation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_auto_TSNR.py000066400000000000000000000015441257611314500231540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.algorithms.misc import TSNR def test_TSNR_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), regress_poly=dict(), ) inputs = TSNR.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TSNR_outputs(): output_map = dict(detrended_file=dict(), mean_file=dict(), stddev_file=dict(), tsnr_file=dict(), ) outputs = TSNR.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/algorithms/tests/test_errormap.py000066400000000000000000000047111257611314500231640ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from nipype.testing import (assert_equal, example_data) from nipype.algorithms.metrics import ErrorMap import nibabel as nib import numpy as np from tempfile import mkdtemp import os def test_errormap(): tempdir = mkdtemp() # Single-Spectual # Make two fake 2*2*2 voxel volumes volume1 = np.array([[[2.0, 8.0], [1.0, 2.0]], [[1.0, 9.0], [0.0, 3.0]]]) # John von Neumann's birthday volume2 = np.array([[[0.0, 7.0], [2.0, 3.0]], [[1.0, 9.0], [1.0, 2.0]]]) # Alan Turing's birthday mask = np.array([[[1, 0], [0, 1]], [[1, 0], [0, 1]]]) img1 = nib.Nifti1Image(volume1, np.eye(4)) img2 = nib.Nifti1Image(volume2, np.eye(4)) maskimg = nib.Nifti1Image(mask, np.eye(4)) nib.save(img1, os.path.join(tempdir, 'von.nii.gz')) nib.save(img2, os.path.join(tempdir, 'alan.nii.gz')) nib.save(maskimg, os.path.join(tempdir, 'mask.nii.gz')) # Default metric errmap = ErrorMap() errmap.inputs.in_tst = os.path.join(tempdir, 'von.nii.gz') errmap.inputs.in_ref = os.path.join(tempdir, 'alan.nii.gz') errmap.out_map = os.path.join(tempdir, 'out_map.nii.gz') result = errmap.run() yield assert_equal, result.outputs.distance, 1.125 # Square metric errmap.inputs.metric = 'sqeuclidean' result = errmap.run() yield assert_equal, result.outputs.distance, 1.125 # Linear metric errmap.inputs.metric = 'euclidean' result = errmap.run() yield assert_equal, result.outputs.distance, 0.875 # Masked errmap.inputs.mask = os.path.join(tempdir, 'mask.nii.gz') result = errmap.run() yield assert_equal, result.outputs.distance, 1.0 ## Multi-Spectual volume3 = np.array([[[1.0, 6.0], [0.0, 3.0]], [[1.0, 9.0], [3.0, 6.0]]]) # Raymond Vahan Damadian's birthday msvolume1 = np.zeros(shape=(2,2,2,2)) msvolume1[:,:,:,0] = volume1 msvolume1[:,:,:,1] = volume3 msimg1 = nib.Nifti1Image(msvolume1, np.eye(4)) msvolume2 = np.zeros(shape=(2,2,2,2)) msvolume2[:,:,:,0] = volume3 msvolume2[:,:,:,1] = volume1 msimg2 = nib.Nifti1Image(msvolume2, np.eye(4)) nib.save(msimg1, os.path.join(tempdir, 'von-ray.nii.gz')) nib.save(msimg2, os.path.join(tempdir, 'alan-ray.nii.gz')) errmap.inputs.in_tst = os.path.join(tempdir, 'von-ray.nii.gz') errmap.inputs.in_ref = os.path.join(tempdir, 'alan-ray.nii.gz') errmap.inputs.metric = 'sqeuclidean' result = errmap.run() yield assert_equal, result.outputs.distance, 5.5 errmap.inputs.metric = 'euclidean' result = errmap.run() yield assert_equal, result.outputs.distance, np.float32(1.25 * (2**0.5)) nipype-0.11.0/nipype/algorithms/tests/test_icc_anova.py000066400000000000000000000013311257611314500232520ustar00rootroot00000000000000import numpy as np from nipype.testing import assert_equal from nipype.algorithms.icc import ICC_rep_anova def test_ICC_rep_anova(): #see table 2 in P. E. Shrout & Joseph L. Fleiss (1979). "Intraclass Correlations: Uses in # Assessing Rater Reliability". Psychological Bulletin 86 (2): 420-428 Y = np.array([[9, 2, 5, 8], [6, 1, 3, 2], [8, 4, 6, 8], [7, 1, 2, 6], [10, 5, 6, 9], [6, 2, 4, 7]]) icc, r_var, e_var , _, dfc, dfe = ICC_rep_anova(Y) #see table 4 yield assert_equal, round(icc, 2), 0.71 yield assert_equal, dfc, 3 yield assert_equal, dfe, 15 yield assert_equal, r_var/(r_var + e_var), icc nipype-0.11.0/nipype/algorithms/tests/test_mesh_ops.py000066400000000000000000000040241257611314500231470ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from shutil import rmtree from tempfile import mkdtemp from nipype.testing import (assert_equal, skipif, assert_almost_equal, example_data) import numpy as np from nipype.algorithms import mesh as m notvtk = True import platform if 'darwin' not in platform.system().lower(): try: from tvtk.api import tvtk notvtk = False except ImportError: pass @skipif(notvtk) def test_ident_distances(): tempdir = mkdtemp() curdir = os.getcwd() os.chdir(tempdir) in_surf = example_data('surf01.vtk') dist_ident = m.ComputeMeshWarp() dist_ident.inputs.surface1 = in_surf dist_ident.inputs.surface2 = in_surf dist_ident.inputs.out_file = os.path.join(tempdir, 'distance.npy') res = dist_ident.run() yield assert_equal, res.outputs.distance, 0.0 dist_ident.inputs.weighting = 'area' res = dist_ident.run() yield assert_equal, res.outputs.distance, 0.0 os.chdir(curdir) rmtree(tempdir) @skipif(notvtk) def test_trans_distances(): tempdir = mkdtemp() in_surf = example_data('surf01.vtk') warped_surf = os.path.join(tempdir, 'warped.vtk') curdir = os.getcwd() os.chdir(tempdir) inc = np.array([0.7, 0.3, -0.2]) r1 = tvtk.PolyDataReader(file_name=in_surf) vtk1 = r1.output r1.update() vtk1.points = np.array(vtk1.points) + inc writer = tvtk.PolyDataWriter(file_name=warped_surf) writer.set_input_data(vtk1) writer.write() dist = m.ComputeMeshWarp() dist.inputs.surface1 = in_surf dist.inputs.surface2 = warped_surf dist.inputs.out_file = os.path.join(tempdir, 'distance.npy') res = dist.run() yield assert_almost_equal, res.outputs.distance, np.linalg.norm(inc), 4 dist.inputs.weighting = 'area' res = dist.run() yield assert_almost_equal, res.outputs.distance, np.linalg.norm(inc), 4 os.chdir(curdir) rmtree(tempdir) nipype-0.11.0/nipype/algorithms/tests/test_modelgen.py000066400000000000000000000211231257611314500231230ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from copy import deepcopy import os from shutil import rmtree from tempfile import mkdtemp from nibabel import Nifti1Image import numpy as np from nipype.testing import (assert_equal, assert_raises, assert_almost_equal) from nipype.interfaces.base import Bunch, TraitError from nipype.algorithms.modelgen import (SpecifyModel, SpecifySparseModel, SpecifySPMModel) def test_modelgen1(): tempdir = mkdtemp() filename1 = os.path.join(tempdir, 'test1.nii') filename2 = os.path.join(tempdir, 'test2.nii') Nifti1Image(np.random.rand(10, 10, 10, 200), np.eye(4)).to_filename(filename1) Nifti1Image(np.random.rand(10, 10, 10, 200), np.eye(4)).to_filename(filename2) s = SpecifyModel() s.inputs.input_units = 'scans' set_output_units = lambda: setattr(s.inputs, 'output_units', 'scans') yield assert_raises, TraitError, set_output_units s.inputs.functional_runs = [filename1, filename2] s.inputs.time_repetition = 6 s.inputs.high_pass_filter_cutoff = 128. info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 180]], durations=[[1]], amplitudes=None, pmod=None, regressors=None, regressor_names=None, tmod=None), Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]], amplitudes=None, pmod=None, regressors=None, regressor_names=None, tmod=None)] s.inputs.subject_info = info res = s.run() yield assert_equal, len(res.outputs.session_info), 2 yield assert_equal, len(res.outputs.session_info[0]['regress']), 0 yield assert_equal, len(res.outputs.session_info[0]['cond']), 1 yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['onset']), np.array([12, 300, 600, 1080]) info = [Bunch(conditions=['cond1'], onsets=[[2]], durations=[[1]]), Bunch(conditions=['cond1'], onsets=[[3]], durations=[[1]])] s.inputs.subject_info = deepcopy(info) res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['duration']), np.array([6.]) yield assert_almost_equal, np.array(res.outputs.session_info[1]['cond'][0]['duration']), np.array([6.]) info = [Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2]], durations=[[1, 1], [1]]), Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2, 4]], durations=[[1, 1], [1, 1]])] s.inputs.subject_info = deepcopy(info) s.inputs.input_units = 'scans' res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['duration']), np.array([6., 6.]) yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][1]['duration']), np.array([6.,]) yield assert_almost_equal, np.array(res.outputs.session_info[1]['cond'][1]['duration']), np.array([6., 6.]) rmtree(tempdir) def test_modelgen_spm_concat(): tempdir = mkdtemp() filename1 = os.path.join(tempdir, 'test1.nii') filename2 = os.path.join(tempdir, 'test2.nii') Nifti1Image(np.random.rand(10, 10, 10, 30), np.eye(4)).to_filename(filename1) Nifti1Image(np.random.rand(10, 10, 10, 30), np.eye(4)).to_filename(filename2) # Test case when only one duration is passed, as being the same for all onsets. s = SpecifySPMModel() s.inputs.input_units = 'secs' s.inputs.concatenate_runs = True setattr(s.inputs, 'output_units', 'secs') yield assert_equal, s.inputs.output_units, 'secs' s.inputs.functional_runs = [filename1, filename2] s.inputs.time_repetition = 6 s.inputs.high_pass_filter_cutoff = 128. info = [Bunch(conditions=['cond1'], onsets=[[2, 50, 100, 170]], durations=[[1]]), Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]])] s.inputs.subject_info = deepcopy(info) res = s.run() yield assert_equal, len(res.outputs.session_info), 1 yield assert_equal, len(res.outputs.session_info[0]['regress']), 1 yield assert_equal, np.sum(res.outputs.session_info[0]['regress'][0]['val']), 30 yield assert_equal, len(res.outputs.session_info[0]['cond']), 1 yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['onset']), np.array([2.0, 50.0, 100.0, 170.0, 210.0, 220.0, 280.0, 330.0]) yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['duration']), np.array([1., 1., 1., 1., 1., 1., 1., 1.]) # Test case of scans as output units instead of seconds setattr(s.inputs, 'output_units', 'scans') yield assert_equal, s.inputs.output_units, 'scans' s.inputs.subject_info = deepcopy(info) res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['onset']), np.array([2.0, 50.0, 100.0, 170.0, 210.0, 220.0, 280.0, 330.0])/6 # Test case for no concatenation with seconds as output units s.inputs.concatenate_runs = False s.inputs.subject_info = deepcopy(info) s.inputs.output_units = 'secs' res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['onset']), np.array([2.0, 50.0, 100.0, 170.0]) # Test case for variable number of events in separate runs, sometimes unique. filename3 = os.path.join(tempdir, 'test3.nii') Nifti1Image(np.random.rand(10, 10, 10, 30), np.eye(4)).to_filename(filename3) s.inputs.functional_runs = [filename1, filename2, filename3] info = [Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2]], durations=[[1, 1], [1]]), Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2, 4]], durations=[[1, 1], [1, 1]]), Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2]], durations=[[1, 1], [1]])] s.inputs.subject_info = deepcopy(info) res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['duration']), np.array([1., 1.]) yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][1]['duration']), np.array([1.,]) yield assert_almost_equal, np.array(res.outputs.session_info[1]['cond'][1]['duration']), np.array([1., 1.]) yield assert_almost_equal, np.array(res.outputs.session_info[2]['cond'][1]['duration']), np.array([1.,]) # Test case for variable number of events in concatenated runs, sometimes unique. s.inputs.concatenate_runs = True info = [Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2]], durations=[[1, 1], [1]]), Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2, 4]], durations=[[1, 1], [1, 1]]), Bunch(conditions=['cond1', 'cond2'], onsets=[[2, 3], [2]], durations=[[1, 1], [1]])] s.inputs.subject_info = deepcopy(info) res = s.run() yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][0]['duration']), np.array([1., 1., 1., 1., 1., 1.]) yield assert_almost_equal, np.array(res.outputs.session_info[0]['cond'][1]['duration']), np.array([1., 1., 1., 1.]) rmtree(tempdir) def test_modelgen_sparse(): tempdir = mkdtemp() filename1 = os.path.join(tempdir, 'test1.nii') filename2 = os.path.join(tempdir, 'test2.nii') Nifti1Image(np.random.rand(10, 10, 10, 50), np.eye(4)).to_filename(filename1) Nifti1Image(np.random.rand(10, 10, 10, 50), np.eye(4)).to_filename(filename2) s = SpecifySparseModel() s.inputs.input_units = 'secs' s.inputs.functional_runs = [filename1, filename2] s.inputs.time_repetition = 6 info = [Bunch(conditions=['cond1'], onsets=[[0, 50, 100, 180]], durations=[[2]]), Bunch(conditions=['cond1'], onsets=[[30, 40, 100, 150]], durations=[[1]])] s.inputs.subject_info = info s.inputs.volumes_in_cluster = 1 s.inputs.time_acquisition = 2 s.inputs.high_pass_filter_cutoff = np.inf res = s.run() yield assert_equal, len(res.outputs.session_info), 2 yield assert_equal, len(res.outputs.session_info[0]['regress']), 1 yield assert_equal, len(res.outputs.session_info[0]['cond']), 0 s.inputs.stimuli_as_impulses = False res = s.run() yield assert_equal, res.outputs.session_info[0]['regress'][0]['val'][0], 1.0 s.inputs.model_hrf = True res = s.run() yield assert_almost_equal, res.outputs.session_info[0]['regress'][0]['val'][0], 0.016675298129743384 yield assert_equal, len(res.outputs.session_info[0]['regress']), 1 s.inputs.use_temporal_deriv = True res = s.run() yield assert_equal, len(res.outputs.session_info[0]['regress']), 2 yield assert_almost_equal, res.outputs.session_info[0]['regress'][0]['val'][0], 0.016675298129743384 yield assert_almost_equal, res.outputs.session_info[1]['regress'][1]['val'][5], 0.007671459162258378 rmtree(tempdir) nipype-0.11.0/nipype/algorithms/tests/test_moments.py000066400000000000000000000322441257611314500230210ustar00rootroot00000000000000import numpy as np from nipype.testing import assert_true import tempfile from nipype.algorithms.misc import calc_moments def test_skew(): data = """14.62418305 5.916396751 -1.658088086 4.71113546 1.598428608 5.612553811 -5.004056368 -4.057513911 11.16365251 17.32688599 -3.099920667 2.630189741 2.389709914 0.379332731 -0.2899694205 -4.363591482 2.059205599 23.90705054 0.7180462297 -1.976963652 7.487682025 -5.583986129 1.094800525 -2.319858134 -1.907579712 22.08277347 4.595575886 -3.869054671 8.214834769 -3.442156385 2.428766374 0.7736184662 0.6535290043 14.1320384 0.9458768261 -2.577892846 -0.8925440241 3.177128674 6.048546332 1.736059675 3.149271524 8.106285467 -6.173280371 -0.5146958863 -11.83574747 4.066575201 9.160589786 0.1680632718 3.089673173 8.736851925 -5.624227736 1.386441126 -12.58621755 -0.726443824 8.036414499 -0.3318169666 2.685349599 9.968755255 2.965603277 2.634928414 -3.783441929 -1.858587372 3.238274675 2.594880211 0.870577208 2.323455904 7.840351954 1.635436162 2.451630603 2.834494164 -1.384081764 5.840475644 -4.421008251 -12.78755879 2.985581265 -1.609381512 -0.1816579797 5.448215202 -2.855889998 5.041186537 -8.502455278 -22.66799593 -3.964218147 -4.180363107 -5.061764789 2.439737668 -0.9988071581 1.437142327 -5.355058719 -19.00567875 -4.803737548 -3.884369973 -4.977945181 -0.4758749938 1.894453988 0.003263759218 1.29682909 -8.295173365 -1.51226274 -1.611159469 -2.5403281 -0.2155584519 2.597114132 1.16528519 3.162947556 -3.093405654 0.4782790153 1.015061011 -2.755821487 -1.015685899 0.1402527399 0.05435017236 0.9158883917 -6.679241736 0.9376568982 3.175011335 -2.712383777 -3.836563374 -2.270503748 -4.593165145 0.5468675209 -11.14130502 1.420140475 3.506045445 2.777240829 -3.14187819 -0.7823285883 -6.84663074 -0.5754863055 -9.638785593 0.2926825231 1.039079149 9.613209645 1.300380032 3.755092776 -2.30881605 -9.12095608 -5.422145216 -3.089096046 -1.913969236 8.36828235 1.622740946 6.756285589 4.803793558 -18.6459149 -5.677906762 -4.447399529 -1.826561667 -1.179681537 -3.51737806 6.062770694 7.743917051 -14.12032005 -9.346953111 -0.3927872312 0.5116398162 -8.814603334 -4.191932775 3.735940996 5.926107194 3.984986352 -7.490234063 5.101302343 0.6359344324 -8.098435707 3.372259941 1.603560776 2.787631701 16.74369044 2.523688856 4.825375014 -2.888386026 -2.929939078 7.41176576 -0.9444665519 -0.5476924783 13.0864062 10.44887074 -2.409155335 -6.466987193 2.038766622 -0.9844478726 -3.872608358 -3.903240663 3.888161509 7.356308659 -9.783752602 -6.593576679 7.785360016 -11.59798121 -5.359996968 -4.646576281 2.919034842 0.4926039084 -9.765686304 -3.169484175 13.3885185 -10.00053277 -5.284251069 -1.953467094 7.762685816 3.138596183 -2.417670781 2.087535944 12.09072814 0.3201456619 -5.986630196 -0.393473785 8.598656701 12.64638617 4.32929224 6.665685612 2.52013659 4.924021467 -7.729146671 -2.531538284 4.286211902 12.70121508 4.197284784 7.586579174 -4.511459665 1.039992021 -7.200406996 -2.678018972 -0.206805413 -1.118395095 1.251956053 4.927663964 -0.3269306726 -1.614001868 -2.858296125 3.708027659 -3.615745533 -13.26040515 4.163662563 3.376525012 6.876574727 1.021356663 1.813515644 9.401028448 -6.392625018 -11.19412506 11.70010341 5.557449086 3.188483207 3.033109557 3.108015432 5.00732323 -5.697688304 -1.564055358 12.53451981 6.641295722 -9.330508253 1.60952695 1.985401431 -4.635334005 -0.4739120366 5.308731294 3.209488234 1.907340382 -15.26443399 1.262158357 1.288838724 -6.54661201 3.733208755 11.99608217 -4.121352088 -3.787629919 -8.977806581 3.760241115 1.048439633 -0.2497259139 1.633682769 21.98252106 0.008457593931 -2.863301753 -1.475378656 4.854200462 -0.156717616 2.028483989 -4.262983941 24.73198623 6.529712692 1.286325062 -1.857794734 2.962236297 -1.586154566 -3.6478191 -7.502330557 10.60931417 2.397686502 -1.56459968 -4.721655517 2.006857078 -1.490344215 -7.044842318 -5.198726771 -8.273929595 -7.6127574 -11.03862432 -1.592101433 3.747829535 -0.06779667515 -2.412618507 0.7334095101 -11.76661769 -9.165804187 -14.81298889 5.36362746 4.955331255 1.673488979 2.0899358 5.517823916 -1.529874203 -2.421802273 -6.947139589 8.366593034 3.55375893 4.03335273 -0.05524186477 1.474077483 2.649817521 7.255506458 6.068405441 -2.220943179 -0.6343270953 1.382522916 -2.748044018 -6.776840898 2.855345278 -3.570626044 1.654853143 -2.838161622 0.755210647 7.252510904 1.235575241 -14.86022341 -0.8943548346 -10.36165869 -1.966680076 -3.641426564 -3.670112785 8.644955043 6.859610046 -7.145239483 -0.1458937017 -3.867994525 -0.9484554762 -2.48227248 -8.36071796 2.539637492 5.399990929 8.804929045 1.925551314 3.240568033 1.273961559 2.104351411 -6.141864838 -5.255423549 -0.7896387751 9.735755254 -1.862844212 -2.552156104 -0.3902178948 5.745817797 -1.515932976 -8.546922674 -3.440929455 -5.837957148 -8.226266393 -13.20837554 -4.385043051 2.553090991 -4.209818986 -8.331176217 -1.707250641 -12.64051676 -8.2399894 -12.76990779 -5.960467624 -4.294427772 -10.92374675 -8.6902905 0.3421994093 1.17028221 -1.953361346 -2.607159313 -4.896369845 -4.519583123 -8.055510792 -9.019182555 3.36412153 14.48433641 2.152584104 3.178007658 -3.9792054 3.873546228 5.321306118 -5.445499499 8.684509027 8.116988393 0.4683619278 1.046001596 -3.128586059 10.0250152 12.58326776 1.447856102 10.18164703 -4.706381289 -1.788728553 0.6563335204 -0.5831451131 5.744824049 3.988876139 5.65836796 2.189197844 -2.76704126 -0.495980308 6.533235978 2.372759856 -2.792331174 -7.896310272 3.502571539 -8.556072249 8.315654337 0.7043190657 11.38508989 2.565286445 -5.081739754 -6.900720718 -1.667312154 -10.59024727 9.909297104 -2.934946689 8.968652164 -0.5610029798 -0.6957945725 3.815352939 -4.277309457 -4.346939024 3.809478921 -8.178727502 2.78966603 -4.568498377 3.295953611 9.457549108 -2.931773943 -0.04922082646 4.940986376 -6.906199411 -0.6726182267 -6.550149966 3.251783239 6.324220141 0.1496185048 -1.7701633 10.55846735 1.720423345 -0.02248084003 -4.475053837 0.3943175795 3.615274407 3.17786214 -4.661015894 5.164991215 7.975239079 2.030845129 1.259865261 -3.543706118 6.424886561 5.257164014 -5.686755714 -7.85360929 4.585684687 2.641661508 6.399259194 -5.791994946 9.620021677 5.059618162 -5.841773643 -7.887333445 -1.663863126 0.531225876 6.442066641 -2.580841985 8.356612294 2.609875283 -3.391732494 7.467417207 0.7346301535 -2.719728468 2.822035284 4.54698989 4.221046784 0.791568596 3.728706407 14.76100347 9.382305581 -3.17219641 1.381585183 7.754995237 -0.3908054543 1.355349478 9.807914939 0.1267792801 9.818588278 0.5608772817 3.633460684 3.711951896 -5.421004876 1.162611597 7.001274262 -19.35283277 -2.103358718 4.16130701 4.67192889 -0.8231375514 -8.81474386 -2.846417531 -1.268859264 -20.80038431 -11.76135621 2.944594891 1.64388247 -0.1668629943 -6.707442921 -6.544901517 -3.830974298 -5.592905106 -6.057725588 -1.233208621 -1.339964983 0.7299911265 -0.7530015377 -3.117175727 1.142381884 7.890421323 8.119524766 -2.606602104 0.007101965698 -4.473969864 1.35750371 5.357618774 4.161238035 9.600782899 14.52365435 0.1990637024 3.403466406 -11.59507852 -3.675154543 8.718678202 0.7825822225 3.703846665 8.748127367 3.135332804 4.127582534 -12.38852274 -9.447080613 3.417599727 -1.915488323 -3.011725724 -0.5381126202 3.567929983 2.184591464 -7.411651508 -9.252946446 -1.827784625 1.560496584 -7.142629796 -5.355184696 3.289780212 1.113331632 -3.105505654 -5.606446238 0.1961208934 6.334603712 -6.659543803 -4.245675975 3.726757782 1.953178495 -0.7484610023 -4.426403774 3.716311729 6.200735049 -1.643440395 0.7536090906 2.509268017 2.15471156 2.374200456 -3.774138064 -0.1428981969 2.646676328 3.686406766 4.827058909 -2.458101484 -0.39559615 5.082577298 3.167157352 -8.147321924 -0.03506891856 4.407495284 2.5606793 -8.149493446 -4.632729429 4.938050013 14.56344531 -9.374945991 -1.3893417 -0.1687177084 -4.106757231 -9.343602374 -7.415904922 4.749022091 18.81314153 -1.749200795 -2.02566815 -6.507688641 -6.001538055 -6.108916568 -6.784929595 7.21051134 10.59847744 5.776257506 -0.4990570991 -9.820082348 -0.5741078285 -4.687969138 -4.377866052 7.40862329 -0.06470407472 6.857336593 2.745243336 -7.04365894 2.689020958 -8.804350547 -3.506610093 0.5732906688 -1.771827007 4.332768659 3.537426733 -0.4346222942 -2.295147419 -12.91289393 -3.95705062 -7.130741497 1.478867856 2.340197798 -0.2224791818 2.355519667 -7.446912611 -8.580935982 -1.515500603 -6.545362285 -2.460234117 0.4822626914 -5.261252431 -3.230857748 -4.456435972 3.105258325 4.868182005 -0.3155725672 -12.9461276 -1.81314629 -7.915543953 -10.61694158 1.023409988 11.23695246 9.13393953 2.080132446 -15.68433051 -2.452603277 -8.067702457 -8.952785439 0.3914623321 9.072213866 5.788054925 0.5661677477 -4.862572943 -1.253393229 -6.497656047 1.825216246 -2.868761361 2.684946057 -1.702605515 2.524615008 6.658427102 -1.464383881 -3.333412097 10.52499456 -1.807928838 1.602770946 -5.693835167 7.025193015 6.172728664 -3.989160551 -0.7754719889 10.83430082 0.3010957187 5.703164372 -4.7215044 5.747620411 -0.6137370397 -5.393253651 -1.967790019 9.084992271 -1.297359974 7.313272774 -2.919262371 -0.341939585 -0.488964096 -3.962652217 -5.129527247 11.86896398 -0.4901633845 3.193953846 -1.811431925 -0.3604987261 6.192234507 -2.348495577 -4.159036411 14.81736012 7.870835671 -2.04922723 0.122245812 7.807201578 8.435263453 -1.994392703 2.494961459 10.99679669 13.62141018 -3.175917696 1.68947873 12.43613872 4.131979444 -0.8035598171 8.583091116 3.538171963 6.008200439 0.5876902994 0.4403643142 6.183013749 2.012581919 1.090536757 8.392496526 0.5460594103 -6.259032909 6.647104433 -1.43557129 -3.452884137 4.366160275 -0.2274303705 3.900139848 1.772017802 -8.109091085 10.50095909 -0.1621391129 -7.608906136 2.481208401 -4.509906047 0.7763248812 0.606115406 -2.603199426 7.692974034 2.104967053 -8.226098406 -6.837921596 -4.561655055 1.015397953 -2.978847372 -2.385761908 -0.8339871055 0.6707971346 -9.874595181 -13.39338209 3.157380259 2.413897035 -2.985013991 -5.160444086 -7.29279473 -2.371762765 -10.03622895 -9.34912711 10.97609581 2.654665151 -1.068091568 -0.2479914452 -6.107351633 -0.9239821871 -5.835733231 -2.189236707 9.811317248 1.508754364 -6.520427038 7.430392097 -1.95095948 4.15525371 -2.032963385 -2.693509918 2.091753969 0.4782648423 -18.09299987 4.740223292 -2.838854108 6.118069011 -3.664423954 -7.91518773 -2.533067915 1.120941519 -19.32711056 -3.231687054 -8.04776777 3.689162869 -6.952885159 -6.854774161 -1.172264884 2.581894309 -2.203996345 -0.5339747203 -10.27858531 1.833505163 -5.406679162 1.678416611 0.871971912 1.837113402 15.60657966 8.749980935 -7.560269196 1.70515063 0.1003191195 8.04135078 1.044572756 -1.582641946 12.19564564 5.273436246 -4.367517279 -0.0400759142 4.431313549 7.067826794 2.741622337 -3.458851463 -6.44120462 -9.849684434 -1.946651925 -2.183436603 6.686267514 4.016449169 6.302612811 -0.9698019507 -13.80878408 -13.92578887 3.071419193 -0.156449455 8.551444945 4.051266929 5.541317929 1.901010931 -1.084801367 -1.267516734 9.774222689 3.461150291 8.195043157 4.77412064 -2.223359889 0.07143463336 11.95939854 7.195316999 11.93418631 1.472618288 3.247038347 2.656123844 -9.091445458 -4.097157466 -2.752420619 -1.103781682 -3.382675846 -3.9326499 0.3168555978 -2.600573426 -9.409987851 -1.564842317 -11.68718367 -12.62978052 -7.436711849 -11.05071165 -4.535693861 -4.973062537 -9.154275121 -0.8478464554 -11.1129098 -8.014294516 -5.818564146 -6.557508409 -4.920322355 -2.444494132 -0.762850219 -1.035995467 -0.1942650118 5.507757423 -0.6713848498 2.045539379 0.2907563314 2.654730384 5.268838031 -2.711154892 6.638825325 9.118078409 2.220738816 5.875202986 0.6059672284 -5.305207318 -0.08004872831 -2.950039659 12.18704972 0.6256114468 2.352153233 8.701077613 4.804756766 -6.163162012 -1.779998967 -6.493561445 4.442326811 -15.10908307 4.919949591 3.969210961 7.004029439 0.1398435001 -4.659976897 -3.899267451 -7.594265524 -20.77328745 5.94521557 -2.385814065 3.224509406 8.943882025 -3.270587613 3.470325906 -8.696673766 -12.29052026 -0.3763403003 -5.55470641 -3.51572569 12.51259902 3.753517263 8.67338497 -0.5057854071 -2.415896554 -9.663571931 -5.714041661 -6.037933426 8.673756933 10.03557773 8.629816199 3.622185659 0.4716627142 -10.92515308 -3.705286841 -2.776089545 2.271920902 9.251504922 5.744980887 """ with tempfile.NamedTemporaryFile(delete=True) as f: f.write(data) f.flush() skewness = calc_moments(f.name, 3) yield assert_true, np.allclose(skewness, np.array( [-0.23418937314622, 0.2946365564954823, -0.05781002053540932, -0.3512508282578762, - 0.07035664150233077, - 0.01935867699166935, 0.00483863369427428, 0.21879460029850167])) nipype-0.11.0/nipype/algorithms/tests/test_normalize_tpms.py000066400000000000000000000031021257611314500243710ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from shutil import rmtree from tempfile import mkdtemp from nipype.testing import (assert_equal,assert_raises, assert_almost_equal,example_data ) import numpy as np import nibabel as nb import nipype.testing as nit from nipype.algorithms.misc import normalize_tpms def test_normalize_tpms(): tempdir = mkdtemp() in_mask = example_data('tpms_msk.nii.gz' ) mskdata = nb.load( in_mask ).get_data() mskdata[mskdata>0.0] = 1.0 mapdata = [] in_files = [] out_files = [] for i in range(3): mapname = example_data('tpm_%02d.nii.gz' % i) filename = os.path.join(tempdir, 'modtpm_%02d.nii.gz' % i ) out_files.append(os.path.join(tempdir, 'normtpm_%02d.nii.gz' % i )) im = nb.load(mapname) data = im.get_data() mapdata.append( data.copy() ) nb.Nifti1Image(2.0 * (data * mskdata), im.get_affine(), im.get_header() ).to_filename(filename) in_files.append( filename ) normalize_tpms( in_files, in_mask, out_files=out_files ) sumdata = np.zeros_like(mskdata) for i,tstfname in enumerate( out_files ): normdata = nb.load( tstfname ).get_data() sumdata+=normdata yield assert_equal, np.all( normdata[mskdata==0]==0 ), True yield assert_equal, np.allclose( normdata, mapdata[i] ), True yield assert_equal, np.allclose(sumdata[sumdata>0.0], 1.0 ), True rmtree(tempdir) nipype-0.11.0/nipype/algorithms/tests/test_overlap.py000066400000000000000000000024611257611314500230050ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from shutil import rmtree from tempfile import mkdtemp from nipype.testing import (example_data) import numpy as np def test_overlap(): from nipype.algorithms.metrics import Overlap def check_close(val1, val2): import numpy.testing as npt return npt.assert_almost_equal(val1, val2, decimal=3) tempdir = mkdtemp() in1 = example_data('segmentation0.nii.gz') in2 = example_data('segmentation1.nii.gz') cwd = os.getcwd() os.chdir(tempdir) overlap = Overlap() overlap.inputs.volume1 = in1 overlap.inputs.volume2 = in1 res = overlap.run() yield check_close, res.outputs.jaccard, 1.0 overlap = Overlap() overlap.inputs.volume1 = in1 overlap.inputs.volume2 = in2 res = overlap.run() yield check_close, res.outputs.jaccard, 0.99705 overlap = Overlap() overlap.inputs.volume1 = in1 overlap.inputs.volume2 = in2 overlap.inputs.vol_units = 'mm' res = overlap.run() yield check_close, res.outputs.jaccard, 0.99705 yield (check_close, res.outputs.roi_voldiff, np.array([0.0063086, -0.0025506, 0.0])) os.chdir(cwd) rmtree(tempdir) nipype-0.11.0/nipype/algorithms/tests/test_rapidart.py000066400000000000000000000065131257611314500231450ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import numpy as np from ...testing import (assert_equal, assert_false, assert_true, assert_almost_equal) from .. import rapidart as ra from ...interfaces.base import Bunch def test_ad_init(): ad = ra.ArtifactDetect(use_differences=[True, False]) yield assert_true, ad.inputs.use_differences[0] yield assert_false, ad.inputs.use_differences[1] def test_ad_output_filenames(): ad = ra.ArtifactDetect() outputdir = '/tmp' f = 'motion.nii' (outlierfile, intensityfile, statsfile, normfile, plotfile, displacementfile, maskfile) = ad._get_output_filenames(f, outputdir) yield assert_equal, outlierfile, '/tmp/art.motion_outliers.txt' yield assert_equal, intensityfile, '/tmp/global_intensity.motion.txt' yield assert_equal, statsfile, '/tmp/stats.motion.txt' yield assert_equal, normfile, '/tmp/norm.motion.txt' yield assert_equal, plotfile, '/tmp/plot.motion.png' yield assert_equal, displacementfile, '/tmp/disp.motion.nii' yield assert_equal, maskfile, '/tmp/mask.motion.nii' def test_ad_get_affine_matrix(): matrix = ra._get_affine_matrix(np.array([0]), 'SPM') yield assert_equal, matrix, np.eye(4) # test translation params = [1, 2, 3] matrix = ra._get_affine_matrix(params, 'SPM') out = np.eye(4) out[0:3, 3] = params yield assert_equal, matrix, out # test rotation params = np.array([0, 0, 0, np.pi / 2, np.pi / 2, np.pi / 2]) matrix = ra._get_affine_matrix(params, 'SPM') out = np.array([0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1]).reshape((4, 4)) yield assert_almost_equal, matrix, out # test scaling params = np.array([0, 0, 0, 0, 0, 0, 1, 2, 3]) matrix = ra._get_affine_matrix(params, 'SPM') out = np.array([1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1]).reshape((4, 4)) yield assert_equal, matrix, out # test shear params = np.array([0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 3]) matrix = ra._get_affine_matrix(params, 'SPM') out = np.array([1, 1, 2, 0, 0, 1, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1]).reshape((4, 4)) yield assert_equal, matrix, out def test_ad_get_norm(): params = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0, np.pi / 4, np.pi / 4, np.pi / 4, 0, 0, 0, -np.pi / 4, -np.pi / 4, -np.pi / 4]).reshape((3, 6)) norm, _ = ra._calc_norm(params, False, 'SPM') yield assert_almost_equal, norm, np.array([18.86436316, 37.74610158, 31.29780829]) norm, _ = ra._calc_norm(params, True, 'SPM') yield assert_almost_equal, norm, np.array([0., 143.72192614, 173.92527131]) def test_sc_init(): sc = ra.StimulusCorrelation(concatenated_design=True) yield assert_true, sc.inputs.concatenated_design def test_sc_populate_inputs(): sc = ra.StimulusCorrelation() inputs = Bunch(realignment_parameters=None, intensity_values=None, spm_mat_file=None, concatenated_design=None) yield assert_equal, sc.inputs.__dict__.keys(), inputs.__dict__.keys() def test_sc_output_filenames(): sc = ra.StimulusCorrelation() outputdir = '/tmp' f = 'motion.nii' corrfile = sc._get_output_filenames(f, outputdir) yield assert_equal, corrfile, '/tmp/qa.motion_stimcorr.txt' nipype-0.11.0/nipype/algorithms/tests/test_splitmerge.py000066400000000000000000000021261257611314500235060ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- from shutil import rmtree from tempfile import mkdtemp from nipype.testing import (assert_equal, example_data) def test_split_and_merge(): import numpy as np import nibabel as nb import os.path as op import os cwd = os.getcwd() from nipype.algorithms.misc import split_rois, merge_rois tmpdir = mkdtemp() in_mask = example_data('tpms_msk.nii.gz') dwfile = op.join(tmpdir, 'dwi.nii.gz') mskdata = nb.load(in_mask).get_data() aff = nb.load(in_mask).get_affine() dwshape = (mskdata.shape[0], mskdata.shape[1], mskdata.shape[2], 6) dwdata = np.random.normal(size=dwshape) os.chdir(tmpdir) nb.Nifti1Image(dwdata.astype(np.float32), aff, None).to_filename(dwfile) resdw, resmsk, resid = split_rois(dwfile, in_mask, roishape=(20, 20, 2)) merged = merge_rois(resdw, resid, in_mask) dwmerged = nb.load(merged).get_data() dwmasked = dwdata * mskdata[:, :, :, np.newaxis] os.chdir(cwd) rmtree(tmpdir) yield assert_equal, np.allclose(dwmasked, dwmerged), True nipype-0.11.0/nipype/caching/000077500000000000000000000000001257611314500160025ustar00rootroot00000000000000nipype-0.11.0/nipype/caching/__init__.py000066400000000000000000000000521257611314500201100ustar00rootroot00000000000000from nipype.caching.memory import Memory nipype-0.11.0/nipype/caching/memory.py000066400000000000000000000252471257611314500176760ustar00rootroot00000000000000""" Using nipype with persistence and lazy recomputation but without explicit name-steps pipeline: getting back scope in command-line based programming. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ import os import hashlib import pickle import time import shutil import glob from nipype.interfaces.base import BaseInterface from nipype.pipeline.engine import Node from nipype.pipeline.utils import modify_paths ################################################################################ # PipeFunc object: callable interface to nipype.interface objects class PipeFunc(object): """ Callable interface to nipype.interface objects Use this to wrap nipype.interface object and call them specifying their input with keyword arguments:: fsl_merge = PipeFunc(fsl.Merge, base_dir='.') out = fsl_merge(in_files=files, dimension='t') """ def __init__(self, interface, base_dir, callback=None): """ Parameters =========== interface: a nipype interface class The interface class to wrap base_dir: a string The directory in which the computation will be stored callback: a callable An optional callable called each time after the function is called. """ if not (isinstance(interface, type) and issubclass(interface, BaseInterface)): raise ValueError('the interface argument should be a nipype ' 'interface class, but %s (type %s) was passed.' % (interface, type(interface))) self.interface = interface base_dir = os.path.abspath(base_dir) if not os.path.exists(base_dir) and os.path.isdir(base_dir): raise ValueError('base_dir should be an existing directory') self.base_dir = base_dir doc = '%s\n%s' % (self.interface.__doc__, self.interface.help(returnhelp=True)) self.__doc__ = doc self.callback = callback def __call__(self, **kwargs): kwargs = modify_paths(kwargs, relative=False) interface = self.interface() # Set the inputs early to get some argument checking interface.inputs.set(**kwargs) # Make a name for our node inputs = interface.inputs.get_hashval() hasher = hashlib.new('md5') hasher.update(pickle.dumps(inputs)) dir_name = '%s-%s' % (interface.__class__.__module__.replace('.', '-'), interface.__class__.__name__) job_name = hasher.hexdigest() node = Node(interface, name=job_name) node.base_dir = os.path.join(self.base_dir, dir_name) cwd = os.getcwd() try: out = node.run() finally: # node.run() changes to the node directory - if something goes wrong # before it cds back you would end up in strange places os.chdir(cwd) if self.callback is not None: self.callback(dir_name, job_name) return out def __repr__(self): return '%s(%s.%s, base_dir=%s)' % (self.__class__.__name__, self.interface.__module__, self.interface.__name__, self.base_dir) ################################################################################ # Memory manager: provide some tracking about what is computed when, to # be able to flush the disk def read_log(filename, run_dict=None): if run_dict is None: run_dict = dict() for line in open(filename, 'r'): dir_name, job_name = line[:-1].split('/') jobs = run_dict.get(dir_name, set()) jobs.add(job_name) run_dict[dir_name] = jobs return run_dict def rm_all_but(base_dir, dirs_to_keep, warn=False): """ Remove all the sub-directories of base_dir, but those listed Parameters ============ base_dir: string The base directory dirs_to_keep: set The names of the directories to keep """ try: all_dirs = os.listdir(base_dir) except OSError: "Dir has been deleted" return all_dirs = [d for d in all_dirs if not d.startswith('log.')] dirs_to_rm = list(dirs_to_keep.symmetric_difference(all_dirs)) for dir_name in dirs_to_rm: dir_name = os.path.join(base_dir, dir_name) if os.path.exists(dir_name): if warn: print 'removing directory: %s' % dir_name shutil.rmtree(dir_name) class _MemoryCallback(object): "An object to avoid closures and have everything pickle" def __init__(self, memory): self.memory = memory def __call__(self, dir_name, job_name): self.memory._log_name(dir_name, job_name) class Memory(object): """ Memory context to provide caching for interfaces Parameters ========== base_dir: string The directory name of the location for the caching Methods ======= cache Creates a cacheable function from an nipype Interface class clear_previous_runs Removes from the disk all the runs that where not used after the creation time of the specific Memory instance clear_previous_runs Removes from the disk all the runs that where not used after the given time """ def __init__(self, base_dir): base_dir = os.path.join(os.path.abspath(base_dir), 'nipype_mem') if not os.path.exists(base_dir): os.mkdir(base_dir) elif not os.path.isdir(base_dir): raise ValueError('base_dir should be a directory') self.base_dir = base_dir open(os.path.join(base_dir, 'log.current'), 'w') def cache(self, interface): """ Returns a callable that caches the output of an interface Parameters ========== interface: nipype interface The nipype interface class to be wrapped and cached Returns ======= pipe_func: a PipeFunc callable object An object that can be used as a function to apply the interface to arguments. Inputs of the interface are given as keyword arguments, bearing the same name as the name in the inputs specs of the interface. Examples ======== >>> from tempfile import mkdtemp >>> mem = Memory(mkdtemp()) >>> from nipype.interfaces import fsl Here we create a callable that can be used to apply an fsl.Merge interface to files >>> fsl_merge = mem.cache(fsl.Merge) Now we apply it to a list of files. We need to specify the list of input files and the dimension along which the files should be merged. >>> results = fsl_merge(in_files=['a.nii', 'b.nii'], ... dimension='t') # doctest: +SKIP We can retrieve the resulting file from the outputs: >>> results.outputs.merged_file # doctest: +SKIP '...' """ return PipeFunc(interface, self.base_dir, _MemoryCallback(self)) def _log_name(self, dir_name, job_name): """ Increment counters tracking which cached function get executed. """ base_dir = self.base_dir # Every counter is a file opened in append mode and closed # immediately to avoid race conditions in parallel computing: # file appends are atomic open(os.path.join(base_dir, 'log.current'), 'a').write('%s/%s\n' % (dir_name, job_name)) t = time.localtime() year_dir = os.path.join(base_dir, 'log.%i' % t.tm_year) try: os.mkdir(year_dir) except OSError: "Dir exists" month_dir = os.path.join(year_dir, '%02i' % t.tm_mon) try: os.mkdir(month_dir) except OSError: "Dir exists" open(os.path.join(month_dir, '%02i.log' % t.tm_mday), 'a').write('%s/%s\n' % (dir_name, job_name)) def clear_previous_runs(self, warn=True): """ Remove all the cache that where not used in the latest run of the memory object: i.e. since the corresponding Python object was created. Parameters ========== warn: boolean, optional If true, echoes warning messages for all directory removed """ base_dir = self.base_dir latest_runs = read_log(os.path.join(base_dir, 'log.current')) self._clear_all_but(latest_runs, warn=warn) def clear_runs_since(self, day=None, month=None, year=None, warn=True): """ Remove all the cache that where not used since the given date Parameters ========== day, month, year: integers, optional The integers specifying the latest day (in localtime) that a node should have been accessed to be kept. If not given, the current date is used. warn: boolean, optional If true, echoes warning messages for all directory removed """ t = time.localtime() day = day if day is not None else t.tm_mday month = month if month is not None else t.tm_mon year = year if year is not None else t.tm_year base_dir = self.base_dir cut_off_file = '%s/log.%i/%02i/%02i.log' % (base_dir, year, month, day) logs_to_flush = list() recent_runs = dict() for log_name in glob.glob('%s/log.*/*/*.log' % base_dir): if log_name < cut_off_file: logs_to_flush.append(log_name) else: recent_runs = read_log(log_name, recent_runs) self._clear_all_but(recent_runs, warn=warn) for log_name in logs_to_flush: os.remove(log_name) def _clear_all_but(self, runs, warn=True): """ Remove all the runs appart from those given to the function input. """ rm_all_but(self.base_dir, set(runs.keys()), warn=warn) for dir_name, job_names in runs.iteritems(): rm_all_but(os.path.join(self.base_dir, dir_name), job_names, warn=warn) def __repr__(self): return '%s(base_dir=%s)' % (self.__class__.__name__, self.base_dir) nipype-0.11.0/nipype/caching/tests/000077500000000000000000000000001257611314500171445ustar00rootroot00000000000000nipype-0.11.0/nipype/caching/tests/__init__.py000066400000000000000000000000001257611314500212430ustar00rootroot00000000000000nipype-0.11.0/nipype/caching/tests/test_memory.py000066400000000000000000000030371257611314500220700ustar00rootroot00000000000000""" Test the nipype interface caching mechanism """ from tempfile import mkdtemp from shutil import rmtree from nose.tools import assert_equal from .. import Memory from ...pipeline.tests.test_engine import TestInterface from ... import config config.set_default_config() nb_runs = 0 class SideEffectInterface(TestInterface): def _run_interface(self, runtime): global nb_runs nb_runs += 1 runtime.returncode = 0 return runtime def test_caching(): temp_dir = mkdtemp(prefix='test_memory_') old_rerun = config.get('execution', 'stop_on_first_rerun') try: # Prevent rerun to check that evaluation is computed only once config.set('execution', 'stop_on_first_rerun', 'true') mem = Memory(temp_dir) first_nb_run = nb_runs results = mem.cache(SideEffectInterface)(input1=2, input2=1) assert_equal(nb_runs, first_nb_run + 1) assert_equal(results.outputs.output1, [1, 2]) results = mem.cache(SideEffectInterface)(input1=2, input2=1) # Check that the node hasn't been rerun assert_equal(nb_runs, first_nb_run + 1) assert_equal(results.outputs.output1, [1, 2]) results = mem.cache(SideEffectInterface)(input1=1, input2=1) # Check that the node hasn been rerun assert_equal(nb_runs, first_nb_run + 2) assert_equal(results.outputs.output1, [1, 1]) finally: rmtree(temp_dir) config.set('execution', 'stop_on_first_rerun', old_rerun) if __name__ == '__main__': test_caching() nipype-0.11.0/nipype/external/000077500000000000000000000000001257611314500162305ustar00rootroot00000000000000nipype-0.11.0/nipype/external/__init__.py000066400000000000000000000000001257611314500203270ustar00rootroot00000000000000nipype-0.11.0/nipype/external/cloghandler.py000066400000000000000000000353571257611314500211010ustar00rootroot00000000000000# Copyright 2008 Lowell Alleman # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy # of the License at http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. """ cloghandler.py: A smart replacement for the standard RotatingFileHandler ConcurrentRotatingFileHandler: This class is a log handler which is a drop-in replacement for the python standard log handler 'RotateFileHandler', the primary difference being that this handler will continue to write to the same file if the file cannot be rotated for some reason, whereas the RotatingFileHandler will strictly adhere to the maximum file size. Unfortunately, if you are using the RotatingFileHandler on Windows, you will find that once an attempted rotation fails, all subsequent log messages are dropped. The other major advantage of this module is that multiple processes can safely write to a single log file. To put it another way: This module's top priority is preserving your log records, whereas the standard library attempts to limit disk usage, which can potentially drop log messages. If you are trying to determine which module to use, there are number of considerations: What is most important: strict disk space usage or preservation of log messages? What OSes are you supporting? Can you afford to have processes blocked by file locks? Concurrent access is handled by using file locks, which should ensure that log messages are not dropped or clobbered. This means that a file lock is acquired and released for every log message that is written to disk. (On Windows, you may also run into a temporary situation where the log file must be opened and closed for each log message.) This can have potentially performance implications. In my testing, performance was more than adequate, but if you need a high-volume or low-latency solution, I suggest you look elsewhere. This module currently only support the 'nt' and 'posix' platforms due to the usage of the portalocker module. I do not have access to any other platforms for testing, patches are welcome. See the README file for an example usage of this module. """ __version__ = "$Id: cloghandler.py 6175 2009-11-02 18:40:35Z lowell $" __author__ = "Lowell Alleman" __all__ = [ "ConcurrentRotatingFileHandler", ] import os import sys from random import randint from logging import Handler from logging.handlers import BaseRotatingHandler try: import codecs except ImportError: codecs = None # Question/TODO: Should we have a fallback mode if we can't load portalocker / # we should still be better off than with the standard RotattingFileHandler # class, right? We do some rename checking... that should prevent some file # clobbering that the builtin class allows. # sibling module than handles all the ugly platform-specific details of file locking from .portalocker import lock, unlock, LOCK_EX, LOCK_NB, LockException # A client can set this to true to automatically convert relative paths to # absolute paths (which will also hide the absolute path warnings) FORCE_ABSOLUTE_PATH = False class ConcurrentRotatingFileHandler(BaseRotatingHandler): """ Handler for logging to a set of files, which switches from one file to the next when the current file reaches a certain size. Multiple processes can write to the log file concurrently, but this may mean that the file will exceed the given size. """ def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, debug=True, supress_abs_warn=False): """ Open the specified file and use it as the stream for logging. By default, the file grows indefinitely. You can specify particular values of maxBytes and backupCount to allow the file to rollover at a predetermined size. Rollover occurs whenever the current log file is nearly maxBytes in length. If backupCount is >= 1, the system will successively create new files with the same pathname as the base file, but with extensions ".1", ".2" etc. appended to it. For example, with a backupCount of 5 and a base file name of "app.log", you would get "app.log", "app.log.1", "app.log.2", ... through to "app.log.5". The file being written to is always "app.log" - when it gets filled up, it is closed and renamed to "app.log.1", and if files "app.log.1", "app.log.2" etc. exist, then they are renamed to "app.log.2", "app.log.3" etc. respectively. If maxBytes is zero, rollover never occurs. On Windows, it is not possible to rename a file that is currently opened by another process. This means that it is not possible to rotate the log files if multiple processes is using the same log file. In this case, the current log file will continue to grow until the rotation can be completed successfully. In order for rotation to be possible, all of the other processes need to close the file first. A mechanism, called "degraded" mode, has been created for this scenario. In degraded mode, the log file is closed after each log message is written. So once all processes have entered degraded mode, the next rotate log attempt should be successful and then normal logging can be resumed. This log handler assumes that all concurrent processes logging to a single file will are using only this class, and that the exact same parameters are provided to each instance of this class. If, for example, two different processes are using this class, but with different values for 'maxBytes' or 'backupCount', then odd behavior is expected. The same is true if this class is used by one application, but the RotatingFileHandler is used by another. NOTE: You should always provide 'filename' as an absolute path, since this class will need to re-open the file during rotation. If your application call os.chdir() then subsequent log files could be created in the wrong directory. """ # The question of absolute paths: I'm not sure what the 'right thing' is # to do here. RotatingFileHander simply ignores this possibility. I was # going call os.path.abspath(), but that potentially limits uses. For # example, on Linux (any posix system?) you can rename a directory of a # running app, and the app wouldn't notice as long as it only opens new # files using relative paths. But since that's not a "normal" thing to # do, and having an app call os.chdir() is a much more likely scenario # that should be supported. For the moment, we are just going to warn # the user if they provide a relative path and do some other voodoo # logic that you'll just have to review for yourself. # if the given filename contains no path, we make an absolute path if not os.path.isabs(filename): if FORCE_ABSOLUTE_PATH or \ not os.path.split(filename)[0]: filename = os.path.abspath(filename) elif not supress_abs_warn: from warnings import warn warn("The given 'filename' should be an absolute path. If your " "application calls os.chdir(), your logs may get messed up. " "Use 'supress_abs_warn=True' to hide this message.") try: BaseRotatingHandler.__init__(self, filename, mode, encoding) except TypeError: # Due to a different logging release without encoding support (Python 2.4.1 and earlier?) BaseRotatingHandler.__init__(self, filename, mode) self.encoding = encoding self._rotateFailed = False self.maxBytes = maxBytes self.backupCount = backupCount # Prevent multiple extensions on the lock file (Only handles the normal "*.log" case.) if filename.endswith(".log"): lock_file = filename[:-4] else: lock_file = filename self.stream_lock = open(lock_file + ".lock", "w") # For debug mode, swap out the "_degrade()" method with a more a verbose one. if debug: self._degrade = self._degrade_debug def _openFile(self, mode): if self.encoding: self.stream = codecs.open(self.baseFilename, mode, self.encoding) else: self.stream = open(self.baseFilename, mode) def acquire(self): """ Acquire thread and file locks. Also re-opening log file when running in 'degraded' mode. """ # handle thread lock Handler.acquire(self) lock(self.stream_lock, LOCK_EX) if self.stream.closed: self._openFile(self.mode) def release(self): """ Release file and thread locks. Flush stream and take care of closing stream in 'degraded' mode. """ try: if not self.stream.closed: self.stream.flush() if self._rotateFailed: self.stream.close() except IOError: if self._rotateFailed: self.stream.close() finally: try: unlock(self.stream_lock) finally: # release thread lock Handler.release(self) def close(self): """ Closes the stream. """ if not self.stream.closed: self.stream.flush() self.stream.close() Handler.close(self) def flush(self): """ flush(): Do nothing. Since a flush is issued in release(), we don't do it here. To do a flush here, it would be necessary to re-lock everything, and it is just easier and cleaner to do it all in release(), rather than requiring two lock ops per handle() call. Doing a flush() here would also introduces a window of opportunity for another process to write to the log file in between calling stream.write() and stream.flush(), which seems like a bad thing. """ pass def _degrade(self, degrade, msg, *args): """ Set degrade mode or not. Ignore msg. """ self._rotateFailed = degrade del msg, args # avoid pychecker warnings def _degrade_debug(self, degrade, msg, *args): """ A more colorful version of _degade(). (This is enabled by passing "debug=True" at initialization). """ if degrade: if not self._rotateFailed: sys.stderr.write("Degrade mode - ENTERING - (pid=%d) %s\n" % (os.getpid(), msg % args)) self._rotateFailed = True else: if self._rotateFailed: sys.stderr.write("Degrade mode - EXITING - (pid=%d) %s\n" % (os.getpid(), msg % args)) self._rotateFailed = False def doRollover(self): """ Do a rollover, as described in __init__(). """ if self.backupCount <= 0: # Don't keep any backups, just overwrite the existing backup file # Locking doesn't much matter here; since we are overwriting it anyway self.stream.close() self._openFile("w") return self.stream.close() try: # Attempt to rename logfile to tempname: There is a slight race-condition here, but it seems unavoidable tmpname = None while not tmpname or os.path.exists(tmpname): tmpname = "%s.rotate.%08d" % (self.baseFilename, randint(0,99999999)) try: # Do a rename test to determine if we can successfully rename the log file os.rename(self.baseFilename, tmpname) except (IOError, OSError): exc_value = sys.exc_info()[1] self._degrade(True, "rename failed. File in use? " "exception=%s", exc_value) return # Q: Is there some way to protect this code from a KeboardInterupt? # This isn't necessarily a data loss issue, but it certainly would # break the rotation process during my stress testing. # There is currently no mechanism in place to handle the situation # where one of these log files cannot be renamed. (Example, user # opens "logfile.3" in notepad) for i in range(self.backupCount - 1, 0, -1): sfn = "%s.%d" % (self.baseFilename, i) dfn = "%s.%d" % (self.baseFilename, i + 1) if os.path.exists(sfn): #print "%s -> %s" % (sfn, dfn) if os.path.exists(dfn): os.remove(dfn) os.rename(sfn, dfn) dfn = self.baseFilename + ".1" if os.path.exists(dfn): os.remove(dfn) os.rename(tmpname, dfn) #print "%s -> %s" % (self.baseFilename, dfn) self._degrade(False, "Rotation completed") finally: self._openFile(self.mode) def shouldRollover(self, record): """ Determine if rollover should occur. For those that are keeping track. This differs from the standard library's RotatingLogHandler class. Because there is no promise to keep the file size under maxBytes we ignore the length of the current record. """ del record # avoid pychecker warnings if self._shouldRollover(): # if some other process already did the rollover we might # checked log.1, so we reopen the stream and check again on # the right log file self.stream.close() self._openFile(self.mode) return self._shouldRollover() return False def _shouldRollover(self): if self.maxBytes > 0: # are we rolling over? try: self.stream.seek(0, 2) #due to non-posix-compliant Windows feature except IOError: return True if self.stream.tell() >= self.maxBytes: return True else: self._degrade(False, "Rotation done or not needed at this time") return False # Publish this class to the "logging.handlers" module so that it can be use # from a logging config file via logging.config.fileConfig(). import logging.handlers logging.handlers.ConcurrentRotatingFileHandler = ConcurrentRotatingFileHandler nipype-0.11.0/nipype/external/d3.js000066400000000000000000011751651257611314500171140ustar00rootroot00000000000000!function() { var d3 = { version: "3.4.8" }; if (!Date.now) Date.now = function() { return +new Date(); }; var d3_arraySlice = [].slice, d3_array = function(list) { return d3_arraySlice.call(list); }; var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window; try { d3_array(d3_documentElement.childNodes)[0].nodeType; } catch (e) { d3_array = function(list) { var i = list.length, array = new Array(i); while (i--) array[i] = list[i]; return array; }; } try { d3_document.createElement("div").style.setProperty("opacity", 0, ""); } catch (error) { var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty; d3_element_prototype.setAttribute = function(name, value) { d3_element_setAttribute.call(this, name, value + ""); }; d3_element_prototype.setAttributeNS = function(space, local, value) { d3_element_setAttributeNS.call(this, space, local, value + ""); }; d3_style_prototype.setProperty = function(name, value, priority) { d3_style_setProperty.call(this, name, value + "", priority); }; } d3.ascending = d3_ascending; function d3_ascending(a, b) { return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; } d3.descending = function(a, b) { return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN; }; d3.min = function(array, f) { var i = -1, n = array.length, a, b; if (arguments.length === 1) { while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; while (++i < n) if ((b = array[i]) != null && a > b) a = b; } else { while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b; } return a; }; d3.max = function(array, f) { var i = -1, n = array.length, a, b; if (arguments.length === 1) { while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined; while (++i < n) if ((b = array[i]) != null && b > a) a = b; } else { while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined; while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b; } return a; }; d3.extent = function(array, f) { var i = -1, n = array.length, a, b, c; if (arguments.length === 1) { while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined; while (++i < n) if ((b = array[i]) != null) { if (a > b) a = b; if (c < b) c = b; } } else { while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined; while (++i < n) if ((b = f.call(array, array[i], i)) != null) { if (a > b) a = b; if (c < b) c = b; } } return [ a, c ]; }; d3.sum = function(array, f) { var s = 0, n = array.length, a, i = -1; if (arguments.length === 1) { while (++i < n) if (!isNaN(a = +array[i])) s += a; } else { while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a; } return s; }; function d3_number(x) { return x != null && !isNaN(x); } d3.mean = function(array, f) { var s = 0, n = array.length, a, i = -1, j = n; if (arguments.length === 1) { while (++i < n) if (d3_number(a = array[i])) s += a; else --j; } else { while (++i < n) if (d3_number(a = f.call(array, array[i], i))) s += a; else --j; } return j ? s / j : undefined; }; d3.quantile = function(values, p) { var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h; return e ? v + e * (values[h] - v) : v; }; d3.median = function(array, f) { if (arguments.length > 1) array = array.map(f); array = array.filter(d3_number); return array.length ? d3.quantile(array.sort(d3_ascending), .5) : undefined; }; function d3_bisector(compare) { return { left: function(a, x, lo, hi) { if (arguments.length < 3) lo = 0; if (arguments.length < 4) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid; } return lo; }, right: function(a, x, lo, hi) { if (arguments.length < 3) lo = 0; if (arguments.length < 4) hi = a.length; while (lo < hi) { var mid = lo + hi >>> 1; if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1; } return lo; } }; } var d3_bisect = d3_bisector(d3_ascending); d3.bisectLeft = d3_bisect.left; d3.bisect = d3.bisectRight = d3_bisect.right; d3.bisector = function(f) { return d3_bisector(f.length === 1 ? function(d, x) { return d3_ascending(f(d), x); } : f); }; d3.shuffle = function(array) { var m = array.length, t, i; while (m) { i = Math.random() * m-- | 0; t = array[m], array[m] = array[i], array[i] = t; } return array; }; d3.permute = function(array, indexes) { var i = indexes.length, permutes = new Array(i); while (i--) permutes[i] = array[indexes[i]]; return permutes; }; d3.pairs = function(array) { var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n); while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ]; return pairs; }; d3.zip = function() { if (!(n = arguments.length)) return []; for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) { for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) { zip[j] = arguments[j][i]; } } return zips; }; function d3_zipLength(d) { return d.length; } d3.transpose = function(matrix) { return d3.zip.apply(d3, matrix); }; d3.keys = function(map) { var keys = []; for (var key in map) keys.push(key); return keys; }; d3.values = function(map) { var values = []; for (var key in map) values.push(map[key]); return values; }; d3.entries = function(map) { var entries = []; for (var key in map) entries.push({ key: key, value: map[key] }); return entries; }; d3.merge = function(arrays) { var n = arrays.length, m, i = -1, j = 0, merged, array; while (++i < n) j += arrays[i].length; merged = new Array(j); while (--n >= 0) { array = arrays[n]; m = array.length; while (--m >= 0) { merged[--j] = array[m]; } } return merged; }; var abs = Math.abs; d3.range = function(start, stop, step) { if (arguments.length < 3) { step = 1; if (arguments.length < 2) { stop = start; start = 0; } } if ((stop - start) / step === Infinity) throw new Error("infinite range"); var range = [], k = d3_range_integerScale(abs(step)), i = -1, j; start *= k, stop *= k, step *= k; if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k); return range; }; function d3_range_integerScale(x) { var k = 1; while (x * k % 1) k *= 10; return k; } function d3_class(ctor, properties) { try { for (var key in properties) { Object.defineProperty(ctor.prototype, key, { value: properties[key], enumerable: false }); } } catch (e) { ctor.prototype = properties; } } d3.map = function(object) { var map = new d3_Map(); if (object instanceof d3_Map) object.forEach(function(key, value) { map.set(key, value); }); else for (var key in object) map.set(key, object[key]); return map; }; function d3_Map() {} d3_class(d3_Map, { has: d3_map_has, get: function(key) { return this[d3_map_prefix + key]; }, set: function(key, value) { return this[d3_map_prefix + key] = value; }, remove: d3_map_remove, keys: d3_map_keys, values: function() { var values = []; this.forEach(function(key, value) { values.push(value); }); return values; }, entries: function() { var entries = []; this.forEach(function(key, value) { entries.push({ key: key, value: value }); }); return entries; }, size: d3_map_size, empty: d3_map_empty, forEach: function(f) { for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]); } }); var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0); function d3_map_has(key) { return d3_map_prefix + key in this; } function d3_map_remove(key) { key = d3_map_prefix + key; return key in this && delete this[key]; } function d3_map_keys() { var keys = []; this.forEach(function(key) { keys.push(key); }); return keys; } function d3_map_size() { var size = 0; for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size; return size; } function d3_map_empty() { for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false; return true; } d3.nest = function() { var nest = {}, keys = [], sortKeys = [], sortValues, rollup; function map(mapType, array, depth) { if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array; var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values; while (++i < n) { if (values = valuesByKey.get(keyValue = key(object = array[i]))) { values.push(object); } else { valuesByKey.set(keyValue, [ object ]); } } if (mapType) { object = mapType(); setter = function(keyValue, values) { object.set(keyValue, map(mapType, values, depth)); }; } else { object = {}; setter = function(keyValue, values) { object[keyValue] = map(mapType, values, depth); }; } valuesByKey.forEach(setter); return object; } function entries(map, depth) { if (depth >= keys.length) return map; var array = [], sortKey = sortKeys[depth++]; map.forEach(function(key, keyMap) { array.push({ key: key, values: entries(keyMap, depth) }); }); return sortKey ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; } nest.map = function(array, mapType) { return map(mapType, array, 0); }; nest.entries = function(array) { return entries(map(d3.map, array, 0), 0); }; nest.key = function(d) { keys.push(d); return nest; }; nest.sortKeys = function(order) { sortKeys[keys.length - 1] = order; return nest; }; nest.sortValues = function(order) { sortValues = order; return nest; }; nest.rollup = function(f) { rollup = f; return nest; }; return nest; }; d3.set = function(array) { var set = new d3_Set(); if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]); return set; }; function d3_Set() {} d3_class(d3_Set, { has: d3_map_has, add: function(value) { this[d3_map_prefix + value] = true; return value; }, remove: function(value) { value = d3_map_prefix + value; return value in this && delete this[value]; }, values: d3_map_keys, size: d3_map_size, empty: d3_map_empty, forEach: function(f) { for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1)); } }); d3.behavior = {}; d3.rebind = function(target, source) { var i = 1, n = arguments.length, method; while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]); return target; }; function d3_rebind(target, source, method) { return function() { var value = method.apply(source, arguments); return value === source ? target : value; }; } function d3_vendorSymbol(object, name) { if (name in object) return name; name = name.charAt(0).toUpperCase() + name.substring(1); for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) { var prefixName = d3_vendorPrefixes[i] + name; if (prefixName in object) return prefixName; } } var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ]; function d3_noop() {} d3.dispatch = function() { var dispatch = new d3_dispatch(), i = -1, n = arguments.length; while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); return dispatch; }; function d3_dispatch() {} d3_dispatch.prototype.on = function(type, listener) { var i = type.indexOf("."), name = ""; if (i >= 0) { name = type.substring(i + 1); type = type.substring(0, i); } if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener); if (arguments.length === 2) { if (listener == null) for (type in this) { if (this.hasOwnProperty(type)) this[type].on(name, null); } return this; } }; function d3_dispatch_event(dispatch) { var listeners = [], listenerByName = new d3_Map(); function event() { var z = listeners, i = -1, n = z.length, l; while (++i < n) if (l = z[i].on) l.apply(this, arguments); return dispatch; } event.on = function(name, listener) { var l = listenerByName.get(name), i; if (arguments.length < 2) return l && l.on; if (l) { l.on = null; listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1)); listenerByName.remove(name); } if (listener) listeners.push(listenerByName.set(name, { on: listener })); return dispatch; }; return event; } d3.event = null; function d3_eventPreventDefault() { d3.event.preventDefault(); } function d3_eventSource() { var e = d3.event, s; while (s = e.sourceEvent) e = s; return e; } function d3_eventDispatch(target) { var dispatch = new d3_dispatch(), i = 0, n = arguments.length; while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch); dispatch.of = function(thiz, argumentz) { return function(e1) { try { var e0 = e1.sourceEvent = d3.event; e1.target = target; d3.event = e1; dispatch[e1.type].apply(thiz, argumentz); } finally { d3.event = e0; } }; }; return dispatch; } d3.requote = function(s) { return s.replace(d3_requote_re, "\\$&"); }; var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; var d3_subclass = {}.__proto__ ? function(object, prototype) { object.__proto__ = prototype; } : function(object, prototype) { for (var property in prototype) object[property] = prototype[property]; }; function d3_selection(groups) { d3_subclass(groups, d3_selectionPrototype); return groups; } var d3_select = function(s, n) { return n.querySelector(s); }, d3_selectAll = function(s, n) { return n.querySelectorAll(s); }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) { return d3_selectMatcher.call(n, s); }; if (typeof Sizzle === "function") { d3_select = function(s, n) { return Sizzle(s, n)[0] || null; }; d3_selectAll = Sizzle; d3_selectMatches = Sizzle.matchesSelector; } d3.selection = function() { return d3_selectionRoot; }; var d3_selectionPrototype = d3.selection.prototype = []; d3_selectionPrototype.select = function(selector) { var subgroups = [], subgroup, subnode, group, node; selector = d3_selection_selector(selector); for (var j = -1, m = this.length; ++j < m; ) { subgroups.push(subgroup = []); subgroup.parentNode = (group = this[j]).parentNode; for (var i = -1, n = group.length; ++i < n; ) { if (node = group[i]) { subgroup.push(subnode = selector.call(node, node.__data__, i, j)); if (subnode && "__data__" in node) subnode.__data__ = node.__data__; } else { subgroup.push(null); } } } return d3_selection(subgroups); }; function d3_selection_selector(selector) { return typeof selector === "function" ? selector : function() { return d3_select(selector, this); }; } d3_selectionPrototype.selectAll = function(selector) { var subgroups = [], subgroup, node; selector = d3_selection_selectorAll(selector); for (var j = -1, m = this.length; ++j < m; ) { for (var group = this[j], i = -1, n = group.length; ++i < n; ) { if (node = group[i]) { subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j))); subgroup.parentNode = node; } } } return d3_selection(subgroups); }; function d3_selection_selectorAll(selector) { return typeof selector === "function" ? selector : function() { return d3_selectAll(selector, this); }; } var d3_nsPrefix = { svg: "http://www.w3.org/2000/svg", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/" }; d3.ns = { prefix: d3_nsPrefix, qualify: function(name) { var i = name.indexOf(":"), prefix = name; if (i >= 0) { prefix = name.substring(0, i); name = name.substring(i + 1); } return d3_nsPrefix.hasOwnProperty(prefix) ? { space: d3_nsPrefix[prefix], local: name } : name; } }; d3_selectionPrototype.attr = function(name, value) { if (arguments.length < 2) { if (typeof name === "string") { var node = this.node(); name = d3.ns.qualify(name); return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name); } for (value in name) this.each(d3_selection_attr(value, name[value])); return this; } return this.each(d3_selection_attr(name, value)); }; function d3_selection_attr(name, value) { name = d3.ns.qualify(name); function attrNull() { this.removeAttribute(name); } function attrNullNS() { this.removeAttributeNS(name.space, name.local); } function attrConstant() { this.setAttribute(name, value); } function attrConstantNS() { this.setAttributeNS(name.space, name.local, value); } function attrFunction() { var x = value.apply(this, arguments); if (x == null) this.removeAttribute(name); else this.setAttribute(name, x); } function attrFunctionNS() { var x = value.apply(this, arguments); if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x); } return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant; } function d3_collapse(s) { return s.trim().replace(/\s+/g, " "); } d3_selectionPrototype.classed = function(name, value) { if (arguments.length < 2) { if (typeof name === "string") { var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1; if (value = node.classList) { while (++i < n) if (!value.contains(name[i])) return false; } else { value = node.getAttribute("class"); while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false; } return true; } for (value in name) this.each(d3_selection_classed(value, name[value])); return this; } return this.each(d3_selection_classed(name, value)); }; function d3_selection_classedRe(name) { return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g"); } function d3_selection_classes(name) { return name.trim().split(/^|\s+/); } function d3_selection_classed(name, value) { name = d3_selection_classes(name).map(d3_selection_classedName); var n = name.length; function classedConstant() { var i = -1; while (++i < n) name[i](this, value); } function classedFunction() { var i = -1, x = value.apply(this, arguments); while (++i < n) name[i](this, x); } return typeof value === "function" ? classedFunction : classedConstant; } function d3_selection_classedName(name) { var re = d3_selection_classedRe(name); return function(node, value) { if (c = node.classList) return value ? c.add(name) : c.remove(name); var c = node.getAttribute("class") || ""; if (value) { re.lastIndex = 0; if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name)); } else { node.setAttribute("class", d3_collapse(c.replace(re, " "))); } }; } d3_selectionPrototype.style = function(name, value, priority) { var n = arguments.length; if (n < 3) { if (typeof name !== "string") { if (n < 2) value = ""; for (priority in name) this.each(d3_selection_style(priority, name[priority], value)); return this; } if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name); priority = ""; } return this.each(d3_selection_style(name, value, priority)); }; function d3_selection_style(name, value, priority) { function styleNull() { this.style.removeProperty(name); } function styleConstant() { this.style.setProperty(name, value, priority); } function styleFunction() { var x = value.apply(this, arguments); if (x == null) this.style.removeProperty(name); else this.style.setProperty(name, x, priority); } return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant; } d3_selectionPrototype.property = function(name, value) { if (arguments.length < 2) { if (typeof name === "string") return this.node()[name]; for (value in name) this.each(d3_selection_property(value, name[value])); return this; } return this.each(d3_selection_property(name, value)); }; function d3_selection_property(name, value) { function propertyNull() { delete this[name]; } function propertyConstant() { this[name] = value; } function propertyFunction() { var x = value.apply(this, arguments); if (x == null) delete this[name]; else this[name] = x; } return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant; } d3_selectionPrototype.text = function(value) { return arguments.length ? this.each(typeof value === "function" ? function() { var v = value.apply(this, arguments); this.textContent = v == null ? "" : v; } : value == null ? function() { this.textContent = ""; } : function() { this.textContent = value; }) : this.node().textContent; }; d3_selectionPrototype.html = function(value) { return arguments.length ? this.each(typeof value === "function" ? function() { var v = value.apply(this, arguments); this.innerHTML = v == null ? "" : v; } : value == null ? function() { this.innerHTML = ""; } : function() { this.innerHTML = value; }) : this.node().innerHTML; }; d3_selectionPrototype.append = function(name) { name = d3_selection_creator(name); return this.select(function() { return this.appendChild(name.apply(this, arguments)); }); }; function d3_selection_creator(name) { return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() { return this.ownerDocument.createElementNS(name.space, name.local); } : function() { return this.ownerDocument.createElementNS(this.namespaceURI, name); }; } d3_selectionPrototype.insert = function(name, before) { name = d3_selection_creator(name); before = d3_selection_selector(before); return this.select(function() { return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null); }); }; d3_selectionPrototype.remove = function() { return this.each(function() { var parent = this.parentNode; if (parent) parent.removeChild(this); }); }; d3_selectionPrototype.data = function(value, key) { var i = -1, n = this.length, group, node; if (!arguments.length) { value = new Array(n = (group = this[0]).length); while (++i < n) { if (node = group[i]) { value[i] = node.__data__; } } return value; } function bind(group, groupData) { var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData; if (key) { var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue; for (i = -1; ++i < n; ) { keyValue = key.call(node = group[i], node.__data__, i); if (nodeByKeyValue.has(keyValue)) { exitNodes[i] = node; } else { nodeByKeyValue.set(keyValue, node); } keyValues.push(keyValue); } for (i = -1; ++i < m; ) { keyValue = key.call(groupData, nodeData = groupData[i], i); if (node = nodeByKeyValue.get(keyValue)) { updateNodes[i] = node; node.__data__ = nodeData; } else if (!dataByKeyValue.has(keyValue)) { enterNodes[i] = d3_selection_dataNode(nodeData); } dataByKeyValue.set(keyValue, nodeData); nodeByKeyValue.remove(keyValue); } for (i = -1; ++i < n; ) { if (nodeByKeyValue.has(keyValues[i])) { exitNodes[i] = group[i]; } } } else { for (i = -1; ++i < n0; ) { node = group[i]; nodeData = groupData[i]; if (node) { node.__data__ = nodeData; updateNodes[i] = node; } else { enterNodes[i] = d3_selection_dataNode(nodeData); } } for (;i < m; ++i) { enterNodes[i] = d3_selection_dataNode(groupData[i]); } for (;i < n; ++i) { exitNodes[i] = group[i]; } } enterNodes.update = updateNodes; enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode; enter.push(enterNodes); update.push(updateNodes); exit.push(exitNodes); } var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]); if (typeof value === "function") { while (++i < n) { bind(group = this[i], value.call(group, group.parentNode.__data__, i)); } } else { while (++i < n) { bind(group = this[i], value); } } update.enter = function() { return enter; }; update.exit = function() { return exit; }; return update; }; function d3_selection_dataNode(data) { return { __data__: data }; } d3_selectionPrototype.datum = function(value) { return arguments.length ? this.property("__data__", value) : this.property("__data__"); }; d3_selectionPrototype.filter = function(filter) { var subgroups = [], subgroup, group, node; if (typeof filter !== "function") filter = d3_selection_filter(filter); for (var j = 0, m = this.length; j < m; j++) { subgroups.push(subgroup = []); subgroup.parentNode = (group = this[j]).parentNode; for (var i = 0, n = group.length; i < n; i++) { if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { subgroup.push(node); } } } return d3_selection(subgroups); }; function d3_selection_filter(selector) { return function() { return d3_selectMatches(this, selector); }; } d3_selectionPrototype.order = function() { for (var j = -1, m = this.length; ++j < m; ) { for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) { if (node = group[i]) { if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); next = node; } } } return this; }; d3_selectionPrototype.sort = function(comparator) { comparator = d3_selection_sortComparator.apply(this, arguments); for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator); return this.order(); }; function d3_selection_sortComparator(comparator) { if (!arguments.length) comparator = d3_ascending; return function(a, b) { return a && b ? comparator(a.__data__, b.__data__) : !a - !b; }; } d3_selectionPrototype.each = function(callback) { return d3_selection_each(this, function(node, i, j) { callback.call(node, node.__data__, i, j); }); }; function d3_selection_each(groups, callback) { for (var j = 0, m = groups.length; j < m; j++) { for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) { if (node = group[i]) callback(node, i, j); } } return groups; } d3_selectionPrototype.call = function(callback) { var args = d3_array(arguments); callback.apply(args[0] = this, args); return this; }; d3_selectionPrototype.empty = function() { return !this.node(); }; d3_selectionPrototype.node = function() { for (var j = 0, m = this.length; j < m; j++) { for (var group = this[j], i = 0, n = group.length; i < n; i++) { var node = group[i]; if (node) return node; } } return null; }; d3_selectionPrototype.size = function() { var n = 0; this.each(function() { ++n; }); return n; }; function d3_selection_enter(selection) { d3_subclass(selection, d3_selection_enterPrototype); return selection; } var d3_selection_enterPrototype = []; d3.selection.enter = d3_selection_enter; d3.selection.enter.prototype = d3_selection_enterPrototype; d3_selection_enterPrototype.append = d3_selectionPrototype.append; d3_selection_enterPrototype.empty = d3_selectionPrototype.empty; d3_selection_enterPrototype.node = d3_selectionPrototype.node; d3_selection_enterPrototype.call = d3_selectionPrototype.call; d3_selection_enterPrototype.size = d3_selectionPrototype.size; d3_selection_enterPrototype.select = function(selector) { var subgroups = [], subgroup, subnode, upgroup, group, node; for (var j = -1, m = this.length; ++j < m; ) { upgroup = (group = this[j]).update; subgroups.push(subgroup = []); subgroup.parentNode = group.parentNode; for (var i = -1, n = group.length; ++i < n; ) { if (node = group[i]) { subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j)); subnode.__data__ = node.__data__; } else { subgroup.push(null); } } } return d3_selection(subgroups); }; d3_selection_enterPrototype.insert = function(name, before) { if (arguments.length < 2) before = d3_selection_enterInsertBefore(this); return d3_selectionPrototype.insert.call(this, name, before); }; function d3_selection_enterInsertBefore(enter) { var i0, j0; return function(d, i, j) { var group = enter[j].update, n = group.length, node; if (j != j0) j0 = j, i0 = 0; if (i >= i0) i0 = i + 1; while (!(node = group[i0]) && ++i0 < n) ; return node; }; } d3_selectionPrototype.transition = function() { var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || { time: Date.now(), ease: d3_ease_cubicInOut, delay: 0, duration: 250 }; for (var j = -1, m = this.length; ++j < m; ) { subgroups.push(subgroup = []); for (var group = this[j], i = -1, n = group.length; ++i < n; ) { if (node = group[i]) d3_transitionNode(node, i, id, transition); subgroup.push(node); } } return d3_transition(subgroups, id); }; d3_selectionPrototype.interrupt = function() { return this.each(d3_selection_interrupt); }; function d3_selection_interrupt() { var lock = this.__transition__; if (lock) ++lock.active; } d3.select = function(node) { var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ]; group.parentNode = d3_documentElement; return d3_selection([ group ]); }; d3.selectAll = function(nodes) { var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes); group.parentNode = d3_documentElement; return d3_selection([ group ]); }; var d3_selectionRoot = d3.select(d3_documentElement); d3_selectionPrototype.on = function(type, listener, capture) { var n = arguments.length; if (n < 3) { if (typeof type !== "string") { if (n < 2) listener = false; for (capture in type) this.each(d3_selection_on(capture, type[capture], listener)); return this; } if (n < 2) return (n = this.node()["__on" + type]) && n._; capture = false; } return this.each(d3_selection_on(type, listener, capture)); }; function d3_selection_on(type, listener, capture) { var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener; if (i > 0) type = type.substring(0, i); var filter = d3_selection_onFilters.get(type); if (filter) type = filter, wrap = d3_selection_onFilter; function onRemove() { var l = this[name]; if (l) { this.removeEventListener(type, l, l.$); delete this[name]; } } function onAdd() { var l = wrap(listener, d3_array(arguments)); onRemove.call(this); this.addEventListener(type, this[name] = l, l.$ = capture); l._ = listener; } function removeAll() { var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match; for (var name in this) { if (match = name.match(re)) { var l = this[name]; this.removeEventListener(match[1], l, l.$); delete this[name]; } } } return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll; } var d3_selection_onFilters = d3.map({ mouseenter: "mouseover", mouseleave: "mouseout" }); d3_selection_onFilters.forEach(function(k) { if ("on" + k in d3_document) d3_selection_onFilters.remove(k); }); function d3_selection_onListener(listener, argumentz) { return function(e) { var o = d3.event; d3.event = e; argumentz[0] = this.__data__; try { listener.apply(this, argumentz); } finally { d3.event = o; } }; } function d3_selection_onFilter(listener, argumentz) { var l = d3_selection_onListener(listener, argumentz); return function(e) { var target = this, related = e.relatedTarget; if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) { l.call(target, e); } }; } var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0; function d3_event_dragSuppress() { var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault); if (d3_event_dragSelect) { var style = d3_documentElement.style, select = style[d3_event_dragSelect]; style[d3_event_dragSelect] = "none"; } return function(suppressClick) { w.on(name, null); if (d3_event_dragSelect) style[d3_event_dragSelect] = select; if (suppressClick) { function off() { w.on(click, null); } w.on(click, function() { d3_eventPreventDefault(); off(); }, true); setTimeout(off, 0); } }; } d3.mouse = function(container) { return d3_mousePoint(container, d3_eventSource()); }; function d3_mousePoint(container, e) { if (e.changedTouches) e = e.changedTouches[0]; var svg = container.ownerSVGElement || container; if (svg.createSVGPoint) { var point = svg.createSVGPoint(); point.x = e.clientX, point.y = e.clientY; point = point.matrixTransform(container.getScreenCTM().inverse()); return [ point.x, point.y ]; } var rect = container.getBoundingClientRect(); return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ]; } d3.touches = function(container, touches) { if (arguments.length < 2) touches = d3_eventSource().touches; return touches ? d3_array(touches).map(function(touch) { var point = d3_mousePoint(container, touch); point.identifier = touch.identifier; return point; }) : []; }; d3.behavior.drag = function() { var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, d3_behavior_dragMouseSubject, "mousemove", "mouseup"), touchstart = dragstart(d3_behavior_dragTouchId, d3.touch, d3_behavior_dragTouchSubject, "touchmove", "touchend"); function drag() { this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart); } function dragstart(id, position, subject, move, end) { return function() { var that = this, target = d3.event.target, parent = that.parentNode, dispatch = event.of(that, arguments), dragged = 0, dragId = id(), dragName = ".drag" + (dragId == null ? "" : "-" + dragId), dragOffset, dragSubject = d3.select(subject()).on(move + dragName, moved).on(end + dragName, ended), dragRestore = d3_event_dragSuppress(), position0 = position(parent, dragId); if (origin) { dragOffset = origin.apply(that, arguments); dragOffset = [ dragOffset.x - position0[0], dragOffset.y - position0[1] ]; } else { dragOffset = [ 0, 0 ]; } dispatch({ type: "dragstart" }); function moved() { var position1 = position(parent, dragId), dx, dy; if (!position1) return; dx = position1[0] - position0[0]; dy = position1[1] - position0[1]; dragged |= dx | dy; position0 = position1; dispatch({ type: "drag", x: position1[0] + dragOffset[0], y: position1[1] + dragOffset[1], dx: dx, dy: dy }); } function ended() { if (!position(parent, dragId)) return; dragSubject.on(move + dragName, null).on(end + dragName, null); dragRestore(dragged && d3.event.target === target); dispatch({ type: "dragend" }); } }; } drag.origin = function(x) { if (!arguments.length) return origin; origin = x; return drag; }; return d3.rebind(drag, event, "on"); }; function d3_behavior_dragTouchId() { return d3.event.changedTouches[0].identifier; } function d3_behavior_dragTouchSubject() { return d3.event.target; } function d3_behavior_dragMouseSubject() { return d3_window; } var Ď€ = Math.PI, Ď„ = 2 * Ď€, halfĎ€ = Ď€ / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = Ď€ / 180, d3_degrees = 180 / Ď€; function d3_sgn(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; } function d3_cross2d(a, b, c) { return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); } function d3_acos(x) { return x > 1 ? 0 : x < -1 ? Ď€ : Math.acos(x); } function d3_asin(x) { return x > 1 ? halfĎ€ : x < -1 ? -halfĎ€ : Math.asin(x); } function d3_sinh(x) { return ((x = Math.exp(x)) - 1 / x) / 2; } function d3_cosh(x) { return ((x = Math.exp(x)) + 1 / x) / 2; } function d3_tanh(x) { return ((x = Math.exp(2 * x)) - 1) / (x + 1); } function d3_haversin(x) { return (x = Math.sin(x / 2)) * x; } var Ď = Math.SQRT2, Ď2 = 2, Ď4 = 4; d3.interpolateZoom = function(p0, p1) { var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2]; var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + Ď4 * d2) / (2 * w0 * Ď2 * d1), b1 = (w1 * w1 - w0 * w0 - Ď4 * d2) / (2 * w1 * Ď2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / Ď; function interpolate(t) { var s = t * S; if (dr) { var coshr0 = d3_cosh(r0), u = w0 / (Ď2 * d1) * (coshr0 * d3_tanh(Ď * s + r0) - d3_sinh(r0)); return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(Ď * s + r0) ]; } return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(Ď * s) ]; } interpolate.duration = S * 1e3; return interpolate; }; d3.behavior.zoom = function() { var view = { x: 0, y: 0, k: 1 }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1; function zoom(g) { g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted); } zoom.event = function(g) { g.each(function() { var dispatch = event.of(this, arguments), view1 = view; if (d3_transitionInheritId) { d3.select(this).transition().each("start.zoom", function() { view = this.__chart__ || { x: 0, y: 0, k: 1 }; zoomstarted(dispatch); }).tween("zoom:zoom", function() { var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]); return function(t) { var l = i(t), k = dx / l[2]; this.__chart__ = view = { x: cx - l[0] * k, y: cy - l[1] * k, k: k }; zoomed(dispatch); }; }).each("end.zoom", function() { zoomended(dispatch); }); } else { this.__chart__ = view; zoomstarted(dispatch); zoomed(dispatch); zoomended(dispatch); } }); }; zoom.translate = function(_) { if (!arguments.length) return [ view.x, view.y ]; view = { x: +_[0], y: +_[1], k: view.k }; rescale(); return zoom; }; zoom.scale = function(_) { if (!arguments.length) return view.k; view = { x: view.x, y: view.y, k: +_ }; rescale(); return zoom; }; zoom.scaleExtent = function(_) { if (!arguments.length) return scaleExtent; scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ]; return zoom; }; zoom.center = function(_) { if (!arguments.length) return center; center = _ && [ +_[0], +_[1] ]; return zoom; }; zoom.size = function(_) { if (!arguments.length) return size; size = _ && [ +_[0], +_[1] ]; return zoom; }; zoom.x = function(z) { if (!arguments.length) return x1; x1 = z; x0 = z.copy(); view = { x: 0, y: 0, k: 1 }; return zoom; }; zoom.y = function(z) { if (!arguments.length) return y1; y1 = z; y0 = z.copy(); view = { x: 0, y: 0, k: 1 }; return zoom; }; function location(p) { return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ]; } function point(l) { return [ l[0] * view.k + view.x, l[1] * view.k + view.y ]; } function scaleTo(s) { view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s)); } function translateTo(p, l) { l = point(l); view.x += p[0] - l[0]; view.y += p[1] - l[1]; } function rescale() { if (x1) x1.domain(x0.range().map(function(x) { return (x - view.x) / view.k; }).map(x0.invert)); if (y1) y1.domain(y0.range().map(function(y) { return (y - view.y) / view.k; }).map(y0.invert)); } function zoomstarted(dispatch) { dispatch({ type: "zoomstart" }); } function zoomed(dispatch) { rescale(); dispatch({ type: "zoom", scale: view.k, translate: [ view.x, view.y ] }); } function zoomended(dispatch) { dispatch({ type: "zoomend" }); } function mousedowned() { var that = this, target = d3.event.target, dispatch = event.of(that, arguments), dragged = 0, subject = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), location0 = location(d3.mouse(that)), dragRestore = d3_event_dragSuppress(); d3_selection_interrupt.call(that); zoomstarted(dispatch); function moved() { dragged = 1; translateTo(d3.mouse(that), location0); zoomed(dispatch); } function ended() { subject.on(mousemove, d3_window === that ? mousewheelreset : null).on(mouseup, null); dragRestore(dragged && d3.event.target === target); zoomended(dispatch); } } function touchstarted() { var that = this, dispatch = event.of(that, arguments), locations0 = {}, distance0 = 0, scale0, zoomName = ".zoom-" + d3.event.changedTouches[0].identifier, touchmove = "touchmove" + zoomName, touchend = "touchend" + zoomName, targets = [], subject = d3.select(that).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress(); d3_selection_interrupt.call(that); started(); zoomstarted(dispatch); function relocate() { var touches = d3.touches(that); scale0 = view.k; touches.forEach(function(t) { if (t.identifier in locations0) locations0[t.identifier] = location(t); }); return touches; } function started() { var target = d3.event.target; d3.select(target).on(touchmove, moved).on(touchend, ended); targets.push(target); var changed = d3.event.changedTouches; for (var i = 0, n = changed.length; i < n; ++i) { locations0[changed[i].identifier] = null; } var touches = relocate(), now = Date.now(); if (touches.length === 1) { if (now - touchtime < 500) { var p = touches[0], l = locations0[p.identifier]; scaleTo(view.k * 2); translateTo(p, l); d3_eventPreventDefault(); zoomed(dispatch); } touchtime = now; } else if (touches.length > 1) { var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1]; distance0 = dx * dx + dy * dy; } } function moved() { var touches = d3.touches(that), p0, l0, p1, l1; for (var i = 0, n = touches.length; i < n; ++i, l1 = null) { p1 = touches[i]; if (l1 = locations0[p1.identifier]) { if (l0) break; p0 = p1, l0 = l1; } } if (l1) { var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0); p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ]; l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ]; scaleTo(scale1 * scale0); } touchtime = null; translateTo(p0, l0); zoomed(dispatch); } function ended() { if (d3.event.touches.length) { var changed = d3.event.changedTouches; for (var i = 0, n = changed.length; i < n; ++i) { delete locations0[changed[i].identifier]; } for (var identifier in locations0) { return void relocate(); } } d3.selectAll(targets).on(zoomName, null); subject.on(mousedown, mousedowned).on(touchstart, touchstarted); dragRestore(); zoomended(dispatch); } } function mousewheeled() { var dispatch = event.of(this, arguments); if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this), zoomstarted(dispatch); mousewheelTimer = setTimeout(function() { mousewheelTimer = null; zoomended(dispatch); }, 50); d3_eventPreventDefault(); var point = center || d3.mouse(this); if (!translate0) translate0 = location(point); scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k); translateTo(point, translate0); zoomed(dispatch); } function mousewheelreset() { translate0 = null; } function dblclicked() { var dispatch = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2; zoomstarted(dispatch); scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1)); translateTo(p, l); zoomed(dispatch); zoomended(dispatch); } return d3.rebind(zoom, event, "on"); }; var d3_behavior_zoomInfinity = [ 0, Infinity ]; var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() { return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1); }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() { return d3.event.wheelDelta; }, "mousewheel") : (d3_behavior_zoomDelta = function() { return -d3.event.detail; }, "MozMousePixelScroll"); function d3_Color() {} d3_Color.prototype.toString = function() { return this.rgb() + ""; }; d3.hsl = function(h, s, l) { return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l); }; function d3_hsl(h, s, l) { return new d3_Hsl(h, s, l); } function d3_Hsl(h, s, l) { this.h = h; this.s = s; this.l = l; } var d3_hslPrototype = d3_Hsl.prototype = new d3_Color(); d3_hslPrototype.brighter = function(k) { k = Math.pow(.7, arguments.length ? k : 1); return d3_hsl(this.h, this.s, this.l / k); }; d3_hslPrototype.darker = function(k) { k = Math.pow(.7, arguments.length ? k : 1); return d3_hsl(this.h, this.s, k * this.l); }; d3_hslPrototype.rgb = function() { return d3_hsl_rgb(this.h, this.s, this.l); }; function d3_hsl_rgb(h, s, l) { var m1, m2; h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h; s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s; l = l < 0 ? 0 : l > 1 ? 1 : l; m2 = l <= .5 ? l * (1 + s) : l + s - l * s; m1 = 2 * l - m2; function v(h) { if (h > 360) h -= 360; else if (h < 0) h += 360; if (h < 60) return m1 + (m2 - m1) * h / 60; if (h < 180) return m2; if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60; return m1; } function vv(h) { return Math.round(v(h) * 255); } return d3_rgb(vv(h + 120), vv(h), vv(h - 120)); } d3.hcl = function(h, c, l) { return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l); }; function d3_hcl(h, c, l) { return new d3_Hcl(h, c, l); } function d3_Hcl(h, c, l) { this.h = h; this.c = c; this.l = l; } var d3_hclPrototype = d3_Hcl.prototype = new d3_Color(); d3_hclPrototype.brighter = function(k) { return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1))); }; d3_hclPrototype.darker = function(k) { return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1))); }; d3_hclPrototype.rgb = function() { return d3_hcl_lab(this.h, this.c, this.l).rgb(); }; function d3_hcl_lab(h, c, l) { if (isNaN(h)) h = 0; if (isNaN(c)) c = 0; return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c); } d3.lab = function(l, a, b) { return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b); }; function d3_lab(l, a, b) { return new d3_Lab(l, a, b); } function d3_Lab(l, a, b) { this.l = l; this.a = a; this.b = b; } var d3_lab_K = 18; var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883; var d3_labPrototype = d3_Lab.prototype = new d3_Color(); d3_labPrototype.brighter = function(k) { return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); }; d3_labPrototype.darker = function(k) { return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b); }; d3_labPrototype.rgb = function() { return d3_lab_rgb(this.l, this.a, this.b); }; function d3_lab_rgb(l, a, b) { var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200; x = d3_lab_xyz(x) * d3_lab_X; y = d3_lab_xyz(y) * d3_lab_Y; z = d3_lab_xyz(z) * d3_lab_Z; return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z)); } function d3_lab_hcl(l, a, b) { return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l); } function d3_lab_xyz(x) { return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037; } function d3_xyz_lab(x) { return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29; } function d3_xyz_rgb(r) { return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055)); } d3.rgb = function(r, g, b) { return arguments.length === 1 ? r instanceof d3_Rgb ? d3_rgb(r.r, r.g, r.b) : d3_rgb_parse("" + r, d3_rgb, d3_hsl_rgb) : d3_rgb(~~r, ~~g, ~~b); }; function d3_rgbNumber(value) { return d3_rgb(value >> 16, value >> 8 & 255, value & 255); } function d3_rgbString(value) { return d3_rgbNumber(value) + ""; } function d3_rgb(r, g, b) { return new d3_Rgb(r, g, b); } function d3_Rgb(r, g, b) { this.r = r; this.g = g; this.b = b; } var d3_rgbPrototype = d3_Rgb.prototype = new d3_Color(); d3_rgbPrototype.brighter = function(k) { k = Math.pow(.7, arguments.length ? k : 1); var r = this.r, g = this.g, b = this.b, i = 30; if (!r && !g && !b) return d3_rgb(i, i, i); if (r && r < i) r = i; if (g && g < i) g = i; if (b && b < i) b = i; return d3_rgb(Math.min(255, ~~(r / k)), Math.min(255, ~~(g / k)), Math.min(255, ~~(b / k))); }; d3_rgbPrototype.darker = function(k) { k = Math.pow(.7, arguments.length ? k : 1); return d3_rgb(~~(k * this.r), ~~(k * this.g), ~~(k * this.b)); }; d3_rgbPrototype.hsl = function() { return d3_rgb_hsl(this.r, this.g, this.b); }; d3_rgbPrototype.toString = function() { return "#" + d3_rgb_hex(this.r) + d3_rgb_hex(this.g) + d3_rgb_hex(this.b); }; function d3_rgb_hex(v) { return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16); } function d3_rgb_parse(format, rgb, hsl) { var r = 0, g = 0, b = 0, m1, m2, color; m1 = /([a-z]+)\((.*)\)/i.exec(format); if (m1) { m2 = m1[2].split(","); switch (m1[1]) { case "hsl": { return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100); } case "rgb": { return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2])); } } } if (color = d3_rgb_names.get(format)) return rgb(color.r, color.g, color.b); if (format != null && format.charAt(0) === "#" && !isNaN(color = parseInt(format.substring(1), 16))) { if (format.length === 4) { r = (color & 3840) >> 4; r = r >> 4 | r; g = color & 240; g = g >> 4 | g; b = color & 15; b = b << 4 | b; } else if (format.length === 7) { r = (color & 16711680) >> 16; g = (color & 65280) >> 8; b = color & 255; } } return rgb(r, g, b); } function d3_rgb_hsl(r, g, b) { var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2; if (d) { s = l < .5 ? d / (max + min) : d / (2 - max - min); if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4; h *= 60; } else { h = NaN; s = l > 0 && l < 1 ? 0 : h; } return d3_hsl(h, s, l); } function d3_rgb_lab(r, g, b) { r = d3_rgb_xyz(r); g = d3_rgb_xyz(g); b = d3_rgb_xyz(b); var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z); return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z)); } function d3_rgb_xyz(r) { return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4); } function d3_rgb_parseNumber(c) { var f = parseFloat(c); return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f; } var d3_rgb_names = d3.map({ aliceblue: 15792383, antiquewhite: 16444375, aqua: 65535, aquamarine: 8388564, azure: 15794175, beige: 16119260, bisque: 16770244, black: 0, blanchedalmond: 16772045, blue: 255, blueviolet: 9055202, brown: 10824234, burlywood: 14596231, cadetblue: 6266528, chartreuse: 8388352, chocolate: 13789470, coral: 16744272, cornflowerblue: 6591981, cornsilk: 16775388, crimson: 14423100, cyan: 65535, darkblue: 139, darkcyan: 35723, darkgoldenrod: 12092939, darkgray: 11119017, darkgreen: 25600, darkgrey: 11119017, darkkhaki: 12433259, darkmagenta: 9109643, darkolivegreen: 5597999, darkorange: 16747520, darkorchid: 10040012, darkred: 9109504, darksalmon: 15308410, darkseagreen: 9419919, darkslateblue: 4734347, darkslategray: 3100495, darkslategrey: 3100495, darkturquoise: 52945, darkviolet: 9699539, deeppink: 16716947, deepskyblue: 49151, dimgray: 6908265, dimgrey: 6908265, dodgerblue: 2003199, firebrick: 11674146, floralwhite: 16775920, forestgreen: 2263842, fuchsia: 16711935, gainsboro: 14474460, ghostwhite: 16316671, gold: 16766720, goldenrod: 14329120, gray: 8421504, green: 32768, greenyellow: 11403055, grey: 8421504, honeydew: 15794160, hotpink: 16738740, indianred: 13458524, indigo: 4915330, ivory: 16777200, khaki: 15787660, lavender: 15132410, lavenderblush: 16773365, lawngreen: 8190976, lemonchiffon: 16775885, lightblue: 11393254, lightcoral: 15761536, lightcyan: 14745599, lightgoldenrodyellow: 16448210, lightgray: 13882323, lightgreen: 9498256, lightgrey: 13882323, lightpink: 16758465, lightsalmon: 16752762, lightseagreen: 2142890, lightskyblue: 8900346, lightslategray: 7833753, lightslategrey: 7833753, lightsteelblue: 11584734, lightyellow: 16777184, lime: 65280, limegreen: 3329330, linen: 16445670, magenta: 16711935, maroon: 8388608, mediumaquamarine: 6737322, mediumblue: 205, mediumorchid: 12211667, mediumpurple: 9662683, mediumseagreen: 3978097, mediumslateblue: 8087790, mediumspringgreen: 64154, mediumturquoise: 4772300, mediumvioletred: 13047173, midnightblue: 1644912, mintcream: 16121850, mistyrose: 16770273, moccasin: 16770229, navajowhite: 16768685, navy: 128, oldlace: 16643558, olive: 8421376, olivedrab: 7048739, orange: 16753920, orangered: 16729344, orchid: 14315734, palegoldenrod: 15657130, palegreen: 10025880, paleturquoise: 11529966, palevioletred: 14381203, papayawhip: 16773077, peachpuff: 16767673, peru: 13468991, pink: 16761035, plum: 14524637, powderblue: 11591910, purple: 8388736, red: 16711680, rosybrown: 12357519, royalblue: 4286945, saddlebrown: 9127187, salmon: 16416882, sandybrown: 16032864, seagreen: 3050327, seashell: 16774638, sienna: 10506797, silver: 12632256, skyblue: 8900331, slateblue: 6970061, slategray: 7372944, slategrey: 7372944, snow: 16775930, springgreen: 65407, steelblue: 4620980, tan: 13808780, teal: 32896, thistle: 14204888, tomato: 16737095, turquoise: 4251856, violet: 15631086, wheat: 16113331, white: 16777215, whitesmoke: 16119285, yellow: 16776960, yellowgreen: 10145074 }); d3_rgb_names.forEach(function(key, value) { d3_rgb_names.set(key, d3_rgbNumber(value)); }); function d3_functor(v) { return typeof v === "function" ? v : function() { return v; }; } d3.functor = d3_functor; function d3_identity(d) { return d; } d3.xhr = d3_xhrType(d3_identity); function d3_xhrType(response) { return function(url, mimeType, callback) { if (arguments.length === 2 && typeof mimeType === "function") callback = mimeType, mimeType = null; return d3_xhr(url, mimeType, response, callback); }; } function d3_xhr(url, mimeType, response, callback) { var xhr = {}, dispatch = d3.dispatch("beforesend", "progress", "load", "error"), headers = {}, request = new XMLHttpRequest(), responseType = null; if (d3_window.XDomainRequest && !("withCredentials" in request) && /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); "onload" in request ? request.onload = request.onerror = respond : request.onreadystatechange = function() { request.readyState > 3 && respond(); }; function respond() { var status = request.status, result; if (!status && request.responseText || status >= 200 && status < 300 || status === 304) { try { result = response.call(xhr, request); } catch (e) { dispatch.error.call(xhr, e); return; } dispatch.load.call(xhr, result); } else { dispatch.error.call(xhr, request); } } request.onprogress = function(event) { var o = d3.event; d3.event = event; try { dispatch.progress.call(xhr, request); } finally { d3.event = o; } }; xhr.header = function(name, value) { name = (name + "").toLowerCase(); if (arguments.length < 2) return headers[name]; if (value == null) delete headers[name]; else headers[name] = value + ""; return xhr; }; xhr.mimeType = function(value) { if (!arguments.length) return mimeType; mimeType = value == null ? null : value + ""; return xhr; }; xhr.responseType = function(value) { if (!arguments.length) return responseType; responseType = value; return xhr; }; xhr.response = function(value) { response = value; return xhr; }; [ "get", "post" ].forEach(function(method) { xhr[method] = function() { return xhr.send.apply(xhr, [ method ].concat(d3_array(arguments))); }; }); xhr.send = function(method, data, callback) { if (arguments.length === 2 && typeof data === "function") callback = data, data = null; request.open(method, url, true); if (mimeType != null && !("accept" in headers)) headers["accept"] = mimeType + ",*/*"; if (request.setRequestHeader) for (var name in headers) request.setRequestHeader(name, headers[name]); if (mimeType != null && request.overrideMimeType) request.overrideMimeType(mimeType); if (responseType != null) request.responseType = responseType; if (callback != null) xhr.on("error", callback).on("load", function(request) { callback(null, request); }); dispatch.beforesend.call(xhr, request); request.send(data == null ? null : data); return xhr; }; xhr.abort = function() { request.abort(); return xhr; }; d3.rebind(xhr, dispatch, "on"); return callback == null ? xhr : xhr.get(d3_xhr_fixCallback(callback)); } function d3_xhr_fixCallback(callback) { return callback.length === 1 ? function(error, request) { callback(error == null ? request : null); } : callback; } d3.dsv = function(delimiter, mimeType) { var reFormat = new RegExp('["' + delimiter + "\n]"), delimiterCode = delimiter.charCodeAt(0); function dsv(url, row, callback) { if (arguments.length < 3) callback = row, row = null; var xhr = d3_xhr(url, mimeType, row == null ? response : typedResponse(row), callback); xhr.row = function(_) { return arguments.length ? xhr.response((row = _) == null ? response : typedResponse(_)) : row; }; return xhr; } function response(request) { return dsv.parse(request.responseText); } function typedResponse(f) { return function(request) { return dsv.parse(request.responseText, f); }; } dsv.parse = function(text, f) { var o; return dsv.parseRows(text, function(row, i) { if (o) return o(row, i - 1); var a = new Function("d", "return {" + row.map(function(name, i) { return JSON.stringify(name) + ": d[" + i + "]"; }).join(",") + "}"); o = f ? function(row, i) { return f(a(row), i); } : a; }); }; dsv.parseRows = function(text, f) { var EOL = {}, EOF = {}, rows = [], N = text.length, I = 0, n = 0, t, eol; function token() { if (I >= N) return EOF; if (eol) return eol = false, EOL; var j = I; if (text.charCodeAt(j) === 34) { var i = j; while (i++ < N) { if (text.charCodeAt(i) === 34) { if (text.charCodeAt(i + 1) !== 34) break; ++i; } } I = i + 2; var c = text.charCodeAt(i + 1); if (c === 13) { eol = true; if (text.charCodeAt(i + 2) === 10) ++I; } else if (c === 10) { eol = true; } return text.substring(j + 1, i).replace(/""/g, '"'); } while (I < N) { var c = text.charCodeAt(I++), k = 1; if (c === 10) eol = true; else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } else if (c !== delimiterCode) continue; return text.substring(j, I - k); } return text.substring(j); } while ((t = token()) !== EOF) { var a = []; while (t !== EOL && t !== EOF) { a.push(t); t = token(); } if (f && !(a = f(a, n++))) continue; rows.push(a); } return rows; }; dsv.format = function(rows) { if (Array.isArray(rows[0])) return dsv.formatRows(rows); var fieldSet = new d3_Set(), fields = []; rows.forEach(function(row) { for (var field in row) { if (!fieldSet.has(field)) { fields.push(fieldSet.add(field)); } } }); return [ fields.map(formatValue).join(delimiter) ].concat(rows.map(function(row) { return fields.map(function(field) { return formatValue(row[field]); }).join(delimiter); })).join("\n"); }; dsv.formatRows = function(rows) { return rows.map(formatRow).join("\n"); }; function formatRow(row) { return row.map(formatValue).join(delimiter); } function formatValue(text) { return reFormat.test(text) ? '"' + text.replace(/\"/g, '""') + '"' : text; } return dsv; }; d3.csv = d3.dsv(",", "text/csv"); d3.tsv = d3.dsv(" ", "text/tab-separated-values"); d3.touch = function(container, touches, identifier) { if (arguments.length < 3) identifier = touches, touches = d3_eventSource().changedTouches; if (touches) for (var i = 0, n = touches.length, touch; i < n; ++i) { if ((touch = touches[i]).identifier === identifier) { return d3_mousePoint(container, touch); } } }; var d3_timer_queueHead, d3_timer_queueTail, d3_timer_interval, d3_timer_timeout, d3_timer_active, d3_timer_frame = d3_window[d3_vendorSymbol(d3_window, "requestAnimationFrame")] || function(callback) { setTimeout(callback, 17); }; d3.timer = function(callback, delay, then) { var n = arguments.length; if (n < 2) delay = 0; if (n < 3) then = Date.now(); var time = then + delay, timer = { c: callback, t: time, f: false, n: null }; if (d3_timer_queueTail) d3_timer_queueTail.n = timer; else d3_timer_queueHead = timer; d3_timer_queueTail = timer; if (!d3_timer_interval) { d3_timer_timeout = clearTimeout(d3_timer_timeout); d3_timer_interval = 1; d3_timer_frame(d3_timer_step); } }; function d3_timer_step() { var now = d3_timer_mark(), delay = d3_timer_sweep() - now; if (delay > 24) { if (isFinite(delay)) { clearTimeout(d3_timer_timeout); d3_timer_timeout = setTimeout(d3_timer_step, delay); } d3_timer_interval = 0; } else { d3_timer_interval = 1; d3_timer_frame(d3_timer_step); } } d3.timer.flush = function() { d3_timer_mark(); d3_timer_sweep(); }; function d3_timer_mark() { var now = Date.now(); d3_timer_active = d3_timer_queueHead; while (d3_timer_active) { if (now >= d3_timer_active.t) d3_timer_active.f = d3_timer_active.c(now - d3_timer_active.t); d3_timer_active = d3_timer_active.n; } return now; } function d3_timer_sweep() { var t0, t1 = d3_timer_queueHead, time = Infinity; while (t1) { if (t1.f) { t1 = t0 ? t0.n = t1.n : d3_timer_queueHead = t1.n; } else { if (t1.t < time) time = t1.t; t1 = (t0 = t1).n; } } d3_timer_queueTail = t0; return time; } function d3_format_precision(x, p) { return p - (x ? Math.ceil(Math.log(x) / Math.LN10) : 1); } d3.round = function(x, n) { return n ? Math.round(x * (n = Math.pow(10, n))) / n : Math.round(x); }; var d3_formatPrefixes = [ "y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y" ].map(d3_formatPrefix); d3.formatPrefix = function(value, precision) { var i = 0; if (value) { if (value < 0) value *= -1; if (precision) value = d3.round(value, d3_format_precision(value, precision)); i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10); i = Math.max(-24, Math.min(24, Math.floor((i - 1) / 3) * 3)); } return d3_formatPrefixes[8 + i / 3]; }; function d3_formatPrefix(d, i) { var k = Math.pow(10, abs(8 - i) * 3); return { scale: i > 8 ? function(d) { return d / k; } : function(d) { return d * k; }, symbol: d }; } function d3_locale_numberFormat(locale) { var locale_decimal = locale.decimal, locale_thousands = locale.thousands, locale_grouping = locale.grouping, locale_currency = locale.currency, formatGroup = locale_grouping ? function(value) { var i = value.length, t = [], j = 0, g = locale_grouping[0]; while (i > 0 && g > 0) { t.push(value.substring(i -= g, i + g)); g = locale_grouping[j = (j + 1) % locale_grouping.length]; } return t.reverse().join(locale_thousands); } : d3_identity; return function(specifier) { var match = d3_format_re.exec(specifier), fill = match[1] || " ", align = match[2] || ">", sign = match[3] || "", symbol = match[4] || "", zfill = match[5], width = +match[6], comma = match[7], precision = match[8], type = match[9], scale = 1, prefix = "", suffix = "", integer = false; if (precision) precision = +precision.substring(1); if (zfill || fill === "0" && align === "=") { zfill = fill = "0"; align = "="; if (comma) width -= Math.floor((width - 1) / 4); } switch (type) { case "n": comma = true; type = "g"; break; case "%": scale = 100; suffix = "%"; type = "f"; break; case "p": scale = 100; suffix = "%"; type = "r"; break; case "b": case "o": case "x": case "X": if (symbol === "#") prefix = "0" + type.toLowerCase(); case "c": case "d": integer = true; precision = 0; break; case "s": scale = -1; type = "r"; break; } if (symbol === "$") prefix = locale_currency[0], suffix = locale_currency[1]; if (type == "r" && !precision) type = "g"; if (precision != null) { if (type == "g") precision = Math.max(1, Math.min(21, precision)); else if (type == "e" || type == "f") precision = Math.max(0, Math.min(20, precision)); } type = d3_format_types.get(type) || d3_format_typeDefault; var zcomma = zfill && comma; return function(value) { var fullSuffix = suffix; if (integer && value % 1) return ""; var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, "-") : sign; if (scale < 0) { var unit = d3.formatPrefix(value, precision); value = unit.scale(value); fullSuffix = unit.symbol + suffix; } else { value *= scale; } value = type(value, precision); var i = value.lastIndexOf("."), before = i < 0 ? value : value.substring(0, i), after = i < 0 ? "" : locale_decimal + value.substring(i + 1); if (!zfill && comma) before = formatGroup(before); var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length), padding = length < width ? new Array(length = width - length + 1).join(fill) : ""; if (zcomma) before = formatGroup(padding + before); negative += prefix; value = before + after; return (align === "<" ? negative + value + padding : align === ">" ? padding + negative + value : align === "^" ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length) : negative + (zcomma ? value : padding + value)) + fullSuffix; }; }; } var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i; var d3_format_types = d3.map({ b: function(x) { return x.toString(2); }, c: function(x) { return String.fromCharCode(x); }, o: function(x) { return x.toString(8); }, x: function(x) { return x.toString(16); }, X: function(x) { return x.toString(16).toUpperCase(); }, g: function(x, p) { return x.toPrecision(p); }, e: function(x, p) { return x.toExponential(p); }, f: function(x, p) { return x.toFixed(p); }, r: function(x, p) { return (x = d3.round(x, d3_format_precision(x, p))).toFixed(Math.max(0, Math.min(20, d3_format_precision(x * (1 + 1e-15), p)))); } }); function d3_format_typeDefault(x) { return x + ""; } var d3_time = d3.time = {}, d3_date = Date; function d3_date_utc() { this._ = new Date(arguments.length > 1 ? Date.UTC.apply(this, arguments) : arguments[0]); } d3_date_utc.prototype = { getDate: function() { return this._.getUTCDate(); }, getDay: function() { return this._.getUTCDay(); }, getFullYear: function() { return this._.getUTCFullYear(); }, getHours: function() { return this._.getUTCHours(); }, getMilliseconds: function() { return this._.getUTCMilliseconds(); }, getMinutes: function() { return this._.getUTCMinutes(); }, getMonth: function() { return this._.getUTCMonth(); }, getSeconds: function() { return this._.getUTCSeconds(); }, getTime: function() { return this._.getTime(); }, getTimezoneOffset: function() { return 0; }, valueOf: function() { return this._.valueOf(); }, setDate: function() { d3_time_prototype.setUTCDate.apply(this._, arguments); }, setDay: function() { d3_time_prototype.setUTCDay.apply(this._, arguments); }, setFullYear: function() { d3_time_prototype.setUTCFullYear.apply(this._, arguments); }, setHours: function() { d3_time_prototype.setUTCHours.apply(this._, arguments); }, setMilliseconds: function() { d3_time_prototype.setUTCMilliseconds.apply(this._, arguments); }, setMinutes: function() { d3_time_prototype.setUTCMinutes.apply(this._, arguments); }, setMonth: function() { d3_time_prototype.setUTCMonth.apply(this._, arguments); }, setSeconds: function() { d3_time_prototype.setUTCSeconds.apply(this._, arguments); }, setTime: function() { d3_time_prototype.setTime.apply(this._, arguments); } }; var d3_time_prototype = Date.prototype; function d3_time_interval(local, step, number) { function round(date) { var d0 = local(date), d1 = offset(d0, 1); return date - d0 < d1 - date ? d0 : d1; } function ceil(date) { step(date = local(new d3_date(date - 1)), 1); return date; } function offset(date, k) { step(date = new d3_date(+date), k); return date; } function range(t0, t1, dt) { var time = ceil(t0), times = []; if (dt > 1) { while (time < t1) { if (!(number(time) % dt)) times.push(new Date(+time)); step(time, 1); } } else { while (time < t1) times.push(new Date(+time)), step(time, 1); } return times; } function range_utc(t0, t1, dt) { try { d3_date = d3_date_utc; var utc = new d3_date_utc(); utc._ = t0; return range(utc, t1, dt); } finally { d3_date = Date; } } local.floor = local; local.round = round; local.ceil = ceil; local.offset = offset; local.range = range; var utc = local.utc = d3_time_interval_utc(local); utc.floor = utc; utc.round = d3_time_interval_utc(round); utc.ceil = d3_time_interval_utc(ceil); utc.offset = d3_time_interval_utc(offset); utc.range = range_utc; return local; } function d3_time_interval_utc(method) { return function(date, k) { try { d3_date = d3_date_utc; var utc = new d3_date_utc(); utc._ = date; return method(utc, k)._; } finally { d3_date = Date; } }; } d3_time.year = d3_time_interval(function(date) { date = d3_time.day(date); date.setMonth(0, 1); return date; }, function(date, offset) { date.setFullYear(date.getFullYear() + offset); }, function(date) { return date.getFullYear(); }); d3_time.years = d3_time.year.range; d3_time.years.utc = d3_time.year.utc.range; d3_time.day = d3_time_interval(function(date) { var day = new d3_date(2e3, 0); day.setFullYear(date.getFullYear(), date.getMonth(), date.getDate()); return day; }, function(date, offset) { date.setDate(date.getDate() + offset); }, function(date) { return date.getDate() - 1; }); d3_time.days = d3_time.day.range; d3_time.days.utc = d3_time.day.utc.range; d3_time.dayOfYear = function(date) { var year = d3_time.year(date); return Math.floor((date - year - (date.getTimezoneOffset() - year.getTimezoneOffset()) * 6e4) / 864e5); }; [ "sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday" ].forEach(function(day, i) { i = 7 - i; var interval = d3_time[day] = d3_time_interval(function(date) { (date = d3_time.day(date)).setDate(date.getDate() - (date.getDay() + i) % 7); return date; }, function(date, offset) { date.setDate(date.getDate() + Math.floor(offset) * 7); }, function(date) { var day = d3_time.year(date).getDay(); return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7) - (day !== i); }); d3_time[day + "s"] = interval.range; d3_time[day + "s"].utc = interval.utc.range; d3_time[day + "OfYear"] = function(date) { var day = d3_time.year(date).getDay(); return Math.floor((d3_time.dayOfYear(date) + (day + i) % 7) / 7); }; }); d3_time.week = d3_time.sunday; d3_time.weeks = d3_time.sunday.range; d3_time.weeks.utc = d3_time.sunday.utc.range; d3_time.weekOfYear = d3_time.sundayOfYear; function d3_locale_timeFormat(locale) { var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_days = locale.days, locale_shortDays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; function d3_time_format(template) { var n = template.length; function format(date) { var string = [], i = -1, j = 0, c, p, f; while (++i < n) { if (template.charCodeAt(i) === 37) { string.push(template.substring(j, i)); if ((p = d3_time_formatPads[c = template.charAt(++i)]) != null) c = template.charAt(++i); if (f = d3_time_formats[c]) c = f(date, p == null ? c === "e" ? " " : "0" : p); string.push(c); j = i + 1; } } string.push(template.substring(j, i)); return string.join(""); } format.parse = function(string) { var d = { y: 1900, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0, Z: null }, i = d3_time_parse(d, template, string, 0); if (i != string.length) return null; if ("p" in d) d.H = d.H % 12 + d.p * 12; var localZ = d.Z != null && d3_date !== d3_date_utc, date = new (localZ ? d3_date_utc : d3_date)(); if ("j" in d) date.setFullYear(d.y, 0, d.j); else if ("w" in d && ("W" in d || "U" in d)) { date.setFullYear(d.y, 0, 1); date.setFullYear(d.y, 0, "W" in d ? (d.w + 6) % 7 + d.W * 7 - (date.getDay() + 5) % 7 : d.w + d.U * 7 - (date.getDay() + 6) % 7); } else date.setFullYear(d.y, d.m, d.d); date.setHours(d.H + Math.floor(d.Z / 100), d.M + d.Z % 100, d.S, d.L); return localZ ? date._ : date; }; format.toString = function() { return template; }; return format; } function d3_time_parse(date, template, string, j) { var c, p, t, i = 0, n = template.length, m = string.length; while (i < n) { if (j >= m) return -1; c = template.charCodeAt(i++); if (c === 37) { t = template.charAt(i++); p = d3_time_parsers[t in d3_time_formatPads ? template.charAt(i++) : t]; if (!p || (j = p(date, string, j)) < 0) return -1; } else if (c != string.charCodeAt(j++)) { return -1; } } return j; } d3_time_format.utc = function(template) { var local = d3_time_format(template); function format(date) { try { d3_date = d3_date_utc; var utc = new d3_date(); utc._ = date; return local(utc); } finally { d3_date = Date; } } format.parse = function(string) { try { d3_date = d3_date_utc; var date = local.parse(string); return date && date._; } finally { d3_date = Date; } }; format.toString = local.toString; return format; }; d3_time_format.multi = d3_time_format.utc.multi = d3_time_formatMulti; var d3_time_periodLookup = d3.map(), d3_time_dayRe = d3_time_formatRe(locale_days), d3_time_dayLookup = d3_time_formatLookup(locale_days), d3_time_dayAbbrevRe = d3_time_formatRe(locale_shortDays), d3_time_dayAbbrevLookup = d3_time_formatLookup(locale_shortDays), d3_time_monthRe = d3_time_formatRe(locale_months), d3_time_monthLookup = d3_time_formatLookup(locale_months), d3_time_monthAbbrevRe = d3_time_formatRe(locale_shortMonths), d3_time_monthAbbrevLookup = d3_time_formatLookup(locale_shortMonths); locale_periods.forEach(function(p, i) { d3_time_periodLookup.set(p.toLowerCase(), i); }); var d3_time_formats = { a: function(d) { return locale_shortDays[d.getDay()]; }, A: function(d) { return locale_days[d.getDay()]; }, b: function(d) { return locale_shortMonths[d.getMonth()]; }, B: function(d) { return locale_months[d.getMonth()]; }, c: d3_time_format(locale_dateTime), d: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); }, e: function(d, p) { return d3_time_formatPad(d.getDate(), p, 2); }, H: function(d, p) { return d3_time_formatPad(d.getHours(), p, 2); }, I: function(d, p) { return d3_time_formatPad(d.getHours() % 12 || 12, p, 2); }, j: function(d, p) { return d3_time_formatPad(1 + d3_time.dayOfYear(d), p, 3); }, L: function(d, p) { return d3_time_formatPad(d.getMilliseconds(), p, 3); }, m: function(d, p) { return d3_time_formatPad(d.getMonth() + 1, p, 2); }, M: function(d, p) { return d3_time_formatPad(d.getMinutes(), p, 2); }, p: function(d) { return locale_periods[+(d.getHours() >= 12)]; }, S: function(d, p) { return d3_time_formatPad(d.getSeconds(), p, 2); }, U: function(d, p) { return d3_time_formatPad(d3_time.sundayOfYear(d), p, 2); }, w: function(d) { return d.getDay(); }, W: function(d, p) { return d3_time_formatPad(d3_time.mondayOfYear(d), p, 2); }, x: d3_time_format(locale_date), X: d3_time_format(locale_time), y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 100, p, 2); }, Y: function(d, p) { return d3_time_formatPad(d.getFullYear() % 1e4, p, 4); }, Z: d3_time_zone, "%": function() { return "%"; } }; var d3_time_parsers = { a: d3_time_parseWeekdayAbbrev, A: d3_time_parseWeekday, b: d3_time_parseMonthAbbrev, B: d3_time_parseMonth, c: d3_time_parseLocaleFull, d: d3_time_parseDay, e: d3_time_parseDay, H: d3_time_parseHour24, I: d3_time_parseHour24, j: d3_time_parseDayOfYear, L: d3_time_parseMilliseconds, m: d3_time_parseMonthNumber, M: d3_time_parseMinutes, p: d3_time_parseAmPm, S: d3_time_parseSeconds, U: d3_time_parseWeekNumberSunday, w: d3_time_parseWeekdayNumber, W: d3_time_parseWeekNumberMonday, x: d3_time_parseLocaleDate, X: d3_time_parseLocaleTime, y: d3_time_parseYear, Y: d3_time_parseFullYear, Z: d3_time_parseZone, "%": d3_time_parseLiteralPercent }; function d3_time_parseWeekdayAbbrev(date, string, i) { d3_time_dayAbbrevRe.lastIndex = 0; var n = d3_time_dayAbbrevRe.exec(string.substring(i)); return n ? (date.w = d3_time_dayAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function d3_time_parseWeekday(date, string, i) { d3_time_dayRe.lastIndex = 0; var n = d3_time_dayRe.exec(string.substring(i)); return n ? (date.w = d3_time_dayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function d3_time_parseMonthAbbrev(date, string, i) { d3_time_monthAbbrevRe.lastIndex = 0; var n = d3_time_monthAbbrevRe.exec(string.substring(i)); return n ? (date.m = d3_time_monthAbbrevLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function d3_time_parseMonth(date, string, i) { d3_time_monthRe.lastIndex = 0; var n = d3_time_monthRe.exec(string.substring(i)); return n ? (date.m = d3_time_monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function d3_time_parseLocaleFull(date, string, i) { return d3_time_parse(date, d3_time_formats.c.toString(), string, i); } function d3_time_parseLocaleDate(date, string, i) { return d3_time_parse(date, d3_time_formats.x.toString(), string, i); } function d3_time_parseLocaleTime(date, string, i) { return d3_time_parse(date, d3_time_formats.X.toString(), string, i); } function d3_time_parseAmPm(date, string, i) { var n = d3_time_periodLookup.get(string.substring(i, i += 2).toLowerCase()); return n == null ? -1 : (date.p = n, i); } return d3_time_format; } var d3_time_formatPads = { "-": "", _: " ", "0": "0" }, d3_time_numberRe = /^\s*\d+/, d3_time_percentRe = /^%/; function d3_time_formatPad(value, fill, width) { var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); } function d3_time_formatRe(names) { return new RegExp("^(?:" + names.map(d3.requote).join("|") + ")", "i"); } function d3_time_formatLookup(names) { var map = new d3_Map(), i = -1, n = names.length; while (++i < n) map.set(names[i].toLowerCase(), i); return map; } function d3_time_parseWeekdayNumber(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 1)); return n ? (date.w = +n[0], i + n[0].length) : -1; } function d3_time_parseWeekNumberSunday(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i)); return n ? (date.U = +n[0], i + n[0].length) : -1; } function d3_time_parseWeekNumberMonday(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i)); return n ? (date.W = +n[0], i + n[0].length) : -1; } function d3_time_parseFullYear(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 4)); return n ? (date.y = +n[0], i + n[0].length) : -1; } function d3_time_parseYear(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.y = d3_time_expandYear(+n[0]), i + n[0].length) : -1; } function d3_time_parseZone(date, string, i) { return /^[+-]\d{4}$/.test(string = string.substring(i, i + 5)) ? (date.Z = -string, i + 5) : -1; } function d3_time_expandYear(d) { return d + (d > 68 ? 1900 : 2e3); } function d3_time_parseMonthNumber(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.m = n[0] - 1, i + n[0].length) : -1; } function d3_time_parseDay(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.d = +n[0], i + n[0].length) : -1; } function d3_time_parseDayOfYear(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 3)); return n ? (date.j = +n[0], i + n[0].length) : -1; } function d3_time_parseHour24(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.H = +n[0], i + n[0].length) : -1; } function d3_time_parseMinutes(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.M = +n[0], i + n[0].length) : -1; } function d3_time_parseSeconds(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 2)); return n ? (date.S = +n[0], i + n[0].length) : -1; } function d3_time_parseMilliseconds(date, string, i) { d3_time_numberRe.lastIndex = 0; var n = d3_time_numberRe.exec(string.substring(i, i + 3)); return n ? (date.L = +n[0], i + n[0].length) : -1; } function d3_time_zone(d) { var z = d.getTimezoneOffset(), zs = z > 0 ? "-" : "+", zh = ~~(abs(z) / 60), zm = abs(z) % 60; return zs + d3_time_formatPad(zh, "0", 2) + d3_time_formatPad(zm, "0", 2); } function d3_time_parseLiteralPercent(date, string, i) { d3_time_percentRe.lastIndex = 0; var n = d3_time_percentRe.exec(string.substring(i, i + 1)); return n ? i + n[0].length : -1; } function d3_time_formatMulti(formats) { var n = formats.length, i = -1; while (++i < n) formats[i][0] = this(formats[i][0]); return function(date) { var i = 0, f = formats[i]; while (!f[1](date)) f = formats[++i]; return f[0](date); }; } d3.locale = function(locale) { return { numberFormat: d3_locale_numberFormat(locale), timeFormat: d3_locale_timeFormat(locale) }; }; var d3_locale_enUS = d3.locale({ decimal: ".", thousands: ",", grouping: [ 3 ], currency: [ "$", "" ], dateTime: "%a %b %e %X %Y", date: "%m/%d/%Y", time: "%H:%M:%S", periods: [ "AM", "PM" ], days: [ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ], shortDays: [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ], months: [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ], shortMonths: [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] }); d3.format = d3_locale_enUS.numberFormat; d3.geo = {}; function d3_adder() {} d3_adder.prototype = { s: 0, t: 0, add: function(y) { d3_adderSum(y, this.t, d3_adderTemp); d3_adderSum(d3_adderTemp.s, this.s, this); if (this.s) this.t += d3_adderTemp.t; else this.s = d3_adderTemp.t; }, reset: function() { this.s = this.t = 0; }, valueOf: function() { return this.s; } }; var d3_adderTemp = new d3_adder(); function d3_adderSum(a, b, o) { var x = o.s = a + b, bv = x - a, av = x - bv; o.t = a - av + (b - bv); } d3.geo.stream = function(object, listener) { if (object && d3_geo_streamObjectType.hasOwnProperty(object.type)) { d3_geo_streamObjectType[object.type](object, listener); } else { d3_geo_streamGeometry(object, listener); } }; function d3_geo_streamGeometry(geometry, listener) { if (geometry && d3_geo_streamGeometryType.hasOwnProperty(geometry.type)) { d3_geo_streamGeometryType[geometry.type](geometry, listener); } } var d3_geo_streamObjectType = { Feature: function(feature, listener) { d3_geo_streamGeometry(feature.geometry, listener); }, FeatureCollection: function(object, listener) { var features = object.features, i = -1, n = features.length; while (++i < n) d3_geo_streamGeometry(features[i].geometry, listener); } }; var d3_geo_streamGeometryType = { Sphere: function(object, listener) { listener.sphere(); }, Point: function(object, listener) { object = object.coordinates; listener.point(object[0], object[1], object[2]); }, MultiPoint: function(object, listener) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) object = coordinates[i], listener.point(object[0], object[1], object[2]); }, LineString: function(object, listener) { d3_geo_streamLine(object.coordinates, listener, 0); }, MultiLineString: function(object, listener) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) d3_geo_streamLine(coordinates[i], listener, 0); }, Polygon: function(object, listener) { d3_geo_streamPolygon(object.coordinates, listener); }, MultiPolygon: function(object, listener) { var coordinates = object.coordinates, i = -1, n = coordinates.length; while (++i < n) d3_geo_streamPolygon(coordinates[i], listener); }, GeometryCollection: function(object, listener) { var geometries = object.geometries, i = -1, n = geometries.length; while (++i < n) d3_geo_streamGeometry(geometries[i], listener); } }; function d3_geo_streamLine(coordinates, listener, closed) { var i = -1, n = coordinates.length - closed, coordinate; listener.lineStart(); while (++i < n) coordinate = coordinates[i], listener.point(coordinate[0], coordinate[1], coordinate[2]); listener.lineEnd(); } function d3_geo_streamPolygon(coordinates, listener) { var i = -1, n = coordinates.length; listener.polygonStart(); while (++i < n) d3_geo_streamLine(coordinates[i], listener, 1); listener.polygonEnd(); } d3.geo.area = function(object) { d3_geo_areaSum = 0; d3.geo.stream(object, d3_geo_area); return d3_geo_areaSum; }; var d3_geo_areaSum, d3_geo_areaRingSum = new d3_adder(); var d3_geo_area = { sphere: function() { d3_geo_areaSum += 4 * Ď€; }, point: d3_noop, lineStart: d3_noop, lineEnd: d3_noop, polygonStart: function() { d3_geo_areaRingSum.reset(); d3_geo_area.lineStart = d3_geo_areaRingStart; }, polygonEnd: function() { var area = 2 * d3_geo_areaRingSum; d3_geo_areaSum += area < 0 ? 4 * Ď€ + area : area; d3_geo_area.lineStart = d3_geo_area.lineEnd = d3_geo_area.point = d3_noop; } }; function d3_geo_areaRingStart() { var λ00, φ00, λ0, cosφ0, sinφ0; d3_geo_area.point = function(λ, φ) { d3_geo_area.point = nextPoint; λ0 = (λ00 = λ) * d3_radians, cosφ0 = Math.cos(φ = (φ00 = φ) * d3_radians / 2 + Ď€ / 4), sinφ0 = Math.sin(φ); }; function nextPoint(λ, φ) { λ *= d3_radians; φ = φ * d3_radians / 2 + Ď€ / 4; var dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, cosφ = Math.cos(φ), sinφ = Math.sin(φ), k = sinφ0 * sinφ, u = cosφ0 * cosφ + k * Math.cos(adλ), v = k * sdλ * Math.sin(adλ); d3_geo_areaRingSum.add(Math.atan2(v, u)); λ0 = λ, cosφ0 = cosφ, sinφ0 = sinφ; } d3_geo_area.lineEnd = function() { nextPoint(λ00, φ00); }; } function d3_geo_cartesian(spherical) { var λ = spherical[0], φ = spherical[1], cosφ = Math.cos(φ); return [ cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ) ]; } function d3_geo_cartesianDot(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; } function d3_geo_cartesianCross(a, b) { return [ a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0] ]; } function d3_geo_cartesianAdd(a, b) { a[0] += b[0]; a[1] += b[1]; a[2] += b[2]; } function d3_geo_cartesianScale(vector, k) { return [ vector[0] * k, vector[1] * k, vector[2] * k ]; } function d3_geo_cartesianNormalize(d) { var l = Math.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); d[0] /= l; d[1] /= l; d[2] /= l; } function d3_geo_spherical(cartesian) { return [ Math.atan2(cartesian[1], cartesian[0]), d3_asin(cartesian[2]) ]; } function d3_geo_sphericalEqual(a, b) { return abs(a[0] - b[0]) < ε && abs(a[1] - b[1]) < ε; } d3.geo.bounds = function() { var λ0, φ0, λ1, φ1, λ_, λ__, φ__, p0, dλSum, ranges, range; var bound = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { bound.point = ringPoint; bound.lineStart = ringStart; bound.lineEnd = ringEnd; dλSum = 0; d3_geo_area.polygonStart(); }, polygonEnd: function() { d3_geo_area.polygonEnd(); bound.point = point; bound.lineStart = lineStart; bound.lineEnd = lineEnd; if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90); else if (dλSum > ε) φ1 = 90; else if (dλSum < -ε) φ0 = -90; range[0] = λ0, range[1] = λ1; } }; function point(λ, φ) { ranges.push(range = [ λ0 = λ, λ1 = λ ]); if (φ < φ0) φ0 = φ; if (φ > φ1) φ1 = φ; } function linePoint(λ, φ) { var p = d3_geo_cartesian([ λ * d3_radians, φ * d3_radians ]); if (p0) { var normal = d3_geo_cartesianCross(p0, p), equatorial = [ normal[1], -normal[0], 0 ], inflection = d3_geo_cartesianCross(equatorial, normal); d3_geo_cartesianNormalize(inflection); inflection = d3_geo_spherical(inflection); var dλ = λ - λ_, s = dλ > 0 ? 1 : -1, λi = inflection[0] * d3_degrees * s, antimeridian = abs(dλ) > 180; if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) { var φi = inflection[1] * d3_degrees; if (φi > φ1) φ1 = φi; } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) { var φi = -inflection[1] * d3_degrees; if (φi < φ0) φ0 = φi; } else { if (φ < φ0) φ0 = φ; if (φ > φ1) φ1 = φ; } if (antimeridian) { if (λ < λ_) { if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; } else { if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; } } else { if (λ1 >= λ0) { if (λ < λ0) λ0 = λ; if (λ > λ1) λ1 = λ; } else { if (λ > λ_) { if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ; } else { if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ; } } } } else { point(λ, φ); } p0 = p, λ_ = λ; } function lineStart() { bound.point = linePoint; } function lineEnd() { range[0] = λ0, range[1] = λ1; bound.point = point; p0 = null; } function ringPoint(λ, φ) { if (p0) { var dλ = λ - λ_; dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ; } else λ__ = λ, φ__ = φ; d3_geo_area.point(λ, φ); linePoint(λ, φ); } function ringStart() { d3_geo_area.lineStart(); } function ringEnd() { ringPoint(λ__, φ__); d3_geo_area.lineEnd(); if (abs(dλSum) > ε) λ0 = -(λ1 = 180); range[0] = λ0, range[1] = λ1; p0 = null; } function angle(λ0, λ1) { return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; } function compareRanges(a, b) { return a[0] - b[0]; } function withinRange(x, range) { return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; } return function(feature) { φ1 = λ1 = -(λ0 = φ0 = Infinity); ranges = []; d3.geo.stream(feature, bound); var n = ranges.length; if (n) { ranges.sort(compareRanges); for (var i = 1, a = ranges[0], b, merged = [ a ]; i < n; ++i) { b = ranges[i]; if (withinRange(b[0], a) || withinRange(b[1], a)) { if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; } else { merged.push(a = b); } } var best = -Infinity, dλ; for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) { b = merged[i]; if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1]; } } ranges = range = null; return λ0 === Infinity || φ0 === Infinity ? [ [ NaN, NaN ], [ NaN, NaN ] ] : [ [ λ0, φ0 ], [ λ1, φ1 ] ]; }; }(); d3.geo.centroid = function(object) { d3_geo_centroidW0 = d3_geo_centroidW1 = d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; d3.geo.stream(object, d3_geo_centroid); var x = d3_geo_centroidX2, y = d3_geo_centroidY2, z = d3_geo_centroidZ2, m = x * x + y * y + z * z; if (m < ε2) { x = d3_geo_centroidX1, y = d3_geo_centroidY1, z = d3_geo_centroidZ1; if (d3_geo_centroidW1 < ε) x = d3_geo_centroidX0, y = d3_geo_centroidY0, z = d3_geo_centroidZ0; m = x * x + y * y + z * z; if (m < ε2) return [ NaN, NaN ]; } return [ Math.atan2(y, x) * d3_degrees, d3_asin(z / Math.sqrt(m)) * d3_degrees ]; }; var d3_geo_centroidW0, d3_geo_centroidW1, d3_geo_centroidX0, d3_geo_centroidY0, d3_geo_centroidZ0, d3_geo_centroidX1, d3_geo_centroidY1, d3_geo_centroidZ1, d3_geo_centroidX2, d3_geo_centroidY2, d3_geo_centroidZ2; var d3_geo_centroid = { sphere: d3_noop, point: d3_geo_centroidPoint, lineStart: d3_geo_centroidLineStart, lineEnd: d3_geo_centroidLineEnd, polygonStart: function() { d3_geo_centroid.lineStart = d3_geo_centroidRingStart; }, polygonEnd: function() { d3_geo_centroid.lineStart = d3_geo_centroidLineStart; } }; function d3_geo_centroidPoint(λ, φ) { λ *= d3_radians; var cosφ = Math.cos(φ *= d3_radians); d3_geo_centroidPointXYZ(cosφ * Math.cos(λ), cosφ * Math.sin(λ), Math.sin(φ)); } function d3_geo_centroidPointXYZ(x, y, z) { ++d3_geo_centroidW0; d3_geo_centroidX0 += (x - d3_geo_centroidX0) / d3_geo_centroidW0; d3_geo_centroidY0 += (y - d3_geo_centroidY0) / d3_geo_centroidW0; d3_geo_centroidZ0 += (z - d3_geo_centroidZ0) / d3_geo_centroidW0; } function d3_geo_centroidLineStart() { var x0, y0, z0; d3_geo_centroid.point = function(λ, φ) { λ *= d3_radians; var cosφ = Math.cos(φ *= d3_radians); x0 = cosφ * Math.cos(λ); y0 = cosφ * Math.sin(λ); z0 = Math.sin(φ); d3_geo_centroid.point = nextPoint; d3_geo_centroidPointXYZ(x0, y0, z0); }; function nextPoint(λ, φ) { λ *= d3_radians; var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), w = Math.atan2(Math.sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); d3_geo_centroidW1 += w; d3_geo_centroidX1 += w * (x0 + (x0 = x)); d3_geo_centroidY1 += w * (y0 + (y0 = y)); d3_geo_centroidZ1 += w * (z0 + (z0 = z)); d3_geo_centroidPointXYZ(x0, y0, z0); } } function d3_geo_centroidLineEnd() { d3_geo_centroid.point = d3_geo_centroidPoint; } function d3_geo_centroidRingStart() { var λ00, φ00, x0, y0, z0; d3_geo_centroid.point = function(λ, φ) { λ00 = λ, φ00 = φ; d3_geo_centroid.point = nextPoint; λ *= d3_radians; var cosφ = Math.cos(φ *= d3_radians); x0 = cosφ * Math.cos(λ); y0 = cosφ * Math.sin(λ); z0 = Math.sin(φ); d3_geo_centroidPointXYZ(x0, y0, z0); }; d3_geo_centroid.lineEnd = function() { nextPoint(λ00, φ00); d3_geo_centroid.lineEnd = d3_geo_centroidLineEnd; d3_geo_centroid.point = d3_geo_centroidPoint; }; function nextPoint(λ, φ) { λ *= d3_radians; var cosφ = Math.cos(φ *= d3_radians), x = cosφ * Math.cos(λ), y = cosφ * Math.sin(λ), z = Math.sin(φ), cx = y0 * z - z0 * y, cy = z0 * x - x0 * z, cz = x0 * y - y0 * x, m = Math.sqrt(cx * cx + cy * cy + cz * cz), u = x0 * x + y0 * y + z0 * z, v = m && -d3_acos(u) / m, w = Math.atan2(m, u); d3_geo_centroidX2 += v * cx; d3_geo_centroidY2 += v * cy; d3_geo_centroidZ2 += v * cz; d3_geo_centroidW1 += w; d3_geo_centroidX1 += w * (x0 + (x0 = x)); d3_geo_centroidY1 += w * (y0 + (y0 = y)); d3_geo_centroidZ1 += w * (z0 + (z0 = z)); d3_geo_centroidPointXYZ(x0, y0, z0); } } function d3_true() { return true; } function d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener) { var subject = [], clip = []; segments.forEach(function(segment) { if ((n = segment.length - 1) <= 0) return; var n, p0 = segment[0], p1 = segment[n]; if (d3_geo_sphericalEqual(p0, p1)) { listener.lineStart(); for (var i = 0; i < n; ++i) listener.point((p0 = segment[i])[0], p0[1]); listener.lineEnd(); return; } var a = new d3_geo_clipPolygonIntersection(p0, segment, null, true), b = new d3_geo_clipPolygonIntersection(p0, null, a, false); a.o = b; subject.push(a); clip.push(b); a = new d3_geo_clipPolygonIntersection(p1, segment, null, false); b = new d3_geo_clipPolygonIntersection(p1, null, a, true); a.o = b; subject.push(a); clip.push(b); }); clip.sort(compare); d3_geo_clipPolygonLinkCircular(subject); d3_geo_clipPolygonLinkCircular(clip); if (!subject.length) return; for (var i = 0, entry = clipStartInside, n = clip.length; i < n; ++i) { clip[i].e = entry = !entry; } var start = subject[0], points, point; while (1) { var current = start, isSubject = true; while (current.v) if ((current = current.n) === start) return; points = current.z; listener.lineStart(); do { current.v = current.o.v = true; if (current.e) { if (isSubject) { for (var i = 0, n = points.length; i < n; ++i) listener.point((point = points[i])[0], point[1]); } else { interpolate(current.x, current.n.x, 1, listener); } current = current.n; } else { if (isSubject) { points = current.p.z; for (var i = points.length - 1; i >= 0; --i) listener.point((point = points[i])[0], point[1]); } else { interpolate(current.x, current.p.x, -1, listener); } current = current.p; } current = current.o; points = current.z; isSubject = !isSubject; } while (!current.v); listener.lineEnd(); } } function d3_geo_clipPolygonLinkCircular(array) { if (!(n = array.length)) return; var n, i = 0, a = array[0], b; while (++i < n) { a.n = b = array[i]; b.p = a; a = b; } a.n = b = array[0]; b.p = a; } function d3_geo_clipPolygonIntersection(point, points, other, entry) { this.x = point; this.z = points; this.o = other; this.e = entry; this.v = false; this.n = this.p = null; } function d3_geo_clip(pointVisible, clipLine, interpolate, clipStart) { return function(rotate, listener) { var line = clipLine(listener), rotatedClipStart = rotate.invert(clipStart[0], clipStart[1]); var clip = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { clip.point = pointRing; clip.lineStart = ringStart; clip.lineEnd = ringEnd; segments = []; polygon = []; }, polygonEnd: function() { clip.point = point; clip.lineStart = lineStart; clip.lineEnd = lineEnd; segments = d3.merge(segments); var clipStartInside = d3_geo_pointInPolygon(rotatedClipStart, polygon); if (segments.length) { if (!polygonStarted) listener.polygonStart(), polygonStarted = true; d3_geo_clipPolygon(segments, d3_geo_clipSort, clipStartInside, interpolate, listener); } else if (clipStartInside) { if (!polygonStarted) listener.polygonStart(), polygonStarted = true; listener.lineStart(); interpolate(null, null, 1, listener); listener.lineEnd(); } if (polygonStarted) listener.polygonEnd(), polygonStarted = false; segments = polygon = null; }, sphere: function() { listener.polygonStart(); listener.lineStart(); interpolate(null, null, 1, listener); listener.lineEnd(); listener.polygonEnd(); } }; function point(λ, φ) { var point = rotate(λ, φ); if (pointVisible(λ = point[0], φ = point[1])) listener.point(λ, φ); } function pointLine(λ, φ) { var point = rotate(λ, φ); line.point(point[0], point[1]); } function lineStart() { clip.point = pointLine; line.lineStart(); } function lineEnd() { clip.point = point; line.lineEnd(); } var segments; var buffer = d3_geo_clipBufferListener(), ringListener = clipLine(buffer), polygonStarted = false, polygon, ring; function pointRing(λ, φ) { ring.push([ λ, φ ]); var point = rotate(λ, φ); ringListener.point(point[0], point[1]); } function ringStart() { ringListener.lineStart(); ring = []; } function ringEnd() { pointRing(ring[0][0], ring[0][1]); ringListener.lineEnd(); var clean = ringListener.clean(), ringSegments = buffer.buffer(), segment, n = ringSegments.length; ring.pop(); polygon.push(ring); ring = null; if (!n) return; if (clean & 1) { segment = ringSegments[0]; var n = segment.length - 1, i = -1, point; if (n > 0) { if (!polygonStarted) listener.polygonStart(), polygonStarted = true; listener.lineStart(); while (++i < n) listener.point((point = segment[i])[0], point[1]); listener.lineEnd(); } return; } if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); segments.push(ringSegments.filter(d3_geo_clipSegmentLength1)); } return clip; }; } function d3_geo_clipSegmentLength1(segment) { return segment.length > 1; } function d3_geo_clipBufferListener() { var lines = [], line; return { lineStart: function() { lines.push(line = []); }, point: function(λ, φ) { line.push([ λ, φ ]); }, lineEnd: d3_noop, buffer: function() { var buffer = lines; lines = []; line = null; return buffer; }, rejoin: function() { if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); } }; } function d3_geo_clipSort(a, b) { return ((a = a.x)[0] < 0 ? a[1] - halfĎ€ - ε : halfĎ€ - a[1]) - ((b = b.x)[0] < 0 ? b[1] - halfĎ€ - ε : halfĎ€ - b[1]); } function d3_geo_pointInPolygon(point, polygon) { var meridian = point[0], parallel = point[1], meridianNormal = [ Math.sin(meridian), -Math.cos(meridian), 0 ], polarAngle = 0, winding = 0; d3_geo_areaRingSum.reset(); for (var i = 0, n = polygon.length; i < n; ++i) { var ring = polygon[i], m = ring.length; if (!m) continue; var point0 = ring[0], λ0 = point0[0], φ0 = point0[1] / 2 + Ď€ / 4, sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), j = 1; while (true) { if (j === m) j = 0; point = ring[j]; var λ = point[0], φ = point[1] / 2 + Ď€ / 4, sinφ = Math.sin(φ), cosφ = Math.cos(φ), dλ = λ - λ0, sdλ = dλ >= 0 ? 1 : -1, adλ = sdλ * dλ, antimeridian = adλ > Ď€, k = sinφ0 * sinφ; d3_geo_areaRingSum.add(Math.atan2(k * sdλ * Math.sin(adλ), cosφ0 * cosφ + k * Math.cos(adλ))); polarAngle += antimeridian ? dλ + sdλ * Ď„ : dλ; if (antimeridian ^ λ0 >= meridian ^ λ >= meridian) { var arc = d3_geo_cartesianCross(d3_geo_cartesian(point0), d3_geo_cartesian(point)); d3_geo_cartesianNormalize(arc); var intersection = d3_geo_cartesianCross(meridianNormal, arc); d3_geo_cartesianNormalize(intersection); var φarc = (antimeridian ^ dλ >= 0 ? -1 : 1) * d3_asin(intersection[2]); if (parallel > φarc || parallel === φarc && (arc[0] || arc[1])) { winding += antimeridian ^ dλ >= 0 ? 1 : -1; } } if (!j++) break; λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ, point0 = point; } } return (polarAngle < -ε || polarAngle < ε && d3_geo_areaRingSum < 0) ^ winding & 1; } var d3_geo_clipAntimeridian = d3_geo_clip(d3_true, d3_geo_clipAntimeridianLine, d3_geo_clipAntimeridianInterpolate, [ -Ď€, -Ď€ / 2 ]); function d3_geo_clipAntimeridianLine(listener) { var λ0 = NaN, φ0 = NaN, sλ0 = NaN, clean; return { lineStart: function() { listener.lineStart(); clean = 1; }, point: function(λ1, φ1) { var sλ1 = λ1 > 0 ? Ď€ : -Ď€, dλ = abs(λ1 - λ0); if (abs(dλ - Ď€) < ε) { listener.point(λ0, φ0 = (φ0 + φ1) / 2 > 0 ? halfĎ€ : -halfĎ€); listener.point(sλ0, φ0); listener.lineEnd(); listener.lineStart(); listener.point(sλ1, φ0); listener.point(λ1, φ0); clean = 0; } else if (sλ0 !== sλ1 && dλ >= Ď€) { if (abs(λ0 - sλ0) < ε) λ0 -= sλ0 * ε; if (abs(λ1 - sλ1) < ε) λ1 -= sλ1 * ε; φ0 = d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1); listener.point(sλ0, φ0); listener.lineEnd(); listener.lineStart(); listener.point(sλ1, φ0); clean = 0; } listener.point(λ0 = λ1, φ0 = φ1); sλ0 = sλ1; }, lineEnd: function() { listener.lineEnd(); λ0 = φ0 = NaN; }, clean: function() { return 2 - clean; } }; } function d3_geo_clipAntimeridianIntersect(λ0, φ0, λ1, φ1) { var cosφ0, cosφ1, sinλ0_λ1 = Math.sin(λ0 - λ1); return abs(sinλ0_λ1) > ε ? Math.atan((Math.sin(φ0) * (cosφ1 = Math.cos(φ1)) * Math.sin(λ1) - Math.sin(φ1) * (cosφ0 = Math.cos(φ0)) * Math.sin(λ0)) / (cosφ0 * cosφ1 * sinλ0_λ1)) : (φ0 + φ1) / 2; } function d3_geo_clipAntimeridianInterpolate(from, to, direction, listener) { var φ; if (from == null) { φ = direction * halfĎ€; listener.point(-Ď€, φ); listener.point(0, φ); listener.point(Ď€, φ); listener.point(Ď€, 0); listener.point(Ď€, -φ); listener.point(0, -φ); listener.point(-Ď€, -φ); listener.point(-Ď€, 0); listener.point(-Ď€, φ); } else if (abs(from[0] - to[0]) > ε) { var s = from[0] < to[0] ? Ď€ : -Ď€; φ = direction * s / 2; listener.point(-s, φ); listener.point(0, φ); listener.point(s, φ); } else { listener.point(to[0], to[1]); } } function d3_geo_clipCircle(radius) { var cr = Math.cos(radius), smallRadius = cr > 0, notHemisphere = abs(cr) > ε, interpolate = d3_geo_circleInterpolate(radius, 6 * d3_radians); return d3_geo_clip(visible, clipLine, interpolate, smallRadius ? [ 0, -radius ] : [ -Ď€, radius - Ď€ ]); function visible(λ, φ) { return Math.cos(λ) * Math.cos(φ) > cr; } function clipLine(listener) { var point0, c0, v0, v00, clean; return { lineStart: function() { v00 = v0 = false; clean = 1; }, point: function(λ, φ) { var point1 = [ λ, φ ], point2, v = visible(λ, φ), c = smallRadius ? v ? 0 : code(λ, φ) : v ? code(λ + (λ < 0 ? Ď€ : -Ď€), φ) : 0; if (!point0 && (v00 = v0 = v)) listener.lineStart(); if (v !== v0) { point2 = intersect(point0, point1); if (d3_geo_sphericalEqual(point0, point2) || d3_geo_sphericalEqual(point1, point2)) { point1[0] += ε; point1[1] += ε; v = visible(point1[0], point1[1]); } } if (v !== v0) { clean = 0; if (v) { listener.lineStart(); point2 = intersect(point1, point0); listener.point(point2[0], point2[1]); } else { point2 = intersect(point0, point1); listener.point(point2[0], point2[1]); listener.lineEnd(); } point0 = point2; } else if (notHemisphere && point0 && smallRadius ^ v) { var t; if (!(c & c0) && (t = intersect(point1, point0, true))) { clean = 0; if (smallRadius) { listener.lineStart(); listener.point(t[0][0], t[0][1]); listener.point(t[1][0], t[1][1]); listener.lineEnd(); } else { listener.point(t[1][0], t[1][1]); listener.lineEnd(); listener.lineStart(); listener.point(t[0][0], t[0][1]); } } } if (v && (!point0 || !d3_geo_sphericalEqual(point0, point1))) { listener.point(point1[0], point1[1]); } point0 = point1, v0 = v, c0 = c; }, lineEnd: function() { if (v0) listener.lineEnd(); point0 = null; }, clean: function() { return clean | (v00 && v0) << 1; } }; } function intersect(a, b, two) { var pa = d3_geo_cartesian(a), pb = d3_geo_cartesian(b); var n1 = [ 1, 0, 0 ], n2 = d3_geo_cartesianCross(pa, pb), n2n2 = d3_geo_cartesianDot(n2, n2), n1n2 = n2[0], determinant = n2n2 - n1n2 * n1n2; if (!determinant) return !two && a; var c1 = cr * n2n2 / determinant, c2 = -cr * n1n2 / determinant, n1xn2 = d3_geo_cartesianCross(n1, n2), A = d3_geo_cartesianScale(n1, c1), B = d3_geo_cartesianScale(n2, c2); d3_geo_cartesianAdd(A, B); var u = n1xn2, w = d3_geo_cartesianDot(A, u), uu = d3_geo_cartesianDot(u, u), t2 = w * w - uu * (d3_geo_cartesianDot(A, A) - 1); if (t2 < 0) return; var t = Math.sqrt(t2), q = d3_geo_cartesianScale(u, (-w - t) / uu); d3_geo_cartesianAdd(q, A); q = d3_geo_spherical(q); if (!two) return q; var λ0 = a[0], λ1 = b[0], φ0 = a[1], φ1 = b[1], z; if (λ1 < λ0) z = λ0, λ0 = λ1, λ1 = z; var δλ = λ1 - λ0, polar = abs(δλ - Ď€) < ε, meridian = polar || δλ < ε; if (!polar && φ1 < φ0) z = φ0, φ0 = φ1, φ1 = z; if (meridian ? polar ? φ0 + φ1 > 0 ^ q[1] < (abs(q[0] - λ0) < ε ? φ0 : φ1) : φ0 <= q[1] && q[1] <= φ1 : δλ > Ď€ ^ (λ0 <= q[0] && q[0] <= λ1)) { var q1 = d3_geo_cartesianScale(u, (-w + t) / uu); d3_geo_cartesianAdd(q1, A); return [ q, d3_geo_spherical(q1) ]; } } function code(λ, φ) { var r = smallRadius ? radius : Ď€ - radius, code = 0; if (λ < -r) code |= 1; else if (λ > r) code |= 2; if (φ < -r) code |= 4; else if (φ > r) code |= 8; return code; } } function d3_geom_clipLine(x0, y0, x1, y1) { return function(line) { var a = line.a, b = line.b, ax = a.x, ay = a.y, bx = b.x, by = b.y, t0 = 0, t1 = 1, dx = bx - ax, dy = by - ay, r; r = x0 - ax; if (!dx && r > 0) return; r /= dx; if (dx < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dx > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = x1 - ax; if (!dx && r < 0) return; r /= dx; if (dx < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dx > 0) { if (r < t0) return; if (r < t1) t1 = r; } r = y0 - ay; if (!dy && r > 0) return; r /= dy; if (dy < 0) { if (r < t0) return; if (r < t1) t1 = r; } else if (dy > 0) { if (r > t1) return; if (r > t0) t0 = r; } r = y1 - ay; if (!dy && r < 0) return; r /= dy; if (dy < 0) { if (r > t1) return; if (r > t0) t0 = r; } else if (dy > 0) { if (r < t0) return; if (r < t1) t1 = r; } if (t0 > 0) line.a = { x: ax + t0 * dx, y: ay + t0 * dy }; if (t1 < 1) line.b = { x: ax + t1 * dx, y: ay + t1 * dy }; return line; }; } var d3_geo_clipExtentMAX = 1e9; d3.geo.clipExtent = function() { var x0, y0, x1, y1, stream, clip, clipExtent = { stream: function(output) { if (stream) stream.valid = false; stream = clip(output); stream.valid = true; return stream; }, extent: function(_) { if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; clip = d3_geo_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]); if (stream) stream.valid = false, stream = null; return clipExtent; } }; return clipExtent.extent([ [ 0, 0 ], [ 960, 500 ] ]); }; function d3_geo_clipExtent(x0, y0, x1, y1) { return function(listener) { var listener_ = listener, bufferListener = d3_geo_clipBufferListener(), clipLine = d3_geom_clipLine(x0, y0, x1, y1), segments, polygon, ring; var clip = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { listener = bufferListener; segments = []; polygon = []; clean = true; }, polygonEnd: function() { listener = listener_; segments = d3.merge(segments); var clipStartInside = insidePolygon([ x0, y1 ]), inside = clean && clipStartInside, visible = segments.length; if (inside || visible) { listener.polygonStart(); if (inside) { listener.lineStart(); interpolate(null, null, 1, listener); listener.lineEnd(); } if (visible) { d3_geo_clipPolygon(segments, compare, clipStartInside, interpolate, listener); } listener.polygonEnd(); } segments = polygon = ring = null; } }; function insidePolygon(p) { var wn = 0, n = polygon.length, y = p[1]; for (var i = 0; i < n; ++i) { for (var j = 1, v = polygon[i], m = v.length, a = v[0], b; j < m; ++j) { b = v[j]; if (a[1] <= y) { if (b[1] > y && d3_cross2d(a, b, p) > 0) ++wn; } else { if (b[1] <= y && d3_cross2d(a, b, p) < 0) --wn; } a = b; } } return wn !== 0; } function interpolate(from, to, direction, listener) { var a = 0, a1 = 0; if (from == null || (a = corner(from, direction)) !== (a1 = corner(to, direction)) || comparePoints(from, to) < 0 ^ direction > 0) { do { listener.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); } while ((a = (a + direction + 4) % 4) !== a1); } else { listener.point(to[0], to[1]); } } function pointVisible(x, y) { return x0 <= x && x <= x1 && y0 <= y && y <= y1; } function point(x, y) { if (pointVisible(x, y)) listener.point(x, y); } var x__, y__, v__, x_, y_, v_, first, clean; function lineStart() { clip.point = linePoint; if (polygon) polygon.push(ring = []); first = true; v_ = false; x_ = y_ = NaN; } function lineEnd() { if (segments) { linePoint(x__, y__); if (v__ && v_) bufferListener.rejoin(); segments.push(bufferListener.buffer()); } clip.point = point; if (v_) listener.lineEnd(); } function linePoint(x, y) { x = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, x)); y = Math.max(-d3_geo_clipExtentMAX, Math.min(d3_geo_clipExtentMAX, y)); var v = pointVisible(x, y); if (polygon) ring.push([ x, y ]); if (first) { x__ = x, y__ = y, v__ = v; first = false; if (v) { listener.lineStart(); listener.point(x, y); } } else { if (v && v_) listener.point(x, y); else { var l = { a: { x: x_, y: y_ }, b: { x: x, y: y } }; if (clipLine(l)) { if (!v_) { listener.lineStart(); listener.point(l.a.x, l.a.y); } listener.point(l.b.x, l.b.y); if (!v) listener.lineEnd(); clean = false; } else if (v) { listener.lineStart(); listener.point(x, y); clean = false; } } } x_ = x, y_ = y, v_ = v; } return clip; }; function corner(p, direction) { return abs(p[0] - x0) < ε ? direction > 0 ? 0 : 3 : abs(p[0] - x1) < ε ? direction > 0 ? 2 : 1 : abs(p[1] - y0) < ε ? direction > 0 ? 1 : 0 : direction > 0 ? 3 : 2; } function compare(a, b) { return comparePoints(a.x, b.x); } function comparePoints(a, b) { var ca = corner(a, 1), cb = corner(b, 1); return ca !== cb ? ca - cb : ca === 0 ? b[1] - a[1] : ca === 1 ? a[0] - b[0] : ca === 2 ? a[1] - b[1] : b[0] - a[0]; } } function d3_geo_compose(a, b) { function compose(x, y) { return x = a(x, y), b(x[0], x[1]); } if (a.invert && b.invert) compose.invert = function(x, y) { return x = b.invert(x, y), x && a.invert(x[0], x[1]); }; return compose; } function d3_geo_conic(projectAt) { var φ0 = 0, φ1 = Ď€ / 3, m = d3_geo_projectionMutator(projectAt), p = m(φ0, φ1); p.parallels = function(_) { if (!arguments.length) return [ φ0 / Ď€ * 180, φ1 / Ď€ * 180 ]; return m(φ0 = _[0] * Ď€ / 180, φ1 = _[1] * Ď€ / 180); }; return p; } function d3_geo_conicEqualArea(φ0, φ1) { var sinφ0 = Math.sin(φ0), n = (sinφ0 + Math.sin(φ1)) / 2, C = 1 + sinφ0 * (2 * n - sinφ0), Ď0 = Math.sqrt(C) / n; function forward(λ, φ) { var Ď = Math.sqrt(C - 2 * n * Math.sin(φ)) / n; return [ Ď * Math.sin(λ *= n), Ď0 - Ď * Math.cos(λ) ]; } forward.invert = function(x, y) { var Ď0_y = Ď0 - y; return [ Math.atan2(x, Ď0_y) / n, d3_asin((C - (x * x + Ď0_y * Ď0_y) * n * n) / (2 * n)) ]; }; return forward; } (d3.geo.conicEqualArea = function() { return d3_geo_conic(d3_geo_conicEqualArea); }).raw = d3_geo_conicEqualArea; d3.geo.albers = function() { return d3.geo.conicEqualArea().rotate([ 96, 0 ]).center([ -.6, 38.7 ]).parallels([ 29.5, 45.5 ]).scale(1070); }; d3.geo.albersUsa = function() { var lower48 = d3.geo.albers(); var alaska = d3.geo.conicEqualArea().rotate([ 154, 0 ]).center([ -2, 58.5 ]).parallels([ 55, 65 ]); var hawaii = d3.geo.conicEqualArea().rotate([ 157, 0 ]).center([ -3, 19.9 ]).parallels([ 8, 18 ]); var point, pointStream = { point: function(x, y) { point = [ x, y ]; } }, lower48Point, alaskaPoint, hawaiiPoint; function albersUsa(coordinates) { var x = coordinates[0], y = coordinates[1]; point = null; (lower48Point(x, y), point) || (alaskaPoint(x, y), point) || hawaiiPoint(x, y); return point; } albersUsa.invert = function(coordinates) { var k = lower48.scale(), t = lower48.translate(), x = (coordinates[0] - t[0]) / k, y = (coordinates[1] - t[1]) / k; return (y >= .12 && y < .234 && x >= -.425 && x < -.214 ? alaska : y >= .166 && y < .234 && x >= -.214 && x < -.115 ? hawaii : lower48).invert(coordinates); }; albersUsa.stream = function(stream) { var lower48Stream = lower48.stream(stream), alaskaStream = alaska.stream(stream), hawaiiStream = hawaii.stream(stream); return { point: function(x, y) { lower48Stream.point(x, y); alaskaStream.point(x, y); hawaiiStream.point(x, y); }, sphere: function() { lower48Stream.sphere(); alaskaStream.sphere(); hawaiiStream.sphere(); }, lineStart: function() { lower48Stream.lineStart(); alaskaStream.lineStart(); hawaiiStream.lineStart(); }, lineEnd: function() { lower48Stream.lineEnd(); alaskaStream.lineEnd(); hawaiiStream.lineEnd(); }, polygonStart: function() { lower48Stream.polygonStart(); alaskaStream.polygonStart(); hawaiiStream.polygonStart(); }, polygonEnd: function() { lower48Stream.polygonEnd(); alaskaStream.polygonEnd(); hawaiiStream.polygonEnd(); } }; }; albersUsa.precision = function(_) { if (!arguments.length) return lower48.precision(); lower48.precision(_); alaska.precision(_); hawaii.precision(_); return albersUsa; }; albersUsa.scale = function(_) { if (!arguments.length) return lower48.scale(); lower48.scale(_); alaska.scale(_ * .35); hawaii.scale(_); return albersUsa.translate(lower48.translate()); }; albersUsa.translate = function(_) { if (!arguments.length) return lower48.translate(); var k = lower48.scale(), x = +_[0], y = +_[1]; lower48Point = lower48.translate(_).clipExtent([ [ x - .455 * k, y - .238 * k ], [ x + .455 * k, y + .238 * k ] ]).stream(pointStream).point; alaskaPoint = alaska.translate([ x - .307 * k, y + .201 * k ]).clipExtent([ [ x - .425 * k + ε, y + .12 * k + ε ], [ x - .214 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; hawaiiPoint = hawaii.translate([ x - .205 * k, y + .212 * k ]).clipExtent([ [ x - .214 * k + ε, y + .166 * k + ε ], [ x - .115 * k - ε, y + .234 * k - ε ] ]).stream(pointStream).point; return albersUsa; }; return albersUsa.scale(1070); }; var d3_geo_pathAreaSum, d3_geo_pathAreaPolygon, d3_geo_pathArea = { point: d3_noop, lineStart: d3_noop, lineEnd: d3_noop, polygonStart: function() { d3_geo_pathAreaPolygon = 0; d3_geo_pathArea.lineStart = d3_geo_pathAreaRingStart; }, polygonEnd: function() { d3_geo_pathArea.lineStart = d3_geo_pathArea.lineEnd = d3_geo_pathArea.point = d3_noop; d3_geo_pathAreaSum += abs(d3_geo_pathAreaPolygon / 2); } }; function d3_geo_pathAreaRingStart() { var x00, y00, x0, y0; d3_geo_pathArea.point = function(x, y) { d3_geo_pathArea.point = nextPoint; x00 = x0 = x, y00 = y0 = y; }; function nextPoint(x, y) { d3_geo_pathAreaPolygon += y0 * x - x0 * y; x0 = x, y0 = y; } d3_geo_pathArea.lineEnd = function() { nextPoint(x00, y00); }; } var d3_geo_pathBoundsX0, d3_geo_pathBoundsY0, d3_geo_pathBoundsX1, d3_geo_pathBoundsY1; var d3_geo_pathBounds = { point: d3_geo_pathBoundsPoint, lineStart: d3_noop, lineEnd: d3_noop, polygonStart: d3_noop, polygonEnd: d3_noop }; function d3_geo_pathBoundsPoint(x, y) { if (x < d3_geo_pathBoundsX0) d3_geo_pathBoundsX0 = x; if (x > d3_geo_pathBoundsX1) d3_geo_pathBoundsX1 = x; if (y < d3_geo_pathBoundsY0) d3_geo_pathBoundsY0 = y; if (y > d3_geo_pathBoundsY1) d3_geo_pathBoundsY1 = y; } function d3_geo_pathBuffer() { var pointCircle = d3_geo_pathBufferCircle(4.5), buffer = []; var stream = { point: point, lineStart: function() { stream.point = pointLineStart; }, lineEnd: lineEnd, polygonStart: function() { stream.lineEnd = lineEndPolygon; }, polygonEnd: function() { stream.lineEnd = lineEnd; stream.point = point; }, pointRadius: function(_) { pointCircle = d3_geo_pathBufferCircle(_); return stream; }, result: function() { if (buffer.length) { var result = buffer.join(""); buffer = []; return result; } } }; function point(x, y) { buffer.push("M", x, ",", y, pointCircle); } function pointLineStart(x, y) { buffer.push("M", x, ",", y); stream.point = pointLine; } function pointLine(x, y) { buffer.push("L", x, ",", y); } function lineEnd() { stream.point = point; } function lineEndPolygon() { buffer.push("Z"); } return stream; } function d3_geo_pathBufferCircle(radius) { return "m0," + radius + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + "z"; } var d3_geo_pathCentroid = { point: d3_geo_pathCentroidPoint, lineStart: d3_geo_pathCentroidLineStart, lineEnd: d3_geo_pathCentroidLineEnd, polygonStart: function() { d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidRingStart; }, polygonEnd: function() { d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; d3_geo_pathCentroid.lineStart = d3_geo_pathCentroidLineStart; d3_geo_pathCentroid.lineEnd = d3_geo_pathCentroidLineEnd; } }; function d3_geo_pathCentroidPoint(x, y) { d3_geo_centroidX0 += x; d3_geo_centroidY0 += y; ++d3_geo_centroidZ0; } function d3_geo_pathCentroidLineStart() { var x0, y0; d3_geo_pathCentroid.point = function(x, y) { d3_geo_pathCentroid.point = nextPoint; d3_geo_pathCentroidPoint(x0 = x, y0 = y); }; function nextPoint(x, y) { var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); d3_geo_centroidX1 += z * (x0 + x) / 2; d3_geo_centroidY1 += z * (y0 + y) / 2; d3_geo_centroidZ1 += z; d3_geo_pathCentroidPoint(x0 = x, y0 = y); } } function d3_geo_pathCentroidLineEnd() { d3_geo_pathCentroid.point = d3_geo_pathCentroidPoint; } function d3_geo_pathCentroidRingStart() { var x00, y00, x0, y0; d3_geo_pathCentroid.point = function(x, y) { d3_geo_pathCentroid.point = nextPoint; d3_geo_pathCentroidPoint(x00 = x0 = x, y00 = y0 = y); }; function nextPoint(x, y) { var dx = x - x0, dy = y - y0, z = Math.sqrt(dx * dx + dy * dy); d3_geo_centroidX1 += z * (x0 + x) / 2; d3_geo_centroidY1 += z * (y0 + y) / 2; d3_geo_centroidZ1 += z; z = y0 * x - x0 * y; d3_geo_centroidX2 += z * (x0 + x); d3_geo_centroidY2 += z * (y0 + y); d3_geo_centroidZ2 += z * 3; d3_geo_pathCentroidPoint(x0 = x, y0 = y); } d3_geo_pathCentroid.lineEnd = function() { nextPoint(x00, y00); }; } function d3_geo_pathContext(context) { var pointRadius = 4.5; var stream = { point: point, lineStart: function() { stream.point = pointLineStart; }, lineEnd: lineEnd, polygonStart: function() { stream.lineEnd = lineEndPolygon; }, polygonEnd: function() { stream.lineEnd = lineEnd; stream.point = point; }, pointRadius: function(_) { pointRadius = _; return stream; }, result: d3_noop }; function point(x, y) { context.moveTo(x, y); context.arc(x, y, pointRadius, 0, Ď„); } function pointLineStart(x, y) { context.moveTo(x, y); stream.point = pointLine; } function pointLine(x, y) { context.lineTo(x, y); } function lineEnd() { stream.point = point; } function lineEndPolygon() { context.closePath(); } return stream; } function d3_geo_resample(project) { var δ2 = .5, cosMinDistance = Math.cos(30 * d3_radians), maxDepth = 16; function resample(stream) { return (maxDepth ? resampleRecursive : resampleNone)(stream); } function resampleNone(stream) { return d3_geo_transformPoint(stream, function(x, y) { x = project(x, y); stream.point(x[0], x[1]); }); } function resampleRecursive(stream) { var λ00, φ00, x00, y00, a00, b00, c00, λ0, x0, y0, a0, b0, c0; var resample = { point: point, lineStart: lineStart, lineEnd: lineEnd, polygonStart: function() { stream.polygonStart(); resample.lineStart = ringStart; }, polygonEnd: function() { stream.polygonEnd(); resample.lineStart = lineStart; } }; function point(x, y) { x = project(x, y); stream.point(x[0], x[1]); } function lineStart() { x0 = NaN; resample.point = linePoint; stream.lineStart(); } function linePoint(λ, φ) { var c = d3_geo_cartesian([ λ, φ ]), p = project(λ, φ); resampleLineTo(x0, y0, λ0, a0, b0, c0, x0 = p[0], y0 = p[1], λ0 = λ, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); stream.point(x0, y0); } function lineEnd() { resample.point = point; stream.lineEnd(); } function ringStart() { lineStart(); resample.point = ringPoint; resample.lineEnd = ringEnd; } function ringPoint(λ, φ) { linePoint(λ00 = λ, φ00 = φ), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; resample.point = linePoint; } function ringEnd() { resampleLineTo(x0, y0, λ0, a0, b0, c0, x00, y00, λ00, a00, b00, c00, maxDepth, stream); resample.lineEnd = lineEnd; lineEnd(); } return resample; } function resampleLineTo(x0, y0, λ0, a0, b0, c0, x1, y1, λ1, a1, b1, c1, depth, stream) { var dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy; if (d2 > 4 * δ2 && depth--) { var a = a0 + a1, b = b0 + b1, c = c0 + c1, m = Math.sqrt(a * a + b * b + c * c), φ2 = Math.asin(c /= m), λ2 = abs(abs(c) - 1) < ε || abs(λ0 - λ1) < ε ? (λ0 + λ1) / 2 : Math.atan2(b, a), p = project(λ2, φ2), x2 = p[0], y2 = p[1], dx2 = x2 - x0, dy2 = y2 - y0, dz = dy * dx2 - dx * dy2; if (dz * dz / d2 > δ2 || abs((dx * dx2 + dy * dy2) / d2 - .5) > .3 || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { resampleLineTo(x0, y0, λ0, a0, b0, c0, x2, y2, λ2, a /= m, b /= m, c, depth, stream); stream.point(x2, y2); resampleLineTo(x2, y2, λ2, a, b, c, x1, y1, λ1, a1, b1, c1, depth, stream); } } } resample.precision = function(_) { if (!arguments.length) return Math.sqrt(δ2); maxDepth = (δ2 = _ * _) > 0 && 16; return resample; }; return resample; } d3.geo.path = function() { var pointRadius = 4.5, projection, context, projectStream, contextStream, cacheStream; function path(object) { if (object) { if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); if (!cacheStream || !cacheStream.valid) cacheStream = projectStream(contextStream); d3.geo.stream(object, cacheStream); } return contextStream.result(); } path.area = function(object) { d3_geo_pathAreaSum = 0; d3.geo.stream(object, projectStream(d3_geo_pathArea)); return d3_geo_pathAreaSum; }; path.centroid = function(object) { d3_geo_centroidX0 = d3_geo_centroidY0 = d3_geo_centroidZ0 = d3_geo_centroidX1 = d3_geo_centroidY1 = d3_geo_centroidZ1 = d3_geo_centroidX2 = d3_geo_centroidY2 = d3_geo_centroidZ2 = 0; d3.geo.stream(object, projectStream(d3_geo_pathCentroid)); return d3_geo_centroidZ2 ? [ d3_geo_centroidX2 / d3_geo_centroidZ2, d3_geo_centroidY2 / d3_geo_centroidZ2 ] : d3_geo_centroidZ1 ? [ d3_geo_centroidX1 / d3_geo_centroidZ1, d3_geo_centroidY1 / d3_geo_centroidZ1 ] : d3_geo_centroidZ0 ? [ d3_geo_centroidX0 / d3_geo_centroidZ0, d3_geo_centroidY0 / d3_geo_centroidZ0 ] : [ NaN, NaN ]; }; path.bounds = function(object) { d3_geo_pathBoundsX1 = d3_geo_pathBoundsY1 = -(d3_geo_pathBoundsX0 = d3_geo_pathBoundsY0 = Infinity); d3.geo.stream(object, projectStream(d3_geo_pathBounds)); return [ [ d3_geo_pathBoundsX0, d3_geo_pathBoundsY0 ], [ d3_geo_pathBoundsX1, d3_geo_pathBoundsY1 ] ]; }; path.projection = function(_) { if (!arguments.length) return projection; projectStream = (projection = _) ? _.stream || d3_geo_pathProjectStream(_) : d3_identity; return reset(); }; path.context = function(_) { if (!arguments.length) return context; contextStream = (context = _) == null ? new d3_geo_pathBuffer() : new d3_geo_pathContext(_); if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); return reset(); }; path.pointRadius = function(_) { if (!arguments.length) return pointRadius; pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); return path; }; function reset() { cacheStream = null; return path; } return path.projection(d3.geo.albersUsa()).context(null); }; function d3_geo_pathProjectStream(project) { var resample = d3_geo_resample(function(x, y) { return project([ x * d3_degrees, y * d3_degrees ]); }); return function(stream) { return d3_geo_projectionRadians(resample(stream)); }; } d3.geo.transform = function(methods) { return { stream: function(stream) { var transform = new d3_geo_transform(stream); for (var k in methods) transform[k] = methods[k]; return transform; } }; }; function d3_geo_transform(stream) { this.stream = stream; } d3_geo_transform.prototype = { point: function(x, y) { this.stream.point(x, y); }, sphere: function() { this.stream.sphere(); }, lineStart: function() { this.stream.lineStart(); }, lineEnd: function() { this.stream.lineEnd(); }, polygonStart: function() { this.stream.polygonStart(); }, polygonEnd: function() { this.stream.polygonEnd(); } }; function d3_geo_transformPoint(stream, point) { return { point: point, sphere: function() { stream.sphere(); }, lineStart: function() { stream.lineStart(); }, lineEnd: function() { stream.lineEnd(); }, polygonStart: function() { stream.polygonStart(); }, polygonEnd: function() { stream.polygonEnd(); } }; } d3.geo.projection = d3_geo_projection; d3.geo.projectionMutator = d3_geo_projectionMutator; function d3_geo_projection(project) { return d3_geo_projectionMutator(function() { return project; })(); } function d3_geo_projectionMutator(projectAt) { var project, rotate, projectRotate, projectResample = d3_geo_resample(function(x, y) { x = project(x, y); return [ x[0] * k + δx, δy - x[1] * k ]; }), k = 150, x = 480, y = 250, λ = 0, φ = 0, δλ = 0, δφ = 0, δγ = 0, δx, δy, preclip = d3_geo_clipAntimeridian, postclip = d3_identity, clipAngle = null, clipExtent = null, stream; function projection(point) { point = projectRotate(point[0] * d3_radians, point[1] * d3_radians); return [ point[0] * k + δx, δy - point[1] * k ]; } function invert(point) { point = projectRotate.invert((point[0] - δx) / k, (δy - point[1]) / k); return point && [ point[0] * d3_degrees, point[1] * d3_degrees ]; } projection.stream = function(output) { if (stream) stream.valid = false; stream = d3_geo_projectionRadians(preclip(rotate, projectResample(postclip(output)))); stream.valid = true; return stream; }; projection.clipAngle = function(_) { if (!arguments.length) return clipAngle; preclip = _ == null ? (clipAngle = _, d3_geo_clipAntimeridian) : d3_geo_clipCircle((clipAngle = +_) * d3_radians); return invalidate(); }; projection.clipExtent = function(_) { if (!arguments.length) return clipExtent; clipExtent = _; postclip = _ ? d3_geo_clipExtent(_[0][0], _[0][1], _[1][0], _[1][1]) : d3_identity; return invalidate(); }; projection.scale = function(_) { if (!arguments.length) return k; k = +_; return reset(); }; projection.translate = function(_) { if (!arguments.length) return [ x, y ]; x = +_[0]; y = +_[1]; return reset(); }; projection.center = function(_) { if (!arguments.length) return [ λ * d3_degrees, φ * d3_degrees ]; λ = _[0] % 360 * d3_radians; φ = _[1] % 360 * d3_radians; return reset(); }; projection.rotate = function(_) { if (!arguments.length) return [ δλ * d3_degrees, δφ * d3_degrees, δγ * d3_degrees ]; δλ = _[0] % 360 * d3_radians; δφ = _[1] % 360 * d3_radians; δγ = _.length > 2 ? _[2] % 360 * d3_radians : 0; return reset(); }; d3.rebind(projection, projectResample, "precision"); function reset() { projectRotate = d3_geo_compose(rotate = d3_geo_rotation(δλ, δφ, δγ), project); var center = project(λ, φ); δx = x - center[0] * k; δy = y + center[1] * k; return invalidate(); } function invalidate() { if (stream) stream.valid = false, stream = null; return projection; } return function() { project = projectAt.apply(this, arguments); projection.invert = project.invert && invert; return reset(); }; } function d3_geo_projectionRadians(stream) { return d3_geo_transformPoint(stream, function(x, y) { stream.point(x * d3_radians, y * d3_radians); }); } function d3_geo_equirectangular(λ, φ) { return [ λ, φ ]; } (d3.geo.equirectangular = function() { return d3_geo_projection(d3_geo_equirectangular); }).raw = d3_geo_equirectangular.invert = d3_geo_equirectangular; d3.geo.rotation = function(rotate) { rotate = d3_geo_rotation(rotate[0] % 360 * d3_radians, rotate[1] * d3_radians, rotate.length > 2 ? rotate[2] * d3_radians : 0); function forward(coordinates) { coordinates = rotate(coordinates[0] * d3_radians, coordinates[1] * d3_radians); return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; } forward.invert = function(coordinates) { coordinates = rotate.invert(coordinates[0] * d3_radians, coordinates[1] * d3_radians); return coordinates[0] *= d3_degrees, coordinates[1] *= d3_degrees, coordinates; }; return forward; }; function d3_geo_identityRotation(λ, φ) { return [ λ > Ď€ ? λ - Ď„ : λ < -Ď€ ? λ + Ď„ : λ, φ ]; } d3_geo_identityRotation.invert = d3_geo_equirectangular; function d3_geo_rotation(δλ, δφ, δγ) { return δλ ? δφ || δγ ? d3_geo_compose(d3_geo_rotationλ(δλ), d3_geo_rotationφγ(δφ, δγ)) : d3_geo_rotationλ(δλ) : δφ || δγ ? d3_geo_rotationφγ(δφ, δγ) : d3_geo_identityRotation; } function d3_geo_forwardRotationλ(δλ) { return function(λ, φ) { return λ += δλ, [ λ > Ď€ ? λ - Ď„ : λ < -Ď€ ? λ + Ď„ : λ, φ ]; }; } function d3_geo_rotationλ(δλ) { var rotation = d3_geo_forwardRotationλ(δλ); rotation.invert = d3_geo_forwardRotationλ(-δλ); return rotation; } function d3_geo_rotationφγ(δφ, δγ) { var cosδφ = Math.cos(δφ), sinδφ = Math.sin(δφ), cosδγ = Math.cos(δγ), sinδγ = Math.sin(δγ); function rotation(λ, φ) { var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδφ + x * sinδφ; return [ Math.atan2(y * cosδγ - k * sinδγ, x * cosδφ - z * sinδφ), d3_asin(k * cosδγ + y * sinδγ) ]; } rotation.invert = function(λ, φ) { var cosφ = Math.cos(φ), x = Math.cos(λ) * cosφ, y = Math.sin(λ) * cosφ, z = Math.sin(φ), k = z * cosδγ - y * sinδγ; return [ Math.atan2(y * cosδγ + z * sinδγ, x * cosδφ + k * sinδφ), d3_asin(k * cosδφ - x * sinδφ) ]; }; return rotation; } d3.geo.circle = function() { var origin = [ 0, 0 ], angle, precision = 6, interpolate; function circle() { var center = typeof origin === "function" ? origin.apply(this, arguments) : origin, rotate = d3_geo_rotation(-center[0] * d3_radians, -center[1] * d3_radians, 0).invert, ring = []; interpolate(null, null, 1, { point: function(x, y) { ring.push(x = rotate(x, y)); x[0] *= d3_degrees, x[1] *= d3_degrees; } }); return { type: "Polygon", coordinates: [ ring ] }; } circle.origin = function(x) { if (!arguments.length) return origin; origin = x; return circle; }; circle.angle = function(x) { if (!arguments.length) return angle; interpolate = d3_geo_circleInterpolate((angle = +x) * d3_radians, precision * d3_radians); return circle; }; circle.precision = function(_) { if (!arguments.length) return precision; interpolate = d3_geo_circleInterpolate(angle * d3_radians, (precision = +_) * d3_radians); return circle; }; return circle.angle(90); }; function d3_geo_circleInterpolate(radius, precision) { var cr = Math.cos(radius), sr = Math.sin(radius); return function(from, to, direction, listener) { var step = direction * precision; if (from != null) { from = d3_geo_circleAngle(cr, from); to = d3_geo_circleAngle(cr, to); if (direction > 0 ? from < to : from > to) from += direction * Ď„; } else { from = radius + direction * Ď„; to = radius - .5 * step; } for (var point, t = from; direction > 0 ? t > to : t < to; t -= step) { listener.point((point = d3_geo_spherical([ cr, -sr * Math.cos(t), -sr * Math.sin(t) ]))[0], point[1]); } }; } function d3_geo_circleAngle(cr, point) { var a = d3_geo_cartesian(point); a[0] -= cr; d3_geo_cartesianNormalize(a); var angle = d3_acos(-a[1]); return ((-a[2] < 0 ? -angle : angle) + 2 * Math.PI - ε) % (2 * Math.PI); } d3.geo.distance = function(a, b) { var Δλ = (b[0] - a[0]) * d3_radians, φ0 = a[1] * d3_radians, φ1 = b[1] * d3_radians, sinΔλ = Math.sin(Δλ), cosΔλ = Math.cos(Δλ), sinφ0 = Math.sin(φ0), cosφ0 = Math.cos(φ0), sinφ1 = Math.sin(φ1), cosφ1 = Math.cos(φ1), t; return Math.atan2(Math.sqrt((t = cosφ1 * sinΔλ) * t + (t = cosφ0 * sinφ1 - sinφ0 * cosφ1 * cosΔλ) * t), sinφ0 * sinφ1 + cosφ0 * cosφ1 * cosΔλ); }; d3.geo.graticule = function() { var x1, x0, X1, X0, y1, y0, Y1, Y0, dx = 10, dy = dx, DX = 90, DY = 360, x, y, X, Y, precision = 2.5; function graticule() { return { type: "MultiLineString", coordinates: lines() }; } function lines() { return d3.range(Math.ceil(X0 / DX) * DX, X1, DX).map(X).concat(d3.range(Math.ceil(Y0 / DY) * DY, Y1, DY).map(Y)).concat(d3.range(Math.ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > ε; }).map(x)).concat(d3.range(Math.ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > ε; }).map(y)); } graticule.lines = function() { return lines().map(function(coordinates) { return { type: "LineString", coordinates: coordinates }; }); }; graticule.outline = function() { return { type: "Polygon", coordinates: [ X(X0).concat(Y(Y1).slice(1), X(X1).reverse().slice(1), Y(Y0).reverse().slice(1)) ] }; }; graticule.extent = function(_) { if (!arguments.length) return graticule.minorExtent(); return graticule.majorExtent(_).minorExtent(_); }; graticule.majorExtent = function(_) { if (!arguments.length) return [ [ X0, Y0 ], [ X1, Y1 ] ]; X0 = +_[0][0], X1 = +_[1][0]; Y0 = +_[0][1], Y1 = +_[1][1]; if (X0 > X1) _ = X0, X0 = X1, X1 = _; if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; return graticule.precision(precision); }; graticule.minorExtent = function(_) { if (!arguments.length) return [ [ x0, y0 ], [ x1, y1 ] ]; x0 = +_[0][0], x1 = +_[1][0]; y0 = +_[0][1], y1 = +_[1][1]; if (x0 > x1) _ = x0, x0 = x1, x1 = _; if (y0 > y1) _ = y0, y0 = y1, y1 = _; return graticule.precision(precision); }; graticule.step = function(_) { if (!arguments.length) return graticule.minorStep(); return graticule.majorStep(_).minorStep(_); }; graticule.majorStep = function(_) { if (!arguments.length) return [ DX, DY ]; DX = +_[0], DY = +_[1]; return graticule; }; graticule.minorStep = function(_) { if (!arguments.length) return [ dx, dy ]; dx = +_[0], dy = +_[1]; return graticule; }; graticule.precision = function(_) { if (!arguments.length) return precision; precision = +_; x = d3_geo_graticuleX(y0, y1, 90); y = d3_geo_graticuleY(x0, x1, precision); X = d3_geo_graticuleX(Y0, Y1, 90); Y = d3_geo_graticuleY(X0, X1, precision); return graticule; }; return graticule.majorExtent([ [ -180, -90 + ε ], [ 180, 90 - ε ] ]).minorExtent([ [ -180, -80 - ε ], [ 180, 80 + ε ] ]); }; function d3_geo_graticuleX(y0, y1, dy) { var y = d3.range(y0, y1 - ε, dy).concat(y1); return function(x) { return y.map(function(y) { return [ x, y ]; }); }; } function d3_geo_graticuleY(x0, x1, dx) { var x = d3.range(x0, x1 - ε, dx).concat(x1); return function(y) { return x.map(function(x) { return [ x, y ]; }); }; } function d3_source(d) { return d.source; } function d3_target(d) { return d.target; } d3.geo.greatArc = function() { var source = d3_source, source_, target = d3_target, target_; function greatArc() { return { type: "LineString", coordinates: [ source_ || source.apply(this, arguments), target_ || target.apply(this, arguments) ] }; } greatArc.distance = function() { return d3.geo.distance(source_ || source.apply(this, arguments), target_ || target.apply(this, arguments)); }; greatArc.source = function(_) { if (!arguments.length) return source; source = _, source_ = typeof _ === "function" ? null : _; return greatArc; }; greatArc.target = function(_) { if (!arguments.length) return target; target = _, target_ = typeof _ === "function" ? null : _; return greatArc; }; greatArc.precision = function() { return arguments.length ? greatArc : 0; }; return greatArc; }; d3.geo.interpolate = function(source, target) { return d3_geo_interpolate(source[0] * d3_radians, source[1] * d3_radians, target[0] * d3_radians, target[1] * d3_radians); }; function d3_geo_interpolate(x0, y0, x1, y1) { var cy0 = Math.cos(y0), sy0 = Math.sin(y0), cy1 = Math.cos(y1), sy1 = Math.sin(y1), kx0 = cy0 * Math.cos(x0), ky0 = cy0 * Math.sin(x0), kx1 = cy1 * Math.cos(x1), ky1 = cy1 * Math.sin(x1), d = 2 * Math.asin(Math.sqrt(d3_haversin(y1 - y0) + cy0 * cy1 * d3_haversin(x1 - x0))), k = 1 / Math.sin(d); var interpolate = d ? function(t) { var B = Math.sin(t *= d) * k, A = Math.sin(d - t) * k, x = A * kx0 + B * kx1, y = A * ky0 + B * ky1, z = A * sy0 + B * sy1; return [ Math.atan2(y, x) * d3_degrees, Math.atan2(z, Math.sqrt(x * x + y * y)) * d3_degrees ]; } : function() { return [ x0 * d3_degrees, y0 * d3_degrees ]; }; interpolate.distance = d; return interpolate; } d3.geo.length = function(object) { d3_geo_lengthSum = 0; d3.geo.stream(object, d3_geo_length); return d3_geo_lengthSum; }; var d3_geo_lengthSum; var d3_geo_length = { sphere: d3_noop, point: d3_noop, lineStart: d3_geo_lengthLineStart, lineEnd: d3_noop, polygonStart: d3_noop, polygonEnd: d3_noop }; function d3_geo_lengthLineStart() { var λ0, sinφ0, cosφ0; d3_geo_length.point = function(λ, φ) { λ0 = λ * d3_radians, sinφ0 = Math.sin(φ *= d3_radians), cosφ0 = Math.cos(φ); d3_geo_length.point = nextPoint; }; d3_geo_length.lineEnd = function() { d3_geo_length.point = d3_geo_length.lineEnd = d3_noop; }; function nextPoint(λ, φ) { var sinφ = Math.sin(φ *= d3_radians), cosφ = Math.cos(φ), t = abs((λ *= d3_radians) - λ0), cosΔλ = Math.cos(t); d3_geo_lengthSum += Math.atan2(Math.sqrt((t = cosφ * Math.sin(t)) * t + (t = cosφ0 * sinφ - sinφ0 * cosφ * cosΔλ) * t), sinφ0 * sinφ + cosφ0 * cosφ * cosΔλ); λ0 = λ, sinφ0 = sinφ, cosφ0 = cosφ; } } function d3_geo_azimuthal(scale, angle) { function azimuthal(λ, φ) { var cosλ = Math.cos(λ), cosφ = Math.cos(φ), k = scale(cosλ * cosφ); return [ k * cosφ * Math.sin(λ), k * Math.sin(φ) ]; } azimuthal.invert = function(x, y) { var Ď = Math.sqrt(x * x + y * y), c = angle(Ď), sinc = Math.sin(c), cosc = Math.cos(c); return [ Math.atan2(x * sinc, Ď * cosc), Math.asin(Ď && y * sinc / Ď) ]; }; return azimuthal; } var d3_geo_azimuthalEqualArea = d3_geo_azimuthal(function(cosλcosφ) { return Math.sqrt(2 / (1 + cosλcosφ)); }, function(Ď) { return 2 * Math.asin(Ď / 2); }); (d3.geo.azimuthalEqualArea = function() { return d3_geo_projection(d3_geo_azimuthalEqualArea); }).raw = d3_geo_azimuthalEqualArea; var d3_geo_azimuthalEquidistant = d3_geo_azimuthal(function(cosλcosφ) { var c = Math.acos(cosλcosφ); return c && c / Math.sin(c); }, d3_identity); (d3.geo.azimuthalEquidistant = function() { return d3_geo_projection(d3_geo_azimuthalEquidistant); }).raw = d3_geo_azimuthalEquidistant; function d3_geo_conicConformal(φ0, φ1) { var cosφ0 = Math.cos(φ0), t = function(φ) { return Math.tan(Ď€ / 4 + φ / 2); }, n = φ0 === φ1 ? Math.sin(φ0) : Math.log(cosφ0 / Math.cos(φ1)) / Math.log(t(φ1) / t(φ0)), F = cosφ0 * Math.pow(t(φ0), n) / n; if (!n) return d3_geo_mercator; function forward(λ, φ) { if (F > 0) { if (φ < -halfĎ€ + ε) φ = -halfĎ€ + ε; } else { if (φ > halfĎ€ - ε) φ = halfĎ€ - ε; } var Ď = F / Math.pow(t(φ), n); return [ Ď * Math.sin(n * λ), F - Ď * Math.cos(n * λ) ]; } forward.invert = function(x, y) { var Ď0_y = F - y, Ď = d3_sgn(n) * Math.sqrt(x * x + Ď0_y * Ď0_y); return [ Math.atan2(x, Ď0_y) / n, 2 * Math.atan(Math.pow(F / Ď, 1 / n)) - halfĎ€ ]; }; return forward; } (d3.geo.conicConformal = function() { return d3_geo_conic(d3_geo_conicConformal); }).raw = d3_geo_conicConformal; function d3_geo_conicEquidistant(φ0, φ1) { var cosφ0 = Math.cos(φ0), n = φ0 === φ1 ? Math.sin(φ0) : (cosφ0 - Math.cos(φ1)) / (φ1 - φ0), G = cosφ0 / n + φ0; if (abs(n) < ε) return d3_geo_equirectangular; function forward(λ, φ) { var Ď = G - φ; return [ Ď * Math.sin(n * λ), G - Ď * Math.cos(n * λ) ]; } forward.invert = function(x, y) { var Ď0_y = G - y; return [ Math.atan2(x, Ď0_y) / n, G - d3_sgn(n) * Math.sqrt(x * x + Ď0_y * Ď0_y) ]; }; return forward; } (d3.geo.conicEquidistant = function() { return d3_geo_conic(d3_geo_conicEquidistant); }).raw = d3_geo_conicEquidistant; var d3_geo_gnomonic = d3_geo_azimuthal(function(cosλcosφ) { return 1 / cosλcosφ; }, Math.atan); (d3.geo.gnomonic = function() { return d3_geo_projection(d3_geo_gnomonic); }).raw = d3_geo_gnomonic; function d3_geo_mercator(λ, φ) { return [ λ, Math.log(Math.tan(Ď€ / 4 + φ / 2)) ]; } d3_geo_mercator.invert = function(x, y) { return [ x, 2 * Math.atan(Math.exp(y)) - halfĎ€ ]; }; function d3_geo_mercatorProjection(project) { var m = d3_geo_projection(project), scale = m.scale, translate = m.translate, clipExtent = m.clipExtent, clipAuto; m.scale = function() { var v = scale.apply(m, arguments); return v === m ? clipAuto ? m.clipExtent(null) : m : v; }; m.translate = function() { var v = translate.apply(m, arguments); return v === m ? clipAuto ? m.clipExtent(null) : m : v; }; m.clipExtent = function(_) { var v = clipExtent.apply(m, arguments); if (v === m) { if (clipAuto = _ == null) { var k = Ď€ * scale(), t = translate(); clipExtent([ [ t[0] - k, t[1] - k ], [ t[0] + k, t[1] + k ] ]); } } else if (clipAuto) { v = null; } return v; }; return m.clipExtent(null); } (d3.geo.mercator = function() { return d3_geo_mercatorProjection(d3_geo_mercator); }).raw = d3_geo_mercator; var d3_geo_orthographic = d3_geo_azimuthal(function() { return 1; }, Math.asin); (d3.geo.orthographic = function() { return d3_geo_projection(d3_geo_orthographic); }).raw = d3_geo_orthographic; var d3_geo_stereographic = d3_geo_azimuthal(function(cosλcosφ) { return 1 / (1 + cosλcosφ); }, function(Ď) { return 2 * Math.atan(Ď); }); (d3.geo.stereographic = function() { return d3_geo_projection(d3_geo_stereographic); }).raw = d3_geo_stereographic; function d3_geo_transverseMercator(λ, φ) { return [ Math.log(Math.tan(Ď€ / 4 + φ / 2)), -λ ]; } d3_geo_transverseMercator.invert = function(x, y) { return [ -y, 2 * Math.atan(Math.exp(x)) - halfĎ€ ]; }; (d3.geo.transverseMercator = function() { var projection = d3_geo_mercatorProjection(d3_geo_transverseMercator), center = projection.center, rotate = projection.rotate; projection.center = function(_) { return _ ? center([ -_[1], _[0] ]) : (_ = center(), [ -_[1], _[0] ]); }; projection.rotate = function(_) { return _ ? rotate([ _[0], _[1], _.length > 2 ? _[2] + 90 : 90 ]) : (_ = rotate(), [ _[0], _[1], _[2] - 90 ]); }; return projection.rotate([ 0, 0 ]); }).raw = d3_geo_transverseMercator; d3.geom = {}; function d3_geom_pointX(d) { return d[0]; } function d3_geom_pointY(d) { return d[1]; } d3.geom.hull = function(vertices) { var x = d3_geom_pointX, y = d3_geom_pointY; if (arguments.length) return hull(vertices); function hull(data) { if (data.length < 3) return []; var fx = d3_functor(x), fy = d3_functor(y), i, n = data.length, points = [], flippedPoints = []; for (i = 0; i < n; i++) { points.push([ +fx.call(this, data[i], i), +fy.call(this, data[i], i), i ]); } points.sort(d3_geom_hullOrder); for (i = 0; i < n; i++) flippedPoints.push([ points[i][0], -points[i][1] ]); var upper = d3_geom_hullUpper(points), lower = d3_geom_hullUpper(flippedPoints); var skipLeft = lower[0] === upper[0], skipRight = lower[lower.length - 1] === upper[upper.length - 1], polygon = []; for (i = upper.length - 1; i >= 0; --i) polygon.push(data[points[upper[i]][2]]); for (i = +skipLeft; i < lower.length - skipRight; ++i) polygon.push(data[points[lower[i]][2]]); return polygon; } hull.x = function(_) { return arguments.length ? (x = _, hull) : x; }; hull.y = function(_) { return arguments.length ? (y = _, hull) : y; }; return hull; }; function d3_geom_hullUpper(points) { var n = points.length, hull = [ 0, 1 ], hs = 2; for (var i = 2; i < n; i++) { while (hs > 1 && d3_cross2d(points[hull[hs - 2]], points[hull[hs - 1]], points[i]) <= 0) --hs; hull[hs++] = i; } return hull.slice(0, hs); } function d3_geom_hullOrder(a, b) { return a[0] - b[0] || a[1] - b[1]; } d3.geom.polygon = function(coordinates) { d3_subclass(coordinates, d3_geom_polygonPrototype); return coordinates; }; var d3_geom_polygonPrototype = d3.geom.polygon.prototype = []; d3_geom_polygonPrototype.area = function() { var i = -1, n = this.length, a, b = this[n - 1], area = 0; while (++i < n) { a = b; b = this[i]; area += a[1] * b[0] - a[0] * b[1]; } return area * .5; }; d3_geom_polygonPrototype.centroid = function(k) { var i = -1, n = this.length, x = 0, y = 0, a, b = this[n - 1], c; if (!arguments.length) k = -1 / (6 * this.area()); while (++i < n) { a = b; b = this[i]; c = a[0] * b[1] - b[0] * a[1]; x += (a[0] + b[0]) * c; y += (a[1] + b[1]) * c; } return [ x * k, y * k ]; }; d3_geom_polygonPrototype.clip = function(subject) { var input, closed = d3_geom_polygonClosed(subject), i = -1, n = this.length - d3_geom_polygonClosed(this), j, m, a = this[n - 1], b, c, d; while (++i < n) { input = subject.slice(); subject.length = 0; b = this[i]; c = input[(m = input.length - closed) - 1]; j = -1; while (++j < m) { d = input[j]; if (d3_geom_polygonInside(d, a, b)) { if (!d3_geom_polygonInside(c, a, b)) { subject.push(d3_geom_polygonIntersect(c, d, a, b)); } subject.push(d); } else if (d3_geom_polygonInside(c, a, b)) { subject.push(d3_geom_polygonIntersect(c, d, a, b)); } c = d; } if (closed) subject.push(subject[0]); a = b; } return subject; }; function d3_geom_polygonInside(p, a, b) { return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0]); } function d3_geom_polygonIntersect(c, d, a, b) { var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3, y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3, ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21); return [ x1 + ua * x21, y1 + ua * y21 ]; } function d3_geom_polygonClosed(coordinates) { var a = coordinates[0], b = coordinates[coordinates.length - 1]; return !(a[0] - b[0] || a[1] - b[1]); } var d3_geom_voronoiEdges, d3_geom_voronoiCells, d3_geom_voronoiBeaches, d3_geom_voronoiBeachPool = [], d3_geom_voronoiFirstCircle, d3_geom_voronoiCircles, d3_geom_voronoiCirclePool = []; function d3_geom_voronoiBeach() { d3_geom_voronoiRedBlackNode(this); this.edge = this.site = this.circle = null; } function d3_geom_voronoiCreateBeach(site) { var beach = d3_geom_voronoiBeachPool.pop() || new d3_geom_voronoiBeach(); beach.site = site; return beach; } function d3_geom_voronoiDetachBeach(beach) { d3_geom_voronoiDetachCircle(beach); d3_geom_voronoiBeaches.remove(beach); d3_geom_voronoiBeachPool.push(beach); d3_geom_voronoiRedBlackNode(beach); } function d3_geom_voronoiRemoveBeach(beach) { var circle = beach.circle, x = circle.x, y = circle.cy, vertex = { x: x, y: y }, previous = beach.P, next = beach.N, disappearing = [ beach ]; d3_geom_voronoiDetachBeach(beach); var lArc = previous; while (lArc.circle && abs(x - lArc.circle.x) < ε && abs(y - lArc.circle.cy) < ε) { previous = lArc.P; disappearing.unshift(lArc); d3_geom_voronoiDetachBeach(lArc); lArc = previous; } disappearing.unshift(lArc); d3_geom_voronoiDetachCircle(lArc); var rArc = next; while (rArc.circle && abs(x - rArc.circle.x) < ε && abs(y - rArc.circle.cy) < ε) { next = rArc.N; disappearing.push(rArc); d3_geom_voronoiDetachBeach(rArc); rArc = next; } disappearing.push(rArc); d3_geom_voronoiDetachCircle(rArc); var nArcs = disappearing.length, iArc; for (iArc = 1; iArc < nArcs; ++iArc) { rArc = disappearing[iArc]; lArc = disappearing[iArc - 1]; d3_geom_voronoiSetEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); } lArc = disappearing[0]; rArc = disappearing[nArcs - 1]; rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, rArc.site, null, vertex); d3_geom_voronoiAttachCircle(lArc); d3_geom_voronoiAttachCircle(rArc); } function d3_geom_voronoiAddBeach(site) { var x = site.x, directrix = site.y, lArc, rArc, dxl, dxr, node = d3_geom_voronoiBeaches._; while (node) { dxl = d3_geom_voronoiLeftBreakPoint(node, directrix) - x; if (dxl > ε) node = node.L; else { dxr = x - d3_geom_voronoiRightBreakPoint(node, directrix); if (dxr > ε) { if (!node.R) { lArc = node; break; } node = node.R; } else { if (dxl > -ε) { lArc = node.P; rArc = node; } else if (dxr > -ε) { lArc = node; rArc = node.N; } else { lArc = rArc = node; } break; } } } var newArc = d3_geom_voronoiCreateBeach(site); d3_geom_voronoiBeaches.insert(lArc, newArc); if (!lArc && !rArc) return; if (lArc === rArc) { d3_geom_voronoiDetachCircle(lArc); rArc = d3_geom_voronoiCreateBeach(lArc.site); d3_geom_voronoiBeaches.insert(newArc, rArc); newArc.edge = rArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); d3_geom_voronoiAttachCircle(lArc); d3_geom_voronoiAttachCircle(rArc); return; } if (!rArc) { newArc.edge = d3_geom_voronoiCreateEdge(lArc.site, newArc.site); return; } d3_geom_voronoiDetachCircle(lArc); d3_geom_voronoiDetachCircle(rArc); var lSite = lArc.site, ax = lSite.x, ay = lSite.y, bx = site.x - ax, by = site.y - ay, rSite = rArc.site, cx = rSite.x - ax, cy = rSite.y - ay, d = 2 * (bx * cy - by * cx), hb = bx * bx + by * by, hc = cx * cx + cy * cy, vertex = { x: (cy * hb - by * hc) / d + ax, y: (bx * hc - cx * hb) / d + ay }; d3_geom_voronoiSetEdgeEnd(rArc.edge, lSite, rSite, vertex); newArc.edge = d3_geom_voronoiCreateEdge(lSite, site, null, vertex); rArc.edge = d3_geom_voronoiCreateEdge(site, rSite, null, vertex); d3_geom_voronoiAttachCircle(lArc); d3_geom_voronoiAttachCircle(rArc); } function d3_geom_voronoiLeftBreakPoint(arc, directrix) { var site = arc.site, rfocx = site.x, rfocy = site.y, pby2 = rfocy - directrix; if (!pby2) return rfocx; var lArc = arc.P; if (!lArc) return -Infinity; site = lArc.site; var lfocx = site.x, lfocy = site.y, plby2 = lfocy - directrix; if (!plby2) return lfocx; var hl = lfocx - rfocx, aby2 = 1 / pby2 - 1 / plby2, b = hl / plby2; if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; return (rfocx + lfocx) / 2; } function d3_geom_voronoiRightBreakPoint(arc, directrix) { var rArc = arc.N; if (rArc) return d3_geom_voronoiLeftBreakPoint(rArc, directrix); var site = arc.site; return site.y === directrix ? site.x : Infinity; } function d3_geom_voronoiCell(site) { this.site = site; this.edges = []; } d3_geom_voronoiCell.prototype.prepare = function() { var halfEdges = this.edges, iHalfEdge = halfEdges.length, edge; while (iHalfEdge--) { edge = halfEdges[iHalfEdge].edge; if (!edge.b || !edge.a) halfEdges.splice(iHalfEdge, 1); } halfEdges.sort(d3_geom_voronoiHalfEdgeOrder); return halfEdges.length; }; function d3_geom_voronoiCloseCells(extent) { var x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], x2, y2, x3, y3, cells = d3_geom_voronoiCells, iCell = cells.length, cell, iHalfEdge, halfEdges, nHalfEdges, start, end; while (iCell--) { cell = cells[iCell]; if (!cell || !cell.prepare()) continue; halfEdges = cell.edges; nHalfEdges = halfEdges.length; iHalfEdge = 0; while (iHalfEdge < nHalfEdges) { end = halfEdges[iHalfEdge].end(), x3 = end.x, y3 = end.y; start = halfEdges[++iHalfEdge % nHalfEdges].start(), x2 = start.x, y2 = start.y; if (abs(x3 - x2) > ε || abs(y3 - y2) > ε) { halfEdges.splice(iHalfEdge, 0, new d3_geom_voronoiHalfEdge(d3_geom_voronoiCreateBorderEdge(cell.site, end, abs(x3 - x0) < ε && y1 - y3 > ε ? { x: x0, y: abs(x2 - x0) < ε ? y2 : y1 } : abs(y3 - y1) < ε && x1 - x3 > ε ? { x: abs(y2 - y1) < ε ? x2 : x1, y: y1 } : abs(x3 - x1) < ε && y3 - y0 > ε ? { x: x1, y: abs(x2 - x1) < ε ? y2 : y0 } : abs(y3 - y0) < ε && x3 - x0 > ε ? { x: abs(y2 - y0) < ε ? x2 : x0, y: y0 } : null), cell.site, null)); ++nHalfEdges; } } } } function d3_geom_voronoiHalfEdgeOrder(a, b) { return b.angle - a.angle; } function d3_geom_voronoiCircle() { d3_geom_voronoiRedBlackNode(this); this.x = this.y = this.arc = this.site = this.cy = null; } function d3_geom_voronoiAttachCircle(arc) { var lArc = arc.P, rArc = arc.N; if (!lArc || !rArc) return; var lSite = lArc.site, cSite = arc.site, rSite = rArc.site; if (lSite === rSite) return; var bx = cSite.x, by = cSite.y, ax = lSite.x - bx, ay = lSite.y - by, cx = rSite.x - bx, cy = rSite.y - by; var d = 2 * (ax * cy - ay * cx); if (d >= -ε2) return; var ha = ax * ax + ay * ay, hc = cx * cx + cy * cy, x = (cy * ha - ay * hc) / d, y = (ax * hc - cx * ha) / d, cy = y + by; var circle = d3_geom_voronoiCirclePool.pop() || new d3_geom_voronoiCircle(); circle.arc = arc; circle.site = cSite; circle.x = x + bx; circle.y = cy + Math.sqrt(x * x + y * y); circle.cy = cy; arc.circle = circle; var before = null, node = d3_geom_voronoiCircles._; while (node) { if (circle.y < node.y || circle.y === node.y && circle.x <= node.x) { if (node.L) node = node.L; else { before = node.P; break; } } else { if (node.R) node = node.R; else { before = node; break; } } } d3_geom_voronoiCircles.insert(before, circle); if (!before) d3_geom_voronoiFirstCircle = circle; } function d3_geom_voronoiDetachCircle(arc) { var circle = arc.circle; if (circle) { if (!circle.P) d3_geom_voronoiFirstCircle = circle.N; d3_geom_voronoiCircles.remove(circle); d3_geom_voronoiCirclePool.push(circle); d3_geom_voronoiRedBlackNode(circle); arc.circle = null; } } function d3_geom_voronoiClipEdges(extent) { var edges = d3_geom_voronoiEdges, clip = d3_geom_clipLine(extent[0][0], extent[0][1], extent[1][0], extent[1][1]), i = edges.length, e; while (i--) { e = edges[i]; if (!d3_geom_voronoiConnectEdge(e, extent) || !clip(e) || abs(e.a.x - e.b.x) < ε && abs(e.a.y - e.b.y) < ε) { e.a = e.b = null; edges.splice(i, 1); } } } function d3_geom_voronoiConnectEdge(edge, extent) { var vb = edge.b; if (vb) return true; var va = edge.a, x0 = extent[0][0], x1 = extent[1][0], y0 = extent[0][1], y1 = extent[1][1], lSite = edge.l, rSite = edge.r, lx = lSite.x, ly = lSite.y, rx = rSite.x, ry = rSite.y, fx = (lx + rx) / 2, fy = (ly + ry) / 2, fm, fb; if (ry === ly) { if (fx < x0 || fx >= x1) return; if (lx > rx) { if (!va) va = { x: fx, y: y0 }; else if (va.y >= y1) return; vb = { x: fx, y: y1 }; } else { if (!va) va = { x: fx, y: y1 }; else if (va.y < y0) return; vb = { x: fx, y: y0 }; } } else { fm = (lx - rx) / (ry - ly); fb = fy - fm * fx; if (fm < -1 || fm > 1) { if (lx > rx) { if (!va) va = { x: (y0 - fb) / fm, y: y0 }; else if (va.y >= y1) return; vb = { x: (y1 - fb) / fm, y: y1 }; } else { if (!va) va = { x: (y1 - fb) / fm, y: y1 }; else if (va.y < y0) return; vb = { x: (y0 - fb) / fm, y: y0 }; } } else { if (ly < ry) { if (!va) va = { x: x0, y: fm * x0 + fb }; else if (va.x >= x1) return; vb = { x: x1, y: fm * x1 + fb }; } else { if (!va) va = { x: x1, y: fm * x1 + fb }; else if (va.x < x0) return; vb = { x: x0, y: fm * x0 + fb }; } } } edge.a = va; edge.b = vb; return true; } function d3_geom_voronoiEdge(lSite, rSite) { this.l = lSite; this.r = rSite; this.a = this.b = null; } function d3_geom_voronoiCreateEdge(lSite, rSite, va, vb) { var edge = new d3_geom_voronoiEdge(lSite, rSite); d3_geom_voronoiEdges.push(edge); if (va) d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, va); if (vb) d3_geom_voronoiSetEdgeEnd(edge, rSite, lSite, vb); d3_geom_voronoiCells[lSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, lSite, rSite)); d3_geom_voronoiCells[rSite.i].edges.push(new d3_geom_voronoiHalfEdge(edge, rSite, lSite)); return edge; } function d3_geom_voronoiCreateBorderEdge(lSite, va, vb) { var edge = new d3_geom_voronoiEdge(lSite, null); edge.a = va; edge.b = vb; d3_geom_voronoiEdges.push(edge); return edge; } function d3_geom_voronoiSetEdgeEnd(edge, lSite, rSite, vertex) { if (!edge.a && !edge.b) { edge.a = vertex; edge.l = lSite; edge.r = rSite; } else if (edge.l === rSite) { edge.b = vertex; } else { edge.a = vertex; } } function d3_geom_voronoiHalfEdge(edge, lSite, rSite) { var va = edge.a, vb = edge.b; this.edge = edge; this.site = lSite; this.angle = rSite ? Math.atan2(rSite.y - lSite.y, rSite.x - lSite.x) : edge.l === lSite ? Math.atan2(vb.x - va.x, va.y - vb.y) : Math.atan2(va.x - vb.x, vb.y - va.y); } d3_geom_voronoiHalfEdge.prototype = { start: function() { return this.edge.l === this.site ? this.edge.a : this.edge.b; }, end: function() { return this.edge.l === this.site ? this.edge.b : this.edge.a; } }; function d3_geom_voronoiRedBlackTree() { this._ = null; } function d3_geom_voronoiRedBlackNode(node) { node.U = node.C = node.L = node.R = node.P = node.N = null; } d3_geom_voronoiRedBlackTree.prototype = { insert: function(after, node) { var parent, grandpa, uncle; if (after) { node.P = after; node.N = after.N; if (after.N) after.N.P = node; after.N = node; if (after.R) { after = after.R; while (after.L) after = after.L; after.L = node; } else { after.R = node; } parent = after; } else if (this._) { after = d3_geom_voronoiRedBlackFirst(this._); node.P = null; node.N = after; after.P = after.L = node; parent = after; } else { node.P = node.N = null; this._ = node; parent = null; } node.L = node.R = null; node.U = parent; node.C = true; after = node; while (parent && parent.C) { grandpa = parent.U; if (parent === grandpa.L) { uncle = grandpa.R; if (uncle && uncle.C) { parent.C = uncle.C = false; grandpa.C = true; after = grandpa; } else { if (after === parent.R) { d3_geom_voronoiRedBlackRotateLeft(this, parent); after = parent; parent = after.U; } parent.C = false; grandpa.C = true; d3_geom_voronoiRedBlackRotateRight(this, grandpa); } } else { uncle = grandpa.L; if (uncle && uncle.C) { parent.C = uncle.C = false; grandpa.C = true; after = grandpa; } else { if (after === parent.L) { d3_geom_voronoiRedBlackRotateRight(this, parent); after = parent; parent = after.U; } parent.C = false; grandpa.C = true; d3_geom_voronoiRedBlackRotateLeft(this, grandpa); } } parent = after.U; } this._.C = false; }, remove: function(node) { if (node.N) node.N.P = node.P; if (node.P) node.P.N = node.N; node.N = node.P = null; var parent = node.U, sibling, left = node.L, right = node.R, next, red; if (!left) next = right; else if (!right) next = left; else next = d3_geom_voronoiRedBlackFirst(right); if (parent) { if (parent.L === node) parent.L = next; else parent.R = next; } else { this._ = next; } if (left && right) { red = next.C; next.C = node.C; next.L = left; left.U = next; if (next !== right) { parent = next.U; next.U = node.U; node = next.R; parent.L = node; next.R = right; right.U = next; } else { next.U = parent; parent = next; node = next.R; } } else { red = node.C; node = next; } if (node) node.U = parent; if (red) return; if (node && node.C) { node.C = false; return; } do { if (node === this._) break; if (node === parent.L) { sibling = parent.R; if (sibling.C) { sibling.C = false; parent.C = true; d3_geom_voronoiRedBlackRotateLeft(this, parent); sibling = parent.R; } if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { if (!sibling.R || !sibling.R.C) { sibling.L.C = false; sibling.C = true; d3_geom_voronoiRedBlackRotateRight(this, sibling); sibling = parent.R; } sibling.C = parent.C; parent.C = sibling.R.C = false; d3_geom_voronoiRedBlackRotateLeft(this, parent); node = this._; break; } } else { sibling = parent.L; if (sibling.C) { sibling.C = false; parent.C = true; d3_geom_voronoiRedBlackRotateRight(this, parent); sibling = parent.L; } if (sibling.L && sibling.L.C || sibling.R && sibling.R.C) { if (!sibling.L || !sibling.L.C) { sibling.R.C = false; sibling.C = true; d3_geom_voronoiRedBlackRotateLeft(this, sibling); sibling = parent.L; } sibling.C = parent.C; parent.C = sibling.L.C = false; d3_geom_voronoiRedBlackRotateRight(this, parent); node = this._; break; } } sibling.C = true; node = parent; parent = parent.U; } while (!node.C); if (node) node.C = false; } }; function d3_geom_voronoiRedBlackRotateLeft(tree, node) { var p = node, q = node.R, parent = p.U; if (parent) { if (parent.L === p) parent.L = q; else parent.R = q; } else { tree._ = q; } q.U = parent; p.U = q; p.R = q.L; if (p.R) p.R.U = p; q.L = p; } function d3_geom_voronoiRedBlackRotateRight(tree, node) { var p = node, q = node.L, parent = p.U; if (parent) { if (parent.L === p) parent.L = q; else parent.R = q; } else { tree._ = q; } q.U = parent; p.U = q; p.L = q.R; if (p.L) p.L.U = p; q.R = p; } function d3_geom_voronoiRedBlackFirst(node) { while (node.L) node = node.L; return node; } function d3_geom_voronoi(sites, bbox) { var site = sites.sort(d3_geom_voronoiVertexOrder).pop(), x0, y0, circle; d3_geom_voronoiEdges = []; d3_geom_voronoiCells = new Array(sites.length); d3_geom_voronoiBeaches = new d3_geom_voronoiRedBlackTree(); d3_geom_voronoiCircles = new d3_geom_voronoiRedBlackTree(); while (true) { circle = d3_geom_voronoiFirstCircle; if (site && (!circle || site.y < circle.y || site.y === circle.y && site.x < circle.x)) { if (site.x !== x0 || site.y !== y0) { d3_geom_voronoiCells[site.i] = new d3_geom_voronoiCell(site); d3_geom_voronoiAddBeach(site); x0 = site.x, y0 = site.y; } site = sites.pop(); } else if (circle) { d3_geom_voronoiRemoveBeach(circle.arc); } else { break; } } if (bbox) d3_geom_voronoiClipEdges(bbox), d3_geom_voronoiCloseCells(bbox); var diagram = { cells: d3_geom_voronoiCells, edges: d3_geom_voronoiEdges }; d3_geom_voronoiBeaches = d3_geom_voronoiCircles = d3_geom_voronoiEdges = d3_geom_voronoiCells = null; return diagram; } function d3_geom_voronoiVertexOrder(a, b) { return b.y - a.y || b.x - a.x; } d3.geom.voronoi = function(points) { var x = d3_geom_pointX, y = d3_geom_pointY, fx = x, fy = y, clipExtent = d3_geom_voronoiClipExtent; if (points) return voronoi(points); function voronoi(data) { var polygons = new Array(data.length), x0 = clipExtent[0][0], y0 = clipExtent[0][1], x1 = clipExtent[1][0], y1 = clipExtent[1][1]; d3_geom_voronoi(sites(data), clipExtent).cells.forEach(function(cell, i) { var edges = cell.edges, site = cell.site, polygon = polygons[i] = edges.length ? edges.map(function(e) { var s = e.start(); return [ s.x, s.y ]; }) : site.x >= x0 && site.x <= x1 && site.y >= y0 && site.y <= y1 ? [ [ x0, y1 ], [ x1, y1 ], [ x1, y0 ], [ x0, y0 ] ] : []; polygon.point = data[i]; }); return polygons; } function sites(data) { return data.map(function(d, i) { return { x: Math.round(fx(d, i) / ε) * ε, y: Math.round(fy(d, i) / ε) * ε, i: i }; }); } voronoi.links = function(data) { return d3_geom_voronoi(sites(data)).edges.filter(function(edge) { return edge.l && edge.r; }).map(function(edge) { return { source: data[edge.l.i], target: data[edge.r.i] }; }); }; voronoi.triangles = function(data) { var triangles = []; d3_geom_voronoi(sites(data)).cells.forEach(function(cell, i) { var site = cell.site, edges = cell.edges.sort(d3_geom_voronoiHalfEdgeOrder), j = -1, m = edges.length, e0, s0, e1 = edges[m - 1].edge, s1 = e1.l === site ? e1.r : e1.l; while (++j < m) { e0 = e1; s0 = s1; e1 = edges[j].edge; s1 = e1.l === site ? e1.r : e1.l; if (i < s0.i && i < s1.i && d3_geom_voronoiTriangleArea(site, s0, s1) < 0) { triangles.push([ data[i], data[s0.i], data[s1.i] ]); } } }); return triangles; }; voronoi.x = function(_) { return arguments.length ? (fx = d3_functor(x = _), voronoi) : x; }; voronoi.y = function(_) { return arguments.length ? (fy = d3_functor(y = _), voronoi) : y; }; voronoi.clipExtent = function(_) { if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent; clipExtent = _ == null ? d3_geom_voronoiClipExtent : _; return voronoi; }; voronoi.size = function(_) { if (!arguments.length) return clipExtent === d3_geom_voronoiClipExtent ? null : clipExtent && clipExtent[1]; return voronoi.clipExtent(_ && [ [ 0, 0 ], _ ]); }; return voronoi; }; var d3_geom_voronoiClipExtent = [ [ -1e6, -1e6 ], [ 1e6, 1e6 ] ]; function d3_geom_voronoiTriangleArea(a, b, c) { return (a.x - c.x) * (b.y - a.y) - (a.x - b.x) * (c.y - a.y); } d3.geom.delaunay = function(vertices) { return d3.geom.voronoi().triangles(vertices); }; d3.geom.quadtree = function(points, x1, y1, x2, y2) { var x = d3_geom_pointX, y = d3_geom_pointY, compat; if (compat = arguments.length) { x = d3_geom_quadtreeCompatX; y = d3_geom_quadtreeCompatY; if (compat === 3) { y2 = y1; x2 = x1; y1 = x1 = 0; } return quadtree(points); } function quadtree(data) { var d, fx = d3_functor(x), fy = d3_functor(y), xs, ys, i, n, x1_, y1_, x2_, y2_; if (x1 != null) { x1_ = x1, y1_ = y1, x2_ = x2, y2_ = y2; } else { x2_ = y2_ = -(x1_ = y1_ = Infinity); xs = [], ys = []; n = data.length; if (compat) for (i = 0; i < n; ++i) { d = data[i]; if (d.x < x1_) x1_ = d.x; if (d.y < y1_) y1_ = d.y; if (d.x > x2_) x2_ = d.x; if (d.y > y2_) y2_ = d.y; xs.push(d.x); ys.push(d.y); } else for (i = 0; i < n; ++i) { var x_ = +fx(d = data[i], i), y_ = +fy(d, i); if (x_ < x1_) x1_ = x_; if (y_ < y1_) y1_ = y_; if (x_ > x2_) x2_ = x_; if (y_ > y2_) y2_ = y_; xs.push(x_); ys.push(y_); } } var dx = x2_ - x1_, dy = y2_ - y1_; if (dx > dy) y2_ = y1_ + dx; else x2_ = x1_ + dy; function insert(n, d, x, y, x1, y1, x2, y2) { if (isNaN(x) || isNaN(y)) return; if (n.leaf) { var nx = n.x, ny = n.y; if (nx != null) { if (abs(nx - x) + abs(ny - y) < .01) { insertChild(n, d, x, y, x1, y1, x2, y2); } else { var nPoint = n.point; n.x = n.y = n.point = null; insertChild(n, nPoint, nx, ny, x1, y1, x2, y2); insertChild(n, d, x, y, x1, y1, x2, y2); } } else { n.x = x, n.y = y, n.point = d; } } else { insertChild(n, d, x, y, x1, y1, x2, y2); } } function insertChild(n, d, x, y, x1, y1, x2, y2) { var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, right = x >= sx, bottom = y >= sy, i = (bottom << 1) + right; n.leaf = false; n = n.nodes[i] || (n.nodes[i] = d3_geom_quadtreeNode()); if (right) x1 = sx; else x2 = sx; if (bottom) y1 = sy; else y2 = sy; insert(n, d, x, y, x1, y1, x2, y2); } var root = d3_geom_quadtreeNode(); root.add = function(d) { insert(root, d, +fx(d, ++i), +fy(d, i), x1_, y1_, x2_, y2_); }; root.visit = function(f) { d3_geom_quadtreeVisit(f, root, x1_, y1_, x2_, y2_); }; i = -1; if (x1 == null) { while (++i < n) { insert(root, data[i], xs[i], ys[i], x1_, y1_, x2_, y2_); } --i; } else data.forEach(root.add); xs = ys = data = d = null; return root; } quadtree.x = function(_) { return arguments.length ? (x = _, quadtree) : x; }; quadtree.y = function(_) { return arguments.length ? (y = _, quadtree) : y; }; quadtree.extent = function(_) { if (!arguments.length) return x1 == null ? null : [ [ x1, y1 ], [ x2, y2 ] ]; if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = +_[0][0], y1 = +_[0][1], x2 = +_[1][0], y2 = +_[1][1]; return quadtree; }; quadtree.size = function(_) { if (!arguments.length) return x1 == null ? null : [ x2 - x1, y2 - y1 ]; if (_ == null) x1 = y1 = x2 = y2 = null; else x1 = y1 = 0, x2 = +_[0], y2 = +_[1]; return quadtree; }; return quadtree; }; function d3_geom_quadtreeCompatX(d) { return d.x; } function d3_geom_quadtreeCompatY(d) { return d.y; } function d3_geom_quadtreeNode() { return { leaf: true, nodes: [], point: null, x: null, y: null }; } function d3_geom_quadtreeVisit(f, node, x1, y1, x2, y2) { if (!f(node, x1, y1, x2, y2)) { var sx = (x1 + x2) * .5, sy = (y1 + y2) * .5, children = node.nodes; if (children[0]) d3_geom_quadtreeVisit(f, children[0], x1, y1, sx, sy); if (children[1]) d3_geom_quadtreeVisit(f, children[1], sx, y1, x2, sy); if (children[2]) d3_geom_quadtreeVisit(f, children[2], x1, sy, sx, y2); if (children[3]) d3_geom_quadtreeVisit(f, children[3], sx, sy, x2, y2); } } d3.interpolateRgb = d3_interpolateRgb; function d3_interpolateRgb(a, b) { a = d3.rgb(a); b = d3.rgb(b); var ar = a.r, ag = a.g, ab = a.b, br = b.r - ar, bg = b.g - ag, bb = b.b - ab; return function(t) { return "#" + d3_rgb_hex(Math.round(ar + br * t)) + d3_rgb_hex(Math.round(ag + bg * t)) + d3_rgb_hex(Math.round(ab + bb * t)); }; } d3.interpolateObject = d3_interpolateObject; function d3_interpolateObject(a, b) { var i = {}, c = {}, k; for (k in a) { if (k in b) { i[k] = d3_interpolate(a[k], b[k]); } else { c[k] = a[k]; } } for (k in b) { if (!(k in a)) { c[k] = b[k]; } } return function(t) { for (k in i) c[k] = i[k](t); return c; }; } d3.interpolateNumber = d3_interpolateNumber; function d3_interpolateNumber(a, b) { b -= a = +a; return function(t) { return a + b * t; }; } d3.interpolateString = d3_interpolateString; function d3_interpolateString(a, b) { var bi = d3_interpolate_numberA.lastIndex = d3_interpolate_numberB.lastIndex = 0, am, bm, bs, i = -1, s = [], q = []; a = a + "", b = b + ""; while ((am = d3_interpolate_numberA.exec(a)) && (bm = d3_interpolate_numberB.exec(b))) { if ((bs = bm.index) > bi) { bs = b.substring(bi, bs); if (s[i]) s[i] += bs; else s[++i] = bs; } if ((am = am[0]) === (bm = bm[0])) { if (s[i]) s[i] += bm; else s[++i] = bm; } else { s[++i] = null; q.push({ i: i, x: d3_interpolateNumber(am, bm) }); } bi = d3_interpolate_numberB.lastIndex; } if (bi < b.length) { bs = b.substring(bi); if (s[i]) s[i] += bs; else s[++i] = bs; } return s.length < 2 ? q[0] ? (b = q[0].x, function(t) { return b(t) + ""; }) : function() { return b; } : (b = q.length, function(t) { for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); return s.join(""); }); } var d3_interpolate_numberA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g, d3_interpolate_numberB = new RegExp(d3_interpolate_numberA.source, "g"); d3.interpolate = d3_interpolate; function d3_interpolate(a, b) { var i = d3.interpolators.length, f; while (--i >= 0 && !(f = d3.interpolators[i](a, b))) ; return f; } d3.interpolators = [ function(a, b) { var t = typeof b; return (t === "string" ? d3_rgb_names.has(b) || /^(#|rgb\(|hsl\()/.test(b) ? d3_interpolateRgb : d3_interpolateString : b instanceof d3_Color ? d3_interpolateRgb : Array.isArray(b) ? d3_interpolateArray : t === "object" && isNaN(b) ? d3_interpolateObject : d3_interpolateNumber)(a, b); } ]; d3.interpolateArray = d3_interpolateArray; function d3_interpolateArray(a, b) { var x = [], c = [], na = a.length, nb = b.length, n0 = Math.min(a.length, b.length), i; for (i = 0; i < n0; ++i) x.push(d3_interpolate(a[i], b[i])); for (;i < na; ++i) c[i] = a[i]; for (;i < nb; ++i) c[i] = b[i]; return function(t) { for (i = 0; i < n0; ++i) c[i] = x[i](t); return c; }; } var d3_ease_default = function() { return d3_identity; }; var d3_ease = d3.map({ linear: d3_ease_default, poly: d3_ease_poly, quad: function() { return d3_ease_quad; }, cubic: function() { return d3_ease_cubic; }, sin: function() { return d3_ease_sin; }, exp: function() { return d3_ease_exp; }, circle: function() { return d3_ease_circle; }, elastic: d3_ease_elastic, back: d3_ease_back, bounce: function() { return d3_ease_bounce; } }); var d3_ease_mode = d3.map({ "in": d3_identity, out: d3_ease_reverse, "in-out": d3_ease_reflect, "out-in": function(f) { return d3_ease_reflect(d3_ease_reverse(f)); } }); d3.ease = function(name) { var i = name.indexOf("-"), t = i >= 0 ? name.substring(0, i) : name, m = i >= 0 ? name.substring(i + 1) : "in"; t = d3_ease.get(t) || d3_ease_default; m = d3_ease_mode.get(m) || d3_identity; return d3_ease_clamp(m(t.apply(null, d3_arraySlice.call(arguments, 1)))); }; function d3_ease_clamp(f) { return function(t) { return t <= 0 ? 0 : t >= 1 ? 1 : f(t); }; } function d3_ease_reverse(f) { return function(t) { return 1 - f(1 - t); }; } function d3_ease_reflect(f) { return function(t) { return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t)); }; } function d3_ease_quad(t) { return t * t; } function d3_ease_cubic(t) { return t * t * t; } function d3_ease_cubicInOut(t) { if (t <= 0) return 0; if (t >= 1) return 1; var t2 = t * t, t3 = t2 * t; return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75); } function d3_ease_poly(e) { return function(t) { return Math.pow(t, e); }; } function d3_ease_sin(t) { return 1 - Math.cos(t * halfĎ€); } function d3_ease_exp(t) { return Math.pow(2, 10 * (t - 1)); } function d3_ease_circle(t) { return 1 - Math.sqrt(1 - t * t); } function d3_ease_elastic(a, p) { var s; if (arguments.length < 2) p = .45; if (arguments.length) s = p / Ď„ * Math.asin(1 / a); else a = 1, s = p / 4; return function(t) { return 1 + a * Math.pow(2, -10 * t) * Math.sin((t - s) * Ď„ / p); }; } function d3_ease_back(s) { if (!s) s = 1.70158; return function(t) { return t * t * ((s + 1) * t - s); }; } function d3_ease_bounce(t) { return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375; } d3.interpolateHcl = d3_interpolateHcl; function d3_interpolateHcl(a, b) { a = d3.hcl(a); b = d3.hcl(b); var ah = a.h, ac = a.c, al = a.l, bh = b.h - ah, bc = b.c - ac, bl = b.l - al; if (isNaN(bc)) bc = 0, ac = isNaN(ac) ? b.c : ac; if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; return function(t) { return d3_hcl_lab(ah + bh * t, ac + bc * t, al + bl * t) + ""; }; } d3.interpolateHsl = d3_interpolateHsl; function d3_interpolateHsl(a, b) { a = d3.hsl(a); b = d3.hsl(b); var ah = a.h, as = a.s, al = a.l, bh = b.h - ah, bs = b.s - as, bl = b.l - al; if (isNaN(bs)) bs = 0, as = isNaN(as) ? b.s : as; if (isNaN(bh)) bh = 0, ah = isNaN(ah) ? b.h : ah; else if (bh > 180) bh -= 360; else if (bh < -180) bh += 360; return function(t) { return d3_hsl_rgb(ah + bh * t, as + bs * t, al + bl * t) + ""; }; } d3.interpolateLab = d3_interpolateLab; function d3_interpolateLab(a, b) { a = d3.lab(a); b = d3.lab(b); var al = a.l, aa = a.a, ab = a.b, bl = b.l - al, ba = b.a - aa, bb = b.b - ab; return function(t) { return d3_lab_rgb(al + bl * t, aa + ba * t, ab + bb * t) + ""; }; } d3.interpolateRound = d3_interpolateRound; function d3_interpolateRound(a, b) { b -= a; return function(t) { return Math.round(a + b * t); }; } d3.transform = function(string) { var g = d3_document.createElementNS(d3.ns.prefix.svg, "g"); return (d3.transform = function(string) { if (string != null) { g.setAttribute("transform", string); var t = g.transform.baseVal.consolidate(); } return new d3_transform(t ? t.matrix : d3_transformIdentity); })(string); }; function d3_transform(m) { var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0; if (r0[0] * r1[1] < r1[0] * r0[1]) { r0[0] *= -1; r0[1] *= -1; kx *= -1; kz *= -1; } this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_degrees; this.translate = [ m.e, m.f ]; this.scale = [ kx, ky ]; this.skew = ky ? Math.atan2(kz, ky) * d3_degrees : 0; } d3_transform.prototype.toString = function() { return "translate(" + this.translate + ")rotate(" + this.rotate + ")skewX(" + this.skew + ")scale(" + this.scale + ")"; }; function d3_transformDot(a, b) { return a[0] * b[0] + a[1] * b[1]; } function d3_transformNormalize(a) { var k = Math.sqrt(d3_transformDot(a, a)); if (k) { a[0] /= k; a[1] /= k; } return k; } function d3_transformCombine(a, b, k) { a[0] += k * b[0]; a[1] += k * b[1]; return a; } var d3_transformIdentity = { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }; d3.interpolateTransform = d3_interpolateTransform; function d3_interpolateTransform(a, b) { var s = [], q = [], n, A = d3.transform(a), B = d3.transform(b), ta = A.translate, tb = B.translate, ra = A.rotate, rb = B.rotate, wa = A.skew, wb = B.skew, ka = A.scale, kb = B.scale; if (ta[0] != tb[0] || ta[1] != tb[1]) { s.push("translate(", null, ",", null, ")"); q.push({ i: 1, x: d3_interpolateNumber(ta[0], tb[0]) }, { i: 3, x: d3_interpolateNumber(ta[1], tb[1]) }); } else if (tb[0] || tb[1]) { s.push("translate(" + tb + ")"); } else { s.push(""); } if (ra != rb) { if (ra - rb > 180) rb += 360; else if (rb - ra > 180) ra += 360; q.push({ i: s.push(s.pop() + "rotate(", null, ")") - 2, x: d3_interpolateNumber(ra, rb) }); } else if (rb) { s.push(s.pop() + "rotate(" + rb + ")"); } if (wa != wb) { q.push({ i: s.push(s.pop() + "skewX(", null, ")") - 2, x: d3_interpolateNumber(wa, wb) }); } else if (wb) { s.push(s.pop() + "skewX(" + wb + ")"); } if (ka[0] != kb[0] || ka[1] != kb[1]) { n = s.push(s.pop() + "scale(", null, ",", null, ")"); q.push({ i: n - 4, x: d3_interpolateNumber(ka[0], kb[0]) }, { i: n - 2, x: d3_interpolateNumber(ka[1], kb[1]) }); } else if (kb[0] != 1 || kb[1] != 1) { s.push(s.pop() + "scale(" + kb + ")"); } n = q.length; return function(t) { var i = -1, o; while (++i < n) s[(o = q[i]).i] = o.x(t); return s.join(""); }; } function d3_uninterpolateNumber(a, b) { b = b - (a = +a) ? 1 / (b - a) : 0; return function(x) { return (x - a) * b; }; } function d3_uninterpolateClamp(a, b) { b = b - (a = +a) ? 1 / (b - a) : 0; return function(x) { return Math.max(0, Math.min(1, (x - a) * b)); }; } d3.layout = {}; d3.layout.bundle = function() { return function(links) { var paths = [], i = -1, n = links.length; while (++i < n) paths.push(d3_layout_bundlePath(links[i])); return paths; }; }; function d3_layout_bundlePath(link) { var start = link.source, end = link.target, lca = d3_layout_bundleLeastCommonAncestor(start, end), points = [ start ]; while (start !== lca) { start = start.parent; points.push(start); } var k = points.length; while (end !== lca) { points.splice(k, 0, end); end = end.parent; } return points; } function d3_layout_bundleAncestors(node) { var ancestors = [], parent = node.parent; while (parent != null) { ancestors.push(node); node = parent; parent = parent.parent; } ancestors.push(node); return ancestors; } function d3_layout_bundleLeastCommonAncestor(a, b) { if (a === b) return a; var aNodes = d3_layout_bundleAncestors(a), bNodes = d3_layout_bundleAncestors(b), aNode = aNodes.pop(), bNode = bNodes.pop(), sharedNode = null; while (aNode === bNode) { sharedNode = aNode; aNode = aNodes.pop(); bNode = bNodes.pop(); } return sharedNode; } d3.layout.chord = function() { var chord = {}, chords, groups, matrix, n, padding = 0, sortGroups, sortSubgroups, sortChords; function relayout() { var subgroups = {}, groupSums = [], groupIndex = d3.range(n), subgroupIndex = [], k, x, x0, i, j; chords = []; groups = []; k = 0, i = -1; while (++i < n) { x = 0, j = -1; while (++j < n) { x += matrix[i][j]; } groupSums.push(x); subgroupIndex.push(d3.range(n)); k += x; } if (sortGroups) { groupIndex.sort(function(a, b) { return sortGroups(groupSums[a], groupSums[b]); }); } if (sortSubgroups) { subgroupIndex.forEach(function(d, i) { d.sort(function(a, b) { return sortSubgroups(matrix[i][a], matrix[i][b]); }); }); } k = (Ď„ - padding * n) / k; x = 0, i = -1; while (++i < n) { x0 = x, j = -1; while (++j < n) { var di = groupIndex[i], dj = subgroupIndex[di][j], v = matrix[di][dj], a0 = x, a1 = x += v * k; subgroups[di + "-" + dj] = { index: di, subindex: dj, startAngle: a0, endAngle: a1, value: v }; } groups[di] = { index: di, startAngle: x0, endAngle: x, value: (x - x0) / k }; x += padding; } i = -1; while (++i < n) { j = i - 1; while (++j < n) { var source = subgroups[i + "-" + j], target = subgroups[j + "-" + i]; if (source.value || target.value) { chords.push(source.value < target.value ? { source: target, target: source } : { source: source, target: target }); } } } if (sortChords) resort(); } function resort() { chords.sort(function(a, b) { return sortChords((a.source.value + a.target.value) / 2, (b.source.value + b.target.value) / 2); }); } chord.matrix = function(x) { if (!arguments.length) return matrix; n = (matrix = x) && matrix.length; chords = groups = null; return chord; }; chord.padding = function(x) { if (!arguments.length) return padding; padding = x; chords = groups = null; return chord; }; chord.sortGroups = function(x) { if (!arguments.length) return sortGroups; sortGroups = x; chords = groups = null; return chord; }; chord.sortSubgroups = function(x) { if (!arguments.length) return sortSubgroups; sortSubgroups = x; chords = null; return chord; }; chord.sortChords = function(x) { if (!arguments.length) return sortChords; sortChords = x; if (chords) resort(); return chord; }; chord.chords = function() { if (!chords) relayout(); return chords; }; chord.groups = function() { if (!groups) relayout(); return groups; }; return chord; }; d3.layout.force = function() { var force = {}, event = d3.dispatch("start", "tick", "end"), size = [ 1, 1 ], drag, alpha, friction = .9, linkDistance = d3_layout_forceLinkDistance, linkStrength = d3_layout_forceLinkStrength, charge = -30, chargeDistance2 = d3_layout_forceChargeDistance2, gravity = .1, theta2 = .64, nodes = [], links = [], distances, strengths, charges; function repulse(node) { return function(quad, x1, _, x2) { if (quad.point !== node) { var dx = quad.cx - node.x, dy = quad.cy - node.y, dw = x2 - x1, dn = dx * dx + dy * dy; if (dw * dw / theta2 < dn) { if (dn < chargeDistance2) { var k = quad.charge / dn; node.px -= dx * k; node.py -= dy * k; } return true; } if (quad.point && dn && dn < chargeDistance2) { var k = quad.pointCharge / dn; node.px -= dx * k; node.py -= dy * k; } } return !quad.charge; }; } force.tick = function() { if ((alpha *= .99) < .005) { event.end({ type: "end", alpha: alpha = 0 }); return true; } var n = nodes.length, m = links.length, q, i, o, s, t, l, k, x, y; for (i = 0; i < m; ++i) { o = links[i]; s = o.source; t = o.target; x = t.x - s.x; y = t.y - s.y; if (l = x * x + y * y) { l = alpha * strengths[i] * ((l = Math.sqrt(l)) - distances[i]) / l; x *= l; y *= l; t.x -= x * (k = s.weight / (t.weight + s.weight)); t.y -= y * k; s.x += x * (k = 1 - k); s.y += y * k; } } if (k = alpha * gravity) { x = size[0] / 2; y = size[1] / 2; i = -1; if (k) while (++i < n) { o = nodes[i]; o.x += (x - o.x) * k; o.y += (y - o.y) * k; } } if (charge) { d3_layout_forceAccumulate(q = d3.geom.quadtree(nodes), alpha, charges); i = -1; while (++i < n) { if (!(o = nodes[i]).fixed) { q.visit(repulse(o)); } } } i = -1; while (++i < n) { o = nodes[i]; if (o.fixed) { o.x = o.px; o.y = o.py; } else { o.x -= (o.px - (o.px = o.x)) * friction; o.y -= (o.py - (o.py = o.y)) * friction; } } event.tick({ type: "tick", alpha: alpha }); }; force.nodes = function(x) { if (!arguments.length) return nodes; nodes = x; return force; }; force.links = function(x) { if (!arguments.length) return links; links = x; return force; }; force.size = function(x) { if (!arguments.length) return size; size = x; return force; }; force.linkDistance = function(x) { if (!arguments.length) return linkDistance; linkDistance = typeof x === "function" ? x : +x; return force; }; force.distance = force.linkDistance; force.linkStrength = function(x) { if (!arguments.length) return linkStrength; linkStrength = typeof x === "function" ? x : +x; return force; }; force.friction = function(x) { if (!arguments.length) return friction; friction = +x; return force; }; force.charge = function(x) { if (!arguments.length) return charge; charge = typeof x === "function" ? x : +x; return force; }; force.chargeDistance = function(x) { if (!arguments.length) return Math.sqrt(chargeDistance2); chargeDistance2 = x * x; return force; }; force.gravity = function(x) { if (!arguments.length) return gravity; gravity = +x; return force; }; force.theta = function(x) { if (!arguments.length) return Math.sqrt(theta2); theta2 = x * x; return force; }; force.alpha = function(x) { if (!arguments.length) return alpha; x = +x; if (alpha) { if (x > 0) alpha = x; else alpha = 0; } else if (x > 0) { event.start({ type: "start", alpha: alpha = x }); d3.timer(force.tick); } return force; }; force.start = function() { var i, n = nodes.length, m = links.length, w = size[0], h = size[1], neighbors, o; for (i = 0; i < n; ++i) { (o = nodes[i]).index = i; o.weight = 0; } for (i = 0; i < m; ++i) { o = links[i]; if (typeof o.source == "number") o.source = nodes[o.source]; if (typeof o.target == "number") o.target = nodes[o.target]; ++o.source.weight; ++o.target.weight; } for (i = 0; i < n; ++i) { o = nodes[i]; if (isNaN(o.x)) o.x = position("x", w); if (isNaN(o.y)) o.y = position("y", h); if (isNaN(o.px)) o.px = o.x; if (isNaN(o.py)) o.py = o.y; } distances = []; if (typeof linkDistance === "function") for (i = 0; i < m; ++i) distances[i] = +linkDistance.call(this, links[i], i); else for (i = 0; i < m; ++i) distances[i] = linkDistance; strengths = []; if (typeof linkStrength === "function") for (i = 0; i < m; ++i) strengths[i] = +linkStrength.call(this, links[i], i); else for (i = 0; i < m; ++i) strengths[i] = linkStrength; charges = []; if (typeof charge === "function") for (i = 0; i < n; ++i) charges[i] = +charge.call(this, nodes[i], i); else for (i = 0; i < n; ++i) charges[i] = charge; function position(dimension, size) { if (!neighbors) { neighbors = new Array(n); for (j = 0; j < n; ++j) { neighbors[j] = []; } for (j = 0; j < m; ++j) { var o = links[j]; neighbors[o.source.index].push(o.target); neighbors[o.target.index].push(o.source); } } var candidates = neighbors[i], j = -1, m = candidates.length, x; while (++j < m) if (!isNaN(x = candidates[j][dimension])) return x; return Math.random() * size; } return force.resume(); }; force.resume = function() { return force.alpha(.1); }; force.stop = function() { return force.alpha(0); }; force.drag = function() { if (!drag) drag = d3.behavior.drag().origin(d3_identity).on("dragstart.force", d3_layout_forceDragstart).on("drag.force", dragmove).on("dragend.force", d3_layout_forceDragend); if (!arguments.length) return drag; this.on("mouseover.force", d3_layout_forceMouseover).on("mouseout.force", d3_layout_forceMouseout).call(drag); }; function dragmove(d) { d.px = d3.event.x, d.py = d3.event.y; force.resume(); } return d3.rebind(force, event, "on"); }; function d3_layout_forceDragstart(d) { d.fixed |= 2; } function d3_layout_forceDragend(d) { d.fixed &= ~6; } function d3_layout_forceMouseover(d) { d.fixed |= 4; d.px = d.x, d.py = d.y; } function d3_layout_forceMouseout(d) { d.fixed &= ~4; } function d3_layout_forceAccumulate(quad, alpha, charges) { var cx = 0, cy = 0; quad.charge = 0; if (!quad.leaf) { var nodes = quad.nodes, n = nodes.length, i = -1, c; while (++i < n) { c = nodes[i]; if (c == null) continue; d3_layout_forceAccumulate(c, alpha, charges); quad.charge += c.charge; cx += c.charge * c.cx; cy += c.charge * c.cy; } } if (quad.point) { if (!quad.leaf) { quad.point.x += Math.random() - .5; quad.point.y += Math.random() - .5; } var k = alpha * charges[quad.point.index]; quad.charge += quad.pointCharge = k; cx += k * quad.point.x; cy += k * quad.point.y; } quad.cx = cx / quad.charge; quad.cy = cy / quad.charge; } var d3_layout_forceLinkDistance = 20, d3_layout_forceLinkStrength = 1, d3_layout_forceChargeDistance2 = Infinity; d3.layout.hierarchy = function() { var sort = d3_layout_hierarchySort, children = d3_layout_hierarchyChildren, value = d3_layout_hierarchyValue; function hierarchy(root) { var stack = [ root ], nodes = [], node; root.depth = 0; while ((node = stack.pop()) != null) { nodes.push(node); if ((childs = children.call(hierarchy, node, node.depth)) && (n = childs.length)) { var n, childs, child; while (--n >= 0) { stack.push(child = childs[n]); child.parent = node; child.depth = node.depth + 1; } if (value) node.value = 0; node.children = childs; } else { if (value) node.value = +value.call(hierarchy, node, node.depth) || 0; delete node.children; } } d3_layout_hierarchyVisitAfter(root, function(node) { var childs, parent; if (sort && (childs = node.children)) childs.sort(sort); if (value && (parent = node.parent)) parent.value += node.value; }); return nodes; } hierarchy.sort = function(x) { if (!arguments.length) return sort; sort = x; return hierarchy; }; hierarchy.children = function(x) { if (!arguments.length) return children; children = x; return hierarchy; }; hierarchy.value = function(x) { if (!arguments.length) return value; value = x; return hierarchy; }; hierarchy.revalue = function(root) { if (value) { d3_layout_hierarchyVisitBefore(root, function(node) { if (node.children) node.value = 0; }); d3_layout_hierarchyVisitAfter(root, function(node) { var parent; if (!node.children) node.value = +value.call(hierarchy, node, node.depth) || 0; if (parent = node.parent) parent.value += node.value; }); } return root; }; return hierarchy; }; function d3_layout_hierarchyRebind(object, hierarchy) { d3.rebind(object, hierarchy, "sort", "children", "value"); object.nodes = object; object.links = d3_layout_hierarchyLinks; return object; } function d3_layout_hierarchyVisitBefore(node, callback) { var nodes = [ node ]; while ((node = nodes.pop()) != null) { callback(node); if ((children = node.children) && (n = children.length)) { var n, children; while (--n >= 0) nodes.push(children[n]); } } } function d3_layout_hierarchyVisitAfter(node, callback) { var nodes = [ node ], nodes2 = []; while ((node = nodes.pop()) != null) { nodes2.push(node); if ((children = node.children) && (n = children.length)) { var i = -1, n, children; while (++i < n) nodes.push(children[i]); } } while ((node = nodes2.pop()) != null) { callback(node); } } function d3_layout_hierarchyChildren(d) { return d.children; } function d3_layout_hierarchyValue(d) { return d.value; } function d3_layout_hierarchySort(a, b) { return b.value - a.value; } function d3_layout_hierarchyLinks(nodes) { return d3.merge(nodes.map(function(parent) { return (parent.children || []).map(function(child) { return { source: parent, target: child }; }); })); } d3.layout.partition = function() { var hierarchy = d3.layout.hierarchy(), size = [ 1, 1 ]; function position(node, x, dx, dy) { var children = node.children; node.x = x; node.y = node.depth * dy; node.dx = dx; node.dy = dy; if (children && (n = children.length)) { var i = -1, n, c, d; dx = node.value ? dx / node.value : 0; while (++i < n) { position(c = children[i], x, d = c.value * dx, dy); x += d; } } } function depth(node) { var children = node.children, d = 0; if (children && (n = children.length)) { var i = -1, n; while (++i < n) d = Math.max(d, depth(children[i])); } return 1 + d; } function partition(d, i) { var nodes = hierarchy.call(this, d, i); position(nodes[0], 0, size[0], size[1] / depth(nodes[0])); return nodes; } partition.size = function(x) { if (!arguments.length) return size; size = x; return partition; }; return d3_layout_hierarchyRebind(partition, hierarchy); }; d3.layout.pie = function() { var value = Number, sort = d3_layout_pieSortByValue, startAngle = 0, endAngle = Ď„; function pie(data) { var values = data.map(function(d, i) { return +value.call(pie, d, i); }); var a = +(typeof startAngle === "function" ? startAngle.apply(this, arguments) : startAngle); var k = ((typeof endAngle === "function" ? endAngle.apply(this, arguments) : endAngle) - a) / d3.sum(values); var index = d3.range(data.length); if (sort != null) index.sort(sort === d3_layout_pieSortByValue ? function(i, j) { return values[j] - values[i]; } : function(i, j) { return sort(data[i], data[j]); }); var arcs = []; index.forEach(function(i) { var d; arcs[i] = { data: data[i], value: d = values[i], startAngle: a, endAngle: a += d * k }; }); return arcs; } pie.value = function(x) { if (!arguments.length) return value; value = x; return pie; }; pie.sort = function(x) { if (!arguments.length) return sort; sort = x; return pie; }; pie.startAngle = function(x) { if (!arguments.length) return startAngle; startAngle = x; return pie; }; pie.endAngle = function(x) { if (!arguments.length) return endAngle; endAngle = x; return pie; }; return pie; }; var d3_layout_pieSortByValue = {}; d3.layout.stack = function() { var values = d3_identity, order = d3_layout_stackOrderDefault, offset = d3_layout_stackOffsetZero, out = d3_layout_stackOut, x = d3_layout_stackX, y = d3_layout_stackY; function stack(data, index) { var series = data.map(function(d, i) { return values.call(stack, d, i); }); var points = series.map(function(d) { return d.map(function(v, i) { return [ x.call(stack, v, i), y.call(stack, v, i) ]; }); }); var orders = order.call(stack, points, index); series = d3.permute(series, orders); points = d3.permute(points, orders); var offsets = offset.call(stack, points, index); var n = series.length, m = series[0].length, i, j, o; for (j = 0; j < m; ++j) { out.call(stack, series[0][j], o = offsets[j], points[0][j][1]); for (i = 1; i < n; ++i) { out.call(stack, series[i][j], o += points[i - 1][j][1], points[i][j][1]); } } return data; } stack.values = function(x) { if (!arguments.length) return values; values = x; return stack; }; stack.order = function(x) { if (!arguments.length) return order; order = typeof x === "function" ? x : d3_layout_stackOrders.get(x) || d3_layout_stackOrderDefault; return stack; }; stack.offset = function(x) { if (!arguments.length) return offset; offset = typeof x === "function" ? x : d3_layout_stackOffsets.get(x) || d3_layout_stackOffsetZero; return stack; }; stack.x = function(z) { if (!arguments.length) return x; x = z; return stack; }; stack.y = function(z) { if (!arguments.length) return y; y = z; return stack; }; stack.out = function(z) { if (!arguments.length) return out; out = z; return stack; }; return stack; }; function d3_layout_stackX(d) { return d.x; } function d3_layout_stackY(d) { return d.y; } function d3_layout_stackOut(d, y0, y) { d.y0 = y0; d.y = y; } var d3_layout_stackOrders = d3.map({ "inside-out": function(data) { var n = data.length, i, j, max = data.map(d3_layout_stackMaxIndex), sums = data.map(d3_layout_stackReduceSum), index = d3.range(n).sort(function(a, b) { return max[a] - max[b]; }), top = 0, bottom = 0, tops = [], bottoms = []; for (i = 0; i < n; ++i) { j = index[i]; if (top < bottom) { top += sums[j]; tops.push(j); } else { bottom += sums[j]; bottoms.push(j); } } return bottoms.reverse().concat(tops); }, reverse: function(data) { return d3.range(data.length).reverse(); }, "default": d3_layout_stackOrderDefault }); var d3_layout_stackOffsets = d3.map({ silhouette: function(data) { var n = data.length, m = data[0].length, sums = [], max = 0, i, j, o, y0 = []; for (j = 0; j < m; ++j) { for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; if (o > max) max = o; sums.push(o); } for (j = 0; j < m; ++j) { y0[j] = (max - sums[j]) / 2; } return y0; }, wiggle: function(data) { var n = data.length, x = data[0], m = x.length, i, j, k, s1, s2, s3, dx, o, o0, y0 = []; y0[0] = o = o0 = 0; for (j = 1; j < m; ++j) { for (i = 0, s1 = 0; i < n; ++i) s1 += data[i][j][1]; for (i = 0, s2 = 0, dx = x[j][0] - x[j - 1][0]; i < n; ++i) { for (k = 0, s3 = (data[i][j][1] - data[i][j - 1][1]) / (2 * dx); k < i; ++k) { s3 += (data[k][j][1] - data[k][j - 1][1]) / dx; } s2 += s3 * data[i][j][1]; } y0[j] = o -= s1 ? s2 / s1 * dx : 0; if (o < o0) o0 = o; } for (j = 0; j < m; ++j) y0[j] -= o0; return y0; }, expand: function(data) { var n = data.length, m = data[0].length, k = 1 / n, i, j, o, y0 = []; for (j = 0; j < m; ++j) { for (i = 0, o = 0; i < n; i++) o += data[i][j][1]; if (o) for (i = 0; i < n; i++) data[i][j][1] /= o; else for (i = 0; i < n; i++) data[i][j][1] = k; } for (j = 0; j < m; ++j) y0[j] = 0; return y0; }, zero: d3_layout_stackOffsetZero }); function d3_layout_stackOrderDefault(data) { return d3.range(data.length); } function d3_layout_stackOffsetZero(data) { var j = -1, m = data[0].length, y0 = []; while (++j < m) y0[j] = 0; return y0; } function d3_layout_stackMaxIndex(array) { var i = 1, j = 0, v = array[0][1], k, n = array.length; for (;i < n; ++i) { if ((k = array[i][1]) > v) { j = i; v = k; } } return j; } function d3_layout_stackReduceSum(d) { return d.reduce(d3_layout_stackSum, 0); } function d3_layout_stackSum(p, d) { return p + d[1]; } d3.layout.histogram = function() { var frequency = true, valuer = Number, ranger = d3_layout_histogramRange, binner = d3_layout_histogramBinSturges; function histogram(data, i) { var bins = [], values = data.map(valuer, this), range = ranger.call(this, values, i), thresholds = binner.call(this, range, values, i), bin, i = -1, n = values.length, m = thresholds.length - 1, k = frequency ? 1 : 1 / n, x; while (++i < m) { bin = bins[i] = []; bin.dx = thresholds[i + 1] - (bin.x = thresholds[i]); bin.y = 0; } if (m > 0) { i = -1; while (++i < n) { x = values[i]; if (x >= range[0] && x <= range[1]) { bin = bins[d3.bisect(thresholds, x, 1, m) - 1]; bin.y += k; bin.push(data[i]); } } } return bins; } histogram.value = function(x) { if (!arguments.length) return valuer; valuer = x; return histogram; }; histogram.range = function(x) { if (!arguments.length) return ranger; ranger = d3_functor(x); return histogram; }; histogram.bins = function(x) { if (!arguments.length) return binner; binner = typeof x === "number" ? function(range) { return d3_layout_histogramBinFixed(range, x); } : d3_functor(x); return histogram; }; histogram.frequency = function(x) { if (!arguments.length) return frequency; frequency = !!x; return histogram; }; return histogram; }; function d3_layout_histogramBinSturges(range, values) { return d3_layout_histogramBinFixed(range, Math.ceil(Math.log(values.length) / Math.LN2 + 1)); } function d3_layout_histogramBinFixed(range, n) { var x = -1, b = +range[0], m = (range[1] - b) / n, f = []; while (++x <= n) f[x] = m * x + b; return f; } function d3_layout_histogramRange(values) { return [ d3.min(values), d3.max(values) ]; } d3.layout.pack = function() { var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort), padding = 0, size = [ 1, 1 ], radius; function pack(d, i) { var nodes = hierarchy.call(this, d, i), root = nodes[0], w = size[0], h = size[1], r = radius == null ? Math.sqrt : typeof radius === "function" ? radius : function() { return radius; }; root.x = root.y = 0; d3_layout_hierarchyVisitAfter(root, function(d) { d.r = +r(d.value); }); d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); if (padding) { var dr = padding * (radius ? 1 : Math.max(2 * root.r / w, 2 * root.r / h)) / 2; d3_layout_hierarchyVisitAfter(root, function(d) { d.r += dr; }); d3_layout_hierarchyVisitAfter(root, d3_layout_packSiblings); d3_layout_hierarchyVisitAfter(root, function(d) { d.r -= dr; }); } d3_layout_packTransform(root, w / 2, h / 2, radius ? 1 : 1 / Math.max(2 * root.r / w, 2 * root.r / h)); return nodes; } pack.size = function(_) { if (!arguments.length) return size; size = _; return pack; }; pack.radius = function(_) { if (!arguments.length) return radius; radius = _ == null || typeof _ === "function" ? _ : +_; return pack; }; pack.padding = function(_) { if (!arguments.length) return padding; padding = +_; return pack; }; return d3_layout_hierarchyRebind(pack, hierarchy); }; function d3_layout_packSort(a, b) { return a.value - b.value; } function d3_layout_packInsert(a, b) { var c = a._pack_next; a._pack_next = b; b._pack_prev = a; b._pack_next = c; c._pack_prev = b; } function d3_layout_packSplice(a, b) { a._pack_next = b; b._pack_prev = a; } function d3_layout_packIntersects(a, b) { var dx = b.x - a.x, dy = b.y - a.y, dr = a.r + b.r; return .999 * dr * dr > dx * dx + dy * dy; } function d3_layout_packSiblings(node) { if (!(nodes = node.children) || !(n = nodes.length)) return; var nodes, xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, a, b, c, i, j, k, n; function bound(node) { xMin = Math.min(node.x - node.r, xMin); xMax = Math.max(node.x + node.r, xMax); yMin = Math.min(node.y - node.r, yMin); yMax = Math.max(node.y + node.r, yMax); } nodes.forEach(d3_layout_packLink); a = nodes[0]; a.x = -a.r; a.y = 0; bound(a); if (n > 1) { b = nodes[1]; b.x = b.r; b.y = 0; bound(b); if (n > 2) { c = nodes[2]; d3_layout_packPlace(a, b, c); bound(c); d3_layout_packInsert(a, c); a._pack_prev = c; d3_layout_packInsert(c, b); b = a._pack_next; for (i = 3; i < n; i++) { d3_layout_packPlace(a, b, c = nodes[i]); var isect = 0, s1 = 1, s2 = 1; for (j = b._pack_next; j !== b; j = j._pack_next, s1++) { if (d3_layout_packIntersects(j, c)) { isect = 1; break; } } if (isect == 1) { for (k = a._pack_prev; k !== j._pack_prev; k = k._pack_prev, s2++) { if (d3_layout_packIntersects(k, c)) { break; } } } if (isect) { if (s1 < s2 || s1 == s2 && b.r < a.r) d3_layout_packSplice(a, b = j); else d3_layout_packSplice(a = k, b); i--; } else { d3_layout_packInsert(a, c); b = c; bound(c); } } } } var cx = (xMin + xMax) / 2, cy = (yMin + yMax) / 2, cr = 0; for (i = 0; i < n; i++) { c = nodes[i]; c.x -= cx; c.y -= cy; cr = Math.max(cr, c.r + Math.sqrt(c.x * c.x + c.y * c.y)); } node.r = cr; nodes.forEach(d3_layout_packUnlink); } function d3_layout_packLink(node) { node._pack_next = node._pack_prev = node; } function d3_layout_packUnlink(node) { delete node._pack_next; delete node._pack_prev; } function d3_layout_packTransform(node, x, y, k) { var children = node.children; node.x = x += k * node.x; node.y = y += k * node.y; node.r *= k; if (children) { var i = -1, n = children.length; while (++i < n) d3_layout_packTransform(children[i], x, y, k); } } function d3_layout_packPlace(a, b, c) { var db = a.r + c.r, dx = b.x - a.x, dy = b.y - a.y; if (db && (dx || dy)) { var da = b.r + c.r, dc = dx * dx + dy * dy; da *= da; db *= db; var x = .5 + (db - da) / (2 * dc), y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); c.x = a.x + x * dx + y * dy; c.y = a.y + x * dy - y * dx; } else { c.x = a.x + db; c.y = a.y; } } d3.layout.tree = function() { var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = null; function tree(d, i) { var nodes = hierarchy.call(this, d, i), root0 = nodes[0], root1 = wrapTree(root0); d3_layout_hierarchyVisitAfter(root1, firstWalk), root1.parent.m = -root1.z; d3_layout_hierarchyVisitBefore(root1, secondWalk); if (nodeSize) d3_layout_hierarchyVisitBefore(root0, sizeNode); else { var left = root0, right = root0, bottom = root0; d3_layout_hierarchyVisitBefore(root0, function(node) { if (node.x < left.x) left = node; if (node.x > right.x) right = node; if (node.depth > bottom.depth) bottom = node; }); var tx = separation(left, right) / 2 - left.x, kx = size[0] / (right.x + separation(right, left) / 2 + tx), ky = size[1] / (bottom.depth || 1); d3_layout_hierarchyVisitBefore(root0, function(node) { node.x = (node.x + tx) * kx; node.y = node.depth * ky; }); } return nodes; } function wrapTree(root0) { var root1 = { A: null, children: [ root0 ] }, queue = [ root1 ], node1; while ((node1 = queue.pop()) != null) { for (var children = node1.children, child, i = 0, n = children.length; i < n; ++i) { queue.push((children[i] = child = { _: children[i], parent: node1, children: (child = children[i].children) && child.slice() || [], A: null, a: null, z: 0, m: 0, c: 0, s: 0, t: null, i: i }).a = child); } } return root1.children[0]; } function firstWalk(v) { var children = v.children, siblings = v.parent.children, w = v.i ? siblings[v.i - 1] : null; if (children.length) { d3_layout_treeShift(v); var midpoint = (children[0].z + children[children.length - 1].z) / 2; if (w) { v.z = w.z + separation(v._, w._); v.m = v.z - midpoint; } else { v.z = midpoint; } } else if (w) { v.z = w.z + separation(v._, w._); } v.parent.A = apportion(v, w, v.parent.A || siblings[0]); } function secondWalk(v) { v._.x = v.z + v.parent.m; v.m += v.parent.m; } function apportion(v, w, ancestor) { if (w) { var vip = v, vop = v, vim = w, vom = vip.parent.children[0], sip = vip.m, sop = vop.m, sim = vim.m, som = vom.m, shift; while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) { vom = d3_layout_treeLeft(vom); vop = d3_layout_treeRight(vop); vop.a = v; shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); if (shift > 0) { d3_layout_treeMove(d3_layout_treeAncestor(vim, v, ancestor), v, shift); sip += shift; sop += shift; } sim += vim.m; sip += vip.m; som += vom.m; sop += vop.m; } if (vim && !d3_layout_treeRight(vop)) { vop.t = vim; vop.m += sim - sop; } if (vip && !d3_layout_treeLeft(vom)) { vom.t = vip; vom.m += sip - som; ancestor = v; } } return ancestor; } function sizeNode(node) { node.x *= size[0]; node.y = node.depth * size[1]; } tree.separation = function(x) { if (!arguments.length) return separation; separation = x; return tree; }; tree.size = function(x) { if (!arguments.length) return nodeSize ? null : size; nodeSize = (size = x) == null ? sizeNode : null; return tree; }; tree.nodeSize = function(x) { if (!arguments.length) return nodeSize ? size : null; nodeSize = (size = x) == null ? null : sizeNode; return tree; }; return d3_layout_hierarchyRebind(tree, hierarchy); }; function d3_layout_treeSeparation(a, b) { return a.parent == b.parent ? 1 : 2; } function d3_layout_treeLeft(v) { var children = v.children; return children.length ? children[0] : v.t; } function d3_layout_treeRight(v) { var children = v.children, n; return (n = children.length) ? children[n - 1] : v.t; } function d3_layout_treeMove(wm, wp, shift) { var change = shift / (wp.i - wm.i); wp.c -= change; wp.s += shift; wm.c += change; wp.z += shift; wp.m += shift; } function d3_layout_treeShift(v) { var shift = 0, change = 0, children = v.children, i = children.length, w; while (--i >= 0) { w = children[i]; w.z += shift; w.m += shift; shift += w.s + (change += w.c); } } function d3_layout_treeAncestor(vim, v, ancestor) { return vim.a.parent === v.parent ? vim.a : ancestor; } d3.layout.cluster = function() { var hierarchy = d3.layout.hierarchy().sort(null).value(null), separation = d3_layout_treeSeparation, size = [ 1, 1 ], nodeSize = false; function cluster(d, i) { var nodes = hierarchy.call(this, d, i), root = nodes[0], previousNode, x = 0; d3_layout_hierarchyVisitAfter(root, function(node) { var children = node.children; if (children && children.length) { node.x = d3_layout_clusterX(children); node.y = d3_layout_clusterY(children); } else { node.x = previousNode ? x += separation(node, previousNode) : 0; node.y = 0; previousNode = node; } }); var left = d3_layout_clusterLeft(root), right = d3_layout_clusterRight(root), x0 = left.x - separation(left, right) / 2, x1 = right.x + separation(right, left) / 2; d3_layout_hierarchyVisitAfter(root, nodeSize ? function(node) { node.x = (node.x - root.x) * size[0]; node.y = (root.y - node.y) * size[1]; } : function(node) { node.x = (node.x - x0) / (x1 - x0) * size[0]; node.y = (1 - (root.y ? node.y / root.y : 1)) * size[1]; }); return nodes; } cluster.separation = function(x) { if (!arguments.length) return separation; separation = x; return cluster; }; cluster.size = function(x) { if (!arguments.length) return nodeSize ? null : size; nodeSize = (size = x) == null; return cluster; }; cluster.nodeSize = function(x) { if (!arguments.length) return nodeSize ? size : null; nodeSize = (size = x) != null; return cluster; }; return d3_layout_hierarchyRebind(cluster, hierarchy); }; function d3_layout_clusterY(children) { return 1 + d3.max(children, function(child) { return child.y; }); } function d3_layout_clusterX(children) { return children.reduce(function(x, child) { return x + child.x; }, 0) / children.length; } function d3_layout_clusterLeft(node) { var children = node.children; return children && children.length ? d3_layout_clusterLeft(children[0]) : node; } function d3_layout_clusterRight(node) { var children = node.children, n; return children && (n = children.length) ? d3_layout_clusterRight(children[n - 1]) : node; } d3.layout.treemap = function() { var hierarchy = d3.layout.hierarchy(), round = Math.round, size = [ 1, 1 ], padding = null, pad = d3_layout_treemapPadNull, sticky = false, stickies, mode = "squarify", ratio = .5 * (1 + Math.sqrt(5)); function scale(children, k) { var i = -1, n = children.length, child, area; while (++i < n) { area = (child = children[i]).value * (k < 0 ? 0 : k); child.area = isNaN(area) || area <= 0 ? 0 : area; } } function squarify(node) { var children = node.children; if (children && children.length) { var rect = pad(node), row = [], remaining = children.slice(), child, best = Infinity, score, u = mode === "slice" ? rect.dx : mode === "dice" ? rect.dy : mode === "slice-dice" ? node.depth & 1 ? rect.dy : rect.dx : Math.min(rect.dx, rect.dy), n; scale(remaining, rect.dx * rect.dy / node.value); row.area = 0; while ((n = remaining.length) > 0) { row.push(child = remaining[n - 1]); row.area += child.area; if (mode !== "squarify" || (score = worst(row, u)) <= best) { remaining.pop(); best = score; } else { row.area -= row.pop().area; position(row, u, rect, false); u = Math.min(rect.dx, rect.dy); row.length = row.area = 0; best = Infinity; } } if (row.length) { position(row, u, rect, true); row.length = row.area = 0; } children.forEach(squarify); } } function stickify(node) { var children = node.children; if (children && children.length) { var rect = pad(node), remaining = children.slice(), child, row = []; scale(remaining, rect.dx * rect.dy / node.value); row.area = 0; while (child = remaining.pop()) { row.push(child); row.area += child.area; if (child.z != null) { position(row, child.z ? rect.dx : rect.dy, rect, !remaining.length); row.length = row.area = 0; } } children.forEach(stickify); } } function worst(row, u) { var s = row.area, r, rmax = 0, rmin = Infinity, i = -1, n = row.length; while (++i < n) { if (!(r = row[i].area)) continue; if (r < rmin) rmin = r; if (r > rmax) rmax = r; } s *= s; u *= u; return s ? Math.max(u * rmax * ratio / s, s / (u * rmin * ratio)) : Infinity; } function position(row, u, rect, flush) { var i = -1, n = row.length, x = rect.x, y = rect.y, v = u ? round(row.area / u) : 0, o; if (u == rect.dx) { if (flush || v > rect.dy) v = rect.dy; while (++i < n) { o = row[i]; o.x = x; o.y = y; o.dy = v; x += o.dx = Math.min(rect.x + rect.dx - x, v ? round(o.area / v) : 0); } o.z = true; o.dx += rect.x + rect.dx - x; rect.y += v; rect.dy -= v; } else { if (flush || v > rect.dx) v = rect.dx; while (++i < n) { o = row[i]; o.x = x; o.y = y; o.dx = v; y += o.dy = Math.min(rect.y + rect.dy - y, v ? round(o.area / v) : 0); } o.z = false; o.dy += rect.y + rect.dy - y; rect.x += v; rect.dx -= v; } } function treemap(d) { var nodes = stickies || hierarchy(d), root = nodes[0]; root.x = 0; root.y = 0; root.dx = size[0]; root.dy = size[1]; if (stickies) hierarchy.revalue(root); scale([ root ], root.dx * root.dy / root.value); (stickies ? stickify : squarify)(root); if (sticky) stickies = nodes; return nodes; } treemap.size = function(x) { if (!arguments.length) return size; size = x; return treemap; }; treemap.padding = function(x) { if (!arguments.length) return padding; function padFunction(node) { var p = x.call(treemap, node, node.depth); return p == null ? d3_layout_treemapPadNull(node) : d3_layout_treemapPad(node, typeof p === "number" ? [ p, p, p, p ] : p); } function padConstant(node) { return d3_layout_treemapPad(node, x); } var type; pad = (padding = x) == null ? d3_layout_treemapPadNull : (type = typeof x) === "function" ? padFunction : type === "number" ? (x = [ x, x, x, x ], padConstant) : padConstant; return treemap; }; treemap.round = function(x) { if (!arguments.length) return round != Number; round = x ? Math.round : Number; return treemap; }; treemap.sticky = function(x) { if (!arguments.length) return sticky; sticky = x; stickies = null; return treemap; }; treemap.ratio = function(x) { if (!arguments.length) return ratio; ratio = x; return treemap; }; treemap.mode = function(x) { if (!arguments.length) return mode; mode = x + ""; return treemap; }; return d3_layout_hierarchyRebind(treemap, hierarchy); }; function d3_layout_treemapPadNull(node) { return { x: node.x, y: node.y, dx: node.dx, dy: node.dy }; } function d3_layout_treemapPad(node, padding) { var x = node.x + padding[3], y = node.y + padding[0], dx = node.dx - padding[1] - padding[3], dy = node.dy - padding[0] - padding[2]; if (dx < 0) { x += dx / 2; dx = 0; } if (dy < 0) { y += dy / 2; dy = 0; } return { x: x, y: y, dx: dx, dy: dy }; } d3.random = { normal: function(µ, Ď) { var n = arguments.length; if (n < 2) Ď = 1; if (n < 1) µ = 0; return function() { var x, y, r; do { x = Math.random() * 2 - 1; y = Math.random() * 2 - 1; r = x * x + y * y; } while (!r || r > 1); return µ + Ď * x * Math.sqrt(-2 * Math.log(r) / r); }; }, logNormal: function() { var random = d3.random.normal.apply(d3, arguments); return function() { return Math.exp(random()); }; }, bates: function(m) { var random = d3.random.irwinHall(m); return function() { return random() / m; }; }, irwinHall: function(m) { return function() { for (var s = 0, j = 0; j < m; j++) s += Math.random(); return s; }; } }; d3.scale = {}; function d3_scaleExtent(domain) { var start = domain[0], stop = domain[domain.length - 1]; return start < stop ? [ start, stop ] : [ stop, start ]; } function d3_scaleRange(scale) { return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range()); } function d3_scale_bilinear(domain, range, uninterpolate, interpolate) { var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]); return function(x) { return i(u(x)); }; } function d3_scale_nice(domain, nice) { var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx; if (x1 < x0) { dx = i0, i0 = i1, i1 = dx; dx = x0, x0 = x1, x1 = dx; } domain[i0] = nice.floor(x0); domain[i1] = nice.ceil(x1); return domain; } function d3_scale_niceStep(step) { return step ? { floor: function(x) { return Math.floor(x / step) * step; }, ceil: function(x) { return Math.ceil(x / step) * step; } } : d3_scale_niceIdentity; } var d3_scale_niceIdentity = { floor: d3_identity, ceil: d3_identity }; function d3_scale_polylinear(domain, range, uninterpolate, interpolate) { var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1; if (domain[k] < domain[0]) { domain = domain.slice().reverse(); range = range.slice().reverse(); } while (++j <= k) { u.push(uninterpolate(domain[j - 1], domain[j])); i.push(interpolate(range[j - 1], range[j])); } return function(x) { var j = d3.bisect(domain, x, 1, k) - 1; return i[j](u[j](x)); }; } d3.scale.linear = function() { return d3_scale_linear([ 0, 1 ], [ 0, 1 ], d3_interpolate, false); }; function d3_scale_linear(domain, range, interpolate, clamp) { var output, input; function rescale() { var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber; output = linear(domain, range, uninterpolate, interpolate); input = linear(range, domain, uninterpolate, d3_interpolate); return scale; } function scale(x) { return output(x); } scale.invert = function(y) { return input(y); }; scale.domain = function(x) { if (!arguments.length) return domain; domain = x.map(Number); return rescale(); }; scale.range = function(x) { if (!arguments.length) return range; range = x; return rescale(); }; scale.rangeRound = function(x) { return scale.range(x).interpolate(d3_interpolateRound); }; scale.clamp = function(x) { if (!arguments.length) return clamp; clamp = x; return rescale(); }; scale.interpolate = function(x) { if (!arguments.length) return interpolate; interpolate = x; return rescale(); }; scale.ticks = function(m) { return d3_scale_linearTicks(domain, m); }; scale.tickFormat = function(m, format) { return d3_scale_linearTickFormat(domain, m, format); }; scale.nice = function(m) { d3_scale_linearNice(domain, m); return rescale(); }; scale.copy = function() { return d3_scale_linear(domain, range, interpolate, clamp); }; return rescale(); } function d3_scale_linearRebind(scale, linear) { return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp"); } function d3_scale_linearNice(domain, m) { return d3_scale_nice(domain, d3_scale_niceStep(d3_scale_linearTickRange(domain, m)[2])); } function d3_scale_linearTickRange(domain, m) { if (m == null) m = 10; var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step; if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2; extent[0] = Math.ceil(extent[0] / step) * step; extent[1] = Math.floor(extent[1] / step) * step + step * .5; extent[2] = step; return extent; } function d3_scale_linearTicks(domain, m) { return d3.range.apply(d3, d3_scale_linearTickRange(domain, m)); } function d3_scale_linearTickFormat(domain, m, format) { var range = d3_scale_linearTickRange(domain, m); if (format) { var match = d3_format_re.exec(format); match.shift(); if (match[8] === "s") { var prefix = d3.formatPrefix(Math.max(abs(range[0]), abs(range[1]))); if (!match[7]) match[7] = "." + d3_scale_linearPrecision(prefix.scale(range[2])); match[8] = "f"; format = d3.format(match.join("")); return function(d) { return format(prefix.scale(d)) + prefix.symbol; }; } if (!match[7]) match[7] = "." + d3_scale_linearFormatPrecision(match[8], range); format = match.join(""); } else { format = ",." + d3_scale_linearPrecision(range[2]) + "f"; } return d3.format(format); } var d3_scale_linearFormatSignificant = { s: 1, g: 1, p: 1, r: 1, e: 1 }; function d3_scale_linearPrecision(value) { return -Math.floor(Math.log(value) / Math.LN10 + .01); } function d3_scale_linearFormatPrecision(type, range) { var p = d3_scale_linearPrecision(range[2]); return type in d3_scale_linearFormatSignificant ? Math.abs(p - d3_scale_linearPrecision(Math.max(abs(range[0]), abs(range[1])))) + +(type !== "e") : p - (type === "%") * 2; } d3.scale.log = function() { return d3_scale_log(d3.scale.linear().domain([ 0, 1 ]), 10, true, [ 1, 10 ]); }; function d3_scale_log(linear, base, positive, domain) { function log(x) { return (positive ? Math.log(x < 0 ? 0 : x) : -Math.log(x > 0 ? 0 : -x)) / Math.log(base); } function pow(x) { return positive ? Math.pow(base, x) : -Math.pow(base, -x); } function scale(x) { return linear(log(x)); } scale.invert = function(x) { return pow(linear.invert(x)); }; scale.domain = function(x) { if (!arguments.length) return domain; positive = x[0] >= 0; linear.domain((domain = x.map(Number)).map(log)); return scale; }; scale.base = function(_) { if (!arguments.length) return base; base = +_; linear.domain(domain.map(log)); return scale; }; scale.nice = function() { var niced = d3_scale_nice(domain.map(log), positive ? Math : d3_scale_logNiceNegative); linear.domain(niced); domain = niced.map(pow); return scale; }; scale.ticks = function() { var extent = d3_scaleExtent(domain), ticks = [], u = extent[0], v = extent[1], i = Math.floor(log(u)), j = Math.ceil(log(v)), n = base % 1 ? 2 : base; if (isFinite(j - i)) { if (positive) { for (;i < j; i++) for (var k = 1; k < n; k++) ticks.push(pow(i) * k); ticks.push(pow(i)); } else { ticks.push(pow(i)); for (;i++ < j; ) for (var k = n - 1; k > 0; k--) ticks.push(pow(i) * k); } for (i = 0; ticks[i] < u; i++) {} for (j = ticks.length; ticks[j - 1] > v; j--) {} ticks = ticks.slice(i, j); } return ticks; }; scale.tickFormat = function(n, format) { if (!arguments.length) return d3_scale_logFormat; if (arguments.length < 2) format = d3_scale_logFormat; else if (typeof format !== "function") format = d3.format(format); var k = Math.max(.1, n / scale.ticks().length), f = positive ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), e; return function(d) { return d / pow(f(log(d) + e)) <= k ? format(d) : ""; }; }; scale.copy = function() { return d3_scale_log(linear.copy(), base, positive, domain); }; return d3_scale_linearRebind(scale, linear); } var d3_scale_logFormat = d3.format(".0e"), d3_scale_logNiceNegative = { floor: function(x) { return -Math.ceil(-x); }, ceil: function(x) { return -Math.floor(-x); } }; d3.scale.pow = function() { return d3_scale_pow(d3.scale.linear(), 1, [ 0, 1 ]); }; function d3_scale_pow(linear, exponent, domain) { var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent); function scale(x) { return linear(powp(x)); } scale.invert = function(x) { return powb(linear.invert(x)); }; scale.domain = function(x) { if (!arguments.length) return domain; linear.domain((domain = x.map(Number)).map(powp)); return scale; }; scale.ticks = function(m) { return d3_scale_linearTicks(domain, m); }; scale.tickFormat = function(m, format) { return d3_scale_linearTickFormat(domain, m, format); }; scale.nice = function(m) { return scale.domain(d3_scale_linearNice(domain, m)); }; scale.exponent = function(x) { if (!arguments.length) return exponent; powp = d3_scale_powPow(exponent = x); powb = d3_scale_powPow(1 / exponent); linear.domain(domain.map(powp)); return scale; }; scale.copy = function() { return d3_scale_pow(linear.copy(), exponent, domain); }; return d3_scale_linearRebind(scale, linear); } function d3_scale_powPow(e) { return function(x) { return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e); }; } d3.scale.sqrt = function() { return d3.scale.pow().exponent(.5); }; d3.scale.ordinal = function() { return d3_scale_ordinal([], { t: "range", a: [ [] ] }); }; function d3_scale_ordinal(domain, ranger) { var index, range, rangeBand; function scale(x) { return range[((index.get(x) || (ranger.t === "range" ? index.set(x, domain.push(x)) : NaN)) - 1) % range.length]; } function steps(start, step) { return d3.range(domain.length).map(function(i) { return start + step * i; }); } scale.domain = function(x) { if (!arguments.length) return domain; domain = []; index = new d3_Map(); var i = -1, n = x.length, xi; while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi)); return scale[ranger.t].apply(scale, ranger.a); }; scale.range = function(x) { if (!arguments.length) return range; range = x; rangeBand = 0; ranger = { t: "range", a: arguments }; return scale; }; scale.rangePoints = function(x, padding) { if (arguments.length < 2) padding = 0; var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding); range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step); rangeBand = 0; ranger = { t: "rangePoints", a: arguments }; return scale; }; scale.rangeBands = function(x, padding, outerPadding) { if (arguments.length < 2) padding = 0; if (arguments.length < 3) outerPadding = padding; var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding); range = steps(start + step * outerPadding, step); if (reverse) range.reverse(); rangeBand = step * (1 - padding); ranger = { t: "rangeBands", a: arguments }; return scale; }; scale.rangeRoundBands = function(x, padding, outerPadding) { if (arguments.length < 2) padding = 0; if (arguments.length < 3) outerPadding = padding; var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step; range = steps(start + Math.round(error / 2), step); if (reverse) range.reverse(); rangeBand = Math.round(step * (1 - padding)); ranger = { t: "rangeRoundBands", a: arguments }; return scale; }; scale.rangeBand = function() { return rangeBand; }; scale.rangeExtent = function() { return d3_scaleExtent(ranger.a[0]); }; scale.copy = function() { return d3_scale_ordinal(domain, ranger); }; return scale.domain(domain); } d3.scale.category10 = function() { return d3.scale.ordinal().range(d3_category10); }; d3.scale.category20 = function() { return d3.scale.ordinal().range(d3_category20); }; d3.scale.category20b = function() { return d3.scale.ordinal().range(d3_category20b); }; d3.scale.category20c = function() { return d3.scale.ordinal().range(d3_category20c); }; var d3_category10 = [ 2062260, 16744206, 2924588, 14034728, 9725885, 9197131, 14907330, 8355711, 12369186, 1556175 ].map(d3_rgbString); var d3_category20 = [ 2062260, 11454440, 16744206, 16759672, 2924588, 10018698, 14034728, 16750742, 9725885, 12955861, 9197131, 12885140, 14907330, 16234194, 8355711, 13092807, 12369186, 14408589, 1556175, 10410725 ].map(d3_rgbString); var d3_category20b = [ 3750777, 5395619, 7040719, 10264286, 6519097, 9216594, 11915115, 13556636, 9202993, 12426809, 15186514, 15190932, 8666169, 11356490, 14049643, 15177372, 8077683, 10834324, 13528509, 14589654 ].map(d3_rgbString); var d3_category20c = [ 3244733, 7057110, 10406625, 13032431, 15095053, 16616764, 16625259, 16634018, 3253076, 7652470, 10607003, 13101504, 7695281, 10394312, 12369372, 14342891, 6513507, 9868950, 12434877, 14277081 ].map(d3_rgbString); d3.scale.quantile = function() { return d3_scale_quantile([], []); }; function d3_scale_quantile(domain, range) { var thresholds; function rescale() { var k = 0, q = range.length; thresholds = []; while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q); return scale; } function scale(x) { if (!isNaN(x = +x)) return range[d3.bisect(thresholds, x)]; } scale.domain = function(x) { if (!arguments.length) return domain; domain = x.filter(d3_number).sort(d3_ascending); return rescale(); }; scale.range = function(x) { if (!arguments.length) return range; range = x; return rescale(); }; scale.quantiles = function() { return thresholds; }; scale.invertExtent = function(y) { y = range.indexOf(y); return y < 0 ? [ NaN, NaN ] : [ y > 0 ? thresholds[y - 1] : domain[0], y < thresholds.length ? thresholds[y] : domain[domain.length - 1] ]; }; scale.copy = function() { return d3_scale_quantile(domain, range); }; return rescale(); } d3.scale.quantize = function() { return d3_scale_quantize(0, 1, [ 0, 1 ]); }; function d3_scale_quantize(x0, x1, range) { var kx, i; function scale(x) { return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))]; } function rescale() { kx = range.length / (x1 - x0); i = range.length - 1; return scale; } scale.domain = function(x) { if (!arguments.length) return [ x0, x1 ]; x0 = +x[0]; x1 = +x[x.length - 1]; return rescale(); }; scale.range = function(x) { if (!arguments.length) return range; range = x; return rescale(); }; scale.invertExtent = function(y) { y = range.indexOf(y); y = y < 0 ? NaN : y / kx + x0; return [ y, y + 1 / kx ]; }; scale.copy = function() { return d3_scale_quantize(x0, x1, range); }; return rescale(); } d3.scale.threshold = function() { return d3_scale_threshold([ .5 ], [ 0, 1 ]); }; function d3_scale_threshold(domain, range) { function scale(x) { if (x <= x) return range[d3.bisect(domain, x)]; } scale.domain = function(_) { if (!arguments.length) return domain; domain = _; return scale; }; scale.range = function(_) { if (!arguments.length) return range; range = _; return scale; }; scale.invertExtent = function(y) { y = range.indexOf(y); return [ domain[y - 1], domain[y] ]; }; scale.copy = function() { return d3_scale_threshold(domain, range); }; return scale; } d3.scale.identity = function() { return d3_scale_identity([ 0, 1 ]); }; function d3_scale_identity(domain) { function identity(x) { return +x; } identity.invert = identity; identity.domain = identity.range = function(x) { if (!arguments.length) return domain; domain = x.map(identity); return identity; }; identity.ticks = function(m) { return d3_scale_linearTicks(domain, m); }; identity.tickFormat = function(m, format) { return d3_scale_linearTickFormat(domain, m, format); }; identity.copy = function() { return d3_scale_identity(domain); }; return identity; } d3.svg = {}; d3.svg.arc = function() { var innerRadius = d3_svg_arcInnerRadius, outerRadius = d3_svg_arcOuterRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; function arc() { var r0 = innerRadius.apply(this, arguments), r1 = outerRadius.apply(this, arguments), a0 = startAngle.apply(this, arguments) + d3_svg_arcOffset, a1 = endAngle.apply(this, arguments) + d3_svg_arcOffset, da = (a1 < a0 && (da = a0, a0 = a1, a1 = da), a1 - a0), df = da < Ď€ ? "0" : "1", c0 = Math.cos(a0), s0 = Math.sin(a0), c1 = Math.cos(a1), s1 = Math.sin(a1); return da >= d3_svg_arcMax ? r0 ? "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "M0," + r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + -r0 + "A" + r0 + "," + r0 + " 0 1,0 0," + r0 + "Z" : "M0," + r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + -r1 + "A" + r1 + "," + r1 + " 0 1,1 0," + r1 + "Z" : r0 ? "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L" + r0 * c1 + "," + r0 * s1 + "A" + r0 + "," + r0 + " 0 " + df + ",0 " + r0 * c0 + "," + r0 * s0 + "Z" : "M" + r1 * c0 + "," + r1 * s0 + "A" + r1 + "," + r1 + " 0 " + df + ",1 " + r1 * c1 + "," + r1 * s1 + "L0,0" + "Z"; } arc.innerRadius = function(v) { if (!arguments.length) return innerRadius; innerRadius = d3_functor(v); return arc; }; arc.outerRadius = function(v) { if (!arguments.length) return outerRadius; outerRadius = d3_functor(v); return arc; }; arc.startAngle = function(v) { if (!arguments.length) return startAngle; startAngle = d3_functor(v); return arc; }; arc.endAngle = function(v) { if (!arguments.length) return endAngle; endAngle = d3_functor(v); return arc; }; arc.centroid = function() { var r = (innerRadius.apply(this, arguments) + outerRadius.apply(this, arguments)) / 2, a = (startAngle.apply(this, arguments) + endAngle.apply(this, arguments)) / 2 + d3_svg_arcOffset; return [ Math.cos(a) * r, Math.sin(a) * r ]; }; return arc; }; var d3_svg_arcOffset = -halfĎ€, d3_svg_arcMax = Ď„ - ε; function d3_svg_arcInnerRadius(d) { return d.innerRadius; } function d3_svg_arcOuterRadius(d) { return d.outerRadius; } function d3_svg_arcStartAngle(d) { return d.startAngle; } function d3_svg_arcEndAngle(d) { return d.endAngle; } function d3_svg_line(projection) { var x = d3_geom_pointX, y = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7; function line(data) { var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y); function segment() { segments.push("M", interpolate(projection(points), tension)); } while (++i < n) { if (defined.call(this, d = data[i], i)) { points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]); } else if (points.length) { segment(); points = []; } } if (points.length) segment(); return segments.length ? segments.join("") : null; } line.x = function(_) { if (!arguments.length) return x; x = _; return line; }; line.y = function(_) { if (!arguments.length) return y; y = _; return line; }; line.defined = function(_) { if (!arguments.length) return defined; defined = _; return line; }; line.interpolate = function(_) { if (!arguments.length) return interpolateKey; if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; return line; }; line.tension = function(_) { if (!arguments.length) return tension; tension = _; return line; }; return line; } d3.svg.line = function() { return d3_svg_line(d3_identity); }; var d3_svg_lineInterpolators = d3.map({ linear: d3_svg_lineLinear, "linear-closed": d3_svg_lineLinearClosed, step: d3_svg_lineStep, "step-before": d3_svg_lineStepBefore, "step-after": d3_svg_lineStepAfter, basis: d3_svg_lineBasis, "basis-open": d3_svg_lineBasisOpen, "basis-closed": d3_svg_lineBasisClosed, bundle: d3_svg_lineBundle, cardinal: d3_svg_lineCardinal, "cardinal-open": d3_svg_lineCardinalOpen, "cardinal-closed": d3_svg_lineCardinalClosed, monotone: d3_svg_lineMonotone }); d3_svg_lineInterpolators.forEach(function(key, value) { value.key = key; value.closed = /-closed$/.test(key); }); function d3_svg_lineLinear(points) { return points.join("L"); } function d3_svg_lineLinearClosed(points) { return d3_svg_lineLinear(points) + "Z"; } function d3_svg_lineStep(points) { var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; while (++i < n) path.push("H", (p[0] + (p = points[i])[0]) / 2, "V", p[1]); if (n > 1) path.push("H", p[0]); return path.join(""); } function d3_svg_lineStepBefore(points) { var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]); return path.join(""); } function d3_svg_lineStepAfter(points) { var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ]; while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]); return path.join(""); } function d3_svg_lineCardinalOpen(points, tension) { return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension)); } function d3_svg_lineCardinalClosed(points, tension) { return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension)); } function d3_svg_lineCardinal(points, tension) { return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension)); } function d3_svg_lineHermite(points, tangents) { if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) { return d3_svg_lineLinear(points); } var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1; if (quad) { path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1]; p0 = points[1]; pi = 2; } if (tangents.length > 1) { t = tangents[1]; p = points[pi]; pi++; path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; for (var i = 2; i < tangents.length; i++, pi++) { p = points[pi]; t = tangents[i]; path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1]; } } if (quad) { var lp = points[pi]; path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1]; } return path; } function d3_svg_lineCardinalTangents(points, tension) { var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length; while (++i < n) { p0 = p1; p1 = p2; p2 = points[i]; tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]); } return tangents; } function d3_svg_lineBasis(points) { if (points.length < 3) return d3_svg_lineLinear(points); var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0, "L", d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; points.push(points[n - 1]); while (++i <= n) { pi = points[i]; px.shift(); px.push(pi[0]); py.shift(); py.push(pi[1]); d3_svg_lineBasisBezier(path, px, py); } points.pop(); path.push("L", pi); return path.join(""); } function d3_svg_lineBasisOpen(points) { if (points.length < 4) return d3_svg_lineLinear(points); var path = [], i = -1, n = points.length, pi, px = [ 0 ], py = [ 0 ]; while (++i < 3) { pi = points[i]; px.push(pi[0]); py.push(pi[1]); } path.push(d3_svg_lineDot4(d3_svg_lineBasisBezier3, px) + "," + d3_svg_lineDot4(d3_svg_lineBasisBezier3, py)); --i; while (++i < n) { pi = points[i]; px.shift(); px.push(pi[0]); py.shift(); py.push(pi[1]); d3_svg_lineBasisBezier(path, px, py); } return path.join(""); } function d3_svg_lineBasisClosed(points) { var path, i = -1, n = points.length, m = n + 4, pi, px = [], py = []; while (++i < 4) { pi = points[i % n]; px.push(pi[0]); py.push(pi[1]); } path = [ d3_svg_lineDot4(d3_svg_lineBasisBezier3, px), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, py) ]; --i; while (++i < m) { pi = points[i % n]; px.shift(); px.push(pi[0]); py.shift(); py.push(pi[1]); d3_svg_lineBasisBezier(path, px, py); } return path.join(""); } function d3_svg_lineBundle(points, tension) { var n = points.length - 1; if (n) { var x0 = points[0][0], y0 = points[0][1], dx = points[n][0] - x0, dy = points[n][1] - y0, i = -1, p, t; while (++i <= n) { p = points[i]; t = i / n; p[0] = tension * p[0] + (1 - tension) * (x0 + t * dx); p[1] = tension * p[1] + (1 - tension) * (y0 + t * dy); } } return d3_svg_lineBasis(points); } function d3_svg_lineDot4(a, b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; } var d3_svg_lineBasisBezier1 = [ 0, 2 / 3, 1 / 3, 0 ], d3_svg_lineBasisBezier2 = [ 0, 1 / 3, 2 / 3, 0 ], d3_svg_lineBasisBezier3 = [ 0, 1 / 6, 2 / 3, 1 / 6 ]; function d3_svg_lineBasisBezier(path, x, y) { path.push("C", d3_svg_lineDot4(d3_svg_lineBasisBezier1, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier1, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier2, y), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, x), ",", d3_svg_lineDot4(d3_svg_lineBasisBezier3, y)); } function d3_svg_lineSlope(p0, p1) { return (p1[1] - p0[1]) / (p1[0] - p0[0]); } function d3_svg_lineFiniteDifferences(points) { var i = 0, j = points.length - 1, m = [], p0 = points[0], p1 = points[1], d = m[0] = d3_svg_lineSlope(p0, p1); while (++i < j) { m[i] = (d + (d = d3_svg_lineSlope(p0 = p1, p1 = points[i + 1]))) / 2; } m[i] = d; return m; } function d3_svg_lineMonotoneTangents(points) { var tangents = [], d, a, b, s, m = d3_svg_lineFiniteDifferences(points), i = -1, j = points.length - 1; while (++i < j) { d = d3_svg_lineSlope(points[i], points[i + 1]); if (abs(d) < ε) { m[i] = m[i + 1] = 0; } else { a = m[i] / d; b = m[i + 1] / d; s = a * a + b * b; if (s > 9) { s = d * 3 / Math.sqrt(s); m[i] = s * a; m[i + 1] = s * b; } } } i = -1; while (++i <= j) { s = (points[Math.min(j, i + 1)][0] - points[Math.max(0, i - 1)][0]) / (6 * (1 + m[i] * m[i])); tangents.push([ s || 0, m[i] * s || 0 ]); } return tangents; } function d3_svg_lineMonotone(points) { return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineMonotoneTangents(points)); } d3.svg.line.radial = function() { var line = d3_svg_line(d3_svg_lineRadial); line.radius = line.x, delete line.x; line.angle = line.y, delete line.y; return line; }; function d3_svg_lineRadial(points) { var point, i = -1, n = points.length, r, a; while (++i < n) { point = points[i]; r = point[0]; a = point[1] + d3_svg_arcOffset; point[0] = r * Math.cos(a); point[1] = r * Math.sin(a); } return points; } function d3_svg_area(projection) { var x0 = d3_geom_pointX, x1 = d3_geom_pointX, y0 = 0, y1 = d3_geom_pointY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, interpolateReverse = interpolate, L = "L", tension = .7; function area(data) { var segments = [], points0 = [], points1 = [], i = -1, n = data.length, d, fx0 = d3_functor(x0), fy0 = d3_functor(y0), fx1 = x0 === x1 ? function() { return x; } : d3_functor(x1), fy1 = y0 === y1 ? function() { return y; } : d3_functor(y1), x, y; function segment() { segments.push("M", interpolate(projection(points1), tension), L, interpolateReverse(projection(points0.reverse()), tension), "Z"); } while (++i < n) { if (defined.call(this, d = data[i], i)) { points0.push([ x = +fx0.call(this, d, i), y = +fy0.call(this, d, i) ]); points1.push([ +fx1.call(this, d, i), +fy1.call(this, d, i) ]); } else if (points0.length) { segment(); points0 = []; points1 = []; } } if (points0.length) segment(); return segments.length ? segments.join("") : null; } area.x = function(_) { if (!arguments.length) return x1; x0 = x1 = _; return area; }; area.x0 = function(_) { if (!arguments.length) return x0; x0 = _; return area; }; area.x1 = function(_) { if (!arguments.length) return x1; x1 = _; return area; }; area.y = function(_) { if (!arguments.length) return y1; y0 = y1 = _; return area; }; area.y0 = function(_) { if (!arguments.length) return y0; y0 = _; return area; }; area.y1 = function(_) { if (!arguments.length) return y1; y1 = _; return area; }; area.defined = function(_) { if (!arguments.length) return defined; defined = _; return area; }; area.interpolate = function(_) { if (!arguments.length) return interpolateKey; if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key; interpolateReverse = interpolate.reverse || interpolate; L = interpolate.closed ? "M" : "L"; return area; }; area.tension = function(_) { if (!arguments.length) return tension; tension = _; return area; }; return area; } d3_svg_lineStepBefore.reverse = d3_svg_lineStepAfter; d3_svg_lineStepAfter.reverse = d3_svg_lineStepBefore; d3.svg.area = function() { return d3_svg_area(d3_identity); }; d3.svg.area.radial = function() { var area = d3_svg_area(d3_svg_lineRadial); area.radius = area.x, delete area.x; area.innerRadius = area.x0, delete area.x0; area.outerRadius = area.x1, delete area.x1; area.angle = area.y, delete area.y; area.startAngle = area.y0, delete area.y0; area.endAngle = area.y1, delete area.y1; return area; }; d3.svg.chord = function() { var source = d3_source, target = d3_target, radius = d3_svg_chordRadius, startAngle = d3_svg_arcStartAngle, endAngle = d3_svg_arcEndAngle; function chord(d, i) { var s = subgroup(this, source, d, i), t = subgroup(this, target, d, i); return "M" + s.p0 + arc(s.r, s.p1, s.a1 - s.a0) + (equals(s, t) ? curve(s.r, s.p1, s.r, s.p0) : curve(s.r, s.p1, t.r, t.p0) + arc(t.r, t.p1, t.a1 - t.a0) + curve(t.r, t.p1, s.r, s.p0)) + "Z"; } function subgroup(self, f, d, i) { var subgroup = f.call(self, d, i), r = radius.call(self, subgroup, i), a0 = startAngle.call(self, subgroup, i) + d3_svg_arcOffset, a1 = endAngle.call(self, subgroup, i) + d3_svg_arcOffset; return { r: r, a0: a0, a1: a1, p0: [ r * Math.cos(a0), r * Math.sin(a0) ], p1: [ r * Math.cos(a1), r * Math.sin(a1) ] }; } function equals(a, b) { return a.a0 == b.a0 && a.a1 == b.a1; } function arc(r, p, a) { return "A" + r + "," + r + " 0 " + +(a > Ď€) + ",1 " + p; } function curve(r0, p0, r1, p1) { return "Q 0,0 " + p1; } chord.radius = function(v) { if (!arguments.length) return radius; radius = d3_functor(v); return chord; }; chord.source = function(v) { if (!arguments.length) return source; source = d3_functor(v); return chord; }; chord.target = function(v) { if (!arguments.length) return target; target = d3_functor(v); return chord; }; chord.startAngle = function(v) { if (!arguments.length) return startAngle; startAngle = d3_functor(v); return chord; }; chord.endAngle = function(v) { if (!arguments.length) return endAngle; endAngle = d3_functor(v); return chord; }; return chord; }; function d3_svg_chordRadius(d) { return d.radius; } d3.svg.diagonal = function() { var source = d3_source, target = d3_target, projection = d3_svg_diagonalProjection; function diagonal(d, i) { var p0 = source.call(this, d, i), p3 = target.call(this, d, i), m = (p0.y + p3.y) / 2, p = [ p0, { x: p0.x, y: m }, { x: p3.x, y: m }, p3 ]; p = p.map(projection); return "M" + p[0] + "C" + p[1] + " " + p[2] + " " + p[3]; } diagonal.source = function(x) { if (!arguments.length) return source; source = d3_functor(x); return diagonal; }; diagonal.target = function(x) { if (!arguments.length) return target; target = d3_functor(x); return diagonal; }; diagonal.projection = function(x) { if (!arguments.length) return projection; projection = x; return diagonal; }; return diagonal; }; function d3_svg_diagonalProjection(d) { return [ d.x, d.y ]; } d3.svg.diagonal.radial = function() { var diagonal = d3.svg.diagonal(), projection = d3_svg_diagonalProjection, projection_ = diagonal.projection; diagonal.projection = function(x) { return arguments.length ? projection_(d3_svg_diagonalRadialProjection(projection = x)) : projection; }; return diagonal; }; function d3_svg_diagonalRadialProjection(projection) { return function() { var d = projection.apply(this, arguments), r = d[0], a = d[1] + d3_svg_arcOffset; return [ r * Math.cos(a), r * Math.sin(a) ]; }; } d3.svg.symbol = function() { var type = d3_svg_symbolType, size = d3_svg_symbolSize; function symbol(d, i) { return (d3_svg_symbols.get(type.call(this, d, i)) || d3_svg_symbolCircle)(size.call(this, d, i)); } symbol.type = function(x) { if (!arguments.length) return type; type = d3_functor(x); return symbol; }; symbol.size = function(x) { if (!arguments.length) return size; size = d3_functor(x); return symbol; }; return symbol; }; function d3_svg_symbolSize() { return 64; } function d3_svg_symbolType() { return "circle"; } function d3_svg_symbolCircle(size) { var r = Math.sqrt(size / Ď€); return "M0," + r + "A" + r + "," + r + " 0 1,1 0," + -r + "A" + r + "," + r + " 0 1,1 0," + r + "Z"; } var d3_svg_symbols = d3.map({ circle: d3_svg_symbolCircle, cross: function(size) { var r = Math.sqrt(size / 5) / 2; return "M" + -3 * r + "," + -r + "H" + -r + "V" + -3 * r + "H" + r + "V" + -r + "H" + 3 * r + "V" + r + "H" + r + "V" + 3 * r + "H" + -r + "V" + r + "H" + -3 * r + "Z"; }, diamond: function(size) { var ry = Math.sqrt(size / (2 * d3_svg_symbolTan30)), rx = ry * d3_svg_symbolTan30; return "M0," + -ry + "L" + rx + ",0" + " 0," + ry + " " + -rx + ",0" + "Z"; }, square: function(size) { var r = Math.sqrt(size) / 2; return "M" + -r + "," + -r + "L" + r + "," + -r + " " + r + "," + r + " " + -r + "," + r + "Z"; }, "triangle-down": function(size) { var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; return "M0," + ry + "L" + rx + "," + -ry + " " + -rx + "," + -ry + "Z"; }, "triangle-up": function(size) { var rx = Math.sqrt(size / d3_svg_symbolSqrt3), ry = rx * d3_svg_symbolSqrt3 / 2; return "M0," + -ry + "L" + rx + "," + ry + " " + -rx + "," + ry + "Z"; } }); d3.svg.symbolTypes = d3_svg_symbols.keys(); var d3_svg_symbolSqrt3 = Math.sqrt(3), d3_svg_symbolTan30 = Math.tan(30 * d3_radians); function d3_transition(groups, id) { d3_subclass(groups, d3_transitionPrototype); groups.id = id; return groups; } var d3_transitionPrototype = [], d3_transitionId = 0, d3_transitionInheritId, d3_transitionInherit; d3_transitionPrototype.call = d3_selectionPrototype.call; d3_transitionPrototype.empty = d3_selectionPrototype.empty; d3_transitionPrototype.node = d3_selectionPrototype.node; d3_transitionPrototype.size = d3_selectionPrototype.size; d3.transition = function(selection) { return arguments.length ? d3_transitionInheritId ? selection.transition() : selection : d3_selectionRoot.transition(); }; d3.transition.prototype = d3_transitionPrototype; d3_transitionPrototype.select = function(selector) { var id = this.id, subgroups = [], subgroup, subnode, node; selector = d3_selection_selector(selector); for (var j = -1, m = this.length; ++j < m; ) { subgroups.push(subgroup = []); for (var group = this[j], i = -1, n = group.length; ++i < n; ) { if ((node = group[i]) && (subnode = selector.call(node, node.__data__, i, j))) { if ("__data__" in node) subnode.__data__ = node.__data__; d3_transitionNode(subnode, i, id, node.__transition__[id]); subgroup.push(subnode); } else { subgroup.push(null); } } } return d3_transition(subgroups, id); }; d3_transitionPrototype.selectAll = function(selector) { var id = this.id, subgroups = [], subgroup, subnodes, node, subnode, transition; selector = d3_selection_selectorAll(selector); for (var j = -1, m = this.length; ++j < m; ) { for (var group = this[j], i = -1, n = group.length; ++i < n; ) { if (node = group[i]) { transition = node.__transition__[id]; subnodes = selector.call(node, node.__data__, i, j); subgroups.push(subgroup = []); for (var k = -1, o = subnodes.length; ++k < o; ) { if (subnode = subnodes[k]) d3_transitionNode(subnode, k, id, transition); subgroup.push(subnode); } } } } return d3_transition(subgroups, id); }; d3_transitionPrototype.filter = function(filter) { var subgroups = [], subgroup, group, node; if (typeof filter !== "function") filter = d3_selection_filter(filter); for (var j = 0, m = this.length; j < m; j++) { subgroups.push(subgroup = []); for (var group = this[j], i = 0, n = group.length; i < n; i++) { if ((node = group[i]) && filter.call(node, node.__data__, i, j)) { subgroup.push(node); } } } return d3_transition(subgroups, this.id); }; d3_transitionPrototype.tween = function(name, tween) { var id = this.id; if (arguments.length < 2) return this.node().__transition__[id].tween.get(name); return d3_selection_each(this, tween == null ? function(node) { node.__transition__[id].tween.remove(name); } : function(node) { node.__transition__[id].tween.set(name, tween); }); }; function d3_transition_tween(groups, name, value, tween) { var id = groups.id; return d3_selection_each(groups, typeof value === "function" ? function(node, i, j) { node.__transition__[id].tween.set(name, tween(value.call(node, node.__data__, i, j))); } : (value = tween(value), function(node) { node.__transition__[id].tween.set(name, value); })); } d3_transitionPrototype.attr = function(nameNS, value) { if (arguments.length < 2) { for (value in nameNS) this.attr(value, nameNS[value]); return this; } var interpolate = nameNS == "transform" ? d3_interpolateTransform : d3_interpolate, name = d3.ns.qualify(nameNS); function attrNull() { this.removeAttribute(name); } function attrNullNS() { this.removeAttributeNS(name.space, name.local); } function attrTween(b) { return b == null ? attrNull : (b += "", function() { var a = this.getAttribute(name), i; return a !== b && (i = interpolate(a, b), function(t) { this.setAttribute(name, i(t)); }); }); } function attrTweenNS(b) { return b == null ? attrNullNS : (b += "", function() { var a = this.getAttributeNS(name.space, name.local), i; return a !== b && (i = interpolate(a, b), function(t) { this.setAttributeNS(name.space, name.local, i(t)); }); }); } return d3_transition_tween(this, "attr." + nameNS, value, name.local ? attrTweenNS : attrTween); }; d3_transitionPrototype.attrTween = function(nameNS, tween) { var name = d3.ns.qualify(nameNS); function attrTween(d, i) { var f = tween.call(this, d, i, this.getAttribute(name)); return f && function(t) { this.setAttribute(name, f(t)); }; } function attrTweenNS(d, i) { var f = tween.call(this, d, i, this.getAttributeNS(name.space, name.local)); return f && function(t) { this.setAttributeNS(name.space, name.local, f(t)); }; } return this.tween("attr." + nameNS, name.local ? attrTweenNS : attrTween); }; d3_transitionPrototype.style = function(name, value, priority) { var n = arguments.length; if (n < 3) { if (typeof name !== "string") { if (n < 2) value = ""; for (priority in name) this.style(priority, name[priority], value); return this; } priority = ""; } function styleNull() { this.style.removeProperty(name); } function styleString(b) { return b == null ? styleNull : (b += "", function() { var a = d3_window.getComputedStyle(this, null).getPropertyValue(name), i; return a !== b && (i = d3_interpolate(a, b), function(t) { this.style.setProperty(name, i(t), priority); }); }); } return d3_transition_tween(this, "style." + name, value, styleString); }; d3_transitionPrototype.styleTween = function(name, tween, priority) { if (arguments.length < 3) priority = ""; function styleTween(d, i) { var f = tween.call(this, d, i, d3_window.getComputedStyle(this, null).getPropertyValue(name)); return f && function(t) { this.style.setProperty(name, f(t), priority); }; } return this.tween("style." + name, styleTween); }; d3_transitionPrototype.text = function(value) { return d3_transition_tween(this, "text", value, d3_transition_text); }; function d3_transition_text(b) { if (b == null) b = ""; return function() { this.textContent = b; }; } d3_transitionPrototype.remove = function() { return this.each("end.transition", function() { var p; if (this.__transition__.count < 2 && (p = this.parentNode)) p.removeChild(this); }); }; d3_transitionPrototype.ease = function(value) { var id = this.id; if (arguments.length < 1) return this.node().__transition__[id].ease; if (typeof value !== "function") value = d3.ease.apply(d3, arguments); return d3_selection_each(this, function(node) { node.__transition__[id].ease = value; }); }; d3_transitionPrototype.delay = function(value) { var id = this.id; if (arguments.length < 1) return this.node().__transition__[id].delay; return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { node.__transition__[id].delay = +value.call(node, node.__data__, i, j); } : (value = +value, function(node) { node.__transition__[id].delay = value; })); }; d3_transitionPrototype.duration = function(value) { var id = this.id; if (arguments.length < 1) return this.node().__transition__[id].duration; return d3_selection_each(this, typeof value === "function" ? function(node, i, j) { node.__transition__[id].duration = Math.max(1, value.call(node, node.__data__, i, j)); } : (value = Math.max(1, value), function(node) { node.__transition__[id].duration = value; })); }; d3_transitionPrototype.each = function(type, listener) { var id = this.id; if (arguments.length < 2) { var inherit = d3_transitionInherit, inheritId = d3_transitionInheritId; d3_transitionInheritId = id; d3_selection_each(this, function(node, i, j) { d3_transitionInherit = node.__transition__[id]; type.call(node, node.__data__, i, j); }); d3_transitionInherit = inherit; d3_transitionInheritId = inheritId; } else { d3_selection_each(this, function(node) { var transition = node.__transition__[id]; (transition.event || (transition.event = d3.dispatch("start", "end"))).on(type, listener); }); } return this; }; d3_transitionPrototype.transition = function() { var id0 = this.id, id1 = ++d3_transitionId, subgroups = [], subgroup, group, node, transition; for (var j = 0, m = this.length; j < m; j++) { subgroups.push(subgroup = []); for (var group = this[j], i = 0, n = group.length; i < n; i++) { if (node = group[i]) { transition = Object.create(node.__transition__[id0]); transition.delay += transition.duration; d3_transitionNode(node, i, id1, transition); } subgroup.push(node); } } return d3_transition(subgroups, id1); }; function d3_transitionNode(node, i, id, inherit) { var lock = node.__transition__ || (node.__transition__ = { active: 0, count: 0 }), transition = lock[id]; if (!transition) { var time = inherit.time; transition = lock[id] = { tween: new d3_Map(), time: time, ease: inherit.ease, delay: inherit.delay, duration: inherit.duration }; ++lock.count; d3.timer(function(elapsed) { var d = node.__data__, ease = transition.ease, delay = transition.delay, duration = transition.duration, timer = d3_timer_active, tweened = []; timer.t = delay + time; if (delay <= elapsed) return start(elapsed - delay); timer.c = start; function start(elapsed) { if (lock.active > id) return stop(); lock.active = id; transition.event && transition.event.start.call(node, d, i); transition.tween.forEach(function(key, value) { if (value = value.call(node, d, i)) { tweened.push(value); } }); d3.timer(function() { timer.c = tick(elapsed || 1) ? d3_true : tick; return 1; }, 0, time); } function tick(elapsed) { if (lock.active !== id) return stop(); var t = elapsed / duration, e = ease(t), n = tweened.length; while (n > 0) { tweened[--n].call(node, e); } if (t >= 1) { transition.event && transition.event.end.call(node, d, i); return stop(); } } function stop() { if (--lock.count) delete lock[id]; else delete node.__transition__; return 1; } }, 0, time); } } d3.svg.axis = function() { var scale = d3.scale.linear(), orient = d3_svg_axisDefaultOrient, innerTickSize = 6, outerTickSize = 6, tickPadding = 3, tickArguments_ = [ 10 ], tickValues = null, tickFormat_; function axis(g) { g.each(function() { var g = d3.select(this); var scale0 = this.__chart__ || scale, scale1 = this.__chart__ = scale.copy(); var ticks = tickValues == null ? scale1.ticks ? scale1.ticks.apply(scale1, tickArguments_) : scale1.domain() : tickValues, tickFormat = tickFormat_ == null ? scale1.tickFormat ? scale1.tickFormat.apply(scale1, tickArguments_) : d3_identity : tickFormat_, tick = g.selectAll(".tick").data(ticks, scale1), tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", ε), tickExit = d3.transition(tick.exit()).style("opacity", ε).remove(), tickUpdate = d3.transition(tick.order()).style("opacity", 1), tickTransform; var range = d3_scaleRange(scale1), path = g.selectAll(".domain").data([ 0 ]), pathUpdate = (path.enter().append("path").attr("class", "domain"), d3.transition(path)); tickEnter.append("line"); tickEnter.append("text"); var lineEnter = tickEnter.select("line"), lineUpdate = tickUpdate.select("line"), text = tick.select("text").text(tickFormat), textEnter = tickEnter.select("text"), textUpdate = tickUpdate.select("text"); switch (orient) { case "bottom": { tickTransform = d3_svg_axisX; lineEnter.attr("y2", innerTickSize); textEnter.attr("y", Math.max(innerTickSize, 0) + tickPadding); lineUpdate.attr("x2", 0).attr("y2", innerTickSize); textUpdate.attr("x", 0).attr("y", Math.max(innerTickSize, 0) + tickPadding); text.attr("dy", ".71em").style("text-anchor", "middle"); pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize); break; } case "top": { tickTransform = d3_svg_axisX; lineEnter.attr("y2", -innerTickSize); textEnter.attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); lineUpdate.attr("x2", 0).attr("y2", -innerTickSize); textUpdate.attr("x", 0).attr("y", -(Math.max(innerTickSize, 0) + tickPadding)); text.attr("dy", "0em").style("text-anchor", "middle"); pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize); break; } case "left": { tickTransform = d3_svg_axisY; lineEnter.attr("x2", -innerTickSize); textEnter.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)); lineUpdate.attr("x2", -innerTickSize).attr("y2", 0); textUpdate.attr("x", -(Math.max(innerTickSize, 0) + tickPadding)).attr("y", 0); text.attr("dy", ".32em").style("text-anchor", "end"); pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize); break; } case "right": { tickTransform = d3_svg_axisY; lineEnter.attr("x2", innerTickSize); textEnter.attr("x", Math.max(innerTickSize, 0) + tickPadding); lineUpdate.attr("x2", innerTickSize).attr("y2", 0); textUpdate.attr("x", Math.max(innerTickSize, 0) + tickPadding).attr("y", 0); text.attr("dy", ".32em").style("text-anchor", "start"); pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize); break; } } if (scale1.rangeBand) { var x = scale1, dx = x.rangeBand() / 2; scale0 = scale1 = function(d) { return x(d) + dx; }; } else if (scale0.rangeBand) { scale0 = scale1; } else { tickExit.call(tickTransform, scale1); } tickEnter.call(tickTransform, scale0); tickUpdate.call(tickTransform, scale1); }); } axis.scale = function(x) { if (!arguments.length) return scale; scale = x; return axis; }; axis.orient = function(x) { if (!arguments.length) return orient; orient = x in d3_svg_axisOrients ? x + "" : d3_svg_axisDefaultOrient; return axis; }; axis.ticks = function() { if (!arguments.length) return tickArguments_; tickArguments_ = arguments; return axis; }; axis.tickValues = function(x) { if (!arguments.length) return tickValues; tickValues = x; return axis; }; axis.tickFormat = function(x) { if (!arguments.length) return tickFormat_; tickFormat_ = x; return axis; }; axis.tickSize = function(x) { var n = arguments.length; if (!n) return innerTickSize; innerTickSize = +x; outerTickSize = +arguments[n - 1]; return axis; }; axis.innerTickSize = function(x) { if (!arguments.length) return innerTickSize; innerTickSize = +x; return axis; }; axis.outerTickSize = function(x) { if (!arguments.length) return outerTickSize; outerTickSize = +x; return axis; }; axis.tickPadding = function(x) { if (!arguments.length) return tickPadding; tickPadding = +x; return axis; }; axis.tickSubdivide = function() { return arguments.length && axis; }; return axis; }; var d3_svg_axisDefaultOrient = "bottom", d3_svg_axisOrients = { top: 1, right: 1, bottom: 1, left: 1 }; function d3_svg_axisX(selection, x) { selection.attr("transform", function(d) { return "translate(" + x(d) + ",0)"; }); } function d3_svg_axisY(selection, y) { selection.attr("transform", function(d) { return "translate(0," + y(d) + ")"; }); } d3.svg.brush = function() { var event = d3_eventDispatch(brush, "brushstart", "brush", "brushend"), x = null, y = null, xExtent = [ 0, 0 ], yExtent = [ 0, 0 ], xExtentDomain, yExtentDomain, xClamp = true, yClamp = true, resizes = d3_svg_brushResizes[0]; function brush(g) { g.each(function() { var g = d3.select(this).style("pointer-events", "all").style("-webkit-tap-highlight-color", "rgba(0,0,0,0)").on("mousedown.brush", brushstart).on("touchstart.brush", brushstart); var background = g.selectAll(".background").data([ 0 ]); background.enter().append("rect").attr("class", "background").style("visibility", "hidden").style("cursor", "crosshair"); g.selectAll(".extent").data([ 0 ]).enter().append("rect").attr("class", "extent").style("cursor", "move"); var resize = g.selectAll(".resize").data(resizes, d3_identity); resize.exit().remove(); resize.enter().append("g").attr("class", function(d) { return "resize " + d; }).style("cursor", function(d) { return d3_svg_brushCursor[d]; }).append("rect").attr("x", function(d) { return /[ew]$/.test(d) ? -3 : null; }).attr("y", function(d) { return /^[ns]/.test(d) ? -3 : null; }).attr("width", 6).attr("height", 6).style("visibility", "hidden"); resize.style("display", brush.empty() ? "none" : null); var gUpdate = d3.transition(g), backgroundUpdate = d3.transition(background), range; if (x) { range = d3_scaleRange(x); backgroundUpdate.attr("x", range[0]).attr("width", range[1] - range[0]); redrawX(gUpdate); } if (y) { range = d3_scaleRange(y); backgroundUpdate.attr("y", range[0]).attr("height", range[1] - range[0]); redrawY(gUpdate); } redraw(gUpdate); }); } brush.event = function(g) { g.each(function() { var event_ = event.of(this, arguments), extent1 = { x: xExtent, y: yExtent, i: xExtentDomain, j: yExtentDomain }, extent0 = this.__chart__ || extent1; this.__chart__ = extent1; if (d3_transitionInheritId) { d3.select(this).transition().each("start.brush", function() { xExtentDomain = extent0.i; yExtentDomain = extent0.j; xExtent = extent0.x; yExtent = extent0.y; event_({ type: "brushstart" }); }).tween("brush:brush", function() { var xi = d3_interpolateArray(xExtent, extent1.x), yi = d3_interpolateArray(yExtent, extent1.y); xExtentDomain = yExtentDomain = null; return function(t) { xExtent = extent1.x = xi(t); yExtent = extent1.y = yi(t); event_({ type: "brush", mode: "resize" }); }; }).each("end.brush", function() { xExtentDomain = extent1.i; yExtentDomain = extent1.j; event_({ type: "brush", mode: "resize" }); event_({ type: "brushend" }); }); } else { event_({ type: "brushstart" }); event_({ type: "brush", mode: "resize" }); event_({ type: "brushend" }); } }); }; function redraw(g) { g.selectAll(".resize").attr("transform", function(d) { return "translate(" + xExtent[+/e$/.test(d)] + "," + yExtent[+/^s/.test(d)] + ")"; }); } function redrawX(g) { g.select(".extent").attr("x", xExtent[0]); g.selectAll(".extent,.n>rect,.s>rect").attr("width", xExtent[1] - xExtent[0]); } function redrawY(g) { g.select(".extent").attr("y", yExtent[0]); g.selectAll(".extent,.e>rect,.w>rect").attr("height", yExtent[1] - yExtent[0]); } function brushstart() { var target = this, eventTarget = d3.select(d3.event.target), event_ = event.of(target, arguments), g = d3.select(target), resizing = eventTarget.datum(), resizingX = !/^(n|s)$/.test(resizing) && x, resizingY = !/^(e|w)$/.test(resizing) && y, dragging = eventTarget.classed("extent"), dragRestore = d3_event_dragSuppress(), center, origin = d3.mouse(target), offset; var w = d3.select(d3_window).on("keydown.brush", keydown).on("keyup.brush", keyup); if (d3.event.changedTouches) { w.on("touchmove.brush", brushmove).on("touchend.brush", brushend); } else { w.on("mousemove.brush", brushmove).on("mouseup.brush", brushend); } g.interrupt().selectAll("*").interrupt(); if (dragging) { origin[0] = xExtent[0] - origin[0]; origin[1] = yExtent[0] - origin[1]; } else if (resizing) { var ex = +/w$/.test(resizing), ey = +/^n/.test(resizing); offset = [ xExtent[1 - ex] - origin[0], yExtent[1 - ey] - origin[1] ]; origin[0] = xExtent[ex]; origin[1] = yExtent[ey]; } else if (d3.event.altKey) center = origin.slice(); g.style("pointer-events", "none").selectAll(".resize").style("display", null); d3.select("body").style("cursor", eventTarget.style("cursor")); event_({ type: "brushstart" }); brushmove(); function keydown() { if (d3.event.keyCode == 32) { if (!dragging) { center = null; origin[0] -= xExtent[1]; origin[1] -= yExtent[1]; dragging = 2; } d3_eventPreventDefault(); } } function keyup() { if (d3.event.keyCode == 32 && dragging == 2) { origin[0] += xExtent[1]; origin[1] += yExtent[1]; dragging = 0; d3_eventPreventDefault(); } } function brushmove() { var point = d3.mouse(target), moved = false; if (offset) { point[0] += offset[0]; point[1] += offset[1]; } if (!dragging) { if (d3.event.altKey) { if (!center) center = [ (xExtent[0] + xExtent[1]) / 2, (yExtent[0] + yExtent[1]) / 2 ]; origin[0] = xExtent[+(point[0] < center[0])]; origin[1] = yExtent[+(point[1] < center[1])]; } else center = null; } if (resizingX && move1(point, x, 0)) { redrawX(g); moved = true; } if (resizingY && move1(point, y, 1)) { redrawY(g); moved = true; } if (moved) { redraw(g); event_({ type: "brush", mode: dragging ? "move" : "resize" }); } } function move1(point, scale, i) { var range = d3_scaleRange(scale), r0 = range[0], r1 = range[1], position = origin[i], extent = i ? yExtent : xExtent, size = extent[1] - extent[0], min, max; if (dragging) { r0 -= position; r1 -= size + position; } min = (i ? yClamp : xClamp) ? Math.max(r0, Math.min(r1, point[i])) : point[i]; if (dragging) { max = (min += position) + size; } else { if (center) position = Math.max(r0, Math.min(r1, 2 * center[i] - min)); if (position < min) { max = min; min = position; } else { max = position; } } if (extent[0] != min || extent[1] != max) { if (i) yExtentDomain = null; else xExtentDomain = null; extent[0] = min; extent[1] = max; return true; } } function brushend() { brushmove(); g.style("pointer-events", "all").selectAll(".resize").style("display", brush.empty() ? "none" : null); d3.select("body").style("cursor", null); w.on("mousemove.brush", null).on("mouseup.brush", null).on("touchmove.brush", null).on("touchend.brush", null).on("keydown.brush", null).on("keyup.brush", null); dragRestore(); event_({ type: "brushend" }); } } brush.x = function(z) { if (!arguments.length) return x; x = z; resizes = d3_svg_brushResizes[!x << 1 | !y]; return brush; }; brush.y = function(z) { if (!arguments.length) return y; y = z; resizes = d3_svg_brushResizes[!x << 1 | !y]; return brush; }; brush.clamp = function(z) { if (!arguments.length) return x && y ? [ xClamp, yClamp ] : x ? xClamp : y ? yClamp : null; if (x && y) xClamp = !!z[0], yClamp = !!z[1]; else if (x) xClamp = !!z; else if (y) yClamp = !!z; return brush; }; brush.extent = function(z) { var x0, x1, y0, y1, t; if (!arguments.length) { if (x) { if (xExtentDomain) { x0 = xExtentDomain[0], x1 = xExtentDomain[1]; } else { x0 = xExtent[0], x1 = xExtent[1]; if (x.invert) x0 = x.invert(x0), x1 = x.invert(x1); if (x1 < x0) t = x0, x0 = x1, x1 = t; } } if (y) { if (yExtentDomain) { y0 = yExtentDomain[0], y1 = yExtentDomain[1]; } else { y0 = yExtent[0], y1 = yExtent[1]; if (y.invert) y0 = y.invert(y0), y1 = y.invert(y1); if (y1 < y0) t = y0, y0 = y1, y1 = t; } } return x && y ? [ [ x0, y0 ], [ x1, y1 ] ] : x ? [ x0, x1 ] : y && [ y0, y1 ]; } if (x) { x0 = z[0], x1 = z[1]; if (y) x0 = x0[0], x1 = x1[0]; xExtentDomain = [ x0, x1 ]; if (x.invert) x0 = x(x0), x1 = x(x1); if (x1 < x0) t = x0, x0 = x1, x1 = t; if (x0 != xExtent[0] || x1 != xExtent[1]) xExtent = [ x0, x1 ]; } if (y) { y0 = z[0], y1 = z[1]; if (x) y0 = y0[1], y1 = y1[1]; yExtentDomain = [ y0, y1 ]; if (y.invert) y0 = y(y0), y1 = y(y1); if (y1 < y0) t = y0, y0 = y1, y1 = t; if (y0 != yExtent[0] || y1 != yExtent[1]) yExtent = [ y0, y1 ]; } return brush; }; brush.clear = function() { if (!brush.empty()) { xExtent = [ 0, 0 ], yExtent = [ 0, 0 ]; xExtentDomain = yExtentDomain = null; } return brush; }; brush.empty = function() { return !!x && xExtent[0] == xExtent[1] || !!y && yExtent[0] == yExtent[1]; }; return d3.rebind(brush, event, "on"); }; var d3_svg_brushCursor = { n: "ns-resize", e: "ew-resize", s: "ns-resize", w: "ew-resize", nw: "nwse-resize", ne: "nesw-resize", se: "nwse-resize", sw: "nesw-resize" }; var d3_svg_brushResizes = [ [ "n", "e", "s", "w", "nw", "ne", "se", "sw" ], [ "e", "w" ], [ "n", "s" ], [] ]; var d3_time_format = d3_time.format = d3_locale_enUS.timeFormat; var d3_time_formatUtc = d3_time_format.utc; var d3_time_formatIso = d3_time_formatUtc("%Y-%m-%dT%H:%M:%S.%LZ"); d3_time_format.iso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") ? d3_time_formatIsoNative : d3_time_formatIso; function d3_time_formatIsoNative(date) { return date.toISOString(); } d3_time_formatIsoNative.parse = function(string) { var date = new Date(string); return isNaN(date) ? null : date; }; d3_time_formatIsoNative.toString = d3_time_formatIso.toString; d3_time.second = d3_time_interval(function(date) { return new d3_date(Math.floor(date / 1e3) * 1e3); }, function(date, offset) { date.setTime(date.getTime() + Math.floor(offset) * 1e3); }, function(date) { return date.getSeconds(); }); d3_time.seconds = d3_time.second.range; d3_time.seconds.utc = d3_time.second.utc.range; d3_time.minute = d3_time_interval(function(date) { return new d3_date(Math.floor(date / 6e4) * 6e4); }, function(date, offset) { date.setTime(date.getTime() + Math.floor(offset) * 6e4); }, function(date) { return date.getMinutes(); }); d3_time.minutes = d3_time.minute.range; d3_time.minutes.utc = d3_time.minute.utc.range; d3_time.hour = d3_time_interval(function(date) { var timezone = date.getTimezoneOffset() / 60; return new d3_date((Math.floor(date / 36e5 - timezone) + timezone) * 36e5); }, function(date, offset) { date.setTime(date.getTime() + Math.floor(offset) * 36e5); }, function(date) { return date.getHours(); }); d3_time.hours = d3_time.hour.range; d3_time.hours.utc = d3_time.hour.utc.range; d3_time.month = d3_time_interval(function(date) { date = d3_time.day(date); date.setDate(1); return date; }, function(date, offset) { date.setMonth(date.getMonth() + offset); }, function(date) { return date.getMonth(); }); d3_time.months = d3_time.month.range; d3_time.months.utc = d3_time.month.utc.range; function d3_time_scale(linear, methods, format) { function scale(x) { return linear(x); } scale.invert = function(x) { return d3_time_scaleDate(linear.invert(x)); }; scale.domain = function(x) { if (!arguments.length) return linear.domain().map(d3_time_scaleDate); linear.domain(x); return scale; }; function tickMethod(extent, count) { var span = extent[1] - extent[0], target = span / count, i = d3.bisect(d3_time_scaleSteps, target); return i == d3_time_scaleSteps.length ? [ methods.year, d3_scale_linearTickRange(extent.map(function(d) { return d / 31536e6; }), count)[2] ] : !i ? [ d3_time_scaleMilliseconds, d3_scale_linearTickRange(extent, count)[2] ] : methods[target / d3_time_scaleSteps[i - 1] < d3_time_scaleSteps[i] / target ? i - 1 : i]; } scale.nice = function(interval, skip) { var domain = scale.domain(), extent = d3_scaleExtent(domain), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" && tickMethod(extent, interval); if (method) interval = method[0], skip = method[1]; function skipped(date) { return !isNaN(date) && !interval.range(date, d3_time_scaleDate(+date + 1), skip).length; } return scale.domain(d3_scale_nice(domain, skip > 1 ? { floor: function(date) { while (skipped(date = interval.floor(date))) date = d3_time_scaleDate(date - 1); return date; }, ceil: function(date) { while (skipped(date = interval.ceil(date))) date = d3_time_scaleDate(+date + 1); return date; } } : interval)); }; scale.ticks = function(interval, skip) { var extent = d3_scaleExtent(scale.domain()), method = interval == null ? tickMethod(extent, 10) : typeof interval === "number" ? tickMethod(extent, interval) : !interval.range && [ { range: interval }, skip ]; if (method) interval = method[0], skip = method[1]; return interval.range(extent[0], d3_time_scaleDate(+extent[1] + 1), skip < 1 ? 1 : skip); }; scale.tickFormat = function() { return format; }; scale.copy = function() { return d3_time_scale(linear.copy(), methods, format); }; return d3_scale_linearRebind(scale, linear); } function d3_time_scaleDate(t) { return new Date(t); } var d3_time_scaleSteps = [ 1e3, 5e3, 15e3, 3e4, 6e4, 3e5, 9e5, 18e5, 36e5, 108e5, 216e5, 432e5, 864e5, 1728e5, 6048e5, 2592e6, 7776e6, 31536e6 ]; var d3_time_scaleLocalMethods = [ [ d3_time.second, 1 ], [ d3_time.second, 5 ], [ d3_time.second, 15 ], [ d3_time.second, 30 ], [ d3_time.minute, 1 ], [ d3_time.minute, 5 ], [ d3_time.minute, 15 ], [ d3_time.minute, 30 ], [ d3_time.hour, 1 ], [ d3_time.hour, 3 ], [ d3_time.hour, 6 ], [ d3_time.hour, 12 ], [ d3_time.day, 1 ], [ d3_time.day, 2 ], [ d3_time.week, 1 ], [ d3_time.month, 1 ], [ d3_time.month, 3 ], [ d3_time.year, 1 ] ]; var d3_time_scaleLocalFormat = d3_time_format.multi([ [ ".%L", function(d) { return d.getMilliseconds(); } ], [ ":%S", function(d) { return d.getSeconds(); } ], [ "%I:%M", function(d) { return d.getMinutes(); } ], [ "%I %p", function(d) { return d.getHours(); } ], [ "%a %d", function(d) { return d.getDay() && d.getDate() != 1; } ], [ "%b %d", function(d) { return d.getDate() != 1; } ], [ "%B", function(d) { return d.getMonth(); } ], [ "%Y", d3_true ] ]); var d3_time_scaleMilliseconds = { range: function(start, stop, step) { return d3.range(Math.ceil(start / step) * step, +stop, step).map(d3_time_scaleDate); }, floor: d3_identity, ceil: d3_identity }; d3_time_scaleLocalMethods.year = d3_time.year; d3_time.scale = function() { return d3_time_scale(d3.scale.linear(), d3_time_scaleLocalMethods, d3_time_scaleLocalFormat); }; var d3_time_scaleUtcMethods = d3_time_scaleLocalMethods.map(function(m) { return [ m[0].utc, m[1] ]; }); var d3_time_scaleUtcFormat = d3_time_formatUtc.multi([ [ ".%L", function(d) { return d.getUTCMilliseconds(); } ], [ ":%S", function(d) { return d.getUTCSeconds(); } ], [ "%I:%M", function(d) { return d.getUTCMinutes(); } ], [ "%I %p", function(d) { return d.getUTCHours(); } ], [ "%a %d", function(d) { return d.getUTCDay() && d.getUTCDate() != 1; } ], [ "%b %d", function(d) { return d.getUTCDate() != 1; } ], [ "%B", function(d) { return d.getUTCMonth(); } ], [ "%Y", d3_true ] ]); d3_time_scaleUtcMethods.year = d3_time.year.utc; d3_time.scale.utc = function() { return d3_time_scale(d3.scale.linear(), d3_time_scaleUtcMethods, d3_time_scaleUtcFormat); }; d3.text = d3_xhrType(function(request) { return request.responseText; }); d3.json = function(url, callback) { return d3_xhr(url, "application/json", d3_json, callback); }; function d3_json(request) { return JSON.parse(request.responseText); } d3.html = function(url, callback) { return d3_xhr(url, "text/html", d3_html, callback); }; function d3_html(request) { var range = d3_document.createRange(); range.selectNode(d3_document.body); return range.createContextualFragment(request.responseText); } d3.xml = d3_xhrType(function(request) { return request.responseXML; }); if (typeof define === "function" && define.amd) { define(d3); } else if (typeof module === "object" && module.exports) { module.exports = d3; } else { this.d3 = d3; } }();nipype-0.11.0/nipype/external/portalocker.py000066400000000000000000000072211257611314500211310ustar00rootroot00000000000000# portalocker.py - Cross-platform (posix/nt) API for flock-style file locking. # Requires python 1.5.2 or better. '''Cross-platform (posix/nt) API for flock-style file locking. Synopsis: import portalocker file = open('somefile', 'r+') portalocker.lock(file, portalocker.LOCK_EX) file.seek(12) file.write('foo') file.close() If you know what you're doing, you may choose to portalocker.unlock(file) before closing the file, but why? Methods: lock( file, flags ) unlock( file ) Constants: LOCK_EX LOCK_SH LOCK_NB Exceptions: LockException Notes: For the 'nt' platform, this module requires the Python Extensions for Windows. Be aware that this may not work as expected on Windows 95/98/ME. History: I learned the win32 technique for locking files from sample code provided by John Nielsen in the documentation that accompanies the win32 modules. Author: Jonathan Feinberg , Lowell Alleman Version: $Id: portalocker.py 5474 2008-05-16 20:53:50Z lowell $ ''' __all__ = [ 'lock', 'unlock', 'LOCK_EX', 'LOCK_SH', 'LOCK_NB', 'LockException', ] import os class LockException(Exception): # Error codes: LOCK_FAILED = 1 if os.name == 'nt': import win32con import win32file import pywintypes LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK LOCK_SH = 0 # the default LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY # is there any reason not to reuse the following structure? __overlapped = pywintypes.OVERLAPPED() elif os.name == 'posix': import fcntl LOCK_EX = fcntl.LOCK_EX LOCK_SH = fcntl.LOCK_SH LOCK_NB = fcntl.LOCK_NB else: raise RuntimeError, 'PortaLocker only defined for nt and posix platforms' if os.name == 'nt': def lock(file, flags): hfile = win32file._get_osfhandle(file.fileno()) try: win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped) except pywintypes.error, exc_value: # error: (33, 'LockFileEx', 'The process cannot access the file because another process has locked a portion of the file.') if exc_value[0] == 33: raise LockException(LockException.LOCK_FAILED, exc_value[2]) else: # Q: Are there exceptions/codes we should be dealing with here? raise def unlock(file): hfile = win32file._get_osfhandle(file.fileno()) try: win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped) except pywintypes.error, exc_value: if exc_value[0] == 158: # error: (158, 'UnlockFileEx', 'The segment is already unlocked.') # To match the 'posix' implementation, silently ignore this error pass else: # Q: Are there exceptions/codes we should be dealing with here? raise elif os.name == 'posix': def lock(file, flags): try: fcntl.flock(file.fileno(), flags) except IOError, exc_value: # The exception code varies on different systems so we'll catch # every IO error raise LockException(*exc_value) def unlock(file): fcntl.flock(file.fileno(), fcntl.LOCK_UN) if __name__ == '__main__': from time import time, strftime, localtime import sys import portalocker log = open('log.txt', 'a+') portalocker.lock(log, portalocker.LOCK_EX) timestamp = strftime('%m/%d/%Y %H:%M:%S\n', localtime(time())) log.write( timestamp ) print 'Wrote lines. Hit enter to release lock.' dummy = sys.stdin.readline() log.close() nipype-0.11.0/nipype/external/provcopy.py000066400000000000000000002333201257611314500204660ustar00rootroot00000000000000'''Python implemetation of the W3C Provenance Data Model (PROV-DM) Support for PROV-JSON import/export References: PROV-DM: http://www.w3.org/TR/prov-dm/ @author: Trung Dong Huynh @copyright: University of Southampton 2013 ''' import logging import datetime import json import re import dateutil.parser import collections from collections import defaultdict import six try: from rdflib.term import URIRef, BNode from rdflib.term import Literal as RDFLiteral from rdflib.graph import ConjunctiveGraph, Graph from rdflib.namespace import RDF, RDFS except ImportError: pass from copy import deepcopy, copy try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict logger = logging.getLogger(__name__) # # PROV record constants - PROV-DM LC # C1. Entities/Activities PROV_REC_ENTITY = 1 PROV_REC_ACTIVITY = 2 PROV_REC_GENERATION = 11 PROV_REC_USAGE = 12 PROV_REC_COMMUNICATION = 13 PROV_REC_START = 14 PROV_REC_END = 15 PROV_REC_INVALIDATION = 16 # C2. Derivations PROV_REC_DERIVATION = 21 # C3. Agents/Responsibility PROV_REC_AGENT = 3 PROV_REC_ATTRIBUTION = 31 PROV_REC_ASSOCIATION = 32 PROV_REC_DELEGATION = 33 PROV_REC_INFLUENCE = 34 # C4. Bundles PROV_REC_BUNDLE = 4 # This is the lowest value, so bundle(s) in JSON will be decoded first # C5. Alternate PROV_REC_ALTERNATE = 51 PROV_REC_SPECIALIZATION = 52 PROV_REC_MENTION = 53 # C6. Collections PROV_REC_MEMBERSHIP = 61 PROV_RECORD_TYPES = ( (PROV_REC_ENTITY, u'Entity'), (PROV_REC_ACTIVITY, u'Activity'), (PROV_REC_GENERATION, u'Generation'), (PROV_REC_USAGE, u'Usage'), (PROV_REC_COMMUNICATION, u'Communication'), (PROV_REC_START, u'Start'), (PROV_REC_END, u'End'), (PROV_REC_INVALIDATION, u'Invalidation'), (PROV_REC_DERIVATION, u'Derivation'), (PROV_REC_AGENT, u'Agent'), (PROV_REC_ATTRIBUTION, u'Attribution'), (PROV_REC_ASSOCIATION, u'Association'), (PROV_REC_DELEGATION, u'Delegation'), (PROV_REC_INFLUENCE, u'Influence'), (PROV_REC_BUNDLE, u'Bundle'), (PROV_REC_ALTERNATE, u'Alternate'), (PROV_REC_SPECIALIZATION, u'Specialization'), (PROV_REC_MENTION, u'Mention'), (PROV_REC_MEMBERSHIP, u'Membership'), ) PROV_N_MAP = { PROV_REC_ENTITY: u'entity', PROV_REC_ACTIVITY: u'activity', PROV_REC_GENERATION: u'wasGeneratedBy', PROV_REC_USAGE: u'used', PROV_REC_COMMUNICATION: u'wasInformedBy', PROV_REC_START: u'wasStartedBy', PROV_REC_END: u'wasEndedBy', PROV_REC_INVALIDATION: u'wasInvalidatedBy', PROV_REC_DERIVATION: u'wasDerivedFrom', PROV_REC_AGENT: u'agent', PROV_REC_ATTRIBUTION: u'wasAttributedTo', PROV_REC_ASSOCIATION: u'wasAssociatedWith', PROV_REC_DELEGATION: u'actedOnBehalfOf', PROV_REC_INFLUENCE: u'wasInfluencedBy', PROV_REC_ALTERNATE: u'alternateOf', PROV_REC_SPECIALIZATION: u'specializationOf', PROV_REC_MENTION: u'mentionOf', PROV_REC_MEMBERSHIP: u'hadMember', PROV_REC_BUNDLE: u'bundle', } # # Identifiers for PROV's attributes PROV_ATTR_ENTITY = 1 PROV_ATTR_ACTIVITY = 2 PROV_ATTR_TRIGGER = 3 PROV_ATTR_INFORMED = 4 PROV_ATTR_INFORMANT = 5 PROV_ATTR_STARTER = 6 PROV_ATTR_ENDER = 7 PROV_ATTR_AGENT = 8 PROV_ATTR_PLAN = 9 PROV_ATTR_DELEGATE = 10 PROV_ATTR_RESPONSIBLE = 11 PROV_ATTR_GENERATED_ENTITY = 12 PROV_ATTR_USED_ENTITY = 13 PROV_ATTR_GENERATION = 14 PROV_ATTR_USAGE = 15 PROV_ATTR_SPECIFIC_ENTITY = 16 PROV_ATTR_GENERAL_ENTITY = 17 PROV_ATTR_ALTERNATE1 = 18 PROV_ATTR_ALTERNATE2 = 19 PROV_ATTR_BUNDLE = 20 PROV_ATTR_INFLUENCEE = 21 PROV_ATTR_INFLUENCER = 22 PROV_ATTR_COLLECTION = 23 # Literal properties PROV_ATTR_TIME = 100 PROV_ATTR_STARTTIME = 101 PROV_ATTR_ENDTIME = 102 PROV_RECORD_ATTRIBUTES = ( # Relations properties (PROV_ATTR_ENTITY, u'prov:entity'), (PROV_ATTR_ACTIVITY, u'prov:activity'), (PROV_ATTR_TRIGGER, u'prov:trigger'), (PROV_ATTR_INFORMED, u'prov:informed'), (PROV_ATTR_INFORMANT, u'prov:informant'), (PROV_ATTR_STARTER, u'prov:starter'), (PROV_ATTR_ENDER, u'prov:ender'), (PROV_ATTR_AGENT, u'prov:agent'), (PROV_ATTR_PLAN, u'prov:plan'), (PROV_ATTR_DELEGATE, u'prov:delegate'), (PROV_ATTR_RESPONSIBLE, u'prov:responsible'), (PROV_ATTR_GENERATED_ENTITY, u'prov:generatedEntity'), (PROV_ATTR_USED_ENTITY, u'prov:usedEntity'), (PROV_ATTR_GENERATION, u'prov:generation'), (PROV_ATTR_USAGE, u'prov:usage'), (PROV_ATTR_SPECIFIC_ENTITY, u'prov:specificEntity'), (PROV_ATTR_GENERAL_ENTITY, u'prov:generalEntity'), (PROV_ATTR_ALTERNATE1, u'prov:alternate1'), (PROV_ATTR_ALTERNATE2, u'prov:alternate2'), (PROV_ATTR_BUNDLE, u'prov:bundle'), (PROV_ATTR_INFLUENCEE, u'prov:influencee'), (PROV_ATTR_INFLUENCER, u'prov:influencer'), (PROV_ATTR_COLLECTION, u'prov:collection'), # Literal properties (PROV_ATTR_TIME, u'prov:time'), (PROV_ATTR_STARTTIME, u'prov:startTime'), (PROV_ATTR_ENDTIME, u'prov:endTime'), ) PROV_ATTRIBUTE_LITERALS = set([PROV_ATTR_TIME, PROV_ATTR_STARTTIME, PROV_ATTR_ENDTIME]) PROV_RECORD_IDS_MAP = dict((PROV_N_MAP[rec_type_id], rec_type_id) for rec_type_id in PROV_N_MAP) PROV_ID_ATTRIBUTES_MAP = dict((prov_id, attribute) for (prov_id, attribute) in PROV_RECORD_ATTRIBUTES) PROV_ATTRIBUTES_ID_MAP = dict((attribute, prov_id) for (prov_id, attribute) in PROV_RECORD_ATTRIBUTES) # Converting an attribute to the normal form for comparison purposes _normalise_attributes = lambda attr: (unicode(attr[0]), unicode(attr[1])) # Datatypes attr2rdf = lambda attr: PROV[PROV_ID_ATTRIBUTES_MAP[attr].split('prov:')[1]].rdf_representation() def _parse_xsd_dateTime(s): return dateutil.parser.parse(s) def _ensure_datetime(time): if isinstance(time, six.string_types): return _parse_xsd_dateTime(time) else: return time def parse_xsd_dateTime(s): try: return _parse_xsd_dateTime(s) except ValueError: pass return None DATATYPE_PARSERS = { datetime.datetime: parse_xsd_dateTime, } def parse_datatype(value, datatype): if datatype in DATATYPE_PARSERS: # found the required parser return DATATYPE_PARSERS[datatype](value) else: # No parser found for the given data type raise Exception(u'No parser found for the data type <%s>' % unicode(datatype)) # Mappings for XSD datatypes to Python standard types XSD_DATATYPE_PARSERS = { u"xsd:string": unicode, u"xsd:double": float, u"xsd:long": long, u"xsd:int": int, u"xsd:boolean": bool, u"xsd:dateTime": parse_xsd_dateTime, } def parse_xsd_types(value, datatype): # if the datatype is a QName, convert it to a Unicode string datatype = unicode(datatype) return XSD_DATATYPE_PARSERS[datatype](value) if datatype in XSD_DATATYPE_PARSERS else None def _ensure_multiline_string_triple_quoted(s): format_str = u'"""%s"""' if isinstance(s, six.string_types) and '\n' in s else u'"%s"' return format_str % s def encoding_PROV_N_value(value): if isinstance(value, six.string_types): return _ensure_multiline_string_triple_quoted(value) elif isinstance(value, datetime.datetime): return value.isoformat() elif isinstance(value, float): return u'"%f" %%%% xsd:float' % value else: return unicode(value) class AnonymousIDGenerator(): def __init__(self): self._cache = {} self._count = 0 def get_anon_id(self, obj, local_prefix="id"): if obj not in self._cache: self._count += 1 self._cache[obj] = Identifier('_:%s%d' % (local_prefix, self._count)) return self._cache[obj] class Literal(object): def __init__(self, value, datatype=None, langtag=None): self._value = value if langtag: if datatype is None: logger.debug('Assuming prov:InternationalizedString as the type of "%s"@%s' % (value, langtag)) datatype = PROV["InternationalizedString"] elif datatype != PROV["InternationalizedString"]: logger.warn('Invalid data type (%s) for "%s"@%s, overridden as prov:InternationalizedString.' % (value, langtag)) datatype = PROV["InternationalizedString"] self._datatype = datatype self._langtag = langtag def __unicode__(self): return self.provn_representation() def __str__(self): return unicode(self).encode('utf-8') def __eq__(self, other): return self._value == other._value and self._datatype == other._datatype and self._langtag == other._langtag if isinstance(other, Literal) else False def __hash__(self): return hash((self._value, self._datatype, self._langtag)) def get_value(self): return self._value def get_datatype(self): return self._datatype def get_langtag(self): return self._langtag def has_no_langtag(self): return self._langtag is None def provn_representation(self): if self._langtag: # a language tag can only go with prov:InternationalizedString return u'%s@%s' % (_ensure_multiline_string_triple_quoted(self._value), unicode(self._langtag)) else: return u'%s %%%% %s' % (_ensure_multiline_string_triple_quoted(self._value), unicode(self._datatype)) def json_representation(self): if self._langtag: # a language tag can only go with prov:InternationalizedString return {'$': unicode(self._value), 'lang': self._langtag} else: if isinstance(self._datatype, QName): return {'$': unicode(self._value), 'type': unicode(self._datatype)} else: # Assuming it is a valid identifier return {'$': unicode(self._value), 'type': self._datatype.get_uri()} def rdf_representation(self): if self._langtag: # a langtag can only goes with string return RDFLiteral(self._value, lang=str(self._langtag)) else: return RDFLiteral(self._value, datatype=self._datatype.get_uri()) class Identifier(object): def __init__(self, uri): self._uri = unicode(uri) # Ensure this is a unicode string def get_uri(self): return self._uri def __unicode__(self): return self._uri def __str__(self): return unicode(self).encode('utf-8') def __eq__(self, other): return self.get_uri() == other.get_uri() if isinstance(other, Identifier) else False def __hash__(self): return hash(self.get_uri()) def provn_representation(self): return u'"%s" %%%% xsd:anyURI' % self._uri def json_representation(self): return {'$': self._uri, 'type': u'xsd:anyURI'} def rdf_representation(self): return URIRef(self.get_uri()) class QName(Identifier): def __init__(self, namespace, localpart): self._namespace = namespace self._localpart = localpart self._str = u':'.join([namespace._prefix, localpart]) if namespace._prefix else localpart def get_namespace(self): return self._namespace def get_localpart(self): return self._localpart def get_uri(self): return u''.join([self._namespace._uri, self._localpart]) def __unicode__(self): return self._str def __str__(self): return unicode(self).encode('utf-8') def provn_representation(self): return u"'%s'" % self._str def json_representation(self): return {'$': self._str, 'type': u'xsd:QName'} class Namespace(object): def __init__(self, prefix, uri): self._prefix = prefix self._uri = uri self._cache = dict() def get_prefix(self): return self._prefix def get_uri(self): return self._uri def contains(self, identifier): uri = identifier if isinstance(identifier, (str, unicode)) else (identifier.get_uri() if isinstance(identifier, Identifier) else None) return uri.startswith(self._uri) if uri else False def qname(self, identifier): uri = identifier if isinstance(identifier, (str, unicode)) else (identifier.get_uri() if isinstance(identifier, Identifier) else None) if uri and uri.startswith(self._uri): return QName(self, uri[len(self._uri):]) else: return None def __eq__(self, other): return (self._uri == other._uri and self._prefix == other._prefix) if isinstance(other, Namespace) else False def __hash__(self): return hash((self._uri, self._prefix)) def __getitem__(self, localpart): if localpart in self._cache: return self._cache[localpart] else: qname = QName(self, localpart) self._cache[localpart] = qname return qname XSD = Namespace("xsd", 'http://www.w3.org/2001/XMLSchema-datatypes#') PROV = Namespace("prov", 'http://www.w3.org/ns/prov#') # Exceptions class ProvException(Exception): """Base class for exceptions in this module.""" pass class ProvExceptionMissingRequiredAttribute(ProvException): def __init__(self, record_type, attribute_id): self.record_type = record_type self.attribute_id = attribute_id self.args += (PROV_N_MAP[record_type], attribute_id) def __str__(self): return 'Missing the required attribute "%s" in %s' % (PROV_ID_ATTRIBUTES_MAP[self.attribute_id], PROV_N_MAP[self.record_type]) class ProvExceptionNotValidAttribute(ProvException): def __init__(self, record_type, attribute, attribute_types): self.record_type = record_type self.attribute = attribute self.attribute_types = attribute_types self.args += (PROV_N_MAP[record_type], unicode(attribute), attribute_types) def __str__(self): return 'Invalid attribute value: %s. %s expected' % (self.attribute, self.attribute_types) class ProvExceptionCannotUnifyAttribute(ProvException): def __init__(self, identifier, record_type1, record_type2): self.identifier = identifier self.record_type1 = record_type1 self.record_type2 = record_type2 self.args += (identifier, PROV_N_MAP[record_type1], PROV_N_MAP[record_type2]) def __str__(self): return 'Cannot unify two records of type %s and %s with same identifier (%s)' % (self.identifier, PROV_N_MAP[self.record_type1], PROV_N_MAP[self.record_type2]) class ProvExceptionContraint(ProvException): def __init__(self, record_type, attribute1, attribute2, msg): self.record_type = record_type self.attribute1 = attribute1 self.attribute2 = attribute2 self.args += (PROV_N_MAP[record_type], attribute1, attribute2, msg) self.msg = msg # PROV records class ProvRecord(object): """Base class for PROV _records.""" def __init__(self, bundle, identifier, attributes=None, other_attributes=None, asserted=True, allowed_types=None, infered_for=None): self._bundle = bundle self._identifier = identifier self._asserted = asserted self._attributes = None self._extra_attributes = None if attributes or other_attributes: self.add_attributes(attributes, other_attributes) if not asserted: self._allowed_types = allowed_types self._infered_for = infered_for def get_type(self): pass def get_allowed_types(self): if self._asserted: return [self.__class__] else: return [self.__class__] + list(self._allowed_types) def get_prov_type(self): pass def get_asserted_types(self): if self._extra_attributes: prov_type = PROV['type'] return set([value for attr, value in self._extra_attributes if attr == prov_type]) return set() def add_asserted_type(self, type_identifier): asserted_types = self.get_asserted_types() if type_identifier not in asserted_types: if self._extra_attributes is None: self._extra_attributes = set() self._extra_attributes.add((PROV['type'], type_identifier)) def get_attribute(self, attr_name): attr_name = self._bundle.valid_identifier(attr_name) if not self._extra_attributes: return [] results = [value for attr, value in self._extra_attributes if attr == attr_name] return results def get_identifier(self): return self._identifier def get_label(self): label = None if self._extra_attributes: for attribute in self._extra_attributes: if attribute[0]: if attribute[0] == PROV['label']: label = attribute[1] # use the first label found break return label if label else self._identifier def get_value(self): return self.get_attribute(PROV['value']) def _auto_literal_conversion(self, literal): '''This method normalise datatype for literals ''' if isinstance(literal, URIRef): return literal if isinstance(literal, six.string_types): return unicode(literal) if isinstance(literal, Literal) and literal.has_no_langtag(): # try convert generic Literal object to Python standard type if possible # this is to match JSON decoding's literal conversion value = parse_xsd_types(literal.get_value(), literal.get_datatype()) if value is not None: return value # No conversion here, return the original value return literal def parse_extra_attributes(self, extra_attributes): if isinstance(extra_attributes, dict): # Converting the dictionary into a list of tuples (i.e. attribute-value pairs) extra_attributes = extra_attributes.items() attr_set = set((self._bundle.valid_identifier(attribute), self._auto_literal_conversion(value)) for attribute, value in extra_attributes) return attr_set def add_extra_attributes(self, extra_attributes): if extra_attributes: if self._extra_attributes is None: self._extra_attributes = set() # Check attributes for valid qualified names attr_set = self.parse_extra_attributes(extra_attributes) self._extra_attributes.update(attr_set) def add_attributes(self, attributes, extra_attributes): if attributes: if self._attributes is None: self._attributes = attributes else: self._attributes.update(dict((k, v) for k, v in attributes.iteritems() if v is not None)) self.add_extra_attributes(extra_attributes) def get_attributes(self): return (self._attributes, self._extra_attributes) def get_bundle(self): return self._bundle def _parse_identifier(self, value): try: return value.get_identifier() except: return self._bundle.valid_identifier(value) def _parse_record(self, attribute, attribute_types): # check to see if there is an existing record matching the attribute (as the record's identifier) existing_record = self._bundle.get_record(attribute) if existing_record is None: # try to see if there is a bundle with the id existing_record = self._bundle.get_bundle(attribute) if existing_record and isinstance(existing_record, attribute_types): return existing_record else: if hasattr(attribute_types, '__getitem__'): # it is a list klass = attribute_types[0] # get the first class else: klass = attribute_types # only one class provided attribute_types = [attribute_types] if issubclass(klass, ProvRecord): # Create an inferred record for the id given: return self._bundle.add_inferred_record(klass, attribute, self, attribute_types) return None def _parse_attribute(self, attribute, attribute_types): if attribute_types is Identifier: if isinstance(attribute, ProvRecord): # This is a record, return its identifier (if any) return attribute.get_identifier() # Otherwise, trying to parse the attribute as an identifier return self._parse_identifier(attribute) # putting all the types in to a tuple: if not isinstance(attribute_types, collections.Iterable): attribute_types = (attribute_types,) # attempt to find an existing record having the same identifier if any(map(lambda x: issubclass(x, ProvRecord), attribute_types)): record = self._parse_record(attribute, attribute_types) if record: return record # Try to parse it with known datatype parsers for datatype in attribute_types: data = parse_datatype(attribute, datatype) if data is not None: return data return None def _validate_attribute(self, attribute, attribute_types): if isinstance(attribute, attribute_types): # The attribute is of a required type # Return it if isinstance(attribute, ProvRecord) and attribute._identifier in self._bundle._id_map: return self._bundle._id_map[attribute._identifier] else: return attribute else: # The attribute is not of a valid type if isinstance(attribute, ProvRecord): # It is definitely not valid since no further parsing is possible raise ProvExceptionNotValidAttribute(self.get_type(), attribute, attribute_types) # Attempt to parse it parsed_value = self._parse_attribute(attribute, attribute_types) if parsed_value is None: raise ProvExceptionNotValidAttribute(self.get_type(), attribute, attribute_types) return parsed_value def required_attribute(self, attributes, attribute_id, attribute_types): if attribute_id not in attributes: # Raise an exception about the missing attribute raise ProvExceptionMissingRequiredAttribute(self.get_type(), attribute_id) # Found the required attribute attribute = attributes.get(attribute_id) return self._validate_attribute(attribute, attribute_types) def optional_attribute(self, attributes, attribute_id, attribute_types): if not attributes or attribute_id not in attributes: # Because this is optional, return nothing return None # Found the optional attribute attribute = attributes.get(attribute_id) if attribute is None: return None # Validate its type return self._validate_attribute(attribute, attribute_types) def __eq__(self, other): if self.get_prov_type() != other.get_prov_type(): return False if self._identifier and not (self._identifier == other._identifier): return False if self._asserted != other._asserted: return False if self._attributes and other._attributes: if len(self._attributes) != len(other._attributes): return False for attr, value_a in self._attributes.items(): value_b = other._attributes[attr] if isinstance(value_a, ProvRecord) and value_a._identifier: if not (value_a._identifier == value_b._identifier): return False elif not (value_a == value_b): return False elif other._attributes and not self._attributes: other_attrs = [(key, value) for key, value in other._attributes.items() if value is not None] if other_attrs: # the other's attributes set is not empty. return False elif self._attributes and not other._attributes: my_attrs = [(key, value) for key, value in self._attributes.items() if value is not None] if my_attrs: # my attributes set is not empty. return False sattr = sorted(self._extra_attributes, key=_normalise_attributes) if self._extra_attributes else None oattr = sorted(other._extra_attributes, key=_normalise_attributes) if other._extra_attributes else None if sattr != oattr: if logger.isEnabledFor(logging.DEBUG): for spair, opair in zip(sattr, oattr): # Log the first unequal pair of attributes if spair != opair: logger.debug("Equality (ProvRecord): unequal attribute-value pairs - %s = %s - %s = %s", spair[0], spair[1], opair[0], opair[1]) break return False return True def __unicode__(self): return self.get_provn() def __str__(self): return unicode(self).encode('utf-8') def get_provn(self, _indent_level=0): items = [] if self._identifier: items.append(unicode(self._identifier)) if self._attributes: for (attr, value) in self._attributes.items(): if value is None: items.append(u'-') else: if isinstance(value, ProvRecord): record_id = value.get_identifier() items.append(unicode(record_id)) else: # Assuming this is a datetime or QName value items.append(value.isoformat() if isinstance(value, datetime.datetime) else unicode(value)) if self._extra_attributes: extra = [] for (attr, value) in self._extra_attributes: try: # try if there is a prov-n representation defined provn_represenation = value.provn_representation() except: provn_represenation = encoding_PROV_N_value(value) extra.append(u'%s=%s' % (unicode(attr), provn_represenation)) if extra: items.append(u'[%s]' % u', '.join(extra)) prov_n = u'%s(%s)' % (PROV_N_MAP[self.get_type()], u', '.join(items)) return prov_n if self._asserted else u'// ' + prov_n def rdf(self, graph=None, subj=None): if graph is None: graph = Graph() if subj is None: # this method need a subject as relations may not have identifiers return graph if self._attributes: for (attr, value) in self._attributes.items(): if value is None: continue pred = attr2rdf(attr) try: # try if there is a RDF representation defined obj = value.rdf_representation() except: obj = RDFLiteral(value) graph.add((subj, pred, obj)) if self._extra_attributes: for (attr, value) in self._extra_attributes: try: # try if there is a RDF representation defined obj = value.rdf_representation() except Exception, e: obj = RDFLiteral(value) if attr == PROV['location']: pred = PROV['atLocation'].rdf_representation() if isinstance(value, (URIRef, QName)): if isinstance(value, QName): value = URIRef(value.get_uri()) graph.add((subj, pred, value)) graph.add((value, RDF.type, PROV['Location'].rdf_representation())) else: graph.add((subj, pred, obj)) continue if attr == PROV['type']: pred = RDF.type elif attr == PROV['label']: pred = RDFS.label else: pred = attr.rdf_representation() graph.add((subj, pred, obj)) return graph def is_asserted(self): return self._asserted def is_element(self): return False def is_relation(self): return False # Abstract classes for elements and relations class ProvElement(ProvRecord): def is_element(self): return True def rdf(self, graph=None): if graph is None: graph = Graph() uri = self.get_identifier().rdf_representation() type_uri = self.get_prov_type().rdf_representation() graph.add((uri, RDF.type, type_uri)) ProvRecord.rdf(self, graph, uri) return graph class ProvRelation(ProvRecord): def is_relation(self): return True def rdf(self, graph=None): if graph is None: graph = Graph() pred = PROV[PROV_N_MAP[self.get_type()]].rdf_representation() items = [] subj=None obj=None for idx, (attr, value) in enumerate(self._attributes.items()): if idx == 0: subj = value.get_identifier().rdf_representation() elif idx == 1: if value: obj = value.get_identifier().rdf_representation() items.append((attr2rdf(attr), obj)) elif value: try: # try if there is a RDF representation defined otherobj = value.rdf_representation() except: otherobj = RDFLiteral(value) items.append((attr2rdf(attr), otherobj)) if subj and obj: graph.add((subj, pred, obj)) if self._extra_attributes: for (attr, value) in self._extra_attributes: if not value: continue if attr == PROV['type']: pred = RDF.type elif attr == PROV['label']: pred = RDFS.label else: pred = attr.rdf_representation() try: # try if there is a RDF representation defined otherobj = value.rdf_representation() except: otherobj = RDFLiteral(value) items.append((pred, otherobj)) if obj and len(items) == 1: items = [] if items: QRole = PROV['qualified' + str(self.get_prov_type()).split('prov:')[1]].rdf_representation() bnode = BNode() graph.add((subj, QRole, bnode)) graph.add((bnode, RDF.type, self.get_prov_type().rdf_representation())) for attr, value in items: graph.add((bnode, attr, value)) return graph # ## Component 1: Entities and Activities class ProvEntity(ProvElement): def get_type(self): return PROV_REC_ENTITY def get_prov_type(self): return PROV['Entity'] class ProvActivity(ProvElement): def get_type(self): return PROV_REC_ACTIVITY def get_prov_type(self): return PROV['Activity'] def add_attributes(self, attributes, extra_attributes): startTime = self.optional_attribute(attributes, PROV_ATTR_STARTTIME, datetime.datetime) endTime = self.optional_attribute(attributes, PROV_ATTR_ENDTIME, datetime.datetime) if startTime and endTime and startTime > endTime: raise ValueError('StartTime %s > EndTime %s' % (startTime, endTime)) attributes = OrderedDict() attributes[PROV_ATTR_STARTTIME] = startTime attributes[PROV_ATTR_ENDTIME] = endTime ProvElement.add_attributes(self, attributes, extra_attributes) # Convenient methods def set_time(self, startTime=None, endTime=None): # The _attributes dict should have been initialised if startTime is not None: self._attributes[PROV_ATTR_STARTTIME] = startTime if endTime is not None: self._attributes[PROV_ATTR_ENDTIME] = endTime def get_startTime(self): return self._attributes[PROV_ATTR_STARTTIME] def get_endTime(self): return self._attributes[PROV_ATTR_ENDTIME] class ProvGeneration(ProvRelation): def get_type(self): return PROV_REC_GENERATION def get_prov_type(self): return PROV['Generation'] def add_attributes(self, attributes, extra_attributes): # Required attributes entity = self.required_attribute(attributes, PROV_ATTR_ENTITY, (ProvEntity, ProvAgent)) # Optional attributes activity = self.optional_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) time = self.optional_attribute(attributes, PROV_ATTR_TIME, datetime.datetime) attributes = OrderedDict() attributes[PROV_ATTR_ENTITY] = entity attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_TIME] = time ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvUsage(ProvRelation): def get_type(self): return PROV_REC_USAGE def get_prov_type(self): return PROV['Usage'] def add_attributes(self, attributes, extra_attributes): # Required attributes activity = self.required_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) # Optional attributes entity = self.optional_attribute(attributes, PROV_ATTR_ENTITY, (ProvEntity, ProvAgent)) time = self.optional_attribute(attributes, PROV_ATTR_TIME, datetime.datetime) attributes = OrderedDict() attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_ENTITY] = entity attributes[PROV_ATTR_TIME] = time ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvCommunication(ProvRelation): def get_type(self): return PROV_REC_COMMUNICATION def get_prov_type(self): return PROV['Communication'] def add_attributes(self, attributes, extra_attributes): # Required attributes informed = self.required_attribute(attributes, PROV_ATTR_INFORMED, ProvActivity) informant = self.required_attribute(attributes, PROV_ATTR_INFORMANT, ProvActivity) attributes = OrderedDict() attributes[PROV_ATTR_INFORMED] = informed attributes[PROV_ATTR_INFORMANT] = informant ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvStart(ProvRelation): def get_type(self): return PROV_REC_START def get_prov_type(self): return PROV['Start'] def add_attributes(self, attributes, extra_attributes): # Required attributes activity = self.required_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) # Optional attributes trigger = self.optional_attribute(attributes, PROV_ATTR_TRIGGER, (ProvEntity, ProvAgent)) starter = self.optional_attribute(attributes, PROV_ATTR_STARTER, ProvActivity) time = self.optional_attribute(attributes, PROV_ATTR_TIME, datetime.datetime) attributes = OrderedDict() attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_TRIGGER] = trigger attributes[PROV_ATTR_STARTER] = starter attributes[PROV_ATTR_TIME] = time ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvEnd(ProvRelation): def get_type(self): return PROV_REC_END def get_prov_type(self): return PROV['End'] def add_attributes(self, attributes, extra_attributes): # Required attributes activity = self.required_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) # Optional attributes trigger = self.optional_attribute(attributes, PROV_ATTR_TRIGGER, (ProvEntity, ProvAgent)) ender = self.optional_attribute(attributes, PROV_ATTR_ENDER, ProvActivity) time = self.optional_attribute(attributes, PROV_ATTR_TIME, datetime.datetime) attributes = OrderedDict() attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_TRIGGER] = trigger attributes[PROV_ATTR_ENDER] = ender attributes[PROV_ATTR_TIME] = time ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvInvalidation(ProvRelation): def get_type(self): return PROV_REC_INVALIDATION def get_prov_type(self): return PROV['Invalidation'] def add_attributes(self, attributes, extra_attributes): # Required attributes entity = self.required_attribute(attributes, PROV_ATTR_ENTITY, (ProvEntity, ProvAgent)) # Optional attributes activity = self.optional_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) time = self.optional_attribute(attributes, PROV_ATTR_TIME, datetime.datetime) attributes = OrderedDict() attributes[PROV_ATTR_ENTITY] = entity attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_TIME] = time ProvRelation.add_attributes(self, attributes, extra_attributes) # ## Component 2: Derivations class ProvDerivation(ProvRelation): def get_type(self): return PROV_REC_DERIVATION def get_prov_type(self): return PROV['Derivation'] def add_attributes(self, attributes, extra_attributes): # Required attributes generatedEntity = self.required_attribute(attributes, PROV_ATTR_GENERATED_ENTITY, (ProvEntity, ProvAgent)) usedEntity = self.required_attribute(attributes, PROV_ATTR_USED_ENTITY, (ProvEntity, ProvAgent)) # Optional attributes activity = self.optional_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) generation = self.optional_attribute(attributes, PROV_ATTR_GENERATION, ProvGeneration) usage = self.optional_attribute(attributes, PROV_ATTR_USAGE, ProvUsage) attributes = OrderedDict() attributes[PROV_ATTR_GENERATED_ENTITY] = generatedEntity attributes[PROV_ATTR_USED_ENTITY] = usedEntity attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_GENERATION] = generation attributes[PROV_ATTR_USAGE] = usage ProvRelation.add_attributes(self, attributes, extra_attributes) # ## Component 3: Agents, Responsibility, and Influence class ProvAgent(ProvElement): def get_type(self): return PROV_REC_AGENT def get_prov_type(self): return PROV['Agent'] class ProvAttribution(ProvRelation): def get_type(self): return PROV_REC_ATTRIBUTION def get_prov_type(self): return PROV['Attribution'] def add_attributes(self, attributes, extra_attributes): # Required attributes entity = self.required_attribute(attributes, PROV_ATTR_ENTITY, (ProvEntity, ProvAgent)) agent = self.required_attribute(attributes, PROV_ATTR_AGENT, (ProvAgent, ProvEntity)) attributes = OrderedDict() attributes[PROV_ATTR_ENTITY] = entity attributes[PROV_ATTR_AGENT] = agent ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvAssociation(ProvRelation): def get_type(self): return PROV_REC_ASSOCIATION def get_prov_type(self): return PROV['Association'] def add_attributes(self, attributes, extra_attributes): # Required attributes activity = self.required_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) # Optional attributes agent = self.optional_attribute(attributes, PROV_ATTR_AGENT, (ProvAgent, ProvEntity)) plan = self.optional_attribute(attributes, PROV_ATTR_PLAN, (ProvEntity, ProvAgent)) attributes = OrderedDict() attributes[PROV_ATTR_ACTIVITY] = activity attributes[PROV_ATTR_AGENT] = agent attributes[PROV_ATTR_PLAN] = plan ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvDelegation(ProvRelation): def get_type(self): return PROV_REC_DELEGATION def get_prov_type(self): return PROV['Delegation'] def add_attributes(self, attributes, extra_attributes): # Required attributes delegate = self.required_attribute(attributes, PROV_ATTR_DELEGATE, (ProvAgent, ProvEntity)) responsible = self.required_attribute(attributes, PROV_ATTR_RESPONSIBLE, (ProvAgent, ProvEntity)) # Optional attributes activity = self.optional_attribute(attributes, PROV_ATTR_ACTIVITY, ProvActivity) attributes = OrderedDict() attributes[PROV_ATTR_DELEGATE] = delegate attributes[PROV_ATTR_RESPONSIBLE] = responsible attributes[PROV_ATTR_ACTIVITY] = activity ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvInfluence(ProvRelation): def get_type(self): return PROV_REC_INFLUENCE def get_prov_type(self): return PROV['Influence'] def add_attributes(self, attributes, extra_attributes): # Required attributes influencee = self.required_attribute(attributes, PROV_ATTR_INFLUENCEE, (ProvEntity, ProvActivity, ProvAgent)) influencer = self.required_attribute(attributes, PROV_ATTR_INFLUENCER, (ProvAgent, ProvEntity, ProvActivity)) attributes = OrderedDict() attributes[PROV_ATTR_INFLUENCEE] = influencee attributes[PROV_ATTR_INFLUENCER] = influencer ProvRelation.add_attributes(self, attributes, extra_attributes) # ## Component 4: Bundles # See below # ## Component 5: Alternate Entities class ProvSpecialization(ProvRelation): def get_type(self): return PROV_REC_SPECIALIZATION def get_prov_type(self): return PROV['Specialization'] def add_attributes(self, attributes, extra_attributes): # Required attributes specificEntity = self.required_attribute(attributes, PROV_ATTR_SPECIFIC_ENTITY, (ProvEntity, ProvAgent)) generalEntity = self.required_attribute(attributes, PROV_ATTR_GENERAL_ENTITY, (ProvEntity, ProvAgent)) attributes = OrderedDict() attributes[PROV_ATTR_SPECIFIC_ENTITY] = specificEntity attributes[PROV_ATTR_GENERAL_ENTITY] = generalEntity ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvAlternate(ProvRelation): def get_type(self): return PROV_REC_ALTERNATE def get_prov_type(self): return PROV['Alternate'] def add_attributes(self, attributes, extra_attributes): # Required attributes alternate1 = self.required_attribute(attributes, PROV_ATTR_ALTERNATE1, (ProvEntity, ProvAgent)) alternate2 = self.required_attribute(attributes, PROV_ATTR_ALTERNATE2, (ProvEntity, ProvAgent)) attributes = OrderedDict() attributes[PROV_ATTR_ALTERNATE1] = alternate1 attributes[PROV_ATTR_ALTERNATE2] = alternate2 ProvRelation.add_attributes(self, attributes, extra_attributes) class ProvMention(ProvSpecialization): def get_type(self): return PROV_REC_MENTION def get_prov_type(self): return PROV['Mention'] def add_attributes(self, attributes, extra_attributes): # Required attributes specificEntity = self.required_attribute(attributes, PROV_ATTR_SPECIFIC_ENTITY, (ProvEntity, ProvAgent)) generalEntity = self.required_attribute(attributes, PROV_ATTR_GENERAL_ENTITY, Identifier) bundle = self.required_attribute(attributes, PROV_ATTR_BUNDLE, Identifier) #======================================================================= # # This is disabled so that mentionOf can refer to bundle that is not defined in the same place # bundle = self.required_attribute(attributes, PROV_ATTR_BUNDLE, ProvBundle) # # Check if generalEntity is in the bundle # if generalEntity.get_bundle() is not bundle: # raise ProvExceptionContraint(PROV_REC_MENTION, generalEntity, bundle, 'The generalEntity must belong to the bundle') #======================================================================= attributes = OrderedDict() attributes[PROV_ATTR_SPECIFIC_ENTITY] = specificEntity attributes[PROV_ATTR_GENERAL_ENTITY] = generalEntity attributes[PROV_ATTR_BUNDLE] = bundle ProvRelation.add_attributes(self, attributes, extra_attributes) # ## Component 6: Collections class ProvMembership(ProvRelation): def get_type(self): return PROV_REC_MEMBERSHIP def get_prov_type(self): return PROV['Membership'] def add_attributes(self, attributes, extra_attributes): # Required attributes collection = self.required_attribute(attributes, PROV_ATTR_COLLECTION, (ProvEntity, ProvAgent)) entity = self.required_attribute(attributes, PROV_ATTR_ENTITY, (ProvEntity, ProvAgent)) attributes = OrderedDict() attributes[PROV_ATTR_COLLECTION] = collection attributes[PROV_ATTR_ENTITY] = entity ProvRelation.add_attributes(self, attributes, extra_attributes) # Class mappings from PROV record type PROV_REC_CLS = { PROV_REC_ENTITY : ProvEntity, PROV_REC_ACTIVITY : ProvActivity, PROV_REC_GENERATION : ProvGeneration, PROV_REC_USAGE : ProvUsage, PROV_REC_COMMUNICATION : ProvCommunication, PROV_REC_START : ProvStart, PROV_REC_END : ProvEnd, PROV_REC_INVALIDATION : ProvInvalidation, PROV_REC_DERIVATION : ProvDerivation, PROV_REC_AGENT : ProvAgent, PROV_REC_ATTRIBUTION : ProvAttribution, PROV_REC_ASSOCIATION : ProvAssociation, PROV_REC_DELEGATION : ProvDelegation, PROV_REC_INFLUENCE : ProvInfluence, PROV_REC_SPECIALIZATION : ProvSpecialization, PROV_REC_ALTERNATE : ProvAlternate, PROV_REC_MENTION : ProvMention, PROV_REC_MEMBERSHIP : ProvMembership, } # Bundle class NamespaceManager(dict): def __init__(self, namespaces={}, default_namespaces={PROV.get_prefix(): PROV, XSD.get_prefix(): XSD}, default=None, parent=None): self._default_namespaces = {} self._default_namespaces.update(default_namespaces) self.update(self._default_namespaces) self._namespaces = {} if default is not None: self.set_default_namespace(default) else: self._default = None self.parent = parent # TODO check if default is in the default namespaces self._anon_id_count = 0 self._rename_map = {} self.add_namespaces(namespaces) def get_namespace(self, uri): for namespace in self.values(): if uri == namespace._uri: return namespace return None def get_registered_namespaces(self): return self._namespaces.values() def set_default_namespace(self, uri): self._default = Namespace('', uri) self[''] = self._default def get_default_namespace(self): return self._default def add_namespace(self, namespace): if namespace in self.values(): # no need to do anything return if namespace in self._rename_map: # already renamed and added return prefix = namespace.get_prefix() if prefix in self: # Conflicting prefix new_prefix = self._get_unused_prefix(prefix) new_namespace = Namespace(new_prefix, namespace.get_uri()) self._rename_map[namespace] = new_namespace prefix = new_prefix namespace = new_namespace self._namespaces[prefix] = namespace self[prefix] = namespace return namespace def add_namespaces(self, namespaces): if namespaces: for prefix, uri in namespaces.items(): ns = Namespace(prefix, uri) self.add_namespace(ns) def get_valid_identifier(self, identifier): if not identifier: return None if isinstance(identifier, Identifier): if isinstance(identifier, QName): # Register the namespace if it has not been registered before namespace = identifier._namespace prefix = namespace.get_prefix() if prefix in self and self[prefix] == namespace: # No need to add the namespace existing_ns = self[prefix] if existing_ns is namespace: return identifier else: return existing_ns[identifier._localpart] # reuse the existing namespace else: ns = self.add_namespace(deepcopy(namespace)) # Do not reuse the namespace object return ns[identifier._localpart] else: # return the original identifier return identifier elif isinstance(identifier, (str, unicode)): if identifier.startswith('_:'): return None elif ':' in identifier: # check if the identifier contains a registered prefix prefix, local_part = identifier.split(':', 1) if prefix in self: # return a new QName return self[prefix][local_part] else: # treat as a URI (with the first part as its scheme) # check if the URI can be compacted for namespace in self.values(): if identifier.startswith(namespace.get_uri()): # create a QName with the namespace return namespace[identifier.replace(namespace.get_uri(), '')] if self.parent is not None: # try the parent namespace manager return self.parent.get_valid_identifier(identifier) else: # return an Identifier with the given URI return Identifier(identifier) elif self._default: # create and return an identifier in the default namespace return self._default[identifier] else: # This is not an identifier return None def get_anonymous_identifier(self, local_prefix='id'): self._anon_id_count += 1 return Identifier('_:%s%d' % (local_prefix, self._anon_id_count)) def _get_unused_prefix(self, original_prefix): if original_prefix not in self: return original_prefix count = 1 while True: new_prefix = '_'.join((original_prefix, unicode(count))) if new_prefix in self: count += 1 else: return new_prefix class ProvBundle(ProvEntity): def __init__(self, bundle=None, identifier=None, attributes=None, other_attributes=None, asserted=True, namespaces={}): # Initializing bundle-specific attributes self._records = list() self._id_map = dict() self._bundles = dict() self._namespaces = NamespaceManager(namespaces, parent=(bundle._namespaces if bundle is not None else None)) # Initializing record-specific attributes super(ProvBundle, self).__init__(bundle, identifier, attributes, other_attributes, asserted) # Bundle configurations def set_default_namespace(self, uri): self._namespaces.set_default_namespace(uri) def get_default_namespace(self): return self._namespaces.get_default_namespace() def add_namespace(self, namespace_or_prefix, uri=None): if uri is None: self._namespaces.add_namespace(namespace_or_prefix) else: self._namespaces.add_namespace(Namespace(namespace_or_prefix, uri)) def get_registered_namespaces(self): return self._namespaces.get_registered_namespaces() def valid_identifier(self, identifier): return self._namespaces.get_valid_identifier(identifier) def get_anon_id(self, record): # TODO Implement a dict of self-generated anon ids for records without identifier return self._namespaces.get_anonymous_identifier() def get_records(self, class_or_type_or_tuple=None): # Only returning asserted records results = [rec for rec in self._records if rec.is_asserted()] if class_or_type_or_tuple: return filter(lambda rec: isinstance(rec, class_or_type_or_tuple), results) else: return results def get_record(self, identifier): if identifier is None: return None valid_id = self.valid_identifier(identifier) try: return self._id_map[valid_id] except: # looking up the parent bundle if self._bundle is not None: return self._bundle.get_record(valid_id) else: return None def get_bundle(self, identifier): try: valid_id = self.valid_identifier(identifier) return self._bundles[valid_id] except: # looking up the parent bundle if self._bundle is not None: return self._bundle.get_bundle(valid_id) else: return None # PROV-JSON serialization/deserialization class JSONEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, ProvBundle): return o._encode_JSON_container() else: # Use the default encoder instead return json.JSONEncoder.default(self, o) class JSONDecoder(json.JSONDecoder): def decode(self, s): json_container = json.JSONDecoder.decode(self, s) result = ProvBundle() result._decode_JSON_container(json_container) return result def _encode_json_representation(self, value): try: return value.json_representation() except AttributeError: if isinstance(value, datetime.datetime): return {'$': value.isoformat(), 'type': u'xsd:dateTime'} else: return value def _decode_json_representation(self, literal): if isinstance(literal, dict): # complex type value = literal['$'] datatype = literal['type'] if 'type' in literal else None langtag = literal['lang'] if 'lang' in literal else None if datatype == u'xsd:anyURI': return Identifier(value) elif datatype == u'xsd:QName': return self.valid_identifier(value) else: # The literal of standard Python types is not converted here # It will be automatically converted when added to a record by _auto_literal_conversion() return Literal(value, self.valid_identifier(datatype), langtag) else: # simple type, just return it return literal def _encode_JSON_container(self): container = defaultdict(dict) if self._bundle is None: # This is a document prefixes = {} for namespace in self._namespaces.get_registered_namespaces(): prefixes[namespace.get_prefix()] = namespace.get_uri() if self._namespaces._default: prefixes['default'] = self._namespaces._default.get_uri() if prefixes: container[u'prefix'] = prefixes id_generator = AnonymousIDGenerator() real_or_anon_id = lambda record: record._identifier if record._identifier else id_generator.get_anon_id(record) for record in self._records: if not record.is_asserted(): continue # skipping inferred records rec_type = record.get_type() rec_label = PROV_N_MAP[rec_type] identifier = unicode(real_or_anon_id(record)) if rec_type == PROV_REC_BUNDLE: # encoding the sub-bundle record_json = record._encode_JSON_container() else: record_json = {} if record._attributes: for (attr, value) in record._attributes.items(): if isinstance(value, ProvRecord): attr_record_id = real_or_anon_id(value) record_json[PROV_ID_ATTRIBUTES_MAP[attr]] = unicode(attr_record_id) elif value is not None: # Assuming this is a datetime value record_json[PROV_ID_ATTRIBUTES_MAP[attr]] = value.isoformat() if isinstance(value, datetime.datetime) else unicode(value) if record._extra_attributes: for (attr, value) in record._extra_attributes: attr_id = unicode(attr) value_json = self._encode_json_representation(value) if attr_id in record_json: # Multi-value attribute existing_value = record_json[attr_id] try: # Add the value to the current list of values existing_value.append(value_json) except: # But if the existing value is not a list, it'll fail # create the list for the existing value and the second value record_json[attr_id] = [existing_value, value_json] else: record_json[attr_id] = value_json container[rec_label][identifier] = record_json return container def _decode_JSON_container(self, jc): if u'prefix' in jc: prefixes = jc[u'prefix'] for prefix, uri in prefixes.items(): if prefix != 'default': self.add_namespace(Namespace(prefix, uri)) else: self.set_default_namespace(uri) records = sorted([(PROV_RECORD_IDS_MAP[rec_type], rec_id, jc[rec_type][rec_id]) for rec_type in jc if rec_type != u'prefix' for rec_id in jc[rec_type]], key=lambda tuple_rec: tuple_rec[0]) record_map = {} _parse_attr_value = lambda value: record_map[value] if (isinstance(value, six.string_types) and value in record_map) else self._decode_json_representation(value) # Create all the records before setting their attributes for (record_type, identifier, content) in records: if record_type == PROV_REC_BUNDLE: bundle = self.bundle(identifier) bundle._decode_JSON_container(content) else: record_map[identifier] = self.add_record(record_type, identifier, None, None) for (record_type, identifier, attributes) in records: if record_type != PROV_REC_BUNDLE: record = record_map[identifier] if hasattr(attributes, 'items'): # it is a dict # There is only one element, create a singleton list elements = [attributes] else: # expect it to be a list of dictionaries elements = attributes for element in elements: prov_attributes = {} extra_attributes = [] # Splitting PROV attributes and the others membership_extra_members = None # this is for the multiple-entity membership hack to come for attr, value in element.items(): if attr in PROV_ATTRIBUTES_ID_MAP: attr_id = PROV_ATTRIBUTES_ID_MAP[attr] if isinstance(value, list): # Multiple values if len(value) == 1: # Only a single value in the list, unpack it value = value[0] else: if record.get_type() == PROV_REC_MEMBERSHIP and attr_id == PROV_ATTR_ENTITY: # This is a membership relation with multiple entities # HACK: create multiple membership relations, one for each entity membership_extra_members = value[1:] # Store all the extra entities value = value[0] # Create the first membership relation as normal for the first entity else: error_msg = 'The prov package does not support PROV attributes having multiple values.' logger.error(error_msg) raise ProvException(error_msg) prov_attributes[attr_id] = _parse_attr_value(value) else: attr_id = self.valid_identifier(attr) if isinstance(value, list): # Parsing multi-value attribute extra_attributes.extend((attr_id, self._decode_json_representation(value_single)) for value_single in value) else: # add the single-value attribute extra_attributes.append((attr_id, self._decode_json_representation(value))) record.add_attributes(prov_attributes, extra_attributes) # HACK: creating extra (unidentified) membership relations if membership_extra_members: collection = prov_attributes[PROV_ATTR_COLLECTION] for member in membership_extra_members: self.membership(collection, _parse_attr_value(member), None, extra_attributes) # Miscellaneous functions def is_document(self): return self._bundle is None def is_bundle(self): return self._bundle is not None def get_type(self): return PROV_REC_BUNDLE def get_provn(self, _indent_level=0, asserted_only=True): indentation = '' + (' ' * _indent_level) newline = '\n' + (' ' * (_indent_level + 1)) # if this is the document, start the document; otherwise, start the bundle records = ['document'] if self._bundle is None else ['bundle %s' % self._identifier] if self._bundle is None: # Only output the namespaces of a document default_namespace = self._namespaces.get_default_namespace() if default_namespace: records.append('default <%s>' % default_namespace.get_uri()) registered_namespaces = self._namespaces.get_registered_namespaces() if registered_namespaces: records.extend(['prefix %s <%s>' % (namespace.get_prefix(), namespace.get_uri()) for namespace in registered_namespaces]) if default_namespace or registered_namespaces: # a blank line between the prefixes and the assertions records.append('') # adding all the records records.extend([record.get_provn(_indent_level + 1) for record in self._records if record.is_asserted() or not asserted_only]) provn_str = newline.join(records) + '\n' # closing the structure provn_str += indentation + ('endDocument' if self._bundle is None else 'endBundle') return provn_str def rdf(self, graph=None): if self._bundle is None: # top bundle if graph is None: graph = ConjunctiveGraph() else: # graph should not None here uri = self.get_identifier().rdf_representation() graph = Graph(graph.store, uri) for prefix, namespace in self._namespaces.items(): graph.bind(prefix, namespace.get_uri()) for record in self._records: if record.is_asserted(): record.rdf(graph) return graph def get_provjson(self, **kw): """Return the `PROV-JSON `_ representation for the bundle/document. Parameters for `json.dumps `_ like `indent=4` can be also passed as keyword arguments. """ # Prevent overwriting the encoder class if 'cls' in kw: del kw['cls'] json_content = json.dumps(self, cls=ProvBundle.JSONEncoder, **kw) return json_content @staticmethod def from_provjson(json_content, **kw): """Construct the bundle/document from the given `PROV-JSON `_ representation. Parameters for `json.loads `_ can be also passed as keyword arguments. """ # Prevent overwriting the decoder class if 'cls' in kw: del kw['cls'] return json.loads(json_content, cls=ProvBundle.JSONDecoder, **kw) def get_flattened(self): namespaces = dict((ns.get_prefix(), ns.get_uri()) for ns in self.get_registered_namespaces()) document = ProvBundle(namespaces=namespaces) default_ns_uri = self.get_default_namespace() if default_ns_uri is not None: document.set_default_namespace(default_ns_uri) # Enumerate records and bundles bundles = [] records = [] for record in self.get_records(): if isinstance(record, ProvBundle): bundles.append(record) else: records.append(record) records = deepcopy(records) for record in records: document._add_record(record) for bundle in bundles: for record in bundle._records: document.add_record(record.get_type(), copy(record._identifier), deepcopy(record._attributes), deepcopy(record._extra_attributes), record._asserted) return document def __eq__(self, other): if not isinstance(other, ProvBundle): return False other_records = set(other.get_records()) this_records = set(self.get_records()) if len(this_records) != len(other_records): return False # check if all records for equality for record_a in this_records: if record_a._identifier: if record_a.get_type() == PROV_REC_BUNDLE: record_b = other.get_bundle(record_a._identifier) else: record_b = other.get_record(record_a._identifier) if record_b: if record_a == record_b: other_records.remove(record_b) continue else: logger.debug("Equality (ProvBundle): Unequal PROV records:") logger.debug("%s", unicode(record_a)) logger.debug("%s", unicode(record_b)) return False else: logger.debug("Equality (ProvBundle): Could not find a record with this identifier: %s", unicode(record_a._identifier)) return False else: # Manually look for the record found = False for record_b in other_records: if record_a == record_b: other_records.remove(record_b) found = True break if not found: logger.debug("Equality (ProvBundle): Could not find this record: %s", unicode(record_a)) return False return True # Provenance statements def _add_record(self, record): if record._identifier: if record.get_type() == PROV_REC_BUNDLE: # Don't mix bunle ids with normal record ids. self._bundles[record._identifier] = record self._records.append(record) else: if record._identifier in self._id_map: merge_target = self._id_map[record._identifier] if not merge_target._asserted and record._asserted: if record.__class__ in merge_target.get_allowed_types(): for attribute_id, attribute in merge_target._infered_for._attributes.iteritems(): if attribute == merge_target: merge_target._infered_for._attributes[attribute_id] = record self._records.remove(merge_target) self._id_map[record._identifier] = record self._records.append(record) else: raise ProvExceptionCannotUnifyAttribute(record._identifier, merge_target.get_type(), record.get_type()) else: if record.get_type() != merge_target.get_type(): raise ProvExceptionCannotUnifyAttribute(record._identifier, merge_target.get_type(), record.get_type()) merge_target.add_attributes(record._attributes, record._extra_attributes) else: self._records.append(record) self._id_map[record._identifier] = record else: self._records.append(record) def add_record(self, record_type, identifier, attributes=None, other_attributes=None, asserted=True): new_record = PROV_REC_CLS[record_type](self, self.valid_identifier(identifier), attributes, other_attributes, asserted) self._add_record(new_record) return new_record def add_inferred_record(self, record_cls, identifier, infered_for, allowed_types): record_id = self.valid_identifier(identifier) record = record_cls(self, record_id, asserted=False, allowed_types=allowed_types, infered_for=infered_for) self._add_record(record) return record def add_bundle(self, bundle, identifier=None): '''Add a bundle to the current document ''' if identifier == None: identifier = bundle.get_identifier() if not identifier: raise ProvException(u"The added bundle has no identifier") valid_id = self.valid_identifier(identifier) bundle._identifier = valid_id if valid_id in self._bundles: raise ProvException(u"A bundle with that identifier already exists") if len(bundle._bundles) > 0: raise ProvException(u"A bundle may not contain bundles") self._bundles[valid_id] = bundle self._records.append(bundle) for namespace in bundle.get_registered_namespaces(): self.add_namespace(namespace) bundle._bundle = self def add_element(self, record_type, identifier, attributes=None, other_attributes=None): return self.add_record(record_type, identifier, attributes, other_attributes) def entity(self, identifier, other_attributes=None): return self.add_element(PROV_REC_ENTITY, identifier, None, other_attributes) def activity(self, identifier, startTime=None, endTime=None, other_attributes=None): return self.add_element(PROV_REC_ACTIVITY, identifier, {PROV_ATTR_STARTTIME: _ensure_datetime(startTime), PROV_ATTR_ENDTIME: _ensure_datetime(endTime)}, other_attributes) def generation(self, entity, activity=None, time=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_GENERATION, identifier, {PROV_ATTR_ENTITY: entity, PROV_ATTR_ACTIVITY: activity, PROV_ATTR_TIME: _ensure_datetime(time)}, other_attributes) def usage(self, activity, entity=None, time=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_USAGE, identifier, {PROV_ATTR_ACTIVITY: activity, PROV_ATTR_ENTITY: entity, PROV_ATTR_TIME: _ensure_datetime(time)}, other_attributes) def start(self, activity, trigger=None, starter=None, time=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_START, identifier, {PROV_ATTR_ACTIVITY: activity, PROV_ATTR_TRIGGER: trigger, PROV_ATTR_STARTER: starter, PROV_ATTR_TIME: _ensure_datetime(time)}, other_attributes) def end(self, activity, trigger=None, ender=None, time=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_END, identifier, {PROV_ATTR_ACTIVITY: activity, PROV_ATTR_TRIGGER: trigger, PROV_ATTR_ENDER: ender, PROV_ATTR_TIME: _ensure_datetime(time)}, other_attributes) def invalidation(self, entity, activity=None, time=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_INVALIDATION, identifier, {PROV_ATTR_ENTITY: entity, PROV_ATTR_ACTIVITY: activity, PROV_ATTR_TIME: _ensure_datetime(time)}, other_attributes) def communication(self, informed, informant, identifier=None, other_attributes=None): return self.add_record(PROV_REC_COMMUNICATION, identifier, {PROV_ATTR_INFORMED: informed, PROV_ATTR_INFORMANT: informant}, other_attributes) def agent(self, identifier, other_attributes=None): return self.add_element(PROV_REC_AGENT, identifier, None, other_attributes) def attribution(self, entity, agent, identifier=None, other_attributes=None): return self.add_record(PROV_REC_ATTRIBUTION, identifier, {PROV_ATTR_ENTITY: entity, PROV_ATTR_AGENT: agent}, other_attributes) def association(self, activity, agent=None, plan=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_ASSOCIATION, identifier, {PROV_ATTR_ACTIVITY: activity, PROV_ATTR_AGENT: agent, PROV_ATTR_PLAN: plan}, other_attributes) def delegation(self, delegate, responsible, activity=None, identifier=None, other_attributes=None): return self.add_record(PROV_REC_DELEGATION, identifier, {PROV_ATTR_DELEGATE: delegate, PROV_ATTR_RESPONSIBLE: responsible, PROV_ATTR_ACTIVITY: activity}, other_attributes) def influence(self, influencee, influencer, identifier=None, other_attributes=None): return self.add_record(PROV_REC_INFLUENCE, identifier, {PROV_ATTR_INFLUENCEE: influencee, PROV_ATTR_INFLUENCER: influencer}, other_attributes) def derivation(self, generatedEntity, usedEntity, activity=None, generation=None, usage=None, time=None, identifier=None, other_attributes=None): attributes = {PROV_ATTR_GENERATED_ENTITY: generatedEntity, PROV_ATTR_USED_ENTITY: usedEntity, PROV_ATTR_ACTIVITY: activity, PROV_ATTR_GENERATION: generation, PROV_ATTR_USAGE: usage} return self.add_record(PROV_REC_DERIVATION, identifier, attributes, other_attributes) def revision(self, generatedEntity, usedEntity, activity=None, generation=None, usage=None, time=None, identifier=None, other_attributes=None): record = self.derivation(generatedEntity, usedEntity, activity, generation, usage, time, identifier, other_attributes) record.add_asserted_type(PROV['Revision']) return record def quotation(self, generatedEntity, usedEntity, activity=None, generation=None, usage=None, time=None, identifier=None, other_attributes=None): record = self.derivation(generatedEntity, usedEntity, activity, generation, usage, time, identifier, other_attributes) record.add_asserted_type(PROV['Quotation']) return record def primary_source(self, generatedEntity, usedEntity, activity=None, generation=None, usage=None, time=None, identifier=None, other_attributes=None): record = self.derivation(generatedEntity, usedEntity, activity, generation, usage, time, identifier, other_attributes) record.add_asserted_type(PROV['PrimarySource']) return record def specialization(self, specificEntity, generalEntity, identifier=None, other_attributes=None): return self.add_record(PROV_REC_SPECIALIZATION, identifier, {PROV_ATTR_SPECIFIC_ENTITY: specificEntity, PROV_ATTR_GENERAL_ENTITY: generalEntity}, other_attributes) def alternate(self, alternate1, alternate2, identifier=None, other_attributes=None): return self.add_record(PROV_REC_ALTERNATE, identifier, {PROV_ATTR_ALTERNATE1: alternate1, PROV_ATTR_ALTERNATE2: alternate2}, other_attributes) def mention(self, specificEntity, generalEntity, bundle, identifier=None, other_attributes=None): return self.add_record(PROV_REC_MENTION, identifier, {PROV_ATTR_SPECIFIC_ENTITY: specificEntity, PROV_ATTR_GENERAL_ENTITY: generalEntity, PROV_ATTR_BUNDLE: bundle}, other_attributes) def collection(self, identifier, other_attributes=None): record = self.add_element(PROV_REC_ENTITY, identifier, None, other_attributes) record.add_asserted_type(PROV['Collection']) return record def membership(self, collection, entity, identifier=None, other_attributes=None): return self.add_record(PROV_REC_MEMBERSHIP, identifier, {PROV_ATTR_COLLECTION: collection, PROV_ATTR_ENTITY: entity}, other_attributes) def bundle(self, identifier, other_attributes=None): return self.add_element(PROV_REC_BUNDLE, identifier, None, other_attributes) # Aliases wasGeneratedBy = generation used = usage wasStartedBy = start wasEndedBy = end wasInvalidatedBy = invalidation wasInformedBy = communication wasAttributedTo = attribution wasAssociatedWith = association actedOnBehalfOf = delegation wasInfluencedBy = influence wasDerivedFrom = derivation wasRevisionOf = revision wasQuotedFrom = quotation hadPrimarySource = primary_source alternateOf = alternate specializationOf = specialization mentionOf = mention hadMember = membership # Add the newly defined ProvBundle into the PROV class dictionary PROV_REC_CLS[PROV_REC_BUNDLE] = ProvBundle nipype-0.11.0/nipype/external/six.py000066400000000000000000000653201257611314500174130ustar00rootroot00000000000000"""Utilities for writing code that runs on Python 2 and 3""" # Copyright (c) 2010-2014 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. from __future__ import absolute_import import functools import operator import sys import types __author__ = "Benjamin Peterson " __version__ = "1.8.0" # Useful for very coarse version differentiation. PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 if PY3: string_types = str, integer_types = int, class_types = type, text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: string_types = basestring, integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode binary_type = str if sys.platform.startswith("java"): # Jython always uses 32 bits. MAXSIZE = int((1 << 31) - 1) else: # It's possible to have sizeof(long) != sizeof(Py_ssize_t). class X(object): def __len__(self): return 1 << 31 try: len(X()) except OverflowError: # 32-bit MAXSIZE = int((1 << 31) - 1) else: # 64-bit MAXSIZE = int((1 << 63) - 1) del X def _add_doc(func, doc): """Add documentation to a function.""" func.__doc__ = doc def _import_module(name): """Import module, returning the module after the last dot.""" __import__(name) return sys.modules[name] class _LazyDescr(object): def __init__(self, name): self.name = name def __get__(self, obj, tp): result = self._resolve() setattr(obj, self.name, result) # Invokes __set__. # This is a bit ugly, but it avoids running this again. delattr(obj.__class__, self.name) return result class MovedModule(_LazyDescr): def __init__(self, name, old, new=None): super(MovedModule, self).__init__(name) if PY3: if new is None: new = name self.mod = new else: self.mod = old def _resolve(self): return _import_module(self.mod) def __getattr__(self, attr): _module = self._resolve() value = getattr(_module, attr) setattr(self, attr, value) return value class _LazyModule(types.ModuleType): def __init__(self, name): super(_LazyModule, self).__init__(name) self.__doc__ = self.__class__.__doc__ def __dir__(self): attrs = ["__doc__", "__name__"] attrs += [attr.name for attr in self._moved_attributes] return attrs # Subclasses should override this _moved_attributes = [] class MovedAttribute(_LazyDescr): def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): super(MovedAttribute, self).__init__(name) if PY3: if new_mod is None: new_mod = name self.mod = new_mod if new_attr is None: if old_attr is None: new_attr = name else: new_attr = old_attr self.attr = new_attr else: self.mod = old_mod if old_attr is None: old_attr = name self.attr = old_attr def _resolve(self): module = _import_module(self.mod) return getattr(module, self.attr) class _SixMetaPathImporter(object): """ A meta path importer to import six.moves and its submodules. This class implements a PEP302 finder and loader. It should be compatible with Python 2.5 and all existing versions of Python3 """ def __init__(self, six_module_name): self.name = six_module_name self.known_modules = {} def _add_module(self, mod, *fullnames): for fullname in fullnames: self.known_modules[self.name + "." + fullname] = mod def _get_module(self, fullname): return self.known_modules[self.name + "." + fullname] def find_module(self, fullname, path=None): if fullname in self.known_modules: return self return None def __get_module(self, fullname): try: return self.known_modules[fullname] except KeyError: raise ImportError("This loader does not know module " + fullname) def load_module(self, fullname): try: # in case of a reload return sys.modules[fullname] except KeyError: pass mod = self.__get_module(fullname) if isinstance(mod, MovedModule): mod = mod._resolve() else: mod.__loader__ = self sys.modules[fullname] = mod return mod def is_package(self, fullname): """ Return true, if the named module is a package. We need this method to get correct spec objects with Python 3.4 (see PEP451) """ return hasattr(self.__get_module(fullname), "__path__") def get_code(self, fullname): """Return None Required, if is_package is implemented""" self.__get_module(fullname) # eventually raises ImportError return None get_source = get_code # same as get_code _importer = _SixMetaPathImporter(__name__) class _MovedItems(_LazyModule): """Lazy loading of moved objects""" __path__ = [] # mark as package _moved_attributes = [ MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), MovedAttribute("intern", "__builtin__", "sys"), MovedAttribute("map", "itertools", "builtins", "imap", "map"), MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("reload_module", "__builtin__", "imp", "reload"), MovedAttribute("reduce", "__builtin__", "functools"), MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), MovedAttribute("StringIO", "StringIO", "io"), MovedAttribute("UserDict", "UserDict", "collections"), MovedAttribute("UserList", "UserList", "collections"), MovedAttribute("UserString", "UserString", "collections"), MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), MovedModule("builtins", "__builtin__"), MovedModule("configparser", "ConfigParser"), MovedModule("copyreg", "copy_reg"), MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), MovedModule("http_cookies", "Cookie", "http.cookies"), MovedModule("html_entities", "htmlentitydefs", "html.entities"), MovedModule("html_parser", "HTMLParser", "html.parser"), MovedModule("http_client", "httplib", "http.client"), MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), MovedModule("cPickle", "cPickle", "pickle"), MovedModule("queue", "Queue"), MovedModule("reprlib", "repr"), MovedModule("socketserver", "SocketServer"), MovedModule("_thread", "thread", "_thread"), MovedModule("tkinter", "Tkinter"), MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), MovedModule("tkinter_tix", "Tix", "tkinter.tix"), MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), MovedModule("tkinter_colorchooser", "tkColorChooser", "tkinter.colorchooser"), MovedModule("tkinter_commondialog", "tkCommonDialog", "tkinter.commondialog"), MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), MovedModule("tkinter_font", "tkFont", "tkinter.font"), MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", "tkinter.simpledialog"), MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), MovedModule("winreg", "_winreg"), ] for attr in _moved_attributes: setattr(_MovedItems, attr.name, attr) if isinstance(attr, MovedModule): _importer._add_module(attr, "moves." + attr.name) del attr _MovedItems._moved_attributes = _moved_attributes moves = _MovedItems(__name__ + ".moves") _importer._add_module(moves, "moves") class Module_six_moves_urllib_parse(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_parse""" _urllib_parse_moved_attributes = [ MovedAttribute("ParseResult", "urlparse", "urllib.parse"), MovedAttribute("SplitResult", "urlparse", "urllib.parse"), MovedAttribute("parse_qs", "urlparse", "urllib.parse"), MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), MovedAttribute("urldefrag", "urlparse", "urllib.parse"), MovedAttribute("urljoin", "urlparse", "urllib.parse"), MovedAttribute("urlparse", "urlparse", "urllib.parse"), MovedAttribute("urlsplit", "urlparse", "urllib.parse"), MovedAttribute("urlunparse", "urlparse", "urllib.parse"), MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), MovedAttribute("quote", "urllib", "urllib.parse"), MovedAttribute("quote_plus", "urllib", "urllib.parse"), MovedAttribute("unquote", "urllib", "urllib.parse"), MovedAttribute("unquote_plus", "urllib", "urllib.parse"), MovedAttribute("urlencode", "urllib", "urllib.parse"), MovedAttribute("splitquery", "urllib", "urllib.parse"), MovedAttribute("splittag", "urllib", "urllib.parse"), MovedAttribute("splituser", "urllib", "urllib.parse"), MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), MovedAttribute("uses_params", "urlparse", "urllib.parse"), MovedAttribute("uses_query", "urlparse", "urllib.parse"), MovedAttribute("uses_relative", "urlparse", "urllib.parse"), ] for attr in _urllib_parse_moved_attributes: setattr(Module_six_moves_urllib_parse, attr.name, attr) del attr Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes _importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), "moves.urllib_parse", "moves.urllib.parse") class Module_six_moves_urllib_error(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_error""" _urllib_error_moved_attributes = [ MovedAttribute("URLError", "urllib2", "urllib.error"), MovedAttribute("HTTPError", "urllib2", "urllib.error"), MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), ] for attr in _urllib_error_moved_attributes: setattr(Module_six_moves_urllib_error, attr.name, attr) del attr Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes _importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), "moves.urllib_error", "moves.urllib.error") class Module_six_moves_urllib_request(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_request""" _urllib_request_moved_attributes = [ MovedAttribute("urlopen", "urllib2", "urllib.request"), MovedAttribute("install_opener", "urllib2", "urllib.request"), MovedAttribute("build_opener", "urllib2", "urllib.request"), MovedAttribute("pathname2url", "urllib", "urllib.request"), MovedAttribute("url2pathname", "urllib", "urllib.request"), MovedAttribute("getproxies", "urllib", "urllib.request"), MovedAttribute("Request", "urllib2", "urllib.request"), MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), MovedAttribute("BaseHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), MovedAttribute("FileHandler", "urllib2", "urllib.request"), MovedAttribute("FTPHandler", "urllib2", "urllib.request"), MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), MovedAttribute("urlretrieve", "urllib", "urllib.request"), MovedAttribute("urlcleanup", "urllib", "urllib.request"), MovedAttribute("URLopener", "urllib", "urllib.request"), MovedAttribute("FancyURLopener", "urllib", "urllib.request"), MovedAttribute("proxy_bypass", "urllib", "urllib.request"), ] for attr in _urllib_request_moved_attributes: setattr(Module_six_moves_urllib_request, attr.name, attr) del attr Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes _importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), "moves.urllib_request", "moves.urllib.request") class Module_six_moves_urllib_response(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_response""" _urllib_response_moved_attributes = [ MovedAttribute("addbase", "urllib", "urllib.response"), MovedAttribute("addclosehook", "urllib", "urllib.response"), MovedAttribute("addinfo", "urllib", "urllib.response"), MovedAttribute("addinfourl", "urllib", "urllib.response"), ] for attr in _urllib_response_moved_attributes: setattr(Module_six_moves_urllib_response, attr.name, attr) del attr Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes _importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), "moves.urllib_response", "moves.urllib.response") class Module_six_moves_urllib_robotparser(_LazyModule): """Lazy loading of moved objects in six.moves.urllib_robotparser""" _urllib_robotparser_moved_attributes = [ MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), ] for attr in _urllib_robotparser_moved_attributes: setattr(Module_six_moves_urllib_robotparser, attr.name, attr) del attr Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes _importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), "moves.urllib_robotparser", "moves.urllib.robotparser") class Module_six_moves_urllib(types.ModuleType): """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" __path__ = [] # mark as package parse = _importer._get_module("moves.urllib_parse") error = _importer._get_module("moves.urllib_error") request = _importer._get_module("moves.urllib_request") response = _importer._get_module("moves.urllib_response") robotparser = _importer._get_module("moves.urllib_robotparser") def __dir__(self): return ['parse', 'error', 'request', 'response', 'robotparser'] _importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), "moves.urllib") def add_move(move): """Add an item to six.moves.""" setattr(_MovedItems, move.name, move) def remove_move(name): """Remove item from six.moves.""" try: delattr(_MovedItems, name) except AttributeError: try: del moves.__dict__[name] except KeyError: raise AttributeError("no such move, %r" % (name,)) if PY3: _meth_func = "__func__" _meth_self = "__self__" _func_closure = "__closure__" _func_code = "__code__" _func_defaults = "__defaults__" _func_globals = "__globals__" else: _meth_func = "im_func" _meth_self = "im_self" _func_closure = "func_closure" _func_code = "func_code" _func_defaults = "func_defaults" _func_globals = "func_globals" try: advance_iterator = next except NameError: def advance_iterator(it): return it.next() next = advance_iterator try: callable = callable except NameError: def callable(obj): return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) if PY3: def get_unbound_function(unbound): return unbound create_bound_method = types.MethodType Iterator = object else: def get_unbound_function(unbound): return unbound.im_func def create_bound_method(func, obj): return types.MethodType(func, obj, obj.__class__) class Iterator(object): def next(self): return type(self).__next__(self) callable = callable _add_doc(get_unbound_function, """Get the function out of a possibly unbound function""") get_method_function = operator.attrgetter(_meth_func) get_method_self = operator.attrgetter(_meth_self) get_function_closure = operator.attrgetter(_func_closure) get_function_code = operator.attrgetter(_func_code) get_function_defaults = operator.attrgetter(_func_defaults) get_function_globals = operator.attrgetter(_func_globals) if PY3: def iterkeys(d, **kw): return iter(d.keys(**kw)) def itervalues(d, **kw): return iter(d.values(**kw)) def iteritems(d, **kw): return iter(d.items(**kw)) def iterlists(d, **kw): return iter(d.lists(**kw)) else: def iterkeys(d, **kw): return iter(d.iterkeys(**kw)) def itervalues(d, **kw): return iter(d.itervalues(**kw)) def iteritems(d, **kw): return iter(d.iteritems(**kw)) def iterlists(d, **kw): return iter(d.iterlists(**kw)) _add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") _add_doc(itervalues, "Return an iterator over the values of a dictionary.") _add_doc(iteritems, "Return an iterator over the (key, value) pairs of a dictionary.") _add_doc(iterlists, "Return an iterator over the (key, [values]) pairs of a dictionary.") if PY3: def b(s): return s.encode("latin-1") def u(s): return s unichr = chr if sys.version_info[1] <= 1: def int2byte(i): return bytes((i,)) else: # This is about 2x faster than the implementation above on 3.2+ int2byte = operator.methodcaller("to_bytes", 1, "big") byte2int = operator.itemgetter(0) indexbytes = operator.getitem iterbytes = iter import io StringIO = io.StringIO BytesIO = io.BytesIO else: def b(s): return s # Workaround for standalone backslash def u(s): return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") unichr = unichr int2byte = chr def byte2int(bs): return ord(bs[0]) def indexbytes(buf, i): return ord(buf[i]) def iterbytes(buf): return (ord(byte) for byte in buf) import StringIO StringIO = BytesIO = StringIO.StringIO _add_doc(b, """Byte literal""") _add_doc(u, """Text literal""") if PY3: exec_ = getattr(moves.builtins, "exec") def reraise(tp, value, tb=None): if value is None: value = tp() if value.__traceback__ is not tb: raise value.with_traceback(tb) raise value else: def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: frame = sys._getframe(1) _globs_ = frame.f_globals if _locs_ is None: _locs_ = frame.f_locals del frame elif _locs_ is None: _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") exec_("""def reraise(tp, value, tb=None): raise tp, value, tb """) print_ = getattr(moves.builtins, "print", None) if print_ is None: def print_(*args, **kwargs): """The new-style print function for Python 2.4 and 2.5.""" fp = kwargs.pop("file", sys.stdout) if fp is None: return def write(data): if not isinstance(data, basestring): data = str(data) # If the file has an encoding, encode unicode with it. if (isinstance(fp, file) and isinstance(data, unicode) and fp.encoding is not None): errors = getattr(fp, "errors", None) if errors is None: errors = "strict" data = data.encode(fp.encoding, errors) fp.write(data) want_unicode = False sep = kwargs.pop("sep", None) if sep is not None: if isinstance(sep, unicode): want_unicode = True elif not isinstance(sep, str): raise TypeError("sep must be None or a string") end = kwargs.pop("end", None) if end is not None: if isinstance(end, unicode): want_unicode = True elif not isinstance(end, str): raise TypeError("end must be None or a string") if kwargs: raise TypeError("invalid keyword arguments to print()") if not want_unicode: for arg in args: if isinstance(arg, unicode): want_unicode = True break if want_unicode: newline = unicode("\n") space = unicode(" ") else: newline = "\n" space = " " if sep is None: sep = space if end is None: end = newline for i, arg in enumerate(args): if i: write(sep) write(arg) write(end) _add_doc(reraise, """Reraise an exception.""") if sys.version_info[0:2] < (3, 4): def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, updated=functools.WRAPPER_UPDATES): def wrapper(f): f = functools.wraps(wrapped)(f) f.__wrapped__ = wrapped return f return wrapper else: wraps = functools.wraps def with_metaclass(meta, *bases): """Create a base class with a metaclass.""" # This requires a bit of explanation: the basic idea is to make a dummy # metaclass for one level of class instantiation that replaces itself with # the actual metaclass. class metaclass(meta): def __new__(cls, name, this_bases, d): return meta(name, bases, d) return type.__new__(metaclass, 'temporary_class', (), {}) def add_metaclass(metaclass): """Class decorator for creating a class with a metaclass.""" def wrapper(cls): orig_vars = cls.__dict__.copy() slots = orig_vars.get('__slots__') if slots is not None: if isinstance(slots, str): slots = [slots] for slots_var in slots: orig_vars.pop(slots_var) orig_vars.pop('__dict__', None) orig_vars.pop('__weakref__', None) return metaclass(cls.__name__, cls.__bases__, orig_vars) return wrapper # Complete the moves implementation. # This code is at the end of this module to speed up module loading. # Turn this module into a package. __path__ = [] # required for PEP 302 and PEP 451 __package__ = __name__ # see PEP 366 @ReservedAssignment if globals().get("__spec__") is not None: __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable # Remove other six meta path importers, since they cause problems. This can # happen if six is removed from sys.modules and then reloaded. (Setuptools does # this for some reason.) if sys.meta_path: for i, importer in enumerate(sys.meta_path): # Here's some real nastiness: Another "instance" of the six module might # be floating around. Therefore, we can't use isinstance() to check for # the six meta path importer, since the other six instance will have # inserted an importer with different class. if (type(importer).__name__ == "_SixMetaPathImporter" and importer.name == __name__): del sys.meta_path[i] break del i, importer # Finally, add the importer to the meta path import hook. sys.meta_path.append(_importer) nipype-0.11.0/nipype/fixes/000077500000000000000000000000001257611314500155245ustar00rootroot00000000000000nipype-0.11.0/nipype/fixes/README.txt000066400000000000000000000006061257611314500172240ustar00rootroot00000000000000This directory is meant to contain fixes to external packages, such as scipy, numpy that are meant to eventually be moved upstream to these packages. When these changes find their way upstream and are released, they can be deleted from the "fixes" directory when new versions of NIPY are released. PACKAGES/MODULES: --------- scipy/stats_models: corresponds to module "scipy.stats.models"nipype-0.11.0/nipype/fixes/__init__.py000066400000000000000000000012671257611314500176430ustar00rootroot00000000000000# We import numpy fixes during init of the testing package. We need to delay # import of the testing package until after it has initialized from os.path import dirname # Cache for the actual testing functin _tester = None def test(*args, **kwargs): """ test function for fixes subpackage This function defers import of the testing machinery so it can import from us first. See nipy.test docstring for parameters and return values """ global _tester if _tester is None: from nipy.testing import Tester _tester = Tester(dirname(__file__)).test return _tester(*args, **kwargs) # Remind nose not to test the test function test.__test__ = False nipype-0.11.0/nipype/fixes/numpy/000077500000000000000000000000001257611314500166745ustar00rootroot00000000000000nipype-0.11.0/nipype/fixes/numpy/__init__.py000066400000000000000000000000261257611314500210030ustar00rootroot00000000000000# numpy fixes package nipype-0.11.0/nipype/fixes/numpy/testing/000077500000000000000000000000001257611314500203515ustar00rootroot00000000000000nipype-0.11.0/nipype/fixes/numpy/testing/__init__.py000066400000000000000000000000471257611314500224630ustar00rootroot00000000000000# Package init for fixes.numpy.testing nipype-0.11.0/nipype/fixes/numpy/testing/noseclasses.py000066400000000000000000000340151257611314500232500ustar00rootroot00000000000000# These classes implement a doctest runner plugin for nose, a "known failure" # error class, and a customized TestProgram for NumPy. # Because this module imports nose directly, it should not # be used except by nosetester.py to avoid a general NumPy # dependency on nose. import os import doctest import nose from nose.plugins import doctests as npd from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin from nose.plugins.base import Plugin from nose.util import src import numpy from nosetester import get_package_name import inspect # Some of the classes in this module begin with 'Numpy' to clearly distinguish # them from the plethora of very similar names from nose/unittest/doctest #----------------------------------------------------------------------------- # Modified version of the one in the stdlib, that fixes a python bug (doctests # not found in extension modules, http://bugs.python.org/issue3158) class NumpyDocTestFinder(doctest.DocTestFinder): def _from_module(self, module, object): """ Return true if the given object is defined in the given module. """ if module is None: #print '_fm C1' # dbg return True elif inspect.isfunction(object): #print '_fm C2' # dbg return module.__dict__ is object.func_globals elif inspect.isbuiltin(object): #print '_fm C2-1' # dbg return module.__name__ == object.__module__ elif inspect.isclass(object): #print '_fm C3' # dbg return module.__name__ == object.__module__ elif inspect.ismethod(object): # This one may be a bug in cython that fails to correctly set the # __module__ attribute of methods, but since the same error is easy # to make by extension code writers, having this safety in place # isn't such a bad idea #print '_fm C3-1' # dbg return module.__name__ == object.im_class.__module__ elif inspect.getmodule(object) is not None: #print '_fm C4' # dbg #print 'C4 mod',module,'obj',object # dbg return module is inspect.getmodule(object) elif hasattr(object, '__module__'): #print '_fm C5' # dbg return module.__name__ == object.__module__ elif isinstance(object, property): #print '_fm C6' # dbg return True # [XX] no way not be sure. else: raise ValueError("object must be a class or function") def _find(self, tests, obj, name, module, source_lines, globs, seen): """ Find tests for the given object and any contained objects, and add them to `tests`. """ doctest.DocTestFinder._find(self,tests, obj, name, module, source_lines, globs, seen) # Below we re-run pieces of the above method with manual modifications, # because the original code is buggy and fails to correctly identify # doctests in extension modules. # Local shorthands from inspect import isroutine, isclass, ismodule, isfunction, \ ismethod # Look for tests in a module's contained objects. if ismodule(obj) and self._recurse: for valname, val in obj.__dict__.items(): valname1 = '%s.%s' % (name, valname) if ( (isroutine(val) or isclass(val)) and self._from_module(module, val) ): self._find(tests, val, valname1, module, source_lines, globs, seen) # Look for tests in a class's contained objects. if isclass(obj) and self._recurse: #print 'RECURSE into class:',obj # dbg for valname, val in obj.__dict__.items(): #valname1 = '%s.%s' % (name, valname) # dbg #print 'N',name,'VN:',valname,'val:',str(val)[:77] # dbg # Special handling for staticmethod/classmethod. if isinstance(val, staticmethod): val = getattr(obj, valname) if isinstance(val, classmethod): val = getattr(obj, valname).im_func # Recurse to methods, properties, and nested classes. if ((isfunction(val) or isclass(val) or ismethod(val) or isinstance(val, property)) and self._from_module(module, val)): valname = '%s.%s' % (name, valname) self._find(tests, val, valname, module, source_lines, globs, seen) # second-chance checker; if the default comparison doesn't # pass, then see if the expected output string contains flags that # tell us to ignore the output class NumpyOutputChecker(doctest.OutputChecker): def check_output(self, want, got, optionflags): ret = doctest.OutputChecker.check_output(self, want, got, optionflags) if not ret: if "#random" in want: return True # it would be useful to normalize endianness so that # bigendian machines don't fail all the tests (and there are # actually some bigendian examples in the doctests). Let's try # making them all little endian got = got.replace("'>","'<") want= want.replace("'>","'<") # try to normalize out 32 and 64 bit default int sizes for sz in [4,8]: got = got.replace("'>> np.testing.nosetester.get_package_name('nonsense') 'numpy' """ fullpath = filepath[:] pkg_name = [] while 'site-packages' in filepath or 'dist-packages' in filepath: filepath, p2 = os.path.split(filepath) if p2 in ('site-packages', 'dist-packages'): break pkg_name.append(p2) # if package name determination failed, just default to numpy/scipy if not pkg_name: if 'scipy' in fullpath: return 'scipy' else: return 'numpy' # otherwise, reverse to get correct order and return pkg_name.reverse() # don't include the outer egg directory if pkg_name[0].endswith('.egg'): pkg_name.pop(0) return '.'.join(pkg_name) def import_nose(): """ Import nose only when needed. """ fine_nose = True minimum_nose_version = (0,10,0) try: import nose from nose.tools import raises except ImportError: fine_nose = False else: if nose.__versioninfo__ < minimum_nose_version: fine_nose = False if not fine_nose: msg = 'Need nose >= %d.%d.%d for tests - see ' \ 'http://somethingaboutorange.com/mrl/projects/nose' % \ minimum_nose_version raise ImportError(msg) return nose def run_module_suite(file_to_run = None): if file_to_run is None: f = sys._getframe(1) file_to_run = f.f_locals.get('__file__', None) if file_to_run is None: raise AssertionError import_nose().run(argv=['',file_to_run]) class NoseTester(object): """ Nose test runner. This class is made available as numpy.testing.Tester, and a test function is typically added to a package's __init__.py like so:: from numpy.testing import Tester test = Tester().test Calling this test function finds and runs all tests associated with the package and all its sub-packages. Attributes ---------- package_path : str Full path to the package to test. package_name : str Name of the package to test. Parameters ---------- package : module, str or None The package to test. If a string, this should be the full path to the package. If None (default), `package` is set to the module from which `NoseTester` is initialized. """ # Stuff to exclude from tests. These are from numpy.distutils excludes = ['f2py_ext', 'f2py_f90_ext', 'gen_ext', 'pyrex_ext', 'swig_ext'] def __init__(self, package=None): ''' Test class init Parameters ---------- package : string or module If string, gives full path to package If None, extract calling module path Default is None ''' package_name = None if package is None: f = sys._getframe(1) package_path = f.f_locals.get('__file__', None) if package_path is None: raise AssertionError package_path = os.path.dirname(package_path) package_name = f.f_locals.get('__name__', None) elif isinstance(package, type(os)): package_path = os.path.dirname(package.__file__) package_name = getattr(package, '__name__', None) else: package_path = str(package) self.package_path = package_path # find the package name under test; this name is used to limit coverage # reporting (if enabled) if package_name is None: package_name = get_package_name(package_path) self.package_name = package_name def _test_argv(self, label, verbose, extra_argv): ''' Generate argv for nosetest command Parameters ---------- label : {'fast', 'full', '', attribute identifier}, optional see ``test`` docstring verbose : int, optional Verbosity value for test outputs, in the range 1-10. Default is 1. extra_argv : list, optional List with any extra arguments to pass to nosetests. Returns ------- argv : list command line arguments that will be passed to nose ''' argv = [__file__, self.package_path, '-s'] if label and label != 'full': if not isinstance(label, six.string_types): raise TypeError('Selection label should be a string') if label == 'fast': label = 'not slow' argv += ['-A', label] argv += ['--verbosity', str(verbose)] if extra_argv: argv += extra_argv return argv def _show_system_info(self): nose = import_nose() import numpy print "NumPy version %s" % numpy.__version__ npdir = os.path.dirname(numpy.__file__) print "NumPy is installed in %s" % npdir if 'scipy' in self.package_name: import scipy print "SciPy version %s" % scipy.__version__ spdir = os.path.dirname(scipy.__file__) print "SciPy is installed in %s" % spdir pyversion = sys.version.replace('\n','') print "Python version %s" % pyversion print "nose version %d.%d.%d" % nose.__versioninfo__ def _get_custom_doctester(self): """ Return instantiated plugin for doctests Allows subclassing of this class to override doctester A return value of None means use the nose builtin doctest plugin """ from noseclasses import NumpyDoctest return NumpyDoctest() def prepare_test_args(self, label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False): """ Run tests for module using nose. This method does the heavy lifting for the `test` method. It takes all the same arguments, for details see `test`. See Also -------- test """ # fail with nice error message if nose is not present import_nose() # compile argv argv = self._test_argv(label, verbose, extra_argv) # bypass tests noted for exclude for ename in self.excludes: argv += ['--exclude', ename] # our way of doing coverage if coverage: argv+=['--cover-package=%s' % self.package_name, '--with-coverage', '--cover-tests', '--cover-inclusive', '--cover-erase'] # construct list of plugins import nose.plugins.builtin from noseclasses import KnownFailure, Unplugger plugins = [KnownFailure()] plugins += [p() for p in nose.plugins.builtin.plugins] # add doctesting if required doctest_argv = '--with-doctest' in argv if doctests == False and doctest_argv: doctests = True plug = self._get_custom_doctester() if plug is None: # use standard doctesting if doctests and not doctest_argv: argv += ['--with-doctest'] else: # custom doctesting if doctest_argv: # in fact the unplugger would take care of this argv.remove('--with-doctest') plugins += [Unplugger('doctest'), plug] if doctests: argv += ['--with-' + plug.name] return argv, plugins def test(self, label='fast', verbose=1, extra_argv=None, doctests=False, coverage=False): """ Run tests for module using nose. Parameters ---------- label : {'fast', 'full', '', attribute identifier}, optional Identifies the tests to run. This can be a string to pass to the nosetests executable with the '-A' option, or one of several special values. Special values are: * 'fast' - the default - which corresponds to the ``nosetests -A`` option of 'not slow'. * 'full' - fast (as above) and slow tests as in the 'no -A' option to nosetests - this is the same as ''. * None or '' - run all tests. attribute_identifier - string passed directly to nosetests as '-A'. verbose : int, optional Verbosity value for test outputs, in the range 1-10. Default is 1. extra_argv : list, optional List with any extra arguments to pass to nosetests. doctests : bool, optional If True, run doctests in module. Default is False. coverage : bool, optional If True, report coverage of NumPy code. Default is False. (This requires the `coverage module: `_). Returns ------- result : object Returns the result of running the tests as a ``nose.result.TextTestResult`` object. Notes ----- Each NumPy module exposes `test` in its namespace to run all tests for it. For example, to run all tests for numpy.lib: >>> np.lib.test() #doctest: +SKIP Examples -------- >>> result = np.lib.test() #doctest: +SKIP Running unit tests for numpy.lib ... Ran 976 tests in 3.933s OK >>> result.errors #doctest: +SKIP [] >>> result.knownfail #doctest: +SKIP [] """ # cap verbosity at 3 because nose becomes *very* verbose beyond that verbose = min(verbose, 3) import utils utils.verbose = verbose if doctests: print "Running unit tests and doctests for %s" % self.package_name else: print "Running unit tests for %s" % self.package_name self._show_system_info() # reset doctest state on every run import doctest doctest.master = None argv, plugins = self.prepare_test_args(label, verbose, extra_argv, doctests, coverage) from noseclasses import NumpyTestProgram t = NumpyTestProgram(argv=argv, exit=False, plugins=plugins) return t.result def bench(self, label='fast', verbose=1, extra_argv=None): """ Run benchmarks for module using nose. Parameters ---------- label : {'fast', 'full', '', attribute identifier}, optional Identifies the benchmarks to run. This can be a string to pass to the nosetests executable with the '-A' option, or one of several special values. Special values are: * 'fast' - the default - which corresponds to the ``nosetests -A`` option of 'not slow'. * 'full' - fast (as above) and slow benchmarks as in the 'no -A' option to nosetests - this is the same as ''. * None or '' - run all tests. attribute_identifier - string passed directly to nosetests as '-A'. verbose : int, optional Verbosity value for benchmark outputs, in the range 1-10. Default is 1. extra_argv : list, optional List with any extra arguments to pass to nosetests. Returns ------- success : bool Returns True if running the benchmarks works, False if an error occurred. Notes ----- Benchmarks are like tests, but have names starting with "bench" instead of "test", and can be found under the "benchmarks" sub-directory of the module. Each NumPy module exposes `bench` in its namespace to run all benchmarks for it. Examples -------- >>> success = np.lib.bench() #doctest: +SKIP Running benchmarks for numpy.lib ... using 562341 items: unique: 0.11 unique1d: 0.11 ratio: 1.0 nUnique: 56230 == 56230 ... OK >>> success #doctest: +SKIP True """ print "Running benchmarks for %s" % self.package_name self._show_system_info() argv = self._test_argv(label, verbose, extra_argv) argv += ['--match', r'(?:^|[\\b_\\.%s-])[Bb]ench' % os.sep] # import nose or make informative error nose = import_nose() # get plugin to disable doctests from noseclasses import Unplugger add_plugins = [Unplugger('doctest')] return nose.run(argv=argv, addplugins=add_plugins) nipype-0.11.0/nipype/fixes/numpy/testing/utils.py000066400000000000000000000001361257611314500220630ustar00rootroot00000000000000# Allow numpy fixes noseclasses to do local import of utils from numpy.testing.utils import * nipype-0.11.0/nipype/info.py000066400000000000000000000132771257611314500157250ustar00rootroot00000000000000""" This file contains defines parameters for nipy that we use to fill settings in setup.py, the nipy top-level docstring, and for building the docs. In setup.py in particular, we exec this file, so it cannot import nipy """ # nipy version information. An empty _version_extra corresponds to a # full release. '.dev' as a _version_extra string means this is a development # version _version_major = 0 _version_minor = 11 _version_micro = 0 _version_extra = '' # switch to -dev for non release def get_nipype_gitversion(): """Nipype version as reported by the last commit in git Returns ------- None or str Version of NiPype according to git. """ import os import subprocess try: import nipype gitpath = os.path.realpath(os.path.join(os.path.dirname(nipype.__file__), os.path.pardir)) except: gitpath = os.getcwd() gitpathgit = os.path.join(gitpath, '.git') if not os.path.exists(gitpathgit): return None ver = None try: o, _ = subprocess.Popen('git describe', shell=True, cwd=gitpath, stdout=subprocess.PIPE).communicate() except Exception: pass else: ver = o.strip().split('-')[-1] return ver if '-dev' in _version_extra: gitversion = get_nipype_gitversion() if gitversion: _version_extra = '-' + gitversion + '.dev' # Format expected by setup.py and doc/source/conf.py: string of form "X.Y.Z" __version__ = "%s.%s.%s%s" % (_version_major, _version_minor, _version_micro, _version_extra) CLASSIFIERS = ["Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX :: Linux", "Programming Language :: Python :: 2.7", "Topic :: Scientific/Engineering"] description = 'Neuroimaging in Python: Pipelines and Interfaces' # Note: this long_description is actually a copy/paste from the top-level # README.txt, so that it shows up nicely on PyPI. So please remember to edit # it only in one place and sync it correctly. long_description = \ """ ======================================================== NIPYPE: Neuroimaging in Python: Pipelines and Interfaces ======================================================== Current neuroimaging software offer users an incredible opportunity to analyze data using a variety of different algorithms. However, this has resulted in a heterogeneous collection of specialized applications without transparent interoperability or a uniform operating interface. *Nipype*, an open-source, community-developed initiative under the umbrella of NiPy_, is a Python project that provides a uniform interface to existing neuroimaging software and facilitates interaction between these packages within a single workflow. Nipype provides an environment that encourages interactive exploration of algorithms from different packages (e.g., ANTS, SPM, FSL, FreeSurfer, Camino, MRtrix, MNE, AFNI, BRAINS, Slicer), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is creating a collaborative platform for neuroimaging software development in a high-level language and addressing limitations of existing pipeline systems. *Nipype* allows you to: * easily interact with tools from different software packages * combine processing steps from different software packages * develop new workflows faster by reusing common steps from old ones * process data faster by running it in parallel on many cores/machines * make your research easily reproducible * share your processing workflows with the community """ # versions NIBABEL_MIN_VERSION = '2.0.1' NETWORKX_MIN_VERSION = '1.7' NUMPY_MIN_VERSION = '1.6.2' SCIPY_MIN_VERSION = '0.11' TRAITS_MIN_VERSION = '4.3' DATEUTIL_MIN_VERSION = '1.5' NOSE_MIN_VERSION = '1.2' NAME = 'nipype' MAINTAINER = "nipype developers" MAINTAINER_EMAIL = "neuroimaging@python.org" DESCRIPTION = description LONG_DESCRIPTION = long_description URL = "http://nipy.org/nipype" DOWNLOAD_URL = "http://github.com/nipy/nipype/archives/master" LICENSE = "BSD license" CLASSIFIERS = CLASSIFIERS AUTHOR = "nipype developers" AUTHOR_EMAIL = "neuroimaging@python.org" PLATFORMS = "OS Independent" MAJOR = _version_major MINOR = _version_minor MICRO = _version_micro ISRELEASE = _version_extra == '' VERSION = __version__ PROVIDES = ['nipype'] REQUIRES = ["nibabel (>=%s)" % NIBABEL_MIN_VERSION, "networkx (>=%s)" % NETWORKX_MIN_VERSION, "numpy (>=%s)" % NUMPY_MIN_VERSION, "python-dateutil (>=%s)" % DATEUTIL_MIN_VERSION, "scipy (>=%s)" % SCIPY_MIN_VERSION, "traits (>=%s)" % TRAITS_MIN_VERSION, "nose (>=%s)" % NOSE_MIN_VERSION] REQUIRES = ["nibabel>=%s" % NIBABEL_MIN_VERSION, "networkx>=%s" % NETWORKX_MIN_VERSION, "numpy>=%s" % NUMPY_MIN_VERSION, "python-dateutil>=%s" % DATEUTIL_MIN_VERSION, "scipy>=%s" % SCIPY_MIN_VERSION, "traits>=%s" % TRAITS_MIN_VERSION, "nose>=%s" % NOSE_MIN_VERSION] STATUS = 'stable' nipype-0.11.0/nipype/interfaces/000077500000000000000000000000001257611314500165315ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/__init__.py000066400000000000000000000006111257611314500206400ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Package contains interfaces for using existing functionality in other packages Requires Packages to be installed """ __docformat__ = 'restructuredtext' from io import DataGrabber, DataSink, SelectFiles from utility import IdentityInterface, Rename, Function, Select, Merge nipype-0.11.0/nipype/interfaces/afni/000077500000000000000000000000001257611314500174465ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/afni/__init__.py000066400000000000000000000014101257611314500215530ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The afni module provides classes for interfacing with the `AFNI `_ command line tools. Top-level namespace for afni. """ from .base import Info from .preprocess import (To3D, Refit, Resample, TStat, Automask, Volreg, Merge, ZCutUp, Calc, TShift, Warp, Detrend, Despike, Copy, Fourier, Allineate, Maskave, SkullStrip, TCat, Fim, BlurInMask, Autobox, TCorrMap, Bandpass, Retroicor, TCorrelate, TCorr1D, BrickStat, ROIStats, AutoTcorrelate, AFNItoNIFTI, Eval, Means) from .svm import (SVMTest, SVMTrain) nipype-0.11.0/nipype/interfaces/afni/base.py000066400000000000000000000114641257611314500207400ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Provide interface to AFNI commands.""" import os import warnings from ...utils.filemanip import split_filename from ..base import ( CommandLine, traits, CommandLineInputSpec, isdefined, File, TraitedSpec) warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class Info(object): """Handle afni output type and version information. """ __outputtype = 'AFNI' ftypes = {'NIFTI': '.nii', 'AFNI': '', 'NIFTI_GZ': '.nii.gz'} @staticmethod def version(): """Check for afni version on system Parameters ---------- None Returns ------- version : str Version number as string or None if AFNI not found """ clout = CommandLine(command='afni_vcheck', terminal_output='allatonce').run() out = clout.runtime.stdout return out.split('\n')[1] @classmethod def outputtype_to_ext(cls, outputtype): """Get the file extension for the given output type. Parameters ---------- outputtype : {'NIFTI', 'NIFTI_GZ', 'AFNI'} String specifying the output type. Returns ------- extension : str The file extension for the output type. """ try: return cls.ftypes[outputtype] except KeyError: msg = 'Invalid AFNIOUTPUTTYPE: ', outputtype raise KeyError(msg) @classmethod def outputtype(cls): """AFNI has no environment variables, Output filetypes get set in command line calls Nipype uses AFNI as default Returns ------- None """ #warn(('AFNI has no environment variable that sets filetype ' # 'Nipype uses NIFTI_GZ as default')) return 'AFNI' @staticmethod def standard_image(img_name): '''Grab an image from the standard location. Could be made more fancy to allow for more relocatability''' clout = CommandLine('which afni', terminal_output='allatonce').run() if clout.runtime.returncode is not 0: return None out = clout.runtime.stdout basedir = os.path.split(out)[0] return os.path.join(basedir, img_name) class AFNICommandInputSpec(CommandLineInputSpec): outputtype = traits.Enum('AFNI', Info.ftypes.keys(), desc='AFNI output filetype') out_file = File(name_template="%s_afni", desc='output image file name', argstr='-prefix %s', name_source=["in_file"]) class AFNICommandOutputSpec(TraitedSpec): out_file = File(desc='output file', exists=True) class AFNICommand(CommandLine): input_spec = AFNICommandInputSpec _outputtype = None def __init__(self, **inputs): super(AFNICommand, self).__init__(**inputs) self.inputs.on_trait_change(self._output_update, 'outputtype') if self._outputtype is None: self._outputtype = Info.outputtype() if not isdefined(self.inputs.outputtype): self.inputs.outputtype = self._outputtype else: self._output_update() def _output_update(self): """ i think? updates class private attribute based on instance input in fsl also updates ENVIRON variable....not valid in afni as it uses no environment variables """ self._outputtype = self.inputs.outputtype @classmethod def set_default_output_type(cls, outputtype): """Set the default output type for AFNI classes. This method is used to set the default output type for all afni subclasses. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.outputtype. """ if outputtype in Info.ftypes: cls._outputtype = outputtype else: raise AttributeError('Invalid AFNI outputtype: %s' % outputtype) def _overload_extension(self, value, name=None): path, base, _ = split_filename(value) return os.path.join(path, base + Info.outputtype_to_ext(self.inputs.outputtype)) def _list_outputs(self): outputs = super(AFNICommand, self)._list_outputs() metadata = dict(name_source=lambda t: t is not None) out_names = self.inputs.traits(**metadata).keys() if out_names: for name in out_names: if outputs[name]: _,_,ext = split_filename(outputs[name]) if ext == "": outputs[name] = outputs[name] + "+orig.BRIK" return outputs nipype-0.11.0/nipype/interfaces/afni/preprocess.py000066400000000000000000002232341257611314500222130ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft = python sts = 4 ts = 4 sw = 4 et: """Afni preprocessing interfaces Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import warnings import os import re from ..base import (Directory, TraitedSpec, traits, isdefined, File, InputMultiPath, Undefined) from ...utils.filemanip import (load_json, save_json, split_filename) from nipype.utils.filemanip import fname_presuffix from .base import AFNICommand, AFNICommandInputSpec,\ AFNICommandOutputSpec from nipype.interfaces.base import CommandLineInputSpec, CommandLine,\ OutputMultiPath warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class To3DInputSpec(AFNICommandInputSpec): out_file = File(name_template="%s", desc='output image file name', argstr='-prefix %s', name_source=["in_folder"]) in_folder = Directory(desc='folder with DICOM images to convert', argstr='%s/*.dcm', position=-1, mandatory=True, exists=True) filetype = traits.Enum('spgr', 'fse', 'epan', 'anat', 'ct', 'spct', 'pet', 'mra', 'bmap', 'diff', 'omri', 'abuc', 'fim', 'fith', 'fico', 'fitt', 'fift', 'fizt', 'fict', 'fibt', 'fibn', 'figt', 'fipt', 'fbuc', argstr='-%s', desc='type of datafile being converted') skipoutliers = traits.Bool(desc='skip the outliers check', argstr='-skip_outliers') assumemosaic = traits.Bool(desc='assume that Siemens image is mosaic', argstr='-assume_dicom_mosaic') datatype = traits.Enum('short', 'float', 'byte', 'complex', desc='set output file datatype', argstr='-datum %s') funcparams = traits.Str(desc='parameters for functional data', argstr='-time:zt %s alt+z2') class To3D(AFNICommand): """Create a 3D dataset from 2D image files using AFNI to3d command For complete details, see the `to3d Documentation `_ Examples ======== >>> from nipype.interfaces import afni >>> To3D = afni.To3D() >>> To3D.inputs.datatype = 'float' >>> To3D.inputs.in_folder = '.' >>> To3D.inputs.out_file = 'dicomdir.nii' >>> To3D.inputs.filetype = "anat" >>> To3D.cmdline #doctest: +ELLIPSIS 'to3d -datum float -anat -prefix dicomdir.nii ./*.dcm' >>> res = To3D.run() #doctest: +SKIP """ _cmd = 'to3d' input_spec = To3DInputSpec output_spec = AFNICommandOutputSpec class TShiftInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dTShift', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_tshift", desc='output image file name', argstr='-prefix %s', name_source="in_file") tr = traits.Str(desc='manually set the TR' + 'You can attach suffix "s" for seconds or "ms" for milliseconds.', argstr='-TR %s') tzero = traits.Float(desc='align each slice to given time offset', argstr='-tzero %s', xor=['tslice']) tslice = traits.Int(desc='align each slice to time offset of given slice', argstr='-slice %s', xor=['tzero']) ignore = traits.Int(desc='ignore the first set of points specified', argstr='-ignore %s') interp = traits.Enum(('Fourier', 'linear', 'cubic', 'quintic', 'heptic'), desc='different interpolation methods (see 3dTShift for details)' + ' default = Fourier', argstr='-%s') tpattern = traits.Str(desc='use specified slice time pattern rather than one in header', argstr='-tpattern %s') rlt = traits.Bool(desc='Before shifting, remove the mean and linear trend', argstr="-rlt") rltplus = traits.Bool(desc='Before shifting,' + ' remove the mean and linear trend and ' + 'later put back the mean', argstr="-rlt+") class TShift(AFNICommand): """Shifts voxel time series from input so that seperate slices are aligned to the same temporal origin For complete details, see the `3dTshift Documentation. Examples ======== >>> from nipype.interfaces import afni as afni >>> tshift = afni.TShift() >>> tshift.inputs.in_file = 'functional.nii' >>> tshift.inputs.tpattern = 'alt+z' >>> tshift.inputs.tzero = 0.0 >>> tshift.cmdline #doctest: '3dTshift -prefix functional_tshift -tpattern alt+z -tzero 0.0 functional.nii' >>> res = tshift.run() # doctest: +SKIP """ _cmd = '3dTshift' input_spec = TShiftInputSpec output_spec = AFNICommandOutputSpec class RefitInputSpec(CommandLineInputSpec): in_file = File(desc='input file to 3drefit', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=True) deoblique = traits.Bool(desc='replace current transformation' + ' matrix with cardinal matrix', argstr='-deoblique') xorigin = traits.Str(desc='x distance for edge voxel offset', argstr='-xorigin %s') yorigin = traits.Str(desc='y distance for edge voxel offset', argstr='-yorigin %s') zorigin = traits.Str(desc='z distance for edge voxel offset', argstr='-zorigin %s') xdel = traits.Float(desc='new x voxel dimension in mm', argstr='-xdel %f') ydel = traits.Float(desc='new y voxel dimension in mm', argstr='-ydel %f') zdel = traits.Float(desc='new z voxel dimension in mm', argstr='-zdel %f') space = traits.Enum('TLRC', 'MNI', 'ORIG', argstr='-space %s', desc='Associates the dataset with a specific' + ' template type, e.g. TLRC, MNI, ORIG') class Refit(CommandLine): """Changes some of the information inside a 3D dataset's header For complete details, see the `3drefit Documentation. Examples ======== >>> from nipype.interfaces import afni as afni >>> refit = afni.Refit() >>> refit.inputs.in_file = 'structural.nii' >>> refit.inputs.deoblique = True >>> refit.cmdline '3drefit -deoblique structural.nii' >>> res = refit.run() # doctest: +SKIP """ _cmd = '3drefit' input_spec = RefitInputSpec output_spec = AFNICommandOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = os.path.abspath(self.inputs.in_file) return outputs class WarpInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dWarp', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_warp", desc='output image file name', argstr='-prefix %s', name_source="in_file") tta2mni = traits.Bool(desc='transform dataset from Talairach to MNI152', argstr='-tta2mni') mni2tta = traits.Bool(desc='transform dataset from MNI152 to Talaraich', argstr='-mni2tta') matparent = File(desc="apply transformation from 3dWarpDrive", argstr="-matparent %s", exists=True) deoblique = traits.Bool(desc='transform dataset from oblique to cardinal', argstr='-deoblique') interp = traits.Enum(('linear', 'cubic', 'NN', 'quintic'), desc='spatial interpolation methods [default = linear]', argstr='-%s') gridset = File(desc="copy grid of specified dataset", argstr="-gridset %s", exists=True) newgrid = traits.Float(desc="specify grid of this size (mm)", argstr="-newgrid %f") zpad = traits.Int(desc="pad input dataset with N planes" + " of zero on all sides.", argstr="-zpad %d") class Warp(AFNICommand): """Use 3dWarp for spatially transforming a dataset For complete details, see the `3dWarp Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> warp = afni.Warp() >>> warp.inputs.in_file = 'structural.nii' >>> warp.inputs.deoblique = True >>> warp.inputs.out_file = "trans.nii.gz" >>> warp.cmdline '3dWarp -deoblique -prefix trans.nii.gz structural.nii' >>> warp_2 = afni.Warp() >>> warp_2.inputs.in_file = 'structural.nii' >>> warp_2.inputs.newgrid = 1.0 >>> warp_2.inputs.out_file = "trans.nii.gz" >>> warp_2.cmdline '3dWarp -newgrid 1.000000 -prefix trans.nii.gz structural.nii' """ _cmd = '3dWarp' input_spec = WarpInputSpec output_spec = AFNICommandOutputSpec class ResampleInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dresample', argstr='-inset %s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_resample", desc='output image file name', argstr='-prefix %s', name_source="in_file") orientation = traits.Str(desc='new orientation code', argstr='-orient %s') resample_mode = traits.Enum('NN', 'Li', 'Cu', 'Bk', argstr='-rmode %s', desc="resampling method from set {'NN', 'Li', 'Cu', 'Bk'}. These are for 'Nearest Neighbor', 'Linear', 'Cubic' and 'Blocky' interpolation, respectively. Default is NN.") voxel_size = traits.Tuple(*[traits.Float()]*3, argstr='-dxyz %f %f %f', desc="resample to new dx, dy and dz") master = traits.File(argstr='-master %s', desc='align dataset grid to a reference file') class Resample(AFNICommand): """Resample or reorient an image using AFNI 3dresample command For complete details, see the `3dresample Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> resample = afni.Resample() >>> resample.inputs.in_file = 'functional.nii' >>> resample.inputs.orientation= 'RPI' >>> resample.inputs.outputtype = "NIFTI" >>> resample.cmdline '3dresample -orient RPI -prefix functional_resample.nii -inset functional.nii' >>> res = resample.run() # doctest: +SKIP """ _cmd = '3dresample' input_spec = ResampleInputSpec output_spec = AFNICommandOutputSpec class AutoTcorrelateInputSpec(AFNICommandInputSpec): in_file = File(desc='timeseries x space (volume or surface) file', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) polort = traits.Int( desc='Remove polynomical trend of order m or -1 for no detrending', argstr="-polort %d") eta2 = traits.Bool(desc='eta^2 similarity', argstr="-eta2") mask = File(exists=True, desc="mask of voxels", argstr="-mask %s") mask_only_targets = traits.Bool(desc="use mask only on targets voxels", argstr="-mask_only_targets", xor=['mask_source']) mask_source = File(exists=True, desc="mask for source voxels", argstr="-mask_source %s", xor=['mask_only_targets']) out_file = File(name_template="%s_similarity_matrix.1D", desc='output image file name', argstr='-prefix %s', name_source="in_file") class AutoTcorrelate(AFNICommand): """Computes the correlation coefficient between the time series of each pair of voxels in the input dataset, and stores the output into a new anatomical bucket dataset [scaled to shorts to save memory space]. Examples ======== >>> from nipype.interfaces import afni as afni >>> corr = afni.AutoTcorrelate() >>> corr.inputs.in_file = 'functional.nii' >>> corr.inputs.polort = -1 >>> corr.inputs.eta2 = True >>> corr.inputs.mask = 'mask.nii' >>> corr.inputs.mask_only_targets = True >>> corr.cmdline # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE '3dAutoTcorrelate -eta2 -mask mask.nii -mask_only_targets -prefix functional_similarity_matrix.1D -polort -1 functional.nii' >>> res = corr.run() # doctest: +SKIP """ input_spec = AutoTcorrelateInputSpec output_spec = AFNICommandOutputSpec _cmd = '3dAutoTcorrelate' def _overload_extension(self, value, name=None): path, base, ext = split_filename(value) if ext.lower() not in [".1d", ".nii.gz", ".nii"]: ext = ext + ".1D" return os.path.join(path, base + ext) class TStatInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dTstat', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_tstat", desc='output image file name', argstr='-prefix %s', name_source="in_file") mask = File(desc='mask file', argstr='-mask %s', exists=True) options = traits.Str(desc='selected statistical output', argstr='%s') class TStat(AFNICommand): """Compute voxel-wise statistics using AFNI 3dTstat command For complete details, see the `3dTstat Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> tstat = afni.TStat() >>> tstat.inputs.in_file = 'functional.nii' >>> tstat.inputs.args= '-mean' >>> tstat.inputs.out_file = "stats" >>> tstat.cmdline '3dTstat -mean -prefix stats functional.nii' >>> res = tstat.run() # doctest: +SKIP """ _cmd = '3dTstat' input_spec = TStatInputSpec output_spec = AFNICommandOutputSpec class DetrendInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dDetrend', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_detrend", desc='output image file name', argstr='-prefix %s', name_source="in_file") class Detrend(AFNICommand): """This program removes components from voxel time series using linear least squares For complete details, see the `3dDetrend Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> detrend = afni.Detrend() >>> detrend.inputs.in_file = 'functional.nii' >>> detrend.inputs.args = '-polort 2' >>> detrend.inputs.outputtype = "AFNI" >>> detrend.cmdline '3dDetrend -polort 2 -prefix functional_detrend functional.nii' >>> res = detrend.run() # doctest: +SKIP """ _cmd = '3dDetrend' input_spec = DetrendInputSpec output_spec = AFNICommandOutputSpec class DespikeInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dDespike', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_despike", desc='output image file name', argstr='-prefix %s', name_source="in_file") class Despike(AFNICommand): """Removes 'spikes' from the 3D+time input dataset For complete details, see the `3dDespike Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> despike = afni.Despike() >>> despike.inputs.in_file = 'functional.nii' >>> despike.cmdline '3dDespike -prefix functional_despike functional.nii' >>> res = despike.run() # doctest: +SKIP """ _cmd = '3dDespike' input_spec = DespikeInputSpec output_spec = AFNICommandOutputSpec class AutomaskInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dAutomask', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_mask", desc='output image file name', argstr='-prefix %s', name_source="in_file") brain_file = File(name_template="%s_masked", desc="output file from 3dAutomask", argstr='-apply_prefix %s', name_source="in_file") clfrac = traits.Float(desc='sets the clip level fraction' + ' (must be 0.1-0.9). ' + 'A small value will tend to make the mask larger [default = 0.5].', argstr="-clfrac %s") dilate = traits.Int(desc='dilate the mask outwards', argstr="-dilate %s") erode = traits.Int(desc='erode the mask inwards', argstr="-erode %s") class AutomaskOutputSpec(TraitedSpec): out_file = File(desc='mask file', exists=True) brain_file = File(desc='brain file (skull stripped)', exists=True) class Automask(AFNICommand): """Create a brain-only mask of the image using AFNI 3dAutomask command For complete details, see the `3dAutomask Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> automask = afni.Automask() >>> automask.inputs.in_file = 'functional.nii' >>> automask.inputs.dilate = 1 >>> automask.inputs.outputtype = "NIFTI" >>> automask.cmdline #doctest: +ELLIPSIS '3dAutomask -apply_prefix functional_masked.nii -dilate 1 -prefix functional_mask.nii functional.nii' >>> res = automask.run() # doctest: +SKIP """ _cmd = '3dAutomask' input_spec = AutomaskInputSpec output_spec = AutomaskOutputSpec class VolregInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dvolreg', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_volreg", desc='output image file name', argstr='-prefix %s', name_source="in_file") basefile = File(desc='base file for registration', argstr='-base %s', position=-6, exists=True) zpad = traits.Int(desc='Zeropad around the edges' + ' by \'n\' voxels during rotations', argstr='-zpad %d', position=-5) md1d_file = File(name_template='%s_md.1D', desc='max displacement output file', argstr='-maxdisp1D %s', name_source="in_file", keep_extension=True, position=-4) oned_file = File(name_template='%s.1D', desc='1D movement parameters output file', argstr='-1Dfile %s', name_source="in_file", keep_extension=True) verbose = traits.Bool(desc='more detailed description of the process', argstr='-verbose') timeshift = traits.Bool(desc='time shift to mean slice time offset', argstr='-tshift 0') copyorigin = traits.Bool(desc='copy base file origin coords to output', argstr='-twodup') oned_matrix_save = File(name_template='%s.aff12.1D', desc='Save the matrix transformation', argstr='-1Dmatrix_save %s', keep_extension=True, name_source="in_file") class VolregOutputSpec(TraitedSpec): out_file = File(desc='registered file', exists=True) md1d_file = File(desc='max displacement info file', exists=True) oned_file = File(desc='movement parameters info file', exists=True) oned_matrix_save = File(desc='matrix transformation from base to input', exists=True) class Volreg(AFNICommand): """Register input volumes to a base volume using AFNI 3dvolreg command For complete details, see the `3dvolreg Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> volreg = afni.Volreg() >>> volreg.inputs.in_file = 'functional.nii' >>> volreg.inputs.args = '-Fourier -twopass' >>> volreg.inputs.zpad = 4 >>> volreg.inputs.outputtype = "NIFTI" >>> volreg.cmdline #doctest: +ELLIPSIS '3dvolreg -Fourier -twopass -1Dfile functional.1D -1Dmatrix_save functional.aff12.1D -prefix functional_volreg.nii -zpad 4 -maxdisp1D functional_md.1D functional.nii' >>> res = volreg.run() # doctest: +SKIP """ _cmd = '3dvolreg' input_spec = VolregInputSpec output_spec = VolregOutputSpec class MergeInputSpec(AFNICommandInputSpec): in_files = InputMultiPath( File(desc='input file to 3dmerge', exists=True), argstr='%s', position=-1, mandatory=True, copyfile=False) out_file = File(name_template="%s_merge", desc='output image file name', argstr='-prefix %s', name_source="in_file") doall = traits.Bool(desc='apply options to all sub-bricks in dataset', argstr='-doall') blurfwhm = traits.Int(desc='FWHM blur value (mm)', argstr='-1blur_fwhm %d', units='mm') class Merge(AFNICommand): """Merge or edit volumes using AFNI 3dmerge command For complete details, see the `3dmerge Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> merge = afni.Merge() >>> merge.inputs.in_files = ['functional.nii', 'functional2.nii'] >>> merge.inputs.blurfwhm = 4 >>> merge.inputs.doall = True >>> merge.inputs.out_file = 'e7.nii' >>> res = merge.run() # doctest: +SKIP """ _cmd = '3dmerge' input_spec = MergeInputSpec output_spec = AFNICommandOutputSpec class CopyInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dcopy', argstr='%s', position=-2, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_copy", desc='output image file name', argstr='%s', position=-1, name_source="in_file") class Copy(AFNICommand): """Copies an image of one type to an image of the same or different type using 3dcopy command For complete details, see the `3dcopy Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> copy3d = afni.Copy() >>> copy3d.inputs.in_file = 'functional.nii' >>> copy3d.cmdline '3dcopy functional.nii functional_copy' >>> from copy import deepcopy >>> copy3d_2 = deepcopy(copy3d) >>> copy3d_2.inputs.outputtype = 'NIFTI' >>> copy3d_2.cmdline '3dcopy functional.nii functional_copy.nii' >>> copy3d_3 = deepcopy(copy3d) >>> copy3d_3.inputs.outputtype = 'NIFTI_GZ' >>> copy3d_3.cmdline '3dcopy functional.nii functional_copy.nii.gz' >>> copy3d_4 = deepcopy(copy3d) >>> copy3d_4.inputs.out_file = 'new_func.nii' >>> copy3d_4.cmdline '3dcopy functional.nii new_func.nii' """ _cmd = '3dcopy' input_spec = CopyInputSpec output_spec = AFNICommandOutputSpec class FourierInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dFourier', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_fourier", desc='output image file name', argstr='-prefix %s', name_source="in_file") lowpass = traits.Float(desc='lowpass', argstr='-lowpass %f', position=0, mandatory=True) highpass = traits.Float(desc='highpass', argstr='-highpass %f', position=1, mandatory=True) class Fourier(AFNICommand): """Program to lowpass and/or highpass each voxel time series in a dataset, via the FFT For complete details, see the `3dFourier Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> fourier = afni.Fourier() >>> fourier.inputs.in_file = 'functional.nii' >>> fourier.inputs.args = '-retrend' >>> fourier.inputs.highpass = 0.005 >>> fourier.inputs.lowpass = 0.1 >>> res = fourier.run() # doctest: +SKIP """ _cmd = '3dFourier' input_spec = FourierInputSpec output_spec = AFNICommandOutputSpec class BandpassInputSpec(AFNICommandInputSpec): in_file = File( desc='input file to 3dBandpass', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File( name_template='%s_bp', desc='output file from 3dBandpass', argstr='-prefix %s', position=1, name_source='in_file', genfile=True) lowpass = traits.Float( desc='lowpass', argstr='%f', position=-2, mandatory=True) highpass = traits.Float( desc='highpass', argstr='%f', position=-3, mandatory=True) mask = File( desc='mask file', position=2, argstr='-mask %s', exists=True) despike = traits.Bool( argstr='-despike', desc="""Despike each time series before other processing. ++ Hopefully, you don't actually need to do this, which is why it is optional.""") orthogonalize_file = InputMultiPath( File(exists=True), argstr="-ort %s", desc="""Also orthogonalize input to columns in f.1D ++ Multiple '-ort' options are allowed.""") orthogonalize_dset = File( exists=True, argstr="-dsort %s", desc="""Orthogonalize each voxel to the corresponding voxel time series in dataset 'fset', which must have the same spatial and temporal grid structure as the main input dataset. ++ At present, only one '-dsort' option is allowed.""") no_detrend = traits.Bool( argstr='-nodetrend', desc="""Skip the quadratic detrending of the input that occurs before the FFT-based bandpassing. ++ You would only want to do this if the dataset had been detrended already in some other program.""") tr = traits.Float( argstr="-dt %f", desc="set time step (TR) in sec [default=from dataset header]") nfft = traits.Int( argstr='-nfft %d', desc="set the FFT length [must be a legal value]") normalize = traits.Bool( argstr='-norm', desc="""Make all output time series have L2 norm = 1 ++ i.e., sum of squares = 1""") automask = traits.Bool( argstr='-automask', desc="Create a mask from the input dataset") blur = traits.Float( argstr='-blur %f', desc="""Blur (inside the mask only) with a filter width (FWHM) of 'fff' millimeters.""") localPV = traits.Float( argstr='-localPV %f', desc="""Replace each vector by the local Principal Vector (AKA first singular vector) from a neighborhood of radius 'rrr' millimiters. ++ Note that the PV time series is L2 normalized. ++ This option is mostly for Bob Cox to have fun with.""") notrans = traits.Bool( argstr='-notrans', desc="""Don't check for initial positive transients in the data: ++ The test is a little slow, so skipping it is OK, if you KNOW the data time series are transient-free.""") class Bandpass(AFNICommand): """Program to lowpass and/or highpass each voxel time series in a dataset, offering more/different options than Fourier For complete details, see the `3dBandpass Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> from nipype.testing import example_data >>> bandpass = afni.Bandpass() >>> bandpass.inputs.in_file = example_data('functional.nii') >>> bandpass.inputs.highpass = 0.005 >>> bandpass.inputs.lowpass = 0.1 >>> res = bandpass.run() # doctest: +SKIP """ _cmd = '3dBandpass' input_spec = BandpassInputSpec output_spec = AFNICommandOutputSpec class ZCutUpInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dZcutup', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_zcupup", desc='output image file name', argstr='-prefix %s', name_source="in_file") keep = traits.Str(desc='slice range to keep in output', argstr='-keep %s') class ZCutUp(AFNICommand): """Cut z-slices from a volume using AFNI 3dZcutup command For complete details, see the `3dZcutup Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> zcutup = afni.ZCutUp() >>> zcutup.inputs.in_file = 'functional.nii' >>> zcutup.inputs.out_file = 'functional_zcutup.nii' >>> zcutup.inputs.keep= '0 10' >>> res = zcutup.run() # doctest: +SKIP """ _cmd = '3dZcutup' input_spec = ZCutUpInputSpec output_spec = AFNICommandOutputSpec class AllineateInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dAllineate', argstr='-source %s', position=-1, mandatory=True, exists=True, copyfile=False) reference = File( exists=True, argstr='-base %s', desc="""file to be used as reference, the first volume will be used if not given the reference will be the first volume of in_file.""") out_file = File( desc='output file from 3dAllineate', argstr='-prefix %s', position=-2, name_source='%s_allineate', genfile=True) out_param_file = File( argstr='-1Dparam_save %s', desc='Save the warp parameters in ASCII (.1D) format.') in_param_file = File( exists=True, argstr='-1Dparam_apply %s', desc="""Read warp parameters from file and apply them to the source dataset, and produce a new dataset""") out_matrix = File( argstr='-1Dmatrix_save %s', desc='Save the transformation matrix for each volume.') in_matrix = File(desc='matrix to align input file', argstr='-1Dmatrix_apply %s', position=-3) _cost_funcs = [ 'leastsq', 'ls', 'mutualinfo', 'mi', 'corratio_mul', 'crM', 'norm_mutualinfo', 'nmi', 'hellinger', 'hel', 'corratio_add', 'crA', 'corratio_uns', 'crU'] cost = traits.Enum( *_cost_funcs, argstr='-cost %s', desc="""Defines the 'cost' function that defines the matching between the source and the base""") _interp_funcs = [ 'nearestneighbour', 'linear', 'cubic', 'quintic', 'wsinc5'] interpolation = traits.Enum( *_interp_funcs[:-1], argstr='-interp %s', desc='Defines interpolation method to use during matching') final_interpolation = traits.Enum( *_interp_funcs, argstr='-final %s', desc='Defines interpolation method used to create the output dataset') # TECHNICAL OPTIONS (used for fine control of the program): nmatch = traits.Int( argstr='-nmatch %d', desc='Use at most n scattered points to match the datasets.') no_pad = traits.Bool( argstr='-nopad', desc='Do not use zero-padding on the base image.') zclip = traits.Bool( argstr='-zclip', desc='Replace negative values in the input datasets (source & base) with zero.') convergence = traits.Float( argstr='-conv %f', desc='Convergence test in millimeters (default 0.05mm).') usetemp = traits.Bool(argstr='-usetemp', desc='temporary file use') check = traits.List( traits.Enum(*_cost_funcs), argstr='-check %s', desc="""After cost functional optimization is done, start at the final parameters and RE-optimize using this new cost functions. If the results are too different, a warning message will be printed. However, the final parameters from the original optimization will be used to create the output dataset.""") # ** PARAMETERS THAT AFFECT THE COST OPTIMIZATION STRATEGY ** one_pass = traits.Bool( argstr='-onepass', desc="""Use only the refining pass -- do not try a coarse resolution pass first. Useful if you know that only small amounts of image alignment are needed.""") two_pass = traits.Bool( argstr='-twopass', desc="""Use a two pass alignment strategy for all volumes, searching for a large rotation+shift and then refining the alignment.""") two_blur = traits.Float( argstr='-twoblur', desc='Set the blurring radius for the first pass in mm.') two_first = traits.Bool( argstr='-twofirst', desc="""Use -twopass on the first image to be registered, and then on all subsequent images from the source dataset, use results from the first image's coarse pass to start the fine pass.""") two_best = traits.Int( argstr='-twobest %d', desc="""In the coarse pass, use the best 'bb' set of initial points to search for the starting point for the fine pass. If bb==0, then no search is made for the best starting point, and the identity transformation is used as the starting point. [Default=5; min=0 max=11]""") fine_blur = traits.Float( argstr='-fineblur %f', desc="""Set the blurring radius to use in the fine resolution pass to 'x' mm. A small amount (1-2 mm?) of blurring at the fine step may help with convergence, if there is some problem, especially if the base volume is very noisy. [Default == 0 mm = no blurring at the final alignment pass]""") center_of_mass = traits.Str( argstr='-cmass%s', desc='Use the center-of-mass calculation to bracket the shifts.') autoweight = traits.Str( argstr='-autoweight%s', desc="""Compute a weight function using the 3dAutomask algorithm plus some blurring of the base image.""") automask = traits.Int( argstr='-automask+%d', desc="""Compute a mask function, set a value for dilation or 0.""") autobox = traits.Bool( argstr='-autobox', desc="""Expand the -automask function to enclose a rectangular box that holds the irregular mask.""") nomask = traits.Bool( argstr='-nomask', desc="""Don't compute the autoweight/mask; if -weight is not also used, then every voxel will be counted equally.""") weight_file = File( argstr='-weight %s', exists=True, desc="""Set the weighting for each voxel in the base dataset; larger weights mean that voxel count more in the cost function. Must be defined on the same grid as the base dataset""") out_weight_file = traits.File( argstr='-wtprefix %s', desc="""Write the weight volume to disk as a dataset""") source_mask = File( exists=True, argstr='-source_mask %s', desc='mask the input dataset') source_automask = traits.Int( argstr='-source_automask+%d', desc='Automatically mask the source dataset with dilation or 0.') warp_type = traits.Enum( 'shift_only', 'shift_rotate', 'shift_rotate_scale', 'affine_general', argstr='-warp %s', desc='Set the warp type.') warpfreeze = traits.Bool( argstr='-warpfreeze', desc='Freeze the non-rigid body parameters after first volume.') replacebase = traits.Bool( argstr='-replacebase', desc="""If the source has more than one volume, then after the first volume is aligned to the base""") replacemeth = traits.Enum( *_cost_funcs, argstr='-replacemeth %s', desc="""After first volume is aligned, switch method for later volumes. For use with '-replacebase'.""") epi = traits.Bool( argstr='-EPI', desc="""Treat the source dataset as being composed of warped EPI slices, and the base as comprising anatomically 'true' images. Only phase-encoding direction image shearing and scaling will be allowed with this option.""") master = File( exists=True, argstr='-master %s', desc='Write the output dataset on the same grid as this file') newgrid = traits.Float( argstr='-newgrid %f', desc='Write the output dataset using isotropic grid spacing in mm') # Non-linear experimental _nwarp_types = ['bilinear', 'cubic', 'quintic', 'heptic', 'nonic', 'poly3', 'poly5', 'poly7', 'poly9'] # same non-hellenistic nwarp = traits.Enum( *_nwarp_types, argstr='-nwarp %s', desc='Experimental nonlinear warping: bilinear or legendre poly.') _dirs = ['X', 'Y', 'Z', 'I', 'J', 'K'] nwarp_fixmot = traits.List( traits.Enum(*_dirs), argstr='-nwarp_fixmot%s', desc='To fix motion along directions.') nwarp_fixdep = traits.List( traits.Enum(*_dirs), argstr='-nwarp_fixdep%s', desc='To fix non-linear warp dependency along directions.') class AllineateOutputSpec(TraitedSpec): out_file = File(desc='output image file name') matrix = File(desc='matrix to align input file') class Allineate(AFNICommand): """Program to align one dataset (the 'source') to a base dataset For complete details, see the `3dAllineate Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> allineate = afni.Allineate() >>> allineate.inputs.in_file = 'functional.nii' >>> allineate.inputs.out_file= 'functional_allineate.nii' >>> allineate.inputs.in_matrix= 'cmatrix.mat' >>> res = allineate.run() # doctest: +SKIP """ _cmd = '3dAllineate' input_spec = AllineateInputSpec output_spec = AllineateOutputSpec def _format_arg(self, name, trait_spec, value): if name == 'nwarp_fixmot' or name == 'nwarp_fixdep': arg = ' '.join([trait_spec.argstr % v for v in value]) return arg return super(Allineate, self)._format_arg(name, trait_spec, value) def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_file): outputs['out_file'] = self._gen_filename(self.inputs.in_file, suffix=self.inputs.suffix) else: outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] class MaskaveInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dmaskave', argstr='%s', position=-2, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_maskave.1D", desc='output image file name', keep_extension=True, argstr="> %s", name_source="in_file", position=-1) mask = File(desc='matrix to align input file', argstr='-mask %s', position=1, exists=True) quiet = traits.Bool(desc='matrix to align input file', argstr='-quiet', position=2) class Maskave(AFNICommand): """Computes average of all voxels in the input dataset which satisfy the criterion in the options list For complete details, see the `3dmaskave Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> maskave = afni.Maskave() >>> maskave.inputs.in_file = 'functional.nii' >>> maskave.inputs.mask= 'seed_mask.nii' >>> maskave.inputs.quiet= True >>> maskave.cmdline #doctest: +ELLIPSIS '3dmaskave -mask seed_mask.nii -quiet functional.nii > functional_maskave.1D' >>> res = maskave.run() # doctest: +SKIP """ _cmd = '3dmaskave' input_spec = MaskaveInputSpec output_spec = AFNICommandOutputSpec class SkullStripInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dSkullStrip', argstr='-input %s', position=1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_skullstrip", desc='output image file name', argstr='-prefix %s', name_source="in_file") class SkullStrip(AFNICommand): """A program to extract the brain from surrounding tissue from MRI T1-weighted images For complete details, see the `3dSkullStrip Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> skullstrip = afni.SkullStrip() >>> skullstrip.inputs.in_file = 'functional.nii' >>> skullstrip.inputs.args = '-o_ply' >>> res = skullstrip.run() # doctest: +SKIP """ _cmd = '3dSkullStrip' input_spec = SkullStripInputSpec output_spec = AFNICommandOutputSpec class TCatInputSpec(AFNICommandInputSpec): in_files = InputMultiPath( File(exists=True), desc='input file to 3dTcat', argstr=' %s', position=-1, mandatory=True, copyfile=False) out_file = File(name_template="%s_tcat", desc='output image file name', argstr='-prefix %s', name_source="in_files") rlt = traits.Str(desc='options', argstr='-rlt%s', position=1) class TCat(AFNICommand): """Concatenate sub-bricks from input datasets into one big 3D+time dataset For complete details, see the `3dTcat Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> tcat = afni.TCat() >>> tcat.inputs.in_files = ['functional.nii', 'functional2.nii'] >>> tcat.inputs.out_file= 'functional_tcat.nii' >>> tcat.inputs.rlt = '+' >>> res = tcat.run() # doctest: +SKIP """ _cmd = '3dTcat' input_spec = TCatInputSpec output_spec = AFNICommandOutputSpec class FimInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dfim+', argstr=' -input %s', position=1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_fim", desc='output image file name', argstr='-bucket %s', name_source="in_file") ideal_file = File(desc='ideal time series file name', argstr='-ideal_file %s', position=2, mandatory=True, exists=True) fim_thr = traits.Float(desc='fim internal mask threshold value', argstr='-fim_thr %f', position=3) out = traits.Str(desc='Flag to output the specified parameter', argstr='-out %s', position=4) class Fim(AFNICommand): """Program to calculate the cross-correlation of an ideal reference waveform with the measured FMRI time series for each voxel For complete details, see the `3dfim+ Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> fim = afni.Fim() >>> fim.inputs.in_file = 'functional.nii' >>> fim.inputs.ideal_file= 'seed.1D' >>> fim.inputs.out_file = 'functional_corr.nii' >>> fim.inputs.out = 'Correlation' >>> fim.inputs.fim_thr = 0.0009 >>> res = fim.run() # doctest: +SKIP """ _cmd = '3dfim+' input_spec = FimInputSpec output_spec = AFNICommandOutputSpec class TCorrelateInputSpec(AFNICommandInputSpec): xset = File(desc='input xset', argstr=' %s', position=-2, mandatory=True, exists=True, copyfile=False) yset = File(desc='input yset', argstr=' %s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_tcorr", desc='output image file name', argstr='-prefix %s', name_source="xset") pearson = traits.Bool(desc='Correlation is the normal' + ' Pearson correlation coefficient', argstr='-pearson', position=1) polort = traits.Int(desc='Remove polynomical trend of order m', argstr='-polort %d', position=2) class TCorrelate(AFNICommand): """Computes the correlation coefficient between corresponding voxel time series in two input 3D+time datasets 'xset' and 'yset' For complete details, see the `3dTcorrelate Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> tcorrelate = afni.TCorrelate() >>> tcorrelate.inputs.xset= 'u_rc1s1_Template.nii' >>> tcorrelate.inputs.yset = 'u_rc1s2_Template.nii' >>> tcorrelate.inputs.out_file = 'functional_tcorrelate.nii.gz' >>> tcorrelate.inputs.polort = -1 >>> tcorrelate.inputs.pearson = True >>> res = tcarrelate.run() # doctest: +SKIP """ _cmd = '3dTcorrelate' input_spec = TCorrelateInputSpec output_spec = AFNICommandOutputSpec class TCorr1DInputSpec(AFNICommandInputSpec): xset = File(desc = '3d+time dataset input', argstr = ' %s', position = -2, mandatory = True, exists = True, copyfile=False) y_1d = File(desc = '1D time series file input', argstr = ' %s', position = -1, mandatory = True, exists = True) out_file = File(desc = 'output filename prefix', name_template='%s_correlation.nii.gz', argstr = '-prefix %s', name_source = 'xset', keep_extension = True) pearson = traits.Bool(desc='Correlation is the normal' + ' Pearson correlation coefficient', argstr=' -pearson', xor=['spearman','quadrant','ktaub'], position=1) spearman = traits.Bool(desc='Correlation is the' + ' Spearman (rank) correlation coefficient', argstr=' -spearman', xor=['pearson','quadrant','ktaub'], position=1) quadrant = traits.Bool(desc='Correlation is the' + ' quadrant correlation coefficient', argstr=' -quadrant', xor=['pearson','spearman','ktaub'], position=1) ktaub = traits.Bool(desc='Correlation is the' + ' Kendall\'s tau_b correlation coefficient', argstr=' -ktaub', xor=['pearson','spearman','quadrant'], position=1) class TCorr1DOutputSpec(TraitedSpec): out_file = File(desc = 'output file containing correlations', exists = True) class TCorr1D(AFNICommand): """Computes the correlation coefficient between each voxel time series in the input 3D+time dataset. For complete details, see the `3dTcorr1D Documentation. `_ >>> from nipype.interfaces import afni as afni >>> tcorr1D = afni.TCorr1D() >>> tcorr1D.inputs.xset= 'u_rc1s1_Template.nii' >>> tcorr1D.inputs.y_1d = 'seed.1D' >>> tcorr1D.cmdline '3dTcorr1D -prefix u_rc1s1_Template_correlation.nii.gz u_rc1s1_Template.nii seed.1D' >>> res = tcorr1D.run() # doctest: +SKIP """ _cmd = '3dTcorr1D' input_spec = TCorr1DInputSpec output_spec = TCorr1DOutputSpec class BrickStatInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dmaskave', argstr='%s', position=-1, mandatory=True, exists=True) mask = File(desc='-mask dset = use dset as mask to include/exclude voxels', argstr='-mask %s', position=2, exists=True) min = traits.Bool(desc='print the minimum value in dataset', argstr='-min', position=1) class BrickStatOutputSpec(TraitedSpec): min_val = traits.Float(desc='output') class BrickStat(AFNICommand): """Compute maximum and/or minimum voxel values of an input dataset For complete details, see the `3dBrickStat Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> brickstat = afni.BrickStat() >>> brickstat.inputs.in_file = 'functional.nii' >>> brickstat.inputs.mask = 'skeleton_mask.nii.gz' >>> brickstat.inputs.min = True >>> res = brickstat.run() # doctest: +SKIP """ _cmd = '3dBrickStat' input_spec = BrickStatInputSpec output_spec = BrickStatOutputSpec def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() outfile = os.path.join(os.getcwd(), 'stat_result.json') if runtime is None: try: min_val = load_json(outfile)['stat'] except IOError: return self.run().outputs else: min_val = [] for line in runtime.stdout.split('\n'): if line: values = line.split() if len(values) > 1: min_val.append([float(val) for val in values]) else: min_val.extend([float(val) for val in values]) if len(min_val) == 1: min_val = min_val[0] save_json(outfile, dict(stat=min_val)) outputs.min_val = min_val return outputs class ROIStatsInputSpec(CommandLineInputSpec): in_file = File(desc='input file to 3dROIstats', argstr='%s', position=-1, mandatory=True, exists=True) mask = File(desc='input mask', argstr='-mask %s', position=3, exists=True) mask_f2short = traits.Bool( desc='Tells the program to convert a float mask ' + 'to short integers, by simple rounding.', argstr='-mask_f2short', position=2) quiet = traits.Bool(desc='execute quietly', argstr='-quiet', position=1) terminal_output = traits.Enum('allatonce', desc=('Control terminal output:' '`allatonce` - waits till command is ' 'finished to display output'), nohash=True, mandatory=True, usedefault=True) class ROIStatsOutputSpec(TraitedSpec): stats = File(desc='output tab separated values file', exists=True) class ROIStats(CommandLine): """Display statistics over masked regions For complete details, see the `3dROIstats Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> roistats = afni.ROIStats() >>> roistats.inputs.in_file = 'functional.nii' >>> roistats.inputs.mask = 'skeleton_mask.nii.gz' >>> roistats.inputs.quiet=True >>> res = roistats.run() # doctest: +SKIP """ _cmd = '3dROIstats' input_spec = ROIStatsInputSpec output_spec = ROIStatsOutputSpec def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() output_filename = "roi_stats.csv" f = open(output_filename, "w") f.write(runtime.stdout) f.close() outputs.stats = os.path.abspath(output_filename) return outputs class CalcInputSpec(AFNICommandInputSpec): in_file_a = File(desc='input file to 3dcalc', argstr='-a %s', position=0, mandatory=True, exists=True) in_file_b = File(desc='operand file to 3dcalc', argstr=' -b %s', position=1, exists=True) in_file_c = File(desc='operand file to 3dcalc', argstr=' -c %s', position=2, exists=True) out_file = File(name_template="%s_calc", desc='output image file name', argstr='-prefix %s', name_source="in_file_a") expr = traits.Str(desc='expr', argstr='-expr "%s"', position=3, mandatory=True) start_idx = traits.Int(desc='start index for in_file_a', requires=['stop_idx']) stop_idx = traits.Int(desc='stop index for in_file_a', requires=['start_idx']) single_idx = traits.Int(desc='volume index for in_file_a') other = File(desc='other options', argstr='') class Calc(AFNICommand): """This program does voxel-by-voxel arithmetic on 3D datasets For complete details, see the `3dcalc Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> calc = afni.Calc() >>> calc.inputs.in_file_a = 'functional.nii' >>> calc.inputs.in_file_b = 'functional2.nii' >>> calc.inputs.expr='a*b' >>> calc.inputs.out_file = 'functional_calc.nii.gz' >>> calc.inputs.outputtype = "NIFTI" >>> calc.cmdline #doctest: +ELLIPSIS '3dcalc -a functional.nii -b functional2.nii -expr "a*b" -prefix functional_calc.nii.gz' """ _cmd = '3dcalc' input_spec = CalcInputSpec output_spec = AFNICommandOutputSpec def _format_arg(self, name, trait_spec, value): if name == 'in_file_a': arg = trait_spec.argstr % value if isdefined(self.inputs.start_idx): arg += '[%d..%d]' % (self.inputs.start_idx, self.inputs.stop_idx) if isdefined(self.inputs.single_idx): arg += '[%d]' % (self.inputs.single_idx) return arg return super(Calc, self)._format_arg(name, trait_spec, value) def _parse_inputs(self, skip=None): """Skip the arguments without argstr metadata """ return super(Calc, self)._parse_inputs( skip=('start_idx', 'stop_idx', 'other')) class BlurInMaskInputSpec(AFNICommandInputSpec): in_file = File( desc='input file to 3dSkullStrip', argstr='-input %s', position=1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template='%s_blur', desc='output to the file', argstr='-prefix %s', name_source='in_file', position=-1) mask = File( desc='Mask dataset, if desired. Blurring will occur only within the mask. Voxels NOT in the mask will be set to zero in the output.', argstr='-mask %s') multimask = File( desc='Multi-mask dataset -- each distinct nonzero value in dataset will be treated as a separate mask for blurring purposes.', argstr='-Mmask %s') automask = traits.Bool( desc='Create an automask from the input dataset.', argstr='-automask') fwhm = traits.Float( desc='fwhm kernel size', argstr='-FWHM %f', mandatory=True) preserve = traits.Bool( desc='Normally, voxels not in the mask will be set to zero in the output. If you want the original values in the dataset to be preserved in the output, use this option.', argstr='-preserve') float_out = traits.Bool( desc='Save dataset as floats, no matter what the input data type is.', argstr='-float') options = traits.Str(desc='options', argstr='%s', position=2) class BlurInMask(AFNICommand): """ Blurs a dataset spatially inside a mask. That's all. Experimental. For complete details, see the `3dBlurInMask Documentation. Examples ======== >>> from nipype.interfaces import afni as afni >>> bim = afni.BlurInMask() >>> bim.inputs.in_file = 'functional.nii' >>> bim.inputs.mask = 'mask.nii' >>> bim.inputs.fwhm = 5.0 >>> bim.cmdline #doctest: +ELLIPSIS '3dBlurInMask -input functional.nii -FWHM 5.000000 -mask mask.nii -prefix functional_blur' >>> res = bim.run() # doctest: +SKIP """ _cmd = '3dBlurInMask' input_spec = BlurInMaskInputSpec output_spec = AFNICommandOutputSpec class TCorrMapInputSpec(AFNICommandInputSpec): in_file = File(exists=True, argstr='-input %s', mandatory=True, copyfile=False) seeds = File(exists=True, argstr='-seed %s', xor=('seeds_width')) mask = File(exists=True, argstr='-mask %s') automask = traits.Bool(argstr='-automask') polort = traits.Int(argstr='-polort %d') bandpass = traits.Tuple((traits.Float(), traits.Float()), argstr='-bpass %f %f') regress_out_timeseries = traits.File(exists=True, argstr='-ort %s') blur_fwhm = traits.Float(argstr='-Gblur %f') seeds_width = traits.Float(argstr='-Mseed %f', xor=('seeds')) # outputs mean_file = File(argstr='-Mean %s', suffix='_mean', name_source="in_file") zmean = File(argstr='-Zmean %s', suffix='_zmean', name_source="in_file") qmean = File(argstr='-Qmean %s', suffix='_qmean', name_source="in_file") pmean = File(argstr='-Pmean %s', suffix='_pmean', name_source="in_file") _thresh_opts = ('absolute_threshold', 'var_absolute_threshold', 'var_absolute_threshold_normalize') thresholds = traits.List(traits.Int()) absolute_threshold = File( argstr='-Thresh %f %s', suffix='_thresh', name_source="in_file", xor=_thresh_opts) var_absolute_threshold = File( argstr='-VarThresh %f %f %f %s', suffix='_varthresh', name_source="in_file", xor=_thresh_opts) var_absolute_threshold_normalize = File( argstr='-VarThreshN %f %f %f %s', suffix='_varthreshn', name_source="in_file", xor=_thresh_opts) correlation_maps = File( argstr='-CorrMap %s', name_source="in_file") correlation_maps_masked = File( argstr='-CorrMask %s', name_source="in_file") _expr_opts = ('average_expr', 'average_expr_nonzero', 'sum_expr') expr = traits.Str() average_expr = File( argstr='-Aexpr %s %s', suffix='_aexpr', name_source='in_file', xor=_expr_opts) average_expr_nonzero = File( argstr='-Cexpr %s %s', suffix='_cexpr', name_source='in_file', xor=_expr_opts) sum_expr = File( argstr='-Sexpr %s %s', suffix='_sexpr', name_source='in_file', xor=_expr_opts) histogram_bin_numbers = traits.Int() histogram = File( name_source='in_file', argstr='-Hist %d %s', suffix='_hist') class TCorrMapOutputSpec(TraitedSpec): mean_file = File() zmean = File() qmean = File() pmean = File() absolute_threshold = File() var_absolute_threshold = File() var_absolute_threshold_normalize = File() correlation_maps = File() correlation_maps_masked = File() average_expr = File() average_expr_nonzero = File() sum_expr = File() histogram = File() class TCorrMap(AFNICommand): """ For each voxel time series, computes the correlation between it and all other voxels, and combines this set of values into the output dataset(s) in some way. For complete details, see the `3dTcorrMap Documentation. Examples ======== >>> from nipype.interfaces import afni as afni >>> tcm = afni.TCorrMap() >>> tcm.inputs.in_file = 'functional.nii' >>> tcm.inputs.mask = 'mask.nii' >>> tcm.mean_file = '%s_meancorr.nii' >>> res = tcm.run() # doctest: +SKIP """ _cmd = '3dTcorrMap' input_spec = TCorrMapInputSpec output_spec = TCorrMapOutputSpec _additional_metadata = ['suffix'] def _format_arg(self, name, trait_spec, value): if name in self.inputs._thresh_opts: return trait_spec.argstr % self.inputs.thresholds + [value] elif name in self.inputs._expr_opts: return trait_spec.argstr % (self.inputs.expr, value) elif name == 'histogram': return trait_spec.argstr % (self.inputs.histogram_bin_numbers, value) else: return super(TCorrMap, self)._format_arg(name, trait_spec, value) class AutoboxInputSpec(AFNICommandInputSpec): in_file = File(exists=True, mandatory=True, argstr='-input %s', desc='input file', copyfile=False) padding = traits.Int( argstr='-npad %d', desc='Number of extra voxels to pad on each side of box') out_file = File(argstr="-prefix %s", name_source="in_file") no_clustering = traits.Bool( argstr='-noclust', desc="""Don't do any clustering to find box. Any non-zero voxel will be preserved in the cropped volume. The default method uses some clustering to find the cropping box, and will clip off small isolated blobs.""") class AutoboxOuputSpec(TraitedSpec): # out_file not mandatory x_min = traits.Int() x_max = traits.Int() y_min = traits.Int() y_max = traits.Int() z_min = traits.Int() z_max = traits.Int() out_file = File(desc='output file') class Autobox(AFNICommand): """ Computes size of a box that fits around the volume. Also can be used to crop the volume to that box. For complete details, see the `3dAutobox Documentation. Examples ======== >>> from nipype.interfaces import afni as afni >>> abox = afni.Autobox() >>> abox.inputs.in_file = 'structural.nii' >>> abox.inputs.padding = 5 >>> res = abox.run() # doctest: +SKIP """ _cmd = '3dAutobox' input_spec = AutoboxInputSpec output_spec = AutoboxOuputSpec def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() pattern = 'x=(?P-?\d+)\.\.(?P-?\d+) y=(?P-?\d+)\.\.(?P-?\d+) z=(?P-?\d+)\.\.(?P-?\d+)' for line in runtime.stderr.split('\n'): m = re.search(pattern, line) if m: d = m.groupdict() for k in d.keys(): d[k] = int(d[k]) outputs.set(**d) outputs.set(out_file=self._gen_filename('out_file')) return outputs def _gen_filename(self, name): if name == 'out_file' and (not isdefined(self.inputs.out_file)): return Undefined return super(Autobox, self)._gen_filename(name) class RetroicorInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dretroicor', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(desc='output image file name', argstr='-prefix %s', mandatory=True, position=1) card = File(desc='1D cardiac data file for cardiac correction', argstr='-card %s', position=-2, exists=True) resp = File(desc='1D respiratory waveform data for correction', argstr='-resp %s', position=-3, exists=True) threshold = traits.Int(desc='Threshold for detection of R-wave peaks in input (Make sure it is above the background noise level, Try 3/4 or 4/5 times range plus minimum)', argstr='-threshold %d', position=-4) order = traits.Int(desc='The order of the correction (2 is typical)', argstr='-order %s', position=-5) cardphase = File(desc='Filename for 1D cardiac phase output', argstr='-cardphase %s', position=-6, hash_files=False) respphase = File(desc='Filename for 1D resp phase output', argstr='-respphase %s', position=-7, hash_files=False) class Retroicor(AFNICommand): """Performs Retrospective Image Correction for physiological motion effects, using a slightly modified version of the RETROICOR algorithm The durations of the physiological inputs are assumed to equal the duration of the dataset. Any constant sampling rate may be used, but 40 Hz seems to be acceptable. This program's cardiac peak detection algorithm is rather simplistic, so you might try using the scanner's cardiac gating output (transform it to a spike wave if necessary). This program uses slice timing information embedded in the dataset to estimate the proper cardiac/respiratory phase for each slice. It makes sense to run this program before any program that may destroy the slice timings (e.g. 3dvolreg for motion correction). For complete details, see the `3dretroicor Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> ret = afni.Retroicor() >>> ret.inputs.in_file = 'functional.nii' >>> ret.inputs.card = 'mask.1D' >>> ret.inputs.resp = 'resp.1D' >>> res = ret.run() # doctest: +SKIP """ _cmd = '3dretroicor' input_spec = RetroicorInputSpec output_spec = AFNICommandOutputSpec class AFNItoNIFTIInputSpec(AFNICommandInputSpec): in_file = File(desc='input file to 3dAFNItoNIFTI', argstr='%s', position=-1, mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s.nii", desc='output image file name', argstr='-prefix %s', name_source="in_file") hash_files = False class AFNItoNIFTI(AFNICommand): """Changes AFNI format files to NIFTI format using 3dAFNItoNIFTI see AFNI Documentation: this can also convert 2D or 1D data, which you can numpy.squeeze() to remove extra dimensions Examples ======== >>> from nipype.interfaces import afni as afni >>> a2n = afni.AFNItoNIFTI() >>> a2n.inputs.in_file = 'afni_output.3D' >>> a2n.inputs.out_file = 'afni_output.nii' >>> a2n.cmdline '3dAFNItoNIFTI -prefix afni_output.nii afni_output.3D' """ _cmd = '3dAFNItoNIFTI' input_spec = AFNItoNIFTIInputSpec output_spec = AFNICommandOutputSpec def _overload_extension(self, value): path, base, ext = split_filename(value) if ext.lower() not in [".1d", ".nii.gz", ".1D"]: ext = ext + ".nii" return os.path.join(path, base + ext) def _gen_filename(self, name): return os.path.abspath(super(AFNItoNIFTI, self)._gen_filename(name)) class EvalInputSpec(AFNICommandInputSpec): in_file_a = File(desc='input file to 1deval', argstr='-a %s', position=0, mandatory=True, exists=True) in_file_b = File(desc='operand file to 1deval', argstr=' -b %s', position=1, exists=True) in_file_c = File(desc='operand file to 1deval', argstr=' -c %s', position=2, exists=True) out_file = File(name_template="%s_calc", desc='output image file name', argstr='-prefix %s', name_source="in_file_a") out1D = traits.Bool(desc="output in 1D", argstr='-1D') expr = traits.Str(desc='expr', argstr='-expr "%s"', position=3, mandatory=True) start_idx = traits.Int(desc='start index for in_file_a', requires=['stop_idx']) stop_idx = traits.Int(desc='stop index for in_file_a', requires=['start_idx']) single_idx = traits.Int(desc='volume index for in_file_a') other = File(desc='other options', argstr='') class Eval(AFNICommand): """Evaluates an expression that may include columns of data from one or more text files see AFNI Documentation: Examples ======== >>> from nipype.interfaces import afni as afni >>> eval = afni.Eval() >>> eval.inputs.in_file_a = 'seed.1D' >>> eval.inputs.in_file_b = 'resp.1D' >>> eval.inputs.expr='a*b' >>> eval.inputs.out1D = True >>> eval.inputs.out_file = 'data_calc.1D' >>> calc.cmdline #doctest: +SKIP '3deval -a timeseries1.1D -b timeseries2.1D -expr "a*b" -1D -prefix data_calc.1D' """ _cmd = '1deval' input_spec = EvalInputSpec output_spec = AFNICommandOutputSpec def _format_arg(self, name, trait_spec, value): if name == 'in_file_a': arg = trait_spec.argstr % value if isdefined(self.inputs.start_idx): arg += '[%d..%d]' % (self.inputs.start_idx, self.inputs.stop_idx) if isdefined(self.inputs.single_idx): arg += '[%d]' % (self.inputs.single_idx) return arg return super(Eval, self)._format_arg(name, trait_spec, value) def _parse_inputs(self, skip=None): """Skip the arguments without argstr metadata """ return super(Eval, self)._parse_inputs( skip=('start_idx', 'stop_idx', 'out1D', 'other')) class MeansInputSpec(AFNICommandInputSpec): in_file_a = File(desc='input file to 3dMean', argstr='%s', position=0, mandatory=True, exists=True) in_file_b = File(desc='another input file to 3dMean', argstr='%s', position=1, exists=True) out_file = File(name_template="%s_mean", desc='output image file name', argstr='-prefix %s', name_source="in_file_a") scale = traits.Str(desc='scaling of output', argstr='-%sscale') non_zero = traits.Bool(desc='use only non-zero values', argstr='-non_zero') std_dev = traits.Bool(desc='calculate std dev', argstr='-stdev') sqr = traits.Bool(desc='mean square instead of value', argstr='-sqr') summ = traits.Bool(desc='take sum, (not average)', argstr='-sum') count = traits.Bool(desc='compute count of non-zero voxels', argstr='-count') mask_inter = traits.Bool(desc='create intersection mask', argstr='-mask_inter') mask_union = traits.Bool(desc='create union mask', argstr='-mask_union') class Means(AFNICommand): """Takes the voxel-by-voxel mean of all input datasets using 3dMean see AFNI Documentation: Examples ======== >>> from nipype.interfaces import afni as afni >>> means = afni.Means() >>> means.inputs.in_file_a = 'im1.nii' >>> means.inputs.in_file_b = 'im2.nii' >>> means.inputs.out_file = 'output.nii' >>> means.cmdline '3dMean im1.nii im2.nii -prefix output.nii' """ _cmd = '3dMean' input_spec = MeansInputSpec output_spec = AFNICommandOutputSpec nipype-0.11.0/nipype/interfaces/afni/svm.py000066400000000000000000000145341257611314500206340ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft = python sts = 4 ts = 4 sw = 4 et: """Afni svm interfaces Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import warnings import os import re from ..base import (Directory, TraitedSpec, traits, isdefined, File, InputMultiPath, Undefined) from ...utils.filemanip import (load_json, save_json, split_filename) from nipype.utils.filemanip import fname_presuffix from .base import AFNICommand, AFNICommandInputSpec,\ AFNICommandOutputSpec from nipype.interfaces.base import CommandLineInputSpec, CommandLine,\ OutputMultiPath warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class SVMTrainInputSpec(AFNICommandInputSpec): #training options ttype = traits.Str(desc='tname: classification or regression', argstr='-type %s', mandatory=True) in_file = File(desc='A 3D+t AFNI brik dataset to be used for training.', argstr='-trainvol %s', mandatory=True, exists=True, copyfile=False) out_file = File(name_template="%s_vectors", desc='output sum of weighted linear support vectors file name', argstr='-bucket %s', suffix='_bucket', name_source="in_file") model = File(name_template="%s_model", desc='basename for the brik containing the SVM model', argstr='-model %s', suffix='_model', name_source="in_file") alphas = File(name_template="%s_alphas", desc='output alphas file name', argstr='-alpha %s', suffix='_alphas', name_source="in_file") mask = File(desc='byte-format brik file used to mask voxels in the analysis', argstr='-mask %s', position=-1, exists=True, copyfile=False) nomodelmask = traits.Bool(desc='Flag to enable the omission of a mask file', argstr='-nomodelmask') trainlabels = File(desc='.1D labels corresponding to the stimulus paradigm for the training data.', argstr='-trainlabels %s', exists=True) censor = File(desc='.1D censor file that allows the user to ignore certain samples in the training data.', argstr='-censor %s', exists=True) kernel = traits.Str(desc='string specifying type of kernel function:linear, polynomial, rbf, sigmoid', argstr='-kernel %s') max_iterations = traits.Int(desc='Specify the maximum number of iterations for the optimization.', argstr='-max_iterations %d') w_out = traits.Bool(desc='output sum of weighted linear support vectors', argstr='-wout') options = traits.Str(desc='additional options for SVM-light', argstr='%s') class SVMTrainOutputSpec(TraitedSpec): out_file = File(desc='sum of weighted linear support vectors file name') model = File(desc='brik containing the SVM model file name') alphas = File(desc='output alphas file name') class SVMTrain(AFNICommand): """Temporally predictive modeling with the support vector machine SVM Train Only For complete details, see the `3dsvm Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> svmTrain = afni.SVMTrain() >>> svmTrain.inputs.in_file = 'run1+orig' >>> svmTrain.inputs.trainlabels = 'run1_categories.1D' >>> svmTrain.inputs.ttype = 'regression' >>> svmTrain.inputs.mask = 'mask.nii' >>> svmTrain.inputs.model = 'model_run1' >>> svmTrain.inputs.alphas = 'alphas_run1' >>> res = svmTrain.run() # doctest: +SKIP """ _cmd = '3dsvm' input_spec = SVMTrainInputSpec output_spec = SVMTrainOutputSpec _additional_metadata = ['suffix'] def _format_arg(self, name, trait_spec, value): return super(SVMTrain, self)._format_arg(name, trait_spec, value) class SVMTestInputSpec(AFNICommandInputSpec): #testing options model = traits.Str(desc='modname is the basename for the brik containing the SVM model', argstr='-model %s', mandatory=True) in_file = File(desc='A 3D or 3D+t AFNI brik dataset to be used for testing.', argstr='-testvol %s', exists=True, mandatory=True) out_file = File(name_template="%s_predictions", desc='filename for .1D prediction file(s).', argstr='-predictions %s') testlabels = File(desc='*true* class category .1D labels for the test dataset. It is used to calculate the prediction accuracy performance', exists=True, argstr='-testlabels %s') classout = traits.Bool(desc='Flag to specify that pname files should be integer-valued, corresponding to class category decisions.', argstr='-classout') nopredcensord = traits.Bool(desc='Flag to prevent writing predicted values for censored time-points', argstr='-nopredcensord') nodetrend = traits.Bool(desc='Flag to specify that pname files should not be linearly detrended', argstr='-nodetrend') multiclass = traits.Bool(desc='Specifies multiclass algorithm for classification', argstr='-multiclass %s') options = traits.Str(desc='additional options for SVM-light', argstr='%s') class SVMTest(AFNICommand): """Temporally predictive modeling with the support vector machine SVM Test Only For complete details, see the `3dsvm Documentation. `_ Examples ======== >>> from nipype.interfaces import afni as afni >>> svmTest = afni.SVMTest() >>> svmTest.inputs.in_file= 'run2+orig' >>> svmTest.inputs.model= 'run1+orig_model' >>> svmTest.inputs.testlabels= 'run2_categories.1D' >>> svmTest.inputs.out_file= 'pred2_model1' >>> res = svmTest.run() # doctest: +SKIP """ _cmd = '3dsvm' input_spec = SVMTestInputSpec output_spec = AFNICommandOutputSpec nipype-0.11.0/nipype/interfaces/afni/tests/000077500000000000000000000000001257611314500206105ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/afni/tests/__init__.py000066400000000000000000000001621257611314500227200ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_AFNICommand.py000066400000000000000000000013461257611314500252710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.base import AFNICommand def test_AFNICommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='-prefix %s', name_source=['in_file'], name_template='%s_afni', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = AFNICommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_AFNItoNIFTI.py000066400000000000000000000021521257611314500251230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import AFNItoNIFTI def test_AFNItoNIFTI_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s.nii', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = AFNItoNIFTI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AFNItoNIFTI_outputs(): output_map = dict(out_file=dict(), ) outputs = AFNItoNIFTI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Allineate.py000066400000000000000000000057541257611314500251620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Allineate def test_Allineate_inputs(): input_map = dict(args=dict(argstr='%s', ), autobox=dict(argstr='-autobox', ), automask=dict(argstr='-automask+%d', ), autoweight=dict(argstr='-autoweight%s', ), center_of_mass=dict(argstr='-cmass%s', ), check=dict(argstr='-check %s', ), convergence=dict(argstr='-conv %f', ), cost=dict(argstr='-cost %s', ), environ=dict(nohash=True, usedefault=True, ), epi=dict(argstr='-EPI', ), final_interpolation=dict(argstr='-final %s', ), fine_blur=dict(argstr='-fineblur %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-source %s', copyfile=False, mandatory=True, position=-1, ), in_matrix=dict(argstr='-1Dmatrix_apply %s', position=-3, ), in_param_file=dict(argstr='-1Dparam_apply %s', ), interpolation=dict(argstr='-interp %s', ), master=dict(argstr='-master %s', ), newgrid=dict(argstr='-newgrid %f', ), nmatch=dict(argstr='-nmatch %d', ), no_pad=dict(argstr='-nopad', ), nomask=dict(argstr='-nomask', ), nwarp=dict(argstr='-nwarp %s', ), nwarp_fixdep=dict(argstr='-nwarp_fixdep%s', ), nwarp_fixmot=dict(argstr='-nwarp_fixmot%s', ), one_pass=dict(argstr='-onepass', ), out_file=dict(argstr='-prefix %s', genfile=True, name_source='%s_allineate', position=-2, ), out_matrix=dict(argstr='-1Dmatrix_save %s', ), out_param_file=dict(argstr='-1Dparam_save %s', ), out_weight_file=dict(argstr='-wtprefix %s', ), outputtype=dict(), reference=dict(argstr='-base %s', ), replacebase=dict(argstr='-replacebase', ), replacemeth=dict(argstr='-replacemeth %s', ), source_automask=dict(argstr='-source_automask+%d', ), source_mask=dict(argstr='-source_mask %s', ), terminal_output=dict(nohash=True, ), two_best=dict(argstr='-twobest %d', ), two_blur=dict(argstr='-twoblur', ), two_first=dict(argstr='-twofirst', ), two_pass=dict(argstr='-twopass', ), usetemp=dict(argstr='-usetemp', ), warp_type=dict(argstr='-warp %s', ), warpfreeze=dict(argstr='-warpfreeze', ), weight_file=dict(argstr='-weight %s', ), zclip=dict(argstr='-zclip', ), ) inputs = Allineate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Allineate_outputs(): output_map = dict(matrix=dict(), out_file=dict(), ) outputs = Allineate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_AutoTcorrelate.py000066400000000000000000000026601257611314500262120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import AutoTcorrelate def test_AutoTcorrelate_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), eta2=dict(argstr='-eta2', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), mask=dict(argstr='-mask %s', ), mask_only_targets=dict(argstr='-mask_only_targets', xor=['mask_source'], ), mask_source=dict(argstr='-mask_source %s', xor=['mask_only_targets'], ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_similarity_matrix.1D', ), outputtype=dict(), polort=dict(argstr='-polort %d', ), terminal_output=dict(nohash=True, ), ) inputs = AutoTcorrelate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AutoTcorrelate_outputs(): output_map = dict(out_file=dict(), ) outputs = AutoTcorrelate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Autobox.py000066400000000000000000000023701257611314500246740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Autobox def test_Autobox_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-input %s', copyfile=False, mandatory=True, ), no_clustering=dict(argstr='-noclust', ), out_file=dict(argstr='-prefix %s', name_source='in_file', ), outputtype=dict(), padding=dict(argstr='-npad %d', ), terminal_output=dict(nohash=True, ), ) inputs = Autobox.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Autobox_outputs(): output_map = dict(out_file=dict(), x_max=dict(), x_min=dict(), y_max=dict(), y_min=dict(), z_max=dict(), z_min=dict(), ) outputs = Autobox.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Automask.py000066400000000000000000000025451257611314500250430ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Automask def test_Automask_inputs(): input_map = dict(args=dict(argstr='%s', ), brain_file=dict(argstr='-apply_prefix %s', name_source='in_file', name_template='%s_masked', ), clfrac=dict(argstr='-clfrac %s', ), dilate=dict(argstr='-dilate %s', ), environ=dict(nohash=True, usedefault=True, ), erode=dict(argstr='-erode %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_mask', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Automask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Automask_outputs(): output_map = dict(brain_file=dict(), out_file=dict(), ) outputs = Automask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Bandpass.py000066400000000000000000000034641257611314500250130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Bandpass def test_Bandpass_inputs(): input_map = dict(args=dict(argstr='%s', ), automask=dict(argstr='-automask', ), blur=dict(argstr='-blur %f', ), despike=dict(argstr='-despike', ), environ=dict(nohash=True, usedefault=True, ), highpass=dict(argstr='%f', mandatory=True, position=-3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), localPV=dict(argstr='-localPV %f', ), lowpass=dict(argstr='%f', mandatory=True, position=-2, ), mask=dict(argstr='-mask %s', position=2, ), nfft=dict(argstr='-nfft %d', ), no_detrend=dict(argstr='-nodetrend', ), normalize=dict(argstr='-norm', ), notrans=dict(argstr='-notrans', ), orthogonalize_dset=dict(argstr='-dsort %s', ), orthogonalize_file=dict(argstr='-ort %s', ), out_file=dict(argstr='-prefix %s', genfile=True, name_source='in_file', name_template='%s_bp', position=1, ), outputtype=dict(), terminal_output=dict(nohash=True, ), tr=dict(argstr='-dt %f', ), ) inputs = Bandpass.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Bandpass_outputs(): output_map = dict(out_file=dict(), ) outputs = Bandpass.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_BlurInMask.py000066400000000000000000000027111257611314500252610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import BlurInMask def test_BlurInMask_inputs(): input_map = dict(args=dict(argstr='%s', ), automask=dict(argstr='-automask', ), environ=dict(nohash=True, usedefault=True, ), float_out=dict(argstr='-float', ), fwhm=dict(argstr='-FWHM %f', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-input %s', copyfile=False, mandatory=True, position=1, ), mask=dict(argstr='-mask %s', ), multimask=dict(argstr='-Mmask %s', ), options=dict(argstr='%s', position=2, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_blur', position=-1, ), outputtype=dict(), preserve=dict(argstr='-preserve', ), terminal_output=dict(nohash=True, ), ) inputs = BlurInMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BlurInMask_outputs(): output_map = dict(out_file=dict(), ) outputs = BlurInMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_BrickStat.py000066400000000000000000000022711257611314500251410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import BrickStat def test_BrickStat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-1, ), mask=dict(argstr='-mask %s', position=2, ), min=dict(argstr='-min', position=1, ), out_file=dict(argstr='-prefix %s', name_source=['in_file'], name_template='%s_afni', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = BrickStat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BrickStat_outputs(): output_map = dict(min_val=dict(), ) outputs = BrickStat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Calc.py000066400000000000000000000026301257611314500241140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Calc def test_Calc_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), expr=dict(argstr='-expr "%s"', mandatory=True, position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file_a=dict(argstr='-a %s', mandatory=True, position=0, ), in_file_b=dict(argstr=' -b %s', position=1, ), in_file_c=dict(argstr=' -c %s', position=2, ), other=dict(argstr='', ), out_file=dict(argstr='-prefix %s', name_source='in_file_a', name_template='%s_calc', ), outputtype=dict(), single_idx=dict(), start_idx=dict(requires=['stop_idx'], ), stop_idx=dict(requires=['start_idx'], ), terminal_output=dict(nohash=True, ), ) inputs = Calc.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Calc_outputs(): output_map = dict(out_file=dict(), ) outputs = Calc.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Copy.py000066400000000000000000000021211257611314500241570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Copy def test_Copy_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-2, ), out_file=dict(argstr='%s', name_source='in_file', name_template='%s_copy', position=-1, ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Copy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Copy_outputs(): output_map = dict(out_file=dict(), ) outputs = Copy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Despike.py000066400000000000000000000021321257611314500246330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Despike def test_Despike_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_despike', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Despike.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Despike_outputs(): output_map = dict(out_file=dict(), ) outputs = Despike.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Detrend.py000066400000000000000000000021321257611314500246340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Detrend def test_Detrend_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_detrend', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Detrend.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Detrend_outputs(): output_map = dict(out_file=dict(), ) outputs = Detrend.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Eval.py000066400000000000000000000026741257611314500241510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Eval def test_Eval_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), expr=dict(argstr='-expr "%s"', mandatory=True, position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file_a=dict(argstr='-a %s', mandatory=True, position=0, ), in_file_b=dict(argstr=' -b %s', position=1, ), in_file_c=dict(argstr=' -c %s', position=2, ), other=dict(argstr='', ), out1D=dict(argstr='-1D', ), out_file=dict(argstr='-prefix %s', name_source='in_file_a', name_template='%s_calc', ), outputtype=dict(), single_idx=dict(), start_idx=dict(requires=['stop_idx'], ), stop_idx=dict(requires=['start_idx'], ), terminal_output=dict(nohash=True, ), ) inputs = Eval.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Eval_outputs(): output_map = dict(out_file=dict(), ) outputs = Eval.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Fim.py000066400000000000000000000024251257611314500237670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Fim def test_Fim_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fim_thr=dict(argstr='-fim_thr %f', position=3, ), ideal_file=dict(argstr='-ideal_file %s', mandatory=True, position=2, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr=' -input %s', copyfile=False, mandatory=True, position=1, ), out=dict(argstr='-out %s', position=4, ), out_file=dict(argstr='-bucket %s', name_source='in_file', name_template='%s_fim', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Fim.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Fim_outputs(): output_map = dict(out_file=dict(), ) outputs = Fim.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Fourier.py000066400000000000000000000024001257611314500246600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Fourier def test_Fourier_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), highpass=dict(argstr='-highpass %f', mandatory=True, position=1, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), lowpass=dict(argstr='-lowpass %f', mandatory=True, position=0, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_fourier', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Fourier.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Fourier_outputs(): output_map = dict(out_file=dict(), ) outputs = Fourier.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Maskave.py000066400000000000000000000023601257611314500246410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Maskave def test_Maskave_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-2, ), mask=dict(argstr='-mask %s', position=1, ), out_file=dict(argstr='> %s', keep_extension=True, name_source='in_file', name_template='%s_maskave.1D', position=-1, ), outputtype=dict(), quiet=dict(argstr='-quiet', position=2, ), terminal_output=dict(nohash=True, ), ) inputs = Maskave.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Maskave_outputs(): output_map = dict(out_file=dict(), ) outputs = Maskave.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Means.py000066400000000000000000000027021257611314500243150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Means def test_Means_inputs(): input_map = dict(args=dict(argstr='%s', ), count=dict(argstr='-count', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file_a=dict(argstr='%s', mandatory=True, position=0, ), in_file_b=dict(argstr='%s', position=1, ), mask_inter=dict(argstr='-mask_inter', ), mask_union=dict(argstr='-mask_union', ), non_zero=dict(argstr='-non_zero', ), out_file=dict(argstr='-prefix %s', name_source='in_file_a', name_template='%s_mean', ), outputtype=dict(), scale=dict(argstr='-%sscale', ), sqr=dict(argstr='-sqr', ), std_dev=dict(argstr='-stdev', ), summ=dict(argstr='-sum', ), terminal_output=dict(nohash=True, ), ) inputs = Means.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Means_outputs(): output_map = dict(out_file=dict(), ) outputs = Means.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Merge.py000066400000000000000000000022701257611314500243110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Merge def test_Merge_inputs(): input_map = dict(args=dict(argstr='%s', ), blurfwhm=dict(argstr='-1blur_fwhm %d', units='mm', ), doall=dict(argstr='-doall', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_merge', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = Merge.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Merge_outputs(): output_map = dict(out_file=dict(), ) outputs = Merge.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_ROIStats.py000066400000000000000000000022451257611314500247240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import ROIStats def test_ROIStats_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-1, ), mask=dict(argstr='-mask %s', position=3, ), mask_f2short=dict(argstr='-mask_f2short', position=2, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(mandatory=True, nohash=True, usedefault=True, ), ) inputs = ROIStats.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ROIStats_outputs(): output_map = dict(stats=dict(), ) outputs = ROIStats.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Refit.py000066400000000000000000000024521257611314500243250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Refit def test_Refit_inputs(): input_map = dict(args=dict(argstr='%s', ), deoblique=dict(argstr='-deoblique', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=True, mandatory=True, position=-1, ), space=dict(argstr='-space %s', ), terminal_output=dict(nohash=True, ), xdel=dict(argstr='-xdel %f', ), xorigin=dict(argstr='-xorigin %s', ), ydel=dict(argstr='-ydel %f', ), yorigin=dict(argstr='-yorigin %s', ), zdel=dict(argstr='-zdel %f', ), zorigin=dict(argstr='-zorigin %s', ), ) inputs = Refit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Refit_outputs(): output_map = dict(out_file=dict(), ) outputs = Refit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Resample.py000066400000000000000000000024521257611314500250240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Resample def test_Resample_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inset %s', copyfile=False, mandatory=True, position=-1, ), master=dict(argstr='-master %s', ), orientation=dict(argstr='-orient %s', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_resample', ), outputtype=dict(), resample_mode=dict(argstr='-rmode %s', ), terminal_output=dict(nohash=True, ), voxel_size=dict(argstr='-dxyz %f %f %f', ), ) inputs = Resample.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Resample_outputs(): output_map = dict(out_file=dict(), ) outputs = Resample.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Retroicor.py000066400000000000000000000027571257611314500252340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Retroicor def test_Retroicor_inputs(): input_map = dict(args=dict(argstr='%s', ), card=dict(argstr='-card %s', position=-2, ), cardphase=dict(argstr='-cardphase %s', hash_files=False, position=-6, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), order=dict(argstr='-order %s', position=-5, ), out_file=dict(argstr='-prefix %s', mandatory=True, position=1, ), outputtype=dict(), resp=dict(argstr='-resp %s', position=-3, ), respphase=dict(argstr='-respphase %s', hash_files=False, position=-7, ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='-threshold %d', position=-4, ), ) inputs = Retroicor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Retroicor_outputs(): output_map = dict(out_file=dict(), ) outputs = Retroicor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_SVMTest.py000066400000000000000000000026031257611314500245570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.svm import SVMTest def test_SVMTest_inputs(): input_map = dict(args=dict(argstr='%s', ), classout=dict(argstr='-classout', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-testvol %s', mandatory=True, ), model=dict(argstr='-model %s', mandatory=True, ), multiclass=dict(argstr='-multiclass %s', ), nodetrend=dict(argstr='-nodetrend', ), nopredcensord=dict(argstr='-nopredcensord', ), options=dict(argstr='%s', ), out_file=dict(argstr='-predictions %s', name_template='%s_predictions', ), outputtype=dict(), terminal_output=dict(nohash=True, ), testlabels=dict(argstr='-testlabels %s', ), ) inputs = SVMTest.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SVMTest_outputs(): output_map = dict(out_file=dict(), ) outputs = SVMTest.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_SVMTrain.py000066400000000000000000000035211257611314500247150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.svm import SVMTrain def test_SVMTrain_inputs(): input_map = dict(alphas=dict(argstr='-alpha %s', name_source='in_file', name_template='%s_alphas', suffix='_alphas', ), args=dict(argstr='%s', ), censor=dict(argstr='-censor %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-trainvol %s', copyfile=False, mandatory=True, ), kernel=dict(argstr='-kernel %s', ), mask=dict(argstr='-mask %s', copyfile=False, position=-1, ), max_iterations=dict(argstr='-max_iterations %d', ), model=dict(argstr='-model %s', name_source='in_file', name_template='%s_model', suffix='_model', ), nomodelmask=dict(argstr='-nomodelmask', ), options=dict(argstr='%s', ), out_file=dict(argstr='-bucket %s', name_source='in_file', name_template='%s_vectors', suffix='_bucket', ), outputtype=dict(), terminal_output=dict(nohash=True, ), trainlabels=dict(argstr='-trainlabels %s', ), ttype=dict(argstr='-type %s', mandatory=True, ), w_out=dict(argstr='-wout', ), ) inputs = SVMTrain.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SVMTrain_outputs(): output_map = dict(alphas=dict(), model=dict(), out_file=dict(), ) outputs = SVMTrain.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_SkullStrip.py000066400000000000000000000021621257611314500253660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import SkullStrip def test_SkullStrip_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-input %s', copyfile=False, mandatory=True, position=1, ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_skullstrip', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = SkullStrip.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SkullStrip_outputs(): output_map = dict(out_file=dict(), ) outputs = SkullStrip.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TCat.py000066400000000000000000000022001257611314500240760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TCat def test_TCat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr=' %s', copyfile=False, mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source='in_files', name_template='%s_tcat', ), outputtype=dict(), rlt=dict(argstr='-rlt%s', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = TCat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TCat_outputs(): output_map = dict(out_file=dict(), ) outputs = TCat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TCorr1D.py000066400000000000000000000031351257611314500244710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TCorr1D def test_TCorr1D_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), ktaub=dict(argstr=' -ktaub', position=1, xor=['pearson', 'spearman', 'quadrant'], ), out_file=dict(argstr='-prefix %s', keep_extension=True, name_source='xset', name_template='%s_correlation.nii.gz', ), outputtype=dict(), pearson=dict(argstr=' -pearson', position=1, xor=['spearman', 'quadrant', 'ktaub'], ), quadrant=dict(argstr=' -quadrant', position=1, xor=['pearson', 'spearman', 'ktaub'], ), spearman=dict(argstr=' -spearman', position=1, xor=['pearson', 'quadrant', 'ktaub'], ), terminal_output=dict(nohash=True, ), xset=dict(argstr=' %s', copyfile=False, mandatory=True, position=-2, ), y_1d=dict(argstr=' %s', mandatory=True, position=-1, ), ) inputs = TCorr1D.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TCorr1D_outputs(): output_map = dict(out_file=dict(), ) outputs = TCorr1D.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TCorrMap.py000066400000000000000000000071541257611314500247470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TCorrMap def test_TCorrMap_inputs(): input_map = dict(absolute_threshold=dict(argstr='-Thresh %f %s', name_source='in_file', suffix='_thresh', xor=('absolute_threshold', 'var_absolute_threshold', 'var_absolute_threshold_normalize'), ), args=dict(argstr='%s', ), automask=dict(argstr='-automask', ), average_expr=dict(argstr='-Aexpr %s %s', name_source='in_file', suffix='_aexpr', xor=('average_expr', 'average_expr_nonzero', 'sum_expr'), ), average_expr_nonzero=dict(argstr='-Cexpr %s %s', name_source='in_file', suffix='_cexpr', xor=('average_expr', 'average_expr_nonzero', 'sum_expr'), ), bandpass=dict(argstr='-bpass %f %f', ), blur_fwhm=dict(argstr='-Gblur %f', ), correlation_maps=dict(argstr='-CorrMap %s', name_source='in_file', ), correlation_maps_masked=dict(argstr='-CorrMask %s', name_source='in_file', ), environ=dict(nohash=True, usedefault=True, ), expr=dict(), histogram=dict(argstr='-Hist %d %s', name_source='in_file', suffix='_hist', ), histogram_bin_numbers=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-input %s', copyfile=False, mandatory=True, ), mask=dict(argstr='-mask %s', ), mean_file=dict(argstr='-Mean %s', name_source='in_file', suffix='_mean', ), out_file=dict(argstr='-prefix %s', name_source=['in_file'], name_template='%s_afni', ), outputtype=dict(), pmean=dict(argstr='-Pmean %s', name_source='in_file', suffix='_pmean', ), polort=dict(argstr='-polort %d', ), qmean=dict(argstr='-Qmean %s', name_source='in_file', suffix='_qmean', ), regress_out_timeseries=dict(argstr='-ort %s', ), seeds=dict(argstr='-seed %s', xor='seeds_width', ), seeds_width=dict(argstr='-Mseed %f', xor='seeds', ), sum_expr=dict(argstr='-Sexpr %s %s', name_source='in_file', suffix='_sexpr', xor=('average_expr', 'average_expr_nonzero', 'sum_expr'), ), terminal_output=dict(nohash=True, ), thresholds=dict(), var_absolute_threshold=dict(argstr='-VarThresh %f %f %f %s', name_source='in_file', suffix='_varthresh', xor=('absolute_threshold', 'var_absolute_threshold', 'var_absolute_threshold_normalize'), ), var_absolute_threshold_normalize=dict(argstr='-VarThreshN %f %f %f %s', name_source='in_file', suffix='_varthreshn', xor=('absolute_threshold', 'var_absolute_threshold', 'var_absolute_threshold_normalize'), ), zmean=dict(argstr='-Zmean %s', name_source='in_file', suffix='_zmean', ), ) inputs = TCorrMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TCorrMap_outputs(): output_map = dict(absolute_threshold=dict(), average_expr=dict(), average_expr_nonzero=dict(), correlation_maps=dict(), correlation_maps_masked=dict(), histogram=dict(), mean_file=dict(), pmean=dict(), qmean=dict(), sum_expr=dict(), var_absolute_threshold=dict(), var_absolute_threshold_normalize=dict(), zmean=dict(), ) outputs = TCorrMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TCorrelate.py000066400000000000000000000024651257611314500253240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TCorrelate def test_TCorrelate_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='-prefix %s', name_source='xset', name_template='%s_tcorr', ), outputtype=dict(), pearson=dict(argstr='-pearson', position=1, ), polort=dict(argstr='-polort %d', position=2, ), terminal_output=dict(nohash=True, ), xset=dict(argstr=' %s', copyfile=False, mandatory=True, position=-2, ), yset=dict(argstr=' %s', copyfile=False, mandatory=True, position=-1, ), ) inputs = TCorrelate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TCorrelate_outputs(): output_map = dict(out_file=dict(), ) outputs = TCorrelate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TShift.py000066400000000000000000000027001257611314500244510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TShift def test_TShift_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore=dict(argstr='-ignore %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), interp=dict(argstr='-%s', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_tshift', ), outputtype=dict(), rlt=dict(argstr='-rlt', ), rltplus=dict(argstr='-rlt+', ), terminal_output=dict(nohash=True, ), tpattern=dict(argstr='-tpattern %s', ), tr=dict(argstr='-TR %s', ), tslice=dict(argstr='-slice %s', xor=['tzero'], ), tzero=dict(argstr='-tzero %s', xor=['tslice'], ), ) inputs = TShift.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TShift_outputs(): output_map = dict(out_file=dict(), ) outputs = TShift.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_TStat.py000066400000000000000000000022331257611314500243100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import TStat def test_TStat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), mask=dict(argstr='-mask %s', ), options=dict(argstr='%s', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_tstat', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = TStat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TStat_outputs(): output_map = dict(out_file=dict(), ) outputs = TStat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_To3D.py000066400000000000000000000024711257611314500240260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import To3D def test_To3D_inputs(): input_map = dict(args=dict(argstr='%s', ), assumemosaic=dict(argstr='-assume_dicom_mosaic', ), datatype=dict(argstr='-datum %s', ), environ=dict(nohash=True, usedefault=True, ), filetype=dict(argstr='-%s', ), funcparams=dict(argstr='-time:zt %s alt+z2', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_folder=dict(argstr='%s/*.dcm', mandatory=True, position=-1, ), out_file=dict(argstr='-prefix %s', name_source=['in_folder'], name_template='%s', ), outputtype=dict(), skipoutliers=dict(argstr='-skip_outliers', ), terminal_output=dict(nohash=True, ), ) inputs = To3D.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_To3D_outputs(): output_map = dict(out_file=dict(), ) outputs = To3D.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Volreg.py000066400000000000000000000034761257611314500245210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Volreg def test_Volreg_inputs(): input_map = dict(args=dict(argstr='%s', ), basefile=dict(argstr='-base %s', position=-6, ), copyorigin=dict(argstr='-twodup', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), md1d_file=dict(argstr='-maxdisp1D %s', keep_extension=True, name_source='in_file', name_template='%s_md.1D', position=-4, ), oned_file=dict(argstr='-1Dfile %s', keep_extension=True, name_source='in_file', name_template='%s.1D', ), oned_matrix_save=dict(argstr='-1Dmatrix_save %s', keep_extension=True, name_source='in_file', name_template='%s.aff12.1D', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_volreg', ), outputtype=dict(), terminal_output=dict(nohash=True, ), timeshift=dict(argstr='-tshift 0', ), verbose=dict(argstr='-verbose', ), zpad=dict(argstr='-zpad %d', position=-5, ), ) inputs = Volreg.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Volreg_outputs(): output_map = dict(md1d_file=dict(), oned_file=dict(), oned_matrix_save=dict(), out_file=dict(), ) outputs = Volreg.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_Warp.py000066400000000000000000000026501257611314500241650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import Warp def test_Warp_inputs(): input_map = dict(args=dict(argstr='%s', ), deoblique=dict(argstr='-deoblique', ), environ=dict(nohash=True, usedefault=True, ), gridset=dict(argstr='-gridset %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), interp=dict(argstr='-%s', ), matparent=dict(argstr='-matparent %s', ), mni2tta=dict(argstr='-mni2tta', ), newgrid=dict(argstr='-newgrid %f', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_warp', ), outputtype=dict(), terminal_output=dict(nohash=True, ), tta2mni=dict(argstr='-tta2mni', ), zpad=dict(argstr='-zpad %d', ), ) inputs = Warp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Warp_outputs(): output_map = dict(out_file=dict(), ) outputs = Warp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/afni/tests/test_auto_ZCutUp.py000066400000000000000000000021741257611314500244470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.afni.preprocess import ZCutUp def test_ZCutUp_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), keep=dict(argstr='-keep %s', ), out_file=dict(argstr='-prefix %s', name_source='in_file', name_template='%s_zcupup', ), outputtype=dict(), terminal_output=dict(nohash=True, ), ) inputs = ZCutUp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ZCutUp_outputs(): output_map = dict(out_file=dict(), ) outputs = ZCutUp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/000077500000000000000000000000001257611314500174765ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/ants/__init__.py000066400000000000000000000012671257611314500216150ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Top-level namespace for ants.""" # Registraiton programs from .registration import ANTS, Registration # Resampling Programs from .resampling import ApplyTransforms, ApplyTransformsToPoints, WarpImageMultiTransform, WarpTimeSeriesImageMultiTransform # Segmentation Programs from .segmentation import Atropos, LaplacianThickness, N4BiasFieldCorrection, JointFusion # Visualization Programs from .visualization import ConvertScalarImageToRGB, CreateTiledMosaic # Utility Programs from .utils import AverageAffineTransform, AverageImages, MultiplyImages, JacobianDeterminant nipype-0.11.0/nipype/interfaces/ants/base.py000066400000000000000000000075011257611314500207650ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The ants module provides basic functions for interfacing with ANTS tools.""" # Local imports from ..base import (CommandLine, CommandLineInputSpec, traits, isdefined) from ... import logging logger = logging.getLogger('interface') # -Using -1 gives primary responsibilty to ITKv4 to do the correct # thread limitings. # -Using 1 takes a very conservative approach to avoid overloading # the computer (when running MultiProc) by forcing everything to # single threaded. This can be a severe penalty for registration # performance. LOCAL_DEFAULT_NUMBER_OF_THREADS=1 # -Using NSLOTS has the same behavior as ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS # as long as ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS is not set. Otherwise # ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS takes precidence. # This behavior states that you the user explicitly specifies # num_threads, then respect that no matter what SGE tries to limit. PREFERED_ITKv4_THREAD_LIMIT_VARIABLE='NSLOTS' ALT_ITKv4_THREAD_LIMIT_VARIABLE='ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS' class ANTSCommandInputSpec(CommandLineInputSpec): """Base Input Specification for all ANTS Commands """ num_threads = traits.Int(LOCAL_DEFAULT_NUMBER_OF_THREADS, usedefault=True, nohash=True, desc="Number of ITK threads to use") class ANTSCommand(CommandLine): """Base class for ANTS interfaces """ input_spec = ANTSCommandInputSpec _num_threads = LOCAL_DEFAULT_NUMBER_OF_THREADS def __init__(self, **inputs): super(ANTSCommand, self).__init__(**inputs) self.inputs.on_trait_change(self._num_threads_update, 'num_threads') if not isdefined(self.inputs.num_threads): self.inputs.num_threads = self._num_threads else: self._num_threads_update() def _num_threads_update(self): self._num_threads = self.inputs.num_threads ## ONLY SET THE ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS if requested ## by the end user. The default setting did not allow for ## overwriting the default values. ## In ITKv4 (the version used for all ANTS programs), ITK respects ## the SGE controlled $NSLOTS environmental variable. ## If user specifies -1, then that indicates that the system ## default behavior should be the one specified by ITKv4 rules ## (i.e. respect SGE $NSLOTS or environmental variables of threads, or ## user environmental settings) if ( self.inputs.num_threads == -1 ): if ( ALT_ITKv4_THREAD_LIMIT_VARIABLE in self.inputs.environ ): del self.inputs.environ[ALT_ITKv4_THREAD_LIMIT_VARIABLE] if ( PREFERED_ITKv4_THREAD_LIMIT_VARIABLE in self.inputs.environ ): del self.inputs.environ[PREFERED_ITKv4_THREAD_LIMIT_VARIABLE] else: self.inputs.environ.update({PREFERED_ITKv4_THREAD_LIMIT_VARIABLE: '%s' % self.inputs.num_threads}) @staticmethod def _format_xarray(val): """ Convenience method for converting input arrays [1,2,3] to commandline format '1x2x3' """ return 'x'.join([str(x) for x in val]) @classmethod def set_default_num_threads(cls, num_threads): """Set the default number of threads for ITK calls This method is used to set the default number of ITK threads for all the ANTS interfaces. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.num_threads """ cls._num_threads = num_threads def _format_xarray(self, val): """ Convienence method for converting [1,2,3] -> 1x2x3 """ val = 'x'.join([str(x) for x in val]) return val nipype-0.11.0/nipype/interfaces/ants/legacy.py000066400000000000000000000316021257611314500213160ustar00rootroot00000000000000## NOTE: This implementation has been superceeded buy the antsApplyTransform ## implmeentation that more closely follows the strucutre and capabilities ## of the antsApplyTransform program. This implementation is here ## for backwards compatibility. """ANTS Apply Transforms interface Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ # Local imports from ..base import (TraitedSpec, File, traits, InputMultiPath, isdefined) from ...utils.filemanip import split_filename from .base import ANTSCommand, ANTSCommandInputSpec import os from glob import glob from nipype.interfaces.base import OutputMultiPath class antsIntroductionInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='-d %d', usedefault=True, desc='image dimension (2 or 3)', position=1) reference_image = File(exists=True, argstr='-r %s', desc='template file to warp to', mandatory=True, copyfile=True) input_image = File(exists=True, argstr='-i %s', desc='input image to warp to template', mandatory=True, copyfile=False) force_proceed = traits.Bool(argstr='-f 1', desc=('force script to proceed even if headers ' 'may be incompatible')) inverse_warp_template_labels = traits.Bool(argstr='-l', desc=('Applies inverse warp to the template labels ' 'to estimate label positions in target space (use ' 'for template-based segmentation)')) max_iterations = traits.List(traits.Int, argstr='-m %s', sep='x', desc=('maximum number of iterations (must be ' 'list of integers in the form [J,K,L...]: ' 'J = coarsest resolution iterations, K = ' 'middle resolution interations, L = fine ' 'resolution iterations')) bias_field_correction = traits.Bool(argstr='-n 1', desc=('Applies bias field correction to moving ' 'image')) similarity_metric = traits.Enum('PR', 'CC', 'MI', 'MSQ', argstr='-s %s', desc=('Type of similartiy metric used for registration ' '(CC = cross correlation, MI = mutual information, ' 'PR = probability mapping, MSQ = mean square difference)')) transformation_model = traits.Enum('GR', 'EL', 'SY', 'S2', 'EX', 'DD', 'RI', 'RA', argstr='-t %s', usedefault=True, desc=('Type of transofmration model used for registration ' '(EL = elastic transformation model, SY = SyN with time, ' 'arbitrary number of time points, S2 = SyN with time ' 'optimized for 2 time points, GR = greedy SyN, EX = ' 'exponential, DD = diffeomorphic demons style exponential ' 'mapping, RI = purely rigid, RA = affine rigid')) out_prefix = traits.Str('ants_', argstr='-o %s', usedefault=True, desc=('Prefix that is prepended to all output ' 'files (default = ants_)')) quality_check = traits.Bool(argstr='-q 1', desc='Perform a quality check of the result') class antsIntroductionOutputSpec(TraitedSpec): affine_transformation = File(exists=True, desc='affine (prefix_Affine.txt)') warp_field = File(exists=True, desc='warp field (prefix_Warp.nii)') inverse_warp_field = File(exists=True, desc='inverse warp field (prefix_InverseWarp.nii)') input_file = File(exists=True, desc='input image (prefix_repaired.nii)') output_file = File(exists=True, desc='output image (prefix_deformed.nii)') class antsIntroduction(ANTSCommand): """Uses ANTS to generate matrices to warp data from one space to another. Examples -------- >>> from nipype.interfaces.ants.legacy import antsIntroduction >>> warp = antsIntroduction() >>> warp.inputs.reference_image = 'Template_6.nii' >>> warp.inputs.input_image = 'structural.nii' >>> warp.inputs.max_iterations = [30,90,20] >>> warp.cmdline 'antsIntroduction.sh -d 3 -i structural.nii -m 30x90x20 -o ants_ -r Template_6.nii -t GR' """ _cmd = 'antsIntroduction.sh' input_spec = antsIntroductionInputSpec output_spec = antsIntroductionOutputSpec def _list_outputs(self): outputs = self._outputs().get() transmodel = self.inputs.transformation_model # When transform is set as 'RI'/'RA', wrap fields should not be expected # The default transformation is GR, which outputs the wrap fields if not isdefined(transmodel) or (isdefined(transmodel) and transmodel not in ['RI', 'RA']): outputs['warp_field'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'Warp.nii.gz') outputs['inverse_warp_field'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'InverseWarp.nii.gz') outputs['affine_transformation'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'Affine.txt') outputs['input_file'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'repaired.nii.gz') outputs['output_file'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'deformed.nii.gz') return outputs ## How do we make a pass through so that GenWarpFields is just an alias for antsIntroduction ? class GenWarpFields(antsIntroduction): pass class buildtemplateparallelInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='-d %d', usedefault=True, desc='image dimension (2 or 3)', position=1) out_prefix = traits.Str('antsTMPL_', argstr='-o %s', usedefault=True, desc=('Prefix that is prepended to all output ' 'files (default = antsTMPL_)')) in_files = traits.List(File(exists=True), mandatory=True, desc='list of images to generate template from', argstr='%s', position=-1) parallelization = traits.Enum(0, 1, 2, argstr='-c %d', usedefault=True, desc=('control for parallel processing (0 = ' 'serial, 1 = use PBS, 2 = use PEXEC, 3 = ' 'use Apple XGrid')) gradient_step_size = traits.Float(argstr='-g %f', desc=('smaller magnitude results in ' 'more cautious steps (default = ' '.25)')) iteration_limit = traits.Int(4, argstr='-i %d', usedefault=True, desc='iterations of template construction') num_cores = traits.Int(argstr='-j %d', requires=['parallelization'], desc=('Requires parallelization = 2 (PEXEC). ' 'Sets number of cpu cores to use')) max_iterations = traits.List(traits.Int, argstr='-m %s', sep='x', desc=('maximum number of iterations (must be ' 'list of integers in the form [J,K,L...]: ' 'J = coarsest resolution iterations, K = ' 'middle resolution interations, L = fine ' 'resolution iterations')) bias_field_correction = traits.Bool(argstr='-n 1', desc=('Applies bias field correction to moving ' 'image')) rigid_body_registration = traits.Bool(argstr='-r 1', desc=('registers inputs before creating template ' '(useful if no initial template available)')) similarity_metric = traits.Enum('PR', 'CC', 'MI', 'MSQ', argstr='-s %s', desc=('Type of similartiy metric used for registration ' '(CC = cross correlation, MI = mutual information, ' 'PR = probability mapping, MSQ = mean square difference)')) transformation_model = traits.Enum('GR', 'EL', 'SY', 'S2', 'EX', 'DD', argstr='-t %s', usedefault=True, desc=('Type of transofmration model used for registration ' '(EL = elastic transformation model, SY = SyN with time, ' 'arbitrary number of time points, S2 = SyN with time ' 'optimized for 2 time points, GR = greedy SyN, EX = ' 'exponential, DD = diffeomorphic demons style exponential ' 'mapping')) use_first_as_target = traits.Bool(desc=('uses first volume as target of ' 'all inputs. When not used, an ' 'unbiased average image is used ' 'to start.')) class buildtemplateparallelOutputSpec(TraitedSpec): final_template_file = File(exists=True, desc='final ANTS template') template_files = OutputMultiPath(File(exists=True), desc='Templates from different stages of iteration') subject_outfiles = OutputMultiPath(File(exists=True), desc=('Outputs for each input image. Includes warp ' 'field, inverse warp, Affine, original image ' '(repaired) and warped image (deformed)')) class buildtemplateparallel(ANTSCommand): """Generate a optimal average template .. warning:: This can take a VERY long time to complete Examples -------- >>> from nipype.interfaces.ants.legacy import buildtemplateparallel >>> tmpl = buildtemplateparallel() >>> tmpl.inputs.in_files = ['T1.nii', 'structural.nii'] >>> tmpl.inputs.max_iterations = [30, 90, 20] >>> tmpl.cmdline 'buildtemplateparallel.sh -d 3 -i 4 -m 30x90x20 -o antsTMPL_ -c 0 -t GR T1.nii structural.nii' """ _cmd = 'buildtemplateparallel.sh' input_spec = buildtemplateparallelInputSpec output_spec = buildtemplateparallelOutputSpec def _format_arg(self, opt, spec, val): if opt == 'num_cores': if self.inputs.parallelization == 2: return '-j ' + str(val) else: return '' if opt == 'in_files': if self.inputs.use_first_as_target: start = '-z ' else: start = '' return start + ' '.join(name for name in val) return super(buildtemplateparallel, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['template_files'] = [] for i in range(len(glob(os.path.realpath('*iteration*')))): temp = os.path.realpath('%s_iteration_%d/%stemplate.nii.gz' % (self.inputs.transformation_model, i, self.inputs.out_prefix)) os.rename(temp, os.path.realpath('%s_iteration_%d/%stemplate_i%d.nii.gz' % (self.inputs.transformation_model, i, self.inputs.out_prefix, i))) file_ = ('%s_iteration_%d/%stemplate_i%d.nii.gz' % (self.inputs.transformation_model, i, self.inputs.out_prefix, i)) outputs['template_files'].append(os.path.realpath(file_)) outputs['final_template_file'] = \ os.path.realpath('%stemplate.nii.gz' % self.inputs.out_prefix) outputs['subject_outfiles'] = [] for filename in self.inputs.in_files: _, base, _ = split_filename(filename) temp = glob(os.path.realpath('%s%s*' % (self.inputs.out_prefix, base))) for file_ in temp: outputs['subject_outfiles'].append(file_) return outputs nipype-0.11.0/nipype/interfaces/ants/registration.py000066400000000000000000001371611257611314500225730ustar00rootroot00000000000000"""The ants module provides basic functions for interfacing with ants functions. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from ..base import (TraitedSpec, File, traits, InputMultiPath) from .base import ANTSCommand, ANTSCommandInputSpec import os from ..traits_extension import isdefined import numpy as np class ANTSInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', usedefault=False, position=1, desc='image dimension (2 or 3)') fixed_image = InputMultiPath(File(exists=True), mandatory=True, desc=('image to apply transformation to (generally a coregistered ' 'functional)')) moving_image = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, desc=('image to apply transformation to (generally a coregistered ' 'functional)')) # Not all metrics are appropriate for all modalities. Also, not all metrics # are efficeint or appropriate at all resolution levels, Some metrics perform # well for gross global registraiton, but do poorly for small changes (i.e. # Mattes), and some metrics do well for small changes but don't work well for # gross level changes (i.e. 'CC'). # # This is a two stage registration. in the first stage # [ 'Mattes', .................] # ^^^^^^ <- First stage # Do a unimodal registration of the first elements of the fixed/moving input # list use the"CC" as the metric. # # In the second stage # [ ....., ['Mattes','CC'] ] # ^^^^^^^^^^^^^^^ <- Second stage # Do a multi-modal registration where the first elements of fixed/moving # input list use 'CC' metric and that is added to 'Mattes' metric result of # the second elements of the fixed/moving input. # # Cost = Sum_i ( metricweight[i] Metric_i ( fixedimage[i], movingimage[i]) ) metric = traits.List(traits.Enum('CC', 'MI', 'SMI', 'PR', 'SSD', 'MSQ', 'PSE'), mandatory=True, desc='') metric_weight = traits.List(traits.Float(), requires=['metric'], desc='') radius = traits.List(traits.Int(), requires=['metric'], desc='') output_transform_prefix = traits.Str('out', usedefault=True, argstr='--output-naming %s', mandatory=True, desc='') transformation_model = traits.Enum('Diff', 'Elast', 'Exp', 'Greedy Exp', 'SyN', argstr='%s', mandatory=True, desc='') gradient_step_length = traits.Float( requires=['transformation_model'], desc='') number_of_time_steps = traits.Float( requires=['gradient_step_length'], desc='') delta_time = traits.Float(requires=['number_of_time_steps'], desc='') symmetry_type = traits.Float(requires=['delta_time'], desc='') use_histogram_matching = traits.Bool( argstr='%s', default=True, usedefault=True) number_of_iterations = traits.List( traits.Int(), argstr='--number-of-iterations %s', sep='x') smoothing_sigmas = traits.List( traits.Int(), argstr='--gaussian-smoothing-sigmas %s', sep='x') subsampling_factors = traits.List( traits.Int(), argstr='--subsampling-factors %s', sep='x') affine_gradient_descent_option = traits.List(traits.Float(), argstr='%s') mi_option = traits.List(traits.Int(), argstr='--MI-option %s', sep='x') regularization = traits.Enum('Gauss', 'DMFFD', argstr='%s', desc='') regularization_gradient_field_sigma = traits.Float( requires=['regularization'], desc='') regularization_deformation_field_sigma = traits.Float( requires=['regularization'], desc='') number_of_affine_iterations = traits.List( traits.Int(), argstr='--number-of-affine-iterations %s', sep='x') class ANTSOutputSpec(TraitedSpec): affine_transform = File(exists=True, desc='Affine transform file') warp_transform = File(exists=True, desc='Warping deformation field') inverse_warp_transform = File( exists=True, desc='Inverse warping deformation field') metaheader = File(exists=True, desc='VTK metaheader .mhd file') metaheader_raw = File(exists=True, desc='VTK metaheader .raw file') class ANTS(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import ANTS >>> ants = ANTS() >>> ants.inputs.dimension = 3 >>> ants.inputs.output_transform_prefix = 'MY' >>> ants.inputs.metric = ['CC'] >>> ants.inputs.fixed_image = ['T1.nii'] >>> ants.inputs.moving_image = ['resting.nii'] >>> ants.inputs.metric_weight = [1.0] >>> ants.inputs.radius = [5] >>> ants.inputs.transformation_model = 'SyN' >>> ants.inputs.gradient_step_length = 0.25 >>> ants.inputs.number_of_iterations = [50, 35, 15] >>> ants.inputs.use_histogram_matching = True >>> ants.inputs.mi_option = [32, 16000] >>> ants.inputs.regularization = 'Gauss' >>> ants.inputs.regularization_gradient_field_sigma = 3 >>> ants.inputs.regularization_deformation_field_sigma = 0 >>> ants.inputs.number_of_affine_iterations = [10000,10000,10000,10000,10000] >>> ants.cmdline 'ANTS 3 --MI-option 32x16000 --image-metric CC[ T1.nii, resting.nii, 1, 5 ] --number-of-affine-iterations 10000x10000x10000x10000x10000 --number-of-iterations 50x35x15 --output-naming MY --regularization Gauss[3.0,0.0] --transformation-model SyN[0.25] --use-Histogram-Matching 1' """ _cmd = 'ANTS' input_spec = ANTSInputSpec output_spec = ANTSOutputSpec def _image_metric_constructor(self): retval = [] intensityBased = ['CC', 'MI', 'SMI', 'PR', 'SSD', 'MSQ'] pointSetBased = ['PSE', 'JTB'] for ii in range(len(self.inputs.moving_image)): if self.inputs.metric[ii] in intensityBased: retval.append( '--image-metric %s[ %s, %s, %g, %d ]' % (self.inputs.metric[ii], self.inputs.fixed_image[ ii], self.inputs.moving_image[ ii], self.inputs.metric_weight[ ii], self.inputs.radius[ii])) elif self.inputs.metric[ii] == pointSetBased: pass # retval.append('--image-metric %s[%s, %s, ...'.format(self.inputs.metric[ii], self.inputs.fixed_image[ii], self.inputs.moving_image[ii], ...)) return ' '.join(retval) def _transformation_constructor(self): model = self.inputs.transformation_model stepLength = self.inputs.gradient_step_length timeStep = self.inputs.number_of_time_steps deltaTime = self.inputs.delta_time symmetryType = self.inputs.symmetry_type retval = ['--transformation-model %s' % model] parameters = [] for elem in (stepLength, timeStep, deltaTime, symmetryType): if not elem is traits.Undefined: parameters.append('%#.2g' % elem) if len(parameters) > 0: if len(parameters) > 1: parameters = ','.join(parameters) else: parameters = ''.join(parameters) retval.append('[%s]' % parameters) return ''.join(retval) def _regularization_constructor(self): return '--regularization {0}[{1},{2}]'.format(self.inputs.regularization, self.inputs.regularization_gradient_field_sigma, self.inputs.regularization_deformation_field_sigma) def _affine_gradient_descent_option_constructor(self): retval = ['--affine-gradient-descent-option'] values = self.inputs.affine_gradient_descent_option defaults = [0.1, 0.5, 1.e-4, 1.e-4] for ii in range(len(defaults)): try: defaults[ii] = values[ii] except IndexError: break stringList = [('%g' % defaults[index]) for index in range(4)] parameters = 'x'.join(stringList) retval.append(parameters) return ' '.join(retval) def _format_arg(self, opt, spec, val): if opt == 'moving_image': return self._image_metric_constructor() elif opt == 'transformation_model': return self._transformation_constructor() elif opt == 'regularization': return self._regularization_constructor() elif opt == 'affine_gradient_descent_option': return self._affine_gradient_descent_option_constructor() elif opt == 'use_histogram_matching': if self.inputs.use_histogram_matching: return '--use-Histogram-Matching 1' else: return '--use-Histogram-Matching 0' return super(ANTS, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['affine_transform'] = os.path.abspath( self.inputs.output_transform_prefix + 'Affine.txt') outputs['warp_transform'] = os.path.abspath( self.inputs.output_transform_prefix + 'Warp.nii.gz') outputs['inverse_warp_transform'] = os.path.abspath( self.inputs.output_transform_prefix + 'InverseWarp.nii.gz') # outputs['metaheader'] = os.path.abspath(self.inputs.output_transform_prefix + 'velocity.mhd') # outputs['metaheader_raw'] = os.path.abspath(self.inputs.output_transform_prefix + 'velocity.raw') return outputs class RegistrationInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='--dimensionality %d', usedefault=True, desc='image dimension (2 or 3)') fixed_image = InputMultiPath(File(exists=True), mandatory=True, desc='image to apply transformation to (generally a coregistered functional)') fixed_image_mask = File(argstr='%s', exists=True, desc='mask used to limit metric sampling region of the fixed image') moving_image = InputMultiPath(File(exists=True), mandatory=True, desc='image to apply transformation to (generally a coregistered functional)') moving_image_mask = File(requires=['fixed_image_mask'], exists=True, desc='mask used to limit metric sampling region of the moving image') save_state = File(argstr='--save-state %s', exists=False, desc='Filename for saving the internal restorable state of the registration') restore_state = File(argstr='--restore-state %s', exists=True, desc='Filename for restoring the internal restorable state of the registration') initial_moving_transform = File(argstr='%s', exists=True, desc='', xor=['initial_moving_transform_com']) invert_initial_moving_transform = traits.Bool( default=False, requires=["initial_moving_transform"], desc='', xor=['initial_moving_transform_com']) initial_moving_transform_com = traits.Enum(0, 1, 2, argstr='%s', default=0, xor=['initial_moving_transform'], desc="Use center of mass for moving transform") metric_item_trait = traits.Enum("CC", "MeanSquares", "Demons", "GC", "MI", "Mattes") metric_stage_trait = traits.Either( metric_item_trait, traits.List(metric_item_trait)) metric = traits.List(metric_stage_trait, mandatory=True, desc='the metric(s) to use for each stage. ' 'Note that multiple metrics per stage are not supported ' 'in ANTS 1.9.1 and earlier.') metric_weight_item_trait = traits.Float(1.0) metric_weight_stage_trait = traits.Either( metric_weight_item_trait, traits.List(metric_weight_item_trait)) metric_weight = traits.List( metric_weight_stage_trait, value=[1.0], usedefault=True, requires=['metric'], mandatory=True, desc='the metric weight(s) for each stage. ' 'The weights must sum to 1 per stage.') radius_bins_item_trait = traits.Int(5) radius_bins_stage_trait = traits.Either( radius_bins_item_trait, traits.List(radius_bins_item_trait)) radius_or_number_of_bins = traits.List( radius_bins_stage_trait, value=[5], usedefault=True, requires=['metric_weight'], desc='the number of bins in each stage for the MI and Mattes metric, ' 'the radius for other metrics') sampling_strategy_item_trait = traits.Enum( "None", "Regular", "Random", None) sampling_strategy_stage_trait = traits.Either( sampling_strategy_item_trait, traits.List(sampling_strategy_item_trait)) sampling_strategy = traits.List( trait=sampling_strategy_stage_trait, requires=['metric_weight'], desc='the metric sampling strategy (strategies) for each stage') sampling_percentage_item_trait = traits.Either( traits.Range(low=0.0, high=1.0), None) sampling_percentage_stage_trait = traits.Either( sampling_percentage_item_trait, traits.List(sampling_percentage_item_trait)) sampling_percentage = traits.List( trait=sampling_percentage_stage_trait, requires=['sampling_strategy'], desc="the metric sampling percentage(s) to use for each stage") use_estimate_learning_rate_once = traits.List(traits.Bool(), desc='') use_histogram_matching = traits.Either( traits.Bool, traits.List(traits.Bool(argstr='%s')), default=True, usedefault=True) interpolation = traits.Enum( 'Linear', 'NearestNeighbor', 'CosineWindowedSinc', 'WelchWindowedSinc', 'HammingWindowedSinc', 'LanczosWindowedSinc', 'BSpline', # MultiLabel[,] # Gaussian[,] # BSpline[] argstr='%s', usedefault=True) write_composite_transform = traits.Bool( argstr='--write-composite-transform %d', default=False, usedefault=True, desc='') collapse_output_transforms = traits.Bool( argstr='--collapse-output-transforms %d', default=True, usedefault=True, # This should be true for explicit completeness desc=('Collapse output transforms. Specifically, enabling this option ' 'combines all adjacent linear transforms and composes all ' 'adjacent displacement field transforms before writing the ' 'results to disk.')) initialize_transforms_per_stage = traits.Bool( argstr='--initialize-transforms-per-stage %d', default=False, usedefault=True, # This should be true for explicit completeness desc=('Initialize linear transforms from the previous stage. By enabling this option, ' 'the current linear stage transform is directly intialized from the previous ' 'stages linear transform; this allows multiple linear stages to be run where ' 'each stage directly updates the estimated linear transform from the previous ' 'stage. (e.g. Translation -> Rigid -> Affine). ' )) # NOTE: Even though only 0=False and 1=True are allowed, ants uses integer # values instead of booleans float = traits.Bool( argstr='--float %d', default=False, desc=('Use float instead of double for computations.')) transforms = traits.List(traits.Enum('Rigid', 'Affine', 'CompositeAffine', 'Similarity', 'Translation', 'BSpline', 'GaussianDisplacementField', 'TimeVaryingVelocityField', 'TimeVaryingBSplineVelocityField', 'SyN', 'BSplineSyN', 'Exponential', 'BSplineExponential'), argstr='%s', mandatory=True) # TODO: transform_parameters currently supports rigid, affine, composite # affine, translation, bspline, gaussian displacement field (gdf), and SyN # -----ONLY-----! transform_parameters = traits.List(traits.Either(traits.Float(), traits.Tuple( traits.Float()), traits.Tuple(traits.Float(), # gdf & syn traits.Float( ), traits.Float( )), traits.Tuple(traits.Float(), # BSplineSyn traits.Int(), traits.Int(), traits.Int()))) # Convergence flags number_of_iterations = traits.List(traits.List(traits.Int())) smoothing_sigmas = traits.List(traits.List(traits.Float()), mandatory=True) sigma_units = traits.List(traits.Enum('mm', 'vox'), requires=['smoothing_sigmas'], desc="units for smoothing sigmas") shrink_factors = traits.List(traits.List(traits.Int()), mandatory=True) convergence_threshold = traits.List(trait=traits.Float(), value=[ 1e-6], minlen=1, requires=['number_of_iterations'], usedefault=True) convergence_window_size = traits.List(trait=traits.Int(), value=[ 10], minlen=1, requires=['convergence_threshold'], usedefault=True) # Output flags output_transform_prefix = traits.Str( "transform", usedefault=True, argstr="%s", desc="") output_warped_image = traits.Either( traits.Bool, File(), hash_files=False, desc="") output_inverse_warped_image = traits.Either(traits.Bool, File(), hash_files=False, requires=['output_warped_image'], desc="") winsorize_upper_quantile = traits.Range( low=0.0, high=1.0, value=1.0, argstr='%s', usedefault=True, desc="The Upper quantile to clip image ranges") winsorize_lower_quantile = traits.Range( low=0.0, high=1.0, value=0.0, argstr='%s', usedefault=True, desc="The Lower quantile to clip image ranges") class RegistrationOutputSpec(TraitedSpec): forward_transforms = traits.List( File(exists=True), desc='List of output transforms for forward registration') reverse_transforms = traits.List( File(exists=True), desc='List of output transforms for reverse registration') forward_invert_flags = traits.List(traits.Bool( ), desc='List of flags corresponding to the forward transforms') reverse_invert_flags = traits.List(traits.Bool( ), desc='List of flags corresponding to the reverse transforms') composite_transform = File(exists=True, desc='Composite transform file') inverse_composite_transform = File(exists=True, desc='Inverse composite transform file') warped_image = File(desc="Outputs warped image") inverse_warped_image = File(desc="Outputs the inverse of the warped image") save_state = File(desc="The saved registration state to be restored") class Registration(ANTSCommand): """ Examples -------- >>> import copy >>> from nipype.interfaces.ants import Registration >>> reg = Registration() >>> reg.inputs.fixed_image = 'fixed1.nii' >>> reg.inputs.moving_image = 'moving1.nii' >>> reg.inputs.output_transform_prefix = "output_" >>> reg.inputs.initial_moving_transform = 'trans.mat' >>> reg.inputs.invert_initial_moving_transform = True >>> reg.inputs.transforms = ['Affine', 'SyN'] >>> reg.inputs.transform_parameters = [(2.0,), (0.25, 3.0, 0.0)] >>> reg.inputs.number_of_iterations = [[1500, 200], [100, 50, 30]] >>> reg.inputs.dimension = 3 >>> reg.inputs.write_composite_transform = True >>> reg.inputs.collapse_output_transforms = False >>> reg.inputs.initialize_transforms_per_stage = False >>> reg.inputs.metric = ['Mattes']*2 >>> reg.inputs.metric_weight = [1]*2 # Default (value ignored currently by ANTs) >>> reg.inputs.radius_or_number_of_bins = [32]*2 >>> reg.inputs.sampling_strategy = ['Random', None] >>> reg.inputs.sampling_percentage = [0.05, None] >>> reg.inputs.convergence_threshold = [1.e-8, 1.e-9] >>> reg.inputs.convergence_window_size = [20]*2 >>> reg.inputs.smoothing_sigmas = [[1,0], [2,1,0]] >>> reg.inputs.sigma_units = ['vox'] * 2 >>> reg.inputs.shrink_factors = [[2,1], [3,2,1]] >>> reg.inputs.use_estimate_learning_rate_once = [True, True] >>> reg.inputs.use_histogram_matching = [True, True] # This is the default >>> reg.inputs.output_warped_image = 'output_warped_image.nii.gz' >>> reg1 = copy.deepcopy(reg) >>> reg1.inputs.winsorize_lower_quantile = 0.025 >>> reg1.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1' >>> reg1.run() #doctest: +SKIP >>> reg2 = copy.deepcopy(reg) >>> reg2.inputs.winsorize_upper_quantile = 0.975 >>> reg2.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1' >>> reg3 = copy.deepcopy(reg) >>> reg3.inputs.winsorize_lower_quantile = 0.025 >>> reg3.inputs.winsorize_upper_quantile = 0.975 >>> reg3.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1' >>> reg3a = copy.deepcopy(reg) >>> reg3a.inputs.float = True >>> reg3a.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --float 1 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1' >>> reg3b = copy.deepcopy(reg) >>> reg3b.inputs.float = False >>> reg3b.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --float 0 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1' >>> # Test collapse transforms flag >>> reg4 = copy.deepcopy(reg) >>> reg.inputs.save_state = 'trans.mat' >>> reg.inputs.restore_state = 'trans.mat' >>> reg4.inputs.initialize_transforms_per_stage = True >>> reg4.inputs.collapse_output_transforms = True >>> outputs = reg4._list_outputs() >>> print outputs #doctest: +ELLIPSIS {'reverse_invert_flags': [], 'inverse_composite_transform': '.../nipype/testing/data/output_InverseComposite.h5', 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': , 'forward_invert_flags': [], 'reverse_transforms': [], 'save_state': , 'composite_transform': '.../nipype/testing/data/output_Composite.h5', 'forward_transforms': []} >>> # Test collapse transforms flag >>> reg4b = copy.deepcopy(reg4) >>> reg4b.inputs.write_composite_transform = False >>> outputs = reg4b._list_outputs() >>> print outputs #doctest: +ELLIPSIS {'reverse_invert_flags': [True, False], 'inverse_composite_transform': , 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': , 'forward_invert_flags': [False, False], 'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1InverseWarp.nii.gz'], 'save_state': , 'composite_transform': , 'forward_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1Warp.nii.gz']} >>> reg4b.aggregate_outputs() #doctest: +SKIP >>> # Test multiple metrics per stage >>> reg5 = copy.deepcopy(reg) >>> reg5.inputs.fixed_image = 'fixed1.nii' >>> reg5.inputs.moving_image = 'moving1.nii' >>> reg5.inputs.metric = ['Mattes', ['Mattes', 'CC']] >>> reg5.inputs.metric_weight = [1, [.5,.5]] >>> reg5.inputs.radius_or_number_of_bins = [32, [32, 4] ] >>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage >>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]] >>> reg5.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 4, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1' >>> # Test multiple inputs >>> reg6 = copy.deepcopy(reg5) >>> reg6.inputs.fixed_image = ['fixed1.nii', 'fixed2.nii'] >>> reg6.inputs.moving_image = ['moving1.nii', 'moving2.nii'] >>> reg6.cmdline 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric CC[ fixed2.nii, moving2.nii, 0.5, 4, None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --write-composite-transform 1' """ DEF_SAMPLING_STRATEGY = 'None' """The default sampling strategy argument.""" _cmd = 'antsRegistration' input_spec = RegistrationInputSpec output_spec = RegistrationOutputSpec _quantilesDone = False _linear_transform_names = np.array( ['Rigid', 'Affine', 'Translation', 'CompositeAffine', 'Similarity']) def _formatMetric(self, index): """ Format the antsRegistration -m metric argument(s). Parameters ---------- index: the stage index """ # The metric name input for the current stage. name_input = self.inputs.metric[index] # The stage-specific input dictionary. stage_inputs = dict( fixed_image=self.inputs.fixed_image[0], moving_image=self.inputs.moving_image[0], metric=name_input, weight=self.inputs.metric_weight[index], radius_or_bins=self.inputs.radius_or_number_of_bins[index], optional=self.inputs.radius_or_number_of_bins[index] ) # The optional sampling strategy and percentage. if (isdefined(self.inputs.sampling_strategy) and self.inputs.sampling_strategy): sampling_strategy = self.inputs.sampling_strategy[index] if sampling_strategy: stage_inputs['sampling_strategy'] = sampling_strategy sampling_percentage = self.inputs.sampling_percentage if (isdefined(self.inputs.sampling_percentage) and self.inputs.sampling_percentage): sampling_percentage = self.inputs.sampling_percentage[index] if sampling_percentage: stage_inputs['sampling_percentage'] = sampling_percentage # Make a list of metric specifications, one per -m command line # argument for the current stage. # If there are multiple inputs for this stage, then convert the # dictionary of list inputs into a list of metric specifications. # Otherwise, make a singleton list of the metric specification # from the non-list inputs. if isinstance(name_input, list): items = stage_inputs.items() indexes = range(0, len(name_input)) specs = list() for i in indexes: temp = dict([(k, v[i]) for k, v in items]) if len(self.inputs.fixed_image) == 1: temp["fixed_image"] = self.inputs.fixed_image[0] else: temp["fixed_image"] = self.inputs.fixed_image[i] if len(self.inputs.moving_image) == 1: temp["moving_image"] = self.inputs.moving_image[0] else: temp["moving_image"] = self.inputs.moving_image[i] specs.append( temp ) else: specs = [stage_inputs] # Format the --metric command line metric arguments, one per # specification. return [self._formatMetricArgument(**spec) for spec in specs] def _formatMetricArgument(self, **kwargs): retval = '%s[ %s, %s, %g, %d' % (kwargs['metric'], kwargs['fixed_image'], kwargs['moving_image'], kwargs['weight'], kwargs['radius_or_bins']) # The optional sampling strategy. if kwargs.has_key('sampling_strategy'): sampling_strategy = kwargs['sampling_strategy'] elif kwargs.has_key('sampling_percentage'): # The sampling percentage is specified but not the # sampling strategy. Use the default strategy. sampling_strategy = Registration.DEF_SAMPLING_STRATEGY else: sampling_strategy = None # Format the optional sampling arguments. if sampling_strategy: retval += ', %s' % sampling_strategy if kwargs.has_key('sampling_percentage'): retval += ', %g' % kwargs['sampling_percentage'] retval += ' ]' return retval def _formatTransform(self, index): retval = [] retval.append('%s[ ' % self.inputs.transforms[index]) parameters = ', '.join([str( element) for element in self.inputs.transform_parameters[index]]) retval.append('%s' % parameters) retval.append(' ]') return "".join(retval) def _formatRegistration(self): retval = [] for ii in range(len(self.inputs.transforms)): retval.append('--transform %s' % (self._formatTransform(ii))) for metric in self._formatMetric(ii): retval.append('--metric %s' % metric) retval.append('--convergence %s' % self._formatConvergence(ii)) if isdefined(self.inputs.sigma_units): retval.append('--smoothing-sigmas %s%s' % (self._antsJoinList(self.inputs.smoothing_sigmas[ ii]), self.inputs.sigma_units[ii])) else: retval.append('--smoothing-sigmas %s' % self._antsJoinList(self.inputs.smoothing_sigmas[ii])) retval.append('--shrink-factors %s' % self._antsJoinList(self.inputs.shrink_factors[ii])) if isdefined(self.inputs.use_estimate_learning_rate_once): retval.append('--use-estimate-learning-rate-once %d' % self.inputs.use_estimate_learning_rate_once[ii]) if isdefined(self.inputs.use_histogram_matching): # use_histogram_matching is either a common flag for all transforms # or a list of transform-specific flags if isinstance(self.inputs.use_histogram_matching, bool): histval = self.inputs.use_histogram_matching else: histval = self.inputs.use_histogram_matching[ii] retval.append('--use-histogram-matching %d' % histval) return " ".join(retval) def _antsJoinList(self, antsList): return "x".join([str(i) for i in antsList]) def _get_outputfilenames(self, inverse=False): output_filename = None if not inverse: if isdefined(self.inputs.output_warped_image) and \ self.inputs.output_warped_image: output_filename = self.inputs.output_warped_image if isinstance(output_filename, bool): output_filename = '%s_Warped.nii.gz' % self.inputs.output_transform_prefix else: output_filename = output_filename return output_filename inv_output_filename = None if isdefined(self.inputs.output_inverse_warped_image) and \ self.inputs.output_inverse_warped_image: inv_output_filename = self.inputs.output_inverse_warped_image if isinstance(inv_output_filename, bool): inv_output_filename = '%s_InverseWarped.nii.gz' % self.inputs.output_transform_prefix else: inv_output_filename = inv_output_filename return inv_output_filename def _formatConvergence(self, ii): convergence_iter = self._antsJoinList( self.inputs.number_of_iterations[ii]) if len(self.inputs.convergence_threshold) > ii: convergence_value = self.inputs.convergence_threshold[ii] else: convergence_value = self.inputs.convergence_threshold[0] if len(self.inputs.convergence_window_size) > ii: convergence_ws = self.inputs.convergence_window_size[ii] else: convergence_ws = self.inputs.convergence_window_size[0] return '[ %s, %g, %d ]' % (convergence_iter, convergence_value, convergence_ws) def _formatWinsorizeImageIntensities(self): assert(self.inputs.winsorize_upper_quantile > self.inputs.winsorize_lower_quantile), "Upper bound MUST be more than lower bound: %g > %g" \ % (self.inputs.winsorize_upper_quantile, self.inputs.winsorize_lower_quantile) self._quantilesDone = True return '--winsorize-image-intensities [ %s, %s ]' % (self.inputs.winsorize_lower_quantile, self.inputs.winsorize_upper_quantile) def _format_arg(self, opt, spec, val): if opt == 'fixed_image_mask': if isdefined(self.inputs.moving_image_mask): return '--masks [ %s, %s ]' % (self.inputs.fixed_image_mask, self.inputs.moving_image_mask) else: return '--masks %s' % self.inputs.fixed_image_mask elif opt == 'transforms': return self._formatRegistration() elif opt == 'initial_moving_transform': try: doInvertTransform = int( self.inputs.invert_initial_moving_transform) except: doInvertTransform = 0 # Just do the default behavior return '--initial-moving-transform [ %s, %d ]' % (self.inputs.initial_moving_transform, doInvertTransform) elif opt == 'initial_moving_transform_com': try: doCenterOfMassInit = int( self.inputs.initial_moving_transform_com) except: doCenterOfMassInit = 0 # Just do the default behavior return '--initial-moving-transform [ %s, %s, %d ]' % (self.inputs.fixed_image[0], self.inputs.moving_image[ 0], doCenterOfMassInit) elif opt == 'interpolation': # TODO: handle multilabel, gaussian, and bspline options return '--interpolation %s' % self.inputs.interpolation elif opt == 'output_transform_prefix': out_filename = self._get_outputfilenames(inverse=False) inv_out_filename = self._get_outputfilenames(inverse=True) if out_filename and inv_out_filename: return '--output [ %s, %s, %s ]' % (self.inputs.output_transform_prefix, out_filename, inv_out_filename) elif out_filename: return '--output [ %s, %s ]' % (self.inputs.output_transform_prefix, out_filename) else: return '--output %s' % self.inputs.output_transform_prefix elif opt == 'winsorize_upper_quantile' or opt == 'winsorize_lower_quantile': if not self._quantilesDone: return self._formatWinsorizeImageIntensities() return '' # Must return something for argstr! # This feature was removed from recent versions of antsRegistration due to corrupt outputs. # elif opt == 'collapse_linear_transforms_to_fixed_image_header': # return self._formatCollapseLinearTransformsToFixedImageHeader() return super(Registration, self)._format_arg(opt, spec, val) def _outputFileNames(self, prefix, count, transform, inverse=False): self.lowDimensionalTransformMap = {'Rigid': 'Rigid.mat', 'Affine': 'Affine.mat', 'GenericAffine': 'GenericAffine.mat', 'CompositeAffine': 'Affine.mat', 'Similarity': 'Similarity.mat', 'Translation': 'Translation.mat', 'BSpline': 'BSpline.txt', 'Initial': 'DerivedInitialMovingTranslation.mat'} if transform in self.lowDimensionalTransformMap.keys(): suffix = self.lowDimensionalTransformMap[transform] inverse_mode = inverse else: inverse_mode = False # These are not analytically invertable if inverse: suffix = 'InverseWarp.nii.gz' else: suffix = 'Warp.nii.gz' return '%s%d%s' % (prefix, count, suffix), inverse_mode def _list_outputs(self): outputs = self._outputs().get() outputs['forward_transforms'] = [] outputs['forward_invert_flags'] = [] outputs['reverse_transforms'] = [] outputs['reverse_invert_flags'] = [] # invert_initial_moving_transform should be always defined, even if # there's no initial transform invert_initial_moving_transform = False if isdefined(self.inputs.invert_initial_moving_transform): invert_initial_moving_transform = self.inputs.invert_initial_moving_transform if self.inputs.write_composite_transform: fileName = self.inputs.output_transform_prefix + 'Composite.h5' outputs['composite_transform'] = os.path.abspath(fileName) fileName = self.inputs.output_transform_prefix + \ 'InverseComposite.h5' outputs['inverse_composite_transform'] = os.path.abspath(fileName) else: # If composite transforms are written, then individuals are not written (as of 2014-10-26 if not self.inputs.collapse_output_transforms: transformCount = 0 if isdefined(self.inputs.initial_moving_transform): outputs['forward_transforms'].append( self.inputs.initial_moving_transform) outputs['forward_invert_flags'].append( invert_initial_moving_transform) outputs['reverse_transforms'].insert( 0, self.inputs.initial_moving_transform) outputs['reverse_invert_flags'].insert( 0, not invert_initial_moving_transform) # Prepend transformCount += 1 elif isdefined(self.inputs.initial_moving_transform_com): forwardFileName, forwardInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, 'Initial') reverseFileName, reverseInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, 'Initial', True) outputs['forward_transforms'].append(os.path.abspath(forwardFileName)) outputs['forward_invert_flags'].append(False) outputs['reverse_transforms'].insert(0, os.path.abspath(reverseFileName)) outputs['reverse_invert_flags'].insert(0, True) transformCount += 1 for count in range(len(self.inputs.transforms)): forwardFileName, forwardInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, self.inputs.transforms[count]) reverseFileName, reverseInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, self.inputs.transforms[count], True) outputs['forward_transforms'].append( os.path.abspath(forwardFileName)) outputs['forward_invert_flags'].append(forwardInverseMode) outputs['reverse_transforms'].insert( 0, os.path.abspath(reverseFileName)) outputs[ 'reverse_invert_flags'].insert(0, reverseInverseMode) transformCount += 1 else: transformCount = 0 isLinear = [any(self._linear_transform_names == t) for t in self.inputs.transforms] collapse_list = [] if isdefined(self.inputs.initial_moving_transform) or \ isdefined(self.inputs.initial_moving_transform_com): isLinear.insert(0, True) # Only files returned by collapse_output_transforms if any(isLinear): collapse_list.append('GenericAffine') if not all(isLinear): collapse_list.append('SyN') for transform in collapse_list: forwardFileName, forwardInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, transform, inverse=False) reverseFileName, reverseInverseMode = self._outputFileNames( self.inputs.output_transform_prefix, transformCount, transform, inverse=True) outputs['forward_transforms'].append(os.path.abspath( forwardFileName)) outputs['forward_invert_flags'].append(forwardInverseMode) outputs['reverse_transforms'].append( os.path.abspath(reverseFileName)) outputs['reverse_invert_flags'].append(reverseInverseMode) transformCount += 1 out_filename = self._get_outputfilenames(inverse=False) inv_out_filename = self._get_outputfilenames(inverse=True) if out_filename: outputs['warped_image'] = os.path.abspath(out_filename) if inv_out_filename: outputs['inverse_warped_image'] = os.path.abspath(inv_out_filename) if len(self.inputs.save_state): outputs['save_state'] = os.path.abspath(self.inputs.save_state) return outputs nipype-0.11.0/nipype/interfaces/ants/resampling.py000066400000000000000000000473411257611314500222220ustar00rootroot00000000000000"""ANTS Apply Transforms interface Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from .base import ANTSCommand, ANTSCommandInputSpec from ..base import (TraitedSpec, File, traits, isdefined) from ...utils.filemanip import split_filename from nipype.interfaces.base import InputMultiPath class WarpTimeSeriesImageMultiTransformInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(4, 3, argstr='%d', usedefault=True, desc='image dimension (3 or 4)', position=1) input_image = File(argstr='%s', mandatory=True, copyfile=True, desc=('image to apply transformation to (generally a ' 'coregistered functional)')) out_postfix = traits.Str('_wtsimt', argstr='%s', usedefault=True, desc=('Postfix that is prepended to all output ' 'files (default = _wtsimt)')) reference_image = File(argstr='-R %s', xor=['tightest_box'], desc='reference image space that you wish to warp INTO') tightest_box = traits.Bool(argstr='--tightest-bounding-box', desc=('computes tightest bounding box (overrided by ' 'reference_image if given)'), xor=['reference_image']) reslice_by_header = traits.Bool(argstr='--reslice-by-header', desc=('Uses orientation matrix and origin encoded in ' 'reference image file header. Not typically used ' 'with additional transforms')) use_nearest = traits.Bool(argstr='--use-NN', desc='Use nearest neighbor interpolation') use_bspline = traits.Bool(argstr='--use-Bspline', desc='Use 3rd order B-Spline interpolation') transformation_series = InputMultiPath(File(exists=True), argstr='%s', desc='transformation file(s) to be applied', mandatory=True, copyfile=False) invert_affine = traits.List(traits.Int, desc=('List of Affine transformations to invert. ' 'E.g.: [1,4,5] inverts the 1st, 4th, and 5th Affines ' 'found in transformation_series')) class WarpTimeSeriesImageMultiTransformOutputSpec(TraitedSpec): output_image = File(exists=True, desc='Warped image') class WarpTimeSeriesImageMultiTransform(ANTSCommand): """Warps a time-series from one space to another Examples -------- >>> from nipype.interfaces.ants import WarpTimeSeriesImageMultiTransform >>> wtsimt = WarpTimeSeriesImageMultiTransform() >>> wtsimt.inputs.input_image = 'resting.nii' >>> wtsimt.inputs.reference_image = 'ants_deformed.nii.gz' >>> wtsimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt'] >>> wtsimt.cmdline 'WarpTimeSeriesImageMultiTransform 4 resting.nii resting_wtsimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt' """ _cmd = 'WarpTimeSeriesImageMultiTransform' input_spec = WarpTimeSeriesImageMultiTransformInputSpec output_spec = WarpTimeSeriesImageMultiTransformOutputSpec def _format_arg(self, opt, spec, val): if opt == 'out_postfix': _, name, ext = split_filename( os.path.abspath(self.inputs.input_image)) return name + val + ext if opt == 'transformation_series': series = [] affine_counter = 0 for transformation in val: if 'Affine' in transformation and \ isdefined(self.inputs.invert_affine): affine_counter += 1 if affine_counter in self.inputs.invert_affine: series += ['-i'], series += [transformation] return ' '.join(series) return super(WarpTimeSeriesImageMultiTransform, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(os.path.abspath(self.inputs.input_image)) outputs['output_image'] = os.path.join(os.getcwd(), ''.join((name, self.inputs.out_postfix, ext))) return outputs def _run_interface(self, runtime): runtime = super(WarpTimeSeriesImageMultiTransform, self)._run_interface(runtime, correct_return_codes = [0,1]) if "100 % complete" not in runtime.stdout: self.raise_exception(runtime) return runtime class WarpImageMultiTransformInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', usedefault=True, desc='image dimension (2 or 3)', position=1) input_image = File(argstr='%s', mandatory=True, desc=('image to apply transformation to (generally a ' 'coregistered functional)'), position=2) output_image = File(genfile=True, hash_files=False, argstr='%s', desc=('name of the output warped image'), position = 3, xor=['out_postfix']) out_postfix = File("_wimt", usedefault=True, hash_files=False, desc=('Postfix that is prepended to all output ' 'files (default = _wimt)'), xor=['output_image']) reference_image = File(argstr='-R %s', xor=['tightest_box'], desc='reference image space that you wish to warp INTO') tightest_box = traits.Bool(argstr='--tightest-bounding-box', desc=('computes tightest bounding box (overrided by ' 'reference_image if given)'), xor=['reference_image']) reslice_by_header = traits.Bool(argstr='--reslice-by-header', desc=('Uses orientation matrix and origin encoded in ' 'reference image file header. Not typically used ' 'with additional transforms')) use_nearest = traits.Bool(argstr='--use-NN', desc='Use nearest neighbor interpolation') use_bspline = traits.Bool(argstr='--use-BSpline', desc='Use 3rd order B-Spline interpolation') transformation_series = InputMultiPath(File(exists=True), argstr='%s', desc='transformation file(s) to be applied', mandatory=True, position=-1) invert_affine = traits.List(traits.Int, desc=('List of Affine transformations to invert.' 'E.g.: [1,4,5] inverts the 1st, 4th, and 5th Affines ' 'found in transformation_series. Note that indexing ' 'starts with 1 and does not include warp fields. Affine ' 'transformations are distinguished ' 'from warp fields by the word "affine" included in their filenames.')) class WarpImageMultiTransformOutputSpec(TraitedSpec): output_image = File(exists=True, desc='Warped image') class WarpImageMultiTransform(ANTSCommand): """Warps an image from one space to another Examples -------- >>> from nipype.interfaces.ants import WarpImageMultiTransform >>> wimt = WarpImageMultiTransform() >>> wimt.inputs.input_image = 'structural.nii' >>> wimt.inputs.reference_image = 'ants_deformed.nii.gz' >>> wimt.inputs.transformation_series = ['ants_Warp.nii.gz','ants_Affine.txt'] >>> wimt.cmdline 'WarpImageMultiTransform 3 structural.nii structural_wimt.nii -R ants_deformed.nii.gz ants_Warp.nii.gz ants_Affine.txt' >>> wimt = WarpImageMultiTransform() >>> wimt.inputs.input_image = 'diffusion_weighted.nii' >>> wimt.inputs.reference_image = 'functional.nii' >>> wimt.inputs.transformation_series = ['func2anat_coreg_Affine.txt','func2anat_InverseWarp.nii.gz','dwi2anat_Warp.nii.gz','dwi2anat_coreg_Affine.txt'] >>> wimt.inputs.invert_affine = [1] >>> wimt.cmdline 'WarpImageMultiTransform 3 diffusion_weighted.nii diffusion_weighted_wimt.nii -R functional.nii -i func2anat_coreg_Affine.txt func2anat_InverseWarp.nii.gz dwi2anat_Warp.nii.gz dwi2anat_coreg_Affine.txt' """ _cmd = 'WarpImageMultiTransform' input_spec = WarpImageMultiTransformInputSpec output_spec = WarpImageMultiTransformOutputSpec def _gen_filename(self, name): if name == 'output_image': _, name, ext = split_filename( os.path.abspath(self.inputs.input_image)) return ''.join((name, self.inputs.out_postfix, ext)) return None def _format_arg(self, opt, spec, val): if opt == 'transformation_series': series = [] affine_counter = 0 for transformation in val: if "affine" in transformation.lower() and \ isdefined(self.inputs.invert_affine): affine_counter += 1 if affine_counter in self.inputs.invert_affine: series += '-i', series += [transformation] return ' '.join(series) return super(WarpImageMultiTransform, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.output_image): outputs['output_image'] = os.path.abspath(self.inputs.output_image) else: outputs['output_image'] = os.path.abspath( self._gen_filename('output_image')) return outputs class ApplyTransformsInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(2, 3, 4, argstr='--dimensionality %d', desc=('This option forces the image to be treated ' 'as a specified-dimensional image. If not ' 'specified, antsWarp tries to infer the ' 'dimensionality from the input image.')) input_image_type = traits.Enum(0, 1, 2, 3, argstr='--input-image-type %d', desc=('Option specifying the input image ' 'type of scalar (default), vector, ' 'tensor, or time series.')) input_image = File(argstr='--input %s', mandatory=True, desc=('image to apply transformation to (generally a ' 'coregistered functional)'), exists=True) output_image = traits.Str(argstr='--output %s', desc=('output file name'), genfile=True, hash_files=False) out_postfix = traits.Str("_trans", usedefault=True, desc=('Postfix that is appended to all output ' 'files (default = _trans)')) reference_image = File(argstr='--reference-image %s', mandatory=True, desc='reference image space that you wish to warp INTO', exists=True) interpolation = traits.Enum('Linear', 'NearestNeighbor', 'CosineWindowedSinc', 'WelchWindowedSinc', 'HammingWindowedSinc', 'LanczosWindowedSinc', 'MultiLabel', 'Gaussian', 'BSpline', argstr='%s', usedefault=True) # TODO: Implement these options for multilabel, gaussian, and bspline # interpolation_sigma = traits.Float(requires=['interpolation']) # interpolation_alpha = traits.Float(requires=['interpolation_sigma']) # bspline_order = traits.Int(3, requires=['interpolation']) transforms = InputMultiPath( File(exists=True), argstr='%s', mandatory=True, desc=('')) invert_transform_flags = InputMultiPath(traits.Bool()) default_value = traits.Float( 0.0, argstr='--default-value %g', usedefault=True) print_out_composite_warp_file = traits.Enum( 0, 1, requires=["output_image"], desc=('')) # TODO: Change to boolean class ApplyTransformsOutputSpec(TraitedSpec): output_image = File(exists=True, desc='Warped image') class ApplyTransforms(ANTSCommand): """ApplyTransforms, applied to an input image, transforms it according to a reference image and a transform (or a set of transforms). Examples -------- >>> from nipype.interfaces.ants import ApplyTransforms >>> at = ApplyTransforms() >>> at.inputs.dimension = 3 >>> at.inputs.input_image = 'moving1.nii' >>> at.inputs.reference_image = 'fixed1.nii' >>> at.inputs.output_image = 'deformed_moving1.nii' >>> at.inputs.interpolation = 'Linear' >>> at.inputs.default_value = 0 >>> at.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz'] >>> at.inputs.invert_transform_flags = [False, False] >>> at.cmdline 'antsApplyTransforms --default-value 0 --dimensionality 3 --input moving1.nii --interpolation Linear --output deformed_moving1.nii --reference-image fixed1.nii --transform [trans.mat,0] --transform [ants_Warp.nii.gz,0]' """ _cmd = 'antsApplyTransforms' input_spec = ApplyTransformsInputSpec output_spec = ApplyTransformsOutputSpec def _gen_filename(self, name): if name == 'output_image': output = self.inputs.output_image if not isdefined(output): _, name, ext = split_filename(self.inputs.input_image) output = name + self.inputs.out_postfix + ext return output return None def _getTransformFileNames(self): retval = [] for ii in range(len(self.inputs.transforms)): if isdefined(self.inputs.invert_transform_flags): if len(self.inputs.transforms) == len(self.inputs.invert_transform_flags): invert_code = 1 if self.inputs.invert_transform_flags[ ii] else 0 retval.append("--transform [%s,%d]" % (self.inputs.transforms[ii], invert_code)) else: raise Exception("ERROR: The useInverse list must have the same number of entries as the transformsFileName list.") else: retval.append("--transform %s" % self.inputs.transforms[ii]) return " ".join(retval) def _getOutputWarpedFileName(self): if isdefined(self.inputs.print_out_composite_warp_file): return "--output [%s,%s]" % (self._gen_filename("output_image"), self.inputs.print_out_composite_warp_file) else: return "--output %s" % (self._gen_filename("output_image")) def _format_arg(self, opt, spec, val): if opt == "output_image": return self._getOutputWarpedFileName() elif opt == "transforms": return self._getTransformFileNames() elif opt == 'interpolation': # TODO: handle multilabel, gaussian, and bspline options return '--interpolation %s' % self.inputs.interpolation return super(ApplyTransforms, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['output_image'] = os.path.abspath( self._gen_filename('output_image')) return outputs class ApplyTransformsToPointsInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(2, 3, 4, argstr='--dimensionality %d', desc=('This option forces the image to be treated ' 'as a specified-dimensional image. If not ' 'specified, antsWarp tries to infer the ' 'dimensionality from the input image.')) input_file = File(argstr='--input %s', mandatory=True, desc=("Currently, the only input supported is a csv file with " "columns including x,y (2D), x,y,z (3D) or x,y,z,t,label (4D) column headers." "The points should be defined in physical space." "If in doubt how to convert coordinates from your files to the space" "required by antsApplyTransformsToPoints try creating/drawing a simple" "label volume with only one voxel set to 1 and all others set to 0." "Write down the voxel coordinates. Then use ImageMaths LabelStats to find" "out what coordinates for this voxel antsApplyTransformsToPoints is" "expecting."), exists=True) output_file = traits.Str(argstr='--output %s', desc=('Name of the output CSV file'), name_source=['input_file'], hash_files=False, name_template='%s_transformed.csv') transforms = traits.List(File(exists=True), argstr='%s', mandatory=True, desc=('transforms that will be applied to the points')) invert_transform_flags = traits.List(traits.Bool(), desc=('list indicating if a transform should be reversed')) class ApplyTransformsToPointsOutputSpec(TraitedSpec): output_file = File(exists=True, desc='csv file with transformed coordinates') class ApplyTransformsToPoints(ANTSCommand): """ApplyTransformsToPoints, applied to an CSV file, transforms coordinates using provided transform (or a set of transforms). Examples -------- >>> from nipype.interfaces.ants import ApplyTransforms >>> at = ApplyTransformsToPoints() >>> at.inputs.dimension = 3 >>> at.inputs.input_file = 'moving.csv' >>> at.inputs.transforms = ['trans.mat', 'ants_Warp.nii.gz'] >>> at.inputs.invert_transform_flags = [False, False] >>> at.cmdline 'antsApplyTransformsToPoints --dimensionality 3 --input moving.csv --output moving_transformed.csv --transform [trans.mat,0] --transform [ants_Warp.nii.gz,0]' """ _cmd = 'antsApplyTransformsToPoints' input_spec = ApplyTransformsToPointsInputSpec output_spec = ApplyTransformsToPointsOutputSpec def _getTransformFileNames(self): retval = [] for ii in range(len(self.inputs.transforms)): if isdefined(self.inputs.invert_transform_flags): if len(self.inputs.transforms) == len(self.inputs.invert_transform_flags): invert_code = 1 if self.inputs.invert_transform_flags[ ii] else 0 retval.append("--transform [%s,%d]" % (self.inputs.transforms[ii], invert_code)) else: raise Exception("ERROR: The useInverse list must have the same number of entries as the transformsFileName list.") else: retval.append("--transform %s" % self.inputs.transforms[ii]) return " ".join(retval) def _format_arg(self, opt, spec, val): if opt == "transforms": return self._getTransformFileNames() return super(ApplyTransformsToPoints, self)._format_arg(opt, spec, val) nipype-0.11.0/nipype/interfaces/ants/segmentation.py000066400000000000000000001100251257611314500225440ustar00rootroot00000000000000"""The ants module provides basic functions for interfacing with ants functions. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from ..base import (TraitedSpec, File, traits, InputMultiPath, OutputMultiPath, isdefined) from ...utils.filemanip import split_filename from .base import ANTSCommand, ANTSCommandInputSpec import os from ...utils.filemanip import copyfile class AtroposInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, 4, argstr='--image-dimensionality %d', usedefault=True, desc='image dimension (2, 3, or 4)') intensity_images = InputMultiPath(File(exists=True), argstr="--intensity-image %s...", mandatory=True) mask_image = File(exists=True, argstr='--mask-image %s', mandatory=True) initialization = traits.Enum('Random', 'Otsu', 'KMeans', 'PriorProbabilityImages', 'PriorLabelImage', argstr="%s", requires=['number_of_tissue_classes'], mandatory=True) prior_probability_images = InputMultiPath(File(exists=True)) number_of_tissue_classes = traits.Int(mandatory=True) prior_weighting = traits.Float() prior_probability_threshold = traits.Float(requires=['prior_weighting']) likelihood_model = traits.Str(argstr="--likelihood-model %s") mrf_smoothing_factor = traits.Float(argstr="%s") mrf_radius = traits.List(traits.Int(), requires=['mrf_smoothing_factor']) icm_use_synchronous_update = traits.Bool(argstr="%s") maximum_number_of_icm_terations = traits.Int( requires=['icm_use_synchronous_update']) n_iterations = traits.Int(argstr="%s") convergence_threshold = traits.Float(requires=['n_iterations']) posterior_formulation = traits.Str(argstr="%s") use_mixture_model_proportions = traits.Bool( requires=['posterior_formulation']) out_classified_image_name = File(argstr="%s", genfile=True, hash_files=False) save_posteriors = traits.Bool() output_posteriors_name_template = traits.Str('POSTERIOR_%02d.nii.gz', usedefault=True) class AtroposOutputSpec(TraitedSpec): classified_image = File(exists=True) posteriors = OutputMultiPath(File(exist=True)) class Atropos(ANTSCommand): """A finite mixture modeling (FMM) segmentation approach with possibilities for specifying prior constraints. These prior constraints include the specification of a prior label image, prior probability images (one for each class), and/or an MRF prior to enforce spatial smoothing of the labels. Similar algorithms include FAST and SPM. Examples -------- >>> from nipype.interfaces.ants import Atropos >>> at = Atropos() >>> at.inputs.dimension = 3 >>> at.inputs.intensity_images = 'structural.nii' >>> at.inputs.mask_image = 'mask.nii' >>> at.inputs.initialization = 'PriorProbabilityImages' >>> at.inputs.prior_probability_images = ['rc1s1.nii', 'rc1s2.nii'] >>> at.inputs.number_of_tissue_classes = 2 >>> at.inputs.prior_weighting = 0.8 >>> at.inputs.prior_probability_threshold = 0.0000001 >>> at.inputs.likelihood_model = 'Gaussian' >>> at.inputs.mrf_smoothing_factor = 0.2 >>> at.inputs.mrf_radius = [1, 1, 1] >>> at.inputs.icm_use_synchronous_update = True >>> at.inputs.maximum_number_of_icm_terations = 1 >>> at.inputs.n_iterations = 5 >>> at.inputs.convergence_threshold = 0.000001 >>> at.inputs.posterior_formulation = 'Socrates' >>> at.inputs.use_mixture_model_proportions = True >>> at.inputs.save_posteriors = True >>> at.cmdline 'Atropos --image-dimensionality 3 --icm [1,1] --initialization PriorProbabilityImages[2,priors/priorProbImages%02d.nii,0.8,1e-07] --intensity-image structural.nii --likelihood-model Gaussian --mask-image mask.nii --mrf [0.2,1x1x1] --convergence [5,1e-06] --output [structural_labeled.nii,POSTERIOR_%02d.nii.gz] --posterior-formulation Socrates[1]' """ input_spec = AtroposInputSpec output_spec = AtroposOutputSpec _cmd = 'Atropos' def _format_arg(self, opt, spec, val): if opt == 'initialization': retval = "--initialization %s[%d" % (val, self.inputs.number_of_tissue_classes) if val == "PriorProbabilityImages": _, _, ext = split_filename( self.inputs.prior_probability_images[0]) retval += ",priors/priorProbImages%02d" + \ ext + ",%g" % self.inputs.prior_weighting if isdefined(self.inputs.prior_probability_threshold): retval += ",%g" % self.inputs.prior_probability_threshold return retval + "]" if opt == 'mrf_smoothing_factor': retval = "--mrf [%g" % val if isdefined(self.inputs.mrf_radius): retval += ",%s" % 'x'.join([str(s) for s in self.inputs.mrf_radius]) return retval + "]" if opt == "icm_use_synchronous_update": retval = "--icm [%d" % val if isdefined(self.inputs.maximum_number_of_icm_terations): retval += ",%g" % self.inputs.maximum_number_of_icm_terations return retval + "]" if opt == "n_iterations": retval = "--convergence [%d" % val if isdefined(self.inputs.convergence_threshold): retval += ",%g" % self.inputs.convergence_threshold return retval + "]" if opt == "posterior_formulation": retval = "--posterior-formulation %s" % val if isdefined(self.inputs.use_mixture_model_proportions): retval += "[%d]" % self.inputs.use_mixture_model_proportions return retval if opt == "out_classified_image_name": retval = "--output [%s" % val if isdefined(self.inputs.save_posteriors): retval += ",%s" % self.inputs.output_posteriors_name_template return retval + "]" return super(ANTSCommand, self)._format_arg(opt, spec, val) def _run_interface(self, runtime, correct_return_codes=[0]): if self.inputs.initialization == "PriorProbabilityImages": priors_directory = os.path.join(os.getcwd(), "priors") if not os.path.exists(priors_directory): os.makedirs(priors_directory) _, _, ext = split_filename(self.inputs.prior_probability_images[0]) for i, f in enumerate(self.inputs.prior_probability_images): target = os.path.join(priors_directory, 'priorProbImages%02d' % (i + 1) + ext) if not (os.path.exists(target) and os.path.realpath(target) == os.path.abspath(f)): copyfile(os.path.abspath(f), os.path.join(priors_directory, 'priorProbImages%02d' % (i + 1) + ext)) runtime = super(Atropos, self)._run_interface(runtime) return runtime def _gen_filename(self, name): if name == 'out_classified_image_name': output = self.inputs.out_classified_image_name if not isdefined(output): _, name, ext = split_filename(self.inputs.intensity_images[0]) output = name + '_labeled' + ext return output return None def _list_outputs(self): outputs = self._outputs().get() outputs['classified_image'] = os.path.abspath( self._gen_filename('out_classified_image_name')) if isdefined(self.inputs.save_posteriors) and self.inputs.save_posteriors: outputs['posteriors'] = [] for i in range(self.inputs.number_of_tissue_classes): outputs['posteriors'].append(os.path.abspath( self.inputs.output_posteriors_name_template % (i + 1))) return outputs class LaplacianThicknessInputSpec(ANTSCommandInputSpec): input_wm = File(argstr='%s', mandatory=True, copyfile=True, desc='white matter segmentation image', position=1) input_gm = File(argstr='%s', mandatory=True, copyfile=True, desc='gray matter segmentation image', position=2) output_image = File(desc='name of output file', argstr='%s', position=3, genfile=True, hash_files=False) smooth_param = traits.Float(argstr='smoothparam=%d', desc='', position=4) prior_thickness = traits.Float(argstr='priorthickval=%d', desc='', position=5) dT = traits.Float(argstr='dT=%d', desc='', position=6) sulcus_prior = traits.Bool(argstr='use-sulcus-prior', desc='', position=7) opt_tolerance = traits.Float(argstr='optional-laplacian-tolerance=%d', desc='', position=8) class LaplacianThicknessOutputSpec(TraitedSpec): output_image = File(exists=True, desc='Cortical thickness') class LaplacianThickness(ANTSCommand): """Calculates the cortical thickness from an anatomical image Examples -------- >>> from nipype.interfaces.ants import LaplacianThickness >>> cort_thick = LaplacianThickness() >>> cort_thick.inputs.input_wm = 'white_matter.nii.gz' >>> cort_thick.inputs.input_gm = 'gray_matter.nii.gz' >>> cort_thick.inputs.output_image = 'output_thickness.nii.gz' >>> cort_thick.cmdline 'LaplacianThickness white_matter.nii.gz gray_matter.nii.gz output_thickness.nii.gz' """ _cmd = 'LaplacianThickness' input_spec = LaplacianThicknessInputSpec output_spec = LaplacianThicknessOutputSpec def _gen_filename(self, name): if name == 'output_image': output = self.inputs.output_image if not isdefined(output): _, name, ext = split_filename(self.inputs.input_wm) output = name + '_thickness' + ext return output return None def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(os.path.abspath(self.inputs.input_wm)) outputs['output_image'] = os.path.join(os.getcwd(), ''.join((name, self.inputs.output_image, ext))) return outputs class N4BiasFieldCorrectionInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='-d %d', usedefault=True, desc='image dimension (2 or 3)') input_image = File(argstr='--input-image %s', mandatory=True, desc=('image to apply transformation to (generally a ' 'coregistered functional)')) mask_image = File(argstr='--mask-image %s') weight_image = File(argstr='--weight-image %s') output_image = traits.Str(argstr='--output %s', desc='output file name', genfile=True, hash_files=False) bspline_fitting_distance = traits.Float(argstr="--bspline-fitting %s") bspline_order = traits.Int(requires=['bspline_fitting_distance']) shrink_factor = traits.Int(argstr="--shrink-factor %d") n_iterations = traits.List(traits.Int(), argstr="--convergence %s") convergence_threshold = traits.Float(requires=['n_iterations']) save_bias = traits.Bool(False, mandatory=True, usedefault=True, desc=('True if the estimated bias should be saved' ' to file.'), xor=['bias_image']) bias_image = File(desc='Filename for the estimated bias.', hash_files=False) class N4BiasFieldCorrectionOutputSpec(TraitedSpec): output_image = File(exists=True, desc='Warped image') bias_image = File(exists=True, desc='Estimated bias') class N4BiasFieldCorrection(ANTSCommand): """N4 is a variant of the popular N3 (nonparameteric nonuniform normalization) retrospective bias correction algorithm. Based on the assumption that the corruption of the low frequency bias field can be modeled as a convolution of the intensity histogram by a Gaussian, the basic algorithmic protocol is to iterate between deconvolving the intensity histogram by a Gaussian, remapping the intensities, and then spatially smoothing this result by a B-spline modeling of the bias field itself. The modifications from and improvements obtained over the original N3 algorithm are described in [Tustison2010]_. .. [Tustison2010] N. Tustison et al., N4ITK: Improved N3 Bias Correction, IEEE Transactions on Medical Imaging, 29(6):1310-1320, June 2010. Examples -------- >>> import copy >>> from nipype.interfaces.ants import N4BiasFieldCorrection >>> n4 = N4BiasFieldCorrection() >>> n4.inputs.dimension = 3 >>> n4.inputs.input_image = 'structural.nii' >>> n4.inputs.bspline_fitting_distance = 300 >>> n4.inputs.shrink_factor = 3 >>> n4.inputs.n_iterations = [50,50,30,20] >>> n4.cmdline 'N4BiasFieldCorrection --bspline-fitting [ 300 ] \ -d 3 --input-image structural.nii \ --convergence [ 50x50x30x20 ] --output structural_corrected.nii \ --shrink-factor 3' >>> n4_2 = copy.deepcopy(n4) >>> n4_2.inputs.convergence_threshold = 1e-6 >>> n4_2.cmdline 'N4BiasFieldCorrection --bspline-fitting [ 300 ] \ -d 3 --input-image structural.nii \ --convergence [ 50x50x30x20, 1e-06 ] --output structural_corrected.nii \ --shrink-factor 3' >>> n4_3 = copy.deepcopy(n4_2) >>> n4_3.inputs.bspline_order = 5 >>> n4_3.cmdline 'N4BiasFieldCorrection --bspline-fitting [ 300, 5 ] \ -d 3 --input-image structural.nii \ --convergence [ 50x50x30x20, 1e-06 ] --output structural_corrected.nii \ --shrink-factor 3' >>> n4_4 = N4BiasFieldCorrection() >>> n4_4.inputs.input_image = 'structural.nii' >>> n4_4.inputs.save_bias = True >>> n4_4.cmdline 'N4BiasFieldCorrection -d 3 --input-image structural.nii \ --output [ structural_corrected.nii, structural_bias.nii ]' """ _cmd = 'N4BiasFieldCorrection' input_spec = N4BiasFieldCorrectionInputSpec output_spec = N4BiasFieldCorrectionOutputSpec def _gen_filename(self, name): if name == 'output_image': output = self.inputs.output_image if not isdefined(output): _, name, ext = split_filename(self.inputs.input_image) output = name + '_corrected' + ext return output if name == 'bias_image': output = self.inputs.bias_image if not isdefined(output): _, name, ext = split_filename(self.inputs.input_image) output = name + '_bias' + ext return output return None def _format_arg(self, name, trait_spec, value): if ((name == 'output_image') and (self.inputs.save_bias or isdefined(self.inputs.bias_image))): bias_image = self._gen_filename('bias_image') output = self._gen_filename('output_image') newval = '[ %s, %s ]' % (output, bias_image) return trait_spec.argstr % newval if name == 'bspline_fitting_distance': if isdefined(self.inputs.bspline_order): newval = '[ %g, %d ]' % (value, self.inputs.bspline_order) else: newval = '[ %g ]' % value return trait_spec.argstr % newval if name == 'n_iterations': if isdefined(self.inputs.convergence_threshold): newval = '[ %s, %g ]' % ('x'.join([str(elt) for elt in value]), self.inputs.convergence_threshold) else: newval = '[ %s ]' % 'x'.join([str(elt) for elt in value]) return trait_spec.argstr % newval return super(N4BiasFieldCorrection, self)._format_arg(name, trait_spec, value) def _parse_inputs(self, skip=None): if skip is None: skip = [] skip += ['save_bias', 'bias_image'] return super(N4BiasFieldCorrection, self)._parse_inputs(skip=skip) def _list_outputs(self): outputs = self._outputs().get() outputs['output_image'] = os.path.abspath( self._gen_filename('output_image')) if self.inputs.save_bias or isdefined(self.inputs.bias_image): outputs['bias_image'] = os.path.abspath( self._gen_filename('bias_image')) return outputs class antsCorticalThicknessInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='-d %d', usedefault=True, desc='image dimension (2 or 3)') anatomical_image = File(exists=True, argstr='-a %s', desc=('Structural *intensity* image, typically T1.' 'If more than one anatomical image is specified,' 'subsequently specified images are used during the' 'segmentation process. However, only the first' 'image is used in the registration of priors.' 'Our suggestion would be to specify the T1' 'as the first image.'), mandatory=True) brain_template = File(exists=True, argstr='-e %s', desc=('Anatomical *intensity* template (possibly created using a' 'population data set with buildtemplateparallel.sh in ANTs).' 'This template is *not* skull-stripped.'), mandatory=True) brain_probability_mask = File(exists=True, argstr='-m %s', desc='brain probability mask in template space', copyfile=False, mandatory=True) segmentation_priors = InputMultiPath( File(exists=True), argstr='-p %s', mandatory=True) out_prefix = traits.Str('antsCT_', argstr='-o %s', usedefault=True, desc=('Prefix that is prepended to all output' ' files (default = antsCT_)')) image_suffix = traits.Str('nii.gz', desc=('any of standard ITK formats,' ' nii.gz is default'), argstr='-s %s', usedefault=True) t1_registration_template = File(exists=True, desc=('Anatomical *intensity* template' '(assumed to be skull-stripped). A common' 'case would be where this would be the same' 'template as specified in the -e option which' 'is not skull stripped.'), argstr='-t %s', mandatory=True) extraction_registration_mask = File(exists=True, argstr='-f %s', desc=('Mask (defined in the template space) used during' ' registration for brain extraction.')) keep_temporary_files = traits.Int(argstr='-k %d', desc='Keep brain extraction/segmentation warps, etc (default = 0).') max_iterations = traits.Int(argstr='-i %d', desc=('ANTS registration max iterations' '(default = 100x100x70x20)')) prior_segmentation_weight = traits.Float(argstr='-w %f', desc=('Atropos spatial prior *probability* weight for' 'the segmentation')) segmentation_iterations = traits.Int(argstr='-n %d', desc=('N4 -> Atropos -> N4 iterations during segmentation' '(default = 3)')) posterior_formulation = traits.Str(argstr='-b %s', desc=('Atropos posterior formulation and whether or not' 'to use mixture model proportions.' '''e.g 'Socrates[1]' (default) or 'Aristotle[1]'.''' 'Choose the latter if you' 'want use the distance priors (see also the -l option' 'for label propagation control).')) use_floatingpoint_precision = traits.Enum(0, 1, argstr='-j %d', desc=('Use floating point precision ' 'in registrations (default = 0)')) use_random_seeding = traits.Enum(0, 1, argstr='-u %d', desc=('Use random number generated from system clock in Atropos' '(default = 1)')) b_spline_smoothing = traits.Bool(argstr='-v', desc=('Use B-spline SyN for registrations and B-spline' 'exponential mapping in DiReCT.')) cortical_label_image = File(exists=True, desc='Cortical ROI labels to use as a prior for ATITH.') label_propagation = traits.Str(argstr='-l %s', desc=('Incorporate a distance prior one the posterior formulation. Should be' '''of the form 'label[lambda,boundaryProbability]' where label''' 'is a value of 1,2,3,... denoting label ID. The label' 'probability for anything outside the current label' ' = boundaryProbability * exp( -lambda * distanceFromBoundary )' 'Intuitively, smaller lambda values will increase the spatial capture' 'range of the distance prior. To apply to all label values, simply omit' 'specifying the label, i.e. -l [lambda,boundaryProbability].')) quick_registration = traits.Bool(argstr='-q 1', desc=('If = 1, use antsRegistrationSyNQuick.sh as the basis for registration' 'during brain extraction, brain segmentation, and' '(optional) normalization to a template.' 'Otherwise use antsRegistrationSyN.sh (default = 0).')) debug = traits.Bool(argstr='-z 1', desc=('If > 0, runs a faster version of the script.' 'Only for testing. Implies -u 0.' 'Requires single thread computation for complete reproducibility.')) class antsCorticalThicknessoutputSpec(TraitedSpec): BrainExtractionMask = File(exists=True, desc='brain extraction mask') BrainSegmentation = File(exists=True, desc='brain segmentaion image') BrainSegmentationN4 = File(exists=True, desc='N4 corrected image') BrainSegmentationPosteriors = OutputMultiPath(File(exists=True), desc='Posterior probability images') CorticalThickness = File(exists=True, desc='cortical thickness file') TemplateToSubject1GenericAffine = File( exists=True, desc='Template to subject affine') TemplateToSubject0Warp = File(exists=True, desc='Template to subject warp') SubjectToTemplate1Warp = File( exists=True, desc='Template to subject inverse warp') SubjectToTemplate0GenericAffine = File( exists=True, desc='Template to subject inverse affine') SubjectToTemplateLogJacobian = File( exists=True, desc='Template to subject log jacobian') CorticalThicknessNormedToTemplate = File(exists=True, desc='Normalized cortical thickness') BrainVolumes = File(exists=True, desc='Brain volumes as text') class antsCorticalThickness(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants.segmentation import antsCorticalThickness >>> corticalthickness = antsCorticalThickness() >>> corticalthickness.inputs.dimension = 3 >>> corticalthickness.inputs.anatomical_image ='T1.nii.gz' >>> corticalthickness.inputs.brain_template = 'study_template.nii.gz' >>> corticalthickness.inputs.brain_probability_mask ='ProbabilityMaskOfStudyTemplate.nii.gz' >>> corticalthickness.inputs.segmentation_priors = ['BrainSegmentationPrior01.nii.gz', 'BrainSegmentationPrior02.nii.gz', 'BrainSegmentationPrior03.nii.gz', 'BrainSegmentationPrior04.nii.gz'] >>> corticalthickness.inputs.t1_registration_template = 'brain_study_template.nii.gz' >>> corticalthickness.cmdline 'antsCorticalThickness.sh -a T1.nii.gz -m ProbabilityMaskOfStudyTemplate.nii.gz -e study_template.nii.gz -d 3 -s nii.gz -o antsCT_ -p nipype_priors/BrainSegmentationPrior%02d.nii.gz -t brain_study_template.nii.gz' """ input_spec = antsCorticalThicknessInputSpec output_spec = antsCorticalThicknessoutputSpec _cmd = 'antsCorticalThickness.sh' def _format_arg(self, opt, spec, val): if opt == 'anatomical_image': retval = '-a %s' % val return retval if opt == 'brain_template': retval = '-e %s' % val return retval if opt == 'brain_probability_mask': retval = '-m %s' % val return retval if opt == 'out_prefix': retval = '-o %s' % val return retval if opt == 't1_registration_template': retval = '-t %s' % val return retval if opt == 'segmentation_priors': _, _, ext = split_filename(self.inputs.segmentation_priors[0]) retval = "-p nipype_priors/BrainSegmentationPrior%02d" + ext return retval return super(ANTSCommand, self)._format_arg(opt, spec, val) def _run_interface(self, runtime, correct_return_codes=[0]): priors_directory = os.path.join(os.getcwd(), "nipype_priors") if not os.path.exists(priors_directory): os.makedirs(priors_directory) _, _, ext = split_filename(self.inputs.segmentation_priors[0]) for i, f in enumerate(self.inputs.segmentation_priors): target = os.path.join( priors_directory, 'BrainSegmentationPrior%02d' % (i + 1) + ext) if not (os.path.exists(target) and os.path.realpath(target) == os.path.abspath(f)): copyfile(os.path.abspath(f), target) runtime = super(antsCorticalThickness, self)._run_interface(runtime) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['BrainExtractionMask'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'BrainExtractionMask.' + self.inputs.image_suffix) outputs['BrainSegmentation'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'BrainSegmentation.' + self.inputs.image_suffix) outputs['BrainSegmentationN4'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'BrainSegmentation0N4.' + self.inputs.image_suffix) posteriors = [] for i in range(len(self.inputs.segmentation_priors)): posteriors.append(os.path.join(os.getcwd(), self.inputs.out_prefix + 'BrainSegmentationPosteriors%02d.' % (i + 1) + self.inputs.image_suffix)) outputs['BrainSegmentationPosteriors'] = posteriors outputs['CorticalThickness'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'CorticalThickness.' + self.inputs.image_suffix) outputs['TemplateToSubject1GenericAffine'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'TemplateToSubject1GenericAffine.mat') outputs['TemplateToSubject0Warp'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'TemplateToSubject0Warp.' + self.inputs.image_suffix) outputs['SubjectToTemplate1Warp'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'SubjectToTemplate1Warp.' + self.inputs.image_suffix) outputs['SubjectToTemplate0GenericAffine'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'SubjectToTemplate0GenericAffine.mat') outputs['SubjectToTemplateLogJacobian'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'SubjectToTemplateLogJacobian.' + self.inputs.image_suffix) outputs['CorticalThicknessNormedToTemplate'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'CorticalThickness.' + self.inputs.image_suffix) outputs['BrainVolumes'] = os.path.join(os.getcwd(), self.inputs.out_prefix + 'brainvols.csv') return outputs class JointFusionInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, 4, argstr='%d', position=0, usedefault=True, mandatory=True, desc='image dimension (2, 3, or 4)') modalities = traits.Int(argstr='%d', position=1, mandatory=True, desc='Number of modalities or features') warped_intensity_images = InputMultiPath(File(exists=True), argstr="-g %s...", mandatory=True, desc='Warped atlas images') target_image = InputMultiPath(File(exists=True), argstr='-tg %s...', mandatory=True, desc='Target image(s)') warped_label_images = InputMultiPath(File(exists=True), argstr="-l %s...", mandatory=True, desc='Warped atlas segmentations') method = traits.Str(default='Joint', argstr='-m %s', usedefault=True, desc=('Select voting method. Options: Joint (Joint ' 'Label Fusion). May be followed by optional ' 'parameters in brackets, e.g., -m Joint[0.1,2]')) alpha = traits.Float(default=0.1, usedefault=True, requires=['method'], desc=('Regularization term added to matrix Mx for ' 'inverse')) beta = traits.Int(default=2, usedefault=True, requires=['method'], desc=('Exponent for mapping intensity difference to joint' ' error')) output_label_image = File(argstr='%s', mandatory=True, position=-1, name_template='%s', output_name='output_label_image', desc='Output fusion label map image') patch_radius = traits.ListInt(minlen=3, maxlen=3, argstr='-rp %s', desc=('Patch radius for similarity measures, ' 'scalar or vector. Default: 2x2x2')) search_radius = traits.ListInt(minlen=3, maxlen=3, argstr='-rs %s', desc='Local search radius. Default: 3x3x3') exclusion_region = File(exists=True, argstr='-x %s', desc=('Specify an exclusion region for the given ' 'label.')) atlas_group_id = traits.ListInt(argstr='-gp %d...', desc=('Assign a group ID for each atlas')) atlas_group_weights = traits.ListInt(argstr='-gpw %d...', desc=('Assign the voting weights to ' 'each atlas group')) class JointFusionOutputSpec(TraitedSpec): output_label_image = File(exists=True) # TODO: optional outputs - output_posteriors, output_voting_weights class JointFusion(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import JointFusion >>> at = JointFusion() >>> at.inputs.dimension = 3 >>> at.inputs.modalities = 1 >>> at.inputs.method = 'Joint[0.1,2]' >>> at.inputs.output_label_image ='fusion_labelimage_output.nii' >>> at.inputs.warped_intensity_images = ['im1.nii', ... 'im2.nii', ... 'im3.nii'] >>> at.inputs.warped_label_images = ['segmentation0.nii.gz', ... 'segmentation1.nii.gz', ... 'segmentation1.nii.gz'] >>> at.inputs.target_image = 'T1.nii' >>> at.cmdline 'jointfusion 3 1 -m Joint[0.1,2] -tg T1.nii -g im1.nii -g im2.nii -g im3.nii -l segmentation0.nii.gz -l segmentation1.nii.gz -l segmentation1.nii.gz fusion_labelimage_output.nii' >>> at.inputs.method = 'Joint' >>> at.inputs.alpha = 0.5 >>> at.inputs.beta = 1 >>> at.inputs.patch_radius = [3,2,1] >>> at.inputs.search_radius = [1,2,3] >>> at.cmdline 'jointfusion 3 1 -m Joint[0.5,1] -rp 3x2x1 -rs 1x2x3 -tg T1.nii -g im1.nii -g im2.nii -g im3.nii -l segmentation0.nii.gz -l segmentation1.nii.gz -l segmentation1.nii.gz fusion_labelimage_output.nii' """ input_spec = JointFusionInputSpec output_spec = JointFusionOutputSpec _cmd = 'jointfusion' def _format_arg(self, opt, spec, val): if opt == 'method': if '[' in val: retval = '-m {0}'.format(val) else: retval = '-m {0}[{1},{2}]'.format( self.inputs.method, self.inputs.alpha, self.inputs.beta) elif opt == 'patch_radius': retval = '-rp {0}'.format(self._format_xarray(val)) elif opt == 'search_radius': retval = '-rs {0}'.format(self._format_xarray(val)) else: if opt == 'warped_intensity_images': assert len(val) == self.inputs.modalities * len(self.inputs.warped_label_images), "Number of intensity images and label maps must be the same {0}!={1}".format( len(val), len(self.inputs.warped_label_images)) return super(ANTSCommand, self)._format_arg(opt, spec, val) return retval def _list_outputs(self): outputs = self._outputs().get() outputs['output_label_image'] = os.path.abspath( self.inputs.output_label_image) return outputs nipype-0.11.0/nipype/interfaces/ants/tests/000077500000000000000000000000001257611314500206405ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/ants/tests/__init__.py000066400000000000000000000001621257611314500227500ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_ANTS.py000066400000000000000000000050261257611314500240510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.registration import ANTS def test_ANTS_inputs(): input_map = dict(affine_gradient_descent_option=dict(argstr='%s', ), args=dict(argstr='%s', ), delta_time=dict(requires=['number_of_time_steps'], ), dimension=dict(argstr='%d', position=1, usedefault=False, ), environ=dict(nohash=True, usedefault=True, ), fixed_image=dict(mandatory=True, ), gradient_step_length=dict(requires=['transformation_model'], ), ignore_exception=dict(nohash=True, usedefault=True, ), metric=dict(mandatory=True, ), metric_weight=dict(requires=['metric'], ), mi_option=dict(argstr='--MI-option %s', sep='x', ), moving_image=dict(argstr='%s', mandatory=True, ), num_threads=dict(nohash=True, usedefault=True, ), number_of_affine_iterations=dict(argstr='--number-of-affine-iterations %s', sep='x', ), number_of_iterations=dict(argstr='--number-of-iterations %s', sep='x', ), number_of_time_steps=dict(requires=['gradient_step_length'], ), output_transform_prefix=dict(argstr='--output-naming %s', mandatory=True, usedefault=True, ), radius=dict(requires=['metric'], ), regularization=dict(argstr='%s', ), regularization_deformation_field_sigma=dict(requires=['regularization'], ), regularization_gradient_field_sigma=dict(requires=['regularization'], ), smoothing_sigmas=dict(argstr='--gaussian-smoothing-sigmas %s', sep='x', ), subsampling_factors=dict(argstr='--subsampling-factors %s', sep='x', ), symmetry_type=dict(requires=['delta_time'], ), terminal_output=dict(nohash=True, ), transformation_model=dict(argstr='%s', mandatory=True, ), use_histogram_matching=dict(argstr='%s', usedefault=True, ), ) inputs = ANTS.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ANTS_outputs(): output_map = dict(affine_transform=dict(), inverse_warp_transform=dict(), metaheader=dict(), metaheader_raw=dict(), warp_transform=dict(), ) outputs = ANTS.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_ANTSCommand.py000066400000000000000000000012451257611314500253470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.base import ANTSCommand def test_ANTSCommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_threads=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ANTSCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_ApplyTransforms.py000066400000000000000000000032671257611314500264550ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.resampling import ApplyTransforms def test_ApplyTransforms_inputs(): input_map = dict(args=dict(argstr='%s', ), default_value=dict(argstr='--default-value %g', usedefault=True, ), dimension=dict(argstr='--dimensionality %d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='--input %s', mandatory=True, ), input_image_type=dict(argstr='--input-image-type %d', ), interpolation=dict(argstr='%s', usedefault=True, ), invert_transform_flags=dict(), num_threads=dict(nohash=True, usedefault=True, ), out_postfix=dict(usedefault=True, ), output_image=dict(argstr='--output %s', genfile=True, hash_files=False, ), print_out_composite_warp_file=dict(requires=['output_image'], ), reference_image=dict(argstr='--reference-image %s', mandatory=True, ), terminal_output=dict(nohash=True, ), transforms=dict(argstr='%s', mandatory=True, ), ) inputs = ApplyTransforms.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyTransforms_outputs(): output_map = dict(output_image=dict(), ) outputs = ApplyTransforms.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_ApplyTransformsToPoints.py000066400000000000000000000025701257611314500301510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.resampling import ApplyTransformsToPoints def test_ApplyTransformsToPoints_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='--dimensionality %d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_file=dict(argstr='--input %s', mandatory=True, ), invert_transform_flags=dict(), num_threads=dict(nohash=True, usedefault=True, ), output_file=dict(argstr='--output %s', hash_files=False, name_source=['input_file'], name_template='%s_transformed.csv', ), terminal_output=dict(nohash=True, ), transforms=dict(argstr='%s', mandatory=True, ), ) inputs = ApplyTransformsToPoints.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyTransformsToPoints_outputs(): output_map = dict(output_file=dict(), ) outputs = ApplyTransformsToPoints.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_Atropos.py000066400000000000000000000043531257611314500247350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.segmentation import Atropos def test_Atropos_inputs(): input_map = dict(args=dict(argstr='%s', ), convergence_threshold=dict(requires=['n_iterations'], ), dimension=dict(argstr='--image-dimensionality %d', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), icm_use_synchronous_update=dict(argstr='%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialization=dict(argstr='%s', mandatory=True, requires=['number_of_tissue_classes'], ), intensity_images=dict(argstr='--intensity-image %s...', mandatory=True, ), likelihood_model=dict(argstr='--likelihood-model %s', ), mask_image=dict(argstr='--mask-image %s', mandatory=True, ), maximum_number_of_icm_terations=dict(requires=['icm_use_synchronous_update'], ), mrf_radius=dict(requires=['mrf_smoothing_factor'], ), mrf_smoothing_factor=dict(argstr='%s', ), n_iterations=dict(argstr='%s', ), num_threads=dict(nohash=True, usedefault=True, ), number_of_tissue_classes=dict(mandatory=True, ), out_classified_image_name=dict(argstr='%s', genfile=True, hash_files=False, ), output_posteriors_name_template=dict(usedefault=True, ), posterior_formulation=dict(argstr='%s', ), prior_probability_images=dict(), prior_probability_threshold=dict(requires=['prior_weighting'], ), prior_weighting=dict(), save_posteriors=dict(), terminal_output=dict(nohash=True, ), use_mixture_model_proportions=dict(requires=['posterior_formulation'], ), ) inputs = Atropos.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Atropos_outputs(): output_map = dict(classified_image=dict(), posteriors=dict(), ) outputs = Atropos.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_AverageAffineTransform.py000066400000000000000000000024161257611314500276630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.utils import AverageAffineTransform def test_AverageAffineTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', mandatory=True, position=0, usedefault=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_threads=dict(nohash=True, usedefault=True, ), output_affine_transform=dict(argstr='%s', mandatory=True, position=1, ), terminal_output=dict(nohash=True, ), transforms=dict(argstr='%s', mandatory=True, position=3, ), ) inputs = AverageAffineTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AverageAffineTransform_outputs(): output_map = dict(affine_transform=dict(), ) outputs = AverageAffineTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_AverageImages.py000066400000000000000000000024521257611314500260040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.utils import AverageImages def test_AverageImages_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', mandatory=True, position=0, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), images=dict(argstr='%s', mandatory=True, position=3, ), normalize=dict(argstr='%d', mandatory=True, position=2, ), num_threads=dict(nohash=True, usedefault=True, ), output_average_image=dict(argstr='%s', hash_files=False, position=1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = AverageImages.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AverageImages_outputs(): output_map = dict(output_average_image=dict(), ) outputs = AverageImages.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_ConvertScalarImageToRGB.py000066400000000000000000000035311257611314500276520ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.visualization import ConvertScalarImageToRGB def test_ConvertScalarImageToRGB_inputs(): input_map = dict(args=dict(argstr='%s', ), colormap=dict(argstr='%s', mandatory=True, position=4, usedefault=True, ), custom_color_map_file=dict(argstr='%s', position=5, usedefault=True, ), dimension=dict(argstr='%d', mandatory=True, position=0, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='%s', mandatory=True, position=1, ), mask_image=dict(argstr='%s', position=3, usedefault=True, ), maximum_RGB_output=dict(argstr='%d', position=9, usedefault=True, ), maximum_input=dict(argstr='%d', mandatory=True, position=7, ), minimum_RGB_output=dict(argstr='%d', position=8, usedefault=True, ), minimum_input=dict(argstr='%d', mandatory=True, position=6, ), num_threads=dict(nohash=True, usedefault=True, ), output_image=dict(argstr='%s', position=2, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ConvertScalarImageToRGB.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ConvertScalarImageToRGB_outputs(): output_map = dict(output_image=dict(), ) outputs = ConvertScalarImageToRGB.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_CreateTiledMosaic.py000066400000000000000000000030141257611314500266200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.visualization import CreateTiledMosaic def test_CreateTiledMosaic_inputs(): input_map = dict(alpha_value=dict(argstr='-a %.2f', ), args=dict(argstr='%s', ), direction=dict(argstr='-d %d', ), environ=dict(nohash=True, usedefault=True, ), flip_slice=dict(argstr='-f %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='-i %s', mandatory=True, ), mask_image=dict(argstr='-x %s', ), num_threads=dict(nohash=True, usedefault=True, ), output_image=dict(argstr='-o %s', usedefault=True, ), pad_or_crop=dict(argstr='-p %s', ), permute_axes=dict(argstr='-g', ), rgb_image=dict(argstr='-r %s', mandatory=True, ), slices=dict(argstr='-s %s', ), terminal_output=dict(nohash=True, ), tile_geometry=dict(argstr='-t %s', ), ) inputs = CreateTiledMosaic.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CreateTiledMosaic_outputs(): output_map = dict(output_image=dict(), ) outputs = CreateTiledMosaic.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_GenWarpFields.py000066400000000000000000000034011257611314500257710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.legacy import GenWarpFields def test_GenWarpFields_inputs(): input_map = dict(args=dict(argstr='%s', ), bias_field_correction=dict(argstr='-n 1', ), dimension=dict(argstr='-d %d', position=1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), force_proceed=dict(argstr='-f 1', ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='-i %s', copyfile=False, mandatory=True, ), inverse_warp_template_labels=dict(argstr='-l', ), max_iterations=dict(argstr='-m %s', sep='x', ), num_threads=dict(nohash=True, usedefault=True, ), out_prefix=dict(argstr='-o %s', usedefault=True, ), quality_check=dict(argstr='-q 1', ), reference_image=dict(argstr='-r %s', copyfile=True, mandatory=True, ), similarity_metric=dict(argstr='-s %s', ), terminal_output=dict(nohash=True, ), transformation_model=dict(argstr='-t %s', usedefault=True, ), ) inputs = GenWarpFields.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenWarpFields_outputs(): output_map = dict(affine_transformation=dict(), input_file=dict(), inverse_warp_field=dict(), output_file=dict(), warp_field=dict(), ) outputs = GenWarpFields.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_JacobianDeterminant.py000066400000000000000000000027751257611314500272150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.utils import JacobianDeterminant def test_JacobianDeterminant_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', mandatory=True, position=0, usedefault=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), norm_by_total=dict(argstr='%d', position=5, ), num_threads=dict(nohash=True, usedefault=True, ), output_prefix=dict(argstr='%s', genfile=True, hash_files=False, position=2, ), projection_vector=dict(argstr='%s', position=6, sep='x', ), template_mask=dict(argstr='%s', position=4, ), terminal_output=dict(nohash=True, ), use_log=dict(argstr='%d', position=3, ), warp_file=dict(argstr='%s', mandatory=True, position=1, ), ) inputs = JacobianDeterminant.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JacobianDeterminant_outputs(): output_map = dict(jacobian_image=dict(), ) outputs = JacobianDeterminant.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_JointFusion.py000066400000000000000000000037451257611314500255610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.segmentation import JointFusion def test_JointFusion_inputs(): input_map = dict(alpha=dict(requires=['method'], usedefault=True, ), args=dict(argstr='%s', ), atlas_group_id=dict(argstr='-gp %d...', ), atlas_group_weights=dict(argstr='-gpw %d...', ), beta=dict(requires=['method'], usedefault=True, ), dimension=dict(argstr='%d', mandatory=True, position=0, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), exclusion_region=dict(argstr='-x %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), method=dict(argstr='-m %s', usedefault=True, ), modalities=dict(argstr='%d', mandatory=True, position=1, ), num_threads=dict(nohash=True, usedefault=True, ), output_label_image=dict(argstr='%s', mandatory=True, name_template='%s', output_name='output_label_image', position=-1, ), patch_radius=dict(argstr='-rp %s', maxlen=3, minlen=3, ), search_radius=dict(argstr='-rs %s', maxlen=3, minlen=3, ), target_image=dict(argstr='-tg %s...', mandatory=True, ), terminal_output=dict(nohash=True, ), warped_intensity_images=dict(argstr='-g %s...', mandatory=True, ), warped_label_images=dict(argstr='-l %s...', mandatory=True, ), ) inputs = JointFusion.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JointFusion_outputs(): output_map = dict(output_label_image=dict(), ) outputs = JointFusion.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_LaplacianThickness.py000066400000000000000000000031671257611314500270500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.segmentation import LaplacianThickness def test_LaplacianThickness_inputs(): input_map = dict(args=dict(argstr='%s', ), dT=dict(argstr='dT=%d', position=6, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_gm=dict(argstr='%s', copyfile=True, mandatory=True, position=2, ), input_wm=dict(argstr='%s', copyfile=True, mandatory=True, position=1, ), num_threads=dict(nohash=True, usedefault=True, ), opt_tolerance=dict(argstr='optional-laplacian-tolerance=%d', position=8, ), output_image=dict(argstr='%s', genfile=True, hash_files=False, position=3, ), prior_thickness=dict(argstr='priorthickval=%d', position=5, ), smooth_param=dict(argstr='smoothparam=%d', position=4, ), sulcus_prior=dict(argstr='use-sulcus-prior', position=7, ), terminal_output=dict(nohash=True, ), ) inputs = LaplacianThickness.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LaplacianThickness_outputs(): output_map = dict(output_image=dict(), ) outputs = LaplacianThickness.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_MultiplyImages.py000066400000000000000000000024661257611314500262560ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.utils import MultiplyImages def test_MultiplyImages_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', mandatory=True, position=0, usedefault=False, ), environ=dict(nohash=True, usedefault=True, ), first_input=dict(argstr='%s', mandatory=True, position=1, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_threads=dict(nohash=True, usedefault=True, ), output_product_image=dict(argstr='%s', mandatory=True, position=3, ), second_input=dict(argstr='%s', mandatory=True, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = MultiplyImages.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultiplyImages_outputs(): output_map = dict(output_product_image=dict(), ) outputs = MultiplyImages.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_N4BiasFieldCorrection.py000066400000000000000000000034651257611314500273650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.segmentation import N4BiasFieldCorrection def test_N4BiasFieldCorrection_inputs(): input_map = dict(args=dict(argstr='%s', ), bias_image=dict(hash_files=False, ), bspline_fitting_distance=dict(argstr='--bspline-fitting %s', ), bspline_order=dict(requires=['bspline_fitting_distance'], ), convergence_threshold=dict(requires=['n_iterations'], ), dimension=dict(argstr='-d %d', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='--input-image %s', mandatory=True, ), mask_image=dict(argstr='--mask-image %s', ), n_iterations=dict(argstr='--convergence %s', ), num_threads=dict(nohash=True, usedefault=True, ), output_image=dict(argstr='--output %s', genfile=True, hash_files=False, ), save_bias=dict(mandatory=True, usedefault=True, xor=['bias_image'], ), shrink_factor=dict(argstr='--shrink-factor %d', ), terminal_output=dict(nohash=True, ), weight_image=dict(argstr='--weight-image %s', ), ) inputs = N4BiasFieldCorrection.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_N4BiasFieldCorrection_outputs(): output_map = dict(bias_image=dict(), output_image=dict(), ) outputs = N4BiasFieldCorrection.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_Registration.py000066400000000000000000000077361257611314500257700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.registration import Registration def test_Registration_inputs(): input_map = dict(args=dict(argstr='%s', ), collapse_output_transforms=dict(argstr='--collapse-output-transforms %d', usedefault=True, ), convergence_threshold=dict(requires=['number_of_iterations'], usedefault=True, ), convergence_window_size=dict(requires=['convergence_threshold'], usedefault=True, ), dimension=dict(argstr='--dimensionality %d', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), fixed_image=dict(mandatory=True, ), fixed_image_mask=dict(argstr='%s', ), float=dict(argstr='--float %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), initial_moving_transform=dict(argstr='%s', xor=['initial_moving_transform_com'], ), initial_moving_transform_com=dict(argstr='%s', xor=['initial_moving_transform'], ), initialize_transforms_per_stage=dict(argstr='--initialize-transforms-per-stage %d', usedefault=True, ), interpolation=dict(argstr='%s', usedefault=True, ), invert_initial_moving_transform=dict(requires=['initial_moving_transform'], xor=['initial_moving_transform_com'], ), metric=dict(mandatory=True, ), metric_item_trait=dict(), metric_stage_trait=dict(), metric_weight=dict(mandatory=True, requires=['metric'], usedefault=True, ), metric_weight_item_trait=dict(), metric_weight_stage_trait=dict(), moving_image=dict(mandatory=True, ), moving_image_mask=dict(requires=['fixed_image_mask'], ), num_threads=dict(nohash=True, usedefault=True, ), number_of_iterations=dict(), output_inverse_warped_image=dict(hash_files=False, requires=['output_warped_image'], ), output_transform_prefix=dict(argstr='%s', usedefault=True, ), output_warped_image=dict(hash_files=False, ), radius_bins_item_trait=dict(), radius_bins_stage_trait=dict(), radius_or_number_of_bins=dict(requires=['metric_weight'], usedefault=True, ), restore_state=dict(argstr='--restore-state %s', ), sampling_percentage=dict(requires=['sampling_strategy'], ), sampling_percentage_item_trait=dict(), sampling_percentage_stage_trait=dict(), sampling_strategy=dict(requires=['metric_weight'], ), sampling_strategy_item_trait=dict(), sampling_strategy_stage_trait=dict(), save_state=dict(argstr='--save-state %s', ), shrink_factors=dict(mandatory=True, ), sigma_units=dict(requires=['smoothing_sigmas'], ), smoothing_sigmas=dict(mandatory=True, ), terminal_output=dict(nohash=True, ), transform_parameters=dict(), transforms=dict(argstr='%s', mandatory=True, ), use_estimate_learning_rate_once=dict(), use_histogram_matching=dict(usedefault=True, ), winsorize_lower_quantile=dict(argstr='%s', usedefault=True, ), winsorize_upper_quantile=dict(argstr='%s', usedefault=True, ), write_composite_transform=dict(argstr='--write-composite-transform %d', usedefault=True, ), ) inputs = Registration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Registration_outputs(): output_map = dict(composite_transform=dict(), forward_invert_flags=dict(), forward_transforms=dict(), inverse_composite_transform=dict(), inverse_warped_image=dict(), reverse_invert_flags=dict(), reverse_transforms=dict(), save_state=dict(), warped_image=dict(), ) outputs = Registration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_WarpImageMultiTransform.py000066400000000000000000000034721257611314500300720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.resampling import WarpImageMultiTransform def test_WarpImageMultiTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', position=1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='%s', mandatory=True, position=2, ), invert_affine=dict(), num_threads=dict(nohash=True, usedefault=True, ), out_postfix=dict(hash_files=False, usedefault=True, xor=['output_image'], ), output_image=dict(argstr='%s', genfile=True, hash_files=False, position=3, xor=['out_postfix'], ), reference_image=dict(argstr='-R %s', xor=['tightest_box'], ), reslice_by_header=dict(argstr='--reslice-by-header', ), terminal_output=dict(nohash=True, ), tightest_box=dict(argstr='--tightest-bounding-box', xor=['reference_image'], ), transformation_series=dict(argstr='%s', mandatory=True, position=-1, ), use_bspline=dict(argstr='--use-BSpline', ), use_nearest=dict(argstr='--use-NN', ), ) inputs = WarpImageMultiTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WarpImageMultiTransform_outputs(): output_map = dict(output_image=dict(), ) outputs = WarpImageMultiTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_WarpTimeSeriesImageMultiTransform.py000066400000000000000000000033301257611314500320550ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.resampling import WarpTimeSeriesImageMultiTransform def test_WarpTimeSeriesImageMultiTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='%d', position=1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='%s', copyfile=True, mandatory=True, ), invert_affine=dict(), num_threads=dict(nohash=True, usedefault=True, ), out_postfix=dict(argstr='%s', usedefault=True, ), reference_image=dict(argstr='-R %s', xor=['tightest_box'], ), reslice_by_header=dict(argstr='--reslice-by-header', ), terminal_output=dict(nohash=True, ), tightest_box=dict(argstr='--tightest-bounding-box', xor=['reference_image'], ), transformation_series=dict(argstr='%s', copyfile=False, mandatory=True, ), use_bspline=dict(argstr='--use-Bspline', ), use_nearest=dict(argstr='--use-NN', ), ) inputs = WarpTimeSeriesImageMultiTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WarpTimeSeriesImageMultiTransform_outputs(): output_map = dict(output_image=dict(), ) outputs = WarpTimeSeriesImageMultiTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_antsCorticalThickness.py000066400000000000000000000051561257611314500276120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.segmentation import antsCorticalThickness def test_antsCorticalThickness_inputs(): input_map = dict(anatomical_image=dict(argstr='-a %s', mandatory=True, ), args=dict(argstr='%s', ), b_spline_smoothing=dict(argstr='-v', ), brain_probability_mask=dict(argstr='-m %s', copyfile=False, mandatory=True, ), brain_template=dict(argstr='-e %s', mandatory=True, ), cortical_label_image=dict(), debug=dict(argstr='-z 1', ), dimension=dict(argstr='-d %d', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), extraction_registration_mask=dict(argstr='-f %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), image_suffix=dict(argstr='-s %s', usedefault=True, ), keep_temporary_files=dict(argstr='-k %d', ), label_propagation=dict(argstr='-l %s', ), max_iterations=dict(argstr='-i %d', ), num_threads=dict(nohash=True, usedefault=True, ), out_prefix=dict(argstr='-o %s', usedefault=True, ), posterior_formulation=dict(argstr='-b %s', ), prior_segmentation_weight=dict(argstr='-w %f', ), quick_registration=dict(argstr='-q 1', ), segmentation_iterations=dict(argstr='-n %d', ), segmentation_priors=dict(argstr='-p %s', mandatory=True, ), t1_registration_template=dict(argstr='-t %s', mandatory=True, ), terminal_output=dict(nohash=True, ), use_floatingpoint_precision=dict(argstr='-j %d', ), use_random_seeding=dict(argstr='-u %d', ), ) inputs = antsCorticalThickness.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_antsCorticalThickness_outputs(): output_map = dict(BrainExtractionMask=dict(), BrainSegmentation=dict(), BrainSegmentationN4=dict(), BrainSegmentationPosteriors=dict(), BrainVolumes=dict(), CorticalThickness=dict(), CorticalThicknessNormedToTemplate=dict(), SubjectToTemplate0GenericAffine=dict(), SubjectToTemplate1Warp=dict(), SubjectToTemplateLogJacobian=dict(), TemplateToSubject0Warp=dict(), TemplateToSubject1GenericAffine=dict(), ) outputs = antsCorticalThickness.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_antsIntroduction.py000066400000000000000000000034201257611314500266470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.legacy import antsIntroduction def test_antsIntroduction_inputs(): input_map = dict(args=dict(argstr='%s', ), bias_field_correction=dict(argstr='-n 1', ), dimension=dict(argstr='-d %d', position=1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), force_proceed=dict(argstr='-f 1', ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='-i %s', copyfile=False, mandatory=True, ), inverse_warp_template_labels=dict(argstr='-l', ), max_iterations=dict(argstr='-m %s', sep='x', ), num_threads=dict(nohash=True, usedefault=True, ), out_prefix=dict(argstr='-o %s', usedefault=True, ), quality_check=dict(argstr='-q 1', ), reference_image=dict(argstr='-r %s', copyfile=True, mandatory=True, ), similarity_metric=dict(argstr='-s %s', ), terminal_output=dict(nohash=True, ), transformation_model=dict(argstr='-t %s', usedefault=True, ), ) inputs = antsIntroduction.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_antsIntroduction_outputs(): output_map = dict(affine_transformation=dict(), input_file=dict(), inverse_warp_field=dict(), output_file=dict(), warp_field=dict(), ) outputs = antsIntroduction.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_auto_buildtemplateparallel.py000066400000000000000000000035461257611314500276610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.ants.legacy import buildtemplateparallel def test_buildtemplateparallel_inputs(): input_map = dict(args=dict(argstr='%s', ), bias_field_correction=dict(argstr='-n 1', ), dimension=dict(argstr='-d %d', position=1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), gradient_step_size=dict(argstr='-g %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=-1, ), iteration_limit=dict(argstr='-i %d', usedefault=True, ), max_iterations=dict(argstr='-m %s', sep='x', ), num_cores=dict(argstr='-j %d', requires=['parallelization'], ), num_threads=dict(nohash=True, usedefault=True, ), out_prefix=dict(argstr='-o %s', usedefault=True, ), parallelization=dict(argstr='-c %d', usedefault=True, ), rigid_body_registration=dict(argstr='-r 1', ), similarity_metric=dict(argstr='-s %s', ), terminal_output=dict(nohash=True, ), transformation_model=dict(argstr='-t %s', usedefault=True, ), use_first_as_target=dict(), ) inputs = buildtemplateparallel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_buildtemplateparallel_outputs(): output_map = dict(final_template_file=dict(), subject_outfiles=dict(), template_files=dict(), ) outputs = buildtemplateparallel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/ants/tests/test_spec_JointFusion.py000066400000000000000000000063571257611314500255450ustar00rootroot00000000000000from nipype.testing import assert_equal, assert_raises, example_data from nipype.interfaces.base import InputMultiPath from traits.trait_errors import TraitError from nipype.interfaces.ants import JointFusion def test_JointFusion_dimension(): at = JointFusion() set_dimension = lambda d: setattr(at.inputs, 'dimension', int(d)) for d in range(2, 5): set_dimension(d) yield assert_equal, at.inputs.dimension, int(d) for d in [0, 1, 6, 7]: yield assert_raises, TraitError, set_dimension, d def test_JointFusion_modalities(): at = JointFusion() set_modalities = lambda m: setattr(at.inputs, 'modalities', int(m)) for m in range(1, 5): set_modalities(m) yield assert_equal, at.inputs.modalities, int(m) def test_JointFusion_method(): at = JointFusion() set_method = lambda a, b: setattr(at.inputs, 'method', 'Joint[%.1f,%d]'.format(a, b)) for a in range(10): _a = a / 10.0 for b in range(10): set_method(_a, b) # set directly yield assert_equal, at.inputs.method, 'Joint[%.1f,%d]'.format(_a, b) aprime = _a + 0.1 bprime = b + 1 at.inputs.alpha = aprime at.inputs.beta = bprime # set with alpha/beta yield assert_equal, at.inputs.method, 'Joint[%.1f,%d]'.format(aprime, bprime) def test_JointFusion_radius(): at = JointFusion() set_radius = lambda attr,x,y,z: setattr(at.inputs, attr, [x, y, z]) for attr in ['patch_radius', 'search_radius']: for x in range(5): set_radius(attr, x, x + 1, x**x) yield assert_equal, at._format_arg(attr, None, getattr(at.inputs, attr))[4:], '{0}x{1}x{2}'.format(x, x + 1, x**x) def test_JointFusion_cmd(): at = JointFusion() at.inputs.dimension = 3 at.inputs.modalities = 1 at.inputs.method = 'Joint[0.1,2]' at.inputs.output_label_image = 'fusion_labelimage_output.nii' warped_intensity_images = [example_data('im1.nii'), example_data('im2.nii')] at.inputs.warped_intensity_images = warped_intensity_images segmentation_images = [example_data('segmentation0.nii.gz'), example_data('segmentation1.nii.gz')] at.inputs.warped_label_images = segmentation_images T1_image = example_data('T1.nii') at.inputs.target_image = T1_image at.inputs.patch_radius = [3,2,1] at.inputs.search_radius = [1,2,3] expected_command = ('jointfusion 3 1 -m Joint[0.1,2] -rp 3x2x1 -rs 1x2x3' ' -tg %s -g %s -g %s -l %s -l %s' ' fusion_labelimage_output.nii') % (T1_image, warped_intensity_images[0], warped_intensity_images[1], segmentation_images[0], segmentation_images[1]) yield assert_equal, at.cmdline, expected_command # setting intensity or labels with unequal lengths raises error yield assert_raises, AssertionError, at._format_arg, 'warped_intensity_images', InputMultiPath, warped_intensity_images + [example_data('im3.nii')] nipype-0.11.0/nipype/interfaces/ants/utils.py000066400000000000000000000173501257611314500212160ustar00rootroot00000000000000"""ANTS Apply Transforms interface Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from .base import ANTSCommand, ANTSCommandInputSpec from ..base import (TraitedSpec, File, traits, isdefined) from ...utils.filemanip import split_filename from nipype.interfaces.base import InputMultiPath class AverageAffineTransformInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', usedefault=False, mandatory=True, position=0, desc='image dimension (2 or 3)') output_affine_transform = File(argstr='%s', mandatory=True, position=1, desc='Outputfname.txt: the name of the resulting transform.') transforms = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=3, desc=('transforms to average')) class AverageAffineTransformOutputSpec(TraitedSpec): affine_transform = File(exists=True, desc='average transform file') class AverageAffineTransform(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import AverageAffineTransform >>> avg = AverageAffineTransform() >>> avg.inputs.dimension = 3 >>> avg.inputs.transforms = ['trans.mat', 'func_to_struct.mat'] >>> avg.inputs.output_affine_transform = 'MYtemplatewarp.mat' >>> avg.cmdline 'AverageAffineTransform 3 MYtemplatewarp.mat trans.mat func_to_struct.mat' """ _cmd = 'AverageAffineTransform' input_spec = AverageAffineTransformInputSpec output_spec = AverageAffineTransformOutputSpec def _format_arg(self, opt, spec, val): return super(AverageAffineTransform, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['affine_transform'] = os.path.abspath( self.inputs.output_affine_transform) return outputs class AverageImagesInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', mandatory=True, position=0, desc='image dimension (2 or 3)') output_average_image = File("average.nii", argstr='%s', position=1, desc='the name of the resulting image.', usedefault=True, hash_files=False) normalize = traits.Bool(argstr="%d", mandatory=True, position=2, desc='Normalize: if true, the 2nd image' + 'is divided by its mean. This will select the largest image to average into.') images = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=3, desc=('image to apply transformation to (generally a coregistered functional)')) class AverageImagesOutputSpec(TraitedSpec): output_average_image = File(exists=True, desc='average image file') class AverageImages(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import AverageImages >>> avg = AverageImages() >>> avg.inputs.dimension = 3 >>> avg.inputs.output_average_image = "average.nii.gz" >>> avg.inputs.normalize = True >>> avg.inputs.images = ['rc1s1.nii', 'rc1s1.nii'] >>> avg.cmdline 'AverageImages 3 average.nii.gz 1 rc1s1.nii rc1s1.nii' """ _cmd = 'AverageImages' input_spec = AverageImagesInputSpec output_spec = AverageImagesOutputSpec def _format_arg(self, opt, spec, val): return super(AverageImages, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['output_average_image'] = os.path.realpath( self.inputs.output_average_image) return outputs class MultiplyImagesInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', usedefault=False, mandatory=True, position=0, desc='image dimension (2 or 3)') first_input = File( argstr='%s', exists=True, mandatory=True, position=1, desc='image 1') second_input = traits.Either(File(exists=True), traits.Float, argstr='%s', mandatory=True, position=2, desc='image 2 or multiplication weight') output_product_image = File(argstr='%s', mandatory=True, position=3, desc='Outputfname.nii.gz: the name of the resulting image.') class MultiplyImagesOutputSpec(TraitedSpec): output_product_image = File(exists=True, desc='average image file') class MultiplyImages(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import MultiplyImages >>> test = MultiplyImages() >>> test.inputs.dimension = 3 >>> test.inputs.first_input = 'moving2.nii' >>> test.inputs.second_input = 0.25 >>> test.inputs.output_product_image = "out.nii" >>> test.cmdline 'MultiplyImages 3 moving2.nii 0.25 out.nii' """ _cmd = 'MultiplyImages' input_spec = MultiplyImagesInputSpec output_spec = MultiplyImagesOutputSpec def _format_arg(self, opt, spec, val): return super(MultiplyImages, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['output_product_image'] = os.path.abspath( self.inputs.output_product_image) return outputs class JacobianDeterminantInputSpec(ANTSCommandInputSpec): dimension = traits.Enum(3, 2, argstr='%d', usedefault=False, mandatory=True, position=0, desc='image dimension (2 or 3)') warp_file = File(argstr='%s', exists=True, mandatory=True, position=1, desc='input warp file') output_prefix = File(argstr='%s', genfile=True, hash_files=False, position=2, desc=('prefix of the output image filename: ' 'PREFIX(log)jacobian.nii.gz')) use_log = traits.Enum(0, 1, argstr='%d', position=3, desc='log transform the jacobian determinant') template_mask = File(argstr='%s', exists=True, position=4, desc='template mask to adjust for head size') norm_by_total = traits.Enum(0, 1, argstr='%d', position=5, desc=('normalize jacobian by total in mask to ' 'adjust for head size')) projection_vector = traits.List(traits.Float(), argstr='%s', sep='x', position=6, desc='vector to project warp against') class JacobianDeterminantOutputSpec(TraitedSpec): jacobian_image = File(exists=True, desc='(log transformed) jacobian image') class JacobianDeterminant(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants import JacobianDeterminant >>> jacobian = JacobianDeterminant() >>> jacobian.inputs.dimension = 3 >>> jacobian.inputs.warp_file = 'ants_Warp.nii.gz' >>> jacobian.inputs.output_prefix = 'Sub001_' >>> jacobian.inputs.use_log = 1 >>> jacobian.cmdline 'ANTSJacobian 3 ants_Warp.nii.gz Sub001_ 1' """ _cmd = 'ANTSJacobian' input_spec = JacobianDeterminantInputSpec output_spec = JacobianDeterminantOutputSpec def _gen_filename(self, name): if name == 'output_prefix': output = self.inputs.output_prefix if not isdefined(output): _, name, ext = split_filename(self.inputs.warp_file) output = name + '_' return output return None def _list_outputs(self): outputs = self._outputs().get() if self.inputs.use_log == 1: outputs['jacobian_image'] = os.path.abspath( self._gen_filename('output_prefix') + 'logjacobian.nii.gz') else: outputs['jacobian_image'] = os.path.abspath( self._gen_filename('output_prefix') + 'jacobian.nii.gz') return outputs nipype-0.11.0/nipype/interfaces/ants/visualization.py000066400000000000000000000161361257611314500227600ustar00rootroot00000000000000"""The ants visualisation module provides basic functions based on ITK. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from ..base import (TraitedSpec, File, traits) from .base import ANTSCommand, ANTSCommandInputSpec from nipype.utils.filemanip import split_filename from nipype.interfaces.base import InputMultiPath from nipype.interfaces.traits_extension import isdefined import numpy as np import os class ConvertScalarImageToRGBInputSpec(ANTSCommandInputSpec): dimension=traits.Enum(3, 2, argstr= '%d', usedefault=True, desc='image dimension (2 or 3)', mandatory=True, position = 0) input_image=File(argstr='%s', exists=True, desc='Main input is a 3-D grayscale image.', mandatory=True, position = 1) output_image=traits.Str('rgb.nii.gz', argstr='%s', usedefault=True, desc=('rgb output image'), position = 2) mask_image=File('none', argstr='%s', exists=True, desc = 'mask image', position = 3, usedefault = True) colormap=traits.Str(argstr='%s', usedefault=True, desc=('Possible colormaps: grey, red, green, ' 'blue, copper, jet, hsv, spring, summer, ' 'autumn, winter, hot, cool, overunder, custom ' ), mandatory = True, position = 4) custom_color_map_file=traits.Str('none', argstr='%s', usedefault=True, desc = 'custom color map file', position = 5) minimum_input = traits.Int(argstr='%d', desc='minimum input', mandatory = True, position = 6) maximum_input = traits.Int(argstr='%d', desc='maximum input', mandatory = True, position = 7) minimum_RGB_output = traits.Int(0, usedefault=True, argstr='%d', desc = '', position = 8) maximum_RGB_output = traits.Int(255, usedefault=True, argstr='%d', desc = '', position = 9) class ConvertScalarImageToRGBOutputSpec(TraitedSpec): output_image= File(exists=True, desc='converted RGB image') class ConvertScalarImageToRGB(ANTSCommand): """ Examples -------- >>> from nipype.interfaces.ants.visualization import ConvertScalarImageToRGB >>> converter = ConvertScalarImageToRGB() >>> converter.inputs.dimension = 3 >>> converter.inputs.input_image = 'T1.nii.gz' >>> converter.inputs.colormap = 'jet' >>> converter.inputs.minimum_input = 0 >>> converter.inputs.maximum_input = 6 >>> converter.cmdline 'ConvertScalarImageToRGB 3 T1.nii.gz rgb.nii.gz none jet none 0 6 0 255' """ _cmd = 'ConvertScalarImageToRGB' input_spec = ConvertScalarImageToRGBInputSpec output_spec = ConvertScalarImageToRGBOutputSpec def _format_arg(self, opt, spec, val): return super(ConvertScalarImageToRGB, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['output_image'] = os.path.join(os.getcwd(), self.inputs.output_image) return outputs class CreateTiledMosaicInputSpec(ANTSCommandInputSpec): input_image = File(argstr='-i %s', exists=True, desc = 'Main input is a 3-D grayscale image.', mandatory = True) rgb_image= File(argstr='-r %s', exists = True, desc = ('An optional Rgb image can be added as an overlay.' 'It must have the same image' 'geometry as the input grayscale image.'), mandatory = True) mask_image = File(argstr = '-x %s', exists = True, desc = 'Specifies the ROI of the RGB voxels used.') alpha_value = traits.Float(argstr = '-a %.2f', desc = ('If an Rgb image is provided, render the overlay ' 'using the specified alpha parameter.')) output_image = traits.Str('output.png', argstr = '-o %s', desc = 'The output consists of the tiled mosaic image.', usedefault = True) tile_geometry = traits.Str(argstr = '-t %s',desc = ( 'The tile geometry specifies the number of rows and columns' 'in the output image. For example, if the user specifies "5x10", ' 'then 5 rows by 10 columns of slices are rendered. If R < 0 and C > ' '0 (or vice versa), the negative value is selected' 'based on direction.')) direction = traits.Int(argstr = '-d %d', desc = ('Specifies the direction of ' 'the slices. If no direction is specified, the ' 'direction with the coarsest spacing is chosen.')) pad_or_crop = traits.Str(argstr='-p %s', desc = 'argument passed to -p flag:' '[padVoxelWidth,]' '[lowerPadding[0]xlowerPadding[1],upperPadding[0]xupperPadding[1],' 'constantValue]' 'The user can specify whether to pad or crop a specified ' 'voxel-width boundary of each individual slice. For this ' 'program, cropping is simply padding with negative voxel-widths.' 'If one pads (+), the user can also specify a constant pad ' 'value (default = 0). If a mask is specified, the user can use ' 'the mask to define the region, by using the keyword "mask"' ' plus an offset, e.g. "-p mask+3".' ) slices = traits.Str(argstr='-s %s', desc = ('Number of slices to increment Slice1xSlice2xSlice3' '[numberOfSlicesToIncrement,,]')) flip_slice = traits.Str(argstr = '-f %s', desc = ('flipXxflipY')) permute_axes = traits.Bool(argstr = '-g', desc = 'doPermute' ) class CreateTiledMosaicOutputSpec(TraitedSpec): output_image= File(exists=True, desc='image file') class CreateTiledMosaic(ANTSCommand): """The program CreateTiledMosaic in conjunction with ConvertScalarImageToRGB provides useful functionality for common image analysis tasks. The basic usage of CreateTiledMosaic is to tile a 3-D image volume slice-wise into a 2-D image. Examples -------- >>> from nipype.interfaces.ants.visualization import CreateTiledMosaic >>> mosaic_slicer = CreateTiledMosaic() >>> mosaic_slicer.inputs.input_image = 'T1.nii.gz' >>> mosaic_slicer.inputs.rgb_image = 'rgb.nii.gz' >>> mosaic_slicer.inputs.mask_image = 'mask.nii.gz' >>> mosaic_slicer.inputs.output_image = 'output.png' >>> mosaic_slicer.inputs.alpha_value = 0.5 >>> mosaic_slicer.inputs.direction = 2 >>> mosaic_slicer.inputs.pad_or_crop = '[ -15x -50 , -15x -30 ,0]' >>> mosaic_slicer.inputs.slices = '[2 ,100 ,160]' >>> mosaic_slicer.cmdline 'CreateTiledMosaic -a 0.50 -d 2 -i T1.nii.gz -x mask.nii.gz -o output.png -p [ -15x -50 , -15x -30 ,0] -r rgb.nii.gz -s [2 ,100 ,160]' """ _cmd = 'CreateTiledMosaic' input_spec = CreateTiledMosaicInputSpec output_spec = CreateTiledMosaicOutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs['output_image'] = os.path.join(os.getcwd(), self.inputs.output_image) return outputs nipype-0.11.0/nipype/interfaces/base.py000066400000000000000000002024511257611314500200210ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Package contains interfaces for using existing functionality in other packages Exaples FSL, matlab/SPM , afni Requires Packages to be installed """ from ConfigParser import NoOptionError from copy import deepcopy import datetime import errno import os import re import platform from socket import getfqdn from string import Template import select import subprocess import sys from textwrap import wrap from datetime import datetime as dt from dateutil.parser import parse as parseutc from warnings import warn from nipype.external import six from .traits_extension import (traits, Undefined, TraitDictObject, TraitListObject, TraitError, isdefined, File, Directory, has_metadata) from ..utils.filemanip import (md5, hash_infile, FileNotFoundError, hash_timestamp, save_json, split_filename) from ..utils.misc import is_container, trim, str2bool from ..utils.provenance import write_provenance from .. import config, logging, LooseVersion from .. import __version__ import random, time, fnmatch nipype_version = LooseVersion(__version__) iflogger = logging.getLogger('interface') __docformat__ = 'restructuredtext' class NipypeInterfaceError(Exception): def __init__(self, value): self.value = value def __str__(self): return repr(self.value) def _unlock_display(ndisplay): lockf = os.path.join('/tmp', '.X%d-lock' % ndisplay) try: os.remove(lockf) except: return False return True def _exists_in_path(cmd, environ): ''' Based on a code snippet from http://orip.org/2009/08/python-checking-if-executable-exists-in.html ''' if 'PATH' in environ: input_environ = environ.get("PATH") else: input_environ = os.environ.get("PATH", "") extensions = os.environ.get("PATHEXT", "").split(os.pathsep) for directory in input_environ.split(os.pathsep): base = os.path.join(directory, cmd) options = [base] + [(base + ext) for ext in extensions] for filename in options: if os.path.exists(filename): return True, filename return False, None def load_template(name): """Load a template from the script_templates directory Parameters ---------- name : str The name of the file to load Returns ------- template : string.Template """ full_fname = os.path.join(os.path.dirname(__file__), 'script_templates', name) template_file = open(full_fname) template = Template(template_file.read()) template_file.close() return template class Bunch(object): """Dictionary-like class that provides attribute-style access to it's items. A `Bunch` is a simple container that stores it's items as class attributes. Internally all items are stored in a dictionary and the class exposes several of the dictionary methods. Examples -------- >>> from nipype.interfaces.base import Bunch >>> inputs = Bunch(infile='subj.nii', fwhm=6.0, register_to_mean=True) >>> inputs Bunch(fwhm=6.0, infile='subj.nii', register_to_mean=True) >>> inputs.register_to_mean = False >>> inputs Bunch(fwhm=6.0, infile='subj.nii', register_to_mean=False) Notes ----- The Bunch pattern came from the Python Cookbook: .. [1] A. Martelli, D. Hudgeon, "Collecting a Bunch of Named Items", Python Cookbook, 2nd Ed, Chapter 4.18, 2005. """ def __init__(self, *args, **kwargs): self.__dict__.update(*args, **kwargs) def update(self, *args, **kwargs): """update existing attribute, or create new attribute Note: update is very much like HasTraits.set""" self.__dict__.update(*args, **kwargs) def items(self): """iterates over bunch attributes as key, value pairs""" return self.__dict__.items() def iteritems(self): """iterates over bunch attributes as key, value pairs""" warn('iteritems is deprecated, use items instead') return self.items() def get(self, *args): '''Support dictionary get() functionality ''' return self.__dict__.get(*args) def set(self, **kwargs): '''Support dictionary get() functionality ''' return self.__dict__.update(**kwargs) def dictcopy(self): """returns a deep copy of existing Bunch as a dictionary""" return deepcopy(self.__dict__) def __repr__(self): """representation of the sorted Bunch as a string Currently, this string representation of the `inputs` Bunch of interfaces is hashed to determine if the process' dirty-bit needs setting or not. Till that mechanism changes, only alter this after careful consideration. """ outstr = ['Bunch('] first = True for k, v in sorted(self.items()): if not first: outstr.append(', ') if isinstance(v, dict): pairs = [] for key, value in sorted(v.items()): pairs.append("'%s': %s" % (key, value)) v = '{' + ', '.join(pairs) + '}' outstr.append('%s=%s' % (k, v)) else: outstr.append('%s=%r' % (k, v)) first = False outstr.append(')') return ''.join(outstr) def _hash_infile(self, adict, key): # Inject file hashes into adict[key] stuff = adict[key] if not is_container(stuff): stuff = [stuff] file_list = [] for afile in stuff: if os.path.isfile(afile): md5obj = md5() fp = file(afile, 'rb') while True: data = fp.read(8192) if not data: break md5obj.update(data) fp.close() md5hex = md5obj.hexdigest() else: md5hex = None file_list.append((afile, md5hex)) return file_list def _get_bunch_hash(self): """Return a dictionary of our items with hashes for each file. Searches through dictionary items and if an item is a file, it calculates the md5 hash of the file contents and stores the file name and hash value as the new key value. However, the overall bunch hash is calculated only on the hash value of a file. The path and name of the file are not used in the overall hash calculation. Returns ------- dict_withhash : dict Copy of our dictionary with the new file hashes included with each file. hashvalue : str The md5 hash value of the `dict_withhash` """ infile_list = [] for key, val in self.items(): if is_container(val): # XXX - SG this probably doesn't catch numpy arrays # containing embedded file names either. if isinstance(val, dict): # XXX - SG should traverse dicts, but ignoring for now item = None else: if len(val) == 0: raise AttributeError('%s attribute is empty' % key) item = val[0] else: item = val try: if os.path.isfile(item): infile_list.append(key) except TypeError: # `item` is not a file or string. continue dict_withhash = self.dictcopy() dict_nofilename = self.dictcopy() for item in infile_list: dict_withhash[item] = self._hash_infile(dict_withhash, item) dict_nofilename[item] = [val[1] for val in dict_withhash[item]] # Sort the items of the dictionary, before hashing the string # representation so we get a predictable order of the # dictionary. sorted_dict = str(sorted(dict_nofilename.items())) return (dict_withhash, md5(sorted_dict).hexdigest()) def __pretty__(self, p, cycle): '''Support for the pretty module pretty is included in ipython.externals for ipython > 0.10''' if cycle: p.text('Bunch(...)') else: p.begin_group(6, 'Bunch(') first = True for k, v in sorted(self.items()): if not first: p.text(',') p.breakable() p.text(k + '=') p.pretty(v) first = False p.end_group(6, ')') class InterfaceResult(object): """Object that contains the results of running a particular Interface. Attributes ---------- version : version of this Interface result object (a readonly property) interface : class type A copy of the `Interface` class that was run to generate this result. inputs : a traits free representation of the inputs outputs : Bunch An `Interface` specific Bunch that contains all possible files that are generated by the interface. The `outputs` are used as the `inputs` to another node when interfaces are used in the pipeline. runtime : Bunch Contains attributes that describe the runtime environment when the `Interface` was run. Contains the attributes: * cmdline : The command line string that was executed * cwd : The directory the ``cmdline`` was executed in. * stdout : The output of running the ``cmdline``. * stderr : Any error messages output from running ``cmdline``. * returncode : The code returned from running the ``cmdline``. """ def __init__(self, interface, runtime, inputs=None, outputs=None, provenance=None): self._version = 2.0 self.interface = interface self.runtime = runtime self.inputs = inputs self.outputs = outputs self.provenance = provenance @property def version(self): return self._version class BaseTraitedSpec(traits.HasTraits): """Provide a few methods necessary to support nipype interface api The inputs attribute of interfaces call certain methods that are not available in traits.HasTraits. These are provided here. new metadata: * usedefault : set this to True if the default value of the trait should be used. Unless this is set, the attributes are set to traits.Undefined new attribute: * get_hashval : returns a tuple containing the state of the trait as a dict and hashvalue corresponding to dict. XXX Reconsider this in the long run, but it seems like the best solution to move forward on the refactoring. """ def __init__(self, **kwargs): """ Initialize handlers and inputs""" # NOTE: In python 2.6, object.__init__ no longer accepts input # arguments. HasTraits does not define an __init__ and # therefore these args were being ignored. #super(TraitedSpec, self).__init__(*args, **kwargs) super(BaseTraitedSpec, self).__init__(**kwargs) traits.push_exception_handler(reraise_exceptions=True) undefined_traits = {} for trait in self.copyable_trait_names(): if not self.traits()[trait].usedefault: undefined_traits[trait] = Undefined self.trait_set(trait_change_notify=False, **undefined_traits) self._generate_handlers() self.set(**kwargs) def items(self): """ Name, trait generator for user modifiable traits """ for name in sorted(self.copyable_trait_names()): yield name, self.traits()[name] def __repr__(self): """ Return a well-formatted representation of the traits """ outstr = [] for name, value in sorted(self.trait_get().items()): outstr.append('%s = %s' % (name, value)) return '\n' + '\n'.join(outstr) + '\n' def _generate_handlers(self): """Find all traits with the 'xor' metadata and attach an event handler to them. """ has_xor = dict(xor=lambda t: t is not None) xors = self.trait_names(**has_xor) for elem in xors: self.on_trait_change(self._xor_warn, elem) has_requires = dict(requires=lambda t: t is not None) requires = self.trait_names(**has_requires) for elem in requires: self.on_trait_change(self._requires_warn, elem) has_deprecation = dict(deprecated=lambda t: t is not None) deprecated = self.trait_names(**has_deprecation) for elem in deprecated: self.on_trait_change(self._deprecated_warn, elem) def _xor_warn(self, obj, name, old, new): """ Generates warnings for xor traits """ if isdefined(new): trait_spec = self.traits()[name] # for each xor, set to default_value for trait_name in trait_spec.xor: if trait_name == name: # skip ourself continue if isdefined(getattr(self, trait_name)): self.trait_set(trait_change_notify=False, **{'%s' % name: Undefined}) msg = ('Input "%s" is mutually exclusive with input "%s", ' 'which is already set') % (name, trait_name) raise IOError(msg) def _requires_warn(self, obj, name, old, new): """Part of the xor behavior """ if isdefined(new): trait_spec = self.traits()[name] msg = None for trait_name in trait_spec.requires: if not isdefined(getattr(self, trait_name)): if not msg: msg = 'Input %s requires inputs: %s' \ % (name, ', '.join(trait_spec.requires)) if msg: warn(msg) def _deprecated_warn(self, obj, name, old, new): """Checks if a user assigns a value to a deprecated trait """ if isdefined(new): trait_spec = self.traits()[name] msg1 = ('Input %s in interface %s is deprecated.' % (name, self.__class__.__name__.split('InputSpec')[0])) msg2 = ('Will be removed or raise an error as of release %s' % trait_spec.deprecated) if trait_spec.new_name: if trait_spec.new_name not in self.copyable_trait_names(): raise TraitError(msg1 + ' Replacement trait %s not found' % trait_spec.new_name) msg3 = 'It has been replaced by %s.' % trait_spec.new_name else: msg3 = '' msg = ' '.join((msg1, msg2, msg3)) if LooseVersion(str(trait_spec.deprecated)) < nipype_version: raise TraitError(msg) else: warn(msg) if trait_spec.new_name: warn('Unsetting %s and setting %s.' % (name, trait_spec.new_name)) self.trait_set(trait_change_notify=False, **{'%s' % name: Undefined, '%s' % trait_spec.new_name: new}) def _hash_infile(self, adict, key): """ Inject file hashes into adict[key]""" stuff = adict[key] if not is_container(stuff): stuff = [stuff] file_list = [] for afile in stuff: if is_container(afile): hashlist = self._hash_infile({'infiles': afile}, 'infiles') hash = [val[1] for val in hashlist] else: if config.get('execution', 'hash_method').lower() == 'timestamp': hash = hash_timestamp(afile) elif config.get('execution', 'hash_method').lower() == 'content': hash = hash_infile(afile) else: raise Exception("Unknown hash method: %s" % config.get('execution', 'hash_method')) file_list.append((afile, hash)) return file_list def get(self, **kwargs): """ Returns traited class as a dict Augments the trait get function to return a dictionary without notification handles """ out = super(BaseTraitedSpec, self).get(**kwargs) out = self._clean_container(out, Undefined) return out def get_traitsfree(self, **kwargs): """ Returns traited class as a dict Augments the trait get function to return a dictionary without any traits. The dictionary does not contain any attributes that were Undefined """ out = super(BaseTraitedSpec, self).get(**kwargs) out = self._clean_container(out, skipundefined=True) return out def _clean_container(self, object, undefinedval=None, skipundefined=False): """Convert a traited obejct into a pure python representation. """ if isinstance(object, TraitDictObject) or isinstance(object, dict): out = {} for key, val in object.items(): if isdefined(val): out[key] = self._clean_container(val, undefinedval) else: if not skipundefined: out[key] = undefinedval elif (isinstance(object, TraitListObject) or isinstance(object, list) or isinstance(object, tuple)): out = [] for val in object: if isdefined(val): out.append(self._clean_container(val, undefinedval)) else: if not skipundefined: out.append(undefinedval) else: out.append(None) if isinstance(object, tuple): out = tuple(out) else: if isdefined(object): out = object else: if not skipundefined: out = undefinedval return out def get_hashval(self, hash_method=None): """Return a dictionary of our items with hashes for each file. Searches through dictionary items and if an item is a file, it calculates the md5 hash of the file contents and stores the file name and hash value as the new key value. However, the overall bunch hash is calculated only on the hash value of a file. The path and name of the file are not used in the overall hash calculation. Returns ------- dict_withhash : dict Copy of our dictionary with the new file hashes included with each file. hashvalue : str The md5 hash value of the traited spec """ dict_withhash = [] dict_nofilename = [] for name, val in sorted(self.get().items()): if isdefined(val): trait = self.trait(name) if has_metadata(trait.trait_type, "nohash", True): continue hash_files = (not has_metadata(trait.trait_type, "hash_files", False) and not has_metadata(trait.trait_type, "name_source")) dict_nofilename.append((name, self._get_sorteddict(val, hash_method=hash_method, hash_files=hash_files))) dict_withhash.append((name, self._get_sorteddict(val, True, hash_method=hash_method, hash_files=hash_files))) return dict_withhash, md5(str(dict_nofilename)).hexdigest() def _get_sorteddict(self, object, dictwithhash=False, hash_method=None, hash_files=True): if isinstance(object, dict): out = [] for key, val in sorted(object.items()): if isdefined(val): out.append((key, self._get_sorteddict(val, dictwithhash, hash_method=hash_method, hash_files=hash_files))) elif isinstance(object, (list, tuple)): out = [] for val in object: if isdefined(val): out.append(self._get_sorteddict(val, dictwithhash, hash_method=hash_method, hash_files=hash_files)) if isinstance(object, tuple): out = tuple(out) else: if isdefined(object): if (hash_files and isinstance(object, six.string_types) and os.path.isfile(object)): if hash_method is None: hash_method = config.get('execution', 'hash_method') if hash_method.lower() == 'timestamp': hash = hash_timestamp(object) elif hash_method.lower() == 'content': hash = hash_infile(object) else: raise Exception("Unknown hash method: %s" % hash_method) if dictwithhash: out = (object, hash) else: out = hash elif isinstance(object, float): out = '%.10f' % object else: out = object return out class DynamicTraitedSpec(BaseTraitedSpec): """ A subclass to handle dynamic traits This class is a workaround for add_traits and clone_traits not functioning well together. """ def __deepcopy__(self, memo): """ bug in deepcopy for HasTraits results in weird cloning behavior for added traits """ id_self = id(self) if id_self in memo: return memo[id_self] dup_dict = deepcopy(self.get(), memo) # access all keys for key in self.copyable_trait_names(): _ = getattr(self, key) # clone once dup = self.clone_traits(memo=memo) for key in self.copyable_trait_names(): try: _ = getattr(dup, key) except: pass # clone twice dup = self.clone_traits(memo=memo) dup.set(**dup_dict) return dup class TraitedSpec(BaseTraitedSpec): """ Create a subclass with strict traits. This is used in 90% of the cases. """ _ = traits.Disallow class Interface(object): """This is an abstract definition for Interface objects. It provides no functionality. It defines the necessary attributes and methods all Interface objects should have. """ input_spec = None # A traited input specification output_spec = None # A traited output specification _can_resume = False # defines if the interface can reuse partial results # after interruption @property def can_resume(self): return self._can_resume _always_run = False # should the interface be always run even if the # inputs were not changed? @property def always_run(self): return self._always_run def __init__(self, **inputs): """Initialize command with given args and inputs.""" raise NotImplementedError @classmethod def help(cls): """ Prints class help""" raise NotImplementedError @classmethod def _inputs_help(cls): """ Prints inputs help""" raise NotImplementedError @classmethod def _outputs_help(cls): """ Prints outputs help""" raise NotImplementedError @classmethod def _outputs(cls): """ Initializes outputs""" raise NotImplementedError @property def version(self): raise NotImplementedError def run(self): """Execute the command.""" raise NotImplementedError def aggregate_outputs(self, runtime=None, needed_outputs=None): """Called to populate outputs""" raise NotImplementedError def _list_outputs(self): """ List expected outputs""" raise NotImplementedError def _get_filecopy_info(self): """ Provides information about file inputs to copy or link to cwd. Necessary for pipeline operation """ raise NotImplementedError class BaseInterfaceInputSpec(TraitedSpec): ignore_exception = traits.Bool(False, desc="Print an error message instead \ of throwing an exception in case the interface fails to run", usedefault=True, nohash=True) class BaseInterface(Interface): """Implements common interface functionality. Implements ---------- * Initializes inputs/outputs from input_spec/output_spec * Provides help based on input_spec and output_spec * Checks for mandatory inputs before running an interface * Runs an interface and returns results * Determines which inputs should be copied or linked to cwd This class does not implement aggregate_outputs, input_spec or output_spec. These should be defined by derived classes. This class cannot be instantiated. """ input_spec = BaseInterfaceInputSpec _version = None _additional_metadata = [] _redirect_x = False def __init__(self, **inputs): if not self.input_spec: raise Exception('No input_spec in class: %s' % self.__class__.__name__) self.inputs = self.input_spec(**inputs) @classmethod def help(cls, returnhelp=False): """ Prints class help """ if cls.__doc__: #docstring = cls.__doc__.split('\n') #docstring = [trim(line, '') for line in docstring] docstring = trim(cls.__doc__).split('\n') + [''] else: docstring = [''] allhelp = '\n'.join(docstring + cls._inputs_help() + [''] + cls._outputs_help() + ['']) if returnhelp: return allhelp else: print(allhelp) @classmethod def _get_trait_desc(self, inputs, name, spec): desc = spec.desc xor = spec.xor requires = spec.requires argstr = spec.argstr manhelpstr = ['\t%s' % name] type_info = spec.full_info(inputs, name, None) default = '' if spec.usedefault: default = ', nipype default value: %s' % str(spec.default_value()[1]) line = "(%s%s)" % (type_info, default) manhelpstr = wrap(line, 70, initial_indent=manhelpstr[0]+': ', subsequent_indent='\t\t ') if desc: for line in desc.split('\n'): line = re.sub("\s+", " ", line) manhelpstr += wrap(line, 70, initial_indent='\t\t', subsequent_indent='\t\t') if argstr: pos = spec.position if pos is not None: manhelpstr += wrap('flag: %s, position: %s' % (argstr, pos), 70, initial_indent='\t\t', subsequent_indent='\t\t') else: manhelpstr += wrap('flag: %s' % argstr, 70, initial_indent='\t\t', subsequent_indent='\t\t') if xor: line = '%s' % ', '.join(xor) manhelpstr += wrap(line, 70, initial_indent='\t\tmutually_exclusive: ', subsequent_indent='\t\t ') if requires: others = [field for field in requires if field != name] line = '%s' % ', '.join(others) manhelpstr += wrap(line, 70, initial_indent='\t\trequires: ', subsequent_indent='\t\t ') return manhelpstr @classmethod def _inputs_help(cls): """ Prints description for input parameters """ helpstr = ['Inputs::'] inputs = cls.input_spec() if len(inputs.traits(transient=None).items()) == 0: helpstr += ['', '\tNone'] return helpstr manhelpstr = ['', '\t[Mandatory]'] mandatory_items = inputs.traits(mandatory=True) for name, spec in sorted(mandatory_items.items()): manhelpstr += cls._get_trait_desc(inputs, name, spec) opthelpstr = ['', '\t[Optional]'] for name, spec in sorted(inputs.traits(transient=None).items()): if name in mandatory_items: continue opthelpstr += cls._get_trait_desc(inputs, name, spec) if manhelpstr: helpstr += manhelpstr if opthelpstr: helpstr += opthelpstr return helpstr @classmethod def _outputs_help(cls): """ Prints description for output parameters """ helpstr = ['Outputs::', ''] if cls.output_spec: outputs = cls.output_spec() for name, spec in sorted(outputs.traits(transient=None).items()): helpstr += cls._get_trait_desc(outputs, name, spec) if len(helpstr) == 2: helpstr += ['\tNone'] return helpstr def _outputs(self): """ Returns a bunch containing output fields for the class """ outputs = None if self.output_spec: outputs = self.output_spec() return outputs @classmethod def _get_filecopy_info(cls): """ Provides information about file inputs to copy or link to cwd. Necessary for pipeline operation """ info = [] if cls.input_spec is None: return info metadata = dict(copyfile=lambda t: t is not None) for name, spec in sorted(cls.input_spec().traits(**metadata).items()): info.append(dict(key=name, copy=spec.copyfile)) return info def _check_requires(self, spec, name, value): """ check if required inputs are satisfied """ if spec.requires: values = [not isdefined(getattr(self.inputs, field)) for field in spec.requires] if any(values) and isdefined(value): msg = ("%s requires a value for input '%s' because one of %s " "is set. For a list of required inputs, see %s.help()" % (self.__class__.__name__, name, ', '.join(spec.requires), self.__class__.__name__)) raise ValueError(msg) def _check_xor(self, spec, name, value): """ check if mutually exclusive inputs are satisfied """ if spec.xor: values = [isdefined(getattr(self.inputs, field)) for field in spec.xor] if not any(values) and not isdefined(value): msg = ("%s requires a value for one of the inputs '%s'. " "For a list of required inputs, see %s.help()" % (self.__class__.__name__, ', '.join(spec.xor), self.__class__.__name__)) raise ValueError(msg) def _check_mandatory_inputs(self): """ Raises an exception if a mandatory input is Undefined """ for name, spec in self.inputs.traits(mandatory=True).items(): value = getattr(self.inputs, name) self._check_xor(spec, name, value) if not isdefined(value) and spec.xor is None: msg = ("%s requires a value for input '%s'. " "For a list of required inputs, see %s.help()" % (self.__class__.__name__, name, self.__class__.__name__)) raise ValueError(msg) if isdefined(value): self._check_requires(spec, name, value) for name, spec in self.inputs.traits(mandatory=None, transient=None).items(): self._check_requires(spec, name, getattr(self.inputs, name)) def _check_version_requirements(self, trait_object, raise_exception=True): """ Raises an exception on version mismatch """ unavailable_traits = [] # check minimum version check = dict(min_ver=lambda t: t is not None) names = trait_object.trait_names(**check) if names: version = LooseVersion(str(self.version)) if not version: return for name in names: min_ver = LooseVersion(str(trait_object.traits()[name].min_ver)) if min_ver > version: unavailable_traits.append(name) if not isdefined(getattr(trait_object, name)): continue if raise_exception: raise Exception('Trait %s (%s) (version %s < required %s)' % (name, self.__class__.__name__, version, min_ver)) check = dict(max_ver=lambda t: t is not None) names = trait_object.trait_names(**check) for name in names: max_ver = LooseVersion(str(trait_object.traits()[name].max_ver)) if max_ver < version: unavailable_traits.append(name) if not isdefined(getattr(trait_object, name)): continue if raise_exception: raise Exception('Trait %s (%s) (version %s > required %s)' % (name, self.__class__.__name__, version, max_ver)) return unavailable_traits def _run_wrapper(self, runtime): sysdisplay = os.getenv('DISPLAY') if self._redirect_x: try: from xvfbwrapper import Xvfb except ImportError: iflogger.error('Xvfb wrapper could not be imported') raise vdisp = Xvfb(nolisten='tcp') vdisp.start() vdisp_num = vdisp.vdisplay_num iflogger.info('Redirecting X to :%d' % vdisp_num) runtime.environ['DISPLAY'] = ':%d' % vdisp_num runtime = self._run_interface(runtime) if self._redirect_x: if sysdisplay is None: os.unsetenv('DISPLAY') else: os.environ['DISPLAY'] = sysdisplay iflogger.info('Freeing X :%d' % vdisp_num) vdisp.stop() _unlock_display(vdisp_num) return runtime def _run_interface(self, runtime): """ Core function that executes interface """ raise NotImplementedError def run(self, **inputs): """Execute this interface. This interface will not raise an exception if runtime.returncode is non-zero. Parameters ---------- inputs : allows the interface settings to be updated Returns ------- results : an InterfaceResult object containing a copy of the instance that was executed, provenance information and, if successful, results """ self.inputs.set(**inputs) self._check_mandatory_inputs() self._check_version_requirements(self.inputs) interface = self.__class__ # initialize provenance tracking env = deepcopy(os.environ.data) runtime = Bunch(cwd=os.getcwd(), returncode=None, duration=None, environ=env, startTime=dt.isoformat(dt.utcnow()), endTime=None, platform=platform.platform(), hostname=getfqdn(), version=self.version) try: runtime = self._run_wrapper(runtime) outputs = self.aggregate_outputs(runtime) runtime.endTime = dt.isoformat(dt.utcnow()) timediff = parseutc(runtime.endTime) - parseutc(runtime.startTime) runtime.duration = timediff.days * 86400 + timediff.seconds + \ timediff.microseconds/100000. results = InterfaceResult(interface, runtime, inputs=self.inputs.get_traitsfree(), outputs=outputs) prov_record = None if str2bool(config.get('execution', 'write_provenance')): prov_record = write_provenance(results) results.provenance = prov_record except Exception, e: runtime.endTime = dt.isoformat(dt.utcnow()) timediff = parseutc(runtime.endTime) - parseutc(runtime.startTime) runtime.duration = timediff.days * 86400 + timediff.seconds + \ timediff.microseconds/100000. if len(e.args) == 0: e.args = ("") message = "\nInterface %s failed to run." % self.__class__.__name__ if config.has_option('logging', 'interface_level') and \ config.get('logging', 'interface_level').lower() == 'debug': inputs_str = "Inputs:" + str(self.inputs) + "\n" else: inputs_str = '' if len(e.args) == 1 and isinstance(e.args[0], six.string_types): e.args = (e.args[0] + " ".join([message, inputs_str]),) else: e.args += (message, ) if inputs_str != '': e.args += (inputs_str, ) #exception raising inhibition for special cases import traceback runtime.traceback = traceback.format_exc() runtime.traceback_args = e.args inputs = None try: inputs = self.inputs.get_traitsfree() except Exception, e: pass results = InterfaceResult(interface, runtime, inputs=inputs) prov_record = None if str2bool(config.get('execution', 'write_provenance')): try: prov_record = write_provenance(results) except Exception: prov_record = None results.provenance = prov_record if hasattr(self.inputs, 'ignore_exception') and \ isdefined(self.inputs.ignore_exception) and \ self.inputs.ignore_exception: pass else: raise return results def _list_outputs(self): """ List the expected outputs """ if self.output_spec: raise NotImplementedError else: return None def aggregate_outputs(self, runtime=None, needed_outputs=None): """ Collate expected outputs and check for existence """ predicted_outputs = self._list_outputs() outputs = self._outputs() if predicted_outputs: _unavailable_outputs = [] if outputs: _unavailable_outputs = \ self._check_version_requirements(self._outputs()) for key, val in predicted_outputs.items(): if needed_outputs and key not in needed_outputs: continue if key in _unavailable_outputs: raise KeyError(('Output trait %s not available in version ' '%s of interface %s. Please inform ' 'developers.') % (key, self.version, self.__class__.__name__)) try: setattr(outputs, key, val) _ = getattr(outputs, key) except TraitError, error: if hasattr(error, 'info') and \ error.info.startswith("an existing"): msg = ("File/Directory '%s' not found for %s output " "'%s'." % (val, self.__class__.__name__, key)) raise FileNotFoundError(msg) else: raise error return outputs @property def version(self): if self._version is None: if str2bool(config.get('execution', 'stop_on_unknown_version')): raise ValueError('Interface %s has no version information' % self.__class__.__name__) return self._version class Stream(object): """Function to capture stdout and stderr streams with timestamps stackoverflow.com/questions/4984549/merge-and-sync-stdout-and-stderr/5188359 """ def __init__(self, name, impl): self._name = name self._impl = impl self._buf = '' self._rows = [] self._lastidx = 0 def fileno(self): "Pass-through for file descriptor." return self._impl.fileno() def read(self, drain=0): "Read from the file descriptor. If 'drain' set, read until EOF." while self._read(drain) is not None: if not drain: break def _read(self, drain): "Read from the file descriptor" fd = self.fileno() buf = os.read(fd, 4096) if not buf and not self._buf: return None if '\n' not in buf: if not drain: self._buf += buf return [] # prepend any data previously read, then split into lines and format buf = self._buf + buf if '\n' in buf: tmp, rest = buf.rsplit('\n', 1) else: tmp = buf rest = None self._buf = rest now = datetime.datetime.now().isoformat() rows = tmp.split('\n') self._rows += [(now, '%s %s:%s' % (self._name, now, r), r) for r in rows] for idx in range(self._lastidx, len(self._rows)): iflogger.info(self._rows[idx][1]) self._lastidx = len(self._rows) def run_command(runtime, output=None, timeout=0.01, redirect_x=False): """Run a command, read stdout and stderr, prefix with timestamp. The returned runtime contains a merged stdout+stderr log with timestamps """ PIPE = subprocess.PIPE cmdline = runtime.cmdline if redirect_x: exist_xvfb, _ = _exists_in_path('xvfb-run', runtime.environ) if not exist_xvfb: raise RuntimeError('Xvfb was not found, X redirection aborted') cmdline = 'xvfb-run -a ' + cmdline if output == 'file': errfile = os.path.join(runtime.cwd, 'stderr.nipype') outfile = os.path.join(runtime.cwd, 'stdout.nipype') stderr = open(errfile, 'wt') stdout = open(outfile, 'wt') proc = subprocess.Popen(cmdline, stdout=stdout, stderr=stderr, shell=True, cwd=runtime.cwd, env=runtime.environ) else: proc = subprocess.Popen(cmdline, stdout=PIPE, stderr=PIPE, shell=True, cwd=runtime.cwd, env=runtime.environ) result = {} errfile = os.path.join(runtime.cwd, 'stderr.nipype') outfile = os.path.join(runtime.cwd, 'stdout.nipype') if output == 'stream': streams = [Stream('stdout', proc.stdout), Stream('stderr', proc.stderr)] def _process(drain=0): try: res = select.select(streams, [], [], timeout) except select.error, e: iflogger.info(str(e)) if e[0] == errno.EINTR: return else: raise else: for stream in res[0]: stream.read(drain) while proc.returncode is None: proc.poll() _process() _process(drain=1) # collect results, merge and return result = {} temp = [] for stream in streams: rows = stream._rows temp += rows result[stream._name] = [r[2] for r in rows] temp.sort() result['merged'] = [r[1] for r in temp] if output == 'allatonce': stdout, stderr = proc.communicate() result['stdout'] = stdout.split('\n') result['stderr'] = stderr.split('\n') result['merged'] = '' if output == 'file': ret_code = proc.wait() stderr.flush() stdout.flush() result['stdout'] = [line.strip() for line in open(outfile).readlines()] result['stderr'] = [line.strip() for line in open(errfile).readlines()] result['merged'] = '' if output == 'none': proc.communicate() result['stdout'] = [] result['stderr'] = [] result['merged'] = '' runtime.stderr = '\n'.join(result['stderr']) runtime.stdout = '\n'.join(result['stdout']) runtime.merged = result['merged'] runtime.returncode = proc.returncode return runtime def get_dependencies(name, environ): """Return library dependencies of a dynamically linked executable Uses otool on darwin, ldd on linux. Currently doesn't support windows. """ PIPE = subprocess.PIPE if sys.platform == 'darwin': proc = subprocess.Popen('otool -L `which %s`' % name, stdout=PIPE, stderr=PIPE, shell=True, env=environ) elif 'linux' in sys.platform: proc = subprocess.Popen('ldd `which %s`' % name, stdout=PIPE, stderr=PIPE, shell=True, env=environ) else: return 'Platform %s not supported' % sys.platform o, e = proc.communicate() return o.rstrip() class CommandLineInputSpec(BaseInterfaceInputSpec): args = traits.Str(argstr='%s', desc='Additional parameters to the command') environ = traits.DictStrStr(desc='Environment variables', usedefault=True, nohash=True) # This input does not have a "usedefault=True" so the set_default_terminal_output() # method would work terminal_output = traits.Enum('stream', 'allatonce', 'file', 'none', desc=('Control terminal output: `stream` - ' 'displays to terminal immediately (default), ' '`allatonce` - waits till command is ' 'finished to display output, `file` - ' 'writes output to file, `none` - output' ' is ignored'), nohash=True) class CommandLine(BaseInterface): """Implements functionality to interact with command line programs class must be instantiated with a command argument Parameters ---------- command : string define base immutable `command` you wish to run args : string, optional optional arguments passed to base `command` Examples -------- >>> from nipype.interfaces.base import CommandLine >>> cli = CommandLine(command='ls', environ={'DISPLAY': ':1'}) >>> cli.inputs.args = '-al' >>> cli.cmdline 'ls -al' >>> cli.inputs.trait_get() # doctest: +NORMALIZE_WHITESPACE {'ignore_exception': False, 'terminal_output': 'stream', 'environ': {'DISPLAY': ':1'}, 'args': '-al'} >>> cli.inputs.get_hashval() ([('args', '-al')], '11c37f97649cd61627f4afe5136af8c0') """ input_spec = CommandLineInputSpec _cmd = None _version = None _terminal_output = 'stream' def __init__(self, command=None, **inputs): super(CommandLine, self).__init__(**inputs) self._environ = None if not hasattr(self, '_cmd'): self._cmd = None if self.cmd is None and command is None: raise Exception("Missing command") if command: self._cmd = command self.inputs.on_trait_change(self._terminal_output_update, 'terminal_output') if not isdefined(self.inputs.terminal_output): self.inputs.terminal_output = self._terminal_output else: self._terminal_output_update() def _terminal_output_update(self): self._terminal_output = self.inputs.terminal_output @classmethod def set_default_terminal_output(cls, output_type): """Set the default terminal output for CommandLine Interfaces. This method is used to set default terminal output for CommandLine Interfaces. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.terminal_output. """ if output_type in ['stream', 'allatonce', 'file', 'none']: cls._terminal_output = output_type else: raise AttributeError('Invalid terminal output_type: %s' % output_type) @property def cmd(self): """sets base command, immutable""" return self._cmd @property def cmdline(self): """ `command` plus any arguments (args) validates arguments and generates command line""" self._check_mandatory_inputs() allargs = self._parse_inputs() allargs.insert(0, self.cmd) return ' '.join(allargs) def raise_exception(self, runtime): message = "Command:\n" + runtime.cmdline + "\n" message += "Standard output:\n" + runtime.stdout + "\n" message += "Standard error:\n" + runtime.stderr + "\n" message += "Return code: " + str(runtime.returncode) raise RuntimeError(message) @classmethod def help(cls, returnhelp=False): allhelp = super(CommandLine, cls).help(returnhelp=True) allhelp = "Wraps command **%s**\n\n" % cls._cmd + allhelp if returnhelp: return allhelp else: print(allhelp) def _get_environ(self): out_environ = {} if not self._redirect_x: try: display_var = config.get('execution', 'display_variable') out_environ = {'DISPLAY': display_var} except NoOptionError: pass iflogger.debug(out_environ) if isdefined(self.inputs.environ): out_environ.update(self.inputs.environ) return out_environ def version_from_command(self, flag='-v'): cmdname = self.cmd.split()[0] if _exists_in_path(cmdname): env = deepcopy(os.environ.data) out_environ = self._get_environ() env.update(out_environ) proc = subprocess.Popen(' '.join((cmdname, flag)), shell=True, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) o, e = proc.communicate() return o def _run_wrapper(self, runtime): runtime = self._run_interface(runtime) return runtime def _run_interface(self, runtime, correct_return_codes=[0]): """Execute command via subprocess Parameters ---------- runtime : passed by the run function Returns ------- runtime : updated runtime information adds stdout, stderr, merged, cmdline, dependencies, command_path """ setattr(runtime, 'stdout', None) setattr(runtime, 'stderr', None) setattr(runtime, 'cmdline', self.cmdline) out_environ = self._get_environ() runtime.environ.update(out_environ) executable_name = self.cmd.split()[0] exist_val, cmd_path = _exists_in_path(executable_name, runtime.environ) if not exist_val: raise IOError("%s could not be found on host %s" % (self.cmd.split()[0], runtime.hostname)) setattr(runtime, 'command_path', cmd_path) setattr(runtime, 'dependencies', get_dependencies(executable_name, runtime.environ)) runtime = run_command(runtime, output=self.inputs.terminal_output, redirect_x=self._redirect_x) if runtime.returncode is None or \ runtime.returncode not in correct_return_codes: self.raise_exception(runtime) return runtime def _format_arg(self, name, trait_spec, value): """A helper function for _parse_inputs Formats a trait containing argstr metadata """ argstr = trait_spec.argstr iflogger.debug('%s_%s' % (name, str(value))) if trait_spec.is_trait_type(traits.Bool) and "%" not in argstr: if value: # Boolean options have no format string. Just append options # if True. return argstr else: return None # traits.Either turns into traits.TraitCompound and does not have any # inner_traits elif trait_spec.is_trait_type(traits.List) \ or (trait_spec.is_trait_type(traits.TraitCompound) and isinstance(value, list)): # This is a bit simple-minded at present, and should be # construed as the default. If more sophisticated behavior # is needed, it can be accomplished with metadata (e.g. # format string for list member str'ification, specifying # the separator, etc.) # Depending on whether we stick with traitlets, and whether or # not we beef up traitlets.List, we may want to put some # type-checking code here as well sep = trait_spec.sep if sep is None: sep = ' ' if argstr.endswith('...'): # repeatable option # --id %d... will expand to # --id 1 --id 2 --id 3 etc.,. argstr = argstr.replace('...', '') return sep.join([argstr % elt for elt in value]) else: return argstr % sep.join(str(elt) for elt in value) else: # Append options using format string. return argstr % value def _filename_from_source(self, name, chain=None): if chain is None: chain = [] trait_spec = self.inputs.trait(name) retval = getattr(self.inputs, name) if not isdefined(retval) or "%s" in retval: if not trait_spec.name_source: return retval if isdefined(retval) and "%s" in retval: name_template = retval else: name_template = trait_spec.name_template if not name_template: name_template = "%s_generated" ns = trait_spec.name_source while isinstance(ns, list): if len(ns) > 1: iflogger.warn('Only one name_source per trait is allowed') ns = ns[0] if not isinstance(ns, six.string_types): raise ValueError(('name_source of \'%s\' trait sould be an ' 'input trait name') % name) if isdefined(getattr(self.inputs, ns)): name_source = ns source = getattr(self.inputs, name_source) while isinstance(source, list): source = source[0] # special treatment for files try: _, base, _ = split_filename(source) except AttributeError: base = source else: if name in chain: raise NipypeInterfaceError('Mutually pointing name_sources') chain.append(name) base = self._filename_from_source(ns, chain) chain = None retval = name_template % base _, _, ext = split_filename(retval) if trait_spec.keep_extension and ext: return retval return self._overload_extension(retval, name) return retval def _gen_filename(self, name): raise NotImplementedError def _overload_extension(self, value, name=None): return value def _list_outputs(self): metadata = dict(name_source=lambda t: t is not None) traits = self.inputs.traits(**metadata) if traits: outputs = self.output_spec().get() for name, trait_spec in traits.iteritems(): out_name = name if trait_spec.output_name is not None: out_name = trait_spec.output_name outputs[out_name] = \ os.path.abspath(self._filename_from_source(name)) return outputs def _parse_inputs(self, skip=None): """Parse all inputs using the ``argstr`` format string in the Trait. Any inputs that are assigned (not the default_value) are formatted to be added to the command line. Returns ------- all_args : list A list of all inputs formatted for the command line. """ all_args = [] initial_args = {} final_args = {} metadata = dict(argstr=lambda t: t is not None) for name, spec in sorted(self.inputs.traits(**metadata).items()): if skip and name in skip: continue value = getattr(self.inputs, name) if spec.genfile or spec.name_source: value = self._filename_from_source(name) if not isdefined(value): value = self._gen_filename(name) if not isdefined(value): continue arg = self._format_arg(name, spec, value) if arg is None: continue pos = spec.position if pos is not None: if pos >= 0: initial_args[pos] = arg else: final_args[pos] = arg else: all_args.append(arg) first_args = [arg for pos, arg in sorted(initial_args.items())] last_args = [arg for pos, arg in sorted(final_args.items())] return first_args + all_args + last_args class StdOutCommandLineInputSpec(CommandLineInputSpec): out_file = File(argstr="> %s", position=-1, genfile=True) class StdOutCommandLine(CommandLine): input_spec = StdOutCommandLineInputSpec def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): raise NotImplementedError class MpiCommandLineInputSpec(CommandLineInputSpec): use_mpi = traits.Bool(False, desc="Whether or not to run the command with mpiexec", usedefault=True) n_procs = traits.Int(desc="Num processors to specify to mpiexec. Do not " "specify if this is managed externally (e.g. through " "SGE)") class MpiCommandLine(CommandLine): '''Implements functionality to interact with command line programs that can be run with MPI (i.e. using 'mpiexec'). Examples -------- >>> from nipype.interfaces.base import MpiCommandLine >>> mpi_cli = MpiCommandLine(command='my_mpi_prog') >>> mpi_cli.inputs.args = '-v' >>> mpi_cli.cmdline 'my_mpi_prog -v' >>> mpi_cli.inputs.use_mpi = True >>> mpi_cli.inputs.n_procs = 8 >>> mpi_cli.cmdline 'mpiexec -n 8 my_mpi_prog -v' ''' input_spec = MpiCommandLineInputSpec @property def cmdline(self): """Adds 'mpiexec' to begining of command""" result = [] if self.inputs.use_mpi: result.append('mpiexec') if self.inputs.n_procs: result.append('-n %d' % self.inputs.n_procs) result.append(super(MpiCommandLine, self).cmdline) return ' '.join(result) class SEMLikeCommandLine(CommandLine): """In SEM derived interface all outputs have corresponding inputs. However, some SEM commands create outputs that are not defined in the XML. In those cases one has to create a subclass of the autogenerated one and overload the _list_outputs method. _outputs_from_inputs should still be used but only for the reduced (by excluding those that do not have corresponding inputs list of outputs. """ def _list_outputs(self): outputs = self.output_spec().get() return self._outputs_from_inputs(outputs) def _outputs_from_inputs(self, outputs): for name in outputs.keys(): corresponding_input = getattr(self.inputs, name) if isdefined(corresponding_input): if (isinstance(corresponding_input, bool) and corresponding_input): outputs[name] = \ os.path.abspath(self._outputs_filenames[name]) else: if isinstance(corresponding_input, list): outputs[name] = [os.path.abspath(inp) for inp in corresponding_input] else: outputs[name] = os.path.abspath(corresponding_input) return outputs def _format_arg(self, name, spec, value): if name in self._outputs_filenames.keys(): if isinstance(value, bool): if value: value = os.path.abspath(self._outputs_filenames[name]) else: return "" return super(SEMLikeCommandLine, self)._format_arg(name, spec, value) class MultiPath(traits.List): """ Abstract class - shared functionality of input and output MultiPath """ def validate(self, object, name, value): if not isdefined(value) or \ (isinstance(value, list) and len(value) == 0): return Undefined newvalue = value if not isinstance(value, list) \ or (self.inner_traits() and isinstance(self.inner_traits()[0].trait_type, traits.List) and not isinstance(self.inner_traits()[0].trait_type, InputMultiPath) and isinstance(value, list) and value and not isinstance(value[0], list)): newvalue = [value] value = super(MultiPath, self).validate(object, name, newvalue) if len(value) > 0: return value self.error(object, name, value) class OutputMultiPath(MultiPath): """ Implements a user friendly traits that accepts one or more paths to files or directories. This is the output version which return a single string whenever possible (when it was set to a single value or a list of length 1). Default value of this trait is _Undefined. It does not accept empty lists. XXX This should only be used as a final resort. We should stick to established Traits to the extent possible. XXX This needs to be vetted by somebody who understands traits >>> from nipype.interfaces.base import OutputMultiPath >>> class A(TraitedSpec): ... foo = OutputMultiPath(File(exists=False)) >>> a = A() >>> a.foo >>> a.foo = '/software/temp/foo.txt' >>> a.foo '/software/temp/foo.txt' >>> a.foo = ['/software/temp/foo.txt'] >>> a.foo '/software/temp/foo.txt' >>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt'] >>> a.foo ['/software/temp/foo.txt', '/software/temp/goo.txt'] """ def get(self, object, name): value = self.get_value(object, name) if len(value) == 0: return Undefined elif len(value) == 1: return value[0] else: return value def set(self, object, name, value): self.set_value(object, name, value) class InputMultiPath(MultiPath): """ Implements a user friendly traits that accepts one or more paths to files or directories. This is the input version which always returns a list. Default value of this trait is _Undefined. It does not accept empty lists. XXX This should only be used as a final resort. We should stick to established Traits to the extent possible. XXX This needs to be vetted by somebody who understands traits >>> from nipype.interfaces.base import InputMultiPath >>> class A(TraitedSpec): ... foo = InputMultiPath(File(exists=False)) >>> a = A() >>> a.foo >>> a.foo = '/software/temp/foo.txt' >>> a.foo ['/software/temp/foo.txt'] >>> a.foo = ['/software/temp/foo.txt'] >>> a.foo ['/software/temp/foo.txt'] >>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt'] >>> a.foo ['/software/temp/foo.txt', '/software/temp/goo.txt'] """ pass nipype-0.11.0/nipype/interfaces/c3.py000066400000000000000000000031011257611314500174030ustar00rootroot00000000000000"""The ants module provides basic functions for interfacing with ants functions. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (CommandLineInputSpec, traits, TraitedSpec, File, SEMLikeCommandLine) class C3dAffineToolInputSpec(CommandLineInputSpec): reference_file = File(exists=True, argstr="-ref %s", position=1) source_file = File(exists=True, argstr='-src %s', position=2) transform_file = File(exists=True, argstr='%s', position=3) itk_transform = traits.Either(traits.Bool, File(), hash_files=False, desc="Export ITK transform.", argstr="-oitk %s", position=5) fsl2ras = traits.Bool(argstr='-fsl2ras', position=4) class C3dAffineToolOutputSpec(TraitedSpec): itk_transform = File(exists=True) class C3dAffineTool(SEMLikeCommandLine): """Converts fsl-style Affine registration into ANTS compatible itk format Example ======= >>> from nipype.interfaces.c3 import C3dAffineTool >>> c3 = C3dAffineTool() >>> c3.inputs.source_file = 'cmatrix.mat' >>> c3.inputs.itk_transform = 'affine.txt' >>> c3.inputs.fsl2ras = True >>> c3.cmdline 'c3d_affine_tool -src cmatrix.mat -fsl2ras -oitk affine.txt' """ input_spec = C3dAffineToolInputSpec output_spec = C3dAffineToolOutputSpec _cmd = 'c3d_affine_tool' _outputs_filenames = {'itk_transform': 'affine.txt'} nipype-0.11.0/nipype/interfaces/camino/000077500000000000000000000000001257611314500177775ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/camino/__init__.py000066400000000000000000000015211257611314500221070ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Camino top level namespace """ from .connectivity import Conmat from .convert import (Image2Voxel, FSL2Scheme, VtkStreamlines, ProcStreamlines, TractShredder, DT2NIfTI, NIfTIDT2Camino, AnalyzeHeader, Shredder) from .dti import (DTIFit, ModelFit, DTLUTGen, PicoPDFs, Track, TrackPICo, TrackBayesDirac, TrackDT, TrackBallStick, TrackBootstrap, TrackBedpostxDeter, TrackBedpostxProba, ComputeFractionalAnisotropy, ComputeMeanDiffusivity, ComputeTensorTrace, ComputeEigensystem, DTMetric) from .calib import (SFPICOCalibData, SFLUTGen) from .odf import (QBallMX, LinRecon, SFPeaks, MESD) from .utils import ImageStats nipype-0.11.0/nipype/interfaces/camino/calib.py000066400000000000000000000276641257611314500214420ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, StdOutCommandLine, StdOutCommandLineInputSpec, isdefined) from nipype.utils.filemanip import split_filename class SFPICOCalibDataInputSpec(StdOutCommandLineInputSpec): snr = traits.Float(argstr='-snr %f', units='NA', desc=('Specifies the signal-to-noise ratio of the ' 'non-diffusion-weighted measurements to use in simulations.')) scheme_file = File(exists=True, argstr='-schemefile %s', mandatory=True, desc='Specifies the scheme file for the diffusion MRI data') info_file = File(desc='The name to be given to the information output filename.', argstr='-infooutputfile %s', mandatory=True, genfile=True, hash_files=False) # Genfile and hash_files? trace = traits.Float(argstr='-trace %f', units='NA', desc='Trace of the diffusion tensor(s) used in the test function.') onedtfarange = traits.List(traits.Float, argstr='-onedtfarange %s', minlen=2, maxlen=2, units='NA', desc=('Minimum and maximum FA for the single tensor ' 'synthetic data.')) onedtfastep = traits.Float(argstr='-onedtfastep %f', units='NA', desc=('FA step size controlling how many steps there are ' 'between the minimum and maximum FA settings.')) twodtfarange = traits.List(traits.Float, argstr='-twodtfarange %s', minlen=2, maxlen=2, units='NA', desc=('Minimum and maximum FA for the two tensor ' 'synthetic data. FA is varied for both tensors ' 'to give all the different permutations.')) twodtfastep = traits.Float(argstr='-twodtfastep %f', units='NA', desc=('FA step size controlling how many steps there are ' 'between the minimum and maximum FA settings ' 'for the two tensor cases.')) twodtanglerange = traits.List(traits.Float, argstr='-twodtanglerange %s', minlen=2, maxlen=2, units='NA', desc=('Minimum and maximum crossing angles ' 'between the two fibres.')) twodtanglestep = traits.Float(argstr='-twodtanglestep %f', units='NA', desc=('Angle step size controlling how many steps there are ' 'between the minimum and maximum crossing angles for ' 'the two tensor cases.')) twodtmixmax = traits.Float(argstr='-twodtmixmax %f', units='NA', desc=('Mixing parameter controlling the proportion of one fibre population ' 'to the other. The minimum mixing parameter is (1 - twodtmixmax).')) twodtmixstep = traits.Float(argstr='-twodtmixstep %f', units='NA', desc=('Mixing parameter step size for the two tensor cases. ' 'Specify how many mixing parameter increments to use.')) seed = traits.Float(argstr='-seed %f', units='NA', desc='Specifies the random seed to use for noise generation in simulation trials.') class SFPICOCalibDataOutputSpec(TraitedSpec): PICOCalib = File(exists=True, desc='Calibration dataset') calib_info = File(exists=True, desc='Calibration dataset') class SFPICOCalibData(StdOutCommandLine): """ Generates Spherical Function PICo Calibration Data. SFPICOCalibData creates synthetic data for use with SFLUTGen. The synthetic data is generated using a mixture of gaussians, in the same way datasynth generates data. Each voxel of data models a slightly different fibre configuration (varying FA and fibre- crossings) and undergoes a random rotation to help account for any directional bias in the chosen acquisition scheme. A second file, which stores information about the datafile, is generated along with the datafile. Example 1 --------- To create a calibration dataset using the default settings >>> import nipype.interfaces.camino as cam >>> calib = cam.SFPICOCalibData() >>> calib.inputs.scheme_file = 'A.scheme' >>> calib.inputs.snr = 20 >>> calib.inputs.info_file = 'PICO_calib.info' >>> calib.run() # doctest: +SKIP The default settings create a large dataset (249,231 voxels), of which 3401 voxels contain a single fibre population per voxel and the rest of the voxels contain two fibre-populations. The amount of data produced can be varied by specifying the ranges and steps of the parameters for both the one and two fibre datasets used. Example 2 --------- To create a custom calibration dataset >>> import nipype.interfaces.camino as cam >>> calib = cam.SFPICOCalibData() >>> calib.inputs.scheme_file = 'A.scheme' >>> calib.inputs.snr = 20 >>> calib.inputs.info_file = 'PICO_calib.info' >>> calib.inputs.twodtfarange = [0.3, 0.9] >>> calib.inputs.twodtfastep = 0.02 >>> calib.inputs.twodtanglerange = [0, 0.785] >>> calib.inputs.twodtanglestep = 0.03925 >>> calib.inputs.twodtmixmax = 0.8 >>> calib.inputs.twodtmixstep = 0.1 >>> calib.run() # doctest: +SKIP This would provide 76,313 voxels of synthetic data, where 3401 voxels simulate the one fibre cases and 72,912 voxels simulate the various two fibre cases. However, care should be taken to ensure that enough data is generated for calculating the LUT. # doctest: +SKIP """ _cmd = 'sfpicocalibdata' input_spec=SFPICOCalibDataInputSpec output_spec=SFPICOCalibDataOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['PICOCalib'] = os.path.abspath(self._gen_outfilename()) outputs['calib_info'] = os.path.abspath(self.inputs.info_file) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.scheme_file) return name + '_PICOCalib.Bfloat' class SFLUTGenInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, desc='Voxel-order data of the spherical functions peaks.') info_file = File(argstr='-infofile %s', mandatory=True, desc=('The Info file that corresponds to the calibration ' 'datafile used in the reconstruction.')) outputstem = traits.Str('LUT', argstr='-outputstem %s', desc=('Define the name of the generated luts. The form of the filenames will be ' '[outputstem]_oneFibreSurfaceCoeffs.Bdouble and ' '[outputstem]_twoFibreSurfaceCoeffs.Bdouble'), usedefault=True) pdf = traits.Enum('bingham', 'watson', argstr='-pdf %s', desc=('Sets the distribution to use for the calibration. The default is the Bingham ' 'distribution, which allows elliptical probability density contours. ' 'Currently supported options are: ' ' bingham - The Bingham distribution, which allows elliptical probability ' ' density contours. ' ' watson - The Watson distribution. This distribution is rotationally symmetric.'), usedefault=True) binincsize = traits.Int(argstr='-binincsize %d', units='NA', desc=('Sets the size of the bins. In the case of 2D histograms such as the ' 'Bingham, the bins are always square. Default is 1.')) minvectsperbin = traits.Int(argstr='-minvectsperbin %d', units='NA', desc=('Specifies the minimum number of fibre-orientation estimates a bin ' 'must contain before it is used in the lut line/surface generation. ' 'Default is 50. If you get the error "no fibre-orientation estimates ' 'in histogram!", the calibration data set is too small to get enough ' 'samples in any of the histogram bins. You can decrease the minimum ' 'number per bin to get things running in quick tests, but the sta- ' 'tistics will not be reliable and for serious applications, you need ' 'to increase the size of the calibration data set until the error goes.')) directmap = traits.Bool(argstr='-directmap', desc=('Use direct mapping between the eigenvalues and the distribution parameters ' 'instead of the log of the eigenvalues.')) order = traits.Int(argstr='-order %d', units='NA', desc=('The order of the polynomial fitting the surface. Order 1 is linear. ' 'Order 2 (default) is quadratic.')) class SFLUTGenOutputSpec(TraitedSpec): lut_one_fibre = File(exists=True, desc='PICo lut for one-fibre model') lut_two_fibres = File(exists=True, desc='PICo lut for two-fibre model') class SFLUTGen(StdOutCommandLine): """ Generates PICo lookup tables (LUT) for multi-fibre methods such as PASMRI and Q-Ball. SFLUTGen creates the lookup tables for the generalized multi-fibre implementation of the PICo tractography algorithm. The outputs of this utility are either surface or line coefficients up to a given order. The calibration can be performed for different distributions, such as the Bingham and Watson distributions. This utility uses calibration data generated from SFPICOCalibData and peak information created by SFPeaks. The utility outputs two lut's, *_oneFibreSurfaceCoeffs.Bdouble and *_twoFibreSurfaceCoeffs.Bdouble. Each of these files contains big- endian doubles as standard. The format of the output is: :: dimensions (1 for Watson, 2 for Bingham) order (the order of the polynomial) coefficient_1 coefficient_2 ... coefficient_N In the case of the Watson, there is a single set of coefficients, which are ordered: :: constant, x, x^2, ..., x^order. In the case of the Bingham, there are two sets of coefficients (one for each surface), ordered so that: :: for j = 1 to order for k = 1 to order coeff_i = x^j * y^k where j+k < order Example --------- To create a calibration dataset using the default settings >>> import nipype.interfaces.camino as cam >>> lutgen = cam.SFLUTGen() >>> lutgen.inputs.in_file = 'QSH_peaks.Bdouble' >>> lutgen.inputs.info_file = 'PICO_calib.info' >>> lutgen.run() # doctest: +SKIP """ _cmd = 'sflutgen' input_spec=SFLUTGenInputSpec output_spec=SFLUTGenOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['lut_one_fibre'] = self.inputs.outputstem + '_oneFibreSurfaceCoeffs.Bdouble' outputs['lut_two_fibres'] = self.inputs.outputstem + '_twoFibreSurfaceCoeffs.Bdouble' return outputs def _gen_outfilename(self): return '/dev/null' nipype-0.11.0/nipype/interfaces/camino/connectivity.py000066400000000000000000000145671257611314500231040ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (traits, TraitedSpec, File, CommandLine, CommandLineInputSpec, isdefined) from nipype.utils.filemanip import split_filename import os class ConmatInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, desc='Streamlines as generated by the Track interface') target_file = File(exists=True, argstr='-targetfile %s', mandatory=True, desc='An image containing targets, as used in ProcStreamlines interface.') scalar_file = File(exists=True, argstr='-scalarfile %s', desc=('Optional scalar file for computing tract-based statistics. ' 'Must be in the same space as the target file.'), requires=['tract_stat']) targetname_file = File(exists=True, argstr='-targetnamefile %s', desc=('Optional names of targets. This file should contain one entry per line, ' 'with the target intensity followed by the name, separated by white space. ' 'For example: ' ' 1 some_brain_region ' ' 2 some_other_region ' 'These names will be used in the output. The names themselves should not ' 'contain spaces or commas. The labels may be in any order but the output ' 'matrices will be ordered by label intensity.')) tract_stat = traits.Enum("mean", "min", "max", "sum", "median", "var", argstr='-tractstat %s', units='NA', desc=("Tract statistic to use. See TractStats for other options."), requires=['scalar_file'],xor=['tract_prop']) tract_prop = traits.Enum("length", "endpointsep", argstr='-tractstat %s', units='NA', xor=['tract_stat'], desc=('Tract property average to compute in the connectivity matrix. ' 'See TractStats for details.')) output_root = File(argstr='-outputroot %s', genfile=True, desc=('filename root prepended onto the names of the output files. ' 'The extension will be determined from the input.')) class ConmatOutputSpec(TraitedSpec): conmat_sc = File(exists=True, desc='Connectivity matrix in CSV file.') conmat_ts = File(desc='Tract statistics in CSV file.') class Conmat(CommandLine): """ Creates a connectivity matrix using a 3D label image (the target image) and a set of streamlines. The connectivity matrix records how many stream- lines connect each pair of targets, and optionally the mean tractwise statistic (eg tract-averaged FA, or length). The output is a comma separated variable file or files. The first row of the output matrix is label names. Label names may be defined by the user, otherwise they are assigned based on label intensity. Starting from the seed point, we move along the streamline until we find a point in a labeled region. This is done in both directions from the seed point. Streamlines are counted if they connect two target regions, one on either side of the seed point. Only the labeled region closest to the seed is counted, for example if the input contains two streamlines: :: 1: A-----B------SEED---C 2: A--------SEED----------- then the output would be :: A,B,C 0,0,0 0,0,1 0,1,0 There are zero connections to A because in streamline 1, the connection to B is closer to the seed than the connection to A, and in streamline 2 there is no region reached in the other direction. The connected target regions can have the same label, as long as the seed point is outside of the labeled region and both ends connect to the same label (which may be in different locations). Therefore this is allowed: :: A------SEED-------A Such fibers will add to the diagonal elements of the matrix. To remove these entries, run procstreamlines with -endpointfile before running conmat. If the seed point is inside a labled region, it counts as one end of the connection. So :: ----[SEED inside A]---------B counts as a connection between A and B, while :: C----[SEED inside A]---------B counts as a connection between A and C, because C is closer to the seed point. In all cases, distance to the seed point is defined along the streamline path. Example 1 --------- To create a standard connectivity matrix based on streamline counts. >>> import nipype.interfaces.camino as cam >>> conmat = cam.Conmat() >>> conmat.inputs.in_file = 'tracts.Bdouble' >>> conmat.inputs.target_file = 'atlas.nii.gz' >>> conmat.run() # doctest: +SKIP Example 1 --------- To create a standard connectivity matrix and mean tractwise FA statistics. >>> import nipype.interfaces.camino as cam >>> conmat = cam.Conmat() >>> conmat.inputs.in_file = 'tracts.Bdouble' >>> conmat.inputs.target_file = 'atlas.nii.gz' >>> conmat.inputs.scalar_file = 'fa.nii.gz' >>> conmat.run() # doctest: +SKIP """ _cmd = 'conmat' input_spec=ConmatInputSpec output_spec=ConmatOutputSpec def _list_outputs(self): outputs = self.output_spec().get() output_root = self._gen_outputroot() outputs['conmat_sc'] = os.path.abspath(output_root + "sc.csv") outputs['conmat_ts'] = os.path.abspath(output_root + "ts.csv") return outputs def _gen_outfilename(self): return self._gen_outputroot() def _gen_outputroot(self): output_root = self.inputs.output_root if not isdefined(output_root): output_root = self._gen_filename('output_root') return output_root def _gen_filename(self, name): if name == 'output_root': _, filename , _ = split_filename(self.inputs.in_file) filename = filename + "_" return filename nipype-0.11.0/nipype/interfaces/camino/convert.py000066400000000000000000000757501257611314500220470ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os import glob from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, StdOutCommandLine, OutputMultiPath, StdOutCommandLineInputSpec, isdefined) from nipype.utils.filemanip import split_filename class Image2VoxelInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='-4dimage %s', mandatory=True, position=1, desc='4d image file') #TODO convert list of files on the fly # imagelist = File(exists=True, argstr='-imagelist %s', # mandatory=True, position=1, # desc='Name of a file containing a list of 3D images') # # imageprefix = traits.Str(argstr='-imageprefix %s', position=3, # desc='Path to prepend onto filenames in the imagelist.') out_type = traits.Enum("float", "char", "short", "int", "long", "double", argstr='-outputdatatype %s', position=2, desc='"i.e. Bfloat". Can be "char", "short", "int", "long", "float" or "double"', usedefault=True) class Image2VoxelOutputSpec(TraitedSpec): voxel_order = File(exists=True, desc='path/name of 4D volume in voxel order') class Image2Voxel(StdOutCommandLine): """ Converts Analyze / NIFTI / MHA files to voxel order. Converts scanner-order data in a supported image format to voxel-order data. Either takes a 4D file (all measurements in single image) or a list of 3D images. Examples -------- >>> import nipype.interfaces.camino as cmon >>> img2vox = cmon.Image2Voxel() >>> img2vox.inputs.in_file = '4d_dwi.nii' >>> img2vox.run() # doctest: +SKIP """ _cmd = 'image2voxel' input_spec = Image2VoxelInputSpec output_spec = Image2VoxelOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['voxel_order'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '.B'+ self.inputs.out_type class FSL2SchemeInputSpec(StdOutCommandLineInputSpec): bvec_file = File(exists=True, argstr='-bvecfile %s', mandatory=True, position=1, desc='b vector file') bval_file = File(exists=True, argstr='-bvalfile %s', mandatory=True, position=2, desc='b value file') numscans = traits.Int(argstr='-numscans %d', units='NA', desc="Output all measurements numerous (n) times, used when combining multiple scans from the same imaging session.") interleave = traits.Bool(argstr='-interleave', desc="Interleave repeated scans. Only used with -numscans.") bscale = traits.Float(argstr='-bscale %d', units='NA', desc="Scaling factor to convert the b-values into different units. Default is 10^6.") diffusiontime = traits.Float(argstr = '-diffusiontime %f', units = 'NA', desc="Diffusion time") flipx = traits.Bool(argstr='-flipx', desc="Negate the x component of all the vectors.") flipy = traits.Bool(argstr='-flipy', desc="Negate the y component of all the vectors.") flipz = traits.Bool(argstr='-flipz', desc="Negate the z component of all the vectors.") usegradmod = traits.Bool(argstr='-usegradmod', desc="Use the gradient magnitude to scale b. This option has no effect if your gradient directions have unit magnitude.") class FSL2SchemeOutputSpec(TraitedSpec): scheme = File(exists=True, desc='Scheme file') class FSL2Scheme(StdOutCommandLine): """ Converts b-vectors and b-values from FSL format to a Camino scheme file. Examples -------- >>> import nipype.interfaces.camino as cmon >>> makescheme = cmon.FSL2Scheme() >>> makescheme.inputs.bvec_file = 'bvecs' >>> makescheme.inputs.bvec_file = 'bvals' >>> makescheme.run() # doctest: +SKIP """ _cmd = 'fsl2scheme' input_spec=FSL2SchemeInputSpec output_spec=FSL2SchemeOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['scheme'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.bvec_file) return name + '.scheme' class VtkStreamlinesInputSpec(StdOutCommandLineInputSpec): inputmodel = traits.Enum('raw', 'voxels', argstr='-inputmodel %s', desc='input model type (raw or voxels)', usedefault=True) in_file = File(exists=True, argstr=' < %s', mandatory=True, position=-2, desc='data file') voxeldims = traits.List(traits.Int, desc = 'voxel dimensions in mm', argstr='-voxeldims %s', minlen=3, maxlen=3, position=4, units='mm') seed_file = File(exists=False, argstr='-seedfile %s', position=1, desc='image containing seed points') target_file = File(exists=False, argstr='-targetfile %s', position=2, desc='image containing integer-valued target regions') scalar_file = File(exists=False, argstr='-scalarfile %s', position=3, desc='image that is in the same physical space as the tracts') colourorient = traits.Bool(argstr='-colourorient', desc="Each point on the streamline is coloured by the local orientation.") interpolatescalars = traits.Bool(argstr='-interpolatescalars', desc="the scalar value at each point on the streamline is calculated by trilinear interpolation") interpolate = traits.Bool(argstr='-interpolate', desc="the scalar value at each point on the streamline is calculated by trilinear interpolation") class VtkStreamlinesOutputSpec(TraitedSpec): vtk = File(exists=True, desc='Streamlines in VTK format') class VtkStreamlines(StdOutCommandLine): """ Use vtkstreamlines to convert raw or voxel format streamlines to VTK polydata Examples -------- >>> import nipype.interfaces.camino as cmon >>> vtk = cmon.VtkStreamlines() >>> vtk.inputs.in_file = 'tract_data.Bfloat' >>> vtk.inputs.voxeldims = [1,1,1] >>> vtk.run() # doctest: +SKIP """ _cmd = 'vtkstreamlines' input_spec=VtkStreamlinesInputSpec output_spec=VtkStreamlinesOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['vtk'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '.vtk' class ProcStreamlinesInputSpec(StdOutCommandLineInputSpec): inputmodel = traits.Enum('raw', 'voxels', argstr='-inputmodel %s', desc='input model type (raw or voxels)', usedefault=True) in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, position=1, desc='data file') maxtractpoints= traits.Int(argstr='-maxtractpoints %d', units='NA', desc="maximum number of tract points") mintractpoints= traits.Int(argstr='-mintractpoints %d', units='NA', desc="minimum number of tract points") maxtractlength= traits.Int(argstr='-maxtractlength %d', units='mm', desc="maximum length of tracts") mintractlength= traits.Int(argstr='-mintractlength %d', units='mm', desc="minimum length of tracts") datadims = traits.List(traits.Int, desc = 'data dimensions in voxels', argstr='-datadims %s', minlen=3, maxlen=3, units='voxels') voxeldims = traits.List(traits.Int, desc = 'voxel dimensions in mm', argstr='-voxeldims %s', minlen=3, maxlen=3, units='mm') seedpointmm = traits.List(traits.Int, desc = 'The coordinates of a single seed point for tractography in mm', argstr='-seedpointmm %s', minlen=3, maxlen=3, units='mm') seedpointvox = traits.List(traits.Int, desc = 'The coordinates of a single seed point for tractography in voxels', argstr='-seedpointvox %s', minlen=3, maxlen=3, units='voxels') seedfile = File(exists=False, argstr='-seedfile %s', desc='Image Containing Seed Points') regionindex = traits.Int(argstr='-regionindex %d', units='mm', desc="index of specific region to process") iterations = traits.Float(argstr='-iterations %d', units='NA', desc="Number of streamlines generated for each seed. Not required when outputting streamlines, but needed to create PICo images. The default is 1 if the output is streamlines, and 5000 if the output is connection probability images.") targetfile = File(exists=False, argstr='-targetfile %s', desc='Image containing target volumes.') allowmultitargets = traits.Bool(argstr='-allowmultitargets', desc="Allows streamlines to connect to multiple target volumes.") directional = traits.List(traits.Int, desc = 'Splits the streamlines at the seed point and computes separate connection probabilities for each segment. Streamline segments are grouped according to their dot product with the vector (X, Y, Z). The ideal vector will be tangential to the streamline trajectory at the seed, such that the streamline projects from the seed along (X, Y, Z) and -(X, Y, Z). However, it is only necessary for the streamline trajectory to not be orthogonal to (X, Y, Z).', argstr='-directional %s', minlen=3, maxlen=3, units='NA') waypointfile = File(exists=False, argstr='-waypointfile %s', desc='Image containing waypoints. Waypoints are defined as regions of the image with the same intensity, where 0 is background and any value > 0 is a waypoint.') truncateloops = traits.Bool(argstr='-truncateloops', desc="This option allows streamlines to enter a waypoint exactly once. After the streamline leaves the waypoint, it is truncated upon a second entry to the waypoint.") discardloops = traits.Bool(argstr='-discardloops', desc="This option allows streamlines to enter a waypoint exactly once. After the streamline leaves the waypoint, the entire streamline is discarded upon a second entry to the waypoint.") exclusionfile = File(exists=False, argstr='-exclusionfile %s', desc='Image containing exclusion ROIs. This should be an Analyze 7.5 header / image file.hdr and file.img.') truncateinexclusion = traits.Bool(argstr='-truncateinexclusion', desc="Retain segments of a streamline before entry to an exclusion ROI.") endpointfile = File(exists=False, argstr='-endpointfile %s', desc='Image containing endpoint ROIs. This should be an Analyze 7.5 header / image file.hdr and file.img.') resamplestepsize = traits.Float(argstr='-resamplestepsize %d', units='NA', desc="Each point on a streamline is tested for entry into target, exclusion or waypoint volumes. If the length between points on a tract is not much smaller than the voxel length, then streamlines may pass through part of a voxel without being counted. To avoid this, the program resamples streamlines such that the step size is one tenth of the smallest voxel dimension in the image. This increases the size of raw or oogl streamline output and incurs some performance penalty. The resample resolution can be controlled with this option or disabled altogether by passing a negative step size or by passing the -noresample option.") noresample = traits.Bool(argstr='-noresample', desc="Disables resampling of input streamlines. Resampling is automatically disabled if the input model is voxels.") outputtracts = traits.Bool(argstr='-outputtracts', desc="Output streamlines in raw binary format.") outputroot = File(exists=False, argstr='-outputroot %s', desc='Prepended onto all output file names.') gzip = traits.Bool(argstr='-gzip', desc="save the output image in gzip format") outputcp = traits.Bool(argstr='-outputcp', desc="output the connection probability map (Analyze image, float)", requires=['outputroot','seedfile']) outputsc = traits.Bool(argstr='-outputsc', desc="output the connection probability map (raw streamlines, int)", requires=['outputroot','seedfile']) outputacm = traits.Bool(argstr='-outputacm', desc="output all tracts in a single connection probability map (Analyze image)", requires=['outputroot','seedfile']) outputcbs = traits.Bool(argstr='-outputcbs', desc="outputs connectivity-based segmentation maps; requires target outputfile", requires=['outputroot','targetfile','seedfile']) class ProcStreamlinesOutputSpec(TraitedSpec): proc = File(exists=True, desc='Processed Streamlines') outputroot_files = OutputMultiPath(File(exists=True)) class ProcStreamlines(StdOutCommandLine): """ Process streamline data This program does post-processing of streamline output from track. It can either output streamlines or connection probability maps. * http://web4.cs.ucl.ac.uk/research/medic/camino/pmwiki/pmwiki.php?n=Man.procstreamlines Examples -------- >>> import nipype.interfaces.camino as cmon >>> proc = cmon.ProcStreamlines() >>> proc.inputs.in_file = 'tract_data.Bfloat' >>> proc.run() # doctest: +SKIP """ _cmd = 'procstreamlines' input_spec=ProcStreamlinesInputSpec output_spec=ProcStreamlinesOutputSpec def _format_arg(self, name, spec, value): if name == 'outputroot': return spec.argstr % self._get_actual_outputroot(value) return super(ProcStreamlines, self)._format_arg(name, spec, value) def _run_interface(self, runtime): outputroot = self.inputs.outputroot if isdefined(outputroot): actual_outputroot = self._get_actual_outputroot(outputroot) base, filename, ext = split_filename(actual_outputroot) if not os.path.exists(base): os.makedirs(base) new_runtime = super(ProcStreamlines, self)._run_interface(runtime) self.outputroot_files = glob.glob(os.path.join(os.getcwd(),actual_outputroot+'*')) return new_runtime else: new_runtime = super(ProcStreamlines, self)._run_interface(runtime) return new_runtime def _get_actual_outputroot(self, outputroot): actual_outputroot = os.path.join('procstream_outfiles', outputroot) return actual_outputroot def _list_outputs(self): outputs = self.output_spec().get() outputs['proc'] = os.path.abspath(self._gen_outfilename()) outputs['outputroot_files'] = self.outputroot_files return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_proc' class TractShredderInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=-2, desc='tract file') offset = traits.Int(argstr='%d', units='NA', desc='initial offset of offset tracts', position=1) bunchsize = traits.Int(argstr='%d', units='NA', desc='reads and outputs a group of bunchsize tracts', position=2) space = traits.Int(argstr='%d', units='NA', desc='skips space tracts', position=3) class TractShredderOutputSpec(TraitedSpec): shredded = File(exists=True, desc='Shredded tract file') class TractShredder(StdOutCommandLine): """ Extracts bunches of streamlines. tractshredder works in a similar way to shredder, but processes streamlines instead of scalar data. The input is raw streamlines, in the format produced by track or procstreamlines. The program first makes an initial offset of offset tracts. It then reads and outputs a group of bunchsize tracts, skips space tracts, and repeats until there is no more input. Examples -------- >>> import nipype.interfaces.camino as cmon >>> shred = cmon.TractShredder() >>> shred.inputs.in_file = 'tract_data.Bfloat' >>> shred.inputs.offset = 0 >>> shred.inputs.bunchsize = 1 >>> shred.inputs.space = 2 >>> shred.run() # doctest: +SKIP """ _cmd = 'tractshredder' input_spec=TractShredderInputSpec output_spec=TractShredderOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['shredded'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + "_shredded" class DT2NIfTIInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, position=1, desc='tract file') output_root = File(argstr='-outputroot %s', position=2, genfile=True, desc='filename root prepended onto the names of three output files.') header_file = File(exists=True, argstr='-header %s', mandatory=True, position=3, desc=' A Nifti .nii or .hdr file containing the header information') class DT2NIfTIOutputSpec(TraitedSpec): dt = File(exists=True, desc='diffusion tensors in NIfTI format') exitcode = File(exists=True, desc='exit codes from Camino reconstruction in NIfTI format') lns0 = File(exists=True, desc='estimated lns0 from Camino reconstruction in NIfTI format') class DT2NIfTI(CommandLine): """ Converts camino tensor data to NIfTI format Reads Camino diffusion tensors, and converts them to NIFTI format as three .nii files. """ _cmd = 'dt2nii' input_spec=DT2NIfTIInputSpec output_spec=DT2NIfTIOutputSpec def _list_outputs(self): outputs = self.output_spec().get() output_root = self._gen_outputroot() outputs["dt"] = os.path.abspath(output_root + "dt.nii") outputs["exitcode"] = os.path.abspath(output_root + "exitcode.nii") outputs["lns0"] = os.path.abspath(output_root + "lns0.nii") return outputs def _gen_outfilename(self): return self._gen_outputroot() def _gen_outputroot(self): output_root = self.inputs.output_root if not isdefined(output_root): output_root = self._gen_filename('output_root') return output_root def _gen_filename(self, name): if name == 'output_root': _, filename , _ = split_filename(self.inputs.in_file) filename = filename + "_" return filename class NIfTIDT2CaminoInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, position=1, desc='A NIFTI-1 dataset containing diffusion tensors. The tensors are assumed to be ' 'in lower-triangular order as specified by the NIFTI standard for the storage of ' 'symmetric matrices. This file should be either a .nii or a .hdr file.') s0_file = File(argstr='-s0 %s', exists=True, desc='File containing the unweighted signal for each voxel, may be a raw binary ' 'file (specify type with -inputdatatype) or a supported image file.') lns0_file = File(argstr='-lns0 %s', exists=True, desc='File containing the log of the unweighted signal for each voxel, may be a ' 'raw binary file (specify type with -inputdatatype) or a supported image file.') bgmask = File(argstr='-bgmask %s', exists=True, desc='Binary valued brain / background segmentation, may be a raw binary file ' '(specify type with -maskdatatype) or a supported image file.') scaleslope = traits.Float(argstr='-scaleslope %s', desc='A value v in the diffusion tensor is scaled to v * s + i. This is ' 'applied after any scaling specified by the input image. Default is 1.0.') scaleinter = traits.Float(argstr='-scaleinter %s', desc='A value v in the diffusion tensor is scaled to v * s + i. This is ' 'applied after any scaling specified by the input image. Default is 0.0.') uppertriangular = traits.Bool(argstr='-uppertriangular %s', desc = 'Specifies input in upper-triangular (VTK style) order.') class NIfTIDT2CaminoOutputSpec(TraitedSpec): out_file = File(desc='diffusion tensors data in Camino format') class NIfTIDT2Camino(CommandLine): """ Converts NIFTI-1 diffusion tensors to Camino format. The program reads the NIFTI header but does not apply any spatial transformations to the data. The NIFTI intensity scaling parameters are applied. The output is the tensors in Camino voxel ordering: [exit, ln(S0), dxx, dxy, dxz, dyy, dyz, dzz]. The exit code is set to 0 unless a background mask is supplied, in which case the code is 0 in brain voxels and -1 in background voxels. The value of ln(S0) in the output is taken from a file if one is supplied, otherwise it is set to 0. NOTE FOR FSL USERS - FSL's dtifit can output NIFTI tensors, but they are not stored in the usual way (which is using NIFTI_INTENT_SYMMATRIX). FSL's tensors follow the ITK / VTK "upper-triangular" convention, so you will need to use the -uppertriangular option to convert these correctly. """ _cmd = 'niftidt2camino' input_spec=NIfTIDT2CaminoInputSpec output_spec=NIfTIDT2CaminoOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = self._gen_filename('out_file') return outputs def _gen_filename(self, name): if name == 'out_file': _, filename , _ = split_filename(self.inputs.in_file) return filename class AnalyzeHeaderInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='Tensor-fitted data filename') scheme_file = File(exists=True, argstr='%s', position=2, desc=('Camino scheme file (b values / vectors, ' 'see camino.fsl2scheme)')) readheader = File(exists=True, argstr='-readheader %s', position=3, desc=('Reads header information from file and prints to ' 'stdout. If this option is not specified, then the ' 'program writes a header based on the other ' 'arguments.')) printimagedims = File(exists=True, argstr='-printimagedims %s', position=3, desc=('Prints image data and voxel dimensions as ' 'Camino arguments and exits.')) # How do we implement both file and enum (for the program) in one argument? # Is this option useful anyway? #-printprogargs #Prints data dimension (and type, if relevant) arguments for a specific # Camino program, where prog is one of shredder, scanner2voxel, # vcthreshselect, pdview, track. printprogargs = File(exists=True, argstr='-printprogargs %s', position=3, desc=('Prints data dimension (and type, if relevant) ' 'arguments for a specific Camino program, where ' 'prog is one of shredder, scanner2voxel, ' 'vcthreshselect, pdview, track.')) printintelbyteorder = File(exists=True, argstr='-printintelbyteorder %s', position=3, desc=('Prints 1 if the header is little-endian, ' '0 otherwise.')) printbigendian = File(exists=True, argstr='-printbigendian %s', position=3, desc=('Prints 1 if the header is big-endian, 0 ' 'otherwise.')) initfromheader = File(exists=True, argstr='-initfromheader %s', position=3, desc=('Reads header information from file and ' 'intializes a new header with the values read ' 'from the file. You may replace any ' 'combination of fields in the new header by ' 'specifying subsequent options.')) data_dims = traits.List(traits.Int, desc = 'data dimensions in voxels', argstr='-datadims %s', minlen=3, maxlen=3, units='voxels') voxel_dims = traits.List(traits.Float, desc = 'voxel dimensions in mm', argstr='-voxeldims %s', minlen=3, maxlen=3, units='mm') centre = traits.List(traits.Int, argstr='-centre %s', minlen=3, maxlen=3, units='mm', desc=('Voxel specifying origin of Talairach ' 'coordinate system for SPM, default [0 0 0].')) picoseed = traits.List(traits.Int, argstr='-picoseed %s', minlen=3, maxlen=3, desc=('Voxel specifying the seed (for PICo maps), ' 'default [0 0 0].'), units='mm') nimages = traits.Int(argstr='-nimages %d', units='NA', desc="Number of images in the img file. Default 1.") datatype = traits.Enum('byte', 'char', '[u]short', '[u]int', 'float', 'complex', 'double', argstr='-datatype %s', desc=('The char datatype is 8 bit (not the 16 bit ' 'char of Java), as specified by the Analyze ' '7.5 standard. The byte, ushort and uint ' 'types are not part of the Analyze ' 'specification but are supported by SPM.'), mandatory=True) offset = traits.Int(argstr='-offset %d', units='NA', desc=('According to the Analyze 7.5 standard, this is ' 'the byte offset in the .img file at which ' 'voxels start. This value can be negative to ' 'specify that the absolute value is applied for ' 'every image in the file.')) greylevels = traits.List(traits.Int, argstr='-gl %s', minlen=2, maxlen=2, desc=('Minimum and maximum greylevels. Stored as ' 'shorts in the header.'), units='NA') scaleslope = traits.Float(argstr='-scaleslope %d', units='NA', desc=('Intensities in the image are scaled by ' 'this factor by SPM and MRICro. Default is ' '1.0.')) scaleinter = traits.Float(argstr='-scaleinter %d', units='NA', desc=('Constant to add to the image intensities. ' 'Used by SPM and MRIcro.')) description = traits.String(argstr='-description %s', desc=('Short description - No spaces, max ' 'length 79 bytes. Will be null ' 'terminated automatically.')) intelbyteorder = traits.Bool(argstr='-intelbyteorder', desc=("Write header in intel byte order " "(little-endian).")) networkbyteorder = traits.Bool(argstr='-networkbyteorder', desc=("Write header in network byte order " "(big-endian). This is the default " "for new headers.")) class AnalyzeHeaderOutputSpec(TraitedSpec): header = File(exists=True, desc='Analyze header') class AnalyzeHeader(StdOutCommandLine): """ Create or read an Analyze 7.5 header file. Analyze image header, provides support for the most common header fields. Some fields, such as patient_id, are not currently supported. The program allows three nonstandard options: the field image_dimension.funused1 is the image scale. The intensity of each pixel in the associated .img file is (image value from file) * scale. Also, the origin of the Talairach coordinates (midline of the anterior commisure) are encoded in the field data_history.originator. These changes are included for compatibility with SPM. All headers written with this program are big endian by default. Example ------- >>> import nipype.interfaces.camino as cmon >>> hdr = cmon.AnalyzeHeader() >>> hdr.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> hdr.inputs.scheme_file = 'A.scheme' >>> hdr.inputs.data_dims = [256,256,256] >>> hdr.inputs.voxel_dims = [1,1,1] >>> hdr.run() # doctest: +SKIP """ _cmd = 'analyzeheader' input_spec=AnalyzeHeaderInputSpec output_spec=AnalyzeHeaderOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['header'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + ".hdr" class ShredderInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=-2, desc='raw binary data file') offset = traits.Int(argstr='%d', units='NA', desc='initial offset of offset bytes', position=1) chunksize = traits.Int(argstr='%d', units='NA', desc='reads and outputs a chunk of chunksize bytes', position=2) space = traits.Int(argstr='%d', units='NA', desc='skips space bytes', position=3) class ShredderOutputSpec(TraitedSpec): shredded = File(exists=True, desc='Shredded binary data file') class Shredder(StdOutCommandLine): """ Extracts periodic chunks from a data stream. Shredder makes an initial offset of offset bytes. It then reads and outputs chunksize bytes, skips space bytes, and repeats until there is no more input. If the chunksize is negative, chunks of size chunksize are read and the byte ordering of each chunk is reversed. The whole chunk will be reversed, so the chunk must be the same size as the data type, otherwise the order of the values in the chunk, as well as their endianness, will be reversed. Examples -------- >>> import nipype.interfaces.camino as cam >>> shred = cam.Shredder() >>> shred.inputs.in_file = 'SubjectA.Bfloat' >>> shred.inputs.offset = 0 >>> shred.inputs.chunksize = 1 >>> shred.inputs.space = 2 >>> shred.run() # doctest: +SKIP """ _cmd = 'shredder' input_spec=ShredderInputSpec output_spec=ShredderOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['shredded_file'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + "_shredded" nipype-0.11.0/nipype/interfaces/camino/dti.py000066400000000000000000001445331257611314500211430ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, Directory, StdOutCommandLine, StdOutCommandLineInputSpec, isdefined, InputMultiPath) from nipype.utils.filemanip import split_filename import os class DTIFitInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=1, desc='voxel-order data filename') bgmask = File(argstr='-bgmask %s', exists=True, desc=('Provides the name of a file containing a background mask computed using, ' 'for example, FSL bet2 program. The mask file contains zero in background ' 'voxels and non-zero in foreground.')) scheme_file = File(exists=True, argstr='%s', mandatory=True, position=2, desc='Camino scheme file (b values / vectors, see camino.fsl2scheme)') non_linear = traits.Bool(argstr='-nonlinear', position=3, desc="Use non-linear fitting instead of the default linear regression to the log measurements. ") class DTIFitOutputSpec(TraitedSpec): tensor_fitted = File(exists=True, desc='path/name of 4D volume in voxel order') class DTIFit(StdOutCommandLine): """ Reads diffusion MRI data, acquired using the acquisition scheme detailed in the scheme file, from the data file. Use non-linear fitting instead of the default linear regression to the log measurements. The data file stores the diffusion MRI data in voxel order with the measurements stored in big-endian format and ordered as in the scheme file. The default input data type is four-byte float. The default output data type is eight-byte double. See modelfit and camino for the format of the data file and scheme file. The program fits the diffusion tensor to each voxel and outputs the results, in voxel order and as big-endian eight-byte doubles, to the standard output. The program outputs eight values in each voxel: [exit code, ln(S(0)), D_xx, D_xy, D_xz, D_yy, D_yz, D_zz]. An exit code of zero indicates no problems. For a list of other exit codes, see modelfit(1). The entry S(0) is an estimate of the signal at q=0. Example ------- >>> import nipype.interfaces.camino as cmon >>> fit = cmon.DTIFit() >>> fit.inputs.scheme_file = 'A.scheme' >>> fit.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> fit.run() # doctest: +SKIP """ _cmd = 'dtfit' input_spec=DTIFitInputSpec output_spec=DTIFitOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['tensor_fitted'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_DT.Bdouble' class DTMetricInputSpec(CommandLineInputSpec): eigen_data = File(exists=True, argstr='-inputfile %s', mandatory=True, desc='voxel-order data filename') metric = traits.Enum('fa','md','rd','l1', 'l2', 'l3', 'tr', 'ra', '2dfa','cl','cp','cs', argstr='-stat %s', mandatory=True, desc=('Specifies the metric to compute. Possible choices are: ' '"fa", "md", "rd", "l1", "l2", "l3", "tr", "ra", "2dfa", "cl", "cp" or "cs".')) inputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char', argstr='-inputdatatype %s', usedefault=True, desc=('Specifies the data type of the input data. ' 'The data type can be any of the following strings: ' '"char", "short", "int", "long", "float" or "double".' 'Default is double data type')) outputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char', argstr='-outputdatatype %s', usedefault=True, desc=('Specifies the data type of the output data. ' 'The data type can be any of the following strings: ' '"char", "short", "int", "long", "float" or "double".' 'Default is double data type')) data_header = File(argstr='-header %s', exists=True, desc=('A Nifti .nii or .nii.gz file containing the header information. ' 'Usually this will be the header of the raw data file from which ' 'the diffusion tensors were reconstructed.')) outputfile = File(argstr='-outputfile %s', genfile=True, desc=('Output name. Output will be a .nii.gz file if data_header is provided and' 'in voxel order with outputdatatype datatype (default: double) otherwise.')) class DTMetricOutputSpec(TraitedSpec): metric_stats = File(exists=True, desc='Diffusion Tensor statistics of the chosen metric') class DTMetric(CommandLine): """ Computes tensor metric statistics based on the eigenvalues l1 >= l2 >= l3 typically obtained from ComputeEigensystem. The full list of statistics is: - = (l1 - l2) / l1 , a measure of linearity - = (l2 - l3) / l1 , a measure of planarity - = l3 / l1 , a measure of isotropy with: cl + cp + cs = 1 - = first eigenvalue - = second eigenvalue - = third eigenvalue - = l1 + l2 + l3 - = tr / 3 - = (l2 + l3) / 2 - = fractional anisotropy. (Basser et al, J Magn Reson B 1996) - = relative anisotropy (Basser et al, J Magn Reson B 1996) - <2dfa> = 2D FA of the two minor eigenvalues l2 and l3 i.e. sqrt( 2 * [(l2 - )^2 + (l3 - )^2] / (l2^2 + l3^2) ) with: = (l2 + l3) / 2 Example ------- Compute the CP planar metric as float data type. >>> import nipype.interfaces.camino as cam >>> dtmetric = cam.DTMetric() >>> dtmetric.inputs.eigen_data = 'dteig.Bdouble' >>> dtmetric.inputs.metric = 'cp' >>> dtmetric.inputs.outputdatatype = 'float' >>> dtmetric.run() # doctest: +SKIP """ _cmd = 'dtshape' input_spec=DTMetricInputSpec output_spec=DTMetricOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['metric_stats'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): return self._gen_outputfile() def _gen_outputfile(self): outputfile = self.inputs.outputfile if not isdefined(outputfile): outputfile = self._gen_filename('outputfile') return outputfile def _gen_filename(self, name): if name == 'outputfile': _, name , _ = split_filename(self.inputs.eigen_data) metric = self.inputs.metric datatype= self.inputs.outputdatatype if isdefined(self.inputs.data_header): filename = name + '_' + metric + '.nii.gz' else: filename = name + '_' + metric + '.B' + datatype return filename class ModelFitInputSpec(StdOutCommandLineInputSpec): def _gen_model_options(): #@NoSelf """ Generate all possible permutations of < multi - tensor > < single - tensor > options """ single_tensor = ['dt', 'restore', 'algdt', 'nldt_pos', 'nldt', 'ldt_wtd'] multi_tensor = ['cylcyl', 'cylcyl_eq', 'pospos', 'pospos_eq', 'poscyl', 'poscyl_eq', 'cylcylcyl', 'cylcylcyl_eq', 'pospospos', 'pospospos_eq', 'posposcyl', 'posposcyl_eq', 'poscylcyl', 'poscylcyl_eq'] other = ['adc', 'ball_stick'] model_list = single_tensor model_list.extend(other) model_list.extend([multi + ' ' + single for multi in multi_tensor for single in single_tensor]) return model_list model = traits.Enum(_gen_model_options(), argstr='-model %s', mandatory=True, desc='Specifies the model to be fit to the data.') in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, desc='voxel-order data filename') inputdatatype = traits.Enum('float', 'char', 'short', 'int', 'long', 'double', argstr='-inputdatatype %s', desc='Specifies the data type of the input file: "char", "short", "int", "long", "float" or "double". The input file must have BIG-ENDIAN ordering. By default, the input type is "float".') scheme_file = File(exists=True, argstr='-schemefile %s', mandatory=True, desc='Camino scheme file (b values / vectors, see camino.fsl2scheme)') outputfile = File(argstr='-outputfile %s', desc='Filename of the output file.') outlier = File(argstr='-outliermap %s', exists=True, desc='Specifies the name of the file to contain the outlier map generated by the RESTORE algorithm.') noisemap = File(argstr='-noisemap %s', exists=True, desc='Specifies the name of the file to contain the estimated noise variance on the diffusion-weighted signal, generated by a weighted tensor fit. The data type of this file is big-endian double.') residualmap = File(argstr='-residualmap %s', exists=True, desc='Specifies the name of the file to contain the weighted residual errors after computing a weighted linear tensor fit. One value is produced per measurement, in voxel order.The data type of this file is big-endian double. Images of the residuals for each measurement can be extracted with shredder.') sigma = traits.Float(argstr='-sigma %G', desc='Specifies the standard deviation of the noise in the data. Required by the RESTORE algorithm.') bgthresh = traits.Float(argstr='-bgthresh %G', desc='Sets a threshold on the average q=0 measurement to separate foreground and background. The program does not process background voxels, but outputs the same number of values in background voxels and foreground voxels. Each value is zero in background voxels apart from the exit code which is -1.') bgmask = File(argstr='-bgmask %s', exists=True, desc='Provides the name of a file containing a background mask computed using, for example, FSL\'s bet2 program. The mask file contains zero in background voxels and non-zero in foreground.') cfthresh = traits.Float(argstr='-csfthresh %G', desc='Sets a threshold on the average q=0 measurement to determine which voxels are CSF. This program does not treat CSF voxels any different to other voxels.') fixedmodq = traits.List(traits.Float, argstr='-fixedmod %s', minlen=4, maxlen=4, desc='Specifies a spherical acquisition scheme with M measurements with q=0 and N measurements with |q|=Q and diffusion time tau. The N measurements with |q|=Q have unique directions. The program reads in the directions from the files in directory PointSets.') fixedbvalue = traits.List(traits.Float, argstr='-fixedbvalue %s', minlen=3, maxlen=3, desc='As above, but specifies . The resulting scheme is the same whether you specify b directly or indirectly using -fixedmodq.') tau = traits.Float(argstr='-tau %G', desc='Sets the diffusion time separately. This overrides the diffusion time specified in a scheme file or by a scheme index for both the acquisition scheme and in the data synthesis.') class ModelFitOutputSpec(TraitedSpec): fitted_data = File(exists=True, desc='output file of 4D volume in voxel order') class ModelFit(StdOutCommandLine): """ Fits models of the spin-displacement density to diffusion MRI measurements. This is an interface to various model fitting routines for diffusion MRI data that fit models of the spin-displacement density function. In particular, it will fit the diffusion tensor to a set of measurements as well as various other models including two or three-tensor models. The program can read input data from a file or can generate synthetic data using various test functions for testing and simulations. Example ------- >>> import nipype.interfaces.camino as cmon >>> fit = cmon.ModelFit() >>> fit.model = 'dt' >>> fit.inputs.scheme_file = 'A.scheme' >>> fit.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> fit.run() # doctest: +SKIP """ _cmd = 'modelfit' input_spec=ModelFitInputSpec output_spec=ModelFitOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['fitted_data'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_fit.Bdouble' class DTLUTGenInputSpec(StdOutCommandLineInputSpec): lrange = traits.List(traits.Float, desc = 'Index to one-tensor LUTs. This is the ratio L1/L3 and L2 / L3.' \ 'The LUT is square, with half the values calculated (because L2 / L3 cannot be less than L1 / L3 by definition).' \ 'The minimum must be >= 1. For comparison, a ratio L1 / L3 = 10 with L2 / L3 = 1 corresponds to an FA of 0.891, '\ 'and L1 / L3 = 15 with L2 / L3 = 1 corresponds to an FA of 0.929. The default range is 1 to 10.', \ argstr='-lrange %s', minlen=2, maxlen=2, position=1, units='NA') frange = traits.List(traits.Float, desc = 'Index to two-tensor LUTs. This is the fractional anisotropy \ of the two tensors. The default is 0.3 to 0.94', \ argstr='-frange %s', minlen=2, maxlen=2, position=1, units='NA') step = traits.Float(argstr='-step %f', units='NA', desc='Distance between points in the LUT.' \ 'For example, if lrange is 1 to 10 and the step is 0.1, LUT entries will be computed ' \ 'at L1 / L3 = 1, 1.1, 1.2 ... 10.0 and at L2 / L3 = 1.0, 1.1 ... L1 / L3.' \ 'For single tensor LUTs, the default step is 0.2, for two-tensor LUTs it is 0.02.') samples = traits.Int(argstr='-samples %d', units='NA', desc='The number of synthetic measurements to generate at each point in the LUT. The default is 2000.') snr = traits.Float(argstr='-snr %f', units='NA', desc='The signal to noise ratio of the unweighted (q = 0) measurements.'\ 'This should match the SNR (in white matter) of the images that the LUTs are used with.') bingham = traits.Bool(argstr='-bingham', desc="Compute a LUT for the Bingham PDF. This is the default.") acg = traits.Bool(argstr='-acg', desc="Compute a LUT for the ACG PDF.") watson = traits.Bool(argstr='-watson', desc="Compute a LUT for the Watson PDF.") inversion = traits.Int(argstr='-inversion %d', units='NA', desc='Index of the inversion to use. The default is 1 (linear single tensor inversion).') trace = traits.Float(argstr='-trace %G', units='NA', desc='Trace of the diffusion tensor(s) used in the test function in the LUT generation. The default is 2100E-12 m^2 s^-1.') scheme_file = File(argstr='-schemefile %s', mandatory=True, position=2, desc='The scheme file of the images to be processed using this LUT.') class DTLUTGenOutputSpec(TraitedSpec): dtLUT = File(exists=True, desc='Lookup Table') class DTLUTGen(StdOutCommandLine): """ Calibrates the PDFs for PICo probabilistic tractography. This program needs to be run once for every acquisition scheme. It outputs a lookup table that is used by the dtpicoparams program to find PICo PDF parameters for an image. The default single tensor LUT contains parameters of the Bingham distribution and is generated by supplying a scheme file and an estimated signal to noise in white matter regions of the (q=0) image. The default inversion is linear (inversion index 1). Advanced users can control several options, including the extent and resolution of the LUT, the inversion index, and the type of PDF. See dtlutgen(1) for details. Example ------- >>> import nipype.interfaces.camino as cmon >>> dtl = cmon.DTLUTGen() >>> dtl.inputs.snr = 16 >>> dtl.inputs.scheme_file = 'A.scheme' >>> dtl.run() # doctest: +SKIP """ _cmd = 'dtlutgen' input_spec=DTLUTGenInputSpec output_spec=DTLUTGenOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['dtLUT'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.scheme_file) return name + '.dat' class PicoPDFsInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='voxel-order data filename') inputmodel = traits.Enum('dt', 'multitensor', 'pds', argstr='-inputmodel %s', position=2, desc='input model type', usedefault=True) luts = InputMultiPath(File(exists=True), argstr='-luts %s', mandatory=True, desc='Files containing the lookup tables.'\ 'For tensor data, one lut must be specified for each type of inversion used in the image (one-tensor, two-tensor, three-tensor).'\ 'For pds, the number of LUTs must match -numpds (it is acceptable to use the same LUT several times - see example, above).'\ 'These LUTs may be generated with dtlutgen.') pdf = traits.Enum('bingham', 'watson', 'acg', argstr='-pdf %s', position=4, desc=' Specifies the PDF to use. There are three choices:'\ 'watson - The Watson distribution. This distribution is rotationally symmetric.'\ 'bingham - The Bingham distributionn, which allows elliptical probability density contours.'\ 'acg - The Angular Central Gaussian distribution, which also allows elliptical probability density contours', usedefault=True) directmap = traits.Bool(argstr='-directmap', desc="Only applicable when using pds as the inputmodel. Use direct mapping between the eigenvalues and the distribution parameters instead of the log of the eigenvalues.") maxcomponents = traits.Int(argstr='-maxcomponents %d', units='NA', desc='The maximum number of tensor components in a voxel (default 2) for multitensor data.'\ 'Currently, only the default is supported, but future releases may allow the input of three-tensor data using this option.') numpds = traits.Int(argstr='-numpds %d', units='NA', desc='The maximum number of PDs in a voxel (default 3) for PD data.' \ 'This option determines the size of the input and output voxels.' \ 'This means that the data file may be large enough to accomodate three or more PDs,'\ 'but does not mean that any of the voxels are classified as containing three or more PDs.') class PicoPDFsOutputSpec(TraitedSpec): pdfs = File(exists=True, desc='path/name of 4D volume in voxel order') class PicoPDFs(StdOutCommandLine): """ Constructs a spherical PDF in each voxel for probabilistic tractography. Example ------- >>> import nipype.interfaces.camino as cmon >>> pdf = cmon.PicoPDFs() >>> pdf.inputs.inputmodel = 'dt' >>> pdf.inputs.luts = ['lut_file'] >>> pdf.inputs.in_file = 'voxel-order_data.Bfloat' >>> pdf.run() # doctest: +SKIP """ _cmd = 'picopdfs' input_spec=PicoPDFsInputSpec output_spec=PicoPDFsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['pdfs'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_pdfs.Bdouble' class TrackInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', position=1, desc='input data file') seed_file = File(exists=True, argstr='-seedfile %s', position=2, desc='seed file') inputmodel = traits.Enum('dt', 'multitensor', 'sfpeak', 'pico', 'repbs_dt', 'repbs_multitensor', 'ballstick', 'wildbs_dt', 'bayesdirac', 'bayesdirac_dt','bedpostx_dyad', 'bedpostx', argstr='-inputmodel %s', desc='input model type', usedefault=True) tracker = traits.Enum('fact', 'euler', 'rk4', argstr='-tracker %s', desc=("The tracking algorithm controls streamlines are " "generated from the data. The choices are: " "- FACT, which follows the local fibre orientation " "in each voxel. No interpolation is used." "- EULER, which uses a fixed step size along the " "local fibre orientation. With nearest-neighbour " "interpolation, this method may be very similar to " "FACT, except that the step size is fixed, whereas " "FACT steps extend to the boundary of the next voxel " "(distance variable depending on the entry and exit " "points to the voxel)." "- RK4: Fourth-order Runge-Kutta method. The step " "size is fixed, however the eventual direction of " "the step is determined by taking and averaging a " "series of partial steps."), usedefault=True) interpolator = traits.Enum('nn', 'prob_nn', 'linear', argstr='-interpolator %s', desc=("The interpolation algorithm determines how " "the fiber orientation(s) are defined at a given " "continuous point within the input image. " "Interpolators are only used when the tracking " "algorithm is not FACT. The choices are: " "- NN: Nearest-neighbour interpolation, just " "uses the local voxel data directly." "- PROB_NN: Probabilistic nearest-neighbor " "interpolation, similar to the method pro- " "posed by Behrens et al [Magnetic Resonance " "in Medicine, 50:1077-1088, 2003]. The data " "is not interpolated, but at each point we " "randomly choose one of the 8 voxels sur- " "rounding a point. The probability of choosing " "a particular voxel is based on how close the " "point is to the centre of that voxel." "- LINEAR: Linear interpolation of the vector " "field containing the principal directions at " "each point.")) stepsize = traits.Float(argstr='-stepsize %f', requires=['tracker'], desc=('Step size for EULER and RK4 tracking. ' 'The default is 1mm.')) inputdatatype = traits.Enum('float', 'double', argstr='-inputdatatype %s', desc='input file type') gzip = traits.Bool(argstr='-gzip', desc="save the output image in gzip format") maxcomponents = traits.Int(argstr='-maxcomponents %d', units='NA', desc=("The maximum number of tensor components in a " "voxel. This determines the size of the input " "file and does not say anything about the " "voxel classification. The default is 2 if " "the input model is multitensor and 1 if the " "input model is dt.")) numpds = traits.Int(argstr='-numpds %d', units='NA', desc=("The maximum number of PDs in a voxel for input " "models sfpeak and pico. The default is 3 for input " "model sfpeak and 1 for input model pico. This option " "determines the size of the voxels in the input file " "and does not affect tracking. For tensor data, use " "the -maxcomponents option.")) data_dims = traits.List(traits.Int, desc='data dimensions in voxels', argstr='-datadims %s', minlen=3, maxlen=3, units='voxels') voxel_dims = traits.List(traits.Float, desc='voxel dimensions in mm', argstr='-voxeldims %s', minlen=3, maxlen=3, units='mm') ipthresh = traits.Float(argstr='-ipthresh %f', desc=('Curvature threshold for tracking, expressed as ' 'the minimum dot product between two streamline ' 'orientations calculated over the length of a ' 'voxel. If the dot product between the previous ' 'and current directions is less than this ' 'threshold, then the streamline terminates. The ' 'default setting will terminate fibres that curve ' 'by more than 80 degrees. Set this to -1.0 to ' 'disable curvature checking completely.')) curvethresh = traits.Float(argstr='-curvethresh %f', desc=('Curvature threshold for tracking, expressed ' 'as the maximum angle (in degrees) between ' 'between two streamline orientations ' 'calculated over the length of a voxel. If ' 'the angle is greater than this, then the ' 'streamline terminates.')) curveinterval = traits.Float(argstr='-curveinterval %f', requires=['curvethresh'], desc=('Interval over which the curvature threshold ' 'should be evaluated, in mm. The default is ' '5mm. When using the default curvature ' 'threshold of 90 degrees, this means that ' 'streamlines will terminate if they curve by ' 'more than 90 degrees over a path length ' 'of 5mm.')) anisthresh = traits.Float(argstr='-anisthresh %f', desc=('Terminate fibres that enter a voxel with lower ' 'anisotropy than the threshold.')) anisfile = File(argstr='-anisfile %s', exists=True, desc=('File containing the anisotropy map. This is required to ' 'apply an anisotropy threshold with non tensor data. If ' 'the map issupplied it is always used, even in tensor ' 'data.')) outputtracts = traits.Enum('float', 'double', 'oogl', argstr='-outputtracts %s', desc='output tract file type') out_file = File(argstr='-outputfile %s', position= -1, genfile=True, desc='output data file') output_root = File(exists=False, argstr='-outputroot %s', position= -1, desc='root directory for output') class TrackOutputSpec(TraitedSpec): tracked = File(exists=True, desc='output file containing reconstructed tracts') class Track(CommandLine): """ Performs tractography using one of the following models: dt', 'multitensor', 'pds', 'pico', 'bootstrap', 'ballstick', 'bayesdirac' Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.Track() >>> track.inputs.inputmodel = 'dt' >>> track.inputs.in_file = 'data.Bfloat' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ _cmd = 'track' input_spec = TrackInputSpec output_spec = TrackOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.out_file): out_file_path = os.path.abspath(self.inputs.out_file) else: out_file_path = os.path.abspath(self._gen_outfilename()) outputs['tracked'] = out_file_path return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): # Currently in_file is only undefined for bedpostx input if not isdefined(self.inputs.in_file): name = 'bedpostx' else: _, name , _ = split_filename(self.inputs.in_file) return name + '_tracked' class TrackDT(Track): """ Performs streamline tractography using tensor data Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.TrackDT() >>> track.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ def __init__(self, command=None, **inputs): inputs["inputmodel"] = "dt" return super(TrackDT, self).__init__(command, **inputs) class TrackPICoInputSpec(TrackInputSpec): pdf = traits.Enum('bingham', 'watson', 'acg', argstr='-pdf %s', desc='Specifies the model for PICo parameters. The default is "bingham.') iterations = traits.Int(argstr='-iterations %d', units='NA', desc="Number of streamlines to generate at each seed point. The default is 5000.") class TrackPICo(Track): """ Performs streamline tractography using the Probabilistic Index of Connectivity (PICo) algorithm Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.TrackPICo() >>> track.inputs.in_file = 'pdfs.Bfloat' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ input_spec = TrackPICoInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "pico" return super(TrackPICo, self).__init__(command, **inputs) class TrackBedpostxDeterInputSpec(TrackInputSpec): bedpostxdir = Directory(argstr='-bedpostxdir %s', mandatory=True, exists=True, desc=('Directory containing bedpostx output')) min_vol_frac = traits.Float(argstr='-bedpostxminf %d', units='NA', desc=("Zeros out compartments in bedpostx data " "with a mean volume fraction f of less than " "min_vol_frac. The default is 0.01.")) class TrackBedpostxDeter(Track): """ Data from FSL's bedpostx can be imported into Camino for deterministic tracking. (Use TrackBedpostxProba for bedpostx probabilistic tractography.) The tracking is based on the vector images dyads1.nii.gz, ... , dyadsN.nii.gz, where there are a maximum of N compartments (corresponding to each fiber population) in each voxel. It also uses the N images mean_f1samples.nii.gz, ..., mean_fNsamples.nii.gz, normalized such that the sum of all compartments is 1. Compartments where the mean_f is less than a threshold are discarded and not used for tracking. The default value is 0.01. This can be changed with the min_vol_frac option. Example ------- >>> import nipype.interfaces.camino as cam >>> track = cam.TrackBedpostxDeter() >>> track.inputs.bedpostxdir = 'bedpostxout' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ input_spec = TrackBedpostxDeterInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bedpostx_dyad" return super(TrackBedpostxDeter, self).__init__(command, **inputs) class TrackBedpostxProbaInputSpec(TrackInputSpec): bedpostxdir = Directory(argstr='-bedpostxdir %s', mandatory=True, exists=True, desc=('Directory containing bedpostx output')) min_vol_frac = traits.Float(argstr='-bedpostxminf %d', units='NA', desc=("Zeros out compartments in bedpostx data " "with a mean volume fraction f of less than " "min_vol_frac. The default is 0.01.")) iterations = traits.Int(argstr='-iterations %d', units='NA', desc=("Number of streamlines to generate at each " "seed point. The default is 1.")) class TrackBedpostxProba(Track): """ Data from FSL's bedpostx can be imported into Camino for probabilistic tracking. (Use TrackBedpostxDeter for bedpostx deterministic tractography.) The tracking uses the files merged_th1samples.nii.gz, merged_ph1samples.nii.gz, ... , merged_thNsamples.nii.gz, merged_phNsamples.nii.gz where there are a maximum of N compartments (corresponding to each fiber population) in each voxel. These images contain M samples of theta and phi, the polar coordinates describing the "stick" for each compartment. At each iteration, a random number X between 1 and M is drawn and the Xth samples of theta and phi become the principal directions in the voxel. It also uses the N images mean_f1samples.nii.gz, ..., mean_fNsamples.nii.gz, normalized such that the sum of all compartments is 1. Compartments where the mean_f is less than a threshold are discarded and not used for tracking. The default value is 0.01. This can be changed with the min_vol_frac option. Example ------- >>> import nipype.interfaces.camino as cam >>> track = cam.TrackBedpostxProba() >>> track.inputs.bedpostxdir = 'bedpostxout' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.inputs.iterations = 100 >>> track.run() # doctest: +SKIP """ input_spec = TrackBedpostxProbaInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bedpostx_dyad" return super(TrackBedpostxProba, self).__init__(command, **inputs) class TrackBayesDiracInputSpec(TrackInputSpec): scheme_file = File(argstr='-schemefile %s', mandatory=True, exists=True, desc=('The scheme file corresponding to the data being ' 'processed.')) iterations = traits.Int(argstr='-iterations %d', units='NA', desc=("Number of streamlines to generate at each " "seed point. The default is 5000.")) pdf = traits.Enum('bingham', 'watson', 'acg', argstr='-pdf %s', desc='Specifies the model for PICo priors (not the curvature priors). The default is "bingham".') pointset = traits.Int(argstr='-pointset %s', desc='Index to the point set to use for Bayesian likelihood calculation. The index specifies a set of evenly distributed points on the unit sphere, where each point x defines two possible step directions (x or -x) for the streamline path. A larger number indexes a larger point set, which gives higher angular resolution at the expense of computation time. The default is index 1, which gives 1922 points, index 0 gives 1082 points, index 2 gives 3002 points.') datamodel = traits.Enum('cylsymmdt', 'ballstick', argstr='-datamodel %s', desc='Model of the data for Bayesian tracking. The default model is "cylsymmdt", a diffusion tensor with cylindrical symmetry about e_1, ie L1 >= L_2 = L_3. The other model is "ballstick", the partial volume model (see ballstickfit).') curvepriork = traits.Float(argstr='-curvepriork %G', desc='Concentration parameter for the prior distribution on fibre orientations given the fibre orientation at the previous step. Larger values of k make curvature less likely.') curvepriorg = traits.Float(argstr='-curvepriorg %G', desc='Concentration parameter for the prior distribution on fibre orientations given the fibre orientation at the previous step. Larger values of g make curvature less likely.') extpriorfile = File(exists=True, argstr='-extpriorfile %s', desc='Path to a PICo image produced by picopdfs. The PDF in each voxel is used as a prior for the fibre orientation in Bayesian tracking. The prior image must be in the same space as the diffusion data.') extpriordatatype = traits.Enum('float', 'double', argstr='-extpriordatatype %s', desc='Datatype of the prior image. The default is "double".') class TrackBayesDirac(Track): """ Performs streamline tractography using a Bayesian tracking with Dirac priors Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.TrackBayesDirac() >>> track.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.inputs.scheme_file = 'bvecs.scheme' >>> track.run() # doctest: +SKIP """ input_spec = TrackBayesDiracInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bayesdirac" return super(TrackBayesDirac, self).__init__(command, **inputs) class TrackBallStick(Track): """ Performs streamline tractography using ball-stick fitted data Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.TrackBallStick() >>> track.inputs.in_file = 'ballstickfit_data.Bfloat' >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ def __init__(self, command=None, **inputs): inputs["inputmodel"] = "ballstick" return super(TrackBallStick, self).__init__(command, **inputs) class TrackBootstrapInputSpec(TrackInputSpec): scheme_file = File(argstr='-schemefile %s', mandatory=True, exists=True, desc='The scheme file corresponding to the data being processed.') iterations = traits.Int(argstr='-iterations %d', units='NA', desc="Number of streamlines to generate at each seed point.") inversion = traits.Int(argstr='-inversion %s', desc = 'Tensor reconstruction algorithm for repetition bootstrapping. Default is 1 (linear reconstruction, single tensor).') bsdatafiles = traits.List(File(exists=True), mandatory=True, argstr='-bsdatafile %s', desc='Specifies files containing raw data for repetition bootstrapping. Use -inputfile for wild bootstrap data.') bgmask = File(argstr='-bgmask %s', exists=True, desc = 'Provides the name of a file containing a background mask computed using, for example, FSL\'s bet2 program. The mask file contains zero in background voxels and non-zero in foreground.') class TrackBootstrap(Track): """ Performs bootstrap streamline tractography using mulitple scans of the same subject Example ------- >>> import nipype.interfaces.camino as cmon >>> track = cmon.TrackBootstrap() >>> track.inputs.inputmodel='repbs_dt' >>> track.inputs.scheme_file = 'bvecs.scheme' >>> track.inputs.bsdatafiles = ['fitted_data1.Bfloat', 'fitted_data2.Bfloat'] >>> track.inputs.seed_file = 'seed_mask.nii' >>> track.run() # doctest: +SKIP """ input_spec = TrackBootstrapInputSpec def __init__(self, command=None, **inputs): return super(TrackBootstrap, self).__init__(command, **inputs) class ComputeMeanDiffusivityInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='Tensor-fitted data filename') scheme_file = File(exists=True, argstr='%s', position=2, desc='Camino scheme file (b values / vectors, see camino.fsl2scheme)') out_file = File(argstr="> %s", position=-1, genfile=True) inputmodel = traits.Enum('dt', 'twotensor', 'threetensor', argstr='-inputmodel %s', desc='Specifies the model that the input tensor data contains parameters for.' \ 'Possible model types are: "dt" (diffusion-tensor data), "twotensor" (two-tensor data), '\ '"threetensor" (three-tensor data). By default, the program assumes that the input data '\ 'contains a single diffusion tensor in each voxel.') inputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-inputdatatype %s', desc='Specifies the data type of the input file. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') outputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-outputdatatype %s', desc='Specifies the data type of the output data. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') class ComputeMeanDiffusivityOutputSpec(TraitedSpec): md = File(exists=True, desc='Mean Diffusivity Map') class ComputeMeanDiffusivity(StdOutCommandLine): """ Computes the mean diffusivity (trace/3) from diffusion tensors. Example ------- >>> import nipype.interfaces.camino as cmon >>> md = cmon.ComputeMeanDiffusivity() >>> md.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> md.inputs.scheme_file = 'A.scheme' >>> md.run() # doctest: +SKIP """ _cmd = 'md' input_spec=ComputeMeanDiffusivityInputSpec output_spec=ComputeMeanDiffusivityOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["md"] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + "_MD.img" #Need to change to self.inputs.outputdatatype class ComputeFractionalAnisotropyInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='Tensor-fitted data filename') scheme_file = File(exists=True, argstr='%s', position=2, desc='Camino scheme file (b values / vectors, see camino.fsl2scheme)') inputmodel = traits.Enum('dt', 'twotensor', 'threetensor', 'multitensor', argstr='-inputmodel %s', desc='Specifies the model that the input tensor data contains parameters for.' \ 'Possible model types are: "dt" (diffusion-tensor data), "twotensor" (two-tensor data), '\ '"threetensor" (three-tensor data). By default, the program assumes that the input data '\ 'contains a single diffusion tensor in each voxel.') inputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-inputdatatype %s', desc='Specifies the data type of the input file. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') outputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-outputdatatype %s', desc='Specifies the data type of the output data. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') class ComputeFractionalAnisotropyOutputSpec(TraitedSpec): fa = File(exists=True, desc='Fractional Anisotropy Map') class ComputeFractionalAnisotropy(StdOutCommandLine): """ Computes the fractional anisotropy of tensors. Reads diffusion tensor (single, two-tensor or three-tensor) data from the standard input, computes the fractional anisotropy (FA) of each tensor and outputs the results to the standard output. For multiple-tensor data the program outputs the FA of each tensor, so for three-tensor data, for example, the output contains three fractional anisotropy values per voxel. Example ------- >>> import nipype.interfaces.camino as cmon >>> fa = cmon.ComputeFractionalAnisotropy() >>> fa.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> fa.inputs.scheme_file = 'A.scheme' >>> fa.run() # doctest: +SKIP """ _cmd = 'fa' input_spec=ComputeFractionalAnisotropyInputSpec output_spec=ComputeFractionalAnisotropyOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['fa'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_FA.Bdouble' #Need to change to self.inputs.outputdatatype class ComputeTensorTraceInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='Tensor-fitted data filename') scheme_file = File(exists=True, argstr='%s', position=2, desc='Camino scheme file (b values / vectors, see camino.fsl2scheme)') inputmodel = traits.Enum('dt', 'twotensor', 'threetensor', 'multitensor', argstr='-inputmodel %s', desc='Specifies the model that the input tensor data contains parameters for.' \ 'Possible model types are: "dt" (diffusion-tensor data), "twotensor" (two-tensor data), '\ '"threetensor" (three-tensor data). By default, the program assumes that the input data '\ 'contains a single diffusion tensor in each voxel.') inputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-inputdatatype %s', desc='Specifies the data type of the input file. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') outputdatatype = traits.Enum('char', 'short', 'int', 'long', 'float', 'double', argstr='-outputdatatype %s', desc='Specifies the data type of the output data. The data type can be any of the' \ 'following strings: "char", "short", "int", "long", "float" or "double".') class ComputeTensorTraceOutputSpec(TraitedSpec): trace = File(exists=True, desc='Trace of the diffusion tensor') class ComputeTensorTrace(StdOutCommandLine): """ Computes the trace of tensors. Reads diffusion tensor (single, two-tensor or three-tensor) data from the standard input, computes the trace of each tensor, i.e., three times the mean diffusivity, and outputs the results to the standard output. For multiple-tensor data the program outputs the trace of each tensor, so for three-tensor data, for example, the output contains three values per voxel. Divide the output by three to get the mean diffusivity. Example ------- >>> import nipype.interfaces.camino as cmon >>> trace = cmon.ComputeTensorTrace() >>> trace.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> trace.inputs.scheme_file = 'A.scheme' >>> trace.run() # doctest: +SKIP """ _cmd = 'trd' input_spec=ComputeTensorTraceInputSpec output_spec=ComputeTensorTraceOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['trace'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_TrD.img' #Need to change to self.inputs.outputdatatype class ComputeEigensystemInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='< %s', mandatory=True, position=1, desc='Tensor-fitted data filename') inputmodel = traits.Enum('dt', 'multitensor', argstr='-inputmodel %s', desc='Specifies the model that the input data contains parameters for. Possible model types are: "dt" (diffusion-tensor data) and "multitensor"') maxcomponents = traits.Int(argstr='-maxcomponents %d', desc='The maximum number of tensor components in a voxel of the input data.') inputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char', argstr='-inputdatatype %s', usedefault=True, desc=('Specifies the data type of the input data. ' 'The data type can be any of the following strings: ' '"char", "short", "int", "long", "float" or "double".' 'Default is double data type')) outputdatatype = traits.Enum('double', 'float', 'long', 'int', 'short', 'char', argstr='-outputdatatype %s', usedefault=True, desc=('Specifies the data type of the output data. ' 'The data type can be any of the following strings: ' '"char", "short", "int", "long", "float" or "double".' 'Default is double data type')) class ComputeEigensystemOutputSpec(TraitedSpec): eigen = File(exists=True, desc='Trace of the diffusion tensor') class ComputeEigensystem(StdOutCommandLine): """ Computes the eigensystem from tensor fitted data. Reads diffusion tensor (single, two-tensor, three-tensor or multitensor) data from the standard input, computes the eigenvalues and eigenvectors of each tensor and outputs the results to the standard output. For multiple-tensor data the program outputs the eigensystem of each tensor. For each tensor the program outputs: {l_1, e_11, e_12, e_13, l_2, e_21, e_22, e_33, l_3, e_31, e_32, e_33}, where l_1 >= l_2 >= l_3 and e_i = (e_i1, e_i2, e_i3) is the eigenvector with eigenvalue l_i. For three-tensor data, for example, the output contains thirty-six values per voxel. Example ------- >>> import nipype.interfaces.camino as cmon >>> dteig = cmon.ComputeEigensystem() >>> dteig.inputs.in_file = 'tensor_fitted_data.Bdouble' >>> dteig.run() # doctest: +SKIP """ _cmd = 'dteig' input_spec=ComputeEigensystemInputSpec output_spec=ComputeEigensystemOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["eigen"] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) datatype= self.inputs.outputdatatype return name + '_eig.B' + datatype nipype-0.11.0/nipype/interfaces/camino/odf.py000066400000000000000000000546641257611314500211400ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, StdOutCommandLine, StdOutCommandLineInputSpec, isdefined) from nipype.utils.filemanip import split_filename class QBallMXInputSpec(StdOutCommandLineInputSpec): basistype = traits.Enum('rbf', 'sh', argstr='-basistype %s', desc=('Basis function type. "rbf" to use radial basis functions ' '"sh" to use spherical harmonics'), usedefault=True) scheme_file = File(exists=True, argstr='-schemefile %s', mandatory=True, desc='Specifies the scheme file for the diffusion MRI data') order = traits.Int(argstr='-order %d', units='NA', desc=('Specific to sh. Maximum order of the spherical harmonic series. ' 'Default is 4.')) rbfpointset = traits.Int(argstr='-rbfpointset %d', units='NA', desc=('Specific to rbf. Sets the number of radial basis functions to use. ' 'The value specified must be present in the Pointsets directory. ' 'The default value is 246.')) rbfsigma = traits.Float(argstr='-rbfsigma %f', units='NA', desc=('Specific to rbf. Sets the width of the interpolating basis functions. ' 'The default value is 0.2618 (15 degrees).')) smoothingsigma = traits.Float(argstr='-smoothingsigma %f', units='NA', desc=('Specific to rbf. Sets the width of the smoothing basis functions. ' 'The default value is 0.1309 (7.5 degrees).')) class QBallMXOutputSpec(TraitedSpec): qmat = File(exists=True, desc='Q-Ball reconstruction matrix') class QBallMX(StdOutCommandLine): """ Generates a reconstruction matrix for Q-Ball. Used in LinRecon with the same scheme file to reconstruct data. Example 1 --------- To create a linear transform matrix using Spherical Harmonics (sh). >>> import nipype.interfaces.camino as cam >>> qballmx = cam.QBallMX() >>> qballmx.inputs.scheme_file = 'A.scheme' >>> qballmx.inputs.basistype = 'sh' >>> qballmx.inputs.order = 6 >>> qballmx.run() # doctest: +SKIP Example 2 --------- To create a linear transform matrix using Radial Basis Functions (rbf). This command uses the default setting of rbf sigma = 0.2618 (15 degrees), data smoothing sigma = 0.1309 (7.5 degrees), rbf pointset 246 >>> import nipype.interfaces.camino as cam >>> qballmx = cam.QBallMX() >>> qballmx.inputs.scheme_file = 'A.scheme' >>> qballmx.run() # doctest: +SKIP The linear transform matrix from any of these two examples can then be run over each voxel using LinRecon >>> qballcoeffs = cam.LinRecon() >>> qballcoeffs.inputs.in_file = 'SubjectA.Bfloat' >>> qballcoeffs.inputs.scheme_file = 'A.scheme' >>> qballcoeffs.inputs.qball_mat = 'A_qmat.Bdouble' >>> qballcoeffs.inputs.normalize = True >>> qballcoeffs.inputs.bgmask = 'brain_mask.nii' >>> qballcoeffs.run() # doctest: +SKIP """ _cmd = 'qballmx' input_spec=QBallMXInputSpec output_spec=QBallMXOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['qmat'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.scheme_file) return name + '_qmat.Bdouble' class LinReconInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=1, desc='voxel-order data filename') scheme_file = File(exists=True, argstr='%s', mandatory=True, position=2, desc='Specifies the scheme file for the diffusion MRI data') qball_mat = File(exists=True, argstr='%s', mandatory=True, position=3, desc='Linear transformation matrix.') normalize = traits.Bool(argstr='-normalize', desc=('Normalize the measurements and discard ' 'the zero measurements before the linear transform.')) log = traits.Bool(argstr='-log', desc=('Transform the log measurements rather than the ' 'measurements themselves')) bgmask = File(exists=True, argstr='-bgmask %s', desc='background mask') class LinReconOutputSpec(TraitedSpec): recon_data = File(exists=True, desc='Transformed data') class LinRecon(StdOutCommandLine): """ Runs a linear transformation in each voxel. Reads a linear transformation from the matrix file assuming the imaging scheme specified in the scheme file. Performs the linear transformation on the data in every voxel and outputs the result to the standard output. The ouput in every voxel is actually: :: [exit code, ln(S(0)), p1, ..., pR] where p1, ..., pR are the parameters of the reconstruction. Possible exit codes are: - 0. No problems. - 6. Bad data replaced by substitution of zero. The matrix must be R by N+M where N+M is the number of measurements and R is the number of parameters of the reconstruction. The matrix file contains binary double-precision floats. The matrix elements are stored row by row. Example --------- First run QBallMX and create a linear transform matrix using Spherical Harmonics (sh). >>> import nipype.interfaces.camino as cam >>> qballmx = cam.QBallMX() >>> qballmx.inputs.scheme_file = 'A.scheme' >>> qballmx.inputs.basistype = 'sh' >>> qballmx.inputs.order = 4 >>> qballmx.run() # doctest: +SKIP Then run it over each voxel using LinRecon >>> qballcoeffs = cam.LinRecon() >>> qballcoeffs.inputs.in_file = 'SubjectA.Bfloat' >>> qballcoeffs.inputs.scheme_file = 'A.scheme' >>> qballcoeffs.inputs.qball_mat = 'A_qmat.Bdouble' >>> qballcoeffs.inputs.normalize = True >>> qballcoeffs.run() # doctest: +SKIP """ _cmd = 'linrecon' input_spec=LinReconInputSpec output_spec=LinReconOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['recon_data'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.scheme_file) return name + '_recondata.Bdouble' class MESDInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, position=1, desc='voxel-order data filename') inverter = traits.Enum('SPIKE', 'PAS', argstr='-filter %s', position=2, mandatory=True, desc=('The inversion index specifies the type of inversion to perform on the data.' 'The currently available choices are:' 'Inverter name | Inverter parameters' '---------------|------------------' 'SPIKE | bd (b-value x diffusivity along the fibre.)' 'PAS | r')) inverter_param = traits.Float(argstr='%f', units='NA', position=3, mandatory=True, desc=('Parameter associated with the inverter. Cf. inverter description for' 'more information.')) fastmesd = traits.Bool(argstr='-fastmesd', requires=['mepointset'], desc=('Turns off numerical integration checks and fixes the integration point set size at that of' 'the index specified by -basepointset..')) mepointset = traits.Int(argstr='-mepointset %d', units='NA', desc=('Use a set of directions other than those in the scheme file for the deconvolution kernel.' 'The number refers to the number of directions on the unit sphere. For example, ' '"-mepointset 54" uses the directions in "camino/PointSets/Elec054.txt".')) scheme_file = File(exists=True, argstr='-schemefile %s', mandatory=True, desc='Specifies the scheme file for the diffusion MRI data') bgmask = File(exists=True, argstr='-bgmask %s', desc='background mask') inputdatatype = traits.Enum('float', 'char', 'short', 'int', 'long', 'double', argstr='-inputdatatype %s', desc=('Specifies the data type of the input file: "char", "short", "int", "long",' '"float" or "double". The input file must have BIG-ENDIAN ordering.' 'By default, the input type is "float".')) class MESDOutputSpec(TraitedSpec): mesd_data = File(exists=True, desc='MESD data') class MESD(StdOutCommandLine): """ MESD is a general program for maximum entropy spherical deconvolution. It also runs PASMRI, which is a special case of spherical deconvolution. The input data must be in voxel order. The format of the output in each voxel is: { exitcode, ln(A^star(0)), lambda_0, lambda_1, ..., lambda_N } The exitcode contains the results of three tests. The first test thresholds the maximum relative error between the numerical integrals computed at con- vergence and those computed using a larger test point set; if the error is greater than a threshold the exitcode is increased from zero to one as a warning; if it is greater than a larger threshold the exitcode is increased to two to suggest failure. The second test thresholds the predicted error in numerical integrals computed using the test point set; if the predicted error is greater than a threshold the exitcode is increased by 10. The third test thresholds the RMS error between the measurements and their predictions from the fitted deconvolution; if the errors are greater than a threshold, the exit code is increased by 100. An exitcode of 112 means that all three tests were failed and the result is likely to be unreliable. If all is well the exitcode is zero. Results are often still reliable even if one or two of the tests are failed. Other possible exitcodes are: - 5 - The optimization failed to converge - -1 - Background - -100 - Something wrong in the MRI data, e.g. negative or zero measurements, so that the optimization could not run. The standard MESD implementation is computationally demanding, particularly as the number of measurements increases (computation is approximately O(N^2), where N is the number of measurements). There are two ways to obtain significant computational speed-up: i) Turn off error checks and use a small point set for computing numerical integrals in the algorithm by adding the flag -fastmesd. Sakaie CDMRI 2008 shows that using the smallest point set (-basepointset 0) with no error checks usually has only a minor effect on the output of the algorithm, but provides a major reduction in computation time. You can increase the point set size using -basepointset with an argument higher than 0, which may produce better results in some voxels, but will increase computation time, which approximately doubles every time the point set index increases by 1. ii) Reduce the complexity of the maximum entropy encoding using -mepointset . By default = N, the number of measurements, and is the number of parameters in the max. ent. representation of the output function, ie the number of lambda parameters, as described in Jansons and Alexander Inverse Problems 2003. However, we can represent the function using less components and here specifies the number of lambda parameters. To obtain speed-up, set < N; complexity become O(^2) rather than O(N^2). Note that must be chosen so that the camino/PointSets directory contains a point set with that number of elements. When -mepointset decreases, the numerical integration checks make less and less of a difference and smaller point sets for numerical integration (see -basepointset) become adequate. So when is low -fastmesd is worth using to get even more speed-up. The choice of is a parameter of the technique. Too low and you lose angular resoloution; too high and you see no computational benefit and may even suffer from overfitting. Empirically, we have found that =16 often gives good results and good speed up, but it is worth trying a few values a comparing performance. The reduced encoding is described in the following ISMRM abstract: Sweet and Alexander "Reduced Encoding Persistent Angular Structure" 572 ISMRM 2010. Example --------- Run MESD on every voxel of the data file SubjectA.Bfloat using the PASMRI kernel. >>> import nipype.interfaces.camino as cam >>> mesd = cam.MESD() >>> mesd.inputs.in_file = 'SubjectA.Bfloat' >>> mesd.inputs.scheme_file = 'A.scheme' >>> mesd.inputs.inverter = 'PAS' >>> mesd.inputs.inverter_param = 1.4 >>> mesd.run() # doctest: +SKIP """ _cmd = 'mesd' input_spec=MESDInputSpec output_spec=MESDOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['mesd_data'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.scheme_file) return name + '_MESD.Bdouble' class SFPeaksInputSpec(StdOutCommandLineInputSpec): in_file = File(exists=True, argstr='-inputfile %s', mandatory=True, desc='Voxel-order data of spherical functions') inputmodel = traits.Enum('sh', 'maxent', 'rbf', argstr='-inputmodel %s', mandatory=True, desc=('Type of functions input via in_file. Currently supported options are: ' ' sh - Spherical harmonic series. Specify the maximum order of the SH series ' ' with the "order" attribute if different from the default of 4. ' ' maxent - Maximum entropy representations output by MESD. The reconstruction ' ' directions input to MESD must be specified. By default this is the ' ' same set of gradient directions (excluding zero gradients) in the ' ' scheme file, so specify the "schemefile" attribute unless the ' ' "mepointset" attribute was set in MESD. ' ' rbf - Sums of radial basis functions. Specify the pointset with the attribute ' ' "rbfpointset" if different from the default. See QBallMX.')) order = traits.Int(argstr='-order %d', units='NA', desc='Specific to sh. Maximum order of the spherical harmonic series.') scheme_file = File(exists=True, argstr='%s', desc='Specific to maxent. Specifies the scheme file.') rbfpointset = traits.Int(argstr='-rbfpointset %d', units='NA', desc=('Specific to rbf. Sets the number of radial basis functions to use. ' 'The value specified must be present in the Pointsets directory. ' 'The default value is 246.')) mepointset = traits.Int(argstr='-mepointset %d', units='NA', desc=('Use a set of directions other than those in the scheme file for the deconvolution ' 'kernel. The number refers to the number of directions on the unit sphere. ' 'For example, "mepointset = 54" uses the directions in "camino/PointSets/Elec054.txt" ' 'Use this option only if you told MESD to use a custom set of directions with the same ' 'option. Otherwise, specify the scheme file with the "schemefile" attribute.')) numpds = traits.Int(argstr='-numpds %d', units='NA', desc='The largest number of peak directions to output in each voxel.') noconsistencycheck = traits.Bool(argstr='-noconsistencycheck', desc='Turns off the consistency check. The output shows all consistencies as true.') searchradius = traits.Float(argstr='-searchradius %f', units='NA', desc='The search radius in the peak finding algorithm. The default is 0.4 (cf. "density")') density = traits.Int(argstr='-density %d', units='NA', desc=('The number of randomly rotated icosahedra to use in constructing the set of points for ' 'random sampling in the peak finding algorithm. Default is 1000, which works well for very ' 'spiky maxent functions. For other types of function, it is reasonable to set the density ' 'much lower and increase the search radius slightly, which speeds up the computation.')) pointset = traits.Int(argstr='-pointset %d', units='NA', desc=('To sample using an evenly distributed set of points instead. The integer can be ' '0, 1, ..., 7. Index 0 gives 1082 points, 1 gives 1922, 2 gives 3002, 3 gives 4322, ' '4 gives 5882, 5 gives 8672, 6 gives 12002, 7 gives 15872.')) pdthresh = traits.Float(argstr='-pdthresh %f', units='NA', desc=('Base threshold on the actual peak direction strength divided by the mean of the ' 'function. The default is 1.0 (the peak must be equal or greater than the mean).')) stdsfrommean = traits.Float(argstr='-stdsfrommean %f', units='NA', desc=('This is the number of standard deviations of the function to be added to the ' '"pdthresh" attribute in the peak directions pruning.')) class SFPeaksOutputSpec(TraitedSpec): peaks = File(exists=True, desc='Peaks of the spherical functions.') class SFPeaks(StdOutCommandLine): """ Finds the peaks of spherical functions. This utility reads coefficients of the spherical functions and outputs a list of peak directions of the function. It computes the value of the function at each of a set of sample points. Then it finds local maxima by finding all points at which the function is larger than for any other point within a fixed search radius (the default is 0.4). The utility then uses Powell's algorithm to optimize the position of each local maximum. Finally the utility removes duplicates and tiny peaks with function value smaller than some threshold, which is the mean of the function plus some number of standard deviations. By default the program checks for con- sistency with a second set of starting points, but skips the optimization step. To speed up execution, you can turn off the con- sistency check by setting the noconsistencycheck flag to True. By default, the utility constructs a set of sample points by randomly rotating a unit icosahedron repeatedly (the default is 1000 times, which produces a set of 6000 points) and concatenating the lists of vertices. The 'pointset = ' attribute can tell the utility to use an evenly distributed set of points (index 0 gives 1082 points, 1 gives 1922, 2 gives 4322, 3 gives 8672, 4 gives 15872, 5 gives 32762, 6 gives 72032), which is quicker, because you can get away with fewer points. We estimate that you can use a factor of 2.5 less evenly distributed points than randomly distributed points and still expect similar performance levels. The output for each voxel is: - exitcode (inherited from the input data). - ln(A(0)) - number of peaks found. - flag for consistency with a repeated run (number of directions is the same and the directions are the same to within a threshold.) - mean(f). - std(f). - direction 1 (x, y, z, f, H00, H01, H10, H11). - direction 2 (x, y, z, f, H00, H01, H10, H11). - direction 3 (x, y, z, f, H00, H01, H10, H11). H is the Hessian of f at the peak. It is the matrix: :: [d^2f/ds^2 d^2f/dsdt] [d^2f/dtds d^2f/dt^2] = [H00 H01] [H10 H11] where s and t are orthogonal coordinates local to the peak. By default the maximum number of peak directions output in each voxel is three. If less than three directions are found, zeros are output for later directions. The peaks are ordered by the value of the function at the peak. If more than the maximum number of directions are found only the strongest ones are output. The maximum number can be changed setting the 'numpds' attribute. The utility can read various kinds of spherical function, but must be told what kind of function is input using the 'inputmodel' attribute. The description of the 'inputmodel' attribute lists additional information required by SFPeaks for each input model. Example --------- First run QBallMX and create a linear transform matrix using Spherical Harmonics (sh). >>> import nipype.interfaces.camino as cam >>> sf_peaks = cam.SFPeaks() >>> sf_peaks.inputs.in_file = 'A_recon_params.Bdouble' >>> sf_peaks.inputs.inputmodel = 'sh' >>> sf_peaks.inputs.order = 4 >>> sf_peaks.inputs.density = 100 >>> sf_peaks.inputs.searchradius = 1.0 >>> sf_peaks.run() # doctest: +SKIP """ _cmd = 'sfpeaks' input_spec=SFPeaksInputSpec output_spec=SFPeaksOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['peaks'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_peaks.Bdouble' nipype-0.11.0/nipype/interfaces/camino/tests/000077500000000000000000000000001257611314500211415ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/camino/tests/__init__.py000066400000000000000000000001621257611314500232510ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_AnalyzeHeader.py000066400000000000000000000045401257611314500263210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import AnalyzeHeader def test_AnalyzeHeader_inputs(): input_map = dict(args=dict(argstr='%s', ), centre=dict(argstr='-centre %s', units='mm', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), datatype=dict(argstr='-datatype %s', mandatory=True, ), description=dict(argstr='-description %s', ), environ=dict(nohash=True, usedefault=True, ), greylevels=dict(argstr='-gl %s', units='NA', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), initfromheader=dict(argstr='-initfromheader %s', position=3, ), intelbyteorder=dict(argstr='-intelbyteorder', ), networkbyteorder=dict(argstr='-networkbyteorder', ), nimages=dict(argstr='-nimages %d', units='NA', ), offset=dict(argstr='-offset %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), picoseed=dict(argstr='-picoseed %s', units='mm', ), printbigendian=dict(argstr='-printbigendian %s', position=3, ), printimagedims=dict(argstr='-printimagedims %s', position=3, ), printintelbyteorder=dict(argstr='-printintelbyteorder %s', position=3, ), printprogargs=dict(argstr='-printprogargs %s', position=3, ), readheader=dict(argstr='-readheader %s', position=3, ), scaleinter=dict(argstr='-scaleinter %d', units='NA', ), scaleslope=dict(argstr='-scaleslope %d', units='NA', ), scheme_file=dict(argstr='%s', position=2, ), terminal_output=dict(nohash=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = AnalyzeHeader.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AnalyzeHeader_outputs(): output_map = dict(header=dict(), ) outputs = AnalyzeHeader.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ComputeEigensystem.py000066400000000000000000000025171257611314500274400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import ComputeEigensystem def test_ComputeEigensystem_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', usedefault=True, ), inputmodel=dict(argstr='-inputmodel %s', ), maxcomponents=dict(argstr='-maxcomponents %d', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputdatatype=dict(argstr='-outputdatatype %s', usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ComputeEigensystem.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeEigensystem_outputs(): output_map = dict(eigen=dict(), ) outputs = ComputeEigensystem.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ComputeFractionalAnisotropy.py000066400000000000000000000025161257611314500313150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import ComputeFractionalAnisotropy def test_ComputeFractionalAnisotropy_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputdatatype=dict(argstr='-outputdatatype %s', ), scheme_file=dict(argstr='%s', position=2, ), terminal_output=dict(nohash=True, ), ) inputs = ComputeFractionalAnisotropy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeFractionalAnisotropy_outputs(): output_map = dict(fa=dict(), ) outputs = ComputeFractionalAnisotropy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ComputeMeanDiffusivity.py000066400000000000000000000024651257611314500302540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import ComputeMeanDiffusivity def test_ComputeMeanDiffusivity_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputdatatype=dict(argstr='-outputdatatype %s', ), scheme_file=dict(argstr='%s', position=2, ), terminal_output=dict(nohash=True, ), ) inputs = ComputeMeanDiffusivity.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeMeanDiffusivity_outputs(): output_map = dict(md=dict(), ) outputs = ComputeMeanDiffusivity.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ComputeTensorTrace.py000066400000000000000000000024441257611314500273740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import ComputeTensorTrace def test_ComputeTensorTrace_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputdatatype=dict(argstr='-outputdatatype %s', ), scheme_file=dict(argstr='%s', position=2, ), terminal_output=dict(nohash=True, ), ) inputs = ComputeTensorTrace.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeTensorTrace_outputs(): output_map = dict(trace=dict(), ) outputs = ComputeTensorTrace.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_Conmat.py000066400000000000000000000027111257611314500250240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.connectivity import Conmat def test_Conmat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, ), output_root=dict(argstr='-outputroot %s', genfile=True, ), scalar_file=dict(argstr='-scalarfile %s', requires=['tract_stat'], ), target_file=dict(argstr='-targetfile %s', mandatory=True, ), targetname_file=dict(argstr='-targetnamefile %s', ), terminal_output=dict(nohash=True, ), tract_prop=dict(argstr='-tractstat %s', units='NA', xor=['tract_stat'], ), tract_stat=dict(argstr='-tractstat %s', requires=['scalar_file'], units='NA', xor=['tract_prop'], ), ) inputs = Conmat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Conmat_outputs(): output_map = dict(conmat_sc=dict(), conmat_ts=dict(), ) outputs = Conmat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_DT2NIfTI.py000066400000000000000000000022401257611314500250230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import DT2NIfTI def test_DT2NIfTI_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), header_file=dict(argstr='-header %s', mandatory=True, position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, position=1, ), output_root=dict(argstr='-outputroot %s', genfile=True, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = DT2NIfTI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DT2NIfTI_outputs(): output_map = dict(dt=dict(), exitcode=dict(), lns0=dict(), ) outputs = DT2NIfTI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_DTIFit.py000066400000000000000000000023041257611314500246640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import DTIFit def test_DTIFit_inputs(): input_map = dict(args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), non_linear=dict(argstr='-nonlinear', position=3, ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), scheme_file=dict(argstr='%s', mandatory=True, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = DTIFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTIFit_outputs(): output_map = dict(tensor_fitted=dict(), ) outputs = DTIFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_DTLUTGen.py000066400000000000000000000031241257611314500251300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import DTLUTGen def test_DTLUTGen_inputs(): input_map = dict(acg=dict(argstr='-acg', ), args=dict(argstr='%s', ), bingham=dict(argstr='-bingham', ), environ=dict(nohash=True, usedefault=True, ), frange=dict(argstr='-frange %s', position=1, units='NA', ), ignore_exception=dict(nohash=True, usedefault=True, ), inversion=dict(argstr='-inversion %d', units='NA', ), lrange=dict(argstr='-lrange %s', position=1, units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), samples=dict(argstr='-samples %d', units='NA', ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, position=2, ), snr=dict(argstr='-snr %f', units='NA', ), step=dict(argstr='-step %f', units='NA', ), terminal_output=dict(nohash=True, ), trace=dict(argstr='-trace %G', units='NA', ), watson=dict(argstr='-watson', ), ) inputs = DTLUTGen.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTLUTGen_outputs(): output_map = dict(dtLUT=dict(), ) outputs = DTLUTGen.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_DTMetric.py000066400000000000000000000024341257611314500252600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import DTMetric def test_DTMetric_inputs(): input_map = dict(args=dict(argstr='%s', ), data_header=dict(argstr='-header %s', ), eigen_data=dict(argstr='-inputfile %s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputdatatype=dict(argstr='-inputdatatype %s', usedefault=True, ), metric=dict(argstr='-stat %s', mandatory=True, ), outputdatatype=dict(argstr='-outputdatatype %s', usedefault=True, ), outputfile=dict(argstr='-outputfile %s', genfile=True, ), terminal_output=dict(nohash=True, ), ) inputs = DTMetric.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTMetric_outputs(): output_map = dict(metric_stats=dict(), ) outputs = DTMetric.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_FSL2Scheme.py000066400000000000000000000030321257611314500254330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import FSL2Scheme def test_FSL2Scheme_inputs(): input_map = dict(args=dict(argstr='%s', ), bscale=dict(argstr='-bscale %d', units='NA', ), bval_file=dict(argstr='-bvalfile %s', mandatory=True, position=2, ), bvec_file=dict(argstr='-bvecfile %s', mandatory=True, position=1, ), diffusiontime=dict(argstr='-diffusiontime %f', units='NA', ), environ=dict(nohash=True, usedefault=True, ), flipx=dict(argstr='-flipx', ), flipy=dict(argstr='-flipy', ), flipz=dict(argstr='-flipz', ), ignore_exception=dict(nohash=True, usedefault=True, ), interleave=dict(argstr='-interleave', ), numscans=dict(argstr='-numscans %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), terminal_output=dict(nohash=True, ), usegradmod=dict(argstr='-usegradmod', ), ) inputs = FSL2Scheme.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FSL2Scheme_outputs(): output_map = dict(scheme=dict(), ) outputs = FSL2Scheme.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_Image2Voxel.py000066400000000000000000000022121257611314500257210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import Image2Voxel def test_Image2Voxel_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-4dimage %s', mandatory=True, position=1, ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), out_type=dict(argstr='-outputdatatype %s', position=2, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = Image2Voxel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Image2Voxel_outputs(): output_map = dict(voxel_order=dict(), ) outputs = Image2Voxel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ImageStats.py000066400000000000000000000022731257611314500256470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.utils import ImageStats def test_ImageStats_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='-images %s', mandatory=True, position=-1, ), out_type=dict(argstr='-outputdatatype %s', usedefault=True, ), output_root=dict(argstr='-outputroot %s', mandatory=True, ), stat=dict(argstr='-stat %s', mandatory=True, units='NA', ), terminal_output=dict(nohash=True, ), ) inputs = ImageStats.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageStats_outputs(): output_map = dict(out_file=dict(), ) outputs = ImageStats.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_LinRecon.py000066400000000000000000000024501257611314500253140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.odf import LinRecon def test_LinRecon_inputs(): input_map = dict(args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), log=dict(argstr='-log', ), normalize=dict(argstr='-normalize', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), qball_mat=dict(argstr='%s', mandatory=True, position=3, ), scheme_file=dict(argstr='%s', mandatory=True, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = LinRecon.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LinRecon_outputs(): output_map = dict(recon_data=dict(), ) outputs = LinRecon.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_MESD.py000066400000000000000000000027671257611314500243460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.odf import MESD def test_MESD_inputs(): input_map = dict(args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), environ=dict(nohash=True, usedefault=True, ), fastmesd=dict(argstr='-fastmesd', requires=['mepointset'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inverter=dict(argstr='-filter %s', mandatory=True, position=2, ), inverter_param=dict(argstr='%f', mandatory=True, position=3, units='NA', ), mepointset=dict(argstr='-mepointset %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), terminal_output=dict(nohash=True, ), ) inputs = MESD.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MESD_outputs(): output_map = dict(mesd_data=dict(), ) outputs = MESD.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ModelFit.py000066400000000000000000000033361257611314500253120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import ModelFit def test_ModelFit_inputs(): input_map = dict(args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), bgthresh=dict(argstr='-bgthresh %G', ), cfthresh=dict(argstr='-csfthresh %G', ), environ=dict(nohash=True, usedefault=True, ), fixedbvalue=dict(argstr='-fixedbvalue %s', ), fixedmodq=dict(argstr='-fixedmod %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, ), inputdatatype=dict(argstr='-inputdatatype %s', ), model=dict(argstr='-model %s', mandatory=True, ), noisemap=dict(argstr='-noisemap %s', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outlier=dict(argstr='-outliermap %s', ), outputfile=dict(argstr='-outputfile %s', ), residualmap=dict(argstr='-residualmap %s', ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), sigma=dict(argstr='-sigma %G', ), tau=dict(argstr='-tau %G', ), terminal_output=dict(nohash=True, ), ) inputs = ModelFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ModelFit_outputs(): output_map = dict(fitted_data=dict(), ) outputs = ModelFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_NIfTIDT2Camino.py000066400000000000000000000025451257611314500261620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import NIfTIDT2Camino def test_NIfTIDT2Camino_inputs(): input_map = dict(args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, position=1, ), lns0_file=dict(argstr='-lns0 %s', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), s0_file=dict(argstr='-s0 %s', ), scaleinter=dict(argstr='-scaleinter %s', ), scaleslope=dict(argstr='-scaleslope %s', ), terminal_output=dict(nohash=True, ), uppertriangular=dict(argstr='-uppertriangular %s', ), ) inputs = NIfTIDT2Camino.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NIfTIDT2Camino_outputs(): output_map = dict(out_file=dict(), ) outputs = NIfTIDT2Camino.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_PicoPDFs.py000066400000000000000000000026431257611314500252160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import PicoPDFs def test_PicoPDFs_inputs(): input_map = dict(args=dict(argstr='%s', ), directmap=dict(argstr='-directmap', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=1, ), inputmodel=dict(argstr='-inputmodel %s', position=2, usedefault=True, ), luts=dict(argstr='-luts %s', mandatory=True, ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), pdf=dict(argstr='-pdf %s', position=4, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = PicoPDFs.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PicoPDFs_outputs(): output_map = dict(pdfs=dict(), ) outputs = PicoPDFs.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_ProcStreamlines.py000066400000000000000000000060611257611314500267170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import ProcStreamlines def test_ProcStreamlines_inputs(): input_map = dict(allowmultitargets=dict(argstr='-allowmultitargets', ), args=dict(argstr='%s', ), datadims=dict(argstr='-datadims %s', units='voxels', ), directional=dict(argstr='-directional %s', units='NA', ), discardloops=dict(argstr='-discardloops', ), endpointfile=dict(argstr='-endpointfile %s', ), environ=dict(nohash=True, usedefault=True, ), exclusionfile=dict(argstr='-exclusionfile %s', ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, position=1, ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), iterations=dict(argstr='-iterations %d', units='NA', ), maxtractlength=dict(argstr='-maxtractlength %d', units='mm', ), maxtractpoints=dict(argstr='-maxtractpoints %d', units='NA', ), mintractlength=dict(argstr='-mintractlength %d', units='mm', ), mintractpoints=dict(argstr='-mintractpoints %d', units='NA', ), noresample=dict(argstr='-noresample', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputacm=dict(argstr='-outputacm', requires=['outputroot', 'seedfile'], ), outputcbs=dict(argstr='-outputcbs', requires=['outputroot', 'targetfile', 'seedfile'], ), outputcp=dict(argstr='-outputcp', requires=['outputroot', 'seedfile'], ), outputroot=dict(argstr='-outputroot %s', ), outputsc=dict(argstr='-outputsc', requires=['outputroot', 'seedfile'], ), outputtracts=dict(argstr='-outputtracts', ), regionindex=dict(argstr='-regionindex %d', units='mm', ), resamplestepsize=dict(argstr='-resamplestepsize %d', units='NA', ), seedfile=dict(argstr='-seedfile %s', ), seedpointmm=dict(argstr='-seedpointmm %s', units='mm', ), seedpointvox=dict(argstr='-seedpointvox %s', units='voxels', ), targetfile=dict(argstr='-targetfile %s', ), terminal_output=dict(nohash=True, ), truncateinexclusion=dict(argstr='-truncateinexclusion', ), truncateloops=dict(argstr='-truncateloops', ), voxeldims=dict(argstr='-voxeldims %s', units='mm', ), waypointfile=dict(argstr='-waypointfile %s', ), ) inputs = ProcStreamlines.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProcStreamlines_outputs(): output_map = dict(outputroot_files=dict(), proc=dict(), ) outputs = ProcStreamlines.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_QBallMX.py000066400000000000000000000025321257611314500250440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.odf import QBallMX def test_QBallMX_inputs(): input_map = dict(args=dict(argstr='%s', ), basistype=dict(argstr='-basistype %s', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), order=dict(argstr='-order %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), rbfpointset=dict(argstr='-rbfpointset %d', units='NA', ), rbfsigma=dict(argstr='-rbfsigma %f', units='NA', ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), smoothingsigma=dict(argstr='-smoothingsigma %f', units='NA', ), terminal_output=dict(nohash=True, ), ) inputs = QBallMX.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_QBallMX_outputs(): output_map = dict(qmat=dict(), ) outputs = QBallMX.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_SFLUTGen.py000066400000000000000000000027571257611314500251440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.calib import SFLUTGen def test_SFLUTGen_inputs(): input_map = dict(args=dict(argstr='%s', ), binincsize=dict(argstr='-binincsize %d', units='NA', ), directmap=dict(argstr='-directmap', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, ), info_file=dict(argstr='-infofile %s', mandatory=True, ), minvectsperbin=dict(argstr='-minvectsperbin %d', units='NA', ), order=dict(argstr='-order %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), outputstem=dict(argstr='-outputstem %s', usedefault=True, ), pdf=dict(argstr='-pdf %s', usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = SFLUTGen.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SFLUTGen_outputs(): output_map = dict(lut_one_fibre=dict(), lut_two_fibres=dict(), ) outputs = SFLUTGen.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_SFPICOCalibData.py000066400000000000000000000036541257611314500263220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.calib import SFPICOCalibData def test_SFPICOCalibData_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), info_file=dict(argstr='-infooutputfile %s', genfile=True, hash_files=False, mandatory=True, ), onedtfarange=dict(argstr='-onedtfarange %s', units='NA', ), onedtfastep=dict(argstr='-onedtfastep %f', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), seed=dict(argstr='-seed %f', units='NA', ), snr=dict(argstr='-snr %f', units='NA', ), terminal_output=dict(nohash=True, ), trace=dict(argstr='-trace %f', units='NA', ), twodtanglerange=dict(argstr='-twodtanglerange %s', units='NA', ), twodtanglestep=dict(argstr='-twodtanglestep %f', units='NA', ), twodtfarange=dict(argstr='-twodtfarange %s', units='NA', ), twodtfastep=dict(argstr='-twodtfastep %f', units='NA', ), twodtmixmax=dict(argstr='-twodtmixmax %f', units='NA', ), twodtmixstep=dict(argstr='-twodtmixstep %f', units='NA', ), ) inputs = SFPICOCalibData.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SFPICOCalibData_outputs(): output_map = dict(PICOCalib=dict(), calib_info=dict(), ) outputs = SFPICOCalibData.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_SFPeaks.py000066400000000000000000000034031257611314500250760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.odf import SFPeaks def test_SFPeaks_inputs(): input_map = dict(args=dict(argstr='%s', ), density=dict(argstr='-density %d', units='NA', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', mandatory=True, ), inputmodel=dict(argstr='-inputmodel %s', mandatory=True, ), mepointset=dict(argstr='-mepointset %d', units='NA', ), noconsistencycheck=dict(argstr='-noconsistencycheck', ), numpds=dict(argstr='-numpds %d', units='NA', ), order=dict(argstr='-order %d', units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), pdthresh=dict(argstr='-pdthresh %f', units='NA', ), pointset=dict(argstr='-pointset %d', units='NA', ), rbfpointset=dict(argstr='-rbfpointset %d', units='NA', ), scheme_file=dict(argstr='%s', ), searchradius=dict(argstr='-searchradius %f', units='NA', ), stdsfrommean=dict(argstr='-stdsfrommean %f', units='NA', ), terminal_output=dict(nohash=True, ), ) inputs = SFPeaks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SFPeaks_outputs(): output_map = dict(peaks=dict(), ) outputs = SFPeaks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_Shredder.py000066400000000000000000000023451257611314500253460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import Shredder def test_Shredder_inputs(): input_map = dict(args=dict(argstr='%s', ), chunksize=dict(argstr='%d', position=2, units='NA', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=-2, ), offset=dict(argstr='%d', position=1, units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), space=dict(argstr='%d', position=3, units='NA', ), terminal_output=dict(nohash=True, ), ) inputs = Shredder.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Shredder_outputs(): output_map = dict(shredded=dict(), ) outputs = Shredder.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_Track.py000066400000000000000000000041351257611314500246510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import Track def test_Track_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = Track.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Track_outputs(): output_map = dict(tracked=dict(), ) outputs = Track.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackBallStick.py000066400000000000000000000042121257611314500264360ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackBallStick def test_TrackBallStick_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackBallStick.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackBallStick_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackBallStick.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackBayesDirac.py000066400000000000000000000052101257611314500265730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackBayesDirac def test_TrackBayesDirac_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvepriorg=dict(argstr='-curvepriorg %G', ), curvepriork=dict(argstr='-curvepriork %G', ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), datamodel=dict(argstr='-datamodel %s', ), environ=dict(nohash=True, usedefault=True, ), extpriordatatype=dict(argstr='-extpriordatatype %s', ), extpriorfile=dict(argstr='-extpriorfile %s', ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), iterations=dict(argstr='-iterations %d', units='NA', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), pdf=dict(argstr='-pdf %s', ), pointset=dict(argstr='-pointset %s', ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackBayesDirac.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackBayesDirac_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackBayesDirac.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackBedpostxDeter.py000066400000000000000000000044601257611314500273470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackBedpostxDeter def test_TrackBedpostxDeter_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), bedpostxdir=dict(argstr='-bedpostxdir %s', mandatory=True, ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), min_vol_frac=dict(argstr='-bedpostxminf %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackBedpostxDeter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackBedpostxDeter_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackBedpostxDeter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackBedpostxProba.py000066400000000000000000000045641257611314500273540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackBedpostxProba def test_TrackBedpostxProba_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), bedpostxdir=dict(argstr='-bedpostxdir %s', mandatory=True, ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), iterations=dict(argstr='-iterations %d', units='NA', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), min_vol_frac=dict(argstr='-bedpostxminf %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackBedpostxProba.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackBedpostxProba_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackBedpostxProba.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackBootstrap.py000066400000000000000000000046761257611314500265610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackBootstrap def test_TrackBootstrap_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), bgmask=dict(argstr='-bgmask %s', ), bsdatafiles=dict(argstr='-bsdatafile %s', mandatory=True, ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), inversion=dict(argstr='-inversion %s', ), ipthresh=dict(argstr='-ipthresh %f', ), iterations=dict(argstr='-iterations %d', units='NA', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), scheme_file=dict(argstr='-schemefile %s', mandatory=True, ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackBootstrap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackBootstrap_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackBootstrap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackDT.py000066400000000000000000000041471257611314500251040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackDT def test_TrackDT_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackDT.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackDT_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackDT.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TrackPICo.py000066400000000000000000000043331257611314500253640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.dti import TrackPICo def test_TrackPICo_inputs(): input_map = dict(anisfile=dict(argstr='-anisfile %s', ), anisthresh=dict(argstr='-anisthresh %f', ), args=dict(argstr='%s', ), curveinterval=dict(argstr='-curveinterval %f', requires=['curvethresh'], ), curvethresh=dict(argstr='-curvethresh %f', ), data_dims=dict(argstr='-datadims %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), gzip=dict(argstr='-gzip', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-inputfile %s', position=1, ), inputdatatype=dict(argstr='-inputdatatype %s', ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolator=dict(argstr='-interpolator %s', ), ipthresh=dict(argstr='-ipthresh %f', ), iterations=dict(argstr='-iterations %d', units='NA', ), maxcomponents=dict(argstr='-maxcomponents %d', units='NA', ), numpds=dict(argstr='-numpds %d', units='NA', ), out_file=dict(argstr='-outputfile %s', genfile=True, position=-1, ), output_root=dict(argstr='-outputroot %s', position=-1, ), outputtracts=dict(argstr='-outputtracts %s', ), pdf=dict(argstr='-pdf %s', ), seed_file=dict(argstr='-seedfile %s', position=2, ), stepsize=dict(argstr='-stepsize %f', requires=['tracker'], ), terminal_output=dict(nohash=True, ), tracker=dict(argstr='-tracker %s', usedefault=True, ), voxel_dims=dict(argstr='-voxeldims %s', units='mm', ), ) inputs = TrackPICo.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackPICo_outputs(): output_map = dict(tracked=dict(), ) outputs = TrackPICo.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_TractShredder.py000066400000000000000000000023761257611314500263500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import TractShredder def test_TractShredder_inputs(): input_map = dict(args=dict(argstr='%s', ), bunchsize=dict(argstr='%d', position=2, units='NA', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='< %s', mandatory=True, position=-2, ), offset=dict(argstr='%d', position=1, units='NA', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), space=dict(argstr='%d', position=3, units='NA', ), terminal_output=dict(nohash=True, ), ) inputs = TractShredder.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TractShredder_outputs(): output_map = dict(shredded=dict(), ) outputs = TractShredder.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/tests/test_auto_VtkStreamlines.py000066400000000000000000000031001257611314500265470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino.convert import VtkStreamlines def test_VtkStreamlines_inputs(): input_map = dict(args=dict(argstr='%s', ), colourorient=dict(argstr='-colourorient', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr=' < %s', mandatory=True, position=-2, ), inputmodel=dict(argstr='-inputmodel %s', usedefault=True, ), interpolate=dict(argstr='-interpolate', ), interpolatescalars=dict(argstr='-interpolatescalars', ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), scalar_file=dict(argstr='-scalarfile %s', position=3, ), seed_file=dict(argstr='-seedfile %s', position=1, ), target_file=dict(argstr='-targetfile %s', position=2, ), terminal_output=dict(nohash=True, ), voxeldims=dict(argstr='-voxeldims %s', position=4, units='mm', ), ) inputs = VtkStreamlines.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VtkStreamlines_outputs(): output_map = dict(vtk=dict(), ) outputs = VtkStreamlines.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino/utils.py000066400000000000000000000052771257611314500215240ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (traits, TraitedSpec, File, CommandLine, CommandLineInputSpec, isdefined, InputMultiPath) from nipype.utils.filemanip import split_filename import os class ImageStatsInputSpec(CommandLineInputSpec): in_files = InputMultiPath(File(exists=True), argstr='-images %s', mandatory=True, position=-1, desc=('List of images to process. They must ' 'be in the same space and have the same ' 'dimensions.')) stat = traits.Enum("min", "max", "mean", "median", "sum", "std", "var", argstr='-stat %s', units='NA', mandatory=True, desc="The statistic to compute.") out_type = traits.Enum("float", "char", "short", "int", "long", "double", argstr='-outputdatatype %s', usedefault=True, desc=('A Camino data type string, default is "float". ' 'Type must be signed.')) output_root = File(argstr='-outputroot %s', mandatory=True, desc=('Filename root prepended onto the names of the output ' ' files. The extension will be determined from the input.')) class ImageStatsOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Path of the file computed with the statistic chosen') class ImageStats(CommandLine): """ This program computes voxelwise statistics on a series of 3D images. The images must be in the same space; the operation is performed voxelwise and one output is produced per voxel. Examples -------- >>> import nipype.interfaces.camino as cam >>> imstats = cam.ImageStats() >>> imstats.inputs.in_files = ['im1.nii','im2.nii','im3.nii'] >>> imstats.inputs.stat = 'max' >>> imstats.run() # doctest: +SKIP """ _cmd = 'imagestats' input_spec = ImageStatsInputSpec output_spec = ImageStatsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): output_root = self.inputs.output_root first_file = self.inputs.in_files[0] _, _ , ext = split_filename(first_file) return output_root + ext nipype-0.11.0/nipype/interfaces/camino2trackvis/000077500000000000000000000000001257611314500216305ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/camino2trackvis/__init__.py000066400000000000000000000003241257611314500237400ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Camino2Trackvis top level namespace """ from .convert import Camino2Trackvis, Trackvis2Camino nipype-0.11.0/nipype/interfaces/camino2trackvis/convert.py000066400000000000000000000115031257611314500236620ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import CommandLineInputSpec, CommandLine, traits, TraitedSpec, File from nipype.utils.filemanip import split_filename import os """Provides interfaces to various commands provided by Camino-Trackvis """ class Camino2TrackvisInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-i %s', mandatory=True, position=1, desc='The input .Bfloat (camino) file.') out_file = File(argstr='-o %s', genfile=True, position=2, desc='The filename to which to write the .trk (trackvis) file.') min_length = traits.Float(argstr='-l %d', position=3, units='mm', desc='The minimum length of tracts to output') data_dims = traits.List(traits.Int, argstr='-d %s', sep=',', mandatory=True, position=4, minlen=3, maxlen=3, desc='Three comma-separated integers giving the number of voxels along each dimension of the source scans.') voxel_dims = traits.List(traits.Float, argstr='-x %s', sep=',', mandatory=True, position=5, minlen=3, maxlen=3, desc='Three comma-separated numbers giving the size of each voxel in mm.') #Change to enum with all combinations? i.e. LAS, LPI, RAS, etc.. voxel_order = File(argstr='--voxel-order %s', mandatory=True, position=6, desc='Set the order in which various directions were stored.\ Specify with three letters consisting of one each \ from the pairs LR, AP, and SI. These stand for Left-Right, \ Anterior-Posterior, and Superior-Inferior. \ Whichever is specified in each position will \ be the direction of increasing order. \ Read coordinate system from a NIfTI file.') nifti_file = File(argstr='--nifti %s', exists=True, position=7, desc='Read coordinate system from a NIfTI file.') class Camino2TrackvisOutputSpec(TraitedSpec): trackvis = File(exists=True, desc='The filename to which to write the .trk (trackvis) file.') class Camino2Trackvis(CommandLine): """ Wraps camino_to_trackvis from Camino-Trackvis Convert files from camino .Bfloat format to trackvis .trk format. Example ------- >>> import nipype.interfaces.camino2trackvis as cam2trk >>> c2t = cam2trk.Camino2Trackvis() >>> c2t.inputs.in_file = 'data.Bfloat' >>> c2t.inputs.out_file = 'streamlines.trk' >>> c2t.inputs.min_length = 30 >>> c2t.inputs.data_dims = [128, 104, 64] >>> c2t.inputs.voxel_dims = [2.0, 2.0, 2.0] >>> c2t.inputs.voxel_order = 'LAS' >>> c2t.run() # doctest: +SKIP """ _cmd = 'camino_to_trackvis' input_spec=Camino2TrackvisInputSpec output_spec=Camino2TrackvisOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['trackvis'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '.trk' class Trackvis2CaminoInputSpec(CommandLineInputSpec): """ Wraps trackvis_to_camino from Camino-Trackvis Convert files from camino .Bfloat format to trackvis .trk format. Example ------- >>> import nipype.interfaces.camino2trackvis as cam2trk >>> t2c = cam2trk.Trackvis2Camino() >>> t2c.inputs.in_file = 'streamlines.trk' >>> t2c.inputs.out_file = 'streamlines.Bfloat' >>> t2c.run() # doctest: +SKIP """ in_file = File(exists=True, argstr='-i %s', mandatory=True, position=1, desc='The input .trk (trackvis) file.') out_file = File(argstr='-o %s', genfile=True, position=2, desc='The filename to which to write the .Bfloat (camino).') append_file = File(exists=True, argstr='-a %s', position=2, desc='A file to which the append the .Bfloat data. ') class Trackvis2CaminoOutputSpec(TraitedSpec): camino = File(exists=True, desc='The filename to which to write the .Bfloat (camino).') class Trackvis2Camino(CommandLine): _cmd = 'trackvis_to_camino' input_spec=Trackvis2CaminoInputSpec output_spec=Trackvis2CaminoOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['camino'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '.Bfloat' nipype-0.11.0/nipype/interfaces/camino2trackvis/tests/000077500000000000000000000000001257611314500227725ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/camino2trackvis/tests/test_auto_Camino2Trackvis.py000066400000000000000000000027401257611314500304350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino2trackvis.convert import Camino2Trackvis def test_Camino2Trackvis_inputs(): input_map = dict(args=dict(argstr='%s', ), data_dims=dict(argstr='-d %s', mandatory=True, position=4, sep=',', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=1, ), min_length=dict(argstr='-l %d', position=3, units='mm', ), nifti_file=dict(argstr='--nifti %s', position=7, ), out_file=dict(argstr='-o %s', genfile=True, position=2, ), terminal_output=dict(nohash=True, ), voxel_dims=dict(argstr='-x %s', mandatory=True, position=5, sep=',', ), voxel_order=dict(argstr='--voxel-order %s', mandatory=True, position=6, ), ) inputs = Camino2Trackvis.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Camino2Trackvis_outputs(): output_map = dict(trackvis=dict(), ) outputs = Camino2Trackvis.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/camino2trackvis/tests/test_auto_Trackvis2Camino.py000066400000000000000000000021751257611314500304370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.camino2trackvis.convert import Trackvis2Camino def test_Trackvis2Camino_inputs(): input_map = dict(append_file=dict(argstr='-a %s', position=2, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=1, ), out_file=dict(argstr='-o %s', genfile=True, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = Trackvis2Camino.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Trackvis2Camino_outputs(): output_map = dict(camino=dict(), ) outputs = Trackvis2Camino.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/000077500000000000000000000000001257611314500174675ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/cmtk/__init__.py000066400000000000000000000003431257611314500216000ustar00rootroot00000000000000from .cmtk import ROIGen, CreateMatrix, CreateNodes from .nx import NetworkXMetrics, AverageNetworks from .parcellation import Parcellate from .convert import CFFConverter, MergeCNetworks from .nbs import NetworkBasedStatistic nipype-0.11.0/nipype/interfaces/cmtk/cmtk.py000066400000000000000000001121121257611314500207750ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, InputMultiPath, Directory, OutputMultiPath, isdefined) from nipype.utils.filemanip import split_filename import pickle import scipy.io as sio import os, os.path as op import numpy as np import nibabel as nb import networkx as nx import sys from ... import logging iflogger = logging.getLogger('interface') def length(xyz, along=False): """ Euclidean length of track line Parameters ---------- xyz : array-like shape (N,3) array representing x,y,z of N points in a track along : bool, optional If True, return array giving cumulative length along track, otherwise (default) return scalar giving total length. Returns ------- L : scalar or array shape (N-1,) scalar in case of `along` == False, giving total length, array if `along` == True, giving cumulative lengths. Examples -------- >>> xyz = np.array([[1,1,1],[2,3,4],[0,0,0]]) >>> expected_lens = np.sqrt([1+2**2+3**2, 2**2+3**2+4**2]) >>> length(xyz) == expected_lens.sum() True >>> len_along = length(xyz, along=True) >>> np.allclose(len_along, expected_lens.cumsum()) True >>> length([]) 0 >>> length([[1, 2, 3]]) 0 >>> length([], along=True) array([0]) """ xyz = np.asarray(xyz) if xyz.shape[0] < 2: if along: return np.array([0]) return 0 dists = np.sqrt((np.diff(xyz, axis=0) ** 2).sum(axis=1)) if along: return np.cumsum(dists) return np.sum(dists) def get_rois_crossed(pointsmm, roiData, voxelSize): n_points = len(pointsmm) rois_crossed = [] for j in xrange(0, n_points): # store point x = int(pointsmm[j, 0] / float(voxelSize[0])) y = int(pointsmm[j, 1] / float(voxelSize[1])) z = int(pointsmm[j, 2] / float(voxelSize[2])) if not roiData[x, y, z] == 0: rois_crossed.append(roiData[x, y, z]) rois_crossed = dict.fromkeys(rois_crossed).keys() #Removed duplicates from the list return rois_crossed def get_connectivity_matrix(n_rois, list_of_roi_crossed_lists): connectivity_matrix = np.zeros((n_rois, n_rois), dtype=np.uint) for rois_crossed in list_of_roi_crossed_lists: for idx_i, roi_i in enumerate(rois_crossed): for idx_j, roi_j in enumerate(rois_crossed): if idx_i > idx_j: if not roi_i == roi_j: connectivity_matrix[roi_i - 1, roi_j - 1] += 1 connectivity_matrix = connectivity_matrix + connectivity_matrix.T return connectivity_matrix def create_allpoints_cmat(streamlines, roiData, voxelSize, n_rois): """ Create the intersection arrays for each fiber """ n_fib = len(streamlines) pc = -1 # Computation for each fiber final_fiber_ids = [] list_of_roi_crossed_lists = [] for i, fiber in enumerate(streamlines): pcN = int(round(float(100 * i) / n_fib)) if pcN > pc and pcN % 1 == 0: pc = pcN print '%4.0f%%' % (pc) rois_crossed = get_rois_crossed(fiber[0], roiData, voxelSize) if len(rois_crossed) > 0: list_of_roi_crossed_lists.append(list(rois_crossed)) final_fiber_ids.append(i) connectivity_matrix = get_connectivity_matrix(n_rois, list_of_roi_crossed_lists) dis = n_fib - len(final_fiber_ids) iflogger.info("Found %i (%f percent out of %i fibers) fibers that start or terminate in a voxel which is not labeled. (orphans)" % (dis, dis * 100.0 / n_fib, n_fib)) iflogger.info("Valid fibers: %i (%f percent)" % (n_fib - dis, 100 - dis * 100.0 / n_fib)) iflogger.info('Returning the intersecting point connectivity matrix') return connectivity_matrix, final_fiber_ids def create_endpoints_array(fib, voxelSize): """ Create the endpoints arrays for each fiber Parameters ---------- fib: the fibers data voxelSize: 3-tuple containing the voxel size of the ROI image Returns ------- (endpoints: matrix of size [#fibers, 2, 3] containing for each fiber the index of its first and last point in the voxelSize volume endpointsmm) : endpoints in milimeter coordinates """ # Init n = len(fib) endpoints = np.zeros((n, 2, 3)) endpointsmm = np.zeros((n, 2, 3)) pc = -1 # Computation for each fiber for i, fi in enumerate(fib): f = fi[0] # store startpoint endpoints[i, 0, :] = f[0, :] # store endpoint endpoints[i, 1, :] = f[-1, :] # store startpoint endpointsmm[i, 0, :] = f[0, :] # store endpoint endpointsmm[i, 1, :] = f[-1, :] # Translate from mm to index endpoints[i, 0, 0] = int(endpoints[i, 0, 0] / float(voxelSize[0])) endpoints[i, 0, 1] = int(endpoints[i, 0, 1] / float(voxelSize[1])) endpoints[i, 0, 2] = int(endpoints[i, 0, 2] / float(voxelSize[2])) endpoints[i, 1, 0] = int(endpoints[i, 1, 0] / float(voxelSize[0])) endpoints[i, 1, 1] = int(endpoints[i, 1, 1] / float(voxelSize[1])) endpoints[i, 1, 2] = int(endpoints[i, 1, 2] / float(voxelSize[2])) # Return the matrices iflogger.info('Returning the endpoint matrix') return (endpoints, endpointsmm) def cmat(track_file, roi_file, resolution_network_file, matrix_name, matrix_mat_name, endpoint_name, intersections=False): """ Create the connection matrix for each resolution using fibers and ROIs. """ stats = {} iflogger.info('Running cmat function') # Identify the endpoints of each fiber en_fname = op.abspath(endpoint_name + '_endpoints.npy') en_fnamemm = op.abspath(endpoint_name + '_endpointsmm.npy') iflogger.info('Reading Trackvis file {trk}'.format(trk=track_file)) fib, hdr = nb.trackvis.read(track_file, False) stats['orig_n_fib'] = len(fib) roi = nb.load(roi_file) roiData = roi.get_data() roiVoxelSize = roi.get_header().get_zooms() (endpoints, endpointsmm) = create_endpoints_array(fib, roiVoxelSize) # Output endpoint arrays iflogger.info('Saving endpoint array: {array}'.format(array=en_fname)) np.save(en_fname, endpoints) iflogger.info('Saving endpoint array in mm: {array}'.format(array=en_fnamemm)) np.save(en_fnamemm, endpointsmm) n = len(fib) iflogger.info('Number of fibers {num}'.format(num=n)) # Create empty fiber label array fiberlabels = np.zeros((n, 2)) final_fiberlabels = [] final_fibers_idx = [] # Add node information from specified parcellation scheme path, name, ext = split_filename(resolution_network_file) if ext == '.pck': gp = nx.read_gpickle(resolution_network_file) elif ext == '.graphml': gp = nx.read_graphml(resolution_network_file) nROIs = len(gp.nodes()) # add node information from parcellation if gp.node[gp.nodes()[0]].has_key('dn_position'): G = gp.copy() else: G = nx.Graph() for u, d in gp.nodes_iter(data=True): G.add_node(int(u), d) # compute a position for the node based on the mean position of the # ROI in voxel coordinates (segmentation volume ) xyz = tuple(np.mean(np.where(np.flipud(roiData) == int(d["dn_correspondence_id"])) , axis=1)) G.node[int(u)]['dn_position'] = tuple([xyz[0], xyz[2], -xyz[1]]) if intersections: iflogger.info("Filtering tractography from intersections") intersection_matrix, final_fiber_ids = create_allpoints_cmat(fib, roiData, roiVoxelSize, nROIs) finalfibers_fname = op.abspath(endpoint_name + '_intersections_streamline_final.trk') stats['intersections_n_fib'] = save_fibers(hdr, fib, finalfibers_fname, final_fiber_ids) intersection_matrix = np.matrix(intersection_matrix) I = G.copy() H = nx.from_numpy_matrix(np.matrix(intersection_matrix)) H = nx.relabel_nodes(H, lambda x: x + 1) #relabel nodes so they start at 1 I.add_weighted_edges_from(((u, v, d['weight']) for u, v, d in H.edges(data=True))) dis = 0 for i in xrange(endpoints.shape[0]): # ROI start => ROI end try: startROI = int(roiData[endpoints[i, 0, 0], endpoints[i, 0, 1], endpoints[i, 0, 2]]) endROI = int(roiData[endpoints[i, 1, 0], endpoints[i, 1, 1], endpoints[i, 1, 2]]) except IndexError: iflogger.error(("AN INDEXERROR EXCEPTION OCCURED FOR FIBER %s. PLEASE CHECK ENDPOINT GENERATION" % i)) break # Filter if startROI == 0 or endROI == 0: dis += 1 fiberlabels[i, 0] = -1 continue if startROI > nROIs or endROI > nROIs: iflogger.error("Start or endpoint of fiber terminate in a voxel which is labeled higher") iflogger.error("than is expected by the parcellation node information.") iflogger.error("Start ROI: %i, End ROI: %i" % (startROI, endROI)) iflogger.error("This needs bugfixing!") continue # Update fiber label # switch the rois in order to enforce startROI < endROI if endROI < startROI: tmp = startROI startROI = endROI endROI = tmp fiberlabels[i, 0] = startROI fiberlabels[i, 1] = endROI final_fiberlabels.append([ startROI, endROI ]) final_fibers_idx.append(i) # Add edge to graph if G.has_edge(startROI, endROI) and G.edge[startROI][endROI].has_key('fiblist'): G.edge[startROI][endROI]['fiblist'].append(i) else: G.add_edge(startROI, endROI, fiblist=[i]) # create a final fiber length array finalfiberlength = [] if intersections: final_fibers_indices = final_fiber_ids else: final_fibers_indices = final_fibers_idx for idx in final_fibers_indices: # compute length of fiber finalfiberlength.append(length(fib[idx][0])) # convert to array final_fiberlength_array = np.array(finalfiberlength) # make final fiber labels as array final_fiberlabels_array = np.array(final_fiberlabels, dtype=int) iflogger.info("Found %i (%f percent out of %i fibers) fibers that start or terminate in a voxel which is not labeled. (orphans)" % (dis, dis * 100.0 / n, n)) iflogger.info("Valid fibers: %i (%f percent)" % (n - dis, 100 - dis * 100.0 / n)) numfib = nx.Graph() numfib.add_nodes_from(G) fibmean = numfib.copy() fibmedian = numfib.copy() fibdev = numfib.copy() for u, v, d in G.edges_iter(data=True): G.remove_edge(u, v) di = {} if d.has_key('fiblist'): di['number_of_fibers'] = len(d['fiblist']) idx = np.where((final_fiberlabels_array[:, 0] == int(u)) & (final_fiberlabels_array[:, 1] == int(v)))[0] di['fiber_length_mean'] = float(np.mean(final_fiberlength_array[idx])) di['fiber_length_median'] = float(np.median(final_fiberlength_array[idx])) di['fiber_length_std'] = float(np.std(final_fiberlength_array[idx])) else: di['number_of_fibers'] = 0 di['fiber_length_mean'] = 0 di['fiber_length_median'] = 0 di['fiber_length_std'] = 0 if not u == v: #Fix for self loop problem G.add_edge(u, v, di) if d.has_key('fiblist'): numfib.add_edge(u, v, weight=di['number_of_fibers']) fibmean.add_edge(u, v, weight=di['fiber_length_mean']) fibmedian.add_edge(u, v, weight=di['fiber_length_median']) fibdev.add_edge(u, v, weight=di['fiber_length_std']) iflogger.info('Writing network as {ntwk}'.format(ntwk=matrix_name)) nx.write_gpickle(G, op.abspath(matrix_name)) numfib_mlab = nx.to_numpy_matrix(numfib, dtype=int) numfib_dict = {'number_of_fibers': numfib_mlab} fibmean_mlab = nx.to_numpy_matrix(fibmean, dtype=np.float64) fibmean_dict = {'mean_fiber_length':fibmean_mlab} fibmedian_mlab = nx.to_numpy_matrix(fibmedian, dtype=np.float64) fibmedian_dict = {'median_fiber_length':fibmedian_mlab} fibdev_mlab = nx.to_numpy_matrix(fibdev, dtype=np.float64) fibdev_dict = {'fiber_length_std':fibdev_mlab} if intersections: path, name, ext = split_filename(matrix_name) intersection_matrix_name = op.abspath(name + '_intersections') + ext iflogger.info('Writing intersection network as {ntwk}'.format(ntwk=intersection_matrix_name)) nx.write_gpickle(I, intersection_matrix_name) path, name, ext = split_filename(matrix_mat_name) if not ext == '.mat': ext = '.mat' matrix_mat_name = matrix_mat_name + ext iflogger.info('Writing matlab matrix as {mat}'.format(mat=matrix_mat_name)) sio.savemat(matrix_mat_name, numfib_dict) if intersections: intersect_dict = {'intersections': intersection_matrix} intersection_matrix_mat_name = op.abspath(name + '_intersections') + ext iflogger.info('Writing intersection matrix as {mat}'.format(mat=intersection_matrix_mat_name)) sio.savemat(intersection_matrix_mat_name, intersect_dict) mean_fiber_length_matrix_name = op.abspath(name + '_mean_fiber_length') + ext iflogger.info('Writing matlab mean fiber length matrix as {mat}'.format(mat=mean_fiber_length_matrix_name)) sio.savemat(mean_fiber_length_matrix_name, fibmean_dict) median_fiber_length_matrix_name = op.abspath(name + '_median_fiber_length') + ext iflogger.info('Writing matlab median fiber length matrix as {mat}'.format(mat=median_fiber_length_matrix_name)) sio.savemat(median_fiber_length_matrix_name, fibmedian_dict) fiber_length_std_matrix_name = op.abspath(name + '_fiber_length_std') + ext iflogger.info('Writing matlab fiber length deviation matrix as {mat}'.format(mat=fiber_length_std_matrix_name)) sio.savemat(fiber_length_std_matrix_name, fibdev_dict) fiberlengths_fname = op.abspath(endpoint_name + '_final_fiberslength.npy') iflogger.info("Storing final fiber length array as %s" % fiberlengths_fname) np.save(fiberlengths_fname, final_fiberlength_array) fiberlabels_fname = op.abspath(endpoint_name + '_filtered_fiberslabel.npy') iflogger.info("Storing all fiber labels (with orphans) as %s" % fiberlabels_fname) np.save(fiberlabels_fname, np.array(fiberlabels, dtype=np.int32),) fiberlabels_noorphans_fname = op.abspath(endpoint_name + '_final_fiberslabels.npy') iflogger.info("Storing final fiber labels (no orphans) as %s" % fiberlabels_noorphans_fname) np.save(fiberlabels_noorphans_fname, final_fiberlabels_array) iflogger.info("Filtering tractography - keeping only no orphan fibers") finalfibers_fname = op.abspath(endpoint_name + '_streamline_final.trk') stats['endpoint_n_fib'] = save_fibers(hdr, fib, finalfibers_fname, final_fibers_idx) stats['endpoints_percent'] = float(stats['endpoint_n_fib'])/float(stats['orig_n_fib'])*100 stats['intersections_percent'] = float(stats['intersections_n_fib'])/float(stats['orig_n_fib'])*100 out_stats_file = op.abspath(endpoint_name + '_statistics.mat') iflogger.info("Saving matrix creation statistics as %s" % out_stats_file) sio.savemat(out_stats_file, stats) def save_fibers(oldhdr, oldfib, fname, indices): """ Stores a new trackvis file fname using only given indices """ hdrnew = oldhdr.copy() outstreams = [] for i in indices: outstreams.append(oldfib[i]) n_fib_out = len(outstreams) hdrnew['n_count'] = n_fib_out iflogger.info("Writing final non-orphan fibers as %s" % fname) nb.trackvis.write(fname, outstreams, hdrnew) return n_fib_out class CreateMatrixInputSpec(TraitedSpec): roi_file = File(exists=True, mandatory=True, desc='Freesurfer aparc+aseg file') tract_file = File(exists=True, mandatory=True, desc='Trackvis tract file') resolution_network_file = File(exists=True, mandatory=True, desc='Parcellation files from Connectome Mapping Toolkit') count_region_intersections = traits.Bool(False, usedefault=True, desc='Counts all of the fiber-region traversals in the connectivity matrix (requires significantly more computational time)') out_matrix_file = File(genfile=True, desc='NetworkX graph describing the connectivity') out_matrix_mat_file = File('cmatrix.mat', usedefault=True, desc='Matlab matrix describing the connectivity') out_mean_fiber_length_matrix_mat_file = File(genfile=True, desc='Matlab matrix describing the mean fiber lengths between each node.') out_median_fiber_length_matrix_mat_file = File(genfile=True, desc='Matlab matrix describing the mean fiber lengths between each node.') out_fiber_length_std_matrix_mat_file = File(genfile=True, desc='Matlab matrix describing the deviation in fiber lengths connecting each node.') out_intersection_matrix_mat_file = File(genfile=True, desc='Matlab connectivity matrix if all region/fiber intersections are counted.') out_endpoint_array_name = File(genfile=True, desc='Name for the generated endpoint arrays') class CreateMatrixOutputSpec(TraitedSpec): matrix_file = File(desc='NetworkX graph describing the connectivity', exists=True) intersection_matrix_file = File(desc='NetworkX graph describing the connectivity', exists=True) matrix_files = OutputMultiPath(File(desc='All of the gpickled network files output by this interface', exists=True)) matlab_matrix_files = OutputMultiPath(File(desc='All of the MATLAB .mat files output by this interface', exists=True)) matrix_mat_file = File(desc='Matlab matrix describing the connectivity', exists=True) intersection_matrix_mat_file = File(desc='Matlab matrix describing the mean fiber lengths between each node.', exists=True) mean_fiber_length_matrix_mat_file = File(desc='Matlab matrix describing the mean fiber lengths between each node.', exists=True) median_fiber_length_matrix_mat_file = File(desc='Matlab matrix describing the median fiber lengths between each node.', exists=True) fiber_length_std_matrix_mat_file = File(desc='Matlab matrix describing the deviation in fiber lengths connecting each node.', exists=True) endpoint_file = File(desc='Saved Numpy array with the endpoints of each fiber', exists=True) endpoint_file_mm = File(desc='Saved Numpy array with the endpoints of each fiber (in millimeters)', exists=True) fiber_length_file = File(desc='Saved Numpy array with the lengths of each fiber', exists=True) fiber_label_file = File(desc='Saved Numpy array with the labels for each fiber', exists=True) fiber_labels_noorphans = File(desc='Saved Numpy array with the labels for each non-orphan fiber', exists=True) filtered_tractography = File(desc='TrackVis file containing only those fibers originate in one and terminate in another region', exists=True) filtered_tractography_by_intersections = File(desc='TrackVis file containing all fibers which connect two regions', exists=True) filtered_tractographies = OutputMultiPath(File(desc='TrackVis file containing only those fibers originate in one and terminate in another region', exists=True)) stats_file = File(desc='Saved Matlab .mat file with the number of fibers saved at each stage', exists=True) class CreateMatrix(BaseInterface): """ Performs connectivity mapping and outputs the result as a NetworkX graph and a Matlab matrix Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> conmap = cmtk.CreateMatrix() >>> conmap.roi_file = 'fsLUT_aparc+aseg.nii' >>> conmap.tract_file = 'fibers.trk' >>> conmap.run() # doctest: +SKIP """ input_spec = CreateMatrixInputSpec output_spec = CreateMatrixOutputSpec def _run_interface(self, runtime): if isdefined(self.inputs.out_matrix_file): path, name, _ = split_filename(self.inputs.out_matrix_file) matrix_file = op.abspath(name + '.pck') else: matrix_file = self._gen_outfilename('.pck') matrix_mat_file = op.abspath(self.inputs.out_matrix_mat_file) path, name, ext = split_filename(matrix_mat_file) if not ext == '.mat': ext = '.mat' matrix_mat_file = matrix_mat_file + ext if isdefined(self.inputs.out_mean_fiber_length_matrix_mat_file): mean_fiber_length_matrix_mat_file = op.abspath(self.inputs.out_mean_fiber_length_matrix_mat_file) else: mean_fiber_length_matrix_name = op.abspath(self._gen_outfilename('_mean_fiber_length.mat')) if isdefined(self.inputs.out_median_fiber_length_matrix_mat_file): median_fiber_length_matrix_mat_file = op.abspath(self.inputs.out_median_fiber_length_matrix_mat_file) else: median_fiber_length_matrix_name = op.abspath(self._gen_outfilename('_median_fiber_length.mat')) if isdefined(self.inputs.out_fiber_length_std_matrix_mat_file): fiber_length_std_matrix_mat_file = op.abspath(self.inputs.out_fiber_length_std_matrix_mat_file) else: fiber_length_std_matrix_name = op.abspath(self._gen_outfilename('_fiber_length_std.mat')) if not isdefined(self.inputs.out_endpoint_array_name): _, endpoint_name , _ = split_filename(self.inputs.tract_file) endpoint_name = op.abspath(endpoint_name) else: endpoint_name = op.abspath(self.inputs.out_endpoint_array_name) cmat(self.inputs.tract_file, self.inputs.roi_file, self.inputs.resolution_network_file, matrix_file, matrix_mat_file, endpoint_name, self.inputs.count_region_intersections) return runtime def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.out_matrix_file): path, name, _ = split_filename(self.inputs.out_matrix_file) out_matrix_file = op.abspath(name + '.pck') out_intersection_matrix_file = op.abspath(name + '_intersections.pck') else: out_matrix_file = op.abspath(self._gen_outfilename('.pck')) out_intersection_matrix_file = op.abspath(self._gen_outfilename('_intersections.pck')) outputs['matrix_file'] = out_matrix_file outputs['intersection_matrix_file'] = out_intersection_matrix_file matrix_mat_file = op.abspath(self.inputs.out_matrix_mat_file) path, name, ext = split_filename(matrix_mat_file) if not ext == '.mat': ext = '.mat' matrix_mat_file = matrix_mat_file + ext outputs['matrix_mat_file'] = matrix_mat_file if isdefined(self.inputs.out_mean_fiber_length_matrix_mat_file): outputs['mean_fiber_length_matrix_mat_file'] = op.abspath(self.inputs.out_mean_fiber_length_matrix_mat_file) else: outputs['mean_fiber_length_matrix_mat_file'] = op.abspath(self._gen_outfilename('_mean_fiber_length.mat')) if isdefined(self.inputs.out_median_fiber_length_matrix_mat_file): outputs['median_fiber_length_matrix_mat_file'] = op.abspath(self.inputs.out_median_fiber_length_matrix_mat_file) else: outputs['median_fiber_length_matrix_mat_file'] = op.abspath(self._gen_outfilename('_median_fiber_length.mat')) if isdefined(self.inputs.out_fiber_length_std_matrix_mat_file): outputs['fiber_length_std_matrix_mat_file'] = op.abspath(self.inputs.out_fiber_length_std_matrix_mat_file) else: outputs['fiber_length_std_matrix_mat_file'] = op.abspath(self._gen_outfilename('_fiber_length_std.mat')) if isdefined(self.inputs.out_intersection_matrix_mat_file): outputs['intersection_matrix_mat_file'] = op.abspath(self.inputs.out_intersection_matrix_mat_file) else: outputs['intersection_matrix_mat_file'] = op.abspath(self._gen_outfilename('_intersections.mat')) if isdefined(self.inputs.out_endpoint_array_name): endpoint_name = self.inputs.out_endpoint_array_name outputs['endpoint_file'] = op.abspath(self.inputs.out_endpoint_array_name + '_endpoints.npy') outputs['endpoint_file_mm'] = op.abspath(self.inputs.out_endpoint_array_name + '_endpointsmm.npy') outputs['fiber_length_file'] = op.abspath(self.inputs.out_endpoint_array_name + '_final_fiberslength.npy') outputs['fiber_label_file'] = op.abspath(self.inputs.out_endpoint_array_name + '_filtered_fiberslabel.npy') outputs['fiber_labels_noorphans'] = op.abspath(self.inputs.out_endpoint_array_name + '_final_fiberslabels.npy') else: _, endpoint_name , _ = split_filename(self.inputs.tract_file) outputs['endpoint_file'] = op.abspath(endpoint_name + '_endpoints.npy') outputs['endpoint_file_mm'] = op.abspath(endpoint_name + '_endpointsmm.npy') outputs['fiber_length_file'] = op.abspath(endpoint_name + '_final_fiberslength.npy') outputs['fiber_label_file'] = op.abspath(endpoint_name + '_filtered_fiberslabel.npy') outputs['fiber_labels_noorphans'] = op.abspath(endpoint_name + '_final_fiberslabels.npy') if self.inputs.count_region_intersections: outputs['matrix_files'] = [out_matrix_file, out_intersection_matrix_file] outputs['matlab_matrix_files'] = [outputs['matrix_mat_file'], outputs['mean_fiber_length_matrix_mat_file'], outputs['median_fiber_length_matrix_mat_file'], outputs['fiber_length_std_matrix_mat_file'], outputs['intersection_matrix_mat_file']] else: outputs['matrix_files'] = [out_matrix_file] outputs['matlab_matrix_files'] = [outputs['matrix_mat_file'], outputs['mean_fiber_length_matrix_mat_file'], outputs['median_fiber_length_matrix_mat_file'], outputs['fiber_length_std_matrix_mat_file']] outputs['filtered_tractography'] = op.abspath(endpoint_name + '_streamline_final.trk') outputs['filtered_tractography_by_intersections'] = op.abspath(endpoint_name + '_intersections_streamline_final.trk') outputs['filtered_tractographies'] = [outputs['filtered_tractography'], outputs['filtered_tractography_by_intersections']] outputs['stats_file'] = op.abspath(endpoint_name + '_statistics.mat') return outputs def _gen_outfilename(self, ext): if ext.endswith("mat") and isdefined(self.inputs.out_matrix_mat_file): _, name , _ = split_filename(self.inputs.out_matrix_mat_file) elif isdefined(self.inputs.out_matrix_file): _, name , _ = split_filename(self.inputs.out_matrix_file) else: _, name , _ = split_filename(self.inputs.tract_file) return name + ext class ROIGenInputSpec(BaseInterfaceInputSpec): aparc_aseg_file = File(exists=True, mandatory=True, desc='Freesurfer aparc+aseg file') LUT_file = File(exists=True, xor=['use_freesurfer_LUT'], desc='Custom lookup table (cf. FreeSurferColorLUT.txt)') use_freesurfer_LUT = traits.Bool(xor=['LUT_file'], desc='Boolean value; Set to True to use default Freesurfer LUT, False for custom LUT') freesurfer_dir = Directory(requires=['use_freesurfer_LUT'], desc='Freesurfer main directory') out_roi_file = File(genfile=True, desc='Region of Interest file for connectivity mapping') out_dict_file = File(genfile=True, desc='Label dictionary saved in Pickle format') class ROIGenOutputSpec(TraitedSpec): roi_file = File(desc='Region of Interest file for connectivity mapping') dict_file = File(desc='Label dictionary saved in Pickle format') class ROIGen(BaseInterface): """ Generates a ROI file for connectivity mapping and a dictionary file containing relevant node information Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> rg = cmtk.ROIGen() >>> rg.inputs.aparc_aseg_file = 'aparc+aseg.nii' >>> rg.inputs.use_freesurfer_LUT = True >>> rg.inputs.freesurfer_dir = '/usr/local/freesurfer' >>> rg.run() # doctest: +SKIP The label dictionary is written to disk using Pickle. Resulting data can be loaded using: >>> file = open("FreeSurferColorLUT_adapted_aparc+aseg_out.pck", "r") >>> file = open("fsLUT_aparc+aseg.pck", "r") >>> labelDict = pickle.load(file) # doctest: +SKIP >>> print labelDict # doctest: +SKIP """ input_spec = ROIGenInputSpec output_spec = ROIGenOutputSpec def _run_interface(self, runtime): aparc_aseg_file = self.inputs.aparc_aseg_file aparcpath, aparcname, aparcext = split_filename(aparc_aseg_file) iflogger.info('Using Aparc+Aseg file: {name}'.format(name=aparcname + aparcext)) niiAPARCimg = nb.load(aparc_aseg_file) niiAPARCdata = niiAPARCimg.get_data() niiDataLabels = np.unique(niiAPARCdata) numDataLabels = np.size(niiDataLabels) iflogger.info('Number of labels in image: {n}'.format(n=numDataLabels)) write_dict = True if self.inputs.use_freesurfer_LUT: self.LUT_file = self.inputs.freesurfer_dir + '/FreeSurferColorLUT.txt' iflogger.info('Using Freesurfer LUT: {name}'.format(name=self.LUT_file)) prefix = 'fsLUT' elif not self.inputs.use_freesurfer_LUT and isdefined(self.inputs.LUT_file): self.LUT_file = op.abspath(self.inputs.LUT_file) lutpath, lutname, lutext = split_filename(self.LUT_file) iflogger.info('Using Custom LUT file: {name}'.format(name=lutname + lutext)) prefix = lutname else: prefix = 'hardcoded' write_dict = False if isdefined(self.inputs.out_roi_file): roi_file = op.abspath(self.inputs.out_roi_file) else: roi_file = op.abspath(prefix + '_' + aparcname + '.nii') if isdefined(self.inputs.out_dict_file): dict_file = op.abspath(self.inputs.out_dict_file) else: dict_file = op.abspath(prefix + '_' + aparcname + '.pck') if write_dict: iflogger.info('Lookup table: {name}'.format(name=op.abspath(self.LUT_file))) LUTlabelsRGBA = np.loadtxt(self.LUT_file, skiprows=4, usecols=[0, 1, 2, 3, 4, 5], comments='#', dtype={'names': ('index', 'label', 'R', 'G', 'B', 'A'), 'formats': ('int', '|S30', 'int', 'int', 'int', 'int')}) numLUTLabels = np.size(LUTlabelsRGBA) if numLUTLabels < numDataLabels: iflogger.error('LUT file provided does not contain all of the regions in the image') iflogger.error('Removing unmapped regions') iflogger.info('Number of labels in LUT: {n}'.format(n=numLUTLabels)) LUTlabelDict = {} """ Create dictionary for input LUT table""" for labels in xrange(0, numLUTLabels): LUTlabelDict[LUTlabelsRGBA[labels][0]] = [LUTlabelsRGBA[labels][1], LUTlabelsRGBA[labels][2], LUTlabelsRGBA[labels][3], LUTlabelsRGBA[labels][4], LUTlabelsRGBA[labels][5]] iflogger.info('Printing LUT label dictionary') iflogger.info(LUTlabelDict) mapDict = {} MAPPING = [[1, 2012], [2, 2019], [3, 2032], [4, 2014], [5, 2020], [6, 2018], [7, 2027], [8, 2028], [9, 2003], [10, 2024], [11, 2017], [12, 2026], [13, 2002], [14, 2023], [15, 2010], [16, 2022], [17, 2031], [18, 2029], [19, 2008], [20, 2025], [21, 2005], [22, 2021], [23, 2011], [24, 2013], [25, 2007], [26, 2016], [27, 2006], [28, 2033], [29, 2009], [30, 2015], [31, 2001], [32, 2030], [33, 2034], [34, 2035], [35, 49], [36, 50], [37, 51], [38, 52], [39, 58], [40, 53], [41, 54], [42, 1012], [43, 1019], [44, 1032], [45, 1014], [46, 1020], [47, 1018], [48, 1027], [49, 1028], [50, 1003], [51, 1024], [52, 1017], [53, 1026], [54, 1002], [55, 1023], [56, 1010], [57, 1022], [58, 1031], [59, 1029], [60, 1008], [61, 1025], [62, 1005], [63, 1021], [64, 1011], [65, 1013], [66, 1007], [67, 1016], [68, 1006], [69, 1033], [70, 1009], [71, 1015], [72, 1001], [73, 1030], [74, 1034], [75, 1035], [76, 10], [77, 11], [78, 12], [79, 13], [80, 26], [81, 17], [82, 18], [83, 16]] """ Create empty grey matter mask, Populate with only those regions defined in the mapping.""" niiGM = np.zeros(niiAPARCdata.shape, dtype=np.uint) for ma in MAPPING: niiGM[ niiAPARCdata == ma[1]] = ma[0] mapDict[ma[0]] = ma[1] iflogger.info('Grey matter mask created') greyMaskLabels = np.unique(niiGM) numGMLabels = np.size(greyMaskLabels) iflogger.info('Number of grey matter labels: {num}'.format(num=numGMLabels)) labelDict = {} GMlabelDict = {} for label in greyMaskLabels: try: mapDict[label] if write_dict: GMlabelDict['originalID'] = mapDict[label] except: iflogger.info('Label {lbl} not in provided mapping'.format(lbl=label)) if write_dict: del GMlabelDict GMlabelDict = {} GMlabelDict['labels'] = LUTlabelDict[label][0] GMlabelDict['colors'] = [LUTlabelDict[label][1], LUTlabelDict[label][2], LUTlabelDict[label][3]] GMlabelDict['a'] = LUTlabelDict[label][4] labelDict[label] = GMlabelDict roi_image = nb.Nifti1Image(niiGM, niiAPARCimg.get_affine(), niiAPARCimg.get_header()) iflogger.info('Saving ROI File to {path}'.format(path=roi_file)) nb.save(roi_image, roi_file) if write_dict: iflogger.info('Saving Dictionary File to {path} in Pickle format'.format(path=dict_file)) file = open(dict_file, 'w') pickle.dump(labelDict, file) file.close() return runtime def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.out_roi_file): outputs['roi_file'] = op.abspath(self.inputs.out_roi_file) else: outputs['roi_file'] = op.abspath(self._gen_outfilename('nii')) if isdefined(self.inputs.out_dict_file): outputs['dict_file'] = op.abspath(self.inputs.out_dict_file) else: outputs['dict_file'] = op.abspath(self._gen_outfilename('pck')) return outputs def _gen_outfilename(self, ext): _, name , _ = split_filename(self.inputs.aparc_aseg_file) if self.inputs.use_freesurfer_LUT: prefix = 'fsLUT' elif not self.inputs.use_freesurfer_LUT and isdefined(self.inputs.LUT_file): lutpath, lutname, lutext = split_filename(self.inputs.LUT_file) prefix = lutname else: prefix = 'hardcoded' return prefix + '_' + name + '.' + ext def create_nodes(roi_file, resolution_network_file, out_filename): G = nx.Graph() gp = nx.read_graphml(resolution_network_file) roi_image = nb.load(roi_file) roiData = roi_image.get_data() nROIs = len(gp.nodes()) for u, d in gp.nodes_iter(data=True): G.add_node(int(u), d) xyz = tuple(np.mean(np.where(np.flipud(roiData) == int(d["dn_correspondence_id"])) , axis=1)) G.node[int(u)]['dn_position'] = tuple([xyz[0], xyz[2], -xyz[1]]) nx.write_gpickle(G, out_filename) return out_filename class CreateNodesInputSpec(BaseInterfaceInputSpec): roi_file = File(exists=True, mandatory=True, desc='Region of interest file') resolution_network_file = File(exists=True, mandatory=True, desc='Parcellation file from Connectome Mapping Toolkit') out_filename = File('nodenetwork.pck', usedefault=True, desc='Output gpickled network with the nodes defined.') class CreateNodesOutputSpec(TraitedSpec): node_network = File(desc='Output gpickled network with the nodes defined.') class CreateNodes(BaseInterface): """ Generates a NetworkX graph containing nodes at the centroid of each region in the input ROI file. Node data is added from the resolution network file. Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> mknode = cmtk.CreateNodes() >>> mknode.inputs.roi_file = 'ROI_scale500.nii.gz' >>> mknode.run() # doctest: +SKIP """ input_spec = CreateNodesInputSpec output_spec = CreateNodesOutputSpec def _run_interface(self, runtime): iflogger.info('Creating nodes...') create_nodes(self.inputs.roi_file, self.inputs.resolution_network_file, self.inputs.out_filename) iflogger.info('Saving node network to {path}'.format(path=op.abspath(self.inputs.out_filename))) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['node_network'] = op.abspath(self.inputs.out_filename) return outputs nipype-0.11.0/nipype/interfaces/cmtk/convert.py000066400000000000000000000241731257611314500215300ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os, os.path as op import datetime import string import warnings import networkx as nx from nipype.interfaces.base import (BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, InputMultiPath, isdefined) from nipype.utils.filemanip import split_filename from nipype.utils.misc import package_check have_cfflib = True try: package_check('cfflib') except Exception, e: have_cfflib = False else: import cfflib as cf class CFFConverterInputSpec(BaseInterfaceInputSpec): graphml_networks = InputMultiPath(File(exists=True), desc='list of graphML networks') gpickled_networks = InputMultiPath(File(exists=True), desc='list of gpickled Networkx graphs') gifti_surfaces = InputMultiPath(File(exists=True), desc='list of GIFTI surfaces') gifti_labels = InputMultiPath(File(exists=True), desc='list of GIFTI labels') nifti_volumes = InputMultiPath(File(exists=True), desc='list of NIFTI volumes') tract_files = InputMultiPath(File(exists=True), desc='list of Trackvis fiber files') timeseries_files = InputMultiPath(File(exists=True), desc='list of HDF5 timeseries files') script_files = InputMultiPath(File(exists=True), desc='list of script files to include') data_files = InputMultiPath(File(exists=True), desc='list of external data files (i.e. Numpy, HD5, XML) ') title = traits.Str(desc='Connectome Title') creator = traits.Str(desc='Creator') email = traits.Str(desc='Email address') publisher = traits.Str(desc='Publisher') license = traits.Str(desc='License') rights = traits.Str(desc='Rights') references = traits.Str(desc='References') relation = traits.Str(desc='Relation') species = traits.Str('Homo sapiens',desc='Species',usedefault=True) description = traits.Str('Created with the Nipype CFF converter', desc='Description', usedefault=True) out_file = File('connectome.cff', usedefault = True, desc='Output connectome file') class CFFConverterOutputSpec(TraitedSpec): connectome_file = File(exists=True, desc='Output connectome file') class CFFConverter(BaseInterface): """ Creates a Connectome File Format (CFF) file from input networks, surfaces, volumes, tracts, etcetera.... Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> cvt = cmtk.CFFConverter() >>> cvt.inputs.title = 'subject 1' >>> cvt.inputs.gifti_surfaces = ['lh.pial_converted.gii', 'rh.pial_converted.gii'] >>> cvt.inputs.tract_files = ['streamlines.trk'] >>> cvt.inputs.gpickled_networks = ['network0.gpickle'] >>> cvt.run() # doctest: +SKIP """ input_spec = CFFConverterInputSpec output_spec = CFFConverterOutputSpec def _run_interface(self, runtime): a = cf.connectome() if isdefined(self.inputs.title): a.connectome_meta.set_title(self.inputs.title) else: a.connectome_meta.set_title(self.inputs.out_file) if isdefined(self.inputs.creator): a.connectome_meta.set_creator(self.inputs.creator) else: #Probably only works on some OSes... a.connectome_meta.set_creator(os.getenv('USER')) if isdefined(self.inputs.email): a.connectome_meta.set_email(self.inputs.email) if isdefined(self.inputs.publisher): a.connectome_meta.set_publisher(self.inputs.publisher) if isdefined(self.inputs.license): a.connectome_meta.set_license(self.inputs.license) if isdefined(self.inputs.rights): a.connectome_meta.set_rights(self.inputs.rights) if isdefined(self.inputs.references): a.connectome_meta.set_references(self.inputs.references) if isdefined(self.inputs.relation): a.connectome_meta.set_relation(self.inputs.relation) if isdefined(self.inputs.species): a.connectome_meta.set_species(self.inputs.species) if isdefined(self.inputs.description): a.connectome_meta.set_description(self.inputs.description) a.connectome_meta.set_created(datetime.date.today()) count = 0 if isdefined(self.inputs.graphml_networks): for ntwk in self.inputs.graphml_networks: # There must be a better way to deal with the unique name problem #(i.e. tracks and networks can't use the same name, and previously we were pulling them both from the input files) ntwk_name = 'Network {cnt}'.format(cnt=count) a.add_connectome_network_from_graphml(ntwk_name, ntwk) count += 1 if isdefined(self.inputs.gpickled_networks): unpickled = [] for ntwk in self.inputs.gpickled_networks: _, ntwk_name, _ = split_filename(ntwk) unpickled = nx.read_gpickle(ntwk) cnet = cf.CNetwork(name = ntwk_name) cnet.set_with_nxgraph(unpickled) a.add_connectome_network(cnet) count += 1 count = 0 if isdefined(self.inputs.tract_files): for trk in self.inputs.tract_files: _, trk_name, _ = split_filename(trk) ctrack = cf.CTrack(trk_name, trk) a.add_connectome_track(ctrack) count += 1 count = 0 if isdefined(self.inputs.gifti_surfaces): for surf in self.inputs.gifti_surfaces: _, surf_name, _ = split_filename(surf) csurf = cf.CSurface.create_from_gifti("Surface %d - %s" % (count,surf_name), surf) csurf.fileformat='Gifti' csurf.dtype='Surfaceset' a.add_connectome_surface(csurf) count += 1 count = 0 if isdefined(self.inputs.gifti_labels): for label in self.inputs.gifti_labels: _, label_name, _ = split_filename(label) csurf = cf.CSurface.create_from_gifti("Surface Label %d - %s" % (count,label_name), label) csurf.fileformat='Gifti' csurf.dtype='Labels' a.add_connectome_surface(csurf) count += 1 if isdefined(self.inputs.nifti_volumes): for vol in self.inputs.nifti_volumes: _, vol_name, _ = split_filename(vol) cvol = cf.CVolume.create_from_nifti(vol_name,vol) a.add_connectome_volume(cvol) if isdefined(self.inputs.script_files): for script in self.inputs.script_files: _, script_name, _ = split_filename(script) cscript = cf.CScript.create_from_file(script_name, script) a.add_connectome_script(cscript) if isdefined(self.inputs.data_files): for data in self.inputs.data_files: _, data_name, _ = split_filename(data) cda = cf.CData(name=data_name, src=data, fileformat='NumPy') if not string.find(data_name,'lengths') == -1: cda.dtype = 'FinalFiberLengthArray' if not string.find(data_name,'endpoints') == -1: cda.dtype = 'FiberEndpoints' if not string.find(data_name,'labels') == -1: cda.dtype = 'FinalFiberLabels' a.add_connectome_data(cda) a.print_summary() _, name, ext = split_filename(self.inputs.out_file) if not ext == '.cff': ext = '.cff' cf.save_to_cff(a,op.abspath(name + ext)) return runtime def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(self.inputs.out_file) if not ext == '.cff': ext = '.cff' outputs['connectome_file'] = op.abspath(name + ext) return outputs class MergeCNetworksInputSpec(BaseInterfaceInputSpec): in_files = InputMultiPath(File(exists=True), mandatory=True, desc='List of CFF files to extract networks from') out_file = File('merged_network_connectome.cff', usedefault = True, desc='Output CFF file with all the networks added') class MergeCNetworksOutputSpec(TraitedSpec): connectome_file = File(exists=True, desc='Output CFF file with all the networks added') class MergeCNetworks(BaseInterface): """ Merges networks from multiple CFF files into one new CFF file. Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> mrg = cmtk.MergeCNetworks() >>> mrg.inputs.in_files = ['subj1.cff','subj2.cff'] >>> mrg.run() # doctest: +SKIP """ input_spec = MergeCNetworksInputSpec output_spec = MergeCNetworksOutputSpec def _run_interface(self, runtime): extracted_networks = [] for i, con in enumerate(self.inputs.in_files): mycon = cf.load(con) nets = mycon.get_connectome_network() for ne in nets: # here, you might want to skip networks with a given # metadata information ne.load() contitle = mycon.get_connectome_meta().get_title() ne.set_name( str(i) + ': ' + contitle + ' - ' + ne.get_name() ) ne.set_src(ne.get_name()) extracted_networks.append(ne) # Add networks to new connectome newcon = cf.connectome(title = 'All CNetworks', connectome_network = extracted_networks) # Setting additional metadata metadata = newcon.get_connectome_meta() metadata.set_creator('My Name') metadata.set_email('My Email') _, name, ext = split_filename(self.inputs.out_file) if not ext == '.cff': ext = '.cff' cf.save_to_cff(newcon, op.abspath(name + ext)) return runtime def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(self.inputs.out_file) if not ext == '.cff': ext = '.cff' outputs['connectome_file'] = op.abspath(name + ext) return outputs nipype-0.11.0/nipype/interfaces/cmtk/nbs.py000066400000000000000000000140631257611314500206270ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from nipype.interfaces.base import (BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, InputMultiPath, OutputMultiPath, isdefined) import os.path as op import numpy as np import networkx as nx from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_cv = True try: package_check('cviewer') except Exception, e: have_cv = False else: import cviewer.libs.pyconto.groupstatistics.nbs as nbs def ntwks_to_matrices(in_files, edge_key): first = nx.read_gpickle(in_files[0]) files = len(in_files) nodes = len(first.nodes()) matrix = np.zeros((nodes, nodes, files)) for idx, name in enumerate(in_files): graph = nx.read_gpickle(name) for u, v, d in graph.edges(data=True): graph[u][v]['weight'] = d[edge_key] # Setting the edge requested edge value as weight value matrix[:, :, idx] = nx.to_numpy_matrix(graph) # Retrieve the matrix return matrix class NetworkBasedStatisticInputSpec(BaseInterfaceInputSpec): in_group1 = InputMultiPath(File(exists=True), mandatory=True, desc='Networks for the first group of subjects') in_group2 = InputMultiPath(File(exists=True), mandatory=True, desc='Networks for the second group of subjects') node_position_network = File(desc='An optional network used to position the nodes for the output networks') number_of_permutations = traits.Int(1000, usedefault=True, desc='Number of permutations to perform') threshold = traits.Float(3, usedefault=True, desc='T-statistic threshold') t_tail = traits.Enum('left', 'right', 'both', usedefault=True, desc='Can be one of "left", "right", or "both"') edge_key = traits.Str('number_of_fibers', usedefault=True, desc='Usually "number_of_fibers, "fiber_length_mean", "fiber_length_std" for matrices made with CMTK' \ 'Sometimes "weight" or "value" for functional networks.') out_nbs_network = File(desc='Output network with edges identified by the NBS') out_nbs_pval_network = File(desc='Output network with p-values to weight the edges identified by the NBS') class NetworkBasedStatisticOutputSpec(TraitedSpec): nbs_network = File(exists=True, desc='Output network with edges identified by the NBS') nbs_pval_network = File(exists=True, desc='Output network with p-values to weight the edges identified by the NBS') network_files = OutputMultiPath(File(exists=True), desc='Output network with edges identified by the NBS') class NetworkBasedStatistic(BaseInterface): """ Calculates and outputs the average network given a set of input NetworkX gpickle files For documentation of Network-based statistic parameters: https://github.com/LTS5/connectomeviewer/blob/master/cviewer/libs/pyconto/groupstatistics/nbs/_nbs.py Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> nbs = cmtk.NetworkBasedStatistic() >>> nbs.inputs.in_group1 = ['subj1.pck', 'subj2.pck'] # doctest: +SKIP >>> nbs.inputs.in_group2 = ['pat1.pck', 'pat2.pck'] # doctest: +SKIP >>> nbs.run() # doctest: +SKIP """ input_spec = NetworkBasedStatisticInputSpec output_spec = NetworkBasedStatisticOutputSpec def _run_interface(self, runtime): THRESH = self.inputs.threshold K = self.inputs.number_of_permutations TAIL = self.inputs.t_tail edge_key = self.inputs.edge_key details = edge_key + '-thresh-' + str(THRESH) + '-k-' + str(K) + '-tail-' + TAIL + '.pck' # Fill in the data from the networks X = ntwks_to_matrices(self.inputs.in_group1, edge_key) Y = ntwks_to_matrices(self.inputs.in_group2, edge_key) PVAL, ADJ, _ = nbs.compute_nbs(X, Y, THRESH, K, TAIL) iflogger.info('p-values:') iflogger.info(PVAL) pADJ = ADJ.copy() for idx, _ in enumerate(PVAL): x, y = np.where(ADJ == idx + 1) pADJ[x, y] = PVAL[idx] # Create networkx graphs from the adjacency matrix nbsgraph = nx.from_numpy_matrix(ADJ) nbs_pval_graph = nx.from_numpy_matrix(pADJ) # Relabel nodes because they should not start at zero for our convention nbsgraph = nx.relabel_nodes(nbsgraph, lambda x: x + 1) nbs_pval_graph = nx.relabel_nodes(nbs_pval_graph, lambda x: x + 1) if isdefined(self.inputs.node_position_network): node_ntwk_name = self.inputs.node_position_network else: node_ntwk_name = self.inputs.in_group1[0] node_network = nx.read_gpickle(node_ntwk_name) iflogger.info('Populating node dictionaries with attributes from {node}'.format(node=node_ntwk_name)) for nid, ndata in node_network.nodes_iter(data=True): nbsgraph.node[nid] = ndata nbs_pval_graph.node[nid] = ndata path = op.abspath('NBS_Result_' + details) iflogger.info(path) nx.write_gpickle(nbsgraph, path) iflogger.info('Saving output NBS edge network as {out}'.format(out=path)) pval_path = op.abspath('NBS_P_vals_' + details) iflogger.info(pval_path) nx.write_gpickle(nbs_pval_graph, pval_path) iflogger.info('Saving output p-value network as {out}'.format(out=pval_path)) return runtime def _list_outputs(self): outputs = self.output_spec().get() THRESH = self.inputs.threshold K = self.inputs.number_of_permutations TAIL = self.inputs.t_tail edge_key = self.inputs.edge_key details = edge_key + '-thresh-' + str(THRESH) + '-k-' + str(K) + '-tail-' + TAIL + '.pck' path = op.abspath('NBS_Result_' + details) pval_path = op.abspath('NBS_P_vals_' + details) outputs['nbs_network'] = path outputs['nbs_pval_network'] = pval_path outputs['network_files'] = [path, pval_path] return outputs def _gen_outfilename(self, name, ext): return name + '.' + ext nipype-0.11.0/nipype/interfaces/cmtk/nx.py000066400000000000000000000616241257611314500204770ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, InputMultiPath, OutputMultiPath, isdefined) from nipype.utils.filemanip import split_filename import os, os.path as op import numpy as np import networkx as nx import scipy.io as sio import pickle from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_cmp = True try: package_check('cmp') except Exception, e: have_cmp = False else: import cmp def read_unknown_ntwk(ntwk): if not isinstance(ntwk, nx.classes.graph.Graph): path, name, ext = split_filename(ntwk) if ext == '.pck': ntwk = nx.read_gpickle(ntwk) elif ext == '.graphml': ntwk = nx.read_graphml(ntwk) return ntwk def remove_all_edges(ntwk): ntwktmp = ntwk.copy() edges = ntwktmp.edges_iter() for edge in edges: ntwk.remove_edge(edge[0], edge[1]) return ntwk def fix_keys_for_gexf(orig): """ GEXF Networks can be read in Gephi, however, the keys for the node and edge IDs must be converted to strings """ import networkx as nx ntwk = nx.Graph() nodes = orig.nodes_iter() edges = orig.edges_iter() for node in nodes: newnodedata = {} newnodedata.update(orig.node[node]) if orig.node[node].has_key('dn_fsname'): newnodedata['label'] = orig.node[node]['dn_fsname'] ntwk.add_node(str(node), newnodedata) if ntwk.node[str(node)].has_key('dn_position') and newnodedata.has_key('dn_position'): ntwk.node[str(node)]['dn_position'] = str(newnodedata['dn_position']) for edge in edges: data = {} data = orig.edge[edge[0]][edge[1]] ntwk.add_edge(str(edge[0]), str(edge[1]), data) if ntwk.edge[str(edge[0])][str(edge[1])].has_key('fiber_length_mean'): ntwk.edge[str(edge[0])][str(edge[1])]['fiber_length_mean'] = str(data['fiber_length_mean']) if ntwk.edge[str(edge[0])][str(edge[1])].has_key('fiber_length_std'): ntwk.edge[str(edge[0])][str(edge[1])]['fiber_length_std'] = str(data['fiber_length_std']) if ntwk.edge[str(edge[0])][str(edge[1])].has_key('number_of_fibers'): ntwk.edge[str(edge[0])][str(edge[1])]['number_of_fibers'] = str(data['number_of_fibers']) if ntwk.edge[str(edge[0])][str(edge[1])].has_key('value'): ntwk.edge[str(edge[0])][str(edge[1])]['value'] = str(data['value']) return ntwk def add_dicts_by_key(in_dict1, in_dict2): """ Combines two dictionaries and adds the values for those keys that are shared """ both = {} for key1 in in_dict1: for key2 in in_dict2: if key1 == key2: both[key1] = in_dict1[key1] + in_dict2[key2] return both def average_networks(in_files, ntwk_res_file, group_id): """ Sums the edges of input networks and divides by the number of networks Writes the average network as .pck and .gexf and returns the name of the written networks """ import networkx as nx import os.path as op iflogger.info("Creating average network for group: {grp}".format(grp=group_id)) matlab_network_list = [] if len(in_files) == 1: avg_ntwk = read_unknown_ntwk(in_files[0]) else: count_to_keep_edge = np.round(float(len(in_files)) / 2) iflogger.info("Number of networks: {L}, an edge must occur in at least {c} to remain in the average network".format(L=len(in_files), c=count_to_keep_edge)) ntwk_res_file = read_unknown_ntwk(ntwk_res_file) iflogger.info("{n} Nodes found in network resolution file".format(n=ntwk_res_file.number_of_nodes())) ntwk = remove_all_edges(ntwk_res_file) counting_ntwk = ntwk.copy() # Sums all the relevant variables for index, subject in enumerate(in_files): tmp = nx.read_gpickle(subject) iflogger.info('File {s} has {n} edges'.format(s=subject, n=tmp.number_of_edges())) edges = tmp.edges_iter() for edge in edges: data = {} data = tmp.edge[edge[0]][edge[1]] data['count'] = 1 if ntwk.has_edge(edge[0], edge[1]): current = {} current = ntwk.edge[edge[0]][edge[1]] data = add_dicts_by_key(current, data) ntwk.add_edge(edge[0], edge[1], data) nodes = tmp.nodes_iter() for node in nodes: data = {} data = ntwk.node[node] if tmp.node[node].has_key('value'): data['value'] = data['value'] + tmp.node[node]['value'] ntwk.add_node(node, data) # Divides each value by the number of files nodes = ntwk.nodes_iter() edges = ntwk.edges_iter() iflogger.info('Total network has {n} edges'.format(n=ntwk.number_of_edges())) avg_ntwk = nx.Graph() newdata = {} for node in nodes: data = ntwk.node[node] newdata = data if data.has_key('value'): newdata['value'] = data['value'] / len(in_files) ntwk.node[node]['value'] = newdata avg_ntwk.add_node(node, newdata) edge_dict = {} edge_dict['count'] = np.zeros((avg_ntwk.number_of_nodes(), avg_ntwk.number_of_nodes())) for edge in edges: data = ntwk.edge[edge[0]][edge[1]] if ntwk.edge[edge[0]][edge[1]]['count'] >= count_to_keep_edge: for key in data.keys(): if not key == 'count': data[key] = data[key] / len(in_files) ntwk.edge[edge[0]][edge[1]] = data avg_ntwk.add_edge(edge[0],edge[1],data) edge_dict['count'][edge[0]-1][edge[1]-1] = ntwk.edge[edge[0]][edge[1]]['count'] iflogger.info('After thresholding, the average network has has {n} edges'.format(n=avg_ntwk.number_of_edges())) avg_edges = avg_ntwk.edges_iter() for edge in avg_edges: data = avg_ntwk.edge[edge[0]][edge[1]] for key in data.keys(): if not key == 'count': edge_dict[key] = np.zeros((avg_ntwk.number_of_nodes(), avg_ntwk.number_of_nodes())) edge_dict[key][edge[0]-1][edge[1]-1] = data[key] for key in edge_dict.keys(): tmp = {} network_name = group_id + '_' + key + '_average.mat' matlab_network_list.append(op.abspath(network_name)) tmp[key] = edge_dict[key] sio.savemat(op.abspath(network_name), tmp) iflogger.info('Saving average network for key: {k} as {out}'.format(k=key, out=op.abspath(network_name))) # Writes the networks and returns the name network_name = group_id + '_average.pck' nx.write_gpickle(avg_ntwk, op.abspath(network_name)) iflogger.info('Saving average network as {out}'.format(out=op.abspath(network_name))) avg_ntwk = fix_keys_for_gexf(avg_ntwk) network_name = group_id + '_average.gexf' nx.write_gexf(avg_ntwk, op.abspath(network_name)) iflogger.info('Saving average network as {out}'.format(out=op.abspath(network_name))) return network_name, matlab_network_list def compute_node_measures(ntwk, calculate_cliques=False): """ These return node-based measures """ iflogger.info('Computing node measures:') measures = {} iflogger.info('...Computing degree...') measures['degree'] = np.array(ntwk.degree().values()) iflogger.info('...Computing load centrality...') measures['load_centrality'] = np.array(nx.load_centrality(ntwk).values()) iflogger.info('...Computing betweenness centrality...') measures['betweenness_centrality'] = np.array(nx.betweenness_centrality(ntwk).values()) iflogger.info('...Computing degree centrality...') measures['degree_centrality'] = np.array(nx.degree_centrality(ntwk).values()) iflogger.info('...Computing closeness centrality...') measures['closeness_centrality'] = np.array(nx.closeness_centrality(ntwk).values()) # iflogger.info('...Computing eigenvector centrality...') # measures['eigenvector_centrality'] = np.array(nx.eigenvector_centrality(ntwk, max_iter=100000).values()) iflogger.info('...Computing triangles...') measures['triangles'] = np.array(nx.triangles(ntwk).values()) iflogger.info('...Computing clustering...') measures['clustering'] = np.array(nx.clustering(ntwk).values()) iflogger.info('...Computing k-core number') measures['core_number'] = np.array(nx.core_number(ntwk).values()) iflogger.info('...Identifying network isolates...') isolate_list = nx.isolates(ntwk) binarized = np.zeros((ntwk.number_of_nodes(), 1)) for value in isolate_list: value = value - 1 # Zero indexing binarized[value] = 1 measures['isolates'] = binarized if calculate_cliques: iflogger.info('...Calculating node clique number') measures['node_clique_number'] = np.array(nx.node_clique_number(ntwk).values()) iflogger.info('...Computing number of cliques for each node...') measures['number_of_cliques'] = np.array(nx.number_of_cliques(ntwk).values()) return measures def compute_edge_measures(ntwk): """ These return edge-based measures """ iflogger.info('Computing edge measures:') measures = {} #iflogger.info('...Computing google matrix...' #Makes really large networks (500k+ edges)) #measures['google_matrix'] = nx.google_matrix(ntwk) #iflogger.info('...Computing hub matrix...') #measures['hub_matrix'] = nx.hub_matrix(ntwk) #iflogger.info('...Computing authority matrix...') #measures['authority_matrix'] = nx.authority_matrix(ntwk) return measures def compute_dict_measures(ntwk): """ Returns a dictionary """ iflogger.info('Computing measures which return a dictionary:') measures = {} iflogger.info('...Computing rich club coefficient...') measures['rich_club_coef'] = nx.rich_club_coefficient(ntwk) return measures def compute_singlevalued_measures(ntwk, weighted=True, calculate_cliques=False): """ Returns a single value per network """ iflogger.info('Computing single valued measures:') measures = {} iflogger.info('...Computing degree assortativity (pearson number) ...') try: measures['degree_pearsonr'] = nx.degree_pearsonr(ntwk) except AttributeError: # For NetworkX 1.6 measures['degree_pearsonr'] = nx.degree_pearson_correlation_coefficient(ntwk) iflogger.info('...Computing degree assortativity...') try: measures['degree_assortativity'] = nx.degree_assortativity(ntwk) except AttributeError: measures['degree_assortativity'] = nx.degree_assortativity_coefficient(ntwk) iflogger.info('...Computing transitivity...') measures['transitivity'] = nx.transitivity(ntwk) iflogger.info('...Computing number of connected_components...') measures['number_connected_components'] = nx.number_connected_components(ntwk) iflogger.info('...Computing graph density...') measures['graph_density'] = nx.density(ntwk) iflogger.info('...Recording number of edges...') measures['number_of_edges'] = nx.number_of_edges(ntwk) iflogger.info('...Recording number of nodes...') measures['number_of_nodes'] = nx.number_of_nodes(ntwk) iflogger.info('...Computing average clustering...') measures['average_clustering'] = nx.average_clustering(ntwk) if nx.is_connected(ntwk): iflogger.info('...Calculating average shortest path length...') measures['average_shortest_path_length'] = nx.average_shortest_path_length(ntwk, weighted) else: iflogger.info('...Calculating average shortest path length...') measures['average_shortest_path_length'] = nx.average_shortest_path_length(nx.connected_component_subgraphs(ntwk)[0], weighted) if calculate_cliques: iflogger.info('...Computing graph clique number...') measures['graph_clique_number'] = nx.graph_clique_number(ntwk) #out of memory error return measures def compute_network_measures(ntwk): measures = {} #iflogger.info('Identifying k-core') #measures['k_core'] = nx.k_core(ntwk) #iflogger.info('Identifying k-shell') #measures['k_shell'] = nx.k_shell(ntwk) #iflogger.info('Identifying k-crust') #measures['k_crust'] = nx.k_crust(ntwk) return measures def add_node_data(node_array, ntwk): node_ntwk = nx.Graph() newdata = {} for idx, data in ntwk.nodes_iter(data=True): if not int(idx) == 0: newdata['value'] = node_array[int(idx) - 1] data.update(newdata) node_ntwk.add_node(int(idx), data) return node_ntwk def add_edge_data(edge_array, ntwk, above=0, below=0): edge_ntwk = ntwk.copy() data = {} for x, row in enumerate(edge_array): for y in range(0, np.max(np.shape(edge_array[x]))): if not edge_array[x, y] == 0: data['value'] = edge_array[x, y] if data['value'] <= below or data['value'] >= above: if edge_ntwk.has_edge(x + 1, y + 1): old_edge_dict = edge_ntwk.edge[x + 1][y + 1] edge_ntwk.remove_edge(x + 1, y + 1) data.update(old_edge_dict) edge_ntwk.add_edge(x + 1, y + 1, data) return edge_ntwk class NetworkXMetricsInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='Input network') out_k_core = File('k_core', usedefault=True, desc='Computed k-core network stored as a NetworkX pickle.') out_k_shell = File('k_shell', usedefault=True, desc='Computed k-shell network stored as a NetworkX pickle.') out_k_crust = File('k_crust', usedefault=True, desc='Computed k-crust network stored as a NetworkX pickle.') treat_as_weighted_graph = traits.Bool(True, usedefault=True, desc='Some network metrics can be calculated while considering only a binarized version of the graph') compute_clique_related_measures = traits.Bool(False, usedefault=True, desc='Computing clique-related measures (e.g. node clique number) can be very time consuming') out_global_metrics_matlab = File(genfile=True, desc='Output node metrics in MATLAB .mat format') out_node_metrics_matlab = File(genfile=True, desc='Output node metrics in MATLAB .mat format') out_edge_metrics_matlab = File(genfile=True, desc='Output edge metrics in MATLAB .mat format') out_pickled_extra_measures = File('extra_measures', usedefault=True, desc='Network measures for group 1 that return dictionaries stored as a Pickle.') class NetworkXMetricsOutputSpec(TraitedSpec): gpickled_network_files = OutputMultiPath(File(desc='Output gpickled network files')) matlab_matrix_files = OutputMultiPath(File(desc='Output network metrics in MATLAB .mat format')) global_measures_matlab = File(desc='Output global metrics in MATLAB .mat format') node_measures_matlab = File(desc='Output node metrics in MATLAB .mat format') edge_measures_matlab = File(desc='Output edge metrics in MATLAB .mat format') node_measure_networks = OutputMultiPath(File(desc='Output gpickled network files for all node-based measures')) edge_measure_networks = OutputMultiPath(File(desc='Output gpickled network files for all edge-based measures')) k_networks = OutputMultiPath(File(desc='Output gpickled network files for the k-core, k-shell, and k-crust networks')) k_core = File(desc='Computed k-core network stored as a NetworkX pickle.') k_shell = File(desc='Computed k-shell network stored as a NetworkX pickle.') k_crust = File(desc='Computed k-crust network stored as a NetworkX pickle.') pickled_extra_measures = File(desc='Network measures for the group that return dictionaries, stored as a Pickle.') matlab_dict_measures = OutputMultiPath(File(desc='Network measures for the group that return dictionaries, stored as matlab matrices.')) class NetworkXMetrics(BaseInterface): """ Calculates and outputs NetworkX-based measures for an input network Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> nxmetrics = cmtk.NetworkXMetrics() >>> nxmetrics.inputs.in_file = 'subj1.pck' >>> nxmetrics.run() # doctest: +SKIP """ input_spec = NetworkXMetricsInputSpec output_spec = NetworkXMetricsOutputSpec def _run_interface(self, runtime): global gpickled, nodentwks, edgentwks, kntwks, matlab gpickled = list() nodentwks = list() edgentwks = list() kntwks = list() matlab = list() ntwk = nx.read_gpickle(self.inputs.in_file) # Each block computes, writes, and saves a measure # The names are then added to the output .pck file list # In the case of the degeneracy networks, they are given specified output names calculate_cliques = self.inputs.compute_clique_related_measures weighted = self.inputs.treat_as_weighted_graph global_measures = compute_singlevalued_measures(ntwk, weighted, calculate_cliques) if isdefined(self.inputs.out_global_metrics_matlab): global_out_file = op.abspath(self.inputs.out_global_metrics_matlab) else: global_out_file = op.abspath(self._gen_outfilename('globalmetrics', 'mat')) sio.savemat(global_out_file, global_measures, oned_as='column') matlab.append(global_out_file) node_measures = compute_node_measures(ntwk, calculate_cliques) for key in node_measures.keys(): newntwk = add_node_data(node_measures[key], ntwk) out_file = op.abspath(self._gen_outfilename(key, 'pck')) nx.write_gpickle(newntwk, out_file) nodentwks.append(out_file) if isdefined(self.inputs.out_node_metrics_matlab): node_out_file = op.abspath(self.inputs.out_node_metrics_matlab) else: node_out_file = op.abspath(self._gen_outfilename('nodemetrics', 'mat')) sio.savemat(node_out_file, node_measures, oned_as='column') matlab.append(node_out_file) gpickled.extend(nodentwks) edge_measures = compute_edge_measures(ntwk) for key in edge_measures.keys(): newntwk = add_edge_data(edge_measures[key], ntwk) out_file = op.abspath(self._gen_outfilename(key, 'pck')) nx.write_gpickle(newntwk, out_file) edgentwks.append(out_file) if isdefined(self.inputs.out_edge_metrics_matlab): edge_out_file = op.abspath(self.inputs.out_edge_metrics_matlab) else: edge_out_file = op.abspath(self._gen_outfilename('edgemetrics', 'mat')) sio.savemat(edge_out_file, edge_measures, oned_as='column') matlab.append(edge_out_file) gpickled.extend(edgentwks) ntwk_measures = compute_network_measures(ntwk) for key in ntwk_measures.keys(): if key == 'k_core': out_file = op.abspath(self._gen_outfilename(self.inputs.out_k_core, 'pck')) if key == 'k_shell': out_file = op.abspath(self._gen_outfilename(self.inputs.out_k_shell, 'pck')) if key == 'k_crust': out_file = op.abspath(self._gen_outfilename(self.inputs.out_k_crust, 'pck')) nx.write_gpickle(ntwk_measures[key], out_file) kntwks.append(out_file) gpickled.extend(kntwks) out_pickled_extra_measures = op.abspath(self._gen_outfilename(self.inputs.out_pickled_extra_measures, 'pck')) dict_measures = compute_dict_measures(ntwk) iflogger.info('Saving extra measure file to {path} in Pickle format'.format(path=op.abspath(out_pickled_extra_measures))) file = open(out_pickled_extra_measures, 'w') pickle.dump(dict_measures, file) file.close() iflogger.info('Saving MATLAB measures as {m}'.format(m=matlab)) # Loops through the measures which return a dictionary, # converts the keys and values to a Numpy array, # stacks them together, and saves them in a MATLAB .mat file via Scipy global dicts dicts = list() for idx, key in enumerate(dict_measures.keys()): for idxd, keyd in enumerate(dict_measures[key].keys()): if idxd == 0: nparraykeys = np.array(keyd) nparrayvalues = np.array(dict_measures[key][keyd]) else: nparraykeys = np.append(nparraykeys, np.array(keyd)) values = np.array(dict_measures[key][keyd]) nparrayvalues = np.append(nparrayvalues, values) nparray = np.vstack((nparraykeys, nparrayvalues)) out_file = op.abspath(self._gen_outfilename(key, 'mat')) npdict = {} npdict[key] = nparray sio.savemat(out_file, npdict, oned_as='column') dicts.append(out_file) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs["k_core"] = op.abspath(self._gen_outfilename(self.inputs.out_k_core, 'pck')) outputs["k_shell"] = op.abspath(self._gen_outfilename(self.inputs.out_k_shell, 'pck')) outputs["k_crust"] = op.abspath(self._gen_outfilename(self.inputs.out_k_crust, 'pck')) outputs["gpickled_network_files"] = gpickled outputs["k_networks"] = kntwks outputs["node_measure_networks"] = nodentwks outputs["edge_measure_networks"] = edgentwks outputs["matlab_dict_measures"] = dicts outputs["global_measures_matlab"] = op.abspath(self._gen_outfilename('globalmetrics', 'mat')) outputs["node_measures_matlab"] = op.abspath(self._gen_outfilename('nodemetrics', 'mat')) outputs["edge_measures_matlab"] = op.abspath(self._gen_outfilename('edgemetrics', 'mat')) outputs["matlab_matrix_files"] = [outputs["global_measures_matlab"], outputs["node_measures_matlab"], outputs["edge_measures_matlab"]] outputs["pickled_extra_measures"] = op.abspath(self._gen_outfilename(self.inputs.out_pickled_extra_measures, 'pck')) return outputs def _gen_outfilename(self, name, ext): return name + '.' + ext class AverageNetworksInputSpec(BaseInterfaceInputSpec): in_files = InputMultiPath(File(exists=True), mandatory=True, desc='Networks for a group of subjects') resolution_network_file = File(exists=True, desc='Parcellation files from Connectome Mapping Toolkit. This is not necessary' \ ', but if included, the interface will output the statistical maps as networkx graphs.') group_id = traits.Str('group1', usedefault=True, desc='ID for group') out_gpickled_groupavg = File(desc='Average network saved as a NetworkX .pck') out_gexf_groupavg = File(desc='Average network saved as a .gexf file') class AverageNetworksOutputSpec(TraitedSpec): gpickled_groupavg = File(desc='Average network saved as a NetworkX .pck') gexf_groupavg = File(desc='Average network saved as a .gexf file') matlab_groupavgs = OutputMultiPath(File(desc='Average network saved as a .gexf file')) class AverageNetworks(BaseInterface): """ Calculates and outputs the average network given a set of input NetworkX gpickle files This interface will only keep an edge in the averaged network if that edge is present in at least half of the input networks. Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> avg = cmtk.AverageNetworks() >>> avg.inputs.in_files = ['subj1.pck', 'subj2.pck'] >>> avg.run() # doctest: +SKIP """ input_spec = AverageNetworksInputSpec output_spec = AverageNetworksOutputSpec def _run_interface(self, runtime): if isdefined(self.inputs.resolution_network_file): ntwk_res_file = self.inputs.resolution_network_file else: ntwk_res_file = self.inputs.in_files[0] global matlab_network_list network_name, matlab_network_list = average_networks(self.inputs.in_files, ntwk_res_file, self.inputs.group_id) return runtime def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_gpickled_groupavg): outputs["gpickled_groupavg"] = op.abspath(self._gen_outfilename(self.inputs.group_id + '_average', 'pck')) else: outputs["gpickled_groupavg"] = op.abspath(self.inputs.out_gpickled_groupavg) if not isdefined(self.inputs.out_gexf_groupavg): outputs["gexf_groupavg"] = op.abspath(self._gen_outfilename(self.inputs.group_id + '_average', 'gexf')) else: outputs["gexf_groupavg"] = op.abspath(self.inputs.out_gexf_groupavg) outputs["matlab_groupavgs"] = matlab_network_list return outputs def _gen_outfilename(self, name, ext): return name + '.' + ext nipype-0.11.0/nipype/interfaces/cmtk/parcellation.py000066400000000000000000000616211257611314500225240ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import ( BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, Directory, isdefined) import os import os.path as op import numpy as np import nibabel as nb import networkx as nx import shutil from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_cmp = True try: package_check('cmp') except Exception, e: have_cmp = False else: import cmp from cmp.util import runCmd def create_annot_label(subject_id, subjects_dir, fs_dir, parcellation_name): iflogger.info("Create the cortical labels necessary for our ROIs") iflogger.info("=================================================") fs_label_dir = op.join(op.join(subjects_dir, subject_id), 'label') output_dir = op.abspath(op.curdir) paths = [] cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" for hemi in ['lh', 'rh']: spath = cmp_config._get_lausanne_parcellation( 'Lausanne2008')[parcellation_name]['fs_label_subdir_name'] % hemi paths.append(spath) for p in paths: try: os.makedirs(op.join('.', p)) except: pass if '33' in parcellation_name: comp = [ ('rh', 'myatlas_36_rh.gcs', 'rh.myaparc_36.annot', 'regenerated_rh_36', 'myaparc_36'), ('rh', 'myatlas_60_rh.gcs', 'rh.myaparc_60.annot', 'regenerated_rh_60', 'myaparc_60'), ('lh', 'myatlas_36_lh.gcs', 'lh.myaparc_36.annot', 'regenerated_lh_36', 'myaparc_36'), ('lh', 'myatlas_60_lh.gcs', 'lh.myaparc_60.annot', 'regenerated_lh_60', 'myaparc_60'), ] elif '60' in parcellation_name: comp = [ ('rh', 'myatlas_60_rh.gcs', 'rh.myaparc_60.annot', 'regenerated_rh_60', 'myaparc_60'), ('lh', 'myatlas_60_lh.gcs', 'lh.myaparc_60.annot', 'regenerated_lh_60', 'myaparc_60'), ] elif '125' in parcellation_name: comp = [ ('rh', 'myatlas_125_rh.gcs', 'rh.myaparc_125.annot', 'regenerated_rh_125', 'myaparc_125'), ('rh', 'myatlas_60_rh.gcs', 'rh.myaparc_60.annot', 'regenerated_rh_60', 'myaparc_60'), ('lh', 'myatlas_125_lh.gcs', 'lh.myaparc_125.annot', 'regenerated_lh_125', 'myaparc_125'), ('lh', 'myatlas_60_lh.gcs', 'lh.myaparc_60.annot', 'regenerated_lh_60', 'myaparc_60'), ] elif '250' in parcellation_name: comp = [ ('rh', 'myatlas_250_rh.gcs', 'rh.myaparc_250.annot', 'regenerated_rh_250', 'myaparc_250'), ('rh', 'myatlas_60_rh.gcs', 'rh.myaparc_60.annot', 'regenerated_rh_60', 'myaparc_60'), ('lh', 'myatlas_250_lh.gcs', 'lh.myaparc_250.annot', 'regenerated_lh_250', 'myaparc_250'), ('lh', 'myatlas_60_lh.gcs', 'lh.myaparc_60.annot', 'regenerated_lh_60', 'myaparc_60'), ] else: comp = [ ('rh', 'myatlas_36_rh.gcs', 'rh.myaparc_36.annot', 'regenerated_rh_36', 'myaparc_36'), ('rh', 'myatlasP1_16_rh.gcs', 'rh.myaparcP1_16.annot', 'regenerated_rh_500', 'myaparcP1_16'), ('rh', 'myatlasP17_28_rh.gcs', 'rh.myaparcP17_28.annot', 'regenerated_rh_500', 'myaparcP17_28'), ('rh', 'myatlasP29_36_rh.gcs', 'rh.myaparcP29_36.annot', 'regenerated_rh_500', 'myaparcP29_36'), ('rh', 'myatlas_60_rh.gcs', 'rh.myaparc_60.annot', 'regenerated_rh_60', 'myaparc_60'), ('rh', 'myatlas_125_rh.gcs', 'rh.myaparc_125.annot', 'regenerated_rh_125', 'myaparc_125'), ('rh', 'myatlas_250_rh.gcs', 'rh.myaparc_250.annot', 'regenerated_rh_250', 'myaparc_250'), ('lh', 'myatlas_36_lh.gcs', 'lh.myaparc_36.annot', 'regenerated_lh_36', 'myaparc_36'), ('lh', 'myatlasP1_16_lh.gcs', 'lh.myaparcP1_16.annot', 'regenerated_lh_500', 'myaparcP1_16'), ('lh', 'myatlasP17_28_lh.gcs', 'lh.myaparcP17_28.annot', 'regenerated_lh_500', 'myaparcP17_28'), ('lh', 'myatlasP29_36_lh.gcs', 'lh.myaparcP29_36.annot', 'regenerated_lh_500', 'myaparcP29_36'), ('lh', 'myatlas_60_lh.gcs', 'lh.myaparc_60.annot', 'regenerated_lh_60', 'myaparc_60'), ('lh', 'myatlas_125_lh.gcs', 'lh.myaparc_125.annot', 'regenerated_lh_125', 'myaparc_125'), ('lh', 'myatlas_250_lh.gcs', 'lh.myaparc_250.annot', 'regenerated_lh_250', 'myaparc_250'), ] log = cmp_config.get_logger() for out in comp: mris_cmd = 'mris_ca_label %s %s "%s/surf/%s.sphere.reg" "%s" "%s" ' % (subject_id, out[0], op.join(subjects_dir, subject_id), out[0], cmp_config.get_lausanne_atlas(out[1]), op.join(fs_label_dir, out[2])) runCmd(mris_cmd, log) iflogger.info('-----------') annot = '--annotation "%s"' % out[4] mri_an_cmd = 'mri_annotation2label --subject %s --hemi %s --outdir "%s" %s' % (subject_id, out[0], op.join(output_dir, out[3]), annot) iflogger.info(mri_an_cmd) runCmd(mri_an_cmd, log) iflogger.info('-----------') iflogger.info(os.environ['SUBJECTS_DIR']) # extract cc and unknown to add to tractography mask, we do not want this as a region of interest # in FS 5.0, unknown and corpuscallosum are not available for the 35 scale (why?), # but for the other scales only, take the ones from _60 rhun = op.join(output_dir, 'rh.unknown.label') lhun = op.join(output_dir, 'lh.unknown.label') rhco = op.join(output_dir, 'rh.corpuscallosum.label') lhco = op.join(output_dir, 'lh.corpuscallosum.label') shutil.copy( op.join(output_dir, 'regenerated_rh_60', 'rh.unknown.label'), rhun) shutil.copy( op.join(output_dir, 'regenerated_lh_60', 'lh.unknown.label'), lhun) shutil.copy(op.join( output_dir, 'regenerated_rh_60', 'rh.corpuscallosum.label'), rhco) shutil.copy(op.join( output_dir, 'regenerated_lh_60', 'lh.corpuscallosum.label'), lhco) mri_cmd = """mri_label2vol --label "%s" --label "%s" --label "%s" --label "%s" --temp "%s" --o "%s" --identity """ % (rhun, lhun, rhco, lhco, op.join(op.join(subjects_dir, subject_id), 'mri', 'orig.mgz'), op.join(fs_label_dir, 'cc_unknown.nii.gz') ) runCmd(mri_cmd, log) runCmd('mris_volmask %s' % subject_id, log) mri_cmd = 'mri_convert -i "%s/mri/ribbon.mgz" -o "%s/mri/ribbon.nii.gz"' % (op.join(subjects_dir, subject_id), op.join(subjects_dir, subject_id)) runCmd(mri_cmd, log) mri_cmd = 'mri_convert -i "%s/mri/aseg.mgz" -o "%s/mri/aseg.nii.gz"' % ( op.join(subjects_dir, subject_id), op.join(subjects_dir, subject_id)) runCmd(mri_cmd, log) iflogger.info("[ DONE ]") def create_roi(subject_id, subjects_dir, fs_dir, parcellation_name, dilation): """ Creates the ROI_%s.nii.gz files using the given parcellation information from networks. Iteratively create volume. """ iflogger.info("Create the ROIs:") output_dir = op.abspath(op.curdir) fs_dir = op.join(subjects_dir, subject_id) cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" log = cmp_config.get_logger() parval = cmp_config._get_lausanne_parcellation( 'Lausanne2008')[parcellation_name] pgpath = parval['node_information_graphml'] aseg = nb.load(op.join(fs_dir, 'mri', 'aseg.nii.gz')) asegd = aseg.get_data() # identify cortical voxels, right (3) and left (42) hemispheres idxr = np.where(asegd == 3) idxl = np.where(asegd == 42) xx = np.concatenate((idxr[0], idxl[0])) yy = np.concatenate((idxr[1], idxl[1])) zz = np.concatenate((idxr[2], idxl[2])) # initialize variables necessary for cortical ROIs dilation # dimensions of the neighbourhood for rois labels assignment (choose odd dimensions!) shape = (25, 25, 25) center = np.array(shape) // 2 # dist: distances from the center of the neighbourhood dist = np.zeros(shape, dtype='float32') for x in range(shape[0]): for y in range(shape[1]): for z in range(shape[2]): distxyz = center - [x, y, z] dist[x, y, z] = np.sqrt(np.sum(np.multiply(distxyz, distxyz))) iflogger.info("Working on parcellation: ") iflogger.info(cmp_config._get_lausanne_parcellation( 'Lausanne2008')[parcellation_name]) iflogger.info("========================") pg = nx.read_graphml(pgpath) # each node represents a brain region # create a big 256^3 volume for storage of all ROIs rois = np.zeros((256, 256, 256), dtype=np.int16) count = 0 for brk, brv in pg.nodes_iter(data=True): count = count + 1 iflogger.info(brv) iflogger.info(brk) if brv['dn_hemisphere'] == 'left': hemi = 'lh' elif brv['dn_hemisphere'] == 'right': hemi = 'rh' if brv['dn_region'] == 'subcortical': iflogger.info(brv) iflogger.info("---------------------") iflogger.info("Work on brain region: %s" % (brv['dn_region'])) iflogger.info("Freesurfer Name: %s" % brv['dn_fsname']) iflogger.info("Region %s of %s " % (count, pg.number_of_nodes())) iflogger.info("---------------------") # if it is subcortical, retrieve roi from aseg idx = np.where(asegd == int(brv['dn_fs_aseg_val'])) rois[idx] = int(brv['dn_correspondence_id']) elif brv['dn_region'] == 'cortical': iflogger.info(brv) iflogger.info("---------------------") iflogger.info("Work on brain region: %s" % (brv['dn_region'])) iflogger.info("Freesurfer Name: %s" % brv['dn_fsname']) iflogger.info("Region %s of %s " % (count, pg.number_of_nodes())) iflogger.info("---------------------") labelpath = op.join( output_dir, parval['fs_label_subdir_name'] % hemi) # construct .label file name fname = '%s.%s.label' % (hemi, brv['dn_fsname']) # execute fs mri_label2vol to generate volume roi from the label file # store it in temporary file to be overwritten for each region mri_cmd = 'mri_label2vol --label "%s" --temp "%s" --o "%s" --identity' % (op.join(labelpath, fname), op.join(fs_dir, 'mri', 'orig.mgz'), op.join(output_dir, 'tmp.nii.gz')) runCmd(mri_cmd, log) tmp = nb.load(op.join(output_dir, 'tmp.nii.gz')) tmpd = tmp.get_data() # find voxel and set them to intensityvalue in rois idx = np.where(tmpd == 1) rois[idx] = int(brv['dn_correspondence_id']) # store volume eg in ROI_scale33.nii.gz out_roi = op.abspath('ROI_%s.nii.gz' % parcellation_name) # update the header hdr = aseg.get_header() hdr2 = hdr.copy() hdr2.set_data_dtype(np.uint16) log.info("Save output image to %s" % out_roi) img = nb.Nifti1Image(rois, aseg.get_affine(), hdr2) nb.save(img, out_roi) iflogger.info("[ DONE ]") # dilate cortical regions if (dilation == True): iflogger.info("Dilating cortical regions...") # loop throughout all the voxels belonging to the aseg GM volume for j in range(xx.size): if rois[xx[j], yy[j], zz[j]] == 0: local = extract( rois, shape, position=(xx[j], yy[j], zz[j]), fill=0) mask = local.copy() mask[np.nonzero(local > 0)] = 1 thisdist = np.multiply(dist, mask) thisdist[np.nonzero(thisdist == 0)] = np.amax(thisdist) value = np.int_( local[np.nonzero(thisdist == np.amin(thisdist))]) if value.size > 1: counts = np.bincount(value) value = np.argmax(counts) rois[xx[j], yy[j], zz[j]] = value # store volume eg in ROIv_scale33.nii.gz out_roi = op.abspath('ROIv_%s.nii.gz' % parcellation_name) iflogger.info("Save output image to %s" % out_roi) img = nb.Nifti1Image(rois, aseg.get_affine(), hdr2) nb.save(img, out_roi) iflogger.info("[ DONE ]") def create_wm_mask(subject_id, subjects_dir, fs_dir, parcellation_name): iflogger.info("Create white matter mask") fs_dir = op.join(subjects_dir, subject_id) cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" pgpath = cmp_config._get_lausanne_parcellation( 'Lausanne2008')[parcellation_name]['node_information_graphml'] # load ribbon as basis for white matter mask fsmask = nb.load(op.join(fs_dir, 'mri', 'ribbon.nii.gz')) fsmaskd = fsmask.get_data() wmmask = np.zeros(fsmaskd.shape) # extract right and left white matter idx_lh = np.where(fsmaskd == 120) idx_rh = np.where(fsmaskd == 20) wmmask[idx_lh] = 1 wmmask[idx_rh] = 1 # remove subcortical nuclei from white matter mask aseg = nb.load(op.join(fs_dir, 'mri', 'aseg.nii.gz')) asegd = aseg.get_data() try: import scipy.ndimage.morphology as nd except ImportError: raise Exception('Need scipy for binary erosion of white matter mask') # need binary erosion function imerode = nd.binary_erosion # ventricle erosion csfA = np.zeros(asegd.shape) csfB = np.zeros(asegd.shape) # structuring elements for erosion se1 = np.zeros((3, 3, 5)) se1[1, :, 2] = 1 se1[:, 1, 2] = 1 se1[1, 1, :] = 1 se = np.zeros((3, 3, 3)) se[1, :, 1] = 1 se[:, 1, 1] = 1 se[1, 1, :] = 1 # lateral ventricles, thalamus proper and caudate # the latter two removed for better erosion, but put back afterwards idx = np.where((asegd == 4) | (asegd == 43) | (asegd == 11) | (asegd == 50) | (asegd == 31) | (asegd == 63) | (asegd == 10) | (asegd == 49)) csfA[idx] = 1 csfA = imerode(imerode(csfA, se1), se) # thalmus proper and cuadate are put back because they are not lateral ventricles idx = np.where((asegd == 11) | (asegd == 50) | (asegd == 10) | (asegd == 49)) csfA[idx] = 0 # REST CSF, IE 3RD AND 4TH VENTRICULE AND EXTRACEREBRAL CSF idx = np.where((asegd == 5) | (asegd == 14) | (asegd == 15) | (asegd == 24) | (asegd == 44) | (asegd == 72) | (asegd == 75) | (asegd == 76) | (asegd == 213) | (asegd == 221)) # 43 ??, 4?? 213?, 221? # more to discuss. for i in [5, 14, 15, 24, 44, 72, 75, 76, 213, 221]: idx = np.where(asegd == i) csfB[idx] = 1 # do not remove the subthalamic nucleus for now from the wm mask # 23, 60 # would stop the fiber going to the segmented "brainstem" # grey nuclei, either with or without erosion gr_ncl = np.zeros(asegd.shape) # with erosion for i in [10, 11, 12, 49, 50, 51]: idx = np.where(asegd == i) # temporary volume tmp = np.zeros(asegd.shape) tmp[idx] = 1 tmp = imerode(tmp, se) idx = np.where(tmp == 1) gr_ncl[idx] = 1 # without erosion for i in [13, 17, 18, 26, 52, 53, 54, 58]: idx = np.where(asegd == i) gr_ncl[idx] = 1 # remove remaining structure, e.g. brainstem remaining = np.zeros(asegd.shape) idx = np.where(asegd == 16) remaining[idx] = 1 # now remove all the structures from the white matter idx = np.where( (csfA != 0) | (csfB != 0) | (gr_ncl != 0) | (remaining != 0)) wmmask[idx] = 0 iflogger.info("Removing lateral ventricles and eroded grey nuclei and brainstem from white matter mask") # ADD voxels from 'cc_unknown.nii.gz' dataset ccun = nb.load(op.join(fs_dir, 'label', 'cc_unknown.nii.gz')) ccund = ccun.get_data() idx = np.where(ccund != 0) iflogger.info("Add corpus callosum and unknown to wm mask") wmmask[idx] = 1 # check if we should subtract the cortical rois from this parcellation iflogger.info("Loading %s to subtract cortical ROIs from white matter mask" % ('ROI_%s.nii.gz' % parcellation_name)) roi = nb.load(op.join(op.curdir, 'ROI_%s.nii.gz' % parcellation_name)) roid = roi.get_data() assert roid.shape[0] == wmmask.shape[0] pg = nx.read_graphml(pgpath) for brk, brv in pg.nodes_iter(data=True): if brv['dn_region'] == 'cortical': iflogger.info("Subtracting region %s with intensity value %s" % (brv['dn_region'], brv['dn_correspondence_id'])) idx = np.where(roid == int(brv['dn_correspondence_id'])) wmmask[idx] = 0 # output white matter mask. crop and move it afterwards wm_out = op.join(fs_dir, 'mri', 'fsmask_1mm.nii.gz') img = nb.Nifti1Image(wmmask, fsmask.get_affine(), fsmask.get_header()) iflogger.info("Save white matter mask: %s" % wm_out) nb.save(img, wm_out) def crop_and_move_datasets(subject_id, subjects_dir, fs_dir, parcellation_name, out_roi_file,dilation): fs_dir = op.join(subjects_dir, subject_id) cmp_config = cmp.configuration.PipelineConfiguration() cmp_config.parcellation_scheme = "Lausanne2008" log = cmp_config.get_logger() output_dir = op.abspath(op.curdir) iflogger.info("Cropping and moving datasets to %s" % output_dir) ds = [ (op.join(fs_dir, 'mri', 'aseg.nii.gz'), op.abspath('aseg.nii.gz')), (op.join(fs_dir, 'mri', 'ribbon.nii.gz'), op.abspath('ribbon.nii.gz')), (op.join(fs_dir, 'mri', 'fsmask_1mm.nii.gz'), op.abspath('fsmask_1mm.nii.gz')), (op.join(fs_dir, 'label', 'cc_unknown.nii.gz'), op.abspath('cc_unknown.nii.gz')) ] ds.append((op.abspath('ROI_%s.nii.gz' % parcellation_name), op.abspath('ROI_HR_th.nii.gz'))) if(dilation==True): ds.append((op.abspath('ROIv_%s.nii.gz' % parcellation_name), op.abspath('ROIv_HR_th.nii.gz'))) orig = op.join(fs_dir, 'mri', 'orig', '001.mgz') for d in ds: iflogger.info("Processing %s:" % d[0]) if not op.exists(d[0]): raise Exception('File %s does not exist.' % d[0]) # reslice to original volume because the roi creation with freesurfer # changed to 256x256x256 resolution mri_cmd = 'mri_convert -rl "%s" -rt nearest "%s" -nc "%s"' % ( orig, d[0], d[1]) runCmd(mri_cmd, log) def extract(Z, shape, position, fill): """ Extract voxel neighbourhood Parameters ---------- Z: the original data shape: tuple containing neighbourhood dimensions position: tuple containing central point indexes fill: value for the padding of Z Returns ------- R: the neighbourhood of the specified point in Z """ R = np.ones(shape, dtype=Z.dtype) * \ fill # initialize output block to the fill value P = np.array( list(position)).astype(int) # position coordinates(numpy array) Rs = np.array( list(R.shape)).astype(int) # output block dimensions (numpy array) Zs = np.array( list(Z.shape)).astype(int) # original volume dimensions (numpy array) R_start = np.zeros(len(shape)).astype(int) R_stop = np.array(list(shape)).astype(int) Z_start = (P - Rs // 2) Z_start_cor = (np.maximum(Z_start, 0)).tolist() # handle borders R_start = R_start + (Z_start_cor - Z_start) Z_stop = (P + Rs // 2) + Rs % 2 Z_stop_cor = (np.minimum(Z_stop, Zs)).tolist() # handle borders R_stop = R_stop - (Z_stop - Z_stop_cor) R[R_start[0]:R_stop[0], R_start[1]:R_stop[1], R_start[2]:R_stop[2]] = Z[Z_start_cor[0]:Z_stop_cor[0], Z_start_cor[1]:Z_stop_cor[1], Z_start_cor[2]:Z_stop_cor[2]] return R class ParcellateInputSpec(BaseInterfaceInputSpec): subject_id = traits.String(mandatory=True, desc='Subject ID') parcellation_name = traits.Enum('scale500', ['scale33', 'scale60', 'scale125', 'scale250', 'scale500'], usedefault=True) freesurfer_dir = Directory(exists=True, desc='Freesurfer main directory') subjects_dir = Directory(exists=True, desc='Freesurfer subjects directory') out_roi_file = File( genfile=True, desc='Region of Interest file for connectivity mapping') dilation = traits.Bool(False, usedefault=True, desc='Dilate cortical parcels? Useful for fMRI connectivity') class ParcellateOutputSpec(TraitedSpec): roi_file = File( exists=True, desc='Region of Interest file for connectivity mapping') roiv_file = File(desc='Region of Interest file for fMRI connectivity mapping') white_matter_mask_file = File(exists=True, desc='White matter mask file') cc_unknown_file = File( desc='Image file with regions labelled as unknown cortical structures', exists=True) ribbon_file = File(desc='Image file detailing the cortical ribbon', exists=True) aseg_file = File( desc='Automated segmentation file converted from Freesurfer "subjects" directory', exists=True) roi_file_in_structural_space = File( desc='ROI image resliced to the dimensions of the original structural image', exists=True) dilated_roi_file_in_structural_space = File( desc='dilated ROI image resliced to the dimensions of the original structural image') class Parcellate(BaseInterface): """Subdivides segmented ROI file into smaller subregions This interface implements the same procedure as in the ConnectomeMapper's parcellation stage (cmp/stages/parcellation/maskcreation.py) for a single parcellation scheme (e.g. 'scale500'). Example ------- >>> import nipype.interfaces.cmtk as cmtk >>> parcellate = cmtk.Parcellate() >>> parcellate.inputs.freesurfer_dir = '.' >>> parcellate.inputs.subjects_dir = '.' >>> parcellate.inputs.subject_id = 'subj1' >>> parcellate.inputs.dilation = True >>> parcellate.inputs.parcellation_name = 'scale500' >>> parcellate.run() # doctest: +SKIP """ input_spec = ParcellateInputSpec output_spec = ParcellateOutputSpec def _run_interface(self, runtime): if self.inputs.subjects_dir: os.environ.update({'SUBJECTS_DIR': self.inputs.subjects_dir}) if not os.path.exists(op.join(self.inputs.subjects_dir, self.inputs.subject_id)): raise Exception iflogger.info("ROI_HR_th.nii.gz / fsmask_1mm.nii.gz CREATION") iflogger.info("=============================================") create_annot_label(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name) create_roi(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name, self.inputs.dilation) create_wm_mask(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name) crop_and_move_datasets(self.inputs.subject_id, self.inputs.subjects_dir, self.inputs.freesurfer_dir, self.inputs.parcellation_name, self.inputs.out_roi_file,self.inputs.dilation) return runtime def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.out_roi_file): outputs['roi_file'] = op.abspath(self.inputs.out_roi_file) else: outputs['roi_file'] = op.abspath( self._gen_outfilename('nii.gz', 'ROI')) if(self.inputs.dilation==True): outputs['roiv_file'] = op.abspath(self._gen_outfilename( 'nii.gz', 'ROIv')) outputs['white_matter_mask_file'] = op.abspath('fsmask_1mm.nii.gz') outputs['cc_unknown_file'] = op.abspath('cc_unknown.nii.gz') outputs['ribbon_file'] = op.abspath('ribbon.nii.gz') outputs['aseg_file'] = op.abspath('aseg.nii.gz') outputs['roi_file_in_structural_space'] = op.abspath( 'ROI_HR_th.nii.gz') if(self.inputs.dilation==True): outputs['dilated_roi_file_in_structural_space'] = op.abspath( 'ROIv_HR_th.nii.gz') return outputs def _gen_outfilename(self, ext, prefix='ROI'): return prefix + '_' + self.inputs.parcellation_name + '.' + ext nipype-0.11.0/nipype/interfaces/cmtk/tests/000077500000000000000000000000001257611314500206315ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_AverageNetworks.py000066400000000000000000000020121257611314500263740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.nx import AverageNetworks def test_AverageNetworks_inputs(): input_map = dict(group_id=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(mandatory=True, ), out_gexf_groupavg=dict(), out_gpickled_groupavg=dict(), resolution_network_file=dict(), ) inputs = AverageNetworks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AverageNetworks_outputs(): output_map = dict(gexf_groupavg=dict(), gpickled_groupavg=dict(), matlab_groupavgs=dict(), ) outputs = AverageNetworks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_CFFConverter.py000066400000000000000000000024371257611314500255660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.convert import CFFConverter def test_CFFConverter_inputs(): input_map = dict(creator=dict(), data_files=dict(), description=dict(usedefault=True, ), email=dict(), gifti_labels=dict(), gifti_surfaces=dict(), gpickled_networks=dict(), graphml_networks=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), license=dict(), nifti_volumes=dict(), out_file=dict(usedefault=True, ), publisher=dict(), references=dict(), relation=dict(), rights=dict(), script_files=dict(), species=dict(usedefault=True, ), timeseries_files=dict(), title=dict(), tract_files=dict(), ) inputs = CFFConverter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CFFConverter_outputs(): output_map = dict(connectome_file=dict(), ) outputs = CFFConverter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_CreateMatrix.py000066400000000000000000000036061257611314500256670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.cmtk import CreateMatrix def test_CreateMatrix_inputs(): input_map = dict(count_region_intersections=dict(usedefault=True, ), out_endpoint_array_name=dict(genfile=True, ), out_fiber_length_std_matrix_mat_file=dict(genfile=True, ), out_intersection_matrix_mat_file=dict(genfile=True, ), out_matrix_file=dict(genfile=True, ), out_matrix_mat_file=dict(usedefault=True, ), out_mean_fiber_length_matrix_mat_file=dict(genfile=True, ), out_median_fiber_length_matrix_mat_file=dict(genfile=True, ), resolution_network_file=dict(mandatory=True, ), roi_file=dict(mandatory=True, ), tract_file=dict(mandatory=True, ), ) inputs = CreateMatrix.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CreateMatrix_outputs(): output_map = dict(endpoint_file=dict(), endpoint_file_mm=dict(), fiber_label_file=dict(), fiber_labels_noorphans=dict(), fiber_length_file=dict(), fiber_length_std_matrix_mat_file=dict(), filtered_tractographies=dict(), filtered_tractography=dict(), filtered_tractography_by_intersections=dict(), intersection_matrix_file=dict(), intersection_matrix_mat_file=dict(), matlab_matrix_files=dict(), matrix_file=dict(), matrix_files=dict(), matrix_mat_file=dict(), mean_fiber_length_matrix_mat_file=dict(), median_fiber_length_matrix_mat_file=dict(), stats_file=dict(), ) outputs = CreateMatrix.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_CreateNodes.py000066400000000000000000000016241257611314500254710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.cmtk import CreateNodes def test_CreateNodes_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), out_filename=dict(usedefault=True, ), resolution_network_file=dict(mandatory=True, ), roi_file=dict(mandatory=True, ), ) inputs = CreateNodes.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CreateNodes_outputs(): output_map = dict(node_network=dict(), ) outputs = CreateNodes.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_MergeCNetworks.py000066400000000000000000000015551257611314500261770ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.convert import MergeCNetworks def test_MergeCNetworks_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(mandatory=True, ), out_file=dict(usedefault=True, ), ) inputs = MergeCNetworks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MergeCNetworks_outputs(): output_map = dict(connectome_file=dict(), ) outputs = MergeCNetworks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_NetworkBasedStatistic.py000066400000000000000000000023241257611314500275530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.nbs import NetworkBasedStatistic def test_NetworkBasedStatistic_inputs(): input_map = dict(edge_key=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_group1=dict(mandatory=True, ), in_group2=dict(mandatory=True, ), node_position_network=dict(), number_of_permutations=dict(usedefault=True, ), out_nbs_network=dict(), out_nbs_pval_network=dict(), t_tail=dict(usedefault=True, ), threshold=dict(usedefault=True, ), ) inputs = NetworkBasedStatistic.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NetworkBasedStatistic_outputs(): output_map = dict(nbs_network=dict(), nbs_pval_network=dict(), network_files=dict(), ) outputs = NetworkBasedStatistic.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_NetworkXMetrics.py000066400000000000000000000032101257611314500263760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.nx import NetworkXMetrics def test_NetworkXMetrics_inputs(): input_map = dict(compute_clique_related_measures=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), out_edge_metrics_matlab=dict(genfile=True, ), out_global_metrics_matlab=dict(genfile=True, ), out_k_core=dict(usedefault=True, ), out_k_crust=dict(usedefault=True, ), out_k_shell=dict(usedefault=True, ), out_node_metrics_matlab=dict(genfile=True, ), out_pickled_extra_measures=dict(usedefault=True, ), treat_as_weighted_graph=dict(usedefault=True, ), ) inputs = NetworkXMetrics.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NetworkXMetrics_outputs(): output_map = dict(edge_measure_networks=dict(), edge_measures_matlab=dict(), global_measures_matlab=dict(), gpickled_network_files=dict(), k_core=dict(), k_crust=dict(), k_networks=dict(), k_shell=dict(), matlab_dict_measures=dict(), matlab_matrix_files=dict(), node_measure_networks=dict(), node_measures_matlab=dict(), pickled_extra_measures=dict(), ) outputs = NetworkXMetrics.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_Parcellate.py000066400000000000000000000023101257611314500253420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.parcellation import Parcellate def test_Parcellate_inputs(): input_map = dict(dilation=dict(usedefault=True, ), freesurfer_dir=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), out_roi_file=dict(genfile=True, ), parcellation_name=dict(usedefault=True, ), subject_id=dict(mandatory=True, ), subjects_dir=dict(), ) inputs = Parcellate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Parcellate_outputs(): output_map = dict(aseg_file=dict(), cc_unknown_file=dict(), dilated_roi_file_in_structural_space=dict(), ribbon_file=dict(), roi_file=dict(), roi_file_in_structural_space=dict(), roiv_file=dict(), white_matter_mask_file=dict(), ) outputs = Parcellate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/cmtk/tests/test_auto_ROIGen.py000066400000000000000000000020571257611314500243610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.cmtk.cmtk import ROIGen def test_ROIGen_inputs(): input_map = dict(LUT_file=dict(xor=['use_freesurfer_LUT'], ), aparc_aseg_file=dict(mandatory=True, ), freesurfer_dir=dict(requires=['use_freesurfer_LUT'], ), ignore_exception=dict(nohash=True, usedefault=True, ), out_dict_file=dict(genfile=True, ), out_roi_file=dict(genfile=True, ), use_freesurfer_LUT=dict(xor=['LUT_file'], ), ) inputs = ROIGen.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ROIGen_outputs(): output_map = dict(dict_file=dict(), roi_file=dict(), ) outputs = ROIGen.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dcm2nii.py000066400000000000000000000161361257611314500204370ustar00rootroot00000000000000"""The dcm2nii module provides basic functions for dicom conversion Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (CommandLine, CommandLineInputSpec, InputMultiPath, traits, TraitedSpec, OutputMultiPath, isdefined, File, Directory) import os from copy import deepcopy from nipype.utils.filemanip import split_filename import re class Dcm2niiInputSpec(CommandLineInputSpec): source_names = InputMultiPath(File(exists=True), argstr="%s", position=-1, copyfile=False, mandatory=True, xor=['source_dir']) source_dir = Directory(exists=True, argstr="%s", position=-1, mandatory=True, xor=['source_names']) anonymize = traits.Bool(True, argstr='-a', usedefault=True) config_file = File(exists=True, argstr="-b %s", genfile=True) collapse_folders = traits.Bool(True, argstr='-c', usedefault=True) date_in_filename = traits.Bool(True, argstr='-d', usedefault=True) events_in_filename = traits.Bool(True, argstr='-e', usedefault=True) source_in_filename = traits.Bool(False, argstr='-f', usedefault=True) gzip_output = traits.Bool(False, argstr='-g', usedefault=True) id_in_filename = traits.Bool(False, argstr='-i', usedefault=True) nii_output = traits.Bool(True, argstr='-n', usedefault=True) output_dir = Directory(exists=True, argstr='-o %s', genfile=True) protocol_in_filename = traits.Bool(True, argstr='-p', usedefault=True) reorient = traits.Bool(argstr='-r') spm_analyze = traits.Bool(argstr='-s', xor=['nii_output']) convert_all_pars = traits.Bool(True, argstr='-v', usedefault=True) reorient_and_crop = traits.Bool(False, argstr='-x', usedefault=True) class Dcm2niiOutputSpec(TraitedSpec): converted_files = OutputMultiPath(File(exists=True)) reoriented_files = OutputMultiPath(File(exists=True)) reoriented_and_cropped_files = OutputMultiPath(File(exists=True)) bvecs = OutputMultiPath(File(exists=True)) bvals = OutputMultiPath(File(exists=True)) class Dcm2nii(CommandLine): """Uses MRICRON's dcm2nii to convert dicom files Examples ======== >>> from nipype.interfaces.dcm2nii import Dcm2nii >>> converter = Dcm2nii() >>> converter.inputs.source_names = ['functional_1.dcm', 'functional_2.dcm'] >>> converter.inputs.gzip_output = True >>> converter.inputs.output_dir = '.' >>> converter.cmdline 'dcm2nii -a y -c y -b config.ini -v y -d y -e y -g y -i n -n y -o . -p y -x n -f n functional_1.dcm' """ input_spec = Dcm2niiInputSpec output_spec = Dcm2niiOutputSpec _cmd = 'dcm2nii' def _format_arg(self, opt, spec, val): if opt in ['anonymize', 'collapse_folders', 'date_in_filename', 'events_in_filename', 'source_in_filename', 'gzip_output', 'id_in_filename', 'nii_output', 'protocol_in_filename', 'reorient', 'spm_analyze', 'convert_all_pars', 'reorient_and_crop']: spec = deepcopy(spec) if val: spec.argstr += ' y' else: spec.argstr += ' n' val = True if opt == 'source_names': return spec.argstr % val[0] return super(Dcm2nii, self)._format_arg(opt, spec, val) def _run_interface(self, runtime): self._config_created = False new_runtime = super(Dcm2nii, self)._run_interface(runtime) (self.output_files, self.reoriented_files, self.reoriented_and_cropped_files, self.bvecs, self.bvals) = self._parse_stdout(new_runtime.stdout) if self._config_created: os.remove('config.ini') return new_runtime def _parse_stdout(self, stdout): files = [] reoriented_files = [] reoriented_and_cropped_files = [] bvecs = [] bvals = [] skip = False last_added_file = None for line in stdout.split("\n"): if not skip: out_file = None if line.startswith("Saving "): out_file = line[len("Saving "):] elif line.startswith("GZip..."): # for gzipped outpus files are not absolute if isdefined(self.inputs.output_dir): output_dir = self.inputs.output_dir else: output_dir = self._gen_filename('output_dir') out_file = os.path.abspath(os.path.join(output_dir, line[len("GZip..."):])) elif line.startswith("Number of diffusion directions "): if last_added_file: base, filename, ext = split_filename(last_added_file) bvecs.append(os.path.join(base, filename + ".bvec")) bvals.append(os.path.join(base, filename + ".bval")) elif re.search('.*-->(.*)', line): val = re.search('.*-->(.*)', line) val = val.groups()[0] if isdefined(self.inputs.output_dir): output_dir = self.inputs.output_dir else: output_dir = self._gen_filename('output_dir') val = os.path.join(output_dir, val) out_file = val if out_file: files.append(out_file) last_added_file = out_file continue if line.startswith("Reorienting as "): reoriented_files.append(line[len("Reorienting as "):]) skip = True continue elif line.startswith("Cropping NIfTI/Analyze image "): base, filename = os.path.split(line[len("Cropping NIfTI/Analyze image "):]) filename = "c" + filename reoriented_and_cropped_files.append(os.path.join(base, filename)) skip = True continue skip = False return files, reoriented_files, reoriented_and_cropped_files, bvecs, bvals def _list_outputs(self): outputs = self.output_spec().get() outputs['converted_files'] = self.output_files outputs['reoriented_files'] = self.reoriented_files outputs['reoriented_and_cropped_files'] = self.reoriented_and_cropped_files outputs['bvecs'] = self.bvecs outputs['bvals'] = self.bvals return outputs def _gen_filename(self, name): if name == 'output_dir': return os.getcwd() elif name == 'config_file': self._config_created = True config_file = "config.ini" f = open(config_file, "w") # disable interactive mode f.write("[BOOL]\nManualNIfTIConv=0\n") f.close() return config_file return None nipype-0.11.0/nipype/interfaces/dcmstack.py000066400000000000000000000360051257611314500207000ustar00rootroot00000000000000"""Provides interfaces to various commands provided by dcmstack Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from __future__ import absolute_import import os import string import errno from os import path as op from glob import glob from nipype.interfaces.base import (TraitedSpec, DynamicTraitedSpec, InputMultiPath, File, Directory, traits, BaseInterface, ) import nibabel as nb from nipype.interfaces.traits_extension import isdefined, Undefined import imghdr from nipype.external import six have_dcmstack = True try: import dicom import dcmstack from dcmstack.dcmmeta import NiftiWrapper except ImportError: have_dcmstack = False def sanitize_path_comp(path_comp): result = [] for char in path_comp: if not char in string.letters + string.digits + '-_.': result.append('_') else: result.append(char) return ''.join(result) class NiftiGeneratorBaseInputSpec(TraitedSpec): out_format = traits.Str(desc="String which can be formatted with " "meta data to create the output filename(s)") out_ext = traits.Str('.nii.gz', usedefault=True, desc="Determines output file type") out_path = Directory(desc='output path, current working directory if not set') class NiftiGeneratorBase(BaseInterface): '''Base class for interfaces that produce Nifti files, potentially with embedded meta data.''' def _get_out_path(self, meta, idx=None): '''Return the output path for the gernerated Nifti.''' if self.inputs.out_format: out_fmt = self.inputs.out_format else: #If no out_format is specified, use a sane default that will work #with the provided meta data. out_fmt = [] if not idx is None: out_fmt.append('%03d' % idx) if 'SeriesNumber' in meta: out_fmt.append('%(SeriesNumber)03d') if 'ProtocolName' in meta: out_fmt.append('%(ProtocolName)s') elif 'SeriesDescription' in meta: out_fmt.append('%(SeriesDescription)s') else: out_fmt.append('sequence') out_fmt = '-'.join(out_fmt) out_fn = (out_fmt % meta) + self.inputs.out_ext out_fn = sanitize_path_comp(out_fn) out_path = os.getcwd() if isdefined(self.inputs.out_path): out_path = op.abspath(self.inputs.out_path) # now, mkdir -p $out_path try: os.makedirs(out_path) except OSError as exc: # Python >2.5 if exc.errno == errno.EEXIST and op.isdir(out_path): pass else: raise return op.join(out_path, out_fn) class DcmStackInputSpec(NiftiGeneratorBaseInputSpec): dicom_files = traits.Either(InputMultiPath(File(exists=True)), Directory(exists=True), traits.Str(), mandatory=True) embed_meta = traits.Bool(desc="Embed DICOM meta data into result") exclude_regexes = traits.List(desc="Meta data to exclude, suplementing " "any default exclude filters") include_regexes = traits.List(desc="Meta data to include, overriding any " "exclude filters") force_read = traits.Bool(True, usedefault=True, desc=('Force reading files without DICM marker')) class DcmStackOutputSpec(TraitedSpec): out_file = File(exists=True) class DcmStack(NiftiGeneratorBase): '''Create one Nifti file from a set of DICOM files. Can optionally embed meta data. Example ------- >>> from nipype.interfaces.dcmstack import DcmStack >>> stacker = DcmStack() >>> stacker.inputs.dicom_files = 'path/to/series/' >>> stacker.run() # doctest: +SKIP >>> result.outputs.out_file # doctest: +SKIP '/path/to/cwd/sequence.nii.gz' ''' input_spec = DcmStackInputSpec output_spec = DcmStackOutputSpec def _get_filelist(self, trait_input): if isinstance(trait_input, six.string_types): if op.isdir(trait_input): return glob(op.join(trait_input, '*.dcm')) else: return glob(trait_input) return trait_input def _run_interface(self, runtime): src_paths = self._get_filelist(self.inputs.dicom_files) include_regexes = dcmstack.default_key_incl_res if isdefined(self.inputs.include_regexes): include_regexes += self.inputs.include_regexes exclude_regexes = dcmstack.default_key_excl_res if isdefined(self.inputs.exclude_regexes): exclude_regexes += self.inputs.exclude_regexes meta_filter = dcmstack.make_key_regex_filter(exclude_regexes, include_regexes) stack = dcmstack.DicomStack(meta_filter=meta_filter) for src_path in src_paths: if not imghdr.what(src_path)=="gif": src_dcm = dicom.read_file(src_path, force=self.inputs.force_read) stack.add_dcm(src_dcm) nii = stack.to_nifti(embed_meta=True) nw = NiftiWrapper(nii) self.out_path = \ self._get_out_path(nw.meta_ext.get_class_dict(('global', 'const'))) if not self.inputs.embed_meta: nw.remove_extension() nb.save(nii, self.out_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = self.out_path return outputs class GroupAndStackOutputSpec(TraitedSpec): out_list = traits.List(desc="List of output nifti files") class GroupAndStack(DcmStack): '''Create (potentially) multiple Nifti files for a set of DICOM files. ''' input_spec = DcmStackInputSpec output_spec = GroupAndStackOutputSpec def _run_interface(self, runtime): src_paths = self._get_filelist(self.inputs.dicom_files) stacks = dcmstack.parse_and_stack(src_paths) self.out_list = [] for key, stack in stacks.iteritems(): nw = NiftiWrapper(stack.to_nifti(embed_meta=True)) const_meta = nw.meta_ext.get_class_dict(('global', 'const')) out_path = self._get_out_path(const_meta) if not self.inputs.embed_meta: nw.remove_extension() nb.save(nw.nii_img, out_path) self.out_list.append(out_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["out_list"] = self.out_list return outputs class LookupMetaInputSpec(TraitedSpec): in_file = File(mandatory=True, exists=True, desc='The input Nifti file') meta_keys = traits.Either(traits.List(), traits.Dict(), mandatory=True, desc=("List of meta data keys to lookup, or a " "dict where keys specify the meta data keys to " "lookup and the values specify the output names") ) class LookupMeta(BaseInterface): '''Lookup meta data values from a Nifti with embedded meta data. Example ------- >>> from nipype.interfaces import dcmstack >>> lookup = dcmstack.LookupMeta() >>> lookup.inputs.in_file = 'functional.nii' >>> lookup.inputs.meta_keys = {'RepetitionTime' : 'TR', \ 'EchoTime' : 'TE'} >>> result = lookup.run() # doctest: +SKIP >>> result.outputs.TR # doctest: +SKIP 9500.0 >>> result.outputs.TE # doctest: +SKIP 95.0 ''' input_spec = LookupMetaInputSpec output_spec = DynamicTraitedSpec def _make_name_map(self): if isinstance(self.inputs.meta_keys, list): self._meta_keys = {} for key in self.inputs.meta_keys: self._meta_keys[key] = key else: self._meta_keys = self.inputs.meta_keys def _outputs(self): self._make_name_map() outputs = super(LookupMeta, self)._outputs() undefined_traits = {} for out_name in self._meta_keys.values(): outputs.add_trait(out_name, traits.Any) undefined_traits[out_name] = Undefined outputs.trait_set(trait_change_notify=False, **undefined_traits) # Not sure why this is needed for out_name in self._meta_keys.values(): _ = getattr(outputs, out_name) return outputs def _run_interface(self, runtime): # If the 'meta_keys' input is a list, covert it to a dict self._make_name_map() nw = NiftiWrapper.from_filename(self.inputs.in_file) self.result = {} for meta_key, out_name in self._meta_keys.iteritems(): self.result[out_name] = nw.meta_ext.get_values(meta_key) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs.update(self.result) return outputs class CopyMetaInputSpec(TraitedSpec): src_file = File(mandatory=True, exists=True) dest_file = File(mandatory=True, exists=True) include_classes = traits.List(desc="List of specific meta data " "classifications to include. If not " "specified include everything.") exclude_classes = traits.List(desc="List of meta data " "classifications to exclude") class CopyMetaOutputSpec(TraitedSpec): dest_file = File(exists=True) class CopyMeta(BaseInterface): '''Copy meta data from one Nifti file to another. Useful for preserving meta data after some processing steps.''' input_spec = CopyMetaInputSpec output_spec = CopyMetaOutputSpec def _run_interface(self, runtime): src_nii = nb.load(self.inputs.src_file) src = NiftiWrapper(src_nii, make_empty=True) dest_nii = nb.load(self.inputs.dest_file) dest = NiftiWrapper(dest_nii, make_empty=True) classes = src.meta_ext.get_valid_classes() if self.inputs.include_classes: classes = [cls for cls in classes if cls in self.inputs.include_classes ] if self.inputs.exclude_classes: classes = [cls for cls in classes if not cls in self.inputs.exclude_classes ] for cls in classes: src_dict = src.meta_ext.get_class_dict(cls) dest_dict = dest.meta_ext.get_class_dict(cls) dest_dict.update(src_dict) # Update the shape and slice dimension to reflect the meta extension update. dest.meta_ext.slice_dim = src.meta_ext.slice_dim dest.meta_ext.shape = src.meta_ext.shape self.out_path = op.join(os.getcwd(), op.basename(self.inputs.dest_file)) dest.to_filename(self.out_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['dest_file'] = self.out_path return outputs class MergeNiftiInputSpec(NiftiGeneratorBaseInputSpec): in_files = traits.List(mandatory=True, desc="List of Nifti files to merge") sort_order = traits.Either(traits.Str(), traits.List(), desc="One or more meta data keys to " "sort files by.") merge_dim = traits.Int(desc="Dimension to merge along. If not " "specified, the last singular or " "non-existant dimension is used.") class MergeNiftiOutputSpec(TraitedSpec): out_file = File(exists=True, desc="Merged Nifti file") def make_key_func(meta_keys, index=None): def key_func(src_nii): result = [src_nii.get_meta(key, index) for key in meta_keys] return result return key_func class MergeNifti(NiftiGeneratorBase): '''Merge multiple Nifti files into one. Merges together meta data extensions as well.''' input_spec = MergeNiftiInputSpec output_spec = MergeNiftiOutputSpec def _run_interface(self, runtime): niis = [nb.load(fn) for fn in self.inputs.in_files ] nws = [NiftiWrapper(nii, make_empty=True) for nii in niis ] if self.inputs.sort_order: sort_order = self.inputs.sort_order if isinstance(sort_order, six.string_types): sort_order = [sort_order] nws.sort(key=make_key_func(sort_order)) if self.inputs.merge_dim == traits.Undefined: merge_dim = None else: merge_dim = self.inputs.merge_dim merged = NiftiWrapper.from_sequence(nws, merge_dim) const_meta = merged.meta_ext.get_class_dict(('global', 'const')) self.out_path = self._get_out_path(const_meta) nb.save(merged.nii_img, self.out_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = self.out_path return outputs class SplitNiftiInputSpec(NiftiGeneratorBaseInputSpec): in_file = File(exists=True, mandatory=True, desc="Nifti file to split") split_dim = traits.Int(desc="Dimension to split along. If not " "specified, the last dimension is used.") class SplitNiftiOutputSpec(TraitedSpec): out_list = traits.List(File(exists=True), desc="Split Nifti files") class SplitNifti(NiftiGeneratorBase): ''' Split one Nifti file into many along the specified dimension. Each result has an updated meta data extension as well. ''' input_spec = SplitNiftiInputSpec output_spec = SplitNiftiOutputSpec def _run_interface(self, runtime): self.out_list = [] nii = nb.load(self.inputs.in_file) nw = NiftiWrapper(nii, make_empty=True) split_dim = None if self.inputs.split_dim == traits.Undefined: split_dim = None else: split_dim = self.inputs.split_dim for split_idx, split_nw in enumerate(nw.split(split_dim)): const_meta = split_nw.meta_ext.get_class_dict(('global', 'const')) out_path = self._get_out_path(const_meta, idx=split_idx) nb.save(split_nw.nii_img, out_path) self.out_list.append(out_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_list'] = self.out_list return outputs nipype-0.11.0/nipype/interfaces/diffusion_toolkit/000077500000000000000000000000001257611314500222645ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/diffusion_toolkit/__init__.py000066400000000000000000000002341257611314500243740ustar00rootroot00000000000000from .base import Info from .postproc import SplineFilter, TrackMerge from .dti import DTIRecon, DTITracker from .odf import HARDIMat, ODFRecon, ODFTracker nipype-0.11.0/nipype/interfaces/diffusion_toolkit/base.py000066400000000000000000000024371257611314500235560ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The dtk module provides basic functions for interfacing with Diffusion Toolkit tools. Currently these tools are supported: * TODO Examples -------- See the docstrings for the individual classes for 'working' examples. """ __docformat__ = 'restructuredtext' import re from nipype.interfaces.base import CommandLine class Info(object): """ Handle dtk output type and version information. Examples -------- >>> from nipype.interfaces.diffusion_toolkit import Info >>> Info.version() # doctest: +SKIP >>> Info.subjectsdir() # doctest: +SKIP """ @staticmethod def version(): """Check for dtk version on system Parameters ---------- None Returns ------- version : str Version number as string or None if FSL not found """ clout = CommandLine(command='dti_recon', terminal_output='allatonce').run() if clout.runtime.returncode is not 0: return None dtirecon = clout.runtime.stdout result = re.search('dti_recon (.*)\n', dtirecon) version = result.group(0).split()[1] return version nipype-0.11.0/nipype/interfaces/diffusion_toolkit/dti.py000066400000000000000000000223371257611314500234250ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Provides interfaces to various commands provided by diffusion toolkit Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import re from nipype.utils.filemanip import fname_presuffix, split_filename, copyfile import os __docformat__ = 'restructuredtext' from nipype.interfaces.base import (TraitedSpec, File, traits, CommandLine, CommandLineInputSpec, isdefined) class DTIReconInputSpec(CommandLineInputSpec): DWI = File(desc='Input diffusion volume', argstr='%s',exists=True, mandatory=True,position=1) out_prefix = traits.Str("dti", desc='Output file prefix', argstr='%s', usedefault=True,position=2) output_type = traits.Enum('nii', 'analyze', 'ni1', 'nii.gz', argstr='-ot %s', desc='output file type', usedefault=True) bvecs = File(exists=True, desc = 'b vectors file', argstr='-gm %s', mandatory=True) bvals = File(exists=True,desc = 'b values file', mandatory=True) n_averages = traits.Int(desc='Number of averages', argstr='-nex %s') image_orientation_vectors = traits.List(traits.Float(), minlen=6, maxlen=6, desc="""specify image orientation vectors. if just one argument given, will treat it as filename and read the orientation vectors from the file. if 6 arguments are given, will treat them as 6 float numbers and construct the 1st and 2nd vector and calculate the 3rd one automatically. this information will be used to determine image orientation, as well as to adjust gradient vectors with oblique angle when""", argstr="-iop %f") oblique_correction = traits.Bool(desc="""when oblique angle(s) applied, some SIEMENS dti protocols do not adjust gradient accordingly, thus it requires adjustment for correct diffusion tensor calculation""", argstr="-oc") b0_threshold = traits.Float(desc="""program will use b0 image with the given threshold to mask out high background of fa/adc maps. by default it will calculate threshold automatically. but if it failed, you need to set it manually.""", argstr="-b0_th") class DTIReconOutputSpec(TraitedSpec): ADC = File(exists=True) B0 = File(exists=True) L1 = File(exists=True) L2 = File(exists=True) L3 = File(exists=True) exp = File(exists=True) FA = File(exists=True) FA_color = File(exists=True) tensor = File(exists=True) V1 = File(exists=True) V2 = File(exists=True) V3 = File(exists=True) class DTIRecon(CommandLine): """Use dti_recon to generate tensors and other maps """ input_spec=DTIReconInputSpec output_spec=DTIReconOutputSpec _cmd = 'dti_recon' def _create_gradient_matrix(self, bvecs_file, bvals_file): _gradient_matrix_file = 'gradient_matrix.txt' bvals = [val for val in re.split('\s+', open(bvals_file).readline().strip())] bvecs_f = open(bvecs_file) bvecs_x = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_y = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_z = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_f.close() gradient_matrix_f = open(_gradient_matrix_file, 'w') for i in range(len(bvals)): gradient_matrix_f.write("%s, %s, %s, %s\n"%(bvecs_x[i], bvecs_y[i], bvecs_z[i], bvals[i])) gradient_matrix_f.close() return _gradient_matrix_file def _format_arg(self, name, spec, value): if name == "bvecs": new_val = self._create_gradient_matrix(self.inputs.bvecs, self.inputs.bvals) return super(DTIRecon, self)._format_arg("bvecs", spec, new_val) return super(DTIRecon, self)._format_arg(name, spec, value) def _list_outputs(self): out_prefix = self.inputs.out_prefix output_type = self.inputs.output_type outputs = self.output_spec().get() outputs['ADC'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_adc.'+ output_type)) outputs['B0'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_b0.'+ output_type)) outputs['L1'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_e1.'+ output_type)) outputs['L2'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_e2.'+ output_type)) outputs['L3'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_e3.'+ output_type)) outputs['exp'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_exp.'+ output_type)) outputs['FA'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_fa.'+ output_type)) outputs['FA_color'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_fa_color.'+ output_type)) outputs['tensor'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_tensor.'+ output_type)) outputs['V1'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_v1.'+ output_type)) outputs['V2'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_v2.'+ output_type)) outputs['V3'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_v3.'+ output_type)) return outputs class DTITrackerInputSpec(CommandLineInputSpec): tensor_file = File(exists=True, desc="reconstructed tensor file") input_type = traits.Enum('nii', 'analyze', 'ni1', 'nii.gz', desc="""input and output file type. accepted values are: analyze -> analyze format 7.5 ni1 -> nifti format saved in seperate .hdr and .img file nii -> nifti format with one .nii file nii.gz -> nifti format with compression default type is 'nii'""", argstr = "-it %s") tracking_method = traits.Enum('fact', 'rk2', 'tl', 'sl', desc="""fact -> use FACT method for tracking. this is the default method. rk2 -> use 2nd order runge-kutta method for tracking. tl -> use tensorline method for tracking. sl -> use interpolated streamline method with fixed step-length""", argstr="-%s") step_length = traits.Float(desc="""set step length, in the unit of minimum voxel size. default value is 0.5 for interpolated streamline method and 0.1 for other methods""", argstr="-l %f") angle_threshold = traits.Float(desc="set angle threshold. default value is 35 degree", argstr="-at %f") angle_threshold_weight = traits.Float(desc="set angle threshold weighting factor. weighting will be be applied \ on top of the angle_threshold", argstr = "-atw %f") random_seed = traits.Int(desc = "use random location in a voxel instead of the center of the voxel \ to seed. can also define number of seed per voxel. default is 1", argstr="-rseed") invert_x = traits.Bool(desc="invert x component of the vector", argstr = "-ix") invert_y = traits.Bool(desc="invert y component of the vector", argstr = "-iy") invert_z = traits.Bool(desc="invert z component of the vector", argstr = "-iz") swap_xy = traits.Bool(desc="swap x & y vectors while tracking", argstr = "-sxy") swap_yz = traits.Bool(desc="swap y & z vectors while tracking", argstr = "-syz") swap_zx = traits.Bool(desc="swap x & z vectors while tracking", argstr = "-szx") mask1_file = File(desc="first mask image", mandatory=True, argstr="-m %s", position=2) mask1_threshold = traits.Float(desc="threshold value for the first mask image, if not given, the program will \ try automatically find the threshold", position=3) mask2_file = File(desc="second mask image", argstr="-m2 %s", position=4) mask2_threshold = traits.Float(desc="threshold value for the second mask image, if not given, the program will \ try automatically find the threshold", position=5) input_data_prefix = traits.Str("dti", desc="for internal naming use only", position=0, argstr="%s", usedefault=True) output_file = File("tracks.trk", "file containing tracks", argstr="%s", position=1, usedefault=True) output_mask = File(desc="output a binary mask file in analyze format", argstr="-om %s") primary_vector = traits.Enum('v2', 'v3', desc = "which vector to use for fibre tracking: v2 or v3. If not set use v1", argstr="-%s") class DTITrackerOutputSpec(TraitedSpec): track_file = File(exists=True) mask_file = File(exists=True) class DTITracker(CommandLine): input_spec=DTITrackerInputSpec output_spec=DTITrackerOutputSpec _cmd = 'dti_tracker' def _run_interface(self, runtime): _, _, ext = split_filename(self.inputs.tensor_file) copyfile(self.inputs.tensor_file, os.path.abspath(self.inputs.input_data_prefix + "_tensor" + ext), copy=False) return super(DTITracker, self)._run_interface(runtime) def _list_outputs(self): outputs = self.output_spec().get() outputs['track_file'] = os.path.abspath(self.inputs.output_file) if isdefined(self.inputs.output_mask) and self.inputs.output_mask: outputs['mask_file'] = os.path.abspath(self.inputs.output_mask) return outputsnipype-0.11.0/nipype/interfaces/diffusion_toolkit/odf.py000066400000000000000000000316771257611314500234240ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Provides interfaces to various commands provided by diffusion toolkit Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import re from nipype.utils.filemanip import fname_presuffix, split_filename, copyfile import os __docformat__ = 'restructuredtext' from nipype.interfaces.base import (TraitedSpec, File, traits, CommandLine, CommandLineInputSpec, isdefined) class HARDIMatInputSpec(CommandLineInputSpec): bvecs = File(exists=True, desc = 'b vectors file', argstr='%s', position=1, mandatory=True) bvals = File(exists=True,desc = 'b values file', mandatory=True) out_file = File("recon_mat.dat", desc = 'output matrix file', argstr='%s', usedefault=True, position=2) order = traits.Int(argstr='-order %s', desc="""maximum order of spherical harmonics. must be even number. default is 4""") odf_file = File(exists=True, argstr='-odf %s', desc="""filename that contains the reconstruction points on a HEMI-sphere. use the pre-set 181 points by default""") reference_file = File(exists=True, argstr='-ref %s', desc="""provide a dicom or nifti image as the reference for the program to figure out the image orientation information. if no such info was found in the given image header, the next 5 options -info, etc., will be used if provided. if image orientation info can be found in the given reference, all other 5 image orientation options will be IGNORED""") image_info = File(exists=True, argstr='-info %s', desc="""specify image information file. the image info file is generated from original dicom image by diff_unpack program and contains image orientation and other information needed for reconstruction and tracking. by default will look into the image folder for .info file""") image_orientation_vectors = traits.List(traits.Float(), minlen=6, maxlen=6, desc="""specify image orientation vectors. if just one argument given, will treat it as filename and read the orientation vectors from the file. if 6 arguments are given, will treat them as 6 float numbers and construct the 1st and 2nd vector and calculate the 3rd one automatically. this information will be used to determine image orientation, as well as to adjust gradient vectors with oblique angle when""", argstr="-iop %f") oblique_correction = traits.Bool(desc="""when oblique angle(s) applied, some SIEMENS dti protocols do not adjust gradient accordingly, thus it requires adjustment for correct diffusion tensor calculation""", argstr="-oc") class HARDIMatOutputSpec(TraitedSpec): out_file = File(exists=True, desc='output matrix file') class HARDIMat(CommandLine): """Use hardi_mat to calculate a reconstruction matrix from a gradient table """ input_spec=HARDIMatInputSpec output_spec=HARDIMatOutputSpec _cmd = 'hardi_mat' def _create_gradient_matrix(self, bvecs_file, bvals_file): _gradient_matrix_file = 'gradient_matrix.txt' bvals = [val for val in re.split('\s+', open(bvals_file).readline().strip())] bvecs_f = open(bvecs_file) bvecs_x = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_y = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_z = [val for val in re.split('\s+', bvecs_f.readline().strip())] bvecs_f.close() gradient_matrix_f = open(_gradient_matrix_file, 'w') for i in range(len(bvals)): if int(bvals[i]) == 0: continue gradient_matrix_f.write("%s %s %s\n"%(bvecs_x[i], bvecs_y[i], bvecs_z[i])) gradient_matrix_f.close() return _gradient_matrix_file def _format_arg(self, name, spec, value): if name == "bvecs": new_val = self._create_gradient_matrix(self.inputs.bvecs, self.inputs.bvals) return super(HARDIMat, self)._format_arg("bvecs", spec, new_val) return super(HARDIMat, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs class ODFReconInputSpec(CommandLineInputSpec): DWI = File(desc='Input raw data', argstr='%s',exists=True, mandatory=True,position=1) n_directions = traits.Int(desc='Number of directions', argstr='%s', mandatory=True, position=2) n_output_directions = traits.Int(desc='Number of output directions', argstr='%s', mandatory=True, position=3) out_prefix = traits.Str("odf", desc='Output file prefix', argstr='%s', usedefault=True, position=4) matrix = File(argstr='-mat %s', exists=True, desc="""use given file as reconstruction matrix.""", mandatory=True) n_b0 = traits.Int(argstr='-b0 %s', desc="""number of b0 scans. by default the program gets this information from the number of directions and number of volumes in the raw data. useful when dealing with incomplete raw data set or only using part of raw data set to reconstruct""", mandatory=True) output_type = traits.Enum('nii', 'analyze', 'ni1', 'nii.gz', argstr='-ot %s', desc='output file type', usedefault=True) sharpness = traits.Float(desc="""smooth or sharpen the raw data. factor > 0 is smoothing. factor < 0 is sharpening. default value is 0 NOTE: this option applies to DSI study only""", argstr='-s %f') filter = traits.Bool(desc="""apply a filter (e.g. high pass) to the raw image""", argstr='-f') subtract_background = traits.Bool(desc="""subtract the background value before reconstruction""", argstr='-bg') dsi = traits.Bool(desc="""indicates that the data is dsi""", argstr='-dsi') output_entropy = traits.Bool(desc="""output entropy map""", argstr='-oe') image_orientation_vectors = traits.List(traits.Float(), minlen=6, maxlen=6, desc="""specify image orientation vectors. if just one argument given, will treat it as filename and read the orientation vectors from the file. if 6 arguments are given, will treat them as 6 float numbers and construct the 1st and 2nd vector and calculate the 3rd one automatically. this information will be used to determine image orientation, as well as to adjust gradient vectors with oblique angle when""", argstr="-iop %f") oblique_correction = traits.Bool(desc="""when oblique angle(s) applied, some SIEMENS dti protocols do not adjust gradient accordingly, thus it requires adjustment for correct diffusion tensor calculation""", argstr="-oc") class ODFReconOutputSpec(TraitedSpec): B0 = File(exists=True) DWI = File(exists=True) max = File(exists=True) ODF = File(exists=True) entropy = File() class ODFRecon(CommandLine): """Use odf_recon to generate tensors and other maps """ input_spec=ODFReconInputSpec output_spec=ODFReconOutputSpec _cmd = 'odf_recon' def _list_outputs(self): out_prefix = self.inputs.out_prefix output_type = self.inputs.output_type outputs = self.output_spec().get() outputs['B0'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_b0.'+ output_type)) outputs['DWI'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_dwi.'+ output_type)) outputs['max'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_max.'+ output_type)) outputs['ODF'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_odf.'+ output_type)) if isdefined(self.inputs.output_entropy): outputs['entropy'] = os.path.abspath(fname_presuffix("", prefix=out_prefix, suffix='_entropy.'+ output_type)) return outputs class ODFTrackerInputSpec(CommandLineInputSpec): max = File(exists=True, mandatory=True) ODF = File(exists=True, mandatory=True) input_data_prefix = traits.Str("odf", desc='recon data prefix', argstr='%s', usedefault=True, position=0) out_file = File("tracks.trk", desc = 'output track file', argstr='%s', usedefault=True, position=1) input_output_type = traits.Enum('nii', 'analyze', 'ni1', 'nii.gz', argstr='-it %s', desc='input and output file type', usedefault=True) runge_kutta2 = traits.Bool(argstr='-rk2', desc="""use 2nd order runge-kutta method for tracking. default tracking method is non-interpolate streamline""") step_length = traits.Float(argstr='-l %f', desc="""set step length, in the unit of minimum voxel size. default value is 0.1.""") angle_threshold = traits.Float(argstr='-at %f',desc="""set angle threshold. default value is 35 degree for default tracking method and 25 for rk2""") random_seed = traits.Int(argstr='-rseed %s', desc="""use random location in a voxel instead of the center of the voxel to seed. can also define number of seed per voxel. default is 1""") invert_x = traits.Bool(argstr='-ix', desc='invert x component of the vector') invert_y = traits.Bool(argstr='-iy', desc='invert y component of the vector') invert_z = traits.Bool(argstr='-iz', desc='invert z component of the vector') swap_xy = traits.Bool(argstr='-sxy', desc='swap x and y vectors while tracking') swap_yz = traits.Bool(argstr='-syz', desc='swap y and z vectors while tracking') swap_zx = traits.Bool(argstr='-szx', desc='swap x and z vectors while tracking') disc = traits.Bool(argstr='-disc', desc='use disc tracking') mask1_file = File(desc="first mask image", mandatory=True, argstr="-m %s", position=2) mask1_threshold = traits.Float(desc="threshold value for the first mask image, if not given, the program will \ try automatically find the threshold", position=3) mask2_file = File(desc="second mask image", argstr="-m2 %s", position=4) mask2_threshold = traits.Float(desc="threshold value for the second mask image, if not given, the program will \ try automatically find the threshold", position=5) limit = traits.Int(argstr='-limit %d', desc="""in some special case, such as heart data, some track may go into infinite circle and take long time to stop. this option allows setting a limit for the longest tracking steps (voxels)""") dsi = traits.Bool(argstr='-dsi', desc=""" specify the input odf data is dsi. because dsi recon uses fixed pre-calculated matrix, some special orientation patch needs to be applied to keep dti/dsi/q-ball consistent.""") image_orientation_vectors = traits.List(traits.Float(), minlen=6, maxlen=6, desc="""specify image orientation vectors. if just one argument given, will treat it as filename and read the orientation vectors from the file. if 6 arguments are given, will treat them as 6 float numbers and construct the 1st and 2nd vector and calculate the 3rd one automatically. this information will be used to determine image orientation, as well as to adjust gradient vectors with oblique angle when""", argstr="-iop %f") slice_order = traits.Int(argstr='-sorder %d', desc='set the slice order. 1 means normal, -1 means reversed. default value is 1') voxel_order = traits.Enum('RAS', 'RPS', 'RAI', 'RPI', 'LAI', 'LAS', 'LPS', 'LPI', argstr='-vorder %s', desc="""specify the voxel order in RL/AP/IS (human brain) reference. must be 3 letters with no space in between. for example, RAS means the voxel row is from L->R, the column is from P->A and the slice order is from I->S. by default voxel order is determined by the image orientation (but NOT guaranteed to be correct because of various standards). for example, siemens axial image is LPS, coronal image is LIP and sagittal image is PIL. this information also is NOT needed for tracking but will be saved in the track file and is essential for track display to map onto the right coordinates""") class ODFTrackerOutputSpec(TraitedSpec): track_file = File(exists=True, desc='output track file') class ODFTracker(CommandLine): """Use odf_tracker to generate track file """ input_spec=ODFTrackerInputSpec output_spec=ODFTrackerOutputSpec _cmd = 'odf_tracker' def _run_interface(self, runtime): _, _, ext = split_filename(self.inputs.max) copyfile(self.inputs.max, os.path.abspath(self.inputs.input_data_prefix + "_max" + ext), copy=False) _, _, ext = split_filename(self.inputs.ODF) copyfile(self.inputs.ODF, os.path.abspath(self.inputs.input_data_prefix + "_odf" + ext), copy=False) return super(ODFTracker, self)._run_interface(runtime) def _list_outputs(self): outputs = self.output_spec().get() outputs['track_file'] = os.path.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/diffusion_toolkit/postproc.py000066400000000000000000000064411257611314500245140ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Provides interfaces to various commands provided by diffusion toolkit Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os __docformat__ = 'restructuredtext' from nipype.interfaces.base import (TraitedSpec, File, traits, CommandLine, InputMultiPath, CommandLineInputSpec) class SplineFilterInputSpec(CommandLineInputSpec): track_file = File(exists=True, desc="file containing tracks to be filtered", position=0, argstr="%s", mandatory=True) step_length = traits.Float(desc="in the unit of minimum voxel size", position=1, argstr="%f", mandatory=True) output_file = File("spline_tracks.trk", desc="target file for smoothed tracks", position=2, argstr="%s", usedefault=True) class SplineFilterOutputSpec(TraitedSpec): smoothed_track_file = File(exists=True) class SplineFilter(CommandLine): """ Smoothes TrackVis track files with a B-Spline filter. Helps remove redundant track points and segments (thus reducing the size of the track file) and also make tracks nicely smoothed. It will NOT change the quality of the tracks or lose any original information. Example ------- >>> import nipype.interfaces.diffusion_toolkit as dtk >>> filt = dtk.SplineFilter() >>> filt.inputs.track_file = 'tracks.trk' >>> filt.inputs.step_length = 0.5 >>> filt.run() # doctest: +SKIP """ input_spec=SplineFilterInputSpec output_spec=SplineFilterOutputSpec _cmd = "spline_filter" def _list_outputs(self): outputs = self.output_spec().get() outputs['smoothed_track_file'] = os.path.abspath(self.inputs.output_file) return outputs class TrackMergeInputSpec(CommandLineInputSpec): track_files = InputMultiPath(File(exists=True), desc="file containing tracks to be filtered", position=0, argstr="%s...", mandatory=True) output_file = File("merged_tracks.trk", desc="target file for merged tracks", position=-1, argstr="%s", usedefault=True) class TrackMergeOutputSpec(TraitedSpec): track_file = File(exists=True) class TrackMerge(CommandLine): """ Merges several TrackVis track files into a single track file. An id type property tag is added to each track in the newly merged file, with each unique id representing where the track was originally from. When the merged file is loaded in TrackVis, a property filter will show up in Track Property panel. Users can adjust that to distinguish and sub-group tracks by its id (origin). Example ------- >>> import nipype.interfaces.diffusion_toolkit as dtk >>> mrg = dtk.TrackMerge() >>> mrg.inputs.track_files = ['track1.trk','track2.trk'] >>> mrg.run() # doctest: +SKIP """ input_spec=TrackMergeInputSpec output_spec=TrackMergeOutputSpec _cmd = "track_merge" def _list_outputs(self): outputs = self.output_spec().get() outputs['track_file'] = os.path.abspath(self.inputs.output_file) return outputs nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/000077500000000000000000000000001257611314500234265ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_DTIRecon.py000066400000000000000000000030571257611314500275030ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.dti import DTIRecon def test_DTIRecon_inputs(): input_map = dict(DWI=dict(argstr='%s', mandatory=True, position=1, ), args=dict(argstr='%s', ), b0_threshold=dict(argstr='-b0_th', ), bvals=dict(mandatory=True, ), bvecs=dict(argstr='-gm %s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image_orientation_vectors=dict(argstr='-iop %f', ), n_averages=dict(argstr='-nex %s', ), oblique_correction=dict(argstr='-oc', ), out_prefix=dict(argstr='%s', position=2, usedefault=True, ), output_type=dict(argstr='-ot %s', usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = DTIRecon.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTIRecon_outputs(): output_map = dict(ADC=dict(), B0=dict(), FA=dict(), FA_color=dict(), L1=dict(), L2=dict(), L3=dict(), V1=dict(), V2=dict(), V3=dict(), exp=dict(), tensor=dict(), ) outputs = DTIRecon.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_DTITracker.py000066400000000000000000000036471257611314500300350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.dti import DTITracker def test_DTITracker_inputs(): input_map = dict(angle_threshold=dict(argstr='-at %f', ), angle_threshold_weight=dict(argstr='-atw %f', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), input_data_prefix=dict(argstr='%s', position=0, usedefault=True, ), input_type=dict(argstr='-it %s', ), invert_x=dict(argstr='-ix', ), invert_y=dict(argstr='-iy', ), invert_z=dict(argstr='-iz', ), mask1_file=dict(argstr='-m %s', mandatory=True, position=2, ), mask1_threshold=dict(position=3, ), mask2_file=dict(argstr='-m2 %s', position=4, ), mask2_threshold=dict(position=5, ), output_file=dict(argstr='%s', position=1, usedefault=True, ), output_mask=dict(argstr='-om %s', ), primary_vector=dict(argstr='-%s', ), random_seed=dict(argstr='-rseed', ), step_length=dict(argstr='-l %f', ), swap_xy=dict(argstr='-sxy', ), swap_yz=dict(argstr='-syz', ), swap_zx=dict(argstr='-szx', ), tensor_file=dict(), terminal_output=dict(nohash=True, ), tracking_method=dict(argstr='-%s', ), ) inputs = DTITracker.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTITracker_outputs(): output_map = dict(mask_file=dict(), track_file=dict(), ) outputs = DTITracker.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_HARDIMat.py000066400000000000000000000025401257611314500273610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.odf import HARDIMat def test_HARDIMat_inputs(): input_map = dict(args=dict(argstr='%s', ), bvals=dict(mandatory=True, ), bvecs=dict(argstr='%s', mandatory=True, position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image_info=dict(argstr='-info %s', ), image_orientation_vectors=dict(argstr='-iop %f', ), oblique_correction=dict(argstr='-oc', ), odf_file=dict(argstr='-odf %s', ), order=dict(argstr='-order %s', ), out_file=dict(argstr='%s', position=2, usedefault=True, ), reference_file=dict(argstr='-ref %s', ), terminal_output=dict(nohash=True, ), ) inputs = HARDIMat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_HARDIMat_outputs(): output_map = dict(out_file=dict(), ) outputs = HARDIMat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_ODFRecon.py000066400000000000000000000033601257611314500274700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.odf import ODFRecon def test_ODFRecon_inputs(): input_map = dict(DWI=dict(argstr='%s', mandatory=True, position=1, ), args=dict(argstr='%s', ), dsi=dict(argstr='-dsi', ), environ=dict(nohash=True, usedefault=True, ), filter=dict(argstr='-f', ), ignore_exception=dict(nohash=True, usedefault=True, ), image_orientation_vectors=dict(argstr='-iop %f', ), matrix=dict(argstr='-mat %s', mandatory=True, ), n_b0=dict(argstr='-b0 %s', mandatory=True, ), n_directions=dict(argstr='%s', mandatory=True, position=2, ), n_output_directions=dict(argstr='%s', mandatory=True, position=3, ), oblique_correction=dict(argstr='-oc', ), out_prefix=dict(argstr='%s', position=4, usedefault=True, ), output_entropy=dict(argstr='-oe', ), output_type=dict(argstr='-ot %s', usedefault=True, ), sharpness=dict(argstr='-s %f', ), subtract_background=dict(argstr='-bg', ), terminal_output=dict(nohash=True, ), ) inputs = ODFRecon.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ODFRecon_outputs(): output_map = dict(B0=dict(), DWI=dict(), ODF=dict(), entropy=dict(), max=dict(), ) outputs = ODFRecon.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_ODFTracker.py000066400000000000000000000041301257611314500300110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.odf import ODFTracker def test_ODFTracker_inputs(): input_map = dict(ODF=dict(mandatory=True, ), angle_threshold=dict(argstr='-at %f', ), args=dict(argstr='%s', ), disc=dict(argstr='-disc', ), dsi=dict(argstr='-dsi', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image_orientation_vectors=dict(argstr='-iop %f', ), input_data_prefix=dict(argstr='%s', position=0, usedefault=True, ), input_output_type=dict(argstr='-it %s', usedefault=True, ), invert_x=dict(argstr='-ix', ), invert_y=dict(argstr='-iy', ), invert_z=dict(argstr='-iz', ), limit=dict(argstr='-limit %d', ), mask1_file=dict(argstr='-m %s', mandatory=True, position=2, ), mask1_threshold=dict(position=3, ), mask2_file=dict(argstr='-m2 %s', position=4, ), mask2_threshold=dict(position=5, ), max=dict(mandatory=True, ), out_file=dict(argstr='%s', position=1, usedefault=True, ), random_seed=dict(argstr='-rseed %s', ), runge_kutta2=dict(argstr='-rk2', ), slice_order=dict(argstr='-sorder %d', ), step_length=dict(argstr='-l %f', ), swap_xy=dict(argstr='-sxy', ), swap_yz=dict(argstr='-syz', ), swap_zx=dict(argstr='-szx', ), terminal_output=dict(nohash=True, ), voxel_order=dict(argstr='-vorder %s', ), ) inputs = ODFTracker.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ODFTracker_outputs(): output_map = dict(track_file=dict(), ) outputs = ODFTracker.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_SplineFilter.py000066400000000000000000000022221257611314500304650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.postproc import SplineFilter def test_SplineFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_file=dict(argstr='%s', position=2, usedefault=True, ), step_length=dict(argstr='%f', mandatory=True, position=1, ), terminal_output=dict(nohash=True, ), track_file=dict(argstr='%s', mandatory=True, position=0, ), ) inputs = SplineFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SplineFilter_outputs(): output_map = dict(smoothed_track_file=dict(), ) outputs = SplineFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/diffusion_toolkit/tests/test_auto_TrackMerge.py000066400000000000000000000020671257611314500301200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.diffusion_toolkit.postproc import TrackMerge def test_TrackMerge_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_file=dict(argstr='%s', position=-1, usedefault=True, ), terminal_output=dict(nohash=True, ), track_files=dict(argstr='%s...', mandatory=True, position=0, ), ) inputs = TrackMerge.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackMerge_outputs(): output_map = dict(track_file=dict(), ) outputs = TrackMerge.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/000077500000000000000000000000001257611314500174765ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/dipy/__init__.py000066400000000000000000000002351257611314500216070ustar00rootroot00000000000000from .tracks import TrackDensityMap from .tensors import TensorMode, DTI from .preprocess import Resample, Denoise from .simulate import SimulateMultiTensor nipype-0.11.0/nipype/interfaces/dipy/preprocess.py000066400000000000000000000173441257611314500222460ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- """Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (traits, TraitedSpec, BaseInterface, File, isdefined) from nipype.utils.filemanip import split_filename import os.path as op import nibabel as nb import numpy as np from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_dipy = True try: package_check('dipy', version='0.6.0') except Exception, e: have_dipy = False else: from dipy.align.aniso2iso import resample from dipy.core.gradients import GradientTable class ResampleInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input 4D diffusion-weighted image file') vox_size = traits.Tuple(traits.Float, traits.Float, traits.Float, desc=('specify the new voxel zooms. If no vox_size' ' is set, then isotropic regridding will ' 'be performed, with spacing equal to the ' 'smallest current zoom.')) interp = traits.Int(1, mandatory=True, usedefault=True, desc=('order of ' 'the interpolator (0 = nearest, 1 = linear, etc.')) class ResampleOutputSpec(TraitedSpec): out_file = File(exists=True) class Resample(BaseInterface): """ An interface to reslicing diffusion datasets. See http://nipy.org/dipy/examples_built/reslice_datasets.html#example-reslice-datasets. Example ------- >>> import nipype.interfaces.dipy as dipy >>> reslice = dipy.Resample() >>> reslice.inputs.in_file = 'diffusion.nii' >>> reslice.run() # doctest: +SKIP """ input_spec = ResampleInputSpec output_spec = ResampleOutputSpec def _run_interface(self, runtime): order = self.inputs.interp vox_size = None if isdefined(self.inputs.vox_size): vox_size = self.inputs.vox_size out_file = op.abspath(self._gen_outfilename()) resample_proxy(self.inputs.in_file, order=order, new_zooms=vox_size, out_file=out_file) iflogger.info('Resliced image saved as {i}'.format(i=out_file)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): fname, fext = op.splitext(op.basename(self.inputs.in_file)) if fext == '.gz': fname, fext2 = op.splitext(fname) fext = fext2 + fext return op.abspath('%s_reslice%s' % (fname, fext)) class DenoiseInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input 4D diffusion-weighted image file') in_mask = File(exists=True, desc='brain mask') noise_model = traits.Enum('rician', 'gaussian', mandatory=True, usedefault=True, desc=('noise distribution model')) noise_mask = File(desc=('mask in which the standard deviation of noise ' 'will be computed'), exists=True) patch_radius = traits.Int(1, desc='patch radius') block_radius = traits.Int(5, desc='block_radius') class DenoiseOutputSpec(TraitedSpec): out_file = File(exists=True) class Denoise(BaseInterface): """ An interface to denoising diffusion datasets [Coupe2008]_. See http://nipy.org/dipy/examples_built/denoise_nlmeans.html#example-denoise-nlmeans. .. [Coupe2008] Coupe P et al., `An Optimized Blockwise Non Local Means Denoising Filter for 3D Magnetic Resonance Images `_, IEEE Transactions on Medical Imaging, 27(4):425-441, 2008. Example ------- >>> import nipype.interfaces.dipy as dipy >>> denoise = dipy.Denoise() >>> denoise.inputs.in_file = 'diffusion.nii' >>> denoise.run() # doctest: +SKIP """ input_spec = DenoiseInputSpec output_spec = DenoiseOutputSpec def _run_interface(self, runtime): out_file = op.abspath(self._gen_outfilename()) settings = dict(mask=None, rician=(self.inputs.noise_model == 'rician')) if isdefined(self.inputs.in_mask): settings['mask'] = nb.load(self.inputs.in_mask).get_data() if isdefined(self.inputs.patch_radius): settings['patch_radius'] = self.inputs.patch_radius if isdefined(self.inputs.block_radius): settings['block_radius'] = self.inputs.block_radius noise_mask = None if isdefined(self.inputs.in_mask): noise_mask = nb.load(self.inputs.noise_mask).get_data() _, s = nlmeans_proxy(self.inputs.in_file, settings, noise_mask=noise_mask, out_file=out_file) iflogger.info(('Denoised image saved as {i}, estimated ' 'sigma={s}').format(i=out_file, s=s)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self._gen_outfilename()) return outputs def _gen_outfilename(self): fname, fext = op.splitext(op.basename(self.inputs.in_file)) if fext == '.gz': fname, fext2 = op.splitext(fname) fext = fext2 + fext return op.abspath('%s_denoise%s' % (fname, fext)) def resample_proxy(in_file, order=3, new_zooms=None, out_file=None): """ Performs regridding of an image to set isotropic voxel sizes using dipy. """ if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, fext2 = op.splitext(fname) fext = fext2 + fext out_file = op.abspath('./%s_reslice%s' % (fname, fext)) img = nb.load(in_file) hdr = img.get_header().copy() data = img.get_data().astype(np.float32) affine = img.get_affine() im_zooms = hdr.get_zooms()[:3] if new_zooms is None: minzoom = np.array(im_zooms).min() new_zooms = tuple(np.ones((3,)) * minzoom) if np.all(im_zooms == new_zooms): return in_file data2, affine2 = resample(data, affine, im_zooms, new_zooms, order=order) tmp_zooms = np.array(hdr.get_zooms()) tmp_zooms[:3] = new_zooms[0] hdr.set_zooms(tuple(tmp_zooms)) hdr.set_data_shape(data2.shape) hdr.set_xyzt_units('mm') nb.Nifti1Image(data2.astype(hdr.get_data_dtype()), affine2, hdr).to_filename(out_file) return out_file, new_zooms def nlmeans_proxy(in_file, settings, noise_mask=None, out_file=None): """ Uses non-local means to denoise 4D datasets """ package_check('dipy', version='0.8.0.dev') from dipy.denoise.nlmeans import nlmeans if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, fext2 = op.splitext(fname) fext = fext2 + fext out_file = op.abspath('./%s_denoise%s' % (fname, fext)) img = nb.load(in_file) hdr = img.get_header() data = img.get_data() aff = img.get_affine() nmask = data[..., 0] > 80 if noise_mask is not None: nmask = noise_mask > 0 sigma = np.std(data[nmask == 1]) den = nlmeans(data, sigma, **settings) nb.Nifti1Image(den.astype(hdr.get_data_dtype()), aff, hdr).to_filename(out_file) return out_file, sigma nipype-0.11.0/nipype/interfaces/dipy/simulate.py000066400000000000000000000302271257611314500216770ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import ( traits, TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File, InputMultiPath, isdefined) from nipype.utils.filemanip import split_filename import os.path as op import nibabel as nb import numpy as np from nipype.utils.misc import package_check import warnings from multiprocessing import (Process, Pool, cpu_count, pool, Manager, TimeoutError) from ... import logging iflogger = logging.getLogger('interface') have_dipy = True try: package_check('dipy', version='0.8.0') except Exception, e: have_dipy = False else: import numpy as np from dipy.sims.voxel import (multi_tensor, add_noise, all_tensor_evecs) from dipy.core.gradients import gradient_table class SimulateMultiTensorInputSpec(BaseInterfaceInputSpec): in_dirs = InputMultiPath(File(exists=True), mandatory=True, desc='list of fibers (principal directions)') in_frac = InputMultiPath(File(exists=True), mandatory=True, desc=('volume fraction of each fiber')) in_vfms = InputMultiPath(File(exists=True), mandatory=True, desc=('volume fractions of isotropic ' 'compartiments')) in_mask = File(exists=True, desc='mask to simulate data') diff_iso = traits.List( [3000e-6, 960e-6, 680e-6], traits.Float, usedefault=True, desc='Diffusivity of isotropic compartments') diff_sf = traits.Tuple( (1700e-6, 200e-6, 200e-6), traits.Float, traits.Float, traits.Float, usedefault=True, desc='Single fiber tensor') n_proc = traits.Int(0, usedefault=True, desc='number of processes') baseline = File(exists=True, mandatory=True, desc='baseline T2 signal') gradients = File(exists=True, desc='gradients file') in_bvec = File(exists=True, desc='input bvecs file') in_bval = File(exists=True, desc='input bvals file') num_dirs = traits.Int(32, usedefault=True, desc=('number of gradient directions (when table ' 'is automatically generated)')) bvalues = traits.List(traits.Int, value=[1000, 3000], usedefault=True, desc=('list of b-values (when table ' 'is automatically generated)')) out_file = File('sim_dwi.nii.gz', usedefault=True, desc='output file with fractions to be simluated') out_mask = File('sim_msk.nii.gz', usedefault=True, desc='file with the mask simulated') out_bvec = File('bvec.sim', usedefault=True, desc='simulated b vectors') out_bval = File('bval.sim', usedefault=True, desc='simulated b values') snr = traits.Int(0, usedefault=True, desc='signal-to-noise ratio (dB)') class SimulateMultiTensorOutputSpec(TraitedSpec): out_file = File(exists=True, desc='simulated DWIs') out_mask = File(exists=True, desc='mask file') out_bvec = File(exists=True, desc='simulated b vectors') out_bval = File(exists=True, desc='simulated b values') class SimulateMultiTensor(BaseInterface): """ Interface to MultiTensor model simulator in dipy http://nipy.org/dipy/examples_built/simulate_multi_tensor.html Example ------- >>> import nipype.interfaces.dipy as dipy >>> sim = dipy.SimulateMultiTensor() >>> sim.inputs.in_dirs = ['fdir00.nii', 'fdir01.nii'] >>> sim.inputs.in_frac = ['ffra00.nii', 'ffra01.nii'] >>> sim.inputs.in_vfms = ['tpm_00.nii.gz', 'tpm_01.nii.gz', ... 'tpm_02.nii.gz'] >>> sim.inputs.baseline = 'b0.nii' >>> sim.inputs.in_bvec = 'bvecs' >>> sim.inputs.in_bval = 'bvals' >>> sim.run() # doctest: +SKIP """ input_spec = SimulateMultiTensorInputSpec output_spec = SimulateMultiTensorOutputSpec def _run_interface(self, runtime): # Gradient table if isdefined(self.inputs.in_bval) and isdefined(self.inputs.in_bvec): # Load the gradient strengths and directions bvals = np.loadtxt(self.inputs.in_bval) bvecs = np.loadtxt(self.inputs.in_bvec).T gtab = gradient_table(bvals, bvecs) else: gtab = _generate_gradients(self.inputs.num_dirs, self.inputs.bvalues) ndirs = len(gtab.bvals) np.savetxt(op.abspath(self.inputs.out_bvec), gtab.bvecs.T) np.savetxt(op.abspath(self.inputs.out_bval), gtab.bvals) # Load the baseline b0 signal b0_im = nb.load(self.inputs.baseline) hdr = b0_im.get_header() shape = b0_im.get_shape() aff = b0_im.get_affine() # Check and load sticks and their volume fractions nsticks = len(self.inputs.in_dirs) if len(self.inputs.in_frac) != nsticks: raise RuntimeError(('Number of sticks and their volume fractions' ' must match.')) # Volume fractions of isotropic compartments nballs = len(self.inputs.in_vfms) vfs = np.squeeze(nb.concat_images( [nb.load(f) for f in self.inputs.in_vfms]).get_data()) if nballs == 1: vfs = vfs[..., np.newaxis] total_vf = np.sum(vfs, axis=3) # Generate a mask if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() msk[msk > 0.0] = 1.0 msk[msk < 1.0] = 0.0 else: msk = np.zeros(shape) msk[total_vf > 0.0] = 1.0 msk = np.clip(msk, 0.0, 1.0) nvox = len(msk[msk > 0]) # Fiber fractions ffsim = nb.concat_images([nb.load(f) for f in self.inputs.in_frac]) ffs = np.nan_to_num(np.squeeze(ffsim.get_data())) # fiber fractions ffs = np.clip(ffs, 0., 1.) if nsticks == 1: ffs = ffs[..., np.newaxis] for i in range(nsticks): ffs[..., i] *= msk total_ff = np.sum(ffs, axis=3) # Fix incongruencies in fiber fractions for i in range(1, nsticks): if np.any(total_ff > 1.0): errors = np.zeros_like(total_ff) errors[total_ff > 1.0] = total_ff[total_ff > 1.0] - 1.0 ffs[..., i] -= errors ffs[ffs < 0.0] = 0.0 total_ff = np.sum(ffs, axis=3) for i in range(vfs.shape[-1]): vfs[..., i] -= total_ff vfs = np.clip(vfs, 0., 1.) fractions = np.concatenate((ffs, vfs), axis=3) nb.Nifti1Image(fractions, aff, None).to_filename('fractions.nii.gz') nb.Nifti1Image(np.sum(fractions, axis=3), aff, None).to_filename( 'total_vf.nii.gz') mhdr = hdr.copy() mhdr.set_data_dtype(np.uint8) mhdr.set_xyzt_units('mm', 'sec') nb.Nifti1Image(msk, aff, mhdr).to_filename( op.abspath(self.inputs.out_mask)) # Initialize stack of args fracs = fractions[msk > 0] # Stack directions dirs = None for i in range(nsticks): f = self.inputs.in_dirs[i] fd = np.nan_to_num(nb.load(f).get_data()) w = np.linalg.norm(fd, axis=3)[..., np.newaxis] w[w < np.finfo(float).eps] = 1.0 fd /= w if dirs is None: dirs = fd[msk > 0].copy() else: dirs = np.hstack((dirs, fd[msk > 0])) # Add random directions for isotropic components for d in range(nballs): fd = np.random.randn(nvox, 3) w = np.linalg.norm(fd, axis=1) fd[w < np.finfo(float).eps, ...] = np.array([1., 0., 0.]) w[w < np.finfo(float).eps] = 1.0 fd /= w[..., np.newaxis] dirs = np.hstack((dirs, fd)) sf_evals = list(self.inputs.diff_sf) ba_evals = list(self.inputs.diff_iso) mevals = [sf_evals] * nsticks + \ [[ba_evals[d]] * 3 for d in range(nballs)] b0 = b0_im.get_data()[msk > 0] args = [] for i in range(nvox): args.append( {'fractions': fracs[i, ...].tolist(), 'sticks': [tuple(dirs[i, j:j + 3]) for j in range(nsticks + nballs)], 'gradients': gtab, 'mevals': mevals, 'S0': b0[i], 'snr': self.inputs.snr }) n_proc = self.inputs.n_proc if n_proc == 0: n_proc = cpu_count() try: pool = Pool(processes=n_proc, maxtasksperchild=50) except TypeError: pool = Pool(processes=n_proc) # Simulate sticks using dipy iflogger.info(('Starting simulation of %d voxels, %d diffusion' ' directions.') % (len(args), ndirs)) result = np.array(pool.map(_compute_voxel, args)) if np.shape(result)[1] != ndirs: raise RuntimeError(('Computed directions do not match number' 'of b-values.')) signal = np.zeros((shape[0], shape[1], shape[2], ndirs)) signal[msk > 0] = result simhdr = hdr.copy() simhdr.set_data_dtype(np.float32) simhdr.set_xyzt_units('mm', 'sec') nb.Nifti1Image(signal.astype(np.float32), aff, simhdr).to_filename(op.abspath(self.inputs.out_file)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self.inputs.out_file) outputs['out_mask'] = op.abspath(self.inputs.out_mask) outputs['out_bvec'] = op.abspath(self.inputs.out_bvec) outputs['out_bval'] = op.abspath(self.inputs.out_bval) return outputs def _compute_voxel(args): """ Simulate DW signal for one voxel. Uses the multi-tensor model and three isotropic compartments. Apparent diffusivity tensors are taken from [Alexander2002]_ and [Pierpaoli1996]_. .. [Alexander2002] Alexander et al., Detection and modeling of non-Gaussian apparent diffusion coefficient profiles in human brain data, MRM 48(2):331-340, 2002, doi: `10.1002/mrm.10209 `_. .. [Pierpaoli1996] Pierpaoli et al., Diffusion tensor MR imaging of the human brain, Radiology 201:637-648. 1996. """ ffs = args['fractions'] gtab = args['gradients'] signal = np.zeros_like(gtab.bvals, dtype=np.float32) # Simulate dwi signal sf_vf = np.sum(ffs) if sf_vf > 0.0: ffs = ((np.array(ffs) / sf_vf) * 100) snr = args['snr'] if args['snr'] > 0 else None try: signal, _ = multi_tensor( gtab, args['mevals'], S0=args['S0'], angles=args['sticks'], fractions=ffs, snr=snr) except Exception as e: pass # iflogger.warn('Exception simulating dwi signal: %s' % e) return signal.tolist() def _generate_gradients(ndirs=64, values=[1000, 3000], nb0s=1): """ Automatically generate a `gradient table `_ """ import numpy as np from dipy.core.sphere import (disperse_charges, Sphere, HemiSphere) from dipy.core.gradients import gradient_table theta = np.pi * np.random.rand(ndirs) phi = 2 * np.pi * np.random.rand(ndirs) hsph_initial = HemiSphere(theta=theta, phi=phi) hsph_updated, potential = disperse_charges(hsph_initial, 5000) values = np.atleast_1d(values).tolist() vertices = hsph_updated.vertices bvecs = vertices.copy() bvals = np.ones(vertices.shape[0]) * values[0] for v in values[1:]: bvecs = np.vstack((bvecs, vertices)) bvals = np.hstack((bvals, v * np.ones(vertices.shape[0]))) for i in xrange(0, nb0s): bvals = bvals.tolist() bvals.insert(0, 0) bvecs = bvecs.tolist() bvecs.insert(0, np.zeros(3)) return gradient_table(bvals, bvecs) nipype-0.11.0/nipype/interfaces/dipy/tensors.py000066400000000000000000000142361257611314500215530ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import ( TraitedSpec, BaseInterface, File) from nipype.utils.filemanip import split_filename import os.path as op import nibabel as nb import numpy as np from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_dipy = True try: package_check('dipy', version='0.6.0') except Exception, e: have_dipy = False else: import dipy.reconst.dti as dti from dipy.core.gradients import gradient_table from dipy.io.utils import nifti1_symmat def tensor_fitting(data, bvals, bvecs, mask_file=None): """ Use dipy to fit DTI Parameters ---------- in_file : str Full path to a DWI data file. bvals : str Full path to a file containing gradient magnitude information (b-values). bvecs : str Full path to a file containing gradient direction information (b-vectors). mask_file : str, optional Full path to a file containing a binary mask. Defaults to use the entire volume. Returns ------- TensorFit object, affine """ img = nb.load(in_file).get_data() data = img.get_data() affine = img.get_affine() if mask_file is not None: mask = nb.load(self.inputs.mask_file).get_data() else: mask=None # Load information about the gradients: gtab = grad.gradient_table(self.inputs.bvals, self.inputs.bvecs) # Fit it tenmodel = dti.TensorModel(gtab) return tenmodel.fit(data, mask), affine class DTIInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input 4D diffusion-weighted image file') bvecs = File(exists=True, mandatory=True, desc='The input b-vector text file') bvals = File(exists=True, mandatory=True, desc='The input b-value text file') mask_file = File(exists=True, desc='An optional white matter mask') out_filename = File( genfile=True, desc='The output filename for the DTI parameters image') class DTIOutputSpec(TraitedSpec): out_file = File(exists=True) class DTI(BaseInterface): """ Calculates the diffusion tensor model parameters Example ------- >>> import nipype.interfaces.dipy as dipy >>> dti = dipy.DTI() >>> dti.inputs.in_file = 'diffusion.nii' >>> dti.inputs.bvecs = 'bvecs' >>> dti.inputs.bvals = 'bvals' >>> dti.run() # doctest: +SKIP """ input_spec = DTIInputSpec output_spec = DTIOutputSpec def _run_interface(self, runtime): ten_fit, affine = tensor_fitting(self.inputs.in_file, self.inputs.bvals, self.inputs.bvecs, self.inputs.mask_file) lower_triangular = tenfit.lower_triangular() img = nifti1_symmat(lower_triangular, affine) out_file = op.abspath(self._gen_outfilename()) nb.save(img, out_file) iflogger.info('DTI parameters image saved as {i}'.format(i=out_file)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name, _ = split_filename(self.inputs.in_file) return name + '_dti.nii' class TensorModeInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input 4D diffusion-weighted image file') bvecs = File(exists=True, mandatory=True, desc='The input b-vector text file') bvals = File(exists=True, mandatory=True, desc='The input b-value text file') mask_file = File(exists=True, desc='An optional white matter mask') out_filename = File( genfile=True, desc='The output filename for the Tensor mode image') class TensorModeOutputSpec(TraitedSpec): out_file = File(exists=True) class TensorMode(BaseInterface): """ Creates a map of the mode of the diffusion tensors given a set of diffusion-weighted images, as well as their associated b-values and b-vectors. Fits the diffusion tensors and calculates tensor mode with Dipy. .. [1] Daniel B. Ennis and G. Kindlmann, "Orthogonal Tensor Invariants and the Analysis of Diffusion Tensor Magnetic Resonance Images", Magnetic Resonance in Medicine, vol. 55, no. 1, pp. 136-146, 2006. Example ------- >>> import nipype.interfaces.dipy as dipy >>> mode = dipy.TensorMode() >>> mode.inputs.in_file = 'diffusion.nii' >>> mode.inputs.bvecs = 'bvecs' >>> mode.inputs.bvals = 'bvals' >>> mode.run() # doctest: +SKIP """ input_spec = TensorModeInputSpec output_spec = TensorModeOutputSpec def _run_interface(self, runtime): ten_fit = tensor_fitting(self.inputs.in_file, self.inputs.bvals, self.inputs.bvecs, self.inputs.mask_file) ## Write as a 3D Nifti image with the original affine img = nb.Nifti1Image(tenfit.mode, affine) out_file = op.abspath(self._gen_outfilename()) nb.save(img, out_file) iflogger.info('Tensor mode image saved as {i}'.format(i=out_file)) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name, _ = split_filename(self.inputs.in_file) return name + '_mode.nii' nipype-0.11.0/nipype/interfaces/dipy/tests/000077500000000000000000000000001257611314500206405ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_DTI.py000066400000000000000000000015161257611314500237240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.tensors import DTI def test_DTI_inputs(): input_map = dict(bvals=dict(mandatory=True, ), bvecs=dict(mandatory=True, ), in_file=dict(mandatory=True, ), mask_file=dict(), out_filename=dict(genfile=True, ), ) inputs = DTI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTI_outputs(): output_map = dict(out_file=dict(), ) outputs = DTI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_Denoise.py000066400000000000000000000015661257611314500246770ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.preprocess import Denoise def test_Denoise_inputs(): input_map = dict(block_radius=dict(), in_file=dict(mandatory=True, ), in_mask=dict(), noise_mask=dict(), noise_model=dict(mandatory=True, usedefault=True, ), patch_radius=dict(), ) inputs = Denoise.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Denoise_outputs(): output_map = dict(out_file=dict(), ) outputs = Denoise.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_Resample.py000066400000000000000000000014561257611314500250570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.preprocess import Resample def test_Resample_inputs(): input_map = dict(in_file=dict(mandatory=True, ), interp=dict(mandatory=True, usedefault=True, ), vox_size=dict(), ) inputs = Resample.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Resample_outputs(): output_map = dict(out_file=dict(), ) outputs = Resample.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_SimulateMultiTensor.py000066400000000000000000000027721257611314500273020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.simulate import SimulateMultiTensor def test_SimulateMultiTensor_inputs(): input_map = dict(baseline=dict(mandatory=True, ), bvalues=dict(usedefault=True, ), diff_iso=dict(usedefault=True, ), diff_sf=dict(usedefault=True, ), gradients=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(), in_dirs=dict(mandatory=True, ), in_frac=dict(mandatory=True, ), in_mask=dict(), in_vfms=dict(mandatory=True, ), n_proc=dict(usedefault=True, ), num_dirs=dict(usedefault=True, ), out_bval=dict(usedefault=True, ), out_bvec=dict(usedefault=True, ), out_file=dict(usedefault=True, ), out_mask=dict(usedefault=True, ), snr=dict(usedefault=True, ), ) inputs = SimulateMultiTensor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SimulateMultiTensor_outputs(): output_map = dict(out_bval=dict(), out_bvec=dict(), out_file=dict(), out_mask=dict(), ) outputs = SimulateMultiTensor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_TensorMode.py000066400000000000000000000015611257611314500253630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.tensors import TensorMode def test_TensorMode_inputs(): input_map = dict(bvals=dict(mandatory=True, ), bvecs=dict(mandatory=True, ), in_file=dict(mandatory=True, ), mask_file=dict(), out_filename=dict(genfile=True, ), ) inputs = TensorMode.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TensorMode_outputs(): output_map = dict(out_file=dict(), ) outputs = TensorMode.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tests/test_auto_TrackDensityMap.py000066400000000000000000000016331257611314500263460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dipy.tracks import TrackDensityMap def test_TrackDensityMap_inputs(): input_map = dict(data_dims=dict(), in_file=dict(mandatory=True, ), out_filename=dict(usedefault=True, ), points_space=dict(usedefault=True, ), reference=dict(), voxel_dims=dict(), ) inputs = TrackDensityMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TrackDensityMap_outputs(): output_map = dict(out_file=dict(), ) outputs = TrackDensityMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/dipy/tracks.py000066400000000000000000000074231257611314500213450ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import ( TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File, isdefined, traits) from nipype.utils.filemanip import split_filename import os.path as op import nibabel as nb import nibabel.trackvis as nbt from nipype.utils.misc import package_check import warnings from ... import logging iflogger = logging.getLogger('interface') have_dipy = True try: package_check('dipy', version='0.6.0') except Exception, e: have_dipy = False else: from dipy.tracking.utils import density_map class TrackDensityMapInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input TrackVis track file') reference = File(exists=True, desc='A reference file to define RAS coordinates space') points_space = traits.Enum('rasmm', 'voxel', None, usedefault=True, desc='coordinates of trk file') voxel_dims = traits.List(traits.Float, minlen=3, maxlen=3, desc='The size of each voxel in mm.') data_dims = traits.List(traits.Int, minlen=3, maxlen=3, desc='The size of the image in voxels.') out_filename = File('tdi.nii', usedefault=True, desc=('The output filename for the tracks in TrackVis ' '(.trk) format')) class TrackDensityMapOutputSpec(TraitedSpec): out_file = File(exists=True) class TrackDensityMap(BaseInterface): """ Creates a tract density image from a TrackVis track file using functions from dipy Example ------- >>> import nipype.interfaces.dipy as dipy >>> trk2tdi = dipy.TrackDensityMap() >>> trk2tdi.inputs.in_file = 'converted.trk' >>> trk2tdi.run() # doctest: +SKIP """ input_spec = TrackDensityMapInputSpec output_spec = TrackDensityMapOutputSpec def _run_interface(self, runtime): tracks, header = nbt.read(self.inputs.in_file) streams = ((ii[0]) for ii in tracks) if isdefined(self.inputs.reference): refnii = nb.load(self.inputs.reference) affine = refnii.get_affine() data_dims = refnii.get_shape()[:3] kwargs = dict(affine=affine) else: iflogger.warn(('voxel_dims and data_dims are deprecated' 'as of dipy 0.7.1. Please use reference ' 'input instead')) if not isdefined(self.inputs.data_dims): data_dims = header['dim'] else: data_dims = self.inputs.data_dims if not isdefined(self.inputs.voxel_dims): voxel_size = header['voxel_size'] else: voxel_size = self.inputs.voxel_dims affine = header['vox_to_ras'] kwargs = dict(voxel_size=voxel_size) data = density_map(streams, data_dims, **kwargs) data = data.astype(np.min_scalar_type(data.max())) img = nb.Nifti1Image(data, affine) out_file = op.abspath(self.inputs.out_filename) nb.save(img, out_file) iflogger.info( ('Track density map saved as {i}, size={d}, ' 'dimensions={v}').format( i=out_file, d=img.get_shape(), v=img.get_header().get_zooms())) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self.inputs.out_filename) return outputs nipype-0.11.0/nipype/interfaces/dynamic_slicer.py000066400000000000000000000170101257611314500220670ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import warnings import xml.dom.minidom from nipype.interfaces.base import (CommandLine, CommandLineInputSpec, DynamicTraitedSpec, traits, Undefined, File, isdefined) class SlicerCommandLineInputSpec(DynamicTraitedSpec, CommandLineInputSpec): module = traits.Str(desc="name of the Slicer command line module you want to use") class SlicerCommandLine(CommandLine): """Experimental Slicer wrapper. Work in progress. """ _cmd = "Slicer3" input_spec = SlicerCommandLineInputSpec output_spec = DynamicTraitedSpec def _grab_xml(self, module): cmd = CommandLine(command = "Slicer3", args="--launch %s --xml"%module) ret = cmd.run() if ret.runtime.returncode == 0: return xml.dom.minidom.parseString(ret.runtime.stdout) else: raise Exception(cmd.cmdline + " failed:\n%s"%ret.runtime.stderr) def _outputs(self): base = super(SlicerCommandLine, self)._outputs() undefined_output_traits = {} for key in [node.getElementsByTagName('name')[0].firstChild.nodeValue for node in self._outputs_nodes]: base.add_trait(key, File(exists = True)) undefined_output_traits[key] = Undefined base.trait_set(trait_change_notify=False, **undefined_output_traits) return base def __init__(self, module, **inputs): warnings.warn('slicer is Not fully implemented', RuntimeWarning) super(SlicerCommandLine, self).__init__(command= "Slicer3 --launch %s "%module, name= module, **inputs) dom = self._grab_xml(module) self._outputs_filenames = {} self._outputs_nodes = [] undefined_traits = {} for paramGroup in dom.getElementsByTagName("parameters"): for param in paramGroup.childNodes: if param.nodeName in ['label', 'description', '#text', '#comment']: continue traitsParams = {} name = param.getElementsByTagName('name')[0].firstChild.nodeValue longFlagNode = param.getElementsByTagName('longflag') if longFlagNode: traitsParams["argstr"] = "--" + longFlagNode[0].firstChild.nodeValue + " " else: traitsParams["argstr"] = "--" + name + " " argsDict = {'file': '%s', 'integer': "%d", 'double': "%f", 'float': "%f", 'image': "%s", 'transform': "%s", 'boolean': '', 'string-enumeration': '%s', 'string': "%s"} if param.nodeName.endswith('-vector'): traitsParams["argstr"] += argsDict[param.nodeName[:-7]] else: traitsParams["argstr"] += argsDict[param.nodeName] index = param.getElementsByTagName('index') if index: traitsParams["position"] = index[0].firstChild.nodeValue desc = param.getElementsByTagName('description') if index: traitsParams["desc"] = desc[0].firstChild.nodeValue name = param.getElementsByTagName('name')[0].firstChild.nodeValue typesDict = {'integer': traits.Int, 'double': traits.Float, 'float': traits.Float, 'image': File, 'transform': File, 'boolean': traits.Bool, 'string': traits.Str, 'file':File} if param.nodeName == 'string-enumeration': type = traits.Enum values = [el.firstChild.nodeValue for el in param.getElementsByTagName('element')] elif param.nodeName.endswith('-vector'): type = traits.List values = [typesDict[param.nodeName[:-7]]] traitsParams["sep"] = ',' else: values = [] type = typesDict[param.nodeName] if param.nodeName in ['file', 'directory', 'image', 'transform'] and param.getElementsByTagName('channel')[0].firstChild.nodeValue == 'output': self.inputs.add_trait(name, traits.Either(traits.Bool, File, **traitsParams)) undefined_traits[name] = Undefined #traitsParams["exists"] = True self._outputs_filenames[name] = self._gen_filename_from_param(param) #undefined_output_traits[name] = Undefined #self._outputs().add_trait(name, File(*values, **traitsParams)) self._outputs_nodes.append(param) else: if param.nodeName in ['file', 'directory', 'image', 'transform']: traitsParams["exists"] = True self.inputs.add_trait(name, type(*values, **traitsParams)) undefined_traits[name] = Undefined self.inputs.trait_set(trait_change_notify=False, **undefined_traits) for name in undefined_traits.keys(): _ = getattr(self.inputs, name) #self._outputs().trait_set(trait_change_notify=False, **undefined_output_traits) def _gen_filename(self, name): if name in self._outputs_filenames: return os.path.join(os.getcwd(), self._outputs_filenames[name]) return None def _gen_filename_from_param(self,param): base = param.getElementsByTagName('name')[0].firstChild.nodeValue fileExtensions = param.getAttribute("fileExtensions") if fileExtensions: ext = fileExtensions else: ext = {'image': '.nii', 'transform': '.txt', 'file': ''}[param.nodeName] return base + ext def _list_outputs(self): outputs = self.output_spec().get() for output_node in self._outputs_nodes: name = output_node.getElementsByTagName('name')[0].firstChild.nodeValue outputs[name] = getattr(self.inputs, name) if isdefined(outputs[name]) and isinstance(outputs[name], bool): if outputs[name]: outputs[name] = self._gen_filename(name) else: outputs[name] = Undefined return outputs def _format_arg(self, name, spec, value): if name in [output_node.getElementsByTagName('name')[0].firstChild.nodeValue for output_node in self._outputs_nodes]: if isinstance(value, bool): fname = self._gen_filename(name) else: fname = value return spec.argstr % fname return super(SlicerCommandLine, self)._format_arg(name, spec, value) # test = SlicerCommandLine(module="BRAINSFit") # test.inputs.fixedVolume = "/home/filo/workspace/fmri_tumour/data/pilot1/10_co_COR_3D_IR_PREP.nii" # test.inputs.movingVolume = "/home/filo/workspace/fmri_tumour/data/pilot1/2_line_bisection.nii" # test.inputs.outputTransform = True # test.inputs.transformType = ["Affine"] # print test.cmdline # print test.inputs # print test._outputs() # ret = test.run() # test = SlicerCommandLine(name="BRAINSResample") # test.inputs.referenceVolume = "/home/filo/workspace/fmri_tumour/data/pilot1/10_co_COR_3D_IR_PREP.nii" # test.inputs.inputVolume = "/home/filo/workspace/fmri_tumour/data/pilot1/2_line_bisection.nii" # test.inputs.outputVolume = True # test.inputs.warpTransform = "/home/filo/workspace/nipype/nipype/interfaces/outputTransform.mat" # print test.cmdline # ret = test.run() # print ret.runtime.stderr # print ret.runtime.returncode nipype-0.11.0/nipype/interfaces/elastix/000077500000000000000000000000001257611314500202025ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/elastix/__init__.py000066400000000000000000000004251257611314500223140ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Top-level namespace for elastix.""" from registration import Registration, ApplyWarp, AnalyzeWarp, PointsWarp from utils import EditTransform nipype-0.11.0/nipype/interfaces/elastix/base.py000066400000000000000000000014711257611314500214710ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The :py:mod:`nipype.interfaces.elastix` provides the interface to the elastix registration software. .. note:: http://elastix.isi.uu.nl/ """ from ..base import (CommandLine, CommandLineInputSpec, isdefined, TraitedSpec, File, Directory, traits, InputMultiPath) from ... import logging logger = logging.getLogger('interface') class ElastixBaseInputSpec(CommandLineInputSpec): output_path = Directory('./', exists=True, mandatory=True, usedefault=True, argstr='-out %s', desc='output directory') num_threads = traits.Int( 1, argstr='-threads %01d', nohash=True, desc='set the maximum number of threads of elastix') nipype-0.11.0/nipype/interfaces/elastix/registration.py000066400000000000000000000177041257611314500232770ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Interfaces to perform image registrations and to apply the resulting displacement maps to images and points. """ import os.path as op import re from ..base import (CommandLine, CommandLineInputSpec, isdefined, TraitedSpec, File, traits, InputMultiPath) from base import ElastixBaseInputSpec from ... import logging logger = logging.getLogger('interface') class RegistrationInputSpec(ElastixBaseInputSpec): fixed_image = File(exists=True, mandatory=True, argstr='-f %s', desc='fixed image') moving_image = File(exists=True, mandatory=True, argstr='-m %s', desc='moving image') parameters = InputMultiPath(File(exists=True), mandatory=True, argstr='-p %s...', desc='parameter file, elastix handles 1 or more -p') fixed_mask = File(exists=True, argstr='-fMask %s', desc='mask for fixed image') moving_mask = File(exists=True, argstr='-mMask %s', desc='mask for moving image') initial_transform = File(exists=True, argstr='-t0 %s', desc='parameter file for initial transform') class RegistrationOutputSpec(TraitedSpec): transform = InputMultiPath(File(exists=True), desc='output transform') warped_file = File(desc='input moving image warped to fixed image') warped_files = InputMultiPath(File(exists=False), desc=('input moving image warped to fixed image at each level')) warped_files_flags = traits.List(traits.Bool(False), desc='flag indicating if warped image was generated') class Registration(CommandLine): """ Elastix nonlinear registration interface Example ------- >>> from nipype.interfaces.elastix import Registration >>> reg = Registration() >>> reg.inputs.fixed_image = 'fixed1.nii' >>> reg.inputs.moving_image = 'moving1.nii' >>> reg.inputs.parameters = ['elastix.txt'] >>> reg.cmdline 'elastix -f fixed1.nii -m moving1.nii -out ./ -p elastix.txt' """ _cmd = 'elastix' input_spec = RegistrationInputSpec output_spec = RegistrationOutputSpec def _list_outputs(self): outputs = self._outputs().get() out_dir = op.abspath(self.inputs.output_path) opts = [ 'WriteResultImage', 'ResultImageFormat' ] regex = re.compile(r'^\((\w+)\s(.+)\)$') outputs['transform'] = [] outputs['warped_files'] = [] outputs['warped_files_flags'] = [] for i,params in enumerate(self.inputs.parameters): config = {} with open(params, 'r') as f: for line in f.readlines(): line = line.strip() if not line.startswith('//') and line: m = regex.search(line) if m: value = self._cast(m.group(2).strip()) config[m.group(1).strip()] = value outputs['transform'].append(op.join(out_dir, 'TransformParameters.%01d.txt' % i )) warped_file = None if config['WriteResultImage']: warped_file = op.join(out_dir, 'result.%01d.%s' %(i,config['ResultImageFormat'])) outputs['warped_files'].append(warped_file) outputs['warped_files_flags'].append(config['WriteResultImage']) if outputs['warped_files_flags'][-1]: outputs['warped_file'] = outputs['warped_files'][-1] return outputs def _cast(self,val): if val.startswith('"') and val.endswith('"'): if val == '"true"': return True elif val == '"false"': return False else: return val[1:-1] try: return int(val) except ValueError: try: return float(val) except ValueError: return val class ApplyWarpInputSpec(ElastixBaseInputSpec): transform_file = File(exists=True, mandatory=True, argstr='-tp %s', desc='transform-parameter file, only 1') moving_image = File(exists=True, argstr='-in %s', mandatory=True, desc='input image to deform') class ApplyWarpOutputSpec(TraitedSpec): warped_file = File(desc='input moving image warped to fixed image') class ApplyWarp(CommandLine): """ Use ``transformix`` to apply a transform on an input image. The transform is specified in the transform-parameter file. Example ------- >>> from nipype.interfaces.elastix import ApplyWarp >>> reg = ApplyWarp() >>> reg.inputs.moving_image = 'moving1.nii' >>> reg.inputs.transform_file = 'TransformParameters.0.txt' >>> reg.cmdline 'transformix -in moving1.nii -out ./ -tp TransformParameters.0.txt' """ _cmd = 'transformix' input_spec = ApplyWarpInputSpec output_spec = ApplyWarpOutputSpec def _list_outputs(self): outputs = self._outputs().get() out_dir = op.abspath(self.inputs.output_path) outputs['warped_file'] = op.join(out_dir,'result.nii.gz') return outputs class AnalyzeWarpInputSpec(ElastixBaseInputSpec): transform_file = File(exists=True, mandatory=True, argstr='-tp %s', desc='transform-parameter file, only 1') class AnalyzeWarpOutputSpec(TraitedSpec): disp_field = File(desc='displacements field') jacdet_map = File(desc='det(Jacobian) map') jacmat_map = File(desc='Jacobian matrix map') class AnalyzeWarp(CommandLine): """ Use transformix to get details from the input transform (generate the corresponding deformation field, generate the determinant of the Jacobian map or the Jacobian map itself) Example ------- >>> from nipype.interfaces.elastix import AnalyzeWarp >>> reg = AnalyzeWarp() >>> reg.inputs.transform_file = 'TransformParameters.0.txt' >>> reg.cmdline 'transformix -def all -jac all -jacmat all -out ./ -tp TransformParameters.0.txt' """ _cmd = 'transformix -def all -jac all -jacmat all' input_spec = AnalyzeWarpInputSpec output_spec = AnalyzeWarpOutputSpec def _list_outputs(self): outputs = self._outputs().get() out_dir = op.abspath(self.inputs.output_path) outputs['disp_field'] = op.join(out_dir,'deformationField.nii.gz') outputs['jacdet_map'] = op.join(out_dir,'spatialJacobian.nii.gz') outputs['jacmat_map'] = op.join(out_dir,'fullSpatialJacobian.nii.gz') return outputs class PointsWarpInputSpec(ElastixBaseInputSpec): points_file = File(exists=True, argstr='-def %s', mandatory=True, desc='input points (accepts .vtk triangular meshes).') transform_file = File(exists=True, mandatory=True, argstr='-tp %s', desc='transform-parameter file, only 1') class PointsWarpOutputSpec(TraitedSpec): warped_file = File(desc='input points displaced in fixed image domain') class PointsWarp(CommandLine): """Use ``transformix`` to apply a transform on an input point set. The transform is specified in the transform-parameter file. Example ------- >>> from nipype.interfaces.elastix import PointsWarp >>> reg = PointsWarp() >>> reg.inputs.points_file = 'surf1.vtk' >>> reg.inputs.transform_file = 'TransformParameters.0.txt' >>> reg.cmdline 'transformix -out ./ -def surf1.vtk -tp TransformParameters.0.txt' """ _cmd = 'transformix' input_spec = PointsWarpInputSpec output_spec = PointsWarpOutputSpec def _list_outputs(self): outputs = self._outputs().get() out_dir = op.abspath(self.inputs.output_path) fname, ext = op.splitext(op.basename(self.inputs.points_file)) outputs['warped_file'] = op.join(out_dir,'outputpoints%s' % ext) return outputs nipype-0.11.0/nipype/interfaces/elastix/tests/000077500000000000000000000000001257611314500213445ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/elastix/tests/test_auto_AnalyzeWarp.py000066400000000000000000000022451257611314500262450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.elastix.registration import AnalyzeWarp def test_AnalyzeWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_threads=dict(argstr='-threads %01d', nohash=True, ), output_path=dict(argstr='-out %s', mandatory=True, usedefault=True, ), terminal_output=dict(nohash=True, ), transform_file=dict(argstr='-tp %s', mandatory=True, ), ) inputs = AnalyzeWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AnalyzeWarp_outputs(): output_map = dict(disp_field=dict(), jacdet_map=dict(), jacmat_map=dict(), ) outputs = AnalyzeWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/elastix/tests/test_auto_ApplyWarp.py000066400000000000000000000022601257611314500257240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.elastix.registration import ApplyWarp def test_ApplyWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), moving_image=dict(argstr='-in %s', mandatory=True, ), num_threads=dict(argstr='-threads %01d', nohash=True, ), output_path=dict(argstr='-out %s', mandatory=True, usedefault=True, ), terminal_output=dict(nohash=True, ), transform_file=dict(argstr='-tp %s', mandatory=True, ), ) inputs = ApplyWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyWarp_outputs(): output_map = dict(warped_file=dict(), ) outputs = ApplyWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/elastix/tests/test_auto_EditTransform.py000066400000000000000000000021061257611314500265650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.elastix.utils import EditTransform def test_EditTransform_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), interpolation=dict(argstr='FinalBSplineInterpolationOrder', usedefault=True, ), output_file=dict(), output_format=dict(argstr='ResultImageFormat', ), output_type=dict(argstr='ResultImagePixelType', ), reference_image=dict(), transform_file=dict(mandatory=True, ), ) inputs = EditTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EditTransform_outputs(): output_map = dict(output_file=dict(), ) outputs = EditTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/elastix/tests/test_auto_PointsWarp.py000066400000000000000000000022651257611314500261200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.elastix.registration import PointsWarp def test_PointsWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_threads=dict(argstr='-threads %01d', nohash=True, ), output_path=dict(argstr='-out %s', mandatory=True, usedefault=True, ), points_file=dict(argstr='-def %s', mandatory=True, ), terminal_output=dict(nohash=True, ), transform_file=dict(argstr='-tp %s', mandatory=True, ), ) inputs = PointsWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PointsWarp_outputs(): output_map = dict(warped_file=dict(), ) outputs = PointsWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/elastix/tests/test_auto_Registration.py000066400000000000000000000027341257611314500264650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.elastix.registration import Registration def test_Registration_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixed_image=dict(argstr='-f %s', mandatory=True, ), fixed_mask=dict(argstr='-fMask %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), initial_transform=dict(argstr='-t0 %s', ), moving_image=dict(argstr='-m %s', mandatory=True, ), moving_mask=dict(argstr='-mMask %s', ), num_threads=dict(argstr='-threads %01d', nohash=True, ), output_path=dict(argstr='-out %s', mandatory=True, usedefault=True, ), parameters=dict(argstr='-p %s...', mandatory=True, ), terminal_output=dict(nohash=True, ), ) inputs = Registration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Registration_outputs(): output_map = dict(transform=dict(), warped_file=dict(), warped_files=dict(), warped_files_flags=dict(), ) outputs = Registration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/elastix/utils.py000066400000000000000000000131461257611314500217210ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Generic interfaces to manipulate registration parameters files, including transform files (to configure warpings) """ import os.path as op import re from nipype.interfaces.base import (BaseInterface, BaseInterfaceInputSpec, isdefined, TraitedSpec, File, traits, InputMultiPath) from nipype import logging logger = logging.getLogger('interface') class EditTransformInputSpec(BaseInterfaceInputSpec): transform_file = File(exists=True, mandatory=True, desc='transform-parameter file, only 1') reference_image = File(exists=True, desc=('set a new reference image to change the ' 'target coordinate system.')) interpolation = traits.Enum('cubic','linear','nearest', usedefault=True, argstr='FinalBSplineInterpolationOrder', desc='set a new interpolator for transformation') output_type = traits.Enum('float', 'unsigned char', 'unsigned short','short', 'unsigned long','long','double', argstr='ResultImagePixelType', desc='set a new output pixel type for resampled images') output_format = traits.Enum('nii.gz', 'nii', 'mhd', 'hdr', 'vtk', argstr='ResultImageFormat', desc='set a new image format for resampled images') output_file = File(desc='the filename for the resulting transform file') class EditTransformOutputSpec(TraitedSpec): output_file = File(exists=True, desc='output transform file') class EditTransform(BaseInterface): """ Manipulates an existing transform file generated with elastix Example ------- >>> from nipype.interfaces.elastix import EditTransform >>> tfm = EditTransform() >>> tfm.inputs.transform_file = 'TransformParameters.0.txt' >>> tfm.inputs.reference_image = 'fixed1.nii' >>> tfm.inputs.output_type = 'unsigned char' >>> tfm.run() # doctest: +SKIP """ input_spec = EditTransformInputSpec output_spec = EditTransformOutputSpec _out_file = '' _pattern = '\((?P%s\s\"?)([-\.\s\w]+)(\"?\))' _interp = { 'nearest': 0, 'linear': 1, 'cubic': 3 } def _run_interface(self, runtime): import re import nibabel as nb import numpy as np contents = '' with open(self.inputs.transform_file, 'r') as f: contents = f.read() if isdefined(self.inputs.output_type): p = re.compile((self._pattern % 'ResultImagePixelType').decode('string-escape')) rep = '(\g%s\g<3>' % self.inputs.output_type contents = p.sub(rep, contents) if isdefined(self.inputs.output_format): p = re.compile((self._pattern % 'ResultImageFormat').decode('string-escape')) rep = '(\g%s\g<3>' % self.inputs.output_format contents = p.sub(rep, contents) if isdefined(self.inputs.interpolation): p = re.compile((self._pattern % 'FinalBSplineInterpolationOrder').decode('string-escape')) rep = '(\g%s\g<3>' % self._interp[self.inputs.interpolation] contents = p.sub(rep, contents) if isdefined(self.inputs.reference_image): im = nb.load(self.inputs.reference_image) if len(im.get_header().get_zooms()) == 4: im = nb.func.four_to_three(im)[0] size = ' '.join(["%01d" % s for s in im.get_shape() ]) p = re.compile((self._pattern % 'Size').decode('string-escape')) rep = '(\g%s\g<3>' % size contents = p.sub(rep, contents) index = ' '.join(["0" for s in im.get_shape() ]) p = re.compile((self._pattern % 'Index').decode('string-escape')) rep = '(\g%s\g<3>' % index contents = p.sub(rep, contents) spacing = ' '.join(["%0.4f" % f for f in im.get_header().get_zooms()]) p = re.compile((self._pattern % 'Spacing').decode('string-escape')) rep = '(\g%s\g<3>' % spacing contents = p.sub(rep, contents) itkmat = np.eye(4) itkmat[0,0] = -1 itkmat[1,1] = -1 affine = np.dot( itkmat, im.get_affine() ) dirs = ' '.join(['%0.4f' % f for f in affine[0:3,0:3].reshape(-1)]) orig = ' '.join(['%0.4f' % f for f in affine[0:3,3].reshape(-1)]) #p = re.compile((self._pattern % 'Direction').decode('string-escape')) #rep = '(\g%s\g<3>' % dirs #contents = p.sub(rep, contents) p = re.compile((self._pattern % 'Origin').decode('string-escape')) rep = '(\g%s\g<3>' % orig contents = p.sub(rep, contents) with open(self._get_outfile(), 'w') as of: of.write(contents) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['output_file'] = getattr(self, '_out_file') return outputs def _get_outfile(self): val = getattr(self,'_out_file') if not val is None and not val=='': return val if isdefined(self.inputs.output_file): setattr(self,'_out_file',self.inputs.output_file) return self.inputs.output_file out_file = op.abspath(op.basename(self.inputs.transform_file)) setattr(self, '_out_file', out_file) return out_file nipype-0.11.0/nipype/interfaces/freesurfer/000077500000000000000000000000001257611314500207015ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/freesurfer/__init__.py000066400000000000000000000015771257611314500230240ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Top-level namespace for freesurfer.""" from .base import Info, FSCommand from .preprocess import (ParseDICOMDir, UnpackSDICOMDir, MRIConvert, Resample, ReconAll, BBRegister, ApplyVolTransform,Smooth, DICOMConvert, RobustRegister, FitMSParams, SynthesizeFLASH) from .model import (MRISPreproc, GLMFit, OneSampleTTest, Binarize, Concatenate, SegStats, Label2Vol, MS_LDA) from .utils import (SampleToSurface, SurfaceSmooth, SurfaceTransform, Surface2VolTransform, SurfaceSnapshots,ApplyMask, MRIsConvert, MRITessellate, MRIPretess, MRIMarchingCubes, SmoothTessellation, MakeAverageSubject, ExtractMainComponent, Tkregister2) nipype-0.11.0/nipype/interfaces/freesurfer/base.py000066400000000000000000000107311257611314500221670ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The freesurfer module provides basic functions for interfacing with freesurfer tools. Currently these tools are supported: * Dicom2Nifti: using mri_convert * Resample: using mri_convert Examples -------- See the docstrings for the individual classes for 'working' examples. """ __docformat__ = 'restructuredtext' import os from nipype.utils.filemanip import fname_presuffix from nipype.interfaces.base import (CommandLine, Directory, CommandLineInputSpec, isdefined) class Info(object): """ Freesurfer subject directory and version information. Examples -------- >>> from nipype.interfaces.freesurfer import Info >>> Info.version() # doctest: +SKIP >>> Info.subjectsdir() # doctest: +SKIP """ @staticmethod def version(): """Check for freesurfer version on system Find which freesurfer is being used....and get version from /path/to/freesurfer/build-stamp.txt Returns ------- version : string version number as string or None if freesurfer version not found """ fs_home = os.getenv('FREESURFER_HOME') if fs_home is None: return None versionfile = os.path.join(fs_home, 'build-stamp.txt') if not os.path.exists(versionfile): return None fid = open(versionfile, 'rt') version = fid.readline() fid.close() return version @classmethod def subjectsdir(cls): """Check the global SUBJECTS_DIR Parameters ---------- subjects_dir : string The system defined subjects directory Returns ------- subject_dir : string Represents the current environment setting of SUBJECTS_DIR """ if cls.version(): return os.environ['SUBJECTS_DIR'] return None class FSTraitedSpec(CommandLineInputSpec): subjects_dir = Directory(exists=True, desc='subjects directory') class FSCommand(CommandLine): """General support for FreeSurfer commands. Every FS command accepts 'subjects_dir' input. """ input_spec = FSTraitedSpec _subjects_dir = None def __init__(self, **inputs): super(FSCommand, self).__init__(**inputs) self.inputs.on_trait_change(self._subjects_dir_update, 'subjects_dir') if not self._subjects_dir: self._subjects_dir = Info.subjectsdir() if not isdefined(self.inputs.subjects_dir) and self._subjects_dir: self.inputs.subjects_dir = self._subjects_dir self._subjects_dir_update() def _subjects_dir_update(self): if self.inputs.subjects_dir: self.inputs.environ.update({'SUBJECTS_DIR': self.inputs.subjects_dir}) @classmethod def set_default_subjects_dir(cls, subjects_dir): cls._subjects_dir = subjects_dir @property def version(self): return Info.version() def run(self, **inputs): if 'subjects_dir' in inputs: self.inputs.subjects_dir = inputs['subjects_dir'] self._subjects_dir_update() return super(FSCommand, self).run(**inputs) def _gen_fname(self, basename, fname=None, cwd=None, suffix='_fs', use_ext=True): '''Define a generic mapping for a single outfile The filename is potentially autogenerated by suffixing inputs.infile Parameters ---------- basename : string (required) filename to base the new filename on fname : string if not None, just use this fname cwd : string prefix paths with cwd, otherwise os.getcwd() suffix : string default suffix ''' if basename == '': msg = 'Unable to generate filename for command %s. ' % self.cmd msg += 'basename is not set!' raise ValueError(msg) if cwd is None: cwd = os.getcwd() fname = fname_presuffix(basename, suffix=suffix, use_ext=use_ext, newpath=cwd) return fname @property def version(self): ver = Info.version() if ver: if 'dev' in ver: return ver.rstrip().split('-')[-1] + '.dev' else: return ver.rstrip().split('-v')[-1] nipype-0.11.0/nipype/interfaces/freesurfer/model.py000066400000000000000000001217621257611314500223640ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The freesurfer module provides basic functions for interfacing with freesurfer tools. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ __docformat__ = 'restructuredtext' import os from nipype.utils.filemanip import fname_presuffix, split_filename from nipype.interfaces.freesurfer.base import FSCommand, FSTraitedSpec from nipype.interfaces.base import (TraitedSpec, File, traits, InputMultiPath, OutputMultiPath, Directory, isdefined) class MRISPreprocInputSpec(FSTraitedSpec): out_file = File(argstr='--out %s', genfile=True, desc='output filename') target = traits.Str(argstr='--target %s', mandatory=True, desc='target subject name') hemi = traits.Enum('lh', 'rh', argstr='--hemi %s', mandatory=True, desc='hemisphere for source and target') surf_measure = traits.Str(argstr='--meas %s', xor=('surf_measure', 'surf_measure_file', 'surf_area'), desc='Use subject/surf/hemi.surf_measure as input') surf_area = traits.Str(argstr='--area %s', xor=('surf_measure', 'surf_measure_file', 'surf_area'), desc='Extract vertex area from subject/surf/hemi.surfname to use as input.') subjects = traits.List(argstr='--s %s...', xor=('subjects', 'fsgd_file', 'subject_file'), desc='subjects from who measures are calculated') fsgd_file = File(exists=True, argstr='--fsgd %s', xor=('subjects', 'fsgd_file', 'subject_file'), desc='specify subjects using fsgd file') subject_file = File(exists=True, argstr='--f %s', xor=('subjects', 'fsgd_file', 'subject_file'), desc='file specifying subjects separated by white space') surf_measure_file = InputMultiPath(File(exists=True), argstr='--is %s...', xor=('surf_measure', 'surf_measure_file', 'surf_area'), desc='file alternative to surfmeas, still requires list of subjects') source_format = traits.Str(argstr='--srcfmt %s', desc='source format') surf_dir = traits.Str(argstr='--surfdir %s', desc='alternative directory (instead of surf)') vol_measure_file = InputMultiPath(traits.Tuple(File(exists=True), File(exists=True)), argstr='--iv %s %s...', desc='list of volume measure and reg file tuples') proj_frac = traits.Float(argstr='--projfrac %s', desc='projection fraction for vol2surf') fwhm = traits.Float(argstr='--fwhm %f', xor=['num_iters'], desc='smooth by fwhm mm on the target surface') num_iters = traits.Int(argstr='--niters %d', xor=['fwhm'], desc='niters : smooth by niters on the target surface') fwhm_source = traits.Float(argstr='--fwhm-src %f', xor=['num_iters_source'], desc='smooth by fwhm mm on the source surface') num_iters_source = traits.Int(argstr='--niterssrc %d', xor=['fwhm_source'], desc='niters : smooth by niters on the source surface') smooth_cortex_only = traits.Bool(argstr='--smooth-cortex-only', desc='only smooth cortex (ie, exclude medial wall)') class MRISPreprocOutputSpec(TraitedSpec): out_file = File(exists=True, desc='preprocessed output file') class MRISPreproc(FSCommand): """Use FreeSurfer mris_preproc to prepare a group of contrasts for a second level analysis Examples -------- >>> preproc = MRISPreproc() >>> preproc.inputs.target = 'fsaverage' >>> preproc.inputs.hemi = 'lh' >>> preproc.inputs.vol_measure_file = [('cont1.nii', 'register.dat'), \ ('cont1a.nii', 'register.dat')] >>> preproc.inputs.out_file = 'concatenated_file.mgz' >>> preproc.cmdline 'mris_preproc --hemi lh --out concatenated_file.mgz --target fsaverage --iv cont1.nii register.dat --iv cont1a.nii register.dat' """ _cmd = 'mris_preproc' input_spec = MRISPreprocInputSpec output_spec = MRISPreprocOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outfile = self.inputs.out_file outputs['out_file'] = outfile if not isdefined(outfile): outputs['out_file'] = os.path.join(os.getcwd(), 'concat_%s_%s.mgz' % (self.inputs.hemi, self.inputs.target)) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] return None class GLMFitInputSpec(FSTraitedSpec): glm_dir = traits.Str(argstr='--glmdir %s', desc='save outputs to dir', genfile=True) in_file = File(desc='input 4D file', argstr='--y %s', mandatory=True, copyfile=False) _design_xor = ('fsgd', 'design', 'one_sample') fsgd = traits.Tuple(File(exists=True), traits.Enum('doss', 'dods'), argstr='--fsgd %s %s', xor=_design_xor, desc='freesurfer descriptor file') design = File(exists=True, argstr='--X %s', xor=_design_xor, desc='design matrix file') contrast = InputMultiPath(File(exists=True), argstr='--C %s...', desc='contrast file') one_sample = traits.Bool(argstr='--osgm', xor=('one_sample', 'fsgd', 'design', 'contrast'), desc='construct X and C as a one-sample group mean') no_contrast_sok = traits.Bool(argstr='--no-contrasts-ok', desc='do not fail if no contrasts specified') per_voxel_reg = InputMultiPath(File(exists=True), argstr='--pvr %s...', desc='per-voxel regressors') self_reg = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--selfreg %d %d %d', desc='self-regressor from index col row slice') weighted_ls = File(exists=True, argstr='--wls %s', xor=('weight_file', 'weight_inv', 'weight_sqrt'), desc='weighted least squares') fixed_fx_var = File(exists=True, argstr='--yffxvar %s', desc='for fixed effects analysis') fixed_fx_dof = traits.Int(argstr='--ffxdof %d', xor=['fixed_fx_dof_file'], desc='dof for fixed effects analysis') fixed_fx_dof_file = File(argstr='--ffxdofdat %d', xor=['fixed_fx_dof'], desc='text file with dof for fixed effects analysis') weight_file = File(exists=True, xor=['weighted_ls'], desc='weight for each input at each voxel') weight_inv = traits.Bool(argstr='--w-inv', desc='invert weights', xor=['weighted_ls']) weight_sqrt = traits.Bool(argstr='--w-sqrt', desc='sqrt of weights', xor=['weighted_ls']) fwhm = traits.Range(low=0.0, argstr='--fwhm %f', desc='smooth input by fwhm') var_fwhm = traits.Range(low=0.0, argstr='--var-fwhm %f', desc='smooth variance by fwhm') no_mask_smooth = traits.Bool(argstr='--no-mask-smooth', desc='do not mask when smoothing') no_est_fwhm = traits.Bool(argstr='--no-est-fwhm', desc='turn off FWHM output estimation') mask_file = File(exists=True, argstr='--mask %s', desc='binary mask') label_file = File(exists=True, argstr='--label %s', xor=['cortex'], desc='use label as mask, surfaces only') cortex = traits.Bool(argstr='--cortex', xor=['label_file'], desc='use subjects ?h.cortex.label as label') invert_mask = traits.Bool(argstr='--mask-inv', desc='invert mask') prune = traits.Bool(argstr='--prune', desc='remove voxels that do not have a non-zero value at each frame (def)') no_prune = traits.Bool(argstr='--no-prune', xor=['prunethresh'], desc='do not prune') prune_thresh = traits.Float(argstr='--prune_thr %f', xor=['noprune'], desc='prune threshold. Default is FLT_MIN') compute_log_y = traits.Bool(argstr='--logy', desc='compute natural log of y prior to analysis') save_estimate = traits.Bool(argstr='--yhat-save', desc='save signal estimate (yhat)') save_residual = traits.Bool(argstr='--eres-save', desc='save residual error (eres)') save_res_corr_mtx = traits.Bool(argstr='--eres-scm', desc='save residual error spatial correlation matrix (eres.scm). Big!') surf = traits.Bool(argstr="--surf %s %s %s", requires=["subject_id", "hemi"], desc="analysis is on a surface mesh") subject_id = traits.Str(desc="subject id for surface geometry") hemi = traits.Enum("lh", "rh", desc="surface hemisphere") surf_geo = traits.Str("white", usedefault=True, desc="surface geometry name (e.g. white, pial)") simulation = traits.Tuple(traits.Enum('perm', 'mc-full', 'mc-z'), traits.Int(min=1), traits.Float, traits.Str, argstr='--sim %s %d %f %s', desc='nulltype nsim thresh csdbasename') sim_sign = traits.Enum('abs', 'pos', 'neg', argstr='--sim-sign %s', desc='abs, pos, or neg') uniform = traits.Tuple(traits.Float, traits.Float, argstr='--uniform %f %f', desc='use uniform distribution instead of gaussian') pca = traits.Bool(argstr='--pca', desc='perform pca/svd analysis on residual') calc_AR1 = traits.Bool(argstr='--tar1', desc='compute and save temporal AR1 of residual') save_cond = traits.Bool(argstr='--save-cond', desc='flag to save design matrix condition at each voxel') vox_dump = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--voxdump %d %d %d', desc='dump voxel GLM and exit') seed = traits.Int(argstr='--seed %d', desc='used for synthesizing noise') synth = traits.Bool(argstr='--synth', desc='replace input with gaussian') resynth_test = traits.Int(argstr='--resynthtest %d', desc='test GLM by resynthsis') profile = traits.Int(argstr='--profile %d', desc='niters : test speed') force_perm = traits.Bool(argstr='--perm-force', desc='force perumtation test, even when design matrix is not orthog') diag = traits.Int('--diag %d', desc='Gdiag_no : set diagnositc level') diag_cluster = traits.Bool(argstr='--diag-cluster', desc='save sig volume and exit from first sim loop') debug = traits.Bool(argstr='--debug', desc='turn on debugging') check_opts = traits.Bool(argstr='--checkopts', desc="don't run anything, just check options and exit") allow_repeated_subjects = traits.Bool(argstr='--allowsubjrep', desc='allow subject names to repeat in the fsgd file (must appear before --fsgd') allow_ill_cond = traits.Bool(argstr='--illcond', desc='allow ill-conditioned design matrices') sim_done_file = File(argstr='--sim-done %s', desc='create file when simulation finished') class GLMFitOutputSpec(TraitedSpec): glm_dir = Directory(exists=True, desc="output directory") beta_file = File(exists=True, desc="map of regression coefficients") error_file = File(desc="map of residual error") error_var_file = File(desc="map of residual error variance") error_stddev_file = File(desc="map of residual error standard deviation") estimate_file = File(desc="map of the estimated Y values") mask_file = File(desc="map of the mask used in the analysis") fwhm_file = File(desc="text file with estimated smoothness") dof_file = File(desc="text file with effective degrees-of-freedom for the analysis") gamma_file = OutputMultiPath(desc="map of contrast of regression coefficients") gamma_var_file = OutputMultiPath(desc="map of regression contrast variance") sig_file = OutputMultiPath(desc="map of F-test significance (in -log10p)") ftest_file = OutputMultiPath(desc="map of test statistic values") spatial_eigenvectors = File(desc="map of spatial eigenvectors from residual PCA") frame_eigenvectors = File(desc="matrix of frame eigenvectors from residual PCA") singular_values = File(desc="matrix singular values from residual PCA") svd_stats_file = File(desc="text file summarizing the residual PCA") class GLMFit(FSCommand): """Use FreeSurfer's mri_glmfit to specify and estimate a general linear model. Examples -------- >>> glmfit = GLMFit() >>> glmfit.inputs.in_file = 'functional.nii' >>> glmfit.inputs.one_sample = True >>> glmfit.cmdline == 'mri_glmfit --glmdir %s --y functional.nii --osgm'%os.getcwd() True """ _cmd = 'mri_glmfit' input_spec = GLMFitInputSpec output_spec = GLMFitOutputSpec def _format_arg(self, name, spec, value): if name == "surf": _si = self.inputs return spec.argstr % (_si.subject_id, _si.hemi, _si.surf_geo) return super(GLMFit, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() # Get the top-level output directory if not isdefined(self.inputs.glm_dir): glmdir = os.getcwd() else: glmdir = os.path.abspath(self.inputs.glm_dir) outputs["glm_dir"] = glmdir # Assign the output files that always get created outputs["beta_file"] = os.path.join(glmdir, "beta.mgh") outputs["error_var_file"] = os.path.join(glmdir, "rvar.mgh") outputs["error_stddev_file"] = os.path.join(glmdir, "rstd.mgh") outputs["mask_file"] = os.path.join(glmdir, "mask.mgh") outputs["fwhm_file"] = os.path.join(glmdir, "fwhm.dat") outputs["dof_file"] = os.path.join(glmdir, "dof.dat") # Assign the conditional outputs if isdefined(self.inputs.save_residual) and self.inputs.save_residual: outputs["error_file"] = os.path.join(glmdir, "eres.mgh") if isdefined(self.inputs.save_estimate) and self.inputs.save_estimate: outputs["estimate_file"] = os.path.join(glmdir, "yhat.mgh") # Get the contrast directory name(s) if isdefined(self.inputs.contrast): contrasts = [] for c in self.inputs.contrast: if split_filename(c)[2] in [".mat", ".dat", ".mtx", ".con"]: contrasts.append(split_filename(c)[1]) else: contrasts.append(os.path.split(c)[1]) elif isdefined(self.inputs.one_sample) and self.inputs.one_sample: contrasts = ["osgm"] # Add in the contrast images outputs["sig_file"] = [os.path.join(glmdir, c, "sig.mgh") for c in contrasts] outputs["ftest_file"] = [os.path.join(glmdir, c, "F.mgh") for c in contrasts] outputs["gamma_file"] = [os.path.join(glmdir, c, "gamma.mgh") for c in contrasts] outputs["gamma_var_file"] = [os.path.join(glmdir, c, "gammavar.mgh") for c in contrasts] # Add in the PCA results, if relevant if isdefined(self.inputs.pca) and self.inputs.pca: pcadir = os.path.join(glmdir, "pca-eres") outputs["spatial_eigenvectors"] = os.path.join(pcadir, "v.mgh") outputs["frame_eigenvectors"] = os.path.join(pcadir, "u.mtx") outputs["singluar_values"] = os.path.join(pcadir, "sdiag.mat") outputs["svd_stats_file"] = os.path.join(pcadir, "stats.dat") return outputs def _gen_filename(self, name): if name == 'glm_dir': return os.getcwd() return None class OneSampleTTest(GLMFit): def __init__(self, **kwargs): super(OneSampleTTest, self).__init__(**kwargs) self.inputs.one_sample = True class BinarizeInputSpec(FSTraitedSpec): in_file = File(exists=True, argstr='--i %s', mandatory=True, copyfile=False, desc='input volume') min = traits.Float(argstr='--min %f', xor=['wm_ven_csf'], desc='min thresh') max = traits.Float(argstr='--max %f', xor=['wm_ven_csf'], desc='max thresh') rmin = traits.Float(argstr='--rmin %f', desc='compute min based on rmin*globalmean') rmax = traits.Float(argstr='--rmax %f', desc='compute max based on rmax*globalmean') match = traits.List(traits.Int, argstr='--match %d...', desc='match instead of threshold') wm = traits.Bool(argstr='--wm', desc='set match vals to 2 and 41 (aseg for cerebral WM)') ventricles = traits.Bool(argstr='--ventricles', desc='set match vals those for aseg ventricles+choroid (not 4th)') wm_ven_csf = traits.Bool(argstr='--wm+vcsf', xor=['min', 'max'], desc='WM and ventricular CSF, including choroid (not 4th)') binary_file = File(argstr='--o %s', genfile=True, desc='binary output volume') out_type = traits.Enum('nii', 'nii.gz', 'mgz', argstr='', desc='output file type') count_file = traits.Either(traits.Bool, File, argstr='--count %s', desc='save number of hits in ascii file (hits, ntotvox, pct)') bin_val = traits.Int(argstr='--binval %d', desc='set vox within thresh to val (default is 1)') bin_val_not = traits.Int(argstr='--binvalnot %d', desc='set vox outside range to val (default is 0)') invert = traits.Bool(argstr='--inv', desc='set binval=0, binvalnot=1') frame_no = traits.Int(argstr='--frame %s', desc='use 0-based frame of input (default is 0)') merge_file = File(exists=True, argstr='--merge %s', desc='merge with mergevol') mask_file = File(exists=True, argstr='--mask maskvol', desc='must be within mask') mask_thresh = traits.Float(argstr='--mask-thresh %f', desc='set thresh for mask') abs = traits.Bool(argstr='--abs', desc='take abs of invol first (ie, make unsigned)') bin_col_num = traits.Bool(argstr='--bincol', desc='set binarized voxel value to its column number') zero_edges = traits.Bool(argstr='--zero-edges', desc='zero the edge voxels') zero_slice_edge = traits.Bool(argstr='--zero-slice-edges', desc='zero the edge slice voxels') dilate = traits.Int(argstr='--dilate %d', desc='niters: dilate binarization in 3D') erode = traits.Int(argstr='--erode %d', desc='nerode: erode binarization in 3D (after any dilation)') erode2d = traits.Int(argstr='--erode2d %d', desc='nerode2d: erode binarization in 2D (after any 3D erosion)') class BinarizeOutputSpec(TraitedSpec): binary_file = File(exists=True, desc='binarized output volume') count_file = File(desc='ascii file containing number of hits') class Binarize(FSCommand): """Use FreeSurfer mri_binarize to threshold an input volume Examples -------- >>> binvol = Binarize(in_file='structural.nii', min=10, binary_file='foo_out.nii') >>> binvol.cmdline 'mri_binarize --o foo_out.nii --i structural.nii --min 10.000000' """ _cmd = 'mri_binarize' input_spec = BinarizeInputSpec output_spec = BinarizeOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outfile = self.inputs.binary_file if not isdefined(outfile): if isdefined(self.inputs.out_type): outfile = fname_presuffix(self.inputs.in_file, newpath=os.getcwd(), suffix='.'.join(('_thresh', self.inputs.out_type)), use_ext=False) else: outfile = fname_presuffix(self.inputs.in_file, newpath=os.getcwd(), suffix='_thresh') outputs['binary_file'] = os.path.abspath(outfile) value = self.inputs.count_file if isdefined(value): if isinstance(value, bool): if value: outputs['count_file'] = fname_presuffix(self.inputs.in_file, suffix='_count.txt', newpath=os.getcwd(), use_ext=False) else: outputs['count_file'] = value return outputs def _format_arg(self, name, spec, value): if name == 'count_file': if isinstance(value, bool): fname = self._list_outputs()[name] else: fname = value return spec.argstr % fname if name == 'out_type': return '' return super(Binarize, self)._format_arg(name, spec, value) def _gen_filename(self, name): if name == 'binary_file': return self._list_outputs()[name] return None class ConcatenateInputSpec(FSTraitedSpec): in_files = InputMultiPath(File(exists=True), desc='Individual volumes to be concatenated', argstr='--i %s...', mandatory=True) concatenated_file = File(desc='Output volume', argstr='--o %s', genfile=True) sign = traits.Enum('abs', 'pos', 'neg', argstr='--%s', desc='Take only pos or neg voxles from input, or take abs') stats = traits.Enum('sum', 'var', 'std', 'max', 'min', 'mean', argstr='--%s', desc='Compute the sum, var, std, max, min or mean of the input volumes') paired_stats = traits.Enum('sum', 'avg', 'diff', 'diff-norm', 'diff-norm1', 'diff-norm2', argstr='--paired-%s', desc='Compute paired sum, avg, or diff') gmean = traits.Int(argstr='--gmean %d', desc='create matrix to average Ng groups, Nper=Ntot/Ng') mean_div_n = traits.Bool(argstr='--mean-div-n', desc='compute mean/nframes (good for var)') multiply_by = traits.Float(argstr='--mul %f', desc='Multiply input volume by some amount') add_val = traits.Float(argstr='--add %f', desc='Add some amount to the input volume') multiply_matrix_file = File(exists=True, argstr='--mtx %s', desc='Multiply input by an ascii matrix in file') combine = traits.Bool(argstr='--combine', desc='Combine non-zero values into single frame volume') keep_dtype = traits.Bool(argstr='--keep-datatype', desc='Keep voxelwise precision type (default is float') max_bonfcor = traits.Bool(argstr='--max-bonfcor', desc='Compute max and bonferroni correct (assumes -log10(ps))') max_index = traits.Bool(argstr='--max-index', desc='Compute the index of max voxel in concatenated volumes') mask_file = File(exists=True, argstr='--mask %s', desc='Mask input with a volume') vote = traits.Bool(argstr='--vote', desc='Most frequent value at each voxel and fraction of occurances') sort = traits.Bool(argstr='--sort', desc='Sort each voxel by ascending frame value') class ConcatenateOutputSpec(TraitedSpec): concatenated_file = File(exists=True, desc='Path/name of the output volume') class Concatenate(FSCommand): """Use Freesurfer mri_concat to combine several input volumes into one output volume. Can concatenate by frames, or compute a variety of statistics on the input volumes. Examples -------- Combine two input volumes into one volume with two frames >>> concat = Concatenate() >>> concat.inputs.in_files = ['cont1.nii', 'cont2.nii'] >>> concat.inputs.concatenated_file = 'bar.nii' >>> concat.cmdline 'mri_concat --o bar.nii --i cont1.nii --i cont2.nii' """ _cmd = 'mri_concat' input_spec = ConcatenateInputSpec output_spec = ConcatenateOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.concatenated_file): outputs['concatenated_file'] = os.path.join(os.getcwd(), 'concat_output.nii.gz') else: outputs['concatenated_file'] = self.inputs.concatenated_file return outputs def _gen_filename(self, name): if name == 'concatenated_file': return self._list_outputs()[name] return None class SegStatsInputSpec(FSTraitedSpec): _xor_inputs = ('segmentation_file', 'annot', 'surf_label') segmentation_file = File(exists=True, argstr='--seg %s', xor=_xor_inputs, mandatory=True, desc='segmentation volume path') annot = traits.Tuple(traits.Str, traits.Enum('lh', 'rh'), traits.Str, argstr='--annot %s %s %s', xor=_xor_inputs, mandatory=True, desc='subject hemi parc : use surface parcellation') surf_label = traits.Tuple(traits.Str, traits.Enum('lh', 'rh'), traits.Str, argstr='--slabel %s %s %s', xor=_xor_inputs, mandatory=True, desc='subject hemi label : use surface label') summary_file = File(argstr='--sum %s', genfile=True, desc='Segmentation stats summary table file') partial_volume_file = File(exists=True, argstr='--pv %f', desc='Compensate for partial voluming') in_file = File(exists=True, argstr='--i %s', desc='Use the segmentation to report stats on this volume') frame = traits.Int(argstr='--frame %d', desc='Report stats on nth frame of input volume') multiply = traits.Float(argstr='--mul %f', desc='multiply input by val') calc_snr = traits.Bool(argstr='--snr', desc='save mean/std as extra column in output table') calc_power = traits.Enum('sqr', 'sqrt', argstr='--%s', desc='Compute either the sqr or the sqrt of the input') _ctab_inputs = ('color_table_file', 'default_color_table', 'gca_color_table') color_table_file = File(exists=True, argstr='--ctab %s', xor=_ctab_inputs, desc='color table file with seg id names') default_color_table = traits.Bool(argstr='--ctab-default', xor=_ctab_inputs, desc='use $FREESURFER_HOME/FreeSurferColorLUT.txt') gca_color_table = File(exists=True, argstr='--ctab-gca %s', xor=_ctab_inputs, desc='get color table from GCA (CMA)') segment_id = traits.List(argstr='--id %s...', desc='Manually specify segmentation ids') exclude_id = traits.Int(argstr='--excludeid %d', desc='Exclude seg id from report') exclude_ctx_gm_wm = traits.Bool(argstr='--excl-ctxgmwm', desc='exclude cortical gray and white matter') wm_vol_from_surf = traits.Bool(argstr='--surf-wm-vol', desc='Compute wm volume from surf') cortex_vol_from_surf = traits.Bool(argstr='--surf-ctx-vol', desc='Compute cortex volume from surf') non_empty_only = traits.Bool(argstr='--nonempty', desc='Only report nonempty segmentations') mask_file = File(exists=True, argstr='--mask %s', desc='Mask volume (same size as seg') mask_thresh = traits.Float(argstr='--maskthresh %f', desc='binarize mask with this threshold <0.5>') mask_sign = traits.Enum('abs', 'pos', 'neg', '--masksign %s', desc='Sign for mask threshold: pos, neg, or abs') mask_frame = traits.Int('--maskframe %d', requires=['mask_file'], desc='Mask with this (0 based) frame of the mask volume') mask_invert = traits.Bool(argstr='--maskinvert', desc='Invert binarized mask volume') mask_erode = traits.Int(argstr='--maskerode %d', desc='Erode mask by some amount') brain_vol = traits.Enum('brain-vol-from-seg', 'brainmask', '--%s', desc='Compute brain volume either with ``brainmask`` or ``brain-vol-from-seg``') etiv = traits.Bool(argstr='--etiv', desc='Compute ICV from talairach transform') etiv_only = traits.Enum('etiv', 'old-etiv', '--%s-only', desc='Compute etiv and exit. Use ``etiv`` or ``old-etiv``') avgwf_txt_file = traits.Either(traits.Bool, File, argstr='--avgwf %s', desc='Save average waveform into file (bool or filename)') avgwf_file = traits.Either(traits.Bool, File, argstr='--avgwfvol %s', desc='Save as binary volume (bool or filename)') sf_avg_file = traits.Either(traits.Bool, File, argstr='--sfavg %s', desc='Save mean across space and time') vox = traits.List(traits.Int, argstr='--vox %s', desc='Replace seg with all 0s except at C R S (three int inputs)') class SegStatsOutputSpec(TraitedSpec): summary_file = File(exists=True, desc='Segmentation summary statistics table') avgwf_txt_file = File(desc='Text file with functional statistics averaged over segs') avgwf_file = File(desc='Volume with functional statistics averaged over segs') sf_avg_file = File(desc='Text file with func statistics averaged over segs and framss') class SegStats(FSCommand): """Use FreeSurfer mri_segstats for ROI analysis Examples -------- >>> import nipype.interfaces.freesurfer as fs >>> ss = fs.SegStats() >>> ss.inputs.annot = ('PWS04', 'lh', 'aparc') >>> ss.inputs.in_file = 'functional.nii' >>> ss.inputs.subjects_dir = '.' >>> ss.inputs.avgwf_txt_file = './avgwf.txt' >>> ss.inputs.summary_file = './summary.stats' >>> ss.cmdline 'mri_segstats --annot PWS04 lh aparc --avgwf ./avgwf.txt --i functional.nii --sum ./summary.stats' """ _cmd = 'mri_segstats' input_spec = SegStatsInputSpec output_spec = SegStatsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.summary_file): outputs['summary_file'] = os.path.abspath(self.inputs.summary_file) else: outputs['summary_file'] = os.path.join(os.getcwd(), 'summary.stats') suffices = dict(avgwf_txt_file='_avgwf.txt', avgwf_file='_avgwf.nii.gz', sf_avg_file='sfavg.txt') if isdefined(self.inputs.segmentation_file): _, src = os.path.split(self.inputs.segmentation_file) if isdefined(self.inputs.annot): src = '_'.join(self.inputs.annot) if isdefined(self.inputs.surf_label): src = '_'.join(self.inputs.surf_label) for name, suffix in suffices.items(): value = getattr(self.inputs, name) if isdefined(value): if isinstance(value, bool): outputs[name] = fname_presuffix(src, suffix=suffix, newpath=os.getcwd(), use_ext=False) else: outputs[name] = os.path.abspath(value) return outputs def _format_arg(self, name, spec, value): if name in ['avgwf_txt_file', 'avgwf_file', 'sf_avg_file']: if isinstance(value, bool): fname = self._list_outputs()[name] else: fname = value return spec.argstr % fname return super(SegStats, self)._format_arg(name, spec, value) def _gen_filename(self, name): if name == 'summary_file': return self._list_outputs()[name] return None class Label2VolInputSpec(FSTraitedSpec): label_file = InputMultiPath(File(exists=True), argstr='--label %s...', xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), copyfile=False, mandatory=True, desc='list of label files') annot_file = File(exists=True, argstr='--annot %s', xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), requires=('subject_id', 'hemi'), mandatory=True, copyfile=False, desc='surface annotation file') seg_file = File(exists=True, argstr='--seg %s', xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), mandatory=True, copyfile=False, desc='segmentation file') aparc_aseg = traits.Bool(argstr='--aparc+aseg', xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), mandatory=True, desc='use aparc+aseg.mgz in subjectdir as seg') template_file = File(exists=True, argstr='--temp %s', mandatory=True, desc='output template volume') reg_file = File(exists=True, argstr='--reg %s', xor=('reg_file', 'reg_header', 'identity'), desc='tkregister style matrix VolXYZ = R*LabelXYZ') reg_header = File(exists=True, argstr='--regheader %s', xor=('reg_file', 'reg_header', 'identity'), desc='label template volume') identity = traits.Bool(argstr='--identity', xor=('reg_file', 'reg_header', 'identity'), desc='set R=I') invert_mtx = traits.Bool(argstr='--invertmtx', desc='Invert the registration matrix') fill_thresh = traits.Range(0., 1., argstr='--fillthresh %.f', desc='thresh : between 0 and 1') label_voxel_volume = traits.Float(argstr='--labvoxvol %f', desc='volume of each label point (def 1mm3)') proj = traits.Tuple(traits.Enum('abs', 'frac'), traits.Float, traits.Float, traits.Float, argstr='--proj %s %f %f %f', requires=('subject_id', 'hemi'), desc='project along surface normal') subject_id = traits.Str(argstr='--subject %s', desc='subject id') hemi = traits.Enum('lh', 'rh', argstr='--hemi %s', desc='hemisphere to use lh or rh') surface = traits.Str(argstr='--surf %s', desc='use surface instead of white') vol_label_file = File(argstr='--o %s', genfile=True, desc='output volume') label_hit_file = File(argstr='--hits %s', desc='file with each frame is nhits for a label') map_label_stat = File(argstr='--label-stat %s', desc='map the label stats field into the vol') native_vox2ras = traits.Bool(argstr='--native-vox2ras', desc='use native vox2ras xform instead of tkregister-style') class Label2VolOutputSpec(TraitedSpec): vol_label_file = File(exists=True, desc='output volume') class Label2Vol(FSCommand): """Make a binary volume from a Freesurfer label Examples -------- >>> binvol = Label2Vol(label_file='cortex.label', template_file='structural.nii', reg_file='register.dat', fill_thresh=0.5, vol_label_file='foo_out.nii') >>> binvol.cmdline 'mri_label2vol --fillthresh 0 --label cortex.label --reg register.dat --temp structural.nii --o foo_out.nii' """ _cmd = 'mri_label2vol' input_spec = Label2VolInputSpec output_spec = Label2VolOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outfile = self.inputs.vol_label_file if not isdefined(outfile): for key in ['label_file', 'annot_file', 'seg_file']: if isdefined(getattr(self.inputs,key)): path = getattr(self.inputs, key) if isinstance(path,list): path = path[0] _, src = os.path.split(path) if isdefined(self.inputs.aparc_aseg): src = 'aparc+aseg.mgz' outfile = fname_presuffix(src, suffix='_vol.nii.gz', newpath=os.getcwd(), use_ext=False) outputs['vol_label_file'] = outfile return outputs def _gen_filename(self, name): if name == 'vol_label_file': return self._list_outputs()[name] return None class MS_LDAInputSpec(FSTraitedSpec): lda_labels = traits.List(traits.Int(), argstr='-lda %s', mandatory=True, minlen=2, maxlen=2, sep=' ', desc='pair of class labels to optimize') weight_file = traits.File(argstr='-weight %s', mandatory=True, desc='filename for the LDA weights (input or output)') vol_synth_file = traits.File(exists=False, argstr='-synth %s', mandatory=True, desc=('filename for the synthesized output ' 'volume')) label_file = traits.File(exists=True, argstr='-label %s', desc='filename of the label volume') mask_file = traits.File(exists=True, argstr='-mask %s', desc='filename of the brain mask volume') shift = traits.Int(argstr='-shift %d', desc='shift all values equal to the given value to zero') conform = traits.Bool(argstr='-conform', desc=('Conform the input volumes (brain mask ' 'typically already conformed)')) use_weights = traits.Bool(argstr='-W', desc=('Use the weights from a previously ' 'generated weight file')) images = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, copyfile=False, desc='list of input FLASH images', position=-1) class MS_LDAOutputSpec(TraitedSpec): weight_file = File(exists=True, desc='') vol_synth_file = File(exists=True, desc='') class MS_LDA(FSCommand): """Perform LDA reduction on the intensity space of an arbitrary # of FLASH images Examples -------- >>> grey_label = 2 >>> white_label = 3 >>> zero_value = 1 >>> optimalWeights = MS_LDA(lda_labels=[grey_label, white_label], \ label_file='label.mgz', weight_file='weights.txt', \ shift=zero_value, vol_synth_file='synth_out.mgz', \ conform=True, use_weights=True, \ images=['FLASH1.mgz', 'FLASH2.mgz', 'FLASH3.mgz']) >>> optimalWeights.cmdline 'mri_ms_LDA -conform -label label.mgz -lda 2 3 -shift 1 -W -synth synth_out.mgz -weight weights.txt FLASH1.mgz FLASH2.mgz FLASH3.mgz' """ _cmd = 'mri_ms_LDA' input_spec = MS_LDAInputSpec output_spec = MS_LDAOutputSpec def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.output_synth): outputs['vol_synth_file'] = os.path.abspath(self.inputs.output_synth) else: outputs['vol_synth_file'] = os.path.abspath(self.inputs.vol_synth_file) if not isdefined(self.inputs.use_weights) or self.inputs.use_weights is False: outputs['weight_file'] = os.path.abspath(self.inputs.weight_file) return outputs def _verify_weights_file_exists(self): if not os.path.exists(os.path.abspath(self.inputs.weight_file)): raise traits.TraitError("MS_LDA: use_weights must accompany an existing weights file") def _format_arg(self, name, spec, value): if name is 'use_weights': if self.inputs.use_weights is True: self._verify_weights_file_exists() else: return '' # TODO: Fix bug when boolean values are set explicitly to false return super(MS_LDA, self)._format_arg(name, spec, value) def _gen_filename(self, name): pass nipype-0.11.0/nipype/interfaces/freesurfer/preprocess.py000066400000000000000000001704131257611314500234460ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Provides interfaces to various commands provided by FreeSurfer Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ __docformat__ = 'restructuredtext' import os import os.path as op from glob import glob #import itertools import numpy as np from nibabel import load from nipype.utils.filemanip import fname_presuffix from nipype.interfaces.io import FreeSurferSource from nipype.interfaces.freesurfer.base import FSCommand, FSTraitedSpec from nipype.interfaces.base import (TraitedSpec, File, traits, Directory, InputMultiPath, OutputMultiPath, CommandLine, CommandLineInputSpec, isdefined) from ... import logging iflogger = logging.getLogger('interface') class ParseDICOMDirInputSpec(FSTraitedSpec): dicom_dir = Directory(exists=True, argstr='--d %s', mandatory=True, desc='path to siemens dicom directory') dicom_info_file = File('dicominfo.txt', argstr='--o %s', usedefault=True, desc='file to which results are written') sortbyrun = traits.Bool(argstr='--sortbyrun', desc='assign run numbers') summarize = traits.Bool(argstr='--summarize', desc='only print out info for run leaders') class ParseDICOMDirOutputSpec(TraitedSpec): dicom_info_file = File(exists=True, desc='text file containing dicom information') class ParseDICOMDir(FSCommand): """Uses mri_parse_sdcmdir to get information from dicom directories Examples -------- >>> from nipype.interfaces.freesurfer import ParseDICOMDir >>> dcminfo = ParseDICOMDir() >>> dcminfo.inputs.dicom_dir = '.' >>> dcminfo.inputs.sortbyrun = True >>> dcminfo.inputs.summarize = True >>> dcminfo.cmdline 'mri_parse_sdcmdir --d . --o dicominfo.txt --sortbyrun --summarize' """ _cmd = 'mri_parse_sdcmdir' input_spec = ParseDICOMDirInputSpec output_spec = ParseDICOMDirOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.dicom_info_file): outputs['dicom_info_file'] = os.path.join(os.getcwd(), self.inputs.dicom_info_file) return outputs class UnpackSDICOMDirInputSpec(FSTraitedSpec): source_dir = Directory(exists=True, argstr='-src %s', mandatory=True, desc='directory with the DICOM files') output_dir = Directory(argstr='-targ %s', desc='top directory into which the files will be unpacked') run_info = traits.Tuple(traits.Int, traits.Str, traits.Str, traits.Str, mandatory=True, argstr='-run %d %s %s %s', xor=('run_info', 'config', 'seq_config'), desc='runno subdir format name : spec unpacking rules on cmdline') config = File(exists=True, argstr='-cfg %s', mandatory=True, xor=('run_info', 'config', 'seq_config'), desc='specify unpacking rules in file') seq_config = File(exists=True, argstr='-seqcfg %s', mandatory=True, xor=('run_info', 'config', 'seq_config'), desc='specify unpacking rules based on sequence') dir_structure = traits.Enum('fsfast', 'generic', argstr='-%s', desc='unpack to specified directory structures') no_info_dump = traits.Bool(argstr='-noinfodump', desc='do not create infodump file') scan_only = File(exists=True, argstr='-scanonly %s', desc='only scan the directory and put result in file') log_file = File(exists=True, argstr='-log %s', desc='explicilty set log file') spm_zeropad = traits.Int(argstr='-nspmzeropad %d', desc='set frame number zero padding width for SPM') no_unpack_err = traits.Bool(argstr='-no-unpackerr', desc='do not try to unpack runs with errors') class UnpackSDICOMDir(FSCommand): """Use unpacksdcmdir to convert dicom files Call unpacksdcmdir -help from the command line to see more information on using this command. Examples -------- >>> from nipype.interfaces.freesurfer import UnpackSDICOMDir >>> unpack = UnpackSDICOMDir() >>> unpack.inputs.source_dir = '.' >>> unpack.inputs.output_dir = '.' >>> unpack.inputs.run_info = (5, 'mprage', 'nii', 'struct') >>> unpack.inputs.dir_structure = 'generic' >>> unpack.cmdline 'unpacksdcmdir -generic -targ . -run 5 mprage nii struct -src .' """ _cmd = 'unpacksdcmdir' input_spec = UnpackSDICOMDirInputSpec class MRIConvertInputSpec(FSTraitedSpec): read_only = traits.Bool(argstr='--read_only', desc='read the input volume') no_write = traits.Bool(argstr='--no_write', desc='do not write output') in_info = traits.Bool(argstr='--in_info', desc='display input info') out_info = traits.Bool(argstr='--out_info', desc='display output info') in_stats = traits.Bool(argstr='--in_stats', desc='display input stats') out_stats = traits.Bool(argstr='--out_stats', desc='display output stats') in_matrix = traits.Bool(argstr='--in_matrix', desc='display input matrix') out_matrix = traits.Bool(argstr='--out_matrix', desc='display output matrix') in_i_size = traits.Int(argstr='--in_i_size %d', desc='input i size') in_j_size = traits.Int(argstr='--in_j_size %d', desc='input j size') in_k_size = traits.Int(argstr='--in_k_size %d', desc='input k size') force_ras = traits.Bool(argstr='--force_ras_good', desc='use default when orientation info absent') in_i_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--in_i_direction %f %f %f', desc=' ') in_j_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--in_j_direction %f %f %f', desc=' ') in_k_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--in_k_direction %f %f %f', desc=' ') _orientations = ['LAI', 'LIA', 'ALI', 'AIL', 'ILA', 'IAL', 'LAS', 'LSA', 'ALS', 'ASL', 'SLA', 'SAL', 'LPI', 'LIP', 'PLI', 'PIL', 'ILP', 'IPL', 'LPS', 'LSP', 'PLS', 'PSL', 'SLP', 'SPL', 'RAI', 'RIA', 'ARI', 'AIR', 'IRA', 'IAR', 'RAS', 'RSA', 'ARS', 'ASR', 'SRA', 'SAR', 'RPI', 'RIP', 'PRI', 'PIR', 'IRP', 'IPR', 'RPS', 'RSP', 'PRS', 'PSR', 'SRP', 'SPR'] #_orientations = [comb for comb in itertools.chain(*[[''.join(c) for c in itertools.permutations(s)] for s in [a+b+c for a in 'LR' for b in 'AP' for c in 'IS']])] in_orientation = traits.Enum(_orientations, argstr='--in_orientation %s', desc='specify the input orientation') in_center = traits.List(traits.Float, maxlen=3, argstr='--in_center %s', desc=' ') sphinx = traits.Bool(argstr='--sphinx', desc='change orientation info to sphinx') out_i_count = traits.Int(argstr='--out_i_count %d', desc='some count ?? in i direction') out_j_count = traits.Int(argstr='--out_j_count %d', desc='some count ?? in j direction') out_k_count = traits.Int(argstr='--out_k_count %d', desc='some count ?? in k direction') vox_size = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='-voxsize %f %f %f', desc=' specify the size (mm) - useful for upsampling or downsampling') out_i_size = traits.Int(argstr='--out_i_size %d', desc='output i size') out_j_size = traits.Int(argstr='--out_j_size %d', desc='output j size') out_k_size = traits.Int(argstr='--out_k_size %d', desc='output k size') out_i_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--out_i_direction %f %f %f', desc=' ') out_j_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--out_j_direction %f %f %f', desc=' ') out_k_dir = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--out_k_direction %f %f %f', desc=' ') out_orientation = traits.Enum(_orientations, argstr='--out_orientation %s', desc='specify the output orientation') out_center = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--out_center %f %f %f', desc=' ') out_datatype = traits.Enum('uchar', 'short', 'int', 'float', argstr='--out_data_type %s', desc='output data type ') resample_type = traits.Enum('interpolate', 'weighted', 'nearest', 'sinc', 'cubic', argstr='--resample_type %s', desc=' (default is interpolate)') no_scale = traits.Bool(argstr='--no_scale 1', desc='dont rescale values for COR') no_change = traits.Bool(argstr='--nochange', desc="don't change type of input to that of template") tr = traits.Int(argstr='-tr %d', desc='TR in msec') te = traits.Int(argstr='-te %d', desc='TE in msec') ti = traits.Int(argstr='-ti %d', desc='TI in msec (note upper case flag)') autoalign_matrix = File(exists=True, argstr='--autoalign %s', desc='text file with autoalign matrix') unwarp_gradient = traits.Bool(argstr='--unwarp_gradient_nonlinearity', desc='unwarp gradient nonlinearity') apply_transform = File(exists=True, argstr='--apply_transform %s', desc='apply xfm file') apply_inv_transform = File(exists=True, argstr='--apply_inverse_transform %s', desc='apply inverse transformation xfm file') devolve_transform = traits.Str(argstr='--devolvexfm %s', desc='subject id') crop_center = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--crop %d %d %d', desc=' crop to 256 around center (x, y, z)') crop_size = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--cropsize %d %d %d', desc=' crop to size ') cut_ends = traits.Int(argstr='--cutends %d', desc='remove ncut slices from the ends') slice_crop = traits.Tuple(traits.Int, traits.Int, argstr='--slice-crop %d %d', desc='s_start s_end : keep slices s_start to s_end') slice_reverse = traits.Bool(argstr='--slice-reverse', desc='reverse order of slices, update vox2ras') slice_bias = traits.Float(argstr='--slice-bias %f', desc='apply half-cosine bias field') fwhm = traits.Float(argstr='--fwhm %f', desc='smooth input volume by fwhm mm') _filetypes = ['cor', 'mgh', 'mgz', 'minc', 'analyze', 'analyze4d', 'spm', 'afni', 'brik', 'bshort', 'bfloat', 'sdt', 'outline', 'otl', 'gdf', 'nifti1', 'nii', 'niigz'] _infiletypes = ['ge', 'gelx', 'lx', 'ximg', 'siemens', 'dicom', 'siemens_dicom'] in_type = traits.Enum(_filetypes + _infiletypes, argstr='--in_type %s', desc='input file type') out_type = traits.Enum(_filetypes, argstr='--out_type %s', desc='output file type') ascii = traits.Bool(argstr='--ascii', desc='save output as ascii col>row>slice>frame') reorder = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--reorder %d %d %d', desc='olddim1 olddim2 olddim3') invert_contrast = traits.Float(argstr='--invert_contrast %f', desc='threshold for inversting contrast') in_file = File(exists=True, mandatory=True, position=-2, argstr='--input_volume %s', desc='File to read/convert') out_file = File(argstr='--output_volume %s', position=-1, genfile=True, desc='output filename or True to generate one') conform = traits.Bool(argstr='--conform', desc='conform to 256^3') conform_min = traits.Bool(argstr='--conform_min', desc='conform to smallest size') conform_size = traits.Float(argstr='--conform_size %s', desc='conform to size_in_mm') parse_only = traits.Bool(argstr='--parse_only', desc='parse input only') subject_name = traits.Str(argstr='--subject_name %s', desc='subject name ???') reslice_like = File(exists=True, argstr='--reslice_like %s', desc='reslice output to match file') template_type = traits.Enum(_filetypes + _infiletypes, argstr='--template_type %s', desc='template file type') split = traits.Bool(argstr='--split', desc='split output frames into separate output files.') frame = traits.Int(argstr='--frame %d', desc='keep only 0-based frame number') midframe = traits.Bool(argstr='--mid-frame', desc='keep only the middle frame') skip_n = traits.Int(argstr='--nskip %d', desc='skip the first n frames') drop_n = traits.Int(argstr='--ndrop %d', desc='drop the last n frames') frame_subsample = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--fsubsample %d %d %d', desc='start delta end : frame subsampling (end = -1 for end)') in_scale = traits.Float(argstr='--scale %f', desc='input intensity scale factor') out_scale = traits.Float(argstr='--out-scale %d', desc='output intensity scale factor') in_like = File(exists=True, argstr='--in_like %s', desc='input looks like') fill_parcellation = traits.Bool(argstr='--fill_parcellation', desc='fill parcellation') smooth_parcellation = traits.Bool(argstr='--smooth_parcellation', desc='smooth parcellation') zero_outlines = traits.Bool(argstr='--zero_outlines', desc='zero outlines') color_file = File(exists=True, argstr='--color_file %s', desc='color file') no_translate = traits.Bool(argstr='--no_translate', desc='???') status_file = File(argstr='--status %s', desc='status file for DICOM conversion') sdcm_list = File(exists=True, argstr='--sdcmlist %s', desc='list of DICOM files for conversion') template_info = traits.Bool('--template_info', desc='dump info about template') crop_gdf = traits.Bool(argstr='--crop_gdf', desc='apply GDF cropping') zero_ge_z_offset = traits.Bool(argstr='--zero_ge_z_offset', desc='zero ge z offset ???') class MRIConvertOutputSpec(TraitedSpec): out_file = OutputMultiPath(File(exists=True), desc='converted output file') class MRIConvert(FSCommand): """use fs mri_convert to manipulate files .. note:: Adds niigz as an output type option Examples -------- >>> mc = MRIConvert() >>> mc.inputs.in_file = 'structural.nii' >>> mc.inputs.out_file = 'outfile.mgz' >>> mc.inputs.out_type = 'mgz' >>> mc.cmdline 'mri_convert --out_type mgz --input_volume structural.nii --output_volume outfile.mgz' """ _cmd = 'mri_convert' input_spec = MRIConvertInputSpec output_spec = MRIConvertOutputSpec filemap = dict(cor='cor', mgh='mgh', mgz='mgz', minc='mnc', afni='brik', brik='brik', bshort='bshort', spm='img', analyze='img', analyze4d='img', bfloat='bfloat', nifti1='img', nii='nii', niigz='nii.gz') def _format_arg(self, name, spec, value): if name in ['in_type', 'out_type', 'template_type']: if value == 'niigz': return spec.argstr % 'nii' return super(MRIConvert, self)._format_arg(name, spec, value) def _get_outfilename(self): outfile = self.inputs.out_file if not isdefined(outfile): if isdefined(self.inputs.out_type): suffix = '_out.' + self.filemap[self.inputs.out_type] else: suffix = '_out.nii.gz' outfile = fname_presuffix(self.inputs.in_file, newpath=os.getcwd(), suffix=suffix, use_ext=False) return os.path.abspath(outfile) def _list_outputs(self): outputs = self.output_spec().get() outfile = self._get_outfilename() if isdefined(self.inputs.split) and self.inputs.split: size = load(self.inputs.in_file).get_shape() if len(size) == 3: tp = 1 else: tp = size[-1] if outfile.endswith('.mgz'): stem = outfile.split('.mgz')[0] ext = '.mgz' elif outfile.endswith('.nii.gz'): stem = outfile.split('.nii.gz')[0] ext = '.nii.gz' else: stem = '.'.join(outfile.split('.')[:-1]) ext = '.' + outfile.split('.')[-1] outfile = [] for idx in range(0, tp): outfile.append(stem + '%04d' % idx + ext) if isdefined(self.inputs.out_type): if self.inputs.out_type in ['spm', 'analyze']: # generate all outputs size = load(self.inputs.in_file).get_shape() if len(size) == 3: tp = 1 else: tp = size[-1] # have to take care of all the frame manipulations raise Exception('Not taking frame manipulations into account- please warn the developers') outfiles = [] outfile = self._get_outfilename() for i in range(tp): outfiles.append(fname_presuffix(outfile, suffix='%03d' % (i + 1))) outfile = outfiles outputs['out_file'] = outfile return outputs def _gen_filename(self, name): if name == 'out_file': return self._get_outfilename() return None class DICOMConvertInputSpec(FSTraitedSpec): dicom_dir = Directory(exists=True, mandatory=True, desc='dicom directory from which to convert dicom files') base_output_dir = Directory(mandatory=True, desc='directory in which subject directories are created') subject_dir_template = traits.Str('S.%04d', usedefault=True, desc='template for subject directory name') subject_id = traits.Any(desc='subject identifier to insert into template') file_mapping = traits.List(traits.Tuple(traits.Str, traits.Str), desc='defines the output fields of interface') out_type = traits.Enum('niigz', MRIConvertInputSpec._filetypes, usedefault=True, desc='defines the type of output file produced') dicom_info = File(exists=True, desc='File containing summary information from mri_parse_sdcmdir') seq_list = traits.List(traits.Str, requires=['dicom_info'], desc='list of pulse sequence names to be converted.') ignore_single_slice = traits.Bool(requires=['dicom_info'], desc='ignore volumes containing a single slice') class DICOMConvert(FSCommand): """use fs mri_convert to convert dicom files Examples -------- >>> from nipype.interfaces.freesurfer import DICOMConvert >>> cvt = DICOMConvert() >>> cvt.inputs.dicom_dir = 'dicomdir' >>> cvt.inputs.file_mapping = [('nifti', '*.nii'), ('info', 'dicom*.txt'), ('dti', '*dti.bv*')] """ _cmd = 'mri_convert' input_spec = DICOMConvertInputSpec def _get_dicomfiles(self): """validate fsl bet options if set to None ignore """ return glob(os.path.abspath(os.path.join(self.inputs.dicom_dir, '*-1.dcm'))) def _get_outdir(self): """returns output directory""" subjid = self.inputs.subject_id if not isdefined(subjid): path, fname = os.path.split(self._get_dicomfiles()[0]) subjid = int(fname.split('-')[0]) if isdefined(self.inputs.subject_dir_template): subjid = self.inputs.subject_dir_template % subjid basedir = self.inputs.base_output_dir if not isdefined(basedir): basedir = os.path.abspath('.') outdir = os.path.abspath(os.path.join(basedir, subjid)) return outdir def _get_runs(self): """Returns list of dicom series that should be converted. Requires a dicom info summary file generated by ``DicomDirInfo`` """ seq = np.genfromtxt(self.inputs.dicom_info, dtype=object) runs = [] for s in seq: if self.inputs.seq_list: if self.inputs.ignore_single_slice: if (int(s[8]) > 1) and any([s[12].startswith(sn) for sn in self.inputs.seq_list]): runs.append(int(s[2])) else: if any([s[12].startswith(sn) for sn in self.inputs.seq_list]): runs.append(int(s[2])) else: runs.append(int(s[2])) return runs def _get_filelist(self, outdir): """Returns list of files to be converted""" filemap = {} for f in self._get_dicomfiles(): head, fname = os.path.split(f) fname, ext = os.path.splitext(fname) fileparts = fname.split('-') runno = int(fileparts[1]) out_type = MRIConvert.filemap[self.inputs.out_type] outfile = os.path.join(outdir, '.'.join(('%s-%02d' % (fileparts[0], runno), out_type))) filemap[runno] = (f, outfile) if self.inputs.dicom_info: files = [filemap[r] for r in self._get_runs()] else: files = [filemap[r] for r in filemap.keys()] return files @property def cmdline(self): """ `command` plus any arguments (args) validates arguments and generates command line""" self._check_mandatory_inputs() outdir = self._get_outdir() cmd = [] if not os.path.exists(outdir): cmdstr = 'python -c "import os; os.makedirs(\'%s\')"' % outdir cmd.extend([cmdstr]) infofile = os.path.join(outdir, 'shortinfo.txt') if not os.path.exists(infofile): cmdstr = 'dcmdir-info-mgh %s > %s' % (self.inputs.dicom_dir, infofile) cmd.extend([cmdstr]) files = self._get_filelist(outdir) for infile, outfile in files: if not os.path.exists(outfile): single_cmd = '%s %s %s' % (self.cmd, infile, os.path.join(outdir, outfile)) cmd.extend([single_cmd]) return '; '.join(cmd) class ResampleInputSpec(FSTraitedSpec): in_file = File(exists=True, argstr='-i %s', mandatory=True, desc='file to resample', position=-2) resampled_file = File(argstr='-o %s', desc='output filename', genfile=True, position=-1) voxel_size = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='-vs %.2f %.2f %.2f', desc='triplet of output voxel sizes', mandatory=True) class ResampleOutputSpec(TraitedSpec): resampled_file = File(exists=True, desc='output filename') class Resample(FSCommand): """Use FreeSurfer mri_convert to up or down-sample image files Examples -------- >>> from nipype.interfaces import freesurfer >>> resampler = freesurfer.Resample() >>> resampler.inputs.in_file = 'structural.nii' >>> resampler.inputs.resampled_file = 'resampled.nii' >>> resampler.inputs.voxel_size = (2.1, 2.1, 2.1) >>> resampler.cmdline 'mri_convert -vs 2.10 2.10 2.10 -i structural.nii -o resampled.nii' """ _cmd = 'mri_convert' input_spec = ResampleInputSpec output_spec = ResampleOutputSpec def _get_outfilename(self): if isdefined(self.inputs.resampled_file): outfile = self.inputs.resampled_file else: outfile = fname_presuffix(self.inputs.in_file, newpath=os.getcwd(), suffix='_resample') return outfile def _list_outputs(self): outputs = self.output_spec().get() outputs['resampled_file'] = self._get_outfilename() return outputs def _gen_filename(self, name): if name == 'resampled_file': return self._get_outfilename() return None class ReconAllInputSpec(CommandLineInputSpec): subject_id = traits.Str("recon_all", argstr='-subjid %s', desc='subject name', usedefault=True) directive = traits.Enum('all', 'autorecon1', 'autorecon2', 'autorecon2-cp', 'autorecon2-wm', 'autorecon2-inflate1', 'autorecon2-perhemi', 'autorecon3', 'localGI', 'qcache', argstr='-%s', desc='process directive', usedefault=True, position=0) hemi = traits.Enum('lh', 'rh', desc='hemisphere to process', argstr="-hemi %s") T1_files = InputMultiPath(File(exists=True), argstr='-i %s...', desc='name of T1 file to process') T2_file = File(exists=True, argstr="-T2 %s", min_ver='5.3.0', desc='Use a T2 image to refine the cortical surface') openmp = traits.Int(argstr="-openmp %d", desc="Number of processors to use in parallel") subjects_dir = Directory(exists=True, argstr='-sd %s', hash_files=False, desc='path to subjects directory', genfile=True) flags = traits.Str(argstr='%s', desc='additional parameters') class ReconAllIOutputSpec(FreeSurferSource.output_spec): subjects_dir = Directory(exists=True, desc='Freesurfer subjects directory.') subject_id = traits.Str(desc='Subject name for whom to retrieve data') class ReconAll(CommandLine): """Uses recon-all to generate surfaces and parcellations of structural data from anatomical images of a subject. Examples -------- >>> from nipype.interfaces.freesurfer import ReconAll >>> reconall = ReconAll() >>> reconall.inputs.subject_id = 'foo' >>> reconall.inputs.directive = 'all' >>> reconall.inputs.subjects_dir = '.' >>> reconall.inputs.T1_files = 'structural.nii' >>> reconall.cmdline 'recon-all -all -i structural.nii -subjid foo -sd .' """ _cmd = 'recon-all' _additional_metadata = ['loc', 'altkey'] input_spec = ReconAllInputSpec output_spec = ReconAllIOutputSpec _can_resume = True _steps = [ #autorecon1 ('motioncor', ['mri/rawavg.mgz', 'mri/orig.mgz']), ('talairach', ['mri/transforms/talairach.auto.xfm', 'mri/transforms/talairach.xfm']), ('nuintensitycor', ['mri/nu.mgz']), ('normalization', ['mri/T1.mgz']), ('skullstrip', ['mri/brainmask.auto.mgz', 'mri/brainmask.mgz']), #autorecon2 ('gcareg', ['mri/transforms/talairach.lta']), ('canorm', ['mri/norm.mgz']), ('careg', ['mri/transforms/talairach.m3z']), ('careginv', ['mri/transforms/talairach.m3z.inv.x.mgz', 'mri/transforms/talairach.m3z.inv.y.mgz', 'mri/transforms/talairach.m3z.inv.z.mgz']), ('rmneck', ['mri/nu_noneck.mgz']), ('skull-lta', ['mri/transforms/talairach_with_skull_2.lta']), ('calabel', ['mri/aseg.auto_noCCseg.mgz', 'mri/aseg.auto.mgz', 'mri/aseg.mgz']), ('normalization2', ['mri/brain.mgz']), ('maskbfs', ['mri/brain.finalsurfs.mgz']), ('segmentation', ['mri/wm.asegedit.mgz', 'mri/wm.mgz']), ('fill', ['mri/filled.mgz']), ('tessellate', ['surf/lh.orig.nofix', 'surf/rh.orig.nofix']), ('smooth1', ['surf/lh.smoothwm.nofix', 'surf/rh.smoothwm.nofix']), ('inflate1', ['surf/lh.inflated.nofix', 'surf/rh.inflated.nofix']), ('qsphere', ['surf/lh.qsphere.nofix', 'surf/rh.qsphere.nofix']), ('fix', ['surf/lh.orig', 'surf/rh.orig']), ('white', ['surf/lh.white', 'surf/rh.white', 'surf/lh.curv', 'surf/rh.curv', 'surf/lh.area', 'surf/rh.area', 'label/lh.cortex.label', 'label/rh.cortex.label']), ('smooth2', ['surf/lh.smoothwm', 'surf/rh.smoothwm']), ('inflate2', ['surf/lh.inflated', 'surf/rh.inflated', 'surf/lh.sulc', 'surf/rh.sulc', 'surf/lh.inflated.H', 'surf/rh.inflated.H', 'surf/lh.inflated.K', 'surf/rh.inflated.K']), #autorecon3 ('sphere', ['surf/lh.sphere', 'surf/rh.sphere']), ('surfreg', ['surf/lh.sphere.reg', 'surf/rh.sphere.reg']), ('jacobian_white', ['surf/lh.jacobian_white', 'surf/rh.jacobian_white']), ('avgcurv', ['surf/lh.avg_curv', 'surf/rh.avg_curv']), ('cortparc', ['label/lh.aparc.annot', 'label/rh.aparc.annot']), ('pial', ['surf/lh.pial', 'surf/rh.pial', 'surf/lh.curv.pial', 'surf/rh.curv.pial', 'surf/lh.area.pial', 'surf/rh.area.pial', 'surf/lh.thickness', 'surf/rh.thickness']), ('cortparc2', ['label/lh.aparc.a2009s.annot', 'label/rh.aparc.a2009s.annot']), ('parcstats2', ['stats/lh.aparc.a2009s.stats', 'stats/rh.aparc.a2009s.stats', 'stats/aparc.annot.a2009s.ctab']), ('cortribbon', ['mri/lh.ribbon.mgz', 'mri/rh.ribbon.mgz', 'mri/ribbon.mgz']), ('segstats', ['stats/aseg.stats']), ('aparc2aseg', ['mri/aparc+aseg.mgz', 'mri/aparc.a2009s+aseg.mgz']), ('wmparc', ['mri/wmparc.mgz', 'stats/wmparc.stats']), ('balabels', ['BA.ctab', 'BA.thresh.ctab']), ('label-exvivo-ec', ['label/lh.entorhinal_exvivo.label', 'label/rh.entorhinal_exvivo.label'])] def _gen_subjects_dir(self): return os.getcwd() def _gen_filename(self, name): if name == 'subjects_dir': return self._gen_subjects_dir() return None def _list_outputs(self): """ See io.FreeSurferSource.outputs for the list of outputs returned """ if isdefined(self.inputs.subjects_dir): subjects_dir = self.inputs.subjects_dir else: subjects_dir = self._gen_subjects_dir() if isdefined(self.inputs.hemi): hemi = self.inputs.hemi else: hemi = 'both' outputs = self._outputs().get() outputs.update(FreeSurferSource(subject_id=self.inputs.subject_id, subjects_dir=subjects_dir, hemi=hemi)._list_outputs()) outputs['subject_id'] = self.inputs.subject_id outputs['subjects_dir'] = subjects_dir return outputs def _is_resuming(self): subjects_dir = self.inputs.subjects_dir if not isdefined(subjects_dir): subjects_dir = self._gen_subjects_dir() if os.path.isdir(os.path.join(subjects_dir, self.inputs.subject_id, 'mri')): return True return False def _format_arg(self, name, trait_spec, value): if name == 'T1_files': if self._is_resuming(): return '' return super(ReconAll, self)._format_arg(name, trait_spec, value) @property def cmdline(self): cmd = super(ReconAll, self).cmdline if not self._is_resuming(): return cmd subjects_dir = self.inputs.subjects_dir if not isdefined(subjects_dir): subjects_dir = self._gen_subjects_dir() #cmd = cmd.replace(' -all ', ' -make all ') iflogger.info('Overriding recon-all directive') flags = [] directive = 'all' for idx, step in enumerate(self._steps): step, outfiles = step if all([os.path.exists(os.path.join(subjects_dir, self.inputs.subject_id,f)) for f in outfiles]): flags.append('-no%s'%step) if idx > 4: directive = 'autorecon2' elif idx > 23: directive = 'autorecon3' else: flags.append('-%s'%step) cmd = cmd.replace(' -%s ' % self.inputs.directive, ' -%s ' % directive) cmd += ' ' + ' '.join(flags) iflogger.info('resume recon-all : %s' % cmd) return cmd class BBRegisterInputSpec(FSTraitedSpec): subject_id = traits.Str(argstr='--s %s', desc='freesurfer subject id', mandatory=True) source_file = File(argstr='--mov %s', desc='source file to be registered', mandatory=True, copyfile=False) init = traits.Enum('spm', 'fsl', 'header', argstr='--init-%s', mandatory=True, xor=['init_reg_file'], desc='initialize registration spm, fsl, header') init_reg_file = File(exists=True, argstr='--init-reg %s', desc='existing registration file', xor=['init'], mandatory=True) contrast_type = traits.Enum('t1', 't2', argstr='--%s', desc='contrast type of image', mandatory=True) intermediate_file = File(exists=True, argstr="--int %s", desc="Intermediate image, e.g. in case of partial FOV") reg_frame = traits.Int(argstr="--frame %d", xor=["reg_middle_frame"], desc="0-based frame index for 4D source file") reg_middle_frame = traits.Bool(argstr="--mid-frame", xor=["reg_frame"], desc="Register middle frame of 4D source file") out_reg_file = File(argstr='--reg %s', desc='output registration file', genfile=True) spm_nifti = traits.Bool(argstr="--spm-nii", desc="force use of nifti rather than analyze with SPM") epi_mask = traits.Bool(argstr="--epi-mask", desc="mask out B0 regions in stages 1 and 2") out_fsl_file = traits.Either(traits.Bool, File, argstr="--fslmat %s", desc="write the transformation matrix in FSL FLIRT format") registered_file = traits.Either(traits.Bool, File, argstr='--o %s', desc='output warped sourcefile either True or filename') class BBRegisterOutputSpec(TraitedSpec): out_reg_file = File(exists=True, desc='Output registration file') out_fsl_file = File(desc='Output FLIRT-style registration file') min_cost_file = File(exists=True, desc='Output registration minimum cost file') registered_file = File(desc='Registered and resampled source file') class BBRegister(FSCommand): """Use FreeSurfer bbregister to register a volume to the Freesurfer anatomical. This program performs within-subject, cross-modal registration using a boundary-based cost function. The registration is constrained to be 6 DOF (rigid). It is required that you have an anatomical scan of the subject that has already been recon-all-ed using freesurfer. Examples -------- >>> from nipype.interfaces.freesurfer import BBRegister >>> bbreg = BBRegister(subject_id='me', source_file='structural.nii', init='header', contrast_type='t2') >>> bbreg.cmdline 'bbregister --t2 --init-header --reg structural_bbreg_me.dat --mov structural.nii --s me' """ _cmd = 'bbregister' input_spec = BBRegisterInputSpec output_spec = BBRegisterOutputSpec def _list_outputs(self): outputs = self.output_spec().get() _in = self.inputs if isdefined(_in.out_reg_file): outputs['out_reg_file'] = op.abspath(_in.out_reg_file) elif _in.source_file: suffix = '_bbreg_%s.dat' % _in.subject_id outputs['out_reg_file'] = fname_presuffix(_in.source_file, suffix=suffix, use_ext=False) if isdefined(_in.registered_file): if isinstance(_in.registered_file, bool): outputs['registered_file'] = fname_presuffix(_in.source_file, suffix='_bbreg') else: outputs['registered_file'] = op.abspath(_in.registered_file) if isdefined(_in.out_fsl_file): if isinstance(_in.out_fsl_file, bool): suffix='_bbreg_%s.mat' % _in.subject_id out_fsl_file = fname_presuffix(_in.source_file, suffix=suffix, use_ext=False) outputs['out_fsl_file'] = out_fsl_file else: outputs['out_fsl_file'] = op.abspath(_in.out_fsl_file) outputs['min_cost_file'] = outputs['out_reg_file'] + '.mincost' return outputs def _format_arg(self, name, spec, value): if name in ['registered_file', 'out_fsl_file']: if isinstance(value, bool): fname = self._list_outputs()[name] else: fname = value return spec.argstr % fname return super(BBRegister, self)._format_arg(name, spec, value) def _gen_filename(self, name): if name == 'out_reg_file': return self._list_outputs()[name] return None class ApplyVolTransformInputSpec(FSTraitedSpec): source_file = File(exists=True, argstr='--mov %s', copyfile=False, mandatory=True, desc='Input volume you wish to transform') transformed_file = File(desc='Output volume', argstr='--o %s', genfile=True) _targ_xor = ('target_file', 'tal', 'fs_target') target_file = File(exists=True, argstr='--targ %s', xor=_targ_xor, desc='Output template volume', mandatory=True) tal = traits.Bool(argstr='--tal', xor=_targ_xor, mandatory=True, desc='map to a sub FOV of MNI305 (with --reg only)') tal_resolution = traits.Float(argstr="--talres %.10f", desc="Resolution to sample when using tal") fs_target = traits.Bool(argstr='--fstarg', xor=_targ_xor, mandatory=True, requires=['reg_file'], desc='use orig.mgz from subject in regfile as target') _reg_xor = ('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject') reg_file = File(exists=True, xor=_reg_xor, argstr='--reg %s', mandatory=True, desc='tkRAS-to-tkRAS matrix (tkregister2 format)') fsl_reg_file = File(exists=True, xor=_reg_xor, argstr='--fsl %s', mandatory=True, desc='fslRAS-to-fslRAS matrix (FSL format)') xfm_reg_file = File(exists=True, xor=_reg_xor, argstr='--xfm %s', mandatory=True, desc='ScannerRAS-to-ScannerRAS matrix (MNI format)') reg_header = traits.Bool(xor=_reg_xor, argstr='--regheader', mandatory=True, desc='ScannerRAS-to-ScannerRAS matrix = identity') subject = traits.Str(xor=_reg_xor, argstr='--s %s', mandatory=True, desc='set matrix = identity and use subject for any templates') inverse = traits.Bool(desc='sample from target to source', argstr='--inv') interp = traits.Enum('trilin', 'nearest', 'cubic', argstr='--interp %s', desc='Interpolation method ( or nearest)') no_resample = traits.Bool(desc='Do not resample; just change vox2ras matrix', argstr='--no-resample') m3z_file = File(argstr="--m3z %s", desc=('This is the morph to be applied to the volume. ' 'Unless the morph is in mri/transforms (eg.: for ' 'talairach.m3z computed by reconall), you will need ' 'to specify the full path to this morph and use the ' '--noDefM3zPath flag.')) no_ded_m3z_path = traits.Bool(argstr="--noDefM3zPath", requires=['m3z_file'], desc=('To be used with the m3z flag. ' 'Instructs the code not to look for the' 'm3z morph in the default location ' '(SUBJECTS_DIR/subj/mri/transforms), ' 'but instead just use the path ' 'indicated in --m3z.')) invert_morph = traits.Bool(argstr="--inv-morph", requires=['m3z_file'], desc=('Compute and use the inverse of the ' 'non-linear morph to resample the input ' 'volume. To be used by --m3z.')) class ApplyVolTransformOutputSpec(TraitedSpec): transformed_file = File(exists=True, desc='Path to output file if used normally') class ApplyVolTransform(FSCommand): """Use FreeSurfer mri_vol2vol to apply a transform. Examples -------- >>> from nipype.interfaces.freesurfer import ApplyVolTransform >>> applyreg = ApplyVolTransform() >>> applyreg.inputs.source_file = 'structural.nii' >>> applyreg.inputs.reg_file = 'register.dat' >>> applyreg.inputs.transformed_file = 'struct_warped.nii' >>> applyreg.inputs.fs_target = True >>> applyreg.cmdline 'mri_vol2vol --fstarg --reg register.dat --mov structural.nii --o struct_warped.nii' """ _cmd = 'mri_vol2vol' input_spec = ApplyVolTransformInputSpec output_spec = ApplyVolTransformOutputSpec def _get_outfile(self): outfile = self.inputs.transformed_file if not isdefined(outfile): if self.inputs.inverse == True: if self.inputs.fs_target == True: src = 'orig.mgz' else: src = self.inputs.target_file else: src = self.inputs.source_file outfile = fname_presuffix(src, newpath=os.getcwd(), suffix='_warped') return outfile def _list_outputs(self): outputs = self.output_spec().get() outputs['transformed_file'] = os.path.abspath(self._get_outfile()) return outputs def _gen_filename(self, name): if name == 'transformed_file': return self._get_outfile() return None class SmoothInputSpec(FSTraitedSpec): in_file = File(exists=True, desc='source volume', argstr='--i %s', mandatory=True) reg_file = File(desc='registers volume to surface anatomical ', argstr='--reg %s', mandatory=True, exists=True) smoothed_file = File(desc='output volume', argstr='--o %s', genfile=True) proj_frac_avg = traits.Tuple(traits.Float, traits.Float, traits.Float, xor=['proj_frac'], desc='average a long normal min max delta', argstr='--projfrac-avg %.2f %.2f %.2f') proj_frac = traits.Float(desc='project frac of thickness a long surface normal', xor=['proj_frac_avg'], argstr='--projfrac %s') surface_fwhm = traits.Range(low=0.0, requires=['reg_file'], mandatory=True, xor=['num_iters'], desc='surface FWHM in mm', argstr='--fwhm %f') num_iters = traits.Range(low=1, xor=['surface_fwhm'], mandatory=True, argstr='--niters %d', desc='number of iterations instead of fwhm') vol_fwhm = traits.Range(low=0.0, argstr='--vol-fwhm %f', desc='volume smoothing outside of surface') class SmoothOutputSpec(TraitedSpec): smoothed_file = File(exists=True, desc='smoothed input volume') class Smooth(FSCommand): """Use FreeSurfer mris_volsmooth to smooth a volume This function smoothes cortical regions on a surface and non-cortical regions in volume. .. note:: Cortical voxels are mapped to the surface (3D->2D) and then the smoothed values from the surface are put back into the volume to fill the cortical ribbon. If data is smoothed with this algorithm, one has to be careful about how further processing is interpreted. Examples -------- >>> from nipype.interfaces.freesurfer import Smooth >>> smoothvol = Smooth(in_file='functional.nii', smoothed_file = 'foo_out.nii', reg_file='register.dat', surface_fwhm=10, vol_fwhm=6) >>> smoothvol.cmdline 'mris_volsmooth --i functional.nii --reg register.dat --o foo_out.nii --fwhm 10.000000 --vol-fwhm 6.000000' """ _cmd = 'mris_volsmooth' input_spec = SmoothInputSpec output_spec = SmoothOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outfile = self.inputs.smoothed_file if not isdefined(outfile): outfile = self._gen_fname(self.inputs.in_file, suffix='_smooth') outputs['smoothed_file'] = outfile return outputs def _gen_filename(self, name): if name == 'smoothed_file': return self._list_outputs()[name] return None class RobustRegisterInputSpec(FSTraitedSpec): source_file = File(mandatory=True, argstr='--mov %s', desc='volume to be registered') target_file = File(mandatory=True, argstr='--dst %s', desc='target volume for the registration') out_reg_file = File(genfile=True, argstr='--lta %s', desc='registration file to write') registered_file = traits.Either(traits.Bool, File, argstr='--warp %s', desc='registered image; either True or filename') weights_file = traits.Either(traits.Bool, File, argstr='--weights %s', desc='weights image to write; either True or filename') est_int_scale = traits.Bool(argstr='--iscale', desc='estimate intensity scale (recommended for unnormalized images)') trans_only = traits.Bool(argstr='--transonly', desc='find 3 parameter translation only') in_xfm_file = File(exists=True, argstr='--transform', desc='use initial transform on source') half_source = traits.Either(traits.Bool, File, argstr='--halfmov %s', desc="write source volume mapped to halfway space") half_targ = traits.Either(traits.Bool, File, argstr="--halfdst %s", desc="write target volume mapped to halfway space") half_weights = traits.Either(traits.Bool, File, argstr="--halfweights %s", desc="write weights volume mapped to halfway space") half_source_xfm = traits.Either(traits.Bool, File, argstr="--halfmovlta %s", desc="write transform from source to halfway space") half_targ_xfm = traits.Either(traits.Bool, File, argstr="--halfdstlta %s", desc="write transform from target to halfway space") auto_sens = traits.Bool(argstr='--satit', xor=['outlier_sens'], mandatory=True, desc='auto-detect good sensitivity') outlier_sens = traits.Float(argstr='--sat %.4f', xor=['auto_sens'], mandatory=True, desc='set outlier sensitivity explicitly') least_squares = traits.Bool(argstr='--leastsquares', desc='use least squares instead of robust estimator') no_init = traits.Bool(argstr='--noinit', desc='skip transform init') init_orient = traits.Bool(argstr='--initorient', desc='use moments for initial orient (recommended for stripped brains)') max_iterations = traits.Int(argstr='--maxit %d', desc='maximum # of times on each resolution') high_iterations = traits.Int(argstr='--highit %d', desc='max # of times on highest resolution') iteration_thresh = traits.Float(argstr='--epsit %.3f', desc='stop iterations when below threshold') subsample_thresh = traits.Int(argstr='--subsample %d', desc='subsample if dimension is above threshold size') outlier_limit = traits.Float(argstr='--wlimit %.3f', desc='set maximal outlier limit in satit') write_vo2vox = traits.Bool(argstr='--vox2vox', desc='output vox2vox matrix (default is RAS2RAS)') no_multi = traits.Bool(argstr='--nomulti', desc='work on highest resolution') mask_source = File(exists=True, argstr='--maskmov %s', desc='image to mask source volume with') mask_target = File(exists=True, argstr='--maskdst %s', desc='image to mask target volume with') force_double = traits.Bool(argstr='--doubleprec', desc='use double-precision intensities') force_float = traits.Bool(argstr='--floattype', desc='use float intensities') class RobustRegisterOutputSpec(TraitedSpec): out_reg_file = File(exists=True, desc="output registration file") registered_file = File(desc="output image with registration applied") weights_file = File(desc="image of weights used") half_source = File(desc="source image mapped to halfway space") half_targ = File(desc="target image mapped to halfway space") half_weights = File(desc="weights image mapped to halfway space") half_source_xfm = File(desc="transform file to map source image to halfway space") half_targ_xfm = File(desc="transform file to map target image to halfway space") class RobustRegister(FSCommand): """Perform intramodal linear registration (translation and rotation) using robust statistics. Examples -------- >>> from nipype.interfaces.freesurfer import RobustRegister >>> reg = RobustRegister() >>> reg.inputs.source_file = 'structural.nii' >>> reg.inputs.target_file = 'T1.nii' >>> reg.inputs.auto_sens = True >>> reg.inputs.init_orient = True >>> reg.cmdline 'mri_robust_register --satit --initorient --lta structural_robustreg.lta --mov structural.nii --dst T1.nii' References ---------- Reuter, M, Rosas, HD, and Fischl, B, (2010). Highly Accurate Inverse Consistent Registration: A Robust Approach. Neuroimage 53(4) 1181-96. """ _cmd = 'mri_robust_register' input_spec = RobustRegisterInputSpec output_spec = RobustRegisterOutputSpec def _format_arg(self, name, spec, value): for option in ["registered_file", "weights_file", "half_source", "half_targ", "half_weights", "half_source_xfm", "half_targ_xfm"]: if name == option: if isinstance(value, bool): fname = self._list_outputs()[name] else: fname = value return spec.argstr % fname return super(RobustRegister, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_reg_file'] = self.inputs.out_reg_file if not isdefined(self.inputs.out_reg_file) and self.inputs.source_file: outputs['out_reg_file'] = fname_presuffix(self.inputs.source_file, suffix='_robustreg.lta', use_ext=False) prefices = dict(src=self.inputs.source_file, trg=self.inputs.target_file) suffices = dict(registered_file=("src", "_robustreg", True), weights_file=("src", "_robustweights", True), half_source=("src", "_halfway", True), half_targ=("trg", "_halfway", True), half_weights=("src", "_halfweights", True), half_source_xfm=("src", "_robustxfm.lta", False), half_targ_xfm=("trg", "_robustxfm.lta", False)) for name, sufftup in suffices.items(): value = getattr(self.inputs, name) if isdefined(value): if isinstance(value, bool): outputs[name] = fname_presuffix(prefices[sufftup[0]], suffix=sufftup[1], newpath=os.getcwd(), use_ext=sufftup[2]) else: outputs[name] = value return outputs def _gen_filename(self, name): if name == 'out_reg_file': return self._list_outputs()[name] return None class FitMSParamsInputSpec(FSTraitedSpec): in_files = traits.List(File(exists=True), argstr="%s", position=-2, mandatory=True, desc="list of FLASH images (must be in mgh format)") tr_list = traits.List(traits.Int, desc="list of TRs of the input files (in msec)") te_list = traits.List(traits.Float, desc="list of TEs of the input files (in msec)") flip_list = traits.List(traits.Int, desc="list of flip angles of the input files") xfm_list = traits.List(File(exists=True), desc="list of transform files to apply to each FLASH image") out_dir = Directory(argstr="%s", position=-1, genfile=True, desc="directory to store output in") class FitMSParamsOutputSpec(TraitedSpec): t1_image = File(exists=True, desc="image of estimated T1 relaxation values") pd_image = File(exists=True, desc="image of estimated proton density values") t2star_image = File(exists=True, desc="image of estimated T2* values") class FitMSParams(FSCommand): """Estimate tissue paramaters from a set of FLASH images. Examples -------- >>> from nipype.interfaces.freesurfer import FitMSParams >>> msfit = FitMSParams() >>> msfit.inputs.in_files = ['flash_05.mgz', 'flash_30.mgz'] >>> msfit.inputs.out_dir = 'flash_parameters' >>> msfit.cmdline 'mri_ms_fitparms flash_05.mgz flash_30.mgz flash_parameters' """ _cmd = "mri_ms_fitparms" input_spec = FitMSParamsInputSpec output_spec = FitMSParamsOutputSpec def _format_arg(self, name, spec, value): if name == "in_files": cmd = "" for i, file in enumerate(value): if isdefined(self.inputs.tr_list): cmd = " ".join((cmd, "-tr %.1f" % self.inputs.tr_list[i])) if isdefined(self.inputs.te_list): cmd = " ".join((cmd, "-te %.3f" % self.inputs.te_list[i])) if isdefined(self.inputs.flip_list): cmd = " ".join((cmd, "-fa %.1f" % self.inputs.flip_list[i])) if isdefined(self.inputs.xfm_list): cmd = " ".join((cmd, "-at %s" % self.inputs.xfm_list[i])) cmd = " ".join((cmd, file)) return cmd return super(FitMSParams, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_dir): out_dir = self._gen_filename("out_dir") else: out_dir = self.inputs.out_dir outputs["t1_image"] = os.path.join(out_dir, "T1.mgz") outputs["pd_image"] = os.path.join(out_dir, "PD.mgz") outputs["t2star_image"] = os.path.join(out_dir, "T2star.mgz") return outputs def _gen_filename(self, name): if name == "out_dir": return os.getcwd() return None class SynthesizeFLASHInputSpec(FSTraitedSpec): fixed_weighting = traits.Bool(position=1, argstr="-w", desc="use a fixed weighting to generate optimal gray/white contrast") tr = traits.Float(mandatory=True, position=2, argstr="%.2f", desc="repetition time (in msec)") flip_angle = traits.Float(mandatory=True, position=3, argstr="%.2f", desc="flip angle (in degrees)") te = traits.Float(mandatory=True, position=4, argstr="%.3f", desc="echo time (in msec)") t1_image = File(exists=True, mandatory=True, position=5, argstr="%s", desc="image of T1 values") pd_image = File(exists=True, mandatory=True, position=6, argstr="%s", desc="image of proton density values") out_file = File(genfile=True, argstr="%s", desc="image to write") class SynthesizeFLASHOutputSpec(TraitedSpec): out_file = File(exists=True, desc="synthesized FLASH acquisition") class SynthesizeFLASH(FSCommand): """Synthesize a FLASH acquisition from T1 and proton density maps. Examples -------- >>> from nipype.interfaces.freesurfer import SynthesizeFLASH >>> syn = SynthesizeFLASH(tr=20, te=3, flip_angle=30) >>> syn.inputs.t1_image = 'T1.mgz' >>> syn.inputs.pd_image = 'PD.mgz' >>> syn.inputs.out_file = 'flash_30syn.mgz' >>> syn.cmdline 'mri_synthesize 20.00 30.00 3.000 T1.mgz PD.mgz flash_30syn.mgz' """ _cmd = "mri_synthesize" input_spec = SynthesizeFLASHInputSpec output_spec = SynthesizeFLASHOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.out_file): outputs["out_file"] = self.inputs.out_file else: outputs["out_file"] = self._gen_fname("synth-flash_%02d.mgz" % self.inputs.flip_angle, suffix="") return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()["out_file"] return None nipype-0.11.0/nipype/interfaces/freesurfer/tests/000077500000000000000000000000001257611314500220435ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ApplyMask.py000066400000000000000000000026201257611314500264050ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import ApplyMask def test_ApplyMask_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), invert_xfm=dict(argstr='-invert', ), mask_file=dict(argstr='%s', mandatory=True, position=-2, ), mask_thresh=dict(argstr='-T %.4f', ), out_file=dict(argstr='%s', genfile=True, position=-1, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), use_abs=dict(argstr='-abs', ), xfm_file=dict(argstr='-xform %s', ), xfm_source=dict(argstr='-lta_src %s', ), xfm_target=dict(argstr='-lta_dst %s', ), ) inputs = ApplyMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyMask_outputs(): output_map = dict(out_file=dict(), ) outputs = ApplyMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ApplyVolTransform.py000066400000000000000000000050631257611314500301520ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import ApplyVolTransform def test_ApplyVolTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fs_target=dict(argstr='--fstarg', mandatory=True, requires=['reg_file'], xor=('target_file', 'tal', 'fs_target'), ), fsl_reg_file=dict(argstr='--fsl %s', mandatory=True, xor=('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject'), ), ignore_exception=dict(nohash=True, usedefault=True, ), interp=dict(argstr='--interp %s', ), inverse=dict(argstr='--inv', ), invert_morph=dict(argstr='--inv-morph', requires=['m3z_file'], ), m3z_file=dict(argstr='--m3z %s', ), no_ded_m3z_path=dict(argstr='--noDefM3zPath', requires=['m3z_file'], ), no_resample=dict(argstr='--no-resample', ), reg_file=dict(argstr='--reg %s', mandatory=True, xor=('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject'), ), reg_header=dict(argstr='--regheader', mandatory=True, xor=('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject'), ), source_file=dict(argstr='--mov %s', copyfile=False, mandatory=True, ), subject=dict(argstr='--s %s', mandatory=True, xor=('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject'), ), subjects_dir=dict(), tal=dict(argstr='--tal', mandatory=True, xor=('target_file', 'tal', 'fs_target'), ), tal_resolution=dict(argstr='--talres %.10f', ), target_file=dict(argstr='--targ %s', mandatory=True, xor=('target_file', 'tal', 'fs_target'), ), terminal_output=dict(nohash=True, ), transformed_file=dict(argstr='--o %s', genfile=True, ), xfm_reg_file=dict(argstr='--xfm %s', mandatory=True, xor=('reg_file', 'fsl_reg_file', 'xfm_reg_file', 'reg_header', 'subject'), ), ) inputs = ApplyVolTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyVolTransform_outputs(): output_map = dict(transformed_file=dict(), ) outputs = ApplyVolTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_BBRegister.py000066400000000000000000000035331257611314500265000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import BBRegister def test_BBRegister_inputs(): input_map = dict(args=dict(argstr='%s', ), contrast_type=dict(argstr='--%s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), epi_mask=dict(argstr='--epi-mask', ), ignore_exception=dict(nohash=True, usedefault=True, ), init=dict(argstr='--init-%s', mandatory=True, xor=['init_reg_file'], ), init_reg_file=dict(argstr='--init-reg %s', mandatory=True, xor=['init'], ), intermediate_file=dict(argstr='--int %s', ), out_fsl_file=dict(argstr='--fslmat %s', ), out_reg_file=dict(argstr='--reg %s', genfile=True, ), reg_frame=dict(argstr='--frame %d', xor=['reg_middle_frame'], ), reg_middle_frame=dict(argstr='--mid-frame', xor=['reg_frame'], ), registered_file=dict(argstr='--o %s', ), source_file=dict(argstr='--mov %s', copyfile=False, mandatory=True, ), spm_nifti=dict(argstr='--spm-nii', ), subject_id=dict(argstr='--s %s', mandatory=True, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = BBRegister.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BBRegister_outputs(): output_map = dict(min_cost_file=dict(), out_fsl_file=dict(), out_reg_file=dict(), registered_file=dict(), ) outputs = BBRegister.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Binarize.py000066400000000000000000000043161257611314500262530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import Binarize def test_Binarize_inputs(): input_map = dict(abs=dict(argstr='--abs', ), args=dict(argstr='%s', ), bin_col_num=dict(argstr='--bincol', ), bin_val=dict(argstr='--binval %d', ), bin_val_not=dict(argstr='--binvalnot %d', ), binary_file=dict(argstr='--o %s', genfile=True, ), count_file=dict(argstr='--count %s', ), dilate=dict(argstr='--dilate %d', ), environ=dict(nohash=True, usedefault=True, ), erode=dict(argstr='--erode %d', ), erode2d=dict(argstr='--erode2d %d', ), frame_no=dict(argstr='--frame %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--i %s', copyfile=False, mandatory=True, ), invert=dict(argstr='--inv', ), mask_file=dict(argstr='--mask maskvol', ), mask_thresh=dict(argstr='--mask-thresh %f', ), match=dict(argstr='--match %d...', ), max=dict(argstr='--max %f', xor=['wm_ven_csf'], ), merge_file=dict(argstr='--merge %s', ), min=dict(argstr='--min %f', xor=['wm_ven_csf'], ), out_type=dict(argstr='', ), rmax=dict(argstr='--rmax %f', ), rmin=dict(argstr='--rmin %f', ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ventricles=dict(argstr='--ventricles', ), wm=dict(argstr='--wm', ), wm_ven_csf=dict(argstr='--wm+vcsf', xor=['min', 'max'], ), zero_edges=dict(argstr='--zero-edges', ), zero_slice_edge=dict(argstr='--zero-slice-edges', ), ) inputs = Binarize.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Binarize_outputs(): output_map = dict(binary_file=dict(), count_file=dict(), ) outputs = Binarize.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Concatenate.py000066400000000000000000000033431257611314500267330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import Concatenate def test_Concatenate_inputs(): input_map = dict(add_val=dict(argstr='--add %f', ), args=dict(argstr='%s', ), combine=dict(argstr='--combine', ), concatenated_file=dict(argstr='--o %s', genfile=True, ), environ=dict(nohash=True, usedefault=True, ), gmean=dict(argstr='--gmean %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='--i %s...', mandatory=True, ), keep_dtype=dict(argstr='--keep-datatype', ), mask_file=dict(argstr='--mask %s', ), max_bonfcor=dict(argstr='--max-bonfcor', ), max_index=dict(argstr='--max-index', ), mean_div_n=dict(argstr='--mean-div-n', ), multiply_by=dict(argstr='--mul %f', ), multiply_matrix_file=dict(argstr='--mtx %s', ), paired_stats=dict(argstr='--paired-%s', ), sign=dict(argstr='--%s', ), sort=dict(argstr='--sort', ), stats=dict(argstr='--%s', ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), vote=dict(argstr='--vote', ), ) inputs = Concatenate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Concatenate_outputs(): output_map = dict(concatenated_file=dict(), ) outputs = Concatenate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_DICOMConvert.py000066400000000000000000000017771257611314500267140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import DICOMConvert def test_DICOMConvert_inputs(): input_map = dict(args=dict(argstr='%s', ), base_output_dir=dict(mandatory=True, ), dicom_dir=dict(mandatory=True, ), dicom_info=dict(), environ=dict(nohash=True, usedefault=True, ), file_mapping=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), ignore_single_slice=dict(requires=['dicom_info'], ), out_type=dict(usedefault=True, ), seq_list=dict(requires=['dicom_info'], ), subject_dir_template=dict(usedefault=True, ), subject_id=dict(), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = DICOMConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ExtractMainComponent.py000066400000000000000000000021701257611314500306060ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import ExtractMainComponent def test_ExtractMainComponent_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), out_file=dict(argstr='%s', name_source='in_file', name_template='%s.maincmp', position=2, ), terminal_output=dict(nohash=True, ), ) inputs = ExtractMainComponent.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ExtractMainComponent_outputs(): output_map = dict(out_file=dict(), ) outputs = ExtractMainComponent.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_FSCommand.py000066400000000000000000000012001257611314500263040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.base import FSCommand def test_FSCommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = FSCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_FitMSParams.py000066400000000000000000000023031257611314500266300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import FitMSParams def test_FitMSParams_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), flip_list=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=-2, ), out_dir=dict(argstr='%s', genfile=True, position=-1, ), subjects_dir=dict(), te_list=dict(), terminal_output=dict(nohash=True, ), tr_list=dict(), xfm_list=dict(), ) inputs = FitMSParams.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FitMSParams_outputs(): output_map = dict(pd_image=dict(), t1_image=dict(), t2star_image=dict(), ) outputs = FitMSParams.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_GLMFit.py000066400000000000000000000103601257611314500255660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import GLMFit def test_GLMFit_inputs(): input_map = dict(allow_ill_cond=dict(argstr='--illcond', ), allow_repeated_subjects=dict(argstr='--allowsubjrep', ), args=dict(argstr='%s', ), calc_AR1=dict(argstr='--tar1', ), check_opts=dict(argstr='--checkopts', ), compute_log_y=dict(argstr='--logy', ), contrast=dict(argstr='--C %s...', ), cortex=dict(argstr='--cortex', xor=['label_file'], ), debug=dict(argstr='--debug', ), design=dict(argstr='--X %s', xor=('fsgd', 'design', 'one_sample'), ), diag=dict(), diag_cluster=dict(argstr='--diag-cluster', ), environ=dict(nohash=True, usedefault=True, ), fixed_fx_dof=dict(argstr='--ffxdof %d', xor=['fixed_fx_dof_file'], ), fixed_fx_dof_file=dict(argstr='--ffxdofdat %d', xor=['fixed_fx_dof'], ), fixed_fx_var=dict(argstr='--yffxvar %s', ), force_perm=dict(argstr='--perm-force', ), fsgd=dict(argstr='--fsgd %s %s', xor=('fsgd', 'design', 'one_sample'), ), fwhm=dict(argstr='--fwhm %f', ), glm_dir=dict(argstr='--glmdir %s', genfile=True, ), hemi=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--y %s', copyfile=False, mandatory=True, ), invert_mask=dict(argstr='--mask-inv', ), label_file=dict(argstr='--label %s', xor=['cortex'], ), mask_file=dict(argstr='--mask %s', ), no_contrast_sok=dict(argstr='--no-contrasts-ok', ), no_est_fwhm=dict(argstr='--no-est-fwhm', ), no_mask_smooth=dict(argstr='--no-mask-smooth', ), no_prune=dict(argstr='--no-prune', xor=['prunethresh'], ), one_sample=dict(argstr='--osgm', xor=('one_sample', 'fsgd', 'design', 'contrast'), ), pca=dict(argstr='--pca', ), per_voxel_reg=dict(argstr='--pvr %s...', ), profile=dict(argstr='--profile %d', ), prune=dict(argstr='--prune', ), prune_thresh=dict(argstr='--prune_thr %f', xor=['noprune'], ), resynth_test=dict(argstr='--resynthtest %d', ), save_cond=dict(argstr='--save-cond', ), save_estimate=dict(argstr='--yhat-save', ), save_res_corr_mtx=dict(argstr='--eres-scm', ), save_residual=dict(argstr='--eres-save', ), seed=dict(argstr='--seed %d', ), self_reg=dict(argstr='--selfreg %d %d %d', ), sim_done_file=dict(argstr='--sim-done %s', ), sim_sign=dict(argstr='--sim-sign %s', ), simulation=dict(argstr='--sim %s %d %f %s', ), subject_id=dict(), subjects_dir=dict(), surf=dict(argstr='--surf %s %s %s', requires=['subject_id', 'hemi'], ), surf_geo=dict(usedefault=True, ), synth=dict(argstr='--synth', ), terminal_output=dict(nohash=True, ), uniform=dict(argstr='--uniform %f %f', ), var_fwhm=dict(argstr='--var-fwhm %f', ), vox_dump=dict(argstr='--voxdump %d %d %d', ), weight_file=dict(xor=['weighted_ls'], ), weight_inv=dict(argstr='--w-inv', xor=['weighted_ls'], ), weight_sqrt=dict(argstr='--w-sqrt', xor=['weighted_ls'], ), weighted_ls=dict(argstr='--wls %s', xor=('weight_file', 'weight_inv', 'weight_sqrt'), ), ) inputs = GLMFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GLMFit_outputs(): output_map = dict(beta_file=dict(), dof_file=dict(), error_file=dict(), error_stddev_file=dict(), error_var_file=dict(), estimate_file=dict(), frame_eigenvectors=dict(), ftest_file=dict(), fwhm_file=dict(), gamma_file=dict(), gamma_var_file=dict(), glm_dir=dict(), mask_file=dict(), sig_file=dict(), singular_values=dict(), spatial_eigenvectors=dict(), svd_stats_file=dict(), ) outputs = GLMFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ImageInfo.py000066400000000000000000000022351257611314500263440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import ImageInfo def test_ImageInfo_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', position=1, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = ImageInfo.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageInfo_outputs(): output_map = dict(TE=dict(), TI=dict(), TR=dict(), data_type=dict(), dimensions=dict(), file_format=dict(), info=dict(), orientation=dict(), out_file=dict(), ph_enc_dir=dict(), vox_sizes=dict(), ) outputs = ImageInfo.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Label2Vol.py000066400000000000000000000047461257611314500263010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import Label2Vol def test_Label2Vol_inputs(): input_map = dict(annot_file=dict(argstr='--annot %s', copyfile=False, mandatory=True, requires=('subject_id', 'hemi'), xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), ), aparc_aseg=dict(argstr='--aparc+aseg', mandatory=True, xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fill_thresh=dict(argstr='--fillthresh %.f', ), hemi=dict(argstr='--hemi %s', ), identity=dict(argstr='--identity', xor=('reg_file', 'reg_header', 'identity'), ), ignore_exception=dict(nohash=True, usedefault=True, ), invert_mtx=dict(argstr='--invertmtx', ), label_file=dict(argstr='--label %s...', copyfile=False, mandatory=True, xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), ), label_hit_file=dict(argstr='--hits %s', ), label_voxel_volume=dict(argstr='--labvoxvol %f', ), map_label_stat=dict(argstr='--label-stat %s', ), native_vox2ras=dict(argstr='--native-vox2ras', ), proj=dict(argstr='--proj %s %f %f %f', requires=('subject_id', 'hemi'), ), reg_file=dict(argstr='--reg %s', xor=('reg_file', 'reg_header', 'identity'), ), reg_header=dict(argstr='--regheader %s', xor=('reg_file', 'reg_header', 'identity'), ), seg_file=dict(argstr='--seg %s', copyfile=False, mandatory=True, xor=('label_file', 'annot_file', 'seg_file', 'aparc_aseg'), ), subject_id=dict(argstr='--subject %s', ), subjects_dir=dict(), surface=dict(argstr='--surf %s', ), template_file=dict(argstr='--temp %s', mandatory=True, ), terminal_output=dict(nohash=True, ), vol_label_file=dict(argstr='--o %s', genfile=True, ), ) inputs = Label2Vol.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Label2Vol_outputs(): output_map = dict(vol_label_file=dict(), ) outputs = Label2Vol.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRIConvert.py000066400000000000000000000123071257611314500264770ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import MRIConvert def test_MRIConvert_inputs(): input_map = dict(apply_inv_transform=dict(argstr='--apply_inverse_transform %s', ), apply_transform=dict(argstr='--apply_transform %s', ), args=dict(argstr='%s', ), ascii=dict(argstr='--ascii', ), autoalign_matrix=dict(argstr='--autoalign %s', ), color_file=dict(argstr='--color_file %s', ), conform=dict(argstr='--conform', ), conform_min=dict(argstr='--conform_min', ), conform_size=dict(argstr='--conform_size %s', ), crop_center=dict(argstr='--crop %d %d %d', ), crop_gdf=dict(argstr='--crop_gdf', ), crop_size=dict(argstr='--cropsize %d %d %d', ), cut_ends=dict(argstr='--cutends %d', ), devolve_transform=dict(argstr='--devolvexfm %s', ), drop_n=dict(argstr='--ndrop %d', ), environ=dict(nohash=True, usedefault=True, ), fill_parcellation=dict(argstr='--fill_parcellation', ), force_ras=dict(argstr='--force_ras_good', ), frame=dict(argstr='--frame %d', ), frame_subsample=dict(argstr='--fsubsample %d %d %d', ), fwhm=dict(argstr='--fwhm %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_center=dict(argstr='--in_center %s', ), in_file=dict(argstr='--input_volume %s', mandatory=True, position=-2, ), in_i_dir=dict(argstr='--in_i_direction %f %f %f', ), in_i_size=dict(argstr='--in_i_size %d', ), in_info=dict(argstr='--in_info', ), in_j_dir=dict(argstr='--in_j_direction %f %f %f', ), in_j_size=dict(argstr='--in_j_size %d', ), in_k_dir=dict(argstr='--in_k_direction %f %f %f', ), in_k_size=dict(argstr='--in_k_size %d', ), in_like=dict(argstr='--in_like %s', ), in_matrix=dict(argstr='--in_matrix', ), in_orientation=dict(argstr='--in_orientation %s', ), in_scale=dict(argstr='--scale %f', ), in_stats=dict(argstr='--in_stats', ), in_type=dict(argstr='--in_type %s', ), invert_contrast=dict(argstr='--invert_contrast %f', ), midframe=dict(argstr='--mid-frame', ), no_change=dict(argstr='--nochange', ), no_scale=dict(argstr='--no_scale 1', ), no_translate=dict(argstr='--no_translate', ), no_write=dict(argstr='--no_write', ), out_center=dict(argstr='--out_center %f %f %f', ), out_datatype=dict(argstr='--out_data_type %s', ), out_file=dict(argstr='--output_volume %s', genfile=True, position=-1, ), out_i_count=dict(argstr='--out_i_count %d', ), out_i_dir=dict(argstr='--out_i_direction %f %f %f', ), out_i_size=dict(argstr='--out_i_size %d', ), out_info=dict(argstr='--out_info', ), out_j_count=dict(argstr='--out_j_count %d', ), out_j_dir=dict(argstr='--out_j_direction %f %f %f', ), out_j_size=dict(argstr='--out_j_size %d', ), out_k_count=dict(argstr='--out_k_count %d', ), out_k_dir=dict(argstr='--out_k_direction %f %f %f', ), out_k_size=dict(argstr='--out_k_size %d', ), out_matrix=dict(argstr='--out_matrix', ), out_orientation=dict(argstr='--out_orientation %s', ), out_scale=dict(argstr='--out-scale %d', ), out_stats=dict(argstr='--out_stats', ), out_type=dict(argstr='--out_type %s', ), parse_only=dict(argstr='--parse_only', ), read_only=dict(argstr='--read_only', ), reorder=dict(argstr='--reorder %d %d %d', ), resample_type=dict(argstr='--resample_type %s', ), reslice_like=dict(argstr='--reslice_like %s', ), sdcm_list=dict(argstr='--sdcmlist %s', ), skip_n=dict(argstr='--nskip %d', ), slice_bias=dict(argstr='--slice-bias %f', ), slice_crop=dict(argstr='--slice-crop %d %d', ), slice_reverse=dict(argstr='--slice-reverse', ), smooth_parcellation=dict(argstr='--smooth_parcellation', ), sphinx=dict(argstr='--sphinx', ), split=dict(argstr='--split', ), status_file=dict(argstr='--status %s', ), subject_name=dict(argstr='--subject_name %s', ), subjects_dir=dict(), te=dict(argstr='-te %d', ), template_info=dict(), template_type=dict(argstr='--template_type %s', ), terminal_output=dict(nohash=True, ), ti=dict(argstr='-ti %d', ), tr=dict(argstr='-tr %d', ), unwarp_gradient=dict(argstr='--unwarp_gradient_nonlinearity', ), vox_size=dict(argstr='-voxsize %f %f %f', ), zero_ge_z_offset=dict(argstr='--zero_ge_z_offset', ), zero_outlines=dict(argstr='--zero_outlines', ), ) inputs = MRIConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRIConvert_outputs(): output_map = dict(out_file=dict(), ) outputs = MRIConvert.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRIMarchingCubes.py000066400000000000000000000023711257611314500275710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import MRIMarchingCubes def test_MRIMarchingCubes_inputs(): input_map = dict(args=dict(argstr='%s', ), connectivity_value=dict(argstr='%d', position=-1, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), label_value=dict(argstr='%d', mandatory=True, position=2, ), out_file=dict(argstr='./%s', genfile=True, position=-2, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = MRIMarchingCubes.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRIMarchingCubes_outputs(): output_map = dict(surface=dict(), ) outputs = MRIMarchingCubes.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRIPretess.py000066400000000000000000000025321257611314500265030ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import MRIPretess def test_MRIPretess_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_filled=dict(argstr='%s', mandatory=True, position=-4, ), in_norm=dict(argstr='%s', mandatory=True, position=-2, ), keep=dict(argstr='-keep', ), label=dict(argstr='%s', mandatory=True, position=-3, usedefault=True, ), nocorners=dict(argstr='-nocorners', ), out_file=dict(argstr='%s', genfile=True, position=-1, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), test=dict(argstr='-test', ), ) inputs = MRIPretess.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRIPretess_outputs(): output_map = dict(out_file=dict(), ) outputs = MRIPretess.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRISPreproc.py000066400000000000000000000044121257611314500266120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import MRISPreproc def test_MRISPreproc_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fsgd_file=dict(argstr='--fsgd %s', xor=('subjects', 'fsgd_file', 'subject_file'), ), fwhm=dict(argstr='--fwhm %f', xor=['num_iters'], ), fwhm_source=dict(argstr='--fwhm-src %f', xor=['num_iters_source'], ), hemi=dict(argstr='--hemi %s', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), num_iters=dict(argstr='--niters %d', xor=['fwhm'], ), num_iters_source=dict(argstr='--niterssrc %d', xor=['fwhm_source'], ), out_file=dict(argstr='--out %s', genfile=True, ), proj_frac=dict(argstr='--projfrac %s', ), smooth_cortex_only=dict(argstr='--smooth-cortex-only', ), source_format=dict(argstr='--srcfmt %s', ), subject_file=dict(argstr='--f %s', xor=('subjects', 'fsgd_file', 'subject_file'), ), subjects=dict(argstr='--s %s...', xor=('subjects', 'fsgd_file', 'subject_file'), ), subjects_dir=dict(), surf_area=dict(argstr='--area %s', xor=('surf_measure', 'surf_measure_file', 'surf_area'), ), surf_dir=dict(argstr='--surfdir %s', ), surf_measure=dict(argstr='--meas %s', xor=('surf_measure', 'surf_measure_file', 'surf_area'), ), surf_measure_file=dict(argstr='--is %s...', xor=('surf_measure', 'surf_measure_file', 'surf_area'), ), target=dict(argstr='--target %s', mandatory=True, ), terminal_output=dict(nohash=True, ), vol_measure_file=dict(argstr='--iv %s %s...', ), ) inputs = MRISPreproc.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRISPreproc_outputs(): output_map = dict(out_file=dict(), ) outputs = MRISPreproc.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRITessellate.py000066400000000000000000000023761257611314500271710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import MRITessellate def test_MRITessellate_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), label_value=dict(argstr='%d', mandatory=True, position=-2, ), out_file=dict(argstr='./%s', genfile=True, position=-1, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), tesselate_all_voxels=dict(argstr='-a', ), use_real_RAS_coordinates=dict(argstr='-n', ), ) inputs = MRITessellate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRITessellate_outputs(): output_map = dict(surface=dict(), ) outputs = MRITessellate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MRIsConvert.py000066400000000000000000000034221257611314500266600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import MRIsConvert def test_MRIsConvert_inputs(): input_map = dict(annot_file=dict(argstr='--annot %s', ), args=dict(argstr='%s', ), dataarray_num=dict(argstr='--da_num %d', ), environ=dict(nohash=True, usedefault=True, ), functional_file=dict(argstr='-f %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), label_file=dict(argstr='--label %s', ), labelstats_outfile=dict(argstr='--labelstats %s', ), normal=dict(argstr='-n', ), origname=dict(argstr='-o %s', ), out_datatype=dict(mandatory=True, ), out_file=dict(argstr='./%s', genfile=True, position=-1, ), parcstats_file=dict(argstr='--parcstats %s', ), patch=dict(argstr='-p', ), rescale=dict(argstr='-r', ), scalarcurv_file=dict(argstr='-c %s', ), scale=dict(argstr='-s %.3f', ), subjects_dir=dict(), talairachxfm_subjid=dict(argstr='-t %s', ), terminal_output=dict(nohash=True, ), vertex=dict(argstr='-v', ), xyz_ascii=dict(argstr='-a', ), ) inputs = MRIsConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRIsConvert_outputs(): output_map = dict(converted=dict(), ) outputs = MRIsConvert.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MS_LDA.py000066400000000000000000000027001257611314500255020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import MS_LDA def test_MS_LDA_inputs(): input_map = dict(args=dict(argstr='%s', ), conform=dict(argstr='-conform', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), images=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), label_file=dict(argstr='-label %s', ), lda_labels=dict(argstr='-lda %s', mandatory=True, sep=' ', ), mask_file=dict(argstr='-mask %s', ), shift=dict(argstr='-shift %d', ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), use_weights=dict(argstr='-W', ), vol_synth_file=dict(argstr='-synth %s', mandatory=True, ), weight_file=dict(argstr='-weight %s', mandatory=True, ), ) inputs = MS_LDA.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MS_LDA_outputs(): output_map = dict(vol_synth_file=dict(), weight_file=dict(), ) outputs = MS_LDA.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_MakeAverageSubject.py000066400000000000000000000021601257611314500301730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import MakeAverageSubject def test_MakeAverageSubject_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_name=dict(argstr='--out %s', usedefault=True, ), subjects_dir=dict(), subjects_ids=dict(argstr='--subjects %s', mandatory=True, sep=' ', ), terminal_output=dict(nohash=True, ), ) inputs = MakeAverageSubject.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MakeAverageSubject_outputs(): output_map = dict(average_subject_name=dict(), ) outputs = MakeAverageSubject.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_OneSampleTTest.py000066400000000000000000000104301257611314500273510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import OneSampleTTest def test_OneSampleTTest_inputs(): input_map = dict(allow_ill_cond=dict(argstr='--illcond', ), allow_repeated_subjects=dict(argstr='--allowsubjrep', ), args=dict(argstr='%s', ), calc_AR1=dict(argstr='--tar1', ), check_opts=dict(argstr='--checkopts', ), compute_log_y=dict(argstr='--logy', ), contrast=dict(argstr='--C %s...', ), cortex=dict(argstr='--cortex', xor=['label_file'], ), debug=dict(argstr='--debug', ), design=dict(argstr='--X %s', xor=('fsgd', 'design', 'one_sample'), ), diag=dict(), diag_cluster=dict(argstr='--diag-cluster', ), environ=dict(nohash=True, usedefault=True, ), fixed_fx_dof=dict(argstr='--ffxdof %d', xor=['fixed_fx_dof_file'], ), fixed_fx_dof_file=dict(argstr='--ffxdofdat %d', xor=['fixed_fx_dof'], ), fixed_fx_var=dict(argstr='--yffxvar %s', ), force_perm=dict(argstr='--perm-force', ), fsgd=dict(argstr='--fsgd %s %s', xor=('fsgd', 'design', 'one_sample'), ), fwhm=dict(argstr='--fwhm %f', ), glm_dir=dict(argstr='--glmdir %s', genfile=True, ), hemi=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--y %s', copyfile=False, mandatory=True, ), invert_mask=dict(argstr='--mask-inv', ), label_file=dict(argstr='--label %s', xor=['cortex'], ), mask_file=dict(argstr='--mask %s', ), no_contrast_sok=dict(argstr='--no-contrasts-ok', ), no_est_fwhm=dict(argstr='--no-est-fwhm', ), no_mask_smooth=dict(argstr='--no-mask-smooth', ), no_prune=dict(argstr='--no-prune', xor=['prunethresh'], ), one_sample=dict(argstr='--osgm', xor=('one_sample', 'fsgd', 'design', 'contrast'), ), pca=dict(argstr='--pca', ), per_voxel_reg=dict(argstr='--pvr %s...', ), profile=dict(argstr='--profile %d', ), prune=dict(argstr='--prune', ), prune_thresh=dict(argstr='--prune_thr %f', xor=['noprune'], ), resynth_test=dict(argstr='--resynthtest %d', ), save_cond=dict(argstr='--save-cond', ), save_estimate=dict(argstr='--yhat-save', ), save_res_corr_mtx=dict(argstr='--eres-scm', ), save_residual=dict(argstr='--eres-save', ), seed=dict(argstr='--seed %d', ), self_reg=dict(argstr='--selfreg %d %d %d', ), sim_done_file=dict(argstr='--sim-done %s', ), sim_sign=dict(argstr='--sim-sign %s', ), simulation=dict(argstr='--sim %s %d %f %s', ), subject_id=dict(), subjects_dir=dict(), surf=dict(argstr='--surf %s %s %s', requires=['subject_id', 'hemi'], ), surf_geo=dict(usedefault=True, ), synth=dict(argstr='--synth', ), terminal_output=dict(nohash=True, ), uniform=dict(argstr='--uniform %f %f', ), var_fwhm=dict(argstr='--var-fwhm %f', ), vox_dump=dict(argstr='--voxdump %d %d %d', ), weight_file=dict(xor=['weighted_ls'], ), weight_inv=dict(argstr='--w-inv', xor=['weighted_ls'], ), weight_sqrt=dict(argstr='--w-sqrt', xor=['weighted_ls'], ), weighted_ls=dict(argstr='--wls %s', xor=('weight_file', 'weight_inv', 'weight_sqrt'), ), ) inputs = OneSampleTTest.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_OneSampleTTest_outputs(): output_map = dict(beta_file=dict(), dof_file=dict(), error_file=dict(), error_stddev_file=dict(), error_var_file=dict(), estimate_file=dict(), frame_eigenvectors=dict(), ftest_file=dict(), fwhm_file=dict(), gamma_file=dict(), gamma_var_file=dict(), glm_dir=dict(), mask_file=dict(), sig_file=dict(), singular_values=dict(), spatial_eigenvectors=dict(), svd_stats_file=dict(), ) outputs = OneSampleTTest.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ParseDICOMDir.py000066400000000000000000000022451257611314500267740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import ParseDICOMDir def test_ParseDICOMDir_inputs(): input_map = dict(args=dict(argstr='%s', ), dicom_dir=dict(argstr='--d %s', mandatory=True, ), dicom_info_file=dict(argstr='--o %s', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), sortbyrun=dict(argstr='--sortbyrun', ), subjects_dir=dict(), summarize=dict(argstr='--summarize', ), terminal_output=dict(nohash=True, ), ) inputs = ParseDICOMDir.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ParseDICOMDir_outputs(): output_map = dict(dicom_info_file=dict(), ) outputs = ParseDICOMDir.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py000066400000000000000000000053741257611314500262140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import ReconAll def test_ReconAll_inputs(): input_map = dict(T1_files=dict(argstr='-i %s...', ), T2_file=dict(argstr='-T2 %s', min_ver='5.3.0', ), args=dict(argstr='%s', ), directive=dict(argstr='-%s', position=0, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), flags=dict(argstr='%s', ), hemi=dict(argstr='-hemi %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), openmp=dict(argstr='-openmp %d', ), subject_id=dict(argstr='-subjid %s', usedefault=True, ), subjects_dir=dict(argstr='-sd %s', genfile=True, hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = ReconAll.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ReconAll_outputs(): output_map = dict(BA_stats=dict(altkey='BA', loc='stats', ), T1=dict(loc='mri', ), annot=dict(altkey='*annot', loc='label', ), aparc_a2009s_stats=dict(altkey='aparc.a2009s', loc='stats', ), aparc_aseg=dict(altkey='aparc*aseg', loc='mri', ), aparc_stats=dict(altkey='aparc', loc='stats', ), aseg=dict(loc='mri', ), aseg_stats=dict(altkey='aseg', loc='stats', ), brain=dict(loc='mri', ), brainmask=dict(loc='mri', ), curv=dict(loc='surf', ), curv_stats=dict(altkey='curv', loc='stats', ), entorhinal_exvivo_stats=dict(altkey='entorhinal_exvivo', loc='stats', ), filled=dict(loc='mri', ), inflated=dict(loc='surf', ), label=dict(altkey='*label', loc='label', ), norm=dict(loc='mri', ), nu=dict(loc='mri', ), orig=dict(loc='mri', ), pial=dict(loc='surf', ), rawavg=dict(loc='mri', ), ribbon=dict(altkey='*ribbon', loc='mri', ), smoothwm=dict(loc='surf', ), sphere=dict(loc='surf', ), sphere_reg=dict(altkey='sphere.reg', loc='surf', ), subject_id=dict(), subjects_dir=dict(), sulc=dict(loc='surf', ), thickness=dict(loc='surf', ), volume=dict(loc='surf', ), white=dict(loc='surf', ), wm=dict(loc='mri', ), wmparc=dict(loc='mri', ), wmparc_stats=dict(altkey='wmparc', loc='stats', ), ) outputs = ReconAll.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Resample.py000066400000000000000000000022211257611314500262510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import Resample def test_Resample_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=-2, ), resampled_file=dict(argstr='-o %s', genfile=True, position=-1, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), voxel_size=dict(argstr='-vs %.2f %.2f %.2f', mandatory=True, ), ) inputs = Resample.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Resample_outputs(): output_map = dict(resampled_file=dict(), ) outputs = Resample.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_RobustRegister.py000066400000000000000000000053161257611314500274740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import RobustRegister def test_RobustRegister_inputs(): input_map = dict(args=dict(argstr='%s', ), auto_sens=dict(argstr='--satit', mandatory=True, xor=['outlier_sens'], ), environ=dict(nohash=True, usedefault=True, ), est_int_scale=dict(argstr='--iscale', ), force_double=dict(argstr='--doubleprec', ), force_float=dict(argstr='--floattype', ), half_source=dict(argstr='--halfmov %s', ), half_source_xfm=dict(argstr='--halfmovlta %s', ), half_targ=dict(argstr='--halfdst %s', ), half_targ_xfm=dict(argstr='--halfdstlta %s', ), half_weights=dict(argstr='--halfweights %s', ), high_iterations=dict(argstr='--highit %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_xfm_file=dict(argstr='--transform', ), init_orient=dict(argstr='--initorient', ), iteration_thresh=dict(argstr='--epsit %.3f', ), least_squares=dict(argstr='--leastsquares', ), mask_source=dict(argstr='--maskmov %s', ), mask_target=dict(argstr='--maskdst %s', ), max_iterations=dict(argstr='--maxit %d', ), no_init=dict(argstr='--noinit', ), no_multi=dict(argstr='--nomulti', ), out_reg_file=dict(argstr='--lta %s', genfile=True, ), outlier_limit=dict(argstr='--wlimit %.3f', ), outlier_sens=dict(argstr='--sat %.4f', mandatory=True, xor=['auto_sens'], ), registered_file=dict(argstr='--warp %s', ), source_file=dict(argstr='--mov %s', mandatory=True, ), subjects_dir=dict(), subsample_thresh=dict(argstr='--subsample %d', ), target_file=dict(argstr='--dst %s', mandatory=True, ), terminal_output=dict(nohash=True, ), trans_only=dict(argstr='--transonly', ), weights_file=dict(argstr='--weights %s', ), write_vo2vox=dict(argstr='--vox2vox', ), ) inputs = RobustRegister.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_RobustRegister_outputs(): output_map = dict(half_source=dict(), half_source_xfm=dict(), half_targ=dict(), half_targ_xfm=dict(), half_weights=dict(), out_reg_file=dict(), registered_file=dict(), weights_file=dict(), ) outputs = RobustRegister.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SampleToSurface.py000066400000000000000000000063011257611314500275410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import SampleToSurface def test_SampleToSurface_inputs(): input_map = dict(apply_rot=dict(argstr='--rot %.3f %.3f %.3f', ), apply_trans=dict(argstr='--trans %.3f %.3f %.3f', ), args=dict(argstr='%s', ), cortex_mask=dict(argstr='--cortex', xor=['mask_label'], ), environ=dict(nohash=True, usedefault=True, ), fix_tk_reg=dict(argstr='--fixtkreg', ), float2int_method=dict(argstr='--float2int %s', ), frame=dict(argstr='--frame %d', ), hemi=dict(argstr='--hemi %s', mandatory=True, ), hits_file=dict(argstr='--srchit %s', ), hits_type=dict(argstr='--srchit_type', ), ico_order=dict(argstr='--icoorder %d', requires=['target_subject'], ), ignore_exception=dict(nohash=True, usedefault=True, ), interp_method=dict(argstr='--interp %s', ), mask_label=dict(argstr='--mask %s', xor=['cortex_mask'], ), mni152reg=dict(argstr='--mni152reg', mandatory=True, xor=['reg_file', 'reg_header', 'mni152reg'], ), no_reshape=dict(argstr='--noreshape', xor=['reshape'], ), out_file=dict(argstr='--o %s', genfile=True, ), out_type=dict(argstr='--out_type %s', ), override_reg_subj=dict(argstr='--srcsubject %s', requires=['subject_id'], ), projection_stem=dict(mandatory=True, xor=['sampling_method'], ), reference_file=dict(argstr='--ref %s', ), reg_file=dict(argstr='--reg %s', mandatory=True, xor=['reg_file', 'reg_header', 'mni152reg'], ), reg_header=dict(argstr='--regheader %s', mandatory=True, requires=['subject_id'], xor=['reg_file', 'reg_header', 'mni152reg'], ), reshape=dict(argstr='--reshape', xor=['no_reshape'], ), reshape_slices=dict(argstr='--rf %d', ), sampling_method=dict(argstr='%s', mandatory=True, requires=['sampling_range', 'sampling_units'], xor=['projection_stem'], ), sampling_range=dict(), sampling_units=dict(), scale_input=dict(argstr='--scale %.3f', ), smooth_surf=dict(argstr='--surf-fwhm %.3f', ), smooth_vol=dict(argstr='--fwhm %.3f', ), source_file=dict(argstr='--mov %s', mandatory=True, ), subject_id=dict(), subjects_dir=dict(), surf_reg=dict(argstr='--surfreg', requires=['target_subject'], ), surface=dict(argstr='--surf %s', ), target_subject=dict(argstr='--trgsubject %s', ), terminal_output=dict(nohash=True, ), vox_file=dict(argstr='--nvox %s', ), ) inputs = SampleToSurface.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SampleToSurface_outputs(): output_map = dict(hits_file=dict(), out_file=dict(), vox_file=dict(), ) outputs = SampleToSurface.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SegStats.py000066400000000000000000000056401257611314500262460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.model import SegStats def test_SegStats_inputs(): input_map = dict(annot=dict(argstr='--annot %s %s %s', mandatory=True, xor=('segmentation_file', 'annot', 'surf_label'), ), args=dict(argstr='%s', ), avgwf_file=dict(argstr='--avgwfvol %s', ), avgwf_txt_file=dict(argstr='--avgwf %s', ), brain_vol=dict(), calc_power=dict(argstr='--%s', ), calc_snr=dict(argstr='--snr', ), color_table_file=dict(argstr='--ctab %s', xor=('color_table_file', 'default_color_table', 'gca_color_table'), ), cortex_vol_from_surf=dict(argstr='--surf-ctx-vol', ), default_color_table=dict(argstr='--ctab-default', xor=('color_table_file', 'default_color_table', 'gca_color_table'), ), environ=dict(nohash=True, usedefault=True, ), etiv=dict(argstr='--etiv', ), etiv_only=dict(), exclude_ctx_gm_wm=dict(argstr='--excl-ctxgmwm', ), exclude_id=dict(argstr='--excludeid %d', ), frame=dict(argstr='--frame %d', ), gca_color_table=dict(argstr='--ctab-gca %s', xor=('color_table_file', 'default_color_table', 'gca_color_table'), ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--i %s', ), mask_erode=dict(argstr='--maskerode %d', ), mask_file=dict(argstr='--mask %s', ), mask_frame=dict(requires=['mask_file'], ), mask_invert=dict(argstr='--maskinvert', ), mask_sign=dict(), mask_thresh=dict(argstr='--maskthresh %f', ), multiply=dict(argstr='--mul %f', ), non_empty_only=dict(argstr='--nonempty', ), partial_volume_file=dict(argstr='--pv %f', ), segment_id=dict(argstr='--id %s...', ), segmentation_file=dict(argstr='--seg %s', mandatory=True, xor=('segmentation_file', 'annot', 'surf_label'), ), sf_avg_file=dict(argstr='--sfavg %s', ), subjects_dir=dict(), summary_file=dict(argstr='--sum %s', genfile=True, ), surf_label=dict(argstr='--slabel %s %s %s', mandatory=True, xor=('segmentation_file', 'annot', 'surf_label'), ), terminal_output=dict(nohash=True, ), vox=dict(argstr='--vox %s', ), wm_vol_from_surf=dict(argstr='--surf-wm-vol', ), ) inputs = SegStats.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SegStats_outputs(): output_map = dict(avgwf_file=dict(), avgwf_txt_file=dict(), sf_avg_file=dict(), summary_file=dict(), ) outputs = SegStats.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Smooth.py000066400000000000000000000030111257611314500257500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import Smooth def test_Smooth_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--i %s', mandatory=True, ), num_iters=dict(argstr='--niters %d', mandatory=True, xor=['surface_fwhm'], ), proj_frac=dict(argstr='--projfrac %s', xor=['proj_frac_avg'], ), proj_frac_avg=dict(argstr='--projfrac-avg %.2f %.2f %.2f', xor=['proj_frac'], ), reg_file=dict(argstr='--reg %s', mandatory=True, ), smoothed_file=dict(argstr='--o %s', genfile=True, ), subjects_dir=dict(), surface_fwhm=dict(argstr='--fwhm %f', mandatory=True, requires=['reg_file'], xor=['num_iters'], ), terminal_output=dict(nohash=True, ), vol_fwhm=dict(argstr='--vol-fwhm %f', ), ) inputs = Smooth.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Smooth_outputs(): output_map = dict(smoothed_file=dict(), ) outputs = Smooth.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SmoothTessellation.py000066400000000000000000000034551257611314500303530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import SmoothTessellation def test_SmoothTessellation_inputs(): input_map = dict(args=dict(argstr='%s', ), curvature_averaging_iterations=dict(argstr='-a %d', position=-1, usedefault=True, ), disable_estimates=dict(argstr='-nw', ), environ=dict(nohash=True, usedefault=True, ), gaussian_curvature_norm_steps=dict(argstr='%d ', position=4, ), gaussian_curvature_smoothing_steps=dict(argstr='%d', position=5, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), normalize_area=dict(argstr='-area', ), out_area_file=dict(argstr='-b %s', ), out_curvature_file=dict(argstr='-c %s', ), out_file=dict(argstr='%s', genfile=True, position=2, ), smoothing_iterations=dict(argstr='-n %d', position=-2, usedefault=True, ), snapshot_writing_iterations=dict(argstr='-w %d', ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), use_gaussian_curvature_smoothing=dict(argstr='-g', position=3, ), use_momentum=dict(argstr='-m', ), ) inputs = SmoothTessellation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SmoothTessellation_outputs(): output_map = dict(surface=dict(), ) outputs = SmoothTessellation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Surface2VolTransform.py000066400000000000000000000034601257611314500305360ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import Surface2VolTransform def test_Surface2VolTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), hemi=dict(argstr='--hemi %s', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mkmask=dict(argstr='--mkmask', ), projfrac=dict(argstr='--projfrac %s', ), reg_file=dict(argstr='--volreg %s', mandatory=True, xor=['subject_id'], ), source_file=dict(argstr='--surfval %s', copyfile=False, mandatory=True, ), subject_id=dict(argstr='--identity %s', xor=['reg_file'], ), subjects_dir=dict(argstr='--sd %s', ), surf_name=dict(argstr='--surf %s', ), template_file=dict(argstr='--template %s', ), terminal_output=dict(nohash=True, ), transformed_file=dict(argstr='--outvol %s', hash_files=False, name_source=['source_file'], name_template='%s_asVol.nii', ), vertexvol_file=dict(argstr='--vtxvol %s', hash_files=False, name_source=['source_file'], name_template='%s_asVol_vertex.nii', ), ) inputs = Surface2VolTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Surface2VolTransform_outputs(): output_map = dict(transformed_file=dict(), vertexvol_file=dict(), ) outputs = Surface2VolTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SurfaceSmooth.py000066400000000000000000000026451257611314500272750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import SurfaceSmooth def test_SurfaceSmooth_inputs(): input_map = dict(args=dict(argstr='%s', ), cortex=dict(argstr='--cortex', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), fwhm=dict(argstr='--fwhm %.4f', xor=['smooth_iters'], ), hemi=dict(argstr='--hemi %s', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--sval %s', mandatory=True, ), out_file=dict(argstr='--tval %s', genfile=True, ), reshape=dict(argstr='--reshape', ), smooth_iters=dict(argstr='--smooth %d', xor=['fwhm'], ), subject_id=dict(argstr='--s %s', mandatory=True, ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = SurfaceSmooth.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SurfaceSmooth_outputs(): output_map = dict(out_file=dict(), ) outputs = SurfaceSmooth.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SurfaceSnapshots.py000066400000000000000000000056021257611314500300020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import SurfaceSnapshots def test_SurfaceSnapshots_inputs(): input_map = dict(annot_file=dict(argstr='-annotation %s', xor=['annot_name'], ), annot_name=dict(argstr='-annotation %s', xor=['annot_file'], ), args=dict(argstr='%s', ), colortable=dict(argstr='-colortable %s', ), demean_overlay=dict(argstr='-zm', ), environ=dict(nohash=True, usedefault=True, ), hemi=dict(argstr='%s', mandatory=True, position=2, ), identity_reg=dict(argstr='-overlay-reg-identity', xor=['overlay_reg', 'identity_reg', 'mni152_reg'], ), ignore_exception=dict(nohash=True, usedefault=True, ), invert_overlay=dict(argstr='-invphaseflag 1', ), label_file=dict(argstr='-label %s', xor=['label_name'], ), label_name=dict(argstr='-label %s', xor=['label_file'], ), label_outline=dict(argstr='-label-outline', ), label_under=dict(argstr='-labels-under', ), mni152_reg=dict(argstr='-mni152reg', xor=['overlay_reg', 'identity_reg', 'mni152_reg'], ), orig_suffix=dict(argstr='-orig %s', ), overlay=dict(argstr='-overlay %s', requires=['overlay_range'], ), overlay_range=dict(argstr='%s', ), overlay_range_offset=dict(argstr='-foffset %.3f', ), overlay_reg=dict(argstr='-overlay-reg %s', xor=['overlay_reg', 'identity_reg', 'mni152_reg'], ), patch_file=dict(argstr='-patch %s', ), reverse_overlay=dict(argstr='-revphaseflag 1', ), screenshot_stem=dict(), show_color_scale=dict(argstr='-colscalebarflag 1', ), show_color_text=dict(argstr='-colscaletext 1', ), show_curv=dict(argstr='-curv', xor=['show_gray_curv'], ), show_gray_curv=dict(argstr='-gray', xor=['show_curv'], ), six_images=dict(), sphere_suffix=dict(argstr='-sphere %s', ), stem_template_args=dict(requires=['screenshot_stem'], ), subject_id=dict(argstr='%s', mandatory=True, position=1, ), subjects_dir=dict(), surface=dict(argstr='%s', mandatory=True, position=3, ), tcl_script=dict(argstr='%s', genfile=True, ), terminal_output=dict(nohash=True, ), truncate_overlay=dict(argstr='-truncphaseflag 1', ), ) inputs = SurfaceSnapshots.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SurfaceSnapshots_outputs(): output_map = dict(snapshots=dict(), ) outputs = SurfaceSnapshots.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SurfaceTransform.py000066400000000000000000000033051257611314500277710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import SurfaceTransform def test_SurfaceTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), hemi=dict(argstr='--hemi %s', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='--tval %s', genfile=True, ), reshape=dict(argstr='--reshape', ), reshape_factor=dict(argstr='--reshape-factor', ), source_annot_file=dict(argstr='--sval-annot %s', mandatory=True, xor=['source_file'], ), source_file=dict(argstr='--sval %s', mandatory=True, xor=['source_annot_file'], ), source_subject=dict(argstr='--srcsubject %s', mandatory=True, ), source_type=dict(argstr='--sfmt %s', requires=['source_file'], ), subjects_dir=dict(), target_ico_order=dict(argstr='--trgicoorder %d', ), target_subject=dict(argstr='--trgsubject %s', mandatory=True, ), target_type=dict(argstr='--tfmt %s', ), terminal_output=dict(nohash=True, ), ) inputs = SurfaceTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SurfaceTransform_outputs(): output_map = dict(out_file=dict(), ) outputs = SurfaceTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_SynthesizeFLASH.py000066400000000000000000000026461257611314500274370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import SynthesizeFLASH def test_SynthesizeFLASH_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixed_weighting=dict(argstr='-w', position=1, ), flip_angle=dict(argstr='%.2f', mandatory=True, position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='%s', genfile=True, ), pd_image=dict(argstr='%s', mandatory=True, position=6, ), subjects_dir=dict(), t1_image=dict(argstr='%s', mandatory=True, position=5, ), te=dict(argstr='%.3f', mandatory=True, position=4, ), terminal_output=dict(nohash=True, ), tr=dict(argstr='%.2f', mandatory=True, position=2, ), ) inputs = SynthesizeFLASH.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SynthesizeFLASH_outputs(): output_map = dict(out_file=dict(), ) outputs = SynthesizeFLASH.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_Tkregister2.py000066400000000000000000000032111257611314500267060ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.utils import Tkregister2 def test_Tkregister2_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fsl_in_matrix=dict(argstr='--fsl %s', ), fsl_out=dict(argstr='--fslregout %s', ), fstal=dict(argstr='--fstal', xor=['target_image', 'moving_image'], ), fstarg=dict(argstr='--fstarg', xor=['target_image'], ), ignore_exception=dict(nohash=True, usedefault=True, ), moving_image=dict(argstr='--mov %s', mandatory=True, ), movscale=dict(argstr='--movscale %f', ), noedit=dict(argstr='--noedit', usedefault=True, ), reg_file=dict(argstr='--reg %s', mandatory=True, usedefault=True, ), reg_header=dict(argstr='--regheader', ), subject_id=dict(argstr='--s %s', ), subjects_dir=dict(), target_image=dict(argstr='--targ %s', xor=['fstarg'], ), terminal_output=dict(nohash=True, ), xfm=dict(argstr='--xfm %s', ), ) inputs = Tkregister2.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tkregister2_outputs(): output_map = dict(fsl_file=dict(), reg_file=dict(), ) outputs = Tkregister2.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_auto_UnpackSDICOMDir.py000066400000000000000000000026011257611314500272620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.freesurfer.preprocess import UnpackSDICOMDir def test_UnpackSDICOMDir_inputs(): input_map = dict(args=dict(argstr='%s', ), config=dict(argstr='-cfg %s', mandatory=True, xor=('run_info', 'config', 'seq_config'), ), dir_structure=dict(argstr='-%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), log_file=dict(argstr='-log %s', ), no_info_dump=dict(argstr='-noinfodump', ), no_unpack_err=dict(argstr='-no-unpackerr', ), output_dir=dict(argstr='-targ %s', ), run_info=dict(argstr='-run %d %s %s %s', mandatory=True, xor=('run_info', 'config', 'seq_config'), ), scan_only=dict(argstr='-scanonly %s', ), seq_config=dict(argstr='-seqcfg %s', mandatory=True, xor=('run_info', 'config', 'seq_config'), ), source_dir=dict(argstr='-src %s', mandatory=True, ), spm_zeropad=dict(argstr='-nspmzeropad %d', ), subjects_dir=dict(), terminal_output=dict(nohash=True, ), ) inputs = UnpackSDICOMDir.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_preprocess.py000066400000000000000000000101621257611314500256410ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from shutil import rmtree import nibabel as nif import numpy as np from tempfile import mkdtemp from nipype.testing import (assert_equal, assert_false, assert_true, assert_raises, skipif) import nipype.interfaces.freesurfer as freesurfer def no_freesurfer(): if freesurfer.Info().version is None: return True else: return False def create_files_in_directory(): outdir = os.path.realpath(mkdtemp()) cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii','b.nii'] for f in filelist: hdr = nif.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nif.save(nif.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) @skipif(no_freesurfer) def test_robustregister(): filelist, outdir, cwd = create_files_in_directory() reg = freesurfer.RobustRegister() # make sure command gets called yield assert_equal, reg.cmd, 'mri_robust_register' # test raising error with mandatory args absent yield assert_raises, ValueError, reg.run # .inputs based parameters setting reg.inputs.source_file = filelist[0] reg.inputs.target_file = filelist[1] reg.inputs.auto_sens = True yield assert_equal, reg.cmdline, ('mri_robust_register ' '--satit --lta %s_robustreg.lta --mov %s --dst %s'%(filelist[0][:-4],filelist[0],filelist[1])) # constructor based parameter setting reg2 = freesurfer.RobustRegister(source_file=filelist[0],target_file=filelist[1],outlier_sens=3.0, out_reg_file='foo.lta', half_targ=True) yield assert_equal, reg2.cmdline, ('mri_robust_register --halfdst %s_halfway.nii --lta foo.lta ' '--sat 3.0000 --mov %s --dst %s' %(os.path.join(outdir,filelist[1][:-4]),filelist[0],filelist[1])) clean_directory(outdir, cwd) @skipif(no_freesurfer) def test_fitmsparams(): filelist, outdir, cwd = create_files_in_directory() fit = freesurfer.FitMSParams() # make sure command gets called yield assert_equal, fit.cmd, 'mri_ms_fitparms' # test raising error with mandatory args absent yield assert_raises, ValueError, fit.run # .inputs based parameters setting fit.inputs.in_files = filelist fit.inputs.out_dir = outdir yield assert_equal, fit.cmdline, 'mri_ms_fitparms %s %s %s'%(filelist[0],filelist[1],outdir) # constructor based parameter setting fit2 = freesurfer.FitMSParams(in_files=filelist,te_list=[1.5,3.5],flip_list=[20,30],out_dir=outdir) yield assert_equal, fit2.cmdline, ('mri_ms_fitparms -te %.3f -fa %.1f %s -te %.3f -fa %.1f %s %s' %(1.500,20.0,filelist[0],3.500,30.0,filelist[1],outdir)) clean_directory(outdir, cwd) @skipif(no_freesurfer) def test_synthesizeflash(): filelist, outdir, cwd = create_files_in_directory() syn = freesurfer.SynthesizeFLASH() # make sure command gets called yield assert_equal, syn.cmd, 'mri_synthesize' # test raising error with mandatory args absent yield assert_raises, ValueError, syn.run # .inputs based parameters setting syn.inputs.t1_image = filelist[0] syn.inputs.pd_image = filelist[1] syn.inputs.flip_angle = 30 syn.inputs.te = 4.5 syn.inputs.tr = 20 yield assert_equal, syn.cmdline, ('mri_synthesize 20.00 30.00 4.500 %s %s %s' %(filelist[0],filelist[1],os.path.join(outdir,'synth-flash_30.mgz'))) # constructor based parameters setting syn2 = freesurfer.SynthesizeFLASH(t1_image=filelist[0],pd_image=filelist[1],flip_angle=20,te=5,tr=25) yield assert_equal, syn2.cmdline, ('mri_synthesize 25.00 20.00 5.000 %s %s %s' %(filelist[0],filelist[1],os.path.join(outdir,'synth-flash_20.mgz'))) nipype-0.11.0/nipype/interfaces/freesurfer/tests/test_utils.py000066400000000000000000000162151257611314500246210ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np import nibabel as nif from nipype.testing import (assert_equal, assert_not_equal, assert_raises, skipif) from nipype.interfaces.base import TraitError import nipype.interfaces.freesurfer as fs def no_freesurfer(): if fs.Info().version is None: return True else: return False def create_files_in_directory(): outdir = os.path.realpath(mkdtemp()) cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii','b.nii'] for f in filelist: hdr = nif.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nif.save(nif.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,f)) with open(os.path.join(outdir, 'reg.dat'), 'wt') as fp: fp.write('dummy file') filelist.append('reg.dat') return filelist, outdir, cwd def create_surf_file(): outdir = os.path.realpath(mkdtemp()) cwd = os.getcwd() os.chdir(outdir) surf = 'lh.a.nii' hdr = nif.Nifti1Header() shape = (1,100,1) hdr.set_data_shape(shape) img = np.random.random(shape) nif.save(nif.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,surf)) return surf, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) @skipif(no_freesurfer) def test_sample2surf(): s2s = fs.SampleToSurface() # Test underlying command yield assert_equal, s2s.cmd, 'mri_vol2surf' # Test mandatory args exception yield assert_raises, ValueError, s2s.run # Create testing files files, cwd, oldwd = create_files_in_directory() # Test input settings s2s.inputs.source_file = files[0] s2s.inputs.reference_file = files[1] s2s.inputs.hemi = "lh" s2s.inputs.reg_file = files[2] s2s.inputs.sampling_range = .5 s2s.inputs.sampling_units = "frac" s2s.inputs.sampling_method = "point" # Test a basic command line yield assert_equal, s2s.cmdline, ("mri_vol2surf " "--hemi lh --o %s --ref %s --reg reg.dat --projfrac 0.500 --mov %s" %(os.path.join(cwd, "lh.a.mgz"),files[1],files[0])) # Test identity s2sish = fs.SampleToSurface(source_file = files[1], reference_file = files[0],hemi="rh") yield assert_not_equal, s2s, s2sish # Test hits file name creation s2s.inputs.hits_file = True yield assert_equal, s2s._get_outfilename("hits_file"), os.path.join(cwd, "lh.a_hits.mgz") # Test that a 2-tuple range raises an error def set_illegal_range(): s2s.inputs.sampling_range = (.2, .5) yield assert_raises, TraitError, set_illegal_range # Clean up our mess clean_directory(cwd, oldwd) @skipif(no_freesurfer) def test_surfsmooth(): smooth = fs.SurfaceSmooth() # Test underlying command yield assert_equal, smooth.cmd, "mri_surf2surf" # Test mandatory args exception yield assert_raises, ValueError, smooth.run # Create testing files surf, cwd, oldwd = create_surf_file() # Test input settings smooth.inputs.in_file = surf smooth.inputs.subject_id = "fsaverage" fwhm = 5 smooth.inputs.fwhm = fwhm smooth.inputs.hemi = "lh" # Test the command line yield assert_equal, smooth.cmdline, \ ("mri_surf2surf --cortex --fwhm 5.0000 --hemi lh --sval %s --tval %s/lh.a_smooth%d.nii --s fsaverage"% (surf, cwd, fwhm)) # Test identity shmooth = fs.SurfaceSmooth( subject_id="fsaverage", fwhm=6, in_file=surf, hemi="lh", out_file="lh.a_smooth.nii") yield assert_not_equal, smooth, shmooth # Clean up clean_directory(cwd, oldwd) @skipif(no_freesurfer) def test_surfxfm(): xfm = fs.SurfaceTransform() # Test underlying command yield assert_equal, xfm.cmd, "mri_surf2surf" # Test mandatory args exception yield assert_raises, ValueError, xfm.run # Create testing files surf, cwd, oldwd = create_surf_file() # Test input settings xfm.inputs.source_file = surf xfm.inputs.source_subject = "my_subject" xfm.inputs.target_subject = "fsaverage" xfm.inputs.hemi = "lh" # Test the command line yield assert_equal, xfm.cmdline, \ ("mri_surf2surf --hemi lh --tval %s/lh.a.fsaverage.nii --sval %s --srcsubject my_subject --trgsubject fsaverage"% (cwd, surf)) # Test identity xfmish = fs.SurfaceTransform( source_subject="fsaverage", target_subject="my_subject", source_file=surf, hemi="lh") yield assert_not_equal, xfm, xfmish # Clean up clean_directory(cwd, oldwd) @skipif(no_freesurfer) def test_applymask(): masker = fs.ApplyMask() filelist, testdir, origdir = create_files_in_directory() # Test underlying command yield assert_equal, masker.cmd, "mri_mask" # Test exception with mandatory args absent yield assert_raises, ValueError, masker.run for input in ["in_file", "mask_file"]: indict = {input:filelist[0]} willbreak = fs.ApplyMask(**indict) yield assert_raises, ValueError, willbreak.run # Now test a basic command line masker.inputs.in_file = filelist[0] masker.inputs.mask_file = filelist[1] outfile = os.path.join(testdir, "a_masked.nii") yield assert_equal, masker.cmdline, "mri_mask a.nii b.nii %s"%outfile # Now test that optional inputs get formatted properly masker.inputs.mask_thresh = 2 yield assert_equal, masker.cmdline, "mri_mask -T 2.0000 a.nii b.nii %s"%outfile masker.inputs.use_abs = True yield assert_equal, masker.cmdline, "mri_mask -T 2.0000 -abs a.nii b.nii %s"%outfile # Now clean up clean_directory(testdir, origdir) @skipif(no_freesurfer) def test_surfshots(): fotos = fs.SurfaceSnapshots() # Test underlying command yield assert_equal, fotos.cmd, "tksurfer" # Test mandatory args exception yield assert_raises, ValueError, fotos.run # Create testing files files, cwd, oldwd = create_files_in_directory() # Test input settins fotos.inputs.subject_id = "fsaverage" fotos.inputs.hemi = "lh" fotos.inputs.surface = "pial" # Test a basic command line yield assert_equal, fotos.cmdline, "tksurfer fsaverage lh pial -tcl snapshots.tcl" # Test identity schmotos = fs.SurfaceSnapshots(subject_id="mysubject",hemi="rh",surface="white") yield assert_not_equal, fotos, schmotos # Test that the tcl script gets written fotos._write_tcl_script() yield assert_equal, True, os.path.exists("snapshots.tcl") # Test that we can use a different tcl script foo = open("other.tcl", "w").close() fotos.inputs.tcl_script = "other.tcl" yield assert_equal, fotos.cmdline, "tksurfer fsaverage lh pial -tcl other.tcl" # Test that the interface crashes politely if graphics aren't enabled try: hold_display = os.environ["DISPLAY"] del os.environ["DISPLAY"] yield assert_raises, RuntimeError, fotos.run os.environ["DISPLAY"] = hold_display except KeyError: pass # Clean up our mess clean_directory(cwd, oldwd) nipype-0.11.0/nipype/interfaces/freesurfer/utils.py000066400000000000000000001551131257611314500224210ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Interfaces to assorted Freesurfer utility programs. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ __docformat__ = 'restructuredtext' import os import re from nipype.utils.filemanip import fname_presuffix, split_filename from nipype.interfaces.freesurfer.base import FSCommand, FSTraitedSpec from nipype.interfaces.base import TraitedSpec, File, traits, OutputMultiPath, isdefined, CommandLine, CommandLineInputSpec filemap = dict(cor='cor', mgh='mgh', mgz='mgz', minc='mnc', afni='brik', brik='brik', bshort='bshort', spm='img', analyze='img', analyze4d='img', bfloat='bfloat', nifti1='img', nii='nii', niigz='nii.gz') filetypes = ['cor', 'mgh', 'mgz', 'minc', 'analyze', 'analyze4d', 'spm', 'afni', 'brik', 'bshort', 'bfloat', 'sdt', 'outline', 'otl', 'gdf', 'nifti1', 'nii', 'niigz'] class SampleToSurfaceInputSpec(FSTraitedSpec): source_file = File(exists=True, mandatory=True, argstr="--mov %s", desc="volume to sample values from") reference_file = File(exists=True, argstr="--ref %s", desc="reference volume (default is orig.mgz)") hemi = traits.Enum("lh", "rh", mandatory=True, argstr="--hemi %s", desc="target hemisphere") surface = traits.String(argstr="--surf %s", desc="target surface (default is white)") reg_xors = ["reg_file", "reg_header", "mni152reg"] reg_file = File(exists=True, argstr="--reg %s", mandatory=True, xor=reg_xors, desc="source-to-reference registration file") reg_header = traits.Bool(argstr="--regheader %s", requires=["subject_id"], mandatory=True, xor=reg_xors, desc="register based on header geometry") mni152reg = traits.Bool(argstr="--mni152reg", mandatory=True, xor=reg_xors, desc="source volume is in MNI152 space") apply_rot = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr="--rot %.3f %.3f %.3f", desc="rotation angles (in degrees) to apply to reg matrix") apply_trans = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr="--trans %.3f %.3f %.3f", desc="translation (in mm) to apply to reg matrix") override_reg_subj = traits.Bool(argstr="--srcsubject %s", requires=["subject_id"], desc="override the subject in the reg file header") sampling_method = traits.Enum("point", "max", "average", mandatory=True, argstr="%s", xor=["projection_stem"], requires=["sampling_range", "sampling_units"], desc="how to sample -- at a point or at the max or average over a range") sampling_range = traits.Either(traits.Float, traits.Tuple(traits.Float, traits.Float, traits.Float), desc="sampling range - a point or a tuple of (min, max, step)") sampling_units = traits.Enum("mm", "frac", desc="sampling range type -- either 'mm' or 'frac'") projection_stem = traits.String(mandatory=True, xor=["sampling_method"], desc="stem for precomputed linear estimates and volume fractions") smooth_vol = traits.Float(argstr="--fwhm %.3f", desc="smooth input volume (mm fwhm)") smooth_surf = traits.Float(argstr="--surf-fwhm %.3f", desc="smooth output surface (mm fwhm)") interp_method = traits.Enum("nearest", "trilinear", argstr="--interp %s", desc="interpolation method") cortex_mask = traits.Bool(argstr="--cortex", xor=["mask_label"], desc="mask the target surface with hemi.cortex.label") mask_label = File(exists=True, argstr="--mask %s", xor=["cortex_mask"], desc="label file to mask output with") float2int_method = traits.Enum("round", "tkregister", argstr="--float2int %s", desc="method to convert reg matrix values (default is round)") fix_tk_reg = traits.Bool(argstr="--fixtkreg", desc="make reg matrix round-compatible") subject_id = traits.String(desc="subject id") target_subject = traits.String(argstr="--trgsubject %s", desc="sample to surface of different subject than source") surf_reg = traits.Bool(argstr="--surfreg", requires=["target_subject"], desc="use surface registration to target subject") ico_order = traits.Int(argstr="--icoorder %d", requires=["target_subject"], desc="icosahedron order when target_subject is 'ico'") reshape = traits.Bool(argstr="--reshape", xor=["no_reshape"], desc="reshape surface vector to fit in non-mgh format") no_reshape = traits.Bool(argstr="--noreshape", xor=["reshape"], desc="do not reshape surface vector (default)") reshape_slices = traits.Int(argstr="--rf %d", desc="number of 'slices' for reshaping") scale_input = traits.Float(argstr="--scale %.3f", desc="multiple all intensities by scale factor") frame = traits.Int(argstr="--frame %d", desc="save only one frame (0-based)") out_file = File(argstr="--o %s", genfile=True, desc="surface file to write") out_type = traits.Enum(filetypes, argstr="--out_type %s", desc="output file type") hits_file = traits.Either(traits.Bool, File(exists=True), argstr="--srchit %s", desc="save image with number of hits at each voxel") hits_type = traits.Enum(filetypes, argstr="--srchit_type", desc="hits file type") vox_file = traits.Either(traits.Bool, File, argstr="--nvox %s", desc="text file with the number of voxels intersecting the surface") class SampleToSurfaceOutputSpec(TraitedSpec): out_file = File(exists=True, desc="surface file") hits_file = File(exists=True, desc="image with number of hits at each voxel") vox_file = File(exists=True, desc="text file with the number of voxels intersecting the surface") class SampleToSurface(FSCommand): """Sample a volume to the cortical surface using Freesurfer's mri_vol2surf. You must supply a sampling method, range, and units. You can project either a given distance (in mm) or a given fraction of the cortical thickness at that vertex along the surface normal from the target surface, and then set the value of that vertex to be either the value at that point or the average or maximum value found along the projection vector. By default, the surface will be saved as a vector with a length equal to the number of vertices on the target surface. This is not a problem for Freesurfer programs, but if you intend to use the file with interfaces to another package, you must set the ``reshape`` input to True, which will factor the surface vector into a matrix with dimensions compatible with proper Nifti files. Examples -------- >>> import nipype.interfaces.freesurfer as fs >>> sampler = fs.SampleToSurface(hemi="lh") >>> sampler.inputs.source_file = "cope1.nii.gz" >>> sampler.inputs.reg_file = "register.dat" >>> sampler.inputs.sampling_method = "average" >>> sampler.inputs.sampling_range = 1 >>> sampler.inputs.sampling_units = "frac" >>> res = sampler.run() # doctest: +SKIP """ _cmd = "mri_vol2surf" input_spec = SampleToSurfaceInputSpec output_spec = SampleToSurfaceOutputSpec filemap = dict(cor='cor', mgh='mgh', mgz='mgz', minc='mnc', afni='brik', brik='brik', bshort='bshort', spm='img', analyze='img', analyze4d='img', bfloat='bfloat', nifti1='img', nii='nii', niigz='nii.gz') def _format_arg(self, name, spec, value): if name == "sampling_method": range = self.inputs.sampling_range units = self.inputs.sampling_units if units == "mm": units = "dist" if isinstance(range, tuple): range = "%.3f %.3f %.3f" % range else: range = "%.3f" % range method = dict(point="", max="-max", average="-avg")[value] return "--proj%s%s %s" % (units, method, range) if name == "reg_header": return spec.argstr % self.inputs.subject_id if name == "override_reg_subj": return spec.argstr % self.inputs.subject_id if name in ["hits_file", "vox_file"]: return spec.argstr % self._get_outfilename(name) return super(SampleToSurface, self)._format_arg(name, spec, value) def _get_outfilename(self, opt="out_file"): outfile = getattr(self.inputs, opt) if not isdefined(outfile) or isinstance(outfile, bool): if isdefined(self.inputs.out_type): if opt == "hits_file": suffix = '_hits.' + self.filemap[self.inputs.out_type] else: suffix = '.' + self.filemap[self.inputs.out_type] elif opt == "hits_file": suffix = "_hits.mgz" else: suffix = '.mgz' outfile = fname_presuffix(self.inputs.source_file, newpath=os.getcwd(), prefix=self.inputs.hemi + ".", suffix=suffix, use_ext=False) return outfile def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = os.path.abspath(self._get_outfilename()) hitsfile = self.inputs.hits_file if isdefined(hitsfile): outputs["hits_file"] = hitsfile if isinstance(hitsfile, bool): hitsfile = self._get_outfilename("hits_file") voxfile = self.inputs.vox_file if isdefined(voxfile): if isinstance(voxfile, bool): voxfile = fname_presuffix(self.inputs.source_file, newpath=os.getcwd(), prefix=self.inputs.hemi + ".", suffix="_vox.txt", use_ext=False) outputs["vox_file"] = voxfile return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()[name] return None class SurfaceSmoothInputSpec(FSTraitedSpec): in_file = File(mandatory=True, argstr="--sval %s", desc="source surface file") subject_id = traits.String(mandatory=True, argstr="--s %s", desc="subject id of surface file") hemi = traits.Enum("lh", "rh", argstr="--hemi %s", mandatory=True, desc="hemisphere to operate on") fwhm = traits.Float(argstr="--fwhm %.4f", xor=["smooth_iters"], desc="effective FWHM of the smoothing process") smooth_iters = traits.Int(argstr="--smooth %d", xor=["fwhm"], desc="iterations of the smoothing process") cortex = traits.Bool(True, argstr="--cortex", usedefault=True, desc="only smooth within $hemi.cortex.label") reshape = traits.Bool(argstr="--reshape", desc="reshape surface vector to fit in non-mgh format") out_file = File(argstr="--tval %s", genfile=True, desc="surface file to write") class SurfaceSmoothOutputSpec(TraitedSpec): out_file = File(exists=True, desc="smoothed surface file") class SurfaceSmooth(FSCommand): """Smooth a surface image with mri_surf2surf. The surface is smoothed by an interative process of averaging the value at each vertex with those of its adjacent neighbors. You may supply either the number of iterations to run or a desired effective FWHM of the smoothing process. If the latter, the underlying program will calculate the correct number of iterations internally. .. seealso:: SmoothTessellation() Interface For smoothing a tessellated surface (e.g. in gifti or .stl) Examples -------- >>> import nipype.interfaces.freesurfer as fs >>> smoother = fs.SurfaceSmooth() >>> smoother.inputs.in_file = "lh.cope1.mgz" >>> smoother.inputs.subject_id = "subj_1" >>> smoother.inputs.hemi = "lh" >>> smoother.inputs.fwhm = 5 >>> smoother.run() # doctest: +SKIP """ _cmd = "mri_surf2surf" input_spec = SurfaceSmoothInputSpec output_spec = SurfaceSmoothOutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = self.inputs.out_file if not isdefined(outputs["out_file"]): in_file = self.inputs.in_file if isdefined(self.inputs.fwhm): kernel = self.inputs.fwhm else: kernel = self.inputs.smooth_iters outputs["out_file"] = fname_presuffix(in_file, suffix="_smooth%d" % kernel, newpath=os.getcwd()) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()[name] return None class SurfaceTransformInputSpec(FSTraitedSpec): source_file = File(exists=True, mandatory=True, argstr="--sval %s", xor=['source_annot_file'], desc="surface file with source values") source_annot_file = File(exists=True, mandatory=True, argstr="--sval-annot %s", xor=['source_file'], desc="surface annotation file") source_subject = traits.String(mandatory=True, argstr="--srcsubject %s", desc="subject id for source surface") hemi = traits.Enum("lh", "rh", argstr="--hemi %s", mandatory=True, desc="hemisphere to transform") target_subject = traits.String(mandatory=True, argstr="--trgsubject %s", desc="subject id of target surface") target_ico_order = traits.Enum(1, 2, 3, 4, 5, 6, 7, argstr="--trgicoorder %d", desc=("order of the icosahedron if " "target_subject is 'ico'")) source_type = traits.Enum(filetypes, argstr='--sfmt %s', requires=['source_file'], desc="source file format") target_type = traits.Enum(filetypes, argstr='--tfmt %s', desc="output format") reshape = traits.Bool(argstr="--reshape", desc="reshape output surface to conform with Nifti") reshape_factor = traits.Int(argstr="--reshape-factor", desc="number of slices in reshaped image") out_file = File(argstr="--tval %s", genfile=True, desc="surface file to write") class SurfaceTransformOutputSpec(TraitedSpec): out_file = File(exists=True, desc="transformed surface file") class SurfaceTransform(FSCommand): """Transform a surface file from one subject to another via a spherical registration. Both the source and target subject must reside in your Subjects Directory, and they must have been processed with recon-all, unless you are transforming to one of the icosahedron meshes. Examples -------- >>> from nipype.interfaces.freesurfer import SurfaceTransform >>> sxfm = SurfaceTransform() >>> sxfm.inputs.source_file = "lh.cope1.nii.gz" >>> sxfm.inputs.source_subject = "my_subject" >>> sxfm.inputs.target_subject = "fsaverage" >>> sxfm.inputs.hemi = "lh" >>> sxfm.run() # doctest: +SKIP """ _cmd = "mri_surf2surf" input_spec = SurfaceTransformInputSpec output_spec = SurfaceTransformOutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = self.inputs.out_file if not isdefined(outputs["out_file"]): source = self.inputs.source_file # Some recon-all files don't have a proper extension (e.g. "lh.thickness") # so we have to account for that here bad_extensions = [".%s" % e for e in ["area", "mid", "pial", "avg_curv", "curv", "inflated", "jacobian_white", "orig", "nofix", "smoothwm", "crv", "sphere", "sulc", "thickness", "volume", "white"]] use_ext = True if split_filename(source)[2] in bad_extensions: source = source + ".stripme" use_ext = False ext = "" if isdefined(self.inputs.target_type): ext = "." + filemap[self.inputs.target_type] use_ext = False outputs["out_file"] = fname_presuffix(source, suffix=".%s%s" % (self.inputs.target_subject, ext), newpath=os.getcwd(), use_ext=use_ext) else: outputs["out_file"] = os.path.abspath(self.inputs.out_file) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()[name] return None class Surface2VolTransformInputSpec(FSTraitedSpec): source_file = File(exists=True, argstr='--surfval %s', copyfile=False, mandatory=True, desc='This is the source of the surface values') hemi = traits.Str(argstr='--hemi %s', mandatory=True, desc='hemisphere of data') transformed_file = File(name_template="%s_asVol.nii", desc='Output volume', argstr='--outvol %s', name_source=['source_file'], hash_files=False) reg_file = File(exists=True, argstr='--volreg %s', mandatory=True, desc='tkRAS-to-tkRAS matrix (tkregister2 format)', xor=['subject_id']) template_file = File(exists=True, argstr='--template %s', desc='Output template volume') mkmask = traits.Bool(desc='make a mask instead of loading surface values', argstr='--mkmask') vertexvol_file = File(name_template="%s_asVol_vertex.nii", desc=('Path name of the vertex output volume, which ' 'is the same as output volume except that the ' 'value of each voxel is the vertex-id that is ' 'mapped to that voxel.'), argstr='--vtxvol %s', name_source=['source_file'], hash_files=False) surf_name = traits.Str(argstr='--surf %s', desc='surfname (default is white)') projfrac = traits.Float(argstr='--projfrac %s', desc='thickness fraction') subjects_dir = traits.Str(argstr='--sd %s', desc=('freesurfer subjects directory defaults to ' '$SUBJECTS_DIR')) subject_id = traits.Str(argstr='--identity %s',desc='subject id', xor=['reg_file']) class Surface2VolTransformOutputSpec(TraitedSpec): transformed_file = File(exists=True, desc='Path to output file if used normally') vertexvol_file = File(desc='vertex map volume path id. Optional') class Surface2VolTransform(FSCommand): """Use FreeSurfer mri_surf2vol to apply a transform. Examples -------- >>> from nipype.interfaces.freesurfer import Surface2VolTransform >>> xfm2vol = Surface2VolTransform() >>> xfm2vol.inputs.source_file = 'lh.cope1.mgz' >>> xfm2vol.inputs.reg_file = 'register.mat' >>> xfm2vol.inputs.hemi = 'lh' >>> xfm2vol.inputs.template_file = 'cope1.nii.gz' >>> xfm2vol.inputs.subjects_dir = '.' >>> xfm2vol.cmdline 'mri_surf2vol --hemi lh --volreg register.mat --surfval lh.cope1.mgz --sd . --template cope1.nii.gz --outvol lh.cope1_asVol.nii --vtxvol lh.cope1_asVol_vertex.nii' >>> res = xfm2vol.run()# doctest: +SKIP """ _cmd = 'mri_surf2vol' input_spec = Surface2VolTransformInputSpec output_spec = Surface2VolTransformOutputSpec class ApplyMaskInputSpec(FSTraitedSpec): in_file = File(exists=True, mandatory=True, position=-3, argstr="%s", desc="input image (will be masked)") mask_file = File(exists=True, mandatory=True, position=-2, argstr="%s", desc="image defining mask space") out_file = File(genfile=True, position=-1, argstr="%s", desc="final image to write") xfm_file = File(exists=True, argstr="-xform %s", desc="LTA-format transformation matrix to align mask with input") invert_xfm = traits.Bool(argstr="-invert", desc="invert transformation") xfm_source = File(exists=True, argstr="-lta_src %s", desc="image defining transform source space") xfm_target = File(exists=True, argstr="-lta_dst %s", desc="image defining transform target space") use_abs = traits.Bool(argstr="-abs", desc="take absolute value of mask before applying") mask_thresh = traits.Float(argstr="-T %.4f", desc="threshold mask before applying") class ApplyMaskOutputSpec(TraitedSpec): out_file = File(exists=True, desc="masked image") class ApplyMask(FSCommand): """Use Freesurfer's mri_mask to apply a mask to an image. The mask file need not be binarized; it can be thresholded above a given value before application. It can also optionally be transformed into input space with an LTA matrix. """ _cmd = "mri_mask" input_spec = ApplyMaskInputSpec output_spec = ApplyMaskOutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = self.inputs.out_file if not isdefined(outputs["out_file"]): outputs["out_file"] = fname_presuffix(self.inputs.in_file, suffix="_masked", newpath=os.getcwd(), use_ext=True) else: outputs["out_file"] = os.path.abspath(outputs["out_file"]) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()[name] return None class SurfaceSnapshotsInputSpec(FSTraitedSpec): subject_id = traits.String(position=1, argstr="%s", mandatory=True, desc="subject to visualize") hemi = traits.Enum("lh", "rh", position=2, argstr="%s", mandatory=True, desc="hemisphere to visualize") surface = traits.String(position=3, argstr="%s", mandatory=True, desc="surface to visualize") show_curv = traits.Bool(argstr="-curv", desc="show curvature", xor=["show_gray_curv"]) show_gray_curv = traits.Bool(argstr="-gray", desc="show curvature in gray", xor=["show_curv"]) overlay = File(exists=True, argstr="-overlay %s", desc="load an overlay volume/surface", requires=["overlay_range"]) reg_xors = ["overlay_reg", "identity_reg", "mni152_reg"] overlay_reg = traits.File(exists=True, argstr="-overlay-reg %s", xor=reg_xors, desc="registration matrix file to register overlay to surface") identity_reg = traits.Bool(argstr="-overlay-reg-identity", xor=reg_xors, desc="use the identity matrix to register the overlay to the surface") mni152_reg = traits.Bool(argstr="-mni152reg", xor=reg_xors, desc="use to display a volume in MNI152 space on the average subject") overlay_range = traits.Either(traits.Float, traits.Tuple(traits.Float, traits.Float), traits.Tuple(traits.Float, traits.Float, traits.Float), desc="overlay range--either min, (min, max) or (min, mid, max)", argstr="%s") overlay_range_offset = traits.Float(argstr="-foffset %.3f", desc="overlay range will be symettric around offset value") truncate_overlay = traits.Bool(argstr="-truncphaseflag 1", desc="truncate the overlay display") reverse_overlay = traits.Bool(argstr="-revphaseflag 1", desc="reverse the overlay display") invert_overlay = traits.Bool(argstr="-invphaseflag 1", desc="invert the overlay display") demean_overlay = traits.Bool(argstr="-zm", desc="remove mean from overlay") annot_file = File(exists=True, argstr="-annotation %s", xor=["annot_name"], desc="path to annotation file to display") annot_name = traits.String(argstr="-annotation %s", xor=["annot_file"], desc="name of annotation to display (must be in $subject/label directory") label_file = File(exists=True, argstr="-label %s", xor=["label_name"], desc="path to label file to display") label_name = traits.String(argstr="-label %s", xor=["label_file"], desc="name of label to display (must be in $subject/label directory") colortable = File(exists=True, argstr="-colortable %s", desc="load colortable file") label_under = traits.Bool(argstr="-labels-under", desc="draw label/annotation under overlay") label_outline = traits.Bool(argstr="-label-outline", desc="draw label/annotation as outline") patch_file = File(exists=True, argstr="-patch %s", desc="load a patch") orig_suffix = traits.String(argstr="-orig %s", desc="set the orig surface suffix string") sphere_suffix = traits.String(argstr="-sphere %s", desc="set the sphere.reg suffix string") show_color_scale = traits.Bool(argstr="-colscalebarflag 1", desc="display the color scale bar") show_color_text = traits.Bool(argstr="-colscaletext 1", desc="display text in the color scale bar") six_images = traits.Bool(desc="also take anterior and posterior snapshots") screenshot_stem = traits.String(desc="stem to use for screenshot file names") stem_template_args = traits.List(traits.String, requires=["screenshot_stem"], desc="input names to use as arguments for a string-formated stem template") tcl_script = File(exists=True, argstr="%s", genfile=True, desc="override default screenshot script") class SurfaceSnapshotsOutputSpec(TraitedSpec): snapshots = OutputMultiPath(File(exists=True), desc="tiff images of the surface from different perspectives") class SurfaceSnapshots(FSCommand): """Use Tksurfer to save pictures of the cortical surface. By default, this takes snapshots of the lateral, medial, ventral, and dorsal surfaces. See the ``six_images`` option to add the anterior and posterior surfaces. You may also supply your own tcl script (see the Freesurfer wiki for information on scripting tksurfer). The screenshot stem is set as the environment variable "_SNAPSHOT_STEM", which you can use in your own scripts. Node that this interface will not run if you do not have graphics enabled on your system. Examples -------- >>> import nipype.interfaces.freesurfer as fs >>> shots = fs.SurfaceSnapshots(subject_id="fsaverage", hemi="lh", surface="pial") >>> shots.inputs.overlay = "zstat1.nii.gz" >>> shots.inputs.overlay_range = (2.3, 6) >>> shots.inputs.overlay_reg = "register.dat" >>> res = shots.run() # doctest: +SKIP """ _cmd = "tksurfer" input_spec = SurfaceSnapshotsInputSpec output_spec = SurfaceSnapshotsOutputSpec def _format_arg(self, name, spec, value): if name == "tcl_script": if not isdefined(value): return "-tcl snapshots.tcl" else: return "-tcl %s" % value elif name == "overlay_range": if isinstance(value, float): return "-fthresh %.3f" % value else: if len(value) == 2: return "-fminmax %.3f %.3f" % value else: return "-fminmax %.3f %.3f -fmid %.3f" % (value[0], value[2], value[1]) elif name == "annot_name" and isdefined(value): # Matching annot by name needs to strip the leading hemi and trailing # extension strings if value.endswith(".annot"): value = value[:-6] if re.match("%s[\.\-_]" % self.inputs.hemi, value[:3]): value = value[3:] return "-annotation %s" % value return super(SurfaceSnapshots, self)._format_arg(name, spec, value) def _run_interface(self, runtime): if not isdefined(self.inputs.screenshot_stem): stem = "%s_%s_%s" % ( self.inputs.subject_id, self.inputs.hemi, self.inputs.surface) else: stem = self.inputs.screenshot_stem stem_args = self.inputs.stem_template_args if isdefined(stem_args): args = tuple([getattr(self.inputs, arg) for arg in stem_args]) stem = stem % args # Check if the DISPLAY variable is set -- should avoid crashes (might not?) if not "DISPLAY" in os.environ: raise RuntimeError("Graphics are not enabled -- cannot run tksurfer") runtime.environ["_SNAPSHOT_STEM"] = stem self._write_tcl_script() runtime = super(SurfaceSnapshots, self)._run_interface(runtime) # If a display window can't be opened, this will crash on # aggregate_outputs. Let's try to parse stderr and raise a # better exception here if that happened. errors = ["surfer: failed, no suitable display found", "Fatal Error in tksurfer.bin: could not open display"] for err in errors: if err in runtime.stderr: self.raise_exception(runtime) # Tksurfer always (or at least always when you run a tcl script) # exits with a nonzero returncode. We have to force it to 0 here. runtime.returncode = 0 return runtime def _write_tcl_script(self): fid = open("snapshots.tcl", "w") script = ["save_tiff $env(_SNAPSHOT_STEM)-lat.tif", "make_lateral_view", "rotate_brain_y 180", "redraw", "save_tiff $env(_SNAPSHOT_STEM)-med.tif", "make_lateral_view", "rotate_brain_x 90", "redraw", "save_tiff $env(_SNAPSHOT_STEM)-ven.tif", "make_lateral_view", "rotate_brain_x -90", "redraw", "save_tiff $env(_SNAPSHOT_STEM)-dor.tif"] if isdefined(self.inputs.six_images) and self.inputs.six_images: script.extend(["make_lateral_view", "rotate_brain_y 90", "redraw", "save_tiff $env(_SNAPSHOT_STEM)-pos.tif", "make_lateral_view", "rotate_brain_y -90", "redraw", "save_tiff $env(_SNAPSHOT_STEM)-ant.tif"]) script.append("exit") fid.write("\n".join(script)) fid.close() def _list_outputs(self): outputs = self._outputs().get() if not isdefined(self.inputs.screenshot_stem): stem = "%s_%s_%s" % (self.inputs.subject_id, self.inputs.hemi, self.inputs.surface) else: stem = self.inputs.screenshot_stem stem_args = self.inputs.stem_template_args if isdefined(stem_args): args = tuple([getattr(self.inputs, arg) for arg in stem_args]) stem = stem % args snapshots = ["%s-lat.tif", "%s-med.tif", "%s-dor.tif", "%s-ven.tif"] if self.inputs.six_images: snapshots.extend(["%s-pos.tif", "%s-ant.tif"]) snapshots = [self._gen_fname(f % stem, suffix="") for f in snapshots] outputs["snapshots"] = snapshots return outputs def _gen_filename(self, name): if name == "tcl_script": return "snapshots.tcl" return None class ImageInfoInputSpec(FSTraitedSpec): in_file = File(exists=True, position=1, argstr="%s", desc="image to query") class ImageInfoOutputSpec(TraitedSpec): info = traits.Any(desc="output of mri_info") out_file = File(exists=True, desc="text file with image information") data_type = traits.String(desc="image data type") file_format = traits.String(desc="file format") TE = traits.String(desc="echo time (msec)") TR = traits.String(desc="repetition time(msec)") TI = traits.String(desc="inversion time (msec)") dimensions = traits.Tuple(desc="image dimensions (voxels)") vox_sizes = traits.Tuple(desc="voxel sizes (mm)") orientation = traits.String(desc="image orientation") ph_enc_dir = traits.String(desc="phase encode direction") class ImageInfo(FSCommand): _cmd = "mri_info" input_spec = ImageInfoInputSpec output_spec = ImageInfoOutputSpec def info_regexp(self, info, field, delim="\n"): m = re.search("%s\s*:\s+(.+?)%s" % (field, delim), info) if m: return m.group(1) else: return None def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() info = runtime.stdout outputs.info = info # Pulse sequence parameters for field in ["TE", "TR", "TI"]: fieldval = self.info_regexp(info, field, ", ") if fieldval.endswith(" msec"): fieldval = fieldval[:-5] setattr(outputs, field, fieldval) # Voxel info vox = self.info_regexp(info, "voxel sizes") vox = tuple(vox.split(", ")) outputs.vox_sizes = vox dim = self.info_regexp(info, "dimensions") dim = tuple([int(d) for d in dim.split(" x ")]) outputs.dimensions = dim outputs.orientation = self.info_regexp(info, "Orientation") outputs.ph_enc_dir = self.info_regexp(info, "PhEncDir") # File format and datatype are both keyed by "type" ftype, dtype = re.findall("%s\s*:\s+(.+?)\n" % "type", info) outputs.file_format = ftype outputs.data_type = dtype return outputs class MRIsConvertInputSpec(FSTraitedSpec): """ Uses Freesurfer's mris_convert to convert surface files to various formats """ annot_file = File(exists=True, argstr="--annot %s", desc="input is annotation or gifti label data") parcstats_file = File(exists=True, argstr="--parcstats %s", desc="infile is name of text file containing label/val pairs") label_file = File(exists=True, argstr="--label %s", desc="infile is .label file, label is name of this label") scalarcurv_file = File(exists=True, argstr="-c %s", desc="input is scalar curv overlay file (must still specify surface)") functional_file = File(exists=True, argstr="-f %s", desc="input is functional time-series or other multi-frame data (must specify surface)") labelstats_outfile = File(exists=False, argstr="--labelstats %s", desc="outfile is name of gifti file to which label stats will be written") patch = traits.Bool(argstr="-p", desc="input is a patch, not a full surface") rescale = traits.Bool(argstr="-r", desc="rescale vertex xyz so total area is same as group average") normal = traits.Bool(argstr="-n", desc="output is an ascii file where vertex data") xyz_ascii = traits.Bool(argstr="-a", desc="Print only surface xyz to ascii file") vertex = traits.Bool(argstr="-v", desc="Writes out neighbors of a vertex in each row") scale = traits.Float(argstr="-s %.3f", desc="scale vertex xyz by scale") dataarray_num = traits.Int(argstr="--da_num %d", desc="if input is gifti, 'num' specifies which data array to use") talairachxfm_subjid = traits.String(argstr="-t %s", desc="apply talairach xfm of subject to vertex xyz") origname = traits.String(argstr="-o %s", desc="read orig positions") in_file = File(exists=True, mandatory=True, position=-2, argstr='%s', desc='File to read/convert') out_file = File(argstr='./%s', position=-1, genfile=True, desc='output filename or True to generate one') #Not really sure why the ./ is necessary but the module fails without it out_datatype = traits.Enum("ico", "tri", "stl", "vtk", "gii", "mgh", "mgz", mandatory=True, desc="These file formats are supported: ASCII: .asc" \ "ICO: .ico, .tri GEO: .geo STL: .stl VTK: .vtk GIFTI: .gii MGH surface-encoded 'volume': .mgh, .mgz") class MRIsConvertOutputSpec(TraitedSpec): """ Uses Freesurfer's mris_convert to convert surface files to various formats """ converted = File(exists=True, desc='converted output surface') class MRIsConvert(FSCommand): """ Uses Freesurfer's mris_convert to convert surface files to various formats Example ------- >>> import nipype.interfaces.freesurfer as fs >>> mris = fs.MRIsConvert() >>> mris.inputs.in_file = 'lh.pial' >>> mris.inputs.out_datatype = 'gii' >>> mris.run() # doctest: +SKIP """ _cmd = 'mris_convert' input_spec = MRIsConvertInputSpec output_spec = MRIsConvertOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["converted"] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): if isdefined(self.inputs.annot_file): _, name, ext = split_filename(self.inputs.annot_file) elif isdefined(self.inputs.parcstats_file): _, name, ext = split_filename(self.inputs.parcstats_file) elif isdefined(self.inputs.label_file): _, name, ext = split_filename(self.inputs.label_file) elif isdefined(self.inputs.scalarcurv_file): _, name, ext = split_filename(self.inputs.scalarcurv_file) elif isdefined(self.inputs.functional_file): _, name, ext = split_filename(self.inputs.functional_file) elif isdefined(self.inputs.in_file): _, name, ext = split_filename(self.inputs.in_file) return name + ext + "_converted." + self.inputs.out_datatype class MRITessellateInputSpec(FSTraitedSpec): """ Uses Freesurfer's mri_tessellate to create surfaces by tessellating a given input volume """ in_file = File(exists=True, mandatory=True, position=-3, argstr='%s', desc='Input volume to tesselate voxels from.') label_value = traits.Int(position=-2, argstr='%d', mandatory=True, desc='Label value which to tesselate from the input volume. (integer, if input is "filled.mgz" volume, 127 is rh, 255 is lh)') out_file = File(argstr='./%s', position=-1, genfile=True, desc='output filename or True to generate one') tesselate_all_voxels = traits.Bool(argstr='-a', desc='Tessellate the surface of all voxels with different labels') use_real_RAS_coordinates = traits.Bool(argstr='-n', desc='Saves surface with real RAS coordinates where c_(r,a,s) != 0') class MRITessellateOutputSpec(TraitedSpec): """ Uses Freesurfer's mri_tessellate to create surfaces by tessellating a given input volume """ surface = File(exists=True, desc='binary surface of the tessellation ') class MRITessellate(FSCommand): """ Uses Freesurfer's mri_tessellate to create surfaces by tessellating a given input volume Example ------- >>> import nipype.interfaces.freesurfer as fs >>> tess = fs.MRITessellate() >>> tess.inputs.in_file = 'aseg.mgz' >>> tess.inputs.label_value = 17 >>> tess.inputs.out_file = 'lh.hippocampus' >>> tess.run() # doctest: +SKIP """ _cmd = 'mri_tessellate' input_spec = MRITessellateInputSpec output_spec = MRITessellateOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['surface'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): if isdefined(self.inputs.out_file): return self.inputs.out_file else: _, name, ext = split_filename(self.inputs.in_file) return name + ext + '_' + str(self.inputs.label_value) class MRIPretessInputSpec(FSTraitedSpec): in_filled = File(exists=True, mandatory=True, position=-4, argstr='%s', desc=('filled volume, usually wm.mgz')) label = traits.Either(traits.Str('wm'), traits.Int(1), argstr='%s', default='wm', mandatory=True, usedefault=True, position=-3, desc=('label to be picked up, can be a Freesurfer\'s string like ' '\'wm\' or a label value (e.g. 127 for rh or 255 for lh)')) in_norm = File(exists=True, mandatory=True, position=-2, argstr='%s', desc=('the normalized, brain-extracted T1w image. Usually norm.mgz')) out_file = File(position=-1, argstr='%s', genfile=True, desc=('the output file after mri_pretess.')) nocorners = traits.Bool(False, argstr='-nocorners', desc=('do not remove corner configurations' ' in addition to edge ones.')) keep = traits.Bool(False, argstr='-keep', desc=('keep WM edits')) test = traits.Bool(False, argstr='-test', desc=('adds a voxel that should be removed by ' 'mri_pretess. The value of the voxel is set to that of an ON-edited WM, ' 'so it should be kept with -keep. The output will NOT be saved.')) class MRIPretessOutputSpec(TraitedSpec): out_file = File(exists=True, desc='output file after mri_pretess') class MRIPretess(FSCommand): """ Uses Freesurfer's mri_pretess to prepare volumes to be tessellated. Description ----------- Changes white matter (WM) segmentation so that the neighbors of all voxels labeled as WM have a face in common - no edges or corners allowed. Example ------- >>> import nipype.interfaces.freesurfer as fs >>> pretess = fs.MRIPretess() >>> pretess.inputs.in_filled = 'wm.mgz' >>> pretess.inputs.in_norm = 'norm.mgz' >>> pretess.inputs.nocorners = True >>> pretess.cmdline 'mri_pretess -nocorners wm.mgz wm norm.mgz wm_pretesswm.mgz' >>> pretess.run() # doctest: +SKIP """ _cmd = 'mri_pretess' input_spec = MRIPretessInputSpec output_spec = MRIPretessOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): if isdefined(self.inputs.out_file): return self.inputs.out_file else: _, name, ext = split_filename(self.inputs.in_filled) return name + '_pretess' + str(self.inputs.label) + ext class MRIMarchingCubesInputSpec(FSTraitedSpec): """ Uses Freesurfer's mri_mc to create surfaces by tessellating a given input volume """ in_file = File(exists=True, mandatory=True, position=1, argstr='%s', desc='Input volume to tesselate voxels from.') label_value = traits.Int(position=2, argstr='%d', mandatory=True, desc='Label value which to tesselate from the input volume. (integer, if input is "filled.mgz" volume, 127 is rh, 255 is lh)') connectivity_value = traits.Int(1, position=-1, argstr='%d', usedefault=True, desc='Alter the marching cubes connectivity: 1=6+,2=18,3=6,4=26 (default=1)') out_file = File(argstr='./%s', position=-2, genfile=True, desc='output filename or True to generate one') class MRIMarchingCubesOutputSpec(TraitedSpec): """ Uses Freesurfer's mri_mc to create surfaces by tessellating a given input volume """ surface = File(exists=True, desc='binary surface of the tessellation ') class MRIMarchingCubes(FSCommand): """ Uses Freesurfer's mri_mc to create surfaces by tessellating a given input volume Example ------- >>> import nipype.interfaces.freesurfer as fs >>> mc = fs.MRIMarchingCubes() >>> mc.inputs.in_file = 'aseg.mgz' >>> mc.inputs.label_value = 17 >>> mc.inputs.out_file = 'lh.hippocampus' >>> mc.run() # doctest: +SKIP """ _cmd = 'mri_mc' input_spec = MRIMarchingCubesInputSpec output_spec = MRIMarchingCubesOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['surface'] = self._gen_outfilename() return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): if isdefined(self.inputs.out_file): return os.path.abspath(self.inputs.out_file) else: _, name, ext = split_filename(self.inputs.in_file) return os.path.abspath(name + ext + '_' + str(self.inputs.label_value)) class SmoothTessellationInputSpec(FSTraitedSpec): """ This program smooths the tessellation of a surface using 'mris_smooth' """ in_file = File(exists=True, mandatory=True, argstr='%s', position=1, desc='Input volume to tesselate voxels from.') curvature_averaging_iterations = traits.Int(10, usedefault=True, argstr='-a %d', position=-1, desc='Number of curvature averaging iterations (default=10)') smoothing_iterations = traits.Int(10, usedefault=True, argstr='-n %d', position=-2, desc='Number of smoothing iterations (default=10)') snapshot_writing_iterations = traits.Int(argstr='-w %d', desc='Write snapshot every "n" iterations') use_gaussian_curvature_smoothing = traits.Bool(argstr='-g', position=3, desc='Use Gaussian curvature smoothing') gaussian_curvature_norm_steps = traits.Int(argstr='%d ', position=4, desc='Use Gaussian curvature smoothing') gaussian_curvature_smoothing_steps = traits.Int(argstr='%d', position=5, desc='Use Gaussian curvature smoothing') disable_estimates = traits.Bool(argstr='-nw', desc='Disables the writing of curvature and area estimates') normalize_area = traits.Bool(argstr='-area', desc='Normalizes the area after smoothing') use_momentum = traits.Bool(argstr='-m', desc='Uses momentum') out_file = File(argstr='%s', position=2, genfile=True, desc='output filename or True to generate one') out_curvature_file = File(argstr='-c %s', desc='Write curvature to ?h.curvname (default "curv")') out_area_file = File(argstr='-b %s', desc='Write area to ?h.areaname (default "area")') class SmoothTessellationOutputSpec(TraitedSpec): """ This program smooths the tessellation of a surface using 'mris_smooth' """ surface = File(exists=True, desc='Smoothed surface file ') class SmoothTessellation(FSCommand): """ This program smooths the tessellation of a surface using 'mris_smooth' .. seealso:: SurfaceSmooth() Interface For smoothing a scalar field along a surface manifold Example ------- >>> import nipype.interfaces.freesurfer as fs >>> smooth = fs.SmoothTessellation() >>> smooth.inputs.in_file = 'lh.hippocampus.stl' >>> smooth.run() # doctest: +SKIP """ _cmd = 'mris_smooth' input_spec = SmoothTessellationInputSpec output_spec = SmoothTessellationOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['surface'] = self._gen_outfilename() return outputs def _gen_filename(self, name): if name is 'out_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): if isdefined(self.inputs.out_file): return os.path.abspath(self.inputs.out_file) else: _, name, ext = split_filename(self.inputs.in_file) return os.path.abspath(name + '_smoothed' + ext) def _run_interface(self, runtime): # The returncode is meaningless in BET. So check the output # in stderr and if it's set, then update the returncode # accordingly. runtime = super(SmoothTessellation, self)._run_interface(runtime) if "failed" in runtime.stderr: self.raise_exception(runtime) return runtime class MakeAverageSubjectInputSpec(FSTraitedSpec): subjects_ids = traits.List(traits.Str(), argstr='--subjects %s', desc='freesurfer subjects ids to average', mandatory=True, sep=' ') out_name = File('average', argstr='--out %s', desc='name for the average subject', usedefault=True) class MakeAverageSubjectOutputSpec(TraitedSpec): average_subject_name = traits.Str(desc='Output registration file') class MakeAverageSubject(FSCommand): """Make an average freesurfer subject Examples -------- >>> from nipype.interfaces.freesurfer import MakeAverageSubject >>> avg = MakeAverageSubject(subjects_ids=['s1', 's2']) >>> avg.cmdline 'make_average_subject --out average --subjects s1 s2' """ _cmd = 'make_average_subject' input_spec = MakeAverageSubjectInputSpec output_spec = MakeAverageSubjectOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['average_subject_name'] = self.inputs.out_name return outputs class ExtractMainComponentInputSpec(CommandLineInputSpec): in_file = File(exists=True, mandatory=True, argstr='%s', position=1, desc='input surface file') out_file = File(name_template='%s.maincmp', name_source='in_file', argstr='%s', position=2, desc='surface containing main component') class ExtractMainComponentOutputSpec(TraitedSpec): out_file = File(exists=True, desc='surface containing main component') class ExtractMainComponent(CommandLine): """Extract the main component of a tesselated surface Examples -------- >>> from nipype.interfaces.freesurfer import ExtractMainComponent >>> mcmp = ExtractMainComponent(in_file='lh.pial') >>> mcmp.cmdline 'mris_extract_main_component lh.pial lh.maincmp' """ _cmd='mris_extract_main_component' input_spec=ExtractMainComponentInputSpec output_spec=ExtractMainComponentOutputSpec class Tkregister2InputSpec(FSTraitedSpec): target_image = File(exists=True, argstr="--targ %s", xor=['fstarg'], desc='target volume') fstarg = traits.Bool(False, argstr='--fstarg', xor=['target_image'], desc='use subject\'s T1 as reference') moving_image = File(exists=True, mandatory=True, argstr="--mov %s", desc='moving volume') fsl_in_matrix = File(exists=True, argstr="--fsl %s", desc='fsl-style registration input matrix') subject_id = traits.String(argstr="--s %s", desc='freesurfer subject ID') noedit = traits.Bool(True, argstr="--noedit", usedefault=True, desc='do not open edit window (exit)') reg_file = File('register.dat', usedefault=True, mandatory=True, argstr='--reg %s', desc='freesurfer-style registration file') reg_header = traits.Bool(False, argstr='--regheader', desc='compute regstration from headers') fstal = traits.Bool(False, argstr='--fstal', xor=['target_image', 'moving_image'], desc='set mov to be tal and reg to be tal xfm') movscale = traits.Float(argstr='--movscale %f', desc='adjust registration matrix to scale mov') xfm = File(exists=True, argstr='--xfm %s', desc='use a matrix in MNI coordinates as initial registration') fsl_out = File(argstr='--fslregout %s', desc='compute an FSL-compatible resgitration matrix') class Tkregister2OutputSpec(TraitedSpec): reg_file = File(exists=True, desc='freesurfer-style registration file') fsl_file = File(desc='FSL-style registration file') class Tkregister2(FSCommand): """ Examples -------- Get transform matrix between orig (*tkRAS*) and native (*scannerRAS*) coordinates in Freesurfer. Implements the first step of mapping surfaces to native space in `this guide `_. >>> from nipype.interfaces.freesurfer import Tkregister2 >>> tk2 = Tkregister2(reg_file='T1_to_native.dat') >>> tk2.inputs.moving_image = 'T1.mgz' >>> tk2.inputs.target_image = 'structural.nii' >>> tk2.inputs.reg_header = True >>> tk2.cmdline 'tkregister2 --mov T1.mgz --noedit --reg T1_to_native.dat --regheader \ --targ structural.nii' >>> tk2.run() # doctest: +SKIP The example below uses tkregister2 without the manual editing stage to convert FSL-style registration matrix (.mat) to FreeSurfer-style registration matrix (.dat) >>> from nipype.interfaces.freesurfer import Tkregister2 >>> tk2 = Tkregister2() >>> tk2.inputs.moving_image = 'epi.nii' >>> tk2.inputs.fsl_in_matrix = 'flirt.mat' >>> tk2.cmdline 'tkregister2 --fsl flirt.mat --mov epi.nii --noedit --reg register.dat' >>> tk2.run() # doctest: +SKIP """ _cmd = "tkregister2" input_spec = Tkregister2InputSpec output_spec = Tkregister2OutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs['reg_file'] = os.path.abspath(self.inputs.reg_file) if isdefined(self.inputs.fsl_out): outputs['fsl_file'] = os.path.abspath(self.inputs.fsl_out) return outputs def _gen_outfilename(self): if isdefined(self.inputs.out_file): return os.path.abspath(self.inputs.out_file) else: _, name, ext = split_filename(self.inputs.in_file) return os.path.abspath(name + '_smoothed' + ext)nipype-0.11.0/nipype/interfaces/fsl/000077500000000000000000000000001257611314500173155ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/fsl/__init__.py000066400000000000000000000033401257611314500214260ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. Top-level namespace for fsl. """ from .base import (FSLCommand, Info, check_fsl, no_fsl, no_fsl_course_data) from .preprocess import (FAST, FLIRT, ApplyXfm, BET, MCFLIRT, FNIRT, ApplyWarp, SliceTimer, SUSAN, PRELUDE, FUGUE, FIRST) from .model import (Level1Design, FEAT, FEATModel, FILMGLS, FEATRegister, FLAMEO, ContrastMgr, MultipleRegressDesign, L2Model, SMM, MELODIC, SmoothEstimate, Cluster, Randomise, GLM) from .utils import (Smooth, Merge, ExtractROI, Split, ImageMaths, ImageMeants, ImageStats, FilterRegressor, Overlay, Slicer, PlotTimeSeries, PlotMotionParams, ConvertXFM, SwapDimensions, PowerSpectrum, Reorient2Std, Complex, InvWarp, WarpUtils, ConvertWarp, WarpPoints, WarpPointsToStd, RobustFOV, CopyGeom, MotionOutliers) from .epi import (PrepareFieldmap, TOPUP, ApplyTOPUP, Eddy, EPIDeWarp, SigLoss, EddyCorrect, EpiReg) from .dti import (BEDPOSTX, XFibres, DTIFit, ProbTrackX, ProbTrackX2, VecReg, ProjThresh, FindTheBiggest, DistanceMap, TractSkeleton, MakeDyadicVectors, BEDPOSTX5, XFibres5, BEDPOSTX4, XFibres4) from .maths import (ChangeDataType, Threshold, MeanImage, ApplyMask, IsotropicSmooth, TemporalFilter, DilateImage, ErodeImage, SpatialFilter, UnaryMaths, BinaryMaths, MultiImageMaths) nipype-0.11.0/nipype/interfaces/fsl/base.py000066400000000000000000000172531257611314500206110ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 4.1.4. These are the base tools for working with FSL. Preprocessing tools are found in fsl/preprocess.py Model tools are found in fsl/model.py DTI tools are found in fsl/dti.py XXX Make this doc current! Currently these tools are supported: * BET v2.1: brain extraction * FAST v4.1: segmentation and bias correction * FLIRT v5.5: linear registration * MCFLIRT: motion correction * FNIRT v1.0: non-linear warp Examples -------- See the docstrings of the individual classes for examples. """ from glob import glob import os import warnings from ...utils.filemanip import fname_presuffix, split_filename, copyfile from ..base import (traits, isdefined, CommandLine, CommandLineInputSpec, TraitedSpec, File, Directory, InputMultiPath, OutputMultiPath) warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class Info(object): """Handle fsl output type and version information. version refers to the version of fsl on the system output type refers to the type of file fsl defaults to writing eg, NIFTI, NIFTI_GZ """ ftypes = {'NIFTI': '.nii', 'NIFTI_PAIR': '.img', 'NIFTI_GZ': '.nii.gz', 'NIFTI_PAIR_GZ': '.img.gz'} @staticmethod def version(): """Check for fsl version on system Parameters ---------- None Returns ------- version : str Version number as string or None if FSL not found """ # find which fsl being used....and get version from # /path/to/fsl/etc/fslversion try: basedir = os.environ['FSLDIR'] except KeyError: return None out = open('%s/etc/fslversion' % (basedir)).read() return out.strip('\n') @classmethod def output_type_to_ext(cls, output_type): """Get the file extension for the given output type. Parameters ---------- output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} String specifying the output type. Returns ------- extension : str The file extension for the output type. """ try: return cls.ftypes[output_type] except KeyError: msg = 'Invalid FSLOUTPUTTYPE: ', output_type raise KeyError(msg) @classmethod def output_type(cls): """Get the global FSL output file type FSLOUTPUTTYPE. This returns the value of the environment variable FSLOUTPUTTYPE. An exception is raised if it is not defined. Returns ------- fsl_ftype : string Represents the current environment setting of FSLOUTPUTTYPE """ try: return os.environ['FSLOUTPUTTYPE'] except KeyError: warnings.warn(('FSL environment variables not set. setting output ' 'type to NIFTI')) return 'NIFTI' @staticmethod def standard_image(img_name=None): '''Grab an image from the standard location. Returns a list of standard images if called without arguments. Could be made more fancy to allow for more relocatability''' try: fsldir = os.environ['FSLDIR'] except KeyError: raise Exception('FSL environment variables not set') stdpath = os.path.join(fsldir, 'data', 'standard') if img_name is None: return [filename.replace(stdpath + '/', '') for filename in glob(os.path.join(stdpath, '*nii*'))] return os.path.join(stdpath, img_name) class FSLCommandInputSpec(CommandLineInputSpec): """ Base Input Specification for all FSL Commands All command support specifying FSLOUTPUTTYPE dynamically via output_type. Example ------- fsl.ExtractRoi(tmin=42, tsize=1, output_type='NIFTI') """ output_type = traits.Enum('NIFTI', Info.ftypes.keys(), desc='FSL output type') class FSLCommand(CommandLine): """Base support for FSL commands. """ input_spec = FSLCommandInputSpec _output_type = None def __init__(self, **inputs): super(FSLCommand, self).__init__(**inputs) self.inputs.on_trait_change(self._output_update, 'output_type') if self._output_type is None: self._output_type = Info.output_type() if not isdefined(self.inputs.output_type): self.inputs.output_type = self._output_type else: self._output_update() def _output_update(self): self._output_type = self.inputs.output_type self.inputs.environ.update({'FSLOUTPUTTYPE': self.inputs.output_type}) @classmethod def set_default_output_type(cls, output_type): """Set the default output type for FSL classes. This method is used to set the default output type for all fSL subclasses. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.output_type. """ if output_type in Info.ftypes: cls._output_type = output_type else: raise AttributeError('Invalid FSL output_type: %s' % output_type) @property def version(self): return Info.version() def _gen_fname(self, basename, cwd=None, suffix=None, change_ext=True, ext=None): """Generate a filename based on the given parameters. The filename will take the form: cwd/basename. If change_ext is True, it will use the extentions specified in intputs.output_type. Parameters ---------- basename : str Filename to base the new filename on. cwd : str Path to prefix to the new filename. (default is os.getcwd()) suffix : str Suffix to add to the `basename`. (defaults is '' ) change_ext : bool Flag to change the filename extension to the FSL output type. (default True) Returns ------- fname : str New filename based on given parameters. """ if basename == '': msg = 'Unable to generate filename for command %s. ' % self.cmd msg += 'basename is not set!' raise ValueError(msg) if cwd is None: cwd = os.getcwd() if ext is None: ext = Info.output_type_to_ext(self.inputs.output_type) if change_ext: if suffix: suffix = ''.join((suffix, ext)) else: suffix = ext if suffix is None: suffix = '' fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) return fname def _overload_extension(self, value, name=None): return value + Info.output_type_to_ext(self.inputs.output_type) def check_fsl(): ver = Info.version() if ver: return 0 else: return 1 def no_fsl(): """Checks if FSL is NOT installed used with skipif to skip tests that will fail if FSL is not installed""" if Info.version() is None: return True else: return False def no_fsl_course_data(): """check if fsl_course data is present""" return not ('FSL_COURSE_DATA' in os.environ and os.path.isdir(os.path.abspath(os.environ['FSL_COURSE_DATA']))) nipype-0.11.0/nipype/interfaces/fsl/dti.py000066400000000000000000001770231257611314500204610ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 4.1.4. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os import shutil import warnings from ... import LooseVersion from nipype.interfaces.fsl.base import (FSLCommand, FSLCommandInputSpec, Info) from nipype.interfaces.base import (TraitedSpec, isdefined, File, Directory, InputMultiPath, OutputMultiPath, traits) from nipype.utils.filemanip import fname_presuffix, split_filename, copyfile warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class DTIFitInputSpec(FSLCommandInputSpec): dwi = File(exists=True, desc='diffusion weighted image data file', argstr='-k %s', position=0, mandatory=True) base_name = traits.Str("dtifit_", desc='base_name that all output files will start with', argstr='-o %s', position=1, usedefault=True) mask = File(exists=True, desc='bet binary mask file', argstr='-m %s', position=2, mandatory=True) bvecs = File(exists=True, desc='b vectors file', argstr='-r %s', position=3, mandatory=True) bvals = File(exists=True, desc='b values file', argstr='-b %s', position=4, mandatory=True) min_z = traits.Int(argstr='-z %d', desc='min z') max_z = traits.Int(argstr='-Z %d', desc='max z') min_y = traits.Int(argstr='-y %d', desc='min y') max_y = traits.Int(argstr='-Y %d', desc='max y') min_x = traits.Int(argstr='-x %d', desc='min x') max_x = traits.Int(argstr='-X %d', desc='max x') save_tensor = traits.Bool(desc='save the elements of the tensor', argstr='--save_tensor') sse = traits.Bool(desc='output sum of squared errors', argstr='--sse') cni = File(exists=True, desc='input counfound regressors', argstr='--cni=%s') little_bit = traits.Bool(desc='only process small area of brain', argstr='--littlebit') gradnonlin = File(exists=True, argstr='--gradnonlin=%s', desc='gradient non linearities') class DTIFitOutputSpec(TraitedSpec): V1 = File(exists=True, desc='path/name of file with the 1st eigenvector') V2 = File(exists=True, desc='path/name of file with the 2nd eigenvector') V3 = File(exists=True, desc='path/name of file with the 3rd eigenvector') L1 = File(exists=True, desc='path/name of file with the 1st eigenvalue') L2 = File(exists=True, desc='path/name of file with the 2nd eigenvalue') L3 = File(exists=True, desc='path/name of file with the 3rd eigenvalue') MD = File(exists=True, desc='path/name of file with the mean diffusivity') FA = File(exists=True, desc='path/name of file with the fractional anisotropy') MO = File(exists=True, desc='path/name of file with the mode of anisotropy') S0 = File(exists=True, desc='path/name of file with the raw T2 signal with no ' + 'diffusion weighting') tensor = File(exists=True, desc='path/name of file with the 4D tensor volume') class DTIFit(FSLCommand): """ Use FSL dtifit command for fitting a diffusion tensor model at each voxel Example ------- >>> from nipype.interfaces import fsl >>> dti = fsl.DTIFit() >>> dti.inputs.dwi = 'diffusion.nii' >>> dti.inputs.bvecs = 'bvecs' >>> dti.inputs.bvals = 'bvals' >>> dti.inputs.base_name = 'TP' >>> dti.inputs.mask = 'mask.nii' >>> dti.cmdline 'dtifit -k diffusion.nii -o TP -m mask.nii -r bvecs -b bvals' """ _cmd = 'dtifit' input_spec = DTIFitInputSpec output_spec = DTIFitOutputSpec def _list_outputs(self): outputs = self.output_spec().get() for k in outputs.keys(): if k not in ('outputtype', 'environ', 'args'): if k != 'tensor' or (isdefined(self.inputs.save_tensor) and self.inputs.save_tensor): outputs[k] = self._gen_fname(self.inputs.base_name, suffix='_' + k) return outputs class FSLXCommandInputSpec(FSLCommandInputSpec): dwi = File(exists=True, argstr='--data=%s', mandatory=True, desc='diffusion weighted image data file') mask = File(exists=True, argstr='--mask=%s', mandatory=True, desc='brain binary mask file (i.e. from BET)') bvecs = File(exists=True, argstr='--bvecs=%s', mandatory=True, desc='b vectors file') bvals = File(exists=True, argstr='--bvals=%s', mandatory=True, desc='b values file') logdir = Directory('.', argstr='--logdir=%s', usedefault=True) n_fibres = traits.Range( usedefault=True, low=1, default=2, argstr='--nfibres=%d', desc=('Maximum number of fibres to fit in each voxel'), mandatory=True) model = traits.Enum(1, 2, argstr='--model=%d', desc=('use monoexponential (1, default, required for ' 'single-shell) or multiexponential (2, multi-' 'shell) model')) fudge = traits.Int(argstr='--fudge=%d', desc='ARD fudge factor') n_jumps = traits.Int(5000, argstr='--njumps=%d', desc='Num of jumps to be made by MCMC') burn_in = traits.Range(low=0, default=0, argstr='--burnin=%d', desc=('Total num of jumps at start of MCMC to be ' 'discarded')) burn_in_no_ard = traits.Range(low=0, default=0, argstr='--burninnoard=%d', desc=('num of burnin jumps before the ard is' ' imposed')) sample_every = traits.Range(low=0, default=1, argstr='--sampleevery=%d', desc='Num of jumps for each sample (MCMC)') update_proposal_every = traits.Range(low=1, default=40, argstr='--updateproposalevery=%d', desc=('Num of jumps for each update ' 'to the proposal density std ' '(MCMC)')) seed = traits.Int(argstr='--seed=%d', desc='seed for pseudo random number generator') _xor_inputs1 = ('no_ard', 'all_ard') no_ard = traits.Bool(argstr='--noard', xor=_xor_inputs1, desc='Turn ARD off on all fibres') all_ard = traits.Bool(argstr='--allard', xor=_xor_inputs1, desc='Turn ARD on on all fibres') _xor_inputs2 = ('no_spat', 'non_linear', 'cnlinear') no_spat = traits.Bool(argstr='--nospat', xor=_xor_inputs2, desc='Initialise with tensor, not spatially') non_linear = traits.Bool(argstr='--nonlinear', xor=_xor_inputs2, desc='Initialise with nonlinear fitting') cnlinear = traits.Bool(argstr='--cnonlinear', xor=_xor_inputs2, desc=('Initialise with constrained nonlinear ' 'fitting')) rician = traits.Bool(argstr='--rician', desc=('use Rician noise modeling')) _xor_inputs3 = ['f0_noard', 'f0_ard'] f0_noard = traits.Bool(argstr='--f0', xor=_xor_inputs3, desc=('Noise floor model: add to the model an ' 'unattenuated signal compartment f0')) f0_ard = traits.Bool(argstr='--f0 --ardf0', xor=_xor_inputs3 + ['all_ard'], desc=('Noise floor model: add to the model an ' 'unattenuated signal compartment f0')) force_dir = traits.Bool(True, argstr='--forcedir', usedefault=True, desc=('use the actual directory name given ' '(do not add + to make a new directory)')) class FSLXCommandOutputSpec(TraitedSpec): dyads = OutputMultiPath(File(exists=True), desc=('Mean of PDD distribution' ' in vector form.')) fsamples = OutputMultiPath(File(exists=True), desc=('Samples from the ' 'distribution on f anisotropy')) mean_dsamples = File(exists=True, desc='Mean of distribution on diffusivity d') mean_fsamples = OutputMultiPath(File(exists=True), desc=('Mean of ' 'distribution on f anisotropy')) mean_S0samples = File(exists=True,desc=('Mean of distribution on T2w' 'baseline signal intensity S0')) mean_tausamples = File(exists=True,desc=('Mean of distribution on ' 'tau samples (only with rician noise)')) phsamples = OutputMultiPath(File(exists=True), desc=('phi samples, per fiber')) thsamples = OutputMultiPath(File(exists=True), desc=('theta samples, per fiber')) class FSLXCommand(FSLCommand): """ Base support for ``xfibres`` and ``bedpostx`` """ input_spec = FSLXCommandInputSpec output_spec = FSLXCommandOutputSpec def _run_interface(self, runtime): self._out_dir = os.getcwd() runtime = super(FSLXCommand, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime def _list_outputs(self, out_dir=None): outputs = self.output_spec().get() n_fibres = self.inputs.n_fibres if not out_dir: if isdefined(self.inputs.logdir): out_dir = os.path.abspath(self.inputs.logdir) else: out_dir = os.path.abspath('logdir') multi_out = ['dyads', 'fsamples', 'mean_fsamples', 'phsamples', 'thsamples'] single_out = ['mean_dsamples', 'mean_S0samples'] for k in single_out: outputs[k] = self._gen_fname(k, cwd=out_dir) if isdefined(self.inputs.rician) and self.inputs.rician: outputs['mean_tausamples'] = self._gen_fname('mean_tausamples', cwd=out_dir) for k in multi_out: outputs[k] = [] for i in xrange(1, n_fibres + 1): outputs['fsamples'].append(self._gen_fname('f%dsamples' % i, cwd=out_dir)) outputs['mean_fsamples'].append(self._gen_fname(('mean_f%d' 'samples') % i, cwd=out_dir)) for i in xrange(1, n_fibres + 1): outputs['dyads'].append(self._gen_fname('dyads%d' % i, cwd=out_dir)) outputs['phsamples'].append(self._gen_fname('ph%dsamples' % i, cwd=out_dir)) outputs['thsamples'].append(self._gen_fname('th%dsamples' % i, cwd=out_dir)) return outputs class BEDPOSTX5InputSpec(FSLXCommandInputSpec): dwi = File(exists=True, desc='diffusion weighted image data file', mandatory=True) mask = File(exists=True, desc='bet binary mask file', mandatory=True) bvecs = File(exists=True, desc='b vectors file', mandatory=True) bvals = File(exists=True, desc='b values file', mandatory=True) logdir = Directory(argstr='--logdir=%s') n_fibres = traits.Range( usedefault=True, low=1, default=2, argstr='-n %d', desc=('Maximum number of fibres to fit in each voxel'), mandatory=True) model = traits.Enum(1, 2, argstr='-model %d', desc=('use monoexponential (1, default, required for ' 'single-shell) or multiexponential (2, multi-' 'shell) model')) fudge = traits.Int(argstr='-w %d', desc='ARD fudge factor') n_jumps = traits.Int(5000, argstr='-j %d', desc='Num of jumps to be made by MCMC') burn_in = traits.Range(low=0, default=0, argstr='-b %d', desc=('Total num of jumps at start of MCMC to be ' 'discarded')) sample_every = traits.Range(low=0, default=1, argstr='-s %d', desc='Num of jumps for each sample (MCMC)') out_dir = Directory('bedpostx', mandatory=True, desc='output directory', usedefault=True, position=1, argstr='%s') gradnonlin = traits.Bool(False, argstr='-g', desc=('consider gradient ' 'nonlinearities, default off')) use_gpu = traits.Bool(False, desc='Use the GPU version of bedpostx') class BEDPOSTX5OutputSpec(TraitedSpec): mean_dsamples = File(exists=True, desc='Mean of distribution on diffusivity d') mean_fsamples = OutputMultiPath(File(exists=True), desc=('Mean of ' 'distribution on f anisotropy')) mean_S0samples = File(exists=True,desc=('Mean of distribution on T2w' 'baseline signal intensity S0')) mean_phsamples = OutputMultiPath(File(exists=True), desc=('Mean of ' 'distribution on phi')) mean_thsamples = OutputMultiPath(File(exists=True), desc=('Mean of ' 'distribution on theta')) merged_thsamples = OutputMultiPath(File(exists=True), desc=('Samples from ' 'the distribution on theta')) merged_phsamples = OutputMultiPath(File(exists=True), desc=('Samples from ' 'the distribution on phi')) merged_fsamples = OutputMultiPath(File(exists=True), desc=('Samples from the distribution on ' 'anisotropic volume fraction')) dyads = OutputMultiPath(File(exists=True), desc=('Mean of PDD distribution' ' in vector form.')) dyads_dispersion = OutputMultiPath(File(exists=True), desc=('Dispersion')) class BEDPOSTX5(FSLXCommand): """ BEDPOSTX stands for Bayesian Estimation of Diffusion Parameters Obtained using Sampling Techniques. The X stands for modelling Crossing Fibres. bedpostx runs Markov Chain Monte Carlo sampling to build up distributions on diffusion parameters at each voxel. It creates all the files necessary for running probabilistic tractography. For an overview of the modelling carried out within bedpostx see this `technical report `_. .. note:: Consider using :func:`nipype.workflows.fsl.dmri.create_bedpostx_pipeline` instead. Example ------- >>> from nipype.interfaces import fsl >>> bedp = fsl.BEDPOSTX5(bvecs='bvecs', bvals='bvals', dwi='diffusion.nii', ... mask='mask.nii', n_fibres=1) >>> bedp.cmdline 'bedpostx bedpostx --forcedir -n 1' """ _cmd = 'bedpostx' _default_cmd = _cmd input_spec = BEDPOSTX5InputSpec output_spec = BEDPOSTX5OutputSpec _can_resume = True def __init__(self, **inputs): super(BEDPOSTX5, self).__init__(**inputs) self.inputs.on_trait_change(self._cuda_update, 'use_gpu') def _cuda_update(self): if isdefined(self.inputs.use_gpu) and self.inputs.use_gpu: self._cmd = 'bedpostx_gpu' else: self._cmd = self._default_cmd def _run_interface(self, runtime): subjectdir = os.path.abspath(self.inputs.out_dir) if not os.path.exists(subjectdir): os.makedirs(subjectdir) _, _, ext = split_filename(self.inputs.mask) copyfile(self.inputs.mask, os.path.join(subjectdir, 'nodif_brain_mask' + ext)) _, _, ext = split_filename(self.inputs.dwi) copyfile(self.inputs.dwi, os.path.join(subjectdir, 'data' + ext)) copyfile(self.inputs.bvals, os.path.join(subjectdir, 'bvals')) copyfile(self.inputs.bvecs, os.path.join(subjectdir, 'bvecs')) retval = super(BEDPOSTX5, self)._run_interface(runtime) self._out_dir = subjectdir + '.bedpostX' return retval def _list_outputs(self): outputs = self.output_spec().get() n_fibres = self.inputs.n_fibres multi_out = ['merged_thsamples', 'merged_fsamples', 'merged_phsamples', 'mean_phsamples', 'mean_thsamples', 'mean_fsamples', 'dyads_dispersion', 'dyads'] single_out = ['mean_dsamples', 'mean_S0samples'] for k in single_out: outputs[k] = self._gen_fname(k, cwd=self._out_dir) for k in multi_out: outputs[k] = [] for i in xrange(1, n_fibres + 1): outputs['merged_thsamples'].append(self._gen_fname('merged_th%dsamples' % i, cwd=self._out_dir)) outputs['merged_fsamples'].append(self._gen_fname('merged_f%dsamples' % i, cwd=self._out_dir)) outputs['merged_phsamples'].append(self._gen_fname('merged_ph%dsamples' % i, cwd=self._out_dir)) outputs['mean_thsamples'].append(self._gen_fname('mean_th%dsamples' % i, cwd=self._out_dir)) outputs['mean_phsamples'].append(self._gen_fname('mean_ph%dsamples' % i, cwd=self._out_dir)) outputs['mean_fsamples'].append(self._gen_fname('mean_f%dsamples' % i, cwd=self._out_dir)) outputs['dyads'].append(self._gen_fname('dyads%d' % i, cwd=self._out_dir)) outputs['dyads_dispersion'].append(self._gen_fname('dyads%d_dispersion' % i, cwd=self._out_dir)) return outputs class XFibres5InputSpec(FSLXCommandInputSpec): gradnonlin = File(exists=True, argstr='--gradnonlin=%s', desc='gradient file corresponding to slice') class XFibres5(FSLXCommand): """ Perform model parameters estimation for local (voxelwise) diffusion parameters """ _cmd = 'xfibres' input_spec = XFibres5InputSpec output_spec = FSLXCommandOutputSpec class XFibres4InputSpec(FSLCommandInputSpec): dwi = File(exists=True, argstr="--data=%s", mandatory=True) mask = File(exists=True, argstr="--mask=%s", mandatory=True) gradnonlin = File(exists=True, argstr="--gradnonlin=%s") bvecs = File(exists=True, argstr="--bvecs=%s", mandatory=True) bvals = File(exists=True, argstr="--bvals=%s", mandatory=True) logdir = Directory("logdir", argstr="--logdir=%s", usedefault=True) n_fibres = traits.Range(low=1, argstr="--nfibres=%d", desc="Maximum nukmber of fibres to fit in each voxel") fudge = traits.Int(argstr="--fudge=%d", desc="ARD fudge factor") n_jumps = traits.Range(low=1, argstr="--njumps=%d", desc="Num of jumps to be made by MCMC") burn_in = traits.Range(low=0, argstr="--burnin=%d", desc="Total num of jumps at start of MCMC to be discarded") burn_in_no_ard = traits.Range(low=0, argstr="--burninnoard=%d", desc="num of burnin jumps before the ard is imposed") sample_every = traits.Range(low=0, argstr="--sampleevery=%d", desc="Num of jumps for each sample (MCMC)") update_proposal_every = traits.Range(low=1, argstr="--updateproposalevery=%d", desc="Num of jumps for each update to the proposal density std (MCMC)") seed = traits.Int(argstr="--seed=%d", desc="seed for pseudo random number generator") model = traits.Int(argstr="--model=%d", desc="Which model to use. \ 1=mono-exponential (default and required for single shell). 2=continous \ exponential (for multi-shell experiments)") _xor_inputs1 = ('no_ard', 'all_ard') no_ard = traits.Bool(argstr="--noard", desc="Turn ARD off on all fibres", xor=_xor_inputs1) all_ard = traits.Bool(argstr="--allard", desc="Turn ARD on on all fibres", xor=_xor_inputs1) _xor_inputs2 = ('no_spat', 'non_linear') no_spat = traits.Bool(argstr="--nospat", desc="Initialise with tensor, not spatially", xor=_xor_inputs2) non_linear = traits.Bool(argstr="--nonlinear", desc="Initialise with nonlinear fitting", xor=_xor_inputs2) force_dir = traits.Bool(True, desc='use the actual directory name given - i.e. ' + 'do not add + to make a new directory', argstr='--forcedir', usedefault=True) class XFibres4OutputSpec(TraitedSpec): dyads = OutputMultiPath(File(exists=True), desc="Mean of PDD distribution in vector form.") fsamples = OutputMultiPath(File(exists=True), desc="Samples from the distribution on anisotropic volume fraction") mean_dsamples = File(exists=True, desc="Mean of distribution on diffusivity d") mean_fsamples = OutputMultiPath(File(exists=True), desc="Mean of distribution on f anisotropy") mean_S0samples = File(exists=True, desc="Samples from S0 distribution") phsamples = OutputMultiPath(File(exists=True), desc="Samples from the distribution on phi") thsamples = OutputMultiPath(File(exists=True), desc="Samples from the distribution on theta") class XFibres4(FSLCommand): """ Perform model parameters estimation for local (voxelwise) diffusion parameters .. deprecated:: 0.9.2 Use :class:`.XFibres5` instead. """ _cmd = "xfibres" input_spec = XFibres4InputSpec output_spec = XFibres4OutputSpec def __init__(self, **inputs): warnings.warn(('Deprecated: Please use XFIBERS5 instead. This ' 'interface will be removed in version 0.11.'), DeprecationWarning) super(XFibres4, self).__init__(**inputs) def _list_outputs(self): outputs = self.output_spec().get() outputs["mean_dsamples"] = self._gen_fname("mean_dsamples", cwd=self.inputs.logdir) outputs["mean_S0samples"] = self._gen_fname("mean_S0samples", cwd=self.inputs.logdir) outputs["dyads"] = [] outputs["fsamples"] = [] outputs["mean_fsamples"] = [] outputs["phsamples"] = [] outputs["thsamples"] = [] for i in range(1, self.inputs.n_fibres + 1): outputs["dyads"].append(self._gen_fname("dyads%d" % i, cwd=self.inputs.logdir)) outputs["fsamples"].append(self._gen_fname("f%dsamples" % i, cwd=self.inputs.logdir)) outputs["mean_fsamples"].append(self._gen_fname("mean_f%dsamples" % i, cwd=self.inputs.logdir)) outputs["phsamples"].append(self._gen_fname("ph%dsamples" % i, cwd=self.inputs.logdir)) outputs["thsamples"].append(self._gen_fname("th%dsamples" % i, cwd=self.inputs.logdir)) return outputs class BEDPOSTX4InputSpec(XFibres4InputSpec): dwi = File(exists=True, desc='diffusion weighted image data file', mandatory=True) mask = File(exists=True, desc='bet binary mask file', mandatory=True) bvecs = File(exists=True, desc='b vectors file', mandatory=True) bvals = File(exists=True, desc='b values file', mandatory=True) bpx_directory = Directory('bedpostx', argstr='%s', usedefault=True, desc=('the name for this subject\'s bedpostx' ' folder')) fibres = traits.Int(2, argstr='-n %d', desc='number of fibres per voxel') weight = traits.Float(1.00, argstr='-w %.2f', desc=('ARD weight, more weight means less' ' secondary fibres per voxel')) burn_period = traits.Int(1000, argstr='-b %d', desc='burnin period') jumps = traits.Int(1250, argstr='-j %d', desc='number of jumps') sampling = traits.Int(25, argstr='-s %d', desc='sample every') model = traits.Enum(1, 2, argstr='-model %d', desc=('model choice: monoexponential (1) or ' 'multiexponential (2). ')) nlgradient = traits.Bool(False, argstr='-g', desc=('consider gradient' 'nonlinearities, default off')) no_cuda = traits.Bool(False, argstr='-c', desc=('do not use CUDA capable hardware/queue ' '(if found)')) class BEDPOSTX4OutputSpec(TraitedSpec): bpx_out_directory = Directory(exists=True, desc='path/name of directory with all ' + 'bedpostx output files for this subject') xfms_directory = Directory(exists=True, desc='path/name of directory with the ' + 'tranformation matrices') merged_thsamples = traits.List(File(exists=True), desc='a list of path/name of 4D volume ' + 'with samples from the distribution ' + 'on theta') merged_phsamples = traits.List(File(exists=True), desc='a list of path/name of file with ' 'samples from the distribution on phi') merged_fsamples = traits.List(File(exists=True), desc='a list of path/name of 4D volume ' + 'with samples from the distribution ' + 'on anisotropic volume fraction') mean_thsamples = traits.List(File(exists=True), desc='a list of path/name of 3D volume with mean of distribution on theta') mean_phsamples = traits.List(File(exists=True), desc='a list of path/name of 3D volume with mean of distribution on phi') mean_fsamples = traits.List(File(exists=True), desc='a list of path/name of 3D volume with mean of distribution on f anisotropy') dyads = traits.List(File(exists=True), desc='a list of path/name of mean of PDD distribution in vector form') class BEDPOSTX4(FSLCommand): """ bedpostx has an old interface, implemented here Example ------- >>> from nipype.interfaces import fsl >>> bedp = fsl.BEDPOSTX4(bpx_directory='subjdir', bvecs='bvecs', \ bvals='bvals', dwi='diffusion.nii', mask='mask.nii', fibres=1) >>> bedp.cmdline 'bedpostx subjdir -n 1 --forcedir --logdir=logdir' """ _cmd = 'bedpostx' input_spec = BEDPOSTX4InputSpec output_spec = BEDPOSTX4OutputSpec _can_resume = True def __init__(self, **inputs): warnings.warn(('Deprecated: Please use BEDPOSTX5 or ' 'create_bedpostx_pipeline instead. This interface will ' 'be removed in version 0.11.'), DeprecationWarning) super(BEDPOSTX4, self).__init__(**inputs) def _get_bedpostx_dir(self): return os.path.join(os.getcwd(), self.inputs.bpx_directory) def _run_interface(self, runtime, correct_return_codes=[0]): #create the subject specific bpx_directory bpx_directory = self._get_bedpostx_dir() if not os.path.exists(bpx_directory): os.makedirs(bpx_directory) _, _, ext = split_filename(self.inputs.mask) shutil.copyfile(self.inputs.mask, os.path.join(self.inputs.bpx_directory, 'nodif_brain_mask' + ext)) _, _, ext = split_filename(self.inputs.dwi) shutil.copyfile(self.inputs.dwi, os.path.join(self.inputs.bpx_directory, 'data' + ext)) shutil.copyfile(self.inputs.bvals, os.path.join(self.inputs.bpx_directory, 'bvals')) shutil.copyfile(self.inputs.bvecs, os.path.join(self.inputs.bpx_directory, 'bvecs')) runtime = super(BEDPOSTX4, self)._run_interface(runtime, correct_return_codes) if runtime.stderr: self.raise_exception(runtime) return runtime def _list_outputs(self): outputs = self.output_spec().get() bpx_directory = self._get_bedpostx_dir() outputs['bpx_out_directory'] = os.path.join(bpx_directory + '.bedpostX') outputs['xfms_directory'] = os.path.join(bpx_directory + '.bedpostX', 'xfms') for k in outputs.keys(): if k not in ('outputtype', 'environ', 'args', 'bpx_out_directory', 'xfms_directory'): outputs[k] = [] for n in range(self.inputs.fibres): outputs['merged_thsamples'].append(self._gen_fname('merged_th' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['merged_phsamples'].append(self._gen_fname('merged_ph' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['merged_fsamples'].append(self._gen_fname('merged_f' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['mean_thsamples'].append(self._gen_fname('mean_th' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['mean_phsamples'].append(self._gen_fname('mean_ph' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['mean_fsamples'].append(self._gen_fname('mean_f' + repr(n + 1) + 'samples', suffix='', cwd=outputs['bpx_out_directory'])) outputs['dyads'].append(self._gen_fname('dyads' + repr(n + 1), suffix='', cwd=outputs['bpx_out_directory'])) return outputs if (Info.version() and LooseVersion(Info.version()) >= LooseVersion('5.0.0')): CurrentXFibres = XFibres5 CurrentBEDPOST = BEDPOSTX5 else: CurrentXFibres = XFibres4 CurrentBEDPOST = BEDPOSTX4 class XFibres(CurrentXFibres): pass class BEDPOSTX(CurrentBEDPOST): pass class ProbTrackXBaseInputSpec(FSLCommandInputSpec): thsamples = InputMultiPath(File(exists=True), mandatory=True) phsamples = InputMultiPath(File(exists=True), mandatory=True) fsamples = InputMultiPath(File(exists=True), mandatory=True) samples_base_name = traits.Str("merged", desc='the rootname/base_name for samples files', argstr='--samples=%s', usedefault=True) mask = File(exists=True, desc='bet binary mask file in diffusion space', argstr='-m %s', mandatory=True) seed = traits.Either(File(exists=True), traits.List(File(exists=True)), traits.List(traits.List(traits.Int(), minlen=3, maxlen=3)), desc='seed volume(s), or voxel(s)' + 'or freesurfer label file', argstr='--seed=%s', mandatory=True) target_masks = InputMultiPath(File(exits=True), desc='list of target masks - ' + 'required for seeds_to_targets classification', argstr='--targetmasks=%s') waypoints = File(exists=True, desc='waypoint mask or ascii list of waypoint masks - ' + 'only keep paths going through ALL the masks', argstr='--waypoints=%s') network = traits.Bool(desc='activate network mode - only keep paths going through ' + 'at least one seed mask (required if multiple seed masks)', argstr='--network') seed_ref = File(exists=True, desc='reference vol to define seed space in ' + 'simple mode - diffusion space assumed if absent', argstr='--seedref=%s') out_dir = Directory(exists=True, argstr='--dir=%s', desc='directory to put the final volumes in', genfile=True) force_dir = traits.Bool(True, desc='use the actual directory name given - i.e. ' + 'do not add + to make a new directory', argstr='--forcedir', usedefault=True) opd = traits.Bool(True, desc='outputs path distributions', argstr='--opd', usedefault=True) correct_path_distribution = traits.Bool(desc='correct path distribution for the length of the pathways', argstr='--pd') os2t = traits.Bool(desc='Outputs seeds to targets', argstr='--os2t') #paths_file = File('nipype_fdtpaths', usedefault=True, argstr='--out=%s', # desc='produces an output file (default is fdt_paths)') avoid_mp = File(exists=True, desc='reject pathways passing through locations given by this mask', argstr='--avoid=%s') stop_mask = File(exists=True, argstr='--stop=%s', desc='stop tracking at locations given by this mask file') xfm = File(exists=True, argstr='--xfm=%s', desc='transformation matrix taking seed space to DTI space ' + '(either FLIRT matrix or FNIRT warp_field) - default is identity') inv_xfm = File(argstr='--invxfm=%s', desc='transformation matrix taking DTI space to seed' + ' space (compulsory when using a warp_field for seeds_to_dti)') n_samples = traits.Int(5000, argstr='--nsamples=%d', desc='number of samples - default=5000', usedefault=True) n_steps = traits.Int(argstr='--nsteps=%d', desc='number of steps per sample - default=2000') dist_thresh = traits.Float(argstr='--distthresh=%.3f', desc='discards samples shorter than ' + 'this threshold (in mm - default=0)') c_thresh = traits.Float(argstr='--cthr=%.3f', desc='curvature threshold - default=0.2') sample_random_points = traits.Bool(argstr='--sampvox', desc='sample random points within seed voxels') step_length = traits.Float(argstr='--steplength=%.3f', desc='step_length in mm - default=0.5') loop_check = traits.Bool(argstr='--loopcheck', desc='perform loop_checks on paths -' + ' slower, but allows lower curvature threshold') use_anisotropy = traits.Bool(argstr='--usef', desc='use anisotropy to constrain tracking') rand_fib = traits.Enum(0, 1, 2, 3, argstr='--randfib=%d', desc='options: 0 - default, 1 - to randomly sample' + ' initial fibres (with f > fibthresh), 2 - to sample in ' + 'proportion fibres (with f>fibthresh) to f, 3 - to sample ALL ' + 'populations at random (even if f>> from nipype.interfaces import fsl >>> pbx = fsl.ProbTrackX(samples_base_name='merged', mask='mask.nii', \ seed='MASK_average_thal_right.nii', mode='seedmask', \ xfm='trans.mat', n_samples=3, n_steps=10, force_dir=True, opd=True, os2t=True, \ target_masks = ['targets_MASK1.nii', 'targets_MASK2.nii'], \ thsamples='merged_thsamples.nii', fsamples='merged_fsamples.nii', phsamples='merged_phsamples.nii', \ out_dir='.') >>> pbx.cmdline 'probtrackx --forcedir -m mask.nii --mode=seedmask --nsamples=3 --nsteps=10 --opd --os2t --dir=. --samples=merged --seed=MASK_average_thal_right.nii --targetmasks=targets.txt --xfm=trans.mat' """ _cmd = 'probtrackx' input_spec = ProbTrackXInputSpec output_spec = ProbTrackXOutputSpec def __init__(self, **inputs): warnings.warn("Deprecated: Please use create_bedpostx_pipeline instead", DeprecationWarning) return super(ProbTrackX, self).__init__(**inputs) def _run_interface(self, runtime): for i in range(1, len(self.inputs.thsamples) + 1): _, _, ext = split_filename(self.inputs.thsamples[i - 1]) copyfile(self.inputs.thsamples[i - 1], self.inputs.samples_base_name + "_th%dsamples" % i + ext, copy=False) _, _, ext = split_filename(self.inputs.thsamples[i - 1]) copyfile(self.inputs.phsamples[i - 1], self.inputs.samples_base_name + "_ph%dsamples" % i + ext, copy=False) _, _, ext = split_filename(self.inputs.thsamples[i - 1]) copyfile(self.inputs.fsamples[i - 1], self.inputs.samples_base_name + "_f%dsamples" % i + ext, copy=False) if isdefined(self.inputs.target_masks): f = open("targets.txt", "w") for target in self.inputs.target_masks: f.write("%s\n" % target) f.close() if isinstance(self.inputs.seed, list): f = open("seeds.txt", "w") for seed in self.inputs.seed: if isinstance(seed, list): f.write("%s\n" % (" ".join([str(s) for s in seed]))) else: f.write("%s\n" % seed) f.close() runtime = super(ProbTrackX, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime def _format_arg(self, name, spec, value): if name == 'target_masks' and isdefined(value): fname = "targets.txt" return super(ProbTrackX, self)._format_arg(name, spec, [fname]) elif name == 'seed' and isinstance(value, list): fname = "seeds.txt" return super(ProbTrackX, self)._format_arg(name, spec, fname) else: return super(ProbTrackX, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_dir): out_dir = self._gen_filename("out_dir") else: out_dir = self.inputs.out_dir outputs['log'] = os.path.abspath(os.path.join(out_dir, 'probtrackx.log')) #utputs['way_total'] = os.path.abspath(os.path.join(out_dir, 'waytotal')) if isdefined(self.inputs.opd == True): if isinstance(self.inputs.seed, list) and isinstance(self.inputs.seed[0], list): outputs['fdt_paths'] = [] for seed in self.inputs.seed: outputs['fdt_paths'].append( os.path.abspath( self._gen_fname("fdt_paths_%s" % ("_".join([str(s) for s in seed])), cwd=out_dir, suffix=''))) else: outputs['fdt_paths'] = os.path.abspath(self._gen_fname("fdt_paths", cwd=out_dir, suffix='')) # handle seeds-to-target output files if isdefined(self.inputs.target_masks): outputs['targets'] = [] for target in self.inputs.target_masks: outputs['targets'].append(os.path.abspath( self._gen_fname('seeds_to_' + os.path.split(target)[1], cwd=out_dir, suffix=''))) if isdefined(self.inputs.verbose) and self.inputs.verbose == 2: outputs['particle_files'] = [os.path.abspath( os.path.join(out_dir, 'particle%d' % i)) for i in range(self.inputs.n_samples)] return outputs def _gen_filename(self, name): if name == "out_dir": return os.getcwd() elif name == "mode": if isinstance(self.inputs.seed, list) and isinstance(self.inputs.seed[0], list): return "simple" else: return "seedmask" class ProbTrackX2InputSpec(ProbTrackXBaseInputSpec): simple = traits.Bool(desc='rack from a list of voxels (seed must be a ASCII list of coordinates)', usedefault=False, argstr='--simple') fopd = File(exists=True, desc='Other mask for binning tract distribution', argstr='--fopd=%s') waycond = traits.Enum("OR", "AND", argstr='--waycond=%s', desc='Waypoint condition. Either "AND" (default) or "OR"') wayorder = traits.Bool(desc='Reject streamlines that do not hit waypoints in given order. ' + 'Only valid if waycond=AND', argstr='--wayorder') onewaycondition = traits.Bool(desc='Apply waypoint conditions to each half tract separately', argstr='--onewaycondition') omatrix1 = traits.Bool(desc='Output matrix1 - SeedToSeed Connectivity', argstr='--omatrix1') distthresh1 = traits.Float(argstr='--distthresh1=%.3f', desc='Discards samples (in matrix1) shorter than this threshold ' + '(in mm - default=0)') omatrix2 = traits.Bool(desc='Output matrix2 - SeedToLowResMask', argstr='--omatrix2', requires=['target2']) target2 = File(exists=True, desc='Low resolution binary brain mask for storing ' + 'connectivity distribution in matrix2 mode', argstr='--target2=%s') omatrix3 = traits.Bool(desc='Output matrix3 (NxN connectivity matrix)', argstr='--omatrix3', requires=['target3', 'lrtarget3']) target3 = File(exists=True, desc='Mask used for NxN connectivity matrix ' + '(or Nxn if lrtarget3 is set)', argstr='--target3=%s') lrtarget3 = File(exists=True, desc='Column-space mask used for Nxn connectivity matrix', argstr='--lrtarget3=%s') distthresh3 = traits.Float(argstr='--distthresh3=%.3f', desc='Discards samples (in matrix3) shorter than this threshold ' + '(in mm - default=0)') omatrix4 = traits.Bool(desc='Output matrix4 - DtiMaskToSeed (special Oxford Sparse Format)', argstr='--omatrix4') colmask4 = File(exists=True, desc='Mask for columns of matrix4 (default=seed mask)', argstr='--colmask4=%s') target4 = File(exists=True, desc='Brain mask in DTI space', argstr='--target4=%s') meshspace = traits.Enum("caret", "freesurfer", "first", "vox", argstr='--meshspace=%s', desc='Mesh reference space - either "caret" (default) or ' + '"freesurfer" or "first" or "vox"') class ProbTrackX2OutputSpec(ProbTrackXOutputSpec): network_matrix = File(exists=True, desc='the network matrix generated by --omatrix1 option') matrix1_dot = File(exists=True, desc='Output matrix1.dot - SeedToSeed Connectivity') lookup_tractspace = File(exists=True, desc='lookup_tractspace generated by --omatrix2 option') matrix2_dot = File(exists=True, desc='Output matrix2.dot - SeedToLowResMask') matrix3_dot = File(exists=True, desc='Output matrix3 - NxN connectivity matrix') class ProbTrackX2(ProbTrackX): """ Use FSL probtrackx2 for tractography on bedpostx results Examples -------- >>> from nipype.interfaces import fsl >>> pbx2 = fsl.ProbTrackX2() >>> pbx2.inputs.seed = 'seed_source.nii.gz' >>> pbx2.inputs.thsamples = 'merged_th1samples.nii.gz' >>> pbx2.inputs.fsamples = 'merged_f1samples.nii.gz' >>> pbx2.inputs.phsamples = 'merged_ph1samples.nii.gz' >>> pbx2.inputs.mask = 'nodif_brain_mask.nii.gz' >>> pbx2.inputs.out_dir = '.' >>> pbx2.inputs.n_samples = 3 >>> pbx2.inputs.n_steps = 10 >>> pbx2.cmdline 'probtrackx2 --forcedir -m nodif_brain_mask.nii.gz --nsamples=3 --nsteps=10 --opd --dir=. --samples=merged --seed=seed_source.nii.gz' """ _cmd = 'probtrackx2' input_spec = ProbTrackX2InputSpec output_spec = ProbTrackX2OutputSpec def _list_outputs(self): outputs = super(ProbTrackX2, self)._list_outputs() if not isdefined(self.inputs.out_dir): out_dir = os.getcwd() else: out_dir = self.inputs.out_dir if isdefined(self.inputs.omatrix1): outputs['network_matrix'] = os.path.abspath(os.path.join(out_dir, 'fdt_network_matrix')) outputs['matrix1_dot'] = os.path.abspath(os.path.join(out_dir, 'fdt_matrix1.dot')) if isdefined(self.inputs.omatrix2): outputs['lookup_tractspace'] = \ os.path.abspath(os.path.join(out_dir, 'lookup_tractspace_fdt_matrix2.nii.gz')) outputs['matrix2_dot'] = os.path.abspath(os.path.join(out_dir, 'fdt_matrix2.dot')) if isdefined(self.inputs.omatrix3): outputs['matrix3_dot'] = os.path.abspath(os.path.join(out_dir, 'fdt_matrix3.dot')) return outputs class VecRegInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='-i %s', desc='filename for input vector or tensor field', mandatory=True) out_file = File(argstr='-o %s', desc='filename for output registered vector or tensor field', genfile=True, hash_files=False) ref_vol = File(exists=True, argstr='-r %s', desc='filename for reference (target) volume', mandatory=True) affine_mat = File(exists=True, argstr='-t %s', desc='filename for affine transformation matrix') warp_field = File(exists=True, argstr='-w %s', desc='filename for 4D warp field for nonlinear registration') rotation_mat = File(exists=True, argstr='--rotmat=%s', desc='filename for secondary affine matrix' + 'if set, this will be used for the rotation of the vector/tensor field') rotation_warp = File(exists=True, argstr='--rotwarp=%s', desc='filename for secondary warp field' + 'if set, this will be used for the rotation of the vector/tensor field') interpolation = traits.Enum("nearestneighbour", "trilinear", "sinc", "spline", argstr='--interp=%s', desc='interpolation method : ' + 'nearestneighbour, trilinear (default), sinc or spline') mask = File(exists=True, argstr='-m %s', desc='brain mask in input space') ref_mask = File(exists=True, argstr='--refmask=%s', desc='brain mask in output space ' + '(useful for speed up of nonlinear reg)') class VecRegOutputSpec(TraitedSpec): out_file = File(exists=True, desc='path/name of filename for the registered vector or tensor field') class VecReg(FSLCommand): """Use FSL vecreg for registering vector data For complete details, see the FDT Documentation Example ------- >>> from nipype.interfaces import fsl >>> vreg = fsl.VecReg(in_file='diffusion.nii', \ affine_mat='trans.mat', \ ref_vol='mni.nii', \ out_file='diffusion_vreg.nii') >>> vreg.cmdline 'vecreg -t trans.mat -i diffusion.nii -o diffusion_vreg.nii -r mni.nii' """ _cmd = 'vecreg' input_spec = VecRegInputSpec output_spec = VecRegOutputSpec def _run_interface(self, runtime): if not isdefined(self.inputs.out_file): pth, base_name = os.path.split(self.inputs.in_file) self.inputs.out_file = self._gen_fname(base_name, cwd=os.path.abspath(pth), suffix='_vreg') return super(VecReg, self)._run_interface(runtime) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']) and isdefined(self.inputs.in_file): pth, base_name = os.path.split(self.inputs.in_file) outputs['out_file'] = self._gen_fname(base_name, cwd=os.path.abspath(pth), suffix='_vreg') outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_file': return self._list_outputs()[name] else: return None class ProjThreshInputSpec(FSLCommandInputSpec): in_files = traits.List(File(exists=True), argstr='%s', desc='a list of input volumes', mandatory=True, position=0) threshold = traits.Int(argstr='%d', desc='threshold indicating minimum ' + 'number of seed voxels entering this mask region', mandatory=True, position=1) class ProjThreshOuputSpec(TraitedSpec): out_files = traits.List(File(exists=True), desc='path/name of output volume after thresholding') class ProjThresh(FSLCommand): """Use FSL proj_thresh for thresholding some outputs of probtrack For complete details, see the FDT Documentation Example ------- >>> from nipype.interfaces import fsl >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] >>> pThresh = fsl.ProjThresh(in_files=ldir, threshold=3) >>> pThresh.cmdline 'proj_thresh seeds_to_M1.nii seeds_to_M2.nii 3' """ _cmd = 'proj_thresh' input_spec = ProjThreshInputSpec output_spec = ProjThreshOuputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_files'] = [] for name in self.inputs.in_files: cwd, base_name = os.path.split(name) outputs['out_files'].append(self._gen_fname(base_name, cwd=cwd, suffix='_proj_seg_thr_' + repr(self.inputs.threshold))) return outputs class FindTheBiggestInputSpec(FSLCommandInputSpec): in_files = traits.List(File(exists=True), argstr='%s', desc='a list of input volumes or a singleMatrixFile', position=0, mandatory=True) out_file = File(argstr='%s', desc='file with the resulting segmentation', position=2, genfile=True, hash_files=False) class FindTheBiggestOutputSpec(TraitedSpec): out_file = File(exists=True, argstr='%s', desc='output file indexed in order of input files') class FindTheBiggest(FSLCommand): """ Use FSL find_the_biggest for performing hard segmentation on the outputs of connectivity-based thresholding in probtrack. For complete details, see the `FDT Documentation. `_ Example ------- >>> from nipype.interfaces import fsl >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] >>> fBig = fsl.FindTheBiggest(in_files=ldir, out_file='biggestSegmentation') >>> fBig.cmdline 'find_the_biggest seeds_to_M1.nii seeds_to_M2.nii biggestSegmentation' """ _cmd = 'find_the_biggest' input_spec = FindTheBiggestInputSpec output_spec = FindTheBiggestOutputSpec def _run_interface(self, runtime): if not isdefined(self.inputs.out_file): self.inputs.out_file = self._gen_fname('biggestSegmentation', suffix='') return super(FindTheBiggest, self)._run_interface(runtime) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']): outputs['out_file'] = self._gen_fname('biggestSegmentation', suffix='') outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_file': return self._list_outputs()[name] else: return None class TractSkeletonInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="-i %s", desc="input image (typcially mean FA volume)") _proj_inputs = ["threshold", "distance_map", "data_file"] project_data = traits.Bool(argstr="-p %.3f %s %s %s %s", requires=_proj_inputs, desc="project data onto skeleton") threshold = traits.Float(desc="skeleton threshold value") distance_map = File(exists=True, desc="distance map image") search_mask_file = File(exists=True, xor=["use_cingulum_mask"], desc="mask in which to use alternate search rule") use_cingulum_mask = traits.Bool(True, usedefault=True, xor=["search_mask_file"], desc="perform alternate search using built-in cingulum mask") data_file = File(exists=True, desc="4D data to project onto skeleton (usually FA)") alt_data_file = File(exists=True, argstr="-a %s", desc="4D non-FA data to project onto skeleton") alt_skeleton = File(exists=True, argstr="-s %s", desc="alternate skeleton to use") projected_data = File(desc="input data projected onto skeleton") skeleton_file = traits.Either(traits.Bool, File, argstr="-o %s", desc="write out skeleton image") class TractSkeletonOutputSpec(TraitedSpec): projected_data = File(desc="input data projected onto skeleton") skeleton_file = File(desc="tract skeleton image") class TractSkeleton(FSLCommand): """Use FSL's tbss_skeleton to skeletonise an FA image or project arbitrary values onto a skeleton. There are two ways to use this interface. To create a skeleton from an FA image, just supply the ``in_file`` and set ``skeleton_file`` to True (or specify a skeleton filename. To project values onto a skeleton, you must set ``project_data`` to True, and then also supply values for ``threshold``, ``distance_map``, and ``data_file``. The ``search_mask_file`` and ``use_cingulum_mask`` inputs are also used in data projection, but ``use_cingulum_mask`` is set to True by default. This mask controls where the projection algorithm searches within a circular space around a tract, rather than in a single perpindicular direction. Example ------- >>> import nipype.interfaces.fsl as fsl >>> skeletor = fsl.TractSkeleton() >>> skeletor.inputs.in_file = "all_FA.nii.gz" >>> skeletor.inputs.skeleton_file = True >>> skeletor.run() # doctest: +SKIP """ _cmd = "tbss_skeleton" input_spec = TractSkeletonInputSpec output_spec = TractSkeletonOutputSpec def _format_arg(self, name, spec, value): if name == "project_data": if isdefined(value) and value: _si = self.inputs if isdefined(_si.use_cingulum_mask) and _si.use_cingulum_mask: mask_file = Info.standard_image("LowerCingulum_1mm.nii.gz") else: mask_file = _si.search_mask_file if not isdefined(_si.projected_data): proj_file = self._list_outputs()["projected_data"] else: proj_file = _si.projected_data return spec.argstr % (_si.threshold, _si.distance_map, mask_file, _si.data_file, proj_file) elif name == "skeleton_file": if isinstance(value, bool): return spec.argstr % self._list_outputs()["skeleton_file"] else: return spec.argstr % value return super(TractSkeleton, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() _si = self.inputs if isdefined(_si.project_data) and _si.project_data: proj_data = _si.projected_data outputs["projected_data"] = proj_data if not isdefined(proj_data): stem = _si.data_file if isdefined(_si.alt_data_file): stem = _si.alt_data_file outputs["projected_data"] = fname_presuffix(stem, suffix="_skeletonised", newpath=os.getcwd(), use_ext=True) if isdefined(_si.skeleton_file) and _si.skeleton_file: outputs["skeleton_file"] = _si.skeleton_file if isinstance(_si.skeleton_file, bool): outputs["skeleton_file"] = fname_presuffix(_si.in_file, suffix="_skeleton", newpath=os.getcwd(), use_ext=True) return outputs class DistanceMapInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="--in=%s", desc="image to calculate distance values for") mask_file = File(exists=True, argstr="--mask=%s", desc="binary mask to contrain calculations") invert_input = traits.Bool(argstr="--invert", desc="invert input image") local_max_file = traits.Either(traits.Bool, File, argstr="--localmax=%s", desc="write an image of the local maxima", hash_files=False) distance_map = File(genfile=True, argstr="--out=%s", desc="distance map to write", hash_files=False) class DistanceMapOutputSpec(TraitedSpec): distance_map = File(exists=True, desc="value is distance to nearest nonzero voxels") local_max_file = File(desc="image of local maxima") class DistanceMap(FSLCommand): """Use FSL's distancemap to generate a map of the distance to the nearest nonzero voxel. Example ------- >>> import nipype.interfaces.fsl as fsl >>> mapper = fsl.DistanceMap() >>> mapper.inputs.in_file = "skeleton_mask.nii.gz" >>> mapper.run() # doctest: +SKIP """ _cmd = "distancemap" input_spec = DistanceMapInputSpec output_spec = DistanceMapOutputSpec def _format_arg(self, name, spec, value): if name == "local_max_file": if isinstance(value, bool): return spec.argstr % self._list_outputs()["local_max_file"] return super(DistanceMap, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() _si = self.inputs outputs["distance_map"] = _si.distance_map if not isdefined(_si.distance_map): outputs["distance_map"] = fname_presuffix(_si.in_file, suffix="_dstmap", use_ext=True, newpath=os.getcwd()) outputs["distance_map"] = os.path.abspath(outputs["distance_map"]) if isdefined(_si.local_max_file): outputs["local_max_file"] = _si.local_max_file if isinstance(_si.local_max_file, bool): outputs["local_max_file"] = fname_presuffix(_si.in_file, suffix="_lclmax", use_ext=True, newpath=os.getcwd()) outputs["local_max_file"] = os.path.abspath(outputs["local_max_file"]) return outputs def _gen_filename(self, name): if name == "distance_map": return self._list_outputs()["distance_map"] return None class MakeDyadicVectorsInputSpec(FSLCommandInputSpec): theta_vol = File(exists=True, mandatory=True, position=0, argstr="%s") phi_vol = File(exists=True, mandatory=True, position=1, argstr="%s") mask = File(exists=True, position=2, argstr="%s") output = File("dyads", position=3, usedefault=True, argstr="%s", hash_files=False) perc = traits.Float(desc="the {perc}% angle of the output cone of \ uncertainty (output will be in degrees)", position=4, argstr="%f") class MakeDyadicVectorsOutputSpec(TraitedSpec): dyads = File(exists=True) dispersion = File(exists=True) class MakeDyadicVectors(FSLCommand): """Create vector volume representing mean principal diffusion direction and its uncertainty (dispersion)""" _cmd = "make_dyadic_vectors" input_spec = MakeDyadicVectorsInputSpec output_spec = MakeDyadicVectorsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs["dyads"] = self._gen_fname(self.inputs.output) outputs["dispersion"] = self._gen_fname(self.inputs.output, suffix="_dispersion") return outputs nipype-0.11.0/nipype/interfaces/fsl/epi.py000066400000000000000000001124271257611314500204530ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 5.0.4. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__)) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os from glob import glob import warnings import numpy as np import nibabel as nib from nipype.interfaces.fsl.base import FSLCommand, FSLCommandInputSpec, Info from nipype.interfaces.base import (traits, TraitedSpec, InputMultiPath, File, isdefined, Undefined) from nipype.utils.filemanip import (load_json, save_json, split_filename, fname_presuffix) warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class PrepareFieldmapInputSpec(FSLCommandInputSpec): scanner = traits.String('SIEMENS', argstr='%s', position=1, desc='must be SIEMENS', usedefault=True) in_phase = File(exists=True, argstr='%s', position=2, mandatory=True, desc=('Phase difference map, in SIEMENS format range from ' '0-4096 or 0-8192)')) in_magnitude = File(exists=True, argstr='%s', position=3, mandatory=True, desc='Magnitude difference map, brain extracted') delta_TE = traits.Float(2.46, usedefault=True, mandatory=True, argstr='%f', position=-2, desc=('echo time difference of the ' 'fieldmap sequence in ms. (usually 2.46ms in' ' Siemens)')) nocheck = traits.Bool(False, position=-1, argstr='--nocheck', usedefault=True, desc=('do not perform sanity checks for image ' 'size/range/dimensions')) out_fieldmap = File(argstr='%s', position=4, desc='output name for prepared fieldmap') class PrepareFieldmapOutputSpec(TraitedSpec): out_fieldmap = File(exists=True, desc='output name for prepared fieldmap') class PrepareFieldmap(FSLCommand): """ Interface for the fsl_prepare_fieldmap script (FSL 5.0) Prepares a fieldmap suitable for FEAT from SIEMENS data - saves output in rad/s format (e.g. ```fsl_prepare_fieldmap SIEMENS images_3_gre_field_mapping images_4_gre_field_mapping fmap_rads 2.65```). Examples -------- >>> from nipype.interfaces.fsl import PrepareFieldmap >>> prepare = PrepareFieldmap() >>> prepare.inputs.in_phase = "phase.nii" >>> prepare.inputs.in_magnitude = "magnitude.nii" >>> prepare.inputs.output_type = "NIFTI_GZ" >>> prepare.cmdline #doctest: +ELLIPSIS 'fsl_prepare_fieldmap SIEMENS phase.nii magnitude.nii \ .../phase_fslprepared.nii.gz 2.460000' >>> res = prepare.run() # doctest: +SKIP """ _cmd = 'fsl_prepare_fieldmap' input_spec = PrepareFieldmapInputSpec output_spec = PrepareFieldmapOutputSpec def _parse_inputs(self, skip=None): if skip is None: skip = [] if not isdefined(self.inputs.out_fieldmap): self.inputs.out_fieldmap = self._gen_fname( self.inputs.in_phase, suffix='_fslprepared') if not isdefined(self.inputs.nocheck) or not self.inputs.nocheck: skip += ['nocheck'] return super(PrepareFieldmap, self)._parse_inputs(skip=skip) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_fieldmap'] = self.inputs.out_fieldmap return outputs def _run_interface(self, runtime): runtime = super(PrepareFieldmap, self)._run_interface(runtime) if runtime.returncode == 0: out_file = self.inputs.out_fieldmap im = nib.load(out_file) dumb_img = nib.Nifti1Image(np.zeros(im.get_shape()), im.get_affine(), im.get_header()) out_nii = nib.funcs.concat_images((im, dumb_img)) nib.save(out_nii, out_file) return runtime class TOPUPInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, desc='name of 4D file with images', argstr='--imain=%s') encoding_file = File(exists=True, mandatory=True, xor=['encoding_direction'], desc='name of text file with PE directions/times', argstr='--datain=%s') encoding_direction = traits.List(traits.Enum('y', 'x', 'z', 'x-', 'y-', 'z-'), mandatory=True, xor=['encoding_file'], requires=['readout_times'], argstr='--datain=%s', desc=('encoding direction for automatic ' 'generation of encoding_file')) readout_times = InputMultiPath(traits.Float, requires=['encoding_direction'], xor=['encoding_file'], mandatory=True, desc=('readout times (dwell times by # ' 'phase-encode steps minus 1)')) out_base = File(desc=('base-name of output files (spline ' 'coefficients (Hz) and movement parameters)'), name_source=['in_file'], name_template='%s_base', argstr='--out=%s', hash_files=False) out_field = File(argstr='--fout=%s', hash_files=False, name_source=['in_file'], name_template='%s_field', desc='name of image file with field (Hz)') out_corrected = File(argstr='--iout=%s', hash_files=False, name_source=['in_file'], name_template='%s_corrected', desc='name of 4D image file with unwarped images') out_logfile = File(argstr='--logout=%s', desc='name of log-file', name_source=['in_file'], name_template='%s_topup.log', keep_extension=True, hash_files=False) # TODO: the following traits admit values separated by commas, one value # per registration level inside topup. warp_res = traits.Float(10.0, argstr='--warpres=%f', desc=('(approximate) resolution (in mm) of warp ' 'basis for the different sub-sampling levels' '.')) subsamp = traits.Int(1, argstr='--subsamp=%d', desc='sub-sampling scheme') fwhm = traits.Float(8.0, argstr='--fwhm=%f', desc='FWHM (in mm) of gaussian smoothing kernel') config = traits.String('b02b0.cnf', argstr='--config=%s', usedefault=True, desc=('Name of config file specifying command line ' 'arguments')) max_iter = traits.Int(5, argstr='--miter=%d', desc='max # of non-linear iterations') reg_lambda = traits.Float(1.0, argstr='--miter=%0.f', desc=('lambda weighting value of the ' 'regularisation term')) ssqlambda = traits.Enum(1, 0, argstr='--ssqlambda=%d', desc=('Weight lambda by the current value of the ' 'ssd. If used (=1), the effective weight of ' 'regularisation term becomes higher for the ' 'initial iterations, therefore initial steps' ' are a little smoother than they would ' 'without weighting. This reduces the ' 'risk of finding a local minimum.')) regmod = traits.Enum('bending_energy', 'membrane_energy', argstr='--regmod=%s', desc=('Regularisation term implementation. Defaults ' 'to bending_energy. Note that the two functions' ' have vastly different scales. The membrane ' 'energy is based on the first derivatives and ' 'the bending energy on the second derivatives. ' 'The second derivatives will typically be much ' 'smaller than the first derivatives, so input ' 'lambda will have to be larger for ' 'bending_energy to yield approximately the same' ' level of regularisation.')) estmov = traits.Enum(1, 0, argstr='--estmov=%d', desc='estimate movements if set') minmet = traits.Enum(0, 1, argstr='--minmet=%d', desc=('Minimisation method 0=Levenberg-Marquardt, ' '1=Scaled Conjugate Gradient')) splineorder = traits.Int(3, argstr='--splineorder=%d', desc=('order of spline, 2->Qadratic spline, ' '3->Cubic spline')) numprec = traits.Enum('double', 'float', argstr='--numprec=%s', desc=('Precision for representing Hessian, double ' 'or float.')) interp = traits.Enum('spline', 'linear', argstr='--interp=%s', desc='Image interpolation model, linear or spline.') scale = traits.Enum(0, 1, argstr='--scale=%d', desc=('If set (=1), the images are individually scaled' ' to a common mean')) regrid = traits.Enum(1, 0, argstr='--regrid=%d', desc=('If set (=1), the calculations are done in a ' 'different grid')) class TOPUPOutputSpec(TraitedSpec): out_fieldcoef = File(exists=True, desc='file containing the field coefficients') out_movpar = File(exists=True, desc='movpar.txt output file') out_enc_file = File(desc='encoding directions file output for applytopup') out_field = File(desc='name of image file with field (Hz)') out_corrected = File(desc='name of 4D image file with unwarped images') out_logfile = File(desc='name of log-file') class TOPUP(FSLCommand): """ Interface for FSL topup, a tool for estimating and correcting susceptibility induced distortions. See FSL documentation for `reference `_, `usage examples `_, and `exemplary config files `_. Examples -------- >>> from nipype.interfaces.fsl import TOPUP >>> topup = TOPUP() >>> topup.inputs.in_file = "b0_b0rev.nii" >>> topup.inputs.encoding_file = "topup_encoding.txt" >>> topup.inputs.output_type = "NIFTI_GZ" >>> topup.cmdline #doctest: +ELLIPSIS 'topup --config=b02b0.cnf --datain=topup_encoding.txt \ --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz \ --fout=b0_b0rev_field.nii.gz --logout=b0_b0rev_topup.log' >>> res = topup.run() # doctest: +SKIP """ _cmd = 'topup' input_spec = TOPUPInputSpec output_spec = TOPUPOutputSpec def _format_arg(self, name, trait_spec, value): if name == 'encoding_direction': return trait_spec.argstr % self._generate_encfile() if name == 'out_base': path, name, ext = split_filename(value) if path != '': if not os.path.exists(path): raise ValueError('out_base path must exist if provided') return super(TOPUP, self)._format_arg(name, trait_spec, value) def _list_outputs(self): outputs = super(TOPUP, self)._list_outputs() del outputs['out_base'] base_path = None if isdefined(self.inputs.out_base): base_path, base, _ = split_filename(self.inputs.out_base) if base_path == '': base_path = None else: base = split_filename(self.inputs.in_file)[1] + '_base' outputs['out_fieldcoef'] = self._gen_fname(base, suffix='_fieldcoef', cwd=base_path) outputs['out_movpar'] = self._gen_fname(base, suffix='_movpar', ext='.txt', cwd=base_path) if isdefined(self.inputs.encoding_direction): outputs['out_enc_file'] = self._get_encfilename() return outputs def _get_encfilename(self): out_file = os.path.join(os.getcwd(), ('%s_encfile.txt' % split_filename(self.inputs.in_file)[1])) return out_file def _generate_encfile(self): """Generate a topup compatible encoding file based on given directions """ out_file = self._get_encfilename() durations = self.inputs.readout_times if len(self.inputs.encoding_direction) != len(durations): if len(self.inputs.readout_times) != 1: raise ValueError(('Readout time must be a float or match the' 'length of encoding directions')) durations = durations * len(self.inputs.encoding_direction) lines = [] for idx, encdir in enumerate(self.inputs.encoding_direction): direction = 1.0 if encdir.endswith('-'): direction = -1.0 line = [float(val[0] == encdir[0]) * direction for val in ['x', 'y', 'z']] + [durations[idx]] lines.append(line) np.savetxt(out_file, np.array(lines), fmt='%d %d %d %.8f') return out_file def _overload_extension(self, value, name=None): if name == 'out_base': return value return super(TOPUP, self)._overload_extension(value, name) class ApplyTOPUPInputSpec(FSLCommandInputSpec): in_files = InputMultiPath(File(exists=True), mandatory=True, desc='name of 4D file with images', argstr='--imain=%s', sep=',') encoding_file = File(exists=True, mandatory=True, desc='name of text file with PE directions/times', argstr='--datain=%s') in_index = traits.List(traits.Int, argstr='--inindex=%s', sep=',', mandatory=True, desc=('comma separated list of indicies into ' '--datain of the input image (to be ' 'corrected)')) in_topup_fieldcoef = File(exists=True, argstr="--topup=%s", copyfile=False, requires=['in_topup_movpar'], desc=('topup file containing the field ' 'coefficients')) in_topup_movpar = File(exists=True, requires=['in_topup_fieldcoef'], copyfile=False, desc='topup movpar.txt file') out_corrected = File(desc='output (warped) image', name_source=['in_files'], name_template='%s_corrected', argstr='--out=%s') method = traits.Enum('jac', 'lsr', argstr='--method=%s', desc=('use jacobian modulation (jac) or least-squares' ' resampling (lsr)')) interp = traits.Enum('trilinear', 'spline', argstr='--interp=%s', desc='interpolation method') datatype = traits.Enum('char', 'short', 'int', 'float', 'double', argstr='-d=%s', desc='force output data type') class ApplyTOPUPOutputSpec(TraitedSpec): out_corrected = File(exists=True, desc=('name of 4D image file with ' 'unwarped images')) class ApplyTOPUP(FSLCommand): """ Interface for FSL topup, a tool for estimating and correcting susceptibility induced distortions. `General reference `_ and `use example `_. Examples -------- >>> from nipype.interfaces.fsl import ApplyTOPUP >>> applytopup = ApplyTOPUP() >>> applytopup.inputs.in_files = ["epi.nii", "epi_rev.nii"] >>> applytopup.inputs.encoding_file = "topup_encoding.txt" >>> applytopup.inputs.in_index = [1,2] >>> applytopup.inputs.in_topup_fieldcoef = "topup_fieldcoef.nii.gz" >>> applytopup.inputs.in_topup_movpar = "topup_movpar.txt" >>> applytopup.inputs.output_type = "NIFTI_GZ" >>> applytopup.cmdline #doctest: +ELLIPSIS 'applytopup --datain=topup_encoding.txt --imain=epi.nii,epi_rev.nii \ --inindex=1,2 --topup=topup --out=epi_corrected.nii.gz' >>> res = applytopup.run() # doctest: +SKIP """ _cmd = 'applytopup' input_spec = ApplyTOPUPInputSpec output_spec = ApplyTOPUPOutputSpec def _format_arg(self, name, spec, value): if name == 'in_topup_fieldcoef': return spec.argstr % value.split('_fieldcoef')[0] return super(ApplyTOPUP, self)._format_arg(name, spec, value) class EddyInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr='--imain=%s', desc=('File containing all the images to estimate ' 'distortions for')) in_mask = File(exists=True, mandatory=True, argstr='--mask=%s', desc='Mask to indicate brain') in_index = File(exists=True, mandatory=True, argstr='--index=%s', desc=('File containing indices for all volumes in --imain ' 'into --acqp and --topup')) in_acqp = File(exists=True, mandatory=True, argstr='--acqp=%s', desc='File containing acquisition parameters') in_bvec = File(exists=True, mandatory=True, argstr='--bvecs=%s', desc=('File containing the b-vectors for all volumes in ' '--imain')) in_bval = File(exists=True, mandatory=True, argstr='--bvals=%s', desc=('File containing the b-values for all volumes in ' '--imain')) out_base = traits.Unicode('eddy_corrected', argstr='--out=%s', usedefault=True, desc=('basename for output (warped) image')) session = File(exists=True, argstr='--session=%s', desc=('File containing session indices for all volumes in ' '--imain')) in_topup_fieldcoef = File(exists=True, argstr="--topup=%s", requires=['in_topup_movpar'], desc=('topup file containing the field ' 'coefficients')) in_topup_movpar = File(exists=True, requires=['in_topup_fieldcoef'], desc='topup movpar.txt file') flm = traits.Enum('linear', 'quadratic', 'cubic', argstr='--flm=%s', desc='First level EC model') fwhm = traits.Float(desc=('FWHM for conditioning filter when estimating ' 'the parameters'), argstr='--fwhm=%s') niter = traits.Int(5, argstr='--niter=%s', desc='Number of iterations') method = traits.Enum('jac', 'lsr', argstr='--resamp=%s', desc=('Final resampling method (jacobian/least ' 'squares)')) repol = traits.Bool(False, argstr='--repol', desc='Detect and replace outlier slices') num_threads = traits.Int(1, usedefault=True, nohash=True, desc="Number of openmp threads to use") class EddyOutputSpec(TraitedSpec): out_corrected = File(exists=True, desc=('4D image file containing all the corrected ' 'volumes')) out_parameter = File(exists=True, desc=('text file with parameters definining the ' 'field and movement for each scan')) class Eddy(FSLCommand): """ Interface for FSL eddy, a tool for estimating and correcting eddy currents induced distortions. `User guide `_ and `more info regarding acqp file `_. Examples -------- >>> from nipype.interfaces.fsl import Eddy >>> eddy = Eddy() >>> eddy.inputs.in_file = 'epi.nii' >>> eddy.inputs.in_mask = 'epi_mask.nii' >>> eddy.inputs.in_index = 'epi_index.txt' >>> eddy.inputs.in_acqp = 'epi_acqp.txt' >>> eddy.inputs.in_bvec = 'bvecs.scheme' >>> eddy.inputs.in_bval = 'bvals.scheme' >>> eddy.cmdline #doctest: +ELLIPSIS 'eddy --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme \ --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii \ --out=.../eddy_corrected' >>> res = eddy.run() # doctest: +SKIP """ _cmd = 'eddy' input_spec = EddyInputSpec output_spec = EddyOutputSpec _num_threads = 1 def __init__(self, **inputs): super(Eddy, self).__init__(**inputs) self.inputs.on_trait_change(self._num_threads_update, 'num_threads') if not isdefined(self.inputs.num_threads): self.inputs.num_threads = self._num_threads else: self._num_threads_update() def _num_threads_update(self): self._num_threads = self.inputs.num_threads if not isdefined(self.inputs.num_threads): if 'OMP_NUM_THREADS' in self.inputs.environ: del self.inputs.environ['OMP_NUM_THREADS'] else: self.inputs.environ['OMP_NUM_THREADS'] = str(self.inputs.num_threads) def _format_arg(self, name, spec, value): if name == 'in_topup_fieldcoef': return spec.argstr % value.split('_fieldcoef')[0] if name == 'out_base': return spec.argstr % os.path.abspath(value) return super(Eddy, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_corrected'] = os.path.abspath('%s.nii.gz' % self.inputs.out_base) outputs['out_parameter'] = os.path.abspath('%s.eddy_parameters' % self.inputs.out_base) return outputs class SigLossInputSpec(FSLCommandInputSpec): in_file = File(mandatory=True, exists=True, argstr='-i %s', desc='b0 fieldmap file') out_file = File(argstr='-s %s', desc='output signal loss estimate file', genfile=True) mask_file = File(exists=True, argstr='-m %s', desc='brain mask file') echo_time = traits.Float(argstr='--te=%f', desc='echo time in seconds') slice_direction = traits.Enum('x', 'y', 'z', argstr='-d %s', desc='slicing direction') class SigLossOuputSpec(TraitedSpec): out_file = File(exists=True, desc='signal loss estimate file') class SigLoss(FSLCommand): """ Estimates signal loss from a field map (in rad/s) Examples -------- >>> from nipype.interfaces.fsl import SigLoss >>> sigloss = SigLoss() >>> sigloss.inputs.in_file = "phase.nii" >>> sigloss.inputs.echo_time = 0.03 >>> sigloss.inputs.output_type = "NIFTI_GZ" >>> sigloss.cmdline #doctest: +ELLIPSIS 'sigloss --te=0.030000 -i phase.nii -s .../phase_sigloss.nii.gz' >>> res = sigloss.run() # doctest: +SKIP """ input_spec = SigLossInputSpec output_spec = SigLossOuputSpec _cmd = 'sigloss' def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if ((not isdefined(outputs['out_file'])) and (isdefined(self.inputs.in_file))): outputs['out_file'] = self._gen_fname(self.inputs.in_file, suffix='_sigloss') return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['out_file'] return None class EpiRegInputSpec(FSLCommandInputSpec): epi = File(exists=True, argstr='--epi=%s', mandatory=True, position=-4, desc='EPI image') t1_head = File(exists=True, argstr='--t1=%s', mandatory=True, position=-3, desc='wholehead T1 image') t1_brain = File(exists=True, argstr='--t1brain=%s', mandatory=True, position=-2, desc='brain extracted T1 image') out_base = traits.String("epi2struct", desc='output base name', argstr='--out=%s', position=-1, usedefault=True) fmap = File(exists=True, argstr='--fmap=%s', desc='fieldmap image (in rad/s)') fmapmag = File(exists=True, argstr='--fmapmag=%s', desc='fieldmap magnitude image - wholehead') fmapmagbrain = File(exists=True, argstr='--fmapmagbrain=%s', desc='fieldmap magnitude image - brain extracted') wmseg = File(exists=True, argstr='--wmseg=%s', desc='white matter segmentation of T1 image, has to be named \ like the t1brain and end on _wmseg') echospacing = traits.Float(argstr='--echospacing=%f', desc='Effective EPI echo spacing \ (sometimes called dwell time) - in seconds') pedir = traits.Enum('x', 'y', 'z', '-x', '-y', '-z', argstr='--pedir=%s', desc='phase encoding direction, dir = x/y/z/-x/-y/-z') weight_image = File(exists=True, argstr='--weight=%s', desc='weighting image (in T1 space)') no_fmapreg = traits.Bool(False, argstr='--nofmapreg', desc='do not perform registration of fmap to T1 \ (use if fmap already registered)') no_clean = traits.Bool(False, argstr='--noclean', desc='do not clean up intermediate files') class EpiRegOutputSpec(TraitedSpec): out_file = File(exists=True, desc='unwarped and coregistered epi input') out_1vol = File(exists=True, desc='unwarped and coregistered single volume') fmap2str_mat = File(exists=True, desc='rigid fieldmap-to-structural transform') fmap2epi_mat = File(exists=True, desc='rigid fieldmap-to-epi transform') fmap_epi = File(exists=True, desc='fieldmap in epi space') fmap_str = File(exists=True, desc='fieldmap in structural space') fmapmag_str = File(exists=True, desc='fieldmap magnitude image in structural space') epi2str_inv = File(exists=True, desc='rigid structural-to-epi transform') epi2str_mat = File(exists=True, desc='rigid epi-to-structural transform') shiftmap = File(exists=True, desc='shiftmap in epi space') fullwarp = File(exists=True, desc='warpfield to unwarp epi and transform into \ structural space') wmseg = File(exists=True, desc='white matter segmentation used in flirt bbr') wmedge = File(exists=True, desc='white matter edges for visualization') class EpiReg(FSLCommand): """ Runs FSL epi_reg script for simultaneous coregistration and fieldmap unwarping. Examples -------- >>> from nipype.interfaces.fsl import EpiReg >>> epireg = EpiReg() >>> epireg.inputs.epi='epi.nii' >>> epireg.inputs.t1_head='T1.nii' >>> epireg.inputs.t1_brain='T1_brain.nii' >>> epireg.inputs.out_base='epi2struct' >>> epireg.inputs.fmap='fieldmap_phase_fslprepared.nii' >>> epireg.inputs.fmapmag='fieldmap_mag.nii' >>> epireg.inputs.fmapmagbrain='fieldmap_mag_brain.nii' >>> epireg.inputs.echospacing=0.00067 >>> epireg.inputs.pedir='y' >>> epireg.cmdline #doctest: +ELLIPSIS 'epi_reg --echospacing=0.000670 --fmap=fieldmap_phase_fslprepared.nii \ --fmapmag=fieldmap_mag.nii --fmapmagbrain=fieldmap_mag_brain.nii --pedir=y \ --epi=epi.nii --t1=T1.nii --t1brain=T1_brain.nii --out=epi2struct' >>> epireg.run() # doctest: +SKIP """ _cmd = 'epi_reg' input_spec = EpiRegInputSpec output_spec = EpiRegOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = os.path.join(os.getcwd(), self.inputs.out_base + '.nii.gz') if not (isdefined(self.inputs.no_fmapreg) and self.inputs.no_fmapreg) and isdefined(self.inputs.fmap): outputs['out_1vol'] = os.path.join(os.getcwd(), self.inputs.out_base + '_1vol.nii.gz') outputs['fmap2str_mat'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmap2str.mat') outputs['fmap2epi_mat'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmaprads2epi.mat') outputs['fmap_epi'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmaprads2epi.nii.gz') outputs['fmap_str'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmaprads2str.ni `i.gz') outputs['fmapmag_str'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmap2str.nii.gz') outputs['shiftmap'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fieldmaprads2epi_shift.nii.gz') outputs['fullwarp'] = os.path.join(os.getcwd(), self.inputs.out_base + '_warp.nii.gz') outputs['epi2str_inv'] = os.path.join(os.getcwd(), self.inputs.out_base + '_inv.mat') outputs['epi2str_mat'] = os.path.join(os.getcwd(), self.inputs.out_base + '.mat') outputs['wmedge'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fast_wmedge.nii.gz') outputs['wmseg'] = os.path.join(os.getcwd(), self.inputs.out_base + '_fast_wmseg.nii.gz') return outputs ####################################### # deprecated interfaces ####################################### class EPIDeWarpInputSpec(FSLCommandInputSpec): mag_file = File(exists=True, desc='Magnitude file', argstr='--mag %s', position=0, mandatory=True) dph_file = File(exists=True, desc='Phase file assumed to be scaled from 0 to 4095', argstr='--dph %s', mandatory=True) exf_file = File(exists=True, desc='example func volume (or use epi)', argstr='--exf %s') epi_file = File(exists=True, desc='EPI volume to unwarp', argstr='--epi %s') tediff = traits.Float(2.46, usedefault=True, desc='difference in B0 field map TEs', argstr='--tediff %s') esp = traits.Float(0.58, desc='EPI echo spacing', argstr='--esp %s', usedefault=True) sigma = traits.Int(2, usedefault=True, argstr='--sigma %s', desc="2D spatial gaussing smoothing \ stdev (default = 2mm)") vsm = traits.String(genfile=True, desc='voxel shift map', argstr='--vsm %s') exfdw = traits.String(desc='dewarped example func volume', genfile=True, argstr='--exfdw %s') epidw = traits.String(desc='dewarped epi volume', genfile=False, argstr='--epidw %s') tmpdir = traits.String(genfile=True, desc='tmpdir', argstr='--tmpdir %s') nocleanup = traits.Bool(True, usedefault=True, desc='no cleanup', argstr='--nocleanup') cleanup = traits.Bool(desc='cleanup', argstr='--cleanup') class EPIDeWarpOutputSpec(TraitedSpec): unwarped_file = File(desc="unwarped epi file") vsm_file = File(desc="voxel shift map") exfdw = File(desc="dewarped functional volume example") exf_mask = File(desc="Mask from example functional volume") class EPIDeWarp(FSLCommand): """ Wraps the unwarping script `epidewarp.fsl `_. .. warning:: deprecated in FSL, please use :func:`nipype.workflows.dmri.preprocess.epi.sdc_fmb` instead. Examples -------- >>> from nipype.interfaces.fsl import EPIDeWarp >>> dewarp = EPIDeWarp() >>> dewarp.inputs.epi_file = "functional.nii" >>> dewarp.inputs.mag_file = "magnitude.nii" >>> dewarp.inputs.dph_file = "phase.nii" >>> dewarp.inputs.output_type = "NIFTI_GZ" >>> dewarp.cmdline #doctest: +ELLIPSIS 'epidewarp.fsl --mag magnitude.nii --dph phase.nii --epi functional.nii \ --esp 0.58 --exfdw .../exfdw.nii.gz --nocleanup --sigma 2 --tediff 2.46 \ --tmpdir .../temp --vsm .../vsm.nii.gz' >>> res = dewarp.run() # doctest: +SKIP """ _cmd = 'epidewarp.fsl' input_spec = EPIDeWarpInputSpec output_spec = EPIDeWarpOutputSpec def __init__(self, **inputs): warnings.warn(("Deprecated: Please use " "nipype.workflows.dmri.preprocess.epi.sdc_fmb instead"), DeprecationWarning) return super(EPIDeWarp, self).__init__(**inputs) def _run_interface(self, runtime): runtime = super(EPIDeWarp, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime def _gen_filename(self, name): if name == 'exfdw': if isdefined(self.inputs.exf_file): return self._gen_fname(self.inputs.exf_file, suffix="_exfdw") else: return self._gen_fname("exfdw") if name == 'epidw': if isdefined(self.inputs.epi_file): return self._gen_fname(self.inputs.epi_file, suffix="_epidw") if name == 'vsm': return self._gen_fname('vsm') if name == 'tmpdir': return os.path.join(os.getcwd(), 'temp') return None def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.exfdw): outputs['exfdw'] = self._gen_filename('exfdw') else: outputs['exfdw'] = self.inputs.exfdw if isdefined(self.inputs.epi_file): if isdefined(self.inputs.epidw): outputs['unwarped_file'] = self.inputs.epidw else: outputs['unwarped_file'] = self._gen_filename('epidw') if not isdefined(self.inputs.vsm): outputs['vsm_file'] = self._gen_filename('vsm') else: outputs['vsm_file'] = self._gen_fname(self.inputs.vsm) if not isdefined(self.inputs.tmpdir): outputs[ 'exf_mask'] = self._gen_fname(cwd=self._gen_filename('tmpdir'), basename='maskexf') else: outputs['exf_mask'] = self._gen_fname(cwd=self.inputs.tmpdir, basename='maskexf') return outputs class EddyCorrectInputSpec(FSLCommandInputSpec): in_file = File(exists=True, desc='4D input file', argstr='%s', position=0, mandatory=True) out_file = File(desc='4D output file', argstr='%s', position=1, name_source=['in_file'], name_template='%s_edc', output_name='eddy_corrected') ref_num = traits.Int(0, argstr='%d', position=2, desc='reference number', mandatory=True, usedefault=True) class EddyCorrectOutputSpec(TraitedSpec): eddy_corrected = File(exists=True, desc='path/name of 4D eddy corrected output file') class EddyCorrect(FSLCommand): """ .. warning:: Deprecated in FSL. Please use :class:`nipype.interfaces.fsl.epi.Eddy` instead Example ------- >>> from nipype.interfaces.fsl import EddyCorrect >>> eddyc = EddyCorrect(in_file='diffusion.nii', ... out_file="diffusion_edc.nii", ref_num=0) >>> eddyc.cmdline 'eddy_correct diffusion.nii diffusion_edc.nii 0' """ _cmd = 'eddy_correct' input_spec = EddyCorrectInputSpec output_spec = EddyCorrectOutputSpec def __init__(self, **inputs): warnings.warn(("Deprecated: Please use nipype.interfaces.fsl.epi.Eddy " "instead"), DeprecationWarning) return super(EddyCorrect, self).__init__(**inputs) def _run_interface(self, runtime): runtime = super(EddyCorrect, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime nipype-0.11.0/nipype/interfaces/fsl/maths.py000066400000000000000000000257041257611314500210130ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ The maths module provides higher-level interfaces to some of the operations that can be performed with the fslmaths command-line program. """ import os import numpy as np from nipype.interfaces.fsl.base import FSLCommand, FSLCommandInputSpec from nipype.interfaces.base import (TraitedSpec, File, traits, InputMultiPath, isdefined) class MathsInput(FSLCommandInputSpec): in_file = File(position=2, argstr="%s", exists=True, mandatory=True, desc="image to operate on") out_file = File(genfile=True, position=-2, argstr="%s", desc="image to write", hash_files=False) _dtypes = ["float", "char", "int", "short", "double", "input"] internal_datatype = traits.Enum(*_dtypes, position=1, argstr="-dt %s", desc="datatype to use for calculations (default is float)") output_datatype = traits.Enum(*_dtypes, position=-1, argstr="-odt %s", desc="datatype to use for output (default uses input type)") nan2zeros = traits.Bool(position=3, argstr='-nan', desc='change NaNs to zeros before doing anything') class MathsOutput(TraitedSpec): out_file = File(exists=True, desc="image written after calculations") class MathsCommand(FSLCommand): _cmd = "fslmaths" input_spec = MathsInput output_spec = MathsOutput _suffix = "_maths" def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = self.inputs.out_file if not isdefined(self.inputs.out_file): outputs["out_file"] = self._gen_fname(self.inputs.in_file, suffix=self._suffix) outputs["out_file"] = os.path.abspath(outputs["out_file"]) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()["out_file"] return None class ChangeDataTypeInput(MathsInput): _dtypes = ["float", "char", "int", "short", "double", "input"] output_datatype = traits.Enum(*_dtypes, position=-1, argstr="-odt %s", mandatory=True, desc="output data type") class ChangeDataType(MathsCommand): """Use fslmaths to change the datatype of an image. """ input_spec = ChangeDataTypeInput _suffix = "_chdt" class ThresholdInputSpec(MathsInput): thresh = traits.Float(mandatory=True, position=4, argstr="%s", desc="threshold value") direction = traits.Enum("below", "above", usedefault=True, desc="zero-out either below or above thresh value") use_robust_range = traits.Bool(desc="inteperet thresh as percentage (0-100) of robust range") use_nonzero_voxels = traits.Bool(desc="use nonzero voxels to caluclate robust range", requires=["use_robust_range"]) class Threshold(MathsCommand): """Use fslmaths to apply a threshold to an image in a variety of ways. """ input_spec = ThresholdInputSpec _suffix = "_thresh" def _format_arg(self, name, spec, value): if name == "thresh": arg = "-" _si = self.inputs if self.inputs.direction == "above": arg += "u" arg += "thr" if isdefined(_si.use_robust_range) and _si.use_robust_range: if isdefined(_si.use_nonzero_voxels) and _si.use_nonzero_voxels: arg += "P" else: arg += "p" arg += " %.10f" % value return arg return super(Threshold, self)._format_arg(name, spec, value) class MeanImageInput(MathsInput): dimension = traits.Enum("T", "X", "Y", "Z", usedefault=True, argstr="-%smean", position=4, desc="dimension to mean across") class MeanImage(MathsCommand): """Use fslmaths to generate a mean image across a given dimension. """ input_spec = MeanImageInput _suffix = "_mean" class MaxImageInput(MathsInput): dimension = traits.Enum("T", "X", "Y", "Z", usedefault=True, argstr="-%smax", position=4, desc="dimension to max across") class MaxImage(MathsCommand): """Use fslmaths to generate a max image across a given dimension. Examples -------- from nipype.interfaces.fsl.maths import MaxImage maxer = MaxImage() maxer.inputs.in_file = "functional.nii" maxer.dimension = "T" maths.cmdline fslmaths functional.nii -Tmax functional_max.nii """ input_spec = MaxImageInput _suffix = "_max" class IsotropicSmoothInput(MathsInput): fwhm = traits.Float(mandatory=True, xor=["sigma"], position=4, argstr="-s %.5f", desc="fwhm of smoothing kernel [mm]") sigma = traits.Float(mandatory=True, xor=["fwhm"], position=4, argstr="-s %.5f", desc="sigma of smoothing kernel [mm]") class IsotropicSmooth(MathsCommand): """Use fslmaths to spatially smooth an image with a gaussian kernel. """ input_spec = IsotropicSmoothInput _suffix = "_smooth" def _format_arg(self, name, spec, value): if name == "fwhm": sigma = float(value) / np.sqrt(8 * np.log(2)) return spec.argstr % sigma return super(IsotropicSmooth, self)._format_arg(name, spec, value) class ApplyMaskInput(MathsInput): mask_file = File(exists=True, mandatory=True, argstr="-mas %s", position=4, desc="binary image defining mask space") class ApplyMask(MathsCommand): """Use fslmaths to apply a binary mask to another image. """ input_spec = ApplyMaskInput _suffix = "_masked" class KernelInput(MathsInput): kernel_shape = traits.Enum("3D", "2D", "box", "boxv", "gauss", "sphere", "file", argstr="-kernel %s", position=4, desc="kernel shape to use") kernel_size = traits.Float(argstr="%.4f", position=5, xor=["kernel_file"], desc="kernel size - voxels for box/boxv, mm for sphere, mm sigma for gauss") kernel_file = File(exists=True, argstr="%s", position=5, xor=["kernel_size"], desc="use external file for kernel") class DilateInput(KernelInput): operation = traits.Enum("mean", "modal", "max", argstr="-dil%s", position=6, mandatory=True, desc="filtering operation to perfoem in dilation") class DilateImage(MathsCommand): """Use fslmaths to perform a spatial dilation of an image. """ input_spec = DilateInput _suffix = "_dil" def _format_arg(self, name, spec, value): if name == "operation": return spec.argstr % dict(mean="M", modal="D", max="F")[value] return super(DilateImage, self)._format_arg(name, spec, value) class ErodeInput(KernelInput): minimum_filter = traits.Bool(argstr="%s", position=6, usedefault=True, default_value=False, desc="if true, minimum filter rather than erosion by zeroing-out") class ErodeImage(MathsCommand): """Use fslmaths to perform a spatial erosion of an image. """ input_spec = ErodeInput _suffix = "_ero" def _format_arg(self, name, spec, value): if name == "minimum_filter": if value: return "-eroF" return "-ero" return super(ErodeImage, self)._format_arg(name, spec, value) class SpatialFilterInput(KernelInput): operation = traits.Enum("mean", "median", "meanu", argstr="-f%s", position=6, mandatory=True, desc="operation to filter with") class SpatialFilter(MathsCommand): """Use fslmaths to spatially filter an image. """ input_spec = SpatialFilterInput _suffix = "_filt" class UnaryMathsInput(MathsInput): operation = traits.Enum("exp", "log", "sin", "cos", "tan", "asin", "acos", "atan", "sqr", "sqrt", "recip", "abs", "bin", "binv", "fillh", "fillh26", "index", "edge", "nan", "nanm", "rand", "randn", "range", argstr="-%s", position=4, mandatory=True, desc="operation to perform") class UnaryMaths(MathsCommand): """Use fslmaths to perorm a variety of mathematical operations on an image. """ input_spec = UnaryMathsInput def _list_outputs(self): self._suffix = "_" + self.inputs.operation return super(UnaryMaths, self)._list_outputs() class BinaryMathsInput(MathsInput): operation = traits.Enum("add", "sub", "mul", "div", "rem", "max", "min", mandatory=True, argstr="-%s", position=4, desc="operation to perform") operand_file = File(exists=True, argstr="%s", mandatory=True, position=5, xor=["operand_value"], desc="second image to perform operation with") operand_value = traits.Float(argstr="%.8f", mandatory=True, position=5, xor=["operand_file"], desc="value to perform operation with") class BinaryMaths(MathsCommand): """Use fslmaths to perform mathematical operations using a second image or a numeric value. """ input_spec = BinaryMathsInput class MultiImageMathsInput(MathsInput): op_string = traits.String(position=4, argstr="%s", mandatory=True, desc="python formatted string of operations to perform") operand_files = InputMultiPath(File(exists=True), mandatory=True, desc="list of file names to plug into op string") class MultiImageMaths(MathsCommand): """Use fslmaths to perform a sequence of mathematical operations. Examples -------- from nipype.interfaces.fsl import MultiImageMaths maths = MultiImageMaths() maths.inputs.in_file = "functional.nii" maths.inputs.op_string = "-add %s -mul -1 -div %s" maths.inputs.operand_files = ["functional2.nii", "functional3.nii"] maths.inputs.out_file = functional4.nii maths.cmdline fslmaths functional1.nii -add functional2.nii -mul -1 -div functional3.nii functional4.nii """ input_spec = MultiImageMathsInput def _format_arg(self, name, spec, value): if name == "op_string": return value % tuple(self.inputs.operand_files) return super(MultiImageMaths, self)._format_arg(name, spec, value) class TemporalFilterInput(MathsInput): lowpass_sigma = traits.Float(-1, argstr="%.6f", position=5, usedefault=True, desc="lowpass filter sigma (in volumes)") highpass_sigma = traits.Float(-1, argstr="-bptf %.6f", position=4, usedefault=True, desc="highpass filter sigma (in volumes)") class TemporalFilter(MathsCommand): """Use fslmaths to apply a low, high, or bandpass temporal filter to a timeseries. """ input_spec = TemporalFilterInput _suffix = "_filt" nipype-0.11.0/nipype/interfaces/fsl/model.py000066400000000000000000002544761257611314500210110ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 4.1.4. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from glob import glob import warnings from shutil import rmtree import numpy as np from nibabel import load from ... import LooseVersion from .base import (FSLCommand, FSLCommandInputSpec, Info) from ..base import (load_template, File, traits, isdefined, TraitedSpec, BaseInterface, Directory, InputMultiPath, OutputMultiPath, BaseInterfaceInputSpec) from ...utils.filemanip import (list_to_filename, filename_to_list) from ...utils.misc import human_order_sorted warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class Level1DesignInputSpec(BaseInterfaceInputSpec): interscan_interval = traits.Float(mandatory=True, desc='Interscan interval (in secs)') session_info = traits.Any(mandatory=True, desc='Session specific information generated by ``modelgen.SpecifyModel``') bases = traits.Either( traits.Dict(traits.Enum( 'dgamma'), traits.Dict(traits.Enum('derivs'), traits.Bool)), traits.Dict(traits.Enum('gamma'), traits.Dict( traits.Enum('derivs'), traits.Bool)), traits.Dict(traits.Enum('none'), traits.Enum(None)), mandatory=True, desc="name of basis function and options e.g., {'dgamma': {'derivs': True}}") model_serial_correlations = traits.Bool( desc="Option to model serial correlations using an \ autoregressive estimator (order 1). Setting this option is only \ useful in the context of the fsf file. If you set this to False, you need to repeat \ this option for FILMGLS by setting autocorr_noestimate to True", mandatory=True) contrasts = traits.List( traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('F'), traits.List( traits.Either(traits.Tuple(traits.Str, traits.Enum( 'T'), traits.List( traits.Str), traits.List( traits.Float)), traits.Tuple( traits.Str, traits.Enum( 'T'), traits.List( traits.Str), traits.List( traits.Float), traits.List( traits.Float)))))), desc="List of contrasts with each contrast being a list of the form - \ [('name', 'stat', [condition list], [weight list], [session list])]. if \ session list is None or not provided, all sessions are used. For F \ contrasts, the condition list should contain previously defined \ T-contrasts.") class Level1DesignOutputSpec(TraitedSpec): fsf_files = OutputMultiPath(File(exists=True), desc='FSL feat specification files') ev_files = OutputMultiPath(traits.List(File(exists=True)), desc='condition information files') class Level1Design(BaseInterface): """Generate FEAT specific files Examples -------- >>> level1design = Level1Design() >>> level1design.inputs.interscan_interval = 2.5 >>> level1design.inputs.bases = {'dgamma':{'derivs': False}} >>> level1design.inputs.session_info = 'session_info.npz' >>> level1design.run() # doctest: +SKIP """ input_spec = Level1DesignInputSpec output_spec = Level1DesignOutputSpec def _create_ev_file(self, evfname, evinfo): f = open(evfname, 'wt') for i in evinfo: if len(i) == 3: f.write('%f %f %f\n' % (i[0], i[1], i[2])) else: f.write('%f\n' % i[0]) f.close() def _create_ev_files( self, cwd, runinfo, runidx, usetd, contrasts, no_bases, do_tempfilter): """Creates EV files from condition and regressor information. Parameters: ----------- runinfo : dict Generated by `SpecifyModel` and contains information about events and other regressors. runidx : int Index to run number usetd : int Whether or not to use temporal derivatives for conditions contrasts : list of lists Information on contrasts to be evaluated """ conds = {} evname = [] ev_hrf = load_template('feat_ev_hrf.tcl') ev_none = load_template('feat_ev_none.tcl') ev_ortho = load_template('feat_ev_ortho.tcl') ev_txt = '' # generate sections for conditions and other nuisance # regressors num_evs = [0, 0] for field in ['cond', 'regress']: for i, cond in enumerate(runinfo[field]): name = cond['name'] evname.append(name) evfname = os.path.join(cwd, 'ev_%s_%d_%d.txt' % (name, runidx, len(evname))) evinfo = [] num_evs[0] += 1 num_evs[1] += 1 if field == 'cond': for j, onset in enumerate(cond['onset']): try: amplitudes = cond['amplitudes'] if len(amplitudes) > 1: amp = amplitudes[j] else: amp = amplitudes[0] except KeyError: amp = 1 if len(cond['duration']) > 1: evinfo.insert(j, [onset, cond['duration'][j], amp]) else: evinfo.insert(j, [onset, cond['duration'][0], amp]) if no_bases: ev_txt += ev_none.substitute(ev_num=num_evs[0], ev_name=name, tempfilt_yn=do_tempfilter, cond_file=evfname) else: ev_txt += ev_hrf.substitute(ev_num=num_evs[0], ev_name=name, tempfilt_yn=do_tempfilter, temporalderiv=usetd, cond_file=evfname) if usetd: evname.append(name + 'TD') num_evs[1] += 1 elif field == 'regress': evinfo = [[j] for j in cond['val']] ev_txt += ev_none.substitute(ev_num=num_evs[0], ev_name=name, tempfilt_yn=do_tempfilter, cond_file=evfname) ev_txt += "\n" conds[name] = evfname self._create_ev_file(evfname, evinfo) # add ev orthogonalization for i in range(1, num_evs[0] + 1): for j in range(0, num_evs[0] + 1): ev_txt += ev_ortho.substitute(c0=i, c1=j) ev_txt += "\n" # add contrast info to fsf file if isdefined(contrasts): contrast_header = load_template('feat_contrast_header.tcl') contrast_prolog = load_template('feat_contrast_prolog.tcl') contrast_element = load_template('feat_contrast_element.tcl') contrast_ftest_element = load_template( 'feat_contrast_ftest_element.tcl') contrastmask_header = load_template('feat_contrastmask_header.tcl') contrastmask_footer = load_template('feat_contrastmask_footer.tcl') contrastmask_element = load_template( 'feat_contrastmask_element.tcl') # add t/f contrast info ev_txt += contrast_header.substitute() con_names = [] for j, con in enumerate(contrasts): con_names.append(con[0]) con_map = {} ftest_idx = [] ttest_idx = [] for j, con in enumerate(contrasts): if con[1] == 'F': ftest_idx.append(j) for c in con[2]: if c[0] not in con_map.keys(): con_map[c[0]] = [] con_map[c[0]].append(j) else: ttest_idx.append(j) for ctype in ['real', 'orig']: for j, con in enumerate(contrasts): if con[1] == 'F': continue tidx = ttest_idx.index(j) + 1 ev_txt += contrast_prolog.substitute(cnum=tidx, ctype=ctype, cname=con[0]) count = 0 for c in range(1, len(evname) + 1): if evname[c - 1].endswith('TD') and ctype == 'orig': continue count = count + 1 if evname[c - 1] in con[2]: val = con[3][con[2].index(evname[c - 1])] else: val = 0.0 ev_txt += contrast_element.substitute(cnum=tidx, element=count, ctype=ctype, val=val) ev_txt += "\n" if con[0] in con_map.keys(): for fconidx in con_map[con[0]]: ev_txt += contrast_ftest_element.substitute( cnum=ftest_idx.index(fconidx) + 1, element=tidx, ctype=ctype, val=1) ev_txt += "\n" # add contrast mask info ev_txt += contrastmask_header.substitute() for j, _ in enumerate(contrasts): for k, _ in enumerate(contrasts): if j != k: ev_txt += contrastmask_element.substitute(c1=j + 1, c2=k + 1) ev_txt += contrastmask_footer.substitute() return num_evs, ev_txt def _format_session_info(self, session_info): if isinstance(session_info, dict): session_info = [session_info] return session_info def _get_func_files(self, session_info): """Returns functional files in the order of runs """ func_files = [] for i, info in enumerate(session_info): func_files.insert(i, info['scans']) return func_files def _run_interface(self, runtime): cwd = os.getcwd() fsf_header = load_template('feat_header_l1.tcl') fsf_postscript = load_template('feat_nongui.tcl') prewhiten = 0 if isdefined(self.inputs.model_serial_correlations): prewhiten = int(self.inputs.model_serial_correlations) usetd = 0 no_bases = False basis_key = self.inputs.bases.keys()[0] if basis_key in ['dgamma', 'gamma']: usetd = int(self.inputs.bases[basis_key]['derivs']) if basis_key == 'none': no_bases = True session_info = self._format_session_info(self.inputs.session_info) func_files = self._get_func_files(session_info) n_tcon = 0 n_fcon = 0 if isdefined(self.inputs.contrasts): for i, c in enumerate(self.inputs.contrasts): if c[1] == 'T': n_tcon += 1 elif c[1] == 'F': n_fcon += 1 for i, info in enumerate(session_info): do_tempfilter = 1 if info['hpf'] == np.inf: do_tempfilter = 0 num_evs, cond_txt = self._create_ev_files(cwd, info, i, usetd, self.inputs.contrasts, no_bases, do_tempfilter) nim = load(func_files[i]) (_, _, _, timepoints) = nim.get_shape() fsf_txt = fsf_header.substitute(run_num=i, interscan_interval=self.inputs.interscan_interval, num_vols=timepoints, prewhiten=prewhiten, num_evs=num_evs[0], num_evs_real=num_evs[1], num_tcon=n_tcon, num_fcon=n_fcon, high_pass_filter_cutoff=info[ 'hpf'], temphp_yn=do_tempfilter, func_file=func_files[i]) fsf_txt += cond_txt fsf_txt += fsf_postscript.substitute(overwrite=1) f = open(os.path.join(cwd, 'run%d.fsf' % i), 'w') f.write(fsf_txt) f.close() return runtime def _list_outputs(self): outputs = self.output_spec().get() cwd = os.getcwd() outputs['fsf_files'] = [] outputs['ev_files'] = [] usetd = 0 basis_key = self.inputs.bases.keys()[0] if basis_key in ['dgamma', 'gamma']: usetd = int(self.inputs.bases[basis_key]['derivs']) for runno, runinfo in enumerate(self._format_session_info(self.inputs.session_info)): outputs['fsf_files'].append(os.path.join(cwd, 'run%d.fsf' % runno)) outputs['ev_files'].insert(runno, []) evname = [] for field in ['cond', 'regress']: for i, cond in enumerate(runinfo[field]): name = cond['name'] evname.append(name) evfname = os.path.join( cwd, 'ev_%s_%d_%d.txt' % (name, runno, len(evname))) if field == 'cond': if usetd: evname.append(name + 'TD') outputs['ev_files'][runno].append( os.path.join(cwd, evfname)) return outputs class FEATInputSpec(FSLCommandInputSpec): fsf_file = File(exists=True, mandatory=True, argstr="%s", position=0, desc="File specifying the feat design spec file") class FEATOutputSpec(TraitedSpec): feat_dir = Directory(exists=True) class FEAT(FSLCommand): """Uses FSL feat to calculate first level stats """ _cmd = 'feat' input_spec = FEATInputSpec output_spec = FEATOutputSpec def _list_outputs(self): outputs = self._outputs().get() is_ica = False outputs['feat_dir']=None with open(self.inputs.fsf_file, 'rt') as fp: text = fp.read() if "set fmri(inmelodic) 1" in text: is_ica = True for line in text.split('\n'): if line.find("set fmri(outputdir)")>-1: try: outputdir_spec=line.split('"')[-2] if os.path.exists(outputdir_spec): outputs['feat_dir']=outputdir_spec except: pass if not outputs['feat_dir']: if is_ica: outputs['feat_dir'] = glob(os.path.join(os.getcwd(), '*ica'))[0] else: outputs['feat_dir'] = glob(os.path.join(os.getcwd(), '*feat'))[0] print 'Outputs from FEATmodel:',outputs return outputs class FEATModelInputSpec(FSLCommandInputSpec): fsf_file = File(exists=True, mandatory=True, argstr="%s", position=0, desc="File specifying the feat design spec file", copyfile=False) ev_files = traits.List(File(exists=True), mandatory=True, argstr="%s", desc="Event spec files generated by level1design", position=1, copyfile=False) class FEATModelOutpuSpec(TraitedSpec): design_file = File( exists=True, desc='Mat file containing ascii matrix for design') design_image = File( exists=True, desc='Graphical representation of design matrix') design_cov = File( exists=True, desc='Graphical representation of design covariance') con_file = File( exists=True, desc='Contrast file containing contrast vectors') fcon_file = File(desc='Contrast file containing contrast vectors') class FEATModel(FSLCommand): """Uses FSL feat_model to generate design.mat files """ _cmd = 'feat_model' input_spec = FEATModelInputSpec output_spec = FEATModelOutpuSpec def _format_arg(self, name, trait_spec, value): if name == 'fsf_file': return super(FEATModel, self)._format_arg(name, trait_spec, self._get_design_root(value)) elif name == 'ev_files': return '' else: return super(FEATModel, self)._format_arg(name, trait_spec, value) def _get_design_root(self, infile): _, fname = os.path.split(infile) return fname.split('.')[0] def _list_outputs(self): # TODO: figure out file names and get rid off the globs outputs = self._outputs().get() root = self._get_design_root(list_to_filename(self.inputs.fsf_file)) design_file = glob(os.path.join(os.getcwd(), '%s*.mat' % root)) assert len(design_file) == 1, 'No mat file generated by FEAT Model' outputs['design_file'] = design_file[0] design_image = glob(os.path.join(os.getcwd(), '%s.png' % root)) assert len( design_image) == 1, 'No design image generated by FEAT Model' outputs['design_image'] = design_image[0] design_cov = glob(os.path.join(os.getcwd(), '%s_cov.png' % root)) assert len( design_cov) == 1, 'No covariance image generated by FEAT Model' outputs['design_cov'] = design_cov[0] con_file = glob(os.path.join(os.getcwd(), '%s*.con' % root)) assert len(con_file) == 1, 'No con file generated by FEAT Model' outputs['con_file'] = con_file[0] fcon_file = glob(os.path.join(os.getcwd(), '%s*.fts' % root)) if fcon_file: assert len(fcon_file) == 1, 'No fts file generated by FEAT Model' outputs['fcon_file'] = fcon_file[0] return outputs class FILMGLSInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, position=-3, argstr='%s', desc='input data file') design_file = File(exists=True, position=-2, argstr='%s', desc='design matrix file') threshold = traits.Range(default=1000., low=0.0, argstr='%f', position=-1, usedefault=True, desc='threshold') smooth_autocorr = traits.Bool(argstr='-sa', desc='Smooth auto corr estimates') mask_size = traits.Int(argstr='-ms %d', desc="susan mask size") brightness_threshold = traits.Range(low=0, argstr='-epith %d', desc='susan brightness threshold, otherwise it is estimated') full_data = traits.Bool(argstr='-v', desc='output full data') _estimate_xor = ['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'] autocorr_estimate_only = traits.Bool(argstr='-ac', xor=_estimate_xor, desc='perform autocorrelation estimatation only') fit_armodel = traits.Bool(argstr='-ar', xor=_estimate_xor, desc='fits autoregressive model - default is to use tukey with M=sqrt(numvols)') tukey_window = traits.Int(argstr='-tukey %d', xor=_estimate_xor, desc='tukey window size to estimate autocorr') multitaper_product = traits.Int(argstr='-mt %d', xor=_estimate_xor, desc='multitapering with slepian tapers and num is the time-bandwidth product') use_pava = traits.Bool( argstr='-pava', desc='estimates autocorr using PAVA') autocorr_noestimate = traits.Bool(argstr='-noest', xor=_estimate_xor, desc='do not estimate autocorrs') output_pwdata = traits.Bool(argstr='-output_pwdata', desc='output prewhitened data and average design matrix') results_dir = Directory('results', argstr='-rn %s', usedefault=True, desc='directory to store results in') class FILMGLSInputSpec505(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, position=-3, argstr='--in=%s', desc='input data file') design_file = File(exists=True, position=-2, argstr='--pd=%s', desc='design matrix file') threshold = traits.Range(default=1000., low=0.0, argstr='--thr=%f', position=-1, usedefault=True, desc='threshold') smooth_autocorr = traits.Bool(argstr='--sa', desc='Smooth auto corr estimates') mask_size = traits.Int(argstr='--ms=%d', desc="susan mask size") brightness_threshold = traits.Range(low=0, argstr='--epith=%d', desc=('susan brightness threshold, ' 'otherwise it is estimated')) full_data = traits.Bool(argstr='-v', desc='output full data') _estimate_xor = ['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'] autocorr_estimate_only = traits.Bool(argstr='--ac', xor=_estimate_xor, desc=('perform autocorrelation ' 'estimation only')) fit_armodel = traits.Bool(argstr='--ar', xor=_estimate_xor, desc=('fits autoregressive model - default is to ' 'use tukey with M=sqrt(numvols)')) tukey_window = traits.Int(argstr='--tukey=%d', xor=_estimate_xor, desc='tukey window size to estimate autocorr') multitaper_product = traits.Int(argstr='--mt=%d', xor=_estimate_xor, desc=('multitapering with slepian tapers ' 'and num is the time-bandwidth ' 'product')) use_pava = traits.Bool(argstr='--pava', desc='estimates autocorr using PAVA') autocorr_noestimate = traits.Bool(argstr='--noest', xor=_estimate_xor, desc='do not estimate autocorrs') output_pwdata = traits.Bool(argstr='--outputPWdata', desc=('output prewhitened data and average ' 'design matrix')) results_dir = Directory('results', argstr='--rn=%s', usedefault=True, desc='directory to store results in') class FILMGLSInputSpec507(FILMGLSInputSpec505): threshold = traits.Float(default=-1000., argstr='--thr=%f', position=-1, usedefault=True, desc='threshold') tcon_file = File(exists=True, argstr='--con=%s', desc='contrast file containing T-contrasts') fcon_file = File(exists=True, argstr='--fcon=%s', desc='contrast file containing F-contrasts') mode = traits.Enum('volumetric', 'surface', argstr="--mode=%s", desc="Type of analysis to be done") surface = File(exists=True, argstr="--in2=%s", desc=("input surface for autocorr smoothing in " "surface-based analyses")) class FILMGLSOutputSpec(TraitedSpec): param_estimates = OutputMultiPath(File(exists=True), desc='Parameter estimates for each column of the design matrix') residual4d = File(exists=True, desc='Model fit residual mean-squared error for each time point') dof_file = File(exists=True, desc='degrees of freedom') sigmasquareds = File( exists=True, desc='summary of residuals, See Woolrich, et. al., 2001') results_dir = Directory(exists=True, desc='directory storing model estimation output') corrections = File(exists=True, desc='statistical corrections used within FILM modelling') thresholdac = File(exists=True, desc='The FILM autocorrelation parameters') logfile = File(exists=True, desc='FILM run logfile') class FILMGLSOutputSpec507(TraitedSpec): param_estimates = OutputMultiPath(File(exists=True), desc='Parameter estimates for each column of the design matrix') residual4d = File(exists=True, desc='Model fit residual mean-squared error for each time point') dof_file = File(exists=True, desc='degrees of freedom') sigmasquareds = File( exists=True, desc='summary of residuals, See Woolrich, et. al., 2001') results_dir = Directory(exists=True, desc='directory storing model estimation output') thresholdac = File(exists=True, desc='The FILM autocorrelation parameters') logfile = File(exists=True, desc='FILM run logfile') copes = OutputMultiPath(File(exists=True), desc='Contrast estimates for each contrast') varcopes = OutputMultiPath(File(exists=True), desc='Variance estimates for each contrast') zstats = OutputMultiPath(File(exists=True), desc='z-stat file for each contrast') tstats = OutputMultiPath(File(exists=True), desc='t-stat file for each contrast') fstats = OutputMultiPath(File(exists=True), desc='f-stat file for each contrast') zfstats = OutputMultiPath(File(exists=True), desc='z-stat file for each F contrast') class FILMGLS(FSLCommand): """Use FSL film_gls command to fit a design matrix to voxel timeseries Examples -------- Initialize with no options, assigning them when calling run: >>> from nipype.interfaces import fsl >>> fgls = fsl.FILMGLS() >>> res = fgls.run('in_file', 'design_file', 'thresh', rn='stats') #doctest: +SKIP Assign options through the ``inputs`` attribute: >>> fgls = fsl.FILMGLS() >>> fgls.inputs.in_file = 'functional.nii' >>> fgls.inputs.design_file = 'design.mat' >>> fgls.inputs.threshold = 10 >>> fgls.inputs.results_dir = 'stats' >>> res = fgls.run() #doctest: +SKIP Specify options when creating an instance: >>> fgls = fsl.FILMGLS(in_file='functional.nii', \ design_file='design.mat', \ threshold=10, results_dir='stats') >>> res = fgls.run() #doctest: +SKIP """ _cmd = 'film_gls' if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'): input_spec = FILMGLSInputSpec507 elif Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.4'): input_spec = FILMGLSInputSpec505 else: input_spec = FILMGLSInputSpec if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'): output_spec = FILMGLSOutputSpec507 else: output_spec = FILMGLSOutputSpec def _get_pe_files(self, cwd): files = None if isdefined(self.inputs.design_file): fp = open(self.inputs.design_file, 'rt') for line in fp.readlines(): if line.startswith('/NumWaves'): numpes = int(line.split()[-1]) files = [] for i in range(numpes): files.append(self._gen_fname('pe%d.nii' % (i + 1), cwd=cwd)) break fp.close() return files def _get_numcons(self): numtcons = 0 numfcons = 0 if isdefined(self.inputs.tcon_file): fp = open(self.inputs.tcon_file, 'rt') for line in fp.readlines(): if line.startswith('/NumContrasts'): numtcons = int(line.split()[-1]) break fp.close() if isdefined(self.inputs.fcon_file): fp = open(self.inputs.fcon_file, 'rt') for line in fp.readlines(): if line.startswith('/NumContrasts'): numfcons = int(line.split()[-1]) break fp.close() return numtcons, numfcons def _list_outputs(self): outputs = self._outputs().get() cwd = os.getcwd() results_dir = os.path.join(cwd, self.inputs.results_dir) outputs['results_dir'] = results_dir pe_files = self._get_pe_files(results_dir) if pe_files: outputs['param_estimates'] = pe_files outputs['residual4d'] = self._gen_fname('res4d.nii', cwd=results_dir) outputs['dof_file'] = os.path.join(results_dir, 'dof') outputs['sigmasquareds'] = self._gen_fname('sigmasquareds.nii', cwd=results_dir) outputs['thresholdac'] = self._gen_fname('threshac1.nii', cwd=results_dir) if Info.version() and LooseVersion(Info.version()) < LooseVersion('5.0.7'): outputs['corrections'] = self._gen_fname('corrections.nii', cwd=results_dir) outputs['logfile'] = self._gen_fname('logfile', change_ext=False, cwd=results_dir) if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'): pth = results_dir numtcons, numfcons = self._get_numcons() base_contrast = 1 copes = [] varcopes = [] zstats = [] tstats = [] neffs = [] for i in range(numtcons): copes.append(self._gen_fname('cope%d.nii' % (base_contrast + i), cwd=pth)) varcopes.append( self._gen_fname('varcope%d.nii' % (base_contrast + i), cwd=pth)) zstats.append(self._gen_fname('zstat%d.nii' % (base_contrast + i), cwd=pth)) tstats.append(self._gen_fname('tstat%d.nii' % (base_contrast + i), cwd=pth)) if copes: outputs['copes'] = copes outputs['varcopes'] = varcopes outputs['zstats'] = zstats outputs['tstats'] = tstats fstats = [] zfstats = [] for i in range(numfcons): fstats.append(self._gen_fname('fstat%d.nii' % (base_contrast + i), cwd=pth)) zfstats.append( self._gen_fname('zfstat%d.nii' % (base_contrast + i), cwd=pth)) if fstats: outputs['fstats'] = fstats outputs['zfstats'] = zfstats return outputs class FEATRegisterInputSpec(BaseInterfaceInputSpec): feat_dirs = InputMultiPath( Directory(exists=True), desc="Lower level feat dirs", mandatory=True) reg_image = File( exists=True, desc="image to register to (will be treated as standard)", mandatory=True) reg_dof = traits.Int( 12, desc="registration degrees of freedom", usedefault=True) class FEATRegisterOutputSpec(TraitedSpec): fsf_file = File(exists=True, desc="FSL feat specification file") class FEATRegister(BaseInterface): """Register feat directories to a specific standard """ input_spec = FEATRegisterInputSpec output_spec = FEATRegisterOutputSpec def _run_interface(self, runtime): fsf_header = load_template('featreg_header.tcl') fsf_footer = load_template('feat_nongui.tcl') fsf_dirs = load_template('feat_fe_featdirs.tcl') num_runs = len(self.inputs.feat_dirs) fsf_txt = fsf_header.substitute(num_runs=num_runs, regimage=self.inputs.reg_image, regdof=self.inputs.reg_dof) for i, rundir in enumerate(filename_to_list(self.inputs.feat_dirs)): fsf_txt += fsf_dirs.substitute(runno=i + 1, rundir=os.path.abspath(rundir)) fsf_txt += fsf_footer.substitute() f = open(os.path.join(os.getcwd(), 'register.fsf'), 'wt') f.write(fsf_txt) f.close() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['fsf_file'] = os.path.abspath( os.path.join(os.getcwd(), 'register.fsf')) return outputs class FLAMEOInputSpec(FSLCommandInputSpec): cope_file = File(exists=True, argstr='--copefile=%s', mandatory=True, desc='cope regressor data file') var_cope_file = File(exists=True, argstr='--varcopefile=%s', desc='varcope weightings data file') dof_var_cope_file = File(exists=True, argstr='--dofvarcopefile=%s', desc='dof data file for varcope data') mask_file = File(exists=True, argstr='--maskfile=%s', mandatory=True, desc='mask file') design_file = File(exists=True, argstr='--designfile=%s', mandatory=True, desc='design matrix file') t_con_file = File( exists=True, argstr='--tcontrastsfile=%s', mandatory=True, desc='ascii matrix specifying t-contrasts') f_con_file = File(exists=True, argstr='--fcontrastsfile=%s', desc='ascii matrix specifying f-contrasts') cov_split_file = File( exists=True, argstr='--covsplitfile=%s', mandatory=True, desc='ascii matrix specifying the groups the covariance is split into') run_mode = traits.Enum( 'fe', 'ols', 'flame1', 'flame12', argstr='--runmode=%s', mandatory=True, desc='inference to perform') n_jumps = traits.Int( argstr='--njumps=%d', desc='number of jumps made by mcmc') burnin = traits.Int(argstr='--burnin=%d', desc='number of jumps at start of mcmc to be discarded') sample_every = traits.Int(argstr='--sampleevery=%d', desc='number of jumps for each sample') fix_mean = traits.Bool(argstr='--fixmean', desc='fix mean for tfit') infer_outliers = traits.Bool(argstr='--inferoutliers', desc='infer outliers - not for fe') no_pe_outputs = traits.Bool(argstr='--nopeoutput', desc='do not output pe files') sigma_dofs = traits.Int(argstr='--sigma_dofs=%d', desc='sigma (in mm) to use for Gaussian smoothing the DOFs in FLAME 2. Default is 1mm, -1 indicates no smoothing') outlier_iter = traits.Int(argstr='--ioni=%d', desc='Number of max iterations to use when inferring outliers. Default is 12.') log_dir = Directory("stats", argstr='--ld=%s', usedefault=True) # ohinds # no support for ven, vef class FLAMEOOutputSpec(TraitedSpec): pes = OutputMultiPath(File(exists=True), desc=("Parameter estimates for each column of the " "design matrix for each voxel")) res4d = OutputMultiPath(File(exists=True), desc=("Model fit residual mean-squared error for " "each time point")) copes = OutputMultiPath(File(exists=True), desc="Contrast estimates for each contrast") var_copes = OutputMultiPath(File(exists=True), desc="Variance estimates for each contrast") zstats = OutputMultiPath(File(exists=True), desc="z-stat file for each contrast") tstats = OutputMultiPath(File(exists=True), desc="t-stat file for each contrast") zfstats = OutputMultiPath(File(exists=True), desc="z stat file for each f contrast") fstats = OutputMultiPath(File(exists=True), desc="f-stat file for each contrast") mrefvars = OutputMultiPath(File(exists=True), desc=("mean random effect variances for each " "contrast")) tdof = OutputMultiPath(File(exists=True), desc="temporal dof file for each contrast") weights = OutputMultiPath(File(exists=True), desc="weights file for each contrast") stats_dir = Directory(File(exists=True), desc="directory storing model estimation output") class FLAMEO(FSLCommand): """Use FSL flameo command to perform higher level model fits Examples -------- Initialize FLAMEO with no options, assigning them when calling run: >>> from nipype.interfaces import fsl >>> import os >>> flameo = fsl.FLAMEO(cope_file='cope.nii.gz', \ var_cope_file='varcope.nii.gz', \ cov_split_file='cov_split.mat', \ design_file='design.mat', \ t_con_file='design.con', \ mask_file='mask.nii', \ run_mode='fe') >>> flameo.cmdline 'flameo --copefile=cope.nii.gz --covsplitfile=cov_split.mat --designfile=design.mat --ld=stats --maskfile=mask.nii --runmode=fe --tcontrastsfile=design.con --varcopefile=varcope.nii.gz' """ _cmd = 'flameo' input_spec = FLAMEOInputSpec output_spec = FLAMEOOutputSpec # ohinds: 2010-04-06 def _run_interface(self, runtime): log_dir = self.inputs.log_dir cwd = os.getcwd() if os.access(os.path.join(cwd, log_dir), os.F_OK): rmtree(os.path.join(cwd, log_dir)) return super(FLAMEO, self)._run_interface(runtime) # ohinds: 2010-04-06 # made these compatible with flameo def _list_outputs(self): outputs = self._outputs().get() pth = os.path.join(os.getcwd(), self.inputs.log_dir) pes = human_order_sorted(glob(os.path.join(pth, 'pe[0-9]*.*'))) assert len(pes) >= 1, 'No pe volumes generated by FSL Estimate' outputs['pes'] = pes res4d = human_order_sorted(glob(os.path.join(pth, 'res4d.*'))) assert len(res4d) == 1, 'No residual volume generated by FSL Estimate' outputs['res4d'] = res4d[0] copes = human_order_sorted(glob(os.path.join(pth, 'cope[0-9]*.*'))) assert len(copes) >= 1, 'No cope volumes generated by FSL CEstimate' outputs['copes'] = copes var_copes = human_order_sorted( glob(os.path.join(pth, 'varcope[0-9]*.*'))) assert len( var_copes) >= 1, 'No varcope volumes generated by FSL CEstimate' outputs['var_copes'] = var_copes zstats = human_order_sorted(glob(os.path.join(pth, 'zstat[0-9]*.*'))) assert len(zstats) >= 1, 'No zstat volumes generated by FSL CEstimate' outputs['zstats'] = zstats if isdefined(self.inputs.f_con_file): zfstats = human_order_sorted( glob(os.path.join(pth, 'zfstat[0-9]*.*'))) assert len( zfstats) >= 1, 'No zfstat volumes generated by FSL CEstimate' outputs['zfstats'] = zfstats fstats = human_order_sorted( glob(os.path.join(pth, 'fstat[0-9]*.*'))) assert len( fstats) >= 1, 'No fstat volumes generated by FSL CEstimate' outputs['fstats'] = fstats tstats = human_order_sorted(glob(os.path.join(pth, 'tstat[0-9]*.*'))) assert len(tstats) >= 1, 'No tstat volumes generated by FSL CEstimate' outputs['tstats'] = tstats mrefs = human_order_sorted( glob(os.path.join(pth, 'mean_random_effects_var[0-9]*.*'))) assert len( mrefs) >= 1, 'No mean random effects volumes generated by FLAMEO' outputs['mrefvars'] = mrefs tdof = human_order_sorted(glob(os.path.join(pth, 'tdof_t[0-9]*.*'))) assert len(tdof) >= 1, 'No T dof volumes generated by FLAMEO' outputs['tdof'] = tdof weights = human_order_sorted( glob(os.path.join(pth, 'weights[0-9]*.*'))) assert len(weights) >= 1, 'No weight volumes generated by FLAMEO' outputs['weights'] = weights outputs['stats_dir'] = pth return outputs class ContrastMgrInputSpec(FSLCommandInputSpec): tcon_file = File(exists=True, mandatory=True, argstr='%s', position=-1, desc='contrast file containing T-contrasts') fcon_file = File(exists=True, argstr='-f %s', desc='contrast file containing F-contrasts') param_estimates = InputMultiPath(File(exists=True), argstr='', copyfile=False, mandatory=True, desc='Parameter estimates for each column of the design matrix') corrections = File(exists=True, copyfile=False, mandatory=True, desc='statistical corrections used within FILM modelling') dof_file = File(exists=True, argstr='', copyfile=False, mandatory=True, desc='degrees of freedom') sigmasquareds = File(exists=True, argstr='', position=-2, copyfile=False, mandatory=True, desc='summary of residuals, See Woolrich, et. al., 2001') contrast_num = traits.Range(low=1, argstr='-cope', desc='contrast number to start labeling copes from') suffix = traits.Str(argstr='-suffix %s', desc='suffix to put on the end of the cope filename before the contrast number, default is nothing') class ContrastMgrOutputSpec(TraitedSpec): copes = OutputMultiPath(File(exists=True), desc='Contrast estimates for each contrast') varcopes = OutputMultiPath(File(exists=True), desc='Variance estimates for each contrast') zstats = OutputMultiPath(File(exists=True), desc='z-stat file for each contrast') tstats = OutputMultiPath(File(exists=True), desc='t-stat file for each contrast') fstats = OutputMultiPath(File(exists=True), desc='f-stat file for each contrast') zfstats = OutputMultiPath(File(exists=True), desc='z-stat file for each F contrast') neffs = OutputMultiPath(File(exists=True), desc='neff file ?? for each contrast') class ContrastMgr(FSLCommand): """Use FSL contrast_mgr command to evaluate contrasts In interface mode this file assumes that all the required inputs are in the same location. """ _cmd = 'contrast_mgr' input_spec = ContrastMgrInputSpec output_spec = ContrastMgrOutputSpec def _run_interface(self, runtime): # The returncode is meaningless in ContrastMgr. So check the output # in stderr and if it's set, then update the returncode # accordingly. runtime = super(ContrastMgr, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime def _format_arg(self, name, trait_spec, value): if name in ['param_estimates', 'corrections', 'dof_file']: return '' elif name in ['sigmasquareds']: path, _ = os.path.split(value) return path else: return super(ContrastMgr, self)._format_arg(name, trait_spec, value) def _get_design_root(self, infile): _, fname = os.path.split(infile) return fname.split('.')[0] def _get_numcons(self): numtcons = 0 numfcons = 0 if isdefined(self.inputs.tcon_file): fp = open(self.inputs.tcon_file, 'rt') for line in fp.readlines(): if line.startswith('/NumContrasts'): numtcons = int(line.split()[-1]) break fp.close() if isdefined(self.inputs.fcon_file): fp = open(self.inputs.fcon_file, 'rt') for line in fp.readlines(): if line.startswith('/NumContrasts'): numfcons = int(line.split()[-1]) break fp.close() return numtcons, numfcons def _list_outputs(self): outputs = self._outputs().get() pth, _ = os.path.split(self.inputs.sigmasquareds) numtcons, numfcons = self._get_numcons() base_contrast = 1 if isdefined(self.inputs.contrast_num): base_contrast = self.inputs.contrast_num copes = [] varcopes = [] zstats = [] tstats = [] neffs = [] for i in range(numtcons): copes.append(self._gen_fname('cope%d.nii' % (base_contrast + i), cwd=pth)) varcopes.append( self._gen_fname('varcope%d.nii' % (base_contrast + i), cwd=pth)) zstats.append(self._gen_fname('zstat%d.nii' % (base_contrast + i), cwd=pth)) tstats.append(self._gen_fname('tstat%d.nii' % (base_contrast + i), cwd=pth)) neffs.append(self._gen_fname('neff%d.nii' % (base_contrast + i), cwd=pth)) if copes: outputs['copes'] = copes outputs['varcopes'] = varcopes outputs['zstats'] = zstats outputs['tstats'] = tstats outputs['neffs'] = neffs fstats = [] zfstats = [] for i in range(numfcons): fstats.append(self._gen_fname('fstat%d.nii' % (base_contrast + i), cwd=pth)) zfstats.append( self._gen_fname('zfstat%d.nii' % (base_contrast + i), cwd=pth)) if fstats: outputs['fstats'] = fstats outputs['zfstats'] = zfstats return outputs class L2ModelInputSpec(BaseInterfaceInputSpec): num_copes = traits.Range(low=1, mandatory=True, desc='number of copes to be combined') class L2ModelOutputSpec(TraitedSpec): design_mat = File(exists=True, desc='design matrix file') design_con = File(exists=True, desc='design contrast file') design_grp = File(exists=True, desc='design group file') class L2Model(BaseInterface): """Generate subject specific second level model Examples -------- >>> from nipype.interfaces.fsl import L2Model >>> model = L2Model(num_copes=3) # 3 sessions """ input_spec = L2ModelInputSpec output_spec = L2ModelOutputSpec def _run_interface(self, runtime): cwd = os.getcwd() mat_txt = ['/NumWaves 1', '/NumPoints %d' % self.inputs.num_copes, '/PPheights %e' % 1, '', '/Matrix'] for i in range(self.inputs.num_copes): mat_txt += ['%e' % 1] mat_txt = '\n'.join(mat_txt) con_txt = ['/ContrastName1 group mean', '/NumWaves 1', '/NumContrasts 1', '/PPheights %e' % 1, '/RequiredEffect 100.0', # XX where does this # number come from '', '/Matrix', '%e' % 1] con_txt = '\n'.join(con_txt) grp_txt = ['/NumWaves 1', '/NumPoints %d' % self.inputs.num_copes, '', '/Matrix'] for i in range(self.inputs.num_copes): grp_txt += ['1'] grp_txt = '\n'.join(grp_txt) txt = {'design.mat': mat_txt, 'design.con': con_txt, 'design.grp': grp_txt} # write design files for i, name in enumerate(['design.mat', 'design.con', 'design.grp']): f = open(os.path.join(cwd, name), 'wt') f.write(txt[name]) f.close() return runtime def _list_outputs(self): outputs = self._outputs().get() for field in outputs.keys(): outputs[field] = os.path.join(os.getcwd(), field.replace('_', '.')) return outputs class MultipleRegressDesignInputSpec(BaseInterfaceInputSpec): contrasts = traits.List( traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('F'), traits.List(traits.Tuple(traits.Str, traits.Enum('T'), traits.List( traits.Str), traits.List( traits.Float)), ))), mandatory=True, desc="List of contrasts with each contrast being a list of the form - \ [('name', 'stat', [condition list], [weight list])]. if \ session list is None or not provided, all sessions are used. For F \ contrasts, the condition list should contain previously defined \ T-contrasts without any weight list.") regressors = traits.Dict(traits.Str, traits.List(traits.Float), mandatory=True, desc='dictionary containing named lists of regressors') groups = traits.List(traits.Int, desc='list of group identifiers (defaults to single group)') class MultipleRegressDesignOutputSpec(TraitedSpec): design_mat = File(exists=True, desc='design matrix file') design_con = File(exists=True, desc='design t-contrast file') design_fts = File(exists=True, desc='design f-contrast file') design_grp = File(exists=True, desc='design group file') class MultipleRegressDesign(BaseInterface): """Generate multiple regression design .. note:: FSL does not demean columns for higher level analysis. Please see `FSL documentation `_ for more details on model specification for higher level analysis. Examples -------- >>> from nipype.interfaces.fsl import MultipleRegressDesign >>> model = MultipleRegressDesign() >>> model.inputs.contrasts = [['group mean', 'T',['reg1'],[1]]] >>> model.inputs.regressors = dict(reg1=[1, 1, 1], reg2=[2.,-4, 3]) >>> model.run() # doctest: +SKIP """ input_spec = MultipleRegressDesignInputSpec output_spec = MultipleRegressDesignOutputSpec def _run_interface(self, runtime): cwd = os.getcwd() regs = sorted(self.inputs.regressors.keys()) nwaves = len(regs) npoints = len(self.inputs.regressors[regs[0]]) ntcons = sum([1 for con in self.inputs.contrasts if con[1] == 'T']) nfcons = sum([1 for con in self.inputs.contrasts if con[1] == 'F']) # write mat file mat_txt = ['/NumWaves %d' % nwaves, '/NumPoints %d' % npoints] ppheights = [] for reg in regs: maxreg = np.max(self.inputs.regressors[reg]) minreg = np.min(self.inputs.regressors[reg]) if np.sign(maxreg) == np.sign(minreg): regheight = max([abs(minreg), abs(maxreg)]) else: regheight = abs(maxreg - minreg) ppheights.append('%e' % regheight) mat_txt += ['/PPheights ' + ' '.join(ppheights)] mat_txt += ['', '/Matrix'] for cidx in range(npoints): mat_txt.append(' '.join( ['%e' % self.inputs.regressors[key][cidx] for key in regs])) mat_txt = '\n'.join(mat_txt) + '\n' # write t-con file con_txt = [] counter = 0 tconmap = {} for conidx, con in enumerate(self.inputs.contrasts): if con[1] == 'T': tconmap[conidx] = counter counter += 1 con_txt += ['/ContrastName%d %s' % (counter, con[0])] con_txt += ['/NumWaves %d' % nwaves, '/NumContrasts %d' % ntcons, '/PPheights %s' % ' '.join( ['%e' % 1 for i in range(counter)]), '/RequiredEffect %s' % ' '.join( ['%.3f' % 100 for i in range(counter)]), '', '/Matrix'] for idx in sorted(tconmap.keys()): convals = np.zeros((nwaves, 1)) for regidx, reg in enumerate(self.inputs.contrasts[idx][2]): convals[regs.index(reg) ] = self.inputs.contrasts[idx][3][regidx] con_txt.append(' '.join(['%e' % val for val in convals])) con_txt = '\n'.join(con_txt) + '\n' # write f-con file fcon_txt = '' if nfcons: fcon_txt = ['/NumWaves %d' % ntcons, '/NumContrasts %d' % nfcons, '', '/Matrix'] for conidx, con in enumerate(self.inputs.contrasts): if con[1] == 'F': convals = np.zeros((ntcons, 1)) for tcon in con[2]: convals[tconmap[self.inputs.contrasts.index(tcon)]] = 1 fcon_txt.append(' '.join(['%d' % val for val in convals])) fcon_txt = '\n'.join(fcon_txt) fcon_txt += '\n' # write group file grp_txt = ['/NumWaves 1', '/NumPoints %d' % npoints, '', '/Matrix'] for i in range(npoints): if isdefined(self.inputs.groups): grp_txt += ['%d' % self.inputs.groups[i]] else: grp_txt += ['1'] grp_txt = '\n'.join(grp_txt) + '\n' txt = {'design.mat': mat_txt, 'design.con': con_txt, 'design.fts': fcon_txt, 'design.grp': grp_txt} # write design files for key, val in txt.items(): if ('fts' in key) and (nfcons == 0): continue filename = key.replace('_', '.') f = open(os.path.join(cwd, filename), 'wt') f.write(val) f.close() return runtime def _list_outputs(self): outputs = self._outputs().get() nfcons = sum([1 for con in self.inputs.contrasts if con[1] == 'F']) for field in outputs.keys(): if ('fts' in field) and (nfcons == 0): continue outputs[field] = os.path.join(os.getcwd(), field.replace('_', '.')) return outputs class SMMInputSpec(FSLCommandInputSpec): spatial_data_file = File( exists=True, position=0, argstr='--sdf="%s"', mandatory=True, desc="statistics spatial map", copyfile=False) mask = File(exists=True, position=1, argstr='--mask="%s"', mandatory=True, desc="mask file", copyfile=False) no_deactivation_class = traits.Bool(position=2, argstr="--zfstatmode", desc="enforces no deactivation class") class SMMOutputSpec(TraitedSpec): null_p_map = File(exists=True) activation_p_map = File(exists=True) deactivation_p_map = File(exists=True) class SMM(FSLCommand): ''' Spatial Mixture Modelling. For more detail on the spatial mixture modelling see Mixture Models with Adaptive Spatial Regularisation for Segmentation with an Application to FMRI Data; Woolrich, M., Behrens, T., Beckmann, C., and Smith, S.; IEEE Trans. Medical Imaging, 24(1):1-11, 2005. ''' _cmd = 'mm --ld=logdir' input_spec = SMMInputSpec output_spec = SMMOutputSpec def _list_outputs(self): outputs = self._outputs().get() # TODO get the true logdir from the stdout outputs['null_p_map'] = self._gen_fname(basename="w1_mean", cwd="logdir") outputs['activation_p_map'] = self._gen_fname( basename="w2_mean", cwd="logdir") if not isdefined(self.inputs.no_deactivation_class) or not self.inputs.no_deactivation_class: outputs['deactivation_p_map'] = self._gen_fname( basename="w3_mean", cwd="logdir") return outputs class MELODICInputSpec(FSLCommandInputSpec): in_files = InputMultiPath( File(exists=True), argstr="-i %s", mandatory=True, position=0, desc="input file names (either single file name or a list)", sep=",") out_dir = Directory( argstr="-o %s", desc="output directory name", genfile=True) mask = File(exists=True, argstr="-m %s", desc="file name of mask for thresholding") no_mask = traits.Bool(argstr="--nomask", desc="switch off masking") update_mask = traits.Bool( argstr="--update_mask", desc="switch off mask updating") no_bet = traits.Bool(argstr="--nobet", desc="switch off BET") bg_threshold = traits.Float( argstr="--bgthreshold=%f", desc="brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected)") dim = traits.Int(argstr="-d %d", desc="dimensionality reduction into #num dimensions" "(default: automatic estimation)") dim_est = traits.Str(argstr="--dimest=%s", desc="use specific dim. estimation technique:" " lap, bic, mdl, aic, mean (default: lap)") sep_whiten = traits.Bool( argstr="--sep_whiten", desc="switch on separate whitening") sep_vn = traits.Bool( argstr="--sep_vn", desc="switch off joined variance normalization") num_ICs = traits.Int( argstr="-n %d", desc="number of IC's to extract (for deflation approach)") approach = traits.Str(argstr="-a %s", desc="approach for decomposition, 2D: defl, symm (default), " " 3D: tica (default), concat") non_linearity = traits.Str( argstr="--nl=%s", desc="nonlinearity: gauss, tanh, pow3, pow4") var_norm = traits.Bool( argstr="--vn", desc="switch off variance normalization") pbsc = traits.Bool( argstr="--pbsc", desc="switch off conversion to percent BOLD signal change") cov_weight = traits.Float(argstr="--covarweight=%f", desc="voxel-wise weights for the covariance " "matrix (e.g. segmentation information)") epsilon = traits.Float(argstr="--eps=%f", desc="minimum error change") epsilonS = traits.Float( argstr="--epsS=%f", desc="minimum error change for rank-1 approximation in TICA") maxit = traits.Int(argstr="--maxit=%d", desc="maximum number of iterations before restart") max_restart = traits.Int( argstr="--maxrestart=%d", desc="maximum number of restarts") mm_thresh = traits.Float( argstr="--mmthresh=%f", desc="threshold for Mixture Model based inference") no_mm = traits.Bool( argstr="--no_mm", desc="switch off mixture modelling on IC maps") ICs = File(exists=True, argstr="--ICs=%s", desc="filename of the IC components file for mixture modelling") mix = File(exists=True, argstr="--mix=%s", desc="mixing matrix for mixture modelling / filtering") smode = File(exists=True, argstr="--smode=%s", desc="matrix of session modes for report generation") rem_cmp = traits.List( traits.Int, argstr="-f %d", desc="component numbers to remove") report = traits.Bool(argstr="--report", desc="generate Melodic web report") bg_image = File(exists=True, argstr="--bgimage=%s", desc="specify background image for report" " (default: mean image)") tr_sec = traits.Float(argstr="--tr=%f", desc="TR in seconds") log_power = traits.Bool( argstr="--logPower", desc="calculate log of power for frequency spectrum") t_des = File(exists=True, argstr="--Tdes=%s", desc="design matrix across time-domain") t_con = File(exists=True, argstr="--Tcon=%s", desc="t-contrast matrix across time-domain") s_des = File(exists=True, argstr="--Sdes=%s", desc="design matrix across subject-domain") s_con = File(exists=True, argstr="--Scon=%s", desc="t-contrast matrix across subject-domain") out_all = traits.Bool(argstr="--Oall", desc="output everything") out_unmix = traits.Bool(argstr="--Ounmix", desc="output unmixing matrix") out_stats = traits.Bool( argstr="--Ostats", desc="output thresholded maps and probability maps") out_pca = traits.Bool(argstr="--Opca", desc="output PCA results") out_white = traits.Bool( argstr="--Owhite", desc="output whitening/dewhitening matrices") out_orig = traits.Bool(argstr="--Oorig", desc="output the original ICs") out_mean = traits.Bool(argstr="--Omean", desc="output mean volume") report_maps = traits.Str(argstr="--report_maps=%s", desc="control string for spatial map images (see slicer)") remove_deriv = traits.Bool(argstr="--remove_deriv", desc="removes every second entry in paradigm" " file (EV derivatives)") class MELODICOutputSpec(TraitedSpec): out_dir = Directory(exists=True) report_dir = Directory(exists=True) class MELODIC(FSLCommand): """Multivariate Exploratory Linear Optimised Decomposition into Independent Components Examples -------- >>> melodic_setup = MELODIC() >>> melodic_setup.inputs.approach = 'tica' >>> melodic_setup.inputs.in_files = ['functional.nii', 'functional2.nii', 'functional3.nii'] >>> melodic_setup.inputs.no_bet = True >>> melodic_setup.inputs.bg_threshold = 10 >>> melodic_setup.inputs.tr_sec = 1.5 >>> melodic_setup.inputs.mm_thresh = 0.5 >>> melodic_setup.inputs.out_stats = True >>> melodic_setup.inputs.t_des = 'timeDesign.mat' >>> melodic_setup.inputs.t_con = 'timeDesign.con' >>> melodic_setup.inputs.s_des = 'subjectDesign.mat' >>> melodic_setup.inputs.s_con = 'subjectDesign.con' >>> melodic_setup.inputs.out_dir = 'groupICA.out' >>> melodic_setup.cmdline 'melodic -i functional.nii,functional2.nii,functional3.nii -a tica --bgthreshold=10.000000 --mmthresh=0.500000 --nobet -o groupICA.out --Ostats --Scon=subjectDesign.con --Sdes=subjectDesign.mat --Tcon=timeDesign.con --Tdes=timeDesign.mat --tr=1.500000' >>> melodic_setup.run() # doctest: +SKIP """ input_spec = MELODICInputSpec output_spec = MELODICOutputSpec _cmd = 'melodic' def _list_outputs(self): outputs = self.output_spec().get() outputs['out_dir'] = self.inputs.out_dir if not isdefined(outputs['out_dir']): outputs['out_dir'] = self._gen_filename("out_dir") if isdefined(self.inputs.report) and self.inputs.report: outputs['report_dir'] = os.path.join( self._gen_filename("out_dir"), "report") return outputs def _gen_filename(self, name): if name == "out_dir": return os.getcwd() class SmoothEstimateInputSpec(FSLCommandInputSpec): dof = traits.Int(argstr='--dof=%d', mandatory=True, xor=['zstat_file'], desc='number of degrees of freedom') mask_file = File(argstr='--mask=%s', exists=True, mandatory=True, desc='brain mask volume') residual_fit_file = File(argstr='--res=%s', exists=True, requires=['dof'], desc='residual-fit image file') zstat_file = File(argstr='--zstat=%s', exists=True, xor=['dof'], desc='zstat image file') class SmoothEstimateOutputSpec(TraitedSpec): dlh = traits.Float(desc='smoothness estimate sqrt(det(Lambda))') volume = traits.Int(desc='number of voxels in mask') resels = traits.Float(desc='number of resels') class SmoothEstimate(FSLCommand): """ Estimates the smoothness of an image Examples -------- >>> est = SmoothEstimate() >>> est.inputs.zstat_file = 'zstat1.nii.gz' >>> est.inputs.mask_file = 'mask.nii' >>> est.cmdline 'smoothest --mask=mask.nii --zstat=zstat1.nii.gz' """ input_spec = SmoothEstimateInputSpec output_spec = SmoothEstimateOutputSpec _cmd = 'smoothest' def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() stdout = runtime.stdout.split('\n') outputs.dlh = float(stdout[0].split()[1]) outputs.volume = int(stdout[1].split()[1]) outputs.resels = float(stdout[2].split()[1]) return outputs class ClusterInputSpec(FSLCommandInputSpec): in_file = File(argstr='--in=%s', mandatory=True, exists=True, desc='input volume') threshold = traits.Float(argstr='--thresh=%.10f', mandatory=True, desc='threshold for input volume') out_index_file = traits.Either(traits.Bool, File, argstr='--oindex=%s', desc='output of cluster index (in size order)', hash_files=False) out_threshold_file = traits.Either(traits.Bool, File, argstr='--othresh=%s', desc='thresholded image', hash_files=False) out_localmax_txt_file = traits.Either(traits.Bool, File, argstr='--olmax=%s', desc='local maxima text file', hash_files=False) out_localmax_vol_file = traits.Either(traits.Bool, File, argstr='--olmaxim=%s', desc='output of local maxima volume', hash_files=False) out_size_file = traits.Either(traits.Bool, File, argstr='--osize=%s', desc='filename for output of size image', hash_files=False) out_max_file = traits.Either(traits.Bool, File, argstr='--omax=%s', desc='filename for output of max image', hash_files=False) out_mean_file = traits.Either(traits.Bool, File, argstr='--omean=%s', desc='filename for output of mean image', hash_files=False) out_pval_file = traits.Either(traits.Bool, File, argstr='--opvals=%s', desc='filename for image output of log pvals', hash_files=False) pthreshold = traits.Float(argstr='--pthresh=%.10f', requires=['dlh', 'volume'], desc='p-threshold for clusters') peak_distance = traits.Float(argstr='--peakdist=%.10f', desc='minimum distance between local maxima/minima, in mm (default 0)') cope_file = traits.File(argstr='--cope=%s', desc='cope volume') volume = traits.Int(argstr='--volume=%d', desc='number of voxels in the mask') dlh = traits.Float(argstr='--dlh=%.10f', desc='smoothness estimate = sqrt(det(Lambda))') fractional = traits.Bool('--fractional', desc='interprets the threshold as a fraction of the robust range') connectivity = traits.Int(argstr='--connectivity=%d', desc='the connectivity of voxels (default 26)') use_mm = traits.Bool('--mm', desc='use mm, not voxel, coordinates') find_min = traits.Bool('--min', desc='find minima instead of maxima') no_table = traits.Bool( '--no_table', desc='suppresses printing of the table info') minclustersize = traits.Bool(argstr='--minclustersize', desc='prints out minimum significant cluster size') xfm_file = File(argstr='--xfm=%s', desc='filename for Linear: input->standard-space transform. Non-linear: input->highres transform') std_space_file = File(argstr='--stdvol=%s', desc='filename for standard-space volume') num_maxima = traits.Int(argstr='--num=%d', desc='no of local maxima to report') warpfield_file = File(argstr='--warpvol=%s', desc='file contining warpfield') class ClusterOutputSpec(TraitedSpec): index_file = File(desc='output of cluster index (in size order)') threshold_file = File(desc='thresholded image') localmax_txt_file = File(desc='local maxima text file') localmax_vol_file = File(desc='output of local maxima volume') size_file = File(desc='filename for output of size image') max_file = File(desc='filename for output of max image') mean_file = File(desc='filename for output of mean image') pval_file = File(desc='filename for image output of log pvals') class Cluster(FSLCommand): """ Uses FSL cluster to perform clustering on statistical output Examples -------- >>> cl = Cluster() >>> cl.inputs.threshold = 2.3 >>> cl.inputs.in_file = 'zstat1.nii.gz' >>> cl.inputs.out_localmax_txt_file = 'stats.txt' >>> cl.cmdline 'cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000' """ input_spec = ClusterInputSpec output_spec = ClusterOutputSpec _cmd = 'cluster' filemap = {'out_index_file': 'index', 'out_threshold_file': 'threshold', 'out_localmax_txt_file': 'localmax.txt', 'out_localmax_vol_file': 'localmax', 'out_size_file': 'size', 'out_max_file': 'max', 'out_mean_file': 'mean', 'out_pval_file': 'pval'} def _list_outputs(self): outputs = self.output_spec().get() for key, suffix in self.filemap.items(): outkey = key[4:] inval = getattr(self.inputs, key) if isdefined(inval): if isinstance(inval, bool): if inval: change_ext = True if suffix.endswith('.txt'): change_ext = False outputs[outkey] = self._gen_fname(self.inputs.in_file, suffix='_' + suffix, change_ext=change_ext) else: outputs[outkey] = os.path.abspath(inval) return outputs def _format_arg(self, name, spec, value): if name in self.filemap.keys(): if isinstance(value, bool): fname = self._list_outputs()[name[4:]] else: fname = value return spec.argstr % fname return super(Cluster, self)._format_arg(name, spec, value) class RandomiseInputSpec(FSLCommandInputSpec): in_file = File(exists=True, desc='4D input file', argstr='-i %s', position=0, mandatory=True) base_name = traits.Str( 'tbss_', desc='the rootname that all generated files will have', argstr='-o "%s"', position=1, usedefault=True) design_mat = File( exists=True, desc='design matrix file', argstr='-d %s', position=2) tcon = File( exists=True, desc='t contrasts file', argstr='-t %s', position=3) fcon = File(exists=True, desc='f contrasts file', argstr='-f %s') mask = File(exists=True, desc='mask image', argstr='-m %s') x_block_labels = File( exists=True, desc='exchangeability block labels file', argstr='-e %s') demean = traits.Bool( desc='demean data temporally before model fitting', argstr='-D') one_sample_group_mean = traits.Bool( desc='perform 1-sample group-mean test instead of generic permutation test', argstr='-1') show_total_perms = traits.Bool( desc='print out how many unique permutations would be generated and exit', argstr='-q') show_info_parallel_mode = traits.Bool( desc='print out information required for parallel mode and exit', argstr='-Q') vox_p_values = traits.Bool( desc='output voxelwise (corrected and uncorrected) p-value images', argstr='-x') tfce = traits.Bool( desc='carry out Threshold-Free Cluster Enhancement', argstr='-T') tfce2D = traits.Bool( desc='carry out Threshold-Free Cluster Enhancement with 2D optimisation', argstr='--T2') f_only = traits.Bool(desc='calculate f-statistics only', argstr='--f_only') raw_stats_imgs = traits.Bool( desc='output raw ( unpermuted ) statistic images', argstr='-R') p_vec_n_dist_files = traits.Bool( desc='output permutation vector and null distribution text files', argstr='-P') num_perm = traits.Int( argstr='-n %d', desc='number of permutations (default 5000, set to 0 for exhaustive)') seed = traits.Int( argstr='--seed=%d', desc='specific integer seed for random number generator') var_smooth = traits.Int( argstr='-v %d', desc='use variance smoothing (std is in mm)') c_thresh = traits.Float( argstr='-c %.2f', desc='carry out cluster-based thresholding') cm_thresh = traits.Float( argstr='-C %.2f', desc='carry out cluster-mass-based thresholding') f_c_thresh = traits.Float( argstr='-F %.2f', desc='carry out f cluster thresholding') f_cm_thresh = traits.Float( argstr='-S %.2f', desc='carry out f cluster-mass thresholding') tfce_H = traits.Float( argstr='--tfce_H=%.2f', desc='TFCE height parameter (default=2)') tfce_E = traits.Float( argstr='--tfce_E=%.2f', desc='TFCE extent parameter (default=0.5)') tfce_C = traits.Float( argstr='--tfce_C=%.2f', desc='TFCE connectivity (6 or 26; default=6)') class RandomiseOutputSpec(TraitedSpec): tstat_files = traits.List( File(exists=True), desc='t contrast raw statistic') fstat_files = traits.List( File(exists=True), desc='f contrast raw statistic') t_p_files = traits.List( File(exists=True), desc='f contrast uncorrected p values files') f_p_files = traits.List( File(exists=True), desc='f contrast uncorrected p values files') t_corrected_p_files = traits.List( File(exists=True), desc='t contrast FWE (Family-wise error) corrected p values files') f_corrected_p_files = traits.List( File(exists=True), desc='f contrast FWE (Family-wise error) corrected p values files') class Randomise(FSLCommand): """XXX UNSTABLE DO NOT USE FSL Randomise: feeds the 4D projected FA data into GLM modelling and thresholding in order to find voxels which correlate with your model Example ------- >>> import nipype.interfaces.fsl as fsl >>> rand = fsl.Randomise(in_file='allFA.nii', mask = 'mask.nii', tcon='design.con', design_mat='design.mat') >>> rand.cmdline 'randomise -i allFA.nii -o "tbss_" -d design.mat -t design.con -m mask.nii' """ _cmd = 'randomise' input_spec = RandomiseInputSpec output_spec = RandomiseOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['tstat_files'] = glob(self._gen_fname( '%s_tstat*.nii' % self.inputs.base_name)) outputs['fstat_files'] = glob(self._gen_fname( '%s_fstat*.nii' % self.inputs.base_name)) prefix = False if self.inputs.tfce or self.inputs.tfce2D: prefix = 'tfce' elif self.inputs.vox_p_values: prefix = 'vox' elif self.inputs.c_thresh or self.inputs.f_c_thresh: prefix = 'clustere' elif self.inputs.cm_thresh or self.inputs.f_cm_thresh: prefix = 'clusterm' if prefix: outputs['t_p_files'] = glob(self._gen_fname( '%s_%s_p_tstat*' % (self.inputs.base_name, prefix))) outputs['t_corrected_p_files'] = glob(self._gen_fname( '%s_%s_corrp_tstat*.nii' % (self.inputs.base_name, prefix))) outputs['f_p_files'] = glob(self._gen_fname( '%s_%s_p_fstat*.nii' % (self.inputs.base_name, prefix))) outputs['f_corrected_p_files'] = glob(self._gen_fname( '%s_%s_corrp_fstat*.nii' % (self.inputs.base_name, prefix))) return outputs class GLMInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='-i %s', mandatory=True, position=1, desc='input file name (text matrix or 3D/4D image file)') out_file = File(name_template="%s_glm", argstr='-o %s', position=3, desc=('filename for GLM parameter estimates' + ' (GLM betas)'), name_source="in_file", keep_extension=True) design = File(exists=True, argstr='-d %s', mandatory=True, position=2, desc=('file name of the GLM design matrix (text time' + ' courses for temporal regression or an image' + ' file for spatial regression)')) contrasts = File(exists=True, argstr='-c %s', desc=('matrix of t-statics' + ' contrasts')) mask = File(exists=True, argstr='-m %s', desc=('mask image file name if' + ' input is image')) dof = traits.Int(argstr='--dof=%d', desc=('set degrees of freedom' + ' explicitly')) des_norm = traits.Bool(argstr='--des_norm', desc=('switch on normalization' + ' of the design matrix' + ' columns to unit std' + ' deviation')) dat_norm = traits.Bool(argstr='--dat_norm', desc=('switch on normalization' + ' of the data time' + ' series to unit std' + ' deviation')) var_norm = traits.Bool(argstr='--vn', desc=('perform MELODIC variance-' + 'normalisation on data')) demean = traits.Bool(argstr='--demean', desc=('switch on demeaining of ' + ' design and data')) out_cope = File(argstr='--out_cope=%s', desc='output file name for COPE (either as txt or image') out_z_name = File(argstr='--out_z=%s', desc='output file name for Z-stats (either as txt or image') out_t_name = File(argstr='--out_t=%s', desc='output file name for t-stats (either as txt or image') out_p_name = File(argstr='--out_p=%s', desc=('output file name for p-values of Z-stats (either as' + ' text file or image)')) out_f_name = File(argstr='--out_f=%s', desc='output file name for F-value of full model fit') out_pf_name = File(argstr='--out_pf=%s', desc='output file name for p-value for full model fit') out_res_name = File(argstr='--out_res=%s', desc='output file name for residuals') out_varcb_name = File(argstr='--out_varcb=%s', desc='output file name for variance of COPEs') out_sigsq_name = File(argstr='--out_sigsq=%s', desc=('output file name for residual noise variance' + ' sigma-square')) out_data_name = File(argstr='--out_data=%s', desc='output file name for pre-processed data') out_vnscales_name = File(argstr='--out_vnscales=%s', desc=('output file name for scaling factors for variance' + ' normalisation')) class GLMOutputSpec(TraitedSpec): out_file = File(exists=True, desc=('file name of GLM parameters' ' (if generated)')) out_cope = OutputMultiPath(File(exists=True), desc=('output file name for COPEs (either as ' 'text file or image)')) out_z = OutputMultiPath(File(exists=True), desc=('output file name for COPEs (either as text ' 'file or image)')) out_t = OutputMultiPath(File(exists=True), desc=('output file name for t-stats (either as ' 'text file or image)')) out_p = OutputMultiPath(File(exists=True), desc=('output file name for p-values of Z-stats ' '(either as text file or image)')) out_f = OutputMultiPath(File(exists=True), desc=('output file name for F-value of full model ' 'fit')) out_pf = OutputMultiPath(File(exists=True), desc=('output file name for p-value for full ' 'model fit')) out_res = OutputMultiPath(File(exists=True), desc='output file name for residuals') out_varcb = OutputMultiPath(File(exists=True), desc='output file name for variance of COPEs') out_sigsq = OutputMultiPath(File(exists=True), desc=('output file name for residual noise ' 'variance sigma-square')) out_data = OutputMultiPath(File(exists=True), desc='output file for preprocessed data') out_vnscales = OutputMultiPath(File(exists=True), desc=('output file name for scaling factors ' 'for variance normalisation')) class GLM(FSLCommand): """ FSL GLM: Example ------- >>> import nipype.interfaces.fsl as fsl >>> glm = fsl.GLM(in_file='functional.nii', design='maps.nii', output_type='NIFTI') >>> glm.cmdline 'fsl_glm -i functional.nii -d maps.nii -o functional_glm.nii' """ _cmd = 'fsl_glm' input_spec = GLMInputSpec output_spec = GLMOutputSpec def _list_outputs(self): outputs = super(GLM, self)._list_outputs() if isdefined(self.inputs.out_cope): outputs['out_cope'] = os.path.abspath(self.inputs.out_cope) if isdefined(self.inputs.out_z_name): outputs['out_z'] = os.path.abspath(self.inputs.out_z_name) if isdefined(self.inputs.out_t_name): outputs['out_t'] = os.path.abspath(self.inputs.out_t_name) if isdefined(self.inputs.out_p_name): outputs['out_p'] = os.path.abspath(self.inputs.out_p_name) if isdefined(self.inputs.out_f_name): outputs['out_f'] = os.path.abspath(self.inputs.out_f_name) if isdefined(self.inputs.out_pf_name): outputs['out_pf'] = os.path.abspath(self.inputs.out_pf_name) if isdefined(self.inputs.out_res_name): outputs['out_res'] = os.path.abspath(self.inputs.out_res_name) if isdefined(self.inputs.out_varcb_name): outputs['out_varcb'] = os.path.abspath(self.inputs.out_varcb_name) if isdefined(self.inputs.out_sigsq_name): outputs['out_sigsq'] = os.path.abspath(self.inputs.out_sigsq_name) if isdefined(self.inputs.out_data_name): outputs['out_data'] = os.path.abspath(self.inputs.out_data_name) if isdefined(self.inputs.out_vnscales_name): outputs['out_vnscales'] = os.path.abspath( self.inputs.out_vnscales_name) return outputs nipype-0.11.0/nipype/interfaces/fsl/preprocess.py000066400000000000000000002240301257611314500220550ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 4.1.4. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op import warnings import glob import numpy as np from nipype.interfaces.fsl.base import FSLCommand, FSLCommandInputSpec from nipype.interfaces.base import (TraitedSpec, File, InputMultiPath, OutputMultiPath, Undefined, traits, isdefined, OutputMultiPath) from nipype.utils.filemanip import split_filename from nibabel import load warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class BETInputSpec(FSLCommandInputSpec): # We use position args here as list indices - so a negative number # will put something on the end in_file = File(exists=True, desc='input file to skull strip', argstr='%s', position=0, mandatory=True) out_file = File(desc='name of output skull stripped image', argstr='%s', position=1, genfile=True, hash_files=False) outline = traits.Bool(desc='create surface outline image', argstr='-o') mask = traits.Bool(desc='create binary mask image', argstr='-m') skull = traits.Bool(desc='create skull image', argstr='-s') no_output = traits.Bool(argstr='-n', desc="Don't generate segmented output") frac = traits.Float(desc='fractional intensity threshold', argstr='-f %.2f') vertical_gradient = traits.Float(argstr='-g %.2f', desc='vertical gradient in fractional intensity ' 'threshold (-1, 1)') radius = traits.Int(argstr='-r %d', units='mm', desc="head radius") center = traits.List(traits.Int, desc='center of gravity in voxels', argstr='-c %s', minlen=0, maxlen=3, units='voxels') threshold = traits.Bool(argstr='-t', desc="apply thresholding to segmented brain image and mask") mesh = traits.Bool(argstr='-e', desc="generate a vtk mesh brain surface") # the remaining 'options' are more like modes (mutually exclusive) that # FSL actually implements in a shell script wrapper around the bet binary. # for some combinations of them in specific order a call would not fail, # but in general using more than one of the following is clearly not # supported _xor_inputs = ('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided') robust = traits.Bool(desc='robust brain centre estimation ' '(iterates BET several times)', argstr='-R', xor=_xor_inputs) padding = traits.Bool(desc='improve BET if FOV is very small in Z ' '(by temporarily padding end slices)', argstr='-Z', xor=_xor_inputs) remove_eyes = traits.Bool(desc='eye & optic nerve cleanup (can be ' 'useful in SIENA)', argstr='-S', xor=_xor_inputs) surfaces = traits.Bool(desc='run bet2 and then betsurf to get additional ' 'skull and scalp surfaces (includes ' 'registrations)', argstr='-A', xor=_xor_inputs) t2_guided = File(desc='as with creating surfaces, when also feeding in ' 'non-brain-extracted T2 (includes registrations)', argstr='-A2 %s', xor=_xor_inputs) functional = traits.Bool(argstr='-F', xor=_xor_inputs, desc="apply to 4D fMRI data") reduce_bias = traits.Bool(argstr='-B', xor=_xor_inputs, desc="bias field and neck cleanup") class BETOutputSpec(TraitedSpec): out_file = File( desc="path/name of skullstripped file (if generated)") mask_file = File( desc="path/name of binary brain mask (if generated)") outline_file = File( desc="path/name of outline file (if generated)") meshfile = File( desc="path/name of vtk mesh file (if generated)") inskull_mask_file = File( desc="path/name of inskull mask (if generated)") inskull_mesh_file = File( desc="path/name of inskull mesh outline (if generated)") outskull_mask_file = File( desc="path/name of outskull mask (if generated)") outskull_mesh_file = File( desc="path/name of outskull mesh outline (if generated)") outskin_mask_file = File( desc="path/name of outskin mask (if generated)") outskin_mesh_file = File( desc="path/name of outskin mesh outline (if generated)") skull_mask_file = File( desc="path/name of skull mask (if generated)") class BET(FSLCommand): """Use FSL BET command for skull stripping. For complete details, see the `BET Documentation. `_ Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> btr = fsl.BET() >>> btr.inputs.in_file = example_data('structural.nii') >>> btr.inputs.frac = 0.7 >>> res = btr.run() # doctest: +SKIP """ _cmd = 'bet' input_spec = BETInputSpec output_spec = BETOutputSpec def _run_interface(self, runtime): # The returncode is meaningless in BET. So check the output # in stderr and if it's set, then update the returncode # accordingly. runtime = super(BET, self)._run_interface(runtime) if runtime.stderr: self.raise_exception(runtime) return runtime def _gen_outfilename(self): out_file = self.inputs.out_file if not isdefined(out_file) and isdefined(self.inputs.in_file): out_file = self._gen_fname(self.inputs.in_file, suffix='_brain') return os.path.abspath(out_file) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self._gen_outfilename() if ((isdefined(self.inputs.mesh) and self.inputs.mesh) or (isdefined(self.inputs.surfaces) and self.inputs.surfaces)): outputs['meshfile'] = self._gen_fname(outputs['out_file'], suffix='_mesh.vtk', change_ext=False) if (isdefined(self.inputs.mask) and self.inputs.mask) or \ (isdefined(self.inputs.reduce_bias) and self.inputs.reduce_bias): outputs['mask_file'] = self._gen_fname(outputs['out_file'], suffix='_mask') if isdefined(self.inputs.outline) and self.inputs.outline: outputs['outline_file'] = self._gen_fname(outputs['out_file'], suffix='_overlay') if isdefined(self.inputs.surfaces) and self.inputs.surfaces: outputs['inskull_mask_file'] = self._gen_fname(outputs['out_file'], suffix='_inskull_mask') outputs['inskull_mesh_file'] = self._gen_fname(outputs['out_file'], suffix='_inskull_mesh') outputs[ 'outskull_mask_file'] = self._gen_fname(outputs['out_file'], suffix='_outskull_mask') outputs[ 'outskull_mesh_file'] = self._gen_fname(outputs['out_file'], suffix='_outskull_mesh') outputs['outskin_mask_file'] = self._gen_fname(outputs['out_file'], suffix='_outskin_mask') outputs['outskin_mesh_file'] = self._gen_fname(outputs['out_file'], suffix='_outskin_mesh') outputs['skull_mask_file'] = self._gen_fname(outputs['out_file'], suffix='_skull_mask') if isdefined(self.inputs.no_output) and self.inputs.no_output: outputs['out_file'] = Undefined return outputs def _gen_filename(self, name): if name == 'out_file': return self._gen_outfilename() return None class FASTInputSpec(FSLCommandInputSpec): """ Defines inputs (trait classes) for FAST """ in_files = InputMultiPath(File(exists=True), copyfile=False, desc='image, or multi-channel set of images, ' 'to be segmented', argstr='%s', position=-1, mandatory=True) out_basename = File(desc='base name of output files', argstr='-o %s') # uses in_file name as basename if none given number_classes = traits.Range(low=1, high=10, argstr='-n %d', desc='number of tissue-type classes') output_biasfield = traits.Bool(desc='output estimated bias field', argstr='-b') output_biascorrected = traits.Bool(desc='output restored image ' '(bias-corrected image)', argstr='-B') img_type = traits.Enum((1, 2, 3), desc='int specifying type of image: ' '(1 = T1, 2 = T2, 3 = PD)', argstr='-t %d') bias_iters = traits.Range(low=1, high=10, argstr='-I %d', desc='number of main-loop iterations during ' 'bias-field removal') bias_lowpass = traits.Range(low=4, high=40, desc='bias field smoothing extent (FWHM) ' 'in mm', argstr='-l %d', units='mm') init_seg_smooth = traits.Range(low=0.0001, high=0.1, desc='initial segmentation spatial ' 'smoothness (during bias field ' 'estimation)', argstr='-f %.3f') segments = traits.Bool(desc='outputs a separate binary image for each ' 'tissue type', argstr='-g') init_transform = File(exists=True, desc=' initialise' ' using priors', argstr='-a %s') other_priors = InputMultiPath( File(exist=True), desc='alternative prior images', argstr='-A %s', minlen=3, maxlen=3) no_pve = traits.Bool(desc='turn off PVE (partial volume estimation)', argstr='--nopve') no_bias = traits.Bool(desc='do not remove bias field', argstr='-N') use_priors = traits.Bool(desc='use priors throughout', argstr='-P') # must also set -a!, # mutually inclusive?? # No, conditional # mandatory... need to # figure out how to # handle with traits. segment_iters = traits.Range(low=1, high=50, desc='number of segmentation-initialisation' ' iterations', argstr='-W %d') mixel_smooth = traits.Range(low=0.0, high=1.0, desc='spatial smoothness for mixeltype', argstr='-R %.2f') iters_afterbias = traits.Range(low=1, high=20, desc='number of main-loop iterations ' 'after bias-field removal', argstr='-O %d') hyper = traits.Range(low=0.0, high=1.0, desc='segmentation spatial smoothness', argstr='-H %.2f') verbose = traits.Bool(desc='switch on diagnostic messages', argstr='-v') manual_seg = File(exists=True, desc='Filename containing intensities', argstr='-s %s') probability_maps = traits.Bool(desc='outputs individual probability maps', argstr='-p') class FASTOutputSpec(TraitedSpec): """Specify possible outputs from FAST""" tissue_class_map = File(exists=True, desc='path/name of binary segmented volume file' ' one val for each class _seg') tissue_class_files = OutputMultiPath(File(desc='path/name of binary segmented volumes ' 'one file for each class _seg_x')) restored_image = OutputMultiPath(File(desc='restored images (one for each input image) ' 'named according to the input images _restore')) mixeltype = File(desc="path/name of mixeltype volume file _mixeltype") partial_volume_map = File(desc="path/name of partial volume file _pveseg") partial_volume_files = OutputMultiPath(File(desc='path/name of partial volumes files ' 'one for each class, _pve_x')) bias_field = OutputMultiPath(File(desc='Estimated bias field _bias')) probability_maps = OutputMultiPath(File(desc='filenames, one for each class, for each ' 'input, prob_x')) class FAST(FSLCommand): """ Use FSL FAST for segmenting and bias correction. For complete details, see the `FAST Documentation. `_ Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data Assign options through the ``inputs`` attribute: >>> fastr = fsl.FAST() >>> fastr.inputs.in_files = example_data('structural.nii') >>> out = fastr.run() #doctest: +SKIP """ _cmd = 'fast' input_spec = FASTInputSpec output_spec = FASTOutputSpec def _format_arg(self, name, spec, value): # first do what should be done in general formated = super(FAST, self)._format_arg(name, spec, value) if name == 'in_files': # FAST needs the -S parameter value to correspond to the number # of input images, otherwise it will ignore all but the first formated = "-S %d %s" % (len(value), formated) return formated def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.number_classes): nclasses = 3 else: nclasses = self.inputs.number_classes # when using multichannel, results basename is based on last # input filename if isdefined(self.inputs.out_basename): basefile = self.inputs.out_basename else: basefile = self.inputs.in_files[-1] outputs['tissue_class_map'] = self._gen_fname(basefile, suffix='_seg') if self.inputs.segments: outputs['tissue_class_files'] = [] for i in range(nclasses): outputs['tissue_class_files'].append( self._gen_fname(basefile, suffix='_seg_%d' % i)) if isdefined(self.inputs.output_biascorrected): outputs['restored_image'] = [] if len(self.inputs.in_files) > 1: # for multi-image segmentation there is one corrected image # per input for val, f in enumerate(self.inputs.in_files): # image numbering is 1-based outputs['restored_image'].append( self._gen_fname(basefile, suffix='_restore_%d' % (val + 1))) else: # single image segmentation has unnumbered output image outputs['restored_image'].append( self._gen_fname(basefile, suffix='_restore')) outputs['mixeltype'] = self._gen_fname(basefile, suffix='_mixeltype') if not self.inputs.no_pve: outputs['partial_volume_map'] = self._gen_fname( basefile, suffix='_pveseg') outputs['partial_volume_files'] = [] for i in range(nclasses): outputs[ 'partial_volume_files'].append(self._gen_fname(basefile, suffix='_pve_%d' % i)) if self.inputs.output_biasfield: outputs['bias_field'] = [] if len(self.inputs.in_files) > 1: # for multi-image segmentation there is one bias field image # per input for val, f in enumerate(self.inputs.in_files): # image numbering is 1-based outputs['bias_field'].append( self._gen_fname(basefile, suffix='_bias_%d' % (val + 1))) else: # single image segmentation has unnumbered output image outputs['bias_field'].append( self._gen_fname(basefile, suffix='_bias')) if self.inputs.probability_maps: outputs['probability_maps'] = [] for i in range(nclasses): outputs['probability_maps'].append( self._gen_fname(basefile, suffix='_prob_%d' % i)) return outputs class FLIRTInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='-in %s', mandatory=True, position=0, desc='input file') reference = File(exists=True, argstr='-ref %s', mandatory=True, position=1, desc='reference file') out_file = File(argstr='-out %s', desc='registered output file', name_source=['in_file'], name_template='%s_flirt', position=2, hash_files=False) out_matrix_file = File(argstr='-omat %s', name_source=['in_file'], keep_extension=True, name_template='%s_flirt.mat', desc='output affine matrix in 4x4 asciii format', position=3, hash_files=False) out_log = File(name_source=['in_file'], keep_extension=True, requires=['save_log'], name_template='%s_flirt.log', desc='output log') in_matrix_file = File(argstr='-init %s', desc='input 4x4 affine matrix') apply_xfm = traits.Bool(argstr='-applyxfm', requires=['in_matrix_file'], desc='apply transformation supplied by in_matrix_file') apply_isoxfm = traits.Float(argstr='-applyisoxfm %f', xor=['apply_xfm'], desc='as applyxfm but forces isotropic resampling') datatype = traits.Enum('char', 'short', 'int', 'float', 'double', argstr='-datatype %s', desc='force output data type') cost = traits.Enum('mutualinfo', 'corratio', 'normcorr', 'normmi', 'leastsq', 'labeldiff', 'bbr', argstr='-cost %s', desc='cost function') # XXX What is the difference between 'cost' and 'searchcost'? Are # these both necessary or do they map to the same variable. cost_func = traits.Enum('mutualinfo', 'corratio', 'normcorr', 'normmi', 'leastsq', 'labeldiff', 'bbr', argstr='-searchcost %s', desc='cost function') uses_qform = traits.Bool(argstr='-usesqform', desc='initialize using sform or qform') display_init = traits.Bool(argstr='-displayinit', desc='display initial matrix') angle_rep = traits.Enum('quaternion', 'euler', argstr='-anglerep %s', desc='representation of rotation angles') interp = traits.Enum('trilinear', 'nearestneighbour', 'sinc', 'spline', argstr='-interp %s', desc='final interpolation method used in reslicing') sinc_width = traits.Int(argstr='-sincwidth %d', units='voxels', desc='full-width in voxels') sinc_window = traits.Enum('rectangular', 'hanning', 'blackman', argstr='-sincwindow %s', desc='sinc window') # XXX better doc bins = traits.Int(argstr='-bins %d', desc='number of histogram bins') dof = traits.Int(argstr='-dof %d', desc='number of transform degrees of freedom') no_resample = traits.Bool(argstr='-noresample', desc='do not change input sampling') force_scaling = traits.Bool(argstr='-forcescaling', desc='force rescaling even for low-res images') min_sampling = traits.Float(argstr='-minsampling %f', units='mm', desc='set minimum voxel dimension for sampling') padding_size = traits.Int(argstr='-paddingsize %d', units='voxels', desc='for applyxfm: interpolates outside image ' 'by size') searchr_x = traits.List(traits.Int, minlen=2, maxlen=2, units='degrees', argstr='-searchrx %s', desc='search angles along x-axis, in degrees') searchr_y = traits.List(traits.Int, minlen=2, maxlen=2, units='degrees', argstr='-searchry %s', desc='search angles along y-axis, in degrees') searchr_z = traits.List(traits.Int, minlen=2, maxlen=2, units='degrees', argstr='-searchrz %s', desc='search angles along z-axis, in degrees') no_search = traits.Bool(argstr='-nosearch', desc='set all angular searches to ranges 0 to 0') coarse_search = traits.Int(argstr='-coarsesearch %d', units='degrees', desc='coarse search delta angle') fine_search = traits.Int(argstr='-finesearch %d', units='degrees', desc='fine search delta angle') schedule = File(exists=True, argstr='-schedule %s', desc='replaces default schedule') ref_weight = File(exists=True, argstr='-refweight %s', desc='File for reference weighting volume') in_weight = File(exists=True, argstr='-inweight %s', desc='File for input weighting volume') no_clamp = traits.Bool(argstr='-noclamp', desc='do not use intensity clamping') no_resample_blur = traits.Bool(argstr='-noresampblur', desc='do not use blurring on downsampling') rigid2D = traits.Bool(argstr='-2D', desc='use 2D rigid body mode - ignores dof') save_log = traits.Bool(desc='save to log file') verbose = traits.Int(argstr='-verbose %d', desc='verbose mode, 0 is least') bgvalue = traits.Float(0, argstr='-setbackground %f', desc=('use specified background value for points ' 'outside FOV')) # BBR options wm_seg = File( argstr='-wmseg %s', min_ver='5.0.0', desc='white matter segmentation volume needed by BBR cost function') wmcoords = File( argstr='-wmcoords %s', min_ver='5.0.0', desc='white matter boundary coordinates for BBR cost function') wmnorms = File( argstr='-wmnorms %s', min_ver='5.0.0', desc='white matter boundary normals for BBR cost function') fieldmap = File( argstr='-fieldmap %s', min_ver='5.0.0', desc='fieldmap image in rads/s - must be already registered to the reference image') fieldmapmask = File( argstr='-fieldmapmask %s', min_ver='5.0.0', desc='mask for fieldmap image') pedir = traits.Int( argstr='-pedir %d', min_ver='5.0.0', desc='phase encode direction of EPI - 1/2/3=x/y/z & -1/-2/-3=-x/-y/-z') echospacing = traits.Float( argstr='-echospacing %f', min_ver='5.0.0', desc='value of EPI echo spacing - units of seconds') bbrtype = traits.Enum( 'signed', 'global_abs', 'local_abs', argstr='-bbrtype %s', min_ver='5.0.0', desc='type of bbr cost function: signed [default], global_abs, local_abs') bbrslope = traits.Float( argstr='-bbrslope %f', min_ver='5.0.0', desc='value of bbr slope') class FLIRTOutputSpec(TraitedSpec): out_file = File(exists=True, desc='path/name of registered file (if generated)') out_matrix_file = File(exists=True, desc='path/name of calculated affine transform ' '(if generated)') out_log = File(desc='path/name of output log (if generated)') class FLIRT(FSLCommand): """Use FSL FLIRT for coregistration. For complete details, see the `FLIRT Documentation. `_ To print out the command line help, use: fsl.FLIRT().inputs_help() Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> flt = fsl.FLIRT(bins=640, cost_func='mutualinfo') >>> flt.inputs.in_file = 'structural.nii' >>> flt.inputs.reference = 'mni.nii' >>> flt.inputs.output_type = "NIFTI_GZ" >>> flt.cmdline #doctest: +ELLIPSIS 'flirt -in structural.nii -ref mni.nii -out structural_flirt.nii.gz -omat structural_flirt.mat -bins 640 -searchcost mutualinfo' >>> res = flt.run() #doctest: +SKIP """ _cmd = 'flirt' input_spec = FLIRTInputSpec output_spec = FLIRTOutputSpec def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = super(FLIRT, self).aggregate_outputs( runtime=runtime, needed_outputs=needed_outputs) if isdefined(self.inputs.save_log) and self.inputs.save_log: with open(outputs.out_log, "a") as text_file: text_file.write(runtime.stdout + '\n') return outputs def _parse_inputs(self, skip=None): skip = [] if isdefined(self.inputs.save_log) and self.inputs.save_log: if not isdefined(self.inputs.verbose) or self.inputs.verbose == 0: self.inputs.verbose = 1 skip.append('save_log') return super(FLIRT, self)._parse_inputs(skip=skip) class ApplyXfmInputSpec(FLIRTInputSpec): apply_xfm = traits.Bool( True, argstr='-applyxfm', requires=['in_matrix_file'], desc='apply transformation supplied by in_matrix_file', usedefault=True) class ApplyXfm(FLIRT): """Currently just a light wrapper around FLIRT, with no modifications ApplyXfm is used to apply an existing tranform to an image Examples -------- >>> import nipype.interfaces.fsl as fsl >>> from nipype.testing import example_data >>> applyxfm = fsl.ApplyXfm() >>> applyxfm.inputs.in_file = example_data('structural.nii') >>> applyxfm.inputs.in_matrix_file = example_data('trans.mat') >>> applyxfm.inputs.out_file = 'newfile.nii' >>> applyxfm.inputs.reference = example_data('mni.nii') >>> applyxfm.inputs.apply_xfm = True >>> result = applyxfm.run() # doctest: +SKIP """ input_spec = ApplyXfmInputSpec class MCFLIRTInputSpec(FSLCommandInputSpec): in_file = File(exists=True, position=0, argstr="-in %s", mandatory=True, desc="timeseries to motion-correct") out_file = File(argstr='-out %s', genfile=True, desc="file to write", hash_files=False) cost = traits.Enum( 'mutualinfo', 'woods', 'corratio', 'normcorr', 'normmi', 'leastsquares', argstr='-cost %s', desc="cost function to optimize") bins = traits.Int(argstr='-bins %d', desc="number of histogram bins") dof = traits.Int( argstr='-dof %d', desc="degrees of freedom for the transformation") ref_vol = traits.Int(argstr='-refvol %d', desc="volume to align frames to") scaling = traits.Float( argstr='-scaling %.2f', desc="scaling factor to use") smooth = traits.Float( argstr='-smooth %.2f', desc="smoothing factor for the cost function") rotation = traits.Int( argstr='-rotation %d', desc="scaling factor for rotation tolerances") stages = traits.Int(argstr='-stages %d', desc="stages (if 4, perform final search with sinc interpolation") init = File(exists=True, argstr='-init %s', desc="inital transformation matrix") interpolation = traits.Enum("spline", "nn", "sinc", argstr="-%s_final", desc="interpolation method for transformation") use_gradient = traits.Bool( argstr='-gdt', desc="run search on gradient images") use_contour = traits.Bool( argstr='-edge', desc="run search on contour images") mean_vol = traits.Bool(argstr='-meanvol', desc="register to mean volume") stats_imgs = traits.Bool( argstr='-stats', desc="produce variance and std. dev. images") save_mats = traits.Bool( argstr='-mats', desc="save transformation matrices") save_plots = traits.Bool( argstr='-plots', desc="save transformation parameters") save_rms = traits.Bool( argstr='-rmsabs -rmsrel', desc="save rms displacement parameters") ref_file = File(exists=True, argstr='-reffile %s', desc="target image for motion correction") class MCFLIRTOutputSpec(TraitedSpec): out_file = File(exists=True, desc="motion-corrected timeseries") variance_img = File(exists=True, desc="variance image") std_img = File(exists=True, desc="standard deviation image") mean_img = File(exists=True, desc="mean timeseries image") par_file = File(exists=True, desc="text-file with motion parameters") mat_file = OutputMultiPath(File( exists=True), desc="transformation matrices") rms_files = OutputMultiPath(File(exists=True), desc="absolute and relative displacement parameters") class MCFLIRT(FSLCommand): """Use FSL MCFLIRT to do within-modality motion correction. For complete details, see the `MCFLIRT Documentation. `_ Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> mcflt = fsl.MCFLIRT(in_file=example_data('functional.nii'), cost='mutualinfo') >>> res = mcflt.run() # doctest: +SKIP """ _cmd = 'mcflirt' input_spec = MCFLIRTInputSpec output_spec = MCFLIRTOutputSpec def _format_arg(self, name, spec, value): if name == "interpolation": if value == "trilinear": return "" else: return spec.argstr % value return super(MCFLIRT, self)._format_arg(name, spec, value) def _list_outputs(self): cwd = os.getcwd() outputs = self._outputs().get() outputs['out_file'] = self._gen_outfilename() if isdefined(self.inputs.stats_imgs) and self.inputs.stats_imgs: outputs['variance_img'] = self._gen_fname(outputs['out_file'] + '_variance.ext', cwd=cwd) outputs['std_img'] = self._gen_fname(outputs['out_file'] + '_sigma.ext', cwd=cwd) # The mean image created if -stats option is specified ('meanvol') # is missing the top and bottom slices. Therefore we only expose the # mean image created by -meanvol option ('mean_reg') which isn't # corrupted. # Note that the same problem holds for the std and variance image. if isdefined(self.inputs.mean_vol) and self.inputs.mean_vol: outputs['mean_img'] = self._gen_fname(outputs['out_file'] + '_mean_reg.ext', cwd=cwd) if isdefined(self.inputs.save_mats) and self.inputs.save_mats: _, filename = os.path.split(outputs['out_file']) matpathname = os.path.join(cwd, filename + '.mat') _, _, _, timepoints = load(self.inputs.in_file).get_shape() outputs['mat_file'] = [] for t in range(timepoints): outputs['mat_file'].append(os.path.join(matpathname, 'MAT_%04d' % t)) if isdefined(self.inputs.save_plots) and self.inputs.save_plots: # Note - if e.g. out_file has .nii.gz, you get .nii.gz.par, # which is what mcflirt does! outputs['par_file'] = outputs['out_file'] + '.par' if isdefined(self.inputs.save_rms) and self.inputs.save_rms: outfile = outputs['out_file'] outputs['rms_files'] = [outfile + '_abs.rms', outfile + '_rel.rms'] return outputs def _gen_filename(self, name): if name == 'out_file': return self._gen_outfilename() return None def _gen_outfilename(self): out_file = self.inputs.out_file if isdefined(out_file): out_file = os.path.realpath(out_file) if not isdefined(out_file) and isdefined(self.inputs.in_file): out_file = self._gen_fname(self.inputs.in_file, suffix='_mcf') return os.path.abspath(out_file) class FNIRTInputSpec(FSLCommandInputSpec): ref_file = File(exists=True, argstr='--ref=%s', mandatory=True, desc='name of reference image') in_file = File(exists=True, argstr='--in=%s', mandatory=True, desc='name of input image') affine_file = File(exists=True, argstr='--aff=%s', desc='name of file containing affine transform') inwarp_file = File(exists=True, argstr='--inwarp=%s', desc='name of file containing initial non-linear warps') in_intensitymap_file = File(exists=True, argstr='--intin=%s', desc='name of file/files containing initial intensity maping' 'usually generated by previos fnirt run') fieldcoeff_file = traits.Either(traits.Bool, File, argstr='--cout=%s', desc='name of output file with field coefficients or true') warped_file = File(argstr='--iout=%s', desc='name of output image', genfile=True, hash_files=False) field_file = traits.Either(traits.Bool, File, argstr='--fout=%s', desc='name of output file with field or true', hash_files=False) jacobian_file = traits.Either(traits.Bool, File, argstr='--jout=%s', desc='name of file for writing out the Jacobian' 'of the field (for diagnostic or VBM purposes)', hash_files=False) modulatedref_file = traits.Either(traits.Bool, File, argstr='--refout=%s', desc='name of file for writing out intensity modulated' '--ref (for diagnostic purposes)', hash_files=False) out_intensitymap_file = traits.Either(traits.Bool, File, argstr='--intout=%s', desc='name of files for writing information pertaining ' 'to intensity mapping', hash_files=False) log_file = File(argstr='--logout=%s', desc='Name of log-file', genfile=True, hash_files=False) config_file = traits.Either( traits.Enum("T1_2_MNI152_2mm", "FA_2_FMRIB58_1mm"), File(exists=True), argstr='--config=%s', desc='Name of config file specifying command line arguments') refmask_file = File(exists=True, argstr='--refmask=%s', desc='name of file with mask in reference space') inmask_file = File(exists=True, argstr='--inmask=%s', desc='name of file with mask in input image space') skip_refmask = traits.Bool( argstr='--applyrefmask=0', xor=['apply_refmask'], desc='Skip specified refmask if set, default false') skip_inmask = traits.Bool(argstr='--applyinmask=0', xor=['apply_inmask'], desc='skip specified inmask if set, default false') apply_refmask = traits.List( traits.Enum(0, 1), argstr='--applyrefmask=%s', xor=['skip_refmask'], desc='list of iterations to use reference mask on (1 to use, 0 to skip)', sep=",") apply_inmask = traits.List( traits.Enum(0, 1), argstr='--applyinmask=%s', xor=['skip_inmask'], desc='list of iterations to use input mask on (1 to use, 0 to skip)', sep=",") skip_implicit_ref_masking = traits.Bool(argstr='--imprefm=0', desc='skip implicit masking based on value' 'in --ref image. Default = 0') skip_implicit_in_masking = traits.Bool(argstr='--impinm=0', desc='skip implicit masking based on value' 'in --in image. Default = 0') refmask_val = traits.Float(argstr='--imprefval=%f', desc='Value to mask out in --ref image. Default =0.0') inmask_val = traits.Float(argstr='--impinval=%f', desc='Value to mask out in --in image. Default =0.0') max_nonlin_iter = traits.List(traits.Int, argstr='--miter=%s', desc='Max # of non-linear iterations list, default [5, 5, 5, 5]', sep=",") subsampling_scheme = traits.List(traits.Int, argstr='--subsamp=%s', desc='sub-sampling scheme, list, default [4, 2, 1, 1]', sep=",") warp_resolution = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--warpres=%d,%d,%d', desc='(approximate) resolution (in mm) of warp basis ' 'in x-, y- and z-direction, default 10, 10, 10') spline_order = traits.Int(argstr='--splineorder=%d', desc='Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3') in_fwhm = traits.List(traits.Int, argstr='--infwhm=%s', desc='FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2]', sep=",") ref_fwhm = traits.List(traits.Int, argstr='--reffwhm=%s', desc='FWHM (in mm) of gaussian smoothing kernel for ref volume, default [4, 2, 0, 0]', sep=",") regularization_model = traits.Enum('membrane_energy', 'bending_energy', argstr='--regmod=%s', desc='Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy') regularization_lambda = traits.List(traits.Float, argstr='--lambda=%s', desc='Weight of regularisation, default depending on --ssqlambda and --regmod ' 'switches. See user documetation.', sep=",") skip_lambda_ssq = traits.Bool(argstr='--ssqlambda=0', desc='If true, lambda is not weighted by current ssq, default false') jacobian_range = traits.Tuple(traits.Float, traits.Float, argstr='--jacrange=%f,%f', desc='Allowed range of Jacobian determinants, default 0.01, 100.0') derive_from_ref = traits.Bool(argstr='--refderiv', desc='If true, ref image is used to calculate derivatives. Default false') intensity_mapping_model = traits.Enum('none', 'global_linear', 'global_non_linear' 'local_linear', 'global_non_linear_with_bias', 'local_non_linear', argstr='--intmod=%s', desc='Model for intensity-mapping') intensity_mapping_order = traits.Int(argstr='--intorder=%d', desc='Order of poynomial for mapping intensities, default 5') biasfield_resolution = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--biasres=%d,%d,%d', desc='Resolution (in mm) of bias-field modelling ' 'local intensities, default 50, 50, 50') bias_regularization_lambda = traits.Float(argstr='--biaslambda=%f', desc='Weight of regularisation for bias-field, default 10000') skip_intensity_mapping = traits.Bool( argstr='--estint=0', xor=['apply_intensity_mapping'], desc='Skip estimate intensity-mapping default false') apply_intensity_mapping = traits.List( traits.Enum(0, 1), argstr='--estint=%s', xor=['skip_intensity_mapping'], desc='List of subsampling levels to apply intensity mapping for (0 to skip, 1 to apply)', sep=",") hessian_precision = traits.Enum('double', 'float', argstr='--numprec=%s', desc='Precision for representing Hessian, double or float. Default double') class FNIRTOutputSpec(TraitedSpec): fieldcoeff_file = File(exists=True, desc='file with field coefficients') warped_file = File(exists=True, desc='warped image') field_file = File(desc='file with warp field') jacobian_file = File(desc='file containing Jacobian of the field') modulatedref_file = File(desc='file containing intensity modulated --ref') out_intensitymap_file = File( desc='file containing info pertaining to intensity mapping') log_file = File(desc='Name of log-file') class FNIRT(FSLCommand): """Use FSL FNIRT for non-linear registration. Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> fnt = fsl.FNIRT(affine_file=example_data('trans.mat')) >>> res = fnt.run(ref_file=example_data('mni.nii', in_file=example_data('structural.nii')) #doctest: +SKIP T1 -> Mni153 >>> from nipype.interfaces import fsl >>> fnirt_mprage = fsl.FNIRT() >>> fnirt_mprage.inputs.in_fwhm = [8, 4, 2, 2] >>> fnirt_mprage.inputs.subsampling_scheme = [4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6) >>> res = fnirt_mprage.run(in_file='structural.nii', ref_file='mni.nii', warped_file='warped.nii', fieldcoeff_file='fieldcoeff.nii')#doctest: +SKIP We can check the command line and confirm that it's what we expect. >>> fnirt_mprage.cmdline #doctest: +SKIP 'fnirt --cout=fieldcoeff.nii --in=structural.nii --infwhm=8,4,2,2 --ref=mni.nii --subsamp=4,2,1,1 --warpres=6,6,6 --iout=warped.nii' """ _cmd = 'fnirt' input_spec = FNIRTInputSpec output_spec = FNIRTOutputSpec filemap = {'warped_file': 'warped', 'field_file': 'field', 'jacobian_file': 'field_jacobian', 'modulatedref_file': 'modulated', 'out_intensitymap_file': 'intmap', 'log_file': 'log.txt', 'fieldcoeff_file': 'fieldwarp'} def _list_outputs(self): outputs = self.output_spec().get() for key, suffix in self.filemap.items(): inval = getattr(self.inputs, key) change_ext = True if key in ['warped_file', 'log_file']: if suffix.endswith('.txt'): change_ext = False if isdefined(inval): outputs[key] = inval else: outputs[key] = self._gen_fname(self.inputs.in_file, suffix='_' + suffix, change_ext=change_ext) elif isdefined(inval): if isinstance(inval, bool): if inval: outputs[key] = self._gen_fname(self.inputs.in_file, suffix='_' + suffix, change_ext=change_ext) else: outputs[key] = os.path.abspath(inval) return outputs def _format_arg(self, name, spec, value): if name in self.filemap.keys(): return spec.argstr % self._list_outputs()[name] return super(FNIRT, self)._format_arg(name, spec, value) def _gen_filename(self, name): if name in ['warped_file', 'log_file']: return self._list_outputs()[name] return None def write_config(self, configfile): """Writes out currently set options to specified config file XX TODO : need to figure out how the config file is written Parameters ---------- configfile : /path/to/configfile """ try: fid = open(configfile, 'w+') except IOError: print ('unable to create config_file %s' % (configfile)) for item in self.inputs.get().items(): fid.write('%s\n' % (item)) fid.close() class ApplyWarpInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='--in=%s', mandatory=True, position=0, desc='image to be warped') out_file = File(argstr='--out=%s', genfile=True, position=2, desc='output filename', hash_files=False) ref_file = File(exists=True, argstr='--ref=%s', mandatory=True, position=1, desc='reference image') field_file = File(exists=True, argstr='--warp=%s', desc='file containing warp field') abswarp = traits.Bool(argstr='--abs', xor=['relwarp'], desc="treat warp field as absolute: x' = w(x)") relwarp = traits.Bool(argstr='--rel', xor=['abswarp'], position=-1, desc="treat warp field as relative: x' = x + w(x)") datatype = traits.Enum('char', 'short', 'int', 'float', 'double', argstr='--datatype=%s', desc='Force output data type [char short int float double].') supersample = traits.Bool(argstr='--super', desc='intermediary supersampling of output, default is off') superlevel = traits.Either(traits.Enum('a'), traits.Int, argstr='--superlevel=%s', desc="level of intermediary supersampling, a for 'automatic' or integer level. Default = 2") premat = File(exists=True, argstr='--premat=%s', desc='filename for pre-transform (affine matrix)') postmat = File(exists=True, argstr='--postmat=%s', desc='filename for post-transform (affine matrix)') mask_file = File(exists=True, argstr='--mask=%s', desc='filename for mask image (in reference space)') interp = traits.Enum( 'nn', 'trilinear', 'sinc', 'spline', argstr='--interp=%s', position=-2, desc='interpolation method') class ApplyWarpOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Warped output file') class ApplyWarp(FSLCommand): """Use FSL's applywarp to apply the results of a FNIRT registration Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> aw = fsl.ApplyWarp() >>> aw.inputs.in_file = example_data('structural.nii') >>> aw.inputs.ref_file = example_data('mni.nii') >>> aw.inputs.field_file = 'my_coefficients_filed.nii' #doctest: +SKIP >>> res = aw.run() #doctest: +SKIP """ _cmd = 'applywarp' input_spec = ApplyWarpInputSpec output_spec = ApplyWarpOutputSpec def _format_arg(self, name, spec, value): if name == 'superlevel': return spec.argstr % str(value) return super(ApplyWarp, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() if not isdefined(self.inputs.out_file): outputs['out_file'] = self._gen_fname(self.inputs.in_file, suffix='_warp') else: outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] return None class SliceTimerInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='--in=%s', mandatory=True, position=0, desc='filename of input timeseries') out_file = File(argstr='--out=%s', genfile=True, desc='filename of output timeseries', hash_files=False) index_dir = traits.Bool(argstr='--down', desc='slice indexing from top to bottom') time_repetition = traits.Float(argstr='--repeat=%f', desc='Specify TR of data - default is 3s') slice_direction = traits.Enum(1, 2, 3, argstr='--direction=%d', desc='direction of slice acquisition (x=1, y=2, z=3) - default is z') interleaved = traits.Bool(argstr='--odd', desc='use interleaved acquisition') custom_timings = File(exists=True, argstr='--tcustom=%s', desc='slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift)') global_shift = traits.Float(argstr='--tglobal', desc='shift in fraction of TR, range 0:1 (default is 0.5 = no shift)') custom_order = File(exists=True, argstr='--ocustom=%s', desc='filename of single-column custom interleave order file (first slice is referred to as 1 not 0)') class SliceTimerOutputSpec(TraitedSpec): slice_time_corrected_file = File( exists=True, desc='slice time corrected file') class SliceTimer(FSLCommand): """ use FSL slicetimer to perform slice timing correction. Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> st = fsl.SliceTimer() >>> st.inputs.in_file = example_data('functional.nii') >>> st.inputs.interleaved = True >>> result = st.run() #doctest: +SKIP """ _cmd = 'slicetimer' input_spec = SliceTimerInputSpec output_spec = SliceTimerOutputSpec def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): out_file = self._gen_fname(self.inputs.in_file, suffix='_st') outputs['slice_time_corrected_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['slice_time_corrected_file'] return None class SUSANInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=1, desc='filename of input timeseries') brightness_threshold = traits.Float(argstr='%.10f', position=2, mandatory=True, desc='brightness threshold and should be greater than ' 'noise level and less than contrast of edges to ' 'be preserved.') fwhm = traits.Float(argstr='%.10f', position=3, mandatory=True, desc='fwhm of smoothing, in mm, gets converted using sqrt(8*log(2))') dimension = traits.Enum(3, 2, argstr='%d', position=4, usedefault=True, desc='within-plane (2) or fully 3D (3)') use_median = traits.Enum(1, 0, argstr='%d', position=5, usedefault=True, desc='whether to use a local median filter in the cases where single-point noise is detected') usans = traits.List( traits.Tuple(File(exists=True), traits.Float), maxlen=2, argstr='', position=6, default=[], usedefault=True, desc='determines whether the smoothing area (USAN) is to be ' 'found from secondary images (0, 1 or 2). A negative ' 'value for any brightness threshold will auto-set the ' 'threshold at 10% of the robust range') out_file = File(argstr='%s', position=-1, genfile=True, desc='output file name', hash_files=False) class SUSANOutputSpec(TraitedSpec): smoothed_file = File(exists=True, desc='smoothed output file') class SUSAN(FSLCommand): """ use FSL SUSAN to perform smoothing Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> print anatfile #doctest: +SKIP anatomical.nii #doctest: +SKIP >>> sus = fsl.SUSAN() >>> sus.inputs.in_file = example_data('structural.nii') >>> sus.inputs.brightness_threshold = 2000.0 >>> sus.inputs.fwhm = 8.0 >>> result = sus.run() #doctest: +SKIP """ _cmd = 'susan' input_spec = SUSANInputSpec output_spec = SUSANOutputSpec def _format_arg(self, name, spec, value): if name == 'fwhm': return spec.argstr % (float(value) / np.sqrt(8 * np.log(2))) if name == 'usans': if not value: return '0' arglist = [str(len(value))] for filename, thresh in value: arglist.extend([filename, '%.10f' % thresh]) return ' '.join(arglist) return super(SUSAN, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): out_file = self._gen_fname(self.inputs.in_file, suffix='_smooth') outputs['smoothed_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['smoothed_file'] return None class FUGUEInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='--in=%s', desc='filename of input volume') shift_in_file = File(exists=True, argstr='--loadshift=%s', desc='filename for reading pixel shift volume') phasemap_in_file = File(exists=True, argstr='--phasemap=%s', desc='filename for input phase image') fmap_in_file = File(exists=True, argstr='--loadfmap=%s', desc='filename for loading fieldmap (rad/s)') unwarped_file = File(argstr='--unwarp=%s', desc='apply unwarping and save as filename', xor=['warped_file'], requires=['in_file']) warped_file = File(argstr='--warp=%s', desc='apply forward warping and save as filename', xor=['unwarped_file'], requires=['in_file']) forward_warping = traits.Bool(False, usedefault=True, desc='apply forward warping instead of unwarping') dwell_to_asym_ratio = traits.Float(argstr='--dwelltoasym=%.10f', desc='set the dwell to asym time ratio') dwell_time = traits.Float(argstr='--dwell=%.10f', desc=('set the EPI dwell time per phase-encode line - same as echo ' 'spacing - (sec)')) asym_se_time = traits.Float(argstr='--asym=%.10f', desc='set the fieldmap asymmetric spin echo time (sec)') median_2dfilter = traits.Bool(argstr='--median', desc='apply 2D median filtering') despike_2dfilter = traits.Bool(argstr='--despike', desc='apply a 2D de-spiking filter') no_gap_fill = traits.Bool(argstr='--nofill', desc='do not apply gap-filling measure to the fieldmap') no_extend = traits.Bool(argstr='--noextend', desc='do not apply rigid-body extrapolation to the fieldmap') smooth2d = traits.Float(argstr='--smooth2=%.2f', desc='apply 2D Gaussian smoothing of sigma N (in mm)') smooth3d = traits.Float(argstr='--smooth3=%.2f', desc='apply 3D Gaussian smoothing of sigma N (in mm)') poly_order = traits.Int(argstr='--poly=%d', desc='apply polynomial fitting of order N') fourier_order = traits.Int(argstr='--fourier=%d', desc='apply Fourier (sinusoidal) fitting of order N') pava = traits.Bool(argstr='--pava', desc='apply monotonic enforcement via PAVA') despike_threshold = traits.Float(argstr='--despikethreshold=%s', desc='specify the threshold for de-spiking (default=3.0)') unwarp_direction = traits.Enum('x', 'y', 'z', 'x-', 'y-', 'z-', argstr='--unwarpdir=%s', desc='specifies direction of warping (default y)') phase_conjugate = traits.Bool(argstr='--phaseconj', desc='apply phase conjugate method of unwarping') icorr = traits.Bool(argstr='--icorr', requires=['shift_in_file'], desc='apply intensity correction to unwarping (pixel shift method only)') icorr_only = traits.Bool(argstr='--icorronly', requires=['unwarped_file'], desc='apply intensity correction only') mask_file = File(exists=True, argstr='--mask=%s', desc='filename for loading valid mask') nokspace = traits.Bool(False, argstr='--nokspace', desc='do not use k-space forward warping') # Special outputs: shift (voxel shift map, vsm) save_shift = traits.Bool(False, xor=['save_unmasked_shift'], desc='write pixel shift volume') shift_out_file = File(argstr='--saveshift=%s', desc='filename for saving pixel shift volume') save_unmasked_shift = traits.Bool(argstr='--unmaskshift', xor=['save_shift'], desc='saves the unmasked shiftmap when using --saveshift') # Special outputs: fieldmap (fmap) save_fmap = traits.Bool(False, xor=['save_unmasked_fmap'], desc='write field map volume') fmap_out_file = File(argstr='--savefmap=%s', desc='filename for saving fieldmap (rad/s)') save_unmasked_fmap = traits.Bool(False, argstr='--unmaskfmap', xor=['save_fmap'], desc='saves the unmasked fieldmap when using --savefmap') class FUGUEOutputSpec(TraitedSpec): unwarped_file = File(desc='unwarped file') warped_file = File(desc='forward warped file') shift_out_file = File(desc='voxel shift map file') fmap_out_file = File(desc='fieldmap file') class FUGUE(FSLCommand): """ `FUGUE `_ is, most generally, a set of tools for EPI distortion correction. Distortions may be corrected for 1. improving registration with non-distorted images (e.g. structurals), or 2. dealing with motion-dependent changes. FUGUE is designed to deal only with the first case - improving registration. Examples -------- Unwarping an input image (shift map is known) >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() >>> fugue.inputs.in_file = 'epi.nii' >>> fugue.inputs.mask_file = 'epi_mask.nii' >>> fugue.inputs.shift_in_file = 'vsm.nii' # Previously computed with fugue as well >>> fugue.inputs.unwarp_direction = 'y' >>> fugue.inputs.output_type = "NIFTI_GZ" >>> fugue.cmdline #doctest: +ELLIPSIS 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --unwarp=epi_unwarped.nii.gz' >>> fugue.run() #doctest: +SKIP Warping an input image (shift map is known) >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() >>> fugue.inputs.in_file = 'epi.nii' >>> fugue.inputs.forward_warping = True >>> fugue.inputs.mask_file = 'epi_mask.nii' >>> fugue.inputs.shift_in_file = 'vsm.nii' # Previously computed with fugue as well >>> fugue.inputs.unwarp_direction = 'y' >>> fugue.inputs.output_type = "NIFTI_GZ" >>> fugue.cmdline #doctest: +ELLIPSIS 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --warp=epi_warped.nii.gz' >>> fugue.run() #doctest: +SKIP Computing the vsm (unwrapped phase map is known) >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() >>> fugue.inputs.phasemap_in_file = 'epi_phasediff.nii' >>> fugue.inputs.mask_file = 'epi_mask.nii' >>> fugue.inputs.dwell_to_asym_ratio = (0.77e-3 * 3) / 2.46e-3 >>> fugue.inputs.unwarp_direction = 'y' >>> fugue.inputs.save_shift = True >>> fugue.inputs.output_type = "NIFTI_GZ" >>> fugue.cmdline #doctest: +ELLIPSIS 'fugue --dwelltoasym=0.9390243902 --mask=epi_mask.nii --phasemap=epi_phasediff.nii --saveshift=epi_phasediff_vsm.nii.gz --unwarpdir=y' >>> fugue.run() #doctest: +SKIP """ _cmd = 'fugue' input_spec = FUGUEInputSpec output_spec = FUGUEOutputSpec def _parse_inputs(self, skip=None): if skip is None: skip = [] input_phase = isdefined(self.inputs.phasemap_in_file) input_vsm = isdefined(self.inputs.shift_in_file) input_fmap = isdefined(self.inputs.fmap_in_file) if not input_phase and not input_vsm and not input_fmap: raise RuntimeError('Either phasemap_in_file, shift_in_file or fmap_in_file must be set.') if not isdefined(self.inputs.in_file): skip += ['unwarped_file', 'warped_file'] else: if self.inputs.forward_warping: skip += ['unwarped_file'] trait_spec = self.inputs.trait('warped_file') trait_spec.name_template = "%s_warped" trait_spec.name_source = 'in_file' trait_spec.output_name = 'warped_file' else: skip += ['warped_file'] trait_spec = self.inputs.trait('unwarped_file') trait_spec.name_template = "%s_unwarped" trait_spec.name_source = 'in_file' trait_spec.output_name = 'unwarped_file' # Handle shift output if not isdefined(self.inputs.shift_out_file): vsm_save_masked = (isdefined(self.inputs.save_shift) and self.inputs.save_shift) vsm_save_unmasked = (isdefined(self.inputs.save_unmasked_shift) and self.inputs.save_unmasked_shift) if (vsm_save_masked or vsm_save_unmasked): trait_spec = self.inputs.trait('shift_out_file') trait_spec.output_name = 'shift_out_file' if input_fmap: trait_spec.name_source = 'fmap_in_file' elif input_phase: trait_spec.name_source = 'phasemap_in_file' elif input_vsm: trait_spec.name_source = 'shift_in_file' else: raise RuntimeError(('Either phasemap_in_file, shift_in_file or ' 'fmap_in_file must be set.')) if vsm_save_unmasked: trait_spec.name_template = '%s_vsm_unmasked' else: trait_spec.name_template = '%s_vsm' else: skip += ['save_shift', 'save_unmasked_shift', 'shift_out_file'] # Handle fieldmap output if not isdefined(self.inputs.fmap_out_file): fmap_save_masked = (isdefined(self.inputs.save_fmap) and self.inputs.save_fmap) fmap_save_unmasked = (isdefined(self.inputs.save_unmasked_fmap) and self.inputs.save_unmasked_fmap) if (fmap_save_masked or fmap_save_unmasked): trait_spec = self.inputs.trait('fmap_out_file') trait_spec.output_name = 'fmap_out_file' if input_vsm: trait_spec.name_source = 'shift_in_file' elif input_phase: trait_spec.name_source = 'phasemap_in_file' elif input_fmap: trait_spec.name_source = 'fmap_in_file' else: raise RuntimeError(('Either phasemap_in_file, shift_in_file or ' 'fmap_in_file must be set.')) if fmap_save_unmasked: trait_spec.name_template = '%s_fieldmap_unmasked' else: trait_spec.name_template = '%s_fieldmap' else: skip += ['save_fmap', 'save_unmasked_fmap', 'fmap_out_file'] return super(FUGUE, self)._parse_inputs(skip=skip) class PRELUDEInputSpec(FSLCommandInputSpec): complex_phase_file = File(exists=True, argstr='--complex=%s', mandatory=True, xor=[ 'magnitude_file', 'phase_file'], desc='complex phase input volume') magnitude_file = File(exists=True, argstr='--abs=%s', mandatory=True, xor=['complex_phase_file'], desc='file containing magnitude image') phase_file = File(exists=True, argstr='--phase=%s', mandatory=True, xor=['complex_phase_file'], desc='raw phase file') unwrapped_phase_file = File(genfile=True, argstr='--unwrap=%s', desc='file containing unwrapepd phase', hash_files=False) num_partitions = traits.Int(argstr='--numphasesplit=%d', desc='number of phase partitions to use') labelprocess2d = traits.Bool(argstr='--labelslices', desc='does label processing in 2D (slice at a time)') process2d = traits.Bool(argstr='--slices', xor=['labelprocess2d'], desc='does all processing in 2D (slice at a time)') process3d = traits.Bool(argstr='--force3D', xor=['labelprocess2d', 'process2d'], desc='forces all processing to be full 3D') threshold = traits.Float(argstr='--thresh=%.10f', desc='intensity threshold for masking') mask_file = File(exists=True, argstr='--mask=%s', desc='filename of mask input volume') start = traits.Int(argstr='--start=%d', desc='first image number to process (default 0)') end = traits.Int(argstr='--end=%d', desc='final image number to process (default Inf)') savemask_file = File(argstr='--savemask=%s', desc='saving the mask volume', hash_files=False) rawphase_file = File(argstr='--rawphase=%s', desc='saving the raw phase output', hash_files=False) label_file = File(argstr='--labels=%s', desc='saving the area labels output', hash_files=False) removeramps = traits.Bool(argstr='--removeramps', desc='remove phase ramps during unwrapping') class PRELUDEOutputSpec(TraitedSpec): unwrapped_phase_file = File(exists=True, desc='unwrapped phase file') class PRELUDE(FSLCommand): """Use FSL prelude to do phase unwrapping Examples -------- Please insert examples for use of this command """ input_spec = PRELUDEInputSpec output_spec = PRELUDEOutputSpec _cmd = 'prelude' def __init__(self, **kwargs): super(PRELUDE, self).__init__(**kwargs) warn('This has not been fully tested. Please report any failures.') def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.unwrapped_phase_file if not isdefined(out_file): if isdefined(self.inputs.phase_file): out_file = self._gen_fname(self.inputs.phase_file, suffix='_unwrapped') elif isdefined(self.inputs.complex_phase_file): out_file = self._gen_fname(self.inputs.complex_phase_file, suffix='_phase_unwrapped') outputs['unwrapped_phase_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'unwrapped_phase_file': return self._list_outputs()['unwrapped_phase_file'] return None class FIRSTInputSpec(FSLCommandInputSpec): in_file = File( exists=True, mandatory=True, position=-2, copyfile=False, argstr='-i %s', desc='input data file') out_file = File( 'segmented', usedefault=True, mandatory=True, position=-1, argstr='-o %s', desc='output data file', hash_files=False) verbose = traits.Bool(argstr='-v', position=1, desc="Use verbose logging.") brain_extracted = traits.Bool( argstr='-b', position=2, desc="Input structural image is already brain-extracted") no_cleanup = traits.Bool( argstr='-d', position=3, desc="Input structural image is already brain-extracted") method = traits.Enum( 'auto', 'fast', 'none', xor=['method_as_numerical_threshold'], argstr='-m %s', position=4, usedefault=True, desc=("Method must be one of auto, fast, none, or it can be entered " "using the 'method_as_numerical_threshold' input")) method_as_numerical_threshold = traits.Float( argstr='-m %.4f', position=4, desc=("Specify a numerical threshold value or use the 'method' input " "to choose auto, fast, or none")) list_of_specific_structures = traits.List( traits.Str, argstr='-s %s', sep=',', position=5, minlen=1, desc='Runs only on the specified structures (e.g. L_Hipp, R_Hipp' 'L_Accu, R_Accu, L_Amyg, R_Amyg' 'L_Caud, R_Caud, L_Pall, R_Pall' 'L_Puta, R_Puta, L_Thal, R_Thal, BrStem') affine_file = File( exists=True, position=6, argstr='-a %s', desc=('Affine matrix to use (e.g. img2std.mat) (does not ' 're-run registration)')) class FIRSTOutputSpec(TraitedSpec): vtk_surfaces = OutputMultiPath( File(exists=True), desc='VTK format meshes for each subcortical region') bvars = OutputMultiPath( File(exists=True), desc='bvars for each subcortical region') original_segmentations = File( exists=True, desc=('3D image file containing the segmented regions ' 'as integer values. Uses CMA labelling')) segmentation_file = File( exists=True, desc=('4D image file containing a single volume per ' 'segmented region')) class FIRST(FSLCommand): """ Use FSL's run_first_all command to segment subcortical volumes http://www.fmrib.ox.ac.uk/fsl/first/index.html Examples -------- >>> from nipype.interfaces import fsl >>> first = fsl.FIRST() >>> first.inputs.in_file = 'structural.nii' >>> first.inputs.out_file = 'segmented.nii' >>> res = first.run() #doctest: +SKIP """ _cmd = 'run_first_all' input_spec = FIRSTInputSpec output_spec = FIRSTOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.list_of_specific_structures): structures = self.inputs.list_of_specific_structures else: structures = ['L_Hipp', 'R_Hipp', 'L_Accu', 'R_Accu', 'L_Amyg', 'R_Amyg', 'L_Caud', 'R_Caud', 'L_Pall', 'R_Pall', 'L_Puta', 'R_Puta', 'L_Thal', 'R_Thal', 'BrStem'] outputs['original_segmentations'] = \ self._gen_fname('original_segmentations') outputs['segmentation_file'] = self._gen_fname('segmentation_file') outputs['vtk_surfaces'] = self._gen_mesh_names('vtk_surfaces', structures) outputs['bvars'] = self._gen_mesh_names('bvars', structures) return outputs def _gen_fname(self, name): path, outname, ext = split_filename(self.inputs.out_file) method = 'none' if isdefined(self.inputs.method) and self.inputs.method == 'fast': method = 'fast' if isdefined(self.inputs.method_as_numerical_threshold): thres = '%.4f' % self.inputs.method_as_numerical_threshold method = thres.replace('.', '') if name == 'original_segmentations': return op.abspath('%s_all_%s_origsegs.nii.gz' % (outname, method)) if name == 'segmentation_file': return op.abspath('%s_all_%s_firstseg.nii.gz' % (outname, method)) return None def _gen_mesh_names(self, name, structures): path, prefix, ext = split_filename(self.inputs.out_file) if name == 'vtk_surfaces': vtks = list() for struct in structures: vtk = prefix + '-' + struct + '_first.vtk' vtks.append(op.abspath(vtk)) return vtks if name == 'bvars': bvars = list() for struct in structures: bvar = prefix + '-' + struct + '_first.bvars' bvars.append(op.abspath(bvar)) return bvars return Nonenipype-0.11.0/nipype/interfaces/fsl/tests/000077500000000000000000000000001257611314500204575ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/fsl/tests/test_BEDPOSTX.py000066400000000000000000000002151257611314500233160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import BEDPOSTX nipype-0.11.0/nipype/interfaces/fsl/tests/test_FILMGLS.py000066400000000000000000000100561257611314500231670ustar00rootroot00000000000000from nipype.testing import assert_equal from nipype.interfaces.fsl.model import FILMGLS, FILMGLSInputSpec def test_filmgls(): input_map = dict(args = dict(argstr='%s',), autocorr_estimate_only = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='-ac',), autocorr_noestimate = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='-noest',), brightness_threshold = dict(argstr='-epith %d',), design_file = dict(argstr='%s',), environ = dict(usedefault=True,), fit_armodel = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='-ar',), full_data = dict(argstr='-v',), ignore_exception = dict(usedefault=True,), in_file = dict(mandatory=True,argstr='%s',), mask_size = dict(argstr='-ms %d',), multitaper_product = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='-mt %d',), output_pwdata = dict(argstr='-output_pwdata',), output_type = dict(), results_dir = dict(usedefault=True,argstr='-rn %s',), smooth_autocorr = dict(argstr='-sa',), threshold = dict(argstr='%f',), tukey_window = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='-tukey %d',), use_pava = dict(argstr='-pava',), ) input_map2 = dict(args = dict(argstr='%s',), autocorr_estimate_only = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='--ac',), autocorr_noestimate = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='--noest',), brightness_threshold = dict(argstr='--epith=%d',), design_file = dict(argstr='--pd=%s',), environ = dict(usedefault=True,), fit_armodel = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='--ar',), full_data = dict(argstr='-v',), ignore_exception = dict(usedefault=True,), in_file = dict(mandatory=True,argstr='--in=%s',), mask_size = dict(argstr='--ms=%d',), multitaper_product = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='--mt=%d',), output_pwdata = dict(argstr='--outputPWdata',), output_type = dict(), results_dir = dict(argstr='--rn=%s',usedefault=True,), smooth_autocorr = dict(argstr='--sa',), terminal_output = dict(), threshold = dict(usedefault=True,argstr='--thr=%f',), tukey_window = dict(xor=['autocorr_estimate_only', 'fit_armodel', 'tukey_window', 'multitaper_product', 'use_pava', 'autocorr_noestimate'],argstr='--tukey=%d',), use_pava = dict(argstr='--pava',), ) instance = FILMGLS() if isinstance(instance.inputs, FILMGLSInputSpec): for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(instance.inputs.traits()[key], metakey), value else: for key, metadata in input_map2.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(instance.inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_XFibres.py000066400000000000000000000001271257611314500234320ustar00rootroot00000000000000from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import XFibres nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ApplyMask.py000066400000000000000000000025171257611314500250260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import ApplyMask def test_ApplyMask_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), mask_file=dict(argstr='-mas %s', mandatory=True, position=4, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = ApplyMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyMask_outputs(): output_map = dict(out_file=dict(), ) outputs = ApplyMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ApplyTOPUP.py000066400000000000000000000030771257611314500250440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import ApplyTOPUP def test_ApplyTOPUP_inputs(): input_map = dict(args=dict(argstr='%s', ), datatype=dict(argstr='-d=%s', ), encoding_file=dict(argstr='--datain=%s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='--imain=%s', mandatory=True, sep=',', ), in_index=dict(argstr='--inindex=%s', mandatory=True, sep=',', ), in_topup_fieldcoef=dict(argstr='--topup=%s', copyfile=False, requires=['in_topup_movpar'], ), in_topup_movpar=dict(copyfile=False, requires=['in_topup_fieldcoef'], ), interp=dict(argstr='--interp=%s', ), method=dict(argstr='--method=%s', ), out_corrected=dict(argstr='--out=%s', name_source=['in_files'], name_template='%s_corrected', ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = ApplyTOPUP.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyTOPUP_outputs(): output_map = dict(out_corrected=dict(), ) outputs = ApplyTOPUP.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ApplyWarp.py000066400000000000000000000032651257611314500250450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import ApplyWarp def test_ApplyWarp_inputs(): input_map = dict(abswarp=dict(argstr='--abs', xor=['relwarp'], ), args=dict(argstr='%s', ), datatype=dict(argstr='--datatype=%s', ), environ=dict(nohash=True, usedefault=True, ), field_file=dict(argstr='--warp=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, position=0, ), interp=dict(argstr='--interp=%s', position=-2, ), mask_file=dict(argstr='--mask=%s', ), out_file=dict(argstr='--out=%s', genfile=True, hash_files=False, position=2, ), output_type=dict(), postmat=dict(argstr='--postmat=%s', ), premat=dict(argstr='--premat=%s', ), ref_file=dict(argstr='--ref=%s', mandatory=True, position=1, ), relwarp=dict(argstr='--rel', position=-1, xor=['abswarp'], ), superlevel=dict(argstr='--superlevel=%s', ), supersample=dict(argstr='--super', ), terminal_output=dict(nohash=True, ), ) inputs = ApplyWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyWarp_outputs(): output_map = dict(out_file=dict(), ) outputs = ApplyWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ApplyXfm.py000066400000000000000000000076671257611314500247000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import ApplyXfm def test_ApplyXfm_inputs(): input_map = dict(angle_rep=dict(argstr='-anglerep %s', ), apply_isoxfm=dict(argstr='-applyisoxfm %f', xor=['apply_xfm'], ), apply_xfm=dict(argstr='-applyxfm', requires=['in_matrix_file'], usedefault=True, ), args=dict(argstr='%s', ), bbrslope=dict(argstr='-bbrslope %f', min_ver='5.0.0', ), bbrtype=dict(argstr='-bbrtype %s', min_ver='5.0.0', ), bgvalue=dict(argstr='-setbackground %f', ), bins=dict(argstr='-bins %d', ), coarse_search=dict(argstr='-coarsesearch %d', units='degrees', ), cost=dict(argstr='-cost %s', ), cost_func=dict(argstr='-searchcost %s', ), datatype=dict(argstr='-datatype %s', ), display_init=dict(argstr='-displayinit', ), dof=dict(argstr='-dof %d', ), echospacing=dict(argstr='-echospacing %f', min_ver='5.0.0', ), environ=dict(nohash=True, usedefault=True, ), fieldmap=dict(argstr='-fieldmap %s', min_ver='5.0.0', ), fieldmapmask=dict(argstr='-fieldmapmask %s', min_ver='5.0.0', ), fine_search=dict(argstr='-finesearch %d', units='degrees', ), force_scaling=dict(argstr='-forcescaling', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-in %s', mandatory=True, position=0, ), in_matrix_file=dict(argstr='-init %s', ), in_weight=dict(argstr='-inweight %s', ), interp=dict(argstr='-interp %s', ), min_sampling=dict(argstr='-minsampling %f', units='mm', ), no_clamp=dict(argstr='-noclamp', ), no_resample=dict(argstr='-noresample', ), no_resample_blur=dict(argstr='-noresampblur', ), no_search=dict(argstr='-nosearch', ), out_file=dict(argstr='-out %s', hash_files=False, name_source=['in_file'], name_template='%s_flirt', position=2, ), out_log=dict(keep_extension=True, name_source=['in_file'], name_template='%s_flirt.log', requires=['save_log'], ), out_matrix_file=dict(argstr='-omat %s', hash_files=False, keep_extension=True, name_source=['in_file'], name_template='%s_flirt.mat', position=3, ), output_type=dict(), padding_size=dict(argstr='-paddingsize %d', units='voxels', ), pedir=dict(argstr='-pedir %d', min_ver='5.0.0', ), ref_weight=dict(argstr='-refweight %s', ), reference=dict(argstr='-ref %s', mandatory=True, position=1, ), rigid2D=dict(argstr='-2D', ), save_log=dict(), schedule=dict(argstr='-schedule %s', ), searchr_x=dict(argstr='-searchrx %s', units='degrees', ), searchr_y=dict(argstr='-searchry %s', units='degrees', ), searchr_z=dict(argstr='-searchrz %s', units='degrees', ), sinc_width=dict(argstr='-sincwidth %d', units='voxels', ), sinc_window=dict(argstr='-sincwindow %s', ), terminal_output=dict(nohash=True, ), uses_qform=dict(argstr='-usesqform', ), verbose=dict(argstr='-verbose %d', ), wm_seg=dict(argstr='-wmseg %s', min_ver='5.0.0', ), wmcoords=dict(argstr='-wmcoords %s', min_ver='5.0.0', ), wmnorms=dict(argstr='-wmnorms %s', min_ver='5.0.0', ), ) inputs = ApplyXfm.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyXfm_outputs(): output_map = dict(out_file=dict(), out_log=dict(), out_matrix_file=dict(), ) outputs = ApplyXfm.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_AvScale.py000066400000000000000000000022441257611314500244400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import AvScale def test_AvScale_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mat_file=dict(argstr='%s', position=0, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = AvScale.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AvScale_outputs(): output_map = dict(average_scaling=dict(), backward_half_transform=dict(), determinant=dict(), forward_half_transform=dict(), left_right_orientation_preserved=dict(), rotation_translation_matrix=dict(), scales=dict(), skews=dict(), ) outputs = AvScale.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_BEDPOSTX4.py000066400000000000000000000050231257611314500244340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import BEDPOSTX4 def test_BEDPOSTX4_inputs(): input_map = dict(all_ard=dict(argstr='--allard', xor=('no_ard', 'all_ard'), ), args=dict(argstr='%s', ), bpx_directory=dict(argstr='%s', usedefault=True, ), burn_in=dict(argstr='--burnin=%d', ), burn_in_no_ard=dict(argstr='--burninnoard=%d', ), burn_period=dict(argstr='-b %d', ), bvals=dict(mandatory=True, ), bvecs=dict(mandatory=True, ), dwi=dict(mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), fibres=dict(argstr='-n %d', ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fudge=dict(argstr='--fudge=%d', ), gradnonlin=dict(argstr='--gradnonlin=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), jumps=dict(argstr='-j %d', ), logdir=dict(argstr='--logdir=%s', usedefault=True, ), mask=dict(mandatory=True, ), model=dict(argstr='-model %d', ), n_fibres=dict(argstr='--nfibres=%d', ), n_jumps=dict(argstr='--njumps=%d', ), nlgradient=dict(argstr='-g', ), no_ard=dict(argstr='--noard', xor=('no_ard', 'all_ard'), ), no_cuda=dict(argstr='-c', ), no_spat=dict(argstr='--nospat', xor=('no_spat', 'non_linear'), ), non_linear=dict(argstr='--nonlinear', xor=('no_spat', 'non_linear'), ), output_type=dict(), sample_every=dict(argstr='--sampleevery=%d', ), sampling=dict(argstr='-s %d', ), seed=dict(argstr='--seed=%d', ), terminal_output=dict(nohash=True, ), update_proposal_every=dict(argstr='--updateproposalevery=%d', ), weight=dict(argstr='-w %.2f', ), ) inputs = BEDPOSTX4.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BEDPOSTX4_outputs(): output_map = dict(bpx_out_directory=dict(), dyads=dict(), mean_fsamples=dict(), mean_phsamples=dict(), mean_thsamples=dict(), merged_fsamples=dict(), merged_phsamples=dict(), merged_thsamples=dict(), xfms_directory=dict(), ) outputs = BEDPOSTX4.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_BEDPOSTX5.py000066400000000000000000000051541257611314500244420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import BEDPOSTX5 def test_BEDPOSTX5_inputs(): input_map = dict(all_ard=dict(argstr='--allard', xor=('no_ard', 'all_ard'), ), args=dict(argstr='%s', ), burn_in=dict(argstr='-b %d', ), burn_in_no_ard=dict(argstr='--burninnoard=%d', ), bvals=dict(mandatory=True, ), bvecs=dict(mandatory=True, ), cnlinear=dict(argstr='--cnonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), dwi=dict(mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), f0_ard=dict(argstr='--f0 --ardf0', xor=['f0_noard', 'f0_ard', 'all_ard'], ), f0_noard=dict(argstr='--f0', xor=['f0_noard', 'f0_ard'], ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fudge=dict(argstr='-w %d', ), gradnonlin=dict(argstr='-g', ), ignore_exception=dict(nohash=True, usedefault=True, ), logdir=dict(argstr='--logdir=%s', ), mask=dict(mandatory=True, ), model=dict(argstr='-model %d', ), n_fibres=dict(argstr='-n %d', mandatory=True, usedefault=True, ), n_jumps=dict(argstr='-j %d', ), no_ard=dict(argstr='--noard', xor=('no_ard', 'all_ard'), ), no_spat=dict(argstr='--nospat', xor=('no_spat', 'non_linear', 'cnlinear'), ), non_linear=dict(argstr='--nonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), out_dir=dict(argstr='%s', mandatory=True, position=1, usedefault=True, ), output_type=dict(), rician=dict(argstr='--rician', ), sample_every=dict(argstr='-s %d', ), seed=dict(argstr='--seed=%d', ), terminal_output=dict(nohash=True, ), update_proposal_every=dict(argstr='--updateproposalevery=%d', ), use_gpu=dict(), ) inputs = BEDPOSTX5.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BEDPOSTX5_outputs(): output_map = dict(dyads=dict(), dyads_dispersion=dict(), mean_S0samples=dict(), mean_dsamples=dict(), mean_fsamples=dict(), mean_phsamples=dict(), mean_thsamples=dict(), merged_fsamples=dict(), merged_phsamples=dict(), merged_thsamples=dict(), ) outputs = BEDPOSTX5.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_BET.py000066400000000000000000000052631257611314500235400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import BET def test_BET_inputs(): input_map = dict(args=dict(argstr='%s', ), center=dict(argstr='-c %s', units='voxels', ), environ=dict(nohash=True, usedefault=True, ), frac=dict(argstr='-f %.2f', ), functional=dict(argstr='-F', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), mask=dict(argstr='-m', ), mesh=dict(argstr='-e', ), no_output=dict(argstr='-n', ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=1, ), outline=dict(argstr='-o', ), output_type=dict(), padding=dict(argstr='-Z', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), radius=dict(argstr='-r %d', units='mm', ), reduce_bias=dict(argstr='-B', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), remove_eyes=dict(argstr='-S', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), robust=dict(argstr='-R', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), skull=dict(argstr='-s', ), surfaces=dict(argstr='-A', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), t2_guided=dict(argstr='-A2 %s', xor=('functional', 'reduce_bias', 'robust', 'padding', 'remove_eyes', 'surfaces', 't2_guided'), ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='-t', ), vertical_gradient=dict(argstr='-g %.2f', ), ) inputs = BET.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BET_outputs(): output_map = dict(inskull_mask_file=dict(), inskull_mesh_file=dict(), mask_file=dict(), meshfile=dict(), out_file=dict(), outline_file=dict(), outskin_mask_file=dict(), outskin_mesh_file=dict(), outskull_mask_file=dict(), outskull_mesh_file=dict(), skull_mask_file=dict(), ) outputs = BET.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_BinaryMaths.py000066400000000000000000000030511257611314500253400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import BinaryMaths def test_BinaryMaths_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), operand_file=dict(argstr='%s', mandatory=True, position=5, xor=['operand_value'], ), operand_value=dict(argstr='%.8f', mandatory=True, position=5, xor=['operand_file'], ), operation=dict(argstr='-%s', mandatory=True, position=4, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = BinaryMaths.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BinaryMaths_outputs(): output_map = dict(out_file=dict(), ) outputs = BinaryMaths.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ChangeDataType.py000066400000000000000000000024541257611314500257460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import ChangeDataType def test_ChangeDataType_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', mandatory=True, position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = ChangeDataType.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ChangeDataType_outputs(): output_map = dict(out_file=dict(), ) outputs = ChangeDataType.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Cluster.py000066400000000000000000000047041257611314500245460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import Cluster def test_Cluster_inputs(): input_map = dict(args=dict(argstr='%s', ), connectivity=dict(argstr='--connectivity=%d', ), cope_file=dict(argstr='--cope=%s', ), dlh=dict(argstr='--dlh=%.10f', ), environ=dict(nohash=True, usedefault=True, ), find_min=dict(), fractional=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, ), minclustersize=dict(argstr='--minclustersize', ), no_table=dict(), num_maxima=dict(argstr='--num=%d', ), out_index_file=dict(argstr='--oindex=%s', hash_files=False, ), out_localmax_txt_file=dict(argstr='--olmax=%s', hash_files=False, ), out_localmax_vol_file=dict(argstr='--olmaxim=%s', hash_files=False, ), out_max_file=dict(argstr='--omax=%s', hash_files=False, ), out_mean_file=dict(argstr='--omean=%s', hash_files=False, ), out_pval_file=dict(argstr='--opvals=%s', hash_files=False, ), out_size_file=dict(argstr='--osize=%s', hash_files=False, ), out_threshold_file=dict(argstr='--othresh=%s', hash_files=False, ), output_type=dict(), peak_distance=dict(argstr='--peakdist=%.10f', ), pthreshold=dict(argstr='--pthresh=%.10f', requires=['dlh', 'volume'], ), std_space_file=dict(argstr='--stdvol=%s', ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--thresh=%.10f', mandatory=True, ), use_mm=dict(), volume=dict(argstr='--volume=%d', ), warpfield_file=dict(argstr='--warpvol=%s', ), xfm_file=dict(argstr='--xfm=%s', ), ) inputs = Cluster.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Cluster_outputs(): output_map = dict(index_file=dict(), localmax_txt_file=dict(), localmax_vol_file=dict(), max_file=dict(), mean_file=dict(), pval_file=dict(), size_file=dict(), threshold_file=dict(), ) outputs = Cluster.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Complex.py000066400000000000000000000073371257611314500245410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Complex def test_Complex_inputs(): input_map = dict(args=dict(argstr='%s', ), complex_cartesian=dict(argstr='-complex', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), complex_in_file=dict(argstr='%s', position=2, ), complex_in_file2=dict(argstr='%s', position=3, ), complex_merge=dict(argstr='-complexmerge', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge', 'start_vol', 'end_vol'], ), complex_out_file=dict(argstr='%s', genfile=True, position=-3, xor=['complex_out_file', 'magnitude_out_file', 'phase_out_file', 'real_out_file', 'imaginary_out_file', 'real_polar', 'real_cartesian'], ), complex_polar=dict(argstr='-complexpolar', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), complex_split=dict(argstr='-complexsplit', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), end_vol=dict(argstr='%d', position=-1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), imaginary_in_file=dict(argstr='%s', position=3, ), imaginary_out_file=dict(argstr='%s', genfile=True, position=-3, xor=['complex_out_file', 'magnitude_out_file', 'phase_out_file', 'real_polar', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), magnitude_in_file=dict(argstr='%s', position=2, ), magnitude_out_file=dict(argstr='%s', genfile=True, position=-4, xor=['complex_out_file', 'real_out_file', 'imaginary_out_file', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), output_type=dict(), phase_in_file=dict(argstr='%s', position=3, ), phase_out_file=dict(argstr='%s', genfile=True, position=-3, xor=['complex_out_file', 'real_out_file', 'imaginary_out_file', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), real_cartesian=dict(argstr='-realcartesian', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), real_in_file=dict(argstr='%s', position=2, ), real_out_file=dict(argstr='%s', genfile=True, position=-4, xor=['complex_out_file', 'magnitude_out_file', 'phase_out_file', 'real_polar', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), real_polar=dict(argstr='-realpolar', position=1, xor=['real_polar', 'real_cartesian', 'complex_cartesian', 'complex_polar', 'complex_split', 'complex_merge'], ), start_vol=dict(argstr='%d', position=-2, ), terminal_output=dict(nohash=True, ), ) inputs = Complex.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Complex_outputs(): output_map = dict(complex_out_file=dict(), imaginary_out_file=dict(), magnitude_out_file=dict(), phase_out_file=dict(), real_out_file=dict(), ) outputs = Complex.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ContrastMgr.py000066400000000000000000000030431257611314500253630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import ContrastMgr def test_ContrastMgr_inputs(): input_map = dict(args=dict(argstr='%s', ), contrast_num=dict(argstr='-cope', ), corrections=dict(copyfile=False, mandatory=True, ), dof_file=dict(argstr='', copyfile=False, mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), fcon_file=dict(argstr='-f %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), output_type=dict(), param_estimates=dict(argstr='', copyfile=False, mandatory=True, ), sigmasquareds=dict(argstr='', copyfile=False, mandatory=True, position=-2, ), suffix=dict(argstr='-suffix %s', ), tcon_file=dict(argstr='%s', mandatory=True, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = ContrastMgr.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ContrastMgr_outputs(): output_map = dict(copes=dict(), fstats=dict(), neffs=dict(), tstats=dict(), varcopes=dict(), zfstats=dict(), zstats=dict(), ) outputs = ContrastMgr.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ConvertWarp.py000066400000000000000000000036341257611314500254000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ConvertWarp def test_ConvertWarp_inputs(): input_map = dict(abswarp=dict(argstr='--abs', xor=['relwarp'], ), args=dict(argstr='%s', ), cons_jacobian=dict(argstr='--constrainj', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), jacobian_max=dict(argstr='--jmax=%f', ), jacobian_min=dict(argstr='--jmin=%f', ), midmat=dict(argstr='--midmat=%s', ), out_abswarp=dict(argstr='--absout', xor=['out_relwarp'], ), out_file=dict(argstr='--out=%s', name_source=['reference'], name_template='%s_concatwarp', output_name='out_file', position=-1, ), out_relwarp=dict(argstr='--relout', xor=['out_abswarp'], ), output_type=dict(), postmat=dict(argstr='--postmat=%s', ), premat=dict(argstr='--premat=%s', ), reference=dict(argstr='--ref=%s', mandatory=True, position=1, ), relwarp=dict(argstr='--rel', xor=['abswarp'], ), shift_direction=dict(argstr='--shiftdir=%s', requires=['shift_in_file'], ), shift_in_file=dict(argstr='--shiftmap=%s', ), terminal_output=dict(nohash=True, ), warp1=dict(argstr='--warp1=%s', ), warp2=dict(argstr='--warp2=%s', ), ) inputs = ConvertWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ConvertWarp_outputs(): output_map = dict(out_file=dict(), ) outputs = ConvertWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ConvertXFM.py000066400000000000000000000030451257611314500251150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ConvertXFM def test_ConvertXFM_inputs(): input_map = dict(args=dict(argstr='%s', ), concat_xfm=dict(argstr='-concat', position=-3, requires=['in_file2'], xor=['invert_xfm', 'concat_xfm', 'fix_scale_skew'], ), environ=dict(nohash=True, usedefault=True, ), fix_scale_skew=dict(argstr='-fixscaleskew', position=-3, requires=['in_file2'], xor=['invert_xfm', 'concat_xfm', 'fix_scale_skew'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-1, ), in_file2=dict(argstr='%s', position=-2, ), invert_xfm=dict(argstr='-inverse', position=-3, xor=['invert_xfm', 'concat_xfm', 'fix_scale_skew'], ), out_file=dict(argstr='-omat %s', genfile=True, hash_files=False, position=1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = ConvertXFM.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ConvertXFM_outputs(): output_map = dict(out_file=dict(), ) outputs = ConvertXFM.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_CopyGeom.py000066400000000000000000000023071257611314500246440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import CopyGeom def test_CopyGeom_inputs(): input_map = dict(args=dict(argstr='%s', ), dest_file=dict(argstr='%s', copyfile=True, mandatory=True, name_source='dest_file', name_template='%s', output_name='out_file', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_dims=dict(argstr='-d', position='-1', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = CopyGeom.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CopyGeom_outputs(): output_map = dict(out_file=dict(), ) outputs = CopyGeom.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_DTIFit.py000066400000000000000000000035301257611314500242040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import DTIFit def test_DTIFit_inputs(): input_map = dict(args=dict(argstr='%s', ), base_name=dict(argstr='-o %s', position=1, usedefault=True, ), bvals=dict(argstr='-b %s', mandatory=True, position=4, ), bvecs=dict(argstr='-r %s', mandatory=True, position=3, ), cni=dict(argstr='--cni=%s', ), dwi=dict(argstr='-k %s', mandatory=True, position=0, ), environ=dict(nohash=True, usedefault=True, ), gradnonlin=dict(argstr='--gradnonlin=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), little_bit=dict(argstr='--littlebit', ), mask=dict(argstr='-m %s', mandatory=True, position=2, ), max_x=dict(argstr='-X %d', ), max_y=dict(argstr='-Y %d', ), max_z=dict(argstr='-Z %d', ), min_x=dict(argstr='-x %d', ), min_y=dict(argstr='-y %d', ), min_z=dict(argstr='-z %d', ), output_type=dict(), save_tensor=dict(argstr='--save_tensor', ), sse=dict(argstr='--sse', ), terminal_output=dict(nohash=True, ), ) inputs = DTIFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTIFit_outputs(): output_map = dict(FA=dict(), L1=dict(), L2=dict(), L3=dict(), MD=dict(), MO=dict(), S0=dict(), V1=dict(), V2=dict(), V3=dict(), tensor=dict(), ) outputs = DTIFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_DilateImage.py000066400000000000000000000031001257611314500252570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import DilateImage def test_DilateImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), kernel_file=dict(argstr='%s', position=5, xor=['kernel_size'], ), kernel_shape=dict(argstr='-kernel %s', position=4, ), kernel_size=dict(argstr='%.4f', position=5, xor=['kernel_file'], ), nan2zeros=dict(argstr='-nan', position=3, ), operation=dict(argstr='-dil%s', mandatory=True, position=6, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = DilateImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DilateImage_outputs(): output_map = dict(out_file=dict(), ) outputs = DilateImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_DistanceMap.py000066400000000000000000000024001257611314500253040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import DistanceMap def test_DistanceMap_inputs(): input_map = dict(args=dict(argstr='%s', ), distance_map=dict(argstr='--out=%s', genfile=True, hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, ), invert_input=dict(argstr='--invert', ), local_max_file=dict(argstr='--localmax=%s', hash_files=False, ), mask_file=dict(argstr='--mask=%s', ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = DistanceMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DistanceMap_outputs(): output_map = dict(distance_map=dict(), local_max_file=dict(), ) outputs = DistanceMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_EPIDeWarp.py000066400000000000000000000033411257611314500246410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import EPIDeWarp def test_EPIDeWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), cleanup=dict(argstr='--cleanup', ), dph_file=dict(argstr='--dph %s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), epi_file=dict(argstr='--epi %s', ), epidw=dict(argstr='--epidw %s', genfile=False, ), esp=dict(argstr='--esp %s', usedefault=True, ), exf_file=dict(argstr='--exf %s', ), exfdw=dict(argstr='--exfdw %s', genfile=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mag_file=dict(argstr='--mag %s', mandatory=True, position=0, ), nocleanup=dict(argstr='--nocleanup', usedefault=True, ), output_type=dict(), sigma=dict(argstr='--sigma %s', usedefault=True, ), tediff=dict(argstr='--tediff %s', usedefault=True, ), terminal_output=dict(nohash=True, ), tmpdir=dict(argstr='--tmpdir %s', genfile=True, ), vsm=dict(argstr='--vsm %s', genfile=True, ), ) inputs = EPIDeWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EPIDeWarp_outputs(): output_map = dict(exf_mask=dict(), exfdw=dict(), unwarped_file=dict(), vsm_file=dict(), ) outputs = EPIDeWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Eddy.py000066400000000000000000000034721257611314500240130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import Eddy def test_Eddy_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), flm=dict(argstr='--flm=%s', ), fwhm=dict(argstr='--fwhm=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_acqp=dict(argstr='--acqp=%s', mandatory=True, ), in_bval=dict(argstr='--bvals=%s', mandatory=True, ), in_bvec=dict(argstr='--bvecs=%s', mandatory=True, ), in_file=dict(argstr='--imain=%s', mandatory=True, ), in_index=dict(argstr='--index=%s', mandatory=True, ), in_mask=dict(argstr='--mask=%s', mandatory=True, ), in_topup_fieldcoef=dict(argstr='--topup=%s', requires=['in_topup_movpar'], ), in_topup_movpar=dict(requires=['in_topup_fieldcoef'], ), method=dict(argstr='--resamp=%s', ), niter=dict(argstr='--niter=%s', ), num_threads=dict(nohash=True, usedefault=True, ), out_base=dict(argstr='--out=%s', usedefault=True, ), output_type=dict(), repol=dict(argstr='--repol', ), session=dict(argstr='--session=%s', ), terminal_output=dict(nohash=True, ), ) inputs = Eddy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Eddy_outputs(): output_map = dict(out_corrected=dict(), out_parameter=dict(), ) outputs = Eddy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_EddyCorrect.py000066400000000000000000000023361257611314500253330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import EddyCorrect def test_EddyCorrect_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), out_file=dict(argstr='%s', name_source=['in_file'], name_template='%s_edc', output_name='eddy_corrected', position=1, ), output_type=dict(), ref_num=dict(argstr='%d', mandatory=True, position=2, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = EddyCorrect.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EddyCorrect_outputs(): output_map = dict(eddy_corrected=dict(), ) outputs = EddyCorrect.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_EpiReg.py000066400000000000000000000036001257611314500242720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import EpiReg def test_EpiReg_inputs(): input_map = dict(args=dict(argstr='%s', ), echospacing=dict(argstr='--echospacing=%f', ), environ=dict(nohash=True, usedefault=True, ), epi=dict(argstr='--epi=%s', mandatory=True, position=-4, ), fmap=dict(argstr='--fmap=%s', ), fmapmag=dict(argstr='--fmapmag=%s', ), fmapmagbrain=dict(argstr='--fmapmagbrain=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), no_clean=dict(argstr='--noclean', ), no_fmapreg=dict(argstr='--nofmapreg', ), out_base=dict(argstr='--out=%s', position=-1, usedefault=True, ), output_type=dict(), pedir=dict(argstr='--pedir=%s', ), t1_brain=dict(argstr='--t1brain=%s', mandatory=True, position=-2, ), t1_head=dict(argstr='--t1=%s', mandatory=True, position=-3, ), terminal_output=dict(nohash=True, ), weight_image=dict(argstr='--weight=%s', ), wmseg=dict(argstr='--wmseg=%s', ), ) inputs = EpiReg.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EpiReg_outputs(): output_map = dict(epi2str_inv=dict(), epi2str_mat=dict(), fmap2epi_mat=dict(), fmap2str_mat=dict(), fmap_epi=dict(), fmap_str=dict(), fmapmag_str=dict(), fullwarp=dict(), out_1vol=dict(), out_file=dict(), shiftmap=dict(), wmedge=dict(), wmseg=dict(), ) outputs = EpiReg.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ErodeImage.py000066400000000000000000000030751257611314500251260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import ErodeImage def test_ErodeImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), kernel_file=dict(argstr='%s', position=5, xor=['kernel_size'], ), kernel_shape=dict(argstr='-kernel %s', position=4, ), kernel_size=dict(argstr='%.4f', position=5, xor=['kernel_file'], ), minimum_filter=dict(argstr='%s', position=6, usedefault=True, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = ErodeImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ErodeImage_outputs(): output_map = dict(out_file=dict(), ) outputs = ErodeImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ExtractROI.py000066400000000000000000000031551257611314500251100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ExtractROI def test_ExtractROI_inputs(): input_map = dict(args=dict(argstr='%s', ), crop_list=dict(argstr='%s', position=2, xor=['x_min', 'x_size', 'y_min', 'y_size', 'z_min', 'z_size', 't_min', 't_size'], ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), output_type=dict(), roi_file=dict(argstr='%s', genfile=True, hash_files=False, position=1, ), t_min=dict(argstr='%d', position=8, ), t_size=dict(argstr='%d', position=9, ), terminal_output=dict(nohash=True, ), x_min=dict(argstr='%d', position=2, ), x_size=dict(argstr='%d', position=3, ), y_min=dict(argstr='%d', position=4, ), y_size=dict(argstr='%d', position=5, ), z_min=dict(argstr='%d', position=6, ), z_size=dict(argstr='%d', position=7, ), ) inputs = ExtractROI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ExtractROI_outputs(): output_map = dict(roi_file=dict(), ) outputs = ExtractROI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FAST.py000066400000000000000000000041311257611314500236540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import FAST def test_FAST_inputs(): input_map = dict(args=dict(argstr='%s', ), bias_iters=dict(argstr='-I %d', ), bias_lowpass=dict(argstr='-l %d', units='mm', ), environ=dict(nohash=True, usedefault=True, ), hyper=dict(argstr='-H %.2f', ), ignore_exception=dict(nohash=True, usedefault=True, ), img_type=dict(argstr='-t %d', ), in_files=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, ), init_seg_smooth=dict(argstr='-f %.3f', ), init_transform=dict(argstr='-a %s', ), iters_afterbias=dict(argstr='-O %d', ), manual_seg=dict(argstr='-s %s', ), mixel_smooth=dict(argstr='-R %.2f', ), no_bias=dict(argstr='-N', ), no_pve=dict(argstr='--nopve', ), number_classes=dict(argstr='-n %d', ), other_priors=dict(argstr='-A %s', ), out_basename=dict(argstr='-o %s', ), output_biascorrected=dict(argstr='-B', ), output_biasfield=dict(argstr='-b', ), output_type=dict(), probability_maps=dict(argstr='-p', ), segment_iters=dict(argstr='-W %d', ), segments=dict(argstr='-g', ), terminal_output=dict(nohash=True, ), use_priors=dict(argstr='-P', ), verbose=dict(argstr='-v', ), ) inputs = FAST.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FAST_outputs(): output_map = dict(bias_field=dict(), mixeltype=dict(), partial_volume_files=dict(), partial_volume_map=dict(), probability_maps=dict(), restored_image=dict(), tissue_class_files=dict(), tissue_class_map=dict(), ) outputs = FAST.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FEAT.py000066400000000000000000000017111257611314500236370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import FEAT def test_FEAT_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fsf_file=dict(argstr='%s', mandatory=True, position=0, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = FEAT.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FEAT_outputs(): output_map = dict(feat_dir=dict(), ) outputs = FEAT.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FEATModel.py000066400000000000000000000022621257611314500246220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import FEATModel def test_FEATModel_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ev_files=dict(argstr='%s', copyfile=False, mandatory=True, position=1, ), fsf_file=dict(argstr='%s', copyfile=False, mandatory=True, position=0, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = FEATModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FEATModel_outputs(): output_map = dict(con_file=dict(), design_cov=dict(), design_file=dict(), design_image=dict(), fcon_file=dict(), ) outputs = FEATModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FEATRegister.py000066400000000000000000000016031257611314500253440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import FEATRegister def test_FEATRegister_inputs(): input_map = dict(feat_dirs=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), reg_dof=dict(usedefault=True, ), reg_image=dict(mandatory=True, ), ) inputs = FEATRegister.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FEATRegister_outputs(): output_map = dict(fsf_file=dict(), ) outputs = FEATRegister.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FIRST.py000066400000000000000000000033001257611314500240030ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import FIRST def test_FIRST_inputs(): input_map = dict(affine_file=dict(argstr='-a %s', position=6, ), args=dict(argstr='%s', ), brain_extracted=dict(argstr='-b', position=2, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', copyfile=False, mandatory=True, position=-2, ), list_of_specific_structures=dict(argstr='-s %s', position=5, sep=',', ), method=dict(argstr='-m %s', position=4, usedefault=True, xor=['method_as_numerical_threshold'], ), method_as_numerical_threshold=dict(argstr='-m %.4f', position=4, ), no_cleanup=dict(argstr='-d', position=3, ), out_file=dict(argstr='-o %s', hash_files=False, mandatory=True, position=-1, usedefault=True, ), output_type=dict(), terminal_output=dict(nohash=True, ), verbose=dict(argstr='-v', position=1, ), ) inputs = FIRST.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FIRST_outputs(): output_map = dict(bvars=dict(), original_segmentations=dict(), segmentation_file=dict(), vtk_surfaces=dict(), ) outputs = FIRST.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FLAMEO.py000066400000000000000000000042261257611314500240670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import FLAMEO def test_FLAMEO_inputs(): input_map = dict(args=dict(argstr='%s', ), burnin=dict(argstr='--burnin=%d', ), cope_file=dict(argstr='--copefile=%s', mandatory=True, ), cov_split_file=dict(argstr='--covsplitfile=%s', mandatory=True, ), design_file=dict(argstr='--designfile=%s', mandatory=True, ), dof_var_cope_file=dict(argstr='--dofvarcopefile=%s', ), environ=dict(nohash=True, usedefault=True, ), f_con_file=dict(argstr='--fcontrastsfile=%s', ), fix_mean=dict(argstr='--fixmean', ), ignore_exception=dict(nohash=True, usedefault=True, ), infer_outliers=dict(argstr='--inferoutliers', ), log_dir=dict(argstr='--ld=%s', usedefault=True, ), mask_file=dict(argstr='--maskfile=%s', mandatory=True, ), n_jumps=dict(argstr='--njumps=%d', ), no_pe_outputs=dict(argstr='--nopeoutput', ), outlier_iter=dict(argstr='--ioni=%d', ), output_type=dict(), run_mode=dict(argstr='--runmode=%s', mandatory=True, ), sample_every=dict(argstr='--sampleevery=%d', ), sigma_dofs=dict(argstr='--sigma_dofs=%d', ), t_con_file=dict(argstr='--tcontrastsfile=%s', mandatory=True, ), terminal_output=dict(nohash=True, ), var_cope_file=dict(argstr='--varcopefile=%s', ), ) inputs = FLAMEO.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FLAMEO_outputs(): output_map = dict(copes=dict(), fstats=dict(), mrefvars=dict(), pes=dict(), res4d=dict(), stats_dir=dict(), tdof=dict(), tstats=dict(), var_copes=dict(), weights=dict(), zfstats=dict(), zstats=dict(), ) outputs = FLAMEO.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FLIRT.py000066400000000000000000000076231257611314500240100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import FLIRT def test_FLIRT_inputs(): input_map = dict(angle_rep=dict(argstr='-anglerep %s', ), apply_isoxfm=dict(argstr='-applyisoxfm %f', xor=['apply_xfm'], ), apply_xfm=dict(argstr='-applyxfm', requires=['in_matrix_file'], ), args=dict(argstr='%s', ), bbrslope=dict(argstr='-bbrslope %f', min_ver='5.0.0', ), bbrtype=dict(argstr='-bbrtype %s', min_ver='5.0.0', ), bgvalue=dict(argstr='-setbackground %f', ), bins=dict(argstr='-bins %d', ), coarse_search=dict(argstr='-coarsesearch %d', units='degrees', ), cost=dict(argstr='-cost %s', ), cost_func=dict(argstr='-searchcost %s', ), datatype=dict(argstr='-datatype %s', ), display_init=dict(argstr='-displayinit', ), dof=dict(argstr='-dof %d', ), echospacing=dict(argstr='-echospacing %f', min_ver='5.0.0', ), environ=dict(nohash=True, usedefault=True, ), fieldmap=dict(argstr='-fieldmap %s', min_ver='5.0.0', ), fieldmapmask=dict(argstr='-fieldmapmask %s', min_ver='5.0.0', ), fine_search=dict(argstr='-finesearch %d', units='degrees', ), force_scaling=dict(argstr='-forcescaling', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-in %s', mandatory=True, position=0, ), in_matrix_file=dict(argstr='-init %s', ), in_weight=dict(argstr='-inweight %s', ), interp=dict(argstr='-interp %s', ), min_sampling=dict(argstr='-minsampling %f', units='mm', ), no_clamp=dict(argstr='-noclamp', ), no_resample=dict(argstr='-noresample', ), no_resample_blur=dict(argstr='-noresampblur', ), no_search=dict(argstr='-nosearch', ), out_file=dict(argstr='-out %s', hash_files=False, name_source=['in_file'], name_template='%s_flirt', position=2, ), out_log=dict(keep_extension=True, name_source=['in_file'], name_template='%s_flirt.log', requires=['save_log'], ), out_matrix_file=dict(argstr='-omat %s', hash_files=False, keep_extension=True, name_source=['in_file'], name_template='%s_flirt.mat', position=3, ), output_type=dict(), padding_size=dict(argstr='-paddingsize %d', units='voxels', ), pedir=dict(argstr='-pedir %d', min_ver='5.0.0', ), ref_weight=dict(argstr='-refweight %s', ), reference=dict(argstr='-ref %s', mandatory=True, position=1, ), rigid2D=dict(argstr='-2D', ), save_log=dict(), schedule=dict(argstr='-schedule %s', ), searchr_x=dict(argstr='-searchrx %s', units='degrees', ), searchr_y=dict(argstr='-searchry %s', units='degrees', ), searchr_z=dict(argstr='-searchrz %s', units='degrees', ), sinc_width=dict(argstr='-sincwidth %d', units='voxels', ), sinc_window=dict(argstr='-sincwindow %s', ), terminal_output=dict(nohash=True, ), uses_qform=dict(argstr='-usesqform', ), verbose=dict(argstr='-verbose %d', ), wm_seg=dict(argstr='-wmseg %s', min_ver='5.0.0', ), wmcoords=dict(argstr='-wmcoords %s', min_ver='5.0.0', ), wmnorms=dict(argstr='-wmnorms %s', min_ver='5.0.0', ), ) inputs = FLIRT.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FLIRT_outputs(): output_map = dict(out_file=dict(), out_log=dict(), out_matrix_file=dict(), ) outputs = FLIRT.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FNIRT.py000066400000000000000000000073461257611314500240140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import FNIRT def test_FNIRT_inputs(): input_map = dict(affine_file=dict(argstr='--aff=%s', ), apply_inmask=dict(argstr='--applyinmask=%s', sep=',', xor=['skip_inmask'], ), apply_intensity_mapping=dict(argstr='--estint=%s', sep=',', xor=['skip_intensity_mapping'], ), apply_refmask=dict(argstr='--applyrefmask=%s', sep=',', xor=['skip_refmask'], ), args=dict(argstr='%s', ), bias_regularization_lambda=dict(argstr='--biaslambda=%f', ), biasfield_resolution=dict(argstr='--biasres=%d,%d,%d', ), config_file=dict(argstr='--config=%s', ), derive_from_ref=dict(argstr='--refderiv', ), environ=dict(nohash=True, usedefault=True, ), field_file=dict(argstr='--fout=%s', hash_files=False, ), fieldcoeff_file=dict(argstr='--cout=%s', ), hessian_precision=dict(argstr='--numprec=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, ), in_fwhm=dict(argstr='--infwhm=%s', sep=',', ), in_intensitymap_file=dict(argstr='--intin=%s', ), inmask_file=dict(argstr='--inmask=%s', ), inmask_val=dict(argstr='--impinval=%f', ), intensity_mapping_model=dict(argstr='--intmod=%s', ), intensity_mapping_order=dict(argstr='--intorder=%d', ), inwarp_file=dict(argstr='--inwarp=%s', ), jacobian_file=dict(argstr='--jout=%s', hash_files=False, ), jacobian_range=dict(argstr='--jacrange=%f,%f', ), log_file=dict(argstr='--logout=%s', genfile=True, hash_files=False, ), max_nonlin_iter=dict(argstr='--miter=%s', sep=',', ), modulatedref_file=dict(argstr='--refout=%s', hash_files=False, ), out_intensitymap_file=dict(argstr='--intout=%s', hash_files=False, ), output_type=dict(), ref_file=dict(argstr='--ref=%s', mandatory=True, ), ref_fwhm=dict(argstr='--reffwhm=%s', sep=',', ), refmask_file=dict(argstr='--refmask=%s', ), refmask_val=dict(argstr='--imprefval=%f', ), regularization_lambda=dict(argstr='--lambda=%s', sep=',', ), regularization_model=dict(argstr='--regmod=%s', ), skip_implicit_in_masking=dict(argstr='--impinm=0', ), skip_implicit_ref_masking=dict(argstr='--imprefm=0', ), skip_inmask=dict(argstr='--applyinmask=0', xor=['apply_inmask'], ), skip_intensity_mapping=dict(argstr='--estint=0', xor=['apply_intensity_mapping'], ), skip_lambda_ssq=dict(argstr='--ssqlambda=0', ), skip_refmask=dict(argstr='--applyrefmask=0', xor=['apply_refmask'], ), spline_order=dict(argstr='--splineorder=%d', ), subsampling_scheme=dict(argstr='--subsamp=%s', sep=',', ), terminal_output=dict(nohash=True, ), warp_resolution=dict(argstr='--warpres=%d,%d,%d', ), warped_file=dict(argstr='--iout=%s', genfile=True, hash_files=False, ), ) inputs = FNIRT.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FNIRT_outputs(): output_map = dict(field_file=dict(), fieldcoeff_file=dict(), jacobian_file=dict(), log_file=dict(), modulatedref_file=dict(), out_intensitymap_file=dict(), warped_file=dict(), ) outputs = FNIRT.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FSLCommand.py000066400000000000000000000011731257611314500250450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.base import FSLCommand def test_FSLCommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = FSLCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FSLXCommand.py000066400000000000000000000050531257611314500251760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import FSLXCommand def test_FSLXCommand_inputs(): input_map = dict(all_ard=dict(argstr='--allard', xor=('no_ard', 'all_ard'), ), args=dict(argstr='%s', ), burn_in=dict(argstr='--burnin=%d', ), burn_in_no_ard=dict(argstr='--burninnoard=%d', ), bvals=dict(argstr='--bvals=%s', mandatory=True, ), bvecs=dict(argstr='--bvecs=%s', mandatory=True, ), cnlinear=dict(argstr='--cnonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), dwi=dict(argstr='--data=%s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), f0_ard=dict(argstr='--f0 --ardf0', xor=['f0_noard', 'f0_ard', 'all_ard'], ), f0_noard=dict(argstr='--f0', xor=['f0_noard', 'f0_ard'], ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fudge=dict(argstr='--fudge=%d', ), ignore_exception=dict(nohash=True, usedefault=True, ), logdir=dict(argstr='--logdir=%s', usedefault=True, ), mask=dict(argstr='--mask=%s', mandatory=True, ), model=dict(argstr='--model=%d', ), n_fibres=dict(argstr='--nfibres=%d', mandatory=True, usedefault=True, ), n_jumps=dict(argstr='--njumps=%d', ), no_ard=dict(argstr='--noard', xor=('no_ard', 'all_ard'), ), no_spat=dict(argstr='--nospat', xor=('no_spat', 'non_linear', 'cnlinear'), ), non_linear=dict(argstr='--nonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), output_type=dict(), rician=dict(argstr='--rician', ), sample_every=dict(argstr='--sampleevery=%d', ), seed=dict(argstr='--seed=%d', ), terminal_output=dict(nohash=True, ), update_proposal_every=dict(argstr='--updateproposalevery=%d', ), ) inputs = FSLXCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FSLXCommand_outputs(): output_map = dict(dyads=dict(), fsamples=dict(), mean_S0samples=dict(), mean_dsamples=dict(), mean_fsamples=dict(), mean_tausamples=dict(), phsamples=dict(), thsamples=dict(), ) outputs = FSLXCommand.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FUGUE.py000066400000000000000000000054541257611314500240030ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import FUGUE def test_FUGUE_inputs(): input_map = dict(args=dict(argstr='%s', ), asym_se_time=dict(argstr='--asym=%.10f', ), despike_2dfilter=dict(argstr='--despike', ), despike_threshold=dict(argstr='--despikethreshold=%s', ), dwell_time=dict(argstr='--dwell=%.10f', ), dwell_to_asym_ratio=dict(argstr='--dwelltoasym=%.10f', ), environ=dict(nohash=True, usedefault=True, ), fmap_in_file=dict(argstr='--loadfmap=%s', ), fmap_out_file=dict(argstr='--savefmap=%s', ), forward_warping=dict(usedefault=True, ), fourier_order=dict(argstr='--fourier=%d', ), icorr=dict(argstr='--icorr', requires=['shift_in_file'], ), icorr_only=dict(argstr='--icorronly', requires=['unwarped_file'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', ), mask_file=dict(argstr='--mask=%s', ), median_2dfilter=dict(argstr='--median', ), no_extend=dict(argstr='--noextend', ), no_gap_fill=dict(argstr='--nofill', ), nokspace=dict(argstr='--nokspace', ), output_type=dict(), pava=dict(argstr='--pava', ), phase_conjugate=dict(argstr='--phaseconj', ), phasemap_in_file=dict(argstr='--phasemap=%s', ), poly_order=dict(argstr='--poly=%d', ), save_fmap=dict(xor=['save_unmasked_fmap'], ), save_shift=dict(xor=['save_unmasked_shift'], ), save_unmasked_fmap=dict(argstr='--unmaskfmap', xor=['save_fmap'], ), save_unmasked_shift=dict(argstr='--unmaskshift', xor=['save_shift'], ), shift_in_file=dict(argstr='--loadshift=%s', ), shift_out_file=dict(argstr='--saveshift=%s', ), smooth2d=dict(argstr='--smooth2=%.2f', ), smooth3d=dict(argstr='--smooth3=%.2f', ), terminal_output=dict(nohash=True, ), unwarp_direction=dict(argstr='--unwarpdir=%s', ), unwarped_file=dict(argstr='--unwarp=%s', requires=['in_file'], xor=['warped_file'], ), warped_file=dict(argstr='--warp=%s', requires=['in_file'], xor=['unwarped_file'], ), ) inputs = FUGUE.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FUGUE_outputs(): output_map = dict(fmap_out_file=dict(), shift_out_file=dict(), unwarped_file=dict(), warped_file=dict(), ) outputs = FUGUE.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FilterRegressor.py000066400000000000000000000030201257611314500262340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import FilterRegressor def test_FilterRegressor_inputs(): input_map = dict(args=dict(argstr='%s', ), design_file=dict(argstr='-d %s', mandatory=True, position=3, ), environ=dict(nohash=True, usedefault=True, ), filter_all=dict(argstr="-f '%s'", mandatory=True, position=4, xor=['filter_columns'], ), filter_columns=dict(argstr="-f '%s'", mandatory=True, position=4, xor=['filter_all'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=1, ), mask=dict(argstr='-m %s', ), out_file=dict(argstr='-o %s', genfile=True, hash_files=False, position=2, ), out_vnscales=dict(argstr='--out_vnscales', ), output_type=dict(), terminal_output=dict(nohash=True, ), var_norm=dict(argstr='--vn', ), ) inputs = FilterRegressor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FilterRegressor_outputs(): output_map = dict(out_file=dict(), ) outputs = FilterRegressor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_FindTheBiggest.py000066400000000000000000000021501257611314500257440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import FindTheBiggest def test_FindTheBiggest_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=0, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=2, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = FindTheBiggest.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FindTheBiggest_outputs(): output_map = dict(out_file=dict(argstr='%s', ), ) outputs = FindTheBiggest.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_GLM.py000066400000000000000000000043271257611314500235450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import GLM def test_GLM_inputs(): input_map = dict(args=dict(argstr='%s', ), contrasts=dict(argstr='-c %s', ), dat_norm=dict(argstr='--dat_norm', ), demean=dict(argstr='--demean', ), des_norm=dict(argstr='--des_norm', ), design=dict(argstr='-d %s', mandatory=True, position=2, ), dof=dict(argstr='--dof=%d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=1, ), mask=dict(argstr='-m %s', ), out_cope=dict(argstr='--out_cope=%s', ), out_data_name=dict(argstr='--out_data=%s', ), out_f_name=dict(argstr='--out_f=%s', ), out_file=dict(argstr='-o %s', keep_extension=True, name_source='in_file', name_template='%s_glm', position=3, ), out_p_name=dict(argstr='--out_p=%s', ), out_pf_name=dict(argstr='--out_pf=%s', ), out_res_name=dict(argstr='--out_res=%s', ), out_sigsq_name=dict(argstr='--out_sigsq=%s', ), out_t_name=dict(argstr='--out_t=%s', ), out_varcb_name=dict(argstr='--out_varcb=%s', ), out_vnscales_name=dict(argstr='--out_vnscales=%s', ), out_z_name=dict(argstr='--out_z=%s', ), output_type=dict(), terminal_output=dict(nohash=True, ), var_norm=dict(argstr='--vn', ), ) inputs = GLM.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GLM_outputs(): output_map = dict(out_cope=dict(), out_data=dict(), out_f=dict(), out_file=dict(), out_p=dict(), out_pf=dict(), out_res=dict(), out_sigsq=dict(), out_t=dict(), out_varcb=dict(), out_vnscales=dict(), out_z=dict(), ) outputs = GLM.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ImageMaths.py000066400000000000000000000024041257611314500251370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ImageMaths def test_ImageMaths_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), in_file2=dict(argstr='%s', position=3, ), op_string=dict(argstr='%s', position=2, ), out_data_type=dict(argstr='-odt %s', position=5, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=4, ), output_type=dict(), suffix=dict(), terminal_output=dict(nohash=True, ), ) inputs = ImageMaths.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageMaths_outputs(): output_map = dict(out_file=dict(), ) outputs = ImageMaths.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ImageMeants.py000066400000000000000000000026451257611314500253210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ImageMeants def test_ImageMeants_inputs(): input_map = dict(args=dict(argstr='%s', ), eig=dict(argstr='--eig', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=0, ), mask=dict(argstr='-m %s', ), nobin=dict(argstr='--no_bin', ), order=dict(argstr='--order=%d', usedefault=True, ), out_file=dict(argstr='-o %s', genfile=True, hash_files=False, ), output_type=dict(), show_all=dict(argstr='--showall', ), spatial_coord=dict(argstr='-c %s', ), terminal_output=dict(nohash=True, ), transpose=dict(argstr='--transpose', ), use_mm=dict(argstr='--usemm', ), ) inputs = ImageMeants.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageMeants_outputs(): output_map = dict(out_file=dict(), ) outputs = ImageMeants.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ImageStats.py000066400000000000000000000022141257611314500251600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import ImageStats def test_ImageStats_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), mask_file=dict(argstr='', ), op_string=dict(argstr='%s', mandatory=True, position=3, ), output_type=dict(), split_4d=dict(argstr='-t', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = ImageStats.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageStats_outputs(): output_map = dict(out_stat=dict(), ) outputs = ImageStats.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_InvWarp.py000066400000000000000000000030061257611314500245050ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import InvWarp def test_InvWarp_inputs(): input_map = dict(absolute=dict(argstr='--abs', xor=['relative'], ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inverse_warp=dict(argstr='--out=%s', hash_files=False, name_source=['warp'], name_template='%s_inverse', ), jacobian_max=dict(argstr='--jmax=%f', ), jacobian_min=dict(argstr='--jmin=%f', ), niter=dict(argstr='--niter=%d', ), noconstraint=dict(argstr='--noconstraint', ), output_type=dict(), reference=dict(argstr='--ref=%s', mandatory=True, ), regularise=dict(argstr='--regularise=%f', ), relative=dict(argstr='--rel', xor=['absolute'], ), terminal_output=dict(nohash=True, ), warp=dict(argstr='--warp=%s', mandatory=True, ), ) inputs = InvWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_InvWarp_outputs(): output_map = dict(inverse_warp=dict(), ) outputs = InvWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_IsotropicSmooth.py000066400000000000000000000027311257611314500262700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import IsotropicSmooth def test_IsotropicSmooth_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fwhm=dict(argstr='-s %.5f', mandatory=True, position=4, xor=['sigma'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), sigma=dict(argstr='-s %.5f', mandatory=True, position=4, xor=['fwhm'], ), terminal_output=dict(nohash=True, ), ) inputs = IsotropicSmooth.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_IsotropicSmooth_outputs(): output_map = dict(out_file=dict(), ) outputs = IsotropicSmooth.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_L2Model.py000066400000000000000000000015071257611314500243610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import L2Model def test_L2Model_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), num_copes=dict(mandatory=True, ), ) inputs = L2Model.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_L2Model_outputs(): output_map = dict(design_con=dict(), design_grp=dict(), design_mat=dict(), ) outputs = L2Model.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Level1Design.py000066400000000000000000000017621257611314500254100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import Level1Design def test_Level1Design_inputs(): input_map = dict(bases=dict(mandatory=True, ), contrasts=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), interscan_interval=dict(mandatory=True, ), model_serial_correlations=dict(mandatory=True, ), session_info=dict(mandatory=True, ), ) inputs = Level1Design.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Level1Design_outputs(): output_map = dict(ev_files=dict(), fsf_files=dict(), ) outputs = Level1Design.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MCFLIRT.py000066400000000000000000000037241257611314500242260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import MCFLIRT def test_MCFLIRT_inputs(): input_map = dict(args=dict(argstr='%s', ), bins=dict(argstr='-bins %d', ), cost=dict(argstr='-cost %s', ), dof=dict(argstr='-dof %d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-in %s', mandatory=True, position=0, ), init=dict(argstr='-init %s', ), interpolation=dict(argstr='-%s_final', ), mean_vol=dict(argstr='-meanvol', ), out_file=dict(argstr='-out %s', genfile=True, hash_files=False, ), output_type=dict(), ref_file=dict(argstr='-reffile %s', ), ref_vol=dict(argstr='-refvol %d', ), rotation=dict(argstr='-rotation %d', ), save_mats=dict(argstr='-mats', ), save_plots=dict(argstr='-plots', ), save_rms=dict(argstr='-rmsabs -rmsrel', ), scaling=dict(argstr='-scaling %.2f', ), smooth=dict(argstr='-smooth %.2f', ), stages=dict(argstr='-stages %d', ), stats_imgs=dict(argstr='-stats', ), terminal_output=dict(nohash=True, ), use_contour=dict(argstr='-edge', ), use_gradient=dict(argstr='-gdt', ), ) inputs = MCFLIRT.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MCFLIRT_outputs(): output_map = dict(mat_file=dict(), mean_img=dict(), out_file=dict(), par_file=dict(), rms_files=dict(), std_img=dict(), variance_img=dict(), ) outputs = MCFLIRT.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MELODIC.py000066400000000000000000000055721257611314500242050ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import MELODIC def test_MELODIC_inputs(): input_map = dict(ICs=dict(argstr='--ICs=%s', ), approach=dict(argstr='-a %s', ), args=dict(argstr='%s', ), bg_image=dict(argstr='--bgimage=%s', ), bg_threshold=dict(argstr='--bgthreshold=%f', ), cov_weight=dict(argstr='--covarweight=%f', ), dim=dict(argstr='-d %d', ), dim_est=dict(argstr='--dimest=%s', ), environ=dict(nohash=True, usedefault=True, ), epsilon=dict(argstr='--eps=%f', ), epsilonS=dict(argstr='--epsS=%f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='-i %s', mandatory=True, position=0, sep=',', ), log_power=dict(argstr='--logPower', ), mask=dict(argstr='-m %s', ), max_restart=dict(argstr='--maxrestart=%d', ), maxit=dict(argstr='--maxit=%d', ), mix=dict(argstr='--mix=%s', ), mm_thresh=dict(argstr='--mmthresh=%f', ), no_bet=dict(argstr='--nobet', ), no_mask=dict(argstr='--nomask', ), no_mm=dict(argstr='--no_mm', ), non_linearity=dict(argstr='--nl=%s', ), num_ICs=dict(argstr='-n %d', ), out_all=dict(argstr='--Oall', ), out_dir=dict(argstr='-o %s', genfile=True, ), out_mean=dict(argstr='--Omean', ), out_orig=dict(argstr='--Oorig', ), out_pca=dict(argstr='--Opca', ), out_stats=dict(argstr='--Ostats', ), out_unmix=dict(argstr='--Ounmix', ), out_white=dict(argstr='--Owhite', ), output_type=dict(), pbsc=dict(argstr='--pbsc', ), rem_cmp=dict(argstr='-f %d', ), remove_deriv=dict(argstr='--remove_deriv', ), report=dict(argstr='--report', ), report_maps=dict(argstr='--report_maps=%s', ), s_con=dict(argstr='--Scon=%s', ), s_des=dict(argstr='--Sdes=%s', ), sep_vn=dict(argstr='--sep_vn', ), sep_whiten=dict(argstr='--sep_whiten', ), smode=dict(argstr='--smode=%s', ), t_con=dict(argstr='--Tcon=%s', ), t_des=dict(argstr='--Tdes=%s', ), terminal_output=dict(nohash=True, ), tr_sec=dict(argstr='--tr=%f', ), update_mask=dict(argstr='--update_mask', ), var_norm=dict(argstr='--vn', ), ) inputs = MELODIC.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MELODIC_outputs(): output_map = dict(out_dir=dict(), report_dir=dict(), ) outputs = MELODIC.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MakeDyadicVectors.py000066400000000000000000000024511257611314500264630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import MakeDyadicVectors def test_MakeDyadicVectors_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mask=dict(argstr='%s', position=2, ), output=dict(argstr='%s', hash_files=False, position=3, usedefault=True, ), output_type=dict(), perc=dict(argstr='%f', position=4, ), phi_vol=dict(argstr='%s', mandatory=True, position=1, ), terminal_output=dict(nohash=True, ), theta_vol=dict(argstr='%s', mandatory=True, position=0, ), ) inputs = MakeDyadicVectors.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MakeDyadicVectors_outputs(): output_map = dict(dispersion=dict(), dyads=dict(), ) outputs = MakeDyadicVectors.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MathsCommand.py000066400000000000000000000024161257611314500254760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import MathsCommand def test_MathsCommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = MathsCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MathsCommand_outputs(): output_map = dict(out_file=dict(), ) outputs = MathsCommand.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MaxImage.py000066400000000000000000000025121257611314500246100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import MaxImage def test_MaxImage_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='-%smax', position=4, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = MaxImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MaxImage_outputs(): output_map = dict(out_file=dict(), ) outputs = MaxImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MeanImage.py000066400000000000000000000025201257611314500247420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import MeanImage def test_MeanImage_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='-%smean', position=4, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = MeanImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MeanImage_outputs(): output_map = dict(out_file=dict(), ) outputs = MeanImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Merge.py000066400000000000000000000023321257611314500241570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Merge def test_Merge_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='-%s', mandatory=True, position=0, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=2, ), merged_file=dict(argstr='%s', hash_files=False, name_source='in_files', name_template='%s_merged', position=1, ), output_type=dict(), terminal_output=dict(nohash=True, ), tr=dict(argstr='%.2f', position=-1, ), ) inputs = Merge.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Merge_outputs(): output_map = dict(merged_file=dict(), ) outputs = Merge.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MotionOutliers.py000066400000000000000000000033331257611314500261160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import MotionOutliers def test_MotionOutliers_inputs(): input_map = dict(args=dict(argstr='%s', ), dummy=dict(argstr='--dummy=%d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, ), mask=dict(argstr='-m %s', ), metric=dict(argstr='--%s', ), no_motion_correction=dict(argstr='--nomoco', ), out_file=dict(argstr='-o %s', hash_files=False, keep_extension=True, name_source='in_file', name_template='%s_outliers.txt', ), out_metric_plot=dict(argstr='-p %s', hash_files=False, keep_extension=True, name_source='in_file', name_template='%s_metrics.png', ), out_metric_values=dict(argstr='-s %s', hash_files=False, keep_extension=True, name_source='in_file', name_template='%s_metrics.txt', ), output_type=dict(), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--thresh=%g', ), ) inputs = MotionOutliers.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MotionOutliers_outputs(): output_map = dict(out_file=dict(), out_metric_plot=dict(), out_metric_values=dict(), ) outputs = MotionOutliers.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MultiImageMaths.py000066400000000000000000000026261257611314500261600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import MultiImageMaths def test_MultiImageMaths_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), op_string=dict(argstr='%s', mandatory=True, position=4, ), operand_files=dict(mandatory=True, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = MultiImageMaths.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultiImageMaths_outputs(): output_map = dict(out_file=dict(), ) outputs = MultiImageMaths.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_MultipleRegressDesign.py000066400000000000000000000017421257611314500274040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import MultipleRegressDesign def test_MultipleRegressDesign_inputs(): input_map = dict(contrasts=dict(mandatory=True, ), groups=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), regressors=dict(mandatory=True, ), ) inputs = MultipleRegressDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultipleRegressDesign_outputs(): output_map = dict(design_con=dict(), design_fts=dict(), design_grp=dict(), design_mat=dict(), ) outputs = MultipleRegressDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Overlay.py000066400000000000000000000041141257611314500245410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Overlay def test_Overlay_inputs(): input_map = dict(args=dict(argstr='%s', ), auto_thresh_bg=dict(argstr='-a', mandatory=True, position=5, xor=('auto_thresh_bg', 'full_bg_range', 'bg_thresh'), ), background_image=dict(argstr='%s', mandatory=True, position=4, ), bg_thresh=dict(argstr='%.3f %.3f', mandatory=True, position=5, xor=('auto_thresh_bg', 'full_bg_range', 'bg_thresh'), ), environ=dict(nohash=True, usedefault=True, ), full_bg_range=dict(argstr='-A', mandatory=True, position=5, xor=('auto_thresh_bg', 'full_bg_range', 'bg_thresh'), ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-1, ), out_type=dict(argstr='%s', position=2, usedefault=True, ), output_type=dict(), show_negative_stats=dict(argstr='%s', position=8, xor=['stat_image2'], ), stat_image=dict(argstr='%s', mandatory=True, position=6, ), stat_image2=dict(argstr='%s', position=9, xor=['show_negative_stats'], ), stat_thresh=dict(argstr='%.2f %.2f', mandatory=True, position=7, ), stat_thresh2=dict(argstr='%.2f %.2f', position=10, ), terminal_output=dict(nohash=True, ), transparency=dict(argstr='%s', position=1, usedefault=True, ), use_checkerboard=dict(argstr='-c', position=3, ), ) inputs = Overlay.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Overlay_outputs(): output_map = dict(out_file=dict(), ) outputs = Overlay.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_PRELUDE.py000066400000000000000000000040351257611314500242220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import PRELUDE def test_PRELUDE_inputs(): input_map = dict(args=dict(argstr='%s', ), complex_phase_file=dict(argstr='--complex=%s', mandatory=True, xor=['magnitude_file', 'phase_file'], ), end=dict(argstr='--end=%d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), label_file=dict(argstr='--labels=%s', hash_files=False, ), labelprocess2d=dict(argstr='--labelslices', ), magnitude_file=dict(argstr='--abs=%s', mandatory=True, xor=['complex_phase_file'], ), mask_file=dict(argstr='--mask=%s', ), num_partitions=dict(argstr='--numphasesplit=%d', ), output_type=dict(), phase_file=dict(argstr='--phase=%s', mandatory=True, xor=['complex_phase_file'], ), process2d=dict(argstr='--slices', xor=['labelprocess2d'], ), process3d=dict(argstr='--force3D', xor=['labelprocess2d', 'process2d'], ), rawphase_file=dict(argstr='--rawphase=%s', hash_files=False, ), removeramps=dict(argstr='--removeramps', ), savemask_file=dict(argstr='--savemask=%s', hash_files=False, ), start=dict(argstr='--start=%d', ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--thresh=%.10f', ), unwrapped_phase_file=dict(argstr='--unwrap=%s', genfile=True, hash_files=False, ), ) inputs = PRELUDE.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PRELUDE_outputs(): output_map = dict(unwrapped_phase_file=dict(), ) outputs = PRELUDE.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_PlotMotionParams.py000066400000000000000000000023411257611314500263700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import PlotMotionParams def test_PlotMotionParams_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), in_source=dict(mandatory=True, ), out_file=dict(argstr='-o %s', genfile=True, hash_files=False, ), output_type=dict(), plot_size=dict(argstr='%s', ), plot_type=dict(argstr='%s', mandatory=True, ), terminal_output=dict(nohash=True, ), ) inputs = PlotMotionParams.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PlotMotionParams_outputs(): output_map = dict(out_file=dict(), ) outputs = PlotMotionParams.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_PlotTimeSeries.py000066400000000000000000000034621257611314500260350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import PlotTimeSeries def test_PlotTimeSeries_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), labels=dict(argstr='%s', ), legend_file=dict(argstr='--legend=%s', ), out_file=dict(argstr='-o %s', genfile=True, hash_files=False, ), output_type=dict(), plot_finish=dict(argstr='--finish=%d', xor=('plot_range',), ), plot_range=dict(argstr='%s', xor=('plot_start', 'plot_finish'), ), plot_size=dict(argstr='%s', ), plot_start=dict(argstr='--start=%d', xor=('plot_range',), ), sci_notation=dict(argstr='--sci', ), terminal_output=dict(nohash=True, ), title=dict(argstr='%s', ), x_precision=dict(argstr='--precision=%d', ), x_units=dict(argstr='-u %d', usedefault=True, ), y_max=dict(argstr='--ymax=%.2f', xor=('y_range',), ), y_min=dict(argstr='--ymin=%.2f', xor=('y_range',), ), y_range=dict(argstr='%s', xor=('y_min', 'y_max'), ), ) inputs = PlotTimeSeries.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PlotTimeSeries_outputs(): output_map = dict(out_file=dict(), ) outputs = PlotTimeSeries.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_PowerSpectrum.py000066400000000000000000000021231257611314500257350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import PowerSpectrum def test_PowerSpectrum_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = PowerSpectrum.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PowerSpectrum_outputs(): output_map = dict(out_file=dict(), ) outputs = PowerSpectrum.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_PrepareFieldmap.py000066400000000000000000000026061257611314500261640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import PrepareFieldmap def test_PrepareFieldmap_inputs(): input_map = dict(args=dict(argstr='%s', ), delta_TE=dict(argstr='%f', mandatory=True, position=-2, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_magnitude=dict(argstr='%s', mandatory=True, position=3, ), in_phase=dict(argstr='%s', mandatory=True, position=2, ), nocheck=dict(argstr='--nocheck', position=-1, usedefault=True, ), out_fieldmap=dict(argstr='%s', position=4, ), output_type=dict(), scanner=dict(argstr='%s', position=1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = PrepareFieldmap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PrepareFieldmap_outputs(): output_map = dict(out_fieldmap=dict(), ) outputs = PrepareFieldmap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ProbTrackX.py000066400000000000000000000054271257611314500251470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import ProbTrackX def test_ProbTrackX_inputs(): input_map = dict(args=dict(argstr='%s', ), avoid_mp=dict(argstr='--avoid=%s', ), c_thresh=dict(argstr='--cthr=%.3f', ), correct_path_distribution=dict(argstr='--pd', ), dist_thresh=dict(argstr='--distthresh=%.3f', ), environ=dict(nohash=True, usedefault=True, ), fibst=dict(argstr='--fibst=%d', ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fsamples=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inv_xfm=dict(argstr='--invxfm=%s', ), loop_check=dict(argstr='--loopcheck', ), mask=dict(argstr='-m %s', mandatory=True, ), mask2=dict(argstr='--mask2=%s', ), mesh=dict(argstr='--mesh=%s', ), mod_euler=dict(argstr='--modeuler', ), mode=dict(argstr='--mode=%s', genfile=True, ), n_samples=dict(argstr='--nsamples=%d', usedefault=True, ), n_steps=dict(argstr='--nsteps=%d', ), network=dict(argstr='--network', ), opd=dict(argstr='--opd', usedefault=True, ), os2t=dict(argstr='--os2t', ), out_dir=dict(argstr='--dir=%s', genfile=True, ), output_type=dict(), phsamples=dict(mandatory=True, ), rand_fib=dict(argstr='--randfib=%d', ), random_seed=dict(argstr='--rseed', ), s2tastext=dict(argstr='--s2tastext', ), sample_random_points=dict(argstr='--sampvox', ), samples_base_name=dict(argstr='--samples=%s', usedefault=True, ), seed=dict(argstr='--seed=%s', mandatory=True, ), seed_ref=dict(argstr='--seedref=%s', ), step_length=dict(argstr='--steplength=%.3f', ), stop_mask=dict(argstr='--stop=%s', ), target_masks=dict(argstr='--targetmasks=%s', ), terminal_output=dict(nohash=True, ), thsamples=dict(mandatory=True, ), use_anisotropy=dict(argstr='--usef', ), verbose=dict(argstr='--verbose=%d', ), waypoints=dict(argstr='--waypoints=%s', ), xfm=dict(argstr='--xfm=%s', ), ) inputs = ProbTrackX.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProbTrackX_outputs(): output_map = dict(fdt_paths=dict(), log=dict(), particle_files=dict(), targets=dict(), way_total=dict(), ) outputs = ProbTrackX.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ProbTrackX2.py000066400000000000000000000072371257611314500252320ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import ProbTrackX2 def test_ProbTrackX2_inputs(): input_map = dict(args=dict(argstr='%s', ), avoid_mp=dict(argstr='--avoid=%s', ), c_thresh=dict(argstr='--cthr=%.3f', ), colmask4=dict(argstr='--colmask4=%s', ), correct_path_distribution=dict(argstr='--pd', ), dist_thresh=dict(argstr='--distthresh=%.3f', ), distthresh1=dict(argstr='--distthresh1=%.3f', ), distthresh3=dict(argstr='--distthresh3=%.3f', ), environ=dict(nohash=True, usedefault=True, ), fibst=dict(argstr='--fibst=%d', ), fopd=dict(argstr='--fopd=%s', ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fsamples=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inv_xfm=dict(argstr='--invxfm=%s', ), loop_check=dict(argstr='--loopcheck', ), lrtarget3=dict(argstr='--lrtarget3=%s', ), mask=dict(argstr='-m %s', mandatory=True, ), meshspace=dict(argstr='--meshspace=%s', ), mod_euler=dict(argstr='--modeuler', ), n_samples=dict(argstr='--nsamples=%d', usedefault=True, ), n_steps=dict(argstr='--nsteps=%d', ), network=dict(argstr='--network', ), omatrix1=dict(argstr='--omatrix1', ), omatrix2=dict(argstr='--omatrix2', requires=['target2'], ), omatrix3=dict(argstr='--omatrix3', requires=['target3', 'lrtarget3'], ), omatrix4=dict(argstr='--omatrix4', ), onewaycondition=dict(argstr='--onewaycondition', ), opd=dict(argstr='--opd', usedefault=True, ), os2t=dict(argstr='--os2t', ), out_dir=dict(argstr='--dir=%s', genfile=True, ), output_type=dict(), phsamples=dict(mandatory=True, ), rand_fib=dict(argstr='--randfib=%d', ), random_seed=dict(argstr='--rseed', ), s2tastext=dict(argstr='--s2tastext', ), sample_random_points=dict(argstr='--sampvox', ), samples_base_name=dict(argstr='--samples=%s', usedefault=True, ), seed=dict(argstr='--seed=%s', mandatory=True, ), seed_ref=dict(argstr='--seedref=%s', ), simple=dict(argstr='--simple', usedefault=False, ), step_length=dict(argstr='--steplength=%.3f', ), stop_mask=dict(argstr='--stop=%s', ), target2=dict(argstr='--target2=%s', ), target3=dict(argstr='--target3=%s', ), target4=dict(argstr='--target4=%s', ), target_masks=dict(argstr='--targetmasks=%s', ), terminal_output=dict(nohash=True, ), thsamples=dict(mandatory=True, ), use_anisotropy=dict(argstr='--usef', ), verbose=dict(argstr='--verbose=%d', ), waycond=dict(argstr='--waycond=%s', ), wayorder=dict(argstr='--wayorder', ), waypoints=dict(argstr='--waypoints=%s', ), xfm=dict(argstr='--xfm=%s', ), ) inputs = ProbTrackX2.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProbTrackX2_outputs(): output_map = dict(fdt_paths=dict(), log=dict(), lookup_tractspace=dict(), matrix1_dot=dict(), matrix2_dot=dict(), matrix3_dot=dict(), network_matrix=dict(), particle_files=dict(), targets=dict(), way_total=dict(), ) outputs = ProbTrackX2.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_ProjThresh.py000066400000000000000000000020611257611314500252070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import ProjThresh def test_ProjThresh_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=0, ), output_type=dict(), terminal_output=dict(nohash=True, ), threshold=dict(argstr='%d', mandatory=True, position=1, ), ) inputs = ProjThresh.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProjThresh_outputs(): output_map = dict(out_files=dict(), ) outputs = ProjThresh.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Randomise.py000066400000000000000000000044231257611314500250440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import Randomise def test_Randomise_inputs(): input_map = dict(args=dict(argstr='%s', ), base_name=dict(argstr='-o "%s"', position=1, usedefault=True, ), c_thresh=dict(argstr='-c %.2f', ), cm_thresh=dict(argstr='-C %.2f', ), demean=dict(argstr='-D', ), design_mat=dict(argstr='-d %s', position=2, ), environ=dict(nohash=True, usedefault=True, ), f_c_thresh=dict(argstr='-F %.2f', ), f_cm_thresh=dict(argstr='-S %.2f', ), f_only=dict(argstr='--f_only', ), fcon=dict(argstr='-f %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=0, ), mask=dict(argstr='-m %s', ), num_perm=dict(argstr='-n %d', ), one_sample_group_mean=dict(argstr='-1', ), output_type=dict(), p_vec_n_dist_files=dict(argstr='-P', ), raw_stats_imgs=dict(argstr='-R', ), seed=dict(argstr='--seed=%d', ), show_info_parallel_mode=dict(argstr='-Q', ), show_total_perms=dict(argstr='-q', ), tcon=dict(argstr='-t %s', position=3, ), terminal_output=dict(nohash=True, ), tfce=dict(argstr='-T', ), tfce2D=dict(argstr='--T2', ), tfce_C=dict(argstr='--tfce_C=%.2f', ), tfce_E=dict(argstr='--tfce_E=%.2f', ), tfce_H=dict(argstr='--tfce_H=%.2f', ), var_smooth=dict(argstr='-v %d', ), vox_p_values=dict(argstr='-x', ), x_block_labels=dict(argstr='-e %s', ), ) inputs = Randomise.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Randomise_outputs(): output_map = dict(f_corrected_p_files=dict(), f_p_files=dict(), fstat_files=dict(), t_corrected_p_files=dict(), t_p_files=dict(), tstat_files=dict(), ) outputs = Randomise.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Reorient2Std.py000066400000000000000000000020561257611314500254470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Reorient2Std def test_Reorient2Std_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = Reorient2Std.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Reorient2Std_outputs(): output_map = dict(out_file=dict(), ) outputs = Reorient2Std.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_RobustFOV.py000066400000000000000000000021321257611314500247470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import RobustFOV def test_RobustFOV_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, position=0, ), out_roi=dict(argstr='-r %s', hash_files=False, name_source=['in_file'], name_template='%s_ROI', ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = RobustFOV.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_RobustFOV_outputs(): output_map = dict(out_roi=dict(), ) outputs = RobustFOV.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SMM.py000066400000000000000000000023271257611314500235600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import SMM def test_SMM_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mask=dict(argstr='--mask="%s"', copyfile=False, mandatory=True, position=1, ), no_deactivation_class=dict(argstr='--zfstatmode', position=2, ), output_type=dict(), spatial_data_file=dict(argstr='--sdf="%s"', copyfile=False, mandatory=True, position=0, ), terminal_output=dict(nohash=True, ), ) inputs = SMM.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SMM_outputs(): output_map = dict(activation_p_map=dict(), deactivation_p_map=dict(), null_p_map=dict(), ) outputs = SMM.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SUSAN.py000066400000000000000000000026671257611314500240240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import SUSAN def test_SUSAN_inputs(): input_map = dict(args=dict(argstr='%s', ), brightness_threshold=dict(argstr='%.10f', mandatory=True, position=2, ), dimension=dict(argstr='%d', position=4, usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), fwhm=dict(argstr='%.10f', mandatory=True, position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), usans=dict(argstr='', position=6, usedefault=True, ), use_median=dict(argstr='%d', position=5, usedefault=True, ), ) inputs = SUSAN.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SUSAN_outputs(): output_map = dict(smoothed_file=dict(), ) outputs = SUSAN.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SigLoss.py000066400000000000000000000022131257611314500245010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import SigLoss def test_SigLoss_inputs(): input_map = dict(args=dict(argstr='%s', ), echo_time=dict(argstr='--te=%f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, ), mask_file=dict(argstr='-m %s', ), out_file=dict(argstr='-s %s', genfile=True, ), output_type=dict(), slice_direction=dict(argstr='-d %s', ), terminal_output=dict(nohash=True, ), ) inputs = SigLoss.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SigLoss_outputs(): output_map = dict(out_file=dict(), ) outputs = SigLoss.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SliceTimer.py000066400000000000000000000026661257611314500251720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.preprocess import SliceTimer def test_SliceTimer_inputs(): input_map = dict(args=dict(argstr='%s', ), custom_order=dict(argstr='--ocustom=%s', ), custom_timings=dict(argstr='--tcustom=%s', ), environ=dict(nohash=True, usedefault=True, ), global_shift=dict(argstr='--tglobal', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, position=0, ), index_dir=dict(argstr='--down', ), interleaved=dict(argstr='--odd', ), out_file=dict(argstr='--out=%s', genfile=True, hash_files=False, ), output_type=dict(), slice_direction=dict(argstr='--direction=%d', ), terminal_output=dict(nohash=True, ), time_repetition=dict(argstr='--repeat=%f', ), ) inputs = SliceTimer.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SliceTimer_outputs(): output_map = dict(slice_time_corrected_file=dict(), ) outputs = SliceTimer.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Slicer.py000066400000000000000000000045401257611314500243440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Slicer def test_Slicer_inputs(): input_map = dict(all_axial=dict(argstr='-A', position=10, requires=['image_width'], xor=('single_slice', 'middle_slices', 'all_axial', 'sample_axial'), ), args=dict(argstr='%s', ), colour_map=dict(argstr='-l %s', position=4, ), dither_edges=dict(argstr='-t', position=7, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image_edges=dict(argstr='%s', position=2, ), image_width=dict(argstr='%d', position=-2, ), in_file=dict(argstr='%s', mandatory=True, position=1, ), intensity_range=dict(argstr='-i %.3f %.3f', position=5, ), label_slices=dict(argstr='-L', position=3, usedefault=True, ), middle_slices=dict(argstr='-a', position=10, xor=('single_slice', 'middle_slices', 'all_axial', 'sample_axial'), ), nearest_neighbour=dict(argstr='-n', position=8, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-1, ), output_type=dict(), sample_axial=dict(argstr='-S %d', position=10, requires=['image_width'], xor=('single_slice', 'middle_slices', 'all_axial', 'sample_axial'), ), scaling=dict(argstr='-s %f', position=0, ), show_orientation=dict(argstr='%s', position=9, usedefault=True, ), single_slice=dict(argstr='-%s', position=10, requires=['slice_number'], xor=('single_slice', 'middle_slices', 'all_axial', 'sample_axial'), ), slice_number=dict(argstr='-%d', position=11, ), terminal_output=dict(nohash=True, ), threshold_edges=dict(argstr='-e %.3f', position=6, ), ) inputs = Slicer.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Slicer_outputs(): output_map = dict(out_file=dict(), ) outputs = Slicer.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Smooth.py000066400000000000000000000022251257611314500243720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Smooth def test_Smooth_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fwhm=dict(argstr='-kernel gauss %f -fmean', mandatory=True, position=1, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), output_type=dict(), smoothed_file=dict(argstr='%s', genfile=True, hash_files=False, position=2, ), terminal_output=dict(nohash=True, ), ) inputs = Smooth.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Smooth_outputs(): output_map = dict(smoothed_file=dict(), ) outputs = Smooth.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SmoothEstimate.py000066400000000000000000000023631257611314500260710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.model import SmoothEstimate def test_SmoothEstimate_inputs(): input_map = dict(args=dict(argstr='%s', ), dof=dict(argstr='--dof=%d', mandatory=True, xor=['zstat_file'], ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mask_file=dict(argstr='--mask=%s', mandatory=True, ), output_type=dict(), residual_fit_file=dict(argstr='--res=%s', requires=['dof'], ), terminal_output=dict(nohash=True, ), zstat_file=dict(argstr='--zstat=%s', xor=['dof'], ), ) inputs = SmoothEstimate.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SmoothEstimate_outputs(): output_map = dict(dlh=dict(), resels=dict(), volume=dict(), ) outputs = SmoothEstimate.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SpatialFilter.py000066400000000000000000000031101257611314500256560ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import SpatialFilter def test_SpatialFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), kernel_file=dict(argstr='%s', position=5, xor=['kernel_size'], ), kernel_shape=dict(argstr='-kernel %s', position=4, ), kernel_size=dict(argstr='%.4f', position=5, xor=['kernel_file'], ), nan2zeros=dict(argstr='-nan', position=3, ), operation=dict(argstr='-f%s', mandatory=True, position=6, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = SpatialFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SpatialFilter_outputs(): output_map = dict(out_file=dict(), ) outputs = SpatialFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Split.py000066400000000000000000000021251257611314500242130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import Split def test_Split_inputs(): input_map = dict(args=dict(argstr='%s', ), dimension=dict(argstr='-%s', mandatory=True, position=2, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=0, ), out_base_name=dict(argstr='%s', position=1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = Split.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Split_outputs(): output_map = dict(out_files=dict(), ) outputs = Split.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_SwapDimensions.py000066400000000000000000000022121257611314500260600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import SwapDimensions def test_SwapDimensions_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position='1', ), new_dims=dict(argstr='%s %s %s', mandatory=True, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = SwapDimensions.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SwapDimensions_outputs(): output_map = dict(out_file=dict(), ) outputs = SwapDimensions.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_TOPUP.py000066400000000000000000000052171257611314500240340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.epi import TOPUP def test_TOPUP_inputs(): input_map = dict(args=dict(argstr='%s', ), config=dict(argstr='--config=%s', usedefault=True, ), encoding_direction=dict(argstr='--datain=%s', mandatory=True, requires=['readout_times'], xor=['encoding_file'], ), encoding_file=dict(argstr='--datain=%s', mandatory=True, xor=['encoding_direction'], ), environ=dict(nohash=True, usedefault=True, ), estmov=dict(argstr='--estmov=%d', ), fwhm=dict(argstr='--fwhm=%f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--imain=%s', mandatory=True, ), interp=dict(argstr='--interp=%s', ), max_iter=dict(argstr='--miter=%d', ), minmet=dict(argstr='--minmet=%d', ), numprec=dict(argstr='--numprec=%s', ), out_base=dict(argstr='--out=%s', hash_files=False, name_source=['in_file'], name_template='%s_base', ), out_corrected=dict(argstr='--iout=%s', hash_files=False, name_source=['in_file'], name_template='%s_corrected', ), out_field=dict(argstr='--fout=%s', hash_files=False, name_source=['in_file'], name_template='%s_field', ), out_logfile=dict(argstr='--logout=%s', hash_files=False, keep_extension=True, name_source=['in_file'], name_template='%s_topup.log', ), output_type=dict(), readout_times=dict(mandatory=True, requires=['encoding_direction'], xor=['encoding_file'], ), reg_lambda=dict(argstr='--miter=%0.f', ), regmod=dict(argstr='--regmod=%s', ), regrid=dict(argstr='--regrid=%d', ), scale=dict(argstr='--scale=%d', ), splineorder=dict(argstr='--splineorder=%d', ), ssqlambda=dict(argstr='--ssqlambda=%d', ), subsamp=dict(argstr='--subsamp=%d', ), terminal_output=dict(nohash=True, ), warp_res=dict(argstr='--warpres=%f', ), ) inputs = TOPUP.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TOPUP_outputs(): output_map = dict(out_corrected=dict(), out_enc_file=dict(), out_field=dict(), out_fieldcoef=dict(), out_logfile=dict(), out_movpar=dict(), ) outputs = TOPUP.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_TemporalFilter.py000066400000000000000000000027031257611314500260530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import TemporalFilter def test_TemporalFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), highpass_sigma=dict(argstr='-bptf %.6f', position=4, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), lowpass_sigma=dict(argstr='%.6f', position=5, usedefault=True, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = TemporalFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TemporalFilter_outputs(): output_map = dict(out_file=dict(), ) outputs = TemporalFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_Threshold.py000066400000000000000000000027211257611314500250560ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import Threshold def test_Threshold_inputs(): input_map = dict(args=dict(argstr='%s', ), direction=dict(usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), thresh=dict(argstr='%s', mandatory=True, position=4, ), use_nonzero_voxels=dict(requires=['use_robust_range'], ), use_robust_range=dict(), ) inputs = Threshold.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Threshold_outputs(): output_map = dict(out_file=dict(), ) outputs = Threshold.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_TractSkeleton.py000066400000000000000000000027601257611314500257070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import TractSkeleton def test_TractSkeleton_inputs(): input_map = dict(alt_data_file=dict(argstr='-a %s', ), alt_skeleton=dict(argstr='-s %s', ), args=dict(argstr='%s', ), data_file=dict(), distance_map=dict(), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, ), output_type=dict(), project_data=dict(argstr='-p %.3f %s %s %s %s', requires=['threshold', 'distance_map', 'data_file'], ), projected_data=dict(), search_mask_file=dict(xor=['use_cingulum_mask'], ), skeleton_file=dict(argstr='-o %s', ), terminal_output=dict(nohash=True, ), threshold=dict(), use_cingulum_mask=dict(usedefault=True, xor=['search_mask_file'], ), ) inputs = TractSkeleton.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TractSkeleton_outputs(): output_map = dict(projected_data=dict(), skeleton_file=dict(), ) outputs = TractSkeleton.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_UnaryMaths.py000066400000000000000000000025201257611314500252120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.maths import UnaryMaths def test_UnaryMaths_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=2, ), internal_datatype=dict(argstr='-dt %s', position=1, ), nan2zeros=dict(argstr='-nan', position=3, ), operation=dict(argstr='-%s', mandatory=True, position=4, ), out_file=dict(argstr='%s', genfile=True, hash_files=False, position=-2, ), output_datatype=dict(argstr='-odt %s', position=-1, ), output_type=dict(), terminal_output=dict(nohash=True, ), ) inputs = UnaryMaths.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_UnaryMaths_outputs(): output_map = dict(out_file=dict(), ) outputs = UnaryMaths.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_VecReg.py000066400000000000000000000026271257611314500243020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import VecReg def test_VecReg_inputs(): input_map = dict(affine_mat=dict(argstr='-t %s', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-i %s', mandatory=True, ), interpolation=dict(argstr='--interp=%s', ), mask=dict(argstr='-m %s', ), out_file=dict(argstr='-o %s', genfile=True, hash_files=False, ), output_type=dict(), ref_mask=dict(argstr='--refmask=%s', ), ref_vol=dict(argstr='-r %s', mandatory=True, ), rotation_mat=dict(argstr='--rotmat=%s', ), rotation_warp=dict(argstr='--rotwarp=%s', ), terminal_output=dict(nohash=True, ), warp_field=dict(argstr='-w %s', ), ) inputs = VecReg.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VecReg_outputs(): output_map = dict(out_file=dict(), ) outputs = VecReg.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_WarpPoints.py000066400000000000000000000027001257611314500252250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import WarpPoints def test_WarpPoints_inputs(): input_map = dict(args=dict(argstr='%s', ), coord_mm=dict(argstr='-mm', xor=['coord_vox'], ), coord_vox=dict(argstr='-vox', xor=['coord_mm'], ), dest_file=dict(argstr='-dest %s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_coords=dict(argstr='%s', mandatory=True, position=-1, ), out_file=dict(name_source='in_coords', name_template='%s_warped', output_name='out_file', ), src_file=dict(argstr='-src %s', mandatory=True, ), terminal_output=dict(nohash=True, ), warp_file=dict(argstr='-warp %s', xor=['xfm_file'], ), xfm_file=dict(argstr='-xfm %s', xor=['warp_file'], ), ) inputs = WarpPoints.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WarpPoints_outputs(): output_map = dict(out_file=dict(), ) outputs = WarpPoints.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_WarpPointsToStd.py000066400000000000000000000030101257611314500261760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import WarpPointsToStd def test_WarpPointsToStd_inputs(): input_map = dict(args=dict(argstr='%s', ), coord_mm=dict(argstr='-mm', xor=['coord_vox'], ), coord_vox=dict(argstr='-vox', xor=['coord_mm'], ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), img_file=dict(argstr='-img %s', mandatory=True, ), in_coords=dict(argstr='%s', mandatory=True, position=-1, ), out_file=dict(name_source='in_coords', name_template='%s_warped', output_name='out_file', ), premat_file=dict(argstr='-premat %s', ), std_file=dict(argstr='-std %s', mandatory=True, ), terminal_output=dict(nohash=True, ), warp_file=dict(argstr='-warp %s', xor=['xfm_file'], ), xfm_file=dict(argstr='-xfm %s', xor=['warp_file'], ), ) inputs = WarpPointsToStd.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WarpPointsToStd_outputs(): output_map = dict(out_file=dict(), ) outputs = WarpPointsToStd.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_WarpUtils.py000066400000000000000000000027761257611314500250660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.utils import WarpUtils def test_WarpUtils_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='--in=%s', mandatory=True, ), knot_space=dict(argstr='--knotspace=%d,%d,%d', ), out_file=dict(argstr='--out=%s', name_source=['in_file'], output_name='out_file', position=-1, ), out_format=dict(argstr='--outformat=%s', ), out_jacobian=dict(argstr='--jac=%s', ), output_type=dict(), reference=dict(argstr='--ref=%s', mandatory=True, ), terminal_output=dict(nohash=True, ), warp_resolution=dict(argstr='--warpres=%0.4f,%0.4f,%0.4f', ), with_affine=dict(argstr='--withaff', ), write_jacobian=dict(mandatory=True, usedefault=True, ), ) inputs = WarpUtils.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WarpUtils_outputs(): output_map = dict(out_file=dict(), out_jacobian=dict(), ) outputs = WarpUtils.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_XFibres4.py000066400000000000000000000043121257611314500245460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import XFibres4 def test_XFibres4_inputs(): input_map = dict(all_ard=dict(argstr='--allard', xor=('no_ard', 'all_ard'), ), args=dict(argstr='%s', ), burn_in=dict(argstr='--burnin=%d', ), burn_in_no_ard=dict(argstr='--burninnoard=%d', ), bvals=dict(argstr='--bvals=%s', mandatory=True, ), bvecs=dict(argstr='--bvecs=%s', mandatory=True, ), dwi=dict(argstr='--data=%s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fudge=dict(argstr='--fudge=%d', ), gradnonlin=dict(argstr='--gradnonlin=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), logdir=dict(argstr='--logdir=%s', usedefault=True, ), mask=dict(argstr='--mask=%s', mandatory=True, ), model=dict(argstr='--model=%d', ), n_fibres=dict(argstr='--nfibres=%d', ), n_jumps=dict(argstr='--njumps=%d', ), no_ard=dict(argstr='--noard', xor=('no_ard', 'all_ard'), ), no_spat=dict(argstr='--nospat', xor=('no_spat', 'non_linear'), ), non_linear=dict(argstr='--nonlinear', xor=('no_spat', 'non_linear'), ), output_type=dict(), sample_every=dict(argstr='--sampleevery=%d', ), seed=dict(argstr='--seed=%d', ), terminal_output=dict(nohash=True, ), update_proposal_every=dict(argstr='--updateproposalevery=%d', ), ) inputs = XFibres4.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_XFibres4_outputs(): output_map = dict(dyads=dict(), fsamples=dict(), mean_S0samples=dict(), mean_dsamples=dict(), mean_fsamples=dict(), phsamples=dict(), thsamples=dict(), ) outputs = XFibres4.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_auto_XFibres5.py000066400000000000000000000051211257611314500245460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.fsl.dti import XFibres5 def test_XFibres5_inputs(): input_map = dict(all_ard=dict(argstr='--allard', xor=('no_ard', 'all_ard'), ), args=dict(argstr='%s', ), burn_in=dict(argstr='--burnin=%d', ), burn_in_no_ard=dict(argstr='--burninnoard=%d', ), bvals=dict(argstr='--bvals=%s', mandatory=True, ), bvecs=dict(argstr='--bvecs=%s', mandatory=True, ), cnlinear=dict(argstr='--cnonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), dwi=dict(argstr='--data=%s', mandatory=True, ), environ=dict(nohash=True, usedefault=True, ), f0_ard=dict(argstr='--f0 --ardf0', xor=['f0_noard', 'f0_ard', 'all_ard'], ), f0_noard=dict(argstr='--f0', xor=['f0_noard', 'f0_ard'], ), force_dir=dict(argstr='--forcedir', usedefault=True, ), fudge=dict(argstr='--fudge=%d', ), gradnonlin=dict(argstr='--gradnonlin=%s', ), ignore_exception=dict(nohash=True, usedefault=True, ), logdir=dict(argstr='--logdir=%s', usedefault=True, ), mask=dict(argstr='--mask=%s', mandatory=True, ), model=dict(argstr='--model=%d', ), n_fibres=dict(argstr='--nfibres=%d', mandatory=True, usedefault=True, ), n_jumps=dict(argstr='--njumps=%d', ), no_ard=dict(argstr='--noard', xor=('no_ard', 'all_ard'), ), no_spat=dict(argstr='--nospat', xor=('no_spat', 'non_linear', 'cnlinear'), ), non_linear=dict(argstr='--nonlinear', xor=('no_spat', 'non_linear', 'cnlinear'), ), output_type=dict(), rician=dict(argstr='--rician', ), sample_every=dict(argstr='--sampleevery=%d', ), seed=dict(argstr='--seed=%d', ), terminal_output=dict(nohash=True, ), update_proposal_every=dict(argstr='--updateproposalevery=%d', ), ) inputs = XFibres5.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_XFibres5_outputs(): output_map = dict(dyads=dict(), fsamples=dict(), mean_S0samples=dict(), mean_dsamples=dict(), mean_fsamples=dict(), mean_tausamples=dict(), phsamples=dict(), thsamples=dict(), ) outputs = XFibres5.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/fsl/tests/test_base.py000066400000000000000000000060561257611314500230110ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from nipype.testing import (assert_equal, assert_true, assert_raises, assert_not_equal, skipif) import nipype.interfaces.fsl as fsl from nipype.interfaces.base import InterfaceResult from nipype.interfaces.fsl import check_fsl, no_fsl @skipif(no_fsl)#skip if fsl not installed) def test_fslversion(): ver = fsl.Info.version() if ver: # If ver is None, fsl is not installed ver = ver.split('.') yield assert_true, ver[0] in ['4', '5'] @skipif(no_fsl)#skip if fsl not installed) def test_fsloutputtype(): types = fsl.Info.ftypes.keys() orig_out_type = fsl.Info.output_type() yield assert_true, orig_out_type in types def test_outputtype_to_ext(): for ftype, ext in fsl.Info.ftypes.items(): res = fsl.Info.output_type_to_ext(ftype) yield assert_equal, res, ext yield assert_raises, KeyError, fsl.Info.output_type_to_ext, 'JUNK' @skipif(no_fsl)#skip if fsl not installed) def test_FSLCommand(): # Most methods in FSLCommand are tested in the subclasses. Only # testing the one item that is not. cmd = fsl.FSLCommand(command='ls') res = cmd.run() yield assert_equal, type(res), InterfaceResult @skipif(no_fsl)#skip if fsl not installed) def test_FSLCommand2(): # Check default output type and environ cmd = fsl.FSLCommand(command='junk') yield assert_equal, cmd._output_type, fsl.Info.output_type() yield assert_equal, cmd.inputs.environ['FSLOUTPUTTYPE'], cmd._output_type yield assert_true, cmd._output_type in fsl.Info.ftypes cmd = fsl.FSLCommand cmdinst = fsl.FSLCommand(command='junk') for out_type in fsl.Info.ftypes: cmd.set_default_output_type(out_type) yield assert_equal, cmd._output_type, out_type if out_type != fsl.Info.output_type(): # Setting class outputtype should not effect existing instances yield assert_not_equal, cmdinst.inputs.output_type, out_type @skipif(no_fsl)#skip if fsl not installed) def test_gen_fname(): # Test _gen_fname method of FSLCommand cmd = fsl.FSLCommand(command = 'junk',output_type = 'NIFTI_GZ') pth = os.getcwd() # just the filename fname = cmd._gen_fname('foo.nii.gz',suffix='_fsl') desired = os.path.join(pth, 'foo_fsl.nii.gz') yield assert_equal, fname, desired # filename with suffix fname = cmd._gen_fname('foo.nii.gz', suffix = '_brain') desired = os.path.join(pth, 'foo_brain.nii.gz') yield assert_equal, fname, desired # filename with suffix and working directory fname = cmd._gen_fname('foo.nii.gz', suffix = '_brain', cwd = '/data') desired = os.path.join('/data', 'foo_brain.nii.gz') yield assert_equal, fname, desired # filename with suffix and no file extension change fname = cmd._gen_fname('foo.nii.gz', suffix = '_brain.mat', change_ext = False) desired = os.path.join(pth, 'foo_brain.mat') yield assert_equal, fname, desired nipype-0.11.0/nipype/interfaces/fsl/tests/test_dti.py000066400000000000000000000461321257611314500226560ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import tempfile import shutil from tempfile import mkdtemp from shutil import rmtree import numpy as np import nibabel as nb from nipype.testing import (assert_equal, assert_not_equal, assert_raises, skipif, example_data) import nipype.interfaces.fsl.dti as fsl from nipype.interfaces.fsl import Info, no_fsl from nipype.interfaces.base import Undefined # nosetests --with-doctest path_to/test_fsl.py def skip_dti_tests(): """XXX These tests are skipped until we clean up some of this code """ return True def create_files_in_directory(): outdir = os.path.realpath(mkdtemp()) cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii', 'b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3, 3, 3, 4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img, np.eye(4), hdr), os.path.join(outdir, f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) # test bedpostx @skipif(no_fsl) def test_oldbedpostx2(): filelist, outdir, cwd = create_files_in_directory() bpx = fsl.BEDPOSTX() # make sure command gets called yield assert_equal, bpx.cmd, 'bedpostx' # test raising error with mandatory args absent yield assert_raises, ValueError, bpx.run # .inputs based parameters setting bpx2 = fsl.BEDPOSTX4() bpx2.inputs.mask = example_data('mask.nii') bpx2.inputs.dwi = example_data('diffusion.nii') bpx2.inputs.bvals = example_data('bvals') bpx2.inputs.bvecs = example_data('bvecs') bpx2.inputs.fibres = 2 bpx2.inputs.weight = 0.3 bpx2.inputs.burn_period = 200 bpx2.inputs.jumps = 500 bpx2.inputs.sampling = 20 actualCmdline = sorted(bpx2.cmdline.split()) cmd = 'bedpostx bedpostx -b 200 -n 2 -j 500 -s 20 -w 0.30 --forcedir --logdir=logdir' desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline # test dtifit @skipif(no_fsl) def test_dtifit2(): filelist, outdir, cwd = create_files_in_directory() dti = fsl.DTIFit() # make sure command gets called yield assert_equal, dti.cmd, 'dtifit' # test raising error with mandatory args absent yield assert_raises, ValueError, dti.run # .inputs based parameters setting dti.inputs.dwi = filelist[0] dti.inputs.base_name = 'foo.dti.nii' dti.inputs.mask = filelist[1] dti.inputs.bvecs = filelist[0] dti.inputs.bvals = filelist[1] dti.inputs.min_z = 10 dti.inputs.max_z = 50 yield assert_equal, dti.cmdline, \ 'dtifit -k %s -o foo.dti.nii -m %s -r %s -b %s -Z 50 -z 10'%(filelist[0], filelist[1], filelist[0], filelist[1]) clean_directory(outdir, cwd) # Globals to store paths for tbss tests tbss_dir = None test_dir = None def setup_tbss(): # Setup function is called before each test. Setup is called only # once for each generator function. global tbss_dir, tbss_files, test_dir test_dir = os.getcwd() tbss_dir = tempfile.mkdtemp() os.chdir(tbss_dir) tbss_files = ['a.nii', 'b.nii'] for f in tbss_files: fp = open(f, 'wt') fp.write('dummy') fp.close() def teardown_tbss(): # Teardown is called after each test to perform cleanup os.chdir(test_dir) shutil.rmtree(tbss_dir) @skipif(skip_dti_tests) def test_randomise2(): rand = fsl.Randomise() # make sure command gets called yield assert_equal, rand.cmd, 'randomise' # test raising error with mandatory args absent yield assert_raises, ValueError, rand.run # .inputs based parameters setting rand.inputs.input_4D = 'infile.nii' rand.inputs.output_rootname = 'outfile' rand.inputs.design_matrix = 'design.mat' rand.inputs.t_contrast = 'infile.con' actualCmdline = sorted(rand.cmdline.split()) cmd = 'randomise -i infile.nii -o outfile -d design.mat -t infile.con' desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline # .run based parameter setting rand2 = fsl.Randomise(input_4D='infile2', output_rootname='outfile2', f_contrast='infile.f', one_sample_gmean=True, int_seed=4) actualCmdline = sorted(rand2.cmdline.split()) cmd = 'randomise -i infile2 -o outfile2 -1 -f infile.f --seed=4' desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline rand3 = fsl.Randomise() results = rand3.run(input_4D='infile3', output_rootname='outfile3') yield assert_equal, results.runtime.cmdline, \ 'randomise -i infile3 -o outfile3' # test arguments for opt_map opt_map = {'demean_data': ('-D', True), 'one_sample_gmean': ('-1', True), 'mask_image': ('-m inp_mask', 'inp_mask'), 'design_matrix': ('-d design.mat', 'design.mat'), 't_contrast': ('-t input.con', 'input.con'), 'f_contrast': ('-f input.fts', 'input.fts'), 'xchange_block_labels': ('-e design.grp', 'design.grp'), 'print_unique_perm': ('-q', True), 'print_info_parallelMode': ('-Q', True), 'num_permutations': ('-n 10', 10), 'vox_pvalus': ('-x', True), 'fstats_only': ('--fonly', True), 'thresh_free_cluster': ('-T', True), 'thresh_free_cluster_2Dopt': ('--T2', True), 'cluster_thresholding': ('-c 0.20', 0.20), 'cluster_mass_thresholding': ('-C 0.40', 0.40), 'fcluster_thresholding': ('-F 0.10', 0.10), 'fcluster_mass_thresholding': ('-S 0.30', 0.30), 'variance_smoothing': ('-v 0.20', 0.20), 'diagnostics_off': ('--quiet', True), 'output_raw': ('-R', True), 'output_perm_vect': ('-P', True), 'int_seed': ('--seed=20', 20), 'TFCE_height_param': ('--tfce_H=0.11', 0.11), 'TFCE_extent_param': ('--tfce_E=0.50', 0.50), 'TFCE_connectivity': ('--tfce_C=0.30', 0.30), 'list_num_voxel_EVs_pos': ('--vxl=1,2,3,4', '1,2,3,4'), 'list_img_voxel_EVs': ('--vxf=6,7,8,9,3', '6,7,8,9,3')} for name, settings in opt_map.items(): rand4 = fsl.Randomise(input_4D='infile', output_rootname='root', **{name: settings[1]}) yield assert_equal, rand4.cmdline, rand4.cmd + ' -i infile -o root ' \ + settings[0] @skipif(skip_dti_tests) def test_Randomise_parallel(): rand = fsl.Randomise_parallel() # make sure command gets called yield assert_equal, rand.cmd, 'randomise_parallel' # test raising error with mandatory args absent yield assert_raises, ValueError, rand.run # .inputs based parameters setting rand.inputs.input_4D = 'infile.nii' rand.inputs.output_rootname = 'outfile' rand.inputs.design_matrix = 'design.mat' rand.inputs.t_contrast = 'infile.con' actualCmdline = sorted(rand.cmdline.split()) cmd = ('randomise_parallel -i infile.nii -o outfile -d design.mat -t ' 'infile.con') desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline # .run based parameter setting rand2 = fsl.Randomise_parallel(input_4D='infile2', output_rootname='outfile2', f_contrast='infile.f', one_sample_gmean=True, int_seed=4) actualCmdline = sorted(rand2.cmdline.split()) cmd = 'randomise_parallel -i infile2 -o outfile2 -1 -f infile.f --seed=4' desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline rand3 = fsl.Randomise_parallel() results = rand3.run(input_4D='infile3', output_rootname='outfile3') yield assert_equal, results.runtime.cmdline, \ 'randomise_parallel -i infile3 -o outfile3' # test arguments for opt_map opt_map = {'demean_data': ('-D', True), 'one_sample_gmean': ('-1', True), 'mask_image': ('-m inp_mask', 'inp_mask'), 'design_matrix': ('-d design.mat', 'design.mat'), 't_contrast': ('-t input.con', 'input.con'), 'f_contrast': ('-f input.fts', 'input.fts'), 'xchange_block_labels': ('-e design.grp', 'design.grp'), 'print_unique_perm': ('-q', True), 'print_info_parallelMode': ('-Q', True), 'num_permutations': ('-n 10', 10), 'vox_pvalus': ('-x', True), 'fstats_only': ('--fonly', True), 'thresh_free_cluster': ('-T', True), 'thresh_free_cluster_2Dopt': ('--T2', True), 'cluster_thresholding': ('-c 0.20', 0.20), 'cluster_mass_thresholding': ('-C 0.40', 0.40), 'fcluster_thresholding': ('-F 0.10', 0.10), 'fcluster_mass_thresholding': ('-S 0.30', 0.30), 'variance_smoothing': ('-v 0.20', 0.20), 'diagnostics_off': ('--quiet', True), 'output_raw': ('-R', True), 'output_perm_vect': ('-P', True), 'int_seed': ('--seed=20', 20), 'TFCE_height_param': ('--tfce_H=0.11', 0.11), 'TFCE_extent_param': ('--tfce_E=0.50', 0.50), 'TFCE_connectivity': ('--tfce_C=0.30', 0.30), 'list_num_voxel_EVs_pos': ('--vxl=' \ + repr([1, 2, 3, 4]), repr([1, 2, 3, 4])), 'list_img_voxel_EVs': ('--vxf=' \ + repr([6, 7, 8, 9, 3]), repr([6, 7, 8, 9, 3]))} for name, settings in opt_map.items(): rand4 = fsl.Randomise_parallel(input_4D='infile', output_rootname='root', **{name: settings[1]}) yield assert_equal, rand4.cmdline, rand4.cmd + ' -i infile -o root ' \ + settings[0] # test proj_thresh @skipif(skip_dti_tests) def test_Proj_thresh(): proj = fsl.ProjThresh() # make sure command gets called yield assert_equal, proj.cmd, 'proj_thresh' # test raising error with mandatory args absent yield assert_raises, ValueError, proj.run # .inputs based parameters setting proj.inputs.volumes = ['vol1', 'vol2', 'vol3'] proj.inputs.threshold = 3 yield assert_equal, proj.cmdline, 'proj_thresh vol1 vol2 vol3 3' proj2 = fsl.ProjThresh(threshold=10, volumes=['vola', 'volb']) yield assert_equal, proj2.cmdline, 'proj_thresh vola volb 10' # .run based parameters setting proj3 = fsl.ProjThresh() results = proj3.run(volumes=['inp1', 'inp3', 'inp2'], threshold=2) yield assert_equal, results.runtime.cmdline, 'proj_thresh inp1 inp3 inp2 2' yield assert_not_equal, results.runtime.returncode, 0 yield assert_equal, isinstance(results.interface.inputs.volumes, list), \ True yield assert_equal, results.interface.inputs.threshold, 2 # test arguments for opt_map # Proj_thresh doesn't have an opt_map{} # test vec_reg @skipif(skip_dti_tests) def test_Vec_reg(): vrg = fsl.VecReg() # make sure command gets called yield assert_equal, vrg.cmd, 'vecreg' # test raising error with mandatory args absent yield assert_raises, ValueError, vrg.run # .inputs based parameters setting vrg.inputs.infile = 'infile' vrg.inputs.outfile = 'outfile' vrg.inputs.refVolName = 'MNI152' vrg.inputs.affineTmat = 'tmat.mat' yield assert_equal, vrg.cmdline, \ 'vecreg -i infile -o outfile -r MNI152 -t tmat.mat' # .run based parameter setting vrg2 = fsl.VecReg(infile='infile2', outfile='outfile2', refVolName='MNI152', affineTmat='tmat2.mat', brainMask='nodif_brain_mask') actualCmdline = sorted(vrg2.cmdline.split()) cmd = 'vecreg -i infile2 -o outfile2 -r MNI152 -t tmat2.mat -m nodif_brain_mask' desiredCmdline = sorted(cmd.split()) yield assert_equal, actualCmdline, desiredCmdline vrg3 = fsl.VecReg() results = vrg3.run(infile='infile3', outfile='outfile3', refVolName='MNI152', affineTmat='tmat3.mat',) yield assert_equal, results.runtime.cmdline, \ 'vecreg -i infile3 -o outfile3 -r MNI152 -t tmat3.mat' yield assert_not_equal, results.runtime.returncode, 0 yield assert_equal, results.interface.inputs.infile, 'infile3' yield assert_equal, results.interface.inputs.outfile, 'outfile3' yield assert_equal, results.interface.inputs.refVolName, 'MNI152' yield assert_equal, results.interface.inputs.affineTmat, 'tmat3.mat' # test arguments for opt_map opt_map = { 'verbose': ('-v', True), 'helpDoc': ('-h', True), 'tensor': ('--tensor', True), 'affineTmat': ('-t Tmat', 'Tmat'), 'warpFile': ('-w wrpFile', 'wrpFile'), 'interpolation': ('--interp=sinc', 'sinc'), 'brainMask': ('-m mask', 'mask')} for name, settings in opt_map.items(): vrg4 = fsl.VecReg(infile='infile', outfile='outfile', refVolName='MNI152', **{name: settings[1]}) yield assert_equal, vrg4.cmdline, vrg4.cmd + \ ' -i infile -o outfile -r MNI152 ' + settings[0] # test find_the_biggest @skipif(skip_dti_tests) def test_Find_the_biggest(): fbg = fsl.FindTheBiggest() # make sure command gets called yield assert_equal, fbg.cmd, 'find_the_biggest' # test raising error with mandatory args absent yield assert_raises, ValueError, fbg.run # .inputs based parameters setting fbg.inputs.infiles = 'seed*' fbg.inputs.outfile = 'fbgfile' yield assert_equal, fbg.cmdline, 'find_the_biggest seed* fbgfile' fbg2 = fsl.FindTheBiggest(infiles='seed2*', outfile='fbgfile2') yield assert_equal, fbg2.cmdline, 'find_the_biggest seed2* fbgfile2' # .run based parameters setting fbg3 = fsl.FindTheBiggest() results = fbg3.run(infiles='seed3', outfile='out3') yield assert_equal, results.runtime.cmdline, 'find_the_biggest seed3 out3' # test arguments for opt_map # Find_the_biggest doesn't have an opt_map{} @skipif(no_fsl) def test_tbss_skeleton(): skeletor = fsl.TractSkeleton() files, newdir, olddir = create_files_in_directory() # Test the underlying command yield assert_equal, skeletor.cmd, "tbss_skeleton" # It shouldn't run yet yield assert_raises, ValueError, skeletor.run # Test the most basic way to use it skeletor.inputs.in_file = files[0] # First by implicit argument skeletor.inputs.skeleton_file = True yield assert_equal, skeletor.cmdline, \ "tbss_skeleton -i a.nii -o %s"%os.path.join(newdir, "a_skeleton.nii") # Now with a specific name skeletor.inputs.skeleton_file = "old_boney.nii" yield assert_equal, skeletor.cmdline, "tbss_skeleton -i a.nii -o old_boney.nii" # Now test the more complicated usage bones = fsl.TractSkeleton(in_file="a.nii", project_data=True) # This should error yield assert_raises, ValueError, bones.run # But we can set what we need bones.inputs.threshold = 0.2 bones.inputs.distance_map = "b.nii" bones.inputs.data_file = "b.nii" # Even though that's silly # Now we get a command line yield assert_equal, bones.cmdline, \ "tbss_skeleton -i a.nii -p 0.200 b.nii %s b.nii %s"%(Info.standard_image("LowerCingulum_1mm.nii.gz"), os.path.join(newdir, "b_skeletonised.nii")) # Can we specify a mask? bones.inputs.use_cingulum_mask = Undefined bones.inputs.search_mask_file = "a.nii" yield assert_equal, bones.cmdline, \ "tbss_skeleton -i a.nii -p 0.200 b.nii a.nii b.nii %s"%os.path.join(newdir, "b_skeletonised.nii") # Looks good; clean up clean_directory(newdir, olddir) @skipif(no_fsl) def test_distancemap(): mapper = fsl.DistanceMap() files, newdir, olddir = create_files_in_directory() # Test the underlying command yield assert_equal, mapper.cmd, "distancemap" # It shouldn't run yet yield assert_raises, ValueError, mapper.run # But if we do this... mapper.inputs.in_file = "a.nii" # It should yield assert_equal, mapper.cmdline, "distancemap --out=%s --in=a.nii"%os.path.join(newdir, "a_dstmap.nii") # And we should be able to write out a maxima map mapper.inputs.local_max_file = True yield assert_equal, mapper.cmdline, \ "distancemap --out=%s --in=a.nii --localmax=%s"%(os.path.join(newdir, "a_dstmap.nii"), os.path.join(newdir, "a_lclmax.nii")) # And call it whatever we want mapper.inputs.local_max_file = "max.nii" yield assert_equal, mapper.cmdline, \ "distancemap --out=%s --in=a.nii --localmax=max.nii"%os.path.join(newdir, "a_dstmap.nii") # Not much else to do here clean_directory(newdir, olddir) nipype-0.11.0/nipype/interfaces/fsl/tests/test_epi.py000066400000000000000000000034711257611314500226520ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np import nibabel as nb from nipype.testing import ( assert_equal, assert_not_equal, assert_raises, skipif) import nipype.interfaces.fsl.epi as fsl from nipype.interfaces.fsl import no_fsl def create_files_in_directory(): outdir = os.path.realpath(mkdtemp()) cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii','b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) # test eddy_correct @skipif(no_fsl) def test_eddy_correct2(): filelist, outdir, cwd = create_files_in_directory() eddy = fsl.EddyCorrect() # make sure command gets called yield assert_equal, eddy.cmd, 'eddy_correct' # test raising error with mandatory args absent yield assert_raises, ValueError, eddy.run # .inputs based parameters setting eddy.inputs.in_file = filelist[0] eddy.inputs.out_file = 'foo_eddc.nii' eddy.inputs.ref_num = 100 yield assert_equal, eddy.cmdline, 'eddy_correct %s foo_eddc.nii 100'%filelist[0] # .run based parameter setting eddy2 = fsl.EddyCorrect(in_file=filelist[0], out_file='foo_ec.nii', ref_num=20) yield assert_equal, eddy2.cmdline, 'eddy_correct %s foo_ec.nii 20'%filelist[0] # test arguments for opt_map # eddy_correct class doesn't have opt_map{} clean_directory(outdir, cwd) nipype-0.11.0/nipype/interfaces/fsl/tests/test_maths.py000066400000000000000000000371751257611314500232210ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np import nibabel as nb from nipype.testing import (assert_equal, assert_raises, skipif) from nipype.interfaces.base import Undefined import nipype.interfaces.fsl.maths as fsl from nipype.interfaces.fsl import no_fsl def create_files_in_directory(): testdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(testdir) ftype = os.environ["FSLOUTPUTTYPE"] os.environ["FSLOUTPUTTYPE"] = "NIFTI" filelist = ['a.nii','b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img,np.eye(4),hdr), os.path.join(testdir,f)) return filelist, testdir, origdir, ftype def clean_directory(testdir, origdir, ftype): if os.path.exists(testdir): rmtree(testdir) os.chdir(origdir) os.environ["FSLOUTPUTTYPE"] = ftype @skipif(no_fsl) def test_maths_base(): files, testdir, origdir, ftype = create_files_in_directory() # Get some fslmaths maths = fsl.MathsCommand() # Test that we got what we wanted yield assert_equal, maths.cmd, "fslmaths" # Test that it needs a mandatory argument yield assert_raises, ValueError, maths.run # Set an in file maths.inputs.in_file = "a.nii" # Now test the most basic command line yield assert_equal, maths.cmdline, "fslmaths a.nii %s"%os.path.join(testdir, "a_maths.nii") # Now test that we can set the various data types dtypes = ["float","char","int","short","double","input"] int_cmdline = "fslmaths -dt %s a.nii " + os.path.join(testdir, "a_maths.nii") out_cmdline = "fslmaths a.nii " + os.path.join(testdir, "a_maths.nii") + " -odt %s" duo_cmdline = "fslmaths -dt %s a.nii " + os.path.join(testdir, "a_maths.nii") + " -odt %s" for dtype in dtypes: foo = fsl.MathsCommand(in_file="a.nii",internal_datatype=dtype) yield assert_equal, foo.cmdline, int_cmdline%dtype bar = fsl.MathsCommand(in_file="a.nii",output_datatype=dtype) yield assert_equal, bar.cmdline, out_cmdline%dtype foobar = fsl.MathsCommand(in_file="a.nii",internal_datatype=dtype,output_datatype=dtype) yield assert_equal, foobar.cmdline, duo_cmdline%(dtype, dtype) # Test that we can ask for an outfile name maths.inputs.out_file = "b.nii" yield assert_equal, maths.cmdline, "fslmaths a.nii b.nii" # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_changedt(): files, testdir, origdir, ftype = create_files_in_directory() # Get some fslmaths cdt = fsl.ChangeDataType() # Test that we got what we wanted yield assert_equal, cdt.cmd, "fslmaths" # Test that it needs a mandatory argument yield assert_raises, ValueError, cdt.run # Set an in file and out file cdt.inputs.in_file = "a.nii" cdt.inputs.out_file = "b.nii" # But it still shouldn't work yield assert_raises, ValueError, cdt.run # Now test that we can set the various data types dtypes = ["float","char","int","short","double","input"] cmdline = "fslmaths a.nii b.nii -odt %s" for dtype in dtypes: foo = fsl.MathsCommand(in_file="a.nii",out_file="b.nii",output_datatype=dtype) yield assert_equal, foo.cmdline, cmdline%dtype # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_threshold(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command thresh = fsl.Threshold(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, thresh.cmd, "fslmaths" # Test mandtory args yield assert_raises, ValueError, thresh.run # Test the various opstrings cmdline = "fslmaths a.nii %s b.nii" for val in [0, 0., -1, -1.5, -0.5, 0.5, 3, 400, 400.5]: thresh.inputs.thresh = val yield assert_equal, thresh.cmdline, cmdline%"-thr %.10f"%val val = "%.10f"%42 thresh = fsl.Threshold(in_file="a.nii",out_file="b.nii",thresh=42,use_robust_range=True) yield assert_equal, thresh.cmdline, cmdline%("-thrp "+val) thresh.inputs.use_nonzero_voxels = True yield assert_equal, thresh.cmdline, cmdline%("-thrP "+val) thresh = fsl.Threshold(in_file="a.nii",out_file="b.nii",thresh=42,direction="above") yield assert_equal, thresh.cmdline, cmdline%("-uthr "+val) thresh.inputs.use_robust_range=True yield assert_equal, thresh.cmdline, cmdline%("-uthrp "+val) thresh.inputs.use_nonzero_voxels = True yield assert_equal, thresh.cmdline, cmdline%("-uthrP "+val) # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_meanimage(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command meaner = fsl.MeanImage(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, meaner.cmd, "fslmaths" # Test the defualt opstring yield assert_equal, meaner.cmdline, "fslmaths a.nii -Tmean b.nii" # Test the other dimensions cmdline = "fslmaths a.nii -%smean b.nii" for dim in ["X","Y","Z","T"]: meaner.inputs.dimension=dim yield assert_equal, meaner.cmdline, cmdline%dim # Test the auto naming meaner = fsl.MeanImage(in_file="a.nii") yield assert_equal, meaner.cmdline, "fslmaths a.nii -Tmean %s"%os.path.join(testdir, "a_mean.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_maximage(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command maxer = fsl.MaxImage(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, maxer.cmd, "fslmaths" # Test the defualt opstring yield assert_equal, maxer.cmdline, "fslmaths a.nii -Tmax b.nii" # Test the other dimensions cmdline = "fslmaths a.nii -%smax b.nii" for dim in ["X","Y","Z","T"]: maxer.inputs.dimension=dim yield assert_equal, maxer.cmdline, cmdline%dim # Test the auto naming maxer = fsl.MaxImage(in_file="a.nii") yield assert_equal, maxer.cmdline, "fslmaths a.nii -Tmax %s"%os.path.join(testdir, "a_max.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_smooth(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command smoother = fsl.IsotropicSmooth(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, smoother.cmd, "fslmaths" # Test that smoothing kernel is mandatory yield assert_raises, ValueError, smoother.run # Test smoothing kernels cmdline = "fslmaths a.nii -s %.5f b.nii" for val in [0,1.,1,25,0.5,8/3]: smoother = fsl.IsotropicSmooth(in_file="a.nii",out_file="b.nii",sigma=val) yield assert_equal, smoother.cmdline, cmdline%val smoother = fsl.IsotropicSmooth(in_file="a.nii",out_file="b.nii",fwhm=val) val = float(val)/np.sqrt(8 * np.log(2)) yield assert_equal, smoother.cmdline, cmdline%val # Test automatic naming smoother = fsl.IsotropicSmooth(in_file="a.nii", sigma=5) yield assert_equal, smoother.cmdline, "fslmaths a.nii -s %.5f %s"%(5, os.path.join(testdir, "a_smooth.nii")) # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_mask(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command masker = fsl.ApplyMask(in_file="a.nii",out_file="c.nii") # Test the underlying command yield assert_equal, masker.cmd, "fslmaths" # Test that the mask image is mandatory yield assert_raises, ValueError, masker.run # Test setting the mask image masker.inputs.mask_file = "b.nii" yield assert_equal, masker.cmdline, "fslmaths a.nii -mas b.nii c.nii" # Test auto name generation masker = fsl.ApplyMask(in_file="a.nii",mask_file="b.nii") yield assert_equal, masker.cmdline, "fslmaths a.nii -mas b.nii "+os.path.join(testdir, "a_masked.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_dilation(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command diller = fsl.DilateImage(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, diller.cmd, "fslmaths" # Test that the dilation operation is mandatory yield assert_raises, ValueError, diller.run # Test the different dilation operations for op in ["mean", "modal", "max"]: cv = dict(mean="M", modal="D", max="F") diller.inputs.operation = op yield assert_equal, diller.cmdline, "fslmaths a.nii -dil%s b.nii"%cv[op] # Now test the different kernel options for k in ["3D", "2D", "box", "boxv", "gauss", "sphere"]: for size in [1, 1.5, 5]: diller.inputs.kernel_shape = k diller.inputs.kernel_size = size yield assert_equal, diller.cmdline, "fslmaths a.nii -kernel %s %.4f -dilF b.nii"%(k, size) # Test that we can use a file kernel f = open("kernel.txt","w").close() del f # Shut pyflakes up diller.inputs.kernel_shape = "file" diller.inputs.kernel_size = Undefined diller.inputs.kernel_file = "kernel.txt" yield assert_equal, diller.cmdline, "fslmaths a.nii -kernel file kernel.txt -dilF b.nii" # Test that we don't need to request an out name dil = fsl.DilateImage(in_file="a.nii", operation="max") yield assert_equal, dil.cmdline, "fslmaths a.nii -dilF %s"%os.path.join(testdir, "a_dil.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_erosion(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command erode = fsl.ErodeImage(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, erode.cmd, "fslmaths" # Test the basic command line yield assert_equal, erode.cmdline, "fslmaths a.nii -ero b.nii" # Test that something else happens when you minimum filter erode.inputs.minimum_filter = True yield assert_equal, erode.cmdline, "fslmaths a.nii -eroF b.nii" # Test that we don't need to request an out name erode = fsl.ErodeImage(in_file="a.nii") yield assert_equal, erode.cmdline, "fslmaths a.nii -ero %s"%os.path.join(testdir, "a_ero.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_spatial_filter(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command filter = fsl.SpatialFilter(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, filter.cmd, "fslmaths" # Test that it fails without an operation yield assert_raises, ValueError, filter.run # Test the different operations for op in ["mean", "meanu", "median"]: filter.inputs.operation = op yield assert_equal, filter.cmdline, "fslmaths a.nii -f%s b.nii"%op # Test that we don't need to ask for an out name filter = fsl.SpatialFilter(in_file="a.nii", operation="mean") yield assert_equal, filter.cmdline, "fslmaths a.nii -fmean %s"%os.path.join(testdir, "a_filt.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_unarymaths(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command maths = fsl.UnaryMaths(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, maths.cmd, "fslmaths" # Test that it fails without an operation yield assert_raises, ValueError, maths.run # Test the different operations ops = ["exp", "log", "sin", "cos", "sqr", "sqrt", "recip", "abs", "bin", "index"] for op in ops: maths.inputs.operation = op yield assert_equal, maths.cmdline, "fslmaths a.nii -%s b.nii"%op # Test that we don't need to ask for an out file for op in ops: maths = fsl.UnaryMaths(in_file="a.nii", operation=op) yield assert_equal, maths.cmdline, "fslmaths a.nii -%s %s"%(op, os.path.join(testdir, "a_%s.nii"%op)) # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_binarymaths(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command maths = fsl.BinaryMaths(in_file="a.nii",out_file="c.nii") # Test the underlying command yield assert_equal, maths.cmd, "fslmaths" # Test that it fails without an operation an yield assert_raises, ValueError, maths.run # Test the different operations ops = ["add", "sub", "mul", "div", "rem", "min", "max"] operands = ["b.nii", -2, -0.5, 0, .123456, np.pi, 500] for op in ops: for ent in operands: maths = fsl.BinaryMaths(in_file="a.nii", out_file="c.nii", operation = op) if ent == "b.nii": maths.inputs.operand_file = ent yield assert_equal, maths.cmdline, "fslmaths a.nii -%s b.nii c.nii"%op else: maths.inputs.operand_value = ent yield assert_equal, maths.cmdline, "fslmaths a.nii -%s %.8f c.nii"%(op, ent) # Test that we don't need to ask for an out file for op in ops: maths = fsl.BinaryMaths(in_file="a.nii", operation=op, operand_file="b.nii") yield assert_equal, maths.cmdline, "fslmaths a.nii -%s b.nii %s"%(op,os.path.join(testdir,"a_maths.nii")) # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_multimaths(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command maths = fsl.MultiImageMaths(in_file="a.nii",out_file="c.nii") # Test the underlying command yield assert_equal, maths.cmd, "fslmaths" # Test that it fails without an operation an yield assert_raises, ValueError, maths.run # Test a few operations maths.inputs.operand_files = ["a.nii", "b.nii"] opstrings = ["-add %s -div %s", "-max 1 -sub %s -min %s", "-mas %s -add %s"] for ostr in opstrings: maths.inputs.op_string = ostr yield assert_equal, maths.cmdline, "fslmaths a.nii %s c.nii"%ostr%("a.nii", "b.nii") # Test that we don't need to ask for an out file maths = fsl.MultiImageMaths(in_file="a.nii", op_string="-add %s -mul 5", operand_files=["b.nii"]) yield assert_equal, maths.cmdline, \ "fslmaths a.nii -add b.nii -mul 5 %s"%os.path.join(testdir,"a_maths.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) @skipif(no_fsl) def test_tempfilt(): files, testdir, origdir, ftype = create_files_in_directory() # Get the command filt = fsl.TemporalFilter(in_file="a.nii",out_file="b.nii") # Test the underlying command yield assert_equal, filt.cmd, "fslmaths" # Test that both filters are initialized off yield assert_equal, filt.cmdline, "fslmaths a.nii -bptf -1.000000 -1.000000 b.nii" # Test some filters windows = [(-1, -1), (0.1, 0.1), (-1, 20), (20, -1), (128, 248)] for win in windows: filt.inputs.highpass_sigma = win[0] filt.inputs.lowpass_sigma = win[1] yield assert_equal, filt.cmdline, "fslmaths a.nii -bptf %.6f %.6f b.nii"%win # Test that we don't need to ask for an out file filt = fsl.TemporalFilter(in_file="a.nii", highpass_sigma = 64) yield assert_equal, filt.cmdline, \ "fslmaths a.nii -bptf 64.000000 -1.000000 %s"%os.path.join(testdir,"a_filt.nii") # Clean up our mess clean_directory(testdir, origdir, ftype) nipype-0.11.0/nipype/interfaces/fsl/tests/test_model.py000066400000000000000000000053151257611314500231740ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import tempfile import shutil from nipype.testing import (assert_equal, assert_true, skipif) import nipype.interfaces.fsl.model as fsl from nipype.interfaces.fsl import Info from nipype.interfaces.fsl import no_fsl tmp_infile = None tmp_dir = None cwd = None @skipif(no_fsl) def setup_infile(): global tmp_infile, tmp_dir, cwd cwd = os.getcwd() ext = Info.output_type_to_ext(Info.output_type()) tmp_dir = tempfile.mkdtemp() tmp_infile = os.path.join(tmp_dir, 'foo' + ext) file(tmp_infile, 'w') os.chdir(tmp_dir) return tmp_infile, tmp_dir def teardown_infile(tmp_dir): os.chdir(cwd) shutil.rmtree(tmp_dir) @skipif(no_fsl) def test_MultipleRegressDesign(): _, tp_dir = setup_infile() foo = fsl.MultipleRegressDesign() foo.inputs.regressors = dict(voice_stenght=[1,1,1],age=[0.2,0.4,0.5],BMI=[1,-1,2]) con1 = ['voice_and_age','T',['age','voice_stenght'],[0.5,0.5]] con2 = ['just_BMI','T',['BMI'],[1]] foo.inputs.contrasts = [con1,con2,['con3','F',[con1,con2]]] res = foo.run() yield assert_equal, res.outputs.design_mat, os.path.join(os.getcwd(),'design.mat') yield assert_equal, res.outputs.design_con, os.path.join(os.getcwd(),'design.con') yield assert_equal, res.outputs.design_fts, os.path.join(os.getcwd(),'design.fts') yield assert_equal, res.outputs.design_grp, os.path.join(os.getcwd(),'design.grp') design_mat_expected_content = """/NumWaves 3 /NumPoints 3 /PPheights 3.000000e+00 5.000000e-01 1.000000e+00 /Matrix 1.000000e+00 2.000000e-01 1.000000e+00 -1.000000e+00 4.000000e-01 1.000000e+00 2.000000e+00 5.000000e-01 1.000000e+00 """ design_con_expected_content = """/ContrastName1 voice_and_age /ContrastName2 just_BMI /NumWaves 3 /NumContrasts 2 /PPheights 1.000000e+00 1.000000e+00 /RequiredEffect 100.000 100.000 /Matrix 0.000000e+00 5.000000e-01 5.000000e-01 1.000000e+00 0.000000e+00 0.000000e+00 """ design_fts_expected_content = """/NumWaves 2 /NumContrasts 1 /Matrix 1 1 """ design_grp_expected_content = """/NumWaves 1 /NumPoints 3 /Matrix 1 1 1 """ yield assert_equal, open(os.path.join(os.getcwd(),'design.con'), 'r').read(), design_con_expected_content yield assert_equal, open(os.path.join(os.getcwd(),'design.mat'), 'r').read(), design_mat_expected_content yield assert_equal, open(os.path.join(os.getcwd(),'design.fts'), 'r').read(), design_fts_expected_content yield assert_equal, open(os.path.join(os.getcwd(),'design.grp'), 'r').read(), design_grp_expected_content teardown_infile(tp_dir) nipype-0.11.0/nipype/interfaces/fsl/tests/test_preprocess.py000066400000000000000000000514611257611314500242640ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import tempfile import shutil from nipype.testing import (assert_equal, assert_not_equal, assert_raises, skipif) from nipype.utils.filemanip import split_filename import nipype.interfaces.fsl.preprocess as fsl from nipype.interfaces.fsl import Info from nipype.interfaces.base import File, TraitError, Undefined, isdefined from nipype.interfaces.fsl import no_fsl @skipif(no_fsl) def fsl_name(obj, fname): """Create valid fsl name, including file extension for output type. """ ext = Info.output_type_to_ext(obj.inputs.output_type) return fname + ext tmp_infile = None tmp_dir = None @skipif(no_fsl) def setup_infile(): global tmp_infile, tmp_dir ext = Info.output_type_to_ext(Info.output_type()) tmp_dir = tempfile.mkdtemp() tmp_infile = os.path.join(tmp_dir, 'foo' + ext) file(tmp_infile, 'w') return tmp_infile, tmp_dir def teardown_infile(tmp_dir): shutil.rmtree(tmp_dir) # test BET #@with_setup(setup_infile, teardown_infile) # broken in nose with generators @skipif(no_fsl) def test_bet(): tmp_infile, tp_dir = setup_infile() better = fsl.BET() yield assert_equal, better.cmd, 'bet' # Test raising error with mandatory args absent yield assert_raises, ValueError, better.run # Test generated outfile name better.inputs.in_file = tmp_infile outfile = fsl_name(better, 'foo_brain') outpath = os.path.join(os.getcwd(), outfile) realcmd = 'bet %s %s' % (tmp_infile, outpath) yield assert_equal, better.cmdline, realcmd # Test specified outfile name outfile = fsl_name(better, '/newdata/bar') better.inputs.out_file = outfile realcmd = 'bet %s %s' % (tmp_infile, outfile) yield assert_equal, better.cmdline, realcmd # infile foo.nii doesn't exist def func(): better.run(in_file='foo2.nii', out_file='bar.nii') yield assert_raises, TraitError, func # Our options and some test values for them # Should parallel the opt_map structure in the class for clarity opt_map = { 'outline': ('-o', True), 'mask': ('-m', True), 'skull': ('-s', True), 'no_output': ('-n', True), 'frac': ('-f 0.40', 0.4), 'vertical_gradient': ('-g 0.75', 0.75), 'radius': ('-r 20', 20), 'center': ('-c 54 75 80', [54, 75, 80]), 'threshold': ('-t', True), 'mesh': ('-e', True), 'surfaces': ('-A', True) #'verbose': ('-v', True), #'flags': ('--i-made-this-up', '--i-made-this-up'), } # Currently we don't test -R, -S, -B, -Z, -F, -A or -A2 # test each of our arguments better = fsl.BET() outfile = fsl_name(better, 'foo_brain') outpath = os.path.join(os.getcwd(), outfile) for name, settings in opt_map.items(): better = fsl.BET(**{name: settings[1]}) # Add mandatory input better.inputs.in_file = tmp_infile realcmd = ' '.join([better.cmd, tmp_infile, outpath, settings[0]]) yield assert_equal, better.cmdline, realcmd teardown_infile(tmp_dir) # test fast @skipif(no_fsl) def test_fast(): tmp_infile, tp_dir = setup_infile() faster = fsl.FAST() faster.inputs.verbose = True fasted = fsl.FAST(in_files=tmp_infile, verbose=True) fasted2 = fsl.FAST(in_files=[tmp_infile, tmp_infile], verbose=True) yield assert_equal, faster.cmd, 'fast' yield assert_equal, faster.inputs.verbose, True yield assert_equal, faster.inputs.manual_seg, Undefined yield assert_not_equal, faster.inputs, fasted.inputs yield assert_equal, fasted.cmdline, 'fast -v -S 1 %s' % (tmp_infile) yield assert_equal, fasted2.cmdline, 'fast -v -S 2 %s %s' % (tmp_infile, tmp_infile) faster = fsl.FAST() faster.inputs.in_files = tmp_infile yield assert_equal, faster.cmdline, 'fast -S 1 %s' % (tmp_infile) faster.inputs.in_files = [tmp_infile, tmp_infile] yield assert_equal, faster.cmdline, 'fast -S 2 %s %s' % (tmp_infile, tmp_infile) # Our options and some test values for them # Should parallel the opt_map structure in the class for clarity opt_map = {'number_classes': ('-n 4', 4), 'bias_iters': ('-I 5', 5), 'bias_lowpass': ('-l 15', 15), 'img_type': ('-t 2', 2), 'init_seg_smooth': ('-f 0.035', 0.035), 'segments': ('-g', True), 'init_transform': ('-a %s' % (tmp_infile), '%s' % (tmp_infile)), 'other_priors': ('-A %s %s %s' % (tmp_infile, tmp_infile, tmp_infile), (['%s' % (tmp_infile), '%s' % (tmp_infile), '%s' % (tmp_infile)])), 'no_pve': ('--nopve', True), 'output_biasfield': ('-b', True), 'output_biascorrected': ('-B', True), 'no_bias': ('-N', True), 'out_basename': ('-o fasted', 'fasted'), 'use_priors': ('-P', True), 'segment_iters': ('-W 14', 14), 'mixel_smooth': ('-R 0.25', 0.25), 'iters_afterbias': ('-O 3', 3), 'hyper': ('-H 0.15', 0.15), 'verbose': ('-v', True), 'manual_seg': ('-s %s' % (tmp_infile), '%s' % (tmp_infile)), 'probability_maps': ('-p', True), } # test each of our arguments for name, settings in opt_map.items(): faster = fsl.FAST(in_files=tmp_infile, **{name: settings[1]}) yield assert_equal, faster.cmdline, ' '.join([faster.cmd, settings[0], "-S 1 %s" % tmp_infile]) teardown_infile(tmp_dir) @skipif(no_fsl) def setup_flirt(): ext = Info.output_type_to_ext(Info.output_type()) tmpdir = tempfile.mkdtemp() _, infile = tempfile.mkstemp(suffix=ext, dir=tmpdir) _, reffile = tempfile.mkstemp(suffix=ext, dir=tmpdir) return tmpdir, infile, reffile def teardown_flirt(tmpdir): shutil.rmtree(tmpdir) @skipif(no_fsl) def test_flirt(): # setup tmpdir, infile, reffile = setup_flirt() flirter = fsl.FLIRT() yield assert_equal, flirter.cmd, 'flirt' flirter.inputs.bins = 256 flirter.inputs.cost = 'mutualinfo' flirted = fsl.FLIRT(in_file=infile, reference=reffile, out_file='outfile', out_matrix_file='outmat.mat', bins=256, cost='mutualinfo') flirt_est = fsl.FLIRT(in_file=infile, reference=reffile, out_matrix_file='outmat.mat', bins=256, cost='mutualinfo') yield assert_not_equal, flirter.inputs, flirted.inputs yield assert_not_equal, flirted.inputs, flirt_est.inputs yield assert_equal, flirter.inputs.bins, flirted.inputs.bins yield assert_equal, flirter.inputs.cost, flirt_est.inputs.cost realcmd = 'flirt -in %s -ref %s -out outfile -omat outmat.mat ' \ '-bins 256 -cost mutualinfo' % (infile, reffile) yield assert_equal, flirted.cmdline, realcmd flirter = fsl.FLIRT() # infile not specified yield assert_raises, ValueError, flirter.run flirter.inputs.in_file = infile # reference not specified yield assert_raises, ValueError, flirter.run flirter.inputs.reference = reffile # Generate outfile and outmatrix pth, fname, ext = split_filename(infile) outfile = fsl_name(flirter, '%s_flirt' % fname) outmat = '%s_flirt.mat' % fname realcmd = 'flirt -in %s -ref %s -out %s -omat %s' % (infile, reffile, outfile, outmat) yield assert_equal, flirter.cmdline, realcmd _, tmpfile = tempfile.mkstemp(suffix='.nii', dir=tmpdir) # Loop over all inputs, set a reasonable value and make sure the # cmdline is updated correctly. for key, trait_spec in sorted(fsl.FLIRT.input_spec().traits().items()): # Skip mandatory inputs and the trait methods if key in ('trait_added', 'trait_modified', 'in_file', 'reference', 'environ', 'output_type', 'out_file', 'out_matrix_file', 'in_matrix_file', 'apply_xfm', 'ignore_exception', 'terminal_output', 'out_log', 'save_log'): continue param = None value = None if key == 'args': param = '-v' value = '-v' elif isinstance(trait_spec.trait_type, File): value = tmpfile param = trait_spec.argstr % value elif trait_spec.default is False: param = trait_spec.argstr value = True elif key in ('searchr_x', 'searchr_y', 'searchr_z'): value = [-45, 45] param = trait_spec.argstr % ' '.join(str(elt) for elt in value) else: value = trait_spec.default param = trait_spec.argstr % value cmdline = 'flirt -in %s -ref %s' % (infile, reffile) # Handle autogeneration of outfile pth, fname, ext = split_filename(infile) outfile = fsl_name(fsl.FLIRT(), '%s_flirt' % fname) outfile = ' '.join(['-out', outfile]) # Handle autogeneration of outmatrix outmatrix = '%s_flirt.mat' % fname outmatrix = ' '.join(['-omat', outmatrix]) # Build command line cmdline = ' '.join([cmdline, outfile, outmatrix, param]) flirter = fsl.FLIRT(in_file=infile, reference=reffile) setattr(flirter.inputs, key, value) yield assert_equal, flirter.cmdline, cmdline # Test OutputSpec flirter = fsl.FLIRT(in_file=infile, reference=reffile) pth, fname, ext = split_filename(infile) flirter.inputs.out_file = ''.join(['foo', ext]) flirter.inputs.out_matrix_file = ''.join(['bar', ext]) outs = flirter._list_outputs() yield assert_equal, outs['out_file'], \ os.path.join(os.getcwd(), flirter.inputs.out_file) yield assert_equal, outs['out_matrix_file'], \ os.path.join(os.getcwd(), flirter.inputs.out_matrix_file) teardown_flirt(tmpdir) # Mcflirt @skipif(no_fsl) def test_mcflirt(): tmpdir, infile, reffile = setup_flirt() frt = fsl.MCFLIRT() yield assert_equal, frt.cmd, 'mcflirt' # Test generated outfile name frt.inputs.in_file = infile _, nme = os.path.split(infile) outfile = os.path.join(os.getcwd(), nme) outfile = frt._gen_fname(outfile, suffix='_mcf') realcmd = 'mcflirt -in ' + infile + ' -out ' + outfile yield assert_equal, frt.cmdline, realcmd # Test specified outfile name outfile2 = '/newdata/bar.nii' frt.inputs.out_file = outfile2 realcmd = 'mcflirt -in ' + infile + ' -out ' + outfile2 yield assert_equal, frt.cmdline, realcmd opt_map = { 'cost': ('-cost mutualinfo', 'mutualinfo'), 'bins': ('-bins 256', 256), 'dof': ('-dof 6', 6), 'ref_vol': ('-refvol 2', 2), 'scaling': ('-scaling 6.00', 6.00), 'smooth': ('-smooth 1.00', 1.00), 'rotation': ('-rotation 2', 2), 'stages': ('-stages 3', 3), 'init': ('-init %s' % (infile), infile), 'use_gradient': ('-gdt', True), 'use_contour': ('-edge', True), 'mean_vol': ('-meanvol', True), 'stats_imgs': ('-stats', True), 'save_mats': ('-mats', True), 'save_plots': ('-plots', True), } for name, settings in opt_map.items(): fnt = fsl.MCFLIRT(in_file=infile, **{name: settings[1]}) instr = '-in %s' % (infile) outstr = '-out %s' % (outfile) if name in ('init', 'cost', 'dof', 'mean_vol', 'bins'): yield assert_equal, fnt.cmdline, ' '.join([fnt.cmd, instr, settings[0], outstr]) else: yield assert_equal, fnt.cmdline, ' '.join([fnt.cmd, instr, outstr, settings[0]]) # Test error is raised when missing required args fnt = fsl.MCFLIRT() yield assert_raises, ValueError, fnt.run teardown_flirt(tmpdir) # test fnirt @skipif(no_fsl) def test_fnirt(): tmpdir, infile, reffile = setup_flirt() fnirt = fsl.FNIRT() yield assert_equal, fnirt.cmd, 'fnirt' # Test list parameters params = [('subsampling_scheme', '--subsamp', [4, 2, 2, 1], '4,2,2,1'), ('max_nonlin_iter', '--miter', [4, 4, 4, 2], '4,4,4,2'), ('ref_fwhm', '--reffwhm', [4, 2, 2, 0], '4,2,2,0'), ('in_fwhm', '--infwhm', [4, 2, 2, 0], '4,2,2,0'), ('apply_refmask', '--applyrefmask', [0, 0, 1, 1], '0,0,1,1'), ('apply_inmask', '--applyinmask', [0, 0, 0, 1], '0,0,0,1'), ('regularization_lambda', '--lambda', [0.5, 0.75], '0.5,0.75')] for item, flag, val, strval in params: fnirt = fsl.FNIRT(in_file=infile, ref_file=reffile, **{item: val}) log = fnirt._gen_fname(infile, suffix='_log.txt', change_ext=False) iout = fnirt._gen_fname(infile, suffix='_warped') if item in ('max_nonlin_iter'): cmd = 'fnirt --in=%s '\ '--logout=%s'\ ' %s=%s --ref=%s'\ ' --iout=%s' % (infile, log, flag, strval, reffile, iout) elif item in ('in_fwhm'): cmd = 'fnirt --in=%s %s=%s --logout=%s '\ '--ref=%s --iout=%s' % (infile, flag, strval, log, reffile, iout) elif item.startswith('apply'): cmd = 'fnirt %s=%s '\ '--in=%s '\ '--logout=%s '\ '--ref=%s --iout=%s' % (flag, strval, infile, log, reffile, iout) else: cmd = 'fnirt '\ '--in=%s --logout=%s '\ '--ref=%s %s=%s --iout=%s' % (infile, log, reffile, flag, strval, iout) yield assert_equal, fnirt.cmdline, cmd # Test ValueError is raised when missing mandatory args fnirt = fsl.FNIRT() yield assert_raises, ValueError, fnirt.run fnirt.inputs.in_file = infile fnirt.inputs.ref_file = reffile # test files opt_map = { 'affine_file': ('--aff='), 'inwarp_file': ('--inwarp='), 'in_intensitymap_file': ('--intin='), 'config_file': ('--config='), 'refmask_file': ('--refmask='), 'inmask_file': ('--inmask='), 'field_file': ('--fout='), 'jacobian_file': ('--jout='), 'modulatedref_file': ('--refout='), 'out_intensitymap_file': ('--intout='), 'log_file': ('--logout=')} for name, settings in opt_map.items(): fnirt = fsl.FNIRT(in_file=infile, ref_file=reffile, **{name: infile}) if name in ('config_file', 'affine_file', 'field_file'): cmd = 'fnirt %s%s --in=%s '\ '--logout=%s '\ '--ref=%s --iout=%s' % (settings, infile, infile, log, reffile, iout) elif name in ('refmask_file'): cmd = 'fnirt --in=%s '\ '--logout=%s --ref=%s '\ '%s%s '\ '--iout=%s' % (infile, log, reffile, settings, infile, iout) elif name in ('in_intensitymap_file', 'inwarp_file', 'inmask_file', 'jacobian_file'): cmd = 'fnirt --in=%s '\ '%s%s '\ '--logout=%s --ref=%s '\ '--iout=%s' % (infile, settings, infile, log, reffile, iout) elif name in ('log_file'): cmd = 'fnirt --in=%s '\ '%s%s --ref=%s '\ '--iout=%s' % (infile, settings, infile, reffile, iout) else: cmd = 'fnirt --in=%s '\ '--logout=%s %s%s '\ '--ref=%s --iout=%s' % (infile, log, settings, infile, reffile, iout) yield assert_equal, fnirt.cmdline, cmd teardown_flirt(tmpdir) @skipif(no_fsl) def test_applywarp(): tmpdir, infile, reffile = setup_flirt() opt_map = { 'out_file': ('--out=bar.nii', 'bar.nii'), 'premat': ('--premat=%s' % (reffile), reffile), 'postmat': ('--postmat=%s' % (reffile), reffile), } # in_file, ref_file, field_file mandatory for name, settings in opt_map.items(): awarp = fsl.ApplyWarp(in_file=infile, ref_file=reffile, field_file=reffile, **{name: settings[1]}) if name == 'out_file': realcmd = 'applywarp --in=%s '\ '--ref=%s --out=%s '\ '--warp=%s' % (infile, reffile, settings[1], reffile) else: outfile = awarp._gen_fname(infile, suffix='_warp') realcmd = 'applywarp --in=%s '\ '--ref=%s --out=%s '\ '--warp=%s %s' % (infile, reffile, outfile, reffile, settings[0]) yield assert_equal, awarp.cmdline, realcmd awarp = fsl.ApplyWarp(in_file=infile, ref_file=reffile, field_file=reffile) teardown_flirt(tmpdir) @skipif(no_fsl) def setup_fugue(): import nibabel as nb import numpy as np import os.path as op d = np.ones((80, 80, 80)) tmpdir = tempfile.mkdtemp() infile = op.join(tmpdir, 'dumbfile.nii.gz') nb.Nifti1Image(d, None, None).to_filename(infile) return tmpdir, infile def teardown_fugue(tmpdir): shutil.rmtree(tmpdir) @skipif(no_fsl) def test_fugue(): import os.path as op tmpdir, infile = setup_fugue() fugue = fsl.FUGUE() fugue.inputs.save_unmasked_fmap = True fugue.inputs.fmap_in_file = infile fugue.inputs.mask_file = infile fugue.inputs.output_type = "NIFTI_GZ" res = fugue.run() if not isdefined(res.outputs.fmap_out_file): yield False else: trait_spec = fugue.inputs.trait('fmap_out_file') out_name = trait_spec.name_template % 'dumbfile' out_name += '.nii.gz' yield assert_equal, op.basename(res.outputs.fmap_out_file), out_name fugue = fsl.FUGUE() fugue.inputs.save_unmasked_shift = True fugue.inputs.fmap_in_file = infile fugue.inputs.dwell_time = 1.0e-3 fugue.inputs.mask_file = infile fugue.inputs.output_type = "NIFTI_GZ" res = fugue.run() if not isdefined(res.outputs.shift_out_file): yield False else: trait_spec = fugue.inputs.trait('shift_out_file') out_name = trait_spec.name_template % 'dumbfile' out_name += '.nii.gz' yield assert_equal, op.basename(res.outputs.shift_out_file), \ out_name fugue = fsl.FUGUE() fugue.inputs.in_file = infile fugue.inputs.mask_file = infile # Previously computed with fugue as well fugue.inputs.shift_in_file = infile fugue.inputs.output_type = "NIFTI_GZ" res = fugue.run() if not isdefined(res.outputs.unwarped_file): yield False else: trait_spec = fugue.inputs.trait('unwarped_file') out_name = trait_spec.name_template % 'dumbfile' out_name += '.nii.gz' yield assert_equal, op.basename(res.outputs.unwarped_file), out_name teardown_fugue(tmpdir) nipype-0.11.0/nipype/interfaces/fsl/tests/test_utils.py000066400000000000000000000247151257611314500232410ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np import nibabel as nb from nipype.testing import (assert_equal, assert_not_equal, assert_raises, skipif) import nipype.interfaces.fsl.utils as fsl from nipype.interfaces.fsl import no_fsl def create_files_in_directory(): outdir = mkdtemp() cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii', 'b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3, 3, 3, 4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img, np.eye(4), hdr), os.path.join(outdir, f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) @skipif(no_fsl) def test_fslroi(): filelist, outdir, cwd = create_files_in_directory() roi = fsl.ExtractROI() # make sure command gets called yield assert_equal, roi.cmd, 'fslroi' # test raising error with mandatory args absent yield assert_raises, ValueError, roi.run # .inputs based parameters setting roi.inputs.in_file = filelist[0] roi.inputs.roi_file = 'foo_roi.nii' roi.inputs.t_min = 10 roi.inputs.t_size = 20 yield assert_equal, roi.cmdline, 'fslroi %s foo_roi.nii 10 20' % filelist[0] # .run based parameter setting roi2 = fsl.ExtractROI(in_file=filelist[0], roi_file='foo2_roi.nii', t_min=20, t_size=40, x_min=3, x_size=30, y_min=40, y_size=10, z_min=5, z_size=20) yield assert_equal, roi2.cmdline, \ 'fslroi %s foo2_roi.nii 3 30 40 10 5 20 20 40' % filelist[0] clean_directory(outdir, cwd) # test arguments for opt_map # Fslroi class doesn't have a filled opt_map{} @skipif(no_fsl) def test_fslmerge(): filelist, outdir, cwd = create_files_in_directory() merger = fsl.Merge() # make sure command gets called yield assert_equal, merger.cmd, 'fslmerge' # test raising error with mandatory args absent yield assert_raises, ValueError, merger.run # .inputs based parameters setting merger.inputs.in_files = filelist merger.inputs.merged_file = 'foo_merged.nii' merger.inputs.dimension = 't' merger.inputs.output_type = 'NIFTI' yield assert_equal, merger.cmdline, 'fslmerge -t foo_merged.nii %s' % ' '.join(filelist) # verify that providing a tr value updates the dimension to tr merger.inputs.tr = 2.25 yield assert_equal, merger.cmdline, 'fslmerge -tr foo_merged.nii %s %.2f' % (' '.join(filelist), 2.25) # .run based parameter setting merger2 = fsl.Merge(in_files=filelist, merged_file='foo_merged.nii', dimension='t', output_type='NIFTI', tr=2.25) yield assert_equal, merger2.cmdline, \ 'fslmerge -tr foo_merged.nii %s %.2f' % (' '.join(filelist), 2.25) clean_directory(outdir, cwd) # test arguments for opt_map # Fslmerge class doesn't have a filled opt_map{} # test fslmath @skipif(no_fsl) def test_fslmaths(): filelist, outdir, cwd = create_files_in_directory() math = fsl.ImageMaths() # make sure command gets called yield assert_equal, math.cmd, 'fslmaths' # test raising error with mandatory args absent yield assert_raises, ValueError, math.run # .inputs based parameters setting math.inputs.in_file = filelist[0] math.inputs.op_string = '-add 2.5 -mul input_volume2' math.inputs.out_file = 'foo_math.nii' yield assert_equal, math.cmdline, \ 'fslmaths %s -add 2.5 -mul input_volume2 foo_math.nii' % filelist[0] # .run based parameter setting math2 = fsl.ImageMaths(in_file=filelist[0], op_string='-add 2.5', out_file='foo2_math.nii') yield assert_equal, math2.cmdline, 'fslmaths %s -add 2.5 foo2_math.nii' % filelist[0] # test arguments for opt_map # Fslmath class doesn't have opt_map{} clean_directory(outdir, cwd) # test overlay @skipif(no_fsl) def test_overlay(): filelist, outdir, cwd = create_files_in_directory() overlay = fsl.Overlay() # make sure command gets called yield assert_equal, overlay.cmd, 'overlay' # test raising error with mandatory args absent yield assert_raises, ValueError, overlay.run # .inputs based parameters setting overlay.inputs.stat_image = filelist[0] overlay.inputs.stat_thresh = (2.5, 10) overlay.inputs.background_image = filelist[1] overlay.inputs.auto_thresh_bg = True overlay.inputs.show_negative_stats = True overlay.inputs.out_file = 'foo_overlay.nii' yield assert_equal, overlay.cmdline, \ 'overlay 1 0 %s -a %s 2.50 10.00 %s -2.50 -10.00 foo_overlay.nii' % ( filelist[1], filelist[0], filelist[0]) # .run based parameter setting overlay2 = fsl.Overlay(stat_image=filelist[0], stat_thresh=(2.5, 10), background_image=filelist[1], auto_thresh_bg=True, out_file='foo2_overlay.nii') yield assert_equal, overlay2.cmdline, 'overlay 1 0 %s -a %s 2.50 10.00 foo2_overlay.nii' % ( filelist[1], filelist[0]) clean_directory(outdir, cwd) # test slicer @skipif(no_fsl) def test_slicer(): filelist, outdir, cwd = create_files_in_directory() slicer = fsl.Slicer() # make sure command gets called yield assert_equal, slicer.cmd, 'slicer' # test raising error with mandatory args absent yield assert_raises, ValueError, slicer.run # .inputs based parameters setting slicer.inputs.in_file = filelist[0] slicer.inputs.image_edges = filelist[1] slicer.inputs.intensity_range = (10., 20.) slicer.inputs.all_axial = True slicer.inputs.image_width = 750 slicer.inputs.out_file = 'foo_bar.png' yield assert_equal, slicer.cmdline, \ 'slicer %s %s -L -i 10.000 20.000 -A 750 foo_bar.png' % ( filelist[0], filelist[1]) # .run based parameter setting slicer2 = fsl.Slicer( in_file=filelist[0], middle_slices=True, label_slices=False, out_file='foo_bar2.png') yield assert_equal, slicer2.cmdline, 'slicer %s -a foo_bar2.png' % (filelist[0]) clean_directory(outdir, cwd) def create_parfiles(): np.savetxt('a.par', np.random.rand(6, 3)) np.savetxt('b.par', np.random.rand(6, 3)) return ['a.par', 'b.par'] # test fsl_tsplot @skipif(no_fsl) def test_plottimeseries(): filelist, outdir, cwd = create_files_in_directory() parfiles = create_parfiles() plotter = fsl.PlotTimeSeries() # make sure command gets called yield assert_equal, plotter.cmd, 'fsl_tsplot' # test raising error with mandatory args absent yield assert_raises, ValueError, plotter.run # .inputs based parameters setting plotter.inputs.in_file = parfiles[0] plotter.inputs.labels = ['x', 'y', 'z'] plotter.inputs.y_range = (0, 1) plotter.inputs.title = 'test plot' plotter.inputs.out_file = 'foo.png' yield assert_equal, plotter.cmdline, \ ('fsl_tsplot -i %s -a x,y,z -o foo.png -t \'test plot\' -u 1 --ymin=0 --ymax=1' % parfiles[0]) # .run based parameter setting plotter2 = fsl.PlotTimeSeries( in_file=parfiles, title='test2 plot', plot_range=(2, 5), out_file='bar.png') yield assert_equal, plotter2.cmdline, \ 'fsl_tsplot -i %s,%s -o bar.png --start=2 --finish=5 -t \'test2 plot\' -u 1' % tuple( parfiles) clean_directory(outdir, cwd) @skipif(no_fsl) def test_plotmotionparams(): filelist, outdir, cwd = create_files_in_directory() parfiles = create_parfiles() plotter = fsl.PlotMotionParams() # make sure command gets called yield assert_equal, plotter.cmd, 'fsl_tsplot' # test raising error with mandatory args absent yield assert_raises, ValueError, plotter.run # .inputs based parameters setting plotter.inputs.in_file = parfiles[0] plotter.inputs.in_source = 'fsl' plotter.inputs.plot_type = 'rotations' plotter.inputs.out_file = 'foo.png' yield assert_equal, plotter.cmdline, \ ('fsl_tsplot -i %s -o foo.png -t \'MCFLIRT estimated rotations (radians)\' ' '--start=1 --finish=3 -a x,y,z' % parfiles[0]) # .run based parameter setting plotter2 = fsl.PlotMotionParams( in_file=parfiles[1], in_source='spm', plot_type='translations', out_file='bar.png') yield assert_equal, plotter2.cmdline, \ ('fsl_tsplot -i %s -o bar.png -t \'Realign estimated translations (mm)\' ' '--start=1 --finish=3 -a x,y,z' % parfiles[1]) clean_directory(outdir, cwd) @skipif(no_fsl) def test_convertxfm(): filelist, outdir, cwd = create_files_in_directory() cvt = fsl.ConvertXFM() # make sure command gets called yield assert_equal, cvt.cmd, "convert_xfm" # test raising error with mandatory args absent yield assert_raises, ValueError, cvt.run # .inputs based parameters setting cvt.inputs.in_file = filelist[0] cvt.inputs.invert_xfm = True cvt.inputs.out_file = "foo.mat" yield assert_equal, cvt.cmdline, 'convert_xfm -omat foo.mat -inverse %s' % filelist[0] # constructor based parameter setting cvt2 = fsl.ConvertXFM( in_file=filelist[0], in_file2=filelist[1], concat_xfm=True, out_file="bar.mat") yield assert_equal, cvt2.cmdline, \ "convert_xfm -omat bar.mat -concat %s %s" % (filelist[1], filelist[0]) clean_directory(outdir, cwd) @skipif(no_fsl) def test_swapdims(): files, testdir, origdir = create_files_in_directory() swap = fsl.SwapDimensions() # Test the underlying command yield assert_equal, swap.cmd, "fslswapdim" # Test mandatory args args = [dict(in_file=files[0]), dict(new_dims=("x", "y", "z"))] for arg in args: wontrun = fsl.SwapDimensions(**arg) yield assert_raises, ValueError, wontrun.run # Now test a basic command line swap.inputs.in_file = files[0] swap.inputs.new_dims = ("x", "y", "z") yield assert_equal, swap.cmdline, "fslswapdim a.nii x y z %s" % os.path.realpath(os.path.join(testdir, "a_newdims.nii")) # Test that we can set an output name swap.inputs.out_file = "b.nii" yield assert_equal, swap.cmdline, "fslswapdim a.nii x y z b.nii" # Clean up clean_directory(testdir, origdir) nipype-0.11.0/nipype/interfaces/fsl/utils.py000066400000000000000000002430661257611314500210420ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The fsl module provides classes for interfacing with the `FSL `_ command line tools. This was written to work with FSL version 4.1.4. Examples -------- See the docstrings of the individual classes for examples. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os from glob import glob import warnings import tempfile import numpy as np from .base import FSLCommand, FSLCommandInputSpec, Info from ..base import (traits, TraitedSpec, OutputMultiPath, File, CommandLine, CommandLineInputSpec, isdefined) from ...utils.filemanip import (load_json, save_json, split_filename, fname_presuffix, copyfile) warn = warnings.warn warnings.filterwarnings('always', category=UserWarning) class CopyGeomInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="%s", position=0, desc="source image") dest_file = File(exists=True, mandatory=True, argstr="%s", position=1, desc="destination image", copyfile=True, output_name='out_file', name_source='dest_file', name_template='%s') ignore_dims = traits.Bool(desc=('Do not copy image dimensions'), argstr='-d', position="-1") class CopyGeomOutputSpec(TraitedSpec): out_file = File(exists=True, desc="image with new geometry header") class CopyGeom(FSLCommand): """Use fslcpgeom to copy the header geometry information to another image. Copy certain parts of the header information (image dimensions, voxel dimensions, voxel dimensions units string, image orientation/origin or qform/sform info) from one image to another. Note that only copies from Analyze to Analyze or Nifti to Nifti will work properly. Copying from different files will result in loss of information or potentially incorrect settings. """ _cmd = "fslcpgeom" input_spec = CopyGeomInputSpec output_spec = CopyGeomOutputSpec class RobustFOVInputSpec(FSLCommandInputSpec): in_file = File(exists=True, desc='input filename', argstr='-i %s', position=0, mandatory=True) out_roi = File(desc="ROI volume output name", argstr="-r %s", name_source=['in_file'], hash_files=False, name_template='%s_ROI') class RobustFOVOutputSpec(TraitedSpec): out_roi = File(exists=True, desc="ROI volume output name") class RobustFOV(FSLCommand): _cmd = 'robustfov' input_spec = RobustFOVInputSpec output_spec = RobustFOVOutputSpec class ImageMeantsInputSpec(FSLCommandInputSpec): in_file = File(exists=True, desc='input file for computing the average timeseries', argstr='-i %s', position=0, mandatory=True) out_file = File(desc='name of output text matrix', argstr='-o %s', genfile=True, hash_files=False) mask = File(exists=True, desc='input 3D mask', argstr='-m %s') spatial_coord = traits.List(traits.Int, desc=(' requested spatial coordinate ' '(instead of mask)'), argstr='-c %s') use_mm = traits.Bool(desc=('use mm instead of voxel coordinates (for -c ' 'option)'), argstr='--usemm') show_all = traits.Bool(desc=('show all voxel time series (within mask) ' 'instead of averaging'), argstr='--showall') eig = traits.Bool(desc=('calculate Eigenvariate(s) instead of mean (output ' 'will have 0 mean)'), argstr='--eig') order = traits.Int(1, desc='select number of Eigenvariates', argstr='--order=%d', usedefault=True) nobin = traits.Bool(desc=('do not binarise the mask for calculation of ' 'Eigenvariates'), argstr='--no_bin') transpose = traits.Bool(desc=('output results in transpose format (one row ' 'per voxel/mean)'), argstr='--transpose') class ImageMeantsOutputSpec(TraitedSpec): out_file = File(exists=True, desc="path/name of output text matrix") class ImageMeants(FSLCommand): """ Use fslmeants for printing the average timeseries (intensities) to the screen (or saves to a file). The average is taken over all voxels in the mask (or all voxels in the image if no mask is specified) """ _cmd = 'fslmeants' input_spec = ImageMeantsInputSpec output_spec = ImageMeantsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']): outputs['out_file'] = self._gen_fname(self.inputs.in_file, suffix='_ts', ext='.txt', change_ext=True) outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] return None class SmoothInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr="%s", position=0, mandatory=True) fwhm = traits.Float(argstr="-kernel gauss %f -fmean", position=1, mandatory=True) smoothed_file = File( argstr="%s", position=2, genfile=True, hash_files=False) class SmoothOutputSpec(TraitedSpec): smoothed_file = File(exists=True) class Smooth(FSLCommand): '''Use fslmaths to smooth the image ''' input_spec = SmoothInputSpec output_spec = SmoothOutputSpec _cmd = 'fslmaths' def _gen_filename(self, name): if name == 'smoothed_file': return self._list_outputs()['smoothed_file'] return None def _list_outputs(self): outputs = self._outputs().get() outputs['smoothed_file'] = self.inputs.smoothed_file if not isdefined(outputs['smoothed_file']): outputs['smoothed_file'] = self._gen_fname(self.inputs.in_file, suffix='_smooth') outputs['smoothed_file'] = os.path.abspath(outputs['smoothed_file']) return outputs def _format_arg(self, name, trait_spec, value): if name == 'fwhm': sigma = float(value) / np.sqrt(8 * np.log(2)) return super(Smooth, self)._format_arg(name, trait_spec, sigma) return super(Smooth, self)._format_arg(name, trait_spec, value) class MergeInputSpec(FSLCommandInputSpec): in_files = traits.List(File(exists=True), argstr="%s", position=2, mandatory=True) dimension = traits.Enum('t', 'x', 'y', 'z', 'a', argstr="-%s", position=0, desc=("dimension along which to merge, optionally " "set tr input when dimension is t"), mandatory=True) tr = traits.Float(position=-1, argstr='%.2f', desc=('use to specify TR in seconds (default is 1.00 ' 'sec), overrides dimension and sets it to tr')) merged_file = File(argstr="%s", position=1, name_source='in_files', name_template='%s_merged', hash_files=False) class MergeOutputSpec(TraitedSpec): merged_file = File(exists=True) class Merge(FSLCommand): """Use fslmerge to concatenate images Images can be concatenated across time, x, y, or z dimensions. Across the time (t) dimension the TR is set by default to 1 sec. Note: to set the TR to a different value, specify 't' for dimension and specify the TR value in seconds for the tr input. The dimension will be automatically updated to 'tr'. Examples -------- >>> from nipype.interfaces.fsl import Merge >>> merger = Merge() >>> merger.inputs.in_files = ['functional2.nii', 'functional3.nii'] >>> merger.inputs.dimension = 't' >>> merger.inputs.output_type = 'NIFTI_GZ' >>> merger.cmdline 'fslmerge -t functional2_merged.nii.gz functional2.nii functional3.nii' >>> merger.inputs.tr = 2.25 >>> merger.cmdline 'fslmerge -tr functional2_merged.nii.gz functional2.nii functional3.nii 2.25' """ _cmd = 'fslmerge' input_spec = MergeInputSpec output_spec = MergeOutputSpec def _format_arg(self, name, spec, value): if name == 'tr': if self.inputs.dimension != 't': raise ValueError('When TR is specified, dimension must be t') return spec.argstr % value if name == 'dimension': if isdefined(self.inputs.tr): return '-tr' return spec.argstr % value return super(Merge, self)._format_arg(name, spec, value) class ExtractROIInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr="%s", position=0, desc="input file", mandatory=True) roi_file = File(argstr="%s", position=1, desc="output file", genfile=True, hash_files=False) x_min = traits.Int(argstr="%d", position=2) x_size = traits.Int(argstr="%d", position=3) y_min = traits.Int(argstr="%d", position=4) y_size = traits.Int(argstr="%d", position=5) z_min = traits.Int(argstr="%d", position=6) z_size = traits.Int(argstr="%d", position=7) t_min = traits.Int(argstr="%d", position=8) t_size = traits.Int(argstr="%d", position=9) _crop_xor = ['x_min', 'x_size', 'y_min', 'y_size', 'z_min', 'z_size', 't_min', 't_size'] crop_list = traits.List(traits.Tuple(traits.Int, traits.Int), argstr="%s", position=2, xor=_crop_xor, desc="list of two tuples specifying crop options") class ExtractROIOutputSpec(TraitedSpec): roi_file = File(exists=True) class ExtractROI(FSLCommand): """Uses FSL Fslroi command to extract region of interest (ROI) from an image. You can a) take a 3D ROI from a 3D data set (or if it is 4D, the same ROI is taken from each time point and a new 4D data set is created), b) extract just some time points from a 4D data set, or c) control time and space limits to the ROI. Note that the arguments are minimum index and size (not maximum index). So to extract voxels 10 to 12 inclusive you would specify 10 and 3 (not 10 and 12). Examples -------- >>> from nipype.interfaces.fsl import ExtractROI >>> from nipype.testing import anatfile >>> fslroi = ExtractROI(in_file=anatfile, roi_file='bar.nii', t_min=0, ... t_size=1) >>> fslroi.cmdline == 'fslroi %s bar.nii 0 1' % anatfile True """ _cmd = 'fslroi' input_spec = ExtractROIInputSpec output_spec = ExtractROIOutputSpec def _format_arg(self, name, spec, value): if name == "crop_list": return " ".join(map(str, sum(map(list, value), []))) return super(ExtractROI, self)._format_arg(name, spec, value) def _list_outputs(self): """Create a Bunch which contains all possible files generated by running the interface. Some files are always generated, others depending on which ``inputs`` options are set. Returns ------- outputs : Bunch object Bunch object containing all possible files generated by interface object. If None, file was not generated Else, contains path, filename of generated outputfile """ outputs = self._outputs().get() outputs['roi_file'] = self.inputs.roi_file if not isdefined(outputs['roi_file']): outputs['roi_file'] = self._gen_fname(self.inputs.in_file, suffix='_roi') outputs['roi_file'] = os.path.abspath(outputs['roi_file']) return outputs def _gen_filename(self, name): if name == 'roi_file': return self._list_outputs()[name] return None class SplitInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr="%s", position=0, mandatory=True, desc="input filename") out_base_name = traits.Str(argstr="%s", position=1, desc="outputs prefix") dimension = traits.Enum('t', 'x', 'y', 'z', argstr="-%s", position=2, mandatory=True, desc="dimension along which the file will be split") class SplitOutputSpec(TraitedSpec): out_files = OutputMultiPath(File(exists=True)) class Split(FSLCommand): """Uses FSL Fslsplit command to separate a volume into images in time, x, y or z dimension. """ _cmd = 'fslsplit' input_spec = SplitInputSpec output_spec = SplitOutputSpec def _list_outputs(self): """Create a Bunch which contains all possible files generated by running the interface. Some files are always generated, others depending on which ``inputs`` options are set. Returns ------- outputs : Bunch object Bunch object containing all possible files generated by interface object. If None, file was not generated Else, contains path, filename of generated outputfile """ outputs = self._outputs().get() ext = Info.output_type_to_ext(self.inputs.output_type) outbase = 'vol*' if isdefined(self.inputs.out_base_name): outbase = '%s*' % self.inputs.out_base_name outputs['out_files'] = sorted(glob(os.path.join(os.getcwd(), outbase + ext))) return outputs class ImageMathsInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr="%s", mandatory=True, position=1) in_file2 = File(exists=True, argstr="%s", position=3) out_file = File(argstr="%s", position=4, genfile=True, hash_files=False) op_string = traits.Str(argstr="%s", position=2, desc="string defining the operation, i. e. -add") suffix = traits.Str(desc="out_file suffix") out_data_type = traits.Enum('char', 'short', 'int', 'float', 'double', 'input', argstr="-odt %s", position=5, desc=("output datatype, one of (char, short, " "int, float, double, input)")) class ImageMathsOutputSpec(TraitedSpec): out_file = File(exists=True) class ImageMaths(FSLCommand): """Use FSL fslmaths command to allow mathematical manipulation of images `FSL info `_ Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import anatfile >>> maths = fsl.ImageMaths(in_file=anatfile, op_string= '-add 5', ... out_file='foo_maths.nii') >>> maths.cmdline == 'fslmaths %s -add 5 foo_maths.nii' % anatfile True """ input_spec = ImageMathsInputSpec output_spec = ImageMathsOutputSpec _cmd = 'fslmaths' def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] return None def _parse_inputs(self, skip=None): return super(ImageMaths, self)._parse_inputs(skip=['suffix']) def _list_outputs(self): suffix = '_maths' # ohinds: build suffix if isdefined(self.inputs.suffix): suffix = self.inputs.suffix outputs = self._outputs().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']): outputs['out_file'] = self._gen_fname(self.inputs.in_file, suffix=suffix) outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs class FilterRegressorInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr="-i %s", desc="input file name (4D image)", mandatory=True, position=1) out_file = File(argstr="-o %s", desc="output file name for the filtered data", genfile=True, position=2, hash_files=False) design_file = File(exists=True, argstr="-d %s", position=3, mandatory=True, desc=("name of the matrix with time courses (e.g. GLM " "design or MELODIC mixing matrix)")) filter_columns = traits.List(traits.Int, argstr="-f '%s'", xor=["filter_all"], mandatory=True, position=4, desc=("(1-based) column indices to filter out " "of the data")) filter_all = traits.Bool(mandatory=True, argstr="-f '%s'", xor=["filter_columns"], position=4, desc=("use all columns in the design file in " "denoising")) mask = File(exists=True, argstr="-m %s", desc="mask image file name") var_norm = traits.Bool(argstr="--vn", desc="perform variance-normalization on data") out_vnscales = traits.Bool(argstr="--out_vnscales", desc=("output scaling factors for variance " "normalization")) class FilterRegressorOutputSpec(TraitedSpec): out_file = File(exists=True, desc="output file name for the filtered data") class FilterRegressor(FSLCommand): """Data de-noising by regressing out part of a design matrix Uses simple OLS regression on 4D images """ input_spec = FilterRegressorInputSpec output_spec = FilterRegressorOutputSpec _cmd = 'fsl_regfilt' def _format_arg(self, name, trait_spec, value): if name == 'filter_columns': return trait_spec.argstr % ",".join(map(str, value)) elif name == "filter_all": design = np.loadtxt(self.inputs.design_file) try: n_cols = design.shape[1] except IndexError: n_cols = 1 return trait_spec.argstr % ",".join(map(str, range(1, n_cols + 1))) return super(FilterRegressor, self)._format_arg(name, trait_spec, value) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']): outputs['out_file'] = self._gen_fname( self.inputs.in_file, suffix='_regfilt') outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()[name] return None class ImageStatsInputSpec(FSLCommandInputSpec): split_4d = traits.Bool(argstr='-t', position=1, desc=('give a separate output line for each 3D ' 'volume of a 4D timeseries')) in_file = File(exists=True, argstr="%s", mandatory=True, position=2, desc='input file to generate stats of') op_string = traits.Str(argstr="%s", mandatory=True, position=3, desc=("string defining the operation, options are " "applied in order, e.g. -M -l 10 -M will " "report the non-zero mean, apply a threshold " "and then report the new nonzero mean")) mask_file = File(exists=True, argstr="", desc='mask file used for option -k %s') class ImageStatsOutputSpec(TraitedSpec): out_stat = traits.Any(desc='stats output') class ImageStats(FSLCommand): """Use FSL fslstats command to calculate stats from images `FSL info `_ Examples -------- >>> from nipype.interfaces.fsl import ImageStats >>> from nipype.testing import funcfile >>> stats = ImageStats(in_file=funcfile, op_string= '-M') >>> stats.cmdline == 'fslstats %s -M'%funcfile True """ input_spec = ImageStatsInputSpec output_spec = ImageStatsOutputSpec _cmd = 'fslstats' def _format_arg(self, name, trait_spec, value): if name == 'mask_file': return '' if name == 'op_string': if '-k %s' in self.inputs.op_string: if isdefined(self.inputs.mask_file): return self.inputs.op_string % self.inputs.mask_file else: raise ValueError( '-k %s option in op_string requires mask_file') return super(ImageStats, self)._format_arg(name, trait_spec, value) def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() # local caching for backward compatibility outfile = os.path.join(os.getcwd(), 'stat_result.json') if runtime is None: try: out_stat = load_json(outfile)['stat'] except IOError: return self.run().outputs else: out_stat = [] for line in runtime.stdout.split('\n'): if line: values = line.split() if len(values) > 1: out_stat.append([float(val) for val in values]) else: out_stat.extend([float(val) for val in values]) if len(out_stat) == 1: out_stat = out_stat[0] save_json(outfile, dict(stat=out_stat)) outputs.out_stat = out_stat return outputs class AvScaleInputSpec(FSLCommandInputSpec): mat_file = File(exists=True, argstr="%s", desc='mat file to read', position=0) class AvScaleOutputSpec(TraitedSpec): rotation_translation_matrix = traits.Any( desc='Rotation and Translation Matrix') scales = traits.Any(desc='Scales (x,y,z)') skews = traits.Any(desc='Skews') average_scaling = traits.Any(desc='Average Scaling') determinant = traits.Any(desc='Determinant') forward_half_transform = traits.Any(desc='Forward Half Transform') backward_half_transform = traits.Any(desc='Backwards Half Transform') left_right_orientation_preserved = traits.Bool( desc='True if LR orientation preserved') class AvScale(FSLCommand): """Use FSL avscale command to extract info from mat file output of FLIRT Examples -------- >>> avscale = AvScale() >>> avscale.inputs.mat_file = 'flirt.mat' >>> res = avscale.run() # doctest: +SKIP """ input_spec = AvScaleInputSpec output_spec = AvScaleOutputSpec _cmd = 'avscale' def _format_arg(self, name, trait_spec, value): return super(AvScale, self)._format_arg(name, trait_spec, value) def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() def lines_to_float(lines): out = [] for line in lines: values = line.split() out.append([float(val) for val in values]) return out out = runtime.stdout.split('\n') outputs.rotation_translation_matrix = lines_to_float(out[1:5]) outputs.scales = lines_to_float([out[6].split(" = ")[1]]) outputs.skews = lines_to_float([out[8].split(" = ")[1]]) outputs.average_scaling = lines_to_float([out[10].split(" = ")[1]]) outputs.determinant = lines_to_float([out[12].split(" = ")[1]]) if out[13].split(": ")[1] == 'preserved': outputs.left_right_orientation_preserved = True else: outputs.left_right_orientation_preserved = False outputs.forward_half_transform = lines_to_float(out[16:20]) outputs.backward_half_transform = lines_to_float(out[22:-1]) return outputs class OverlayInputSpec(FSLCommandInputSpec): transparency = traits.Bool(desc='make overlay colors semi-transparent', position=1, argstr='%s', usedefault=True, default_value=True) out_type = traits.Enum('float', 'int', position=2, usedefault=True, argstr='%s', desc='write output with float or int') use_checkerboard = traits.Bool(desc='use checkerboard mask for overlay', argstr='-c', position=3) background_image = File(exists=True, position=4, mandatory=True, argstr='%s', desc='image to use as background') _xor_inputs = ('auto_thresh_bg', 'full_bg_range', 'bg_thresh') auto_thresh_bg = traits.Bool(desc=('automatically threshold the background ' 'image'), argstr='-a', position=5, xor=_xor_inputs, mandatory=True) full_bg_range = traits.Bool(desc='use full range of background image', argstr='-A', position=5, xor=_xor_inputs, mandatory=True) bg_thresh = traits.Tuple(traits.Float, traits.Float, argstr='%.3f %.3f', position=5, desc='min and max values for background intensity', xor=_xor_inputs, mandatory=True) stat_image = File(exists=True, position=6, mandatory=True, argstr='%s', desc='statistical image to overlay in color') stat_thresh = traits.Tuple(traits.Float, traits.Float, position=7, mandatory=True, argstr='%.2f %.2f', desc=('min and max values for the statistical ' 'overlay')) show_negative_stats = traits.Bool(desc=('display negative statistics in ' 'overlay'), xor=['stat_image2'], argstr='%s', position=8) stat_image2 = File(exists=True, position=9, xor=['show_negative_stats'], argstr='%s', desc='second statistical image to overlay in color') stat_thresh2 = traits.Tuple(traits.Float, traits.Float, position=10, desc=('min and max values for second ' 'statistical overlay'), argstr='%.2f %.2f') out_file = File(desc='combined image volume', position=-1, argstr='%s', genfile=True, hash_files=False) class OverlayOutputSpec(TraitedSpec): out_file = File(exists=True, desc='combined image volume') class Overlay(FSLCommand): """ Use FSL's overlay command to combine background and statistical images into one volume Examples -------- >>> from nipype.interfaces import fsl >>> combine = fsl.Overlay() >>> combine.inputs.background_image = 'mean_func.nii.gz' >>> combine.inputs.auto_thresh_bg = True >>> combine.inputs.stat_image = 'zstat1.nii.gz' >>> combine.inputs.stat_thresh = (3.5, 10) >>> combine.inputs.show_negative_stats = True >>> res = combine.run() #doctest: +SKIP """ _cmd = 'overlay' input_spec = OverlayInputSpec output_spec = OverlayOutputSpec def _format_arg(self, name, spec, value): if name == 'transparency': if value: return '1' else: return '0' if name == 'out_type': if value == 'float': return '0' else: return '1' if name == 'show_negative_stats': return '%s %.2f %.2f' % (self.inputs.stat_image, self.inputs.stat_thresh[0] * -1, self.inputs.stat_thresh[1] * -1) return super(Overlay, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): if isdefined(self.inputs.stat_image2) and ( not isdefined(self.inputs.show_negative_stats) or not self.inputs.show_negative_stats): stem = "%s_and_%s" % (split_filename(self.inputs.stat_image)[1], split_filename(self.inputs.stat_image2)[1]) else: stem = split_filename(self.inputs.stat_image)[1] out_file = self._gen_fname(stem, suffix='_overlay') outputs['out_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['out_file'] return None class SlicerInputSpec(FSLCommandInputSpec): in_file = File(exists=True, position=1, argstr='%s', mandatory=True, desc='input volume') image_edges = File(exists=True, position=2, argstr='%s', desc=('volume to display edge overlay for (useful for ' 'checking registration')) label_slices = traits.Bool( position=3, argstr='-L', desc='display slice number', usedefault=True, default_value=True) colour_map = File(exists=True, position=4, argstr='-l %s', desc=('use different colour map from that stored in ' 'nifti header')) intensity_range = traits.Tuple(traits.Float, traits.Float, position=5, argstr='-i %.3f %.3f', desc='min and max intensities to display') threshold_edges = traits.Float(position=6, argstr='-e %.3f', desc='use threshold for edges') dither_edges = traits.Bool(position=7, argstr='-t', desc=('produce semi-transparent (dithered) ' 'edges')) nearest_neighbour = traits.Bool(position=8, argstr='-n', desc=('use nearest neighbor interpolation ' 'for output')) show_orientation = traits.Bool(position=9, argstr='%s', usedefault=True, default_value=True, desc='label left-right orientation') _xor_options = ('single_slice', 'middle_slices', 'all_axial', 'sample_axial') single_slice = traits.Enum('x', 'y', 'z', position=10, argstr='-%s', xor=_xor_options, requires=['slice_number'], desc=('output picture of single slice in the x, ' 'y, or z plane')) slice_number = traits.Int(position=11, argstr='-%d', desc='slice number to save in picture') middle_slices = traits.Bool(position=10, argstr='-a', xor=_xor_options, desc=('output picture of mid-sagittal, axial, ' 'and coronal slices')) all_axial = traits.Bool(position=10, argstr='-A', xor=_xor_options, requires=['image_width'], desc='output all axial slices into one picture') sample_axial = traits.Int(position=10, argstr='-S %d', xor=_xor_options, requires=['image_width'], desc=('output every n axial slices into one ' 'picture')) image_width = traits.Int(position=-2, argstr='%d', desc='max picture width') out_file = File(position=-1, genfile=True, argstr='%s', desc='picture to write', hash_files=False) scaling = traits.Float(position=0, argstr='-s %f', desc='image scale') class SlicerOutputSpec(TraitedSpec): out_file = File(exists=True, desc='picture to write') class Slicer(FSLCommand): """Use FSL's slicer command to output a png image from a volume. Examples -------- >>> from nipype.interfaces import fsl >>> from nipype.testing import example_data >>> slice = fsl.Slicer() >>> slice.inputs.in_file = example_data('functional.nii') >>> slice.inputs.all_axial = True >>> slice.inputs.image_width = 750 >>> res = slice.run() #doctest: +SKIP """ _cmd = 'slicer' input_spec = SlicerInputSpec output_spec = SlicerOutputSpec def _format_arg(self, name, spec, value): if name == 'show_orientation': if value: return '' else: return '-u' elif name == "label_slices": if value: return '-L' else: return '' return super(Slicer, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): out_file = self._gen_fname(self.inputs.in_file, ext='.png') outputs['out_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['out_file'] return None class PlotTimeSeriesInputSpec(FSLCommandInputSpec): in_file = traits.Either(File(exists=True), traits.List(File(exists=True)), mandatory=True, argstr="%s", position=1, desc=("file or list of files with columns of " "timecourse information")) plot_start = traits.Int(argstr="--start=%d", xor=("plot_range",), desc="first column from in-file to plot") plot_finish = traits.Int(argstr="--finish=%d", xor=("plot_range",), desc="final column from in-file to plot") plot_range = traits.Tuple(traits.Int, traits.Int, argstr="%s", xor=("plot_start", "plot_finish"), desc=("first and last columns from the in-file " "to plot")) title = traits.Str(argstr="%s", desc="plot title") legend_file = File(exists=True, argstr="--legend=%s", desc="legend file") labels = traits.Either(traits.Str, traits.List(traits.Str), argstr="%s", desc="label or list of labels") y_min = traits.Float(argstr="--ymin=%.2f", desc="minumum y value", xor=("y_range",)) y_max = traits.Float(argstr="--ymax=%.2f", desc="maximum y value", xor=("y_range",)) y_range = traits.Tuple(traits.Float, traits.Float, argstr="%s", xor=("y_min", "y_max"), desc="min and max y axis values") x_units = traits.Int(argstr="-u %d", usedefault=True, default_value=1, desc=("scaling units for x-axis (between 1 and length " "of in file)")) plot_size = traits.Tuple(traits.Int, traits.Int, argstr="%s", desc="plot image height and width") x_precision = traits.Int(argstr="--precision=%d", desc="precision of x-axis labels") sci_notation = traits.Bool(argstr="--sci", desc="switch on scientific notation") out_file = File(argstr="-o %s", genfile=True, desc="image to write", hash_files=False) class PlotTimeSeriesOutputSpec(TraitedSpec): out_file = File(exists=True, desc='image to write') class PlotTimeSeries(FSLCommand): """Use fsl_tsplot to create images of time course plots. Examples -------- >>> import nipype.interfaces.fsl as fsl >>> plotter = fsl.PlotTimeSeries() >>> plotter.inputs.in_file = 'functional.par' >>> plotter.inputs.title = 'Functional timeseries' >>> plotter.inputs.labels = ['run1', 'run2'] >>> plotter.run() #doctest: +SKIP """ _cmd = "fsl_tsplot" input_spec = PlotTimeSeriesInputSpec output_spec = PlotTimeSeriesOutputSpec def _format_arg(self, name, spec, value): if name == "in_file": if isinstance(value, list): args = ",".join(value) return "-i %s" % args else: return "-i %s" % value elif name == "labels": if isinstance(value, list): args = ",".join(value) return "-a %s" % args else: return "-a %s" % value elif name == "title": return "-t \'%s\'" % value elif name == "plot_range": return "--start=%d --finish=%d" % value elif name == "y_range": return "--ymin=%d --ymax=%d" % value elif name == "plot_size": return "-h %d -w %d" % value return super(PlotTimeSeries, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): if isinstance(self.inputs.in_file, list): infile = self.inputs.in_file[0] else: infile = self.inputs.in_file out_file = self._gen_fname(infile, ext='.png') outputs['out_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['out_file'] return None class PlotMotionParamsInputSpec(FSLCommandInputSpec): in_file = traits.Either(File(exists=True), traits.List(File(exists=True)), mandatory=True, argstr="%s", position=1, desc="file with motion parameters") in_source = traits.Enum("spm", "fsl", mandatory=True, desc=("which program generated the motion " "parameter file - fsl, spm")) plot_type = traits.Enum("rotations", "translations", "displacement", argstr="%s", mandatory=True, desc=("which motion type to plot - rotations, " "translations, displacement")) plot_size = traits.Tuple(traits.Int, traits.Int, argstr="%s", desc="plot image height and width") out_file = File(argstr="-o %s", genfile=True, desc="image to write", hash_files=False) class PlotMotionParamsOutputSpec(TraitedSpec): out_file = File(exists=True, desc='image to write') class PlotMotionParams(FSLCommand): """Use fsl_tsplot to plot the estimated motion parameters from a realignment program. Examples -------- >>> import nipype.interfaces.fsl as fsl >>> plotter = fsl.PlotMotionParams() >>> plotter.inputs.in_file = 'functional.par' >>> plotter.inputs.in_source = 'fsl' >>> plotter.inputs.plot_type = 'rotations' >>> res = plotter.run() #doctest: +SKIP Notes ----- The 'in_source' attribute determines the order of columns that are expected in the source file. FSL prints motion parameters in the order rotations, translations, while SPM prints them in the opposite order. This interface should be able to plot timecourses of motion parameters generated from other sources as long as they fall under one of these two patterns. For more flexibilty, see the :class:`fsl.PlotTimeSeries` interface. """ _cmd = 'fsl_tsplot' input_spec = PlotMotionParamsInputSpec output_spec = PlotMotionParamsOutputSpec def _format_arg(self, name, spec, value): if name == "plot_type": source = self.inputs.in_source if self.inputs.plot_type == 'displacement': title = '-t \'MCFLIRT estimated mean displacement (mm)\'' labels = '-a abs,rel' return '%s %s' % (title, labels) # Get the right starting and ending position depending on source # package sfdict = dict(fsl_rot=(1, 3), fsl_tra=( 4, 6), spm_rot=(4, 6), spm_tra=(1, 3)) # Format the title properly sfstr = "--start=%d --finish=%d" % sfdict[ "%s_%s" % (source, value[:3])] titledict = dict(fsl="MCFLIRT", spm="Realign") unitdict = dict(rot="radians", tra="mm") title = "\'%s estimated %s (%s)\'" % ( titledict[source], value, unitdict[value[:3]]) return "-t %s %s -a x,y,z" % (title, sfstr) elif name == "plot_size": return "-h %d -w %d" % value elif name == "in_file": if isinstance(value, list): args = ",".join(value) return "-i %s" % args else: return "-i %s" % value return super(PlotMotionParams, self)._format_arg(name, spec, value) def _list_outputs(self): outputs = self._outputs().get() out_file = self.inputs.out_file if not isdefined(out_file): if isinstance(self.inputs.in_file, list): infile = self.inputs.in_file[0] else: infile = self.inputs.in_file plttype = dict(rot="rot", tra="trans", dis="disp")[ self.inputs.plot_type[:3]] out_file = fname_presuffix( infile, suffix="_%s.png" % plttype, use_ext=False) outputs['out_file'] = os.path.abspath(out_file) return outputs def _gen_filename(self, name): if name == 'out_file': return self._list_outputs()['out_file'] return None class ConvertXFMInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="%s", position=-1, desc="input transformation matrix") in_file2 = File(exists=True, argstr="%s", position=-2, desc=("second input matrix (for use with fix_scale_skew or " "concat_xfm")) _options = ["invert_xfm", "concat_xfm", "fix_scale_skew"] invert_xfm = traits.Bool(argstr="-inverse", position=-3, xor=_options, desc="invert input transformation") concat_xfm = traits.Bool(argstr="-concat", position=-3, xor=_options, requires=["in_file2"], desc=("write joint transformation of two input " "matrices")) fix_scale_skew = traits.Bool(argstr="-fixscaleskew", position=-3, xor=_options, requires=["in_file2"], desc=("use secondary matrix to fix scale and " "skew")) out_file = File(genfile=True, argstr="-omat %s", position=1, desc="final transformation matrix", hash_files=False) class ConvertXFMOutputSpec(TraitedSpec): out_file = File(exists=True, desc="output transformation matrix") class ConvertXFM(FSLCommand): """Use the FSL utility convert_xfm to modify FLIRT transformation matrices. Examples -------- >>> import nipype.interfaces.fsl as fsl >>> invt = fsl.ConvertXFM() >>> invt.inputs.in_file = "flirt.mat" >>> invt.inputs.invert_xfm = True >>> invt.inputs.out_file = 'flirt_inv.mat' >>> invt.cmdline 'convert_xfm -omat flirt_inv.mat -inverse flirt.mat' """ _cmd = "convert_xfm" input_spec = ConvertXFMInputSpec output_spec = ConvertXFMOutputSpec def _list_outputs(self): outputs = self._outputs().get() outfile = self.inputs.out_file if not isdefined(outfile): _, infile1, _ = split_filename(self.inputs.in_file) if self.inputs.invert_xfm: outfile = fname_presuffix(infile1, suffix="_inv.mat", newpath=os.getcwd(), use_ext=False) else: if self.inputs.concat_xfm: _, infile2, _ = split_filename(self.inputs.in_file2) outfile = fname_presuffix("%s_%s" % (infile1, infile2), suffix=".mat", newpath=os.getcwd(), use_ext=False) else: outfile = fname_presuffix(infile1, suffix="_fix.mat", newpath=os.getcwd(), use_ext=False) outputs["out_file"] = os.path.abspath(outfile) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()["out_file"] return None class SwapDimensionsInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="%s", position="1", desc="input image") _dims = ["x", "-x", "y", "-y", "z", "-z", "RL", "LR", "AP", "PA", "IS", "SI"] new_dims = traits.Tuple(traits.Enum(_dims), traits.Enum(_dims), traits.Enum(_dims), argstr="%s %s %s", mandatory=True, desc="3-tuple of new dimension order") out_file = File(genfile=True, argstr="%s", desc="image to write", hash_files=False) class SwapDimensionsOutputSpec(TraitedSpec): out_file = File(exists=True, desc="image with new dimensions") class SwapDimensions(FSLCommand): """Use fslswapdim to alter the orientation of an image. This interface accepts a three-tuple corresponding to the new orientation. You may either provide dimension ids in the form of (-)x, (-)y, or (-z), or nifti-syle dimension codes (RL, LR, AP, PA, IS, SI). """ _cmd = "fslswapdim" input_spec = SwapDimensionsInputSpec output_spec = SwapDimensionsOutputSpec def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = self.inputs.out_file if not isdefined(self.inputs.out_file): outputs["out_file"] = self._gen_fname(self.inputs.in_file, suffix='_newdims') outputs["out_file"] = os.path.abspath(outputs["out_file"]) return outputs def _gen_filename(self, name): if name == "out_file": return self._list_outputs()["out_file"] return None class PowerSpectrumInputSpec(FSLCommandInputSpec): # We use position args here as list indices - so a negative number # will put something on the end in_file = File(exists=True, desc="input 4D file to estimate the power spectrum", argstr='%s', position=0, mandatory=True) out_file = File(desc='name of output 4D file for power spectrum', argstr='%s', position=1, genfile=True, hash_files=False) class PowerSpectrumOutputSpec(TraitedSpec): out_file = File( exists=True, desc="path/name of the output 4D power spectrum file") class PowerSpectrum(FSLCommand): """Use FSL PowerSpectrum command for power spectrum estimation. Examples -------- >>> from nipype.interfaces import fsl >>> pspec = fsl.PowerSpectrum() >>> pspec.inputs.in_file = 'functional.nii' >>> res = pspec.run() # doctest: +SKIP """ _cmd = 'fslpspec' input_spec = PowerSpectrumInputSpec output_spec = PowerSpectrumOutputSpec def _gen_outfilename(self): out_file = self.inputs.out_file if not isdefined(out_file) and isdefined(self.inputs.in_file): out_file = self._gen_fname(self.inputs.in_file, suffix='_ps') return out_file def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = os.path.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name == 'out_file': return self._gen_outfilename() return None class SigLossInputSpec(FSLCommandInputSpec): in_file = File(mandatory=True, exists=True, argstr='-i %s', desc='b0 fieldmap file') out_file = File(argstr='-s %s', desc='output signal loss estimate file', genfile=True) mask_file = File(exists=True, argstr='-m %s', desc='brain mask file') echo_time = traits.Float(argstr='--te=%f', desc='echo time in seconds') slice_direction = traits.Enum('x','y','z', argstr='-d %s', desc='slicing direction') class SigLossOuputSpec(TraitedSpec): out_file = File(exists=True, desc='signal loss estimate file') class SigLoss(FSLCommand): """Estimates signal loss from a field map (in rad/s) Examples -------- >>> sigloss = SigLoss() >>> sigloss.inputs.in_file = "phase.nii" >>> sigloss.inputs.echo_time = 0.03 >>> res = sigloss.run() # doctest: +SKIP """ input_spec = SigLossInputSpec output_spec = SigLossOuputSpec _cmd = 'sigloss' def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']) and \ isdefined(self.inputs.in_file): outputs['out_file']=self._gen_fname(self.inputs.in_file, suffix='_sigloss') return outputs def _gen_filename(self, name): if name=='out_file': return self._list_outputs()['out_file'] return None class Reorient2StdInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, argstr="%s") out_file = File(genfile=True, hash_files=False, argstr="%s") class Reorient2StdOutputSpec(TraitedSpec): out_file = File(exists=True) class Reorient2Std(FSLCommand): """fslreorient2std is a tool for reorienting the image to match the approximate orientation of the standard template images (MNI152). Examples -------- >>> reorient = Reorient2Std() >>> reorient.inputs.in_file = "functional.nii" >>> res = reorient.run() # doctest: +SKIP """ _cmd = 'fslreorient2std' input_spec = Reorient2StdInputSpec output_spec = Reorient2StdOutputSpec def _gen_filename(self, name): if name == 'out_file': return self._gen_fname(self.inputs.in_file, suffix="_reoriented") return None def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_file): outputs['out_file'] = self._gen_filename('out_file') else: outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs class InvWarpInputSpec(FSLCommandInputSpec): warp = File(exists=True, argstr='--warp=%s', mandatory=True, desc=('Name of file containing warp-coefficients/fields. This ' 'would typically be the output from the --cout switch of ' 'fnirt (but can also use fields, like the output from ' '--fout).')) reference = File(exists=True, argstr='--ref=%s', mandatory=True, desc=('Name of a file in target space. Note that the ' 'target space is now different from the target ' 'space that was used to create the --warp file. It ' 'would typically be the file that was specified ' 'with the --in argument when running fnirt.')) inverse_warp = File(argstr='--out=%s', name_source=['warp'], hash_files=False, name_template='%s_inverse', desc=('Name of output file, containing warps that are ' 'the "reverse" of those in --warp. This will be ' 'a field-file (rather than a file of spline ' 'coefficients), and it will have any affine ' 'component included as part of the ' 'displacements.')) absolute = traits.Bool(argstr='--abs', xor=['relative'], desc=('If set it indicates that the warps in --warp ' 'should be interpreted as absolute, provided ' 'that it is not created by fnirt (which ' 'always uses relative warps). If set it also ' 'indicates that the output --out should be ' 'absolute.')) relative = traits.Bool(argstr='--rel', xor=['absolute'], desc=('If set it indicates that the warps in --warp ' 'should be interpreted as relative. I.e. the ' 'values in --warp are displacements from the ' 'coordinates in the --ref space. If set it ' 'also indicates that the output --out should ' 'be relative.')) niter = traits.Int(argstr='--niter=%d', desc=('Determines how many iterations of the ' 'gradient-descent search that should be run.')) regularise = traits.Float(argstr='--regularise=%f', desc='Regularization strength (deafult=1.0).') noconstraint = traits.Bool(argstr='--noconstraint', desc='Do not apply Jacobian constraint') jacobian_min = traits.Float(argstr='--jmin=%f', desc=('Minimum acceptable Jacobian value for ' 'constraint (default 0.01)')) jacobian_max = traits.Float(argstr='--jmax=%f', desc=('Maximum acceptable Jacobian value for ' 'constraint (default 100.0)')) class InvWarpOutputSpec(TraitedSpec): inverse_warp = File(exists=True, desc=('Name of output file, containing warps that are ' 'the "reverse" of those in --warp.')) class InvWarp(FSLCommand): """ Use FSL Invwarp to invert a FNIRT warp Examples -------- >>> from nipype.interfaces.fsl import InvWarp >>> invwarp = InvWarp() >>> invwarp.inputs.warp = "struct2mni.nii" >>> invwarp.inputs.reference = "anatomical.nii" >>> invwarp.inputs.output_type = "NIFTI_GZ" >>> invwarp.cmdline 'invwarp --out=struct2mni_inverse.nii.gz --ref=anatomical.nii --warp=struct2mni.nii' >>> res = invwarp.run() # doctest: +SKIP """ input_spec = InvWarpInputSpec output_spec = InvWarpOutputSpec _cmd = 'invwarp' class ComplexInputSpec(FSLCommandInputSpec): complex_in_file = File(exists=True, argstr="%s", position=2) complex_in_file2 = File(exists=True, argstr="%s", position=3) real_in_file = File(exists=True, argstr="%s", position=2) imaginary_in_file = File(exists=True, argstr="%s", position=3) magnitude_in_file = File(exists=True, argstr="%s", position=2) phase_in_file = File(exists=True, argstr='%s', position=3) _ofs = ['complex_out_file', 'magnitude_out_file','phase_out_file', 'real_out_file','imaginary_out_file'] _conversion = ['real_polar','real_cartesian', 'complex_cartesian','complex_polar', 'complex_split','complex_merge',] complex_out_file = File(genfile=True, argstr="%s", position=-3, xor=_ofs+_conversion[:2]) magnitude_out_file = File(genfile=True, argstr="%s", position=-4, xor=_ofs[:1]+_ofs[3:]+_conversion[1:]) phase_out_file = File(genfile=True, argstr="%s", position=-3, xor=_ofs[:1]+_ofs[3:]+_conversion[1:]) real_out_file = File(genfile=True, argstr="%s", position=-4, xor=_ofs[:3]+_conversion[:1]+_conversion[2:]) imaginary_out_file = File(genfile=True, argstr="%s", position=-3, xor=_ofs[:3]+_conversion[:1]+_conversion[2:]) start_vol = traits.Int(position=-2, argstr='%d') end_vol = traits.Int(position=-1, argstr='%d') real_polar = traits.Bool( argstr = '-realpolar', xor = _conversion, position=1,) # requires=['complex_in_file','magnitude_out_file','phase_out_file']) real_cartesian = traits.Bool( argstr = '-realcartesian', xor = _conversion, position=1,) # requires=['complex_in_file','real_out_file','imaginary_out_file']) complex_cartesian = traits.Bool( argstr = '-complex', xor = _conversion, position=1,) # requires=['real_in_file','imaginary_in_file','complex_out_file']) complex_polar = traits.Bool( argstr = '-complexpolar', xor = _conversion, position=1,) # requires=['magnitude_in_file','phase_in_file', # 'magnitude_out_file','phase_out_file']) complex_split = traits.Bool( argstr = '-complexsplit', xor = _conversion, position=1,) # requires=['complex_in_file','complex_out_file']) complex_merge = traits.Bool( argstr = '-complexmerge', xor = _conversion + ['start_vol','end_vol'], position=1,) # requires=['complex_in_file','complex_in_file2','complex_out_file']) class ComplexOuputSpec(TraitedSpec): magnitude_out_file = File() phase_out_file = File() real_out_file = File() imaginary_out_file = File() complex_out_file = File() class Complex(FSLCommand): """fslcomplex is a tool for converting complex data Examples -------- >>> cplx = Complex() >>> cplx.inputs.complex_in_file = "complex.nii" >>> cplx.real_polar = True >>> res = cplx.run() # doctest: +SKIP """ _cmd = 'fslcomplex' input_spec = ComplexInputSpec output_spec = ComplexOuputSpec def _parse_inputs(self, skip=None): if skip == None: skip = [] if self.inputs.real_cartesian: skip += self.inputs._ofs[:3] elif self.inputs.real_polar: skip += self.inputs._ofs[:1]+self.inputs._ofs[3:] else: skip += self.inputs._ofs[1:] return super(Complex,self)._parse_inputs(skip) def _gen_filename(self, name): if name == 'complex_out_file': if self.inputs.complex_cartesian: in_file = self.inputs.real_in_file elif self.inputs.complex_polar: in_file = self.inputs.magnitude_in_file elif self.inputs.complex_split or self.inputs.complex_merge: in_file = self.inputs.complex_in_file else: return None return self._gen_fname(in_file, suffix="_cplx") elif name =='magnitude_out_file': return self._gen_fname(self.inputs.complex_in_file, suffix="_mag") elif name =='phase_out_file': return self._gen_fname(self.inputs.complex_in_file,suffix="_phase") elif name =='real_out_file': return self._gen_fname(self.inputs.complex_in_file, suffix="_real") elif name =='imaginary_out_file': return self._gen_fname(self.inputs.complex_in_file, suffix="_imag") return None def _get_output(self,name): output = getattr(self.inputs,name) if not isdefined(output): output = self._gen_filename(name) return os.path.abspath(output) def _list_outputs(self): outputs = self.output_spec().get() if self.inputs.complex_cartesian or self.inputs.complex_polar or \ self.inputs.complex_split or self.inputs.complex_merge: outputs['complex_out_file'] = self._get_output('complex_out_file') elif self.inputs.real_cartesian: outputs['real_out_file'] = self._get_output('real_out_file') outputs['imaginary_out_file'] = self._get_output('imaginary_out_file') elif self.inputs.real_polar: outputs['magnitude_out_file'] = self._get_output('magnitude_out_file') outputs['phase_out_file'] = self._get_output('phase_out_file') return outputs class WarpUtilsInputSpec(FSLCommandInputSpec): in_file = File(exists=True, argstr='--in=%s', mandatory=True, desc=('Name of file containing warp-coefficients/fields. This ' 'would typically be the output from the --cout switch of ' 'fnirt (but can also use fields, like the output from ' '--fout).')) reference = File(exists=True, argstr='--ref=%s', mandatory=True, desc=('Name of a file in target space. Note that the ' 'target space is now different from the target ' 'space that was used to create the --warp file. It ' 'would typically be the file that was specified ' 'with the --in argument when running fnirt.')) out_format = traits.Enum('spline', 'field', argstr='--outformat=%s', desc=('Specifies the output format. If set to field (default) ' 'the output will be a (4D) field-file. If set to spline ' 'the format will be a (4D) file of spline coefficients.')) warp_resolution = traits.Tuple(traits.Float, traits.Float, traits.Float, argstr='--warpres=%0.4f,%0.4f,%0.4f', desc=('Specifies the resolution/knot-spacing of the splines pertaining ' 'to the coefficients in the --out file. This parameter is only ' 'relevant if --outformat is set to spline. It should be noted ' 'that if the --in file has a higher resolution, the resulting ' 'coefficients will pertain to the closest (in a least-squares' ' sense) file in the space of fields with the --warpres' ' resolution. It should also be noted that the resolution ' 'will always be an integer multiple of the voxel ' 'size.')) knot_space = traits.Tuple(traits.Int, traits.Int, traits.Int, argstr='--knotspace=%d,%d,%d', desc=('Alternative (to --warpres) specification of the resolution of ' 'the output spline-field.')) out_file = File(argstr='--out=%s', position=-1, name_source = ['in_file'], output_name='out_file', desc=('Name of output file. The format of the output depends on what other ' 'parameters are set. The default format is a (4D) field-file. If the ' '--outformat is set to spline the format will be a (4D) file of spline ' 'coefficients.')) write_jacobian = traits.Bool(False, mandatory=True, usedefault=True, desc='Switch on --jac flag with automatically generated filename') out_jacobian = File(argstr='--jac=%s', desc=('Specifies that a (3D) file of Jacobian determinants corresponding ' 'to --in should be produced and written to filename.')) with_affine = traits.Bool(False, argstr='--withaff', desc=('Specifies that the affine transform (i.e. that which was ' 'specified for the --aff parameter in fnirt) should be ' 'included as displacements in the --out file. That can be ' 'useful for interfacing with software that cannot decode ' 'FSL/fnirt coefficient-files (where the affine transform is ' 'stored separately from the displacements).')) class WarpUtilsOutputSpec(TraitedSpec): out_file = File(desc=('Name of output file, containing the warp as field or coefficients.')) out_jacobian = File(desc=('Name of output file, containing the map of the determinant of ' 'the Jacobian')) class WarpUtils(FSLCommand): """Use FSL `fnirtfileutils `_ to convert field->coefficients, coefficients->field, coefficients->other_coefficients etc Examples -------- >>> from nipype.interfaces.fsl import WarpUtils >>> warputils = WarpUtils() >>> warputils.inputs.in_file = "warpfield.nii" >>> warputils.inputs.reference = "T1.nii" >>> warputils.inputs.out_format = 'spline' >>> warputils.inputs.warp_resolution = (10,10,10) >>> warputils.inputs.output_type = "NIFTI_GZ" >>> warputils.cmdline # doctest: +ELLIPSIS 'fnirtfileutils --in=warpfield.nii --outformat=spline --ref=T1.nii --warpres=10.0000,10.0000,10.0000 --out=warpfield_coeffs.nii.gz' >>> res = invwarp.run() # doctest: +SKIP """ input_spec = WarpUtilsInputSpec output_spec = WarpUtilsOutputSpec _cmd = 'fnirtfileutils' def _parse_inputs(self, skip=None): if skip is None: skip = [] suffix = 'field' if isdefined(self.inputs.out_format) and self.inputs.out_format=='spline': suffix = 'coeffs' trait_spec = self.inputs.trait('out_file') trait_spec.name_template = "%s_" + suffix if self.inputs.write_jacobian: if not isdefined(self.inputs.out_jacobian): jac_spec = self.inputs.trait('out_jacobian') jac_spec.name_source = ['in_file'] jac_spec.name_template = '%s_jac' jac_spec.output_name = 'out_jacobian' else: skip+=['out_jacobian'] skip+=['write_jacobian'] return super(WarpUtils, self)._parse_inputs(skip=skip) class ConvertWarpInputSpec(FSLCommandInputSpec): reference = File(exists=True, argstr='--ref=%s', mandatory=True, position=1, desc=('Name of a file in target space of the full transform.')) out_file = File(argstr='--out=%s', position=-1, name_source=['reference'], name_template='%s_concatwarp', output_name='out_file', desc=('Name of output file, containing warps that are the combination of all ' 'those given as arguments. The format of this will be a field-file (rather ' 'than spline coefficients) with any affine components included.')) premat = File(exists=True, argstr='--premat=%s', desc='filename for pre-transform (affine matrix)') warp1 = File(exists=True, argstr='--warp1=%s', desc=('Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a ' 'fnirt-transform from a subjects structural scan to an average of a group ' 'of subjects.')) midmat=File(exists=True, argstr="--midmat=%s", desc="Name of file containing mid-warp-affine transform") warp2 = File(exists=True, argstr='--warp2=%s', desc=('Name of file containing secondary warp-fields/coefficients (after warp1/midmat but before postmat). This could e.g. be a ' 'fnirt-transform from the average of a group of subjects to some standard ' 'space (e.g. MNI152).')) postmat = File(exists=True, argstr='--postmat=%s', desc=('Name of file containing an affine transform (applied last). It could e.g. be an affine ' 'transform that maps the MNI152-space into a better approximation to the ' 'Talairach-space (if indeed there is one).')) shift_in_file = File(exists=True, argstr='--shiftmap=%s', desc=('Name of file containing a "shiftmap", a non-linear transform with ' 'displacements only in one direction (applied first, before premat). This would typically be a ' 'fieldmap that has been pre-processed using fugue that maps a ' 'subjects functional (EPI) data onto an undistorted space (i.e. a space ' 'that corresponds to his/her true anatomy).')) shift_direction = traits.Enum('y-','y','x','x-','z','z-', argstr="--shiftdir=%s", requires=['shift_in_file'], desc=('Indicates the direction that the distortions from ' '--shiftmap goes. It depends on the direction and ' 'polarity of the phase-encoding in the EPI sequence.')) cons_jacobian = traits.Bool(False, argstr='--constrainj', desc=('Constrain the Jacobian of the warpfield to lie within specified ' 'min/max limits.')) jacobian_min = traits.Float(argstr='--jmin=%f', desc=('Minimum acceptable Jacobian value for ' 'constraint (default 0.01)')) jacobian_max = traits.Float(argstr='--jmax=%f', desc=('Maximum acceptable Jacobian value for ' 'constraint (default 100.0)')) abswarp = traits.Bool(argstr='--abs', xor=['relwarp'], desc=('If set it indicates that the warps in --warp1 and --warp2 should be ' 'interpreted as absolute. I.e. the values in --warp1/2 are the ' 'coordinates in the next space, rather than displacements. This flag ' 'is ignored if --warp1/2 was created by fnirt, which always creates ' 'relative displacements.')) relwarp = traits.Bool(argstr='--rel', xor=['abswarp'], desc=('If set it indicates that the warps in --warp1/2 should be interpreted ' 'as relative. I.e. the values in --warp1/2 are displacements from the ' 'coordinates in the next space.')) out_abswarp = traits.Bool(argstr='--absout', xor=['out_relwarp'], desc=('If set it indicates that the warps in --out should be absolute, i.e. ' 'the values in --out are displacements from the coordinates in --ref.')) out_relwarp = traits.Bool(argstr='--relout', xor=['out_abswarp'], desc=('If set it indicates that the warps in --out should be relative, i.e. ' 'the values in --out are displacements from the coordinates in --ref.')) class ConvertWarpOutputSpec(TraitedSpec): out_file = File(exists=True, desc=('Name of output file, containing the warp as field or coefficients.')) class ConvertWarp(FSLCommand): """Use FSL `convertwarp `_ for combining multiple transforms into one. Examples -------- >>> from nipype.interfaces.fsl import ConvertWarp >>> warputils = ConvertWarp() >>> warputils.inputs.warp1 = "warpfield.nii" >>> warputils.inputs.reference = "T1.nii" >>> warputils.inputs.relwarp = True >>> warputils.inputs.output_type = "NIFTI_GZ" >>> warputils.cmdline # doctest: +ELLIPSIS 'convertwarp --ref=T1.nii --rel --warp1=warpfield.nii --out=T1_concatwarp.nii.gz' >>> res = invwarp.run() # doctest: +SKIP """ input_spec = ConvertWarpInputSpec output_spec = ConvertWarpOutputSpec _cmd = 'convertwarp' class WarpPointsBaseInputSpec(CommandLineInputSpec): in_coords = File(exists=True, position=-1, argstr='%s', mandatory=True, desc=('filename of file containing coordinates')) xfm_file = File(exists=True, argstr='-xfm %s', xor=['warp_file'], desc=('filename of affine transform (e.g. source2dest.mat)')) warp_file = File(exists=True, argstr='-warp %s', xor=['xfm_file'], desc=('filename of warpfield (e.g. ' 'intermediate2dest_warp.nii.gz)')) coord_vox = traits.Bool(True, argstr='-vox', xor=['coord_mm'], desc=('all coordinates in voxels - default')) coord_mm = traits.Bool(False, argstr='-mm', xor=['coord_vox'], desc=('all coordinates in mm')) out_file = File(name_source='in_coords', name_template='%s_warped', output_name='out_file', desc='output file name') class WarpPointsInputSpec(WarpPointsBaseInputSpec): src_file = File(exists=True, argstr='-src %s', mandatory=True, desc=('filename of source image')) dest_file = File(exists=True, argstr='-dest %s', mandatory=True, desc=('filename of destination image')) class WarpPointsOutputSpec(TraitedSpec): out_file = File(exists=True, desc=('Name of output file, containing the warp as field or coefficients.')) class WarpPoints(CommandLine): """Use FSL `img2imgcoord `_ to transform point sets. Accepts plain text files and vtk files. .. Note:: transformation of TrackVis trk files is not yet implemented Examples -------- >>> from nipype.interfaces.fsl import WarpPoints >>> warppoints = WarpPoints() >>> warppoints.inputs.in_coords = 'surf.txt' >>> warppoints.inputs.src_file = 'epi.nii' >>> warppoints.inputs.dest_file = 'T1.nii' >>> warppoints.inputs.warp_file = 'warpfield.nii' >>> warppoints.inputs.coord_mm = True >>> warppoints.cmdline # doctest: +ELLIPSIS 'img2imgcoord -mm -dest T1.nii -src epi.nii -warp warpfield.nii surf.txt' >>> res = invwarp.run() # doctest: +SKIP """ input_spec = WarpPointsInputSpec output_spec = WarpPointsOutputSpec _cmd = 'img2imgcoord' _terminal_output = 'stream' def __init__(self, command=None, **inputs): self._tmpfile = None self._in_file = None self._outformat = None super(WarpPoints, self).__init__(command=command, **inputs) def _format_arg(self, name, trait_spec, value): if name == 'out_file': return '' else: return super(WarpPoints, self)._format_arg(name, trait_spec, value) def _parse_inputs(self, skip=None): import os.path as op fname, ext = op.splitext(self.inputs.in_coords) setattr(self, '_in_file', fname) setattr(self, '_outformat', ext[1:]) first_args = super(WarpPoints, self)._parse_inputs(skip=['in_coords', 'out_file']) second_args = fname + '.txt' if ext in ['.vtk', '.trk']: if self._tmpfile is None: self._tmpfile = tempfile.NamedTemporaryFile(suffix='.txt', dir=os.getcwd(), delete=False).name second_args = self._tmpfile return first_args + [ second_args ] def _vtk_to_coords(self, in_file, out_file=None): import os.path as op try: from tvtk.api import tvtk except ImportError: raise ImportError('This interface requires tvtk to run.') reader = tvtk.PolyDataReader(file_name=in_file+'.vtk') reader.update() points = reader.output.points if out_file is None: out_file, _ = op.splitext(in_file) + '.txt' np.savetxt(out_file, points) return out_file def _coords_to_vtk(self, points, out_file): import os.path as op try: from tvtk.api import tvtk except ImportError: raise ImportError('This interface requires tvtk to run.') reader = tvtk.PolyDataReader(file_name=self.inputs.in_file) reader.update() mesh = reader.output mesh.points = points writer = tvtk.PolyDataWriter(file_name=out_file, input=mesh) writer.write() def _trk_to_coords(self, in_file, out_file=None): raise NotImplementedError('trk files are not yet supported') try: from nibabel.trackvis import TrackvisFile except ImportError: raise ImportError('This interface requires nibabel to run') trkfile = TrackvisFile.from_file(in_file) streamlines = trkfile.streamlines if out_file is None: out_file, _ = op.splitext(in_file) np.savetxt(points, out_file + '.txt') return out_file + '.txt' def _coords_to_trk(self, points, out_file): raise NotImplementedError('trk files are not yet supported') def _overload_extension(self, value, name): if name == 'out_file': return '%s.%s' % (value, getattr(self, '_outformat')) def _run_interface(self, runtime): fname = getattr(self, '_in_file') outformat = getattr(self, '_outformat') tmpfile = None if outformat == 'vtk': tmpfile = self._tmpfile self._vtk_to_coords(fname, out_file=tmpfile) elif outformat == 'trk': tmpfile = self._tmpfile self._trk_to_coords(fname, out_file=tmpfile) runtime = super(WarpPoints, self)._run_interface(runtime) newpoints = np.fromstring('\n'.join(runtime.stdout.split('\n')[1:]), sep=' ') if not tmpfile is None: try: os.remove(tmpfile.name) except: pass out_file = self._filename_from_source('out_file') if outformat == 'vtk': self._coords_to_vtk(newpoints, out_file) elif outformat == 'trk': self._coords_to_trk(newpoints, out_file) else: np.savetxt(out_file, newpoints.reshape(-1,3)) return runtime class WarpPointsToStdInputSpec(WarpPointsBaseInputSpec): img_file = File(exists=True, argstr='-img %s', mandatory=True, desc=('filename of input image')) std_file = File(exists=True, argstr='-std %s', mandatory=True, desc=('filename of destination image')) premat_file = File(exists=True, argstr='-premat %s', desc=('filename of pre-warp affine transform ' '(e.g. example_func2highres.mat)')) class WarpPointsToStd(WarpPoints): """ Use FSL `img2stdcoord `_ to transform point sets to standard space coordinates. Accepts plain text files and vtk files. .. Note:: transformation of TrackVis trk files is not yet implemented Examples -------- >>> from nipype.interfaces.fsl import WarpPointsToStd >>> warppoints = WarpPointsToStd() >>> warppoints.inputs.in_coords = 'surf.txt' >>> warppoints.inputs.img_file = 'T1.nii' >>> warppoints.inputs.std_file = 'mni.nii' >>> warppoints.inputs.warp_file = 'warpfield.nii' >>> warppoints.inputs.coord_mm = True >>> warppoints.cmdline # doctest: +ELLIPSIS 'img2stdcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt' >>> res = invwarp.run() # doctest: +SKIP """ input_spec = WarpPointsToStdInputSpec output_spec = WarpPointsOutputSpec _cmd = 'img2stdcoord' class MotionOutliersInputSpec(FSLCommandInputSpec): in_file = File(exists=True, mandatory=True, desc="unfiltered 4D image", argstr="-i %s") out_file = File(argstr="-o %s", name_source='in_file', name_template='%s_outliers.txt', keep_extension=True, desc='output outlier file name', hash_files=False) mask = File(exists=True, argstr="-m %s", desc="mask image for calculating metric") metric = traits.Enum('refrms', ['refrms', 'dvars', 'refmse', 'fd', 'fdrms'], argstr="--%s", desc="metrics: refrms - RMS intensity difference to reference volume as metric [default metric],\ refmse - Mean Square Error version of refrms (used in original version of fsl_motion_outliers) \ dvars - DVARS \ fd - frame displacement \ fdrms - FD with RMS matrix calculation") threshold = traits.Float(argstr="--thresh=%g", desc="specify absolute threshold value (otherwise use box-plot cutoff = P75 + 1.5*IQR)") no_motion_correction = traits.Bool(argstr="--nomoco", desc="do not run motion correction (assumed already done)") dummy = traits.Int(argstr="--dummy=%d", desc='number of dummy scans to delete (before running anything and creating EVs)') out_metric_values = File(argstr="-s %s", name_source='in_file', name_template='%s_metrics.txt', keep_extension=True, desc='output metric values (DVARS etc.) file name', hash_files=False) out_metric_plot = File(argstr="-p %s", name_source='in_file', name_template='%s_metrics.png', keep_extension=True, desc='output metric values plot (DVARS etc.) file name', hash_files=False) class MotionOutliersOutputSpec(TraitedSpec): out_file = File(exists=True) out_metric_values = File(exists=True) out_metric_plot = File(exists=True) class MotionOutliers(FSLCommand): """ Use FSL fsl_motion_outliers`http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLMotionOutliers`_ to find outliers in timeseries (4d) data. Examples -------- >>> from nipype.interfaces.fsl import MotionOutliers >>> mo = MotionOutliers() >>> mo.inputs.in_file = "epi.nii" >>> mo.cmdline # doctest: +ELLIPSIS 'fsl_motion_outliers -i epi.nii -o epi_outliers.txt -p epi_metrics.png -s epi_metrics.txt' >>> res = mo.run() # doctest: +SKIP """ input_spec = MotionOutliersInputSpec output_spec = MotionOutliersOutputSpec _cmd = 'fsl_motion_outliers' nipype-0.11.0/nipype/interfaces/io.py000066400000000000000000002244631257611314500175250ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Set of interfaces that allow interaction with data. Currently available interfaces are: DataSource: Generic nifti to named Nifti interface DataSink: Generic named output from interfaces to data store XNATSource: preliminary interface to XNAT To come : XNATSink Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ import glob import fnmatch import string import os import os.path as op import shutil import subprocess import re import tempfile from warnings import warn import sqlite3 from nipype.utils.misc import human_order_sorted from nipype.external import six from ..utils.misc import str2bool from .. import config try: import pyxnat except: pass try: import paramiko except: pass from nipype.interfaces.base import (TraitedSpec, traits, File, Directory, BaseInterface, InputMultiPath, isdefined, OutputMultiPath, DynamicTraitedSpec, Undefined, BaseInterfaceInputSpec) from nipype.utils.filemanip import (copyfile, list_to_filename, filename_to_list) from .. import logging iflogger = logging.getLogger('interface') def copytree(src, dst, use_hardlink=False): """Recursively copy a directory tree using nipype.utils.filemanip.copyfile() This is not a thread-safe routine. However, in the case of creating new directories, it checks to see if a particular directory has already been created by another process. """ names = os.listdir(src) try: os.makedirs(dst) except OSError, why: if 'File exists' in why: pass else: raise why errors = [] for name in names: srcname = os.path.join(src, name) dstname = os.path.join(dst, name) try: if os.path.isdir(srcname): copytree(srcname, dstname, use_hardlink) else: copyfile(srcname, dstname, True, hashmethod='content', use_hardlink=use_hardlink) except (IOError, os.error), why: errors.append((srcname, dstname, str(why))) # catch the Error from the recursive copytree so that we can # continue with other files except Exception, err: errors.extend(err.args[0]) if errors: raise Exception(errors) def add_traits(base, names, trait_type=None): """ Add traits to a traited class. All traits are set to Undefined by default """ if trait_type is None: trait_type = traits.Any undefined_traits = {} for key in names: base.add_trait(key, trait_type) undefined_traits[key] = Undefined base.trait_set(trait_change_notify=False, **undefined_traits) # access each trait for key in names: _ = getattr(base, key) return base class IOBase(BaseInterface): def _run_interface(self, runtime): return runtime def _list_outputs(self): raise NotImplementedError def _outputs(self): return self._add_output_traits(super(IOBase, self)._outputs()) def _add_output_traits(self, base): return base class DataSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): base_directory = Directory( desc='Path to the base directory for storing data.') container = traits.Str( desc='Folder within base directory in which to store output') parameterization = traits.Bool(True, usedefault=True, desc='store output in parametrized structure') strip_dir = Directory(desc='path to strip out of filename') substitutions = InputMultiPath(traits.Tuple(traits.Str, traits.Str), desc=('List of 2-tuples reflecting string ' 'to substitute and string to replace ' 'it with')) regexp_substitutions = InputMultiPath(traits.Tuple(traits.Str, traits.Str), desc=('List of 2-tuples reflecting a pair ' 'of a Python regexp pattern and a ' 'replacement string. Invoked after ' 'string `substitutions`')) _outputs = traits.Dict(traits.Str, value={}, usedefault=True) remove_dest_dir = traits.Bool(False, usedefault=True, desc='remove dest directory when copying dirs') def __setattr__(self, key, value): if key not in self.copyable_trait_names(): if not isdefined(value): super(DataSinkInputSpec, self).__setattr__(key, value) self._outputs[key] = value else: if key in self._outputs: self._outputs[key] = value super(DataSinkInputSpec, self).__setattr__(key, value) class DataSinkOutputSpec(TraitedSpec): out_file = traits.Any(desc='datasink output') class DataSink(IOBase): """ Generic datasink module to store structured outputs Primarily for use within a workflow. This interface allows arbitrary creation of input attributes. The names of these attributes define the directory structure to create for storage of the files or directories. The attributes take the following form: string[[.[@]]string[[.[@]]string]] ... where parts between [] are optional. An attribute such as contrasts.@con will create a 'contrasts' directory to store the results linked to the attribute. If the @ is left out, such as in 'contrasts.con', a subdirectory 'con' will be created under 'contrasts'. the general form of the output is:: 'base_directory/container/parameterization/destloc/filename' destloc = string[[.[@]]string[[.[@]]string]] and filename comesfrom the input to the connect statement. .. warning:: This is not a thread-safe node because it can write to a common shared location. It will not complain when it overwrites a file. .. note:: If both substitutions and regexp_substitutions are used, then substitutions are applied first followed by regexp_substitutions. This interface **cannot** be used in a MapNode as the inputs are defined only when the connect statement is executed. Examples -------- >>> ds = DataSink() >>> ds.inputs.base_directory = 'results_dir' >>> ds.inputs.container = 'subject' >>> ds.inputs.structural = 'structural.nii' >>> setattr(ds.inputs, 'contrasts.@con', ['cont1.nii', 'cont2.nii']) >>> setattr(ds.inputs, 'contrasts.alt', ['cont1a.nii', 'cont2a.nii']) >>> ds.run() # doctest: +SKIP To use DataSink in a MapNode, its inputs have to be defined at the time the interface is created. >>> ds = DataSink(infields=['contasts.@con']) >>> ds.inputs.base_directory = 'results_dir' >>> ds.inputs.container = 'subject' >>> ds.inputs.structural = 'structural.nii' >>> setattr(ds.inputs, 'contrasts.@con', ['cont1.nii', 'cont2.nii']) >>> setattr(ds.inputs, 'contrasts.alt', ['cont1a.nii', 'cont2a.nii']) >>> ds.run() # doctest: +SKIP """ input_spec = DataSinkInputSpec output_spec = DataSinkOutputSpec def __init__(self, infields=None, force_run=True, **kwargs): """ Parameters ---------- infields : list of str Indicates the input fields to be dynamically created """ super(DataSink, self).__init__(**kwargs) undefined_traits = {} # used for mandatory inputs check self._infields = infields if infields: for key in infields: self.inputs.add_trait(key, traits.Any) self.inputs._outputs[key] = Undefined undefined_traits[key] = Undefined self.inputs.trait_set(trait_change_notify=False, **undefined_traits) if force_run: self._always_run = True def _get_dst(self, src): # If path is directory with trailing os.path.sep, # then remove that for a more robust behavior src = src.rstrip(os.path.sep) path, fname = os.path.split(src) if self.inputs.parameterization: dst = path if isdefined(self.inputs.strip_dir): dst = dst.replace(self.inputs.strip_dir, '') folders = [folder for folder in dst.split(os.path.sep) if folder.startswith('_')] dst = os.path.sep.join(folders) if fname: dst = os.path.join(dst, fname) else: if fname: dst = fname else: dst = path.split(os.path.sep)[-1] if dst[0] == os.path.sep: dst = dst[1:] return dst def _substitute(self, pathstr): pathstr_ = pathstr if isdefined(self.inputs.substitutions): for key, val in self.inputs.substitutions: oldpathstr = pathstr pathstr = pathstr.replace(key, val) if pathstr != oldpathstr: iflogger.debug('sub.str: %s -> %s using %r -> %r' % (oldpathstr, pathstr, key, val)) if isdefined(self.inputs.regexp_substitutions): for key, val in self.inputs.regexp_substitutions: oldpathstr = pathstr pathstr, _ = re.subn(key, val, pathstr) if pathstr != oldpathstr: iflogger.debug('sub.regexp: %s -> %s using %r -> %r' % (oldpathstr, pathstr, key, val)) if pathstr_ != pathstr: iflogger.info('sub: %s -> %s' % (pathstr_, pathstr)) return pathstr def _list_outputs(self): """Execute this module. """ outputs = self.output_spec().get() out_files = [] outdir = self.inputs.base_directory if not isdefined(outdir): outdir = '.' outdir = os.path.abspath(outdir) if isdefined(self.inputs.container): outdir = os.path.join(outdir, self.inputs.container) if not os.path.exists(outdir): try: os.makedirs(outdir) except OSError, inst: if 'File exists' in inst: pass else: raise(inst) use_hardlink = str2bool(config.get('execution', 'try_hard_link_datasink') ) for key, files in self.inputs._outputs.items(): if not isdefined(files): continue iflogger.debug("key: %s files: %s" % (key, str(files))) files = filename_to_list(files) tempoutdir = outdir for d in key.split('.'): if d[0] == '@': continue tempoutdir = os.path.join(tempoutdir, d) # flattening list if isinstance(files, list): if isinstance(files[0], list): files = [item for sublist in files for item in sublist] for src in filename_to_list(files): src = os.path.abspath(src) if os.path.isfile(src): dst = self._get_dst(src) dst = os.path.join(tempoutdir, dst) dst = self._substitute(dst) path, _ = os.path.split(dst) if not os.path.exists(path): try: os.makedirs(path) except OSError, inst: if 'File exists' in inst: pass else: raise(inst) iflogger.debug("copyfile: %s %s" % (src, dst)) copyfile(src, dst, copy=True, hashmethod='content', use_hardlink=use_hardlink) out_files.append(dst) elif os.path.isdir(src): dst = self._get_dst(os.path.join(src, '')) dst = os.path.join(tempoutdir, dst) dst = self._substitute(dst) path, _ = os.path.split(dst) if not os.path.exists(path): try: os.makedirs(path) except OSError, inst: if 'File exists' in inst: pass else: raise(inst) if os.path.exists(dst) and self.inputs.remove_dest_dir: iflogger.debug("removing: %s" % dst) shutil.rmtree(dst) iflogger.debug("copydir: %s %s" % (src, dst)) copytree(src, dst) out_files.append(dst) outputs['out_file'] = out_files return outputs class DataGrabberInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): base_directory = Directory(exists=True, desc='Path to the base directory consisting of subject data.') raise_on_empty = traits.Bool(True, usedefault=True, desc='Generate exception if list is empty for a given field') sort_filelist = traits.Bool(mandatory=True, desc='Sort the filelist that matches the template') template = traits.Str(mandatory=True, desc='Layout used to get files. relative to base directory if defined') template_args = traits.Dict(key_trait=traits.Str, value_trait=traits.List(traits.List), desc='Information to plug into template') class DataGrabber(IOBase): """ Generic datagrabber module that wraps around glob in an intelligent way for neuroimaging tasks to grab files .. attention:: Doesn't support directories currently Examples -------- >>> from nipype.interfaces.io import DataGrabber Pick all files from current directory >>> dg = DataGrabber() >>> dg.inputs.template = '*' Pick file foo/foo.nii from current directory >>> dg.inputs.template = '%s/%s.dcm' >>> dg.inputs.template_args['outfiles']=[['dicomdir','123456-1-1.dcm']] Same thing but with dynamically created fields >>> dg = DataGrabber(infields=['arg1','arg2']) >>> dg.inputs.template = '%s/%s.nii' >>> dg.inputs.arg1 = 'foo' >>> dg.inputs.arg2 = 'foo' however this latter form can be used with iterables and iterfield in a pipeline. Dynamically created, user-defined input and output fields >>> dg = DataGrabber(infields=['sid'], outfields=['func','struct','ref']) >>> dg.inputs.base_directory = '.' >>> dg.inputs.template = '%s/%s.nii' >>> dg.inputs.template_args['func'] = [['sid',['f3','f5']]] >>> dg.inputs.template_args['struct'] = [['sid',['struct']]] >>> dg.inputs.template_args['ref'] = [['sid','ref']] >>> dg.inputs.sid = 's1' Change the template only for output field struct. The rest use the general template >>> dg.inputs.field_template = dict(struct='%s/struct.nii') >>> dg.inputs.template_args['struct'] = [['sid']] """ input_spec = DataGrabberInputSpec output_spec = DynamicTraitedSpec _always_run = True def __init__(self, infields=None, outfields=None, **kwargs): """ Parameters ---------- infields : list of str Indicates the input fields to be dynamically created outfields: list of str Indicates output fields to be dynamically created See class examples for usage """ if not outfields: outfields = ['outfiles'] super(DataGrabber, self).__init__(**kwargs) undefined_traits = {} # used for mandatory inputs check self._infields = infields self._outfields = outfields if infields: for key in infields: self.inputs.add_trait(key, traits.Any) undefined_traits[key] = Undefined # add ability to insert field specific templates self.inputs.add_trait('field_template', traits.Dict(traits.Enum(outfields), desc="arguments that fit into template")) undefined_traits['field_template'] = Undefined if not isdefined(self.inputs.template_args): self.inputs.template_args = {} for key in outfields: if not key in self.inputs.template_args: if infields: self.inputs.template_args[key] = [infields] else: self.inputs.template_args[key] = [] self.inputs.trait_set(trait_change_notify=False, **undefined_traits) def _add_output_traits(self, base): """ Using traits.Any instead out OutputMultiPath till add_trait bug is fixed. """ return add_traits(base, self.inputs.template_args.keys()) def _list_outputs(self): # infields are mandatory, however I could not figure out how to set 'mandatory' flag dynamically # hence manual check if self._infields: for key in self._infields: value = getattr(self.inputs, key) if not isdefined(value): msg = "%s requires a value for input '%s' because it was listed in 'infields'" % \ (self.__class__.__name__, key) raise ValueError(msg) outputs = {} for key, args in self.inputs.template_args.items(): outputs[key] = [] template = self.inputs.template if hasattr(self.inputs, 'field_template') and \ isdefined(self.inputs.field_template) and \ key in self.inputs.field_template: template = self.inputs.field_template[key] if isdefined(self.inputs.base_directory): template = os.path.join( os.path.abspath(self.inputs.base_directory), template) else: template = os.path.abspath(template) if not args: filelist = glob.glob(template) if len(filelist) == 0: msg = 'Output key: %s Template: %s returned no files' % ( key, template) if self.inputs.raise_on_empty: raise IOError(msg) else: warn(msg) else: if self.inputs.sort_filelist: filelist = human_order_sorted(filelist) outputs[key] = list_to_filename(filelist) for argnum, arglist in enumerate(args): maxlen = 1 for arg in arglist: if isinstance(arg, six.string_types) and hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): if (maxlen > 1) and (len(arg) != maxlen): raise ValueError('incompatible number of arguments for %s' % key) if len(arg) > maxlen: maxlen = len(arg) outfiles = [] for i in range(maxlen): argtuple = [] for arg in arglist: if isinstance(arg, six.string_types) and hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): argtuple.append(arg[i]) else: argtuple.append(arg) filledtemplate = template if argtuple: try: filledtemplate = template % tuple(argtuple) except TypeError as e: raise TypeError(e.message + ": Template %s failed to convert with args %s" % (template, str(tuple(argtuple)))) outfiles = glob.glob(filledtemplate) if len(outfiles) == 0: msg = 'Output key: %s Template: %s returned no files' % (key, filledtemplate) if self.inputs.raise_on_empty: raise IOError(msg) else: warn(msg) outputs[key].append(None) else: if self.inputs.sort_filelist: outfiles = human_order_sorted(outfiles) outputs[key].append(list_to_filename(outfiles)) if any([val is None for val in outputs[key]]): outputs[key] = [] if len(outputs[key]) == 0: outputs[key] = None elif len(outputs[key]) == 1: outputs[key] = outputs[key][0] return outputs class SelectFilesInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): base_directory = Directory(exists=True, desc="Root path common to templates.") sort_filelist = traits.Bool(True, usedefault=True, desc="When matching mutliple files, return them in sorted order.") raise_on_empty = traits.Bool(True, usedefault=True, desc="Raise an exception if a template pattern matches no files.") force_lists = traits.Either(traits.Bool(), traits.List(traits.Str()), default=False, usedefault=True, desc=("Whether to return outputs as a list even when only one file " "matches the template. Either a boolean that applies to all " "output fields or a list of output field names to coerce to " " a list")) class SelectFiles(IOBase): """Flexibly collect data from disk to feed into workflows. This interface uses the {}-based string formatting syntax to plug values (possibly known only at workflow execution time) into string templates and collect files from persistant storage. These templates can also be combined with glob wildcards. The field names in the formatting template (i.e. the terms in braces) will become inputs fields on the interface, and the keys in the templates dictionary will form the output fields. Examples -------- >>> from nipype import SelectFiles, Node >>> templates={"T1": "{subject_id}/struct/T1.nii", ... "epi": "{subject_id}/func/f[0, 1].nii"} >>> dg = Node(SelectFiles(templates), "selectfiles") >>> dg.inputs.subject_id = "subj1" >>> dg.outputs.get() {'T1': , 'epi': } The same thing with dynamic grabbing of specific files: >>> templates["epi"] = "{subject_id}/func/f{run!s}.nii" >>> dg = Node(SelectFiles(templates), "selectfiles") >>> dg.inputs.subject_id = "subj1" >>> dg.inputs.run = [2, 4] """ input_spec = SelectFilesInputSpec output_spec = DynamicTraitedSpec _always_run = True def __init__(self, templates, **kwargs): """Create an instance with specific input fields. Parameters ---------- templates : dictionary Mapping from string keys to string template values. The keys become output fields on the interface. The templates should use {}-formatting syntax, where the names in curly braces become inputs fields on the interface. Format strings can also use glob wildcards to match multiple files. At runtime, the values of the interface inputs will be plugged into these templates, and the resulting strings will be used to select files. """ super(SelectFiles, self).__init__(**kwargs) # Infer the infields and outfields from the template infields = [] for name, template in templates.iteritems(): for _, field_name, _, _ in string.Formatter().parse(template): if field_name is not None and field_name not in infields: infields.append(field_name) self._infields = infields self._outfields = list(templates) self._templates = templates # Add the dynamic input fields undefined_traits = {} for field in infields: self.inputs.add_trait(field, traits.Any) undefined_traits[field] = Undefined self.inputs.trait_set(trait_change_notify=False, **undefined_traits) def _add_output_traits(self, base): """Add the dynamic output fields""" return add_traits(base, self._templates.keys()) def _list_outputs(self): """Find the files and expose them as interface outputs.""" outputs = {} info = dict([(k, v) for k, v in self.inputs.__dict__.items() if k in self._infields]) force_lists = self.inputs.force_lists if isinstance(force_lists, bool): force_lists = self._outfields if force_lists else [] bad_fields = set(force_lists) - set(self._outfields) if bad_fields: bad_fields = ", ".join(list(bad_fields)) plural = "s" if len(bad_fields) > 1 else "" verb = "were" if len(bad_fields) > 1 else "was" msg = ("The field%s '%s' %s set in 'force_lists' and not in " "'templates'.") % (plural, bad_fields, verb) raise ValueError(msg) for field, template in self._templates.iteritems(): # Build the full template path if isdefined(self.inputs.base_directory): template = op.abspath(op.join( self.inputs.base_directory, template)) else: template = op.abspath(template) # Fill in the template and glob for files filled_template = template.format(**info) filelist = glob.glob(filled_template) # Handle the case where nothing matched if not filelist: msg = "No files were found matching %s template: %s" % ( field, filled_template) if self.inputs.raise_on_empty: raise IOError(msg) else: warn(msg) # Possibly sort the list if self.inputs.sort_filelist: filelist = human_order_sorted(filelist) # Handle whether this must be a list or not if field not in force_lists: filelist = list_to_filename(filelist) outputs[field] = filelist return outputs class DataFinderInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): root_paths = traits.Either(traits.List(), traits.Str(), mandatory=True,) match_regex = traits.Str('(.+)', usedefault=True, desc=("Regular expression for matching " "paths.")) ignore_regexes = traits.List(desc=("List of regular expressions, " "if any match the path it will be " "ignored.") ) max_depth = traits.Int(desc="The maximum depth to search beneath " "the root_paths") min_depth = traits.Int(desc="The minimum depth to search beneath " "the root paths") unpack_single = traits.Bool(False, usedefault=True, desc="Unpack single results from list") class DataFinder(IOBase): """Search for paths that match a given regular expression. Allows a less proscriptive approach to gathering input files compared to DataGrabber. Will recursively search any subdirectories by default. This can be limited with the min/max depth options. Matched paths are available in the output 'out_paths'. Any named groups of captured text from the regular expression are also available as ouputs of the same name. Examples -------- >>> from nipype.interfaces.io import DataFinder >>> df = DataFinder() >>> df.inputs.root_paths = '.' >>> df.inputs.match_regex = '.+/(?P.+(qT1|ep2d_fid_T1).+)/(?P.+)\.nii.gz' >>> result = df.run() # doctest: +SKIP >>> print result.outputs.out_paths # doctest: +SKIP ['./027-ep2d_fid_T1_Gd4/acquisition.nii.gz', './018-ep2d_fid_T1_Gd2/acquisition.nii.gz', './016-ep2d_fid_T1_Gd1/acquisition.nii.gz', './013-ep2d_fid_T1_pre/acquisition.nii.gz'] >>> print result.outputs.series_dir # doctest: +SKIP ['027-ep2d_fid_T1_Gd4', '018-ep2d_fid_T1_Gd2', '016-ep2d_fid_T1_Gd1', '013-ep2d_fid_T1_pre'] >>> print result.outputs.basename # doctest: +SKIP ['acquisition', 'acquisition' 'acquisition', 'acquisition'] """ input_spec = DataFinderInputSpec output_spec = DynamicTraitedSpec _always_run = True def _match_path(self, target_path): #Check if we should ignore the path for ignore_re in self.ignore_regexes: if ignore_re.search(target_path): return #Check if we can match the path match = self.match_regex.search(target_path) if not match is None: match_dict = match.groupdict() if self.result is None: self.result = {'out_paths': []} for key in match_dict.keys(): self.result[key] = [] self.result['out_paths'].append(target_path) for key, val in match_dict.iteritems(): self.result[key].append(val) def _run_interface(self, runtime): #Prepare some of the inputs if isinstance(self.inputs.root_paths, six.string_types): self.inputs.root_paths = [self.inputs.root_paths] self.match_regex = re.compile(self.inputs.match_regex) if self.inputs.max_depth is Undefined: max_depth = None else: max_depth = self.inputs.max_depth if self.inputs.min_depth is Undefined: min_depth = 0 else: min_depth = self.inputs.min_depth if self.inputs.ignore_regexes is Undefined: self.ignore_regexes = [] else: self.ignore_regexes = \ [re.compile(regex) for regex in self.inputs.ignore_regexes] self.result = None for root_path in self.inputs.root_paths: #Handle tilda/env variables and remove extra seperators root_path = os.path.normpath(os.path.expandvars(os.path.expanduser(root_path))) #Check if the root_path is a file if os.path.isfile(root_path): if min_depth == 0: self._match_path(root_path) continue #Walk through directory structure checking paths for curr_dir, sub_dirs, files in os.walk(root_path): #Determine the current depth from the root_path curr_depth = (curr_dir.count(os.sep) - root_path.count(os.sep)) #If the max path depth has been reached, clear sub_dirs #and files if max_depth is not None and curr_depth >= max_depth: sub_dirs[:] = [] files = [] #Test the path for the curr_dir and all files if curr_depth >= min_depth: self._match_path(curr_dir) if curr_depth >= (min_depth - 1): for infile in files: full_path = os.path.join(curr_dir, infile) self._match_path(full_path) if (self.inputs.unpack_single and len(self.result['out_paths']) == 1 ): for key, vals in self.result.iteritems(): self.result[key] = vals[0] else: #sort all keys acording to out_paths for key in self.result.keys(): if key == "out_paths": continue sort_tuples = human_order_sorted(zip(self.result["out_paths"], self.result[key])) self.result[key] = [x for (_, x) in sort_tuples] self.result["out_paths"] = human_order_sorted(self.result["out_paths"]) if not self.result: raise RuntimeError("Regular expression did not match any files!") return runtime def _list_outputs(self): outputs = self._outputs().get() outputs.update(self.result) return outputs class FSSourceInputSpec(BaseInterfaceInputSpec): subjects_dir = Directory(mandatory=True, desc='Freesurfer subjects directory.') subject_id = traits.Str(mandatory=True, desc='Subject name for whom to retrieve data') hemi = traits.Enum('both', 'lh', 'rh', usedefault=True, desc='Selects hemisphere specific outputs') class FSSourceOutputSpec(TraitedSpec): T1 = File( exists=True, desc='Intensity normalized whole-head volume', loc='mri') aseg = File( exists=True, desc='Volumetric map of regions from automatic segmentation', loc='mri') brain = File( exists=True, desc='Intensity normalized brain-only volume', loc='mri') brainmask = File( exists=True, desc='Skull-stripped (brain-only) volume', loc='mri') filled = File(exists=True, desc='Subcortical mass volume', loc='mri') norm = File( exists=True, desc='Normalized skull-stripped volume', loc='mri') nu = File(exists=True, desc='Non-uniformity corrected whole-head volume', loc='mri') orig = File(exists=True, desc='Base image conformed to Freesurfer space', loc='mri') rawavg = File(exists=True, desc='Volume formed by averaging input images', loc='mri') ribbon = OutputMultiPath( File(exists=True), desc='Volumetric maps of cortical ribbons', loc='mri', altkey='*ribbon') wm = File(exists=True, desc='Segmented white-matter volume', loc='mri') wmparc = File( exists=True, desc='Aparc parcellation projected into subcortical white matter', loc='mri') curv = OutputMultiPath(File(exists=True), desc='Maps of surface curvature', loc='surf') inflated = OutputMultiPath( File(exists=True), desc='Inflated surface meshes', loc='surf') pial = OutputMultiPath( File(exists=True), desc='Gray matter/pia mater surface meshes', loc='surf') smoothwm = OutputMultiPath(File(exists=True), loc='surf', desc='Smoothed original surface meshes') sphere = OutputMultiPath( File(exists=True), desc='Spherical surface meshes', loc='surf') sulc = OutputMultiPath( File(exists=True), desc='Surface maps of sulcal depth', loc='surf') thickness = OutputMultiPath(File(exists=True), loc='surf', desc='Surface maps of cortical thickness') volume = OutputMultiPath( File(exists=True), desc='Surface maps of cortical volume', loc='surf') white = OutputMultiPath( File(exists=True), desc='White/gray matter surface meshes', loc='surf') label = OutputMultiPath( File(exists=True), desc='Volume and surface label files', loc='label', altkey='*label') annot = OutputMultiPath(File(exists=True), desc='Surface annotation files', loc='label', altkey='*annot') aparc_aseg = OutputMultiPath( File(exists=True), loc='mri', altkey='aparc*aseg', desc='Aparc parcellation projected into aseg volume') sphere_reg = OutputMultiPath( File(exists=True), loc='surf', altkey='sphere.reg', desc='Spherical registration file') aseg_stats = OutputMultiPath(File(exists=True), loc='stats', altkey='aseg', desc='Automated segmentation statistics file') wmparc_stats = OutputMultiPath( File(exists=True), loc='stats', altkey='wmparc', desc='White matter parcellation statistics file') aparc_stats = OutputMultiPath( File(exists=True), loc='stats', altkey='aparc', desc='Aparc parcellation statistics files') BA_stats = OutputMultiPath(File(exists=True), loc='stats', altkey='BA', desc='Brodmann Area statistics files') aparc_a2009s_stats = OutputMultiPath( File(exists=True), loc='stats', altkey='aparc.a2009s', desc='Aparc a2009s parcellation statistics files') curv_stats = OutputMultiPath(File(exists=True), loc='stats', altkey='curv', desc='Curvature statistics files') entorhinal_exvivo_stats = OutputMultiPath( File(exists=True), loc='stats', altkey='entorhinal_exvivo', desc='Entorhinal exvivo statistics files') class FreeSurferSource(IOBase): """Generates freesurfer subject info from their directories Examples -------- >>> from nipype.interfaces.io import FreeSurferSource >>> fs = FreeSurferSource() >>> #fs.inputs.subjects_dir = '.' >>> fs.inputs.subject_id = 'PWS04' >>> res = fs.run() # doctest: +SKIP >>> fs.inputs.hemi = 'lh' >>> res = fs.run() # doctest: +SKIP """ input_spec = FSSourceInputSpec output_spec = FSSourceOutputSpec _always_run = True _additional_metadata = ['loc', 'altkey'] def _get_files(self, path, key, dirval, altkey=None): globsuffix = '' if dirval == 'mri': globsuffix = '.mgz' elif dirval == 'stats': globsuffix = '.stats' globprefix = '' if key == 'ribbon' or dirval in ['surf', 'label', 'stats']: if self.inputs.hemi != 'both': globprefix = self.inputs.hemi + '.' else: globprefix = '*' if key == 'aseg_stats' or key == 'wmparc_stats': globprefix = '' keydir = os.path.join(path, dirval) if altkey: key = altkey globpattern = os.path.join( keydir, ''.join((globprefix, key, globsuffix))) return [os.path.abspath(f) for f in glob.glob(globpattern)] def _list_outputs(self): subjects_dir = self.inputs.subjects_dir subject_path = os.path.join(subjects_dir, self.inputs.subject_id) output_traits = self._outputs() outputs = output_traits.get() for k in outputs.keys(): val = self._get_files(subject_path, k, output_traits.traits()[k].loc, output_traits.traits()[k].altkey) if val: outputs[k] = list_to_filename(val) return outputs class XNATSourceInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): query_template = traits.Str( mandatory=True, desc=('Layout used to get files. Relative to base ' 'directory if defined') ) query_template_args = traits.Dict( traits.Str, traits.List(traits.List), value=dict(outfiles=[]), usedefault=True, desc='Information to plug into template' ) server = traits.Str( mandatory=True, requires=['user', 'pwd'], xor=['config'] ) user = traits.Str() pwd = traits.Password() config = File(mandatory=True, xor=['server']) cache_dir = Directory(desc='Cache directory') class XNATSource(IOBase): """ Generic XNATSource module that wraps around the pyxnat module in an intelligent way for neuroimaging tasks to grab files and data from an XNAT server. Examples -------- >>> from nipype.interfaces.io import XNATSource Pick all files from current directory >>> dg = XNATSource() >>> dg.inputs.template = '*' >>> dg = XNATSource(infields=['project','subject','experiment','assessor','inout']) >>> dg.inputs.query_template = '/projects/%s/subjects/%s/experiments/%s' \ '/assessors/%s/%s_resources/files' >>> dg.inputs.project = 'IMAGEN' >>> dg.inputs.subject = 'IMAGEN_000000001274' >>> dg.inputs.experiment = '*SessionA*' >>> dg.inputs.assessor = '*ADNI_MPRAGE_nii' >>> dg.inputs.inout = 'out' >>> dg = XNATSource(infields=['sid'],outfields=['struct','func']) >>> dg.inputs.query_template = '/projects/IMAGEN/subjects/%s/experiments/*SessionA*' \ '/assessors/*%s_nii/out_resources/files' >>> dg.inputs.query_template_args['struct'] = [['sid','ADNI_MPRAGE']] >>> dg.inputs.query_template_args['func'] = [['sid','EPI_faces']] >>> dg.inputs.sid = 'IMAGEN_000000001274' """ input_spec = XNATSourceInputSpec output_spec = DynamicTraitedSpec def __init__(self, infields=None, outfields=None, **kwargs): """ Parameters ---------- infields : list of str Indicates the input fields to be dynamically created outfields: list of str Indicates output fields to be dynamically created See class examples for usage """ super(XNATSource, self).__init__(**kwargs) undefined_traits = {} # used for mandatory inputs check self._infields = infields if infields: for key in infields: self.inputs.add_trait(key, traits.Any) undefined_traits[key] = Undefined self.inputs.query_template_args['outfiles'] = [infields] if outfields: # add ability to insert field specific templates self.inputs.add_trait( 'field_template', traits.Dict(traits.Enum(outfields), desc="arguments that fit into query_template") ) undefined_traits['field_template'] = Undefined #self.inputs.remove_trait('query_template_args') outdict = {} for key in outfields: outdict[key] = [] self.inputs.query_template_args = outdict self.inputs.trait_set(trait_change_notify=False, **undefined_traits) def _add_output_traits(self, base): """ Using traits.Any instead out OutputMultiPath till add_trait bug is fixed. """ return add_traits(base, self.inputs.query_template_args.keys()) def _list_outputs(self): # infields are mandatory, however I could not figure out # how to set 'mandatory' flag dynamically, hence manual check cache_dir = self.inputs.cache_dir or tempfile.gettempdir() if self.inputs.config: xnat = pyxnat.Interface(config=self.inputs.config) else: xnat = pyxnat.Interface(self.inputs.server, self.inputs.user, self.inputs.pwd, cache_dir ) if self._infields: for key in self._infields: value = getattr(self.inputs, key) if not isdefined(value): msg = ("%s requires a value for input '%s' " "because it was listed in 'infields'" % (self.__class__.__name__, key) ) raise ValueError(msg) outputs = {} for key, args in self.inputs.query_template_args.items(): outputs[key] = [] template = self.inputs.query_template if hasattr(self.inputs, 'field_template') and \ isdefined(self.inputs.field_template) and \ key in self.inputs.field_template: template = self.inputs.field_template[key] if not args: file_objects = xnat.select(template).get('obj') if file_objects == []: raise IOError('Template %s returned no files' % template ) outputs[key] = list_to_filename( [str(file_object.get()) for file_object in file_objects if file_object.exists() ]) for argnum, arglist in enumerate(args): maxlen = 1 for arg in arglist: if isinstance(arg, six.string_types) and hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): if (maxlen > 1) and (len(arg) != maxlen): raise ValueError('incompatible number ' 'of arguments for %s' % key ) if len(arg) > maxlen: maxlen = len(arg) outfiles = [] for i in range(maxlen): argtuple = [] for arg in arglist: if isinstance(arg, six.string_types) and \ hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): argtuple.append(arg[i]) else: argtuple.append(arg) if argtuple: target = template % tuple(argtuple) file_objects = xnat.select(target).get('obj') if file_objects == []: raise IOError('Template %s ' 'returned no files' % target ) outfiles = list_to_filename( [str(file_object.get()) for file_object in file_objects if file_object.exists() ] ) else: file_objects = xnat.select(template).get('obj') if file_objects == []: raise IOError('Template %s ' 'returned no files' % template ) outfiles = list_to_filename( [str(file_object.get()) for file_object in file_objects if file_object.exists() ] ) outputs[key].insert(i, outfiles) if len(outputs[key]) == 0: outputs[key] = None elif len(outputs[key]) == 1: outputs[key] = outputs[key][0] return outputs class XNATSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): _outputs = traits.Dict(traits.Str, value={}, usedefault=True) server = traits.Str(mandatory=True, requires=['user', 'pwd'], xor=['config'] ) user = traits.Str() pwd = traits.Password() config = File(mandatory=True, xor=['server']) cache_dir = Directory(desc='') project_id = traits.Str( desc='Project in which to store the outputs', mandatory=True) subject_id = traits.Str( desc='Set to subject id', mandatory=True) experiment_id = traits.Str( desc='Set to workflow name', mandatory=True) assessor_id = traits.Str( desc=('Option to customize ouputs representation in XNAT - ' 'assessor level will be used with specified id'), xor=['reconstruction_id'] ) reconstruction_id = traits.Str( desc=('Option to customize ouputs representation in XNAT - ' 'reconstruction level will be used with specified id'), xor=['assessor_id'] ) share = traits.Bool(False, desc=('Option to share the subjects from the original project' 'instead of creating new ones when possible - the created ' 'experiments are then shared back to the original project' ), usedefault=True) def __setattr__(self, key, value): if key not in self.copyable_trait_names(): self._outputs[key] = value else: super(XNATSinkInputSpec, self).__setattr__(key, value) class XNATSink(IOBase): """ Generic datasink module that takes a directory containing a list of nifti files and provides a set of structured output fields. """ input_spec = XNATSinkInputSpec def _list_outputs(self): """Execute this module. """ # setup XNAT connection cache_dir = self.inputs.cache_dir or tempfile.gettempdir() if self.inputs.config: xnat = pyxnat.Interface(config=self.inputs.config) else: xnat = pyxnat.Interface(self.inputs.server, self.inputs.user, self.inputs.pwd, cache_dir ) # if possible share the subject from the original project if self.inputs.share: subject_id = self.inputs.subject_id result = xnat.select( 'xnat:subjectData', ['xnat:subjectData/PROJECT', 'xnat:subjectData/SUBJECT_ID'] ).where('xnat:subjectData/SUBJECT_ID = %s AND' % subject_id) # subject containing raw data exists on the server if (result.data and isinstance(result.data[0], dict)): result = result.data[0] shared = xnat.select('/project/%s/subject/%s' % (self.inputs.project_id, self.inputs.subject_id ) ) if not shared.exists(): # subject not in share project share_project = xnat.select( '/project/%s' % self.inputs.project_id) if not share_project.exists(): # check project exists share_project.insert() subject = xnat.select('/project/%(project)s' '/subject/%(subject_id)s' % result ) subject.share(str(self.inputs.project_id)) # setup XNAT resource uri_template_args = dict( project_id=quote_id(self.inputs.project_id), subject_id=self.inputs.subject_id, experiment_id=quote_id(self.inputs.experiment_id)) if self.inputs.share: uri_template_args['original_project'] = result['project'] if self.inputs.assessor_id: uri_template_args['assessor_id'] = quote_id(self.inputs.assessor_id) elif self.inputs.reconstruction_id: uri_template_args['reconstruction_id'] = quote_id(self.inputs.reconstruction_id) # gather outputs and upload them for key, files in self.inputs._outputs.items(): for name in filename_to_list(files): if isinstance(name, list): for i, file_name in enumerate(name): push_file(self, xnat, file_name, '%s_' % i + key, uri_template_args ) else: push_file(self, xnat, name, key, uri_template_args) def quote_id(string): return str(string).replace('_', '---') def unquote_id(string): return str(string).replace('---', '_') def push_file(self, xnat, file_name, out_key, uri_template_args): # grab info from output file names val_list = [unquote_id(val) for part in os.path.split(file_name)[0].split(os.sep) for val in part.split('_')[1:] if part.startswith('_') and len(part.split('_')) % 2 ] keymap = dict(zip(val_list[1::2], val_list[2::2])) _label = [] for key, val in sorted(keymap.items()): if str(self.inputs.subject_id) not in val: _label.extend([key, val]) # select and define container level uri_template_args['container_type'] = None for container in ['assessor_id', 'reconstruction_id']: if getattr(self.inputs, container): uri_template_args['container_type'] = container.split('_id')[0] uri_template_args['container_id'] = uri_template_args[container] if uri_template_args['container_type'] is None: uri_template_args['container_type'] = 'reconstruction' uri_template_args['container_id'] = unquote_id( uri_template_args['experiment_id'] ) if _label: uri_template_args['container_id'] += ( '_results_%s' % '_'.join(_label) ) else: uri_template_args['container_id'] += '_results' # define resource level uri_template_args['resource_label'] = ( '%s_%s' % (uri_template_args['container_id'], out_key.split('.')[0] ) ) # define file level uri_template_args['file_name'] = os.path.split( os.path.abspath(unquote_id(file_name)))[1] uri_template = ( '/project/%(project_id)s/subject/%(subject_id)s' '/experiment/%(experiment_id)s/%(container_type)s/%(container_id)s' '/out/resource/%(resource_label)s/file/%(file_name)s' ) # unquote values before uploading for key in uri_template_args.keys(): uri_template_args[key] = unquote_id(uri_template_args[key]) # upload file remote_file = xnat.select(uri_template % uri_template_args) remote_file.insert(file_name, experiments='xnat:imageSessionData', use_label=True ) # shares the experiment back to the original project if relevant if 'original_project' in uri_template_args: experiment_template = ( '/project/%(original_project)s' '/subject/%(subject_id)s/experiment/%(experiment_id)s' ) xnat.select(experiment_template % uri_template_args ).share(uri_template_args['original_project']) def capture_provenance(): pass def push_provenance(): pass class SQLiteSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): database_file = File(exists=True, mandatory=True) table_name = traits.Str(mandatory=True) class SQLiteSink(IOBase): """ Very simple frontend for storing values into SQLite database. .. warning:: This is not a thread-safe node because it can write to a common shared location. It will not complain when it overwrites a file. Examples -------- >>> sql = SQLiteSink(input_names=['subject_id', 'some_measurement']) >>> sql.inputs.database_file = 'my_database.db' >>> sql.inputs.table_name = 'experiment_results' >>> sql.inputs.subject_id = 's1' >>> sql.inputs.some_measurement = 11.4 >>> sql.run() # doctest: +SKIP """ input_spec = SQLiteSinkInputSpec def __init__(self, input_names, **inputs): super(SQLiteSink, self).__init__(**inputs) self._input_names = filename_to_list(input_names) add_traits(self.inputs, [name for name in self._input_names]) def _list_outputs(self): """Execute this module. """ conn = sqlite3.connect(self.inputs.database_file, check_same_thread=False) c = conn.cursor() c.execute("INSERT OR REPLACE INTO %s (" % self.inputs.table_name + ",".join(self._input_names) + ") VALUES (" + ",".join(["?"] * len(self._input_names)) + ")", [getattr(self.inputs, name) for name in self._input_names]) conn.commit() c.close() return None class MySQLSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): host = traits.Str('localhost', mandatory=True, requires=['username', 'password'], xor=['config'], usedefault=True) config = File(mandatory=True, xor=['host'], desc="MySQL Options File (same format as my.cnf)") database_name = traits.Str( mandatory=True, desc='Otherwise known as the schema name') table_name = traits.Str(mandatory=True) username = traits.Str() password = traits.Str() class MySQLSink(IOBase): """ Very simple frontend for storing values into MySQL database. Examples -------- >>> sql = MySQLSink(input_names=['subject_id', 'some_measurement']) >>> sql.inputs.database_name = 'my_database' >>> sql.inputs.table_name = 'experiment_results' >>> sql.inputs.username = 'root' >>> sql.inputs.password = 'secret' >>> sql.inputs.subject_id = 's1' >>> sql.inputs.some_measurement = 11.4 >>> sql.run() # doctest: +SKIP """ input_spec = MySQLSinkInputSpec def __init__(self, input_names, **inputs): super(MySQLSink, self).__init__(**inputs) self._input_names = filename_to_list(input_names) add_traits(self.inputs, [name for name in self._input_names]) def _list_outputs(self): """Execute this module. """ import MySQLdb if isdefined(self.inputs.config): conn = MySQLdb.connect(db=self.inputs.database_name, read_default_file=self.inputs.config) else: conn = MySQLdb.connect(host=self.inputs.host, user=self.inputs.username, passwd=self.inputs.password, db=self.inputs.database_name) c = conn.cursor() c.execute("REPLACE INTO %s (" % self.inputs.table_name + ",".join(self._input_names) + ") VALUES (" + ",".join(["%s"] * len(self._input_names)) + ")", [getattr(self.inputs, name) for name in self._input_names]) conn.commit() c.close() return None class SSHDataGrabberInputSpec(DataGrabberInputSpec): hostname = traits.Str(mandatory=True, desc='Server hostname.') username = traits.Str(desc='Server username.') password = traits.Password(desc='Server password.') download_files = traits.Bool(True, usedefault=True, desc='If false it will return the file names without downloading them') base_directory = traits.Str(mandatory=True, desc='Path to the base directory consisting of subject data.') template_expression = traits.Enum(['fnmatch', 'regexp'], usedefault=True, desc='Use either fnmatch or regexp to express templates') ssh_log_to_file = traits.Str('', usedefault=True, desc='If set SSH commands will be logged to the given file') class SSHDataGrabber(DataGrabber): """ Extension of DataGrabber module that downloads the file list and optionally the files from a SSH server. The SSH operation must not need user and password so an SSH agent must be active in where this module is being run. .. attention:: Doesn't support directories currently Examples -------- >>> from nipype.interfaces.io import SSHDataGrabber >>> dg = SSHDataGrabber() >>> dg.inputs.hostname = 'test.rebex.net' >>> dg.inputs.user = 'demo' >>> dg.inputs.password = 'password' >>> dg.inputs.base_directory = 'pub/example' Pick all files from the base directory >>> dg.inputs.template = '*' Pick all files starting with "s" and a number from current directory >>> dg.inputs.template_expression = 'regexp' >>> dg.inputs.template = 'pop[0-9].*' Same thing but with dynamically created fields >>> dg = SSHDataGrabber(infields=['arg1','arg2']) >>> dg.inputs.hostname = 'test.rebex.net' >>> dg.inputs.user = 'demo' >>> dg.inputs.password = 'password' >>> dg.inputs.base_directory = 'pub' >>> dg.inputs.template = '%s/%s.txt' >>> dg.inputs.arg1 = 'example' >>> dg.inputs.arg2 = 'foo' however this latter form can be used with iterables and iterfield in a pipeline. Dynamically created, user-defined input and output fields >>> dg = SSHDataGrabber(infields=['sid'], outfields=['func','struct','ref']) >>> dg.inputs.hostname = 'myhost.com' >>> dg.inputs.base_directory = '/main_folder/my_remote_dir' >>> dg.inputs.template_args['func'] = [['sid',['f3','f5']]] >>> dg.inputs.template_args['struct'] = [['sid',['struct']]] >>> dg.inputs.template_args['ref'] = [['sid','ref']] >>> dg.inputs.sid = 's1' Change the template only for output field struct. The rest use the general template >>> dg.inputs.field_template = dict(struct='%s/struct.nii') >>> dg.inputs.template_args['struct'] = [['sid']] """ input_spec = SSHDataGrabberInputSpec output_spec = DynamicTraitedSpec _always_run = False def __init__(self, infields=None, outfields=None, **kwargs): """ Parameters ---------- infields : list of str Indicates the input fields to be dynamically created outfields: list of str Indicates output fields to be dynamically created See class examples for usage """ try: paramiko except NameError: warn( "The library parmiko needs to be installed" " for this module to run." ) if not outfields: outfields = ['outfiles'] kwargs = kwargs.copy() kwargs['infields'] = infields kwargs['outfields'] = outfields super(SSHDataGrabber, self).__init__(**kwargs) if ( None in (self.inputs.username, self.inputs.password) ): raise ValueError( "either both username and password " "are provided or none of them" ) if ( self.inputs.template_expression == 'regexp' and self.inputs.template[-1] != '$' ): self.inputs.template += '$' def _list_outputs(self): try: paramiko except NameError: raise ImportError( "The library parmiko needs to be installed" " for this module to run." ) if len(self.inputs.ssh_log_to_file) > 0: paramiko.util.log_to_file(self.inputs.ssh_log_to_file) # infields are mandatory, however I could not figure out how to set 'mandatory' flag dynamically # hence manual check if self._infields: for key in self._infields: value = getattr(self.inputs, key) if not isdefined(value): msg = "%s requires a value for input '%s' because it was listed in 'infields'" % \ (self.__class__.__name__, key) raise ValueError(msg) outputs = {} for key, args in self.inputs.template_args.items(): outputs[key] = [] template = self.inputs.template if hasattr(self.inputs, 'field_template') and \ isdefined(self.inputs.field_template) and \ key in self.inputs.field_template: template = self.inputs.field_template[key] if not args: client = self._get_ssh_client() sftp = client.open_sftp() sftp.chdir(self.inputs.base_directory) filelist = sftp.listdir() if self.inputs.template_expression == 'fnmatch': filelist = fnmatch.filter(filelist, template) elif self.inputs.template_expression == 'regexp': regexp = re.compile(template) filelist = filter(regexp.match, filelist) else: raise ValueError('template_expression value invalid') if len(filelist) == 0: msg = 'Output key: %s Template: %s returned no files' % ( key, template) if self.inputs.raise_on_empty: raise IOError(msg) else: warn(msg) else: if self.inputs.sort_filelist: filelist = human_order_sorted(filelist) outputs[key] = list_to_filename(filelist) if self.inputs.download_files: for f in filelist: sftp.get(f, f) for argnum, arglist in enumerate(args): maxlen = 1 for arg in arglist: if isinstance(arg, six.string_types) and hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): if (maxlen > 1) and (len(arg) != maxlen): raise ValueError('incompatible number of arguments for %s' % key) if len(arg) > maxlen: maxlen = len(arg) outfiles = [] for i in range(maxlen): argtuple = [] for arg in arglist: if isinstance(arg, six.string_types) and hasattr(self.inputs, arg): arg = getattr(self.inputs, arg) if isinstance(arg, list): argtuple.append(arg[i]) else: argtuple.append(arg) filledtemplate = template if argtuple: try: filledtemplate = template % tuple(argtuple) except TypeError as e: raise TypeError(e.message + ": Template %s failed to convert with args %s" % (template, str(tuple(argtuple)))) client = self._get_ssh_client() sftp = client.open_sftp() sftp.chdir(self.inputs.base_directory) filledtemplate_dir = os.path.dirname(filledtemplate) filledtemplate_base = os.path.basename(filledtemplate) filelist = sftp.listdir(filledtemplate_dir) if self.inputs.template_expression == 'fnmatch': outfiles = fnmatch.filter(filelist, filledtemplate_base) elif self.inputs.template_expression == 'regexp': regexp = re.compile(filledtemplate_base) outfiles = filter(regexp.match, filelist) else: raise ValueError('template_expression value invalid') if len(outfiles) == 0: msg = 'Output key: %s Template: %s returned no files' % (key, filledtemplate) if self.inputs.raise_on_empty: raise IOError(msg) else: warn(msg) outputs[key].append(None) else: if self.inputs.sort_filelist: outfiles = human_order_sorted(outfiles) outputs[key].append(list_to_filename(outfiles)) if self.inputs.download_files: for f in outfiles: try: sftp.get(os.path.join(filledtemplate_dir, f), f) except IOError: iflogger.info('remote file %s not found' % f) if any([val is None for val in outputs[key]]): outputs[key] = [] if len(outputs[key]) == 0: outputs[key] = None elif len(outputs[key]) == 1: outputs[key] = outputs[key][0] for k, v in outputs.items(): outputs[k] = os.path.join(os.getcwd(), v) return outputs def _get_ssh_client(self): config = paramiko.SSHConfig() config.parse(open(os.path.expanduser('~/.ssh/config'))) host = config.lookup(self.inputs.hostname) if 'proxycommand' in host: proxy = paramiko.ProxyCommand( subprocess.check_output( [os.environ['SHELL'], '-c', 'echo %s' % host['proxycommand']] ).strip() ) else: proxy = None client = paramiko.SSHClient() client.load_system_host_keys() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(host['hostname'], username=host['user'], sock=proxy) return client class JSONFileGrabberInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): in_file = File(exists=True, desc='JSON source file') defaults = traits.Dict(desc=('JSON dictionary that sets default output' 'values, overridden by values found in in_file')) class JSONFileGrabber(IOBase): """ Datagrabber interface that loads a json file and generates an output for every first-level object Example ------- >>> from nipype.interfaces.io import JSONFileGrabber >>> jsonSource = JSONFileGrabber() >>> jsonSource.inputs.defaults = {'param1': u'overrideMe', 'param3': 1.0} >>> res = jsonSource.run() >>> res.outputs.get() {'param3': 1.0, 'param1': u'overrideMe'} >>> jsonSource.inputs.in_file = 'jsongrabber.txt' >>> res = jsonSource.run() >>> res.outputs.get() {'param3': 1.0, 'param2': 4, 'param1': u'exampleStr'} """ input_spec = JSONFileGrabberInputSpec output_spec = DynamicTraitedSpec _always_run = True def _list_outputs(self): import json outputs = {} if isdefined(self.inputs.in_file): with open(self.inputs.in_file, 'r') as f: data = json.load(f) if not isinstance(data, dict): raise RuntimeError('JSON input has no dictionary structure') for key, value in data.iteritems(): outputs[key] = value if isdefined(self.inputs.defaults): defaults = self.inputs.defaults for key, value in defaults.iteritems(): if key not in outputs.keys(): outputs[key] = value return outputs class JSONFileSinkInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): out_file = File(desc='JSON sink file') in_dict = traits.Dict(value={}, usedefault=True, desc='input JSON dictionary') _outputs = traits.Dict(value={}, usedefault=True) def __setattr__(self, key, value): if key not in self.copyable_trait_names(): if not isdefined(value): super(JSONFileSinkInputSpec, self).__setattr__(key, value) self._outputs[key] = value else: if key in self._outputs: self._outputs[key] = value super(JSONFileSinkInputSpec, self).__setattr__(key, value) class JSONFileSinkOutputSpec(TraitedSpec): out_file = File(desc='JSON sink file') class JSONFileSink(IOBase): """ Very simple frontend for storing values into a JSON file. Entries already existing in in_dict will be overridden by matching entries dynamically added as inputs. .. warning:: This is not a thread-safe node because it can write to a common shared location. It will not complain when it overwrites a file. Examples -------- >>> jsonsink = JSONFileSink(input_names=['subject_id', ... 'some_measurement']) >>> jsonsink.inputs.subject_id = 's1' >>> jsonsink.inputs.some_measurement = 11.4 >>> jsonsink.run() # doctest: +SKIP Using a dictionary as input: >>> dictsink = JSONFileSink() >>> dictsink.inputs.in_dict = {'subject_id': 's1', ... 'some_measurement': 11.4} >>> dictsink.run() # doctest: +SKIP """ input_spec = JSONFileSinkInputSpec output_spec = JSONFileSinkOutputSpec def __init__(self, infields=[], force_run=True, **inputs): super(JSONFileSink, self).__init__(**inputs) self._input_names = infields undefined_traits = {} for key in infields: self.inputs.add_trait(key, traits.Any) self.inputs._outputs[key] = Undefined undefined_traits[key] = Undefined self.inputs.trait_set(trait_change_notify=False, **undefined_traits) if force_run: self._always_run = True def _process_name(self, name, val): if '.' in name: newkeys = name.split('.') name = newkeys.pop(0) nested_dict = {newkeys.pop(): val} for nk in reversed(newkeys): nested_dict = {nk: nested_dict} val = nested_dict return name, val def _list_outputs(self): import json import os.path as op if not isdefined(self.inputs.out_file): out_file = op.abspath('datasink.json') else: out_file = op.abspath(self.inputs.out_file) out_dict = self.inputs.in_dict # Overwrite in_dict entries automatically for key, val in self.inputs._outputs.items(): if not isdefined(val) or key == 'trait_added': continue key, val = self._process_name(key, val) out_dict[key] = val with open(out_file, 'w') as f: json.dump(out_dict, f) outputs = self.output_spec().get() outputs['out_file'] = out_file return outputs nipype-0.11.0/nipype/interfaces/matlab.py000066400000000000000000000171741257611314500203550ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ General matlab interface code """ import os from nipype.interfaces.base import (CommandLineInputSpec, InputMultiPath, isdefined, CommandLine, traits, File, Directory) from .. import config def get_matlab_command(): if 'NIPYPE_NO_MATLAB' in os.environ: return None try: matlab_cmd = os.environ['MATLABCMD'] except: matlab_cmd = 'matlab' try: res = CommandLine(command='which', args=matlab_cmd, terminal_output='allatonce').run() matlab_path = res.runtime.stdout.strip() except Exception, e: return None return matlab_cmd no_matlab = get_matlab_command() is None class MatlabInputSpec(CommandLineInputSpec): """ Basic expected inputs to Matlab interface """ script = traits.Str(argstr='-r \"%s;exit\"', desc='m-code to run', mandatory=True, position=-1) uses_mcr = traits.Bool(desc='use MCR interface', xor=['nodesktop', 'nosplash', 'single_comp_thread'], nohash=True) nodesktop = traits.Bool(True, argstr='-nodesktop', usedefault=True, desc='Switch off desktop mode on unix platforms', nohash=True) nosplash = traits.Bool(True, argstr='-nosplash', usedefault=True, desc='Switch of splash screen', nohash=True) logfile = File(argstr='-logfile %s', desc='Save matlab output to log') single_comp_thread = traits.Bool(argstr="-singleCompThread", desc="force single threaded operation", nohash=True) # non-commandline options mfile = traits.Bool(True, desc='Run m-code using m-file', usedefault=True) script_file = File('pyscript.m', usedefault=True, desc='Name of file to write m-code to') paths = InputMultiPath(Directory(), desc='Paths to add to matlabpath') prescript = traits.List(["ver,","try,"], usedefault=True, desc='prescript to be added before code') postscript = traits.List(["\n,catch ME,", "fprintf(2,'MATLAB code threw an exception:\\n');", "fprintf(2,'%s\\n',ME.message);", "if length(ME.stack) ~= 0, fprintf(2,'File:%s\\nName:%s\\nLine:%d\\n',ME.stack.file,ME.stack.name,ME.stack.line);, end;", "end;"], desc='script added after code', usedefault = True) class MatlabCommand(CommandLine): """Interface that runs matlab code >>> import nipype.interfaces.matlab as matlab >>> mlab = matlab.MatlabCommand() >>> mlab.inputs.script = "which('who')" >>> out = mlab.run() # doctest: +SKIP """ _cmd = 'matlab' _default_matlab_cmd = None _default_mfile = None _default_paths = None input_spec = MatlabInputSpec def __init__(self, matlab_cmd = None, **inputs): """initializes interface to matlab (default 'matlab -nodesktop -nosplash') """ super(MatlabCommand,self).__init__(**inputs) if matlab_cmd and isdefined(matlab_cmd): self._cmd = matlab_cmd elif self._default_matlab_cmd: self._cmd = self._default_matlab_cmd if self._default_mfile and not isdefined(self.inputs.mfile): self.inputs.mfile = self._default_mfile if self._default_paths and not isdefined(self.inputs.paths): self.inputs.paths = self._default_paths if not isdefined(self.inputs.single_comp_thread) and \ not isdefined(self.inputs.uses_mcr): if config.getboolean('execution','single_thread_matlab'): self.inputs.single_comp_thread = True # For matlab commands force all output to be returned since matlab # does not have a clean way of notifying an error self.inputs.terminal_output = 'allatonce' @classmethod def set_default_matlab_cmd(cls, matlab_cmd): """Set the default MATLAB command line for MATLAB classes. This method is used to set values for all MATLAB subclasses. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.matlab_cmd. """ cls._default_matlab_cmd = matlab_cmd @classmethod def set_default_mfile(cls, mfile): """Set the default MATLAB script file format for MATLAB classes. This method is used to set values for all MATLAB subclasses. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.mfile. """ cls._default_mfile = mfile @classmethod def set_default_paths(cls, paths): """Set the default MATLAB paths for MATLAB classes. This method is used to set values for all MATLAB subclasses. However, setting this will not update the output type for any existing instances. For these, assign the .inputs.paths. """ cls._default_paths = paths def _run_interface(self,runtime): self.inputs.terminal_output = 'allatonce' runtime = super(MatlabCommand, self)._run_interface(runtime) try: # Matlab can leave the terminal in a barbbled state os.system('stty sane') except: # We might be on a system where stty doesn't exist pass if 'MATLAB code threw an exception' in runtime.stderr: self.raise_exception(runtime) return runtime def _format_arg(self, name, trait_spec, value): if name in ['script']: argstr = trait_spec.argstr if self.inputs.uses_mcr: argstr='%s' return self._gen_matlab_command(argstr, value) return super(MatlabCommand, self)._format_arg(name, trait_spec, value) def _gen_matlab_command(self, argstr, script_lines): cwd = os.getcwd() mfile = self.inputs.mfile or self.inputs.uses_mcr paths = [] if isdefined(self.inputs.paths): paths = self.inputs.paths # prescript prescript = self.inputs.prescript postscript = self.inputs.postscript #postcript takes different default value depending on the mfile argument if mfile: prescript.insert(0,"fprintf(1,'Executing %s at %s:\\n',mfilename,datestr(now));") else: prescript.insert(0,"fprintf(1,'Executing code at %s:\\n',datestr(now));") for path in paths: prescript.append("addpath('%s');\n" % path) if not mfile: #clean up the code of comments and replace newlines with commas script_lines = ','.join([line for line in script_lines.split("\n") if not line.strip().startswith("%")]) script_lines = '\n'.join(prescript)+script_lines+'\n'.join(postscript) if mfile: mfile = file(os.path.join(cwd,self.inputs.script_file), 'wt') mfile.write(script_lines) mfile.close() if self.inputs.uses_mcr: script = '%s' % (os.path.join(cwd,self.inputs.script_file)) else: script = "addpath('%s');%s" % (cwd, self.inputs.script_file.split('.')[0]) else: script = ''.join(script_lines.split('\n')) return argstr % script nipype-0.11.0/nipype/interfaces/meshfix.py000066400000000000000000000173231257611314500205540ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Fixes meshes: Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from .base import (CommandLine, CommandLineInputSpec, traits, TraitedSpec, isdefined, File) import os.path as op from ..utils.filemanip import split_filename class MeshFixInputSpec(CommandLineInputSpec): number_of_biggest_shells = traits.Int(argstr='--shells %d', desc="Only the N biggest shells are kept") epsilon_angle = traits.Range(argstr='-a %f', low=0.0, high=2.0, desc="Epsilon angle in degrees (must be between 0 and 2)") join_overlapping_largest_components = traits.Bool(argstr='-j', xor=['join_closest_components'], desc='Join 2 biggest components if they overlap, remove the rest.') join_closest_components = traits.Bool(argstr='-jc', xor=['join_closest_components'], desc='Join the closest pair of components.') quiet_mode = traits.Bool(argstr='-q', desc="Quiet mode, don't write much to stdout.") dont_clean = traits.Bool(argstr='--no-clean', desc="Don't Clean") save_as_stl = traits.Bool(xor= ['save_as_vmrl', 'save_as_freesurfer_mesh'], argstr='--stl', desc="Result is saved in stereolithographic format (.stl)") save_as_vmrl = traits.Bool(argstr='--wrl', xor= ['save_as_stl', 'save_as_freesurfer_mesh'], desc="Result is saved in VRML1.0 format (.wrl)") save_as_freesurfer_mesh = traits.Bool(argstr='--fsmesh', xor= ['save_as_vrml', 'save_as_stl'], desc="Result is saved in freesurfer mesh format") remove_handles = traits.Bool(argstr='--remove-handles', desc="Remove handles") uniform_remeshing_steps = traits.Int(argstr='-u %d', requires=['uniform_remeshing_vertices'], desc="Number of steps for uniform remeshing of the whole mesh") uniform_remeshing_vertices = traits.Int(argstr='--vertices %d', requires=['uniform_remeshing_steps'], desc="Constrains the number of vertices." \ "Must be used with uniform_remeshing_steps") laplacian_smoothing_steps = traits.Int(argstr='--smooth %d', desc="The number of laplacian smoothing steps to apply") x_shift = traits.Int(argstr='--smooth %d', desc="Shifts the coordinates of the vertices when saving. Output must be in FreeSurfer format") # Cutting, decoupling, dilation cut_outer = traits.Int(argstr='--cut-outer %d', desc="Remove triangles of 1st that are outside of the 2nd shell.") cut_inner = traits.Int(argstr='--cut-inner %d', desc="Remove triangles of 1st that are inside of the 2nd shell. Dilate 2nd by N; Fill holes and keep only 1st afterwards.") decouple_inin = traits.Int(argstr='--decouple-inin %d', desc="Treat 1st file as inner, 2nd file as outer component." \ "Resolve overlaps by moving inners triangles inwards. Constrain the min distance between the components > d.") decouple_outin = traits.Int(argstr='--decouple-outin %d', desc="Treat 1st file as outer, 2nd file as inner component." \ "Resolve overlaps by moving outers triangles inwards. Constrain the min distance between the components > d.") decouple_outout = traits.Int(argstr='--decouple-outout %d', desc="Treat 1st file as outer, 2nd file as inner component." \ "Resolve overlaps by moving outers triangles outwards. Constrain the min distance between the components > d.") finetuning_inwards = traits.Bool(argstr='--fineTuneIn ', requires=['finetuning_distance', 'finetuning_substeps']) finetuning_outwards = traits.Bool(argstr='--fineTuneIn ', requires=['finetuning_distance', 'finetuning_substeps'], xor=['finetuning_inwards'], desc = 'Similar to finetuning_inwards, but ensures minimal distance in the other direction') finetuning_distance = traits.Float(argstr='%f', requires=['finetuning_substeps'], desc="Used to fine-tune the minimal distance between surfaces." \ "A minimal distance d is ensured, and reached in n substeps. When using the surfaces for subsequent volume meshing by gmsh, this step prevent too flat tetrahedra2)") finetuning_substeps = traits.Int(argstr='%d', requires=['finetuning_distance'], desc="Used to fine-tune the minimal distance between surfaces." \ "A minimal distance d is ensured, and reached in n substeps. When using the surfaces for subsequent volume meshing by gmsh, this step prevent too flat tetrahedra2)") dilation = traits.Int(argstr='--dilate %d', desc="Dilate the surface by d. d < 0 means shrinking.") set_intersections_to_one = traits.Bool(argstr='--intersect', desc="If the mesh contains intersections, return value = 1." \ "If saved in gmsh format, intersections will be highlighted.") in_file1 = File(exists=True, argstr="%s", position=1, mandatory=True) in_file2 = File(exists=True, argstr="%s", position=2) output_type = traits.Enum('off', ['stl', 'msh', 'wrl', 'vrml', 'fs', 'off'], usedefault=True, desc='The output type to save the file as.') out_filename = File(genfile=True, argstr="-o %s", desc='The output filename for the fixed mesh file') class MeshFixOutputSpec(TraitedSpec): mesh_file = File(exists=True, desc='The output mesh file') class MeshFix(CommandLine): """ MeshFix v1.2-alpha - by Marco Attene, Mirko Windhoff, Axel Thielscher. .. seealso:: http://jmeshlib.sourceforge.net Sourceforge page http://simnibs.de/installation/meshfixandgetfem Ubuntu installation instructions If MeshFix is used for research purposes, please cite the following paper: M. Attene - A lightweight approach to repairing digitized polygon meshes. The Visual Computer, 2010. (c) Springer. Accepted input formats are OFF, PLY and STL. Other formats (like .msh for gmsh) are supported only partially. Example ------- >>> import nipype.interfaces.meshfix as mf >>> fix = mf.MeshFix() >>> fix.inputs.in_file1 = 'lh-pial.stl' >>> fix.inputs.in_file2 = 'rh-pial.stl' >>> fix.run() # doctest: +SKIP >>> fix.cmdline 'meshfix lh-pial.stl rh-pial.stl -o lh-pial_fixed.off' """ _cmd = 'meshfix' input_spec=MeshFixInputSpec output_spec=MeshFixOutputSpec def _list_outputs(self): outputs = self.output_spec().get() if isdefined(self.inputs.out_filename): path, name, ext = split_filename(self.inputs.out_filename) ext = ext.replace('.', '') out_types = ['stl', 'msh', 'wrl', 'vrml', 'fs', 'off'] # Make sure that the output filename uses one of the possible file types if any(ext == out_type.lower() for out_type in out_types): outputs['mesh_file'] = op.abspath(self.inputs.out_filename) else: outputs['mesh_file'] = op.abspath(name + '.' + self.inputs.output_type) else: outputs['mesh_file'] = op.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file1) if self.inputs.save_as_freesurfer_mesh or self.inputs.output_type == 'fs': self.inputs.output_type = 'fs' self.inputs.save_as_freesurfer_mesh = True if self.inputs.save_as_stl or self.inputs.output_type == 'stl': self.inputs.output_type = 'stl' self.inputs.save_as_stl = True if self.inputs.save_as_vmrl or self.inputs.output_type == 'vmrl': self.inputs.output_type = 'vmrl' self.inputs.save_as_vmrl = True return name + '_fixed.' + self.inputs.output_type nipype-0.11.0/nipype/interfaces/mipav/000077500000000000000000000000001257611314500176455ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mipav/__init__.py000066400000000000000000000010151257611314500217530ustar00rootroot00000000000000from developer import JistLaminarVolumetricLayering, JistBrainMgdmSegmentation, JistLaminarProfileGeometry, JistLaminarProfileCalculator, MedicAlgorithmN3, JistLaminarROIAveraging, MedicAlgorithmLesionToads, JistBrainMp2rageSkullStripping, JistCortexSurfaceMeshInflation, RandomVol, MedicAlgorithmImageCalculator, JistBrainMp2rageDuraEstimation, JistLaminarProfileSampling, MedicAlgorithmMipavReorient, MedicAlgorithmSPECTRE2010, JistBrainPartialVolumeFilter, JistIntensityMp2rageMasking, MedicAlgorithmThresholdToBinaryMask nipype-0.11.0/nipype/interfaces/mipav/developer.py000066400000000000000000001374471257611314500222240ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class JistLaminarVolumetricLayeringInputSpec(CommandLineInputSpec): inInner = File(desc="Inner Distance Image (GM/WM boundary)", exists=True, argstr="--inInner %s") inOuter = File(desc="Outer Distance Image (CSF/GM boundary)", exists=True, argstr="--inOuter %s") inNumber = traits.Int(desc="Number of layers", argstr="--inNumber %d") inMax = traits.Int(desc="Max iterations for narrow band evolution", argstr="--inMax %d") inMin = traits.Float(desc="Min change ratio for narrow band evolution", argstr="--inMin %f") inLayering = traits.Enum("distance-preserving", "volume-preserving", desc="Layering method", argstr="--inLayering %s") inLayering2 = traits.Enum("outward", "inward", desc="Layering direction", argstr="--inLayering2 %s") incurvature = traits.Int(desc="curvature approximation scale (voxels)", argstr="--incurvature %d") inratio = traits.Float(desc="ratio smoothing kernel size (voxels)", argstr="--inratio %f") inpresmooth = traits.Enum("true", "false", desc="pre-smooth cortical surfaces", argstr="--inpresmooth %s") inTopology = traits.Enum("26/6", "6/26", "18/6", "6/18", "6/6", "wcs", "wco", "no", desc="Topology", argstr="--inTopology %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outContinuous = traits.Either(traits.Bool, File(), hash_files=False, desc="Continuous depth measurement", argstr="--outContinuous %s") outDiscrete = traits.Either(traits.Bool, File(), hash_files=False, desc="Discrete sampled layers", argstr="--outDiscrete %s") outLayer = traits.Either(traits.Bool, File(), hash_files=False, desc="Layer boundary surfaces", argstr="--outLayer %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistLaminarVolumetricLayeringOutputSpec(TraitedSpec): outContinuous = File(desc="Continuous depth measurement", exists=True) outDiscrete = File(desc="Discrete sampled layers", exists=True) outLayer = File(desc="Layer boundary surfaces", exists=True) class JistLaminarVolumetricLayering(SEMLikeCommandLine): """title: Volumetric Layering category: Developer Tools description: Builds a continuous layering of the cortex following distance-preserving or volume-preserving models of cortical folding. Waehnert MD, Dinse J, Weiss M, Streicher MN, Waehnert P, Geyer S, Turner R, Bazin PL, Anatomically motivated modeling of cortical laminae, Neuroimage, 2013. version: 3.0.RC contributor: Miriam Waehnert (waehnert@cbs.mpg.de) http://www.cbs.mpg.de/ """ input_spec = JistLaminarVolumetricLayeringInputSpec output_spec = JistLaminarVolumetricLayeringOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.laminar.JistLaminarVolumetricLayering " _outputs_filenames = {'outContinuous':'outContinuous.nii','outLayer':'outLayer.nii','outDiscrete':'outDiscrete.nii'} _redirect_x = True class JistBrainMgdmSegmentationInputSpec(CommandLineInputSpec): inMP2RAGE = File(desc="MP2RAGE T1 Map Image", exists=True, argstr="--inMP2RAGE %s") inMP2RAGE2 = File(desc="MP2RAGE T1-weighted Image", exists=True, argstr="--inMP2RAGE2 %s") inPV = File(desc="PV / Dura Image", exists=True, argstr="--inPV %s") inMPRAGE = File(desc="MPRAGE T1-weighted Image", exists=True, argstr="--inMPRAGE %s") inFLAIR = File(desc="FLAIR Image", exists=True, argstr="--inFLAIR %s") inAtlas = File(desc="Atlas file", exists=True, argstr="--inAtlas %s") inData = traits.Float(desc="Data weight", argstr="--inData %f") inCurvature = traits.Float(desc="Curvature weight", argstr="--inCurvature %f") inPosterior = traits.Float(desc="Posterior scale (mm)", argstr="--inPosterior %f") inMax = traits.Int(desc="Max iterations", argstr="--inMax %d") inMin = traits.Float(desc="Min change", argstr="--inMin %f") inSteps = traits.Int(desc="Steps", argstr="--inSteps %d") inTopology = traits.Enum("26/6", "6/26", "18/6", "6/18", "6/6", "wcs", "wco", "no", desc="Topology", argstr="--inTopology %s") inCompute = traits.Enum("true", "false", desc="Compute posteriors", argstr="--inCompute %s") inAdjust = traits.Enum("true", "false", desc="Adjust intensity priors", argstr="--inAdjust %s") inOutput = traits.Enum("segmentation", "memberships", desc="Output images", argstr="--inOutput %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outSegmented = traits.Either(traits.Bool, File(), hash_files=False, desc="Segmented Brain Image", argstr="--outSegmented %s") outLevelset = traits.Either(traits.Bool, File(), hash_files=False, desc="Levelset Boundary Image", argstr="--outLevelset %s") outPosterior2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Posterior Maximum Memberships (4D)", argstr="--outPosterior2 %s") outPosterior3 = traits.Either(traits.Bool, File(), hash_files=False, desc="Posterior Maximum Labels (4D)", argstr="--outPosterior3 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistBrainMgdmSegmentationOutputSpec(TraitedSpec): outSegmented = File(desc="Segmented Brain Image", exists=True) outLevelset = File(desc="Levelset Boundary Image", exists=True) outPosterior2 = File(desc="Posterior Maximum Memberships (4D)", exists=True) outPosterior3 = File(desc="Posterior Maximum Labels (4D)", exists=True) class JistBrainMgdmSegmentation(SEMLikeCommandLine): """title: MGDM Whole Brain Segmentation category: Developer Tools description: Estimate brain structures from an atlas for a MRI dataset (multiple input combinations are possible). version: 2.0.RC """ input_spec = JistBrainMgdmSegmentationInputSpec output_spec = JistBrainMgdmSegmentationOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.brain.JistBrainMgdmSegmentation " _outputs_filenames = {'outSegmented':'outSegmented.nii','outPosterior2':'outPosterior2.nii','outPosterior3':'outPosterior3.nii','outLevelset':'outLevelset.nii'} _redirect_x = True class JistLaminarProfileGeometryInputSpec(CommandLineInputSpec): inProfile = File(desc="Profile Surface Image", exists=True, argstr="--inProfile %s") incomputed = traits.Enum("thickness", "curvedness", "shape_index", "mean_curvature", "gauss_curvature", "profile_length", "profile_curvature", "profile_torsion", desc="computed measure", argstr="--incomputed %s") inregularization = traits.Enum("none", "Gaussian", desc="regularization", argstr="--inregularization %s") insmoothing = traits.Float(desc="smoothing parameter", argstr="--insmoothing %f") inoutside = traits.Float(desc="outside extension (mm)", argstr="--inoutside %f") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outResult = traits.Either(traits.Bool, File(), hash_files=False, desc="Result", argstr="--outResult %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistLaminarProfileGeometryOutputSpec(TraitedSpec): outResult = File(desc="Result", exists=True) class JistLaminarProfileGeometry(SEMLikeCommandLine): """title: Profile Geometry category: Developer Tools description: Compute various geometric quantities for a cortical layers. version: 3.0.RC """ input_spec = JistLaminarProfileGeometryInputSpec output_spec = JistLaminarProfileGeometryOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.laminar.JistLaminarProfileGeometry " _outputs_filenames = {'outResult':'outResult.nii'} _redirect_x = True class JistLaminarProfileCalculatorInputSpec(CommandLineInputSpec): inIntensity = File(desc="Intensity Profile Image", exists=True, argstr="--inIntensity %s") inMask = File(desc="Mask Image (opt, 3D or 4D)", exists=True, argstr="--inMask %s") incomputed = traits.Enum("mean", "stdev", "skewness", "kurtosis", desc="computed statistic", argstr="--incomputed %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outResult = traits.Either(traits.Bool, File(), hash_files=False, desc="Result", argstr="--outResult %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistLaminarProfileCalculatorOutputSpec(TraitedSpec): outResult = File(desc="Result", exists=True) class JistLaminarProfileCalculator(SEMLikeCommandLine): """title: Profile Calculator category: Developer Tools description: Compute various moments for intensities mapped along a cortical profile. version: 3.0.RC """ input_spec = JistLaminarProfileCalculatorInputSpec output_spec = JistLaminarProfileCalculatorOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.laminar.JistLaminarProfileCalculator " _outputs_filenames = {'outResult':'outResult.nii'} _redirect_x = True class MedicAlgorithmN3InputSpec(CommandLineInputSpec): inInput = File(desc="Input Volume", exists=True, argstr="--inInput %s") inSignal = traits.Float(desc="Default = min + 1, Values at less than threshold are treated as part of the background", argstr="--inSignal %f") inMaximum = traits.Int(desc="Maximum number of Iterations", argstr="--inMaximum %d") inEnd = traits.Float(desc="Usually 0.01-0.00001, The measure used to terminate the iterations is the coefficient of variation of change in field estimates between successive iterations.", argstr="--inEnd %f") inField = traits.Float(desc="Characteristic distance over which the field varies. The distance between adjacent knots in bspline fitting with at least 4 knots going in every dimension. The default in the dialog is one third the distance (resolution * extents) of the smallest dimension.", argstr="--inField %f") inSubsample = traits.Float(desc="Usually between 1-32, The factor by which the data is subsampled to a lower resolution in estimating the slowly varying non-uniformity field. Reduce sampling in the finest sampling direction by the shrink factor.", argstr="--inSubsample %f") inKernel = traits.Float(desc="Usually between 0.05-0.50, Width of deconvolution kernel used to sharpen the histogram. Larger values give faster convergence while smaller values give greater accuracy.", argstr="--inKernel %f") inWeiner = traits.Float(desc="Usually between 0.0-1.0", argstr="--inWeiner %f") inAutomatic = traits.Enum("true", "false", desc="If true determines the threshold by histogram analysis. If true a VOI cannot be used and the input threshold is ignored.", argstr="--inAutomatic %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outInhomogeneity = traits.Either(traits.Bool, File(), hash_files=False, desc="Inhomogeneity Corrected Volume", argstr="--outInhomogeneity %s") outInhomogeneity2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Inhomogeneity Field", argstr="--outInhomogeneity2 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmN3OutputSpec(TraitedSpec): outInhomogeneity = File(desc="Inhomogeneity Corrected Volume", exists=True) outInhomogeneity2 = File(desc="Inhomogeneity Field", exists=True) class MedicAlgorithmN3(SEMLikeCommandLine): """title: N3 Correction category: Developer Tools description: Non-parametric Intensity Non-uniformity Correction, N3, originally by J.G. Sled. version: 1.8.R """ input_spec = MedicAlgorithmN3InputSpec output_spec = MedicAlgorithmN3OutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.classification.MedicAlgorithmN3 " _outputs_filenames = {'outInhomogeneity2':'outInhomogeneity2.nii','outInhomogeneity':'outInhomogeneity.nii'} _redirect_x = True class JistLaminarROIAveragingInputSpec(CommandLineInputSpec): inIntensity = File(desc="Intensity Profile Image", exists=True, argstr="--inIntensity %s") inROI = File(desc="ROI Mask", exists=True, argstr="--inROI %s") inROI2 = traits.Str(desc="ROI Name", argstr="--inROI2 %s") inMask = File(desc="Mask Image (opt, 3D or 4D)", exists=True, argstr="--inMask %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outROI3 = traits.Either(traits.Bool, File(), hash_files=False, desc="ROI Average", argstr="--outROI3 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistLaminarROIAveragingOutputSpec(TraitedSpec): outROI3 = File(desc="ROI Average", exists=True) class JistLaminarROIAveraging(SEMLikeCommandLine): """title: Profile ROI Averaging category: Developer Tools description: Compute an average profile over a given ROI. version: 3.0.RC """ input_spec = JistLaminarROIAveragingInputSpec output_spec = JistLaminarROIAveragingOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.laminar.JistLaminarROIAveraging " _outputs_filenames = {'outROI3':'outROI3'} _redirect_x = True class MedicAlgorithmLesionToadsInputSpec(CommandLineInputSpec): inT1_MPRAGE = File(desc="T1_MPRAGE Image", exists=True, argstr="--inT1_MPRAGE %s") inT1_SPGR = File(desc="T1_SPGR Image", exists=True, argstr="--inT1_SPGR %s") inFLAIR = File(desc="FLAIR Image", exists=True, argstr="--inFLAIR %s") inAtlas = traits.Enum("With Lesion", "No Lesion", desc="Atlas to Use", argstr="--inAtlas %s") inOutput = traits.Enum("hard segmentation", "hard segmentation+memberships", "cruise inputs", "dura removal inputs", desc="Output images", argstr="--inOutput %s") inOutput2 = traits.Enum("true", "false", desc="Output the hard classification using maximum membership (not neceesarily topologically correct)", argstr="--inOutput2 %s") inCorrect = traits.Enum("true", "false", desc="Correct MR field inhomogeneity.", argstr="--inCorrect %s") inOutput3 = traits.Enum("true", "false", desc="Output the estimated inhomogeneity field", argstr="--inOutput3 %s") inAtlas2 = File(desc="Atlas File - With Lesions", exists=True, argstr="--inAtlas2 %s") inAtlas3 = File(desc="Atlas File - No Lesion - T1 and FLAIR", exists=True, argstr="--inAtlas3 %s") inAtlas4 = File(desc="Atlas File - No Lesion - T1 Only", exists=True, argstr="--inAtlas4 %s") inMaximum = traits.Int(desc="Maximum distance from the interventricular WM boundary to downweight the lesion membership to avoid false postives", argstr="--inMaximum %d") inMaximum2 = traits.Int(desc="Maximum Ventircle Distance", argstr="--inMaximum2 %d") inMaximum3 = traits.Int(desc="Maximum InterVentricular Distance", argstr="--inMaximum3 %d") inInclude = traits.Enum("true", "false", desc="Include lesion in WM class in hard classification", argstr="--inInclude %s") inAtlas5 = traits.Float(desc="Controls the effect of the statistical atlas on the segmentation", argstr="--inAtlas5 %f") inSmooting = traits.Float(desc="Controls the effect of neighberhood voxels on the membership", argstr="--inSmooting %f") inMaximum4 = traits.Float(desc="Maximum amount of relative change in the energy function considered as the convergence criteria", argstr="--inMaximum4 %f") inMaximum5 = traits.Int(desc="Maximum iterations", argstr="--inMaximum5 %d") inAtlas6 = traits.Enum("rigid", "multi_fully_affine", desc="Atlas alignment", argstr="--inAtlas6 %s") inConnectivity = traits.Enum("(26,6)", "(6,26)", "(6,18)", "(18,6)", desc="Connectivity (foreground,background)", argstr="--inConnectivity %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outHard = traits.Either(traits.Bool, File(), hash_files=False, desc="Hard segmentation", argstr="--outHard %s") outHard2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Hard segmentationfrom memberships", argstr="--outHard2 %s") outInhomogeneity = traits.Either(traits.Bool, File(), hash_files=False, desc="Inhomogeneity Field", argstr="--outInhomogeneity %s") outMembership = traits.Either(traits.Bool, File(), hash_files=False, desc="Membership Functions", argstr="--outMembership %s") outLesion = traits.Either(traits.Bool, File(), hash_files=False, desc="Lesion Segmentation", argstr="--outLesion %s") outSulcal = traits.Either(traits.Bool, File(), hash_files=False, desc="Sulcal CSF Membership", argstr="--outSulcal %s") outCortical = traits.Either(traits.Bool, File(), hash_files=False, desc="Cortical GM Membership", argstr="--outCortical %s") outFilled = traits.Either(traits.Bool, File(), hash_files=False, desc="Filled WM Membership", argstr="--outFilled %s") outWM = traits.Either(traits.Bool, File(), hash_files=False, desc="WM Mask", argstr="--outWM %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmLesionToadsOutputSpec(TraitedSpec): outHard = File(desc="Hard segmentation", exists=True) outHard2 = File(desc="Hard segmentationfrom memberships", exists=True) outInhomogeneity = File(desc="Inhomogeneity Field", exists=True) outMembership = File(desc="Membership Functions", exists=True) outLesion = File(desc="Lesion Segmentation", exists=True) outSulcal = File(desc="Sulcal CSF Membership", exists=True) outCortical = File(desc="Cortical GM Membership", exists=True) outFilled = File(desc="Filled WM Membership", exists=True) outWM = File(desc="WM Mask", exists=True) class MedicAlgorithmLesionToads(SEMLikeCommandLine): """title: Lesion TOADS category: Developer Tools description: Algorithm for simulataneous brain structures and MS lesion segmentation of MS Brains. The brain segmentation is topologically consistent and the algorithm can use multiple MR sequences as input data. N. Shiee, P.-L. Bazin, A.Z. Ozturk, P.A. Calabresi, D.S. Reich, D.L. Pham, "A Topology-Preserving Approach to the Segmentation of Brain Images with Multiple Sclerosis", NeuroImage, vol. 49, no. 2, pp. 1524-1535, 2010. version: 1.9.R contributor: Navid Shiee (navid.shiee@nih.gov) http://iacl.ece.jhu.edu/~nshiee/ """ input_spec = MedicAlgorithmLesionToadsInputSpec output_spec = MedicAlgorithmLesionToadsOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.classification.MedicAlgorithmLesionToads " _outputs_filenames = {'outWM':'outWM.nii','outHard':'outHard.nii','outFilled':'outFilled.nii','outMembership':'outMembership.nii','outInhomogeneity':'outInhomogeneity.nii','outCortical':'outCortical.nii','outHard2':'outHard2.nii','outLesion':'outLesion.nii','outSulcal':'outSulcal.nii'} _redirect_x = True class JistBrainMp2rageSkullStrippingInputSpec(CommandLineInputSpec): inSecond = File(desc="Second inversion (Inv2) Image", exists=True, argstr="--inSecond %s") inT1 = File(desc="T1 Map (T1_Images) Image (opt)", exists=True, argstr="--inT1 %s") inT1weighted = File(desc="T1-weighted (UNI) Image (opt)", exists=True, argstr="--inT1weighted %s") inFilter = File(desc="Filter Image (opt)", exists=True, argstr="--inFilter %s") inSkip = traits.Enum("true", "false", desc="Skip zero values", argstr="--inSkip %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outBrain = traits.Either(traits.Bool, File(), hash_files=False, desc="Brain Mask Image", argstr="--outBrain %s") outMasked = traits.Either(traits.Bool, File(), hash_files=False, desc="Masked T1 Map Image", argstr="--outMasked %s") outMasked2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Masked T1-weighted Image", argstr="--outMasked2 %s") outMasked3 = traits.Either(traits.Bool, File(), hash_files=False, desc="Masked Filter Image", argstr="--outMasked3 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistBrainMp2rageSkullStrippingOutputSpec(TraitedSpec): outBrain = File(desc="Brain Mask Image", exists=True) outMasked = File(desc="Masked T1 Map Image", exists=True) outMasked2 = File(desc="Masked T1-weighted Image", exists=True) outMasked3 = File(desc="Masked Filter Image", exists=True) class JistBrainMp2rageSkullStripping(SEMLikeCommandLine): """title: MP2RAGE Skull Stripping category: Developer Tools description: Estimate a brain mask for a MP2RAGE dataset. At least a T1-weighted or a T1 map image is required. version: 3.0.RC """ input_spec = JistBrainMp2rageSkullStrippingInputSpec output_spec = JistBrainMp2rageSkullStrippingOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.brain.JistBrainMp2rageSkullStripping " _outputs_filenames = {'outBrain':'outBrain.nii','outMasked3':'outMasked3.nii','outMasked2':'outMasked2.nii','outMasked':'outMasked.nii'} _redirect_x = True class JistCortexSurfaceMeshInflationInputSpec(CommandLineInputSpec): inLevelset = File(desc="Levelset Image", exists=True, argstr="--inLevelset %s") inSOR = traits.Float(desc="SOR Parameter", argstr="--inSOR %f") inMean = traits.Float(desc="Mean Curvature Threshold", argstr="--inMean %f") inStep = traits.Int(desc="Step Size", argstr="--inStep %d") inMax = traits.Int(desc="Max Iterations", argstr="--inMax %d") inLorentzian = traits.Enum("true", "false", desc="Lorentzian Norm", argstr="--inLorentzian %s") inTopology = traits.Enum("26/6", "6/26", "18/6", "6/18", "6/6", "wcs", "wco", "no", desc="Topology", argstr="--inTopology %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outOriginal = traits.Either(traits.Bool, File(), hash_files=False, desc="Original Surface", argstr="--outOriginal %s") outInflated = traits.Either(traits.Bool, File(), hash_files=False, desc="Inflated Surface", argstr="--outInflated %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistCortexSurfaceMeshInflationOutputSpec(TraitedSpec): outOriginal = File(desc="Original Surface", exists=True) outInflated = File(desc="Inflated Surface", exists=True) class JistCortexSurfaceMeshInflation(SEMLikeCommandLine): """title: Surface Mesh Inflation category: Developer Tools description: Inflates a cortical surface mesh. D. Tosun, M. E. Rettmann, X. Han, X. Tao, C. Xu, S. M. Resnick, D. Pham, and J. L. Prince, Cortical Surface Segmentation and Mapping, NeuroImage, vol. 23, pp. S108--S118, 2004. version: 3.0.RC contributor: Duygu Tosun """ input_spec = JistCortexSurfaceMeshInflationInputSpec output_spec = JistCortexSurfaceMeshInflationOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.cortex.JistCortexSurfaceMeshInflation " _outputs_filenames = {'outOriginal':'outOriginal','outInflated':'outInflated'} _redirect_x = True class RandomVolInputSpec(CommandLineInputSpec): inSize = traits.Int(desc="Size of Volume in X direction", argstr="--inSize %d") inSize2 = traits.Int(desc="Size of Volume in Y direction", argstr="--inSize2 %d") inSize3 = traits.Int(desc="Size of Volume in Z direction", argstr="--inSize3 %d") inSize4 = traits.Int(desc="Size of Volume in t direction", argstr="--inSize4 %d") inStandard = traits.Int(desc="Standard Deviation for Normal Distribution", argstr="--inStandard %d") inLambda = traits.Float(desc="Lambda Value for Exponential Distribution", argstr="--inLambda %f") inMaximum = traits.Int(desc="Maximum Value", argstr="--inMaximum %d") inMinimum = traits.Int(desc="Minimum Value", argstr="--inMinimum %d") inField = traits.Enum("Uniform", "Normal", "Exponential", desc="Field", argstr="--inField %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outRand1 = traits.Either(traits.Bool, File(), hash_files=False, desc="Rand1", argstr="--outRand1 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class RandomVolOutputSpec(TraitedSpec): outRand1 = File(desc="Rand1", exists=True) class RandomVol(SEMLikeCommandLine): """title: Random Volume Generator category: Developer Tools description: Generate a random scalar volume. version: 1.12.RC documentation-url: http://www.nitrc.org/projects/jist/ """ input_spec = RandomVolInputSpec output_spec = RandomVolOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.bme.smile.demo.RandomVol " _outputs_filenames = {'outRand1':'outRand1.nii'} _redirect_x = True class MedicAlgorithmImageCalculatorInputSpec(CommandLineInputSpec): inVolume = File(desc="Volume 1", exists=True, argstr="--inVolume %s") inVolume2 = File(desc="Volume 2", exists=True, argstr="--inVolume2 %s") inOperation = traits.Enum("Add", "Subtract", "Multiply", "Divide", "Min", "Max", desc="Operation", argstr="--inOperation %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outResult = traits.Either(traits.Bool, File(), hash_files=False, desc="Result Volume", argstr="--outResult %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmImageCalculatorOutputSpec(TraitedSpec): outResult = File(desc="Result Volume", exists=True) class MedicAlgorithmImageCalculator(SEMLikeCommandLine): """title: Image Calculator category: Developer Tools description: Perform simple image calculator operations on two images. The operations include 'Add', 'Subtract', 'Multiply', and 'Divide' version: 1.10.RC documentation-url: http://www.iacl.ece.jhu.edu/ """ input_spec = MedicAlgorithmImageCalculatorInputSpec output_spec = MedicAlgorithmImageCalculatorOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.utilities.math.MedicAlgorithmImageCalculator " _outputs_filenames = {'outResult':'outResult.nii'} _redirect_x = True class JistBrainMp2rageDuraEstimationInputSpec(CommandLineInputSpec): inSecond = File(desc="Second inversion (Inv2) Image", exists=True, argstr="--inSecond %s") inSkull = File(desc="Skull Stripping Mask", exists=True, argstr="--inSkull %s") inDistance = traits.Float(desc="Distance to background (mm)", argstr="--inDistance %f") inoutput = traits.Enum("dura_region", "boundary", "dura_prior", "bg_prior", "intens_prior", desc="Outputs an estimate of the dura / CSF boundary or an estimate of the entire dura region.", argstr="--inoutput %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outDura = traits.Either(traits.Bool, File(), hash_files=False, desc="Dura Image", argstr="--outDura %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistBrainMp2rageDuraEstimationOutputSpec(TraitedSpec): outDura = File(desc="Dura Image", exists=True) class JistBrainMp2rageDuraEstimation(SEMLikeCommandLine): """title: MP2RAGE Dura Estimation category: Developer Tools description: Filters a MP2RAGE brain image to obtain a probability map of dura matter. version: 3.0.RC """ input_spec = JistBrainMp2rageDuraEstimationInputSpec output_spec = JistBrainMp2rageDuraEstimationOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.brain.JistBrainMp2rageDuraEstimation " _outputs_filenames = {'outDura':'outDura.nii'} _redirect_x = True class JistLaminarProfileSamplingInputSpec(CommandLineInputSpec): inProfile = File(desc="Profile Surface Image", exists=True, argstr="--inProfile %s") inIntensity = File(desc="Intensity Image", exists=True, argstr="--inIntensity %s") inCortex = File(desc="Cortex Mask (opt)", exists=True, argstr="--inCortex %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outProfilemapped = traits.Either(traits.Bool, File(), hash_files=False, desc="Profile-mapped Intensity Image", argstr="--outProfilemapped %s") outProfile2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Profile 4D Mask", argstr="--outProfile2 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistLaminarProfileSamplingOutputSpec(TraitedSpec): outProfilemapped = File(desc="Profile-mapped Intensity Image", exists=True) outProfile2 = File(desc="Profile 4D Mask", exists=True) class JistLaminarProfileSampling(SEMLikeCommandLine): """title: Profile Sampling category: Developer Tools description: Sample some intensity image along a cortical profile across layer surfaces. version: 3.0.RC """ input_spec = JistLaminarProfileSamplingInputSpec output_spec = JistLaminarProfileSamplingOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.laminar.JistLaminarProfileSampling " _outputs_filenames = {'outProfile2':'outProfile2.nii','outProfilemapped':'outProfilemapped.nii'} _redirect_x = True class MedicAlgorithmMipavReorientInputSpec(CommandLineInputSpec): inSource = InputMultiPath(File, desc="Source", sep=";", argstr="--inSource %s") inTemplate = File(desc="Template", exists=True, argstr="--inTemplate %s") inNew = traits.Enum("Dicom axial", "Dicom coronal", "Dicom sagittal", "User defined", desc="New image orientation", argstr="--inNew %s") inUser = traits.Enum("Unknown", "Patient Right to Left", "Patient Left to Right", "Patient Posterior to Anterior", "Patient Anterior to Posterior", "Patient Inferior to Superior", "Patient Superior to Inferior", desc="User defined X-axis orientation (image left to right)", argstr="--inUser %s") inUser2 = traits.Enum("Unknown", "Patient Right to Left", "Patient Left to Right", "Patient Posterior to Anterior", "Patient Anterior to Posterior", "Patient Inferior to Superior", "Patient Superior to Inferior", desc="User defined Y-axis orientation (image top to bottom)", argstr="--inUser2 %s") inUser3 = traits.Enum("Unknown", "Patient Right to Left", "Patient Left to Right", "Patient Posterior to Anterior", "Patient Anterior to Posterior", "Patient Inferior to Superior", "Patient Superior to Inferior", desc="User defined Z-axis orientation (into the screen)", argstr="--inUser3 %s") inUser4 = traits.Enum("Axial", "Coronal", "Sagittal", "Unknown", desc="User defined Image Orientation", argstr="--inUser4 %s") inInterpolation = traits.Enum("Nearest Neighbor", "Trilinear", "Bspline 3rd order", "Bspline 4th order", "Cubic Lagrangian", "Quintic Lagrangian", "Heptic Lagrangian", "Windowed Sinc", desc="Interpolation", argstr="--inInterpolation %s") inResolution = traits.Enum("Unchanged", "Finest cubic", "Coarsest cubic", "Same as template", desc="Resolution", argstr="--inResolution %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outReoriented = InputMultiPath(File, desc="Reoriented Volume", sep=";", argstr="--outReoriented %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmMipavReorientOutputSpec(TraitedSpec): pass class MedicAlgorithmMipavReorient(SEMLikeCommandLine): """title: Reorient Volume category: Developer Tools description: Reorient a volume to a particular anatomical orientation. version: .alpha """ input_spec = MedicAlgorithmMipavReorientInputSpec output_spec = MedicAlgorithmMipavReorientOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.utilities.volume.MedicAlgorithmMipavReorient " _outputs_filenames = {} _redirect_x = True class MedicAlgorithmSPECTRE2010InputSpec(CommandLineInputSpec): inInput = File(desc="Input volume to be skullstripped.", exists=True, argstr="--inInput %s") inAtlas = File(desc="SPECTRE atlas description file. A text file enumerating atlas files and landmarks.", exists=True, argstr="--inAtlas %s") inInitial = traits.Int(desc="Erosion of the inital mask, which is based on the probability mask and the classification., The initial mask is ouput as the d0 volume at the conclusion of SPECTRE.", argstr="--inInitial %d") inImage = traits.Enum("T1_SPGR", "T1_ALT", "T1_MPRAGE", "T2", "FLAIR", desc="Set the image modality. MP-RAGE is recommended for most T1 sequence images.", argstr="--inImage %s") inOutput = traits.Enum("true", "false", desc="Determines if the output results are transformed back into the space of the original input image.", argstr="--inOutput %s") inFind = traits.Enum("true", "false", desc="Find Midsaggital Plane", argstr="--inFind %s") inRun = traits.Enum("true", "false", desc="Run Smooth Brain Mask", argstr="--inRun %s") inResample = traits.Enum("true", "false", desc="Determines if the data is resampled to be isotropic during the processing.", argstr="--inResample %s") inInitial2 = traits.Float(desc="Initial probability threshold", argstr="--inInitial2 %f") inMinimum = traits.Float(desc="Minimum probability threshold", argstr="--inMinimum %f") inMMC = traits.Int(desc="The size of the dilation step within the Modified Morphological Closing.", argstr="--inMMC %d") inMMC2 = traits.Int(desc="The size of the erosion step within the Modified Morphological Closing.", argstr="--inMMC2 %d") inInhomogeneity = traits.Enum("true", "false", desc="Set to false by default, this parameter will make FANTASM try to do inhomogeneity correction during it's iterative cycle.", argstr="--inInhomogeneity %s") inSmoothing = traits.Float(argstr="--inSmoothing %f") inBackground = traits.Float(argstr="--inBackground %f") inOutput2 = traits.Enum("true", "false", desc="Output Plane?", argstr="--inOutput2 %s") inOutput3 = traits.Enum("true", "false", desc="Output Split-Halves?", argstr="--inOutput3 %s") inOutput4 = traits.Enum("true", "false", desc="Output Segmentation on Plane?", argstr="--inOutput4 %s") inDegrees = traits.Enum("Rigid - 6", "Global rescale - 7", "Specific rescale - 9", "Affine - 12", desc="Degrees of freedom", argstr="--inDegrees %s") inCost = traits.Enum("Correlation ratio", "Least squares", "Normalized cross correlation", "Normalized mutual information", desc="Cost function", argstr="--inCost %s") inRegistration = traits.Enum("Trilinear", "Bspline 3rd order", "Bspline 4th order", "Cubic Lagrangian", "Quintic Lagrangian", "Heptic Lagrangian", "Windowed sinc", desc="Registration interpolation", argstr="--inRegistration %s") inOutput5 = traits.Enum("Trilinear", "Bspline 3rd order", "Bspline 4th order", "Cubic Lagrangian", "Quintic Lagrangian", "Heptic Lagrangian", "Windowed sinc", "Nearest Neighbor", desc="Output interpolation", argstr="--inOutput5 %s") inApply = traits.Enum("All", "X", "Y", "Z", desc="Apply rotation", argstr="--inApply %s") inMinimum2 = traits.Float(desc="Minimum angle", argstr="--inMinimum2 %f") inMaximum = traits.Float(desc="Maximum angle", argstr="--inMaximum %f") inCoarse = traits.Float(desc="Coarse angle increment", argstr="--inCoarse %f") inFine = traits.Float(desc="Fine angle increment", argstr="--inFine %f") inMultiple = traits.Int(desc="Multiple of tolerance to bracket the minimum", argstr="--inMultiple %d") inNumber = traits.Int(desc="Number of iterations", argstr="--inNumber %d") inNumber2 = traits.Int(desc="Number of minima from Level 8 to test at Level 4", argstr="--inNumber2 %d") inUse = traits.Enum("true", "false", desc="Use the max of the min resolutions of the two datasets when resampling", argstr="--inUse %s") inSubsample = traits.Enum("true", "false", desc="Subsample image for speed", argstr="--inSubsample %s") inSkip = traits.Enum("true", "false", desc="Skip multilevel search (Assume images are close to alignment)", argstr="--inSkip %s") inMultithreading = traits.Enum("true", "false", desc="Set to false by default, this parameter controls the multithreaded behavior of the linear registration.", argstr="--inMultithreading %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outOriginal = traits.Either(traits.Bool, File(), hash_files=False, desc="If Output in Original Space Flag is true then outputs the original input volume. Otherwise outputs the axialy reoriented input volume.", argstr="--outOriginal %s") outStripped = traits.Either(traits.Bool, File(), hash_files=False, desc="Skullstripped result of the input volume with just the brain.", argstr="--outStripped %s") outMask = traits.Either(traits.Bool, File(), hash_files=False, desc="Binary Mask of the skullstripped result with just the brain", argstr="--outMask %s") outPrior = traits.Either(traits.Bool, File(), hash_files=False, desc="Probability prior from the atlas registrations", argstr="--outPrior %s") outFANTASM = traits.Either(traits.Bool, File(), hash_files=False, desc="Tissue classification of of the whole input volume.", argstr="--outFANTASM %s") outd0 = traits.Either(traits.Bool, File(), hash_files=False, desc="Initial Brainmask", argstr="--outd0 %s") outMidsagittal = traits.Either(traits.Bool, File(), hash_files=False, desc="Plane dividing the brain hemispheres", argstr="--outMidsagittal %s") outSplitHalves = traits.Either(traits.Bool, File(), hash_files=False, desc="Skullstripped mask of the brain with the hemispheres divided.", argstr="--outSplitHalves %s") outSegmentation = traits.Either(traits.Bool, File(), hash_files=False, desc="2D image showing the tissue classification on the midsagittal plane", argstr="--outSegmentation %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmSPECTRE2010OutputSpec(TraitedSpec): outOriginal = File(desc="If Output in Original Space Flag is true then outputs the original input volume. Otherwise outputs the axialy reoriented input volume.", exists=True) outStripped = File(desc="Skullstripped result of the input volume with just the brain.", exists=True) outMask = File(desc="Binary Mask of the skullstripped result with just the brain", exists=True) outPrior = File(desc="Probability prior from the atlas registrations", exists=True) outFANTASM = File(desc="Tissue classification of of the whole input volume.", exists=True) outd0 = File(desc="Initial Brainmask", exists=True) outMidsagittal = File(desc="Plane dividing the brain hemispheres", exists=True) outSplitHalves = File(desc="Skullstripped mask of the brain with the hemispheres divided.", exists=True) outSegmentation = File(desc="2D image showing the tissue classification on the midsagittal plane", exists=True) class MedicAlgorithmSPECTRE2010(SEMLikeCommandLine): """title: SPECTRE 2010 category: Developer Tools description: Simple Paradigm for Extra-Cranial Tissue REmoval ################################################ Algorithm Version: 1.6 GUI Version: 1.10 A. Carass, M.B. Wheeler, J. Cuzzocreo, P.-L. Bazin, S.S. Bassett, and J.L. Prince, 'A Joint Registration and Segmentation Approach to Skull Stripping', Fourth IEEE International Symposium on Biomedical Imaging (ISBI 2007), Arlington, VA, April 12-15, 2007. A. Carass, J. Cuzzocreo, M.B. Wheeler, P.-L. Bazin, S.M. Resnick, and J.L. Prince, 'Simple paradigm for extra-cerebral tissue removal: Algorithm and analysis', NeuroImage 56(4):1982-1992, 2011. version: 1.6.R documentation-url: http://www.iacl.ece.jhu.edu/ contributor: Aaron Carass (aaron_carass@jhu.edu) http://www.iacl.ece.jhu.edu/ Hanlin Wan (hanlinwan@gmail.com) """ input_spec = MedicAlgorithmSPECTRE2010InputSpec output_spec = MedicAlgorithmSPECTRE2010OutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.segmentation.skull_strip.MedicAlgorithmSPECTRE2010 " _outputs_filenames = {'outd0':'outd0.nii','outOriginal':'outOriginal.nii','outMask':'outMask.nii','outSplitHalves':'outSplitHalves.nii','outMidsagittal':'outMidsagittal.nii','outPrior':'outPrior.nii','outFANTASM':'outFANTASM.nii','outSegmentation':'outSegmentation.nii','outStripped':'outStripped.nii'} _redirect_x = True class JistBrainPartialVolumeFilterInputSpec(CommandLineInputSpec): inInput = File(desc="Input Image", exists=True, argstr="--inInput %s") inPV = traits.Enum("bright", "dark", "both", desc="Outputs the raw intensity values or a probability score for the partial volume regions.", argstr="--inPV %s") inoutput = traits.Enum("probability", "intensity", desc="output", argstr="--inoutput %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outPartial = traits.Either(traits.Bool, File(), hash_files=False, desc="Partial Volume Image", argstr="--outPartial %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistBrainPartialVolumeFilterOutputSpec(TraitedSpec): outPartial = File(desc="Partial Volume Image", exists=True) class JistBrainPartialVolumeFilter(SEMLikeCommandLine): """title: Partial Volume Filter category: Developer Tools description: Filters an image for regions of partial voluming assuming a ridge-like model of intensity. version: 2.0.RC """ input_spec = JistBrainPartialVolumeFilterInputSpec output_spec = JistBrainPartialVolumeFilterOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.brain.JistBrainPartialVolumeFilter " _outputs_filenames = {'outPartial':'outPartial.nii'} _redirect_x = True class JistIntensityMp2rageMaskingInputSpec(CommandLineInputSpec): inSecond = File(desc="Second inversion (Inv2) Image", exists=True, argstr="--inSecond %s") inQuantitative = File(desc="Quantitative T1 Map (T1_Images) Image", exists=True, argstr="--inQuantitative %s") inT1weighted = File(desc="T1-weighted (UNI) Image", exists=True, argstr="--inT1weighted %s") inBackground = traits.Enum("exponential", "half-normal", desc="Model distribution for background noise (default is half-normal, exponential is more stringent).", argstr="--inBackground %s") inSkip = traits.Enum("true", "false", desc="Skip zero values", argstr="--inSkip %s") inMasking = traits.Enum("binary", "proba", desc="Whether to use a binary threshold or a weighted average based on the probability.", argstr="--inMasking %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outSignal = traits.Either(traits.Bool, File(), hash_files=False, desc="Signal Proba Image", argstr="--outSignal %s") outSignal2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Signal Mask Image", argstr="--outSignal2 %s") outMasked = traits.Either(traits.Bool, File(), hash_files=False, desc="Masked T1 Map Image", argstr="--outMasked %s") outMasked2 = traits.Either(traits.Bool, File(), hash_files=False, desc="Masked Iso Image", argstr="--outMasked2 %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class JistIntensityMp2rageMaskingOutputSpec(TraitedSpec): outSignal = File(desc="Signal Proba Image", exists=True) outSignal2 = File(desc="Signal Mask Image", exists=True) outMasked = File(desc="Masked T1 Map Image", exists=True) outMasked2 = File(desc="Masked Iso Image", exists=True) class JistIntensityMp2rageMasking(SEMLikeCommandLine): """title: MP2RAGE Background Masking category: Developer Tools description: Estimate a background signal mask for a MP2RAGE dataset. version: 3.0.RC """ input_spec = JistIntensityMp2rageMaskingInputSpec output_spec = JistIntensityMp2rageMaskingOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run de.mpg.cbs.jist.intensity.JistIntensityMp2rageMasking " _outputs_filenames = {'outSignal2':'outSignal2.nii','outSignal':'outSignal.nii','outMasked2':'outMasked2.nii','outMasked':'outMasked.nii'} _redirect_x = True class MedicAlgorithmThresholdToBinaryMaskInputSpec(CommandLineInputSpec): inLabel = InputMultiPath(File, desc="Input volumes", sep=";", argstr="--inLabel %s") inMinimum = traits.Float(desc="Minimum threshold value.", argstr="--inMinimum %f") inMaximum = traits.Float(desc="Maximum threshold value.", argstr="--inMaximum %f") inUse = traits.Enum("true", "false", desc="Use the images max intensity as the max value of the range.", argstr="--inUse %s") xPrefExt = traits.Enum("nrrd", desc="Output File Type", argstr="--xPrefExt %s") outBinary = InputMultiPath(File, desc="Binary Mask", sep=";", argstr="--outBinary %s") null = traits.Str(desc="Execution Time", argstr="--null %s") xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d") xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True) class MedicAlgorithmThresholdToBinaryMaskOutputSpec(TraitedSpec): pass class MedicAlgorithmThresholdToBinaryMask(SEMLikeCommandLine): """title: Threshold to Binary Mask category: Developer Tools description: Given a volume and an intensity range create a binary mask for values within that range. version: 1.2.RC documentation-url: http://www.iacl.ece.jhu.edu/ """ input_spec = MedicAlgorithmThresholdToBinaryMaskInputSpec output_spec = MedicAlgorithmThresholdToBinaryMaskOutputSpec _cmd = "java edu.jhu.ece.iacl.jist.cli.run edu.jhu.ece.iacl.plugins.utilities.volume.MedicAlgorithmThresholdToBinaryMask " _outputs_filenames = {} _redirect_x = True nipype-0.11.0/nipype/interfaces/mipav/generate_classes.py000066400000000000000000000050531257611314500235310ustar00rootroot00000000000000from nipype.interfaces.slicer.generate_classes import generate_all_classes if __name__ == "__main__": ## NOTE: For now either the launcher needs to be found on the default path, or ## every tool in the modules list must be found on the default path ## AND calling the module with --xml must be supported and compliant. modules_list = ['edu.jhu.bme.smile.demo.RandomVol', 'de.mpg.cbs.jist.laminar.JistLaminarProfileCalculator', 'de.mpg.cbs.jist.laminar.JistLaminarProfileSampling', 'de.mpg.cbs.jist.laminar.JistLaminarROIAveraging', 'de.mpg.cbs.jist.laminar.JistLaminarVolumetricLayering', 'de.mpg.cbs.jist.laminar.JistLaminarProfileGeometry', 'de.mpg.cbs.jist.brain.JistBrainMgdmSegmentation', 'de.mpg.cbs.jist.brain.JistBrainMp2rageSkullStripping', 'de.mpg.cbs.jist.brain.JistBrainPartialVolumeFilter', 'de.mpg.cbs.jist.brain.JistBrainMp2rageDuraEstimation'] modules_from_chris = ['edu.jhu.ece.iacl.plugins.segmentation.skull_strip.MedicAlgorithmSPECTRE2010', 'edu.jhu.ece.iacl.plugins.utilities.volume.MedicAlgorithmMipavReorient', 'edu.jhu.ece.iacl.plugins.utilities.math.MedicAlgorithmImageCalculator', 'de.mpg.cbs.jist.brain.JistBrainMp2rageDuraEstimation', 'de.mpg.cbs.jist.brain.JistBrainPartialVolumeFilter', 'edu.jhu.ece.iacl.plugins.utilities.volume.MedicAlgorithmThresholdToBinaryMask', #'de.mpg.cbs.jist.cortex.JistCortexFullCRUISE', # waiting for http://www.nitrc.org/tracker/index.php?func=detail&aid=7236&group_id=228&atid=942 to be fixed 'de.mpg.cbs.jist.cortex.JistCortexSurfaceMeshInflation'] modules_from_julia = ['de.mpg.cbs.jist.intensity.JistIntensityMp2rageMasking', 'edu.jhu.ece.iacl.plugins.segmentation.skull_strip.MedicAlgorithmSPECTRE2010'] modules_from_leonie = ['edu.jhu.ece.iacl.plugins.classification.MedicAlgorithmLesionToads'] modules_from_yasinyazici = ['edu.jhu.ece.iacl.plugins.classification.MedicAlgorithmN3'] modules_list = list(set(modules_list).union(modules_from_chris).union(modules_from_leonie).union(modules_from_julia).union(modules_from_yasinyazici).union(modules_list)) generate_all_classes(modules_list=modules_list,launcher=["java edu.jhu.ece.iacl.jist.cli.run" ], redirect_x=True, mipav_hacks=True) nipype-0.11.0/nipype/interfaces/mipav/tests/000077500000000000000000000000001257611314500210075ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistBrainMgdmSegmentation.py000066400000000000000000000045111257611314500305210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistBrainMgdmSegmentation def test_JistBrainMgdmSegmentation_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inAdjust=dict(argstr='--inAdjust %s', ), inAtlas=dict(argstr='--inAtlas %s', ), inCompute=dict(argstr='--inCompute %s', ), inCurvature=dict(argstr='--inCurvature %f', ), inData=dict(argstr='--inData %f', ), inFLAIR=dict(argstr='--inFLAIR %s', ), inMP2RAGE=dict(argstr='--inMP2RAGE %s', ), inMP2RAGE2=dict(argstr='--inMP2RAGE2 %s', ), inMPRAGE=dict(argstr='--inMPRAGE %s', ), inMax=dict(argstr='--inMax %d', ), inMin=dict(argstr='--inMin %f', ), inOutput=dict(argstr='--inOutput %s', ), inPV=dict(argstr='--inPV %s', ), inPosterior=dict(argstr='--inPosterior %f', ), inSteps=dict(argstr='--inSteps %d', ), inTopology=dict(argstr='--inTopology %s', ), null=dict(argstr='--null %s', ), outLevelset=dict(argstr='--outLevelset %s', hash_files=False, ), outPosterior2=dict(argstr='--outPosterior2 %s', hash_files=False, ), outPosterior3=dict(argstr='--outPosterior3 %s', hash_files=False, ), outSegmented=dict(argstr='--outSegmented %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistBrainMgdmSegmentation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistBrainMgdmSegmentation_outputs(): output_map = dict(outLevelset=dict(), outPosterior2=dict(), outPosterior3=dict(), outSegmented=dict(), ) outputs = JistBrainMgdmSegmentation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistBrainMp2rageDuraEstimation.py000066400000000000000000000027241257611314500314310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistBrainMp2rageDuraEstimation def test_JistBrainMp2rageDuraEstimation_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inDistance=dict(argstr='--inDistance %f', ), inSecond=dict(argstr='--inSecond %s', ), inSkull=dict(argstr='--inSkull %s', ), inoutput=dict(argstr='--inoutput %s', ), null=dict(argstr='--null %s', ), outDura=dict(argstr='--outDura %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistBrainMp2rageDuraEstimation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistBrainMp2rageDuraEstimation_outputs(): output_map = dict(outDura=dict(), ) outputs = JistBrainMp2rageDuraEstimation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistBrainMp2rageSkullStripping.py000066400000000000000000000034451257611314500314740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistBrainMp2rageSkullStripping def test_JistBrainMp2rageSkullStripping_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inFilter=dict(argstr='--inFilter %s', ), inSecond=dict(argstr='--inSecond %s', ), inSkip=dict(argstr='--inSkip %s', ), inT1=dict(argstr='--inT1 %s', ), inT1weighted=dict(argstr='--inT1weighted %s', ), null=dict(argstr='--null %s', ), outBrain=dict(argstr='--outBrain %s', hash_files=False, ), outMasked=dict(argstr='--outMasked %s', hash_files=False, ), outMasked2=dict(argstr='--outMasked2 %s', hash_files=False, ), outMasked3=dict(argstr='--outMasked3 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistBrainMp2rageSkullStripping.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistBrainMp2rageSkullStripping_outputs(): output_map = dict(outBrain=dict(), outMasked=dict(), outMasked2=dict(), outMasked3=dict(), ) outputs = JistBrainMp2rageSkullStripping.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistBrainPartialVolumeFilter.py000066400000000000000000000026261257611314500312160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistBrainPartialVolumeFilter def test_JistBrainPartialVolumeFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inInput=dict(argstr='--inInput %s', ), inPV=dict(argstr='--inPV %s', ), inoutput=dict(argstr='--inoutput %s', ), null=dict(argstr='--null %s', ), outPartial=dict(argstr='--outPartial %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistBrainPartialVolumeFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistBrainPartialVolumeFilter_outputs(): output_map = dict(outPartial=dict(), ) outputs = JistBrainPartialVolumeFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistCortexSurfaceMeshInflation.py000066400000000000000000000033221257611314500315400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistCortexSurfaceMeshInflation def test_JistCortexSurfaceMeshInflation_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inLevelset=dict(argstr='--inLevelset %s', ), inLorentzian=dict(argstr='--inLorentzian %s', ), inMax=dict(argstr='--inMax %d', ), inMean=dict(argstr='--inMean %f', ), inSOR=dict(argstr='--inSOR %f', ), inStep=dict(argstr='--inStep %d', ), inTopology=dict(argstr='--inTopology %s', ), null=dict(argstr='--null %s', ), outInflated=dict(argstr='--outInflated %s', hash_files=False, ), outOriginal=dict(argstr='--outOriginal %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistCortexSurfaceMeshInflation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistCortexSurfaceMeshInflation_outputs(): output_map = dict(outInflated=dict(), outOriginal=dict(), ) outputs = JistCortexSurfaceMeshInflation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistIntensityMp2rageMasking.py000066400000000000000000000035501257611314500310230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistIntensityMp2rageMasking def test_JistIntensityMp2rageMasking_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inBackground=dict(argstr='--inBackground %s', ), inMasking=dict(argstr='--inMasking %s', ), inQuantitative=dict(argstr='--inQuantitative %s', ), inSecond=dict(argstr='--inSecond %s', ), inSkip=dict(argstr='--inSkip %s', ), inT1weighted=dict(argstr='--inT1weighted %s', ), null=dict(argstr='--null %s', ), outMasked=dict(argstr='--outMasked %s', hash_files=False, ), outMasked2=dict(argstr='--outMasked2 %s', hash_files=False, ), outSignal=dict(argstr='--outSignal %s', hash_files=False, ), outSignal2=dict(argstr='--outSignal2 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistIntensityMp2rageMasking.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistIntensityMp2rageMasking_outputs(): output_map = dict(outMasked=dict(), outMasked2=dict(), outSignal=dict(), outSignal2=dict(), ) outputs = JistIntensityMp2rageMasking.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistLaminarProfileCalculator.py000066400000000000000000000026431257611314500312250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistLaminarProfileCalculator def test_JistLaminarProfileCalculator_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inIntensity=dict(argstr='--inIntensity %s', ), inMask=dict(argstr='--inMask %s', ), incomputed=dict(argstr='--incomputed %s', ), null=dict(argstr='--null %s', ), outResult=dict(argstr='--outResult %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistLaminarProfileCalculator.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistLaminarProfileCalculator_outputs(): output_map = dict(outResult=dict(), ) outputs = JistLaminarProfileCalculator.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistLaminarProfileGeometry.py000066400000000000000000000030231257611314500307200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistLaminarProfileGeometry def test_JistLaminarProfileGeometry_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inProfile=dict(argstr='--inProfile %s', ), incomputed=dict(argstr='--incomputed %s', ), inoutside=dict(argstr='--inoutside %f', ), inregularization=dict(argstr='--inregularization %s', ), insmoothing=dict(argstr='--insmoothing %f', ), null=dict(argstr='--null %s', ), outResult=dict(argstr='--outResult %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistLaminarProfileGeometry.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistLaminarProfileGeometry_outputs(): output_map = dict(outResult=dict(), ) outputs = JistLaminarProfileGeometry.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistLaminarProfileSampling.py000066400000000000000000000030251257611314500307010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistLaminarProfileSampling def test_JistLaminarProfileSampling_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inCortex=dict(argstr='--inCortex %s', ), inIntensity=dict(argstr='--inIntensity %s', ), inProfile=dict(argstr='--inProfile %s', ), null=dict(argstr='--null %s', ), outProfile2=dict(argstr='--outProfile2 %s', hash_files=False, ), outProfilemapped=dict(argstr='--outProfilemapped %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistLaminarProfileSampling.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistLaminarProfileSampling_outputs(): output_map = dict(outProfile2=dict(), outProfilemapped=dict(), ) outputs = JistLaminarProfileSampling.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistLaminarROIAveraging.py000066400000000000000000000026471257611314500300740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistLaminarROIAveraging def test_JistLaminarROIAveraging_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inIntensity=dict(argstr='--inIntensity %s', ), inMask=dict(argstr='--inMask %s', ), inROI=dict(argstr='--inROI %s', ), inROI2=dict(argstr='--inROI2 %s', ), null=dict(argstr='--null %s', ), outROI3=dict(argstr='--outROI3 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistLaminarROIAveraging.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistLaminarROIAveraging_outputs(): output_map = dict(outROI3=dict(), ) outputs = JistLaminarROIAveraging.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_JistLaminarVolumetricLayering.py000066400000000000000000000037771257611314500314500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import JistLaminarVolumetricLayering def test_JistLaminarVolumetricLayering_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inInner=dict(argstr='--inInner %s', ), inLayering=dict(argstr='--inLayering %s', ), inLayering2=dict(argstr='--inLayering2 %s', ), inMax=dict(argstr='--inMax %d', ), inMin=dict(argstr='--inMin %f', ), inNumber=dict(argstr='--inNumber %d', ), inOuter=dict(argstr='--inOuter %s', ), inTopology=dict(argstr='--inTopology %s', ), incurvature=dict(argstr='--incurvature %d', ), inpresmooth=dict(argstr='--inpresmooth %s', ), inratio=dict(argstr='--inratio %f', ), null=dict(argstr='--null %s', ), outContinuous=dict(argstr='--outContinuous %s', hash_files=False, ), outDiscrete=dict(argstr='--outDiscrete %s', hash_files=False, ), outLayer=dict(argstr='--outLayer %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = JistLaminarVolumetricLayering.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JistLaminarVolumetricLayering_outputs(): output_map = dict(outContinuous=dict(), outDiscrete=dict(), outLayer=dict(), ) outputs = JistLaminarVolumetricLayering.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmImageCalculator.py000066400000000000000000000026521257611314500313220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmImageCalculator def test_MedicAlgorithmImageCalculator_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inOperation=dict(argstr='--inOperation %s', ), inVolume=dict(argstr='--inVolume %s', ), inVolume2=dict(argstr='--inVolume2 %s', ), null=dict(argstr='--null %s', ), outResult=dict(argstr='--outResult %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmImageCalculator.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmImageCalculator_outputs(): output_map = dict(outResult=dict(), ) outputs = MedicAlgorithmImageCalculator.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmLesionToads.py000066400000000000000000000060701257611314500305100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmLesionToads def test_MedicAlgorithmLesionToads_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inAtlas=dict(argstr='--inAtlas %s', ), inAtlas2=dict(argstr='--inAtlas2 %s', ), inAtlas3=dict(argstr='--inAtlas3 %s', ), inAtlas4=dict(argstr='--inAtlas4 %s', ), inAtlas5=dict(argstr='--inAtlas5 %f', ), inAtlas6=dict(argstr='--inAtlas6 %s', ), inConnectivity=dict(argstr='--inConnectivity %s', ), inCorrect=dict(argstr='--inCorrect %s', ), inFLAIR=dict(argstr='--inFLAIR %s', ), inInclude=dict(argstr='--inInclude %s', ), inMaximum=dict(argstr='--inMaximum %d', ), inMaximum2=dict(argstr='--inMaximum2 %d', ), inMaximum3=dict(argstr='--inMaximum3 %d', ), inMaximum4=dict(argstr='--inMaximum4 %f', ), inMaximum5=dict(argstr='--inMaximum5 %d', ), inOutput=dict(argstr='--inOutput %s', ), inOutput2=dict(argstr='--inOutput2 %s', ), inOutput3=dict(argstr='--inOutput3 %s', ), inSmooting=dict(argstr='--inSmooting %f', ), inT1_MPRAGE=dict(argstr='--inT1_MPRAGE %s', ), inT1_SPGR=dict(argstr='--inT1_SPGR %s', ), null=dict(argstr='--null %s', ), outCortical=dict(argstr='--outCortical %s', hash_files=False, ), outFilled=dict(argstr='--outFilled %s', hash_files=False, ), outHard=dict(argstr='--outHard %s', hash_files=False, ), outHard2=dict(argstr='--outHard2 %s', hash_files=False, ), outInhomogeneity=dict(argstr='--outInhomogeneity %s', hash_files=False, ), outLesion=dict(argstr='--outLesion %s', hash_files=False, ), outMembership=dict(argstr='--outMembership %s', hash_files=False, ), outSulcal=dict(argstr='--outSulcal %s', hash_files=False, ), outWM=dict(argstr='--outWM %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmLesionToads.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmLesionToads_outputs(): output_map = dict(outCortical=dict(), outFilled=dict(), outHard=dict(), outHard2=dict(), outInhomogeneity=dict(), outLesion=dict(), outMembership=dict(), outSulcal=dict(), outWM=dict(), ) outputs = MedicAlgorithmLesionToads.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmMipavReorient.py000066400000000000000000000032761257611314500310550ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmMipavReorient def test_MedicAlgorithmMipavReorient_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inInterpolation=dict(argstr='--inInterpolation %s', ), inNew=dict(argstr='--inNew %s', ), inResolution=dict(argstr='--inResolution %s', ), inSource=dict(argstr='--inSource %s', sep=';', ), inTemplate=dict(argstr='--inTemplate %s', ), inUser=dict(argstr='--inUser %s', ), inUser2=dict(argstr='--inUser2 %s', ), inUser3=dict(argstr='--inUser3 %s', ), inUser4=dict(argstr='--inUser4 %s', ), null=dict(argstr='--null %s', ), outReoriented=dict(argstr='--outReoriented %s', sep=';', ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmMipavReorient.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmMipavReorient_outputs(): output_map = dict() outputs = MedicAlgorithmMipavReorient.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmN3.py000066400000000000000000000034271257611314500265470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmN3 def test_MedicAlgorithmN3_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inAutomatic=dict(argstr='--inAutomatic %s', ), inEnd=dict(argstr='--inEnd %f', ), inField=dict(argstr='--inField %f', ), inInput=dict(argstr='--inInput %s', ), inKernel=dict(argstr='--inKernel %f', ), inMaximum=dict(argstr='--inMaximum %d', ), inSignal=dict(argstr='--inSignal %f', ), inSubsample=dict(argstr='--inSubsample %f', ), inWeiner=dict(argstr='--inWeiner %f', ), null=dict(argstr='--null %s', ), outInhomogeneity=dict(argstr='--outInhomogeneity %s', hash_files=False, ), outInhomogeneity2=dict(argstr='--outInhomogeneity2 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmN3.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmN3_outputs(): output_map = dict(outInhomogeneity=dict(), outInhomogeneity2=dict(), ) outputs = MedicAlgorithmN3.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmSPECTRE2010.py000066400000000000000000000073211257611314500276740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmSPECTRE2010 def test_MedicAlgorithmSPECTRE2010_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inApply=dict(argstr='--inApply %s', ), inAtlas=dict(argstr='--inAtlas %s', ), inBackground=dict(argstr='--inBackground %f', ), inCoarse=dict(argstr='--inCoarse %f', ), inCost=dict(argstr='--inCost %s', ), inDegrees=dict(argstr='--inDegrees %s', ), inFind=dict(argstr='--inFind %s', ), inFine=dict(argstr='--inFine %f', ), inImage=dict(argstr='--inImage %s', ), inInhomogeneity=dict(argstr='--inInhomogeneity %s', ), inInitial=dict(argstr='--inInitial %d', ), inInitial2=dict(argstr='--inInitial2 %f', ), inInput=dict(argstr='--inInput %s', ), inMMC=dict(argstr='--inMMC %d', ), inMMC2=dict(argstr='--inMMC2 %d', ), inMaximum=dict(argstr='--inMaximum %f', ), inMinimum=dict(argstr='--inMinimum %f', ), inMinimum2=dict(argstr='--inMinimum2 %f', ), inMultiple=dict(argstr='--inMultiple %d', ), inMultithreading=dict(argstr='--inMultithreading %s', ), inNumber=dict(argstr='--inNumber %d', ), inNumber2=dict(argstr='--inNumber2 %d', ), inOutput=dict(argstr='--inOutput %s', ), inOutput2=dict(argstr='--inOutput2 %s', ), inOutput3=dict(argstr='--inOutput3 %s', ), inOutput4=dict(argstr='--inOutput4 %s', ), inOutput5=dict(argstr='--inOutput5 %s', ), inRegistration=dict(argstr='--inRegistration %s', ), inResample=dict(argstr='--inResample %s', ), inRun=dict(argstr='--inRun %s', ), inSkip=dict(argstr='--inSkip %s', ), inSmoothing=dict(argstr='--inSmoothing %f', ), inSubsample=dict(argstr='--inSubsample %s', ), inUse=dict(argstr='--inUse %s', ), null=dict(argstr='--null %s', ), outFANTASM=dict(argstr='--outFANTASM %s', hash_files=False, ), outMask=dict(argstr='--outMask %s', hash_files=False, ), outMidsagittal=dict(argstr='--outMidsagittal %s', hash_files=False, ), outOriginal=dict(argstr='--outOriginal %s', hash_files=False, ), outPrior=dict(argstr='--outPrior %s', hash_files=False, ), outSegmentation=dict(argstr='--outSegmentation %s', hash_files=False, ), outSplitHalves=dict(argstr='--outSplitHalves %s', hash_files=False, ), outStripped=dict(argstr='--outStripped %s', hash_files=False, ), outd0=dict(argstr='--outd0 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmSPECTRE2010.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmSPECTRE2010_outputs(): output_map = dict(outFANTASM=dict(), outMask=dict(), outMidsagittal=dict(), outOriginal=dict(), outPrior=dict(), outSegmentation=dict(), outSplitHalves=dict(), outStripped=dict(), outd0=dict(), ) outputs = MedicAlgorithmSPECTRE2010.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_MedicAlgorithmThresholdToBinaryMask.py000066400000000000000000000027331257611314500325060ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import MedicAlgorithmThresholdToBinaryMask def test_MedicAlgorithmThresholdToBinaryMask_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inLabel=dict(argstr='--inLabel %s', sep=';', ), inMaximum=dict(argstr='--inMaximum %f', ), inMinimum=dict(argstr='--inMinimum %f', ), inUse=dict(argstr='--inUse %s', ), null=dict(argstr='--null %s', ), outBinary=dict(argstr='--outBinary %s', sep=';', ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = MedicAlgorithmThresholdToBinaryMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedicAlgorithmThresholdToBinaryMask_outputs(): output_map = dict() outputs = MedicAlgorithmThresholdToBinaryMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mipav/tests/test_auto_RandomVol.py000066400000000000000000000031351257611314500253530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mipav.developer import RandomVol def test_RandomVol_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inField=dict(argstr='--inField %s', ), inLambda=dict(argstr='--inLambda %f', ), inMaximum=dict(argstr='--inMaximum %d', ), inMinimum=dict(argstr='--inMinimum %d', ), inSize=dict(argstr='--inSize %d', ), inSize2=dict(argstr='--inSize2 %d', ), inSize3=dict(argstr='--inSize3 %d', ), inSize4=dict(argstr='--inSize4 %d', ), inStandard=dict(argstr='--inStandard %d', ), null=dict(argstr='--null %s', ), outRand1=dict(argstr='--outRand1 %s', hash_files=False, ), terminal_output=dict(nohash=True, ), xDefaultMem=dict(argstr='-xDefaultMem %d', ), xMaxProcess=dict(argstr='-xMaxProcess %d', usedefault=True, ), xPrefExt=dict(argstr='--xPrefExt %s', ), ) inputs = RandomVol.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_RandomVol_outputs(): output_map = dict(outRand1=dict(), ) outputs = RandomVol.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mne/000077500000000000000000000000001257611314500173105ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mne/__init__.py000066400000000000000000000000641257611314500214210ustar00rootroot00000000000000from nipype.interfaces.mne.base import WatershedBEM nipype-0.11.0/nipype/interfaces/mne/base.py000066400000000000000000000105651257611314500206030ustar00rootroot00000000000000from nipype.interfaces.base import (traits, File, Directory, TraitedSpec, OutputMultiPath) import os.path as op import glob from nipype.interfaces.freesurfer.base import FSCommand, FSTraitedSpec from nipype.utils.filemanip import list_to_filename from nipype.external import six import logging logging.basicConfig() iflogger = logging.getLogger('interface') class WatershedBEMInputSpec(FSTraitedSpec): subject_id = traits.Str(argstr='--subject %s', mandatory=True, desc='Subject ID (must have a complete Freesurfer directory)') subjects_dir = Directory(exists=True, mandatory=True, usedefault=True, desc='Path to Freesurfer subjects directory') volume = traits.Enum('T1', 'aparc+aseg', 'aseg', 'brain', 'orig', 'brainmask', 'ribbon', argstr='--volume %s', usedefault=True, desc='The volume from the "mri" directory to use (defaults to T1)') overwrite = traits.Bool(True, usedefault=True, argstr='--overwrite', desc='Overwrites the existing files') atlas_mode = traits.Bool(argstr='--atlas', desc='Use atlas mode for registration (default: no rigid alignment)') class WatershedBEMOutputSpec(TraitedSpec): mesh_files = OutputMultiPath(File(exists=True), desc=('Paths to the output meshes (brain, inner ' 'skull, outer skull, outer skin)')) brain_surface = File(exists=True, loc='bem/watershed', desc='Brain surface (in Freesurfer format)') inner_skull_surface = File(exists=True, loc='bem/watershed', desc='Inner skull surface (in Freesurfer format)') outer_skull_surface = File(exists=True, loc='bem/watershed', desc='Outer skull surface (in Freesurfer format)') outer_skin_surface = File(exists=True, loc='bem/watershed', desc='Outer skin surface (in Freesurfer format)') fif_file = File(exists=True, loc='bem', altkey='fif', desc='"fif" format file for EEG processing in MNE') cor_files = OutputMultiPath(File(exists=True), loc='bem/watershed/ws', altkey='COR', desc='"COR" format files') class WatershedBEM(FSCommand): """Uses mne_watershed_bem to get information from dicom directories Examples -------- >>> from nipype.interfaces.mne import WatershedBEM >>> bem = WatershedBEM() >>> bem.inputs.subject_id = 'subj1' >>> bem.inputs.subjects_dir = '.' >>> bem.cmdline 'mne_watershed_bem --overwrite --subject subj1 --volume T1' >>> bem.run() # doctest: +SKIP """ _cmd = 'mne_watershed_bem' input_spec = WatershedBEMInputSpec output_spec = WatershedBEMOutputSpec _additional_metadata = ['loc', 'altkey'] def _get_files(self, path, key, dirval, altkey=None): globsuffix = '*' globprefix = '*' keydir = op.join(path, dirval) if altkey: key = altkey globpattern = op.join(keydir, ''.join((globprefix, key, globsuffix))) return glob.glob(globpattern) def _list_outputs(self): outputs = self.output_spec().get() subjects_dir = self.inputs.subjects_dir subject_path = op.join(subjects_dir, self.inputs.subject_id) output_traits = self._outputs() mesh_paths = [] for k in outputs.keys(): if k != 'mesh_files': val = self._get_files(subject_path, k, output_traits.traits()[k].loc, output_traits.traits()[k].altkey) if val: value_list = list_to_filename(val) if isinstance(value_list, list): out_files = [] for value in value_list: out_files.append(op.abspath(value)) elif isinstance(value_list, six.string_types): out_files = op.abspath(value_list) else: raise TypeError outputs[k] = out_files if not k.rfind('surface') == -1: mesh_paths.append(out_files) outputs['mesh_files'] = mesh_paths return outputs nipype-0.11.0/nipype/interfaces/mne/tests/000077500000000000000000000000001257611314500204525ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mne/tests/test_auto_WatershedBEM.py000066400000000000000000000030431257611314500253650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mne.base import WatershedBEM def test_WatershedBEM_inputs(): input_map = dict(args=dict(argstr='%s', ), atlas_mode=dict(argstr='--atlas', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), overwrite=dict(argstr='--overwrite', usedefault=True, ), subject_id=dict(argstr='--subject %s', mandatory=True, ), subjects_dir=dict(mandatory=True, usedefault=True, ), terminal_output=dict(nohash=True, ), volume=dict(argstr='--volume %s', usedefault=True, ), ) inputs = WatershedBEM.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_WatershedBEM_outputs(): output_map = dict(brain_surface=dict(loc='bem/watershed', ), cor_files=dict(altkey='COR', loc='bem/watershed/ws', ), fif_file=dict(altkey='fif', loc='bem', ), inner_skull_surface=dict(loc='bem/watershed', ), mesh_files=dict(), outer_skin_surface=dict(loc='bem/watershed', ), outer_skull_surface=dict(loc='bem/watershed', ), ) outputs = WatershedBEM.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/000077500000000000000000000000001257611314500200565ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mrtrix/__init__.py000066400000000000000000000016311257611314500221700ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from .tracking import (Tracks2Prob, FilterTracks, StreamlineTrack, DiffusionTensorStreamlineTrack, SphericallyDeconvolutedStreamlineTrack, ProbabilisticSphericallyDeconvolutedStreamlineTrack) from .tensors import (FSL2MRTrix, ConstrainedSphericalDeconvolution, DWI2SphericalHarmonicsImage, EstimateResponseForSH, GenerateDirections, FindShPeaks, Directions2Amplitude) from .preprocess import (MRConvert, MRMultiply, MRTrixViewer, MRTrixInfo, GenerateWhiteMatterMask, DWI2Tensor, Tensor2ApparentDiffusion, Tensor2FractionalAnisotropy, Tensor2Vector, MedianFilter3D, Erode, Threshold) from .convert import MRTrix2TrackVisnipype-0.11.0/nipype/interfaces/mrtrix/convert.py000066400000000000000000000235771257611314500221260ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ # -*- coding: utf-8 -*- import os.path as op import nibabel as nb, nibabel.trackvis as trk import numpy as np from nibabel.trackvis import HeaderError from nibabel.volumeutils import native_code from ..base import (TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File, isdefined, traits) from ...utils.filemanip import split_filename from ...utils.misc import package_check from ...workflows.misc.utils import get_data_dims, get_vox_dims import warnings have_dipy = True try: package_check('dipy') except Exception, e: False else: from dipy.tracking.utils import move_streamlines, affine_from_fsl_mat_file from nibabel.orientations import aff2axcodes from ... import logging iflogger = logging.getLogger('interface') def transform_to_affine(streams, header, affine): rotation, scale = np.linalg.qr(affine) streams = move_streamlines(streams, rotation) scale[0:3,0:3] = np.dot(scale[0:3,0:3], np.diag(1./header['voxel_size'])) scale[0:3,3] = abs(scale[0:3,3]) streams = move_streamlines(streams, scale) return streams def read_mrtrix_tracks(in_file, as_generator=True): header = read_mrtrix_header(in_file) streamlines = read_mrtrix_streamlines(in_file, header, as_generator) return header, streamlines def read_mrtrix_header(in_file): fileobj = open(in_file,'r') header = {} iflogger.info('Reading header data...') for line in fileobj: if line == 'END\n': iflogger.info('Reached the end of the header!') break elif ': ' in line: line = line.replace('\n','') line = line.replace("'","") key = line.split(': ')[0] value = line.split(': ')[1] header[key] = value iflogger.info('...adding "{v}" to header for key "{k}"'.format(v=value,k=key)) fileobj.close() header['count'] = int(header['count'].replace('\n','')) header['offset'] = int(header['file'].replace('.','')) return header def read_mrtrix_streamlines(in_file, header, as_generator=True): offset = header['offset'] stream_count = header['count'] fileobj = open(in_file,'r') fileobj.seek(offset) endianness = native_code f4dt = np.dtype(endianness + 'f4') pt_cols = 3 bytesize = pt_cols*4 def points_per_track(offset): n_streams = 0 n_points = 0 track_points = [] iflogger.info('Identifying the number of points per tract...') all_str = fileobj.read() num_triplets = len(all_str)/bytesize pts = np.ndarray(shape=(num_triplets,pt_cols), dtype='f4',buffer=all_str) nonfinite_list = np.where(np.isfinite(pts[:,2]) == False) nonfinite_list = list(nonfinite_list[0])[0:-1] # Converts numpy array to list, removes the last value nonfinite_list_bytes = [offset+x*bytesize for x in nonfinite_list] for idx, value in enumerate(nonfinite_list): if idx == 0: track_points.append(nonfinite_list[idx]) else: track_points.append(nonfinite_list[idx]-nonfinite_list[idx-1]-1) return track_points, nonfinite_list def track_gen(track_points): n_streams = 0 iflogger.info('Reading tracks...') while True: try: n_pts = track_points[n_streams] except IndexError: break pts_str = fileobj.read(n_pts * bytesize) nan_str = fileobj.read(bytesize) if len(pts_str) < (n_pts * bytesize): if not n_streams == stream_count: raise HeaderError( 'Expecting %s points, found only %s' % ( stream_count, n_streams)) iflogger.error('Expecting %s points, found only %s' % ( stream_count, n_streams)) break pts = np.ndarray( shape = (n_pts, pt_cols), dtype = f4dt, buffer = pts_str) nan_pt = np.ndarray( shape = (1, pt_cols), dtype = f4dt, buffer = nan_str) if np.isfinite(nan_pt[0][0]): raise ValueError break xyz = pts[:,:3] yield xyz n_streams += 1 if n_streams == stream_count: iflogger.info('100% : {n} tracks read'.format(n=n_streams)) raise StopIteration if n_streams % (float(stream_count)/100) == 0: percent = int(float(n_streams)/float(stream_count)*100) iflogger.info('{p}% : {n} tracks read'.format(p=percent, n=n_streams)) track_points, nonfinite_list = points_per_track(offset) fileobj.seek(offset) streamlines = track_gen(track_points) if not as_generator: streamlines = list(streamlines) return streamlines class MRTrix2TrackVisInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc='The input file for the tracks in MRTrix (.tck) format') image_file = File(exists=True, desc='The image the tracks were generated from') matrix_file = File(exists=True, desc='A transformation matrix to apply to the tracts after they have been generated (from FLIRT - affine transformation from image_file to registration_image_file)') registration_image_file = File(exists=True, desc='The final image the tracks should be registered to.') out_filename = File('converted.trk', genfile=True, usedefault=True, desc='The output filename for the tracks in TrackVis (.trk) format') class MRTrix2TrackVisOutputSpec(TraitedSpec): out_file = File(exists=True) class MRTrix2TrackVis(BaseInterface): """ Converts MRtrix (.tck) tract files into TrackVis (.trk) format using functions from dipy Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> tck2trk = mrt.MRTrix2TrackVis() >>> tck2trk.inputs.in_file = 'dwi_CSD_tracked.tck' >>> tck2trk.inputs.image_file = 'diffusion.nii' >>> tck2trk.run() # doctest: +SKIP """ input_spec = MRTrix2TrackVisInputSpec output_spec = MRTrix2TrackVisOutputSpec def _run_interface(self, runtime): dx, dy, dz = get_data_dims(self.inputs.image_file) vx, vy, vz = get_vox_dims(self.inputs.image_file) image_file = nb.load(self.inputs.image_file) affine = image_file.get_affine() out_filename = op.abspath(self.inputs.out_filename) #Reads MRTrix tracks header, streamlines = read_mrtrix_tracks(self.inputs.in_file, as_generator=True) iflogger.info('MRTrix Header:') iflogger.info(header) # Writes to Trackvis trk_header = nb.trackvis.empty_header() trk_header['dim'] = [dx,dy,dz] trk_header['voxel_size'] = [vx,vy,vz] trk_header['n_count'] = header['count'] if isdefined(self.inputs.matrix_file) and isdefined(self.inputs.registration_image_file): iflogger.info('Applying transformation from matrix file {m}'.format(m=self.inputs.matrix_file)) xfm = np.genfromtxt(self.inputs.matrix_file) iflogger.info(xfm) registration_image_file = nb.load(self.inputs.registration_image_file) reg_affine = registration_image_file.get_affine() r_dx, r_dy, r_dz = get_data_dims(self.inputs.registration_image_file) r_vx, r_vy, r_vz = get_vox_dims(self.inputs.registration_image_file) iflogger.info('Using affine from registration image file {r}'.format(r=self.inputs.registration_image_file)) iflogger.info(reg_affine) trk_header['vox_to_ras'] = reg_affine trk_header['dim'] = [r_dx,r_dy,r_dz] trk_header['voxel_size'] = [r_vx,r_vy,r_vz] affine = np.dot(affine,np.diag(1./np.array([vx, vy, vz, 1]))) transformed_streamlines = transform_to_affine(streamlines, trk_header, affine) aff = affine_from_fsl_mat_file(xfm, [vx,vy,vz], [r_vx,r_vy,r_vz]) iflogger.info(aff) axcode = aff2axcodes(reg_affine) trk_header['voxel_order'] = axcode[0]+axcode[1]+axcode[2] final_streamlines = move_streamlines(transformed_streamlines, aff) trk_tracks = ((ii,None,None) for ii in final_streamlines) trk.write(out_filename, trk_tracks, trk_header) iflogger.info('Saving transformed Trackvis file as {out}'.format(out=out_filename)) iflogger.info('New TrackVis Header:') iflogger.info(trk_header) else: iflogger.info('Applying transformation from scanner coordinates to {img}'.format(img=self.inputs.image_file)) axcode = aff2axcodes(affine) trk_header['voxel_order'] = axcode[0]+axcode[1]+axcode[2] trk_header['vox_to_ras'] = affine transformed_streamlines = transform_to_affine(streamlines, trk_header, affine) trk_tracks = ((ii,None,None) for ii in transformed_streamlines) trk.write(out_filename, trk_tracks, trk_header) iflogger.info('Saving Trackvis file as {out}'.format(out=out_filename)) iflogger.info('TrackVis Header:') iflogger.info(trk_header) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = op.abspath(self.inputs.out_filename) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '.trk' nipype-0.11.0/nipype/interfaces/mrtrix/defhdr.mat000066400000000000000000000010251257611314500220130ustar00rootroot00000000000000MATLAB 5.0 MAT-file, Platform: GLNXA64, Created on: Mon Jul 18 07:53:57 2011 IMŤxśí–˝NĂ0€m*RŐ‰§&ĆVŚ0bµ¬Ćj-µvd‡ŇvâÁxŢ‘‘‘ q[׹P¨'ť¬»Ë—ű‰§MŮ; ¤U¬ Ś”˛ëmşTJħ?!GŢw «”»Ü*= ±¤j\ń•21S9âNÍe1V ”ĆÍ]_Ś„u•HéçZŚăŰižY“I›+aŢ?«RPĎ ·˘’ČJ'íD¦uý›JE2‘žbÝŔÜĆb QRç"Wj…Ś‚9©aôŠćÓÚȬ62ŻFÜ˝ČřAĘČ AĘČ)fÝ7wP}U żţČ0µč.(¤ zFVű2ńţp_¶üZHÇŰ7W˝ó Ď| áwžő0ě6âcŤ¸Eź›8şĆŃ%÷ţĹ|öAŁů<‘˙#Űą5“˘˙.©ź[âu5·rŘ}Ţhýéúü;Ţ·•ż-ń{‡}—ĂýÓë˛wÝ[ä Ďě=ĎŘô›ő˛µĽ íó'ß—-÷{®řĎ|~ˇŤňaĎ}—ů Gňëknipype-0.11.0/nipype/interfaces/mrtrix/preprocess.py000066400000000000000000000644021257611314500226230ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, InputMultiPath, isdefined from nipype.utils.filemanip import split_filename import os.path as op class MRConvertInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='voxel-order data filename') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output filename') extract_at_axis = traits.Enum(1,2,3, argstr='-coord %s', position=1, desc='"Extract data only at the coordinates specified. This option specifies the Axis. Must be used in conjunction with extract_at_coordinate.') extract_at_coordinate = traits.List(traits.Float, argstr='%s', sep=',', position=2, minlen=1, maxlen=3, desc='"Extract data only at the coordinates specified. This option specifies the coordinates. Must be used in conjunction with extract_at_axis. Three comma-separated numbers giving the size of each voxel in mm.') voxel_dims = traits.List(traits.Float, argstr='-vox %s', sep=',', position=3, minlen=3, maxlen=3, desc='Three comma-separated numbers giving the size of each voxel in mm.') output_datatype = traits.Enum("nii", "float", "char", "short", "int", "long", "double", argstr='-output %s', position=2, desc='"i.e. Bfloat". Can be "char", "short", "int", "long", "float" or "double"') #, usedefault=True) extension = traits.Enum("mif","nii", "float", "char", "short", "int", "long", "double", position=2, desc='"i.e. Bfloat". Can be "char", "short", "int", "long", "float" or "double"', usedefault=True) layout = traits.Enum("nii", "float", "char", "short", "int", "long", "double", argstr='-output %s', position=2, desc='specify the layout of the data in memory. The actual layout produced will depend on whether the output image format can support it.') resample = traits.Float(argstr='-scale %d', position=3, units='mm', desc='Apply scaling to the intensity values.') offset_bias = traits.Float(argstr='-scale %d', position=3, units='mm', desc='Apply offset to the intensity values.') replace_NaN_with_zero = traits.Bool(argstr='-zero', position=3, desc="Replace all NaN values with zero.") prs = traits.Bool(argstr='-prs', position=3, desc="Assume that the DW gradients are specified in the PRS frame (Siemens DICOM only).") class MRConvertOutputSpec(TraitedSpec): converted = File(exists=True, desc='path/name of 4D volume in voxel order') class MRConvert(CommandLine): """ Perform conversion between different file types and optionally extract a subset of the input image. If used correctly, this program can be a very useful workhorse. In addition to converting images between different formats, it can be used to extract specific studies from a data set, extract a specific region of interest, flip the images, or to scale the intensity of the images. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> mrconvert = mrt.MRConvert() >>> mrconvert.inputs.in_file = 'dwi_FA.mif' >>> mrconvert.inputs.out_filename = 'dwi_FA.nii' >>> mrconvert.run() # doctest: +SKIP """ _cmd = 'mrconvert' input_spec=MRConvertInputSpec output_spec=MRConvertOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['converted'] = self.inputs.out_filename if not isdefined(outputs['converted']): outputs['converted'] = op.abspath(self._gen_outfilename()) else: outputs['converted'] = op.abspath(outputs['converted']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) if isdefined(self.inputs.out_filename): outname = self.inputs.out_filename else: outname = name + '_mrconvert.' + self.inputs.extension return outname class DWI2TensorInputSpec(CommandLineInputSpec): in_file = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=-2, desc='Diffusion-weighted images') out_filename = File(name_template="%s_tensor.mif", name_source="in_file", output_name="tensor", argstr='%s', desc='Output tensor filename', position=-1) encoding_file = File(argstr='-grad %s', position=2, desc=('Encoding file supplied as a 4xN text file with ' 'each line is in the format [ X Y Z b ], where ' '[ X Y Z ] describe the direction of the applied ' 'gradient, and b gives the b-value in units ' '(1000 s/mm^2). See FSL2MRTrix()')) ignore_slice_by_volume = traits.List(traits.Int, argstr='-ignoreslices %s', sep=' ', position=2, minlen=2, maxlen=2, desc=('Requires two values (i.e. [34 ' '1] for [Slice Volume] Ignores ' 'the image slices specified ' 'when computing the tensor. ' 'Slice here means the z ' 'coordinate of the slice to be ' 'ignored.')) ignore_volumes = traits.List(traits.Int, argstr='-ignorevolumes %s', sep=' ', position=2, minlen=1, desc=('Requires two values (i.e. [2 5 6] for ' '[Volumes] Ignores the image volumes ' 'specified when computing the tensor.')) quiet = traits.Bool(argstr='-quiet', position=1, desc=("Do not display information messages or progress " "status.")) debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class DWI2TensorOutputSpec(TraitedSpec): tensor = File(exists=True, desc='path/name of output diffusion tensor image') class DWI2Tensor(CommandLine): """ Converts diffusion-weighted images to tensor images. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> dwi2tensor = mrt.DWI2Tensor() >>> dwi2tensor.inputs.in_file = 'dwi.mif' >>> dwi2tensor.inputs.encoding_file = 'encoding.txt' >>> dwi2tensor.cmdline 'dwi2tensor -grad encoding.txt dwi.mif dwi_tensor.mif' >>> dwi2tensor.run() # doctest: +SKIP """ _cmd = 'dwi2tensor' input_spec=DWI2TensorInputSpec output_spec=DWI2TensorOutputSpec class Tensor2VectorInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Diffusion tensor image') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output vector filename') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class Tensor2VectorOutputSpec(TraitedSpec): vector = File(exists=True, desc='the output image of the major eigenvectors of the diffusion tensor image.') class Tensor2Vector(CommandLine): """ Generates a map of the major eigenvectors of the tensors in each voxel. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> tensor2vector = mrt.Tensor2Vector() >>> tensor2vector.inputs.in_file = 'dwi_tensor.mif' >>> tensor2vector.run() # doctest: +SKIP """ _cmd = 'tensor2vector' input_spec=Tensor2VectorInputSpec output_spec=Tensor2VectorOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['vector'] = self.inputs.out_filename if not isdefined(outputs['vector']): outputs['vector'] = op.abspath(self._gen_outfilename()) else: outputs['vector'] = op.abspath(outputs['vector']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_vector.mif' class Tensor2FractionalAnisotropyInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Diffusion tensor image') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output Fractional Anisotropy filename') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class Tensor2FractionalAnisotropyOutputSpec(TraitedSpec): FA = File(exists=True, desc='the output image of the major eigenvectors of the diffusion tensor image.') class Tensor2FractionalAnisotropy(CommandLine): """ Generates a map of the fractional anisotropy in each voxel. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> tensor2FA = mrt.Tensor2FractionalAnisotropy() >>> tensor2FA.inputs.in_file = 'dwi_tensor.mif' >>> tensor2FA.run() # doctest: +SKIP """ _cmd = 'tensor2FA' input_spec=Tensor2FractionalAnisotropyInputSpec output_spec=Tensor2FractionalAnisotropyOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['FA'] = self.inputs.out_filename if not isdefined(outputs['FA']): outputs['FA'] = op.abspath(self._gen_outfilename()) else: outputs['FA'] = op.abspath(outputs['FA']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_FA.mif' class Tensor2ApparentDiffusionInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Diffusion tensor image') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output Fractional Anisotropy filename') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class Tensor2ApparentDiffusionOutputSpec(TraitedSpec): ADC = File(exists=True, desc='the output image of the major eigenvectors of the diffusion tensor image.') class Tensor2ApparentDiffusion(CommandLine): """ Generates a map of the apparent diffusion coefficient (ADC) in each voxel Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> tensor2ADC = mrt.Tensor2ApparentDiffusion() >>> tensor2ADC.inputs.in_file = 'dwi_tensor.mif' >>> tensor2ADC.run() # doctest: +SKIP """ _cmd = 'tensor2ADC' input_spec=Tensor2ApparentDiffusionInputSpec output_spec=Tensor2ApparentDiffusionOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['ADC'] = self.inputs.out_filename if not isdefined(outputs['ADC']): outputs['ADC'] = op.abspath(self._gen_outfilename()) else: outputs['ADC'] = op.abspath(outputs['ADC']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_ADC.mif' class MRMultiplyInputSpec(CommandLineInputSpec): in_files = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=-2, desc='Input images to be multiplied') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output image filename') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class MRMultiplyOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output image of the multiplication') class MRMultiply(CommandLine): """ Multiplies two images. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> MRmult = mrt.MRMultiply() >>> MRmult.inputs.in_files = ['dwi.mif', 'dwi_WMProb.mif'] >>> MRmult.run() # doctest: +SKIP """ _cmd = 'mrmult' input_spec=MRMultiplyInputSpec output_spec=MRMultiplyOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_filename if not isdefined(outputs['out_file']): outputs['out_file'] = op.abspath(self._gen_outfilename()) else: outputs['out_file'] = op.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_files[0]) return name + '_MRMult.mif' class MRTrixViewerInputSpec(CommandLineInputSpec): in_files = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=-2, desc='Input images to be viewed') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class MRTrixViewerOutputSpec(TraitedSpec): pass class MRTrixViewer(CommandLine): """ Loads the input images in the MRTrix Viewer. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> MRview = mrt.MRTrixViewer() >>> MRview.inputs.in_files = 'dwi.mif' >>> MRview.run() # doctest: +SKIP """ _cmd = 'mrview' input_spec=MRTrixViewerInputSpec output_spec=MRTrixViewerOutputSpec def _list_outputs(self): return class MRTrixInfoInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Input images to be read') class MRTrixInfoOutputSpec(TraitedSpec): pass class MRTrixInfo(CommandLine): """ Prints out relevant header information found in the image specified. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> MRinfo = mrt.MRTrixInfo() >>> MRinfo.inputs.in_file = 'dwi.mif' >>> MRinfo.run() # doctest: +SKIP """ _cmd = 'mrinfo' input_spec=MRTrixInfoInputSpec output_spec=MRTrixInfoOutputSpec def _list_outputs(self): return class GenerateWhiteMatterMaskInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='Diffusion-weighted images') binary_mask = File(exists=True, argstr='%s', mandatory=True, position = -2, desc='Binary brain mask') out_WMProb_filename = File(genfile=True, argstr='%s', position = -1, desc='Output WM probability image filename') encoding_file = File(exists=True, argstr='-grad %s', mandatory=True, position=1, desc='Gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). See FSL2MRTrix') noise_level_margin = traits.Float(argstr='-margin %s', desc='Specify the width of the margin on either side of the image to be used to estimate the noise level (default = 10)') class GenerateWhiteMatterMaskOutputSpec(TraitedSpec): WMprobabilitymap = File(exists=True, desc='WMprobabilitymap') class GenerateWhiteMatterMask(CommandLine): """ Generates a white matter probability mask from the DW images. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> genWM = mrt.GenerateWhiteMatterMask() >>> genWM.inputs.in_file = 'dwi.mif' >>> genWM.inputs.encoding_file = 'encoding.txt' >>> genWM.run() # doctest: +SKIP """ _cmd = 'gen_WM_mask' input_spec=GenerateWhiteMatterMaskInputSpec output_spec=GenerateWhiteMatterMaskOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['WMprobabilitymap'] = op.abspath(self._gen_outfilename()) return outputs def _gen_filename(self, name): if name is 'out_WMProb_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_WMProb.mif' class ErodeInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Input mask image to be eroded') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output image filename') number_of_passes = traits.Int(argstr='-npass %s', desc='the number of passes (default: 1)') dilate = traits.Bool(argstr='-dilate', position=1, desc="Perform dilation rather than erosion") quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class ErodeOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output image') class Erode(CommandLine): """ Erode (or dilates) a mask (i.e. binary) image Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> erode = mrt.Erode() >>> erode.inputs.in_file = 'mask.mif' >>> erode.run() # doctest: +SKIP """ _cmd = 'erode' input_spec=ErodeInputSpec output_spec=ErodeOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_filename if not isdefined(outputs['out_file']): outputs['out_file'] = op.abspath(self._gen_outfilename()) else: outputs['out_file'] = op.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_erode.mif' class ThresholdInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='The input image to be thresholded') out_filename = File(genfile=True, argstr='%s', position=-1, desc='The output binary image mask.') absolute_threshold_value = traits.Float(argstr='-abs %s', desc='Specify threshold value as absolute intensity.') percentage_threshold_value = traits.Float(argstr='-percent %s', desc='Specify threshold value as a percentage of the peak intensity in the input image.') invert = traits.Bool(argstr='-invert', position=1, desc="Invert output binary mask") replace_zeros_with_NaN = traits.Bool(argstr='-nan', position=1, desc="Replace all zero values with NaN") quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class ThresholdOutputSpec(TraitedSpec): out_file = File(exists=True, desc='The output binary image mask.') class Threshold(CommandLine): """ Create bitwise image by thresholding image intensity. By default, the threshold level is determined using a histogram analysis to cut out the background. Otherwise, the threshold intensity can be specified using command line options. Note that only the first study is used for thresholding. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> thresh = mrt.Threshold() >>> thresh.inputs.in_file = 'wm_mask.mif' >>> thresh.run() # doctest: +SKIP """ _cmd = 'threshold' input_spec=ThresholdInputSpec output_spec=ThresholdOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_filename if not isdefined(outputs['out_file']): outputs['out_file'] = op.abspath(self._gen_outfilename()) else: outputs['out_file'] = op.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_thresh.mif' class MedianFilter3DInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Input images to be smoothed') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output image filename') quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class MedianFilter3DOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output image') class MedianFilter3D(CommandLine): """ Smooth images using a 3x3x3 median filter. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> median3d = mrt.MedianFilter3D() >>> median3d.inputs.in_file = 'mask.mif' >>> median3d.run() # doctest: +SKIP """ _cmd = 'median3D' input_spec=MedianFilter3DInputSpec output_spec=MedianFilter3DOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_filename if not isdefined(outputs['out_file']): outputs['out_file'] = op.abspath(self._gen_outfilename()) else: outputs['out_file'] = op.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_median3D.mif' class MRTransformInputSpec(CommandLineInputSpec): in_files = InputMultiPath(File(exists=True), argstr='%s', mandatory=True, position=-2, desc='Input images to be transformed') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output image') invert = traits.Bool(argstr='-inverse', position=1, desc="Invert the specified transform before using it") replace_transform = traits.Bool(argstr='-replace', position=1, desc="replace the current transform by that specified, rather than applying it to the current transform") transformation_file = File(exists=True, argstr='-transform %s', position=1, desc='The transform to apply, in the form of a 4x4 ascii file.') template_image = File(exists=True, argstr='-template %s', position=1, desc='Reslice the input image to match the specified template image.') reference_image = File(exists=True, argstr='-reference %s', position=1, desc='in case the transform supplied maps from the input image onto a reference image, use this option to specify the reference. Note that this implicitly sets the -replace option.') flip_x = traits.Bool(argstr='-flipx', position=1, desc="assume the transform is supplied assuming a coordinate system with the x-axis reversed relative to the MRtrix convention (i.e. x increases from right to left). This is required to handle transform matrices produced by FSL's FLIRT command. This is only used in conjunction with the -reference option.") quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class MRTransformOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output image of the transformation') class MRTransform(CommandLine): """ Apply spatial transformations or reslice images Example ------- >>> MRxform = MRTransform() >>> MRxform.inputs.in_files = 'anat_coreg.mif' >>> MRxform.run() # doctest: +SKIP """ _cmd = 'mrtransform' input_spec=MRTransformInputSpec output_spec=MRTransformOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_filename if not isdefined(outputs['out_file']): outputs['out_file'] = op.abspath(self._gen_outfilename()) else: outputs['out_file'] = op.abspath(outputs['out_file']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_files[0]) return name + '_MRTransform.mif' nipype-0.11.0/nipype/interfaces/mrtrix/tensors.py000066400000000000000000000511351257611314500221320ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import (CommandLineInputSpec, CommandLine, BaseInterface, BaseInterfaceInputSpec, traits, File, TraitedSpec, Directory, InputMultiPath, OutputMultiPath, isdefined) from nipype.utils.filemanip import split_filename import os.path as op import numpy as np from ... import logging iflogger = logging.getLogger('interface') class DWI2SphericalHarmonicsImageInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='Diffusion-weighted images') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output filename') encoding_file = File(exists=True, argstr='-grad %s', mandatory=True, position=1, desc='Gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). See FSL2MRTrix') maximum_harmonic_order = traits.Float(argstr='-lmax %s', desc='set the maximum harmonic order for the output series. By default, the program will use the highest possible lmax given the number of diffusion-weighted images.') normalise = traits.Bool(argstr='-normalise', position=3, desc="normalise the DW signal to the b=0 image") class DWI2SphericalHarmonicsImageOutputSpec(TraitedSpec): spherical_harmonics_image = File(exists=True, desc='Spherical harmonics image') class DWI2SphericalHarmonicsImage(CommandLine): """ Convert base diffusion-weighted images to their spherical harmonic representation. This program outputs the spherical harmonic decomposition for the set measured signal attenuations. The signal attenuations are calculated by identifying the b-zero images from the diffusion encoding supplied (i.e. those with zero as the b-value), and dividing the remaining signals by the mean b-zero signal intensity. The spherical harmonic decomposition is then calculated by least-squares linear fitting. Note that this program makes use of implied symmetries in the diffusion profile. First, the fact the signal attenuation profile is real implies that it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)* (where * denotes the complex conjugate). Second, the diffusion profile should be antipodally symmetric (i.e. S(x) = S(-x)), implying that all odd l components should be zero. Therefore, this program only computes the even elements. Note that the spherical harmonics equations used here differ slightly from those conventionally used, in that the (-1)^m factor has been omitted. This should be taken into account in all subsequent calculations. Each volume in the output image corresponds to a different spherical harmonic component, according to the following convention: * [0] Y(0,0) * [1] Im {Y(2,2)} * [2] Im {Y(2,1)} * [3] Y(2,0) * [4] Re {Y(2,1)} * [5] Re {Y(2,2)} * [6] Im {Y(4,4)} * [7] Im {Y(4,3)} Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> dwi2SH = mrt.DWI2SphericalHarmonicsImage() >>> dwi2SH.inputs.in_file = 'diffusion.nii' >>> dwi2SH.inputs.encoding_file = 'encoding.txt' >>> dwi2SH.run() # doctest: +SKIP """ _cmd = 'dwi2SH' input_spec=DWI2SphericalHarmonicsImageInputSpec output_spec=DWI2SphericalHarmonicsImageOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['spherical_harmonics_image'] = self.inputs.out_filename if not isdefined(outputs['spherical_harmonics_image']): outputs['spherical_harmonics_image'] = op.abspath(self._gen_outfilename()) else: outputs['spherical_harmonics_image'] = op.abspath(outputs['spherical_harmonics_image']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_SH.mif' class ConstrainedSphericalDeconvolutionInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='diffusion-weighted image') response_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='the diffusion-weighted signal response function for a single fibre population (see EstimateResponse)') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output filename') mask_image = File(exists=True, argstr='-mask %s', position=2, desc='only perform computation within the specified binary brain mask image') encoding_file = File(exists=True, argstr='-grad %s', position=1, desc='Gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). See FSL2MRTrix') filter_file = File(exists=True, argstr='-filter %s', position=-2, desc='a text file containing the filtering coefficients for each even harmonic order.' \ 'the linear frequency filtering parameters used for the initial linear spherical deconvolution step (default = [ 1 1 1 0 0 ]).') lambda_value = traits.Float(argstr='-lambda %s', desc='the regularisation parameter lambda that controls the strength of the constraint (default = 1.0).') maximum_harmonic_order = traits.Int(argstr='-lmax %s', desc='set the maximum harmonic order for the output series. By default, the program will use the highest possible lmax given the number of diffusion-weighted images.') threshold_value = traits.Float(argstr='-threshold %s', desc='the threshold below which the amplitude of the FOD is assumed to be zero, expressed as a fraction of the mean value of the initial FOD (default = 0.1)') iterations = traits.Int(argstr='-niter %s', desc='the maximum number of iterations to perform for each voxel (default = 50)') debug = traits.Bool(argstr='-debug', desc='Display debugging messages.') directions_file = File(exists=True, argstr='-directions %s', position=-2, desc='a text file containing the [ el az ] pairs for the directions: Specify the directions over which to apply the non-negativity constraint (by default, the built-in 300 direction set is used)') normalise = traits.Bool(argstr='-normalise', position=3, desc="normalise the DW signal to the b=0 image") class ConstrainedSphericalDeconvolutionOutputSpec(TraitedSpec): spherical_harmonics_image = File(exists=True, desc='Spherical harmonics image') class ConstrainedSphericalDeconvolution(CommandLine): """ Perform non-negativity constrained spherical deconvolution. Note that this program makes use of implied symmetries in the diffusion profile. First, the fact the signal attenuation profile is real implies that it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)* (where * denotes the complex conjugate). Second, the diffusion profile should be antipodally symmetric (i.e. S(x) = S(-x)), implying that all odd l components should be zero. Therefore, this program only computes the even elements. Note that the spherical harmonics equations used here differ slightly from those conventionally used, in that the (-1)^m factor has been omitted. This should be taken into account in all subsequent calculations. Each volume in the output image corresponds to a different spherical harmonic component, according to the following convention: * [0] Y(0,0) * [1] Im {Y(2,2)} * [2] Im {Y(2,1)} * [3] Y(2,0) * [4] Re {Y(2,1)} * [5] Re {Y(2,2)} * [6] Im {Y(4,4)} * [7] Im {Y(4,3)} Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> csdeconv = mrt.ConstrainedSphericalDeconvolution() >>> csdeconv.inputs.in_file = 'dwi.mif' >>> csdeconv.inputs.encoding_file = 'encoding.txt' >>> csdeconv.run() # doctest: +SKIP """ _cmd = 'csdeconv' input_spec=ConstrainedSphericalDeconvolutionInputSpec output_spec=ConstrainedSphericalDeconvolutionOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['spherical_harmonics_image'] = self.inputs.out_filename if not isdefined(outputs['spherical_harmonics_image']): outputs['spherical_harmonics_image'] = op.abspath(self._gen_outfilename()) else: outputs['spherical_harmonics_image'] = op.abspath(outputs['spherical_harmonics_image']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_CSD.mif' class EstimateResponseForSHInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='Diffusion-weighted images') mask_image = File(exists=True, mandatory=True, argstr='%s', position=-2, desc='only perform computation within the specified binary brain mask image') out_filename = File(genfile=True, argstr='%s', position=-1, desc='Output filename') encoding_file = File(exists=True, argstr='-grad %s', mandatory=True, position=1, desc='Gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). See FSL2MRTrix') maximum_harmonic_order = traits.Int(argstr='-lmax %s', desc='set the maximum harmonic order for the output series. By default, the program will use the highest possible lmax given the number of diffusion-weighted images.') normalise = traits.Bool(argstr='-normalise', desc='normalise the DW signal to the b=0 image') quiet = traits.Bool(argstr='-quiet', desc='Do not display information messages or progress status.') debug = traits.Bool(argstr='-debug', desc='Display debugging messages.') class EstimateResponseForSHOutputSpec(TraitedSpec): response = File(exists=True, desc='Spherical harmonics image') class EstimateResponseForSH(CommandLine): """ Estimates the fibre response function for use in spherical deconvolution. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> estresp = mrt.EstimateResponseForSH() >>> estresp.inputs.in_file = 'dwi.mif' >>> estresp.inputs.mask_image = 'dwi_WMProb.mif' >>> estresp.inputs.encoding_file = 'encoding.txt' >>> estresp.run() # doctest: +SKIP """ _cmd = 'estimate_response' input_spec=EstimateResponseForSHInputSpec output_spec=EstimateResponseForSHOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['response'] = self.inputs.out_filename if not isdefined(outputs['response']): outputs['response'] = op.abspath(self._gen_outfilename()) else: outputs['response'] = op.abspath(outputs['response']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_ER.txt' def concat_files(bvec_file, bval_file, invert_x, invert_y, invert_z): bvecs = np.loadtxt(bvec_file) bvals = np.loadtxt(bval_file) flip = False if np.shape(bvecs)[0] > np.shape(bvecs)[1]: flip = True bvecs = np.transpose(bvecs) if invert_x: bvecs[0,:] = -bvecs[0,:] iflogger.info('Inverting b-vectors in the x direction') if invert_y: bvecs[1,:] = -bvecs[1,:] iflogger.info('Inverting b-vectors in the y direction') if invert_z: bvecs[2,:] = -bvecs[2,:] iflogger.info('Inverting b-vectors in the z direction') iflogger.info(np.shape(bvecs)) iflogger.info(np.shape(bvals)) encoding = np.transpose(np.vstack((bvecs,bvals))) _, bvec , _ = split_filename(bvec_file) _, bval , _ = split_filename(bval_file) out_encoding_file = bvec + '_' + bval + '.txt' np.savetxt(out_encoding_file, encoding) return out_encoding_file class FSL2MRTrixInputSpec(TraitedSpec): bvec_file = File(exists=True, mandatory=True, desc='FSL b-vectors file (3xN text file)') bval_file = File(exists=True, mandatory=True, desc='FSL b-values file (1xN text file)') invert_x = traits.Bool(False, usedefault=True, desc='Inverts the b-vectors along the x-axis') invert_y = traits.Bool(False, usedefault=True, desc='Inverts the b-vectors along the y-axis') invert_z = traits.Bool(False, usedefault=True, desc='Inverts the b-vectors along the z-axis') out_encoding_file = File(genfile=True, desc='Output encoding filename') class FSL2MRTrixOutputSpec(TraitedSpec): encoding_file = File(desc='The gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient' \ 'and b gives the b-value in units (1000 s/mm^2).') class FSL2MRTrix(BaseInterface): """ Converts separate b-values and b-vectors from text files (FSL style) into a 4xN text file in which each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> fsl2mrtrix = mrt.FSL2MRTrix() >>> fsl2mrtrix.inputs.bvec_file = 'bvecs' >>> fsl2mrtrix.inputs.bval_file = 'bvals' >>> fsl2mrtrix.inputs.invert_y = True >>> fsl2mrtrix.run() # doctest: +SKIP """ input_spec = FSL2MRTrixInputSpec output_spec = FSL2MRTrixOutputSpec def _run_interface(self, runtime): encoding = concat_files(self.inputs.bvec_file, self.inputs.bval_file, self.inputs.invert_x, self.inputs.invert_y, self.inputs.invert_z) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['encoding_file'] = op.abspath(self._gen_filename('out_encoding_file')) return outputs def _gen_filename(self, name): if name is 'out_encoding_file': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, bvec , _ = split_filename(self.inputs.bvec_file) _, bval , _ = split_filename(self.inputs.bval_file) return bvec + '_' + bval + '.txt' class GenerateDirectionsInputSpec(CommandLineInputSpec): num_dirs = traits.Int(mandatory=True, argstr='%s', position=-2 , desc='the number of directions to generate.') power = traits.Float(argstr='-power %s', desc='specify exponent to use for repulsion power law.') niter = traits.Int(argstr='-niter %s', desc='specify the maximum number of iterations to perform.') display_info = traits.Bool(argstr='-info', desc='Display information messages.') quiet_display = traits.Bool(argstr='-quiet', desc='do not display information messages or progress status.') display_debug = traits.Bool(argstr='-debug', desc='Display debugging messages.') out_file = File(name_source=['num_dirs'], name_template='directions_%d.txt', argstr='%s', hash_files=False, position= -1, desc='the text file to write the directions to, as [ az el ] pairs.') class GenerateDirectionsOutputSpec(TraitedSpec): out_file = File(exists=True, desc='directions file') class GenerateDirections(CommandLine): """ generate a set of directions evenly distributed over a hemisphere. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> gendir = mrt.GenerateDirections() >>> gendir.inputs.num_dirs = 300 >>> gendir.run() # doctest: +SKIP """ _cmd = 'gendir' input_spec=GenerateDirectionsInputSpec output_spec=GenerateDirectionsOutputSpec class FindShPeaksInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='the input image of SH coefficients.') directions_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='the set of directions to use as seeds for the peak finding') peaks_image = File(exists=True, argstr='-peaks %s', desc='the program will try to find the peaks that most closely match those in the image provided') num_peaks = traits.Int(argstr='-num %s', desc='the number of peaks to extract (default is 3)') peak_directions = traits.List(traits.Float, argstr='-direction %s', sep=' ', minlen=2, maxlen=2, desc='phi theta. the direction of a peak to estimate. The algorithm will attempt to find the same number of peaks as have been specified using this option ' \ ' phi: the azimuthal angle of the direction (in degrees). theta: the elevation angle of the direction (in degrees, from the vertical z-axis)') peak_threshold = traits.Float(argstr='-threshold %s', desc='only peak amplitudes greater than the threshold will be considered') display_info = traits.Bool(argstr='-info', desc='Display information messages.') quiet_display = traits.Bool(argstr='-quiet', desc='do not display information messages or progress status.') display_debug = traits.Bool(argstr='-debug', desc='Display debugging messages.') out_file = File(name_template="%s_peak_dirs.mif", keep_extension=False, argstr='%s', hash_files=False, position= -1, desc='the output image. Each volume corresponds to the x, y & z component of each peak direction vector in turn', name_source=["in_file"]) class FindShPeaksOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Peak directions image') class FindShPeaks(CommandLine): """ identify the orientations of the N largest peaks of a SH profile Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> shpeaks = mrt.FindShPeaks() >>> shpeaks.inputs.in_file = 'csd.mif' >>> shpeaks.inputs.directions_file = 'dirs.txt' >>> shpeaks.inputs.num_peaks = 2 >>> shpeaks.run() # doctest: +SKIP """ _cmd = 'find_SH_peaks' input_spec=FindShPeaksInputSpec output_spec=FindShPeaksOutputSpec class Directions2AmplitudeInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='the input directions image. Each volume corresponds to the x, y & z component of each direction vector in turn.') peaks_image = File(exists=True, argstr='-peaks %s', desc='the program will try to find the peaks that most closely match those in the image provided') num_peaks = traits.Int(argstr='-num %s', desc='the number of peaks to extract (default is 3)') peak_directions = traits.List(traits.Float, argstr='-direction %s', sep=' ', minlen=2, maxlen=2, desc='phi theta. the direction of a peak to estimate. The algorithm will attempt to find the same number of peaks as have been specified using this option ' \ ' phi: the azimuthal angle of the direction (in degrees). theta: the elevation angle of the direction (in degrees, from the vertical z-axis)') display_info = traits.Bool(argstr='-info', desc='Display information messages.') quiet_display = traits.Bool(argstr='-quiet', desc='do not display information messages or progress status.') display_debug = traits.Bool(argstr='-debug', desc='Display debugging messages.') out_file = File(name_template="%s_amplitudes.mif", keep_extension=False, argstr='%s', hash_files=False, position= -1, desc='the output amplitudes image', name_source=["in_file"]) class Directions2AmplitudeOutputSpec(TraitedSpec): out_file = File(exists=True, desc='amplitudes image') class Directions2Amplitude(CommandLine): """ convert directions image to amplitudes Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> amplitudes = mrt.Directions2Amplitude() >>> amplitudes.inputs.in_file = 'peak_directions.mif' >>> amplitudes.run() # doctest: +SKIP """ _cmd = 'dir2amp' input_spec=Directions2AmplitudeInputSpec output_spec=Directions2AmplitudeOutputSpec nipype-0.11.0/nipype/interfaces/mrtrix/tests/000077500000000000000000000000001257611314500212205ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_ConstrainedSphericalDeconvolution.py000066400000000000000000000034711257611314500325430ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import ConstrainedSphericalDeconvolution def test_ConstrainedSphericalDeconvolution_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', ), directions_file=dict(argstr='-directions %s', position=-2, ), encoding_file=dict(argstr='-grad %s', position=1, ), environ=dict(nohash=True, usedefault=True, ), filter_file=dict(argstr='-filter %s', position=-2, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), iterations=dict(argstr='-niter %s', ), lambda_value=dict(argstr='-lambda %s', ), mask_image=dict(argstr='-mask %s', position=2, ), maximum_harmonic_order=dict(argstr='-lmax %s', ), normalise=dict(argstr='-normalise', position=3, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), response_file=dict(argstr='%s', mandatory=True, position=-2, ), terminal_output=dict(nohash=True, ), threshold_value=dict(argstr='-threshold %s', ), ) inputs = ConstrainedSphericalDeconvolution.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ConstrainedSphericalDeconvolution_outputs(): output_map = dict(spherical_harmonics_image=dict(), ) outputs = ConstrainedSphericalDeconvolution.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_DWI2SphericalHarmonicsImage.py000066400000000000000000000025251257611314500310340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import DWI2SphericalHarmonicsImage def test_DWI2SphericalHarmonicsImage_inputs(): input_map = dict(args=dict(argstr='%s', ), encoding_file=dict(argstr='-grad %s', mandatory=True, position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), maximum_harmonic_order=dict(argstr='-lmax %s', ), normalise=dict(argstr='-normalise', position=3, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = DWI2SphericalHarmonicsImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWI2SphericalHarmonicsImage_outputs(): output_map = dict(spherical_harmonics_image=dict(), ) outputs = DWI2SphericalHarmonicsImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_DWI2Tensor.py000066400000000000000000000027161257611314500255670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import DWI2Tensor def test_DWI2Tensor_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), encoding_file=dict(argstr='-grad %s', position=2, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), ignore_slice_by_volume=dict(argstr='-ignoreslices %s', position=2, sep=' ', ), ignore_volumes=dict(argstr='-ignorevolumes %s', position=2, sep=' ', ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', name_source='in_file', name_template='%s_tensor.mif', output_name='tensor', position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = DWI2Tensor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWI2Tensor_outputs(): output_map = dict(tensor=dict(), ) outputs = DWI2Tensor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_DiffusionTensorStreamlineTrack.py000066400000000000000000000061011257611314500320110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import DiffusionTensorStreamlineTrack def test_DiffusionTensorStreamlineTrack_inputs(): input_map = dict(args=dict(argstr='%s', ), cutoff_value=dict(argstr='-cutoff %s', units='NA', ), desired_number_of_tracks=dict(argstr='-number %d', ), do_not_precompute=dict(argstr='-noprecomputed', ), environ=dict(nohash=True, usedefault=True, ), exclude_file=dict(argstr='-exclude %s', xor=['exclude_file', 'exclude_spec'], ), exclude_spec=dict(argstr='-exclude %s', position=2, sep=',', units='mm', xor=['exclude_file', 'exclude_spec'], ), gradient_encoding_file=dict(argstr='-grad %s', mandatory=True, position=-2, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), include_file=dict(argstr='-include %s', xor=['include_file', 'include_spec'], ), include_spec=dict(argstr='-include %s', position=2, sep=',', units='mm', xor=['include_file', 'include_spec'], ), initial_cutoff_value=dict(argstr='-initcutoff %s', units='NA', ), initial_direction=dict(argstr='-initdirection %s', units='voxels', ), inputmodel=dict(argstr='%s', position=-3, usedefault=True, ), mask_file=dict(argstr='-mask %s', xor=['mask_file', 'mask_spec'], ), mask_spec=dict(argstr='-mask %s', position=2, sep=',', units='mm', xor=['mask_file', 'mask_spec'], ), maximum_number_of_tracks=dict(argstr='-maxnum %d', ), maximum_tract_length=dict(argstr='-length %s', units='mm', ), minimum_radius_of_curvature=dict(argstr='-curvature %s', units='mm', ), minimum_tract_length=dict(argstr='-minlength %s', units='mm', ), no_mask_interpolation=dict(argstr='-nomaskinterp', ), out_file=dict(argstr='%s', name_source=['in_file'], name_template='%s_tracked.tck', output_name='tracked', position=-1, ), seed_file=dict(argstr='-seed %s', xor=['seed_file', 'seed_spec'], ), seed_spec=dict(argstr='-seed %s', position=2, sep=',', units='mm', xor=['seed_file', 'seed_spec'], ), step_size=dict(argstr='-step %s', units='mm', ), stop=dict(argstr='-stop', ), terminal_output=dict(nohash=True, ), unidirectional=dict(argstr='-unidirectional', ), ) inputs = DiffusionTensorStreamlineTrack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DiffusionTensorStreamlineTrack_outputs(): output_map = dict(tracked=dict(), ) outputs = DiffusionTensorStreamlineTrack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Directions2Amplitude.py000066400000000000000000000027351257611314500277220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import Directions2Amplitude def test_Directions2Amplitude_inputs(): input_map = dict(args=dict(argstr='%s', ), display_debug=dict(argstr='-debug', ), display_info=dict(argstr='-info', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), num_peaks=dict(argstr='-num %s', ), out_file=dict(argstr='%s', hash_files=False, keep_extension=False, name_source=['in_file'], name_template='%s_amplitudes.mif', position=-1, ), peak_directions=dict(argstr='-direction %s', sep=' ', ), peaks_image=dict(argstr='-peaks %s', ), quiet_display=dict(argstr='-quiet', ), terminal_output=dict(nohash=True, ), ) inputs = Directions2Amplitude.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Directions2Amplitude_outputs(): output_map = dict(out_file=dict(), ) outputs = Directions2Amplitude.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Erode.py000066400000000000000000000023471257611314500247250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import Erode def test_Erode_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), dilate=dict(argstr='-dilate', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), number_of_passes=dict(argstr='-npass %s', ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = Erode.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Erode_outputs(): output_map = dict(out_file=dict(), ) outputs = Erode.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_EstimateResponseForSH.py000066400000000000000000000026611257611314500300620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import EstimateResponseForSH def test_EstimateResponseForSH_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', ), encoding_file=dict(argstr='-grad %s', mandatory=True, position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), mask_image=dict(argstr='%s', mandatory=True, position=-2, ), maximum_harmonic_order=dict(argstr='-lmax %s', ), normalise=dict(argstr='-normalise', ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', ), terminal_output=dict(nohash=True, ), ) inputs = EstimateResponseForSH.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EstimateResponseForSH_outputs(): output_map = dict(response=dict(), ) outputs = EstimateResponseForSH.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_FSL2MRTrix.py000066400000000000000000000017051257611314500255000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import FSL2MRTrix def test_FSL2MRTrix_inputs(): input_map = dict(bval_file=dict(mandatory=True, ), bvec_file=dict(mandatory=True, ), invert_x=dict(usedefault=True, ), invert_y=dict(usedefault=True, ), invert_z=dict(usedefault=True, ), out_encoding_file=dict(genfile=True, ), ) inputs = FSL2MRTrix.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FSL2MRTrix_outputs(): output_map = dict(encoding_file=dict(), ) outputs = FSL2MRTrix.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_FilterTracks.py000066400000000000000000000035261257611314500262640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import FilterTracks def test_FilterTracks_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), exclude_file=dict(argstr='-exclude %s', xor=['exclude_file', 'exclude_spec'], ), exclude_spec=dict(argstr='-exclude %s', position=2, sep=',', units='mm', xor=['exclude_file', 'exclude_spec'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), include_file=dict(argstr='-include %s', xor=['include_file', 'include_spec'], ), include_spec=dict(argstr='-include %s', position=2, sep=',', units='mm', xor=['include_file', 'include_spec'], ), invert=dict(argstr='-invert', ), minimum_tract_length=dict(argstr='-minlength %s', units='mm', ), no_mask_interpolation=dict(argstr='-nomaskinterp', ), out_file=dict(argstr='%s', hash_files=False, name_source=['in_file'], name_template='%s_filt', position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = FilterTracks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FilterTracks_outputs(): output_map = dict(out_file=dict(), ) outputs = FilterTracks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_FindShPeaks.py000066400000000000000000000030701257611314500260200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import FindShPeaks def test_FindShPeaks_inputs(): input_map = dict(args=dict(argstr='%s', ), directions_file=dict(argstr='%s', mandatory=True, position=-2, ), display_debug=dict(argstr='-debug', ), display_info=dict(argstr='-info', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), num_peaks=dict(argstr='-num %s', ), out_file=dict(argstr='%s', hash_files=False, keep_extension=False, name_source=['in_file'], name_template='%s_peak_dirs.mif', position=-1, ), peak_directions=dict(argstr='-direction %s', sep=' ', ), peak_threshold=dict(argstr='-threshold %s', ), peaks_image=dict(argstr='-peaks %s', ), quiet_display=dict(argstr='-quiet', ), terminal_output=dict(nohash=True, ), ) inputs = FindShPeaks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FindShPeaks_outputs(): output_map = dict(out_file=dict(), ) outputs = FindShPeaks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_GenerateDirections.py000066400000000000000000000025561257611314500274470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tensors import GenerateDirections def test_GenerateDirections_inputs(): input_map = dict(args=dict(argstr='%s', ), display_debug=dict(argstr='-debug', ), display_info=dict(argstr='-info', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), niter=dict(argstr='-niter %s', ), num_dirs=dict(argstr='%s', mandatory=True, position=-2, ), out_file=dict(argstr='%s', hash_files=False, name_source=['num_dirs'], name_template='directions_%d.txt', position=-1, ), power=dict(argstr='-power %s', ), quiet_display=dict(argstr='-quiet', ), terminal_output=dict(nohash=True, ), ) inputs = GenerateDirections.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateDirections_outputs(): output_map = dict(out_file=dict(), ) outputs = GenerateDirections.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_GenerateWhiteMatterMask.py000066400000000000000000000025171257611314500304120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import GenerateWhiteMatterMask def test_GenerateWhiteMatterMask_inputs(): input_map = dict(args=dict(argstr='%s', ), binary_mask=dict(argstr='%s', mandatory=True, position=-2, ), encoding_file=dict(argstr='-grad %s', mandatory=True, position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), noise_level_margin=dict(argstr='-margin %s', ), out_WMProb_filename=dict(argstr='%s', genfile=True, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = GenerateWhiteMatterMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateWhiteMatterMask_outputs(): output_map = dict(WMprobabilitymap=dict(), ) outputs = GenerateWhiteMatterMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRConvert.py000066400000000000000000000033201257611314500255360ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MRConvert def test_MRConvert_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), extension=dict(position=2, usedefault=True, ), extract_at_axis=dict(argstr='-coord %s', position=1, ), extract_at_coordinate=dict(argstr='%s', position=2, sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), layout=dict(argstr='-output %s', position=2, ), offset_bias=dict(argstr='-scale %d', position=3, units='mm', ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), output_datatype=dict(argstr='-output %s', position=2, ), prs=dict(argstr='-prs', position=3, ), replace_NaN_with_zero=dict(argstr='-zero', position=3, ), resample=dict(argstr='-scale %d', position=3, units='mm', ), terminal_output=dict(nohash=True, ), voxel_dims=dict(argstr='-vox %s', position=3, sep=',', ), ) inputs = MRConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRConvert_outputs(): output_map = dict(converted=dict(), ) outputs = MRConvert.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRMultiply.py000066400000000000000000000022231257611314500257360ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MRMultiply def test_MRMultiply_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = MRMultiply.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRMultiply_outputs(): output_map = dict(out_file=dict(), ) outputs = MRMultiply.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRTransform.py000066400000000000000000000030511257611314500260720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MRTransform def test_MRTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), flip_x=dict(argstr='-flipx', position=1, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=-2, ), invert=dict(argstr='-inverse', position=1, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), reference_image=dict(argstr='-reference %s', position=1, ), replace_transform=dict(argstr='-replace', position=1, ), template_image=dict(argstr='-template %s', position=1, ), terminal_output=dict(nohash=True, ), transformation_file=dict(argstr='-transform %s', position=1, ), ) inputs = MRTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRTransform_outputs(): output_map = dict(out_file=dict(), ) outputs = MRTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRTrix2TrackVis.py000066400000000000000000000016221257611314500266000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.convert import MRTrix2TrackVis def test_MRTrix2TrackVis_inputs(): input_map = dict(image_file=dict(), in_file=dict(mandatory=True, ), matrix_file=dict(), out_filename=dict(genfile=True, usedefault=True, ), registration_image_file=dict(), ) inputs = MRTrix2TrackVis.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRTrix2TrackVis_outputs(): output_map = dict(out_file=dict(), ) outputs = MRTrix2TrackVis.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRTrixInfo.py000066400000000000000000000017021257611314500256620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MRTrixInfo def test_MRTrixInfo_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), terminal_output=dict(nohash=True, ), ) inputs = MRTrixInfo.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRTrixInfo_outputs(): output_map = dict() outputs = MRTrixInfo.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MRTrixViewer.py000066400000000000000000000020731257611314500262320ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MRTrixViewer def test_MRTrixViewer_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(argstr='%s', mandatory=True, position=-2, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = MRTrixViewer.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MRTrixViewer_outputs(): output_map = dict() outputs = MRTrixViewer.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_MedianFilter3D.py000066400000000000000000000022461257611314500264170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import MedianFilter3D def test_MedianFilter3D_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = MedianFilter3D.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedianFilter3D_outputs(): output_map = dict(out_file=dict(), ) outputs = MedianFilter3D.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_ProbabilisticSphericallyDeconvolutedStreamlineTrack.py000066400000000000000000000062111257611314500361550ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mrtrix/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import ProbabilisticSphericallyDeconvolutedStreamlineTrack def test_ProbabilisticSphericallyDeconvolutedStreamlineTrack_inputs(): input_map = dict(args=dict(argstr='%s', ), cutoff_value=dict(argstr='-cutoff %s', units='NA', ), desired_number_of_tracks=dict(argstr='-number %d', ), do_not_precompute=dict(argstr='-noprecomputed', ), environ=dict(nohash=True, usedefault=True, ), exclude_file=dict(argstr='-exclude %s', xor=['exclude_file', 'exclude_spec'], ), exclude_spec=dict(argstr='-exclude %s', position=2, sep=',', units='mm', xor=['exclude_file', 'exclude_spec'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), include_file=dict(argstr='-include %s', xor=['include_file', 'include_spec'], ), include_spec=dict(argstr='-include %s', position=2, sep=',', units='mm', xor=['include_file', 'include_spec'], ), initial_cutoff_value=dict(argstr='-initcutoff %s', units='NA', ), initial_direction=dict(argstr='-initdirection %s', units='voxels', ), inputmodel=dict(argstr='%s', position=-3, usedefault=True, ), mask_file=dict(argstr='-mask %s', xor=['mask_file', 'mask_spec'], ), mask_spec=dict(argstr='-mask %s', position=2, sep=',', units='mm', xor=['mask_file', 'mask_spec'], ), maximum_number_of_tracks=dict(argstr='-maxnum %d', ), maximum_number_of_trials=dict(argstr='-trials %s', ), maximum_tract_length=dict(argstr='-length %s', units='mm', ), minimum_radius_of_curvature=dict(argstr='-curvature %s', units='mm', ), minimum_tract_length=dict(argstr='-minlength %s', units='mm', ), no_mask_interpolation=dict(argstr='-nomaskinterp', ), out_file=dict(argstr='%s', name_source=['in_file'], name_template='%s_tracked.tck', output_name='tracked', position=-1, ), seed_file=dict(argstr='-seed %s', xor=['seed_file', 'seed_spec'], ), seed_spec=dict(argstr='-seed %s', position=2, sep=',', units='mm', xor=['seed_file', 'seed_spec'], ), step_size=dict(argstr='-step %s', units='mm', ), stop=dict(argstr='-stop', ), terminal_output=dict(nohash=True, ), unidirectional=dict(argstr='-unidirectional', ), ) inputs = ProbabilisticSphericallyDeconvolutedStreamlineTrack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProbabilisticSphericallyDeconvolutedStreamlineTrack_outputs(): output_map = dict(tracked=dict(), ) outputs = ProbabilisticSphericallyDeconvolutedStreamlineTrack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_SphericallyDeconvolutedStreamlineTrack.py000066400000000000000000000060121257611314500335240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import SphericallyDeconvolutedStreamlineTrack def test_SphericallyDeconvolutedStreamlineTrack_inputs(): input_map = dict(args=dict(argstr='%s', ), cutoff_value=dict(argstr='-cutoff %s', units='NA', ), desired_number_of_tracks=dict(argstr='-number %d', ), do_not_precompute=dict(argstr='-noprecomputed', ), environ=dict(nohash=True, usedefault=True, ), exclude_file=dict(argstr='-exclude %s', xor=['exclude_file', 'exclude_spec'], ), exclude_spec=dict(argstr='-exclude %s', position=2, sep=',', units='mm', xor=['exclude_file', 'exclude_spec'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), include_file=dict(argstr='-include %s', xor=['include_file', 'include_spec'], ), include_spec=dict(argstr='-include %s', position=2, sep=',', units='mm', xor=['include_file', 'include_spec'], ), initial_cutoff_value=dict(argstr='-initcutoff %s', units='NA', ), initial_direction=dict(argstr='-initdirection %s', units='voxels', ), inputmodel=dict(argstr='%s', position=-3, usedefault=True, ), mask_file=dict(argstr='-mask %s', xor=['mask_file', 'mask_spec'], ), mask_spec=dict(argstr='-mask %s', position=2, sep=',', units='mm', xor=['mask_file', 'mask_spec'], ), maximum_number_of_tracks=dict(argstr='-maxnum %d', ), maximum_tract_length=dict(argstr='-length %s', units='mm', ), minimum_radius_of_curvature=dict(argstr='-curvature %s', units='mm', ), minimum_tract_length=dict(argstr='-minlength %s', units='mm', ), no_mask_interpolation=dict(argstr='-nomaskinterp', ), out_file=dict(argstr='%s', name_source=['in_file'], name_template='%s_tracked.tck', output_name='tracked', position=-1, ), seed_file=dict(argstr='-seed %s', xor=['seed_file', 'seed_spec'], ), seed_spec=dict(argstr='-seed %s', position=2, sep=',', units='mm', xor=['seed_file', 'seed_spec'], ), step_size=dict(argstr='-step %s', units='mm', ), stop=dict(argstr='-stop', ), terminal_output=dict(nohash=True, ), unidirectional=dict(argstr='-unidirectional', ), ) inputs = SphericallyDeconvolutedStreamlineTrack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SphericallyDeconvolutedStreamlineTrack_outputs(): output_map = dict(tracked=dict(), ) outputs = SphericallyDeconvolutedStreamlineTrack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_StreamlineTrack.py000066400000000000000000000056271257611314500267630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import StreamlineTrack def test_StreamlineTrack_inputs(): input_map = dict(args=dict(argstr='%s', ), cutoff_value=dict(argstr='-cutoff %s', units='NA', ), desired_number_of_tracks=dict(argstr='-number %d', ), do_not_precompute=dict(argstr='-noprecomputed', ), environ=dict(nohash=True, usedefault=True, ), exclude_file=dict(argstr='-exclude %s', xor=['exclude_file', 'exclude_spec'], ), exclude_spec=dict(argstr='-exclude %s', position=2, sep=',', units='mm', xor=['exclude_file', 'exclude_spec'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), include_file=dict(argstr='-include %s', xor=['include_file', 'include_spec'], ), include_spec=dict(argstr='-include %s', position=2, sep=',', units='mm', xor=['include_file', 'include_spec'], ), initial_cutoff_value=dict(argstr='-initcutoff %s', units='NA', ), initial_direction=dict(argstr='-initdirection %s', units='voxels', ), inputmodel=dict(argstr='%s', position=-3, usedefault=True, ), mask_file=dict(argstr='-mask %s', xor=['mask_file', 'mask_spec'], ), mask_spec=dict(argstr='-mask %s', position=2, sep=',', units='mm', xor=['mask_file', 'mask_spec'], ), maximum_number_of_tracks=dict(argstr='-maxnum %d', ), maximum_tract_length=dict(argstr='-length %s', units='mm', ), minimum_radius_of_curvature=dict(argstr='-curvature %s', units='mm', ), minimum_tract_length=dict(argstr='-minlength %s', units='mm', ), no_mask_interpolation=dict(argstr='-nomaskinterp', ), out_file=dict(argstr='%s', name_source=['in_file'], name_template='%s_tracked.tck', output_name='tracked', position=-1, ), seed_file=dict(argstr='-seed %s', xor=['seed_file', 'seed_spec'], ), seed_spec=dict(argstr='-seed %s', position=2, sep=',', units='mm', xor=['seed_file', 'seed_spec'], ), step_size=dict(argstr='-step %s', units='mm', ), stop=dict(argstr='-stop', ), terminal_output=dict(nohash=True, ), unidirectional=dict(argstr='-unidirectional', ), ) inputs = StreamlineTrack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_StreamlineTrack_outputs(): output_map = dict(tracked=dict(), ) outputs = StreamlineTrack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Tensor2ApparentDiffusion.py000066400000000000000000000023231257611314500305570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import Tensor2ApparentDiffusion def test_Tensor2ApparentDiffusion_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = Tensor2ApparentDiffusion.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tensor2ApparentDiffusion_outputs(): output_map = dict(ADC=dict(), ) outputs = Tensor2ApparentDiffusion.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Tensor2FractionalAnisotropy.py000066400000000000000000000023411257611314500313100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import Tensor2FractionalAnisotropy def test_Tensor2FractionalAnisotropy_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = Tensor2FractionalAnisotropy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tensor2FractionalAnisotropy_outputs(): output_map = dict(FA=dict(), ) outputs = Tensor2FractionalAnisotropy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Tensor2Vector.py000066400000000000000000000022371257611314500264040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import Tensor2Vector def test_Tensor2Vector_inputs(): input_map = dict(args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), quiet=dict(argstr='-quiet', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = Tensor2Vector.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tensor2Vector_outputs(): output_map = dict(vector=dict(), ) outputs = Tensor2Vector.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Threshold.py000066400000000000000000000026101257611314500256140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.preprocess import Threshold def test_Threshold_inputs(): input_map = dict(absolute_threshold_value=dict(argstr='-abs %s', ), args=dict(argstr='%s', ), debug=dict(argstr='-debug', position=1, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), invert=dict(argstr='-invert', position=1, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), percentage_threshold_value=dict(argstr='-percent %s', ), quiet=dict(argstr='-quiet', position=1, ), replace_zeros_with_NaN=dict(argstr='-nan', position=1, ), terminal_output=dict(nohash=True, ), ) inputs = Threshold.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Threshold_outputs(): output_map = dict(out_file=dict(), ) outputs = Threshold.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tests/test_auto_Tracks2Prob.py000066400000000000000000000027061257611314500260220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix.tracking import Tracks2Prob def test_Tracks2Prob_inputs(): input_map = dict(args=dict(argstr='%s', ), colour=dict(argstr='-colour', position=3, ), environ=dict(nohash=True, usedefault=True, ), fraction=dict(argstr='-fraction', position=3, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_filename=dict(argstr='%s', genfile=True, position=-1, ), output_datatype=dict(argstr='-datatype %s', position=2, ), resample=dict(argstr='-resample %d', position=3, units='mm', ), template_file=dict(argstr='-template %s', position=1, ), terminal_output=dict(nohash=True, ), voxel_dims=dict(argstr='-vox %s', position=2, sep=',', ), ) inputs = Tracks2Prob.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tracks2Prob_outputs(): output_map = dict(tract_image=dict(), ) outputs = Tracks2Prob.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix/tracking.py000066400000000000000000000347131257611314500222420ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import CommandLineInputSpec, CommandLine, traits, TraitedSpec, File from nipype.utils.filemanip import split_filename import os, os.path as op from nipype.interfaces.traits_extension import isdefined class FilterTracksInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input tracks to be filtered') include_xor = ['include_file', 'include_spec'] include_file = File(exists=True, argstr='-include %s', desc='inclusion file', xor = include_xor) include_spec = traits.List(traits.Float, desc='inclusion specification in mm and radius (x y z r)', position=2, argstr='-include %s', minlen=4, maxlen=4, sep=',', units='mm', xor = include_xor) exclude_xor = ['exclude_file', 'exclude_spec'] exclude_file = File(exists=True, argstr='-exclude %s', desc='exclusion file', xor = exclude_xor) exclude_spec = traits.List(traits.Float, desc='exclusion specification in mm and radius (x y z r)', position=2, argstr='-exclude %s', minlen=4, maxlen=4, sep=',', units='mm', xor = exclude_xor) minimum_tract_length = traits.Float(argstr='-minlength %s', units='mm', desc="Sets the minimum length of any track in millimeters (default is 10 mm).") out_file = File(argstr='%s', position=-1, desc='Output filtered track filename', name_source=['in_file'], hash_files=False, name_template='%s_filt') no_mask_interpolation = traits.Bool(argstr='-nomaskinterp', desc="Turns off trilinear interpolation of mask images.") invert = traits.Bool(argstr='-invert', desc="invert the matching process, so that tracks that would" \ "otherwise have been included are now excluded and vice-versa.") quiet = traits.Bool(argstr='-quiet', position=1, desc="Do not display information messages or progress status.") debug = traits.Bool(argstr='-debug', position=1, desc="Display debugging messages.") class FilterTracksOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output filtered tracks') class FilterTracks(CommandLine): """ Use regions-of-interest to select a subset of tracks from a given MRtrix track file. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> filt = mrt.FilterTracks() >>> filt.inputs.in_file = 'tracks.tck' >>> filt.run() # doctest: +SKIP """ _cmd = 'filter_tracks' input_spec=FilterTracksInputSpec output_spec=FilterTracksOutputSpec class Tracks2ProbInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='tract file') template_file = File(exists=True, argstr='-template %s', position=1, desc='an image file to be used as a template for the output (the output image wil have the same transform and field of view)') voxel_dims = traits.List(traits.Float, argstr='-vox %s', sep=',', position=2, minlen=3, maxlen=3, desc='Three comma-separated numbers giving the size of each voxel in mm.') colour = traits.Bool(argstr='-colour', position=3, desc="add colour to the output image according to the direction of the tracks.") fraction = traits.Bool(argstr='-fraction', position=3, desc="produce an image of the fraction of fibres through each voxel (as a proportion of the total number in the file), rather than the count.") output_datatype = traits.Enum("Bit","Int8", "UInt8","Int16", "UInt16","Int32", "UInt32", "float32", "float64", argstr='-datatype %s', position=2, desc='"i.e. Bfloat". Can be "char", "short", "int", "long", "float" or "double"') #, usedefault=True) resample = traits.Float(argstr='-resample %d', position=3, units='mm', desc='resample the tracks at regular intervals using Hermite interpolation. If omitted, the program will select an appropriate interpolation factor automatically.') out_filename = File(genfile=True, argstr='%s', position= -1, desc='output data file') class Tracks2ProbOutputSpec(TraitedSpec): tract_image = File(exists=True, desc='Output tract count or track density image') class Tracks2Prob(CommandLine): """ Convert a tract file into a map of the fraction of tracks to enter each voxel - also known as a tract density image (TDI) - in MRtrix's image format (.mif). This can be viewed using MRview or converted to Nifti using MRconvert. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> tdi = mrt.Tracks2Prob() >>> tdi.inputs.in_file = 'dwi_CSD_tracked.tck' >>> tdi.inputs.colour = True >>> tdi.run() # doctest: +SKIP """ _cmd = 'tracks2prob' input_spec=Tracks2ProbInputSpec output_spec=Tracks2ProbOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['tract_image'] = self.inputs.out_filename if not isdefined(outputs['tract_image']): outputs['tract_image'] = op.abspath(self._gen_outfilename()) else: outputs['tract_image'] = os.path.abspath(outputs['tract_image']) return outputs def _gen_filename(self, name): if name is 'out_filename': return self._gen_outfilename() else: return None def _gen_outfilename(self): _, name , _ = split_filename(self.inputs.in_file) return name + '_TDI.mif' class StreamlineTrackInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='the image containing the source data.' \ 'The type of data required depends on the type of tracking as set in the preceeding argument. For DT methods, ' \ 'the base DWI are needed. For SD methods, the SH harmonic coefficients of the FOD are needed.') seed_xor = ['seed_file', 'seed_spec'] seed_file = File(exists=True, argstr='-seed %s', desc='seed file', xor = seed_xor) seed_spec = traits.List(traits.Float, desc='seed specification in mm and radius (x y z r)', position=2, argstr='-seed %s', minlen=4, maxlen=4, sep=',', units='mm', xor = seed_xor) include_xor = ['include_file', 'include_spec'] include_file = File(exists=True, argstr='-include %s', desc='inclusion file', xor = include_xor) include_spec = traits.List(traits.Float, desc='inclusion specification in mm and radius (x y z r)', position=2, argstr='-include %s', minlen=4, maxlen=4, sep=',', units='mm', xor = include_xor) exclude_xor = ['exclude_file', 'exclude_spec'] exclude_file = File(exists=True, argstr='-exclude %s', desc='exclusion file', xor = exclude_xor) exclude_spec = traits.List(traits.Float, desc='exclusion specification in mm and radius (x y z r)', position=2, argstr='-exclude %s', minlen=4, maxlen=4, sep=',', units='mm', xor = exclude_xor) mask_xor = ['mask_file', 'mask_spec'] mask_file = File(exists=True, argstr='-mask %s', desc='mask file. Only tracks within mask.', xor = mask_xor) mask_spec = traits.List(traits.Float, desc='Mask specification in mm and radius (x y z r). Tracks will be terminated when they leave the ROI.', position=2, argstr='-mask %s', minlen=4, maxlen=4, sep=',', units='mm', xor = mask_xor) inputmodel = traits.Enum('DT_STREAM', 'SD_PROB', 'SD_STREAM', argstr='%s', desc='input model type', usedefault=True, position=-3) stop = traits.Bool(argstr='-stop', desc="stop track as soon as it enters any of the include regions.") do_not_precompute = traits.Bool(argstr='-noprecomputed', desc="Turns off precomputation of the legendre polynomial values. Warning: this will slow down the algorithm by a factor of approximately 4.") unidirectional = traits.Bool(argstr='-unidirectional', desc="Track from the seed point in one direction only (default is to track in both directions).") no_mask_interpolation = traits.Bool(argstr='-nomaskinterp', desc="Turns off trilinear interpolation of mask images.") step_size = traits.Float(argstr='-step %s', units='mm', desc="Set the step size of the algorithm in mm (default is 0.2).") minimum_radius_of_curvature = traits.Float(argstr='-curvature %s', units='mm', desc="Set the minimum radius of curvature (default is 2 mm for DT_STREAM, 0 for SD_STREAM, 1 mm for SD_PROB and DT_PROB)") desired_number_of_tracks = traits.Int(argstr='-number %d', desc='Sets the desired number of tracks.' \ 'The program will continue to generate tracks until this number of tracks have been selected and written to the output file' \ '(default is 100 for *_STREAM methods, 1000 for *_PROB methods).') maximum_number_of_tracks = traits.Int(argstr='-maxnum %d', desc='Sets the maximum number of tracks to generate.' \ "The program will not generate more tracks than this number, even if the desired number of tracks hasn't yet been reached" \ '(default is 100 x number).') minimum_tract_length = traits.Float(argstr='-minlength %s', units='mm', desc="Sets the minimum length of any track in millimeters (default is 10 mm).") maximum_tract_length = traits.Float(argstr='-length %s', units='mm', desc="Sets the maximum length of any track in millimeters (default is 200 mm).") cutoff_value = traits.Float(argstr='-cutoff %s', units='NA', desc="Set the FA or FOD amplitude cutoff for terminating tracks (default is 0.1).") initial_cutoff_value = traits.Float(argstr='-initcutoff %s', units='NA', desc="Sets the minimum FA or FOD amplitude for initiating tracks (default is twice the normal cutoff).") initial_direction = traits.List(traits.Int, desc='Specify the initial tracking direction as a vector', argstr='-initdirection %s', minlen=2, maxlen=2, units='voxels') out_file = File(argstr='%s', position= -1, name_source = ['in_file'], name_template='%s_tracked.tck', output_name='tracked', desc='output data file') class StreamlineTrackOutputSpec(TraitedSpec): tracked = File(exists=True, desc='output file containing reconstructed tracts') class StreamlineTrack(CommandLine): """ Performs tractography using one of the following models: 'dt_prob', 'dt_stream', 'sd_prob', 'sd_stream', Where 'dt' stands for diffusion tensor, 'sd' stands for spherical deconvolution, and 'prob' stands for probabilistic. Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> strack = mrt.StreamlineTrack() >>> strack.inputs.inputmodel = 'SD_PROB' >>> strack.inputs.in_file = 'data.Bfloat' >>> strack.inputs.seed_file = 'seed_mask.nii' >>> strack.inputs.mask_file = 'mask.nii' >>> strack.cmdline 'streamtrack -mask mask.nii -seed seed_mask.nii SD_PROB data.Bfloat data_tracked.tck' >>> strack.run() # doctest: +SKIP """ _cmd = 'streamtrack' input_spec = StreamlineTrackInputSpec output_spec = StreamlineTrackOutputSpec class DiffusionTensorStreamlineTrackInputSpec(StreamlineTrackInputSpec): gradient_encoding_file = File(exists=True, argstr='-grad %s', mandatory=True, position=-2, desc='Gradient encoding, supplied as a 4xN text file with each line is in the format [ X Y Z b ], where [ X Y Z ] describe the direction of the applied gradient, and b gives the b-value in units (1000 s/mm^2). See FSL2MRTrix') class DiffusionTensorStreamlineTrack(StreamlineTrack): """ Specialized interface to StreamlineTrack. This interface is used for streamline tracking from diffusion tensor data, and calls the MRtrix function 'streamtrack' with the option 'DT_STREAM' Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> dtstrack = mrt.DiffusionTensorStreamlineTrack() >>> dtstrack.inputs.in_file = 'data.Bfloat' >>> dtstrack.inputs.seed_file = 'seed_mask.nii' >>> dtstrack.run() # doctest: +SKIP """ input_spec = DiffusionTensorStreamlineTrackInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "DT_STREAM" return super(DiffusionTensorStreamlineTrack, self).__init__(command, **inputs) class ProbabilisticSphericallyDeconvolutedStreamlineTrackInputSpec(StreamlineTrackInputSpec): maximum_number_of_trials = traits.Int(argstr='-trials %s', desc="Set the maximum number of sampling trials at each point (only used for probabilistic tracking).") class ProbabilisticSphericallyDeconvolutedStreamlineTrack(StreamlineTrack): """ Performs probabilistic tracking using spherically deconvolved data Specialized interface to StreamlineTrack. This interface is used for probabilistic tracking from spherically deconvolved data, and calls the MRtrix function 'streamtrack' with the option 'SD_PROB' Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> sdprobtrack = mrt.ProbabilisticSphericallyDeconvolutedStreamlineTrack() >>> sdprobtrack.inputs.in_file = 'data.Bfloat' >>> sdprobtrack.inputs.seed_file = 'seed_mask.nii' >>> sdprobtrack.run() # doctest: +SKIP """ input_spec = ProbabilisticSphericallyDeconvolutedStreamlineTrackInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "SD_PROB" return super(ProbabilisticSphericallyDeconvolutedStreamlineTrack, self).__init__(command, **inputs) class SphericallyDeconvolutedStreamlineTrack(StreamlineTrack): """ Performs streamline tracking using spherically deconvolved data Specialized interface to StreamlineTrack. This interface is used for streamline tracking from spherically deconvolved data, and calls the MRtrix function 'streamtrack' with the option 'SD_STREAM' Example ------- >>> import nipype.interfaces.mrtrix as mrt >>> sdtrack = mrt.SphericallyDeconvolutedStreamlineTrack() >>> sdtrack.inputs.in_file = 'data.Bfloat' >>> sdtrack.inputs.seed_file = 'seed_mask.nii' >>> sdtrack.run() # doctest: +SKIP """ input_spec = StreamlineTrackInputSpec def __init__(self, command=None, **inputs): inputs["inputmodel"] = "SD_STREAM" return super(SphericallyDeconvolutedStreamlineTrack, self).__init__(command, **inputs) nipype-0.11.0/nipype/interfaces/mrtrix3/000077500000000000000000000000001257611314500201415ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mrtrix3/__init__.py000066400000000000000000000006771257611314500222640ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- from utils import (Mesh2PVE, Generate5tt, BrainMask, TensorMetrics, ComputeTDI, TCK2VTK) from preprocess import ResponseSD, ACTPrepareFSL, ReplaceFSwithFIRST from tracking import Tractography from reconst import FitTensor, EstimateFOD from connectivity import LabelConfig, BuildConnectome nipype-0.11.0/nipype/interfaces/mrtrix3/base.py000066400000000000000000000063051257611314500214310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, InputMultiPath) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined from ... import logging logger = logging.getLogger('interface') class MRTrix3BaseInputSpec(CommandLineInputSpec): nthreads = traits.Int( argstr='-nthreads %d', desc='number of threads. if zero, the number' ' of available cpus will be used', nohash=True) # DW gradient table import options grad_file = File(exists=True, argstr='-grad %s', desc='dw gradient scheme (MRTrix format') grad_fsl = traits.Tuple( File(exists=True), File(exists=True), argstr='-fslgrad %s %s', desc='(bvecs, bvals) dw gradient scheme (FSL format') bval_scale = traits.Enum( 'yes', 'no', argstr='-bvalue_scaling %s', desc='specifies whether the b - values should be scaled by the square' ' of the corresponding DW gradient norm, as often required for ' 'multishell or DSI DW acquisition schemes. The default action ' 'can also be set in the MRtrix config file, under the ' 'BValueScaling entry. Valid choices are yes / no, true / ' 'false, 0 / 1 (default: true).') in_bvec = File(exists=True, argstr='-fslgrad %s %s', desc='bvecs file in FSL format') in_bval = File(exists=True, desc='bvals file in FSL format') class MRTrix3Base(CommandLine): def _format_arg(self, name, trait_spec, value): if name == 'nthreads' and value == 0: value = 1 try: from multiprocessing import cpu_count value = cpu_count() except: logger.warn('Number of threads could not be computed') pass return trait_spec.argstr % value if name == 'in_bvec': return trait_spec.argstr % (value, self.inputs.in_bval) return super(MRTrix3Base, self)._format_arg(name, trait_spec, value) def _parse_inputs(self, skip=None): if skip is None: skip = [] try: if (isdefined(self.inputs.grad_file) or isdefined(self.inputs.grad_fsl)): skip += ['in_bvec', 'in_bval'] is_bvec = isdefined(self.inputs.in_bvec) is_bval = isdefined(self.inputs.in_bval) if is_bvec or is_bval: if not is_bvec or not is_bval: raise RuntimeError('If using bvecs and bvals inputs, both' 'should be defined') skip += ['in_bval'] except AttributeError: pass return super(MRTrix3Base, self)._parse_inputs(skip=skip) nipype-0.11.0/nipype/interfaces/mrtrix3/connectivity.py000066400000000000000000000165311257611314500232370ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from base import MRTrix3BaseInputSpec, MRTrix3Base from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined class BuildConnectomeInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='input tractography') in_parc = File(exists=True, argstr='%s', position=-2, desc='parcellation file') out_file = File( 'connectome.csv', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file after processing') nthreads = traits.Int( argstr='-nthreads %d', desc='number of threads. if zero, the number' ' of available cpus will be used', nohash=True) vox_lookup = traits.Bool( argstr='-assignment_voxel_lookup', desc='use a simple voxel lookup value at each streamline endpoint') search_radius = traits.Float( argstr='-assignment_radial_search %f', desc='perform a radial search from each streamline endpoint to locate ' 'the nearest node. Argument is the maximum radius in mm; if no node is' ' found within this radius, the streamline endpoint is not assigned to' ' any node.') search_reverse = traits.Float( argstr='-assignment_reverse_search %f', desc='traverse from each streamline endpoint inwards along the ' 'streamline, in search of the last node traversed by the streamline. ' 'Argument is the maximum traversal length in mm (set to 0 to allow ' 'search to continue to the streamline midpoint).') search_forward = traits.Float( argstr='-assignment_forward_search %f', desc='project the streamline forwards from the endpoint in search of a' 'parcellation node voxel. Argument is the maximum traversal length in ' 'mm.') metric = traits.Enum( 'count', 'meanlength', 'invlength', 'invnodevolume', 'mean_scalar', 'invlength_invnodevolume', argstr='-metric %s', desc='specify the edge' ' weight metric') in_scalar = File( exists=True, argstr='-image %s', desc='provide the associated image ' 'for the mean_scalar metric') in_weights = File( exists=True, argstr='-tck_weights_in %s', desc='specify a text scalar ' 'file containing the streamline weights') keep_unassigned = traits.Bool( argstr='-keep_unassigned', desc='By default, the program discards the' ' information regarding those streamlines that are not successfully ' 'assigned to a node pair. Set this option to keep these values (will ' 'be the first row/column in the output matrix)') zero_diagonal = traits.Bool( argstr='-zero_diagonal', desc='set all diagonal entries in the matrix ' 'to zero (these represent streamlines that connect to the same node at' ' both ends)') class BuildConnectomeOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class BuildConnectome(MRTrix3Base): """ Generate a connectome matrix from a streamlines file and a node parcellation image Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> mat = mrt.BuildConnectome() >>> mat.inputs.in_file = 'tracks.tck' >>> mat.inputs.in_parc = 'aparc+aseg.nii' >>> mat.cmdline # doctest: +ELLIPSIS 'tck2connectome tracks.tck aparc+aseg.nii connectome.csv' >>> mat.run() # doctest: +SKIP """ _cmd = 'tck2connectome' input_spec = BuildConnectomeInputSpec output_spec = BuildConnectomeOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class LabelConfigInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='input anatomical image') in_config = File(exists=True, argstr='%s', position=-2, desc='connectome configuration file') out_file = File( 'parcellation.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file after processing') lut_basic = File(argstr='-lut_basic %s', desc='get information from ' 'a basic lookup table consisting of index / name pairs') lut_fs = File(argstr='-lut_freesurfer %s', desc='get information from ' 'a FreeSurfer lookup table(typically "FreeSurferColorLUT' '.txt")') lut_aal = File(argstr='-lut_aal %s', desc='get information from the AAL ' 'lookup table (typically "ROI_MNI_V4.txt")') lut_itksnap = File(argstr='-lut_itksnap %s', desc='get information from an' ' ITK - SNAP lookup table(this includes the IIT atlas ' 'file "LUT_GM.txt")') spine = File(argstr='-spine %s', desc='provide a manually-defined ' 'segmentation of the base of the spine where the streamlines' ' terminate, so that this can become a node in the connection' ' matrix.') nthreads = traits.Int( argstr='-nthreads %d', desc='number of threads. if zero, the number' ' of available cpus will be used', nohash=True) class LabelConfigOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class LabelConfig(MRTrix3Base): """ Re-configure parcellation to be incrementally defined. Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> labels = mrt.LabelConfig() >>> labels.inputs.in_file = 'aparc+aseg.nii' >>> labels.inputs.in_config = 'mrtrix3_labelconfig.txt' >>> labels.cmdline # doctest: +ELLIPSIS 'labelconfig aparc+aseg.nii mrtrix3_labelconfig.txt parcellation.mif' >>> labels.run() # doctest: +SKIP """ _cmd = 'labelconfig' input_spec = LabelConfigInputSpec output_spec = LabelConfigOutputSpec def _parse_inputs(self, skip=None): if skip is None: skip = [] if not isdefined(self.inputs.in_config): from distutils.spawn import find_executable path = find_executable(self._cmd) if path is None: path = os.getenv(MRTRIX3_HOME, '/opt/mrtrix3') else: path = op.dirname(op.dirname(path)) self.inputs.in_config = op.join( path, 'src/dwi/tractography/connectomics/' 'example_configs/fs_default.txt') return super(LabelConfig, self)._parse_inputs(skip=skip) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/mrtrix3/preprocess.py000066400000000000000000000164261257611314500227110ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from base import MRTrix3BaseInputSpec, MRTrix3Base from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined class ResponseSDInputSpec(MRTrix3BaseInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input diffusion weighted images') out_file = File( 'response.txt', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file containing SH coefficients') # DW Shell selection options shell = traits.List(traits.Float, sep=',', argstr='-shell %s', desc='specify one or more dw gradient shells') in_mask = File(exists=True, argstr='-mask %s', desc='provide initial mask image') max_sh = traits.Int(8, argstr='-lmax %d', desc='maximum harmonic degree of response function') out_sf = File('sf_mask.nii.gz', argstr='-sf %s', desc='write a mask containing single-fibre voxels') test_all = traits.Bool(False, argstr='-test_all', desc='re-test all voxels at every iteration') # Optimization iterations = traits.Int(0, argstr='-max_iters %d', desc='maximum number of iterations per pass') max_change = traits.Float( argstr='-max_change %f', desc=('maximum percentile change in any response function coefficient;' ' if no individual coefficient changes by more than this ' 'fraction, the algorithm is terminated.')) # Thresholds vol_ratio = traits.Float( .15, argstr='-volume_ratio %f', desc=('maximal volume ratio between the sum of all other positive' ' lobes in the voxel and the largest FOD lobe')) disp_mult = traits.Float( 1., argstr='-dispersion_multiplier %f', desc=('dispersion of FOD lobe must not exceed some threshold as ' 'determined by this multiplier and the FOD dispersion in other ' 'single-fibre voxels. The threshold is: (mean + (multiplier * ' '(mean - min))); default = 1.0. Criterion is only applied in ' 'second pass of RF estimation.')) int_mult = traits.Float( 2., argstr='-integral_multiplier %f', desc=('integral of FOD lobe must not be outside some range as ' 'determined by this multiplier and FOD lobe integral in other' ' single-fibre voxels. The range is: (mean +- (multiplier * ' 'stdev)); default = 2.0. Criterion is only applied in second ' 'pass of RF estimation.')) class ResponseSDOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') out_sf = File(desc=('mask containing single-fibre voxels')) class ResponseSD(MRTrix3Base): """ Generate an appropriate response function from the image data for spherical deconvolution. .. [1] Tax, C. M.; Jeurissen, B.; Vos, S. B.; Viergever, M. A. and Leemans, A., Recursive calibration of the fiber response function for spherical deconvolution of diffusion MRI data. NeuroImage, 2014, 86, 67-80 Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> resp = mrt.ResponseSD() >>> resp.inputs.in_file = 'dwi.mif' >>> resp.inputs.in_mask = 'mask.nii.gz' >>> resp.inputs.grad_fsl = ('bvecs', 'bvals') >>> resp.cmdline # doctest: +ELLIPSIS 'dwi2response -fslgrad bvecs bvals -mask mask.nii.gz dwi.mif response.txt' >>> resp.run() # doctest: +SKIP """ _cmd = 'dwi2response' input_spec = ResponseSDInputSpec output_spec = ResponseSDOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) if isdefined(self.inputs.out_sf): outputs['out_sf'] = op.abspath(self.inputs.out_sf) return outputs class ACTPrepareFSLInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input anatomical image') out_file = File( 'act_5tt.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file after processing') class ACTPrepareFSLOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class ACTPrepareFSL(CommandLine): """ Generate anatomical information necessary for Anatomically Constrained Tractography (ACT). Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> prep = mrt.ACTPrepareFSL() >>> prep.inputs.in_file = 'T1.nii.gz' >>> prep.cmdline # doctest: +ELLIPSIS 'act_anat_prepare_fsl T1.nii.gz act_5tt.mif' >>> prep.run() # doctest: +SKIP """ _cmd = 'act_anat_prepare_fsl' input_spec = ACTPrepareFSLInputSpec output_spec = ACTPrepareFSLOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class ReplaceFSwithFIRSTInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-4, desc='input anatomical image') in_t1w = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='input T1 image') in_config = File(exists=True, argstr='%s', position=-2, desc='connectome configuration file') out_file = File( 'aparc+first.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file after processing') class ReplaceFSwithFIRSTOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class ReplaceFSwithFIRST(CommandLine): """ Replace deep gray matter structures segmented with FSL FIRST in a FreeSurfer parcellation. Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> prep = mrt.ReplaceFSwithFIRST() >>> prep.inputs.in_file = 'aparc+aseg.nii' >>> prep.inputs.in_t1w = 'T1.nii.gz' >>> prep.inputs.in_config = 'mrtrix3_labelconfig.txt' >>> prep.cmdline # doctest: +ELLIPSIS 'fs_parc_replace_sgm_first aparc+aseg.nii T1.nii.gz \ mrtrix3_labelconfig.txt aparc+first.mif' >>> prep.run() # doctest: +SKIP """ _cmd = 'fs_parc_replace_sgm_first' input_spec = ReplaceFSwithFIRSTInputSpec output_spec = ReplaceFSwithFIRSTOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/mrtrix3/reconst.py000066400000000000000000000170201257611314500221700ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from base import MRTrix3BaseInputSpec, MRTrix3Base from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, InputMultiPath) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined class FitTensorInputSpec(MRTrix3BaseInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input diffusion weighted images') out_file = File( 'dti.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='the output diffusion tensor image') # General options in_mask = File(exists=True, argstr='-mask %s', desc=('only perform computation within the specified ' 'binary brain mask image')) method = traits.Enum( 'nonlinear', 'loglinear', 'sech', 'rician', argstr='-method %s', desc=('select method used to perform the fitting')) reg_term = traits.Float( 5.e3, argstr='-regularisation %f', desc=('specify the strength of the regularisation term on the ' 'magnitude of the tensor elements (default = 5000). This ' 'only applies to the non-linear methods')) class FitTensorOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output DTI file') class FitTensor(MRTrix3Base): """ Convert diffusion-weighted images to tensor images Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> tsr = mrt.FitTensor() >>> tsr.inputs.in_file = 'dwi.mif' >>> tsr.inputs.in_mask = 'mask.nii.gz' >>> tsr.inputs.grad_fsl = ('bvecs', 'bvals') >>> tsr.cmdline # doctest: +ELLIPSIS 'dwi2tensor -fslgrad bvecs bvals -mask mask.nii.gz dwi.mif dti.mif' >>> tsr.run() # doctest: +SKIP """ _cmd = 'dwi2tensor' input_spec = FitTensorInputSpec output_spec = FitTensorOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class EstimateFODInputSpec(MRTrix3BaseInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='input diffusion weighted images') response = File( exists=True, argstr='%s', mandatory=True, position=-2, desc=('a text file containing the diffusion-weighted signal response ' 'function coefficients for a single fibre population')) out_file = File( 'fods.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc=('the output spherical harmonics coefficients' ' image')) # DW Shell selection options shell = traits.List(traits.Float, sep=',', argstr='-shell %s', desc='specify one or more dw gradient shells') # Spherical deconvolution options max_sh = traits.Int(8, argstr='-lmax %d', desc='maximum harmonic degree of response function') in_mask = File(exists=True, argstr='-mask %s', desc='provide initial mask image') in_dirs = File( exists=True, argstr='-directions %s', desc=('specify the directions over which to apply the non-negativity ' 'constraint (by default, the built-in 300 direction set is ' 'used). These should be supplied as a text file containing the ' '[ az el ] pairs for the directions.')) sh_filter = File( exists=True, argstr='-filter %s', desc=('the linear frequency filtering parameters used for the initial ' 'linear spherical deconvolution step (default = [ 1 1 1 0 0 ]). ' 'These should be supplied as a text file containing the ' 'filtering coefficients for each even harmonic order.')) neg_lambda = traits.Float( 1.0, argstr='-neg_lambda %f', desc=('the regularisation parameter lambda that controls the strength' ' of the non-negativity constraint')) thres = traits.Float( 0.0, argstr='-threshold %f', desc=('the threshold below which the amplitude of the FOD is assumed ' 'to be zero, expressed as an absolute amplitude')) n_iter = traits.Int( 50, argstr='-niter %d', desc=('the maximum number of iterations ' 'to perform for each voxel')) class EstimateFODOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class EstimateFOD(MRTrix3Base): """ Convert diffusion-weighted images to tensor images Note that this program makes use of implied symmetries in the diffusion profile. First, the fact the signal attenuation profile is real implies that it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)* (where * denotes the complex conjugate). Second, the diffusion profile should be antipodally symmetric (i.e. S(x) = S(-x)), implying that all odd l components should be zero. Therefore, this program only computes the even elements. Note that the spherical harmonics equations used here differ slightly from those conventionally used, in that the (-1)^m factor has been omitted. This should be taken into account in all subsequent calculations. The spherical harmonic coefficients are stored as follows. First, since the signal attenuation profile is real, it has conjugate symmetry, i.e. Y(l,-m) = Y(l,m)* (where * denotes the complex conjugate). Second, the diffusion profile should be antipodally symmetric (i.e. S(x) = S(-x)), implying that all odd l components should be zero. Therefore, only the even elements are computed. Note that the spherical harmonics equations used here differ slightly from those conventionally used, in that the (-1)^m factor has been omitted. This should be taken into account in all subsequent calculations. Each volume in the output image corresponds to a different spherical harmonic component. Each volume will correspond to the following: volume 0: l = 0, m = 0 volume 1: l = 2, m = -2 (imaginary part of m=2 SH) volume 2: l = 2, m = -1 (imaginary part of m=1 SH) volume 3: l = 2, m = 0 volume 4: l = 2, m = 1 (real part of m=1 SH) volume 5: l = 2, m = 2 (real part of m=2 SH) etc... Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> fod = mrt.EstimateFOD() >>> fod.inputs.in_file = 'dwi.mif' >>> fod.inputs.response = 'response.txt' >>> fod.inputs.in_mask = 'mask.nii.gz' >>> fod.inputs.grad_fsl = ('bvecs', 'bvals') >>> fod.cmdline # doctest: +ELLIPSIS 'dwi2fod -fslgrad bvecs bvals -mask mask.nii.gz dwi.mif response.txt\ fods.mif' >>> fod.run() # doctest: +SKIP """ _cmd = 'dwi2fod' input_spec = EstimateFODInputSpec output_spec = EstimateFODOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/mrtrix3/tests/000077500000000000000000000000001257611314500213035ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_ACTPrepareFSL.py000066400000000000000000000021071257611314500262370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.preprocess import ACTPrepareFSL def test_ACTPrepareFSL_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ACTPrepareFSL.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ACTPrepareFSL_outputs(): output_map = dict(out_file=dict(), ) outputs = ACTPrepareFSL.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_BrainMask.py000066400000000000000000000025131257611314500256140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import BrainMask def test_BrainMask_inputs(): input_map = dict(args=dict(argstr='%s', ), bval_scale=dict(argstr='-bvalue_scaling %s', ), environ=dict(nohash=True, usedefault=True, ), grad_file=dict(argstr='-grad %s', ), grad_fsl=dict(argstr='-fslgrad %s %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(argstr='-fslgrad %s %s', ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = BrainMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BrainMask_outputs(): output_map = dict(out_file=dict(), ) outputs = BrainMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_BuildConnectome.py000066400000000000000000000033371257611314500270240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.connectivity import BuildConnectome def test_BuildConnectome_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), in_parc=dict(argstr='%s', position=-2, ), in_scalar=dict(argstr='-image %s', ), in_weights=dict(argstr='-tck_weights_in %s', ), keep_unassigned=dict(argstr='-keep_unassigned', ), metric=dict(argstr='-metric %s', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), search_forward=dict(argstr='-assignment_forward_search %f', ), search_radius=dict(argstr='-assignment_radial_search %f', ), search_reverse=dict(argstr='-assignment_reverse_search %f', ), terminal_output=dict(nohash=True, ), vox_lookup=dict(argstr='-assignment_voxel_lookup', ), zero_diagonal=dict(argstr='-zero_diagonal', ), ) inputs = BuildConnectome.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BuildConnectome_outputs(): output_map = dict(out_file=dict(), ) outputs = BuildConnectome.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_ComputeTDI.py000066400000000000000000000035211257611314500257220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import ComputeTDI def test_ComputeTDI_inputs(): input_map = dict(args=dict(argstr='%s', ), contrast=dict(argstr='-constrast %s', ), data_type=dict(argstr='-datatype %s', ), dixel=dict(argstr='-dixel %s', ), ends_only=dict(argstr='-ends_only', ), environ=dict(nohash=True, usedefault=True, ), fwhm_tck=dict(argstr='-fwhm_tck %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), in_map=dict(argstr='-image %s', ), map_zero=dict(argstr='-map_zero', ), max_tod=dict(argstr='-tod %d', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', position=-1, usedefault=True, ), precise=dict(argstr='-precise', ), reference=dict(argstr='-template %s', ), stat_tck=dict(argstr='-stat_tck %s', ), stat_vox=dict(argstr='-stat_vox %s', ), tck_weights=dict(argstr='-tck_weights_in %s', ), terminal_output=dict(nohash=True, ), upsample=dict(argstr='-upsample %d', ), use_dec=dict(argstr='-dec', ), vox_size=dict(argstr='-vox %s', sep=',', ), ) inputs = ComputeTDI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeTDI_outputs(): output_map = dict(out_file=dict(), ) outputs = ComputeTDI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_EstimateFOD.py000066400000000000000000000034331257611314500260530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.reconst import EstimateFOD def test_EstimateFOD_inputs(): input_map = dict(args=dict(argstr='%s', ), bval_scale=dict(argstr='-bvalue_scaling %s', ), environ=dict(nohash=True, usedefault=True, ), grad_file=dict(argstr='-grad %s', ), grad_fsl=dict(argstr='-fslgrad %s %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(argstr='-fslgrad %s %s', ), in_dirs=dict(argstr='-directions %s', ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), in_mask=dict(argstr='-mask %s', ), max_sh=dict(argstr='-lmax %d', ), n_iter=dict(argstr='-niter %d', ), neg_lambda=dict(argstr='-neg_lambda %f', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), response=dict(argstr='%s', mandatory=True, position=-2, ), sh_filter=dict(argstr='-filter %s', ), shell=dict(argstr='-shell %s', sep=',', ), terminal_output=dict(nohash=True, ), thres=dict(argstr='-threshold %f', ), ) inputs = EstimateFOD.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EstimateFOD_outputs(): output_map = dict(out_file=dict(), ) outputs = EstimateFOD.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_FitTensor.py000066400000000000000000000027321257611314500256650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.reconst import FitTensor def test_FitTensor_inputs(): input_map = dict(args=dict(argstr='%s', ), bval_scale=dict(argstr='-bvalue_scaling %s', ), environ=dict(nohash=True, usedefault=True, ), grad_file=dict(argstr='-grad %s', ), grad_fsl=dict(argstr='-fslgrad %s %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(argstr='-fslgrad %s %s', ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), in_mask=dict(argstr='-mask %s', ), method=dict(argstr='-method %s', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), reg_term=dict(argstr='-regularisation %f', ), terminal_output=dict(nohash=True, ), ) inputs = FitTensor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FitTensor_outputs(): output_map = dict(out_file=dict(), ) outputs = FitTensor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_Generate5tt.py000066400000000000000000000021571257611314500261400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import Generate5tt def test_Generate5tt_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_fast=dict(argstr='%s', mandatory=True, position=-3, ), in_first=dict(argstr='%s', position=-2, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = Generate5tt.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Generate5tt_outputs(): output_map = dict(out_file=dict(), ) outputs = Generate5tt.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_LabelConfig.py000066400000000000000000000026541257611314500261200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.connectivity import LabelConfig def test_LabelConfig_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_config=dict(argstr='%s', position=-2, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), lut_aal=dict(argstr='-lut_aal %s', ), lut_basic=dict(argstr='-lut_basic %s', ), lut_fs=dict(argstr='-lut_freesurfer %s', ), lut_itksnap=dict(argstr='-lut_itksnap %s', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), spine=dict(argstr='-spine %s', ), terminal_output=dict(nohash=True, ), ) inputs = LabelConfig.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LabelConfig_outputs(): output_map = dict(out_file=dict(), ) outputs = LabelConfig.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_MRTrix3Base.py000066400000000000000000000011521257611314500260060ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.base import MRTrix3Base def test_MRTrix3Base_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = MRTrix3Base.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_Mesh2PVE.py000066400000000000000000000022421257611314500252750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import Mesh2PVE def test_Mesh2PVE_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-3, ), in_first=dict(argstr='-first %s', ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), reference=dict(argstr='%s', mandatory=True, position=-2, ), terminal_output=dict(nohash=True, ), ) inputs = Mesh2PVE.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Mesh2PVE_outputs(): output_map = dict(out_file=dict(), ) outputs = Mesh2PVE.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_ReplaceFSwithFIRST.py000066400000000000000000000023411257611314500272540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.preprocess import ReplaceFSwithFIRST def test_ReplaceFSwithFIRST_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_config=dict(argstr='%s', position=-2, ), in_file=dict(argstr='%s', mandatory=True, position=-4, ), in_t1w=dict(argstr='%s', mandatory=True, position=-3, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ReplaceFSwithFIRST.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ReplaceFSwithFIRST_outputs(): output_map = dict(out_file=dict(), ) outputs = ReplaceFSwithFIRST.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_ResponseSD.py000066400000000000000000000035361257611314500260000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.preprocess import ResponseSD def test_ResponseSD_inputs(): input_map = dict(args=dict(argstr='%s', ), bval_scale=dict(argstr='-bvalue_scaling %s', ), disp_mult=dict(argstr='-dispersion_multiplier %f', ), environ=dict(nohash=True, usedefault=True, ), grad_file=dict(argstr='-grad %s', ), grad_fsl=dict(argstr='-fslgrad %s %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(argstr='-fslgrad %s %s', ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), in_mask=dict(argstr='-mask %s', ), int_mult=dict(argstr='-integral_multiplier %f', ), iterations=dict(argstr='-max_iters %d', ), max_change=dict(argstr='-max_change %f', ), max_sh=dict(argstr='-lmax %d', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), out_sf=dict(argstr='-sf %s', ), shell=dict(argstr='-shell %s', sep=',', ), terminal_output=dict(nohash=True, ), test_all=dict(argstr='-test_all', ), vol_ratio=dict(argstr='-volume_ratio %f', ), ) inputs = ResponseSD.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ResponseSD_outputs(): output_map = dict(out_file=dict(), out_sf=dict(), ) outputs = ResponseSD.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_TCK2VTK.py000066400000000000000000000022511257611314500250340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import TCK2VTK def test_TCK2VTK_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', position=-1, usedefault=True, ), reference=dict(argstr='-image %s', ), terminal_output=dict(nohash=True, ), voxel=dict(argstr='-image %s', ), ) inputs = TCK2VTK.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TCK2VTK_outputs(): output_map = dict(out_file=dict(), ) outputs = TCK2VTK.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_TensorMetrics.py000066400000000000000000000025371257611314500265540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.utils import TensorMetrics def test_TensorMetrics_inputs(): input_map = dict(args=dict(argstr='%s', ), component=dict(argstr='-num %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='%s', mandatory=True, position=-1, ), in_mask=dict(argstr='-mask %s', ), modulate=dict(argstr='-modulate %s', ), out_adc=dict(argstr='-adc %s', ), out_eval=dict(argstr='-value %s', ), out_evec=dict(argstr='-vector %s', ), out_fa=dict(argstr='-fa %s', ), terminal_output=dict(nohash=True, ), ) inputs = TensorMetrics.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TensorMetrics_outputs(): output_map = dict(out_adc=dict(), out_eval=dict(), out_evec=dict(), out_fa=dict(), ) outputs = TensorMetrics.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tests/test_auto_Tractography.py000066400000000000000000000062761257611314500264260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.mrtrix3.tracking import Tractography def test_Tractography_inputs(): input_map = dict(act_file=dict(argstr='-act %s', ), algorithm=dict(argstr='-algorithm %s', usedefault=True, ), angle=dict(argstr='-angle %f', ), args=dict(argstr='%s', ), backtrack=dict(argstr='-backtrack', ), bval_scale=dict(argstr='-bvalue_scaling %s', ), crop_at_gmwmi=dict(argstr='-crop_at_gmwmi', ), cutoff=dict(argstr='-cutoff %f', ), cutoff_init=dict(argstr='-initcutoff %f', ), downsample=dict(argstr='-downsample %f', ), environ=dict(nohash=True, usedefault=True, ), grad_file=dict(argstr='-grad %s', ), grad_fsl=dict(argstr='-fslgrad %s %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_bval=dict(), in_bvec=dict(argstr='-fslgrad %s %s', ), in_file=dict(argstr='%s', mandatory=True, position=-2, ), init_dir=dict(argstr='-initdirection %f,%f,%f', ), max_length=dict(argstr='-maxlength %f', ), max_seed_attempts=dict(argstr='-max_seed_attempts %d', ), max_tracks=dict(argstr='-maxnum %d', ), min_length=dict(argstr='-minlength %f', ), n_samples=dict(argstr='-samples %d', ), n_tracks=dict(argstr='-number %d', ), n_trials=dict(argstr='-trials %d', ), noprecompt=dict(argstr='-noprecomputed', ), nthreads=dict(argstr='-nthreads %d', nohash=True, ), out_file=dict(argstr='%s', mandatory=True, position=-1, usedefault=True, ), out_seeds=dict(argstr='-output_seeds %s', ), power=dict(argstr='-power %d', ), roi_excl=dict(argstr='-exclude %s', ), roi_incl=dict(argstr='-include %s', ), roi_mask=dict(argstr='-mask %s', ), seed_dynamic=dict(argstr='-seed_dynamic %s', ), seed_gmwmi=dict(argstr='-seed_gmwmi %s', requires=['act_file'], ), seed_grid_voxel=dict(argstr='-seed_grid_per_voxel %s %d', xor=['seed_image', 'seed_rnd_voxel'], ), seed_image=dict(argstr='-seed_image %s', ), seed_rejection=dict(argstr='-seed_rejection %s', ), seed_rnd_voxel=dict(argstr='-seed_random_per_voxel %s %d', xor=['seed_image', 'seed_grid_voxel'], ), seed_sphere=dict(argstr='-seed_sphere %f,%f,%f,%f', ), sph_trait=dict(argstr='%f,%f,%f,%f', ), step_size=dict(argstr='-step %f', ), stop=dict(argstr='-stop', ), terminal_output=dict(nohash=True, ), unidirectional=dict(argstr='-unidirectional', ), use_rk4=dict(argstr='-rk4', ), ) inputs = Tractography.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Tractography_outputs(): output_map = dict(out_file=dict(), out_seeds=dict(), ) outputs = Tractography.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/mrtrix3/tracking.py000066400000000000000000000255741257611314500223320ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from base import MRTrix3BaseInputSpec, MRTrix3Base from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined class TractographyInputSpec(MRTrix3BaseInputSpec): sph_trait = traits.Tuple(traits.Float, traits.Float, traits.Float, traits.Float, argstr='%f,%f,%f,%f') in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input file to be processed') out_file = File('tracked.tck', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file containing tracks') algorithm = traits.Enum( 'iFOD2', 'FACT', 'iFOD1', 'Nulldist', 'SD_Stream', 'Tensor_Det', 'Tensor_Prob', usedefault=True, argstr='-algorithm %s', desc='tractography algorithm to be used') # ROIs processing options roi_incl = traits.Either( File(exists=True), sph_trait, argstr='-include %s', desc=('specify an inclusion region of interest, streamlines must' ' traverse ALL inclusion regions to be accepted')) roi_excl = traits.Either( File(exists=True), sph_trait, argstr='-exclude %s', desc=('specify an exclusion region of interest, streamlines that' ' enter ANY exclude region will be discarded')) roi_mask = traits.Either( File(exists=True), sph_trait, argstr='-mask %s', desc=('specify a masking region of interest. If defined,' 'streamlines exiting the mask will be truncated')) # Streamlines tractography options step_size = traits.Float( argstr='-step %f', desc=('set the step size of the algorithm in mm (default is 0.1' ' x voxelsize; for iFOD2: 0.5 x voxelsize)')) angle = traits.Float( argstr='-angle %f', desc=('set the maximum angle between successive steps (default ' 'is 90deg x stepsize / voxelsize)')) n_tracks = traits.Int( argstr='-number %d', desc=('set the desired number of tracks. The program will continue' ' to generate tracks until this number of tracks have been ' 'selected and written to the output file')) max_tracks = traits.Int( argstr='-maxnum %d', desc=('set the maximum number of tracks to generate. The program ' 'will not generate more tracks than this number, even if ' 'the desired number of tracks hasn\'t yet been reached ' '(default is 100 x number)')) max_length = traits.Float( argstr='-maxlength %f', desc=('set the maximum length of any track in mm (default is ' '100 x voxelsize)')) min_length = traits.Float( argstr='-minlength %f', desc=('set the minimum length of any track in mm (default is ' '5 x voxelsize)')) cutoff = traits.Float( argstr='-cutoff %f', desc=('set the FA or FOD amplitude cutoff for terminating ' 'tracks (default is 0.1)')) cutoff_init = traits.Float( argstr='-initcutoff %f', desc=('set the minimum FA or FOD amplitude for initiating ' 'tracks (default is the same as the normal cutoff)')) n_trials = traits.Int( argstr='-trials %d', desc=('set the maximum number of sampling trials at each point' ' (only used for probabilistic tracking)')) unidirectional = traits.Bool( argstr='-unidirectional', desc=('track from the seed point in one direction only ' '(default is to track in both directions)')) init_dir = traits.Tuple( traits.Float, traits.Float, traits.Float, argstr='-initdirection %f,%f,%f', desc=('specify an initial direction for the tracking (this ' 'should be supplied as a vector of 3 comma-separated values')) noprecompt = traits.Bool( argstr='-noprecomputed', desc=('do NOT pre-compute legendre polynomial values. Warning: this ' 'will slow down the algorithm by a factor of approximately 4')) power = traits.Int( argstr='-power %d', desc=('raise the FOD to the power specified (default is 1/nsamples)')) n_samples = traits.Int( 4, argstr='-samples %d', desc=('set the number of FOD samples to take per step for the 2nd ' 'order (iFOD2) method')) use_rk4 = traits.Bool( argstr='-rk4', desc=('use 4th-order Runge-Kutta integration (slower, but eliminates' ' curvature overshoot in 1st-order deterministic methods)')) stop = traits.Bool( argstr='-stop', desc=('stop propagating a streamline once it has traversed all ' 'include regions')) downsample = traits.Float( argstr='-downsample %f', desc='downsample the generated streamlines to reduce output file size') # Anatomically-Constrained Tractography options act_file = File( exists=True, argstr='-act %s', desc=('use the Anatomically-Constrained Tractography framework during' ' tracking; provided image must be in the 5TT ' '(five - tissue - type) format')) backtrack = traits.Bool(argstr='-backtrack', desc='allow tracks to be truncated') crop_at_gmwmi = traits.Bool( argstr='-crop_at_gmwmi', desc=('crop streamline endpoints more ' 'precisely as they cross the GM-WM interface')) # Tractography seeding options seed_sphere = traits.Tuple( traits.Float, traits.Float, traits.Float, traits.Float, argstr='-seed_sphere %f,%f,%f,%f', desc='spherical seed') seed_image = File(exists=True, argstr='-seed_image %s', desc='seed streamlines entirely at random within mask') seed_rnd_voxel = traits.Tuple( File(exists=True), traits.Int(), argstr='-seed_random_per_voxel %s %d', xor=['seed_image', 'seed_grid_voxel'], desc=('seed a fixed number of streamlines per voxel in a mask ' 'image; random placement of seeds in each voxel')) seed_grid_voxel = traits.Tuple( File(exists=True), traits.Int(), argstr='-seed_grid_per_voxel %s %d', xor=['seed_image', 'seed_rnd_voxel'], desc=('seed a fixed number of streamlines per voxel in a mask ' 'image; place seeds on a 3D mesh grid (grid_size argument ' 'is per axis; so a grid_size of 3 results in 27 seeds per' ' voxel)')) seed_rejection = File( exists=True, argstr='-seed_rejection %s', desc=('seed from an image using rejection sampling (higher ' 'values = more probable to seed from')) seed_gmwmi = File( exists=True, argstr='-seed_gmwmi %s', requires=['act_file'], desc=('seed from the grey matter - white matter interface (only ' 'valid if using ACT framework)')) seed_dynamic = File( exists=True, argstr='-seed_dynamic %s', desc=('determine seed points dynamically using the SIFT model ' '(must not provide any other seeding mechanism). Note that' ' while this seeding mechanism improves the distribution of' ' reconstructed streamlines density, it should NOT be used ' 'as a substitute for the SIFT method itself.')) max_seed_attempts = traits.Int( argstr='-max_seed_attempts %d', desc=('set the maximum number of times that the tracking ' 'algorithm should attempt to find an appropriate tracking' ' direction from a given seed point')) out_seeds = File( 'out_seeds.nii.gz', argstr='-output_seeds %s', desc=('output the seed location of all successful streamlines to' ' a file')) class TractographyOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output filtered tracks') out_seeds = File(desc=('output the seed location of all successful' ' streamlines to a file')) class Tractography(MRTrix3Base): """ Performs streamlines tractography after selecting the appropriate algorithm. .. [FACT] Mori, S.; Crain, B. J.; Chacko, V. P. & van Zijl, P. C. M. Three-dimensional tracking of axonal projections in the brain by magnetic resonance imaging. Annals of Neurology, 1999, 45, 265-269 .. [iFOD1] Tournier, J.-D.; Calamante, F. & Connelly, A. MRtrix: Diffusion tractography in crossing fiber regions. Int. J. Imaging Syst. Technol., 2012, 22, 53-66 .. [iFOD2] Tournier, J.-D.; Calamante, F. & Connelly, A. Improved probabilistic streamlines tractography by 2nd order integration over fibre orientation distributions. Proceedings of the International Society for Magnetic Resonance in Medicine, 2010, 1670 .. [Nulldist] Morris, D. M.; Embleton, K. V. & Parker, G. J. Probabilistic fibre tracking: Differentiation of connections from chance events. NeuroImage, 2008, 42, 1329-1339 .. [Tensor_Det] Basser, P. J.; Pajevic, S.; Pierpaoli, C.; Duda, J. and Aldroubi, A. In vivo fiber tractography using DT-MRI data. Magnetic Resonance in Medicine, 2000, 44, 625-632 .. [Tensor_Prob] Jones, D. Tractography Gone Wild: Probabilistic Fibre Tracking Using the Wild Bootstrap With Diffusion Tensor MRI. IEEE Transactions on Medical Imaging, 2008, 27, 1268-1274 Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> tk = mrt.Tractography() >>> tk.inputs.in_file = 'fods.mif' >>> tk.inputs.roi_mask = 'mask.nii.gz' >>> tk.inputs.seed_sphere = (80, 100, 70, 10) >>> tk.cmdline # doctest: +ELLIPSIS 'tckgen -algorithm iFOD2 -mask mask.nii.gz -seed_sphere \ 80.000000,100.000000,70.000000,10.000000 fods.mif tracked.tck' >>> tk.run() # doctest: +SKIP """ _cmd = 'tckgen' input_spec = TractographyInputSpec output_spec = TractographyOutputSpec def _format_arg(self, name, trait_spec, value): if 'roi_' in name and isinstance(value, tuple): value = ['%f' % v for v in value] return trait_spec.argstr % ','.join(value) return super(Tractography, self)._format_arg(name, trait_spec, value) def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/mrtrix3/utils.py000066400000000000000000000354061257611314500216630ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname(os.path.realpath(__file__ )) >>> datadir = os.path.realpath(os.path.join(filepath, ... '../../testing/data')) >>> os.chdir(datadir) """ import os import os.path as op from base import MRTrix3BaseInputSpec, MRTrix3Base from nipype.interfaces.base import ( CommandLineInputSpec, CommandLine, traits, TraitedSpec, File, InputMultiPath) from nipype.utils.filemanip import split_filename from nipype.interfaces.traits_extension import isdefined class BrainMaskInputSpec(MRTrix3BaseInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input diffusion weighted images') out_file = File( 'brainmask.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output brain mask') class BrainMaskOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class BrainMask(CommandLine): """ Convert a mesh surface to a partial volume estimation image Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> bmsk = mrt.BrainMask() >>> bmsk.inputs.in_file = 'dwi.mif' >>> bmsk.cmdline # doctest: +ELLIPSIS 'dwi2mask dwi.mif brainmask.mif' >>> bmsk.run() # doctest: +SKIP """ _cmd = 'dwi2mask' input_spec = BrainMaskInputSpec output_spec = BrainMaskOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class Mesh2PVEInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-3, desc='input mesh') reference = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input reference image') in_first = File( exists=True, argstr='-first %s', desc='indicates that the mesh file is provided by FSL FIRST') out_file = File( 'mesh2volume.nii.gz', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='output file containing SH coefficients') class Mesh2PVEOutputSpec(TraitedSpec): out_file = File(exists=True, desc='the output response file') class Mesh2PVE(CommandLine): """ Convert a mesh surface to a partial volume estimation image Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> m2p = mrt.Mesh2PVE() >>> m2p.inputs.in_file = 'surf1.vtk' >>> m2p.inputs.reference = 'dwi.mif' >>> m2p.inputs.in_first = 'T1.nii.gz' >>> m2p.cmdline # doctest: +ELLIPSIS 'mesh2pve -first T1.nii.gz surf1.vtk dwi.mif mesh2volume.nii.gz' >>> m2p.run() # doctest: +SKIP """ _cmd = 'mesh2pve' input_spec = Mesh2PVEInputSpec output_spec = Mesh2PVEOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class Generate5ttInputSpec(CommandLineInputSpec): in_fast = InputMultiPath( File(exists=True), argstr='%s', mandatory=True, position=-3, desc='list of PVE images from FAST') in_first = File( exists=True, argstr='%s', position=-2, desc='combined segmentation file from FIRST') out_file = File( 'act-5tt.mif', argstr='%s', mandatory=True, position=-1, usedefault=True, desc='name of output file') class Generate5ttOutputSpec(TraitedSpec): out_file = File(exists=True, desc='segmentation for ACT in 5tt format') class Generate5tt(CommandLine): """ Concatenate segmentation results from FSL FAST and FIRST into the 5TT format required for ACT Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> seg = mrt.Generate5tt() >>> seg.inputs.in_fast = ['tpm_00.nii.gz', ... 'tpm_01.nii.gz', 'tpm_02.nii.gz'] >>> seg.inputs.in_first = 'first_merged.nii.gz' >>> seg.cmdline # doctest: +ELLIPSIS '5ttgen tpm_00.nii.gz tpm_01.nii.gz tpm_02.nii.gz first_merged.nii.gz\ act-5tt.mif' >>> seg.run() # doctest: +SKIP """ _cmd = '5ttgen' input_spec = Generate5ttInputSpec output_spec = Generate5ttOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class TensorMetricsInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-1, desc='input DTI image') out_fa = File(argstr='-fa %s', desc='output FA file') out_adc = File(argstr='-adc %s', desc='output ADC file') out_evec = File(argstr='-vector %s', desc='output selected eigenvector(s) file') out_eval = File(argstr='-value %s', desc='output selected eigenvalue(s) file') component = traits.List( [1, 2, 3], argstr='-num %s', sep=',', desc=('specify the desired eigenvalue/eigenvector(s). Note that ' 'several eigenvalues can be specified as a number sequence')) in_mask = File(exists=True, argstr='-mask %s', desc=('only perform computation within the specified binary' ' brain mask image')) modulate = traits.Enum('FA', 'none', 'eval', argstr='-modulate %s', desc=('how to modulate the magnitude of the' ' eigenvectors')) class TensorMetricsOutputSpec(TraitedSpec): out_fa = File(desc='output FA file') out_adc = File(desc='output ADC file') out_evec = File(desc='output selected eigenvector(s) file') out_eval = File(desc='output selected eigenvalue(s) file') class TensorMetrics(CommandLine): """ Compute metrics from tensors Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> comp = mrt.TensorMetrics() >>> comp.inputs.in_file = 'dti.mif' >>> comp.inputs.out_fa = 'fa.mif' >>> comp.cmdline # doctest: +ELLIPSIS 'tensor2metric -fa fa.mif dti.mif' >>> comp.run() # doctest: +SKIP """ _cmd = 'tensor2metric' input_spec = TensorMetricsInputSpec output_spec = TensorMetricsOutputSpec def _list_outputs(self): outputs = self.output_spec().get() for k in outputs.keys(): if isdefined(getattr(self.inputs, k)): outputs[k] = op.abspath(getattr(self.inputs, k)) return outputs class ComputeTDIInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input tractography') out_file = File('tdi.mif', argstr='%s', usedefault=True, position=-1, desc='output TDI file') reference = File( exists=True, argstr='-template %s', desc='a reference' 'image to be used as template') vox_size = traits.List(traits.Int, argstr='-vox %s', sep=',', desc='voxel dimensions') data_type = traits.Enum('float', 'unsigned int', argstr='-datatype %s', desc='specify output image data type') use_dec = traits.Bool(argstr='-dec', desc='perform mapping in DEC space') dixel = File('dixels.txt', argstr='-dixel %s', desc='map streamlines to' 'dixels within each voxel. Directions are stored as' 'azimuth elevation pairs.') max_tod = traits.Int(argstr='-tod %d', desc='generate a Track Orientation ' 'Distribution (TOD) in each voxel.') contrast = traits.Enum('tdi', 'length', 'invlength', 'scalar_map', 'scalar_map_conut', 'fod_amp', 'curvature', argstr='-constrast %s', desc='define the desired ' 'form of contrast for the output image') in_map = File(exists=True, argstr='-image %s', desc='provide the' 'scalar image map for generating images with ' '\'scalar_map\' contrasts, or the SHs image for fod_amp') stat_vox = traits.Enum('sum', 'min', 'mean', 'max', argstr='-stat_vox %s', desc='define the statistic for choosing the final' 'voxel intesities for a given contrast') stat_tck = traits.Enum( 'mean', 'sum', 'min', 'max', 'median', 'mean_nonzero', 'gaussian', 'ends_min', 'ends_mean', 'ends_max', 'ends_prod', argstr='-stat_tck %s', desc='define the statistic for choosing ' 'the contribution to be made by each streamline as a function of' ' the samples taken along their lengths.') fwhm_tck = traits.Float( argstr='-fwhm_tck %f', desc='define the statistic for choosing the' ' contribution to be made by each streamline as a function of the ' 'samples taken along their lengths') map_zero = traits.Bool( argstr='-map_zero', desc='if a streamline has zero contribution based ' 'on the contrast & statistic, typically it is not mapped; use this ' 'option to still contribute to the map even if this is the case ' '(these non-contributing voxels can then influence the mean value in ' 'each voxel of the map)') upsample = traits.Int(argstr='-upsample %d', desc='upsample the tracks by' ' some ratio using Hermite interpolation before ' 'mappping') precise = traits.Bool( argstr='-precise', desc='use a more precise streamline mapping ' 'strategy, that accurately quantifies the length through each voxel ' '(these lengths are then taken into account during TWI calculation)') ends_only = traits.Bool(argstr='-ends_only', desc='only map the streamline' ' endpoints to the image') tck_weights = File(exists=True, argstr='-tck_weights_in %s', desc='specify' ' a text scalar file containing the streamline weights') nthreads = traits.Int( argstr='-nthreads %d', desc='number of threads. if zero, the number' ' of available cpus will be used', nohash=True) class ComputeTDIOutputSpec(TraitedSpec): out_file = File(desc='output TDI file') class ComputeTDI(MRTrix3Base): """ Use track data as a form of contrast for producing a high-resolution image. .. admonition:: References * For TDI or DEC TDI: Calamante, F.; Tournier, J.-D.; Jackson, G. D. & Connelly, A. Track-density imaging (TDI): Super-resolution white matter imaging using whole-brain track-density mapping. NeuroImage, 2010, 53, 1233-1243 * If using -contrast length and -stat_vox mean: Pannek, K.; Mathias, J. L.; Bigler, E. D.; Brown, G.; Taylor, J. D. & Rose, S. E. The average pathlength map: A diffusion MRI tractography-derived index for studying brain pathology. NeuroImage, 2011, 55, 133-141 * If using -dixel option with TDI contrast only: Smith, R.E., Tournier, J-D., Calamante, F., Connelly, A. A novel paradigm for automated segmentation of very large whole-brain probabilistic tractography data sets. In proc. ISMRM, 2011, 19, 673 * If using -dixel option with any other contrast: Pannek, K., Raffelt, D., Salvado, O., Rose, S. Incorporating directional information in diffusion tractography derived maps: angular track imaging (ATI). In Proc. ISMRM, 2012, 20, 1912 * If using -tod option: Dhollander, T., Emsell, L., Van Hecke, W., Maes, F., Sunaert, S., Suetens, P. Track Orientation Density Imaging (TODI) and Track Orientation Distribution (TOD) based tractography. NeuroImage, 2014, 94, 312-336 * If using other contrasts / statistics: Calamante, F.; Tournier, J.-D.; Smith, R. E. & Connelly, A. A generalised framework for super-resolution track-weighted imaging. NeuroImage, 2012, 59, 2494-2503 * If using -precise mapping option: Smith, R. E.; Tournier, J.-D.; Calamante, F. & Connelly, A. SIFT: Spherical-deconvolution informed filtering of tractograms. NeuroImage, 2013, 67, 298-312 (Appendix 3) Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> tdi = mrt.ComputeTDI() >>> tdi.inputs.in_file = 'dti.mif' >>> tdi.cmdline # doctest: +ELLIPSIS 'tckmap dti.mif tdi.mif' >>> tdi.run() # doctest: +SKIP """ _cmd = 'tckmap' input_spec = ComputeTDIInputSpec output_spec = ComputeTDIOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs class TCK2VTKInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='%s', mandatory=True, position=-2, desc='input tractography') out_file = File('tracks.vtk', argstr='%s', usedefault=True, position=-1, desc='output VTK file') reference = File( exists=True, argstr='-image %s', desc='if specified, the properties of' ' this image will be used to convert track point positions from real ' '(scanner) coordinates into image coordinates (in mm).') voxel = File( exists=True, argstr='-image %s', desc='if specified, the properties of' ' this image will be used to convert track point positions from real ' '(scanner) coordinates into image coordinates.') nthreads = traits.Int( argstr='-nthreads %d', desc='number of threads. if zero, the number' ' of available cpus will be used', nohash=True) class TCK2VTKOutputSpec(TraitedSpec): out_file = File(desc='output VTK file') class TCK2VTK(MRTrix3Base): """ Convert a track file to a vtk format, cave: coordinates are in XYZ coordinates not reference Example ------- >>> import nipype.interfaces.mrtrix3 as mrt >>> vtk = mrt.TCK2VTK() >>> vtk.inputs.in_file = 'tracks.tck' >>> vtk.inputs.reference = 'b0.nii' >>> vtk.cmdline # doctest: +ELLIPSIS 'tck2vtk -image b0.nii tracks.tck tracks.vtk' >>> vtk.run() # doctest: +SKIP """ _cmd = 'tck2vtk' input_spec = TCK2VTKInputSpec output_spec = TCK2VTKOutputSpec def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs nipype-0.11.0/nipype/interfaces/nipy/000077500000000000000000000000001257611314500175105ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/nipy/__init__.py000066400000000000000000000002211257611314500216140ustar00rootroot00000000000000from .model import FitGLM, EstimateContrast from .preprocess import ComputeMask, FmriRealign4d, SpaceTimeRealigner from .utils import Similarity nipype-0.11.0/nipype/interfaces/nipy/model.py000066400000000000000000000307101257611314500211630ustar00rootroot00000000000000import warnings import os import nibabel as nb import numpy as np from nipype.external import six from ...utils.misc import package_check have_nipy = True try: package_check('nipy') except Exception, e: have_nipy = False else: import nipy.modalities.fmri.design_matrix as dm import nipy.labs.glm.glm as GLM if have_nipy: try: BlockParadigm = dm.BlockParadigm except AttributeError: from nipy.modalities.fmri.experimental_paradigm import BlockParadigm from ..base import (BaseInterface, TraitedSpec, traits, File, OutputMultiPath, BaseInterfaceInputSpec, isdefined) class FitGLMInputSpec(BaseInterfaceInputSpec): session_info = traits.List(minlen=1, maxlen=1, mandatory=True, desc=('Session specific information generated by' ' ``modelgen.SpecifyModel``, FitGLM does ' 'not support multiple runs uless they are ' 'concatenated (see SpecifyModel options)')) hrf_model = traits.Enum('Canonical', 'Canonical With Derivative', 'FIR', desc=("that specifies the hemodynamic reponse " "function it can be 'Canonical', 'Canonical " "With Derivative' or 'FIR'"), usedefault=True) drift_model = traits.Enum("Cosine", "Polynomial", "Blank", desc = ("string that specifies the desired drift " "model, to be chosen among 'Polynomial', " "'Cosine', 'Blank'"), usedefault=True) TR = traits.Float(mandatory=True) model = traits.Enum("ar1", "spherical", desc=("autoregressive mode is available only for the " "kalman method"), usedefault=True) method = traits.Enum("kalman", "ols", desc=("method to fit the model, ols or kalma; kalman " "is more time consuming but it supports " "autoregressive model"), usedefault=True) mask = traits.File(exists=True, desc=("restrict the fitting only to the region defined " "by this mask")) normalize_design_matrix = traits.Bool(False, desc=("normalize (zscore) the " "regressors before fitting"), usedefault=True) save_residuals = traits.Bool(False, usedefault=True) plot_design_matrix = traits.Bool(False, usedefault=True) class FitGLMOutputSpec(TraitedSpec): beta = File(exists=True) nvbeta = traits.Any() s2 = File(exists=True) dof = traits.Any() constants = traits.Any() axis = traits.Any() reg_names = traits.List() residuals = traits.File() a = File(exists=True) class FitGLM(BaseInterface): ''' Fit GLM model based on the specified design. Supports only single or concatenated runs. ''' input_spec = FitGLMInputSpec output_spec = FitGLMOutputSpec def _run_interface(self, runtime): session_info = self.inputs.session_info functional_runs = self.inputs.session_info[0]['scans'] if isinstance(functional_runs, six.string_types): functional_runs = [functional_runs] nii = nb.load(functional_runs[0]) data = nii.get_data() if isdefined(self.inputs.mask): mask = nb.load(self.inputs.mask).get_data() > 0 else: mask = np.ones(nii.shape[:3]) == 1 timeseries = data.copy()[mask,:] del data for functional_run in functional_runs[1:]: nii = nb.load(functional_run) data = nii.get_data() npdata = data.copy() del data timeseries = np.concatenate((timeseries,npdata[mask,:]), axis=1) del npdata nscans = timeseries.shape[1] if 'hpf' in session_info[0].keys(): hpf = session_info[0]['hpf'] drift_model=self.inputs.drift_model else: hpf=0 drift_model = "Blank" reg_names = [] for reg in session_info[0]['regress']: reg_names.append(reg['name']) reg_vals = np.zeros((nscans,len(reg_names))) for i in range(len(reg_names)): reg_vals[:,i] = np.array(session_info[0]['regress'][i]['val']).reshape(1,-1) frametimes= np.linspace(0, (nscans-1)*self.inputs.TR, nscans) conditions = [] onsets = [] duration = [] for i,cond in enumerate(session_info[0]['cond']): onsets += cond['onset'] conditions += [cond['name']]*len(cond['onset']) if len(cond['duration']) == 1: duration += cond['duration']*len(cond['onset']) else: duration += cond['duration'] if conditions: paradigm = BlockParadigm(con_id=conditions, onset=onsets, duration=duration) else: paradigm = None design_matrix, self._reg_names = dm.dmtx_light(frametimes, paradigm, drift_model=drift_model, hfcut=hpf, hrf_model=self.inputs.hrf_model, add_regs=reg_vals, add_reg_names=reg_names ) if self.inputs.normalize_design_matrix: for i in range(len(self._reg_names)-1): design_matrix[:,i] = (design_matrix[:,i]-design_matrix[:,i].mean())/design_matrix[:,i].std() if self.inputs.plot_design_matrix: import pylab pylab.pcolor(design_matrix) pylab.savefig("design_matrix.pdf") pylab.close() pylab.clf() glm = GLM.glm() glm.fit(timeseries.T, design_matrix, method=self.inputs.method, model=self.inputs.model) self._beta_file = os.path.abspath("beta.nii") beta = np.zeros(mask.shape + (glm.beta.shape[0],)) beta[mask,:] = glm.beta.T nb.save(nb.Nifti1Image(beta, nii.get_affine()), self._beta_file) self._s2_file = os.path.abspath("s2.nii") s2 = np.zeros(mask.shape) s2[mask] = glm.s2 nb.save(nb.Nifti1Image(s2, nii.get_affine()), self._s2_file) if self.inputs.save_residuals: explained = np.dot(design_matrix,glm.beta) residuals = np.zeros(mask.shape + (nscans,)) residuals[mask,:] = timeseries - explained.T self._residuals_file = os.path.abspath("residuals.nii") nb.save(nb.Nifti1Image(residuals, nii.get_affine()), self._residuals_file) self._nvbeta = glm.nvbeta self._dof = glm.dof self._constants = glm._constants self._axis = glm._axis if self.inputs.model == "ar1": self._a_file = os.path.abspath("a.nii") a = np.zeros(mask.shape) a[mask] = glm.a.squeeze() nb.save(nb.Nifti1Image(a, nii.get_affine()), self._a_file) self._model = glm.model self._method = glm.method return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["beta"] = self._beta_file outputs["nvbeta"] = self._nvbeta outputs["s2"] = self._s2_file outputs["dof"] = self._dof outputs["constants"] = self._constants outputs["axis"] = self._axis outputs["reg_names"] = self._reg_names if self.inputs.model == "ar1": outputs["a"] = self._a_file if self.inputs.save_residuals: outputs["residuals"] = self._residuals_file return outputs class EstimateContrastInputSpec(BaseInterfaceInputSpec): contrasts = traits.List( traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('F'), traits.List(traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float), traits.List(traits.Float)))))), desc="""List of contrasts with each contrast being a list of the form: [('name', 'stat', [condition list], [weight list], [session list])]. if session list is None or not provided, all sessions are used. For F contrasts, the condition list should contain previously defined T-contrasts.""", mandatory=True) beta = File(exists=True, desc="beta coefficients of the fitted model",mandatory=True) nvbeta = traits.Any(mandatory=True) s2 = File(exists=True, desc="squared variance of the residuals",mandatory=True) dof = traits.Any(desc="degrees of freedom", mandatory=True) constants = traits.Any(mandatory=True) axis = traits.Any(mandatory=True) reg_names = traits.List(mandatory=True) mask = traits.File(exists=True) class EstimateContrastOutputSpec(TraitedSpec): stat_maps = OutputMultiPath(File(exists=True)) z_maps = OutputMultiPath(File(exists=True)) p_maps = OutputMultiPath(File(exists=True)) class EstimateContrast(BaseInterface): ''' Estimate contrast of a fitted model. ''' input_spec = EstimateContrastInputSpec output_spec = EstimateContrastOutputSpec def _run_interface(self, runtime): beta_nii = nb.load(self.inputs.beta) if isdefined(self.inputs.mask): mask = nb.load(self.inputs.mask).get_data() > 0 else: mask = np.ones(beta_nii.shape[:3]) == 1 glm = GLM.glm() nii = nb.load(self.inputs.beta) glm.beta = beta_nii.get_data().copy()[mask,:].T glm.nvbeta = self.inputs.nvbeta glm.s2 = nb.load(self.inputs.s2).get_data().copy()[mask] glm.dof = self.inputs.dof glm._axis = self.inputs.axis glm._constants = self.inputs.constants reg_names = self.inputs.reg_names self._stat_maps = [] self._p_maps = [] self._z_maps = [] for contrast_def in self.inputs.contrasts: name = contrast_def[0] _ = contrast_def[1] contrast = np.zeros(len(reg_names)) for i, reg_name in enumerate(reg_names): if reg_name in contrast_def[2]: idx = contrast_def[2].index(reg_name) contrast[i] = contrast_def[3][idx] est_contrast = glm.contrast(contrast) stat_map = np.zeros(mask.shape) stat_map[mask] = est_contrast.stat().T stat_map_file = os.path.abspath(name + "_stat_map.nii") nb.save(nb.Nifti1Image(stat_map, nii.get_affine()), stat_map_file) self._stat_maps.append(stat_map_file) p_map = np.zeros(mask.shape) p_map[mask] = est_contrast.pvalue().T p_map_file = os.path.abspath(name + "_p_map.nii") nb.save(nb.Nifti1Image(p_map, nii.get_affine()), p_map_file) self._p_maps.append(p_map_file) z_map = np.zeros(mask.shape) z_map[mask] = est_contrast.zscore().T z_map_file = os.path.abspath(name + "_z_map.nii") nb.save(nb.Nifti1Image(z_map, nii.get_affine()), z_map_file) self._z_maps.append(z_map_file) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["stat_maps"] = self._stat_maps outputs["p_maps"] = self._p_maps outputs["z_maps"] = self._z_maps return outputs nipype-0.11.0/nipype/interfaces/nipy/preprocess.py000066400000000000000000000357011257611314500222550ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import os import warnings import nibabel as nb import numpy as np from ...utils.misc import package_check from ...utils.filemanip import split_filename, fname_presuffix have_nipy = True try: package_check('nipy') except Exception, e: have_nipy = False else: import nipy from nipy import save_image, load_image nipy_version = nipy.__version__ from ..base import (TraitedSpec, BaseInterface, traits, BaseInterfaceInputSpec, isdefined, File, InputMultiPath, OutputMultiPath) class ComputeMaskInputSpec(BaseInterfaceInputSpec): mean_volume = File(exists=True, mandatory=True, desc="mean EPI image, used to compute the threshold for the mask") reference_volume = File(exists=True, desc=("reference volume used to compute the mask. " "If none is give, the mean volume is used.")) m = traits.Float(desc="lower fraction of the histogram to be discarded") M = traits.Float(desc="upper fraction of the histogram to be discarded") cc = traits.Bool(desc="Keep only the largest connected component") class ComputeMaskOutputSpec(TraitedSpec): brain_mask = File(exists=True) class ComputeMask(BaseInterface): input_spec = ComputeMaskInputSpec output_spec = ComputeMaskOutputSpec def _run_interface(self, runtime): from nipy.labs.mask import compute_mask args = {} for key in [k for k, _ in self.inputs.items() if k not in BaseInterfaceInputSpec().trait_names()]: value = getattr(self.inputs, key) if isdefined(value): if key in ['mean_volume', 'reference_volume']: nii = nb.load(value) value = nii.get_data() args[key] = value brain_mask = compute_mask(**args) _, name, ext = split_filename(self.inputs.mean_volume) self._brain_mask_path = os.path.abspath("%s_mask.%s" % (name, ext)) nb.save(nb.Nifti1Image(brain_mask.astype(np.uint8), nii.get_affine()), self._brain_mask_path) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["brain_mask"] = self._brain_mask_path return outputs class FmriRealign4dInputSpec(BaseInterfaceInputSpec): in_file = InputMultiPath(File(exists=True), mandatory=True, desc="File to realign") tr = traits.Float(desc="TR in seconds", mandatory=True) slice_order = traits.List(traits.Int(), desc=('0 based slice order. This would be equivalent to entering' 'np.argsort(spm_slice_order) for this field. This effects' 'interleaved acquisition. This field will be deprecated in' 'future Nipy releases and be replaced by actual slice' 'acquisition times.'), requires=["time_interp"]) tr_slices = traits.Float(desc="TR slices", requires=['time_interp']) start = traits.Float(0.0, usedefault=True, desc="time offset into TR to align slices to") time_interp = traits.Enum(True, requires=["slice_order"], desc="Assume smooth changes across time e.g.,\ fmri series. If you don't want slice timing \ correction set this to undefined") loops = InputMultiPath([5], traits.Int, usedefault=True, desc="loops within each run") between_loops = InputMultiPath([5], traits.Int, usedefault=True, desc="loops used to \ realign different \ runs") speedup = InputMultiPath([5], traits.Int, usedefault=True, desc="successive image \ sub-sampling factors \ for acceleration") class FmriRealign4dOutputSpec(TraitedSpec): out_file = OutputMultiPath(File(exists=True), desc="Realigned files") par_file = OutputMultiPath(File(exists=True), desc="Motion parameter files") class FmriRealign4d(BaseInterface): """Simultaneous motion and slice timing correction algorithm This interface wraps nipy's FmriRealign4d algorithm [1]_. Examples -------- >>> from nipype.interfaces.nipy.preprocess import FmriRealign4d >>> realigner = FmriRealign4d() >>> realigner.inputs.in_file = ['functional.nii'] >>> realigner.inputs.tr = 2 >>> realigner.inputs.slice_order = range(0,67) >>> res = realigner.run() # doctest: +SKIP References ---------- .. [1] Roche A. A four-dimensional registration algorithm with \ application to joint correction of motion and slice timing \ in fMRI. IEEE Trans Med Imaging. 2011 Aug;30(8):1546-54. DOI_. .. _DOI: http://dx.doi.org/10.1109/TMI.2011.2131152 """ input_spec = FmriRealign4dInputSpec output_spec = FmriRealign4dOutputSpec keywords = ['slice timing', 'motion correction'] def _run_interface(self, runtime): from nipy.algorithms.registration import FmriRealign4d as FR4d all_ims = [load_image(fname) for fname in self.inputs.in_file] if not isdefined(self.inputs.tr_slices): TR_slices = None else: TR_slices = self.inputs.tr_slices R = FR4d(all_ims, tr=self.inputs.tr, slice_order=self.inputs.slice_order, tr_slices=TR_slices, time_interp=self.inputs.time_interp, start=self.inputs.start) R.estimate(loops=list(self.inputs.loops), between_loops=list(self.inputs.between_loops), speedup=list(self.inputs.speedup)) corr_run = R.resample() self._out_file_path = [] self._par_file_path = [] for j, corr in enumerate(corr_run): self._out_file_path.append(os.path.abspath('corr_%s.nii.gz' % (split_filename(self.inputs.in_file[j])[1]))) save_image(corr, self._out_file_path[j]) self._par_file_path.append(os.path.abspath('%s.par' % (os.path.split(self.inputs.in_file[j])[1]))) mfile = open(self._par_file_path[j], 'w') motion = R._transforms[j] # nipy does not encode euler angles. return in original form of # translation followed by rotation vector see: # http://en.wikipedia.org/wiki/Rodrigues'_rotation_formula for i, mo in enumerate(motion): params = ['%.10f' % item for item in np.hstack((mo.translation, mo.rotation))] string = ' '.join(params) + '\n' mfile.write(string) mfile.close() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = self._out_file_path outputs['par_file'] = self._par_file_path return outputs class SpaceTimeRealignerInputSpec(BaseInterfaceInputSpec): in_file = InputMultiPath(File(exists=True), mandatory=True, min_ver='0.4.0.dev', desc="File to realign") tr = traits.Float(desc="TR in seconds", requires=['slice_times']) slice_times = traits.Either(traits.List(traits.Float()), traits.Enum('asc_alt_2', 'asc_alt_2_1', 'asc_alt_half', 'asc_alt_siemens', 'ascending', 'desc_alt_2', 'desc_alt_half', 'descending'), desc=('Actual slice acquisition times.')) slice_info = traits.Either(traits.Int, traits.List(min_len=2, max_len=2), desc=('Single integer or length 2 sequence ' 'If int, the axis in `images` that is the ' 'slice axis. In a 4D image, this will ' 'often be axis = 2. If a 2 sequence, then' ' elements are ``(slice_axis, ' 'slice_direction)``, where ``slice_axis`` ' 'is the slice axis in the image as above, ' 'and ``slice_direction`` is 1 if the ' 'slices were acquired slice 0 first, slice' ' -1 last, or -1 if acquired slice -1 ' 'first, slice 0 last. If `slice_info` is ' 'an int, assume ' '``slice_direction`` == 1.'), requires=['slice_times'], ) class SpaceTimeRealignerOutputSpec(TraitedSpec): out_file = OutputMultiPath(File(exists=True), desc="Realigned files") par_file = OutputMultiPath(File(exists=True), desc=("Motion parameter files. Angles are not " "euler angles")) class SpaceTimeRealigner(BaseInterface): """Simultaneous motion and slice timing correction algorithm If slice_times is not specified, this algorithm performs spatial motion correction This interface wraps nipy's SpaceTimeRealign algorithm [Roche2011]_ or simply the SpatialRealign algorithm when timing info is not provided. Examples -------- >>> from nipype.interfaces.nipy import SpaceTimeRealigner >>> #Run spatial realignment only >>> realigner = SpaceTimeRealigner() >>> realigner.inputs.in_file = ['functional.nii'] >>> res = realigner.run() # doctest: +SKIP >>> realigner = SpaceTimeRealigner() >>> realigner.inputs.in_file = ['functional.nii'] >>> realigner.inputs.tr = 2 >>> realigner.inputs.slice_times = range(0, 3, 67) >>> realigner.inputs.slice_info = 2 >>> res = realigner.run() # doctest: +SKIP References ---------- .. [Roche2011] Roche A. A four-dimensional registration algorithm with \ application to joint correction of motion and slice timing \ in fMRI. IEEE Trans Med Imaging. 2011 Aug;30(8):1546-54. DOI_. .. _DOI: http://dx.doi.org/10.1109/TMI.2011.2131152 """ input_spec = SpaceTimeRealignerInputSpec output_spec = SpaceTimeRealignerOutputSpec keywords = ['slice timing', 'motion correction'] @property def version(self): return nipy_version def _run_interface(self, runtime): all_ims = [load_image(fname) for fname in self.inputs.in_file] if not isdefined(self.inputs.slice_times): from nipy.algorithms.registration.groupwise_registration import \ SpaceRealign R = SpaceRealign(all_ims) else: from nipy.algorithms.registration import SpaceTimeRealign R = SpaceTimeRealign(all_ims, tr=self.inputs.tr, slice_times=self.inputs.slice_times, slice_info=self.inputs.slice_info, ) R.estimate(refscan=None) corr_run = R.resample() self._out_file_path = [] self._par_file_path = [] for j, corr in enumerate(corr_run): self._out_file_path.append(os.path.abspath('corr_%s.nii.gz' % (split_filename(self.inputs.in_file[j])[1]))) save_image(corr, self._out_file_path[j]) self._par_file_path.append(os.path.abspath('%s.par' % (os.path.split(self.inputs.in_file[j])[1]))) mfile = open(self._par_file_path[j], 'w') motion = R._transforms[j] # nipy does not encode euler angles. return in original form of # translation followed by rotation vector see: # http://en.wikipedia.org/wiki/Rodrigues'_rotation_formula for i, mo in enumerate(motion): params = ['%.10f' % item for item in np.hstack((mo.translation, mo.rotation))] string = ' '.join(params) + '\n' mfile.write(string) mfile.close() return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = self._out_file_path outputs['par_file'] = self._par_file_path return outputs class TrimInputSpec(BaseInterfaceInputSpec): in_file = File( exists=True, mandatory=True, desc="EPI image to trim") begin_index = traits.Int( 0, usedefault=True, desc='first volume') end_index = traits.Int( 0, usedefault=True, desc='last volume indexed as in python (and 0 for last)') out_file = File(desc='output filename') suffix = traits.Str( '_trim', usedefault=True, desc='suffix for out_file to use if no out_file provided') class TrimOutputSpec(TraitedSpec): out_file = File(exists=True) class Trim(BaseInterface): """ Simple interface to trim a few volumes from a 4d fmri nifti file Examples -------- >>> from nipype.interfaces.nipy.preprocess import Trim >>> trim = Trim() >>> trim.inputs.in_file = 'functional.nii' >>> trim.inputs.begin_index = 3 # remove 3 first volumes >>> res = trim.run() # doctest: +SKIP """ input_spec = TrimInputSpec output_spec = TrimOutputSpec def _run_interface(self, runtime): out_file = self._list_outputs()['out_file'] nii = nb.load(self.inputs.in_file) if self.inputs.end_index == 0: s = slice(self.inputs.begin_index, nii.shape[3]) else: s = slice(self.inputs.begin_index, self.inputs.end_index) nii2 = nb.Nifti1Image( nii.get_data()[..., s], nii.get_affine(), nii.get_header()) nb.save(nii2, out_file) return runtime def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = self.inputs.out_file if not isdefined(outputs['out_file']): outputs['out_file'] = fname_presuffix( self.inputs.in_file, newpath=os.getcwd(), suffix=self.inputs.suffix) outputs['out_file'] = os.path.abspath(outputs['out_file']) return outputs nipype-0.11.0/nipype/interfaces/nipy/tests/000077500000000000000000000000001257611314500206525ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_ComputeMask.py000066400000000000000000000015751257611314500255530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.preprocess import ComputeMask def test_ComputeMask_inputs(): input_map = dict(M=dict(), cc=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), m=dict(), mean_volume=dict(mandatory=True, ), reference_volume=dict(), ) inputs = ComputeMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ComputeMask_outputs(): output_map = dict(brain_mask=dict(), ) outputs = ComputeMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_EstimateContrast.py000066400000000000000000000022111257611314500266000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.model import EstimateContrast def test_EstimateContrast_inputs(): input_map = dict(axis=dict(mandatory=True, ), beta=dict(mandatory=True, ), constants=dict(mandatory=True, ), contrasts=dict(mandatory=True, ), dof=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mask=dict(), nvbeta=dict(mandatory=True, ), reg_names=dict(mandatory=True, ), s2=dict(mandatory=True, ), ) inputs = EstimateContrast.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EstimateContrast_outputs(): output_map = dict(p_maps=dict(), stat_maps=dict(), z_maps=dict(), ) outputs = EstimateContrast.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_FitGLM.py000066400000000000000000000024351257611314500244010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.model import FitGLM def test_FitGLM_inputs(): input_map = dict(TR=dict(mandatory=True, ), drift_model=dict(usedefault=True, ), hrf_model=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), mask=dict(), method=dict(usedefault=True, ), model=dict(usedefault=True, ), normalize_design_matrix=dict(usedefault=True, ), plot_design_matrix=dict(usedefault=True, ), save_residuals=dict(usedefault=True, ), session_info=dict(mandatory=True, ), ) inputs = FitGLM.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FitGLM_outputs(): output_map = dict(a=dict(), axis=dict(), beta=dict(), constants=dict(), dof=dict(), nvbeta=dict(), reg_names=dict(), residuals=dict(), s2=dict(), ) outputs = FitGLM.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_FmriRealign4d.py000066400000000000000000000022671257611314500257510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.preprocess import FmriRealign4d def test_FmriRealign4d_inputs(): input_map = dict(between_loops=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), loops=dict(usedefault=True, ), slice_order=dict(requires=['time_interp'], ), speedup=dict(usedefault=True, ), start=dict(usedefault=True, ), time_interp=dict(requires=['slice_order'], ), tr=dict(mandatory=True, ), tr_slices=dict(requires=['time_interp'], ), ) inputs = FmriRealign4d.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FmriRealign4d_outputs(): output_map = dict(out_file=dict(), par_file=dict(), ) outputs = FmriRealign4d.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_Similarity.py000066400000000000000000000016331257611314500254440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.utils import Similarity def test_Similarity_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), mask1=dict(), mask2=dict(), metric=dict(usedefault=True, ), volume1=dict(mandatory=True, ), volume2=dict(mandatory=True, ), ) inputs = Similarity.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Similarity_outputs(): output_map = dict(similarity=dict(), ) outputs = Similarity.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_SpaceTimeRealigner.py000066400000000000000000000017721257611314500270250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.preprocess import SpaceTimeRealigner def test_SpaceTimeRealigner_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, min_ver='0.4.0.dev', ), slice_info=dict(requires=['slice_times'], ), slice_times=dict(), tr=dict(requires=['slice_times'], ), ) inputs = SpaceTimeRealigner.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SpaceTimeRealigner_outputs(): output_map = dict(out_file=dict(), par_file=dict(), ) outputs = SpaceTimeRealigner.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/tests/test_auto_Trim.py000066400000000000000000000016411257611314500242300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nipy.preprocess import Trim def test_Trim_inputs(): input_map = dict(begin_index=dict(usedefault=True, ), end_index=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), out_file=dict(), suffix=dict(usedefault=True, ), ) inputs = Trim.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Trim_outputs(): output_map = dict(out_file=dict(), ) outputs = Trim.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nipy/utils.py000066400000000000000000000071761257611314500212350ustar00rootroot00000000000000""" Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ import warnings import nibabel as nb from ...utils.misc import package_check have_nipy = True try: package_check('nipy') except Exception, e: have_nipy = False else: from nipy.algorithms.registration.histogram_registration import HistogramRegistration from nipy.algorithms.registration.affine import Affine from ..base import (TraitedSpec, BaseInterface, traits, BaseInterfaceInputSpec, File, isdefined) class SimilarityInputSpec(BaseInterfaceInputSpec): volume1 = File(exists=True, desc="3D volume", mandatory=True) volume2 = File(exists=True, desc="3D volume", mandatory=True) mask1 = File(exists=True, desc="3D volume") mask2 = File(exists=True, desc="3D volume") metric = traits.Either(traits.Enum('cc', 'cr', 'crl1', 'mi', 'nmi', 'slr'), traits.Callable(), desc="""str or callable Cost-function for assessing image similarity. If a string, one of 'cc': correlation coefficient, 'cr': correlation ratio, 'crl1': L1-norm based correlation ratio, 'mi': mutual information, 'nmi': normalized mutual information, 'slr': supervised log-likelihood ratio. If a callable, it should take a two-dimensional array representing the image joint histogram as an input and return a float.""", usedefault=True) class SimilarityOutputSpec(TraitedSpec): similarity = traits.Float(desc="Similarity between volume 1 and 2") class Similarity(BaseInterface): """Calculates similarity between two 3D volumes. Both volumes have to be in the same coordinate system, same space within that coordinate system and with the same voxel dimensions. .. deprecated:: 0.10.0 Use :py:class:`nipype.algorithms.metrics.Similarity` instead. Example ------- >>> from nipype.interfaces.nipy.utils import Similarity >>> similarity = Similarity() >>> similarity.inputs.volume1 = 'rc1s1.nii' >>> similarity.inputs.volume2 = 'rc1s2.nii' >>> similarity.inputs.mask1 = 'mask.nii' >>> similarity.inputs.mask2 = 'mask.nii' >>> similarity.inputs.metric = 'cr' >>> res = similarity.run() # doctest: +SKIP """ input_spec = SimilarityInputSpec output_spec = SimilarityOutputSpec def __init__(self, **inputs): warnings.warn(("This interface is deprecated since 0.10.0." " Please use nipype.algorithms.metrics.Similarity"), DeprecationWarning) super(Similarity,self).__init__(**inputs) def _run_interface(self, runtime): vol1_nii = nb.load(self.inputs.volume1) vol2_nii = nb.load(self.inputs.volume2) if isdefined(self.inputs.mask1): mask1 = nb.load(self.inputs.mask1).get_data() == 1 else: mask1 = None if isdefined(self.inputs.mask2): mask2 = nb.load(self.inputs.mask2).get_data() == 1 else: mask2 = None histreg = HistogramRegistration(from_img = vol1_nii, to_img = vol2_nii, similarity=self.inputs.metric, from_mask = mask1, to_mask = mask2) self._similarity = histreg.eval(Affine()) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['similarity'] = self._similarity return outputs nipype-0.11.0/nipype/interfaces/nitime/000077500000000000000000000000001257611314500200165ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/nitime/__init__.py000066400000000000000000000003551257611314500221320ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from .analysis import (CoherenceAnalyzerInputSpec, CoherenceAnalyzerOutputSpec, CoherenceAnalyzer) nipype-0.11.0/nipype/interfaces/nitime/analysis.py000066400000000000000000000234241257611314500222200ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Interfaces to functionality from nitime for time-series analysis of fmri data - nitime.analysis.CoherenceAnalyzer: Coherence/y - nitime.fmri.io: - nitime.viz.drawmatrix_channels """ import warnings import numpy as np import tempfile from ...utils.misc import package_check from ..base import (TraitedSpec, File, Undefined, traits, BaseInterface, isdefined, BaseInterfaceInputSpec) from ...utils.filemanip import fname_presuffix have_nitime = True try: package_check('nitime') except Exception, e: have_nitime = False else: import nitime.analysis as nta from nitime.timeseries import TimeSeries import nitime.viz as viz class CoherenceAnalyzerInputSpec(BaseInterfaceInputSpec): #Input either csv file, or time-series object and use _xor_inputs to #discriminate _xor_inputs = ('in_file', 'in_TS') in_file = File(desc=('csv file with ROIs on the columns and ' 'time-points on the rows. ROI names at the top row'), exists=True, requires=('TR',)) #If you gave just a file name, you need to specify the sampling_rate: TR = traits.Float(desc=('The TR used to collect the data' 'in your csv file ')) in_TS = traits.Any(desc='a nitime TimeSeries object') NFFT = traits.Range(low=32, value=64, usedefault=True, desc=('This is the size of the window used for ' 'the spectral estimation. Use values between ' '32 and the number of samples in your time-series.' '(Defaults to 64.)')) n_overlap = traits.Range(low=0, value=0, usedefault=True, desc=('The number of samples which overlap' 'between subsequent windows.(Defaults to 0)')) frequency_range = traits.List(value=[0.02, 0.15], usedefault=True, minlen=2, maxlen=2, desc=('The range of frequencies over' 'which the analysis will average.' '[low,high] (Default [0.02,0.15]')) output_csv_file = File(desc='File to write outputs (coherence,time-delay) with file-names: file_name_ {coherence,timedelay}') output_figure_file = File(desc='File to write output figures (coherence,time-delay) with file-names: file_name_{coherence,timedelay}. Possible formats: .png,.svg,.pdf,.jpg,...') figure_type = traits.Enum('matrix', 'network', usedefault=True, desc=("The type of plot to generate, where " "'matrix' denotes a matrix image and" "'network' denotes a graph representation." " Default: 'matrix'")) class CoherenceAnalyzerOutputSpec(TraitedSpec): coherence_array = traits.Array(desc=('The pairwise coherence values' 'between the ROIs')) timedelay_array = traits.Array(desc=('The pairwise time delays between the' 'ROIs (in seconds)')) coherence_csv = File(desc=('A csv file containing the pairwise ' 'coherence values')) timedelay_csv = File(desc=('A csv file containing the pairwise ' 'time delay values')) coherence_fig = File(desc=('Figure representing coherence values')) timedelay_fig = File(desc=('Figure representing coherence values')) class CoherenceAnalyzer(BaseInterface): input_spec = CoherenceAnalyzerInputSpec output_spec = CoherenceAnalyzerOutputSpec def _read_csv(self): """ Read from csv in_file and return an array and ROI names The input file should have a first row containing the names of the ROIs (strings) the rest of the data will be read in and transposed so that the rows (TRs) will becomes the second (and last) dimension of the array """ #Check that input conforms to expectations: first_row = open(self.inputs.in_file).readline() if not first_row[1].isalpha(): raise ValueError("First row of in_file should contain ROI names as strings of characters") roi_names = open(self.inputs.in_file).readline().replace('\"', '').strip('\n').split(',') #Transpose, so that the time is the last dimension: data = np.loadtxt(self.inputs.in_file, skiprows=1, delimiter=',').T return data, roi_names def _csv2ts(self): """ Read data from the in_file and generate a nitime TimeSeries object""" data, roi_names = self._read_csv() TS = TimeSeries(data=data, sampling_interval=self.inputs.TR, time_unit='s') TS.metadata = dict(ROIs=roi_names) return TS #Rewrite _run_interface, but not run def _run_interface(self, runtime): lb, ub = self.inputs.frequency_range if self.inputs.in_TS is Undefined: # get TS form csv and inputs.TR TS = self._csv2ts() else: # get TS from inputs.in_TS TS = self.inputs.in_TS # deal with creating or storing ROI names: if not TS.metadata.has_key('ROIs'): self.ROIs = ['roi_%d' % x for x, _ in enumerate(TS.data)] else: self.ROIs = TS.metadata['ROIs'] A = nta.CoherenceAnalyzer(TS, method=dict(this_method='welch', NFFT=self.inputs.NFFT, n_overlap=self.inputs.n_overlap)) freq_idx = np.where((A.frequencies > self.inputs.frequency_range[0]) * (A.frequencies < self.inputs.frequency_range[1]))[0] #Get the coherence matrix from the analyzer, averaging on the last #(frequency) dimension: (roi X roi array) self.coherence = np.mean(A.coherence[:, :, freq_idx], -1) # Get the time delay from analyzer, (roi X roi array) self.delay = np.mean(A.delay[:, :, freq_idx], -1) return runtime #Rewrite _list_outputs (look at BET) def _list_outputs(self): outputs = self.output_spec().get() #if isdefined(self.inputs.output_csv_file): #write to a csv file and assign a value to self.coherence_file (a #file name + path) #Always defined (the arrays): outputs['coherence_array'] = self.coherence outputs['timedelay_array'] = self.delay #Conditional if isdefined(self.inputs.output_csv_file) and hasattr(self, 'coherence'): # we need to make a function that we call here that writes the # coherence values to this file "coherence_csv" and makes the # time_delay csv file?? self._make_output_files() outputs['coherence_csv'] = fname_presuffix(self.inputs.output_csv_file, suffix='_coherence') outputs['timedelay_csv'] = fname_presuffix(self.inputs.output_csv_file, suffix='_delay') if isdefined(self.inputs.output_figure_file) and hasattr(self, 'coherence'): self._make_output_figures() outputs['coherence_fig'] = fname_presuffix(self.inputs.output_figure_file, suffix='_coherence') outputs['timedelay_fig'] = fname_presuffix(self.inputs.output_figure_file, suffix='_delay') return outputs def _make_output_files(self): """ Generate the output csv files. """ for this in zip([self.coherence, self.delay], ['coherence', 'delay']): tmp_f = tempfile.mkstemp()[1] np.savetxt(tmp_f, this[0], delimiter=',') fid = open(fname_presuffix(self.inputs.output_csv_file, suffix='_%s' % this[1]), 'w+') # this writes ROIs as header line fid.write(',' + ','.join(self.ROIs) + '\n') # this writes ROI and data to a line for r, line in zip(self.ROIs, open(tmp_f)): fid.write('%s,%s' % (r, line)) fid.close() def _make_output_figures(self): """ Generate the desired figure and save the files according to self.inputs.output_figure_file """ if self.inputs.figure_type == 'matrix': fig_coh = viz.drawmatrix_channels(self.coherence, channel_names=self.ROIs, color_anchor=0) fig_coh.savefig(fname_presuffix(self.inputs.output_figure_file, suffix='_coherence')) fig_dt = viz.drawmatrix_channels(self.delay, channel_names=self.ROIs, color_anchor=0) fig_dt.savefig(fname_presuffix(self.inputs.output_figure_file, suffix='_delay')) else: fig_coh = viz.drawgraph_channels(self.coherence, channel_names=self.ROIs) fig_coh.savefig(fname_presuffix(self.inputs.output_figure_file, suffix='_coherence')) fig_dt = viz.drawgraph_channels(self.delay, channel_names=self.ROIs) fig_dt.savefig(fname_presuffix(self.inputs.output_figure_file, suffix='_delay')) class GetTimeSeriesInputSpec(): pass class GetTimeSeriesOutputSpec(): pass class GetTimeSeries(): # getting time series data from nifti files and ROIs pass nipype-0.11.0/nipype/interfaces/nitime/tests/000077500000000000000000000000001257611314500211605ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/nitime/tests/test_auto_CoherenceAnalyzer.py000066400000000000000000000023451257611314500272260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.nitime.analysis import CoherenceAnalyzer def test_CoherenceAnalyzer_inputs(): input_map = dict(NFFT=dict(usedefault=True, ), TR=dict(), figure_type=dict(usedefault=True, ), frequency_range=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_TS=dict(), in_file=dict(requires=('TR',), ), n_overlap=dict(usedefault=True, ), output_csv_file=dict(), output_figure_file=dict(), ) inputs = CoherenceAnalyzer.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CoherenceAnalyzer_outputs(): output_map = dict(coherence_array=dict(), coherence_csv=dict(), coherence_fig=dict(), timedelay_array=dict(), timedelay_csv=dict(), timedelay_fig=dict(), ) outputs = CoherenceAnalyzer.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/nitime/tests/test_nitime.py000066400000000000000000000050621257611314500240610ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import tempfile import numpy as np from nipype.testing import (assert_equal, assert_raises, skipif) from nipype.testing import example_data import nipype.interfaces.nitime as nitime no_nitime = not nitime.analysis.have_nitime display_available = 'DISPLAY' in os.environ and os.environ['DISPLAY'] @skipif(no_nitime) def test_read_csv(): """Test that reading the data from csv file gives you back a reasonable time-series object """ CA = nitime.CoherenceAnalyzer() CA.inputs.TR = 1.89 # bogus value just to pass traits test CA.inputs.in_file = example_data('fmri_timeseries_nolabels.csv') yield assert_raises,ValueError,CA._read_csv CA.inputs.in_file = example_data('fmri_timeseries.csv') data,roi_names = CA._read_csv() yield assert_equal, data[0][0],10125.9 yield assert_equal, roi_names[0],'WM' @skipif(no_nitime) def test_coherence_analysis(): """Test that the coherence analyzer works """ import nitime.analysis as nta import nitime.timeseries as ts #This is the nipype interface analysis: CA = nitime.CoherenceAnalyzer() CA.inputs.TR = 1.89 CA.inputs.in_file = example_data('fmri_timeseries.csv') if display_available: tmp_png = tempfile.mkstemp(suffix='.png')[1] CA.inputs.output_figure_file = tmp_png tmp_csv = tempfile.mkstemp(suffix='.csv')[1] CA.inputs.output_csv_file = tmp_csv o = CA.run() yield assert_equal,o.outputs.coherence_array.shape,(31,31) #This is the nitime analysis: TR=1.89 data_rec = np.recfromcsv(example_data('fmri_timeseries.csv')) roi_names= np.array(data_rec.dtype.names) n_samples = data_rec.shape[0] data = np.zeros((len(roi_names),n_samples)) for n_idx, roi in enumerate(roi_names): data[n_idx] = data_rec[roi] T = ts.TimeSeries(data,sampling_interval=TR) yield assert_equal,CA._csv2ts().data,T.data T.metadata['roi'] = roi_names C = nta.CoherenceAnalyzer(T,method=dict(this_method='welch', NFFT=CA.inputs.NFFT, n_overlap=CA.inputs.n_overlap)) freq_idx = np.where((C.frequencies>CA.inputs.frequency_range[0]) * (C.frequencies0 instead of thresholding? set fmri(conmask_zerothresh_yn) 0 nipype-0.11.0/nipype/interfaces/script_templates/feat_contrasts.tcl000066400000000000000000000377351257611314500256550ustar00rootroot00000000000000# Contrast & F-tests mode # real : control real EVs # orig : control original EVs set fmri(con_mode_old) orig set fmri(con_mode) orig ### Needs iteration # Display images for contrast_real 1 set fmri(conpic_real.1) 1 # Title for contrast_real 1 set fmri(conname_real.1) "left>right" # Real contrast_real vector 1 element 1 set fmri(con_real1.1) 1 # Real contrast_real vector 1 element 2 set fmri(con_real1.2) -1.0 # Real contrast_real vector 1 element 3 set fmri(con_real1.3) 1.0 # Real contrast_real vector 1 element 4 set fmri(con_real1.4) -1.0 # Real contrast_real vector 1 element 5 set fmri(con_real1.5) 1.0 # Real contrast_real vector 1 element 6 set fmri(con_real1.6) -1.0 # Real contrast_real vector 1 element 7 set fmri(con_real1.7) 1.0 # Real contrast_real vector 1 element 8 set fmri(con_real1.8) -1.0 # Display images for contrast_real 2 set fmri(conpic_real.2) 1 # Title for contrast_real 2 set fmri(conname_real.2) "visual>vibe" # Real contrast_real vector 2 element 1 set fmri(con_real2.1) -1.0 # Real contrast_real vector 2 element 2 set fmri(con_real2.2) -1.0 # Real contrast_real vector 2 element 3 set fmri(con_real2.3) -1.0 # Real contrast_real vector 2 element 4 set fmri(con_real2.4) -1.0 # Real contrast_real vector 2 element 5 set fmri(con_real2.5) 1.0 # Real contrast_real vector 2 element 6 set fmri(con_real2.6) 1.0 # Real contrast_real vector 2 element 7 set fmri(con_real2.7) 1.0 # Real contrast_real vector 2 element 8 set fmri(con_real2.8) 1.0 # Display images for contrast_real 3 set fmri(conpic_real.3) 1 # Title for contrast_real 3 set fmri(conname_real.3) "seq>all" # Real contrast_real vector 3 element 1 set fmri(con_real3.1) -1.0 # Real contrast_real vector 3 element 2 set fmri(con_real3.2) -1.0 # Real contrast_real vector 3 element 3 set fmri(con_real3.3) 1.0 # Real contrast_real vector 3 element 4 set fmri(con_real3.4) 1.0 # Real contrast_real vector 3 element 5 set fmri(con_real3.5) -1.0 # Real contrast_real vector 3 element 6 set fmri(con_real3.6) -1.0 # Real contrast_real vector 3 element 7 set fmri(con_real3.7) 1.0 # Real contrast_real vector 3 element 8 set fmri(con_real3.8) 1.0 # Display images for contrast_real 4 set fmri(conpic_real.4) 1 # Title for contrast_real 4 set fmri(conname_real.4) "visual seq>all" # Real contrast_real vector 4 element 1 set fmri(con_real4.1) 0 # Real contrast_real vector 4 element 2 set fmri(con_real4.2) 0 # Real contrast_real vector 4 element 3 set fmri(con_real4.3) 0 # Real contrast_real vector 4 element 4 set fmri(con_real4.4) 0 # Real contrast_real vector 4 element 5 set fmri(con_real4.5) -1.0 # Real contrast_real vector 4 element 6 set fmri(con_real4.6) -1.0 # Real contrast_real vector 4 element 7 set fmri(con_real4.7) 1.0 # Real contrast_real vector 4 element 8 set fmri(con_real4.8) 1.0 # Display images for contrast_real 5 set fmri(conpic_real.5) 1 # Title for contrast_real 5 set fmri(conname_real.5) "vibe seq>all" # Real contrast_real vector 5 element 1 set fmri(con_real5.1) -1.0 # Real contrast_real vector 5 element 2 set fmri(con_real5.2) -1.0 # Real contrast_real vector 5 element 3 set fmri(con_real5.3) 1.0 # Real contrast_real vector 5 element 4 set fmri(con_real5.4) 1.0 # Real contrast_real vector 5 element 5 set fmri(con_real5.5) 0 # Real contrast_real vector 5 element 6 set fmri(con_real5.6) 0 # Real contrast_real vector 5 element 7 set fmri(con_real5.7) 0 # Real contrast_real vector 5 element 8 set fmri(con_real5.8) 0 # Display images for contrast_real 6 set fmri(conpic_real.6) 1 # Title for contrast_real 6 set fmri(conname_real.6) "visual seq>vibe seq" # Real contrast_real vector 6 element 1 set fmri(con_real6.1) 0 # Real contrast_real vector 6 element 2 set fmri(con_real6.2) 0 # Real contrast_real vector 6 element 3 set fmri(con_real6.3) -1.0 # Real contrast_real vector 6 element 4 set fmri(con_real6.4) -1.0 # Real contrast_real vector 6 element 5 set fmri(con_real6.5) 0 # Real contrast_real vector 6 element 6 set fmri(con_real6.6) 0 # Real contrast_real vector 6 element 7 set fmri(con_real6.7) 1.0 # Real contrast_real vector 6 element 8 set fmri(con_real6.8) 1.0 # Display images for contrast_real 7 set fmri(conpic_real.7) 1 # Title for contrast_real 7 set fmri(conname_real.7) "visual all>vibe all" # Real contrast_real vector 7 element 1 set fmri(con_real7.1) -1.0 # Real contrast_real vector 7 element 2 set fmri(con_real7.2) -1.0 # Real contrast_real vector 7 element 3 set fmri(con_real7.3) 0 # Real contrast_real vector 7 element 4 set fmri(con_real7.4) 0 # Real contrast_real vector 7 element 5 set fmri(con_real7.5) 1.0 # Real contrast_real vector 7 element 6 set fmri(con_real7.6) 1.0 # Real contrast_real vector 7 element 7 set fmri(con_real7.7) 0 # Real contrast_real vector 7 element 8 set fmri(con_real7.8) 0 # Display images for contrast_real 8 set fmri(conpic_real.8) 1 # Title for contrast_real 8 set fmri(conname_real.8) "mode x complexity" # Real contrast_real vector 8 element 1 set fmri(con_real8.1) -1.0 # Real contrast_real vector 8 element 2 set fmri(con_real8.2) -1.0 # Real contrast_real vector 8 element 3 set fmri(con_real8.3) 1.0 # Real contrast_real vector 8 element 4 set fmri(con_real8.4) 1.0 # Real contrast_real vector 8 element 5 set fmri(con_real8.5) 1.0 # Real contrast_real vector 8 element 6 set fmri(con_real8.6) 1.0 # Real contrast_real vector 8 element 7 set fmri(con_real8.7) -1.0 # Real contrast_real vector 8 element 8 set fmri(con_real8.8) -1.0 # Display images for contrast_orig 1 set fmri(conpic_orig.1) 1 # Title for contrast_orig 1 set fmri(conname_orig.1) "left>right" # Real contrast_orig vector 1 element 1 set fmri(con_orig1.1) 1 # Real contrast_orig vector 1 element 2 set fmri(con_orig1.2) -1.0 # Real contrast_orig vector 1 element 3 set fmri(con_orig1.3) 1.0 # Real contrast_orig vector 1 element 4 set fmri(con_orig1.4) -1.0 # Real contrast_orig vector 1 element 5 set fmri(con_orig1.5) 1.0 # Real contrast_orig vector 1 element 6 set fmri(con_orig1.6) -1.0 # Real contrast_orig vector 1 element 7 set fmri(con_orig1.7) 1.0 # Real contrast_orig vector 1 element 8 set fmri(con_orig1.8) -1.0 # Display images for contrast_orig 2 set fmri(conpic_orig.2) 1 # Title for contrast_orig 2 set fmri(conname_orig.2) "visual>vibe" # Real contrast_orig vector 2 element 1 set fmri(con_orig2.1) -1.0 # Real contrast_orig vector 2 element 2 set fmri(con_orig2.2) -1.0 # Real contrast_orig vector 2 element 3 set fmri(con_orig2.3) -1.0 # Real contrast_orig vector 2 element 4 set fmri(con_orig2.4) -1.0 # Real contrast_orig vector 2 element 5 set fmri(con_orig2.5) 1.0 # Real contrast_orig vector 2 element 6 set fmri(con_orig2.6) 1.0 # Real contrast_orig vector 2 element 7 set fmri(con_orig2.7) 1.0 # Real contrast_orig vector 2 element 8 set fmri(con_orig2.8) 1.0 # Display images for contrast_orig 3 set fmri(conpic_orig.3) 1 # Title for contrast_orig 3 set fmri(conname_orig.3) "seq>all" # Real contrast_orig vector 3 element 1 set fmri(con_orig3.1) -1.0 # Real contrast_orig vector 3 element 2 set fmri(con_orig3.2) -1.0 # Real contrast_orig vector 3 element 3 set fmri(con_orig3.3) 1.0 # Real contrast_orig vector 3 element 4 set fmri(con_orig3.4) 1.0 # Real contrast_orig vector 3 element 5 set fmri(con_orig3.5) -1.0 # Real contrast_orig vector 3 element 6 set fmri(con_orig3.6) -1.0 # Real contrast_orig vector 3 element 7 set fmri(con_orig3.7) 1.0 # Real contrast_orig vector 3 element 8 set fmri(con_orig3.8) 1.0 # Display images for contrast_orig 4 set fmri(conpic_orig.4) 1 # Title for contrast_orig 4 set fmri(conname_orig.4) "visual seq>all" # Real contrast_orig vector 4 element 1 set fmri(con_orig4.1) 0 # Real contrast_orig vector 4 element 2 set fmri(con_orig4.2) 0 # Real contrast_orig vector 4 element 3 set fmri(con_orig4.3) 0 # Real contrast_orig vector 4 element 4 set fmri(con_orig4.4) 0 # Real contrast_orig vector 4 element 5 set fmri(con_orig4.5) -1.0 # Real contrast_orig vector 4 element 6 set fmri(con_orig4.6) -1.0 # Real contrast_orig vector 4 element 7 set fmri(con_orig4.7) 1.0 # Real contrast_orig vector 4 element 8 set fmri(con_orig4.8) 1.0 # Display images for contrast_orig 5 set fmri(conpic_orig.5) 1 # Title for contrast_orig 5 set fmri(conname_orig.5) "vibe seq>all" # Real contrast_orig vector 5 element 1 set fmri(con_orig5.1) -1.0 # Real contrast_orig vector 5 element 2 set fmri(con_orig5.2) -1.0 # Real contrast_orig vector 5 element 3 set fmri(con_orig5.3) 1.0 # Real contrast_orig vector 5 element 4 set fmri(con_orig5.4) 1.0 # Real contrast_orig vector 5 element 5 set fmri(con_orig5.5) 0 # Real contrast_orig vector 5 element 6 set fmri(con_orig5.6) 0 # Real contrast_orig vector 5 element 7 set fmri(con_orig5.7) 0 # Real contrast_orig vector 5 element 8 set fmri(con_orig5.8) 0 # Display images for contrast_orig 6 set fmri(conpic_orig.6) 1 # Title for contrast_orig 6 set fmri(conname_orig.6) "visual seq>vibe seq" # Real contrast_orig vector 6 element 1 set fmri(con_orig6.1) 0 # Real contrast_orig vector 6 element 2 set fmri(con_orig6.2) 0 # Real contrast_orig vector 6 element 3 set fmri(con_orig6.3) -1.0 # Real contrast_orig vector 6 element 4 set fmri(con_orig6.4) -1.0 # Real contrast_orig vector 6 element 5 set fmri(con_orig6.5) 0 # Real contrast_orig vector 6 element 6 set fmri(con_orig6.6) 0 # Real contrast_orig vector 6 element 7 set fmri(con_orig6.7) 1.0 # Real contrast_orig vector 6 element 8 set fmri(con_orig6.8) 1.0 # Display images for contrast_orig 7 set fmri(conpic_orig.7) 1 # Title for contrast_orig 7 set fmri(conname_orig.7) "visual all>vibe all" # Real contrast_orig vector 7 element 1 set fmri(con_orig7.1) -1.0 # Real contrast_orig vector 7 element 2 set fmri(con_orig7.2) -1.0 # Real contrast_orig vector 7 element 3 set fmri(con_orig7.3) 0 # Real contrast_orig vector 7 element 4 set fmri(con_orig7.4) 0 # Real contrast_orig vector 7 element 5 set fmri(con_orig7.5) 1.0 # Real contrast_orig vector 7 element 6 set fmri(con_orig7.6) 1.0 # Real contrast_orig vector 7 element 7 set fmri(con_orig7.7) 0 # Real contrast_orig vector 7 element 8 set fmri(con_orig7.8) 0 # Display images for contrast_orig 8 set fmri(conpic_orig.8) 1 # Title for contrast_orig 8 set fmri(conname_orig.8) "mode x complexity" # Real contrast_orig vector 8 element 1 set fmri(con_orig8.1) -1.0 # Real contrast_orig vector 8 element 2 set fmri(con_orig8.2) -1.0 # Real contrast_orig vector 8 element 3 set fmri(con_orig8.3) 1.0 # Real contrast_orig vector 8 element 4 set fmri(con_orig8.4) 1.0 # Real contrast_orig vector 8 element 5 set fmri(con_orig8.5) 1.0 # Real contrast_orig vector 8 element 6 set fmri(con_orig8.6) 1.0 # Real contrast_orig vector 8 element 7 set fmri(con_orig8.7) -1.0 # Real contrast_orig vector 8 element 8 set fmri(con_orig8.8) -1.0 ### This is fixed # Contrast masking - use >0 instead of thresholding? set fmri(conmask_zerothresh_yn) 0 ### These are set for the full combo of contrasts - needs iteration # Mask real contrast/F-test 1 with real contrast/F-test 2? set fmri(conmask1_2) 0 # Mask real contrast/F-test 1 with real contrast/F-test 3? set fmri(conmask1_3) 0 # Mask real contrast/F-test 1 with real contrast/F-test 4? set fmri(conmask1_4) 0 # Mask real contrast/F-test 1 with real contrast/F-test 5? set fmri(conmask1_5) 0 # Mask real contrast/F-test 1 with real contrast/F-test 6? set fmri(conmask1_6) 0 # Mask real contrast/F-test 1 with real contrast/F-test 7? set fmri(conmask1_7) 0 # Mask real contrast/F-test 1 with real contrast/F-test 8? set fmri(conmask1_8) 0 # Mask real contrast/F-test 2 with real contrast/F-test 1? set fmri(conmask2_1) 0 # Mask real contrast/F-test 2 with real contrast/F-test 3? set fmri(conmask2_3) 0 # Mask real contrast/F-test 2 with real contrast/F-test 4? set fmri(conmask2_4) 0 # Mask real contrast/F-test 2 with real contrast/F-test 5? set fmri(conmask2_5) 0 # Mask real contrast/F-test 2 with real contrast/F-test 6? set fmri(conmask2_6) 0 # Mask real contrast/F-test 2 with real contrast/F-test 7? set fmri(conmask2_7) 0 # Mask real contrast/F-test 2 with real contrast/F-test 8? set fmri(conmask2_8) 0 # Mask real contrast/F-test 3 with real contrast/F-test 1? set fmri(conmask3_1) 0 # Mask real contrast/F-test 3 with real contrast/F-test 2? set fmri(conmask3_2) 0 # Mask real contrast/F-test 3 with real contrast/F-test 4? set fmri(conmask3_4) 0 # Mask real contrast/F-test 3 with real contrast/F-test 5? set fmri(conmask3_5) 0 # Mask real contrast/F-test 3 with real contrast/F-test 6? set fmri(conmask3_6) 0 # Mask real contrast/F-test 3 with real contrast/F-test 7? set fmri(conmask3_7) 0 # Mask real contrast/F-test 3 with real contrast/F-test 8? set fmri(conmask3_8) 0 # Mask real contrast/F-test 4 with real contrast/F-test 1? set fmri(conmask4_1) 0 # Mask real contrast/F-test 4 with real contrast/F-test 2? set fmri(conmask4_2) 0 # Mask real contrast/F-test 4 with real contrast/F-test 3? set fmri(conmask4_3) 0 # Mask real contrast/F-test 4 with real contrast/F-test 5? set fmri(conmask4_5) 0 # Mask real contrast/F-test 4 with real contrast/F-test 6? set fmri(conmask4_6) 0 # Mask real contrast/F-test 4 with real contrast/F-test 7? set fmri(conmask4_7) 0 # Mask real contrast/F-test 4 with real contrast/F-test 8? set fmri(conmask4_8) 0 # Mask real contrast/F-test 5 with real contrast/F-test 1? set fmri(conmask5_1) 0 # Mask real contrast/F-test 5 with real contrast/F-test 2? set fmri(conmask5_2) 0 # Mask real contrast/F-test 5 with real contrast/F-test 3? set fmri(conmask5_3) 0 # Mask real contrast/F-test 5 with real contrast/F-test 4? set fmri(conmask5_4) 0 # Mask real contrast/F-test 5 with real contrast/F-test 6? set fmri(conmask5_6) 0 # Mask real contrast/F-test 5 with real contrast/F-test 7? set fmri(conmask5_7) 0 # Mask real contrast/F-test 5 with real contrast/F-test 8? set fmri(conmask5_8) 0 # Mask real contrast/F-test 6 with real contrast/F-test 1? set fmri(conmask6_1) 0 # Mask real contrast/F-test 6 with real contrast/F-test 2? set fmri(conmask6_2) 0 # Mask real contrast/F-test 6 with real contrast/F-test 3? set fmri(conmask6_3) 0 # Mask real contrast/F-test 6 with real contrast/F-test 4? set fmri(conmask6_4) 0 # Mask real contrast/F-test 6 with real contrast/F-test 5? set fmri(conmask6_5) 0 # Mask real contrast/F-test 6 with real contrast/F-test 7? set fmri(conmask6_7) 0 # Mask real contrast/F-test 6 with real contrast/F-test 8? set fmri(conmask6_8) 0 # Mask real contrast/F-test 7 with real contrast/F-test 1? set fmri(conmask7_1) 0 # Mask real contrast/F-test 7 with real contrast/F-test 2? set fmri(conmask7_2) 0 # Mask real contrast/F-test 7 with real contrast/F-test 3? set fmri(conmask7_3) 0 # Mask real contrast/F-test 7 with real contrast/F-test 4? set fmri(conmask7_4) 0 # Mask real contrast/F-test 7 with real contrast/F-test 5? set fmri(conmask7_5) 0 # Mask real contrast/F-test 7 with real contrast/F-test 6? set fmri(conmask7_6) 0 # Mask real contrast/F-test 7 with real contrast/F-test 8? set fmri(conmask7_8) 0 # Mask real contrast/F-test 8 with real contrast/F-test 1? set fmri(conmask8_1) 0 # Mask real contrast/F-test 8 with real contrast/F-test 2? set fmri(conmask8_2) 0 # Mask real contrast/F-test 8 with real contrast/F-test 3? set fmri(conmask8_3) 0 # Mask real contrast/F-test 8 with real contrast/F-test 4? set fmri(conmask8_4) 0 # Mask real contrast/F-test 8 with real contrast/F-test 5? set fmri(conmask8_5) 0 # Mask real contrast/F-test 8 with real contrast/F-test 6? set fmri(conmask8_6) 0 # Mask real contrast/F-test 8 with real contrast/F-test 7? set fmri(conmask8_7) 0 ### The rest is just fixed # Do contrast masking at all? set fmri(conmask1_1) 0 # Now options that don't appear in the GUI # Alternative example_func image (not derived from input 4D dataset) set fmri(alternative_example_func) "" # Alternative (to BETting) mask image set fmri(alternative_mask) "" # Initial structural space registration initialisation transform set fmri(init_initial_highres) "" # Structural space registration initialisation transform set fmri(init_highres) "" # Standard space registration initialisation transform set fmri(init_standard) "" # For full FEAT analysis: overwrite existing .feat output dir? set fmri(overwrite_yn) 1 nipype-0.11.0/nipype/interfaces/script_templates/feat_ev_gamma.tcl000066400000000000000000000013451257611314500253750ustar00rootroot00000000000000# EV title set fmri(evtitle$ev_num) "$ev_name" # Basic waveform shape # 0 : Square # 1 : Sinusoid # 2 : Custom (1 entry per volume) # 3 : Custom (3 column format) # 4 : Interaction # 10 : Empty (all zeros) set fmri(shape$ev_num) 3 # Convolution # 0 : None # 1 : Gaussian # 2 : Gamma # 3 : Double-Gamma HRF # 4 : Gamma basis functions # 5 : Sine basis functions # 6 : FIR basis functions set fmri(convolve$ev_num) 2 # Convolve phase set fmri(convolve_phase$ev_num) 0 # Apply temporal filtering set fmri(tempfilt_yn$ev_num) 1 # Add temporal derivative set fmri(deriv_yn$ev_num) $temporalderiv # Custom EV file set fmri(custom$ev_num) "$cond_file" # Gamma sigma set fmri(gammasigma$ev_num) 3 # Gamma delay set fmri(gammadelay$ev_num) 6 nipype-0.11.0/nipype/interfaces/script_templates/feat_ev_hrf.tcl000066400000000000000000000013441257611314500250710ustar00rootroot00000000000000# EV title set fmri(evtitle$ev_num) "$ev_name" # Basic waveform shape (EV $ev_num) # 0 : Square # 1 : Sinusoid # 2 : Custom (1 entry per volume) # 3 : Custom (3 column format) # 4 : Interaction # 10 : Empty (all zeros) set fmri(shape$ev_num) 3 # Convolution (EV $ev_num) # 0 : None # 1 : Gaussian # 2 : Gamma # 3 : Double-Gamma HRF # 4 : Gamma basis functions # 5 : Sine basis functions # 6 : FIR basis functions set fmri(convolve$ev_num) 3 # Convolve phase (EV $ev_num) set fmri(convolve_phase$ev_num) 0 # Apply temporal filtering (EV $ev_num) set fmri(tempfilt_yn$ev_num) $tempfilt_yn # Add temporal derivative (EV $ev_num) set fmri(deriv_yn$ev_num) $temporalderiv # Custom EV file (EV $ev_num) set fmri(custom$ev_num) "$cond_file" nipype-0.11.0/nipype/interfaces/script_templates/feat_ev_none.tcl000066400000000000000000000011251257611314500252460ustar00rootroot00000000000000# EV title set fmri(evtitle$ev_num) "$ev_name" # Basic waveform shape # 0 : Square # 1 : Sinusoid # 2 : Custom (1 entry per volume) # 3 : Custom (3 column format) # 4 : Interaction # 10 : Empty (all zeros) set fmri(shape$ev_num) 2 # Convolution # 0 : None # 1 : Gaussian # 2 : Gamma # 3 : Double-Gamma HRF # 4 : Gamma basis functions # 5 : Sine basis functions # 6 : FIR basis functions set fmri(convolve$ev_num) 0 # Apply temporal filtering set fmri(tempfilt_yn$ev_num) $tempfilt_yn # Add temporal derivative set fmri(deriv_yn$ev_num) 0 # Custom EV file set fmri(custom$ev_num) "$cond_file" nipype-0.11.0/nipype/interfaces/script_templates/feat_ev_ortho.tcl000066400000000000000000000000731257611314500254430ustar00rootroot00000000000000# Orthogonalise EV $c0 wrt EV $c1 set fmri(ortho$c0.$c1) 0 nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_copes.tcl000066400000000000000000000001321257611314500253750ustar00rootroot00000000000000# Use lower-level cope $copeno for higher-level analysis set fmri(copeinput.${copeno}) 1 nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_ev_element.tcl000066400000000000000000000002171257611314500264130ustar00rootroot00000000000000# Higher-level EV value for EV 1 and input $input set fmri(evg${input}.1) 1 # Group membership for input $input set fmri(groupmem.${input}) 1 nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_ev_header.tcl000066400000000000000000000014241257611314500262130ustar00rootroot00000000000000# Add confound EVs text file set fmri(confoundevs) 0 # EV 1 title set fmri(evtitle1) "" # Basic waveform shape (EV 1) # 0 : Square # 1 : Sinusoid # 2 : Custom (1 entry per volume) # 3 : Custom (3 column format) # 4 : Interaction # 10 : Empty (all zeros) set fmri(shape1) 2 # Convolution (EV 1) # 0 : None # 1 : Gaussian # 2 : Gamma # 3 : Double-Gamma HRF # 4 : Gamma basis functions # 5 : Sine basis functions # 6 : FIR basis functions set fmri(convolve1) 0 # Convolve phase (EV 1) set fmri(convolve_phase1) 0 # Apply temporal filtering (EV 1) set fmri(tempfilt_yn1) 0 # Add temporal derivative (EV 1) set fmri(deriv_yn1) 0 # Custom EV file (EV 1) set fmri(custom1) "dummy" # Orthogonalise EV 1 wrt EV 0 set fmri(ortho1.0) 0 # Orthogonalise EV 1 wrt EV 1 set fmri(ortho1.1) 0 nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_featdirs.tcl000066400000000000000000000001151257611314500260660ustar00rootroot00000000000000# 4D AVW data or FEAT directory ($runno) set feat_files($runno) "${rundir}" nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_footer.tcl000066400000000000000000000021351257611314500255670ustar00rootroot00000000000000# Contrast & F-tests mode # real : control real EVs # orig : control original EVs set fmri(con_mode_old) real set fmri(con_mode) real # Display images for contrast_real 1 set fmri(conpic_real.1) 1 # Title for contrast_real 1 set fmri(conname_real.1) "group mean" # Real contrast_real vector 1 element 1 set fmri(con_real1.1) 1 # Contrast masking - use >0 instead of thresholding? set fmri(conmask_zerothresh_yn) 0 # Do contrast masking at all? set fmri(conmask1_1) 0 ########################################################## # Now options that don't appear in the GUI # Alternative example_func image (not derived from input 4D dataset) set fmri(alternative_example_func) "" # Alternative (to BETting) mask image set fmri(alternative_mask) "" # Initial structural space registration initialisation transform set fmri(init_initial_highres) "" # Structural space registration initialisation transform set fmri(init_highres) "" # Standard space registration initialisation transform set fmri(init_standard) "" # For full FEAT analysis: overwrite existing .feat output dir? set fmri(overwrite_yn) $overwrite nipype-0.11.0/nipype/interfaces/script_templates/feat_fe_header.tcl000066400000000000000000000122521257611314500255220ustar00rootroot00000000000000# FEAT version number set fmri(version) 5.98 # Are we in MELODIC? set fmri(inmelodic) 0 # Analysis level # 1 : First-level analysis # 2 : Higher-level analysis set fmri(level) 2 # Which stages to run # 0 : No first-level analysis (registration and/or group stats only) # 7 : Full first-level analysis # 1 : Pre-Stats # 3 : Pre-Stats + Stats # 2 : Stats # 6 : Stats + Post-stats # 4 : Post-stats set fmri(analysis) 6 # Use relative filenames set fmri(relative_yn) 0 # Balloon help set fmri(help_yn) 1 # Run Featwatcher set fmri(featwatcher_yn) 1 # Cleanup first-level standard-space images set fmri(sscleanup_yn) 0 # Output directory set fmri(outputdir) "./output" # TR(s) set fmri(tr) 3 # Total volumes set fmri(npts) ${num_runs} # Delete volumes set fmri(ndelete) 0 # Perfusion tag/control order set fmri(tagfirst) 1 # Number of first-level analyses set fmri(multiple) ${num_runs} # Higher-level input type # 1 : Inputs are lower-level FEAT directories # 2 : Inputs are cope images from FEAT directories set fmri(inputtype) 1 # Carry out pre-stats processing? set fmri(filtering_yn) 0 # Brain/background threshold, % set fmri(brain_thresh) 10 # Critical z for design efficiency calculation set fmri(critical_z) 5.3 # Noise level set fmri(noise) 0.66 # Noise AR(1) set fmri(noisear) 0.34 # Post-stats-only directory copying # 0 : Overwrite original post-stats results # 1 : Copy original FEAT directory for new Contrasts, Thresholding, Rendering set fmri(newdir_yn) 0 # Motion correction # 0 : None # 1 : MCFLIRT set fmri(mc) 1 # Spin-history (currently obsolete) set fmri(sh_yn) 0 # B0 fieldmap unwarping? set fmri(regunwarp_yn) 0 # EPI dwell time (ms) set fmri(dwell) 0.7 # EPI TE (ms) set fmri(te) 35 # % Signal loss threshold set fmri(signallossthresh) 10 # Unwarp direction set fmri(unwarp_dir) y- # Slice timing correction # 0 : None # 1 : Regular up (0, 1, 2, 3, ...) # 2 : Regular down # 3 : Use slice order file # 4 : Use slice timings file # 5 : Interleaved (0, 2, 4 ... 1, 3, 5 ... ) set fmri(st) 0 # Slice timings file set fmri(st_file) "" # BET brain extraction set fmri(bet_yn) 1 # Spatial smoothing FWHM (mm) set fmri(smooth) 5 # Intensity normalization set fmri(norm_yn) 0 # Perfusion subtraction set fmri(perfsub_yn) 0 # Highpass temporal filtering set fmri(temphp_yn) 1 # Lowpass temporal filtering set fmri(templp_yn) 0 # MELODIC ICA data exploration set fmri(melodic_yn) 0 # Carry out main stats? set fmri(stats_yn) 1 # Carry out prewhitening? set fmri(prewhiten_yn) 1 # Add motion parameters to model # 0 : No # 1 : Yes set fmri(motionevs) 0 # Robust outlier detection in FLAME? set fmri(robust_yn) 0 # Higher-level modelling # 3 : Fixed effects # 0 : Mixed Effects: Simple OLS # 2 : Mixed Effects: FLAME 1 # 1 : Mixed Effects: FLAME 1+2 set fmri(mixed_yn) 3 # Number of EVs set fmri(evs_orig) 1 set fmri(evs_real) 1 set fmri(evs_vox) 0 # Number of contrasts set fmri(ncon_orig) 1 set fmri(ncon_real) 1 # Number of F-tests set fmri(nftests_orig) 0 set fmri(nftests_real) 0 # Add constant column to design matrix? (obsolete) set fmri(constcol) 0 # Carry out post-stats steps? set fmri(poststats_yn) 1 # Pre-threshold masking? set fmri(threshmask) "" # Thresholding # 0 : None # 1 : Uncorrected # 2 : Voxel # 3 : Cluster set fmri(thresh) 3 # P threshold set fmri(prob_thresh) 0.05 # Z threshold set fmri(z_thresh) 2.3 # Z min/max for colour rendering # 0 : Use actual Z min/max # 1 : Use preset Z min/max set fmri(zdisplay) 0 # Z min in colour rendering set fmri(zmin) 2 # Z max in colour rendering set fmri(zmax) 8 # Colour rendering type # 0 : Solid blobs # 1 : Transparent blobs set fmri(rendertype) 1 # Background image for higher-level stats overlays # 1 : Mean highres # 2 : First highres # 3 : Mean functional # 4 : First functional # 5 : Standard space template set fmri(bgimage) 1 # Create time series plots set fmri(tsplot_yn) 1 # Registration? set fmri(reg_yn) 0 # Registration to initial structural set fmri(reginitial_highres_yn) 0 # Search space for registration to initial structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reginitial_highres_search) 90 # Degrees of Freedom for registration to initial structural set fmri(reginitial_highres_dof) 3 # Registration to main structural set fmri(reghighres_yn) 0 # Search space for registration to main structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reghighres_search) 90 # Degrees of Freedom for registration to main structural set fmri(reghighres_dof) 6 # Registration to standard image? set fmri(regstandard_yn) 0 # Standard image set fmri(regstandard) "regimage" # Search space for registration to standard space # 0 : No search # 90 : Normal search # 180 : Full search set fmri(regstandard_search) 90 # Degrees of Freedom for registration to standard space set fmri(regstandard_dof) 12 # Do nonlinear registration from structural to standard space? set fmri(regstandard_nonlinear_yn) 0 # Control nonlinear warp field resolution set fmri(regstandard_nonlinear_warpres) 10 # High pass filter cutoff set fmri(paradigm_hp) 100 # Number of lower-level copes feeding into higher-level analysis set fmri(ncopeinputs) ${num_copes} nipype-0.11.0/nipype/interfaces/script_templates/feat_header.tcl000066400000000000000000000124261257611314500250530ustar00rootroot00000000000000# FEAT version number set fmri(version) 5.98 # Are we in MELODIC? set fmri(inmelodic) 0 # Analysis level # 1 : First-level analysis # 2 : Higher-level analysis set fmri(level) 1 # Which stages to run # 0 : No first-level analysis (registration and/or group stats only) # 7 : Full first-level analysis # 1 : Pre-Stats # 3 : Pre-Stats + Stats # 2 : Stats # 6 : Stats + Post-stats # 4 : Post-stats set fmri(analysis) $analysis_stages # Use relative filenames set fmri(relative_yn) 0 # Balloon help set fmri(help_yn) 1 # Run Featwatcher set fmri(featwatcher_yn) 0 # Cleanup first-level standard-space images set fmri(sscleanup_yn) 0 # Output directory set fmri(outputdir) "scan$scan_num" # TR(s) set fmri(tr) 2.0 # Total volumes set fmri(npts) $num_vols # Delete volumes set fmri(ndelete) 0 # Perfusion tag/control order set fmri(tagfirst) 1 # Number of first-level analyses set fmri(multiple) 1 # Higher-level input type # 1 : Inputs are lower-level FEAT directories # 2 : Inputs are cope images from FEAT directories set fmri(inputtype) 1 # Carry out pre-stats processing? set fmri(filtering_yn) 0 # Brain/background threshold, set fmri(brain_thresh) 10 # Critical z for design efficiency calculation set fmri(critical_z) 5.3 # Noise level set fmri(noise) 0.66 # Noise AR(1) set fmri(noisear) 0.34 # Post-stats-only directory copying # 0 : Overwrite original post-stats results # 1 : Copy original FEAT directory for new Contrasts, Thresholding, Rendering set fmri(newdir_yn) 0 # Motion correction # 0 : None # 1 : MCFLIRT set fmri(mc) 0 # Spin-history (currently obsolete) set fmri(sh_yn) 0 # B0 fieldmap unwarping? set fmri(regunwarp_yn) 0 # EPI dwell time (ms) set fmri(dwell) 0.7 # EPI TE (ms) set fmri(te) 35 # Signal loss threshold set fmri(signallossthresh) 10 # Unwarp direction set fmri(unwarp_dir) y- # Slice timing correction # 0 : None # 1 : Regular up (0, 1, 2, 3, ...) # 2 : Regular down # 3 : Use slice order file # 4 : Use slice timings file # 5 : Interleaved (0, 2, 4 ... 1, 3, 5 ... ) set fmri(st) 0 # Slice timings file set fmri(st_file) "" # BET brain extraction set fmri(bet_yn) 0 # Spatial smoothing FWHM (mm) set fmri(smooth) 5 # Intensity normalization set fmri(norm_yn) 0 # Perfusion subtraction set fmri(perfsub_yn) 0 # Highpass temporal filtering set fmri(temphp_yn) 1 # Lowpass temporal filtering set fmri(templp_yn) 0 # MELODIC ICA data exploration set fmri(melodic_yn) 0 # Carry out main stats? set fmri(stats_yn) 1 # Carry out prewhitening? set fmri(prewhiten_yn) 1 # Add motion parameters to model # 0 : No # 1 : Yes set fmri(motionevs) 0 # Robust outlier detection in FLAME? set fmri(robust_yn) 0 # Higher-level modelling # 3 : Fixed effects # 0 : Mixed Effects: Simple OLS # 2 : Mixed Effects: FLAME 1 # 1 : Mixed Effects: FLAME 1+2 set fmri(mixed_yn) 2 # Number of EVs set fmri(evs_orig) $num_evs set fmri(evs_real) $num_evs set fmri(evs_vox) 0 # Number of contrasts set fmri(ncon_orig) $num_contrasts set fmri(ncon_real) $num_contrasts # Number of F-tests set fmri(nftests_orig) 0 set fmri(nftests_real) 0 # Add constant column to design matrix? (obsolete) set fmri(constcol) 0 # Carry out post-stats steps? set fmri(poststats_yn) $do_contrasts # Pre-threshold masking? set fmri(threshmask) "" # Thresholding # 0 : None # 1 : Uncorrected # 2 : Voxel # 3 : Cluster set fmri(thresh) 3 # P threshold set fmri(prob_thresh) 0.05 # Z threshold set fmri(z_thresh) 2.3 # Z min/max for colour rendering # 0 : Use actual Z min/max # 1 : Use preset Z min/max set fmri(zdisplay) 0 # Z min in colour rendering set fmri(zmin) 2 # Z max in colour rendering set fmri(zmax) 8 # Colour rendering type # 0 : Solid blobs # 1 : Transparent blobs set fmri(rendertype) 1 # Background image for higher-level stats overlays # 1 : Mean highres # 2 : First highres # 3 : Mean functional # 4 : First functional # 5 : Standard space template set fmri(bgimage) 1 # Create time series plots set fmri(tsplot_yn) 1 #Registration? set fmri(reg_yn) 0 # Registration to initial structural set fmri(reginitial_highres_yn) 0 # Search space for registration to initial structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reginitial_highres_search) 90 # Degrees of Freedom for registration to initial structural set fmri(reginitial_highres_dof) 3 # Registration to main structural set fmri(reghighres_yn) 0 # Search space for registration to main structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reghighres_search) 90 # Degrees of Freedom for registration to main structural set fmri(reghighres_dof) 6 # Registration to standard image? set fmri(regstandard_yn) 0 # Standard image set fmri(regstandard) "standard_image" # Search space for registration to standard space # 0 : No search # 90 : Normal search # 180 : Full search set fmri(regstandard_search) 90 # Degrees of Freedom for registration to standard space set fmri(regstandard_dof) 12 # Do nonlinear registration from structural to standard space? set fmri(regstandard_nonlinear_yn) 0 # Control nonlinear warp field resolution set fmri(regstandard_nonlinear_warpres) 10 # High pass filter cutoff set fmri(paradigm_hp) 100 # 4D AVW data or FEAT directory (1) set feat_files(1) "$func_file" # Subject's structural for analysis 1 set highres_files(1) "$struct_file" nipype-0.11.0/nipype/interfaces/script_templates/feat_header_l1.tcl000066400000000000000000000124441257611314500254470ustar00rootroot00000000000000# FEAT version number set fmri(version) 5.98 # Are we in MELODIC? set fmri(inmelodic) 0 # Analysis level # 1 : First-level analysis # 2 : Higher-level analysis set fmri(level) 1 # Which stages to run # 0 : No first-level analysis (registration and/or group stats only) # 7 : Full first-level analysis # 1 : Pre-Stats # 3 : Pre-Stats + Stats # 2 : Stats # 6 : Stats + Post-stats # 4 : Post-stats set fmri(analysis) 6 # Use relative filenames set fmri(relative_yn) 0 # Balloon help set fmri(help_yn) 1 # Run Featwatcher set fmri(featwatcher_yn) 0 # Cleanup first-level standard-space images set fmri(sscleanup_yn) 0 # Output directory set fmri(outputdir) "run$run_num" # TR(s) set fmri(tr) $interscan_interval # Total volumes set fmri(npts) $num_vols # Delete volumes set fmri(ndelete) 0 # Perfusion tag/control order set fmri(tagfirst) 1 # Number of first-level analyses set fmri(multiple) 1 # Higher-level input type # 1 : Inputs are lower-level FEAT directories # 2 : Inputs are cope images from FEAT directories set fmri(inputtype) 1 # Carry out pre-stats processing? set fmri(filtering_yn) 0 # Brain/background threshold, set fmri(brain_thresh) 10 # Critical z for design efficiency calculation set fmri(critical_z) 5.3 # Noise level set fmri(noise) 0.66 # Noise AR(1) set fmri(noisear) 0.34 # Post-stats-only directory copying # 0 : Overwrite original post-stats results # 1 : Copy original FEAT directory for new Contrasts, Thresholding, Rendering set fmri(newdir_yn) 0 # Motion correction # 0 : None # 1 : MCFLIRT set fmri(mc) 0 # Spin-history (currently obsolete) set fmri(sh_yn) 0 # B0 fieldmap unwarping? set fmri(regunwarp_yn) 0 # EPI dwell time (ms) set fmri(dwell) 0.7 # EPI TE (ms) set fmri(te) 35 # Signal loss threshold set fmri(signallossthresh) 10 # Unwarp direction set fmri(unwarp_dir) y- # Slice timing correction # 0 : None # 1 : Regular up (0, 1, 2, 3, ...) # 2 : Regular down # 3 : Use slice order file # 4 : Use slice timings file # 5 : Interleaved (0, 2, 4 ... 1, 3, 5 ... ) set fmri(st) 0 # Slice timings file set fmri(st_file) "" # BET brain extraction set fmri(bet_yn) 0 # Spatial smoothing FWHM (mm) set fmri(smooth) 0 # Intensity normalization set fmri(norm_yn) 0 # Perfusion subtraction set fmri(perfsub_yn) 0 # Highpass temporal filtering set fmri(temphp_yn) $temphp_yn # Lowpass temporal filtering set fmri(templp_yn) 0 # MELODIC ICA data exploration set fmri(melodic_yn) 0 # Carry out main stats? set fmri(stats_yn) 1 # Carry out prewhitening? set fmri(prewhiten_yn) $prewhiten # Add motion parameters to model # 0 : No # 1 : Yes set fmri(motionevs) 0 # Robust outlier detection in FLAME? set fmri(robust_yn) 0 # Higher-level modelling # 3 : Fixed effects # 0 : Mixed Effects: Simple OLS # 2 : Mixed Effects: FLAME 1 # 1 : Mixed Effects: FLAME 1+2 set fmri(mixed_yn) 2 # Number of EVs set fmri(evs_orig) $num_evs set fmri(evs_real) $num_evs_real set fmri(evs_vox) 0 # Number of contrasts set fmri(ncon_orig) $num_tcon set fmri(ncon_real) $num_tcon # Number of F-tests set fmri(nftests_orig) $num_fcon set fmri(nftests_real) $num_fcon # Add constant column to design matrix? (obsolete) set fmri(constcol) 0 # Carry out post-stats steps? set fmri(poststats_yn) 1 # Pre-threshold masking? set fmri(threshmask) "" # Thresholding # 0 : None # 1 : Uncorrected # 2 : Voxel # 3 : Cluster set fmri(thresh) 3 # P threshold set fmri(prob_thresh) 0.05 # Z threshold set fmri(z_thresh) 2.3 # Z min/max for colour rendering # 0 : Use actual Z min/max # 1 : Use preset Z min/max set fmri(zdisplay) 0 # Z min in colour rendering set fmri(zmin) 2 # Z max in colour rendering set fmri(zmax) 8 # Colour rendering type # 0 : Solid blobs # 1 : Transparent blobs set fmri(rendertype) 1 # Background image for higher-level stats overlays # 1 : Mean highres # 2 : First highres # 3 : Mean functional # 4 : First functional # 5 : Standard space template set fmri(bgimage) 1 # Create time series plots set fmri(tsplot_yn) 1 #Registration? set fmri(reg_yn) 0 # Registration to initial structural set fmri(reginitial_highres_yn) 0 # Search space for registration to initial structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reginitial_highres_search) 90 # Degrees of Freedom for registration to initial structural set fmri(reginitial_highres_dof) 3 # Registration to main structural set fmri(reghighres_yn) 0 # Search space for registration to main structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reghighres_search) 90 # Degrees of Freedom for registration to main structural set fmri(reghighres_dof) 6 # Registration to standard image? set fmri(regstandard_yn) 0 # Standard image set fmri(regstandard) "MNI152" # Search space for registration to standard space # 0 : No search # 90 : Normal search # 180 : Full search set fmri(regstandard_search) 90 # Degrees of Freedom for registration to standard space set fmri(regstandard_dof) 0 # Do nonlinear registration from structural to standard space? set fmri(regstandard_nonlinear_yn) 0 # Control nonlinear warp field resolution set fmri(regstandard_nonlinear_warpres) 10 # High pass filter cutoff set fmri(paradigm_hp) $high_pass_filter_cutoff # 4D AVW data or FEAT directory (1) set feat_files(1) "$func_file" # Subject's structural for analysis 1 set highres_files(1) "" nipype-0.11.0/nipype/interfaces/script_templates/feat_nongui.tcl000066400000000000000000000012041257611314500251120ustar00rootroot00000000000000########################################################## # Now options that don't appear in the GUI # Alternative example_func image (not derived from input 4D dataset) set fmri(alternative_example_func) "" # Alternative (to BETting) mask image set fmri(alternative_mask) "" # Initial structural space registration initialisation transform set fmri(init_initial_highres) "" # Structural space registration initialisation transform set fmri(init_highres) "" # Standard space registration initialisation transform set fmri(init_standard) "" # For full FEAT analysis: overwrite existing .feat output dir? set fmri(overwrite_yn) $overwrite nipype-0.11.0/nipype/interfaces/script_templates/featreg_header.tcl000066400000000000000000000122351257611314500255470ustar00rootroot00000000000000# FEAT version number set fmri(version) 5.98 # Are we in MELODIC? set fmri(inmelodic) 0 # Analysis level # 1 : First-level analysis # 2 : Higher-level analysis set fmri(level) 2 # Which stages to run # 0 : No first-level analysis (registration and/or group stats only) # 7 : Full first-level analysis # 1 : Pre-Stats # 3 : Pre-Stats + Stats # 2 : Stats # 6 : Stats + Post-stats # 4 : Post-stats set fmri(analysis) 0 # Use relative filenames set fmri(relative_yn) 0 # Balloon help set fmri(help_yn) 1 # Run Featwatcher set fmri(featwatcher_yn) 1 # Cleanup first-level standard-space images set fmri(sscleanup_yn) 0 # Output directory set fmri(outputdir) "" # TR(s) set fmri(tr) 3 # Total volumes set fmri(npts) 2 # Delete volumes set fmri(ndelete) 0 # Perfusion tag/control order set fmri(tagfirst) 1 # Number of first-level analyses set fmri(multiple) ${num_runs} # Higher-level input type # 1 : Inputs are lower-level FEAT directories # 2 : Inputs are cope images from FEAT directories set fmri(inputtype) 1 # Carry out pre-stats processing? set fmri(filtering_yn) 0 # Brain/background threshold, % set fmri(brain_thresh) 10 # Critical z for design efficiency calculation set fmri(critical_z) 5.3 # Noise level set fmri(noise) 0.66 # Noise AR(1) set fmri(noisear) 0.34 # Post-stats-only directory copying # 0 : Overwrite original post-stats results # 1 : Copy original FEAT directory for new Contrasts, Thresholding, Rendering set fmri(newdir_yn) 0 # Motion correction # 0 : None # 1 : MCFLIRT set fmri(mc) 1 # Spin-history (currently obsolete) set fmri(sh_yn) 0 # B0 fieldmap unwarping? set fmri(regunwarp_yn) 0 # EPI dwell time (ms) set fmri(dwell) 0.7 # EPI TE (ms) set fmri(te) 35 # % Signal loss threshold set fmri(signallossthresh) 10 # Unwarp direction set fmri(unwarp_dir) y- # Slice timing correction # 0 : None # 1 : Regular up (0, 1, 2, 3, ...) # 2 : Regular down # 3 : Use slice order file # 4 : Use slice timings file # 5 : Interleaved (0, 2, 4 ... 1, 3, 5 ... ) set fmri(st) 0 # Slice timings file set fmri(st_file) "" # BET brain extraction set fmri(bet_yn) 1 # Spatial smoothing FWHM (mm) set fmri(smooth) 5 # Intensity normalization set fmri(norm_yn) 0 # Perfusion subtraction set fmri(perfsub_yn) 0 # Highpass temporal filtering set fmri(temphp_yn) 1 # Lowpass temporal filtering set fmri(templp_yn) 0 # MELODIC ICA data exploration set fmri(melodic_yn) 0 # Carry out main stats? set fmri(stats_yn) 1 # Carry out prewhitening? set fmri(prewhiten_yn) 1 # Add motion parameters to model # 0 : No # 1 : Yes set fmri(motionevs) 0 # Robust outlier detection in FLAME? set fmri(robust_yn) 0 # Higher-level modelling # 3 : Fixed effects # 0 : Mixed Effects: Simple OLS # 2 : Mixed Effects: FLAME 1 # 1 : Mixed Effects: FLAME 1+2 set fmri(mixed_yn) 3 # Number of EVs set fmri(evs_orig) 0 set fmri(evs_real) 0 set fmri(evs_vox) 0 # Number of contrasts set fmri(ncon_orig) 0 set fmri(ncon_real) 0 # Number of F-tests set fmri(nftests_orig) 0 set fmri(nftests_real) 0 # Add constant column to design matrix? (obsolete) set fmri(constcol) 0 # Carry out post-stats steps? set fmri(poststats_yn) 1 # Pre-threshold masking? set fmri(threshmask) "" # Thresholding # 0 : None # 1 : Uncorrected # 2 : Voxel # 3 : Cluster set fmri(thresh) 3 # P threshold set fmri(prob_thresh) 0.05 # Z threshold set fmri(z_thresh) 2.3 # Z min/max for colour rendering # 0 : Use actual Z min/max # 1 : Use preset Z min/max set fmri(zdisplay) 0 # Z min in colour rendering set fmri(zmin) 2 # Z max in colour rendering set fmri(zmax) 8 # Colour rendering type # 0 : Solid blobs # 1 : Transparent blobs set fmri(rendertype) 1 # Background image for higher-level stats overlays # 1 : Mean highres # 2 : First highres # 3 : Mean functional # 4 : First functional # 5 : Standard space template set fmri(bgimage) 1 # Create time series plots set fmri(tsplot_yn) 1 # Registration? set fmri(reg_yn) 0 # Registration to initial structural set fmri(reginitial_highres_yn) 0 # Search space for registration to initial structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reginitial_highres_search) 90 # Degrees of Freedom for registration to initial structural set fmri(reginitial_highres_dof) 3 # Registration to main structural set fmri(reghighres_yn) 0 # Search space for registration to main structural # 0 : No search # 90 : Normal search # 180 : Full search set fmri(reghighres_search) 90 # Degrees of Freedom for registration to main structural set fmri(reghighres_dof) 6 # Registration to standard image? set fmri(regstandard_yn) 1 # Standard image set fmri(regstandard) "$regimage" # Search space for registration to standard space # 0 : No search # 90 : Normal search # 180 : Full search set fmri(regstandard_search) 90 # Degrees of Freedom for registration to standard space set fmri(regstandard_dof) $regdof # Do nonlinear registration from structural to standard space? set fmri(regstandard_nonlinear_yn) 0 # Control nonlinear warp field resolution set fmri(regstandard_nonlinear_warpres) 10 # High pass filter cutoff set fmri(paradigm_hp) 100 # Number of lower-level copes feeding into higher-level analysis set fmri(ncopeinputs) ${num_runs} nipype-0.11.0/nipype/interfaces/semtools/000077500000000000000000000000001257611314500203765ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/__init__.py000066400000000000000000000004631257611314500225120ustar00rootroot00000000000000from diffusion import * from featurecreator import GenerateCsfClippedFromClassifiedImage from segmentation import * from filtering import * from brains import * from testing import * from utilities import * from legacy import * from registration import * from converters import DWISimpleCompare, DWICompare nipype-0.11.0/nipype/interfaces/semtools/brains/000077500000000000000000000000001257611314500216545ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/brains/__init__.py000066400000000000000000000002631257611314500237660ustar00rootroot00000000000000from segmentation import SimilarityIndex, BRAINSTalairach, BRAINSTalairachMask from utilities import HistogramMatchingFilter from classify import BRAINSPosteriorToContinuousClass nipype-0.11.0/nipype/interfaces/semtools/brains/classify.py000066400000000000000000000044021257611314500240430ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSPosteriorToContinuousClassInputSpec(CommandLineInputSpec): inputWhiteVolume = File(desc="White Matter Posterior Volume", exists=True, argstr="--inputWhiteVolume %s") inputBasalGmVolume = File(desc="Basal Grey Matter Posterior Volume", exists=True, argstr="--inputBasalGmVolume %s") inputSurfaceGmVolume = File(desc="Surface Grey Matter Posterior Volume", exists=True, argstr="--inputSurfaceGmVolume %s") inputCsfVolume = File(desc="CSF Posterior Volume", exists=True, argstr="--inputCsfVolume %s") inputVbVolume = File(desc="Venous Blood Posterior Volume", exists=True, argstr="--inputVbVolume %s") inputCrblGmVolume = File(desc="Cerebellum Grey Matter Posterior Volume", exists=True, argstr="--inputCrblGmVolume %s") inputCrblWmVolume = File(desc="Cerebellum White Matter Posterior Volume", exists=True, argstr="--inputCrblWmVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Continuous Tissue Classified Image", argstr="--outputVolume %s") class BRAINSPosteriorToContinuousClassOutputSpec(TraitedSpec): outputVolume = File(desc="Output Continuous Tissue Classified Image", exists=True) class BRAINSPosteriorToContinuousClass(SEMLikeCommandLine): """title: Tissue Classification category: BRAINS.Classify description: This program will generate an 8-bit continuous tissue classified image based on BRAINSABC posterior images. version: 3.0 documentation-url: http://www.nitrc.org/plugins/mwiki/index.php/brains:BRAINSClassify license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Vincent A. Magnotta acknowledgements: Funding for this work was provided by NIH/NINDS award NS050568 """ input_spec = BRAINSPosteriorToContinuousClassInputSpec output_spec = BRAINSPosteriorToContinuousClassOutputSpec _cmd = " BRAINSPosteriorToContinuousClass " _outputs_filenames = {'outputVolume': 'outputVolume'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/brains/segmentation.py000066400000000000000000000136641257611314500247350ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class SimilarityIndexInputSpec(CommandLineInputSpec): outputCSVFilename = File(desc="output CSV Filename", exists=True, argstr="--outputCSVFilename %s") ANNContinuousVolume = File(desc="ANN Continuous volume to be compared to the manual volume", exists=True, argstr="--ANNContinuousVolume %s") inputManualVolume = File(desc="input manual(reference) volume", exists=True, argstr="--inputManualVolume %s") thresholdInterval = traits.Float(desc="Threshold interval to compute similarity index between zero and one", argstr="--thresholdInterval %f") class SimilarityIndexOutputSpec(TraitedSpec): pass class SimilarityIndex(SEMLikeCommandLine): """title: BRAINSCut:SimilarityIndexComputation category: BRAINS.Segmentation description: Automatic analysis of BRAINSCut Output version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Eunyoung Regin Kim """ input_spec = SimilarityIndexInputSpec output_spec = SimilarityIndexOutputSpec _cmd = " SimilarityIndex " _outputs_filenames = {} _redirect_x = False class BRAINSTalairachInputSpec(CommandLineInputSpec): AC = InputMultiPath(traits.Float, desc="Location of AC Point ", sep=",", argstr="--AC %s") ACisIndex = traits.Bool(desc="AC Point is Index", argstr="--ACisIndex ") PC = InputMultiPath(traits.Float, desc="Location of PC Point ", sep=",", argstr="--PC %s") PCisIndex = traits.Bool(desc="PC Point is Index", argstr="--PCisIndex ") SLA = InputMultiPath(traits.Float, desc="Location of SLA Point ", sep=",", argstr="--SLA %s") SLAisIndex = traits.Bool(desc="SLA Point is Index", argstr="--SLAisIndex ") IRP = InputMultiPath(traits.Float, desc="Location of IRP Point ", sep=",", argstr="--IRP %s") IRPisIndex = traits.Bool(desc="IRP Point is Index", argstr="--IRPisIndex ") inputVolume = File(desc="Input image used to define physical space of images", exists=True, argstr="--inputVolume %s") outputBox = traits.Either(traits.Bool, File(), hash_files=False, desc="Name of the resulting Talairach Bounding Box file", argstr="--outputBox %s") outputGrid = traits.Either(traits.Bool, File(), hash_files=False, desc="Name of the resulting Talairach Grid file", argstr="--outputGrid %s") class BRAINSTalairachOutputSpec(TraitedSpec): outputBox = File(desc="Name of the resulting Talairach Bounding Box file", exists=True) outputGrid = File(desc="Name of the resulting Talairach Grid file", exists=True) class BRAINSTalairach(SEMLikeCommandLine): """title: BRAINS Talairach category: BRAINS.Segmentation description: This program creates a VTK structured grid defining the Talairach coordinate system based on four points: AC, PC, IRP, and SLA. The resulting structred grid can be written as either a classic VTK file or the new VTK XML file format. Two representations of the resulting grid can be written. The first is a bounding box representation that also contains the location of the AC and PC points. The second representation is the full Talairach grid representation that includes the additional rows of boxes added to the inferior allowing full coverage of the cerebellum. version: 0.1 documentation-url: http://www.nitrc.org/plugins/mwiki/index.php/brains:BRAINSTalairach license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Steven Dunn and Vincent Magnotta acknowledgements: Funding for this work was provided by NIH/NINDS award NS050568 """ input_spec = BRAINSTalairachInputSpec output_spec = BRAINSTalairachOutputSpec _cmd = " BRAINSTalairach " _outputs_filenames = {'outputGrid': 'outputGrid', 'outputBox': 'outputBox'} _redirect_x = False class BRAINSTalairachMaskInputSpec(CommandLineInputSpec): inputVolume = File(desc="Input image used to define physical space of resulting mask", exists=True, argstr="--inputVolume %s") talairachParameters = File(desc="Name of the Talairach parameter file.", exists=True, argstr="--talairachParameters %s") talairachBox = File(desc="Name of the Talairach box file.", exists=True, argstr="--talairachBox %s") hemisphereMode = traits.Enum("left", "right", "both", desc="Mode for box creation: left, right, both", argstr="--hemisphereMode %s") expand = traits.Bool(desc="Expand exterior box to include surface CSF", argstr="--expand ") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output filename for the resulting binary image", argstr="--outputVolume %s") class BRAINSTalairachMaskOutputSpec(TraitedSpec): outputVolume = File(desc="Output filename for the resulting binary image", exists=True) class BRAINSTalairachMask(SEMLikeCommandLine): """title: Talairach Mask category: BRAINS.Segmentation description: This program creates a binary image representing the specified Talairach region. The input is an example image to define the physical space for the resulting image, the Talairach grid representation in VTK format, and the file containing the Talairach box definitions to be generated. These can be combined in BRAINS to create a label map using the procedure Brains::WorkupUtils::CreateLabelMapFromBinaryImages. version: 0.1 documentation-url: http://www.nitrc.org/plugins/mwiki/index.php/brains:BRAINSTalairachMask license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Steven Dunn and Vincent Magnotta acknowledgements: Funding for this work was provided by NIH/NINDS award NS050568 """ input_spec = BRAINSTalairachMaskInputSpec output_spec = BRAINSTalairachMaskOutputSpec _cmd = " BRAINSTalairachMask " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/brains/tests/000077500000000000000000000000001257611314500230165ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/brains/tests/test_auto_BRAINSPosteriorToContinuousClass.py000066400000000000000000000030421257611314500337230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.brains.classify import BRAINSPosteriorToContinuousClass def test_BRAINSPosteriorToContinuousClass_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBasalGmVolume=dict(argstr='--inputBasalGmVolume %s', ), inputCrblGmVolume=dict(argstr='--inputCrblGmVolume %s', ), inputCrblWmVolume=dict(argstr='--inputCrblWmVolume %s', ), inputCsfVolume=dict(argstr='--inputCsfVolume %s', ), inputSurfaceGmVolume=dict(argstr='--inputSurfaceGmVolume %s', ), inputVbVolume=dict(argstr='--inputVbVolume %s', ), inputWhiteVolume=dict(argstr='--inputWhiteVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSPosteriorToContinuousClass.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSPosteriorToContinuousClass_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSPosteriorToContinuousClass.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/brains/tests/test_auto_BRAINSTalairach.py000066400000000000000000000030501257611314500302440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.brains.segmentation import BRAINSTalairach def test_BRAINSTalairach_inputs(): input_map = dict(AC=dict(argstr='--AC %s', sep=',', ), ACisIndex=dict(argstr='--ACisIndex ', ), IRP=dict(argstr='--IRP %s', sep=',', ), IRPisIndex=dict(argstr='--IRPisIndex ', ), PC=dict(argstr='--PC %s', sep=',', ), PCisIndex=dict(argstr='--PCisIndex ', ), SLA=dict(argstr='--SLA %s', sep=',', ), SLAisIndex=dict(argstr='--SLAisIndex ', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), outputBox=dict(argstr='--outputBox %s', hash_files=False, ), outputGrid=dict(argstr='--outputGrid %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSTalairach.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSTalairach_outputs(): output_map = dict(outputBox=dict(), outputGrid=dict(), ) outputs = BRAINSTalairach.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/brains/tests/test_auto_BRAINSTalairachMask.py000066400000000000000000000024671257611314500310730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.brains.segmentation import BRAINSTalairachMask def test_BRAINSTalairachMask_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), expand=dict(argstr='--expand ', ), hemisphereMode=dict(argstr='--hemisphereMode %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), talairachBox=dict(argstr='--talairachBox %s', ), talairachParameters=dict(argstr='--talairachParameters %s', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSTalairachMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSTalairachMask_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSTalairachMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/brains/tests/test_auto_HistogramMatchingFilter.py000066400000000000000000000031561257611314500322420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.brains.utilities import HistogramMatchingFilter def test_HistogramMatchingFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), histogramAlgorithm=dict(argstr='--histogramAlgorithm %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryVolume=dict(argstr='--inputBinaryVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), referenceBinaryVolume=dict(argstr='--referenceBinaryVolume %s', ), referenceVolume=dict(argstr='--referenceVolume %s', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), writeHistogram=dict(argstr='--writeHistogram %s', ), ) inputs = HistogramMatchingFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_HistogramMatchingFilter_outputs(): output_map = dict(outputVolume=dict(), ) outputs = HistogramMatchingFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/brains/tests/test_auto_SimilarityIndex.py000066400000000000000000000022541257611314500306000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.brains.segmentation import SimilarityIndex def test_SimilarityIndex_inputs(): input_map = dict(ANNContinuousVolume=dict(argstr='--ANNContinuousVolume %s', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputManualVolume=dict(argstr='--inputManualVolume %s', ), outputCSVFilename=dict(argstr='--outputCSVFilename %s', ), terminal_output=dict(nohash=True, ), thresholdInterval=dict(argstr='--thresholdInterval %f', ), ) inputs = SimilarityIndex.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SimilarityIndex_outputs(): output_map = dict() outputs = SimilarityIndex.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/brains/utilities.py000066400000000000000000000042141257611314500242420ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class HistogramMatchingFilterInputSpec(CommandLineInputSpec): inputVolume = File(desc="The Input image to be computed for statistics", exists=True, argstr="--inputVolume %s") referenceVolume = File(desc="The Input image to be computed for statistics", exists=True, argstr="--referenceVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Image File Name", argstr="--outputVolume %s") referenceBinaryVolume = File(desc="referenceBinaryVolume", exists=True, argstr="--referenceBinaryVolume %s") inputBinaryVolume = File(desc="inputBinaryVolume", exists=True, argstr="--inputBinaryVolume %s") numberOfMatchPoints = traits.Int(desc=" number of histogram matching points", argstr="--numberOfMatchPoints %d") numberOfHistogramBins = traits.Int(desc=" number of histogram bin", argstr="--numberOfHistogramBins %d") writeHistogram = traits.Str(desc=" decide if histogram data would be written with prefixe of the file name", argstr="--writeHistogram %s") histogramAlgorithm = traits.Enum("OtsuHistogramMatching", desc=" histogram algrithm selection", argstr="--histogramAlgorithm %s") verbose = traits.Bool(desc=" verbose mode running for debbuging", argstr="--verbose ") class HistogramMatchingFilterOutputSpec(TraitedSpec): outputVolume = File(desc="Output Image File Name", exists=True) class HistogramMatchingFilter(SEMLikeCommandLine): """title: Write Out Image Intensities category: BRAINS.Utilities description: For Analysis version: 0.1 contributor: University of Iowa Department of Psychiatry, http:://www.psychiatry.uiowa.edu """ input_spec = HistogramMatchingFilterInputSpec output_spec = HistogramMatchingFilterOutputSpec _cmd = " HistogramMatchingFilter " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/converters.py000066400000000000000000000062341257611314500231470ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class DWISimpleCompareInputSpec(CommandLineInputSpec): inputVolume1 = File(desc="First input volume (.nhdr or .nrrd)", exists=True, argstr="--inputVolume1 %s") inputVolume2 = File(desc="Second input volume (.nhdr or .nrrd)", exists=True, argstr="--inputVolume2 %s") checkDWIData = traits.Bool(desc="check for existence of DWI data, and if present, compare it", argstr="--checkDWIData ") class DWISimpleCompareOutputSpec(TraitedSpec): pass class DWISimpleCompare(SEMLikeCommandLine): """title: Nrrd DWI comparison category: Converters description: Compares two nrrd format DWI images and verifies that gradient magnitudes, gradient directions, measurement frame, and max B0 value are identicle. Used for testing DWIConvert. version: 0.1.0.$Revision: 916 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DWIConvert license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Mark Scully (UIowa) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Additional support for DTI data produced on Philips scanners was contributed by Vincent Magnotta and Hans Johnson at the University of Iowa. """ input_spec = DWISimpleCompareInputSpec output_spec = DWISimpleCompareOutputSpec _cmd = " DWISimpleCompare " _outputs_filenames = {} _redirect_x = False class DWICompareInputSpec(CommandLineInputSpec): inputVolume1 = File(desc="First input volume (.nhdr or .nrrd)", exists=True, argstr="--inputVolume1 %s") inputVolume2 = File(desc="Second input volume (.nhdr or .nrrd)", exists=True, argstr="--inputVolume2 %s") class DWICompareOutputSpec(TraitedSpec): pass class DWICompare(SEMLikeCommandLine): """title: Nrrd DWI comparison category: Converters description: Compares two nrrd format DWI images and verifies that gradient magnitudes, gradient directions, measurement frame, and max B0 value are identicle. Used for testing DWIConvert. version: 0.1.0.$Revision: 916 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DWIConvert license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Mark Scully (UIowa) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Additional support for DTI data produced on Philips scanners was contributed by Vincent Magnotta and Hans Johnson at the University of Iowa. """ input_spec = DWICompareInputSpec output_spec = DWICompareOutputSpec _cmd = " DWICompare " _outputs_filenames = {} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/000077500000000000000000000000001257611314500223645ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/diffusion/__init__.py000066400000000000000000000013231257611314500244740ustar00rootroot00000000000000from diffusion import dtiaverage, dtiestim, dtiprocess, DWIConvert from tractography import * from gtract import gtractTransformToDisplacementField, gtractInvertBSplineTransform, gtractConcatDwi, gtractAverageBvalues, gtractCoregBvalues, gtractResampleAnisotropy, gtractResampleCodeImage, gtractCopyImageOrientation, gtractCreateGuideFiber, gtractAnisotropyMap, gtractClipAnisotropy, gtractResampleB0, gtractInvertRigidTransform, gtractImageConformity, compareTractInclusion, gtractFastMarchingTracking, gtractInvertDisplacementField, gtractCoRegAnatomy, gtractResampleDWIInPlace, gtractCostFastMarching, gtractFiberTracking, extractNrrdVectorIndex, gtractResampleFibers, gtractTensor from maxcurvature import maxcurvature nipype-0.11.0/nipype/interfaces/semtools/diffusion/diffusion.py000066400000000000000000000625071257611314500247360ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class dtiaverageInputSpec(CommandLineInputSpec): inputs = InputMultiPath(File(exists=True), desc="List of all the tensor fields to be averaged", argstr="--inputs %s...") tensor_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Averaged tensor volume", argstr="--tensor_output %s") DTI_double = traits.Bool(desc="Tensor components are saved as doubles (cannot be visualized in Slicer)", argstr="--DTI_double ") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") class dtiaverageOutputSpec(TraitedSpec): tensor_output = File(desc="Averaged tensor volume", exists=True) class dtiaverage(SEMLikeCommandLine): """title: DTIAverage (DTIProcess) category: Diffusion.Diffusion Tensor Images.CommandLineOnly description: dtiaverage is a program that allows to compute the average of an arbitrary number of tensor fields (listed after the --inputs option) This program is used in our pipeline as the last step of the atlas building processing. When all the tensor fields have been deformed in the same space, to create the average tensor field (--tensor_output) we use dtiaverage. Several average method can be used (specified by the --method option): euclidian, log-euclidian and pga. The default being euclidian. version: 1.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett """ input_spec = dtiaverageInputSpec output_spec = dtiaverageOutputSpec _cmd = " dtiaverage " _outputs_filenames = {'tensor_output': 'tensor_output.nii'} _redirect_x = False class dtiestimInputSpec(CommandLineInputSpec): dwi_image = File(desc="DWI image volume (required)", exists=True, argstr="--dwi_image %s") tensor_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Tensor OutputImage", argstr="--tensor_output %s") B0 = traits.Either(traits.Bool, File(), hash_files=False, desc="Baseline image, average of all baseline images", argstr="--B0 %s") idwi = traits.Either(traits.Bool, File(), hash_files=False, desc="idwi output image. Image with isotropic diffusion-weighted information = geometric mean of diffusion images", argstr="--idwi %s") B0_mask_output = traits.Either(traits.Bool, File(), hash_files=False, desc="B0 mask used for the estimation. B0 thresholded either with the -t option value or the automatic OTSU value", argstr="--B0_mask_output %s") brain_mask = File(desc="Brain mask. Image where for every voxel == 0 the tensors are not estimated. Be aware that in addition a threshold based masking will be performed by default. If such an additional threshold masking is NOT desired, then use option -t 0.", exists=True, argstr="--brain_mask %s") bad_region_mask = File(desc="Bad region mask. Image where for every voxel > 0 the tensors are not estimated", exists=True, argstr="--bad_region_mask %s") method = traits.Enum("lls", "wls", "nls", "ml", desc="Esitmation method (lls:linear least squares, wls:weighted least squares, nls:non-linear least squares, ml:maximum likelihood)", argstr="--method %s") correction = traits.Enum("none", "zero", "abs", "nearest", desc="Correct the tensors if computed tensor is not semi-definite positive", argstr="--correction %s") threshold = traits.Int(desc="Baseline threshold for estimation. If not specified calculated using an OTSU threshold on the baseline image.", argstr="--threshold %d") weight_iterations = traits.Int(desc="Number of iterations to recaluate weightings from tensor estimate", argstr="--weight_iterations %d") step = traits.Float(desc="Gradient descent step size (for nls and ml methods)", argstr="--step %f") sigma = traits.Float(argstr="--sigma %f") DTI_double = traits.Bool(desc="Tensor components are saved as doubles (cannot be visualized in Slicer)", argstr="--DTI_double ") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") defaultTensor = InputMultiPath(traits.Float, desc="Default tensor used if estimated tensor is below a given threshold", sep=",", argstr="--defaultTensor %s") shiftNeg = traits.Bool( desc="Shift eigenvalues so all are positive (accounts for bad tensors related to noise or acquisition error). This is the same option as the one available in DWIToDTIEstimation in Slicer (but instead of just adding the minimum eigenvalue to all the eigenvalues if it is smaller than 0, we use a coefficient to have stictly positive eigenvalues", argstr="--shiftNeg ") shiftNegCoeff = traits.Float( desc="Shift eigenvalues so all are positive (accounts for bad tensors related to noise or acquisition error). Instead of just adding the minimum eigenvalue to all the eigenvalues if it is smaller than 0, we use a coefficient to have stictly positive eigenvalues. Coefficient must be between 1.0 and 1.001 (included).", argstr="--shiftNegCoeff %f") class dtiestimOutputSpec(TraitedSpec): tensor_output = File(desc="Tensor OutputImage", exists=True) B0 = File(desc="Baseline image, average of all baseline images", exists=True) idwi = File(desc="idwi output image. Image with isotropic diffusion-weighted information = geometric mean of diffusion images", exists=True) B0_mask_output = File(desc="B0 mask used for the estimation. B0 thresholded either with the -t option value or the automatic OTSU value", exists=True) class dtiestim(SEMLikeCommandLine): """title: DTIEstim (DTIProcess) category: Diffusion.Diffusion Weighted Images description: dtiestim is a tool that takes in a set of DWIs (with --dwi_image option) in nrrd format and estimates a tensor field out of it. The output tensor file name is specified with the --tensor_output option There are several methods to estimate the tensors which you can specify with the option --method lls|wls|nls|ml . Here is a short description of the different methods: lls Linear least squares. Standard estimation technique that recovers the tensor parameters by multiplying the log of the normalized signal intensities by the pseudo-inverse of the gradient matrix. Default option. wls Weighted least squares. This method is similar to the linear least squares method except that the gradient matrix is weighted by the original lls estimate. (See Salvador, R., Pena, A., Menon, D. K., Carpenter, T. A., Pickard, J. D., and Bullmore, E. T. Formal characterization and extension of the linearized diffusion tensor model. Human Brain Mapping 24, 2 (Feb. 2005), 144-155. for more information on this method). This method is recommended for most applications. The weight for each iteration can be specified with the --weight_iterations. It is not currently the default due to occasional matrix singularities. nls Non-linear least squares. This method does not take the log of the signal and requires an optimization based on levenberg-marquadt to optimize the parameters of the signal. The lls estimate is used as an initialization. For this method the step size can be specified with the --step option. ml Maximum likelihood estimation. This method is experimental and is not currently recommended. For this ml method the sigma can be specified with the option --sigma and the step size can be specified with the --step option. You can set a threshold (--threshold) to have the tensor estimated to only a subset of voxels. All the baseline voxel value higher than the threshold define the voxels where the tensors are computed. If not specified the threshold is calculated using an OTSU threshold on the baseline image.The masked generated by the -t option or by the otsu value can be saved with the --B0_mask_output option. dtiestim also can extract a few scalar images out of the DWI set of images: - the average baseline image (--B0) which is the average of all the B0s. - the IDWI (--idwi)which is the geometric mean of the diffusion images. You can also load a mask if you want to compute the tensors only where the voxels are non-zero (--brain_mask) or a negative mask and the tensors will be estimated where the negative mask has zero values (--bad_region_mask) version: 1.2.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett, Francois Budin acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); (1=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering) provided conversions to make DTIProcess compatible with Slicer execution, and simplified the stand-alone build requirements by removing the dependancies on boost and a fortran compiler. """ input_spec = dtiestimInputSpec output_spec = dtiestimOutputSpec _cmd = " dtiestim " _outputs_filenames = {'B0': 'B0.nii', 'idwi': 'idwi.nii', 'tensor_output': 'tensor_output.nii', 'B0_mask_output': 'B0_mask_output.nii'} _redirect_x = False class dtiprocessInputSpec(CommandLineInputSpec): dti_image = File(desc="DTI tensor volume", exists=True, argstr="--dti_image %s") fa_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Fractional Anisotropy output file", argstr="--fa_output %s") md_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Mean Diffusivity output file", argstr="--md_output %s") sigma = traits.Float(desc="Scale of gradients", argstr="--sigma %f") fa_gradient_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Fractional Anisotropy Gradient output file", argstr="--fa_gradient_output %s") fa_gradmag_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Fractional Anisotropy Gradient Magnitude output file", argstr="--fa_gradmag_output %s") color_fa_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Color Fractional Anisotropy output file", argstr="--color_fa_output %s") principal_eigenvector_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Principal Eigenvectors Output", argstr="--principal_eigenvector_output %s") negative_eigenvector_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Negative Eigenvectors Output: create a binary image where if any of the eigen value is below zero, the voxel is set to 1, otherwise 0.", argstr="--negative_eigenvector_output %s") frobenius_norm_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Frobenius Norm Output", argstr="--frobenius_norm_output %s") lambda1_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Axial Diffusivity - Lambda 1 (largest eigenvalue) output", argstr="--lambda1_output %s") lambda2_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Lambda 2 (middle eigenvalue) output", argstr="--lambda2_output %s") lambda3_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Lambda 3 (smallest eigenvalue) output", argstr="--lambda3_output %s") RD_output = traits.Either(traits.Bool, File(), hash_files=False, desc="RD (Radial Diffusivity 1/2*(lambda2+lambda3)) output", argstr="--RD_output %s") rot_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Rotated tensor output file. Must also specify the dof file.", argstr="--rot_output %s") affineitk_file = File(desc="Transformation file for affine transformation. ITK format.", exists=True, argstr="--affineitk_file %s") dof_file = File(desc="Transformation file for affine transformation. This can be ITK format (or the outdated RView).", exists=True, argstr="--dof_file %s") newdof_file = File(desc="Transformation file for affine transformation. RView NEW format. (txt file output of dof2mat)", exists=True, argstr="--newdof_file %s") mask = File(desc="Mask tensors. Specify --outmask if you want to save the masked tensor field, otherwise the mask is applied just for the current processing ", exists=True, argstr="--mask %s") outmask = traits.Either(traits.Bool, File(), hash_files=False, desc="Name of the masked tensor field.", argstr="--outmask %s") hField = traits.Bool(desc="forward and inverse transformations are h-fields instead of displacement fields", argstr="--hField ") forward = File(desc="Forward transformation. Assumed to be a deformation field in world coordinates, unless the --h-field option is specified.", exists=True, argstr="--forward %s") deformation_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Warped tensor field based on a deformation field. This option requires the --forward,-F transformation to be specified.", argstr="--deformation_output %s") interpolation = traits.Enum("nearestneighbor", "linear", "cubic", desc="Interpolation type (nearestneighbor, linear, cubic)", argstr="--interpolation %s") reorientation = traits.Enum("fs", "ppd", desc="Reorientation type (fs, ppd)", argstr="--reorientation %s") correction = traits.Enum("none", "zero", "abs", "nearest", desc="Correct the tensors if computed tensor is not semi-definite positive", argstr="--correction %s") scalar_float = traits.Bool(desc="Write scalar [FA,MD] as unscaled float (with their actual values, otherwise scaled by 10 000). Also causes FA to be unscaled [0..1].", argstr="--scalar_float ") DTI_double = traits.Bool(desc="Tensor components are saved as doubles (cannot be visualized in Slicer)", argstr="--DTI_double ") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") class dtiprocessOutputSpec(TraitedSpec): fa_output = File(desc="Fractional Anisotropy output file", exists=True) md_output = File(desc="Mean Diffusivity output file", exists=True) fa_gradient_output = File(desc="Fractional Anisotropy Gradient output file", exists=True) fa_gradmag_output = File(desc="Fractional Anisotropy Gradient Magnitude output file", exists=True) color_fa_output = File(desc="Color Fractional Anisotropy output file", exists=True) principal_eigenvector_output = File(desc="Principal Eigenvectors Output", exists=True) negative_eigenvector_output = File(desc="Negative Eigenvectors Output: create a binary image where if any of the eigen value is below zero, the voxel is set to 1, otherwise 0.", exists=True) frobenius_norm_output = File(desc="Frobenius Norm Output", exists=True) lambda1_output = File(desc="Axial Diffusivity - Lambda 1 (largest eigenvalue) output", exists=True) lambda2_output = File(desc="Lambda 2 (middle eigenvalue) output", exists=True) lambda3_output = File(desc="Lambda 3 (smallest eigenvalue) output", exists=True) RD_output = File(desc="RD (Radial Diffusivity 1/2*(lambda2+lambda3)) output", exists=True) rot_output = File(desc="Rotated tensor output file. Must also specify the dof file.", exists=True) outmask = File(desc="Name of the masked tensor field.", exists=True) deformation_output = File(desc="Warped tensor field based on a deformation field. This option requires the --forward,-F transformation to be specified.", exists=True) class dtiprocess(SEMLikeCommandLine): """title: DTIProcess (DTIProcess) category: Diffusion.Diffusion Tensor Images description: dtiprocess is a tool that handles tensor fields. It takes as an input a tensor field in nrrd format. It can generate diffusion scalar properties out of the tensor field such as : FA (--fa_output), Gradient FA image (--fa_gradient_output), color FA (--color_fa_output), MD (--md_output), Frobenius norm (--frobenius_norm_output), lbd1, lbd2, lbd3 (--lambda{1,2,3}_output), binary map of voxel where if any of the eigenvalue is negative, the voxel is set to 1 (--negative_eigenvector_output) It also creates 4D images out of the tensor field such as: Highest eigenvector map (highest eigenvector at each voxel) (--principal_eigenvector_output) Masking capabilities: For any of the processing done with dtiprocess, it's possible to apply it on a masked region of the tensor field. You need to use the --mask option for any of the option to be applied on that tensor field sub-region only. If you want to save the masked tensor field use the option --outmask and specify the new masked tensor field file name. dtiprocess also allows a range of transformations on the tensor fields. The transformed tensor field file name is specified with the option --deformation_output. There are 3 resampling interpolation methods specified with the tag --interpolation followed by the type to use (nearestneighbor, linear, cubic) Then you have several transformations possible to apply: - Affine transformations using as an input - itk affine transformation file (based on the itkAffineTransform class) - Affine transformations using rview (details and download at http://www.doc.ic.ac.uk/~dr/software/). There are 2 versions of rview both creating transformation files called dof files. The old version of rview outputs text files containing the transformation parameters. It can be read in with the --dof_file option. The new version outputs binary dof files. These dof files can be transformed into human readable file with the dof2mat tool which is part of the rview package. So you need to save the output of dof2mat into a text file which can then be used with the -- newdof_file option. Usage example: dof2mat mynewdoffile.dof >> mynewdoffile.txt dtiprocess --dti_image mytensorfield.nhdr --newdof_file mynewdoffile.txt --rot_output myaffinetensorfield.nhdr Non linear transformations as an input: The default transformation file type is d-field (displacement field) in nrrd format. The option to use is --forward with the name of the file. If the transformation file is a h-field you have to add the option --hField. version: 1.0.1 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett """ input_spec = dtiprocessInputSpec output_spec = dtiprocessOutputSpec _cmd = " dtiprocess " _outputs_filenames = {'fa_gradmag_output': 'fa_gradmag_output.nii', 'fa_gradient_output': 'fa_gradient_output.nii', 'lambda1_output': 'lambda1_output.nii', 'lambda2_output': 'lambda2_output.nii', 'color_fa_output': 'color_fa_output.nii', 'fa_output': 'fa_output.nii', 'frobenius_norm_output': 'frobenius_norm_output.nii', 'principal_eigenvector_output': 'principal_eigenvector_output.nii', 'outmask': 'outmask.nii', 'lambda3_output': 'lambda3_output.nii', 'negative_eigenvector_output': 'negative_eigenvector_output.nii', 'md_output': 'md_output.nii', 'RD_output': 'RD_output.nii', 'deformation_output': 'deformation_output.nii', 'rot_output': 'rot_output.nii'} _redirect_x = False class DWIConvertInputSpec(CommandLineInputSpec): conversionMode = traits.Enum("DicomToNrrd", "DicomToFSL", "NrrdToFSL", "FSLToNrrd", desc="Determine which conversion to perform. DicomToNrrd (default): Convert DICOM series to NRRD DicomToFSL: Convert DICOM series to NIfTI File + gradient/bvalue text files NrrdToFSL: Convert DWI NRRD file to NIfTI File + gradient/bvalue text files FSLToNrrd: Convert NIfTI File + gradient/bvalue text files to NRRD file.", argstr="--conversionMode %s") inputVolume = File(desc="Input DWI volume -- not used for DicomToNrrd mode.", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output filename (.nhdr or .nrrd)", argstr="--outputVolume %s") inputDicomDirectory = Directory(desc="Directory holding Dicom series", exists=True, argstr="--inputDicomDirectory %s") fslNIFTIFile = File(desc="4D NIfTI file containing gradient volumes", exists=True, argstr="--fslNIFTIFile %s") inputBValues = File(desc="The B Values are stored in FSL .bval text file format", exists=True, argstr="--inputBValues %s") inputBVectors = File(desc="The Gradient Vectors are stored in FSL .bvec text file format", exists=True, argstr="--inputBVectors %s") outputBValues = traits.Either(traits.Bool, File(), hash_files=False, desc="The B Values are stored in FSL .bval text file format (defaults to .bval)", argstr="--outputBValues %s") outputBVectors = traits.Either(traits.Bool, File(), hash_files=False, desc="The Gradient Vectors are stored in FSL .bvec text file format (defaults to .bvec)", argstr="--outputBVectors %s") fMRI = traits.Bool(desc="Output a NRRD file, but without gradients", argstr="--fMRI ") writeProtocolGradientsFile = traits.Bool( desc="Write the protocol gradients to a file suffixed by \'.txt\' as they were specified in the procol by multiplying each diffusion gradient direction by the measurement frame. This file is for debugging purposes only, the format is not fixed, and will likely change as debugging of new dicom formats is necessary.", argstr="--writeProtocolGradientsFile ") useIdentityMeaseurementFrame = traits.Bool(desc="Adjust all the gradients so that the measurement frame is an identity matrix.", argstr="--useIdentityMeaseurementFrame ") useBMatrixGradientDirections = traits.Bool( desc="Fill the nhdr header with the gradient directions and bvalues computed out of the BMatrix. Only changes behavior for Siemens data. In some cases the standard public gradients are not properly computed. The gradients can emperically computed from the private BMatrix fields. In some cases the private BMatrix is consistent with the public grandients, but not in all cases, when it exists BMatrix is usually most robust.", argstr="--useBMatrixGradientDirections ") outputDirectory = traits.Either(traits.Bool, Directory(), hash_files=False, desc="Directory holding the output NRRD file", argstr="--outputDirectory %s") gradientVectorFile = traits.Either(traits.Bool, File(), hash_files=False, desc="Text file giving gradient vectors", argstr="--gradientVectorFile %s") smallGradientThreshold = traits.Float(desc="If a gradient magnitude is greater than 0 and less than smallGradientThreshold, then DWIConvert will display an error message and quit, unless the useBMatrixGradientDirections option is set.", argstr="--smallGradientThreshold %f") class DWIConvertOutputSpec(TraitedSpec): outputVolume = File(desc="Output filename (.nhdr or .nrrd)", exists=True) outputBValues = File(desc="The B Values are stored in FSL .bval text file format (defaults to .bval)", exists=True) outputBVectors = File(desc="The Gradient Vectors are stored in FSL .bvec text file format (defaults to .bvec)", exists=True) outputDirectory = Directory(desc="Directory holding the output NRRD file", exists=True) gradientVectorFile = File(desc="Text file giving gradient vectors", exists=True) class DWIConvert(SEMLikeCommandLine): """title: DWIConverter category: Diffusion.Diffusion Data Conversion description: Converts diffusion weighted MR images in dicom series into Nrrd format for analysis in Slicer. This program has been tested on only a limited subset of DTI dicom formats available from Siemens, GE, and Phillips scanners. Work in progress to support dicom multi-frame data. The program parses dicom header to extract necessary information about measurement frame, diffusion weighting directions, b-values, etc, and write out a nrrd image. For non-diffusion weighted dicom images, it loads in an entire dicom series and writes out a single dicom volume in a .nhdr/.raw pair. version: Version 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DWIConverter license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Vince Magnotta (UIowa), Hans Johnson (UIowa), Joy Matsui (UIowa), Kent Williams (UIowa), Mark Scully (Uiowa), Xiaodong Tao (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Additional support for DTI data produced on Philips scanners was contributed by Vincent Magnotta and Hans Johnson at the University of Iowa. """ input_spec = DWIConvertInputSpec output_spec = DWIConvertOutputSpec _cmd = " DWIConvert " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'outputDirectory': 'outputDirectory', 'outputBValues': 'outputBValues.bval', 'gradientVectorFile': 'gradientVectorFile', 'outputBVectors': 'outputBVectors.bvec'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/gtract.py000066400000000000000000002064551257611314500242360ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class gtractTransformToDisplacementFieldInputSpec(CommandLineInputSpec): inputTransform = File(desc="Input Transform File Name", exists=True, argstr="--inputTransform %s") inputReferenceVolume = File(desc="Required: input image file name to exemplify the anatomical space over which to vcl_express the transform as a displacement field.", exists=True, argstr="--inputReferenceVolume %s") outputDeformationFieldVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output deformation field", argstr="--outputDeformationFieldVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractTransformToDisplacementFieldOutputSpec(TraitedSpec): outputDeformationFieldVolume = File(desc="Output deformation field", exists=True) class gtractTransformToDisplacementField(SEMLikeCommandLine): """title: Create Displacement Field category: Diffusion.GTRACT description: This program will compute forward deformation from the given Transform. The size of the DF is equal to MNI space version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta, Madhura Ingalhalikar, and Greg Harris acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractTransformToDisplacementFieldInputSpec output_spec = gtractTransformToDisplacementFieldOutputSpec _cmd = " gtractTransformToDisplacementField " _outputs_filenames = {'outputDeformationFieldVolume': 'outputDeformationFieldVolume.nii'} _redirect_x = False class gtractInvertBSplineTransformInputSpec(CommandLineInputSpec): inputReferenceVolume = File(desc="Required: input image file name to exemplify the anatomical space to interpolate over.", exists=True, argstr="--inputReferenceVolume %s") inputTransform = File(desc="Required: input B-Spline transform file name", exists=True, argstr="--inputTransform %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output transform file name", argstr="--outputTransform %s") landmarkDensity = InputMultiPath(traits.Int, desc="Number of landmark subdivisions in all 3 directions", sep=",", argstr="--landmarkDensity %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractInvertBSplineTransformOutputSpec(TraitedSpec): outputTransform = File(desc="Required: output transform file name", exists=True) class gtractInvertBSplineTransform(SEMLikeCommandLine): """title: B-Spline Transform Inversion category: Diffusion.GTRACT description: This program will invert a B-Spline transform using a thin-plate spline approximation. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractInvertBSplineTransformInputSpec output_spec = gtractInvertBSplineTransformOutputSpec _cmd = " gtractInvertBSplineTransform " _outputs_filenames = {'outputTransform': 'outputTransform.h5'} _redirect_x = False class gtractConcatDwiInputSpec(CommandLineInputSpec): inputVolume = InputMultiPath(File(exists=True), desc="Required: input file containing the first diffusion weighted image", argstr="--inputVolume %s...") ignoreOrigins = traits.Bool(desc="If image origins are different force all images to origin of first image", argstr="--ignoreOrigins ") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the combined diffusion weighted images.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractConcatDwiOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the combined diffusion weighted images.", exists=True) class gtractConcatDwi(SEMLikeCommandLine): """title: Concat DWI Images category: Diffusion.GTRACT description: This program will concatenate two DTI runs together. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractConcatDwiInputSpec output_spec = gtractConcatDwiOutputSpec _cmd = " gtractConcatDwi " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractAverageBvaluesInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image file name containing multiple baseline gradients to average", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing directly averaged baseline images", argstr="--outputVolume %s") directionsTolerance = traits.Float(desc="Tolerance for matching identical gradient direction pairs", argstr="--directionsTolerance %f") averageB0only = traits.Bool(desc="Average only baseline gradients. All other gradient directions are not averaged, but retained in the outputVolume", argstr="--averageB0only ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractAverageBvaluesOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing directly averaged baseline images", exists=True) class gtractAverageBvalues(SEMLikeCommandLine): """title: Average B-Values category: Diffusion.GTRACT description: This program will directly average together the baseline gradients (b value equals 0) within a DWI scan. This is usually used after gtractCoregBvalues. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractAverageBvaluesInputSpec output_spec = gtractAverageBvaluesOutputSpec _cmd = " gtractAverageBvalues " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractCoregBvaluesInputSpec(CommandLineInputSpec): movingVolume = File(desc="Required: input moving image file name. In order to register gradients within a scan to its first gradient, set the movingVolume and fixedVolume as the same image.", exists=True, argstr="--movingVolume %s") fixedVolume = File(desc="Required: input fixed image file name. It is recommended that this image should either contain or be a b0 image.", exists=True, argstr="--fixedVolume %s") fixedVolumeIndex = traits.Int(desc="Index in the fixed image for registration. It is recommended that this image should be a b0 image.", argstr="--fixedVolumeIndex %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing moving images individually resampled and fit to the specified fixed image index.", argstr="--outputVolume %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Registration 3D transforms concatenated in a single output file. There are no tools that can use this, but can be used for debugging purposes.", argstr="--outputTransform %s") eddyCurrentCorrection = traits.Bool(desc="Flag to perform eddy current corection in addition to motion correction (recommended)", argstr="--eddyCurrentCorrection ") numberOfIterations = traits.Int(desc="Number of iterations in each 3D fit", argstr="--numberOfIterations %d") numberOfSpatialSamples = traits.Int( desc="The number of voxels sampled for mutual information computation. Increase this for a slower, more careful fit. NOTE that it is suggested to use samplingPercentage instead of this option. However, if set, it overwrites the samplingPercentage option. ", argstr="--numberOfSpatialSamples %d") samplingPercentage = traits.Float( desc="This is a number in (0.0,1.0] interval that shows the percentage of the input fixed image voxels that are sampled for mutual information computation. Increase this for a slower, more careful fit. You can also limit the sampling focus with ROI masks and ROIAUTO mask generation. The default is to use approximately 5% of voxels (for backwards compatibility 5% ~= 500000/(256*256*256)). Typical values range from 1% for low detail images to 20% for high detail images.", argstr="--samplingPercentage %f") relaxationFactor = traits.Float(desc="Fraction of gradient from Jacobian to attempt to move in each 3D fit step (adjust when eddyCurrentCorrection is enabled; suggested value = 0.25)", argstr="--relaxationFactor %f") maximumStepSize = traits.Float(desc="Maximum permitted step size to move in each 3D fit step (adjust when eddyCurrentCorrection is enabled; suggested value = 0.1)", argstr="--maximumStepSize %f") minimumStepSize = traits.Float(desc="Minimum required step size to move in each 3D fit step without converging -- decrease this to make the fit more exacting", argstr="--minimumStepSize %f") spatialScale = traits.Float(desc="How much to scale up changes in position compared to unit rotational changes in radians -- decrease this to put more rotation in the fit", argstr="--spatialScale %f") registerB0Only = traits.Bool(desc="Register the B0 images only", argstr="--registerB0Only ") debugLevel = traits.Int(desc="Display debug messages, and produce debug intermediate results. 0=OFF, 1=Minimal, 10=Maximum debugging.", argstr="--debugLevel %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractCoregBvaluesOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing moving images individually resampled and fit to the specified fixed image index.", exists=True) outputTransform = File(desc="Registration 3D transforms concatenated in a single output file. There are no tools that can use this, but can be used for debugging purposes.", exists=True) class gtractCoregBvalues(SEMLikeCommandLine): """title: Coregister B-Values category: Diffusion.GTRACT description: This step should be performed after converting DWI scans from DICOM to NRRD format. This program will register all gradients in a NRRD diffusion weighted 4D vector image (moving image) to a specified index in a fixed image. It also supports co-registration with a T2 weighted image or field map in the same plane as the DWI data. The fixed image for the registration should be a b0 image. A mutual information metric cost function is used for the registration because of the differences in signal intensity as a result of the diffusion gradients. The full affine allows the registration procedure to correct for eddy current distortions that may exist in the data. If the eddyCurrentCorrection is enabled, relaxationFactor (0.25) and maximumStepSize (0.1) should be adjusted. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractCoregBvaluesInputSpec output_spec = gtractCoregBvaluesOutputSpec _cmd = " gtractCoregBvalues " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd', 'outputTransform': 'outputTransform.h5'} _redirect_x = False class gtractResampleAnisotropyInputSpec(CommandLineInputSpec): inputAnisotropyVolume = File(desc="Required: input file containing the anisotropy image", exists=True, argstr="--inputAnisotropyVolume %s") inputAnatomicalVolume = File(desc="Required: input file containing the anatomical image whose characteristics will be cloned.", exists=True, argstr="--inputAnatomicalVolume %s") inputTransform = File(desc="Required: input Rigid OR Bspline transform file name", exists=True, argstr="--inputTransform %s") transformType = traits.Enum("Rigid", "B-Spline", desc="Transform type: Rigid, B-Spline", argstr="--transformType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the resampled transformed anisotropy image.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractResampleAnisotropyOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the resampled transformed anisotropy image.", exists=True) class gtractResampleAnisotropy(SEMLikeCommandLine): """title: Resample Anisotropy category: Diffusion.GTRACT description: This program will resample a floating point image using either the Rigid or B-Spline transform. You may want to save the aligned B0 image after each of the anisotropy map co-registration steps with the anatomical image to check the registration quality with another tool. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractResampleAnisotropyInputSpec output_spec = gtractResampleAnisotropyOutputSpec _cmd = " gtractResampleAnisotropy " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractResampleCodeImageInputSpec(CommandLineInputSpec): inputCodeVolume = File(desc="Required: input file containing the code image", exists=True, argstr="--inputCodeVolume %s") inputReferenceVolume = File(desc="Required: input file containing the standard image to clone the characteristics of.", exists=True, argstr="--inputReferenceVolume %s") inputTransform = File(desc="Required: input Rigid or Inverse-B-Spline transform file name", exists=True, argstr="--inputTransform %s") transformType = traits.Enum("Rigid", "Affine", "B-Spline", "Inverse-B-Spline", "None", desc="Transform type: Rigid or Inverse-B-Spline", argstr="--transformType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the resampled code image in acquisition space.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractResampleCodeImageOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the resampled code image in acquisition space.", exists=True) class gtractResampleCodeImage(SEMLikeCommandLine): """title: Resample Code Image category: Diffusion.GTRACT description: This program will resample a short integer code image using either the Rigid or Inverse-B-Spline transform. The reference image is the DTI tensor anisotropy image space, and the input code image is in anatomical space. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractResampleCodeImageInputSpec output_spec = gtractResampleCodeImageOutputSpec _cmd = " gtractResampleCodeImage " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractCopyImageOrientationInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input file containing the signed short image to reorient without resampling.", exists=True, argstr="--inputVolume %s") inputReferenceVolume = File(desc="Required: input file containing orietation that will be cloned.", exists=True, argstr="--inputReferenceVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD or Nifti file containing the reoriented image in reference image space.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractCopyImageOrientationOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD or Nifti file containing the reoriented image in reference image space.", exists=True) class gtractCopyImageOrientation(SEMLikeCommandLine): """title: Copy Image Orientation category: Diffusion.GTRACT description: This program will copy the orientation from the reference image into the moving image. Currently, the registration process requires that the diffusion weighted images and the anatomical images have the same image orientation (i.e. Axial, Coronal, Sagittal). It is suggested that you copy the image orientation from the diffusion weighted images and apply this to the anatomical image. This image can be subsequently removed after the registration step is complete. We anticipate that this limitation will be removed in future versions of the registration programs. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractCopyImageOrientationInputSpec output_spec = gtractCopyImageOrientationOutputSpec _cmd = " gtractCopyImageOrientation " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractCreateGuideFiberInputSpec(CommandLineInputSpec): inputFiber = File(desc="Required: input fiber tract file name", exists=True, argstr="--inputFiber %s") numberOfPoints = traits.Int(desc="Number of points in output guide fiber", argstr="--numberOfPoints %d") outputFiber = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output guide fiber file name", argstr="--outputFiber %s") writeXMLPolyDataFile = traits.Bool(desc="Flag to make use of XML files when reading and writing vtkPolyData.", argstr="--writeXMLPolyDataFile ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractCreateGuideFiberOutputSpec(TraitedSpec): outputFiber = File(desc="Required: output guide fiber file name", exists=True) class gtractCreateGuideFiber(SEMLikeCommandLine): """title: Create Guide Fiber category: Diffusion.GTRACT description: This program will create a guide fiber by averaging fibers from a previously generated tract. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractCreateGuideFiberInputSpec output_spec = gtractCreateGuideFiberOutputSpec _cmd = " gtractCreateGuideFiber " _outputs_filenames = {'outputFiber': 'outputFiber.vtk'} _redirect_x = False class gtractAnisotropyMapInputSpec(CommandLineInputSpec): inputTensorVolume = File(desc="Required: input file containing the diffusion tensor image", exists=True, argstr="--inputTensorVolume %s") anisotropyType = traits.Enum("ADC", "FA", "RA", "VR", "AD", "RD", "LI", desc="Anisotropy Mapping Type: ADC, FA, RA, VR, AD, RD, LI", argstr="--anisotropyType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the selected kind of anisotropy scalar.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractAnisotropyMapOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the selected kind of anisotropy scalar.", exists=True) class gtractAnisotropyMap(SEMLikeCommandLine): """title: Anisotropy Map category: Diffusion.GTRACT description: This program will generate a scalar map of anisotropy, given a tensor representation. Anisotropy images are used for fiber tracking, but the anisotropy scalars are not defined along the path. Instead, the tensor representation is included as point data allowing all of these metrics to be computed using only the fiber tract point data. The images can be saved in any ITK supported format, but it is suggested that you use an image format that supports the definition of the image origin. This includes NRRD, NifTI, and Meta formats. These images can also be used for scalar analysis including regional anisotropy measures or VBM style analysis. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractAnisotropyMapInputSpec output_spec = gtractAnisotropyMapOutputSpec _cmd = " gtractAnisotropyMap " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractClipAnisotropyInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image file name", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the clipped anisotropy image", argstr="--outputVolume %s") clipFirstSlice = traits.Bool(desc="Clip the first slice of the anisotropy image", argstr="--clipFirstSlice ") clipLastSlice = traits.Bool(desc="Clip the last slice of the anisotropy image", argstr="--clipLastSlice ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractClipAnisotropyOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the clipped anisotropy image", exists=True) class gtractClipAnisotropy(SEMLikeCommandLine): """title: Clip Anisotropy category: Diffusion.GTRACT description: This program will zero the first and/or last slice of an anisotropy image, creating a clipped anisotropy image. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractClipAnisotropyInputSpec output_spec = gtractClipAnisotropyOutputSpec _cmd = " gtractClipAnisotropy " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractResampleB0InputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input file containing the 4D image", exists=True, argstr="--inputVolume %s") inputAnatomicalVolume = File(desc="Required: input file containing the anatomical image defining the origin, spacing and size of the resampled image (template)", exists=True, argstr="--inputAnatomicalVolume %s") inputTransform = File(desc="Required: input Rigid OR Bspline transform file name", exists=True, argstr="--inputTransform %s") vectorIndex = traits.Int(desc="Index in the diffusion weighted image set for the B0 image", argstr="--vectorIndex %d") transformType = traits.Enum("Rigid", "B-Spline", desc="Transform type: Rigid, B-Spline", argstr="--transformType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the resampled input image.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractResampleB0OutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the resampled input image.", exists=True) class gtractResampleB0(SEMLikeCommandLine): """title: Resample B0 category: Diffusion.GTRACT description: This program will resample a signed short image using either a Rigid or B-Spline transform. The user must specify a template image that will be used to define the origin, orientation, spacing, and size of the resampled image. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractResampleB0InputSpec output_spec = gtractResampleB0OutputSpec _cmd = " gtractResampleB0 " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractInvertRigidTransformInputSpec(CommandLineInputSpec): inputTransform = File(desc="Required: input rigid transform file name", exists=True, argstr="--inputTransform %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output transform file name", argstr="--outputTransform %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractInvertRigidTransformOutputSpec(TraitedSpec): outputTransform = File(desc="Required: output transform file name", exists=True) class gtractInvertRigidTransform(SEMLikeCommandLine): """title: Rigid Transform Inversion category: Diffusion.GTRACT description: This program will invert a Rigid transform. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractInvertRigidTransformInputSpec output_spec = gtractInvertRigidTransformOutputSpec _cmd = " gtractInvertRigidTransform " _outputs_filenames = {'outputTransform': 'outputTransform.h5'} _redirect_x = False class gtractImageConformityInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input file containing the signed short image to reorient without resampling.", exists=True, argstr="--inputVolume %s") inputReferenceVolume = File(desc="Required: input file containing the standard image to clone the characteristics of.", exists=True, argstr="--inputReferenceVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output Nrrd or Nifti file containing the reoriented image in reference image space.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractImageConformityOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output Nrrd or Nifti file containing the reoriented image in reference image space.", exists=True) class gtractImageConformity(SEMLikeCommandLine): """title: Image Conformity category: Diffusion.GTRACT description: This program will straighten out the Direction and Origin to match the Reference Image. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractImageConformityInputSpec output_spec = gtractImageConformityOutputSpec _cmd = " gtractImageConformity " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class compareTractInclusionInputSpec(CommandLineInputSpec): testFiber = File(desc="Required: test fiber tract file name", exists=True, argstr="--testFiber %s") standardFiber = File(desc="Required: standard fiber tract file name", exists=True, argstr="--standardFiber %s") closeness = traits.Float(desc="Closeness of every test fiber to some fiber in the standard tract, computed as a sum of squares of spatial differences of standard points", argstr="--closeness %f") numberOfPoints = traits.Int(desc="Number of points in comparison fiber pairs", argstr="--numberOfPoints %d") testForBijection = traits.Bool(desc="Flag to apply the closeness criterion both ways", argstr="--testForBijection ") testForFiberCardinality = traits.Bool(desc="Flag to require the same number of fibers in both tracts", argstr="--testForFiberCardinality ") writeXMLPolyDataFile = traits.Bool(desc="Flag to make use of XML files when reading and writing vtkPolyData.", argstr="--writeXMLPolyDataFile ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class compareTractInclusionOutputSpec(TraitedSpec): pass class compareTractInclusion(SEMLikeCommandLine): """title: Compare Tracts category: Diffusion.GTRACT description: This program will halt with a status code indicating whether a test tract is nearly enough included in a standard tract in the sense that every fiber in the test tract has a low enough sum of squares distance to some fiber in the standard tract modulo spline resampling of every fiber to a fixed number of points. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = compareTractInclusionInputSpec output_spec = compareTractInclusionOutputSpec _cmd = " compareTractInclusion " _outputs_filenames = {} _redirect_x = False class gtractFastMarchingTrackingInputSpec(CommandLineInputSpec): inputTensorVolume = File(desc="Required: input tensor image file name", exists=True, argstr="--inputTensorVolume %s") inputAnisotropyVolume = File(desc="Required: input anisotropy image file name", exists=True, argstr="--inputAnisotropyVolume %s") inputCostVolume = File(desc="Required: input vcl_cost image file name", exists=True, argstr="--inputCostVolume %s") inputStartingSeedsLabelMapVolume = File(desc="Required: input starting seeds LabelMap image file name", exists=True, argstr="--inputStartingSeedsLabelMapVolume %s") startingSeedsLabel = traits.Int(desc="Label value for Starting Seeds", argstr="--startingSeedsLabel %d") outputTract = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output vtkPolydata file containing tract lines and the point data collected along them.", argstr="--outputTract %s") writeXMLPolyDataFile = traits.Bool(desc="Flag to make use of the XML format for vtkPolyData fiber tracts.", argstr="--writeXMLPolyDataFile ") numberOfIterations = traits.Int(desc="Number of iterations used for the optimization", argstr="--numberOfIterations %d") seedThreshold = traits.Float(desc="Anisotropy threshold used for seed selection", argstr="--seedThreshold %f") trackingThreshold = traits.Float(desc="Anisotropy threshold used for fiber tracking", argstr="--trackingThreshold %f") costStepSize = traits.Float(desc="Cost image sub-voxel sampling", argstr="--costStepSize %f") maximumStepSize = traits.Float(desc="Maximum step size to move when tracking", argstr="--maximumStepSize %f") minimumStepSize = traits.Float(desc="Minimum step size to move when tracking", argstr="--minimumStepSize %f") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractFastMarchingTrackingOutputSpec(TraitedSpec): outputTract = File(desc="Required: name of output vtkPolydata file containing tract lines and the point data collected along them.", exists=True) class gtractFastMarchingTracking(SEMLikeCommandLine): """title: Fast Marching Tracking category: Diffusion.GTRACT description: This program will use a fast marching fiber tracking algorithm to identify fiber tracts from a tensor image. This program is the second portion of the algorithm. The user must first run gtractCostFastMarching to generate the vcl_cost image. The second step of the algorithm implemented here is a gradient descent soplution from the defined ending region back to the seed points specified in gtractCostFastMarching. This algorithm is roughly based on the work by G. Parker et al. from IEEE Transactions On Medical Imaging, 21(5): 505-512, 2002. An additional feature of including anisotropy into the vcl_cost function calculation is included. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. The original code here was developed by Daisy Espino. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractFastMarchingTrackingInputSpec output_spec = gtractFastMarchingTrackingOutputSpec _cmd = " gtractFastMarchingTracking " _outputs_filenames = {'outputTract': 'outputTract.vtk'} _redirect_x = False class gtractInvertDisplacementFieldInputSpec(CommandLineInputSpec): baseImage = File(desc="Required: base image used to define the size of the inverse field", exists=True, argstr="--baseImage %s") deformationImage = File(desc="Required: Displacement field image", exists=True, argstr="--deformationImage %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: Output deformation field", argstr="--outputVolume %s") subsamplingFactor = traits.Int(desc="Subsampling factor for the deformation field", argstr="--subsamplingFactor %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractInvertDisplacementFieldOutputSpec(TraitedSpec): outputVolume = File(desc="Required: Output deformation field", exists=True) class gtractInvertDisplacementField(SEMLikeCommandLine): """title: Invert Displacement Field category: Diffusion.GTRACT description: This program will invert a deformatrion field. The size of the deformation field is defined by an example image provided by the user version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractInvertDisplacementFieldInputSpec output_spec = gtractInvertDisplacementFieldOutputSpec _cmd = " gtractInvertDisplacementField " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False class gtractCoRegAnatomyInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input vector image file name. It is recommended that the input volume is the skull stripped baseline image of the DWI scan.", exists=True, argstr="--inputVolume %s") inputAnatomicalVolume = File(desc="Required: input anatomical image file name. It is recommended that that the input anatomical image has been skull stripped and has the same orientation as the DWI scan.", exists=True, argstr="--inputAnatomicalVolume %s") vectorIndex = traits.Int(desc="Vector image index in the moving image (within the DWI) to be used for registration.", argstr="--vectorIndex %d") inputRigidTransform = File(desc="Required (for B-Spline type co-registration): input rigid transform file name. Used as a starting point for the anatomical B-Spline registration.", exists=True, argstr="--inputRigidTransform %s") outputTransformName = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: filename for the fit transform.", argstr="--outputTransformName %s") transformType = traits.Enum("Rigid", "Bspline", desc="Transform Type: Rigid|Bspline", argstr="--transformType %s") numberOfIterations = traits.Int(desc="Number of iterations in the selected 3D fit", argstr="--numberOfIterations %d") gridSize = InputMultiPath(traits.Int, desc="Number of grid subdivisions in all 3 directions", sep=",", argstr="--gridSize %s") borderSize = traits.Int(desc="Size of border", argstr="--borderSize %d") numberOfHistogramBins = traits.Int(desc="Number of histogram bins", argstr="--numberOfHistogramBins %d") spatialScale = traits.Int(desc="Scales the number of voxels in the image by this value to specify the number of voxels used in the registration", argstr="--spatialScale %d") convergence = traits.Float(desc="Convergence Factor", argstr="--convergence %f") gradientTolerance = traits.Float(desc="Gradient Tolerance", argstr="--gradientTolerance %f") maxBSplineDisplacement = traits.Float( desc=" Sets the maximum allowed displacements in image physical coordinates for BSpline control grid along each axis. A value of 0.0 indicates that the problem should be unbounded. NOTE: This only constrains the BSpline portion, and does not limit the displacement from the associated bulk transform. This can lead to a substantial reduction in computation time in the BSpline optimizer., ", argstr="--maxBSplineDisplacement %f") maximumStepSize = traits.Float(desc="Maximum permitted step size to move in the selected 3D fit", argstr="--maximumStepSize %f") minimumStepSize = traits.Float(desc="Minimum required step size to move in the selected 3D fit without converging -- decrease this to make the fit more exacting", argstr="--minimumStepSize %f") translationScale = traits.Float(desc="How much to scale up changes in position compared to unit rotational changes in radians -- decrease this to put more translation in the fit", argstr="--translationScale %f") relaxationFactor = traits.Float(desc="Fraction of gradient from Jacobian to attempt to move in the selected 3D fit", argstr="--relaxationFactor %f") numberOfSamples = traits.Int( desc="The number of voxels sampled for mutual information computation. Increase this for a slower, more careful fit. NOTE that it is suggested to use samplingPercentage instead of this option. However, if set, it overwrites the samplingPercentage option. ", argstr="--numberOfSamples %d") samplingPercentage = traits.Float( desc="This is a number in (0.0,1.0] interval that shows the percentage of the input fixed image voxels that are sampled for mutual information computation. Increase this for a slower, more careful fit. You can also limit the sampling focus with ROI masks and ROIAUTO mask generation. The default is to use approximately 5% of voxels (for backwards compatibility 5% ~= 500000/(256*256*256)). Typical values range from 1% for low detail images to 20% for high detail images.", argstr="--samplingPercentage %f") useMomentsAlign = traits.Bool( desc="MomentsAlign assumes that the center of mass of the images represent similar structures. Perform a MomentsAlign registration as part of the sequential registration steps. This option MUST come first, and CAN NOT be used with either CenterOfHeadLAlign, GeometryAlign, or initialTransform file. This family of options superceeds the use of transformType if any of them are set.", argstr="--useMomentsAlign ") useGeometryAlign = traits.Bool( desc="GeometryAlign on assumes that the center of the voxel lattice of the images represent similar structures. Perform a GeometryCenterAlign registration as part of the sequential registration steps. This option MUST come first, and CAN NOT be used with either MomentsAlign, CenterOfHeadAlign, or initialTransform file. This family of options superceeds the use of transformType if any of them are set.", argstr="--useGeometryAlign ") useCenterOfHeadAlign = traits.Bool( desc="CenterOfHeadAlign attempts to find a hemisphere full of foreground voxels from the superior direction as an estimate of where the center of a head shape would be to drive a center of mass estimate. Perform a CenterOfHeadAlign registration as part of the sequential registration steps. This option MUST come first, and CAN NOT be used with either MomentsAlign, GeometryAlign, or initialTransform file. This family of options superceeds the use of transformType if any of them are set.", argstr="--useCenterOfHeadAlign ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractCoRegAnatomyOutputSpec(TraitedSpec): outputTransformName = File(desc="Required: filename for the fit transform.", exists=True) class gtractCoRegAnatomy(SEMLikeCommandLine): """title: Coregister B0 to Anatomy B-Spline category: Diffusion.GTRACT description: This program will register a Nrrd diffusion weighted 4D vector image to a fixed anatomical image. Two registration methods are supported for alignment with anatomical images: Rigid and B-Spline. The rigid registration performs a rigid body registration with the anatomical images and should be done as well to initialize the B-Spline transform. The B-SPline transform is the deformable transform, where the user can control the amount of deformation based on the number of control points as well as the maximum distance that these points can move. The B-Spline registration places a low dimensional grid in the image, which is deformed. This allows for some susceptibility related distortions to be removed from the diffusion weighted images. In general the amount of motion in the slice selection and read-out directions direction should be kept low. The distortion is in the phase encoding direction in the images. It is recommended that skull stripped (i.e. image containing only brain with skull removed) images shoud be used for image co-registration with the B-Spline transform. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractCoRegAnatomyInputSpec output_spec = gtractCoRegAnatomyOutputSpec _cmd = " gtractCoRegAnatomy " _outputs_filenames = {'outputTransformName': 'outputTransformName.h5'} _redirect_x = False class gtractResampleDWIInPlaceInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image is a 4D NRRD image.", exists=True, argstr="--inputVolume %s") referenceVolume = File(desc="If provided, resample to the final space of the referenceVolume 3D data set.", exists=True, argstr="--referenceVolume %s") outputResampledB0 = traits.Either(traits.Bool, File(), hash_files=False, desc="Convenience function for extracting the first index location (assumed to be the B0)", argstr="--outputResampledB0 %s") inputTransform = File(desc="Required: transform file derived from rigid registration of b0 image to reference structural image.", exists=True, argstr="--inputTransform %s") warpDWITransform = File(desc="Optional: transform file to warp gradient volumes.", exists=True, argstr="--warpDWITransform %s") debugLevel = traits.Int(desc="Display debug messages, and produce debug intermediate results. 0=OFF, 1=Minimal, 10=Maximum debugging.", argstr="--debugLevel %d") imageOutputSize = InputMultiPath(traits.Int, desc="The voxel lattice for the output image, padding is added if necessary. NOTE: if 0,0,0, then the inputVolume size is used.", sep=",", argstr="--imageOutputSize %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image (NRRD file) that has been rigidly transformed into the space of the structural image and padded if image padding was changed from 0,0,0 default.", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractResampleDWIInPlaceOutputSpec(TraitedSpec): outputResampledB0 = File(desc="Convenience function for extracting the first index location (assumed to be the B0)", exists=True) outputVolume = File(desc="Required: output image (NRRD file) that has been rigidly transformed into the space of the structural image and padded if image padding was changed from 0,0,0 default.", exists=True) class gtractResampleDWIInPlace(SEMLikeCommandLine): """title: Resample DWI In Place category: Diffusion.GTRACT description: Resamples DWI image to structural image. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta, Greg Harris, Hans Johnson, and Joy Matsui. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractResampleDWIInPlaceInputSpec output_spec = gtractResampleDWIInPlaceOutputSpec _cmd = " gtractResampleDWIInPlace " _outputs_filenames = {'outputResampledB0': 'outputResampledB0.nii', 'outputVolume': 'outputVolume.nii'} _redirect_x = False class gtractCostFastMarchingInputSpec(CommandLineInputSpec): inputTensorVolume = File(desc="Required: input tensor image file name", exists=True, argstr="--inputTensorVolume %s") inputAnisotropyVolume = File(desc="Required: input anisotropy image file name", exists=True, argstr="--inputAnisotropyVolume %s") inputStartingSeedsLabelMapVolume = File(desc="Required: input starting seeds LabelMap image file name", exists=True, argstr="--inputStartingSeedsLabelMapVolume %s") startingSeedsLabel = traits.Int(desc="Label value for Starting Seeds", argstr="--startingSeedsLabel %d") outputCostVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output vcl_cost image", argstr="--outputCostVolume %s") outputSpeedVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output speed image", argstr="--outputSpeedVolume %s") anisotropyWeight = traits.Float(desc="Anisotropy weight used for vcl_cost function calculations", argstr="--anisotropyWeight %f") stoppingValue = traits.Float(desc="Terminiating value for vcl_cost function estimation", argstr="--stoppingValue %f") seedThreshold = traits.Float(desc="Anisotropy threshold used for seed selection", argstr="--seedThreshold %f") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractCostFastMarchingOutputSpec(TraitedSpec): outputCostVolume = File(desc="Output vcl_cost image", exists=True) outputSpeedVolume = File(desc="Output speed image", exists=True) class gtractCostFastMarching(SEMLikeCommandLine): """title: Cost Fast Marching category: Diffusion.GTRACT description: This program will use a fast marching fiber tracking algorithm to identify fiber tracts from a tensor image. This program is the first portion of the algorithm. The user must first run gtractFastMarchingTracking to generate the actual fiber tracts. This algorithm is roughly based on the work by G. Parker et al. from IEEE Transactions On Medical Imaging, 21(5): 505-512, 2002. An additional feature of including anisotropy into the vcl_cost function calculation is included. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. The original code here was developed by Daisy Espino. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractCostFastMarchingInputSpec output_spec = gtractCostFastMarchingOutputSpec _cmd = " gtractCostFastMarching " _outputs_filenames = {'outputCostVolume': 'outputCostVolume.nrrd', 'outputSpeedVolume': 'outputSpeedVolume.nrrd'} _redirect_x = False class gtractFiberTrackingInputSpec(CommandLineInputSpec): inputTensorVolume = File(desc="Required (for Free, Streamline, GraphSearch, and Guided fiber tracking methods): input tensor image file name", exists=True, argstr="--inputTensorVolume %s") inputAnisotropyVolume = File(desc="Required (for Free, Streamline, GraphSearch, and Guided fiber tracking methods): input anisotropy image file name", exists=True, argstr="--inputAnisotropyVolume %s") inputStartingSeedsLabelMapVolume = File(desc="Required (for Free, Streamline, GraphSearch, and Guided fiber tracking methods): input starting seeds LabelMap image file name", exists=True, argstr="--inputStartingSeedsLabelMapVolume %s") startingSeedsLabel = traits.Int(desc="Label value for Starting Seeds (required if Label number used to create seed point in Slicer was not 1)", argstr="--startingSeedsLabel %d") inputEndingSeedsLabelMapVolume = File(desc="Required (for Streamline, GraphSearch, and Guided fiber tracking methods): input ending seeds LabelMap image file name", exists=True, argstr="--inputEndingSeedsLabelMapVolume %s") endingSeedsLabel = traits.Int(desc="Label value for Ending Seeds (required if Label number used to create seed point in Slicer was not 1)", argstr="--endingSeedsLabel %d") inputTract = File(desc="Required (for Guided fiber tracking method): guide fiber in vtkPolydata file containing one tract line.", exists=True, argstr="--inputTract %s") outputTract = traits.Either(traits.Bool, File(), hash_files=False, desc="Required (for Free, Streamline, GraphSearch, and Guided fiber tracking methods): name of output vtkPolydata file containing tract lines and the point data collected along them.", argstr="--outputTract %s") writeXMLPolyDataFile = traits.Bool(desc="Flag to make use of the XML format for vtkPolyData fiber tracts.", argstr="--writeXMLPolyDataFile ") trackingMethod = traits.Enum("Guided", "Free", "Streamline", "GraphSearch", desc="Fiber tracking Filter Type: Guided|Free|Streamline|GraphSearch", argstr="--trackingMethod %s") guidedCurvatureThreshold = traits.Float(desc="Guided Curvature Threshold (Degrees)", argstr="--guidedCurvatureThreshold %f") maximumGuideDistance = traits.Float(desc="Maximum distance for using the guide fiber direction", argstr="--maximumGuideDistance %f") seedThreshold = traits.Float(desc="Anisotropy threshold for seed selection (recommended for Free fiber tracking)", argstr="--seedThreshold %f") trackingThreshold = traits.Float(desc="Anisotropy threshold for fiber tracking (anisotropy values of the next point along the path)", argstr="--trackingThreshold %f") curvatureThreshold = traits.Float(desc="Curvature threshold in degrees (recommended for Free fiber tracking)", argstr="--curvatureThreshold %f") branchingThreshold = traits.Float(desc="Anisotropy Branching threshold (recommended for GraphSearch fiber tracking method)", argstr="--branchingThreshold %f") maximumBranchPoints = traits.Int(desc="Maximum branch points (recommended for GraphSearch fiber tracking method)", argstr="--maximumBranchPoints %d") useRandomWalk = traits.Bool(desc="Flag to use random walk.", argstr="--useRandomWalk ") randomSeed = traits.Int(desc="Random number generator seed", argstr="--randomSeed %d") branchingAngle = traits.Float(desc="Branching angle in degrees (recommended for GraphSearch fiber tracking method)", argstr="--branchingAngle %f") minimumLength = traits.Float(desc="Minimum fiber length. Helpful for filtering invalid tracts.", argstr="--minimumLength %f") maximumLength = traits.Float(desc="Maximum fiber length (voxels)", argstr="--maximumLength %f") stepSize = traits.Float(desc="Fiber tracking step size", argstr="--stepSize %f") useLoopDetection = traits.Bool(desc="Flag to make use of loop detection.", argstr="--useLoopDetection ") useTend = traits.Bool(desc="Flag to make use of Tend F and Tend G parameters.", argstr="--useTend ") tendF = traits.Float(desc="Tend F parameter", argstr="--tendF %f") tendG = traits.Float(desc="Tend G parameter", argstr="--tendG %f") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractFiberTrackingOutputSpec(TraitedSpec): outputTract = File(desc="Required (for Free, Streamline, GraphSearch, and Guided fiber tracking methods): name of output vtkPolydata file containing tract lines and the point data collected along them.", exists=True) class gtractFiberTracking(SEMLikeCommandLine): """title: Fiber Tracking category: Diffusion.GTRACT description: This program implements four fiber tracking methods (Free, Streamline, GraphSearch, Guided). The output of the fiber tracking is vtkPolyData (i.e. Polylines) that can be loaded into Slicer3 for visualization. The poly data can be saved in either old VTK format files (.vtk) or in the new VTK XML format (.xml). The polylines contain point data that defines ther Tensor at each point along the fiber tract. This can then be used to rendered as glyphs in Slicer3 and can be used to define severeal scalar measures without referencing back to the anisotropy images. (1) Free tracking is a basic streamlines algorithm. This is a direct implementation of the method original proposed by Basser et al. The tracking follows the primarty eigenvector. The tracking begins with seed points in the starting region. Only those voxels above the specified anisotropy threshold in the starting region are used as seed points. Tracking terminates either as a result of maximum fiber length, low ansiotropy, or large curvature. This is a great way to explore your data. (2) The streamlines algorithm is a direct implementation of the method originally proposed by Basser et al. The tracking follows the primary eigenvector. The tracking begins with seed points in the starting region. Only those voxels above the specified anisotropy threshold in the starting region are used as seed points. Tracking terminates either by reaching the ending region or reaching some stopping criteria. Stopping criteria are specified using the following parameters: tracking threshold, curvature threshold, and max length. Only paths terminating in the ending region are kept in this method. The TEND algorithm proposed by Lazar et al. (Human Brain Mapping 18:306-321, 2003) has been instrumented. This can be enabled using the --useTend option while performing Streamlines tracking. This utilizes the entire diffusion tensor to deflect the incoming vector instead of simply following the primary eigenvector. The TEND parameters are set using the --tendF and --tendG options. (3) Graph Search tracking is the first step in the full GTRACT algorithm developed by Cheng et al. (NeuroImage 31(3): 1075-1085, 2006) for finding the tracks in a tensor image. This method was developed to generate fibers in a Tensor representation where crossing fibers occur. The graph search algorithm follows the primary eigenvector in non-ambigous regions and utilizes branching and a graph search algorithm in ambigous regions. Ambiguous tracking regions are defined based on two criteria: Branching Al Threshold (anisotropy values below this value and above the traching threshold) and Curvature Major Eigen (angles of the primary eigenvector direction and the current tracking direction). In regions that meet this criteria, two or three tracking paths are considered. The first is the standard primary eigenvector direction. The second is the seconadary eigenvector direction. This is based on the assumption that these regions may be prolate regions. If the Random Walk option is selected then a third direction is also considered. This direction is defined by a cone pointing from the current position to the centroid of the ending region. The interior angle of the cone is specified by the user with the Branch/Guide Angle parameter. A vector contained inside of the cone is selected at random and used as the third direction. This method can also utilize the TEND option where the primary tracking direction is that specified by the TEND method instead of the primary eigenvector. The parameter '--maximumBranchPoints' allows the tracking to have this number of branches being considered at a time. If this number of branch points is exceeded at any time, then the algorithm will revert back to a streamline alogrithm until the number of branches is reduced. This allows the user to constrain the computational complexity of the algorithm. (4) The second phase of the GTRACT algorithm is Guided Tracking. This method incorporates anatomical information about the track orientation using an initial guess of the fiber track. In the originally proposed GTRACT method, this would be created from the fibers resulting from the Graph Search tracking. However, in practice this can be created using any method and could be defined manually. To create the guide fiber the program gtractCreateGuideFiber can be used. This program will load a fiber tract that has been generated and create a centerline representation of the fiber tract (i.e. a single fiber). In this method, the fiber tracking follows the primary eigenvector direction unless it deviates from the guide fiber track by a angle greater than that specified by the '--guidedCurvatureThreshold' parameter. The user must specify the guide fiber when running this program. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta, Greg Harris and Yongqiang Zhao. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractFiberTrackingInputSpec output_spec = gtractFiberTrackingOutputSpec _cmd = " gtractFiberTracking " _outputs_filenames = {'outputTract': 'outputTract.vtk'} _redirect_x = False class extractNrrdVectorIndexInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input file containing the vector that will be extracted", exists=True, argstr="--inputVolume %s") vectorIndex = traits.Int(desc="Index in the vector image to extract", argstr="--vectorIndex %d") setImageOrientation = traits.Enum("AsAcquired", "Axial", "Coronal", "Sagittal", desc="Sets the image orientation of the extracted vector (Axial, Coronal, Sagittal)", argstr="--setImageOrientation %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the vector image at the given index", argstr="--outputVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class extractNrrdVectorIndexOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the vector image at the given index", exists=True) class extractNrrdVectorIndex(SEMLikeCommandLine): """title: Extract Nrrd Index category: Diffusion.GTRACT description: This program will extract a 3D image (single vector) from a vector 3D image at a given vector index. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = extractNrrdVectorIndexInputSpec output_spec = extractNrrdVectorIndexOutputSpec _cmd = " extractNrrdVectorIndex " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class gtractResampleFibersInputSpec(CommandLineInputSpec): inputForwardDeformationFieldVolume = File(desc="Required: input forward deformation field image file name", exists=True, argstr="--inputForwardDeformationFieldVolume %s") inputReverseDeformationFieldVolume = File(desc="Required: input reverse deformation field image file name", exists=True, argstr="--inputReverseDeformationFieldVolume %s") inputTract = File(desc="Required: name of input vtkPolydata file containing tract lines.", exists=True, argstr="--inputTract %s") outputTract = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output vtkPolydata file containing tract lines and the point data collected along them.", argstr="--outputTract %s") writeXMLPolyDataFile = traits.Bool(desc="Flag to make use of the XML format for vtkPolyData fiber tracts.", argstr="--writeXMLPolyDataFile ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractResampleFibersOutputSpec(TraitedSpec): outputTract = File(desc="Required: name of output vtkPolydata file containing tract lines and the point data collected along them.", exists=True) class gtractResampleFibers(SEMLikeCommandLine): """title: Resample Fibers category: Diffusion.GTRACT description: This program will resample a fiber tract with respect to a pair of deformation fields that represent the forward and reverse deformation fields. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractResampleFibersInputSpec output_spec = gtractResampleFibersOutputSpec _cmd = " gtractResampleFibers " _outputs_filenames = {'outputTract': 'outputTract.vtk'} _redirect_x = False class gtractTensorInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image 4D NRRD image. Must contain data based on at least 6 distinct diffusion directions. The inputVolume is allowed to have multiple b0 and gradient direction images. Averaging of the b0 image is done internally in this step. Prior averaging of the DWIs is not required.", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: name of output NRRD file containing the Tensor vector image", argstr="--outputVolume %s") medianFilterSize = InputMultiPath(traits.Int, desc="Median filter radius in all 3 directions", sep=",", argstr="--medianFilterSize %s") maskProcessingMode = traits.Enum( "NOMASK", "ROIAUTO", "ROI", desc="ROIAUTO: mask is implicitly defined using a otsu forground and hole filling algorithm. ROI: Uses the masks to define what parts of the image should be used for computing the transform. NOMASK: no mask used", argstr="--maskProcessingMode %s") maskVolume = File(desc="Mask Image, if maskProcessingMode is ROI", exists=True, argstr="--maskVolume %s") backgroundSuppressingThreshold = traits.Int( desc="Image threshold to suppress background. This sets a threshold used on the b0 image to remove background voxels from processing. Typically, values of 100 and 500 work well for Siemens and GE DTI data, respectively. Check your data particularly in the globus pallidus to make sure the brain tissue is not being eliminated with this threshold.", argstr="--backgroundSuppressingThreshold %d") resampleIsotropic = traits.Bool(desc="Flag to resample to isotropic voxels. Enabling this feature is recommended if fiber tracking will be performed.", argstr="--resampleIsotropic ") size = traits.Float(desc="Isotropic voxel size to resample to", argstr="--size %f") b0Index = traits.Int(desc="Index in input vector index to extract", argstr="--b0Index %d") applyMeasurementFrame = traits.Bool(desc="Flag to apply the measurement frame to the gradient directions", argstr="--applyMeasurementFrame ") ignoreIndex = InputMultiPath(traits.Int, desc="Ignore diffusion gradient index. Used to remove specific gradient directions with artifacts.", sep=",", argstr="--ignoreIndex %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class gtractTensorOutputSpec(TraitedSpec): outputVolume = File(desc="Required: name of output NRRD file containing the Tensor vector image", exists=True) class gtractTensor(SEMLikeCommandLine): """title: Tensor Estimation category: Diffusion.GTRACT description: This step will convert a b-value averaged diffusion tensor image to a 3x3 tensor voxel image. This step takes the diffusion tensor image data and generates a tensor representation of the data based on the signal intensity decay, b values applied, and the diffusion difrections. The apparent diffusion coefficient for a given orientation is computed on a pixel-by-pixel basis by fitting the image data (voxel intensities) to the Stejskal-Tanner equation. If at least 6 diffusion directions are used, then the diffusion tensor can be computed. This program uses itk::DiffusionTensor3DReconstructionImageFilter. The user can adjust background threshold, median filter, and isotropic resampling. version: 4.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:GTRACT license: http://mri.radiology.uiowa.edu/copyright/GTRACT-Copyright.txt contributor: This tool was developed by Vincent Magnotta and Greg Harris. acknowledgements: Funding for this version of the GTRACT program was provided by NIH/NINDS R01NS050568-01A2S1 """ input_spec = gtractTensorInputSpec output_spec = gtractTensorOutputSpec _cmd = " gtractTensor " _outputs_filenames = {'outputVolume': 'outputVolume.nrrd'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/maxcurvature.py000066400000000000000000000045501257611314500254700ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class maxcurvatureInputSpec(CommandLineInputSpec): image = File(desc="FA Image", exists=True, argstr="--image %s") output = traits.Either(traits.Bool, File(), hash_files=False, desc="Output File", argstr="--output %s") sigma = traits.Float(desc="Scale of Gradients", argstr="--sigma %f") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") class maxcurvatureOutputSpec(TraitedSpec): output = File(desc="Output File", exists=True) class maxcurvature(SEMLikeCommandLine): """title: MaxCurvature-Hessian (DTIProcess) category: Diffusion description: This program computes the Hessian of the FA image (--image). We use this scalar image as a registration input when doing DTI atlas building. For most adult FA we use a sigma of 2 whereas for neonate or primate images and sigma of 1 or 1.5 is more appropriate. For really noisy images, 2.5 - 4 can be considered. The final image (--output) shows the main feature of the input image. version: 1.1.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); (1=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering) provided conversions to make DTIProcess compatible with Slicer execution, and simplified the stand-alone build requirements by removing the dependancies on boost and a fortran compiler. """ input_spec = maxcurvatureInputSpec output_spec = maxcurvatureOutputSpec _cmd = " maxcurvature " _outputs_filenames = {'output': 'output.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/000077500000000000000000000000001257611314500235265ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_DWIConvert.py000066400000000000000000000042141257611314500301540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.diffusion import DWIConvert def test_DWIConvert_inputs(): input_map = dict(args=dict(argstr='%s', ), conversionMode=dict(argstr='--conversionMode %s', ), environ=dict(nohash=True, usedefault=True, ), fMRI=dict(argstr='--fMRI ', ), fslNIFTIFile=dict(argstr='--fslNIFTIFile %s', ), gradientVectorFile=dict(argstr='--gradientVectorFile %s', hash_files=False, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBValues=dict(argstr='--inputBValues %s', ), inputBVectors=dict(argstr='--inputBVectors %s', ), inputDicomDirectory=dict(argstr='--inputDicomDirectory %s', ), inputVolume=dict(argstr='--inputVolume %s', ), outputBValues=dict(argstr='--outputBValues %s', hash_files=False, ), outputBVectors=dict(argstr='--outputBVectors %s', hash_files=False, ), outputDirectory=dict(argstr='--outputDirectory %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), smallGradientThreshold=dict(argstr='--smallGradientThreshold %f', ), terminal_output=dict(nohash=True, ), useBMatrixGradientDirections=dict(argstr='--useBMatrixGradientDirections ', ), useIdentityMeaseurementFrame=dict(argstr='--useIdentityMeaseurementFrame ', ), writeProtocolGradientsFile=dict(argstr='--writeProtocolGradientsFile ', ), ) inputs = DWIConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWIConvert_outputs(): output_map = dict(gradientVectorFile=dict(), outputBValues=dict(), outputBVectors=dict(), outputDirectory=dict(), outputVolume=dict(), ) outputs = DWIConvert.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_compareTractInclusion.py000066400000000000000000000026471257611314500325100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import compareTractInclusion def test_compareTractInclusion_inputs(): input_map = dict(args=dict(argstr='%s', ), closeness=dict(argstr='--closeness %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), numberOfPoints=dict(argstr='--numberOfPoints %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), standardFiber=dict(argstr='--standardFiber %s', ), terminal_output=dict(nohash=True, ), testFiber=dict(argstr='--testFiber %s', ), testForBijection=dict(argstr='--testForBijection ', ), testForFiberCardinality=dict(argstr='--testForFiberCardinality ', ), writeXMLPolyDataFile=dict(argstr='--writeXMLPolyDataFile ', ), ) inputs = compareTractInclusion.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_compareTractInclusion_outputs(): output_map = dict() outputs = compareTractInclusion.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_dtiaverage.py000066400000000000000000000021761257611314500303100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.diffusion import dtiaverage def test_dtiaverage_inputs(): input_map = dict(DTI_double=dict(argstr='--DTI_double ', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputs=dict(argstr='--inputs %s...', ), tensor_output=dict(argstr='--tensor_output %s', hash_files=False, ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = dtiaverage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_dtiaverage_outputs(): output_map = dict(tensor_output=dict(), ) outputs = dtiaverage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_dtiestim.py000066400000000000000000000037211257611314500300140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.diffusion import dtiestim def test_dtiestim_inputs(): input_map = dict(B0=dict(argstr='--B0 %s', hash_files=False, ), B0_mask_output=dict(argstr='--B0_mask_output %s', hash_files=False, ), DTI_double=dict(argstr='--DTI_double ', ), args=dict(argstr='%s', ), bad_region_mask=dict(argstr='--bad_region_mask %s', ), brain_mask=dict(argstr='--brain_mask %s', ), correction=dict(argstr='--correction %s', ), defaultTensor=dict(argstr='--defaultTensor %s', sep=',', ), dwi_image=dict(argstr='--dwi_image %s', ), environ=dict(nohash=True, usedefault=True, ), idwi=dict(argstr='--idwi %s', hash_files=False, ), ignore_exception=dict(nohash=True, usedefault=True, ), method=dict(argstr='--method %s', ), shiftNeg=dict(argstr='--shiftNeg ', ), shiftNegCoeff=dict(argstr='--shiftNegCoeff %f', ), sigma=dict(argstr='--sigma %f', ), step=dict(argstr='--step %f', ), tensor_output=dict(argstr='--tensor_output %s', hash_files=False, ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--threshold %d', ), verbose=dict(argstr='--verbose ', ), weight_iterations=dict(argstr='--weight_iterations %d', ), ) inputs = dtiestim.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_dtiestim_outputs(): output_map = dict(B0=dict(), B0_mask_output=dict(), idwi=dict(), tensor_output=dict(), ) outputs = dtiestim.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_dtiprocess.py000066400000000000000000000063711257611314500303550ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.diffusion import dtiprocess def test_dtiprocess_inputs(): input_map = dict(DTI_double=dict(argstr='--DTI_double ', ), RD_output=dict(argstr='--RD_output %s', hash_files=False, ), affineitk_file=dict(argstr='--affineitk_file %s', ), args=dict(argstr='%s', ), color_fa_output=dict(argstr='--color_fa_output %s', hash_files=False, ), correction=dict(argstr='--correction %s', ), deformation_output=dict(argstr='--deformation_output %s', hash_files=False, ), dof_file=dict(argstr='--dof_file %s', ), dti_image=dict(argstr='--dti_image %s', ), environ=dict(nohash=True, usedefault=True, ), fa_gradient_output=dict(argstr='--fa_gradient_output %s', hash_files=False, ), fa_gradmag_output=dict(argstr='--fa_gradmag_output %s', hash_files=False, ), fa_output=dict(argstr='--fa_output %s', hash_files=False, ), forward=dict(argstr='--forward %s', ), frobenius_norm_output=dict(argstr='--frobenius_norm_output %s', hash_files=False, ), hField=dict(argstr='--hField ', ), ignore_exception=dict(nohash=True, usedefault=True, ), interpolation=dict(argstr='--interpolation %s', ), lambda1_output=dict(argstr='--lambda1_output %s', hash_files=False, ), lambda2_output=dict(argstr='--lambda2_output %s', hash_files=False, ), lambda3_output=dict(argstr='--lambda3_output %s', hash_files=False, ), mask=dict(argstr='--mask %s', ), md_output=dict(argstr='--md_output %s', hash_files=False, ), negative_eigenvector_output=dict(argstr='--negative_eigenvector_output %s', hash_files=False, ), newdof_file=dict(argstr='--newdof_file %s', ), outmask=dict(argstr='--outmask %s', hash_files=False, ), principal_eigenvector_output=dict(argstr='--principal_eigenvector_output %s', hash_files=False, ), reorientation=dict(argstr='--reorientation %s', ), rot_output=dict(argstr='--rot_output %s', hash_files=False, ), scalar_float=dict(argstr='--scalar_float ', ), sigma=dict(argstr='--sigma %f', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = dtiprocess.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_dtiprocess_outputs(): output_map = dict(RD_output=dict(), color_fa_output=dict(), deformation_output=dict(), fa_gradient_output=dict(), fa_gradmag_output=dict(), fa_output=dict(), frobenius_norm_output=dict(), lambda1_output=dict(), lambda2_output=dict(), lambda3_output=dict(), md_output=dict(), negative_eigenvector_output=dict(), outmask=dict(), principal_eigenvector_output=dict(), rot_output=dict(), ) outputs = dtiprocess.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_extractNrrdVectorIndex.py000066400000000000000000000024301257611314500326410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import extractNrrdVectorIndex def test_extractNrrdVectorIndex_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), setImageOrientation=dict(argstr='--setImageOrientation %s', ), terminal_output=dict(nohash=True, ), vectorIndex=dict(argstr='--vectorIndex %d', ), ) inputs = extractNrrdVectorIndex.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_extractNrrdVectorIndex_outputs(): output_map = dict(outputVolume=dict(), ) outputs = extractNrrdVectorIndex.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractAnisotropyMap.py000066400000000000000000000023241257611314500322020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractAnisotropyMap def test_gtractAnisotropyMap_inputs(): input_map = dict(anisotropyType=dict(argstr='--anisotropyType %s', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTensorVolume=dict(argstr='--inputTensorVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractAnisotropyMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractAnisotropyMap_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractAnisotropyMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractAverageBvalues.py000066400000000000000000000024201257611314500322660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractAverageBvalues def test_gtractAverageBvalues_inputs(): input_map = dict(args=dict(argstr='%s', ), averageB0only=dict(argstr='--averageB0only ', ), directionsTolerance=dict(argstr='--directionsTolerance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractAverageBvalues.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractAverageBvalues_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractAverageBvalues.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractClipAnisotropy.py000066400000000000000000000024041257611314500323530ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractClipAnisotropy def test_gtractClipAnisotropy_inputs(): input_map = dict(args=dict(argstr='%s', ), clipFirstSlice=dict(argstr='--clipFirstSlice ', ), clipLastSlice=dict(argstr='--clipLastSlice ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractClipAnisotropy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractClipAnisotropy_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractClipAnisotropy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractCoRegAnatomy.py000066400000000000000000000047511257611314500317330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractCoRegAnatomy def test_gtractCoRegAnatomy_inputs(): input_map = dict(args=dict(argstr='%s', ), borderSize=dict(argstr='--borderSize %d', ), convergence=dict(argstr='--convergence %f', ), environ=dict(nohash=True, usedefault=True, ), gradientTolerance=dict(argstr='--gradientTolerance %f', ), gridSize=dict(argstr='--gridSize %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnatomicalVolume=dict(argstr='--inputAnatomicalVolume %s', ), inputRigidTransform=dict(argstr='--inputRigidTransform %s', ), inputVolume=dict(argstr='--inputVolume %s', ), maxBSplineDisplacement=dict(argstr='--maxBSplineDisplacement %f', ), maximumStepSize=dict(argstr='--maximumStepSize %f', ), minimumStepSize=dict(argstr='--minimumStepSize %f', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfIterations=dict(argstr='--numberOfIterations %d', ), numberOfSamples=dict(argstr='--numberOfSamples %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTransformName=dict(argstr='--outputTransformName %s', hash_files=False, ), relaxationFactor=dict(argstr='--relaxationFactor %f', ), samplingPercentage=dict(argstr='--samplingPercentage %f', ), spatialScale=dict(argstr='--spatialScale %d', ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), translationScale=dict(argstr='--translationScale %f', ), useCenterOfHeadAlign=dict(argstr='--useCenterOfHeadAlign ', ), useGeometryAlign=dict(argstr='--useGeometryAlign ', ), useMomentsAlign=dict(argstr='--useMomentsAlign ', ), vectorIndex=dict(argstr='--vectorIndex %d', ), ) inputs = gtractCoRegAnatomy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractCoRegAnatomy_outputs(): output_map = dict(outputTransformName=dict(), ) outputs = gtractCoRegAnatomy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractConcatDwi.py000066400000000000000000000022631257611314500312520ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractConcatDwi def test_gtractConcatDwi_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignoreOrigins=dict(argstr='--ignoreOrigins ', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s...', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractConcatDwi.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractConcatDwi_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractConcatDwi.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractCopyImageOrientation.py000066400000000000000000000023671257611314500334750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractCopyImageOrientation def test_gtractCopyImageOrientation_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractCopyImageOrientation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractCopyImageOrientation_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractCopyImageOrientation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractCoregBvalues.py000066400000000000000000000037711257611314500317650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractCoregBvalues def test_gtractCoregBvalues_inputs(): input_map = dict(args=dict(argstr='%s', ), debugLevel=dict(argstr='--debugLevel %d', ), eddyCurrentCorrection=dict(argstr='--eddyCurrentCorrection ', ), environ=dict(nohash=True, usedefault=True, ), fixedVolume=dict(argstr='--fixedVolume %s', ), fixedVolumeIndex=dict(argstr='--fixedVolumeIndex %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), maximumStepSize=dict(argstr='--maximumStepSize %f', ), minimumStepSize=dict(argstr='--minimumStepSize %f', ), movingVolume=dict(argstr='--movingVolume %s', ), numberOfIterations=dict(argstr='--numberOfIterations %d', ), numberOfSpatialSamples=dict(argstr='--numberOfSpatialSamples %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), registerB0Only=dict(argstr='--registerB0Only ', ), relaxationFactor=dict(argstr='--relaxationFactor %f', ), samplingPercentage=dict(argstr='--samplingPercentage %f', ), spatialScale=dict(argstr='--spatialScale %f', ), terminal_output=dict(nohash=True, ), ) inputs = gtractCoregBvalues.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractCoregBvalues_outputs(): output_map = dict(outputTransform=dict(), outputVolume=dict(), ) outputs = gtractCoregBvalues.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractCostFastMarching.py000066400000000000000000000033211257611314500325720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractCostFastMarching def test_gtractCostFastMarching_inputs(): input_map = dict(anisotropyWeight=dict(argstr='--anisotropyWeight %f', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnisotropyVolume=dict(argstr='--inputAnisotropyVolume %s', ), inputStartingSeedsLabelMapVolume=dict(argstr='--inputStartingSeedsLabelMapVolume %s', ), inputTensorVolume=dict(argstr='--inputTensorVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputCostVolume=dict(argstr='--outputCostVolume %s', hash_files=False, ), outputSpeedVolume=dict(argstr='--outputSpeedVolume %s', hash_files=False, ), seedThreshold=dict(argstr='--seedThreshold %f', ), startingSeedsLabel=dict(argstr='--startingSeedsLabel %d', ), stoppingValue=dict(argstr='--stoppingValue %f', ), terminal_output=dict(nohash=True, ), ) inputs = gtractCostFastMarching.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractCostFastMarching_outputs(): output_map = dict(outputCostVolume=dict(), outputSpeedVolume=dict(), ) outputs = gtractCostFastMarching.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractCreateGuideFiber.py000066400000000000000000000024311257611314500325250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractCreateGuideFiber def test_gtractCreateGuideFiber_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputFiber=dict(argstr='--inputFiber %s', ), numberOfPoints=dict(argstr='--numberOfPoints %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputFiber=dict(argstr='--outputFiber %s', hash_files=False, ), terminal_output=dict(nohash=True, ), writeXMLPolyDataFile=dict(argstr='--writeXMLPolyDataFile ', ), ) inputs = gtractCreateGuideFiber.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractCreateGuideFiber_outputs(): output_map = dict(outputFiber=dict(), ) outputs = gtractCreateGuideFiber.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractFastMarchingTracking.py000066400000000000000000000036501257611314500334310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractFastMarchingTracking def test_gtractFastMarchingTracking_inputs(): input_map = dict(args=dict(argstr='%s', ), costStepSize=dict(argstr='--costStepSize %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnisotropyVolume=dict(argstr='--inputAnisotropyVolume %s', ), inputCostVolume=dict(argstr='--inputCostVolume %s', ), inputStartingSeedsLabelMapVolume=dict(argstr='--inputStartingSeedsLabelMapVolume %s', ), inputTensorVolume=dict(argstr='--inputTensorVolume %s', ), maximumStepSize=dict(argstr='--maximumStepSize %f', ), minimumStepSize=dict(argstr='--minimumStepSize %f', ), numberOfIterations=dict(argstr='--numberOfIterations %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTract=dict(argstr='--outputTract %s', hash_files=False, ), seedThreshold=dict(argstr='--seedThreshold %f', ), startingSeedsLabel=dict(argstr='--startingSeedsLabel %d', ), terminal_output=dict(nohash=True, ), trackingThreshold=dict(argstr='--trackingThreshold %f', ), writeXMLPolyDataFile=dict(argstr='--writeXMLPolyDataFile ', ), ) inputs = gtractFastMarchingTracking.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractFastMarchingTracking_outputs(): output_map = dict(outputTract=dict(), ) outputs = gtractFastMarchingTracking.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractFiberTracking.py000066400000000000000000000053311257611314500321100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractFiberTracking def test_gtractFiberTracking_inputs(): input_map = dict(args=dict(argstr='%s', ), branchingAngle=dict(argstr='--branchingAngle %f', ), branchingThreshold=dict(argstr='--branchingThreshold %f', ), curvatureThreshold=dict(argstr='--curvatureThreshold %f', ), endingSeedsLabel=dict(argstr='--endingSeedsLabel %d', ), environ=dict(nohash=True, usedefault=True, ), guidedCurvatureThreshold=dict(argstr='--guidedCurvatureThreshold %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnisotropyVolume=dict(argstr='--inputAnisotropyVolume %s', ), inputEndingSeedsLabelMapVolume=dict(argstr='--inputEndingSeedsLabelMapVolume %s', ), inputStartingSeedsLabelMapVolume=dict(argstr='--inputStartingSeedsLabelMapVolume %s', ), inputTensorVolume=dict(argstr='--inputTensorVolume %s', ), inputTract=dict(argstr='--inputTract %s', ), maximumBranchPoints=dict(argstr='--maximumBranchPoints %d', ), maximumGuideDistance=dict(argstr='--maximumGuideDistance %f', ), maximumLength=dict(argstr='--maximumLength %f', ), minimumLength=dict(argstr='--minimumLength %f', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTract=dict(argstr='--outputTract %s', hash_files=False, ), randomSeed=dict(argstr='--randomSeed %d', ), seedThreshold=dict(argstr='--seedThreshold %f', ), startingSeedsLabel=dict(argstr='--startingSeedsLabel %d', ), stepSize=dict(argstr='--stepSize %f', ), tendF=dict(argstr='--tendF %f', ), tendG=dict(argstr='--tendG %f', ), terminal_output=dict(nohash=True, ), trackingMethod=dict(argstr='--trackingMethod %s', ), trackingThreshold=dict(argstr='--trackingThreshold %f', ), useLoopDetection=dict(argstr='--useLoopDetection ', ), useRandomWalk=dict(argstr='--useRandomWalk ', ), useTend=dict(argstr='--useTend ', ), writeXMLPolyDataFile=dict(argstr='--writeXMLPolyDataFile ', ), ) inputs = gtractFiberTracking.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractFiberTracking_outputs(): output_map = dict(outputTract=dict(), ) outputs = gtractFiberTracking.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractImageConformity.py000066400000000000000000000023361257611314500324740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractImageConformity def test_gtractImageConformity_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractImageConformity.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractImageConformity_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractImageConformity.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractInvertBSplineTransform.py000066400000000000000000000025341257611314500340200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractInvertBSplineTransform def test_gtractInvertBSplineTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), inputTransform=dict(argstr='--inputTransform %s', ), landmarkDensity=dict(argstr='--landmarkDensity %s', sep=',', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractInvertBSplineTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractInvertBSplineTransform_outputs(): output_map = dict(outputTransform=dict(), ) outputs = gtractInvertBSplineTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractInvertDisplacementField.py000066400000000000000000000024751257611314500341500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractInvertDisplacementField def test_gtractInvertDisplacementField_inputs(): input_map = dict(args=dict(argstr='%s', ), baseImage=dict(argstr='--baseImage %s', ), deformationImage=dict(argstr='--deformationImage %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), subsamplingFactor=dict(argstr='--subsamplingFactor %d', ), terminal_output=dict(nohash=True, ), ) inputs = gtractInvertDisplacementField.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractInvertDisplacementField_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractInvertDisplacementField.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractInvertRigidTransform.py000066400000000000000000000022751257611314500335240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractInvertRigidTransform def test_gtractInvertRigidTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTransform=dict(argstr='--inputTransform %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractInvertRigidTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractInvertRigidTransform_outputs(): output_map = dict(outputTransform=dict(), ) outputs = gtractInvertRigidTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractResampleAnisotropy.py000066400000000000000000000025731257611314500332430ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractResampleAnisotropy def test_gtractResampleAnisotropy_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnatomicalVolume=dict(argstr='--inputAnatomicalVolume %s', ), inputAnisotropyVolume=dict(argstr='--inputAnisotropyVolume %s', ), inputTransform=dict(argstr='--inputTransform %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), ) inputs = gtractResampleAnisotropy.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractResampleAnisotropy_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractResampleAnisotropy.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractResampleB0.py000066400000000000000000000025661257611314500313370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractResampleB0 def test_gtractResampleB0_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputAnatomicalVolume=dict(argstr='--inputAnatomicalVolume %s', ), inputTransform=dict(argstr='--inputTransform %s', ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), vectorIndex=dict(argstr='--vectorIndex %d', ), ) inputs = gtractResampleB0.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractResampleB0_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractResampleB0.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractResampleCodeImage.py000066400000000000000000000025501257611314500327040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractResampleCodeImage def test_gtractResampleCodeImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputCodeVolume=dict(argstr='--inputCodeVolume %s', ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), inputTransform=dict(argstr='--inputTransform %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), ) inputs = gtractResampleCodeImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractResampleCodeImage_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractResampleCodeImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractResampleDWIInPlace.py000066400000000000000000000031311257611314500327420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractResampleDWIInPlace def test_gtractResampleDWIInPlace_inputs(): input_map = dict(args=dict(argstr='%s', ), debugLevel=dict(argstr='--debugLevel %d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), imageOutputSize=dict(argstr='--imageOutputSize %s', sep=',', ), inputTransform=dict(argstr='--inputTransform %s', ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputResampledB0=dict(argstr='--outputResampledB0 %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), referenceVolume=dict(argstr='--referenceVolume %s', ), terminal_output=dict(nohash=True, ), warpDWITransform=dict(argstr='--warpDWITransform %s', ), ) inputs = gtractResampleDWIInPlace.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractResampleDWIInPlace_outputs(): output_map = dict(outputResampledB0=dict(), outputVolume=dict(), ) outputs = gtractResampleDWIInPlace.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractResampleFibers.py000066400000000000000000000026341257611314500323040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractResampleFibers def test_gtractResampleFibers_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputForwardDeformationFieldVolume=dict(argstr='--inputForwardDeformationFieldVolume %s', ), inputReverseDeformationFieldVolume=dict(argstr='--inputReverseDeformationFieldVolume %s', ), inputTract=dict(argstr='--inputTract %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputTract=dict(argstr='--outputTract %s', hash_files=False, ), terminal_output=dict(nohash=True, ), writeXMLPolyDataFile=dict(argstr='--writeXMLPolyDataFile ', ), ) inputs = gtractResampleFibers.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractResampleFibers_outputs(): output_map = dict(outputTract=dict(), ) outputs = gtractResampleFibers.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_gtractTensor.py000066400000000000000000000032631257611314500306520ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractTensor def test_gtractTensor_inputs(): input_map = dict(applyMeasurementFrame=dict(argstr='--applyMeasurementFrame ', ), args=dict(argstr='%s', ), b0Index=dict(argstr='--b0Index %d', ), backgroundSuppressingThreshold=dict(argstr='--backgroundSuppressingThreshold %d', ), environ=dict(nohash=True, usedefault=True, ), ignoreIndex=dict(argstr='--ignoreIndex %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), maskProcessingMode=dict(argstr='--maskProcessingMode %s', ), maskVolume=dict(argstr='--maskVolume %s', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), resampleIsotropic=dict(argstr='--resampleIsotropic ', ), size=dict(argstr='--size %f', ), terminal_output=dict(nohash=True, ), ) inputs = gtractTensor.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractTensor_outputs(): output_map = dict(outputVolume=dict(), ) outputs = gtractTensor.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_gtractTransformToDisplacementField.py000066400000000000000000000025251257611314500350740ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.gtract import gtractTransformToDisplacementField def test_gtractTransformToDisplacementField_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), inputTransform=dict(argstr='--inputTransform %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputDeformationFieldVolume=dict(argstr='--outputDeformationFieldVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = gtractTransformToDisplacementField.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_gtractTransformToDisplacementField_outputs(): output_map = dict(outputDeformationFieldVolume=dict(), ) outputs = gtractTransformToDisplacementField.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tests/test_auto_maxcurvature.py000066400000000000000000000021511257611314500307140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.maxcurvature import maxcurvature def test_maxcurvature_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image=dict(argstr='--image %s', ), output=dict(argstr='--output %s', hash_files=False, ), sigma=dict(argstr='--sigma %f', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = maxcurvature.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_maxcurvature_outputs(): output_map = dict(output=dict(), ) outputs = maxcurvature.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/000077500000000000000000000000001257611314500250735ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/__init__.py000066400000000000000000000002331257611314500272020ustar00rootroot00000000000000from commandlineonly import fiberstats from fiberprocess import fiberprocess from fibertrack import fibertrack from ukftractography import UKFTractography nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/commandlineonly.py000066400000000000000000000034551257611314500306440ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class fiberstatsInputSpec(CommandLineInputSpec): fiber_file = File(desc="DTI Fiber File", exists=True, argstr="--fiber_file %s") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") class fiberstatsOutputSpec(TraitedSpec): pass class fiberstats(SEMLikeCommandLine): """title: FiberStats (DTIProcess) category: Diffusion.Tractography.CommandLineOnly description: Obsolete tool - Not used anymore version: 1.1.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); (1=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering) provided conversions to make DTIProcess compatible with Slicer execution, and simplified the stand-alone build requirements by removing the dependancies on boost and a fortran compiler. """ input_spec = fiberstatsInputSpec output_spec = fiberstatsOutputSpec _cmd = " fiberstats " _outputs_filenames = {} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/fiberprocess.py000066400000000000000000000132421257611314500301350ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class fiberprocessInputSpec(CommandLineInputSpec): fiber_file = File(desc="DTI fiber file", exists=True, argstr="--fiber_file %s") fiber_output = traits.Either(traits.Bool, File(), hash_files=False, desc="Output fiber file. May be warped or updated with new data depending on other options used.", argstr="--fiber_output %s") tensor_volume = File(desc="Interpolate tensor values from the given field", exists=True, argstr="--tensor_volume %s") h_field = File(desc="HField for warp and statistics lookup. If this option is used tensor-volume must also be specified.", exists=True, argstr="--h_field %s") displacement_field = File(desc="Displacement Field for warp and statistics lookup. If this option is used tensor-volume must also be specified.", exists=True, argstr="--displacement_field %s") saveProperties = traits.Bool(desc="save the tensor property as scalar data into the vtk (only works for vtk fiber files). ", argstr="--saveProperties ") no_warp = traits.Bool(desc="Do not warp the geometry of the tensors only obtain the new statistics.", argstr="--no_warp ") fiber_radius = traits.Float(desc="set radius of all fibers to this value", argstr="--fiber_radius %f") index_space = traits.Bool(desc="Use index-space for fiber output coordinates, otherwise us world space for fiber output coordinates (from tensor file).", argstr="--index_space ") voxelize = traits.Either(traits.Bool, File(), hash_files=False, desc="Voxelize fiber into a label map (the labelmap filename is the argument of -V). The tensor file must be specified using -T for information about the size, origin, spacing of the image. The deformation is applied before the voxelization ", argstr="--voxelize %s") voxelize_count_fibers = traits.Bool(desc="Count number of fibers per-voxel instead of just setting to 1", argstr="--voxelize_count_fibers ") voxel_label = traits.Int(desc="Label for voxelized fiber", argstr="--voxel_label %d") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") noDataChange = traits.Bool(desc="Do not change data ??? ", argstr="--noDataChange ") class fiberprocessOutputSpec(TraitedSpec): fiber_output = File(desc="Output fiber file. May be warped or updated with new data depending on other options used.", exists=True) voxelize = File(desc="Voxelize fiber into a label map (the labelmap filename is the argument of -V). The tensor file must be specified using -T for information about the size, origin, spacing of the image. The deformation is applied before the voxelization ", exists=True) class fiberprocess(SEMLikeCommandLine): """title: FiberProcess (DTIProcess) category: Diffusion.Tractography description: fiberprocess is a tool that manage fiber files extracted from the fibertrack tool or any fiber tracking algorithm. It takes as an input .fib and .vtk files (--fiber_file) and saves the changed fibers (--fiber_output) into the 2 same formats. The main purpose of this tool is to deform the fiber file with a transformation field as an input (--displacement_field or --h_field depending if you deal with dfield or hfield). To use that option you need to specify the tensor field from which the fiber file was extracted with the option --tensor_volume. The transformation applied on the fiber file is the inverse of the one input. If the transformation is from one case to an atlas, fiberprocess assumes that the fiber file is in the atlas space and you want it in the original case space, so it's the inverse of the transformation which has been computed. You have 2 options for fiber modification. You can either deform the fibers (their geometry) into the space OR you can keep the same geometry but map the diffusion properties (fa, md, lbd's...) of the original tensor field along the fibers at the corresponding locations. This is triggered by the --no_warp option. To use the previous example: when you have a tensor field in the original space and the deformed tensor field in the atlas space, you want to track the fibers in the atlas space, keeping this geometry but with the original case diffusion properties. Then you can specify the transformations field (from original case -> atlas) and the original tensor field with the --tensor_volume option. With fiberprocess you can also binarize a fiber file. Using the --voxelize option will create an image where each voxel through which a fiber is passing is set to 1. The output is going to be a binary image with the values 0 or 1 by default but the 1 value voxel can be set to any number with the --voxel_label option. Finally you can create an image where the value at the voxel is the number of fiber passing through. (--voxelize_count_fibers) version: 1.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett """ input_spec = fiberprocessInputSpec output_spec = fiberprocessOutputSpec _cmd = " fiberprocess " _outputs_filenames = {'fiber_output': 'fiber_output.vtk', 'voxelize': 'voxelize.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/fibertrack.py000066400000000000000000000121731257611314500275650ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class fibertrackInputSpec(CommandLineInputSpec): input_tensor_file = File(desc="Tensor Image", exists=True, argstr="--input_tensor_file %s") input_roi_file = File(desc="The filename of the image which contains the labels used for seeding and constraining the algorithm.", exists=True, argstr="--input_roi_file %s") output_fiber_file = traits.Either(traits.Bool, File(), hash_files=False, desc="The filename for the fiber file produced by the algorithm. This file must end in a .fib or .vtk extension for ITK spatial object and vtkPolyData formats respectively.", argstr="--output_fiber_file %s") source_label = traits.Int(desc="The label of voxels in the labelfile to use for seeding tractography. One tract is seeded from the center of each voxel with this label", argstr="--source_label %d") target_label = traits.Int(desc="The label of voxels in the labelfile used to constrain tractography. Tracts that do not pass through a voxel with this label are rejected. Set this keep all tracts.", argstr="--target_label %d") forbidden_label = traits.Int(desc="Forbidden label", argstr="--forbidden_label %d") whole_brain = traits.Bool(desc="If this option is enabled all voxels in the image are used to seed tractography. When this option is enabled both source and target labels function as target labels", argstr="--whole_brain ") max_angle = traits.Float(desc="Maximum angle of change in radians", argstr="--max_angle %f") step_size = traits.Float(desc="Step size in mm for the tracking algorithm", argstr="--step_size %f") min_fa = traits.Float(desc="The minimum FA threshold to continue tractography", argstr="--min_fa %f") force = traits.Bool(desc="Ignore sanity checks.", argstr="--force ") verbose = traits.Bool(desc="produce verbose output", argstr="--verbose ") really_verbose = traits.Bool(desc="Follow detail of fiber tracking algorithm", argstr="--really_verbose ") class fibertrackOutputSpec(TraitedSpec): output_fiber_file = File(desc="The filename for the fiber file produced by the algorithm. This file must end in a .fib or .vtk extension for ITK spatial object and vtkPolyData formats respectively.", exists=True) class fibertrack(SEMLikeCommandLine): """title: FiberTrack (DTIProcess) category: Diffusion.Tractography description: This program implements a simple streamline tractography method based on the principal eigenvector of the tensor field. A fourth order Runge-Kutta integration rule used to advance the streamlines. As a first parameter you have to input the tensor field (with the --input_tensor_file option). Then the region of interest image file is set with the --input_roi_file. Next you want to set the output fiber file name after the --output_fiber_file option. You can specify the label value in the input_roi_file with the --target_label, --source_label and --fobidden_label options. By default target label is 1, source label is 2 and forbidden label is 0. The source label is where the streamlines are seeded, the target label defines the voxels through which the fibers must pass by to be kept in the final fiber file and the forbidden label defines the voxels where the streamlines are stopped if they pass through it. There is also a --whole_brain option which, if enabled, consider both target and source labels of the roi image as target labels and all the voxels of the image are considered as sources. During the tractography, the --fa_min parameter is used as the minimum value needed at different voxel for the tracking to keep going along a streamline. The --step_size parameter is used for each iteration of the tracking algorithm and defines the length of each step. The --max_angle option defines the maximum angle allowed between two successive segments along the tracked fiber. version: 1.1.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); (1=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering) provided conversions to make DTIProcess compatible with Slicer execution, and simplified the stand-alone build requirements by removing the dependancies on boost and a fortran compiler. """ input_spec = fibertrackInputSpec output_spec = fibertrackOutputSpec _cmd = " fibertrack " _outputs_filenames = {'output_fiber_file': 'output_fiber_file.vtk'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/tests/000077500000000000000000000000001257611314500262355ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/tests/test_auto_UKFTractography.py000066400000000000000000000054051257611314500337170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.tractography.ukftractography import UKFTractography def test_UKFTractography_inputs(): input_map = dict(Ql=dict(argstr='--Ql %f', ), Qm=dict(argstr='--Qm %f', ), Qw=dict(argstr='--Qw %f', ), Rs=dict(argstr='--Rs %f', ), args=dict(argstr='%s', ), dwiFile=dict(argstr='--dwiFile %s', ), environ=dict(nohash=True, usedefault=True, ), freeWater=dict(argstr='--freeWater ', ), fullTensorModel=dict(argstr='--fullTensorModel ', ), ignore_exception=dict(nohash=True, usedefault=True, ), labels=dict(argstr='--labels %s', sep=',', ), maskFile=dict(argstr='--maskFile %s', ), maxBranchingAngle=dict(argstr='--maxBranchingAngle %f', ), maxHalfFiberLength=dict(argstr='--maxHalfFiberLength %f', ), minBranchingAngle=dict(argstr='--minBranchingAngle %f', ), minFA=dict(argstr='--minFA %f', ), minGA=dict(argstr='--minGA %f', ), numTensor=dict(argstr='--numTensor %s', ), numThreads=dict(argstr='--numThreads %d', ), recordCovariance=dict(argstr='--recordCovariance ', ), recordFA=dict(argstr='--recordFA ', ), recordFreeWater=dict(argstr='--recordFreeWater ', ), recordLength=dict(argstr='--recordLength %f', ), recordNMSE=dict(argstr='--recordNMSE ', ), recordState=dict(argstr='--recordState ', ), recordTensors=dict(argstr='--recordTensors ', ), recordTrace=dict(argstr='--recordTrace ', ), seedFALimit=dict(argstr='--seedFALimit %f', ), seedsFile=dict(argstr='--seedsFile %s', ), seedsPerVoxel=dict(argstr='--seedsPerVoxel %d', ), stepLength=dict(argstr='--stepLength %f', ), storeGlyphs=dict(argstr='--storeGlyphs ', ), terminal_output=dict(nohash=True, ), tracts=dict(argstr='--tracts %s', hash_files=False, ), tractsWithSecondTensor=dict(argstr='--tractsWithSecondTensor %s', hash_files=False, ), writeAsciiTracts=dict(argstr='--writeAsciiTracts ', ), writeUncompressedTracts=dict(argstr='--writeUncompressedTracts ', ), ) inputs = UKFTractography.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_UKFTractography_outputs(): output_map = dict(tracts=dict(), tractsWithSecondTensor=dict(), ) outputs = UKFTractography.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/tests/test_auto_fiberprocess.py000066400000000000000000000033771257611314500333760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.tractography.fiberprocess import fiberprocess def test_fiberprocess_inputs(): input_map = dict(args=dict(argstr='%s', ), displacement_field=dict(argstr='--displacement_field %s', ), environ=dict(nohash=True, usedefault=True, ), fiber_file=dict(argstr='--fiber_file %s', ), fiber_output=dict(argstr='--fiber_output %s', hash_files=False, ), fiber_radius=dict(argstr='--fiber_radius %f', ), h_field=dict(argstr='--h_field %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), index_space=dict(argstr='--index_space ', ), noDataChange=dict(argstr='--noDataChange ', ), no_warp=dict(argstr='--no_warp ', ), saveProperties=dict(argstr='--saveProperties ', ), tensor_volume=dict(argstr='--tensor_volume %s', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), voxel_label=dict(argstr='--voxel_label %d', ), voxelize=dict(argstr='--voxelize %s', hash_files=False, ), voxelize_count_fibers=dict(argstr='--voxelize_count_fibers ', ), ) inputs = fiberprocess.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_fiberprocess_outputs(): output_map = dict(fiber_output=dict(), voxelize=dict(), ) outputs = fiberprocess.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/tests/test_auto_fiberstats.py000066400000000000000000000017701257611314500330510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.tractography.commandlineonly import fiberstats def test_fiberstats_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fiber_file=dict(argstr='--fiber_file %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = fiberstats.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_fiberstats_outputs(): output_map = dict() outputs = fiberstats.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/tests/test_auto_fibertrack.py000066400000000000000000000032221257611314500330110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.diffusion.tractography.fibertrack import fibertrack def test_fibertrack_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), forbidden_label=dict(argstr='--forbidden_label %d', ), force=dict(argstr='--force ', ), ignore_exception=dict(nohash=True, usedefault=True, ), input_roi_file=dict(argstr='--input_roi_file %s', ), input_tensor_file=dict(argstr='--input_tensor_file %s', ), max_angle=dict(argstr='--max_angle %f', ), min_fa=dict(argstr='--min_fa %f', ), output_fiber_file=dict(argstr='--output_fiber_file %s', hash_files=False, ), really_verbose=dict(argstr='--really_verbose ', ), source_label=dict(argstr='--source_label %d', ), step_size=dict(argstr='--step_size %f', ), target_label=dict(argstr='--target_label %d', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), whole_brain=dict(argstr='--whole_brain ', ), ) inputs = fibertrack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_fibertrack_outputs(): output_map = dict(output_fiber_file=dict(), ) outputs = fibertrack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/diffusion/tractography/ukftractography.py000066400000000000000000000153561257611314500306740ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class UKFTractographyInputSpec(CommandLineInputSpec): dwiFile = File(desc="Input DWI volume", exists=True, argstr="--dwiFile %s") seedsFile = File(desc="Seeds for diffusion. If not specified, full brain tractography will be performed, and the algorithm will start from every voxel in the brain mask where the Generalized Anisotropy is bigger than 0.18", exists=True, argstr="--seedsFile %s") labels = InputMultiPath(traits.Int, desc="A vector of the ROI labels to be used", sep=",", argstr="--labels %s") maskFile = File(desc="Mask for diffusion tractography", exists=True, argstr="--maskFile %s") tracts = traits.Either(traits.Bool, File(), hash_files=False, desc="Tracts generated, with first tensor output", argstr="--tracts %s") writeAsciiTracts = traits.Bool(desc="Write tract file as a VTK binary data file", argstr="--writeAsciiTracts ") writeUncompressedTracts = traits.Bool(desc="Write tract file as a VTK uncompressed data file", argstr="--writeUncompressedTracts ") seedsPerVoxel = traits.Int(desc=" Each seed generates a fiber, thus using more seeds generates more fibers. In general use 1 or 2 seeds, and for a more thorough result use 5 or 10 (depending on your machine this may take up to 2 days to run)., ", argstr="--seedsPerVoxel %d") numTensor = traits.Enum("1", "2", desc="Number of tensors used", argstr="--numTensor %s") freeWater = traits.Bool(desc="Adds a term for free water difusion to the model. (Note for experts: if checked, the 1T simple model is forced) ", argstr="--freeWater ") recordFA = traits.Bool(desc="Whether to store FA. Attaches field 'FA', and 'FA2' for 2-tensor case to fiber. ", argstr="--recordFA ") recordFreeWater = traits.Bool(desc="Whether to store the fraction of free water. Attaches field 'FreeWater' to fiber.", argstr="--recordFreeWater ") recordTrace = traits.Bool(desc="Whether to store Trace. Attaches field 'Trace', and 'Trace2' for 2-tensor case to fiber.", argstr="--recordTrace ") recordTensors = traits.Bool(desc="Recording the tensors enables Slicer to color the fiber bundles by FA, orientation, and so on. The fields will be called 'TensorN', where N is the tensor number. ", argstr="--recordTensors ") recordNMSE = traits.Bool(desc="Whether to store NMSE. Attaches field 'NMSE' to fiber. ", argstr="--recordNMSE ") recordState = traits.Bool(desc="Whether to attach the states to the fiber. Will generate field 'state'.", argstr="--recordState ") recordCovariance = traits.Bool(desc="Whether to store the covariance. Will generate field 'covariance' in fiber.", argstr="--recordCovariance ") recordLength = traits.Float(desc="Record length of tractography, in millimeters", argstr="--recordLength %f") minFA = traits.Float(desc="Abort the tractography when the Fractional Anisotropy is less than this value", argstr="--minFA %f") minGA = traits.Float(desc="Abort the tractography when the Generalized Anisotropy is less than this value", argstr="--minGA %f") fullTensorModel = traits.Bool(desc="Whether to use the full tensor model. If unchecked, use the default simple tensor model", argstr="--fullTensorModel ") numThreads = traits.Int(desc="Number of threads used during computation. Set to the number of cores on your workstation for optimal speed. If left undefined the number of cores detected will be used. ", argstr="--numThreads %d") stepLength = traits.Float(desc="Step length of tractography, in millimeters", argstr="--stepLength %f") maxHalfFiberLength = traits.Float(desc="The max length limit of the half fibers generated during tractography. Here the fiber is \'half\' because the tractography goes in only one direction from one seed point at a time", argstr="--maxHalfFiberLength %f") seedFALimit = traits.Float(desc="Seed points whose FA are below this value are excluded", argstr="--seedFALimit %f") Qm = traits.Float(desc="Process noise for angles/direction", argstr="--Qm %f") Ql = traits.Float(desc="Process noise for eigenvalues", argstr="--Ql %f") Qw = traits.Float(desc="Process noise for free water weights, ignored if no free water estimation", argstr="--Qw %f") Rs = traits.Float(desc="Measurement noise", argstr="--Rs %f") maxBranchingAngle = traits.Float( desc="Maximum branching angle, in degrees. When using multiple tensors, a new branch will be created when the tensors' major directions form an angle between (minBranchingAngle, maxBranchingAngle). Branching is supressed when this maxBranchingAngle is set to 0.0", argstr="--maxBranchingAngle %f") minBranchingAngle = traits.Float(desc="Minimum branching angle, in degrees. When using multiple tensors, a new branch will be created when the tensors' major directions form an angle between (minBranchingAngle, maxBranchingAngle)", argstr="--minBranchingAngle %f") tractsWithSecondTensor = traits.Either(traits.Bool, File(), hash_files=False, desc="Tracts generated, with second tensor output (if there is one)", argstr="--tractsWithSecondTensor %s") storeGlyphs = traits.Bool(desc="Store tensors' main directions as two-point lines in a separate file named glyphs_{tracts}. When using multiple tensors, only the major tensors' main directions are stored", argstr="--storeGlyphs ") class UKFTractographyOutputSpec(TraitedSpec): tracts = File(desc="Tracts generated, with first tensor output", exists=True) tractsWithSecondTensor = File(desc="Tracts generated, with second tensor output (if there is one)", exists=True) class UKFTractography(SEMLikeCommandLine): """title: UKF Tractography category: Diffusion.Tractography description: This module traces fibers in a DWI Volume using the multiple tensor unscented Kalman Filter methology. For more informations check the documentation. version: 1.0 documentation-url: http://www.nitrc.org/plugins/mwiki/index.php/ukftractography:MainPage contributor: Yogesh Rathi, Stefan Lienhard, Yinpeng Li, Martin Styner, Ipek Oguz, Yundi Shi, Christian Baumgartner, Kent Williams, Hans Johnson, Peter Savadjiev, Carl-Fredrik Westin. acknowledgements: The development of this module was supported by NIH grants R01 MH097979 (PI Rathi), R01 MH092862 (PIs Westin and Verma), U01 NS083223 (PI Westin), R01 MH074794 (PI Westin) and P41 EB015902 (PI Kikinis). """ input_spec = UKFTractographyInputSpec output_spec = UKFTractographyOutputSpec _cmd = " UKFTractography " _outputs_filenames = {'tracts': 'tracts.vtp', 'tractsWithSecondTensor': 'tractsWithSecondTensor.vtp'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/featurecreator.py000066400000000000000000000027621257611314500237720ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class GenerateCsfClippedFromClassifiedImageInputSpec(CommandLineInputSpec): inputCassifiedVolume = File(desc="Required: input tissue label image", exists=True, argstr="--inputCassifiedVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class GenerateCsfClippedFromClassifiedImageOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class GenerateCsfClippedFromClassifiedImage(SEMLikeCommandLine): """title: GenerateCsfClippedFromClassifiedImage category: FeatureCreator description: Get the distance from a voxel to the nearest voxel of a given tissue type. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was written by Hans J. Johnson. """ input_spec = GenerateCsfClippedFromClassifiedImageInputSpec output_spec = GenerateCsfClippedFromClassifiedImageOutputSpec _cmd = " GenerateCsfClippedFromClassifiedImage " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/filtering/000077500000000000000000000000001257611314500223615ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/filtering/__init__.py000066400000000000000000000007171257611314500244770ustar00rootroot00000000000000from denoising import UnbiasedNonLocalMeans from featuredetection import GenerateSummedGradientImage, CannySegmentationLevelSetImageFilter, DilateImage, TextureFromNoiseImageFilter, FlippedDifference, ErodeImage, GenerateBrainClippedImage, NeighborhoodMedian, GenerateTestImage, NeighborhoodMean, HammerAttributeCreator, TextureMeasureFilter, DilateMask, DumpBinaryTrainingVectors, DistanceMaps, STAPLEAnalysis, GradientAnisotropicDiffusionImageFilter, CannyEdge nipype-0.11.0/nipype/interfaces/semtools/filtering/denoising.py000066400000000000000000000106641257611314500247210ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class UnbiasedNonLocalMeansInputSpec(CommandLineInputSpec): sigma = traits.Float(desc="The root power of noise (sigma) in the complex Gaussian process the Rician comes from. If it is underestimated, the algorithm fails to remove the noise. If it is overestimated, over-blurring is likely to occur.", argstr="--sigma %f") rs = InputMultiPath(traits.Int, desc="The algorithm search for similar voxels in a neighborhood of this radius (radii larger than 5,5,5 are very slow, and the results can be only marginally better. Small radii may fail to effectively remove the noise).", sep=",", argstr="--rs %s") rc = InputMultiPath(traits.Int, desc="Similarity between blocks is computed as the difference between mean values and gradients. These parameters are computed fitting a hyperplane with LS inside a neighborhood of this size", sep=",", argstr="--rc %s") hp = traits.Float(desc="This parameter is related to noise; the larger the parameter, the more aggressive the filtering. Should be near 1, and only values between 0.8 and 1.2 are allowed", argstr="--hp %f") ps = traits.Float(desc="To accelerate computations, preselection is used: if the normalized difference is above this threshold, the voxel will be discarded (non used for average)", argstr="--ps %f") inputVolume = File(position=-2, desc="Input MRI volume.", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output (filtered) MRI volume.", argstr="%s") class UnbiasedNonLocalMeansOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output (filtered) MRI volume.", exists=True) class UnbiasedNonLocalMeans(SEMLikeCommandLine): """title: Unbiased NLM for MRI category: Filtering.Denoising description: This module implements a fast version of the popular Non-Local Means filter for image denoising. This algorithm filters each pixel as a weighted average of its neighbors in a large vicinity. The weights are computed based on the similarity of each neighbor with the voxel to be denoised. In the original formulation a patch with a certain radius is centered in each of the voxels, and the Mean Squared Error between each pair of corresponding voxels is computed. In this implementation, only the mean value and gradient components are compared. This, together with an efficient memory management, can attain a speed-up of nearly 20x. Besides, the filtering is more accurate than the original with poor SNR. This code is intended for its use with MRI (or any other Rician-distributed modality): the second order moment is estimated, then we subtract twice the squared power of noise, and finally we take the square root of the result to remove the Rician bias. The original implementation of the NLM filter may be found in: A. Buades, B. Coll, J. Morel, "A review of image denoising algorithms, with a new one", Multiscale Modelling and Simulation 4(2): 490-530. 2005. The correction of the Rician bias is described in the following reference (among others): S. Aja-Fernandez, K. Krissian, "An unbiased Non-Local Means scheme for DWI filtering", in: Proceedings of the MICCAI Workshop on Computational Diffusion MRI, 2008, pp. 277-284. The whole description of this version may be found in the following paper (please, cite it if you are willing to use this software): A. Tristan-Vega, V. Garcia Perez, S. Aja-Fenandez, and C.-F. Westin, "Efficient and Robust Nonlocal Means Denoising of MR Data Based on Salient Features Matching", Computer Methods and Programs in Biomedicine. (Accepted for publication) 2011. version: 0.0.1.$Revision: 1 $(beta) documentation-url: http://www.slicer.org/slicerWiki/index.php/Modules:UnbiasedNonLocalMeans-Documentation-3.6 contributor: Antonio Tristan Vega, Veronica Garcia-Perez, Santiago Aja-Fernandez, Carl-Fredrik Westin acknowledgements: Supported by grant number FMECD-2010/71131616E from the Spanish Ministry of Education/Fulbright Committee """ input_spec = UnbiasedNonLocalMeansInputSpec output_spec = UnbiasedNonLocalMeansOutputSpec _cmd = " UnbiasedNonLocalMeans " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/filtering/featuredetection.py000066400000000000000000000574271257611314500263040ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class GenerateSummedGradientImageInputSpec(CommandLineInputSpec): inputVolume1 = File(desc="input volume 1, usally t1 image", exists=True, argstr="--inputVolume1 %s") inputVolume2 = File(desc="input volume 2, usally t2 image", exists=True, argstr="--inputVolume2 %s") outputFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="(required) output file name", argstr="--outputFileName %s") MaximumGradient = traits.Bool(desc="If set this flag, it will compute maximum gradient between two input volumes instead of sum of it.", argstr="--MaximumGradient ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class GenerateSummedGradientImageOutputSpec(TraitedSpec): outputFileName = File(desc="(required) output file name", exists=True) class GenerateSummedGradientImage(SEMLikeCommandLine): """title: GenerateSummedGradient category: Filtering.FeatureDetection description: Automatic FeatureImages using neural networks version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Greg Harris, Eun Young Kim """ input_spec = GenerateSummedGradientImageInputSpec output_spec = GenerateSummedGradientImageOutputSpec _cmd = " GenerateSummedGradientImage " _outputs_filenames = {'outputFileName': 'outputFileName'} _redirect_x = False class CannySegmentationLevelSetImageFilterInputSpec(CommandLineInputSpec): inputVolume = File(exists=True, argstr="--inputVolume %s") initialModel = File(exists=True, argstr="--initialModel %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, argstr="--outputVolume %s") outputSpeedVolume = traits.Either(traits.Bool, File(), hash_files=False, argstr="--outputSpeedVolume %s") cannyThreshold = traits.Float(desc="Canny Threshold Value", argstr="--cannyThreshold %f") cannyVariance = traits.Float(desc="Canny variance", argstr="--cannyVariance %f") advectionWeight = traits.Float(desc="Controls the smoothness of the resulting mask, small number are more smooth, large numbers allow more sharp corners. ", argstr="--advectionWeight %f") initialModelIsovalue = traits.Float(desc="The identification of the input model iso-surface. (for a binary image with 0s and 1s use 0.5) (for a binary image with 0s and 255's use 127.5).", argstr="--initialModelIsovalue %f") maxIterations = traits.Int(desc="The", argstr="--maxIterations %d") class CannySegmentationLevelSetImageFilterOutputSpec(TraitedSpec): outputVolume = File(exists=True) outputSpeedVolume = File(exists=True) class CannySegmentationLevelSetImageFilter(SEMLikeCommandLine): """title: Canny Level Set Image Filter category: Filtering.FeatureDetection description: The CannySegmentationLevelSet is commonly used to refine a manually generated manual mask. version: 0.3.0 license: CC contributor: Regina Kim acknowledgements: This command module was derived from Insight/Examples/Segmentation/CannySegmentationLevelSetImageFilter.cxx (copyright) Insight Software Consortium. See http://wiki.na-mic.org/Wiki/index.php/Slicer3:Execution_Model_Documentation for more detailed descriptions. """ input_spec = CannySegmentationLevelSetImageFilterInputSpec output_spec = CannySegmentationLevelSetImageFilterOutputSpec _cmd = " CannySegmentationLevelSetImageFilter " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'outputSpeedVolume': 'outputSpeedVolume.nii'} _redirect_x = False class DilateImageInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") inputRadius = traits.Int(desc="Required: input neighborhood radius", argstr="--inputRadius %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class DilateImageOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class DilateImage(SEMLikeCommandLine): """title: Dilate Image category: Filtering.FeatureDetection description: Uses mathematical morphology to dilate the input images. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = DilateImageInputSpec output_spec = DilateImageOutputSpec _cmd = " DilateImage " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class TextureFromNoiseImageFilterInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputRadius = traits.Int(desc="Required: input neighborhood radius", argstr="--inputRadius %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class TextureFromNoiseImageFilterOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class TextureFromNoiseImageFilter(SEMLikeCommandLine): """title: TextureFromNoiseImageFilter category: Filtering.FeatureDetection description: Calculate the local noise in an image. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Eunyoung Regina Kim """ input_spec = TextureFromNoiseImageFilterInputSpec output_spec = TextureFromNoiseImageFilterOutputSpec _cmd = " TextureFromNoiseImageFilter " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class FlippedDifferenceInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class FlippedDifferenceOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class FlippedDifference(SEMLikeCommandLine): """title: Flip Image category: Filtering.FeatureDetection description: Difference between an image and the axially flipped version of that image. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = FlippedDifferenceInputSpec output_spec = FlippedDifferenceOutputSpec _cmd = " FlippedDifference " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class ErodeImageInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") inputRadius = traits.Int(desc="Required: input neighborhood radius", argstr="--inputRadius %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class ErodeImageOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class ErodeImage(SEMLikeCommandLine): """title: Erode Image category: Filtering.FeatureDetection description: Uses mathematical morphology to erode the input images. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = ErodeImageInputSpec output_spec = ErodeImageOutputSpec _cmd = " ErodeImage " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class GenerateBrainClippedImageInputSpec(CommandLineInputSpec): inputImg = File(desc="input volume 1, usally t1 image", exists=True, argstr="--inputImg %s") inputMsk = File(desc="input volume 2, usally t2 image", exists=True, argstr="--inputMsk %s") outputFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="(required) output file name", argstr="--outputFileName %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class GenerateBrainClippedImageOutputSpec(TraitedSpec): outputFileName = File(desc="(required) output file name", exists=True) class GenerateBrainClippedImage(SEMLikeCommandLine): """title: GenerateBrainClippedImage category: Filtering.FeatureDetection description: Automatic FeatureImages using neural networks version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Eun Young Kim """ input_spec = GenerateBrainClippedImageInputSpec output_spec = GenerateBrainClippedImageOutputSpec _cmd = " GenerateBrainClippedImage " _outputs_filenames = {'outputFileName': 'outputFileName'} _redirect_x = False class NeighborhoodMedianInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") inputRadius = traits.Int(desc="Required: input neighborhood radius", argstr="--inputRadius %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class NeighborhoodMedianOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class NeighborhoodMedian(SEMLikeCommandLine): """title: Neighborhood Median category: Filtering.FeatureDetection description: Calculates the median, for the given neighborhood size, at each voxel of the input image. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = NeighborhoodMedianInputSpec output_spec = NeighborhoodMedianOutputSpec _cmd = " NeighborhoodMedian " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class GenerateTestImageInputSpec(CommandLineInputSpec): inputVolume = File(desc="input volume 1, usally t1 image", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="(required) output file name", argstr="--outputVolume %s") lowerBoundOfOutputVolume = traits.Float(argstr="--lowerBoundOfOutputVolume %f") upperBoundOfOutputVolume = traits.Float(argstr="--upperBoundOfOutputVolume %f") outputVolumeSize = traits.Float(desc="output Volume Size", argstr="--outputVolumeSize %f") class GenerateTestImageOutputSpec(TraitedSpec): outputVolume = File(desc="(required) output file name", exists=True) class GenerateTestImage(SEMLikeCommandLine): """title: DownSampleImage category: Filtering.FeatureDetection description: Down sample image for testing version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Eun Young Kim """ input_spec = GenerateTestImageInputSpec output_spec = GenerateTestImageOutputSpec _cmd = " GenerateTestImage " _outputs_filenames = {'outputVolume': 'outputVolume'} _redirect_x = False class NeighborhoodMeanInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") inputRadius = traits.Int(desc="Required: input neighborhood radius", argstr="--inputRadius %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class NeighborhoodMeanOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class NeighborhoodMean(SEMLikeCommandLine): """title: Neighborhood Mean category: Filtering.FeatureDetection description: Calculates the mean, for the given neighborhood size, at each voxel of the T1, T2, and FLAIR. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = NeighborhoodMeanInputSpec output_spec = NeighborhoodMeanOutputSpec _cmd = " NeighborhoodMean " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class HammerAttributeCreatorInputSpec(CommandLineInputSpec): Scale = traits.Int(desc="Determine Scale of Ball", argstr="--Scale %d") Strength = traits.Float(desc="Determine Strength of Edges", argstr="--Strength %f") inputGMVolume = File(desc="Required: input grey matter posterior image", exists=True, argstr="--inputGMVolume %s") inputWMVolume = File(desc="Required: input white matter posterior image", exists=True, argstr="--inputWMVolume %s") inputCSFVolume = File(desc="Required: input CSF posterior image", exists=True, argstr="--inputCSFVolume %s") outputVolumeBase = traits.Str(desc="Required: output image base name to be appended for each feature vector.", argstr="--outputVolumeBase %s") class HammerAttributeCreatorOutputSpec(TraitedSpec): pass class HammerAttributeCreator(SEMLikeCommandLine): """title: HAMMER Feature Vectors category: Filtering.FeatureDetection description: Create the feature vectors used by HAMMER. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This was extracted from the Hammer Registration source code, and wrapped up by Hans J. Johnson. """ input_spec = HammerAttributeCreatorInputSpec output_spec = HammerAttributeCreatorOutputSpec _cmd = " HammerAttributeCreator " _outputs_filenames = {} _redirect_x = False class TextureMeasureFilterInputSpec(CommandLineInputSpec): inputVolume = File(exists=True, argstr="--inputVolume %s") inputMaskVolume = File(exists=True, argstr="--inputMaskVolume %s") distance = traits.Int(argstr="--distance %d") insideROIValue = traits.Float(argstr="--insideROIValue %f") outputFilename = traits.Either(traits.Bool, File(), hash_files=False, argstr="--outputFilename %s") class TextureMeasureFilterOutputSpec(TraitedSpec): outputFilename = File(exists=True) class TextureMeasureFilter(SEMLikeCommandLine): """title: Canny Level Set Image Filter category: Filtering.FeatureDetection description: The CannySegmentationLevelSet is commonly used to refine a manually generated manual mask. version: 0.3.0 license: CC contributor: Regina Kim acknowledgements: This command module was derived from Insight/Examples/Segmentation/CannySegmentationLevelSetImageFilter.cxx (copyright) Insight Software Consortium. See http://wiki.na-mic.org/Wiki/index.php/Slicer3:Execution_Model_Documentation for more detailed descriptions. """ input_spec = TextureMeasureFilterInputSpec output_spec = TextureMeasureFilterOutputSpec _cmd = " TextureMeasureFilter " _outputs_filenames = {'outputFilename': 'outputFilename'} _redirect_x = False class DilateMaskInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") inputBinaryVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputBinaryVolume %s") sizeStructuralElement = traits.Int(desc="size of structural element. sizeStructuralElement=1 means that 3x3x3 structuring element for 3D", argstr="--sizeStructuralElement %d") lowerThreshold = traits.Float(desc="Required: lowerThreshold value", argstr="--lowerThreshold %f") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class DilateMaskOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class DilateMask(SEMLikeCommandLine): """title: Dilate Image category: Filtering.FeatureDetection description: Uses mathematical morphology to dilate the input images. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = DilateMaskInputSpec output_spec = DilateMaskOutputSpec _cmd = " DilateMask " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class DumpBinaryTrainingVectorsInputSpec(CommandLineInputSpec): inputHeaderFilename = File(desc="Required: input header file name", exists=True, argstr="--inputHeaderFilename %s") inputVectorFilename = File(desc="Required: input vector filename", exists=True, argstr="--inputVectorFilename %s") class DumpBinaryTrainingVectorsOutputSpec(TraitedSpec): pass class DumpBinaryTrainingVectors(SEMLikeCommandLine): """title: Erode Image category: Filtering.FeatureDetection description: Uses mathematical morphology to erode the input images. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = DumpBinaryTrainingVectorsInputSpec output_spec = DumpBinaryTrainingVectorsOutputSpec _cmd = " DumpBinaryTrainingVectors " _outputs_filenames = {} _redirect_x = False class DistanceMapsInputSpec(CommandLineInputSpec): inputLabelVolume = File(desc="Required: input tissue label image", exists=True, argstr="--inputLabelVolume %s") inputMaskVolume = File(desc="Required: input brain mask image", exists=True, argstr="--inputMaskVolume %s") inputTissueLabel = traits.Int(desc="Required: input integer value of tissue type used to calculate distance", argstr="--inputTissueLabel %d") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class DistanceMapsOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class DistanceMaps(SEMLikeCommandLine): """title: Mauerer Distance category: Filtering.FeatureDetection description: Get the distance from a voxel to the nearest voxel of a given tissue type. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = DistanceMapsInputSpec output_spec = DistanceMapsOutputSpec _cmd = " DistanceMaps " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class STAPLEAnalysisInputSpec(CommandLineInputSpec): inputDimension = traits.Int(desc="Required: input image Dimension 2 or 3", argstr="--inputDimension %d") inputLabelVolume = InputMultiPath(File(exists=True), desc="Required: input label volume", argstr="--inputLabelVolume %s...") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class STAPLEAnalysisOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class STAPLEAnalysis(SEMLikeCommandLine): """title: Dilate Image category: Filtering.FeatureDetection description: Uses mathematical morphology to dilate the input images. version: 0.1.0.$Revision: 1 $(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Mark Scully and Jeremy Bockholt. """ input_spec = STAPLEAnalysisInputSpec output_spec = STAPLEAnalysisOutputSpec _cmd = " STAPLEAnalysis " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class GradientAnisotropicDiffusionImageFilterInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input image", exists=True, argstr="--inputVolume %s") numberOfIterations = traits.Int(desc="Optional value for number of Iterations", argstr="--numberOfIterations %d") timeStep = traits.Float(desc="Time step for diffusion process", argstr="--timeStep %f") conductance = traits.Float(desc="Conductance for diffusion process", argstr="--conductance %f") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class GradientAnisotropicDiffusionImageFilterOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class GradientAnisotropicDiffusionImageFilter(SEMLikeCommandLine): """title: GradientAnisopropicDiffusionFilter category: Filtering.FeatureDetection description: Image Smoothing using Gradient Anisotropic Diffuesion Filer contributor: This tool was developed by Eun Young Kim by modifying ITK Example """ input_spec = GradientAnisotropicDiffusionImageFilterInputSpec output_spec = GradientAnisotropicDiffusionImageFilterOutputSpec _cmd = " GradientAnisotropicDiffusionImageFilter " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class CannyEdgeInputSpec(CommandLineInputSpec): inputVolume = File(desc="Required: input tissue label image", exists=True, argstr="--inputVolume %s") variance = traits.Float(desc="Variance and Maximum error are used in the Gaussian smoothing of the input image. See itkDiscreteGaussianImageFilter for information on these parameters.", argstr="--variance %f") upperThreshold = traits.Float( desc="Threshold is the lowest allowed value in the output image. Its data type is the same as the data type of the output image. Any values below the Threshold level will be replaced with the OutsideValue parameter value, whose default is zero. ", argstr="--upperThreshold %f") lowerThreshold = traits.Float( desc="Threshold is the lowest allowed value in the output image. Its data type is the same as the data type of the output image. Any values below the Threshold level will be replaced with the OutsideValue parameter value, whose default is zero. ", argstr="--lowerThreshold %f") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output image", argstr="--outputVolume %s") class CannyEdgeOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output image", exists=True) class CannyEdge(SEMLikeCommandLine): """title: Canny Edge Detection category: Filtering.FeatureDetection description: Get the distance from a voxel to the nearest voxel of a given tissue type. version: 0.1.0.(alpha) documentation-url: http:://www.na-mic.org/ license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was written by Hans J. Johnson. """ input_spec = CannyEdgeInputSpec output_spec = CannyEdgeOutputSpec _cmd = " CannyEdge " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/000077500000000000000000000000001257611314500235235ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_CannyEdge.py000066400000000000000000000023171257611314500300240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import CannyEdge def test_CannyEdge_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), lowerThreshold=dict(argstr='--lowerThreshold %f', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), upperThreshold=dict(argstr='--upperThreshold %f', ), variance=dict(argstr='--variance %f', ), ) inputs = CannyEdge.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CannyEdge_outputs(): output_map = dict(outputVolume=dict(), ) outputs = CannyEdge.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_CannySegmentationLevelSetImageFilter.py000066400000000000000000000032261257611314500353130ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/filtering/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import CannySegmentationLevelSetImageFilter def test_CannySegmentationLevelSetImageFilter_inputs(): input_map = dict(advectionWeight=dict(argstr='--advectionWeight %f', ), args=dict(argstr='%s', ), cannyThreshold=dict(argstr='--cannyThreshold %f', ), cannyVariance=dict(argstr='--cannyVariance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), initialModel=dict(argstr='--initialModel %s', ), initialModelIsovalue=dict(argstr='--initialModelIsovalue %f', ), inputVolume=dict(argstr='--inputVolume %s', ), maxIterations=dict(argstr='--maxIterations %d', ), outputSpeedVolume=dict(argstr='--outputSpeedVolume %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = CannySegmentationLevelSetImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CannySegmentationLevelSetImageFilter_outputs(): output_map = dict(outputSpeedVolume=dict(), outputVolume=dict(), ) outputs = CannySegmentationLevelSetImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_DilateImage.py000066400000000000000000000022441257611314500303330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import DilateImage def test_DilateImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputRadius=dict(argstr='--inputRadius %d', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = DilateImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DilateImage_outputs(): output_map = dict(outputVolume=dict(), ) outputs = DilateImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_DilateMask.py000066400000000000000000000023641257611314500302070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import DilateMask def test_DilateMask_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryVolume=dict(argstr='--inputBinaryVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), lowerThreshold=dict(argstr='--lowerThreshold %f', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), sizeStructuralElement=dict(argstr='--sizeStructuralElement %d', ), terminal_output=dict(nohash=True, ), ) inputs = DilateMask.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DilateMask_outputs(): output_map = dict(outputVolume=dict(), ) outputs = DilateMask.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_DistanceMaps.py000066400000000000000000000022751257611314500305450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import DistanceMaps def test_DistanceMaps_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputLabelVolume=dict(argstr='--inputLabelVolume %s', ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputTissueLabel=dict(argstr='--inputTissueLabel %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = DistanceMaps.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DistanceMaps_outputs(): output_map = dict(outputVolume=dict(), ) outputs = DistanceMaps.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_DumpBinaryTrainingVectors.py000066400000000000000000000021431257611314500333000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import DumpBinaryTrainingVectors def test_DumpBinaryTrainingVectors_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputHeaderFilename=dict(argstr='--inputHeaderFilename %s', ), inputVectorFilename=dict(argstr='--inputVectorFilename %s', ), terminal_output=dict(nohash=True, ), ) inputs = DumpBinaryTrainingVectors.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DumpBinaryTrainingVectors_outputs(): output_map = dict() outputs = DumpBinaryTrainingVectors.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_ErodeImage.py000066400000000000000000000022371257611314500301710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import ErodeImage def test_ErodeImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputRadius=dict(argstr='--inputRadius %d', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = ErodeImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ErodeImage_outputs(): output_map = dict(outputVolume=dict(), ) outputs = ErodeImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_FlippedDifference.py000066400000000000000000000022131257611314500315200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import FlippedDifference def test_FlippedDifference_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = FlippedDifference.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FlippedDifference_outputs(): output_map = dict(outputVolume=dict(), ) outputs = FlippedDifference.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_GenerateBrainClippedImage.py000066400000000000000000000023441257611314500331410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import GenerateBrainClippedImage def test_GenerateBrainClippedImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputImg=dict(argstr='--inputImg %s', ), inputMsk=dict(argstr='--inputMsk %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputFileName=dict(argstr='--outputFileName %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = GenerateBrainClippedImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateBrainClippedImage_outputs(): output_map = dict(outputFileName=dict(), ) outputs = GenerateBrainClippedImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_GenerateSummedGradientImage.py000066400000000000000000000024731257611314500335200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import GenerateSummedGradientImage def test_GenerateSummedGradientImage_inputs(): input_map = dict(MaximumGradient=dict(argstr='--MaximumGradient ', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='--inputVolume1 %s', ), inputVolume2=dict(argstr='--inputVolume2 %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputFileName=dict(argstr='--outputFileName %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = GenerateSummedGradientImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateSummedGradientImage_outputs(): output_map = dict(outputFileName=dict(), ) outputs = GenerateSummedGradientImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_GenerateTestImage.py000066400000000000000000000024571257611314500315310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import GenerateTestImage def test_GenerateTestImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), lowerBoundOfOutputVolume=dict(argstr='--lowerBoundOfOutputVolume %f', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), outputVolumeSize=dict(argstr='--outputVolumeSize %f', ), terminal_output=dict(nohash=True, ), upperBoundOfOutputVolume=dict(argstr='--upperBoundOfOutputVolume %f', ), ) inputs = GenerateTestImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateTestImage_outputs(): output_map = dict(outputVolume=dict(), ) outputs = GenerateTestImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_GradientAnisotropicDiffusionImageFilter.py000066400000000000000000000025471257611314500360450ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/filtering/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import GradientAnisotropicDiffusionImageFilter def test_GradientAnisotropicDiffusionImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), conductance=dict(argstr='--conductance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfIterations=dict(argstr='--numberOfIterations %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), timeStep=dict(argstr='--timeStep %f', ), ) inputs = GradientAnisotropicDiffusionImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GradientAnisotropicDiffusionImageFilter_outputs(): output_map = dict(outputVolume=dict(), ) outputs = GradientAnisotropicDiffusionImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_HammerAttributeCreator.py000066400000000000000000000024261257611314500326050ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import HammerAttributeCreator def test_HammerAttributeCreator_inputs(): input_map = dict(Scale=dict(argstr='--Scale %d', ), Strength=dict(argstr='--Strength %f', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputCSFVolume=dict(argstr='--inputCSFVolume %s', ), inputGMVolume=dict(argstr='--inputGMVolume %s', ), inputWMVolume=dict(argstr='--inputWMVolume %s', ), outputVolumeBase=dict(argstr='--outputVolumeBase %s', ), terminal_output=dict(nohash=True, ), ) inputs = HammerAttributeCreator.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_HammerAttributeCreator_outputs(): output_map = dict() outputs = HammerAttributeCreator.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_NeighborhoodMean.py000066400000000000000000000022751257611314500314020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import NeighborhoodMean def test_NeighborhoodMean_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputRadius=dict(argstr='--inputRadius %d', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = NeighborhoodMean.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NeighborhoodMean_outputs(): output_map = dict(outputVolume=dict(), ) outputs = NeighborhoodMean.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_NeighborhoodMedian.py000066400000000000000000000023071257611314500317130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import NeighborhoodMedian def test_NeighborhoodMedian_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputRadius=dict(argstr='--inputRadius %d', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = NeighborhoodMedian.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NeighborhoodMedian_outputs(): output_map = dict(outputVolume=dict(), ) outputs = NeighborhoodMedian.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_STAPLEAnalysis.py000066400000000000000000000022071257611314500306610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import STAPLEAnalysis def test_STAPLEAnalysis_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputDimension=dict(argstr='--inputDimension %d', ), inputLabelVolume=dict(argstr='--inputLabelVolume %s...', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = STAPLEAnalysis.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_STAPLEAnalysis_outputs(): output_map = dict(outputVolume=dict(), ) outputs = STAPLEAnalysis.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_TextureFromNoiseImageFilter.py000066400000000000000000000022651257611314500335640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import TextureFromNoiseImageFilter def test_TextureFromNoiseImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputRadius=dict(argstr='--inputRadius %d', ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = TextureFromNoiseImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TextureFromNoiseImageFilter_outputs(): output_map = dict(outputVolume=dict(), ) outputs = TextureFromNoiseImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_TextureMeasureFilter.py000066400000000000000000000024161257611314500323170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.featuredetection import TextureMeasureFilter def test_TextureMeasureFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), distance=dict(argstr='--distance %d', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputVolume=dict(argstr='--inputVolume %s', ), insideROIValue=dict(argstr='--insideROIValue %f', ), outputFilename=dict(argstr='--outputFilename %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = TextureMeasureFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TextureMeasureFilter_outputs(): output_map = dict(outputFilename=dict(), ) outputs = TextureMeasureFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/filtering/tests/test_auto_UnbiasedNonLocalMeans.py000066400000000000000000000025101257611314500323260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.filtering.denoising import UnbiasedNonLocalMeans def test_UnbiasedNonLocalMeans_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), hp=dict(argstr='--hp %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), ps=dict(argstr='--ps %f', ), rc=dict(argstr='--rc %s', sep=',', ), rs=dict(argstr='--rs %s', sep=',', ), sigma=dict(argstr='--sigma %f', ), terminal_output=dict(nohash=True, ), ) inputs = UnbiasedNonLocalMeans.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_UnbiasedNonLocalMeans_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = UnbiasedNonLocalMeans.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/generated.sh000066400000000000000000000005741257611314500226760ustar00rootroot00000000000000local_generate_classes.py --python_paths=/scratch/johnsonhj/src/NEP-11/NIPYPE --program_paths=/scratch/johnsonhj/src/NEP-11/bin:/usr/local/bin:/opt/ogs/bin/darwin-x64:/bin:/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/usr/texbin:/Shared/sinapse/sharedopt/20120722/Darwin_i386/vv/bin:/usr/texbin:/scratch/johnsonhj/bin --output_path=/scratch/johnsonhj/src/NEP-11/BRAINSTools/AutoWorkup nipype-0.11.0/nipype/interfaces/semtools/legacy/000077500000000000000000000000001257611314500216425ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/legacy/__init__.py000066400000000000000000000000511257611314500237470ustar00rootroot00000000000000from registration import scalartransform nipype-0.11.0/nipype/interfaces/semtools/legacy/registration.py000066400000000000000000000042701257611314500247310ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class scalartransformInputSpec(CommandLineInputSpec): input_image = File(desc="Image to tranform", exists=True, argstr="--input_image %s") output_image = traits.Either(traits.Bool, File(), hash_files=False, desc="The transformed image", argstr="--output_image %s") transformation = traits.Either(traits.Bool, File(), hash_files=False, desc="Output file for transformation parameters", argstr="--transformation %s") invert = traits.Bool(desc="Invert tranform before applying.", argstr="--invert ") deformation = File(desc="Deformation field.", exists=True, argstr="--deformation %s") h_field = traits.Bool(desc="The deformation is an h-field.", argstr="--h_field ") interpolation = traits.Enum("nearestneighbor", "linear", "cubic", desc="Interpolation type (nearestneighbor, linear, cubic)", argstr="--interpolation %s") class scalartransformOutputSpec(TraitedSpec): output_image = File(desc="The transformed image", exists=True) transformation = File(desc="Output file for transformation parameters", exists=True) class scalartransform(SEMLikeCommandLine): """title: ScalarTransform (DTIProcess) category: Legacy.Registration version: 1.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/Nightly/Extensions/DTIProcess license: Copyright (c) Casey Goodlett. All rights reserved. See http://www.ia.unc.edu/dev/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. contributor: Casey Goodlett """ input_spec = scalartransformInputSpec output_spec = scalartransformOutputSpec _cmd = " scalartransform " _outputs_filenames = {'output_image': 'output_image.nii', 'transformation': 'transformation'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/legacy/tests/000077500000000000000000000000001257611314500230045ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/legacy/tests/test_auto_scalartransform.py000066400000000000000000000025631257611314500306540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.legacy.registration import scalartransform def test_scalartransform_inputs(): input_map = dict(args=dict(argstr='%s', ), deformation=dict(argstr='--deformation %s', ), environ=dict(nohash=True, usedefault=True, ), h_field=dict(argstr='--h_field ', ), ignore_exception=dict(nohash=True, usedefault=True, ), input_image=dict(argstr='--input_image %s', ), interpolation=dict(argstr='--interpolation %s', ), invert=dict(argstr='--invert ', ), output_image=dict(argstr='--output_image %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformation=dict(argstr='--transformation %s', hash_files=False, ), ) inputs = scalartransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_scalartransform_outputs(): output_map = dict(output_image=dict(), transformation=dict(), ) outputs = scalartransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/registration/000077500000000000000000000000001257611314500231105ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/registration/__init__.py000066400000000000000000000003101257611314500252130ustar00rootroot00000000000000from specialized import VBRAINSDemonWarp, BRAINSDemonWarp, BRAINSTransformFromFiducials from brainsresample import BRAINSResample from brainsfit import BRAINSFit from brainsresize import BRAINSResize nipype-0.11.0/nipype/interfaces/semtools/registration/brainsfit.py000066400000000000000000000547451257611314500254620ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSFitInputSpec(CommandLineInputSpec): fixedVolume = File(desc="Input fixed image (the moving image will be transformed into this image space).", exists=True, argstr="--fixedVolume %s") movingVolume = File(desc="Input moving image (this image will be transformed into the fixed image space).", exists=True, argstr="--movingVolume %s") samplingPercentage = traits.Float( desc="Fraction of voxels of the fixed image that will be used for registration. The number has to be larger than zero and less or equal to one. Higher values increase the computation time but may give more accurate results. You can also limit the sampling focus with ROI masks and ROIAUTO mask generation. The default is 0.002 (use approximately 0.2% of voxels, resulting in 100000 samples in a 512x512x192 volume) to provide a very fast registration in most cases. Typical values range from 0.01 (1%) for low detail images to 0.2 (20%) for high detail images.", argstr="--samplingPercentage %f") splineGridSize = InputMultiPath(traits.Int, desc="Number of BSpline grid subdivisions along each axis of the fixed image, centered on the image space. Values must be 3 or higher for the BSpline to be correctly computed.", sep=",", argstr="--splineGridSize %s") linearTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Output estimated transform - in case the computed transform is not BSpline. NOTE: You must set at least one output object (transform and/or output volume).", argstr="--linearTransform %s") bsplineTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Output estimated transform - in case the computed transform is BSpline. NOTE: You must set at least one output object (transform and/or output volume).", argstr="--bsplineTransform %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Output image: the moving image warped to the fixed image space. NOTE: You must set at least one output object (transform and/or output volume).", argstr="--outputVolume %s") initialTransform = File(desc="Transform to be applied to the moving image to initialize the registration. This can only be used if Initialize Transform Mode is Off.", exists=True, argstr="--initialTransform %s") initializeTransformMode = traits.Enum("Off", "useMomentsAlign", "useCenterOfHeadAlign", "useGeometryAlign", "useCenterOfROIAlign", desc="Determine how to initialize the transform center. useMomentsAlign assumes that the center of mass of the images represent similar structures. useCenterOfHeadAlign attempts to use the top of head and shape of neck to drive a center of mass estimate. useGeometryAlign on assumes that the center of the voxel lattice of the images represent similar structures. Off assumes that the physical space of the images are close. This flag is mutually exclusive with the Initialization transform.", argstr="--initializeTransformMode %s") useRigid = traits.Bool(desc="Perform a rigid registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useRigid ") useScaleVersor3D = traits.Bool(desc="Perform a ScaleVersor3D registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useScaleVersor3D ") useScaleSkewVersor3D = traits.Bool(desc="Perform a ScaleSkewVersor3D registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useScaleSkewVersor3D ") useAffine = traits.Bool(desc="Perform an Affine registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useAffine ") useBSpline = traits.Bool(desc="Perform a BSpline registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useBSpline ") useSyN = traits.Bool(desc="Perform a SyN registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useSyN ") useComposite = traits.Bool(desc="Perform a Composite registration as part of the sequential registration steps. This family of options overrides the use of transformType if any of them are set.", argstr="--useComposite ") maskProcessingMode = traits.Enum( "NOMASK", "ROIAUTO", "ROI", desc="Specifies a mask to only consider a certain image region for the registration. If ROIAUTO is chosen, then the mask is computed using Otsu thresholding and hole filling. If ROI is chosen then the mask has to be specified as in input.", argstr="--maskProcessingMode %s") fixedBinaryVolume = File(desc="Fixed Image binary mask volume, required if Masking Option is ROI. Image areas where the mask volume has zero value are ignored during the registration.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Moving Image binary mask volume, required if Masking Option is ROI. Image areas where the mask volume has zero value are ignored during the registration.", exists=True, argstr="--movingBinaryVolume %s") outputFixedVolumeROI = traits.Either( traits.Bool, File(), hash_files=False, desc="ROI that is automatically computed from the fixed image. Only available if Masking Option is ROIAUTO. Image areas where the mask volume has zero value are ignored during the registration.", argstr="--outputFixedVolumeROI %s") outputMovingVolumeROI = traits.Either( traits.Bool, File(), hash_files=False, desc="ROI that is automatically computed from the moving image. Only available if Masking Option is ROIAUTO. Image areas where the mask volume has zero value are ignored during the registration.", argstr="--outputMovingVolumeROI %s") useROIBSpline = traits.Bool(desc="If enabled then the bounding box of the input ROIs defines the BSpline grid support region. Otherwise the BSpline grid support region is the whole fixed image.", argstr="--useROIBSpline ") histogramMatch = traits.Bool( desc="Apply histogram matching operation for the input images to make them more similar. This is suitable for images of the same modality that may have different brightness or contrast, but the same overall intensity profile. Do NOT use if registering images from different modalities.", argstr="--histogramMatch ") medianFilterSize = InputMultiPath(traits.Int, desc="Apply median filtering to reduce noise in the input volumes. The 3 values specify the radius for the optional MedianImageFilter preprocessing in all 3 directions (in voxels).", sep=",", argstr="--medianFilterSize %s") removeIntensityOutliers = traits.Float( desc="Remove very high and very low intensity voxels from the input volumes. The parameter specifies the half percentage to decide outliers of image intensities. The default value is zero, which means no outlier removal. If the value of 0.005 is given, the 0.005% of both tails will be thrown away, so 0.01% of intensities in total would be ignored in the statistic calculation.", argstr="--removeIntensityOutliers %f") fixedVolume2 = File(desc="Input fixed image that will be used for multimodal registration. (the moving image will be transformed into this image space).", exists=True, argstr="--fixedVolume2 %s") movingVolume2 = File(desc="Input moving image that will be used for multimodal registration(this image will be transformed into the fixed image space).", exists=True, argstr="--movingVolume2 %s") outputVolumePixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", desc="Data type for representing a voxel of the Output Volume.", argstr="--outputVolumePixelType %s") backgroundFillValue = traits.Float(desc="This value will be used for filling those areas of the output image that have no corresponding voxels in the input moving image.", argstr="--backgroundFillValue %f") scaleOutputValues = traits.Bool( desc="If true, and the voxel values do not fit within the minimum and maximum values of the desired outputVolumePixelType, then linearly scale the min/max output image voxel values to fit within the min/max range of the outputVolumePixelType.", argstr="--scaleOutputValues ") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, NearestNeighbor, BSpline, WindowedSinc, Hamming, Cosine, Welch, Lanczos, or ResampleInPlace. The ResampleInPlace option will create an image with the same discrete voxel values and will adjust the origin and direction of the physical space interpretation.", argstr="--interpolationMode %s") numberOfIterations = InputMultiPath( traits.Int, desc="The maximum number of iterations to try before stopping the optimization. When using a lower value (500-1000) then the registration is forced to terminate earlier but there is a higher risk of stopping before an optimal solution is reached.", sep=",", argstr="--numberOfIterations %s") maximumStepLength = traits.Float(desc="Starting step length of the optimizer. In general, higher values allow for recovering larger initial misalignments but there is an increased chance that the registration will not converge.", argstr="--maximumStepLength %f") minimumStepLength = InputMultiPath( traits.Float, desc="Each step in the optimization takes steps at least this big. When none are possible, registration is complete. Smaller values allows the optimizer to make smaller adjustments, but the registration time may increase.", sep=",", argstr="--minimumStepLength %s") relaxationFactor = traits.Float( desc="Specifies how quickly the optimization step length is decreased during registration. The value must be larger than 0 and smaller than 1. Larger values result in slower step size decrease, which allow for recovering larger initial misalignments but it increases the registration time and the chance that the registration will not converge.", argstr="--relaxationFactor %f") translationScale = traits.Float(desc="How much to scale up changes in position (in mm) compared to unit rotational changes (in radians) -- decrease this to allow for more rotation in the search pattern.", argstr="--translationScale %f") reproportionScale = traits.Float(desc="ScaleVersor3D 'Scale' compensation factor. Increase this to allow for more rescaling in a ScaleVersor3D or ScaleSkewVersor3D search pattern. 1.0 works well with a translationScale of 1000.0", argstr="--reproportionScale %f") skewScale = traits.Float(desc="ScaleSkewVersor3D Skew compensation factor. Increase this to allow for more skew in a ScaleSkewVersor3D search pattern. 1.0 works well with a translationScale of 1000.0", argstr="--skewScale %f") maxBSplineDisplacement = traits.Float( desc="Maximum allowed displacements in image physical coordinates (mm) for BSpline control grid along each axis. A value of 0.0 indicates that the problem should be unbounded. NOTE: This only constrains the BSpline portion, and does not limit the displacement from the associated bulk transform. This can lead to a substantial reduction in computation time in the BSpline optimizer., ", argstr="--maxBSplineDisplacement %f") fixedVolumeTimeIndex = traits.Int(desc="The index in the time series for the 3D fixed image to fit. Only allowed if the fixed input volume is 4-dimensional.", argstr="--fixedVolumeTimeIndex %d") movingVolumeTimeIndex = traits.Int(desc="The index in the time series for the 3D moving image to fit. Only allowed if the moving input volume is 4-dimensional", argstr="--movingVolumeTimeIndex %d") numberOfHistogramBins = traits.Int(desc="The number of histogram levels used for mutual information metric estimation.", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="Number of histogram match points used for mutual information metric estimation.", argstr="--numberOfMatchPoints %d") costMetric = traits.Enum("MMI", "MSE", "NC", "MIH", desc="The cost metric to be used during fitting. Defaults to MMI. Options are MMI (Mattes Mutual Information), MSE (Mean Square Error), NC (Normalized Correlation), MC (Match Cardinality for binary images)", argstr="--costMetric %s") maskInferiorCutOffFromCenter = traits.Float( desc="If Initialize Transform Mode is set to useCenterOfHeadAlign or Masking Option is ROIAUTO then this value defines the how much is cut of from the inferior part of the image. The cut-off distance is specified in millimeters, relative to the image center. If the value is 1000 or larger then no cut-off performed.", argstr="--maskInferiorCutOffFromCenter %f") ROIAutoDilateSize = traits.Float( desc="This flag is only relevant when using ROIAUTO mode for initializing masks. It defines the final dilation size to capture a bit of background outside the tissue region. A setting of 10mm has been shown to help regularize a BSpline registration type so that there is some background constraints to match the edges of the head better.", argstr="--ROIAutoDilateSize %f") ROIAutoClosingSize = traits.Float( desc="This flag is only relevant when using ROIAUTO mode for initializing masks. It defines the hole closing size in mm. It is rounded up to the nearest whole pixel size in each direction. The default is to use a closing size of 9mm. For mouse data this value may need to be reset to 0.9 or smaller.", argstr="--ROIAutoClosingSize %f") numberOfSamples = traits.Int( desc="The number of voxels sampled for mutual information computation. Increase this for higher accuracy, at the cost of longer computation time., NOTE that it is suggested to use samplingPercentage instead of this option. However, if set to non-zero, numberOfSamples overwrites the samplingPercentage option. ", argstr="--numberOfSamples %d") strippedOutputTransform = traits.Either( traits.Bool, File(), hash_files=False, desc="Rigid component of the estimated affine transform. Can be used to rigidly register the moving image to the fixed image. NOTE: This value is overridden if either bsplineTransform or linearTransform is set.", argstr="--strippedOutputTransform %s") transformType = InputMultiPath( traits.Str, desc="Specifies a list of registration types to be used. The valid types are, Rigid, ScaleVersor3D, ScaleSkewVersor3D, Affine, BSpline and SyN. Specifying more than one in a comma separated list will initialize the next stage with the previous results. If registrationClass flag is used, it overrides this parameter setting.", sep=",", argstr="--transformType %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Filename to which save the (optional) estimated transform. NOTE: You must select either the outputTransform or the outputVolume option.", argstr="--outputTransform %s") initializeRegistrationByCurrentGenericTransform = traits.Bool( desc="If this flag is ON, the current generic composite transform, resulted from the linear registration stages, is set to initialize the follow nonlinear registration process. However, by the default behaviour, the moving image is first warped based on the existant transform before it is passed to the BSpline registration filter. It is done to speed up the BSpline registration by reducing the computations of composite transform Jacobian.", argstr="--initializeRegistrationByCurrentGenericTransform ") failureExitCode = traits.Int(desc="If the fit fails, exit with this status code. (It can be used to force a successfult exit status of (0) if the registration fails due to reaching the maximum number of iterations.", argstr="--failureExitCode %d") writeTransformOnFailure = traits.Bool(desc="Flag to save the final transform even if the numberOfIterations are reached without convergence. (Intended for use when --failureExitCode 0 )", argstr="--writeTransformOnFailure ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use. (default is auto-detected)", argstr="--numberOfThreads %d") debugLevel = traits.Int(desc="Display debug messages, and produce debug intermediate results. 0=OFF, 1=Minimal, 10=Maximum debugging.", argstr="--debugLevel %d") costFunctionConvergenceFactor = traits.Float( desc="From itkLBFGSBOptimizer.h: Set/Get the CostFunctionConvergenceFactor. Algorithm terminates when the reduction in cost function is less than (factor * epsmcj) where epsmch is the machine precision. Typical values for factor: 1e+12 for low accuracy; 1e+7 for moderate accuracy and 1e+1 for extremely high accuracy. 1e+9 seems to work well., ", argstr="--costFunctionConvergenceFactor %f") projectedGradientTolerance = traits.Float(desc="From itkLBFGSBOptimizer.h: Set/Get the ProjectedGradientTolerance. Algorithm terminates when the project gradient is below the tolerance. Default lbfgsb value is 1e-5, but 1e-4 seems to work well., ", argstr="--projectedGradientTolerance %f") maximumNumberOfEvaluations = traits.Int(desc="Maximum number of evaluations for line search in lbfgsb optimizer.", argstr="--maximumNumberOfEvaluations %d") maximumNumberOfCorrections = traits.Int(desc="Maximum number of corrections in lbfgsb optimizer.", argstr="--maximumNumberOfCorrections %d") gui = traits.Bool(desc="Display intermediate image volumes for debugging. NOTE: This is not part of the standard build sytem, and probably does nothing on your installation.", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") metricSamplingStrategy = traits.Enum("Random", desc="It defines the method that registration filter uses to sample the input fixed image. Only Random is supported for now.", argstr="--metricSamplingStrategy %s") logFileReport = traits.Either(traits.Bool, File(), hash_files=False, desc="A file to write out final information report in CSV file: MetricName,MetricValue,FixedImageName,FixedMaskName,MovingImageName,MovingMaskName", argstr="--logFileReport %s") writeOutputTransformInFloat = traits.Bool(desc="By default, the output registration transforms (either the output composite transform or each transform component) are written to the disk in double precision. If this flag is ON, the output transforms will be written in single (float) precision. It is especially important if the output transform is a displacement field transform, or it is a composite transform that includes several displacement fields.", argstr="--writeOutputTransformInFloat ") class BRAINSFitOutputSpec(TraitedSpec): linearTransform = File(desc="(optional) Output estimated transform - in case the computed transform is not BSpline. NOTE: You must set at least one output object (transform and/or output volume).", exists=True) bsplineTransform = File(desc="(optional) Output estimated transform - in case the computed transform is BSpline. NOTE: You must set at least one output object (transform and/or output volume).", exists=True) outputVolume = File(desc="(optional) Output image: the moving image warped to the fixed image space. NOTE: You must set at least one output object (transform and/or output volume).", exists=True) outputFixedVolumeROI = File(desc="ROI that is automatically computed from the fixed image. Only available if Masking Option is ROIAUTO. Image areas where the mask volume has zero value are ignored during the registration.", exists=True) outputMovingVolumeROI = File(desc="ROI that is automatically computed from the moving image. Only available if Masking Option is ROIAUTO. Image areas where the mask volume has zero value are ignored during the registration.", exists=True) strippedOutputTransform = File(desc="Rigid component of the estimated affine transform. Can be used to rigidly register the moving image to the fixed image. NOTE: This value is overridden if either bsplineTransform or linearTransform is set.", exists=True) outputTransform = File(desc="(optional) Filename to which save the (optional) estimated transform. NOTE: You must select either the outputTransform or the outputVolume option.", exists=True) logFileReport = File(desc="A file to write out final information report in CSV file: MetricName,MetricValue,FixedImageName,FixedMaskName,MovingImageName,MovingMaskName", exists=True) class BRAINSFit(SEMLikeCommandLine): """title: General Registration (BRAINS) category: Registration description: Register a three-dimensional volume to a reference volume (Mattes Mutual Information by default). Full documentation avalable here: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSFit. Method described in BRAINSFit: Mutual Information Registrations of Whole-Brain 3D Images, Using the Insight Toolkit, Johnson H.J., Harris G., Williams K., The Insight Journal, 2007. http://hdl.handle.net/1926/1291 version: 3.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSFit license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson, hans-johnson -at- uiowa.edu, http://www.psychiatry.uiowa.edu acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); Gregory Harris(1), Vincent Magnotta(1,2,3); Andriy Fedorov(5) 1=University of Iowa Department of Psychiatry, 2=University of Iowa Department of Radiology, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering, 5=Surgical Planning Lab, Harvard """ input_spec = BRAINSFitInputSpec output_spec = BRAINSFitOutputSpec _cmd = " BRAINSFit " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'bsplineTransform': 'bsplineTransform.h5', 'outputTransform': 'outputTransform.h5', 'outputFixedVolumeROI': 'outputFixedVolumeROI.nii', 'strippedOutputTransform': 'strippedOutputTransform.h5', 'outputMovingVolumeROI': 'outputMovingVolumeROI.nii', 'linearTransform': 'linearTransform.h5', 'logFileReport': 'logFileReport'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/registration/brainsresample.py000066400000000000000000000100241257611314500264660ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSResampleInputSpec(CommandLineInputSpec): inputVolume = File(desc="Image To Warp", exists=True, argstr="--inputVolume %s") referenceVolume = File(desc="Reference image used only to define the output space. If not specified, the warping is done in the same space as the image to warp.", exists=True, argstr="--referenceVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Resulting deformed image", argstr="--outputVolume %s") pixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", "binary", desc="Specifies the pixel type for the input/output images. The \'binary\' pixel type uses a modified algorithm whereby the image is read in as unsigned char, a signed distance map is created, signed distance map is resampled, and then a thresholded image of type unsigned char is written to disk.", argstr="--pixelType %s") deformationVolume = File(desc="Displacement Field to be used to warp the image (ITKv3 or earlier)", exists=True, argstr="--deformationVolume %s") warpTransform = File(desc="Filename for the BRAINSFit transform (ITKv3 or earlier) or composite transform file (ITKv4)", exists=True, argstr="--warpTransform %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") inverseTransform = traits.Bool(desc="True/False is to compute inverse of given transformation. Default is false", argstr="--inverseTransform ") defaultValue = traits.Float(desc="Default voxel value", argstr="--defaultValue %f") gridSpacing = InputMultiPath( traits.Int, desc="Add warped grid to output image to help show the deformation that occured with specified spacing. A spacing of 0 in a dimension indicates that grid lines should be rendered to fall exactly (i.e. do not allow displacements off that plane). This is useful for makeing a 2D image of grid lines from the 3D space", sep=",", argstr="--gridSpacing %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSResampleOutputSpec(TraitedSpec): outputVolume = File(desc="Resulting deformed image", exists=True) class BRAINSResample(SEMLikeCommandLine): """title: Resample Image (BRAINS) category: Registration description: This program collects together three common image processing tasks that all involve resampling an image volume: Resampling to a new resolution and spacing, applying a transformation (using an ITK transform IO mechanisms) and Warping (using a vector image deformation field). Full documentation available here: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSResample. version: 3.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSResample license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Vincent Magnotta, Greg Harris, and Hans Johnson. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = BRAINSResampleInputSpec output_spec = BRAINSResampleOutputSpec _cmd = " BRAINSResample " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/registration/brainsresize.py000066400000000000000000000037771257611314500262000ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSResizeInputSpec(CommandLineInputSpec): inputVolume = File(desc="Image To Scale", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Resulting scaled image", argstr="--outputVolume %s") pixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", "binary", desc="Specifies the pixel type for the input/output images. The \'binary\' pixel type uses a modified algorithm whereby the image is read in as unsigned char, a signed distance map is created, signed distance map is resampled, and then a thresholded image of type unsigned char is written to disk.", argstr="--pixelType %s") scaleFactor = traits.Float(desc="The scale factor for the image spacing.", argstr="--scaleFactor %f") class BRAINSResizeOutputSpec(TraitedSpec): outputVolume = File(desc="Resulting scaled image", exists=True) class BRAINSResize(SEMLikeCommandLine): """title: Resize Image (BRAINS) category: Registration description: This program is useful for downsampling an image by a constant scale factor. version: 3.0.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Hans Johnson. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = BRAINSResizeInputSpec output_spec = BRAINSResizeOutputSpec _cmd = " BRAINSResize " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/registration/specialized.py000066400000000000000000000500771257611314500257670ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class VBRAINSDemonWarpInputSpec(CommandLineInputSpec): movingVolume = InputMultiPath(File(exists=True), desc="Required: input moving image", argstr="--movingVolume %s...") fixedVolume = InputMultiPath(File(exists=True), desc="Required: input fixed (target) image", argstr="--fixedVolume %s...") inputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="Input volumes will be typecast to this format: float|short|ushort|int|uchar", argstr="--inputPixelType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", argstr="--outputVolume %s") outputDisplacementFieldVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", argstr="--outputDisplacementFieldVolume %s") outputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="outputVolume will be typecast to this format: float|short|ushort|int|uchar", argstr="--outputPixelType %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") registrationFilterType = traits.Enum("Demons", "FastSymmetricForces", "Diffeomorphic", "LogDemons", "SymmetricLogDemons", desc="Registration Filter Type: Demons|FastSymmetricForces|Diffeomorphic|LogDemons|SymmetricLogDemons", argstr="--registrationFilterType %s") smoothDisplacementFieldSigma = traits.Float(desc="A gaussian smoothing value to be applied to the deformation feild at each iteration.", argstr="--smoothDisplacementFieldSigma %f") numberOfPyramidLevels = traits.Int(desc="Number of image pyramid levels to use in the multi-resolution registration.", argstr="--numberOfPyramidLevels %d") minimumFixedPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the fixed image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumFixedPyramid %s") minimumMovingPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the moving image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumMovingPyramid %s") arrayOfPyramidLevelIterations = InputMultiPath(traits.Int, desc="The number of iterations for each pyramid level", sep=",", argstr="--arrayOfPyramidLevelIterations %s") histogramMatch = traits.Bool(desc="Histogram Match the input images. This is suitable for images of the same modality that may have different absolute scales, but the same overall intensity profile.", argstr="--histogramMatch ") numberOfHistogramBins = traits.Int(desc="The number of histogram levels", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="The number of match points for histrogramMatch", argstr="--numberOfMatchPoints %d") medianFilterSize = InputMultiPath(traits.Int, desc="Median filter radius in all 3 directions. When images have a lot of salt and pepper noise, this step can improve the registration.", sep=",", argstr="--medianFilterSize %s") initializeWithDisplacementField = File(desc="Initial deformation field vector image file name", exists=True, argstr="--initializeWithDisplacementField %s") initializeWithTransform = File(desc="Initial Transform filename", exists=True, argstr="--initializeWithTransform %s") makeBOBF = traits.Bool(desc="Flag to make Brain-Only Background-Filled versions of the input and target volumes.", argstr="--makeBOBF ") fixedBinaryVolume = File(desc="Mask filename for desired region of interest in the Fixed image.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Mask filename for desired region of interest in the Moving image.", exists=True, argstr="--movingBinaryVolume %s") lowerThresholdForBOBF = traits.Int(desc="Lower threshold for performing BOBF", argstr="--lowerThresholdForBOBF %d") upperThresholdForBOBF = traits.Int(desc="Upper threshold for performing BOBF", argstr="--upperThresholdForBOBF %d") backgroundFillValue = traits.Int(desc="Replacement value to overwrite background when performing BOBF", argstr="--backgroundFillValue %d") seedForBOBF = InputMultiPath(traits.Int, desc="coordinates in all 3 directions for Seed when performing BOBF", sep=",", argstr="--seedForBOBF %s") neighborhoodForBOBF = InputMultiPath(traits.Int, desc="neighborhood in all 3 directions to be included when performing BOBF", sep=",", argstr="--neighborhoodForBOBF %s") outputDisplacementFieldPrefix = traits.Str(desc="Displacement field filename prefix for writing separate x, y, and z component images", argstr="--outputDisplacementFieldPrefix %s") outputCheckerboardVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", argstr="--outputCheckerboardVolume %s") checkerboardPatternSubdivisions = InputMultiPath(traits.Int, desc="Number of Checkerboard subdivisions in all 3 directions", sep=",", argstr="--checkerboardPatternSubdivisions %s") outputNormalized = traits.Bool(desc="Flag to warp and write the normalized images to output. In normalized images the image values are fit-scaled to be between 0 and the maximum storage type value.", argstr="--outputNormalized ") outputDebug = traits.Bool(desc="Flag to write debugging images after each step.", argstr="--outputDebug ") weightFactors = InputMultiPath(traits.Float, desc="Weight fatctors for each input images", sep=",", argstr="--weightFactors %s") gradient_type = traits.Enum("0", "1", "2", desc="Type of gradient used for computing the demons force (0 is symmetrized, 1 is fixed image, 2 is moving image)", argstr="--gradient_type %s") upFieldSmoothing = traits.Float(desc="Smoothing sigma for the update field at each iteration", argstr="--upFieldSmoothing %f") max_step_length = traits.Float(desc="Maximum length of an update vector (0: no restriction)", argstr="--max_step_length %f") use_vanilla_dem = traits.Bool(desc="Run vanilla demons algorithm", argstr="--use_vanilla_dem ") gui = traits.Bool(desc="Display intermediate image volumes for debugging", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") numberOfBCHApproximationTerms = traits.Int(desc="Number of terms in the BCH expansion", argstr="--numberOfBCHApproximationTerms %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class VBRAINSDemonWarpOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", exists=True) outputDisplacementFieldVolume = File(desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", exists=True) outputCheckerboardVolume = File(desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", exists=True) class VBRAINSDemonWarp(SEMLikeCommandLine): """title: Vector Demon Registration (BRAINS) category: Registration.Specialized description: This program finds a deformation field to warp a moving image onto a fixed image. The images must be of the same signal kind, and contain an image of the same kind of object. This program uses the Thirion Demons warp software in ITK, the Insight Toolkit. Additional information is available at: http://www.nitrc.org/projects/brainsdemonwarp. version: 3.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSDemonWarp license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Hans J. Johnson and Greg Harris. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = VBRAINSDemonWarpInputSpec output_spec = VBRAINSDemonWarpOutputSpec _cmd = " VBRAINSDemonWarp " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'outputCheckerboardVolume': 'outputCheckerboardVolume.nii', 'outputDisplacementFieldVolume': 'outputDisplacementFieldVolume.nrrd'} _redirect_x = False class BRAINSDemonWarpInputSpec(CommandLineInputSpec): movingVolume = File(desc="Required: input moving image", exists=True, argstr="--movingVolume %s") fixedVolume = File(desc="Required: input fixed (target) image", exists=True, argstr="--fixedVolume %s") inputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="Input volumes will be typecast to this format: float|short|ushort|int|uchar", argstr="--inputPixelType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", argstr="--outputVolume %s") outputDisplacementFieldVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", argstr="--outputDisplacementFieldVolume %s") outputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="outputVolume will be typecast to this format: float|short|ushort|int|uchar", argstr="--outputPixelType %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") registrationFilterType = traits.Enum("Demons", "FastSymmetricForces", "Diffeomorphic", desc="Registration Filter Type: Demons|FastSymmetricForces|Diffeomorphic", argstr="--registrationFilterType %s") smoothDisplacementFieldSigma = traits.Float(desc="A gaussian smoothing value to be applied to the deformation feild at each iteration.", argstr="--smoothDisplacementFieldSigma %f") numberOfPyramidLevels = traits.Int(desc="Number of image pyramid levels to use in the multi-resolution registration.", argstr="--numberOfPyramidLevels %d") minimumFixedPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the fixed image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumFixedPyramid %s") minimumMovingPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the moving image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumMovingPyramid %s") arrayOfPyramidLevelIterations = InputMultiPath(traits.Int, desc="The number of iterations for each pyramid level", sep=",", argstr="--arrayOfPyramidLevelIterations %s") histogramMatch = traits.Bool(desc="Histogram Match the input images. This is suitable for images of the same modality that may have different absolute scales, but the same overall intensity profile.", argstr="--histogramMatch ") numberOfHistogramBins = traits.Int(desc="The number of histogram levels", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="The number of match points for histrogramMatch", argstr="--numberOfMatchPoints %d") medianFilterSize = InputMultiPath(traits.Int, desc="Median filter radius in all 3 directions. When images have a lot of salt and pepper noise, this step can improve the registration.", sep=",", argstr="--medianFilterSize %s") initializeWithDisplacementField = File(desc="Initial deformation field vector image file name", exists=True, argstr="--initializeWithDisplacementField %s") initializeWithTransform = File(desc="Initial Transform filename", exists=True, argstr="--initializeWithTransform %s") maskProcessingMode = traits.Enum( "NOMASK", "ROIAUTO", "ROI", "BOBF", desc="What mode to use for using the masks: NOMASK|ROIAUTO|ROI|BOBF. If ROIAUTO is choosen, then the mask is implicitly defined using a otsu forground and hole filling algorithm. Where the Region Of Interest mode uses the masks to define what parts of the image should be used for computing the deformation field. Brain Only Background Fill uses the masks to pre-process the input images by clipping and filling in the background with a predefined value.", argstr="--maskProcessingMode %s") fixedBinaryVolume = File(desc="Mask filename for desired region of interest in the Fixed image.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Mask filename for desired region of interest in the Moving image.", exists=True, argstr="--movingBinaryVolume %s") lowerThresholdForBOBF = traits.Int(desc="Lower threshold for performing BOBF", argstr="--lowerThresholdForBOBF %d") upperThresholdForBOBF = traits.Int(desc="Upper threshold for performing BOBF", argstr="--upperThresholdForBOBF %d") backgroundFillValue = traits.Int(desc="Replacement value to overwrite background when performing BOBF", argstr="--backgroundFillValue %d") seedForBOBF = InputMultiPath(traits.Int, desc="coordinates in all 3 directions for Seed when performing BOBF", sep=",", argstr="--seedForBOBF %s") neighborhoodForBOBF = InputMultiPath(traits.Int, desc="neighborhood in all 3 directions to be included when performing BOBF", sep=",", argstr="--neighborhoodForBOBF %s") outputDisplacementFieldPrefix = traits.Str(desc="Displacement field filename prefix for writing separate x, y, and z component images", argstr="--outputDisplacementFieldPrefix %s") outputCheckerboardVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", argstr="--outputCheckerboardVolume %s") checkerboardPatternSubdivisions = InputMultiPath(traits.Int, desc="Number of Checkerboard subdivisions in all 3 directions", sep=",", argstr="--checkerboardPatternSubdivisions %s") outputNormalized = traits.Bool(desc="Flag to warp and write the normalized images to output. In normalized images the image values are fit-scaled to be between 0 and the maximum storage type value.", argstr="--outputNormalized ") outputDebug = traits.Bool(desc="Flag to write debugging images after each step.", argstr="--outputDebug ") gradient_type = traits.Enum("0", "1", "2", desc="Type of gradient used for computing the demons force (0 is symmetrized, 1 is fixed image, 2 is moving image)", argstr="--gradient_type %s") upFieldSmoothing = traits.Float(desc="Smoothing sigma for the update field at each iteration", argstr="--upFieldSmoothing %f") max_step_length = traits.Float(desc="Maximum length of an update vector (0: no restriction)", argstr="--max_step_length %f") use_vanilla_dem = traits.Bool(desc="Run vanilla demons algorithm", argstr="--use_vanilla_dem ") gui = traits.Bool(desc="Display intermediate image volumes for debugging", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") numberOfBCHApproximationTerms = traits.Int(desc="Number of terms in the BCH expansion", argstr="--numberOfBCHApproximationTerms %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSDemonWarpOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", exists=True) outputDisplacementFieldVolume = File(desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", exists=True) outputCheckerboardVolume = File(desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", exists=True) class BRAINSDemonWarp(SEMLikeCommandLine): """title: Demon Registration (BRAINS) category: Registration.Specialized description: This program finds a deformation field to warp a moving image onto a fixed image. The images must be of the same signal kind, and contain an image of the same kind of object. This program uses the Thirion Demons warp software in ITK, the Insight Toolkit. Additional information is available at: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSDemonWarp. version: 3.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BRAINSDemonWarp license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Hans J. Johnson and Greg Harris. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = BRAINSDemonWarpInputSpec output_spec = BRAINSDemonWarpOutputSpec _cmd = " BRAINSDemonWarp " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'outputCheckerboardVolume': 'outputCheckerboardVolume.nii', 'outputDisplacementFieldVolume': 'outputDisplacementFieldVolume.nrrd'} _redirect_x = False class BRAINSTransformFromFiducialsInputSpec(CommandLineInputSpec): fixedLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the fixed image", argstr="--fixedLandmarks %s...") movingLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the moving image", argstr="--movingLandmarks %s...") saveTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Save the transform that results from registration", argstr="--saveTransform %s") transformType = traits.Enum("Translation", "Rigid", "Similarity", desc="Type of transform to produce", argstr="--transformType %s") fixedLandmarksFile = File(desc="An fcsv formatted file with a list of landmark points.", exists=True, argstr="--fixedLandmarksFile %s") movingLandmarksFile = File(desc="An fcsv formatted file with a list of landmark points.", exists=True, argstr="--movingLandmarksFile %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSTransformFromFiducialsOutputSpec(TraitedSpec): saveTransform = File(desc="Save the transform that results from registration", exists=True) class BRAINSTransformFromFiducials(SEMLikeCommandLine): """title: Fiducial Registration (BRAINS) category: Registration.Specialized description: Computes a rigid, similarity or affine transform from a matched list of fiducials version: 0.1.0.$Revision$ documentation-url: http://www.slicer.org/slicerWiki/index.php/Modules:TransformFromFiducials-Documentation-3.6 contributor: Casey B Goodlett acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = BRAINSTransformFromFiducialsInputSpec output_spec = BRAINSTransformFromFiducialsOutputSpec _cmd = " BRAINSTransformFromFiducials " _outputs_filenames = {'saveTransform': 'saveTransform.h5'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/registration/tests/000077500000000000000000000000001257611314500242525ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/registration/tests/test_auto_BRAINSDemonWarp.py000066400000000000000000000076221257611314500315150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.specialized import BRAINSDemonWarp def test_BRAINSDemonWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), arrayOfPyramidLevelIterations=dict(argstr='--arrayOfPyramidLevelIterations %s', sep=',', ), backgroundFillValue=dict(argstr='--backgroundFillValue %d', ), checkerboardPatternSubdivisions=dict(argstr='--checkerboardPatternSubdivisions %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s', ), gradient_type=dict(argstr='--gradient_type %s', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initializeWithDisplacementField=dict(argstr='--initializeWithDisplacementField %s', ), initializeWithTransform=dict(argstr='--initializeWithTransform %s', ), inputPixelType=dict(argstr='--inputPixelType %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), lowerThresholdForBOBF=dict(argstr='--lowerThresholdForBOBF %d', ), maskProcessingMode=dict(argstr='--maskProcessingMode %s', ), max_step_length=dict(argstr='--max_step_length %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), minimumFixedPyramid=dict(argstr='--minimumFixedPyramid %s', sep=',', ), minimumMovingPyramid=dict(argstr='--minimumMovingPyramid %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s', ), neighborhoodForBOBF=dict(argstr='--neighborhoodForBOBF %s', sep=',', ), numberOfBCHApproximationTerms=dict(argstr='--numberOfBCHApproximationTerms %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfPyramidLevels=dict(argstr='--numberOfPyramidLevels %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputCheckerboardVolume=dict(argstr='--outputCheckerboardVolume %s', hash_files=False, ), outputDebug=dict(argstr='--outputDebug ', ), outputDisplacementFieldPrefix=dict(argstr='--outputDisplacementFieldPrefix %s', ), outputDisplacementFieldVolume=dict(argstr='--outputDisplacementFieldVolume %s', hash_files=False, ), outputNormalized=dict(argstr='--outputNormalized ', ), outputPixelType=dict(argstr='--outputPixelType %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), promptUser=dict(argstr='--promptUser ', ), registrationFilterType=dict(argstr='--registrationFilterType %s', ), seedForBOBF=dict(argstr='--seedForBOBF %s', sep=',', ), smoothDisplacementFieldSigma=dict(argstr='--smoothDisplacementFieldSigma %f', ), terminal_output=dict(nohash=True, ), upFieldSmoothing=dict(argstr='--upFieldSmoothing %f', ), upperThresholdForBOBF=dict(argstr='--upperThresholdForBOBF %d', ), use_vanilla_dem=dict(argstr='--use_vanilla_dem ', ), ) inputs = BRAINSDemonWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSDemonWarp_outputs(): output_map = dict(outputCheckerboardVolume=dict(), outputDisplacementFieldVolume=dict(), outputVolume=dict(), ) outputs = BRAINSDemonWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/registration/tests/test_auto_BRAINSFit.py000066400000000000000000000131461257611314500303410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.brainsfit import BRAINSFit def test_BRAINSFit_inputs(): input_map = dict(ROIAutoClosingSize=dict(argstr='--ROIAutoClosingSize %f', ), ROIAutoDilateSize=dict(argstr='--ROIAutoDilateSize %f', ), args=dict(argstr='%s', ), backgroundFillValue=dict(argstr='--backgroundFillValue %f', ), bsplineTransform=dict(argstr='--bsplineTransform %s', hash_files=False, ), costFunctionConvergenceFactor=dict(argstr='--costFunctionConvergenceFactor %f', ), costMetric=dict(argstr='--costMetric %s', ), debugLevel=dict(argstr='--debugLevel %d', ), environ=dict(nohash=True, usedefault=True, ), failureExitCode=dict(argstr='--failureExitCode %d', ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s', ), fixedVolume2=dict(argstr='--fixedVolume2 %s', ), fixedVolumeTimeIndex=dict(argstr='--fixedVolumeTimeIndex %d', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialTransform=dict(argstr='--initialTransform %s', ), initializeRegistrationByCurrentGenericTransform=dict(argstr='--initializeRegistrationByCurrentGenericTransform ', ), initializeTransformMode=dict(argstr='--initializeTransformMode %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), linearTransform=dict(argstr='--linearTransform %s', hash_files=False, ), logFileReport=dict(argstr='--logFileReport %s', hash_files=False, ), maskInferiorCutOffFromCenter=dict(argstr='--maskInferiorCutOffFromCenter %f', ), maskProcessingMode=dict(argstr='--maskProcessingMode %s', ), maxBSplineDisplacement=dict(argstr='--maxBSplineDisplacement %f', ), maximumNumberOfCorrections=dict(argstr='--maximumNumberOfCorrections %d', ), maximumNumberOfEvaluations=dict(argstr='--maximumNumberOfEvaluations %d', ), maximumStepLength=dict(argstr='--maximumStepLength %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), metricSamplingStrategy=dict(argstr='--metricSamplingStrategy %s', ), minimumStepLength=dict(argstr='--minimumStepLength %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s', ), movingVolume2=dict(argstr='--movingVolume2 %s', ), movingVolumeTimeIndex=dict(argstr='--movingVolumeTimeIndex %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfIterations=dict(argstr='--numberOfIterations %s', sep=',', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfSamples=dict(argstr='--numberOfSamples %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputFixedVolumeROI=dict(argstr='--outputFixedVolumeROI %s', hash_files=False, ), outputMovingVolumeROI=dict(argstr='--outputMovingVolumeROI %s', hash_files=False, ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), outputVolumePixelType=dict(argstr='--outputVolumePixelType %s', ), projectedGradientTolerance=dict(argstr='--projectedGradientTolerance %f', ), promptUser=dict(argstr='--promptUser ', ), relaxationFactor=dict(argstr='--relaxationFactor %f', ), removeIntensityOutliers=dict(argstr='--removeIntensityOutliers %f', ), reproportionScale=dict(argstr='--reproportionScale %f', ), samplingPercentage=dict(argstr='--samplingPercentage %f', ), scaleOutputValues=dict(argstr='--scaleOutputValues ', ), skewScale=dict(argstr='--skewScale %f', ), splineGridSize=dict(argstr='--splineGridSize %s', sep=',', ), strippedOutputTransform=dict(argstr='--strippedOutputTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', sep=',', ), translationScale=dict(argstr='--translationScale %f', ), useAffine=dict(argstr='--useAffine ', ), useBSpline=dict(argstr='--useBSpline ', ), useComposite=dict(argstr='--useComposite ', ), useROIBSpline=dict(argstr='--useROIBSpline ', ), useRigid=dict(argstr='--useRigid ', ), useScaleSkewVersor3D=dict(argstr='--useScaleSkewVersor3D ', ), useScaleVersor3D=dict(argstr='--useScaleVersor3D ', ), useSyN=dict(argstr='--useSyN ', ), writeOutputTransformInFloat=dict(argstr='--writeOutputTransformInFloat ', ), writeTransformOnFailure=dict(argstr='--writeTransformOnFailure ', ), ) inputs = BRAINSFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSFit_outputs(): output_map = dict(bsplineTransform=dict(), linearTransform=dict(), logFileReport=dict(), outputFixedVolumeROI=dict(), outputMovingVolumeROI=dict(), outputTransform=dict(), outputVolume=dict(), strippedOutputTransform=dict(), ) outputs = BRAINSFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/registration/tests/test_auto_BRAINSResample.py000066400000000000000000000031541257611314500313650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.brainsresample import BRAINSResample def test_BRAINSResample_inputs(): input_map = dict(args=dict(argstr='%s', ), defaultValue=dict(argstr='--defaultValue %f', ), deformationVolume=dict(argstr='--deformationVolume %s', ), environ=dict(nohash=True, usedefault=True, ), gridSpacing=dict(argstr='--gridSpacing %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), inverseTransform=dict(argstr='--inverseTransform ', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), pixelType=dict(argstr='--pixelType %s', ), referenceVolume=dict(argstr='--referenceVolume %s', ), terminal_output=dict(nohash=True, ), warpTransform=dict(argstr='--warpTransform %s', ), ) inputs = BRAINSResample.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSResample_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSResample.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/registration/tests/test_auto_BRAINSResize.py000066400000000000000000000022341257611314500310540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.brainsresize import BRAINSResize def test_BRAINSResize_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), pixelType=dict(argstr='--pixelType %s', ), scaleFactor=dict(argstr='--scaleFactor %f', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSResize.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSResize_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSResize.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_BRAINSTransformFromFiducials.py000066400000000000000000000027251257611314500341640ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/registration/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.specialized import BRAINSTransformFromFiducials def test_BRAINSTransformFromFiducials_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedLandmarks=dict(argstr='--fixedLandmarks %s...', ), fixedLandmarksFile=dict(argstr='--fixedLandmarksFile %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), movingLandmarks=dict(argstr='--movingLandmarks %s...', ), movingLandmarksFile=dict(argstr='--movingLandmarksFile %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), saveTransform=dict(argstr='--saveTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), ) inputs = BRAINSTransformFromFiducials.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSTransformFromFiducials_outputs(): output_map = dict(saveTransform=dict(), ) outputs = BRAINSTransformFromFiducials.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/registration/tests/test_auto_VBRAINSDemonWarp.py000066400000000000000000000077171257611314500316500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.registration.specialized import VBRAINSDemonWarp def test_VBRAINSDemonWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), arrayOfPyramidLevelIterations=dict(argstr='--arrayOfPyramidLevelIterations %s', sep=',', ), backgroundFillValue=dict(argstr='--backgroundFillValue %d', ), checkerboardPatternSubdivisions=dict(argstr='--checkerboardPatternSubdivisions %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s...', ), gradient_type=dict(argstr='--gradient_type %s', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initializeWithDisplacementField=dict(argstr='--initializeWithDisplacementField %s', ), initializeWithTransform=dict(argstr='--initializeWithTransform %s', ), inputPixelType=dict(argstr='--inputPixelType %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), lowerThresholdForBOBF=dict(argstr='--lowerThresholdForBOBF %d', ), makeBOBF=dict(argstr='--makeBOBF ', ), max_step_length=dict(argstr='--max_step_length %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), minimumFixedPyramid=dict(argstr='--minimumFixedPyramid %s', sep=',', ), minimumMovingPyramid=dict(argstr='--minimumMovingPyramid %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s...', ), neighborhoodForBOBF=dict(argstr='--neighborhoodForBOBF %s', sep=',', ), numberOfBCHApproximationTerms=dict(argstr='--numberOfBCHApproximationTerms %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfPyramidLevels=dict(argstr='--numberOfPyramidLevels %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputCheckerboardVolume=dict(argstr='--outputCheckerboardVolume %s', hash_files=False, ), outputDebug=dict(argstr='--outputDebug ', ), outputDisplacementFieldPrefix=dict(argstr='--outputDisplacementFieldPrefix %s', ), outputDisplacementFieldVolume=dict(argstr='--outputDisplacementFieldVolume %s', hash_files=False, ), outputNormalized=dict(argstr='--outputNormalized ', ), outputPixelType=dict(argstr='--outputPixelType %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), promptUser=dict(argstr='--promptUser ', ), registrationFilterType=dict(argstr='--registrationFilterType %s', ), seedForBOBF=dict(argstr='--seedForBOBF %s', sep=',', ), smoothDisplacementFieldSigma=dict(argstr='--smoothDisplacementFieldSigma %f', ), terminal_output=dict(nohash=True, ), upFieldSmoothing=dict(argstr='--upFieldSmoothing %f', ), upperThresholdForBOBF=dict(argstr='--upperThresholdForBOBF %d', ), use_vanilla_dem=dict(argstr='--use_vanilla_dem ', ), weightFactors=dict(argstr='--weightFactors %s', sep=',', ), ) inputs = VBRAINSDemonWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VBRAINSDemonWarp_outputs(): output_map = dict(outputCheckerboardVolume=dict(), outputDisplacementFieldVolume=dict(), outputVolume=dict(), ) outputs = VBRAINSDemonWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/000077500000000000000000000000001257611314500230735ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/segmentation/__init__.py000066400000000000000000000002751257611314500252100ustar00rootroot00000000000000from specialized import BRAINSCut, BRAINSROIAuto, BRAINSConstellationDetector, BRAINSCreateLabelMapFromProbabilityMaps, BinaryMaskEditorBasedOnLandmarks, BRAINSMultiSTAPLE, BRAINSABC, ESLR nipype-0.11.0/nipype/interfaces/semtools/segmentation/specialized.py000066400000000000000000001053511257611314500257460ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSCutInputSpec(CommandLineInputSpec): netConfiguration = File(desc="XML File defining BRAINSCut parameters. OLD NAME. PLEASE USE modelConfigurationFilename instead.", exists=True, argstr="--netConfiguration %s") modelConfigurationFilename = File(desc="XML File defining BRAINSCut parameters", exists=True, argstr="--modelConfigurationFilename %s") trainModelStartIndex = traits.Int(desc="Starting iteration for training", argstr="--trainModelStartIndex %d") verbose = traits.Int(desc="print out some debugging information", argstr="--verbose %d") multiStructureThreshold = traits.Bool(desc="multiStructureThreshold module to deal with overlaping area", argstr="--multiStructureThreshold ") histogramEqualization = traits.Bool(desc="A Histogram Equalization process could be added to the creating/applying process from Subject To Atlas. Default is false, which genreate input vectors without Histogram Equalization. ", argstr="--histogramEqualization ") computeSSEOn = traits.Bool(desc="compute Sum of Square Error (SSE) along the trained model until the number of iteration given in the modelConfigurationFilename file", argstr="--computeSSEOn ") generateProbability = traits.Bool(desc="Generate probability map", argstr="--generateProbability ") createVectors = traits.Bool(desc="create vectors for training neural net", argstr="--createVectors ") trainModel = traits.Bool(desc="train the neural net", argstr="--trainModel ") NoTrainingVectorShuffling = traits.Bool(desc="If this flag is on, there will be no shuffling.", argstr="--NoTrainingVectorShuffling ") applyModel = traits.Bool(desc="apply the neural net", argstr="--applyModel ") validate = traits.Bool(desc="validate data set.Just need for the first time run ( This is for validation of xml file and not working yet )", argstr="--validate ") method = traits.Enum("RandomForest", "ANN", argstr="--method %s") numberOfTrees = traits.Int(desc=" Random tree: number of trees. This is to be used when only one model with specified depth wish to be created. ", argstr="--numberOfTrees %d") randomTreeDepth = traits.Int(desc=" Random tree depth. This is to be used when only one model with specified depth wish to be created. ", argstr="--randomTreeDepth %d") modelFilename = traits.Str(desc=" model file name given from user (not by xml configuration file) ", argstr="--modelFilename %s") class BRAINSCutOutputSpec(TraitedSpec): pass class BRAINSCut(SEMLikeCommandLine): """title: BRAINSCut (BRAINS) category: Segmentation.Specialized description: Automatic Segmentation using neural networks version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Vince Magnotta, Hans Johnson, Greg Harris, Kent Williams, Eunyoung Regina Kim """ input_spec = BRAINSCutInputSpec output_spec = BRAINSCutOutputSpec _cmd = " BRAINSCut " _outputs_filenames = {} _redirect_x = False class BRAINSROIAutoInputSpec(CommandLineInputSpec): inputVolume = File(desc="The input image for finding the largest region filled mask.", exists=True, argstr="--inputVolume %s") outputROIMaskVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The ROI automatically found from the input image.", argstr="--outputROIMaskVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The inputVolume with optional [maskOutput|cropOutput] to the region of the brain mask.", argstr="--outputVolume %s") maskOutput = traits.Bool(desc="The inputVolume multiplied by the ROI mask.", argstr="--maskOutput ") cropOutput = traits.Bool(desc="The inputVolume cropped to the region of the ROI mask.", argstr="--cropOutput ") otsuPercentileThreshold = traits.Float(desc="Parameter to the Otsu threshold algorithm.", argstr="--otsuPercentileThreshold %f") thresholdCorrectionFactor = traits.Float(desc="A factor to scale the Otsu algorithm's result threshold, in case clipping mangles the image.", argstr="--thresholdCorrectionFactor %f") closingSize = traits.Float(desc="The Closing Size (in millimeters) for largest connected filled mask. This value is divided by image spacing and rounded to the next largest voxel number.", argstr="--closingSize %f") ROIAutoDilateSize = traits.Float( desc="This flag is only relavent when using ROIAUTO mode for initializing masks. It defines the final dilation size to capture a bit of background outside the tissue region. At setting of 10mm has been shown to help regularize a BSpline registration type so that there is some background constraints to match the edges of the head better.", argstr="--ROIAutoDilateSize %f") outputVolumePixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", desc="The output image Pixel Type is the scalar datatype for representation of the Output Volume.", argstr="--outputVolumePixelType %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSROIAutoOutputSpec(TraitedSpec): outputROIMaskVolume = File(desc="The ROI automatically found from the input image.", exists=True) outputVolume = File(desc="The inputVolume with optional [maskOutput|cropOutput] to the region of the brain mask.", exists=True) class BRAINSROIAuto(SEMLikeCommandLine): """title: Foreground masking (BRAINS) category: Segmentation.Specialized description: This program is used to create a mask over the most prominant forground region in an image. This is accomplished via a combination of otsu thresholding and a closing operation. More documentation is available here: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ForegroundMasking. version: 2.4.1 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson, hans-johnson -at- uiowa.edu, http://www.psychiatry.uiowa.edu acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); Gregory Harris(1), Vincent Magnotta(1,2,3); Andriy Fedorov(5), fedorov -at- bwh.harvard.edu (Slicer integration); (1=University of Iowa Department of Psychiatry, 2=University of Iowa Department of Radiology, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering, 5=Surgical Planning Lab, Harvard) """ input_spec = BRAINSROIAutoInputSpec output_spec = BRAINSROIAutoOutputSpec _cmd = " BRAINSROIAuto " _outputs_filenames = {'outputVolume': 'outputVolume.nii', 'outputROIMaskVolume': 'outputROIMaskVolume.nii'} _redirect_x = False class BRAINSConstellationDetectorInputSpec(CommandLineInputSpec): houghEyeDetectorMode = traits.Int(desc=", This flag controls the mode of Hough eye detector. By default, value of 1 is for T1W images, while the value of 0 is for T2W and PD images., ", argstr="--houghEyeDetectorMode %d") inputTemplateModel = File(desc="User-specified template model., ", exists=True, argstr="--inputTemplateModel %s") LLSModel = File(desc="Linear least squares model filename in HD5 format", exists=True, argstr="--LLSModel %s") inputVolume = File(desc="Input image in which to find ACPC points", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File( ), hash_files=False, desc="ACPC-aligned output image with the same voxels, but updated origin, and direction cosign so that the AC point would fall at the physical location (0.0,0.0,0.0), and the mid-sagital plane is the plane where physical L/R coordinate is 0.0.", argstr="--outputVolume %s") outputResampledVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="ACPC-aligned output image in a resampled unifor space. Currently this is a 1mm, 256^3, Identity direction image.", argstr="--outputResampledVolume %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="The filename for the original space to ACPC alignment to be written (in .h5 format)., ", argstr="--outputTransform %s") outputLandmarksInInputSpace = traits.Either(traits.Bool, File( ), hash_files=False, desc=", The filename for the new subject-specific landmark definition file in the same format produced by Slicer3 (.fcsv) with the landmarks in the original image space (the detected RP, AC, PC, and VN4) in it to be written., ", argstr="--outputLandmarksInInputSpace %s") outputLandmarksInACPCAlignedSpace = traits.Either(traits.Bool, File( ), hash_files=False, desc=", The filename for the new subject-specific landmark definition file in the same format produced by Slicer3 (.fcsv) with the landmarks in the output image space (the detected RP, AC, PC, and VN4) in it to be written., ", argstr="--outputLandmarksInACPCAlignedSpace %s") outputMRML = traits.Either(traits.Bool, File( ), hash_files=False, desc=", The filename for the new subject-specific scene definition file in the same format produced by Slicer3 (in .mrml format). Only the components that were specified by the user on command line would be generated. Compatible components include inputVolume, outputVolume, outputLandmarksInInputSpace, outputLandmarksInACPCAlignedSpace, and outputTransform., ", argstr="--outputMRML %s") outputVerificationScript = traits.Either( traits.Bool, File(), hash_files=False, desc=", The filename for the Slicer3 script that verifies the aligned landmarks against the aligned image file. This will happen only in conjunction with saveOutputLandmarks and an outputVolume., ", argstr="--outputVerificationScript %s") mspQualityLevel = traits.Int( desc=", Flag cotrols how agressive the MSP is estimated. 0=quick estimate (9 seconds), 1=normal estimate (11 seconds), 2=great estimate (22 seconds), 3=best estimate (58 seconds), NOTE: -1= Prealigned so no estimate!., ", argstr="--mspQualityLevel %d") otsuPercentileThreshold = traits.Float(desc=", This is a parameter to FindLargestForegroundFilledMask, which is employed when acLowerBound is set and an outputUntransformedClippedVolume is requested., ", argstr="--otsuPercentileThreshold %f") acLowerBound = traits.Float( desc=", When generating a resampled output image, replace the image with the BackgroundFillValue everywhere below the plane This Far in physical units (millimeters) below (inferior to) the AC point (as found by the model.) The oversize default was chosen to have no effect. Based on visualizing a thousand masks in the IPIG study, we recommend a limit no smaller than 80.0 mm., ", argstr="--acLowerBound %f") cutOutHeadInOutputVolume = traits.Bool(desc=", Flag to cut out just the head tissue when producing an (un)transformed clipped volume., ", argstr="--cutOutHeadInOutputVolume ") outputUntransformedClippedVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output image in which to store neck-clipped input image, with the use of --acLowerBound and maybe --cutOutHeadInUntransformedVolume.", argstr="--outputUntransformedClippedVolume %s") rescaleIntensities = traits.Bool(desc=", Flag to turn on rescaling image intensities on input., ", argstr="--rescaleIntensities ") trimRescaledIntensities = traits.Float( desc=", Turn on clipping the rescaled image one-tailed on input. Units of standard deviations above the mean. Very large values are very permissive. Non-positive value turns clipping off. Defaults to removing 0.00001 of a normal tail above the mean., ", argstr="--trimRescaledIntensities %f") rescaleIntensitiesOutputRange = InputMultiPath( traits.Int, desc=", This pair of integers gives the lower and upper bounds on the signal portion of the output image. Out-of-field voxels are taken from BackgroundFillValue., ", sep=",", argstr="--rescaleIntensitiesOutputRange %s") BackgroundFillValue = traits.Str(desc="Fill the background of image with specified short int value. Enter number or use BIGNEG for a large negative number.", argstr="--BackgroundFillValue %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") forceACPoint = InputMultiPath(traits.Float, desc=", Use this flag to manually specify the AC point from the original image on the command line., ", sep=",", argstr="--forceACPoint %s") forcePCPoint = InputMultiPath(traits.Float, desc=", Use this flag to manually specify the PC point from the original image on the command line., ", sep=",", argstr="--forcePCPoint %s") forceVN4Point = InputMultiPath(traits.Float, desc=", Use this flag to manually specify the VN4 point from the original image on the command line., ", sep=",", argstr="--forceVN4Point %s") forceRPPoint = InputMultiPath(traits.Float, desc=", Use this flag to manually specify the RP point from the original image on the command line., ", sep=",", argstr="--forceRPPoint %s") inputLandmarksEMSP = File( desc=", The filename for the new subject-specific landmark definition file in the same format produced by Slicer3 (in .fcsv) with the landmarks in the estimated MSP aligned space to be loaded. The detector will only process landmarks not enlisted on the file., ", exists=True, argstr="--inputLandmarksEMSP %s") forceHoughEyeDetectorReportFailure = traits.Bool(desc=", Flag indicates whether the Hough eye detector should report failure, ", argstr="--forceHoughEyeDetectorReportFailure ") rmpj = traits.Float(desc=", Search radius for MPJ in unit of mm, ", argstr="--rmpj %f") rac = traits.Float(desc=", Search radius for AC in unit of mm, ", argstr="--rac %f") rpc = traits.Float(desc=", Search radius for PC in unit of mm, ", argstr="--rpc %f") rVN4 = traits.Float(desc=", Search radius for VN4 in unit of mm, ", argstr="--rVN4 %f") debug = traits.Bool(desc=", Show internal debugging information., ", argstr="--debug ") verbose = traits.Bool(desc=", Show more verbose output, ", argstr="--verbose ") writeBranded2DImage = traits.Either(traits.Bool, File(), hash_files=False, desc=", The filename for the 2D .png branded midline debugging image. This will happen only in conjunction with requesting an outputVolume., ", argstr="--writeBranded2DImage %s") resultsDir = traits.Either(traits.Bool, Directory(), hash_files=False, desc=", The directory for the debuging images to be written., ", argstr="--resultsDir %s") writedebuggingImagesLevel = traits.Int(desc=", This flag controls if debugging images are produced. By default value of 0 is no images. Anything greater than zero will be increasing level of debugging images., ", argstr="--writedebuggingImagesLevel %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") atlasVolume = File(desc="Atlas volume image to be used for BRAINSFit registration", exists=True, argstr="--atlasVolume %s") atlasLandmarks = File(desc="Atlas landmarks to be used for BRAINSFit registration initialization, ", exists=True, argstr="--atlasLandmarks %s") atlasLandmarkWeights = File(desc="Weights associated with atlas landmarks to be used for BRAINSFit registration initialization, ", exists=True, argstr="--atlasLandmarkWeights %s") class BRAINSConstellationDetectorOutputSpec(TraitedSpec): outputVolume = File(desc="ACPC-aligned output image with the same voxels, but updated origin, and direction cosign so that the AC point would fall at the physical location (0.0,0.0,0.0), and the mid-sagital plane is the plane where physical L/R coordinate is 0.0.", exists=True) outputResampledVolume = File(desc="ACPC-aligned output image in a resampled unifor space. Currently this is a 1mm, 256^3, Identity direction image.", exists=True) outputTransform = File(desc="The filename for the original space to ACPC alignment to be written (in .h5 format)., ", exists=True) outputLandmarksInInputSpace = File( desc=", The filename for the new subject-specific landmark definition file in the same format produced by Slicer3 (.fcsv) with the landmarks in the original image space (the detected RP, AC, PC, and VN4) in it to be written., ", exists=True) outputLandmarksInACPCAlignedSpace = File( desc=", The filename for the new subject-specific landmark definition file in the same format produced by Slicer3 (.fcsv) with the landmarks in the output image space (the detected RP, AC, PC, and VN4) in it to be written., ", exists=True) outputMRML = File( desc=", The filename for the new subject-specific scene definition file in the same format produced by Slicer3 (in .mrml format). Only the components that were specified by the user on command line would be generated. Compatible components include inputVolume, outputVolume, outputLandmarksInInputSpace, outputLandmarksInACPCAlignedSpace, and outputTransform., ", exists=True) outputVerificationScript = File(desc=", The filename for the Slicer3 script that verifies the aligned landmarks against the aligned image file. This will happen only in conjunction with saveOutputLandmarks and an outputVolume., ", exists=True) outputUntransformedClippedVolume = File(desc="Output image in which to store neck-clipped input image, with the use of --acLowerBound and maybe --cutOutHeadInUntransformedVolume.", exists=True) writeBranded2DImage = File(desc=", The filename for the 2D .png branded midline debugging image. This will happen only in conjunction with requesting an outputVolume., ", exists=True) resultsDir = Directory(desc=", The directory for the debuging images to be written., ", exists=True) class BRAINSConstellationDetector(SEMLikeCommandLine): """title: Brain Landmark Constellation Detector (BRAINS) category: Segmentation.Specialized description: This program will find the mid-sagittal plane, a constellation of landmarks in a volume, and create an AC/PC aligned data set with the AC point at the center of the voxel lattice (labeled at the origin of the image physical space.) Part of this work is an extention of the algorithms originally described by Dr. Babak A. Ardekani, Alvin H. Bachman, Model-based automatic detection of the anterior and posterior commissures on MRI scans, NeuroImage, Volume 46, Issue 3, 1 July 2009, Pages 677-682, ISSN 1053-8119, DOI: 10.1016/j.neuroimage.2009.02.030. (http://www.sciencedirect.com/science/article/B6WNP-4VRP25C-4/2/8207b962a38aa83c822c6379bc43fe4c) version: 1.0 documentation-url: http://www.nitrc.org/projects/brainscdetector/ """ input_spec = BRAINSConstellationDetectorInputSpec output_spec = BRAINSConstellationDetectorOutputSpec _cmd = " BRAINSConstellationDetector " _outputs_filenames = {'outputVolume': 'outputVolume.nii.gz', 'outputMRML': 'outputMRML.mrml', 'resultsDir': 'resultsDir', 'outputResampledVolume': 'outputResampledVolume.nii.gz', 'outputTransform': 'outputTransform.h5', 'writeBranded2DImage': 'writeBranded2DImage.png', 'outputLandmarksInACPCAlignedSpace': 'outputLandmarksInACPCAlignedSpace.fcsv', 'outputLandmarksInInputSpace': 'outputLandmarksInInputSpace.fcsv', 'outputUntransformedClippedVolume': 'outputUntransformedClippedVolume.nii.gz', 'outputVerificationScript': 'outputVerificationScript.sh'} _redirect_x = False class BRAINSCreateLabelMapFromProbabilityMapsInputSpec(CommandLineInputSpec): inputProbabilityVolume = InputMultiPath(File(exists=True), desc="The list of proobabilityimages.", argstr="--inputProbabilityVolume %s...") priorLabelCodes = InputMultiPath(traits.Int, desc="A list of PriorLabelCode values used for coding the output label images", sep=",", argstr="--priorLabelCodes %s") foregroundPriors = InputMultiPath(traits.Int, desc="A list: For each Prior Label, 1 if foreground, 0 if background", sep=",", argstr="--foregroundPriors %s") nonAirRegionMask = File(desc="a mask representing the \'NonAirRegion\' -- Just force pixels in this region to zero", exists=True, argstr="--nonAirRegionMask %s") inclusionThreshold = traits.Float(desc="tolerance for inclusion", argstr="--inclusionThreshold %f") dirtyLabelVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="the labels prior to cleaning", argstr="--dirtyLabelVolume %s") cleanLabelVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="the foreground labels volume", argstr="--cleanLabelVolume %s") class BRAINSCreateLabelMapFromProbabilityMapsOutputSpec(TraitedSpec): dirtyLabelVolume = File(desc="the labels prior to cleaning", exists=True) cleanLabelVolume = File(desc="the foreground labels volume", exists=True) class BRAINSCreateLabelMapFromProbabilityMaps(SEMLikeCommandLine): """title: Create Label Map From Probability Maps (BRAINS) category: Segmentation.Specialized description: Given A list of Probability Maps, generate a LabelMap. """ input_spec = BRAINSCreateLabelMapFromProbabilityMapsInputSpec output_spec = BRAINSCreateLabelMapFromProbabilityMapsOutputSpec _cmd = " BRAINSCreateLabelMapFromProbabilityMaps " _outputs_filenames = {'dirtyLabelVolume': 'dirtyLabelVolume.nii', 'cleanLabelVolume': 'cleanLabelVolume.nii'} _redirect_x = False class BinaryMaskEditorBasedOnLandmarksInputSpec(CommandLineInputSpec): inputBinaryVolume = File(desc="Input binary image in which to be edited", exists=True, argstr="--inputBinaryVolume %s") outputBinaryVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output binary image in which to be edited", argstr="--outputBinaryVolume %s") inputLandmarksFilename = File(desc=" The filename for the landmark definition file in the same format produced by Slicer3 (.fcsv). ", exists=True, argstr="--inputLandmarksFilename %s") inputLandmarkNames = InputMultiPath(traits.Str, desc=" A target input landmark name to be edited. This should be listed in the inputLandmakrFilename Given. ", sep=",", argstr="--inputLandmarkNames %s") setCutDirectionForLandmark = InputMultiPath( traits.Str, desc="Setting the cutting out direction of the input binary image to the one of anterior, posterior, left, right, superior or posterior. (ENUMERATION: ANTERIOR, POSTERIOR, LEFT, RIGHT, SUPERIOR, POSTERIOR) ", sep=",", argstr="--setCutDirectionForLandmark %s") setCutDirectionForObliquePlane = InputMultiPath( traits.Str, desc="If this is true, the mask will be thresholded out to the direction of inferior, posterior, and/or left. Default behavrior is that cutting out to the direction of superior, anterior and/or right. ", sep=",", argstr="--setCutDirectionForObliquePlane %s") inputLandmarkNamesForObliquePlane = InputMultiPath(traits.Str, desc=" Three subset landmark names of inputLandmarksFilename for a oblique plane computation. The plane computed for binary volume editing. ", sep=",", argstr="--inputLandmarkNamesForObliquePlane %s") class BinaryMaskEditorBasedOnLandmarksOutputSpec(TraitedSpec): outputBinaryVolume = File(desc="Output binary image in which to be edited", exists=True) class BinaryMaskEditorBasedOnLandmarks(SEMLikeCommandLine): """title: BRAINS Binary Mask Editor Based On Landmarks(BRAINS) category: Segmentation.Specialized version: 1.0 documentation-url: http://www.nitrc.org/projects/brainscdetector/ """ input_spec = BinaryMaskEditorBasedOnLandmarksInputSpec output_spec = BinaryMaskEditorBasedOnLandmarksOutputSpec _cmd = " BinaryMaskEditorBasedOnLandmarks " _outputs_filenames = {'outputBinaryVolume': 'outputBinaryVolume.nii'} _redirect_x = False class BRAINSMultiSTAPLEInputSpec(CommandLineInputSpec): inputCompositeT1Volume = File(desc="Composite T1, all label maps transofrmed into the space for this image.", exists=True, argstr="--inputCompositeT1Volume %s") inputLabelVolume = InputMultiPath(File(exists=True), desc="The list of proobabilityimages.", argstr="--inputLabelVolume %s...") inputTransform = InputMultiPath(File(exists=True), desc="transforms to apply to label volumes", argstr="--inputTransform %s...") labelForUndecidedPixels = traits.Int(desc="Label for undecided pixels", argstr="--labelForUndecidedPixels %d") resampledVolumePrefix = traits.Str(desc="if given, write out resampled volumes with this prefix", argstr="--resampledVolumePrefix %s") skipResampling = traits.Bool(desc="Omit resampling images into reference space", argstr="--skipResampling ") outputMultiSTAPLE = traits.Either(traits.Bool, File(), hash_files=False, desc="the MultiSTAPLE average of input label volumes", argstr="--outputMultiSTAPLE %s") outputConfusionMatrix = traits.Either(traits.Bool, File(), hash_files=False, desc="Confusion Matrix", argstr="--outputConfusionMatrix %s") class BRAINSMultiSTAPLEOutputSpec(TraitedSpec): outputMultiSTAPLE = File(desc="the MultiSTAPLE average of input label volumes", exists=True) outputConfusionMatrix = File(desc="Confusion Matrix", exists=True) class BRAINSMultiSTAPLE(SEMLikeCommandLine): """title: Create best representative label map) category: Segmentation.Specialized description: given a list of label map images, create a representative/average label map. """ input_spec = BRAINSMultiSTAPLEInputSpec output_spec = BRAINSMultiSTAPLEOutputSpec _cmd = " BRAINSMultiSTAPLE " _outputs_filenames = {'outputMultiSTAPLE': 'outputMultiSTAPLE.nii', 'outputConfusionMatrix': 'outputConfusionMatrixh5|mat|txt'} _redirect_x = False class BRAINSABCInputSpec(CommandLineInputSpec): inputVolumes = InputMultiPath(File(exists=True), desc="The list of input image files to be segmented.", argstr="--inputVolumes %s...") atlasDefinition = File(desc="Contains all parameters for Atlas", exists=True, argstr="--atlasDefinition %s") restoreState = File(desc="The initial state for the registration process", exists=True, argstr="--restoreState %s") saveState = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Filename to which save the final state of the registration", argstr="--saveState %s") inputVolumeTypes = InputMultiPath(traits.Str, desc="The list of input image types corresponding to the inputVolumes.", sep=",", argstr="--inputVolumeTypes %s") outputDir = traits.Either(traits.Bool, Directory(), hash_files=False, desc="Ouput directory", argstr="--outputDir %s") atlasToSubjectTransformType = traits.Enum("Identity", "Rigid", "Affine", "BSpline", "SyN", desc=" What type of linear transform type do you want to use to register the atlas to the reference subject image.", argstr="--atlasToSubjectTransformType %s") atlasToSubjectTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="The transform from atlas to the subject", argstr="--atlasToSubjectTransform %s") atlasToSubjectInitialTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="The initial transform from atlas to the subject", argstr="--atlasToSubjectInitialTransform %s") subjectIntermodeTransformType = traits.Enum("Identity", "Rigid", "Affine", "BSpline", desc=" What type of linear transform type do you want to use to register the atlas to the reference subject image.", argstr="--subjectIntermodeTransformType %s") outputVolumes = traits.Either(traits.Bool, InputMultiPath(File(), ), hash_files=False, desc="Corrected Output Images: should specify the same number of images as inputVolume, if only one element is given, then it is used as a file pattern where %s is replaced by the imageVolumeType, and %d by the index list location.", argstr="--outputVolumes %s...") outputLabels = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Label Image", argstr="--outputLabels %s") outputDirtyLabels = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Dirty Label Image", argstr="--outputDirtyLabels %s") posteriorTemplate = traits.Str(desc="filename template for Posterior output files", argstr="--posteriorTemplate %s") outputFormat = traits.Enum("NIFTI", "Meta", "Nrrd", desc="Output format", argstr="--outputFormat %s") interpolationMode = traits.Enum("BSpline", "NearestNeighbor", "WindowedSinc", "Linear", "ResampleInPlace", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, NearestNeighbor, BSpline, WindowedSinc, or ResampleInPlace. The ResampleInPlace option will create an image with the same discrete voxel values and will adjust the origin and direction of the physical space interpretation.", argstr="--interpolationMode %s") maxIterations = traits.Int(desc="Filter iterations", argstr="--maxIterations %d") medianFilterSize = InputMultiPath(traits.Int, desc="The radius for the optional MedianImageFilter preprocessing in all 3 directions.", sep=",", argstr="--medianFilterSize %s") filterIteration = traits.Int(desc="Filter iterations", argstr="--filterIteration %d") filterTimeStep = traits.Float(desc="Filter time step should be less than (PixelSpacing/(1^(DIM+1)), value is set to negative, then allow automatic setting of this value. ", argstr="--filterTimeStep %f") filterMethod = traits.Enum("None", "CurvatureFlow", "GradientAnisotropicDiffusion", "Median", desc="Filter method for preprocessing of registration", argstr="--filterMethod %s") maxBiasDegree = traits.Int(desc="Maximum bias degree", argstr="--maxBiasDegree %d") useKNN = traits.Bool(desc="Use the KNN stage of estimating posteriors.", argstr="--useKNN ") atlasWarpingOff = traits.Bool(desc="Deformable registration of atlas to subject", argstr="--atlasWarpingOff ") gridSize = InputMultiPath(traits.Int, desc="Grid size for atlas warping with BSplines", sep=",", argstr="--gridSize %s") defaultSuffix = traits.Str(argstr="--defaultSuffix %s") implicitOutputs = traits.Either(traits.Bool, InputMultiPath(File(), ), hash_files=False, desc="Outputs to be made available to NiPype. Needed because not all BRAINSABC outputs have command line arguments.", argstr="--implicitOutputs %s...") debuglevel = traits.Int(desc="Display debug messages, and produce debug intermediate results. 0=OFF, 1=Minimal, 10=Maximum debugging.", argstr="--debuglevel %d") writeLess = traits.Bool(desc="Does not write posteriors and filtered, bias corrected images", argstr="--writeLess ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSABCOutputSpec(TraitedSpec): saveState = File(desc="(optional) Filename to which save the final state of the registration", exists=True) outputDir = Directory(desc="Ouput directory", exists=True) atlasToSubjectTransform = File(desc="The transform from atlas to the subject", exists=True) atlasToSubjectInitialTransform = File(desc="The initial transform from atlas to the subject", exists=True) outputVolumes = OutputMultiPath( File(exists=True), desc="Corrected Output Images: should specify the same number of images as inputVolume, if only one element is given, then it is used as a file pattern where %s is replaced by the imageVolumeType, and %d by the index list location.") outputLabels = File(desc="Output Label Image", exists=True) outputDirtyLabels = File(desc="Output Dirty Label Image", exists=True) implicitOutputs = OutputMultiPath(File(exists=True), desc="Outputs to be made available to NiPype. Needed because not all BRAINSABC outputs have command line arguments.") class BRAINSABC(SEMLikeCommandLine): """title: Intra-subject registration, bias Correction, and tissue classification (BRAINS) category: Segmentation.Specialized description: Atlas-based tissue segmentation method. This is an algorithmic extension of work done by XXXX at UNC and Utah XXXX need more description here. """ input_spec = BRAINSABCInputSpec output_spec = BRAINSABCOutputSpec _cmd = " BRAINSABC " _outputs_filenames = {'saveState': 'saveState.h5', 'outputLabels': 'outputLabels.nii.gz', 'atlasToSubjectTransform': 'atlasToSubjectTransform.h5', 'atlasToSubjectInitialTransform': 'atlasToSubjectInitialTransform.h5', 'outputDirtyLabels': 'outputDirtyLabels.nii.gz', 'outputVolumes': 'outputVolumes.nii.gz', 'outputDir': 'outputDir', 'implicitOutputs': 'implicitOutputs.nii.gz'} _redirect_x = False class ESLRInputSpec(CommandLineInputSpec): inputVolume = File(desc="Input Label Volume", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Label Volume", argstr="--outputVolume %s") low = traits.Int(desc="The lower bound of the labels to be used.", argstr="--low %d") high = traits.Int(desc="The higher bound of the labels to be used.", argstr="--high %d") closingSize = traits.Int(desc="The closing size for hole filling.", argstr="--closingSize %d") openingSize = traits.Int(desc="The opening size for hole filling.", argstr="--openingSize %d") safetySize = traits.Int(desc="The safetySize size for the clipping region.", argstr="--safetySize %d") preserveOutside = traits.Bool(desc="For values outside the specified range, preserve those values.", argstr="--preserveOutside ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class ESLROutputSpec(TraitedSpec): outputVolume = File(desc="Output Label Volume", exists=True) class ESLR(SEMLikeCommandLine): """title: Clean Contiguous Label Map (BRAINS) category: Segmentation.Specialized description: From a range of label map values, extract the largest contiguous region of those labels """ input_spec = ESLRInputSpec output_spec = ESLROutputSpec _cmd = " ESLR " _outputs_filenames = {'outputVolume': 'outputVolume.nii.gz'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/000077500000000000000000000000001257611314500242355ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_BRAINSABC.py000066400000000000000000000062331257611314500301660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSABC def test_BRAINSABC_inputs(): input_map = dict(args=dict(argstr='%s', ), atlasDefinition=dict(argstr='--atlasDefinition %s', ), atlasToSubjectInitialTransform=dict(argstr='--atlasToSubjectInitialTransform %s', hash_files=False, ), atlasToSubjectTransform=dict(argstr='--atlasToSubjectTransform %s', hash_files=False, ), atlasToSubjectTransformType=dict(argstr='--atlasToSubjectTransformType %s', ), atlasWarpingOff=dict(argstr='--atlasWarpingOff ', ), debuglevel=dict(argstr='--debuglevel %d', ), defaultSuffix=dict(argstr='--defaultSuffix %s', ), environ=dict(nohash=True, usedefault=True, ), filterIteration=dict(argstr='--filterIteration %d', ), filterMethod=dict(argstr='--filterMethod %s', ), filterTimeStep=dict(argstr='--filterTimeStep %f', ), gridSize=dict(argstr='--gridSize %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), implicitOutputs=dict(argstr='--implicitOutputs %s...', hash_files=False, ), inputVolumeTypes=dict(argstr='--inputVolumeTypes %s', sep=',', ), inputVolumes=dict(argstr='--inputVolumes %s...', ), interpolationMode=dict(argstr='--interpolationMode %s', ), maxBiasDegree=dict(argstr='--maxBiasDegree %d', ), maxIterations=dict(argstr='--maxIterations %d', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputDir=dict(argstr='--outputDir %s', hash_files=False, ), outputDirtyLabels=dict(argstr='--outputDirtyLabels %s', hash_files=False, ), outputFormat=dict(argstr='--outputFormat %s', ), outputLabels=dict(argstr='--outputLabels %s', hash_files=False, ), outputVolumes=dict(argstr='--outputVolumes %s...', hash_files=False, ), posteriorTemplate=dict(argstr='--posteriorTemplate %s', ), restoreState=dict(argstr='--restoreState %s', ), saveState=dict(argstr='--saveState %s', hash_files=False, ), subjectIntermodeTransformType=dict(argstr='--subjectIntermodeTransformType %s', ), terminal_output=dict(nohash=True, ), useKNN=dict(argstr='--useKNN ', ), writeLess=dict(argstr='--writeLess ', ), ) inputs = BRAINSABC.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSABC_outputs(): output_map = dict(atlasToSubjectInitialTransform=dict(), atlasToSubjectTransform=dict(), implicitOutputs=dict(), outputDir=dict(), outputDirtyLabels=dict(), outputLabels=dict(), outputVolumes=dict(), saveState=dict(), ) outputs = BRAINSABC.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_BRAINSConstellationDetector.py000066400000000000000000000101751257611314500341110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSConstellationDetector def test_BRAINSConstellationDetector_inputs(): input_map = dict(BackgroundFillValue=dict(argstr='--BackgroundFillValue %s', ), LLSModel=dict(argstr='--LLSModel %s', ), acLowerBound=dict(argstr='--acLowerBound %f', ), args=dict(argstr='%s', ), atlasLandmarkWeights=dict(argstr='--atlasLandmarkWeights %s', ), atlasLandmarks=dict(argstr='--atlasLandmarks %s', ), atlasVolume=dict(argstr='--atlasVolume %s', ), cutOutHeadInOutputVolume=dict(argstr='--cutOutHeadInOutputVolume ', ), debug=dict(argstr='--debug ', ), environ=dict(nohash=True, usedefault=True, ), forceACPoint=dict(argstr='--forceACPoint %s', sep=',', ), forceHoughEyeDetectorReportFailure=dict(argstr='--forceHoughEyeDetectorReportFailure ', ), forcePCPoint=dict(argstr='--forcePCPoint %s', sep=',', ), forceRPPoint=dict(argstr='--forceRPPoint %s', sep=',', ), forceVN4Point=dict(argstr='--forceVN4Point %s', sep=',', ), houghEyeDetectorMode=dict(argstr='--houghEyeDetectorMode %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputLandmarksEMSP=dict(argstr='--inputLandmarksEMSP %s', ), inputTemplateModel=dict(argstr='--inputTemplateModel %s', ), inputVolume=dict(argstr='--inputVolume %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), mspQualityLevel=dict(argstr='--mspQualityLevel %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), otsuPercentileThreshold=dict(argstr='--otsuPercentileThreshold %f', ), outputLandmarksInACPCAlignedSpace=dict(argstr='--outputLandmarksInACPCAlignedSpace %s', hash_files=False, ), outputLandmarksInInputSpace=dict(argstr='--outputLandmarksInInputSpace %s', hash_files=False, ), outputMRML=dict(argstr='--outputMRML %s', hash_files=False, ), outputResampledVolume=dict(argstr='--outputResampledVolume %s', hash_files=False, ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), outputUntransformedClippedVolume=dict(argstr='--outputUntransformedClippedVolume %s', hash_files=False, ), outputVerificationScript=dict(argstr='--outputVerificationScript %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), rVN4=dict(argstr='--rVN4 %f', ), rac=dict(argstr='--rac %f', ), rescaleIntensities=dict(argstr='--rescaleIntensities ', ), rescaleIntensitiesOutputRange=dict(argstr='--rescaleIntensitiesOutputRange %s', sep=',', ), resultsDir=dict(argstr='--resultsDir %s', hash_files=False, ), rmpj=dict(argstr='--rmpj %f', ), rpc=dict(argstr='--rpc %f', ), terminal_output=dict(nohash=True, ), trimRescaledIntensities=dict(argstr='--trimRescaledIntensities %f', ), verbose=dict(argstr='--verbose ', ), writeBranded2DImage=dict(argstr='--writeBranded2DImage %s', hash_files=False, ), writedebuggingImagesLevel=dict(argstr='--writedebuggingImagesLevel %d', ), ) inputs = BRAINSConstellationDetector.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSConstellationDetector_outputs(): output_map = dict(outputLandmarksInACPCAlignedSpace=dict(), outputLandmarksInInputSpace=dict(), outputMRML=dict(), outputResampledVolume=dict(), outputTransform=dict(), outputUntransformedClippedVolume=dict(), outputVerificationScript=dict(), outputVolume=dict(), resultsDir=dict(), writeBranded2DImage=dict(), ) outputs = BRAINSConstellationDetector.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_BRAINSCreateLabelMapFromProbabilityMaps.py000066400000000000000000000031611257611314500361660ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSCreateLabelMapFromProbabilityMaps def test_BRAINSCreateLabelMapFromProbabilityMaps_inputs(): input_map = dict(args=dict(argstr='%s', ), cleanLabelVolume=dict(argstr='--cleanLabelVolume %s', hash_files=False, ), dirtyLabelVolume=dict(argstr='--dirtyLabelVolume %s', hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), foregroundPriors=dict(argstr='--foregroundPriors %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inclusionThreshold=dict(argstr='--inclusionThreshold %f', ), inputProbabilityVolume=dict(argstr='--inputProbabilityVolume %s...', ), nonAirRegionMask=dict(argstr='--nonAirRegionMask %s', ), priorLabelCodes=dict(argstr='--priorLabelCodes %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSCreateLabelMapFromProbabilityMaps.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSCreateLabelMapFromProbabilityMaps_outputs(): output_map = dict(cleanLabelVolume=dict(), dirtyLabelVolume=dict(), ) outputs = BRAINSCreateLabelMapFromProbabilityMaps.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_BRAINSCut.py000066400000000000000000000036441257611314500303370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSCut def test_BRAINSCut_inputs(): input_map = dict(NoTrainingVectorShuffling=dict(argstr='--NoTrainingVectorShuffling ', ), applyModel=dict(argstr='--applyModel ', ), args=dict(argstr='%s', ), computeSSEOn=dict(argstr='--computeSSEOn ', ), createVectors=dict(argstr='--createVectors ', ), environ=dict(nohash=True, usedefault=True, ), generateProbability=dict(argstr='--generateProbability ', ), histogramEqualization=dict(argstr='--histogramEqualization ', ), ignore_exception=dict(nohash=True, usedefault=True, ), method=dict(argstr='--method %s', ), modelConfigurationFilename=dict(argstr='--modelConfigurationFilename %s', ), modelFilename=dict(argstr='--modelFilename %s', ), multiStructureThreshold=dict(argstr='--multiStructureThreshold ', ), netConfiguration=dict(argstr='--netConfiguration %s', ), numberOfTrees=dict(argstr='--numberOfTrees %d', ), randomTreeDepth=dict(argstr='--randomTreeDepth %d', ), terminal_output=dict(nohash=True, ), trainModel=dict(argstr='--trainModel ', ), trainModelStartIndex=dict(argstr='--trainModelStartIndex %d', ), validate=dict(argstr='--validate ', ), verbose=dict(argstr='--verbose %d', ), ) inputs = BRAINSCut.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSCut_outputs(): output_map = dict() outputs = BRAINSCut.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_BRAINSMultiSTAPLE.py000066400000000000000000000031131257611314500315760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSMultiSTAPLE def test_BRAINSMultiSTAPLE_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputCompositeT1Volume=dict(argstr='--inputCompositeT1Volume %s', ), inputLabelVolume=dict(argstr='--inputLabelVolume %s...', ), inputTransform=dict(argstr='--inputTransform %s...', ), labelForUndecidedPixels=dict(argstr='--labelForUndecidedPixels %d', ), outputConfusionMatrix=dict(argstr='--outputConfusionMatrix %s', hash_files=False, ), outputMultiSTAPLE=dict(argstr='--outputMultiSTAPLE %s', hash_files=False, ), resampledVolumePrefix=dict(argstr='--resampledVolumePrefix %s', ), skipResampling=dict(argstr='--skipResampling ', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSMultiSTAPLE.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSMultiSTAPLE_outputs(): output_map = dict(outputConfusionMatrix=dict(), outputMultiSTAPLE=dict(), ) outputs = BRAINSMultiSTAPLE.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_BRAINSROIAuto.py000066400000000000000000000032771257611314500310700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BRAINSROIAuto def test_BRAINSROIAuto_inputs(): input_map = dict(ROIAutoDilateSize=dict(argstr='--ROIAutoDilateSize %f', ), args=dict(argstr='%s', ), closingSize=dict(argstr='--closingSize %f', ), cropOutput=dict(argstr='--cropOutput ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), maskOutput=dict(argstr='--maskOutput ', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), otsuPercentileThreshold=dict(argstr='--otsuPercentileThreshold %f', ), outputROIMaskVolume=dict(argstr='--outputROIMaskVolume %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), outputVolumePixelType=dict(argstr='--outputVolumePixelType %s', ), terminal_output=dict(nohash=True, ), thresholdCorrectionFactor=dict(argstr='--thresholdCorrectionFactor %f', ), ) inputs = BRAINSROIAuto.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSROIAuto_outputs(): output_map = dict(outputROIMaskVolume=dict(), outputVolume=dict(), ) outputs = BRAINSROIAuto.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_BinaryMaskEditorBasedOnLandmarks.py000066400000000000000000000032161257611314500351210ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import BinaryMaskEditorBasedOnLandmarks def test_BinaryMaskEditorBasedOnLandmarks_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryVolume=dict(argstr='--inputBinaryVolume %s', ), inputLandmarkNames=dict(argstr='--inputLandmarkNames %s', sep=',', ), inputLandmarkNamesForObliquePlane=dict(argstr='--inputLandmarkNamesForObliquePlane %s', sep=',', ), inputLandmarksFilename=dict(argstr='--inputLandmarksFilename %s', ), outputBinaryVolume=dict(argstr='--outputBinaryVolume %s', hash_files=False, ), setCutDirectionForLandmark=dict(argstr='--setCutDirectionForLandmark %s', sep=',', ), setCutDirectionForObliquePlane=dict(argstr='--setCutDirectionForObliquePlane %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = BinaryMaskEditorBasedOnLandmarks.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BinaryMaskEditorBasedOnLandmarks_outputs(): output_map = dict(outputBinaryVolume=dict(), ) outputs = BinaryMaskEditorBasedOnLandmarks.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/segmentation/tests/test_auto_ESLR.py000066400000000000000000000025701257611314500274470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.segmentation.specialized import ESLR def test_ESLR_inputs(): input_map = dict(args=dict(argstr='%s', ), closingSize=dict(argstr='--closingSize %d', ), environ=dict(nohash=True, usedefault=True, ), high=dict(argstr='--high %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), low=dict(argstr='--low %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), openingSize=dict(argstr='--openingSize %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), preserveOutside=dict(argstr='--preserveOutside ', ), safetySize=dict(argstr='--safetySize %d', ), terminal_output=dict(nohash=True, ), ) inputs = ESLR.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ESLR_outputs(): output_map = dict(outputVolume=dict(), ) outputs = ESLR.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/testing/000077500000000000000000000000001257611314500220535ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/testing/__init__.py000066400000000000000000000002431257611314500241630ustar00rootroot00000000000000from featuredetection import SphericalCoordinateGeneration from landmarkscompare import LandmarksCompare from generateaveragelmkfile import GenerateAverageLmkFile nipype-0.11.0/nipype/interfaces/semtools/testing/featuredetection.py000066400000000000000000000022361257611314500257620ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class SphericalCoordinateGenerationInputSpec(CommandLineInputSpec): inputAtlasImage = File(desc="Input atlas image", exists=True, argstr="--inputAtlasImage %s") outputPath = traits.Str(desc="Output path for rho, phi and theta images", argstr="--outputPath %s") class SphericalCoordinateGenerationOutputSpec(TraitedSpec): pass class SphericalCoordinateGeneration(SEMLikeCommandLine): """title: Spherical Coordinate Generation category: Testing.FeatureDetection description: get the atlas image as input and generates the rho, phi and theta images. version: 0.1.0.$Revision: 1 $(alpha) contributor: Ali Ghayoor """ input_spec = SphericalCoordinateGenerationInputSpec output_spec = SphericalCoordinateGenerationOutputSpec _cmd = " SphericalCoordinateGeneration " _outputs_filenames = {} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/testing/generateaveragelmkfile.py000066400000000000000000000027301257611314500271200ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class GenerateAverageLmkFileInputSpec(CommandLineInputSpec): inputLandmarkFiles = InputMultiPath(traits.Str, desc="Input landmark files names (.fcsv or .wts)", sep=",", argstr="--inputLandmarkFiles %s") outputLandmarkFile = traits.Either(traits.Bool, File(), hash_files=False, desc="Ouput landmark file name that includes average values for landmarks (.fcsv or .wts)", argstr="--outputLandmarkFile %s") class GenerateAverageLmkFileOutputSpec(TraitedSpec): outputLandmarkFile = File(desc="Ouput landmark file name that includes average values for landmarks (.fcsv or .wts)", exists=True) class GenerateAverageLmkFile(SEMLikeCommandLine): """title: Average Fiducials category: Testing description: This program gets several fcsv file each one contains several landmarks with the same name but slightly different coordinates. For EACH landmark we compute the average coordination. contributor: Ali Ghayoor """ input_spec = GenerateAverageLmkFileInputSpec output_spec = GenerateAverageLmkFileOutputSpec _cmd = " GenerateAverageLmkFile " _outputs_filenames = {'outputLandmarkFile': 'outputLandmarkFile'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/testing/landmarkscompare.py000066400000000000000000000023461257611314500257550ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class LandmarksCompareInputSpec(CommandLineInputSpec): inputLandmarkFile1 = File(desc="First input landmark file (.fcsv or .wts)", exists=True, argstr="--inputLandmarkFile1 %s") inputLandmarkFile2 = File(desc="Second input landmark file (.fcsv or .wts)", exists=True, argstr="--inputLandmarkFile2 %s") tolerance = traits.Float(desc="The maximum error (in mm) allowed in each direction of a landmark", argstr="--tolerance %f") class LandmarksCompareOutputSpec(TraitedSpec): pass class LandmarksCompare(SEMLikeCommandLine): """title: Compare Fiducials category: Testing description: Compares two .fcsv or .wts text files and verifies that they are identicle. Used for testing landmarks files. contributor: Ali Ghayoor """ input_spec = LandmarksCompareInputSpec output_spec = LandmarksCompareOutputSpec _cmd = " LandmarksCompare " _outputs_filenames = {} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/tests/000077500000000000000000000000001257611314500215405ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/tests/test_auto_DWICompare.py000066400000000000000000000017541257611314500261420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.converters import DWICompare def test_DWICompare_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='--inputVolume1 %s', ), inputVolume2=dict(argstr='--inputVolume2 %s', ), terminal_output=dict(nohash=True, ), ) inputs = DWICompare.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWICompare_outputs(): output_map = dict() outputs = DWICompare.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/tests/test_auto_DWISimpleCompare.py000066400000000000000000000021011257611314500272770ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.converters import DWISimpleCompare def test_DWISimpleCompare_inputs(): input_map = dict(args=dict(argstr='%s', ), checkDWIData=dict(argstr='--checkDWIData ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='--inputVolume1 %s', ), inputVolume2=dict(argstr='--inputVolume2 %s', ), terminal_output=dict(nohash=True, ), ) inputs = DWISimpleCompare.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWISimpleCompare_outputs(): output_map = dict() outputs = DWISimpleCompare.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/tests/test_auto_GenerateCsfClippedFromClassifiedImage.py000066400000000000000000000022661257611314500334540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.featurecreator import GenerateCsfClippedFromClassifiedImage def test_GenerateCsfClippedFromClassifiedImage_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputCassifiedVolume=dict(argstr='--inputCassifiedVolume %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = GenerateCsfClippedFromClassifiedImage.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateCsfClippedFromClassifiedImage_outputs(): output_map = dict(outputVolume=dict(), ) outputs = GenerateCsfClippedFromClassifiedImage.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/000077500000000000000000000000001257611314500224115ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/utilities/__init__.py000066400000000000000000000007561257611314500245320ustar00rootroot00000000000000from brains import BRAINSConstellationModeler, landmarksConstellationWeights, BRAINSTrimForegroundInDirection, BRAINSLmkTransform, BRAINSMush, BRAINSTransformConvert, landmarksConstellationAligner, BRAINSEyeDetector, BRAINSLinearModelerEPCA, BRAINSInitializedControlPoints, CleanUpOverlapLabels, BRAINSClipInferior, GenerateLabelMapFromProbabilityMap, BRAINSAlignMSP, BRAINSLandmarkInitializer, insertMidACPCpoint, BRAINSSnapShotWriter, JointHistogram, ShuffleVectorsModule, ImageRegionPlotter nipype-0.11.0/nipype/interfaces/semtools/utilities/brains.py000066400000000000000000001230561257611314500242500ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSConstellationModelerInputSpec(CommandLineInputSpec): verbose = traits.Bool(desc=", Show more verbose output, ", argstr="--verbose ") inputTrainingList = File(desc=", Setup file, giving all parameters for training up a template model for each landmark., ", exists=True, argstr="--inputTrainingList %s") outputModel = traits.Either(traits.Bool, File(), hash_files=False, desc=", The full filename of the output model file., ", argstr="--outputModel %s") saveOptimizedLandmarks = traits.Bool( desc=", Flag to make a new subject-specific landmark definition file in the same format produced by Slicer3 with the optimized landmark (the detected RP, AC, and PC) in it. Useful to tighten the variances in the ConstellationModeler., ", argstr="--saveOptimizedLandmarks ") optimizedLandmarksFilenameExtender = traits.Str( desc=", If the trainingList is (indexFullPathName) and contains landmark data filenames [path]/[filename].fcsv , make the optimized landmarks filenames out of [path]/[filename](thisExtender) and the optimized version of the input trainingList out of (indexFullPathName)(thisExtender) , when you rewrite all the landmarks according to the saveOptimizedLandmarks flag., ", argstr="--optimizedLandmarksFilenameExtender %s") resultsDir = traits.Either(traits.Bool, Directory(), hash_files=False, desc=", The directory for the results to be written., ", argstr="--resultsDir %s") mspQualityLevel = traits.Int(desc=", Flag cotrols how agressive the MSP is estimated. 0=quick estimate (9 seconds), 1=normal estimate (11 seconds), 2=great estimate (22 seconds), 3=best estimate (58 seconds)., ", argstr="--mspQualityLevel %d") rescaleIntensities = traits.Bool(desc=", Flag to turn on rescaling image intensities on input., ", argstr="--rescaleIntensities ") trimRescaledIntensities = traits.Float( desc=", Turn on clipping the rescaled image one-tailed on input. Units of standard deviations above the mean. Very large values are very permissive. Non-positive value turns clipping off. Defaults to removing 0.00001 of a normal tail above the mean., ", argstr="--trimRescaledIntensities %f") rescaleIntensitiesOutputRange = InputMultiPath( traits.Int, desc=", This pair of integers gives the lower and upper bounds on the signal portion of the output image. Out-of-field voxels are taken from BackgroundFillValue., ", sep=",", argstr="--rescaleIntensitiesOutputRange %s") BackgroundFillValue = traits.Str(desc="Fill the background of image with specified short int value. Enter number or use BIGNEG for a large negative number.", argstr="--BackgroundFillValue %s") writedebuggingImagesLevel = traits.Int(desc=", This flag controls if debugging images are produced. By default value of 0 is no images. Anything greater than zero will be increasing level of debugging images., ", argstr="--writedebuggingImagesLevel %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSConstellationModelerOutputSpec(TraitedSpec): outputModel = File(desc=", The full filename of the output model file., ", exists=True) resultsDir = Directory(desc=", The directory for the results to be written., ", exists=True) class BRAINSConstellationModeler(SEMLikeCommandLine): """title: Generate Landmarks Model (BRAINS) category: Utilities.BRAINS description: Train up a model for BRAINSConstellationDetector """ input_spec = BRAINSConstellationModelerInputSpec output_spec = BRAINSConstellationModelerOutputSpec _cmd = " BRAINSConstellationModeler " _outputs_filenames = {'outputModel': 'outputModel.mdl', 'resultsDir': 'resultsDir'} _redirect_x = False class landmarksConstellationWeightsInputSpec(CommandLineInputSpec): inputTrainingList = File(desc=", Setup file, giving all parameters for training up a Weight list for landmark., ", exists=True, argstr="--inputTrainingList %s") inputTemplateModel = File(desc="User-specified template model., ", exists=True, argstr="--inputTemplateModel %s") LLSModel = File(desc="Linear least squares model filename in HD5 format", exists=True, argstr="--LLSModel %s") outputWeightsList = traits.Either(traits.Bool, File(), hash_files=False, desc=", The filename of a csv file which is a list of landmarks and their corresponding weights., ", argstr="--outputWeightsList %s") class landmarksConstellationWeightsOutputSpec(TraitedSpec): outputWeightsList = File(desc=", The filename of a csv file which is a list of landmarks and their corresponding weights., ", exists=True) class landmarksConstellationWeights(SEMLikeCommandLine): """title: Generate Landmarks Weights (BRAINS) category: Utilities.BRAINS description: Train up a list of Weights for the Landmarks in BRAINSConstellationDetector """ input_spec = landmarksConstellationWeightsInputSpec output_spec = landmarksConstellationWeightsOutputSpec _cmd = " landmarksConstellationWeights " _outputs_filenames = {'outputWeightsList': 'outputWeightsList.wts'} _redirect_x = False class BRAINSTrimForegroundInDirectionInputSpec(CommandLineInputSpec): inputVolume = File(desc="Input image to trim off the neck (and also air-filling noise.)", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output image with neck and air-filling noise trimmed isotropic image with AC at center of image.", argstr="--outputVolume %s") directionCode = traits.Int(desc=", This flag chooses which dimension to compare. The sign lets you flip direction., ", argstr="--directionCode %d") otsuPercentileThreshold = traits.Float(desc=", This is a parameter to FindLargestForegroundFilledMask, which is employed to trim off air-filling noise., ", argstr="--otsuPercentileThreshold %f") closingSize = traits.Int(desc=", This is a parameter to FindLargestForegroundFilledMask, ", argstr="--closingSize %d") headSizeLimit = traits.Float(desc=", Use this to vary from the command line our search for how much upper tissue is head for the center-of-mass calculation. Units are CCs, not cubic millimeters., ", argstr="--headSizeLimit %f") BackgroundFillValue = traits.Str(desc="Fill the background of image with specified short int value. Enter number or use BIGNEG for a large negative number.", argstr="--BackgroundFillValue %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSTrimForegroundInDirectionOutputSpec(TraitedSpec): outputVolume = File(desc="Output image with neck and air-filling noise trimmed isotropic image with AC at center of image.", exists=True) class BRAINSTrimForegroundInDirection(SEMLikeCommandLine): """title: Trim Foreground In Direction (BRAINS) category: Utilities.BRAINS description: This program will trim off the neck and also air-filling noise from the inputImage. version: 0.1 documentation-url: http://www.nitrc.org/projects/art/ """ input_spec = BRAINSTrimForegroundInDirectionInputSpec output_spec = BRAINSTrimForegroundInDirectionOutputSpec _cmd = " BRAINSTrimForegroundInDirection " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class BRAINSLmkTransformInputSpec(CommandLineInputSpec): inputMovingLandmarks = File(desc="Input Moving Landmark list file in fcsv, ", exists=True, argstr="--inputMovingLandmarks %s") inputFixedLandmarks = File(desc="Input Fixed Landmark list file in fcsv, ", exists=True, argstr="--inputFixedLandmarks %s") outputAffineTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="The filename for the estimated affine transform, ", argstr="--outputAffineTransform %s") inputMovingVolume = File(desc="The filename of input moving volume", exists=True, argstr="--inputMovingVolume %s") inputReferenceVolume = File(desc="The filename of the reference volume", exists=True, argstr="--inputReferenceVolume %s") outputResampledVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The filename of the output resampled volume", argstr="--outputResampledVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSLmkTransformOutputSpec(TraitedSpec): outputAffineTransform = File(desc="The filename for the estimated affine transform, ", exists=True) outputResampledVolume = File(desc="The filename of the output resampled volume", exists=True) class BRAINSLmkTransform(SEMLikeCommandLine): """title: Landmark Transform (BRAINS) category: Utilities.BRAINS description: This utility program estimates the affine transform to align the fixed landmarks to the moving landmarks, and then generate the resampled moving image to the same physical space as that of the reference image. version: 1.0 documentation-url: http://www.nitrc.org/projects/brainscdetector/ """ input_spec = BRAINSLmkTransformInputSpec output_spec = BRAINSLmkTransformOutputSpec _cmd = " BRAINSLmkTransform " _outputs_filenames = {'outputResampledVolume': 'outputResampledVolume.nii', 'outputAffineTransform': 'outputAffineTransform.h5'} _redirect_x = False class BRAINSMushInputSpec(CommandLineInputSpec): inputFirstVolume = File(desc="Input image (1) for mixture optimization", exists=True, argstr="--inputFirstVolume %s") inputSecondVolume = File(desc="Input image (2) for mixture optimization", exists=True, argstr="--inputSecondVolume %s") inputMaskVolume = File(desc="Input label image for mixture optimization", exists=True, argstr="--inputMaskVolume %s") outputWeightsFile = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Weights File", argstr="--outputWeightsFile %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The MUSH image produced from the T1 and T2 weighted images", argstr="--outputVolume %s") outputMask = traits.Either(traits.Bool, File(), hash_files=False, desc="The brain volume mask generated from the MUSH image", argstr="--outputMask %s") seed = InputMultiPath(traits.Int, desc="Seed Point for Brain Region Filling", sep=",", argstr="--seed %s") desiredMean = traits.Float(desc="Desired mean within the mask for weighted sum of both images.", argstr="--desiredMean %f") desiredVariance = traits.Float(desc="Desired variance within the mask for weighted sum of both images.", argstr="--desiredVariance %f") lowerThresholdFactorPre = traits.Float(desc="Lower threshold factor for finding an initial brain mask", argstr="--lowerThresholdFactorPre %f") upperThresholdFactorPre = traits.Float(desc="Upper threshold factor for finding an initial brain mask", argstr="--upperThresholdFactorPre %f") lowerThresholdFactor = traits.Float(desc="Lower threshold factor for defining the brain mask", argstr="--lowerThresholdFactor %f") upperThresholdFactor = traits.Float(desc="Upper threshold factor for defining the brain mask", argstr="--upperThresholdFactor %f") boundingBoxSize = InputMultiPath(traits.Int, desc="Size of the cubic bounding box mask used when no brain mask is present", sep=",", argstr="--boundingBoxSize %s") boundingBoxStart = InputMultiPath(traits.Int, desc="XYZ point-coordinate for the start of the cubic bounding box mask used when no brain mask is present", sep=",", argstr="--boundingBoxStart %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSMushOutputSpec(TraitedSpec): outputWeightsFile = File(desc="Output Weights File", exists=True) outputVolume = File(desc="The MUSH image produced from the T1 and T2 weighted images", exists=True) outputMask = File(desc="The brain volume mask generated from the MUSH image", exists=True) class BRAINSMush(SEMLikeCommandLine): """title: Brain Extraction from T1/T2 image (BRAINS) category: Utilities.BRAINS description: This program: 1) generates a weighted mixture image optimizing the mean and variance and 2) produces a mask of the brain volume version: 0.1.0.$Revision: 1.4 $(alpha) documentation-url: http:://mri.radiology.uiowa.edu license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool is a modification by Steven Dunn of a program developed by Greg Harris and Ron Pierson. acknowledgements: This work was developed by the University of Iowa Departments of Radiology and Psychiatry. This software was supported in part of NIH/NINDS award NS050568. """ input_spec = BRAINSMushInputSpec output_spec = BRAINSMushOutputSpec _cmd = " BRAINSMush " _outputs_filenames = {'outputMask': 'outputMask.nii.gz', 'outputWeightsFile': 'outputWeightsFile.txt', 'outputVolume': 'outputVolume.nii.gz'} _redirect_x = False class BRAINSTransformConvertInputSpec(CommandLineInputSpec): inputTransform = File(exists=True, argstr="--inputTransform %s") referenceVolume = File(exists=True, argstr="--referenceVolume %s") outputTransformType = traits.Enum("Affine", "VersorRigid", "ScaleVersor", "ScaleSkewVersor", "DisplacementField", "Same", desc="The target transformation type. Must be conversion-compatible with the input transform type", argstr="--outputTransformType %s") outputPrecisionType = traits.Enum("double", "float", desc="Precision type of the output transform. It can be either single precision or double precision", argstr="--outputPrecisionType %s") displacementVolume = traits.Either(traits.Bool, File(), hash_files=False, argstr="--displacementVolume %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, argstr="--outputTransform %s") class BRAINSTransformConvertOutputSpec(TraitedSpec): displacementVolume = File(exists=True) outputTransform = File(exists=True) class BRAINSTransformConvert(SEMLikeCommandLine): """title: BRAINS Transform Convert category: Utilities.BRAINS description: Convert ITK transforms to higher order transforms version: 1.0 documentation-url: A utility to convert between transform file formats. license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson,Kent Williams, Ali Ghayoor """ input_spec = BRAINSTransformConvertInputSpec output_spec = BRAINSTransformConvertOutputSpec _cmd = " BRAINSTransformConvert " _outputs_filenames = {'displacementVolume': 'displacementVolume.nii', 'outputTransform': 'outputTransform.mat'} _redirect_x = False class landmarksConstellationAlignerInputSpec(CommandLineInputSpec): inputLandmarksPaired = File(desc="Input landmark file (.fcsv)", exists=True, argstr="--inputLandmarksPaired %s") outputLandmarksPaired = traits.Either(traits.Bool, File(), hash_files=False, desc="Output landmark file (.fcsv)", argstr="--outputLandmarksPaired %s") class landmarksConstellationAlignerOutputSpec(TraitedSpec): outputLandmarksPaired = File(desc="Output landmark file (.fcsv)", exists=True) class landmarksConstellationAligner(SEMLikeCommandLine): """title: MidACPC Landmark Insertion category: Utilities.BRAINS description: This program converts the original landmark files to the acpc-aligned landmark files contributor: Ali Ghayoor """ input_spec = landmarksConstellationAlignerInputSpec output_spec = landmarksConstellationAlignerOutputSpec _cmd = " landmarksConstellationAligner " _outputs_filenames = {'outputLandmarksPaired': 'outputLandmarksPaired'} _redirect_x = False class BRAINSEyeDetectorInputSpec(CommandLineInputSpec): numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") inputVolume = File(desc="The input volume", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The output volume", argstr="--outputVolume %s") debugDir = traits.Str(desc="A place for debug information", argstr="--debugDir %s") class BRAINSEyeDetectorOutputSpec(TraitedSpec): outputVolume = File(desc="The output volume", exists=True) class BRAINSEyeDetector(SEMLikeCommandLine): """title: Eye Detector (BRAINS) category: Utilities.BRAINS version: 1.0 documentation-url: http://www.nitrc.org/projects/brainscdetector/ """ input_spec = BRAINSEyeDetectorInputSpec output_spec = BRAINSEyeDetectorOutputSpec _cmd = " BRAINSEyeDetector " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class BRAINSLinearModelerEPCAInputSpec(CommandLineInputSpec): inputTrainingList = File(desc="Input Training Landmark List Filename, ", exists=True, argstr="--inputTrainingList %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSLinearModelerEPCAOutputSpec(TraitedSpec): pass class BRAINSLinearModelerEPCA(SEMLikeCommandLine): """title: Landmark Linear Modeler (BRAINS) category: Utilities.BRAINS description: Training linear model using EPCA. Implementation based on my MS thesis, "A METHOD FOR AUTOMATED LANDMARK CONSTELLATION DETECTION USING EVOLUTIONARY PRINCIPAL COMPONENTS AND STATISTICAL SHAPE MODELS" version: 1.0 documentation-url: http://www.nitrc.org/projects/brainscdetector/ """ input_spec = BRAINSLinearModelerEPCAInputSpec output_spec = BRAINSLinearModelerEPCAOutputSpec _cmd = " BRAINSLinearModelerEPCA " _outputs_filenames = {} _redirect_x = False class BRAINSInitializedControlPointsInputSpec(CommandLineInputSpec): inputVolume = File(desc="Input Volume", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output Volume", argstr="--outputVolume %s") splineGridSize = InputMultiPath(traits.Int, desc="The number of subdivisions of the BSpline Grid to be centered on the image space. Each dimension must have at least 3 subdivisions for the BSpline to be correctly computed. ", sep=",", argstr="--splineGridSize %s") permuteOrder = InputMultiPath(traits.Int, desc="The permutation order for the images. The default is 0,1,2 (i.e. no permutation)", sep=",", argstr="--permuteOrder %s") outputLandmarksFile = traits.Str(desc="Output filename", argstr="--outputLandmarksFile %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSInitializedControlPointsOutputSpec(TraitedSpec): outputVolume = File(desc="Output Volume", exists=True) class BRAINSInitializedControlPoints(SEMLikeCommandLine): """title: Initialized Control Points (BRAINS) category: Utilities.BRAINS description: Outputs bspline control points as landmarks version: 0.1.0.$Revision: 916 $(alpha) license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Mark Scully acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Additional support for Mark Scully and Hans Johnson at the University of Iowa. """ input_spec = BRAINSInitializedControlPointsInputSpec output_spec = BRAINSInitializedControlPointsOutputSpec _cmd = " BRAINSInitializedControlPoints " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class CleanUpOverlapLabelsInputSpec(CommandLineInputSpec): inputBinaryVolumes = InputMultiPath(File(exists=True), desc="The list of binary images to be checked and cleaned up. Order is important. Binary volume given first always wins out. ", argstr="--inputBinaryVolumes %s...") outputBinaryVolumes = traits.Either(traits.Bool, InputMultiPath(File(), ), hash_files=False, desc="The output label map images, with integer values in it. Each label value specified in the inputLabels is combined into this output label map volume", argstr="--outputBinaryVolumes %s...") class CleanUpOverlapLabelsOutputSpec(TraitedSpec): outputBinaryVolumes = OutputMultiPath(File(exists=True), desc="The output label map images, with integer values in it. Each label value specified in the inputLabels is combined into this output label map volume") class CleanUpOverlapLabels(SEMLikeCommandLine): """title: Clean Up Overla Labels category: Utilities.BRAINS description: Take a series of input binary images and clean up for those overlapped area. Binary volumes given first always wins out version: 0.1.0 contributor: Eun Young Kim """ input_spec = CleanUpOverlapLabelsInputSpec output_spec = CleanUpOverlapLabelsOutputSpec _cmd = " CleanUpOverlapLabels " _outputs_filenames = {'outputBinaryVolumes': 'outputBinaryVolumes.nii'} _redirect_x = False class BRAINSClipInferiorInputSpec(CommandLineInputSpec): inputVolume = File(desc="Input image to make a clipped short int copy from.", exists=True, argstr="--inputVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output image, a short int copy of the upper portion of the input image, filled with BackgroundFillValue.", argstr="--outputVolume %s") acLowerBound = traits.Float( desc=", When the input image to the output image, replace the image with the BackgroundFillValue everywhere below the plane This Far in physical units (millimeters) below (inferior to) the AC point (assumed to be the voxel field middle.) The oversize default was chosen to have no effect. Based on visualizing a thousand masks in the IPIG study, we recommend a limit no smaller than 80.0 mm., ", argstr="--acLowerBound %f") BackgroundFillValue = traits.Str(desc="Fill the background of image with specified short int value. Enter number or use BIGNEG for a large negative number.", argstr="--BackgroundFillValue %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSClipInferiorOutputSpec(TraitedSpec): outputVolume = File(desc="Output image, a short int copy of the upper portion of the input image, filled with BackgroundFillValue.", exists=True) class BRAINSClipInferior(SEMLikeCommandLine): """title: Clip Inferior of Center of Brain (BRAINS) category: Utilities.BRAINS description: This program will read the inputVolume as a short int image, write the BackgroundFillValue everywhere inferior to the lower bound, and write the resulting clipped short int image in the outputVolume. version: 1.0 """ input_spec = BRAINSClipInferiorInputSpec output_spec = BRAINSClipInferiorOutputSpec _cmd = " BRAINSClipInferior " _outputs_filenames = {'outputVolume': 'outputVolume.nii'} _redirect_x = False class GenerateLabelMapFromProbabilityMapInputSpec(CommandLineInputSpec): inputVolumes = InputMultiPath(File(exists=True), desc="The Input probaiblity images to be computed for lable maps", argstr="--inputVolumes %s...") outputLabelVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The Input binary image for region of interest", argstr="--outputLabelVolume %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class GenerateLabelMapFromProbabilityMapOutputSpec(TraitedSpec): outputLabelVolume = File(desc="The Input binary image for region of interest", exists=True) class GenerateLabelMapFromProbabilityMap(SEMLikeCommandLine): """title: Label Map from Probability Images category: Utilities.BRAINS description: Given a list of probability maps for labels, create a discrete label map where only the highest probability region is used for the labeling. version: 0.1 contributor: University of Iowa Department of Psychiatry, http:://www.psychiatry.uiowa.edu """ input_spec = GenerateLabelMapFromProbabilityMapInputSpec output_spec = GenerateLabelMapFromProbabilityMapOutputSpec _cmd = " GenerateLabelMapFromProbabilityMap " _outputs_filenames = {'outputLabelVolume': 'outputLabelVolume.nii.gz'} _redirect_x = False class BRAINSAlignMSPInputSpec(CommandLineInputSpec): inputVolume = File(desc=", The Image to be resampled, ", exists=True, argstr="--inputVolume %s") OutputresampleMSP = traits.Either(traits.Bool, File(), hash_files=False, desc=", The image to be output., ", argstr="--OutputresampleMSP %s") verbose = traits.Bool(desc=", Show more verbose output, ", argstr="--verbose ") resultsDir = traits.Either(traits.Bool, Directory(), hash_files=False, desc=", The directory for the results to be written., ", argstr="--resultsDir %s") writedebuggingImagesLevel = traits.Int(desc=", This flag controls if debugging images are produced. By default value of 0 is no images. Anything greater than zero will be increasing level of debugging images., ", argstr="--writedebuggingImagesLevel %d") mspQualityLevel = traits.Int(desc=", Flag cotrols how agressive the MSP is estimated. 0=quick estimate (9 seconds), 1=normal estimate (11 seconds), 2=great estimate (22 seconds), 3=best estimate (58 seconds)., ", argstr="--mspQualityLevel %d") rescaleIntensities = traits.Bool(desc=", Flag to turn on rescaling image intensities on input., ", argstr="--rescaleIntensities ") trimRescaledIntensities = traits.Float( desc=", Turn on clipping the rescaled image one-tailed on input. Units of standard deviations above the mean. Very large values are very permissive. Non-positive value turns clipping off. Defaults to removing 0.00001 of a normal tail above the mean., ", argstr="--trimRescaledIntensities %f") rescaleIntensitiesOutputRange = InputMultiPath(traits.Int, desc=", This pair of integers gives the lower and upper bounds on the signal portion of the output image. Out-of-field voxels are taken from BackgroundFillValue., ", sep=",", argstr="--rescaleIntensitiesOutputRange %s") BackgroundFillValue = traits.Str(desc="Fill the background of image with specified short int value. Enter number or use BIGNEG for a large negative number.", argstr="--BackgroundFillValue %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSAlignMSPOutputSpec(TraitedSpec): OutputresampleMSP = File(desc=", The image to be output., ", exists=True) resultsDir = Directory(desc=", The directory for the results to be written., ", exists=True) class BRAINSAlignMSP(SEMLikeCommandLine): """title: Align Mid Saggital Brain (BRAINS) category: Utilities.BRAINS description: Resample an image into ACPC alignement ACPCDetect """ input_spec = BRAINSAlignMSPInputSpec output_spec = BRAINSAlignMSPOutputSpec _cmd = " BRAINSAlignMSP " _outputs_filenames = {'OutputresampleMSP': 'OutputresampleMSP.nii', 'resultsDir': 'resultsDir'} _redirect_x = False class BRAINSLandmarkInitializerInputSpec(CommandLineInputSpec): inputFixedLandmarkFilename = File(desc="input fixed landmark. *.fcsv", exists=True, argstr="--inputFixedLandmarkFilename %s") inputMovingLandmarkFilename = File(desc="input moving landmark. *.fcsv", exists=True, argstr="--inputMovingLandmarkFilename %s") inputWeightFilename = File(desc="Input weight file name for landmarks. Higher weighted landmark will be considered more heavily. Weights are propotional, that is the magnitude of weights will be normalized by its minimum and maximum value. ", exists=True, argstr="--inputWeightFilename %s") outputTransformFilename = traits.Either(traits.Bool, File(), hash_files=False, desc="output transform file name (ex: ./outputTransform.mat) ", argstr="--outputTransformFilename %s") class BRAINSLandmarkInitializerOutputSpec(TraitedSpec): outputTransformFilename = File(desc="output transform file name (ex: ./outputTransform.mat) ", exists=True) class BRAINSLandmarkInitializer(SEMLikeCommandLine): """title: BRAINSLandmarkInitializer category: Utilities.BRAINS description: Create transformation file (*mat) from a pair of landmarks (*fcsv) files. version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Eunyoung Regina Kim """ input_spec = BRAINSLandmarkInitializerInputSpec output_spec = BRAINSLandmarkInitializerOutputSpec _cmd = " BRAINSLandmarkInitializer " _outputs_filenames = {'outputTransformFilename': 'outputTransformFilename'} _redirect_x = False class insertMidACPCpointInputSpec(CommandLineInputSpec): inputLandmarkFile = File(desc="Input landmark file (.fcsv)", exists=True, argstr="--inputLandmarkFile %s") outputLandmarkFile = traits.Either(traits.Bool, File(), hash_files=False, desc="Output landmark file (.fcsv)", argstr="--outputLandmarkFile %s") class insertMidACPCpointOutputSpec(TraitedSpec): outputLandmarkFile = File(desc="Output landmark file (.fcsv)", exists=True) class insertMidACPCpoint(SEMLikeCommandLine): """title: MidACPC Landmark Insertion category: Utilities.BRAINS description: This program gets a landmark fcsv file and adds a new landmark as the midpoint between AC and PC points to the output landmark fcsv file contributor: Ali Ghayoor """ input_spec = insertMidACPCpointInputSpec output_spec = insertMidACPCpointOutputSpec _cmd = " insertMidACPCpoint " _outputs_filenames = {'outputLandmarkFile': 'outputLandmarkFile'} _redirect_x = False class BRAINSSnapShotWriterInputSpec(CommandLineInputSpec): inputVolumes = InputMultiPath(File(exists=True), desc="Input image volume list to be extracted as 2D image. Multiple input is possible. At least one input is required.", argstr="--inputVolumes %s...") inputBinaryVolumes = InputMultiPath(File(exists=True), desc="Input mask (binary) volume list to be extracted as 2D image. Multiple input is possible.", argstr="--inputBinaryVolumes %s...") inputSliceToExtractInPhysicalPoint = InputMultiPath(traits.Float, desc="2D slice number of input images. For autoWorkUp output, which AC-PC aligned, 0,0,0 will be the center.", sep=",", argstr="--inputSliceToExtractInPhysicalPoint %s") inputSliceToExtractInIndex = InputMultiPath(traits.Int, desc="2D slice number of input images. For size of 256*256*256 image, 128 is usually used.", sep=",", argstr="--inputSliceToExtractInIndex %s") inputSliceToExtractInPercent = InputMultiPath(traits.Int, desc="2D slice number of input images. Percentage input from 0%-100%. (ex. --inputSliceToExtractInPercent 50,50,50", sep=",", argstr="--inputSliceToExtractInPercent %s") inputPlaneDirection = InputMultiPath(traits.Int, desc="Plane to display. In general, 0=saggital, 1=coronal, and 2=axial plane.", sep=",", argstr="--inputPlaneDirection %s") outputFilename = traits.Either(traits.Bool, File(), hash_files=False, desc="2D file name of input images. Required.", argstr="--outputFilename %s") class BRAINSSnapShotWriterOutputSpec(TraitedSpec): outputFilename = File(desc="2D file name of input images. Required.", exists=True) class BRAINSSnapShotWriter(SEMLikeCommandLine): """title: BRAINSSnapShotWriter category: Utilities.BRAINS description: Create 2D snapshot of input images. Mask images are color-coded version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Eunyoung Regina Kim """ input_spec = BRAINSSnapShotWriterInputSpec output_spec = BRAINSSnapShotWriterOutputSpec _cmd = " BRAINSSnapShotWriter " _outputs_filenames = {'outputFilename': 'outputFilename'} _redirect_x = False class JointHistogramInputSpec(CommandLineInputSpec): inputVolumeInXAxis = File(desc="The Input image to be computed for statistics", exists=True, argstr="--inputVolumeInXAxis %s") inputVolumeInYAxis = File(desc="The Input image to be computed for statistics", exists=True, argstr="--inputVolumeInYAxis %s") inputMaskVolumeInXAxis = File(desc="Input mask volume for inputVolumeInXAxis. Histogram will be computed just for the masked region", exists=True, argstr="--inputMaskVolumeInXAxis %s") inputMaskVolumeInYAxis = File(desc="Input mask volume for inputVolumeInYAxis. Histogram will be computed just for the masked region", exists=True, argstr="--inputMaskVolumeInYAxis %s") outputJointHistogramImage = traits.Str(desc=" output joint histogram image file name. Histogram is usually 2D image. ", argstr="--outputJointHistogramImage %s") verbose = traits.Bool(desc=" print debugging information, ", argstr="--verbose ") class JointHistogramOutputSpec(TraitedSpec): pass class JointHistogram(SEMLikeCommandLine): """title: Write Out Image Intensities category: Utilities.BRAINS description: For Analysis version: 0.1 contributor: University of Iowa Department of Psychiatry, http:://www.psychiatry.uiowa.edu """ input_spec = JointHistogramInputSpec output_spec = JointHistogramOutputSpec _cmd = " JointHistogram " _outputs_filenames = {} _redirect_x = False class ShuffleVectorsModuleInputSpec(CommandLineInputSpec): inputVectorFileBaseName = File(desc="input vector file name prefix. Usually end with .txt and header file has prost fix of .txt.hdr", exists=True, argstr="--inputVectorFileBaseName %s") outputVectorFileBaseName = traits.Either(traits.Bool, File(), hash_files=False, desc="output vector file name prefix. Usually end with .txt and header file has prost fix of .txt.hdr", argstr="--outputVectorFileBaseName %s") resampleProportion = traits.Float(desc="downsample size of 1 will be the same size as the input images, downsample size of 3 will throw 2/3 the vectors away.", argstr="--resampleProportion %f") class ShuffleVectorsModuleOutputSpec(TraitedSpec): outputVectorFileBaseName = File(desc="output vector file name prefix. Usually end with .txt and header file has prost fix of .txt.hdr", exists=True) class ShuffleVectorsModule(SEMLikeCommandLine): """title: ShuffleVectors category: Utilities.BRAINS description: Automatic Segmentation using neural networks version: 1.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans Johnson """ input_spec = ShuffleVectorsModuleInputSpec output_spec = ShuffleVectorsModuleOutputSpec _cmd = " ShuffleVectorsModule " _outputs_filenames = {'outputVectorFileBaseName': 'outputVectorFileBaseName'} _redirect_x = False class ImageRegionPlotterInputSpec(CommandLineInputSpec): inputVolume1 = File(desc="The Input image to be computed for statistics", exists=True, argstr="--inputVolume1 %s") inputVolume2 = File(desc="The Input image to be computed for statistics", exists=True, argstr="--inputVolume2 %s") inputBinaryROIVolume = File(desc="The Input binary image for region of interest", exists=True, argstr="--inputBinaryROIVolume %s") inputLabelVolume = File(desc="The Label Image", exists=True, argstr="--inputLabelVolume %s") numberOfHistogramBins = traits.Int(desc=" the number of histogram levels", argstr="--numberOfHistogramBins %d") outputJointHistogramData = traits.Str(desc=" output data file name", argstr="--outputJointHistogramData %s") useROIAUTO = traits.Bool(desc=" Use ROIAUTO to compute region of interest. This cannot be used with inputLabelVolume", argstr="--useROIAUTO ") useIntensityForHistogram = traits.Bool(desc=" Create Intensity Joint Histogram instead of Quantile Joint Histogram", argstr="--useIntensityForHistogram ") verbose = traits.Bool(desc=" print debugging information, ", argstr="--verbose ") class ImageRegionPlotterOutputSpec(TraitedSpec): pass class ImageRegionPlotter(SEMLikeCommandLine): """title: Write Out Image Intensities category: Utilities.BRAINS description: For Analysis version: 0.1 contributor: University of Iowa Department of Psychiatry, http:://www.psychiatry.uiowa.edu """ input_spec = ImageRegionPlotterInputSpec output_spec = ImageRegionPlotterOutputSpec _cmd = " ImageRegionPlotter " _outputs_filenames = {} _redirect_x = False class fcsv_to_hdf5InputSpec(CommandLineInputSpec): versionID = traits.Str(desc=", Current version ID. It should be match with the version of BCD that will be using the output model file, ", argstr="--versionID %s") landmarksInformationFile = traits.Either(traits.Bool, File(), hash_files=False, desc=", name of HDF5 file to write matrices into, ", argstr="--landmarksInformationFile %s") landmarkTypesList = File(desc=", file containing list of landmark types, ", exists=True, argstr="--landmarkTypesList %s") modelFile = traits.Either(traits.Bool, File(), hash_files=False, desc=", name of HDF5 file containing BRAINSConstellationDetector Model file (LLSMatrices, LLSMeans and LLSSearchRadii), ", argstr="--modelFile %s") landmarkGlobPattern = traits.Str(desc="Glob pattern to select fcsv files", argstr="--landmarkGlobPattern %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class fcsv_to_hdf5OutputSpec(TraitedSpec): landmarksInformationFile = File(desc=", name of HDF5 file to write matrices into, ", exists=True) modelFile = File(desc=", name of HDF5 file containing BRAINSConstellationDetector Model file (LLSMatrices, LLSMeans and LLSSearchRadii), ", exists=True) class fcsv_to_hdf5(SEMLikeCommandLine): """title: fcsv_to_hdf5 (BRAINS) category: Utilities.BRAINS description: Convert a collection of fcsv files to a HDF5 format file """ input_spec = fcsv_to_hdf5InputSpec output_spec = fcsv_to_hdf5OutputSpec _cmd = " fcsv_to_hdf5 " _outputs_filenames = {'modelFile': 'modelFile', 'landmarksInformationFile': 'landmarksInformationFile.h5'} _redirect_x = False class FindCenterOfBrainInputSpec(CommandLineInputSpec): inputVolume = File(desc="The image in which to find the center.", exists=True, argstr="--inputVolume %s") imageMask = File(exists=True, argstr="--imageMask %s") clippedImageMask = traits.Either(traits.Bool, File(), hash_files=False, argstr="--clippedImageMask %s") maximize = traits.Bool(argstr="--maximize ") axis = traits.Int(argstr="--axis %d") otsuPercentileThreshold = traits.Float(argstr="--otsuPercentileThreshold %f") closingSize = traits.Int(argstr="--closingSize %d") headSizeLimit = traits.Float(argstr="--headSizeLimit %f") headSizeEstimate = traits.Float(argstr="--headSizeEstimate %f") backgroundValue = traits.Int(argstr="--backgroundValue %d") generateDebugImages = traits.Bool(argstr="--generateDebugImages ") debugDistanceImage = traits.Either(traits.Bool, File(), hash_files=False, argstr="--debugDistanceImage %s") debugGridImage = traits.Either(traits.Bool, File(), hash_files=False, argstr="--debugGridImage %s") debugAfterGridComputationsForegroundImage = traits.Either(traits.Bool, File(), hash_files=False, argstr="--debugAfterGridComputationsForegroundImage %s") debugClippedImageMask = traits.Either(traits.Bool, File(), hash_files=False, argstr="--debugClippedImageMask %s") debugTrimmedImage = traits.Either(traits.Bool, File(), hash_files=False, argstr="--debugTrimmedImage %s") class FindCenterOfBrainOutputSpec(TraitedSpec): clippedImageMask = File(exists=True) debugDistanceImage = File(exists=True) debugGridImage = File(exists=True) debugAfterGridComputationsForegroundImage = File(exists=True) debugClippedImageMask = File(exists=True) debugTrimmedImage = File(exists=True) class FindCenterOfBrain(SEMLikeCommandLine): """title: Center Of Brain (BRAINS) category: Utilities.BRAINS description: Finds the center point of a brain version: 3.0.0 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson, hans-johnson -at- uiowa.edu, http://wwww.psychiatry.uiowa.edu acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); (1=University of Iowa Department of Psychiatry, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering """ input_spec = FindCenterOfBrainInputSpec output_spec = FindCenterOfBrainOutputSpec _cmd = " FindCenterOfBrain " _outputs_filenames = {'debugClippedImageMask': 'debugClippedImageMask.nii', 'debugTrimmedImage': 'debugTrimmedImage.nii', 'debugDistanceImage': 'debugDistanceImage.nii', 'debugGridImage': 'debugGridImage.nii', 'clippedImageMask': 'clippedImageMask.nii', 'debugAfterGridComputationsForegroundImage': 'debugAfterGridComputationsForegroundImage.nii'} _redirect_x = False nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/000077500000000000000000000000001257611314500235535ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSAlignMSP.py000066400000000000000000000034461257611314500305340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSAlignMSP def test_BRAINSAlignMSP_inputs(): input_map = dict(BackgroundFillValue=dict(argstr='--BackgroundFillValue %s', ), OutputresampleMSP=dict(argstr='--OutputresampleMSP %s', hash_files=False, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), mspQualityLevel=dict(argstr='--mspQualityLevel %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), rescaleIntensities=dict(argstr='--rescaleIntensities ', ), rescaleIntensitiesOutputRange=dict(argstr='--rescaleIntensitiesOutputRange %s', sep=',', ), resultsDir=dict(argstr='--resultsDir %s', hash_files=False, ), terminal_output=dict(nohash=True, ), trimRescaledIntensities=dict(argstr='--trimRescaledIntensities %f', ), verbose=dict(argstr='--verbose ', ), writedebuggingImagesLevel=dict(argstr='--writedebuggingImagesLevel %d', ), ) inputs = BRAINSAlignMSP.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSAlignMSP_outputs(): output_map = dict(OutputresampleMSP=dict(), resultsDir=dict(), ) outputs = BRAINSAlignMSP.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSClipInferior.py000066400000000000000000000024061257611314500315020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSClipInferior def test_BRAINSClipInferior_inputs(): input_map = dict(BackgroundFillValue=dict(argstr='--BackgroundFillValue %s', ), acLowerBound=dict(argstr='--acLowerBound %f', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSClipInferior.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSClipInferior_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSClipInferior.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSConstellationModeler.py000066400000000000000000000037111257611314500332430ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSConstellationModeler def test_BRAINSConstellationModeler_inputs(): input_map = dict(BackgroundFillValue=dict(argstr='--BackgroundFillValue %s', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTrainingList=dict(argstr='--inputTrainingList %s', ), mspQualityLevel=dict(argstr='--mspQualityLevel %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), optimizedLandmarksFilenameExtender=dict(argstr='--optimizedLandmarksFilenameExtender %s', ), outputModel=dict(argstr='--outputModel %s', hash_files=False, ), rescaleIntensities=dict(argstr='--rescaleIntensities ', ), rescaleIntensitiesOutputRange=dict(argstr='--rescaleIntensitiesOutputRange %s', sep=',', ), resultsDir=dict(argstr='--resultsDir %s', hash_files=False, ), saveOptimizedLandmarks=dict(argstr='--saveOptimizedLandmarks ', ), terminal_output=dict(nohash=True, ), trimRescaledIntensities=dict(argstr='--trimRescaledIntensities %f', ), verbose=dict(argstr='--verbose ', ), writedebuggingImagesLevel=dict(argstr='--writedebuggingImagesLevel %d', ), ) inputs = BRAINSConstellationModeler.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSConstellationModeler_outputs(): output_map = dict(outputModel=dict(), resultsDir=dict(), ) outputs = BRAINSConstellationModeler.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSEyeDetector.py000066400000000000000000000022621257611314500313310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSEyeDetector def test_BRAINSEyeDetector_inputs(): input_map = dict(args=dict(argstr='%s', ), debugDir=dict(argstr='--debugDir %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSEyeDetector.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSEyeDetector_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSEyeDetector.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSInitializedControlPoints.py000066400000000000000000000026311257611314500341200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSInitializedControlPoints def test_BRAINSInitializedControlPoints_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputLandmarksFile=dict(argstr='--outputLandmarksFile %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), permuteOrder=dict(argstr='--permuteOrder %s', sep=',', ), splineGridSize=dict(argstr='--splineGridSize %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSInitializedControlPoints.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSInitializedControlPoints_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSInitializedControlPoints.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSLandmarkInitializer.py000066400000000000000000000025071257611314500330540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSLandmarkInitializer def test_BRAINSLandmarkInitializer_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputFixedLandmarkFilename=dict(argstr='--inputFixedLandmarkFilename %s', ), inputMovingLandmarkFilename=dict(argstr='--inputMovingLandmarkFilename %s', ), inputWeightFilename=dict(argstr='--inputWeightFilename %s', ), outputTransformFilename=dict(argstr='--outputTransformFilename %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSLandmarkInitializer.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSLandmarkInitializer_outputs(): output_map = dict(outputTransformFilename=dict(), ) outputs = BRAINSLandmarkInitializer.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSLinearModelerEPCA.py000066400000000000000000000021031257611314500322620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSLinearModelerEPCA def test_BRAINSLinearModelerEPCA_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTrainingList=dict(argstr='--inputTrainingList %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSLinearModelerEPCA.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSLinearModelerEPCA_outputs(): output_map = dict() outputs = BRAINSLinearModelerEPCA.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSLmkTransform.py000066400000000000000000000030111257611314500315250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSLmkTransform def test_BRAINSLmkTransform_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputFixedLandmarks=dict(argstr='--inputFixedLandmarks %s', ), inputMovingLandmarks=dict(argstr='--inputMovingLandmarks %s', ), inputMovingVolume=dict(argstr='--inputMovingVolume %s', ), inputReferenceVolume=dict(argstr='--inputReferenceVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputAffineTransform=dict(argstr='--outputAffineTransform %s', hash_files=False, ), outputResampledVolume=dict(argstr='--outputResampledVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSLmkTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSLmkTransform_outputs(): output_map = dict(outputAffineTransform=dict(), outputResampledVolume=dict(), ) outputs = BRAINSLmkTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSMush.py000066400000000000000000000040711257611314500300310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSMush def test_BRAINSMush_inputs(): input_map = dict(args=dict(argstr='%s', ), boundingBoxSize=dict(argstr='--boundingBoxSize %s', sep=',', ), boundingBoxStart=dict(argstr='--boundingBoxStart %s', sep=',', ), desiredMean=dict(argstr='--desiredMean %f', ), desiredVariance=dict(argstr='--desiredVariance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputFirstVolume=dict(argstr='--inputFirstVolume %s', ), inputMaskVolume=dict(argstr='--inputMaskVolume %s', ), inputSecondVolume=dict(argstr='--inputSecondVolume %s', ), lowerThresholdFactor=dict(argstr='--lowerThresholdFactor %f', ), lowerThresholdFactorPre=dict(argstr='--lowerThresholdFactorPre %f', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputMask=dict(argstr='--outputMask %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), outputWeightsFile=dict(argstr='--outputWeightsFile %s', hash_files=False, ), seed=dict(argstr='--seed %s', sep=',', ), terminal_output=dict(nohash=True, ), upperThresholdFactor=dict(argstr='--upperThresholdFactor %f', ), upperThresholdFactorPre=dict(argstr='--upperThresholdFactorPre %f', ), ) inputs = BRAINSMush.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSMush_outputs(): output_map = dict(outputMask=dict(), outputVolume=dict(), outputWeightsFile=dict(), ) outputs = BRAINSMush.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSSnapShotWriter.py000066400000000000000000000030621257611314500320500ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSSnapShotWriter def test_BRAINSSnapShotWriter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryVolumes=dict(argstr='--inputBinaryVolumes %s...', ), inputPlaneDirection=dict(argstr='--inputPlaneDirection %s', sep=',', ), inputSliceToExtractInIndex=dict(argstr='--inputSliceToExtractInIndex %s', sep=',', ), inputSliceToExtractInPercent=dict(argstr='--inputSliceToExtractInPercent %s', sep=',', ), inputSliceToExtractInPhysicalPoint=dict(argstr='--inputSliceToExtractInPhysicalPoint %s', sep=',', ), inputVolumes=dict(argstr='--inputVolumes %s...', ), outputFilename=dict(argstr='--outputFilename %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSSnapShotWriter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSSnapShotWriter_outputs(): output_map = dict(outputFilename=dict(), ) outputs = BRAINSSnapShotWriter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_BRAINSTransformConvert.py000066400000000000000000000026611257611314500324340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSTransformConvert def test_BRAINSTransformConvert_inputs(): input_map = dict(args=dict(argstr='%s', ), displacementVolume=dict(argstr='--displacementVolume %s', hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTransform=dict(argstr='--inputTransform %s', ), outputPrecisionType=dict(argstr='--outputPrecisionType %s', ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), outputTransformType=dict(argstr='--outputTransformType %s', ), referenceVolume=dict(argstr='--referenceVolume %s', ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSTransformConvert.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSTransformConvert_outputs(): output_map = dict(displacementVolume=dict(), outputTransform=dict(), ) outputs = BRAINSTransformConvert.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_BRAINSTrimForegroundInDirection.py000066400000000000000000000030121257611314500341260ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/utilities/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import BRAINSTrimForegroundInDirection def test_BRAINSTrimForegroundInDirection_inputs(): input_map = dict(BackgroundFillValue=dict(argstr='--BackgroundFillValue %s', ), args=dict(argstr='%s', ), closingSize=dict(argstr='--closingSize %d', ), directionCode=dict(argstr='--directionCode %d', ), environ=dict(nohash=True, usedefault=True, ), headSizeLimit=dict(argstr='--headSizeLimit %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), otsuPercentileThreshold=dict(argstr='--otsuPercentileThreshold %f', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = BRAINSTrimForegroundInDirection.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSTrimForegroundInDirection_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSTrimForegroundInDirection.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_CleanUpOverlapLabels.py000066400000000000000000000021721257611314500322210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import CleanUpOverlapLabels def test_CleanUpOverlapLabels_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryVolumes=dict(argstr='--inputBinaryVolumes %s...', ), outputBinaryVolumes=dict(argstr='--outputBinaryVolumes %s...', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = CleanUpOverlapLabels.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CleanUpOverlapLabels_outputs(): output_map = dict(outputBinaryVolumes=dict(), ) outputs = CleanUpOverlapLabels.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_FindCenterOfBrain.py000066400000000000000000000044001257611314500314740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import FindCenterOfBrain def test_FindCenterOfBrain_inputs(): input_map = dict(args=dict(argstr='%s', ), axis=dict(argstr='--axis %d', ), backgroundValue=dict(argstr='--backgroundValue %d', ), clippedImageMask=dict(argstr='--clippedImageMask %s', hash_files=False, ), closingSize=dict(argstr='--closingSize %d', ), debugAfterGridComputationsForegroundImage=dict(argstr='--debugAfterGridComputationsForegroundImage %s', hash_files=False, ), debugClippedImageMask=dict(argstr='--debugClippedImageMask %s', hash_files=False, ), debugDistanceImage=dict(argstr='--debugDistanceImage %s', hash_files=False, ), debugGridImage=dict(argstr='--debugGridImage %s', hash_files=False, ), debugTrimmedImage=dict(argstr='--debugTrimmedImage %s', hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), generateDebugImages=dict(argstr='--generateDebugImages ', ), headSizeEstimate=dict(argstr='--headSizeEstimate %f', ), headSizeLimit=dict(argstr='--headSizeLimit %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), imageMask=dict(argstr='--imageMask %s', ), inputVolume=dict(argstr='--inputVolume %s', ), maximize=dict(argstr='--maximize ', ), otsuPercentileThreshold=dict(argstr='--otsuPercentileThreshold %f', ), terminal_output=dict(nohash=True, ), ) inputs = FindCenterOfBrain.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FindCenterOfBrain_outputs(): output_map = dict(clippedImageMask=dict(), debugAfterGridComputationsForegroundImage=dict(), debugClippedImageMask=dict(), debugDistanceImage=dict(), debugGridImage=dict(), debugTrimmedImage=dict(), ) outputs = FindCenterOfBrain.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_GenerateLabelMapFromProbabilityMap.py000066400000000000000000000023521257611314500347520ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/semtools/utilities/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import GenerateLabelMapFromProbabilityMap def test_GenerateLabelMapFromProbabilityMap_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolumes=dict(argstr='--inputVolumes %s...', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputLabelVolume=dict(argstr='--outputLabelVolume %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = GenerateLabelMapFromProbabilityMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GenerateLabelMapFromProbabilityMap_outputs(): output_map = dict(outputLabelVolume=dict(), ) outputs = GenerateLabelMapFromProbabilityMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_ImageRegionPlotter.py000066400000000000000000000027571257611314500317670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import ImageRegionPlotter def test_ImageRegionPlotter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputBinaryROIVolume=dict(argstr='--inputBinaryROIVolume %s', ), inputLabelVolume=dict(argstr='--inputLabelVolume %s', ), inputVolume1=dict(argstr='--inputVolume1 %s', ), inputVolume2=dict(argstr='--inputVolume2 %s', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), outputJointHistogramData=dict(argstr='--outputJointHistogramData %s', ), terminal_output=dict(nohash=True, ), useIntensityForHistogram=dict(argstr='--useIntensityForHistogram ', ), useROIAUTO=dict(argstr='--useROIAUTO ', ), verbose=dict(argstr='--verbose ', ), ) inputs = ImageRegionPlotter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageRegionPlotter_outputs(): output_map = dict() outputs = ImageRegionPlotter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_JointHistogram.py000066400000000000000000000024701257611314500311600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import JointHistogram def test_JointHistogram_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMaskVolumeInXAxis=dict(argstr='--inputMaskVolumeInXAxis %s', ), inputMaskVolumeInYAxis=dict(argstr='--inputMaskVolumeInYAxis %s', ), inputVolumeInXAxis=dict(argstr='--inputVolumeInXAxis %s', ), inputVolumeInYAxis=dict(argstr='--inputVolumeInYAxis %s', ), outputJointHistogramImage=dict(argstr='--outputJointHistogramImage %s', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = JointHistogram.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JointHistogram_outputs(): output_map = dict() outputs = JointHistogram.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_ShuffleVectorsModule.py000066400000000000000000000023221257611314500323230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import ShuffleVectorsModule def test_ShuffleVectorsModule_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVectorFileBaseName=dict(argstr='--inputVectorFileBaseName %s', ), outputVectorFileBaseName=dict(argstr='--outputVectorFileBaseName %s', hash_files=False, ), resampleProportion=dict(argstr='--resampleProportion %f', ), terminal_output=dict(nohash=True, ), ) inputs = ShuffleVectorsModule.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ShuffleVectorsModule_outputs(): output_map = dict(outputVectorFileBaseName=dict(), ) outputs = ShuffleVectorsModule.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_fcsv_to_hdf5.py000066400000000000000000000025611257611314500305710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import fcsv_to_hdf5 def test_fcsv_to_hdf5_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), landmarkGlobPattern=dict(argstr='--landmarkGlobPattern %s', ), landmarkTypesList=dict(argstr='--landmarkTypesList %s', ), landmarksInformationFile=dict(argstr='--landmarksInformationFile %s', hash_files=False, ), modelFile=dict(argstr='--modelFile %s', hash_files=False, ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), terminal_output=dict(nohash=True, ), versionID=dict(argstr='--versionID %s', ), ) inputs = fcsv_to_hdf5.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_fcsv_to_hdf5_outputs(): output_map = dict(landmarksInformationFile=dict(), modelFile=dict(), ) outputs = fcsv_to_hdf5.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_insertMidACPCpoint.py000066400000000000000000000021451257611314500316550ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import insertMidACPCpoint def test_insertMidACPCpoint_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputLandmarkFile=dict(argstr='--inputLandmarkFile %s', ), outputLandmarkFile=dict(argstr='--outputLandmarkFile %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = insertMidACPCpoint.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_insertMidACPCpoint_outputs(): output_map = dict(outputLandmarkFile=dict(), ) outputs = insertMidACPCpoint.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_landmarksConstellationAligner.py000066400000000000000000000022531257611314500342330ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import landmarksConstellationAligner def test_landmarksConstellationAligner_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputLandmarksPaired=dict(argstr='--inputLandmarksPaired %s', ), outputLandmarksPaired=dict(argstr='--outputLandmarksPaired %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = landmarksConstellationAligner.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_landmarksConstellationAligner_outputs(): output_map = dict(outputLandmarksPaired=dict(), ) outputs = landmarksConstellationAligner.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/semtools/utilities/tests/test_auto_landmarksConstellationWeights.py000066400000000000000000000024171257611314500342660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.semtools.utilities.brains import landmarksConstellationWeights def test_landmarksConstellationWeights_inputs(): input_map = dict(LLSModel=dict(argstr='--LLSModel %s', ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTemplateModel=dict(argstr='--inputTemplateModel %s', ), inputTrainingList=dict(argstr='--inputTrainingList %s', ), outputWeightsList=dict(argstr='--outputWeightsList %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = landmarksConstellationWeights.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_landmarksConstellationWeights_outputs(): output_map = dict(outputWeightsList=dict(), ) outputs = landmarksConstellationWeights.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/setup.py000066400000000000000000000021511257611314500202420ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: def configuration(parent_package='', top_path=None): from numpy.distutils.misc_util import Configuration config = Configuration('interfaces', parent_package, top_path) config.add_subpackage('afni') config.add_subpackage('ants') config.add_subpackage('camino') config.add_subpackage('camino2trackvis') config.add_subpackage('cmtk') config.add_subpackage('diffusion_toolkit') config.add_subpackage('dipy') config.add_subpackage('elastix') config.add_subpackage('freesurfer') config.add_subpackage('fsl') config.add_subpackage('mne') config.add_subpackage('mrtrix') config.add_subpackage('mrtrix3') config.add_subpackage('nipy') config.add_subpackage('spm') config.add_subpackage('slicer') config.add_subpackage('mipav') config.add_data_dir('script_templates') config.add_data_dir('tests') return config if __name__ == '__main__': from numpy.distutils.core import setup setup(**configuration(top_path='').todict()) nipype-0.11.0/nipype/interfaces/slicer/000077500000000000000000000000001257611314500200125ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/__init__.py000066400000000000000000000006071257611314500221260ustar00rootroot00000000000000from diffusion import * from segmentation import * from filtering import * from utilities import EMSegmentTransformToNewFormat from surface import MergeModels, ModelToLabelMap, GrayscaleModelMaker, ProbeVolumeWithModel, LabelMapSmoothing, ModelMaker from quantification import * from legacy import * from registration import * from converters import DicomToNrrdConverter, OrientScalarVolume nipype-0.11.0/nipype/interfaces/slicer/base.py000066400000000000000000000001351257611314500212750ustar00rootroot00000000000000from ..base import SEMLikeCommandLine class SlicerCommandLine(SEMLikeCommandLine): pass nipype-0.11.0/nipype/interfaces/slicer/converters.py000066400000000000000000000130231257611314500225550ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class DicomToNrrdConverterInputSpec(CommandLineInputSpec): inputDicomDirectory = Directory(desc="Directory holding Dicom series", exists=True, argstr="--inputDicomDirectory %s") outputDirectory = traits.Either(traits.Bool, Directory(), hash_files=False, desc="Directory holding the output NRRD format", argstr="--outputDirectory %s") outputVolume = traits.Str(desc="Output filename (.nhdr or .nrrd)", argstr="--outputVolume %s") smallGradientThreshold = traits.Float(desc="If a gradient magnitude is greater than 0 and less than smallGradientThreshold, then DicomToNrrdConverter will display an error message and quit, unless the useBMatrixGradientDirections option is set.", argstr="--smallGradientThreshold %f") writeProtocolGradientsFile = traits.Bool(desc="Write the protocol gradients to a file suffixed by \'.txt\' as they were specified in the procol by multiplying each diffusion gradient direction by the measurement frame. This file is for debugging purposes only, the format is not fixed, and will likely change as debugging of new dicom formats is necessary.", argstr="--writeProtocolGradientsFile ") useIdentityMeaseurementFrame = traits.Bool(desc="Adjust all the gradients so that the measurement frame is an identity matrix.", argstr="--useIdentityMeaseurementFrame ") useBMatrixGradientDirections = traits.Bool(desc="Fill the nhdr header with the gradient directions and bvalues computed out of the BMatrix. Only changes behavior for Siemens data.", argstr="--useBMatrixGradientDirections ") class DicomToNrrdConverterOutputSpec(TraitedSpec): outputDirectory = Directory(desc="Directory holding the output NRRD format", exists=True) class DicomToNrrdConverter(SEMLikeCommandLine): """title: DICOM to NRRD Converter category: Converters description: Converts diffusion weighted MR images in dicom series into Nrrd format for analysis in Slicer. This program has been tested on only a limited subset of DTI dicom formats available from Siemens, GE, and Phillips scanners. Work in progress to support dicom multi-frame data. The program parses dicom header to extract necessary information about measurement frame, diffusion weighting directions, b-values, etc, and write out a nrrd image. For non-diffusion weighted dicom images, it loads in an entire dicom series and writes out a single dicom volume in a .nhdr/.raw pair. version: 0.2.0.$Revision: 916 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DicomToNrrdConverter license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Xiaodong Tao (GE), Vince Magnotta (UIowa), Hans Johnson (UIowa) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Additional support for DTI data produced on Philips scanners was contributed by Vincent Magnotta and Hans Johnson at the University of Iowa. """ input_spec = DicomToNrrdConverterInputSpec output_spec = DicomToNrrdConverterOutputSpec _cmd = "DicomToNrrdConverter " _outputs_filenames = {'outputDirectory':'outputDirectory'} class OrientScalarVolumeInputSpec(CommandLineInputSpec): inputVolume1 = File(position=-2, desc="Input volume 1", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="The oriented volume", argstr="%s") orientation = traits.Enum("Axial", "Coronal", "Sagittal", "RIP", "LIP", "RSP", "LSP", "RIA", "LIA", "RSA", "LSA", "IRP", "ILP", "SRP", "SLP", "IRA", "ILA", "SRA", "SLA", "RPI", "LPI", "RAI", "LAI", "RPS", "LPS", "RAS", "LAS", "PRI", "PLI", "ARI", "ALI", "PRS", "PLS", "ARS", "ALS", "IPR", "SPR", "IAR", "SAR", "IPL", "SPL", "IAL", "SAL", "PIR", "PSR", "AIR", "ASR", "PIL", "PSL", "AIL", "ASL", desc="Orientation choices", argstr="--orientation %s") class OrientScalarVolumeOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="The oriented volume", exists=True) class OrientScalarVolume(SEMLikeCommandLine): """title: Orient Scalar Volume category: Converters description: Orients an output volume. Rearranges the slices in a volume according to the selected orientation. The slices are not interpolated. They are just reordered and/or permuted. The resulting volume will cover the original volume. NOTE: since Slicer takes into account the orientation of a volume, the re-oriented volume will not show any difference from the original volume, To see the difference, save the volume and display it with a system that either ignores the orientation of the image (e.g. Paraview) or displays individual images. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/OrientImage contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = OrientScalarVolumeInputSpec output_spec = OrientScalarVolumeOutputSpec _cmd = "OrientScalarVolume " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/diffusion/000077500000000000000000000000001257611314500220005ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/diffusion/__init__.py000066400000000000000000000003431257611314500241110ustar00rootroot00000000000000from diffusion import ResampleDTIVolume, DWIRicianLMMSEFilter, TractographyLabelMapSeeding, DWIJointRicianLMMSEFilter, DiffusionWeightedVolumeMasking, DTIimport, DWIToDTIEstimation, DiffusionTensorScalarMeasurements, DTIexport nipype-0.11.0/nipype/interfaces/slicer/diffusion/diffusion.py000066400000000000000000000555321257611314500243520ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ResampleDTIVolumeInputSpec(CommandLineInputSpec): inputVolume = File(position=-2, desc="Input volume to be resampled", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Resampled Volume", argstr="%s") Reference = File(desc="Reference Volume (spacing,size,orientation,origin)", exists=True, argstr="--Reference %s") transformationFile = File(exists=True, argstr="--transformationFile %s") defField = File(desc="File containing the deformation field (3D vector image containing vectors with 3 components)", exists=True, argstr="--defField %s") hfieldtype = traits.Enum("displacement", "h-Field", desc="Set if the deformation field is an -Field", argstr="--hfieldtype %s") interpolation = traits.Enum("linear", "nn", "ws", "bs", desc="Sampling algorithm (linear , nn (nearest neighborhoor), ws (WindowedSinc), bs (BSpline) )", argstr="--interpolation %s") correction = traits.Enum("zero", "none", "abs", "nearest", desc="Correct the tensors if computed tensor is not semi-definite positive", argstr="--correction %s") transform_tensor_method = traits.Enum("PPD", "FS", desc="Chooses between 2 methods to transform the tensors: Finite Strain (FS), faster but less accurate, or Preservation of the Principal Direction (PPD)", argstr="--transform_tensor_method %s") transform_order = traits.Enum("input-to-output", "output-to-input", desc="Select in what order the transforms are read", argstr="--transform_order %s") notbulk = traits.Bool(desc="The transform following the BSpline transform is not set as a bulk transform for the BSpline transform", argstr="--notbulk ") spaceChange = traits.Bool(desc="Space Orientation between transform and image is different (RAS/LPS) (warning: if the transform is a Transform Node in Slicer3, do not select)", argstr="--spaceChange ") rotation_point = traits.List(desc="Center of rotation (only for rigid and affine transforms)", argstr="--rotation_point %s") centered_transform = traits.Bool(desc="Set the center of the transformation to the center of the input image (only for rigid and affine transforms)", argstr="--centered_transform ") image_center = traits.Enum("input", "output", desc="Image to use to center the transform (used only if \'Centered Transform\' is selected)", argstr="--image_center %s") Inverse_ITK_Transformation = traits.Bool(desc="Inverse the transformation before applying it from output image to input image (only for rigid and affine transforms)", argstr="--Inverse_ITK_Transformation ") spacing = InputMultiPath(traits.Float, desc="Spacing along each dimension (0 means use input spacing)", sep=",", argstr="--spacing %s") size = InputMultiPath(traits.Float, desc="Size along each dimension (0 means use input size)", sep=",", argstr="--size %s") origin = traits.List(desc="Origin of the output Image", argstr="--origin %s") direction_matrix = InputMultiPath(traits.Float, desc="9 parameters of the direction matrix by rows (ijk to LPS if LPS transform, ijk to RAS if RAS transform)", sep=",", argstr="--direction_matrix %s") number_of_thread = traits.Int(desc="Number of thread used to compute the output image", argstr="--number_of_thread %d") default_pixel_value = traits.Float(desc="Default pixel value for samples falling outside of the input region", argstr="--default_pixel_value %f") window_function = traits.Enum("h", "c", "w", "l", "b", desc="Window Function , h = Hamming , c = Cosine , w = Welch , l = Lanczos , b = Blackman", argstr="--window_function %s") spline_order = traits.Int(desc="Spline Order (Spline order may be from 0 to 5)", argstr="--spline_order %d") transform_matrix = InputMultiPath(traits.Float, desc="12 parameters of the transform matrix by rows ( --last 3 being translation-- )", sep=",", argstr="--transform_matrix %s") transform = traits.Enum("rt", "a", desc="Transform algorithm, rt = Rigid Transform, a = Affine Transform", argstr="--transform %s") class ResampleDTIVolumeOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Resampled Volume", exists=True) class ResampleDTIVolume(SEMLikeCommandLine): """title: Resample DTI Volume category: Diffusion.Diffusion Tensor Images description: Resampling an image is a very important task in image analysis. It is especially important in the frame of image registration. This module implements DT image resampling through the use of itk Transforms. The resampling is controlled by the Output Spacing. "Resampling" is performed in space coordinates, not pixel/grid coordinates. It is quite important to ensure that image spacing is properly set on the images involved. The interpolator is required since the mapping from one space to the other will often require evaluation of the intensity of the image at non-grid positions. version: 0.1 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ResampleDTI contributor: Francois Budin (UNC) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Information on the National Centers for Biomedical Computing can be obtained from http://nihroadmap.nih.gov/bioinformatics """ input_spec = ResampleDTIVolumeInputSpec output_spec = ResampleDTIVolumeOutputSpec _cmd = "ResampleDTIVolume " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class DWIRicianLMMSEFilterInputSpec(CommandLineInputSpec): iter = traits.Int(desc="Number of iterations for the noise removal filter.", argstr="--iter %d") re = InputMultiPath(traits.Int, desc="Estimation radius.", sep=",", argstr="--re %s") rf = InputMultiPath(traits.Int, desc="Filtering radius.", sep=",", argstr="--rf %s") mnvf = traits.Int(desc="Minimum number of voxels in kernel used for filtering.", argstr="--mnvf %d") mnve = traits.Int(desc="Minimum number of voxels in kernel used for estimation.", argstr="--mnve %d") minnstd = traits.Int(desc="Minimum allowed noise standard deviation.", argstr="--minnstd %d") maxnstd = traits.Int(desc="Maximum allowed noise standard deviation.", argstr="--maxnstd %d") hrf = traits.Float(desc="How many histogram bins per unit interval.", argstr="--hrf %f") uav = traits.Bool(desc="Use absolute value in case of negative square.", argstr="--uav ") inputVolume = File(position=-2, desc="Input DWI volume.", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output DWI volume.", argstr="%s") compressOutput = traits.Bool(desc="Compress the data of the compressed file using gzip", argstr="--compressOutput ") class DWIRicianLMMSEFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output DWI volume.", exists=True) class DWIRicianLMMSEFilter(SEMLikeCommandLine): """title: DWI Rician LMMSE Filter category: Diffusion.Diffusion Weighted Images description: This module reduces noise (or unwanted detail) on a set of diffusion weighted images. For this, it filters the image in the mean squared error sense using a Rician noise model. Images corresponding to each gradient direction, including baseline, are processed individually. The noise parameter is automatically estimated (noise estimation improved but slower). Note that this is a general purpose filter for MRi images. The module jointLMMSE has been specifically designed for DWI volumes and shows a better performance, so its use is recommended instead. A complete description of the algorithm in this module can be found in: S. Aja-Fernandez, M. Niethammer, M. Kubicki, M. Shenton, and C.-F. Westin. Restoration of DWI data using a Rician LMMSE estimator. IEEE Transactions on Medical Imaging, 27(10): pp. 1389-1403, Oct. 2008. version: 0.1.1.$Revision: 1 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/RicianLMMSEImageFilter contributor: Antonio Tristan Vega (UVa), Santiago Aja Fernandez (UVa), Marc Niethammer (UNC) acknowledgements: Partially founded by grant number TEC2007-67073/TCM from the Comision Interministerial de Ciencia y Tecnologia (Spain). """ input_spec = DWIRicianLMMSEFilterInputSpec output_spec = DWIRicianLMMSEFilterOutputSpec _cmd = "DWIRicianLMMSEFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class TractographyLabelMapSeedingInputSpec(CommandLineInputSpec): InputVolume = File(position=-2, desc="Input DTI volume", exists=True, argstr="%s") inputroi = File(desc="Label map with seeding ROIs", exists=True, argstr="--inputroi %s") OutputFibers = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Tractography result", argstr="%s") useindexspace = traits.Bool(desc="Seed at IJK voxel grid", argstr="--useindexspace ") seedspacing = traits.Float(desc="Spacing (in mm) between seed points, only matters if use Use Index Space is off", argstr="--seedspacing %f") randomgrid = traits.Bool(desc="Enable random placing of seeds", argstr="--randomgrid ") clthreshold = traits.Float(desc="Minimum Linear Measure for the seeding to start.", argstr="--clthreshold %f") minimumlength = traits.Float(desc="Minimum length of the fibers (in mm)", argstr="--minimumlength %f") maximumlength = traits.Float(desc="Maximum length of fibers (in mm)", argstr="--maximumlength %f") stoppingmode = traits.Enum("LinearMeasure", "FractionalAnisotropy", desc="Tensor measurement used to stop the tractography", argstr="--stoppingmode %s") stoppingvalue = traits.Float(desc="Tractography will stop when the stopping measurement drops below this value", argstr="--stoppingvalue %f") stoppingcurvature = traits.Float(desc="Tractography will stop if radius of curvature becomes smaller than this number units are degrees per mm", argstr="--stoppingcurvature %f") integrationsteplength = traits.Float(desc="Distance between points on the same fiber in mm", argstr="--integrationsteplength %f") label = traits.Int(desc="Label value that defines seeding region.", argstr="--label %d") writetofile = traits.Bool(desc="Write fibers to disk or create in the scene?", argstr="--writetofile ") outputdirectory = traits.Either(traits.Bool, Directory(), hash_files=False, desc="Directory in which to save fiber(s)", argstr="--outputdirectory %s") name = traits.Str(desc="Name to use for fiber files", argstr="--name %s") class TractographyLabelMapSeedingOutputSpec(TraitedSpec): OutputFibers = File(position=-1, desc="Tractography result", exists=True) outputdirectory = Directory(desc="Directory in which to save fiber(s)", exists=True) class TractographyLabelMapSeeding(SEMLikeCommandLine): """title: Tractography Label Map Seeding category: Diffusion.Diffusion Tensor Images description: Seed tracts on a Diffusion Tensor Image (DT) from a label map version: 0.1.0.$Revision: 1892 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Seeding license: slicer3 contributor: Raul San Jose (SPL, BWH), Demian Wassermann (SPL, BWH) acknowledgements: Laboratory of Mathematics in Imaging. This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = TractographyLabelMapSeedingInputSpec output_spec = TractographyLabelMapSeedingOutputSpec _cmd = "TractographyLabelMapSeeding " _outputs_filenames = {'OutputFibers':'OutputFibers.vtk','outputdirectory':'outputdirectory'} class DWIJointRicianLMMSEFilterInputSpec(CommandLineInputSpec): re = InputMultiPath(traits.Int, desc="Estimation radius.", sep=",", argstr="--re %s") rf = InputMultiPath(traits.Int, desc="Filtering radius.", sep=",", argstr="--rf %s") ng = traits.Int(desc="The number of the closest gradients that are used to jointly filter a given gradient direction (0 to use all).", argstr="--ng %d") inputVolume = File(position=-2, desc="Input DWI volume.", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output DWI volume.", argstr="%s") compressOutput = traits.Bool(desc="Compress the data of the compressed file using gzip", argstr="--compressOutput ") class DWIJointRicianLMMSEFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output DWI volume.", exists=True) class DWIJointRicianLMMSEFilter(SEMLikeCommandLine): """title: DWI Joint Rician LMMSE Filter category: Diffusion.Diffusion Weighted Images description: This module reduces Rician noise (or unwanted detail) on a set of diffusion weighted images. For this, it filters the image in the mean squared error sense using a Rician noise model. The N closest gradient directions to the direction being processed are filtered together to improve the results: the noise-free signal is seen as an n-diemensional vector which has to be estimated with the LMMSE method from a set of corrupted measurements. To that end, the covariance matrix of the noise-free vector and the cross covariance between this signal and the noise have to be estimated, which is done taking into account the image formation process. The noise parameter is automatically estimated from a rough segmentation of the background of the image. In this area the signal is simply 0, so that Rician statistics reduce to Rayleigh and the noise power can be easily estimated from the mode of the histogram. A complete description of the algorithm may be found in: Antonio Tristan-Vega and Santiago Aja-Fernandez, DWI filtering using joint information for DTI and HARDI, Medical Image Analysis, Volume 14, Issue 2, Pages 205-218. 2010. version: 0.1.1.$Revision: 1 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/JointRicianLMMSEImageFilter contributor: Antonio Tristan Vega (UVa), Santiago Aja Fernandez (UVa) acknowledgements: Partially founded by grant number TEC2007-67073/TCM from the Comision Interministerial de Ciencia y Tecnologia (Spain). """ input_spec = DWIJointRicianLMMSEFilterInputSpec output_spec = DWIJointRicianLMMSEFilterOutputSpec _cmd = "DWIJointRicianLMMSEFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class DiffusionWeightedVolumeMaskingInputSpec(CommandLineInputSpec): inputVolume = File(position=-4, desc="Input DWI volume", exists=True, argstr="%s") outputBaseline = traits.Either(traits.Bool, File(), position=-2, hash_files=False, desc="Estimated baseline volume", argstr="%s") thresholdMask = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Otsu Threshold Mask", argstr="%s") otsuomegathreshold = traits.Float(desc="Control the sharpness of the threshold in the Otsu computation. 0: lower threshold, 1: higher threhold", argstr="--otsuomegathreshold %f") removeislands = traits.Bool(desc="Remove Islands in Threshold Mask?", argstr="--removeislands ") class DiffusionWeightedVolumeMaskingOutputSpec(TraitedSpec): outputBaseline = File(position=-2, desc="Estimated baseline volume", exists=True) thresholdMask = File(position=-1, desc="Otsu Threshold Mask", exists=True) class DiffusionWeightedVolumeMasking(SEMLikeCommandLine): """title: Diffusion Weighted Volume Masking category: Diffusion.Diffusion Weighted Images description:

Performs a mask calculation from a diffusion weighted (DW) image.

Starting from a dw image, this module computes the baseline image averaging all the images without diffusion weighting and then applies the otsu segmentation algorithm in order to produce a mask. this mask can then be used when estimating the diffusion tensor (dt) image, not to estimate tensors all over the volume.

version: 0.1.0.$Revision: 1892 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DiffusionWeightedMasking license: slicer3 contributor: Demian Wassermann (SPL, BWH) """ input_spec = DiffusionWeightedVolumeMaskingInputSpec output_spec = DiffusionWeightedVolumeMaskingOutputSpec _cmd = "DiffusionWeightedVolumeMasking " _outputs_filenames = {'outputBaseline':'outputBaseline.nii','thresholdMask':'thresholdMask.nii'} class DTIimportInputSpec(CommandLineInputSpec): inputFile = File(position=-2, desc="Input DTI file", exists=True, argstr="%s") outputTensor = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output DTI volume", argstr="%s") testingmode = traits.Bool(desc="Enable testing mode. Sample helix file (helix-DTI.nhdr) will be loaded into Slicer and converted in Nifti.", argstr="--testingmode ") class DTIimportOutputSpec(TraitedSpec): outputTensor = File(position=-1, desc="Output DTI volume", exists=True) class DTIimport(SEMLikeCommandLine): """title: DTIimport category: Diffusion.Diffusion Data Conversion description: Import tensor datasets from various formats, including the NifTi file format version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DTIImport contributor: Sonia Pujol (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NA-MIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = DTIimportInputSpec output_spec = DTIimportOutputSpec _cmd = "DTIimport " _outputs_filenames = {'outputTensor':'outputTensor.nii'} class DWIToDTIEstimationInputSpec(CommandLineInputSpec): inputVolume = File(position=-3, desc="Input DWI volume", exists=True, argstr="%s") mask = File(desc="Mask where the tensors will be computed", exists=True, argstr="--mask %s") outputTensor = traits.Either(traits.Bool, File(), position=-2, hash_files=False, desc="Estimated DTI volume", argstr="%s") outputBaseline = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Estimated baseline volume", argstr="%s") enumeration = traits.Enum("LS", "WLS", desc="LS: Least Squares, WLS: Weighted Least Squares", argstr="--enumeration %s") shiftNeg = traits.Bool(desc="Shift eigenvalues so all are positive (accounts for bad tensors related to noise or acquisition error)", argstr="--shiftNeg ") class DWIToDTIEstimationOutputSpec(TraitedSpec): outputTensor = File(position=-2, desc="Estimated DTI volume", exists=True) outputBaseline = File(position=-1, desc="Estimated baseline volume", exists=True) class DWIToDTIEstimation(SEMLikeCommandLine): """title: DWI to DTI Estimation category: Diffusion.Diffusion Weighted Images description: Performs a tensor model estimation from diffusion weighted images. There are three estimation methods available: least squares, weigthed least squares and non-linear estimation. The first method is the traditional method for tensor estimation and the fastest one. Weighted least squares takes into account the noise characteristics of the MRI images to weight the DWI samples used in the estimation based on its intensity magnitude. The last method is the more complex. version: 0.1.0.$Revision: 1892 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DiffusionTensorEstimation license: slicer3 contributor: Raul San Jose (SPL, BWH) acknowledgements: This command module is based on the estimation functionality provided by the Teem library. This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = DWIToDTIEstimationInputSpec output_spec = DWIToDTIEstimationOutputSpec _cmd = "DWIToDTIEstimation " _outputs_filenames = {'outputTensor':'outputTensor.nii','outputBaseline':'outputBaseline.nii'} class DiffusionTensorScalarMeasurementsInputSpec(CommandLineInputSpec): inputVolume = File(position=-3, desc="Input DTI volume", exists=True, argstr="%s") outputScalar = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Scalar volume derived from tensor", argstr="%s") enumeration = traits.Enum("Trace", "Determinant", "RelativeAnisotropy", "FractionalAnisotropy", "Mode", "LinearMeasure", "PlanarMeasure", "SphericalMeasure", "MinEigenvalue", "MidEigenvalue", "MaxEigenvalue", "MaxEigenvalueProjectionX", "MaxEigenvalueProjectionY", "MaxEigenvalueProjectionZ", "RAIMaxEigenvecX", "RAIMaxEigenvecY", "RAIMaxEigenvecZ", "MaxEigenvecX", "MaxEigenvecY", "MaxEigenvecZ", "D11", "D22", "D33", "ParallelDiffusivity", "PerpendicularDffusivity", desc="An enumeration of strings", argstr="--enumeration %s") class DiffusionTensorScalarMeasurementsOutputSpec(TraitedSpec): outputScalar = File(position=-1, desc="Scalar volume derived from tensor", exists=True) class DiffusionTensorScalarMeasurements(SEMLikeCommandLine): """title: Diffusion Tensor Scalar Measurements category: Diffusion.Diffusion Tensor Images description: Compute a set of different scalar measurements from a tensor field, specially oriented for Diffusion Tensors where some rotationally invariant measurements, like Fractional Anisotropy, are highly used to describe the anistropic behaviour of the tensor. version: 0.1.0.$Revision: 1892 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DiffusionTensorMathematics contributor: Raul San Jose (SPL, BWH) acknowledgements: LMI """ input_spec = DiffusionTensorScalarMeasurementsInputSpec output_spec = DiffusionTensorScalarMeasurementsOutputSpec _cmd = "DiffusionTensorScalarMeasurements " _outputs_filenames = {'outputScalar':'outputScalar.nii'} class DTIexportInputSpec(CommandLineInputSpec): inputTensor = File(position=-2, desc="Input DTI volume", exists=True, argstr="%s") outputFile = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output DTI file", argstr="%s") class DTIexportOutputSpec(TraitedSpec): outputFile = File(position=-1, desc="Output DTI file", exists=True) class DTIexport(SEMLikeCommandLine): """title: DTIexport category: Diffusion.Diffusion Data Conversion description: Export DTI data to various file formats version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/DTIExport contributor: Sonia Pujol (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NA-MIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = DTIexportInputSpec output_spec = DTIexportOutputSpec _cmd = "DTIexport " _outputs_filenames = {'outputFile':'outputFile'} nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/000077500000000000000000000000001257611314500231425ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DTIexport.py000066400000000000000000000020551257611314500274670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DTIexport def test_DTIexport_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputTensor=dict(argstr='%s', position=-2, ), outputFile=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = DTIexport.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTIexport_outputs(): output_map = dict(outputFile=dict(position=-1, ), ) outputs = DTIexport.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DTIimport.py000066400000000000000000000021441257611314500274570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DTIimport def test_DTIimport_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputFile=dict(argstr='%s', position=-2, ), outputTensor=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), testingmode=dict(argstr='--testingmode ', ), ) inputs = DTIimport.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DTIimport_outputs(): output_map = dict(outputTensor=dict(position=-1, ), ) outputs = DTIimport.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DWIJointRicianLMMSEFilter.py000066400000000000000000000025051257611314500323260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DWIJointRicianLMMSEFilter def test_DWIJointRicianLMMSEFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), compressOutput=dict(argstr='--compressOutput ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), ng=dict(argstr='--ng %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), re=dict(argstr='--re %s', sep=',', ), rf=dict(argstr='--rf %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = DWIJointRicianLMMSEFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWIJointRicianLMMSEFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = DWIJointRicianLMMSEFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DWIRicianLMMSEFilter.py000066400000000000000000000030541257611314500313220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DWIRicianLMMSEFilter def test_DWIRicianLMMSEFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), compressOutput=dict(argstr='--compressOutput ', ), environ=dict(nohash=True, usedefault=True, ), hrf=dict(argstr='--hrf %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), iter=dict(argstr='--iter %d', ), maxnstd=dict(argstr='--maxnstd %d', ), minnstd=dict(argstr='--minnstd %d', ), mnve=dict(argstr='--mnve %d', ), mnvf=dict(argstr='--mnvf %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), re=dict(argstr='--re %s', sep=',', ), rf=dict(argstr='--rf %s', sep=',', ), terminal_output=dict(nohash=True, ), uav=dict(argstr='--uav ', ), ) inputs = DWIRicianLMMSEFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWIRicianLMMSEFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = DWIRicianLMMSEFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DWIToDTIEstimation.py000066400000000000000000000025541257611314500311350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DWIToDTIEstimation def test_DWIToDTIEstimation_inputs(): input_map = dict(args=dict(argstr='%s', ), enumeration=dict(argstr='--enumeration %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-3, ), mask=dict(argstr='--mask %s', ), outputBaseline=dict(argstr='%s', hash_files=False, position=-1, ), outputTensor=dict(argstr='%s', hash_files=False, position=-2, ), shiftNeg=dict(argstr='--shiftNeg ', ), terminal_output=dict(nohash=True, ), ) inputs = DWIToDTIEstimation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWIToDTIEstimation_outputs(): output_map = dict(outputBaseline=dict(position=-1, ), outputTensor=dict(position=-2, ), ) outputs = DWIToDTIEstimation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_DiffusionTensorScalarMeasurements.py000066400000000000000000000023401257611314500343630ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DiffusionTensorScalarMeasurements def test_DiffusionTensorScalarMeasurements_inputs(): input_map = dict(args=dict(argstr='%s', ), enumeration=dict(argstr='--enumeration %s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-3, ), outputScalar=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = DiffusionTensorScalarMeasurements.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DiffusionTensorScalarMeasurements_outputs(): output_map = dict(outputScalar=dict(position=-1, ), ) outputs = DiffusionTensorScalarMeasurements.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_DiffusionWeightedVolumeMasking.py000066400000000000000000000026311257611314500337160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import DiffusionWeightedVolumeMasking def test_DiffusionWeightedVolumeMasking_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-4, ), otsuomegathreshold=dict(argstr='--otsuomegathreshold %f', ), outputBaseline=dict(argstr='%s', hash_files=False, position=-2, ), removeislands=dict(argstr='--removeislands ', ), terminal_output=dict(nohash=True, ), thresholdMask=dict(argstr='%s', hash_files=False, position=-1, ), ) inputs = DiffusionWeightedVolumeMasking.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DiffusionWeightedVolumeMasking_outputs(): output_map = dict(outputBaseline=dict(position=-2, ), thresholdMask=dict(position=-1, ), ) outputs = DiffusionWeightedVolumeMasking.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_ResampleDTIVolume.py000066400000000000000000000050211257611314500311020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import ResampleDTIVolume def test_ResampleDTIVolume_inputs(): input_map = dict(Inverse_ITK_Transformation=dict(argstr='--Inverse_ITK_Transformation ', ), Reference=dict(argstr='--Reference %s', ), args=dict(argstr='%s', ), centered_transform=dict(argstr='--centered_transform ', ), correction=dict(argstr='--correction %s', ), defField=dict(argstr='--defField %s', ), default_pixel_value=dict(argstr='--default_pixel_value %f', ), direction_matrix=dict(argstr='--direction_matrix %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), hfieldtype=dict(argstr='--hfieldtype %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), image_center=dict(argstr='--image_center %s', ), inputVolume=dict(argstr='%s', position=-2, ), interpolation=dict(argstr='--interpolation %s', ), notbulk=dict(argstr='--notbulk ', ), number_of_thread=dict(argstr='--number_of_thread %d', ), origin=dict(argstr='--origin %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), rotation_point=dict(argstr='--rotation_point %s', ), size=dict(argstr='--size %s', sep=',', ), spaceChange=dict(argstr='--spaceChange ', ), spacing=dict(argstr='--spacing %s', sep=',', ), spline_order=dict(argstr='--spline_order %d', ), terminal_output=dict(nohash=True, ), transform=dict(argstr='--transform %s', ), transform_matrix=dict(argstr='--transform_matrix %s', sep=',', ), transform_order=dict(argstr='--transform_order %s', ), transform_tensor_method=dict(argstr='--transform_tensor_method %s', ), transformationFile=dict(argstr='--transformationFile %s', ), window_function=dict(argstr='--window_function %s', ), ) inputs = ResampleDTIVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ResampleDTIVolume_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = ResampleDTIVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/diffusion/tests/test_auto_TractographyLabelMapSeeding.py000066400000000000000000000040101257611314500331420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.diffusion.diffusion import TractographyLabelMapSeeding def test_TractographyLabelMapSeeding_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-2, ), OutputFibers=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), clthreshold=dict(argstr='--clthreshold %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputroi=dict(argstr='--inputroi %s', ), integrationsteplength=dict(argstr='--integrationsteplength %f', ), label=dict(argstr='--label %d', ), maximumlength=dict(argstr='--maximumlength %f', ), minimumlength=dict(argstr='--minimumlength %f', ), name=dict(argstr='--name %s', ), outputdirectory=dict(argstr='--outputdirectory %s', hash_files=False, ), randomgrid=dict(argstr='--randomgrid ', ), seedspacing=dict(argstr='--seedspacing %f', ), stoppingcurvature=dict(argstr='--stoppingcurvature %f', ), stoppingmode=dict(argstr='--stoppingmode %s', ), stoppingvalue=dict(argstr='--stoppingvalue %f', ), terminal_output=dict(nohash=True, ), useindexspace=dict(argstr='--useindexspace ', ), writetofile=dict(argstr='--writetofile ', ), ) inputs = TractographyLabelMapSeeding.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TractographyLabelMapSeeding_outputs(): output_map = dict(OutputFibers=dict(position=-1, ), outputdirectory=dict(), ) outputs = TractographyLabelMapSeeding.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/000077500000000000000000000000001257611314500217755ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/filtering/__init__.py000066400000000000000000000014311257611314500241050ustar00rootroot00000000000000from morphology import GrayscaleGrindPeakImageFilter, GrayscaleFillHoleImageFilter from denoising import GradientAnisotropicDiffusion, CurvatureAnisotropicDiffusion, GaussianBlurImageFilter, MedianImageFilter from arithmetic import MultiplyScalarVolumes, MaskScalarVolume, SubtractScalarVolumes, AddScalarVolumes, CastScalarVolume from extractskeleton import ExtractSkeleton from histogrammatching import HistogramMatching from thresholdscalarvolume import ThresholdScalarVolume from n4itkbiasfieldcorrection import N4ITKBiasFieldCorrection from checkerboardfilter import CheckerBoardFilter from imagelabelcombine import ImageLabelCombine from votingbinaryholefillingimagefilter import VotingBinaryHoleFillingImageFilter from resamplescalarvectordwivolume import ResampleScalarVectorDWIVolume nipype-0.11.0/nipype/interfaces/slicer/filtering/arithmetic.py000066400000000000000000000200601257611314500244760ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class MultiplyScalarVolumesInputSpec(CommandLineInputSpec): inputVolume1 = File(position=-3, desc="Input volume 1", exists=True, argstr="%s") inputVolume2 = File(position=-2, desc="Input volume 2", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Volume1 * Volume2", argstr="%s") order = traits.Enum("0", "1", "2", "3", desc="Interpolation order if two images are in different coordinate frames or have different sampling.", argstr="--order %s") class MultiplyScalarVolumesOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Volume1 * Volume2", exists=True) class MultiplyScalarVolumes(SEMLikeCommandLine): """title: Multiply Scalar Volumes category: Filtering.Arithmetic description: Multiplies two images. Although all image types are supported on input, only signed types are produced. The two images do not have to have the same dimensions. version: 0.1.0.$Revision: 8595 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Multiply contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = MultiplyScalarVolumesInputSpec output_spec = MultiplyScalarVolumesOutputSpec _cmd = "MultiplyScalarVolumes " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class MaskScalarVolumeInputSpec(CommandLineInputSpec): InputVolume = File(position=-3, desc="Input volume to be masked", exists=True, argstr="%s") MaskVolume = File(position=-2, desc="Label volume containing the mask", exists=True, argstr="%s") OutputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output volume: Input Volume masked by label value from Mask Volume", argstr="%s") label = traits.Int(desc="Label value in the Mask Volume to use as the mask", argstr="--label %d") replace = traits.Int(desc="Value to use for the output volume outside of the mask", argstr="--replace %d") class MaskScalarVolumeOutputSpec(TraitedSpec): OutputVolume = File(position=-1, desc="Output volume: Input Volume masked by label value from Mask Volume", exists=True) class MaskScalarVolume(SEMLikeCommandLine): """title: Mask Scalar Volume category: Filtering.Arithmetic description: Masks two images. The output image is set to 0 everywhere except where the chosen label from the mask volume is present, at which point it will retain it's original values. Although all image types are supported on input, only signed types are produced. The two images do not have to have the same dimensions. version: 0.1.0.$Revision: 8595 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Mask contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = MaskScalarVolumeInputSpec output_spec = MaskScalarVolumeOutputSpec _cmd = "MaskScalarVolume " _outputs_filenames = {'OutputVolume':'OutputVolume.nii'} class SubtractScalarVolumesInputSpec(CommandLineInputSpec): inputVolume1 = File(position=-3, desc="Input volume 1", exists=True, argstr="%s") inputVolume2 = File(position=-2, desc="Input volume 2", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Volume1 - Volume2", argstr="%s") order = traits.Enum("0", "1", "2", "3", desc="Interpolation order if two images are in different coordinate frames or have different sampling.", argstr="--order %s") class SubtractScalarVolumesOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Volume1 - Volume2", exists=True) class SubtractScalarVolumes(SEMLikeCommandLine): """title: Subtract Scalar Volumes category: Filtering.Arithmetic description: Subtracts two images. Although all image types are supported on input, only signed types are produced. The two images do not have to have the same dimensions. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Subtract contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = SubtractScalarVolumesInputSpec output_spec = SubtractScalarVolumesOutputSpec _cmd = "SubtractScalarVolumes " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class AddScalarVolumesInputSpec(CommandLineInputSpec): inputVolume1 = File(position=-3, desc="Input volume 1", exists=True, argstr="%s") inputVolume2 = File(position=-2, desc="Input volume 2", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Volume1 + Volume2", argstr="%s") order = traits.Enum("0", "1", "2", "3", desc="Interpolation order if two images are in different coordinate frames or have different sampling.", argstr="--order %s") class AddScalarVolumesOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Volume1 + Volume2", exists=True) class AddScalarVolumes(SEMLikeCommandLine): """title: Add Scalar Volumes category: Filtering.Arithmetic description: Adds two images. Although all image types are supported on input, only signed types are produced. The two images do not have to have the same dimensions. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Add contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = AddScalarVolumesInputSpec output_spec = AddScalarVolumesOutputSpec _cmd = "AddScalarVolumes " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class CastScalarVolumeInputSpec(CommandLineInputSpec): InputVolume = File(position=-2, desc="Input volume, the volume to cast.", exists=True, argstr="%s") OutputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output volume, cast to the new type.", argstr="%s") type = traits.Enum("Char", "UnsignedChar", "Short", "UnsignedShort", "Int", "UnsignedInt", "Float", "Double", desc="Type for the new output volume.", argstr="--type %s") class CastScalarVolumeOutputSpec(TraitedSpec): OutputVolume = File(position=-1, desc="Output volume, cast to the new type.", exists=True) class CastScalarVolume(SEMLikeCommandLine): """title: Cast Scalar Volume category: Filtering.Arithmetic description: Cast a volume to a given data type. Use at your own risk when casting an input volume into a lower precision type! Allows casting to the same type as the input volume. version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Cast contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = CastScalarVolumeInputSpec output_spec = CastScalarVolumeOutputSpec _cmd = "CastScalarVolume " _outputs_filenames = {'OutputVolume':'OutputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/checkerboardfilter.py000066400000000000000000000044201257611314500261710ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class CheckerBoardFilterInputSpec(CommandLineInputSpec): checkerPattern = InputMultiPath(traits.Int, desc="The pattern of input 1 and input 2 in the output image. The user can specify the number of checkers in each dimension. A checkerPattern of 2,2,1 means that images will alternate in every other checker in the first two dimensions. The same pattern will be used in the 3rd dimension.", sep=",", argstr="--checkerPattern %s") inputVolume1 = File(position=-3, desc="First Input volume", exists=True, argstr="%s") inputVolume2 = File(position=-2, desc="Second Input volume", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class CheckerBoardFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class CheckerBoardFilter(SEMLikeCommandLine): """title: CheckerBoard Filter category: Filtering description: Create a checkerboard volume of two volumes. The output volume will show the two inputs alternating according to the user supplied checkerPattern. This filter is often used to compare the results of image registration. Note that the second input is resampled to the same origin, spacing and direction before it is composed with the first input. The scalar type of the output volume will be the same as the input image scalar type. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/CheckerBoard contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = CheckerBoardFilterInputSpec output_spec = CheckerBoardFilterOutputSpec _cmd = "CheckerBoardFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/denoising.py000066400000000000000000000213231257611314500243270ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class GradientAnisotropicDiffusionInputSpec(CommandLineInputSpec): conductance = traits.Float(desc="Conductance controls the sensitivity of the conductance term. As a general rule, the lower the value, the more strongly the filter preserves edges. A high value will cause diffusion (smoothing) across edges. Note that the number of iterations controls how much smoothing is done within regions bounded by edges.", argstr="--conductance %f") iterations = traits.Int(desc="The more iterations, the more smoothing. Each iteration takes the same amount of time. If it takes 10 seconds for one iteration, then it will take 100 seconds for 10 iterations. Note that the conductance controls how much each iteration smooths across edges.", argstr="--iterations %d") timeStep = traits.Float(desc="The time step depends on the dimensionality of the image. In Slicer the images are 3D and the default (.0625) time step will provide a stable solution.", argstr="--timeStep %f") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class GradientAnisotropicDiffusionOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class GradientAnisotropicDiffusion(SEMLikeCommandLine): """title: Gradient Anisotropic Diffusion category: Filtering.Denoising description: Runs gradient anisotropic diffusion on a volume. Anisotropic diffusion methods reduce noise (or unwanted detail) in images while preserving specific image features, like edges. For many applications, there is an assumption that light-dark transitions (edges) are interesting. Standard isotropic diffusion methods move and blur light-dark boundaries. Anisotropic diffusion methods are formulated to specifically preserve edges. The conductance term for this implementation is a function of the gradient magnitude of the image at each point, reducing the strength of diffusion at edges. The numerical implementation of this equation is similar to that described in the Perona-Malik paper, but uses a more robust technique for gradient magnitude estimation and has been generalized to N-dimensions. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/GradientAnisotropicDiffusion contributor: Bill Lorensen (GE) acknowledgements: This command module was derived from Insight/Examples (copyright) Insight Software Consortium """ input_spec = GradientAnisotropicDiffusionInputSpec output_spec = GradientAnisotropicDiffusionOutputSpec _cmd = "GradientAnisotropicDiffusion " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class CurvatureAnisotropicDiffusionInputSpec(CommandLineInputSpec): conductance = traits.Float(desc="Conductance controls the sensitivity of the conductance term. As a general rule, the lower the value, the more strongly the filter preserves edges. A high value will cause diffusion (smoothing) across edges. Note that the number of iterations controls how much smoothing is done within regions bounded by edges.", argstr="--conductance %f") iterations = traits.Int(desc="The more iterations, the more smoothing. Each iteration takes the same amount of time. If it takes 10 seconds for one iteration, then it will take 100 seconds for 10 iterations. Note that the conductance controls how much each iteration smooths across edges.", argstr="--iterations %d") timeStep = traits.Float(desc="The time step depends on the dimensionality of the image. In Slicer the images are 3D and the default (.0625) time step will provide a stable solution.", argstr="--timeStep %f") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class CurvatureAnisotropicDiffusionOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class CurvatureAnisotropicDiffusion(SEMLikeCommandLine): """title: Curvature Anisotropic Diffusion category: Filtering.Denoising description: Performs anisotropic diffusion on an image using a modified curvature diffusion equation (MCDE). MCDE does not exhibit the edge enhancing properties of classic anisotropic diffusion, which can under certain conditions undergo a 'negative' diffusion, which enhances the contrast of edges. Equations of the form of MCDE always undergo positive diffusion, with the conductance term only varying the strength of that diffusion. Qualitatively, MCDE compares well with other non-linear diffusion techniques. It is less sensitive to contrast than classic Perona-Malik style diffusion, and preserves finer detailed structures in images. There is a potential speed trade-off for using this function in place of Gradient Anisotropic Diffusion. Each iteration of the solution takes roughly twice as long. Fewer iterations, however, may be required to reach an acceptable solution. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/CurvatureAnisotropicDiffusion contributor: Bill Lorensen (GE) acknowledgements: This command module was derived from Insight/Examples (copyright) Insight Software Consortium """ input_spec = CurvatureAnisotropicDiffusionInputSpec output_spec = CurvatureAnisotropicDiffusionOutputSpec _cmd = "CurvatureAnisotropicDiffusion " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class GaussianBlurImageFilterInputSpec(CommandLineInputSpec): sigma = traits.Float(desc="Sigma value in physical units (e.g., mm) of the Gaussian kernel", argstr="--sigma %f") inputVolume = File(position=-2, desc="Input volume", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Blurred Volume", argstr="%s") class GaussianBlurImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Blurred Volume", exists=True) class GaussianBlurImageFilter(SEMLikeCommandLine): """title: Gaussian Blur Image Filter category: Filtering.Denoising description: Apply a gaussian blurr to an image version: 0.1.0.$Revision: 1.1 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/GaussianBlurImageFilter contributor: Julien Jomier (Kitware), Stephen Aylward (Kitware) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = GaussianBlurImageFilterInputSpec output_spec = GaussianBlurImageFilterOutputSpec _cmd = "GaussianBlurImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class MedianImageFilterInputSpec(CommandLineInputSpec): neighborhood = InputMultiPath(traits.Int, desc="The size of the neighborhood in each dimension", sep=",", argstr="--neighborhood %s") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class MedianImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class MedianImageFilter(SEMLikeCommandLine): """title: Median Image Filter category: Filtering.Denoising description: The MedianImageFilter is commonly used as a robust approach for noise reduction. This filter is particularly efficient against "salt-and-pepper" noise. In other words, it is robust to the presence of gray-level outliers. MedianImageFilter computes the value of each output pixel as the statistical median of the neighborhood of values around the corresponding input pixel. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/MedianImageFilter contributor: Bill Lorensen (GE) acknowledgements: This command module was derived from Insight/Examples/Filtering/MedianImageFilter (copyright) Insight Software Consortium """ input_spec = MedianImageFilterInputSpec output_spec = MedianImageFilterOutputSpec _cmd = "MedianImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/extractskeleton.py000066400000000000000000000043761257611314500256000ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ExtractSkeletonInputSpec(CommandLineInputSpec): InputImageFileName = File(position=-2, desc="Input image", exists=True, argstr="%s") OutputImageFileName = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Skeleton of the input image", argstr="%s") type = traits.Enum("1D", "2D", desc="Type of skeleton to create", argstr="--type %s") dontPrune = traits.Bool(desc="Return the full skeleton, not just the maximal skeleton", argstr="--dontPrune ") numPoints = traits.Int(desc="Number of points used to represent the skeleton", argstr="--numPoints %d") pointsFile = traits.Str(desc="Name of the file to store the coordinates of the central (1D) skeleton points", argstr="--pointsFile %s") class ExtractSkeletonOutputSpec(TraitedSpec): OutputImageFileName = File(position=-1, desc="Skeleton of the input image", exists=True) class ExtractSkeleton(SEMLikeCommandLine): """title: Extract Skeleton category: Filtering description: Extract the skeleton of a binary object. The skeleton can be limited to being a 1D curve or allowed to be a full 2D manifold. The branches of the skeleton can be pruned so that only the maximal center skeleton is returned. version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ExtractSkeleton contributor: Pierre Seroul (UNC), Martin Styner (UNC), Guido Gerig (UNC), Stephen Aylward (Kitware) acknowledgements: The original implementation of this method was provided by ETH Zurich, Image Analysis Laboratory of Profs Olaf Kuebler, Gabor Szekely and Guido Gerig. Martin Styner at UNC, Chapel Hill made enhancements. Wrapping for Slicer was provided by Pierre Seroul and Stephen Aylward at Kitware, Inc. """ input_spec = ExtractSkeletonInputSpec output_spec = ExtractSkeletonOutputSpec _cmd = "ExtractSkeleton " _outputs_filenames = {'OutputImageFileName':'OutputImageFileName.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/histogrammatching.py000066400000000000000000000056421257611314500260660ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class HistogramMatchingInputSpec(CommandLineInputSpec): numberOfHistogramLevels = traits.Int(desc="The number of hisogram levels to use", argstr="--numberOfHistogramLevels %d") numberOfMatchPoints = traits.Int(desc="The number of match points to use", argstr="--numberOfMatchPoints %d") threshold = traits.Bool(desc="If on, only pixels above the mean in each volume are thresholded.", argstr="--threshold ") inputVolume = File(position=-3, desc="Input volume to be filtered", exists=True, argstr="%s") referenceVolume = File(position=-2, desc="Input volume whose histogram will be matched", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output volume. This is the input volume with intensities matched to the reference volume.", argstr="%s") class HistogramMatchingOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output volume. This is the input volume with intensities matched to the reference volume.", exists=True) class HistogramMatching(SEMLikeCommandLine): """title: Histogram Matching category: Filtering description: Normalizes the grayscale values of a source image based on the grayscale values of a reference image. This filter uses a histogram matching technique where the histograms of the two images are matched only at a specified number of quantile values. The filter was orginally designed to normalize MR images of the sameMR protocol and same body part. The algorithm works best if background pixels are excluded from both the source and reference histograms. A simple background exclusion method is to exclude all pixels whose grayscale values are smaller than the mean grayscale value. ThresholdAtMeanIntensity switches on this simple background exclusion method. Number of match points governs the number of quantile values to be matched. The filter assumes that both the source and reference are of the same type and that the input and output image type have the same number of dimension and have scalar pixel types. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/HistogramMatching contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = HistogramMatchingInputSpec output_spec = HistogramMatchingOutputSpec _cmd = "HistogramMatching " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/imagelabelcombine.py000066400000000000000000000026721257611314500257750ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ImageLabelCombineInputSpec(CommandLineInputSpec): InputLabelMap_A = File(position=-3, desc="Label map image", exists=True, argstr="%s") InputLabelMap_B = File(position=-2, desc="Label map image", exists=True, argstr="%s") OutputLabelMap = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Resulting Label map image", argstr="%s") first_overwrites = traits.Bool(desc="Use first or second label when both are present", argstr="--first_overwrites ") class ImageLabelCombineOutputSpec(TraitedSpec): OutputLabelMap = File(position=-1, desc="Resulting Label map image", exists=True) class ImageLabelCombine(SEMLikeCommandLine): """title: Image Label Combine category: Filtering description: Combine two label maps into one version: 0.1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ImageLabelCombine contributor: Alex Yarmarkovich (SPL, BWH) """ input_spec = ImageLabelCombineInputSpec output_spec = ImageLabelCombineOutputSpec _cmd = "ImageLabelCombine " _outputs_filenames = {'OutputLabelMap':'OutputLabelMap.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/morphology.py000066400000000000000000000120731257611314500245510ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class GrayscaleGrindPeakImageFilterInputSpec(CommandLineInputSpec): inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class GrayscaleGrindPeakImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class GrayscaleGrindPeakImageFilter(SEMLikeCommandLine): """title: Grayscale Grind Peak Image Filter category: Filtering.Morphology description: GrayscaleGrindPeakImageFilter removes peaks in a grayscale image. Peaks are local maxima in the grayscale topography that are not connected to boundaries of the image. Gray level values adjacent to a peak are extrapolated through the peak. This filter is used to smooth over local maxima without affecting the values of local minima. If you take the difference between the output of this filter and the original image (and perhaps threshold the difference above a small value), you'll obtain a map of the local maxima. This filter uses the GrayscaleGeodesicDilateImageFilter. It provides its own input as the "mask" input to the geodesic erosion. The "marker" image for the geodesic erosion is constructed such that boundary pixels match the boundary pixels of the input image and the interior pixels are set to the minimum pixel value in the input image. This filter is the dual to the GrayscaleFillholeImageFilter which implements the Fillhole algorithm. Since it is a dual, it is somewhat superfluous but is provided as a convenience. Geodesic morphology and the Fillhole algorithm is described in Chapter 6 of Pierre Soille's book "Morphological Image Analysis: Principles and Applications", Second Edition, Springer, 2003. A companion filter, Grayscale Fill Hole, fills holes in grayscale images. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/GrayscaleGrindPeakImageFilter contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = GrayscaleGrindPeakImageFilterInputSpec output_spec = GrayscaleGrindPeakImageFilterOutputSpec _cmd = "GrayscaleGrindPeakImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class GrayscaleFillHoleImageFilterInputSpec(CommandLineInputSpec): inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class GrayscaleFillHoleImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class GrayscaleFillHoleImageFilter(SEMLikeCommandLine): """title: Grayscale Fill Hole Image Filter category: Filtering.Morphology description: GrayscaleFillholeImageFilter fills holes in a grayscale image. Holes are local minima in the grayscale topography that are not connected to boundaries of the image. Gray level values adjacent to a hole are extrapolated across the hole. This filter is used to smooth over local minima without affecting the values of local maxima. If you take the difference between the output of this filter and the original image (and perhaps threshold the difference above a small value), you'll obtain a map of the local minima. This filter uses the itkGrayscaleGeodesicErodeImageFilter. It provides its own input as the "mask" input to the geodesic erosion. The "marker" image for the geodesic erosion is constructed such that boundary pixels match the boundary pixels of the input image and the interior pixels are set to the maximum pixel value in the input image. Geodesic morphology and the Fillhole algorithm is described in Chapter 6 of Pierre Soille's book "Morphological Image Analysis: Principles and Applications", Second Edition, Springer, 2003. A companion filter, Grayscale Grind Peak, removes peaks in grayscale images. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/GrayscaleFillHoleImageFilter contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = GrayscaleFillHoleImageFilterInputSpec output_spec = GrayscaleFillHoleImageFilterOutputSpec _cmd = "GrayscaleFillHoleImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/n4itkbiasfieldcorrection.py000066400000000000000000000110011257611314500273240ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class N4ITKBiasFieldCorrectionInputSpec(CommandLineInputSpec): inputimage = File(desc="Input image where you observe signal inhomegeneity", exists=True, argstr="--inputimage %s") maskimage = File(desc="Binary mask that defines the structure of your interest. NOTE: This parameter is OPTIONAL. If the mask is not specified, the module will use internally Otsu thresholding to define this mask. Better processing results can often be obtained when a meaningful mask is defined.", exists=True, argstr="--maskimage %s") outputimage = traits.Either(traits.Bool, File(), hash_files=False, desc="Result of processing", argstr="--outputimage %s") outputbiasfield = traits.Either(traits.Bool, File(), hash_files=False, desc="Recovered bias field (OPTIONAL)", argstr="--outputbiasfield %s") iterations = InputMultiPath(traits.Int, desc="Maximum number of iterations at each level of resolution. Larger values will increase execution time, but may lead to better results.", sep=",", argstr="--iterations %s") convergencethreshold = traits.Float(desc="Stopping criterion for the iterative bias estimation. Larger values will lead to smaller execution time.", argstr="--convergencethreshold %f") meshresolution = InputMultiPath(traits.Float, desc="Resolution of the initial bspline grid defined as a sequence of three numbers. The actual resolution will be defined by adding the bspline order (default is 3) to the resolution in each dimension specified here. For example, 1,1,1 will result in a 4x4x4 grid of control points. This parameter may need to be adjusted based on your input image. In the multi-resolution N4 framework, the resolution of the bspline grid at subsequent iterations will be doubled. The number of resolutions is implicitly defined by Number of iterations parameter (the size of this list is the number of resolutions)", sep=",", argstr="--meshresolution %s") splinedistance = traits.Float(desc="An alternative means to define the spline grid, by setting the distance between the control points. This parameter is used only if the grid resolution is not specified.", argstr="--splinedistance %f") shrinkfactor = traits.Int(desc="Defines how much the image should be upsampled before estimating the inhomogeneity field. Increase if you want to reduce the execution time. 1 corresponds to the original resolution. Larger values will significantly reduce the computation time.", argstr="--shrinkfactor %d") bsplineorder = traits.Int(desc="Order of B-spline used in the approximation. Larger values will lead to longer execution times, may result in overfitting and poor result.", argstr="--bsplineorder %d") weightimage = File(desc="Weight Image", exists=True, argstr="--weightimage %s") histogramsharpening = InputMultiPath(traits.Float, desc="A vector of up to three values. Non-zero values correspond to Bias Field Full Width at Half Maximum, Wiener filter noise, and Number of histogram bins.", sep=",", argstr="--histogramsharpening %s") class N4ITKBiasFieldCorrectionOutputSpec(TraitedSpec): outputimage = File(desc="Result of processing", exists=True) outputbiasfield = File(desc="Recovered bias field (OPTIONAL)", exists=True) class N4ITKBiasFieldCorrection(SEMLikeCommandLine): """title: N4ITK MRI Bias correction category: Filtering description: Performs image bias correction using N4 algorithm. This module is based on the ITK filters contributed in the following publication: Tustison N, Gee J "N4ITK: Nick's N3 ITK Implementation For MRI Bias Field Correction", The Insight Journal 2009 January-June, http://hdl.handle.net/10380/3053 version: 9 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/N4ITKBiasFieldCorrection contributor: Nick Tustison (UPenn), Andrey Fedorov (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: The development of this module was partially supported by NIH grants R01 AA016748-01, R01 CA111288 and U01 CA151261 as well as by NA-MIC, NAC, NCIGT and the Slicer community. """ input_spec = N4ITKBiasFieldCorrectionInputSpec output_spec = N4ITKBiasFieldCorrectionOutputSpec _cmd = "N4ITKBiasFieldCorrection " _outputs_filenames = {'outputimage':'outputimage.nii','outputbiasfield':'outputbiasfield.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/resamplescalarvectordwivolume.py000066400000000000000000000125661257611314500305360ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ResampleScalarVectorDWIVolumeInputSpec(CommandLineInputSpec): inputVolume = File(position=-2, desc="Input Volume to be resampled", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Resampled Volume", argstr="%s") Reference = File(desc="Reference Volume (spacing,size,orientation,origin)", exists=True, argstr="--Reference %s") transformationFile = File(exists=True, argstr="--transformationFile %s") defField = File(desc="File containing the deformation field (3D vector image containing vectors with 3 components)", exists=True, argstr="--defField %s") hfieldtype = traits.Enum("displacement", "h-Field", desc="Set if the deformation field is an h-Field", argstr="--hfieldtype %s") interpolation = traits.Enum("linear", "nn", "ws", "bs", desc="Sampling algorithm (linear or nn (nearest neighborhoor), ws (WindowedSinc), bs (BSpline) )", argstr="--interpolation %s") transform_order = traits.Enum("input-to-output", "output-to-input", desc="Select in what order the transforms are read", argstr="--transform_order %s") notbulk = traits.Bool(desc="The transform following the BSpline transform is not set as a bulk transform for the BSpline transform", argstr="--notbulk ") spaceChange = traits.Bool(desc="Space Orientation between transform and image is different (RAS/LPS) (warning: if the transform is a Transform Node in Slicer3, do not select)", argstr="--spaceChange ") rotation_point = traits.List(desc="Rotation Point in case of rotation around a point (otherwise useless)", argstr="--rotation_point %s") centered_transform = traits.Bool(desc="Set the center of the transformation to the center of the input image", argstr="--centered_transform ") image_center = traits.Enum("input", "output", desc="Image to use to center the transform (used only if \'Centered Transform\' is selected)", argstr="--image_center %s") Inverse_ITK_Transformation = traits.Bool(desc="Inverse the transformation before applying it from output image to input image", argstr="--Inverse_ITK_Transformation ") spacing = InputMultiPath(traits.Float, desc="Spacing along each dimension (0 means use input spacing)", sep=",", argstr="--spacing %s") size = InputMultiPath(traits.Float, desc="Size along each dimension (0 means use input size)", sep=",", argstr="--size %s") origin = traits.List(desc="Origin of the output Image", argstr="--origin %s") direction_matrix = InputMultiPath(traits.Float, desc="9 parameters of the direction matrix by rows (ijk to LPS if LPS transform, ijk to RAS if RAS transform)", sep=",", argstr="--direction_matrix %s") number_of_thread = traits.Int(desc="Number of thread used to compute the output image", argstr="--number_of_thread %d") default_pixel_value = traits.Float(desc="Default pixel value for samples falling outside of the input region", argstr="--default_pixel_value %f") window_function = traits.Enum("h", "c", "w", "l", "b", desc="Window Function , h = Hamming , c = Cosine , w = Welch , l = Lanczos , b = Blackman", argstr="--window_function %s") spline_order = traits.Int(desc="Spline Order", argstr="--spline_order %d") transform_matrix = InputMultiPath(traits.Float, desc="12 parameters of the transform matrix by rows ( --last 3 being translation-- )", sep=",", argstr="--transform_matrix %s") transform = traits.Enum("rt", "a", desc="Transform algorithm, rt = Rigid Transform, a = Affine Transform", argstr="--transform %s") class ResampleScalarVectorDWIVolumeOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Resampled Volume", exists=True) class ResampleScalarVectorDWIVolume(SEMLikeCommandLine): """title: Resample Scalar/Vector/DWI Volume category: Filtering description: This module implements image and vector-image resampling through the use of itk Transforms.It can also handle diffusion weighted MRI image resampling. "Resampling" is performed in space coordinates, not pixel/grid coordinates. It is quite important to ensure that image spacing is properly set on the images involved. The interpolator is required since the mapping from one space to the other will often require evaluation of the intensity of the image at non-grid positions. Warning: To resample DWMR Images, use nrrd input and output files. Warning: Do not use to resample Diffusion Tensor Images, tensors would not be reoriented version: 0.1 documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ResampleScalarVectorDWIVolume contributor: Francois Budin (UNC) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. Information on the National Centers for Biomedical Computing can be obtained from http://nihroadmap.nih.gov/bioinformatics """ input_spec = ResampleScalarVectorDWIVolumeInputSpec output_spec = ResampleScalarVectorDWIVolumeOutputSpec _cmd = "ResampleScalarVectorDWIVolume " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/000077500000000000000000000000001257611314500231375ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_AddScalarVolumes.py000066400000000000000000000022741257611314500307760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.arithmetic import AddScalarVolumes def test_AddScalarVolumes_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='%s', position=-3, ), inputVolume2=dict(argstr='%s', position=-2, ), order=dict(argstr='--order %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = AddScalarVolumes.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AddScalarVolumes_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = AddScalarVolumes.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_CastScalarVolume.py000066400000000000000000000021761257611314500310160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.arithmetic import CastScalarVolume def test_CastScalarVolume_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-2, ), OutputVolume=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), type=dict(argstr='--type %s', ), ) inputs = CastScalarVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CastScalarVolume_outputs(): output_map = dict(OutputVolume=dict(position=-1, ), ) outputs = CastScalarVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_CheckerBoardFilter.py000066400000000000000000000023551257611314500312670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.checkerboardfilter import CheckerBoardFilter def test_CheckerBoardFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), checkerPattern=dict(argstr='--checkerPattern %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='%s', position=-3, ), inputVolume2=dict(argstr='%s', position=-2, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = CheckerBoardFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CheckerBoardFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = CheckerBoardFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_CurvatureAnisotropicDiffusion.py000066400000000000000000000024621257611314500336460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.denoising import CurvatureAnisotropicDiffusion def test_CurvatureAnisotropicDiffusion_inputs(): input_map = dict(args=dict(argstr='%s', ), conductance=dict(argstr='--conductance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), iterations=dict(argstr='--iterations %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), timeStep=dict(argstr='--timeStep %f', ), ) inputs = CurvatureAnisotropicDiffusion.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CurvatureAnisotropicDiffusion_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = CurvatureAnisotropicDiffusion.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_ExtractSkeleton.py000066400000000000000000000024541257611314500307240ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.extractskeleton import ExtractSkeleton def test_ExtractSkeleton_inputs(): input_map = dict(InputImageFileName=dict(argstr='%s', position=-2, ), OutputImageFileName=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), dontPrune=dict(argstr='--dontPrune ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), numPoints=dict(argstr='--numPoints %d', ), pointsFile=dict(argstr='--pointsFile %s', ), terminal_output=dict(nohash=True, ), type=dict(argstr='--type %s', ), ) inputs = ExtractSkeleton.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ExtractSkeleton_outputs(): output_map = dict(OutputImageFileName=dict(position=-1, ), ) outputs = ExtractSkeleton.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_GaussianBlurImageFilter.py000066400000000000000000000022421257611314500323100ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.denoising import GaussianBlurImageFilter def test_GaussianBlurImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), sigma=dict(argstr='--sigma %f', ), terminal_output=dict(nohash=True, ), ) inputs = GaussianBlurImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GaussianBlurImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = GaussianBlurImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_GradientAnisotropicDiffusion.py000066400000000000000000000024551257611314500334250ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.denoising import GradientAnisotropicDiffusion def test_GradientAnisotropicDiffusion_inputs(): input_map = dict(args=dict(argstr='%s', ), conductance=dict(argstr='--conductance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), iterations=dict(argstr='--iterations %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), timeStep=dict(argstr='--timeStep %f', ), ) inputs = GradientAnisotropicDiffusion.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GradientAnisotropicDiffusion_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = GradientAnisotropicDiffusion.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_GrayscaleFillHoleImageFilter.py000066400000000000000000000022211257611314500332370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.morphology import GrayscaleFillHoleImageFilter def test_GrayscaleFillHoleImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = GrayscaleFillHoleImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GrayscaleFillHoleImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = GrayscaleFillHoleImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_GrayscaleGrindPeakImageFilter.py000066400000000000000000000022261257611314500334120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.morphology import GrayscaleGrindPeakImageFilter def test_GrayscaleGrindPeakImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = GrayscaleGrindPeakImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GrayscaleGrindPeakImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = GrayscaleGrindPeakImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_HistogramMatching.py000066400000000000000000000025461257611314500312170ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.histogrammatching import HistogramMatching def test_HistogramMatching_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-3, ), numberOfHistogramLevels=dict(argstr='--numberOfHistogramLevels %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), referenceVolume=dict(argstr='%s', position=-2, ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--threshold ', ), ) inputs = HistogramMatching.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_HistogramMatching_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = HistogramMatching.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_ImageLabelCombine.py000066400000000000000000000023461257611314500310640ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.imagelabelcombine import ImageLabelCombine def test_ImageLabelCombine_inputs(): input_map = dict(InputLabelMap_A=dict(argstr='%s', position=-3, ), InputLabelMap_B=dict(argstr='%s', position=-2, ), OutputLabelMap=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), first_overwrites=dict(argstr='--first_overwrites ', ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ImageLabelCombine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ImageLabelCombine_outputs(): output_map = dict(OutputLabelMap=dict(position=-1, ), ) outputs = ImageLabelCombine.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_MaskScalarVolume.py000066400000000000000000000023501257611314500310110ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.arithmetic import MaskScalarVolume def test_MaskScalarVolume_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-3, ), MaskVolume=dict(argstr='%s', position=-2, ), OutputVolume=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), label=dict(argstr='--label %d', ), replace=dict(argstr='--replace %d', ), terminal_output=dict(nohash=True, ), ) inputs = MaskScalarVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MaskScalarVolume_outputs(): output_map = dict(OutputVolume=dict(position=-1, ), ) outputs = MaskScalarVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_MedianImageFilter.py000066400000000000000000000022371257611314500311120ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.denoising import MedianImageFilter def test_MedianImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), neighborhood=dict(argstr='--neighborhood %s', sep=',', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = MedianImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MedianImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = MedianImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_MultiplyScalarVolumes.py000066400000000000000000000023251257611314500321220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.arithmetic import MultiplyScalarVolumes def test_MultiplyScalarVolumes_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='%s', position=-3, ), inputVolume2=dict(argstr='%s', position=-2, ), order=dict(argstr='--order %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = MultiplyScalarVolumes.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultiplyScalarVolumes_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = MultiplyScalarVolumes.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_N4ITKBiasFieldCorrection.py000066400000000000000000000034431257611314500322300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.n4itkbiasfieldcorrection import N4ITKBiasFieldCorrection def test_N4ITKBiasFieldCorrection_inputs(): input_map = dict(args=dict(argstr='%s', ), bsplineorder=dict(argstr='--bsplineorder %d', ), convergencethreshold=dict(argstr='--convergencethreshold %f', ), environ=dict(nohash=True, usedefault=True, ), histogramsharpening=dict(argstr='--histogramsharpening %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputimage=dict(argstr='--inputimage %s', ), iterations=dict(argstr='--iterations %s', sep=',', ), maskimage=dict(argstr='--maskimage %s', ), meshresolution=dict(argstr='--meshresolution %s', sep=',', ), outputbiasfield=dict(argstr='--outputbiasfield %s', hash_files=False, ), outputimage=dict(argstr='--outputimage %s', hash_files=False, ), shrinkfactor=dict(argstr='--shrinkfactor %d', ), splinedistance=dict(argstr='--splinedistance %f', ), terminal_output=dict(nohash=True, ), weightimage=dict(argstr='--weightimage %s', ), ) inputs = N4ITKBiasFieldCorrection.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_N4ITKBiasFieldCorrection_outputs(): output_map = dict(outputbiasfield=dict(), outputimage=dict(), ) outputs = N4ITKBiasFieldCorrection.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_ResampleScalarVectorDWIVolume.py000066400000000000000000000047351257611314500334260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.resamplescalarvectordwivolume import ResampleScalarVectorDWIVolume def test_ResampleScalarVectorDWIVolume_inputs(): input_map = dict(Inverse_ITK_Transformation=dict(argstr='--Inverse_ITK_Transformation ', ), Reference=dict(argstr='--Reference %s', ), args=dict(argstr='%s', ), centered_transform=dict(argstr='--centered_transform ', ), defField=dict(argstr='--defField %s', ), default_pixel_value=dict(argstr='--default_pixel_value %f', ), direction_matrix=dict(argstr='--direction_matrix %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), hfieldtype=dict(argstr='--hfieldtype %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), image_center=dict(argstr='--image_center %s', ), inputVolume=dict(argstr='%s', position=-2, ), interpolation=dict(argstr='--interpolation %s', ), notbulk=dict(argstr='--notbulk ', ), number_of_thread=dict(argstr='--number_of_thread %d', ), origin=dict(argstr='--origin %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), rotation_point=dict(argstr='--rotation_point %s', ), size=dict(argstr='--size %s', sep=',', ), spaceChange=dict(argstr='--spaceChange ', ), spacing=dict(argstr='--spacing %s', sep=',', ), spline_order=dict(argstr='--spline_order %d', ), terminal_output=dict(nohash=True, ), transform=dict(argstr='--transform %s', ), transform_matrix=dict(argstr='--transform_matrix %s', sep=',', ), transform_order=dict(argstr='--transform_order %s', ), transformationFile=dict(argstr='--transformationFile %s', ), window_function=dict(argstr='--window_function %s', ), ) inputs = ResampleScalarVectorDWIVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ResampleScalarVectorDWIVolume_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = ResampleScalarVectorDWIVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_SubtractScalarVolumes.py000066400000000000000000000023251257611314500320720ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.arithmetic import SubtractScalarVolumes def test_SubtractScalarVolumes_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='%s', position=-3, ), inputVolume2=dict(argstr='%s', position=-2, ), order=dict(argstr='--order %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = SubtractScalarVolumes.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SubtractScalarVolumes_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = SubtractScalarVolumes.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/tests/test_auto_ThresholdScalarVolume.py000066400000000000000000000025661257611314500320630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.thresholdscalarvolume import ThresholdScalarVolume def test_ThresholdScalarVolume_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-2, ), OutputVolume=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), lower=dict(argstr='--lower %d', ), outsidevalue=dict(argstr='--outsidevalue %d', ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--threshold %d', ), thresholdtype=dict(argstr='--thresholdtype %s', ), upper=dict(argstr='--upper %d', ), ) inputs = ThresholdScalarVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ThresholdScalarVolume_outputs(): output_map = dict(OutputVolume=dict(position=-1, ), ) outputs = ThresholdScalarVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_VotingBinaryHoleFillingImageFilter.py000066400000000000000000000026561257611314500343730ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/filtering/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.filtering.votingbinaryholefillingimagefilter import VotingBinaryHoleFillingImageFilter def test_VotingBinaryHoleFillingImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), background=dict(argstr='--background %d', ), environ=dict(nohash=True, usedefault=True, ), foreground=dict(argstr='--foreground %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), majorityThreshold=dict(argstr='--majorityThreshold %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), radius=dict(argstr='--radius %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = VotingBinaryHoleFillingImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VotingBinaryHoleFillingImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = VotingBinaryHoleFillingImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/filtering/thresholdscalarvolume.py000066400000000000000000000051311257611314500267610ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ThresholdScalarVolumeInputSpec(CommandLineInputSpec): InputVolume = File(position=-2, desc="Input volume", exists=True, argstr="%s") OutputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Thresholded input volume", argstr="%s") threshold = traits.Int(desc="Threshold value", argstr="--threshold %d") lower = traits.Int(desc="Lower threshold value", argstr="--lower %d") upper = traits.Int(desc="Upper threshold value", argstr="--upper %d") outsidevalue = traits.Int(desc="Set the voxels to this value if they fall outside the threshold range", argstr="--outsidevalue %d") thresholdtype = traits.Enum("Below", "Above", "Outside", desc="What kind of threshold to perform. If Outside is selected, uses Upper and Lower values. If Below is selected, uses the ThresholdValue, if Above is selected, uses the ThresholdValue.", argstr="--thresholdtype %s") class ThresholdScalarVolumeOutputSpec(TraitedSpec): OutputVolume = File(position=-1, desc="Thresholded input volume", exists=True) class ThresholdScalarVolume(SEMLikeCommandLine): """title: Threshold Scalar Volume category: Filtering description:

Threshold an image.

Set image values to a user-specified outside value if they are below, above, or between simple threshold values.

ThresholdAbove: The values greater than or equal to the threshold value are set to OutsideValue.

ThresholdBelow: The values less than or equal to the threshold value are set to OutsideValue.

ThresholdOutside: The values outside the range Lower-Upper are set to OutsideValue.

Although all image types are supported on input, only signed types are produced.

version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/Threshold contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ThresholdScalarVolumeInputSpec output_spec = ThresholdScalarVolumeOutputSpec _cmd = "ThresholdScalarVolume " _outputs_filenames = {'OutputVolume':'OutputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/filtering/votingbinaryholefillingimagefilter.py000066400000000000000000000050701257611314500315120ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class VotingBinaryHoleFillingImageFilterInputSpec(CommandLineInputSpec): radius = InputMultiPath(traits.Int, desc="The radius of a hole to be filled", sep=",", argstr="--radius %s") majorityThreshold = traits.Int(desc="The number of pixels over 50% that will decide whether an OFF pixel will become ON or not. For example, if the neighborhood of a pixel has 124 pixels (excluding itself), the 50% will be 62, and if you set a Majority threshold of 5, that means that the filter will require 67 or more neighbor pixels to be ON in order to switch the current OFF pixel to ON.", argstr="--majorityThreshold %d") background = traits.Int(desc="The value associated with the background (not object)", argstr="--background %d") foreground = traits.Int(desc="The value associated with the foreground (object)", argstr="--foreground %d") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class VotingBinaryHoleFillingImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class VotingBinaryHoleFillingImageFilter(SEMLikeCommandLine): """title: Voting Binary Hole Filling Image Filter category: Filtering description: Applies a voting operation in order to fill-in cavities. This can be used for smoothing contours and for filling holes in binary images. This technique is used frequently when segmenting complete organs that may have ducts or vasculature that may not have been included in the initial segmentation, e.g. lungs, kidneys, liver. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/VotingBinaryHoleFillingImageFilter contributor: Bill Lorensen (GE) acknowledgements: This command module was derived from Insight/Examples/Filtering/VotingBinaryHoleFillingImageFilter (copyright) Insight Software Consortium """ input_spec = VotingBinaryHoleFillingImageFilterInputSpec output_spec = VotingBinaryHoleFillingImageFilterOutputSpec _cmd = "VotingBinaryHoleFillingImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/generate_classes.py000066400000000000000000000521711257611314500237010ustar00rootroot00000000000000"""This script generates Slicer Interfaces based on the CLI modules XML. CLI modules are selected from the hardcoded list below and generated code is placed in the cli_modules.py file (and imported in __init__.py). For this to work correctly you must have your CLI executabes in $PATH""" import xml.dom.minidom import subprocess import os from shutil import rmtree from nipype.external import six import keyword python_keywords = keyword.kwlist # If c++ SEM module uses one of these key words as a command line parameter, we need to modify variable def force_to_valid_python_variable_name(old_name): """ Valid c++ names are not always valid in python, so provide alternate naming >>> force_to_valid_python_variable_name('lambda') 'opt_lambda' >>> force_to_valid_python_variable_name('inputVolume') 'inputVolume' """ new_name = old_name new_name = new_name.lstrip().rstrip() if old_name in python_keywords: new_name = 'opt_' + old_name return new_name def add_class_to_package(class_codes, class_names, module_name, package_dir): module_python_filename = os.path.join(package_dir, "%s.py" % module_name) f_m = open(module_python_filename, 'w') f_i = open(os.path.join(package_dir, "__init__.py"), 'a+') f_m.write("""# -*- coding: utf8 -*- \"\"\"Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.\"\"\"\n\n""") imports = """from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os\n\n\n""" f_m.write(imports) f_m.write("\n\n".join(class_codes).encode('utf8')) f_i.write("from %s import %s\n" % (module_name, ", ".join(class_names))) f_m.close() f_i.close() def crawl_code_struct(code_struct, package_dir): subpackages = [] for k, v in code_struct.iteritems(): if isinstance(v, six.string_types) or isinstance(v, unicode): module_name = k.lower() class_name = k class_code = v add_class_to_package( [class_code], [class_name], module_name, package_dir) else: l1 = {} l2 = {} for key in v.keys(): if (isinstance(v[key], six.string_types) or isinstance(v[key], unicode)): l1[key] = v[key] else: l2[key] = v[key] if l2: v = l2 subpackages.append(k.lower()) f_i = open(os.path.join(package_dir, "__init__.py"), 'a+') f_i.write("from %s import *\n" % k.lower()) f_i.close() new_pkg_dir = os.path.join(package_dir, k.lower()) if os.path.exists(new_pkg_dir): rmtree(new_pkg_dir) os.mkdir(new_pkg_dir) crawl_code_struct(v, new_pkg_dir) if l1: for ik, iv in l1.iteritems(): crawl_code_struct({ik: {ik: iv}}, new_pkg_dir) elif l1: v = l1 module_name = k.lower() add_class_to_package( v.values(), v.keys(), module_name, package_dir) if subpackages: f = open(os.path.join(package_dir, "setup.py"), 'w') f.write("""# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: def configuration(parent_package='',top_path=None): from numpy.distutils.misc_util import Configuration config = Configuration('{pkg_name}', parent_package, top_path) {sub_pks} return config if __name__ == '__main__': from numpy.distutils.core import setup setup(**configuration(top_path='').todict()) """.format(pkg_name=package_dir.split("/")[-1], sub_pks="\n ".join(["config.add_data_dir('%s')" % sub_pkg for sub_pkg in subpackages]))) f.close() def generate_all_classes(modules_list=[], launcher=[], redirect_x=False, mipav_hacks=False): """ modules_list contains all the SEM compliant tools that should have wrappers created for them. launcher containtains the command line prefix wrapper arugments needed to prepare a proper environment for each of the modules. """ all_code = {} for module in modules_list: print("=" * 80) print("Generating Definition for module {0}".format(module)) print("^" * 80) package, code, module = generate_class(module, launcher, redirect_x = redirect_x, mipav_hacks=mipav_hacks) cur_package = all_code module_name = package.strip().split(" ")[0].split(".")[-1] for package in package.strip().split(" ")[0].split(".")[:-1]: if package not in cur_package: cur_package[package] = {} cur_package = cur_package[package] if module_name not in cur_package: cur_package[module_name] = {} cur_package[module_name][module] = code if os.path.exists("__init__.py"): os.unlink("__init__.py") crawl_code_struct(all_code, os.getcwd()) def generate_class(module, launcher, strip_module_name_prefix=True, redirect_x = False, mipav_hacks=False): dom = grab_xml(module, launcher, mipav_hacks=mipav_hacks) if strip_module_name_prefix: module_name = module.split(".")[-1] else: module_name = module inputTraits = [] outputTraits = [] outputs_filenames = {} #self._outputs_nodes = [] class_string = "\"\"\"" for desc_str in ['title', 'category', 'description', 'version', 'documentation-url', 'license', 'contributor', 'acknowledgements']: el = dom.getElementsByTagName(desc_str) if el and el[0].firstChild and el[0].firstChild.nodeValue.strip(): class_string += desc_str + ": " + el[0].firstChild.nodeValue.strip() + "\n\n" if desc_str == 'category': category = el[0].firstChild.nodeValue.strip() class_string += "\"\"\"" for paramGroup in dom.getElementsByTagName("parameters"): indices = paramGroup.getElementsByTagName('index') max_index = 0 for index in indices: if int(index.firstChild.nodeValue) > max_index: max_index = int(index.firstChild.nodeValue) for param in paramGroup.childNodes: if param.nodeName in ['label', 'description', '#text', '#comment']: continue traitsParams = {} longFlagNode = param.getElementsByTagName('longflag') if longFlagNode: ## Prefer to use longFlag as name if it is given, rather than the parameter name longFlagName = longFlagNode[0].firstChild.nodeValue ## SEM automatically strips prefixed "--" or "-" from from xml before processing ## we need to replicate that behavior here The following ## two nodes in xml have the same behavior in the program ## --test ## test longFlagName = longFlagName.lstrip(" -").rstrip(" ") name = longFlagName name = force_to_valid_python_variable_name(name) traitsParams["argstr"] = "--" + longFlagName + " " else: name = param.getElementsByTagName( 'name')[0].firstChild.nodeValue name = force_to_valid_python_variable_name(name) if param.getElementsByTagName('index'): traitsParams["argstr"] = "" else: traitsParams["argstr"] = "--" + name + " " if param.getElementsByTagName('description') and param.getElementsByTagName('description')[0].firstChild: traitsParams["desc"] = param.getElementsByTagName('description')[0].firstChild.nodeValue.replace('"', "\\\"").replace("\n", ", ") argsDict = {'directory': '%s', 'file': '%s', 'integer': "%d", 'double': "%f", 'float': "%f", 'image': "%s", 'transform': "%s", 'boolean': '', 'string-enumeration': '%s', 'string': "%s", 'integer-enumeration': '%s', 'table': '%s', 'point': '%s', 'region': '%s', 'geometry': '%s'} if param.nodeName.endswith('-vector'): traitsParams["argstr"] += "%s" else: traitsParams["argstr"] += argsDict[param.nodeName] index = param.getElementsByTagName('index') if index: traitsParams["position"] = int( index[0].firstChild.nodeValue) - (max_index + 1) desc = param.getElementsByTagName('description') if index: traitsParams["desc"] = desc[0].firstChild.nodeValue typesDict = {'integer': "traits.Int", 'double': "traits.Float", 'float': "traits.Float", 'image': "File", 'transform': "File", 'boolean': "traits.Bool", 'string': "traits.Str", 'file': "File", 'geometry': "File", 'directory': "Directory", 'table': "File", 'point': "traits.List", 'region': "traits.List"} if param.nodeName.endswith('-enumeration'): type = "traits.Enum" values = ['"%s"' % str(el.firstChild.nodeValue).replace('"', '') for el in param.getElementsByTagName('element')] elif param.nodeName.endswith('-vector'): type = "InputMultiPath" if param.nodeName in ['file', 'directory', 'image', 'geometry', 'transform', 'table']: values = ["%s(exists=True)" % typesDict[ param.nodeName.replace('-vector', '')]] else: values = [typesDict[param.nodeName.replace('-vector', '')]] if mipav_hacks == True: traitsParams["sep"] = ";" else: traitsParams["sep"] = ',' elif param.getAttribute('multiple') == "true": type = "InputMultiPath" if param.nodeName in ['file', 'directory', 'image', 'geometry', 'transform', 'table']: values = ["%s(exists=True)" % typesDict[param.nodeName]] elif param.nodeName in ['point', 'region']: values = ["%s(traits.Float(), minlen=3, maxlen=3)" % typesDict[param.nodeName]] else: values = [typesDict[param.nodeName]] traitsParams["argstr"] += "..." else: values = [] type = typesDict[param.nodeName] if param.nodeName in ['file', 'directory', 'image', 'geometry', 'transform', 'table']: if not param.getElementsByTagName('channel'): raise RuntimeError("Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field.\n{0}".format(traitsParams)) elif param.getElementsByTagName('channel')[0].firstChild.nodeValue == 'output': traitsParams["hash_files"] = False inputTraits.append( "%s = traits.Either(traits.Bool, %s(%s), %s)" % (name, type, parse_values( values).replace("exists=True", ""), parse_params(traitsParams))) traitsParams["exists"] = True traitsParams.pop("argstr") traitsParams.pop("hash_files") outputTraits.append("%s = %s(%s%s)" % (name, type.replace("Input", "Output"), parse_values(values), parse_params(traitsParams))) outputs_filenames[ name] = gen_filename_from_param(param, name) elif param.getElementsByTagName('channel')[0].firstChild.nodeValue == 'input': if param.nodeName in ['file', 'directory', 'image', 'geometry', 'transform', 'table'] and type not in ["InputMultiPath", "traits.List"]: traitsParams["exists"] = True inputTraits.append("%s = %s(%s%s)" % (name, type, parse_values(values), parse_params(traitsParams))) else: raise RuntimeError("Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field to be in ['input','output'].\n{0}".format(traitsParams)) else: # For all other parameter types, they are implicitly only input types inputTraits.append("%s = %s(%s%s)" % (name, type, parse_values( values), parse_params(traitsParams))) if mipav_hacks: blacklisted_inputs = ["maxMemoryUsage"] inputTraits = [trait for trait in inputTraits if trait.split()[0] not in blacklisted_inputs] compulsory_inputs = ['xDefaultMem = traits.Int(desc="Set default maximum heap size", argstr="-xDefaultMem %d")', 'xMaxProcess = traits.Int(1, desc="Set default maximum number of processes.", argstr="-xMaxProcess %d", usedefault=True)'] inputTraits += compulsory_inputs input_spec_code = "class " + module_name + "InputSpec(CommandLineInputSpec):\n" for trait in inputTraits: input_spec_code += " " + trait + "\n" output_spec_code = "class " + module_name + "OutputSpec(TraitedSpec):\n" if not outputTraits: output_spec_code += " pass\n" else: for trait in outputTraits: output_spec_code += " " + trait + "\n" output_filenames_code = "_outputs_filenames = {" output_filenames_code += ",".join(["'%s':'%s'" % ( key, value) for key, value in outputs_filenames.iteritems()]) output_filenames_code += "}" input_spec_code += "\n\n" output_spec_code += "\n\n" template = """class %module_name%(SEMLikeCommandLine): %class_str% input_spec = %module_name%InputSpec output_spec = %module_name%OutputSpec _cmd = "%launcher% %name% " %output_filenames_code%\n""" template += " _redirect_x = {0}\n".format(str(redirect_x)) main_class = template.replace('%class_str%', class_string).replace("%module_name%", module_name).replace("%name%", module).replace("%output_filenames_code%", output_filenames_code).replace("%launcher%", " ".join(launcher)) return category, input_spec_code + output_spec_code + main_class, module_name def grab_xml(module, launcher, mipav_hacks=False): # cmd = CommandLine(command = "Slicer3", args="--launch %s --xml"%module) # ret = cmd.run() command_list = launcher[:] # force copy to preserve original command_list.extend([module, "--xml"]) final_command = " ".join(command_list) xmlReturnValue = subprocess.Popen( final_command, stdout=subprocess.PIPE, shell=True).communicate()[0] if mipav_hacks: #workaround for a jist bug https://www.nitrc.org/tracker/index.php?func=detail&aid=7234&group_id=228&atid=942 new_xml = "" replace_closing_tag = False for line in xmlReturnValue.splitlines(): if line.strip() == "": new_xml += "\n" replace_closing_tag = True elif replace_closing_tag and line.strip() == "": new_xml += "\n" replace_closing_tag = False else: new_xml += line + "\n" xmlReturnValue = new_xml #workaround for a JIST bug https://www.nitrc.org/tracker/index.php?func=detail&aid=7233&group_id=228&atid=942 if xmlReturnValue.strip().endswith("XML"): xmlReturnValue = xmlReturnValue.strip()[:-3] if xmlReturnValue.strip().startswith("Error: Unable to set default atlas"): xmlReturnValue = xmlReturnValue.strip()[len("Error: Unable to set default atlas"):] try: dom = xml.dom.minidom.parseString(xmlReturnValue.strip()) except Exception, e: print xmlReturnValue.strip() raise e return dom # if ret.runtime.returncode == 0: # return xml.dom.minidom.parseString(ret.runtime.stdout) # else: # raise Exception(cmd.cmdline + " failed:\n%s"%ret.runtime.stderr) def parse_params(params): list = [] for key, value in params.iteritems(): if isinstance(value, six.string_types) or isinstance(value, unicode): list.append('%s="%s"' % (key, value.replace('"', "'"))) else: list.append('%s=%s' % (key, value)) return ", ".join(list) def parse_values(values): values = ['%s' % value for value in values] if len(values) > 0: retstr = ", ".join(values) + ", " else: retstr = "" return retstr def gen_filename_from_param(param, base): fileExtensions = param.getAttribute("fileExtensions") if fileExtensions: ## It is possible that multiple file extensions can be specified in a ## comma separated list, This will extract just the first extension firstFileExtension = fileExtensions.split(',')[0] ext = firstFileExtension else: ext = {'image': '.nii', 'transform': '.mat', 'file': '', 'directory': '', 'geometry': '.vtk'}[param.nodeName] return base + ext if __name__ == "__main__": ## NOTE: For now either the launcher needs to be found on the default path, or ## every tool in the modules list must be found on the default path ## AND calling the module with --xml must be supported and compliant. modules_list = ['MedianImageFilter', 'CheckerBoardFilter', 'EMSegmentCommandLine', 'GrayscaleFillHoleImageFilter', #'CreateDICOMSeries', #missing channel 'TractographyLabelMapSeeding', 'IntensityDifferenceMetric', 'DWIToDTIEstimation', 'MaskScalarVolume', 'ImageLabelCombine', 'DTIimport', 'OtsuThresholdImageFilter', 'ExpertAutomatedRegistration', 'ThresholdScalarVolume', 'DWIUnbiasedNonLocalMeansFilter', 'BRAINSFit', 'MergeModels', 'ResampleDTIVolume', 'MultiplyScalarVolumes', 'LabelMapSmoothing', 'RigidRegistration', 'VotingBinaryHoleFillingImageFilter', 'BRAINSROIAuto', 'RobustStatisticsSegmenter', 'GradientAnisotropicDiffusion', 'ProbeVolumeWithModel', 'ModelMaker', 'ExtractSkeleton', 'GrayscaleGrindPeakImageFilter', 'N4ITKBiasFieldCorrection', 'BRAINSResample', 'DTIexport', 'VBRAINSDemonWarp', 'ResampleScalarVectorDWIVolume', 'ResampleScalarVolume', 'OtsuThresholdSegmentation', # 'ExecutionModelTour', 'HistogramMatching', 'BRAINSDemonWarp', 'ModelToLabelMap', 'GaussianBlurImageFilter', 'DiffusionWeightedVolumeMasking', 'GrayscaleModelMaker', 'CastScalarVolume', 'DicomToNrrdConverter', 'AffineRegistration', 'AddScalarVolumes', 'LinearRegistration', 'SimpleRegionGrowingSegmentation', 'DWIJointRicianLMMSEFilter', 'MultiResolutionAffineRegistration', 'SubtractScalarVolumes', 'DWIRicianLMMSEFilter', 'OrientScalarVolume', 'FiducialRegistration', 'BSplineDeformableRegistration', 'CurvatureAnisotropicDiffusion', 'PETStandardUptakeValueComputation', 'DiffusionTensorScalarMeasurements', 'ACPCTransform', 'EMSegmentTransformToNewFormat', 'BSplineToDeformationField'] ## SlicerExecutionModel compliant tools that are usually statically built, and don't need the Slicer3 --launcher generate_all_classes(modules_list=modules_list,launcher=[]) ## Tools compliant with SlicerExecutionModel called from the Slicer environment (for shared lib compatibility) #launcher = ['/home/raid3/gorgolewski/software/slicer/Slicer', '--launch'] #generate_all_classes(modules_list=modules_list, launcher=launcher) #generate_all_classes(modules_list=['BRAINSABC'], launcher=[] ) nipype-0.11.0/nipype/interfaces/slicer/legacy/000077500000000000000000000000001257611314500212565ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/legacy/__init__.py000066400000000000000000000005631257611314500233730ustar00rootroot00000000000000from diffusion import * from segmentation import OtsuThresholdSegmentation from filtering import OtsuThresholdImageFilter, ResampleScalarVolume from converters import BSplineToDeformationField from registration import BSplineDeformableRegistration, AffineRegistration, MultiResolutionAffineRegistration, RigidRegistration, LinearRegistration, ExpertAutomatedRegistration nipype-0.11.0/nipype/interfaces/slicer/legacy/converters.py000066400000000000000000000025351257611314500240270ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BSplineToDeformationFieldInputSpec(CommandLineInputSpec): tfm = File(exists=True, argstr="--tfm %s") refImage = File(exists=True, argstr="--refImage %s") defImage = traits.Either(traits.Bool, File(), hash_files=False, argstr="--defImage %s") class BSplineToDeformationFieldOutputSpec(TraitedSpec): defImage = File(exists=True) class BSplineToDeformationField(SEMLikeCommandLine): """title: BSpline to deformation field category: Legacy.Converters description: Create a dense deformation field from a bspline+bulk transform. version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BSplineToDeformationField contributor: Andrey Fedorov (SPL, BWH) acknowledgements: This work is funded by NIH grants R01 CA111288 and U01 CA151261. """ input_spec = BSplineToDeformationFieldInputSpec output_spec = BSplineToDeformationFieldOutputSpec _cmd = "BSplineToDeformationField " _outputs_filenames = {'defImage':'defImage.nii'} nipype-0.11.0/nipype/interfaces/slicer/legacy/diffusion/000077500000000000000000000000001257611314500232445ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/legacy/diffusion/__init__.py000066400000000000000000000000651257611314500253560ustar00rootroot00000000000000from denoising import DWIUnbiasedNonLocalMeansFilter nipype-0.11.0/nipype/interfaces/slicer/legacy/diffusion/denoising.py000066400000000000000000000067511257611314500256060ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class DWIUnbiasedNonLocalMeansFilterInputSpec(CommandLineInputSpec): rs = InputMultiPath(traits.Int, desc="The algorithm search for similar voxels in a neighborhood of this size (larger sizes than the default one are extremely slow).", sep=",", argstr="--rs %s") rc = InputMultiPath(traits.Int, desc="Similarity between blocks is measured using windows of this size.", sep=",", argstr="--rc %s") hp = traits.Float(desc="This parameter is related to noise; the larger the parameter, the more agressive the filtering. Should be near 1, and only values between 0.8 and 1.2 are allowed", argstr="--hp %f") ng = traits.Int(desc="The number of the closest gradients that are used to jointly filter a given gradient direction (a maximum of 5 is allowed).", argstr="--ng %d") re = InputMultiPath(traits.Int, desc="A neighborhood of this size is used to compute the statistics for noise estimation.", sep=",", argstr="--re %s") inputVolume = File(position=-2, desc="Input DWI volume.", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output DWI volume.", argstr="%s") class DWIUnbiasedNonLocalMeansFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output DWI volume.", exists=True) class DWIUnbiasedNonLocalMeansFilter(SEMLikeCommandLine): """title: DWI Unbiased Non Local Means Filter category: Legacy.Diffusion.Denoising description: This module reduces noise (or unwanted detail) on a set of diffusion weighted images. For this, it filters the images using a Unbiased Non Local Means for Rician noise algorithm. It exploits not only the spatial redundancy, but the redundancy in similar gradient directions as well; it takes into account the N closest gradient directions to the direction being processed (a maximum of 5 gradient directions is allowed to keep a reasonable computational load, since we do not use neither similarity maps nor block-wise implementation). The noise parameter is automatically estimated in the same way as in the jointLMMSE module. A complete description of the algorithm may be found in: Antonio Tristan-Vega and Santiago Aja-Fernandez, DWI filtering using joint information for DTI and HARDI, Medical Image Analysis, Volume 14, Issue 2, Pages 205-218. 2010. Please, note that the execution of this filter is extremely slow, son only very conservative parameters (block size and search size as small as possible) should be used. Even so, its execution may take several hours. The advantage of this filter over joint LMMSE is its better preservation of edges and fine structures. version: 0.0.1.$Revision: 1 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/UnbiasedNonLocalMeansFilterForDWI contributor: Antonio Tristan Vega (UVa), Santiago Aja Fernandez (UVa) acknowledgements: Partially founded by grant number TEC2007-67073/TCM from the Comision Interministerial de Ciencia y Tecnologia (Spain). """ input_spec = DWIUnbiasedNonLocalMeansFilterInputSpec output_spec = DWIUnbiasedNonLocalMeansFilterOutputSpec _cmd = "DWIUnbiasedNonLocalMeansFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/legacy/diffusion/tests/000077500000000000000000000000001257611314500244065ustar00rootroot00000000000000test_auto_DWIUnbiasedNonLocalMeansFilter.py000066400000000000000000000026011257611314500346450ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/legacy/diffusion/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.diffusion.denoising import DWIUnbiasedNonLocalMeansFilter def test_DWIUnbiasedNonLocalMeansFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), hp=dict(argstr='--hp %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), ng=dict(argstr='--ng %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), rc=dict(argstr='--rc %s', sep=',', ), re=dict(argstr='--re %s', sep=',', ), rs=dict(argstr='--rs %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = DWIUnbiasedNonLocalMeansFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DWIUnbiasedNonLocalMeansFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = DWIUnbiasedNonLocalMeansFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/filtering.py000066400000000000000000000126421257611314500236200ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class OtsuThresholdImageFilterInputSpec(CommandLineInputSpec): insideValue = traits.Int(desc="The value assigned to pixels that are inside the computed threshold", argstr="--insideValue %d") outsideValue = traits.Int(desc="The value assigned to pixels that are outside the computed threshold", argstr="--outsideValue %d") numberOfBins = traits.Int(desc="This is an advanced parameter. The number of bins in the histogram used to model the probability mass function of the two intensity distributions. Small numbers of bins may result in a more conservative threshold. The default should suffice for most applications. Experimentation is the only way to see the effect of varying this parameter.", argstr="--numberOfBins %d") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class OtsuThresholdImageFilterOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class OtsuThresholdImageFilter(SEMLikeCommandLine): """title: Otsu Threshold Image Filter category: Legacy.Filtering description: This filter creates a binary thresholded image that separates an image into foreground and background components. The filter calculates the optimum threshold separating those two classes so that their combined spread (intra-class variance) is minimal (see http://en.wikipedia.org/wiki/Otsu%27s_method). Then the filter applies that threshold to the input image using the itkBinaryThresholdImageFilter. The numberOfHistogram bins can be set for the Otsu Calculator. The insideValue and outsideValue can be set for the BinaryThresholdImageFilter. The filter produces a labeled volume. The original reference is: N.Otsu, â€â€A threshold selection method from gray level histograms,’’ IEEE Trans.Syst.ManCybern.SMC-9,62–66 1979. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/OtsuThresholdImageFilter contributor: Bill Lorensen (GE) acknowledgements: This command module was derived from Insight/Examples (copyright) Insight Software Consortium """ input_spec = OtsuThresholdImageFilterInputSpec output_spec = OtsuThresholdImageFilterOutputSpec _cmd = "OtsuThresholdImageFilter " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class ResampleScalarVolumeInputSpec(CommandLineInputSpec): spacing = InputMultiPath(traits.Float, desc="Spacing along each dimension (0 means use input spacing)", sep=",", argstr="--spacing %s") interpolation = traits.Enum("linear", "nearestNeighbor", "bspline", "hamming", "cosine", "welch", "lanczos", "blackman", desc="Sampling algorithm (linear, nearest neighbor, bspline(cubic) or windowed sinc). There are several sinc algorithms available as described in the following publication: Erik H. W. Meijering, Wiro J. Niessen, Josien P. W. Pluim, Max A. Viergever: Quantitative Comparison of Sinc-Approximating Kernels for Medical Image Interpolation. MICCAI 1999, pp. 210-217. Each window has a radius of 3;", argstr="--interpolation %s") InputVolume = File(position=-2, desc="Input volume to be resampled", exists=True, argstr="%s") OutputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Resampled Volume", argstr="%s") class ResampleScalarVolumeOutputSpec(TraitedSpec): OutputVolume = File(position=-1, desc="Resampled Volume", exists=True) class ResampleScalarVolume(SEMLikeCommandLine): """title: Resample Scalar Volume category: Legacy.Filtering description: Resampling an image is an important task in image analysis. It is especially important in the frame of image registration. This module implements image resampling through the use of itk Transforms. This module uses an Identity Transform. The resampling is controlled by the Output Spacing. "Resampling" is performed in space coordinates, not pixel/grid coordinates. It is quite important to ensure that image spacing is properly set on the images involved. The interpolator is required since the mapping from one space to the other will often require evaluation of the intensity of the image at non-grid positions. Several interpolators are available: linear, nearest neighbor, bspline and five flavors of sinc. The sinc interpolators, although more precise, are much slower than the linear and nearest neighbor interpolator. To resample label volumnes, nearest neighbor interpolation should be used exclusively. version: 0.1.0.$Revision: 20594 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ResampleVolume contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ResampleScalarVolumeInputSpec output_spec = ResampleScalarVolumeOutputSpec _cmd = "ResampleScalarVolume " _outputs_filenames = {'OutputVolume':'OutputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/legacy/registration.py000066400000000000000000000657741257611314500243650ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BSplineDeformableRegistrationInputSpec(CommandLineInputSpec): iterations = traits.Int(desc="Number of iterations", argstr="--iterations %d") gridSize = traits.Int(desc="Number of grid points on interior of the fixed image. Larger grid sizes allow for finer registrations.", argstr="--gridSize %d") histogrambins = traits.Int(desc="Number of histogram bins to use for Mattes Mutual Information. Reduce the number of bins if a deformable registration fails. If the number of bins is too large, the estimated PDFs will be a field of impulses and will inhibit reliable registration estimation.", argstr="--histogrambins %d") spatialsamples = traits.Int(desc="Number of spatial samples to use in estimating Mattes Mutual Information. Larger values yield more accurate PDFs and improved registration quality.", argstr="--spatialsamples %d") constrain = traits.Bool(desc="Constrain the deformation to the amount specified in Maximum Deformation", argstr="--constrain ") maximumDeformation = traits.Float(desc="If Constrain Deformation is checked, limit the deformation to this amount.", argstr="--maximumDeformation %f") default = traits.Int(desc="Default pixel value used if resampling a pixel outside of the volume.", argstr="--default %d") initialtransform = File(desc="Initial transform for aligning the fixed and moving image. Maps positions in the fixed coordinate frame to positions in the moving coordinate frame. This transform should be an affine or rigid transform. It is used an a bulk transform for the BSpline. Optional.", exists=True, argstr="--initialtransform %s") FixedImageFileName = File(position=-2, desc="Fixed image to which to register", exists=True, argstr="%s") MovingImageFileName = File(position=-1, desc="Moving image", exists=True, argstr="%s") outputtransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Transform calculated that aligns the fixed and moving image. Maps positions from the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--outputtransform %s") outputwarp = traits.Either(traits.Bool, File(), hash_files=False, desc="Vector field that applies an equivalent warp as the BSpline. Maps positions from the fixed coordinate frame to the moving coordinate frame. Optional.", argstr="--outputwarp %s") resampledmovingfilename = traits.Either(traits.Bool, File(), hash_files=False, desc="Resampled moving image to fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--resampledmovingfilename %s") class BSplineDeformableRegistrationOutputSpec(TraitedSpec): outputtransform = File(desc="Transform calculated that aligns the fixed and moving image. Maps positions from the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) outputwarp = File(desc="Vector field that applies an equivalent warp as the BSpline. Maps positions from the fixed coordinate frame to the moving coordinate frame. Optional.", exists=True) resampledmovingfilename = File(desc="Resampled moving image to fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) class BSplineDeformableRegistration(SEMLikeCommandLine): """title: BSpline Deformable Registration category: Legacy.Registration description: Registers two images together using BSpline transform and mutual information. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/BSplineDeformableRegistration contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = BSplineDeformableRegistrationInputSpec output_spec = BSplineDeformableRegistrationOutputSpec _cmd = "BSplineDeformableRegistration " _outputs_filenames = {'resampledmovingfilename':'resampledmovingfilename.nii','outputtransform':'outputtransform.txt','outputwarp':'outputwarp.nrrd'} class AffineRegistrationInputSpec(CommandLineInputSpec): fixedsmoothingfactor = traits.Int(desc="Amount of smoothing applied to fixed image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--fixedsmoothingfactor %d") movingsmoothingfactor = traits.Int(desc="Amount of smoothing applied to moving image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--movingsmoothingfactor %d") histogrambins = traits.Int(desc="Number of histogram bins to use for Mattes Mutual Information. Reduce the number of bins if a registration fails. If the number of bins is too large, the estimated PDFs will be a field of impulses and will inhibit reliable registration estimation.", argstr="--histogrambins %d") spatialsamples = traits.Int(desc="Number of spatial samples to use in estimating Mattes Mutual Information. Larger values yield more accurate PDFs and improved registration quality.", argstr="--spatialsamples %d") iterations = traits.Int(desc="Number of iterations", argstr="--iterations %d") translationscale = traits.Float(desc="Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree. (Actual scale used is 1/(TranslationScale^2)). This parameter is used to \'weight\' or \'standardized\' the transform parameters and their effect on the registration objective function.", argstr="--translationscale %f") initialtransform = File(desc="Initial transform for aligning the fixed and moving image. Maps positions in the fixed coordinate frame to positions in the moving coordinate frame. Optional.", exists=True, argstr="--initialtransform %s") FixedImageFileName = File(position=-2, desc="Fixed image to which to register", exists=True, argstr="%s") MovingImageFileName = File(position=-1, desc="Moving image", exists=True, argstr="%s") outputtransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--outputtransform %s") resampledmovingfilename = traits.Either(traits.Bool, File(), hash_files=False, desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--resampledmovingfilename %s") class AffineRegistrationOutputSpec(TraitedSpec): outputtransform = File(desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) resampledmovingfilename = File(desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) class AffineRegistration(SEMLikeCommandLine): """title: Affine Registration category: Legacy.Registration description: Registers two images together using an affine transform and mutual information. This module is often used to align images of different subjects or images of the same subject from different modalities. This module can smooth images prior to registration to mitigate noise and improve convergence. Many of the registration parameters require a working knowledge of the algorithm although the default parameters are sufficient for many registration tasks. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/AffineRegistration contributor: Daniel Blezek (GE) acknowledgements: This module was developed by Daniel Blezek while at GE Research with contributions from Jim Miller. This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = AffineRegistrationInputSpec output_spec = AffineRegistrationOutputSpec _cmd = "AffineRegistration " _outputs_filenames = {'resampledmovingfilename':'resampledmovingfilename.nii','outputtransform':'outputtransform.txt'} class MultiResolutionAffineRegistrationInputSpec(CommandLineInputSpec): fixedImage = File(position=-2, desc="Image which defines the space into which the moving image is registered", exists=True, argstr="%s") movingImage = File(position=-1, desc="The transform goes from the fixed image's space into the moving image's space", exists=True, argstr="%s") resampledImage = traits.Either(traits.Bool, File(), hash_files=False, desc="Registration results", argstr="--resampledImage %s") saveTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Save the output transform from the registration", argstr="--saveTransform %s") fixedImageMask = File(desc="Label image which defines a mask of interest for the fixed image", exists=True, argstr="--fixedImageMask %s") fixedImageROI = traits.List(desc="Label image which defines a ROI of interest for the fixed image", argstr="--fixedImageROI %s") numIterations = traits.Int(desc="Number of iterations to run at each resolution level.", argstr="--numIterations %d") numLineIterations = traits.Int(desc="Number of iterations to run at each resolution level.", argstr="--numLineIterations %d") stepSize = traits.Float(desc="The maximum step size of the optimizer in voxels", argstr="--stepSize %f") stepTolerance = traits.Float(desc="The maximum step size of the optimizer in voxels", argstr="--stepTolerance %f") metricTolerance = traits.Float(argstr="--metricTolerance %f") class MultiResolutionAffineRegistrationOutputSpec(TraitedSpec): resampledImage = File(desc="Registration results", exists=True) saveTransform = File(desc="Save the output transform from the registration", exists=True) class MultiResolutionAffineRegistration(SEMLikeCommandLine): """title: Robust Multiresolution Affine Registration category: Legacy.Registration description: Provides affine registration using multiple resolution levels and decomposed affine transforms. version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/MultiResolutionAffineRegistration contributor: Casey B Goodlett (Utah) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = MultiResolutionAffineRegistrationInputSpec output_spec = MultiResolutionAffineRegistrationOutputSpec _cmd = "MultiResolutionAffineRegistration " _outputs_filenames = {'resampledImage':'resampledImage.nii','saveTransform':'saveTransform.txt'} class RigidRegistrationInputSpec(CommandLineInputSpec): fixedsmoothingfactor = traits.Int(desc="Amount of smoothing applied to fixed image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--fixedsmoothingfactor %d") movingsmoothingfactor = traits.Int(desc="Amount of smoothing applied to moving image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--movingsmoothingfactor %d") testingmode = traits.Bool(desc="Enable testing mode. Input transform will be used to construct floating image. The floating image will be ignored if passed.", argstr="--testingmode ") histogrambins = traits.Int(desc="Number of histogram bins to use for Mattes Mutual Information. Reduce the number of bins if a registration fails. If the number of bins is too large, the estimated PDFs will be a field of impulses and will inhibit reliable registration estimation.", argstr="--histogrambins %d") spatialsamples = traits.Int(desc="Number of spatial samples to use in estimating Mattes Mutual Information. Larger values yield more accurate PDFs and improved registration quality.", argstr="--spatialsamples %d") iterations = InputMultiPath(traits.Int, desc="Comma separated list of iterations. Must have the same number of elements as the learning rate.", sep=",", argstr="--iterations %s") learningrate = InputMultiPath(traits.Float, desc="Comma separated list of learning rates. Learning rate is a scale factor on the gradient of the registration objective function (gradient with respect to the parameters of the transformation) used to update the parameters of the transformation during optimization. Smaller values cause the optimizer to take smaller steps through the parameter space. Larger values are typically used early in the registration process to take large jumps in parameter space followed by smaller values to home in on the optimum value of the registration objective function. Default is: 0.01, 0.005, 0.0005, 0.0002. Must have the same number of elements as iterations.", sep=",", argstr="--learningrate %s") translationscale = traits.Float(desc="Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree. (Actual scale used 1/(TranslationScale^2)). This parameter is used to \'weight\' or \'standardized\' the transform parameters and their effect on the registration objective function.", argstr="--translationscale %f") initialtransform = File(desc="Initial transform for aligning the fixed and moving image. Maps positions in the fixed coordinate frame to positions in the moving coordinate frame. Optional.", exists=True, argstr="--initialtransform %s") FixedImageFileName = File(position=-2, desc="Fixed image to which to register", exists=True, argstr="%s") MovingImageFileName = File(position=-1, desc="Moving image", exists=True, argstr="%s") outputtransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--outputtransform %s") resampledmovingfilename = traits.Either(traits.Bool, File(), hash_files=False, desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--resampledmovingfilename %s") class RigidRegistrationOutputSpec(TraitedSpec): outputtransform = File(desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) resampledmovingfilename = File(desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) class RigidRegistration(SEMLikeCommandLine): """title: Rigid Registration category: Legacy.Registration description: Registers two images together using a rigid transform and mutual information. This module was originally distributed as "Linear registration" but has been renamed to eliminate confusion with the "Affine registration" module. This module is often used to align images of different subjects or images of the same subject from different modalities. This module can smooth images prior to registration to mitigate noise and improve convergence. Many of the registration parameters require a working knowledge of the algorithm although the default parameters are sufficient for many registration tasks. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/RigidRegistration contributor: Daniel Blezek (GE) acknowledgements: This module was developed by Daniel Blezek while at GE Research with contributions from Jim Miller. This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = RigidRegistrationInputSpec output_spec = RigidRegistrationOutputSpec _cmd = "RigidRegistration " _outputs_filenames = {'resampledmovingfilename':'resampledmovingfilename.nii','outputtransform':'outputtransform.txt'} class LinearRegistrationInputSpec(CommandLineInputSpec): fixedsmoothingfactor = traits.Int(desc="Amount of smoothing applied to fixed image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--fixedsmoothingfactor %d") movingsmoothingfactor = traits.Int(desc="Amount of smoothing applied to moving image prior to registration. Default is 0 (none). Range is 0-5 (unitless). Consider smoothing the input data if there is considerable amounts of noise or the noise pattern in the fixed and moving images is very different.", argstr="--movingsmoothingfactor %d") histogrambins = traits.Int(desc="Number of histogram bins to use for Mattes Mutual Information. Reduce the number of bins if a registration fails. If the number of bins is too large, the estimated PDFs will be a field of impulses and will inhibit reliable registration estimation.", argstr="--histogrambins %d") spatialsamples = traits.Int(desc="Number of spatial samples to use in estimating Mattes Mutual Information. Larger values yield more accurate PDFs and improved registration quality.", argstr="--spatialsamples %d") iterations = InputMultiPath(traits.Int, desc="Comma separated list of iterations. Must have the same number of elements as the learning rate.", sep=",", argstr="--iterations %s") learningrate = InputMultiPath(traits.Float, desc="Comma separated list of learning rates. Learning rate is a scale factor on the gradient of the registration objective function (gradient with respect to the parameters of the transformation) used to update the parameters of the transformation during optimization. Smaller values cause the optimizer to take smaller steps through the parameter space. Larger values are typically used early in the registration process to take large jumps in parameter space followed by smaller values to home in on the optimum value of the registration objective function. Default is: 0.01, 0.005, 0.0005, 0.0002. Must have the same number of elements as iterations.", sep=",", argstr="--learningrate %s") translationscale = traits.Float(desc="Relative scale of translations to rotations, i.e. a value of 100 means 10mm = 1 degree. (Actual scale used 1/(TranslationScale^2)). This parameter is used to \'weight\' or \'standardized\' the transform parameters and their effect on the registration objective function.", argstr="--translationscale %f") initialtransform = File(desc="Initial transform for aligning the fixed and moving image. Maps positions in the fixed coordinate frame to positions in the moving coordinate frame. Optional.", exists=True, argstr="--initialtransform %s") FixedImageFileName = File(position=-2, desc="Fixed image to which to register", exists=True, argstr="%s") MovingImageFileName = File(position=-1, desc="Moving image", exists=True, argstr="%s") outputtransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--outputtransform %s") resampledmovingfilename = traits.Either(traits.Bool, File(), hash_files=False, desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", argstr="--resampledmovingfilename %s") class LinearRegistrationOutputSpec(TraitedSpec): outputtransform = File(desc="Transform calculated that aligns the fixed and moving image. Maps positions in the fixed coordinate frame to the moving coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) resampledmovingfilename = File(desc="Resampled moving image to the fixed image coordinate frame. Optional (specify an output transform or an output volume or both).", exists=True) class LinearRegistration(SEMLikeCommandLine): """title: Linear Registration category: Legacy.Registration description: Registers two images together using a rigid transform and mutual information. version: 0.1.0.$Revision: 19608 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/LinearRegistration contributor: Daniel Blezek (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = LinearRegistrationInputSpec output_spec = LinearRegistrationOutputSpec _cmd = "LinearRegistration " _outputs_filenames = {'resampledmovingfilename':'resampledmovingfilename.nii','outputtransform':'outputtransform.txt'} class ExpertAutomatedRegistrationInputSpec(CommandLineInputSpec): fixedImage = File(position=-2, desc="Image which defines the space into which the moving image is registered", exists=True, argstr="%s") movingImage = File(position=-1, desc="The transform goes from the fixed image's space into the moving image's space", exists=True, argstr="%s") resampledImage = traits.Either(traits.Bool, File(), hash_files=False, desc="Registration results", argstr="--resampledImage %s") loadTransform = File(desc="Load a transform that is immediately applied to the moving image", exists=True, argstr="--loadTransform %s") saveTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Save the transform that results from registration", argstr="--saveTransform %s") initialization = traits.Enum("None", "Landmarks", "ImageCenters", "CentersOfMass", "SecondMoments", desc="Method to prime the registration process", argstr="--initialization %s") registration = traits.Enum("None", "Initial", "Rigid", "Affine", "BSpline", "PipelineRigid", "PipelineAffine", "PipelineBSpline", desc="Method for the registration process", argstr="--registration %s") metric = traits.Enum("MattesMI", "NormCorr", "MeanSqrd", desc="Method to quantify image match", argstr="--metric %s") expectedOffset = traits.Float(desc="Expected misalignment after initialization", argstr="--expectedOffset %f") expectedRotation = traits.Float(desc="Expected misalignment after initialization", argstr="--expectedRotation %f") expectedScale = traits.Float(desc="Expected misalignment after initialization", argstr="--expectedScale %f") expectedSkew = traits.Float(desc="Expected misalignment after initialization", argstr="--expectedSkew %f") verbosityLevel = traits.Enum("Silent", "Standard", "Verbose", desc="Level of detail of reporting progress", argstr="--verbosityLevel %s") sampleFromOverlap = traits.Bool(desc="Limit metric evaluation to the fixed image region overlapped by the moving image", argstr="--sampleFromOverlap ") fixedImageMask = File(desc="Image which defines a mask for the fixed image", exists=True, argstr="--fixedImageMask %s") randomNumberSeed = traits.Int(desc="Seed to generate a consistent random number sequence", argstr="--randomNumberSeed %d") numberOfThreads = traits.Int(desc="Number of CPU threads to use", argstr="--numberOfThreads %d") minimizeMemory = traits.Bool(desc="Reduce the amount of memory required at the cost of increased computation time", argstr="--minimizeMemory ") interpolation = traits.Enum("NearestNeighbor", "Linear", "BSpline", desc="Method for interpolation within the optimization process", argstr="--interpolation %s") fixedLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the fixed image", argstr="--fixedLandmarks %s...") movingLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the moving image", argstr="--movingLandmarks %s...") rigidMaxIterations = traits.Int(desc="Maximum number of rigid optimization iterations", argstr="--rigidMaxIterations %d") rigidSamplingRatio = traits.Float(desc="Portion of the image to use in computing the metric during rigid registration", argstr="--rigidSamplingRatio %f") affineMaxIterations = traits.Int(desc="Maximum number of affine optimization iterations", argstr="--affineMaxIterations %d") affineSamplingRatio = traits.Float(desc="Portion of the image to use in computing the metric during affine registration", argstr="--affineSamplingRatio %f") bsplineMaxIterations = traits.Int(desc="Maximum number of bspline optimization iterations", argstr="--bsplineMaxIterations %d") bsplineSamplingRatio = traits.Float(desc="Portion of the image to use in computing the metric during BSpline registration", argstr="--bsplineSamplingRatio %f") controlPointSpacing = traits.Int(desc="Number of pixels between control points", argstr="--controlPointSpacing %d") class ExpertAutomatedRegistrationOutputSpec(TraitedSpec): resampledImage = File(desc="Registration results", exists=True) saveTransform = File(desc="Save the transform that results from registration", exists=True) class ExpertAutomatedRegistration(SEMLikeCommandLine): """title: Expert Automated Registration category: Legacy.Registration description: Provides rigid, affine, and BSpline registration methods via a simple GUI version: 0.1.0.$Revision: 2104 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ExpertAutomatedRegistration contributor: Stephen R Aylward (Kitware), Casey B Goodlett (Kitware) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ExpertAutomatedRegistrationInputSpec output_spec = ExpertAutomatedRegistrationOutputSpec _cmd = "ExpertAutomatedRegistration " _outputs_filenames = {'resampledImage':'resampledImage.nii','saveTransform':'saveTransform.txt'} nipype-0.11.0/nipype/interfaces/slicer/legacy/segmentation.py000066400000000000000000000056321257611314500243330ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class OtsuThresholdSegmentationInputSpec(CommandLineInputSpec): brightObjects = traits.Bool(desc="Segmenting bright objects on a dark background or dark objects on a bright background.", argstr="--brightObjects ") numberOfBins = traits.Int(desc="This is an advanced parameter. The number of bins in the histogram used to model the probability mass function of the two intensity distributions. Small numbers of bins may result in a more conservative threshold. The default should suffice for most applications. Experimentation is the only way to see the effect of varying this parameter.", argstr="--numberOfBins %d") faceConnected = traits.Bool(desc="This is an advanced parameter. Adjacent voxels are face connected. This affects the connected component algorithm. If this parameter is false, more regions are likely to be identified.", argstr="--faceConnected ") minimumObjectSize = traits.Int(desc="Minimum size of object to retain. This parameter can be used to get rid of small regions in noisy images.", argstr="--minimumObjectSize %d") inputVolume = File(position=-2, desc="Input volume to be segmented", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class OtsuThresholdSegmentationOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class OtsuThresholdSegmentation(SEMLikeCommandLine): """title: Otsu Threshold Segmentation category: Legacy.Segmentation description: This filter creates a labeled image from a grayscale image. First, it calculates an optimal threshold that separates the image into foreground and background. This threshold separates those two classes so that their intra-class variance is minimal (see http://en.wikipedia.org/wiki/Otsu%27s_method). Then the filter runs a connected component algorithm to generate unique labels for each connected region of the foreground. Finally, the resulting image is relabeled to provide consecutive numbering. version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/OtsuThresholdSegmentation contributor: Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = OtsuThresholdSegmentationInputSpec output_spec = OtsuThresholdSegmentationOutputSpec _cmd = "OtsuThresholdSegmentation " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/000077500000000000000000000000001257611314500224205ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_AffineRegistration.py000066400000000000000000000033511257611314500306460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import AffineRegistration def test_AffineRegistration_inputs(): input_map = dict(FixedImageFileName=dict(argstr='%s', position=-2, ), MovingImageFileName=dict(argstr='%s', position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedsmoothingfactor=dict(argstr='--fixedsmoothingfactor %d', ), histogrambins=dict(argstr='--histogrambins %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialtransform=dict(argstr='--initialtransform %s', ), iterations=dict(argstr='--iterations %d', ), movingsmoothingfactor=dict(argstr='--movingsmoothingfactor %d', ), outputtransform=dict(argstr='--outputtransform %s', hash_files=False, ), resampledmovingfilename=dict(argstr='--resampledmovingfilename %s', hash_files=False, ), spatialsamples=dict(argstr='--spatialsamples %d', ), terminal_output=dict(nohash=True, ), translationscale=dict(argstr='--translationscale %f', ), ) inputs = AffineRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_AffineRegistration_outputs(): output_map = dict(outputtransform=dict(), resampledmovingfilename=dict(), ) outputs = AffineRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_BSplineDeformableRegistration.py000066400000000000000000000036031257611314500327730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import BSplineDeformableRegistration def test_BSplineDeformableRegistration_inputs(): input_map = dict(FixedImageFileName=dict(argstr='%s', position=-2, ), MovingImageFileName=dict(argstr='%s', position=-1, ), args=dict(argstr='%s', ), constrain=dict(argstr='--constrain ', ), default=dict(argstr='--default %d', ), environ=dict(nohash=True, usedefault=True, ), gridSize=dict(argstr='--gridSize %d', ), histogrambins=dict(argstr='--histogrambins %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialtransform=dict(argstr='--initialtransform %s', ), iterations=dict(argstr='--iterations %d', ), maximumDeformation=dict(argstr='--maximumDeformation %f', ), outputtransform=dict(argstr='--outputtransform %s', hash_files=False, ), outputwarp=dict(argstr='--outputwarp %s', hash_files=False, ), resampledmovingfilename=dict(argstr='--resampledmovingfilename %s', hash_files=False, ), spatialsamples=dict(argstr='--spatialsamples %d', ), terminal_output=dict(nohash=True, ), ) inputs = BSplineDeformableRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BSplineDeformableRegistration_outputs(): output_map = dict(outputtransform=dict(), outputwarp=dict(), resampledmovingfilename=dict(), ) outputs = BSplineDeformableRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_BSplineToDeformationField.py000066400000000000000000000021761257611314500320620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.converters import BSplineToDeformationField def test_BSplineToDeformationField_inputs(): input_map = dict(args=dict(argstr='%s', ), defImage=dict(argstr='--defImage %s', hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), refImage=dict(argstr='--refImage %s', ), terminal_output=dict(nohash=True, ), tfm=dict(argstr='--tfm %s', ), ) inputs = BSplineToDeformationField.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BSplineToDeformationField_outputs(): output_map = dict(defImage=dict(), ) outputs = BSplineToDeformationField.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_ExpertAutomatedRegistration.py000066400000000000000000000054261257611314500325760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import ExpertAutomatedRegistration def test_ExpertAutomatedRegistration_inputs(): input_map = dict(affineMaxIterations=dict(argstr='--affineMaxIterations %d', ), affineSamplingRatio=dict(argstr='--affineSamplingRatio %f', ), args=dict(argstr='%s', ), bsplineMaxIterations=dict(argstr='--bsplineMaxIterations %d', ), bsplineSamplingRatio=dict(argstr='--bsplineSamplingRatio %f', ), controlPointSpacing=dict(argstr='--controlPointSpacing %d', ), environ=dict(nohash=True, usedefault=True, ), expectedOffset=dict(argstr='--expectedOffset %f', ), expectedRotation=dict(argstr='--expectedRotation %f', ), expectedScale=dict(argstr='--expectedScale %f', ), expectedSkew=dict(argstr='--expectedSkew %f', ), fixedImage=dict(argstr='%s', position=-2, ), fixedImageMask=dict(argstr='--fixedImageMask %s', ), fixedLandmarks=dict(argstr='--fixedLandmarks %s...', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialization=dict(argstr='--initialization %s', ), interpolation=dict(argstr='--interpolation %s', ), loadTransform=dict(argstr='--loadTransform %s', ), metric=dict(argstr='--metric %s', ), minimizeMemory=dict(argstr='--minimizeMemory ', ), movingImage=dict(argstr='%s', position=-1, ), movingLandmarks=dict(argstr='--movingLandmarks %s...', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), randomNumberSeed=dict(argstr='--randomNumberSeed %d', ), registration=dict(argstr='--registration %s', ), resampledImage=dict(argstr='--resampledImage %s', hash_files=False, ), rigidMaxIterations=dict(argstr='--rigidMaxIterations %d', ), rigidSamplingRatio=dict(argstr='--rigidSamplingRatio %f', ), sampleFromOverlap=dict(argstr='--sampleFromOverlap ', ), saveTransform=dict(argstr='--saveTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), verbosityLevel=dict(argstr='--verbosityLevel %s', ), ) inputs = ExpertAutomatedRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ExpertAutomatedRegistration_outputs(): output_map = dict(resampledImage=dict(), saveTransform=dict(), ) outputs = ExpertAutomatedRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_LinearRegistration.py000066400000000000000000000034741257611314500306760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import LinearRegistration def test_LinearRegistration_inputs(): input_map = dict(FixedImageFileName=dict(argstr='%s', position=-2, ), MovingImageFileName=dict(argstr='%s', position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedsmoothingfactor=dict(argstr='--fixedsmoothingfactor %d', ), histogrambins=dict(argstr='--histogrambins %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialtransform=dict(argstr='--initialtransform %s', ), iterations=dict(argstr='--iterations %s', sep=',', ), learningrate=dict(argstr='--learningrate %s', sep=',', ), movingsmoothingfactor=dict(argstr='--movingsmoothingfactor %d', ), outputtransform=dict(argstr='--outputtransform %s', hash_files=False, ), resampledmovingfilename=dict(argstr='--resampledmovingfilename %s', hash_files=False, ), spatialsamples=dict(argstr='--spatialsamples %d', ), terminal_output=dict(nohash=True, ), translationscale=dict(argstr='--translationscale %f', ), ) inputs = LinearRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LinearRegistration_outputs(): output_map = dict(outputtransform=dict(), resampledmovingfilename=dict(), ) outputs = LinearRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_MultiResolutionAffineRegistration.py000066400000000000000000000033411257611314500337440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import MultiResolutionAffineRegistration def test_MultiResolutionAffineRegistration_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedImage=dict(argstr='%s', position=-2, ), fixedImageMask=dict(argstr='--fixedImageMask %s', ), fixedImageROI=dict(argstr='--fixedImageROI %s', ), ignore_exception=dict(nohash=True, usedefault=True, ), metricTolerance=dict(argstr='--metricTolerance %f', ), movingImage=dict(argstr='%s', position=-1, ), numIterations=dict(argstr='--numIterations %d', ), numLineIterations=dict(argstr='--numLineIterations %d', ), resampledImage=dict(argstr='--resampledImage %s', hash_files=False, ), saveTransform=dict(argstr='--saveTransform %s', hash_files=False, ), stepSize=dict(argstr='--stepSize %f', ), stepTolerance=dict(argstr='--stepTolerance %f', ), terminal_output=dict(nohash=True, ), ) inputs = MultiResolutionAffineRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultiResolutionAffineRegistration_outputs(): output_map = dict(resampledImage=dict(), saveTransform=dict(), ) outputs = MultiResolutionAffineRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_OtsuThresholdImageFilter.py000066400000000000000000000024421257611314500320030ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.filtering import OtsuThresholdImageFilter def test_OtsuThresholdImageFilter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), insideValue=dict(argstr='--insideValue %d', ), numberOfBins=dict(argstr='--numberOfBins %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), outsideValue=dict(argstr='--outsideValue %d', ), terminal_output=dict(nohash=True, ), ) inputs = OtsuThresholdImageFilter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_OtsuThresholdImageFilter_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = OtsuThresholdImageFilter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_OtsuThresholdSegmentation.py000066400000000000000000000025571257611314500322570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.segmentation import OtsuThresholdSegmentation def test_OtsuThresholdSegmentation_inputs(): input_map = dict(args=dict(argstr='%s', ), brightObjects=dict(argstr='--brightObjects ', ), environ=dict(nohash=True, usedefault=True, ), faceConnected=dict(argstr='--faceConnected ', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), minimumObjectSize=dict(argstr='--minimumObjectSize %d', ), numberOfBins=dict(argstr='--numberOfBins %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = OtsuThresholdSegmentation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_OtsuThresholdSegmentation_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = OtsuThresholdSegmentation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_ResampleScalarVolume.py000066400000000000000000000023341257611314500311510ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.filtering import ResampleScalarVolume def test_ResampleScalarVolume_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-2, ), OutputVolume=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), interpolation=dict(argstr='--interpolation %s', ), spacing=dict(argstr='--spacing %s', sep=',', ), terminal_output=dict(nohash=True, ), ) inputs = ResampleScalarVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ResampleScalarVolume_outputs(): output_map = dict(OutputVolume=dict(position=-1, ), ) outputs = ResampleScalarVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/legacy/tests/test_auto_RigidRegistration.py000066400000000000000000000035541257611314500305210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.legacy.registration import RigidRegistration def test_RigidRegistration_inputs(): input_map = dict(FixedImageFileName=dict(argstr='%s', position=-2, ), MovingImageFileName=dict(argstr='%s', position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedsmoothingfactor=dict(argstr='--fixedsmoothingfactor %d', ), histogrambins=dict(argstr='--histogrambins %d', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialtransform=dict(argstr='--initialtransform %s', ), iterations=dict(argstr='--iterations %s', sep=',', ), learningrate=dict(argstr='--learningrate %s', sep=',', ), movingsmoothingfactor=dict(argstr='--movingsmoothingfactor %d', ), outputtransform=dict(argstr='--outputtransform %s', hash_files=False, ), resampledmovingfilename=dict(argstr='--resampledmovingfilename %s', hash_files=False, ), spatialsamples=dict(argstr='--spatialsamples %d', ), terminal_output=dict(nohash=True, ), testingmode=dict(argstr='--testingmode ', ), translationscale=dict(argstr='--translationscale %f', ), ) inputs = RigidRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_RigidRegistration_outputs(): output_map = dict(outputtransform=dict(), resampledmovingfilename=dict(), ) outputs = RigidRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/quantification/000077500000000000000000000000001257611314500230305ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/quantification/__init__.py000066400000000000000000000002131257611314500251350ustar00rootroot00000000000000from changequantification import IntensityDifferenceMetric from petstandarduptakevaluecomputation import PETStandardUptakeValueComputation nipype-0.11.0/nipype/interfaces/slicer/quantification/changequantification.py000066400000000000000000000044141257611314500275710ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class IntensityDifferenceMetricInputSpec(CommandLineInputSpec): sensitivityThreshold = traits.Float(desc="This parameter should be between 0 and 1, and defines how sensitive the metric should be to the intensity changes.", argstr="--sensitivityThreshold %f") changingBandSize = traits.Int(desc="How far (in mm) from the boundary of the segmentation should the intensity changes be considered.", argstr="--changingBandSize %d") baselineVolume = File(position=-4, desc="Baseline volume to be compared to", exists=True, argstr="%s") baselineSegmentationVolume = File(position=-3, desc="Label volume that contains segmentation of the structure of interest in the baseline volume.", exists=True, argstr="%s") followupVolume = File(position=-2, desc="Followup volume to be compare to the baseline", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output volume to keep the results of change quantification.", argstr="%s") reportFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="Report file name", argstr="--reportFileName %s") class IntensityDifferenceMetricOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output volume to keep the results of change quantification.", exists=True) reportFileName = File(desc="Report file name", exists=True) class IntensityDifferenceMetric(SEMLikeCommandLine): """title: Intensity Difference Change Detection (FAST) category: Quantification.ChangeQuantification description: Quantifies the changes between two spatially aligned images based on the pixel-wise difference of image intensities. version: 0.1 contributor: Andrey Fedorov acknowledgements: """ input_spec = IntensityDifferenceMetricInputSpec output_spec = IntensityDifferenceMetricOutputSpec _cmd = "IntensityDifferenceMetric " _outputs_filenames = {'outputVolume':'outputVolume.nii','reportFileName':'reportFileName'} nipype-0.11.0/nipype/interfaces/slicer/quantification/petstandarduptakevaluecomputation.py000066400000000000000000000061501257611314500324470ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class PETStandardUptakeValueComputationInputSpec(CommandLineInputSpec): petDICOMPath = Directory(desc="Input path to a directory containing a PET volume containing DICOM header information for SUV computation", exists=True, argstr="--petDICOMPath %s") petVolume = File(desc="Input PET volume for SUVbw computation (must be the same volume as pointed to by the DICOM path!).", exists=True, argstr="--petVolume %s") labelMap = File(desc="Input label volume containing the volumes of interest", exists=True, argstr="--labelMap %s") color = File(desc="Color table to to map labels to colors and names", exists=True, argstr="--color %s") csvFile = traits.Either(traits.Bool, File(), hash_files=False, desc="A file holding the output SUV values in comma separated lines, one per label. Optional.", argstr="--csvFile %s") OutputLabel = traits.Str(desc="List of labels for which SUV values were computed", argstr="--OutputLabel %s") OutputLabelValue = traits.Str(desc="List of label values for which SUV values were computed", argstr="--OutputLabelValue %s") SUVMax = traits.Str(desc="SUV max for each label", argstr="--SUVMax %s") SUVMean = traits.Str(desc="SUV mean for each label", argstr="--SUVMean %s") SUVMin = traits.Str(desc="SUV minimum for each label", argstr="--SUVMin %s") class PETStandardUptakeValueComputationOutputSpec(TraitedSpec): csvFile = File(desc="A file holding the output SUV values in comma separated lines, one per label. Optional.", exists=True) class PETStandardUptakeValueComputation(SEMLikeCommandLine): """title: PET Standard Uptake Value Computation category: Quantification description: Computes the standardized uptake value based on body weight. Takes an input PET image in DICOM and NRRD format (DICOM header must contain Radiopharmaceutical parameters). Produces a CSV file that contains patientID, studyDate, dose, labelID, suvmin, suvmax, suvmean, labelName for each volume of interest. It also displays some of the information as output strings in the GUI, the CSV file is optional in that case. The CSV file is appended to on each execution of the CLI. version: 0.1.0.$Revision: 8595 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ComputeSUVBodyWeight contributor: Wendy Plesniak (SPL, BWH), Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: This work is funded by the Harvard Catalyst, and the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = PETStandardUptakeValueComputationInputSpec output_spec = PETStandardUptakeValueComputationOutputSpec _cmd = "PETStandardUptakeValueComputation " _outputs_filenames = {'csvFile':'csvFile.csv'} nipype-0.11.0/nipype/interfaces/slicer/quantification/tests/000077500000000000000000000000001257611314500241725ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/quantification/tests/test_auto_IntensityDifferenceMetric.py000066400000000000000000000030221257611314500337350ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.quantification.changequantification import IntensityDifferenceMetric def test_IntensityDifferenceMetric_inputs(): input_map = dict(args=dict(argstr='%s', ), baselineSegmentationVolume=dict(argstr='%s', position=-3, ), baselineVolume=dict(argstr='%s', position=-4, ), changingBandSize=dict(argstr='--changingBandSize %d', ), environ=dict(nohash=True, usedefault=True, ), followupVolume=dict(argstr='%s', position=-2, ), ignore_exception=dict(nohash=True, usedefault=True, ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), reportFileName=dict(argstr='--reportFileName %s', hash_files=False, ), sensitivityThreshold=dict(argstr='--sensitivityThreshold %f', ), terminal_output=dict(nohash=True, ), ) inputs = IntensityDifferenceMetric.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_IntensityDifferenceMetric_outputs(): output_map = dict(outputVolume=dict(position=-1, ), reportFileName=dict(), ) outputs = IntensityDifferenceMetric.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_PETStandardUptakeValueComputation.py000066400000000000000000000030631257611314500352610ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/quantification/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.quantification.petstandarduptakevaluecomputation import PETStandardUptakeValueComputation def test_PETStandardUptakeValueComputation_inputs(): input_map = dict(OutputLabel=dict(argstr='--OutputLabel %s', ), OutputLabelValue=dict(argstr='--OutputLabelValue %s', ), SUVMax=dict(argstr='--SUVMax %s', ), SUVMean=dict(argstr='--SUVMean %s', ), SUVMin=dict(argstr='--SUVMin %s', ), args=dict(argstr='%s', ), color=dict(argstr='--color %s', ), csvFile=dict(argstr='--csvFile %s', hash_files=False, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), labelMap=dict(argstr='--labelMap %s', ), petDICOMPath=dict(argstr='--petDICOMPath %s', ), petVolume=dict(argstr='--petVolume %s', ), terminal_output=dict(nohash=True, ), ) inputs = PETStandardUptakeValueComputation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PETStandardUptakeValueComputation_outputs(): output_map = dict(csvFile=dict(), ) outputs = PETStandardUptakeValueComputation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/000077500000000000000000000000001257611314500225245ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/registration/__init__.py000066400000000000000000000002511257611314500246330ustar00rootroot00000000000000from specialized import ACPCTransform, FiducialRegistration, VBRAINSDemonWarp, BRAINSDemonWarp from brainsresample import BRAINSResample from brainsfit import BRAINSFit nipype-0.11.0/nipype/interfaces/slicer/registration/brainsfit.py000066400000000000000000000456121257611314500250670ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSFitInputSpec(CommandLineInputSpec): fixedVolume = File(desc="The fixed image for registration by mutual information optimization.", exists=True, argstr="--fixedVolume %s") movingVolume = File(desc="The moving image for registration by mutual information optimization.", exists=True, argstr="--movingVolume %s") bsplineTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Filename to which save the estimated transform. NOTE: You must set at least one output object (either a deformed image or a transform. NOTE: USE THIS ONLY IF THE FINAL TRANSFORM IS BSpline", argstr="--bsplineTransform %s") linearTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Filename to which save the estimated transform. NOTE: You must set at least one output object (either a deformed image or a transform. NOTE: USE THIS ONLY IF THE FINAL TRANSFORM IS ---NOT--- BSpline", argstr="--linearTransform %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Output image for registration. NOTE: You must select either the outputTransform or the outputVolume option.", argstr="--outputVolume %s") initialTransform = File(desc="Filename of transform used to initialize the registration. This CAN NOT be used with either CenterOfHeadLAlign, MomentsAlign, GeometryAlign, or initialTransform file.", exists=True, argstr="--initialTransform %s") initializeTransformMode = traits.Enum("Off", "useMomentsAlign", "useCenterOfHeadAlign", "useGeometryAlign", "useCenterOfROIAlign", desc="Determine how to initialize the transform center. GeometryAlign on assumes that the center of the voxel lattice of the images represent similar structures. MomentsAlign assumes that the center of mass of the images represent similar structures. useCenterOfHeadAlign attempts to use the top of head and shape of neck to drive a center of mass estimate. Off assumes that the physical space of the images are close, and that centering in terms of the image Origins is a good starting point. This flag is mutually exclusive with the initialTransform flag.", argstr="--initializeTransformMode %s") useRigid = traits.Bool(desc="Perform a rigid registration as part of the sequential registration steps. This family of options superceeds the use of transformType if any of them are set.", argstr="--useRigid ") useScaleVersor3D = traits.Bool(desc="Perform a ScaleVersor3D registration as part of the sequential registration steps. This family of options superceeds the use of transformType if any of them are set.", argstr="--useScaleVersor3D ") useScaleSkewVersor3D = traits.Bool(desc="Perform a ScaleSkewVersor3D registration as part of the sequential registration steps. This family of options superceeds the use of transformType if any of them are set.", argstr="--useScaleSkewVersor3D ") useAffine = traits.Bool(desc="Perform an Affine registration as part of the sequential registration steps. This family of options superceeds the use of transformType if any of them are set.", argstr="--useAffine ") useBSpline = traits.Bool(desc="Perform a BSpline registration as part of the sequential registration steps. This family of options superceeds the use of transformType if any of them are set.", argstr="--useBSpline ") numberOfSamples = traits.Int(desc="The number of voxels sampled for mutual information computation. Increase this for a slower, more careful fit. You can also limit the sampling focus with ROI masks and ROIAUTO mask generation.", argstr="--numberOfSamples %d") splineGridSize = InputMultiPath(traits.Int, desc="The number of subdivisions of the BSpline Grid to be centered on the image space. Each dimension must have at least 3 subdivisions for the BSpline to be correctly computed. ", sep=",", argstr="--splineGridSize %s") numberOfIterations = InputMultiPath(traits.Int, desc="The maximum number of iterations to try before failing to converge. Use an explicit limit like 500 or 1000 to manage risk of divergence", sep=",", argstr="--numberOfIterations %s") maskProcessingMode = traits.Enum("NOMASK", "ROIAUTO", "ROI", desc="What mode to use for using the masks. If ROIAUTO is choosen, then the mask is implicitly defined using a otsu forground and hole filling algorithm. The Region Of Interest mode (choose ROI) uses the masks to define what parts of the image should be used for computing the transform.", argstr="--maskProcessingMode %s") fixedBinaryVolume = File(desc="Fixed Image binary mask volume, ONLY FOR MANUAL ROI mode.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Moving Image binary mask volume, ONLY FOR MANUAL ROI mode.", exists=True, argstr="--movingBinaryVolume %s") outputFixedVolumeROI = traits.Either(traits.Bool, File(), hash_files=False, desc="The ROI automatically found in fixed image, ONLY FOR ROIAUTO mode.", argstr="--outputFixedVolumeROI %s") outputMovingVolumeROI = traits.Either(traits.Bool, File(), hash_files=False, desc="The ROI automatically found in moving image, ONLY FOR ROIAUTO mode.", argstr="--outputMovingVolumeROI %s") outputVolumePixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", desc="The output image Pixel Type is the scalar datatype for representation of the Output Volume.", argstr="--outputVolumePixelType %s") backgroundFillValue = traits.Float(desc="Background fill value for output image.", argstr="--backgroundFillValue %f") maskInferiorCutOffFromCenter = traits.Float(desc="For use with --useCenterOfHeadAlign (and --maskProcessingMode ROIAUTO): the cut-off below the image centers, in millimeters, ", argstr="--maskInferiorCutOffFromCenter %f") scaleOutputValues = traits.Bool(desc="If true, and the voxel values do not fit within the minimum and maximum values of the desired outputVolumePixelType, then linearly scale the min/max output image voxel values to fit within the min/max range of the outputVolumePixelType.", argstr="--scaleOutputValues ") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, NearestNeighbor, BSpline, WindowedSinc, or ResampleInPlace. The ResampleInPlace option will create an image with the same discrete voxel values and will adjust the origin and direction of the physical space interpretation.", argstr="--interpolationMode %s") minimumStepLength = InputMultiPath(traits.Float, desc="Each step in the optimization takes steps at least this big. When none are possible, registration is complete.", sep=",", argstr="--minimumStepLength %s") translationScale = traits.Float(desc="How much to scale up changes in position compared to unit rotational changes in radians -- decrease this to put more rotation in the search pattern.", argstr="--translationScale %f") reproportionScale = traits.Float(desc="ScaleVersor3D 'Scale' compensation factor. Increase this to put more rescaling in a ScaleVersor3D or ScaleSkewVersor3D search pattern. 1.0 works well with a translationScale of 1000.0", argstr="--reproportionScale %f") skewScale = traits.Float(desc="ScaleSkewVersor3D Skew compensation factor. Increase this to put more skew in a ScaleSkewVersor3D search pattern. 1.0 works well with a translationScale of 1000.0", argstr="--skewScale %f") maxBSplineDisplacement = traits.Float(desc=" Sets the maximum allowed displacements in image physical coordinates for BSpline control grid along each axis. A value of 0.0 indicates that the problem should be unbounded. NOTE: This only constrains the BSpline portion, and does not limit the displacement from the associated bulk transform. This can lead to a substantial reduction in computation time in the BSpline optimizer., ", argstr="--maxBSplineDisplacement %f") histogramMatch = traits.Bool(desc="Histogram Match the input images. This is suitable for images of the same modality that may have different absolute scales, but the same overall intensity profile. Do NOT use if registering images from different modailties.", argstr="--histogramMatch ") numberOfHistogramBins = traits.Int(desc="The number of histogram levels", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="the number of match points", argstr="--numberOfMatchPoints %d") strippedOutputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="File name for the rigid component of the estimated affine transform. Can be used to rigidly register the moving image to the fixed image. NOTE: This value is overwritten if either bsplineTransform or linearTransform is set.", argstr="--strippedOutputTransform %s") transformType = InputMultiPath(traits.Str, desc="Specifies a list of registration types to be used. The valid types are, Rigid, ScaleVersor3D, ScaleSkewVersor3D, Affine, and BSpline. Specifiying more than one in a comma separated list will initialize the next stage with the previous results. If registrationClass flag is used, it overrides this parameter setting.", sep=",", argstr="--transformType %s") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="(optional) Filename to which save the (optional) estimated transform. NOTE: You must select either the outputTransform or the outputVolume option.", argstr="--outputTransform %s") fixedVolumeTimeIndex = traits.Int(desc="The index in the time series for the 3D fixed image to fit, if 4-dimensional.", argstr="--fixedVolumeTimeIndex %d") movingVolumeTimeIndex = traits.Int(desc="The index in the time series for the 3D moving image to fit, if 4-dimensional.", argstr="--movingVolumeTimeIndex %d") medianFilterSize = InputMultiPath(traits.Int, desc="The radius for the optional MedianImageFilter preprocessing in all 3 directions.", sep=",", argstr="--medianFilterSize %s") removeIntensityOutliers = traits.Float(desc="The half percentage to decide outliers of image intensities. The default value is zero, which means no outlier removal. If the value of 0.005 is given, the moduel will throw away 0.005 % of both tails, so 0.01% of intensities in total would be ignored in its statistic calculation. ", argstr="--removeIntensityOutliers %f") useCachingOfBSplineWeightsMode = traits.Enum("ON", "OFF", desc="This is a 5x speed advantage at the expense of requiring much more memory. Only relevant when transformType is BSpline.", argstr="--useCachingOfBSplineWeightsMode %s") useExplicitPDFDerivativesMode = traits.Enum("AUTO", "ON", "OFF", desc="Using mode AUTO means OFF for BSplineDeformableTransforms and ON for the linear transforms. The ON alternative uses more memory to sometimes do a better job.", argstr="--useExplicitPDFDerivativesMode %s") ROIAutoDilateSize = traits.Float(desc="This flag is only relavent when using ROIAUTO mode for initializing masks. It defines the final dilation size to capture a bit of background outside the tissue region. At setting of 10mm has been shown to help regularize a BSpline registration type so that there is some background constraints to match the edges of the head better.", argstr="--ROIAutoDilateSize %f") ROIAutoClosingSize = traits.Float(desc="This flag is only relavent when using ROIAUTO mode for initializing masks. It defines the hole closing size in mm. It is rounded up to the nearest whole pixel size in each direction. The default is to use a closing size of 9mm. For mouse data this value may need to be reset to 0.9 or smaller.", argstr="--ROIAutoClosingSize %f") relaxationFactor = traits.Float(desc="Internal debugging parameter, and should probably never be used from the command line. This will be removed in the future.", argstr="--relaxationFactor %f") maximumStepLength = traits.Float(desc="Internal debugging parameter, and should probably never be used from the command line. This will be removed in the future.", argstr="--maximumStepLength %f") failureExitCode = traits.Int(desc="If the fit fails, exit with this status code. (It can be used to force a successfult exit status of (0) if the registration fails due to reaching the maximum number of iterations.", argstr="--failureExitCode %d") writeTransformOnFailure = traits.Bool(desc="Flag to save the final transform even if the numberOfIterations are reached without convergence. (Intended for use when --failureExitCode 0 )", argstr="--writeTransformOnFailure ") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use. (default is auto-detected)", argstr="--numberOfThreads %d") forceMINumberOfThreads = traits.Int(desc="Force the the maximum number of threads to use for non thread safe MI metric. CAUTION: Inconsistent results my arise!", argstr="--forceMINumberOfThreads %d") debugLevel = traits.Int(desc="Display debug messages, and produce debug intermediate results. 0=OFF, 1=Minimal, 10=Maximum debugging.", argstr="--debugLevel %d") costFunctionConvergenceFactor = traits.Float(desc=" From itkLBFGSBOptimizer.h: Set/Get the CostFunctionConvergenceFactor. Algorithm terminates when the reduction in cost function is less than (factor * epsmcj) where epsmch is the machine precision. Typical values for factor: 1e+12 for low accuracy; 1e+7 for moderate accuracy and 1e+1 for extremely high accuracy. 1e+9 seems to work well., ", argstr="--costFunctionConvergenceFactor %f") projectedGradientTolerance = traits.Float(desc=" From itkLBFGSBOptimizer.h: Set/Get the ProjectedGradientTolerance. Algorithm terminates when the project gradient is below the tolerance. Default lbfgsb value is 1e-5, but 1e-4 seems to work well., ", argstr="--projectedGradientTolerance %f") gui = traits.Bool(desc="Display intermediate image volumes for debugging. NOTE: This is not part of the standard build sytem, and probably does nothing on your installation.", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_00 = traits.Bool(desc="DO NOT USE THIS FLAG", argstr="--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_00 ") NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_01 = traits.Bool(desc="DO NOT USE THIS FLAG", argstr="--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_01 ") NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_02 = traits.Bool(desc="DO NOT USE THIS FLAG", argstr="--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_02 ") permitParameterVariation = InputMultiPath(traits.Int, desc="A bit vector to permit linear transform parameters to vary under optimization. The vector order corresponds with transform parameters, and beyond the end ones fill in as a default. For instance, you can choose to rotate only in x (pitch) with 1,0,0; this is mostly for expert use in turning on and off individual degrees of freedom in rotation, translation or scaling without multiplying the number of transform representations; this trick is probably meaningless when tried with the general affine transform.", sep=",", argstr="--permitParameterVariation %s") costMetric = traits.Enum("MMI", "MSE", "NC", "MC", desc="The cost metric to be used during fitting. Defaults to MMI. Options are MMI (Mattes Mutual Information), MSE (Mean Square Error), NC (Normalized Correlation), MC (Match Cardinality for binary images)", argstr="--costMetric %s") writeOutputTransformInFloat = traits.Bool(desc="By default, the output registration transforms (either the output composite transform or each transform component) are written to the disk in double precision. If this flag is ON, the output transforms will be written in single (float) precision. It is especially important if the output transform is a displacement field transform, or it is a composite transform that includes several displacement fields.", argstr="--writeOutputTransformInFloat ") class BRAINSFitOutputSpec(TraitedSpec): bsplineTransform = File(desc="(optional) Filename to which save the estimated transform. NOTE: You must set at least one output object (either a deformed image or a transform. NOTE: USE THIS ONLY IF THE FINAL TRANSFORM IS BSpline", exists=True) linearTransform = File(desc="(optional) Filename to which save the estimated transform. NOTE: You must set at least one output object (either a deformed image or a transform. NOTE: USE THIS ONLY IF THE FINAL TRANSFORM IS ---NOT--- BSpline", exists=True) outputVolume = File(desc="(optional) Output image for registration. NOTE: You must select either the outputTransform or the outputVolume option.", exists=True) outputFixedVolumeROI = File(desc="The ROI automatically found in fixed image, ONLY FOR ROIAUTO mode.", exists=True) outputMovingVolumeROI = File(desc="The ROI automatically found in moving image, ONLY FOR ROIAUTO mode.", exists=True) strippedOutputTransform = File(desc="File name for the rigid component of the estimated affine transform. Can be used to rigidly register the moving image to the fixed image. NOTE: This value is overwritten if either bsplineTransform or linearTransform is set.", exists=True) outputTransform = File(desc="(optional) Filename to which save the (optional) estimated transform. NOTE: You must select either the outputTransform or the outputVolume option.", exists=True) class BRAINSFit(SEMLikeCommandLine): """title: General Registration (BRAINS) category: Registration description: Register a three-dimensional volume to a reference volume (Mattes Mutual Information by default). Described in BRAINSFit: Mutual Information Registrations of Whole-Brain 3D Images, Using the Insight Toolkit, Johnson H.J., Harris G., Williams K., The Insight Journal, 2007. http://hdl.handle.net/1926/1291 version: 3.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:BRAINSFit license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson, hans-johnson -at- uiowa.edu, http://wwww.psychiatry.uiowa.edu acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); Gregory Harris(1), Vincent Magnotta(1,2,3); Andriy Fedorov(5) 1=University of Iowa Department of Psychiatry, 2=University of Iowa Department of Radiology, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering, 5=Surgical Planning Lab, Harvard """ input_spec = BRAINSFitInputSpec output_spec = BRAINSFitOutputSpec _cmd = "BRAINSFit " _outputs_filenames = {'outputVolume':'outputVolume.nii','bsplineTransform':'bsplineTransform.mat','outputTransform':'outputTransform.mat','outputFixedVolumeROI':'outputFixedVolumeROI.nii','strippedOutputTransform':'strippedOutputTransform.mat','outputMovingVolumeROI':'outputMovingVolumeROI.nii','linearTransform':'linearTransform.mat'} nipype-0.11.0/nipype/interfaces/slicer/registration/brainsresample.py000066400000000000000000000071421257611314500261110ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class BRAINSResampleInputSpec(CommandLineInputSpec): inputVolume = File(desc="Image To Warp", exists=True, argstr="--inputVolume %s") referenceVolume = File(desc="Reference image used only to define the output space. If not specified, the warping is done in the same space as the image to warp.", exists=True, argstr="--referenceVolume %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Resulting deformed image", argstr="--outputVolume %s") pixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", "binary", desc="Specifies the pixel type for the input/output images. The \'binary\' pixel type uses a modified algorithm whereby the image is read in as unsigned char, a signed distance map is created, signed distance map is resampled, and then a thresholded image of type unsigned char is written to disk.", argstr="--pixelType %s") deformationVolume = File(desc="Displacement Field to be used to warp the image", exists=True, argstr="--deformationVolume %s") warpTransform = File(desc="Filename for the BRAINSFit transform used in place of the deformation field", exists=True, argstr="--warpTransform %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") inverseTransform = traits.Bool(desc="True/False is to compute inverse of given transformation. Default is false", argstr="--inverseTransform ") defaultValue = traits.Float(desc="Default voxel value", argstr="--defaultValue %f") gridSpacing = InputMultiPath(traits.Int, desc="Add warped grid to output image to help show the deformation that occured with specified spacing. A spacing of 0 in a dimension indicates that grid lines should be rendered to fall exactly (i.e. do not allow displacements off that plane). This is useful for makeing a 2D image of grid lines from the 3D space ", sep=",", argstr="--gridSpacing %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSResampleOutputSpec(TraitedSpec): outputVolume = File(desc="Resulting deformed image", exists=True) class BRAINSResample(SEMLikeCommandLine): """title: Resample Image (BRAINS) category: Registration description: This program resamples an image image using a deformation field or a transform (BSpline, Affine, Rigid, etc.). version: 3.0.0 documentation-url: http://www.slicer.org/slicerWiki/index.php/Modules:BRAINSResample license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Vincent Magnotta, Greg Harris, and Hans Johnson. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = BRAINSResampleInputSpec output_spec = BRAINSResampleOutputSpec _cmd = "BRAINSResample " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/registration/specialized.py000066400000000000000000000534671257611314500254110ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class ACPCTransformInputSpec(CommandLineInputSpec): acpc = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="ACPC line, two fiducial points, one at the anterior commissure and one at the posterior commissure.", argstr="--acpc %s...") midline = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="The midline is a series of points defining the division between the hemispheres of the brain (the mid sagittal plane).", argstr="--midline %s...") outputTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="A transform filled in from the ACPC and Midline registration calculation", argstr="--outputTransform %s") debugSwitch = traits.Bool(desc="Click if wish to see debugging output", argstr="--debugSwitch ") class ACPCTransformOutputSpec(TraitedSpec): outputTransform = File(desc="A transform filled in from the ACPC and Midline registration calculation", exists=True) class ACPCTransform(SEMLikeCommandLine): """title: ACPC Transform category: Registration.Specialized description:

Calculate a transformation from two lists of fiducial points.

ACPC line is two fiducial points, one at the anterior commissure and one at the posterior commissure. The resulting transform will bring the line connecting them to horizontal to the AP axis.

The midline is a series of points defining the division between the hemispheres of the brain (the mid sagittal plane). The resulting transform will put the output volume with the mid sagittal plane lined up with the AS plane.

Use the Filtering moduleResample Scalar/Vector/DWI Volumeto apply the transformation to a volume.

version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ACPCTransform license: slicer3 contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ACPCTransformInputSpec output_spec = ACPCTransformOutputSpec _cmd = "ACPCTransform " _outputs_filenames = {'outputTransform':'outputTransform.mat'} class FiducialRegistrationInputSpec(CommandLineInputSpec): fixedLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the fixed image", argstr="--fixedLandmarks %s...") movingLandmarks = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Ordered list of landmarks in the moving image", argstr="--movingLandmarks %s...") saveTransform = traits.Either(traits.Bool, File(), hash_files=False, desc="Save the transform that results from registration", argstr="--saveTransform %s") transformType = traits.Enum("Translation", "Rigid", "Similarity", desc="Type of transform to produce", argstr="--transformType %s") rms = traits.Float(desc="Display RMS Error.", argstr="--rms %f") outputMessage = traits.Str(desc="Provides more information on the output", argstr="--outputMessage %s") class FiducialRegistrationOutputSpec(TraitedSpec): saveTransform = File(desc="Save the transform that results from registration", exists=True) class FiducialRegistration(SEMLikeCommandLine): """title: Fiducial Registration category: Registration.Specialized description: Computes a rigid, similarity or affine transform from a matched list of fiducials version: 0.1.0.$Revision$ documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/TransformFromFiducials contributor: Casey B Goodlett (Kitware), Dominik Meier (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = FiducialRegistrationInputSpec output_spec = FiducialRegistrationOutputSpec _cmd = "FiducialRegistration " _outputs_filenames = {'saveTransform':'saveTransform.txt'} class VBRAINSDemonWarpInputSpec(CommandLineInputSpec): movingVolume = InputMultiPath(File(exists=True), desc="Required: input moving image", argstr="--movingVolume %s...") fixedVolume = InputMultiPath(File(exists=True), desc="Required: input fixed (target) image", argstr="--fixedVolume %s...") inputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="Input volumes will be typecast to this format: float|short|ushort|int|uchar", argstr="--inputPixelType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", argstr="--outputVolume %s") outputDisplacementFieldVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", argstr="--outputDisplacementFieldVolume %s") outputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="outputVolume will be typecast to this format: float|short|ushort|int|uchar", argstr="--outputPixelType %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") registrationFilterType = traits.Enum("Demons", "FastSymmetricForces", "Diffeomorphic", "LogDemons", "SymmetricLogDemons", desc="Registration Filter Type: Demons|FastSymmetricForces|Diffeomorphic|LogDemons|SymmetricLogDemons", argstr="--registrationFilterType %s") smoothDisplacementFieldSigma = traits.Float(desc="A gaussian smoothing value to be applied to the deformation feild at each iteration.", argstr="--smoothDisplacementFieldSigma %f") numberOfPyramidLevels = traits.Int(desc="Number of image pyramid levels to use in the multi-resolution registration.", argstr="--numberOfPyramidLevels %d") minimumFixedPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the fixed image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumFixedPyramid %s") minimumMovingPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the moving image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumMovingPyramid %s") arrayOfPyramidLevelIterations = InputMultiPath(traits.Int, desc="The number of iterations for each pyramid level", sep=",", argstr="--arrayOfPyramidLevelIterations %s") histogramMatch = traits.Bool(desc="Histogram Match the input images. This is suitable for images of the same modality that may have different absolute scales, but the same overall intensity profile.", argstr="--histogramMatch ") numberOfHistogramBins = traits.Int(desc="The number of histogram levels", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="The number of match points for histrogramMatch", argstr="--numberOfMatchPoints %d") medianFilterSize = InputMultiPath(traits.Int, desc="Median filter radius in all 3 directions. When images have a lot of salt and pepper noise, this step can improve the registration.", sep=",", argstr="--medianFilterSize %s") initializeWithDisplacementField = File(desc="Initial deformation field vector image file name", exists=True, argstr="--initializeWithDisplacementField %s") initializeWithTransform = File(desc="Initial Transform filename", exists=True, argstr="--initializeWithTransform %s") makeBOBF = traits.Bool(desc="Flag to make Brain-Only Background-Filled versions of the input and target volumes.", argstr="--makeBOBF ") fixedBinaryVolume = File(desc="Mask filename for desired region of interest in the Fixed image.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Mask filename for desired region of interest in the Moving image.", exists=True, argstr="--movingBinaryVolume %s") lowerThresholdForBOBF = traits.Int(desc="Lower threshold for performing BOBF", argstr="--lowerThresholdForBOBF %d") upperThresholdForBOBF = traits.Int(desc="Upper threshold for performing BOBF", argstr="--upperThresholdForBOBF %d") backgroundFillValue = traits.Int(desc="Replacement value to overwrite background when performing BOBF", argstr="--backgroundFillValue %d") seedForBOBF = InputMultiPath(traits.Int, desc="coordinates in all 3 directions for Seed when performing BOBF", sep=",", argstr="--seedForBOBF %s") neighborhoodForBOBF = InputMultiPath(traits.Int, desc="neighborhood in all 3 directions to be included when performing BOBF", sep=",", argstr="--neighborhoodForBOBF %s") outputDisplacementFieldPrefix = traits.Str(desc="Displacement field filename prefix for writing separate x, y, and z component images", argstr="--outputDisplacementFieldPrefix %s") outputCheckerboardVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", argstr="--outputCheckerboardVolume %s") checkerboardPatternSubdivisions = InputMultiPath(traits.Int, desc="Number of Checkerboard subdivisions in all 3 directions", sep=",", argstr="--checkerboardPatternSubdivisions %s") outputNormalized = traits.Bool(desc="Flag to warp and write the normalized images to output. In normalized images the image values are fit-scaled to be between 0 and the maximum storage type value.", argstr="--outputNormalized ") outputDebug = traits.Bool(desc="Flag to write debugging images after each step.", argstr="--outputDebug ") weightFactors = InputMultiPath(traits.Float, desc="Weight fatctors for each input images", sep=",", argstr="--weightFactors %s") gradient_type = traits.Enum("0", "1", "2", desc="Type of gradient used for computing the demons force (0 is symmetrized, 1 is fixed image, 2 is moving image)", argstr="--gradient_type %s") upFieldSmoothing = traits.Float(desc="Smoothing sigma for the update field at each iteration", argstr="--upFieldSmoothing %f") max_step_length = traits.Float(desc="Maximum length of an update vector (0: no restriction)", argstr="--max_step_length %f") use_vanilla_dem = traits.Bool(desc="Run vanilla demons algorithm", argstr="--use_vanilla_dem ") gui = traits.Bool(desc="Display intermediate image volumes for debugging", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") numberOfBCHApproximationTerms = traits.Int(desc="Number of terms in the BCH expansion", argstr="--numberOfBCHApproximationTerms %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class VBRAINSDemonWarpOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", exists=True) outputDisplacementFieldVolume = File(desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", exists=True) outputCheckerboardVolume = File(desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", exists=True) class VBRAINSDemonWarp(SEMLikeCommandLine): """title: Vector Demon Registration (BRAINS) category: Registration.Specialized description: This program finds a deformation field to warp a moving image onto a fixed image. The images must be of the same signal kind, and contain an image of the same kind of object. This program uses the Thirion Demons warp software in ITK, the Insight Toolkit. Additional information is available at: http://www.nitrc.org/projects/brainsdemonwarp. version: 3.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:BRAINSDemonWarp license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Hans J. Johnson and Greg Harris. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = VBRAINSDemonWarpInputSpec output_spec = VBRAINSDemonWarpOutputSpec _cmd = "VBRAINSDemonWarp " _outputs_filenames = {'outputVolume':'outputVolume.nii','outputCheckerboardVolume':'outputCheckerboardVolume.nii','outputDisplacementFieldVolume':'outputDisplacementFieldVolume.nrrd'} class BRAINSDemonWarpInputSpec(CommandLineInputSpec): movingVolume = File(desc="Required: input moving image", exists=True, argstr="--movingVolume %s") fixedVolume = File(desc="Required: input fixed (target) image", exists=True, argstr="--fixedVolume %s") inputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="Input volumes will be typecast to this format: float|short|ushort|int|uchar", argstr="--inputPixelType %s") outputVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", argstr="--outputVolume %s") outputDisplacementFieldVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", argstr="--outputDisplacementFieldVolume %s") outputPixelType = traits.Enum("float", "short", "ushort", "int", "uchar", desc="outputVolume will be typecast to this format: float|short|ushort|int|uchar", argstr="--outputPixelType %s") interpolationMode = traits.Enum("NearestNeighbor", "Linear", "ResampleInPlace", "BSpline", "WindowedSinc", "Hamming", "Cosine", "Welch", "Lanczos", "Blackman", desc="Type of interpolation to be used when applying transform to moving volume. Options are Linear, ResampleInPlace, NearestNeighbor, BSpline, or WindowedSinc", argstr="--interpolationMode %s") registrationFilterType = traits.Enum("Demons", "FastSymmetricForces", "Diffeomorphic", desc="Registration Filter Type: Demons|FastSymmetricForces|Diffeomorphic", argstr="--registrationFilterType %s") smoothDisplacementFieldSigma = traits.Float(desc="A gaussian smoothing value to be applied to the deformation feild at each iteration.", argstr="--smoothDisplacementFieldSigma %f") numberOfPyramidLevels = traits.Int(desc="Number of image pyramid levels to use in the multi-resolution registration.", argstr="--numberOfPyramidLevels %d") minimumFixedPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the fixed image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumFixedPyramid %s") minimumMovingPyramid = InputMultiPath(traits.Int, desc="The shrink factor for the first level of the moving image pyramid. (i.e. start at 1/16 scale, then 1/8, then 1/4, then 1/2, and finally full scale)", sep=",", argstr="--minimumMovingPyramid %s") arrayOfPyramidLevelIterations = InputMultiPath(traits.Int, desc="The number of iterations for each pyramid level", sep=",", argstr="--arrayOfPyramidLevelIterations %s") histogramMatch = traits.Bool(desc="Histogram Match the input images. This is suitable for images of the same modality that may have different absolute scales, but the same overall intensity profile.", argstr="--histogramMatch ") numberOfHistogramBins = traits.Int(desc="The number of histogram levels", argstr="--numberOfHistogramBins %d") numberOfMatchPoints = traits.Int(desc="The number of match points for histrogramMatch", argstr="--numberOfMatchPoints %d") medianFilterSize = InputMultiPath(traits.Int, desc="Median filter radius in all 3 directions. When images have a lot of salt and pepper noise, this step can improve the registration.", sep=",", argstr="--medianFilterSize %s") initializeWithDisplacementField = File(desc="Initial deformation field vector image file name", exists=True, argstr="--initializeWithDisplacementField %s") initializeWithTransform = File(desc="Initial Transform filename", exists=True, argstr="--initializeWithTransform %s") maskProcessingMode = traits.Enum("NOMASK", "ROIAUTO", "ROI", "BOBF", desc="What mode to use for using the masks: NOMASK|ROIAUTO|ROI|BOBF. If ROIAUTO is choosen, then the mask is implicitly defined using a otsu forground and hole filling algorithm. Where the Region Of Interest mode uses the masks to define what parts of the image should be used for computing the deformation field. Brain Only Background Fill uses the masks to pre-process the input images by clipping and filling in the background with a predefined value.", argstr="--maskProcessingMode %s") fixedBinaryVolume = File(desc="Mask filename for desired region of interest in the Fixed image.", exists=True, argstr="--fixedBinaryVolume %s") movingBinaryVolume = File(desc="Mask filename for desired region of interest in the Moving image.", exists=True, argstr="--movingBinaryVolume %s") lowerThresholdForBOBF = traits.Int(desc="Lower threshold for performing BOBF", argstr="--lowerThresholdForBOBF %d") upperThresholdForBOBF = traits.Int(desc="Upper threshold for performing BOBF", argstr="--upperThresholdForBOBF %d") backgroundFillValue = traits.Int(desc="Replacement value to overwrite background when performing BOBF", argstr="--backgroundFillValue %d") seedForBOBF = InputMultiPath(traits.Int, desc="coordinates in all 3 directions for Seed when performing BOBF", sep=",", argstr="--seedForBOBF %s") neighborhoodForBOBF = InputMultiPath(traits.Int, desc="neighborhood in all 3 directions to be included when performing BOBF", sep=",", argstr="--neighborhoodForBOBF %s") outputDisplacementFieldPrefix = traits.Str(desc="Displacement field filename prefix for writing separate x, y, and z component images", argstr="--outputDisplacementFieldPrefix %s") outputCheckerboardVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", argstr="--outputCheckerboardVolume %s") checkerboardPatternSubdivisions = InputMultiPath(traits.Int, desc="Number of Checkerboard subdivisions in all 3 directions", sep=",", argstr="--checkerboardPatternSubdivisions %s") outputNormalized = traits.Bool(desc="Flag to warp and write the normalized images to output. In normalized images the image values are fit-scaled to be between 0 and the maximum storage type value.", argstr="--outputNormalized ") outputDebug = traits.Bool(desc="Flag to write debugging images after each step.", argstr="--outputDebug ") gradient_type = traits.Enum("0", "1", "2", desc="Type of gradient used for computing the demons force (0 is symmetrized, 1 is fixed image, 2 is moving image)", argstr="--gradient_type %s") upFieldSmoothing = traits.Float(desc="Smoothing sigma for the update field at each iteration", argstr="--upFieldSmoothing %f") max_step_length = traits.Float(desc="Maximum length of an update vector (0: no restriction)", argstr="--max_step_length %f") use_vanilla_dem = traits.Bool(desc="Run vanilla demons algorithm", argstr="--use_vanilla_dem ") gui = traits.Bool(desc="Display intermediate image volumes for debugging", argstr="--gui ") promptUser = traits.Bool(desc="Prompt the user to hit enter each time an image is sent to the DebugImageViewer", argstr="--promptUser ") numberOfBCHApproximationTerms = traits.Int(desc="Number of terms in the BCH expansion", argstr="--numberOfBCHApproximationTerms %d") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSDemonWarpOutputSpec(TraitedSpec): outputVolume = File(desc="Required: output resampled moving image (will have the same physical space as the fixedVolume).", exists=True) outputDisplacementFieldVolume = File(desc="Output deformation field vector image (will have the same physical space as the fixedVolume).", exists=True) outputCheckerboardVolume = File(desc="Genete a checkerboard image volume between the fixedVolume and the deformed movingVolume.", exists=True) class BRAINSDemonWarp(SEMLikeCommandLine): """title: Demon Registration (BRAINS) category: Registration.Specialized description: This program finds a deformation field to warp a moving image onto a fixed image. The images must be of the same signal kind, and contain an image of the same kind of object. This program uses the Thirion Demons warp software in ITK, the Insight Toolkit. Additional information is available at: http://www.nitrc.org/projects/brainsdemonwarp. version: 3.0.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Modules:BRAINSDemonWarp license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: This tool was developed by Hans J. Johnson and Greg Harris. acknowledgements: The development of this tool was supported by funding from grants NS050568 and NS40068 from the National Institute of Neurological Disorders and Stroke and grants MH31593, MH40856, from the National Institute of Mental Health. """ input_spec = BRAINSDemonWarpInputSpec output_spec = BRAINSDemonWarpOutputSpec _cmd = "BRAINSDemonWarp " _outputs_filenames = {'outputVolume':'outputVolume.nii','outputCheckerboardVolume':'outputCheckerboardVolume.nii','outputDisplacementFieldVolume':'outputDisplacementFieldVolume.nrrd'} nipype-0.11.0/nipype/interfaces/slicer/registration/tests/000077500000000000000000000000001257611314500236665ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_ACPCTransform.py000066400000000000000000000022311257611314500307270ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.specialized import ACPCTransform def test_ACPCTransform_inputs(): input_map = dict(acpc=dict(argstr='--acpc %s...', ), args=dict(argstr='%s', ), debugSwitch=dict(argstr='--debugSwitch ', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), midline=dict(argstr='--midline %s...', ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), ) inputs = ACPCTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ACPCTransform_outputs(): output_map = dict(outputTransform=dict(), ) outputs = ACPCTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_BRAINSDemonWarp.py000066400000000000000000000076201257611314500311270ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.specialized import BRAINSDemonWarp def test_BRAINSDemonWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), arrayOfPyramidLevelIterations=dict(argstr='--arrayOfPyramidLevelIterations %s', sep=',', ), backgroundFillValue=dict(argstr='--backgroundFillValue %d', ), checkerboardPatternSubdivisions=dict(argstr='--checkerboardPatternSubdivisions %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s', ), gradient_type=dict(argstr='--gradient_type %s', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initializeWithDisplacementField=dict(argstr='--initializeWithDisplacementField %s', ), initializeWithTransform=dict(argstr='--initializeWithTransform %s', ), inputPixelType=dict(argstr='--inputPixelType %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), lowerThresholdForBOBF=dict(argstr='--lowerThresholdForBOBF %d', ), maskProcessingMode=dict(argstr='--maskProcessingMode %s', ), max_step_length=dict(argstr='--max_step_length %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), minimumFixedPyramid=dict(argstr='--minimumFixedPyramid %s', sep=',', ), minimumMovingPyramid=dict(argstr='--minimumMovingPyramid %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s', ), neighborhoodForBOBF=dict(argstr='--neighborhoodForBOBF %s', sep=',', ), numberOfBCHApproximationTerms=dict(argstr='--numberOfBCHApproximationTerms %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfPyramidLevels=dict(argstr='--numberOfPyramidLevels %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputCheckerboardVolume=dict(argstr='--outputCheckerboardVolume %s', hash_files=False, ), outputDebug=dict(argstr='--outputDebug ', ), outputDisplacementFieldPrefix=dict(argstr='--outputDisplacementFieldPrefix %s', ), outputDisplacementFieldVolume=dict(argstr='--outputDisplacementFieldVolume %s', hash_files=False, ), outputNormalized=dict(argstr='--outputNormalized ', ), outputPixelType=dict(argstr='--outputPixelType %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), promptUser=dict(argstr='--promptUser ', ), registrationFilterType=dict(argstr='--registrationFilterType %s', ), seedForBOBF=dict(argstr='--seedForBOBF %s', sep=',', ), smoothDisplacementFieldSigma=dict(argstr='--smoothDisplacementFieldSigma %f', ), terminal_output=dict(nohash=True, ), upFieldSmoothing=dict(argstr='--upFieldSmoothing %f', ), upperThresholdForBOBF=dict(argstr='--upperThresholdForBOBF %d', ), use_vanilla_dem=dict(argstr='--use_vanilla_dem ', ), ) inputs = BRAINSDemonWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSDemonWarp_outputs(): output_map = dict(outputCheckerboardVolume=dict(), outputDisplacementFieldVolume=dict(), outputVolume=dict(), ) outputs = BRAINSDemonWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_BRAINSFit.py000066400000000000000000000127171257611314500277600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.brainsfit import BRAINSFit def test_BRAINSFit_inputs(): input_map = dict(NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_00=dict(argstr='--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_00 ', ), NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_01=dict(argstr='--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_01 ', ), NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_02=dict(argstr='--NEVER_USE_THIS_FLAG_IT_IS_OUTDATED_02 ', ), ROIAutoClosingSize=dict(argstr='--ROIAutoClosingSize %f', ), ROIAutoDilateSize=dict(argstr='--ROIAutoDilateSize %f', ), args=dict(argstr='%s', ), backgroundFillValue=dict(argstr='--backgroundFillValue %f', ), bsplineTransform=dict(argstr='--bsplineTransform %s', hash_files=False, ), costFunctionConvergenceFactor=dict(argstr='--costFunctionConvergenceFactor %f', ), costMetric=dict(argstr='--costMetric %s', ), debugLevel=dict(argstr='--debugLevel %d', ), environ=dict(nohash=True, usedefault=True, ), failureExitCode=dict(argstr='--failureExitCode %d', ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s', ), fixedVolumeTimeIndex=dict(argstr='--fixedVolumeTimeIndex %d', ), forceMINumberOfThreads=dict(argstr='--forceMINumberOfThreads %d', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initialTransform=dict(argstr='--initialTransform %s', ), initializeTransformMode=dict(argstr='--initializeTransformMode %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), linearTransform=dict(argstr='--linearTransform %s', hash_files=False, ), maskInferiorCutOffFromCenter=dict(argstr='--maskInferiorCutOffFromCenter %f', ), maskProcessingMode=dict(argstr='--maskProcessingMode %s', ), maxBSplineDisplacement=dict(argstr='--maxBSplineDisplacement %f', ), maximumStepLength=dict(argstr='--maximumStepLength %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), minimumStepLength=dict(argstr='--minimumStepLength %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s', ), movingVolumeTimeIndex=dict(argstr='--movingVolumeTimeIndex %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfIterations=dict(argstr='--numberOfIterations %s', sep=',', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfSamples=dict(argstr='--numberOfSamples %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputFixedVolumeROI=dict(argstr='--outputFixedVolumeROI %s', hash_files=False, ), outputMovingVolumeROI=dict(argstr='--outputMovingVolumeROI %s', hash_files=False, ), outputTransform=dict(argstr='--outputTransform %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), outputVolumePixelType=dict(argstr='--outputVolumePixelType %s', ), permitParameterVariation=dict(argstr='--permitParameterVariation %s', sep=',', ), projectedGradientTolerance=dict(argstr='--projectedGradientTolerance %f', ), promptUser=dict(argstr='--promptUser ', ), relaxationFactor=dict(argstr='--relaxationFactor %f', ), removeIntensityOutliers=dict(argstr='--removeIntensityOutliers %f', ), reproportionScale=dict(argstr='--reproportionScale %f', ), scaleOutputValues=dict(argstr='--scaleOutputValues ', ), skewScale=dict(argstr='--skewScale %f', ), splineGridSize=dict(argstr='--splineGridSize %s', sep=',', ), strippedOutputTransform=dict(argstr='--strippedOutputTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', sep=',', ), translationScale=dict(argstr='--translationScale %f', ), useAffine=dict(argstr='--useAffine ', ), useBSpline=dict(argstr='--useBSpline ', ), useCachingOfBSplineWeightsMode=dict(argstr='--useCachingOfBSplineWeightsMode %s', ), useExplicitPDFDerivativesMode=dict(argstr='--useExplicitPDFDerivativesMode %s', ), useRigid=dict(argstr='--useRigid ', ), useScaleSkewVersor3D=dict(argstr='--useScaleSkewVersor3D ', ), useScaleVersor3D=dict(argstr='--useScaleVersor3D ', ), writeOutputTransformInFloat=dict(argstr='--writeOutputTransformInFloat ', ), writeTransformOnFailure=dict(argstr='--writeTransformOnFailure ', ), ) inputs = BRAINSFit.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSFit_outputs(): output_map = dict(bsplineTransform=dict(), linearTransform=dict(), outputFixedVolumeROI=dict(), outputMovingVolumeROI=dict(), outputTransform=dict(), outputVolume=dict(), strippedOutputTransform=dict(), ) outputs = BRAINSFit.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_BRAINSResample.py000066400000000000000000000031521257611314500307770ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.brainsresample import BRAINSResample def test_BRAINSResample_inputs(): input_map = dict(args=dict(argstr='%s', ), defaultValue=dict(argstr='--defaultValue %f', ), deformationVolume=dict(argstr='--deformationVolume %s', ), environ=dict(nohash=True, usedefault=True, ), gridSpacing=dict(argstr='--gridSpacing %s', sep=',', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), inverseTransform=dict(argstr='--inverseTransform ', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), pixelType=dict(argstr='--pixelType %s', ), referenceVolume=dict(argstr='--referenceVolume %s', ), terminal_output=dict(nohash=True, ), warpTransform=dict(argstr='--warpTransform %s', ), ) inputs = BRAINSResample.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSResample_outputs(): output_map = dict(outputVolume=dict(), ) outputs = BRAINSResample.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_FiducialRegistration.py000066400000000000000000000025021257611314500324410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.specialized import FiducialRegistration def test_FiducialRegistration_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fixedLandmarks=dict(argstr='--fixedLandmarks %s...', ), ignore_exception=dict(nohash=True, usedefault=True, ), movingLandmarks=dict(argstr='--movingLandmarks %s...', ), outputMessage=dict(argstr='--outputMessage %s', ), rms=dict(argstr='--rms %f', ), saveTransform=dict(argstr='--saveTransform %s', hash_files=False, ), terminal_output=dict(nohash=True, ), transformType=dict(argstr='--transformType %s', ), ) inputs = FiducialRegistration.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FiducialRegistration_outputs(): output_map = dict(saveTransform=dict(), ) outputs = FiducialRegistration.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/registration/tests/test_auto_VBRAINSDemonWarp.py000066400000000000000000000077151257611314500312620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.registration.specialized import VBRAINSDemonWarp def test_VBRAINSDemonWarp_inputs(): input_map = dict(args=dict(argstr='%s', ), arrayOfPyramidLevelIterations=dict(argstr='--arrayOfPyramidLevelIterations %s', sep=',', ), backgroundFillValue=dict(argstr='--backgroundFillValue %d', ), checkerboardPatternSubdivisions=dict(argstr='--checkerboardPatternSubdivisions %s', sep=',', ), environ=dict(nohash=True, usedefault=True, ), fixedBinaryVolume=dict(argstr='--fixedBinaryVolume %s', ), fixedVolume=dict(argstr='--fixedVolume %s...', ), gradient_type=dict(argstr='--gradient_type %s', ), gui=dict(argstr='--gui ', ), histogramMatch=dict(argstr='--histogramMatch ', ), ignore_exception=dict(nohash=True, usedefault=True, ), initializeWithDisplacementField=dict(argstr='--initializeWithDisplacementField %s', ), initializeWithTransform=dict(argstr='--initializeWithTransform %s', ), inputPixelType=dict(argstr='--inputPixelType %s', ), interpolationMode=dict(argstr='--interpolationMode %s', ), lowerThresholdForBOBF=dict(argstr='--lowerThresholdForBOBF %d', ), makeBOBF=dict(argstr='--makeBOBF ', ), max_step_length=dict(argstr='--max_step_length %f', ), medianFilterSize=dict(argstr='--medianFilterSize %s', sep=',', ), minimumFixedPyramid=dict(argstr='--minimumFixedPyramid %s', sep=',', ), minimumMovingPyramid=dict(argstr='--minimumMovingPyramid %s', sep=',', ), movingBinaryVolume=dict(argstr='--movingBinaryVolume %s', ), movingVolume=dict(argstr='--movingVolume %s...', ), neighborhoodForBOBF=dict(argstr='--neighborhoodForBOBF %s', sep=',', ), numberOfBCHApproximationTerms=dict(argstr='--numberOfBCHApproximationTerms %d', ), numberOfHistogramBins=dict(argstr='--numberOfHistogramBins %d', ), numberOfMatchPoints=dict(argstr='--numberOfMatchPoints %d', ), numberOfPyramidLevels=dict(argstr='--numberOfPyramidLevels %d', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), outputCheckerboardVolume=dict(argstr='--outputCheckerboardVolume %s', hash_files=False, ), outputDebug=dict(argstr='--outputDebug ', ), outputDisplacementFieldPrefix=dict(argstr='--outputDisplacementFieldPrefix %s', ), outputDisplacementFieldVolume=dict(argstr='--outputDisplacementFieldVolume %s', hash_files=False, ), outputNormalized=dict(argstr='--outputNormalized ', ), outputPixelType=dict(argstr='--outputPixelType %s', ), outputVolume=dict(argstr='--outputVolume %s', hash_files=False, ), promptUser=dict(argstr='--promptUser ', ), registrationFilterType=dict(argstr='--registrationFilterType %s', ), seedForBOBF=dict(argstr='--seedForBOBF %s', sep=',', ), smoothDisplacementFieldSigma=dict(argstr='--smoothDisplacementFieldSigma %f', ), terminal_output=dict(nohash=True, ), upFieldSmoothing=dict(argstr='--upFieldSmoothing %f', ), upperThresholdForBOBF=dict(argstr='--upperThresholdForBOBF %d', ), use_vanilla_dem=dict(argstr='--use_vanilla_dem ', ), weightFactors=dict(argstr='--weightFactors %s', sep=',', ), ) inputs = VBRAINSDemonWarp.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VBRAINSDemonWarp_outputs(): output_map = dict(outputCheckerboardVolume=dict(), outputDisplacementFieldVolume=dict(), outputVolume=dict(), ) outputs = VBRAINSDemonWarp.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/segmentation/000077500000000000000000000000001257611314500225075ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/segmentation/__init__.py000066400000000000000000000002431257611314500246170ustar00rootroot00000000000000from specialized import RobustStatisticsSegmenter, EMSegmentCommandLine, BRAINSROIAuto from simpleregiongrowingsegmentation import SimpleRegionGrowingSegmentation nipype-0.11.0/nipype/interfaces/slicer/segmentation/simpleregiongrowingsegmentation.py000066400000000000000000000053521257611314500315760ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class SimpleRegionGrowingSegmentationInputSpec(CommandLineInputSpec): smoothingIterations = traits.Int(desc="Number of smoothing iterations", argstr="--smoothingIterations %d") timestep = traits.Float(desc="Timestep for curvature flow", argstr="--timestep %f") iterations = traits.Int(desc="Number of iterations of region growing", argstr="--iterations %d") multiplier = traits.Float(desc="Number of standard deviations to include in intensity model", argstr="--multiplier %f") neighborhood = traits.Int(desc="The radius of the neighborhood over which to calculate intensity model", argstr="--neighborhood %d") labelvalue = traits.Int(desc="The integer value (0-255) to use for the segmentation results. This will determine the color of the segmentation that will be generated by the Region growing algorithm", argstr="--labelvalue %d") seed = InputMultiPath(traits.List(traits.Float(), minlen=3, maxlen=3), desc="Seed point(s) for region growing", argstr="--seed %s...") inputVolume = File(position=-2, desc="Input volume to be filtered", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output filtered", argstr="%s") class SimpleRegionGrowingSegmentationOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Output filtered", exists=True) class SimpleRegionGrowingSegmentation(SEMLikeCommandLine): """title: Simple Region Growing Segmentation category: Segmentation description: A simple region growing segmentation algorithm based on intensity statistics. To create a list of fiducials (Seeds) for this algorithm, click on the tool bar icon of an arrow pointing to a starburst fiducial to enter the 'place a new object mode' and then use the fiducials module. This module uses the Slicer Command Line Interface (CLI) and the ITK filters CurvatureFlowImageFilter and ConfidenceConnectedImageFilter. version: 0.1.0.$Revision: 19904 $(alpha) documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/SimpleRegionGrowingSegmentation contributor: Jim Miller (GE) acknowledgements: This command module was derived from Insight/Examples (copyright) Insight Software Consortium """ input_spec = SimpleRegionGrowingSegmentationInputSpec output_spec = SimpleRegionGrowingSegmentationOutputSpec _cmd = "SimpleRegionGrowingSegmentation " _outputs_filenames = {'outputVolume':'outputVolume.nii'} nipype-0.11.0/nipype/interfaces/slicer/segmentation/specialized.py000066400000000000000000000253301257611314500253600ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class RobustStatisticsSegmenterInputSpec(CommandLineInputSpec): expectedVolume = traits.Float(desc="The approximate volume of the object, in mL.", argstr="--expectedVolume %f") intensityHomogeneity = traits.Float(desc="What is the homogeneity of intensity within the object? Given constant intensity at 1.0 score and extreme fluctuating intensity at 0.", argstr="--intensityHomogeneity %f") curvatureWeight = traits.Float(desc="Given sphere 1.0 score and extreme rough bounday/surface 0 score, what is the expected smoothness of the object?", argstr="--curvatureWeight %f") labelValue = traits.Int(desc="Label value of the output image", argstr="--labelValue %d") maxRunningTime = traits.Float(desc="The program will stop if this time is reached.", argstr="--maxRunningTime %f") originalImageFileName = File(position=-3, desc="Original image to be segmented", exists=True, argstr="%s") labelImageFileName = File(position=-2, desc="Label image for initialization", exists=True, argstr="%s") segmentedImageFileName = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Segmented image", argstr="%s") class RobustStatisticsSegmenterOutputSpec(TraitedSpec): segmentedImageFileName = File(position=-1, desc="Segmented image", exists=True) class RobustStatisticsSegmenter(SEMLikeCommandLine): """title: Robust Statistics Segmenter category: Segmentation.Specialized description: Active contour segmentation using robust statistic. version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/RobustStatisticsSegmenter contributor: Yi Gao (gatech), Allen Tannenbaum (gatech), Ron Kikinis (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health """ input_spec = RobustStatisticsSegmenterInputSpec output_spec = RobustStatisticsSegmenterOutputSpec _cmd = "RobustStatisticsSegmenter " _outputs_filenames = {'segmentedImageFileName':'segmentedImageFileName.nii'} class EMSegmentCommandLineInputSpec(CommandLineInputSpec): mrmlSceneFileName = File(desc="Active MRML scene that contains EMSegment algorithm parameters.", exists=True, argstr="--mrmlSceneFileName %s") resultVolumeFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="The file name that the segmentation result volume will be written to.", argstr="--resultVolumeFileName %s") targetVolumeFileNames = InputMultiPath(File(exists=True), desc="File names of target volumes (to be segmented). The number of target images must be equal to the number of target images specified in the parameter set, and these images must be spatially aligned.", argstr="--targetVolumeFileNames %s...") intermediateResultsDirectory = Directory(desc="Directory where EMSegmenter will write intermediate data (e.g., aligned atlas data).", exists=True, argstr="--intermediateResultsDirectory %s") parametersMRMLNodeName = traits.Str(desc="The name of the EMSegment parameters node within the active MRML scene. Leave blank for default.", argstr="--parametersMRMLNodeName %s") disableMultithreading = traits.Int(desc="Disable multithreading for the EMSegmenter algorithm only! Preprocessing might still run in multi-threaded mode. -1: Do not overwrite default value. 0: Disable. 1: Enable.", argstr="--disableMultithreading %d") dontUpdateIntermediateData = traits.Int(desc="Disable update of intermediate results. -1: Do not overwrite default value. 0: Disable. 1: Enable.", argstr="--dontUpdateIntermediateData %d") verbose = traits.Bool(desc="Enable verbose output.", argstr="--verbose ") loadTargetCentered = traits.Bool(desc="Read target files centered.", argstr="--loadTargetCentered ") loadAtlasNonCentered = traits.Bool(desc="Read atlas files non-centered.", argstr="--loadAtlasNonCentered ") taskPreProcessingSetting = traits.Str(desc="Specifies the different task parameter. Leave blank for default.", argstr="--taskPreProcessingSetting %s") keepTempFiles = traits.Bool(desc="If flag is set then at the end of command the temporary files are not removed", argstr="--keepTempFiles ") resultStandardVolumeFileName = File(desc="Used for testing. Compare segmentation results to this image and return EXIT_FAILURE if they do not match.", exists=True, argstr="--resultStandardVolumeFileName %s") dontWriteResults = traits.Bool(desc="Used for testing. Don't actually write the resulting labelmap to disk.", argstr="--dontWriteResults ") generateEmptyMRMLSceneAndQuit = traits.Either(traits.Bool, File(), hash_files=False, desc="Used for testing. Only write a scene with default mrml parameters.", argstr="--generateEmptyMRMLSceneAndQuit %s") resultMRMLSceneFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="Write out the MRML scene after command line substitutions have been made.", argstr="--resultMRMLSceneFileName %s") disableCompression = traits.Bool(desc="Don't use compression when writing result image to disk.", argstr="--disableCompression ") atlasVolumeFileNames = InputMultiPath(File(exists=True), desc="Use an alternative atlas to the one that is specified by the mrml file - note the order matters ! ", argstr="--atlasVolumeFileNames %s...") registrationPackage = traits.Str(desc="specify the registration package for preprocessing (CMTK or BRAINS or PLASTIMATCH or DEMONS)", argstr="--registrationPackage %s") registrationAffineType = traits.Int(desc="specify the accuracy of the affine registration. -2: Do not overwrite default, -1: Test, 0: Disable, 1: Fast, 2: Accurate", argstr="--registrationAffineType %d") registrationDeformableType = traits.Int(desc="specify the accuracy of the deformable registration. -2: Do not overwrite default, -1: Test, 0: Disable, 1: Fast, 2: Accurate", argstr="--registrationDeformableType %d") class EMSegmentCommandLineOutputSpec(TraitedSpec): resultVolumeFileName = File(desc="The file name that the segmentation result volume will be written to.", exists=True) generateEmptyMRMLSceneAndQuit = File(desc="Used for testing. Only write a scene with default mrml parameters.", exists=True) resultMRMLSceneFileName = File(desc="Write out the MRML scene after command line substitutions have been made.", exists=True) class EMSegmentCommandLine(SEMLikeCommandLine): """title: EMSegment Command-line category: Segmentation.Specialized description: This module is used to simplify the process of segmenting large collections of images by providing a command line interface to the EMSegment algorithm for script and batch processing. documentation-url: http://www.slicer.org/slicerWiki/index.php/Documentation/4.0/EMSegment_Command-line contributor: Sebastien Barre, Brad Davis, Kilian Pohl, Polina Golland, Yumin Yuan, Daniel Haehn acknowledgements: Many people and organizations have contributed to the funding, design, and development of the EMSegment algorithm and its various implementations. """ input_spec = EMSegmentCommandLineInputSpec output_spec = EMSegmentCommandLineOutputSpec _cmd = "EMSegmentCommandLine " _outputs_filenames = {'generateEmptyMRMLSceneAndQuit':'generateEmptyMRMLSceneAndQuit','resultMRMLSceneFileName':'resultMRMLSceneFileName','resultVolumeFileName':'resultVolumeFileName.mhd'} class BRAINSROIAutoInputSpec(CommandLineInputSpec): inputVolume = File(desc="The input image for finding the largest region filled mask.", exists=True, argstr="--inputVolume %s") outputROIMaskVolume = traits.Either(traits.Bool, File(), hash_files=False, desc="The ROI automatically found from the input image.", argstr="--outputROIMaskVolume %s") outputClippedVolumeROI = traits.Either(traits.Bool, File(), hash_files=False, desc="The inputVolume clipped to the region of the brain mask.", argstr="--outputClippedVolumeROI %s") otsuPercentileThreshold = traits.Float(desc="Parameter to the Otsu threshold algorithm.", argstr="--otsuPercentileThreshold %f") thresholdCorrectionFactor = traits.Float(desc="A factor to scale the Otsu algorithm's result threshold, in case clipping mangles the image.", argstr="--thresholdCorrectionFactor %f") closingSize = traits.Float(desc="The Closing Size (in millimeters) for largest connected filled mask. This value is divided by image spacing and rounded to the next largest voxel number.", argstr="--closingSize %f") ROIAutoDilateSize = traits.Float(desc="This flag is only relavent when using ROIAUTO mode for initializing masks. It defines the final dilation size to capture a bit of background outside the tissue region. At setting of 10mm has been shown to help regularize a BSpline registration type so that there is some background constraints to match the edges of the head better.", argstr="--ROIAutoDilateSize %f") outputVolumePixelType = traits.Enum("float", "short", "ushort", "int", "uint", "uchar", desc="The output image Pixel Type is the scalar datatype for representation of the Output Volume.", argstr="--outputVolumePixelType %s") numberOfThreads = traits.Int(desc="Explicitly specify the maximum number of threads to use.", argstr="--numberOfThreads %d") class BRAINSROIAutoOutputSpec(TraitedSpec): outputROIMaskVolume = File(desc="The ROI automatically found from the input image.", exists=True) outputClippedVolumeROI = File(desc="The inputVolume clipped to the region of the brain mask.", exists=True) class BRAINSROIAuto(SEMLikeCommandLine): """title: Foreground masking (BRAINS) category: Segmentation.Specialized description: This tool uses a combination of otsu thresholding and a closing operations to identify the most prominant foreground region in an image. version: 2.4.1 license: https://www.nitrc.org/svn/brains/BuildScripts/trunk/License.txt contributor: Hans J. Johnson, hans-johnson -at- uiowa.edu, http://wwww.psychiatry.uiowa.edu acknowledgements: Hans Johnson(1,3,4); Kent Williams(1); Gregory Harris(1), Vincent Magnotta(1,2,3); Andriy Fedorov(5), fedorov -at- bwh.harvard.edu (Slicer integration); (1=University of Iowa Department of Psychiatry, 2=University of Iowa Department of Radiology, 3=University of Iowa Department of Biomedical Engineering, 4=University of Iowa Department of Electrical and Computer Engineering, 5=Surgical Planning Lab, Harvard) """ input_spec = BRAINSROIAutoInputSpec output_spec = BRAINSROIAutoOutputSpec _cmd = "BRAINSROIAuto " _outputs_filenames = {'outputROIMaskVolume':'outputROIMaskVolume.nii','outputClippedVolumeROI':'outputClippedVolumeROI.nii'} nipype-0.11.0/nipype/interfaces/slicer/segmentation/tests/000077500000000000000000000000001257611314500236515ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/segmentation/tests/test_auto_BRAINSROIAuto.py000066400000000000000000000031651257611314500305000ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.segmentation.specialized import BRAINSROIAuto def test_BRAINSROIAuto_inputs(): input_map = dict(ROIAutoDilateSize=dict(argstr='--ROIAutoDilateSize %f', ), args=dict(argstr='%s', ), closingSize=dict(argstr='--closingSize %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='--inputVolume %s', ), numberOfThreads=dict(argstr='--numberOfThreads %d', ), otsuPercentileThreshold=dict(argstr='--otsuPercentileThreshold %f', ), outputClippedVolumeROI=dict(argstr='--outputClippedVolumeROI %s', hash_files=False, ), outputROIMaskVolume=dict(argstr='--outputROIMaskVolume %s', hash_files=False, ), outputVolumePixelType=dict(argstr='--outputVolumePixelType %s', ), terminal_output=dict(nohash=True, ), thresholdCorrectionFactor=dict(argstr='--thresholdCorrectionFactor %f', ), ) inputs = BRAINSROIAuto.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_BRAINSROIAuto_outputs(): output_map = dict(outputClippedVolumeROI=dict(), outputROIMaskVolume=dict(), ) outputs = BRAINSROIAuto.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/segmentation/tests/test_auto_EMSegmentCommandLine.py000066400000000000000000000052041257611314500322460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.segmentation.specialized import EMSegmentCommandLine def test_EMSegmentCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), atlasVolumeFileNames=dict(argstr='--atlasVolumeFileNames %s...', ), disableCompression=dict(argstr='--disableCompression ', ), disableMultithreading=dict(argstr='--disableMultithreading %d', ), dontUpdateIntermediateData=dict(argstr='--dontUpdateIntermediateData %d', ), dontWriteResults=dict(argstr='--dontWriteResults ', ), environ=dict(nohash=True, usedefault=True, ), generateEmptyMRMLSceneAndQuit=dict(argstr='--generateEmptyMRMLSceneAndQuit %s', hash_files=False, ), ignore_exception=dict(nohash=True, usedefault=True, ), intermediateResultsDirectory=dict(argstr='--intermediateResultsDirectory %s', ), keepTempFiles=dict(argstr='--keepTempFiles ', ), loadAtlasNonCentered=dict(argstr='--loadAtlasNonCentered ', ), loadTargetCentered=dict(argstr='--loadTargetCentered ', ), mrmlSceneFileName=dict(argstr='--mrmlSceneFileName %s', ), parametersMRMLNodeName=dict(argstr='--parametersMRMLNodeName %s', ), registrationAffineType=dict(argstr='--registrationAffineType %d', ), registrationDeformableType=dict(argstr='--registrationDeformableType %d', ), registrationPackage=dict(argstr='--registrationPackage %s', ), resultMRMLSceneFileName=dict(argstr='--resultMRMLSceneFileName %s', hash_files=False, ), resultStandardVolumeFileName=dict(argstr='--resultStandardVolumeFileName %s', ), resultVolumeFileName=dict(argstr='--resultVolumeFileName %s', hash_files=False, ), targetVolumeFileNames=dict(argstr='--targetVolumeFileNames %s...', ), taskPreProcessingSetting=dict(argstr='--taskPreProcessingSetting %s', ), terminal_output=dict(nohash=True, ), verbose=dict(argstr='--verbose ', ), ) inputs = EMSegmentCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EMSegmentCommandLine_outputs(): output_map = dict(generateEmptyMRMLSceneAndQuit=dict(), resultMRMLSceneFileName=dict(), resultVolumeFileName=dict(), ) outputs = EMSegmentCommandLine.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/segmentation/tests/test_auto_RobustStatisticsSegmenter.py000066400000000000000000000030341257611314500335150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.segmentation.specialized import RobustStatisticsSegmenter def test_RobustStatisticsSegmenter_inputs(): input_map = dict(args=dict(argstr='%s', ), curvatureWeight=dict(argstr='--curvatureWeight %f', ), environ=dict(nohash=True, usedefault=True, ), expectedVolume=dict(argstr='--expectedVolume %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), intensityHomogeneity=dict(argstr='--intensityHomogeneity %f', ), labelImageFileName=dict(argstr='%s', position=-2, ), labelValue=dict(argstr='--labelValue %d', ), maxRunningTime=dict(argstr='--maxRunningTime %f', ), originalImageFileName=dict(argstr='%s', position=-3, ), segmentedImageFileName=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = RobustStatisticsSegmenter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_RobustStatisticsSegmenter_outputs(): output_map = dict(segmentedImageFileName=dict(position=-1, ), ) outputs = RobustStatisticsSegmenter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value test_auto_SimpleRegionGrowingSegmentation.py000066400000000000000000000030641257611314500345460ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/segmentation/tests# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.segmentation.simpleregiongrowingsegmentation import SimpleRegionGrowingSegmentation def test_SimpleRegionGrowingSegmentation_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), iterations=dict(argstr='--iterations %d', ), labelvalue=dict(argstr='--labelvalue %d', ), multiplier=dict(argstr='--multiplier %f', ), neighborhood=dict(argstr='--neighborhood %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), seed=dict(argstr='--seed %s...', ), smoothingIterations=dict(argstr='--smoothingIterations %d', ), terminal_output=dict(nohash=True, ), timestep=dict(argstr='--timestep %f', ), ) inputs = SimpleRegionGrowingSegmentation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SimpleRegionGrowingSegmentation_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = SimpleRegionGrowingSegmentation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/surface.py000066400000000000000000000374731257611314500220320ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class MergeModelsInputSpec(CommandLineInputSpec): Model1 = File(position=-3, desc="Model", exists=True, argstr="%s") Model2 = File(position=-2, desc="Model", exists=True, argstr="%s") ModelOutput = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Model", argstr="%s") class MergeModelsOutputSpec(TraitedSpec): ModelOutput = File(position=-1, desc="Model", exists=True) class MergeModels(SEMLikeCommandLine): """title: Merge Models category: Surface Models description: Merge the polydata from two input models and output a new model with the added polydata. Uses the vtkAppendPolyData filter. Works on .vtp and .vtk surface files. version: $Revision$ documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/MergeModels contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH), Daniel Haehn (SPL, BWH) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = MergeModelsInputSpec output_spec = MergeModelsOutputSpec _cmd = "MergeModels " _outputs_filenames = {'ModelOutput':'ModelOutput.vtk'} class ModelToLabelMapInputSpec(CommandLineInputSpec): distance = traits.Float(desc="Sample distance", argstr="--distance %f") InputVolume = File(position=-3, desc="Input volume", exists=True, argstr="%s") surface = File(position=-2, desc="Model", exists=True, argstr="%s") OutputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="The label volume", argstr="%s") class ModelToLabelMapOutputSpec(TraitedSpec): OutputVolume = File(position=-1, desc="The label volume", exists=True) class ModelToLabelMap(SEMLikeCommandLine): """title: Model To Label Map category: Surface Models description: Intersects an input model with an reference volume and produces an output label map. version: 0.1.0.$Revision: 8643 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/PolyDataToLabelMap contributor: Nicole Aucoin (SPL, BWH), Xiaodong Tao (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ModelToLabelMapInputSpec output_spec = ModelToLabelMapOutputSpec _cmd = "ModelToLabelMap " _outputs_filenames = {'OutputVolume':'OutputVolume.nii'} class GrayscaleModelMakerInputSpec(CommandLineInputSpec): InputVolume = File(position=-2, desc="Volume containing the input grayscale data.", exists=True, argstr="%s") OutputGeometry = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output that contains geometry model.", argstr="%s") threshold = traits.Float(desc="Grayscale threshold of isosurface. The resulting surface of triangles separates the volume into voxels that lie above (inside) and below (outside) the threshold.", argstr="--threshold %f") name = traits.Str(desc="Name to use for this model.", argstr="--name %s") smooth = traits.Int(desc="Number of smoothing iterations. If 0, no smoothing will be done.", argstr="--smooth %d") decimate = traits.Float(desc="Target reduction during decimation, as a decimal percentage reduction in the number of polygons. If 0, no decimation will be done.", argstr="--decimate %f") splitnormals = traits.Bool(desc="Splitting normals is useful for visualizing sharp features. However it creates holes in surfaces which affect measurements", argstr="--splitnormals ") pointnormals = traits.Bool(desc="Calculate the point normals? Calculated point normals make the surface appear smooth. Without point normals, the surface will appear faceted.", argstr="--pointnormals ") class GrayscaleModelMakerOutputSpec(TraitedSpec): OutputGeometry = File(position=-1, desc="Output that contains geometry model.", exists=True) class GrayscaleModelMaker(SEMLikeCommandLine): """title: Grayscale Model Maker category: Surface Models description: Create 3D surface models from grayscale data. This module uses Marching Cubes to create an isosurface at a given threshold. The resulting surface consists of triangles that separate a volume into regions below and above the threshold. The resulting surface can be smoothed and decimated. This model works on continuous data while the module Model Maker works on labeled (or discrete) data. version: 3.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/GrayscaleModelMaker license: slicer3 contributor: Nicole Aucoin (SPL, BWH), Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = GrayscaleModelMakerInputSpec output_spec = GrayscaleModelMakerOutputSpec _cmd = "GrayscaleModelMaker " _outputs_filenames = {'OutputGeometry':'OutputGeometry.vtk'} class ProbeVolumeWithModelInputSpec(CommandLineInputSpec): InputVolume = File(position=-3, desc="Volume to use to 'paint' the model", exists=True, argstr="%s") InputModel = File(position=-2, desc="Input model", exists=True, argstr="%s") OutputModel = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Output 'painted' model", argstr="%s") class ProbeVolumeWithModelOutputSpec(TraitedSpec): OutputModel = File(position=-1, desc="Output 'painted' model", exists=True) class ProbeVolumeWithModel(SEMLikeCommandLine): """title: Probe Volume With Model category: Surface Models description: Paint a model by a volume (using vtkProbeFilter). version: 0.1.0.$Revision: 1892 $(alpha) documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ProbeVolumeWithModel contributor: Lauren O'Donnell (SPL, BWH) acknowledgements: BWH, NCIGT/LMI """ input_spec = ProbeVolumeWithModelInputSpec output_spec = ProbeVolumeWithModelOutputSpec _cmd = "ProbeVolumeWithModel " _outputs_filenames = {'OutputModel':'OutputModel.vtk'} class LabelMapSmoothingInputSpec(CommandLineInputSpec): labelToSmooth = traits.Int(desc="The label to smooth. All others will be ignored. If no label is selected by the user, the maximum label in the image is chosen by default.", argstr="--labelToSmooth %d") numberOfIterations = traits.Int(desc="The number of iterations of the level set AntiAliasing algorithm", argstr="--numberOfIterations %d") maxRMSError = traits.Float(desc="The maximum RMS error.", argstr="--maxRMSError %f") gaussianSigma = traits.Float(desc="The standard deviation of the Gaussian kernel", argstr="--gaussianSigma %f") inputVolume = File(position=-2, desc="Input label map to smooth", exists=True, argstr="%s") outputVolume = traits.Either(traits.Bool, File(), position=-1, hash_files=False, desc="Smoothed label map", argstr="%s") class LabelMapSmoothingOutputSpec(TraitedSpec): outputVolume = File(position=-1, desc="Smoothed label map", exists=True) class LabelMapSmoothing(SEMLikeCommandLine): """title: Label Map Smoothing category: Surface Models description: This filter smoothes a binary label map. With a label map as input, this filter runs an anti-alising algorithm followed by a Gaussian smoothing algorithm. The output is a smoothed label map. version: 1.0 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/LabelMapSmoothing contributor: Dirk Padfield (GE), Josh Cates (Utah), Ross Whitaker (Utah) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. This filter is based on work developed at the University of Utah, and implemented at GE Research. """ input_spec = LabelMapSmoothingInputSpec output_spec = LabelMapSmoothingOutputSpec _cmd = "LabelMapSmoothing " _outputs_filenames = {'outputVolume':'outputVolume.nii'} class ModelMakerInputSpec(CommandLineInputSpec): InputVolume = File(position=-1, desc="Input label map. The Input Volume drop down menu is populated with the label map volumes that are present in the scene, select one from which to generate models.", exists=True, argstr="%s") color = File(desc="Color table to make labels to colors and objects", exists=True, argstr="--color %s") modelSceneFile = traits.Either(traits.Bool, InputMultiPath(File(), ), hash_files=False, desc="Generated models, under a model hierarchy node. Models are imported into Slicer under a model hierarchy node, and their colors are set by the color table associated with the input label map volume. The model hierarchy node must be created before running the model maker, by selecting Create New ModelHierarchy from the Models drop down menu. If you're running from the command line, a model hierarchy node in a new mrml scene will be created for you.", argstr="--modelSceneFile %s...") name = traits.Str(desc="Name to use for this model. Any text entered in the entry box will be the starting string for the created model file names. The label number and the color name will also be part of the file name. If making multiple models, use this as a prefix to the label and color name.", argstr="--name %s") generateAll = traits.Bool(desc="Generate models for all labels in the input volume. select this option if you want to create all models that correspond to all values in a labelmap volume (using the Joint Smoothing option below is useful with this option). Ignores Labels, Start Label, End Label settings. Skips label 0.", argstr="--generateAll ") labels = InputMultiPath(traits.Int, desc="A comma separated list of label values from which to make models. f you specify a list of Labels, it will override any start/end label settings. If you click Generate All Models it will override the list of labels and any start/end label settings.", sep=",", argstr="--labels %s") start = traits.Int(desc="If you want to specify a continuous range of labels from which to generate models, enter the lower label here. Voxel value from which to start making models. Used instead of the label list to specify a range (make sure the label list is empty or it will over ride this).", argstr="--start %d") end = traits.Int(desc="If you want to specify a continuous range of labels from which to generate models, enter the higher label here. Voxel value up to which to continue making models. Skip any values with zero voxels.", argstr="--end %d") skipUnNamed = traits.Bool(desc="Select this to not generate models from labels that do not have names defined in the color look up table associated with the input label map. If true, only models which have an entry in the color table will be generated. If false, generate all models that exist within the label range.", argstr="--skipUnNamed ") jointsmooth = traits.Bool(desc="This will ensure that all resulting models fit together smoothly, like jigsaw puzzle pieces. Otherwise the models will be smoothed independently and may overlap.", argstr="--jointsmooth ") smooth = traits.Int(desc="Here you can set the number of smoothing iterations for Laplacian smoothing, or the degree of the polynomial approximating the windowed Sinc function. Use 0 if you wish no smoothing. ", argstr="--smooth %d") filtertype = traits.Enum("Sinc", "Laplacian", desc="You can control the type of smoothing done on the models by selecting a filter type of either Sinc or Laplacian.", argstr="--filtertype %s") decimate = traits.Float(desc="Chose the target reduction in number of polygons as a decimal percentage (between 0 and 1) of the number of polygons. Specifies the percentage of triangles to be removed. For example, 0.1 means 10% reduction and 0.9 means 90% reduction.", argstr="--decimate %f") splitnormals = traits.Bool(desc="Splitting normals is useful for visualizing sharp features. However it creates holes in surfaces which affects measurements.", argstr="--splitnormals ") pointnormals = traits.Bool(desc="Turn this flag on if you wish to calculate the normal vectors for the points.", argstr="--pointnormals ") pad = traits.Bool(desc="Pad the input volume with zero value voxels on all 6 faces in order to ensure the production of closed surfaces. Sets the origin translation and extent translation so that the models still line up with the unpadded input volume.", argstr="--pad ") saveIntermediateModels = traits.Bool(desc="You can save a copy of the models after each of the intermediate steps (marching cubes, smoothing, and decimation if not joint smoothing, otherwise just after decimation). These intermediate models are not saved in the mrml file, you have to load them manually after turning off deleting temporary files in they python console (View ->Python Interactor) using the following command slicer.modules.modelmaker.cliModuleLogic().DeleteTemporaryFilesOff().", argstr="--saveIntermediateModels ") debug = traits.Bool(desc="turn this flag on in order to see debugging output (look in the Error Log window that is accessed via the View menu)", argstr="--debug ") class ModelMakerOutputSpec(TraitedSpec): modelSceneFile = OutputMultiPath(File(exists=True), desc="Generated models, under a model hierarchy node. Models are imported into Slicer under a model hierarchy node, and their colors are set by the color table associated with the input label map volume. The model hierarchy node must be created before running the model maker, by selecting Create New ModelHierarchy from the Models drop down menu. If you're running from the command line, a model hierarchy node in a new mrml scene will be created for you.") class ModelMaker(SEMLikeCommandLine): """title: Model Maker category: Surface Models description: Create 3D surface models from segmented data.

Models are imported into Slicer under a model hierarchy node in a MRML scene. The model colors are set by the color table associated with the input volume (these colours will only be visible if you load the model scene file).

Create Multiple:

If you specify a list of Labels, it will over ride any start/end label settings.

If you clickGenerate Allit will over ride the list of lables and any start/end label settings.

Model Maker Settings:

You can set the number of smoothing iterations, target reduction in number of polygons (decimal percentage). Use 0 and 1 if you wish no smoothing nor decimation.
You can set the flags to split normals or generate point normals in this pane as well.
You can save a copy of the models after intermediate steps (marching cubes, smoothing, and decimation if not joint smoothing, otherwise just after decimation); these models are not saved in the mrml file, turn off deleting temporary files first in the python window:
slicer.modules.modelmaker.cliModuleLogic().DeleteTemporaryFilesOff()

version: 4.1 documentation-url: http://wiki.slicer.org/slicerWiki/index.php/Documentation/4.1/Modules/ModelMaker license: slicer4 contributor: Nicole Aucoin (SPL, BWH), Ron Kikinis (SPL, BWH), Bill Lorensen (GE) acknowledgements: This work is part of the National Alliance for Medical Image Computing (NAMIC), funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149. """ input_spec = ModelMakerInputSpec output_spec = ModelMakerOutputSpec _cmd = "ModelMaker " _outputs_filenames = {'modelSceneFile':'modelSceneFile.mrml'} nipype-0.11.0/nipype/interfaces/slicer/tests/000077500000000000000000000000001257611314500211545ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_DicomToNrrdConverter.py000066400000000000000000000027511257611314500276760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.converters import DicomToNrrdConverter def test_DicomToNrrdConverter_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputDicomDirectory=dict(argstr='--inputDicomDirectory %s', ), outputDirectory=dict(argstr='--outputDirectory %s', hash_files=False, ), outputVolume=dict(argstr='--outputVolume %s', ), smallGradientThreshold=dict(argstr='--smallGradientThreshold %f', ), terminal_output=dict(nohash=True, ), useBMatrixGradientDirections=dict(argstr='--useBMatrixGradientDirections ', ), useIdentityMeaseurementFrame=dict(argstr='--useIdentityMeaseurementFrame ', ), writeProtocolGradientsFile=dict(argstr='--writeProtocolGradientsFile ', ), ) inputs = DicomToNrrdConverter.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DicomToNrrdConverter_outputs(): output_map = dict(outputDirectory=dict(), ) outputs = DicomToNrrdConverter.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_EMSegmentTransformToNewFormat.py000066400000000000000000000023121257611314500314610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.utilities import EMSegmentTransformToNewFormat def test_EMSegmentTransformToNewFormat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputMRMLFileName=dict(argstr='--inputMRMLFileName %s', ), outputMRMLFileName=dict(argstr='--outputMRMLFileName %s', hash_files=False, ), templateFlag=dict(argstr='--templateFlag ', ), terminal_output=dict(nohash=True, ), ) inputs = EMSegmentTransformToNewFormat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EMSegmentTransformToNewFormat_outputs(): output_map = dict(outputMRMLFileName=dict(), ) outputs = EMSegmentTransformToNewFormat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_GrayscaleModelMaker.py000066400000000000000000000026031257611314500274710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import GrayscaleModelMaker def test_GrayscaleModelMaker_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-2, ), OutputGeometry=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), decimate=dict(argstr='--decimate %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), name=dict(argstr='--name %s', ), pointnormals=dict(argstr='--pointnormals ', ), smooth=dict(argstr='--smooth %d', ), splitnormals=dict(argstr='--splitnormals ', ), terminal_output=dict(nohash=True, ), threshold=dict(argstr='--threshold %f', ), ) inputs = GrayscaleModelMaker.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GrayscaleModelMaker_outputs(): output_map = dict(OutputGeometry=dict(position=-1, ), ) outputs = GrayscaleModelMaker.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_LabelMapSmoothing.py000066400000000000000000000024771257611314500271740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import LabelMapSmoothing def test_LabelMapSmoothing_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), gaussianSigma=dict(argstr='--gaussianSigma %f', ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume=dict(argstr='%s', position=-2, ), labelToSmooth=dict(argstr='--labelToSmooth %d', ), maxRMSError=dict(argstr='--maxRMSError %f', ), numberOfIterations=dict(argstr='--numberOfIterations %d', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = LabelMapSmoothing.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LabelMapSmoothing_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = LabelMapSmoothing.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_MergeModels.py000066400000000000000000000021351257611314500260210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import MergeModels def test_MergeModels_inputs(): input_map = dict(Model1=dict(argstr='%s', position=-3, ), Model2=dict(argstr='%s', position=-2, ), ModelOutput=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = MergeModels.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MergeModels_outputs(): output_map = dict(ModelOutput=dict(position=-1, ), ) outputs = MergeModels.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_ModelMaker.py000066400000000000000000000034711257611314500256420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import ModelMaker def test_ModelMaker_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-1, ), args=dict(argstr='%s', ), color=dict(argstr='--color %s', ), debug=dict(argstr='--debug ', ), decimate=dict(argstr='--decimate %f', ), end=dict(argstr='--end %d', ), environ=dict(nohash=True, usedefault=True, ), filtertype=dict(argstr='--filtertype %s', ), generateAll=dict(argstr='--generateAll ', ), ignore_exception=dict(nohash=True, usedefault=True, ), jointsmooth=dict(argstr='--jointsmooth ', ), labels=dict(argstr='--labels %s', sep=',', ), modelSceneFile=dict(argstr='--modelSceneFile %s...', hash_files=False, ), name=dict(argstr='--name %s', ), pad=dict(argstr='--pad ', ), pointnormals=dict(argstr='--pointnormals ', ), saveIntermediateModels=dict(argstr='--saveIntermediateModels ', ), skipUnNamed=dict(argstr='--skipUnNamed ', ), smooth=dict(argstr='--smooth %d', ), splitnormals=dict(argstr='--splitnormals ', ), start=dict(argstr='--start %d', ), terminal_output=dict(nohash=True, ), ) inputs = ModelMaker.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ModelMaker_outputs(): output_map = dict(modelSceneFile=dict(), ) outputs = ModelMaker.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_ModelToLabelMap.py000066400000000000000000000022521257611314500265570ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import ModelToLabelMap def test_ModelToLabelMap_inputs(): input_map = dict(InputVolume=dict(argstr='%s', position=-3, ), OutputVolume=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), distance=dict(argstr='--distance %f', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), surface=dict(argstr='%s', position=-2, ), terminal_output=dict(nohash=True, ), ) inputs = ModelToLabelMap.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ModelToLabelMap_outputs(): output_map = dict(OutputVolume=dict(position=-1, ), ) outputs = ModelToLabelMap.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_OrientScalarVolume.py000066400000000000000000000022151257611314500273730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.converters import OrientScalarVolume def test_OrientScalarVolume_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), inputVolume1=dict(argstr='%s', position=-2, ), orientation=dict(argstr='--orientation %s', ), outputVolume=dict(argstr='%s', hash_files=False, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = OrientScalarVolume.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_OrientScalarVolume_outputs(): output_map = dict(outputVolume=dict(position=-1, ), ) outputs = OrientScalarVolume.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_ProbeVolumeWithModel.py000066400000000000000000000022231257611314500276700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.surface import ProbeVolumeWithModel def test_ProbeVolumeWithModel_inputs(): input_map = dict(InputModel=dict(argstr='%s', position=-2, ), InputVolume=dict(argstr='%s', position=-3, ), OutputModel=dict(argstr='%s', hash_files=False, position=-1, ), args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = ProbeVolumeWithModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ProbeVolumeWithModel_outputs(): output_map = dict(OutputModel=dict(position=-1, ), ) outputs = ProbeVolumeWithModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/tests/test_auto_SlicerCommandLine.py000066400000000000000000000011731257611314500271470ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.slicer.base import SlicerCommandLine def test_SlicerCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = SlicerCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/slicer/utilities.py000066400000000000000000000034731257611314500224060ustar00rootroot00000000000000# -*- coding: utf8 -*- """Autogenerated file - DO NOT EDIT If you spot a bug, please report it on the mailing list and/or change the generator.""" from nipype.interfaces.base import CommandLine, CommandLineInputSpec, SEMLikeCommandLine, TraitedSpec, File, Directory, traits, isdefined, InputMultiPath, OutputMultiPath import os class EMSegmentTransformToNewFormatInputSpec(CommandLineInputSpec): inputMRMLFileName = File(desc="Active MRML scene that contains EMSegment algorithm parameters in the format before 3.6.3 - please include absolute file name in path.", exists=True, argstr="--inputMRMLFileName %s") outputMRMLFileName = traits.Either(traits.Bool, File(), hash_files=False, desc="Write out the MRML scene after transformation to format 3.6.3 has been made. - has to be in the same directory as the input MRML file due to Slicer Core bug - please include absolute file name in path ", argstr="--outputMRMLFileName %s") templateFlag = traits.Bool(desc="Set to true if the transformed mrml file should be used as template file ", argstr="--templateFlag ") class EMSegmentTransformToNewFormatOutputSpec(TraitedSpec): outputMRMLFileName = File(desc="Write out the MRML scene after transformation to format 3.6.3 has been made. - has to be in the same directory as the input MRML file due to Slicer Core bug - please include absolute file name in path ", exists=True) class EMSegmentTransformToNewFormat(SEMLikeCommandLine): """title: Transform MRML Files to New EMSegmenter Standard category: Utilities description: Transform MRML Files to New EMSegmenter Standard """ input_spec = EMSegmentTransformToNewFormatInputSpec output_spec = EMSegmentTransformToNewFormatOutputSpec _cmd = "EMSegmentTransformToNewFormat " _outputs_filenames = {'outputMRMLFileName':'outputMRMLFileName.mrml'} nipype-0.11.0/nipype/interfaces/spm/000077500000000000000000000000001257611314500173305ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/spm/__init__.py000066400000000000000000000014751257611314500214500ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Top-level namespace for spm.""" from .base import (Info, SPMCommand, logger, no_spm, scans_for_fname, scans_for_fnames) from .preprocess import (SliceTiming, Realign, Coregister, Normalize, Normalize12, Segment, Smooth, NewSegment, DARTEL, DARTELNorm2MNI, CreateWarped, VBMSegment) from .model import (Level1Design, EstimateModel, EstimateContrast, Threshold, OneSampleTTestDesign, TwoSampleTTestDesign, PairedTTestDesign, MultipleRegressionDesign) from .utils import (Analyze2nii, CalcCoregAffine, ApplyTransform, Reslice, ApplyInverseDeformation, ResliceToReference, DicomImport) nipype-0.11.0/nipype/interfaces/spm/base.py000066400000000000000000000436771257611314500206350ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The spm module provides basic functions for interfacing with SPM tools. In order to use the standalone MCR version of spm, you need to ensure that the following commands are executed at the beginning of your script:: from nipype.interfaces import spm matlab_cmd = '/path/to/run_spm8.sh /path/to/Compiler_Runtime/v713/ script' spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True) you can test by calling:: spm.SPMCommand().version """ __docformat__ = 'restructuredtext' # Standard library imports import os from copy import deepcopy # Third-party imports from nibabel import load import numpy as np from scipy.io import savemat from nipype.external import six # Local imports from ..base import (BaseInterface, traits, isdefined, InputMultiPath, BaseInterfaceInputSpec, Directory, Undefined) from ..matlab import MatlabCommand from ...utils import spm_docs as sd from ... import logging logger = logging.getLogger('interface') def func_is_3d(in_file): """Checks if input functional files are 3d.""" if isinstance(in_file, list): return func_is_3d(in_file[0]) else: img = load(in_file) shape = img.get_shape() if len(shape) == 3 or (len(shape) == 4 and shape[3] == 1): return True else: return False def get_first_3dfile(in_files): if not func_is_3d(in_files): return None if isinstance(in_files[0], list): return in_files[0] return in_files def scans_for_fname(fname): """Reads a nifti file and converts it to a numpy array storing individual nifti volumes. Opens images so will fail if they are not found. """ if isinstance(fname, list): scans = np.zeros((len(fname),), dtype=object) for sno, f in enumerate(fname): scans[sno] = '%s,1' % f return scans img = load(fname) if len(img.get_shape()) == 3: return np.array(('%s,1' % fname,), dtype=object) else: n_scans = img.get_shape()[3] scans = np.zeros((n_scans,), dtype=object) for sno in range(n_scans): scans[sno] = '%s,%d' % (fname, sno + 1) return scans def scans_for_fnames(fnames, keep4d=False, separate_sessions=False): """Converts a list of files to a concatenated numpy array for each volume. keep4d : boolean keeps the entries of the numpy array as 4d files instead of extracting the individual volumes. separate_sessions: boolean if 4d nifti files are being used, then separate_sessions ensures a cell array per session is created in the structure. """ flist = None if not isinstance(fnames[0], list): if func_is_3d(fnames[0]): fnames = [fnames] if separate_sessions or keep4d: flist = np.zeros((len(fnames),), dtype=object) for i, f in enumerate(fnames): if separate_sessions: if keep4d: if isinstance(f, list): flist[i] = np.array(f, dtype=object) else: flist[i] = np.array([f], dtype=object) else: flist[i] = scans_for_fname(f) else: if keep4d: flist[i] = f else: scans = scans_for_fname(f) if flist is None: flist = scans else: flist = np.concatenate((flist, scans)) return flist class Info(object): """Handles SPM version information """ @staticmethod def version(matlab_cmd=None, paths=None, use_mcr=None): """Returns the path to the SPM directory in the Matlab path If path not found, returns None. Parameters ---------- matlab_cmd: str Sets the default matlab command. If None, the value of the environment variable SPMMCRCMD will be used if set and use_mcr is True or the environment variable FORCE_SPMMCR is set. If one of FORCE_SPMMCR or SPMMCRCMD is not set, the existence of the environment variable MATLABCMD is checked and its value is used as the matlab command if possible. If none of the above was successful, the fallback value of 'matlab -nodesktop -nosplash' will be used. paths : str use_mcr : bool Returns ------- spm_path : string representing path to SPM directory returns None of path not found """ if use_mcr or 'FORCE_SPMMCR' in os.environ: use_mcr = True if matlab_cmd is None: try: matlab_cmd = os.environ['SPMMCRCMD'] except KeyError: pass if matlab_cmd is None: try: matlab_cmd = os.environ['MATLABCMD'] except KeyError: matlab_cmd = 'matlab -nodesktop -nosplash' mlab = MatlabCommand(matlab_cmd=matlab_cmd) mlab.inputs.mfile = False if paths: mlab.inputs.paths = paths if use_mcr: mlab.inputs.nodesktop = Undefined mlab.inputs.nosplash = Undefined mlab.inputs.single_comp_thread = Undefined mlab.inputs.mfile = True mlab.inputs.uses_mcr = True mlab.inputs.script = """ if isempty(which('spm')), throw(MException('SPMCheck:NotFound','SPM not in matlab path')); end; spm_path = spm('dir'); [name, version] = spm('ver'); fprintf(1, 'NIPYPE path:%s|name:%s|release:%s', spm_path, name, version); exit; """ try: out = mlab.run() except (IOError, RuntimeError), e: # if no Matlab at all -- exception could be raised # No Matlab -- no spm logger.debug(str(e)) return None else: out = sd._strip_header(out.runtime.stdout) out_dict = {} for part in out.split('|'): key, val = part.split(':') out_dict[key] = val return out_dict def no_spm(): """ Checks if SPM is NOT installed used with nosetests skipif to skip tests that will fail if spm is not installed""" if Info.version() is None or 'NIPYPE_NO_MATLAB' in os.environ: return True else: return False class SPMCommandInputSpec(BaseInterfaceInputSpec): matlab_cmd = traits.Str(desc='matlab command to use') paths = InputMultiPath(Directory(), desc='Paths to add to matlabpath') mfile = traits.Bool(True, desc='Run m-code using m-file', usedefault=True) use_mcr = traits.Bool(desc='Run m-code using SPM MCR') use_v8struct = traits.Bool(True, min_ver='8', usedefault=True, desc=('Generate SPM8 and higher compatible jobs') ) class SPMCommand(BaseInterface): """Extends `BaseInterface` class to implement SPM specific interfaces. WARNING: Pseudo prototype class, meant to be subclassed """ input_spec = SPMCommandInputSpec _additional_metadata = ['field'] _jobtype = 'basetype' _jobname = 'basename' _matlab_cmd = None _paths = None _use_mcr = None def __init__(self, **inputs): super(SPMCommand, self).__init__(**inputs) self.inputs.on_trait_change(self._matlab_cmd_update, ['matlab_cmd', 'mfile', 'paths', 'use_mcr']) self._find_mlab_cmd_defaults() self._check_mlab_inputs() self._matlab_cmd_update() @classmethod def set_mlab_paths(cls, matlab_cmd=None, paths=None, use_mcr=None): cls._matlab_cmd = matlab_cmd cls._paths = paths cls._use_mcr = use_mcr def _find_mlab_cmd_defaults(self): # check if the user has set environment variables to enforce # the standalone (MCR) version of SPM if self._use_mcr or 'FORCE_SPMMCR' in os.environ: self._use_mcr = True if self._matlab_cmd is None: try: self._matlab_cmd = os.environ['SPMMCRCMD'] except KeyError: pass def _matlab_cmd_update(self): # MatlabCommand has to be created here, # because matlab_cmb is not a proper input # and can be set only during init self.mlab = MatlabCommand(matlab_cmd=self.inputs.matlab_cmd, mfile=self.inputs.mfile, paths=self.inputs.paths) self.mlab.inputs.script_file = 'pyscript_%s.m' % \ self.__class__.__name__.split('.')[-1].lower() if isdefined(self.inputs.use_mcr) and self.inputs.use_mcr: self.mlab.inputs.nodesktop = Undefined self.mlab.inputs.nosplash = Undefined self.mlab.inputs.single_comp_thread = Undefined self.mlab.inputs.uses_mcr = True self.mlab.inputs.mfile = True @property def version(self): version_dict = Info.version(matlab_cmd=self.inputs.matlab_cmd, paths=self.inputs.paths, use_mcr=self.inputs.use_mcr) if version_dict: return '.'.join((version_dict['name'].split('SPM')[-1], version_dict['release'])) return version_dict @property def jobtype(self): return self._jobtype @property def jobname(self): return self._jobname def _check_mlab_inputs(self): if not isdefined(self.inputs.matlab_cmd) and self._matlab_cmd: self.inputs.matlab_cmd = self._matlab_cmd if not isdefined(self.inputs.paths) and self._paths: self.inputs.paths = self._paths if not isdefined(self.inputs.use_mcr) and self._use_mcr: self.inputs.use_mcr = self._use_mcr def _run_interface(self, runtime): """Executes the SPM function using MATLAB.""" self.mlab.inputs.script = self._make_matlab_command( deepcopy(self._parse_inputs())) results = self.mlab.run() runtime.returncode = results.runtime.returncode if self.mlab.inputs.uses_mcr: if 'Skipped' in results.runtime.stdout: self.raise_exception(runtime) runtime.stdout = results.runtime.stdout runtime.stderr = results.runtime.stderr runtime.merged = results.runtime.merged return runtime def _list_outputs(self): """Determine the expected outputs based on inputs.""" raise NotImplementedError def _format_arg(self, opt, spec, val): """Convert input to appropriate format for SPM.""" if spec.is_trait_type(traits.Bool): return int(val) else: return val def _parse_inputs(self, skip=()): spmdict = {} metadata = dict(field=lambda t: t is not None) for name, spec in self.inputs.traits(**metadata).items(): if skip and name in skip: continue value = getattr(self.inputs, name) if not isdefined(value): continue field = spec.field if '.' in field: fields = field.split('.') dictref = spmdict for f in fields[:-1]: if f not in dictref.keys(): dictref[f] = {} dictref = dictref[f] dictref[fields[-1]] = self._format_arg(name, spec, value) else: spmdict[field] = self._format_arg(name, spec, value) return [spmdict] def _reformat_dict_for_savemat(self, contents): """Encloses a dict representation within hierarchical lists. In order to create an appropriate SPM job structure, a Python dict storing the job needs to be modified so that each dict embedded in dict needs to be enclosed as a list element. Examples -------- >>> a = SPMCommand()._reformat_dict_for_savemat(dict(a=1, ... b=dict(c=2, d=3))) >>> a == [{'a': 1, 'b': [{'c': 2, 'd': 3}]}] True """ newdict = {} try: for key, value in contents.items(): if isinstance(value, dict): if value: newdict[key] = self._reformat_dict_for_savemat(value) # if value is None, skip else: newdict[key] = value return [newdict] except TypeError: print 'Requires dict input' def _generate_job(self, prefix='', contents=None): """Recursive function to generate spm job specification as a string Parameters ---------- prefix : string A string that needs to get contents : dict A non-tuple Python structure containing spm job information gets converted to an appropriate sequence of matlab commands. """ jobstring = '' if contents is None: return jobstring if isinstance(contents, list): for i, value in enumerate(contents): if prefix.endswith(")"): newprefix = "%s,%d)" % (prefix[:-1], i + 1) else: newprefix = "%s(%d)" % (prefix, i + 1) jobstring += self._generate_job(newprefix, value) return jobstring if isinstance(contents, dict): for key, value in contents.items(): newprefix = "%s.%s" % (prefix, key) jobstring += self._generate_job(newprefix, value) return jobstring if isinstance(contents, np.ndarray): if contents.dtype == np.dtype(object): if prefix: jobstring += "%s = {...\n" % (prefix) else: jobstring += "{...\n" for i, val in enumerate(contents): if isinstance(val, np.ndarray): jobstring += self._generate_job(prefix=None, contents=val) elif isinstance(val, six.string_types): jobstring += '\'%s\';...\n' % (val) else: jobstring += '%s;...\n' % str(val) jobstring += '};\n' else: for i, val in enumerate(contents): for field in val.dtype.fields: if prefix: newprefix = "%s(%d).%s" % (prefix, i + 1, field) else: newprefix = "(%d).%s" % (i + 1, field) jobstring += self._generate_job(newprefix, val[field]) return jobstring if isinstance(contents, six.string_types): jobstring += "%s = '%s';\n" % (prefix, contents) return jobstring jobstring += "%s = %s;\n" % (prefix, str(contents)) return jobstring def _make_matlab_command(self, contents, postscript=None): """Generates a mfile to build job structure Parameters ---------- contents : list a list of dicts generated by _parse_inputs in each subclass cwd : string default os.getcwd() Returns ------- mscript : string contents of a script called by matlab """ cwd = os.getcwd() mscript = """ %% Generated by nipype.interfaces.spm if isempty(which('spm')), throw(MException('SPMCheck:NotFound', 'SPM not in matlab path')); end [name, version] = spm('ver'); fprintf('SPM version: %s Release: %s\\n',name, version); fprintf('SPM path: %s\\n', which('spm')); spm('Defaults','fMRI'); if strcmp(name, 'SPM8') || strcmp(name(1:5), 'SPM12'), spm_jobman('initcfg'); spm_get_defaults('cmdline', 1); end\n """ if self.mlab.inputs.mfile: if isdefined(self.inputs.use_v8struct) and self.inputs.use_v8struct: mscript += self._generate_job('jobs{1}.spm.%s.%s' % (self.jobtype, self.jobname), contents[0]) else: if self.jobname in ['st', 'smooth', 'preproc', 'preproc8', 'fmri_spec', 'fmri_est', 'factorial_design', 'defs']: # parentheses mscript += self._generate_job('jobs{1}.%s{1}.%s(1)' % (self.jobtype, self.jobname), contents[0]) else: #curly brackets mscript += self._generate_job('jobs{1}.%s{1}.%s{1}' % (self.jobtype, self.jobname), contents[0]) else: jobdef = {'jobs': [{self.jobtype: [{self.jobname: self.reformat_dict_for_savemat(contents[0])}] }]} savemat(os.path.join(cwd, 'pyjobs_%s.mat' % self.jobname), jobdef) mscript += "load pyjobs_%s;\n\n" % self.jobname mscript += """ spm_jobman(\'run\', jobs);\n """ if self.inputs.use_mcr: mscript += """ if strcmp(name, 'SPM8') || strcmp(name(1:5), 'SPM12'), close(\'all\', \'force\'); end; """ if postscript is not None: mscript += postscript return mscript nipype-0.11.0/nipype/interfaces/spm/model.py000066400000000000000000001160641257611314500210120ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The spm module provides basic functions for interfacing with matlab and spm to access spm tools. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ __docformat__ = 'restructuredtext' # Standard library imports import os from glob import glob # Third-party imports import numpy as np import scipy.io as sio from nipype.external import six # Local imports from nipype.interfaces.base import (Bunch, traits, TraitedSpec, File, Directory, OutputMultiPath, InputMultiPath, isdefined) from nipype.interfaces.spm.base import (SPMCommand, SPMCommandInputSpec, scans_for_fnames) from nipype.utils.filemanip import (filename_to_list, list_to_filename, split_filename) from ... import logging logger = logging.getLogger('interface') class Level1DesignInputSpec(SPMCommandInputSpec): spm_mat_dir = Directory(exists=True, field='dir', desc='directory to store SPM.mat file (opt)') timing_units = traits.Enum('secs', 'scans', field='timing.units', desc='units for specification of onsets', mandatory=True) interscan_interval = traits.Float(field='timing.RT', desc='Interscan interval in secs', mandatory=True) microtime_resolution = traits.Int(field='timing.fmri_t', desc='Number of time-bins per scan in secs (opt)') microtime_onset = traits.Float(field='timing.fmri_t0', desc='The onset/time-bin in seconds for alignment (opt)') session_info = traits.Any(field='sess', desc='Session specific information generated by ``modelgen.SpecifyModel``', mandatory=True) factor_info = traits.List(traits.Dict(traits.Enum('name', 'levels')), field='fact', desc='Factor specific information file (opt)') bases = traits.Dict(traits.Enum('hrf', 'fourier', 'fourier_han', 'gamma', 'fir'), field='bases', desc=""" dict {'name':{'basesparam1':val,...}} name : string Name of basis function (hrf, fourier, fourier_han, gamma, fir) hrf : derivs : 2-element list Model HRF Derivatives. No derivatives: [0,0], Time derivatives : [1,0], Time and Dispersion derivatives: [1,1] fourier, fourier_han, gamma, fir: length : int Post-stimulus window length (in seconds) order : int Number of basis functions """, mandatory=True) volterra_expansion_order = traits.Enum(1, 2, field='volt', desc='Model interactions - yes:1, no:2') global_intensity_normalization = traits.Enum('none', 'scaling', field='global', desc='Global intensity normalization - scaling or none') mask_image = File(exists=True, field='mask', desc='Image for explicitly masking the analysis') mask_threshold = traits.Either(traits.Enum('-Inf'), traits.Float(), desc="Thresholding for the mask", default='-Inf', usedefault=True) model_serial_correlations = traits.Enum('AR(1)', 'FAST', 'none', field='cvi', desc=('Model serial correlations ' 'AR(1), FAST or none. FAST ' 'is available in SPM12')) class Level1DesignOutputSpec(TraitedSpec): spm_mat_file = File(exists=True, desc='SPM mat file') class Level1Design(SPMCommand): """Generate an SPM design matrix http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=59 Examples -------- >>> level1design = Level1Design() >>> level1design.inputs.timing_units = 'secs' >>> level1design.inputs.interscan_interval = 2.5 >>> level1design.inputs.bases = {'hrf':{'derivs': [0,0]}} >>> level1design.inputs.session_info = 'session_info.npz' >>> level1design.run() # doctest: +SKIP """ input_spec = Level1DesignInputSpec output_spec = Level1DesignOutputSpec _jobtype = 'stats' _jobname = 'fmri_spec' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['spm_mat_dir', 'mask_image']: return np.array([str(val)], dtype=object) if opt in ['session_info']: #, 'factor_info']: if isinstance(val, dict): return [val] else: return val return super(Level1Design, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm realign options if set to None ignore """ einputs = super(Level1Design, self)._parse_inputs(skip=('mask_threshold')) for sessinfo in einputs[0]['sess']: sessinfo['scans'] = scans_for_fnames(filename_to_list(sessinfo['scans']), keep4d=False) if not isdefined(self.inputs.spm_mat_dir): einputs[0]['dir'] = np.array([str(os.getcwd())], dtype=object) return einputs def _make_matlab_command(self, content): """validates spm options and generates job structure if mfile is True uses matlab .m file else generates a job structure and saves in .mat """ if isdefined(self.inputs.mask_image): # SPM doesn't handle explicit masking properly, especially # when you want to use the entire mask image postscript = "load SPM;\n" postscript += "SPM.xM.VM = spm_vol('%s');\n" % list_to_filename(self.inputs.mask_image) postscript += "SPM.xM.I = 0;\n" postscript += "SPM.xM.T = [];\n" postscript += "SPM.xM.TH = ones(size(SPM.xM.TH))*(%s);\n" % self.inputs.mask_threshold postscript += "SPM.xM.xs = struct('Masking', 'explicit masking only');\n" postscript += "save SPM SPM;\n" else: postscript = None return super(Level1Design, self)._make_matlab_command(content, postscript=postscript) def _list_outputs(self): outputs = self._outputs().get() spm = os.path.join(os.getcwd(), 'SPM.mat') outputs['spm_mat_file'] = spm return outputs class EstimateModelInputSpec(SPMCommandInputSpec): spm_mat_file = File(exists=True, field='spmmat', desc='absolute path to SPM.mat', copyfile=True, mandatory=True) estimation_method = traits.Dict(traits.Enum('Classical', 'Bayesian2', 'Bayesian'), field='method', desc='Classical, Bayesian2, Bayesian (dict)', mandatory=True) flags = traits.Str(desc='optional arguments (opt)') class EstimateModelOutputSpec(TraitedSpec): mask_image = File(exists=True, desc='binary mask to constrain estimation') beta_images = OutputMultiPath(File(exists=True), desc='design parameter estimates') residual_image = File(exists=True, desc='Mean-squared image of the residuals') RPVimage = File(exists=True, desc='Resels per voxel image') spm_mat_file = File(exists=True, desc='Updated SPM mat file') class EstimateModel(SPMCommand): """Use spm_spm to estimate the parameters of a model http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=69 Examples -------- >>> est = EstimateModel() >>> est.inputs.spm_mat_file = 'SPM.mat' >>> est.run() # doctest: +SKIP """ input_spec = EstimateModelInputSpec output_spec = EstimateModelOutputSpec _jobtype = 'stats' _jobname = 'fmri_est' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'spm_mat_file': return np.array([str(val)], dtype=object) if opt == 'estimation_method': if isinstance(val, six.string_types): return {'%s' % val: 1} else: return val return super(EstimateModel, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm realign options if set to None ignore """ einputs = super(EstimateModel, self)._parse_inputs(skip=('flags')) if isdefined(self.inputs.flags): einputs[0].update(self.inputs.flags) return einputs def _list_outputs(self): outputs = self._outputs().get() pth, _ = os.path.split(self.inputs.spm_mat_file) spm12 = '12' in self.version.split('.')[0] if spm12: mask = os.path.join(pth, 'mask.nii') else: mask = os.path.join(pth, 'mask.img') outputs['mask_image'] = mask spm = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False) betas = [] for vbeta in spm['SPM'][0, 0].Vbeta[0]: betas.append(str(os.path.join(pth, vbeta.fname[0]))) if betas: outputs['beta_images'] = betas if spm12: resms = os.path.join(pth, 'ResMS.nii') else: resms = os.path.join(pth, 'ResMS.img') outputs['residual_image'] = resms if spm12: rpv = os.path.join(pth, 'RPV.nii') else: rpv = os.path.join(pth, 'RPV.img') outputs['RPVimage'] = rpv spm = os.path.join(pth, 'SPM.mat') outputs['spm_mat_file'] = spm return outputs class EstimateContrastInputSpec(SPMCommandInputSpec): spm_mat_file = File(exists=True, field='spmmat', desc='Absolute path to SPM.mat', copyfile=True, mandatory=True) contrasts = traits.List( traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('F'), traits.List(traits.Either(traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float)), traits.Tuple(traits.Str, traits.Enum('T'), traits.List(traits.Str), traits.List(traits.Float), traits.List(traits.Float)))))), desc="""List of contrasts with each contrast being a list of the form: [('name', 'stat', [condition list], [weight list], [session list])]. if session list is None or not provided, all sessions are used. For F contrasts, the condition list should contain previously defined T-contrasts.""", mandatory=True) beta_images = InputMultiPath(File(exists=True), desc='Parameter estimates of the design matrix', copyfile=False, mandatory=True) residual_image = File(exists=True, desc='Mean-squared image of the residuals', copyfile=False, mandatory=True) use_derivs = traits.Bool(desc='use derivatives for estimation', xor=['group_contrast']) group_contrast = traits.Bool(desc='higher level contrast', xor=['use_derivs']) class EstimateContrastOutputSpec(TraitedSpec): con_images = OutputMultiPath(File(exists=True), desc='contrast images from a t-contrast') spmT_images = OutputMultiPath(File(exists=True), desc='stat images from a t-contrast') ess_images = OutputMultiPath(File(exists=True), desc='contrast images from an F-contrast') spmF_images = OutputMultiPath(File(exists=True), desc='stat images from an F-contrast') spm_mat_file = File(exists=True, desc='Updated SPM mat file') class EstimateContrast(SPMCommand): """use spm_contrasts to estimate contrasts of interest Examples -------- >>> import nipype.interfaces.spm as spm >>> est = spm.EstimateContrast() >>> est.inputs.spm_mat_file = 'SPM.mat' >>> cont1 = ('Task>Baseline','T', ['Task-Odd','Task-Even'],[0.5,0.5]) >>> cont2 = ('Task-Odd>Task-Even','T', ['Task-Odd','Task-Even'],[1,-1]) >>> contrasts = [cont1,cont2] >>> est.inputs.contrasts = contrasts >>> est.run() # doctest: +SKIP """ input_spec = EstimateContrastInputSpec output_spec = EstimateContrastOutputSpec _jobtype = 'stats' _jobname = 'con' def _make_matlab_command(self, _): """validates spm options and generates job structure """ contrasts = [] cname = [] for i, cont in enumerate(self.inputs.contrasts): cname.insert(i, cont[0]) contrasts.insert(i, Bunch(name=cont[0], stat=cont[1], conditions=cont[2], weights=None, sessions=None)) if len(cont) >= 4: contrasts[i].weights = cont[3] if len(cont) >= 5: contrasts[i].sessions = cont[4] script = "% generated by nipype.interfaces.spm\n" script += "spm_defaults;\n" script += "jobs{1}.stats{1}.con.spmmat = {'%s'};\n" % self.inputs.spm_mat_file script += "load(jobs{1}.stats{1}.con.spmmat{:});\n" script += "SPM.swd = '%s';\n" % os.getcwd() script += "save(jobs{1}.stats{1}.con.spmmat{:},'SPM');\n" script += "names = SPM.xX.name;\n" # get names for columns if isdefined(self.inputs.group_contrast) and self.inputs.group_contrast: script += "condnames=names;\n" else: if self.inputs.use_derivs: script += "pat = 'Sn\([0-9]*\) (.*)';\n" else: script += "pat = 'Sn\([0-9]*\) (.*)\*bf\(1\)|Sn\([0-9]*\) .*\*bf\([2-9]\)|Sn\([0-9]*\) (.*)';\n" script += "t = regexp(names,pat,'tokens');\n" # get sessidx for columns script += "pat1 = 'Sn\(([0-9].*)\)\s.*';\n" script += "t1 = regexp(names,pat1,'tokens');\n" script += "for i0=1:numel(t),condnames{i0}='';condsess(i0)=0;if ~isempty(t{i0}{1}),condnames{i0} = t{i0}{1}{1};condsess(i0)=str2num(t1{i0}{1}{1});end;end;\n" # BUILD CONTRAST SESSION STRUCTURE for i, contrast in enumerate(contrasts): if contrast.stat == 'T': script += "consess{%d}.tcon.name = '%s';\n" % (i + 1, contrast.name) script += "consess{%d}.tcon.convec = zeros(1,numel(names));\n" % (i + 1) for c0, cond in enumerate(contrast.conditions): script += "idx = strmatch('%s',condnames,'exact');\n" % (cond) script += "if isempty(idx), throw(MException('CondName:Chk', sprintf('Condition %%s not found in design','%s'))); end;\n" % cond if contrast.sessions: for sno, sw in enumerate(contrast.sessions): script += "sidx = find(condsess(idx)==%d);\n" % (sno + 1) script += "consess{%d}.tcon.convec(idx(sidx)) = %f;\n" % (i + 1, sw * contrast.weights[c0]) else: script += "consess{%d}.tcon.convec(idx) = %f;\n" % (i + 1, contrast.weights[c0]) for i, contrast in enumerate(contrasts): if contrast.stat == 'F': script += "consess{%d}.fcon.name = '%s';\n" % (i + 1, contrast.name) for cl0, fcont in enumerate(contrast.conditions): try: tidx = cname.index(fcont[0]) except: Exception("Contrast Estimate: could not get index of" \ " T contrast. probably not defined prior " \ "to the F contrasts") script += "consess{%d}.fcon.convec{%d} = consess{%d}.tcon.convec;\n" % (i + 1, cl0 + 1, tidx + 1) script += "jobs{1}.stats{1}.con.consess = consess;\n" script += "if strcmp(spm('ver'),'SPM8'), spm_jobman('initcfg');jobs=spm_jobman('spm5tospm8',{jobs});end\n" script += "spm_jobman('run',jobs);" return script def _list_outputs(self): outputs = self._outputs().get() pth, _ = os.path.split(self.inputs.spm_mat_file) spm = sio.loadmat(self.inputs.spm_mat_file, struct_as_record=False) con_images = [] spmT_images = [] for con in spm['SPM'][0, 0].xCon[0]: con_images.append(str(os.path.join(pth, con.Vcon[0, 0].fname[0]))) spmT_images.append(str(os.path.join(pth, con.Vspm[0, 0].fname[0]))) if con_images: outputs['con_images'] = con_images outputs['spmT_images'] = spmT_images spm12 = '12' in self.version.split('.')[0] if spm12: ess = glob(os.path.join(pth, 'ess*.nii')) else: ess = glob(os.path.join(pth, 'ess*.img')) if len(ess) > 0: outputs['ess_images'] = sorted(ess) if spm12: spmf = glob(os.path.join(pth, 'spmF*.nii')) else: spmf = glob(os.path.join(pth, 'spmF*.img')) if len(spmf) > 0: outputs['spmF_images'] = sorted(spmf) outputs['spm_mat_file'] = self.inputs.spm_mat_file return outputs class ThresholdInputSpec(SPMCommandInputSpec): spm_mat_file = File(exists=True, desc='absolute path to SPM.mat', copyfile=True, mandatory=True) stat_image = File(exists=True, desc='stat image', copyfile=False, mandatory=True) contrast_index = traits.Int(mandatory=True, desc='which contrast in the SPM.mat to use') use_fwe_correction = traits.Bool(True, usedefault=True, desc="whether to use FWE (Bonferroni) correction for initial threshold (height_threshold_type has to be set to p-value)") use_topo_fdr = traits.Bool(True, usedefault=True, desc="whether to use FDR over cluster extent probabilities") height_threshold = traits.Float(0.05, usedefault=True, desc="value for initial thresholding (defining clusters)") height_threshold_type = traits.Enum('p-value', 'stat', usedefault=True, desc="Is the cluster forming threshold a stat value or p-value?") extent_fdr_p_threshold = traits.Float(0.05, usedefault=True, desc='p threshold on FDR corrected cluster size probabilities') extent_threshold = traits.Int(0, usedefault=True, desc="Minimum cluster size in voxels") force_activation = traits.Bool(False, usedefault=True, desc="In case no clusters survive the topological inference step this will pick a culster with the highes sum of t-values. Use with care.") class ThresholdOutputSpec(TraitedSpec): thresholded_map = File(exists=True) n_clusters = traits.Int() pre_topo_fdr_map = File(exists=True) pre_topo_n_clusters = traits.Int() activation_forced = traits.Bool() cluster_forming_thr = traits.Float() class Threshold(SPMCommand): '''Topological FDR thresholding based on cluster extent/size. Smoothness is estimated from GLM residuals but is assumed to be the same for all of the voxels. Examples -------- >>> thresh = Threshold() >>> thresh.inputs.spm_mat_file = 'SPM.mat' >>> thresh.inputs.stat_image = 'spmT_0001.img' >>> thresh.inputs.contrast_index = 1 >>> thresh.inputs.extent_fdr_p_threshold = 0.05 >>> thresh.run() # doctest: +SKIP ''' input_spec = ThresholdInputSpec output_spec = ThresholdOutputSpec def _gen_thresholded_map_filename(self): _, fname, ext = split_filename(self.inputs.stat_image) return os.path.abspath(fname + "_thr" + ext) def _gen_pre_topo_map_filename(self): _, fname, ext = split_filename(self.inputs.stat_image) return os.path.abspath(fname + "_pre_topo_thr" + ext) def _make_matlab_command(self, _): script = "con_index = %d;\n" % self.inputs.contrast_index script += "cluster_forming_thr = %f;\n" % self.inputs.height_threshold if self.inputs.use_fwe_correction: script += "thresDesc = 'FWE';\n" else: script += "thresDesc = 'none';\n" if self.inputs.use_topo_fdr: script += "use_topo_fdr = 1;\n" else: script += "use_topo_fdr = 0;\n" if self.inputs.force_activation: script += "force_activation = 1;\n" else: script += "force_activation = 0;\n" script += "cluster_extent_p_fdr_thr = %f;\n" % self.inputs.extent_fdr_p_threshold script += "stat_filename = '%s';\n" % self.inputs.stat_image script += "height_threshold_type = '%s';\n" % self.inputs.height_threshold_type script += "extent_threshold = %d;\n" % self.inputs.extent_threshold script += "load %s;\n" % self.inputs.spm_mat_file script += """ FWHM = SPM.xVol.FWHM; df = [SPM.xCon(con_index).eidf SPM.xX.erdf]; STAT = SPM.xCon(con_index).STAT; R = SPM.xVol.R; S = SPM.xVol.S; n = 1; switch thresDesc case 'FWE' cluster_forming_thr = spm_uc(cluster_forming_thr,df,STAT,R,n,S); case 'none' if strcmp(height_threshold_type, 'p-value') cluster_forming_thr = spm_u(cluster_forming_thr^(1/n),df,STAT); end end stat_map_vol = spm_vol(stat_filename); [stat_map_data, stat_map_XYZmm] = spm_read_vols(stat_map_vol); Z = stat_map_data(:)'; [x,y,z] = ind2sub(size(stat_map_data),(1:numel(stat_map_data))'); XYZ = cat(1, x', y', z'); XYZth = XYZ(:, Z >= cluster_forming_thr); Zth = Z(Z >= cluster_forming_thr); """ script += "spm_write_filtered(Zth,XYZth,stat_map_vol.dim',stat_map_vol.mat,'thresholded map', '%s');\n" % self._gen_pre_topo_map_filename() script += """ max_size = 0; max_size_index = 0; th_nclusters = 0; nclusters = 0; if isempty(XYZth) thresholded_XYZ = []; thresholded_Z = []; else if use_topo_fdr V2R = 1/prod(FWHM(stat_map_vol.dim > 1)); [uc,Pc,ue] = spm_uc_clusterFDR(cluster_extent_p_fdr_thr,df,STAT,R,n,Z,XYZ,V2R,cluster_forming_thr); end voxel_labels = spm_clusters(XYZth); nclusters = max(voxel_labels); thresholded_XYZ = []; thresholded_Z = []; for i = 1:nclusters cluster_size = sum(voxel_labels==i); if cluster_size > extent_threshold && (~use_topo_fdr || (cluster_size - uc) > -1) thresholded_XYZ = cat(2, thresholded_XYZ, XYZth(:,voxel_labels == i)); thresholded_Z = cat(2, thresholded_Z, Zth(voxel_labels == i)); th_nclusters = th_nclusters + 1; end if force_activation cluster_sum = sum(Zth(voxel_labels == i)); if cluster_sum > max_size max_size = cluster_sum; max_size_index = i; end end end end activation_forced = 0; if isempty(thresholded_XYZ) if force_activation && max_size ~= 0 thresholded_XYZ = XYZth(:,voxel_labels == max_size_index); thresholded_Z = Zth(voxel_labels == max_size_index); th_nclusters = 1; activation_forced = 1; else thresholded_Z = [0]; thresholded_XYZ = [1 1 1]'; th_nclusters = 0; end end fprintf('activation_forced = %d\\n',activation_forced); fprintf('pre_topo_n_clusters = %d\\n',nclusters); fprintf('n_clusters = %d\\n',th_nclusters); fprintf('cluster_forming_thr = %f\\n',cluster_forming_thr); """ script += "spm_write_filtered(thresholded_Z,thresholded_XYZ,stat_map_vol.dim',stat_map_vol.mat,'thresholded map', '%s');\n" % self._gen_thresholded_map_filename() return script def aggregate_outputs(self, runtime=None): outputs = self._outputs() setattr(outputs, 'thresholded_map', self._gen_thresholded_map_filename()) setattr(outputs, 'pre_topo_fdr_map', self._gen_pre_topo_map_filename()) for line in runtime.stdout.split('\n'): if line.startswith("activation_forced = "): setattr(outputs, 'activation_forced', line[len("activation_forced = "):].strip() == "1") elif line.startswith("n_clusters = "): setattr(outputs, 'n_clusters', int(line[len("n_clusters = "):].strip())) elif line.startswith("pre_topo_n_clusters = "): setattr(outputs, 'pre_topo_n_clusters', int(line[len("pre_topo_n_clusters = "):].strip())) elif line.startswith("cluster_forming_thr = "): setattr(outputs, 'cluster_forming_thr', float(line[len("cluster_forming_thr = "):].strip())) return outputs def _list_outputs(self): outputs = self._outputs().get() outputs['thresholded_map'] = self._gen_thresholded_map_filename() outputs['pre_topo_fdr_map'] = self._gen_pre_topo_map_filename() return outputs class ThresholdStatisticsInputSpec(SPMCommandInputSpec): spm_mat_file = File(exists=True, desc='absolute path to SPM.mat', copyfile=True, mandatory=True) stat_image = File(exists=True, desc='stat image', copyfile=False, mandatory=True) contrast_index = traits.Int(mandatory=True, desc='which contrast in the SPM.mat to use') height_threshold = traits.Float(desc="stat value for initial thresholding (defining clusters)", mandatory=True) extent_threshold = traits.Int(0, usedefault=True, desc="Minimum cluster size in voxels") class ThresholdStatisticsOutputSpec(TraitedSpec): voxelwise_P_Bonf = traits.Float() voxelwise_P_RF = traits.Float() voxelwise_P_uncor = traits.Float() voxelwise_P_FDR = traits.Float() clusterwise_P_RF = traits.Float() clusterwise_P_FDR = traits.Float() class ThresholdStatistics(SPMCommand): '''Given height and cluster size threshold calculate theoretical probabilities concerning false positives Examples -------- >>> thresh = ThresholdStatistics() >>> thresh.inputs.spm_mat_file = 'SPM.mat' >>> thresh.inputs.stat_image = 'spmT_0001.img' >>> thresh.inputs.contrast_index = 1 >>> thresh.inputs.height_threshold = 4.56 >>> thresh.run() # doctest: +SKIP ''' input_spec = ThresholdStatisticsInputSpec output_spec = ThresholdStatisticsOutputSpec def _make_matlab_command(self, _): script = "con_index = %d;\n" % self.inputs.contrast_index script += "cluster_forming_thr = %f;\n" % self.inputs.height_threshold script += "stat_filename = '%s';\n" % self.inputs.stat_image script += "extent_threshold = %d;\n" % self.inputs.extent_threshold script += "load '%s'\n" % self.inputs.spm_mat_file script += """ FWHM = SPM.xVol.FWHM; df = [SPM.xCon(con_index).eidf SPM.xX.erdf]; STAT = SPM.xCon(con_index).STAT; R = SPM.xVol.R; S = SPM.xVol.S; n = 1; voxelwise_P_Bonf = spm_P_Bonf(cluster_forming_thr,df,STAT,S,n) voxelwise_P_RF = spm_P_RF(1,0,cluster_forming_thr,df,STAT,R,n) stat_map_vol = spm_vol(stat_filename); [stat_map_data, stat_map_XYZmm] = spm_read_vols(stat_map_vol); Z = stat_map_data(:); Zum = Z; switch STAT case 'Z' VPs = (1-spm_Ncdf(Zum)).^n; voxelwise_P_uncor = (1-spm_Ncdf(cluster_forming_thr)).^n case 'T' VPs = (1 - spm_Tcdf(Zum,df(2))).^n; voxelwise_P_uncor = (1 - spm_Tcdf(cluster_forming_thr,df(2))).^n case 'X' VPs = (1-spm_Xcdf(Zum,df(2))).^n; voxelwise_P_uncor = (1-spm_Xcdf(cluster_forming_thr,df(2))).^n case 'F' VPs = (1 - spm_Fcdf(Zum,df)).^n; voxelwise_P_uncor = (1 - spm_Fcdf(cluster_forming_thr,df)).^n end VPs = sort(VPs); voxelwise_P_FDR = spm_P_FDR(cluster_forming_thr,df,STAT,n,VPs) V2R = 1/prod(FWHM(stat_map_vol.dim > 1)); clusterwise_P_RF = spm_P_RF(1,extent_threshold*V2R,cluster_forming_thr,df,STAT,R,n) [x,y,z] = ind2sub(size(stat_map_data),(1:numel(stat_map_data))'); XYZ = cat(1, x', y', z'); [u, CPs, ue] = spm_uc_clusterFDR(0.05,df,STAT,R,n,Z,XYZ,V2R,cluster_forming_thr); clusterwise_P_FDR = spm_P_clusterFDR(extent_threshold*V2R,df,STAT,R,n,cluster_forming_thr,CPs') """ return script def aggregate_outputs(self, runtime=None, needed_outputs=None): outputs = self._outputs() cur_output = "" for line in runtime.stdout.split('\n'): if cur_output != "" and len(line.split()) != 0: setattr(outputs, cur_output, float(line)) cur_output = "" continue if len(line.split()) != 0 and line.split()[0] in ["clusterwise_P_FDR", "clusterwise_P_RF", "voxelwise_P_Bonf", "voxelwise_P_FDR", "voxelwise_P_RF", "voxelwise_P_uncor"]: cur_output = line.split()[0] continue return outputs class FactorialDesignInputSpec(SPMCommandInputSpec): spm_mat_dir = Directory(exists=True, field='dir', desc='directory to store SPM.mat file (opt)') # really need to make an alias of InputMultiPath because the inputs below are not Path covariates = InputMultiPath(traits.Dict(key_trait=traits.Enum('vector', 'name', 'interaction', 'centering')), field='cov', desc='covariate dictionary {vector, name, interaction, centering}') threshold_mask_none = traits.Bool(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], desc='do not use threshold masking') threshold_mask_absolute = traits.Float(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], desc='use an absolute threshold') threshold_mask_relative = traits.Float(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], desc='threshold using a proportion of the global value') use_implicit_threshold = traits.Bool(field='masking.im', desc='use implicit mask NaNs or zeros to threshold') explicit_mask_file = File(field='masking.em', #requires cell desc='use an implicit mask file to threshold') global_calc_omit = traits.Bool(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], desc='omit global calculation') global_calc_mean = traits.Bool(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], desc='use mean for global calculation') global_calc_values = traits.List(traits.Float, field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], desc='omit global calculation') no_grand_mean_scaling = traits.Bool(field='globalm.gmsca.gmsca_no', desc='do not perform grand mean scaling') global_normalization = traits.Enum(1, 2, 3, field='globalm.glonorm', desc='global normalization None-1, Proportional-2, ANCOVA-3') class FactorialDesignOutputSpec(TraitedSpec): spm_mat_file = File(exists=True, desc='SPM mat file') class FactorialDesign(SPMCommand): """Base class for factorial designs http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=77 """ input_spec = FactorialDesignInputSpec output_spec = FactorialDesignOutputSpec _jobtype = 'stats' _jobname = 'factorial_design' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['spm_mat_dir', 'explicit_mask_file']: return np.array([str(val)], dtype=object) if opt in ['covariates']: outlist = [] mapping = {'name': 'cname', 'vector': 'c', 'interaction': 'iCFI', 'centering': 'iCC'} for dictitem in val: outdict = {} for key, keyval in dictitem.items(): outdict[mapping[key]] = keyval outlist.append(outdict) return outlist return super(FactorialDesign, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm realign options if set to None ignore """ einputs = super(FactorialDesign, self)._parse_inputs() if not isdefined(self.inputs.spm_mat_dir): einputs[0]['dir'] = np.array([str(os.getcwd())], dtype=object) return einputs def _list_outputs(self): outputs = self._outputs().get() spm = os.path.join(os.getcwd(), 'SPM.mat') outputs['spm_mat_file'] = spm return outputs class OneSampleTTestDesignInputSpec(FactorialDesignInputSpec): in_files = traits.List(File(exists=True), field='des.t1.scans', mandatory=True, minlen=2, desc='input files') class OneSampleTTestDesign(FactorialDesign): """Create SPM design for one sample t-test Examples -------- >>> ttest = OneSampleTTestDesign() >>> ttest.inputs.in_files = ['cont1.nii', 'cont2.nii'] >>> ttest.run() # doctest: +SKIP """ input_spec = OneSampleTTestDesignInputSpec def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['in_files']: return np.array(val, dtype=object) return super(OneSampleTTestDesign, self)._format_arg(opt, spec, val) class TwoSampleTTestDesignInputSpec(FactorialDesignInputSpec): # very unlikely that you will have a single image in one group, so setting # parameters to require at least two files in each group [SG] group1_files = traits.List(File(exists=True), field='des.t2.scans1', mandatory=True, minlen=2, desc='Group 1 input files') group2_files = traits.List(File(exists=True), field='des.t2.scans2', mandatory=True, minlen=2, desc='Group 2 input files') dependent = traits.Bool(field='des.t2.dept', desc='Are the measurements dependent between levels') unequal_variance = traits.Bool(field='des.t2.variance', desc='Are the variances equal or unequal between groups') class TwoSampleTTestDesign(FactorialDesign): """Create SPM design for two sample t-test Examples -------- >>> ttest = TwoSampleTTestDesign() >>> ttest.inputs.group1_files = ['cont1.nii', 'cont2.nii'] >>> ttest.inputs.group2_files = ['cont1a.nii', 'cont2a.nii'] >>> ttest.run() # doctest: +SKIP """ input_spec = TwoSampleTTestDesignInputSpec def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['group1_files', 'group2_files']: return np.array(val, dtype=object) return super(TwoSampleTTestDesign, self)._format_arg(opt, spec, val) class PairedTTestDesignInputSpec(FactorialDesignInputSpec): paired_files = traits.List(traits.List(File(exists=True), minlen=2, maxlen=2), field='des.pt.pair', mandatory=True, minlen=2, desc='List of paired files') grand_mean_scaling = traits.Bool(field='des.pt.gmsca', desc='Perform grand mean scaling') ancova = traits.Bool(field='des.pt.ancova', desc='Specify ancova-by-factor regressors') class PairedTTestDesign(FactorialDesign): """Create SPM design for paired t-test Examples -------- >>> pttest = PairedTTestDesign() >>> pttest.inputs.paired_files = [['cont1.nii','cont1a.nii'],['cont2.nii','cont2a.nii']] >>> pttest.run() # doctest: +SKIP """ input_spec = PairedTTestDesignInputSpec def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['paired_files']: return [dict(scans=np.array(files, dtype=object)) for files in val] return super(PairedTTestDesign, self)._format_arg(opt, spec, val) class MultipleRegressionDesignInputSpec(FactorialDesignInputSpec): in_files = traits.List(File(exists=True), field='des.mreg.scans', mandatory=True, minlen=2, desc='List of files') include_intercept = traits.Bool(True, field='des.mreg.incint', usedefault=True, desc='Include intercept in design') user_covariates = InputMultiPath(traits.Dict(key_trait=traits.Enum('vector', 'name', 'centering')), field='des.mreg.mcov', desc='covariate dictionary {vector, name, centering}') class MultipleRegressionDesign(FactorialDesign): """Create SPM design for multiple regression Examples -------- >>> mreg = MultipleRegressionDesign() >>> mreg.inputs.in_files = ['cont1.nii','cont2.nii'] >>> mreg.run() # doctest: +SKIP """ input_spec = MultipleRegressionDesignInputSpec def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['in_files']: return np.array(val, dtype=object) if opt in ['user_covariates']: outlist = [] mapping = {'name': 'cname', 'vector': 'c', 'centering': 'iCC'} for dictitem in val: outdict = {} for key, keyval in dictitem.items(): outdict[mapping[key]] = keyval outlist.append(outdict) return outlist return super(MultipleRegressionDesign, self)._format_arg(opt, spec, val) nipype-0.11.0/nipype/interfaces/spm/preprocess.py000066400000000000000000002264401257611314500220770ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """SPM wrappers for preprocessing data Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ __docformat__ = 'restructuredtext' # Standard library imports from copy import deepcopy import os # Third-party imports import numpy as np # Local imports from nipype.interfaces.base import (OutputMultiPath, TraitedSpec, isdefined, traits, InputMultiPath, File) from nipype.interfaces.spm.base import (SPMCommand, scans_for_fname, func_is_3d, Info, scans_for_fnames, SPMCommandInputSpec) from nipype.utils.filemanip import (fname_presuffix, filename_to_list, list_to_filename, split_filename) class SliceTimingInputSpec(SPMCommandInputSpec): in_files = InputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), field='scans', desc='list of filenames to apply slice timing', mandatory=True, copyfile=False) num_slices = traits.Int(field='nslices', desc='number of slices in a volume', mandatory=True) time_repetition = traits.Float(field='tr', desc=('time between volume acquisitions' '(start to start time)'), mandatory=True) time_acquisition = traits.Float(field='ta', desc=('time of volume acquisition. usually' 'calculated as TR-(TR/num_slices)'), mandatory=True) slice_order = traits.List(traits.Int(), field='so', desc='1-based order in which slices are acquired', mandatory=True) ref_slice = traits.Int(field='refslice', desc='1-based Number of the reference slice', mandatory=True) out_prefix = traits.String('a', field='prefix', usedefault=True, desc='slicetimed output prefix') class SliceTimingOutputSpec(TraitedSpec): timecorrected_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), desc='slice time corrected files') class SliceTiming(SPMCommand): """Use spm to perform slice timing correction. http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=19 Examples -------- >>> from nipype.interfaces.spm import SliceTiming >>> st = SliceTiming() >>> st.inputs.in_files = 'functional.nii' >>> st.inputs.num_slices = 32 >>> st.inputs.time_repetition = 6.0 >>> st.inputs.time_acquisition = 6. - 6./32. >>> st.inputs.slice_order = range(32,0,-1) >>> st.inputs.ref_slice = 1 >>> st.run() # doctest: +SKIP """ input_spec = SliceTimingInputSpec output_spec = SliceTimingOutputSpec _jobtype = 'temporal' _jobname = 'st' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': return scans_for_fnames(filename_to_list(val), keep4d=False, separate_sessions=True) return super(SliceTiming, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['timecorrected_files'] = [] filelist = filename_to_list(self.inputs.in_files) for f in filelist: if isinstance(f, list): run = [fname_presuffix(in_f, prefix=self.inputs.out_prefix) for in_f in f] else: run = fname_presuffix(f, prefix=self.inputs.out_prefix) outputs['timecorrected_files'].append(run) return outputs class RealignInputSpec(SPMCommandInputSpec): in_files = InputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), field='data', mandatory=True, copyfile=True, desc='list of filenames to realign') jobtype = traits.Enum('estwrite', 'estimate', 'write', desc='one of: estimate, write, estwrite', usedefault=True) quality = traits.Range(low=0.0, high=1.0, field='eoptions.quality', desc='0.1 = fast, 1.0 = precise') fwhm = traits.Range(low=0.0, field='eoptions.fwhm', desc='gaussian smoothing kernel width') separation = traits.Range(low=0.0, field='eoptions.sep', desc='sampling separation in mm') register_to_mean = traits.Bool(field='eoptions.rtm', desc='Indicate whether realignment is done to the mean image') weight_img = File(exists=True, field='eoptions.weight', desc='filename of weighting image') interp = traits.Range(low=0, high=7, field='eoptions.interp', desc='degree of b-spline used for interpolation') wrap = traits.List(traits.Int(), minlen=3, maxlen=3, field='eoptions.wrap', desc='Check if interpolation should wrap in [x,y,z]') write_which = traits.ListInt([2, 1], field='roptions.which', minlen=2, maxlen=2, usedefault=True, desc='determines which images to reslice') write_interp = traits.Range(low=0, high=7, field='roptions.interp', desc='degree of b-spline used for interpolation') write_wrap = traits.List(traits.Int(), minlen=3, maxlen=3, field='roptions.wrap', desc='Check if interpolation should wrap in [x,y,z]') write_mask = traits.Bool(field='roptions.mask', desc='True/False mask output image') out_prefix = traits.String('r', field='roptions.prefix', usedefault=True, desc='realigned output prefix') class RealignOutputSpec(TraitedSpec): mean_image = File(exists=True, desc='Mean image file from the realignment') modified_in_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), desc='Copies of all files passed to in_files.\ Headers will have been modified to align all\ images with the first, or optionally to first\ do that, extract a mean image, and re-align to\ that mean image.') realigned_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)), File(exists=True)), desc='If jobtype is write or estwrite, these will be the\ resliced files. Otherwise, they will be copies of\ in_files that have had their headers rewritten.') realignment_parameters = OutputMultiPath(File(exists=True), desc='Estimated translation and rotation parameters') class Realign(SPMCommand): """Use spm_realign for estimating within modality rigid body alignment http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=25 Examples -------- >>> import nipype.interfaces.spm as spm >>> realign = spm.Realign() >>> realign.inputs.in_files = 'functional.nii' >>> realign.inputs.register_to_mean = True >>> realign.run() # doctest: +SKIP """ input_spec = RealignInputSpec output_spec = RealignOutputSpec _jobtype = 'spatial' _jobname = 'realign' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': if self.inputs.jobtype == "write": separate_sessions = False else: separate_sessions = True return scans_for_fnames(val, keep4d=False, separate_sessions=separate_sessions) return super(Realign, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm realign options if set to None ignore """ einputs = super(Realign, self)._parse_inputs() return [{'%s' % (self.inputs.jobtype): einputs[0]}] def _list_outputs(self): outputs = self._outputs().get() resliced_all = self.inputs.write_which[0] > 0 resliced_mean = self.inputs.write_which[1] > 0 if self.inputs.jobtype != "write": if isdefined(self.inputs.in_files): outputs['realignment_parameters'] = [] for imgf in self.inputs.in_files: if isinstance(imgf, list): tmp_imgf = imgf[0] else: tmp_imgf = imgf outputs['realignment_parameters'].append(fname_presuffix(tmp_imgf, prefix='rp_', suffix='.txt', use_ext=False)) if not isinstance(imgf, list) and func_is_3d(imgf): break if self.inputs.jobtype == "estimate": outputs['realigned_files'] = self.inputs.in_files if self.inputs.jobtype == "estimate" or self.inputs.jobtype == "estwrite": outputs['modified_in_files'] = self.inputs.in_files if self.inputs.jobtype == "write" or self.inputs.jobtype == "estwrite": if isinstance(self.inputs.in_files[0], list): first_image = self.inputs.in_files[0][0] else: first_image = self.inputs.in_files[0] if resliced_mean: outputs['mean_image'] = fname_presuffix(first_image, prefix='mean') if resliced_all: outputs['realigned_files'] = [] for idx, imgf in enumerate(filename_to_list(self.inputs.in_files)): realigned_run = [] if isinstance(imgf, list): for i, inner_imgf in enumerate(filename_to_list(imgf)): newfile = fname_presuffix(inner_imgf, prefix=self.inputs.out_prefix) realigned_run.append(newfile) else: realigned_run = fname_presuffix(imgf, prefix=self.inputs.out_prefix) outputs['realigned_files'].append(realigned_run) return outputs class CoregisterInputSpec(SPMCommandInputSpec): target = File(exists=True, field='ref', mandatory=True, desc='reference file to register to', copyfile=False) source = InputMultiPath(File(exists=True), field='source', desc='file to register to target', copyfile=True, mandatory=True) jobtype = traits.Enum('estwrite', 'estimate', 'write', desc='one of: estimate, write, estwrite', usedefault=True) apply_to_files = InputMultiPath(File(exists=True), field='other', desc='files to apply transformation to', copyfile=True) cost_function = traits.Enum('mi', 'nmi', 'ecc', 'ncc', field='eoptions.cost_fun', desc="""cost function, one of: 'mi' - Mutual Information, 'nmi' - Normalised Mutual Information, 'ecc' - Entropy Correlation Coefficient, 'ncc' - Normalised Cross Correlation""") fwhm = traits.List(traits.Float(), minlen=2, maxlen=2, field='eoptions.fwhm', desc='gaussian smoothing kernel width (mm)') separation = traits.List(traits.Float(), field='eoptions.sep', desc='sampling separation in mm') tolerance = traits.List(traits.Float(), field='eoptions.tol', desc='acceptable tolerance for each of 12 params') write_interp = traits.Range(low=0, high=7, field='roptions.interp', desc='degree of b-spline used for interpolation') write_wrap = traits.List(traits.Int(), minlen=3, maxlen=3, field='roptions.wrap', desc='Check if interpolation should wrap in [x,y,z]') write_mask = traits.Bool(field='roptions.mask', desc='True/False mask output image') out_prefix = traits.String('r', field='roptions.prefix', usedefault=True, desc='coregistered output prefix') class CoregisterOutputSpec(TraitedSpec): coregistered_source = OutputMultiPath(File(exists=True), desc='Coregistered source files') coregistered_files = OutputMultiPath(File(exists=True), desc='Coregistered other files') class Coregister(SPMCommand): """Use spm_coreg for estimating cross-modality rigid body alignment http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=39 Examples -------- >>> import nipype.interfaces.spm as spm >>> coreg = spm.Coregister() >>> coreg.inputs.target = 'functional.nii' >>> coreg.inputs.source = 'structural.nii' >>> coreg.run() # doctest: +SKIP """ input_spec = CoregisterInputSpec output_spec = CoregisterOutputSpec _jobtype = 'spatial' _jobname = 'coreg' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'target' or (opt == 'source' and self.inputs.jobtype != "write"): return scans_for_fnames(filename_to_list(val), keep4d=True) if opt == 'apply_to_files': return np.array(filename_to_list(val), dtype=object) if opt == 'source' and self.inputs.jobtype == "write": if isdefined(self.inputs.apply_to_files): return scans_for_fnames(val+self.inputs.apply_to_files) else: return scans_for_fnames(val) return super(Coregister, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm coregister options if set to None ignore """ if self.inputs.jobtype == "write": einputs = super(Coregister, self)._parse_inputs(skip=('jobtype', 'apply_to_files')) else: einputs = super(Coregister, self)._parse_inputs(skip=('jobtype')) jobtype = self.inputs.jobtype return [{'%s' % (jobtype): einputs[0]}] def _list_outputs(self): outputs = self._outputs().get() if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs['coregistered_files'] = self.inputs.apply_to_files outputs['coregistered_source'] = self.inputs.source elif self.inputs.jobtype == "write" or self.inputs.jobtype == "estwrite": if isdefined(self.inputs.apply_to_files): outputs['coregistered_files'] = [] for imgf in filename_to_list(self.inputs.apply_to_files): outputs['coregistered_files'].append(fname_presuffix(imgf, prefix=self.inputs.out_prefix)) outputs['coregistered_source'] = [] for imgf in filename_to_list(self.inputs.source): outputs['coregistered_source'].append(fname_presuffix(imgf, prefix=self.inputs.out_prefix)) return outputs class NormalizeInputSpec(SPMCommandInputSpec): template = File(exists=True, field='eoptions.template', desc='template file to normalize to', mandatory=True, xor=['parameter_file'], copyfile=False) source = InputMultiPath(File(exists=True), field='subj.source', desc='file to normalize to template', xor=['parameter_file'], mandatory=True, copyfile=True) jobtype = traits.Enum('estwrite', 'est', 'write', usedefault=True, desc='Estimate, Write or do both') apply_to_files = InputMultiPath(traits.Either(File(exists=True), traits.List(File(exists=True))), field='subj.resample', desc='files to apply transformation to', copyfile=True) parameter_file = File(field='subj.matname', mandatory=True, xor=['source', 'template'], desc='normalization parameter file*_sn.mat', copyfile=False) source_weight = File(field='subj.wtsrc', desc='name of weighting image for source', copyfile=False) template_weight = File(field='eoptions.weight', desc='name of weighting image for template', copyfile=False) source_image_smoothing = traits.Float(field='eoptions.smosrc', desc='source smoothing') template_image_smoothing = traits.Float(field='eoptions.smoref', desc='template smoothing') affine_regularization_type = traits.Enum('mni', 'size', 'none', field='eoptions.regtype', desc='mni, size, none') DCT_period_cutoff = traits.Float(field='eoptions.cutoff', desc='Cutoff of for DCT bases') nonlinear_iterations = traits.Int(field='eoptions.nits', desc='Number of iterations of nonlinear warping') nonlinear_regularization = traits.Float(field='eoptions.reg', desc='the amount of the regularization for the nonlinear part of the normalization') write_preserve = traits.Bool(field='roptions.preserve', desc='True/False warped images are modulated') write_bounding_box = traits.List(traits.List(traits.Float(), minlen=3, maxlen=3), field='roptions.bb', minlen=2, maxlen=2, desc='3x2-element list of lists') write_voxel_sizes = traits.List(traits.Float(), field='roptions.vox', minlen=3, maxlen=3, desc='3-element list') write_interp = traits.Range(low=0, high=7, field='roptions.interp', desc='degree of b-spline used for interpolation') write_wrap = traits.List(traits.Int(), field='roptions.wrap', desc=('Check if interpolation should wrap in [x,y,z]' '- list of bools')) out_prefix = traits.String('w', field='roptions.prefix', usedefault=True, desc='normalized output prefix') class NormalizeOutputSpec(TraitedSpec): normalization_parameters = OutputMultiPath(File(exists=True), desc='MAT files containing the normalization parameters') normalized_source = OutputMultiPath(File(exists=True), desc='Normalized source files') normalized_files = OutputMultiPath(File(exists=True), desc='Normalized other files') class Normalize(SPMCommand): """use spm_normalise for warping an image to a template http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=203 Examples -------- >>> import nipype.interfaces.spm as spm >>> norm = spm.Normalize() >>> norm.inputs.source = 'functional.nii' >>> norm.run() # doctest: +SKIP """ input_spec = NormalizeInputSpec output_spec = NormalizeOutputSpec _jobtype = 'spatial' _jobname = 'normalise' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'template': return scans_for_fname(filename_to_list(val)) if opt == 'source': return scans_for_fname(filename_to_list(val)) if opt == 'apply_to_files': return scans_for_fnames(filename_to_list(val)) if opt == 'parameter_file': return np.array([list_to_filename(val)], dtype=object) if opt in ['write_wrap']: if len(val) != 3: raise ValueError('%s must have 3 elements' % opt) return super(Normalize, self)._format_arg(opt, spec, val) def _parse_inputs(self): """validate spm normalize options if set to None ignore """ einputs = super(Normalize, self)._parse_inputs(skip=('jobtype', 'apply_to_files')) if isdefined(self.inputs.apply_to_files): inputfiles = deepcopy(self.inputs.apply_to_files) if isdefined(self.inputs.source): inputfiles.extend(self.inputs.source) einputs[0]['subj']['resample'] = scans_for_fnames(inputfiles) jobtype = self.inputs.jobtype if jobtype in ['estwrite', 'write']: if not isdefined(self.inputs.apply_to_files): if isdefined(self.inputs.source): einputs[0]['subj']['resample'] = scans_for_fname(self.inputs.source) return [{'%s' % (jobtype): einputs[0]}] def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype.startswith('est'): outputs['normalization_parameters'] = [] for imgf in filename_to_list(self.inputs.source): outputs['normalization_parameters'].append(fname_presuffix(imgf, suffix='_sn.mat', use_ext=False)) outputs['normalization_parameters'] = list_to_filename(outputs['normalization_parameters']) if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs['normalized_files'] = self.inputs.apply_to_files outputs['normalized_source'] = self.inputs.source elif 'write' in self.inputs.jobtype: if isdefined(self.inputs.write_preserve) and self.inputs.write_preserve: prefixNorm = ''.join(['m', self.inputs.out_prefix]) else: prefixNorm = self.inputs.out_prefix outputs['normalized_files'] = [] if isdefined(self.inputs.apply_to_files): filelist = filename_to_list(self.inputs.apply_to_files) for f in filelist: if isinstance(f, list): run = [fname_presuffix(in_f, prefix=prefixNorm) for in_f in f] else: run = [fname_presuffix(f, prefix=prefixNorm)] outputs['normalized_files'].extend(run) if isdefined(self.inputs.source): outputs['normalized_source'] = [] for imgf in filename_to_list(self.inputs.source): outputs['normalized_source'].append(fname_presuffix(imgf, prefix=prefixNorm)) return outputs class Normalize12InputSpec(SPMCommandInputSpec): image_to_align = File(exists=True, field='subj.vol', desc='file to estimate normalization parameters with', xor=['deformation_file'], mandatory=True, copyfile=True) apply_to_files = InputMultiPath(traits.Either(File(exists=True), traits.List(File(exists=True))), field='subj.resample', desc='files to apply transformation to', copyfile=True) deformation_file = File(field='subj.def', mandatory=True, xor=['image_to_align', 'tpm'], desc=('file y_*.nii containing 3 deformation fields ' 'for the deformation in x, y and z dimension'), copyfile=False) jobtype = traits.Enum('estwrite', 'est', 'write', usedefault=True, desc='Estimate, Write or do Both') bias_regularization = traits.Enum(0, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, field='eoptions.biasreg', desc='no(0) - extremely heavy (10)') bias_fwhm = traits.Enum(30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 'Inf', field='eoptions.biasfwhm', desc='FWHM of Gaussian smoothness of bias') tpm = File(exists=True, field='eoptions.tpm', desc='template in form of tissue probablitiy maps to normalize to', xor=['deformation_file'], copyfile=False) affine_regularization_type = traits.Enum('mni', 'size', 'none', field='eoptions.affreg', desc='mni, size, none') warping_regularization = traits.List(traits.Float(), field='eoptions.reg', minlen=5, maxlen=5, desc=('controls balance between ' 'parameters and data')) smoothness = traits.Float(field='eoptions.fwhm', desc=('value (in mm) to smooth the data before ' 'normalization')) sampling_distance = traits.Float(field='eoptions.samp', desc=('Sampling distance on data for ' 'parameter estimation')) write_bounding_box = traits.List(traits.List(traits.Float(), minlen=3, maxlen=3), field='woptions.bb', minlen=2, maxlen=2, desc=('3x2-element list of lists representing ' 'the bounding box (in mm) to be written')) write_voxel_sizes = traits.List(traits.Float(), field='woptions.vox', minlen=3, maxlen=3, desc=('3-element list representing the ' 'voxel sizes (in mm) of the written ' 'normalised images')) write_interp = traits.Range(low=0, high=7, field='woptions.interp', desc='degree of b-spline used for interpolation') class Normalize12OutputSpec(TraitedSpec): deformation_field = OutputMultiPath(File(exists=True), desc=('NIfTI file containing 3 deformation ' 'fields for the deformation in ' 'x, y and z dimension')) normalized_image = OutputMultiPath(File(exists=True), desc=('Normalized file that needed to ' 'be aligned')) normalized_files = OutputMultiPath(File(exists=True), desc='Normalized other files') class Normalize12(SPMCommand): """uses SPM12's new Normalise routine for warping an image to a template. Spatial normalisation is now done via the segmentation routine (which was known as ``New Segment`` in SPM8). Note that the normalisation in SPM12 is done towards a file containing multiple tissue probability maps, which was not the cass in SPM8. http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=49 Examples -------- >>> import nipype.interfaces.spm as spm >>> norm12 = spm.Normalize12() >>> norm12.inputs.image_to_align = 'structural.nii' >>> norm12.inputs.apply_to_files = 'functional.nii' >>> norm12.run() # doctest: +SKIP """ input_spec = Normalize12InputSpec output_spec = Normalize12OutputSpec _jobtype = 'spatial' _jobname = 'normalise' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'tpm': return scans_for_fname(filename_to_list(val)) if opt == 'image_to_align': return scans_for_fname(filename_to_list(val)) if opt == 'apply_to_files': return scans_for_fnames(filename_to_list(val)) if opt == 'deformation_file': return np.array([list_to_filename(val)], dtype=object) if opt in ['nonlinear_regularization']: if len(val) != 5: raise ValueError('%s must have 5 elements' % opt) return super(Normalize12, self)._format_arg(opt, spec, val) def _parse_inputs(self, skip=()): """validate spm normalize options if set to None ignore """ einputs = super(Normalize12, self)._parse_inputs(skip=('jobtype', 'apply_to_files')) if isdefined(self.inputs.apply_to_files): inputfiles = deepcopy(self.inputs.apply_to_files) if isdefined(self.inputs.image_to_align): inputfiles.extend([self.inputs.image_to_align]) einputs[0]['subj']['resample'] = scans_for_fnames(inputfiles) jobtype = self.inputs.jobtype if jobtype in ['estwrite', 'write']: if not isdefined(self.inputs.apply_to_files): if isdefined(self.inputs.image_to_align): einputs[0]['subj']['resample'] = scans_for_fname(self.inputs.image_to_align) return [{'%s' % (jobtype): einputs[0]}] def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype.startswith('est'): outputs['deformation_field'] = [] for imgf in filename_to_list(self.inputs.image_to_align): outputs['deformation_field'].append(fname_presuffix(imgf, prefix='y_')) outputs['deformation_field'] = list_to_filename(outputs['deformation_field']) if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs['normalized_files'] = self.inputs.apply_to_files outputs['normalized_image'] = fname_presuffix(self.inputs.image_to_align, prefix='w') elif 'write' in self.inputs.jobtype: outputs['normalized_files'] = [] if isdefined(self.inputs.apply_to_files): filelist = filename_to_list(self.inputs.apply_to_files) for f in filelist: if isinstance(f, list): run = [fname_presuffix(in_f, prefix='w') for in_f in f] else: run = [fname_presuffix(f, prefix='w')] outputs['normalized_files'].extend(run) if isdefined(self.inputs.image_to_align): outputs['normalized_image'] = fname_presuffix(self.inputs.image_to_align, prefix='w') return outputs class SegmentInputSpec(SPMCommandInputSpec): data = InputMultiPath(File(exists=True), field='data', desc='one scan per subject', copyfile=False, mandatory=True) gm_output_type = traits.List(traits.Bool(), minlen=3, maxlen=3, field='output.GM', desc="""Options to produce grey matter images: c1*.img, wc1*.img and mwc1*.img. None: [False,False,False], Native Space: [False,False,True], Unmodulated Normalised: [False,True,False], Modulated Normalised: [True,False,False], Native + Unmodulated Normalised: [False,True,True], Native + Modulated Normalised: [True,False,True], Native + Modulated + Unmodulated: [True,True,True], Modulated + Unmodulated Normalised: [True,True,False]""") wm_output_type = traits.List(traits.Bool(), minlen=3, maxlen=3, field='output.WM', desc="""Options to produce white matter images: c2*.img, wc2*.img and mwc2*.img. None: [False,False,False], Native Space: [False,False,True], Unmodulated Normalised: [False,True,False], Modulated Normalised: [True,False,False], Native + Unmodulated Normalised: [False,True,True], Native + Modulated Normalised: [True,False,True], Native + Modulated + Unmodulated: [True,True,True], Modulated + Unmodulated Normalised: [True,True,False]""") csf_output_type = traits.List(traits.Bool(), minlen=3, maxlen=3, field='output.CSF', desc="""Options to produce CSF images: c3*.img, wc3*.img and mwc3*.img. None: [False,False,False], Native Space: [False,False,True], Unmodulated Normalised: [False,True,False], Modulated Normalised: [True,False,False], Native + Unmodulated Normalised: [False,True,True], Native + Modulated Normalised: [True,False,True], Native + Modulated + Unmodulated: [True,True,True], Modulated + Unmodulated Normalised: [True,True,False]""") save_bias_corrected = traits.Bool(field='output.biascor', desc='True/False produce a bias corrected image') clean_masks = traits.Enum('no', 'light', 'thorough', field='output.cleanup', desc="clean using estimated brain mask ('no','light','thorough')") tissue_prob_maps = traits.List(File(exists=True), field='opts.tpm', desc='list of gray, white & csf prob. (opt,)') gaussians_per_class = traits.List(traits.Int(), field='opts.ngaus', desc='num Gaussians capture intensity distribution') affine_regularization = traits.Enum('mni', 'eastern', 'subj', 'none', '', field='opts.regtype', desc='Possible options: "mni", "eastern", "subj", "none" (no reguralisation), "" (no affine registration)') warping_regularization = traits.Float(field='opts.warpreg', desc='Controls balance between parameters and data') warp_frequency_cutoff = traits.Float(field='opts.warpco', desc='Cutoff of DCT bases') bias_regularization = traits.Enum(0, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, field='opts.biasreg', desc='no(0) - extremely heavy (10)') bias_fwhm = traits.Enum(30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 'Inf', field='opts.biasfwhm', desc='FWHM of Gaussian smoothness of bias') sampling_distance = traits.Float(field='opts.samp', desc='Sampling distance on data for parameter estimation') mask_image = File(exists=True, field='opts.msk', desc='Binary image to restrict parameter estimation ') class SegmentOutputSpec(TraitedSpec): native_gm_image = File(desc='native space grey probability map') normalized_gm_image = File(desc='normalized grey probability map',) modulated_gm_image = File(desc='modulated, normalized grey probability map') native_wm_image = File(desc='native space white probability map') normalized_wm_image = File(desc='normalized white probability map') modulated_wm_image = File(desc='modulated, normalized white probability map') native_csf_image = File(desc='native space csf probability map') normalized_csf_image = File(desc='normalized csf probability map') modulated_csf_image = File(desc='modulated, normalized csf probability map') modulated_input_image = File(deprecated='0.10', new_name='bias_corrected_image', desc='bias-corrected version of input image') bias_corrected_image = File(desc='bias-corrected version of input image') transformation_mat = File(exists=True, desc='Normalization transformation') inverse_transformation_mat = File(exists=True, desc='Inverse normalization info') class Segment(SPMCommand): """use spm_segment to separate structural images into different tissue classes. http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=209 Examples -------- >>> import nipype.interfaces.spm as spm >>> seg = spm.Segment() >>> seg.inputs.data = 'structural.nii' >>> seg.run() # doctest: +SKIP """ input_spec = SegmentInputSpec output_spec = SegmentOutputSpec def __init__(self, **inputs): _local_version = SPMCommand().version if _local_version and '12.' in _local_version: self._jobtype = 'tools' self._jobname = 'oldseg' else: self._jobtype = 'spatial' self._jobname = 'preproc' SPMCommand.__init__(self, **inputs) def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ clean_masks_dict = {'no': 0, 'light': 1, 'thorough': 2} if opt in ['data', 'tissue_prob_maps']: if isinstance(val, list): return scans_for_fnames(val) else: return scans_for_fname(val) if 'output_type' in opt: return [int(v) for v in val] if opt == 'mask_image': return scans_for_fname(val) if opt == 'clean_masks': return clean_masks_dict[val] return super(Segment, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() f = self.inputs.data[0] for tidx, tissue in enumerate(['gm', 'wm', 'csf']): outtype = '%s_output_type' % tissue if isdefined(getattr(self.inputs, outtype)): for idx, (image, prefix) in enumerate([('modulated', 'mw'), ('normalized', 'w'), ('native', '')]): if getattr(self.inputs, outtype)[idx]: outfield = '%s_%s_image' % (image, tissue) outputs[outfield] = fname_presuffix(f, prefix='%sc%d' % (prefix, tidx+1)) if isdefined(self.inputs.save_bias_corrected) and \ self.inputs.save_bias_corrected: outputs['bias_corrected_image'] = fname_presuffix(f, prefix='m') t_mat = fname_presuffix(f, suffix='_seg_sn.mat', use_ext=False) outputs['transformation_mat'] = t_mat invt_mat = fname_presuffix(f, suffix='_seg_inv_sn.mat', use_ext=False) outputs['inverse_transformation_mat'] = invt_mat return outputs class NewSegmentInputSpec(SPMCommandInputSpec): channel_files = InputMultiPath(File(exists=True), desc="A list of files to be segmented", field='channel', copyfile=False, mandatory=True) channel_info = traits.Tuple(traits.Float(), traits.Float(), traits.Tuple(traits.Bool, traits.Bool), desc="""A tuple with the following fields: - bias reguralisation (0-10) - FWHM of Gaussian smoothness of bias - which maps to save (Corrected, Field) - a tuple of two boolean values""", field='channel') tissues = traits.List(traits.Tuple(traits.Tuple(File(exists=True), traits.Int()), traits.Int(), traits.Tuple(traits.Bool, traits.Bool), traits.Tuple(traits.Bool, traits.Bool)), desc="""A list of tuples (one per tissue) with the following fields: - tissue probability map (4D), 1-based index to frame - number of gaussians - which maps to save [Native, DARTEL] - a tuple of two boolean values - which maps to save [Unmodulated, Modulated] - a tuple of two boolean values""", field='tissue') affine_regularization = traits.Enum('mni', 'eastern', 'subj', 'none', field='warp.affreg', desc='mni, eastern, subj, none ') warping_regularization = traits.Float(field='warp.reg', desc='Aproximate distance between sampling points.') sampling_distance = traits.Float(field='warp.samp', desc='Sampling distance on data for parameter estimation') write_deformation_fields = traits.List(traits.Bool(), minlen=2, maxlen=2, field='warp.write', desc="Which deformation fields to write:[Inverse, Forward]") class NewSegmentOutputSpec(TraitedSpec): native_class_images = traits.List(traits.List(File(exists=True)), desc='native space probability maps') dartel_input_images = traits.List(traits.List(File(exists=True)), desc='dartel imported class images') normalized_class_images = traits.List(traits.List(File(exists=True)), desc='normalized class images') modulated_class_images = traits.List(traits.List(File(exists=True)), desc='modulated+normalized class images') transformation_mat = OutputMultiPath(File(exists=True), desc='Normalization transformation') bias_corrected_images = OutputMultiPath(File(exists=True), desc='bias corrected images') bias_field_images = OutputMultiPath(File(exists=True), desc='bias field images') forward_deformation_field = OutputMultiPath(File(exists=True)) inverse_deformation_field = OutputMultiPath(File(exists=True)) class NewSegment(SPMCommand): """Use spm_preproc8 (New Segment) to separate structural images into different tissue classes. Supports multiple modalities. NOTE: This interface currently supports single channel input only http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=43 Examples -------- >>> import nipype.interfaces.spm as spm >>> seg = spm.NewSegment() >>> seg.inputs.channel_files = 'structural.nii' >>> seg.inputs.channel_info = (0.0001, 60, (True, True)) >>> seg.run() # doctest: +SKIP For VBM pre-processing [http://www.fil.ion.ucl.ac.uk/~john/misc/VBMclass10.pdf], TPM.nii should be replaced by /path/to/spm8/toolbox/Seg/TPM.nii >>> seg = NewSegment() >>> seg.inputs.channel_files = 'structural.nii' >>> tissue1 = (('TPM.nii', 1), 2, (True,True), (False, False)) >>> tissue2 = (('TPM.nii', 2), 2, (True,True), (False, False)) >>> tissue3 = (('TPM.nii', 3), 2, (True,False), (False, False)) >>> tissue4 = (('TPM.nii', 4), 2, (False,False), (False, False)) >>> tissue5 = (('TPM.nii', 5), 2, (False,False), (False, False)) >>> seg.inputs.tissues = [tissue1, tissue2, tissue3, tissue4, tissue5] >>> seg.run() # doctest: +SKIP """ input_spec = NewSegmentInputSpec output_spec = NewSegmentOutputSpec def __init__(self, **inputs): _local_version = SPMCommand().version if _local_version and '12.' in _local_version: self._jobtype = 'spatial' self._jobname = 'preproc' else: self._jobtype = 'tools' self._jobname = 'preproc8' SPMCommand.__init__(self, **inputs) def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['channel_files', 'channel_info']: # structure have to be recreated, because of some weird traits error new_channel = {} new_channel['vols'] = scans_for_fnames(self.inputs.channel_files) if isdefined(self.inputs.channel_info): info = self.inputs.channel_info new_channel['biasreg'] = info[0] new_channel['biasfwhm'] = info[1] new_channel['write'] = [int(info[2][0]), int(info[2][1])] return [new_channel] elif opt == 'tissues': new_tissues = [] for tissue in val: new_tissue = {} new_tissue['tpm'] = np.array([','.join([tissue[0][0], str(tissue[0][1])])], dtype=object) new_tissue['ngaus'] = tissue[1] new_tissue['native'] = [int(tissue[2][0]), int(tissue[2][1])] new_tissue['warped'] = [int(tissue[3][0]), int(tissue[3][1])] new_tissues.append(new_tissue) return new_tissues elif opt == 'write_deformation_fields': return super(NewSegment, self)._format_arg(opt, spec, [int(val[0]), int(val[1])]) else: return super(NewSegment, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['native_class_images'] = [] outputs['dartel_input_images'] = [] outputs['normalized_class_images'] = [] outputs['modulated_class_images'] = [] outputs['transformation_mat'] = [] outputs['bias_corrected_images'] = [] outputs['bias_field_images'] = [] outputs['inverse_deformation_field'] = [] outputs['forward_deformation_field'] = [] n_classes = 5 if isdefined(self.inputs.tissues): n_classes = len(self.inputs.tissues) for i in range(n_classes): outputs['native_class_images'].append([]) outputs['dartel_input_images'].append([]) outputs['normalized_class_images'].append([]) outputs['modulated_class_images'].append([]) for filename in self.inputs.channel_files: pth, base, ext = split_filename(filename) if isdefined(self.inputs.tissues): for i, tissue in enumerate(self.inputs.tissues): if tissue[2][0]: outputs['native_class_images'][i].append(os.path.join(pth, "c%d%s.nii" % (i+1, base))) if tissue[2][1]: outputs['dartel_input_images'][i].append(os.path.join(pth, "rc%d%s.nii" % (i+1, base))) if tissue[3][0]: outputs['normalized_class_images'][i].append(os.path.join(pth, "wc%d%s.nii" % (i+1, base))) if tissue[3][1]: outputs['modulated_class_images'][i].append(os.path.join(pth, "mwc%d%s.nii" % (i+1, base))) else: for i in range(n_classes): outputs['native_class_images'][i].append(os.path.join(pth, "c%d%s.nii" % (i+1, base))) outputs['transformation_mat'].append(os.path.join(pth, "%s_seg8.mat" % base)) if isdefined(self.inputs.write_deformation_fields): if self.inputs.write_deformation_fields[0]: outputs['inverse_deformation_field'].append(os.path.join(pth, "iy_%s.nii" % base)) if self.inputs.write_deformation_fields[1]: outputs['forward_deformation_field'].append(os.path.join(pth, "y_%s.nii" % base)) if isdefined(self.inputs.channel_info): if self.inputs.channel_info[2][0]: outputs['bias_corrected_images'].append(os.path.join(pth, "m%s.nii" % (base))) if self.inputs.channel_info[2][1]: outputs['bias_field_images'].append(os.path.join(pth, "BiasField_%s.nii" % (base))) return outputs class SmoothInputSpec(SPMCommandInputSpec): in_files = InputMultiPath(File(exists=True), field='data', desc='list of files to smooth', mandatory=True, copyfile=False) fwhm = traits.Either(traits.List(traits.Float(), minlen=3, maxlen=3), traits.Float(), field='fwhm', desc='3-list of fwhm for each dimension') data_type = traits.Int(field='dtype', desc='Data type of the output images') implicit_masking = traits.Bool(field='im', desc=('A mask implied by a particular' 'voxel value')) out_prefix = traits.String('s', field='prefix', usedefault=True, desc='smoothed output prefix') class SmoothOutputSpec(TraitedSpec): smoothed_files = OutputMultiPath(File(exists=True), desc='smoothed files') class Smooth(SPMCommand): """Use spm_smooth for 3D Gaussian smoothing of image volumes. http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=55 Examples -------- >>> import nipype.interfaces.spm as spm >>> smooth = spm.Smooth() >>> smooth.inputs.in_files = 'functional.nii' >>> smooth.inputs.fwhm = [4, 4, 4] >>> smooth.run() # doctest: +SKIP """ input_spec = SmoothInputSpec output_spec = SmoothOutputSpec _jobtype = 'spatial' _jobname = 'smooth' def _format_arg(self, opt, spec, val): if opt in ['in_files']: return scans_for_fnames(filename_to_list(val)) if opt == 'fwhm': if not isinstance(val, list): return [val, val, val] if isinstance(val, list): if len(val) == 1: return [val[0], val[0], val[0]] else: return val return super(Smooth, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['smoothed_files'] = [] for imgf in filename_to_list(self.inputs.in_files): outputs['smoothed_files'].append(fname_presuffix(imgf, prefix=self.inputs.out_prefix)) return outputs class DARTELInputSpec(SPMCommandInputSpec): image_files = traits.List(traits.List(File(exists=True)), desc="A list of files to be segmented", field='warp.images', copyfile=False, mandatory=True) template_prefix = traits.Str('Template', usedefault=True, field='warp.settings.template', desc='Prefix for template') regularization_form = traits.Enum('Linear', 'Membrane', 'Bending', field='warp.settings.rform', desc='Form of regularization energy term') iteration_parameters = traits.List(traits.Tuple(traits.Range(1, 10), traits.Tuple(traits.Float, traits.Float, traits.Float), traits.Enum(1, 2, 4, 8, 16, 32, 64, 128, 256, 512), traits.Enum(0, 0.5, 1, 2, 4, 8, 16, 32)), minlen=3, maxlen=12, field='warp.settings.param', desc="""List of tuples for each iteration - Inner iterations - Regularization parameters - Time points for deformation model - smoothing parameter """) optimization_parameters = traits.Tuple(traits.Float, traits.Range(1, 8), traits.Range(1, 8), field='warp.settings.optim', desc="""Optimization settings a tuple - LM regularization - cycles of multigrid solver - relaxation iterations """) class DARTELOutputSpec(TraitedSpec): final_template_file = File(exists=True, desc='final DARTEL template') template_files = traits.List(File(exists=True), desc='Templates from different stages of iteration') dartel_flow_fields = traits.List(File(exists=True), desc='DARTEL flow fields') class DARTEL(SPMCommand): """Use spm DARTEL to create a template and flow fields http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=185 Examples -------- >>> import nipype.interfaces.spm as spm >>> dartel = spm.DARTEL() >>> dartel.inputs.image_files = [['rc1s1.nii','rc1s2.nii'],['rc2s1.nii', 'rc2s2.nii']] >>> dartel.run() # doctest: +SKIP """ input_spec = DARTELInputSpec output_spec = DARTELOutputSpec _jobtype = 'tools' _jobname = 'dartel' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['image_files']: return scans_for_fnames(val, keep4d=True, separate_sessions=True) elif opt == 'regularization_form': mapper = {'Linear': 0, 'Membrane': 1, 'Bending': 2} return mapper[val] elif opt == 'iteration_parameters': params = [] for param in val: new_param = {} new_param['its'] = param[0] new_param['rparam'] = list(param[1]) new_param['K'] = param[2] new_param['slam'] = param[3] params.append(new_param) return params elif opt == 'optimization_parameters': new_param = {} new_param['lmreg'] = val[0] new_param['cyc'] = val[1] new_param['its'] = val[2] return [new_param] else: return super(DARTEL, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['template_files'] = [] for i in range(6): outputs['template_files'].append(os.path.realpath('%s_%d.nii' % (self.inputs.template_prefix, i+1))) outputs['final_template_file'] = os.path.realpath('%s_6.nii' % self.inputs.template_prefix) outputs['dartel_flow_fields'] = [] for filename in self.inputs.image_files[0]: pth, base, ext = split_filename(filename) outputs['dartel_flow_fields'].append(os.path.realpath('u_%s_%s%s' % (base, self.inputs.template_prefix, ext))) return outputs class DARTELNorm2MNIInputSpec(SPMCommandInputSpec): template_file = File(exists=True, desc="DARTEL template", field='mni_norm.template', copyfile=False, mandatory=True) flowfield_files = InputMultiPath(File(exists=True), desc="DARTEL flow fields u_rc1*", field='mni_norm.data.subjs.flowfields', mandatory=True) apply_to_files = InputMultiPath(File(exists=True), desc="Files to apply the transform to", field='mni_norm.data.subjs.images', mandatory=True, copyfile=False) voxel_size = traits.Tuple(traits.Float, traits.Float, traits.Float, desc="Voxel sizes for output file", field='mni_norm.vox') bounding_box = traits.Tuple(traits.Float, traits.Float, traits.Float, traits.Float, traits.Float, traits.Float, desc="Voxel sizes for output file", field='mni_norm.bb') modulate = traits.Bool(field='mni_norm.preserve', desc="Modulate out images - no modulation preserves concentrations") fwhm = traits.Either(traits.List(traits.Float(), minlen=3, maxlen=3), traits.Float(), field='mni_norm.fwhm', desc='3-list of fwhm for each dimension') class DARTELNorm2MNIOutputSpec(TraitedSpec): normalized_files = OutputMultiPath(File(exists=True), desc='Normalized files in MNI space') normalization_parameter_file = File(exists=True, desc='Transform parameters to MNI space') class DARTELNorm2MNI(SPMCommand): """Use spm DARTEL to normalize data to MNI space http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=188 Examples -------- >>> import nipype.interfaces.spm as spm >>> nm = spm.DARTELNorm2MNI() >>> nm.inputs.template_file = 'Template_6.nii' >>> nm.inputs.flowfield_files = ['u_rc1s1_Template.nii', 'u_rc1s3_Template.nii'] >>> nm.inputs.apply_to_files = ['c1s1.nii', 'c1s3.nii'] >>> nm.inputs.modulate = True >>> nm.run() # doctest: +SKIP """ input_spec = DARTELNorm2MNIInputSpec output_spec = DARTELNorm2MNIOutputSpec _jobtype = 'tools' _jobname = 'dartel' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['template_file']: return np.array([val], dtype=object) elif opt in ['flowfield_files']: return scans_for_fnames(val, keep4d=True) elif opt in ['apply_to_files']: return scans_for_fnames(val, keep4d=True, separate_sessions=True) elif opt == 'voxel_size': return list(val) elif opt == 'bounding_box': return list(val) elif opt == 'fwhm': if isinstance(val, list): return val else: return [val, val, val] else: return super(DARTELNorm2MNI, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() pth, base, ext = split_filename(self.inputs.template_file) outputs['normalization_parameter_file'] = os.path.realpath(base+'_2mni.mat') outputs['normalized_files'] = [] prefix = "w" if isdefined(self.inputs.modulate) and self.inputs.modulate: prefix = 'm' + prefix if not isdefined(self.inputs.fwhm) or self.inputs.fwhm > 0: prefix = 's' + prefix for filename in self.inputs.apply_to_files: pth, base, ext = split_filename(filename) outputs['normalized_files'].append(os.path.realpath('%s%s%s' % (prefix, base, ext))) return outputs class CreateWarpedInputSpec(SPMCommandInputSpec): image_files = InputMultiPath(File(exists=True), desc="A list of files to be warped", field='crt_warped.images', copyfile=False, mandatory=True) flowfield_files = InputMultiPath(File(exists=True), desc="DARTEL flow fields u_rc1*", field='crt_warped.flowfields', copyfile=False, mandatory=True) iterations = traits.Range(low=0, high=9, desc=("The number of iterations: log2(number of " "time steps)"), field='crt_warped.K') interp = traits.Range(low=0, high=7, field='crt_warped.interp', desc='degree of b-spline used for interpolation') modulate = traits.Bool(field='crt_warped.jactransf', desc="Modulate images") class CreateWarpedOutputSpec(TraitedSpec): warped_files = traits.List(File(exists=True, desc='final warped files')) class CreateWarped(SPMCommand): """Apply a flow field estimated by DARTEL to create warped images http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=190 Examples -------- >>> import nipype.interfaces.spm as spm >>> create_warped = spm.CreateWarped() >>> create_warped.inputs.image_files = ['rc1s1.nii', 'rc1s2.nii'] >>> create_warped.inputs.flowfield_files = ['u_rc1s1_Template.nii', 'u_rc1s2_Template.nii'] >>> create_warped.run() # doctest: +SKIP """ input_spec = CreateWarpedInputSpec output_spec = CreateWarpedOutputSpec _jobtype = 'tools' _jobname = 'dartel' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['image_files']: return scans_for_fnames(val, keep4d=True, separate_sessions=True) if opt in ['flowfield_files']: return scans_for_fnames(val, keep4d=True) else: return super(CreateWarped, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['warped_files'] = [] for filename in self.inputs.image_files: pth, base, ext = split_filename(filename) if isdefined(self.inputs.modulate) and self.inputs.modulate: outputs['warped_files'].append(os.path.realpath('mw%s%s' % (base, ext))) else: outputs['warped_files'].append(os.path.realpath('w%s%s' % (base, ext))) return outputs class ApplyDeformationFieldInputSpec(SPMCommandInputSpec): in_files = InputMultiPath(File(exists=True), mandatory=True, field='fnames') deformation_field = File(exists=True, mandatory=True, field='comp{1}.def') reference_volume = File(exists=True, mandatory=True, field='comp{2}.id.space') interp = traits.Range(low=0, high=7, field='interp', desc='degree of b-spline used for interpolation') class ApplyDeformationFieldOutputSpec(TraitedSpec): out_files = OutputMultiPath(File(exists=True)) class ApplyDeformations(SPMCommand): input_spec = ApplyDeformationFieldInputSpec output_spec = ApplyDeformationFieldOutputSpec _jobtype = 'util' _jobname = 'defs' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['deformation_field', 'reference_volume']: val = [val] if opt in ['deformation_field']: return scans_for_fnames(val, keep4d=True, separate_sessions=False) if opt in ['in_files', 'reference_volume']: return scans_for_fnames(val, keep4d=False, separate_sessions=False) else: return super(ApplyDeformations, self)._format_arg(opt, spec, val) def _list_outputs(self): outputs = self._outputs().get() outputs['out_files'] = [] for filename in self.inputs.in_files: _, fname = os.path.split(filename) outputs['out_files'].append(os.path.realpath('w%s' % fname)) return outputs class VBMSegmentInputSpec(SPMCommandInputSpec): in_files = InputMultiPath( File(exists=True), desc="A list of files to be segmented", field='estwrite.data', copyfile=False, mandatory=True) tissues = File( exists=True, field='estwrite.tpm', desc='tissue probability map') gaussians_per_class = traits.Tuple( (2, 2, 2, 3, 4, 2), *([traits.Int()]*6), usedefault=True, desc='number of gaussians for each tissue class') bias_regularization = traits.Enum( 0.0001, (0, 0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10), field='estwrite.opts.biasreg', usedefault=True, desc='no(0) - extremely heavy (10)') bias_fwhm = traits.Enum( 60, (30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 'Inf'), field='estwrite.opts.biasfwhm', usedefault=True, desc='FWHM of Gaussian smoothness of bias') sampling_distance = traits.Float( 3, usedefault=True, field='estwrite.opts.samp', desc='Sampling distance on data for parameter estimation') warping_regularization = traits.Float( 4, usedefault=True, field='estwrite.opts.warpreg', desc='Controls balance between parameters and data') spatial_normalization = traits.Enum( 'high', 'low', usedefault=True,) dartel_template = File( exists=True, field='estwrite.extopts.dartelwarp.normhigh.darteltpm') use_sanlm_denoising_filter = traits.Range( 0, 2, 2, usedefault=True, field='estwrite.extopts.sanlm', desc="0=No denoising, 1=denoising,2=denoising multi-threaded") mrf_weighting = traits.Float( 0.15, usedefault=True, field='estwrite.extopts.mrf') cleanup_partitions = traits.Int( 1, usedefault=True, field='estwrite.extopts.cleanup', desc="0=None,1=light,2=thorough") display_results = traits.Bool( True, usedefault=True, field='estwrite.extopts.print') gm_native = traits.Bool( False, usedefault=True, field='estwrite.output.GM.native',) gm_normalized = traits.Bool( False, usedefault=True, field='estwrite.output.GM.warped',) gm_modulated_normalized = traits.Range( 0, 2, 2, usedefault=True, field='estwrite.output.GM.modulated', desc='0=none,1=affine+non-linear(SPM8 default),2=non-linear only') gm_dartel = traits.Range( 0, 2, 0, usedefault=True, field='estwrite.output.GM.dartel', desc="0=None,1=rigid(SPM8 default),2=affine") wm_native = traits.Bool( False, usedefault=True, field='estwrite.output.WM.native',) wm_normalized = traits.Bool( False, usedefault=True, field='estwrite.output.WM.warped',) wm_modulated_normalized = traits.Range( 0, 2, 2, usedefault=True, field='estwrite.output.WM.modulated', desc='0=none,1=affine+non-linear(SPM8 default),2=non-linear only') wm_dartel = traits.Range( 0, 2, 0, usedefault=True, field='estwrite.output.WM.dartel', desc="0=None,1=rigid(SPM8 default),2=affine") csf_native = traits.Bool( False, usedefault=True, field='estwrite.output.CSF.native',) csf_normalized = traits.Bool( False, usedefault=True, field='estwrite.output.CSF.warped',) csf_modulated_normalized = traits.Range( 0, 2, 2, usedefault=True, field='estwrite.output.CSF.modulated', desc='0=none,1=affine+non-linear(SPM8 default),2=non-linear only') csf_dartel = traits.Range( 0, 2, 0, usedefault=True, field='estwrite.output.CSF.dartel', desc="0=None,1=rigid(SPM8 default),2=affine") bias_corrected_native = traits.Bool( False, usedefault=True, field='estwrite.output.bias.native',) bias_corrected_normalized = traits.Bool( True, usedefault=True, field='estwrite.output.bias.warped',) bias_corrected_affine = traits.Bool( False, usedefault=True, field='estwrite.output.bias.affine',) pve_label_native = traits.Bool( False, usedefault=True, field='estwrite.output.label.native') pve_label_normalized = traits.Bool( False, usedefault=True, field='estwrite.output.label.warped') pve_label_dartel = traits.Range( 0, 2, 0, usedefault=True, field='estwrite.output.label.dartel', desc="0=None,1=rigid(SPM8 default),2=affine") jacobian_determinant = traits.Bool( False, usedefault=True, field='estwrite.jacobian.warped') deformation_field = traits.Tuple( (0, 0), traits.Bool, traits.Bool, usedefault=True, field='estwrite.output.warps', desc='forward and inverse field') class VBMSegmentOuputSpec(TraitedSpec): native_class_images = traits.List(traits.List(File(exists=True)), desc='native space probability maps') dartel_input_images = traits.List(traits.List(File(exists=True)), desc='dartel imported class images') normalized_class_images = traits.List(traits.List(File(exists=True)), desc='normalized class images') modulated_class_images = traits.List(traits.List(File(exists=True)), desc='modulated+normalized class images') transformation_mat = OutputMultiPath(File(exists=True), desc='Normalization transformation') bias_corrected_images = OutputMultiPath( File(exists=True), desc='bias corrected images') normalized_bias_corrected_images = OutputMultiPath( File(exists=True), desc='bias corrected images') pve_label_native_images = OutputMultiPath(File(exists=True)) pve_label_normalized_images = OutputMultiPath(File(exists=True)) pve_label_registered_images = OutputMultiPath(File(exists=True)) forward_deformation_field = OutputMultiPath(File(exists=True)) inverse_deformation_field = OutputMultiPath(File(exists=True)) jacobian_determinant_images = OutputMultiPath(File(exists=True)) class VBMSegment(SPMCommand): """Use VBM8 toolbox to separate structural images into different tissue classes. Example ------- >>> import nipype.interfaces.spm as spm >>> seg = spm.VBMSegment() >>> seg.inputs.tissues = 'TPM.nii' >>> seg.inputs.dartel_template = 'Template_1_IXI550_MNI152.nii' >>> seg.inputs.bias_corrected_native = True >>> seg.inputs.gm_native = True >>> seg.inputs.wm_native = True >>> seg.inputs.csf_native = True >>> seg.inputs.pve_label_native = True >>> seg.inputs.deformation_field = (True, False) >>> seg.run() # doctest: +SKIP """ input_spec = VBMSegmentInputSpec output_spec = VBMSegmentOuputSpec _jobtype = 'tools' _jobname = 'vbm8' def _list_outputs(self): outputs = self._outputs().get() do_dartel = self.inputs.spatial_normalization dartel_px = '' if do_dartel: dartel_px = 'r' outputs['native_class_images'] = [[], [], []] outputs['dartel_input_images'] = [[], [], []] outputs['normalized_class_images'] = [[], [], []] outputs['modulated_class_images'] = [[], [], []] outputs['transformation_mat'] = [] outputs['bias_corrected_images'] = [] outputs['normalized_bias_corrected_images'] = [] outputs['inverse_deformation_field'] = [] outputs['forward_deformation_field'] = [] outputs['jacobian_determinant_images'] = [] outputs['pve_label_native_images'] = [] outputs['pve_label_normalized_images'] = [] outputs['pve_label_registered_images'] = [] for filename in self.inputs.in_files: pth, base, ext = split_filename(filename) outputs['transformation_mat'].append( os.path.join(pth, "%s_seg8.mat" % base)) for i, tis in enumerate(['gm', 'wm', 'csf']): # native space if getattr(self.inputs, '%s_native' % tis): outputs['native_class_images'][i].append( os.path.join(pth, "p%d%s.nii" % (i+1, base))) if getattr(self.inputs, '%s_dartel' % tis) == 1: outputs['dartel_input_images'][i].append( os.path.join(pth, "rp%d%s.nii" % (i+1, base))) elif getattr(self.inputs, '%s_dartel' % tis) == 2: outputs['dartel_input_images'][i].append( os.path.join(pth, "rp%d%s_affine.nii" % (i+1, base))) # normalized space if getattr(self.inputs, '%s_normalized' % tis): outputs['normalized_class_images'][i].append( os.path.join(pth, "w%sp%d%s.nii" % (dartel_px, i+1, base))) if getattr(self.inputs, '%s_modulated_normalized' % tis) == 1: outputs['modulated_class_images'][i].append(os.path.join( pth, "mw%sp%d%s.nii" % (dartel_px, i+1, base))) elif getattr(self.inputs, '%s_modulated_normalized' % tis) == 2: outputs['normalized_class_images'][i].append(os.path.join( pth, "m0w%sp%d%s.nii" % (dartel_px, i+1, base))) if self.inputs.pve_label_native: outputs['pve_label_native_images'].append( os.path.join(pth, "p0%s.nii" % (base))) if self.inputs.pve_label_normalized: outputs['pve_label_normalized_images'].append( os.path.join(pth, "w%sp0%s.nii" % (dartel_px, base))) if self.inputs.pve_label_dartel == 1: outputs['pve_label_registered_images'].append( os.path.join(pth, "rp0%s.nii" % (base))) elif self.inputs.pve_label_dartel == 2: outputs['pve_label_registered_images'].append( os.path.join(pth, "rp0%s_affine.nii" % (base))) if self.inputs.bias_corrected_native: outputs['bias_corrected_images'].append( os.path.join(pth, "m%s.nii" % (base))) if self.inputs.bias_corrected_normalized: outputs['normalized_bias_corrected_images'].append( os.path.join(pth, "wm%s%s.nii" % (dartel_px, base))) if self.inputs.deformation_field[0]: outputs['forward_deformation_field'].append( os.path.join(pth, "y_%s%s.nii" % (dartel_px, base))) if self.inputs.deformation_field[1]: outputs['inverse_deformation_field'].append( os.path.join(pth, "iy_%s%s.nii" % (dartel_px, base))) if self.inputs.jacobian_determinant and do_dartel: outputs['jacobian_determinant_images'].append( os.path.join(pth, "jac_wrp1%s.nii" % (base))) return outputs def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt in ['in_files']: return scans_for_fnames(val, keep4d=True) elif opt in ['spatial_normalization']: if val == 'low': return {'normlow': []} elif opt in ['dartel_template']: return np.array([val], dtype=object) elif opt in ['deformation_field']: return super(VBMSegment, self)._format_arg(opt, spec, [int(val[0]), int(val[1])]) else: return super(VBMSegment, self)._format_arg(opt, spec, val) def _parse_inputs(self): if self.inputs.spatial_normalization == 'low': einputs = super(VBMSegment, self)._parse_inputs( skip=('spatial_normalization', 'dartel_template')) einputs[0]['estwrite']['extopts']['dartelwarp'] = {'normlow': 1} return einputs else: return super(VBMSegment, self)._parse_inputs(skip=('spatial_normalization')) nipype-0.11.0/nipype/interfaces/spm/tests/000077500000000000000000000000001257611314500204725ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Analyze2nii.py000066400000000000000000000022711257611314500253220ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import Analyze2nii def test_Analyze2nii_inputs(): input_map = dict(analyze_file=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = Analyze2nii.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Analyze2nii_outputs(): output_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), nifti_file=dict(), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) outputs = Analyze2nii.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_ApplyDeformations.py000066400000000000000000000023061257611314500265740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import ApplyDeformations def test_ApplyDeformations_inputs(): input_map = dict(deformation_field=dict(field='comp{1}.def', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='fnames', mandatory=True, ), interp=dict(field='interp', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), reference_volume=dict(field='comp{2}.id.space', mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = ApplyDeformations.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyDeformations_outputs(): output_map = dict(out_files=dict(), ) outputs = ApplyDeformations.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_ApplyInverseDeformation.py000066400000000000000000000027111257611314500277450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import ApplyInverseDeformation def test_ApplyInverseDeformation_inputs(): input_map = dict(bounding_box=dict(field='comp{1}.inv.comp{1}.sn2def.bb', ), deformation=dict(field='comp{1}.inv.comp{1}.sn2def.matname', xor=['deformation_field'], ), deformation_field=dict(field='comp{1}.inv.comp{1}.def', xor=['deformation'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='fnames', mandatory=True, ), interpolation=dict(field='interp', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), target=dict(field='comp{1}.inv.space', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), voxel_sizes=dict(field='comp{1}.inv.comp{1}.sn2def.vox', ), ) inputs = ApplyInverseDeformation.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyInverseDeformation_outputs(): output_map = dict(out_files=dict(), ) outputs = ApplyInverseDeformation.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_ApplyTransform.py000066400000000000000000000020711257611314500261140ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import ApplyTransform def test_ApplyTransform_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(copyfile=True, mandatory=True, ), mat=dict(mandatory=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), out_file=dict(genfile=True, ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = ApplyTransform.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ApplyTransform_outputs(): output_map = dict(out_file=dict(), ) outputs = ApplyTransform.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_CalcCoregAffine.py000066400000000000000000000021131257611314500260630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import CalcCoregAffine def test_CalcCoregAffine_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), invmat=dict(), mat=dict(), matlab_cmd=dict(), mfile=dict(usedefault=True, ), moving=dict(copyfile=False, mandatory=True, ), paths=dict(), target=dict(mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = CalcCoregAffine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CalcCoregAffine_outputs(): output_map = dict(invmat=dict(), mat=dict(), ) outputs = CalcCoregAffine.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Coregister.py000066400000000000000000000031731257611314500252450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Coregister def test_Coregister_inputs(): input_map = dict(apply_to_files=dict(copyfile=True, field='other', ), cost_function=dict(field='eoptions.cost_fun', ), fwhm=dict(field='eoptions.fwhm', ), ignore_exception=dict(nohash=True, usedefault=True, ), jobtype=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), out_prefix=dict(field='roptions.prefix', usedefault=True, ), paths=dict(), separation=dict(field='eoptions.sep', ), source=dict(copyfile=True, field='source', mandatory=True, ), target=dict(copyfile=False, field='ref', mandatory=True, ), tolerance=dict(field='eoptions.tol', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), write_interp=dict(field='roptions.interp', ), write_mask=dict(field='roptions.mask', ), write_wrap=dict(field='roptions.wrap', ), ) inputs = Coregister.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Coregister_outputs(): output_map = dict(coregistered_files=dict(), coregistered_source=dict(), ) outputs = Coregister.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_CreateWarped.py000066400000000000000000000024221257611314500255010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import CreateWarped def test_CreateWarped_inputs(): input_map = dict(flowfield_files=dict(copyfile=False, field='crt_warped.flowfields', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), image_files=dict(copyfile=False, field='crt_warped.images', mandatory=True, ), interp=dict(field='crt_warped.interp', ), iterations=dict(field='crt_warped.K', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), modulate=dict(field='crt_warped.jactransf', ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = CreateWarped.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CreateWarped_outputs(): output_map = dict(warped_files=dict(), ) outputs = CreateWarped.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_DARTEL.py000066400000000000000000000025131257611314500241070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import DARTEL def test_DARTEL_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), image_files=dict(copyfile=False, field='warp.images', mandatory=True, ), iteration_parameters=dict(field='warp.settings.param', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), optimization_parameters=dict(field='warp.settings.optim', ), paths=dict(), regularization_form=dict(field='warp.settings.rform', ), template_prefix=dict(field='warp.settings.template', usedefault=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = DARTEL.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DARTEL_outputs(): output_map = dict(dartel_flow_fields=dict(), final_template_file=dict(), template_files=dict(), ) outputs = DARTEL.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_DARTELNorm2MNI.py000066400000000000000000000027241257611314500253750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import DARTELNorm2MNI def test_DARTELNorm2MNI_inputs(): input_map = dict(apply_to_files=dict(copyfile=False, field='mni_norm.data.subjs.images', mandatory=True, ), bounding_box=dict(field='mni_norm.bb', ), flowfield_files=dict(field='mni_norm.data.subjs.flowfields', mandatory=True, ), fwhm=dict(field='mni_norm.fwhm', ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), modulate=dict(field='mni_norm.preserve', ), paths=dict(), template_file=dict(copyfile=False, field='mni_norm.template', mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), voxel_size=dict(field='mni_norm.vox', ), ) inputs = DARTELNorm2MNI.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DARTELNorm2MNI_outputs(): output_map = dict(normalization_parameter_file=dict(), normalized_files=dict(), ) outputs = DARTELNorm2MNI.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_DicomImport.py000066400000000000000000000023611257611314500253630ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import DicomImport def test_DicomImport_inputs(): input_map = dict(format=dict(field='convopts.format', usedefault=True, ), icedims=dict(field='convopts.icedims', usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='data', mandatory=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), output_dir=dict(field='outdir', usedefault=True, ), output_dir_struct=dict(field='root', usedefault=True, ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = DicomImport.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DicomImport_outputs(): output_map = dict(out_files=dict(), ) outputs = DicomImport.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_EstimateContrast.py000066400000000000000000000026061257611314500264300ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import EstimateContrast def test_EstimateContrast_inputs(): input_map = dict(beta_images=dict(copyfile=False, mandatory=True, ), contrasts=dict(mandatory=True, ), group_contrast=dict(xor=['use_derivs'], ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), residual_image=dict(copyfile=False, mandatory=True, ), spm_mat_file=dict(copyfile=True, field='spmmat', mandatory=True, ), use_derivs=dict(xor=['group_contrast'], ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = EstimateContrast.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EstimateContrast_outputs(): output_map = dict(con_images=dict(), ess_images=dict(), spmF_images=dict(), spmT_images=dict(), spm_mat_file=dict(), ) outputs = EstimateContrast.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_EstimateModel.py000066400000000000000000000022751257611314500256750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import EstimateModel def test_EstimateModel_inputs(): input_map = dict(estimation_method=dict(field='method', mandatory=True, ), flags=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), spm_mat_file=dict(copyfile=True, field='spmmat', mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = EstimateModel.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_EstimateModel_outputs(): output_map = dict(RPVimage=dict(), beta_images=dict(), mask_image=dict(), residual_image=dict(), spm_mat_file=dict(), ) outputs = EstimateModel.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_FactorialDesign.py000066400000000000000000000037361257611314500262020ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import FactorialDesign def test_FactorialDesign_inputs(): input_map = dict(covariates=dict(field='cov', ), explicit_mask_file=dict(field='masking.em', ), global_calc_mean=dict(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], ), global_calc_omit=dict(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], ), global_calc_values=dict(field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], ), global_normalization=dict(field='globalm.glonorm', ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), no_grand_mean_scaling=dict(field='globalm.gmsca.gmsca_no', ), paths=dict(), spm_mat_dir=dict(field='dir', ), threshold_mask_absolute=dict(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], ), threshold_mask_none=dict(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], ), threshold_mask_relative=dict(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], ), use_implicit_threshold=dict(field='masking.im', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = FactorialDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FactorialDesign_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = FactorialDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Level1Design.py000066400000000000000000000032031257611314500254130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import Level1Design def test_Level1Design_inputs(): input_map = dict(bases=dict(field='bases', mandatory=True, ), factor_info=dict(field='fact', ), global_intensity_normalization=dict(field='global', ), ignore_exception=dict(nohash=True, usedefault=True, ), interscan_interval=dict(field='timing.RT', mandatory=True, ), mask_image=dict(field='mask', ), mask_threshold=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), microtime_onset=dict(field='timing.fmri_t0', ), microtime_resolution=dict(field='timing.fmri_t', ), model_serial_correlations=dict(field='cvi', ), paths=dict(), session_info=dict(field='sess', mandatory=True, ), spm_mat_dir=dict(field='dir', ), timing_units=dict(field='timing.units', mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), volterra_expansion_order=dict(field='volt', ), ) inputs = Level1Design.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Level1Design_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = Level1Design.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_MultipleRegressionDesign.py000066400000000000000000000043271257611314500301270ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import MultipleRegressionDesign def test_MultipleRegressionDesign_inputs(): input_map = dict(covariates=dict(field='cov', ), explicit_mask_file=dict(field='masking.em', ), global_calc_mean=dict(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], ), global_calc_omit=dict(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], ), global_calc_values=dict(field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], ), global_normalization=dict(field='globalm.glonorm', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='des.mreg.scans', mandatory=True, ), include_intercept=dict(field='des.mreg.incint', usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), no_grand_mean_scaling=dict(field='globalm.gmsca.gmsca_no', ), paths=dict(), spm_mat_dir=dict(field='dir', ), threshold_mask_absolute=dict(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], ), threshold_mask_none=dict(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], ), threshold_mask_relative=dict(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], ), use_implicit_threshold=dict(field='masking.im', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), user_covariates=dict(field='des.mreg.mcov', ), ) inputs = MultipleRegressionDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MultipleRegressionDesign_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = MultipleRegressionDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_NewSegment.py000066400000000000000000000031241257611314500252070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import NewSegment def test_NewSegment_inputs(): input_map = dict(affine_regularization=dict(field='warp.affreg', ), channel_files=dict(copyfile=False, field='channel', mandatory=True, ), channel_info=dict(field='channel', ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), sampling_distance=dict(field='warp.samp', ), tissues=dict(field='tissue', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), warping_regularization=dict(field='warp.reg', ), write_deformation_fields=dict(field='warp.write', ), ) inputs = NewSegment.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_NewSegment_outputs(): output_map = dict(bias_corrected_images=dict(), bias_field_images=dict(), dartel_input_images=dict(), forward_deformation_field=dict(), inverse_deformation_field=dict(), modulated_class_images=dict(), native_class_images=dict(), normalized_class_images=dict(), transformation_mat=dict(), ) outputs = NewSegment.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Normalize.py000066400000000000000000000044531257611314500251010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Normalize def test_Normalize_inputs(): input_map = dict(DCT_period_cutoff=dict(field='eoptions.cutoff', ), affine_regularization_type=dict(field='eoptions.regtype', ), apply_to_files=dict(copyfile=True, field='subj.resample', ), ignore_exception=dict(nohash=True, usedefault=True, ), jobtype=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), nonlinear_iterations=dict(field='eoptions.nits', ), nonlinear_regularization=dict(field='eoptions.reg', ), out_prefix=dict(field='roptions.prefix', usedefault=True, ), parameter_file=dict(copyfile=False, field='subj.matname', mandatory=True, xor=['source', 'template'], ), paths=dict(), source=dict(copyfile=True, field='subj.source', mandatory=True, xor=['parameter_file'], ), source_image_smoothing=dict(field='eoptions.smosrc', ), source_weight=dict(copyfile=False, field='subj.wtsrc', ), template=dict(copyfile=False, field='eoptions.template', mandatory=True, xor=['parameter_file'], ), template_image_smoothing=dict(field='eoptions.smoref', ), template_weight=dict(copyfile=False, field='eoptions.weight', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), write_bounding_box=dict(field='roptions.bb', ), write_interp=dict(field='roptions.interp', ), write_preserve=dict(field='roptions.preserve', ), write_voxel_sizes=dict(field='roptions.vox', ), write_wrap=dict(field='roptions.wrap', ), ) inputs = Normalize.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Normalize_outputs(): output_map = dict(normalization_parameters=dict(), normalized_files=dict(), normalized_source=dict(), ) outputs = Normalize.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Normalize12.py000066400000000000000000000036631257611314500252460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Normalize12 def test_Normalize12_inputs(): input_map = dict(affine_regularization_type=dict(field='eoptions.affreg', ), apply_to_files=dict(copyfile=True, field='subj.resample', ), bias_fwhm=dict(field='eoptions.biasfwhm', ), bias_regularization=dict(field='eoptions.biasreg', ), deformation_file=dict(copyfile=False, field='subj.def', mandatory=True, xor=['image_to_align', 'tpm'], ), ignore_exception=dict(nohash=True, usedefault=True, ), image_to_align=dict(copyfile=True, field='subj.vol', mandatory=True, xor=['deformation_file'], ), jobtype=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), sampling_distance=dict(field='eoptions.samp', ), smoothness=dict(field='eoptions.fwhm', ), tpm=dict(copyfile=False, field='eoptions.tpm', xor=['deformation_file'], ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), warping_regularization=dict(field='eoptions.reg', ), write_bounding_box=dict(field='woptions.bb', ), write_interp=dict(field='woptions.interp', ), write_voxel_sizes=dict(field='woptions.vox', ), ) inputs = Normalize12.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Normalize12_outputs(): output_map = dict(deformation_field=dict(), normalized_files=dict(), normalized_image=dict(), ) outputs = Normalize12.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_OneSampleTTestDesign.py000066400000000000000000000040721257611314500271370ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import OneSampleTTestDesign def test_OneSampleTTestDesign_inputs(): input_map = dict(covariates=dict(field='cov', ), explicit_mask_file=dict(field='masking.em', ), global_calc_mean=dict(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], ), global_calc_omit=dict(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], ), global_calc_values=dict(field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], ), global_normalization=dict(field='globalm.glonorm', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='des.t1.scans', mandatory=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), no_grand_mean_scaling=dict(field='globalm.gmsca.gmsca_no', ), paths=dict(), spm_mat_dir=dict(field='dir', ), threshold_mask_absolute=dict(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], ), threshold_mask_none=dict(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], ), threshold_mask_relative=dict(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], ), use_implicit_threshold=dict(field='masking.im', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = OneSampleTTestDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_OneSampleTTestDesign_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = OneSampleTTestDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_PairedTTestDesign.py000066400000000000000000000042251257611314500264600ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import PairedTTestDesign def test_PairedTTestDesign_inputs(): input_map = dict(ancova=dict(field='des.pt.ancova', ), covariates=dict(field='cov', ), explicit_mask_file=dict(field='masking.em', ), global_calc_mean=dict(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], ), global_calc_omit=dict(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], ), global_calc_values=dict(field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], ), global_normalization=dict(field='globalm.glonorm', ), grand_mean_scaling=dict(field='des.pt.gmsca', ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), no_grand_mean_scaling=dict(field='globalm.gmsca.gmsca_no', ), paired_files=dict(field='des.pt.pair', mandatory=True, ), paths=dict(), spm_mat_dir=dict(field='dir', ), threshold_mask_absolute=dict(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], ), threshold_mask_none=dict(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], ), threshold_mask_relative=dict(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], ), use_implicit_threshold=dict(field='masking.im', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = PairedTTestDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_PairedTTestDesign_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = PairedTTestDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Realign.py000066400000000000000000000034111257611314500245130ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Realign def test_Realign_inputs(): input_map = dict(fwhm=dict(field='eoptions.fwhm', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(copyfile=True, field='data', mandatory=True, ), interp=dict(field='eoptions.interp', ), jobtype=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), out_prefix=dict(field='roptions.prefix', usedefault=True, ), paths=dict(), quality=dict(field='eoptions.quality', ), register_to_mean=dict(field='eoptions.rtm', ), separation=dict(field='eoptions.sep', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), weight_img=dict(field='eoptions.weight', ), wrap=dict(field='eoptions.wrap', ), write_interp=dict(field='roptions.interp', ), write_mask=dict(field='roptions.mask', ), write_which=dict(field='roptions.which', maxlen=2, minlen=2, usedefault=True, ), write_wrap=dict(field='roptions.wrap', ), ) inputs = Realign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Realign_outputs(): output_map = dict(mean_image=dict(), modified_in_files=dict(), realigned_files=dict(), realignment_parameters=dict(), ) outputs = Realign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Reslice.py000066400000000000000000000020441257611314500245210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import Reslice def test_Reslice_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(mandatory=True, ), interp=dict(usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), out_file=dict(), paths=dict(), space_defining=dict(mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = Reslice.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Reslice_outputs(): output_map = dict(out_file=dict(), ) outputs = Reslice.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_ResliceToReference.py000066400000000000000000000023261257611314500266460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.utils import ResliceToReference def test_ResliceToReference_inputs(): input_map = dict(bounding_box=dict(field='comp{2}.idbbvox.bb', ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(field='fnames', mandatory=True, ), interpolation=dict(field='interp', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), target=dict(field='comp{1}.id.space', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), voxel_sizes=dict(field='comp{2}.idbbvox.vox', ), ) inputs = ResliceToReference.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ResliceToReference_outputs(): output_map = dict(out_files=dict(), ) outputs = ResliceToReference.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_SPMCommand.py000066400000000000000000000011751257611314500250750ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.base import SPMCommand def test_SPMCommand_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = SPMCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Segment.py000066400000000000000000000042301257611314500245340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Segment def test_Segment_inputs(): input_map = dict(affine_regularization=dict(field='opts.regtype', ), bias_fwhm=dict(field='opts.biasfwhm', ), bias_regularization=dict(field='opts.biasreg', ), clean_masks=dict(field='output.cleanup', ), csf_output_type=dict(field='output.CSF', ), data=dict(copyfile=False, field='data', mandatory=True, ), gaussians_per_class=dict(field='opts.ngaus', ), gm_output_type=dict(field='output.GM', ), ignore_exception=dict(nohash=True, usedefault=True, ), mask_image=dict(field='opts.msk', ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), sampling_distance=dict(field='opts.samp', ), save_bias_corrected=dict(field='output.biascor', ), tissue_prob_maps=dict(field='opts.tpm', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), warp_frequency_cutoff=dict(field='opts.warpco', ), warping_regularization=dict(field='opts.warpreg', ), wm_output_type=dict(field='output.WM', ), ) inputs = Segment.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Segment_outputs(): output_map = dict(bias_corrected_image=dict(), inverse_transformation_mat=dict(), modulated_csf_image=dict(), modulated_gm_image=dict(), modulated_input_image=dict(deprecated='0.10', new_name='bias_corrected_image', ), modulated_wm_image=dict(), native_csf_image=dict(), native_gm_image=dict(), native_wm_image=dict(), normalized_csf_image=dict(), normalized_gm_image=dict(), normalized_wm_image=dict(), transformation_mat=dict(), ) outputs = Segment.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_SliceTiming.py000066400000000000000000000026011257611314500253410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import SliceTiming def test_SliceTiming_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(copyfile=False, field='scans', mandatory=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), num_slices=dict(field='nslices', mandatory=True, ), out_prefix=dict(field='prefix', usedefault=True, ), paths=dict(), ref_slice=dict(field='refslice', mandatory=True, ), slice_order=dict(field='so', mandatory=True, ), time_acquisition=dict(field='ta', mandatory=True, ), time_repetition=dict(field='tr', mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = SliceTiming.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SliceTiming_outputs(): output_map = dict(timecorrected_files=dict(), ) outputs = SliceTiming.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Smooth.py000066400000000000000000000022361257611314500244070ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import Smooth def test_Smooth_inputs(): input_map = dict(data_type=dict(field='dtype', ), fwhm=dict(field='fwhm', ), ignore_exception=dict(nohash=True, usedefault=True, ), implicit_masking=dict(field='im', ), in_files=dict(copyfile=False, field='data', mandatory=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), out_prefix=dict(field='prefix', usedefault=True, ), paths=dict(), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = Smooth.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Smooth_outputs(): output_map = dict(smoothed_files=dict(), ) outputs = Smooth.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_Threshold.py000066400000000000000000000031101257611314500250620ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import Threshold def test_Threshold_inputs(): input_map = dict(contrast_index=dict(mandatory=True, ), extent_fdr_p_threshold=dict(usedefault=True, ), extent_threshold=dict(usedefault=True, ), force_activation=dict(usedefault=True, ), height_threshold=dict(usedefault=True, ), height_threshold_type=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), spm_mat_file=dict(copyfile=True, mandatory=True, ), stat_image=dict(copyfile=False, mandatory=True, ), use_fwe_correction=dict(usedefault=True, ), use_mcr=dict(), use_topo_fdr=dict(usedefault=True, ), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = Threshold.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Threshold_outputs(): output_map = dict(activation_forced=dict(), cluster_forming_thr=dict(), n_clusters=dict(), pre_topo_fdr_map=dict(), pre_topo_n_clusters=dict(), thresholded_map=dict(), ) outputs = Threshold.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_ThresholdStatistics.py000066400000000000000000000025651257611314500271520ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import ThresholdStatistics def test_ThresholdStatistics_inputs(): input_map = dict(contrast_index=dict(mandatory=True, ), extent_threshold=dict(usedefault=True, ), height_threshold=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), paths=dict(), spm_mat_file=dict(copyfile=True, mandatory=True, ), stat_image=dict(copyfile=False, mandatory=True, ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = ThresholdStatistics.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_ThresholdStatistics_outputs(): output_map = dict(clusterwise_P_FDR=dict(), clusterwise_P_RF=dict(), voxelwise_P_Bonf=dict(), voxelwise_P_FDR=dict(), voxelwise_P_RF=dict(), voxelwise_P_uncor=dict(), ) outputs = ThresholdStatistics.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_TwoSampleTTestDesign.py000066400000000000000000000043601257611314500271670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.model import TwoSampleTTestDesign def test_TwoSampleTTestDesign_inputs(): input_map = dict(covariates=dict(field='cov', ), dependent=dict(field='des.t2.dept', ), explicit_mask_file=dict(field='masking.em', ), global_calc_mean=dict(field='globalc.g_mean', xor=['global_calc_omit', 'global_calc_values'], ), global_calc_omit=dict(field='globalc.g_omit', xor=['global_calc_mean', 'global_calc_values'], ), global_calc_values=dict(field='globalc.g_user.global_uval', xor=['global_calc_mean', 'global_calc_omit'], ), global_normalization=dict(field='globalm.glonorm', ), group1_files=dict(field='des.t2.scans1', mandatory=True, ), group2_files=dict(field='des.t2.scans2', mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), no_grand_mean_scaling=dict(field='globalm.gmsca.gmsca_no', ), paths=dict(), spm_mat_dir=dict(field='dir', ), threshold_mask_absolute=dict(field='masking.tm.tma.athresh', xor=['threshold_mask_none', 'threshold_mask_relative'], ), threshold_mask_none=dict(field='masking.tm.tm_none', xor=['threshold_mask_absolute', 'threshold_mask_relative'], ), threshold_mask_relative=dict(field='masking.tm.tmr.rthresh', xor=['threshold_mask_absolute', 'threshold_mask_none'], ), unequal_variance=dict(field='des.t2.variance', ), use_implicit_threshold=dict(field='masking.im', ), use_mcr=dict(), use_v8struct=dict(min_ver='8', usedefault=True, ), ) inputs = TwoSampleTTestDesign.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_TwoSampleTTestDesign_outputs(): output_map = dict(spm_mat_file=dict(), ) outputs = TwoSampleTTestDesign.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_auto_VBMSegment.py000066400000000000000000000101701257611314500251010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.spm.preprocess import VBMSegment def test_VBMSegment_inputs(): input_map = dict(bias_corrected_affine=dict(field='estwrite.output.bias.affine', usedefault=True, ), bias_corrected_native=dict(field='estwrite.output.bias.native', usedefault=True, ), bias_corrected_normalized=dict(field='estwrite.output.bias.warped', usedefault=True, ), bias_fwhm=dict(field='estwrite.opts.biasfwhm', usedefault=True, ), bias_regularization=dict(field='estwrite.opts.biasreg', usedefault=True, ), cleanup_partitions=dict(field='estwrite.extopts.cleanup', usedefault=True, ), csf_dartel=dict(field='estwrite.output.CSF.dartel', usedefault=True, ), csf_modulated_normalized=dict(field='estwrite.output.CSF.modulated', usedefault=True, ), csf_native=dict(field='estwrite.output.CSF.native', usedefault=True, ), csf_normalized=dict(field='estwrite.output.CSF.warped', usedefault=True, ), dartel_template=dict(field='estwrite.extopts.dartelwarp.normhigh.darteltpm', ), deformation_field=dict(field='estwrite.output.warps', usedefault=True, ), display_results=dict(field='estwrite.extopts.print', usedefault=True, ), gaussians_per_class=dict(usedefault=True, ), gm_dartel=dict(field='estwrite.output.GM.dartel', usedefault=True, ), gm_modulated_normalized=dict(field='estwrite.output.GM.modulated', usedefault=True, ), gm_native=dict(field='estwrite.output.GM.native', usedefault=True, ), gm_normalized=dict(field='estwrite.output.GM.warped', usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_files=dict(copyfile=False, field='estwrite.data', mandatory=True, ), jacobian_determinant=dict(field='estwrite.jacobian.warped', usedefault=True, ), matlab_cmd=dict(), mfile=dict(usedefault=True, ), mrf_weighting=dict(field='estwrite.extopts.mrf', usedefault=True, ), paths=dict(), pve_label_dartel=dict(field='estwrite.output.label.dartel', usedefault=True, ), pve_label_native=dict(field='estwrite.output.label.native', usedefault=True, ), pve_label_normalized=dict(field='estwrite.output.label.warped', usedefault=True, ), sampling_distance=dict(field='estwrite.opts.samp', usedefault=True, ), spatial_normalization=dict(usedefault=True, ), tissues=dict(field='estwrite.tpm', ), use_mcr=dict(), use_sanlm_denoising_filter=dict(field='estwrite.extopts.sanlm', usedefault=True, ), use_v8struct=dict(min_ver='8', usedefault=True, ), warping_regularization=dict(field='estwrite.opts.warpreg', usedefault=True, ), wm_dartel=dict(field='estwrite.output.WM.dartel', usedefault=True, ), wm_modulated_normalized=dict(field='estwrite.output.WM.modulated', usedefault=True, ), wm_native=dict(field='estwrite.output.WM.native', usedefault=True, ), wm_normalized=dict(field='estwrite.output.WM.warped', usedefault=True, ), ) inputs = VBMSegment.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VBMSegment_outputs(): output_map = dict(bias_corrected_images=dict(), dartel_input_images=dict(), forward_deformation_field=dict(), inverse_deformation_field=dict(), jacobian_determinant_images=dict(), modulated_class_images=dict(), native_class_images=dict(), normalized_bias_corrected_images=dict(), normalized_class_images=dict(), pve_label_native_images=dict(), pve_label_normalized_images=dict(), pve_label_registered_images=dict(), transformation_mat=dict(), ) outputs = VBMSegment.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/spm/tests/test_base.py000066400000000000000000000140411257611314500230150ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import nibabel as nb import numpy as np from nipype.testing import (assert_equal, assert_false, assert_true, skipif) import nipype.interfaces.spm.base as spm from nipype.interfaces.spm import no_spm import nipype.interfaces.matlab as mlab from nipype.interfaces.spm.base import SPMCommandInputSpec from nipype.interfaces.base import traits try: matlab_cmd = os.environ['MATLABCMD'] except: matlab_cmd = 'matlab' mlab.MatlabCommand.set_default_matlab_cmd(matlab_cmd) def create_files_in_directory(): outdir = mkdtemp() cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii', 'b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3, 3, 3, 4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img, np.eye(4), hdr), os.path.join(outdir, f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) def test_scan_for_fnames(): filelist, outdir, cwd = create_files_in_directory() names = spm.scans_for_fnames(filelist, keep4d=True) yield assert_equal, names[0], filelist[0] yield assert_equal, names[1], filelist[1] clean_directory(outdir, cwd) save_time = False if not save_time: @skipif(no_spm) def test_spm_path(): spm_path = spm.Info.version()['path'] if spm_path is not None: yield assert_equal, type(spm_path), type('') yield assert_true, 'spm' in spm_path def test_use_mfile(): class TestClass(spm.SPMCommand): input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class yield assert_true, dc.inputs.mfile def test_find_mlab_cmd_defaults(): saved_env = dict(os.environ) class TestClass(spm.SPMCommand): pass # test without FORCE_SPMMCR, SPMMCRCMD set for varname in ['FORCE_SPMMCR', 'SPMMCRCMD']: try: del os.environ[varname] except KeyError: pass dc = TestClass() yield assert_equal, dc._use_mcr, None yield assert_equal, dc._matlab_cmd, None # test with only FORCE_SPMMCR set os.environ['FORCE_SPMMCR'] = '1' dc = TestClass() yield assert_equal, dc._use_mcr, True yield assert_equal, dc._matlab_cmd, None # test with both, FORCE_SPMMCR and SPMMCRCMD set os.environ['SPMMCRCMD'] = 'spmcmd' dc = TestClass() yield assert_equal, dc._use_mcr, True yield assert_equal, dc._matlab_cmd, 'spmcmd' # restore environment os.environ.clear(); os.environ.update(saved_env) @skipif(no_spm, "SPM not found") def test_cmd_update(): class TestClass(spm.SPMCommand): input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class dc.inputs.matlab_cmd = 'foo' yield assert_equal, dc.mlab._cmd, 'foo' def test_cmd_update2(): class TestClass(spm.SPMCommand): _jobtype = 'jobtype' _jobname = 'jobname' input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class yield assert_equal, dc.jobtype, 'jobtype' yield assert_equal, dc.jobname, 'jobname' def test_reformat_dict_for_savemat(): class TestClass(spm.SPMCommand): input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class out = dc._reformat_dict_for_savemat({'a': {'b': {'c': []}}}) yield assert_equal, out, [{'a': [{'b': [{'c': []}]}]}] def test_generate_job(): class TestClass(spm.SPMCommand): input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class out = dc._generate_job() yield assert_equal, out, '' # struct array contents = {'contents': [1, 2, 3, 4]} out = dc._generate_job(contents=contents) yield assert_equal, out, ('.contents(1) = 1;\n.contents(2) = 2;' '\n.contents(3) = 3;\n.contents(4) = 4;\n') # cell array of strings filelist, outdir, cwd = create_files_in_directory() names = spm.scans_for_fnames(filelist, keep4d=True) contents = {'files': names} out = dc._generate_job(prefix='test', contents=contents) yield assert_equal, out, "test.files = {...\n'a.nii';...\n'b.nii';...\n};\n" clean_directory(outdir, cwd) # string assignment contents = 'foo' out = dc._generate_job(prefix='test', contents=contents) yield assert_equal, out, "test = 'foo';\n" # cell array of vectors contents = {'onsets': np.array((1,), dtype=object)} contents['onsets'][0] = [1, 2, 3, 4] out = dc._generate_job(prefix='test', contents=contents) yield assert_equal, out, 'test.onsets = {...\n[1, 2, 3, 4];...\n};\n' def test_bool(): class TestClassInputSpec(SPMCommandInputSpec): test_in = include_intercept = traits.Bool(field='testfield') class TestClass(spm.SPMCommand): input_spec = TestClassInputSpec _jobtype = 'jobtype' _jobname = 'jobname' dc = TestClass() # dc = derived_class dc.inputs.test_in = True out = dc._make_matlab_command(dc._parse_inputs()) yield assert_equal, out.find('jobs{1}.spm.jobtype.jobname.testfield = 1;') > 0, 1 dc.inputs.use_v8struct = False out = dc._make_matlab_command(dc._parse_inputs()) yield assert_equal, out.find('jobs{1}.jobtype{1}.jobname{1}.testfield = 1;') > 0, 1 def test_make_matlab_command(): class TestClass(spm.SPMCommand): _jobtype = 'jobtype' _jobname = 'jobname' input_spec = spm.SPMCommandInputSpec dc = TestClass() # dc = derived_class filelist, outdir, cwd = create_files_in_directory() contents = {'contents': [1, 2, 3, 4]} script = dc._make_matlab_command([contents]) yield assert_true, 'jobs{1}.spm.jobtype.jobname.contents(3) = 3;' in script dc.inputs.use_v8struct = False script = dc._make_matlab_command([contents]) yield assert_true, 'jobs{1}.jobtype{1}.jobname{1}.contents(3) = 3;' in script clean_directory(outdir, cwd) nipype-0.11.0/nipype/interfaces/spm/tests/test_model.py000066400000000000000000000043001257611314500232000ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np from nipype.testing import (assert_equal, assert_false, assert_true, assert_raises, skipif) import nibabel as nb import nipype.interfaces.spm.model as spm from nipype.interfaces.spm import no_spm import nipype.interfaces.matlab as mlab try: matlab_cmd = os.environ['MATLABCMD'] except: matlab_cmd = 'matlab' mlab.MatlabCommand.set_default_matlab_cmd(matlab_cmd) def create_files_in_directory(): outdir = mkdtemp() cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii','b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) def test_level1design(): yield assert_equal, spm.Level1Design._jobtype, 'stats' yield assert_equal, spm.Level1Design._jobname, 'fmri_spec' def test_estimatemodel(): yield assert_equal, spm.EstimateModel._jobtype, 'stats' yield assert_equal, spm.EstimateModel._jobname, 'fmri_est' def test_estimatecontrast(): yield assert_equal, spm.EstimateContrast._jobtype, 'stats' yield assert_equal, spm.EstimateContrast._jobname, 'con' def test_threshold(): yield assert_equal, spm.Threshold._jobtype, 'basetype' yield assert_equal, spm.Threshold._jobname, 'basename' def test_factorialdesign(): yield assert_equal, spm.FactorialDesign._jobtype, 'stats' yield assert_equal, spm.FactorialDesign._jobname, 'factorial_design' def test_onesamplettestdesign(): yield assert_equal, spm.OneSampleTTestDesign._jobtype, 'stats' yield assert_equal, spm.OneSampleTTestDesign._jobname, 'factorial_design' def test_twosamplettestdesign(): yield assert_equal, spm.TwoSampleTTestDesign._jobtype, 'stats' yield assert_equal, spm.TwoSampleTTestDesign._jobname, 'factorial_design' nipype-0.11.0/nipype/interfaces/spm/tests/test_preprocess.py000066400000000000000000000120461257611314500242730ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree import numpy as np from nipype.testing import (assert_equal, assert_false, assert_true, assert_raises, skipif) import nibabel as nb import nipype.interfaces.spm as spm from nipype.interfaces.spm import no_spm import nipype.interfaces.matlab as mlab try: matlab_cmd = os.environ['MATLABCMD'] except: matlab_cmd = 'matlab' mlab.MatlabCommand.set_default_matlab_cmd(matlab_cmd) def create_files_in_directory(): outdir = mkdtemp() cwd = os.getcwd() os.chdir(outdir) filelist = ['a.nii','b.nii'] for f in filelist: hdr = nb.Nifti1Header() shape = (3,3,3,4) hdr.set_data_shape(shape) img = np.random.random(shape) nb.save(nb.Nifti1Image(img,np.eye(4),hdr), os.path.join(outdir,f)) return filelist, outdir, cwd def clean_directory(outdir, old_wd): if os.path.exists(outdir): rmtree(outdir) os.chdir(old_wd) def test_slicetiming(): yield assert_equal, spm.SliceTiming._jobtype, 'temporal' yield assert_equal, spm.SliceTiming._jobname, 'st' def test_slicetiming_list_outputs(): filelist, outdir, cwd = create_files_in_directory() st = spm.SliceTiming(in_files=filelist[0]) yield assert_equal, st._list_outputs()['timecorrected_files'][0][0], 'a' clean_directory(outdir, cwd) def test_realign(): yield assert_equal, spm.Realign._jobtype, 'spatial' yield assert_equal, spm.Realign._jobname, 'realign' yield assert_equal, spm.Realign().inputs.jobtype, 'estwrite' def test_realign_list_outputs(): filelist, outdir, cwd = create_files_in_directory() rlgn = spm.Realign(in_files=filelist[0]) yield assert_true, rlgn._list_outputs()['realignment_parameters'][0].startswith('rp_') yield assert_true, rlgn._list_outputs()['realigned_files'][0].startswith('r') yield assert_true, rlgn._list_outputs()['mean_image'].startswith('mean') clean_directory(outdir, cwd) def test_coregister(): yield assert_equal, spm.Coregister._jobtype, 'spatial' yield assert_equal, spm.Coregister._jobname, 'coreg' yield assert_equal, spm.Coregister().inputs.jobtype, 'estwrite' def test_coregister_list_outputs(): filelist, outdir, cwd = create_files_in_directory() coreg = spm.Coregister(source=filelist[0]) yield assert_true, coreg._list_outputs()['coregistered_source'][0].startswith('r') coreg = spm.Coregister(source=filelist[0],apply_to_files=filelist[1]) yield assert_true, coreg._list_outputs()['coregistered_files'][0].startswith('r') clean_directory(outdir, cwd) def test_normalize(): yield assert_equal, spm.Normalize._jobtype, 'spatial' yield assert_equal, spm.Normalize._jobname, 'normalise' yield assert_equal, spm.Normalize().inputs.jobtype, 'estwrite' def test_normalize_list_outputs(): filelist, outdir, cwd = create_files_in_directory() norm = spm.Normalize(source=filelist[0]) yield assert_true, norm._list_outputs()['normalized_source'][0].startswith('w') norm = spm.Normalize(source=filelist[0], apply_to_files=filelist[1]) yield assert_true, norm._list_outputs()['normalized_files'][0].startswith('w') clean_directory(outdir, cwd) def test_normalize12(): yield assert_equal, spm.Normalize12._jobtype, 'spatial' yield assert_equal, spm.Normalize12._jobname, 'normalise' yield assert_equal, spm.Normalize12().inputs.jobtype, 'estwrite' def test_normalize12_list_outputs(): filelist, outdir, cwd = create_files_in_directory() norm12 = spm.Normalize12(image_to_align=filelist[0]) yield assert_true, norm12._list_outputs()['normalized_image'][0].startswith('w') norm12 = spm.Normalize12(image_to_align=filelist[0], apply_to_files=filelist[1]) yield assert_true, norm12._list_outputs()['normalized_files'][0].startswith('w') clean_directory(outdir, cwd) @skipif(no_spm) def test_segment(): if spm.Info.version()['name'] == "SPM12": yield assert_equal, spm.Segment()._jobtype, 'tools' yield assert_equal, spm.Segment()._jobname, 'oldseg' else: yield assert_equal, spm.Segment()._jobtype, 'spatial' yield assert_equal, spm.Segment()._jobname, 'preproc' @skipif(no_spm) def test_newsegment(): if spm.Info.version()['name'] == "SPM12": yield assert_equal, spm.NewSegment()._jobtype, 'spatial' yield assert_equal, spm.NewSegment()._jobname, 'preproc' else: yield assert_equal, spm.NewSegment()._jobtype, 'tools' yield assert_equal, spm.NewSegment()._jobname, 'preproc8' def test_smooth(): yield assert_equal, spm.Smooth._jobtype, 'spatial' yield assert_equal, spm.Smooth._jobname, 'smooth' def test_dartel(): yield assert_equal, spm.DARTEL._jobtype, 'tools' yield assert_equal, spm.DARTEL._jobname, 'dartel' def test_dartelnorm2mni(): yield assert_equal, spm.DARTELNorm2MNI._jobtype, 'tools' yield assert_equal, spm.DARTELNorm2MNI._jobname, 'dartel' nipype-0.11.0/nipype/interfaces/spm/tests/test_utils.py000066400000000000000000000065431257611314500232530ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from nipype.testing import (assert_equal, assert_false,assert_raises, assert_true, skipif, example_data) from nipype.interfaces.spm import no_spm import nipype.interfaces.spm.utils as spmu from nipype.interfaces.base import isdefined from nipype.utils.filemanip import split_filename, fname_presuffix from nipype.interfaces.base import TraitError def test_coreg(): moving = example_data(infile = 'functional.nii') target = example_data(infile = 'T1.nii') mat = example_data(infile = 'trans.mat') coreg = spmu.CalcCoregAffine(matlab_cmd = 'mymatlab') coreg.inputs.target = target assert_equal(coreg.inputs.matlab_cmd, 'mymatlab') coreg.inputs.moving = moving assert_equal( isdefined(coreg.inputs.mat),False) pth, mov, _ = split_filename(moving) _, tgt, _ = split_filename(target) mat = os.path.join(pth, '%s_to_%s.mat'%(mov,tgt)) invmat = fname_presuffix(mat, prefix = 'inverse_') scrpt = coreg._make_matlab_command(None) assert_equal(coreg.inputs.mat, mat) assert_equal( coreg.inputs.invmat, invmat) def test_apply_transform(): moving = example_data(infile = 'functional.nii') mat = example_data(infile = 'trans.mat') applymat = spmu.ApplyTransform(matlab_cmd = 'mymatlab') assert_equal( applymat.inputs.matlab_cmd, 'mymatlab' ) applymat.inputs.in_file = moving applymat.inputs.mat = mat scrpt = applymat._make_matlab_command(None) expected = '[p n e v] = spm_fileparts(V.fname);' assert_equal( expected in scrpt, True) expected = 'V.mat = transform.M * V.mat;' assert_equal(expected in scrpt, True) def test_reslice(): moving = example_data(infile = 'functional.nii') space_defining = example_data(infile = 'T1.nii') reslice = spmu.Reslice(matlab_cmd = 'mymatlab_version') assert_equal( reslice.inputs.matlab_cmd, 'mymatlab_version') reslice.inputs.in_file = moving reslice.inputs.space_defining = space_defining assert_equal( reslice.inputs.interp, 0) assert_raises(TraitError,reslice.inputs.trait_set,interp = 'nearest') assert_raises(TraitError, reslice.inputs.trait_set, interp = 10) reslice.inputs.interp = 1 script = reslice._make_matlab_command(None) outfile = fname_presuffix(moving, prefix='r') assert_equal(reslice.inputs.out_file, outfile) expected = '\nflags.mean=0;\nflags.which=1;\nflags.mask=0;' assert_equal(expected in script.replace(' ',''), True) expected_interp = 'flags.interp = 1;\n' assert_equal(expected_interp in script, True) assert_equal('spm_reslice(invols, flags);' in script, True) def test_dicom_import(): dicom = example_data(infile = 'dicomdir/123456-1-1.dcm') di = spmu.DicomImport(matlab_cmd = 'mymatlab') assert_equal(di.inputs.matlab_cmd, 'mymatlab') assert_equal(di.inputs.output_dir_struct, 'flat') assert_equal(di.inputs.output_dir, './converted_dicom') assert_equal(di.inputs.format, 'nii') assert_equal(di.inputs.icedims, False) assert_raises(TraitError,di.inputs.trait_set,output_dir_struct = 'wrong') assert_raises(TraitError,di.inputs.trait_set,format = 'FAT') assert_raises(TraitError,di.inputs.trait_set,in_files = ['does_sfd_not_32fn_exist.dcm']) di.inputs.in_files = [dicom] assert_equal(di.inputs.in_files, [dicom]) nipype-0.11.0/nipype/interfaces/spm/utils.py000066400000000000000000000376471257611314500210630ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from nipype.interfaces.spm.base import SPMCommandInputSpec, SPMCommand, Info, scans_for_fnames, scans_for_fname from nipype.interfaces.matlab import MatlabCommand from nipype.interfaces.base import (TraitedSpec, BaseInterface, BaseInterfaceInputSpec, isdefined, OutputMultiPath, InputMultiPath) from nipype.interfaces.base import File, traits from nipype.utils.filemanip import split_filename, fname_presuffix, filename_to_list,list_to_filename import os import numpy as np class Analyze2niiInputSpec(SPMCommandInputSpec): analyze_file = File(exists=True, mandatory=True) class Analyze2niiOutputSpec(SPMCommandInputSpec): nifti_file = File(exists=True) class Analyze2nii(SPMCommand): input_spec = Analyze2niiInputSpec output_spec = Analyze2niiOutputSpec def _make_matlab_command(self, _): script = "V = spm_vol('%s');\n"%self.inputs.analyze_file _, name,_ = split_filename(self.inputs.analyze_file) self.output_name = os.path.join(os.getcwd(), name + ".nii") script += "[Y, XYZ] = spm_read_vols(V);\n" script += "V.fname = '%s';\n"%self.output_name script += "spm_write_vol(V, Y);\n" return script def _list_outputs(self): outputs = self._outputs().get() outputs['nifti_file'] = self.output_name return outputs class CalcCoregAffineInputSpec(SPMCommandInputSpec): target = File( exists = True, mandatory = True, desc = 'target for generating affine transform') moving = File( exists = True, mandatory = True, copyfile=False, desc = 'volume transform can be applied to register with target') mat = File( desc = 'Filename used to store affine matrix') invmat = File( desc = 'Filename used to store inverse affine matrix') class CalcCoregAffineOutputSpec(TraitedSpec): mat = File(exists = True, desc = 'Matlab file holding transform') invmat = File( desc = 'Matlab file holding inverse transform') class CalcCoregAffine(SPMCommand): """ Uses SPM (spm_coreg) to calculate the transform mapping moving to target. Saves Transform in mat (matlab binary file) Also saves inverse transform Examples -------- >>> import nipype.interfaces.spm.utils as spmu >>> coreg = spmu.CalcCoregAffine(matlab_cmd='matlab-spm8') >>> coreg.inputs.target = 'structural.nii' >>> coreg.inputs.moving = 'functional.nii' >>> coreg.inputs.mat = 'func_to_struct.mat' >>> coreg.run() # doctest: +SKIP .. note:: * the output file mat is saves as a matlab binary file * calculating the transforms does NOT change either input image it does not **move** the moving image, only calculates the transform that can be used to move it """ input_spec = CalcCoregAffineInputSpec output_spec = CalcCoregAffineOutputSpec def _make_inv_file(self): """ makes filename to hold inverse transform if not specified""" invmat = fname_presuffix(self.inputs.mat, prefix = 'inverse_') return invmat def _make_mat_file(self): """ makes name for matfile if doesn exist""" pth, mv, _ = split_filename(self.inputs.moving) _, tgt, _ = split_filename(self.inputs.target) mat = os.path.join(pth, '%s_to_%s.mat'%(mv,tgt)) return mat def _make_matlab_command(self, _): """checks for SPM, generates script""" if not isdefined(self.inputs.mat): self.inputs.mat = self._make_mat_file() if not isdefined(self.inputs.invmat): self.inputs.invmat = self._make_inv_file() script = """ target = '%s'; moving = '%s'; targetv = spm_vol(target); movingv = spm_vol(moving); x = spm_coreg(targetv, movingv); M = spm_matrix(x); save('%s' , 'M' ); M = inv(M); save('%s','M') """%(self.inputs.target, self.inputs.moving, self.inputs.mat, self.inputs.invmat) return script def _list_outputs(self): outputs = self._outputs().get() outputs['mat'] = os.path.abspath(self.inputs.mat) outputs['invmat'] = os.path.abspath(self.inputs.invmat) return outputs class ApplyTransformInputSpec(SPMCommandInputSpec): in_file = File( exists = True, mandatory = True, copyfile=True, desc='file to apply transform to, (only updates header)') mat = File( exists = True, mandatory = True, desc='file holding transform to apply') out_file = File(desc="output file name for transformed data", genfile=True) class ApplyTransformOutputSpec(TraitedSpec): out_file = File(exists = True, desc = 'Transformed image file') class ApplyTransform(SPMCommand): """ Uses SPM to apply transform stored in a .mat file to given file Examples -------- >>> import nipype.interfaces.spm.utils as spmu >>> applymat = spmu.ApplyTransform() >>> applymat.inputs.in_file = 'functional.nii' >>> applymat.inputs.mat = 'func_to_struct.mat' >>> applymat.run() # doctest: +SKIP """ input_spec = ApplyTransformInputSpec output_spec = ApplyTransformOutputSpec def _make_matlab_command(self, _): """checks for SPM, generates script""" outputs = self._list_outputs() self.inputs.out_file = outputs['out_file'] script = """ infile = '%s'; outfile = '%s' transform = load('%s'); V = spm_vol(infile); X = spm_read_vols(V); [p n e v] = spm_fileparts(V.fname); V.mat = transform.M * V.mat; V.fname = fullfile(outfile); spm_write_vol(V,X); """%(self.inputs.in_file, self.inputs.out_file, self.inputs.mat) #img_space = spm_get_space(infile); #spm_get_space(infile, transform.M * img_space); return script def _list_outputs(self): outputs = self.output_spec().get() if not isdefined(self.inputs.out_file): outputs['out_file'] = os.path.abspath(self._gen_outfilename()) else: outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs def _gen_outfilename(self): _, name, _ = split_filename(self.inputs.in_file) return name + '_trans.nii' class ResliceInputSpec(SPMCommandInputSpec): in_file = File( exists = True, mandatory=True, desc='file to apply transform to, (only updates header)') space_defining = File ( exists = True, mandatory = True, desc = 'Volume defining space to slice in_file into') interp = traits.Range(low = 0, high = 7, usedefault = True, desc='degree of b-spline used for interpolation'\ '0 is nearest neighbor (default)') out_file = File(desc = 'Optional file to save resliced volume') class ResliceOutputSpec(TraitedSpec): out_file = File( exists = True, desc = 'resliced volume') class Reslice(SPMCommand): """ uses spm_reslice to resample in_file into space of space_defining""" input_spec = ResliceInputSpec output_spec = ResliceOutputSpec def _make_matlab_command(self, _): """ generates script""" if not isdefined(self.inputs.out_file): self.inputs.out_file = fname_presuffix(self.inputs.in_file, prefix = 'r') script = """ flags.mean = 0; flags.which = 1; flags.mask = 0; flags.interp = %d; infiles = strvcat(\'%s\', \'%s\'); invols = spm_vol(infiles); spm_reslice(invols, flags); """%(self.inputs.interp, self.inputs.space_defining, self.inputs.in_file) return script def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = os.path.abspath(self.inputs.out_file) return outputs class ApplyInverseDeformationInput(SPMCommandInputSpec): in_files = InputMultiPath( File(exists=True), mandatory=True, field='fnames', desc='Files on which deformation is applied') target = File( exists=True, field='comp{1}.inv.space', desc='File defining target space') deformation = File( exists=True, field='comp{1}.inv.comp{1}.sn2def.matname', desc='SN SPM deformation file', xor=['deformation_field']) deformation_field = File( exists=True, field='comp{1}.inv.comp{1}.def', desc='SN SPM deformation file', xor=['deformation']) interpolation = traits.Range( low=0, high=7, field='interp', desc='degree of b-spline used for interpolation') bounding_box = traits.List( traits.Float(), field='comp{1}.inv.comp{1}.sn2def.bb', minlen=6, maxlen=6, desc='6-element list (opt)') voxel_sizes = traits.List( traits.Float(), field='comp{1}.inv.comp{1}.sn2def.vox', minlen=3, maxlen=3, desc='3-element list (opt)') class ApplyInverseDeformationOutput(TraitedSpec): out_files = OutputMultiPath(File(exists=True), desc='Transformed files') class ApplyInverseDeformation(SPMCommand): """ Uses spm to apply inverse deformation stored in a .mat file or a deformation field to a given file Examples -------- >>> import nipype.interfaces.spm.utils as spmu >>> inv = spmu.ApplyInverseDeformation() >>> inv.inputs.in_files = 'functional.nii' >>> inv.inputs.deformation = 'struct_to_func.mat' >>> inv.inputs.target = 'structural.nii' >>> inv.run() # doctest: +SKIP """ input_spec = ApplyInverseDeformationInput output_spec = ApplyInverseDeformationOutput _jobtype = 'util' _jobname = 'defs' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': return scans_for_fnames(filename_to_list(val)) if opt == 'target': return scans_for_fname(filename_to_list(val)) if opt == 'deformation': return np.array([list_to_filename(val)], dtype=object) if opt == 'deformation_field': return np.array([list_to_filename(val)], dtype=object) return val def _list_outputs(self): outputs = self._outputs().get() outputs['out_files'] = [] for filename in self.inputs.in_files: _, fname = os.path.split(filename) outputs['out_files'].append(os.path.realpath('w%s' % fname)) return outputs class ResliceToReferenceInput(SPMCommandInputSpec): in_files = InputMultiPath( File(exists=True), mandatory=True, field='fnames', desc='Files on which deformation is applied') target = File( exists=True, field='comp{1}.id.space', desc='File defining target space') interpolation = traits.Range( low=0, high=7, field='interp', desc='degree of b-spline used for interpolation') bounding_box = traits.List( traits.Float(), field='comp{2}.idbbvox.bb', minlen=6, maxlen=6, desc='6-element list (opt)') voxel_sizes = traits.List( traits.Float(), field='comp{2}.idbbvox.vox', minlen=3, maxlen=3, desc='3-element list (opt)') class ResliceToReferenceOutput(TraitedSpec): out_files = OutputMultiPath(File(exists=True), desc='Transformed files') class ResliceToReference(SPMCommand): """ Uses spm to reslice a volume to a target image space or to a provided voxel size and bounding box Examples -------- >>> import nipype.interfaces.spm.utils as spmu >>> r2ref = spmu.ResliceToReference() >>> r2ref.inputs.in_files = 'functional.nii' >>> r2ref.inputs.target = 'structural.nii' >>> r2ref.run() # doctest: +SKIP """ input_spec = ResliceToReferenceInput output_spec = ResliceToReferenceOutput _jobtype = 'util' _jobname = 'defs' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': return scans_for_fnames(filename_to_list(val)) if opt == 'target': return scans_for_fname(filename_to_list(val)) if opt == 'deformation': return np.array([list_to_filename(val)], dtype=object) if opt == 'deformation_field': return np.array([list_to_filename(val)], dtype=object) return val def _list_outputs(self): outputs = self._outputs().get() outputs['out_files'] = [] for filename in self.inputs.in_files: _, fname = os.path.split(filename) outputs['out_files'].append(os.path.realpath('w%s' % fname)) return outputs class DicomImportInputSpec(SPMCommandInputSpec): in_files = InputMultiPath( File(exists=True), mandatory=True, field='data', desc='dicom files to be converted') output_dir_struct = traits.Enum( 'flat', 'series', 'patname', 'patid_date', 'patid', 'date_time', field='root', usedefault=True, desc='directory structure for the output.') output_dir = traits.Str('./converted_dicom', field='outdir', usedefault=True, desc='output directory.') format = traits.Enum( 'nii', 'img', field='convopts.format', usedefault=True, desc='output format.') icedims = traits.Bool(False, field='convopts.icedims', usedefault=True, desc='If image sorting fails, one can try using the additional\ SIEMENS ICEDims information to create unique filenames.\ Use this only if there would be multiple volumes with\ exactly the same file names.') class DicomImportOutputSpec(TraitedSpec): out_files = OutputMultiPath(File(exists=True), desc='converted files') class DicomImport(SPMCommand): """ Uses spm to convert DICOM files to nii or img+hdr. Examples -------- >>> import nipype.interfaces.spm.utils as spmu >>> di = spmu.DicomImport() >>> di.inputs.in_files = ['functional_1.dcm', 'functional_2.dcm'] >>> di.run() # doctest: +SKIP """ input_spec = DicomImportInputSpec output_spec = DicomImportOutputSpec _jobtype = 'util' _jobname = 'dicom' def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': return np.array(val, dtype=object) if opt == 'output_dir': return np.array([val], dtype=object) if opt == 'output_dir': return os.path.abspath(val) if opt == 'icedims': if val: return 1 return 0 return super(DicomImport, self)._format_arg(opt, spec, val) def _run_interface(self, runtime): od = os.path.abspath(self.inputs.output_dir) if not os.path.isdir(od): os.mkdir(od) return super(DicomImport, self)._run_interface(runtime) def _list_outputs(self): from glob import glob outputs = self._outputs().get() od = os.path.abspath(self.inputs.output_dir) ext = self.inputs.format if self.inputs.output_dir_struct == "flat": outputs['out_files'] = glob(os.path.join(od, '*.%s'%ext)) elif self.inputs.output_dir_struct == 'series': outputs['out_files'] = glob(os.path.join(od, os.path.join('*','*.%s'%ext))) elif self.inputs.output_dir_struct in ['patid', 'date_time', 'patname']: outputs['out_files'] = glob(os.path.join(od, os.path.join('*','*','*.%s'%ext))) elif self.inputs.output_dir_struct == 'patid_date': outputs['out_files'] = glob(os.path.join(od, os.path.join('*','*','*','*.%s'%ext))) return outputs nipype-0.11.0/nipype/interfaces/tests/000077500000000000000000000000001257611314500176735ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/tests/realign_json.json000066400000000000000000000016431257611314500232440ustar00rootroot00000000000000{ "cwd": "/home/cburns/data/nipype-tutorial/workingdir/_subject_id_s1/Realign.spm", "flags": null, "fwhm": null, "infile": [ [ "/home/cburns/data/nipype-tutorial/data/s1/f3.nii", "a3c80eb0260e7501b1458c462f51c77f" ], [ "/home/cburns/data/nipype-tutorial/data/s1/f5.nii", "9d6931fbd1b295fef475a2fe1eba5b5d" ], [ "/home/cburns/data/nipype-tutorial/data/s1/f7.nii", "bddcecd01af1cd16bcda369e685c8c89" ], [ "/home/cburns/data/nipype-tutorial/data/s1/f10.nii", "d75253b6ec33489adb72daa7b5b3bf31" ] ], "interp": null, "quality": null, "register_to_mean": true, "separation": null, "weight_img": null, "wrap": null, "write": true, "write_interp": null, "write_mask": null, "write_which": null, "write_wrap": null }nipype-0.11.0/nipype/interfaces/tests/test_auto_AssertEqual.py000066400000000000000000000010541257611314500245650ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import AssertEqual def test_AssertEqual_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), volume1=dict(mandatory=True, ), volume2=dict(mandatory=True, ), ) inputs = AssertEqual.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_BaseInterface.py000066400000000000000000000007371257611314500250360ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.base import BaseInterface def test_BaseInterface_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), ) inputs = BaseInterface.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_C3dAffineTool.py000066400000000000000000000023371257611314500247210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.c3 import C3dAffineTool def test_C3dAffineTool_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), fsl2ras=dict(argstr='-fsl2ras', position=4, ), ignore_exception=dict(nohash=True, usedefault=True, ), itk_transform=dict(argstr='-oitk %s', hash_files=False, position=5, ), reference_file=dict(argstr='-ref %s', position=1, ), source_file=dict(argstr='-src %s', position=2, ), terminal_output=dict(nohash=True, ), transform_file=dict(argstr='%s', position=3, ), ) inputs = C3dAffineTool.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_C3dAffineTool_outputs(): output_map = dict(itk_transform=dict(), ) outputs = C3dAffineTool.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_CSVReader.py000066400000000000000000000013551257611314500241160ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import CSVReader def test_CSVReader_inputs(): input_map = dict(header=dict(usedefault=True, ), in_file=dict(mandatory=True, ), ) inputs = CSVReader.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CSVReader_outputs(): output_map = dict() outputs = CSVReader.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_CommandLine.py000066400000000000000000000011421257611314500245200ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.base import CommandLine def test_CommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = CommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_CopyMeta.py000066400000000000000000000014721257611314500240610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import CopyMeta def test_CopyMeta_inputs(): input_map = dict(dest_file=dict(mandatory=True, ), exclude_classes=dict(), include_classes=dict(), src_file=dict(mandatory=True, ), ) inputs = CopyMeta.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_CopyMeta_outputs(): output_map = dict(dest_file=dict(), ) outputs = CopyMeta.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_DataFinder.py000066400000000000000000000016561257611314500243450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import DataFinder def test_DataFinder_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), ignore_regexes=dict(), match_regex=dict(usedefault=True, ), max_depth=dict(), min_depth=dict(), root_paths=dict(mandatory=True, ), unpack_single=dict(usedefault=True, ), ) inputs = DataFinder.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DataFinder_outputs(): output_map = dict() outputs = DataFinder.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_DataGrabber.py000066400000000000000000000016411257611314500244740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import DataGrabber def test_DataGrabber_inputs(): input_map = dict(base_directory=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), raise_on_empty=dict(usedefault=True, ), sort_filelist=dict(mandatory=True, ), template=dict(mandatory=True, ), template_args=dict(), ) inputs = DataGrabber.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DataGrabber_outputs(): output_map = dict() outputs = DataGrabber.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_DataSink.py000066400000000000000000000017721257611314500240410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import DataSink def test_DataSink_inputs(): input_map = dict(_outputs=dict(usedefault=True, ), base_directory=dict(), container=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), parameterization=dict(usedefault=True, ), regexp_substitutions=dict(), remove_dest_dir=dict(usedefault=True, ), strip_dir=dict(), substitutions=dict(), ) inputs = DataSink.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DataSink_outputs(): output_map = dict(out_file=dict(), ) outputs = DataSink.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Dcm2nii.py000066400000000000000000000041771257611314500236320ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcm2nii import Dcm2nii def test_Dcm2nii_inputs(): input_map = dict(anonymize=dict(argstr='-a', usedefault=True, ), args=dict(argstr='%s', ), collapse_folders=dict(argstr='-c', usedefault=True, ), config_file=dict(argstr='-b %s', genfile=True, ), convert_all_pars=dict(argstr='-v', usedefault=True, ), date_in_filename=dict(argstr='-d', usedefault=True, ), environ=dict(nohash=True, usedefault=True, ), events_in_filename=dict(argstr='-e', usedefault=True, ), gzip_output=dict(argstr='-g', usedefault=True, ), id_in_filename=dict(argstr='-i', usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), nii_output=dict(argstr='-n', usedefault=True, ), output_dir=dict(argstr='-o %s', genfile=True, ), protocol_in_filename=dict(argstr='-p', usedefault=True, ), reorient=dict(argstr='-r', ), reorient_and_crop=dict(argstr='-x', usedefault=True, ), source_dir=dict(argstr='%s', mandatory=True, position=-1, xor=['source_names'], ), source_in_filename=dict(argstr='-f', usedefault=True, ), source_names=dict(argstr='%s', copyfile=False, mandatory=True, position=-1, xor=['source_dir'], ), spm_analyze=dict(argstr='-s', xor=['nii_output'], ), terminal_output=dict(nohash=True, ), ) inputs = Dcm2nii.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Dcm2nii_outputs(): output_map = dict(bvals=dict(), bvecs=dict(), converted_files=dict(), reoriented_and_cropped_files=dict(), reoriented_files=dict(), ) outputs = Dcm2nii.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_DcmStack.py000066400000000000000000000016521257611314500240310ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import DcmStack def test_DcmStack_inputs(): input_map = dict(dicom_files=dict(mandatory=True, ), embed_meta=dict(), exclude_regexes=dict(), force_read=dict(usedefault=True, ), include_regexes=dict(), out_ext=dict(usedefault=True, ), out_format=dict(), out_path=dict(), ) inputs = DcmStack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_DcmStack_outputs(): output_map = dict(out_file=dict(), ) outputs = DcmStack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_FreeSurferSource.py000066400000000000000000000044151257611314500255710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import FreeSurferSource def test_FreeSurferSource_inputs(): input_map = dict(hemi=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), subject_id=dict(mandatory=True, ), subjects_dir=dict(mandatory=True, ), ) inputs = FreeSurferSource.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_FreeSurferSource_outputs(): output_map = dict(BA_stats=dict(altkey='BA', loc='stats', ), T1=dict(loc='mri', ), annot=dict(altkey='*annot', loc='label', ), aparc_a2009s_stats=dict(altkey='aparc.a2009s', loc='stats', ), aparc_aseg=dict(altkey='aparc*aseg', loc='mri', ), aparc_stats=dict(altkey='aparc', loc='stats', ), aseg=dict(loc='mri', ), aseg_stats=dict(altkey='aseg', loc='stats', ), brain=dict(loc='mri', ), brainmask=dict(loc='mri', ), curv=dict(loc='surf', ), curv_stats=dict(altkey='curv', loc='stats', ), entorhinal_exvivo_stats=dict(altkey='entorhinal_exvivo', loc='stats', ), filled=dict(loc='mri', ), inflated=dict(loc='surf', ), label=dict(altkey='*label', loc='label', ), norm=dict(loc='mri', ), nu=dict(loc='mri', ), orig=dict(loc='mri', ), pial=dict(loc='surf', ), rawavg=dict(loc='mri', ), ribbon=dict(altkey='*ribbon', loc='mri', ), smoothwm=dict(loc='surf', ), sphere=dict(loc='surf', ), sphere_reg=dict(altkey='sphere.reg', loc='surf', ), sulc=dict(loc='surf', ), thickness=dict(loc='surf', ), volume=dict(loc='surf', ), white=dict(loc='surf', ), wm=dict(loc='mri', ), wmparc=dict(loc='mri', ), wmparc_stats=dict(altkey='wmparc', loc='stats', ), ) outputs = FreeSurferSource.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Function.py000066400000000000000000000014101257611314500241150ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import Function def test_Function_inputs(): input_map = dict(function_str=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), ) inputs = Function.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Function_outputs(): output_map = dict() outputs = Function.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_GroupAndStack.py000066400000000000000000000017031257611314500250420ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import GroupAndStack def test_GroupAndStack_inputs(): input_map = dict(dicom_files=dict(mandatory=True, ), embed_meta=dict(), exclude_regexes=dict(), force_read=dict(usedefault=True, ), include_regexes=dict(), out_ext=dict(usedefault=True, ), out_format=dict(), out_path=dict(), ) inputs = GroupAndStack.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_GroupAndStack_outputs(): output_map = dict(out_list=dict(), ) outputs = GroupAndStack.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_IOBase.py000066400000000000000000000007101257611314500234340ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import IOBase def test_IOBase_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), ) inputs = IOBase.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_IdentityInterface.py000066400000000000000000000013051257611314500257450ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import IdentityInterface def test_IdentityInterface_inputs(): input_map = dict() inputs = IdentityInterface.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_IdentityInterface_outputs(): output_map = dict() outputs = IdentityInterface.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_JSONFileGrabber.py000066400000000000000000000014421257611314500251730ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import JSONFileGrabber def test_JSONFileGrabber_inputs(): input_map = dict(defaults=dict(), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(), ) inputs = JSONFileGrabber.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JSONFileGrabber_outputs(): output_map = dict() outputs = JSONFileGrabber.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_JSONFileSink.py000066400000000000000000000015471257611314500245410ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import JSONFileSink def test_JSONFileSink_inputs(): input_map = dict(_outputs=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_dict=dict(usedefault=True, ), out_file=dict(), ) inputs = JSONFileSink.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_JSONFileSink_outputs(): output_map = dict(out_file=dict(), ) outputs = JSONFileSink.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_LookupMeta.py000066400000000000000000000013651257611314500244210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import LookupMeta def test_LookupMeta_inputs(): input_map = dict(in_file=dict(mandatory=True, ), meta_keys=dict(mandatory=True, ), ) inputs = LookupMeta.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_LookupMeta_outputs(): output_map = dict() outputs = LookupMeta.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_MatlabCommand.py000066400000000000000000000023771257611314500250440ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.matlab import MatlabCommand def test_MatlabCommand_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), logfile=dict(argstr='-logfile %s', ), mfile=dict(usedefault=True, ), nodesktop=dict(argstr='-nodesktop', nohash=True, usedefault=True, ), nosplash=dict(argstr='-nosplash', nohash=True, usedefault=True, ), paths=dict(), postscript=dict(usedefault=True, ), prescript=dict(usedefault=True, ), script=dict(argstr='-r "%s;exit"', mandatory=True, position=-1, ), script_file=dict(usedefault=True, ), single_comp_thread=dict(argstr='-singleCompThread', nohash=True, ), terminal_output=dict(nohash=True, ), uses_mcr=dict(nohash=True, xor=['nodesktop', 'nosplash', 'single_comp_thread'], ), ) inputs = MatlabCommand.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Merge.py000066400000000000000000000014561257611314500234010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import Merge def test_Merge_inputs(): input_map = dict(axis=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), no_flatten=dict(usedefault=True, ), ) inputs = Merge.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Merge_outputs(): output_map = dict(out=dict(), ) outputs = Merge.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_MergeNifti.py000066400000000000000000000015431257611314500243700ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import MergeNifti def test_MergeNifti_inputs(): input_map = dict(in_files=dict(mandatory=True, ), merge_dim=dict(), out_ext=dict(usedefault=True, ), out_format=dict(), out_path=dict(), sort_order=dict(), ) inputs = MergeNifti.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MergeNifti_outputs(): output_map = dict(out_file=dict(), ) outputs = MergeNifti.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_MeshFix.py000066400000000000000000000057211257611314500237040ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.meshfix import MeshFix def test_MeshFix_inputs(): input_map = dict(args=dict(argstr='%s', ), cut_inner=dict(argstr='--cut-inner %d', ), cut_outer=dict(argstr='--cut-outer %d', ), decouple_inin=dict(argstr='--decouple-inin %d', ), decouple_outin=dict(argstr='--decouple-outin %d', ), decouple_outout=dict(argstr='--decouple-outout %d', ), dilation=dict(argstr='--dilate %d', ), dont_clean=dict(argstr='--no-clean', ), environ=dict(nohash=True, usedefault=True, ), epsilon_angle=dict(argstr='-a %f', ), finetuning_distance=dict(argstr='%f', requires=['finetuning_substeps'], ), finetuning_inwards=dict(argstr='--fineTuneIn ', requires=['finetuning_distance', 'finetuning_substeps'], ), finetuning_outwards=dict(argstr='--fineTuneIn ', requires=['finetuning_distance', 'finetuning_substeps'], xor=['finetuning_inwards'], ), finetuning_substeps=dict(argstr='%d', requires=['finetuning_distance'], ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file1=dict(argstr='%s', mandatory=True, position=1, ), in_file2=dict(argstr='%s', position=2, ), join_closest_components=dict(argstr='-jc', xor=['join_closest_components'], ), join_overlapping_largest_components=dict(argstr='-j', xor=['join_closest_components'], ), laplacian_smoothing_steps=dict(argstr='--smooth %d', ), number_of_biggest_shells=dict(argstr='--shells %d', ), out_filename=dict(argstr='-o %s', genfile=True, ), output_type=dict(usedefault=True, ), quiet_mode=dict(argstr='-q', ), remove_handles=dict(argstr='--remove-handles', ), save_as_freesurfer_mesh=dict(argstr='--fsmesh', xor=['save_as_vrml', 'save_as_stl'], ), save_as_stl=dict(argstr='--stl', xor=['save_as_vmrl', 'save_as_freesurfer_mesh'], ), save_as_vmrl=dict(argstr='--wrl', xor=['save_as_stl', 'save_as_freesurfer_mesh'], ), set_intersections_to_one=dict(argstr='--intersect', ), terminal_output=dict(nohash=True, ), uniform_remeshing_steps=dict(argstr='-u %d', requires=['uniform_remeshing_vertices'], ), uniform_remeshing_vertices=dict(argstr='--vertices %d', requires=['uniform_remeshing_steps'], ), x_shift=dict(argstr='--smooth %d', ), ) inputs = MeshFix.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_MeshFix_outputs(): output_map = dict(mesh_file=dict(), ) outputs = MeshFix.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_MpiCommandLine.py000066400000000000000000000012501257611314500251660ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.base import MpiCommandLine def test_MpiCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), n_procs=dict(), terminal_output=dict(nohash=True, ), use_mpi=dict(usedefault=True, ), ) inputs = MpiCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_MySQLSink.py000066400000000000000000000014021257611314500241230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import MySQLSink def test_MySQLSink_inputs(): input_map = dict(config=dict(mandatory=True, xor=['host'], ), database_name=dict(mandatory=True, ), host=dict(mandatory=True, requires=['username', 'password'], usedefault=True, xor=['config'], ), ignore_exception=dict(nohash=True, usedefault=True, ), password=dict(), table_name=dict(mandatory=True, ), username=dict(), ) inputs = MySQLSink.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_NiftiGeneratorBase.py000066400000000000000000000007621257611314500260540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import NiftiGeneratorBase def test_NiftiGeneratorBase_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), ) inputs = NiftiGeneratorBase.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Rename.py000066400000000000000000000015251257611314500235460ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import Rename def test_Rename_inputs(): input_map = dict(format_string=dict(mandatory=True, ), in_file=dict(mandatory=True, ), keep_ext=dict(), parse_string=dict(), use_fullpath=dict(usedefault=True, ), ) inputs = Rename.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Rename_outputs(): output_map = dict(out_file=dict(), ) outputs = Rename.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SEMLikeCommandLine.py000066400000000000000000000011671257611314500257010ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.base import SEMLikeCommandLine def test_SEMLikeCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), terminal_output=dict(nohash=True, ), ) inputs = SEMLikeCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SQLiteSink.py000066400000000000000000000010551257611314500243230ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import SQLiteSink def test_SQLiteSink_inputs(): input_map = dict(database_file=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), table_name=dict(mandatory=True, ), ) inputs = SQLiteSink.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SSHDataGrabber.py000066400000000000000000000022551257611314500250540ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import SSHDataGrabber def test_SSHDataGrabber_inputs(): input_map = dict(base_directory=dict(mandatory=True, ), download_files=dict(usedefault=True, ), hostname=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), password=dict(), raise_on_empty=dict(usedefault=True, ), sort_filelist=dict(mandatory=True, ), ssh_log_to_file=dict(usedefault=True, ), template=dict(mandatory=True, ), template_args=dict(), template_expression=dict(usedefault=True, ), username=dict(), ) inputs = SSHDataGrabber.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SSHDataGrabber_outputs(): output_map = dict() outputs = SSHDataGrabber.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Select.py000066400000000000000000000014561257611314500235610ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import Select def test_Select_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), index=dict(mandatory=True, ), inlist=dict(mandatory=True, ), ) inputs = Select.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Select_outputs(): output_map = dict(out=dict(), ) outputs = Select.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SelectFiles.py000066400000000000000000000016141257611314500245400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import SelectFiles def test_SelectFiles_inputs(): input_map = dict(base_directory=dict(), force_lists=dict(usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), raise_on_empty=dict(usedefault=True, ), sort_filelist=dict(usedefault=True, ), ) inputs = SelectFiles.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SelectFiles_outputs(): output_map = dict() outputs = SelectFiles.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SlicerCommandLine.py000066400000000000000000000016531257611314500256710ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dynamic_slicer import SlicerCommandLine def test_SlicerCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), module=dict(), terminal_output=dict(nohash=True, ), ) inputs = SlicerCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SlicerCommandLine_outputs(): output_map = dict() outputs = SlicerCommandLine.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_Split.py000066400000000000000000000015031257611314500234260ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.utility import Split def test_Split_inputs(): input_map = dict(ignore_exception=dict(nohash=True, usedefault=True, ), inlist=dict(mandatory=True, ), splits=dict(mandatory=True, ), squeeze=dict(usedefault=True, ), ) inputs = Split.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Split_outputs(): output_map = dict() outputs = Split.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_SplitNifti.py000066400000000000000000000015131257611314500244210ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.dcmstack import SplitNifti def test_SplitNifti_inputs(): input_map = dict(in_file=dict(mandatory=True, ), out_ext=dict(usedefault=True, ), out_format=dict(), out_path=dict(), split_dim=dict(), ) inputs = SplitNifti.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_SplitNifti_outputs(): output_map = dict(out_list=dict(), ) outputs = SplitNifti.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_StdOutCommandLine.py000066400000000000000000000012771257611314500256740ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.base import StdOutCommandLine def test_StdOutCommandLine_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), out_file=dict(argstr='> %s', genfile=True, position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = StdOutCommandLine.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_XNATSink.py000066400000000000000000000017341257611314500237400ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import XNATSink def test_XNATSink_inputs(): input_map = dict(_outputs=dict(usedefault=True, ), assessor_id=dict(xor=['reconstruction_id'], ), cache_dir=dict(), config=dict(mandatory=True, xor=['server'], ), experiment_id=dict(mandatory=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), project_id=dict(mandatory=True, ), pwd=dict(), reconstruction_id=dict(xor=['assessor_id'], ), server=dict(mandatory=True, requires=['user', 'pwd'], xor=['config'], ), share=dict(usedefault=True, ), subject_id=dict(mandatory=True, ), user=dict(), ) inputs = XNATSink.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_auto_XNATSource.py000066400000000000000000000020171257611314500242670ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.io import XNATSource def test_XNATSource_inputs(): input_map = dict(cache_dir=dict(), config=dict(mandatory=True, xor=['server'], ), ignore_exception=dict(nohash=True, usedefault=True, ), pwd=dict(), query_template=dict(mandatory=True, ), query_template_args=dict(usedefault=True, ), server=dict(mandatory=True, requires=['user', 'pwd'], xor=['config'], ), user=dict(), ) inputs = XNATSource.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_XNATSource_outputs(): output_map = dict() outputs = XNATSource.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/tests/test_base.py000066400000000000000000000551531257611314500222270ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import tempfile import shutil from nipype.testing import (assert_equal, assert_not_equal, assert_raises, assert_true, assert_false, with_setup, package_check, skipif) import nipype.interfaces.base as nib from nipype.utils.filemanip import split_filename from nipype.interfaces.base import Undefined, config from traits.testing.nose_tools import skip import traits.api as traits #test Bunch def test_bunch(): b = nib.Bunch() yield assert_equal, b.__dict__,{} b = nib.Bunch(a=1,b=[2,3]) yield assert_equal, b.__dict__,{'a': 1, 'b': [2,3]} def test_bunch_attribute(): b = nib.Bunch(a=1,b=[2,3],c=None) yield assert_equal, b.a ,1 yield assert_equal, b.b, [2,3] yield assert_equal, b.c, None def test_bunch_repr(): b = nib.Bunch(b=2,c=3,a=dict(n=1,m=2)) yield assert_equal, repr(b), "Bunch(a={'m': 2, 'n': 1}, b=2, c=3)" def test_bunch_methods(): b = nib.Bunch(a=2) b.update(a=3) newb = b.dictcopy() yield assert_equal, b.a, 3 yield assert_equal, b.get('a'), 3 yield assert_equal, b.get('badkey', 'otherthing'), 'otherthing' yield assert_not_equal, b, newb yield assert_equal, type(dict()), type(newb) yield assert_equal, newb['a'], 3 def test_bunch_hash(): # NOTE: Since the path to the json file is included in the Bunch, # the hash will be unique to each machine. pth = os.path.split(os.path.abspath(__file__))[0] json_pth = os.path.join(pth, 'realign_json.json') b = nib.Bunch(infile = json_pth, otherthing = 'blue', yat = True) newbdict, bhash = b._get_bunch_hash() yield assert_equal, bhash, 'ddcc7b4ec5675df8cf317a48bd1857fa' # Make sure the hash stored in the json file for `infile` is correct. jshash = nib.md5() fp = file(json_pth) jshash.update(fp.read()) fp.close() yield assert_equal, newbdict['infile'][0][1], jshash.hexdigest() yield assert_equal, newbdict['yat'], True # create a temp file #global tmp_infile, tmp_dir #tmp_infile = None #tmp_dir = None def setup_file(): #global tmp_infile, tmp_dir tmp_dir = tempfile.mkdtemp() tmp_infile = os.path.join(tmp_dir, 'foo.txt') open(tmp_infile, 'w').writelines('123456789') return tmp_infile def teardown_file(tmp_dir): shutil.rmtree(tmp_dir) def test_TraitedSpec(): yield assert_true, nib.TraitedSpec().get_hashval() yield assert_equal, nib.TraitedSpec().__repr__(), '\n\n' class spec(nib.TraitedSpec): foo = nib.traits.Int goo = nib.traits.Float(usedefault=True) yield assert_equal, spec().foo, Undefined yield assert_equal, spec().goo, 0.0 specfunc = lambda x : spec(hoo=x) yield assert_raises, nib.traits.TraitError, specfunc, 1 infields = spec(foo=1) hashval = ([('foo', 1), ('goo', '0.0000000000')], 'e89433b8c9141aa0fda2f8f4d662c047') yield assert_equal, infields.get_hashval(), hashval #yield assert_equal, infields.hashval[1], hashval[1] yield assert_equal, infields.__repr__(), '\nfoo = 1\ngoo = 0.0\n' @skip def test_TraitedSpec_dynamic(): from cPickle import dumps, loads a = nib.BaseTraitedSpec() a.add_trait('foo', nib.traits.Int) a.foo = 1 assign_a = lambda : setattr(a, 'foo', 'a') yield assert_raises, Exception, assign_a pkld_a = dumps(a) unpkld_a = loads(pkld_a) assign_a_again = lambda : setattr(unpkld_a, 'foo', 'a') yield assert_raises, Exception, assign_a_again def test_TraitedSpec_logic(): class spec3(nib.TraitedSpec): _xor_inputs = ('foo', 'bar') foo = nib.traits.Int(xor = _xor_inputs, desc = 'foo or bar, not both') bar = nib.traits.Int(xor = _xor_inputs, desc = 'bar or foo, not both') kung = nib.traits.Float(requires = ('foo',), position = 0, desc = 'kung foo') class out3(nib.TraitedSpec): output = nib.traits.Int class MyInterface(nib.BaseInterface): input_spec = spec3 output_spec = out3 myif = MyInterface() yield assert_raises, TypeError, setattr(myif.inputs, 'kung', 10.0) myif.inputs.foo = 1 yield assert_equal, myif.inputs.foo, 1 set_bar = lambda : setattr(myif.inputs, 'bar', 1) yield assert_raises, IOError, set_bar yield assert_equal, myif.inputs.foo, 1 myif.inputs.kung = 2 yield assert_equal, myif.inputs.kung, 2.0 def test_deprecation(): class DeprecationSpec1(nib.TraitedSpec): foo = nib.traits.Int(deprecated='0.1') spec_instance = DeprecationSpec1() set_foo = lambda : setattr(spec_instance, 'foo', 1) yield assert_raises, nib.TraitError, set_foo class DeprecationSpec1numeric(nib.TraitedSpec): foo = nib.traits.Int(deprecated='0.1') spec_instance = DeprecationSpec1numeric() set_foo = lambda : setattr(spec_instance, 'foo', 1) yield assert_raises, nib.TraitError, set_foo class DeprecationSpec2(nib.TraitedSpec): foo = nib.traits.Int(deprecated='100', new_name='bar') spec_instance = DeprecationSpec2() set_foo = lambda : setattr(spec_instance, 'foo', 1) yield assert_raises, nib.TraitError, set_foo class DeprecationSpec3(nib.TraitedSpec): foo = nib.traits.Int(deprecated='1000', new_name='bar') bar = nib.traits.Int() spec_instance = DeprecationSpec3() not_raised = True try: spec_instance.foo = 1 except nib.TraitError: not_raised = False yield assert_true, not_raised class DeprecationSpec3(nib.TraitedSpec): foo = nib.traits.Int(deprecated='1000', new_name='bar') bar = nib.traits.Int() spec_instance = DeprecationSpec3() not_raised = True try: spec_instance.foo = 1 except nib.TraitError: not_raised = False yield assert_true, not_raised yield assert_equal, spec_instance.foo, Undefined yield assert_equal, spec_instance.bar, 1 def test_namesource(): tmp_infile = setup_file() tmpd, nme, ext = split_filename(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) class spec2(nib.CommandLineInputSpec): moo = nib.File(name_source=['doo'], hash_files=False, argstr="%s", position=2) doo = nib.File(exists=True, argstr="%s", position=1) goo = traits.Int(argstr="%d", position=4) poo = nib.File(name_source=['goo'], hash_files=False, argstr="%s",position=3) class TestName(nib.CommandLine): _cmd = "mycommand" input_spec = spec2 testobj = TestName() testobj.inputs.doo = tmp_infile testobj.inputs.goo = 99 yield assert_true, '%s_generated' % nme in testobj.cmdline testobj.inputs.moo = "my_%s_template" yield assert_true, 'my_%s_template' % nme in testobj.cmdline os.chdir(pwd) teardown_file(tmpd) def test_chained_namesource(): tmp_infile = setup_file() tmpd, nme, ext = split_filename(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) class spec2(nib.CommandLineInputSpec): doo = nib.File(exists=True, argstr="%s", position=1) moo = nib.File(name_source=['doo'], hash_files=False, argstr="%s", position=2, name_template='%s_mootpl') poo = nib.File(name_source=['moo'], hash_files=False, argstr="%s", position=3) class TestName(nib.CommandLine): _cmd = "mycommand" input_spec = spec2 testobj = TestName() testobj.inputs.doo = tmp_infile res = testobj.cmdline yield assert_true, '%s' % tmp_infile in res yield assert_true, '%s_mootpl ' % nme in res yield assert_true, '%s_mootpl_generated' % nme in res os.chdir(pwd) teardown_file(tmpd) def test_cycle_namesource1(): tmp_infile = setup_file() tmpd, nme, ext = split_filename(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) class spec3(nib.CommandLineInputSpec): moo = nib.File(name_source=['doo'], hash_files=False, argstr="%s", position=1, name_template='%s_mootpl') poo = nib.File(name_source=['moo'], hash_files=False, argstr="%s", position=2) doo = nib.File(name_source=['poo'], hash_files=False, argstr="%s", position=3) class TestCycle(nib.CommandLine): _cmd = "mycommand" input_spec = spec3 # Check that an exception is raised to0 = TestCycle() not_raised = True try: to0.cmdline except nib.NipypeInterfaceError: not_raised = False yield assert_false, not_raised os.chdir(pwd) teardown_file(tmpd) def test_cycle_namesource2(): tmp_infile = setup_file() tmpd, nme, ext = split_filename(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) class spec3(nib.CommandLineInputSpec): moo = nib.File(name_source=['doo'], hash_files=False, argstr="%s", position=1, name_template='%s_mootpl') poo = nib.File(name_source=['moo'], hash_files=False, argstr="%s", position=2) doo = nib.File(name_source=['poo'], hash_files=False, argstr="%s", position=3) class TestCycle(nib.CommandLine): _cmd = "mycommand" input_spec = spec3 # Check that loop can be broken by setting one of the inputs to1 = TestCycle() to1.inputs.poo = tmp_infile not_raised = True try: res = to1.cmdline except nib.NipypeInterfaceError: not_raised = False print res yield assert_true, not_raised yield assert_true, '%s' % tmp_infile in res yield assert_true, '%s_generated' % nme in res yield assert_true, '%s_generated_mootpl' % nme in res os.chdir(pwd) teardown_file(tmpd) def checknose(): """check version of nose for known incompatability""" mod = __import__('nose') if mod.__versioninfo__[1] <= 11: return 0 else: return 1 @skipif(checknose) def test_TraitedSpec_withFile(): tmp_infile = setup_file() tmpd, nme = os.path.split(tmp_infile) yield assert_true, os.path.exists(tmp_infile) class spec2(nib.TraitedSpec): moo = nib.File(exists=True) doo = nib.traits.List(nib.File(exists=True)) infields = spec2(moo=tmp_infile, doo=[tmp_infile]) hashval = infields.get_hashval(hash_method='content') yield assert_equal, hashval[1], 'a00e9ee24f5bfa9545a515b7a759886b' teardown_file(tmpd) @skipif(checknose) def test_TraitedSpec_withNoFileHashing(): tmp_infile = setup_file() tmpd, nme = os.path.split(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) yield assert_true, os.path.exists(tmp_infile) class spec2(nib.TraitedSpec): moo = nib.File(exists=True, hash_files=False) doo = nib.traits.List(nib.File(exists=True)) infields = spec2(moo=nme, doo=[tmp_infile]) hashval = infields.get_hashval(hash_method='content') yield assert_equal, hashval[1], '8da4669ff5d72f670a46ea3e7a203215' class spec3(nib.TraitedSpec): moo = nib.File(exists=True, name_source="doo") doo = nib.traits.List(nib.File(exists=True)) infields = spec3(moo=nme, doo=[tmp_infile]) hashval1 = infields.get_hashval(hash_method='content') class spec4(nib.TraitedSpec): moo = nib.File(exists=True) doo = nib.traits.List(nib.File(exists=True)) infields = spec4(moo=nme, doo=[tmp_infile]) hashval2 = infields.get_hashval(hash_method='content') yield assert_not_equal, hashval1[1], hashval2[1] os.chdir(pwd) teardown_file(tmpd) def test_Interface(): yield assert_equal, nib.Interface.input_spec, None yield assert_equal, nib.Interface.output_spec, None yield assert_raises, NotImplementedError, nib.Interface yield assert_raises, NotImplementedError, nib.Interface.help yield assert_raises, NotImplementedError, nib.Interface._inputs_help yield assert_raises, NotImplementedError, nib.Interface._outputs_help yield assert_raises, NotImplementedError, nib.Interface._outputs class DerivedInterface(nib.Interface): def __init__(self): pass nif = DerivedInterface() yield assert_raises, NotImplementedError, nif.run yield assert_raises, NotImplementedError, nif.aggregate_outputs yield assert_raises, NotImplementedError, nif._list_outputs yield assert_raises, NotImplementedError, nif._get_filecopy_info def test_BaseInterface(): yield assert_equal, nib.BaseInterface.help(), None yield assert_equal, nib.BaseInterface._get_filecopy_info(), [] class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int') goo = nib.traits.Int(desc='a random int', mandatory=True) moo = nib.traits.Int(desc='a random int', mandatory=False) hoo = nib.traits.Int(desc='a random int', usedefault=True) zoo = nib.File(desc='a file', copyfile=False) woo = nib.File(desc='a file', copyfile=True) class OutputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int') class DerivedInterface(nib.BaseInterface): input_spec = InputSpec yield assert_equal, DerivedInterface.help(), None yield assert_true, 'moo' in ''.join(DerivedInterface._inputs_help()) yield assert_equal, DerivedInterface()._outputs(), None yield assert_equal, DerivedInterface._get_filecopy_info()[0]['key'], 'woo' yield assert_true, DerivedInterface._get_filecopy_info()[0]['copy'] yield assert_equal, DerivedInterface._get_filecopy_info()[1]['key'], 'zoo' yield assert_false, DerivedInterface._get_filecopy_info()[1]['copy'] yield assert_equal, DerivedInterface().inputs.foo, Undefined yield assert_raises, ValueError, DerivedInterface()._check_mandatory_inputs yield assert_equal, DerivedInterface(goo=1)._check_mandatory_inputs(), None yield assert_raises, ValueError, DerivedInterface().run yield assert_raises, NotImplementedError, DerivedInterface(goo=1).run class DerivedInterface2(DerivedInterface): output_spec = OutputSpec def _run_interface(self, runtime): return runtime yield assert_equal, DerivedInterface2.help(), None yield assert_equal, DerivedInterface2()._outputs().foo, Undefined yield assert_raises, NotImplementedError, DerivedInterface2(goo=1).run nib.BaseInterface.input_spec = None yield assert_raises, Exception, nib.BaseInterface def test_input_version(): class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec obj = DerivedInterface1() not_raised = True try: obj._check_version_requirements(obj.inputs) except: not_raised = False yield assert_true, not_raised config.set('execution', 'stop_on_unknown_version', True) try: obj._check_version_requirements(obj.inputs) except: not_raised = False yield assert_false, not_raised config.set_default_config() class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec _version = '0.8' obj = DerivedInterface1() obj.inputs.foo = 1 yield assert_raises, Exception, obj._check_version_requirements class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec _version = '0.10' obj = DerivedInterface1() not_raised = True try: obj._check_version_requirements(obj.inputs) except: not_raised = False yield assert_true, not_raised class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec _version = '0.9' obj = DerivedInterface1() obj.inputs.foo = 1 not_raised = True try: obj._check_version_requirements(obj.inputs) except: not_raised = False yield assert_true, not_raised class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', max_ver='0.7') class DerivedInterface2(nib.BaseInterface): input_spec = InputSpec _version = '0.8' obj = DerivedInterface2() obj.inputs.foo = 1 yield assert_raises, Exception, obj._check_version_requirements class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', max_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec _version = '0.9' obj = DerivedInterface1() obj.inputs.foo = 1 not_raised = True try: obj._check_version_requirements(obj.inputs) except: not_raised = False yield assert_true, not_raised def test_output_version(): class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.9') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec _version = '0.10' obj = DerivedInterface1() yield assert_equal, obj._check_version_requirements(obj._outputs()), [] class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.11') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec _version = '0.10' obj = DerivedInterface1() yield assert_equal, obj._check_version_requirements(obj._outputs()), ['foo'] class InputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): foo = nib.traits.Int(desc='a random int', min_ver='0.11') class DerivedInterface1(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec _version = '0.10' def _run_interface(self, runtime): return runtime def _list_outputs(self): return {'foo': 1} obj = DerivedInterface1() yield assert_raises, KeyError, obj.run def test_Commandline(): yield assert_raises, Exception, nib.CommandLine ci = nib.CommandLine(command='which') yield assert_equal, ci.cmd, 'which' yield assert_equal, ci.inputs.args, Undefined ci2 = nib.CommandLine(command='which', args='ls') yield assert_equal, ci2.cmdline, 'which ls' ci3 = nib.CommandLine(command='echo') ci3.inputs.environ = {'MYENV' : 'foo'} res = ci3.run() yield assert_equal, res.runtime.environ['MYENV'], 'foo' yield assert_equal, res.outputs, None class CommandLineInputSpec1(nib.CommandLineInputSpec): foo = nib.traits.Str(argstr='%s', desc='a str') goo = nib.traits.Bool(argstr='-g', desc='a bool', position=0) hoo = nib.traits.List(argstr='-l %s', desc='a list') moo = nib.traits.List(argstr='-i %d...', desc='a repeated list', position=-1) noo = nib.traits.Int(argstr='-x %d', desc='an int') roo = nib.traits.Str(desc='not on command line') soo = nib.traits.Bool(argstr="-soo") nib.CommandLine.input_spec = CommandLineInputSpec1 ci4 = nib.CommandLine(command='cmd') ci4.inputs.foo = 'foo' ci4.inputs.goo = True ci4.inputs.hoo = ['a', 'b'] ci4.inputs.moo = [1, 2, 3] ci4.inputs.noo = 0 ci4.inputs.roo = 'hello' ci4.inputs.soo = False cmd = ci4._parse_inputs() yield assert_equal, cmd[0], '-g' yield assert_equal, cmd[-1], '-i 1 -i 2 -i 3' yield assert_true, 'hello' not in ' '.join(cmd) yield assert_true, '-soo' not in ' '.join(cmd) ci4.inputs.soo = True cmd = ci4._parse_inputs() yield assert_true, '-soo' in ' '.join(cmd) class CommandLineInputSpec2(nib.CommandLineInputSpec): foo = nib.File(argstr='%s', desc='a str', genfile=True) nib.CommandLine.input_spec = CommandLineInputSpec2 ci5 = nib.CommandLine(command='cmd') yield assert_raises, NotImplementedError, ci5._parse_inputs class DerivedClass(nib.CommandLine): input_spec = CommandLineInputSpec2 def _gen_filename(self, name): return 'filename' ci6 = DerivedClass(command='cmd') yield assert_equal, ci6._parse_inputs()[0], 'filename' nib.CommandLine.input_spec = nib.CommandLineInputSpec def test_Commandline_environ(): from nipype import config config.set_default_config() ci3 = nib.CommandLine(command='echo') res = ci3.run() yield assert_equal, res.runtime.environ['DISPLAY'], ':1' config.set('execution', 'display_variable', ':3') res = ci3.run() yield assert_false, 'DISPLAY' in ci3.inputs.environ yield assert_equal, res.runtime.environ['DISPLAY'], ':3' ci3.inputs.environ = {'DISPLAY' : ':2'} res = ci3.run() yield assert_equal, res.runtime.environ['DISPLAY'], ':2' def test_CommandLine_output(): tmp_infile = setup_file() tmpd, name = os.path.split(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) yield assert_true, os.path.exists(tmp_infile) ci = nib.CommandLine(command='ls -l') ci.inputs.terminal_output = 'allatonce' res = ci.run() yield assert_equal, res.runtime.merged, '' yield assert_true, name in res.runtime.stdout ci = nib.CommandLine(command='ls -l') ci.inputs.terminal_output = 'file' res = ci.run() yield assert_true, 'stdout.nipype' in res.runtime.stdout ci = nib.CommandLine(command='ls -l') ci.inputs.terminal_output = 'none' res = ci.run() yield assert_equal, res.runtime.stdout, '' ci = nib.CommandLine(command='ls -l') res = ci.run() yield assert_true, 'stdout.nipype' in res.runtime.stdout os.chdir(pwd) teardown_file(tmpd) def test_global_CommandLine_output(): tmp_infile = setup_file() tmpd, name = os.path.split(tmp_infile) pwd = os.getcwd() os.chdir(tmpd) ci = nib.CommandLine(command='ls -l') res = ci.run() yield assert_true, name in res.runtime.stdout yield assert_true, os.path.exists(tmp_infile) nib.CommandLine.set_default_terminal_output('allatonce') ci = nib.CommandLine(command='ls -l') res = ci.run() yield assert_equal, res.runtime.merged, '' yield assert_true, name in res.runtime.stdout nib.CommandLine.set_default_terminal_output('file') ci = nib.CommandLine(command='ls -l') res = ci.run() yield assert_true, 'stdout.nipype' in res.runtime.stdout nib.CommandLine.set_default_terminal_output('none') ci = nib.CommandLine(command='ls -l') res = ci.run() yield assert_equal, res.runtime.stdout, '' os.chdir(pwd) teardown_file(tmpd) nipype-0.11.0/nipype/interfaces/tests/test_io.py000066400000000000000000000241041257611314500217140ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import glob import shutil import os.path as op from tempfile import mkstemp, mkdtemp from nose.tools import assert_raises import nipype from nipype.testing import assert_equal, assert_true, assert_false import nipype.interfaces.io as nio from nipype.interfaces.base import Undefined def test_datagrabber(): dg = nio.DataGrabber() yield assert_equal, dg.inputs.template, Undefined yield assert_equal, dg.inputs.base_directory, Undefined yield assert_equal, dg.inputs.template_args, {'outfiles': []} def test_selectfiles(): base_dir = op.dirname(nipype.__file__) templates = {"model": "interfaces/{package}/model.py", "preprocess": "interfaces/{package}/pre*.py"} dg = nio.SelectFiles(templates, base_directory=base_dir) yield assert_equal, dg._infields, ["package"] yield assert_equal, sorted(dg._outfields), ["model", "preprocess"] dg.inputs.package = "fsl" res = dg.run() wanted = op.join(op.dirname(nipype.__file__), "interfaces/fsl/model.py") yield assert_equal, res.outputs.model, wanted dg = nio.SelectFiles(templates, base_directory=base_dir, force_lists=True) outfields = sorted(dg._outputs().get()) yield assert_equal, outfields, ["model", "preprocess"] dg.inputs.package = "spm" res = dg.run() wanted = op.join(op.dirname(nipype.__file__), "interfaces/spm/preprocess.py") yield assert_equal, res.outputs.preprocess, [wanted] dg.inputs.package = "fsl" dg.inputs.force_lists = ["model"] res = dg.run() preproc = op.join(op.dirname(nipype.__file__), "interfaces/fsl/preprocess.py") model = [op.join(op.dirname(nipype.__file__), "interfaces/fsl/model.py")] yield assert_equal, res.outputs.preprocess, preproc yield assert_equal, res.outputs.model, model templates = {"converter": "interfaces/dcm{to!s}nii.py"} dg = nio.SelectFiles(templates, base_directory=base_dir) dg.inputs.to = 2 res = dg.run() wanted = op.join(base_dir, "interfaces/dcm2nii.py") yield assert_equal, res.outputs.converter, wanted def test_selectfiles_valueerror(): """Test ValueError when force_lists has field that isn't in template.""" base_dir = op.dirname(nipype.__file__) templates = {"model": "interfaces/{package}/model.py", "preprocess": "interfaces/{package}/pre*.py"} force_lists = ["model", "preprocess", "registration"] sf = nio.SelectFiles(templates, base_directory=base_dir, force_lists=force_lists) yield assert_raises, ValueError, sf.run def test_datagrabber_order(): tempdir = mkdtemp() file1 = mkstemp(prefix='sub002_L1_R1.q', dir=tempdir) file2 = mkstemp(prefix='sub002_L1_R2.q', dir=tempdir) file3 = mkstemp(prefix='sub002_L2_R1.q', dir=tempdir) file4 = mkstemp(prefix='sub002_L2_R2.q', dir=tempdir) file5 = mkstemp(prefix='sub002_L3_R10.q', dir=tempdir) file6 = mkstemp(prefix='sub002_L3_R2.q', dir=tempdir) dg = nio.DataGrabber(infields=['sid']) dg.inputs.base_directory = tempdir dg.inputs.template = '%s_L%d_R*.q*' dg.inputs.template_args = {'outfiles': [['sid', 1], ['sid', 2], ['sid', 3]]} dg.inputs.sid = 'sub002' dg.inputs.sort_filelist = True res = dg.run() outfiles = res.outputs.outfiles yield assert_true, 'sub002_L1_R1' in outfiles[0][0] yield assert_true, 'sub002_L1_R2' in outfiles[0][1] yield assert_true, 'sub002_L2_R1' in outfiles[1][0] yield assert_true, 'sub002_L2_R2' in outfiles[1][1] yield assert_true, 'sub002_L3_R2' in outfiles[2][0] yield assert_true, 'sub002_L3_R10' in outfiles[2][1] shutil.rmtree(tempdir) def test_datasink(): ds = nio.DataSink() yield assert_true, ds.inputs.parameterization yield assert_equal, ds.inputs.base_directory, Undefined yield assert_equal, ds.inputs.strip_dir, Undefined yield assert_equal, ds.inputs._outputs, {} ds = nio.DataSink(base_directory='foo') yield assert_equal, ds.inputs.base_directory, 'foo' ds = nio.DataSink(infields=['test']) yield assert_true, 'test' in ds.inputs.copyable_trait_names() def test_datasink_substitutions(): indir = mkdtemp(prefix='-Tmp-nipype_ds_subs_in') outdir = mkdtemp(prefix='-Tmp-nipype_ds_subs_out') files = [] for n in ['ababab.n', 'xabababyz.n']: f = os.path.join(indir, n) files.append(f) open(f, 'w') ds = nio.DataSink( parametrization=False, base_directory=outdir, substitutions=[('ababab', 'ABABAB')], # end archoring ($) is used to assure operation on the filename # instead of possible temporary directories names matches # Patterns should be more comprehendable in the real-world usage # cases since paths would be quite more sensible regexp_substitutions=[(r'xABABAB(\w*)\.n$', r'a-\1-b.n'), ('(.*%s)[-a]([^%s]*)$' % ((os.path.sep,) * 2), r'\1!\2')]) setattr(ds.inputs, '@outdir', files) ds.run() yield assert_equal, \ sorted([os.path.basename(x) for x in glob.glob(os.path.join(outdir, '*'))]), \ ['!-yz-b.n', 'ABABAB.n'] # so we got re used 2nd and both patterns shutil.rmtree(indir) shutil.rmtree(outdir) def _temp_analyze_files(): """Generate temporary analyze file pair.""" fd, orig_img = mkstemp(suffix='.img', dir=mkdtemp()) orig_hdr = orig_img[:-4] + '.hdr' fp = file(orig_hdr, 'w+') fp.close() return orig_img, orig_hdr def test_datasink_copydir(): orig_img, orig_hdr = _temp_analyze_files() outdir = mkdtemp() pth, fname = os.path.split(orig_img) ds = nio.DataSink(base_directory=outdir, parameterization=False) setattr(ds.inputs, '@outdir', pth) ds.run() sep = os.path.sep file_exists = lambda: os.path.exists(os.path.join(outdir, pth.split(sep)[-1], fname)) yield assert_true, file_exists() shutil.rmtree(pth) orig_img, orig_hdr = _temp_analyze_files() pth, fname = os.path.split(orig_img) ds.inputs.remove_dest_dir = True setattr(ds.inputs, 'outdir', pth) ds.run() yield assert_false, file_exists() shutil.rmtree(outdir) shutil.rmtree(pth) def test_datafinder_copydir(): outdir = mkdtemp() open(os.path.join(outdir, "findme.txt"), 'a').close() open(os.path.join(outdir, "dontfindme"), 'a').close() open(os.path.join(outdir, "dontfindmealsotxt"), 'a').close() open(os.path.join(outdir, "findmetoo.txt"), 'a').close() open(os.path.join(outdir, "ignoreme.txt"), 'a').close() open(os.path.join(outdir, "alsoignore.txt"), 'a').close() from nipype.interfaces.io import DataFinder df = DataFinder() df.inputs.root_paths = outdir df.inputs.match_regex = '.+/(?P.+)\.txt' df.inputs.ignore_regexes = ['ignore'] result = df.run() expected = ["findme.txt", "findmetoo.txt"] for path, expected_fname in zip(result.outputs.out_paths, expected): _, fname = os.path.split(path) yield assert_equal, fname, expected_fname yield assert_equal, result.outputs.basename, ["findme", "findmetoo"] shutil.rmtree(outdir) def test_datafinder_depth(): outdir = mkdtemp() os.makedirs(os.path.join(outdir, '0', '1', '2', '3')) from nipype.interfaces.io import DataFinder df = DataFinder() df.inputs.root_paths = os.path.join(outdir, '0') for min_depth in range(4): for max_depth in range(min_depth, 4): df.inputs.min_depth = min_depth df.inputs.max_depth = max_depth result = df.run() expected = [str(x) for x in range(min_depth, max_depth + 1)] for path, exp_fname in zip(result.outputs.out_paths, expected): _, fname = os.path.split(path) yield assert_equal, fname, exp_fname shutil.rmtree(outdir) def test_datafinder_unpack(): outdir = mkdtemp() single_res = os.path.join(outdir, "findme.txt") open(single_res, 'a').close() open(os.path.join(outdir, "dontfindme"), 'a').close() from nipype.interfaces.io import DataFinder df = DataFinder() df.inputs.root_paths = outdir df.inputs.match_regex = '.+/(?P.+)\.txt' df.inputs.unpack_single = True result = df.run() print result.outputs.out_paths yield assert_equal, result.outputs.out_paths, single_res def test_freesurfersource(): fss = nio.FreeSurferSource() yield assert_equal, fss.inputs.hemi, 'both' yield assert_equal, fss.inputs.subject_id, Undefined yield assert_equal, fss.inputs.subjects_dir, Undefined def test_jsonsink(): import json import os ds = nio.JSONFileSink() yield assert_equal, ds.inputs._outputs, {} ds = nio.JSONFileSink(in_dict={'foo': 'var'}) yield assert_equal, ds.inputs.in_dict, {'foo': 'var'} ds = nio.JSONFileSink(infields=['test']) yield assert_true, 'test' in ds.inputs.copyable_trait_names() curdir = os.getcwd() outdir = mkdtemp() os.chdir(outdir) js = nio.JSONFileSink(infields=['test'], in_dict={'foo': 'var'}) js.inputs.new_entry = 'someValue' setattr(js.inputs, 'contrasts.alt', 'someNestedValue') res = js.run() with open(res.outputs.out_file, 'r') as f: data = json.load(f) yield assert_true, data == {"contrasts": {"alt": "someNestedValue"}, "foo": "var", "new_entry": "someValue"} js = nio.JSONFileSink(infields=['test'], in_dict={'foo': 'var'}) js.inputs.new_entry = 'someValue' js.inputs.test = 'testInfields' setattr(js.inputs, 'contrasts.alt', 'someNestedValue') res = js.run() with open(res.outputs.out_file, 'r') as f: data = json.load(f) yield assert_true, data == {"test": "testInfields", "contrasts": {"alt": "someNestedValue"}, "foo": "var", "new_entry": "someValue"} os.chdir(curdir) shutil.rmtree(outdir) nipype-0.11.0/nipype/interfaces/tests/test_matlab.py000066400000000000000000000060071257611314500225470ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkdtemp from shutil import rmtree from nipype.testing import (assert_equal, assert_true, assert_false, assert_raises, skipif) import nipype.interfaces.matlab as mlab matlab_cmd = mlab.get_matlab_command() no_matlab = matlab_cmd is None if not no_matlab: mlab.MatlabCommand.set_default_matlab_cmd(matlab_cmd) @skipif(no_matlab) def test_cmdline(): basedir = mkdtemp() mi = mlab.MatlabCommand(script='whos', script_file='testscript', mfile=False) yield assert_equal, mi.cmdline, \ matlab_cmd + (' -nodesktop -nosplash -singleCompThread -r "fprintf(1,' '\'Executing code at %s:\\n\',datestr(now));ver,try,' 'whos,catch ME,fprintf(2,\'MATLAB code threw an ' 'exception:\\n\');fprintf(2,\'%s\\n\',ME.message);if ' 'length(ME.stack) ~= 0, fprintf(2,\'File:%s\\nName:%s\\n' 'Line:%d\\n\',ME.stack.file,ME.stack.name,' 'ME.stack.line);, end;end;;exit"') yield assert_equal, mi.inputs.script, 'whos' yield assert_equal, mi.inputs.script_file, 'testscript' path_exists = os.path.exists(os.path.join(basedir, 'testscript.m')) yield assert_false, path_exists rmtree(basedir) @skipif(no_matlab) def test_mlab_inputspec(): spec = mlab.MatlabInputSpec() for k in ['paths', 'script', 'nosplash', 'mfile', 'logfile', 'script_file', 'nodesktop']: yield assert_true, k in spec.copyable_trait_names() yield assert_true, spec.nodesktop yield assert_true, spec.nosplash yield assert_true, spec.mfile yield assert_equal, spec.script_file, 'pyscript.m' @skipif(no_matlab) def test_mlab_init(): yield assert_equal, mlab.MatlabCommand._cmd, 'matlab' yield assert_equal, mlab.MatlabCommand.input_spec, mlab.MatlabInputSpec yield assert_equal, mlab.MatlabCommand().cmd, matlab_cmd mc = mlab.MatlabCommand(matlab_cmd='foo_m') yield assert_equal, mc.cmd, 'foo_m' @skipif(no_matlab) def test_run_interface(): mc = mlab.MatlabCommand(matlab_cmd='foo_m') yield assert_raises, ValueError, mc.run # script is mandatory mc.inputs.script = 'a=1;' yield assert_raises, IOError, mc.run # foo_m is not an executable cwd = os.getcwd() basedir = mkdtemp() os.chdir(basedir) # bypasses ubuntu dash issue mc = mlab.MatlabCommand(script='foo;', paths=[basedir], mfile=True) yield assert_raises, RuntimeError, mc.run # bypasses ubuntu dash issue res = mlab.MatlabCommand(script='a=1;', paths=[basedir], mfile=True).run() yield assert_equal, res.runtime.returncode, 0 os.chdir(cwd) rmtree(basedir) @skipif(no_matlab) def test_set_matlabcmd(): mi = mlab.MatlabCommand() mi.set_default_matlab_cmd('foo') yield assert_equal, mi._default_matlab_cmd, 'foo' mi.set_default_matlab_cmd(matlab_cmd) nipype-0.11.0/nipype/interfaces/tests/test_utility.py000066400000000000000000000122031257611314500230050ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import shutil from tempfile import mkdtemp, mkstemp import numpy as np from nipype.testing import assert_equal, assert_true, assert_raises from nipype.interfaces import utility import nipype.pipeline.engine as pe def test_rename(): tempdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(tempdir) # Test very simple rename _ = open("file.txt", "w").close() rn = utility.Rename(in_file="file.txt", format_string="test_file1.txt") res = rn.run() outfile = os.path.join(tempdir, "test_file1.txt") yield assert_equal, res.outputs.out_file, outfile yield assert_true, os.path.exists(outfile) # Now a string-formatting version rn = utility.Rename(in_file="file.txt", format_string="%(field1)s_file%(field2)d", keep_ext=True) # Test .input field creation yield assert_true, hasattr(rn.inputs, "field1") yield assert_true, hasattr(rn.inputs, "field2") # Set the inputs rn.inputs.field1 = "test" rn.inputs.field2 = 2 res = rn.run() outfile = os.path.join(tempdir, "test_file2.txt") yield assert_equal, res.outputs.out_file, outfile yield assert_true, os.path.exists(outfile) # Clean up os.chdir(origdir) shutil.rmtree(tempdir) def test_function(): tempdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(tempdir) def gen_random_array(size): import numpy as np return np.random.rand(size, size) f1 = pe.MapNode(utility.Function(input_names=['size'], output_names=['random_array'], function=gen_random_array), name='random_array', iterfield=['size']) f1.inputs.size = [2, 3, 5] wf = pe.Workflow(name="test_workflow") def increment_array(in_array): return in_array + 1 f2 = pe.MapNode(utility.Function(input_names=['in_array'], output_names=['out_array'], function=increment_array), name='increment_array', iterfield=['in_array']) wf.connect(f1, 'random_array', f2, 'in_array') wf.run() # Clean up os.chdir(origdir) shutil.rmtree(tempdir) def make_random_array(size): return np.random.randn(size, size) def should_fail(): tempdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(tempdir) node = pe.Node(utility.Function(input_names=["size"], output_names=["random_array"], function=make_random_array), name="should_fail") try: node.inputs.size = 10 node.run() finally: os.chdir(origdir) shutil.rmtree(tempdir) assert_raises(NameError, should_fail) def test_function_with_imports(): tempdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(tempdir) node = pe.Node(utility.Function(input_names=["size"], output_names=["random_array"], function=make_random_array, imports=["import numpy as np"]), name="should_not_fail") print node.inputs.function_str try: node.inputs.size = 10 node.run() finally: os.chdir(origdir) shutil.rmtree(tempdir) def test_split(): tempdir = os.path.realpath(mkdtemp()) origdir = os.getcwd() os.chdir(tempdir) try: node = pe.Node(utility.Split(inlist=range(4), splits=[1, 3]), name='split_squeeze') res = node.run() yield assert_equal, res.outputs.out1, [0] yield assert_equal, res.outputs.out2, [1, 2, 3] node = pe.Node(utility.Split(inlist=range(4), splits=[1, 3], squeeze=True), name='split_squeeze') res = node.run() yield assert_equal, res.outputs.out1, 0 yield assert_equal, res.outputs.out2, [1, 2, 3] finally: os.chdir(origdir) shutil.rmtree(tempdir) def test_csvReader(): header = "files,labels,erosion\n" lines = ["foo,hello,300.1\n", "bar,world,5\n", "baz,goodbye,0.3\n"] for x in range(2): fd, name = mkstemp(suffix=".csv") with open(name, 'w+b') as fid: reader = utility.CSVReader() if x % 2 == 0: fid.write(header) reader.inputs.header = True fid.writelines(lines) fid.flush() reader.inputs.in_file = name out = reader.run() if x % 2 == 0: yield assert_equal, out.outputs.files, ['foo', 'bar', 'baz'] yield assert_equal, out.outputs.labels, ['hello', 'world', 'goodbye'] yield assert_equal, out.outputs.erosion, ['300.1', '5', '0.3'] else: yield assert_equal, out.outputs.column_0, ['foo', 'bar', 'baz'] yield assert_equal, out.outputs.column_1, ['hello', 'world', 'goodbye'] yield assert_equal, out.outputs.column_2, ['300.1', '5', '0.3'] os.unlink(name) nipype-0.11.0/nipype/interfaces/traits_extension.py000066400000000000000000000206751257611314500225170ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """This module contains Trait classes that we've pulled from the traits source and fixed due to various bugs. File and Directory are redefined as the release version had dependencies on TraitsUI, which we do not want Nipype to depend on. At least not yet. Undefined class was missing the __len__ operator, causing edit_traits and configure_traits to fail on List objects. Even though we don't require TraitsUI, this bug was the only thing preventing us from popping up GUIs which users like. These bugs have been in Traits v3.3.0 and v3.2.1. We have reported all of these bugs and they've been fixed in enthought svn repository (usually by Robert Kern). """ import os # perform all external trait imports here import traits if traits.__version__ < '3.7.0': raise ImportError('Traits version 3.7.0 or higher must be installed') import traits.api as traits from traits.trait_handlers import TraitDictObject, TraitListObject from traits.trait_errors import TraitError from traits.trait_base import _Undefined class BaseFile ( traits.BaseStr ): """ Defines a trait whose value must be the name of a file. """ # A description of the type of value this trait accepts: info_text = 'a file name' def __init__ ( self, value = '', filter = None, auto_set = False, entries = 0, exists = False, **metadata ): """ Creates a File trait. Parameters ---------- value : string The default value for the trait filter : string A wildcard string to filter filenames in the file dialog box used by the attribute trait editor. auto_set : boolean Indicates whether the file editor updates the trait value after every key stroke. exists : boolean Indicates whether the trait value must be an existing file or not. Default Value ------------- *value* or '' """ self.filter = filter self.auto_set = auto_set self.entries = entries self.exists = exists if exists: self.info_text = 'an existing file name' super( BaseFile, self ).__init__( value, **metadata ) def validate ( self, object, name, value ): """ Validates that a specified value is valid for this trait. Note: The 'fast validator' version performs this check in C. """ validated_value = super( BaseFile, self ).validate( object, name, value ) if not self.exists: return validated_value elif os.path.isfile( value ): return validated_value self.error( object, name, value ) class File ( BaseFile ): """ Defines a trait whose value must be the name of a file using a C-level fast validator. """ def __init__ ( self, value = '', filter = None, auto_set = False, entries = 0, exists = False, **metadata ): """ Creates a File trait. Parameters ---------- value : string The default value for the trait filter : string A wildcard string to filter filenames in the file dialog box used by the attribute trait editor. auto_set : boolean Indicates whether the file editor updates the trait value after every key stroke. exists : boolean Indicates whether the trait value must be an existing file or not. Default Value ------------- *value* or '' """ if not exists: # Define the C-level fast validator to use: fast_validate = ( 11, basestring ) super( File, self ).__init__( value, filter, auto_set, entries, exists, **metadata ) #------------------------------------------------------------------------------- # 'BaseDirectory' and 'Directory' traits: #------------------------------------------------------------------------------- class BaseDirectory ( traits.BaseStr ): """ Defines a trait whose value must be the name of a directory. """ # A description of the type of value this trait accepts: info_text = 'a directory name' def __init__ ( self, value = '', auto_set = False, entries = 0, exists = False, **metadata ): """ Creates a BaseDirectory trait. Parameters ---------- value : string The default value for the trait auto_set : boolean Indicates whether the directory editor updates the trait value after every key stroke. exists : boolean Indicates whether the trait value must be an existing directory or not. Default Value ------------- *value* or '' """ self.entries = entries self.auto_set = auto_set self.exists = exists if exists: self.info_text = 'an existing directory name' super( BaseDirectory, self ).__init__( value, **metadata ) def validate ( self, object, name, value ): """ Validates that a specified value is valid for this trait. Note: The 'fast validator' version performs this check in C. """ validated_value = super( BaseDirectory, self ).validate( object, name, value ) if not self.exists: return validated_value if os.path.isdir( value ): return validated_value self.error( object, name, value ) class Directory ( BaseDirectory ): """ Defines a trait whose value must be the name of a directory using a C-level fast validator. """ def __init__ ( self, value = '', auto_set = False, entries = 0, exists = False, **metadata ): """ Creates a Directory trait. Parameters ---------- value : string The default value for the trait auto_set : boolean Indicates whether the directory editor updates the trait value after every key stroke. exists : boolean Indicates whether the trait value must be an existing directory or not. Default Value ------------- *value* or '' """ # Define the C-level fast validator to use if the directory existence # test is not required: if not exists: self.fast_validate = ( 11, basestring ) super( Directory, self ).__init__( value, auto_set, entries, exists, **metadata ) """ The functions that pop-up the Traits GUIs, edit_traits and configure_traits, were failing because all of our inputs default to Undefined deep and down in traits/ui/wx/list_editor.py it checks for the len() of the elements of the list. The _Undefined class in traits does not define the __len__ method and would error. I tried defining our own Undefined and even sublassing Undefined, but both of those failed with a TraitError in our initializer when we assign the Undefined to the inputs because of an incompatible type: TraitError: The 'vertical_gradient' trait of a BetInputSpec instance must be a float, but a value of was specified. So... in order to keep the same type but add the missing method, I monkey patched. """ def length(self): return 0 ########################################################################## # Apply monkeypatch here _Undefined.__len__ = length ########################################################################## Undefined = _Undefined() def isdefined(object): return not isinstance(object, _Undefined) def has_metadata(trait, metadata, value=None, recursive=True): ''' Checks if a given trait has a metadata (and optionally if it is set to particular value) ''' count = 0 if hasattr(trait, "_metadata") and metadata in trait._metadata.keys() and (trait._metadata[metadata] == value or value==None): count += 1 if recursive: if hasattr(trait, 'inner_traits'): for inner_trait in trait.inner_traits(): count += has_metadata(inner_trait.trait_type, metadata, recursive) if hasattr(trait, 'handlers') and trait.handlers != None: for handler in trait.handlers: count += has_metadata(handler, metadata, recursive) return count > 0 nipype-0.11.0/nipype/interfaces/utility.py000066400000000000000000000472661257611314500206250ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Various utilities Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ import os import re from cPickle import dumps, loads import numpy as np import nibabel as nb from nipype.external import six from nipype.utils.filemanip import (filename_to_list, copyfile, split_filename) from nipype.interfaces.base import (traits, TraitedSpec, DynamicTraitedSpec, File, Undefined, isdefined, OutputMultiPath, InputMultiPath, BaseInterface, BaseInterfaceInputSpec) from nipype.interfaces.io import IOBase, add_traits from nipype.testing import assert_equal from nipype.utils.misc import getsource, create_function_from_source class IdentityInterface(IOBase): """Basic interface class generates identity mappings Examples -------- >>> from nipype.interfaces.utility import IdentityInterface >>> ii = IdentityInterface(fields=['a', 'b'], mandatory_inputs=False) >>> ii.inputs.a >>> ii.inputs.a = 'foo' >>> out = ii._outputs() >>> out.a >>> out = ii.run() >>> out.outputs.a 'foo' >>> ii2 = IdentityInterface(fields=['a', 'b'], mandatory_inputs=True) >>> ii2.inputs.a = 'foo' >>> out = ii2.run() # doctest: +SKIP ValueError: IdentityInterface requires a value for input 'b' because it was listed in 'fields' Interface IdentityInterface failed to run. """ input_spec = DynamicTraitedSpec output_spec = DynamicTraitedSpec def __init__(self, fields=None, mandatory_inputs=True, **inputs): super(IdentityInterface, self).__init__(**inputs) if fields is None or not fields: raise ValueError('Identity Interface fields must be a non-empty list') # Each input must be in the fields. for in_field in inputs: if in_field not in fields: raise ValueError('Identity Interface input is not in the fields: %s' % in_field) self._fields = fields self._mandatory_inputs = mandatory_inputs add_traits(self.inputs, fields) # Adding any traits wipes out all input values set in superclass initialization, # even it the trait is not in the add_traits argument. The work-around is to reset # the values after adding the traits. self.inputs.set(**inputs) def _add_output_traits(self, base): undefined_traits = {} for key in self._fields: base.add_trait(key, traits.Any) undefined_traits[key] = Undefined base.trait_set(trait_change_notify=False, **undefined_traits) return base def _list_outputs(self): #manual mandatory inputs check if self._fields and self._mandatory_inputs: for key in self._fields: value = getattr(self.inputs, key) if not isdefined(value): msg = "%s requires a value for input '%s' because it was listed in 'fields'. \ You can turn off mandatory inputs checking by passing mandatory_inputs = False to the constructor." % \ (self.__class__.__name__, key) raise ValueError(msg) outputs = self._outputs().get() for key in self._fields: val = getattr(self.inputs, key) if isdefined(val): outputs[key] = val return outputs class MergeInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): axis = traits.Enum('vstack', 'hstack', usedefault=True, desc='direction in which to merge, hstack requires same number of elements in each input') no_flatten = traits.Bool(False, usedefault=True, desc='append to outlist instead of extending in vstack mode') class MergeOutputSpec(TraitedSpec): out = traits.List(desc='Merged output') class Merge(IOBase): """Basic interface class to merge inputs into a single list Examples -------- >>> from nipype.interfaces.utility import Merge >>> mi = Merge(3) >>> mi.inputs.in1 = 1 >>> mi.inputs.in2 = [2, 5] >>> mi.inputs.in3 = 3 >>> out = mi.run() >>> out.outputs.out [1, 2, 5, 3] """ input_spec = MergeInputSpec output_spec = MergeOutputSpec def __init__(self, numinputs=0, **inputs): super(Merge, self).__init__(**inputs) self._numinputs = numinputs add_traits(self.inputs, ['in%d' % (i + 1) for i in range(numinputs)]) def _list_outputs(self): outputs = self._outputs().get() out = [] if self.inputs.axis == 'vstack': for idx in range(self._numinputs): value = getattr(self.inputs, 'in%d' % (idx + 1)) if isdefined(value): if isinstance(value, list) and not self.inputs.no_flatten: out.extend(value) else: out.append(value) else: for i in range(len(filename_to_list(self.inputs.in1))): out.insert(i, []) for j in range(self._numinputs): out[i].append(filename_to_list(getattr(self.inputs, 'in%d' % (j + 1)))[i]) if out: outputs['out'] = out return outputs class RenameInputSpec(DynamicTraitedSpec): in_file = File(exists=True, mandatory=True, desc="file to rename") keep_ext = traits.Bool(desc=("Keep in_file extension, replace " "non-extension component of name")) format_string = traits.String(mandatory=True, desc=("Python formatting string for output " "template")) parse_string = traits.String(desc=("Python regexp parse string to define " "replacement inputs")) use_fullpath = traits.Bool(False, usedefault=True, desc="Use full path as input to regex parser") class RenameOutputSpec(TraitedSpec): out_file = traits.File(exists=True, desc="softlink to original file with new name") class Rename(IOBase): """Change the name of a file based on a mapped format string. To use additional inputs that will be defined at run-time, the class constructor must be called with the format template, and the fields identified will become inputs to the interface. Additionally, you may set the parse_string input, which will be run over the input filename with a regular expressions search, and will fill in additional input fields from matched groups. Fields set with inputs have precedence over fields filled in with the regexp match. Examples -------- >>> from nipype.interfaces.utility import Rename >>> rename1 = Rename() >>> rename1.inputs.in_file = "zstat1.nii.gz" >>> rename1.inputs.format_string = "Faces-Scenes.nii.gz" >>> res = rename1.run() # doctest: +SKIP >>> print res.outputs.out_file # doctest: +SKIP 'Faces-Scenes.nii.gz" # doctest: +SKIP >>> rename2 = Rename(format_string="%(subject_id)s_func_run%(run)02d") >>> rename2.inputs.in_file = "functional.nii" >>> rename2.inputs.keep_ext = True >>> rename2.inputs.subject_id = "subj_201" >>> rename2.inputs.run = 2 >>> res = rename2.run() # doctest: +SKIP >>> print res.outputs.out_file # doctest: +SKIP 'subj_201_func_run02.nii' # doctest: +SKIP >>> rename3 = Rename(format_string="%(subject_id)s_%(seq)s_run%(run)02d.nii") >>> rename3.inputs.in_file = "func_epi_1_1.nii" >>> rename3.inputs.parse_string = "func_(?P\w*)_.*" >>> rename3.inputs.subject_id = "subj_201" >>> rename3.inputs.run = 2 >>> res = rename3.run() # doctest: +SKIP >>> print res.outputs.out_file # doctest: +SKIP 'subj_201_epi_run02.nii' # doctest: +SKIP """ input_spec = RenameInputSpec output_spec = RenameOutputSpec def __init__(self, format_string=None, **inputs): super(Rename, self).__init__(**inputs) if format_string is not None: self.inputs.format_string = format_string self.fmt_fields = re.findall(r"%\((.+?)\)", format_string) add_traits(self.inputs, self.fmt_fields) else: self.fmt_fields = [] def _rename(self): fmt_dict = dict() if isdefined(self.inputs.parse_string): if isdefined(self.inputs.use_fullpath) and self.inputs.use_fullpath: m = re.search(self.inputs.parse_string, self.inputs.in_file) else: m = re.search(self.inputs.parse_string, os.path.split(self.inputs.in_file)[1]) if m: fmt_dict.update(m.groupdict()) for field in self.fmt_fields: val = getattr(self.inputs, field) if isdefined(val): fmt_dict[field] = getattr(self.inputs, field) if self.inputs.keep_ext: fmt_string = "".join([self.inputs.format_string, split_filename(self.inputs.in_file)[2]]) else: fmt_string = self.inputs.format_string return fmt_string % fmt_dict def _run_interface(self, runtime): runtime.returncode = 0 _ = copyfile(self.inputs.in_file, os.path.join(os.getcwd(), self._rename())) return runtime def _list_outputs(self): outputs = self._outputs().get() outputs["out_file"] = os.path.join(os.getcwd(), self._rename()) return outputs class SplitInputSpec(BaseInterfaceInputSpec): inlist = traits.List(traits.Any, mandatory=True, desc='list of values to split') splits = traits.List(traits.Int, mandatory=True, desc='Number of outputs in each split - should add to number of inputs') squeeze = traits.Bool(False, usedefault=True, desc='unfold one-element splits removing the list') class Split(IOBase): """Basic interface class to split lists into multiple outputs Examples -------- >>> from nipype.interfaces.utility import Split >>> sp = Split() >>> _ = sp.inputs.set(inlist=[1, 2, 3], splits=[2, 1]) >>> out = sp.run() >>> out.outputs.out1 [1, 2] """ input_spec = SplitInputSpec output_spec = DynamicTraitedSpec def _add_output_traits(self, base): undefined_traits = {} for i in range(len(self.inputs.splits)): key = 'out%d' % (i + 1) base.add_trait(key, traits.Any) undefined_traits[key] = Undefined base.trait_set(trait_change_notify=False, **undefined_traits) return base def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.splits): if sum(self.inputs.splits) != len(self.inputs.inlist): raise RuntimeError('sum of splits != num of list elements') splits = [0] splits.extend(self.inputs.splits) splits = np.cumsum(splits) for i in range(len(splits) - 1): val = np.array(self.inputs.inlist)[splits[i]:splits[i + 1]].tolist() if self.inputs.squeeze and len(val) == 1: val = val[0] outputs['out%d' % (i + 1)] = val return outputs class SelectInputSpec(BaseInterfaceInputSpec): inlist = InputMultiPath(traits.Any, mandatory=True, desc='list of values to choose from') index = InputMultiPath(traits.Int, mandatory=True, desc='0-based indices of values to choose') class SelectOutputSpec(TraitedSpec): out = OutputMultiPath(traits.Any, desc='list of selected values') class Select(IOBase): """Basic interface class to select specific elements from a list Examples -------- >>> from nipype.interfaces.utility import Select >>> sl = Select() >>> _ = sl.inputs.set(inlist=[1, 2, 3, 4, 5], index=[3]) >>> out = sl.run() >>> out.outputs.out 4 >>> _ = sl.inputs.set(inlist=[1, 2, 3, 4, 5], index=[3, 4]) >>> out = sl.run() >>> out.outputs.out [4, 5] """ input_spec = SelectInputSpec output_spec = SelectOutputSpec def _list_outputs(self): outputs = self._outputs().get() out = np.array(self.inputs.inlist)[np.array(self.inputs.index)].tolist() outputs['out'] = out return outputs class FunctionInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec): function_str = traits.Str(mandatory=True, desc='code for function') class Function(IOBase): """Runs arbitrary function as an interface Examples -------- >>> func = 'def func(arg1, arg2=5): return arg1 + arg2' >>> fi = Function(input_names=['arg1', 'arg2'], output_names=['out']) >>> fi.inputs.function_str = func >>> res = fi.run(arg1=1) >>> res.outputs.out 6 """ input_spec = FunctionInputSpec output_spec = DynamicTraitedSpec def __init__(self, input_names, output_names, function=None, imports=None, **inputs): """ Parameters ---------- input_names: single str or list names corresponding to function inputs output_names: single str or list names corresponding to function outputs. has to match the number of outputs function : callable callable python object. must be able to execute in an isolated namespace (possibly in concert with the ``imports`` parameter) imports : list of strings list of import statements that allow the function to execute in an otherwise empty namespace """ super(Function, self).__init__(**inputs) if function: if hasattr(function, '__call__'): try: self.inputs.function_str = getsource(function) except IOError: raise Exception('Interface Function does not accept ' \ 'function objects defined interactively ' \ 'in a python session') elif isinstance(function, six.string_types): self.inputs.function_str = dumps(function) else: raise Exception('Unknown type of function') self.inputs.on_trait_change(self._set_function_string, 'function_str') self._input_names = filename_to_list(input_names) self._output_names = filename_to_list(output_names) add_traits(self.inputs, [name for name in self._input_names]) self.imports = imports self._out = {} for name in self._output_names: self._out[name] = None def _set_function_string(self, obj, name, old, new): if name == 'function_str': if hasattr(new, '__call__'): function_source = getsource(new) elif isinstance(new, six.string_types): function_source = dumps(new) self.inputs.trait_set(trait_change_notify=False, **{'%s' % name: function_source}) def _add_output_traits(self, base): undefined_traits = {} for key in self._output_names: base.add_trait(key, traits.Any) undefined_traits[key] = Undefined base.trait_set(trait_change_notify=False, **undefined_traits) return base def _run_interface(self, runtime): function_handle = create_function_from_source(self.inputs.function_str, self.imports) args = {} for name in self._input_names: value = getattr(self.inputs, name) if isdefined(value): args[name] = value out = function_handle(**args) if len(self._output_names) == 1: self._out[self._output_names[0]] = out else: if isinstance(out, tuple) and (len(out) != len(self._output_names)): raise RuntimeError('Mismatch in number of expected outputs') else: for idx, name in enumerate(self._output_names): self._out[name] = out[idx] return runtime def _list_outputs(self): outputs = self._outputs().get() for key in self._output_names: outputs[key] = self._out[key] return outputs class AssertEqualInputSpec(BaseInterfaceInputSpec): volume1 = File(exists=True, mandatory=True) volume2 = File(exists=True, mandatory=True) class AssertEqual(BaseInterface): input_spec = AssertEqualInputSpec def _run_interface(self, runtime): data1 = nb.load(self.inputs.volume1).get_data() data2 = nb.load(self.inputs.volume2).get_data() assert_equal(data1, data2) return runtime class CSVReaderInputSpec(DynamicTraitedSpec, TraitedSpec): in_file = File(exists=True, mandatory=True, desc='Input comma-seperated value (CSV) file') header = traits.Bool(False, usedefault=True, desc='True if the first line is a column header') class CSVReader(BaseInterface): """ Examples -------- >>> reader = CSVReader() # doctest: +SKIP >>> reader.inputs.in_file = 'noHeader.csv' # doctest: +SKIP >>> out = reader.run() # doctest: +SKIP >>> out.outputs.column_0 == ['foo', 'bar', 'baz'] # doctest: +SKIP True >>> out.outputs.column_1 == ['hello', 'world', 'goodbye'] # doctest: +SKIP True >>> out.outputs.column_2 == ['300.1', '5', '0.3'] # doctest: +SKIP True >>> reader = CSVReader() # doctest: +SKIP >>> reader.inputs.in_file = 'header.csv' # doctest: +SKIP >>> reader.inputs.header = True # doctest: +SKIP >>> out = reader.run() # doctest: +SKIP >>> out.outputs.files == ['foo', 'bar', 'baz'] # doctest: +SKIP True >>> out.outputs.labels == ['hello', 'world', 'goodbye'] # doctest: +SKIP True >>> out.outputs.erosion == ['300.1', '5', '0.3'] # doctest: +SKIP True """ input_spec = CSVReaderInputSpec output_spec = DynamicTraitedSpec _always_run = True def _append_entry(self, outputs, entry): for key, value in zip(self._outfields, entry): outputs[key].append(value) return outputs def _parse_line(self, line): line = line.replace('\n', '') entry = [x.strip() for x in line.split(',')] return entry def _get_outfields(self): with open(self.inputs.in_file, 'r') as fid: entry = self._parse_line(fid.readline()) if self.inputs.header: self._outfields = tuple(entry) else: self._outfields = tuple(['column_' + str(x) for x in range(len(entry))]) return self._outfields def _run_interface(self, runtime): self._get_outfields() return runtime def _outputs(self): return self._add_output_traits(super(CSVReader, self)._outputs()) def _add_output_traits(self, base): return add_traits(base, self._get_outfields()) def _list_outputs(self): outputs = self.output_spec().get() isHeader = True for key in self._outfields: outputs[key] = [] # initialize outfields with open(self.inputs.in_file, 'r') as fid: for line in fid.readlines(): if self.inputs.header and isHeader: # skip header line isHeader = False continue entry = self._parse_line(line) outputs = self._append_entry(outputs, entry) return outputs nipype-0.11.0/nipype/interfaces/vista/000077500000000000000000000000001257611314500176575ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/vista/__init__.py000066400000000000000000000002331257611314500217660ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from .vista import (Vnifti2Image, VtoMat)nipype-0.11.0/nipype/interfaces/vista/tests/000077500000000000000000000000001257611314500210215ustar00rootroot00000000000000nipype-0.11.0/nipype/interfaces/vista/tests/test_auto_Vnifti2Image.py000066400000000000000000000022771257611314500257560ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.vista.vista import Vnifti2Image def test_Vnifti2Image_inputs(): input_map = dict(args=dict(argstr='%s', ), attributes=dict(argstr='-attr %s', position=2, ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-in %s', mandatory=True, position=1, ), out_file=dict(argstr='-out %s', hash_files=False, keep_extension=False, name_source=['in_file'], name_template='%s.v', position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = Vnifti2Image.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_Vnifti2Image_outputs(): output_map = dict(out_file=dict(), ) outputs = Vnifti2Image.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/vista/tests/test_auto_VtoMat.py000066400000000000000000000021451257611314500246760ustar00rootroot00000000000000# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT from nipype.testing import assert_equal from nipype.interfaces.vista.vista import VtoMat def test_VtoMat_inputs(): input_map = dict(args=dict(argstr='%s', ), environ=dict(nohash=True, usedefault=True, ), ignore_exception=dict(nohash=True, usedefault=True, ), in_file=dict(argstr='-in %s', mandatory=True, position=1, ), out_file=dict(argstr='-out %s', hash_files=False, keep_extension=False, name_source=['in_file'], name_template='%s.mat', position=-1, ), terminal_output=dict(nohash=True, ), ) inputs = VtoMat.input_spec() for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value def test_VtoMat_outputs(): output_map = dict(out_file=dict(), ) outputs = VtoMat.output_spec() for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value nipype-0.11.0/nipype/interfaces/vista/vista.py000066400000000000000000000045341257611314500213650ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data')) >>> os.chdir(datadir) """ from nipype.interfaces.base import CommandLineInputSpec, CommandLine, traits, TraitedSpec, File from nipype.utils.filemanip import split_filename import os, os.path as op from nipype.interfaces.traits_extension import isdefined class Vnifti2ImageInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-in %s', mandatory=True, position=1, desc='in file') attributes = File(exists=True, argstr='-attr %s', position=2, desc='attribute file') out_file = File(name_template="%s.v", keep_extension=False, argstr='-out %s', hash_files=False, position= -1, desc='output data file', name_source=["in_file"]) class Vnifti2ImageOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Output vista file') class Vnifti2Image(CommandLine): """ Convert a nifti file into a vista file. Example ------- >>> vimage = Vnifti2Image() >>> vimage.inputs.in_file = 'image.nii' >>> vimage.cmdline 'vnifti2image -in image.nii -out image.v' >>> vimage.run() # doctest: +SKIP """ _cmd = 'vnifti2image' input_spec=Vnifti2ImageInputSpec output_spec=Vnifti2ImageOutputSpec class VtoMatInputSpec(CommandLineInputSpec): in_file = File(exists=True, argstr='-in %s', mandatory=True, position=1, desc='in file') out_file = File(name_template="%s.mat", keep_extension=False, argstr='-out %s', hash_files=False, position= -1, desc='output mat file', name_source=["in_file"]) class VtoMatOutputSpec(TraitedSpec): out_file = File(exists=True, desc='Output mat file') class VtoMat(CommandLine): """ Convert a nifti file into a vista file. Example ------- >>> vimage = VtoMat() >>> vimage.inputs.in_file = 'image.v' >>> vimage.cmdline 'vtomat -in image.v -out image.mat' >>> vimage.run() # doctest: +SKIP """ _cmd = 'vtomat' input_spec=VtoMatInputSpec output_spec=VtoMatOutputSpec nipype-0.11.0/nipype/pipeline/000077500000000000000000000000001257611314500162135ustar00rootroot00000000000000nipype-0.11.0/nipype/pipeline/__init__.py000066400000000000000000000004261257611314500203260ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Package contains modules for generating pipelines using interfaces """ __docformat__ = 'restructuredtext' from engine import Node, MapNode, JoinNode, Workflow nipype-0.11.0/nipype/pipeline/engine.py000066400000000000000000003054041257611314500200400ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Defines functionality for pipelined execution of interfaces The `Workflow` class provides core functionality for batch processing. Change directory to provide relative paths for doctests >>> import os >>> filepath = os.path.dirname( os.path.realpath( __file__ ) ) >>> datadir = os.path.realpath(os.path.join(filepath, '../testing/data')) >>> os.chdir(datadir) """ from datetime import datetime from nipype.utils.misc import flatten, unflatten from nipype.interfaces.traits_extension import File try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict from copy import deepcopy import cPickle from glob import glob import gzip import inspect import os import os.path as op import re import shutil import errno from shutil import rmtree from socket import gethostname from string import Template import sys from tempfile import mkdtemp from warnings import warn from hashlib import sha1 from nipype.external import six import numpy as np from ..utils.misc import package_check, str2bool package_check('networkx', '1.3') import networkx as nx from .. import config, logging logger = logging.getLogger('workflow') from ..interfaces.base import (traits, InputMultiPath, CommandLine, Undefined, TraitedSpec, DynamicTraitedSpec, Bunch, InterfaceResult, md5, Interface, TraitDictObject, TraitListObject, isdefined) from ..utils.misc import getsource, create_function_from_source from ..utils.filemanip import (save_json, FileNotFoundError, filename_to_list, list_to_filename, copyfiles, fnames_presuffix, loadpkl, split_filename, load_json, savepkl, write_rst_header, write_rst_dict, write_rst_list) from .utils import (generate_expanded_graph, modify_paths, export_graph, make_output_dir, write_workflow_prov, clean_working_directory, format_dot, topological_sort, get_print_name, merge_dict, evaluate_connect_function) def _write_inputs(node): lines = [] nodename = node.fullname.replace('.', '_') for key, _ in node.inputs.items(): val = getattr(node.inputs, key) if isdefined(val): if type(val) == str: try: func = create_function_from_source(val) except RuntimeError, e: lines.append("%s.inputs.%s = '%s'" % (nodename, key, val)) else: funcname = [name for name in func.func_globals if name != '__builtins__'][0] lines.append(cPickle.loads(val)) if funcname == nodename: lines[-1] = lines[-1].replace(' %s(' % funcname, ' %s_1(' % funcname) funcname = '%s_1' % funcname lines.append('from nipype.utils.misc import getsource') lines.append("%s.inputs.%s = getsource(%s)" % (nodename, key, funcname)) else: lines.append('%s.inputs.%s = %s' % (nodename, key, val)) return lines def format_node(node, format='python', include_config=False): """Format a node in a given output syntax.""" lines = [] name = node.fullname.replace('.', '_') if format == 'python': klass = node._interface importline = 'from %s import %s' % (klass.__module__, klass.__class__.__name__) comment = '# Node: %s' % node.fullname spec = inspect.getargspec(node._interface.__init__) args = spec.args[1:] if args: filled_args = [] for arg in args: if hasattr(node._interface, '_%s' % arg): filled_args.append('%s=%s' % (arg, getattr(node._interface, '_%s' % arg))) args = ', '.join(filled_args) else: args = '' klass_name = klass.__class__.__name__ if isinstance(node, MapNode): nodedef = '%s = MapNode(%s(%s), iterfield=%s, name="%s")' \ % (name, klass_name, args, node.iterfield, name) else: nodedef = '%s = Node(%s(%s), name="%s")' \ % (name, klass_name, args, name) lines = [importline, comment, nodedef] if include_config: lines = [importline, "from collections import OrderedDict", comment, nodedef] lines.append('%s.config = %s' % (name, node.config)) if node.iterables is not None: lines.append('%s.iterables = %s' % (name, node.iterables)) lines.extend(_write_inputs(node)) return lines class WorkflowBase(object): """Defines common attributes and functions for workflows and nodes.""" def __init__(self, name=None, base_dir=None): """ Initialize base parameters of a workflow or node Parameters ---------- name : string (mandatory) Name of this node. Name must be alphanumeric and not contain any special characters (e.g., '.', '@'). base_dir : string base output directory (will be hashed before creations) default=None, which results in the use of mkdtemp """ self.base_dir = base_dir self.config = None self._verify_name(name) self.name = name # for compatibility with node expansion using iterables self._id = self.name self._hierarchy = None @property def inputs(self): raise NotImplementedError @property def outputs(self): raise NotImplementedError @property def fullname(self): fullname = self.name if self._hierarchy: fullname = self._hierarchy + '.' + self.name return fullname def clone(self, name): """Clone a workflowbase object Parameters ---------- name : string (mandatory) A clone of node or workflow must have a new name """ if (name is None) or (name == self.name): raise Exception('Cloning requires a new name') self._verify_name(name) clone = deepcopy(self) clone.name = name clone._id = name clone._hierarchy = None return clone def _check_outputs(self, parameter): return hasattr(self.outputs, parameter) def _check_inputs(self, parameter): if isinstance(self.inputs, DynamicTraitedSpec): return True return hasattr(self.inputs, parameter) def _verify_name(self, name): valid_name = bool(re.match('^[\w-]+$', name)) if not valid_name: raise Exception('the name must not contain any special characters') def __repr__(self): if self._hierarchy: return '.'.join((self._hierarchy, self._id)) else: return self._id def save(self, filename=None): if filename is None: filename = 'temp.pklz' savepkl(filename, self) def load(self, filename): if '.npz' in filename: DeprecationWarning(('npz files will be deprecated in the next ' 'release. you can use numpy to open them.')) return np.load(filename) return loadpkl(filename) class Workflow(WorkflowBase): """Controls the setup and execution of a pipeline of processes.""" def __init__(self, name, base_dir=None): """Create a workflow object. Parameters ---------- name : alphanumeric string unique identifier for the workflow base_dir : string, optional path to workflow storage """ super(Workflow, self).__init__(name, base_dir) self._graph = nx.DiGraph() self.config = deepcopy(config._sections) # PUBLIC API def clone(self, name): """Clone a workflow .. note:: Will reset attributes used for executing workflow. See _init_runtime_fields. Parameters ---------- name: alphanumeric name unique name for the workflow """ clone = super(Workflow, self).clone(name) clone._reset_hierarchy() return clone # Graph creation functions def connect(self, *args, **kwargs): """Connect nodes in the pipeline. This routine also checks if inputs and outputs are actually provided by the nodes that are being connected. Creates edges in the directed graph using the nodes and edges specified in the `connection_list`. Uses the NetworkX method DiGraph.add_edges_from. Parameters ---------- args : list or a set of four positional arguments Four positional arguments of the form:: connect(source, sourceoutput, dest, destinput) source : nodewrapper node sourceoutput : string (must be in source.outputs) dest : nodewrapper node destinput : string (must be in dest.inputs) A list of 3-tuples of the following form:: [(source, target, [('sourceoutput/attribute', 'targetinput'), ...]), ...] Or:: [(source, target, [(('sourceoutput1', func, arg2, ...), 'targetinput'), ...]), ...] sourceoutput1 will always be the first argument to func and func will be evaluated and the results sent ot targetinput currently func needs to define all its needed imports within the function as we use the inspect module to get at the source code and execute it remotely """ if len(args) == 1: connection_list = args[0] elif len(args) == 4: connection_list = [(args[0], args[2], [(args[1], args[3])])] else: raise Exception('unknown set of parameters to connect function') if not kwargs: disconnect = False else: disconnect = kwargs['disconnect'] newnodes = [] for srcnode, destnode, _ in connection_list: if self in [srcnode, destnode]: msg = ('Workflow connect cannot contain itself as node:' ' src[%s] dest[%s] workflow[%s]') % (srcnode, destnode, self.name) raise IOError(msg) if (srcnode not in newnodes) and not self._has_node(srcnode): newnodes.append(srcnode) if (destnode not in newnodes) and not self._has_node(destnode): newnodes.append(destnode) if newnodes: self._check_nodes(newnodes) for node in newnodes: if node._hierarchy is None: node._hierarchy = self.name not_found = [] connected_ports = {} for srcnode, destnode, connects in connection_list: if destnode not in connected_ports: connected_ports[destnode] = [] # check to see which ports of destnode are already # connected. if not disconnect and (destnode in self._graph.nodes()): for edge in self._graph.in_edges_iter(destnode): data = self._graph.get_edge_data(*edge) for sourceinfo, destname in data['connect']: if destname not in connected_ports[destnode]: connected_ports[destnode] += [destname] for source, dest in connects: # Currently datasource/sink/grabber.io modules # determine their inputs/outputs depending on # connection settings. Skip these modules in the check if dest in connected_ports[destnode]: raise Exception(""" Trying to connect %s:%s to %s:%s but input '%s' of node '%s' is already connected. """ % (srcnode, source, destnode, dest, dest, destnode)) if not (hasattr(destnode, '_interface') and '.io' in str(destnode._interface.__class__)): if not destnode._check_inputs(dest): not_found.append(['in', destnode.name, dest]) if not (hasattr(srcnode, '_interface') and '.io' in str(srcnode._interface.__class__)): if isinstance(source, tuple): # handles the case that source is specified # with a function sourcename = source[0] elif isinstance(source, six.string_types): sourcename = source else: raise Exception(('Unknown source specification in ' 'connection from output of %s') % srcnode.name) if sourcename and not srcnode._check_outputs(sourcename): not_found.append(['out', srcnode.name, sourcename]) connected_ports[destnode] += [dest] infostr = [] for info in not_found: infostr += ["Module %s has no %sput called %s\n" % (info[1], info[0], info[2])] if not_found: raise Exception('\n'.join(['Some connections were not found'] + infostr)) # turn functions into strings for srcnode, destnode, connects in connection_list: for idx, (src, dest) in enumerate(connects): if isinstance(src, tuple) and not isinstance(src[1], six.string_types): function_source = getsource(src[1]) connects[idx] = ((src[0], function_source, src[2:]), dest) # add connections for srcnode, destnode, connects in connection_list: edge_data = self._graph.get_edge_data(srcnode, destnode, None) if edge_data: logger.debug('(%s, %s): Edge data exists: %s' % (srcnode, destnode, str(edge_data))) for data in connects: if data not in edge_data['connect']: edge_data['connect'].append(data) if disconnect: logger.debug('Removing connection: %s' % str(data)) edge_data['connect'].remove(data) if edge_data['connect']: self._graph.add_edges_from([(srcnode, destnode, edge_data)]) else: #pass logger.debug('Removing connection: %s->%s' % (srcnode, destnode)) self._graph.remove_edges_from([(srcnode, destnode)]) elif not disconnect: logger.debug('(%s, %s): No edge data' % (srcnode, destnode)) self._graph.add_edges_from([(srcnode, destnode, {'connect': connects})]) edge_data = self._graph.get_edge_data(srcnode, destnode) logger.debug('(%s, %s): new edge data: %s' % (srcnode, destnode, str(edge_data))) def disconnect(self, *args): """Disconnect two nodes See the docstring for connect for format. """ # yoh: explicit **dict was introduced for compatibility with Python 2.5 return self.connect(*args, **dict(disconnect=True)) def add_nodes(self, nodes): """ Add nodes to a workflow Parameters ---------- nodes : list A list of WorkflowBase-based objects """ newnodes = [] all_nodes = self._get_all_nodes() for node in nodes: if self._has_node(node): raise IOError('Node %s already exists in the workflow' % node) if isinstance(node, Workflow): for subnode in node._get_all_nodes(): if subnode in all_nodes: raise IOError(('Subnode %s of node %s already exists ' 'in the workflow') % (subnode, node)) newnodes.append(node) if not newnodes: logger.debug('no new nodes to add') return for node in newnodes: if not issubclass(node.__class__, WorkflowBase): raise Exception('Node %s must be a subclass of WorkflowBase' % str(node)) self._check_nodes(newnodes) for node in newnodes: if node._hierarchy is None: node._hierarchy = self.name self._graph.add_nodes_from(newnodes) def remove_nodes(self, nodes): """ Remove nodes from a workflow Parameters ---------- nodes : list A list of WorkflowBase-based objects """ self._graph.remove_nodes_from(nodes) # Input-Output access @property def inputs(self): return self._get_inputs() @property def outputs(self): return self._get_outputs() def get_node(self, name): """Return an internal node by name """ nodenames = name.split('.') nodename = nodenames[0] outnode = [node for node in self._graph.nodes() if str(node).endswith('.' + nodename)] if outnode: outnode = outnode[0] if nodenames[1:] and issubclass(outnode.__class__, Workflow): outnode = outnode.get_node('.'.join(nodenames[1:])) else: outnode = None return outnode def list_node_names(self): """List names of all nodes in a workflow """ outlist = [] for node in nx.topological_sort(self._graph): if isinstance(node, Workflow): outlist.extend(['.'.join((node.name, nodename)) for nodename in node.list_node_names()]) else: outlist.append(node.name) return sorted(outlist) def write_graph(self, dotfilename='graph.dot', graph2use='hierarchical', format="png", simple_form=True): """Generates a graphviz dot file and a png file Parameters ---------- graph2use: 'orig', 'hierarchical' (default), 'flat', 'exec', 'colored' orig - creates a top level graph without expanding internal workflow nodes; flat - expands workflow nodes recursively; hierarchical - expands workflow nodes recursively with a notion on hierarchy; colored - expands workflow nodes recursively with a notion on hierarchy in color; exec - expands workflows to depict iterables format: 'png', 'svg' simple_form: boolean (default: True) Determines if the node name used in the graph should be of the form 'nodename (package)' when True or 'nodename.Class.package' when False. """ graphtypes = ['orig', 'flat', 'hierarchical', 'exec', 'colored'] if graph2use not in graphtypes: raise ValueError('Unknown graph2use keyword. Must be one of: ' + str(graphtypes)) base_dir, dotfilename = op.split(dotfilename) if base_dir == '': if self.base_dir: base_dir = self.base_dir if self.name: base_dir = op.join(base_dir, self.name) else: base_dir = os.getcwd() base_dir = make_output_dir(base_dir) if graph2use in ['hierarchical', 'colored']: dotfilename = op.join(base_dir, dotfilename) self.write_hierarchical_dotfile(dotfilename=dotfilename, colored=graph2use == "colored", simple_form=simple_form) format_dot(dotfilename, format=format) else: graph = self._graph if graph2use in ['flat', 'exec']: graph = self._create_flat_graph() if graph2use == 'exec': graph = generate_expanded_graph(deepcopy(graph)) export_graph(graph, base_dir, dotfilename=dotfilename, format=format, simple_form=simple_form) def write_hierarchical_dotfile(self, dotfilename=None, colored=False, simple_form=True): dotlist = ['digraph %s{' % self.name] dotlist.append(self._get_dot(prefix=' ', colored=colored, simple_form=simple_form)) dotlist.append('}') dotstr = '\n'.join(dotlist) if dotfilename: fp = open(dotfilename, 'wt') fp.writelines(dotstr) fp.close() else: logger.info(dotstr) def export(self, filename=None, prefix="output", format="python", include_config=False): """Export object into a different format Parameters ---------- filename: string file to save the code to; overrides prefix prefix: string prefix to use for output file format: string one of "python" include_config: boolean whether to include node and workflow config values """ formats = ["python"] if format not in formats: raise ValueError('format must be one of: %s' % '|'.join(formats)) flatgraph = self._create_flat_graph() nodes = nx.topological_sort(flatgraph) lines = ['# Workflow'] importlines = ['from nipype.pipeline.engine import Workflow, ' 'Node, MapNode'] functions = {} if format == "python": connect_template = '%s.connect(%%s, %%s, %%s, "%%s")' % self.name connect_template2 = '%s.connect(%%s, "%%s", %%s, "%%s")' \ % self.name wfdef = '%s = Workflow("%s")' % (self.name, self.name) lines.append(wfdef) if include_config: lines.append('%s.config = %s' % (self.name, self.config)) for idx, node in enumerate(nodes): nodename = node.fullname.replace('.', '_') # write nodes nodelines = format_node(node, format='python', include_config=include_config) for line in nodelines: if line.startswith('from'): if line not in importlines: importlines.append(line) else: lines.append(line) # write connections for u, _, d in flatgraph.in_edges_iter(nbunch=node, data=True): for cd in d['connect']: if isinstance(cd[0], tuple): args = list(cd[0]) if args[1] in functions: funcname = functions[args[1]] else: func = create_function_from_source(args[1]) funcname = [name for name in func.func_globals if name != '__builtins__'][0] functions[args[1]] = funcname args[1] = funcname args = tuple([arg for arg in args if arg]) line_args = (u.fullname.replace('.', '_'), args, nodename, cd[1]) line = connect_template % line_args line = line.replace("'%s'" % funcname, funcname) lines.append(line) else: line_args = (u.fullname.replace('.', '_'), cd[0], nodename, cd[1]) lines.append(connect_template2 % line_args) functionlines = ['# Functions'] for function in functions: functionlines.append(cPickle.loads(function).rstrip()) all_lines = importlines + functionlines + lines if not filename: filename = '%s%s.py' % (prefix, self.name) with open(filename, 'wt') as fp: fp.writelines('\n'.join(all_lines)) return all_lines def run(self, plugin=None, plugin_args=None, updatehash=False): """ Execute the workflow Parameters ---------- plugin: plugin name or object Plugin to use for execution. You can create your own plugins for execution. plugin_args : dictionary containing arguments to be sent to plugin constructor. see individual plugin doc strings for details. """ if plugin is None: plugin = config.get('execution', 'plugin') if type(plugin) is not str: runner = plugin else: name = 'nipype.pipeline.plugins' try: __import__(name) except ImportError: msg = 'Could not import plugin module: %s' % name logger.error(msg) raise ImportError(msg) else: plugin_mod = getattr(sys.modules[name], '%sPlugin' % plugin) runner = plugin_mod(plugin_args=plugin_args) flatgraph = self._create_flat_graph() self.config = merge_dict(deepcopy(config._sections), self.config) if 'crashdump_dir' in self.config: warn(("Deprecated: workflow.config['crashdump_dir']\n" "Please use config['execution']['crashdump_dir']")) crash_dir = self.config['crashdump_dir'] self.config['execution']['crashdump_dir'] = crash_dir del self.config['crashdump_dir'] logger.info(str(sorted(self.config))) self._set_needed_outputs(flatgraph) execgraph = generate_expanded_graph(deepcopy(flatgraph)) for index, node in enumerate(execgraph.nodes()): node.config = merge_dict(deepcopy(self.config), node.config) node.base_dir = self.base_dir node.index = index if isinstance(node, MapNode): node.use_plugin = (plugin, plugin_args) self._configure_exec_nodes(execgraph) if str2bool(self.config['execution']['create_report']): self._write_report_info(self.base_dir, self.name, execgraph) runner.run(execgraph, updatehash=updatehash, config=self.config) datestr = datetime.utcnow().strftime('%Y%m%dT%H%M%S') if str2bool(self.config['execution']['write_provenance']): prov_base = op.join(self.base_dir, 'workflow_provenance_%s' % datestr) logger.info('Provenance file prefix: %s' % prov_base) write_workflow_prov(execgraph, prov_base, format='all') return execgraph # PRIVATE API AND FUNCTIONS def _write_report_info(self, workingdir, name, graph): if workingdir is None: workingdir = os.getcwd() report_dir = op.join(workingdir, name) if not op.exists(report_dir): os.makedirs(report_dir) shutil.copyfile(op.join(op.dirname(__file__), 'report_template.html'), op.join(report_dir, 'index.html')) shutil.copyfile(op.join(op.dirname(__file__), '..', 'external', 'd3.js'), op.join(report_dir, 'd3.js')) nodes, groups = topological_sort(graph, depth_first=True) graph_file = op.join(report_dir, 'graph1.json') json_dict = {'nodes': [], 'links': [], 'groups': [], 'maxN': 0} for i, node in enumerate(nodes): report_file = "%s/_report/report.rst" % \ node.output_dir().replace(report_dir, '') result_file = "%s/result_%s.pklz" % \ (node.output_dir().replace(report_dir, ''), node.name) json_dict['nodes'].append(dict(name='%d_%s' % (i, node.name), report=report_file, result=result_file, group=groups[i])) maxN = 0 for gid in np.unique(groups): procs = [i for i, val in enumerate(groups) if val == gid] N = len(procs) if N > maxN: maxN = N json_dict['groups'].append(dict(procs=procs, total=N, name='Group_%05d' % gid)) json_dict['maxN'] = maxN for u, v in graph.in_edges_iter(): json_dict['links'].append(dict(source=nodes.index(u), target=nodes.index(v), value=1)) save_json(graph_file, json_dict) graph_file = op.join(report_dir, 'graph.json') template = '%%0%dd_' % np.ceil(np.log10(len(nodes))).astype(int) def getname(u, i): name_parts = u.fullname.split('.') #return '.'.join(name_parts[:-1] + [template % i + name_parts[-1]]) return template % i + name_parts[-1] json_dict = [] for i, node in enumerate(nodes): imports = [] for u, v in graph.in_edges_iter(nbunch=node): imports.append(getname(u, nodes.index(u))) json_dict.append(dict(name=getname(node, i), size=1, group=groups[i], imports=imports)) save_json(graph_file, json_dict) def _set_needed_outputs(self, graph): """Initialize node with list of which outputs are needed.""" rm_outputs = self.config['execution']['remove_unnecessary_outputs'] if not str2bool(rm_outputs): return for node in graph.nodes(): node.needed_outputs = [] for edge in graph.out_edges_iter(node): data = graph.get_edge_data(*edge) for sourceinfo, _ in sorted(data['connect']): if isinstance(sourceinfo, tuple): input_name = sourceinfo[0] else: input_name = sourceinfo if input_name not in node.needed_outputs: node.needed_outputs += [input_name] if node.needed_outputs: node.needed_outputs = sorted(node.needed_outputs) def _configure_exec_nodes(self, graph): """Ensure that each node knows where to get inputs from """ for node in graph.nodes(): node.input_source = {} for edge in graph.in_edges_iter(node): data = graph.get_edge_data(*edge) for sourceinfo, field in sorted(data['connect']): node.input_source[field] = \ (op.join(edge[0].output_dir(), 'result_%s.pklz' % edge[0].name), sourceinfo) def _check_nodes(self, nodes): """Checks if any of the nodes are already in the graph """ node_names = [node.name for node in self._graph.nodes()] node_lineage = [node._hierarchy for node in self._graph.nodes()] for node in nodes: if node.name in node_names: idx = node_names.index(node.name) if node_lineage[idx] in [node._hierarchy, self.name]: raise IOError('Duplicate node name %s found.' % node.name) else: node_names.append(node.name) def _has_attr(self, parameter, subtype='in'): """Checks if a parameter is available as an input or output """ if subtype == 'in': subobject = self.inputs else: subobject = self.outputs attrlist = parameter.split('.') cur_out = subobject for attr in attrlist: if not hasattr(cur_out, attr): return False cur_out = getattr(cur_out, attr) return True def _get_parameter_node(self, parameter, subtype='in'): """Returns the underlying node corresponding to an input or output parameter """ if subtype == 'in': subobject = self.inputs else: subobject = self.outputs attrlist = parameter.split('.') cur_out = subobject for attr in attrlist[:-1]: cur_out = getattr(cur_out, attr) return cur_out.traits()[attrlist[-1]].node def _check_outputs(self, parameter): return self._has_attr(parameter, subtype='out') def _check_inputs(self, parameter): return self._has_attr(parameter, subtype='in') def _get_inputs(self): """Returns the inputs of a workflow This function does not return any input ports that are already connected """ inputdict = TraitedSpec() for node in self._graph.nodes(): inputdict.add_trait(node.name, traits.Instance(TraitedSpec)) if isinstance(node, Workflow): setattr(inputdict, node.name, node.inputs) else: taken_inputs = [] for _, _, d in self._graph.in_edges_iter(nbunch=node, data=True): for cd in d['connect']: taken_inputs.append(cd[1]) unconnectedinputs = TraitedSpec() for key, trait in node.inputs.items(): if key not in taken_inputs: unconnectedinputs.add_trait(key, traits.Trait(trait, node=node)) value = getattr(node.inputs, key) setattr(unconnectedinputs, key, value) setattr(inputdict, node.name, unconnectedinputs) getattr(inputdict, node.name).on_trait_change(self._set_input) return inputdict def _get_outputs(self): """Returns all possible output ports that are not already connected """ outputdict = TraitedSpec() for node in self._graph.nodes(): outputdict.add_trait(node.name, traits.Instance(TraitedSpec)) if isinstance(node, Workflow): setattr(outputdict, node.name, node.outputs) elif node.outputs: outputs = TraitedSpec() for key, _ in node.outputs.items(): outputs.add_trait(key, traits.Any(node=node)) setattr(outputs, key, None) setattr(outputdict, node.name, outputs) return outputdict def _set_input(self, object, name, newvalue): """Trait callback function to update a node input """ object.traits()[name].node.set_input(name, newvalue) def _set_node_input(self, node, param, source, sourceinfo): """Set inputs of a node given the edge connection""" if isinstance(sourceinfo, six.string_types): val = source.get_output(sourceinfo) elif isinstance(sourceinfo, tuple): if callable(sourceinfo[1]): val = sourceinfo[1](source.get_output(sourceinfo[0]), *sourceinfo[2:]) newval = val if isinstance(val, TraitDictObject): newval = dict(val) if isinstance(val, TraitListObject): newval = val[:] logger.debug('setting node input: %s->%s', param, str(newval)) node.set_input(param, deepcopy(newval)) def _get_all_nodes(self): allnodes = [] for node in self._graph.nodes(): if isinstance(node, Workflow): allnodes.extend(node._get_all_nodes()) else: allnodes.append(node) return allnodes def _has_node(self, wanted_node): for node in self._graph.nodes(): if wanted_node == node: return True if isinstance(node, Workflow): if node._has_node(wanted_node): return True return False def _create_flat_graph(self): """Make a simple DAG where no node is a workflow.""" logger.debug('Creating flat graph for workflow: %s', self.name) workflowcopy = deepcopy(self) workflowcopy._generate_flatgraph() return workflowcopy._graph def _reset_hierarchy(self): """Reset the hierarchy on a graph """ for node in self._graph.nodes(): if isinstance(node, Workflow): node._reset_hierarchy() for innernode in node._graph.nodes(): innernode._hierarchy = '.'.join((self.name, innernode._hierarchy)) else: node._hierarchy = self.name def _generate_flatgraph(self): """Generate a graph containing only Nodes or MapNodes """ logger.debug('expanding workflow: %s', self) nodes2remove = [] if not nx.is_directed_acyclic_graph(self._graph): raise Exception(('Workflow: %s is not a directed acyclic graph ' '(DAG)') % self.name) nodes = nx.topological_sort(self._graph) for node in nodes: logger.debug('processing node: %s' % node) if isinstance(node, Workflow): nodes2remove.append(node) # use in_edges instead of in_edges_iter to allow # disconnections to take place properly. otherwise, the # edge dict is modified. for u, _, d in self._graph.in_edges(nbunch=node, data=True): logger.debug('in: connections-> %s' % str(d['connect'])) for cd in deepcopy(d['connect']): logger.debug("in: %s" % str(cd)) dstnode = node._get_parameter_node(cd[1], subtype='in') srcnode = u srcout = cd[0] dstin = cd[1].split('.')[-1] logger.debug('in edges: %s %s %s %s' % (srcnode, srcout, dstnode, dstin)) self.disconnect(u, cd[0], node, cd[1]) self.connect(srcnode, srcout, dstnode, dstin) # do not use out_edges_iter for reasons stated in in_edges for _, v, d in self._graph.out_edges(nbunch=node, data=True): logger.debug('out: connections-> %s' % str(d['connect'])) for cd in deepcopy(d['connect']): logger.debug("out: %s" % str(cd)) dstnode = v if isinstance(cd[0], tuple): parameter = cd[0][0] else: parameter = cd[0] srcnode = node._get_parameter_node(parameter, subtype='out') if isinstance(cd[0], tuple): srcout = list(cd[0]) srcout[0] = parameter.split('.')[-1] srcout = tuple(srcout) else: srcout = parameter.split('.')[-1] dstin = cd[1] logger.debug('out edges: %s %s %s %s' % (srcnode, srcout, dstnode, dstin)) self.disconnect(node, cd[0], v, cd[1]) self.connect(srcnode, srcout, dstnode, dstin) # expand the workflow node #logger.debug('expanding workflow: %s', node) node._generate_flatgraph() for innernode in node._graph.nodes(): innernode._hierarchy = '.'.join((self.name, innernode._hierarchy)) self._graph.add_nodes_from(node._graph.nodes()) self._graph.add_edges_from(node._graph.edges(data=True)) if nodes2remove: self._graph.remove_nodes_from(nodes2remove) logger.debug('finished expanding workflow: %s', self) def _get_dot(self, prefix=None, hierarchy=None, colored=False, simple_form=True, level=0): """Create a dot file with connection info """ if prefix is None: prefix = ' ' if hierarchy is None: hierarchy = [] colorset = ['#FFFFC8','#0000FF','#B4B4FF','#E6E6FF','#FF0000', '#FFB4B4','#FFE6E6','#00A300','#B4FFB4','#E6FFE6'] dotlist = ['%slabel="%s";' % (prefix, self.name)] for node in nx.topological_sort(self._graph): fullname = '.'.join(hierarchy + [node.fullname]) nodename = fullname.replace('.', '_') if not isinstance(node, Workflow): node_class_name = get_print_name(node, simple_form=simple_form) if not simple_form: node_class_name = '.'.join(node_class_name.split('.')[1:]) if hasattr(node, 'iterables') and node.iterables: dotlist.append(('%s[label="%s", shape=box3d,' 'style=filled, color=black, colorscheme' '=greys7 fillcolor=2];') % (nodename, node_class_name)) else: if colored: dotlist.append(('%s[label="%s", style=filled,' ' fillcolor="%s"];') % (nodename,node_class_name, colorset[level])) else: dotlist.append(('%s[label="%s"];') % (nodename,node_class_name)) for node in nx.topological_sort(self._graph): if isinstance(node, Workflow): fullname = '.'.join(hierarchy + [node.fullname]) nodename = fullname.replace('.', '_') dotlist.append('subgraph cluster_%s {' % nodename) if colored: dotlist.append(prefix + prefix + 'edge [color="%s"];' % (colorset[level+1])) dotlist.append(prefix + prefix + 'style=filled;') dotlist.append(prefix + prefix + 'fillcolor="%s";' % (colorset[level+2])) dotlist.append(node._get_dot(prefix=prefix + prefix, hierarchy=hierarchy + [self.name], colored=colored, simple_form=simple_form, level=level+3)) dotlist.append('}') if level==6:level=2 else: for subnode in self._graph.successors_iter(node): if node._hierarchy != subnode._hierarchy: continue if not isinstance(subnode, Workflow): nodefullname = '.'.join(hierarchy + [node.fullname]) subnodefullname = '.'.join(hierarchy + [subnode.fullname]) nodename = nodefullname.replace('.', '_') subnodename = subnodefullname.replace('.', '_') for _ in self._graph.get_edge_data(node, subnode)['connect']: dotlist.append('%s -> %s;' % (nodename, subnodename)) logger.debug('connection: ' + dotlist[-1]) # add between workflow connections for u, v, d in self._graph.edges_iter(data=True): uname = '.'.join(hierarchy + [u.fullname]) vname = '.'.join(hierarchy + [v.fullname]) for src, dest in d['connect']: uname1 = uname vname1 = vname if isinstance(src, tuple): srcname = src[0] else: srcname = src if '.' in srcname: uname1 += '.' + '.'.join(srcname.split('.')[:-1]) if '.' in dest and '@' not in dest: if not isinstance(v, Workflow): if 'datasink' not in \ str(v._interface.__class__).lower(): vname1 += '.' + '.'.join(dest.split('.')[:-1]) else: vname1 += '.' + '.'.join(dest.split('.')[:-1]) if uname1.split('.')[:-1] != vname1.split('.')[:-1]: dotlist.append('%s -> %s;' % (uname1.replace('.', '_'), vname1.replace('.', '_'))) logger.debug('cross connection: ' + dotlist[-1]) return ('\n' + prefix).join(dotlist) class Node(WorkflowBase): """Wraps interface objects for use in pipeline A Node creates a sandbox-like directory for executing the underlying interface. It will copy or link inputs into this directory to ensure that input data are not overwritten. A hash of the input state is used to determine if the Node inputs have changed and whether the node needs to be re-executed. Examples -------- >>> from nipype import Node >>> from nipype.interfaces import spm >>> realign = Node(spm.Realign(), 'realign') >>> realign.inputs.in_files = 'functional.nii' >>> realign.inputs.register_to_mean = True >>> realign.run() # doctest: +SKIP """ def __init__(self, interface, name, iterables=None, itersource=None, synchronize=False, overwrite=None, needed_outputs=None, run_without_submitting=False, **kwargs): """ Parameters ---------- interface : interface object node specific interface (fsl.Bet(), spm.Coregister()) name : alphanumeric string node specific name iterables : generator Input field and list to iterate using the pipeline engine for example to iterate over different frac values in fsl.Bet() for a single field the input can be a tuple, otherwise a list of tuples :: node.iterables = ('frac',[0.5,0.6,0.7]) node.iterables = [('fwhm',[2,4]),('fieldx',[0.5,0.6,0.7])] If this node has an itersource, then the iterables values is a dictionary which maps an iterable source field value to the target iterables field values, e.g.: :: inputspec.iterables = ('images',['img1.nii', 'img2.nii']]) node.itersource = ('inputspec', ['frac']) node.iterables = ('frac', {'img1.nii': [0.5, 0.6], 'img2.nii': [0.6, 0.7]}) If this node's synchronize flag is set, then an alternate form of the iterables is a [fields, values] list, where fields is the list of iterated fields and values is the list of value tuples for the given fields, e.g.: :: node.synchronize = True node.iterables = [('frac', 'threshold'), [(0.5, True), (0.6, False)]] itersource: tuple The (name, fields) iterables source which specifies the name of the predecessor iterable node and the input fields to use from that source node. The output field values comprise the key to the iterables parameter value mapping dictionary. synchronize: boolean Flag indicating whether iterables are synchronized. If the iterables are synchronized, then this iterable node is expanded once per iteration over all of the iterables values. Otherwise, this iterable node is expanded once per each permutation of the iterables values. overwrite : Boolean Whether to overwrite contents of output directory if it already exists. If directory exists and hash matches it assumes that process has been executed needed_outputs : list of output_names Force the node to keep only specific outputs. By default all outputs are kept. Setting this attribute will delete any output files and directories from the node's working directory that are not part of the `needed_outputs`. run_without_submitting : boolean Run the node without submitting to a job engine or to a multiprocessing pool """ base_dir = None if 'base_dir' in kwargs: base_dir = kwargs['base_dir'] super(Node, self).__init__(name, base_dir) if interface is None: raise IOError('Interface must be provided') if not isinstance(interface, Interface): raise IOError('interface must be an instance of an Interface') self._interface = interface self.name = name self._result = None self.iterables = iterables self.synchronize = synchronize self.itersource = itersource self.overwrite = overwrite self.parameterization = None self.run_without_submitting = run_without_submitting self.input_source = {} self.needed_outputs = [] self.plugin_args = {} if needed_outputs: self.needed_outputs = sorted(needed_outputs) self._got_inputs = False @property def interface(self): """Return the underlying interface object""" return self._interface @property def result(self): if self._result: return self._result else: cwd = self.output_dir() result, _, _ = self._load_resultfile(cwd) return result @property def inputs(self): """Return the inputs of the underlying interface""" return self._interface.inputs @property def outputs(self): """Return the output fields of the underlying interface""" return self._interface._outputs() def output_dir(self): """Return the location of the output directory for the node""" if self.base_dir is None: self.base_dir = mkdtemp() outputdir = self.base_dir if self._hierarchy: outputdir = op.join(outputdir, *self._hierarchy.split('.')) if self.parameterization: if not str2bool(self.config['execution']['parameterize_dirs']): param_dirs = [self._parameterization_dir(p) for p in self.parameterization] outputdir = op.join(outputdir, *param_dirs) else: outputdir = op.join(outputdir, *self.parameterization) return op.abspath(op.join(outputdir, self.name)) def set_input(self, parameter, val): """ Set interface input value""" logger.debug('setting nodelevel(%s) input %s = %s' % (str(self), parameter, str(val))) setattr(self.inputs, parameter, deepcopy(val)) def get_output(self, parameter): """Retrieve a particular output of the node""" val = None if self._result: val = getattr(self._result.outputs, parameter) else: cwd = self.output_dir() result, _, _ = self._load_resultfile(cwd) if result and result.outputs: val = getattr(result.outputs, parameter) return val def help(self): """ Print interface help""" self._interface.help() def hash_exists(self, updatehash=False): # Get a dictionary with hashed filenames and a hashvalue # of the dictionary itself. hashed_inputs, hashvalue = self._get_hashval() outdir = self.output_dir() if op.exists(outdir): logger.debug(os.listdir(outdir)) hashfiles = glob(op.join(outdir, '_0x*.json')) logger.debug(hashfiles) if len(hashfiles) > 1: logger.info(hashfiles) logger.info('Removing multiple hashfiles and forcing node to rerun') for hashfile in hashfiles: os.unlink(hashfile) hashfile = op.join(outdir, '_0x%s.json' % hashvalue) logger.debug(hashfile) if updatehash and op.exists(outdir): logger.debug("Updating hash: %s" % hashvalue) for file in glob(op.join(outdir, '_0x*.json')): os.remove(file) self._save_hashfile(hashfile, hashed_inputs) return op.exists(hashfile), hashvalue, hashfile, hashed_inputs def run(self, updatehash=False): """Execute the node in its directory. Parameters ---------- updatehash: boolean Update the hash stored in the output directory """ # check to see if output directory and hash exist if self.config is None: self.config = deepcopy(config._sections) else: self.config = merge_dict(deepcopy(config._sections), self.config) if not self._got_inputs: self._get_inputs() self._got_inputs = True outdir = self.output_dir() logger.info("Executing node %s in dir: %s" % (self._id, outdir)) if op.exists(outdir): logger.debug(os.listdir(outdir)) hash_info = self.hash_exists(updatehash=updatehash) hash_exists, hashvalue, hashfile, hashed_inputs = hash_info logger.debug(('updatehash, overwrite, always_run, hash_exists', updatehash, self.overwrite, self._interface.always_run, hash_exists)) if (not updatehash and (((self.overwrite is None and self._interface.always_run) or self.overwrite) or not hash_exists)): logger.debug("Node hash: %s" % hashvalue) # by rerunning we mean only nodes that did finish to run previously json_pat = op.join(outdir, '_0x*.json') json_unfinished_pat = op.join(outdir, '_0x*_unfinished.json') need_rerun = (op.exists(outdir) and not isinstance(self, MapNode) and len(glob(json_pat)) != 0 and len(glob(json_unfinished_pat)) == 0) if need_rerun: logger.debug("Rerunning node") logger.debug(("updatehash = %s, " "self.overwrite = %s, " "self._interface.always_run = %s, " "os.path.exists(%s) = %s, " "hash_method = %s") % (str(updatehash), str(self.overwrite), str(self._interface.always_run), hashfile, str(op.exists(hashfile)), self.config['execution']['hash_method'].lower())) log_debug = config.get('logging', 'workflow_level') == 'DEBUG' if log_debug and not op.exists(hashfile): exp_hash_paths = glob(json_pat) if len(exp_hash_paths) == 1: split_out = split_filename(exp_hash_paths[0]) exp_hash_file_base = split_out[1] exp_hash = exp_hash_file_base[len('_0x'):] logger.debug("Previous node hash = %s" % exp_hash) try: prev_inputs = load_json(exp_hash_paths[0]) except: pass else: logging.logdebug_dict_differences(prev_inputs, hashed_inputs) cannot_rerun = (str2bool( self.config['execution']['stop_on_first_rerun']) and not (self.overwrite is None and self._interface.always_run)) if cannot_rerun: raise Exception(("Cannot rerun when 'stop_on_first_rerun' " "is set to True")) hashfile_unfinished = op.join(outdir, '_0x%s_unfinished.json' % hashvalue) if op.exists(hashfile): os.remove(hashfile) rm_outdir = (op.exists(outdir) and not (op.exists(hashfile_unfinished) and self._interface.can_resume) and not isinstance(self, MapNode)) if rm_outdir: logger.debug("Removing old %s and its contents" % outdir) try: rmtree(outdir) except OSError as ex: outdircont = os.listdir(outdir) if ((ex.errno == errno.ENOTEMPTY) and (len(outdircont) == 0)): logger.warn(('An exception was raised trying to remove old %s, ' 'but the path seems empty. Is it an NFS mount?. ' 'Passing the exception.') % outdir) pass elif ((ex.errno == errno.ENOTEMPTY) and (len(outdircont) != 0)): logger.debug(('Folder contents (%d items): ' '%s') % (len(outdircont), outdircont)) raise ex else: raise ex else: logger.debug(("%s found and can_resume is True or Node is a " "MapNode - resuming execution") % hashfile_unfinished) if isinstance(self, MapNode): # remove old json files for filename in glob(op.join(outdir, '_0x*.json')): os.unlink(filename) outdir = make_output_dir(outdir) self._save_hashfile(hashfile_unfinished, hashed_inputs) self.write_report(report_type='preexec', cwd=outdir) savepkl(op.join(outdir, '_node.pklz'), self) savepkl(op.join(outdir, '_inputs.pklz'), self.inputs.get_traitsfree()) try: self._run_interface() except: os.remove(hashfile_unfinished) raise shutil.move(hashfile_unfinished, hashfile) self.write_report(report_type='postexec', cwd=outdir) else: if not op.exists(op.join(outdir, '_inputs.pklz')): logger.debug('%s: creating inputs file' % self.name) savepkl(op.join(outdir, '_inputs.pklz'), self.inputs.get_traitsfree()) if not op.exists(op.join(outdir, '_node.pklz')): logger.debug('%s: creating node file' % self.name) savepkl(op.join(outdir, '_node.pklz'), self) logger.debug("Hashfile exists. Skipping execution") self._run_interface(execute=False, updatehash=updatehash) logger.debug('Finished running %s in dir: %s\n' % (self._id, outdir)) return self._result # Private functions def _parameterization_dir(self, param): """ Returns the directory name for the given parameterization string as follows: - If the parameterization is longer than 32 characters, then return the SHA-1 hex digest. - Otherwise, return the parameterization unchanged. """ if len(param) > 32: return sha1(param).hexdigest() else: return param def _get_hashval(self): """Return a hash of the input state""" if not self._got_inputs: self._get_inputs() self._got_inputs = True hashed_inputs, hashvalue = self.inputs.get_hashval( hash_method=self.config['execution']['hash_method']) rm_extra = self.config['execution']['remove_unnecessary_outputs'] if str2bool(rm_extra) and self.needed_outputs: hashobject = md5() hashobject.update(hashvalue) sorted_outputs = sorted(self.needed_outputs) hashobject.update(str(sorted_outputs)) hashvalue = hashobject.hexdigest() hashed_inputs.append(('needed_outputs', sorted_outputs)) return hashed_inputs, hashvalue def _save_hashfile(self, hashfile, hashed_inputs): try: save_json(hashfile, hashed_inputs) except (IOError, TypeError): err_type = sys.exc_info()[0] if err_type is TypeError: # XXX - SG current workaround is to just # create the hashed file and not put anything # in it fd = open(hashfile, 'wt') fd.writelines(str(hashed_inputs)) fd.close() logger.debug(('Unable to write a particular type to the json ' 'file')) else: logger.critical('Unable to open the file in write mode: %s' % hashfile) def _get_inputs(self): """Retrieve inputs from pointers to results file This mechanism can be easily extended/replaced to retrieve data from other data sources (e.g., XNAT, HTTP, etc.,.) """ logger.debug('Setting node inputs') for key, info in self.input_source.items(): logger.debug('input: %s' % key) results_file = info[0] logger.debug('results file: %s' % results_file) results = loadpkl(results_file) output_value = Undefined if isinstance(info[1], tuple): output_name = info[1][0] value = getattr(results.outputs, output_name) if isdefined(value): output_value = evaluate_connect_function(info[1][1], info[1][2], value) else: output_name = info[1] try: output_value = results.outputs.get()[output_name] except TypeError: output_value = results.outputs.dictcopy()[output_name] logger.debug('output: %s' % output_name) try: self.set_input(key, deepcopy(output_value)) except traits.TraitError, e: msg = ['Error setting node input:', 'Node: %s' % self.name, 'input: %s' % key, 'results_file: %s' % results_file, 'value: %s' % str(output_value)] e.args = (e.args[0] + "\n" + '\n'.join(msg),) raise def _run_interface(self, execute=True, updatehash=False): if updatehash: return old_cwd = os.getcwd() os.chdir(self.output_dir()) self._result = self._run_command(execute) os.chdir(old_cwd) def _save_results(self, result, cwd): resultsfile = op.join(cwd, 'result_%s.pklz' % self.name) if result.outputs: try: outputs = result.outputs.get() except TypeError: outputs = result.outputs.dictcopy() # outputs was a bunch result.outputs.set(**modify_paths(outputs, relative=True, basedir=cwd)) savepkl(resultsfile, result) logger.debug('saved results in %s' % resultsfile) if result.outputs: result.outputs.set(**outputs) def _load_resultfile(self, cwd): """Load results if it exists in cwd Parameter --------- cwd : working directory of node Returns ------- result : InterfaceResult structure aggregate : boolean indicating whether node should aggregate_outputs attribute error : boolean indicating whether there was some mismatch in versions of traits used to store result and hence node needs to rerun """ aggregate = True resultsoutputfile = op.join(cwd, 'result_%s.pklz' % self.name) result = None attribute_error = False if op.exists(resultsoutputfile): pkl_file = gzip.open(resultsoutputfile, 'rb') try: result = cPickle.load(pkl_file) except (traits.TraitError, AttributeError, ImportError), err: if isinstance(err, (AttributeError, ImportError)): attribute_error = True logger.debug(('attribute error: %s probably using ' 'different trait pickled file') % str(err)) else: logger.debug(('some file does not exist. hence trait ' 'cannot be set')) else: if result.outputs: try: outputs = result.outputs.get() except TypeError: outputs = result.outputs.dictcopy() # outputs == Bunch try: result.outputs.set(**modify_paths(outputs, relative=False, basedir=cwd)) except FileNotFoundError: logger.debug(('conversion to full path results in ' 'non existent file')) aggregate = False pkl_file.close() logger.debug('Aggregate: %s', aggregate) return result, aggregate, attribute_error def _load_results(self, cwd): result, aggregate, attribute_error = self._load_resultfile(cwd) # try aggregating first if aggregate: logger.debug('aggregating results') if attribute_error: old_inputs = loadpkl(op.join(cwd, '_inputs.pklz')) self.inputs.set(**old_inputs) if not isinstance(self, MapNode): self._copyfiles_to_wd(cwd, True, linksonly=True) aggouts = self._interface.aggregate_outputs( needed_outputs=self.needed_outputs) runtime = Bunch(cwd=cwd, returncode=0, environ=deepcopy(os.environ.data), hostname=gethostname()) result = InterfaceResult( interface=self._interface.__class__, runtime=runtime, inputs=self._interface.inputs.get_traitsfree(), outputs=aggouts) self._save_results(result, cwd) else: logger.debug('aggregating mapnode results') self._run_interface() result = self._result return result def _run_command(self, execute, copyfiles=True): cwd = os.getcwd() if execute and copyfiles: self._originputs = deepcopy(self._interface.inputs) if execute: runtime = Bunch(returncode=1, environ=deepcopy(os.environ.data), hostname=gethostname()) result = InterfaceResult( interface=self._interface.__class__, runtime=runtime, inputs=self._interface.inputs.get_traitsfree()) self._result = result logger.debug('Executing node') if copyfiles: self._copyfiles_to_wd(cwd, execute) if issubclass(self._interface.__class__, CommandLine): try: cmd = self._interface.cmdline except Exception, msg: self._result.runtime.stderr = msg raise cmdfile = op.join(cwd, 'command.txt') fd = open(cmdfile, 'wt') fd.writelines(cmd + "\n") fd.close() logger.info('Running: %s' % cmd) try: result = self._interface.run() except Exception, msg: self._result.runtime.stderr = msg raise dirs2keep = None if isinstance(self, MapNode): dirs2keep = [op.join(cwd, 'mapflow')] result.outputs = clean_working_directory(result.outputs, cwd, self._interface.inputs, self.needed_outputs, self.config, dirs2keep=dirs2keep) self._save_results(result, cwd) else: logger.info("Collecting precomputed outputs") try: result = self._load_results(cwd) except (FileNotFoundError, AttributeError): # if aggregation does not work, rerun the node logger.info(("Some of the outputs were not found: " "rerunning node.")) result = self._run_command(execute=True, copyfiles=False) return result def _strip_temp(self, files, wd): out = [] for f in files: if isinstance(f, list): out.append(self._strip_temp(f, wd)) else: out.append(f.replace(op.join(wd, '_tempinput'), wd)) return out def _copyfiles_to_wd(self, outdir, execute, linksonly=False): """ copy files over and change the inputs""" if hasattr(self._interface, '_get_filecopy_info'): logger.debug('copying files to wd [execute=%s, linksonly=%s]' % (str(execute), str(linksonly))) if execute and linksonly: olddir = outdir outdir = op.join(outdir, '_tempinput') os.makedirs(outdir) for info in self._interface._get_filecopy_info(): files = self.inputs.get().get(info['key']) if not isdefined(files): continue if files: infiles = filename_to_list(files) if execute: if linksonly: if not info['copy']: newfiles = copyfiles(infiles, [outdir], copy=info['copy'], create_new=True) else: newfiles = fnames_presuffix(infiles, newpath=outdir) newfiles = self._strip_temp( newfiles, op.abspath(olddir).split(op.sep)[-1]) else: newfiles = copyfiles(infiles, [outdir], copy=info['copy'], create_new=True) else: newfiles = fnames_presuffix(infiles, newpath=outdir) if not isinstance(files, list): newfiles = list_to_filename(newfiles) setattr(self.inputs, info['key'], newfiles) if execute and linksonly: rmtree(outdir) def update(self, **opts): self.inputs.update(**opts) def write_report(self, report_type=None, cwd=None): if not str2bool(self.config['execution']['create_report']): return report_dir = op.join(cwd, '_report') report_file = op.join(report_dir, 'report.rst') if not op.exists(report_dir): os.makedirs(report_dir) if report_type == 'preexec': logger.debug('writing pre-exec report to %s' % report_file) fp = open(report_file, 'wt') fp.writelines(write_rst_header('Node: %s' % get_print_name(self), level=0)) fp.writelines(write_rst_list(['Hierarchy : %s' % self.fullname, 'Exec ID : %s' % self._id])) fp.writelines(write_rst_header('Original Inputs', level=1)) fp.writelines(write_rst_dict(self.inputs.get())) if report_type == 'postexec': logger.debug('writing post-exec report to %s' % report_file) fp = open(report_file, 'at') fp.writelines(write_rst_header('Execution Inputs', level=1)) fp.writelines(write_rst_dict(self.inputs.get())) exit_now = (not hasattr(self.result, 'outputs') or self.result.outputs is None) if exit_now: return fp.writelines(write_rst_header('Execution Outputs', level=1)) if isinstance(self.result.outputs, Bunch): fp.writelines(write_rst_dict(self.result.outputs.dictcopy())) elif self.result.outputs: fp.writelines(write_rst_dict(self.result.outputs.get())) if isinstance(self, MapNode): fp.close() return fp.writelines(write_rst_header('Runtime info', level=1)) if hasattr(self.result.runtime, 'cmdline'): fp.writelines(write_rst_dict( {'hostname': self.result.runtime.hostname, 'duration': self.result.runtime.duration, 'command': self.result.runtime.cmdline})) else: fp.writelines(write_rst_dict( {'hostname': self.result.runtime.hostname, 'duration': self.result.runtime.duration})) if hasattr(self.result.runtime, 'merged'): fp.writelines(write_rst_header('Terminal output', level=2)) fp.writelines(write_rst_list(self.result.runtime.merged)) if hasattr(self.result.runtime, 'environ'): fp.writelines(write_rst_header('Environment', level=2)) fp.writelines(write_rst_dict(self.result.runtime.environ)) fp.close() class JoinNode(Node): """Wraps interface objects that join inputs into a list. Examples -------- >>> import nipype.pipeline.engine as pe >>> from nipype import Node, JoinNode, Workflow >>> from nipype.interfaces.utility import IdentityInterface >>> from nipype.interfaces import (ants, dcm2nii, fsl) >>> wf = Workflow(name='preprocess') >>> inputspec = Node(IdentityInterface(fields=['image']), ... name='inputspec') >>> inputspec.iterables = [('image', ... ['img1.nii', 'img2.nii', 'img3.nii'])] >>> img2flt = Node(fsl.ImageMaths(out_data_type='float'), ... name='img2flt') >>> wf.connect(inputspec, 'image', img2flt, 'in_file') >>> average = JoinNode(ants.AverageImages(), joinsource='inputspec', ... joinfield='images', name='average') >>> wf.connect(img2flt, 'out_file', average, 'images') >>> realign = Node(fsl.FLIRT(), name='realign') >>> wf.connect(img2flt, 'out_file', realign, 'in_file') >>> wf.connect(average, 'output_average_image', realign, 'reference') >>> strip = Node(fsl.BET(), name='strip') >>> wf.connect(realign, 'out_file', strip, 'in_file') """ def __init__(self, interface, name, joinsource, joinfield=None, unique=False, **kwargs): """ Parameters ---------- interface : interface object node specific interface (fsl.Bet(), spm.Coregister()) name : alphanumeric string node specific name joinsource : node name name of the join predecessor iterable node joinfield : string or list of strings name(s) of list input fields that will be aggregated. The default is all of the join node input fields. unique : flag indicating whether to ignore duplicate input values See Node docstring for additional keyword arguments. """ super(JoinNode, self).__init__(interface, name, **kwargs) self.joinsource = joinsource """the join predecessor iterable node""" if not joinfield: # default is the interface fields joinfield = self._interface.inputs.copyable_trait_names() elif isinstance(joinfield, six.string_types): joinfield = [joinfield] self.joinfield = joinfield """the fields to join""" self._inputs = self._override_join_traits(self._interface.inputs, self.joinfield) """the override inputs""" self._unique = unique """flag indicating whether to ignore duplicate input values""" self._next_slot_index = 0 """the joinfield index assigned to an iterated input""" @property def joinsource(self): return self._joinsource @joinsource.setter def joinsource(self, value): """Set the joinsource property. If the given value is a Node, then the joinsource is set to the node name. """ if isinstance(value, Node): value = value.name self._joinsource = value @property def inputs(self): """The JoinNode inputs include the join field overrides.""" return self._inputs def _add_join_item_fields(self): """Add new join item fields assigned to the next iterated input This method is intended solely for workflow graph expansion. Examples -------- >>> from nipype.interfaces.utility import IdentityInterface >>> import nipype.pipeline.engine as pe >>> from nipype import Node, JoinNode, Workflow >>> inputspec = Node(IdentityInterface(fields=['image']), ... name='inputspec'), >>> join = JoinNode(IdentityInterface(fields=['images', 'mask']), ... joinsource='inputspec', joinfield='images', name='join') >>> join._add_join_item_fields() {'images': 'imagesJ1'} Return the {base field: slot field} dictionary """ # create the new join item fields idx = self._next_slot_index newfields = dict([(field, self._add_join_item_field(field, idx)) for field in self.joinfield]) # increment the join slot index logger.debug("Added the %s join item fields %s." % (self, newfields)) self._next_slot_index += 1 return newfields def _add_join_item_field(self, field, index): """Add new join item fields qualified by the given index Return the new field name """ # the new field name name = self._join_item_field_name(field, index) # make a copy of the join trait trait = self._inputs.trait(field, False, True) # add the join item trait to the override traits self._inputs.add_trait(name, trait) return name def _join_item_field_name(self, field, index): """Return the field suffixed by the index + 1""" return "%sJ%d" % (field, index + 1) def _override_join_traits(self, basetraits, fields): """Convert the given join fields to accept an input that is a list item rather than a list. Non-join fields delegate to the interface traits. Return the override DynamicTraitedSpec """ dyntraits = DynamicTraitedSpec() if fields is None: fields = basetraits.copyable_trait_names() else: # validate the fields for field in fields: if not basetraits.trait(field): raise ValueError("The JoinNode %s does not have a field" " named %s" % (self.name, field)) for name, trait in basetraits.items(): # if a join field has a single inner trait, then the item # trait is that inner trait. Otherwise, the item trait is # a new Any trait. if name in fields and len(trait.inner_traits) == 1: item_trait = trait.inner_traits[0] dyntraits.add_trait(name, item_trait) setattr(dyntraits, name, Undefined) logger.debug("Converted the join node %s field %s" " trait type from %s to %s" % (self, name, trait.trait_type.info(), item_trait.info())) else: dyntraits.add_trait(name, traits.Any) setattr(dyntraits, name, Undefined) return dyntraits def _run_command(self, execute, copyfiles=True): """Collates the join inputs prior to delegating to the superclass.""" self._collate_join_field_inputs() return super(JoinNode, self)._run_command(execute, copyfiles) def _collate_join_field_inputs(self): """ Collects each override join item field into the interface join field input.""" for field in self.inputs.copyable_trait_names(): if field in self.joinfield: # collate the join field val = self._collate_input_value(field) try: setattr(self._interface.inputs, field, val) except Exception as e: raise ValueError(">>JN %s %s %s %s %s: %s" % (self, field, val, self.inputs.copyable_trait_names(), self.joinfield, e)) elif hasattr(self._interface.inputs, field): # copy the non-join field val = getattr(self._inputs, field) if isdefined(val): setattr(self._interface.inputs, field, val) logger.debug("Collated %d inputs into the %s node join fields" % (self._next_slot_index, self)) def _collate_input_value(self, field): """ Collects the join item field values into a list or set value for the given field, as follows: - If the field trait is a Set, then the values are collected into a set. - Otherwise, the values are collected into a list which preserves the iterables order. If the ``unique`` flag is set, then duplicate values are removed but the iterables order is preserved. """ val = [self._slot_value(field, idx) for idx in range(self._next_slot_index)] basetrait = self._interface.inputs.trait(field) if isinstance(basetrait.trait_type, traits.Set): return set(val) elif self._unique: return list(OrderedDict.fromkeys(val)) else: return val def _slot_value(self, field, index): slot_field = self._join_item_field_name(field, index) try: return getattr(self._inputs, slot_field) except AttributeError as e: raise AttributeError("The join node %s does not have a slot field %s" " to hold the %s value at index %d: %s" % (self, slot_field, field, index, e)) class MapNode(Node): """Wraps interface objects that need to be iterated on a list of inputs. Examples -------- >>> from nipype import MapNode >>> from nipype.interfaces import fsl >>> realign = MapNode(fsl.MCFLIRT(), 'in_file', 'realign') >>> realign.inputs.in_file = ['functional.nii', ... 'functional2.nii', ... 'functional3.nii'] >>> realign.run() # doctest: +SKIP """ def __init__(self, interface, iterfield, name, serial=False, nested=False, **kwargs): """ Parameters ---------- interface : interface object node specific interface (fsl.Bet(), spm.Coregister()) iterfield : string or list of strings name(s) of input fields that will receive a list of whatever kind of input they take. the node will be run separately for each value in these lists. for more than one input, the values are paired (i.e. it does not compute a combinatorial product). name : alphanumeric string node specific name serial : boolean flag to enforce executing the jobs of the mapnode in a serial manner rather than parallel nested : boolea support for nested lists, if set the input list will be flattened before running, and the nested list structure of the outputs will be resored See Node docstring for additional keyword arguments. """ super(MapNode, self).__init__(interface, name, **kwargs) if isinstance(iterfield, six.string_types): iterfield = [iterfield] self.iterfield = iterfield self.nested = nested self._inputs = self._create_dynamic_traits(self._interface.inputs, fields=self.iterfield) self._inputs.on_trait_change(self._set_mapnode_input) self._got_inputs = False self._serial = serial def _create_dynamic_traits(self, basetraits, fields=None, nitems=None): """Convert specific fields of a trait to accept multiple inputs """ output = DynamicTraitedSpec() if fields is None: fields = basetraits.copyable_trait_names() for name, spec in basetraits.items(): if name in fields and ((nitems is None) or (nitems > 1)): logger.debug('adding multipath trait: %s' % name) if self.nested: output.add_trait(name, InputMultiPath(traits.Any())) else: output.add_trait(name, InputMultiPath(spec.trait_type)) else: output.add_trait(name, traits.Trait(spec)) setattr(output, name, Undefined) value = getattr(basetraits, name) if isdefined(value): setattr(output, name, value) value = getattr(output, name) return output def set_input(self, parameter, val): """ Set interface input value or nodewrapper attribute Priority goes to interface. """ logger.debug('setting nodelevel(%s) input %s = %s' % (str(self), parameter, str(val))) self._set_mapnode_input(self.inputs, parameter, deepcopy(val)) def _set_mapnode_input(self, object, name, newvalue): logger.debug('setting mapnode(%s) input: %s -> %s' % (str(self), name, str(newvalue))) if name in self.iterfield: setattr(self._inputs, name, newvalue) else: setattr(self._interface.inputs, name, newvalue) def _get_hashval(self): """ Compute hash including iterfield lists.""" if not self._got_inputs: self._get_inputs() self._got_inputs = True self._check_iterfield() hashinputs = deepcopy(self._interface.inputs) for name in self.iterfield: hashinputs.remove_trait(name) hashinputs.add_trait( name, InputMultiPath( self._interface.inputs.traits()[name].trait_type)) logger.debug('setting hashinput %s-> %s' % (name, getattr(self._inputs, name))) if self.nested: setattr(hashinputs, name, flatten(getattr(self._inputs, name))) else: setattr(hashinputs, name, getattr(self._inputs, name)) hashed_inputs, hashvalue = hashinputs.get_hashval( hash_method=self.config['execution']['hash_method']) rm_extra = self.config['execution']['remove_unnecessary_outputs'] if str2bool(rm_extra) and self.needed_outputs: hashobject = md5() hashobject.update(hashvalue) sorted_outputs = sorted(self.needed_outputs) hashobject.update(str(sorted_outputs)) hashvalue = hashobject.hexdigest() hashed_inputs.append(('needed_outputs', sorted_outputs)) return hashed_inputs, hashvalue @property def inputs(self): return self._inputs @property def outputs(self): if self._interface._outputs(): return Bunch(self._interface._outputs().get()) else: return None def _make_nodes(self, cwd=None): if cwd is None: cwd = self.output_dir() if self.nested: nitems = len(flatten(filename_to_list(getattr(self.inputs, self.iterfield[0])))) else: nitems = len(filename_to_list(getattr(self.inputs, self.iterfield[0]))) for i in range(nitems): nodename = '_' + self.name + str(i) node = Node(deepcopy(self._interface), name=nodename) node.overwrite = self.overwrite node.run_without_submitting = self.run_without_submitting node.plugin_args = self.plugin_args node._interface.inputs.set( **deepcopy(self._interface.inputs.get())) for field in self.iterfield: if self.nested: fieldvals = flatten(filename_to_list(getattr(self.inputs, field))) else: fieldvals = filename_to_list(getattr(self.inputs, field)) logger.debug('setting input %d %s %s' % (i, field, fieldvals[i])) setattr(node.inputs, field, fieldvals[i]) node.config = self.config node.base_dir = op.join(cwd, 'mapflow') yield i, node def _node_runner(self, nodes, updatehash=False): for i, node in nodes: err = None try: node.run(updatehash=updatehash) except Exception, err: if str2bool(self.config['execution']['stop_on_first_crash']): self._result = node.result raise yield i, node, err def _collate_results(self, nodes): self._result = InterfaceResult(interface=[], runtime=[], provenance=[], inputs=[], outputs=self.outputs) returncode = [] for i, node, err in nodes: self._result.runtime.insert(i, None) if node.result: if hasattr(node.result, 'runtime'): self._result.interface.insert(i, node.result.interface) self._result.inputs.insert(i, node.result.inputs) self._result.runtime[i] = node.result.runtime if hasattr(node.result, 'provenance'): self._result.provenance.insert(i, node.result.provenance) returncode.insert(i, err) if self.outputs: for key, _ in self.outputs.items(): rm_extra = (self.config['execution'] ['remove_unnecessary_outputs']) if str2bool(rm_extra) and self.needed_outputs: if key not in self.needed_outputs: continue values = getattr(self._result.outputs, key) if not isdefined(values): values = [] if node.result.outputs: values.insert(i, node.result.outputs.get()[key]) else: values.insert(i, None) defined_vals = [isdefined(val) for val in values] if any(defined_vals) and self._result.outputs: setattr(self._result.outputs, key, values) if self.nested: for key, _ in self.outputs.items(): values = getattr(self._result.outputs, key) if isdefined(values): values = unflatten(values, filename_to_list(getattr(self.inputs, self.iterfield[0]))) setattr(self._result.outputs, key, values) if returncode and any([code is not None for code in returncode]): msg = [] for i, code in enumerate(returncode): if code is not None: msg += ['Subnode %d failed' % i] msg += ['Error:', str(code)] raise Exception('Subnodes of node: %s failed:\n%s' % (self.name, '\n'.join(msg))) def write_report(self, report_type=None, cwd=None): if not str2bool(self.config['execution']['create_report']): return if report_type == 'preexec': super(MapNode, self).write_report(report_type=report_type, cwd=cwd) if report_type == 'postexec': super(MapNode, self).write_report(report_type=report_type, cwd=cwd) report_dir = op.join(cwd, '_report') report_file = op.join(report_dir, 'report.rst') fp = open(report_file, 'at') fp.writelines(write_rst_header('Subnode reports', level=1)) nitems = len(filename_to_list( getattr(self.inputs, self.iterfield[0]))) subnode_report_files = [] for i in range(nitems): nodename = '_' + self.name + str(i) subnode_report_files.insert(i, 'subnode %d' % i + ' : ' + op.join(cwd, 'mapflow', nodename, '_report', 'report.rst')) fp.writelines(write_rst_list(subnode_report_files)) fp.close() def get_subnodes(self): if not self._got_inputs: self._get_inputs() self._got_inputs = True self._check_iterfield() self.write_report(report_type='preexec', cwd=self.output_dir()) return [node for _, node in self._make_nodes()] def num_subnodes(self): if not self._got_inputs: self._get_inputs() self._got_inputs = True self._check_iterfield() if self._serial : return 1 else: if self.nested: return len(filename_to_list(flatten(getattr(self.inputs, self.iterfield[0])))) else: return len(filename_to_list(getattr(self.inputs, self.iterfield[0]))) def _get_inputs(self): old_inputs = self._inputs.get() self._inputs = self._create_dynamic_traits(self._interface.inputs, fields=self.iterfield) self._inputs.set(**old_inputs) super(MapNode, self)._get_inputs() def _check_iterfield(self): """Checks iterfield * iterfield must be in inputs * number of elements must match across iterfield """ for iterfield in self.iterfield: if not isdefined(getattr(self.inputs, iterfield)): raise ValueError(("Input %s was not set but it is listed " "in iterfields.") % iterfield) if len(self.iterfield) > 1: first_len = len(filename_to_list(getattr(self.inputs, self.iterfield[0]))) for iterfield in self.iterfield[1:]: if first_len != len(filename_to_list(getattr(self.inputs, iterfield))): raise ValueError(("All iterfields of a MapNode have to " "have the same length. %s") % str(self.inputs)) def _run_interface(self, execute=True, updatehash=False): """Run the mapnode interface This is primarily intended for serial execution of mapnode. A parallel execution requires creation of new nodes that can be spawned """ old_cwd = os.getcwd() cwd = self.output_dir() os.chdir(cwd) self._check_iterfield() if execute: if self.nested: nitems = len(filename_to_list(flatten(getattr(self.inputs, self.iterfield[0])))) else: nitems = len(filename_to_list(getattr(self.inputs, self.iterfield[0]))) nodenames = ['_' + self.name + str(i) for i in range(nitems)] # map-reduce formulation self._collate_results(self._node_runner(self._make_nodes(cwd), updatehash=updatehash)) self._save_results(self._result, cwd) # remove any node directories no longer required dirs2remove = [] for path in glob(op.join(cwd, 'mapflow', '*')): if op.isdir(path): if path.split(op.sep)[-1] not in nodenames: dirs2remove.append(path) for path in dirs2remove: shutil.rmtree(path) else: self._result = self._load_results(cwd) os.chdir(old_cwd) nipype-0.11.0/nipype/pipeline/plugins/000077500000000000000000000000001257611314500176745ustar00rootroot00000000000000nipype-0.11.0/nipype/pipeline/plugins/API.rst000066400000000000000000000002051257611314500210340ustar00rootroot00000000000000Execution plugin API ==================== Current status: class plugin_runner(PluginBase): def run(graph, config, updatehash) nipype-0.11.0/nipype/pipeline/plugins/__init__.py000066400000000000000000000011621257611314500220050ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from .debug import DebugPlugin from .linear import LinearPlugin from .ipythonx import IPythonXPlugin from .pbs import PBSPlugin from .sge import SGEPlugin from .condor import CondorPlugin from .dagman import CondorDAGManPlugin from .multiproc import MultiProcPlugin from .ipython import IPythonPlugin from .somaflow import SomaFlowPlugin from .pbsgraph import PBSGraphPlugin from .sgegraph import SGEGraphPlugin from .lsf import LSFPlugin from .slurm import SLURMPlugin from .slurmgraph import SLURMGraphPlugin nipype-0.11.0/nipype/pipeline/plugins/base.py000066400000000000000000000652371257611314500211750ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Common graph operations for execution """ from copy import deepcopy from glob import glob import os import getpass import shutil from socket import gethostname import sys from time import strftime, sleep, time from traceback import format_exception, format_exc from warnings import warn import numpy as np import scipy.sparse as ssp from ..utils import (nx, dfs_preorder, topological_sort) from ..engine import (MapNode, str2bool) from nipype.utils.filemanip import savepkl, loadpkl from ... import logging logger = logging.getLogger('workflow') iflogger = logging.getLogger('interface') def report_crash(node, traceback=None, hostname=None): """Writes crash related information to a file """ name = node._id if node.result and hasattr(node.result, 'runtime') and \ node.result.runtime: if isinstance(node.result.runtime, list): host = node.result.runtime[0].hostname else: host = node.result.runtime.hostname else: if hostname: host = hostname else: host = gethostname() message = ['Node %s failed to run on host %s.' % (name, host)] logger.error(message) if not traceback: exc_type, exc_value, exc_traceback = sys.exc_info() traceback = format_exception(exc_type, exc_value, exc_traceback) timeofcrash = strftime('%Y%m%d-%H%M%S') login_name = getpass.getuser() crashfile = 'crash-%s-%s-%s.pklz' % (timeofcrash, login_name, name) crashdir = node.config['execution']['crashdump_dir'] if crashdir is None: crashdir = os.getcwd() if not os.path.exists(crashdir): os.makedirs(crashdir) crashfile = os.path.join(crashdir, crashfile) logger.info('Saving crash info to %s' % crashfile) logger.info(''.join(traceback)) savepkl(crashfile, dict(node=node, traceback=traceback)) #np.savez(crashfile, node=node, traceback=traceback) return crashfile def report_nodes_not_run(notrun): """List nodes that crashed with crashfile info Optionally displays dependent nodes that weren't executed as a result of the crash. """ if notrun: logger.info("***********************************") for info in notrun: logger.error("could not run node: %s" % '.'.join((info['node']._hierarchy, info['node']._id))) logger.info("crashfile: %s" % info['crashfile']) logger.debug("The following dependent nodes were not run") for subnode in info['dependents']: logger.debug(subnode._id) logger.info("***********************************") raise RuntimeError(('Workflow did not execute cleanly. ' 'Check log for details')) def create_pyscript(node, updatehash=False, store_exception=True): # pickle node timestamp = strftime('%Y%m%d_%H%M%S') if node._hierarchy: suffix = '%s_%s_%s' % (timestamp, node._hierarchy, node._id) batch_dir = os.path.join(node.base_dir, node._hierarchy.split('.')[0], 'batch') else: suffix = '%s_%s' % (timestamp, node._id) batch_dir = os.path.join(node.base_dir, 'batch') if not os.path.exists(batch_dir): os.makedirs(batch_dir) pkl_file = os.path.join(batch_dir, 'node_%s.pklz' % suffix) savepkl(pkl_file, dict(node=node, updatehash=updatehash)) mpl_backend = node.config["execution"]["matplotlib_backend"] # create python script to load and trap exception cmdstr = """import os import sys can_import_matplotlib = True #Silently allow matplotlib to be ignored try: import matplotlib matplotlib.use('%s') except ImportError: can_import_matplotlib = False pass from nipype import config, logging from nipype.utils.filemanip import loadpkl, savepkl from socket import gethostname from traceback import format_exception info = None pklfile = '%s' batchdir = '%s' from nipype.utils.filemanip import loadpkl, savepkl try: if not sys.version_info < (2, 7): from collections import OrderedDict config_dict=%s config.update_config(config_dict) ## Only configure matplotlib if it was successfully imported, matplotlib is an optional component to nipype if can_import_matplotlib: config.update_matplotlib() logging.update_logging(config) traceback=None cwd = os.getcwd() info = loadpkl(pklfile) result = info['node'].run(updatehash=info['updatehash']) except Exception, e: etype, eval, etr = sys.exc_info() traceback = format_exception(etype,eval,etr) if info is None or not os.path.exists(info['node'].output_dir()): result = None resultsfile = os.path.join(batchdir, 'crashdump_%s.pklz') else: result = info['node'].result resultsfile = os.path.join(info['node'].output_dir(), 'result_%%s.pklz'%%info['node'].name) """ if store_exception: cmdstr += """ savepkl(resultsfile, dict(result=result, hostname=gethostname(), traceback=traceback)) """ else: cmdstr += """ if info is None: savepkl(resultsfile, dict(result=result, hostname=gethostname(), traceback=traceback)) else: from nipype.pipeline.plugins.base import report_crash report_crash(info['node'], traceback, gethostname()) raise Exception(e) """ cmdstr = cmdstr % (mpl_backend, pkl_file, batch_dir, node.config, suffix) pyscript = os.path.join(batch_dir, 'pyscript_%s.py' % suffix) fp = open(pyscript, 'wt') fp.writelines(cmdstr) fp.close() return pyscript class PluginBase(object): """Base class for plugins""" def __init__(self, plugin_args=None): if plugin_args and 'status_callback' in plugin_args: self._status_callback = plugin_args['status_callback'] else: self._status_callback = None return def run(self, graph, config, updatehash=False): raise NotImplementedError class DistributedPluginBase(PluginBase): """Execute workflow with a distribution engine """ def __init__(self, plugin_args=None): """Initialize runtime attributes to none procs: list (N) of underlying interface elements to be processed proc_done: a boolean vector (N) signifying whether a process has been executed proc_pending: a boolean vector (N) signifying whether a process is currently running. Note: A process is finished only when both proc_done==True and proc_pending==False depidx: a boolean matrix (NxN) storing the dependency structure accross processes. Process dependencies are derived from each column. """ super(DistributedPluginBase, self).__init__(plugin_args=plugin_args) self.procs = None self.depidx = None self.refidx = None self.mapnodes = None self.mapnodesubids = None self.proc_done = None self.proc_pending = None self.max_jobs = np.inf if plugin_args and 'max_jobs' in plugin_args: self.max_jobs = plugin_args['max_jobs'] def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline using distributed approaches """ logger.info("Running in parallel.") self._config = config # Generate appropriate structures for worker-manager model self._generate_dependency_list(graph) self.pending_tasks = [] self.readytorun = [] self.mapnodes = [] self.mapnodesubids = {} # setup polling - TODO: change to threaded model notrun = [] while np.any(self.proc_done == False) | \ np.any(self.proc_pending == True): toappend = [] # trigger callbacks for any pending results while self.pending_tasks: taskid, jobid = self.pending_tasks.pop() try: result = self._get_result(taskid) if result: if result['traceback']: notrun.append(self._clean_queue(jobid, graph, result=result)) else: self._task_finished_cb(jobid) self._remove_node_dirs() self._clear_task(taskid) else: toappend.insert(0, (taskid, jobid)) except Exception: result = {'result': None, 'traceback': format_exc()} notrun.append(self._clean_queue(jobid, graph, result=result)) if toappend: self.pending_tasks.extend(toappend) num_jobs = len(self.pending_tasks) logger.debug('Number of pending tasks: %d' % num_jobs) if num_jobs < self.max_jobs: self._send_procs_to_workers(updatehash=updatehash, graph=graph) else: logger.debug('Not submitting') sleep(float(self._config['execution']['poll_sleep_duration'])) self._remove_node_dirs() report_nodes_not_run(notrun) def _get_result(self, taskid): raise NotImplementedError def _submit_job(self, node, updatehash=False): raise NotImplementedError def _report_crash(self, node, result=None): raise NotImplementedError def _clear_task(self, taskid): raise NotImplementedError def _clean_queue(self, jobid, graph, result=None): if str2bool(self._config['execution']['stop_on_first_crash']): raise RuntimeError("".join(result['traceback'])) crashfile = self._report_crash(self.procs[jobid], result=result) if self._status_callback: self._status_callback(self.procs[jobid], 'exception') if jobid in self.mapnodesubids: # remove current jobid self.proc_pending[jobid] = False self.proc_done[jobid] = True # remove parent mapnode jobid = self.mapnodesubids[jobid] self.proc_pending[jobid] = False self.proc_done[jobid] = True # remove dependencies from queue return self._remove_node_deps(jobid, crashfile, graph) def _submit_mapnode(self, jobid): if jobid in self.mapnodes: return True self.mapnodes.append(jobid) mapnodesubids = self.procs[jobid].get_subnodes() numnodes = len(mapnodesubids) logger.info('Adding %d jobs for mapnode %s' % (numnodes, self.procs[jobid]._id)) for i in range(numnodes): self.mapnodesubids[self.depidx.shape[0] + i] = jobid self.procs.extend(mapnodesubids) self.depidx = ssp.vstack((self.depidx, ssp.lil_matrix(np.zeros( (numnodes, self.depidx.shape[1])))), 'lil') self.depidx = ssp.hstack((self.depidx, ssp.lil_matrix( np.zeros((self.depidx.shape[0], numnodes)))), 'lil') self.depidx[-numnodes:, jobid] = 1 self.proc_done = np.concatenate((self.proc_done, np.zeros(numnodes, dtype=bool))) self.proc_pending = np.concatenate((self.proc_pending, np.zeros(numnodes, dtype=bool))) return False def _send_procs_to_workers(self, updatehash=False, graph=None): """ Sends jobs to workers """ while np.any(self.proc_done == False): num_jobs = len(self.pending_tasks) if np.isinf(self.max_jobs): slots = None else: slots = max(0, self.max_jobs - num_jobs) logger.debug('Slots available: %s' % slots) if (num_jobs >= self.max_jobs) or (slots == 0): break # Check to see if a job is available jobids = np.flatnonzero((self.proc_done == False) & (self.depidx.sum(axis=0) == 0).__array__()) if len(jobids) > 0: # send all available jobs logger.info('Submitting %d jobs' % len(jobids[:slots])) for jobid in jobids[:slots]: if isinstance(self.procs[jobid], MapNode): try: num_subnodes = self.procs[jobid].num_subnodes() except Exception: self._clean_queue(jobid, graph) self.proc_pending[jobid] = False continue if num_subnodes > 1: submit = self._submit_mapnode(jobid) if not submit: continue # change job status in appropriate queues self.proc_done[jobid] = True self.proc_pending[jobid] = True # Send job to task manager and add to pending tasks logger.info('Executing: %s ID: %d' % (self.procs[jobid]._id, jobid)) if self._status_callback: self._status_callback(self.procs[jobid], 'start') continue_with_submission = True if str2bool(self.procs[jobid].config['execution'] ['local_hash_check']): logger.debug('checking hash locally') try: hash_exists, _, _, _ = self.procs[ jobid].hash_exists() logger.debug('Hash exists %s' % str(hash_exists)) if (hash_exists and (self.procs[jobid].overwrite == False or (self.procs[jobid].overwrite == None and not self.procs[jobid]._interface.always_run) ) ): continue_with_submission = False self._task_finished_cb(jobid) self._remove_node_dirs() except Exception: self._clean_queue(jobid, graph) self.proc_pending[jobid] = False continue_with_submission = False logger.debug('Finished checking hash %s' % str(continue_with_submission)) if continue_with_submission: if self.procs[jobid].run_without_submitting: logger.debug('Running node %s on master thread' % self.procs[jobid]) try: self.procs[jobid].run() except Exception: self._clean_queue(jobid, graph) self._task_finished_cb(jobid) self._remove_node_dirs() else: tid = self._submit_job(deepcopy(self.procs[jobid]), updatehash=updatehash) if tid is None: self.proc_done[jobid] = False self.proc_pending[jobid] = False else: self.pending_tasks.insert(0, (tid, jobid)) else: break def _task_finished_cb(self, jobid): """ Extract outputs and assign to inputs of dependent tasks This is called when a job is completed. """ logger.info('[Job finished] jobname: %s jobid: %d' % (self.procs[jobid]._id, jobid)) if self._status_callback: self._status_callback(self.procs[jobid], 'end') # Update job and worker queues self.proc_pending[jobid] = False # update the job dependency structure rowview = self.depidx.getrowview(jobid) rowview[rowview.nonzero()] = 0 if jobid not in self.mapnodesubids: self.refidx[self.refidx[:, jobid].nonzero()[0], jobid] = 0 def _generate_dependency_list(self, graph): """ Generates a dependency list for a list of graphs. """ self.procs, _ = topological_sort(graph) try: self.depidx = nx.to_scipy_sparse_matrix(graph, nodelist=self.procs, format='lil') except: self.depidx = nx.to_scipy_sparse_matrix(graph, nodelist=self.procs) self.refidx = deepcopy(self.depidx) self.refidx.astype = np.int self.proc_done = np.zeros(len(self.procs), dtype=bool) self.proc_pending = np.zeros(len(self.procs), dtype=bool) def _remove_node_deps(self, jobid, crashfile, graph): subnodes = [s for s in dfs_preorder(graph, self.procs[jobid])] for node in subnodes: idx = self.procs.index(node) self.proc_done[idx] = True self.proc_pending[idx] = False return dict(node=self.procs[jobid], dependents=subnodes, crashfile=crashfile) def _remove_node_dirs(self): """Removes directories whose outputs have already been used up """ if str2bool(self._config['execution']['remove_node_directories']): for idx in np.nonzero( (self.refidx.sum(axis=1) == 0).__array__())[0]: if idx in self.mapnodesubids: continue if self.proc_done[idx] and (not self.proc_pending[idx]): self.refidx[idx, idx] = -1 outdir = self.procs[idx]._output_directory() logger.info(('[node dependencies finished] ' 'removing node: %s from directory %s') % (self.procs[idx]._id, outdir)) shutil.rmtree(outdir) class SGELikeBatchManagerBase(DistributedPluginBase): """Execute workflow with SGE/OGE/PBS like batch system """ def __init__(self, template, plugin_args=None): super(SGELikeBatchManagerBase, self).__init__(plugin_args=plugin_args) self._template = template self._qsub_args = None if plugin_args: if 'template' in plugin_args: self._template = plugin_args['template'] if os.path.isfile(self._template): self._template = open(self._template).read() if 'qsub_args' in plugin_args: self._qsub_args = plugin_args['qsub_args'] self._pending = {} def _is_pending(self, taskid): """Check if a task is pending in the batch system """ raise NotImplementedError def _submit_batchtask(self, scriptfile, node): """Submit a task to the batch system """ raise NotImplementedError def _get_result(self, taskid): if taskid not in self._pending: raise Exception('Task %d not found' % taskid) if self._is_pending(taskid): return None node_dir = self._pending[taskid] # MIT HACK # on the pbs system at mit the parent node directory needs to be # accessed before internal directories become available. there # is a disconnect when the queueing engine knows a job is # finished to when the directories become statable. t = time() timeout = float(self._config['execution']['job_finished_timeout']) timed_out = True while (time() - t) < timeout: try: logger.debug(os.listdir(os.path.realpath(os.path.join(node_dir, '..')))) logger.debug(os.listdir(node_dir)) glob(os.path.join(node_dir, 'result_*.pklz')).pop() timed_out = False break except Exception, e: logger.debug(e) sleep(2) if timed_out: result_data = {'hostname': 'unknown', 'result': None, 'traceback': None} results_file = None try: error_message = ('Job id ({0}) finished or terminated, but ' 'results file does not exist after ({1}) ' 'seconds. Batch dir contains crashdump file ' 'if node raised an exception.\n' 'Node working directory: ({2}) '.format( taskid,timeout,node_dir) ) raise IOError(error_message) except IOError, e: result_data['traceback'] = format_exc() else: results_file = glob(os.path.join(node_dir, 'result_*.pklz'))[0] result_data = loadpkl(results_file) result_out = dict(result=None, traceback=None) if isinstance(result_data, dict): result_out['result'] = result_data['result'] result_out['traceback'] = result_data['traceback'] result_out['hostname'] = result_data['hostname'] if results_file: crash_file = os.path.join(node_dir, 'crashstore.pklz') os.rename(results_file, crash_file) else: result_out['result'] = result_data return result_out def _submit_job(self, node, updatehash=False): """submit job and return taskid """ pyscript = create_pyscript(node, updatehash=updatehash) batch_dir, name = os.path.split(pyscript) name = '.'.join(name.split('.')[:-1]) batchscript = '\n'.join((self._template, '%s %s' % (sys.executable, pyscript))) batchscriptfile = os.path.join(batch_dir, 'batchscript_%s.sh' % name) fp = open(batchscriptfile, 'wt') fp.writelines(batchscript) fp.close() return self._submit_batchtask(batchscriptfile, node) def _report_crash(self, node, result=None): if result and result['traceback']: node._result = result['result'] node._traceback = result['traceback'] return report_crash(node, traceback=result['traceback']) else: return report_crash(node) def _clear_task(self, taskid): del self._pending[taskid] class GraphPluginBase(PluginBase): """Base class for plugins that distribute graphs to workflows """ def __init__(self, plugin_args=None): if plugin_args and 'status_callback' in plugin_args: warn('status_callback not supported for Graph submission plugins') super(GraphPluginBase, self).__init__(plugin_args=plugin_args) def run(self, graph, config, updatehash=False): pyfiles = [] dependencies = {} self._config = config nodes = nx.topological_sort(graph) logger.debug('Creating executable python files for each node') for idx, node in enumerate(nodes): pyfiles.append(create_pyscript(node, updatehash=updatehash, store_exception=False)) dependencies[idx] = [nodes.index(prevnode) for prevnode in graph.predecessors(node)] self._submit_graph(pyfiles, dependencies, nodes) def _get_args(self, node, keywords): values = () for keyword in keywords: value = getattr(self, "_" + keyword) if keyword == "template" and os.path.isfile(value): value = open(value).read() if (hasattr(node, "plugin_args") and isinstance(node.plugin_args, dict) and keyword in node.plugin_args): if (keyword == "template" and os.path.isfile(node.plugin_args[keyword])): tmp_value = open(node.plugin_args[keyword]).read() else: tmp_value = node.plugin_args[keyword] if ('overwrite' in node.plugin_args and node.plugin_args['overwrite']): value = tmp_value else: value += tmp_value values += (value, ) return values def _submit_graph(self, pyfiles, dependencies, nodes): """ pyfiles: list of files corresponding to a topological sort dependencies: dictionary of dependencies based on the toplogical sort """ raise NotImplementedError def _get_result(self, taskid): if taskid not in self._pending: raise Exception('Task %d not found' % taskid) if self._is_pending(taskid): return None node_dir = self._pending[taskid] logger.debug(os.listdir(os.path.realpath(os.path.join(node_dir, '..')))) logger.debug(os.listdir(node_dir)) glob(os.path.join(node_dir, 'result_*.pklz')).pop() results_file = glob(os.path.join(node_dir, 'result_*.pklz'))[0] result_data = loadpkl(results_file) result_out = dict(result=None, traceback=None) if isinstance(result_data, dict): result_out['result'] = result_data['result'] result_out['traceback'] = result_data['traceback'] result_out['hostname'] = result_data['hostname'] if results_file: crash_file = os.path.join(node_dir, 'crashstore.pklz') os.rename(results_file, crash_file) else: result_out['result'] = result_data return result_out nipype-0.11.0/nipype/pipeline/plugins/condor.py000066400000000000000000000107571257611314500215440ustar00rootroot00000000000000"""Parallel workflow execution via Condor """ import os from .base import (SGELikeBatchManagerBase, logger, iflogger, logging) from nipype.interfaces.base import CommandLine from time import sleep class CondorPlugin(SGELikeBatchManagerBase): """Execute using Condor This plugin doesn't work with a plain stock-Condor installation, but requires a 'qsub' emulation script for Condor, called 'condor_qsub'. This script is shipped with the Condor package from NeuroDebian, or can be downloaded from its Git repository at http://anonscm.debian.org/gitweb/?p=pkg-exppsy/condor.git;a=blob_plain;f=debian/condor_qsub;hb=HEAD The plugin_args input to run can be used to control the Condor execution. Currently supported options are: - template : template to use for batch job submission. This can be an SGE-style script with the (limited) set of options supported by condor_qsub - qsub_args : arguments to be prepended to the job execution script in the qsub call """ def __init__(self, **kwargs): template = """ #$ -V #$ -S /bin/sh """ self._retry_timeout = 2 self._max_tries = 2 if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] super(CondorPlugin, self).__init__(template, **kwargs) def _is_pending(self, taskid): cmd = CommandLine('condor_q', terminal_output='allatonce') cmd.inputs.args = '%d' % taskid # check condor cluster oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) result = cmd.run(ignore_exception=True) iflogger.setLevel(oldlevel) if result.runtime.stdout.count('\n%d' % taskid): return True return False def _submit_batchtask(self, scriptfile, node): cmd = CommandLine('condor_qsub', environ=os.environ.data, terminal_output='allatonce') path = os.path.dirname(scriptfile) qsubargs = '' if self._qsub_args: qsubargs = self._qsub_args if 'qsub_args' in node.plugin_args: if 'overwrite' in node.plugin_args and\ node.plugin_args['overwrite']: qsubargs = node.plugin_args['qsub_args'] else: qsubargs += (" " + node.plugin_args['qsub_args']) if self._qsub_args: qsubargs = self._qsub_args if '-o' not in qsubargs: qsubargs = '%s -o %s' % (qsubargs, path) if '-e' not in qsubargs: qsubargs = '%s -e %s' % (qsubargs, path) if node._hierarchy: jobname = '.'.join((os.environ.data['LOGNAME'], node._hierarchy, node._id)) else: jobname = '.'.join((os.environ.data['LOGNAME'], node._id)) jobnameitems = jobname.split('.') jobnameitems.reverse() jobname = '.'.join(jobnameitems) cmd.inputs.args = '%s -N %s %s' % (qsubargs, jobname, scriptfile) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) tries = 0 while True: try: result = cmd.run() except Exception, e: if tries < self._max_tries: tries += 1 sleep(self._retry_timeout) # sleep 2 seconds and try again. else: iflogger.setLevel(oldlevel) raise RuntimeError('\n'.join((('Could not submit condor ' 'cluster' ' for node %s') % node._id, str(e)))) else: break iflogger.setLevel(oldlevel) # retrieve condor clusterid taskid = int(result.runtime.stdout.split(' ')[2]) self._pending[taskid] = node.output_dir() logger.debug('submitted condor cluster: %d for node %s' % (taskid, node._id)) return taskid nipype-0.11.0/nipype/pipeline/plugins/dagman.py000066400000000000000000000172161257611314500215040ustar00rootroot00000000000000"""Parallel workflow execution via Condor DAGMan """ import os import sys import uuid import time from warnings import warn from .base import (GraphPluginBase, logger) from ...interfaces.base import CommandLine class CondorDAGManPlugin(GraphPluginBase): """Execute using Condor DAGMan The plugin_args input to run can be used to control the DAGMan execution. The value of most arguments can be a literal string or a filename, where in the latter case the content of the file will be used as the argument value. Currently supported options are: - submit_template : submit spec template for individual jobs in a DAG (see CondorDAGManPlugin.default_submit_template for the default. - initial_specs : additional submit specs that are prepended to any job's submit file - override_specs : additional submit specs that are appended to any job's submit file - wrapper_cmd : path to an executable that will be started instead of a node script. This is useful for wrapper script that execute certain functionality prior or after a node runs. If this option is given the wrapper command is called with the respective Python executable and the path to the node script as final arguments - wrapper_args : optional additional arguments to a wrapper command - dagman_args : arguments to be prepended to the arguments of the condor_submit_dag call - block : if True the plugin call will block until Condor has finished processing the entire workflow (default: False) """ default_submit_template = """ universe = vanilla notification = Never executable = %(executable)s arguments = %(nodescript)s output = %(basename)s.out error = %(basename)s.err log = %(basename)s.log getenv = True """ def _get_str_or_file(self, arg): if os.path.isfile(arg): content = open(arg).read() else: content = arg return content # XXX feature wishlist # - infer data file dependencies from jobs # - infer CPU requirements from jobs # - infer memory requirements from jobs # - looks like right now all jobs come in here, regardless of whether they # actually have to run. would be good to be able to decide whether they # actually have to be scheduled (i.e. output already exist). def __init__(self, **kwargs): for var, id_, val in \ (('_template', 'submit_template', self.default_submit_template), ('_initial_specs', 'template', ''), ('_initial_specs', 'initial_specs', ''), ('_override_specs', 'submit_specs', ''), ('_override_specs', 'override_specs', ''), ('_wrapper_cmd', 'wrapper_cmd', None), ('_wrapper_args', 'wrapper_args', ''), ('_block', 'block', False), ('_dagman_args', 'dagman_args', '')): if 'plugin_args' in kwargs \ and not kwargs['plugin_args'] is None \ and id_ in kwargs['plugin_args']: if id_ == 'wrapper_cmd': val = os.path.abspath(kwargs['plugin_args'][id_]) elif id_ == 'block': val = kwargs['plugin_args'][id_] else: val = self._get_str_or_file(kwargs['plugin_args'][id_]) setattr(self, var, val) # TODO remove after some time if 'plugin_args' in kwargs \ and not kwargs['plugin_args'] is None: plugin_args = kwargs['plugin_args'] if 'template' in plugin_args: warn("the 'template' argument is deprecated, use 'initial_specs' instead") if 'submit_specs' in plugin_args: warn("the 'submit_specs' argument is deprecated, use 'override_specs' instead") super(CondorDAGManPlugin, self).__init__(**kwargs) def _submit_graph(self, pyfiles, dependencies, nodes): # location of all scripts, place dagman output in here too batch_dir, _ = os.path.split(pyfiles[0]) # DAG description filename dagfilename = os.path.join(batch_dir, 'workflow-%s.dag' % uuid.uuid4()) with open(dagfilename, 'wt') as dagfileptr: # loop over all scripts, create submit files, and define them # as jobs in the DAG for idx, pyscript in enumerate(pyfiles): node = nodes[idx] # XXX redundant with previous value? or could it change between # scripts? template, initial_specs, override_specs, wrapper_cmd, wrapper_args = \ self._get_args(node, ["template", "initial_specs", "override_specs", "wrapper_cmd", "wrapper_args"]) # add required slots to the template template = '%s\n%s\n%s\nqueue\n' % ( '%(initial_specs)s', template, '%(override_specs)s') batch_dir, name = os.path.split(pyscript) name = '.'.join(name.split('.')[:-1]) specs = dict( # TODO make parameter for this, initial_specs=initial_specs, executable=sys.executable, nodescript=pyscript, basename=os.path.join(batch_dir, name), override_specs=override_specs ) if not wrapper_cmd is None: specs['executable'] = wrapper_cmd specs['nodescript'] = \ '%s %s %s' % (wrapper_args % specs, # give access to variables sys.executable, pyscript) submitspec = template % specs # write submit spec for this job submitfile = os.path.join(batch_dir, '%s.submit' % name) with open(submitfile, 'wt') as submitfileprt: submitfileprt.writelines(submitspec) submitfileprt.close() # define job in DAG dagfileptr.write('JOB %i %s\n' % (idx, submitfile)) # define dependencies in DAG for child in dependencies: parents = dependencies[child] if len(parents): dagfileptr.write('PARENT %s CHILD %i\n' % (' '.join([str(i) for i in parents]), child)) # hand over DAG to condor_dagman cmd = CommandLine('condor_submit_dag', environ=os.environ.data, terminal_output='allatonce') # needs -update_submit or re-running a workflow will fail cmd.inputs.args = '%s -update_submit %s' % (self._dagman_args, dagfilename) cmd.run() logger.info('submitted all jobs to Condor DAGMan') if self._block: # wait for DAGMan to settle down, no time wasted it is already running time.sleep(10) if not os.path.exists('%s.condor.sub' % dagfilename): raise EnvironmentError("DAGMan did not create its submit file, please check the logs") # wait for completion logger.info('waiting for DAGMan to finish') lockfilename = '%s.lock' % dagfilename while os.path.exists(lockfilename): time.sleep(5) nipype-0.11.0/nipype/pipeline/plugins/debug.py000066400000000000000000000021621257611314500213350ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Debug plugin """ from .base import (PluginBase, logger) from ..utils import (nx) class DebugPlugin(PluginBase): """Execute workflow in series """ def __init__(self, plugin_args=None): super(DebugPlugin, self).__init__(plugin_args=plugin_args) if plugin_args and "callable" in plugin_args and \ hasattr(plugin_args['callable'], '__call__'): self._callable = plugin_args['callable'] else: raise ValueError('plugin_args must contain a callable function') def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline in a serial order. Parameters ---------- graph : networkx digraph defines order of execution """ if not isinstance(graph, nx.DiGraph): raise ValueError('Input must be a networkx digraph object') logger.info("Executing debug plugin") for node in nx.topological_sort(graph): self._callable(node, graph) nipype-0.11.0/nipype/pipeline/plugins/ipython.py000066400000000000000000000077541257611314500217550ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Parallel workflow execution via IPython controller """ from cPickle import dumps import sys IPython_not_loaded = False try: from IPython import __version__ as IPyversion from IPython.parallel.error import TimeoutError except: IPython_not_loaded = True from .base import (DistributedPluginBase, logger, report_crash) def execute_task(pckld_task, node_config, updatehash): from socket import gethostname from traceback import format_exc from nipype import config, logging traceback=None result=None import os cwd = os.getcwd() try: config.update_config(node_config) logging.update_logging(config) from cPickle import loads task = loads(pckld_task) result = task.run(updatehash=updatehash) except: traceback = format_exc() result = task.result os.chdir(cwd) return result, traceback, gethostname() class IPythonPlugin(DistributedPluginBase): """Execute workflow with ipython """ def __init__(self, plugin_args=None): if IPython_not_loaded: raise ImportError('IPython parallel could not be imported') super(IPythonPlugin, self).__init__(plugin_args=plugin_args) self.iparallel = None self.taskclient = None self.taskmap = {} self._taskid = 0 def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline is distributed approaches based on IPython's parallel processing interface """ # retrieve clients again try: name = 'IPython.parallel' __import__(name) self.iparallel = sys.modules[name] except ImportError: raise ImportError("Ipython kernel not found. Parallel execution " \ "will be unavailable") try: self.taskclient = self.iparallel.Client() except Exception, e: if isinstance(e, TimeoutError): raise Exception("No IPython clients found.") if isinstance(e, IOError): raise Exception("ipcluster/ipcontroller has not been started") if isinstance(e, ValueError): raise Exception("Ipython kernel not installed") raise e return super(IPythonPlugin, self).run(graph, config, updatehash=updatehash) def _get_result(self, taskid): if taskid not in self.taskmap: raise ValueError('Task %d not in pending list' % taskid) if self.taskmap[taskid].ready(): result, traceback, hostname = self.taskmap[taskid].get() result_out = dict(result=None, traceback=None) result_out['result'] = result result_out['traceback'] = traceback result_out['hostname'] = hostname return result_out else: return None def _submit_job(self, node, updatehash=False): pckld_node = dumps(node, 2) result_object = self.taskclient.load_balanced_view().apply(execute_task, pckld_node, node.config, updatehash) self._taskid += 1 self.taskmap[self._taskid] = result_object return self._taskid def _report_crash(self, node, result=None): if result and result['traceback']: node._result = result['result'] node._traceback = result['traceback'] return report_crash(node, traceback=result['traceback']) else: return report_crash(node) def _clear_task(self, taskid): if IPyversion >= '0.11': logger.debug("Clearing id: %d"%taskid) self.taskclient.purge_results(self.taskmap[taskid]) del self.taskmap[taskid] nipype-0.11.0/nipype/pipeline/plugins/ipythonx.py000066400000000000000000000056351257611314500221410ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Parallel workflow execution via IPython controller """ import sys IPython_not_loaded = False try: from IPython import __version__ as IPyversion from IPython.kernel.contexts import ConnectionRefusedError except: IPython_not_loaded = True from .base import (DistributedPluginBase, logger, report_crash) class IPythonXPlugin(DistributedPluginBase): """Execute workflow with ipython """ def __init__(self, plugin_args=None): if IPython_not_loaded: raise ImportError('IPython parallel could not be imported') super(IPythonXPlugin, self).__init__(plugin_args=plugin_args) self.ipyclient = None self.taskclient = None def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline is distributed approaches based on IPython's parallel processing interface """ # retrieve clients again try: name = 'IPython.kernel.client' __import__(name) self.ipyclient = sys.modules[name] except ImportError: raise ImportError("Ipython kernel not found. Parallel execution " \ "will be unavailable") try: self.taskclient = self.ipyclient.TaskClient() except Exception, e: if isinstance(e, ConnectionRefusedError): raise Exception("No IPython clients found.") if isinstance(e, ValueError): raise Exception("Ipython kernel not installed") return super(IPythonXPlugin, self).run(graph, config, updatehash=updatehash) def _get_result(self, taskid): return self.taskclient.get_task_result(taskid, block=False) def _submit_job(self, node, updatehash=False): cmdstr = """import sys from traceback import format_exception traceback=None result=None try: result = task.run(updatehash=updatehash) except: etype, eval, etr = sys.exc_info() traceback = format_exception(etype,eval,etr) result = task.result """ task = self.ipyclient.StringTask(cmdstr, push = dict(task=node, updatehash=updatehash), pull = ['result','traceback']) return self.taskclient.run(task, block = False) def _report_crash(self, node, result=None): if result and result['traceback']: node._result = result['result'] node._traceback = result['traceback'] return report_crash(node, traceback=result['traceback']) else: return report_crash(node) def _clear_task(self, taskid): if IPyversion >= '0.10.1': logger.debug("Clearing id: %d"%taskid) self.taskclient.clear(taskid) nipype-0.11.0/nipype/pipeline/plugins/linear.py000066400000000000000000000037531257611314500215300ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Local serial workflow execution """ import os from .base import (PluginBase, logger, report_crash, report_nodes_not_run, str2bool) from ..utils import (nx, dfs_preorder, topological_sort) class LinearPlugin(PluginBase): """Execute workflow in series """ def run(self, graph, config, updatehash=False): """Executes a pre-defined pipeline in a serial order. Parameters ---------- graph : networkx digraph defines order of execution """ if not isinstance(graph, nx.DiGraph): raise ValueError('Input must be a networkx digraph object') logger.info("Running serially.") old_wd = os.getcwd() notrun = [] donotrun = [] nodes, _ = topological_sort(graph) for node in nodes: try: if node in donotrun: continue if self._status_callback: self._status_callback(node, 'start') node.run(updatehash=updatehash) if self._status_callback: self._status_callback(node, 'end') except: os.chdir(old_wd) if str2bool(config['execution']['stop_on_first_crash']): raise # bare except, but i really don't know where a # node might fail crashfile = report_crash(node) # remove dependencies from queue subnodes = [s for s in dfs_preorder(graph, node)] notrun.append(dict(node = node, dependents = subnodes, crashfile = crashfile)) donotrun.extend(subnodes) if self._status_callback: self._status_callback(node, 'exception') report_nodes_not_run(notrun) nipype-0.11.0/nipype/pipeline/plugins/lsf.py000066400000000000000000000113221257611314500210310ustar00rootroot00000000000000"""Parallel workflow execution via LSF """ import os from .base import (SGELikeBatchManagerBase, logger, iflogger, logging) from nipype.interfaces.base import CommandLine from time import sleep import re class LSFPlugin(SGELikeBatchManagerBase): """Execute using LSF Cluster Submission The plugin_args input to run can be used to control the LSF execution. Currently supported options are: - template : template to use for batch job submission - bsub_args : arguments to be prepended to the job execution script in the bsub call """ def __init__(self, **kwargs): template = """ #$ -S /bin/sh """ self._retry_timeout = 2 self._max_tries = 2 self._bsub_args = '' if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] if 'bsub_args' in kwargs['plugin_args']: self._bsub_args = kwargs['plugin_args']['bsub_args'] super(LSFPlugin, self).__init__(template, **kwargs) def _is_pending(self, taskid): """LSF lists a status of 'PEND' when a job has been submitted but is waiting to be picked up, and 'RUN' when it is actively being processed. But _is_pending should return True until a job has finished and is ready to be checked for completeness. So return True if status is either 'PEND' or 'RUN'""" cmd = CommandLine('bjobs', terminal_output='allatonce') cmd.inputs.args = '%d' % taskid # check lsf task oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) result = cmd.run(ignore_exception=True) iflogger.setLevel(oldlevel) # logger.debug(result.runtime.stdout) if 'DONE' in result.runtime.stdout or 'EXIT' in result.runtime.stdout: return False else: return True def _submit_batchtask(self, scriptfile, node): cmd = CommandLine('bsub', environ=os.environ.data, terminal_output='allatonce') path = os.path.dirname(scriptfile) bsubargs = '' if self._bsub_args: bsubargs = self._bsub_args if 'bsub_args' in node.plugin_args: if 'overwrite' in node.plugin_args and\ node.plugin_args['overwrite']: bsubargs = node.plugin_args['bsub_args'] else: bsubargs += (" " + node.plugin_args['bsub_args']) if '-o' not in bsubargs: # -o outfile bsubargs = '%s -o %s' % (bsubargs, scriptfile + ".log") if '-e' not in bsubargs: bsubargs = '%s -e %s' % (bsubargs, scriptfile + ".log") # -e error file if node._hierarchy: jobname = '.'.join((os.environ.data['LOGNAME'], node._hierarchy, node._id)) else: jobname = '.'.join((os.environ.data['LOGNAME'], node._id)) jobnameitems = jobname.split('.') jobnameitems.reverse() jobname = '.'.join(jobnameitems) cmd.inputs.args = '%s -J %s sh %s' % (bsubargs, jobname, scriptfile) # -J job_name_spec logger.debug('bsub ' + cmd.inputs.args) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) tries = 0 while True: try: result = cmd.run() except Exception, e: if tries < self._max_tries: tries += 1 sleep( self._retry_timeout) # sleep 2 seconds and try again. else: iflogger.setLevel(oldlevel) raise RuntimeError('\n'.join((('Could not submit lsf task' ' for node %s') % node._id, str(e)))) else: break iflogger.setLevel(oldlevel) # retrieve lsf taskid match = re.search('<(\d*)>', result.runtime.stdout) if match: taskid = int(match.groups()[0]) else: raise ScriptError("Can't parse submission job output id: %s" % result.runtime.stdout) self._pending[taskid] = node.output_dir() logger.debug('submitted lsf task: %d for node %s' % (taskid, node._id)) return taskid nipype-0.11.0/nipype/pipeline/plugins/multiproc.py000066400000000000000000000063251257611314500222720ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Parallel workflow execution via multiprocessing Support for child processes running as non-daemons based on http://stackoverflow.com/a/8963618/1183453 """ from multiprocessing import Process, Pool, cpu_count, pool from traceback import format_exception import sys from .base import (DistributedPluginBase, report_crash) def run_node(node, updatehash): result = dict(result=None, traceback=None) try: result['result'] = node.run(updatehash=updatehash) except: etype, eval, etr = sys.exc_info() result['traceback'] = format_exception(etype,eval,etr) result['result'] = node.result return result class NonDaemonProcess(Process): """A non-daemon process to support internal multiprocessing. """ def _get_daemon(self): return False def _set_daemon(self, value): pass daemon = property(_get_daemon, _set_daemon) class NonDaemonPool(pool.Pool): """A process pool with non-daemon processes. """ Process = NonDaemonProcess class MultiProcPlugin(DistributedPluginBase): """Execute workflow with multiprocessing The plugin_args input to run can be used to control the multiprocessing execution. Currently supported options are: - n_procs : number of processes to use - non_daemon : boolean flag to execute as non-daemon processes """ def __init__(self, plugin_args=None): super(MultiProcPlugin, self).__init__(plugin_args=plugin_args) self._taskresult = {} self._taskid = 0 non_daemon = True n_procs = cpu_count() if plugin_args: if 'n_procs' in plugin_args: n_procs = plugin_args['n_procs'] if 'non_daemon' in plugin_args: non_daemon = plugin_args['non_daemon'] if non_daemon: # run the execution using the non-daemon pool subclass self.pool = NonDaemonPool(processes=n_procs) else: self.pool = Pool(processes=n_procs) def _get_result(self, taskid): if taskid not in self._taskresult: raise RuntimeError('Multiproc task %d not found'%taskid) if not self._taskresult[taskid].ready(): return None return self._taskresult[taskid].get() def _submit_job(self, node, updatehash=False): self._taskid += 1 try: if node.inputs.terminal_output == 'stream': node.inputs.terminal_output = 'allatonce' except: pass self._taskresult[self._taskid] = self.pool.apply_async(run_node, (node, updatehash,)) return self._taskid def _report_crash(self, node, result=None): if result and result['traceback']: node._result = result['result'] node._traceback = result['traceback'] return report_crash(node, traceback=result['traceback']) else: return report_crash(node) def _clear_task(self, taskid): del self._taskresult[taskid] nipype-0.11.0/nipype/pipeline/plugins/pbs.py000066400000000000000000000100511257611314500210270ustar00rootroot00000000000000"""Parallel workflow execution via PBS/Torque """ import os from time import sleep import subprocess from .base import (SGELikeBatchManagerBase, logger, iflogger, logging) from nipype.interfaces.base import CommandLine class PBSPlugin(SGELikeBatchManagerBase): """Execute using PBS/Torque The plugin_args input to run can be used to control the SGE execution. Currently supported options are: - template : template to use for batch job submission - qsub_args : arguments to be prepended to the job execution script in the qsub call - max_jobname_len: maximum length of the job name. Default 15. """ # Addtional class variables _max_jobname_len = 15 def __init__(self, **kwargs): template = """ #PBS -V """ self._retry_timeout = 2 self._max_tries = 2 self._max_jobname_length = 15 if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] if 'max_jobname_len' in kwargs['plugin_args']: self._max_jobname_len = kwargs['plugin_args']['max_jobname_len'] super(PBSPlugin, self).__init__(template, **kwargs) def _is_pending(self, taskid): # subprocess.Popen requires taskid to be a string proc = subprocess.Popen(["qstat", str(taskid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, e = proc.communicate() errmsg = 'Unknown Job Id' # %s' % taskid return errmsg not in e def _submit_batchtask(self, scriptfile, node): cmd = CommandLine('qsub', environ=os.environ.data, terminal_output='allatonce') path = os.path.dirname(scriptfile) qsubargs = '' if self._qsub_args: qsubargs = self._qsub_args if 'qsub_args' in node.plugin_args: if 'overwrite' in node.plugin_args and \ node.plugin_args['overwrite']: qsubargs = node.plugin_args['qsub_args'] else: qsubargs += (" " + node.plugin_args['qsub_args']) if '-o' not in qsubargs: qsubargs = '%s -o %s' % (qsubargs, path) if '-e' not in qsubargs: qsubargs = '%s -e %s' % (qsubargs, path) if node._hierarchy: jobname = '.'.join((os.environ.data['LOGNAME'], node._hierarchy, node._id)) else: jobname = '.'.join((os.environ.data['LOGNAME'], node._id)) jobnameitems = jobname.split('.') jobnameitems.reverse() jobname = '.'.join(jobnameitems) jobname = jobname[0:self._max_jobname_len] cmd.inputs.args = '%s -N %s %s' % (qsubargs, jobname, scriptfile) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) tries = 0 while True: try: result = cmd.run() except Exception, e: if tries < self._max_tries: tries += 1 sleep(self._retry_timeout) # sleep 2 seconds and try again. else: iflogger.setLevel(oldlevel) raise RuntimeError('\n'.join((('Could not submit pbs task' ' for node %s') % node._id, str(e)))) else: break iflogger.setLevel(oldlevel) # retrieve pbs taskid taskid = result.runtime.stdout.split('.')[0] self._pending[taskid] = node.output_dir() logger.debug('submitted pbs task: %s for node %s' % (taskid, node._id)) return taskid nipype-0.11.0/nipype/pipeline/plugins/pbsgraph.py000066400000000000000000000044201257611314500220540ustar00rootroot00000000000000"""Parallel workflow execution via PBS/Torque """ import os import sys from .base import (GraphPluginBase, logger) from ...interfaces.base import CommandLine from .sgegraph import SGEGraphPlugin class PBSGraphPlugin(SGEGraphPlugin): """Execute using PBS/Torque The plugin_args input to run can be used to control the SGE execution. Currently supported options are: - template : template to use for batch job submission - qsub_args : arguments to be prepended to the job execution script in the qsub call """ _template = """ #PBS -V """ def _submit_graph(self, pyfiles, dependencies, nodes): batch_dir, _ = os.path.split(pyfiles[0]) submitjobsfile = os.path.join(batch_dir, 'submit_jobs.sh') with open(submitjobsfile, 'wt') as fp: fp.writelines('#!/usr/bin/env sh\n') for idx, pyscript in enumerate(pyfiles): node = nodes[idx] template, qsub_args = self._get_args( node, ["template", "qsub_args"]) batch_dir, name = os.path.split(pyscript) name = '.'.join(name.split('.')[:-1]) batchscript = '\n'.join((template, '%s %s' % (sys.executable, pyscript))) batchscriptfile = os.path.join(batch_dir, 'batchscript_%s.sh' % name) with open(batchscriptfile, 'wt') as batchfp: batchfp.writelines(batchscript) batchfp.close() deps = '' if idx in dependencies: values = ['$job%05d' % jobid for jobid in dependencies[idx]] if len(values): deps = '-W depend=afterok:%s' % ':'.join(values) fp.writelines('job%05d=`qsub %s %s %s`\n' % (idx, deps, qsub_args, batchscriptfile)) cmd = CommandLine('sh', environ=os.environ.data, terminal_output='allatonce') cmd.inputs.args = '%s' % submitjobsfile cmd.run() logger.info('submitted all jobs to queue') nipype-0.11.0/nipype/pipeline/plugins/sge.py000066400000000000000000000437011257611314500210310ustar00rootroot00000000000000"""Parallel workflow execution via SGE """ import os import pwd import re import subprocess import time import xml.dom.minidom import random from .base import (SGELikeBatchManagerBase, logger, iflogger, logging) from nipype.interfaces.base import CommandLine DEBUGGING_PREFIX = str(int(random.uniform(100, 999))) def sge_debug_print(message): """ Needed for debugging on big jobs. Once this is fully vetted, it can be removed. """ logger.debug(DEBUGGING_PREFIX + " " + "=!" * 3 + " " + message) # print DEBUGGING_PREFIX + " " + "=!" * 3 + " " + message class QJobInfo: """Information about a single job created by OGE/SGE or similar Each job is responsible for knowing it's own refresh state :author Hans J. Johnson """ def __init__(self, job_num, job_queue_state, job_time, job_queue_name, job_slots, qsub_command_line): # self._jobName = None # Ascii text name of job not unique self._job_num = int( job_num) # The primary unique identifier for this job, must be an integer! # self._jobOwn = None # Who owns this job self._job_queue_state = str( job_queue_state) # ["running","zombie",...??] # self._jobActionState = str(jobActionState) # ['r','qw','S',...??] self._job_time = job_time # The job start time self._job_info_creation_time = time.time( ) # When this job was created (for comparing against initalization) self._job_queue_name = job_queue_name # Where the job is running self._job_slots = job_slots # How many slots are being used self._qsub_command_line = qsub_command_line def __repr__(self): return str(self._job_num).ljust(8) \ + str(self._job_queue_state).ljust(12) \ + str(self._job_slots).ljust(3) \ + time.strftime("%Y-%m-%dT%H:%M:%S", time.gmtime(self._job_time)).ljust(20) \ + str(self._job_queue_name).ljust(8) \ + str(self._qsub_command_line) def is_initializing(self): return self._job_queue_state == "initializing" def is_zombie(self): return self._job_queue_state == "zombie" def is_running(self): return self._job_queue_state == "running" def is_pending(self): return self._job_queue_state == "pending" def is_job_state_pending(self): """ Return True, unless job is in the "zombie" status """ time_diff = (time.time() - self._job_info_creation_time) if self.is_zombie(): sge_debug_print( "DONE! QJobInfo.IsPending found in 'zombie' list, returning False so claiming done!\n{0}".format(self)) is_pending_status = False # Job explicitly found as being completed! elif self.is_initializing() and (time_diff > 600): # if initializing for more than 5 minute, failure due to # initialization and completion before registration sge_debug_print( "FAILURE! QJobInfo.IsPending found long running at {1} seconds" "'initializing' returning False for to break loop!\n{0}".format(self, time_diff)) is_pending_status = True # Job initialization took too long, so report! else: # self.is_running() || self.is_pending(): is_pending_status = True # Job cache last listed as running return is_pending_status # The job is in one of the hold states def update_info(self, job_queue_state, job_time, job_queue_name, job_slots): self._job_queue_state = job_queue_state self._job_time = job_time self._job_queue_name = job_queue_name self._job_slots = job_slots def set_state(self, new_state): self._job_queue_state = new_state class QstatSubstitute: """A wrapper for Qstat to avoid overloading the SGE/OGS server with rapid continuous qstat requests""" def __init__(self, qstat_instant_executable='qstat', qstat_cached_executable='qstat'): """ :param qstat_instant_executable: :param qstat_cached_executable: """ self._qstat_instant_executable = qstat_instant_executable self._qstat_cached_executable = qstat_cached_executable self._out_of_scope_jobs = list() # Initialize first self._task_dictionary = dict( ) # {'taskid': QJobInfo(), .... } The dictionaryObject self._remove_old_jobs() def _remove_old_jobs(self): """ This is only called during initialization of the function for the purpose of identifying jobs that are not part of this run of nipype. They are jobs that existed prior to starting a new jobs, so they are irrelevant. """ self._run_qstat("QstatInitialization", True) # If qstat does not exist on this system, then quietly # fail during init def add_startup_job(self, taskid, qsub_command_line): """ :param taskid: The job id :param qsub_command_line: When initializing, re-use the job_queue_name :return: NONE """ taskid = int(taskid) # Ensure that it is an integer self._task_dictionary[taskid] = QJobInfo(taskid, "initializing", time.time(), "noQueue", 1, qsub_command_line) @staticmethod def _qacct_verified_complete(taskid): """ request definitive job completion information for the current job from the qacct report """ sge_debug_print("WARNING: " "CONTACTING qacct for finished jobs, " "{0}: {1}".format(time.time(), "Verifying Completion")) this_command = 'qacct' qacct_retries = 10 is_complete = False while qacct_retries > 0: qacct_retries -= 1 try: proc = subprocess.Popen( [this_command, '-o', pwd.getpwuid(os.getuid())[0], '-j', str(taskid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) qacct_result, _ = proc.communicate() if qacct_result.find(str(taskid)): is_complete = True sge_debug_print( "NOTE: qacct for jobs\n{0}".format(qacct_result)) break except: sge_debug_print("NOTE: qacct call failed") time.sleep(5) pass return is_complete def _parse_qstat_job_list(self, xml_job_list): current_jobs_parsed = list() for current_job_element in xml_job_list: # jobname = current_job_element.getElementsByTagName('JB_name')[0].childNodes[0].data # jobown = # current_job_element.getElementsByTagName('JB_owner')[0].childNodes[0].data try: job_queue_name = current_job_element.getElementsByTagName( 'queue_name')[0].childNodes[0].data except: job_queue_name = "unknown" try: job_slots = current_job_element.getElementsByTagName( 'slots')[0].childNodes[0].data except: job_slots = "unknown" job_queue_state = current_job_element.getAttribute('state') job_num = int(current_job_element.getElementsByTagName( 'JB_job_number')[0].childNodes[0].data) try: job_time_text = current_job_element.getElementsByTagName( 'JAT_start_time')[0].childNodes[0].data job_time = float(time.mktime(time.strptime( job_time_text, "%Y-%m-%dT%H:%M:%S"))) except: job_time = float(0.0) # Make job entry task_id = int(job_num) if task_id in self._task_dictionary: self._task_dictionary[task_id].update_info( job_queue_state, job_time, job_queue_name, job_slots) sge_debug_print("Updating job: {0}".format( self._task_dictionary[task_id])) current_jobs_parsed.append(task_id) # Changed from job_num as "in" is used to check which does not cast else: # Any Job that was not explicitly added with qsub command is # out of scope self._out_of_scope_jobs.append(task_id) # To ensure that every job is in the dictionary has a state reported # by the SGE environment, it is necessary to explicitly check jobs # that are not reported by the qstat command to determine if they # were started and finished, and pushed out of the window of review # before their state being recorded. The qacct command is slower, but # much more robust for ensuring that a job has completed. for dictionary_job in self._task_dictionary.keys(): if dictionary_job not in current_jobs_parsed: is_completed = self._qacct_verified_complete(dictionary_job) if is_completed: self._task_dictionary[dictionary_job].set_state("zombie") else: sge_debug_print("ERROR: Job not in current parselist, " "and not in done list {0}: {1}".format(dictionary_job, self._task_dictionary[dictionary_job])) pass if self._task_dictionary[dictionary_job].is_initializing(): is_completed = self._qacct_verified_complete(dictionary_job) if is_completed: self._task_dictionary[dictionary_job].set_state("zombie") else: sge_debug_print("ERROR: Job not in still in intializing mode, " "and not in done list {0}: {1}".format(dictionary_job, self._task_dictionary[dictionary_job])) pass def _run_qstat(self, reason_for_qstat, force_instant=True): """ request all job information for the current user in xmlformat. See documentation from java documentation: http://arc.liv.ac.uk/SGE/javadocs/jgdi/com/sun/grid/jgdi/monitoring/filter/JobStateFilter.html -s r gives running jobs -s z gives recently completed jobs (**recently** is very ambiguous) -s s suspended jobs """ sge_debug_print("WARNING: CONTACTING qmaster for jobs, " "{0}: {1}".format(time.time(), reason_for_qstat)) if force_instant: this_command = self._qstat_instant_executable else: this_command = self._qstat_cached_executable qstat_retries = 10 while qstat_retries > 0: qstat_retries -= 1 try: proc = subprocess.Popen( [this_command, '-u', pwd.getpwuid(os.getuid())[0], '-xml', '-s', 'psrz'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) qstat_xml_result, _ = proc.communicate() dom = xml.dom.minidom.parseString(qstat_xml_result) jobs = dom.getElementsByTagName('job_info') run = jobs[0] runjobs = run.getElementsByTagName('job_list') self._parse_qstat_job_list(runjobs) break except Exception as inst: exception_message = "QstatParsingError:\n\t{0}\n\t{1}\n".format( type( inst), # the exception instance inst # __str__ allows args to printed directly ) sge_debug_print(exception_message) time.sleep(5) pass def print_dictionary(self): """For debugging""" for vv in self._task_dictionary.values(): sge_debug_print(str(vv)) def is_job_pending(self, task_id): task_id = int(task_id) # Ensure that it is an integer # Check if the task is in the dictionary first (before running qstat) if task_id in self._task_dictionary: # Trust the cache, only False if state='zombie' job_is_pending = self._task_dictionary[task_id].is_job_state_pending() # Double check pending jobs in case of change (since we don't check at the beginning) if job_is_pending: self._run_qstat("checking job pending status {0}".format(task_id), False) job_is_pending = self._task_dictionary[task_id].is_job_state_pending() else: self._run_qstat("checking job pending status {0}".format(task_id), True) if task_id in self._task_dictionary: # Trust the cache, only False if state='zombie' job_is_pending = self._task_dictionary[task_id].is_job_state_pending() else: sge_debug_print("ERROR: Job {0} not in task list, " "even after forced qstat!".format(task_id)) job_is_pending = False if not job_is_pending: sge_debug_print("DONE! Returning for {0} claiming done!".format(task_id)) if task_id in self._task_dictionary: sge_debug_print("NOTE: Adding {0} to OutOfScopeJobs list!".format(task_id)) self._out_of_scope_jobs.append(int(task_id)) self._task_dictionary.pop(task_id) else: sge_debug_print("ERROR: Job {0} not in task list, " "but attempted to be removed!".format(task_id)) return job_is_pending def qsub_sanitize_job_name(testjobname): """ Ensure that qsub job names must begin with a letter. Numbers and punctuation are not allowed. >>> qsub_sanitize_job_name('01') 'J01' >>> qsub_sanitize_job_name('a01') 'a01' """ if testjobname[0].isalpha(): return testjobname else: return 'J' + testjobname class SGEPlugin(SGELikeBatchManagerBase): """Execute using SGE (OGE not tested) The plugin_args input to run can be used to control the SGE execution. Currently supported options are: - template : template to use for batch job submission - qsub_args : arguments to be prepended to the job execution script in the qsub call """ def __init__(self, **kwargs): template = """ #$ -V #$ -S /bin/sh """ self._retry_timeout = 2 self._max_tries = 2 instant_qstat = 'qstat' cached_qstat = 'qstat' if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] if 'qstatProgramPath' in kwargs['plugin_args']: instant_qstat = kwargs['plugin_args']['qstatProgramPath'] if 'qstatCachedProgramPath' in kwargs['plugin_args']: cached_qstat = kwargs['plugin_args']['qstatCachedProgramPath'] self._refQstatSubstitute = QstatSubstitute(instant_qstat, cached_qstat) super(SGEPlugin, self).__init__(template, **kwargs) def _is_pending(self, taskid): return self._refQstatSubstitute.is_job_pending(int(taskid)) def _submit_batchtask(self, scriptfile, node): cmd = CommandLine('qsub', environ=os.environ.data, terminal_output='allatonce') path = os.path.dirname(scriptfile) qsubargs = '' if self._qsub_args: qsubargs = self._qsub_args if 'qsub_args' in node.plugin_args: if 'overwrite' in node.plugin_args and \ node.plugin_args['overwrite']: qsubargs = node.plugin_args['qsub_args'] else: qsubargs += (" " + node.plugin_args['qsub_args']) if '-o' not in qsubargs: qsubargs = '%s -o %s' % (qsubargs, path) if '-e' not in qsubargs: qsubargs = '%s -e %s' % (qsubargs, path) if node._hierarchy: jobname = '.'.join((os.environ.data['LOGNAME'], node._hierarchy, node._id)) else: jobname = '.'.join((os.environ.data['LOGNAME'], node._id)) jobnameitems = jobname.split('.') jobnameitems.reverse() jobname = '.'.join(jobnameitems) jobname = qsub_sanitize_job_name(jobname) cmd.inputs.args = '%s -N %s %s' % (qsubargs, jobname, scriptfile) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) tries = 0 result = list() while True: try: result = cmd.run() except Exception, e: if tries < self._max_tries: tries += 1 time.sleep( self._retry_timeout) # sleep 2 seconds and try again. else: iflogger.setLevel(oldlevel) raise RuntimeError('\n'.join((('Could not submit sge task' ' for node %s') % node._id, str(e)))) else: break iflogger.setLevel(oldlevel) # retrieve sge taskid lines = [line for line in result.runtime.stdout.split('\n') if line] taskid = int(re.match("Your job ([0-9]*) .* has been submitted", lines[-1]).groups()[0]) self._pending[taskid] = node.output_dir() self._refQstatSubstitute.add_startup_job(taskid, cmd.cmdline) logger.debug('submitted sge task: %d for node %s with %s' % (taskid, node._id, cmd.cmdline)) return taskid nipype-0.11.0/nipype/pipeline/plugins/sgegraph.py000066400000000000000000000153021257611314500220470ustar00rootroot00000000000000"""Parallel workflow execution via SGE """ import os import sys from .base import (GraphPluginBase, logger) from ...interfaces.base import CommandLine def node_completed_status( checknode): """ A function to determine if a node has previously completed it's work :param checknode: The node to check the run status :return: boolean value True indicates that the node does not need to be run. """ """ TODO: place this in the base.py file and refactor """ node_state_does_not_require_overwrite = ( checknode.overwrite == False or (checknode.overwrite == None and not checknode._interface.always_run ) ) hash_exists = False try: hash_exists, _, _, _ = checknode.hash_exists() except Exception: hash_exists = False return (hash_exists and node_state_does_not_require_overwrite ) class SGEGraphPlugin(GraphPluginBase): """Execute using SGE The plugin_args input to run can be used to control the SGE execution. Currently supported options are: - template : template to use for batch job submission - qsub_args : arguments to be prepended to the job execution script in the qsub call """ _template = """ #!/bin/bash #$ -V #$ -S /bin/bash """ def __init__(self, **kwargs): self._qsub_args = '' self._dont_resubmit_completed_jobs = False if 'plugin_args' in kwargs and kwargs['plugin_args']: plugin_args = kwargs['plugin_args'] if 'template' in plugin_args: self._template = plugin_args['template'] if os.path.isfile(self._template): self._template = open(self._template).read() if 'qsub_args' in plugin_args: self._qsub_args = plugin_args['qsub_args'] if 'dont_resubmit_completed_jobs' in plugin_args: self._dont_resubmit_completed_jobs = plugin_args['dont_resubmit_completed_jobs'] super(SGEGraphPlugin, self).__init__(**kwargs) def _submit_graph(self, pyfiles, dependencies, nodes): def make_job_name(jobnumber, nodeslist): """ - jobnumber: The index number of the job to create - nodeslist: The name of the node being processed - return: A string representing this job to be displayed by SGE """ job_name='j{0}_{1}'.format(jobnumber, nodeslist[jobnumber]._id) # Condition job_name to be a valid bash identifier (i.e. - is invalid) job_name=job_name.replace('-','_').replace('.','_').replace(':','_') return job_name batch_dir, _ = os.path.split(pyfiles[0]) submitjobsfile = os.path.join(batch_dir, 'submit_jobs.sh') cache_doneness_per_node = dict() if self._dont_resubmit_completed_jobs: ## A future parameter for controlling this behavior could be added here for idx, pyscript in enumerate(pyfiles): node = nodes[idx] node_status_done = node_completed_status(node) #if the node itself claims done, then check to ensure all #dependancies are also done if node_status_done and idx in dependencies: for child_idx in dependencies[idx]: if child_idx in cache_doneness_per_node: child_status_done = cache_doneness_per_node[child_idx] else: child_status_done = node_completed_status(nodes[child_idx]) node_status_done = node_status_done and child_status_done cache_doneness_per_node[idx] = node_status_done with open(submitjobsfile, 'wt') as fp: fp.writelines('#!/usr/bin/env bash\n') fp.writelines('# Condense format attempted\n') for idx, pyscript in enumerate(pyfiles): node = nodes[idx] if cache_doneness_per_node.get(idx,False): continue else: template, qsub_args = self._get_args( node, ["template", "qsub_args"]) batch_dir, name = os.path.split(pyscript) name = '.'.join(name.split('.')[:-1]) batchscript = '\n'.join((template, '%s %s' % (sys.executable, pyscript))) batchscriptfile = os.path.join(batch_dir, 'batchscript_%s.sh' % name) batchscriptoutfile = batchscriptfile + '.o' batchscripterrfile = batchscriptfile + '.e' with open(batchscriptfile, 'wt') as batchfp: batchfp.writelines(batchscript) batchfp.close() deps = '' if idx in dependencies: values = ' ' for jobid in dependencies[idx]: ## Avoid dependancies of done jobs if not self._dont_resubmit_completed_jobs or cache_doneness_per_node[jobid] == False: values += "${{{0}}},".format(make_job_name(jobid, nodes)) if values != ' ': # i.e. if some jobs were added to dependency list values = values.rstrip(',') deps = '-hold_jid%s' % values jobname = make_job_name(idx, nodes) # Do not use default output locations if they are set in self._qsub_args stderrFile = '' if self._qsub_args.count('-e ') == 0: stderrFile = '-e {errFile}'.format( errFile=batchscripterrfile) stdoutFile = '' if self._qsub_args.count('-o ') == 0: stdoutFile = '-o {outFile}'.format( outFile=batchscriptoutfile) full_line = '{jobNm}=$(qsub {outFileOption} {errFileOption} {extraQSubArgs} {dependantIndex} -N {jobNm} {batchscript} | awk \'{{print $3}}\')\n'.format( jobNm=jobname, outFileOption=stdoutFile, errFileOption=stderrFile, extraQSubArgs=qsub_args, dependantIndex=deps, batchscript=batchscriptfile) fp.writelines(full_line) cmd = CommandLine('bash', environ=os.environ.data, terminal_output='allatonce') cmd.inputs.args = '%s' % submitjobsfile cmd.run() logger.info('submitted all jobs to queue') nipype-0.11.0/nipype/pipeline/plugins/slurm.py000066400000000000000000000111711257611314500214110ustar00rootroot00000000000000''' Created on Aug 2, 2013 @author: chadcumba Parallel workflow execution with SLURM ''' import os import re import subprocess from time import sleep from .base import (SGELikeBatchManagerBase, logger, iflogger, logging) from nipype.interfaces.base import CommandLine class SLURMPlugin(SGELikeBatchManagerBase): ''' Execute using SLURM The plugin_args input to run can be used to control the SLURM execution. Currently supported options are: - template : template to use for batch job submission - sbatch_args: arguments to pass prepend to the sbatch call ''' def __init__(self, **kwargs): template="#!/bin/bash" self._retry_timeout = 2 self._max_tries = 2 self._template = template self._sbatch_args = None if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] if 'template' in kwargs['plugin_args']: self._template = kwargs['plugin_args']['template'] if os.path.isfile(self._template): self._template = open(self._template).read() if 'sbatch_args' in kwargs['plugin_args']: self._sbatch_args = kwargs['plugin_args']['sbatch_args'] self._pending = {} super(SLURMPlugin, self).__init__(self._template, **kwargs) def _is_pending(self, taskid): # subprocess.Popen requires taskid to be a string proc = subprocess.Popen(["squeue", '-j', '%s' % taskid], stdout=subprocess.PIPE, stderr=subprocess.PIPE) o, _ = proc.communicate() return o.find(str(taskid)) > -1 def _submit_batchtask(self, scriptfile, node): """ This is more or less the _submit_batchtask from sge.py with flipped variable names, different command line switches, and different output formatting/processing """ cmd = CommandLine('sbatch', environ=os.environ.data, terminal_output='allatonce') path = os.path.dirname(scriptfile) sbatch_args = '' if self._sbatch_args: sbatch_args = self._sbatch_args if 'sbatch_args' in node.plugin_args: if 'overwrite' in node.plugin_args and\ node.plugin_args['overwrite']: sbatch_args = node.plugin_args['sbatch_args'] else: sbatch_args += (" " + node.plugin_args['sbatch_args']) if '-o' not in sbatch_args: sbatch_args = '%s -o %s' % (sbatch_args, os.path.join(path, 'slurm-%j.out')) if '-e' not in sbatch_args: sbatch_args = '%s -e %s' % (sbatch_args, os.path.join(path, 'slurm-%j.out')) if node._hierarchy: jobname = '.'.join((os.environ.data['LOGNAME'], node._hierarchy, node._id)) else: jobname = '.'.join((os.environ.data['LOGNAME'], node._id)) jobnameitems = jobname.split('.') jobnameitems.reverse() jobname = '.'.join(jobnameitems) cmd.inputs.args = '%s -J %s %s' % (sbatch_args, jobname, scriptfile) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName('CRITICAL')) tries = 0 while True: try: result = cmd.run() except Exception, e: if tries < self._max_tries: tries += 1 sleep(self._retry_timeout) # sleep 2 seconds and try again. else: iflogger.setLevel(oldlevel) raise RuntimeError('\n'.join((('Could not submit sbatch task' ' for node %s') % node._id, str(e)))) else: break logger.debug('Ran command ({0})'.format(cmd.cmdline)) iflogger.setLevel(oldlevel) # retrieve taskid lines = [line for line in result.runtime.stdout.split('\n') if line] taskid = int(re.match("Submitted batch job ([0-9]*)", lines[-1]).groups()[0]) self._pending[taskid] = node.output_dir() logger.debug('submitted sbatch task: %d for node %s' % (taskid, node._id)) return taskid nipype-0.11.0/nipype/pipeline/plugins/slurmgraph.py000066400000000000000000000157321257611314500224420ustar00rootroot00000000000000"""Parallel workflow execution via SLURM """ import os import sys from .base import (GraphPluginBase, logger) from ...interfaces.base import CommandLine def node_completed_status( checknode): """ A function to determine if a node has previously completed it's work :param checknode: The node to check the run status :return: boolean value True indicates that the node does not need to be run. """ """ TODO: place this in the base.py file and refactor """ node_state_does_not_require_overwrite = ( checknode.overwrite == False or (checknode.overwrite == None and not checknode._interface.always_run ) ) hash_exists = False try: hash_exists, _, _, _ = checknode.hash_exists() except Exception: hash_exists = False return (hash_exists and node_state_does_not_require_overwrite ) class SLURMGraphPlugin(GraphPluginBase): """Execute using SLURM The plugin_args input to run can be used to control the SGE execution. Currently supported options are: - template : template to use for batch job submission - qsub_args : arguments to be prepended to the job execution script in the qsub call """ _template="#!/bin/bash" def __init__(self, **kwargs): if 'plugin_args' in kwargs and kwargs['plugin_args']: if 'retry_timeout' in kwargs['plugin_args']: self._retry_timeout = kwargs['plugin_args']['retry_timeout'] if 'max_tries' in kwargs['plugin_args']: self._max_tries = kwargs['plugin_args']['max_tries'] if 'template' in kwargs['plugin_args']: self._template = kwargs['plugin_args']['template'] if os.path.isfile(self._template): self._template = open(self._template).read() if 'sbatch_args' in kwargs['plugin_args']: self._sbatch_args = kwargs['plugin_args']['sbatch_args'] if 'dont_resubmit_completed_jobs' in kwargs['plugin_args']: self._dont_resubmit_completed_jobs = kwargs['plugin_args']['dont_resubmit_completed_jobs'] else: self._dont_resubmit_completed_jobs = False super(SLURMGraphPlugin, self).__init__(**kwargs) def _submit_graph(self, pyfiles, dependencies, nodes): def make_job_name(jobnumber, nodeslist): """ - jobnumber: The index number of the job to create - nodeslist: The name of the node being processed - return: A string representing this job to be displayed by SLURM """ job_name='j{0}_{1}'.format(jobnumber, nodeslist[jobnumber]._id) # Condition job_name to be a valid bash identifier (i.e. - is invalid) job_name=job_name.replace('-','_').replace('.','_').replace(':','_') return job_name batch_dir, _ = os.path.split(pyfiles[0]) submitjobsfile = os.path.join(batch_dir, 'submit_jobs.sh') cache_doneness_per_node = dict() if self._dont_resubmit_completed_jobs: ## A future parameter for controlling this behavior could be added here for idx, pyscript in enumerate(pyfiles): node = nodes[idx] node_status_done = node_completed_status(node) #if the node itself claims done, then check to ensure all #dependancies are also done if node_status_done and idx in dependencies: for child_idx in dependencies[idx]: if child_idx in cache_doneness_per_node: child_status_done = cache_doneness_per_node[child_idx] else: child_status_done = node_completed_status(nodes[child_idx]) node_status_done = node_status_done and child_status_done cache_doneness_per_node[idx] = node_status_done with open(submitjobsfile, 'wt') as fp: fp.writelines('#!/usr/bin/env bash\n') fp.writelines('# Condense format attempted\n') for idx, pyscript in enumerate(pyfiles): node = nodes[idx] if cache_doneness_per_node.get(idx,False): continue else: template, sbatch_args = self._get_args( node, ["template", "sbatch_args"]) batch_dir, name = os.path.split(pyscript) name = '.'.join(name.split('.')[:-1]) batchscript = '\n'.join((template, '%s %s' % (sys.executable, pyscript))) batchscriptfile = os.path.join(batch_dir, 'batchscript_%s.sh' % name) batchscriptoutfile = batchscriptfile + '.o' batchscripterrfile = batchscriptfile + '.e' with open(batchscriptfile, 'wt') as batchfp: batchfp.writelines(batchscript) batchfp.close() deps = '' if idx in dependencies: values = '' for jobid in dependencies[idx]: ## Avoid dependancies of done jobs if not self._dont_resubmit_completed_jobs or cache_doneness_per_node[jobid] == False: values += "${{{0}}}:".format(make_job_name(jobid, nodes)) if values != '': # i.e. if some jobs were added to dependency list values = values.rstrip(':') deps = '--dependency=afterok:%s' % values jobname = make_job_name(idx, nodes) # Do not use default output locations if they are set in self._sbatch_args stderrFile = '' if self._sbatch_args.count('-e ') == 0: stderrFile = '-e {errFile}'.format( errFile=batchscripterrfile) stdoutFile = '' if self._sbatch_args.count('-o ') == 0: stdoutFile = '-o {outFile}'.format( outFile=batchscriptoutfile) full_line = '{jobNm}=$(sbatch {outFileOption} {errFileOption} {extraSBatchArgs} {dependantIndex} -J {jobNm} {batchscript} | awk \'{{print $4}}\')\n'.format( jobNm=jobname, outFileOption=stdoutFile, errFileOption=stderrFile, extraSBatchArgs=sbatch_args, dependantIndex=deps, batchscript=batchscriptfile) fp.writelines(full_line) cmd = CommandLine('bash', environ=os.environ.data, terminal_output='allatonce') cmd.inputs.args = '%s' % submitjobsfile cmd.run() logger.info('submitted all jobs to queue') nipype-0.11.0/nipype/pipeline/plugins/somaflow.py000066400000000000000000000025451257611314500221030ustar00rootroot00000000000000"""Parallel workflow execution via PBS/Torque """ import os import sys soma_not_loaded = False try: from soma.workflow.client import (Job, Workflow, WorkflowController, Helper) except: soma_not_loaded = True from .base import (GraphPluginBase, logger) class SomaFlowPlugin(GraphPluginBase): """Execute using Soma workflow """ def __init__(self, plugin_args=None): if soma_not_loaded: raise ImportError('SomaFlow could not be imported') super(SomaFlowPlugin, self).__init__(plugin_args=plugin_args) def _submit_graph(self, pyfiles, dependencies, nodes): jobs = [] soma_deps = [] for idx, fname in enumerate(pyfiles): name = os.path.splitext(os.path.split(fname)[1])[0] jobs.append(Job(command=[sys.executable, fname], name=name)) for key, values in dependencies.items(): for val in values: soma_deps.append((jobs[val], jobs[key])) wf = Workflow(jobs, soma_deps) logger.info('serializing workflow') Helper.serialize('workflow', wf) controller = WorkflowController() logger.info('submitting workflow') wf_id = controller.submit_workflow(wf) Helper.wait_workflow(wf_id, controller) nipype-0.11.0/nipype/pipeline/plugins/tests/000077500000000000000000000000001257611314500210365ustar00rootroot00000000000000nipype-0.11.0/nipype/pipeline/plugins/tests/__init__.py000066400000000000000000000001621257611314500231460ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/pipeline/plugins/tests/test_base.py000066400000000000000000000022001257611314500233530ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Tests for the engine module """ import numpy as np import scipy.sparse as ssp from nipype.testing import (assert_raises, assert_equal, assert_true, assert_false, skipif) import nipype.pipeline.plugins.base as pb def test_scipy_sparse(): foo = ssp.lil_matrix(np.eye(3, k=1)) goo = foo.getrowview(0) goo[goo.nonzero()] = 0 yield assert_equal, foo[0,1], 0 ''' Can use the following code to test that a mapnode crash continues successfully Need to put this into a nose-test with a timeout import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe wf = pe.Workflow(name='test') def func(arg1): if arg1 == 2: raise Exception('arg cannot be ' + str(arg1)) return arg1 funkynode = pe.MapNode(niu.Function(function=func, input_names=['arg1'], output_names=['out']), iterfield=['arg1'], name = 'functor') funkynode.inputs.arg1 = [1,2] wf.add_nodes([funkynode]) wf.base_dir = '/tmp' wf.run(plugin='MultiProc') '''nipype-0.11.0/nipype/pipeline/plugins/tests/test_callback.py000066400000000000000000000065111257611314500242060ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Tests for workflow callbacks """ from tempfile import mkdtemp from shutil import rmtree from nipype.testing import assert_equal import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe def func(): return def bad_func(): raise Exception class Status: def __init__(self): self.statuses = [] def callback(self, node, status): self.statuses.append((node, status)) def test_callback_normal(): so = Status() wf = pe.Workflow(name='test', base_dir=mkdtemp()) f_node = pe.Node(niu.Function(function=func, input_names=[], output_names=[]), name='f_node') wf.add_nodes([f_node]) wf.config['execution'] = {'crashdump_dir': wf.base_dir} wf.run(plugin="Linear", plugin_args={'status_callback': so.callback}) assert_equal(len(so.statuses), 2) for (n, s) in so.statuses: yield assert_equal, n.name, 'f_node' yield assert_equal, so.statuses[0][1], 'start' yield assert_equal, so.statuses[1][1], 'end' rmtree(wf.base_dir) def test_callback_exception(): so = Status() wf = pe.Workflow(name='test', base_dir=mkdtemp()) f_node = pe.Node(niu.Function(function=bad_func, input_names=[], output_names=[]), name='f_node') wf.add_nodes([f_node]) wf.config['execution'] = {'crashdump_dir': wf.base_dir} try: wf.run(plugin="Linear", plugin_args={'status_callback': so.callback}) except: pass assert_equal(len(so.statuses), 2) for (n, s) in so.statuses: yield assert_equal, n.name, 'f_node' yield assert_equal, so.statuses[0][1], 'start' yield assert_equal, so.statuses[1][1], 'exception' rmtree(wf.base_dir) def test_callback_multiproc_normal(): so = Status() wf = pe.Workflow(name='test', base_dir=mkdtemp()) f_node = pe.Node(niu.Function(function=func, input_names=[], output_names=[]), name='f_node') wf.add_nodes([f_node]) wf.config['execution']['crashdump_dir'] = wf.base_dir wf.config['execution']['poll_sleep_duration'] = 2 wf.run(plugin='MultiProc', plugin_args={'status_callback': so.callback}) assert_equal(len(so.statuses), 2) for (n, s) in so.statuses: yield assert_equal, n.name, 'f_node' yield assert_equal, so.statuses[0][1], 'start' yield assert_equal, so.statuses[1][1], 'end' rmtree(wf.base_dir) def test_callback_multiproc_exception(): so = Status() wf = pe.Workflow(name='test', base_dir=mkdtemp()) f_node = pe.Node(niu.Function(function=bad_func, input_names=[], output_names=[]), name='f_node') wf.add_nodes([f_node]) wf.config['execution']['crashdump_dir'] = wf.base_dir wf.config['execution']['poll_sleep_duration'] = 2 try: wf.run(plugin='MultiProc', plugin_args={'status_callback': so.callback}) except: pass assert_equal(len(so.statuses), 2) for (n, s) in so.statuses: yield assert_equal, n.name, 'f_node' yield assert_equal, so.statuses[0][1], 'start' yield assert_equal, so.statuses[1][1], 'exception' rmtree(wf.base_dir) nipype-0.11.0/nipype/pipeline/plugins/tests/test_debug.py000066400000000000000000000030601257611314500235340ustar00rootroot00000000000000import os import nipype.interfaces.base as nib from tempfile import mkdtemp from shutil import rmtree from nipype.testing import assert_raises, assert_false import nipype.pipeline.engine as pe class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs def callme(node, graph): pass def test_debug(): cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.MapNode(interface=TestInterface(), iterfield=['input1'], name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) pipe.base_dir = os.getcwd() mod1.inputs.input1 = 1 run_wf = lambda: pipe.run(plugin="Debug") yield assert_raises, ValueError, run_wf try: pipe.run(plugin="Debug", plugin_args={'callable': callme}) exception_raised = False except Exception: exception_raised = True yield assert_false, exception_raised os.chdir(cur_dir) rmtree(temp_dir)nipype-0.11.0/nipype/pipeline/plugins/tests/test_linear.py000066400000000000000000000027421257611314500237260ustar00rootroot00000000000000import os import nipype.interfaces.base as nib from tempfile import mkdtemp from shutil import rmtree from nipype.testing import assert_equal import nipype.pipeline.engine as pe class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs def test_run_in_series(): cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.MapNode(interface=TestInterface(), iterfield=['input1'], name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) pipe.base_dir = os.getcwd() mod1.inputs.input1 = 1 execgraph = pipe.run(plugin="Linear") names = ['.'.join((node._hierarchy,node.name)) for node in execgraph.nodes()] node = execgraph.nodes()[names.index('pipe.mod1')] result = node.get_output('output1') yield assert_equal, result, [1, 1] os.chdir(cur_dir) rmtree(temp_dir)nipype-0.11.0/nipype/pipeline/plugins/tests/test_multiproc.py000066400000000000000000000030351257611314500244660ustar00rootroot00000000000000import os import nipype.interfaces.base as nib from tempfile import mkdtemp from shutil import rmtree from nipype.testing import assert_equal import nipype.pipeline.engine as pe class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs def test_run_multiproc(): cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.MapNode(interface=TestInterface(), iterfield=['input1'], name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) pipe.base_dir = os.getcwd() mod1.inputs.input1 = 1 pipe.config['execution']['poll_sleep_duration'] = 2 execgraph = pipe.run(plugin="MultiProc") names = ['.'.join((node._hierarchy,node.name)) for node in execgraph.nodes()] node = execgraph.nodes()[names.index('pipe.mod1')] result = node.get_output('output1') yield assert_equal, result, [1, 1] os.chdir(cur_dir) rmtree(temp_dir)nipype-0.11.0/nipype/pipeline/plugins/tests/test_multiproc_nondaemon.py000066400000000000000000000101531257611314500265230ustar00rootroot00000000000000import os from tempfile import mkdtemp from shutil import rmtree from nipype.testing import assert_equal, assert_true import nipype.pipeline.engine as pe from nipype.interfaces.utility import Function def mytestFunction(insum=0): ''' Run a multiprocessing job and spawn child processes. ''' # need to import here since this is executed as an external process import multiprocessing import tempfile import time import os numberOfThreads = 2 # list of processes t = [None] * numberOfThreads # list of alive flags a = [None] * numberOfThreads # list of tempFiles f = [None] * numberOfThreads def dummyFunction(filename): ''' This function writes the value 45 to the given filename. ''' j = 0 for i in range(0, 10): j += i # j is now 45 (0+1+2+3+4+5+6+7+8+9) with open(filename, 'w') as f: f.write(str(j)) for n in xrange(numberOfThreads): # mark thread as alive a[n] = True # create a temp file to use as the data exchange container tmpFile = tempfile.mkstemp('.txt', 'test_engine_')[1] f[n] = tmpFile # keep track of the temp file t[n] = multiprocessing.Process(target=dummyFunction, args=(tmpFile,)) # fire up the job t[n].start() # block until all processes are done allDone = False while not allDone: time.sleep(1) for n in xrange(numberOfThreads): a[n] = t[n].is_alive() if not any(a): # if no thread is alive allDone = True # here, all processes are done # read in all temp files and sum them up total = insum for file in f: with open(file) as fd: total += int(fd.read()) os.remove(file) return total def run_multiproc_nondaemon_with_flag(nondaemon_flag): ''' Start a pipe with two nodes using the multiproc plugin and passing the nondaemon_flag. ''' cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') f1 = pe.Node(interface=Function(function=mytestFunction, input_names=['insum'], output_names=['sum_out']), name='f1') f2 = pe.Node(interface=Function(function=mytestFunction, input_names=['insum'], output_names=['sum_out']), name='f2') pipe.connect([(f1, f2, [('sum_out', 'insum')])]) pipe.base_dir = os.getcwd() f1.inputs.insum = 0 pipe.config['execution']['stop_on_first_crash'] = True pipe.config['execution']['poll_sleep_duration'] = 2 # execute the pipe using the MultiProc plugin with 2 processes and the non_daemon flag # to enable child processes which start other multiprocessing jobs execgraph = pipe.run(plugin="MultiProc", plugin_args={'n_procs': 2, 'non_daemon': nondaemon_flag}) names = ['.'.join((node._hierarchy,node.name)) for node in execgraph.nodes()] node = execgraph.nodes()[names.index('pipe.f2')] result = node.get_output('sum_out') os.chdir(cur_dir) rmtree(temp_dir) return result def test_run_multiproc_nondaemon_false(): ''' This is the entry point for the test. Two times a pipe of several multiprocessing jobs gets executed. First, without the nondaemon flag. Second, with the nondaemon flag. Since the processes of the pipe start child processes, the execution only succeeds when the non_daemon flag is on. ''' shouldHaveFailed = False try: # with nondaemon_flag = False, the execution should fail run_multiproc_nondaemon_with_flag(False) except: shouldHaveFailed = True yield assert_true, shouldHaveFailed def test_run_multiproc_nondaemon_true(): # with nondaemon_flag = True, the execution should succeed result = run_multiproc_nondaemon_with_flag(True) yield assert_equal, result, 180 # n_procs (2) * numberOfThreads (2) * 45 == 180 nipype-0.11.0/nipype/pipeline/plugins/tests/test_pbs.py000066400000000000000000000030201257611314500232260ustar00rootroot00000000000000import os from shutil import rmtree from tempfile import mkdtemp from time import sleep import nipype.interfaces.base as nib from nipype.testing import assert_equal, skipif import nipype.pipeline.engine as pe class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs @skipif(True) def test_run_pbsgraph(): cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.MapNode(interface=TestInterface(), iterfield=['input1'], name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) pipe.base_dir = os.getcwd() mod1.inputs.input1 = 1 execgraph = pipe.run(plugin="PBSGraph") names = ['.'.join((node._hierarchy,node.name)) for node in execgraph.nodes()] node = execgraph.nodes()[names.index('pipe.mod1')] result = node.get_output('output1') yield assert_equal, result, [1, 1] os.chdir(cur_dir) rmtree(temp_dir)nipype-0.11.0/nipype/pipeline/plugins/tests/test_somaflow.py000066400000000000000000000031311257611314500242740ustar00rootroot00000000000000import os from shutil import rmtree from tempfile import mkdtemp from time import sleep import nipype.interfaces.base as nib from nipype.testing import assert_equal, skipif import nipype.pipeline.engine as pe from nipype.pipeline.plugins.somaflow import soma_not_loaded class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs @skipif(soma_not_loaded) def test_run_somaflow(): cur_dir = os.getcwd() temp_dir = mkdtemp(prefix='test_engine_') os.chdir(temp_dir) pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.MapNode(interface=TestInterface(), iterfield=['input1'], name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) pipe.base_dir = os.getcwd() mod1.inputs.input1 = 1 execgraph = pipe.run(plugin="SomaFlow") names = ['.'.join((node._hierarchy,node.name)) for node in execgraph.nodes()] node = execgraph.nodes()[names.index('pipe.mod1')] result = node.get_output('output1') yield assert_equal, result, [1, 1] os.chdir(cur_dir) rmtree(temp_dir)nipype-0.11.0/nipype/pipeline/report_template.html000066400000000000000000000150341257611314500223120ustar00rootroot00000000000000

Flare imports
hierarchical edge bundling

tension:
nipype-0.11.0/nipype/pipeline/report_template2.html000066400000000000000000000061031257611314500223710ustar00rootroot00000000000000 Sankey Diagram

Nipype workflow: Sankey Diagram

nipype-0.11.0/nipype/pipeline/tests/000077500000000000000000000000001257611314500173555ustar00rootroot00000000000000nipype-0.11.0/nipype/pipeline/tests/__init__.py000066400000000000000000000003071257611314500214660ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from nipype.testing import skip_if_no_package skip_if_no_package('networkx', '1.0') nipype-0.11.0/nipype/pipeline/tests/test_engine.py000066400000000000000000000605111257611314500222360ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Tests for the engine module """ from copy import deepcopy from glob import glob import os from shutil import rmtree from tempfile import mkdtemp import networkx as nx from nipype.testing import (assert_raises, assert_equal, assert_true, assert_false) import nipype.interfaces.base as nib import nipype.pipeline.engine as pe from nipype import logging class InputSpec(nib.TraitedSpec): input1 = nib.traits.Int(desc='a random int') input2 = nib.traits.Int(desc='a random int') class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1, self.inputs.input1] return outputs def test_init(): yield assert_raises, Exception, pe.Workflow pipe = pe.Workflow(name='pipe') yield assert_equal, type(pipe._graph), nx.DiGraph def test_connect(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') pipe.connect([(mod1,mod2,[('output1','input1')])]) yield assert_true, mod1 in pipe._graph.nodes() yield assert_true, mod2 in pipe._graph.nodes() yield assert_equal, pipe._graph.get_edge_data(mod1,mod2), {'connect':[('output1','input1')]} def test_add_nodes(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') pipe.add_nodes([mod1,mod2]) yield assert_true, mod1 in pipe._graph.nodes() yield assert_true, mod2 in pipe._graph.nodes() # Test graph expansion. The following set tests the building blocks # of the graph expansion routine. # XXX - SG I'll create a graphical version of these tests and actually # ensure that all connections are tested later def test1(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') pipe.add_nodes([mod1]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 1 yield assert_equal, len(pipe._execgraph.edges()), 0 def test2(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod1.iterables = dict(input1=lambda:[1,2],input2=lambda:[1,2]) pipe.add_nodes([mod1]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 4 yield assert_equal, len(pipe._execgraph.edges()), 0 def test3(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod1.iterables = {} mod2 = pe.Node(interface=TestInterface(),name='mod2') mod2.iterables = dict(input1=lambda:[1,2]) pipe.connect([(mod1,mod2,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 3 yield assert_equal, len(pipe._execgraph.edges()), 2 def test4(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') mod1.iterables = dict(input1=lambda:[1,2]) mod2.iterables = {} pipe.connect([(mod1,mod2,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 4 yield assert_equal, len(pipe._execgraph.edges()), 2 def test5(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') mod1.iterables = dict(input1=lambda:[1,2]) mod2.iterables = dict(input1=lambda:[1,2]) pipe.connect([(mod1,mod2,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 6 yield assert_equal, len(pipe._execgraph.edges()), 4 def test6(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') mod3 = pe.Node(interface=TestInterface(),name='mod3') mod1.iterables = {} mod2.iterables = dict(input1=lambda:[1,2]) mod3.iterables = {} pipe.connect([(mod1,mod2,[('output1','input2')]), (mod2,mod3,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 5 yield assert_equal, len(pipe._execgraph.edges()), 4 def test7(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') mod3 = pe.Node(interface=TestInterface(),name='mod3') mod1.iterables = dict(input1=lambda:[1,2]) mod2.iterables = {} mod3.iterables = {} pipe.connect([(mod1,mod3,[('output1','input1')]), (mod2,mod3,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 5 yield assert_equal, len(pipe._execgraph.edges()), 4 def test8(): pipe = pe.Workflow(name='pipe') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') mod3 = pe.Node(interface=TestInterface(),name='mod3') mod1.iterables = dict(input1=lambda:[1,2]) mod2.iterables = dict(input1=lambda:[1,2]) mod3.iterables = {} pipe.connect([(mod1,mod3,[('output1','input1')]), (mod2,mod3,[('output1','input2')])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) yield assert_equal, len(pipe._execgraph.nodes()), 8 yield assert_equal, len(pipe._execgraph.edges()), 8 edgenum = sorted([(len(pipe._execgraph.in_edges(node)) + \ len(pipe._execgraph.out_edges(node))) \ for node in pipe._execgraph.nodes()]) yield assert_true, edgenum[0]>0 def test_expansion(): pipe1 = pe.Workflow(name='pipe1') mod1 = pe.Node(interface=TestInterface(),name='mod1') mod2 = pe.Node(interface=TestInterface(),name='mod2') pipe1.connect([(mod1,mod2,[('output1','input2')])]) pipe2 = pe.Workflow(name='pipe2') mod3 = pe.Node(interface=TestInterface(),name='mod3') mod4 = pe.Node(interface=TestInterface(),name='mod4') pipe2.connect([(mod3,mod4,[('output1','input2')])]) pipe3 = pe.Workflow(name="pipe3") pipe3.connect([(pipe1, pipe2, [('mod2.output1','mod4.input1')])]) pipe4 = pe.Workflow(name="pipe4") mod5 = pe.Node(interface=TestInterface(),name='mod5') pipe4.add_nodes([mod5]) pipe5 = pe.Workflow(name="pipe5") pipe5.add_nodes([pipe4]) pipe6 = pe.Workflow(name="pipe6") pipe6.connect([(pipe5, pipe3, [('pipe4.mod5.output1','pipe2.mod3.input1')])]) error_raised = False try: pipe6._flatgraph = pipe6._create_flat_graph() except: error_raised = True yield assert_false, error_raised def test_iterable_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node2 = pe.Node(TestInterface(),name='node2') node1.iterables = ('input1',[1,2]) wf1.connect(node1,'output1', node2, 'input2') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()),12 def test_synchronize_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node1.iterables = [('input1',[1,2]),('input2',[3,4,5])] node1.synchronize = True node2 = pe.Node(TestInterface(),name='node2') wf1.connect(node1,'output1', node2, 'input2') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() # Each expanded graph clone has: # 3 node1 expansion nodes and # 1 node2 replicate per node1 replicate # => 2 * 3 = 6 nodes per expanded subgraph # => 18 nodes in the group yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()), 18 def test_synchronize_tuples_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node2 = pe.Node(TestInterface(),name='node2') node1.iterables = [('input1','input2'), [(1,3), (2,4), (None,5)]] node1.synchronize = True wf1.connect(node1,'output1', node2, 'input2') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() # Identical to test_synchronize_expansion yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()), 18 def test_itersource_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node1.iterables = ('input1',[1,2]) node2 = pe.Node(TestInterface(),name='node2') wf1.connect(node1,'output1', node2, 'input1') node3 = pe.Node(TestInterface(),name='node3') node3.itersource = ('node1', 'input1') node3.iterables = [('input1', {1:[3,4], 2:[5,6,7]})] wf1.connect(node2,'output1', node3, 'input1') node4 = pe.Node(TestInterface(),name='node4') wf1.connect(node3,'output1', node4, 'input1') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() # each expanded graph clone has: # 2 node1 expansion nodes, # 1 node2 per node1 replicate, # 2 node3 replicates for the node1 input1 value 1, # 3 node3 replicates for the node1 input1 value 2 and # 1 node4 successor per node3 replicate # => 2 + 2 + (2 + 3) + 5 = 14 nodes per expanded graph clone # => 3 * 14 = 42 nodes in the group yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()), 42 def test_itersource_synchronize1_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node1.iterables = [('input1',[1,2]), ('input2',[3,4])] node1.synchronize = True node2 = pe.Node(TestInterface(),name='node2') wf1.connect(node1,'output1', node2, 'input1') node3 = pe.Node(TestInterface(),name='node3') node3.itersource = ('node1', ['input1', 'input2']) node3.iterables = [('input1', {(1,3):[5,6]}), ('input2', {(1,3):[7,8], (2,4): [9]})] wf1.connect(node2,'output1', node3, 'input1') node4 = pe.Node(TestInterface(),name='node4') wf1.connect(node3,'output1', node4, 'input1') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() # each expanded graph clone has: # 2 node1 expansion nodes, # 1 node2 per node1 replicate, # 2 node3 replicates for the node1 input1 value 1, # 3 node3 replicates for the node1 input1 value 2 and # 1 node4 successor per node3 replicate # => 2 + 2 + (2 + 3) + 5 = 14 nodes per expanded graph clone # => 3 * 14 = 42 nodes in the group yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()), 42 def test_itersource_synchronize2_expansion(): import nipype.pipeline.engine as pe wf1 = pe.Workflow(name='test') node1 = pe.Node(TestInterface(),name='node1') node1.iterables = [('input1',[1,2]), ('input2',[3,4])] node1.synchronize = True node2 = pe.Node(TestInterface(),name='node2') wf1.connect(node1,'output1', node2, 'input1') node3 = pe.Node(TestInterface(),name='node3') node3.itersource = ('node1', ['input1', 'input2']) node3.synchronize = True node3.iterables = [('input1', 'input2'), {(1,3):[(5,7), (6,8)], (2,4):[(None,9)]}] wf1.connect(node2,'output1', node3, 'input1') node4 = pe.Node(TestInterface(),name='node4') wf1.connect(node3,'output1', node4, 'input1') wf3 = pe.Workflow(name='group') for i in [0,1,2]: wf3.add_nodes([wf1.clone(name='test%d'%i)]) wf3._flatgraph = wf3._create_flat_graph() # each expanded graph clone has: # 2 node1 expansion nodes, # 1 node2 per node1 replicate, # 2 node3 replicates for the node1 input1 value 1, # 1 node3 replicates for the node1 input1 value 2 and # 1 node4 successor per node3 replicate # => 2 + 2 + (2 + 1) + 3 = 10 nodes per expanded graph clone # => 3 * 10 = 30 nodes in the group yield assert_equal, len(pe.generate_expanded_graph(wf3._flatgraph).nodes()), 30 def test_disconnect(): import nipype.pipeline.engine as pe from nipype.interfaces.utility import IdentityInterface a = pe.Node(IdentityInterface(fields=['a','b']),name='a') b = pe.Node(IdentityInterface(fields=['a','b']),name='b') flow1 = pe.Workflow(name='test') flow1.connect(a,'a',b,'a') flow1.disconnect(a,'a',b,'a') yield assert_equal, flow1._graph.edges(), [] def test_doubleconnect(): import nipype.pipeline.engine as pe from nipype.interfaces.utility import IdentityInterface a = pe.Node(IdentityInterface(fields=['a','b']),name='a') b = pe.Node(IdentityInterface(fields=['a','b']),name='b') flow1 = pe.Workflow(name='test') flow1.connect(a,'a',b,'a') x = lambda: flow1.connect(a,'b',b,'a') yield assert_raises, Exception, x c = pe.Node(IdentityInterface(fields=['a','b']),name='c') flow1 = pe.Workflow(name='test2') x = lambda : flow1.connect([(a, c, [('b', 'b')]), (b, c, [('a', 'b')])]) yield assert_raises, Exception, x ''' Test for order of iterables import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu wf1 = pe.Workflow(name='wf1') node1 = pe.Node(interface=niu.IdentityInterface(fields=['a1','b1']), name='node1') node1.iterables = ('a1', [1,2]) wf1.add_nodes([node1]) wf2 = pe.Workflow(name='wf2') node2 = pe.Node(interface=niu.IdentityInterface(fields=['a2','b2']), name='node2') wf2.add_nodes([node2]) wf1.connect(node1, 'a1', wf2, 'node2.a2') node4 = pe.Node(interface=niu.IdentityInterface(fields=['a4','b4']), name='node4') #node4.iterables = ('a4', [5,6]) wf2.connect(node2, 'b2', node4, 'b4') wf3 = pe.Workflow(name='wf3') node3 = pe.Node(interface=niu.IdentityInterface(fields=['a3','b3']), name='node3') node3.iterables = ('b3', [3,4]) wf3.add_nodes([node3]) wf1.connect(wf3, 'node3.b3', wf2, 'node2.b2') wf1.base_dir = os.path.join(os.getcwd(),'testit') wf1.run(inseries=True, createdirsonly=True) wf1.write_graph(graph2use='exec') ''' ''' import nipype.pipeline.engine as pe import nipype.interfaces.spm as spm import os from nipype.utils.config import config from StringIO import StringIO config.readfp(StringIO(""" [execution] remove_unnecessary_outputs = true """)) segment = pe.Node(interface=spm.Segment(), name="segment") segment.inputs.data = os.path.abspath("data/T1.nii") segment.inputs.gm_output_type = [True, True, True] segment.inputs.wm_output_type = [True, True, True] smooth_gm = pe.Node(interface=spm.Smooth(), name="smooth_gm") workflow = pe.Workflow(name="workflow_cleanup_test") workflow.base_dir = os.path.abspath('./workflow_cleanup_test') workflow.connect([(segment, smooth_gm, [('native_gm_image','in_files')])]) workflow.run() #adding new node that uses one of the previously deleted outputs of segment; this should force segment to rerun smooth_wm = pe.Node(interface=spm.Smooth(), name="smooth_wm") workflow.connect([(segment, smooth_wm, [('native_wm_image','in_files')])]) workflow.run() workflow.run() ''' # Node def test_node_init(): yield assert_raises, Exception, pe.Node try: node = pe.Node(TestInterface, name='test') except IOError: exception = True else: exception = False yield assert_true, exception def test_workflow_add(): from nipype.interfaces.utility import IdentityInterface as ii n1 = pe.Node(ii(fields=['a','b']),name='n1') n2 = pe.Node(ii(fields=['c','d']),name='n2') n3 = pe.Node(ii(fields=['c','d']),name='n1') w1 = pe.Workflow(name='test') w1.connect(n1,'a',n2,'c') yield assert_raises, IOError, w1.add_nodes, [n1] yield assert_raises, IOError, w1.add_nodes, [n2] yield assert_raises, IOError, w1.add_nodes, [n3] yield assert_raises, IOError, w1.connect, [(w1,n2,[('n1.a','d')])] def test_node_get_output(): mod1 = pe.Node(interface=TestInterface(),name='mod1') mod1.inputs.input1 = 1 mod1.run() yield assert_equal, mod1.get_output('output1'), [1, 1] mod1._result = None yield assert_equal, mod1.get_output('output1'), [1, 1] def test_mapnode_iterfield_check(): mod1 = pe.MapNode(TestInterface(), iterfield=['input1'], name='mod1') yield assert_raises, ValueError, mod1._check_iterfield mod1 = pe.MapNode(TestInterface(), iterfield=['input1', 'input2'], name='mod1') mod1.inputs.input1 = [1,2] mod1.inputs.input2 = 3 yield assert_raises, ValueError, mod1._check_iterfield def test_mapnode_nested(): cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) from nipype import MapNode, Function def func1(in1): return in1 + 1 n1 = MapNode(Function(input_names=['in1'], output_names=['out'], function=func1), iterfield=['in1'], nested=True, name='n1') n1.inputs.in1 = [[1,[2]],3,[4,5]] n1.run() print n1.get_output('out') yield assert_equal, n1.get_output('out'), [[2,[3]],4,[5,6]] n2 = MapNode(Function(input_names=['in1'], output_names=['out'], function=func1), iterfield=['in1'], nested=False, name='n1') n2.inputs.in1 = [[1,[2]],3,[4,5]] error_raised = False try: n2.run() except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_true, error_raised def test_node_hash(): cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) from nipype.interfaces.utility import Function def func1(): return 1 def func2(a): return a+1 n1 = pe.Node(Function(input_names=[], output_names=['a'], function=func1), name='n1') n2 = pe.Node(Function(input_names=['a'], output_names=['b'], function=func2), name='n2') w1 = pe.Workflow(name='test') modify = lambda x: x+1 n1.inputs.a = 1 w1.connect(n1, ('a', modify), n2,'a') w1.base_dir = wd # generate outputs w1.run(plugin='Linear') # ensure plugin is being called w1.config['execution'] = {'stop_on_first_crash': 'true', 'local_hash_check': 'false', 'crashdump_dir': wd} error_raised = False # create dummy distributed plugin class from nipype.pipeline.plugins.base import DistributedPluginBase class RaiseError(DistributedPluginBase): def _submit_job(self, node, updatehash=False): raise Exception('Submit called') try: w1.run(plugin=RaiseError()) except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_true, error_raised #yield assert_true, 'Submit called' in e # rerun to ensure we have outputs w1.run(plugin='Linear') # set local check w1.config['execution'] = {'stop_on_first_crash': 'true', 'local_hash_check': 'true', 'crashdump_dir': wd} error_raised = False try: w1.run(plugin=RaiseError()) except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_false, error_raised os.chdir(cwd) rmtree(wd) def test_old_config(): cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) from nipype.interfaces.utility import Function def func1(): return 1 def func2(a): return a+1 n1 = pe.Node(Function(input_names=[], output_names=['a'], function=func1), name='n1') n2 = pe.Node(Function(input_names=['a'], output_names=['b'], function=func2), name='n2') w1 = pe.Workflow(name='test') modify = lambda x: x+1 n1.inputs.a = 1 w1.connect(n1, ('a', modify), n2,'a') w1.base_dir = wd w1.config['execution']['crashdump_dir'] = wd # generate outputs error_raised = False try: w1.run(plugin='Linear') except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_false, error_raised os.chdir(cwd) rmtree(wd) def test_mapnode_json(): """Tests that mapnodes don't generate excess jsons """ cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) from nipype import MapNode, Function, Workflow def func1(in1): return in1 + 1 n1 = MapNode(Function(input_names=['in1'], output_names=['out'], function=func1), iterfield=['in1'], name='n1') n1.inputs.in1 = [1] w1 = Workflow(name='test') w1.base_dir = wd w1.config['execution']['crashdump_dir'] = wd w1.add_nodes([n1]) w1.run() n1.inputs.in1 = [2] w1.run() # should rerun n1.inputs.in1 = [1] eg = w1.run() node = eg.nodes()[0] outjson = glob(os.path.join(node.output_dir(), '_0x*.json')) yield assert_equal, len(outjson), 1 # check that multiple json's don't trigger rerun with open(os.path.join(node.output_dir(), 'test.json'), 'wt') as fp: fp.write('dummy file') w1.config['execution'].update(**{'stop_on_first_rerun': True}) error_raised = False try: w1.run() except: error_raised = True yield assert_false, error_raised os.chdir(cwd) rmtree(wd) def test_serial_input(): cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) from nipype import MapNode, Function, Workflow def func1(in1): return in1 n1 = MapNode(Function(input_names=['in1'], output_names=['out'], function=func1), iterfield=['in1'], name='n1') n1.inputs.in1 = [1,2,3] w1 = Workflow(name='test') w1.base_dir = wd w1.add_nodes([n1]) # set local check w1.config['execution'] = {'stop_on_first_crash': 'true', 'local_hash_check': 'true', 'crashdump_dir': wd, 'poll_sleep_duration': 2} # test output of num_subnodes method when serial is default (False) yield assert_equal, n1.num_subnodes(), len(n1.inputs.in1) # test running the workflow on default conditions error_raised = False try: w1.run(plugin='MultiProc') except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_false, error_raised # test output of num_subnodes method when serial is True n1._serial=True yield assert_equal, n1.num_subnodes(), 1 # test running the workflow on serial conditions error_raised = False try: w1.run(plugin='MultiProc') except Exception, e: pe.logger.info('Exception: %s' % str(e)) error_raised = True yield assert_false, error_raised os.chdir(cwd) rmtree(wd) nipype-0.11.0/nipype/pipeline/tests/test_join.py000066400000000000000000000511431257611314500217310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Tests for join expansion """ from copy import deepcopy import os from shutil import rmtree from tempfile import mkdtemp import networkx as nx from nipype.testing import (assert_equal, assert_true) import nipype.interfaces.base as nib import nipype.pipeline.engine as pe from nipype.interfaces.utility import IdentityInterface from nipype.interfaces.base import traits, File class PickFirstSpec(nib.TraitedSpec): in_files = traits.List(File(exists=True), argstr="%s", position=2, mandatory=True) class PickFirstOutSpec(nib.TraitedSpec): output1 = File(exists=True) class PickFirst(nib.BaseInterface): input_spec = PickFirstSpec output_spec = PickFirstOutSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = self.inputs.in_files[0] return outputs class IncrementInputSpec(nib.TraitedSpec): input1 = nib.traits.Int(mandatory=True, desc='input') inc = nib.traits.Int(usedefault=True, default_value=1, desc='increment') class IncrementOutputSpec(nib.TraitedSpec): output1 = nib.traits.Int(desc='ouput') class IncrementInterface(nib.BaseInterface): input_spec = IncrementInputSpec output_spec = IncrementOutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = self.inputs.input1 + self.inputs.inc return outputs _sums = [] _sum_operands = [] class SumInputSpec(nib.TraitedSpec): input1 = nib.traits.List(nib.traits.Int, mandatory=True, desc='input') class SumOutputSpec(nib.TraitedSpec): output1 = nib.traits.Int(desc='ouput') operands = nib.traits.List(nib.traits.Int, desc='operands') class SumInterface(nib.BaseInterface): input_spec = SumInputSpec output_spec = SumOutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): global _sum global _sum_operands outputs = self._outputs().get() outputs['operands'] = self.inputs.input1 _sum_operands.append(outputs['operands']) outputs['output1'] = sum(self.inputs.input1) _sums.append(outputs['output1']) return outputs _set_len = None """The Set interface execution result.""" class SetInputSpec(nib.TraitedSpec): input1 = nib.traits.Set(nib.traits.Int, mandatory=True, desc='input') class SetOutputSpec(nib.TraitedSpec): output1 = nib.traits.Int(desc='ouput') class SetInterface(nib.BaseInterface): input_spec = SetInputSpec output_spec = SetOutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): global _set_len outputs = self._outputs().get() _set_len = outputs['output1'] = len(self.inputs.input1) return outputs _products = [] """The Products interface execution results.""" class ProductInputSpec(nib.TraitedSpec): input1 = nib.traits.Int(mandatory=True, desc='input1') input2 = nib.traits.Int(mandatory=True, desc='input2') class ProductOutputSpec(nib.TraitedSpec): output1 = nib.traits.Int(mandatory=True, desc='output') class ProductInterface(nib.BaseInterface): input_spec = ProductInputSpec output_spec = ProductOutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): global _products outputs = self._outputs().get() outputs['output1'] = self.inputs.input1 * self.inputs.input2 _products.append(outputs['output1']) return outputs def test_join_expansion(): cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2])] # a pre-join node in the iterated path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # another pre-join node in the iterated path pre_join2 = pe.Node(IncrementInterface(), name='pre_join2') wf.connect(pre_join1, 'output1', pre_join2, 'input1') # the join node join = pe.JoinNode(SumInterface(), joinsource='inputspec', joinfield='input1', name='join') wf.connect(pre_join2, 'output1', join, 'input1') # an uniterated post-join node post_join1 = pe.Node(IncrementInterface(), name='post_join1') wf.connect(join, 'output1', post_join1, 'input1') # a post-join node in the iterated path post_join2 = pe.Node(ProductInterface(), name='post_join2') wf.connect(join, 'output1', post_join2, 'input1') wf.connect(pre_join1, 'output1', post_join2, 'input2') result = wf.run() # the two expanded pre-join predecessor nodes feed into one join node joins = [node for node in result.nodes() if node.name == 'join'] assert_equal(len(joins), 1, "The number of join result nodes is incorrect.") # the expanded graph contains 2 * 2 = 4 iteration pre-join nodes, 1 join # node, 1 non-iterated post-join node and 2 * 1 iteration post-join nodes. # Nipype factors away the IdentityInterface. assert_equal(len(result.nodes()), 8, "The number of expanded nodes is incorrect.") # the join Sum result is (1 + 1 + 1) + (2 + 1 + 1) assert_equal(len(_sums), 1, "The number of join outputs is incorrect") assert_equal(_sums[0], 7, "The join Sum output value is incorrect: %s." % _sums[0]) # the join input preserves the iterables input order assert_equal(_sum_operands[0], [3, 4], "The join Sum input is incorrect: %s." % _sum_operands[0]) # there are two iterations of the post-join node in the iterable path assert_equal(len(_products), 2, "The number of iterated post-join outputs is incorrect") os.chdir(cwd) rmtree(wd) def test_node_joinsource(): """Test setting the joinsource to a Node.""" cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2])] # the join node join = pe.JoinNode(SetInterface(), joinsource=inputspec, joinfield='input1', name='join') # the joinsource is the inputspec name assert_equal(join.joinsource, inputspec.name, "The joinsource is not set to the node name.") os.chdir(cwd) rmtree(wd) def test_set_join_node(): """Test collecting join inputs to a set.""" cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2, 1, 3, 2])] # a pre-join node in the iterated path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # the set join node join = pe.JoinNode(SetInterface(), joinsource='inputspec', joinfield='input1', name='join') wf.connect(pre_join1, 'output1', join, 'input1') wf.run() # the join length is the number of unique inputs assert_equal(_set_len, 3, "The join Set output value is incorrect: %s." % _set_len) os.chdir(cwd) rmtree(wd) def test_unique_join_node(): """Test join with the ``unique`` flag set to True.""" global _sum_operands _sum_operands = [] cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [3, 1, 2, 1, 3])] # a pre-join node in the iterated path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # the set join node join = pe.JoinNode(SumInterface(), joinsource='inputspec', joinfield='input1', unique=True, name='join') wf.connect(pre_join1, 'output1', join, 'input1') wf.run() assert_equal(_sum_operands[0], [4, 2, 3], "The unique join output value is incorrect: %s." % _sum_operands[0]) os.chdir(cwd) rmtree(wd) def test_multiple_join_nodes(): """Test two join nodes, one downstream of the other.""" global _products _products = [] cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2, 3])] # a pre-join node in the iterated path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # the first join node join1 = pe.JoinNode(IdentityInterface(fields=['vector']), joinsource='inputspec', joinfield='vector', name='join1') wf.connect(pre_join1, 'output1', join1, 'vector') # an uniterated post-join node post_join1 = pe.Node(SumInterface(), name='post_join1') wf.connect(join1, 'vector', post_join1, 'input1') # the downstream join node connected to both an upstream join # path output and a separate input in the iterated path join2 = pe.JoinNode(IdentityInterface(fields=['vector', 'scalar']), joinsource='inputspec', joinfield='vector', name='join2') wf.connect(pre_join1, 'output1', join2, 'vector') wf.connect(post_join1, 'output1', join2, 'scalar') # a second post-join node post_join2 = pe.Node(SumInterface(), name='post_join2') wf.connect(join2, 'vector', post_join2, 'input1') # a third post-join node post_join3 = pe.Node(ProductInterface(), name='post_join3') wf.connect(post_join2, 'output1', post_join3, 'input1') wf.connect(join2, 'scalar', post_join3, 'input2') result = wf.run() # The expanded graph contains one pre_join1 replicate per inputspec # replicate and one of each remaining node = 3 + 5 = 8 nodes. # The replicated inputspec nodes are factored out of the expansion. assert_equal(len(result.nodes()), 8, "The number of expanded nodes is incorrect.") # The outputs are: # pre_join1: [2, 3, 4] # post_join1: 9 # join2: [2, 3, 4] and 9 # post_join2: 9 # post_join3: 9 * 9 = 81 assert_equal(_products, [81], "The post-join product is incorrect") os.chdir(cwd) rmtree(wd) def test_identity_join_node(): """Test an IdentityInterface join.""" global _sum_operands _sum_operands = [] cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2, 3])] # a pre-join node in the iterated path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # the IdentityInterface join node join = pe.JoinNode(IdentityInterface(fields=['vector']), joinsource='inputspec', joinfield='vector', name='join') wf.connect(pre_join1, 'output1', join, 'vector') # an uniterated post-join node post_join1 = pe.Node(SumInterface(), name='post_join1') wf.connect(join, 'vector', post_join1, 'input1') result = wf.run() # the expanded graph contains 1 * 3 iteration pre-join nodes, 1 join # node and 1 post-join node. Nipype factors away the iterable input # IdentityInterface but keeps the join IdentityInterface. assert_equal(len(result.nodes()), 5, "The number of expanded nodes is incorrect.") assert_equal(_sum_operands[0], [2, 3, 4], "The join Sum input is incorrect: %s." %_sum_operands[0]) os.chdir(cwd) rmtree(wd) def test_multifield_join_node(): """Test join on several fields.""" global _products _products = [] cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['m', 'n']), name='inputspec') inputspec.iterables = [('m', [1, 2]), ('n', [3, 4])] # two pre-join nodes in a parallel iterated path inc1 = pe.Node(IncrementInterface(), name='inc1') wf.connect(inputspec, 'm', inc1, 'input1') inc2 = pe.Node(IncrementInterface(), name='inc2') wf.connect(inputspec, 'n', inc2, 'input1') # the join node join = pe.JoinNode(IdentityInterface(fields=['vector1', 'vector2']), joinsource='inputspec', name='join') wf.connect(inc1, 'output1', join, 'vector1') wf.connect(inc2, 'output1', join, 'vector2') # a post-join node prod = pe.MapNode(ProductInterface(), name='prod', iterfield=['input1', 'input2']) wf.connect(join, 'vector1', prod, 'input1') wf.connect(join, 'vector2', prod, 'input2') result = wf.run() # the iterables are expanded as the cartesian product of the iterables values. # thus, the expanded graph contains 2 * (2 * 2) iteration pre-join nodes, 1 join # node and 1 post-join node. assert_equal(len(result.nodes()), 10, "The number of expanded nodes is incorrect.") # the product inputs are [2, 4], [2, 5], [3, 4], [3, 5] assert_equal(_products, [8, 10, 12, 15], "The post-join products is incorrect: %s." % _products) os.chdir(cwd) rmtree(wd) def test_synchronize_join_node(): """Test join on an input node which has the ``synchronize`` flag set to True.""" global _products _products = [] cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['m', 'n']), name='inputspec') inputspec.iterables = [('m', [1, 2]), ('n', [3, 4])] inputspec.synchronize = True # two pre-join nodes in a parallel iterated path inc1 = pe.Node(IncrementInterface(), name='inc1') wf.connect(inputspec, 'm', inc1, 'input1') inc2 = pe.Node(IncrementInterface(), name='inc2') wf.connect(inputspec, 'n', inc2, 'input1') # the join node join = pe.JoinNode(IdentityInterface(fields=['vector1', 'vector2']), joinsource='inputspec', name='join') wf.connect(inc1, 'output1', join, 'vector1') wf.connect(inc2, 'output1', join, 'vector2') # a post-join node prod = pe.MapNode(ProductInterface(), name='prod', iterfield=['input1', 'input2']) wf.connect(join, 'vector1', prod, 'input1') wf.connect(join, 'vector2', prod, 'input2') result = wf.run() # there are 3 iterables expansions. # thus, the expanded graph contains 2 * 2 iteration pre-join nodes, 1 join # node and 1 post-join node. assert_equal(len(result.nodes()), 6, "The number of expanded nodes is incorrect.") # the product inputs are [2, 3] and [4, 5] assert_equal(_products, [8, 15], "The post-join products is incorrect: %s." % _products) os.chdir(cwd) rmtree(wd) def test_itersource_join_source_node(): """Test join on an input node which has an ``itersource``.""" cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2])] # an intermediate node in the first iteration path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # an iterable pre-join node with an itersource pre_join2 = pe.Node(ProductInterface(), name='pre_join2') pre_join2.itersource = ('inputspec', 'n') pre_join2.iterables = ('input1', {1: [3, 4], 2: [5, 6]}) wf.connect(pre_join1, 'output1', pre_join2, 'input2') # an intermediate node in the second iteration path pre_join3 = pe.Node(IncrementInterface(), name='pre_join3') wf.connect(pre_join2, 'output1', pre_join3, 'input1') # the join node join = pe.JoinNode(IdentityInterface(fields=['vector']), joinsource='pre_join2', joinfield='vector', name='join') wf.connect(pre_join3, 'output1', join, 'vector') # a join successor node post_join1 = pe.Node(SumInterface(), name='post_join1') wf.connect(join, 'vector', post_join1, 'input1') result = wf.run() # the expanded graph contains # 1 pre_join1 replicate for each inputspec iteration, # 2 pre_join2 replicates for each inputspec iteration, # 1 pre_join3 for each pre_join2 iteration, # 1 join replicate for each inputspec iteration and # 1 post_join1 replicate for each join replicate = # 2 + (2 * 2) + 4 + 2 + 2 = 14 expansion graph nodes. # Nipype factors away the iterable input # IdentityInterface but keeps the join IdentityInterface. assert_equal(len(result.nodes()), 14, "The number of expanded nodes is incorrect.") # The first join inputs are: # 1 + (3 * 2) and 1 + (4 * 2) # The second join inputs are: # 1 + (5 * 3) and 1 + (6 * 3) # the post-join nodes execution order is indeterminate; # therefore, compare the lists item-wise. assert_true([16, 19] in _sum_operands, "The join Sum input is incorrect: %s." % _sum_operands) assert_true([7, 9] in _sum_operands, "The join Sum input is incorrect: %s." % _sum_operands) os.chdir(cwd) rmtree(wd) def test_itersource_two_join_nodes(): """Test join with a midstream ``itersource`` and an upstream iterable.""" cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [1, 2])] # an intermediate node in the first iteration path pre_join1 = pe.Node(IncrementInterface(), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'input1') # an iterable pre-join node with an itersource pre_join2 = pe.Node(ProductInterface(), name='pre_join2') pre_join2.itersource = ('inputspec', 'n') pre_join2.iterables = ('input1', {1: [3, 4], 2: [5, 6]}) wf.connect(pre_join1, 'output1', pre_join2, 'input2') # an intermediate node in the second iteration path pre_join3 = pe.Node(IncrementInterface(), name='pre_join3') wf.connect(pre_join2, 'output1', pre_join3, 'input1') # the first join node join1 = pe.JoinNode(IdentityInterface(fields=['vector']), joinsource='pre_join2', joinfield='vector', name='join1') wf.connect(pre_join3, 'output1', join1, 'vector') # a join successor node post_join1 = pe.Node(SumInterface(), name='post_join1') wf.connect(join1, 'vector', post_join1, 'input1') # a summary join node join2 = pe.JoinNode(IdentityInterface(fields=['vector']), joinsource='inputspec', joinfield='vector', name='join2') wf.connect(post_join1, 'output1', join2, 'vector') result = wf.run() # the expanded graph contains the 14 test_itersource_join_source_node # nodes plus the summary join node. assert_equal(len(result.nodes()), 15, "The number of expanded nodes is incorrect.") os.chdir(cwd) rmtree(wd) def test_set_join_node_file_input(): """Test collecting join inputs to a set.""" cwd = os.getcwd() wd = mkdtemp() os.chdir(wd) open('test.nii', 'w+').close() open('test2.nii', 'w+').close() # Make the workflow. wf = pe.Workflow(name='test') # the iterated input node inputspec = pe.Node(IdentityInterface(fields=['n']), name='inputspec') inputspec.iterables = [('n', [os.path.join(wd, 'test.nii'), os.path.join(wd, 'test2.nii')])] # a pre-join node in the iterated path pre_join1 = pe.Node(IdentityInterface(fields=['n']), name='pre_join1') wf.connect(inputspec, 'n', pre_join1, 'n') # the set join node join = pe.JoinNode(PickFirst(), joinsource='inputspec', joinfield='in_files', name='join') wf.connect(pre_join1, 'n', join, 'in_files') wf.run() os.chdir(cwd) rmtree(wd) if __name__ == "__main__": import nose nose.main(defaultTest=__name__) nipype-0.11.0/nipype/pipeline/tests/test_utils.py000066400000000000000000000316301257611314500221310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Tests for the engine utils module """ import os from copy import deepcopy from tempfile import mkdtemp from shutil import rmtree from ...testing import (assert_equal, assert_true, assert_false) import nipype.pipeline.engine as pe import nipype.interfaces.base as nib import nipype.interfaces.utility as niu from ... import config from ..utils import merge_dict, clean_working_directory def test_identitynode_removal(): def test_function(arg1, arg2, arg3): import numpy as np return (np.array(arg1) + arg2 + arg3).tolist() wf = pe.Workflow(name="testidentity") n1 = pe.Node(niu.IdentityInterface(fields=['a', 'b']), name='src') n1.iterables = ('b', [0, 1, 2, 3]) n1.inputs.a = [0, 1, 2, 3] n2 = pe.Node(niu.Select(), name='selector') wf.connect(n1, ('a', test_function, 1, -1), n2, 'inlist') wf.connect(n1, 'b', n2, 'index') n3 = pe.Node(niu.IdentityInterface(fields=['c', 'd']), name='passer') n3.inputs.c = [1, 2, 3, 4] wf.connect(n2, 'out', n3, 'd') n4 = pe.Node(niu.Select(), name='selector2') wf.connect(n3, ('c', test_function, 1, -1), n4, 'inlist') wf.connect(n3, 'd', n4, 'index') fg = wf._create_flat_graph() wf._set_needed_outputs(fg) eg = pe.generate_expanded_graph(deepcopy(fg)) yield assert_equal, len(eg.nodes()), 8 def test_clean_working_directory(): class OutputSpec(nib.TraitedSpec): files = nib.traits.List(nib.File) others = nib.File() class InputSpec(nib.TraitedSpec): infile = nib.File() outputs = OutputSpec() inputs = InputSpec() wd = mkdtemp() filenames = ['file.hdr', 'file.img', 'file.BRIK', 'file.HEAD', '_0x1234.json', 'foo.txt'] outfiles = [] for filename in filenames: outfile = os.path.join(wd, filename) with open(outfile, 'wt') as fp: fp.writelines('dummy') outfiles.append(outfile) outputs.files = outfiles[:4:2] outputs.others = outfiles[5] inputs.infile = outfiles[-1] needed_outputs = ['files'] config.set_default_config() yield assert_true, os.path.exists(outfiles[5]) config.set_default_config() config.set('execution', 'remove_unnecessary_outputs', False) out = clean_working_directory(outputs, wd, inputs, needed_outputs, deepcopy(config._sections)) yield assert_true, os.path.exists(outfiles[5]) yield assert_equal, out.others, outfiles[5] config.set('execution', 'remove_unnecessary_outputs', True) out = clean_working_directory(outputs, wd, inputs, needed_outputs, deepcopy(config._sections)) yield assert_true, os.path.exists(outfiles[1]) yield assert_true, os.path.exists(outfiles[3]) yield assert_true, os.path.exists(outfiles[4]) yield assert_false, os.path.exists(outfiles[5]) yield assert_equal, out.others, nib.Undefined yield assert_equal, len(out.files), 2 config.set_default_config() rmtree(wd) def test_outputs_removal(): def test_function(arg1): import os file1 = os.path.join(os.getcwd(), 'file1.txt') file2 = os.path.join(os.getcwd(), 'file2.txt') fp = open(file1, 'wt') fp.write('%d' % arg1) fp.close() fp = open(file2, 'wt') fp.write('%d' % arg1) fp.close() return file1, file2 out_dir = mkdtemp() n1 = pe.Node(niu.Function(input_names=['arg1'], output_names=['file1', 'file2'], function=test_function), base_dir=out_dir, name='testoutputs') n1.inputs.arg1 = 1 n1.config = {'execution': {'remove_unnecessary_outputs': True}} n1.config = merge_dict(deepcopy(config._sections), n1.config) n1.run() yield assert_true, os.path.exists(os.path.join(out_dir, n1.name, 'file1.txt')) yield assert_true, os.path.exists(os.path.join(out_dir, n1.name, 'file2.txt')) n1.needed_outputs = ['file2'] n1.run() yield assert_false, os.path.exists(os.path.join(out_dir, n1.name, 'file1.txt')) yield assert_true, os.path.exists(os.path.join(out_dir, n1.name, 'file2.txt')) rmtree(out_dir) class InputSpec(nib.TraitedSpec): in_file = nib.File(exists=True, copyfile=True) class OutputSpec(nib.TraitedSpec): output1 = nib.traits.List(nib.traits.Int, desc='outputs') class TestInterface(nib.BaseInterface): input_spec = InputSpec output_spec = OutputSpec def _run_interface(self, runtime): runtime.returncode = 0 return runtime def _list_outputs(self): outputs = self._outputs().get() outputs['output1'] = [1] return outputs def test_inputs_removal(): out_dir = mkdtemp() file1 = os.path.join(out_dir, 'file1.txt') fp = open(file1, 'wt') fp.write('dummy_file') fp.close() n1 = pe.Node(TestInterface(), base_dir=out_dir, name='testinputs') n1.inputs.in_file = file1 n1.config = {'execution': {'keep_inputs': True}} n1.config = merge_dict(deepcopy(config._sections), n1.config) n1.run() yield assert_true, os.path.exists(os.path.join(out_dir, n1.name, 'file1.txt')) n1.inputs.in_file = file1 n1.config = {'execution': {'keep_inputs': False}} n1.config = merge_dict(deepcopy(config._sections), n1.config) n1.overwrite = True n1.run() yield assert_false, os.path.exists(os.path.join(out_dir, n1.name, 'file1.txt')) rmtree(out_dir) def test_outputs_removal_wf(): def test_function(arg1): import os file1 = os.path.join(os.getcwd(), 'file1.txt') file2 = os.path.join(os.getcwd(), 'file2.txt') file3 = os.path.join(os.getcwd(), 'file3.txt') file4 = os.path.join(os.getcwd(), 'subdir', 'file1.txt') files = [file1, file2, file3, file4] os.mkdir("subdir") for filename in files: with open(filename, 'wt') as fp: fp.write('%d' % arg1) return file1, file2, os.path.join(os.getcwd(),"subdir") def test_function2(in_file, arg): import os in_arg = open(in_file).read() file1 = os.path.join(os.getcwd(), 'file1.txt') file2 = os.path.join(os.getcwd(), 'file2.txt') file3 = os.path.join(os.getcwd(), 'file3.txt') files = [file1, file2, file3] for filename in files: with open(filename, 'wt') as fp: fp.write('%d' % arg + in_arg) return file1, file2, 1 def test_function3(arg): import os return arg out_dir = mkdtemp() for plugin in ('Linear',):#, 'MultiProc'): n1 = pe.Node(niu.Function(input_names=['arg1'], output_names=['out_file1', 'out_file2', 'dir'], function=test_function), name='n1') n1.inputs.arg1 = 1 n2 = pe.Node(niu.Function(input_names=['in_file', 'arg'], output_names=['out_file1', 'out_file2', 'n'], function=test_function2), name='n2') n2.inputs.arg = 2 n3 = pe.Node(niu.Function(input_names=['arg'], output_names=['n'], function=test_function3), name='n3') wf = pe.Workflow(name="node_rem_test" + plugin, base_dir=out_dir) wf.connect(n1, "out_file1", n2, "in_file") wf.run(plugin='Linear') for remove_unnecessary_outputs in [True, False]: config.set_default_config() wf.config = {'execution': {'remove_unnecessary_outputs': remove_unnecessary_outputs}} rmtree(os.path.join(wf.base_dir, wf.name)) wf.run(plugin=plugin) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n1.name, 'file2.txt')) != remove_unnecessary_outputs yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n1.name, "subdir", 'file1.txt')) != remove_unnecessary_outputs yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n1.name, 'file1.txt')) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n1.name, 'file3.txt')) != remove_unnecessary_outputs yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n2.name, 'file1.txt')) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n2.name, 'file2.txt')) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n2.name, 'file3.txt')) != remove_unnecessary_outputs n4 = pe.Node(TestInterface(), name='n4') wf.connect(n2, "out_file1", n4, "in_file") def pick_first(l): return l[0] wf.connect(n4, ("output1", pick_first), n3, "arg") for remove_unnecessary_outputs in [True, False]: for keep_inputs in [True, False]: config.set_default_config() wf.config = {'execution': {'keep_inputs': keep_inputs, 'remove_unnecessary_outputs': remove_unnecessary_outputs}} rmtree(os.path.join(wf.base_dir, wf.name)) wf.run(plugin=plugin) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n2.name, 'file1.txt')) yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n2.name, 'file2.txt')) != remove_unnecessary_outputs yield assert_true, os.path.exists(os.path.join(wf.base_dir, wf.name, n4.name, 'file1.txt')) == keep_inputs rmtree(out_dir) def fwhm(fwhm): return fwhm def create_wf(name): pipe = pe.Workflow(name=name) process = pe.Node(niu.Function(input_names=['fwhm'], output_names=['fwhm'], function=fwhm), name='proc') process.iterables = ('fwhm', [0]) process2 = pe.Node(niu.Function(input_names=['fwhm'], output_names=['fwhm'], function=fwhm), name='proc2') process2.iterables = ('fwhm', [0]) pipe.connect(process, 'fwhm', process2, 'fwhm') return pipe def test_multi_disconnected_iterable(): out_dir = mkdtemp() metawf = pe.Workflow(name='meta') metawf.base_dir = out_dir metawf.add_nodes([create_wf('wf%d' % i) for i in range(30)]) eg = metawf.run(plugin='Linear') yield assert_equal, len(eg.nodes()), 60 rmtree(out_dir) nipype-0.11.0/nipype/pipeline/utils.py000066400000000000000000001326151257611314500177350ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Utility routines for workflow graphs """ from copy import deepcopy from glob import glob from collections import defaultdict import os import re import numpy as np from nipype.utils.misc import package_check from nipype.external import six package_check('networkx', '1.3') import networkx as nx from ..utils.filemanip import (fname_presuffix, FileNotFoundError, filename_to_list, get_related_files) from ..utils.misc import create_function_from_source, str2bool from ..interfaces.base import (CommandLine, isdefined, Undefined, InterfaceResult) from ..interfaces.utility import IdentityInterface from ..utils.provenance import ProvStore, pm, nipype_ns, get_id from .. import logging, config logger = logging.getLogger('workflow') try: dfs_preorder = nx.dfs_preorder except AttributeError: dfs_preorder = nx.dfs_preorder_nodes logger.debug('networkx 1.4 dev or higher detected') try: from os.path import relpath except ImportError: import os.path as op def relpath(path, start=None): """Return a relative version of a path""" if start is None: start = os.curdir if not path: raise ValueError("no path specified") start_list = op.abspath(start).split(op.sep) path_list = op.abspath(path).split(op.sep) if start_list[0].lower() != path_list[0].lower(): unc_path, rest = op.splitunc(path) unc_start, rest = op.splitunc(start) if bool(unc_path) ^ bool(unc_start): raise ValueError(("Cannot mix UNC and non-UNC paths " "(%s and %s)") % (path, start)) else: raise ValueError("path is on drive %s, start on drive %s" % (path_list[0], start_list[0])) # Work out how much of the filepath is shared by start and path. for i in range(min(len(start_list), len(path_list))): if start_list[i].lower() != path_list[i].lower(): break else: i += 1 rel_list = [op.pardir] * (len(start_list) - i) + path_list[i:] if not rel_list: return os.curdir return op.join(*rel_list) def modify_paths(object, relative=True, basedir=None): """Convert paths in data structure to either full paths or relative paths Supports combinations of lists, dicts, tuples, strs Parameters ---------- relative : boolean indicating whether paths should be set relative to the current directory basedir : default os.getcwd() what base directory to use as default """ if not basedir: basedir = os.getcwd() if isinstance(object, dict): out = {} for key, val in sorted(object.items()): if isdefined(val): out[key] = modify_paths(val, relative=relative, basedir=basedir) elif isinstance(object, (list, tuple)): out = [] for val in object: if isdefined(val): out.append(modify_paths(val, relative=relative, basedir=basedir)) if isinstance(object, tuple): out = tuple(out) else: if isdefined(object): if isinstance(object, six.string_types) and os.path.isfile(object): if relative: if config.getboolean('execution', 'use_relative_paths'): out = relpath(object, start=basedir) else: out = object else: out = os.path.abspath(os.path.join(basedir, object)) if not os.path.exists(out): raise FileNotFoundError('File %s not found' % out) else: out = object return out def get_print_name(node, simple_form=True): """Get the name of the node For example, a node containing an instance of interfaces.fsl.BET would be called nodename.BET.fsl """ name = node.fullname if hasattr(node, '_interface'): pkglist = node._interface.__class__.__module__.split('.') interface = node._interface.__class__.__name__ destclass = '' if len(pkglist) > 2: destclass = '.%s' % pkglist[2] if simple_form: name = node.fullname + destclass else: name = '.'.join([node.fullname, interface]) + destclass if simple_form: parts = name.split('.') if len(parts) > 2: return ' ('.join(parts[1:])+')' elif len(parts) == 2: return parts[1] return name def _create_dot_graph(graph, show_connectinfo=False, simple_form=True): """Create a graph that can be pickled. Ensures that edge info is pickleable. """ logger.debug('creating dot graph') pklgraph = nx.DiGraph() for edge in graph.edges(): data = graph.get_edge_data(*edge) srcname = get_print_name(edge[0], simple_form=simple_form) destname = get_print_name(edge[1], simple_form=simple_form) if show_connectinfo: pklgraph.add_edge(srcname, destname, l=str(data['connect'])) else: pklgraph.add_edge(srcname, destname) return pklgraph def _write_detailed_dot(graph, dotfilename): """Create a dot file with connection info digraph structs { node [shape=record]; struct1 [label=" left| mid\ dle| right"]; struct2 [label=" one| two"]; struct3 [label="hello\nworld |{ b |{c| d|e}| f}| g | h"]; struct1:f1 -> struct2:f0; struct1:f0 -> struct2:f1; struct1:f2 -> struct3:here; } """ text = ['digraph structs {', 'node [shape=record];'] # write nodes edges = [] replacefunk = lambda x: x.replace('_', '').replace('.', ''). \ replace('@', '').replace('-', '') for n in nx.topological_sort(graph): nodename = str(n) inports = [] for u, v, d in graph.in_edges_iter(nbunch=n, data=True): for cd in d['connect']: if isinstance(cd[0], six.string_types): outport = cd[0] else: outport = cd[0][0] inport = cd[1] ipstrip = 'in' + replacefunk(inport) opstrip = 'out' + replacefunk(outport) edges.append('%s:%s:e -> %s:%s:w;' % (str(u).replace('.', ''), opstrip, str(v).replace('.', ''), ipstrip)) if inport not in inports: inports.append(inport) inputstr = '{IN' for ip in sorted(inports): inputstr += '| %s' % (replacefunk(ip), ip) inputstr += '}' outports = [] for u, v, d in graph.out_edges_iter(nbunch=n, data=True): for cd in d['connect']: if isinstance(cd[0], six.string_types): outport = cd[0] else: outport = cd[0][0] if outport not in outports: outports.append(outport) outputstr = '{OUT' for op in sorted(outports): outputstr += '| %s' % (replacefunk(op), op) outputstr += '}' srcpackage = '' if hasattr(n, '_interface'): pkglist = n._interface.__class__.__module__.split('.') if len(pkglist) > 2: srcpackage = pkglist[2] srchierarchy = '.'.join(nodename.split('.')[1:-1]) nodenamestr = '{ %s | %s | %s }' % (nodename.split('.')[-1], srcpackage, srchierarchy) text += ['%s [label="%s|%s|%s"];' % (nodename.replace('.', ''), inputstr, nodenamestr, outputstr)] # write edges for edge in sorted(edges): text.append(edge) text.append('}') filep = open(dotfilename, 'wt') filep.write('\n'.join(text)) filep.close() return text # Graph manipulations for iterable expansion def _get_valid_pathstr(pathstr): """Remove disallowed characters from path Removes: [][ (){}?:<>#!|"';] Replaces: ',' -> '.' """ pathstr = pathstr.replace(os.sep, '..') pathstr = re.sub(r'''[][ (){}?:<>#!|"';]''', '', pathstr) pathstr = pathstr.replace(',', '.') return pathstr def expand_iterables(iterables, synchronize=False): if synchronize: return synchronize_iterables(iterables) else: return list(walk(iterables.items())) def count_iterables(iterables, synchronize=False): """Return the number of iterable expansion nodes. If synchronize is True, then the count is the maximum number of iterables value lists. Otherwise, the count is the product of the iterables value list sizes. """ if synchronize: op = max else: op = lambda x,y: x*y return reduce(op, [len(func()) for _, func in iterables.iteritems()]) def walk(children, level=0, path=None, usename=True): """Generate all the full paths in a tree, as a dict. Examples -------- >>> from nipype.pipeline.utils import walk >>> iterables = [('a', lambda: [1, 2]), ('b', lambda: [3, 4])] >>> list(walk(iterables)) [{'a': 1, 'b': 3}, {'a': 1, 'b': 4}, {'a': 2, 'b': 3}, {'a': 2, 'b': 4}] """ # Entry point if level == 0: path = {} # Exit condition if not children: yield path.copy() return # Tree recursion head, tail = children[0], children[1:] name, func = head for child in func(): # We can use the arg name or the tree level as a key if usename: path[name] = child else: path[level] = child # Recurse into the next level for child_paths in walk(tail, level + 1, path, usename): yield child_paths def synchronize_iterables(iterables): """Synchronize the given iterables in item-wise order. Return: the {field: value} dictionary list Examples -------- >>> from nipype.pipeline.utils import synchronize_iterables >>> iterables = dict(a=lambda: [1, 2], b=lambda: [3, 4]) >>> synced = synchronize_iterables(iterables) >>> synced == [{'a': 1, 'b': 3}, {'a': 2, 'b': 4}] True >>> iterables = dict(a=lambda: [1, 2], b=lambda: [3], c=lambda: [4, 5, 6]) >>> synced = synchronize_iterables(iterables) >>> synced == [{'a': 1, 'b': 3, 'c': 4}, {'a': 2, 'c': 5}, {'c': 6}] True """ # Convert the (field, function) tuples into (field, value) lists pair_lists = [[(field, value) for value in func()] for field, func in iterables.iteritems()] # A factory to make a dictionary from the mapped (field, value) # key-value pairs. The filter removes any unmapped None items. factory = lambda *pairs: dict(filter(None, pairs)) # Make a dictionary for each of the correlated (field, value) items return map(factory, *pair_lists) def evaluate_connect_function(function_source, args, first_arg): func = create_function_from_source(function_source) try: output_value = func(first_arg, *list(args)) except NameError as e: if e.args[0].startswith("global name") and \ e.args[0].endswith("is not defined"): e.args = (e.args[0], ("Due to engine constraints all imports have to be done " "inside each function definition")) raise e return output_value def get_levels(G): levels = {} for n in nx.topological_sort(G): levels[n] = 0 for pred in G.predecessors_iter(n): levels[n] = max(levels[n], levels[pred] + 1) return levels def _merge_graphs(supergraph, nodes, subgraph, nodeid, iterables, prefix, synchronize=False): """Merges two graphs that share a subset of nodes. If the subgraph needs to be replicated for multiple iterables, the merge happens with every copy of the subgraph. Assumes that edges between nodes of supergraph and subgraph contain data. Parameters ---------- supergraph : networkx graph Parent graph from which subgraph was selected nodes : networkx nodes Nodes of the parent graph from which the subgraph was initially constructed. subgraph : networkx graph A subgraph that contains as a subset nodes from the supergraph. These nodes connect the subgraph to the supergraph nodeid : string Identifier of a node for which parameterization has been sought iterables : dict of functions see `pipeline.NodeWrapper` for iterable requirements Returns ------- Returns a merged graph containing copies of the subgraph with appropriate edge connections to the supergraph. """ # Retrieve edge information connecting nodes of the subgraph to other # nodes of the supergraph. supernodes = supergraph.nodes() ids = [n._hierarchy + n._id for n in supernodes] if len(np.unique(ids)) != len(ids): # This should trap the problem of miswiring when multiple iterables are # used at the same level. The use of the template below for naming # updates to nodes is the general solution. raise Exception(("Execution graph does not have a unique set of node " "names. Please rerun the workflow")) edgeinfo = {} for n in subgraph.nodes(): nidx = ids.index(n._hierarchy + n._id) for edge in supergraph.in_edges_iter(supernodes[nidx]): #make sure edge is not part of subgraph if edge[0] not in subgraph.nodes(): if n._hierarchy + n._id not in edgeinfo.keys(): edgeinfo[n._hierarchy + n._id] = [] edgeinfo[n._hierarchy + n._id].append((edge[0], supergraph.get_edge_data(*edge))) supergraph.remove_nodes_from(nodes) # Add copies of the subgraph depending on the number of iterables iterable_params = expand_iterables(iterables, synchronize) # If there are no iterable subgraphs, then return if not iterable_params: return supergraph # Make an iterable subgraph node id template count = len(iterable_params) template = '.%s%%0%dd' % (prefix, np.ceil(np.log10(count))) # Copy the iterable subgraphs for i, params in enumerate(iterable_params): Gc = deepcopy(subgraph) ids = [n._hierarchy + n._id for n in Gc.nodes()] nodeidx = ids.index(nodeid) rootnode = Gc.nodes()[nodeidx] paramstr = '' for key, val in sorted(params.items()): paramstr = '_'.join((paramstr, _get_valid_pathstr(key), _get_valid_pathstr(str(val)))) rootnode.set_input(key, val) levels = get_levels(Gc) for n in Gc.nodes(): """ update parameterization of the node to reflect the location of the output directory. For example, if the iterables along a path of the directed graph consisted of the variables 'a' and 'b', then every node in the path including and after the node with iterable 'b' will be placed in a directory _a_aval/_b_bval/. """ path_length = levels[n] # enter as negative numbers so that earlier iterables with longer # path lengths get precedence in a sort paramlist = [(-path_length, paramstr)] if n.parameterization: n.parameterization = paramlist + n.parameterization else: n.parameterization = paramlist supergraph.add_nodes_from(Gc.nodes()) supergraph.add_edges_from(Gc.edges(data=True)) for node in Gc.nodes(): if node._hierarchy + node._id in edgeinfo.keys(): for info in edgeinfo[node._hierarchy + node._id]: supergraph.add_edges_from([(info[0], node, info[1])]) node._id += template % i return supergraph def _connect_nodes(graph, srcnode, destnode, connection_info): """Add a connection between two nodes """ data = graph.get_edge_data(srcnode, destnode, default=None) if not data: data = {'connect': connection_info} graph.add_edges_from([(srcnode, destnode, data)]) else: data['connect'].extend(connection_info) def _remove_nonjoin_identity_nodes(graph, keep_iterables=False): """Remove non-join identity nodes from the given graph Iterable nodes are retained if and only if the keep_iterables flag is set to True. """ # if keep_iterables is False, then include the iterable # and join nodes in the nodes to delete for node in _identity_nodes(graph, not keep_iterables): if not hasattr(node, 'joinsource'): _remove_identity_node(graph, node) return graph def _identity_nodes(graph, include_iterables): """Return the IdentityInterface nodes in the graph The nodes are in topological sort order. The iterable nodes are included if and only if the include_iterables flag is set to True. """ return [node for node in nx.topological_sort(graph) if isinstance(node._interface, IdentityInterface) and (include_iterables or getattr(node, 'iterables') is None)] def _remove_identity_node(graph, node): """Remove identity nodes from an execution graph """ portinputs, portoutputs = _node_ports(graph, node) for field, connections in portoutputs.items(): if portinputs: _propagate_internal_output(graph, node, field, connections, portinputs) else: _propagate_root_output(graph, node, field, connections) graph.remove_nodes_from([node]) logger.debug("Removed the identity node %s from the graph." % node) def _node_ports(graph, node): """Return the given node's input and output ports The return value is the (inputs, outputs) dictionaries. The inputs is a {destination field: (source node, source field)} dictionary. The outputs is a {source field: destination items} dictionary, where each destination item is a (destination node, destination field, source field) tuple. """ portinputs = {} portoutputs = {} for u, _, d in graph.in_edges_iter(node, data=True): for src, dest in d['connect']: portinputs[dest] = (u, src) for _, v, d in graph.out_edges_iter(node, data=True): for src, dest in d['connect']: if isinstance(src, tuple): srcport = src[0] else: srcport = src if srcport not in portoutputs: portoutputs[srcport] = [] portoutputs[srcport].append((v, dest, src)) return (portinputs, portoutputs) def _propagate_root_output(graph, node, field, connections): """Propagates the given graph root node output port field connections to the out-edge destination nodes.""" for destnode, inport, src in connections: value = getattr(node.inputs, field) if isinstance(src, tuple): value = evaluate_connect_function(src[1], src[2], value) destnode.set_input(inport, value) def _propagate_internal_output(graph, node, field, connections, portinputs): """Propagates the given graph internal node output port field connections to the out-edge source node and in-edge destination nodes.""" for destnode, inport, src in connections: if field in portinputs: srcnode, srcport = portinputs[field] if isinstance(srcport, tuple) and isinstance(src, tuple): raise ValueError(("Does not support two inline functions " "in series (\'%s\' and \'%s\'). " "Please use a Function node") % (srcport[1].split("\\n")[0][6:-1], src[1].split("\\n")[0][6:-1])) connect = graph.get_edge_data(srcnode, destnode, default={'connect': []}) if isinstance(src, tuple): connect['connect'].append(((srcport, src[1], src[2]), inport)) else: connect = {'connect': [(srcport, inport)]} old_connect = graph.get_edge_data(srcnode, destnode, default={'connect': []}) old_connect['connect'] += connect['connect'] graph.add_edges_from([(srcnode, destnode, old_connect)]) else: value = getattr(node.inputs, field) if isinstance(src, tuple): value = evaluate_connect_function(src[1], src[2], value) destnode.set_input(inport, value) def generate_expanded_graph(graph_in): """Generates an expanded graph based on node parameterization Parameterization is controlled using the `iterables` field of the pipeline elements. Thus if there are two nodes with iterables a=[1,2] and b=[3,4] this procedure will generate a graph with sub-graphs parameterized as (a=1,b=3), (a=1,b=4), (a=2,b=3) and (a=2,b=4). """ logger.debug("PE: expanding iterables") graph_in = _remove_nonjoin_identity_nodes(graph_in, keep_iterables=True) # standardize the iterables as {(field, function)} dictionaries for node in graph_in.nodes_iter(): if node.iterables: _standardize_iterables(node) allprefixes = list('abcdefghijklmnopqrstuvwxyz') # the iterable nodes inodes = _iterable_nodes(graph_in) logger.debug("Detected iterable nodes %s" % inodes) # while there is an iterable node, expand the iterable node's # subgraphs while inodes: inode = inodes[0] logger.debug("Expanding the iterable node %s..." % inode) # the join successor nodes of the current iterable node jnodes = [node for node in graph_in.nodes_iter() if hasattr(node, 'joinsource') and inode.name == node.joinsource and nx.has_path(graph_in, inode, node)] # excise the join in-edges. save the excised edges in a # {jnode: {source name: (destination name, edge data)}} # dictionary jedge_dict = {} for jnode in jnodes: in_edges = jedge_dict[jnode] = {} for src, dest, data in graph_in.in_edges_iter(jnode, True): in_edges[src._id] = data graph_in.remove_edge(src, dest) logger.debug("Excised the %s -> %s join node in-edge." % (src, dest)) if inode.itersource: # the itersource is a (node name, fields) tuple src_name, src_fields = inode.itersource # convert a single field to a list if isinstance(src_fields, six.string_types): src_fields = [src_fields] # find the unique iterable source node in the graph try: iter_src = next((node for node in graph_in.nodes_iter() if node.name == src_name and nx.has_path(graph_in, node, inode))) except StopIteration: raise ValueError("The node %s itersource %s was not found" " among the iterable predecessor nodes" % (inode, src_name)) logger.debug("The node %s has iterable source node %s" % (inode, iter_src)) # look up the iterables for this particular itersource descendant # using the iterable source ancestor values as a key iterables = {} # the source node iterables values src_values = [getattr(iter_src.inputs, field) for field in src_fields] # if there is one source field, then the key is the the source value, # otherwise the key is the tuple of source values if len(src_values) == 1: key = src_values[0] else: key = tuple(src_values) # The itersource iterables is a {field: lookup} dictionary, where the # lookup is a {source key: iteration list} dictionary. Look up the # current iterable value using the predecessor itersource input values. iter_dict = dict([(field, lookup[key]) for field, lookup in inode.iterables if key in lookup]) # convert the iterables to the standard {field: function} format iter_items = map(lambda(field, value): (field, lambda: value), iter_dict.iteritems()) iterables = dict(iter_items) else: iterables = inode.iterables.copy() inode.iterables = None logger.debug('node: %s iterables: %s' % (inode, iterables)) # collect the subnodes to expand subnodes = [s for s in dfs_preorder(graph_in, inode)] prior_prefix = [] for s in subnodes: prior_prefix.extend(re.findall('\.(.)I', s._id)) prior_prefix = sorted(prior_prefix) if not len(prior_prefix): iterable_prefix = 'a' else: if prior_prefix[-1] == 'z': raise ValueError('Too many iterables in the workflow') iterable_prefix =\ allprefixes[allprefixes.index(prior_prefix[-1]) + 1] logger.debug(('subnodes:', subnodes)) # append a suffix to the iterable node id inode._id += ('.' + iterable_prefix + 'I') # merge the iterated subgraphs subgraph = graph_in.subgraph(subnodes) graph_in = _merge_graphs(graph_in, subnodes, subgraph, inode._hierarchy + inode._id, iterables, iterable_prefix, inode.synchronize) # reconnect the join nodes for jnode in jnodes: # the {node id: edge data} dictionary for edges connecting # to the join node in the unexpanded graph old_edge_dict = jedge_dict[jnode] # the edge source node replicates expansions = defaultdict(list) for node in graph_in.nodes_iter(): for src_id, edge_data in old_edge_dict.iteritems(): if node._id.startswith(src_id): expansions[src_id].append(node) for in_id, in_nodes in expansions.iteritems(): logger.debug("The join node %s input %s was expanded" " to %d nodes." %(jnode, in_id, len(in_nodes))) # preserve the node iteration order by sorting on the node id for in_nodes in expansions.itervalues(): in_nodes.sort(key=lambda node: node._id) # the number of join source replicates. iter_cnt = count_iterables(iterables, inode.synchronize) # make new join node fields to connect to each replicated # join in-edge source node. slot_dicts = [jnode._add_join_item_fields() for _ in range(iter_cnt)] # for each join in-edge, connect every expanded source node # which matches on the in-edge source name to the destination # join node. Qualify each edge connect join field name by # appending the next join slot index, e.g. the connect # from two expanded nodes from field 'out_file' to join # field 'in' are qualified as ('out_file', 'in1') and # ('out_file', 'in2'), resp. This preserves connection port # integrity. for old_id, in_nodes in expansions.iteritems(): # reconnect each replication of the current join in-edge # source for in_idx, in_node in enumerate(in_nodes): olddata = old_edge_dict[old_id] newdata = deepcopy(olddata) # the (source, destination) field tuples connects = newdata['connect'] # the join fields connected to the source join_fields = [field for _, field in connects if field in jnode.joinfield] # the {field: slot fields} maps assigned to the input # node, e.g. {'image': 'imageJ3', 'mask': 'maskJ3'} # for the third join source expansion replicate of a # join node with join fields image and mask slots = slot_dicts[in_idx] for con_idx, connect in enumerate(connects): src_field, dest_field = connect # qualify a join destination field name if dest_field in slots: slot_field = slots[dest_field] connects[con_idx] = (src_field, slot_field) logger.debug("Qualified the %s -> %s join field" " %s as %s." % (in_node, jnode, dest_field, slot_field)) graph_in.add_edge(in_node, jnode, newdata) logger.debug("Connected the join node %s subgraph to the" " expanded join point %s" % (jnode, in_node)) #nx.write_dot(graph_in, '%s_post.dot' % node) # the remaining iterable nodes inodes = _iterable_nodes(graph_in) for node in graph_in.nodes(): if node.parameterization: node.parameterization = [param for _, param in sorted(node.parameterization)] logger.debug("PE: expanding iterables ... done") return _remove_nonjoin_identity_nodes(graph_in) def _iterable_nodes(graph_in): """Returns the iterable nodes in the given graph and their join dependencies. The nodes are ordered as follows: - nodes without an itersource precede nodes with an itersource - nodes without an itersource are sorted in reverse topological order - nodes with an itersource are sorted in topological order This order implies the following: - every iterable node without an itersource is expanded before any node with an itersource - every iterable node without an itersource is expanded before any of it's predecessor iterable nodes without an itersource - every node with an itersource is expanded before any of it's successor nodes with an itersource Return the iterable nodes list """ nodes = nx.topological_sort(graph_in) inodes = [node for node in nodes if node.iterables is not None] inodes_no_src = [node for node in inodes if not node.itersource] inodes_src = [node for node in inodes if node.itersource] inodes_no_src.reverse() return inodes_no_src + inodes_src def _standardize_iterables(node): """Converts the given iterables to a {field: function} dictionary, if necessary, where the function returns a list.""" # trivial case if not node.iterables: return iterables = node.iterables # The candidate iterable fields fields = set(node.inputs.copyable_trait_names()) # Flag indicating whether the iterables are in the alternate # synchronize form and are not converted to a standard format. synchronize = False # A synchronize iterables node without an itersource can be in # [fields, value tuples] format rather than # [(field, value list), (field, value list), ...] if node.synchronize: if len(iterables) == 2: first, last = iterables if all((isinstance(item, six.string_types) and item in fields for item in first)): iterables = _transpose_iterables(first, last) # Convert a tuple to a list if isinstance(iterables, tuple): iterables = [iterables] # Validate the standard [(field, values)] format _validate_iterables(node, iterables, fields) # Convert a list to a dictionary if isinstance(iterables, list): # Convert a values list to a function. This is a legacy # Nipype requirement with unknown rationale. if not node.itersource: iter_items = map(lambda(field, value): (field, lambda: value), iterables) iterables = dict(iter_items) node.iterables = iterables def _validate_iterables(node, iterables, fields): """ Raise TypeError if an iterables member is not iterable. Raise ValueError if an iterables member is not a (field, values) pair. Raise ValueError if an iterable field is not in the inputs. """ # The iterables can be a {field: value list} dictionary. if isinstance(iterables, dict): iterables = iterables.items() elif not isinstance(iterables, tuple) and not isinstance(iterables, list): raise ValueError("The %s iterables type is not a list or a dictionary:" " %s" % (node.name, iterables.__class__)) for item in iterables: try: if len(item) != 2: raise ValueError("The %s iterables is not a [(field, values)]" " list" % node.name) except TypeError, e: raise TypeError("A %s iterables member is not iterable: %s" % (node.name, e)) field, _ = item if field not in fields: raise ValueError("The %s iterables field is unrecognized: %s" % (node.name, field)) def _transpose_iterables(fields, values): """ Converts the given fields and tuple values into a standardized iterables value. If the input values is a synchronize iterables dictionary, then the result is a (field, {key: values}) list. Otherwise, the result is a list of (field: value list) pairs. """ if isinstance(values, dict): transposed = dict([(field, defaultdict(list)) for field in fields]) for key, tuples in values.iteritems(): for kvals in tuples: for idx, val in enumerate(kvals): if val != None: transposed[fields[idx]][key].append(val) return transposed.items() else: return zip(fields, [filter(lambda(v): v != None, list(transpose)) for transpose in zip(*values)]) def export_graph(graph_in, base_dir=None, show=False, use_execgraph=False, show_connectinfo=False, dotfilename='graph.dot', format='png', simple_form=True): """ Displays the graph layout of the pipeline This function requires that pygraphviz and matplotlib are available on the system. Parameters ---------- show : boolean Indicate whether to generate pygraphviz output fromn networkx. default [False] use_execgraph : boolean Indicates whether to use the specification graph or the execution graph. default [False] show_connectioninfo : boolean Indicates whether to show the edge data on the graph. This makes the graph rather cluttered. default [False] """ graph = deepcopy(graph_in) if use_execgraph: graph = generate_expanded_graph(graph) logger.debug('using execgraph') else: logger.debug('using input graph') if base_dir is None: base_dir = os.getcwd() if not os.path.exists(base_dir): os.makedirs(base_dir) outfname = fname_presuffix(dotfilename, suffix='_detailed.dot', use_ext=False, newpath=base_dir) logger.info('Creating detailed dot file: %s' % outfname) _write_detailed_dot(graph, outfname) cmd = 'dot -T%s -O %s' % (format, outfname) res = CommandLine(cmd, terminal_output='allatonce').run() if res.runtime.returncode: logger.warn('dot2png: %s', res.runtime.stderr) pklgraph = _create_dot_graph(graph, show_connectinfo, simple_form) outfname = fname_presuffix(dotfilename, suffix='.dot', use_ext=False, newpath=base_dir) nx.write_dot(pklgraph, outfname) logger.info('Creating dot file: %s' % outfname) cmd = 'dot -T%s -O %s' % (format, outfname) res = CommandLine(cmd, terminal_output='allatonce').run() if res.runtime.returncode: logger.warn('dot2png: %s', res.runtime.stderr) if show: pos = nx.graphviz_layout(pklgraph, prog='dot') nx.draw(pklgraph, pos) if show_connectinfo: nx.draw_networkx_edge_labels(pklgraph, pos) def format_dot(dotfilename, format=None): cmd = 'dot -T%s -O \'%s\'' % (format, dotfilename) CommandLine(cmd).run() logger.info('Converting dotfile: %s to %s format' % (dotfilename, format)) def make_output_dir(outdir): """Make the output_dir if it doesn't exist. Parameters ---------- outdir : output directory to create """ if not os.path.exists(os.path.abspath(outdir)): logger.debug("Creating %s" % outdir) os.makedirs(outdir) return outdir def get_all_files(infile): files = [infile] if infile.endswith(".img"): files.append(infile[:-4] + ".hdr") files.append(infile[:-4] + ".mat") if infile.endswith(".img.gz"): files.append(infile[:-7] + ".hdr.gz") return files def walk_outputs(object): """Extract every file and directory from a python structure """ out = [] if isinstance(object, dict): for key, val in sorted(object.items()): if isdefined(val): out.extend(walk_outputs(val)) elif isinstance(object, (list, tuple)): for val in object: if isdefined(val): out.extend(walk_outputs(val)) else: if isdefined(object) and isinstance(object, six.string_types): if os.path.islink(object) or os.path.isfile(object): out = [(filename, 'f') for filename in get_all_files(object)] elif os.path.isdir(object): out = [(object, 'd')] return out def walk_files(cwd): for path, _, files in os.walk(cwd): for f in files: yield os.path.join(path, f) def clean_working_directory(outputs, cwd, inputs, needed_outputs, config, files2keep=None, dirs2keep=None): """Removes all files not needed for further analysis from the directory """ if not outputs: return outputs_to_keep = outputs.get().keys() if needed_outputs and \ str2bool(config['execution']['remove_unnecessary_outputs']): outputs_to_keep = needed_outputs # build a list of needed files output_files = [] outputdict = outputs.get() for output in outputs_to_keep: output_files.extend(walk_outputs(outputdict[output])) needed_files = [path for path, type in output_files if type == 'f'] if str2bool(config['execution']['keep_inputs']): input_files = [] inputdict = inputs.get() input_files.extend(walk_outputs(inputdict)) needed_files += [path for path, type in input_files if type == 'f'] for extra in ['_0x*.json', 'provenance.*', 'pyscript*.m', 'pyjobs*.mat', 'command.txt', 'result*.pklz', '_inputs.pklz', '_node.pklz']: needed_files.extend(glob(os.path.join(cwd, extra))) if files2keep: needed_files.extend(filename_to_list(files2keep)) needed_dirs = [path for path, type in output_files if type == 'd'] if dirs2keep: needed_dirs.extend(filename_to_list(dirs2keep)) for extra in ['_nipype', '_report']: needed_dirs.extend(glob(os.path.join(cwd, extra))) temp = [] for filename in needed_files: temp.extend(get_related_files(filename)) needed_files = temp logger.debug('Needed files: %s' % (';'.join(needed_files))) logger.debug('Needed dirs: %s' % (';'.join(needed_dirs))) files2remove = [] if str2bool(config['execution']['remove_unnecessary_outputs']): for f in walk_files(cwd): if f not in needed_files: if len(needed_dirs) == 0: files2remove.append(f) elif not any([f.startswith(dname) for dname in needed_dirs]): files2remove.append(f) else: if not str2bool(config['execution']['keep_inputs']): input_files = [] inputdict = inputs.get() input_files.extend(walk_outputs(inputdict)) input_files = [path for path, type in input_files if type == 'f'] for f in walk_files(cwd): if f in input_files and f not in needed_files: files2remove.append(f) logger.debug('Removing files: %s' % (';'.join(files2remove))) for f in files2remove: os.remove(f) for key in outputs.copyable_trait_names(): if key not in outputs_to_keep: setattr(outputs, key, Undefined) return outputs def merge_dict(d1, d2, merge=lambda x, y: y): """ Merges two dictionaries, non-destructively, combining values on duplicate keys as defined by the optional merge function. The default behavior replaces the values in d1 with corresponding values in d2. (There is no other generally applicable merge strategy, but often you'll have homogeneous types in your dicts, so specifying a merge technique can be valuable.) Examples: >>> d1 = {'a': 1, 'c': 3, 'b': 2} >>> merge_dict(d1, d1) {'a': 1, 'c': 3, 'b': 2} >>> merge_dict(d1, d1, lambda x,y: x+y) {'a': 2, 'c': 6, 'b': 4} """ if not isinstance(d1, dict): return merge(d1, d2) result = dict(d1) if d2 is None: return result for k, v in d2.iteritems(): if k in result: result[k] = merge_dict(result[k], v, merge=merge) else: result[k] = v return result def merge_bundles(g1, g2): for rec in g2.get_records(): g1._add_record(rec) return g1 def write_workflow_prov(graph, filename=None, format='turtle'): """Write W3C PROV Model JSON file """ if not filename: filename = os.path.join(os.getcwd(), 'workflow_provenance') ps = ProvStore() processes = [] nodes = graph.nodes() for idx, node in enumerate(nodes): result = node.result classname = node._interface.__class__.__name__ _, hashval, _, _ = node.hash_exists() attrs = {pm.PROV["type"]: nipype_ns[classname], pm.PROV["label"]: '_'.join((classname, node.name)), nipype_ns['hashval']: hashval} process = ps.g.activity(get_id(), None, None, attrs) if isinstance(result.runtime, list): process.add_extra_attributes({pm.PROV["type"]: nipype_ns["MapNode"]}) # add info about sub processes for idx, runtime in enumerate(result.runtime): subresult = InterfaceResult(result.interface[idx], runtime, outputs={}) if result.inputs: if idx < len(result.inputs): subresult.inputs = result.inputs[idx] if result.outputs: for key, value in result.outputs.items(): values = getattr(result.outputs, key) if isdefined(values) and idx < len(values): subresult.outputs[key] = values[idx] sub_bundle = ProvStore().add_results(subresult) ps.g = merge_bundles(ps.g, sub_bundle) ps.g.wasGeneratedBy(sub_bundle, process) else: process.add_extra_attributes({pm.PROV["type"]: nipype_ns["Node"]}) result_bundle = ProvStore().add_results(result) ps.g = merge_bundles(ps.g, result_bundle) ps.g.wasGeneratedBy(result_bundle, process) processes.append(process) # add dependencies (edges) # Process->Process for idx, edgeinfo in enumerate(graph.in_edges_iter()): ps.g.wasStartedBy(processes[nodes.index(edgeinfo[1])], starter=processes[nodes.index(edgeinfo[0])]) # write provenance try: if format in ['turtle', 'all']: ps.g.rdf().serialize(filename + '.ttl', format='turtle') except (ImportError, NameError): format = 'all' finally: if format in ['provn', 'all']: with open(filename + '.provn', 'wt') as fp: fp.writelines(ps.g.get_provn()) if format in ['json', 'all']: with open(filename + '.json', 'wt') as fp: pm.json.dump(ps.g, fp, cls=pm.ProvBundle.JSONEncoder) return ps.g def topological_sort(graph, depth_first=False): """Returns a depth first sorted order if depth_first is True """ nodesort = nx.topological_sort(graph) if not depth_first: return nodesort, None logger.debug("Performing depth first search") nodes=[] groups=[] group=0 G = nx.Graph() G.add_nodes_from(graph.nodes()) G.add_edges_from(graph.edges()) components = nx.connected_components(G) for desc in components: group += 1 indices = [] for node in desc: indices.append(nodesort.index(node)) nodes.extend(np.array(nodesort)[np.array(indices)[np.argsort(indices)]].tolist()) for node in desc: nodesort.remove(node) groups.extend([group] * len(desc)) return nodes, groups nipype-0.11.0/nipype/pkg_info.py000066400000000000000000000060351257611314500165600ustar00rootroot00000000000000import os import sys import subprocess try: from ConfigParser import ConfigParser except ImportError: from configparser import ConfigParser # python 3 COMMIT_INFO_FNAME = 'COMMIT_INFO.txt' def pkg_commit_hash(pkg_path): ''' Get short form of commit hash given directory `pkg_path` There should be a file called 'COMMIT_INFO.txt' in `pkg_path`. This is a file in INI file format, with at least one section: ``commit hash``, and two variables ``archive_subst_hash`` and ``install_hash``. The first has a substitution pattern in it which may have been filled by the execution of ``git archive`` if this is an archive generated that way. The second is filled in by the installation, if the installation is from a git archive. We get the commit hash from (in order of preference): * A substituted value in ``archive_subst_hash`` * A written commit hash value in ``install_hash` * git's output, if we are in a git repository If all these fail, we return a not-found placeholder tuple Parameters ---------- pkg_path : str directory containing package Returns ------- hash_from : str Where we got the hash from - description hash_str : str short form of hash ''' # Try and get commit from written commit text file pth = os.path.join(pkg_path, COMMIT_INFO_FNAME) if not os.path.isfile(pth): raise IOError('Missing commit info file %s' % pth) cfg_parser = ConfigParser() cfg_parser.read(pth) archive_subst = cfg_parser.get('commit hash', 'archive_subst_hash') if not archive_subst.startswith('$Format'): # it has been substituted return 'archive substitution', archive_subst install_subst = cfg_parser.get('commit hash', 'install_hash') if install_subst != '': return 'installation', install_subst # maybe we are in a repository proc = subprocess.Popen('git rev-parse --short HEAD', stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=pkg_path, shell=True) repo_commit, _ = proc.communicate() if repo_commit: return 'repository', repo_commit.strip() return '(none found)', '' def get_pkg_info(pkg_path): ''' Return dict describing the context of this package Parameters ---------- pkg_path : str path containing __init__.py for package Returns ------- context : dict with named parameters of interest ''' src, hsh = pkg_commit_hash(pkg_path) import networkx import nibabel import numpy import scipy import traits return dict( pkg_path=pkg_path, commit_source=src, commit_hash=hsh, sys_version=sys.version, sys_executable=sys.executable, sys_platform=sys.platform, numpy_version=numpy.__version__, scipy_version=scipy.__version__, networkx_version=networkx.__version__, nibabel_version=nibabel.__version__, traits_version=traits.__version__) nipype-0.11.0/nipype/testing/000077500000000000000000000000001257611314500160635ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/README000066400000000000000000000005411257611314500167430ustar00rootroot00000000000000The numpytesting directory contains a copy of all the files from numpy/testing for numpy version 1.3. This provides all the test integration with the nose test framework we need to run the nipype tests. By including these files, nipype can now run on systems that only have numpy 1.1, like Debian Lenny. This feature was added by Yaroslav Halchenko. nipype-0.11.0/nipype/testing/__init__.py000066400000000000000000000026501257611314500201770ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """The testing directory contains a small set of imaging files to be used for doctests only. More thorough tests and example data will be stored in a nipy data packages that you can download separately. .. note: We use the ``nose`` testing framework for tests. Nose is a dependency for the tests, but should not be a dependency for running the algorithms in the NIPY library. This file should import without nose being present on the python path. """ import os # Discover directory path filepath = os.path.abspath(__file__) basedir = os.path.dirname(filepath) funcfile = os.path.join(basedir, 'data', 'functional.nii') anatfile = os.path.join(basedir, 'data', 'structural.nii') template = funcfile transfm = funcfile from nose.tools import * from numpy.testing import * from . import decorators as dec from .utils import skip_if_no_package, package_check skipif = dec.skipif def example_data(infile='functional.nii'): """returns path to empty example data files for doc tests it will raise an exception if filename is not in the directory""" filepath = os.path.abspath(__file__) basedir = os.path.dirname(filepath) outfile = os.path.join(basedir, 'data', infile) if not os.path.exists(outfile): raise IOError('%s empty data file does NOT exist' % outfile) return outfile nipype-0.11.0/nipype/testing/data/000077500000000000000000000000001257611314500167745ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/4d_dwi.nii000066400000000000000000000000001257611314500206350ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/A.scheme000066400000000000000000000000001257611314500203300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/A_qmat.Bdouble000066400000000000000000000000001257611314500214620ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/A_recon_params.Bdouble000066400000000000000000000000001257611314500231710ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/BrainSegmentationPrior01.nii.gz000066400000000000000000000000001257611314500246700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/BrainSegmentationPrior02.nii.gz000066400000000000000000000000001257611314500246710ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/BrainSegmentationPrior03.nii.gz000066400000000000000000000000001257611314500246720ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/BrainSegmentationPrior04.nii.gz000066400000000000000000000000001257611314500246730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/FLASH1.mgz000066400000000000000000000000001257611314500204170ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/FLASH2.mgz000066400000000000000000000000001257611314500204200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/FLASH3.mgz000066400000000000000000000000001257611314500204210ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/FreeSurferColorLUT_adapted_aparc+aseg_out.pck000066400000000000000000000000001257611314500275470ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/MASK_average_thal_right.nii000066400000000000000000000000001257611314500241150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/PD.mgz000066400000000000000000000000001257611314500200040ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ProbabilityMaskOfStudyTemplate.nii.gz000066400000000000000000000000001257611314500262100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/QSH_peaks.Bdouble000066400000000000000000000000001257611314500220760ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/README000066400000000000000000000006211257611314500176530ustar00rootroot00000000000000This directory contains empty, dummy files which are meant to be used in the doctests of nipype. For verion 0.3 of nipype, we're using Traits and for input files, the code checks to confirm the assigned files actually exist. It doesn't matter what the files are, or even if they contain "real data", only that they exist. Again, these files are only meant to serve as documentation in the doctests.nipype-0.11.0/nipype/testing/data/ROI_scale500.nii.gz000066400000000000000000000000001257611314500221270ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/SPM.mat000066400000000000000000000000001257611314500201240ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/SubjectA.Bfloat000066400000000000000000000000001257611314500216130ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/T1.mgz000066400000000000000000000000001257611314500177650ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/T1.nii000066400000000000000000000000001257611314500177470ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/T1.nii.gz000066400000000000000000000000001257611314500203660ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/T1_brain.nii000066400000000000000000000000001257611314500211220ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/TPM.nii000066400000000000000000000000001257611314500201230ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/Template_1_IXI550_MNI152.nii000066400000000000000000000000001257611314500233540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/Template_6.nii000066400000000000000000000000001257611314500214630ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/TransformParameters.0.txt000066400000000000000000000000001257611314500236600ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/afni_output.3D000066400000000000000000000000001257611314500215070ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/allFA.nii000066400000000000000000000000001257611314500204420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/all_FA.nii.gz000066400000000000000000000000001257611314500212200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/anat_coreg.mif000066400000000000000000000000001257611314500215610ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/anatomical.nii000066400000000000000000000000001257611314500215730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ants_Affine.txt000066400000000000000000000000001257611314500217400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ants_Warp.nii.gz000066400000000000000000000000001257611314500220400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ants_deformed.nii.gz000066400000000000000000000000001257611314500227140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/aparc+aseg.nii000066400000000000000000000000001257611314500214640ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/aseg.mgz000066400000000000000000000000001257611314500204200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/atlas.nii.gz000066400000000000000000000000001257611314500212060ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/b0.nii000066400000000000000000000000001257611314500177640ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/b0_b0rev.nii000066400000000000000000000000001257611314500210620ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ballstickfit_data.Bfloat000066400000000000000000000000001257611314500235570ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bedpostxout/000077500000000000000000000000001257611314500213545ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bedpostxout/do_not_delete.txt000066400000000000000000000000731257611314500247210ustar00rootroot00000000000000This file has to be here because git ignores empty folders.nipype-0.11.0/nipype/testing/data/brain_mask.nii000066400000000000000000000000001257611314500215710ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/brain_study_template.nii.gz000066400000000000000000000000001257611314500243200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/brain_track.Bdouble000066400000000000000000000000001257611314500225370ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bvals000066400000000000000000000000001257611314500200140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bvals.scheme000066400000000000000000000000001257611314500212570ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bvecs000066400000000000000000000000001257611314500200070ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/bvecs.scheme000066400000000000000000000000001257611314500212520ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/c1s1.nii000066400000000000000000000000001257611314500202320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/c1s3.nii000066400000000000000000000000001257611314500202340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/clustering.mat000066400000000000000000000000001257611314500216440ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cmatrix.mat000066400000000000000000000000001257611314500211340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/complex.nii000066400000000000000000000000001257611314500211320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/config.ini000066400000000000000000000000311257611314500207340ustar00rootroot00000000000000[BOOL] ManualNIfTIConv=0 nipype-0.11.0/nipype/testing/data/cont1.nii000066400000000000000000000000001257611314500205070ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cont1a.nii000066400000000000000000000000001257611314500206500ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cont2.nii000066400000000000000000000000001257611314500205100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cont2a.nii000066400000000000000000000000001257611314500206510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/converted.trk000066400000000000000000000000001257611314500214750ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope.nii.gz000066400000000000000000000000001257611314500210300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope1.nii.gz000066400000000000000000000000001257611314500211110ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope1run1.nii.gz000066400000000000000000000000001257611314500217170ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope1run2.nii.gz000066400000000000000000000000001257611314500217200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope2run1.nii.gz000066400000000000000000000000001257611314500217200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cope2run2.nii.gz000066400000000000000000000000001257611314500217210ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cortex.label000066400000000000000000000000001257611314500212670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/cov_split.mat000066400000000000000000000000001257611314500214670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/csd.mif000066400000000000000000000000001257611314500202300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/data.Bfloat000066400000000000000000000000001257611314500210240ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/degree.csv000066400000000000000000000000001257611314500207320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/degree.mat000066400000000000000000000000001257611314500207200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/design.con000066400000000000000000000000001257611314500207340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/design.mat000066400000000000000000000000001257611314500207360ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dicomdir/000077500000000000000000000000001257611314500205665ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dicomdir/123456-1-1.dcm000066400000000000000000000000001257611314500223010ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/diffusion.nii000066400000000000000000000000001257611314500214510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/diffusion_weighted.nii000066400000000000000000000000001257611314500233310ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dirs.txt000066400000000000000000000000001257611314500204640ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dofrun1000066400000000000000000000000001257611314500202630ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dofrun2000066400000000000000000000000001257611314500202640ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dteig.Bdouble000066400000000000000000000000001257611314500213540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dti.mif000066400000000000000000000000001257611314500202370ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi.mif000066400000000000000000000000001257611314500202420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi2anat_InverseWarp.nii.gz000066400000000000000000000000001257611314500241400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi2anat_Warp.nii.gz000066400000000000000000000000001257611314500226040ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi2anat_coreg_Affine.txt000066400000000000000000000000001257611314500236630ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi_CSD_tracked.tck000066400000000000000000000000001257611314500224360ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi_FA.mif000066400000000000000000000000001257611314500206100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi_WMProb.mif000066400000000000000000000000001257611314500214700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/dwi_tensor.mif000066400000000000000000000000001257611314500216340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/elastix.txt000066400000000000000000000000001257611314500211740ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/encoding.txt000066400000000000000000000000001257611314500213110ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi.nii000066400000000000000000000000001257611314500202400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi_acqp.txt000066400000000000000000000000001257611314500213040ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi_index.txt000066400000000000000000000000001257611314500214670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi_mask.nii000066400000000000000000000000001257611314500212530ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi_param.txt000066400000000000000000000003121257611314500214660ustar00rootroot00000000000000{ "enc_dir": "y-", "echospacing": 7.800117313764398e-4, "delta_te": 2.46e-3, "epi_factor": 128, "epi_lines": 57, "epi_acc": 2, "field_strength": 3.0, "field_axis": "z" } nipype-0.11.0/nipype/testing/data/epi_phasediff.nii000066400000000000000000000000001257611314500222510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/epi_rev.nii000066400000000000000000000000001257611314500211140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fa.nii.gz000066400000000000000000000000001257611314500204700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fdir00.nii000066400000000000000000000000001257611314500205470ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fdir01.nii000066400000000000000000000000001257611314500205500ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ffra00.nii000066400000000000000000000000001257611314500205410ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ffra01.nii000066400000000000000000000000001257611314500205420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fieldmap_mag.nii000066400000000000000000000000001257611314500220700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fieldmap_mag_brain.nii000066400000000000000000000000001257611314500232430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fieldmap_phase_fslprepared.nii000066400000000000000000000000001257611314500250130ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/first_merged.nii.gz000066400000000000000000000000001257611314500225540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fitted_data1.Bfloat000066400000000000000000000000001257611314500224440ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fitted_data2.Bfloat000066400000000000000000000000001257611314500224450ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fixed1.nii000066400000000000000000000000001257611314500206430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fixed2.nii000066400000000000000000000000001257611314500206440ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/flash_05.mgz000066400000000000000000000000001257611314500211020ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/flash_30.mgz000066400000000000000000000000001257611314500211000ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/flirt.mat000066400000000000000000000000001257611314500206050ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fmri_timeseries.csv000066400000000000000000002026341257611314500227060ustar00rootroot00000000000000"WM","Vent","Brain","LCau","LPut","LThal","LFpol","LAng","LSupraM","LMTG","LHip","LPostPHG","APHG","LAmy","LParaCing","LPCC","LPrec","RCau","RPut","RThal","RFpol","RAng","RSupraM","RMTG","RHip","RPostPHG","RAntPHG","RAmy","RParaCing","RPCC","RPrec" 10125.9,10112.8,9219.5,-7.39443,-8.74936,7.28395,13.7953,32.2328,32.4809,18.958,-12.2383,-6.86466,-23.0912,-16.425,-5.70842,11.2467,-1.58574,-4.53717,-17.3842,0.912601,13.0428,2.44622,2.08875,-8.74373,-9.47217,-6.87574,-8.11158,-14.54,0.414787,6.04424,0.540389 10136.8,10115.1,9222.54,-0.120582,-1.94906,6.92247,4.75197,11.0735,0.972766,10.2285,0.717545,-1.04488,-7.64424,-2.10875,-2.44368,1.52535,-1.14131,-1.72589,-1.1247,-0.993354,2.98318,1.29855,2.0688,1.00297,0.135373,-3.25325,-3.12065,0.913296,-1.7868,1.58829,-0.735248 10148,10122.2,9228.62,4.24336,-0.689111,5.12782,0.132862,-6.64526,-14.7952,5.19361,3.68198,2.77598,-0.691866,1.07559,1.71444,-1.30287,-2.75746,1.74208,4.75944,1.80799,-0.064464,2.37174,1.09905,3.5756,2.98064,-0.238711,0.822007,5.07188,-0.864496,-0.208741,-1.31367 10156.6,10132.2,9236.11,-0.047434,-1.79438,-0.767925,-3.78683,-2.46365,-12.9433,2.00586,-0.48292,1.16216,0.113706,-0.639879,-0.0445654,-2.82995,-2.22008,1.46544,3.70217,2.84476,-3.32792,6.701,0.982599,0.145487,0.0501163,-1.16747,-0.630382,-0.0550437,-0.0563951,0.0449386,-0.715988 10162.9,10141.8,9243.46,-0.3687,0.640608,-2.93969,-0.37466,-5.42813,-8.55527,-4.70566,-3.62351,-3.94857,0.847112,0.357187,1.39279,-3.07124,0.779726,5.12671,3.62277,2.86265,3.44378,5.49842,0.895482,-2.1777,0.14728,-0.491475,-0.0257423,-0.32504,2.28464,-0.610659,2.01955 10168.7,10149.5,9249.62,-0.272231,3.00751,-2.20783,-5.50238,-1.65733,-2.39574,-6.82249,-1.5591,-5.38806,-0.315138,2.41171,-0.227563,-0.306796,1.26618,4.45885,3.55662,3.14737,-0.0497907,2.76691,1.04757,-2.50276,3.25334,1.90194,3.54754,3.2308,0.393197,0.115407,1.88919 10175.3,10155.8,9253.09,0.271133,3.11725,-1.24188,-5.32432,6.94595,5.40219,2.63329,1.77742,-0.434798,3.20784,3.1926,-2.12653,1.4207,-0.162939,1.57116,1.20026,2.14004,-4.36978,-0.074248,0.344989,-2.79157,3.57441,2.795,6.81971,4.61981,-3.15395,-0.556388,-0.951462 10181,10160.9,9253.62,-1.52186,-1.02665,-1.31765,-8.89055,1.45638,-6.40533,-8.20284,3.42071,6.34151,7.32703,2.81444,-5.56924,-2.07761,-2.82472,1.75969,1.56549,2.59032,-4.99642,-0.861721,0.661704,1.27294,4.24609,5.72265,7.93181,6.46356,-4.54558,-2.93302,-2.55741 10182,10163.1,9253.53,-4.12759,-5.01517,-1.383,-11.7032,7.03273,-0.354258,-4.14846,2.56836,5.49077,2.70724,-0.00938943,-7.91268,-3.33257,-3.77932,-2.70035,-1.95288,1.51899,-10.5021,0.604386,1.13765,2.8031,0.719838,5.10986,5.4321,3.01561,-5.05514,-2.51591,-2.29453 10178.9,10161.7,9255.33,-2.09727,-3.23639,-0.971464,-6.47564,-1.86208,1.47429,-8.69004,2.23012,2.64935,4.20852,-0.00802028,-4.11236,-1.54808,-1.73414,-2.21966,-2.31888,0.521142,-4.49634,-1.66003,1.37105,1.47741,-1.17943,3.52554,2.31201,0.381259,-1.24137,-0.930002,-0.860505 10176.3,10158.2,9258.8,-2.87976,-1.16821,-1.15587,-7.36873,-2.70663,3.69409,-6.23946,3.17083,3.67683,5.95472,2.6739,-2.5798,1.61294,2.31642,-4.31408,-1.6647,-0.422612,-6.13843,-0.39141,1.92345,-2.82275,-0.742784,1.68164,-0.706688,-1.87652,0.172975,1.51911,1.04727 10176.2,10155.4,9261.93,-1.79655,0.511159,-2.91648,-1.19976,-6.01265,2.43062,-4.91165,1.64787,2.485,6.04132,2.79139,1.36683,2.36631,4.70105,-3.09068,-0.875835,-2.73203,-1.04036,0.0279962,0.57264,-4.70596,0.399049,0.109101,0.540718,-2.52779,1.90878,1.47212,2.48712 10177,10154.3,9263.36,-2.06935,1.47151,-1.59814,1.1621,-8.21806,2.74994,-4.8666,1.6535,2.86737,3.56179,1.87379,3.98852,2.20191,7.00018,-2.12026,-0.322149,-0.459427,1.99009,-0.386875,-1.65524,-2.88602,2.5405,3.09752,5.52644,1.72241,3.28467,2.06659,4.48929 10176.7,10153.6,9262.97,-2.47996,0.0736981,-1.18826,-1.40068,-2.38119,-1.33094,-3.87199,0.498621,1.31667,-0.952908,0.481976,0.0885501,1.11339,4.67043,-2.37383,-2.32579,0.991108,-0.25346,2.41941,-1.44295,0.0394728,1.67752,2.73018,4.10445,2.29859,0.993454,2.7469,3.39394 10174.9,10153,9261.77,-0.957748,-0.455644,0.885525,1.7746,0.0437147,0.878291,0.0855234,-0.572903,1.39546,0.00119098,1.69176,-1.96049,0.156938,2.84845,-1.18488,-2.65197,1.35428,1.98606,1.65427,-0.643756,-1.03602,-0.0406435,-0.236011,-0.961959,1.28125,-0.464305,1.75539,1.84618 10173.4,10153.5,9261.3,-0.583682,-0.792331,1.36077,0.644185,-3.55594,-0.618864,-4.88099,-0.136266,1.51362,2.73872,3.65897,-2.63062,0.416981,0.735765,0.533665,-0.326252,1.0146,2.83848,2.16063,2.30307,-2.01136,0.638055,-0.22921,-3.19692,0.947596,-0.379132,0.678065,0.747812 10174.5,10155.7,9262.24,-0.685336,0.856591,-2.63545,-0.959601,3.25442,0.791955,-2.20612,0.263046,-1.34292,4.47114,2.99912,-2.56858,-0.21931,-1.56389,-0.808263,0.311028,-2.34261,-0.965718,1.98615,3.50723,-1.41951,-0.258476,-1.16227,-1.73014,0.372641,-0.118946,-0.422557,-1.3986 10179.6,10157.8,9264.01,2.59538,3.68921,-1.9033,3.99249,0.109215,-1.86778,-4.51336,0.591929,-1.29086,1.52475,1.01934,0.773735,0.0652847,-3.00075,1.79923,2.1369,-2.11635,3.17035,-1.87907,2.19309,0.880052,-0.480886,-1.94369,-0.204693,1.63785,1.43004,-2.081,-3.24652 10186.9,10157.6,9265.4,2.10402,4.02633,0.884264,0.1708,-3.27208,-4.9215,-1.0364,1.60796,1.70888,-1.43476,1.10519,1.26841,0.0627916,-2.97727,1.13683,2.82663,-0.301705,-0.592683,-3.81587,-0.70989,1.60855,0.103857,-2.48043,-1.22737,-0.312858,1.31617,-1.91269,-3.98886 10192.2,10155.4,9265.29,1.6824,4.26755,1.57687,1.43194,-5.98808,-2.25097,0.153789,0.168572,0.879003,1.68604,0.75956,3.65922,-0.869793,-2.49312,0.497574,2.41553,-1.34226,-0.127659,-3.59295,-1.56547,0.88849,-0.785242,-4.24845,-5.15572,-4.81836,2.77035,-1.44493,-3.44434 10193.6,10153.7,9263.38,1.6491,4.80854,1.08823,5.10222,-5.26833,5.52263,-0.997094,-0.959485,-1.52356,6.15147,0.897033,7.60472,-1.50848,-0.576994,0.845199,3.25263,-2.21353,2.36454,-2.11918,-0.480371,1.405,-1.24949,-1.88424,-5.50221,-4.39822,4.6832,-0.575266,-0.350337 10193.7,10153.5,9260.14,0.371243,3.4575,-0.922956,2.86612,3.70316,4.4652,-2.35097,-2.08567,-4.55866,2.05406,0.20181,5.48777,-0.851734,-0.932792,0.852325,2.66059,-2.76402,-0.836483,3.32512,2.58318,3.54953,-1.82575,1.03107,-3.58566,-4.1055,2.71087,0.64122,1.16036 10193.4,10154.1,9256.45,0.655998,2.95689,-0.961572,2.95967,6.90968,-0.0847335,-1.13659,-2.64581,-3.78971,-2.43015,-0.722449,3.08777,-0.234356,-0.603156,1.30068,1.14368,-2.23215,0.241084,3.91588,3.38796,4.07024,-1.08082,1.15617,-0.375163,-2.54369,1.29418,0.795869,1.31402 10190.3,10152.8,9253.2,2.59279,1.93007,1.93861,4.82647,-1.84288,-5.84018,-7.03235,-2.16958,-0.8999,-4.4747,-1.99497,2.40008,0.0349671,-0.825783,2.00993,-0.184404,-0.576706,6.30193,1.43455,3.63536,2.34484,0.148851,-1.22127,-0.718508,-0.716753,1.50537,0.412978,0.73252 10185.2,10148.2,9250.73,1.88291,-0.127643,2.41457,0.38457,3.28565,2.40364,1.07674,-0.352091,-0.192694,-2.80281,-2.45121,-0.746935,0.454781,-0.345492,-2.38393,-2.35152,-0.468918,-0.28004,0.207449,2.6636,-1.39254,-2.09536,-4.44811,-4.48824,-2.93117,-0.770421,1.19,0.219788 10183,10142.2,9248.93,3.78484,0.701338,-0.71552,3.48407,0.454755,4.3743,3.68099,-0.668556,-3.42636,5.52772,-1.23863,-0.405148,0.665698,1.06479,-0.0251586,-0.48849,-0.847741,1.4814,-5.36764,-0.405219,-1.51485,-3.88226,-5.12764,-5.33767,-4.3365,-1.173,0.417418,0.415356 10185.4,10138.4,9247.93,3.11727,0.196163,-2.018,0.721283,-2.5075,-1.06349,0.331823,-1.2182,-4.01712,4.78444,0.452166,-2.16432,0.55673,1.61447,1.16718,1.44415,0.569846,-0.812131,-8.14324,-2.91296,2.43154,-1.45218,-0.730675,-1.0947,-2.25658,-3.52675,-0.361214,1.09266 10188,10139,9248.05,1.52249,-1.16117,-2.4591,-2.41492,-0.35832,-7.48161,-0.0490082,-2.1421,-3.52013,0.903896,-0.958215,-5.8036,-2.36788,-0.368615,-1.88998,-1.40466,-1.28791,-4.79995,-5.58563,-3.57656,4.13739,-0.274441,1.53352,2.93946,-1.96753,-6.76034,-1.87752,-0.324793 10186.8,10142.9,9249.23,2.29541,-0.414867,0.263844,-2.42527,-9.23597,-12.7958,-5.40665,-1.3296,-0.255947,1.05195,-3.09731,-3.83996,-4.40177,-0.0123634,-1.79533,-2.22933,-1.59891,-1.58539,-4.29444,-3.24283,2.73497,0.939395,2.25632,3.98042,0.672842,-4.87272,-3.0871,0.140664 10183.8,10146.3,9250.93,1.04007,-0.107056,-0.719832,-5.17314,-6.41206,-13.4527,-3.51115,-1.82372,-1.0661,0.164654,-4.87432,-3.16371,-3.16216,0.547311,-2.31938,-3.32366,-2.59406,-3.07878,1.07584,0.135595,-0.15385,-0.198986,-1.76614,-0.364142,-1.44816,-3.17832,-0.666637,0.539005 10182.5,10148.1,9252.57,1.58315,0.552138,-2.38854,1.84879,-2.25441,-6.8381,0.208721,-2.73312,-3.19332,-2.49192,-4.21087,0.445019,0.0651566,2.67403,-0.780414,-2.43461,-3.10543,1.48742,-0.123359,0.0321366,-2.00728,-1.30717,-5.02137,-5.05394,-3.39985,-0.233706,2.10556,1.51466 10182.7,10149.6,9253.33,0.671616,-1.8801,-5.19861,1.6691,-0.386439,-6.73637,0.390118,-1.36276,-2.8229,-3.74619,-1.53148,0.15594,0.934737,1.96014,-1.35363,-0.924511,-3.00858,0.653744,-1.84706,-3.59509,-0.247233,0.962108,-1.40552,-3.28119,-2.22432,0.0626129,2.48273,0.969888 10182.9,10150.9,9252.01,0.0166707,-2.52456,-5.48285,2.26653,-2.03587,-6.50283,-1.00325,0.264499,-1.46362,-0.822672,-1.11829,0.403605,-0.734484,-0.382999,-0.186567,1.24812,-2.13095,1.80897,-2.82131,-6.15356,2.54337,2.39696,2.51379,2.41699,0.307725,-0.195503,-0.252349,-0.890546 10182.1,10151,9248.33,-1.21698,-1.52567,-2.334,0.102378,3.74418,-1.36756,3.51501,1.50357,-1.80774,-0.855037,-2.71284,0.0746735,-1.2904,-2.37263,-0.326812,1.37779,0.0811662,-2.04277,0.452769,-4.37491,4.60025,0.785458,0.944597,2.57121,-0.443829,-1.9031,-1.78376,-2.25217 10180.2,10149.4,9243.85,-0.498632,0.815261,-1.05027,1.32586,2.65892,-5.17029,-0.588453,1.63481,-3.33979,4.4087,-1.26981,2.01576,-3.03953,-3.66687,1.33091,1.62961,0.568999,0.53543,0.477935,-1.78405,3.91722,-1.12653,-3.07327,-2.27103,-2.21119,-0.0469714,-3.05949,-3.83303 10176.1,10146.3,9240.54,-0.464849,1.25223,-1.14736,-0.645201,4.96922,-0.805424,1.85313,1.43677,-1.45072,6.22509,1.54511,2.89442,-3.56094,-4.35854,-0.476689,0.39343,-0.929162,-1.07774,0.941846,-0.57756,0.363373,-1.13491,-1.30865,-3.06369,-1.8739,2.47973,-3.19611,-5.38414 10169.3,10142.4,9238.91,2.28739,1.91951,-0.759834,1.17008,-1.10807,0.137649,-1.76481,-0.427729,-0.592675,2.50623,0.607717,4.10404,-2.20382,-5.11375,1.80008,0.383348,-3.40396,4.33491,0.605228,-0.0871236,0.185566,0.480246,2.74078,1.48145,2.07534,4.96863,-2.65852,-5.78272 10162.1,10139,9238.14,2.03262,2.32633,0.46709,-2.26524,5.80967,5.85587,5.67759,0.185696,-0.246666,-0.787877,-0.201738,0.61348,-0.542043,-3.51173,0.345287,-0.426571,-4.01566,0.315299,2.10005,-0.391753,2.39343,1.28396,3,4.99164,5.3145,2.31592,0.0224444,-4.14279 10158.4,10136.9,9237.31,2.77556,2.83113,1.37245,1.19159,2.19923,-2.0116,3.1913,1.03754,-0.929092,0.870894,1.00256,-0.624392,-0.561338,-2.99529,2.23674,0.823539,-1.63024,3.75817,0.298891,-1.18515,4.54738,1.25951,1.91277,3.57793,5.44217,0.785618,0.025315,-3.27161 10158.5,10135.5,9236.37,0.0672571,0.761886,2.35427,-0.889999,6.73976,-1.98269,8.45302,1.1398,0.0604089,-1.15193,1.32222,-2.47069,0.131408,-3.48238,-0.669944,0.753279,3.07189,-2.04262,0.174304,-2.32107,2.83224,0.708328,3.23848,0.984911,2.384,-1.28385,-0.548071,-3.32946 10160.6,10134.8,9236.46,-0.783525,0.239203,0.00548465,1.88108,6.83171,-2.89703,7.27976,-2.71585,-1.47417,2.12383,-1.04536,-1.14095,0.145875,-4.3962,-0.139564,0.781551,3.40043,-0.28834,-0.343608,-2.36391,0.0938093,-0.36295,1.0276,-0.578692,-0.619797,-0.489157,-1.92106,-4.163 10166.1,10135,9239.02,0.124276,1.29463,-1.44975,3.21172,2.53479,-3.38317,-0.20102,-4.72755,-2.14129,5.53743,-1.24849,0.994366,0.436372,-3.09635,2.19121,1.13794,1.52365,3.0586,0.622146,-0.699363,0.103461,0.316277,-1.73095,-0.195395,0.490618,1.44514,-2.50878,-3.62472 10175.6,10136.9,9243.9,1.67228,1.70099,-0.125799,2.04051,6.74509,2.05118,7.82124,-3.08565,-1.70842,3.37127,-0.160655,1.32998,0.57087,-1.46351,1.80831,-0.585194,-0.267853,0.719624,2.12333,-0.931791,2.61407,0.519467,-1.78038,1.70819,2.66646,1.47407,-2.48388,-2.6294 10184.4,10140.5,9249.09,4.05746,1.49391,3.1491,4.74869,1.42089,-7.65297,4.6083,-1.50292,-0.681543,0.792377,-1.54194,2.19467,-1.449,-2.54459,5.38937,-0.0662613,0.683022,6.46847,-1.151,-2.09676,5.40097,0.0884146,-0.584039,0.411805,2.87021,2.70096,-3.69024,-2.72328 10185.2,10143.8,9252.71,2.20708,-1.9117,6.2705,-1.38994,9.88462,0.984595,14.8745,1.09177,3.01497,-6.59006,-3.06879,0.864155,-0.352553,-2.42934,1.6214,-0.899998,2.90809,-2.62154,-0.748965,-1.78716,3.1828,-0.76616,1.51574,-1.80336,0.759499,1.08543,-1.48814,-0.830864 10176.5,10145.2,9254.8,3.08758,-1.24415,2.30133,1.5123,4.9996,-2.25743,5.71269,0.326257,0.862459,-5.32366,-2.15784,1.98295,-0.769376,-3.24456,1.73394,-1.18022,0.303592,1.19388,-1.18318,1.1848,-0.484859,-3.12715,-2.31674,-4.16244,-1.41399,2.32149,-1.0187,-1.70219 10164.6,10145.4,9256.92,1.59078,-1.06701,-0.557541,-2.88977,3.22953,-0.245042,-0.474481,0.0498212,-1.16809,-8.33134,-0.306573,0.38113,0.242976,-2.39828,-1.29092,-1.68013,-0.127576,-1.94114,1.03024,1.7825,-1.44807,-2.86352,-4.13379,-1.78466,1.5241,1.16147,-0.513496,-2.30027 10156.4,10145.9,9260.21,0.0333157,-1.40254,-1.63643,-2.63202,2.15792,2.8366,-1.32406,-2.25364,-4.61227,-7.74587,-1.005,0.107792,-0.131513,-2.0428,-1.28031,-1.65736,-0.0589992,-0.767749,0.0451012,-1.23948,0.334266,-2.05544,-5.74107,1.40617,2.47259,0.129519,-1.22605,-3.50154 10152.5,10145.2,9264.25,-2.23854,-3.34598,0.871046,-4.48776,-5.12246,-0.367558,-7.49548,-3.04105,-2.99035,-3.84367,-2.67766,1.19195,0.695189,-1.99211,2.38266,0.800284,2.92667,1.82052,-0.796218,-1.82753,3.43662,1.60186,-2.49788,2.02216,2.59346,0.975508,-0.397427,-2.78437 10148.6,10141.1,9267.56,-4.64613,-5.4569,3.80281,-6.22039,0.554038,5.00519,-0.395733,-3.04225,0.570141,-6.95862,-4.49105,-0.00732036,3.78285,-2.09066,1.46914,-0.873643,3.95228,-2.08532,2.8568,0.749314,1.78963,1.02579,-0.808831,-1.60113,-1.17483,0.544949,1.95805,-1.27827 10142.4,10134.6,9268.73,-4.02228,-5.3818,4.39201,-6.57399,-2.68308,-0.146626,-0.297909,-1.28233,3.72363,-10.5635,-3.46562,-0.498293,3.92457,-1.10422,0.725311,-0.888612,3.1725,-1.82837,4.64182,1.32637,-0.56378,0.781271,3.29557,-0.557202,-0.712584,0.587691,2.76212,1.05325 10137.8,10128,9266.83,-2.98689,-3.62614,2.49614,-3.78405,5.33483,-3.24499,-1.4797,-1.49474,0.75769,-13.0722,-3.57543,-1.73535,1.13307,-2.81826,-2.67056,-2.75063,-0.407379,-1.38965,7.67619,2.2374,-2.93415,-2.1994,0.956463,-2.25511,-4.42128,-0.889014,2.30781,-0.144069 10139.6,10121.2,9261.84,-1.19244,-2.09691,-1.17019,-2.92359,1.84257,-9.64131,-8.2266,-2.48032,-2.29368,-7.41116,-3.60172,0.404837,-2.31741,-3.52505,-1.14341,-1.1367,-2.22469,2.93998,5.91064,0.841518,-1.68308,-1.06298,-0.398387,-1.68239,-3.53445,0.38234,1.02165,-0.403129 10146.2,10113.8,9255.3,-3.35595,-3.34535,-1.74811,-10.4556,3.60927,-0.776329,-3.08604,-1.29687,0.835023,-5.76979,-1.7646,-2.22816,-1.31439,-0.382083,-1.73312,-0.792276,0.206848,-4.1992,4.29806,-0.830575,-1.71405,1.40452,2.00247,0.106559,-0.768805,-1.08451,1.11784,1.22578 10152.4,10107.8,9249.87,-2.49869,-3.87311,-1.98238,-6.90342,-1.23671,2.90852,2.97754,-0.581043,2.81778,-2.71728,-1.21684,-5.07044,0.497485,2.01224,-0.365556,-1.64542,1.17956,-3.76085,-0.573467,-2.58111,-2.12663,0.378165,4.18795,1.24581,-1.36196,-2.87649,0.482267,1.63454 10154.8,10107.2,9247.27,-4.01788,-5.39388,-1.72161,-10.3153,-0.251037,-1.57831,1.61553,1.18147,5.7765,-0.599766,-1.22598,-10.0294,0.895145,2.02015,-4.45992,-2.58818,2.98391,-9.45103,-1.41902,-1.29446,-0.55725,-0.180421,6.94249,-0.594659,-3.53394,-6.50742,1.38112,1.51458 10153,10112.2,9246.76,-3.24249,-5.01072,-2.02956,-7.46567,0.0264794,-1.5224,-3.31193,1.53111,5.32332,2.5335,0.40251,-7.05633,-0.711568,2.89381,-5.39998,-1.36446,2.04786,-7.02942,-4.53297,-0.88262,-0.357391,0.595822,6.5409,-2.84395,-2.64994,-5.7378,1.39939,2.97985 10148.7,10119,9246.16,-3.96002,-4.42756,-3.26432,-8.69557,4.03628,0.616301,-3.92147,2.76458,1.652,2.17356,4.22927,-4.5247,-2.33417,3.89508,-5.29918,-0.309883,-0.288513,-8.36711,-3.09529,-0.126421,-1.8539,2.38545,3.61409,-1.26649,0.429596,-4.19612,1.45711,3.95651 10145,10125.2,9244.17,-1.75695,-0.511195,-1.73883,-3.34742,-1.26592,5.24499,-3.03549,2.78645,-2.1334,0.220919,5.88292,0.160927,-1.7455,5.37331,-1.59599,1.91312,-0.631146,-3.16886,-2.94994,0.34822,-3.01289,2.84951,0.356135,3.47859,4.18276,-0.12287,0.984563,3.64398 10143.1,10130.2,9241.27,-1.71615,1.12867,1.04805,-6.57347,2.41341,16.2593,7.00371,0.924589,-2.71609,-6.2656,3.57183,0.37743,1.96421,5.66573,-2.3041,2.26799,0.668846,-8.32571,2.30148,2.66333,-1.75615,2.71555,1.44408,6.00224,4.85886,0.685304,3.03234,2.82015 10140.7,10134.4,9239.05,-1.25992,2.46902,-0.556969,-2.76672,5.45596,12.4649,8.36959,-2.49709,-3.8708,-1.40646,1.38854,1.37064,2.12007,3.84209,0.459629,2.15086,-1.24194,-4.15365,4.52043,5.4809,0.876317,0.656659,-1.01116,2.09458,1.65028,2.77599,3.21635,0.381243 10133.6,10137.8,9238.32,-2.22442,1.37094,-0.787327,-1.05469,3.55443,5.14715,-0.0509983,-0.0905216,0.72894,3.96149,2.38061,1.75467,3.09083,4.18358,2.79613,3.29833,0.325666,-0.671704,6.07566,7.72379,3.13564,0.655668,-2.59152,-1.76199,1.58102,4.45884,3.34631,0.480564 10121.1,10140.7,9238.2,-2.17367,-0.866588,-2.79273,0.692199,10.1863,9.97874,6.04483,2.66482,1.76948,2.61332,1.9281,-1.1243,5.03132,3.85731,-0.443337,0.284932,-0.868815,-3.31091,8.51065,6.49177,2.23459,-1.67042,-3.77735,-2.781,-0.902713,1.50205,4.04064,0.197185 10110.8,10144,9237.47,0.303664,0.966366,-2.65365,4.69141,3.98147,5.09796,4.57488,3.26927,0.562439,5.41174,1.92471,-1.15766,3.6349,2.42314,-0.0874924,-0.0560302,-1.22366,1.9914,3.44357,1.69106,1.98031,-1.32375,-0.576816,-1.03349,0.269332,-0.300454,3.28264,-0.458562 10110.3,10147.7,9235.48,1.28867,0.940385,2.1165,-0.581377,-0.643187,-2.16313,1.69237,2.47912,1.37859,3.32286,1.26412,-0.720553,2.36863,-1.25903,0.0706914,0.944374,2.2859,0.229574,1.5842,-0.12766,4.43122,1.34327,3.34673,-0.404948,2.87655,-1.67866,3.04869,-0.25307 10116.7,10150.7,9232.33,0.394714,-0.833445,4.94793,-6.11826,9.22151,2.99358,11.1041,1.15853,2.93899,0.397365,0.0221406,-0.0976144,-1.13452,-3.42557,-3.72862,0.476803,3.69054,-8.12164,2.48493,0.363106,3.87676,0.504363,0.972674,-1.44388,2.15926,-0.828986,1.75931,-0.549928 10121.4,10152.8,9229.14,1.29508,-0.757006,3.12597,-1.6729,7.62364,-0.936804,6.48918,-1.03742,1.86227,-0.262351,-0.75051,2.31301,-4.8422,-4.5034,-2.66476,0.578808,1.27532,-2.04282,3.45288,3.01897,0.564668,-1.21876,-3.06331,-2.70583,0.257935,3.52846,-1.56111,-1.5308 10121.6,10152.4,9226.86,0.677648,0.378414,1.31475,-2.61018,4.91454,0.37514,2.86121,-0.193973,1.93324,-4.63591,1.10695,3.14457,-2.96694,-2.19304,-2.99025,0.50097,0.165722,-0.200595,6.85438,4.63234,-2.47705,0.342532,-1.30419,-0.141339,1.63084,4.32707,-1.19328,0.76139 10120.5,10149.2,9225.49,0.499478,1.88224,-2.14427,-2.77288,10.6927,1.71766,6.49787,0.43981,0.0705592,-5.13201,2.57263,1.48076,-1.20267,-0.591255,-4.74193,-1.79266,-1.46188,-3.42451,8.04316,3.54243,-2.30088,0.0710442,-2.83238,0.653942,0.240506,0.904871,0.430945,1.6283 10121.2,10144.8,9224.89,1.35965,2.80608,-1.94166,1.75583,0.26227,-8.26437,0.567312,1.6259,1.60009,0.0627174,2.62631,2.65738,-1.31444,1.36503,-0.138702,-0.303116,1.07964,0.805711,0.6712,-0.0379901,0.596301,1.49046,-2.9437,-0.0854658,1.7116,1.14138,0.19577,2.11315 10121.7,10140,9224.64,-0.625981,1.46152,0.571473,-0.708952,-3.97306,-7.60183,3.54876,2.52756,3.43643,-3.37318,1.25185,1.95327,-0.430742,1.99167,1.38528,0.439469,3.35733,-3.21518,-3.33649,-3.33716,1.63613,2.87364,0.216347,-1.19264,2.34646,1.38095,0.250252,2.26893 10117.5,10135.7,9223.59,-0.644241,3.50756,1.18011,1.32346,-4.09529,-1.15572,8.91836,0.864807,0.810206,-4.21922,0.85698,1.54667,-0.984211,1.49262,0.424346,0.272079,0.55043,-3.11065,-4.92549,-5.21789,0.616593,0.933381,0.453042,-0.907799,0.816878,0.888407,-1.07882,0.897744 10109,10134,9221.44,1.24811,3.97674,3.11247,-1.16572,-9.20759,1.26864,10.07,0.861166,0.629341,-5.07074,1.84156,0.554677,0.501606,2.3508,-1.99158,1.42546,-0.0624237,-4.75601,-4.11731,-5.27973,3.12042,0.927954,2.01431,1.91643,2.26937,-2.42322,-1.85499,2.11246 10103,10135.6,9219.87,2.2046,4.10281,1.87105,-2.44462,-1.81059,2.73657,16.517,1.49188,0.862687,-1.50652,2.91423,-2.27191,-0.311967,3.16828,-6.05317,-0.647296,-0.600809,-9.86797,-3.317,-4.05579,3.51099,-1.77799,-1.17227,0.17711,-2.12588,-5.86398,-2.08211,1.43944 10103.9,10138.7,9220.3,3.77174,5.49059,1.2637,1.03751,-12.6254,-6.24364,0.90728,3.65224,3.71822,2.59825,4.31988,1.86088,-2.62582,4.43061,-1.00461,2.10803,1.47555,-3.28777,-8.18549,-4.31695,2.95113,-1.34785,0.676274,-1.38936,-3.04336,-1.37001,-2.35773,2.00922 10108.6,10140.8,9221.82,-0.70593,3.90046,-1.14247,-3.0764,-1.47295,-1.10809,-0.510284,3.79285,2.60078,-1.28697,3.77566,2.32766,-3.54475,2.99719,-1.20306,1.33262,-0.719923,-9.06449,-7.33119,-4.80493,-0.721145,-2.4024,1.79362,-1.97223,-5.04385,0.0875954,-1.73778,0.950888 10113.1,10142.1,9223.55,-1.06377,0.843971,-1.44889,-5.32939,2.69029,-3.83385,-5.63119,0.535717,-1.61039,-5.59267,1.26514,2.05707,-3.31026,-0.958826,1.33732,1.46551,-3.13585,-9.66605,-6.00234,-4.35532,-0.26599,-0.831562,2.98878,0.128679,-2.54674,-0.278737,-3.58409,-1.324 10120.7,10142.9,9227.01,3.56995,1.04759,3.75113,-1.7421,5.12807,3.1454,2.38504,-1.62768,-2.93793,-5.71266,-0.530001,2.84448,-2.04436,-1.31251,2.17243,2.11298,-0.867238,-7.66197,-6.87331,-3.32769,-0.373459,-0.116178,2.03689,0.379397,-0.00605166,-0.182103,-4.1657,-1.22794 10135.1,10142.1,9232.63,4.13322,3.14571,5.42112,-9.50857,6.61076,-1.5265,-1.3563,-0.229734,-0.953633,-2.39287,0.0907423,-2.25912,-2.95494,-0.622513,-0.878638,3.11006,2.20909,-12.7591,-4.65267,-0.652931,-0.508727,-0.484787,-1.43884,-3.89903,-1.68783,-1.20607,-1.47415,-0.30987 10150.6,10139.9,9237.26,7.08686,7.1115,3.05908,-7.31514,-2.75139,-6.15754,-6.75994,1.34201,0.583247,1.72791,0.0586144,-1.05549,-2.23348,1.35232,0.957745,3.9225,0.27845,-7.28043,-8.71747,-3.21629,1.12263,-1.08286,-3.72117,-4.10901,-0.817087,-0.319549,-0.171801,1.86899 10161.3,10137.9,9238.2,5.45348,5.872,0.0360833,-8.71486,1.68904,-1.57501,-9.84544,2.70784,2.39605,-1.45535,-0.548901,-2.93743,2.31592,2.21738,-0.0678836,1.75621,-1.90485,-7.83172,-5.34721,-0.902631,2.89369,0.938874,1.08004,0.946796,3.39736,-3.2386,1.23533,3.43628 10168.7,10135,9236.89,1.9988,3.16081,-0.959961,-1.65775,15.8147,12.2058,-6.43511,1.69639,2.59198,-2.06327,-0.47323,-4.35241,3.77438,3.79233,-2.16153,-2.08622,-2.56136,-3.89096,-0.736348,5.49778,-0.475583,0.770127,3.05002,3.17719,3.81221,-4.99556,1.59718,3.01185 10178.3,10131.2,9237.28,0.818385,-0.233269,1.46873,6.63122,10.9706,17.5879,-3.54675,0.677416,3.72244,0.655626,-0.201865,-1.16835,1.57109,5.42876,-0.444523,-1.12764,-0.256929,5.62565,-1.99386,6.4084,-2.47406,1.18593,3.2834,3.0293,3.51573,-2.53776,0.959038,3.23253 10193.3,10130.2,9242.16,-2.48525,-2.35837,2.98987,5.98816,11.4719,15.9039,-4.84232,-0.825315,2.54659,1.43064,-0.659643,-2.96556,0.571285,2.41784,-2.00371,-0.757574,1.41844,6.37057,1.42823,7.71148,-4.93994,-1.54988,-0.232174,-1.34349,-1.26249,-2.05601,1.26179,0.464125 10210.2,10133.3,9250.5,-0.302459,-1.69801,0.843368,2.30597,6.15326,11.0157,-5.9274,-1.05244,-1.68469,-0.278629,-0.694935,-0.891837,1.23651,-0.21345,-0.305015,-0.0987808,0.160233,4.91775,0.166271,3.92353,-3.88399,-2.55526,0.198425,-0.923912,-1.86728,-0.552523,1.22445,1.15572 10221,10137.3,9258.6,-1.56339,-0.256664,0.840544,-1.61826,11.0061,14.4706,-2.59098,0.449882,-1.65171,-1.89163,-1.35949,-1.40198,3.60618,0.270121,-1.02351,-1.1912,0.778059,-0.110922,0.867721,2.27546,-5.20223,-2.14642,1.17716,-1.36266,-2.51971,-1.10085,2.42789,2.32548 10222.9,10141.6,9264.61,-4.74868,-0.212232,1.05283,-1.29221,10.744,4.75459,-2.81401,0.644295,0.850172,0.179994,-3.01777,-4.30435,2.71079,-1.12735,-1.29174,-2.07496,1.34575,1.0376,2.5823,1.95702,-4.5778,-1.28586,-0.494008,-4.39926,-5.46478,-2.40477,1.70545,-0.546783 10222.5,10148.7,9269.02,-3.49502,-0.678579,-0.213247,8.06515,8.4472,0.736921,12.8231,-0.680516,1.09355,1.44143,-3.62765,-2.08929,0.194595,-2.35671,-0.392866,-2.86869,-0.655593,6.76095,0.52286,-1.94996,-0.69629,-1.94695,-3.05311,-3.36287,-5.8798,-2.04553,-0.962602,-2.08692 10226.3,10155.2,9271.48,-1.96969,-0.131236,-7.34816,10.3469,1.43629,-18.1274,6.28789,-1.94889,-4.21799,9.10578,-0.96868,-0.513386,-5.07894,-4.75252,3.07715,-1.21549,-4.62974,12.6049,-2.11208,-4.5134,4.07597,-2.26695,-5.31607,-0.080814,-4.75562,0.0499323,-2.60796,-2.05158 10230.1,10151.7,9270.27,-0.441668,1.99564,-2.24149,10.4542,-4.09391,-6.45561,-1.77752,0.712394,-1.02642,8.25875,2.54249,4.31177,-1.67116,1.28898,3.90167,2.27301,-0.292013,13.1856,-3.31394,-4.23242,0.509949,-0.582218,-1.55254,1.54596,0.383257,3.15094,0.659781,3.83919 10224.9,10138.7,9266.49,4.67287,5.1299,-1.26323,13.4301,-10.2745,-9.49416,-12.2719,-1.18436,-2.87586,6.16837,2.83569,6.07774,-2.8315,2.00898,6.40272,2.01559,-1.86315,15.8694,-4.72684,-3.25468,-2.65905,-3.311,-6.24296,-4.21139,-3.70695,4.80612,0.395122,1.76566 10212.8,10131.4,9265.67,3.01888,4.86272,2.80549,9.41976,5.08199,16.7307,3.01517,-1.39232,-0.901598,-3.17761,2.70511,2.89126,0.206015,2.09237,1.79821,0.427067,-0.286912,4.97158,1.88506,1.52106,-4.78901,-3.10639,-5.19696,-1.88352,-1.17405,1.76068,1.66502,-0.462334 10205.3,10137.3,9271.29,5.0191,6.44861,-1.029,10.2232,1.46143,6.79866,-7.1328,-3.52906,-8.32347,-3.93806,2.03961,4.301,-3.73195,-3.92217,6.44854,2.90593,-2.49697,11.4551,-0.562561,1.57056,0.711111,-0.350636,-4.25263,3.76126,3.75639,3.70316,-1.79131,-3.47622 10205.7,10147.7,9278.59,5.83546,6.36501,-0.202118,7.16455,-12.9828,-12.4607,-27.3389,-3.33415,-9.60681,-6.26496,-0.539386,6.78879,-3.91681,-6.10831,9.8609,6.12423,0.502419,17.71,-2.72276,0.90307,5.89102,4.35576,1.47131,6.87862,9.08531,6.44279,-3.45175,-1.92878 10205.4,10153.7,9279.43,2.61204,3.79426,2.8599,4.2373,-6.30104,-6.55433,-17.9117,-2.30217,-4.33352,-8.56342,-2.54108,4.06241,-0.221565,-2.25183,3.87958,2.42384,1.7425,10.0636,-0.274803,1.38918,2.9688,2.49859,1.85002,3.57782,5.56749,4.25356,-1.57246,0.769565 10198.3,10155.2,9271.53,1.79363,-0.436721,3.46418,1.17919,-6.21503,-12.0337,-14.7144,-0.753172,-0.422946,-10.0673,-1.05729,0.16841,0.00393219,0.329848,3.06417,0.641188,1.13987,4.50086,-1.96838,-0.158451,2.22687,1.01485,-0.617827,-1.82684,0.837829,1.35672,-0.969077,2.83866 10187,10154.7,9258.9,0.357944,-3.85399,-0.403587,-0.905802,-6.94279,-16.6984,-17.7781,-0.22625,-1.87358,-4.80273,-0.208291,-3.41762,-1.38116,-0.435891,4.56144,1.47257,0.881539,4.31043,-2.35524,-0.63135,2.49929,2.73787,-0.3439,-0.967951,0.479767,-1.25236,-0.198644,2.70849 10175.5,10150.8,9245.55,-2.22289,-4.64417,-1.57873,-3.37822,-3.35046,-9.88201,-14.3071,0.168661,-0.756661,-2.69992,-1.57269,-4.61371,-0.741804,-0.794809,1.95045,1.34471,1.90438,0.670421,-1.36383,-0.0207592,1.95603,4.44548,1.70081,0.896225,1.96219,-2.68814,1.37985,1.21966 10163.9,10144.5,9233.39,-1.0609,-3.6573,-1.22008,-1.66234,-8.72059,-9.8591,-9.71449,-0.237702,2.4907,-0.383432,-2.45784,-2.52105,-0.451308,-0.95008,0.101755,0.998499,0.0147502,0.763548,-2.08901,-0.286814,2.08671,3.24587,1.98374,-1.03823,1.41551,-1.64013,0.866956,-0.452541 10152.5,10140.9,9224.11,1.58528,-1.3177,-2.21666,-0.770113,-12.1162,-14.2306,-0.877621,-0.372338,1.62768,2.76293,-0.69447,0.389726,-2.24466,-0.492948,-1.07534,1.2119,-2.84085,1.62365,-4.58137,-3.47859,2.38127,-0.58689,-1.20067,-5.12188,-1.38938,0.191315,-1.00868,-0.231626 10144.9,10141,9218.45,2.9188,-0.174985,-4.58083,-6.94645,-12.0718,-23.1781,-6.27315,-0.364715,-3.24703,1.70145,0.993811,-0.598274,-3.56103,-0.759525,0.496704,2.46032,-1.89983,0.597576,-2.01394,-2.93857,4.73883,-0.682548,-1.34504,-3.70636,-1.23983,0.0550942,-2.01066,1.58053 10141.8,10139.7,9215.32,1.06474,0.421951,-5.29652,-9.2234,8.36446,-5.7284,0.960531,-0.909556,-4.90704,0.770291,1.54135,-5.62095,-2.20122,-1.09503,-2.35206,-0.974175,-1.0101,-7.23319,3.01594,0.768168,2.39478,-1.32615,-1.6404,1.53725,-1.51813,-3.97654,-1.7665,0.833795 10141.4,10134.3,9214.23,0.86273,1.35397,-0.657898,-4.72598,2.71892,1.93911,-8.71178,0.127278,0.812447,5.14689,3.34014,-5.47575,-0.124804,-2.70815,-0.541837,-0.600256,1.53834,-3.53843,0.0605411,2.43643,0.689316,0.936364,1.45495,3.58725,0.917646,-4.12549,-2.16127,-1.91164 10145.6,10128.8,9217.09,0.035273,1.26692,3.11502,-4.96307,-6.78084,1.02172,-8.79811,2.69846,4.94751,11.3598,6.51275,-2.0705,0.657905,-2.59061,-0.35795,1.18908,3.42851,-3.05799,-3.41004,0.806424,0.399374,2.92706,4.4301,0.273598,0.553543,-1.76552,-0.755718,-3.46001 10157.5,10128.8,9225.31,0.248702,0.312336,2.57768,-4.36878,-7.1619,-0.049009,-3.2758,2.7151,1.99544,11.1247,7.80862,3.2311,1.05086,1.13953,0.117826,1.5885,2.6575,-2.74279,-2.82058,-0.206648,1.25493,1.71967,2.81266,-4.13773,-2.45207,2.50385,0.789243,-0.268176 10170.7,10133.1,9236.11,-2.23675,-0.885477,2.34602,-6.30375,3.19378,12.3402,5.26964,2.51006,1.86666,4.33237,6.63528,4.85198,3.48519,8.46812,-2.52066,-0.634166,3.57125,-6.40349,1.46869,0.818123,-1.68738,1.2743,1.91738,-0.951766,-0.403311,4.63843,3.18061,7.04436 10176.7,10136.2,9243.78,0.782244,0.338989,-0.179665,0.677035,-11.8864,-9.98092,-16.6014,-0.0876104,-1.39338,0.511794,2.05749,5.37285,2.64871,7.7119,4.8232,-1.23349,2.56586,8.98335,0.643413,1.73431,-0.63479,2.49537,-0.600719,2.26345,1.69812,6.71431,2.31721,8.10433 10176.8,10136.6,9245.84,-3.20567,1.13405,3.92668,-1.78597,-0.236073,-2.19382,-11.4115,3.08973,1.33702,-3.27145,0.727769,-0.100717,5.38921,8.19297,0.492232,-2.20151,5.25989,3.6589,4.08819,2.21554,-1.32513,3.54291,0.119275,3.23854,3.862,2.19948,5.28701,6.25834 10178.4,10137.4,9245.74,-5.53585,0.420645,5.85295,-4.47724,14.54,12.4497,8.36972,4.99424,2.57479,-4.3639,0.677018,-2.6813,6.67898,7.5884,-5.54187,-1.3688,4.05586,-6.15054,4.2909,-0.899213,-1.24567,1.90686,-0.469126,1.72139,5.00978,-1.65339,6.96518,3.71489 10184.8,10141.1,9247.89,-4.95644,-1.91401,3.7243,-7.95873,7.49028,6.40526,5.31843,3.53676,4.4376,-3.95261,0.746514,-2.92295,5.17495,5.09822,-5.56387,2.13589,1.74219,-7.51099,1.13636,-2.24892,-0.712168,1.40767,0.401594,-0.663717,6.22808,-1.51586,5.59537,1.86444 10195.1,10147.9,9253.27,-3.98,-3.06823,-2.05534,-6.10099,3.83685,4.55708,3.92119,0.928846,2.49159,0.0763172,1.14792,-2.88509,3.3624,3.14131,-4.76678,1.53759,-2.49281,-5.00974,0.3227,-1.57677,-2.36177,0.558465,1.76223,-0.153596,3.21585,-0.248642,3.44061,1.09292 10206.6,10155.3,9259.98,-4.64998,-1.64546,-4.6585,-6.92405,-1.23826,-1.4651,-7.80907,2.03872,0.322905,5.35637,2.9557,-1.90346,0.941137,2.90995,-2.25745,1.6362,-2.73525,-3.06893,0.361893,-0.410406,-1.95298,3.18373,4.96997,3.18307,2.09522,2.29277,1.29516,1.46329 10215.1,10159.8,9265.65,-5.64262,-2.22323,-2.32616,-8.62966,1.24852,3.53986,-7.11813,2.5704,-0.221435,0.41167,0.765415,-1.44792,2.10023,1.14341,-1.90736,0.761342,-0.0657556,-6.90094,4.60419,2.00852,-1.1143,4.44335,7.23913,4.6059,2.18355,1.92624,1.0442,1.06642 10218.9,10161,9269.98,-5.54728,-2.69742,0.623383,-4.54971,5.62832,12.115,1.60837,0.527375,0.225195,-4.35554,-1.09064,-1.69716,2.68584,-2.42078,-3.28377,-0.48855,1.46337,-7.59929,7.41232,3.78152,-1.52786,1.12019,5.14455,0.902689,0.791392,0.171231,1.01653,-2.1951 10225.1,10161.4,9274.87,-4.18459,-1.40959,4.0543,-3.78563,4.56469,13.1486,7.4468,1.32559,4.01602,-4.26528,2.47676,-0.706977,1.49841,-2.44619,-4.48237,0.314642,3.21848,-7.78537,6.45365,2.67192,-0.518631,-0.579868,3.1551,-3.30298,0.42352,0.385421,1.09082,-3.38628 10238.6,10163.7,9281.72,0.163978,0.29531,1.39945,-1.88245,0.770367,3.01996,6.47156,0.843119,3.05229,-2.89342,3.69162,1.01002,0.156961,-1.63668,-1.88068,0.459627,0.572044,-3.8789,6.07964,1.73877,1.04155,-0.952277,-0.352698,-3.89818,-1.13337,1.63306,0.655322,-3.05775 10252.3,10168.8,9289.58,1.69242,0.803041,0.969081,-1.57571,10.1963,10.1486,9.01137,-0.23779,2.45598,-11.8335,0.764195,0.347471,0.63322,0.818036,-2.67947,-0.48707,-0.0121974,-5.92175,4.75178,1.31186,-0.59319,-0.865273,-2.13114,-0.629395,-0.22624,0.187864,0.687159,-1.38416 10258.4,10175.1,9296.44,0.693656,-1.47018,1.57507,-4.07861,13.9151,7.913,3.87705,-2.41045,1.40643,-18.8401,-3.38044,-3.78137,0.444306,-0.142111,-3.19856,-0.633983,1.26609,-6.96487,4.03731,1.86282,-0.255938,0.885239,0.576534,4.16798,1.48633,-2.91027,0.44246,-1.26861 10259.2,10179.7,9301.13,-1.11281,-2.9356,3.48279,-4.07376,14.5961,4.75668,2.95063,-2.50321,1.99968,-15.2573,-3.94817,-6.19421,0.994523,-0.409685,-3.36826,-1.30752,2.89435,-7.11783,2.3961,1.75016,-0.287404,0.839505,2.32354,3.16514,0.431073,-4.23834,0.224613,-1.13459 10258.9,10180.8,9303.2,-3.70956,-2.93593,3.76222,-6.98265,14.1006,4.36509,3.13521,0.524873,3.4745,-8.19672,-0.812591,-7.54285,2.87285,0.165482,-4.34303,-3.00502,3.10194,-11.8146,3.48326,1.87454,-2.39007,-1.71717,-0.0308325,-3.00344,-3.10099,-5.07511,0.999296,-0.291248 10259.7,10178.9,9302.61,-2.50722,-0.863499,1.6361,-7.29671,5.65875,7.35687,6.74534,2.86707,2.5541,-4.10002,1.92641,-4.21325,3.79643,1.11564,-2.85299,-3.384,0.718232,-13.5344,2.15514,-0.378278,-3.09826,-4.48668,-4.09564,-6.07121,-4.62941,-4.63714,1.35609,1.33932 10264.3,10176.2,9300.58,-1.50986,-0.476834,0.153861,-9.03392,2.34462,9.76008,11.2624,0.958254,-0.70443,-6.3101,0.886002,-3.04957,4.20237,0.687347,-2.59931,-4.30057,-0.344332,-15.3463,3.30618,0.212706,-1.83037,-5.39362,-6.37009,-5.79293,-5.6463,-5.17005,1.45394,1.2199 10270.2,10175.5,9299.06,-1.8193,-1.62584,1.49621,-15.2891,-0.19176,0.694336,7.97111,-0.906134,-1.88497,-6.47048,-0.900237,-3.70282,1.23614,0.322582,-3.93212,-3.45866,1.71962,-16.8955,0.58688,-0.409914,-0.259588,-2.68512,-3.64588,-3.35838,-4.51583,-4.19392,0.240148,0.159851 10270.2,10179.6,9298.63,-1.90388,-3.42457,3.36972,-15.5947,6.83754,-2.72512,7.96959,-1.26132,-2.35887,-7.13988,-3.00989,-4.84946,-1.32472,-2.90407,-7.21556,-3.99747,1.63284,-18.121,1.49353,-0.486008,-0.289734,-2.44221,-2.61409,-4.74746,-6.81336,-4.22186,-0.397997,-3.01155 10263.1,10186.3,9296.94,0.1046,-2.95923,0.55802,-3.53552,11.956,6.06043,20.0157,-0.175478,-1.81809,-1.77528,-2.10279,-0.283075,-3.48288,-4.09089,-6.41457,-3.4926,-1.98205,-11.2644,1.51324,-2.56718,2.01317,-3.17178,-3.03644,-4.28621,-6.82533,-2.57386,-0.732198,-4.52782 10250.3,10186.7,9289.82,0.787893,-2.63004,-4.83671,4.59987,9.90165,5.11396,20.1712,-1.49013,-0.900383,3.2704,-1.38302,1.01612,-3.51797,-3.65748,-2.01906,-2.31487,-4.58178,-0.663723,4.99631,0.0846666,6.20019,-1.32911,-0.366123,-0.708005,-3.05462,-1.4169,-1.33549,-4.03837 10229.6,10174.2,9276.51,2.92922,1.43172,-8.45959,7.92191,9.82817,0.906035,15.1761,-5.66535,-4.80598,8.92318,-1.50732,0.863702,-4.19618,-1.72605,1.43049,-1.60336,-7.78679,7.9456,2.20311,0.976306,4.6808,-2.0774,-1.41618,1.52784,-1.00485,0.251303,-2.51818,-3.24837 10203.9,10154.8,9263.01,1.97737,4.88419,1.86761,-1.89071,16.8831,21.8027,18.6752,-2.85592,-0.407409,1.1857,1.57668,2.90834,1.42619,5.01683,-2.88862,1.13125,-1.02838,-3.77013,-1.83294,-0.874118,-1.82318,-1.06152,0.617181,1.34269,3.38069,1.15764,1.12216,1.38647 10184.5,10141.2,9256.68,5.24597,7.64832,2.18557,1.58328,4.92602,9.28816,-0.0172234,-2.70209,-2.36954,2.63625,2.45988,6.65341,1.30855,2.45772,0.884071,4.15289,-0.306199,0.501745,-3.91598,-0.843063,-3.78083,-0.751671,-0.908618,-0.353576,1.46737,4.59599,1.10914,-1.05414 10178.9,10140.4,9258.57,8.5511,8.38576,-0.704081,10.0442,3.87995,9.53107,4.06474,-2.33977,-3.33414,3.45052,0.769206,8.44243,0.151836,-0.110094,2.50423,3.89258,-1.86971,4.86933,-2.34618,0.208276,-3.54318,-0.382483,-0.444637,3.17545,1.86638,6.31308,-0.0788599,-2.11239 10182.7,10148,9263.52,7.664,6.75263,-0.540997,5.42972,-5.04193,-7.98425,-8.29464,-0.166299,-0.588527,3.31557,0.500806,4.72146,-2.51571,-1.43305,5.52369,5.671,1.03703,8.03067,0.0463032,4.16527,0.993743,2.27,2.01907,5.48701,6.28587,6.50446,-0.915646,-0.555951 10185.6,10156.6,9266.64,4.26252,2.60407,3.65205,1.35764,1.93964,-1.71464,3.62386,0.664968,2.07164,-1.84774,-1.41728,2.03742,-1.93901,-0.955849,2.55509,2.24827,3.4143,2.08534,1.52467,4.36357,2.40504,-0.149419,1.87333,2.56701,3.76988,3.58853,-0.290298,1.53656 10182.8,10164.1,9266.99,3.44774,1.00051,3.58435,5.06036,-3.20427,-1.32409,2.16178,-1.24869,0.986594,2.68824,-3.10496,3.75494,-3.03899,-1.36189,2.85639,-0.797041,2.25309,6.84226,-1.01807,1.45026,1.64915,-1.77668,1.47461,1.32051,0.0174875,3.15498,-1.91103,0.915561 10177.6,10169.5,9265.47,2.97062,0.742454,2.19308,3.39405,-10.2555,-6.11354,-8.35604,-2.29312,-0.492631,4.2024,-2.46282,2.85236,-2.05854,-1.07623,3.34902,-1.67951,1.43015,9.72371,1.0556,1.2093,0.0329592,0.933345,2.62882,4.14907,1.43657,2.25242,-2.21302,0.424466 10175.1,10171.1,9262.53,2.78573,0.66686,2.0545,2.76769,-2.38316,1.38611,1.33538,-1.98843,-1.22362,0.719734,-1.48276,0.571928,-0.303568,1.13172,0.533248,-2.57485,0.218063,4.75694,4.12677,1.25451,-2.29974,1.77459,2.18864,5.66448,2.31972,-0.197648,-0.423422,1.24127 10176.1,10170.7,9258.49,5.31438,0.737423,2.23937,7.15555,-6.03862,-6.93885,2.59027,-2.08985,-1.82474,1.76361,-1.51506,2.40133,-2.94977,1.13326,2.34185,-1.4691,-0.319475,6.55378,0.151184,-0.820336,-1.03183,0.737373,1.0173,1.60097,0.120988,0.706961,-1.06361,1.61191 10177.1,10171.1,9253.43,5.27989,0.124242,0.594136,6.40228,-14.4792,-17.9873,-7.83873,-2.70593,-2.84279,6.19952,-1.02819,4.22035,-3.89328,-0.655654,4.6427,-0.543649,-0.312946,7.67303,-3.34568,-2.99026,0.892734,0.193866,0.437901,-1.37172,-2.06494,3.10779,-2.09072,0.969194 10175,10171.9,9247.28,2.27598,-1.11333,-0.371999,2.70022,-5.44405,-1.24932,2.95574,-2.54561,-3.07604,2.81372,-0.48024,4.11824,2.04907,-0.370621,1.24343,-2.71039,-1.27809,-0.906837,-1.29061,-4.80376,-0.177684,-0.68347,-0.0356975,0.976652,-2.58184,2.60538,-0.53245,1.0079 10170.6,10171.1,9240.98,0.484599,0.0646839,-1.51326,2.89899,-3.4319,-0.213982,2.47953,-0.834731,-2.00581,5.72898,0.227883,2.67222,2.27602,0.0505934,1.31844,-2.26552,-2.6972,-0.975391,-0.869576,-3.70984,-1.26158,-0.292123,-0.590846,2.58737,-1.84822,1.62378,-0.526111,-0.491878 10166.9,10167.6,9236.09,0.964725,-0.0392702,-0.079079,4.19696,-8.77705,-7.3393,-5.33084,1.7816,1.00552,6.00308,-0.645333,1.80016,-0.345783,0.537513,3.29513,-0.258503,-1.94323,3.02276,-2.07851,-0.708951,-0.985472,0.42465,-0.0047685,-0.0149723,-1.37113,0.550535,-0.779034,-0.484969 10166.1,10161.5,9233.6,-0.598547,-1.76595,-1.06041,-0.952044,-3.22733,-6.25839,-1.71002,3.5389,3.14678,2.52469,-0.94774,-0.697306,-1.82073,1.8162,-0.398189,-0.0962201,-1.17773,-3.11075,-1.86249,-0.148137,-0.912351,0.0729367,0.372787,-1.52491,-1.99794,-1.67208,0.753712,1.02245 10167.9,10154.5,9233.85,1.32924,-0.579085,-4.09528,3.27081,-6.78357,-9.38603,-3.06915,1.95927,0.70163,2.46784,-0.635142,0.854662,-1.03664,2.44479,0.381434,0.976493,-2.1874,1.35415,-3.25712,-1.85514,0.202589,0.286026,0.720155,0.627719,-0.687001,-0.872865,1.21871,2.25385 10170.4,10147.3,9236.23,1.55419,0.655793,-3.90119,3.65032,-6.92144,-3.81534,-0.829364,1.59907,-0.150104,0.588015,0.212751,1.04803,3.09472,3.79829,-0.218751,1.11779,-1.55055,0.933332,-1.25266,-2.59487,0.647035,1.39731,2.58953,2.8589,1.80309,-1.43261,2.52993,2.79953 10171.9,10139.7,9239.22,2.16966,0.513128,-2.93705,2.73804,-10.8601,-4.50483,3.76187,1.03924,-0.676839,-1.4866,-1.19577,1.6866,5.98311,3.12642,0.0885709,0.9896,-0.594518,0.533618,0.379411,-3.82145,2.32664,2.22298,3.60721,3.05218,2.2889,-1.98702,2.79897,1.35025 10172.4,10133.5,9242.05,0.627291,0.905709,1.39363,2.99372,-15.425,-9.09382,2.11414,1.04226,2.10526,-4.39506,-2.77953,2.15891,6.66724,1.70369,-0.372333,1.40462,2.59187,2.26874,-0.378224,-3.69675,3.0335,2.25396,3.10192,0.0429504,0.10951,-0.799702,2.66794,-0.282681 10173.8,10130.2,9245.36,-1.33644,1.42161,3.11004,3.93858,-17.0646,-12.116,1.67239,1.94826,5.54306,-3.85205,-1.5475,2.52019,4.33814,1.15019,-0.541069,1.99129,3.05378,4.25369,-2.76731,-2.80645,1.85733,0.988299,2.88783,-1.97077,-2.83768,1.85125,2.84766,0.389147 10176.4,10130.9,9250,-3.53503,0.391503,-0.270572,1.95882,-15.1875,-18.5758,-1.42497,2.28845,5.40786,-2.12974,1.20821,0.911564,0.2788,0.0689856,-0.00271805,2.01928,-0.20812,3.23848,-1.98612,0.0245125,0.488358,-1.18054,1.47019,-3.47437,-4.6287,2.11498,2.20934,0.993318 10178.8,10135.9,9255.56,-3.20255,-0.268054,-3.48033,2.47099,-11.3536,-16.9308,2.01776,1.40976,1.56328,0.853625,1.89586,1.47109,-1.50849,0.167668,0.627511,1.41809,-4.21425,2.05546,-2.39209,-0.416193,0.276633,-1.50971,-0.820011,-1.25927,-1.76,0.153711,0.431209,1.48315 10181.2,10144.1,9260.31,-2.49125,-0.613263,-3.86482,0.287362,-9.17309,-14.1157,3.48478,0.196793,-1.25386,2.83848,0.198147,-0.0165582,0.471677,-0.139327,-0.216901,-0.966032,-5.2193,-1.40546,-0.977273,-1.2574,1.78779,0.134179,-1.72164,0.653388,0.313432,-3.37716,-0.587605,0.861387 10186.6,10151.1,9263.12,-0.0358474,0.714951,-5.47328,-0.875177,-17.5089,-13.8361,0.471247,0.643912,-2.41975,9.9458,0.993041,0.803296,-0.226386,0.0668295,2.19176,-1.16819,-4.40868,0.69383,-3.38706,-3.58218,3.07732,2.10253,1.79789,2.06744,1.83904,-2.15516,-1.67344,0.661882 10193.4,10152.2,9264.85,-2.78688,1.85556,-1.96216,-7.27433,-5.61022,0.625161,3.91544,2.78407,0.13042,8.01854,3.573,-2.43853,-1.07905,0.148792,-1.48277,-2.3792,0.378784,-7.05144,-1.06108,-1.76148,0.135824,1.71393,3.80312,-1.43656,0.702495,-1.95731,-0.703674,-0.33177 10196.9,10148.7,9267.46,1.41437,4.41491,0.0330121,-0.96198,-19.7539,-11.561,-5.49424,1.03618,-0.588315,13.1158,4.11913,1.82776,-4.02743,-1.24038,4.49417,2.16391,1.61464,5.33203,-6.2827,-3.22771,2.42673,4.53812,5.27571,1.95384,4.83592,2.15944,-2.23414,-0.0179182 10195.1,10146.6,9271.67,-0.599083,4.08109,5.56207,-0.651956,-1.899,4.41751,8.64946,-0.00765143,1.65381,7.40697,3.13743,0.528221,-1.17274,-0.333192,-1.34405,0.810869,3.04978,-1.96585,-3.00608,-1.02587,-0.427114,2.63482,2.33223,1.44749,2.70602,-0.508442,-0.782524,0.838544 10190.6,10149.1,9275.95,0.560997,3.32623,0.00253245,1.6273,-9.62681,-9.32197,-7.13248,-1.74244,-2.26773,10.279,2.01853,1.79006,-2.32577,-1.861,2.70102,2.63733,-0.668516,4.89049,-2.56801,1.67809,-0.682542,1.07859,-0.730879,1.04436,0.219305,1.04839,-1.30085,-0.204558 10188,10153.1,9277.72,-1.05102,1.4439,-1.2902,0.37219,3.61058,7.8905,-0.13638,-0.797121,-3.203,3.7144,-0.467361,1.43319,1.01941,-0.964803,1.27849,1.32106,-0.71757,-0.281666,1.82319,4.43107,-2.93419,-0.102775,-2.79816,1.60946,-0.350934,0.837113,0.975085,-0.206216 10189.3,10155.8,9275.17,1.71247,1.79065,-0.806826,4.2591,-1.07113,5.08033,-3.80833,-1.05846,-3.93516,4.86697,-2.48519,4.41458,1.0147,-2.04319,5.76698,3.04901,0.621182,6.18537,-0.471514,3.74338,0.0954557,1.78055,-2.23478,4.29533,3.28968,4.08665,-0.45381,-1.12752 10190.8,10155.9,9267.91,0.0885688,1.62773,3.97676,0.475719,6.50171,12.0036,4.17355,0.0800788,0.877184,4.13283,-1.66529,2.3731,1.22312,-1.52431,1.32333,1.30085,4.02821,0.00402446,-0.278254,3.83144,-0.00616006,1.70507,0.14686,2.05675,3.75234,3.42709,-1.13997,-2.28219 10186.5,10152.6,9257.34,-0.152071,1.1051,2.98089,-3.26014,-3.23874,0.545145,-3.74253,0.650653,4.32612,4.55661,-0.349067,0.443991,-1.54712,-2.37082,1.08068,1.11666,3.19332,0.114235,-4.77887,1.03262,0.526047,1.57427,1.96416,-1.21359,2.2522,2.81775,-2.19914,-3.20958 10175.9,10146,9246.33,-2.37365,-0.801223,1.8448,-4.49245,2.73452,3.45587,0.665856,0.804743,7.15539,-1.25789,-1.25952,-2.70716,-1.07845,-2.04441,-1.93328,-1.35806,1.5978,-5.1161,-5.79834,-0.925826,-2.80177,-1.15512,-1.39234,-4.88988,-2.71874,-0.727928,-1.17586,-2.55528 10163.6,10137.3,9237.87,-0.803469,-2.78044,-0.895544,-1.96323,-0.541223,-3.95959,-1.23923,0.0489646,5.82687,-0.842944,-2.20839,-1.37161,-0.868195,-0.366623,-0.326653,-0.542204,-0.442138,-3.06811,-5.05951,-1.77693,-2.56412,-2.0747,-5.18551,-5.90628,-3.59607,-1.51359,-1.0358,-0.0442413 10154.4,10129.1,9233.99,1.23915,-3.76005,-2.64612,0.723829,-3.148,-4.96491,0.57486,-0.202117,2.21428,-0.386009,-2.61213,0.591537,-0.420445,2.51457,0.848114,0.0155665,-2.8099,-0.688955,-1.65728,-1.68576,-0.314736,-2.37588,-7.30164,-5.93878,-1.09582,-1.08092,-1.23666,3.04974 10147.7,10124.3,9234.84,0.130569,-3.33534,-5.30783,0.228073,-1.79103,-2.90284,1.72325,0.336059,-1.67646,0.805152,-2.51359,-1.68843,-1.08056,2.79024,0.667811,-0.918425,-5.25023,-0.613583,-1.21144,-3.86108,1.12026,-2.87087,-6.96217,-3.74878,-0.871173,-1.99148,-1.4983,3.13726 10141.9,10125,9238.34,-2.3342,-3.74514,-6.28736,0.247636,2.71253,3.12847,7.57994,-0.0401623,-2.07147,0.481455,-3.97685,-4.46362,-0.415913,1.42821,-0.575486,-2.68041,-4.57327,-2.24353,-2.60028,-5.84863,0.625916,-3.42977,-3.6369,-0.844099,-3.5874,-4.64335,-0.985747,1.2717 10139.9,10130.2,9242.19,-1.31024,-4.72475,-7.14762,0.73153,1.45053,-5.53508,5.90136,-2.31863,0.194991,0.488804,-6.97821,-4.41928,-2.29074,-1.35009,0.919216,-2.89533,-3.25509,-0.799203,-1.99553,-4.14064,2.04707,-1.98553,-0.137078,-0.0166083,-4.9352,-5.40326,-1.67739,-1.42035 10146.2,10135.6,9246.04,1.48702,-3.36982,-6.22071,1.74719,2.56435,-13.0074,1.99705,-3.21561,2.91416,0.844878,-6.7988,-2.16439,-5.4962,-1.85975,2.13575,-1.59383,-2.91884,1.52462,-1.3314,-1.85117,3.6544,-0.430522,0.692754,-0.840642,-3.31251,-2.33908,-3.05762,-2.1983 10158.1,10136.1,9250.8,0.841737,-2.49661,-1.39476,-1.47649,15.6927,0.965199,10.869,-0.546861,4.02682,-3.15137,-2.65822,-1.05518,-4.77058,0.229656,-2.58261,-1.60934,-0.689737,-5.44364,-0.234473,-1.95479,2.60062,-0.769404,0.484685,-2.21476,-2.21659,-0.527818,-2.3356,-0.631119 10167.2,10131.4,9256.17,1.43756,-1.64599,0.0828565,1.10643,1.09851,-8.71597,-1.14743,1.16785,1.24835,1.69522,0.678389,1.91657,-5.73395,-1.26925,0.618759,0.671225,0.99422,2.5392,-3.14056,-3.00047,3.39733,-0.267724,0.865602,-1.72338,-1.28093,1.59131,-3.58079,-1.60917 10168.5,10125.9,9259.95,0.111755,-1.49369,1.18289,-0.284048,-1.52165,-7.82514,1.91577,2.83987,1.30957,4.34859,2.31828,0.547347,-5.35341,-2.95714,0.120479,-0.07344,1.25038,0.863374,-1.97606,-2.63292,2.99367,-1.51317,-0.192761,-1.94301,-2.34527,-0.816782,-4.15688,-3.69083 10164.7,10123.5,9260.03,2.54631,0.123647,1.85441,0.291179,-2.26534,-5.622,0.403256,2.75151,1.92159,5.45502,4.02912,0.277333,-3.49437,-2.59529,1.68451,1.03176,0.611114,1.05444,-1.37086,-0.762577,2.09659,-3.15435,-1.66892,-4.18628,-2.03484,-0.59484,-4.5361,-4.06338 10160.7,10123.9,9256.02,4.16394,1.15842,1.00215,-1.41089,3.00077,3.69915,2.12147,1.50602,1.11373,3.7783,5.12886,1.27055,-1.0735,0.163066,0.715848,1.75274,0.248762,-1.87449,-2.70607,-0.0821427,-0.982237,-3.91753,-0.603176,-5.15131,-1.55797,1.9122,-2.63806,-2.45448 10157.6,10124.8,9249.1,1.13904,0.752742,1.28292,-3.44794,5.87463,13.5955,-3.90547,0.053564,0.392376,-2.17549,4.02652,0.800942,2.14933,0.991305,-1.00534,1.93346,1.74799,-4.3887,-2.62983,2.12002,-3.97726,-2.37985,1.92724,-3.91126,-1.80145,3.29901,0.515867,-2.07875 10155.9,10125.9,9241.01,-1.21278,1.24353,0.0902419,-1.38693,3.90257,17.0687,-1.7671,-0.621263,-0.743581,-3.56603,3.19768,0.515647,2.83626,-0.394058,-0.965446,2.53295,1.02968,-3.73706,-0.646373,4.19926,-3.90665,0.100245,2.07717,0.65145,-0.4389,3.45695,1.30478,-2.26372 10156.9,10129,9233.19,-0.519545,3.45514,-0.128203,0.470911,-4.34917,11.6069,-5.37302,-0.249794,0.0908138,-1.64961,3.7305,0.887725,1.28233,-0.50548,0.651175,4.68216,0.481759,0.131141,2.83721,7.4517,-1.51906,2.02591,0.478488,2.8447,3.96564,4.21205,0.0189546,-1.26083 10160.2,10134.9,9226.61,0.334619,3.63902,-1.33005,0.500933,-0.0390483,15.3466,3.49804,-1.22599,-0.443012,-1.29729,1.85728,0.83413,0.663791,1.08815,-1.61332,2.35978,-1.91003,-1.54128,7.06018,8.52392,-0.0931056,-0.631766,-1.8937,1.21041,3.92464,3.0125,0.582016,-0.0552563 10165.1,10142,9222.12,-0.0501124,2.72845,-2.35233,0.461804,-3.24106,3.89637,-4.4752,-1.7395,-0.658087,1.46568,0.74815,1.9358,-1.37579,1.26993,0.248403,2.1501,-1.97865,2.84403,4.93078,6.34449,2.55208,-1.66616,-1.28941,-0.85475,2.44335,3.28626,0.575625,0.0867697 10169,10147.2,9219.92,-2.57524,1.55278,1.64717,-0.408592,2.78686,3.93608,-3.35557,-1.05071,0.358949,-1.71793,1.23509,0.730307,-0.807758,0.469476,-0.799756,2.26666,1.42763,2.57756,3.31921,4.24278,2.32673,-1.92157,-0.625841,-1.7385,0.55312,2.469,0.416022,0.102824 10167.7,10149.8,9219.39,-2.61236,0.265041,4.14099,-1.10443,5.68968,5.75872,0.437178,-1.27371,-1.44794,-5.50529,0.962099,-1.7594,-0.014506,-1.47838,-2.10998,2.88166,2.32266,2.31558,3.04189,2.76494,1.13588,-2.76241,-2.5749,-1.37983,-0.132212,1.62609,0.00182996,-0.567092 10161.2,10151.5,9219.88,-1.00231,0.225002,2.94421,2.03312,-0.355979,4.16591,-0.636307,-0.980578,-3.17075,-4.4683,-0.0413473,-0.96548,-0.194949,-0.798368,-1.08568,3.94015,1.20872,6.21739,0.493017,0.663456,-1.20346,-2.76074,-4.99576,-0.484664,1.27829,1.87168,-0.0347963,-0.649195 10155.5,10153.9,9220.83,-0.939771,0.647249,0.0634509,3.2582,-1.62031,4.0693,-0.997477,-0.169163,-4.01209,-4.20755,-1.14083,-0.040949,0.676499,1.0769,-0.637069,2.85891,0.53402,4.18699,0.666861,0.369829,-2.63692,-0.336214,-3.73798,1.47577,2.81105,-0.292838,0.0270106,-0.151526 10154.1,10157.5,9221.67,-1.65802,1.59847,-3.57612,1.52401,6.37221,4.48866,-1.46299,-0.915699,-6.98915,-0.340048,-0.952717,-2.18866,-0.811792,-0.642645,-0.622625,-0.300884,-1.00057,-1.15759,2.44751,2.6773,-1.823,1.29837,-1.91591,2.49204,1.93197,-3.59974,-1.91245,-2.4109 10154.4,10160.7,9221.98,-0.583463,-0.108757,-4.6507,-0.0693877,5.35637,4.425,-6.56889,-1.82597,-8.57191,2.85503,-1.05825,-2.33955,-3.22781,-4.76081,2.05753,-0.861931,-1.83229,-0.124382,0.503483,2.18131,1.30665,2.42826,0.824233,3.84653,2.09007,-3.3925,-4.31649,-3.96112 10153.4,10159.2,9221.68,-2.76485,-4.09131,-2.87698,-1.10712,12.5336,12.9839,-4.34652,-1.87041,-6.50663,-1.43881,-2.78497,-4.09349,-3.27711,-7.58611,-0.918956,-2.43732,-1.68029,-2.93885,1.37614,1.00354,-0.202025,0.252735,-1.35224,2.14941,-1.22668,-3.85694,-3.91196,-5.39514 10153.1,10150.6,9221.82,-3.95579,-6.11602,-1.95691,-0.571033,7.36799,2.23424,-8.23593,-1.15065,-2.89936,-3.34966,-3.42278,-4.92737,-4.22729,-7.57776,-1.53936,-2.4826,-0.485854,-2.05301,1.35048,0.235875,-0.851581,0.299046,-3.65228,0.452501,-2.53126,-4.14097,-3.0318,-6.032 10156.5,10138.1,9224.22,-1.72219,-4.81284,-2.04034,3.64429,-3.40667,-8.21149,-2.06758,-0.247629,0.240041,0.844032,-2.55693,-2.29071,-5.62686,-4.10255,0.955484,-2.58578,-0.573095,1.96046,-2.89531,-2.47853,1.00662,1.59082,-2.31097,1.60096,-0.355857,-3.59741,-2.54995,-3.16362 10162.5,10126.5,9229.66,-1.48624,-2.31864,-1.19917,5.07688,-2.15075,-4.48733,6.81643,1.19375,3.4529,3.66948,-1.49639,-1.71619,-5.51437,-1.29231,-0.407537,-4.604,-2.54282,0.0824236,-5.27449,-4.81883,0.767691,-1.39492,-2.55861,-0.325428,-1.75464,-3.59903,-1.89829,-0.732932 10167.7,10118.7,9237.56,-1.06333,-0.880843,-0.709075,2.8371,-10.0447,-10.4348,-2.5904,3.18465,5.97115,6.33779,-0.55058,-1.01646,-4.14332,-1.6247,-0.0193591,-4.01402,-3.73144,0.38443,-5.50468,-6.41294,-0.295721,-3.62009,-2.70822,-3.1355,-4.45086,-2.10376,-1.79258,-1.22716 10172.5,10116.9,9247.18,1.551,0.130326,-0.490568,5.87654,-14.5436,-8.35183,-0.790109,3.39107,4.7174,8.28156,-0.0057788,2.6686,-1.84943,-1.48071,1.03911,-4.0934,-3.48936,2.7605,-6.22541,-8.72046,-2.487,-3.9855,-3.15508,-4.85806,-6.30628,-0.1826,-2.22861,-1.91313 10179.7,10122.6,9257.78,1.5355,1.00586,-2.46594,5.55739,-10.6179,-9.89219,1.01847,2.02002,1.55047,10.3651,1.59035,2.3257,-3.02423,-0.681756,0.379055,-4.13859,-2.86252,2.65539,-7.09955,-8.4785,-1.80811,-2.44766,-3.84586,-6.08215,-4.18234,0.309597,-3.66089,-1.78168 10188.9,10134.4,9267.84,0.423127,-1.44673,-6.16369,2.54558,-3.2605,-10.2788,1.93481,-0.460125,-1.55478,7.53447,1.04311,-2.037,-5.33297,-0.715827,-0.912315,-4.00679,-5.27357,1.32517,-7.02947,-5.6844,2.49,-1.1701,-4.14164,-4.46692,0.160721,-1.23591,-5.46575,-0.678645 10196.3,10145.5,9275.21,0.204833,-4.851,-9.24744,3.38063,-3.90706,-1.89916,-0.318999,-3.05687,-4.83175,3.88926,-1.68472,-4.52857,-6.76493,0.053409,0.356074,-2.44354,-9.25902,3.95243,-8.99635,-3.68403,4.07743,-1.41439,-4.06526,0.784286,2.50666,-1.59161,-6.31937,0.0761621 10200.4,10148.5,9278.92,-3.06966,-5.752,-6.27773,-0.452092,4.18213,13.2473,-12.0757,-4.47092,-6.49884,-5.96616,-4.08975,-9.08064,-3.65565,-1.03612,-1.9757,-2.79369,-8.22081,-3.13926,-2.68074,1.98539,-1.47914,-4.27865,-6.82097,-0.0420558,-2.72616,-3.80964,-3.69263,-2.81706 10202.3,10144.3,9279.66,1.7621,-1.2767,-1.87182,1.61337,-6.80859,14.4514,-16.815,-2.07514,-4.63562,0.0307544,-1.49074,-2.29138,-1.18636,-1.08621,1.86862,0.689509,-4.2555,-0.913166,-4.04706,-1.13903,-2.95495,-1.4359,-3.45987,4.36607,0.619825,-1.53464,-2.06409,-2.58631 10201.6,10141.5,9277.89,2.73427,2.11183,3.79277,1.71546,-5.8859,13.3557,-11.3022,2.79327,2.37116,13.2011,3.98285,0.966107,0.039656,-0.715821,2.85166,2.34242,2.77476,-0.0888099,-4.98538,-3.4432,-1.83877,3.57211,2.68075,7.05565,6.45616,-1.54302,-1.24469,-1.49869 10196,10143.8,9273.55,-2.52737,0.202188,7.08167,-4.89952,6.71679,10.6699,0.756855,5.54471,7.25909,13.9583,6.39787,-2.37566,0.745793,-1.45474,-1.09404,0.910205,7.21143,-6.92492,-3.24203,-2.89701,-0.543452,6.07649,7.33376,6.57894,6.15484,-4.40884,0.0587056,-1.11052 10186.2,10147.8,9267.63,-4.31786,0.145523,8.74123,-1.12372,3.61382,5.90919,-2.20636,4.87121,7.93339,10.8223,5.77747,-1.02016,1.70524,-1.23974,-1.99873,1.22043,7.18349,-2.02393,-4.52471,-1.19367,-1.87015,5.60664,6.92162,5.30532,3.03549,-3.16865,1.33872,-1.3693 10178.3,10151.3,9262.07,-1.01371,-0.36759,7.07326,3.03463,-3.67644,6.41668,1.01659,3.32806,5.69645,6.11989,4.17302,3.13986,4.40199,0.31144,-2.58094,-0.0539033,4.16067,1.49299,-3.2753,-1.39228,-2.172,3.33149,4.19598,3.46064,0.616277,-0.818505,3.98959,0.698301 10177.2,10154.3,9257.94,2.09186,0.0766925,2.17884,5.08344,-13.9717,-0.882929,-3.84368,2.86526,4.57806,7.77504,4.75117,6.29349,4.58116,4.04706,1.06485,0.914494,1.84175,7.12093,-3.92066,-3.04038,-1.76589,1.29071,2.74094,1.46176,1.98937,3.12251,5.09485,3.84087 10179.4,10155.4,9254.74,0.187596,-0.882072,-0.665652,4.15319,-3.56212,6.25634,3.46947,2.99756,3.30879,0.859046,5.1349,3.91232,5.90056,6.60019,0.839946,-0.162343,-0.484405,2.65509,-1.8674,-3.50916,-5.10299,-1.60522,1.28388,-0.0295086,1.05,2.81748,5.21994,5.53563 10178.8,10153.1,9251.26,-1.91139,-0.154839,-0.832651,7.32065,-8.14661,3.20829,-4.61065,3.9011,1.20806,1.29028,6.11631,4.24084,4.66918,7.38927,3.1094,1.72009,-0.436683,6.06925,-3.83738,-3.64103,-8.35166,-0.222316,1.74303,3.43329,2.82215,3.91599,3.2218,6.05878 10175,10149.2,9246.46,-3.00223,-0.829219,2.18951,8.12634,-8.29635,3.98254,-2.55022,3.58933,0.0476173,2.00734,2.85452,5.13863,4.39434,5.86178,1.57419,0.321093,2.11151,4.62819,-0.677836,-1.98205,-7.44972,1.36379,2.52895,5.12261,2.10196,3.15929,2.77152,6.16477 10170.8,10147.7,9240.32,-2.09934,-1.33891,3.77143,6.49402,-6.43302,-0.0826344,0.87837,1.12061,0.421557,1.06025,-1.52903,5.64507,3.68263,3.49536,1.25096,-1.4957,2.92854,4.60413,2.40658,-0.645265,-3.32217,0.987715,2.60908,1.94117,-0.424246,2.85508,2.71473,4.88469 10167.3,10148.7,9234.04,-1.71112,-2.89318,3.67043,1.66277,3.35424,4.57631,10.1924,-0.35173,1.35064,-5.80931,-1.82085,3.64176,4.57117,2.2882,0.924739,-2.41648,2.22467,2.19365,5.80375,-0.426137,-2.32705,-0.919332,2.09081,-2.34116,-2.25007,1.71251,3.40172,3.5108 10165.7,10149.1,9229.23,-1.45001,-3.05548,2.45599,-0.349391,3.71978,4.53119,5.144,-0.0754888,2.20722,-6.90377,0.948441,2.13514,3.08117,1.83942,2.86791,-0.010419,2.66035,5.23219,5.6626,-0.804354,-2.37724,-1.67323,0.673861,-3.53649,-1.59081,1.76997,2.75549,2.29186 10167.4,10147.1,9226.8,-1.49928,-2.70714,1.88393,-0.842721,-0.225431,3.25531,1.41947,0.140255,3.21042,-3.88608,1.41104,1.86088,-0.091131,0.642157,1.94581,0.307133,3.18746,6.22574,4.30938,-1.01513,-1.1936,-1.8575,-0.588364,-1.42784,-2.08205,1.85519,1.46316,1.06047 10171.1,10143.9,9226.48,-2.01672,-2.40053,3.06391,-0.0599903,-8.34303,2.94718,-5.04409,-0.199276,4.0892,-3.68083,-0.226057,2.75547,-0.686676,-0.843757,0.670264,-0.458086,3.08212,7.11729,2.84836,0.933537,-1.50789,-1.59001,0.179663,0.0589795,-2.55704,3.42709,0.775783,0.360096 10175,10140.6,9227.89,-1.34782,-2.60865,2.14445,1.39294,-10.3608,4.5868,-8.2559,-1.78039,0.356678,-10.0047,-3.28868,2.87133,1.85333,-3.67234,1.53223,-1.27653,0.113475,6.97877,4.49731,3.38158,-3.24882,-2.09817,-0.213742,-0.816136,-3.92766,4.36792,1.46638,-0.25462 10179,10139.5,9231.01,-0.683001,-1.14693,0.835389,1.45465,-4.93888,6.92044,-3.2459,-1.76518,-2.11784,-11.5638,-3.99539,3.25477,2.97649,-3.54233,2.62301,-0.286071,-1.99677,5.44349,5.35012,2.55683,-3.04093,-1.82791,-1.42661,0.583625,-2.6178,3.43693,2.29735,-0.308687 10185.5,10142.2,9235.77,-0.0852919,0.0218383,0.522022,1.091,-4.00515,-0.71681,-2.72016,-1.24891,-1.4593,-5.53454,-2.81228,2.98724,1.40275,-1.35994,4.37674,1.00841,-2.02092,6.34309,4.01241,0.223476,0.719167,-0.617158,-1.79277,2.19906,-0.00915837,1.60933,1.1106,-0.276707 10194.7,10147.7,9242.28,-0.507821,-1.45713,1.82236,1.06383,0.990703,1.16431,3.40878,-1.35424,0.436421,-3.7364,-2.82733,0.844561,2.18188,1.42103,2.14788,-1.48658,-0.956157,3.31294,2.03859,-1.09837,2.11718,-0.147919,0.113767,0.665977,1.0134,-0.758268,0.662046,1.48327 10202.3,10153,9250.68,-0.953894,-1.28733,1.09826,0.183582,-2.63676,-4.1377,-2.89907,-0.851983,3.07691,-0.452803,-2.18838,0.00930997,2.87142,4.0314,0.911046,-1.55443,1.18147,4.24956,-2.48362,-1.23019,1.72571,2.11001,5.29268,-0.281886,3.31927,-0.100871,1.85826,4.09941 10205.4,10156.4,9259.89,-1.27754,0.134823,0.181405,0.430733,3.94306,1.54036,2.99815,-1.16285,4.70226,-4.24342,-1.81256,1.00154,4.93307,6.24027,-1.59843,-1.48742,2.34844,2.10305,-2.00905,-0.662325,0.626241,1.17997,6.74123,-1.67701,1.35772,0.491316,4.32271,6.53414 10204.9,10157.9,9267.94,0.0906612,2.16352,-0.379486,5.42194,2.73054,2.84047,-1.4914,-1.83181,4.02307,-5.15449,-0.262248,3.79351,5.21678,7.80905,0.384689,1.27337,2.9796,6.90988,1.28339,2.20996,-0.91791,-0.163496,3.78903,-1.75168,-0.655347,2.9127,4.88667,7.66747 10203.5,10159,9273.39,2.81598,1.22437,-0.368556,7.79675,3.42922,7.94279,4.57077,-0.708312,0.0968463,-6.10539,0.906129,5.55489,5.11842,8.21484,-0.0671665,1.22889,2.37144,6.24544,4.97372,3.9233,-2.49967,0.267274,-0.310124,1.09266,-0.410233,4.04567,4.74621,8.0612 10203.2,10162.2,9275.77,5.91857,0.355765,0.897437,11.4606,-3.5509,6.21936,2.57301,-0.0103725,-3.12789,-4.93913,0.601331,6.94209,5.77388,6.93334,1.15761,0.716978,2.28439,10.4648,4.58557,4.39511,-2.76356,2.73426,-1.51427,4.03252,2.99548,5.47757,3.66414,6.66569 10203.5,10167.2,9275.21,3.60261,-0.370029,0.212296,6.53742,-1.17501,1.39057,4.60494,-1.59955,-3.36286,-6.83681,-0.619753,2.05525,7.21718,4.0699,-0.311278,-1.80144,1.07578,6.02142,4.81799,3.05296,-1.94492,1.84126,-1.66326,1.40391,1.77364,2.95825,3.1993,3.61198 10203.2,10169.7,9272.52,1.94895,1.27875,-0.411546,7.45768,-3.75161,0.551798,7.13428,-3.82068,-2.61405,-4.51085,-0.839975,-0.654388,7.59238,3.63367,1.11679,-0.895324,0.0589114,6.72608,0.605615,-0.28023,-1.84675,-0.134175,-0.468956,-1.06577,2.10307,1.19208,2.14254,2.35948 10201,10166,9269.14,-0.454618,0.774031,2.06017,2.8462,-0.622985,0.18548,5.53147,-2.50822,-2.46147,-4.96779,0.0109421,-5.95039,4.88549,1.45711,-1.36876,0.21175,1.58667,0.959389,-1.72767,-0.999701,-1.91612,-0.271218,-0.271307,-3.60937,2.2528,-2.81471,1.29832,0.342989 10196.9,10158.5,9266.51,1.16537,-1.9421,4.60098,6.66208,-8.91079,-4.05041,0.977918,-0.375912,-2.52562,-2.44083,-1.83608,-5.04574,0.870179,-2.88837,0.903319,2.45464,2.77487,7.13809,-7.32993,-2.29902,0.410437,1.61472,1.76486,-2.68616,2.88565,-3.79142,-0.830458,-1.20118 10194.1,10152.5,9265.18,-4.11534,-5.864,4.81522,5.05616,0.145339,-4.93641,2.59855,0.656712,1.10696,-4.83177,-6.68192,-7.2593,-1.01756,-6.50992,-0.623669,0.165413,3.83811,5.84041,-5.84841,-0.103661,1.98729,0.416145,1.34348,-6.16515,-2.67871,-5.57128,-1.65554,-3.26762 10194.1,10148.4,9264.07,-6.59722,-4.92656,-2.01588,3.7417,0.726794,-18.2936,5.15057,-0.276157,1.50739,-0.538248,-8.52874,-4.00362,-4.55022,-5.27015,0.604573,-0.930054,-0.109161,8.19838,-8.17669,-2.1092,4.17484,-1.56197,-1.02102,-5.8341,-5.50376,-1.7134,-2.50895,-3.06608 10193.9,10142,9261.25,-7.62788,-2.98611,1.9356,-1.40885,17.3716,4.06957,22.1809,1.39972,5.64224,-7.94302,-5.59134,-1.45901,0.439725,1.11211,-6.73411,-3.11746,1.4598,-4.78344,-2.09513,-0.404037,0.473396,-4.22587,-2.43839,-5.70551,-5.26427,-0.515338,1.20082,0.113119 10190.4,10132.9,9256.55,-0.061965,0.47587,-3.01478,1.28661,-2.15014,-14.2047,7.89898,0.463674,0.911903,2.0883,-1.64338,3.11185,-2.21723,0.781415,-1.37312,0.396228,-1.38267,3.09944,-1.8496,-1.29836,2.6087,-3.15966,-2.03297,-3.33185,-3.23065,2.92606,0.328003,-0.0324179 10185,10126,9252.36,-0.460313,1.71643,-3.7396,-2.47922,-1.49725,-15.3645,-1.80975,0.715758,-0.981069,-0.691494,-0.794101,-0.106849,-2.08179,-0.30971,-1.53311,0.428815,-0.320026,-0.221114,2.28648,0.175576,3.04606,-1.33911,-0.290353,-5.37868,-3.63253,0.919151,0.306196,-0.421839 10178.6,10124.8,9251.04,-1.00256,1.33259,-4.2472,-1.03971,2.95821,-4.55752,1.84476,0.117356,-4.36831,-4.27268,-1.02576,-0.886254,0.661063,-0.0446314,-0.718596,-0.508343,-2.00182,-0.337999,2.57329,-0.613947,2.18595,0.685998,2.2221,-1.4549,-2.89677,-0.0111036,1.2411,0.83044 10170.8,10127.6,9252.97,-1.71108,0.0714348,-2.91875,-0.0818013,10.0027,5.28964,4.84662,0.115636,-5.97389,-2.97492,0.466922,-1.16018,3.14319,-0.484977,-0.73996,-1.40938,-2.86898,-1.18229,2.85098,1.59393,-0.709864,0.769892,0.0526875,0.667581,-4.09633,-0.130706,2.87503,0.28772 10163.4,10130.8,9256.69,-0.0482655,-0.561906,-4.41924,-1.93638,1.00001,-3.80859,-6.74655,-0.693966,-6.90741,3.83606,-0.443929,0.133173,1.32042,-4.12952,2.21239,-0.401666,-2.83084,1.48444,3.60821,4.7162,0.0479322,1.57325,-2.9423,0.781086,-3.57562,1.01359,1.5974,-1.03302 10159.1,10132.9,9259.9,0.830676,1.38376,-3.59798,1.88876,1.90766,6.33722,1.16568,-1.88109,-5.49532,7.56995,-3.97276,2.47056,-1.10217,-4.02745,0.530141,-1.80729,-2.44923,1.11112,6.04583,5.79514,-1.61378,0.146823,-4.31812,1.65679,-0.82556,0.385538,-1.6035,-0.921055 10159.8,10135.2,9260.63,-0.16576,1.00018,-5.12473,0.442361,0.505831,-5.64864,-2.63413,-2.52592,-5.46478,4.95174,-4.3147,0.782684,-5.73615,-4.82371,0.266276,-1.86669,-4.0481,-1.31822,9.03428,5.18538,0.835431,-1.04748,-4.21294,1.0615,-0.105573,-1.22812,-5.24566,-3.63422 10165.2,10138.1,9258.46,0.205477,-0.680098,-4.46762,5.26891,1.18115,-1.68502,7.13137,-1.22722,-4.01706,-1.7858,-0.511666,3.55446,-3.85553,-2.43205,1.3525,-0.694302,-4.16672,-0.729833,7.26617,2.38627,0.742375,-2.04911,-3.24066,2.72775,2.10783,0.115275,-4.78462,-4.34396 10171.6,10139.6,9254.61,-1.51268,-2.23477,-5.13237,-3.29461,-0.317239,-10.5071,-7.94002,1.87205,-2.15615,-2.57627,4.52526,1.46446,-2.39092,-3.68309,1.44927,1.27351,-2.10555,-3.67494,7.0263,3.64847,0.370668,0.612656,-2.452,4.76347,5.31087,1.21101,-2.18927,-4.86589 10174.6,10139.6,9250.85,-0.380976,0.430706,-4.77251,1.24603,3.57465,-3.14504,-10.8805,1.4131,-3.82203,6.1265,4.05681,1.86576,-2.69539,-3.84931,0.571097,0.0445532,-3.61574,1.0929,5.45496,4.67637,-2.69117,0.376736,-3.44843,8.26613,5.44059,2.39248,-1.35143,-3.43895 10173.2,10141.8,9247.9,-0.967231,0.660605,-0.333774,0.682442,10.1733,9.80472,-4.02844,0.296976,-2.0856,1.70749,0.105393,-0.302007,-2.02762,-1.68176,-2.57321,-1.85542,-2.20576,-3.56605,7.81712,4.57148,-0.717533,0.00661063,0.070936,7.88567,3.00205,-0.188925,-1.30646,-0.417109 10169.8,10147.8,9245.05,1.57911,1.89614,-1.23894,5.44327,1.1255,2.7455,0.888702,-2.69789,-2.29535,1.37374,-2.16695,0.277041,-2.61632,-0.168021,1.19527,-0.966804,-1.39634,2.02717,6.13068,1.74285,2.61838,-0.673957,2.42798,5.71141,1.0237,-0.190537,-2.48355,-0.424022 10166.9,10152.4,9241.4,1.48812,1.56883,0.00439658,-1.99079,-5.3945,-7.45076,-2.79497,-1.09824,0.438405,1.08335,0.567998,-2.12211,0.537132,0.235065,2.13962,0.850241,2.33283,0.11668,5.71046,0.316621,2.37782,1.5783,4.38674,4.44102,2.85837,-0.867284,0.197126,-0.632035 10166,10149.9,9237.21,3.10346,3.20745,-0.0787972,3.26164,-1.99167,1.15174,7.73898,0.388067,-1.3872,7.93093,2.89628,-0.846609,2.95243,1.10786,0.0356645,-0.191303,-1.48335,3.06518,0.833731,-2.48298,-2.62814,-0.329278,-0.0454046,4.84244,1.50962,-0.571214,2.28968,0.0896905 10169.4,10141.9,9233.72,1.54047,2.79665,0.872984,0.435893,0.341067,4.50191,6.31086,2.24353,0.0763229,5.33021,2.30696,-1.94916,2.28551,1.6759,-3.55737,-0.57595,-3.31446,-1.28349,0.109544,-0.911539,-3.08755,0.149125,-2.57658,2.65457,-0.759677,-1.72314,1.73795,1.22082 10175.5,10134.5,9231.85,3.08721,1.31195,-0.463831,-2.78365,-16.0641,-12.4959,-7.90321,1.44639,2.2521,2.09953,-0.628689,0.674957,-0.991746,0.999703,0.501374,1.08647,-1.9555,-0.457535,-1.969,0.140249,0.679574,4.05153,-1.26929,2.9472,1.23177,0.0460567,-1.18548,1.19414 10178.5,10132.3,9231.94,4.8578,-0.156201,-1.83619,3.45539,-10.5983,-4.40534,-3.25278,-1.48511,1.7839,1.07398,-3.79721,3.44697,-0.661031,-0.19397,1.51898,-2.78611,-1.58924,-1.02247,-4.03291,-0.779814,-2.72459,1.42865,-4.44874,1.96164,0.024013,0.769821,-1.68183,-1.09525 10176,10135.5,9234.24,3.98434,-2.9881,-1.82932,-3.45496,-4.37718,-1.32479,-6.81161,0.242295,3.63988,0.773917,-2.92089,1.50769,1.03257,-1.29175,0.607123,-3.32519,0.794345,-7.2134,-4.18473,-2.11878,-3.48641,2.04926,-1.83971,2.5711,1.8547,-0.444122,0.204744,-0.633906 10170.3,10141.1,9238.24,4.5574,-1.21766,-1.92884,-3.3891,-4.53289,-3.61119,-11.1428,0.87067,2.52674,6.28098,-0.916225,0.833349,-0.285056,-2.02874,2.83162,-0.822357,0.836116,-2.02452,-4.36166,-2.46534,-2.40599,3.53798,0.439996,2.8824,2.66576,-0.190266,-0.411649,-0.335746 10164.8,10146.9,9241.73,1.14271,0.21175,2.54403,-5.97996,8.86795,9.92082,0.583279,0.92891,3.1377,1.52082,0.653327,-2.04189,-0.909795,-1.88382,-1.45444,-1.72465,2.94817,-6.9659,0.661566,-0.779148,-2.33549,3.61435,1.90115,-0.709103,0.572663,-2.44443,-1.61985,-1.24632 10161.8,10151.9,9242.42,0.429305,-0.24402,1.54324,-0.758714,1.99988,2.30697,-0.150645,-1.67843,-0.372931,2.68223,0.974669,-2.18675,-3.69726,-3.84373,0.315076,-1.61503,2.02219,-0.439987,1.5067,0.347441,-0.468043,1.85512,2.51346,-3.61534,-1.61311,-1.68631,-4.32277,-3.31289 10160.6,10154.5,9240.5,-1.6783,-2.7916,3.79283,-1.46484,1.8842,7.0456,3.61276,-2.08564,-1.14902,-3.90469,1.00738,-2.71903,-1.12392,-2.56102,-0.564502,-1.26929,2.87817,-3.80446,2.16188,1.69189,-0.17359,-0.806729,4.45158,-4.99401,-1.9224,-2.1335,-3.41399,-1.5215 10158.8,10152.9,9238.94,-1.26294,-1.55708,2.47997,-0.37092,-5.35681,-1.99801,-4.61673,-3.19995,-3.63982,-3.59422,0.268397,-1.15304,1.21312,-1.94008,2.37467,0.463918,1.03699,-0.249188,1.94821,3.1095,0.656428,-1.26258,5.17342,-2.5293,-0.911564,-0.727538,-1.60047,-0.657086 10157.1,10148.4,9241.47,-0.729297,1.90628,1.50273,8.02209,4.5029,7.25435,-0.943104,-3.87229,-5.15977,-0.605295,-0.786266,-0.00624273,3.2036,-0.99694,1.83674,-0.424322,-0.759934,4.69506,3.12589,4.93905,-1.14094,-2.37706,0.896838,-1.15642,-2.07425,-0.341439,0.651623,-1.90525 10159.3,10145.1,9249.53,-3.61489,-0.368775,4.8318,0.654323,13.8953,20.2332,9.01061,0.740005,1.06482,-1.98312,1.43178,-2.39481,5.44965,2.23927,-2.07082,1.84445,3.36316,-2.3874,5.82791,5.13504,0.331121,1.17574,4.11636,2.46863,2.53744,-2.31289,3.73605,1.261 10166.4,10146.2,9260.39,-0.690065,-0.196533,2.57149,3.28245,1.26863,3.07282,2.3288,0.343504,0.7493,7.7189,2.47287,-2.19401,1.83016,1.49389,2.04941,5.57015,1.68587,7.37325,4.33035,3.86901,3.21355,1.31074,4.30838,4.34097,4.14204,-0.792683,1.91579,1.4487 10174.6,10153.3,9268.63,0.973864,0.288282,4.67663,-0.604468,1.35396,1.77193,6.1612,0.928573,3.56181,0.301872,1.61496,-1.94891,1.37811,1.784,-0.829802,4.5252,2.98522,2.05165,3.03006,0.33278,4.9167,0.692046,4.78248,3.89965,4.1223,-1.28055,0.902128,2.44014 10179.4,10165.9,9270.91,0.383028,0.372248,2.91142,5.26445,-4.52355,-0.481389,-1.47582,-0.0802922,4.09074,-3.4789,-1.84054,-0.641665,1.60157,2.15213,-0.406849,1.24052,1.05589,7.69175,-4.79723,-3.42058,1.48542,-2.69221,-0.604027,-2.8823,-1.41943,-0.386671,1.59434,1.71786 10180.9,10180.3,9268.76,-7.39108,-4.07938,1.96913,5.84801,-1.99672,13.1344,-8.45676,2.45664,8.74322,0.00440195,-3.70354,-4.02376,5.09873,7.07674,-2.94009,-6.27334,-2.18896,9.06615,-15.5002,-6.518,-12.659,-9.2251,-8.78964,-16.0646,-15.2285,-1.36974,7.28841,2.96689 nipype-0.11.0/nipype/testing/data/fmri_timeseries_nolabels.csv000066400000000000000000002022421257611314500245600ustar00rootroot0000000000000010125.9,10112.8,9219.5,-7.39443,-8.74936,7.28395,13.7953,32.2328,32.4809,18.958,-12.2383,-6.86466,-23.0912,-16.425,-5.70842,11.2467,-1.58574,-4.53717,-17.3842,0.912601,13.0428,2.44622,2.08875,-8.74373,-9.47217,-6.87574,-8.11158,-14.54,0.414787,6.04424,0.540389 10136.8,10115.1,9222.54,-0.120582,-1.94906,6.92247,4.75197,11.0735,0.972766,10.2285,0.717545,-1.04488,-7.64424,-2.10875,-2.44368,1.52535,-1.14131,-1.72589,-1.1247,-0.993354,2.98318,1.29855,2.0688,1.00297,0.135373,-3.25325,-3.12065,0.913296,-1.7868,1.58829,-0.735248 10148,10122.2,9228.62,4.24336,-0.689111,5.12782,0.132862,-6.64526,-14.7952,5.19361,3.68198,2.77598,-0.691866,1.07559,1.71444,-1.30287,-2.75746,1.74208,4.75944,1.80799,-0.064464,2.37174,1.09905,3.5756,2.98064,-0.238711,0.822007,5.07188,-0.864496,-0.208741,-1.31367 10156.6,10132.2,9236.11,-0.047434,-1.79438,-0.767925,-3.78683,-2.46365,-12.9433,2.00586,-0.48292,1.16216,0.113706,-0.639879,-0.0445654,-2.82995,-2.22008,1.46544,3.70217,2.84476,-3.32792,6.701,0.982599,0.145487,0.0501163,-1.16747,-0.630382,-0.0550437,-0.0563951,0.0449386,-0.715988 10162.9,10141.8,9243.46,-0.3687,0.640608,-2.93969,-0.37466,-5.42813,-8.55527,-4.70566,-3.62351,-3.94857,0.847112,0.357187,1.39279,-3.07124,0.779726,5.12671,3.62277,2.86265,3.44378,5.49842,0.895482,-2.1777,0.14728,-0.491475,-0.0257423,-0.32504,2.28464,-0.610659,2.01955 10168.7,10149.5,9249.62,-0.272231,3.00751,-2.20783,-5.50238,-1.65733,-2.39574,-6.82249,-1.5591,-5.38806,-0.315138,2.41171,-0.227563,-0.306796,1.26618,4.45885,3.55662,3.14737,-0.0497907,2.76691,1.04757,-2.50276,3.25334,1.90194,3.54754,3.2308,0.393197,0.115407,1.88919 10175.3,10155.8,9253.09,0.271133,3.11725,-1.24188,-5.32432,6.94595,5.40219,2.63329,1.77742,-0.434798,3.20784,3.1926,-2.12653,1.4207,-0.162939,1.57116,1.20026,2.14004,-4.36978,-0.074248,0.344989,-2.79157,3.57441,2.795,6.81971,4.61981,-3.15395,-0.556388,-0.951462 10181,10160.9,9253.62,-1.52186,-1.02665,-1.31765,-8.89055,1.45638,-6.40533,-8.20284,3.42071,6.34151,7.32703,2.81444,-5.56924,-2.07761,-2.82472,1.75969,1.56549,2.59032,-4.99642,-0.861721,0.661704,1.27294,4.24609,5.72265,7.93181,6.46356,-4.54558,-2.93302,-2.55741 10182,10163.1,9253.53,-4.12759,-5.01517,-1.383,-11.7032,7.03273,-0.354258,-4.14846,2.56836,5.49077,2.70724,-0.00938943,-7.91268,-3.33257,-3.77932,-2.70035,-1.95288,1.51899,-10.5021,0.604386,1.13765,2.8031,0.719838,5.10986,5.4321,3.01561,-5.05514,-2.51591,-2.29453 10178.9,10161.7,9255.33,-2.09727,-3.23639,-0.971464,-6.47564,-1.86208,1.47429,-8.69004,2.23012,2.64935,4.20852,-0.00802028,-4.11236,-1.54808,-1.73414,-2.21966,-2.31888,0.521142,-4.49634,-1.66003,1.37105,1.47741,-1.17943,3.52554,2.31201,0.381259,-1.24137,-0.930002,-0.860505 10176.3,10158.2,9258.8,-2.87976,-1.16821,-1.15587,-7.36873,-2.70663,3.69409,-6.23946,3.17083,3.67683,5.95472,2.6739,-2.5798,1.61294,2.31642,-4.31408,-1.6647,-0.422612,-6.13843,-0.39141,1.92345,-2.82275,-0.742784,1.68164,-0.706688,-1.87652,0.172975,1.51911,1.04727 10176.2,10155.4,9261.93,-1.79655,0.511159,-2.91648,-1.19976,-6.01265,2.43062,-4.91165,1.64787,2.485,6.04132,2.79139,1.36683,2.36631,4.70105,-3.09068,-0.875835,-2.73203,-1.04036,0.0279962,0.57264,-4.70596,0.399049,0.109101,0.540718,-2.52779,1.90878,1.47212,2.48712 10177,10154.3,9263.36,-2.06935,1.47151,-1.59814,1.1621,-8.21806,2.74994,-4.8666,1.6535,2.86737,3.56179,1.87379,3.98852,2.20191,7.00018,-2.12026,-0.322149,-0.459427,1.99009,-0.386875,-1.65524,-2.88602,2.5405,3.09752,5.52644,1.72241,3.28467,2.06659,4.48929 10176.7,10153.6,9262.97,-2.47996,0.0736981,-1.18826,-1.40068,-2.38119,-1.33094,-3.87199,0.498621,1.31667,-0.952908,0.481976,0.0885501,1.11339,4.67043,-2.37383,-2.32579,0.991108,-0.25346,2.41941,-1.44295,0.0394728,1.67752,2.73018,4.10445,2.29859,0.993454,2.7469,3.39394 10174.9,10153,9261.77,-0.957748,-0.455644,0.885525,1.7746,0.0437147,0.878291,0.0855234,-0.572903,1.39546,0.00119098,1.69176,-1.96049,0.156938,2.84845,-1.18488,-2.65197,1.35428,1.98606,1.65427,-0.643756,-1.03602,-0.0406435,-0.236011,-0.961959,1.28125,-0.464305,1.75539,1.84618 10173.4,10153.5,9261.3,-0.583682,-0.792331,1.36077,0.644185,-3.55594,-0.618864,-4.88099,-0.136266,1.51362,2.73872,3.65897,-2.63062,0.416981,0.735765,0.533665,-0.326252,1.0146,2.83848,2.16063,2.30307,-2.01136,0.638055,-0.22921,-3.19692,0.947596,-0.379132,0.678065,0.747812 10174.5,10155.7,9262.24,-0.685336,0.856591,-2.63545,-0.959601,3.25442,0.791955,-2.20612,0.263046,-1.34292,4.47114,2.99912,-2.56858,-0.21931,-1.56389,-0.808263,0.311028,-2.34261,-0.965718,1.98615,3.50723,-1.41951,-0.258476,-1.16227,-1.73014,0.372641,-0.118946,-0.422557,-1.3986 10179.6,10157.8,9264.01,2.59538,3.68921,-1.9033,3.99249,0.109215,-1.86778,-4.51336,0.591929,-1.29086,1.52475,1.01934,0.773735,0.0652847,-3.00075,1.79923,2.1369,-2.11635,3.17035,-1.87907,2.19309,0.880052,-0.480886,-1.94369,-0.204693,1.63785,1.43004,-2.081,-3.24652 10186.9,10157.6,9265.4,2.10402,4.02633,0.884264,0.1708,-3.27208,-4.9215,-1.0364,1.60796,1.70888,-1.43476,1.10519,1.26841,0.0627916,-2.97727,1.13683,2.82663,-0.301705,-0.592683,-3.81587,-0.70989,1.60855,0.103857,-2.48043,-1.22737,-0.312858,1.31617,-1.91269,-3.98886 10192.2,10155.4,9265.29,1.6824,4.26755,1.57687,1.43194,-5.98808,-2.25097,0.153789,0.168572,0.879003,1.68604,0.75956,3.65922,-0.869793,-2.49312,0.497574,2.41553,-1.34226,-0.127659,-3.59295,-1.56547,0.88849,-0.785242,-4.24845,-5.15572,-4.81836,2.77035,-1.44493,-3.44434 10193.6,10153.7,9263.38,1.6491,4.80854,1.08823,5.10222,-5.26833,5.52263,-0.997094,-0.959485,-1.52356,6.15147,0.897033,7.60472,-1.50848,-0.576994,0.845199,3.25263,-2.21353,2.36454,-2.11918,-0.480371,1.405,-1.24949,-1.88424,-5.50221,-4.39822,4.6832,-0.575266,-0.350337 10193.7,10153.5,9260.14,0.371243,3.4575,-0.922956,2.86612,3.70316,4.4652,-2.35097,-2.08567,-4.55866,2.05406,0.20181,5.48777,-0.851734,-0.932792,0.852325,2.66059,-2.76402,-0.836483,3.32512,2.58318,3.54953,-1.82575,1.03107,-3.58566,-4.1055,2.71087,0.64122,1.16036 10193.4,10154.1,9256.45,0.655998,2.95689,-0.961572,2.95967,6.90968,-0.0847335,-1.13659,-2.64581,-3.78971,-2.43015,-0.722449,3.08777,-0.234356,-0.603156,1.30068,1.14368,-2.23215,0.241084,3.91588,3.38796,4.07024,-1.08082,1.15617,-0.375163,-2.54369,1.29418,0.795869,1.31402 10190.3,10152.8,9253.2,2.59279,1.93007,1.93861,4.82647,-1.84288,-5.84018,-7.03235,-2.16958,-0.8999,-4.4747,-1.99497,2.40008,0.0349671,-0.825783,2.00993,-0.184404,-0.576706,6.30193,1.43455,3.63536,2.34484,0.148851,-1.22127,-0.718508,-0.716753,1.50537,0.412978,0.73252 10185.2,10148.2,9250.73,1.88291,-0.127643,2.41457,0.38457,3.28565,2.40364,1.07674,-0.352091,-0.192694,-2.80281,-2.45121,-0.746935,0.454781,-0.345492,-2.38393,-2.35152,-0.468918,-0.28004,0.207449,2.6636,-1.39254,-2.09536,-4.44811,-4.48824,-2.93117,-0.770421,1.19,0.219788 10183,10142.2,9248.93,3.78484,0.701338,-0.71552,3.48407,0.454755,4.3743,3.68099,-0.668556,-3.42636,5.52772,-1.23863,-0.405148,0.665698,1.06479,-0.0251586,-0.48849,-0.847741,1.4814,-5.36764,-0.405219,-1.51485,-3.88226,-5.12764,-5.33767,-4.3365,-1.173,0.417418,0.415356 10185.4,10138.4,9247.93,3.11727,0.196163,-2.018,0.721283,-2.5075,-1.06349,0.331823,-1.2182,-4.01712,4.78444,0.452166,-2.16432,0.55673,1.61447,1.16718,1.44415,0.569846,-0.812131,-8.14324,-2.91296,2.43154,-1.45218,-0.730675,-1.0947,-2.25658,-3.52675,-0.361214,1.09266 10188,10139,9248.05,1.52249,-1.16117,-2.4591,-2.41492,-0.35832,-7.48161,-0.0490082,-2.1421,-3.52013,0.903896,-0.958215,-5.8036,-2.36788,-0.368615,-1.88998,-1.40466,-1.28791,-4.79995,-5.58563,-3.57656,4.13739,-0.274441,1.53352,2.93946,-1.96753,-6.76034,-1.87752,-0.324793 10186.8,10142.9,9249.23,2.29541,-0.414867,0.263844,-2.42527,-9.23597,-12.7958,-5.40665,-1.3296,-0.255947,1.05195,-3.09731,-3.83996,-4.40177,-0.0123634,-1.79533,-2.22933,-1.59891,-1.58539,-4.29444,-3.24283,2.73497,0.939395,2.25632,3.98042,0.672842,-4.87272,-3.0871,0.140664 10183.8,10146.3,9250.93,1.04007,-0.107056,-0.719832,-5.17314,-6.41206,-13.4527,-3.51115,-1.82372,-1.0661,0.164654,-4.87432,-3.16371,-3.16216,0.547311,-2.31938,-3.32366,-2.59406,-3.07878,1.07584,0.135595,-0.15385,-0.198986,-1.76614,-0.364142,-1.44816,-3.17832,-0.666637,0.539005 10182.5,10148.1,9252.57,1.58315,0.552138,-2.38854,1.84879,-2.25441,-6.8381,0.208721,-2.73312,-3.19332,-2.49192,-4.21087,0.445019,0.0651566,2.67403,-0.780414,-2.43461,-3.10543,1.48742,-0.123359,0.0321366,-2.00728,-1.30717,-5.02137,-5.05394,-3.39985,-0.233706,2.10556,1.51466 10182.7,10149.6,9253.33,0.671616,-1.8801,-5.19861,1.6691,-0.386439,-6.73637,0.390118,-1.36276,-2.8229,-3.74619,-1.53148,0.15594,0.934737,1.96014,-1.35363,-0.924511,-3.00858,0.653744,-1.84706,-3.59509,-0.247233,0.962108,-1.40552,-3.28119,-2.22432,0.0626129,2.48273,0.969888 10182.9,10150.9,9252.01,0.0166707,-2.52456,-5.48285,2.26653,-2.03587,-6.50283,-1.00325,0.264499,-1.46362,-0.822672,-1.11829,0.403605,-0.734484,-0.382999,-0.186567,1.24812,-2.13095,1.80897,-2.82131,-6.15356,2.54337,2.39696,2.51379,2.41699,0.307725,-0.195503,-0.252349,-0.890546 10182.1,10151,9248.33,-1.21698,-1.52567,-2.334,0.102378,3.74418,-1.36756,3.51501,1.50357,-1.80774,-0.855037,-2.71284,0.0746735,-1.2904,-2.37263,-0.326812,1.37779,0.0811662,-2.04277,0.452769,-4.37491,4.60025,0.785458,0.944597,2.57121,-0.443829,-1.9031,-1.78376,-2.25217 10180.2,10149.4,9243.85,-0.498632,0.815261,-1.05027,1.32586,2.65892,-5.17029,-0.588453,1.63481,-3.33979,4.4087,-1.26981,2.01576,-3.03953,-3.66687,1.33091,1.62961,0.568999,0.53543,0.477935,-1.78405,3.91722,-1.12653,-3.07327,-2.27103,-2.21119,-0.0469714,-3.05949,-3.83303 10176.1,10146.3,9240.54,-0.464849,1.25223,-1.14736,-0.645201,4.96922,-0.805424,1.85313,1.43677,-1.45072,6.22509,1.54511,2.89442,-3.56094,-4.35854,-0.476689,0.39343,-0.929162,-1.07774,0.941846,-0.57756,0.363373,-1.13491,-1.30865,-3.06369,-1.8739,2.47973,-3.19611,-5.38414 10169.3,10142.4,9238.91,2.28739,1.91951,-0.759834,1.17008,-1.10807,0.137649,-1.76481,-0.427729,-0.592675,2.50623,0.607717,4.10404,-2.20382,-5.11375,1.80008,0.383348,-3.40396,4.33491,0.605228,-0.0871236,0.185566,0.480246,2.74078,1.48145,2.07534,4.96863,-2.65852,-5.78272 10162.1,10139,9238.14,2.03262,2.32633,0.46709,-2.26524,5.80967,5.85587,5.67759,0.185696,-0.246666,-0.787877,-0.201738,0.61348,-0.542043,-3.51173,0.345287,-0.426571,-4.01566,0.315299,2.10005,-0.391753,2.39343,1.28396,3,4.99164,5.3145,2.31592,0.0224444,-4.14279 10158.4,10136.9,9237.31,2.77556,2.83113,1.37245,1.19159,2.19923,-2.0116,3.1913,1.03754,-0.929092,0.870894,1.00256,-0.624392,-0.561338,-2.99529,2.23674,0.823539,-1.63024,3.75817,0.298891,-1.18515,4.54738,1.25951,1.91277,3.57793,5.44217,0.785618,0.025315,-3.27161 10158.5,10135.5,9236.37,0.0672571,0.761886,2.35427,-0.889999,6.73976,-1.98269,8.45302,1.1398,0.0604089,-1.15193,1.32222,-2.47069,0.131408,-3.48238,-0.669944,0.753279,3.07189,-2.04262,0.174304,-2.32107,2.83224,0.708328,3.23848,0.984911,2.384,-1.28385,-0.548071,-3.32946 10160.6,10134.8,9236.46,-0.783525,0.239203,0.00548465,1.88108,6.83171,-2.89703,7.27976,-2.71585,-1.47417,2.12383,-1.04536,-1.14095,0.145875,-4.3962,-0.139564,0.781551,3.40043,-0.28834,-0.343608,-2.36391,0.0938093,-0.36295,1.0276,-0.578692,-0.619797,-0.489157,-1.92106,-4.163 10166.1,10135,9239.02,0.124276,1.29463,-1.44975,3.21172,2.53479,-3.38317,-0.20102,-4.72755,-2.14129,5.53743,-1.24849,0.994366,0.436372,-3.09635,2.19121,1.13794,1.52365,3.0586,0.622146,-0.699363,0.103461,0.316277,-1.73095,-0.195395,0.490618,1.44514,-2.50878,-3.62472 10175.6,10136.9,9243.9,1.67228,1.70099,-0.125799,2.04051,6.74509,2.05118,7.82124,-3.08565,-1.70842,3.37127,-0.160655,1.32998,0.57087,-1.46351,1.80831,-0.585194,-0.267853,0.719624,2.12333,-0.931791,2.61407,0.519467,-1.78038,1.70819,2.66646,1.47407,-2.48388,-2.6294 10184.4,10140.5,9249.09,4.05746,1.49391,3.1491,4.74869,1.42089,-7.65297,4.6083,-1.50292,-0.681543,0.792377,-1.54194,2.19467,-1.449,-2.54459,5.38937,-0.0662613,0.683022,6.46847,-1.151,-2.09676,5.40097,0.0884146,-0.584039,0.411805,2.87021,2.70096,-3.69024,-2.72328 10185.2,10143.8,9252.71,2.20708,-1.9117,6.2705,-1.38994,9.88462,0.984595,14.8745,1.09177,3.01497,-6.59006,-3.06879,0.864155,-0.352553,-2.42934,1.6214,-0.899998,2.90809,-2.62154,-0.748965,-1.78716,3.1828,-0.76616,1.51574,-1.80336,0.759499,1.08543,-1.48814,-0.830864 10176.5,10145.2,9254.8,3.08758,-1.24415,2.30133,1.5123,4.9996,-2.25743,5.71269,0.326257,0.862459,-5.32366,-2.15784,1.98295,-0.769376,-3.24456,1.73394,-1.18022,0.303592,1.19388,-1.18318,1.1848,-0.484859,-3.12715,-2.31674,-4.16244,-1.41399,2.32149,-1.0187,-1.70219 10164.6,10145.4,9256.92,1.59078,-1.06701,-0.557541,-2.88977,3.22953,-0.245042,-0.474481,0.0498212,-1.16809,-8.33134,-0.306573,0.38113,0.242976,-2.39828,-1.29092,-1.68013,-0.127576,-1.94114,1.03024,1.7825,-1.44807,-2.86352,-4.13379,-1.78466,1.5241,1.16147,-0.513496,-2.30027 10156.4,10145.9,9260.21,0.0333157,-1.40254,-1.63643,-2.63202,2.15792,2.8366,-1.32406,-2.25364,-4.61227,-7.74587,-1.005,0.107792,-0.131513,-2.0428,-1.28031,-1.65736,-0.0589992,-0.767749,0.0451012,-1.23948,0.334266,-2.05544,-5.74107,1.40617,2.47259,0.129519,-1.22605,-3.50154 10152.5,10145.2,9264.25,-2.23854,-3.34598,0.871046,-4.48776,-5.12246,-0.367558,-7.49548,-3.04105,-2.99035,-3.84367,-2.67766,1.19195,0.695189,-1.99211,2.38266,0.800284,2.92667,1.82052,-0.796218,-1.82753,3.43662,1.60186,-2.49788,2.02216,2.59346,0.975508,-0.397427,-2.78437 10148.6,10141.1,9267.56,-4.64613,-5.4569,3.80281,-6.22039,0.554038,5.00519,-0.395733,-3.04225,0.570141,-6.95862,-4.49105,-0.00732036,3.78285,-2.09066,1.46914,-0.873643,3.95228,-2.08532,2.8568,0.749314,1.78963,1.02579,-0.808831,-1.60113,-1.17483,0.544949,1.95805,-1.27827 10142.4,10134.6,9268.73,-4.02228,-5.3818,4.39201,-6.57399,-2.68308,-0.146626,-0.297909,-1.28233,3.72363,-10.5635,-3.46562,-0.498293,3.92457,-1.10422,0.725311,-0.888612,3.1725,-1.82837,4.64182,1.32637,-0.56378,0.781271,3.29557,-0.557202,-0.712584,0.587691,2.76212,1.05325 10137.8,10128,9266.83,-2.98689,-3.62614,2.49614,-3.78405,5.33483,-3.24499,-1.4797,-1.49474,0.75769,-13.0722,-3.57543,-1.73535,1.13307,-2.81826,-2.67056,-2.75063,-0.407379,-1.38965,7.67619,2.2374,-2.93415,-2.1994,0.956463,-2.25511,-4.42128,-0.889014,2.30781,-0.144069 10139.6,10121.2,9261.84,-1.19244,-2.09691,-1.17019,-2.92359,1.84257,-9.64131,-8.2266,-2.48032,-2.29368,-7.41116,-3.60172,0.404837,-2.31741,-3.52505,-1.14341,-1.1367,-2.22469,2.93998,5.91064,0.841518,-1.68308,-1.06298,-0.398387,-1.68239,-3.53445,0.38234,1.02165,-0.403129 10146.2,10113.8,9255.3,-3.35595,-3.34535,-1.74811,-10.4556,3.60927,-0.776329,-3.08604,-1.29687,0.835023,-5.76979,-1.7646,-2.22816,-1.31439,-0.382083,-1.73312,-0.792276,0.206848,-4.1992,4.29806,-0.830575,-1.71405,1.40452,2.00247,0.106559,-0.768805,-1.08451,1.11784,1.22578 10152.4,10107.8,9249.87,-2.49869,-3.87311,-1.98238,-6.90342,-1.23671,2.90852,2.97754,-0.581043,2.81778,-2.71728,-1.21684,-5.07044,0.497485,2.01224,-0.365556,-1.64542,1.17956,-3.76085,-0.573467,-2.58111,-2.12663,0.378165,4.18795,1.24581,-1.36196,-2.87649,0.482267,1.63454 10154.8,10107.2,9247.27,-4.01788,-5.39388,-1.72161,-10.3153,-0.251037,-1.57831,1.61553,1.18147,5.7765,-0.599766,-1.22598,-10.0294,0.895145,2.02015,-4.45992,-2.58818,2.98391,-9.45103,-1.41902,-1.29446,-0.55725,-0.180421,6.94249,-0.594659,-3.53394,-6.50742,1.38112,1.51458 10153,10112.2,9246.76,-3.24249,-5.01072,-2.02956,-7.46567,0.0264794,-1.5224,-3.31193,1.53111,5.32332,2.5335,0.40251,-7.05633,-0.711568,2.89381,-5.39998,-1.36446,2.04786,-7.02942,-4.53297,-0.88262,-0.357391,0.595822,6.5409,-2.84395,-2.64994,-5.7378,1.39939,2.97985 10148.7,10119,9246.16,-3.96002,-4.42756,-3.26432,-8.69557,4.03628,0.616301,-3.92147,2.76458,1.652,2.17356,4.22927,-4.5247,-2.33417,3.89508,-5.29918,-0.309883,-0.288513,-8.36711,-3.09529,-0.126421,-1.8539,2.38545,3.61409,-1.26649,0.429596,-4.19612,1.45711,3.95651 10145,10125.2,9244.17,-1.75695,-0.511195,-1.73883,-3.34742,-1.26592,5.24499,-3.03549,2.78645,-2.1334,0.220919,5.88292,0.160927,-1.7455,5.37331,-1.59599,1.91312,-0.631146,-3.16886,-2.94994,0.34822,-3.01289,2.84951,0.356135,3.47859,4.18276,-0.12287,0.984563,3.64398 10143.1,10130.2,9241.27,-1.71615,1.12867,1.04805,-6.57347,2.41341,16.2593,7.00371,0.924589,-2.71609,-6.2656,3.57183,0.37743,1.96421,5.66573,-2.3041,2.26799,0.668846,-8.32571,2.30148,2.66333,-1.75615,2.71555,1.44408,6.00224,4.85886,0.685304,3.03234,2.82015 10140.7,10134.4,9239.05,-1.25992,2.46902,-0.556969,-2.76672,5.45596,12.4649,8.36959,-2.49709,-3.8708,-1.40646,1.38854,1.37064,2.12007,3.84209,0.459629,2.15086,-1.24194,-4.15365,4.52043,5.4809,0.876317,0.656659,-1.01116,2.09458,1.65028,2.77599,3.21635,0.381243 10133.6,10137.8,9238.32,-2.22442,1.37094,-0.787327,-1.05469,3.55443,5.14715,-0.0509983,-0.0905216,0.72894,3.96149,2.38061,1.75467,3.09083,4.18358,2.79613,3.29833,0.325666,-0.671704,6.07566,7.72379,3.13564,0.655668,-2.59152,-1.76199,1.58102,4.45884,3.34631,0.480564 10121.1,10140.7,9238.2,-2.17367,-0.866588,-2.79273,0.692199,10.1863,9.97874,6.04483,2.66482,1.76948,2.61332,1.9281,-1.1243,5.03132,3.85731,-0.443337,0.284932,-0.868815,-3.31091,8.51065,6.49177,2.23459,-1.67042,-3.77735,-2.781,-0.902713,1.50205,4.04064,0.197185 10110.8,10144,9237.47,0.303664,0.966366,-2.65365,4.69141,3.98147,5.09796,4.57488,3.26927,0.562439,5.41174,1.92471,-1.15766,3.6349,2.42314,-0.0874924,-0.0560302,-1.22366,1.9914,3.44357,1.69106,1.98031,-1.32375,-0.576816,-1.03349,0.269332,-0.300454,3.28264,-0.458562 10110.3,10147.7,9235.48,1.28867,0.940385,2.1165,-0.581377,-0.643187,-2.16313,1.69237,2.47912,1.37859,3.32286,1.26412,-0.720553,2.36863,-1.25903,0.0706914,0.944374,2.2859,0.229574,1.5842,-0.12766,4.43122,1.34327,3.34673,-0.404948,2.87655,-1.67866,3.04869,-0.25307 10116.7,10150.7,9232.33,0.394714,-0.833445,4.94793,-6.11826,9.22151,2.99358,11.1041,1.15853,2.93899,0.397365,0.0221406,-0.0976144,-1.13452,-3.42557,-3.72862,0.476803,3.69054,-8.12164,2.48493,0.363106,3.87676,0.504363,0.972674,-1.44388,2.15926,-0.828986,1.75931,-0.549928 10121.4,10152.8,9229.14,1.29508,-0.757006,3.12597,-1.6729,7.62364,-0.936804,6.48918,-1.03742,1.86227,-0.262351,-0.75051,2.31301,-4.8422,-4.5034,-2.66476,0.578808,1.27532,-2.04282,3.45288,3.01897,0.564668,-1.21876,-3.06331,-2.70583,0.257935,3.52846,-1.56111,-1.5308 10121.6,10152.4,9226.86,0.677648,0.378414,1.31475,-2.61018,4.91454,0.37514,2.86121,-0.193973,1.93324,-4.63591,1.10695,3.14457,-2.96694,-2.19304,-2.99025,0.50097,0.165722,-0.200595,6.85438,4.63234,-2.47705,0.342532,-1.30419,-0.141339,1.63084,4.32707,-1.19328,0.76139 10120.5,10149.2,9225.49,0.499478,1.88224,-2.14427,-2.77288,10.6927,1.71766,6.49787,0.43981,0.0705592,-5.13201,2.57263,1.48076,-1.20267,-0.591255,-4.74193,-1.79266,-1.46188,-3.42451,8.04316,3.54243,-2.30088,0.0710442,-2.83238,0.653942,0.240506,0.904871,0.430945,1.6283 10121.2,10144.8,9224.89,1.35965,2.80608,-1.94166,1.75583,0.26227,-8.26437,0.567312,1.6259,1.60009,0.0627174,2.62631,2.65738,-1.31444,1.36503,-0.138702,-0.303116,1.07964,0.805711,0.6712,-0.0379901,0.596301,1.49046,-2.9437,-0.0854658,1.7116,1.14138,0.19577,2.11315 10121.7,10140,9224.64,-0.625981,1.46152,0.571473,-0.708952,-3.97306,-7.60183,3.54876,2.52756,3.43643,-3.37318,1.25185,1.95327,-0.430742,1.99167,1.38528,0.439469,3.35733,-3.21518,-3.33649,-3.33716,1.63613,2.87364,0.216347,-1.19264,2.34646,1.38095,0.250252,2.26893 10117.5,10135.7,9223.59,-0.644241,3.50756,1.18011,1.32346,-4.09529,-1.15572,8.91836,0.864807,0.810206,-4.21922,0.85698,1.54667,-0.984211,1.49262,0.424346,0.272079,0.55043,-3.11065,-4.92549,-5.21789,0.616593,0.933381,0.453042,-0.907799,0.816878,0.888407,-1.07882,0.897744 10109,10134,9221.44,1.24811,3.97674,3.11247,-1.16572,-9.20759,1.26864,10.07,0.861166,0.629341,-5.07074,1.84156,0.554677,0.501606,2.3508,-1.99158,1.42546,-0.0624237,-4.75601,-4.11731,-5.27973,3.12042,0.927954,2.01431,1.91643,2.26937,-2.42322,-1.85499,2.11246 10103,10135.6,9219.87,2.2046,4.10281,1.87105,-2.44462,-1.81059,2.73657,16.517,1.49188,0.862687,-1.50652,2.91423,-2.27191,-0.311967,3.16828,-6.05317,-0.647296,-0.600809,-9.86797,-3.317,-4.05579,3.51099,-1.77799,-1.17227,0.17711,-2.12588,-5.86398,-2.08211,1.43944 10103.9,10138.7,9220.3,3.77174,5.49059,1.2637,1.03751,-12.6254,-6.24364,0.90728,3.65224,3.71822,2.59825,4.31988,1.86088,-2.62582,4.43061,-1.00461,2.10803,1.47555,-3.28777,-8.18549,-4.31695,2.95113,-1.34785,0.676274,-1.38936,-3.04336,-1.37001,-2.35773,2.00922 10108.6,10140.8,9221.82,-0.70593,3.90046,-1.14247,-3.0764,-1.47295,-1.10809,-0.510284,3.79285,2.60078,-1.28697,3.77566,2.32766,-3.54475,2.99719,-1.20306,1.33262,-0.719923,-9.06449,-7.33119,-4.80493,-0.721145,-2.4024,1.79362,-1.97223,-5.04385,0.0875954,-1.73778,0.950888 10113.1,10142.1,9223.55,-1.06377,0.843971,-1.44889,-5.32939,2.69029,-3.83385,-5.63119,0.535717,-1.61039,-5.59267,1.26514,2.05707,-3.31026,-0.958826,1.33732,1.46551,-3.13585,-9.66605,-6.00234,-4.35532,-0.26599,-0.831562,2.98878,0.128679,-2.54674,-0.278737,-3.58409,-1.324 10120.7,10142.9,9227.01,3.56995,1.04759,3.75113,-1.7421,5.12807,3.1454,2.38504,-1.62768,-2.93793,-5.71266,-0.530001,2.84448,-2.04436,-1.31251,2.17243,2.11298,-0.867238,-7.66197,-6.87331,-3.32769,-0.373459,-0.116178,2.03689,0.379397,-0.00605166,-0.182103,-4.1657,-1.22794 10135.1,10142.1,9232.63,4.13322,3.14571,5.42112,-9.50857,6.61076,-1.5265,-1.3563,-0.229734,-0.953633,-2.39287,0.0907423,-2.25912,-2.95494,-0.622513,-0.878638,3.11006,2.20909,-12.7591,-4.65267,-0.652931,-0.508727,-0.484787,-1.43884,-3.89903,-1.68783,-1.20607,-1.47415,-0.30987 10150.6,10139.9,9237.26,7.08686,7.1115,3.05908,-7.31514,-2.75139,-6.15754,-6.75994,1.34201,0.583247,1.72791,0.0586144,-1.05549,-2.23348,1.35232,0.957745,3.9225,0.27845,-7.28043,-8.71747,-3.21629,1.12263,-1.08286,-3.72117,-4.10901,-0.817087,-0.319549,-0.171801,1.86899 10161.3,10137.9,9238.2,5.45348,5.872,0.0360833,-8.71486,1.68904,-1.57501,-9.84544,2.70784,2.39605,-1.45535,-0.548901,-2.93743,2.31592,2.21738,-0.0678836,1.75621,-1.90485,-7.83172,-5.34721,-0.902631,2.89369,0.938874,1.08004,0.946796,3.39736,-3.2386,1.23533,3.43628 10168.7,10135,9236.89,1.9988,3.16081,-0.959961,-1.65775,15.8147,12.2058,-6.43511,1.69639,2.59198,-2.06327,-0.47323,-4.35241,3.77438,3.79233,-2.16153,-2.08622,-2.56136,-3.89096,-0.736348,5.49778,-0.475583,0.770127,3.05002,3.17719,3.81221,-4.99556,1.59718,3.01185 10178.3,10131.2,9237.28,0.818385,-0.233269,1.46873,6.63122,10.9706,17.5879,-3.54675,0.677416,3.72244,0.655626,-0.201865,-1.16835,1.57109,5.42876,-0.444523,-1.12764,-0.256929,5.62565,-1.99386,6.4084,-2.47406,1.18593,3.2834,3.0293,3.51573,-2.53776,0.959038,3.23253 10193.3,10130.2,9242.16,-2.48525,-2.35837,2.98987,5.98816,11.4719,15.9039,-4.84232,-0.825315,2.54659,1.43064,-0.659643,-2.96556,0.571285,2.41784,-2.00371,-0.757574,1.41844,6.37057,1.42823,7.71148,-4.93994,-1.54988,-0.232174,-1.34349,-1.26249,-2.05601,1.26179,0.464125 10210.2,10133.3,9250.5,-0.302459,-1.69801,0.843368,2.30597,6.15326,11.0157,-5.9274,-1.05244,-1.68469,-0.278629,-0.694935,-0.891837,1.23651,-0.21345,-0.305015,-0.0987808,0.160233,4.91775,0.166271,3.92353,-3.88399,-2.55526,0.198425,-0.923912,-1.86728,-0.552523,1.22445,1.15572 10221,10137.3,9258.6,-1.56339,-0.256664,0.840544,-1.61826,11.0061,14.4706,-2.59098,0.449882,-1.65171,-1.89163,-1.35949,-1.40198,3.60618,0.270121,-1.02351,-1.1912,0.778059,-0.110922,0.867721,2.27546,-5.20223,-2.14642,1.17716,-1.36266,-2.51971,-1.10085,2.42789,2.32548 10222.9,10141.6,9264.61,-4.74868,-0.212232,1.05283,-1.29221,10.744,4.75459,-2.81401,0.644295,0.850172,0.179994,-3.01777,-4.30435,2.71079,-1.12735,-1.29174,-2.07496,1.34575,1.0376,2.5823,1.95702,-4.5778,-1.28586,-0.494008,-4.39926,-5.46478,-2.40477,1.70545,-0.546783 10222.5,10148.7,9269.02,-3.49502,-0.678579,-0.213247,8.06515,8.4472,0.736921,12.8231,-0.680516,1.09355,1.44143,-3.62765,-2.08929,0.194595,-2.35671,-0.392866,-2.86869,-0.655593,6.76095,0.52286,-1.94996,-0.69629,-1.94695,-3.05311,-3.36287,-5.8798,-2.04553,-0.962602,-2.08692 10226.3,10155.2,9271.48,-1.96969,-0.131236,-7.34816,10.3469,1.43629,-18.1274,6.28789,-1.94889,-4.21799,9.10578,-0.96868,-0.513386,-5.07894,-4.75252,3.07715,-1.21549,-4.62974,12.6049,-2.11208,-4.5134,4.07597,-2.26695,-5.31607,-0.080814,-4.75562,0.0499323,-2.60796,-2.05158 10230.1,10151.7,9270.27,-0.441668,1.99564,-2.24149,10.4542,-4.09391,-6.45561,-1.77752,0.712394,-1.02642,8.25875,2.54249,4.31177,-1.67116,1.28898,3.90167,2.27301,-0.292013,13.1856,-3.31394,-4.23242,0.509949,-0.582218,-1.55254,1.54596,0.383257,3.15094,0.659781,3.83919 10224.9,10138.7,9266.49,4.67287,5.1299,-1.26323,13.4301,-10.2745,-9.49416,-12.2719,-1.18436,-2.87586,6.16837,2.83569,6.07774,-2.8315,2.00898,6.40272,2.01559,-1.86315,15.8694,-4.72684,-3.25468,-2.65905,-3.311,-6.24296,-4.21139,-3.70695,4.80612,0.395122,1.76566 10212.8,10131.4,9265.67,3.01888,4.86272,2.80549,9.41976,5.08199,16.7307,3.01517,-1.39232,-0.901598,-3.17761,2.70511,2.89126,0.206015,2.09237,1.79821,0.427067,-0.286912,4.97158,1.88506,1.52106,-4.78901,-3.10639,-5.19696,-1.88352,-1.17405,1.76068,1.66502,-0.462334 10205.3,10137.3,9271.29,5.0191,6.44861,-1.029,10.2232,1.46143,6.79866,-7.1328,-3.52906,-8.32347,-3.93806,2.03961,4.301,-3.73195,-3.92217,6.44854,2.90593,-2.49697,11.4551,-0.562561,1.57056,0.711111,-0.350636,-4.25263,3.76126,3.75639,3.70316,-1.79131,-3.47622 10205.7,10147.7,9278.59,5.83546,6.36501,-0.202118,7.16455,-12.9828,-12.4607,-27.3389,-3.33415,-9.60681,-6.26496,-0.539386,6.78879,-3.91681,-6.10831,9.8609,6.12423,0.502419,17.71,-2.72276,0.90307,5.89102,4.35576,1.47131,6.87862,9.08531,6.44279,-3.45175,-1.92878 10205.4,10153.7,9279.43,2.61204,3.79426,2.8599,4.2373,-6.30104,-6.55433,-17.9117,-2.30217,-4.33352,-8.56342,-2.54108,4.06241,-0.221565,-2.25183,3.87958,2.42384,1.7425,10.0636,-0.274803,1.38918,2.9688,2.49859,1.85002,3.57782,5.56749,4.25356,-1.57246,0.769565 10198.3,10155.2,9271.53,1.79363,-0.436721,3.46418,1.17919,-6.21503,-12.0337,-14.7144,-0.753172,-0.422946,-10.0673,-1.05729,0.16841,0.00393219,0.329848,3.06417,0.641188,1.13987,4.50086,-1.96838,-0.158451,2.22687,1.01485,-0.617827,-1.82684,0.837829,1.35672,-0.969077,2.83866 10187,10154.7,9258.9,0.357944,-3.85399,-0.403587,-0.905802,-6.94279,-16.6984,-17.7781,-0.22625,-1.87358,-4.80273,-0.208291,-3.41762,-1.38116,-0.435891,4.56144,1.47257,0.881539,4.31043,-2.35524,-0.63135,2.49929,2.73787,-0.3439,-0.967951,0.479767,-1.25236,-0.198644,2.70849 10175.5,10150.8,9245.55,-2.22289,-4.64417,-1.57873,-3.37822,-3.35046,-9.88201,-14.3071,0.168661,-0.756661,-2.69992,-1.57269,-4.61371,-0.741804,-0.794809,1.95045,1.34471,1.90438,0.670421,-1.36383,-0.0207592,1.95603,4.44548,1.70081,0.896225,1.96219,-2.68814,1.37985,1.21966 10163.9,10144.5,9233.39,-1.0609,-3.6573,-1.22008,-1.66234,-8.72059,-9.8591,-9.71449,-0.237702,2.4907,-0.383432,-2.45784,-2.52105,-0.451308,-0.95008,0.101755,0.998499,0.0147502,0.763548,-2.08901,-0.286814,2.08671,3.24587,1.98374,-1.03823,1.41551,-1.64013,0.866956,-0.452541 10152.5,10140.9,9224.11,1.58528,-1.3177,-2.21666,-0.770113,-12.1162,-14.2306,-0.877621,-0.372338,1.62768,2.76293,-0.69447,0.389726,-2.24466,-0.492948,-1.07534,1.2119,-2.84085,1.62365,-4.58137,-3.47859,2.38127,-0.58689,-1.20067,-5.12188,-1.38938,0.191315,-1.00868,-0.231626 10144.9,10141,9218.45,2.9188,-0.174985,-4.58083,-6.94645,-12.0718,-23.1781,-6.27315,-0.364715,-3.24703,1.70145,0.993811,-0.598274,-3.56103,-0.759525,0.496704,2.46032,-1.89983,0.597576,-2.01394,-2.93857,4.73883,-0.682548,-1.34504,-3.70636,-1.23983,0.0550942,-2.01066,1.58053 10141.8,10139.7,9215.32,1.06474,0.421951,-5.29652,-9.2234,8.36446,-5.7284,0.960531,-0.909556,-4.90704,0.770291,1.54135,-5.62095,-2.20122,-1.09503,-2.35206,-0.974175,-1.0101,-7.23319,3.01594,0.768168,2.39478,-1.32615,-1.6404,1.53725,-1.51813,-3.97654,-1.7665,0.833795 10141.4,10134.3,9214.23,0.86273,1.35397,-0.657898,-4.72598,2.71892,1.93911,-8.71178,0.127278,0.812447,5.14689,3.34014,-5.47575,-0.124804,-2.70815,-0.541837,-0.600256,1.53834,-3.53843,0.0605411,2.43643,0.689316,0.936364,1.45495,3.58725,0.917646,-4.12549,-2.16127,-1.91164 10145.6,10128.8,9217.09,0.035273,1.26692,3.11502,-4.96307,-6.78084,1.02172,-8.79811,2.69846,4.94751,11.3598,6.51275,-2.0705,0.657905,-2.59061,-0.35795,1.18908,3.42851,-3.05799,-3.41004,0.806424,0.399374,2.92706,4.4301,0.273598,0.553543,-1.76552,-0.755718,-3.46001 10157.5,10128.8,9225.31,0.248702,0.312336,2.57768,-4.36878,-7.1619,-0.049009,-3.2758,2.7151,1.99544,11.1247,7.80862,3.2311,1.05086,1.13953,0.117826,1.5885,2.6575,-2.74279,-2.82058,-0.206648,1.25493,1.71967,2.81266,-4.13773,-2.45207,2.50385,0.789243,-0.268176 10170.7,10133.1,9236.11,-2.23675,-0.885477,2.34602,-6.30375,3.19378,12.3402,5.26964,2.51006,1.86666,4.33237,6.63528,4.85198,3.48519,8.46812,-2.52066,-0.634166,3.57125,-6.40349,1.46869,0.818123,-1.68738,1.2743,1.91738,-0.951766,-0.403311,4.63843,3.18061,7.04436 10176.7,10136.2,9243.78,0.782244,0.338989,-0.179665,0.677035,-11.8864,-9.98092,-16.6014,-0.0876104,-1.39338,0.511794,2.05749,5.37285,2.64871,7.7119,4.8232,-1.23349,2.56586,8.98335,0.643413,1.73431,-0.63479,2.49537,-0.600719,2.26345,1.69812,6.71431,2.31721,8.10433 10176.8,10136.6,9245.84,-3.20567,1.13405,3.92668,-1.78597,-0.236073,-2.19382,-11.4115,3.08973,1.33702,-3.27145,0.727769,-0.100717,5.38921,8.19297,0.492232,-2.20151,5.25989,3.6589,4.08819,2.21554,-1.32513,3.54291,0.119275,3.23854,3.862,2.19948,5.28701,6.25834 10178.4,10137.4,9245.74,-5.53585,0.420645,5.85295,-4.47724,14.54,12.4497,8.36972,4.99424,2.57479,-4.3639,0.677018,-2.6813,6.67898,7.5884,-5.54187,-1.3688,4.05586,-6.15054,4.2909,-0.899213,-1.24567,1.90686,-0.469126,1.72139,5.00978,-1.65339,6.96518,3.71489 10184.8,10141.1,9247.89,-4.95644,-1.91401,3.7243,-7.95873,7.49028,6.40526,5.31843,3.53676,4.4376,-3.95261,0.746514,-2.92295,5.17495,5.09822,-5.56387,2.13589,1.74219,-7.51099,1.13636,-2.24892,-0.712168,1.40767,0.401594,-0.663717,6.22808,-1.51586,5.59537,1.86444 10195.1,10147.9,9253.27,-3.98,-3.06823,-2.05534,-6.10099,3.83685,4.55708,3.92119,0.928846,2.49159,0.0763172,1.14792,-2.88509,3.3624,3.14131,-4.76678,1.53759,-2.49281,-5.00974,0.3227,-1.57677,-2.36177,0.558465,1.76223,-0.153596,3.21585,-0.248642,3.44061,1.09292 10206.6,10155.3,9259.98,-4.64998,-1.64546,-4.6585,-6.92405,-1.23826,-1.4651,-7.80907,2.03872,0.322905,5.35637,2.9557,-1.90346,0.941137,2.90995,-2.25745,1.6362,-2.73525,-3.06893,0.361893,-0.410406,-1.95298,3.18373,4.96997,3.18307,2.09522,2.29277,1.29516,1.46329 10215.1,10159.8,9265.65,-5.64262,-2.22323,-2.32616,-8.62966,1.24852,3.53986,-7.11813,2.5704,-0.221435,0.41167,0.765415,-1.44792,2.10023,1.14341,-1.90736,0.761342,-0.0657556,-6.90094,4.60419,2.00852,-1.1143,4.44335,7.23913,4.6059,2.18355,1.92624,1.0442,1.06642 10218.9,10161,9269.98,-5.54728,-2.69742,0.623383,-4.54971,5.62832,12.115,1.60837,0.527375,0.225195,-4.35554,-1.09064,-1.69716,2.68584,-2.42078,-3.28377,-0.48855,1.46337,-7.59929,7.41232,3.78152,-1.52786,1.12019,5.14455,0.902689,0.791392,0.171231,1.01653,-2.1951 10225.1,10161.4,9274.87,-4.18459,-1.40959,4.0543,-3.78563,4.56469,13.1486,7.4468,1.32559,4.01602,-4.26528,2.47676,-0.706977,1.49841,-2.44619,-4.48237,0.314642,3.21848,-7.78537,6.45365,2.67192,-0.518631,-0.579868,3.1551,-3.30298,0.42352,0.385421,1.09082,-3.38628 10238.6,10163.7,9281.72,0.163978,0.29531,1.39945,-1.88245,0.770367,3.01996,6.47156,0.843119,3.05229,-2.89342,3.69162,1.01002,0.156961,-1.63668,-1.88068,0.459627,0.572044,-3.8789,6.07964,1.73877,1.04155,-0.952277,-0.352698,-3.89818,-1.13337,1.63306,0.655322,-3.05775 10252.3,10168.8,9289.58,1.69242,0.803041,0.969081,-1.57571,10.1963,10.1486,9.01137,-0.23779,2.45598,-11.8335,0.764195,0.347471,0.63322,0.818036,-2.67947,-0.48707,-0.0121974,-5.92175,4.75178,1.31186,-0.59319,-0.865273,-2.13114,-0.629395,-0.22624,0.187864,0.687159,-1.38416 10258.4,10175.1,9296.44,0.693656,-1.47018,1.57507,-4.07861,13.9151,7.913,3.87705,-2.41045,1.40643,-18.8401,-3.38044,-3.78137,0.444306,-0.142111,-3.19856,-0.633983,1.26609,-6.96487,4.03731,1.86282,-0.255938,0.885239,0.576534,4.16798,1.48633,-2.91027,0.44246,-1.26861 10259.2,10179.7,9301.13,-1.11281,-2.9356,3.48279,-4.07376,14.5961,4.75668,2.95063,-2.50321,1.99968,-15.2573,-3.94817,-6.19421,0.994523,-0.409685,-3.36826,-1.30752,2.89435,-7.11783,2.3961,1.75016,-0.287404,0.839505,2.32354,3.16514,0.431073,-4.23834,0.224613,-1.13459 10258.9,10180.8,9303.2,-3.70956,-2.93593,3.76222,-6.98265,14.1006,4.36509,3.13521,0.524873,3.4745,-8.19672,-0.812591,-7.54285,2.87285,0.165482,-4.34303,-3.00502,3.10194,-11.8146,3.48326,1.87454,-2.39007,-1.71717,-0.0308325,-3.00344,-3.10099,-5.07511,0.999296,-0.291248 10259.7,10178.9,9302.61,-2.50722,-0.863499,1.6361,-7.29671,5.65875,7.35687,6.74534,2.86707,2.5541,-4.10002,1.92641,-4.21325,3.79643,1.11564,-2.85299,-3.384,0.718232,-13.5344,2.15514,-0.378278,-3.09826,-4.48668,-4.09564,-6.07121,-4.62941,-4.63714,1.35609,1.33932 10264.3,10176.2,9300.58,-1.50986,-0.476834,0.153861,-9.03392,2.34462,9.76008,11.2624,0.958254,-0.70443,-6.3101,0.886002,-3.04957,4.20237,0.687347,-2.59931,-4.30057,-0.344332,-15.3463,3.30618,0.212706,-1.83037,-5.39362,-6.37009,-5.79293,-5.6463,-5.17005,1.45394,1.2199 10270.2,10175.5,9299.06,-1.8193,-1.62584,1.49621,-15.2891,-0.19176,0.694336,7.97111,-0.906134,-1.88497,-6.47048,-0.900237,-3.70282,1.23614,0.322582,-3.93212,-3.45866,1.71962,-16.8955,0.58688,-0.409914,-0.259588,-2.68512,-3.64588,-3.35838,-4.51583,-4.19392,0.240148,0.159851 10270.2,10179.6,9298.63,-1.90388,-3.42457,3.36972,-15.5947,6.83754,-2.72512,7.96959,-1.26132,-2.35887,-7.13988,-3.00989,-4.84946,-1.32472,-2.90407,-7.21556,-3.99747,1.63284,-18.121,1.49353,-0.486008,-0.289734,-2.44221,-2.61409,-4.74746,-6.81336,-4.22186,-0.397997,-3.01155 10263.1,10186.3,9296.94,0.1046,-2.95923,0.55802,-3.53552,11.956,6.06043,20.0157,-0.175478,-1.81809,-1.77528,-2.10279,-0.283075,-3.48288,-4.09089,-6.41457,-3.4926,-1.98205,-11.2644,1.51324,-2.56718,2.01317,-3.17178,-3.03644,-4.28621,-6.82533,-2.57386,-0.732198,-4.52782 10250.3,10186.7,9289.82,0.787893,-2.63004,-4.83671,4.59987,9.90165,5.11396,20.1712,-1.49013,-0.900383,3.2704,-1.38302,1.01612,-3.51797,-3.65748,-2.01906,-2.31487,-4.58178,-0.663723,4.99631,0.0846666,6.20019,-1.32911,-0.366123,-0.708005,-3.05462,-1.4169,-1.33549,-4.03837 10229.6,10174.2,9276.51,2.92922,1.43172,-8.45959,7.92191,9.82817,0.906035,15.1761,-5.66535,-4.80598,8.92318,-1.50732,0.863702,-4.19618,-1.72605,1.43049,-1.60336,-7.78679,7.9456,2.20311,0.976306,4.6808,-2.0774,-1.41618,1.52784,-1.00485,0.251303,-2.51818,-3.24837 10203.9,10154.8,9263.01,1.97737,4.88419,1.86761,-1.89071,16.8831,21.8027,18.6752,-2.85592,-0.407409,1.1857,1.57668,2.90834,1.42619,5.01683,-2.88862,1.13125,-1.02838,-3.77013,-1.83294,-0.874118,-1.82318,-1.06152,0.617181,1.34269,3.38069,1.15764,1.12216,1.38647 10184.5,10141.2,9256.68,5.24597,7.64832,2.18557,1.58328,4.92602,9.28816,-0.0172234,-2.70209,-2.36954,2.63625,2.45988,6.65341,1.30855,2.45772,0.884071,4.15289,-0.306199,0.501745,-3.91598,-0.843063,-3.78083,-0.751671,-0.908618,-0.353576,1.46737,4.59599,1.10914,-1.05414 10178.9,10140.4,9258.57,8.5511,8.38576,-0.704081,10.0442,3.87995,9.53107,4.06474,-2.33977,-3.33414,3.45052,0.769206,8.44243,0.151836,-0.110094,2.50423,3.89258,-1.86971,4.86933,-2.34618,0.208276,-3.54318,-0.382483,-0.444637,3.17545,1.86638,6.31308,-0.0788599,-2.11239 10182.7,10148,9263.52,7.664,6.75263,-0.540997,5.42972,-5.04193,-7.98425,-8.29464,-0.166299,-0.588527,3.31557,0.500806,4.72146,-2.51571,-1.43305,5.52369,5.671,1.03703,8.03067,0.0463032,4.16527,0.993743,2.27,2.01907,5.48701,6.28587,6.50446,-0.915646,-0.555951 10185.6,10156.6,9266.64,4.26252,2.60407,3.65205,1.35764,1.93964,-1.71464,3.62386,0.664968,2.07164,-1.84774,-1.41728,2.03742,-1.93901,-0.955849,2.55509,2.24827,3.4143,2.08534,1.52467,4.36357,2.40504,-0.149419,1.87333,2.56701,3.76988,3.58853,-0.290298,1.53656 10182.8,10164.1,9266.99,3.44774,1.00051,3.58435,5.06036,-3.20427,-1.32409,2.16178,-1.24869,0.986594,2.68824,-3.10496,3.75494,-3.03899,-1.36189,2.85639,-0.797041,2.25309,6.84226,-1.01807,1.45026,1.64915,-1.77668,1.47461,1.32051,0.0174875,3.15498,-1.91103,0.915561 10177.6,10169.5,9265.47,2.97062,0.742454,2.19308,3.39405,-10.2555,-6.11354,-8.35604,-2.29312,-0.492631,4.2024,-2.46282,2.85236,-2.05854,-1.07623,3.34902,-1.67951,1.43015,9.72371,1.0556,1.2093,0.0329592,0.933345,2.62882,4.14907,1.43657,2.25242,-2.21302,0.424466 10175.1,10171.1,9262.53,2.78573,0.66686,2.0545,2.76769,-2.38316,1.38611,1.33538,-1.98843,-1.22362,0.719734,-1.48276,0.571928,-0.303568,1.13172,0.533248,-2.57485,0.218063,4.75694,4.12677,1.25451,-2.29974,1.77459,2.18864,5.66448,2.31972,-0.197648,-0.423422,1.24127 10176.1,10170.7,9258.49,5.31438,0.737423,2.23937,7.15555,-6.03862,-6.93885,2.59027,-2.08985,-1.82474,1.76361,-1.51506,2.40133,-2.94977,1.13326,2.34185,-1.4691,-0.319475,6.55378,0.151184,-0.820336,-1.03183,0.737373,1.0173,1.60097,0.120988,0.706961,-1.06361,1.61191 10177.1,10171.1,9253.43,5.27989,0.124242,0.594136,6.40228,-14.4792,-17.9873,-7.83873,-2.70593,-2.84279,6.19952,-1.02819,4.22035,-3.89328,-0.655654,4.6427,-0.543649,-0.312946,7.67303,-3.34568,-2.99026,0.892734,0.193866,0.437901,-1.37172,-2.06494,3.10779,-2.09072,0.969194 10175,10171.9,9247.28,2.27598,-1.11333,-0.371999,2.70022,-5.44405,-1.24932,2.95574,-2.54561,-3.07604,2.81372,-0.48024,4.11824,2.04907,-0.370621,1.24343,-2.71039,-1.27809,-0.906837,-1.29061,-4.80376,-0.177684,-0.68347,-0.0356975,0.976652,-2.58184,2.60538,-0.53245,1.0079 10170.6,10171.1,9240.98,0.484599,0.0646839,-1.51326,2.89899,-3.4319,-0.213982,2.47953,-0.834731,-2.00581,5.72898,0.227883,2.67222,2.27602,0.0505934,1.31844,-2.26552,-2.6972,-0.975391,-0.869576,-3.70984,-1.26158,-0.292123,-0.590846,2.58737,-1.84822,1.62378,-0.526111,-0.491878 10166.9,10167.6,9236.09,0.964725,-0.0392702,-0.079079,4.19696,-8.77705,-7.3393,-5.33084,1.7816,1.00552,6.00308,-0.645333,1.80016,-0.345783,0.537513,3.29513,-0.258503,-1.94323,3.02276,-2.07851,-0.708951,-0.985472,0.42465,-0.0047685,-0.0149723,-1.37113,0.550535,-0.779034,-0.484969 10166.1,10161.5,9233.6,-0.598547,-1.76595,-1.06041,-0.952044,-3.22733,-6.25839,-1.71002,3.5389,3.14678,2.52469,-0.94774,-0.697306,-1.82073,1.8162,-0.398189,-0.0962201,-1.17773,-3.11075,-1.86249,-0.148137,-0.912351,0.0729367,0.372787,-1.52491,-1.99794,-1.67208,0.753712,1.02245 10167.9,10154.5,9233.85,1.32924,-0.579085,-4.09528,3.27081,-6.78357,-9.38603,-3.06915,1.95927,0.70163,2.46784,-0.635142,0.854662,-1.03664,2.44479,0.381434,0.976493,-2.1874,1.35415,-3.25712,-1.85514,0.202589,0.286026,0.720155,0.627719,-0.687001,-0.872865,1.21871,2.25385 10170.4,10147.3,9236.23,1.55419,0.655793,-3.90119,3.65032,-6.92144,-3.81534,-0.829364,1.59907,-0.150104,0.588015,0.212751,1.04803,3.09472,3.79829,-0.218751,1.11779,-1.55055,0.933332,-1.25266,-2.59487,0.647035,1.39731,2.58953,2.8589,1.80309,-1.43261,2.52993,2.79953 10171.9,10139.7,9239.22,2.16966,0.513128,-2.93705,2.73804,-10.8601,-4.50483,3.76187,1.03924,-0.676839,-1.4866,-1.19577,1.6866,5.98311,3.12642,0.0885709,0.9896,-0.594518,0.533618,0.379411,-3.82145,2.32664,2.22298,3.60721,3.05218,2.2889,-1.98702,2.79897,1.35025 10172.4,10133.5,9242.05,0.627291,0.905709,1.39363,2.99372,-15.425,-9.09382,2.11414,1.04226,2.10526,-4.39506,-2.77953,2.15891,6.66724,1.70369,-0.372333,1.40462,2.59187,2.26874,-0.378224,-3.69675,3.0335,2.25396,3.10192,0.0429504,0.10951,-0.799702,2.66794,-0.282681 10173.8,10130.2,9245.36,-1.33644,1.42161,3.11004,3.93858,-17.0646,-12.116,1.67239,1.94826,5.54306,-3.85205,-1.5475,2.52019,4.33814,1.15019,-0.541069,1.99129,3.05378,4.25369,-2.76731,-2.80645,1.85733,0.988299,2.88783,-1.97077,-2.83768,1.85125,2.84766,0.389147 10176.4,10130.9,9250,-3.53503,0.391503,-0.270572,1.95882,-15.1875,-18.5758,-1.42497,2.28845,5.40786,-2.12974,1.20821,0.911564,0.2788,0.0689856,-0.00271805,2.01928,-0.20812,3.23848,-1.98612,0.0245125,0.488358,-1.18054,1.47019,-3.47437,-4.6287,2.11498,2.20934,0.993318 10178.8,10135.9,9255.56,-3.20255,-0.268054,-3.48033,2.47099,-11.3536,-16.9308,2.01776,1.40976,1.56328,0.853625,1.89586,1.47109,-1.50849,0.167668,0.627511,1.41809,-4.21425,2.05546,-2.39209,-0.416193,0.276633,-1.50971,-0.820011,-1.25927,-1.76,0.153711,0.431209,1.48315 10181.2,10144.1,9260.31,-2.49125,-0.613263,-3.86482,0.287362,-9.17309,-14.1157,3.48478,0.196793,-1.25386,2.83848,0.198147,-0.0165582,0.471677,-0.139327,-0.216901,-0.966032,-5.2193,-1.40546,-0.977273,-1.2574,1.78779,0.134179,-1.72164,0.653388,0.313432,-3.37716,-0.587605,0.861387 10186.6,10151.1,9263.12,-0.0358474,0.714951,-5.47328,-0.875177,-17.5089,-13.8361,0.471247,0.643912,-2.41975,9.9458,0.993041,0.803296,-0.226386,0.0668295,2.19176,-1.16819,-4.40868,0.69383,-3.38706,-3.58218,3.07732,2.10253,1.79789,2.06744,1.83904,-2.15516,-1.67344,0.661882 10193.4,10152.2,9264.85,-2.78688,1.85556,-1.96216,-7.27433,-5.61022,0.625161,3.91544,2.78407,0.13042,8.01854,3.573,-2.43853,-1.07905,0.148792,-1.48277,-2.3792,0.378784,-7.05144,-1.06108,-1.76148,0.135824,1.71393,3.80312,-1.43656,0.702495,-1.95731,-0.703674,-0.33177 10196.9,10148.7,9267.46,1.41437,4.41491,0.0330121,-0.96198,-19.7539,-11.561,-5.49424,1.03618,-0.588315,13.1158,4.11913,1.82776,-4.02743,-1.24038,4.49417,2.16391,1.61464,5.33203,-6.2827,-3.22771,2.42673,4.53812,5.27571,1.95384,4.83592,2.15944,-2.23414,-0.0179182 10195.1,10146.6,9271.67,-0.599083,4.08109,5.56207,-0.651956,-1.899,4.41751,8.64946,-0.00765143,1.65381,7.40697,3.13743,0.528221,-1.17274,-0.333192,-1.34405,0.810869,3.04978,-1.96585,-3.00608,-1.02587,-0.427114,2.63482,2.33223,1.44749,2.70602,-0.508442,-0.782524,0.838544 10190.6,10149.1,9275.95,0.560997,3.32623,0.00253245,1.6273,-9.62681,-9.32197,-7.13248,-1.74244,-2.26773,10.279,2.01853,1.79006,-2.32577,-1.861,2.70102,2.63733,-0.668516,4.89049,-2.56801,1.67809,-0.682542,1.07859,-0.730879,1.04436,0.219305,1.04839,-1.30085,-0.204558 10188,10153.1,9277.72,-1.05102,1.4439,-1.2902,0.37219,3.61058,7.8905,-0.13638,-0.797121,-3.203,3.7144,-0.467361,1.43319,1.01941,-0.964803,1.27849,1.32106,-0.71757,-0.281666,1.82319,4.43107,-2.93419,-0.102775,-2.79816,1.60946,-0.350934,0.837113,0.975085,-0.206216 10189.3,10155.8,9275.17,1.71247,1.79065,-0.806826,4.2591,-1.07113,5.08033,-3.80833,-1.05846,-3.93516,4.86697,-2.48519,4.41458,1.0147,-2.04319,5.76698,3.04901,0.621182,6.18537,-0.471514,3.74338,0.0954557,1.78055,-2.23478,4.29533,3.28968,4.08665,-0.45381,-1.12752 10190.8,10155.9,9267.91,0.0885688,1.62773,3.97676,0.475719,6.50171,12.0036,4.17355,0.0800788,0.877184,4.13283,-1.66529,2.3731,1.22312,-1.52431,1.32333,1.30085,4.02821,0.00402446,-0.278254,3.83144,-0.00616006,1.70507,0.14686,2.05675,3.75234,3.42709,-1.13997,-2.28219 10186.5,10152.6,9257.34,-0.152071,1.1051,2.98089,-3.26014,-3.23874,0.545145,-3.74253,0.650653,4.32612,4.55661,-0.349067,0.443991,-1.54712,-2.37082,1.08068,1.11666,3.19332,0.114235,-4.77887,1.03262,0.526047,1.57427,1.96416,-1.21359,2.2522,2.81775,-2.19914,-3.20958 10175.9,10146,9246.33,-2.37365,-0.801223,1.8448,-4.49245,2.73452,3.45587,0.665856,0.804743,7.15539,-1.25789,-1.25952,-2.70716,-1.07845,-2.04441,-1.93328,-1.35806,1.5978,-5.1161,-5.79834,-0.925826,-2.80177,-1.15512,-1.39234,-4.88988,-2.71874,-0.727928,-1.17586,-2.55528 10163.6,10137.3,9237.87,-0.803469,-2.78044,-0.895544,-1.96323,-0.541223,-3.95959,-1.23923,0.0489646,5.82687,-0.842944,-2.20839,-1.37161,-0.868195,-0.366623,-0.326653,-0.542204,-0.442138,-3.06811,-5.05951,-1.77693,-2.56412,-2.0747,-5.18551,-5.90628,-3.59607,-1.51359,-1.0358,-0.0442413 10154.4,10129.1,9233.99,1.23915,-3.76005,-2.64612,0.723829,-3.148,-4.96491,0.57486,-0.202117,2.21428,-0.386009,-2.61213,0.591537,-0.420445,2.51457,0.848114,0.0155665,-2.8099,-0.688955,-1.65728,-1.68576,-0.314736,-2.37588,-7.30164,-5.93878,-1.09582,-1.08092,-1.23666,3.04974 10147.7,10124.3,9234.84,0.130569,-3.33534,-5.30783,0.228073,-1.79103,-2.90284,1.72325,0.336059,-1.67646,0.805152,-2.51359,-1.68843,-1.08056,2.79024,0.667811,-0.918425,-5.25023,-0.613583,-1.21144,-3.86108,1.12026,-2.87087,-6.96217,-3.74878,-0.871173,-1.99148,-1.4983,3.13726 10141.9,10125,9238.34,-2.3342,-3.74514,-6.28736,0.247636,2.71253,3.12847,7.57994,-0.0401623,-2.07147,0.481455,-3.97685,-4.46362,-0.415913,1.42821,-0.575486,-2.68041,-4.57327,-2.24353,-2.60028,-5.84863,0.625916,-3.42977,-3.6369,-0.844099,-3.5874,-4.64335,-0.985747,1.2717 10139.9,10130.2,9242.19,-1.31024,-4.72475,-7.14762,0.73153,1.45053,-5.53508,5.90136,-2.31863,0.194991,0.488804,-6.97821,-4.41928,-2.29074,-1.35009,0.919216,-2.89533,-3.25509,-0.799203,-1.99553,-4.14064,2.04707,-1.98553,-0.137078,-0.0166083,-4.9352,-5.40326,-1.67739,-1.42035 10146.2,10135.6,9246.04,1.48702,-3.36982,-6.22071,1.74719,2.56435,-13.0074,1.99705,-3.21561,2.91416,0.844878,-6.7988,-2.16439,-5.4962,-1.85975,2.13575,-1.59383,-2.91884,1.52462,-1.3314,-1.85117,3.6544,-0.430522,0.692754,-0.840642,-3.31251,-2.33908,-3.05762,-2.1983 10158.1,10136.1,9250.8,0.841737,-2.49661,-1.39476,-1.47649,15.6927,0.965199,10.869,-0.546861,4.02682,-3.15137,-2.65822,-1.05518,-4.77058,0.229656,-2.58261,-1.60934,-0.689737,-5.44364,-0.234473,-1.95479,2.60062,-0.769404,0.484685,-2.21476,-2.21659,-0.527818,-2.3356,-0.631119 10167.2,10131.4,9256.17,1.43756,-1.64599,0.0828565,1.10643,1.09851,-8.71597,-1.14743,1.16785,1.24835,1.69522,0.678389,1.91657,-5.73395,-1.26925,0.618759,0.671225,0.99422,2.5392,-3.14056,-3.00047,3.39733,-0.267724,0.865602,-1.72338,-1.28093,1.59131,-3.58079,-1.60917 10168.5,10125.9,9259.95,0.111755,-1.49369,1.18289,-0.284048,-1.52165,-7.82514,1.91577,2.83987,1.30957,4.34859,2.31828,0.547347,-5.35341,-2.95714,0.120479,-0.07344,1.25038,0.863374,-1.97606,-2.63292,2.99367,-1.51317,-0.192761,-1.94301,-2.34527,-0.816782,-4.15688,-3.69083 10164.7,10123.5,9260.03,2.54631,0.123647,1.85441,0.291179,-2.26534,-5.622,0.403256,2.75151,1.92159,5.45502,4.02912,0.277333,-3.49437,-2.59529,1.68451,1.03176,0.611114,1.05444,-1.37086,-0.762577,2.09659,-3.15435,-1.66892,-4.18628,-2.03484,-0.59484,-4.5361,-4.06338 10160.7,10123.9,9256.02,4.16394,1.15842,1.00215,-1.41089,3.00077,3.69915,2.12147,1.50602,1.11373,3.7783,5.12886,1.27055,-1.0735,0.163066,0.715848,1.75274,0.248762,-1.87449,-2.70607,-0.0821427,-0.982237,-3.91753,-0.603176,-5.15131,-1.55797,1.9122,-2.63806,-2.45448 10157.6,10124.8,9249.1,1.13904,0.752742,1.28292,-3.44794,5.87463,13.5955,-3.90547,0.053564,0.392376,-2.17549,4.02652,0.800942,2.14933,0.991305,-1.00534,1.93346,1.74799,-4.3887,-2.62983,2.12002,-3.97726,-2.37985,1.92724,-3.91126,-1.80145,3.29901,0.515867,-2.07875 10155.9,10125.9,9241.01,-1.21278,1.24353,0.0902419,-1.38693,3.90257,17.0687,-1.7671,-0.621263,-0.743581,-3.56603,3.19768,0.515647,2.83626,-0.394058,-0.965446,2.53295,1.02968,-3.73706,-0.646373,4.19926,-3.90665,0.100245,2.07717,0.65145,-0.4389,3.45695,1.30478,-2.26372 10156.9,10129,9233.19,-0.519545,3.45514,-0.128203,0.470911,-4.34917,11.6069,-5.37302,-0.249794,0.0908138,-1.64961,3.7305,0.887725,1.28233,-0.50548,0.651175,4.68216,0.481759,0.131141,2.83721,7.4517,-1.51906,2.02591,0.478488,2.8447,3.96564,4.21205,0.0189546,-1.26083 10160.2,10134.9,9226.61,0.334619,3.63902,-1.33005,0.500933,-0.0390483,15.3466,3.49804,-1.22599,-0.443012,-1.29729,1.85728,0.83413,0.663791,1.08815,-1.61332,2.35978,-1.91003,-1.54128,7.06018,8.52392,-0.0931056,-0.631766,-1.8937,1.21041,3.92464,3.0125,0.582016,-0.0552563 10165.1,10142,9222.12,-0.0501124,2.72845,-2.35233,0.461804,-3.24106,3.89637,-4.4752,-1.7395,-0.658087,1.46568,0.74815,1.9358,-1.37579,1.26993,0.248403,2.1501,-1.97865,2.84403,4.93078,6.34449,2.55208,-1.66616,-1.28941,-0.85475,2.44335,3.28626,0.575625,0.0867697 10169,10147.2,9219.92,-2.57524,1.55278,1.64717,-0.408592,2.78686,3.93608,-3.35557,-1.05071,0.358949,-1.71793,1.23509,0.730307,-0.807758,0.469476,-0.799756,2.26666,1.42763,2.57756,3.31921,4.24278,2.32673,-1.92157,-0.625841,-1.7385,0.55312,2.469,0.416022,0.102824 10167.7,10149.8,9219.39,-2.61236,0.265041,4.14099,-1.10443,5.68968,5.75872,0.437178,-1.27371,-1.44794,-5.50529,0.962099,-1.7594,-0.014506,-1.47838,-2.10998,2.88166,2.32266,2.31558,3.04189,2.76494,1.13588,-2.76241,-2.5749,-1.37983,-0.132212,1.62609,0.00182996,-0.567092 10161.2,10151.5,9219.88,-1.00231,0.225002,2.94421,2.03312,-0.355979,4.16591,-0.636307,-0.980578,-3.17075,-4.4683,-0.0413473,-0.96548,-0.194949,-0.798368,-1.08568,3.94015,1.20872,6.21739,0.493017,0.663456,-1.20346,-2.76074,-4.99576,-0.484664,1.27829,1.87168,-0.0347963,-0.649195 10155.5,10153.9,9220.83,-0.939771,0.647249,0.0634509,3.2582,-1.62031,4.0693,-0.997477,-0.169163,-4.01209,-4.20755,-1.14083,-0.040949,0.676499,1.0769,-0.637069,2.85891,0.53402,4.18699,0.666861,0.369829,-2.63692,-0.336214,-3.73798,1.47577,2.81105,-0.292838,0.0270106,-0.151526 10154.1,10157.5,9221.67,-1.65802,1.59847,-3.57612,1.52401,6.37221,4.48866,-1.46299,-0.915699,-6.98915,-0.340048,-0.952717,-2.18866,-0.811792,-0.642645,-0.622625,-0.300884,-1.00057,-1.15759,2.44751,2.6773,-1.823,1.29837,-1.91591,2.49204,1.93197,-3.59974,-1.91245,-2.4109 10154.4,10160.7,9221.98,-0.583463,-0.108757,-4.6507,-0.0693877,5.35637,4.425,-6.56889,-1.82597,-8.57191,2.85503,-1.05825,-2.33955,-3.22781,-4.76081,2.05753,-0.861931,-1.83229,-0.124382,0.503483,2.18131,1.30665,2.42826,0.824233,3.84653,2.09007,-3.3925,-4.31649,-3.96112 10153.4,10159.2,9221.68,-2.76485,-4.09131,-2.87698,-1.10712,12.5336,12.9839,-4.34652,-1.87041,-6.50663,-1.43881,-2.78497,-4.09349,-3.27711,-7.58611,-0.918956,-2.43732,-1.68029,-2.93885,1.37614,1.00354,-0.202025,0.252735,-1.35224,2.14941,-1.22668,-3.85694,-3.91196,-5.39514 10153.1,10150.6,9221.82,-3.95579,-6.11602,-1.95691,-0.571033,7.36799,2.23424,-8.23593,-1.15065,-2.89936,-3.34966,-3.42278,-4.92737,-4.22729,-7.57776,-1.53936,-2.4826,-0.485854,-2.05301,1.35048,0.235875,-0.851581,0.299046,-3.65228,0.452501,-2.53126,-4.14097,-3.0318,-6.032 10156.5,10138.1,9224.22,-1.72219,-4.81284,-2.04034,3.64429,-3.40667,-8.21149,-2.06758,-0.247629,0.240041,0.844032,-2.55693,-2.29071,-5.62686,-4.10255,0.955484,-2.58578,-0.573095,1.96046,-2.89531,-2.47853,1.00662,1.59082,-2.31097,1.60096,-0.355857,-3.59741,-2.54995,-3.16362 10162.5,10126.5,9229.66,-1.48624,-2.31864,-1.19917,5.07688,-2.15075,-4.48733,6.81643,1.19375,3.4529,3.66948,-1.49639,-1.71619,-5.51437,-1.29231,-0.407537,-4.604,-2.54282,0.0824236,-5.27449,-4.81883,0.767691,-1.39492,-2.55861,-0.325428,-1.75464,-3.59903,-1.89829,-0.732932 10167.7,10118.7,9237.56,-1.06333,-0.880843,-0.709075,2.8371,-10.0447,-10.4348,-2.5904,3.18465,5.97115,6.33779,-0.55058,-1.01646,-4.14332,-1.6247,-0.0193591,-4.01402,-3.73144,0.38443,-5.50468,-6.41294,-0.295721,-3.62009,-2.70822,-3.1355,-4.45086,-2.10376,-1.79258,-1.22716 10172.5,10116.9,9247.18,1.551,0.130326,-0.490568,5.87654,-14.5436,-8.35183,-0.790109,3.39107,4.7174,8.28156,-0.0057788,2.6686,-1.84943,-1.48071,1.03911,-4.0934,-3.48936,2.7605,-6.22541,-8.72046,-2.487,-3.9855,-3.15508,-4.85806,-6.30628,-0.1826,-2.22861,-1.91313 10179.7,10122.6,9257.78,1.5355,1.00586,-2.46594,5.55739,-10.6179,-9.89219,1.01847,2.02002,1.55047,10.3651,1.59035,2.3257,-3.02423,-0.681756,0.379055,-4.13859,-2.86252,2.65539,-7.09955,-8.4785,-1.80811,-2.44766,-3.84586,-6.08215,-4.18234,0.309597,-3.66089,-1.78168 10188.9,10134.4,9267.84,0.423127,-1.44673,-6.16369,2.54558,-3.2605,-10.2788,1.93481,-0.460125,-1.55478,7.53447,1.04311,-2.037,-5.33297,-0.715827,-0.912315,-4.00679,-5.27357,1.32517,-7.02947,-5.6844,2.49,-1.1701,-4.14164,-4.46692,0.160721,-1.23591,-5.46575,-0.678645 10196.3,10145.5,9275.21,0.204833,-4.851,-9.24744,3.38063,-3.90706,-1.89916,-0.318999,-3.05687,-4.83175,3.88926,-1.68472,-4.52857,-6.76493,0.053409,0.356074,-2.44354,-9.25902,3.95243,-8.99635,-3.68403,4.07743,-1.41439,-4.06526,0.784286,2.50666,-1.59161,-6.31937,0.0761621 10200.4,10148.5,9278.92,-3.06966,-5.752,-6.27773,-0.452092,4.18213,13.2473,-12.0757,-4.47092,-6.49884,-5.96616,-4.08975,-9.08064,-3.65565,-1.03612,-1.9757,-2.79369,-8.22081,-3.13926,-2.68074,1.98539,-1.47914,-4.27865,-6.82097,-0.0420558,-2.72616,-3.80964,-3.69263,-2.81706 10202.3,10144.3,9279.66,1.7621,-1.2767,-1.87182,1.61337,-6.80859,14.4514,-16.815,-2.07514,-4.63562,0.0307544,-1.49074,-2.29138,-1.18636,-1.08621,1.86862,0.689509,-4.2555,-0.913166,-4.04706,-1.13903,-2.95495,-1.4359,-3.45987,4.36607,0.619825,-1.53464,-2.06409,-2.58631 10201.6,10141.5,9277.89,2.73427,2.11183,3.79277,1.71546,-5.8859,13.3557,-11.3022,2.79327,2.37116,13.2011,3.98285,0.966107,0.039656,-0.715821,2.85166,2.34242,2.77476,-0.0888099,-4.98538,-3.4432,-1.83877,3.57211,2.68075,7.05565,6.45616,-1.54302,-1.24469,-1.49869 10196,10143.8,9273.55,-2.52737,0.202188,7.08167,-4.89952,6.71679,10.6699,0.756855,5.54471,7.25909,13.9583,6.39787,-2.37566,0.745793,-1.45474,-1.09404,0.910205,7.21143,-6.92492,-3.24203,-2.89701,-0.543452,6.07649,7.33376,6.57894,6.15484,-4.40884,0.0587056,-1.11052 10186.2,10147.8,9267.63,-4.31786,0.145523,8.74123,-1.12372,3.61382,5.90919,-2.20636,4.87121,7.93339,10.8223,5.77747,-1.02016,1.70524,-1.23974,-1.99873,1.22043,7.18349,-2.02393,-4.52471,-1.19367,-1.87015,5.60664,6.92162,5.30532,3.03549,-3.16865,1.33872,-1.3693 10178.3,10151.3,9262.07,-1.01371,-0.36759,7.07326,3.03463,-3.67644,6.41668,1.01659,3.32806,5.69645,6.11989,4.17302,3.13986,4.40199,0.31144,-2.58094,-0.0539033,4.16067,1.49299,-3.2753,-1.39228,-2.172,3.33149,4.19598,3.46064,0.616277,-0.818505,3.98959,0.698301 10177.2,10154.3,9257.94,2.09186,0.0766925,2.17884,5.08344,-13.9717,-0.882929,-3.84368,2.86526,4.57806,7.77504,4.75117,6.29349,4.58116,4.04706,1.06485,0.914494,1.84175,7.12093,-3.92066,-3.04038,-1.76589,1.29071,2.74094,1.46176,1.98937,3.12251,5.09485,3.84087 10179.4,10155.4,9254.74,0.187596,-0.882072,-0.665652,4.15319,-3.56212,6.25634,3.46947,2.99756,3.30879,0.859046,5.1349,3.91232,5.90056,6.60019,0.839946,-0.162343,-0.484405,2.65509,-1.8674,-3.50916,-5.10299,-1.60522,1.28388,-0.0295086,1.05,2.81748,5.21994,5.53563 10178.8,10153.1,9251.26,-1.91139,-0.154839,-0.832651,7.32065,-8.14661,3.20829,-4.61065,3.9011,1.20806,1.29028,6.11631,4.24084,4.66918,7.38927,3.1094,1.72009,-0.436683,6.06925,-3.83738,-3.64103,-8.35166,-0.222316,1.74303,3.43329,2.82215,3.91599,3.2218,6.05878 10175,10149.2,9246.46,-3.00223,-0.829219,2.18951,8.12634,-8.29635,3.98254,-2.55022,3.58933,0.0476173,2.00734,2.85452,5.13863,4.39434,5.86178,1.57419,0.321093,2.11151,4.62819,-0.677836,-1.98205,-7.44972,1.36379,2.52895,5.12261,2.10196,3.15929,2.77152,6.16477 10170.8,10147.7,9240.32,-2.09934,-1.33891,3.77143,6.49402,-6.43302,-0.0826344,0.87837,1.12061,0.421557,1.06025,-1.52903,5.64507,3.68263,3.49536,1.25096,-1.4957,2.92854,4.60413,2.40658,-0.645265,-3.32217,0.987715,2.60908,1.94117,-0.424246,2.85508,2.71473,4.88469 10167.3,10148.7,9234.04,-1.71112,-2.89318,3.67043,1.66277,3.35424,4.57631,10.1924,-0.35173,1.35064,-5.80931,-1.82085,3.64176,4.57117,2.2882,0.924739,-2.41648,2.22467,2.19365,5.80375,-0.426137,-2.32705,-0.919332,2.09081,-2.34116,-2.25007,1.71251,3.40172,3.5108 10165.7,10149.1,9229.23,-1.45001,-3.05548,2.45599,-0.349391,3.71978,4.53119,5.144,-0.0754888,2.20722,-6.90377,0.948441,2.13514,3.08117,1.83942,2.86791,-0.010419,2.66035,5.23219,5.6626,-0.804354,-2.37724,-1.67323,0.673861,-3.53649,-1.59081,1.76997,2.75549,2.29186 10167.4,10147.1,9226.8,-1.49928,-2.70714,1.88393,-0.842721,-0.225431,3.25531,1.41947,0.140255,3.21042,-3.88608,1.41104,1.86088,-0.091131,0.642157,1.94581,0.307133,3.18746,6.22574,4.30938,-1.01513,-1.1936,-1.8575,-0.588364,-1.42784,-2.08205,1.85519,1.46316,1.06047 10171.1,10143.9,9226.48,-2.01672,-2.40053,3.06391,-0.0599903,-8.34303,2.94718,-5.04409,-0.199276,4.0892,-3.68083,-0.226057,2.75547,-0.686676,-0.843757,0.670264,-0.458086,3.08212,7.11729,2.84836,0.933537,-1.50789,-1.59001,0.179663,0.0589795,-2.55704,3.42709,0.775783,0.360096 10175,10140.6,9227.89,-1.34782,-2.60865,2.14445,1.39294,-10.3608,4.5868,-8.2559,-1.78039,0.356678,-10.0047,-3.28868,2.87133,1.85333,-3.67234,1.53223,-1.27653,0.113475,6.97877,4.49731,3.38158,-3.24882,-2.09817,-0.213742,-0.816136,-3.92766,4.36792,1.46638,-0.25462 10179,10139.5,9231.01,-0.683001,-1.14693,0.835389,1.45465,-4.93888,6.92044,-3.2459,-1.76518,-2.11784,-11.5638,-3.99539,3.25477,2.97649,-3.54233,2.62301,-0.286071,-1.99677,5.44349,5.35012,2.55683,-3.04093,-1.82791,-1.42661,0.583625,-2.6178,3.43693,2.29735,-0.308687 10185.5,10142.2,9235.77,-0.0852919,0.0218383,0.522022,1.091,-4.00515,-0.71681,-2.72016,-1.24891,-1.4593,-5.53454,-2.81228,2.98724,1.40275,-1.35994,4.37674,1.00841,-2.02092,6.34309,4.01241,0.223476,0.719167,-0.617158,-1.79277,2.19906,-0.00915837,1.60933,1.1106,-0.276707 10194.7,10147.7,9242.28,-0.507821,-1.45713,1.82236,1.06383,0.990703,1.16431,3.40878,-1.35424,0.436421,-3.7364,-2.82733,0.844561,2.18188,1.42103,2.14788,-1.48658,-0.956157,3.31294,2.03859,-1.09837,2.11718,-0.147919,0.113767,0.665977,1.0134,-0.758268,0.662046,1.48327 10202.3,10153,9250.68,-0.953894,-1.28733,1.09826,0.183582,-2.63676,-4.1377,-2.89907,-0.851983,3.07691,-0.452803,-2.18838,0.00930997,2.87142,4.0314,0.911046,-1.55443,1.18147,4.24956,-2.48362,-1.23019,1.72571,2.11001,5.29268,-0.281886,3.31927,-0.100871,1.85826,4.09941 10205.4,10156.4,9259.89,-1.27754,0.134823,0.181405,0.430733,3.94306,1.54036,2.99815,-1.16285,4.70226,-4.24342,-1.81256,1.00154,4.93307,6.24027,-1.59843,-1.48742,2.34844,2.10305,-2.00905,-0.662325,0.626241,1.17997,6.74123,-1.67701,1.35772,0.491316,4.32271,6.53414 10204.9,10157.9,9267.94,0.0906612,2.16352,-0.379486,5.42194,2.73054,2.84047,-1.4914,-1.83181,4.02307,-5.15449,-0.262248,3.79351,5.21678,7.80905,0.384689,1.27337,2.9796,6.90988,1.28339,2.20996,-0.91791,-0.163496,3.78903,-1.75168,-0.655347,2.9127,4.88667,7.66747 10203.5,10159,9273.39,2.81598,1.22437,-0.368556,7.79675,3.42922,7.94279,4.57077,-0.708312,0.0968463,-6.10539,0.906129,5.55489,5.11842,8.21484,-0.0671665,1.22889,2.37144,6.24544,4.97372,3.9233,-2.49967,0.267274,-0.310124,1.09266,-0.410233,4.04567,4.74621,8.0612 10203.2,10162.2,9275.77,5.91857,0.355765,0.897437,11.4606,-3.5509,6.21936,2.57301,-0.0103725,-3.12789,-4.93913,0.601331,6.94209,5.77388,6.93334,1.15761,0.716978,2.28439,10.4648,4.58557,4.39511,-2.76356,2.73426,-1.51427,4.03252,2.99548,5.47757,3.66414,6.66569 10203.5,10167.2,9275.21,3.60261,-0.370029,0.212296,6.53742,-1.17501,1.39057,4.60494,-1.59955,-3.36286,-6.83681,-0.619753,2.05525,7.21718,4.0699,-0.311278,-1.80144,1.07578,6.02142,4.81799,3.05296,-1.94492,1.84126,-1.66326,1.40391,1.77364,2.95825,3.1993,3.61198 10203.2,10169.7,9272.52,1.94895,1.27875,-0.411546,7.45768,-3.75161,0.551798,7.13428,-3.82068,-2.61405,-4.51085,-0.839975,-0.654388,7.59238,3.63367,1.11679,-0.895324,0.0589114,6.72608,0.605615,-0.28023,-1.84675,-0.134175,-0.468956,-1.06577,2.10307,1.19208,2.14254,2.35948 10201,10166,9269.14,-0.454618,0.774031,2.06017,2.8462,-0.622985,0.18548,5.53147,-2.50822,-2.46147,-4.96779,0.0109421,-5.95039,4.88549,1.45711,-1.36876,0.21175,1.58667,0.959389,-1.72767,-0.999701,-1.91612,-0.271218,-0.271307,-3.60937,2.2528,-2.81471,1.29832,0.342989 10196.9,10158.5,9266.51,1.16537,-1.9421,4.60098,6.66208,-8.91079,-4.05041,0.977918,-0.375912,-2.52562,-2.44083,-1.83608,-5.04574,0.870179,-2.88837,0.903319,2.45464,2.77487,7.13809,-7.32993,-2.29902,0.410437,1.61472,1.76486,-2.68616,2.88565,-3.79142,-0.830458,-1.20118 10194.1,10152.5,9265.18,-4.11534,-5.864,4.81522,5.05616,0.145339,-4.93641,2.59855,0.656712,1.10696,-4.83177,-6.68192,-7.2593,-1.01756,-6.50992,-0.623669,0.165413,3.83811,5.84041,-5.84841,-0.103661,1.98729,0.416145,1.34348,-6.16515,-2.67871,-5.57128,-1.65554,-3.26762 10194.1,10148.4,9264.07,-6.59722,-4.92656,-2.01588,3.7417,0.726794,-18.2936,5.15057,-0.276157,1.50739,-0.538248,-8.52874,-4.00362,-4.55022,-5.27015,0.604573,-0.930054,-0.109161,8.19838,-8.17669,-2.1092,4.17484,-1.56197,-1.02102,-5.8341,-5.50376,-1.7134,-2.50895,-3.06608 10193.9,10142,9261.25,-7.62788,-2.98611,1.9356,-1.40885,17.3716,4.06957,22.1809,1.39972,5.64224,-7.94302,-5.59134,-1.45901,0.439725,1.11211,-6.73411,-3.11746,1.4598,-4.78344,-2.09513,-0.404037,0.473396,-4.22587,-2.43839,-5.70551,-5.26427,-0.515338,1.20082,0.113119 10190.4,10132.9,9256.55,-0.061965,0.47587,-3.01478,1.28661,-2.15014,-14.2047,7.89898,0.463674,0.911903,2.0883,-1.64338,3.11185,-2.21723,0.781415,-1.37312,0.396228,-1.38267,3.09944,-1.8496,-1.29836,2.6087,-3.15966,-2.03297,-3.33185,-3.23065,2.92606,0.328003,-0.0324179 10185,10126,9252.36,-0.460313,1.71643,-3.7396,-2.47922,-1.49725,-15.3645,-1.80975,0.715758,-0.981069,-0.691494,-0.794101,-0.106849,-2.08179,-0.30971,-1.53311,0.428815,-0.320026,-0.221114,2.28648,0.175576,3.04606,-1.33911,-0.290353,-5.37868,-3.63253,0.919151,0.306196,-0.421839 10178.6,10124.8,9251.04,-1.00256,1.33259,-4.2472,-1.03971,2.95821,-4.55752,1.84476,0.117356,-4.36831,-4.27268,-1.02576,-0.886254,0.661063,-0.0446314,-0.718596,-0.508343,-2.00182,-0.337999,2.57329,-0.613947,2.18595,0.685998,2.2221,-1.4549,-2.89677,-0.0111036,1.2411,0.83044 10170.8,10127.6,9252.97,-1.71108,0.0714348,-2.91875,-0.0818013,10.0027,5.28964,4.84662,0.115636,-5.97389,-2.97492,0.466922,-1.16018,3.14319,-0.484977,-0.73996,-1.40938,-2.86898,-1.18229,2.85098,1.59393,-0.709864,0.769892,0.0526875,0.667581,-4.09633,-0.130706,2.87503,0.28772 10163.4,10130.8,9256.69,-0.0482655,-0.561906,-4.41924,-1.93638,1.00001,-3.80859,-6.74655,-0.693966,-6.90741,3.83606,-0.443929,0.133173,1.32042,-4.12952,2.21239,-0.401666,-2.83084,1.48444,3.60821,4.7162,0.0479322,1.57325,-2.9423,0.781086,-3.57562,1.01359,1.5974,-1.03302 10159.1,10132.9,9259.9,0.830676,1.38376,-3.59798,1.88876,1.90766,6.33722,1.16568,-1.88109,-5.49532,7.56995,-3.97276,2.47056,-1.10217,-4.02745,0.530141,-1.80729,-2.44923,1.11112,6.04583,5.79514,-1.61378,0.146823,-4.31812,1.65679,-0.82556,0.385538,-1.6035,-0.921055 10159.8,10135.2,9260.63,-0.16576,1.00018,-5.12473,0.442361,0.505831,-5.64864,-2.63413,-2.52592,-5.46478,4.95174,-4.3147,0.782684,-5.73615,-4.82371,0.266276,-1.86669,-4.0481,-1.31822,9.03428,5.18538,0.835431,-1.04748,-4.21294,1.0615,-0.105573,-1.22812,-5.24566,-3.63422 10165.2,10138.1,9258.46,0.205477,-0.680098,-4.46762,5.26891,1.18115,-1.68502,7.13137,-1.22722,-4.01706,-1.7858,-0.511666,3.55446,-3.85553,-2.43205,1.3525,-0.694302,-4.16672,-0.729833,7.26617,2.38627,0.742375,-2.04911,-3.24066,2.72775,2.10783,0.115275,-4.78462,-4.34396 10171.6,10139.6,9254.61,-1.51268,-2.23477,-5.13237,-3.29461,-0.317239,-10.5071,-7.94002,1.87205,-2.15615,-2.57627,4.52526,1.46446,-2.39092,-3.68309,1.44927,1.27351,-2.10555,-3.67494,7.0263,3.64847,0.370668,0.612656,-2.452,4.76347,5.31087,1.21101,-2.18927,-4.86589 10174.6,10139.6,9250.85,-0.380976,0.430706,-4.77251,1.24603,3.57465,-3.14504,-10.8805,1.4131,-3.82203,6.1265,4.05681,1.86576,-2.69539,-3.84931,0.571097,0.0445532,-3.61574,1.0929,5.45496,4.67637,-2.69117,0.376736,-3.44843,8.26613,5.44059,2.39248,-1.35143,-3.43895 10173.2,10141.8,9247.9,-0.967231,0.660605,-0.333774,0.682442,10.1733,9.80472,-4.02844,0.296976,-2.0856,1.70749,0.105393,-0.302007,-2.02762,-1.68176,-2.57321,-1.85542,-2.20576,-3.56605,7.81712,4.57148,-0.717533,0.00661063,0.070936,7.88567,3.00205,-0.188925,-1.30646,-0.417109 10169.8,10147.8,9245.05,1.57911,1.89614,-1.23894,5.44327,1.1255,2.7455,0.888702,-2.69789,-2.29535,1.37374,-2.16695,0.277041,-2.61632,-0.168021,1.19527,-0.966804,-1.39634,2.02717,6.13068,1.74285,2.61838,-0.673957,2.42798,5.71141,1.0237,-0.190537,-2.48355,-0.424022 10166.9,10152.4,9241.4,1.48812,1.56883,0.00439658,-1.99079,-5.3945,-7.45076,-2.79497,-1.09824,0.438405,1.08335,0.567998,-2.12211,0.537132,0.235065,2.13962,0.850241,2.33283,0.11668,5.71046,0.316621,2.37782,1.5783,4.38674,4.44102,2.85837,-0.867284,0.197126,-0.632035 10166,10149.9,9237.21,3.10346,3.20745,-0.0787972,3.26164,-1.99167,1.15174,7.73898,0.388067,-1.3872,7.93093,2.89628,-0.846609,2.95243,1.10786,0.0356645,-0.191303,-1.48335,3.06518,0.833731,-2.48298,-2.62814,-0.329278,-0.0454046,4.84244,1.50962,-0.571214,2.28968,0.0896905 10169.4,10141.9,9233.72,1.54047,2.79665,0.872984,0.435893,0.341067,4.50191,6.31086,2.24353,0.0763229,5.33021,2.30696,-1.94916,2.28551,1.6759,-3.55737,-0.57595,-3.31446,-1.28349,0.109544,-0.911539,-3.08755,0.149125,-2.57658,2.65457,-0.759677,-1.72314,1.73795,1.22082 10175.5,10134.5,9231.85,3.08721,1.31195,-0.463831,-2.78365,-16.0641,-12.4959,-7.90321,1.44639,2.2521,2.09953,-0.628689,0.674957,-0.991746,0.999703,0.501374,1.08647,-1.9555,-0.457535,-1.969,0.140249,0.679574,4.05153,-1.26929,2.9472,1.23177,0.0460567,-1.18548,1.19414 10178.5,10132.3,9231.94,4.8578,-0.156201,-1.83619,3.45539,-10.5983,-4.40534,-3.25278,-1.48511,1.7839,1.07398,-3.79721,3.44697,-0.661031,-0.19397,1.51898,-2.78611,-1.58924,-1.02247,-4.03291,-0.779814,-2.72459,1.42865,-4.44874,1.96164,0.024013,0.769821,-1.68183,-1.09525 10176,10135.5,9234.24,3.98434,-2.9881,-1.82932,-3.45496,-4.37718,-1.32479,-6.81161,0.242295,3.63988,0.773917,-2.92089,1.50769,1.03257,-1.29175,0.607123,-3.32519,0.794345,-7.2134,-4.18473,-2.11878,-3.48641,2.04926,-1.83971,2.5711,1.8547,-0.444122,0.204744,-0.633906 10170.3,10141.1,9238.24,4.5574,-1.21766,-1.92884,-3.3891,-4.53289,-3.61119,-11.1428,0.87067,2.52674,6.28098,-0.916225,0.833349,-0.285056,-2.02874,2.83162,-0.822357,0.836116,-2.02452,-4.36166,-2.46534,-2.40599,3.53798,0.439996,2.8824,2.66576,-0.190266,-0.411649,-0.335746 10164.8,10146.9,9241.73,1.14271,0.21175,2.54403,-5.97996,8.86795,9.92082,0.583279,0.92891,3.1377,1.52082,0.653327,-2.04189,-0.909795,-1.88382,-1.45444,-1.72465,2.94817,-6.9659,0.661566,-0.779148,-2.33549,3.61435,1.90115,-0.709103,0.572663,-2.44443,-1.61985,-1.24632 10161.8,10151.9,9242.42,0.429305,-0.24402,1.54324,-0.758714,1.99988,2.30697,-0.150645,-1.67843,-0.372931,2.68223,0.974669,-2.18675,-3.69726,-3.84373,0.315076,-1.61503,2.02219,-0.439987,1.5067,0.347441,-0.468043,1.85512,2.51346,-3.61534,-1.61311,-1.68631,-4.32277,-3.31289 10160.6,10154.5,9240.5,-1.6783,-2.7916,3.79283,-1.46484,1.8842,7.0456,3.61276,-2.08564,-1.14902,-3.90469,1.00738,-2.71903,-1.12392,-2.56102,-0.564502,-1.26929,2.87817,-3.80446,2.16188,1.69189,-0.17359,-0.806729,4.45158,-4.99401,-1.9224,-2.1335,-3.41399,-1.5215 10158.8,10152.9,9238.94,-1.26294,-1.55708,2.47997,-0.37092,-5.35681,-1.99801,-4.61673,-3.19995,-3.63982,-3.59422,0.268397,-1.15304,1.21312,-1.94008,2.37467,0.463918,1.03699,-0.249188,1.94821,3.1095,0.656428,-1.26258,5.17342,-2.5293,-0.911564,-0.727538,-1.60047,-0.657086 10157.1,10148.4,9241.47,-0.729297,1.90628,1.50273,8.02209,4.5029,7.25435,-0.943104,-3.87229,-5.15977,-0.605295,-0.786266,-0.00624273,3.2036,-0.99694,1.83674,-0.424322,-0.759934,4.69506,3.12589,4.93905,-1.14094,-2.37706,0.896838,-1.15642,-2.07425,-0.341439,0.651623,-1.90525 10159.3,10145.1,9249.53,-3.61489,-0.368775,4.8318,0.654323,13.8953,20.2332,9.01061,0.740005,1.06482,-1.98312,1.43178,-2.39481,5.44965,2.23927,-2.07082,1.84445,3.36316,-2.3874,5.82791,5.13504,0.331121,1.17574,4.11636,2.46863,2.53744,-2.31289,3.73605,1.261 10166.4,10146.2,9260.39,-0.690065,-0.196533,2.57149,3.28245,1.26863,3.07282,2.3288,0.343504,0.7493,7.7189,2.47287,-2.19401,1.83016,1.49389,2.04941,5.57015,1.68587,7.37325,4.33035,3.86901,3.21355,1.31074,4.30838,4.34097,4.14204,-0.792683,1.91579,1.4487 10174.6,10153.3,9268.63,0.973864,0.288282,4.67663,-0.604468,1.35396,1.77193,6.1612,0.928573,3.56181,0.301872,1.61496,-1.94891,1.37811,1.784,-0.829802,4.5252,2.98522,2.05165,3.03006,0.33278,4.9167,0.692046,4.78248,3.89965,4.1223,-1.28055,0.902128,2.44014 10179.4,10165.9,9270.91,0.383028,0.372248,2.91142,5.26445,-4.52355,-0.481389,-1.47582,-0.0802922,4.09074,-3.4789,-1.84054,-0.641665,1.60157,2.15213,-0.406849,1.24052,1.05589,7.69175,-4.79723,-3.42058,1.48542,-2.69221,-0.604027,-2.8823,-1.41943,-0.386671,1.59434,1.71786 10180.9,10180.3,9268.76,-7.39108,-4.07938,1.96913,5.84801,-1.99672,13.1344,-8.45676,2.45664,8.74322,0.00440195,-3.70354,-4.02376,5.09873,7.07674,-2.94009,-6.27334,-2.18896,9.06615,-15.5002,-6.518,-12.659,-9.2251,-8.78964,-16.0646,-15.2285,-1.36974,7.28841,2.96689nipype-0.11.0/nipype/testing/data/fods.mif000066400000000000000000000000001257611314500204120ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/fsLUT_aparc+aseg.pck000066400000000000000000000000001257611314500225370ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/func2anat_InverseWarp.nii.gz000066400000000000000000000000001257611314500243100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/func2anat_coreg_Affine.txt000066400000000000000000000000001257611314500240330ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/func2anat_coreg_InverseWarp.nii.gz000066400000000000000000000000001257611314500254670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/func_epi_1_1.nii000066400000000000000000000000001257611314500217130ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/func_to_struct.mat000066400000000000000000000000001257611314500225260ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional.nii000066400000000000000000000000001257611314500216250ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional.par000066400000000000000000000000001257611314500216300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional.rms000066400000000000000000000000001257611314500216470ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional2.nii000066400000000000000000000000001257611314500217070ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional3.nii000066400000000000000000000000001257611314500217100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional_1.dcm000066400000000000000000000000001257611314500220310ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/functional_2.dcm000066400000000000000000000000001257611314500220320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/im1.nii000066400000000000000000000000001257611314500201510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/im2.nii000066400000000000000000000000001257611314500201520ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/im3.nii000066400000000000000000000000001257611314500201530ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/image.nii000066400000000000000000000000001257611314500205450ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/image.v000066400000000000000000000000001257611314500202330ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/indices-labels.txt000066400000000000000000000000001257611314500224010ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/indices.txt000066400000000000000000000000001257611314500211410ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/jsongrabber.txt000066400000000000000000000000451257611314500220320ustar00rootroot00000000000000{"param2": 4, "param1": "exampleStr"}nipype-0.11.0/nipype/testing/data/label.mgz000066400000000000000000000000001257611314500205600ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh-pial.stl000066400000000000000000000000001257611314500210340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh.cope1.mgz000066400000000000000000000000001257611314500211120ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh.cope1.nii.gz000066400000000000000000000000001257611314500215130ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh.hippocampus.stl000066400000000000000000000000001257611314500224400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh.pial000066400000000000000000000000001257611314500202340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lh.pial_converted.gii000066400000000000000000000000001257611314500230540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/lut_file000066400000000000000000000000001257611314500205100ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/magnitude.nii000066400000000000000000000000001257611314500214400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/maps.nii000066400000000000000000000000001257611314500204230ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mask.1D000066400000000000000000000000001257611314500201030ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mask.mif000066400000000000000000000000001257611314500204120ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mask.nii000066400000000000000000000000001257611314500204160ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mask.nii.gz000066400000000000000000000000001257611314500210350ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mean_func.nii.gz000066400000000000000000000000001257611314500220350ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_f1samples.nii.gz000066400000000000000000000000001257611314500233200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_fsamples.nii000066400000000000000000000000001257611314500226200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_ph1samples.nii.gz000066400000000000000000000000001257611314500235020ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_phsamples.nii000066400000000000000000000000001257611314500230020ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_th1samples.nii.gz000066400000000000000000000000001257611314500235060ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/merged_thsamples.nii000066400000000000000000000000001257611314500230060ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mni.nii000066400000000000000000000000001257611314500202460ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mni2t1.nii000066400000000000000000000000001257611314500205750ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/moving.csv000066400000000000000000000000001257611314500207760ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/moving1.nii000066400000000000000000000000001257611314500210430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/moving2.nii000066400000000000000000000000001257611314500210440ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/mrtrix3_labelconfig.txt000066400000000000000000000000001257611314500234600ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/my_database.db000066400000000000000000000000001257611314500215420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/network0.aparc+aseg.nii000066400000000000000000000000001257611314500232340ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/network0.gpickle000066400000000000000000000000001257611314500220730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/nodif_brain_mask.nii.gz000066400000000000000000000000001257611314500233670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/norm.mgz000066400000000000000000000000001257611314500204540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/pdfs.Bfloat000066400000000000000000000000001257611314500210470ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/peak_directions.mif000066400000000000000000000000001257611314500226220ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/pet_resliced.nii000066400000000000000000000000001257611314500221250ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/phase.nii000066400000000000000000000000001257611314500205630ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/pyscript.m000066400000000000000000000010041257611314500210220ustar00rootroot00000000000000fprintf(1,'Executing %s at %s:\n',mfilename,datestr(now)); ver, try, if isempty(which('spm')), throw(MException('SPMCheck:NotFound','SPM not in matlab path')); end; spm_path = spm('dir'); [name, version] = spm('ver'); fprintf(1, 'NIPYPE path:%s|name:%s|release:%s', spm_path, name, version); exit; ,catch ME, fprintf(2,'MATLAB code threw an exception:\n'); fprintf(2,'%s\n',ME.message); if length(ME.stack) ~= 0, fprintf(2,'File:%s\nName:%s\nLine:%d\n',ME.stack.file,ME.stack.name,ME.stack.line);, end; end;nipype-0.11.0/nipype/testing/data/rc1s1.nii000066400000000000000000000000001257611314500204140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rc1s2.nii000066400000000000000000000000001257611314500204150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rc2s1.nii000066400000000000000000000000001257611314500204150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rc2s2.nii000066400000000000000000000000001257611314500204160ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ref_class0.nii000066400000000000000000000000001257611314500215040ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/ref_class1.nii000066400000000000000000000000001257611314500215050ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/register.dat000066400000000000000000000000001257611314500213000ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/register.mat000066400000000000000000000000001257611314500213110ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/resp.1D000066400000000000000000000000001257611314500201210ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/response.txt000066400000000000000000000000001257611314500213610ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/resting.nii000066400000000000000000000000001257611314500211360ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/resting2anat_Warp.nii.gz000066400000000000000000000000001257611314500234740ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/resting2anat_coreg_Affine.txt000066400000000000000000000000001257611314500245530ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rgb.nii.gz000066400000000000000000000000001257611314500206540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rh-pial.stl000066400000000000000000000000001257611314500210420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/rh.pial_converted.gii000066400000000000000000000000001257611314500230620ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi01.nii000066400000000000000000000000001257611314500204150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi01_idx.npz000066400000000000000000000000001257611314500213110ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi02.nii000066400000000000000000000000001257611314500204160ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi02_idx.npz000066400000000000000000000000001257611314500213120ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi03.nii000066400000000000000000000000001257611314500204170ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi03_idx.npz000066400000000000000000000000001257611314500213130ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi04.nii000066400000000000000000000000001257611314500204200ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi04_idx.npz000066400000000000000000000000001257611314500213140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi05.nii000066400000000000000000000000001257611314500204210ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/roi05_idx.npz000066400000000000000000000000001257611314500213150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/run1+orig000066400000000000000000000000001257611314500205260ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/run1+orig_model000066400000000000000000000000001257611314500217060ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/run1_categories.1D000066400000000000000000000000001257611314500222420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/run2+orig000066400000000000000000000000001257611314500205270ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/run2_categories.1D000066400000000000000000000000001257611314500222430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/seed.1D000066400000000000000000000000001257611314500200700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/seed_mask.nii000066400000000000000000000000001257611314500214160ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/seed_source.nii.gz000066400000000000000000000000001257611314500224020ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/seeds_to_M1.nii000066400000000000000000000000001257611314500216250ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/seeds_to_M2.nii000066400000000000000000000000001257611314500216260ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/segmentation0.nii.gz000066400000000000000000000675421257611314500227070ustar00rootroot00000000000000‹íś±˛ő:•=EFÄ#LNÂ@LŤŞ¨˘Š€”„` ¦Š€l‰7€GcÎĎńąr{­î–,Ůň>ë»ĺúĎö–Ą^Ý-Y–µďý›-ĹżŘţýöźţůř›ď˙Žü«ío˙üűOżmĄüuěçöă˙‡ę˘ÉÚúŹ˙ř˙đ_ţç?ţ÷řÇżýĎ˙íýíßýŰżý·˙ćďţ]ÎÎŽ:j;˙é˙üłý˙÷řÝűąýóźsĺ˙—?ň?ţőߍ6W!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„¸™úűżŽ7RŰi8”+ŐńB.k.síëÁĆŇÓÇĘR­ű±ˇ†ląâ+RζGß®™i¸¬yqZăęi~Ó}Ş'ž,7ŢÄno6łăýęÔ¶·jţ~›ćěXő‰šëżłs·ň5QëďaŠ4VN[~C?Fü6˝B!„B!„B!„B!„B!„B!„hăĘoĐo’VgÄoLŢô[ dg‹ÝŮßS®Bö7ĚîčwłÖ+ý˝ëÍ+čölmŽ?¨cĹ˙ŹEKlÎf˝eŽ–,=övǶ>ž¤´ŇÜqöa|R˙má7éýŤ1F:?]łB!„B!„B!„B!„B!„B±ôěżëţzď}}.c{ć÷f+Ńú›1ô{˘č÷”‡ßÎ> ł5Ą?¨cŐßAgcĂrć@ćx’’;"ÍÍżď/Ă4ŃjkŘÇ[Ź›ąbë˝e”’<})í«R¶“–LLßţ{˙Ô3†9Ţřiiťo˝]ďNëňýď'ÄxÇÚßňśýFÍ»Ëńܧk®clĎłĽ«ćťžĽţ"íu™OˇÖĂâúišżřM1ŢůMZ…B!„B!„B!„B!„B!„XŤß˛w·ĺwoţmBę·e;ýýîle?4˙†¨lÝHŻ÷[»§‰ěŤ~_ĂbĽ˛îV[­˝-zOż~€[˝řöh~â÷Á˝± űxc}w2R3+_2őŢDw.VÇ:nÍoŇ~*.ßÇĺřîÇ]´ŘDŽ–8»>¸ĎpX»­fű}qľ{‹fçK÷©2HG+Ě–ŕ¸rŻú)ű$ĄďxÓ\Ńô|ľ+%űŨíě™o…Ďb‹Ó3ż|łŢ/˛q®ďAź¬ŮęO•{ěy±÷xŁ´JóşŚÖűÍ;=}ş.oëY•Úîúßýo϶ şîMxůšŃ˝2(Žőw-¨ĚŞ~=öüÔQÖÔ[łŰ9¬ž˛nś…B!„B!„B!„B!„Bńąx{Aßľg=łg9ÚËýíÍż7(çĎéßŃ.€gsVóoK$ks”×oŃÝkëŐX×őÝIŹťŁ5ßţűŕ¬Mćx«ć+6^Ő[ěą»ěJŹAמ4—«bb.ĺauxő@]Ţ1›V{Čů®I÷d˛qŽlnŃężĐ®gú®ĄO»šďÄł#8ĽqĹ—j~fKu0{­Ţć1íAZž/®Ä˙Ç/ amě™o…sÓEéťSżi­€áéöĆń·jÎÄÚţ-ÍďÓĽj)q™Ő5×6f´dŹ•i‰]“ćBÚşY[ݦý»5w{4ß Ë94VŐó§Lţ®­Ď‘vźÎ}Űź­ÝL#ňSĆ_?íÜLCôť[WŮŇ÷ł»±~f9ÝlcÁ1gúďćϲbÄ˝ĆËón?ćÔË5›Ţ ąŤą]ü˙TZÇ?!„B!„B!„B!„B!„sÉěßEű‘3űśWŁk/úćďs<ýÎp!Ľ˝ę)í%<­˝Őf¶Ż»E󓺯Ř{%ÎOęľbëu÷ÚŘ«ą|đű»`í'ŽŢ83Ý·Ĺ:°oF~4ÖÄž˝™şŠóÝ*š[ô{1EńeuOĎďŔƬ/¬fßúX-ΑFÔQś­Nt<˘y#íV6ŮŘ ˝^~łff§7–5i-Ł…8v¸6~Ţ=«ţ{˝†č݇‹S^· eŁ6fçŃóčŞÔvGs®:oYŮźk§u} łž˛:ž^;ן߬yÇÚŽî?űßoŹó‹ł˝Gů˝2µ}Ůţü¦ľŚě±óŠQÇŞě¶ŤŇ˝×eu?áć–ż#â‹ęľ;l~Î¬ąľ®K{9×ýDŢŁĹ:S/›“×?ˇ;ę§˝Ď~QNŻ˘y˙Śt·Ú”íÇ?ĺŽi˝”Ťę\m®2ÜŽ˛s¸¬Ąw&+ĆW!„B!„B!„B!„Bń˙ą˛Oy…}~­dlĎî~…ţ’?®h^Aű›ŁĽ(ďă}\7±§E3Ňíi}R7‹QĆŢpďs‰ăüsÜD”“]ý“ÔŐw[¬‰ťéŘ$ŽbŽ'5ł|LŰ—<źŐ|G~źöQłÚ3ő<kb{Ź­6®˝uÝĄŮËíí™ëźÖÜjs6ÖÝő̤Ă^›ĚصDś·v;ŃĺÍ=›b|'U»Ąú7“‡Ů9XXßS;zž; ů›öU(ąçĄŚţZ÷ęż3ş:ŹúÄŇ”í§Hëł+ÇׂĆ(¤«ţĽ˙˝ęď"#Ýh ¶Łţ»Âď_(­±ŽÖIWŽ»}öbşë#Zţ©wQÜx|x±Eőß ó˙čµ[çĐ]dbÇr»Gł—·ę'mgňµ5O2s·Ůš˝¸ftGugőÖßß­9m_Cýu}vnfďu·őë˝vY˙ˇąĚ•ú{‰růJ_Ëöá;űónW4f˙u{ăěO7ăęîĄ4aý>$×ʆýhŹ@9>´ŐuVm¤#s óŐ]ş3ăOd{t»Ž“ÉŽ·#4G×ßö»›ŔŽV»˝ëšę‰Ónds´·ß»>Ô>Ňć%{“×»ő̤ÓŢ«ąÖ7“N;3š/Ő7“N;GiF×<ń{ÉŚfö¬ý†,ĺ»» íG¶zżŤ´Ný­K Uűű‘‰ŹŐęů쉹W›»ŮĽĚę}4®Qľ¶Ž_6VĄW7óVĘe«»Öëĺ<ęż+ć3"3&[ťuß~|m d3Ňěő_¤yeí­÷ßý»L|źŇÍl‰O7ÓZÇŘŢďÍ!Ń8śőA¦˙zmţžh›Ý-ľ‰ÚzBł˝˙ÎŇ ďó3©Ú­ÇZt>{߉4ŰvVŃŚl<ő{O/»źßĄ™i«?[Í­u{mPíA÷”Ý1(9ͧď&ĺße{X=ě¸6¶ëgU}¨??ˇy'Ľw^ˇŞŤa?çî¦ŕcčü ®łÜ;vE6MŃ[µqylB!„B!„B!„B!„ŹíoΔeĺ—ŁÄGëĺ©{s.Đj?ÝĘ,ą_¨lM:B= .T›ŤĄśËd÷˛ŇănľŰÍĶ”śćĄu7ÚĺiyîÖńŞEG ×o3 ěföŹĐlë:Ô;“ öŽĐKë›É;{5oćß·i¦÷Úŕ:棕5{1ŽęóĘ߭ٶ}·ć'r;ksÖöeăĽq˛±fżěŽó]ö#Íě·‘Y_ţ~6on‰sëµ·ĆÖŁŹQýůŃ\ÎP¶C,®j¶ůĽ*Ů>Zű łż#~šěŘdc»™óoŃ[ÝěyOó›´{±¶1Ţ?׿űFëÂOig˙O‚ź1ÇśGşY_fqµ÷ć[µŰŘłRvžµlľľ#(ó|ĐłŽ}Š]uŢŢ“"˝ŃýnÖor3mlôxńô|lűČšŁ1¸Uënď!WľşźL×[if/k.çĎHóď ĽţČěËÄŐ§P^ˇ<›:Ž'ěA9—ążxcÝ#}y§ś”ă‡2 d5ߦw‹sÚŐŠ©Çóç]ó6îśâ[.4RŐáćĐ•6.Ř4ĹR/;îÄŘ1Ü˙ Î+cĹ0¬ Łm©ę<ůö“)ŕB,Ă[Ö·„hĺ7ć¶4˙~Łf!„B!„B!„ďíűË”{ăÚ··‡ě¤‡”»sďW/v}J‹S&ĺŻ')ç#Ňĺí˝_^{é?z÷ý?Ş›Řs‡ćGt'íjŐ[Çáš»°íšŮ·FzˇPß#şěrít®÷ĘĐ:fBědq©ŮŐ=“Ýâź'ăěů˝5ż[Ë>©y„†+×ĚÖÜr?E¶ŁßŐ ßRe5ě™DvNíĺ5űŤŕţ{ŽÍÓç&ÍĚvďşPűD<›#ÍĄđßÔy×xşďţ­‹›gł÷[ÉlľŁ3ZçĚžî®Ü~Ý=ăŠďÓĎĎŢďZGkľł˙fażď´–Ęł{Új´ŽÇÖVďÖD[Ć&O?ßźĐÍÚdq‰ú)Ęůč~vç8Ćć#™ó^.×e"­¨맡[í8d5·ĚłZôRڤŇfí´şˇ˙‹Ż9Š1ꨎњQl]™±(«H{V˙ĎwŁízýóŠnĎ—Ěߣcśťc2[FkFcŔ¦H·7ż°:™ŢT3m±<ĎÄű ¤Ť]žć™q®Ç”–xgćSL33îčË@[ě>”í×_D÷¨'5{󨹺γëđ}˛nÔÎ4[ńř¦IsĐĚĄ;(´ëpŢĺßé{S7ë3·Rś\؆7><ÁIó 8„BÜĆS÷'™úĽ»(ż]óoŃţ[5ď˙ţÍB!„B!„BńVĽý`=ĺV%ÚÓWďńö]ťöź-łżĺ|䥴—9ÜUĐ^úŹĚžB¦ý1Ý• ÖFŁ(®č:Z×ÝTmsŘsWň8•+wÚŽlöľďŐ{—ćčwłuďĺvĚ&iËý+eîé±NŘÄ´ =lż{FűŠš[t ˛‘î;ň»n#š3]Őkó8<&‘™G1kým×öżďţ-Óŕi†6“ňQ¬ďxC6[ťÍčw6Ůľđ´ćÖ>Ú˘™éFĎŞwĺwóŻŮ^őˇ[~ńŤ÷ű/¦›ĺcV3‹ďỉx6gbÍěŽ4{yrçłe¤=ŇPHŮŚfkĂÝ0Ýh\˛z2c×’k„e¶1ÍHc¶<•ÇöĽ“Ś6{ÎŻţŔ®Ń°{ż¬ć(Ďë϶źŘqÝúÄóÇ(ͬĎŐç˘üFőp-ň':ö "sőĆž(¶,Ć‘Nč˙4łţÍr;Ň[ĚżžŢ‘ýšéőâŚr5{°ş9]Ć鵚™ŻGkfőy}h¶fÖ'Q\zbŚ4łxĎł—S¬˘8 {P¦{uOÓĽťŰĎÄćźŃÔ2g÷4O™źŘą-•6¦!;W§×΂´鵚í5lŢ•Ń?-Żw`ľ•¶ń‹ivó|6^ŰöŘŔóŔjöú6ü<›r> ćoń#tšëĐqřî.PŰőQô ŕ÷¨îşí›ˇĎ \ĆF÷{Űhg521y"nB1Ěxţ[•ÓÜëđ[5żáţ:’ěĺ“ř­ą˝?G˙ÍB!„B!„BńVŕľ dą·¬ł˝hŹXfÔňşKĂ>źë]^{ÉH·=ďî5«Ż{’‚¶WÎćą»żĚ9ÓMěąăxDł±ˇ5NŮü_EwƮۯřâ6ÝŢňˇTG‹ć»Ćňěý…éeş 8šęźÉwlüő40-컌îé{S6 {ŁŘuǶĚ׌ö’GűĘ[ăĚľŻŰCsŮYxűçŁřebśŤ÷iß™ŁŤ]í-zk­'˙Ĺ·W3˛ąE3ĘńٱnŃŤtĐ8‘ňY˝wjötgăܢ×úşÔß Ćó/ÓmµFqî9~ iłĺŮźiîŃNűÚ Ľ9~«í…üݲÎâőëxë\ŃxţőwݧY-ŕÚLśQîŚÔŚć?‘˙‘fď`ńcľ¦6 ĐśÉ7›§űѢ׋µÍ7'®Rµ™ÉOk×č8ł¶ýă"Ńłb¤Ů–G:÷ż˝ţi=”¬Ůę@š­ßłqöć)VË·d}ěiFąÁôzĺ˝řŽŠń@Ý­š[¤Í5Ń1C3Ę;k˛ŁG3şŢkg¤ćh>móóŞnvŤ—ÓĂăĽqŤ˝±öüő%OóP4#›68wt´†şGÚčŐ;Błmoh^“±§Ą˙z9ĺ7ü< bC«Ţ¬/"Íűą©­Íń5dĆ𾪭iýŘŘÚo`÷'–ŰOh¶ö Í{9{oeqö|VëcmÝŚ(sęŁŕ{ݰŘß­·…®qěhş_}Ńxüiş™^ô÷'čý"Ň|:÷!üĆţĽóĆkŇůÉzw~Cl-_ZŮ\ôů-}X!„B!„B!ŢLëűoďÉękÁčť›÷Ž9Sî¶}A=˛ż„Ţűwř®r˙nZµžöý$Ż[ć˝Gé?Z4?ą?ęDi?P¬Ł=Ëč.çŁ;n×Ü®;i_&ÎőwĄˇŽ;5gă’±żrś Ź@÷Ó¬–}4GfbŰj8Ľř5ŵüeÇŹ-“`űśZu÷ř i˝eżho„ŢÖܦmʦÁ®žĽÎęö4ʵcCOŚKőo‹ćđçŰŚîšRţ×Ţ(ÍQ™Ě¸9*żm,{bV_Ó3˛˛Ö–YšŻćjëŘď•)Ć–aăh—iÎô–ű|¦Ýş‘=­qŽrł%ĎmŰĹW5Ű~\WőzyĐâOh×L˝QŽ1-‘ŻĽxŰkQľŹÔĽ×oëÝëŽâí]ŹolóÚ­9ĺ×›ďjÍ=ą}đóEÍ‘ý¨möť§{·×ćň)şöp ÖĚüË´ŘţĚüô#đ]tÝ Í¬Ťbţµ×±ců\Ląl{^®\†ŐkÚŚć#ŮĂ«#Ęé‘ó0Ö†Ő>Kó®ŰÚ€´zşŃw™s¬Í™złš˝ÜŢŻ©µŘ¸yײXOŘĺٜё)ďúy2-¶ŽŇěĺÖ] ›‘†úÜU_Áöž¦śŹĚ8ܤ}3/@Ë}§éűŔt{ăţcÓhĐX›ŐüF˝_Ř{r4¦ŐeŢŞů OóŇăńE˘űŐéűŔjňĆőOŃüEú9ęĂ`ĎMźă«ůk\űtÍ_â >*µľ·ß‹…B!„B!„¨9­ď&ĘľmMĐ®Ógöeö­Hö=EVëęďtX ˝ýŮ˝čşÇ)Ű٦â=zOÇ“|ŰŔŢ1fsÜóĎŞš]űŞď‡Äx?ž ´ŰŽt—ď#Ýźëó7˝SEGFSÓ8¶ź» tˇ§5OîŇť˝ź¶h¸Ň7~®źDˢçČöi›ăSďۦí^˝—ç$ßű†ă´W|Q{‡kGClˇ»%§ĂkG’°«W[¤ŮÓ[CsĽĂÎV_xőeb<:Ç[úîŚ{5ŻŠă§:GƸŐo4¶ö¸i·W7»żf®µíşv\ŘÜŁŮÎWŮóg¶ľ»4§ňŞă`}¶;żŻ@Ú¬}śyćď]?±meb}ů~ĺčµm1»˛ý!šŹZ»ţčÄłˇUłgźÍ™ěśË«ł7ÖQű|Fy`5{×Ůő¦ŮŤńÍíˇ6={fv°5#ÔË™+ąÍ4{1Ą>'e‘źYŰĐ4łv<˝»›ŻŃ9ď|>{Üf1bşŁ#ňťëĂq•@ď~Dv_Ő›FjŽÚjÉńVÍ^|iľ ĐlŰd±źˇ9›gĂbĽ“°ăŠŢŚnÖÖđ“™‹1ÝY˝‘îâ´ósn0lľŔ42Íőµ…”‰žŻq­ż›€§™Ĺ޶ťĹ‘Ĺšť‡ţž„×nv,ę-ËtŹěĂ”ŞM››^ßłńc}¶şY=ˇ寵;Š!ë—žî»rÚ‚úŠVssšOQüĂĆédßŮţł„Ţ-_µşN”#'-@Żć(®č¸eĽj€igą‰Ć«÷tźZ;bąšŐüě˝4“Űűśtő\öř±µln~{}űMzkX¬Ů}ę47+ĺŻńőaꇍÉö»·ëýˇä4ż>§+Ľ~üqń­ç$żß¦W!„B!„ż¸'fűĚuoĹi]łß”ů¦lx˝ÚüííŤzËúľ÷ţŮŤc9ëeţXI»kcŮB-‘źhżxŠâŰďŮŢrśüňQ¬2yŢRöTţz4Gy‘ŃýsÝÍ ń¨U;ş—5űę&XľőhîńŃÝ÷đ«qŤ´tŤ ł1mĎŠe‹ŹfęNÍ)[ˇ˝‰ňűß…´?bG1çFÇŢÖYĽňŁqÚłşGćµýlm8µ= Ňj;ŁąT˙şq#׹çF‘°Ń‹ő•ŘŰĽŽ|;*Öµž¬îŢ\ŽňšŮrđĹU€–bŽV-˝~±1fv\Ö t!˙¶Äąĺžć}ďŮu [iŻ7ź3sWĎšł÷Ĺý­sW¤é?Ůы٠µimŠâë­#xgkŽ´ŐZPŮŢő(ź]˙NÔĺxĎúŔUÍݱlgůfsďëšČF›3‘ŹgiŽâc5łď2š÷k˘{/;?,ÎÖÁâéĺlTv˙®ö3*ËÚ†őwÂüžŐ̮ߵˇz2s‘ĐŽ+vX›™yłŐ…4·Üłgĸ֜ͱHw­×ú"s?óÚ;śżŠS?ËYfłwdóÄóď,ÍĹüťŤwŻfÔN”˙Ł5[ßźňŞCo«î©zw˝(ţLkĆa ťcčšŘŻÓÔš3±ÜÇ$[>ě« íá1&šmÜ[çÔź ÜpuĎ ĐĐ’ŮňĚ/'żĎb€†+ĺéu3ůnŁö1Óú|Fs}]¤ů§Ül€ťYŰ‘ŻP?eša[wRŮcí­í®í·qgź=˙ÚĽ` ˛3Ňá}oý÷hŚ7ż˙Z»ŮłŇŚľgů~'Ń}4ŁŹĹŮËé'ăěÍî–ܶľ˘íÜŤgKuX(o˝˛ĚwçöőśóĘ<édůý´ć/ě<őëLgyŤĆާôîěíłą!Óé´O/‚7'Žňv®dßťę^p^\ýŤücĽ­©u§¶‹=űyăŠďŰ`ńFľ k/„ÝÇĐůUűl/ôžSťB!„B!Äď`ĺőĘѰwŇŢúĎĘëŘŢ;™zmÓľű°k‚§÷‹˝/¶šŮşŘ[tGďéÚuńă˝j®{ď$ŮŢwdŢ,ˇ»Äďb3:ŁkO}ĺ!2{*˛ÚٵţUtłű‘§éfšŁznĎóŔž–~Ý”ÓöÚ»h°+ŠsÖ¨ţŰ4¶{4Gş˝±űTf"ŢŘ2*×{|:U·cSO|ł÷©¨Ťińn´'ŇB߯7¶35ŢN›Qîe4_‰ő~~¤ftîÉďž9Ş×®=74ÎAŰQłóŇÖŁsCtv˛9ŢW6Źe™—uM=ůݢ?{O´öľď„őcÖŽ—WăŤbîĆ —Ć6Ł<@şNű†@›Q°­ šëĎ6ţQÜ؜ě§´jîîÓ¤ ¦/ŠŻ7ÉĚËîÔěiĚhÎ蹪Ů꿢9WŻ}”ßžîl^ŁĽ;ŘŘAöy>ňÇW=,lÎdÖ‹Ůw§ü»¨9łťńOT&*ďĹ|dśYŐ‡÷ěßę—Öüšˇ9ÓNVł§=› ¨Ü(Ílb6D¶˘µź–\¨}jżż¤wëÇĽţŹŢŃxšŁrpĽż h?ŇŚěn]b~Aíśę˝H4'ĚĆŠŐů˘®7ăß‘šY¬ašŮąě,ÓÎĽţ†őOĎ6¶ĚwĄ´ë¶šĎi±ă,ěGÎÁ|ྫྷíçŃzk͵Ź[ÇĄH;+‹>#;fkn‹Żú‰ůŕăł(yÍlśÉř*síéűYĐß»Ý=¶G×Áqd6ÄĎvÔYL‘fď^w޸ZŰŤôxšŮuôúaĎ‘Ƭf[§ë‹»řnŻ%Ö^β2ˇŢ2V–‹gCuxqby’­÷§Ž`óż+šŃóČ*š˝{N&~^9vîNÍ_xs¨«1Fľqóé&Zćš#ú2Í‘›‰ž©KőoCű=›ÓŐßßăšĂs\áGK¬aź5ő=Ąw'ű\•Ńĺó“ńµdž an‚óĚ+Ä×’ŤuVóęzw2k;^?}‹Î¦ ůeĄţ:’ZÓ)/„B!„BŠßđ¬ö@„ĎÉ™2 â˝Ç`ÚŃ5oYĘčEkAěşŐ×Ţ÷TÍhťtճܴń˛±óö~­ĽŢĺek|QĽWŇí­đÖ­Ł÷pŃ8đŢ€H/ÓŤ|@sčnĘv˛Ďţ˝—Gům}…|÷ČFě`ąČĆ©Öw™Oî%a±őú_kĽQ~ŰĎOhöb2ň@ýćpĚÄi;Łĺ8}G—¬sŞîŞ~dG1˙fr™ů"ę/čÜ”<´DšŁý66ĆH3Şűt߉ŁÇjNĺ˘sdö—ÍÎńĚ^—Śm^|Q¬˝:ŮwCb lôúWý]4ĎBůŢŞyJ¬Ať-~ďÉëhîŮpY·csľ:YY–Cěďš=˝™#Łą.ŤŰévjδŲç{ŻmZ_§f”C­šís:2ş[bŢkŇVÔ~¤ŰęđľoŐ{°ˇ6žxľ`ç[î[žŽŮqöžĺműŃw-ăX¶^Oson}¦÷´DĺJ9ĎG˘6ďŇć“ŃZë­ó“ŐĺD¤ő`ËEÍßÖmzsČČf/ć_˙śď!h+ďĚ5čű(ĆQ>tkŢp[Q®E㽵×Ó›yްyősÝÍěđâEóŤŘh5gűŐđď Ůśôâm}­1fęń ͡2ąÇňŃóó/Ó}Ë^„­Q2ÍL٧™ĹŮóĄ=?zMĚÓĹéEqÎä¶7_›ĄŮú5šŁzš3kdH3ťŻŤ†Říő±Ö8łůŮÎiďXăöúy¤ÝÓ\@]޵S5o¸ížyyvýŢÓ|jwU»ž ,Ö(G=±±6ĚŤ!Űmß‹ž!oËgCë}«8ĺ2šCÜA`Źwô^çúď2kđ,ÖW5Łvî ;Ź@ůąż!˙Řq«®ď­Q=˙dr–Zó)ßĚąŚžT›ĎwŽŰvžŹbéµyîée~˝-Î[îą"_4ŹA9ĚÎß©ů 6§¸Úź˝~sŞëfîÖ sä Ś^¬ó‘ÍĎŮu¶?¦wăý:Ň}°Ý|ÇrĺńřVdÖŃß,Î(ŹWŇ[­Ź˛g1o^7r-s&l~}^9ž=Říš „B!„BüzŢôě•–5»6ö6ßxZíÚg´fúí‘^´f÷ˇ5Ň?ÇbdŢ3Z hÝ,z×µJÜ[Ţ'{ë¸čÚ×Ů{E_cë‹bĘP˙=ÄŐřÚőnvŤůTí#;˝üeqnňߍ´Ľ«A>hÝCÇúĚ­ş+{v =9ť˝G×çNýý˛ďO‘fvoňŢmş1.÷čöö˛>éőë:îčđ4×y6 bŹ×ŹY>Ă÷W¤ţLż™˘Ű±'ĘëZÓšťłşą>Ň&óAKţFe˘|šë–{J¤k„f÷EńÇëŚ]¬ĎÖu·jFç‡Äšh`ą}%Ż#ÍčťăhOŇl@cV¤±÷žměĹ©3ëw4çb÷(ö,i†í_еĺY&†Ě/WrĽ;żv2š­Öo˝ţ|·ćÝ[Á60Ý™ąX¦}ęë š[ýŚľËÜ«Ľë3ßťŽ˘1Äk»Es©t·Ô;CsKn{m×kąL3Š7+ŮńÓÎÍ™67ów­µĺůÓ^cëś稟eŰĎúi˙›ĺE“ŢšQ;‘v¦}ö|ŕµăÎĺhÎĆ/ksKě[c|éYĂiăŠfŻŽ-¨ĺ]­÷Şf”7ĚöŚO˛ľCÚŃu6.3ž'#Ű#=ÍěűÚ÷¨Ü(Í™udw [ăe:صÖŽA´ŚáőVł§µÉĆסëźÄć –YÍH/Ó<:ŻwĐĽČ›ł ťHw¦ś­×ő×h6g5gž—=?ŇëG“h3ăÖř˘zál0híŠĺY6Ö=1¶íO‹ń7Ńz%ę÷µÍ…\gËzzˇćɸ÷ `3˛=/˛ňŢzčz˙PŽŠEFsTÖë§ďgSµ—‰˛żeÝÉö XçDĽçËÍŮĽH×9`gVG«ćt^—Â8^.GZ®hŰ›MžČĆÖţún6 MkS‹ćßťŢmMÍŠů·%˙/çËMdŢ·D6Ű÷X]9~7eŁš›űŁSÎőŮÍ´Ľo`1níu~ ¶.Ő˘™Ĺ2|—ů$e;ińr4Š5ÔWýý¸Ţo˘uomÉ굺÷‰EAĎ~Ńú,ŤďKak*(/VŹç(~‹N!„B!„č=/~*Ţš—}~Ü?źÖQ^BËľŻ?dž׎ŢŃ~/´Čö :–Ó^đ:ZĂŤÖÉĐuuźX‚‚´žÉtŁrh]p ÝLë)Wť˛,ćűđ™÷©¬o[Í^ż_e\óÖď363_°k©Ďn"zç’±;łwĐćĚŁ9něňrlϤŐÎŢ÷®ąěűqżÓžâĎG"_޵Ż"Ę?/gí{6ŽeęľCw´Ź—大7zź‰4ßď¨˙±ĽFýÚ ®÷Ú€1 ‹łĂ{ßL󳜯ń4Ă6GlôÚG}ÔĆ9»˝ľĂÎ Ó ôfňÚÚí ‘ßĂŢé2š˝ĂĆ9ÚsĐÔÖ˛ó­˝™XGůťj«— ]fG4>GqÎä”WćŞćČßĚOłýŽŤg™ůłŁ»_7´Ĺr’iöĆoäç_е©Ç;˘ľoő1­^ÜšýÜAKnˇ6‘Ý-ş˝úĽ|ş˘ą'·˝ĽÎŽŮě¸K3jÇÓŚb›Ńbűw¶]«ýpn˛ffK*Ž/.ĺ× Í=ÚQÔźíż=őÚcÔ˝Ş'žŹěą«~¬Ď]šw'ô^‰ĎŐëćKTőxϸ­ů٢ŮúÝ[“˘yĂz™˛ZŘř íoÔ<ęyĹ×»ŻFZĐ3s¤›µc˙©ú3°§GłŐĹÚ–ˇÍA‘f”ŹQnŁë™n«™ę…ŃQ·ëůśŮźéŢ9÷YlŮ<Îäxk=ě:ęďQ€öXL™–čúVÂ\ ZŰÉÚĹ7ňŐ“šŁçߌľýűÖçÇHóĐ5ýŠĚş•ŐÍ|ąÎ»öŕó‰DóOtĎe1FăOq®eţzRsËÜĘ«Ç+‹ü:Łvˇxd5{ĺĽXźľźIŇÎ^ű»ëśIŐÎ(ÍCü8“ 62˝WuĎÖÜŇ#˝˝ďfŠąfzś7ÓVŇ^¤±U/»vö˝ęu[I›ëkŘÜ­»oÜĹw{˝ąť]_Ů‚:n‰ńŽc#ó´·ř﫢9ĐťDk'=9ęő¨űRsÂÂĎEýĺÄS1®9ÍőË1ćěY";7G9ţ¤Ţ4{ď–‘fÔOŻÖfďXY+"Ň…Ćí•ň÷*l]®3 !„B!„řű~Ů»ć…dÖ}¬6´–öýě=:Zëë!äűń´˘ő-»üńuţ !¬ŢL\/­>Ś÷Âłý Áś[^wÁöGš˝ś¶ĺ`®Ö‡[üĺůlZôząéŐ“ÉĂ1™–{)ÓQżłaőyšˇöY ¶öÚňŢ{ĽLݬÎŃ´ŘćŮ‹Ţٲ뽜B6ŚÔÝ‹LŚŁüŽúδ÷ÚlÍčíÝ7+Öh>|%Ć^Ü[4»q¸ °Ăł iŢ˙¶ďŘí~©ÝLď>męĚŘbmŞ5ł±adś/é&u¶ŘRźc1­ż‹|9=żťşYű,Ć6–™±ŰćHKě»cMęcšŁ9U4fłxîĺZrţŠf»l^gtłë˛ąĹňއˇ÷˘—Ĺšéń÷jöüÎ4GyŤ>÷ĚÇ2ţí՜ɱ+±ŻŰh©7jc´ćVíÝ=ţDőrf‚ćVÝu]-ëÚ­Úgj¶zZbÝűlĘAű®ŕhÝŰCď1<;‘ćlŽ ü­ĺQý]6ć­ďlP›ną‹ 6Xnޡ™ĺÜ!W±őUvĂĽ ěďÉmď€ĺ®BÚľCł§Ť#?çŻBÚ÷ćË‘ŽlnŁzŃőCcĽcëMLűlcĆ4Ű<;|7öŚĎěcq÷üŐ‡bsmŢ3Š“gŻ·ľíůĚđyt0Ů5Ú»3eX˝ĐžÁô>ď{ľ4{ůs‡ć/¬ŢŚnäĚwžć»ô~áiÍĆÇÓ\źóňănÍčŢč=#ˇř{cW!×oćÚÓąI°9¶µĹÚl?ŁůHV3ňőťqfý×;ZüĂrĺ÷4Şö{Ö9˘śh­çŽÜ¶ůÜkëUͰľY ˛—ęśw?îŐÚóÍÖ=csŻć–5ŔĐg“‰ž-Zěő´Úďw}·Ť×–âëé‰3óˇmë˝›3*ż8QľŁőµ7Ä4şźÖZ˝ß>ČoŇ*„B!„¸HÁz¦xółUf-ŘęţúŰ®ĄĽF{Á‘f¶^‚Ö˙V¤ĺý‹Ťµ§ů´~¶vϲ­_žÖʱtý şŁµéLśŁź|ö4Ç1ĘíZoÔě5OŻç·jFcW‹ć'óűę~/÷#ÍO丳쑶™”]R÷w{-š˝˛­Úëúî~ßŢłÍ5-1Gí޵ě˝NŹćźsłíöôÇ–÷ÎŃą=Ł1íőä5ŇŚž-zŽŃ9ŢŹ(˝wŐ­ą3-ÖÄ–«1®ĎµjFĺ‡ęNÚ‘±q×׺/áVͤ~Ďô™Ĺ4çLź?Ô5PsôŚŚú=Óí•ÚŞ:łűŠFč®íCu#Í6&öúZŐŹęĎj>ŐŃ ĐĹ9Š5ÜKQŐi˙Ž4»ů4HsK»^<Ľ=6čŻ]jG§f«ĄE3ň˝w ˝-íŽŇµÇÚîŐ|ČÍŞ®ß^ÍmŻť¦<3ş­®Ô9Csí÷ÖŘ3ÝVoNÍĐŚô^ŐĚęQďLÍudlE6]ÉťH÷Č{•µŻŐć͵3s˝Kš+Ýl~ć™´ô›Sé9îEÍ(¶lm+çŚć¨mŞű*I˝ŮŁĺz”·µ Č7#5×mőŽ»¬Žčšżä»šk;ŁuťŚ†–gsoÎ:úšµŮŞ=wzyíéFyx•ěÚFVłŐÉiŻśt‚= Í(>§Ü3{yĚ6¦Ś‚­é°ű6ÓíiÎęőžĹ†ôĺJłm‡ÝofŁźE±­ů‹ě¸míË檧9ťëˇąěöúg=^GąŇ’ď3`šŁąEKLYuYş®2:N6Łřz>‰ĘĚŻkĽ9§gwvţÁĘ1­'[&ŕé­íł6GzmY[‡mµ?+·˙@Úôúˇ—§ŮkĽľđ„曳ĎMúg1ŔF4ÖgëEľžŞw;Úx%Ż{žżëkďż4Ú:Z·ťLíËßDsd¦±#­^]żÝ°ÍÇ>gć§%ônţüŔËgŻO˘fą4ă*{®Śúq&ÎH÷©/?Dö9ĂŤ•sťőÍÓzk˘ˇľß˛öąB|Ůu˛ěşŇj±exĎ"Ń:ËŰ´ZĐZR­­±˝Mg+÷U!„B!ÄZ¸ďoAŮ·>kxëźv­äPî-ÚŮZ[7ńŢÓ®wo-Ź­“yšŃúŇJÚíz,ËéhMĺ˙i­lŘ;ro Óćv67–‰uŮN¶yŇ›˝v…XŰśÎĆĺu‹Ď‹uŮšlE±f>ËćÉ­$íKĹëb·Qň¶ÚśßŔß—ý6™–÷qLłí­Úm3u÷Ś9ž^¤żµžé9Ţ`«wľőý-Ó|ňÁ`Đ|‰éöüQçc4kÎť ý¶ÝÚ–hîí˝—Ľ¤ą MęGvd÷‰dŢąGm1»žÔĚrľ›u4±gMŞ˙"Ţ{qOsÓ˝,Ëköśň͵&kłc4–Ůň‘ć“öš3}Ějö4döXŘĽÉhýůű˘Ţ(ź=ÍÖ&O«˝®.çidvtalÉęF~Šbů)jĺÓÍ­‘=Lo”ߨíŮš#]č;϶¬ŢzěĎúŐ¶qEsÖ˙ٸGz{siFn·ć9łőăÖz=»FjnŃ™ŤőH_ŽŇśYżÉŘ sŻQ/+7R3z>˛mZűłş[s:ëźCýťxń`yĹlaůŃio×ziÜŢřz†gs:šŁµ†ź:ŻčíÉĎQ÷({ţçóUH›WÖ´®ŢŁĽgźšŮĽ°Go‹ft>ň÷OÝ4{y–±×Ú=#n .Ď÷34ł¶™ťĚµV¦ůÔÖÍŽš˙`Úôžó˝°×Fka^˝(ĂônÇvĐZO«f´.äéőü5%Ć[ü|ËňžĹ=WµĆĺŢĐ8o~»ĚF¤#ó,Ébě­µ Ďí ·r¬¶łWs}}Ö×Ăőn\łŮÓË>gę¸[3ĘżČf¤ŻţéÎh>}?Ó^6ÖŢšmms´®úvî\ϱ%łîŕ•Ť|űóy-ó‡;Ź™š˙0@WÔşëśĹ űŘxÖâ+[ß,Řsk«ÝŢĽ®ëúŮ4ÚÉâ|Es­}fŚwĽőĎvdݧ×;GNź(±&Ô˛qŤĘÜ–ÓŃóŁ·^ĺ=G˛üGzoŤń7­Ď—Ţ::<ż>ˇw§çcë(m™»Ć¬ čy)ĘË˝Św˙«ż_IoŤ·îĂútflXQk Ëugoíü Z-L×®ĂÓý6­6v6Ç?I«B!„b<č‚=KĽý#Zű8ŠEFo‹ć%t;¶y¶zúí÷ézď˘l'[ŁľkóÁÓ›©÷Îx÷Ľ‹łßłkłuŢ™ç-ű!v[jÍŮŽęµőLŤ5°™ŮĆr!㳌ćúďYĎ&čÝŞg3»źěttyą`ËÍÖěŮßÇ‘ż˝÷–u9O艹Áz3şmYôî‘˝ŁfůĺA}ý°x[îú™ÁËiď}{f®ÂúŮÍQ¬=öY)Šqćů3;—˙±q f”[(ÎV·§•˝“·~ uV_Ť5Ż˝Ăë§-1¶×0ťô¤9Łť­}´č¶u±µŃ ­m°ëfk¶1ËćeVóVüvŘçš­M#µ¶Ôá=ŽŽ3őeŁÍ˝zYŰ´Ţ«8¶zyŃ߳víů!ëŔΞüľkďÚ“?®’hņéČô ”^śë~>r­$ęC,'­–úYÉ[űAÚ­fdËHÍ,Ż3ci} {ĆđrČjµíťě±'ăw«%z~ö4łďą> cW&ż™ŽĚ3F¤‹ĹwXŚ7˙ŢŕĹ…ő·¬ćÖ¸ŹÔü‡ş^Öž±˝Uł˝ÖÓëMeCdłąuť$«yJŚ·X‹'¦1łvŕi>ĺűhŚ Ö&¦›Ý“_2šaţĎŔhCvˇďv-H+ë»ČOhNµKľ›uâ?‹şęśČ¬ĂdëšFŐV7ŰYŽG:¦UůŮšíłwÝ€Ýă{rdj^ďtŘZçC‹nV˙IűdŘłŇçĺet_¶×ˇďîĐ»ÍA"űYś˝ň°ÜHćŮ7ŇÍUžÔü…7_öb“™oPţä±óçl¬=­§>[_łŢşËYä”ÇSźŕ=CŁĽő4Űţ°2Q?iůţĚúý›Ćď™ú“™ľ¶#„B!„ř8ŕ»×Ä[Ó´k<+®wµ‚Ţ/Ű5¶ži×UVZ˙Bd×@ŃzŐ ×‘VŁlT[ܵxëž§5ĂEöԟٺ6{'Ę—`ýŮĎÖ5˝ëŕšá“”íd»—ĎŢű –çKĹű»mkOĘŢď#űÎťůçV»˘\®ăśăY[·ęn°ĎÓĹâŐ{Şc2-{"2ď2ţlŢÜ‘çŢ{â0…¬Řz˝k¦ěČä_V7;—ikZ¬M˝,—˝= Y͇k“yŻĚôÖçë1;Űß˝6f˝Űc÷¤ąĺl4‡ŰË6ĺĐ(‚6­ćŚm™˝(¨~ĎßCu¶<Í‘noM6ż™#4gç‡Vł§»Uł÷Ě…®żÚŻQ_Îj®mmÍëş.Ôf䣚[r i®ídz™ďěwQ=W4÷> x1fqŽúó/=.jnŃëŮ‚Ö|3}ÚëK¬˝îX°cŹY¤™­#Dí°¶{5gúrkĚ31îŃYűh”f¦…Ť«-ş{óÇkçŞf·Ď¶ ëjÝŮo¤N7˝v^ÍńÍL·˝ţŞfk—{OlĐśŐęŶnŮ9Jł­?ŰGjf93ęąŇ»¶Ś?‘ć–:RąwT_ë|4ŁżőZosuľýÇNf;ҮɔGíx÷÷Qšłąęi¨żË>§eâ ç94gâkmdz÷ĎŢł±˝Ţóo폹íĹ:˛ŽŻŽľL[°ĚE]^n3»XzĎČą–ůwXś7lł/Š›o÷ĆŮćË0@{^~öhf~ŤrúdË(€>vÎígĄýYŇË#hË Üy-h›Ůś]'ń|†â?ěeI¶Ďln]'ń|Ćlޱ%ŠĂ~ }őµ-cxč÷ÁxĎ‹YÍčZ[Žiö®˝;Α}™őŁ+Ç4˝[űÚUŹ.Ő5‰ÖgOkďsĆĆęšh·nżWsF»wÝLÍ66-63»Ż>WNŤńNáGÖćčžlőyőÜA4wbyó‘Ôá]ű„ć/XŚý^n´j>řěfĐslÔ7[cĚt?ˇw§ÖiŽrű zwĐ3—7ćd× 6óyÚłS'Ţš Ę˙¨ůy® °çE»nňĆç,ď]ň®ýëß]寣_ˇ˝ś×z^»FdµÚWÄ‹)Ó˝kFţ@ţYŽr>fď»čXE·]ÓĘôĺş?łłëžÖ­ë˘\µý—ůŔŐ\& @÷ ¦Ů ű+ąÎŽ»ďî$ÚĎ„ěeëşöűho‘íC·Řăć$8PÎd4ßoďÝšçŚv–÷Q˙®´ŮÖŞ—iFefkfăôͬĽkšë3HŘîĺ5Ű+´2(®ˇöÁ´ě_ŚbČöŕ°}XŮkҲÇć%łŹí)±×zzOuŚ"Đ`mĘ̧Ř /ź™ß§ÄšŘěóöÔ>ÉęőâLýp‘–±Újb¶FšëúYΰ‰3©ßË?oy°ÍÔ…ô˛:~ňřŕ˛nPgk¤ĆٱcřýEÍu˝­šŃµ,Żłą龪9;¦zůëů„=Łež±<_\Éď(®ŻÉ÷-×1Mź_ŃěŮőÍÍ”Eľ¨żót±kí5W5Łz™­‘ćÚGQźÎÔĺ#4{GklZç`ö|FďţśYďËä÷É®ÎëmžA_^Đů3óĚĺŮ:*ŻOĎŞ5÷ŘÜ«9~>_ Ęë^Í-zQáśý˘f–Ë-şëď[s$›Ű‡r43űzâŐ˘Ĺ8ôÁUvXű˝kö9e&7<żÚü›ˇ™µŮ’źÖ>oÜ·ç<˙žň`€ć:§zó´Ö=g´ä,wÖ§‘‘-žfäOt˝—óŁăśŤAô}ĎśŰËëá}yÇi3Ę﫚#śěDöšĺh6·=ÍžëşgiŽŚćŚ>/‡†R×Ř`mfłcYÚçŁ1¶dű]­É»–•‰b{8?A3ës‘ćČ_u™r´íÁ´Î‘ď8y?6kőÁ~Í(ΊńN4–ôhnÖVµu¨k™µ±V۳עü­wÇÓÜŻÖ×׌ž‡0挝ČfďzŻţ»bĽăÍŁs-ţŠ®{Jsť—LË(˝ŁÖs{AqÎ<_e×˙Ţ;ű0ĂĆ8‹ZcműîÓzwĽ÷t·_ÔÜck/Ămnł2­m˙迨™éf9`uy×¶Ć8Łůjnł>góÓjb™ÉäKÖîfĘŚŇ\ן]ßÜËR¦.ë厭ŹÍg~Ę ĐéÍŘZŰk?Gů^LůĐ®ÁškfćHł=˛×GţńLíćh;c3Óë]źY[=ŘrP§çűVÍѵQś‘MŁ4G<›˝ĎhŽtĂ|¸@”S-÷Ł+šOqşç®ŕčÍćvĆîžëܲ5·äl¶,űśÍ‘Đ˙WqěËę­óąľgűÍa`Ă(͵™ćŚÍµĆÖů)kúc°f–ź-š{îŃ-m\%łVâŮT7R3Ę˝Qš3>¶96Zsä‡Ă1o-ÇćţUÍ-şgäő•-QnłďŢŢXŰ6G<_Ô´Ěńm˙Bz÷ďłš™îˇ$4"ű2k=^ßđ4źôŹ&Ń.:˛Ď WŹ™š[ú\dăH˝ĂózűKkć~ť±Żu}đOó÷”oüľŇŁąçşúZ»69%Ćß´®˙e5gݧmOćj¬GřĚ®ťÎ­5Fö"}Wć_węý"zôÎyšłZOńľ‰ĚÜÚÚ×’ĎĚo§Ü¸›Âmeë ŢŘźńŰ!ÇĺfÔÇëÁúĂSzwě3fÔ7‘ć¨Ď®¤wÇ‹·—·ͧÜYŚě:€Őś)·˘ŢťŚng·ĚKđt{ă·]~3§ř“óo×)„B!„bżĺyŃ®kÖ˙t—óšÉŰü‚Ö4˝u.«·.·şöĚ{¬:îµ^¶ďbiÝe1ňtGëâp­lĽujO3ZßE}átÝdŢ+˛ó,¶Č/¶ěŁşË_GvoP&Ć‘OžĘóÖ÷T^®ëČč~˘{ď§ZăÜRţŃľ]ÎGĆöL_mÉďŰb]đŃ_”ŰŮÚ0 vßé±5óţ˛E÷´xwŘiî­ó¶XŹ´ŻÄűŹZęš˘ą˛©U;{çzÚ×ÔéęÝŹA°ç¤¬n/ĆĚö§5ŁXÔv0Ű<»Ł}‘Qźř±ń"l˙g×nŹ'ďą9:Ľ8ŹÔÜbS´ŠĹ ŐăŐaóm”n”™8 Xźěrędą’ŽůEÍŮśFš‘ÝhM}źÍ­“®`t2ż¶ęęőWT׬8{ŇÜ/ĎW™vďĐlmaögâÝŁ—Ţç'i®maó¤ŰÎżJ9çĺ|”k#Ćmź(ĎląZźő·ćë=Ńc€f·ď8zYŮşźG×gňl¤ć¨­›ëصúËko¤ćlěZăĽk÷®‹bmóîÇŹ4{mf4łeç¶^ľÍŚ3ł­'Î66QĽ1Ě´uQs&~™Ů9Š=×â3OűeÍŰ_ő˛v˛yiďŐčŢ=ĘżŁ4{vebt—ćQĎĐl^Đ›ŰWëD~®Űˇ9ÓŹFiÎÔýOsÍČ8÷ć]mS6·[óç¤ {Ř÷Hłw®×·ŁňşÖl}›ŃŚ´yööćĐ ÍWĆŘěóó•ľSűn(¦Ť»f?¶Ťf }ŮŘ·čăíŻş‡ÄŁ´÷T‡őăpŠôŘÜăCjĂ,L;­±á7dĂ”Ó;o˛ö^ťŰŐů˝\.; u[S”čűŐőÖxk?¬ßłďß w'ZóbçŢŞqŇśB!„B!~lí•yű34Zë9­mnŰŮßÇ«ô—í`·]ű„şŞsÖG6'VÂƕŷöA´WČ®‘-E٨NoÍŢ®éŰżéúđÓ”-ĄÓ굹ď•G×>Fe3ăě{-4ţ=oö.6ŠŰ)Oë6P˙SyŢ«ŮĆ9SőťŰsŘ’Ťń)?͵H[č“Ů”óѢł>ĐĐ]ç$l\˛Úi^Vz—ůíŽ{··/ 'źYÜÓ9mŻťA]žŤ®Ý‰ş™ĎFăŧÇ>şOÄ©Ďk{t¬Ł˝.QĽ7p zźÝ‹âúcĺ|drÚ‹ŻZę¶eą2H3Ę­ll#Í˝>¤9‘žý¬ĄŕyV«ćě3=®ĆšŤ]YÍ6˙ösŃÝ;7kşžhŻçČVoţá]›ŽűEÍLŻ—÷v]ݵO´ĚÇŕ1Asćľ’µź]ÓĄu˘f«iG{òz™ë¶Ľ˝g—pěDľ÷t챫m÷Ęy± c~Q3Ë__TĆjŮőÔ±‰ňĺ–  {K¤=Šu]óIK>ŤÖŚňčŞfď¨ĎGZGçvčÓ@3‹u&Ż31®ëş[ł÷}&Ć™±=cĂUÍ˝óm–ßu!„B!„â h˝ŕSAë]Pw!kI/Á®ńÔëzŢZŻ»N¸(^LkÍhmÓž§ë ö 0 hÍţëŰw°űd)íeٱńÖóŁÜöÖĆźÔÍl¶}™éh}×sȧ(ç#Š3Ó‘)wĘ‘›ńö” |DźY.g®ű9n˘u ú®ÎíHc˙ÉDď™fôNťć+©ĂËőéyî´ÍědďŕĐß™|ąSsë>d'›» ˛-ńž¦›´×˘Ůę‹bŘďŃ ˝;=1±ç"ߤ´~#cíĺtVsýw´!«žh/Ęé(ć=ű'‘ʎ'jîŃ˝ŰŮ«é˝qŐ®Ść+z­˙GĺwËśËęęÍmď%÷šŮ~Ö~]®5Îě:Oç)ö4Ł8{ńŽ|ăĹ7ŇĽě˙ťWöEš­]ŮE×xľ5v·Ć‰Ĺ,Ň}˛9á«wXn'´µäŕ•r‘îĂůšYýŃĆľHoŻŹGi®Ç‡žçŞhĚŹ|ň„ć«qFq´ó¦Qš6^Ôlëlµif9pYďEÍ#ćÄ-š{|ş×µŐç.jľ:/ž©Ůćߏţ«ú[ăéĎ˝ľµ>Ąąî/+iŢĚ1JłŐšŐŽ´ŮzFĹůÇÎśću šKRSĎĽĹaHŚÍu[YŁr­ylí™gÔ~FsoÎ2ÍÔŁpÚčµýĘüůaÄs$Ň<*V­c+gőŽÔ<ô™ÇhŽęĚćŐĐĽŢqěéŃť˝Ö–ŻŻ;ťŤcË,˝Ń5łňzç4Ź/íĎ öşČwŢy«{ŢܤWs¦ű]ŰC}“čť“Y›íፏ¬ťöÉô<2ťŮńéž_Kë}ËËçl߀ąq#ČţL>·ÄÖÓ}WN×0Íěo–ßĚW^}OÄxĺw6g˝r‘ć'b| ö ćĺ'ZG`ń}2Ć5­}ô+PžőUôîŘx±ÜE9őĺ™sË«ŘŘŮ\‡}|gŻ_Qk ŇÍúŞwż^9¶ ÔÇi Ůů“Y×~c\{ů …B!„Bqf_qß›–÷Ż•XťŢ®·Ö˝Úz6˘ÖŔtzëúlťtEÝl=żT˙đ­÷Ú˛'ź,˛Ů[×¶źŁ÷ذîa}Ĺ ińŢo±5ń§uGďb‘ľ¨Ş‹úŕf˘~ěez2ý–ż‰Ě>'/FĚ/,oĽ\żkĎl×Řęő]v}Źć[b]ŮÁúa‹f¦‡Ősw¬3ű&ťě=Ą§+S˙Ď5ł(řČj¶±Ťöţeęť™ă˝÷bT†ůˇ)®ŕžăÄţLLĽ\ďĘc`ÇčX{{cZâăĹ([——kł4·äuç+ľsý7‚‹¶EšGčžß ţv^ŃŤ®9Ô;HsćţÚb×ŐX3?ŽÔÜď˝}ö«Łĺ™靡9Ú†Ök2í0íŽ x{úFk®cŐ“ă_ ĐÜjŐŃŃ“4öW(ühŤµ§%[.ťăđž{{4Łël>dëöâ1ZsK z4÷ĆxTn_éĎwi¶ÚŻŢ«Zó­'o{5źtÖç®bÚ¸˘ą·LKnŹš“ěyÚŁ;“+WóÉúo„fëĎŃšëüĽśŰ¸ňŽ¦Öś)×ŰöšmýŮř÷ćŞÇó÷¬8_ťŁ ż]Îe[f fŰNëót1×öęFvü8 ŁÓ{/ŃăžśGu }v®4×í1zbuŐG§Ľ i«'N-÷úln ÍëcCĎ<˘7·mÓżGăŘÝj{Ëóň±=¦čÝüűÔ,Í™~0SóĚ×Y­=ybË@źM$ŁŮ;çŮťŃlý6e¬x¶z磹„ç7vÍzv±xůĚbťż+ľMŮüîŃ{Ę™'(ç#“ăQnŁ~kŹÇ4o±Ý,^u~ÚyŤŐühf”ÍŤ‹×'3}`ú\«“–ç,«%ňÇŠzwĽą!Ę}¤ą®ă´6ľ(h ßć0‹ł=żşÖ¤éeůű†Ř2n揷ke ]ź¦Q!„B!„­ˇ2o‡íŻ:¬ŮoŰi­Ó®{ľű.Ć{żÁöŁŔuđÉľ‡·ńööxZż¬¤ÝĆ˝‡BďqĽ÷;,7~úÄ“”-őNĆjdď1ĽśđĆŔ»pÇ's˝Ď°ůÁü„ę}Bwë>ö9[*{§n–“HŹŤ)ŰĂףůÖľ ěcńD}±eoËŤĂçŮ»Xdš™F¦;jköŔ^»hŚ‚r™\šk`WV?ŇĚîă^ť¬ýi±66·jöěfe3zgéîÍë¬Ý­×Ňqp-{‚zu÷\ ĎŹ˘jĂúąWoďő‘˙†ĺ·ÓÖ;Ż\sp ćqˇů|¦fĎĆČ~/>Łü7:·GÚwU3Şgč^+co«mžö^˙ˇŹŠőŐxxk?łŽ?¶ĐÜŰ~ëőĂb?@3;2šłşň˛Qźý<2·Łg|OłÍqt-*ĆŁűó(ÍHw‹fOű(Í-vdóőŞf¦wÄ˝jÄ8ÖâźVÍpŹüUŞ6XŚ"ŰzýőDn3ÍO»>¨¤ŤvŹŠńáÜ2ďb®äă(Ý_Ǩg öű›¶%ŻĎ¶7C3;®ÄĄG3«c¤ć?4´Ý˘ˇ×O»ľĚľŤ^Ľß]ŐĐă¦}ĺ8gűł×†ý{ĘşľcGOŚŃľ“Śn¶e–ć:—Fčőtdă~¨c4ŔŢŚVds«ftÍ)ł(qś™í¬odô2_˙Ô3;v3ű29ů jźďŘcŃbk¦füĆ4ßş—Ř…lóň“Ť ¨š'wblbv1Ý™1Áë?«ě•BqČćxkśźĐü…—›­÷žú;6çxZďĘO/†(ÇYLin,€˝wâQ¶“nO/ĘCůŐ(´·5·Qß]Rď7l@ď0ŕ{ž…°ď`2{l2ď¬V]÷ööż2 ö]ŽŤďĘďr˛1błďňĐ{ʧ÷Dz™ĆHł=/n„˝gŠĆ+¦Ő4Ăvî"i‹=ó‹ŐĚę;ůr2ě~äĺ$ËŚż¬`łAm;Q.D} ŇŚúĆĚXgú!ËCć[ŢŰoäő‘işI{‘ެŢ?ݡ;;·Ęč¨ółEsF÷P@ý#lmŐÖ=4Glµćˇů®WçŚůYo"Żř-“ßĂút§m{ŻúĎž›Ąy„Í#r‡Ć}fÖF«mčú^˙ťrşŚŤs”[]ń¸P—WßÝĆ®6zk$=uŽ|ÎŮ﬍#4Ó6i™Ź™5’–ś>}7@3ŠÍ{Gj¶vŤěĎ#ňr„ćş.ćšmÝ=6˛ĽĽRź­sĄąç¨8Łň34łşšŰWű‡µkčÚ·Ł÷Šć+ąŤt˙Ô9€:&ŁrűŠŢP÷(.ÚÇ4÷hórf´ć«zk[[ň&ĘŤ)zÍ=9şŰ—Ő]·áŤ{wÄ9ň˙¨ü¶ĺ˝÷Ü#5ŁvZď5ěúÖĽ®Ż·űFsŞßŘĐ›ŁŢő^.AŽĆÔoýÔ1’Ş~oŹSĘ®ržŹ]­otś˝ůđÍ­qf92r gö]±ł'¶¶.t~X¬/ęÍĨµ·Î$ěl±{ŞŢ›4·Ú>JďÝšQ»wÄŮk?†ôéNm‘ÝŃ<'«Ů꩹ņlśGä˛ý~”ćč¸K3Ó}8€ÖpŻĆŞ'ŻÓúG`ężj畺"_ŹŽó(ŰŻÄŮ˱źzk®ŰęÍďŢë¬6ú~h ć:>™µéYšYĽGj¶şGÄéŞf¦}( ţ+v¶÷ä>9´ß/3Ćm¦l” Oőa†í—™ąw¦¬-s:÷0uĽ[öą±˛Ě‡«čÝAk)Ví›Ńřż˛Ţ4Gşłýą®oE˝5YÝ޸˙ôřÜ‹9ÓüĆŘ2ŘłŐ÷ÖŘFآăS±Ú>Y«B!„B!„řť|úße;ŻáĽřć5Pô~–­m˙ˇË—ÖÄ&łoŚĹž˝Ď;ĽóXöĆę§ďŁ öóÓÓxÚĽwŤ‘f›ë§÷\aß7!˝^ě˝wt(7¬ďîŮkß7˘|f:ě{:ä3”3wíńrűds9k«5GąsŃřÄě¬c꽓ŹüuÚÇ1–Ó(ŹmĽ¬fo óŇ?]7°iöúˇç»Ěqjg޸Ĺrą>NóOrmŹîi±¶yş‘}˝šYÍŽuĆNĎöS\ŔgďşČ'Łc=%“őEľ–ßŔľÝ©Ül¬ îGŰďÔç+šQ]?ç1BoF÷•şöĎŁňŰ{.¶yÖźQÇťšŁů·çŁě5čoęĎ”ăáĺWO~·”Źžą‡ŤÝu}¦ŤŢlő•˝Ć^{°qćŚ -šłý?«vn÷j˝çlÜGiF{ŽŻjή˙1ťěüčq۶Óź«qö|>Ró€}˝1˙±­áš¨ž;4ŹŚŐŐ|Ů×cţ|É@{{ó#U×@Đ:üÍ=Ϧ¬lďŃšGč­5gŢo1?Ý©ůj|{sű  Ô5cý“ÝŻZlGĺ[üÇ®›ç? 6ěß.\Ëę9ĺţh{ł6łX·ä7˛cÖÚţ¨>Ťlfe=˝§÷!łhÔŘcöÓ=b#łą'Ć™śźťÓ'{FjŽüq×;čĚs ˛›i¶ő őzÜ„·˙ťËÄšiôtß˝ż‚͇&–=ůý”ޤ;űĎÓŚ|öd|-ŢšQ*Vä{Ö§źÖ»Ţ)Ł|Žt±Ü^)Ć5hŽĆbĹ™őů•ôî°˙™ĎoŐj±ëičYđS´ZĆOÖ+„B!„B!„ř<2ëąź˛ć뽿9h*ńş˙ęص{öŽ••cď¬V$zďŽŢ3Fľůúîônk¬ŢÝVď]rôŮŰŁó4ě=ű)7Áw,7\˝ĺáxŰPĚżČffż=_×eűřÓńÎěIŮ]Î:цÎÝoc ËUćŻË ÔÎť{Y|<=Q¬˝|AypWŽŁ{ŚŻH3ężŮăŽXŁ=",=łĺł×ĎŚ5‹ŻŰŚÝ—ő–9±f1föemoŃ–™€węŤqV·ýĹyt¬˝ůVO|ň‘ÔĺĆůííoË˝šYÁĽD«m»3ó/Ď‘†ç¸iú8a{­9l;™Ü‰»‡ÜśkÍqĂýđÚ°uŤŠ1ŰwśŤŻ-ÓšÓ'MäÚšŁőžŚÝ=ša:FkFu·ŚmLs‹ßP}pŢ?XsOŚŠ)Ëb”Ís/ţ3r›őmdŹgwfŽ“ÍíSÜGAÚĘćf&·ł9ăúa$Ä®–\?ĺ`âš–ś™5÷dţíŽKĂő^ťłź12ó§§tŹćj>ÖyŇzŻó|vČńÁ\‰ďŰ<ŰĐůŃ4čkŃ|ĺú™1ţC}Ěć«Ďá6Öu˝łâ˝ąÝšßÖłâŚćaWĆ!oN×ZÇě5îŚ}¨LKŚmţ˛ëďx/Ýł†Ĺ8ŠĄ—Ű·˝‹7íF¶eúcT†ůäîwt,?ŁśŤ4{ë§vo"ĘË(>¶ŚŐ”ŮgđÄţ/ÖQ^F}Őű´Ţoý$ÝËąL”׏î'Ůrű`Ľ8Ge`î,@ýĚ~x~/ŰÁn–×(Îč˝ď“9Ť@φHOKśm}+éÝi}GíÍłl™őÖ y9ĘqöŚĆé7€Ö‡Q˙Śôľ¶.ÎúëÓ÷ß‘°¸ŰçŇOĐj±qü¤¸ !„B!„B!„ř Ř;+»–m×÷߸Ţí˝Ł;i*ü]Ý´ł÷íŢ;©¨ěŞďë"Ű]żkFď¦W‰»·—‚édďÜ˝wń«Ä<Šmms1çQ9[†˝—~T÷wűžm…ě{[§7ľÝ ˛%Ú3ĺp¤wBlbąśŤł-}WĽŁ˝/žť^_ÎOÄÝkZú1ę§­~‚mϤ˛éĚäs‹źĽ6N>Ű«ÉŮV­-ýŕÍ,ž­1Ž|Ťő¬}8ŢľľÖül‰łďŮąícl±ŮĆŘë¬tn¤n4çŹôEßgňšéc{&Gćwö™)“ŻČÖTüśúfĹŮÇö"Gym˶čB×ÎĐü…·×:Šm”“čsä7[öçÜ@XîŇ\×cë;ť…Ó^dg壸eŽCNďźGÚ`1rˇGł—‡:‚öÚ·äw&Ćźy×ĚĐĚâórÁűî.Í-ë:žÍ™u‚hčÎw7Ů÷pŢw™qĚ›óŢýn’=GqF1Śň×ë#·lÉÄ'ĘíČOî±ěŠbśąŢw÷cZGČösŻ?3ÝOë݉îŐ˝šm™´Ö´ĚU:FŮĎ‹Áôf5{şWÔ[“˝wgÖW鿢۱ťŤÍoŃ»cm‡ýłśŹ7jµ ÝîçĹýÍyÜŇöÉz…B!„B!„BĽ“Ězý'¬éł÷THŰŰßă¸ďeJf5˘=á»ĺżŹ_-îŢ9űÎŮľF{JĐžś•bÎöö°=čť;ŠµŐ»Ę^d+Ëq¤í?ČîżxL÷wűLŰ;–Ńlă_Ęůď»uł}pÖî¨o{c@”węŽĆfkł·ĺvímă9h×ĆŹŮË4÷řꮹ‹—Óµ-Č^/?Ř5‘onÉqÓłŹi¶÷§Öřz1źAfŻbĆn6iŃ}WŽGs­H3ŠsF/ŇŽr{J¬“Z˝s‡\4eí5¶ŹŰC$“‹VO6O™źŘx‰|5[3;ĐĽ‹ŮĘÔŘ÷łs=ŰeňÚUřĺŠńÁ¦ŘyGä˙¬í‘ż2×l‹kvüÍĆ*ă;ć÷;r»ĺ~ăĺsKŚ˝zďĂ26í‡çłčZ–0îacr&Ţ({âěőŹYšŮZe&ÇŃ5YÍ)Ě€´Ťž‰˛ö¶\çižůŚÁ|ŚěńleyŢ’Ółóú‹ěóPä‡l~GZOĺfÚĚjöư«ů={Í “kQžfîS™ďöşžĐěĺdF·§ÉÓ|Ë ±Ăł-٧ĺZtÝťk€-±Žr3ňI”Ów¬őÖmˇüĚęaąíůĘ–»S3˛=Ň\—őüůâÔö X›Ľ8Gą™ÉmŰÎť9]“ť›xkEQaľ<€7ôbyŠUńő˘wCOiţµŁř1ĘÄ}˙Df°uęLÎF1fĎ­OkţÂÓZóžŤU«h­©ugž=ͨ̊šżđć)™ţĹzeŘÚ=Ő’)óŘ˝ŽGűč-Zk˘w5VóĘăU+Ţz©ű>Ao Šĺ§Ĺ—qĐV¶W÷_!„B!„B!„BĽ—ě{™·żĂńŢŻÚw4ôlyŹöhź{'ÉöT¬¬=ÚWŢ»G{h Ź |ŻZ¶“Đ~Ď?§ý’Úńý7Ű[‘é+íą`űŁPޞ~ĘâlŹbţ}*בý6^ž”÷޵0nÄËef·ý7«Ůę~"Ď˝˝_-ńÎîť‹úÇ-şťQÜXN´\||G¬Łý}™řfň!Šą­k¦nďžűő]ÖvoŻ'»Îö…“'ŔîG(fQ®˛=‘,®QĽgkFąŮŠ®‰ú†×ÝS8»_•iÍÎM<ý¬śwn¶ćčČÄ73n{ů„|=Ssëřcmgţk©Ăćͬ±»ÇN/.™ÉäĚĎ1bsmOK¬łšYlgk¶ąÝ:§4·\ŹÎß‘ŰQ]µćhľíi¶×Üq>´ŐhsO¬Q.ďóľźş&€bseŢÜg{śžß'iFţfąžŤWŻîS?™hݶ7ňĂÉÎÇőŘO&ÝŁGjö4ZßĎ$Ółš[ű€[n"QŽy±¶ßeuGľ˝cťÄ®ŮGýĎł5z—áůňPÇdZút¶ŹzšĂ>rčÝLKnfűi”w®ëGšł1l}Ź|rçşľ§;ÓG˝1aµĽŢńž˝8ťl.Ť!»öîřÖdÇćHWÔß­/źÔüE¤ŰËÝĚs8Ň˙¤ŢôLčŤ?^ţFľYAďh<ňĆ –ܶs U4ŃşŚ4żEk š—öj^eĽĘ‚4łXf4ż6_AąËňáMzk&ÔWášč‹Ańdş?AoM¤óÓôÖXmź®W!„B!„B!„B<|ż”yăű«Ăź˛Ţ»Ű÷ËhßÍ›tł÷čűßV3Űgäůh2ű$Řţ ¤ł.·â»i¶oÄÚîée{h¨$»ÎîŤňö™ŰŢAű`C6O¬îdćÉY»Ńs§§‘ŐqđÁšł¶ZÍQn{őÍľG{óLśmn·öÖÎě8łx¶jnŐZÇőIÍ˝v÷ę·ýâ”7@}Ůi°Z[çŢVűÝóíěóŁŐÚ{ĎC9}—foŤÄŰѵͨ/ĚÎëťČÖ(öHwöYâIÍ-ýŐë‡Qn#}°ŹLĆĆ%˛+·VßY˙Ý÷¬aó;´7(cż?µy#Y{Ů==ó]{çŕŢŘcmlŤ1ËkëË•4GýŐڝɔwęýÂ{.ĘöeVÎËý/Ŕ›—0{ł÷e6Ď}*Ć5)ŰŔw,oYźŞSĘŽUŮXzăÂ2zwĘv°?3FE}Âúm)˝[hÍíşO»qźš{ sž–ÚÖĚ=ËËŁ;Ćn«/ĘS/'˘8{ţz*Î6G[űcË5,Ż~lHÓŢq¨Eł-gý|—ćúčŃsĄŚŐzŰsF9Ž?=z®Üól=wÍ·‘ćÍQü˛ÚŘuO!ż­¨·ć—˛ÁüÎh~ޤ™éAcőę9íQë˛_ŢŞµĆÓj5‚ŢšŚöOŇ»óŰôÖü6˝B!„B!„B!„B!.R¶Ó~¸·Í”{ăűh»WÄî‰Bű‘o–Ý˙Wí ‚űdĘyŻÝK¶ž>´/ů„í\QwfżĘc«‡í‹;}^€hŻ*ÚăhýÄö@®¨őËZÓů Ťw§qńиŚb‹ň9ÓźY˙~2Öv/'ęŻ^ülGš­˙îÖÍběinůő”ówÝměĽ2¨¬ő©ŐüDź¦{ Ź˝ŐěŤŃ8öÄütżźZ=µť,źŮXĺů)ŻË}š3öfâÜ2nˇşîŚs”»›#ͨ~[ćIÍh b>ČĆŮÖçŢnÝ‹Ł~Č43Ý›ůů÷nÍu~µä(ËOĘé§4gúoonGuęąú>‘ŤkŻf”űőOŚa蜍}ëz«ăî9 ‹sf|ĘčÍří Í6çZbݢŮÖ˝‚fŰO=ͨ¬őÓúÔ\ű‡Ę>d[ÔOłšéłŰ|·źŐĚô"ż°>đ´föüś‰sf]ŐőD?¶°uŻ(ލ Ę‹Ąňz;Ż üec»·–Â4?:vUDş3}iD城±őą–~ĘâŚb˝ ,Î-c“íŰ+ëýÂŽ5Qś˝ľnˬЇ§”XOVóĘŘ1Íćj&·í8ýn¦ÉÓú&Í_DšŮ÷oÔj±1CÇ'é­Éh˙$˝5Hß'ëÝaš…B!„B!„B!„Bń™˝űž’zÉßÁŰ=2']Uąp?Ő(Ţ T@ĚżËy{BWÖÍödŁ˝`H»Ý¸ú~"3¶ÇůůhEÝČöŻsµn¤·öę×Čo+čfűYmlw]hŚFűz˝ţý4Ěv{ŽőUO'Óţ¤n61?D>AeWÓÍĆ]OŻ7®ŮďŁý°O@můţ;Š“ťŻěß{ăö“c8ş×°±Éöe/Î,Oţ»aýŃżX˙o=ľ˝‘ČfćŹ(lŮUƱh>‘ŃîÝźY=vžó„ćẕöÖńĚčMçryN3XłÜŽr7Ę›§4Ű8fűućY2ňÇąťŃËúlë¸më¸{ÜŽîÁŢąŢţĚęxâ~•é,/Ůxż‘ăÉÜţÂ{žbýÔjČ–cq~ď2ŁĂ›ËEq_aţéőS+/ά¬íĂŹ®»zútĆ?KčÝÎăP¤ąĄ/ł>ł‚fö\E3+żJśŃó}6·mٞ+ĺőާŰę‰Ę ¸Ż¨ů ÖŻkŰ3ăňĂŠzwĐ3e?OóÉ? RŹ3Öno,Fcöôî ń;s˙y«ŢOłí§¨Ć„ŤĺQśßcËi.Q6č8·y1HOt|żI«éűtÍ;HłB!„B!„B!„B!Äo#łO†íń|h_Ű?ĂöĂ˝eź Ť™ýĽ}ÁöĘ­s¶—±Ţż{Š·)ó¦˝ĚŃ^Îbľł{Öm|íţću#űkŰíľ]oź~´ź{2ń˛ÚQ°˛«i®ó”ĹŽK…kµ~<cű&ÓŤĺ(VÝ í)qżÎřÉ׵ý´_’r©±ŕ!Řý(Š­7Ćy}|Ý6÷ěXëŤÁŃćéJ3Ó덿h\Cţ`>9ÝnÝwěßűgk{ůŽůˇî'wÂúe4NŐöFýÖ›Ë=©ŮËkŻ_Ű9JöÚRžŃű‹qÔo˝óŢQűŕ©ţüš˛Úr˝š×?…µŁřcʬżěyXţA2Ďͬ/guĂ6$š{˛üŚćb¶˙ÚëV™Fë,_˝ň¶?<­÷‹ěši@9í=g­ ů‹H3ëÓQ cŔD±öbÉĆ-–×+Ćb–ŰL·Wn5˝;Ý^~SŚwPŽŁ1ú ŁÚĎ‹ĂćŢřŚîGoŃűŤUŮ`ěíą·é­Ů5yš‘oŢŞw‡őńđÜËAşQżý˝;žĆOÔ[cő}şŢ«ńÓő !„B!„B!„B!„Bń±{áŘ÷oß7Ĺö¸žôٵŻ{ h'ÝŹ]ČţtV~Aě^ôÝn¦«]»rĚö•ăţtű¦Ůţ6aĺ>Žöj#-‘fäUu3Íp/z‰5ł˝ű+a5Eż)±c´í«˙6#Ú‹Ďú3Š9»vµ1<˛?ÓźŃXŤ®]MłŐ‰îCőáőc4ŽýhÔ/w˝Xך=ˇ:žŽµÍĺ–¸Y}h¬¶×¬Đ§ŃŚâŤĆ0ŰŚžÔĚô˘qĹ*ŇĚ|¸Šf/NH‹›™f–#OébóĐŚfšë ŕĹ»ÖçťËäůÓy˝ć`¬_˛8ŁďŮř°‚ć/ŘÜÓÓź™wŁůöĘš˝qŘjÍäÂJzwĽç‰Ăx Î3߬śŰ_x÷j«ĎÓËúűjzżČôe¦)ú~ĹÁĆ$g¤™]ł˘ŢO7[đĆ­źĎ/éîŃĽr|-(Ţžf6>żEďśK” Ć~ő{R žnďÜ'Ŕć«Î+GňŰôî Ťź¬W!„B!„B!„B!„B!„ř”ęx1űžÝÓžĺšBöö–î‰,ܧ}ŇQ•CżÉx‹nö»Ŕ“Ž‚Ëٲ«ëfżĄóöŞ×>aż;ZU·÷oĎľőË›bmőŘϧ¸•í¤“ý~á šQŽ»ăZůK3ŞcEÝLg}XűmżEyP_»˘f3OęĎ…\żşćZ›ýŰŽĹÖ'h̶9ż6_‘~¦ŮŽ]^?_oĚBzŃy6έú›$toňć&h cÇꚣ±×ęfýĺüjšYźőbťŃ|ęß‹˝/{ýÜꤹ±Q.#ÍřÎĆö”3 Í5ćĚ5+Ž_5QŽŁ~ŽŽ·jf‡7GőüłŞć/"ÍV;Ęé7éýĹ:“ßvüz‹Ţ/иäŽĂŐy¦ů ĐyrÁšíýéMZkĐ<ęÓoŚŻ…ĹšůâÍZ-î3ayl§¸Vç?ťOŚg†ßŞ[!„B!„B!„B!„B!„B¬Ăá÷EÎ÷§=üo¤ś«%ü˝Ć‹đ~kÁĘŐż}[ĽŮoěoŘďemĽWÇűÝ ú}śý}ýťĘ ţéţ^¬đľü&ÍH+űÝ -~cW˙feEô™ĺóÇʱ®ő0ÍŢď%íńŠűVŮ:ě=ŤĎČ/pĽ[•r¶™Ć­řß2Ž![mľ2ÍőŘ~“”÷kFą]ë}[fs’Hł7Ž˝EłĂŕ˝§`ŤÔG‹‚î?v,óĆ1Ö§W×Ü2c÷h4†/Má}éEúßăd»ŐŔ4ľQďtNQ¶´î×ätEǬć·áĹóú0"›ßőąO zf€c÷ŕ=#}’NŹß Q!„B!„B!„B!„B!„B!„Ać·Ű‡ß8—ďăĄxż=ůˇl§ßĐľů7č÷˘§ß•ă÷Żú]¨Áű}3üÝMů€X˙·Ŕ¶Óü*ÝĄď7ßö»7ŤgµFÖ§Ýţ^˙ý ޱ§ę߆˛ß‡ż†˛bĆběĹ÷mýéň4ĂűTů ÍV‹óűłŤŇěőů7ögű»f6×BcŘ[ălí®uŁ~KÇőrŤÉŢ=úíšQÜ3Ç›@ýŐŐľ#Mń,Űkç"5-š?!Ć;‘¦OŇjaş>Q«B!„B!„B!„B!„B!„B!„¡lü·˝ĺÝż …sTĐß»ż™˛~ÇŽ4Âď€đYó=ű<Ľ–âkţ´8Łß±ÓßKđ˙xx!ě˙Oażgżý~#‘溌ýÝěŰ5Űß±ł2źç/ďű·kf1Deŕ˙ĎäĄD˙Ż‚OÓűű˙(ź÷˙5°ă1Ňô©šŃ}č˙__dúô'éÝńô|Â\„áiB!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„B!„­ü?=/˘¤•nipype-0.11.0/nipype/testing/data/segmentation1.nii.gz000066400000000000000000000637011257611314500227010ustar00rootroot00000000000000‹ňĐ+T˙segmentation.niií˝Ů$Á‘l‡ĺ‡şđ‹đđťĂ/ę@(ɢѮ™{äąTă 1ŔDNwf,nnćQY™…ć˙üë_>˙Ë˙ú—˙C˙Z˙wýí/˙“ţű˙ö—żü·˙¶ýĄż˙ű˙ďéŃ˙ĽŢßvÔ{ť˙ý˙Q ˙ď6ÉGŹußc˙M5)ţxü_˙ó˙rX˝ĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–Ë ţú׏˙ ]UŽâ Ößţ¶˙ź¸zŻř ţ„†˛HÓ4ď7ęüĺ/ÝŽă]«"ţSąű,ŔýťWÔ;ś›ăßµ4śęü‚wŘ­×™Ţ w’ c1÷fŮĽ4˙°Ő¦äÜ*Aî˙?ĺx/ř·˝u±0Ş˙!đ%ç—rë÷Uvň żđ¬ĺŔr`9°X,–ËĺŔrŕßÜ^v%ú%i×l^^L<đ“ćÝq«Yď”#ä¶aš:lކoA=1x„:˙¶w˘ă÷×Ý+wk0kNűČI»Řč_;ţ¶ ?쇱»z?1ď4ć—ŠĂŔžfŇ>Äž™'ń‡ˇ=ŘŽí‘łŽŠ®şcüfÂ,ú:v\ŁZĽkŘÍHˇŁ8ť›ČÉpýαO‚î†řď›ů.r:>Ę®Ć4čf°±ąţíďoźCéÖ>î’~ýŇٰ_˘Ď1…>ěý1öö–i§”«»X,–ËĺŔr`9°Xüŕ)}ż=đ÷kQÁűµn¤»o‘!ţŤ Ţby/ĽGe¦^š;ofŰë÷+¸BŤV°®ří׊-R0·µą÷4‘~Ŕ>‚÷XˇŽšIóÄ|÷Oűx‹Jkç/ńĎĚ fśwŕŚ=1˙ĺ¨ËF"ŹXýó›Ăqż`5=ĐE:¸ßˇDßÓBý7ěřĄ!ţ U\‘íöŘćţŰßţnýďĆCrŃ…>˘_?É{° űŔ"č÷=łŠP*řůh8˙ççCÜBÄ1úϰáý#Ú?Pş ËĺŔr`9°X,–Ë‚ţ¸[ŹÚhÎűgőAęěW@_y»ú‚ĐBo/ÁďřŽ­¨Î+Ą_N_Ř÷ˇ(Ýa?˘7¬Ë„Óx"KůüD=›ß*©XP—Ý'–ĽOEĽ;ď+Ác;ś^ÚĂĚU“čĽR%KíđbíşĎŘ+zŞőPp¦†Gµ·ţ>č_ˇ č°·Şó´·i_Š |xęlĚZ ? ÖĐ÷ÁÓ?T©/cň­±uű 3ć°żŽÉ—Ć3Ú/Ýôˇh­ü÷_Z„ä—ALklN»ôĎÍÁ˙4Ł™+˝wć·•.Ę.vËaŕľó×ËgOµoĚ÷I×Ěr`9°X,–ËĺŔż·<ŞB?Цů©ŢŔŚŘŹpęÄ›QżM~WđHŃX]_|‘_ÇPý} 5ý,ňÓöXS™•ç|`)ôqě| ®÷×–ßîÁ»@7nŐwč±đ5R?s8ářL<Ŕý# w૱©zDýşçW’ŠňeWt ßbĎż’x­¤T¸żóv‡Ě{Ó±úřĆ56fZYnÚO[łłň¦nt:×ĚŻęęCžzĹ\Ž»÷~ÔR^í/'Ç?Ţî™ř+łnU­uw=ÔußŮýš´űńÄĎí‘?Ú ;Xš·§V‘{+XöSá˝ëHęŮ'nŇPłxŔúě˝Rąv4aa ´ŽZđ{ â¬®6÷Ě+f N×XjÝMŽ ŮMś›Ô‹Őűń“u?>k }V6űţŘŤŤWŘr`9°X,–ËĺŔ:'˝zŢăÂń-WbëÜox­ď»đNáŤ÷¶şÚ€# ĆNm•׫˘4Čm¶7»Í߆/-ŔEłs‡lÚäţTî†ĎhcŁr7Ő˘_¨Ék‡ßJ &ë.ç¬Iá'q¦tŇŕ0vBzNp>䇸:˙ľB—ËĺŔr`9°XüË:ஜĆĂäáˇîˇ˛~ÄőłS?ü˝<9v:ÂęŕQ°Űľľ<ť‚[EżĂ>ŁD~Oa¤^aŐzB‡xÄÚ5ŁÇPWw˝–č ®ňőŘ=u"»@ uřÍĐí[°T*€7ČÄmç |ű´ž_UÜŕäóČ»Vë1ťC5¤D{ôťî¸S‘ÍÔČ–s¦ĘÓöŃUË˝lEW¬qŮaŤÎĐ Ř˙ ¦#U={dÇíćTăšçMżëmt~Ŕ^›ĘD$ËÖFÄ3”Yä°ńJ€wlżĹ†xńkrI/L řČK~e”2ü=˙%©ŹĽő"‹ĹĐ×/%Ü‚¶¸ô¶¶WČţćż9č­¦qźÜ.Ů˝`ÁFĎCáÉďŕÓ©+y 7‚•Ťě]Ä0ÁĚ{¦}R•‚Aw`'Ż­ ¦8h6RÜ7Ě„lq[cÜ Xş;ěńź–í˘Hʢ9Ĺn|KO«ÔYÁn¦†#ýŃď°•SsLď'Îmłś §Ďçřcźěiŕśö‘8›áöýE Ž<×ŢnŹ“°GŔę-–ËĺŔr`9°řŕÁ¤ž=ýř5žC_óň0ĹĽšî˝Ç#dˇ70ÉŢŕűč~p#‘Źô[Đ<.üŘŠwů<+óđ¸™8—_ y.BCF“€ s FŰçžd~N7Xč;đŔ^Á]öýŰMxtÎ;Awééčî uM'–÷Oú­pŔÁ…TŁ_#OŕŰ2]DŤ2öŘQc,Čř xăĚcČ#· Íě ®·ŃÝÁ7Ş5ěéÂłŁ8:ť_onyťÓł“h‰!ÍťY›äôű°­7°ßŃšjż‰wňĐěJ7Řk€Ăh1—řü`qxę4µÍę_Yžű9ŔýŻ`¤ŔÝËżŘömG÷ro? =/˛gĂŁsˇéë&Ămćéćë i‹·Ń,Yţpű>¸×¸µ{aučŃ“7âkžÝ10ŐČ”÷ÍFvh±™Ćć2Ů 5Č ‰ČÖ ´Á5: Iz LPŔ[Nůč|ß&-ŻŽŠ=Äl`Ň »Në;ÇŔIBŽ]ř±éęw@ŻĐNp8v¬řš_#€•á~ě!ěŕVOkđÉ®„Ý`uo<ŰŘi×u9°X,–ËĺŔy&ňÓu===iDřČ6<ÔŤc÷@yßwöńyJÎű¸Y[!;x7uuó™=AäaŃŁpö1ăë±­®Ç“l”Ź5ü”ę§SÍsľv…î~+ôc/we3—řnó°[‡őś)«żĽKÔh2ŢG”G°LČŘGp–¶d;?‹ŘřCÇ#KJú¬Á{fîš÷˛YýpýLŇhv'ď;IÖBî°ÇYúŤ}T!˙îvHeĚn6 ĚŁ uo%·Ë+p¤nťŽy¸B «t[š »)ąd6'ŕťÖĺďžšx4ł<xçz_ŕŕE ±ţ_G‹YÉ_ŕÖ¦PG"\ČQ0Ëü ޵壤"í8°@‡Í×ež Ó˝@ ą‘`{í¦čmš•. ĺ«Ä2§2ů»‡ňĂ>Ľüq‹őżďx“)Ş’÷¸ŞŐCŔäŹl~ ŃuĚUçéĹňV'5ŢYďeç^`áBďÄm`gÝÍěš-ĐÂwăqŁËŮOěۨŤ©ü{bEh@Ł“‰=Ř,¦Ŕ¸˝?µťćYOńÇ®Ł&éáVÚcđçžł~Žţěú/VÂ?$ű_ü/¶DKîr`9°ř—v€çż@ë§/Žz “g=`}óBČ RX_>ŕ×ÜéuŠ7xÇŐő@}óś> :aG=ţÄÝ1} q?jól8h.ŤĆđŚÉ3¨±yžĚĂú:Ř=#ÉD#óĘ $2¬˛ } Ó‡‰fZoĚ•ÝŘ‚ěóżen†ŔEďąçŕ݆ś×)v¨{É«Ţ-¸đ&-Dż 7řn›´č¬i-sżÍöäŘĽśÂ\ďľŐ)űî?›ĽÁŕxsějV{^qFŤmŮAŹiź°ýŠšđˇC˘îęí”ÖąSşKHGÝ_˝Bpg»ůuśrľ`óŹ,<ęućSÇ=á6C\/WđŚpl1—V&ĂŇËeńA˘ü‚é/“ –ČňŚOD6‹ NÝÝ•xćux÷ĂÄLô1ăÎäďÝaŃ"‚c*ž)'çś2·sTźo3€ŕ“bĂ©ĺ)É»+µ›)ËşÝŔ¶ĎHŇެs#;e;š5ž‰f;\ ŃŃ•›ŰżĐX6’ß0çwŁć.Ů|Î4ń´d‰€WEafńĹ‚žÁ±,ŕí'?áÉšańJÝu:D°ˇAUďâŹÍ0čĚpŻ'×vâ« H?¦¤'Ődî„×FOg€Îg¦ákđgžć%ÝÍ'čUÓ˙(řĎ•óü¦qµűÍv2»†–ËĺŔrŕ¨~ sĆ­őŤ@Ď]~ôŇH=]Ý>řť&~wîľ<üŕr9=>9ú¬XűÁó™\XCT‰ŇËĐ ™4Ś5zo-’Ýs›ŞëÚ]Ď=€]ŕ|Aű]~˘×C•<?áŇ 5yy¸AďÁy<–LŔ›źŔ;„›]Ś*›3k˘–uĎViý.áEV©čĺý‚ô75;6€ĐńéĐ_ëí„·–Ý×͟Ɨ¨GpbšřÎTď‡cQZĚ •ÓqšËî÷/TĽ™«#´o7Ě›ŔRas/™čů¸aÖp¸ššى ŢŢŐć)ŹîęśÝIÚ9b7yĆ0)ŔÉ -$@ ăT^aôśŢŢÄ!ІVu˝{H˘Ü“ĹŇpŠ“Ga67ž‡¦wEV“€č$.żÚi~ˇi¨žÁÄÖŻŽŠÖ¬`'ľ…u´?r@G]G # ׹ë‘éçď[Ĺl°o‘“¨ ü°ź&\ǡ±EŹĂßz˙ěżţýĎ ű¦oE-–Ëĺ@;Ŕ;w]·şÓÓ÷×>0VpÉvŞÄĚ©wh&%2’dDÜčöT7ćazżť2'/g/ö+éę,3pfí››N˛‚ş3ˇN\#\,ŘÖYu˝q,ŁSá~ 5Š:ĆAę‰c†KţńŹ:p.‰áĄĄÓąę¤çŚŇíçŻwIĐD4śÁŐz ¬(őúĚÉ1Y,çT¸™ˇ(¨®QRLe0X—5`Ť ČŞ® ˝%ŹĹČ€—Üö8%ťKöŹ™-°0} ˝‹ž­Žr pŽ+ŃyF'•ćîŔőKEnÔĹLO\ýÚ~«h´uË7dë`¸Ň^üŇ€óŹcůŔŔŻf <vnY·2Tb/ÇŚ8Ô–Öí¬ ­š˙ßÔł#…íx Şkj~!°#HśÂŐeĆ«}&GüOvôO»Ě\JDš)ç‡)™?óĄÚň•zęô5UˇrąNżŚFÁéöů@ađýř—v°‚«ř/ń‡?L|ꀶ翫&ŕ† úĎ÷§§A˙Čď$=Mş—ËĺŔrŕ´űď·żŮős[ĄČ7ôýĚAy?˛Ő÷:?|çi PnU‚ɤ3bÓŘÉ4ě‡`ž €çĎ+ÚŘM*ń»tĘ´':µw4‹1ďxo,#ž'Ý~HwęÝÖĽKŕ #M Ů­’z)ءmÁ2:ě¨ţ#7žyŽ:‚Ýe©Á¶k4¦Ż­zCxćx@;ż4Đ˙™p'ĚuÇŘÍhÚ6ĹĆXĐ‘·»ë«ŘîĆpóŞĘ3\ť*2Ů’ś9řÎŇ”Ž^ClĽ‚=ę*Ŕw”ÖĘg§h#>ʬT 2ÍËć™Z! ÇyĂ4yćµó™&ؤ®ÂůÁÁáü| .ŤŘż)hľą«OhýłŽžŇŔy‡zsYôˇ ßż“XĂW»[`L,24ŕ1ç8Ő\ţ T˙,Ĺ€ćtÉTř/`&IŃEłl ±çRŘy©ňßÖ°M%B{łŹĐ ˙/X˘ÔöNť†V?RtR}ř­âLm€ĹŁZ$đîGďÓ7Đŕ«ěúݍ$uq•đ`Q{M,LńFÖxŇÎUׯn^%Es+ý´d™€Qx.o‚öeś29ł ŘDŘ«őˇ"#›ěî—őZ.*ďD€ŐžXť•Ű…˛kp"gg;…NçTôoy;›I YZĚŽążbuv×űřÓLĐ ĹühÓ č®puż3řµÔCé68ä7_čÄľSŕxţ±ŇZN?c .×÷Ź;"ß—óµíĺţ#ŐT­C˙ĄÖ?(yúXűďW©Ç89őë¬Ţr`9°řç8Ŕ­łő˝ŐÍZřvě 7?s»&< ő—Öt‰.ú4é˝~ďŇńĐ=]_Č!ĐÚíB‹ŃwpĹŤFőé‘z ‰6}^=ŇŐůíčĚCí ’'p·!v-űp‡†¸yłďg~ŽöÜ>¸Ś'H¶śţLŃŠ=•€$f†çfhăµ(u§`‡]do`R9×íąý)°'«_q®Â ëČ]ŽŢ$6÷…zWîE:ąô‹‘®0b†űĐtEśĐh‰ťumčţí{îĉ—ĐÔ˛+ŁŇż Vwčžy‘,šě&ă˝áóŽ)Ť›ĘcĚęţ"ÚŮ\1]Şż»ŐBR«ĺ˙ŽŢ?Đ\±ë4·vm×­ąZËĺŔrŕ'řjŇŻÄ?a*Ř7lÝ˝ć¬űď÷4ţ†q€őťű î[nů¶›ŕČýҤ˘Ąţ›@üí´c$KFźŃĽ¨·&IŃp«čDbŤŔŠ˝ňD-,ĆlńÇ–SßqźYÝ)!ůXÁsÖ1JUst)>0mŮ4ëǢągĚCÄ ŠnźIđ]s<‚ě@4éó0ÓWá#qžżÇH?v¦çˇŮr)4˛ŠúDŻ®ć3xĄfCC”ŁrpaZ•â¬;íŢÝW?S LŠ3şŔ\ô§Ž˘UŻ[Ě ~˘¶¨ÎpAňÇËžS„Ż€Ű†12U)âČ\XBĐĺ ¤ţë Âŕ¸a˘sÓź/2ńˇV Ę(Ť¨kŘ“¦Ý)ž€ŹşÉuhCݰ>zkĐď±#¸”1 F—ćIßéęěŚŮĽČ™qäćç…0óĎ<Ütag»“ťi#ě?ěx$†í҉y›ńRřÍĽ]¸±&ť#[Z¶WܲÉ&1¶5'óş ™*ćŢ E<Ŕ;1ĆEů´ą˝W­ä’*ş”•zČÇď$jГ«ú* HĂliËĎŕŇlD b˛ěużĘ®¬;pQoÜş‚ywަ,— ĽX·q*Ůďü ˇ –\]M¤©nyę°ĚęxžfĘörFgëĐgpoÂŤ*#5Žć‘wFšŹĺNľ#ÇhYx&ćmH1ě43 J}eLHŔĘwçw§ ´8ËHLň–‹bD ;xšĚ%bBlpÄ~Îd0čV«Ĺ®nŠ‹đN”.˝0ţĂÂptŞę!ü›‡ ěc°Syž~()Wk;O§Ţôçš= 8ˇn`3ţ€®‚“ˇÄćvÚŘ'°É(»˘dťďVť8™ŞĆ.,śnŻ LXc»éN`¶7Ç V»$ôÔ˝Ý&P Űůd1řë»Qd›‘p#Űüif$ô÷˘9vÔĐ:ç˝]IF1ńr[ó /xSŔm™>'Á“Ó;ĺ–}3ň¦ą•פ*ýŽlQď,jmÔî*ˇÜZv#«ąXüÓřăŹ"7ľqŁŤOuÔ7Fŕî|Ľ)űŔr×ÓŤ(_ߪ(lľ_ĆS‰d|P™Üęů˛Rńćţvm•ő±}|¸sRsą+ţâz»ď 7HZľo«üĺ˙ŕó–ZîÚ‰{ʦ­…áűQŔJbŮRôŕxH˛ŞÎŁS¸­í÷Ëšň¦Ń}men…aÔ[8 ˝ĐĺáͤqNĐqv‹m„óN• çW\8}Řđv‚ŐŰÄŽVatéen´ň€mA“ÇOkSřjťS3ؤ¸P›…ä#•čěѡ¶´˛dwżNΤa2kHŹč*x‡.ęp· Í;ä.f‹6w‘]ŘLŇť€µŤîkÜ@·|8 QÓŘšÇ(ďěFŹůsŃÖřd7Hź…oX Ŕ "ęÜ Mש‰85ä°ľ! 팝α掬0%żuđO-śxÇ<—:¨ýoAŔ0ĆâpdŢś‹ěž˛q¨rF’ĺXsĺ ¤XŻk ›†#Ř˙µ›ĺç#p:ŘH!‚U8Ö\˙şˇČBT€I’ĂS'âzw¦(SSŤö‹n ťy*7 Ő”>Z>bhíŮŮęhHAÎîŽ΀hćuľbůJ76Úś¦fđŮ.d„~(rDNŕćôÜY4}âŁ} cDˇ×˙ ˘KĹŘę]_粏DÖěźÄÂ…=„;ÚÍ“z¦Ýšs™FâóČe龝ͱ^k,ŐZ„Dxxćtes˝…íĹnpç¸#Χĝ¦űÎw ¦dkFiÖk= Á'°°Łčá–óŕ–\¸›u0Vž!‚Ů70.Űť^%ĐÓß{fV¤?iyČ8ŻÝ8ˇ‹Íy’/+÷ÄĚG – %ʧö[ż4ńV˛'ŐB*ťkź§ ńĎî!{)ZäŹĘX:Ţx-îţC®Ţĺ/š#ˇ6V6TöÜŻđ^9M¶h˙ĄyśďAĆ˙”Ě@ß“ŻĺŔrŕGüüSá|Śë“Ěmě—›AAą}*o¦źáŤ›÷Qîź_jYÝ3…ĺfü;{)µVĘćóűÍ {8\©köm;Ł/ĘĎĽ…·ČëFcüµ^rá•ŐĐ|Űć|ŐX¶í 'ĄŕĂ=šÜ^™âcĄLkj4ÜŽFxËé,S„›Ws÷hł)>Ôa4s7܉ …ě.ŽEŐ wĹ´jÔÍ>ó,Ň|&ŹżawŤ2‚‰+ZvJgC¶S¨wĂW0Lč¨KéΓaź/Ô!b®Ŕh¸’d±˘ę„fă+P'k·Y ¬4µX< ¤ut”ݡvMžňéî‰m·‘¶¦8śř€.Î1kźRmŐěŸďĐ®ŞĐc‹Ťů”tdÖiË7]лаy5r·!š'5—űźÜŹŃ2óĽ ^·\Ňđ9ň•f;0{>sŠją`ÓaůJtweŰü–‰źImsłš+ H ®âżgf+ _@Ő6ÔYČšă´ą]Üđ¤bě š¬kŕçgď¨!·ó‡šjw–ńöf˛Gp’¨X'¸‚ĺ‚HÎ)Lśt9«ëe?ŘĺŽŃAńCš3őj$łs]‰K·§É›© 6`µ/%űe.[±Ôí3'FKČUu¨Ą+ął[Éhôq‡T¦ÉĆôIXŹ’|˘Ý|N @+ńH°LĎTó.F<ˇ¬?ˇYĽţ°Í±®şČ¤I6‹äwŘĽ˙Â]w;ă÷h T®Ő}¤y v[8T:Ü nt;Ň#Ň ¸Gu˝—dŠç6ó=¸~0hť Ü×ÜénÇŻRC*kł+šőšî/ze@RG+‰˙wÄޡŽ-şwkGľ{löةïdO`ďÇVşfůlˇ',·]fpʨĎĚ Ç]&ôM ±Ś?ß®'2ŠÄ)*ľk%&Á“!đ,čtő0$0)ŚüşeýŞvC¬Ör`90u źĹéÔë XÝEů<Ţ˙‡=ó,†×_n‰ľ ÍCĎŁĺź› ÚçŔI"?…Ďw2*ĐńŽć¦ĺzKíx”Ôŕş±áĎý×5CýřM•o:‹t•ţňŚŇ1)s yu‰Î_ô,­'Ó„E\Ő°ńş2ěăA¸™Jĺ^(#]»‡‡ČsĂ_p!0ą–)_îEMĘ[Ă#2ÄĐđŤĂV-{ôÜ ýĺ䢳#Ťĺ ‹ĂĹ>E'¬U+>µµË2ňś«Ą 3do§.Y祚+šśťŢ…ÂśJ(›©:]ÁĆšĐVM ŻQ'fâLíě¸rÁŚlşĺÍŘ…E—# ĆąĐqĂC'4c1$ L_ b¦çéjśÁđZ-sZ±ńčäJ¬z í© ”ˇývć]îÓ{ăĺż"č}tÚĂĎ’GÝčÜTđČĺůh:ů= ćt.먋Z$÷N‡ĹĘŚą‹¶ĂTF~â.eÎr N†Á‘$äT9ŻĚšA„ůݶ×n°Ŕץ"é.ÎmN‡AśÖ™˙"G°űPłoů¬…lÇ’ýráE!ÆßI!;°ř/lIĎsvŚNńŮń{đ±d™gŃ˝Ş¦ŰMŞŇAćsÉ€!ČĆhę1.·+XŔDź·—<0Ză(Ńěa•ÝaŮEĂĄö&3ŰÓWđ¦X‘áv#0c›ú &Ň Ě,H÷“Âě‘rĹf©6ĽrZeßÇçפ€6÷qL¸¬˛•ŘžVâŃ«®f˘5¦Hç÷α—†uÖžĽ€YĚ޲ÂF“E¶G™cW«¨Ér#» `ĄÝéë=ř7ř8ôŔ| 6µ4ď=xĺPc±iâÝťěÜ‹:6{u‡Ť’»ĄŇgÚK¸:Ţ5ť¬–úĆl ďx‹ęŚI<ÍŰ 6Ŕ•±Ą%ď‰ýDÄf*©pqˇ°yžň&łaŐ̧ć ·Ŕö*ö ę'ŃNk‹}5ź„ŁáÉ«ť A±9`p:>B‹ż0¨ý wGÝúU#*^K=CW9°¸:ŕbßŕűTqńĚ·´ďxß{tëŢ÷Ü Żň&#ő}K'‹đ?BźÄž‡ŔVî]Uw´sěą/§P›’•…~Ă_щop‰¦vp¦:ö˝DDň·|)/÷ßµTĐ:OűˇěÂ:ÜĆ6·.·Ďůš«8‡\żĄvpsXlŤ j=Úz»%Mˇ~ &[tKő-š™Š Vîúo <ľUŘD ł;sq%SÇwرČ0§–ŘhćYŮÖܲ㖱$µ‰ĺ¤şáŠq^Ű}Öő.†Íă´Qa¶‹ĎDýä°ˇľ03Üę¬Á$ŚNOh˘ÚMP^¨^}çvŘٲ\󯿢´eŚŞďeK4~¨Zć#®'HD;çx&ň6uŠ®,Í‹Ś-ł'Oş'®ł©X˝kQű(;ŮMm•đúďaŹ9‰N'ŮCX¤»ëĐT\Łşxp¶´3z?°Äe7ŐŽBCő±Ři1<kŞ#Ńç]Ň™˛ěÖ/ĎńS«Çŕ\X¶ ;ŕlEŠîř šŤPŰçzőDdŢ‚ĹęLÇeV Q$™Evť™„ťj®_–nÁµ#§=bfć­{T‹˘/ÜWÔ™¸ü.‚çě8ŮÚj_Á(Îś3Čó\ÁŹV¤MŔBÖşv,#q¨ř~xĹÖ»pµBGżséę[Ë8čJŃ`ąFŽ[°˙Ť•Ç'®ˇđ=VŹk†ŽĐëZ:žŔě|'0Źe+­”É}ü8ŽúáU.ó0Ú}ö¬ÔŤřCC˘L°[ɦ〠TG‹č>y56â ´E*4Ě»!ĆŃqm»HxtěFÔśll'Ď.”ŽŽ9e®SŕÁChʏ«ÚqsxĹ”±‡˝iXĆ˝] cb˝[§­jď ťšťţ©ĐC ]ąě›nC}ľtöŕÓ VÉ7td$ź†/T“‚aB'*t"ă$r:ÔÚëúŇé ‚¬.SŠ÷Áďrßs­ĺŔżş|Žë¶ăO×÷z¸pűÔťDJn)źďy 8÷Ú·ßMˇ…ާ)ßKhYĹ!pŇŃ­–H ®şnhô_µ÷mb3+Cr)Ů„ë0D¤í2Ř·^çaříŽäŻ‹+K I¦Ý6«±–]´şŕŔ“pĚâ0­4“Á‡Á± ¶ďésľW.Ńęďeë~߬Cómsß=“XóĚÚô˛CźÄsÓ;¨fawŻÜťvVöž8ňŢç3~Fݢ±l“٤=,ťÍÔ‚+ęNśxŻÎî(Đ’›y÷cĹeµV)\=ÉšYdţßĚ`–ńłeý†ŔĽ&•ÜOřĚŔ±ht€­8ő¨9üQĂ“á> ß ™U`Ŕ5ˇNaąś¨÷»ËńM ÷Čŕܢś·l±l„«ôí®Fî“ědßR8Äv—aeXÇŚ˝6ąĘkp9ŚĽ‚Ť=3x˝0wÜĆ‹ nZ_Ă}’ťA«Á0kŤÁý# o[0šd,ć@_Ŕ Jt«096ôq{Öď$gÇ·ľŐ MŠë}̲,łtšIeó¦ćraîĎ™°ű8‹äźJ®źIü)ÚˇÇýOŔB[á™ŮŠ]ă0ĽVٍ/Şý.čĄqmĆĐÍG‚:}b ö§¨ô.°őšŹŘĄdżŠ@´Őä>„ö1ę|p^dF\ÔŹnVŠîŐkěµ? ˇÓ–h);íg«ÝŘ:í¬r¤Oę™č0# ¨ÜňşO¤żnŻ0gŽy·ý‘V „ÜĘ6ĐĚ»[măá\¶>Ó>Ra¤;ĎđôxDŞCű>C7˛/߲v·ww€BOKć~€®ŤŞí­uoýRF×´•+ Đh>±7%{Ą]Á’P[Ň˝ )ŰŤj¨‰Í`tŔśLÎú„Íö®˛Ťm°ď>Ęő@lá!.îű†/č#VhĄ@ČîĽaUw“ą|“ óÂ+ §ä"®ć˝Ď‡Đ:ÄU­/Š· ŕtÄ‚oz7đÖ"Ĺ:–Ë8Ŕg±>?~4„ä.Äť4wÔ~dÉ­G ĚîŰĐWöĐ„˝żś•éĂçZ´%JX‚ÚŻűÁ’ëŽ)rť|ďÔQ @Ń`+‘ű/ÔĘXěfĹŇ!ŮsŐűP˘Q˝ß=XŃWlUňŕ~2m/ŢřľAź”Źo5¦Š˝nę>SXă›Úť›Őf®„‡ŽOĆ®¤đw¶`ÄşrH#nź…OŔ²›Z|aľ€'ÔVśżX1M˛IHł¦tEgŘ‘BDŕ %ËSÉs.Ąf_š8µ@üŚM>LL°L 'ęč43ŕX6ŘíŮ]3çMj®ŞĘ`ň”Ľj2۶·µŐŚ­%}©K&źQˇă ĐVźŐ>Ąü)şđE S>UŢcq¨Ŕ•Gâuć$ţÎ`GU $ď¬hŮqdŢ‘&łĄŕSJĽ<‚í)QĂ8Đű¬XN`E Ö-sŘmgíĽçĄň2x'Öť 0ćđń [O¨ć ćB¶3ˇY †#–עđv´{€ ]łđź÷6_ĂF@Čľ13„Éqf6ÉÎ.G°é;÷ÉleŞý•%UBJ„t•nę>ůĺ÷O#OC¬Ď˘ŃTäa—•5ÓŃîęI˘®eŔ8.Ä€,ŔćAť‹°ł_yź"ŞŠ3…?UöśĺMŔyĽ2ëBD 1^q܉V¤éxgÖ›÷_§¶ŐŠÂ°PWážť#[˛:Ř8aŚ®lhşîMŰpSK2×ęËH{őZ#â$´˘łŔŔŇtRk»YXšÓăúyL23îfŰĐľ| |‰ciÇMÓUvѨÁmýĘRLKÖŕYfÜŰYż;0k*b倞Tí}†řÜÝaąH °:q;×{¬—ş1şňą¸%=?—–0?BB˙6EHŰziÜ›5Ь?‚®& ¶í¬’Ý.E‡ýú ą0#×סě˝T˙żí~3j–Ąńx]cËOüČGâ×Fß>ôYôçú‡Ďd ú†őm@7ľ9Üwn^Rďű‰ľ ÍŁŘşňxbÇ}κ͛ϷŃ#c7kë η[•]ˇg€ÝŢ6Ô·MČ“ ÷v‘×&4Íć®ĂÝ+dŚ4©¨Ę_ŽWô#öŇph˘ĽÖ†çÔŇo•g7pÁFJwuç›ĹŇů†C-č¦/w`'ĚyLěţkhţ1 9äpd Ě‘@ľiŐ„Éă" ä?T·¶Ž®ą­Ç¬Q|¨kĹňů Íl›2.ĽÁU-XĄŕ© fRŮEx3€ÖÇĐň FŘmË_÷¸9efĐÖędbFÇL7ňú@ě@›TA¦{˛Ěę -°ZĹM4•ů>Ž` e|źß5GQJRGËjAJ» Ą‚ű¬Ď`oµ˛ ¬úđqź(Ŕ„ä9×ëëi“â  LżŔŤń'Ů6Ób·ˇń°ähŕpG€HčîE»ň;1ç­]XžÁ$¨n&Ň»Cp¸śŹcü=Ęλ ??'č.ŰĚɦŕyBw׌µ™ŽŰłŢ©ŚVôVv5‚Ôjůg`ˇv%ÍŃÔéqľ‚‰aŢB@d¨.Y•_ŔÜĂÂe´Sé“™…s:(2ĂÉťĎČ`wŇŤ  Ě1q®ą~–Ů»]”?SNäňw´é:^š÷JĚ6Ńá3†ąęJFߊą¨fĄľŚ/fŃĄnáš`)şcL ©AìCýp E§Z˝Ń~Ălj‰W0(’…†yÝźa]łŁś»<ŃÂqŠujLÁc6şŤ»ś$` ćÇŠc°ýą Ý€m÷.¸ŻFRőÜl~0Ř*PŘ!ÇBnTźdaCeŰ8QĄ›®2•°#A~Ö†őĺkjc;ľ¶z2ąŽą[ÍÎ ţx—%ťňPĆ·|@H-h©ÎÄ#–şăRť”ФO´™3RMŽ+Öđ;6ä ůkł}ţÍ’Q8eĂŚqźhwÚĺ­Pđr zß_íĺŔmřDüŮG‚{€ocőŮţ% aß,uŐ˝€»Ę‡ű—Wj»úŇw¤/ËhÁ޶^‰r3|GK'gKŘýmŻŕÔj|ß;ť o¶)F± ×RŃë÷W¦ą}ź5”zuÔšQ‡ó< K ˘‰Ů`ÄřĐĐ=®Š+T{)wčŚ.,ŮÔ”fFŐÔß9:‹TŇ[°ş µ¬;ÓZ\â ő(› ö;j%Ŕ(ťXő#X3ÝÔ–ĂPaüÎĐy"ťţ\ŃYه[|¤ă–wJçą‚KěţÖâČl27MěÜáŠ(Cý#Kc‡ŠŞ‰°KŐrb?jŰ%ůĺíťDauÜąj—Ľő:&ČŔÖď$Iyµ,ň‚¤`HŐ$ËnäÄ|ü€ff&›áŚźŠqŻ´€r¤S~%éi©/z ÖčÜĐŕă%ďÉq zŢß3Ł2[ZJuc+1‡Mć]Čhvc•&49š‹âćÍ&Ő)˘‚{hô;ĺY¶ßaĂÓÂ…ő±‰V>i=ĘÎ °Ć™ÚAďŔt˝xg°«Űa˝Kđd¶ĽcÉ~±1tÄŠqu7 gŐý#‹ă…B+ĆSfÚž±ćKÉ;¦¸ÜNL űjŻý©dŔ Kdťůť¤€dWp4n°>ÜAŤĚ§O•_‰Hkp˘˘ĐË΀ɢÎIyŹ^Ëňɉ˛·«Śäµ§•ěôń¨dnŚÍŠž˝Šś0‰\î~§ŕÚµ€.ěř\eÜŁWâčĆĂËŃ}»ĎěŚZc§®á=ôzĎ'Y}°»aÖ=Űr’ýžŮ$0Ű&˘ŹÇ\µ?ŇÇ@Š8ŹĚU×&ŰłŹ74ő*Űd•©ĂłšxĽz7`hĘ.ă+úěŰ+˝ îEĹ߉f±Ř1Mj.Ůi<€ËđÄťŁj s+ĎXÝańž8J±F7ŘL:™ŘUĽ`A÷ÚÖ'2ĺłŔŻX»fŤč—nă۬ G±}€?Bă›°¦s>– =Â+˙rÇ@†u,–{ţđ3Á-$7}¬ľŢD €Ű˙Źy|GŃiŻč©íű–±ÜĆ”Â˙÷„sE µ@Ľ$UžńĐđ]KsŰôEXÓg‘C"nZŁdŐbŔJzĽv¸cú šzĹžgWšĎh/€˘˘ŢęaŔŁçöްâUKÜ*ÂąHót+mF4÷a1A |Ď × Ůŕ쬬ÝŐ(Ź@ÖMś13y[vś6z¦€˘ÖÜş QĘ]ňíĘfn¦ŰV4V`a Ö‰l÷čbÇdyÚÝÂ’î ŽfŘ~¸Ó›ś”Öb†«á Gpž‘Őc4ŮD}¦v S÷”¬ńě2CŻKťá Y§ymV Č~¸ĎşKzĘ7siélcţlY ŢbŐ˛l‡·W<·1$¦h§qÍé{ĽNÝ)o¤ˇą-3¤4úT´ˇhN˛dâ(r(Š?'°G5×›”8T“ˇůËq×8™›¦Ŕ5ĐÜd=n“p$™Ü4q+·.ׯź.°|.nŹ:×F‹gćd†j|S#=o’db&cĺ2uˇ/`áĚ3Đ‚y¨Á‘F¶Ë'Ú@â\#S&D’ŁŮz!33jU‡Ż×­…ÔÖwelÓ_zś*Ż.'łytŘŢ1»Ű[ÎŘRt‘ť˘É^RaŤ»aNvfgĚČkqą¸ů\$ç’ó FłťdnAD\Á¤ ˇŃę›a&J–†ç`!|8.XŔWŐ\ÁöŰ öę;-§ ¶¶‰“‹YPJW·o»ˇŐy 6Ă۶Ŕ}îÓśY";ŕţŞĹű­=¦6v¬[č:'ć˝;Ç<:‚Iš†¦Ěőc!u$Ww­ă;¨k®=ąŕł)Ń=hŃŘ.–ž{b˙^€hG–ćÝ˝›Š!‘,"ĐŇ@‰±Rń€MŐü»Ţ†hŮŻs§{â^Ó•l‘żbá¶p»ćĹŮTżđšßždWÁ(¶µ^VŞĽz+·Ë® 9sÝM~h‚ĎżdẎĺŔrŕźë€>Îý˛üë'Ň_ÉÜDô¨Â%?ýşč&â›ŕą‹Ý}7^ěá$TîźÜÄÔŇůÓí,±ťíÝ·Ľf.Éty€\ţF}d›ý|ęŐmÚĺúä$¦őéQůÎ*,őŐezÉ:±íşŃK\ ű\{‹Ç C ˙łť¬Ţď6‚uj}WŚţłSşkČ0ßÇ8ßÝ˝Ű,vv;OŔc,ě;ľŃ4qç'LěÎ7ßĺ1Č*˝5¦čb.ěląU"·ëÄư=”CěhXŁŕß=j+ÖĄHLISŕU#Ő9®Á­šÁúĹ5p­Rěń€lť35Ăă¨}xU¸Ľ(ě ČÎMLŁeÜH¬ĆŲ˘–ČŃGâN0‘ÍTv…© Ç(¬=seÖtj HY5a ‡ĆĽî8­•—*ëŐˇŢ"Ňß«¨X9ÁCcb*ËÜ×”ç/j“‚ĐtˇÚ’9‚…ś=hđĆ\:ť«¦¦Ö©M܉> UŔ奮EŤ«ę #úĐ0“ÍśŽ˘ŞčCŻDśÁ[Ě ýn˘ĺť™óŹQ¬µ˘±Kő PtleWp¬Úd«DÝ>70µ*ŤN—šëĄG ŁM諰祪·§¶NĹNŔ–wŹÄKŽ#AÍqśĚV·śá썿¨ćšp’:1aEfňňą3S>Z·…HôU¶¨ čŰ€ˇÁŕ'Řń#K‚ ŇÝőźwq}+: MüĘoqß"U÷ľ‹ˇšź©żtěŔ‡T(ô”xĽúnÔÖ±qÓ˝!ŢVkP'z—LU܇z¸l$;d#|Z1Z[‡ÖI8Ŕ›­ń=Xű›Č°qÖah˛‘é–Xv/”áI†}ÂúSť%±‚Qp±”]®#[zľ`ăřVu™L/ĽžViµBq·>h®Ô `żĐ&¦¸ËoîŔ߱ބßűćgäŹD+|9°řâ@>’_"Ď1Üüőú@?}ąťQîs Í-“[Š[_o%Üý|×»°őžó 훥ąąďqóóŤ÷Ó=ĐśŞ¶!\ÎíwZă6d =]ůłÎZ]nC \IžďŢö6d¦—z›]ë¶č&phSĚp˘Żôj —jc70]do‡fVń劰C(LÇŁ3ß-‡0ň(đeč¦l&Gâ„Ţ '@ÇL·L5Üś@ixYW´â¬´Ń‹ěwp9kěx¸h&râ…+˘ósşČi)š˛Ťžuď|áŢŔě|= 9Oh ŻćMM”ţ2)´B~3Ę,+ÄŐ7ˇ\éöqY-ÉJHŁŢą:ůŚŔ> έËčJUÓĚdkúPÇŁMF°öć,¬­FiýřČLÔqq;eÖ±şç:AÝ|iŹc&»<›¦L`tS•FN`'Uä!XÔŤőx:°ÓRLnnż*•(&ĺÁ™9¸ŘáýźËVŢ銹€…†ýŔ M/ŮŘ«¤đ2(Ůç…˘ᢾàµÝ5éůVpěĹ®ąj} rŞ}6®Ű+Uŕö^¦UFř”Í*fě`‰rTĘ{ă–ó5ظ_{DÍÝŠF™ t»­&cwn5µL |[1p‚÷tXX`ĎDŕÝY±Z%6 ńČKF…‰p‹¨i^±ţ‰,ęHăn>hgKÔőm¬ŕŁÝśäac±?ZS˙„u¸†oĹîąW{9°řOĺwßâó±ţE›obÜ?s#˙ĺN"J˝žpJ'5.ĎŞ7R`%Ü7ě~â¶}żQ|ßő<÷á}ܬŤĘ }ÓoWů!¶1Ęč”lý©ăů Ç.§Ü*ąŠÇ<9q˙P!ţ#ćđËyyn%}Ňş,Řś1Ý»i6› 8vôńŞĄ,y&µŰĘĆ÷UÄĐąx,- pphuŹ”ŐŰEÂi7ěîÔłâŮ“„;Šş şR'DąŁĐ›’ĎE¬©YŐ–TŔ\P·Ç0řYŐ{§űc¸•tHÎş{9ăťć€{§•…'těęô‘[?hđ¸M/ÔähfSĄf˙ňŃią^ÁÁ–zîz[řaŹ9n*» ĺfgJ~ÎSp–B‘ŠoôHÄzxü˛MĆŠ(/eĄó1±icö…9o#çĚŻ,á"]GĐľČîýÇ ¶ĽŰĐg°7’š›ł©ý OßË„s×ĚTR€.‡@wM<+°]¶×„Dž;ÂfŔ¬T^ŞZ·4\Ŕ ©(c«hkÝ|&Yёۢ›c7š,—M’/âŤBö x§+ŘA[Řěa{ąS¬ď_ZÉ˙Ŕ‹mDZ0˛Ă˙Účě'ę˙N µÉú:đ?^›Î:/–Ë?p€ŻLßE~ľ•řćÉg$ţ|Ď Ň~ÍŻo ľx>©WüřŽĆ_|i}Ăj>ľeó]ë+)ßČýŤę/€ůĆP‹vxźÍ }z–ŕŃÇ·zŁX`đî¸ů€ö×Z*D±Rí˛üP¶IĘ%ŲO|Źaę¸+ą°Ž$´hŤănÁAöÇdiy‚ůja9OňčeÔÓ7ÔďÁ Ę ťŻöQőĆd`uíÂDxĆG¤ćÚ†"kf¸Eg_v8~w»Żä»î‡aĎî r×Ĺ Ľ¬µÜÚÇą} mgŕBw’â9¦$ßLöQ˘)Î+`Ů“‡Á“DÓkěČ{łOÎÇ÷ŢsŠSŃçEŮ÷Żô0ş7™ÜAëŘŻvě>;&Ů^ÂFČ5ť`{‡Ż’/vy`vŐ w`/Áu­6•á.­g°K»0ó›ÁáŘěî?ÓbťÝţ˝=w vÍ}RSź ăíy4o{5&źÉťY;ŕ9ˇŁ®wÔĽ-4иËÔCŐ6ěěĄođ6w5Űď[€!tł;€yý­ŁÉ˝o3Í·ČUv^ĹĽG€ę$ŹŃłňć¸#?âéOlŇRN^ŻČ 8_‹{^>.ŰľŤ®[đÎ ĺ¸ÝQwŞZşý… ĘěRĽÇ&áé.Ň]>0ŔÂo‘P×-’uôůş %…Ź‘M=ŤÝbű§Â+—Ą’§“ťůvýB ô0ˇęyŕí„Í LŤNćG0÷Ú–lwIą9kÚł"¤lgë’g€ĂË5Ś ÖĎ5·»ă€Îó9ę­?ĆŁáu׋Çh§ćlŤŻŘÝo4 ţE;µ™Ĺ§ńv\ř:nCŢ&~'}˸ć—ËĺŔ¸ýéŻB}ýĺf”ď&ßţęyůó Ô7ÝúNÎËßÎźnÝ‚ö˙¬ !ůÚô=üµ^+’ď)ľhü­§&=•ń ‡×¸Rßxż|uě°ő˝Z`RčšéH•:éKÂ#ţm Ł¬Ó™Ś©1]nË6Q tttUý~+ÜÁö'ěq“˘›ě7ÔŁBăQ RÚŢpî~Žf&Ć4Ú]g©LގEś¸ľZ瀪a¨NÇ=µ‹Mčn Í)Řq# Ovç–@H Ľę.WöÖą ÝWđž´ßcłâ3fâ.Á9aż8Çś=r$WÄě§×€÷*ȱ˛ Ý–}¬§ŢÝ0Ě—•žT'š+ŘyÎŰÄ+zŃËÖý łiN±0b. ­śg•©oǬő°eWđiˇ„!ßA y4rÁ^~dqÜQ¶MÁt šÔAÔäöŤB¤Őq­™y-ôe{ĘĹőőśLăA_Ŕă?ooh ˝˛«aţw#4 )#-Cđ+qCPľŃš÷ôfčL@Đń^čî0ÁĘáŘ•Ú3•Ü„Ž}Íΰ~yNę-~ë'ÄĽó“ř\ĺ¨Âpo’«ęńŮEBł1ŹBćŞŃ˝ŐÂĐ=őýŁEóTĽöHRM+¦ˇˇĄ†/=Â0Éo±€0Ş+[ĺš|˘†}F‹ÄŽąsŢWě fŽŔgę{ŃUµ0ĹíF AŚşCâĽk©ÚE[€:sČn”đffżQŔďXŻ„€şf÷ż`٦vĽd#ĺV%ěâ]…ĘýŚ5Ű|8ÇΔ/Í ­áÖ‘:řŃ]ŤĺŔr`9đ/ă€nąş…I®N?ÝwůÖŕë‚o'n÷<Ĺ|­ZáŽwsřţ n _îőťĆ·/±€Ę‰ş@˘ÚýýHąůЬ/<_ŃÁ ŞH¬ę\0kěń‹˝č›Ă ý'9?ˇa ] DI 6ő=Ť„ČW  µµÜ­ÁV=r-«”»ÝćýPt`&PĂÁČÜ´Áި¬v°Bkt&|W ¬ë”ş*Ž[%q‚ÖĐ„ZŠ„ßhjŕ26c®=|+Ĺ#źŇ]-‹ęSä¶ šP'ëĆ2ŞĽiw):` [4c[Ď-‡Ý‚÷áWl†xÇuböcÇŘ;'‰éťS’ąĚÁ»7W­šP­ 3z8váÇž“9äRło¸§čŁęŤýžŐ|˛ˇS_×y|–ö˛~aŐĽdľa4ŐÉ“áŘĂ)˛]ýâ=2ß3{ć}š0÷ě·ĐSđ™ąŕżüÖÂ>ŕőÁVľËţR2KB٦›G7ó|{Í™náÂU¤«ÍzĂ\†43y6b'"ólÝCdĽŮĂÉÄ7îě™zăYřIÍznŮB·*-Ü)™Ő1ó ż»Ú†:ŘôűhFĚb5:tĆ26&Đ>Ç6Z‡,F;­®·X?~e˝.‹€ÍŔ=8ÂcÖíĎć“hŠ‘á¦iťôEśOâCÁ6B˕Ъ±ŔČÖßÍASĽTť& zy8‰úfv3 ß±.”ťĆ ľ`y¶X—Ů5kěUs•łˇKô›ĎBnăŤüL›,÷mk N=đŰŹľúô[ć˝X,ţřńv»Să»®ż`~˝ňEç»¶Đţjć&ľËüÔäv__’ů¦s÷Ó÷śż)ڇýuű/FX(ĺĺ @öP/Pž ü×ôj“î­\t´;ăw’G´¸Ę)ˆĘiř·¶%çžş}J¤ź*RAĺŇü­p° ®×ËAKep!wč`]n’ętÂç ;žHGCÇĐt“xN ›‚1TqG0¬>¦Ô&`ł(ÚUÇmkźR¬CPGú-g®ŰqI<ýA{ČŮ&ş=ľočöĐěżŰuÁî ëˇŮçp)ëhDw{wť8Ö`];ІŤŽhӞ쓢9í©ŐÎ^ťÉ†f$/ş=¸üŁěëł&˘‡jĹŐŇ=}#ű…dźJ)ĐqYh>}͵«ĚX&uľĘîî|L¦É'ŕÝŰÜŔł·GÇ \¸'ő?u5.ÍłíÉ_ČŞ´üŮőŤžřĹű–B‘˝ Ą9ókĽNíŃN×ůĘ€;đFâ ©Ł±”«ťŻ+…ě*©Ă‘ĽĎ—ޜَí‹Tđľ›ÔóećÇ6q™˝qì©l˙N˛·‹ĄSpŐď…ä+dV˛6űĆTç˘ó-vň;IwŽ;Żý)+ŞŤ=-ä¸-xÝgć“Ŕ¤aAę¸|”Ç`"8 ę }OĚF©mĺ#ŔA÷“hŤX% `®¨yâ5ÚČBpŠ~ĂÂ6‘ť+Ů^‰Q8ÔÍśâ߉ -e:Q$ÜmKj=UwɶĎŘH—rS{˝>IĚ˙ý J}€řéiř‡Ř_xVěr`9°ř÷q`ÜsGăsmő}Ł;vnűşűĹŠ¬żŰÝĘ·ć't±ú‹j¤Ń#ú—»?Řü7ݢÇcż‘+RqúÔ_†űV8“ †x¸áx⏠#ÚHäôd:!\nCFóľ|ËăK ě«Óě]ď„{aŠ«“¸^irÜ ç˘:ÍV=€Sł›Rb¤şĐj o¤NSĎBÎp^¬@{pJ]ëvE‚mzüÇt›ÖŢ"ĚG"uŢş…žPcWG´= ÚŠsďĂF´V/’”~&V'ôÔW˘™r®Ě~—Tx-×lj‚ô×ĹbĄB™P٢Ą;Gâ?»$jľč†xű@‰/`_›]cV?ďUşT )Ţ MąA;p”i%(đLěf˝†2µÉtś¶\žTĐ[ď°•.5#…NšłÎ 7"÷v}ă•pĆĘýq‡žČö{äË.ľH™-ł˛ťxSÄNv,š}ůÉ Ŕ›WqC|ţ˝Á«ĽW­l:5, Mú"3ÓÖíµ›™ť·0V¶ÁDצkí ĚÁ;ÇŚ/f€^D÷ď°¬Ő`ĄaâzBÓ·Äü:„lĂę<şµŽÓ˝™M5`ź| ŘăîĎ>µádŹUşDZB×iD{“™őĆâ69r€ßBgó‚RţljŤ-–ËĺŔ.ňeĹ-›űţO÷nQř‹Ć˙K2|Ż˝őç»˝ľ¤ňeÍwÖx Şpţř«Ů_ÓďěőHdľÜsţ@^*yPĄ~(ŕŃŔŹhy\ÖĆcX`>Ă‹oO`‡”r)Ö «PŇ4”ü±RZÁx3{ŕŽ¶¶›ţZXýáH06Ź6™Üż®@"Z,mgrĂÝąić¨xGÖĐTăÎ-‡u:ˇŃ6ÂÉľl^®> [Üš2Ű+Ĺt4Đ«QKš˘Eܰ‘păc"đ•Ű$°qÂ54_5yĹň‚ Xö挕"RúĎ ,t,-ZŁ‚śt•a˛MÂŕy«†rĆ5›0ŁŽDrçŘLč])lĆ,–"wp‘ęRé˘13ŮY¬-śŹNVť)¸˝n¦‚Ž:FŽłŁ„pNj˛~űCÝŮQ6˙pí˘˘”“ vxť*2‡ÇDF*ͬdˇ7‰]A±µrwoÁ°WşćÖČTµ™»@_ 줰“Ď… ŰÉvěśŇődĄ°»Žö&]%RŁTë aŽĺ{ĽĘŚuÂDwşÁßýc$Prv˛0gřĆ/W]\>¸ač-±t "óů­F.73ě’­Ř`i(ĄłŞ˙NŐš§ewŽű‚ťł\»°Žů—ĹN‹Â-fÉM2×x8möRÁdy…*ßn«ŮJĐýś«˝âbŁ˙rń¤hcÖ´ČŮ` ÷MŢűěŐçC wť°~°ů.ßČ ż§©/]Č}| ľĆňOxŻ©ÖČr`9°Xü;0ľ'Fă+!_őEKż"ýő^|Űąó®ŔńĄ ą_jü…ůÝPžü‡^ýŁŕűg֡ɬF(OA¦V›4/ÜŤpůj÷s‘“ľ ­ÖĎ<ńHa0üĽU?˘ND+9Ô¸WmćĘĂPÜsŽű'¶ ‚=ŚńáŮ[p‰VÁJ“Ă7˝NťL7uÚófn^µ™€ĘŮ"é’”żZDZ)v ŔĆ$šmA!Ű‘é9xҲ|çŁă˙V™E)现›Ł>;nľ’8š”ő¬`’[Äé»—šĐsÇě…€ÖI‚¦ë* ÖxkÝ]ĹçĄuč'şFśIYnŔĐučŽj¤Kö9ŘJGd$ď‰KÎŘŢ7±KŞKĂí©ěĽ|oşm€ ]MóšąijňP4 .ŃÓ_węfäßVáG¤É5+Yo1Ř1F#Ž´ďŔ 5¨ŚÁ Ö]XgŮíŤ]ł±íľd ËŢ~­JÁ[̸̷¶D[KU˛ĺ~,POú Üݨ”·Äő‹:7&«FR)ąe®Wç$˛C/¸ęĆŻĽú˛ĂŠH÷0G ˛íVçŘ$µL®î{Őďy•¨ĚE^Đ=ĐZŽd§ž‚‰ŁŘTωĆÔxí<VrĂ ”ăľŕh Š)µpeü±bĂá ~¨7řćkćZvDşčHŔŔw^ůŽ2d»$żÜ\ˇU»Ů=ůz…Ü{CW×đ•Ö™Ăm—•čłäVy–čw¬rŔŁţt•\جŕĺŔr`9°ř/ćß3)Ůß8?T_ß«|Ńä öăc|?ÖóLZ|G·g ’™G‰ýÓžqfuŤÂűŃ`ËŁ”o_—„Ç)ŹŁŹ>s T8a»#Í:řőâąpÇű1*@ݵÜÂBípSm`%#ß}ÝĆÖă˛8QeBë¸E[Ł pM¶äńř=u‡Ë5W)ŁtßPFścM—‘ô‘q_5“UpëÎC¤«w2ĐsfEş.ÎŃ1™Ú5‡’éZks)L$¸|9›¤Í¨ů<Ô1x=D/@_ďŔÄ:´Â“ŻGȬ,Sp>÷xÄôXéšîPÍ)Xą+8}ÓiÄWťć?8đidiơ¸SLÝËf˛ËIŃ»duűo+ňĂW…#qGM—˙i“ŮJŐ}o/<ŕÁL5SĂ`ѡҚţ¦Ű3ó•â'tvŮ@1±3Uîć±ĐMż—ŇOUóí@Y:J;:2dlMÝ‚C °1şlhC©ëĚ—…™ cÝ ť˙ŢůUßj VI¸ Őż#fĄŹ2«ťQuÜpşfúUĎ=sŁ›Gëěf dxŔfĄm Laş˘YÍćFµŮŢ~OÄ;tÉ­µ+ç_°Y./©)7÷ŐzĹÚ3˝¬ŰaÝKĹŢy¬uăŰ7(eëz€;ó‡“Ác©śč3ň^ŘŇđíđąTµľk®˛,=čź±ŹăM×(•á:±F–ËĺŔr`9đĎwŔ_±Č ńÓ÷U~˛ĐC…ţŰ©~¤űŽö7«€€ŤĺáDď€<”¬_Áyá)¬°\HÂń‚nˇ Çëˇ`¤x•n°ąŠ‡Hdxy€Dśi˘ÔŹŻÂ2–lĘ 4"á” o§|rM±~]$ľd 8žÝ{n˘p5Řyrr†[°—‰ĄMŤćłFô‡Ü÷`oĹHöŮűĹÉâ\¸§žek™Ażđ.,S-Ł?;> wľH‰aźbýśl<Ѧn-é1w»Ëvˇ–=í}FTúÍ.SdB8űđg)żp% Úç® Wˇ€‹ĂHx·ÇB\AÎ`“€ä0üŽ9kRTvl´Ťvöđ1Úkkµ€Ů^2ü¦fí,Ncjŕs,o°‘:W'ˇç›$o$°×š‰ťŤSSÇ=X“ @ĂËq n…`b3HŠ;,5—żŻ™są÷GÝĹ7 ëĆ.†·X<ĂűĘŇÝ[łÇgpŃ,ś&–÷ÔF_•lh Ű–•6Ô§kLýŔkÝ©Î2·Uv6Öý^43#ĚLQ[Î=ś¬®¶jk†cŻĽŕ1KŘ.˝ß\aő“H6ç ůAtŕ0n˙Ţ+†t˛ôÍçťňBsý_%wŠŢ^Ö·AăjŃűŁźŤüĄŢ]ň?ĄÝĄXÍĺŔr`9°XüŰ9 ďG=‰PÖ•|…J©eëěÖí6×J QŽNC˙k’›’af1ĚäS!Ç€ć~ńŁđѡśdľ_gËŔś@ďĚÖťRţŔ%d+ĺŢmż‹™8u‹iyÇ=`viĂqdN5T÷ʵ^‰/0^‰ünˇ´ĐŔˇSJ/^w|zF3 «k74Ś÷^łúĺ¶j37É’ĹržJŽđ(Ś ç iOŞyíN¸‰Ťn 9źU ‡ĹşfőŔkD'*{8\lYVΆ•¸Lˇ—cv$@üëßI¶Éuuąo›Ď`Ş%ăe•¶‚°ü†ĹrŘu¸v_?‰.~ˇŕ×ń3T‚4ćVÓ·Ö€˙vGţ3ŻŐů7Ą+j9°X,–Ë˙`ü,ăG>?Eýň\ˇ/ußx¦Éă O5ßäúy@áćäÁÓŹ’ßĐ~ăŠ?tň ů‰[á<łúů ź§ľô˛ĺľÄ^cľŽŻ‘ĺŔr`9°X,ţőŕ©ŔŹ~˙éá@@=E®Ç˘OĎŽ±HĎO†sâń—§ąŹä(:)ęů»Šxó?d<~§ <¶~|s¸ŢÍ‚U ňČţŞÜUšV/ÚPća=użŠv8'©¶^ Ëńfą|A©3î$”đ m¬1ć8ő’×…'$‹ 3{…źě¶&źŔDąRÉtËĚQbü#ŘŐĄTŃ*WUŰ5?Qwpr´T4úž&„#šč^猰syëwŐâX˛čĐő9+C¤±®ĺ¶šg0ŚCv5řČś_+ŔÂą1W:yđ Ű2#đ~©\Čó6±OFCÚ ťs}`öO&¤RWËŕ'l˙d°!bwXÉőVpUŠÎbNSăĎŘü…hí˘­ßőża뽝BmX ŽR>ŠÖ"˘­™7ż’čť‚ŘÔÔ–ńˇbS-·jťuˇÝoŻžu6gŔ©ÖŕŽxş‚†Ö|:cjž0cŽ›žătâřµăŘ­ďXĐX±™żiŽxĐÎPY>‹.xů˛ű´HĂ2Ćôé0óĄÓŔ%wjËő©G~şĘä?$ţ‰f/–ËĺŔr`9đďě€g(ĐObż<Ă ˇG¸<Ďđ,H¦ŻN… Y ¦ýéČ#cŢsÔ^ě_Ŕ¦ťźŐÇ«’uĽĂď'uŠőĂz?sż‚WôýŔďפeËWž˛yČw˝Âé ŁŽ7f K4ő ëµú°^„Xy† gxˇŽ×"ËŰúS†<­ÓlŃ ~?păy­Q¬č`¨ŚŽ\ź·Y°D–‚mCó¤Ű«#8ˇŰţ‘‡F~ÜŁv« &ň®"«j6 ŘśźţůŤęa‰mŽ©Ç'ÁsÍúü č¨7Ň`őź ó®/+†u®>~˝mn;m„„â_Ł=ńLěű]¨ĄZčň‹ČőŚ0ęm xĂúýsǦ\Č÷é Ú`ŻN5“á•8Żľ ‹NVý\°gˇÄ‚m­ł*ó@CgŇĎÄ%ÜFg©8%?Ńjź˝FEŁ=TŕťEu|+¸ë¶VHC\Ă/°çÓGĐ3š“Ž1řąÜźaEçńZ ‚˙@óçâVŕr`9°X,–Ë˙ĽčĐB~űI¦ź ÖÓ'Ż?>F kLžŐaćřŕH0”˘ż"Ç‹^¬ćý6#X×lrŇ8Á«ÝŠ#’?1 XşďşůaI¬:Đŕ†űdxcf;‰Ş¨®DxŁF2tņä“EB^¨q9Ü6̲G†p°ev×l!ó6+…R«§Ĺß×íÝ(_70©ţúę6/ˇD W'zŻŞý"Vč€qO‚uĽ›]č”j@ĐB~G'¦Ëä’đćµ÷€‹¶NNBţ ŰŻí†Aj¬—ě_âö>±î±Î,Ů—’íXŮS.ŘÝO%´VL|ĺÖëćÚ>2V~ä%…ę3)'ź–xOmüަ>´ ‹ĹC Ďé8ń­×đoŃç(ˇeŢytő—ËĺŔr`9°X,ţÝĐ3óŹ%ćaY Ľ^üđ _˙áąâő Ý÷GP?ßó†Á˙ű†ĽŁ|~čÖcşßÄôÔkbż—}Dâ ZĽĎń÷3ixą 3żđŕţÉsý>eËŐĘŔ'tŞ~j·~6ů@í_h ăš•Ë>‚EĹ%?˛Č´o`#»(ţ¸Ě2±3°Nvűµ—ÉncĹú°ăŻŽá‘PöČoŔ†ýlÁMíŔ‘ţŠíYĽ>UsýNőÜhďhś-ĄĽ3çÍëŚ÷†ÓúnjcĹlr§ů¦6ŞýúĘěGÓp‹Žţ/ÄüŢ`©Ą[—Ϣ•ß.fżńMłł?CA#”˛sú¶Js¬ÓţÚ'Fđ_!»8Đ˙ŔŹÄ9č˙1ôHłËĺŔr`9°X,–Ë˙8ô´íäyÖ˙‰‡WŁyęć]ăt˝ZÁ»‚ßo>ŁE—CXŢ®ŕţ 60ŻU"ć7ŹŢ4ö›+Đ’î#u čµj_?˙˘f ¸’©…ˇĐPS€ŽĎ«Ą%V°Đ˙î9hŕwÇ„X5ć=V¦Ż9`Ö ,§Żkeć t¦ˇă;ĂŔE¶ńźe#Ôź‡}ŃźkFŞí6•|ܟĂτÝţŠíJ ¨ă3Żë(ŇB«÷Q´Âš±©Á†Űj,ŘúD {NßW¤ŃRËď?Ô»GŁ˙gŢNđ§Ŕ…[,–ËĺŔr`9°X,ţs:ŕw ¤ń{ĹŹ˙|'ď'Âú€_4ô^Ä»¤ÁühńËkJ˝7 B–ߎüÚ+j1ëUđÔÖěw`§áĺîűşn?˛¤v˝~#UoßR«·ŃĽ‡˙®ßřĹuţ©f×kř?˙Ä‚ľ€‘ćźj*5WńŇţ˝fŢše”RŘ0ŢáżýĆź$…ŮJňËŹŽe˛HÇŹ`łSĽŹ_ŔÔZ0_Ŕz­ űëM#ëúqŁsýJ¸H}ţč‚,–ËĺŔr`9°X,–Ëęµ×żtüZ“^&ůy#ďî?‚ĹËo,Ľ ëmř—7`03ďŢ ţf˝Hę­ß5ű·źŠËŹ ~ţUvţńNŮţyę_™al0żüXóű§‡źŔU+›ägblÎ_˙WA~Sív‚¬ÖoŞŤa…pűGżĚĐź`«b_~.nWú'Č_-ZńËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–ËĺŔr`9°X,–˙•ř˙|Í®@q&nipype-0.11.0/nipype/testing/data/session_info.npz000066400000000000000000000000001257611314500222110ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/skeleton_mask.nii.gz000066400000000000000000000000001257611314500227410ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/spmT_0001.img000066400000000000000000000000001257611314500210430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/spminfo000066400000000000000000000007421257611314500203750ustar00rootroot00000000000000fprintf(1,'Executing %s at %s:\n',mfilename,datestr(now)); ver, try, if isempty(which('spm')), throw(MException('SPMCheck:NotFound','SPM not in matlab path')); end; spm_path = spm('dir'); fprintf(1, 'NIPYPE %s', spm_path); ,catch ME, fprintf(2,'MATLAB code threw an exception:\n'); fprintf(2,'%s\n',ME.message); if length(ME.stack) ~= 0, fprintf(2,'File:%s\nName:%s\nLine:%d\n',ME.stack.file,ME.stack.name,ME.stack.line);, end; end;nipype-0.11.0/nipype/testing/data/streamlines.trk000066400000000000000000000000001257611314500220320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/struct2mni.nii000066400000000000000000000000001257611314500215750ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/struct_to_func.mat000066400000000000000000000000001257611314500225260ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/structural.nii000066400000000000000000000000001257611314500216730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/study_template.nii.gz000066400000000000000000000000001257611314500231450ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subj1.cff000066400000000000000000000000001257611314500204660ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subj1.pck000066400000000000000000000000001257611314500205050ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subj2.cff000066400000000000000000000000001257611314500204670ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subj2.pck000066400000000000000000000000001257611314500205060ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subjectDesign.con000066400000000000000000000000001257611314500222540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/subjectDesign.mat000066400000000000000000000000001257611314500222560ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/surf.txt000066400000000000000000000000001257611314500205020ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/surf01.vtk000066400000000000000000115366221257611314500206620ustar00rootroot00000000000000# vtk DataFile Version 1.0 vtk output ASCII DATASET POLYDATA POINTS 31034 float -32.035343170 -33.840930939 -35.797355652 -31.336599350 -33.903381348 -35.879737854 -30.442840576 -33.946811676 -35.937088013 -29.481933594 -33.968864441 -35.965759277 -28.495168686 -33.977611542 -35.976860046 -27.498950958 -33.980327606 -35.980201721 -26.499826431 -33.980976105 -35.980960846 -25.499979019 -33.981090546 -35.981090546 -24.499998093 -33.981101990 -35.981101990 -23.500000000 -33.981101990 -35.981101990 -22.500000000 -33.981101990 -35.981101990 -21.500000000 -33.981101990 -35.981101990 -20.500000000 -33.981101990 -35.981101990 -19.500000000 -33.981101990 -35.981101990 -18.500000000 -33.981101990 -35.981101990 -17.500000000 -33.981101990 -35.981101990 -16.500000000 -33.981101990 -35.981101990 -15.500000000 -33.981101990 -35.981101990 -14.500000000 -33.981101990 -35.981101990 -13.500000000 -33.981101990 -35.981101990 -12.500000000 -33.981101990 -35.981101990 -11.500000000 -33.981101990 -35.981101990 -10.500000000 -33.981101990 -35.981101990 -9.500000000 -33.981101990 -35.981101990 -8.500000000 -33.981101990 -35.981101990 -7.500000000 -33.981101990 -35.981101990 -6.500000000 -33.981101990 -35.981101990 -5.500000000 -33.981101990 -35.981101990 -4.500000000 -33.981101990 -35.981101990 -3.500000000 -33.981101990 -35.981101990 -2.500000000 -33.981101990 -35.981101990 -1.500000000 -33.981101990 -35.981101990 -0.500000000 -33.981101990 -35.981101990 0.500000000 -33.981101990 -35.981101990 1.500000000 -33.981101990 -35.981101990 2.500000000 -33.981101990 -35.981101990 3.500000000 -33.981101990 -35.981101990 4.500000000 -33.981101990 -35.981101990 5.500000000 -33.981101990 -35.981101990 6.500000000 -33.981101990 -35.981101990 7.500000000 -33.981101990 -35.981101990 8.500000000 -33.981101990 -35.981101990 9.500000000 -33.981101990 -35.981101990 10.500000000 -33.981101990 -35.981101990 11.500000000 -33.981101990 -35.981101990 12.500000000 -33.981101990 -35.981101990 13.500000000 -33.981101990 -35.981101990 14.500000000 -33.981101990 -35.981101990 15.500000000 -33.981101990 -35.981101990 16.500000000 -33.981101990 -35.981101990 17.500000000 -33.981101990 -35.981101990 18.500000000 -33.981101990 -35.981101990 19.500000000 -33.981101990 -35.981101990 20.500000000 -33.981101990 -35.981101990 21.500000000 -33.981101990 -35.981101990 22.500000000 -33.981101990 -35.981101990 23.499998093 -33.981101990 -35.981101990 24.499979019 -33.981090546 -35.981090546 25.499824524 -33.980976105 -35.980960846 26.498950958 -33.980335236 -35.980201721 27.495168686 -33.977619171 -35.976860046 28.481933594 -33.968864441 -35.965766907 29.442840576 -33.946807861 -35.937091827 30.336599350 -33.903377533 -35.879737854 31.035345078 -33.840930939 -35.797355652 -33.030693054 -33.030693054 -35.846313477 -32.334243774 -33.254276276 -35.954723358 -31.405673981 -33.216838837 -36.112342834 -30.460596085 -33.220722198 -36.185966492 -29.486719131 -33.227870941 -36.217514038 -28.496377945 -33.231601715 -36.228958130 -27.499221802 -33.232868195 -36.232299805 -26.499872208 -33.233169556 -36.233074188 -25.499984741 -33.233219147 -36.233207703 -24.500000000 -33.233222961 -36.233222961 -23.500000000 -33.233222961 -36.233222961 -22.500000000 -33.233222961 -36.233222961 -21.500000000 -33.233222961 -36.233222961 -20.500000000 -33.233222961 -36.233222961 -19.500000000 -33.233222961 -36.233222961 -18.500000000 -33.233222961 -36.233222961 -17.500000000 -33.233222961 -36.233222961 -16.500000000 -33.233222961 -36.233222961 -15.500000000 -33.233222961 -36.233222961 -14.500000000 -33.233222961 -36.233222961 -13.500000000 -33.233222961 -36.233222961 -12.500000000 -33.233222961 -36.233222961 -11.500000000 -33.233222961 -36.233222961 -10.500000000 -33.233222961 -36.233222961 -9.500000000 -33.233222961 -36.233222961 -8.500000000 -33.233222961 -36.233222961 -7.500000000 -33.233222961 -36.233222961 -6.500000000 -33.233222961 -36.233222961 -5.500000000 -33.233222961 -36.233222961 -4.500000000 -33.233222961 -36.233222961 -3.500000000 -33.233222961 -36.233222961 -2.500000000 -33.233222961 -36.233222961 -1.500000000 -33.233222961 -36.233222961 -0.500000000 -33.233222961 -36.233222961 0.500000000 -33.233222961 -36.233222961 1.500000000 -33.233222961 -36.233222961 2.500000000 -33.233222961 -36.233222961 3.500000000 -33.233222961 -36.233222961 4.500000000 -33.233222961 -36.233222961 5.500000000 -33.233222961 -36.233222961 6.500000000 -33.233222961 -36.233222961 7.500000000 -33.233222961 -36.233222961 8.500000000 -33.233222961 -36.233222961 9.500000000 -33.233222961 -36.233222961 10.500000000 -33.233222961 -36.233222961 11.500000000 -33.233222961 -36.233222961 12.500000000 -33.233222961 -36.233222961 13.500000000 -33.233222961 -36.233222961 14.500000000 -33.233222961 -36.233222961 15.500000000 -33.233222961 -36.233222961 16.500000000 -33.233222961 -36.233222961 17.500000000 -33.233222961 -36.233222961 18.500000000 -33.233222961 -36.233222961 19.500000000 -33.233222961 -36.233222961 20.500000000 -33.233222961 -36.233222961 21.500000000 -33.233222961 -36.233222961 22.500000000 -33.233222961 -36.233222961 23.500000000 -33.233222961 -36.233222961 24.499984741 -33.233222961 -36.233207703 25.499872208 -33.233173370 -36.233074188 26.499225616 -33.232868195 -36.232299805 27.496377945 -33.231605530 -36.228958130 28.486719131 -33.227874756 -36.217514038 29.460596085 -33.220710754 -36.185966492 30.405673981 -33.216838837 -36.112346649 31.334243774 -33.254272461 -35.954723358 32.030693054 -33.030693054 -35.846317291 -33.840927124 -32.035346985 -35.797351837 -33.254272461 -32.334243774 -35.954719543 -32.371025085 -32.371025085 -36.154674530 -31.438953400 -32.375358582 -36.280395508 -30.476003647 -32.379226685 -36.344284058 -29.492319107 -32.382312775 -36.371490479 -28.498050690 -32.383808136 -36.381023407 -27.499622345 -32.384300232 -36.383724213 -26.499948502 -32.384407043 -36.384311676 -25.499996185 -32.384422302 -36.384407043 -24.500000000 -32.384422302 -36.384422302 -23.500000000 -32.384422302 -36.384422302 -22.500000000 -32.384422302 -36.384422302 -21.500000000 -32.384422302 -36.384422302 -20.500000000 -32.384422302 -36.384422302 -19.500000000 -32.384422302 -36.384422302 -18.500000000 -32.384422302 -36.384422302 -17.500000000 -32.384422302 -36.384422302 -16.500000000 -32.384422302 -36.384422302 -15.500000000 -32.384422302 -36.384422302 -14.500000000 -32.384422302 -36.384422302 -13.500000000 -32.384422302 -36.384422302 -12.500000000 -32.384422302 -36.384422302 -11.500000000 -32.384422302 -36.384422302 -10.500000000 -32.384422302 -36.384422302 -9.500000000 -32.384422302 -36.384422302 -8.500000000 -32.384422302 -36.384422302 -7.500000000 -32.384422302 -36.384422302 -6.500000000 -32.384422302 -36.384422302 -5.500000000 -32.384422302 -36.384422302 -4.500000000 -32.384422302 -36.384422302 -3.500000000 -32.384422302 -36.384422302 -2.500000000 -32.384422302 -36.384422302 -1.500000000 -32.384422302 -36.384422302 -0.500000000 -32.384422302 -36.384422302 0.500000000 -32.384422302 -36.384422302 1.500000000 -32.384422302 -36.384422302 2.500000000 -32.384422302 -36.384422302 3.500000000 -32.384422302 -36.384422302 4.500000000 -32.384422302 -36.384422302 5.500000000 -32.384422302 -36.384422302 6.500000000 -32.384422302 -36.384422302 7.500000000 -32.384422302 -36.384422302 8.500000000 -32.384422302 -36.384422302 9.500000000 -32.384422302 -36.384422302 10.500000000 -32.384422302 -36.384422302 11.500000000 -32.384422302 -36.384422302 12.500000000 -32.384422302 -36.384422302 13.500000000 -32.384422302 -36.384422302 14.500000000 -32.384422302 -36.384422302 15.500000000 -32.384422302 -36.384422302 16.500000000 -32.384422302 -36.384422302 17.500000000 -32.384422302 -36.384422302 18.500000000 -32.384422302 -36.384422302 19.500000000 -32.384422302 -36.384422302 20.500000000 -32.384422302 -36.384422302 21.500000000 -32.384422302 -36.384422302 22.500000000 -32.384422302 -36.384422302 23.500000000 -32.384422302 -36.384422302 24.499996185 -32.384422302 -36.384410858 25.499948502 -32.384407043 -36.384315491 26.499622345 -32.384300232 -36.383724213 27.498050690 -32.383811951 -36.381023407 28.492321014 -32.382312775 -36.371490479 29.476007462 -32.379222870 -36.344287872 30.438953400 -32.375358582 -36.280395508 31.371026993 -32.371025085 -36.154674530 32.254276276 -32.334243774 -35.954723358 32.840930939 -32.035343170 -35.797355652 -33.903373718 -31.336603165 -35.879737854 -33.216838837 -31.405673981 -36.112342834 -32.375358582 -31.438953400 -36.280395508 -31.451213837 -31.451221466 -36.380989075 -30.483785629 -31.456089020 -36.430477142 -29.495611191 -31.458080292 -36.450424194 -28.499073029 -31.458770752 -36.456943512 -27.499858856 -31.458948135 -36.458606720 -26.499988556 -31.458978653 -36.458934784 -25.500000000 -31.458980560 -36.458976746 -24.500000000 -31.458980560 -36.458984375 -23.500000000 -31.458980560 -36.458984375 -22.500000000 -31.458980560 -36.458984375 -21.500000000 -31.458980560 -36.458984375 -20.500000000 -31.458980560 -36.458984375 -19.500000000 -31.458980560 -36.458984375 -18.500000000 -31.458980560 -36.458984375 -17.500000000 -31.458980560 -36.458984375 -16.500000000 -31.458980560 -36.458984375 -15.500000000 -31.458980560 -36.458984375 -14.500000000 -31.458980560 -36.458984375 -13.500000000 -31.458980560 -36.458984375 -12.500000000 -31.458980560 -36.458984375 -11.500000000 -31.458980560 -36.458984375 -10.500000000 -31.458980560 -36.458984375 -9.500000000 -31.458980560 -36.458984375 -8.500000000 -31.458980560 -36.458984375 -7.500000000 -31.458980560 -36.458984375 -6.500000000 -31.458980560 -36.458984375 -5.500000000 -31.458980560 -36.458984375 -4.500000000 -31.458980560 -36.458984375 -3.500000000 -31.458980560 -36.458984375 -2.500000000 -31.458980560 -36.458984375 -1.500000000 -31.458980560 -36.458984375 -0.500000000 -31.458980560 -36.458984375 0.500000000 -31.458980560 -36.458984375 1.500000000 -31.458980560 -36.458984375 2.500000000 -31.458980560 -36.458984375 3.500000000 -31.458980560 -36.458984375 4.500000000 -31.458980560 -36.458984375 5.500000000 -31.458980560 -36.458984375 6.500000000 -31.458980560 -36.458984375 7.500000000 -31.458980560 -36.458984375 8.500000000 -31.458980560 -36.458984375 9.500000000 -31.458980560 -36.458984375 10.500000000 -31.458980560 -36.458984375 11.500000000 -31.458980560 -36.458984375 12.500000000 -31.458980560 -36.458984375 13.500000000 -31.458980560 -36.458984375 14.500000000 -31.458980560 -36.458984375 15.500000000 -31.458980560 -36.458984375 16.500000000 -31.458980560 -36.458984375 17.500000000 -31.458980560 -36.458984375 18.500000000 -31.458980560 -36.458984375 19.500000000 -31.458980560 -36.458984375 20.500000000 -31.458980560 -36.458984375 21.500000000 -31.458980560 -36.458984375 22.500000000 -31.458980560 -36.458984375 23.500000000 -31.458980560 -36.458984375 24.500000000 -31.458980560 -36.458976746 25.499988556 -31.458978653 -36.458934784 26.499858856 -31.458948135 -36.458606720 27.499073029 -31.458770752 -36.456943512 28.495611191 -31.458080292 -36.450424194 29.483785629 -31.456085205 -36.430473328 30.451217651 -31.451217651 -36.380989075 31.375360489 -31.438953400 -36.280395508 32.216842651 -31.405675888 -36.112342834 32.903381348 -31.336603165 -35.879737854 -33.946807861 -30.442840576 -35.937091827 -33.220714569 -30.460592270 -36.185966492 -32.379222870 -30.476007462 -36.344284058 -31.456085205 -30.483789444 -36.430477142 -30.486968994 -30.486968994 -36.469234467 -29.496957779 -30.488048553 -36.483337402 -28.499475479 -30.488342285 -36.487373352 -27.499938965 -30.488397598 -36.488258362 -26.499996185 -30.488403320 -36.488391876 -25.500000000 -30.488403320 -36.488410950 -24.500000000 -30.488403320 -36.488410950 -23.500000000 -30.488403320 -36.488410950 -22.500000000 -30.488403320 -36.488410950 -21.500000000 -30.488403320 -36.488410950 -20.500000000 -30.488403320 -36.488410950 -19.500000000 -30.488403320 -36.488410950 -18.500000000 -30.488403320 -36.488410950 -17.500000000 -30.488403320 -36.488410950 -16.500000000 -30.488403320 -36.488410950 -15.500000000 -30.488403320 -36.488410950 -14.500000000 -30.488403320 -36.488410950 -13.500000000 -30.488403320 -36.488410950 -12.500000000 -30.488403320 -36.488410950 -11.500000000 -30.488403320 -36.488410950 -10.500000000 -30.488403320 -36.488410950 -9.500000000 -30.488403320 -36.488410950 -8.500000000 -30.488403320 -36.488410950 -7.500000000 -30.488403320 -36.488410950 -6.500000000 -30.488403320 -36.488410950 -5.500000000 -30.488403320 -36.488410950 -4.500000000 -30.488403320 -36.488410950 -3.500000000 -30.488403320 -36.488410950 -2.500000000 -30.488403320 -36.488410950 -1.500000000 -30.488403320 -36.488410950 -0.500000000 -30.488403320 -36.488410950 0.500000000 -30.488403320 -36.488410950 1.500000000 -30.488403320 -36.488410950 2.500000000 -30.488403320 -36.488410950 3.500000000 -30.488403320 -36.488410950 4.500000000 -30.488403320 -36.488410950 5.500000000 -30.488403320 -36.488410950 6.500000000 -30.488403320 -36.488410950 7.500000000 -30.488403320 -36.488410950 8.500000000 -30.488403320 -36.488410950 9.500000000 -30.488403320 -36.488410950 10.500000000 -30.488403320 -36.488410950 11.500000000 -30.488403320 -36.488410950 12.500000000 -30.488403320 -36.488410950 13.500000000 -30.488403320 -36.488410950 14.500000000 -30.488403320 -36.488410950 15.500000000 -30.488403320 -36.488410950 16.500000000 -30.488403320 -36.488410950 17.500000000 -30.488403320 -36.488410950 18.500000000 -30.488403320 -36.488410950 19.500000000 -30.488403320 -36.488410950 20.500000000 -30.488403320 -36.488410950 21.500000000 -30.488403320 -36.488410950 22.500000000 -30.488403320 -36.488410950 23.500000000 -30.488403320 -36.488410950 24.500000000 -30.488403320 -36.488410950 25.499996185 -30.488403320 -36.488395691 26.499938965 -30.488399506 -36.488258362 27.499477386 -30.488346100 -36.487373352 28.496959686 -30.488052368 -36.483337402 29.486968994 -30.486968994 -36.469234467 30.456085205 -30.483785629 -36.430477142 31.379222870 -30.476007462 -36.344284058 32.220714569 -30.460596085 -36.185966492 32.946811676 -30.442840576 -35.937088013 -33.968864441 -29.481933594 -35.965759277 -33.227867126 -29.486715317 -36.217510223 -32.382312775 -29.492319107 -36.371490479 -31.458074570 -29.495611191 -36.450428009 -30.488048553 -29.496957779 -36.483337402 -29.497375488 -29.497371674 -36.494171143 -28.499578476 -29.497457504 -36.496910095 -27.499954224 -29.497470856 -36.497406006 -26.499996185 -29.497470856 -36.497467041 -25.500000000 -29.497470856 -36.497470856 -24.500000000 -29.497470856 -36.497470856 -23.500000000 -29.497470856 -36.497470856 -22.500000000 -29.497470856 -36.497470856 -21.500000000 -29.497470856 -36.497470856 -20.500000000 -29.497470856 -36.497470856 -19.500000000 -29.497470856 -36.497470856 -18.500000000 -29.497470856 -36.497470856 -17.500000000 -29.497470856 -36.497470856 -16.500000000 -29.497470856 -36.497470856 -15.500000000 -29.497470856 -36.497470856 -14.500000000 -29.497470856 -36.497470856 -13.500000000 -29.497470856 -36.497470856 -12.500000000 -29.497470856 -36.497470856 -11.500000000 -29.497470856 -36.497470856 -10.500000000 -29.497470856 -36.497470856 -9.500000000 -29.497470856 -36.497470856 -8.500000000 -29.497470856 -36.497470856 -7.500000000 -29.497470856 -36.497470856 -6.500000000 -29.497470856 -36.497470856 -5.500000000 -29.497470856 -36.497470856 -4.500000000 -29.497470856 -36.497470856 -3.500000000 -29.497470856 -36.497470856 -2.500000000 -29.497470856 -36.497470856 -1.500000000 -29.497470856 -36.497470856 -0.500000000 -29.497470856 -36.497470856 0.500000000 -29.497470856 -36.497470856 1.500000000 -29.497470856 -36.497470856 2.500000000 -29.497470856 -36.497470856 3.500000000 -29.497470856 -36.497470856 4.500000000 -29.497470856 -36.497470856 5.500000000 -29.497470856 -36.497470856 6.500000000 -29.497470856 -36.497470856 7.500000000 -29.497470856 -36.497470856 8.500000000 -29.497470856 -36.497470856 9.500000000 -29.497470856 -36.497470856 10.500000000 -29.497470856 -36.497470856 11.500000000 -29.497470856 -36.497470856 12.500000000 -29.497470856 -36.497470856 13.500000000 -29.497470856 -36.497470856 14.500000000 -29.497470856 -36.497470856 15.500000000 -29.497470856 -36.497470856 16.500000000 -29.497470856 -36.497470856 17.500000000 -29.497470856 -36.497470856 18.500000000 -29.497470856 -36.497470856 19.500000000 -29.497470856 -36.497470856 20.500000000 -29.497470856 -36.497470856 21.500000000 -29.497470856 -36.497470856 22.500000000 -29.497470856 -36.497470856 23.500000000 -29.497470856 -36.497470856 24.500000000 -29.497470856 -36.497470856 25.499996185 -29.497470856 -36.497467041 26.499954224 -29.497470856 -36.497409821 27.499576569 -29.497461319 -36.496910095 28.497371674 -29.497371674 -36.494174957 29.488048553 -29.496959686 -36.483337402 30.458074570 -29.495611191 -36.450428009 31.382312775 -29.492319107 -36.371490479 32.227874756 -29.486715317 -36.217514038 32.968864441 -29.481933594 -35.965759277 -33.977611542 -28.495168686 -35.976860046 -33.231597900 -28.496377945 -36.228954315 -32.383808136 -28.498052597 -36.381023407 -31.458766937 -28.499073029 -36.456939697 -30.488346100 -28.499475479 -36.487373352 -29.497461319 -28.499576569 -36.496910095 -28.499593735 -28.499591827 -36.499160767 -27.499954224 -28.499591827 -36.499546051 -26.499996185 -28.499591827 -36.499588013 -25.500000000 -28.499591827 -36.499595642 -24.500000000 -28.499591827 -36.499595642 -23.500000000 -28.499591827 -36.499595642 -22.500000000 -28.499591827 -36.499595642 -21.500000000 -28.499591827 -36.499595642 -20.500000000 -28.499591827 -36.499595642 -19.500000000 -28.499591827 -36.499595642 -18.500000000 -28.499591827 -36.499595642 -17.500000000 -28.499591827 -36.499595642 -16.500000000 -28.499591827 -36.499595642 -15.500000000 -28.499591827 -36.499595642 -14.500000000 -28.499591827 -36.499595642 -13.500000000 -28.499591827 -36.499595642 -12.500000000 -28.499591827 -36.499595642 -11.500000000 -28.499591827 -36.499595642 -10.500000000 -28.499591827 -36.499595642 -9.500000000 -28.499591827 -36.499595642 -8.500000000 -28.499591827 -36.499595642 -7.500000000 -28.499591827 -36.499595642 -6.500000000 -28.499591827 -36.499595642 -5.500000000 -28.499591827 -36.499595642 -4.500000000 -28.499591827 -36.499595642 -3.500000000 -28.499591827 -36.499595642 -2.500000000 -28.499591827 -36.499595642 -1.500000000 -28.499591827 -36.499595642 -0.500000000 -28.499591827 -36.499595642 0.500000000 -28.499591827 -36.499595642 1.500000000 -28.499591827 -36.499595642 2.500000000 -28.499591827 -36.499595642 3.500000000 -28.499591827 -36.499595642 4.500000000 -28.499591827 -36.499595642 5.500000000 -28.499591827 -36.499595642 6.500000000 -28.499591827 -36.499595642 7.500000000 -28.499591827 -36.499595642 8.500000000 -28.499591827 -36.499595642 9.500000000 -28.499591827 -36.499595642 10.500000000 -28.499591827 -36.499595642 11.500000000 -28.499591827 -36.499595642 12.500000000 -28.499591827 -36.499595642 13.500000000 -28.499591827 -36.499595642 14.500000000 -28.499591827 -36.499595642 15.500000000 -28.499591827 -36.499595642 16.500000000 -28.499591827 -36.499595642 17.500000000 -28.499591827 -36.499595642 18.500000000 -28.499591827 -36.499595642 19.500000000 -28.499591827 -36.499595642 20.500000000 -28.499591827 -36.499595642 21.500000000 -28.499591827 -36.499595642 22.500000000 -28.499591827 -36.499595642 23.500000000 -28.499591827 -36.499595642 24.500000000 -28.499591827 -36.499595642 25.499996185 -28.499591827 -36.499588013 26.499954224 -28.499591827 -36.499546051 27.499591827 -28.499591827 -36.499160767 28.497461319 -28.499576569 -36.496910095 29.488346100 -28.499475479 -36.487373352 30.458766937 -28.499073029 -36.456939697 31.383810043 -28.498050690 -36.381031036 32.231597900 -28.496377945 -36.228958130 32.977611542 -28.495168686 -35.976860046 -33.980331421 -27.498950958 -35.980201721 -33.232864380 -27.499221802 -36.232307434 -32.384300232 -27.499622345 -36.383720398 -31.458948135 -27.499858856 -36.458606720 -30.488399506 -27.499938965 -36.488258362 -29.497472763 -27.499954224 -36.497406006 -28.499593735 -27.499954224 -36.499546051 -27.499954224 -27.499954224 -36.499908447 -26.499996185 -27.499954224 -36.499950409 -25.500000000 -27.499954224 -36.499954224 -24.500000000 -27.499954224 -36.499954224 -23.500000000 -27.499954224 -36.499954224 -22.500000000 -27.499954224 -36.499954224 -21.500000000 -27.499954224 -36.499954224 -20.500000000 -27.499954224 -36.499954224 -19.500000000 -27.499954224 -36.499954224 -18.500000000 -27.499954224 -36.499954224 -17.500000000 -27.499954224 -36.499954224 -16.500000000 -27.499954224 -36.499954224 -15.500000000 -27.499954224 -36.499954224 -14.500000000 -27.499954224 -36.499954224 -13.500000000 -27.499954224 -36.499954224 -12.500000000 -27.499954224 -36.499954224 -11.500000000 -27.499954224 -36.499954224 -10.500000000 -27.499954224 -36.499954224 -9.500000000 -27.499954224 -36.499954224 -8.500000000 -27.499954224 -36.499954224 -7.500000000 -27.499954224 -36.499954224 -6.500000000 -27.499954224 -36.499954224 -5.500000000 -27.499954224 -36.499954224 -4.500000000 -27.499954224 -36.499954224 -3.500000000 -27.499954224 -36.499954224 -2.500000000 -27.499954224 -36.499954224 -1.500000000 -27.499954224 -36.499954224 -0.500000000 -27.499954224 -36.499954224 0.500000000 -27.499954224 -36.499954224 1.500000000 -27.499954224 -36.499954224 2.500000000 -27.499954224 -36.499954224 3.500000000 -27.499954224 -36.499954224 4.500000000 -27.499954224 -36.499954224 5.500000000 -27.499954224 -36.499954224 6.500000000 -27.499954224 -36.499954224 7.500000000 -27.499954224 -36.499954224 8.500000000 -27.499954224 -36.499954224 9.500000000 -27.499954224 -36.499954224 10.500000000 -27.499954224 -36.499954224 11.500000000 -27.499954224 -36.499954224 12.500000000 -27.499954224 -36.499954224 13.500000000 -27.499954224 -36.499954224 14.500000000 -27.499954224 -36.499954224 15.500000000 -27.499954224 -36.499954224 16.500000000 -27.499954224 -36.499954224 17.500000000 -27.499954224 -36.499954224 18.500000000 -27.499954224 -36.499954224 19.500000000 -27.499954224 -36.499954224 20.500000000 -27.499954224 -36.499954224 21.500000000 -27.499954224 -36.499954224 22.500000000 -27.499954224 -36.499954224 23.500000000 -27.499954224 -36.499954224 24.500000000 -27.499954224 -36.499954224 25.499996185 -27.499954224 -36.499950409 26.499954224 -27.499954224 -36.499908447 27.499591827 -27.499954224 -36.499542236 28.497470856 -27.499954224 -36.497406006 29.488399506 -27.499938965 -36.488258362 30.458948135 -27.499858856 -36.458606720 31.384298325 -27.499618530 -36.383720398 32.232864380 -27.499225616 -36.232307434 32.980327606 -27.498950958 -35.980201721 -33.980972290 -26.499826431 -35.980957031 -33.233165741 -26.499874115 -36.233070374 -32.384403229 -26.499948502 -36.384307861 -31.458978653 -26.499988556 -36.458930969 -30.488407135 -26.499996185 -36.488391876 -29.497472763 -26.499996185 -36.497467041 -28.499593735 -26.499996185 -36.499588013 -27.499954224 -26.499996185 -36.499950409 -26.499996185 -26.499996185 -36.499992371 -25.500000000 -26.499996185 -36.499996185 -24.500000000 -26.499996185 -36.499996185 -23.500000000 -26.499996185 -36.499996185 -22.500000000 -26.499996185 -36.499996185 -21.500000000 -26.499996185 -36.499996185 -20.500000000 -26.499996185 -36.499996185 -19.500000000 -26.499996185 -36.499996185 -18.500000000 -26.499996185 -36.499996185 -17.500000000 -26.499996185 -36.499996185 -16.500000000 -26.499996185 -36.499996185 -15.500000000 -26.499996185 -36.499996185 -14.500000000 -26.499996185 -36.499996185 -13.500000000 -26.499996185 -36.499996185 -12.500000000 -26.499996185 -36.499996185 -11.500000000 -26.499996185 -36.499996185 -10.500000000 -26.499996185 -36.499996185 -9.500000000 -26.499996185 -36.499996185 -8.500000000 -26.499996185 -36.499996185 -7.500000000 -26.499996185 -36.499996185 -6.500000000 -26.499996185 -36.499996185 -5.500000000 -26.499996185 -36.499996185 -4.500000000 -26.499996185 -36.499996185 -3.500000000 -26.499996185 -36.499996185 -2.500000000 -26.499996185 -36.499996185 -1.500000000 -26.499996185 -36.499996185 -0.500000000 -26.499996185 -36.499996185 0.500000000 -26.499996185 -36.499996185 1.500000000 -26.499996185 -36.499996185 2.500000000 -26.499996185 -36.499996185 3.500000000 -26.499996185 -36.499996185 4.500000000 -26.499996185 -36.499996185 5.500000000 -26.499996185 -36.499996185 6.500000000 -26.499996185 -36.499996185 7.500000000 -26.499996185 -36.499996185 8.500000000 -26.499996185 -36.499996185 9.500000000 -26.499996185 -36.499996185 10.500000000 -26.499996185 -36.499996185 11.500000000 -26.499996185 -36.499996185 12.500000000 -26.499996185 -36.499996185 13.500000000 -26.499996185 -36.499996185 14.500000000 -26.499996185 -36.499996185 15.500000000 -26.499996185 -36.499996185 16.500000000 -26.499996185 -36.499996185 17.500000000 -26.499996185 -36.499996185 18.500000000 -26.499996185 -36.499996185 19.500000000 -26.499996185 -36.499996185 20.500000000 -26.499996185 -36.499996185 21.500000000 -26.499996185 -36.499996185 22.500000000 -26.499996185 -36.499996185 23.500000000 -26.499996185 -36.499996185 24.500000000 -26.499996185 -36.499996185 25.499996185 -26.499996185 -36.499992371 26.499954224 -26.499996185 -36.499950409 27.499591827 -26.499996185 -36.499588013 28.497470856 -26.499996185 -36.497467041 29.488407135 -26.499996185 -36.488391876 30.458978653 -26.499988556 -36.458930969 31.384403229 -26.499948502 -36.384311676 32.233165741 -26.499874115 -36.233074188 32.980976105 -26.499826431 -35.980960846 -33.981086731 -25.499979019 -35.981086731 -33.233215332 -25.499986649 -36.233203888 -32.384422302 -25.499996185 -36.384407043 -31.458978653 -25.500000000 -36.458972931 -30.488407135 -25.500000000 -36.488403320 -29.497472763 -25.500000000 -36.497467041 -28.499593735 -25.500000000 -36.499591827 -27.499954224 -25.500000000 -36.499954224 -26.499996185 -25.500000000 -36.499996185 -25.500000000 -25.500000000 -36.500000000 -24.500000000 -25.500000000 -36.500000000 -23.500000000 -25.500000000 -36.500000000 -22.500000000 -25.500000000 -36.500000000 -21.500000000 -25.500000000 -36.500000000 -20.500000000 -25.500000000 -36.500000000 -19.500000000 -25.500000000 -36.500000000 -18.500000000 -25.500000000 -36.500000000 -17.500000000 -25.500000000 -36.500000000 -16.500000000 -25.500000000 -36.500000000 -15.500000000 -25.500000000 -36.500000000 -14.500000000 -25.500000000 -36.500000000 -13.500000000 -25.500000000 -36.500000000 -12.500000000 -25.500000000 -36.500000000 -11.500000000 -25.500000000 -36.500000000 -10.500000000 -25.500000000 -36.500000000 -9.500000000 -25.500000000 -36.500000000 -8.500000000 -25.500000000 -36.500000000 -7.500000000 -25.500000000 -36.500000000 -6.500000000 -25.500000000 -36.500000000 -5.500000000 -25.500000000 -36.500000000 -4.500000000 -25.500000000 -36.500000000 -3.500000000 -25.500000000 -36.500000000 -2.500000000 -25.500000000 -36.500000000 -1.500000000 -25.500000000 -36.500000000 -0.500000000 -25.500000000 -36.500000000 0.500000000 -25.500000000 -36.500000000 1.500000000 -25.500000000 -36.500000000 2.500000000 -25.500000000 -36.500000000 3.500000000 -25.500000000 -36.500000000 4.500000000 -25.500000000 -36.500000000 5.500000000 -25.500000000 -36.500000000 6.500000000 -25.500000000 -36.500000000 7.500000000 -25.500000000 -36.500000000 8.500000000 -25.500000000 -36.500000000 9.500000000 -25.500000000 -36.500000000 10.500000000 -25.500000000 -36.500000000 11.500000000 -25.500000000 -36.500000000 12.500000000 -25.500000000 -36.500000000 13.500000000 -25.500000000 -36.500000000 14.500000000 -25.500000000 -36.500000000 15.500000000 -25.500000000 -36.500000000 16.500000000 -25.500000000 -36.500000000 17.500000000 -25.500000000 -36.500000000 18.500000000 -25.500000000 -36.500000000 19.500000000 -25.500000000 -36.500000000 20.500000000 -25.500000000 -36.500000000 21.500000000 -25.500000000 -36.500000000 22.500000000 -25.500000000 -36.500000000 23.500000000 -25.500000000 -36.500000000 24.500000000 -25.500000000 -36.500000000 25.499996185 -25.500000000 -36.499996185 26.499954224 -25.500000000 -36.499954224 27.499591827 -25.500000000 -36.499591827 28.497470856 -25.500000000 -36.497474670 29.488407135 -25.500000000 -36.488403320 30.458978653 -25.500000000 -36.458976746 31.384418488 -25.499996185 -36.384407043 32.233215332 -25.499986649 -36.233207703 32.981090546 -25.499975204 -35.981090546 -33.981101990 -24.499998093 -35.981101990 -33.233222961 -24.499998093 -36.233222961 -32.384422302 -24.500000000 -36.384418488 -31.458978653 -24.500000000 -36.458976746 -30.488407135 -24.500000000 -36.488403320 -29.497472763 -24.500000000 -36.497467041 -28.499593735 -24.500000000 -36.499591827 -27.499954224 -24.500000000 -36.499954224 -26.499996185 -24.500000000 -36.499996185 -25.500000000 -24.500000000 -36.500000000 -24.500000000 -24.500000000 -36.500000000 -23.500000000 -24.500000000 -36.500000000 -22.500000000 -24.500000000 -36.500000000 -21.500000000 -24.500000000 -36.500000000 -20.500000000 -24.500000000 -36.500000000 -19.500000000 -24.500000000 -36.500000000 -18.500000000 -24.500000000 -36.500000000 -17.500000000 -24.500000000 -36.500000000 -16.500000000 -24.500000000 -36.500000000 -15.500000000 -24.500000000 -36.500000000 -14.500000000 -24.500000000 -36.500000000 -13.500000000 -24.500000000 -36.500000000 -12.500000000 -24.500000000 -36.500000000 -11.500000000 -24.500000000 -36.500000000 -10.500000000 -24.500000000 -36.500000000 -9.500000000 -24.500000000 -36.500000000 -8.500000000 -24.500000000 -36.500000000 -7.500000000 -24.500000000 -36.500000000 -6.500000000 -24.500000000 -36.500000000 -5.500000000 -24.500000000 -36.500000000 -4.500000000 -24.500000000 -36.500000000 -3.500000000 -24.500000000 -36.500000000 -2.500000000 -24.500000000 -36.500000000 -1.500000000 -24.500000000 -36.500000000 -0.500000000 -24.500000000 -36.500000000 0.500000000 -24.500000000 -36.500000000 1.500000000 -24.500000000 -36.500000000 2.500000000 -24.500000000 -36.500000000 3.500000000 -24.500000000 -36.500000000 4.500000000 -24.500000000 -36.500000000 5.500000000 -24.500000000 -36.500000000 6.500000000 -24.500000000 -36.500000000 7.500000000 -24.500000000 -36.500000000 8.500000000 -24.500000000 -36.500000000 9.500000000 -24.500000000 -36.500000000 10.500000000 -24.500000000 -36.500000000 11.500000000 -24.500000000 -36.500000000 12.500000000 -24.500000000 -36.500000000 13.500000000 -24.500000000 -36.500000000 14.500000000 -24.500000000 -36.500000000 15.500000000 -24.500000000 -36.500000000 16.500000000 -24.500000000 -36.500000000 17.500000000 -24.500000000 -36.500000000 18.500000000 -24.500000000 -36.500000000 19.500000000 -24.500000000 -36.500000000 20.500000000 -24.500000000 -36.500000000 21.500000000 -24.500000000 -36.500000000 22.500000000 -24.500000000 -36.500000000 23.500000000 -24.500000000 -36.500000000 24.500000000 -24.500000000 -36.500000000 25.499996185 -24.500000000 -36.499996185 26.499954224 -24.500000000 -36.499954224 27.499591827 -24.500000000 -36.499591827 28.497470856 -24.500000000 -36.497474670 29.488407135 -24.500000000 -36.488403320 30.458978653 -24.500000000 -36.458980560 31.384418488 -24.500000000 -36.384422302 32.233222961 -24.499998093 -36.233222961 32.981101990 -24.499998093 -35.981101990 -33.981101990 -23.500000000 -35.981101990 -33.233222961 -23.500000000 -36.233222961 -32.384422302 -23.500000000 -36.384418488 -31.458978653 -23.500000000 -36.458976746 -30.488407135 -23.500000000 -36.488403320 -29.497472763 -23.500000000 -36.497467041 -28.499593735 -23.500000000 -36.499591827 -27.499954224 -23.500000000 -36.499954224 -26.499996185 -23.500000000 -36.499996185 -25.500000000 -23.500000000 -36.500000000 -24.500000000 -23.500000000 -36.500000000 -23.500000000 -23.500000000 -36.500000000 -22.500000000 -23.500000000 -36.500000000 -21.500000000 -23.500000000 -36.500000000 -20.500000000 -23.500000000 -36.500000000 -19.500000000 -23.500000000 -36.500000000 -18.500000000 -23.500000000 -36.500000000 -17.500000000 -23.500000000 -36.500000000 -16.500000000 -23.500000000 -36.500000000 -15.500000000 -23.500000000 -36.500000000 -14.500000000 -23.500000000 -36.500000000 -13.500000000 -23.500000000 -36.500000000 -12.500000000 -23.500000000 -36.500000000 -11.500000000 -23.500000000 -36.500000000 -10.500000000 -23.500000000 -36.500000000 -9.500000000 -23.500000000 -36.500000000 -8.500000000 -23.500000000 -36.500000000 -7.500000000 -23.500000000 -36.500000000 -6.500000000 -23.500000000 -36.500000000 -5.500000000 -23.500000000 -36.500000000 -4.500000000 -23.500000000 -36.500000000 -3.500000000 -23.500000000 -36.500000000 -2.500000000 -23.500000000 -36.500000000 -1.500000000 -23.500000000 -36.500000000 -0.500000000 -23.500000000 -36.500000000 0.500000000 -23.500000000 -36.500000000 1.500000000 -23.500000000 -36.500000000 2.500000000 -23.500000000 -36.500000000 3.500000000 -23.500000000 -36.500000000 4.500000000 -23.500000000 -36.500000000 5.500000000 -23.500000000 -36.500000000 6.500000000 -23.500000000 -36.500000000 7.500000000 -23.500000000 -36.500000000 8.500000000 -23.500000000 -36.500000000 9.500000000 -23.500000000 -36.500000000 10.500000000 -23.500000000 -36.500000000 11.500000000 -23.500000000 -36.500000000 12.500000000 -23.500000000 -36.500000000 13.500000000 -23.500000000 -36.500000000 14.500000000 -23.500000000 -36.500000000 15.500000000 -23.500000000 -36.500000000 16.500000000 -23.500000000 -36.500000000 17.500000000 -23.500000000 -36.500000000 18.500000000 -23.500000000 -36.500000000 19.500000000 -23.500000000 -36.500000000 20.500000000 -23.500000000 -36.500000000 21.500000000 -23.500000000 -36.500000000 22.500000000 -23.500000000 -36.500000000 23.500000000 -23.500000000 -36.500000000 24.500000000 -23.500000000 -36.500000000 25.499996185 -23.500000000 -36.499996185 26.499954224 -23.500000000 -36.499954224 27.499591827 -23.500000000 -36.499591827 28.497470856 -23.500000000 -36.497474670 29.488407135 -23.500000000 -36.488403320 30.458978653 -23.500000000 -36.458980560 31.384418488 -23.500000000 -36.384422302 32.233222961 -23.500000000 -36.233226776 32.981101990 -23.500000000 -35.981109619 -33.981101990 -22.500000000 -35.981101990 -33.233222961 -22.500000000 -36.233222961 -32.384422302 -22.500000000 -36.384418488 -31.458978653 -22.500000000 -36.458976746 -30.488407135 -22.500000000 -36.488403320 -29.497472763 -22.500000000 -36.497467041 -28.499593735 -22.500000000 -36.499591827 -27.499954224 -22.500000000 -36.499954224 -26.499996185 -22.500000000 -36.499996185 -25.500000000 -22.500000000 -36.500000000 -24.500000000 -22.500000000 -36.500000000 -23.500000000 -22.500000000 -36.500000000 -22.500000000 -22.500000000 -36.500000000 -21.500000000 -22.500000000 -36.500000000 -20.500000000 -22.500000000 -36.500000000 -19.500000000 -22.500000000 -36.500000000 -18.500000000 -22.500000000 -36.500000000 -17.500000000 -22.500000000 -36.500000000 -16.500000000 -22.500000000 -36.500000000 -15.500000000 -22.500000000 -36.500000000 -14.500000000 -22.500000000 -36.500000000 -13.500000000 -22.500000000 -36.500000000 -12.500000000 -22.500000000 -36.500000000 -11.500000000 -22.500000000 -36.500000000 -10.500000000 -22.500000000 -36.500000000 -9.500000000 -22.500000000 -36.500000000 -8.500000000 -22.500000000 -36.500000000 -7.500000000 -22.500000000 -36.500000000 -6.500000000 -22.500000000 -36.500000000 -5.500000000 -22.500000000 -36.500000000 -4.500000000 -22.500000000 -36.500000000 -3.500000000 -22.500000000 -36.500000000 -2.500000000 -22.500000000 -36.500000000 -1.500000000 -22.500000000 -36.500000000 -0.500000000 -22.500000000 -36.500000000 0.500000000 -22.500000000 -36.500000000 1.500000000 -22.500000000 -36.500000000 2.500000000 -22.500000000 -36.500000000 3.500000000 -22.500000000 -36.500000000 4.500000000 -22.500000000 -36.500000000 5.500000000 -22.500000000 -36.500000000 6.500000000 -22.500000000 -36.500000000 7.500000000 -22.500000000 -36.500000000 8.500000000 -22.500000000 -36.500000000 9.500000000 -22.500000000 -36.500000000 10.500000000 -22.500000000 -36.500000000 11.500000000 -22.500000000 -36.500000000 12.500000000 -22.500000000 -36.500000000 13.500000000 -22.500000000 -36.500000000 14.500000000 -22.500000000 -36.500000000 15.500000000 -22.500000000 -36.500000000 16.500000000 -22.500000000 -36.500000000 17.500000000 -22.500000000 -36.500000000 18.500000000 -22.500000000 -36.500000000 19.500000000 -22.500000000 -36.500000000 20.500000000 -22.500000000 -36.500000000 21.500000000 -22.500000000 -36.500000000 22.500000000 -22.500000000 -36.500000000 23.500000000 -22.500000000 -36.500000000 24.500000000 -22.500000000 -36.500000000 25.499996185 -22.500000000 -36.499996185 26.499954224 -22.500000000 -36.499954224 27.499591827 -22.500000000 -36.499591827 28.497470856 -22.500000000 -36.497474670 29.488407135 -22.500000000 -36.488403320 30.458978653 -22.500000000 -36.458980560 31.384418488 -22.500000000 -36.384422302 32.233222961 -22.500000000 -36.233226776 32.981101990 -22.500000000 -35.981109619 -33.981101990 -21.500000000 -35.981101990 -33.233222961 -21.500000000 -36.233222961 -32.384422302 -21.500000000 -36.384418488 -31.458978653 -21.500000000 -36.458976746 -30.488407135 -21.500000000 -36.488403320 -29.497472763 -21.500000000 -36.497467041 -28.499593735 -21.500000000 -36.499591827 -27.499954224 -21.500000000 -36.499954224 -26.499996185 -21.500000000 -36.499996185 -25.500000000 -21.500000000 -36.500000000 -24.500000000 -21.500000000 -36.500000000 -23.500000000 -21.500000000 -36.500000000 -22.500000000 -21.500000000 -36.500000000 -21.500000000 -21.500000000 -36.500000000 -20.500000000 -21.500000000 -36.500000000 -19.500000000 -21.500000000 -36.500000000 -18.500000000 -21.500000000 -36.500000000 -17.500000000 -21.500000000 -36.500000000 -16.500000000 -21.500000000 -36.500000000 -15.500000000 -21.500000000 -36.500000000 -14.500000000 -21.500000000 -36.500000000 -13.500000000 -21.500000000 -36.500000000 -12.500000000 -21.500000000 -36.500000000 -11.500000000 -21.500000000 -36.500000000 -10.500000000 -21.500000000 -36.500000000 -9.500000000 -21.500000000 -36.500000000 -8.500000000 -21.500000000 -36.500000000 -7.500000000 -21.500000000 -36.500000000 -6.500000000 -21.500000000 -36.500000000 -5.500000000 -21.500000000 -36.500000000 -4.500000000 -21.500000000 -36.500000000 -3.500000000 -21.500000000 -36.500000000 -2.500000000 -21.500000000 -36.500000000 -1.500000000 -21.500000000 -36.500000000 -0.500000000 -21.500000000 -36.500000000 0.500000000 -21.500000000 -36.500000000 1.500000000 -21.500000000 -36.500000000 2.500000000 -21.500000000 -36.500000000 3.500000000 -21.500000000 -36.500000000 4.500000000 -21.500000000 -36.500000000 5.500000000 -21.500000000 -36.500000000 6.500000000 -21.500000000 -36.500000000 7.500000000 -21.500000000 -36.500000000 8.500000000 -21.500000000 -36.500000000 9.500000000 -21.500000000 -36.500000000 10.500000000 -21.500000000 -36.500000000 11.500000000 -21.500000000 -36.500000000 12.500000000 -21.500000000 -36.500000000 13.500000000 -21.500000000 -36.500000000 14.500000000 -21.500000000 -36.500000000 15.500000000 -21.500000000 -36.500000000 16.500000000 -21.500000000 -36.500000000 17.500000000 -21.500000000 -36.500000000 18.500000000 -21.500000000 -36.500000000 19.500000000 -21.500000000 -36.500000000 20.500000000 -21.500000000 -36.500000000 21.500000000 -21.500000000 -36.500000000 22.500000000 -21.500000000 -36.500000000 23.500000000 -21.500000000 -36.500000000 24.500000000 -21.500000000 -36.500000000 25.499996185 -21.500000000 -36.499996185 26.499954224 -21.500000000 -36.499954224 27.499591827 -21.500000000 -36.499591827 28.497470856 -21.500000000 -36.497474670 29.488407135 -21.500000000 -36.488403320 30.458978653 -21.500000000 -36.458980560 31.384418488 -21.500000000 -36.384422302 32.233222961 -21.500000000 -36.233226776 32.981101990 -21.500000000 -35.981109619 -33.981101990 -20.500000000 -35.981101990 -33.233222961 -20.500000000 -36.233222961 -32.384422302 -20.500000000 -36.384418488 -31.458978653 -20.500000000 -36.458976746 -30.488407135 -20.500000000 -36.488403320 -29.497472763 -20.500000000 -36.497467041 -28.499593735 -20.500000000 -36.499591827 -27.499954224 -20.500000000 -36.499954224 -26.499996185 -20.500000000 -36.499996185 -25.500000000 -20.500000000 -36.500000000 -24.500000000 -20.500000000 -36.500000000 -23.500000000 -20.500000000 -36.500000000 -22.500000000 -20.500000000 -36.500000000 -21.500000000 -20.500000000 -36.500000000 -20.500000000 -20.500000000 -36.500000000 -19.500000000 -20.500000000 -36.500000000 -18.500000000 -20.500000000 -36.500000000 -17.500000000 -20.500000000 -36.500000000 -16.500000000 -20.500000000 -36.500000000 -15.500000000 -20.500000000 -36.500000000 -14.500000000 -20.500000000 -36.500000000 -13.500000000 -20.500000000 -36.500000000 -12.500000000 -20.500000000 -36.500000000 -11.500000000 -20.500000000 -36.500000000 -10.500000000 -20.500000000 -36.500000000 -9.500000000 -20.500000000 -36.500000000 -8.500000000 -20.500000000 -36.500000000 -7.500000000 -20.500000000 -36.500000000 -6.500000000 -20.500000000 -36.500000000 -5.500000000 -20.500000000 -36.500000000 -4.500000000 -20.500000000 -36.500000000 -3.500000000 -20.500000000 -36.500000000 -2.500000000 -20.500000000 -36.500000000 -1.500000000 -20.500000000 -36.500000000 -0.500000000 -20.500000000 -36.500000000 0.500000000 -20.500000000 -36.500000000 1.500000000 -20.500000000 -36.500000000 2.500000000 -20.500000000 -36.500000000 3.500000000 -20.500000000 -36.500000000 4.500000000 -20.500000000 -36.500000000 5.500000000 -20.500000000 -36.500000000 6.500000000 -20.500000000 -36.500000000 7.500000000 -20.500000000 -36.500000000 8.500000000 -20.500000000 -36.500000000 9.500000000 -20.500000000 -36.500000000 10.500000000 -20.500000000 -36.500000000 11.500000000 -20.500000000 -36.500000000 12.500000000 -20.500000000 -36.500000000 13.500000000 -20.500000000 -36.500000000 14.500000000 -20.500000000 -36.500000000 15.500000000 -20.500000000 -36.500000000 16.500000000 -20.500000000 -36.500000000 17.500000000 -20.500000000 -36.500000000 18.500000000 -20.500000000 -36.500000000 19.500000000 -20.500000000 -36.500000000 20.500000000 -20.500000000 -36.500000000 21.500000000 -20.500000000 -36.500000000 22.500000000 -20.500000000 -36.500000000 23.500000000 -20.500000000 -36.500000000 24.500000000 -20.500000000 -36.500000000 25.499996185 -20.500000000 -36.499996185 26.499954224 -20.500000000 -36.499954224 27.499591827 -20.500000000 -36.499591827 28.497470856 -20.500000000 -36.497474670 29.488407135 -20.500000000 -36.488403320 30.458978653 -20.500000000 -36.458980560 31.384418488 -20.500000000 -36.384422302 32.233222961 -20.500000000 -36.233226776 32.981101990 -20.500000000 -35.981109619 -33.981101990 -19.500000000 -35.981101990 -33.233222961 -19.500000000 -36.233222961 -32.384422302 -19.500000000 -36.384418488 -31.458978653 -19.500000000 -36.458976746 -30.488407135 -19.500000000 -36.488403320 -29.497472763 -19.500000000 -36.497467041 -28.499593735 -19.500000000 -36.499591827 -27.499954224 -19.500000000 -36.499954224 -26.499996185 -19.500000000 -36.499996185 -25.500000000 -19.500000000 -36.500000000 -24.500000000 -19.500000000 -36.500000000 -23.500000000 -19.500000000 -36.500000000 -22.500000000 -19.500000000 -36.500000000 -21.500000000 -19.500000000 -36.500000000 -20.500000000 -19.500000000 -36.500000000 -19.500000000 -19.500000000 -36.500000000 -18.500000000 -19.500000000 -36.500000000 -17.500000000 -19.500000000 -36.500000000 -16.500000000 -19.500000000 -36.500000000 -15.500000000 -19.500000000 -36.500000000 -14.500000000 -19.500000000 -36.500000000 -13.500000000 -19.500000000 -36.500000000 -12.500000000 -19.500000000 -36.500000000 -11.500000000 -19.500000000 -36.500000000 -10.500000000 -19.500000000 -36.500000000 -9.500000000 -19.500000000 -36.500000000 -8.500000000 -19.500000000 -36.500000000 -7.500000000 -19.500000000 -36.500000000 -6.500000000 -19.500000000 -36.500000000 -5.500000000 -19.500000000 -36.500000000 -4.500000000 -19.500000000 -36.500000000 -3.500000000 -19.500000000 -36.500000000 -2.500000000 -19.500000000 -36.500000000 -1.500000000 -19.500000000 -36.500000000 -0.500000000 -19.500000000 -36.500000000 0.500000000 -19.500000000 -36.500000000 1.500000000 -19.500000000 -36.500000000 2.500000000 -19.500000000 -36.500000000 3.500000000 -19.500000000 -36.500000000 4.500000000 -19.500000000 -36.500000000 5.500000000 -19.500000000 -36.500000000 6.500000000 -19.500000000 -36.500000000 7.500000000 -19.500000000 -36.500000000 8.500000000 -19.500000000 -36.500000000 9.500000000 -19.500000000 -36.500000000 10.500000000 -19.500000000 -36.500000000 11.500000000 -19.500000000 -36.500000000 12.500000000 -19.500000000 -36.500000000 13.500000000 -19.500000000 -36.500000000 14.500000000 -19.500000000 -36.500000000 15.500000000 -19.500000000 -36.500000000 16.500000000 -19.500000000 -36.500000000 17.500000000 -19.500000000 -36.500000000 18.500000000 -19.500000000 -36.500000000 19.500000000 -19.500000000 -36.500000000 20.500000000 -19.500000000 -36.500000000 21.500000000 -19.500000000 -36.500000000 22.500000000 -19.500000000 -36.500000000 23.500000000 -19.500000000 -36.500000000 24.500000000 -19.500000000 -36.500000000 25.499996185 -19.500000000 -36.499996185 26.499954224 -19.500000000 -36.499954224 27.499591827 -19.500000000 -36.499591827 28.497470856 -19.500000000 -36.497474670 29.488407135 -19.500000000 -36.488403320 30.458978653 -19.500000000 -36.458980560 31.384418488 -19.500000000 -36.384422302 32.233222961 -19.500000000 -36.233226776 32.981101990 -19.500000000 -35.981109619 -33.981101990 -18.500000000 -35.981101990 -33.233222961 -18.500000000 -36.233222961 -32.384422302 -18.500000000 -36.384418488 -31.458978653 -18.500000000 -36.458976746 -30.488407135 -18.500000000 -36.488403320 -29.497472763 -18.500000000 -36.497467041 -28.499593735 -18.500000000 -36.499591827 -27.499954224 -18.500000000 -36.499954224 -26.499996185 -18.500000000 -36.499996185 -25.500000000 -18.500000000 -36.500000000 -24.500000000 -18.500000000 -36.500000000 -23.500000000 -18.500000000 -36.500000000 -22.500000000 -18.500000000 -36.500000000 -21.500000000 -18.500000000 -36.500000000 -20.500000000 -18.500000000 -36.500000000 -19.500000000 -18.500000000 -36.500000000 -18.500000000 -18.500000000 -36.500000000 -17.500000000 -18.500000000 -36.500000000 -16.500000000 -18.500000000 -36.500000000 -15.500000000 -18.500000000 -36.500000000 -14.500000000 -18.500000000 -36.500000000 -13.500000000 -18.500000000 -36.500000000 -12.500000000 -18.500000000 -36.500000000 -11.500000000 -18.500000000 -36.500000000 -10.500000000 -18.500000000 -36.500000000 -9.500000000 -18.500000000 -36.500000000 -8.500000000 -18.500000000 -36.500000000 -7.500000000 -18.500000000 -36.500000000 -6.500000000 -18.500000000 -36.500000000 -5.500000000 -18.500000000 -36.500000000 -4.500000000 -18.500000000 -36.500000000 -3.500000000 -18.500000000 -36.500000000 -2.500000000 -18.500000000 -36.500000000 -1.500000000 -18.500000000 -36.500000000 -0.500000000 -18.500000000 -36.500000000 0.500000000 -18.500000000 -36.500000000 1.500000000 -18.500000000 -36.500000000 2.500000000 -18.500000000 -36.500000000 3.500000000 -18.500000000 -36.500000000 4.500000000 -18.500000000 -36.500000000 5.500000000 -18.500000000 -36.500000000 6.500000000 -18.500000000 -36.500000000 7.500000000 -18.500000000 -36.500000000 8.500000000 -18.500000000 -36.500000000 9.500000000 -18.500000000 -36.500000000 10.500000000 -18.500000000 -36.500000000 11.500000000 -18.500000000 -36.500000000 12.500000000 -18.500000000 -36.500000000 13.500000000 -18.500000000 -36.500000000 14.500000000 -18.500000000 -36.500000000 15.500000000 -18.500000000 -36.500000000 16.500000000 -18.500000000 -36.500000000 17.500000000 -18.500000000 -36.500000000 18.500000000 -18.500000000 -36.500000000 19.500000000 -18.500000000 -36.500000000 20.500000000 -18.500000000 -36.500000000 21.500000000 -18.500000000 -36.500000000 22.500000000 -18.500000000 -36.500000000 23.500000000 -18.500000000 -36.500000000 24.500000000 -18.500000000 -36.500000000 25.499996185 -18.500000000 -36.499996185 26.499954224 -18.500000000 -36.499954224 27.499591827 -18.500000000 -36.499591827 28.497470856 -18.500000000 -36.497474670 29.488407135 -18.500000000 -36.488403320 30.458978653 -18.500000000 -36.458980560 31.384418488 -18.500000000 -36.384422302 32.233222961 -18.500000000 -36.233226776 32.981101990 -18.500000000 -35.981109619 -33.981101990 -17.500000000 -35.981101990 -33.233222961 -17.500000000 -36.233222961 -32.384422302 -17.500000000 -36.384418488 -31.458978653 -17.500000000 -36.458976746 -30.488407135 -17.500000000 -36.488403320 -29.497472763 -17.500000000 -36.497467041 -28.499593735 -17.500000000 -36.499591827 -27.499954224 -17.500000000 -36.499954224 -26.499996185 -17.500000000 -36.499996185 -25.500000000 -17.500000000 -36.500000000 -24.500000000 -17.500000000 -36.500000000 -23.500000000 -17.500000000 -36.500000000 -22.500000000 -17.500000000 -36.500000000 -21.500000000 -17.500000000 -36.500000000 -20.500000000 -17.500000000 -36.500000000 -19.500000000 -17.500000000 -36.500000000 -18.500000000 -17.500000000 -36.500000000 -17.500000000 -17.500000000 -36.500000000 -16.500000000 -17.500000000 -36.500000000 -15.500000000 -17.500000000 -36.500000000 -14.500000000 -17.500000000 -36.500000000 -13.500000000 -17.500000000 -36.500000000 -12.500000000 -17.500000000 -36.500000000 -11.500000000 -17.500000000 -36.500000000 -10.500000000 -17.500000000 -36.500000000 -9.500000000 -17.500000000 -36.500000000 -8.500000000 -17.500000000 -36.500000000 -7.500000000 -17.500000000 -36.500000000 -6.500000000 -17.500000000 -36.500000000 -5.500000000 -17.500000000 -36.500000000 -4.500000000 -17.500000000 -36.500000000 -3.500000000 -17.500000000 -36.500000000 -2.500000000 -17.500000000 -36.500000000 -1.500000000 -17.500000000 -36.500000000 -0.500000000 -17.500000000 -36.500000000 0.500000000 -17.500000000 -36.500000000 1.500000000 -17.500000000 -36.500000000 2.500000000 -17.500000000 -36.500000000 3.500000000 -17.500000000 -36.500000000 4.500000000 -17.500000000 -36.500000000 5.500000000 -17.500000000 -36.500000000 6.500000000 -17.500000000 -36.500000000 7.500000000 -17.500000000 -36.500000000 8.500000000 -17.500000000 -36.500000000 9.500000000 -17.500000000 -36.500000000 10.500000000 -17.500000000 -36.500000000 11.500000000 -17.500000000 -36.500000000 12.500000000 -17.500000000 -36.500000000 13.500000000 -17.500000000 -36.500000000 14.500000000 -17.500000000 -36.500000000 15.500000000 -17.500000000 -36.500000000 16.500000000 -17.500000000 -36.500000000 17.500000000 -17.500000000 -36.500000000 18.500000000 -17.500000000 -36.500000000 19.500000000 -17.500000000 -36.500000000 20.500000000 -17.500000000 -36.500000000 21.500000000 -17.500000000 -36.500000000 22.500000000 -17.500000000 -36.500000000 23.500000000 -17.500000000 -36.500000000 24.500000000 -17.500000000 -36.500000000 25.499996185 -17.500000000 -36.499996185 26.499954224 -17.500000000 -36.499954224 27.499591827 -17.500000000 -36.499591827 28.497470856 -17.500000000 -36.497474670 29.488407135 -17.500000000 -36.488403320 30.458978653 -17.500000000 -36.458980560 31.384418488 -17.500000000 -36.384422302 32.233222961 -17.500000000 -36.233226776 32.981101990 -17.500000000 -35.981109619 -33.981101990 -16.500000000 -35.981101990 -33.233222961 -16.500000000 -36.233222961 -32.384422302 -16.500000000 -36.384418488 -31.458978653 -16.500000000 -36.458976746 -30.488407135 -16.500000000 -36.488403320 -29.497472763 -16.500000000 -36.497467041 -28.499593735 -16.500000000 -36.499591827 -27.499954224 -16.500000000 -36.499954224 -26.499996185 -16.500000000 -36.499996185 -25.500000000 -16.500000000 -36.500000000 -24.500000000 -16.500000000 -36.500000000 -23.500000000 -16.500000000 -36.500000000 -22.500000000 -16.500000000 -36.500000000 -21.500000000 -16.500000000 -36.500000000 -20.500000000 -16.500000000 -36.500000000 -19.500000000 -16.500000000 -36.500000000 -18.500000000 -16.500000000 -36.500000000 -17.500000000 -16.500000000 -36.500000000 -16.500000000 -16.500000000 -36.500000000 -15.500000000 -16.500000000 -36.500000000 -14.500000000 -16.500000000 -36.500000000 -13.500000000 -16.500000000 -36.500000000 -12.500000000 -16.500000000 -36.500000000 -11.500000000 -16.500000000 -36.500000000 -10.500000000 -16.500000000 -36.500000000 -9.500000000 -16.500000000 -36.500000000 -8.500000000 -16.500000000 -36.500000000 -7.500000000 -16.500000000 -36.500000000 -6.500000000 -16.500000000 -36.500000000 -5.500000000 -16.500000000 -36.500000000 -4.500000000 -16.500000000 -36.500000000 -3.500000000 -16.500000000 -36.500000000 -2.500000000 -16.500000000 -36.500000000 -1.500000000 -16.500000000 -36.500000000 -0.500000000 -16.500000000 -36.500000000 0.500000000 -16.500000000 -36.500000000 1.500000000 -16.500000000 -36.500000000 2.500000000 -16.500000000 -36.500000000 3.500000000 -16.500000000 -36.500000000 4.500000000 -16.500000000 -36.500000000 5.500000000 -16.500000000 -36.500000000 6.500000000 -16.500000000 -36.500000000 7.500000000 -16.500000000 -36.500000000 8.500000000 -16.500000000 -36.500000000 9.500000000 -16.500000000 -36.500000000 10.500000000 -16.500000000 -36.500000000 11.500000000 -16.500000000 -36.500000000 12.500000000 -16.500000000 -36.500000000 13.500000000 -16.500000000 -36.500000000 14.500000000 -16.500000000 -36.500000000 15.500000000 -16.500000000 -36.500000000 16.500000000 -16.500000000 -36.500000000 17.500000000 -16.500000000 -36.500000000 18.500000000 -16.500000000 -36.500000000 19.500000000 -16.500000000 -36.500000000 20.500000000 -16.500000000 -36.500000000 21.500000000 -16.500000000 -36.500000000 22.500000000 -16.500000000 -36.500000000 23.500000000 -16.500000000 -36.500000000 24.500000000 -16.500000000 -36.500000000 25.499996185 -16.500000000 -36.499996185 26.499954224 -16.500000000 -36.499954224 27.499591827 -16.500000000 -36.499591827 28.497470856 -16.500000000 -36.497474670 29.488407135 -16.500000000 -36.488403320 30.458978653 -16.500000000 -36.458980560 31.384418488 -16.500000000 -36.384422302 32.233222961 -16.500000000 -36.233226776 32.981101990 -16.500000000 -35.981109619 -33.981101990 -15.500000000 -35.981101990 -33.233222961 -15.500000000 -36.233222961 -32.384422302 -15.500000000 -36.384418488 -31.458978653 -15.500000000 -36.458976746 -30.488407135 -15.500000000 -36.488403320 -29.497472763 -15.500000000 -36.497467041 -28.499593735 -15.500000000 -36.499591827 -27.499954224 -15.500000000 -36.499954224 -26.499996185 -15.500000000 -36.499996185 -25.500000000 -15.500000000 -36.500000000 -24.500000000 -15.500000000 -36.500000000 -23.500000000 -15.500000000 -36.500000000 -22.500000000 -15.500000000 -36.500000000 -21.500000000 -15.500000000 -36.500000000 -20.500000000 -15.500000000 -36.500000000 -19.500000000 -15.500000000 -36.500000000 -18.500000000 -15.500000000 -36.500000000 -17.500000000 -15.500000000 -36.500000000 -16.500000000 -15.500000000 -36.500000000 -15.500000000 -15.500000000 -36.500000000 -14.500000000 -15.500000000 -36.500000000 -13.500000000 -15.500000000 -36.500000000 -12.500000000 -15.500000000 -36.500000000 -11.500000000 -15.500000000 -36.500000000 -10.500000000 -15.500000000 -36.500000000 -9.500000000 -15.500000000 -36.500000000 -8.500000000 -15.500000000 -36.500000000 -7.500000000 -15.500000000 -36.500000000 -6.500000000 -15.500000000 -36.500000000 -5.500000000 -15.500000000 -36.500000000 -4.500000000 -15.500000000 -36.500000000 -3.500000000 -15.500000000 -36.500000000 -2.500000000 -15.500000000 -36.500000000 -1.500000000 -15.500000000 -36.500000000 -0.500000000 -15.500000000 -36.500000000 0.500000000 -15.500000000 -36.500000000 1.500000000 -15.500000000 -36.500000000 2.500000000 -15.500000000 -36.500000000 3.500000000 -15.500000000 -36.500000000 4.500000000 -15.500000000 -36.500000000 5.500000000 -15.500000000 -36.500000000 6.500000000 -15.500000000 -36.500000000 7.500000000 -15.500000000 -36.500000000 8.500000000 -15.500000000 -36.500000000 9.500000000 -15.500000000 -36.500000000 10.500000000 -15.500000000 -36.500000000 11.500000000 -15.500000000 -36.500000000 12.500000000 -15.500000000 -36.500000000 13.500000000 -15.500000000 -36.500000000 14.500000000 -15.500000000 -36.500000000 15.500000000 -15.500000000 -36.500000000 16.500000000 -15.500000000 -36.500000000 17.500000000 -15.500000000 -36.500000000 18.500000000 -15.500000000 -36.500000000 19.500000000 -15.500000000 -36.500000000 20.500000000 -15.500000000 -36.500000000 21.500000000 -15.500000000 -36.500000000 22.500000000 -15.500000000 -36.500000000 23.500000000 -15.500000000 -36.500000000 24.500000000 -15.500000000 -36.500000000 25.499996185 -15.500000000 -36.499996185 26.499954224 -15.500000000 -36.499954224 27.499591827 -15.500000000 -36.499591827 28.497470856 -15.500000000 -36.497474670 29.488407135 -15.500000000 -36.488403320 30.458978653 -15.500000000 -36.458980560 31.384418488 -15.500000000 -36.384422302 32.233222961 -15.500000000 -36.233226776 32.981101990 -15.500000000 -35.981109619 -33.981101990 -14.500000000 -35.981101990 -33.233222961 -14.500000000 -36.233222961 -32.384422302 -14.500000000 -36.384418488 -31.458978653 -14.500000000 -36.458976746 -30.488407135 -14.500000000 -36.488403320 -29.497472763 -14.500000000 -36.497467041 -28.499593735 -14.500000000 -36.499591827 -27.499954224 -14.500000000 -36.499954224 -26.499996185 -14.500000000 -36.499996185 -25.500000000 -14.500000000 -36.500000000 -24.500000000 -14.500000000 -36.500000000 -23.500000000 -14.500000000 -36.500000000 -22.500000000 -14.500000000 -36.500000000 -21.500000000 -14.500000000 -36.500000000 -20.500000000 -14.500000000 -36.500000000 -19.500000000 -14.500000000 -36.500000000 -18.500000000 -14.500000000 -36.500000000 -17.500000000 -14.500000000 -36.500000000 -16.500000000 -14.500000000 -36.500000000 -15.500000000 -14.500000000 -36.500000000 -14.500000000 -14.500000000 -36.500000000 -13.500000000 -14.500000000 -36.500000000 -12.500000000 -14.500000000 -36.500000000 -11.500000000 -14.500000000 -36.500000000 -10.500000000 -14.500000000 -36.500000000 -9.500000000 -14.500000000 -36.500000000 -8.500000000 -14.500000000 -36.500000000 -7.500000000 -14.500000000 -36.500000000 -6.500000000 -14.500000000 -36.500000000 -5.500000000 -14.500000000 -36.500000000 -4.500000000 -14.500000000 -36.500000000 -3.500000000 -14.500000000 -36.500000000 -2.500000000 -14.500000000 -36.500000000 -1.500000000 -14.500000000 -36.500000000 -0.500000000 -14.500000000 -36.500000000 0.500000000 -14.500000000 -36.500000000 1.500000000 -14.500000000 -36.500000000 2.500000000 -14.500000000 -36.500000000 3.500000000 -14.500000000 -36.500000000 4.500000000 -14.500000000 -36.500000000 5.500000000 -14.500000000 -36.500000000 6.500000000 -14.500000000 -36.500000000 7.500000000 -14.500000000 -36.500000000 8.500000000 -14.500000000 -36.500000000 9.500000000 -14.500000000 -36.500000000 10.500000000 -14.500000000 -36.500000000 11.500000000 -14.500000000 -36.500000000 12.500000000 -14.500000000 -36.500000000 13.500000000 -14.500000000 -36.500000000 14.500000000 -14.500000000 -36.500000000 15.500000000 -14.500000000 -36.500000000 16.500000000 -14.500000000 -36.500000000 17.500000000 -14.500000000 -36.500000000 18.500000000 -14.500000000 -36.500000000 19.500000000 -14.500000000 -36.500000000 20.500000000 -14.500000000 -36.500000000 21.500000000 -14.500000000 -36.500000000 22.500000000 -14.500000000 -36.500000000 23.500000000 -14.500000000 -36.500000000 24.500000000 -14.500000000 -36.500000000 25.499996185 -14.500000000 -36.499996185 26.499954224 -14.500000000 -36.499954224 27.499591827 -14.500000000 -36.499591827 28.497470856 -14.500000000 -36.497474670 29.488407135 -14.500000000 -36.488403320 30.458978653 -14.500000000 -36.458980560 31.384418488 -14.500000000 -36.384422302 32.233222961 -14.500000000 -36.233226776 32.981101990 -14.500000000 -35.981109619 -33.981101990 -13.500000000 -35.981101990 -33.233222961 -13.500000000 -36.233222961 -32.384422302 -13.500000000 -36.384418488 -31.458978653 -13.500000000 -36.458976746 -30.488407135 -13.500000000 -36.488403320 -29.497472763 -13.500000000 -36.497467041 -28.499593735 -13.500000000 -36.499591827 -27.499954224 -13.500000000 -36.499954224 -26.499996185 -13.500000000 -36.499996185 -25.500000000 -13.500000000 -36.500000000 -24.500000000 -13.500000000 -36.500000000 -23.500000000 -13.500000000 -36.500000000 -22.500000000 -13.500000000 -36.500000000 -21.500000000 -13.500000000 -36.500000000 -20.500000000 -13.500000000 -36.500000000 -19.500000000 -13.500000000 -36.500000000 -18.500000000 -13.500000000 -36.500000000 -17.500000000 -13.500000000 -36.500000000 -16.500000000 -13.500000000 -36.500000000 -15.500000000 -13.500000000 -36.500000000 -14.500000000 -13.500000000 -36.500000000 -13.500000000 -13.500000000 -36.500000000 -12.500000000 -13.500000000 -36.500000000 -11.500000000 -13.500000000 -36.500000000 -10.500000000 -13.500000000 -36.500000000 -9.500000000 -13.500000000 -36.500000000 -8.500000000 -13.500000000 -36.500000000 -7.500000000 -13.500000000 -36.500000000 -6.500000000 -13.500000000 -36.500000000 -5.500000000 -13.500000000 -36.500000000 -4.500000000 -13.500000000 -36.500000000 -3.500000000 -13.500000000 -36.500000000 -2.500000000 -13.500000000 -36.500000000 -1.500000000 -13.500000000 -36.500000000 -0.500000000 -13.500000000 -36.500000000 0.500000000 -13.500000000 -36.500000000 1.500000000 -13.500000000 -36.500000000 2.500000000 -13.500000000 -36.500000000 3.500000000 -13.500000000 -36.500000000 4.500000000 -13.500000000 -36.500000000 5.500000000 -13.500000000 -36.500000000 6.500000000 -13.500000000 -36.500000000 7.500000000 -13.500000000 -36.500000000 8.500000000 -13.500000000 -36.500000000 9.500000000 -13.500000000 -36.500000000 10.500000000 -13.500000000 -36.500000000 11.500000000 -13.500000000 -36.500000000 12.500000000 -13.500000000 -36.500000000 13.500000000 -13.500000000 -36.500000000 14.500000000 -13.500000000 -36.500000000 15.500000000 -13.500000000 -36.500000000 16.500000000 -13.500000000 -36.500000000 17.500000000 -13.500000000 -36.500000000 18.500000000 -13.500000000 -36.500000000 19.500000000 -13.500000000 -36.500000000 20.500000000 -13.500000000 -36.500000000 21.500000000 -13.500000000 -36.500000000 22.500000000 -13.500000000 -36.500000000 23.500000000 -13.500000000 -36.500000000 24.500000000 -13.500000000 -36.500000000 25.499996185 -13.500000000 -36.499996185 26.499954224 -13.500000000 -36.499954224 27.499591827 -13.500000000 -36.499591827 28.497470856 -13.500000000 -36.497474670 29.488407135 -13.500000000 -36.488403320 30.458978653 -13.500000000 -36.458980560 31.384418488 -13.500000000 -36.384422302 32.233222961 -13.500000000 -36.233226776 32.981101990 -13.500000000 -35.981109619 -33.981101990 -12.500000000 -35.981101990 -33.233222961 -12.500000000 -36.233222961 -32.384422302 -12.500000000 -36.384418488 -31.458978653 -12.500000000 -36.458976746 -30.488407135 -12.500000000 -36.488403320 -29.497472763 -12.500000000 -36.497467041 -28.499593735 -12.500000000 -36.499591827 -27.499954224 -12.500000000 -36.499954224 -26.499996185 -12.500000000 -36.499996185 -25.500000000 -12.500000000 -36.500000000 -24.500000000 -12.500000000 -36.500000000 -23.500000000 -12.500000000 -36.500000000 -22.500000000 -12.500000000 -36.500000000 -21.500000000 -12.500000000 -36.500000000 -20.500000000 -12.500000000 -36.500000000 -19.500000000 -12.500000000 -36.500000000 -18.500000000 -12.500000000 -36.500000000 -17.500000000 -12.500000000 -36.500000000 -16.500000000 -12.500000000 -36.500000000 -15.500000000 -12.500000000 -36.500000000 -14.500000000 -12.500000000 -36.500000000 -13.500000000 -12.500000000 -36.500000000 -12.500000000 -12.500000000 -36.500000000 -11.500000000 -12.500000000 -36.500000000 -10.500000000 -12.500000000 -36.500000000 -9.500000000 -12.500000000 -36.500000000 -8.500000000 -12.500000000 -36.500000000 -7.500000000 -12.500000000 -36.500000000 -6.500000000 -12.500000000 -36.500000000 -5.500000000 -12.500000000 -36.500000000 -4.500000000 -12.500000000 -36.500000000 -3.500000000 -12.500000000 -36.500000000 -2.500000000 -12.500000000 -36.500000000 -1.500000000 -12.500000000 -36.500000000 -0.500000000 -12.500000000 -36.500000000 0.500000000 -12.500000000 -36.500000000 1.500000000 -12.500000000 -36.500000000 2.500000000 -12.500000000 -36.500000000 3.500000000 -12.500000000 -36.500000000 4.500000000 -12.500000000 -36.500000000 5.500000000 -12.500000000 -36.500000000 6.500000000 -12.500000000 -36.500000000 7.500000000 -12.500000000 -36.500000000 8.500000000 -12.500000000 -36.500000000 9.500000000 -12.500000000 -36.500000000 10.500000000 -12.500000000 -36.500000000 11.500000000 -12.500000000 -36.500000000 12.500000000 -12.500000000 -36.500000000 13.500000000 -12.500000000 -36.500000000 14.500000000 -12.500000000 -36.500000000 15.500000000 -12.500000000 -36.500000000 16.500000000 -12.500000000 -36.500000000 17.500000000 -12.500000000 -36.500000000 18.500000000 -12.500000000 -36.500000000 19.500000000 -12.500000000 -36.500000000 20.500000000 -12.500000000 -36.500000000 21.500000000 -12.500000000 -36.500000000 22.500000000 -12.500000000 -36.500000000 23.500000000 -12.500000000 -36.500000000 24.500000000 -12.500000000 -36.500000000 25.499996185 -12.500000000 -36.499996185 26.499954224 -12.500000000 -36.499954224 27.499591827 -12.500000000 -36.499591827 28.497470856 -12.500000000 -36.497474670 29.488407135 -12.500000000 -36.488403320 30.458978653 -12.500000000 -36.458980560 31.384418488 -12.500000000 -36.384422302 32.233222961 -12.500000000 -36.233226776 32.981101990 -12.500000000 -35.981109619 -33.981101990 -11.500000000 -35.981101990 -33.233222961 -11.500000000 -36.233222961 -32.384422302 -11.500000000 -36.384418488 -31.458978653 -11.500000000 -36.458976746 -30.488407135 -11.500000000 -36.488403320 -29.497472763 -11.500000000 -36.497467041 -28.499593735 -11.500000000 -36.499591827 -27.499954224 -11.500000000 -36.499954224 -26.499996185 -11.500000000 -36.499996185 -25.500000000 -11.500000000 -36.500000000 -24.500000000 -11.500000000 -36.500000000 -23.500000000 -11.500000000 -36.500000000 -22.500000000 -11.500000000 -36.500000000 -21.500000000 -11.500000000 -36.500000000 -20.500000000 -11.500000000 -36.500000000 -19.500000000 -11.500000000 -36.500000000 -18.500000000 -11.500000000 -36.500000000 -17.500000000 -11.500000000 -36.500000000 -16.500000000 -11.500000000 -36.500000000 -15.500000000 -11.500000000 -36.500000000 -14.500000000 -11.500000000 -36.500000000 -13.500000000 -11.500000000 -36.500000000 -12.500000000 -11.500000000 -36.500000000 -11.500000000 -11.500000000 -36.500000000 -10.500000000 -11.500000000 -36.500000000 -9.500000000 -11.500000000 -36.500000000 -8.500000000 -11.500000000 -36.500000000 -7.500000000 -11.500000000 -36.500000000 -6.500000000 -11.500000000 -36.500000000 -5.500000000 -11.500000000 -36.500000000 -4.500000000 -11.500000000 -36.500000000 -3.500000000 -11.500000000 -36.500000000 -2.500000000 -11.500000000 -36.500000000 -1.500000000 -11.500000000 -36.500000000 -0.500000000 -11.500000000 -36.500000000 0.500000000 -11.500000000 -36.500000000 1.500000000 -11.500000000 -36.500000000 2.500000000 -11.500000000 -36.500000000 3.500000000 -11.500000000 -36.500000000 4.500000000 -11.500000000 -36.500000000 5.500000000 -11.500000000 -36.500000000 6.500000000 -11.500000000 -36.500000000 7.500000000 -11.500000000 -36.500000000 8.500000000 -11.500000000 -36.500000000 9.500000000 -11.500000000 -36.500000000 10.500000000 -11.500000000 -36.500000000 11.500000000 -11.500000000 -36.500000000 12.500000000 -11.500000000 -36.500000000 13.500000000 -11.500000000 -36.500000000 14.500000000 -11.500000000 -36.500000000 15.500000000 -11.500000000 -36.500000000 16.500000000 -11.500000000 -36.500000000 17.500000000 -11.500000000 -36.500000000 18.500000000 -11.500000000 -36.500000000 19.500000000 -11.500000000 -36.500000000 20.500000000 -11.500000000 -36.500000000 21.500000000 -11.500000000 -36.500000000 22.500000000 -11.500000000 -36.500000000 23.500000000 -11.500000000 -36.500000000 24.500000000 -11.500000000 -36.500000000 25.499996185 -11.500000000 -36.499996185 26.499954224 -11.500000000 -36.499954224 27.499591827 -11.500000000 -36.499591827 28.497470856 -11.500000000 -36.497474670 29.488407135 -11.500000000 -36.488403320 30.458978653 -11.500000000 -36.458980560 31.384418488 -11.500000000 -36.384422302 32.233222961 -11.500000000 -36.233226776 32.981101990 -11.500000000 -35.981109619 -33.981101990 -10.500000000 -35.981101990 -33.233222961 -10.500000000 -36.233222961 -32.384422302 -10.500000000 -36.384418488 -31.458978653 -10.500000000 -36.458976746 -30.488407135 -10.500000000 -36.488403320 -29.497472763 -10.500000000 -36.497467041 -28.499593735 -10.500000000 -36.499591827 -27.499954224 -10.500000000 -36.499954224 -26.499996185 -10.500000000 -36.499996185 -25.500000000 -10.500000000 -36.500000000 -24.500000000 -10.500000000 -36.500000000 -23.500000000 -10.500000000 -36.500000000 -22.500000000 -10.500000000 -36.500000000 -21.500000000 -10.500000000 -36.500000000 -20.500000000 -10.500000000 -36.500000000 -19.500000000 -10.500000000 -36.500000000 -18.500000000 -10.500000000 -36.500000000 -17.500000000 -10.500000000 -36.500000000 -16.500000000 -10.500000000 -36.500000000 -15.500000000 -10.500000000 -36.500000000 -14.500000000 -10.500000000 -36.500000000 -13.500000000 -10.500000000 -36.500000000 -12.500000000 -10.500000000 -36.500000000 -11.500000000 -10.500000000 -36.500000000 -10.500000000 -10.500000000 -36.500000000 -9.500000000 -10.500000000 -36.500000000 -8.500000000 -10.500000000 -36.500000000 -7.500000000 -10.500000000 -36.500000000 -6.500000000 -10.500000000 -36.500000000 -5.500000000 -10.500000000 -36.500000000 -4.500000000 -10.500000000 -36.500000000 -3.500000000 -10.500000000 -36.500000000 -2.500000000 -10.500000000 -36.500000000 -1.500000000 -10.500000000 -36.500000000 -0.500000000 -10.500000000 -36.500000000 0.500000000 -10.500000000 -36.500000000 1.500000000 -10.500000000 -36.500000000 2.500000000 -10.500000000 -36.500000000 3.500000000 -10.500000000 -36.500000000 4.500000000 -10.500000000 -36.500000000 5.500000000 -10.500000000 -36.500000000 6.500000000 -10.500000000 -36.500000000 7.500000000 -10.500000000 -36.500000000 8.500000000 -10.500000000 -36.500000000 9.500000000 -10.500000000 -36.500000000 10.500000000 -10.500000000 -36.500000000 11.500000000 -10.500000000 -36.500000000 12.500000000 -10.500000000 -36.500000000 13.500000000 -10.500000000 -36.500000000 14.500000000 -10.500000000 -36.500000000 15.500000000 -10.500000000 -36.500000000 16.500000000 -10.500000000 -36.500000000 17.500000000 -10.500000000 -36.500000000 18.500000000 -10.500000000 -36.500000000 19.500000000 -10.500000000 -36.500000000 20.500000000 -10.500000000 -36.500000000 21.500000000 -10.500000000 -36.500000000 22.500000000 -10.500000000 -36.500000000 23.500000000 -10.500000000 -36.500000000 24.500000000 -10.500000000 -36.500000000 25.499996185 -10.500000000 -36.499996185 26.499954224 -10.500000000 -36.499954224 27.499591827 -10.500000000 -36.499591827 28.497470856 -10.500000000 -36.497474670 29.488407135 -10.500000000 -36.488403320 30.458978653 -10.500000000 -36.458980560 31.384418488 -10.500000000 -36.384422302 32.233222961 -10.500000000 -36.233226776 32.981101990 -10.500000000 -35.981109619 -33.981101990 -9.500000000 -35.981101990 -33.233222961 -9.500000000 -36.233222961 -32.384422302 -9.500000000 -36.384418488 -31.458978653 -9.500000000 -36.458976746 -30.488407135 -9.500000000 -36.488403320 -29.497472763 -9.500000000 -36.497467041 -28.499593735 -9.500000000 -36.499591827 -27.499954224 -9.500000000 -36.499954224 -26.499996185 -9.500000000 -36.499996185 -25.500000000 -9.500000000 -36.500000000 -24.500000000 -9.500000000 -36.500000000 -23.500000000 -9.500000000 -36.500000000 -22.500000000 -9.500000000 -36.500000000 -21.500000000 -9.500000000 -36.500000000 -20.500000000 -9.500000000 -36.500000000 -19.500000000 -9.500000000 -36.500000000 -18.500000000 -9.500000000 -36.500000000 -17.500000000 -9.500000000 -36.500000000 -16.500000000 -9.500000000 -36.500000000 -15.500000000 -9.500000000 -36.500000000 -14.500000000 -9.500000000 -36.500000000 -13.500000000 -9.500000000 -36.500000000 -12.500000000 -9.500000000 -36.500000000 -11.500000000 -9.500000000 -36.500000000 -10.500000000 -9.500000000 -36.500000000 -9.500000000 -9.500000000 -36.500000000 -8.500000000 -9.500000000 -36.500000000 -7.500000000 -9.500000000 -36.500000000 -6.500000000 -9.500000000 -36.500000000 -5.500000000 -9.500000000 -36.500000000 -4.500000000 -9.500000000 -36.500000000 -3.500000000 -9.500000000 -36.500000000 -2.500000000 -9.500000000 -36.500000000 -1.500000000 -9.500000000 -36.500000000 -0.500000000 -9.500000000 -36.500000000 0.500000000 -9.500000000 -36.500000000 1.500000000 -9.500000000 -36.500000000 2.500000000 -9.500000000 -36.500000000 3.500000000 -9.500000000 -36.500000000 4.500000000 -9.500000000 -36.500000000 5.500000000 -9.500000000 -36.500000000 6.500000000 -9.500000000 -36.500000000 7.500000000 -9.500000000 -36.500000000 8.500000000 -9.500000000 -36.500000000 9.500000000 -9.500000000 -36.500000000 10.500000000 -9.500000000 -36.500000000 11.500000000 -9.500000000 -36.500000000 12.500000000 -9.500000000 -36.500000000 13.500000000 -9.500000000 -36.500000000 14.500000000 -9.500000000 -36.500000000 15.500000000 -9.500000000 -36.500000000 16.500000000 -9.500000000 -36.500000000 17.500000000 -9.500000000 -36.500000000 18.500000000 -9.500000000 -36.500000000 19.500000000 -9.500000000 -36.500000000 20.500000000 -9.500000000 -36.500000000 21.500000000 -9.500000000 -36.500000000 22.500000000 -9.500000000 -36.500000000 23.500000000 -9.500000000 -36.500000000 24.500000000 -9.500000000 -36.500000000 25.499996185 -9.500000000 -36.499996185 26.499954224 -9.500000000 -36.499954224 27.499591827 -9.500000000 -36.499591827 28.497470856 -9.500000000 -36.497474670 29.488407135 -9.500000000 -36.488403320 30.458978653 -9.500000000 -36.458980560 31.384418488 -9.500000000 -36.384422302 32.233222961 -9.500000000 -36.233226776 32.981101990 -9.500000000 -35.981109619 -33.981101990 -8.500000000 -35.981101990 -33.233222961 -8.500000000 -36.233222961 -32.384422302 -8.500000000 -36.384418488 -31.458978653 -8.500000000 -36.458976746 -30.488407135 -8.500000000 -36.488403320 -29.497472763 -8.500000000 -36.497467041 -28.499593735 -8.500000000 -36.499591827 -27.499954224 -8.500000000 -36.499954224 -26.499996185 -8.500000000 -36.499996185 -25.500000000 -8.500000000 -36.500000000 -24.500000000 -8.500000000 -36.500000000 -23.500000000 -8.500000000 -36.500000000 -22.500000000 -8.500000000 -36.500000000 -21.500000000 -8.500000000 -36.500000000 -20.500000000 -8.500000000 -36.500000000 -19.500000000 -8.500000000 -36.500000000 -18.500000000 -8.500000000 -36.500000000 -17.500000000 -8.500000000 -36.500000000 -16.500000000 -8.500000000 -36.500000000 -15.500000000 -8.500000000 -36.500000000 -14.500000000 -8.500000000 -36.500000000 -13.500000000 -8.500000000 -36.500000000 -12.500000000 -8.500000000 -36.500000000 -11.500000000 -8.500000000 -36.500000000 -10.500000000 -8.500000000 -36.500000000 -9.500000000 -8.500000000 -36.500000000 -8.500000000 -8.500000000 -36.500000000 -7.500000000 -8.500000000 -36.500000000 -6.500000000 -8.500000000 -36.500000000 -5.500000000 -8.500000000 -36.500000000 -4.500000000 -8.500000000 -36.500000000 -3.500000000 -8.500000000 -36.500000000 -2.500000000 -8.500000000 -36.500000000 -1.500000000 -8.500000000 -36.500000000 -0.500000000 -8.500000000 -36.500000000 0.500000000 -8.500000000 -36.500000000 1.500000000 -8.500000000 -36.500000000 2.500000000 -8.500000000 -36.500000000 3.500000000 -8.500000000 -36.500000000 4.500000000 -8.500000000 -36.500000000 5.500000000 -8.500000000 -36.500000000 6.500000000 -8.500000000 -36.500000000 7.500000000 -8.500000000 -36.500000000 8.500000000 -8.500000000 -36.500000000 9.500000000 -8.500000000 -36.500000000 10.500000000 -8.500000000 -36.500000000 11.500000000 -8.500000000 -36.500000000 12.500000000 -8.500000000 -36.500000000 13.500000000 -8.500000000 -36.500000000 14.500000000 -8.500000000 -36.500000000 15.500000000 -8.500000000 -36.500000000 16.500000000 -8.500000000 -36.500000000 17.500000000 -8.500000000 -36.500000000 18.500000000 -8.500000000 -36.500000000 19.500000000 -8.500000000 -36.500000000 20.500000000 -8.500000000 -36.500000000 21.500000000 -8.500000000 -36.500000000 22.500000000 -8.500000000 -36.500000000 23.500000000 -8.500000000 -36.500000000 24.500000000 -8.500000000 -36.500000000 25.499996185 -8.500000000 -36.499996185 26.499954224 -8.500000000 -36.499954224 27.499591827 -8.500000000 -36.499591827 28.497470856 -8.500000000 -36.497474670 29.488407135 -8.500000000 -36.488403320 30.458978653 -8.500000000 -36.458980560 31.384418488 -8.500000000 -36.384422302 32.233222961 -8.500000000 -36.233226776 32.981101990 -8.500000000 -35.981109619 -33.981101990 -7.500000000 -35.981101990 -33.233222961 -7.500000000 -36.233222961 -32.384422302 -7.500000000 -36.384418488 -31.458978653 -7.500000000 -36.458976746 -30.488407135 -7.500000000 -36.488403320 -29.497472763 -7.500000000 -36.497467041 -28.499593735 -7.500000000 -36.499591827 -27.499954224 -7.500000000 -36.499954224 -26.499996185 -7.500000000 -36.499996185 -25.500000000 -7.500000000 -36.500000000 -24.500000000 -7.500000000 -36.500000000 -23.500000000 -7.500000000 -36.500000000 -22.500000000 -7.500000000 -36.500000000 -21.500000000 -7.500000000 -36.500000000 -20.500000000 -7.500000000 -36.500000000 -19.500000000 -7.500000000 -36.500000000 -18.500000000 -7.500000000 -36.500000000 -17.500000000 -7.500000000 -36.500000000 -16.500000000 -7.500000000 -36.500000000 -15.500000000 -7.500000000 -36.500000000 -14.500000000 -7.500000000 -36.500000000 -13.500000000 -7.500000000 -36.500000000 -12.500000000 -7.500000000 -36.500000000 -11.500000000 -7.500000000 -36.500000000 -10.500000000 -7.500000000 -36.500000000 -9.500000000 -7.500000000 -36.500000000 -8.500000000 -7.500000000 -36.500000000 -7.500000000 -7.500000000 -36.500000000 -6.500000000 -7.500000000 -36.500000000 -5.500000000 -7.500000000 -36.500000000 -4.500000000 -7.500000000 -36.500000000 -3.500000000 -7.500000000 -36.500000000 -2.500000000 -7.500000000 -36.500000000 -1.500000000 -7.500000000 -36.500000000 -0.500000000 -7.500000000 -36.500000000 0.500000000 -7.500000000 -36.500000000 1.500000000 -7.500000000 -36.500000000 2.500000000 -7.500000000 -36.500000000 3.500000000 -7.500000000 -36.500000000 4.500000000 -7.500000000 -36.500000000 5.500000000 -7.500000000 -36.500000000 6.500000000 -7.500000000 -36.500000000 7.500000000 -7.500000000 -36.500000000 8.500000000 -7.500000000 -36.500000000 9.500000000 -7.500000000 -36.500000000 10.500000000 -7.500000000 -36.500000000 11.500000000 -7.500000000 -36.500000000 12.500000000 -7.500000000 -36.500000000 13.500000000 -7.500000000 -36.500000000 14.500000000 -7.500000000 -36.500000000 15.500000000 -7.500000000 -36.500000000 16.500000000 -7.500000000 -36.500000000 17.500000000 -7.500000000 -36.500000000 18.500000000 -7.500000000 -36.500000000 19.500000000 -7.500000000 -36.500000000 20.500000000 -7.500000000 -36.500000000 21.500000000 -7.500000000 -36.500000000 22.500000000 -7.500000000 -36.500000000 23.500000000 -7.500000000 -36.500000000 24.500000000 -7.500000000 -36.500000000 25.499996185 -7.500000000 -36.499996185 26.499954224 -7.500000000 -36.499954224 27.499591827 -7.500000000 -36.499591827 28.497470856 -7.500000000 -36.497474670 29.488407135 -7.500000000 -36.488403320 30.458978653 -7.500000000 -36.458980560 31.384418488 -7.500000000 -36.384422302 32.233222961 -7.500000000 -36.233226776 32.981101990 -7.500000000 -35.981109619 -33.981101990 -6.500000000 -35.981101990 -33.233222961 -6.500000000 -36.233222961 -32.384422302 -6.500000000 -36.384418488 -31.458978653 -6.500000000 -36.458976746 -30.488407135 -6.500000000 -36.488403320 -29.497472763 -6.500000000 -36.497467041 -28.499593735 -6.500000000 -36.499591827 -27.499954224 -6.500000000 -36.499954224 -26.499996185 -6.500000000 -36.499996185 -25.500000000 -6.500000000 -36.500000000 -24.500000000 -6.500000000 -36.500000000 -23.500000000 -6.500000000 -36.500000000 -22.500000000 -6.500000000 -36.500000000 -21.500000000 -6.500000000 -36.500000000 -20.500000000 -6.500000000 -36.500000000 -19.500000000 -6.500000000 -36.500000000 -18.500000000 -6.500000000 -36.500000000 -17.500000000 -6.500000000 -36.500000000 -16.500000000 -6.500000000 -36.500000000 -15.500000000 -6.500000000 -36.500000000 -14.500000000 -6.500000000 -36.500000000 -13.500000000 -6.500000000 -36.500000000 -12.500000000 -6.500000000 -36.500000000 -11.500000000 -6.500000000 -36.500000000 -10.500000000 -6.500000000 -36.500000000 -9.500000000 -6.500000000 -36.500000000 -8.500000000 -6.500000000 -36.500000000 -7.500000000 -6.500000000 -36.500000000 -6.500000000 -6.500000000 -36.500000000 -5.500000000 -6.500000000 -36.500000000 -4.500000000 -6.500000000 -36.500000000 -3.500000000 -6.500000000 -36.500000000 -2.500000000 -6.500000000 -36.500000000 -1.500000000 -6.500000000 -36.500000000 -0.500000000 -6.500000000 -36.500000000 0.500000000 -6.500000000 -36.500000000 1.500000000 -6.500000000 -36.500000000 2.500000000 -6.500000000 -36.500000000 3.500000000 -6.500000000 -36.500000000 4.500000000 -6.500000000 -36.500000000 5.500000000 -6.500000000 -36.500000000 6.500000000 -6.500000000 -36.500000000 7.500000000 -6.500000000 -36.500000000 8.500000000 -6.500000000 -36.500000000 9.500000000 -6.500000000 -36.500000000 10.500000000 -6.500000000 -36.500000000 11.500000000 -6.500000000 -36.500000000 12.500000000 -6.500000000 -36.500000000 13.500000000 -6.500000000 -36.500000000 14.500000000 -6.500000000 -36.500000000 15.500000000 -6.500000000 -36.500000000 16.500000000 -6.500000000 -36.500000000 17.500000000 -6.500000000 -36.500000000 18.500000000 -6.500000000 -36.500000000 19.500000000 -6.500000000 -36.500000000 20.500000000 -6.500000000 -36.500000000 21.500000000 -6.500000000 -36.500000000 22.500000000 -6.500000000 -36.500000000 23.500000000 -6.500000000 -36.500000000 24.500000000 -6.500000000 -36.500000000 25.499996185 -6.500000000 -36.499996185 26.499954224 -6.500000000 -36.499954224 27.499591827 -6.500000000 -36.499591827 28.497470856 -6.500000000 -36.497474670 29.488407135 -6.500000000 -36.488403320 30.458978653 -6.500000000 -36.458980560 31.384418488 -6.500000000 -36.384422302 32.233222961 -6.500000000 -36.233226776 32.981101990 -6.500000000 -35.981109619 -33.981101990 -5.500000000 -35.981101990 -33.233222961 -5.500000000 -36.233222961 -32.384422302 -5.500000000 -36.384418488 -31.458978653 -5.500000000 -36.458976746 -30.488407135 -5.500000000 -36.488403320 -29.497472763 -5.500000000 -36.497467041 -28.499593735 -5.500000000 -36.499591827 -27.499954224 -5.500000000 -36.499954224 -26.499996185 -5.500000000 -36.499996185 -25.500000000 -5.500000000 -36.500000000 -24.500000000 -5.500000000 -36.500000000 -23.500000000 -5.500000000 -36.500000000 -22.500000000 -5.500000000 -36.500000000 -21.500000000 -5.500000000 -36.500000000 -20.500000000 -5.500000000 -36.500000000 -19.500000000 -5.500000000 -36.500000000 -18.500000000 -5.500000000 -36.500000000 -17.500000000 -5.500000000 -36.500000000 -16.500000000 -5.500000000 -36.500000000 -15.500000000 -5.500000000 -36.500000000 -14.500000000 -5.500000000 -36.500000000 -13.500000000 -5.500000000 -36.500000000 -12.500000000 -5.500000000 -36.500000000 -11.500000000 -5.500000000 -36.500000000 -10.500000000 -5.500000000 -36.500000000 -9.500000000 -5.500000000 -36.500000000 -8.500000000 -5.500000000 -36.500000000 -7.500000000 -5.500000000 -36.500000000 -6.500000000 -5.500000000 -36.500000000 -5.500000000 -5.500000000 -36.500000000 -4.500000000 -5.500000000 -36.500000000 -3.500000000 -5.500000000 -36.500000000 -2.500000000 -5.500000000 -36.500000000 -1.500000000 -5.500000000 -36.500000000 -0.500000000 -5.500000000 -36.500000000 0.500000000 -5.500000000 -36.500000000 1.500000000 -5.500000000 -36.500000000 2.500000000 -5.500000000 -36.500000000 3.500000000 -5.500000000 -36.500000000 4.500000000 -5.500000000 -36.500000000 5.500000000 -5.500000000 -36.500000000 6.500000000 -5.500000000 -36.500000000 7.500000000 -5.500000000 -36.500000000 8.500000000 -5.500000000 -36.500000000 9.500000000 -5.500000000 -36.500000000 10.500000000 -5.500000000 -36.500000000 11.500000000 -5.500000000 -36.500000000 12.500000000 -5.500000000 -36.500000000 13.500000000 -5.500000000 -36.500000000 14.500000000 -5.500000000 -36.500000000 15.500000000 -5.500000000 -36.500000000 16.500000000 -5.500000000 -36.500000000 17.500000000 -5.500000000 -36.500000000 18.500000000 -5.500000000 -36.500000000 19.500000000 -5.500000000 -36.500000000 20.500000000 -5.500000000 -36.500000000 21.500000000 -5.500000000 -36.500000000 22.500000000 -5.500000000 -36.500000000 23.500000000 -5.500000000 -36.500000000 24.500000000 -5.500000000 -36.500000000 25.499996185 -5.500000000 -36.499996185 26.499954224 -5.500000000 -36.499954224 27.499591827 -5.500000000 -36.499591827 28.497470856 -5.500000000 -36.497474670 29.488407135 -5.500000000 -36.488403320 30.458978653 -5.500000000 -36.458980560 31.384418488 -5.500000000 -36.384422302 32.233222961 -5.500000000 -36.233226776 32.981101990 -5.500000000 -35.981109619 -33.981101990 -4.500000000 -35.981101990 -33.233222961 -4.500000000 -36.233222961 -32.384422302 -4.500000000 -36.384418488 -31.458978653 -4.500000000 -36.458976746 -30.488407135 -4.500000000 -36.488403320 -29.497472763 -4.500000000 -36.497467041 -28.499593735 -4.500000000 -36.499591827 -27.499954224 -4.500000000 -36.499954224 -26.499996185 -4.500000000 -36.499996185 -25.500000000 -4.500000000 -36.500000000 -24.500000000 -4.500000000 -36.500000000 -23.500000000 -4.500000000 -36.500000000 -22.500000000 -4.500000000 -36.500000000 -21.500000000 -4.500000000 -36.500000000 -20.500000000 -4.500000000 -36.500000000 -19.500000000 -4.500000000 -36.500000000 -18.500000000 -4.500000000 -36.500000000 -17.500000000 -4.500000000 -36.500000000 -16.500000000 -4.500000000 -36.500000000 -15.500000000 -4.500000000 -36.500000000 -14.500000000 -4.500000000 -36.500000000 -13.500000000 -4.500000000 -36.500000000 -12.500000000 -4.500000000 -36.500000000 -11.500000000 -4.500000000 -36.500000000 -10.500000000 -4.500000000 -36.500000000 -9.500000000 -4.500000000 -36.500000000 -8.500000000 -4.500000000 -36.500000000 -7.500000000 -4.500000000 -36.500000000 -6.500000000 -4.500000000 -36.500000000 -5.500000000 -4.500000000 -36.500000000 -4.500000000 -4.500000000 -36.500000000 -3.500000000 -4.500000000 -36.500000000 -2.500000000 -4.500000000 -36.500000000 -1.500000000 -4.500000000 -36.500000000 -0.500000000 -4.500000000 -36.500000000 0.500000000 -4.500000000 -36.500000000 1.500000000 -4.500000000 -36.500000000 2.500000000 -4.500000000 -36.500000000 3.500000000 -4.500000000 -36.500000000 4.500000000 -4.500000000 -36.500000000 5.500000000 -4.500000000 -36.500000000 6.500000000 -4.500000000 -36.500000000 7.500000000 -4.500000000 -36.500000000 8.500000000 -4.500000000 -36.500000000 9.500000000 -4.500000000 -36.500000000 10.500000000 -4.500000000 -36.500000000 11.500000000 -4.500000000 -36.500000000 12.500000000 -4.500000000 -36.500000000 13.500000000 -4.500000000 -36.500000000 14.500000000 -4.500000000 -36.500000000 15.500000000 -4.500000000 -36.500000000 16.500000000 -4.500000000 -36.500000000 17.500000000 -4.500000000 -36.500000000 18.500000000 -4.500000000 -36.500000000 19.500000000 -4.500000000 -36.500000000 20.500000000 -4.500000000 -36.500000000 21.500000000 -4.500000000 -36.500000000 22.500000000 -4.500000000 -36.500000000 23.500000000 -4.500000000 -36.500000000 24.500000000 -4.500000000 -36.500000000 25.499996185 -4.500000000 -36.499996185 26.499954224 -4.500000000 -36.499954224 27.499591827 -4.500000000 -36.499591827 28.497470856 -4.500000000 -36.497474670 29.488407135 -4.500000000 -36.488403320 30.458978653 -4.500000000 -36.458980560 31.384418488 -4.500000000 -36.384422302 32.233222961 -4.500000000 -36.233226776 32.981101990 -4.500000000 -35.981109619 -33.981101990 -3.500000000 -35.981101990 -33.233222961 -3.500000000 -36.233222961 -32.384422302 -3.500000000 -36.384418488 -31.458978653 -3.500000000 -36.458976746 -30.488407135 -3.500000000 -36.488403320 -29.497472763 -3.500000000 -36.497467041 -28.499593735 -3.500000000 -36.499591827 -27.499954224 -3.500000000 -36.499954224 -26.499996185 -3.500000000 -36.499996185 -25.500000000 -3.500000000 -36.500000000 -24.500000000 -3.500000000 -36.500000000 -23.500000000 -3.500000000 -36.500000000 -22.500000000 -3.500000000 -36.500000000 -21.500000000 -3.500000000 -36.500000000 -20.500000000 -3.500000000 -36.500000000 -19.500000000 -3.500000000 -36.500000000 -18.500000000 -3.500000000 -36.500000000 -17.500000000 -3.500000000 -36.500000000 -16.500000000 -3.500000000 -36.500000000 -15.500000000 -3.500000000 -36.500000000 -14.500000000 -3.500000000 -36.500000000 -13.500000000 -3.500000000 -36.500000000 -12.500000000 -3.500000000 -36.500000000 -11.500000000 -3.500000000 -36.500000000 -10.500000000 -3.500000000 -36.500000000 -9.500000000 -3.500000000 -36.500000000 -8.500000000 -3.500000000 -36.500000000 -7.500000000 -3.500000000 -36.500000000 -6.500000000 -3.500000000 -36.500000000 -5.500000000 -3.500000000 -36.500000000 -4.500000000 -3.500000000 -36.500000000 -3.500000000 -3.500000000 -36.500000000 -2.500000000 -3.500000000 -36.500000000 -1.500000000 -3.500000000 -36.500000000 -0.500000000 -3.500000000 -36.500000000 0.500000000 -3.500000000 -36.500000000 1.500000000 -3.500000000 -36.500000000 2.500000000 -3.500000000 -36.500000000 3.500000000 -3.500000000 -36.500000000 4.500000000 -3.500000000 -36.500000000 5.500000000 -3.500000000 -36.500000000 6.500000000 -3.500000000 -36.500000000 7.500000000 -3.500000000 -36.500000000 8.500000000 -3.500000000 -36.500000000 9.500000000 -3.500000000 -36.500000000 10.500000000 -3.500000000 -36.500000000 11.500000000 -3.500000000 -36.500000000 12.500000000 -3.500000000 -36.500000000 13.500000000 -3.500000000 -36.500000000 14.500000000 -3.500000000 -36.500000000 15.500000000 -3.500000000 -36.500000000 16.500000000 -3.500000000 -36.500000000 17.500000000 -3.500000000 -36.500000000 18.500000000 -3.500000000 -36.500000000 19.500000000 -3.500000000 -36.500000000 20.500000000 -3.500000000 -36.500000000 21.500000000 -3.500000000 -36.500000000 22.500000000 -3.500000000 -36.500000000 23.500000000 -3.500000000 -36.500000000 24.500000000 -3.500000000 -36.500000000 25.499996185 -3.500000000 -36.499996185 26.499954224 -3.500000000 -36.499954224 27.499591827 -3.500000000 -36.499591827 28.497470856 -3.500000000 -36.497474670 29.488407135 -3.500000000 -36.488403320 30.458978653 -3.500000000 -36.458980560 31.384418488 -3.500000000 -36.384422302 32.233222961 -3.500000000 -36.233226776 32.981101990 -3.500000000 -35.981109619 -33.981101990 -2.500000000 -35.981101990 -33.233222961 -2.500000000 -36.233222961 -32.384422302 -2.500000000 -36.384418488 -31.458978653 -2.500000000 -36.458976746 -30.488407135 -2.500000000 -36.488403320 -29.497472763 -2.500000000 -36.497467041 -28.499593735 -2.500000000 -36.499591827 -27.499954224 -2.500000000 -36.499954224 -26.499996185 -2.500000000 -36.499996185 -25.500000000 -2.500000000 -36.500000000 -24.500000000 -2.500000000 -36.500000000 -23.500000000 -2.500000000 -36.500000000 -22.500000000 -2.500000000 -36.500000000 -21.500000000 -2.500000000 -36.500000000 -20.500000000 -2.500000000 -36.500000000 -19.500000000 -2.500000000 -36.500000000 -18.500000000 -2.500000000 -36.500000000 -17.500000000 -2.500000000 -36.500000000 -16.500000000 -2.500000000 -36.500000000 -15.500000000 -2.500000000 -36.500000000 -14.500000000 -2.500000000 -36.500000000 -13.500000000 -2.500000000 -36.500000000 -12.500000000 -2.500000000 -36.500000000 -11.500000000 -2.500000000 -36.500000000 -10.500000000 -2.500000000 -36.500000000 -9.500000000 -2.500000000 -36.500000000 -8.500000000 -2.500000000 -36.500000000 -7.500000000 -2.500000000 -36.500000000 -6.500000000 -2.500000000 -36.500000000 -5.500000000 -2.500000000 -36.500000000 -4.500000000 -2.500000000 -36.500000000 -3.500000000 -2.500000000 -36.500000000 -2.500000000 -2.500000000 -36.500000000 -1.500000000 -2.500000000 -36.500000000 -0.500000000 -2.500000000 -36.500000000 0.500000000 -2.500000000 -36.500000000 1.500000000 -2.500000000 -36.500000000 2.500000000 -2.500000000 -36.500000000 3.500000000 -2.500000000 -36.500000000 4.500000000 -2.500000000 -36.500000000 5.500000000 -2.500000000 -36.500000000 6.500000000 -2.500000000 -36.500000000 7.500000000 -2.500000000 -36.500000000 8.500000000 -2.500000000 -36.500000000 9.500000000 -2.500000000 -36.500000000 10.500000000 -2.500000000 -36.500000000 11.500000000 -2.500000000 -36.500000000 12.500000000 -2.500000000 -36.500000000 13.500000000 -2.500000000 -36.500000000 14.500000000 -2.500000000 -36.500000000 15.500000000 -2.500000000 -36.500000000 16.500000000 -2.500000000 -36.500000000 17.500000000 -2.500000000 -36.500000000 18.500000000 -2.500000000 -36.500000000 19.500000000 -2.500000000 -36.500000000 20.500000000 -2.500000000 -36.500000000 21.500000000 -2.500000000 -36.500000000 22.500000000 -2.500000000 -36.500000000 23.500000000 -2.500000000 -36.500000000 24.500000000 -2.500000000 -36.500000000 25.499996185 -2.500000000 -36.499996185 26.499954224 -2.500000000 -36.499954224 27.499591827 -2.500000000 -36.499591827 28.497470856 -2.500000000 -36.497474670 29.488407135 -2.500000000 -36.488403320 30.458978653 -2.500000000 -36.458980560 31.384418488 -2.500000000 -36.384422302 32.233222961 -2.500000000 -36.233226776 32.981101990 -2.500000000 -35.981109619 -33.981101990 -1.500000000 -35.981101990 -33.233222961 -1.500000000 -36.233222961 -32.384422302 -1.500000000 -36.384418488 -31.458978653 -1.500000000 -36.458976746 -30.488407135 -1.500000000 -36.488403320 -29.497472763 -1.500000000 -36.497467041 -28.499593735 -1.500000000 -36.499591827 -27.499954224 -1.500000000 -36.499954224 -26.499996185 -1.500000000 -36.499996185 -25.500000000 -1.500000000 -36.500000000 -24.500000000 -1.500000000 -36.500000000 -23.500000000 -1.500000000 -36.500000000 -22.500000000 -1.500000000 -36.500000000 -21.500000000 -1.500000000 -36.500000000 -20.500000000 -1.500000000 -36.500000000 -19.500000000 -1.500000000 -36.500000000 -18.500000000 -1.500000000 -36.500000000 -17.500000000 -1.500000000 -36.500000000 -16.500000000 -1.500000000 -36.500000000 -15.500000000 -1.500000000 -36.500000000 -14.500000000 -1.500000000 -36.500000000 -13.500000000 -1.500000000 -36.500000000 -12.500000000 -1.500000000 -36.500000000 -11.500000000 -1.500000000 -36.500000000 -10.500000000 -1.500000000 -36.500000000 -9.500000000 -1.500000000 -36.500000000 -8.500000000 -1.500000000 -36.500000000 -7.500000000 -1.500000000 -36.500000000 -6.500000000 -1.500000000 -36.500000000 -5.500000000 -1.500000000 -36.500000000 -4.500000000 -1.500000000 -36.500000000 -3.500000000 -1.500000000 -36.500000000 -2.500000000 -1.500000000 -36.500000000 -1.500000000 -1.500000000 -36.500000000 -0.500000000 -1.500000000 -36.500000000 0.500000000 -1.500000000 -36.500000000 1.500000000 -1.500000000 -36.500000000 2.500000000 -1.500000000 -36.500000000 3.500000000 -1.500000000 -36.500000000 4.500000000 -1.500000000 -36.500000000 5.500000000 -1.500000000 -36.500000000 6.500000000 -1.500000000 -36.500000000 7.500000000 -1.500000000 -36.500000000 8.500000000 -1.500000000 -36.500000000 9.500000000 -1.500000000 -36.500000000 10.500000000 -1.500000000 -36.500000000 11.500000000 -1.500000000 -36.500000000 12.500000000 -1.500000000 -36.500000000 13.500000000 -1.500000000 -36.500000000 14.500000000 -1.500000000 -36.500000000 15.500000000 -1.500000000 -36.500000000 16.500000000 -1.500000000 -36.500000000 17.500000000 -1.500000000 -36.500000000 18.500000000 -1.500000000 -36.500000000 19.500000000 -1.500000000 -36.500000000 20.500000000 -1.500000000 -36.500000000 21.500000000 -1.500000000 -36.500000000 22.500000000 -1.500000000 -36.500000000 23.500000000 -1.500000000 -36.500000000 24.500000000 -1.500000000 -36.500000000 25.499996185 -1.500000000 -36.499996185 26.499954224 -1.500000000 -36.499954224 27.499591827 -1.500000000 -36.499591827 28.497470856 -1.500000000 -36.497474670 29.488407135 -1.500000000 -36.488403320 30.458978653 -1.500000000 -36.458980560 31.384418488 -1.500000000 -36.384422302 32.233222961 -1.500000000 -36.233226776 32.981101990 -1.500000000 -35.981109619 -33.981101990 -0.500000000 -35.981101990 -33.233222961 -0.500000000 -36.233222961 -32.384422302 -0.500000000 -36.384418488 -31.458978653 -0.500000000 -36.458976746 -30.488407135 -0.500000000 -36.488403320 -29.497472763 -0.500000000 -36.497467041 -28.499593735 -0.500000000 -36.499591827 -27.499954224 -0.500000000 -36.499954224 -26.499996185 -0.500000000 -36.499996185 -25.500000000 -0.500000000 -36.500000000 -24.500000000 -0.500000000 -36.500000000 -23.500000000 -0.500000000 -36.500000000 -22.500000000 -0.500000000 -36.500000000 -21.500000000 -0.500000000 -36.500000000 -20.500000000 -0.500000000 -36.500000000 -19.500000000 -0.500000000 -36.500000000 -18.500000000 -0.500000000 -36.500000000 -17.500000000 -0.500000000 -36.500000000 -16.500000000 -0.500000000 -36.500000000 -15.500000000 -0.500000000 -36.500000000 -14.500000000 -0.500000000 -36.500000000 -13.500000000 -0.500000000 -36.500000000 -12.500000000 -0.500000000 -36.500000000 -11.500000000 -0.500000000 -36.500000000 -10.500000000 -0.500000000 -36.500000000 -9.500000000 -0.500000000 -36.500000000 -8.500000000 -0.500000000 -36.500000000 -7.500000000 -0.500000000 -36.500000000 -6.500000000 -0.500000000 -36.500000000 -5.500000000 -0.500000000 -36.500000000 -4.500000000 -0.500000000 -36.500000000 -3.500000000 -0.500000000 -36.500000000 -2.500000000 -0.500000000 -36.500000000 -1.500000000 -0.500000000 -36.500000000 -0.500000000 -0.500000000 -36.500000000 0.500000000 -0.500000000 -36.500000000 1.500000000 -0.500000000 -36.500000000 2.500000000 -0.500000000 -36.500000000 3.500000000 -0.500000000 -36.500000000 4.500000000 -0.500000000 -36.500000000 5.500000000 -0.500000000 -36.500000000 6.500000000 -0.500000000 -36.500000000 7.500000000 -0.500000000 -36.500000000 8.500000000 -0.500000000 -36.500000000 9.500000000 -0.500000000 -36.500000000 10.500000000 -0.500000000 -36.500000000 11.500000000 -0.500000000 -36.500000000 12.500000000 -0.500000000 -36.500000000 13.500000000 -0.500000000 -36.500000000 14.500000000 -0.500000000 -36.500000000 15.500000000 -0.500000000 -36.500000000 16.500000000 -0.500000000 -36.500000000 17.500000000 -0.500000000 -36.500000000 18.500000000 -0.500000000 -36.500000000 19.500000000 -0.500000000 -36.500000000 20.500000000 -0.500000000 -36.500000000 21.500000000 -0.500000000 -36.500000000 22.500000000 -0.500000000 -36.500000000 23.500000000 -0.500000000 -36.500000000 24.500000000 -0.500000000 -36.500000000 25.499996185 -0.500000000 -36.499996185 26.499954224 -0.500000000 -36.499954224 27.499591827 -0.500000000 -36.499591827 28.497470856 -0.500000000 -36.497474670 29.488407135 -0.500000000 -36.488403320 30.458978653 -0.500000000 -36.458980560 31.384418488 -0.500000000 -36.384422302 32.233222961 -0.500000000 -36.233226776 32.981101990 -0.500000000 -35.981109619 -33.981101990 0.500000000 -35.981101990 -33.233222961 0.500000000 -36.233222961 -32.384422302 0.500000000 -36.384418488 -31.458978653 0.500000000 -36.458976746 -30.488407135 0.500000000 -36.488403320 -29.497472763 0.500000000 -36.497467041 -28.499593735 0.500000000 -36.499591827 -27.499954224 0.500000000 -36.499954224 -26.499996185 0.500000000 -36.499996185 -25.500000000 0.500000000 -36.500000000 -24.500000000 0.500000000 -36.500000000 -23.500000000 0.500000000 -36.500000000 -22.500000000 0.500000000 -36.500000000 -21.500000000 0.500000000 -36.500000000 -20.500000000 0.500000000 -36.500000000 -19.500000000 0.500000000 -36.500000000 -18.500000000 0.500000000 -36.500000000 -17.500000000 0.500000000 -36.500000000 -16.500000000 0.500000000 -36.500000000 -15.500000000 0.500000000 -36.500000000 -14.500000000 0.500000000 -36.500000000 -13.500000000 0.500000000 -36.500000000 -12.500000000 0.500000000 -36.500000000 -11.500000000 0.500000000 -36.500000000 -10.500000000 0.500000000 -36.500000000 -9.500000000 0.500000000 -36.500000000 -8.500000000 0.500000000 -36.500000000 -7.500000000 0.500000000 -36.500000000 -6.500000000 0.500000000 -36.500000000 -5.500000000 0.500000000 -36.500000000 -4.500000000 0.500000000 -36.500000000 -3.500000000 0.500000000 -36.500000000 -2.500000000 0.500000000 -36.500000000 -1.500000000 0.500000000 -36.500000000 -0.500000000 0.500000000 -36.500000000 0.500000000 0.500000000 -36.500000000 1.500000000 0.500000000 -36.500000000 2.500000000 0.500000000 -36.500000000 3.500000000 0.500000000 -36.500000000 4.500000000 0.500000000 -36.500000000 5.500000000 0.500000000 -36.500000000 6.500000000 0.500000000 -36.500000000 7.500000000 0.500000000 -36.500000000 8.500000000 0.500000000 -36.500000000 9.500000000 0.500000000 -36.500000000 10.500000000 0.500000000 -36.500000000 11.500000000 0.500000000 -36.500000000 12.500000000 0.500000000 -36.500000000 13.500000000 0.500000000 -36.500000000 14.500000000 0.500000000 -36.500000000 15.500000000 0.500000000 -36.500000000 16.500000000 0.500000000 -36.500000000 17.500000000 0.500000000 -36.500000000 18.500000000 0.500000000 -36.500000000 19.500000000 0.500000000 -36.500000000 20.500000000 0.500000000 -36.500000000 21.500000000 0.500000000 -36.500000000 22.500000000 0.500000000 -36.500000000 23.500000000 0.500000000 -36.500000000 24.500000000 0.500000000 -36.500000000 25.499996185 0.500000000 -36.499996185 26.499954224 0.500000000 -36.499954224 27.499591827 0.500000000 -36.499591827 28.497470856 0.500000000 -36.497474670 29.488407135 0.500000000 -36.488403320 30.458978653 0.500000000 -36.458980560 31.384418488 0.500000000 -36.384422302 32.233222961 0.500000000 -36.233226776 32.981101990 0.500000000 -35.981109619 -33.981101990 1.500000000 -35.981101990 -33.233222961 1.500000000 -36.233222961 -32.384422302 1.500000000 -36.384418488 -31.458978653 1.500000000 -36.458976746 -30.488407135 1.500000000 -36.488403320 -29.497472763 1.500000000 -36.497467041 -28.499593735 1.500000000 -36.499591827 -27.499954224 1.500000000 -36.499954224 -26.499996185 1.500000000 -36.499996185 -25.500000000 1.500000000 -36.500000000 -24.500000000 1.500000000 -36.500000000 -23.500000000 1.500000000 -36.500000000 -22.500000000 1.500000000 -36.500000000 -21.500000000 1.500000000 -36.500000000 -20.500000000 1.500000000 -36.500000000 -19.500000000 1.500000000 -36.500000000 -18.500000000 1.500000000 -36.500000000 -17.500000000 1.500000000 -36.500000000 -16.500000000 1.500000000 -36.500000000 -15.500000000 1.500000000 -36.500000000 -14.500000000 1.500000000 -36.500000000 -13.500000000 1.500000000 -36.500000000 -12.500000000 1.500000000 -36.500000000 -11.500000000 1.500000000 -36.500000000 -10.500000000 1.500000000 -36.500000000 -9.500000000 1.500000000 -36.500000000 -8.500000000 1.500000000 -36.500000000 -7.500000000 1.500000000 -36.500000000 -6.500000000 1.500000000 -36.500000000 -5.500000000 1.500000000 -36.500000000 -4.500000000 1.500000000 -36.500000000 -3.500000000 1.500000000 -36.500000000 -2.500000000 1.500000000 -36.500000000 -1.500000000 1.500000000 -36.500000000 -0.500000000 1.500000000 -36.500000000 0.500000000 1.500000000 -36.500000000 1.500000000 1.500000000 -36.500000000 2.500000000 1.500000000 -36.500000000 3.500000000 1.500000000 -36.500000000 4.500000000 1.500000000 -36.500000000 5.500000000 1.500000000 -36.500000000 6.500000000 1.500000000 -36.500000000 7.500000000 1.500000000 -36.500000000 8.500000000 1.500000000 -36.500000000 9.500000000 1.500000000 -36.500000000 10.500000000 1.500000000 -36.500000000 11.500000000 1.500000000 -36.500000000 12.500000000 1.500000000 -36.500000000 13.500000000 1.500000000 -36.500000000 14.500000000 1.500000000 -36.500000000 15.500000000 1.500000000 -36.500000000 16.500000000 1.500000000 -36.500000000 17.500000000 1.500000000 -36.500000000 18.500000000 1.500000000 -36.500000000 19.500000000 1.500000000 -36.500000000 20.500000000 1.500000000 -36.500000000 21.500000000 1.500000000 -36.500000000 22.500000000 1.500000000 -36.500000000 23.500000000 1.500000000 -36.500000000 24.500000000 1.500000000 -36.500000000 25.499996185 1.500000000 -36.499996185 26.499954224 1.500000000 -36.499954224 27.499591827 1.500000000 -36.499591827 28.497470856 1.500000000 -36.497474670 29.488407135 1.500000000 -36.488403320 30.458978653 1.500000000 -36.458980560 31.384418488 1.500000000 -36.384422302 32.233222961 1.500000000 -36.233226776 32.981101990 1.500000000 -35.981109619 -33.981101990 2.500000000 -35.981101990 -33.233222961 2.500000000 -36.233222961 -32.384422302 2.500000000 -36.384418488 -31.458978653 2.500000000 -36.458976746 -30.488407135 2.500000000 -36.488403320 -29.497472763 2.500000000 -36.497467041 -28.499593735 2.500000000 -36.499591827 -27.499954224 2.500000000 -36.499954224 -26.499996185 2.500000000 -36.499996185 -25.500000000 2.500000000 -36.500000000 -24.500000000 2.500000000 -36.500000000 -23.500000000 2.500000000 -36.500000000 -22.500000000 2.500000000 -36.500000000 -21.500000000 2.500000000 -36.500000000 -20.500000000 2.500000000 -36.500000000 -19.500000000 2.500000000 -36.500000000 -18.500000000 2.500000000 -36.500000000 -17.500000000 2.500000000 -36.500000000 -16.500000000 2.500000000 -36.500000000 -15.500000000 2.500000000 -36.500000000 -14.500000000 2.500000000 -36.500000000 -13.500000000 2.500000000 -36.500000000 -12.500000000 2.500000000 -36.500000000 -11.500000000 2.500000000 -36.500000000 -10.500000000 2.500000000 -36.500000000 -9.500000000 2.500000000 -36.500000000 -8.500000000 2.500000000 -36.500000000 -7.500000000 2.500000000 -36.500000000 -6.500000000 2.500000000 -36.500000000 -5.500000000 2.500000000 -36.500000000 -4.500000000 2.500000000 -36.500000000 -3.500000000 2.500000000 -36.500000000 -2.500000000 2.500000000 -36.500000000 -1.500000000 2.500000000 -36.500000000 -0.500000000 2.500000000 -36.500000000 0.500000000 2.500000000 -36.500000000 1.500000000 2.500000000 -36.500000000 2.500000000 2.500000000 -36.500000000 3.500000000 2.500000000 -36.500000000 4.500000000 2.500000000 -36.500000000 5.500000000 2.500000000 -36.500000000 6.500000000 2.500000000 -36.500000000 7.500000000 2.500000000 -36.500000000 8.500000000 2.500000000 -36.500000000 9.500000000 2.500000000 -36.500000000 10.500000000 2.500000000 -36.500000000 11.500000000 2.500000000 -36.500000000 12.500000000 2.500000000 -36.500000000 13.500000000 2.500000000 -36.500000000 14.500000000 2.500000000 -36.500000000 15.500000000 2.500000000 -36.500000000 16.500000000 2.500000000 -36.500000000 17.500000000 2.500000000 -36.500000000 18.500000000 2.500000000 -36.500000000 19.500000000 2.500000000 -36.500000000 20.500000000 2.500000000 -36.500000000 21.500000000 2.500000000 -36.500000000 22.500000000 2.500000000 -36.500000000 23.500000000 2.500000000 -36.500000000 24.500000000 2.500000000 -36.500000000 25.499996185 2.500000000 -36.499996185 26.499954224 2.500000000 -36.499954224 27.499591827 2.500000000 -36.499591827 28.497470856 2.500000000 -36.497474670 29.488407135 2.500000000 -36.488403320 30.458978653 2.500000000 -36.458980560 31.384418488 2.500000000 -36.384422302 32.233222961 2.500000000 -36.233226776 32.981101990 2.500000000 -35.981109619 -33.981101990 3.500000000 -35.981101990 -33.233222961 3.500000000 -36.233222961 -32.384422302 3.500000000 -36.384418488 -31.458978653 3.500000000 -36.458976746 -30.488407135 3.500000000 -36.488403320 -29.497472763 3.500000000 -36.497467041 -28.499593735 3.500000000 -36.499591827 -27.499954224 3.500000000 -36.499954224 -26.499996185 3.500000000 -36.499996185 -25.500000000 3.500000000 -36.500000000 -24.500000000 3.500000000 -36.500000000 -23.500000000 3.500000000 -36.500000000 -22.500000000 3.500000000 -36.500000000 -21.500000000 3.500000000 -36.500000000 -20.500000000 3.500000000 -36.500000000 -19.500000000 3.500000000 -36.500000000 -18.500000000 3.500000000 -36.500000000 -17.500000000 3.500000000 -36.500000000 -16.500000000 3.500000000 -36.500000000 -15.500000000 3.500000000 -36.500000000 -14.500000000 3.500000000 -36.500000000 -13.500000000 3.500000000 -36.500000000 -12.500000000 3.500000000 -36.500000000 -11.500000000 3.500000000 -36.500000000 -10.500000000 3.500000000 -36.500000000 -9.500000000 3.500000000 -36.500000000 -8.500000000 3.500000000 -36.500000000 -7.500000000 3.500000000 -36.500000000 -6.500000000 3.500000000 -36.500000000 -5.500000000 3.500000000 -36.500000000 -4.500000000 3.500000000 -36.500000000 -3.500000000 3.500000000 -36.500000000 -2.500000000 3.500000000 -36.500000000 -1.500000000 3.500000000 -36.500000000 -0.500000000 3.500000000 -36.500000000 0.500000000 3.500000000 -36.500000000 1.500000000 3.500000000 -36.500000000 2.500000000 3.500000000 -36.500000000 3.500000000 3.500000000 -36.500000000 4.500000000 3.500000000 -36.500000000 5.500000000 3.500000000 -36.500000000 6.500000000 3.500000000 -36.500000000 7.500000000 3.500000000 -36.500000000 8.500000000 3.500000000 -36.500000000 9.500000000 3.500000000 -36.500000000 10.500000000 3.500000000 -36.500000000 11.500000000 3.500000000 -36.500000000 12.500000000 3.500000000 -36.500000000 13.500000000 3.500000000 -36.500000000 14.500000000 3.500000000 -36.500000000 15.500000000 3.500000000 -36.500000000 16.500000000 3.500000000 -36.500000000 17.500000000 3.500000000 -36.500000000 18.500000000 3.500000000 -36.500000000 19.500000000 3.500000000 -36.500000000 20.500000000 3.500000000 -36.500000000 21.500000000 3.500000000 -36.500000000 22.500000000 3.500000000 -36.500000000 23.500000000 3.500000000 -36.500000000 24.500000000 3.500000000 -36.500000000 25.499996185 3.500000000 -36.499996185 26.499954224 3.500000000 -36.499954224 27.499591827 3.500000000 -36.499591827 28.497470856 3.500000000 -36.497474670 29.488407135 3.500000000 -36.488403320 30.458978653 3.500000000 -36.458980560 31.384418488 3.500000000 -36.384422302 32.233222961 3.500000000 -36.233226776 32.981101990 3.500000000 -35.981109619 -33.981101990 4.500000000 -35.981101990 -33.233222961 4.500000000 -36.233222961 -32.384422302 4.500000000 -36.384418488 -31.458978653 4.500000000 -36.458976746 -30.488407135 4.500000000 -36.488403320 -29.497472763 4.500000000 -36.497467041 -28.499593735 4.500000000 -36.499591827 -27.499954224 4.500000000 -36.499954224 -26.499996185 4.500000000 -36.499996185 -25.500000000 4.500000000 -36.500000000 -24.500000000 4.500000000 -36.500000000 -23.500000000 4.500000000 -36.500000000 -22.500000000 4.500000000 -36.500000000 -21.500000000 4.500000000 -36.500000000 -20.500000000 4.500000000 -36.500000000 -19.500000000 4.500000000 -36.500000000 -18.500000000 4.500000000 -36.500000000 -17.500000000 4.500000000 -36.500000000 -16.500000000 4.500000000 -36.500000000 -15.500000000 4.500000000 -36.500000000 -14.500000000 4.500000000 -36.500000000 -13.500000000 4.500000000 -36.500000000 -12.500000000 4.500000000 -36.500000000 -11.500000000 4.500000000 -36.500000000 -10.500000000 4.500000000 -36.500000000 -9.500000000 4.500000000 -36.500000000 -8.500000000 4.500000000 -36.500000000 -7.500000000 4.500000000 -36.500000000 -6.500000000 4.500000000 -36.500000000 -5.500000000 4.500000000 -36.500000000 -4.500000000 4.500000000 -36.500000000 -3.500000000 4.500000000 -36.500000000 -2.500000000 4.500000000 -36.500000000 -1.500000000 4.500000000 -36.500000000 -0.500000000 4.500000000 -36.500000000 0.500000000 4.500000000 -36.500000000 1.500000000 4.500000000 -36.500000000 2.500000000 4.500000000 -36.500000000 3.500000000 4.500000000 -36.500000000 4.500000000 4.500000000 -36.500000000 5.500000000 4.500000000 -36.500000000 6.500000000 4.500000000 -36.500000000 7.500000000 4.500000000 -36.500000000 8.500000000 4.500000000 -36.500000000 9.500000000 4.500000000 -36.500000000 10.500000000 4.500000000 -36.500000000 11.500000000 4.500000000 -36.500000000 12.500000000 4.500000000 -36.500000000 13.500000000 4.500000000 -36.500000000 14.500000000 4.500000000 -36.500000000 15.500000000 4.500000000 -36.500000000 16.500000000 4.500000000 -36.500000000 17.500000000 4.500000000 -36.500000000 18.500000000 4.500000000 -36.500000000 19.500000000 4.500000000 -36.500000000 20.500000000 4.500000000 -36.500000000 21.500000000 4.500000000 -36.500000000 22.500000000 4.500000000 -36.500000000 23.500000000 4.500000000 -36.500000000 24.500000000 4.500000000 -36.500000000 25.499996185 4.500000000 -36.499996185 26.499954224 4.500000000 -36.499954224 27.499591827 4.500000000 -36.499591827 28.497470856 4.500000000 -36.497474670 29.488407135 4.500000000 -36.488403320 30.458978653 4.500000000 -36.458980560 31.384418488 4.500000000 -36.384422302 32.233222961 4.500000000 -36.233226776 32.981101990 4.500000000 -35.981109619 -33.981101990 5.500000000 -35.981101990 -33.233222961 5.500000000 -36.233222961 -32.384422302 5.500000000 -36.384418488 -31.458978653 5.500000000 -36.458976746 -30.488407135 5.500000000 -36.488403320 -29.497472763 5.500000000 -36.497467041 -28.499593735 5.500000000 -36.499591827 -27.499954224 5.500000000 -36.499954224 -26.499996185 5.500000000 -36.499996185 -25.500000000 5.500000000 -36.500000000 -24.500000000 5.500000000 -36.500000000 -23.500000000 5.500000000 -36.500000000 -22.500000000 5.500000000 -36.500000000 -21.500000000 5.500000000 -36.500000000 -20.500000000 5.500000000 -36.500000000 -19.500000000 5.500000000 -36.500000000 -18.500000000 5.500000000 -36.500000000 -17.500000000 5.500000000 -36.500000000 -16.500000000 5.500000000 -36.500000000 -15.500000000 5.500000000 -36.500000000 -14.500000000 5.500000000 -36.500000000 -13.500000000 5.500000000 -36.500000000 -12.500000000 5.500000000 -36.500000000 -11.500000000 5.500000000 -36.500000000 -10.500000000 5.500000000 -36.500000000 -9.500000000 5.500000000 -36.500000000 -8.500000000 5.500000000 -36.500000000 -7.500000000 5.500000000 -36.500000000 -6.500000000 5.500000000 -36.500000000 -5.500000000 5.500000000 -36.500000000 -4.500000000 5.500000000 -36.500000000 -3.500000000 5.500000000 -36.500000000 -2.500000000 5.500000000 -36.500000000 -1.500000000 5.500000000 -36.500000000 -0.500000000 5.500000000 -36.500000000 0.500000000 5.500000000 -36.500000000 1.500000000 5.500000000 -36.500000000 2.500000000 5.500000000 -36.500000000 3.500000000 5.500000000 -36.500000000 4.500000000 5.500000000 -36.500000000 5.500000000 5.500000000 -36.500000000 6.500000000 5.500000000 -36.500000000 7.500000000 5.500000000 -36.500000000 8.500000000 5.500000000 -36.500000000 9.500000000 5.500000000 -36.500000000 10.500000000 5.500000000 -36.500000000 11.500000000 5.500000000 -36.500000000 12.500000000 5.500000000 -36.500000000 13.500000000 5.500000000 -36.500000000 14.500000000 5.500000000 -36.500000000 15.500000000 5.500000000 -36.500000000 16.500000000 5.500000000 -36.500000000 17.500000000 5.500000000 -36.500000000 18.500000000 5.500000000 -36.500000000 19.500000000 5.500000000 -36.500000000 20.500000000 5.500000000 -36.500000000 21.500000000 5.500000000 -36.500000000 22.500000000 5.500000000 -36.500000000 23.500000000 5.500000000 -36.500000000 24.500000000 5.500000000 -36.500000000 25.499996185 5.500000000 -36.499996185 26.499954224 5.500000000 -36.499954224 27.499591827 5.500000000 -36.499591827 28.497470856 5.500000000 -36.497474670 29.488407135 5.500000000 -36.488403320 30.458978653 5.500000000 -36.458980560 31.384418488 5.500000000 -36.384422302 32.233222961 5.500000000 -36.233226776 32.981101990 5.500000000 -35.981109619 -33.981101990 6.500000000 -35.981101990 -33.233222961 6.500000000 -36.233222961 -32.384422302 6.500000000 -36.384418488 -31.458978653 6.500000000 -36.458976746 -30.488407135 6.500000000 -36.488403320 -29.497472763 6.500000000 -36.497467041 -28.499593735 6.500000000 -36.499591827 -27.499954224 6.500000000 -36.499954224 -26.499996185 6.500000000 -36.499996185 -25.500000000 6.500000000 -36.500000000 -24.500000000 6.500000000 -36.500000000 -23.500000000 6.500000000 -36.500000000 -22.500000000 6.500000000 -36.500000000 -21.500000000 6.500000000 -36.500000000 -20.500000000 6.500000000 -36.500000000 -19.500000000 6.500000000 -36.500000000 -18.500000000 6.500000000 -36.500000000 -17.500000000 6.500000000 -36.500000000 -16.500000000 6.500000000 -36.500000000 -15.500000000 6.500000000 -36.500000000 -14.500000000 6.500000000 -36.500000000 -13.500000000 6.500000000 -36.500000000 -12.500000000 6.500000000 -36.500000000 -11.500000000 6.500000000 -36.500000000 -10.500000000 6.500000000 -36.500000000 -9.500000000 6.500000000 -36.500000000 -8.500000000 6.500000000 -36.500000000 -7.500000000 6.500000000 -36.500000000 -6.500000000 6.500000000 -36.500000000 -5.500000000 6.500000000 -36.500000000 -4.500000000 6.500000000 -36.500000000 -3.500000000 6.500000000 -36.500000000 -2.500000000 6.500000000 -36.500000000 -1.500000000 6.500000000 -36.500000000 -0.500000000 6.500000000 -36.500000000 0.500000000 6.500000000 -36.500000000 1.500000000 6.500000000 -36.500000000 2.500000000 6.500000000 -36.500000000 3.500000000 6.500000000 -36.500000000 4.500000000 6.500000000 -36.500000000 5.500000000 6.500000000 -36.500000000 6.500000000 6.500000000 -36.500000000 7.500000000 6.500000000 -36.500000000 8.500000000 6.500000000 -36.500000000 9.500000000 6.500000000 -36.500000000 10.500000000 6.500000000 -36.500000000 11.500000000 6.500000000 -36.500000000 12.500000000 6.500000000 -36.500000000 13.500000000 6.500000000 -36.500000000 14.500000000 6.500000000 -36.500000000 15.500000000 6.500000000 -36.500000000 16.500000000 6.500000000 -36.500000000 17.500000000 6.500000000 -36.500000000 18.500000000 6.500000000 -36.500000000 19.500000000 6.500000000 -36.500000000 20.500000000 6.500000000 -36.500000000 21.500000000 6.500000000 -36.500000000 22.500000000 6.500000000 -36.500000000 23.500000000 6.500000000 -36.500000000 24.500000000 6.500000000 -36.500000000 25.499996185 6.500000000 -36.499996185 26.499954224 6.500000000 -36.499954224 27.499591827 6.500000000 -36.499591827 28.497470856 6.500000000 -36.497474670 29.488407135 6.500000000 -36.488403320 30.458978653 6.500000000 -36.458980560 31.384418488 6.500000000 -36.384422302 32.233222961 6.500000000 -36.233226776 32.981101990 6.500000000 -35.981109619 -33.981101990 7.500000000 -35.981101990 -33.233222961 7.500000000 -36.233222961 -32.384422302 7.500000000 -36.384418488 -31.458978653 7.500000000 -36.458976746 -30.488407135 7.500000000 -36.488403320 -29.497472763 7.500000000 -36.497467041 -28.499593735 7.500000000 -36.499591827 -27.499954224 7.500000000 -36.499954224 -26.499996185 7.500000000 -36.499996185 -25.500000000 7.500000000 -36.500000000 -24.500000000 7.500000000 -36.500000000 -23.500000000 7.500000000 -36.500000000 -22.500000000 7.500000000 -36.500000000 -21.500000000 7.500000000 -36.500000000 -20.500000000 7.500000000 -36.500000000 -19.500000000 7.500000000 -36.500000000 -18.500000000 7.500000000 -36.500000000 -17.500000000 7.500000000 -36.500000000 -16.500000000 7.500000000 -36.500000000 -15.500000000 7.500000000 -36.500000000 -14.500000000 7.500000000 -36.500000000 -13.500000000 7.500000000 -36.500000000 -12.500000000 7.500000000 -36.500000000 -11.500000000 7.500000000 -36.500000000 -10.500000000 7.500000000 -36.500000000 -9.500000000 7.500000000 -36.500000000 -8.500000000 7.500000000 -36.500000000 -7.500000000 7.500000000 -36.500000000 -6.500000000 7.500000000 -36.500000000 -5.500000000 7.500000000 -36.500000000 -4.500000000 7.500000000 -36.500000000 -3.500000000 7.500000000 -36.500000000 -2.500000000 7.500000000 -36.500000000 -1.500000000 7.500000000 -36.500000000 -0.500000000 7.500000000 -36.500000000 0.500000000 7.500000000 -36.500000000 1.500000000 7.500000000 -36.500000000 2.500000000 7.500000000 -36.500000000 3.500000000 7.500000000 -36.500000000 4.500000000 7.500000000 -36.500000000 5.500000000 7.500000000 -36.500000000 6.500000000 7.500000000 -36.500000000 7.500000000 7.500000000 -36.500000000 8.500000000 7.500000000 -36.500000000 9.500000000 7.500000000 -36.500000000 10.500000000 7.500000000 -36.500000000 11.500000000 7.500000000 -36.500000000 12.500000000 7.500000000 -36.500000000 13.500000000 7.500000000 -36.500000000 14.500000000 7.500000000 -36.500000000 15.500000000 7.500000000 -36.500000000 16.500000000 7.500000000 -36.500000000 17.500000000 7.500000000 -36.500000000 18.500000000 7.500000000 -36.500000000 19.500000000 7.500000000 -36.500000000 20.500000000 7.500000000 -36.500000000 21.500000000 7.500000000 -36.500000000 22.500000000 7.500000000 -36.500000000 23.500000000 7.500000000 -36.500000000 24.500000000 7.500000000 -36.500000000 25.499996185 7.500000000 -36.499996185 26.499954224 7.500000000 -36.499954224 27.499591827 7.500000000 -36.499591827 28.497470856 7.500000000 -36.497474670 29.488407135 7.500000000 -36.488403320 30.458978653 7.500000000 -36.458980560 31.384418488 7.500000000 -36.384422302 32.233222961 7.500000000 -36.233226776 32.981101990 7.500000000 -35.981109619 -33.981101990 8.500000000 -35.981101990 -33.233222961 8.500000000 -36.233222961 -32.384422302 8.500000000 -36.384418488 -31.458978653 8.500000000 -36.458976746 -30.488407135 8.500000000 -36.488403320 -29.497472763 8.500000000 -36.497467041 -28.499593735 8.500000000 -36.499591827 -27.499954224 8.500000000 -36.499954224 -26.499996185 8.500000000 -36.499996185 -25.500000000 8.500000000 -36.500000000 -24.500000000 8.500000000 -36.500000000 -23.500000000 8.500000000 -36.500000000 -22.500000000 8.500000000 -36.500000000 -21.500000000 8.500000000 -36.500000000 -20.500000000 8.500000000 -36.500000000 -19.500000000 8.500000000 -36.500000000 -18.500000000 8.500000000 -36.500000000 -17.500000000 8.500000000 -36.500000000 -16.500000000 8.500000000 -36.500000000 -15.500000000 8.500000000 -36.500000000 -14.500000000 8.500000000 -36.500000000 -13.500000000 8.500000000 -36.500000000 -12.500000000 8.500000000 -36.500000000 -11.500000000 8.500000000 -36.500000000 -10.500000000 8.500000000 -36.500000000 -9.500000000 8.500000000 -36.500000000 -8.500000000 8.500000000 -36.500000000 -7.500000000 8.500000000 -36.500000000 -6.500000000 8.500000000 -36.500000000 -5.500000000 8.500000000 -36.500000000 -4.500000000 8.500000000 -36.500000000 -3.500000000 8.500000000 -36.500000000 -2.500000000 8.500000000 -36.500000000 -1.500000000 8.500000000 -36.500000000 -0.500000000 8.500000000 -36.500000000 0.500000000 8.500000000 -36.500000000 1.500000000 8.500000000 -36.500000000 2.500000000 8.500000000 -36.500000000 3.500000000 8.500000000 -36.500000000 4.500000000 8.500000000 -36.500000000 5.500000000 8.500000000 -36.500000000 6.500000000 8.500000000 -36.500000000 7.500000000 8.500000000 -36.500000000 8.500000000 8.500000000 -36.500000000 9.500000000 8.500000000 -36.500000000 10.500000000 8.500000000 -36.500000000 11.500000000 8.500000000 -36.500000000 12.500000000 8.500000000 -36.500000000 13.500000000 8.500000000 -36.500000000 14.500000000 8.500000000 -36.500000000 15.500000000 8.500000000 -36.500000000 16.500000000 8.500000000 -36.500000000 17.500000000 8.500000000 -36.500000000 18.500000000 8.500000000 -36.500000000 19.500000000 8.500000000 -36.500000000 20.500000000 8.500000000 -36.500000000 21.500000000 8.500000000 -36.500000000 22.500000000 8.500000000 -36.500000000 23.500000000 8.500000000 -36.500000000 24.500000000 8.500000000 -36.500000000 25.499996185 8.500000000 -36.499996185 26.499954224 8.500000000 -36.499954224 27.499591827 8.500000000 -36.499591827 28.497470856 8.500000000 -36.497474670 29.488407135 8.500000000 -36.488403320 30.458978653 8.500000000 -36.458980560 31.384418488 8.500000000 -36.384422302 32.233222961 8.500000000 -36.233226776 32.981101990 8.500000000 -35.981109619 -33.981101990 9.500000000 -35.981101990 -33.233222961 9.500000000 -36.233222961 -32.384422302 9.500000000 -36.384418488 -31.458978653 9.500000000 -36.458976746 -30.488407135 9.500000000 -36.488403320 -29.497472763 9.500000000 -36.497467041 -28.499593735 9.500000000 -36.499591827 -27.499954224 9.500000000 -36.499954224 -26.499996185 9.500000000 -36.499996185 -25.500000000 9.500000000 -36.500000000 -24.500000000 9.500000000 -36.500000000 -23.500000000 9.500000000 -36.500000000 -22.500000000 9.500000000 -36.500000000 -21.500000000 9.500000000 -36.500000000 -20.500000000 9.500000000 -36.500000000 -19.500000000 9.500000000 -36.500000000 -18.500000000 9.500000000 -36.500000000 -17.500000000 9.500000000 -36.500000000 -16.500000000 9.500000000 -36.500000000 -15.500000000 9.500000000 -36.500000000 -14.500000000 9.500000000 -36.500000000 -13.500000000 9.500000000 -36.500000000 -12.500000000 9.500000000 -36.500000000 -11.500000000 9.500000000 -36.500000000 -10.500000000 9.500000000 -36.500000000 -9.500000000 9.500000000 -36.500000000 -8.500000000 9.500000000 -36.500000000 -7.500000000 9.500000000 -36.500000000 -6.500000000 9.500000000 -36.500000000 -5.500000000 9.500000000 -36.500000000 -4.500000000 9.500000000 -36.500000000 -3.500000000 9.500000000 -36.500000000 -2.500000000 9.500000000 -36.500000000 -1.500000000 9.500000000 -36.500000000 -0.500000000 9.500000000 -36.500000000 0.500000000 9.500000000 -36.500000000 1.500000000 9.500000000 -36.500000000 2.500000000 9.500000000 -36.500000000 3.500000000 9.500000000 -36.500000000 4.500000000 9.500000000 -36.500000000 5.500000000 9.500000000 -36.500000000 6.500000000 9.500000000 -36.500000000 7.500000000 9.500000000 -36.500000000 8.500000000 9.500000000 -36.500000000 9.500000000 9.500000000 -36.500000000 10.500000000 9.500000000 -36.500000000 11.500000000 9.500000000 -36.500000000 12.500000000 9.500000000 -36.500000000 13.500000000 9.500000000 -36.500000000 14.500000000 9.500000000 -36.500000000 15.500000000 9.500000000 -36.500000000 16.500000000 9.500000000 -36.500000000 17.500000000 9.500000000 -36.500000000 18.500000000 9.500000000 -36.500000000 19.500000000 9.500000000 -36.500000000 20.500000000 9.500000000 -36.500000000 21.500000000 9.500000000 -36.500000000 22.500000000 9.500000000 -36.500000000 23.500000000 9.500000000 -36.500000000 24.500000000 9.500000000 -36.500000000 25.499996185 9.500000000 -36.499996185 26.499954224 9.500000000 -36.499954224 27.499591827 9.500000000 -36.499591827 28.497470856 9.500000000 -36.497474670 29.488407135 9.500000000 -36.488403320 30.458978653 9.500000000 -36.458980560 31.384418488 9.500000000 -36.384422302 32.233222961 9.500000000 -36.233226776 32.981101990 9.500000000 -35.981109619 -33.981101990 10.500000000 -35.981101990 -33.233222961 10.500000000 -36.233222961 -32.384422302 10.500000000 -36.384418488 -31.458978653 10.500000000 -36.458976746 -30.488407135 10.500000000 -36.488403320 -29.497472763 10.500000000 -36.497467041 -28.499593735 10.500000000 -36.499591827 -27.499954224 10.500000000 -36.499954224 -26.499996185 10.500000000 -36.499996185 -25.500000000 10.500000000 -36.500000000 -24.500000000 10.500000000 -36.500000000 -23.500000000 10.500000000 -36.500000000 -22.500000000 10.500000000 -36.500000000 -21.500000000 10.500000000 -36.500000000 -20.500000000 10.500000000 -36.500000000 -19.500000000 10.500000000 -36.500000000 -18.500000000 10.500000000 -36.500000000 -17.500000000 10.500000000 -36.500000000 -16.500000000 10.500000000 -36.500000000 -15.500000000 10.500000000 -36.500000000 -14.500000000 10.500000000 -36.500000000 -13.500000000 10.500000000 -36.500000000 -12.500000000 10.500000000 -36.500000000 -11.500000000 10.500000000 -36.500000000 -10.500000000 10.500000000 -36.500000000 -9.500000000 10.500000000 -36.500000000 -8.500000000 10.500000000 -36.500000000 -7.500000000 10.500000000 -36.500000000 -6.500000000 10.500000000 -36.500000000 -5.500000000 10.500000000 -36.500000000 -4.500000000 10.500000000 -36.500000000 -3.500000000 10.500000000 -36.500000000 -2.500000000 10.500000000 -36.500000000 -1.500000000 10.500000000 -36.500000000 -0.500000000 10.500000000 -36.500000000 0.500000000 10.500000000 -36.500000000 1.500000000 10.500000000 -36.500000000 2.500000000 10.500000000 -36.500000000 3.500000000 10.500000000 -36.500000000 4.500000000 10.500000000 -36.500000000 5.500000000 10.500000000 -36.500000000 6.500000000 10.500000000 -36.500000000 7.500000000 10.500000000 -36.500000000 8.500000000 10.500000000 -36.500000000 9.500000000 10.500000000 -36.500000000 10.500000000 10.500000000 -36.500000000 11.500000000 10.500000000 -36.500000000 12.500000000 10.500000000 -36.500000000 13.500000000 10.500000000 -36.500000000 14.500000000 10.500000000 -36.500000000 15.500000000 10.500000000 -36.500000000 16.500000000 10.500000000 -36.500000000 17.500000000 10.500000000 -36.500000000 18.500000000 10.500000000 -36.500000000 19.500000000 10.500000000 -36.500000000 20.500000000 10.500000000 -36.500000000 21.500000000 10.500000000 -36.500000000 22.500000000 10.500000000 -36.500000000 23.500000000 10.500000000 -36.500000000 24.500000000 10.500000000 -36.500000000 25.499996185 10.500000000 -36.499996185 26.499954224 10.500000000 -36.499954224 27.499591827 10.500000000 -36.499591827 28.497470856 10.500000000 -36.497474670 29.488407135 10.500000000 -36.488403320 30.458978653 10.500000000 -36.458980560 31.384418488 10.500000000 -36.384422302 32.233222961 10.500000000 -36.233226776 32.981101990 10.500000000 -35.981109619 -33.981101990 11.500000000 -35.981101990 -33.233222961 11.500000000 -36.233222961 -32.384422302 11.500000000 -36.384418488 -31.458978653 11.500000000 -36.458976746 -30.488407135 11.500000000 -36.488403320 -29.497472763 11.500000000 -36.497467041 -28.499593735 11.500000000 -36.499591827 -27.499954224 11.500000000 -36.499954224 -26.499996185 11.500000000 -36.499996185 -25.500000000 11.500000000 -36.500000000 -24.500000000 11.500000000 -36.500000000 -23.500000000 11.500000000 -36.500000000 -22.500000000 11.500000000 -36.500000000 -21.500000000 11.500000000 -36.500000000 -20.500000000 11.500000000 -36.500000000 -19.500000000 11.500000000 -36.500000000 -18.500000000 11.500000000 -36.500000000 -17.500000000 11.500000000 -36.500000000 -16.500000000 11.500000000 -36.500000000 -15.500000000 11.500000000 -36.500000000 -14.500000000 11.500000000 -36.500000000 -13.500000000 11.500000000 -36.500000000 -12.500000000 11.500000000 -36.500000000 -11.500000000 11.500000000 -36.500000000 -10.500000000 11.500000000 -36.500000000 -9.500000000 11.500000000 -36.500000000 -8.500000000 11.500000000 -36.500000000 -7.500000000 11.500000000 -36.500000000 -6.500000000 11.500000000 -36.500000000 -5.500000000 11.500000000 -36.500000000 -4.500000000 11.500000000 -36.500000000 -3.500000000 11.500000000 -36.500000000 -2.500000000 11.500000000 -36.500000000 -1.500000000 11.500000000 -36.500000000 -0.500000000 11.500000000 -36.500000000 0.500000000 11.500000000 -36.500000000 1.500000000 11.500000000 -36.500000000 2.500000000 11.500000000 -36.500000000 3.500000000 11.500000000 -36.500000000 4.500000000 11.500000000 -36.500000000 5.500000000 11.500000000 -36.500000000 6.500000000 11.500000000 -36.500000000 7.500000000 11.500000000 -36.500000000 8.500000000 11.500000000 -36.500000000 9.500000000 11.500000000 -36.500000000 10.500000000 11.500000000 -36.500000000 11.500000000 11.500000000 -36.500000000 12.500000000 11.500000000 -36.500000000 13.500000000 11.500000000 -36.500000000 14.500000000 11.500000000 -36.500000000 15.500000000 11.500000000 -36.500000000 16.500000000 11.500000000 -36.500000000 17.500000000 11.500000000 -36.500000000 18.500000000 11.500000000 -36.500000000 19.500000000 11.500000000 -36.500000000 20.500000000 11.500000000 -36.500000000 21.500000000 11.500000000 -36.500000000 22.500000000 11.500000000 -36.500000000 23.500000000 11.500000000 -36.500000000 24.500000000 11.500000000 -36.500000000 25.499996185 11.500000000 -36.499996185 26.499954224 11.500000000 -36.499954224 27.499591827 11.500000000 -36.499591827 28.497470856 11.500000000 -36.497474670 29.488407135 11.500000000 -36.488403320 30.458978653 11.500000000 -36.458980560 31.384418488 11.500000000 -36.384422302 32.233222961 11.500000000 -36.233226776 32.981101990 11.500000000 -35.981109619 -33.981101990 12.500000000 -35.981101990 -33.233222961 12.500000000 -36.233222961 -32.384422302 12.500000000 -36.384418488 -31.458978653 12.500000000 -36.458976746 -30.488407135 12.500000000 -36.488403320 -29.497472763 12.500000000 -36.497467041 -28.499593735 12.500000000 -36.499591827 -27.499954224 12.500000000 -36.499954224 -26.499996185 12.500000000 -36.499996185 -25.500000000 12.500000000 -36.500000000 -24.500000000 12.500000000 -36.500000000 -23.500000000 12.500000000 -36.500000000 -22.500000000 12.500000000 -36.500000000 -21.500000000 12.500000000 -36.500000000 -20.500000000 12.500000000 -36.500000000 -19.500000000 12.500000000 -36.500000000 -18.500000000 12.500000000 -36.500000000 -17.500000000 12.500000000 -36.500000000 -16.500000000 12.500000000 -36.500000000 -15.500000000 12.500000000 -36.500000000 -14.500000000 12.500000000 -36.500000000 -13.500000000 12.500000000 -36.500000000 -12.500000000 12.500000000 -36.500000000 -11.500000000 12.500000000 -36.500000000 -10.500000000 12.500000000 -36.500000000 -9.500000000 12.500000000 -36.500000000 -8.500000000 12.500000000 -36.500000000 -7.500000000 12.500000000 -36.500000000 -6.500000000 12.500000000 -36.500000000 -5.500000000 12.500000000 -36.500000000 -4.500000000 12.500000000 -36.500000000 -3.500000000 12.500000000 -36.500000000 -2.500000000 12.500000000 -36.500000000 -1.500000000 12.500000000 -36.500000000 -0.500000000 12.500000000 -36.500000000 0.500000000 12.500000000 -36.500000000 1.500000000 12.500000000 -36.500000000 2.500000000 12.500000000 -36.500000000 3.500000000 12.500000000 -36.500000000 4.500000000 12.500000000 -36.500000000 5.500000000 12.500000000 -36.500000000 6.500000000 12.500000000 -36.500000000 7.500000000 12.500000000 -36.500000000 8.500000000 12.500000000 -36.500000000 9.500000000 12.500000000 -36.500000000 10.500000000 12.500000000 -36.500000000 11.500000000 12.500000000 -36.500000000 12.500000000 12.500000000 -36.500000000 13.500000000 12.500000000 -36.500000000 14.500000000 12.500000000 -36.500000000 15.500000000 12.500000000 -36.500000000 16.500000000 12.500000000 -36.500000000 17.500000000 12.500000000 -36.500000000 18.500000000 12.500000000 -36.500000000 19.500000000 12.500000000 -36.500000000 20.500000000 12.500000000 -36.500000000 21.500000000 12.500000000 -36.500000000 22.500000000 12.500000000 -36.500000000 23.500000000 12.500000000 -36.500000000 24.500000000 12.500000000 -36.500000000 25.499996185 12.500000000 -36.499996185 26.499954224 12.500000000 -36.499954224 27.499591827 12.500000000 -36.499591827 28.497470856 12.500000000 -36.497474670 29.488407135 12.500000000 -36.488403320 30.458978653 12.500000000 -36.458980560 31.384418488 12.500000000 -36.384422302 32.233222961 12.500000000 -36.233226776 32.981101990 12.500000000 -35.981109619 -33.981101990 13.500000000 -35.981101990 -33.233222961 13.500000000 -36.233222961 -32.384422302 13.500000000 -36.384418488 -31.458978653 13.500000000 -36.458976746 -30.488407135 13.500000000 -36.488403320 -29.497472763 13.500000000 -36.497467041 -28.499593735 13.500000000 -36.499591827 -27.499954224 13.500000000 -36.499954224 -26.499996185 13.500000000 -36.499996185 -25.500000000 13.500000000 -36.500000000 -24.500000000 13.500000000 -36.500000000 -23.500000000 13.500000000 -36.500000000 -22.500000000 13.500000000 -36.500000000 -21.500000000 13.500000000 -36.500000000 -20.500000000 13.500000000 -36.500000000 -19.500000000 13.500000000 -36.500000000 -18.500000000 13.500000000 -36.500000000 -17.500000000 13.500000000 -36.500000000 -16.500000000 13.500000000 -36.500000000 -15.500000000 13.500000000 -36.500000000 -14.500000000 13.500000000 -36.500000000 -13.500000000 13.500000000 -36.500000000 -12.500000000 13.500000000 -36.500000000 -11.500000000 13.500000000 -36.500000000 -10.500000000 13.500000000 -36.500000000 -9.500000000 13.500000000 -36.500000000 -8.500000000 13.500000000 -36.500000000 -7.500000000 13.500000000 -36.500000000 -6.500000000 13.500000000 -36.500000000 -5.500000000 13.500000000 -36.500000000 -4.500000000 13.500000000 -36.500000000 -3.500000000 13.500000000 -36.500000000 -2.500000000 13.500000000 -36.500000000 -1.500000000 13.500000000 -36.500000000 -0.500000000 13.500000000 -36.500000000 0.500000000 13.500000000 -36.500000000 1.500000000 13.500000000 -36.500000000 2.500000000 13.500000000 -36.500000000 3.500000000 13.500000000 -36.500000000 4.500000000 13.500000000 -36.500000000 5.500000000 13.500000000 -36.500000000 6.500000000 13.500000000 -36.500000000 7.500000000 13.500000000 -36.500000000 8.500000000 13.500000000 -36.500000000 9.500000000 13.500000000 -36.500000000 10.500000000 13.500000000 -36.500000000 11.500000000 13.500000000 -36.500000000 12.500000000 13.500000000 -36.500000000 13.500000000 13.500000000 -36.500000000 14.500000000 13.500000000 -36.500000000 15.500000000 13.500000000 -36.500000000 16.500000000 13.500000000 -36.500000000 17.500000000 13.500000000 -36.500000000 18.500000000 13.500000000 -36.500000000 19.500000000 13.500000000 -36.500000000 20.500000000 13.500000000 -36.500000000 21.500000000 13.500000000 -36.500000000 22.500000000 13.500000000 -36.500000000 23.500000000 13.500000000 -36.500000000 24.500000000 13.500000000 -36.500000000 25.499996185 13.500000000 -36.499996185 26.499954224 13.500000000 -36.499954224 27.499591827 13.500000000 -36.499591827 28.497470856 13.500000000 -36.497474670 29.488407135 13.500000000 -36.488403320 30.458978653 13.500000000 -36.458980560 31.384418488 13.500000000 -36.384422302 32.233222961 13.500000000 -36.233226776 32.981101990 13.500000000 -35.981109619 -33.981101990 14.500000000 -35.981101990 -33.233222961 14.500000000 -36.233222961 -32.384422302 14.500000000 -36.384418488 -31.458978653 14.500000000 -36.458976746 -30.488407135 14.500000000 -36.488403320 -29.497472763 14.500000000 -36.497467041 -28.499593735 14.500000000 -36.499591827 -27.499954224 14.500000000 -36.499954224 -26.499996185 14.500000000 -36.499996185 -25.500000000 14.500000000 -36.500000000 -24.500000000 14.500000000 -36.500000000 -23.500000000 14.500000000 -36.500000000 -22.500000000 14.500000000 -36.500000000 -21.500000000 14.500000000 -36.500000000 -20.500000000 14.500000000 -36.500000000 -19.500000000 14.500000000 -36.500000000 -18.500000000 14.500000000 -36.500000000 -17.500000000 14.500000000 -36.500000000 -16.500000000 14.500000000 -36.500000000 -15.500000000 14.500000000 -36.500000000 -14.500000000 14.500000000 -36.500000000 -13.500000000 14.500000000 -36.500000000 -12.500000000 14.500000000 -36.500000000 -11.500000000 14.500000000 -36.500000000 -10.500000000 14.500000000 -36.500000000 -9.500000000 14.500000000 -36.500000000 -8.500000000 14.500000000 -36.500000000 -7.500000000 14.500000000 -36.500000000 -6.500000000 14.500000000 -36.500000000 -5.500000000 14.500000000 -36.500000000 -4.500000000 14.500000000 -36.500000000 -3.500000000 14.500000000 -36.500000000 -2.500000000 14.500000000 -36.500000000 -1.500000000 14.500000000 -36.500000000 -0.500000000 14.500000000 -36.500000000 0.500000000 14.500000000 -36.500000000 1.500000000 14.500000000 -36.500000000 2.500000000 14.500000000 -36.500000000 3.500000000 14.500000000 -36.500000000 4.500000000 14.500000000 -36.500000000 5.500000000 14.500000000 -36.500000000 6.500000000 14.500000000 -36.500000000 7.500000000 14.500000000 -36.500000000 8.500000000 14.500000000 -36.500000000 9.500000000 14.500000000 -36.500000000 10.500000000 14.500000000 -36.500000000 11.500000000 14.500000000 -36.500000000 12.500000000 14.500000000 -36.500000000 13.500000000 14.500000000 -36.500000000 14.500000000 14.500000000 -36.500000000 15.500000000 14.500000000 -36.500000000 16.500000000 14.500000000 -36.500000000 17.500000000 14.500000000 -36.500000000 18.500000000 14.500000000 -36.500000000 19.500000000 14.500000000 -36.500000000 20.500000000 14.500000000 -36.500000000 21.500000000 14.500000000 -36.500000000 22.500000000 14.500000000 -36.500000000 23.500000000 14.500000000 -36.500000000 24.500000000 14.500000000 -36.500000000 25.499996185 14.500000000 -36.499996185 26.499954224 14.500000000 -36.499954224 27.499591827 14.500000000 -36.499591827 28.497470856 14.500000000 -36.497474670 29.488407135 14.500000000 -36.488403320 30.458978653 14.500000000 -36.458980560 31.384418488 14.500000000 -36.384422302 32.233222961 14.500000000 -36.233226776 32.981101990 14.500000000 -35.981109619 -33.981101990 15.500000000 -35.981101990 -33.233222961 15.500000000 -36.233222961 -32.384422302 15.500000000 -36.384418488 -31.458978653 15.500000000 -36.458976746 -30.488407135 15.500000000 -36.488403320 -29.497472763 15.500000000 -36.497467041 -28.499593735 15.500000000 -36.499591827 -27.499954224 15.500000000 -36.499954224 -26.499996185 15.500000000 -36.499996185 -25.500000000 15.500000000 -36.500000000 -24.500000000 15.500000000 -36.500000000 -23.500000000 15.500000000 -36.500000000 -22.500000000 15.500000000 -36.500000000 -21.500000000 15.500000000 -36.500000000 -20.500000000 15.500000000 -36.500000000 -19.500000000 15.500000000 -36.500000000 -18.500000000 15.500000000 -36.500000000 -17.500000000 15.500000000 -36.500000000 -16.500000000 15.500000000 -36.500000000 -15.500000000 15.500000000 -36.500000000 -14.500000000 15.500000000 -36.500000000 -13.500000000 15.500000000 -36.500000000 -12.500000000 15.500000000 -36.500000000 -11.500000000 15.500000000 -36.500000000 -10.500000000 15.500000000 -36.500000000 -9.500000000 15.500000000 -36.500000000 -8.500000000 15.500000000 -36.500000000 -7.500000000 15.500000000 -36.500000000 -6.500000000 15.500000000 -36.500000000 -5.500000000 15.500000000 -36.500000000 -4.500000000 15.500000000 -36.500000000 -3.500000000 15.500000000 -36.500000000 -2.500000000 15.500000000 -36.500000000 -1.500000000 15.500000000 -36.500000000 -0.500000000 15.500000000 -36.500000000 0.500000000 15.500000000 -36.500000000 1.500000000 15.500000000 -36.500000000 2.500000000 15.500000000 -36.500000000 3.500000000 15.500000000 -36.500000000 4.500000000 15.500000000 -36.500000000 5.500000000 15.500000000 -36.500000000 6.500000000 15.500000000 -36.500000000 7.500000000 15.500000000 -36.500000000 8.500000000 15.500000000 -36.500000000 9.500000000 15.500000000 -36.500000000 10.500000000 15.500000000 -36.500000000 11.500000000 15.500000000 -36.500000000 12.500000000 15.500000000 -36.500000000 13.500000000 15.500000000 -36.500000000 14.500000000 15.500000000 -36.500000000 15.500000000 15.500000000 -36.500000000 16.500000000 15.500000000 -36.500000000 17.500000000 15.500000000 -36.500000000 18.500000000 15.500000000 -36.500000000 19.500000000 15.500000000 -36.500000000 20.500000000 15.500000000 -36.500000000 21.500000000 15.500000000 -36.500000000 22.500000000 15.500000000 -36.500000000 23.500000000 15.500000000 -36.500000000 24.500000000 15.500000000 -36.500000000 25.499996185 15.500000000 -36.499996185 26.499954224 15.500000000 -36.499954224 27.499591827 15.500000000 -36.499591827 28.497470856 15.500000000 -36.497474670 29.488407135 15.500000000 -36.488403320 30.458978653 15.500000000 -36.458980560 31.384418488 15.500000000 -36.384422302 32.233222961 15.500000000 -36.233226776 32.981101990 15.500000000 -35.981109619 -33.981101990 16.500000000 -35.981101990 -33.233222961 16.500000000 -36.233222961 -32.384422302 16.500000000 -36.384418488 -31.458978653 16.500000000 -36.458976746 -30.488407135 16.500000000 -36.488403320 -29.497472763 16.500000000 -36.497467041 -28.499593735 16.500000000 -36.499591827 -27.499954224 16.500000000 -36.499954224 -26.499996185 16.500000000 -36.499996185 -25.500000000 16.500000000 -36.500000000 -24.500000000 16.500000000 -36.500000000 -23.500000000 16.500000000 -36.500000000 -22.500000000 16.500000000 -36.500000000 -21.500000000 16.500000000 -36.500000000 -20.500000000 16.500000000 -36.500000000 -19.500000000 16.500000000 -36.500000000 -18.500000000 16.500000000 -36.500000000 -17.500000000 16.500000000 -36.500000000 -16.500000000 16.500000000 -36.500000000 -15.500000000 16.500000000 -36.500000000 -14.500000000 16.500000000 -36.500000000 -13.500000000 16.500000000 -36.500000000 -12.500000000 16.500000000 -36.500000000 -11.500000000 16.500000000 -36.500000000 -10.500000000 16.500000000 -36.500000000 -9.500000000 16.500000000 -36.500000000 -8.500000000 16.500000000 -36.500000000 -7.500000000 16.500000000 -36.500000000 -6.500000000 16.500000000 -36.500000000 -5.500000000 16.500000000 -36.500000000 -4.500000000 16.500000000 -36.500000000 -3.500000000 16.500000000 -36.500000000 -2.500000000 16.500000000 -36.500000000 -1.500000000 16.500000000 -36.500000000 -0.500000000 16.500000000 -36.500000000 0.500000000 16.500000000 -36.500000000 1.500000000 16.500000000 -36.500000000 2.500000000 16.500000000 -36.500000000 3.500000000 16.500000000 -36.500000000 4.500000000 16.500000000 -36.500000000 5.500000000 16.500000000 -36.500000000 6.500000000 16.500000000 -36.500000000 7.500000000 16.500000000 -36.500000000 8.500000000 16.500000000 -36.500000000 9.500000000 16.500000000 -36.500000000 10.500000000 16.500000000 -36.500000000 11.500000000 16.500000000 -36.500000000 12.500000000 16.500000000 -36.500000000 13.500000000 16.500000000 -36.500000000 14.500000000 16.500000000 -36.500000000 15.500000000 16.500000000 -36.500000000 16.500000000 16.500000000 -36.500000000 17.500000000 16.500000000 -36.500000000 18.500000000 16.500000000 -36.500000000 19.500000000 16.500000000 -36.500000000 20.500000000 16.500000000 -36.500000000 21.500000000 16.500000000 -36.500000000 22.500000000 16.500000000 -36.500000000 23.500000000 16.500000000 -36.500000000 24.500000000 16.500000000 -36.500000000 25.499996185 16.500000000 -36.499996185 26.499954224 16.500000000 -36.499954224 27.499591827 16.500000000 -36.499591827 28.497470856 16.500000000 -36.497474670 29.488407135 16.500000000 -36.488403320 30.458978653 16.500000000 -36.458980560 31.384418488 16.500000000 -36.384422302 32.233222961 16.500000000 -36.233226776 32.981101990 16.500000000 -35.981109619 -33.981101990 17.500000000 -35.981101990 -33.233222961 17.500000000 -36.233222961 -32.384422302 17.500000000 -36.384418488 -31.458978653 17.500000000 -36.458976746 -30.488407135 17.500000000 -36.488403320 -29.497472763 17.500000000 -36.497467041 -28.499593735 17.500000000 -36.499591827 -27.499954224 17.500000000 -36.499954224 -26.499996185 17.500000000 -36.499996185 -25.500000000 17.500000000 -36.500000000 -24.500000000 17.500000000 -36.500000000 -23.500000000 17.500000000 -36.500000000 -22.500000000 17.500000000 -36.500000000 -21.500000000 17.500000000 -36.500000000 -20.500000000 17.500000000 -36.500000000 -19.500000000 17.500000000 -36.500000000 -18.500000000 17.500000000 -36.500000000 -17.500000000 17.500000000 -36.500000000 -16.500000000 17.500000000 -36.500000000 -15.500000000 17.500000000 -36.500000000 -14.500000000 17.500000000 -36.500000000 -13.500000000 17.500000000 -36.500000000 -12.500000000 17.500000000 -36.500000000 -11.500000000 17.500000000 -36.500000000 -10.500000000 17.500000000 -36.500000000 -9.500000000 17.500000000 -36.500000000 -8.500000000 17.500000000 -36.500000000 -7.500000000 17.500000000 -36.500000000 -6.500000000 17.500000000 -36.500000000 -5.500000000 17.500000000 -36.500000000 -4.500000000 17.500000000 -36.500000000 -3.500000000 17.500000000 -36.500000000 -2.500000000 17.500000000 -36.500000000 -1.500000000 17.500000000 -36.500000000 -0.500000000 17.500000000 -36.500000000 0.500000000 17.500000000 -36.500000000 1.500000000 17.500000000 -36.500000000 2.500000000 17.500000000 -36.500000000 3.500000000 17.500000000 -36.500000000 4.500000000 17.500000000 -36.500000000 5.500000000 17.500000000 -36.500000000 6.500000000 17.500000000 -36.500000000 7.500000000 17.500000000 -36.500000000 8.500000000 17.500000000 -36.500000000 9.500000000 17.500000000 -36.500000000 10.500000000 17.500000000 -36.500000000 11.500000000 17.500000000 -36.500000000 12.500000000 17.500000000 -36.500000000 13.500000000 17.500000000 -36.500000000 14.500000000 17.500000000 -36.500000000 15.500000000 17.500000000 -36.500000000 16.500000000 17.500000000 -36.500000000 17.500000000 17.500000000 -36.500000000 18.500000000 17.500000000 -36.500000000 19.500000000 17.500000000 -36.500000000 20.500000000 17.500000000 -36.500000000 21.500000000 17.500000000 -36.500000000 22.500000000 17.500000000 -36.500000000 23.500000000 17.500000000 -36.500000000 24.500000000 17.500000000 -36.500000000 25.499996185 17.500000000 -36.499996185 26.499954224 17.500000000 -36.499954224 27.499591827 17.500000000 -36.499591827 28.497470856 17.500000000 -36.497474670 29.488407135 17.500000000 -36.488403320 30.458978653 17.500000000 -36.458980560 31.384418488 17.500000000 -36.384422302 32.233222961 17.500000000 -36.233226776 32.981101990 17.500000000 -35.981109619 -33.981101990 18.500000000 -35.981101990 -33.233222961 18.500000000 -36.233222961 -32.384422302 18.500000000 -36.384418488 -31.458978653 18.500000000 -36.458976746 -30.488407135 18.500000000 -36.488403320 -29.497472763 18.500000000 -36.497467041 -28.499593735 18.500000000 -36.499591827 -27.499954224 18.500000000 -36.499954224 -26.499996185 18.500000000 -36.499996185 -25.500000000 18.500000000 -36.500000000 -24.500000000 18.500000000 -36.500000000 -23.500000000 18.500000000 -36.500000000 -22.500000000 18.500000000 -36.500000000 -21.500000000 18.500000000 -36.500000000 -20.500000000 18.500000000 -36.500000000 -19.500000000 18.500000000 -36.500000000 -18.500000000 18.500000000 -36.500000000 -17.500000000 18.500000000 -36.500000000 -16.500000000 18.500000000 -36.500000000 -15.500000000 18.500000000 -36.500000000 -14.500000000 18.500000000 -36.500000000 -13.500000000 18.500000000 -36.500000000 -12.500000000 18.500000000 -36.500000000 -11.500000000 18.500000000 -36.500000000 -10.500000000 18.500000000 -36.500000000 -9.500000000 18.500000000 -36.500000000 -8.500000000 18.500000000 -36.500000000 -7.500000000 18.500000000 -36.500000000 -6.500000000 18.500000000 -36.500000000 -5.500000000 18.500000000 -36.500000000 -4.500000000 18.500000000 -36.500000000 -3.500000000 18.500000000 -36.500000000 -2.500000000 18.500000000 -36.500000000 -1.500000000 18.500000000 -36.500000000 -0.500000000 18.500000000 -36.500000000 0.500000000 18.500000000 -36.500000000 1.500000000 18.500000000 -36.500000000 2.500000000 18.500000000 -36.500000000 3.500000000 18.500000000 -36.500000000 4.500000000 18.500000000 -36.500000000 5.500000000 18.500000000 -36.500000000 6.500000000 18.500000000 -36.500000000 7.500000000 18.500000000 -36.500000000 8.500000000 18.500000000 -36.500000000 9.500000000 18.500000000 -36.500000000 10.500000000 18.500000000 -36.500000000 11.500000000 18.500000000 -36.500000000 12.500000000 18.500000000 -36.500000000 13.500000000 18.500000000 -36.500000000 14.500000000 18.500000000 -36.500000000 15.500000000 18.500000000 -36.500000000 16.500000000 18.500000000 -36.500000000 17.500000000 18.500000000 -36.500000000 18.500000000 18.500000000 -36.500000000 19.500000000 18.500000000 -36.500000000 20.500000000 18.500000000 -36.500000000 21.500000000 18.500000000 -36.500000000 22.500000000 18.500000000 -36.500000000 23.500000000 18.500000000 -36.500000000 24.500000000 18.500000000 -36.500000000 25.499996185 18.500000000 -36.499996185 26.499954224 18.500000000 -36.499954224 27.499591827 18.500000000 -36.499591827 28.497470856 18.500000000 -36.497474670 29.488407135 18.500000000 -36.488403320 30.458978653 18.500000000 -36.458980560 31.384418488 18.500000000 -36.384422302 32.233222961 18.500000000 -36.233226776 32.981101990 18.500000000 -35.981109619 -33.981101990 19.500000000 -35.981101990 -33.233222961 19.500000000 -36.233222961 -32.384422302 19.500000000 -36.384418488 -31.458978653 19.500000000 -36.458976746 -30.488407135 19.500000000 -36.488403320 -29.497472763 19.500000000 -36.497467041 -28.499593735 19.500000000 -36.499591827 -27.499954224 19.500000000 -36.499954224 -26.499996185 19.500000000 -36.499996185 -25.500000000 19.500000000 -36.500000000 -24.500000000 19.500000000 -36.500000000 -23.500000000 19.500000000 -36.500000000 -22.500000000 19.500000000 -36.500000000 -21.500000000 19.500000000 -36.500000000 -20.500000000 19.500000000 -36.500000000 -19.500000000 19.500000000 -36.500000000 -18.500000000 19.500000000 -36.500000000 -17.500000000 19.500000000 -36.500000000 -16.500000000 19.500000000 -36.500000000 -15.500000000 19.500000000 -36.500000000 -14.500000000 19.500000000 -36.500000000 -13.500000000 19.500000000 -36.500000000 -12.500000000 19.500000000 -36.500000000 -11.500000000 19.500000000 -36.500000000 -10.500000000 19.500000000 -36.500000000 -9.500000000 19.500000000 -36.500000000 -8.500000000 19.500000000 -36.500000000 -7.500000000 19.500000000 -36.500000000 -6.500000000 19.500000000 -36.500000000 -5.500000000 19.500000000 -36.500000000 -4.500000000 19.500000000 -36.500000000 -3.500000000 19.500000000 -36.500000000 -2.500000000 19.500000000 -36.500000000 -1.500000000 19.500000000 -36.500000000 -0.500000000 19.500000000 -36.500000000 0.500000000 19.500000000 -36.500000000 1.500000000 19.500000000 -36.500000000 2.500000000 19.500000000 -36.500000000 3.500000000 19.500000000 -36.500000000 4.500000000 19.500000000 -36.500000000 5.500000000 19.500000000 -36.500000000 6.500000000 19.500000000 -36.500000000 7.500000000 19.500000000 -36.500000000 8.500000000 19.500000000 -36.500000000 9.500000000 19.500000000 -36.500000000 10.500000000 19.500000000 -36.500000000 11.500000000 19.500000000 -36.500000000 12.500000000 19.500000000 -36.500000000 13.500000000 19.500000000 -36.500000000 14.500000000 19.500000000 -36.500000000 15.500000000 19.500000000 -36.500000000 16.500000000 19.500000000 -36.500000000 17.500000000 19.500000000 -36.500000000 18.500000000 19.500000000 -36.500000000 19.500000000 19.500000000 -36.500000000 20.500000000 19.500000000 -36.500000000 21.500000000 19.500000000 -36.500000000 22.500000000 19.500000000 -36.500000000 23.500000000 19.500000000 -36.500000000 24.500000000 19.500000000 -36.500000000 25.499996185 19.500000000 -36.499996185 26.499954224 19.500000000 -36.499954224 27.499591827 19.500000000 -36.499591827 28.497470856 19.500000000 -36.497474670 29.488407135 19.500000000 -36.488403320 30.458978653 19.500000000 -36.458980560 31.384418488 19.500000000 -36.384422302 32.233222961 19.500000000 -36.233226776 32.981101990 19.500000000 -35.981109619 -33.981101990 20.500000000 -35.981101990 -33.233222961 20.500000000 -36.233222961 -32.384422302 20.500000000 -36.384418488 -31.458978653 20.500000000 -36.458976746 -30.488407135 20.500000000 -36.488403320 -29.497472763 20.500000000 -36.497467041 -28.499593735 20.500000000 -36.499591827 -27.499954224 20.500000000 -36.499954224 -26.499996185 20.500000000 -36.499996185 -25.500000000 20.500000000 -36.500000000 -24.500000000 20.500000000 -36.500000000 -23.500000000 20.500000000 -36.500000000 -22.500000000 20.500000000 -36.500000000 -21.500000000 20.500000000 -36.500000000 -20.500000000 20.500000000 -36.500000000 -19.500000000 20.500000000 -36.500000000 -18.500000000 20.500000000 -36.500000000 -17.500000000 20.500000000 -36.500000000 -16.500000000 20.500000000 -36.500000000 -15.500000000 20.500000000 -36.500000000 -14.500000000 20.500000000 -36.500000000 -13.500000000 20.500000000 -36.500000000 -12.500000000 20.500000000 -36.500000000 -11.500000000 20.500000000 -36.500000000 -10.500000000 20.500000000 -36.500000000 -9.500000000 20.500000000 -36.500000000 -8.500000000 20.500000000 -36.500000000 -7.500000000 20.500000000 -36.500000000 -6.500000000 20.500000000 -36.500000000 -5.500000000 20.500000000 -36.500000000 -4.500000000 20.500000000 -36.500000000 -3.500000000 20.500000000 -36.500000000 -2.500000000 20.500000000 -36.500000000 -1.500000000 20.500000000 -36.500000000 -0.500000000 20.500000000 -36.500000000 0.500000000 20.500000000 -36.500000000 1.500000000 20.500000000 -36.500000000 2.500000000 20.500000000 -36.500000000 3.500000000 20.500000000 -36.500000000 4.500000000 20.500000000 -36.500000000 5.500000000 20.500000000 -36.500000000 6.500000000 20.500000000 -36.500000000 7.500000000 20.500000000 -36.500000000 8.500000000 20.500000000 -36.500000000 9.500000000 20.500000000 -36.500000000 10.500000000 20.500000000 -36.500000000 11.500000000 20.500000000 -36.500000000 12.500000000 20.500000000 -36.500000000 13.500000000 20.500000000 -36.500000000 14.500000000 20.500000000 -36.500000000 15.500000000 20.500000000 -36.500000000 16.500000000 20.500000000 -36.500000000 17.500000000 20.500000000 -36.500000000 18.500000000 20.500000000 -36.500000000 19.500000000 20.500000000 -36.500000000 20.500000000 20.500000000 -36.500000000 21.500000000 20.500000000 -36.500000000 22.500000000 20.500000000 -36.500000000 23.500000000 20.500000000 -36.500000000 24.500000000 20.500000000 -36.500000000 25.499996185 20.500000000 -36.499996185 26.499954224 20.500000000 -36.499954224 27.499591827 20.500000000 -36.499591827 28.497470856 20.500000000 -36.497474670 29.488407135 20.500000000 -36.488403320 30.458978653 20.500000000 -36.458980560 31.384418488 20.500000000 -36.384422302 32.233222961 20.500000000 -36.233226776 32.981101990 20.500000000 -35.981109619 -33.981101990 21.500000000 -35.981101990 -33.233222961 21.500000000 -36.233222961 -32.384422302 21.500000000 -36.384418488 -31.458978653 21.500000000 -36.458976746 -30.488407135 21.500000000 -36.488403320 -29.497472763 21.500000000 -36.497467041 -28.499593735 21.500000000 -36.499591827 -27.499954224 21.500000000 -36.499954224 -26.499996185 21.500000000 -36.499996185 -25.500000000 21.500000000 -36.500000000 -24.500000000 21.500000000 -36.500000000 -23.500000000 21.500000000 -36.500000000 -22.500000000 21.500000000 -36.500000000 -21.500000000 21.500000000 -36.500000000 -20.500000000 21.500000000 -36.500000000 -19.500000000 21.500000000 -36.500000000 -18.500000000 21.500000000 -36.500000000 -17.500000000 21.500000000 -36.500000000 -16.500000000 21.500000000 -36.500000000 -15.500000000 21.500000000 -36.500000000 -14.500000000 21.500000000 -36.500000000 -13.500000000 21.500000000 -36.500000000 -12.500000000 21.500000000 -36.500000000 -11.500000000 21.500000000 -36.500000000 -10.500000000 21.500000000 -36.500000000 -9.500000000 21.500000000 -36.500000000 -8.500000000 21.500000000 -36.500000000 -7.500000000 21.500000000 -36.500000000 -6.500000000 21.500000000 -36.500000000 -5.500000000 21.500000000 -36.500000000 -4.500000000 21.500000000 -36.500000000 -3.500000000 21.500000000 -36.500000000 -2.500000000 21.500000000 -36.500000000 -1.500000000 21.500000000 -36.500000000 -0.500000000 21.500000000 -36.500000000 0.500000000 21.500000000 -36.500000000 1.500000000 21.500000000 -36.500000000 2.500000000 21.500000000 -36.500000000 3.500000000 21.500000000 -36.500000000 4.500000000 21.500000000 -36.500000000 5.500000000 21.500000000 -36.500000000 6.500000000 21.500000000 -36.500000000 7.500000000 21.500000000 -36.500000000 8.500000000 21.500000000 -36.500000000 9.500000000 21.500000000 -36.500000000 10.500000000 21.500000000 -36.500000000 11.500000000 21.500000000 -36.500000000 12.500000000 21.500000000 -36.500000000 13.500000000 21.500000000 -36.500000000 14.500000000 21.500000000 -36.500000000 15.500000000 21.500000000 -36.500000000 16.500000000 21.500000000 -36.500000000 17.500000000 21.500000000 -36.500000000 18.500000000 21.500000000 -36.500000000 19.500000000 21.500000000 -36.500000000 20.500000000 21.500000000 -36.500000000 21.500000000 21.500000000 -36.500000000 22.500000000 21.500000000 -36.500000000 23.500000000 21.500000000 -36.500000000 24.500000000 21.500000000 -36.500000000 25.499996185 21.500000000 -36.499996185 26.499954224 21.500000000 -36.499954224 27.499591827 21.500000000 -36.499591827 28.497470856 21.500000000 -36.497474670 29.488407135 21.500000000 -36.488403320 30.458978653 21.500000000 -36.458980560 31.384418488 21.500000000 -36.384422302 32.233222961 21.500000000 -36.233226776 32.981101990 21.500000000 -35.981109619 -33.981101990 22.500000000 -35.981101990 -33.233222961 22.500000000 -36.233222961 -32.384422302 22.500000000 -36.384418488 -31.458978653 22.500000000 -36.458976746 -30.488407135 22.500000000 -36.488403320 -29.497472763 22.500000000 -36.497467041 -28.499593735 22.500000000 -36.499591827 -27.499954224 22.500000000 -36.499954224 -26.499996185 22.500000000 -36.499996185 -25.500000000 22.500000000 -36.500000000 -24.500000000 22.500000000 -36.500000000 -23.500000000 22.500000000 -36.500000000 -22.500000000 22.500000000 -36.500000000 -21.500000000 22.500000000 -36.500000000 -20.500000000 22.500000000 -36.500000000 -19.500000000 22.500000000 -36.500000000 -18.500000000 22.500000000 -36.500000000 -17.500000000 22.500000000 -36.500000000 -16.500000000 22.500000000 -36.500000000 -15.500000000 22.500000000 -36.500000000 -14.500000000 22.500000000 -36.500000000 -13.500000000 22.500000000 -36.500000000 -12.500000000 22.500000000 -36.500000000 -11.500000000 22.500000000 -36.500000000 -10.500000000 22.500000000 -36.500000000 -9.500000000 22.500000000 -36.500000000 -8.500000000 22.500000000 -36.500000000 -7.500000000 22.500000000 -36.500000000 -6.500000000 22.500000000 -36.500000000 -5.500000000 22.500000000 -36.500000000 -4.500000000 22.500000000 -36.500000000 -3.500000000 22.500000000 -36.500000000 -2.500000000 22.500000000 -36.500000000 -1.500000000 22.500000000 -36.500000000 -0.500000000 22.500000000 -36.500000000 0.500000000 22.500000000 -36.500000000 1.500000000 22.500000000 -36.500000000 2.500000000 22.500000000 -36.500000000 3.500000000 22.500000000 -36.500000000 4.500000000 22.500000000 -36.500000000 5.500000000 22.500000000 -36.500000000 6.500000000 22.500000000 -36.500000000 7.500000000 22.500000000 -36.500000000 8.500000000 22.500000000 -36.500000000 9.500000000 22.500000000 -36.500000000 10.500000000 22.500000000 -36.500000000 11.500000000 22.500000000 -36.500000000 12.500000000 22.500000000 -36.500000000 13.500000000 22.500000000 -36.500000000 14.500000000 22.500000000 -36.500000000 15.500000000 22.500000000 -36.500000000 16.500000000 22.500000000 -36.500000000 17.500000000 22.500000000 -36.500000000 18.500000000 22.500000000 -36.500000000 19.500000000 22.500000000 -36.500000000 20.500000000 22.500000000 -36.500000000 21.500000000 22.500000000 -36.500000000 22.500000000 22.500000000 -36.500000000 23.500000000 22.500000000 -36.500000000 24.500000000 22.500000000 -36.500000000 25.499996185 22.500000000 -36.499996185 26.499954224 22.500000000 -36.499954224 27.499591827 22.500000000 -36.499591827 28.497470856 22.500000000 -36.497474670 29.488407135 22.500000000 -36.488403320 30.458978653 22.500000000 -36.458980560 31.384418488 22.500000000 -36.384422302 32.233222961 22.500000000 -36.233226776 32.981101990 22.500000000 -35.981109619 -33.981101990 23.499998093 -35.981101990 -33.233222961 23.500000000 -36.233222961 -32.384422302 23.500000000 -36.384418488 -31.458978653 23.500000000 -36.458976746 -30.488407135 23.500000000 -36.488403320 -29.497472763 23.500000000 -36.497467041 -28.499593735 23.500000000 -36.499591827 -27.499954224 23.500000000 -36.499954224 -26.499996185 23.500000000 -36.499996185 -25.500000000 23.500000000 -36.500000000 -24.500000000 23.500000000 -36.500000000 -23.500000000 23.500000000 -36.500000000 -22.500000000 23.500000000 -36.500000000 -21.500000000 23.500000000 -36.500000000 -20.500000000 23.500000000 -36.500000000 -19.500000000 23.500000000 -36.500000000 -18.500000000 23.500000000 -36.500000000 -17.500000000 23.500000000 -36.500000000 -16.500000000 23.500000000 -36.500000000 -15.500000000 23.500000000 -36.500000000 -14.500000000 23.500000000 -36.500000000 -13.500000000 23.500000000 -36.500000000 -12.500000000 23.500000000 -36.500000000 -11.500000000 23.500000000 -36.500000000 -10.500000000 23.500000000 -36.500000000 -9.500000000 23.500000000 -36.500000000 -8.500000000 23.500000000 -36.500000000 -7.500000000 23.500000000 -36.500000000 -6.500000000 23.500000000 -36.500000000 -5.500000000 23.500000000 -36.500000000 -4.500000000 23.500000000 -36.500000000 -3.500000000 23.500000000 -36.500000000 -2.500000000 23.500000000 -36.500000000 -1.500000000 23.500000000 -36.500000000 -0.500000000 23.500000000 -36.500000000 0.500000000 23.500000000 -36.500000000 1.500000000 23.500000000 -36.500000000 2.500000000 23.500000000 -36.500000000 3.500000000 23.500000000 -36.500000000 4.500000000 23.500000000 -36.500000000 5.500000000 23.500000000 -36.500000000 6.500000000 23.500000000 -36.500000000 7.500000000 23.500000000 -36.500000000 8.500000000 23.500000000 -36.500000000 9.500000000 23.500000000 -36.500000000 10.500000000 23.500000000 -36.500000000 11.500000000 23.500000000 -36.500000000 12.500000000 23.500000000 -36.500000000 13.500000000 23.500000000 -36.500000000 14.500000000 23.500000000 -36.500000000 15.500000000 23.500000000 -36.500000000 16.500000000 23.500000000 -36.500000000 17.500000000 23.500000000 -36.500000000 18.500000000 23.500000000 -36.500000000 19.500000000 23.500000000 -36.500000000 20.500000000 23.500000000 -36.500000000 21.500000000 23.500000000 -36.500000000 22.500000000 23.500000000 -36.500000000 23.500000000 23.500000000 -36.500000000 24.500000000 23.500000000 -36.500000000 25.499996185 23.500000000 -36.499996185 26.499954224 23.500000000 -36.499954224 27.499591827 23.500000000 -36.499591827 28.497470856 23.500000000 -36.497474670 29.488407135 23.500000000 -36.488403320 30.458978653 23.500000000 -36.458980560 31.384418488 23.500000000 -36.384422302 32.233222961 23.500000000 -36.233222961 32.981101990 23.499998093 -35.981105804 -33.981086731 24.499979019 -35.981090546 -33.233219147 24.499984741 -36.233207703 -32.384422302 24.499996185 -36.384407043 -31.458978653 24.500000000 -36.458972931 -30.488407135 24.500000000 -36.488403320 -29.497472763 24.500000000 -36.497467041 -28.499593735 24.500000000 -36.499591827 -27.499954224 24.500000000 -36.499954224 -26.499996185 24.500000000 -36.499996185 -25.500000000 24.500000000 -36.500000000 -24.500000000 24.500000000 -36.500000000 -23.500000000 24.500000000 -36.500000000 -22.500000000 24.500000000 -36.500000000 -21.500000000 24.500000000 -36.500000000 -20.500000000 24.500000000 -36.500000000 -19.500000000 24.500000000 -36.500000000 -18.500000000 24.500000000 -36.500000000 -17.500000000 24.500000000 -36.500000000 -16.500000000 24.500000000 -36.500000000 -15.500000000 24.500000000 -36.500000000 -14.500000000 24.500000000 -36.500000000 -13.500000000 24.500000000 -36.500000000 -12.500000000 24.500000000 -36.500000000 -11.500000000 24.500000000 -36.500000000 -10.500000000 24.500000000 -36.500000000 -9.500000000 24.500000000 -36.500000000 -8.500000000 24.500000000 -36.500000000 -7.500000000 24.500000000 -36.500000000 -6.500000000 24.500000000 -36.500000000 -5.500000000 24.500000000 -36.500000000 -4.500000000 24.500000000 -36.500000000 -3.500000000 24.500000000 -36.500000000 -2.500000000 24.500000000 -36.500000000 -1.500000000 24.500000000 -36.500000000 -0.500000000 24.500000000 -36.500000000 0.500000000 24.500000000 -36.500000000 1.500000000 24.500000000 -36.500000000 2.500000000 24.500000000 -36.500000000 3.500000000 24.500000000 -36.500000000 4.500000000 24.500000000 -36.500000000 5.500000000 24.500000000 -36.500000000 6.500000000 24.500000000 -36.500000000 7.500000000 24.500000000 -36.500000000 8.500000000 24.500000000 -36.500000000 9.500000000 24.500000000 -36.500000000 10.500000000 24.500000000 -36.500000000 11.500000000 24.500000000 -36.500000000 12.500000000 24.500000000 -36.500000000 13.500000000 24.500000000 -36.500000000 14.500000000 24.500000000 -36.500000000 15.500000000 24.500000000 -36.500000000 16.500000000 24.500000000 -36.500000000 17.500000000 24.500000000 -36.500000000 18.500000000 24.500000000 -36.500000000 19.500000000 24.500000000 -36.500000000 20.500000000 24.500000000 -36.500000000 21.500000000 24.500000000 -36.500000000 22.500000000 24.500000000 -36.500000000 23.500000000 24.500000000 -36.500000000 24.500000000 24.500000000 -36.500000000 25.499996185 24.500000000 -36.499996185 26.499954224 24.500000000 -36.499954224 27.499591827 24.500000000 -36.499591827 28.497470856 24.500000000 -36.497474670 29.488407135 24.500000000 -36.488403320 30.458978653 24.500000000 -36.458976746 31.384418488 24.499996185 -36.384407043 32.233219147 24.499988556 -36.233207703 32.981090546 24.499979019 -35.981090546 -33.980976105 25.499826431 -35.980960846 -33.233169556 25.499874115 -36.233074188 -32.384407043 25.499948502 -36.384307861 -31.458978653 25.499988556 -36.458930969 -30.488407135 25.499996185 -36.488388062 -29.497472763 25.499996185 -36.497467041 -28.499593735 25.499996185 -36.499584198 -27.499954224 25.499996185 -36.499950409 -26.499996185 25.499996185 -36.499992371 -25.500000000 25.499996185 -36.499996185 -24.500000000 25.499996185 -36.499996185 -23.500000000 25.499996185 -36.499996185 -22.500000000 25.499996185 -36.499996185 -21.500000000 25.499996185 -36.499996185 -20.500000000 25.499996185 -36.499996185 -19.500000000 25.499996185 -36.499996185 -18.500000000 25.499996185 -36.499996185 -17.500000000 25.499996185 -36.499996185 -16.500000000 25.499996185 -36.499996185 -15.500000000 25.499996185 -36.499996185 -14.500000000 25.499996185 -36.499996185 -13.500000000 25.499996185 -36.499996185 -12.500000000 25.499996185 -36.499996185 -11.500000000 25.499996185 -36.499996185 -10.500000000 25.499996185 -36.499996185 -9.500000000 25.499996185 -36.499996185 -8.500000000 25.499996185 -36.499996185 -7.500000000 25.499996185 -36.499996185 -6.500000000 25.499996185 -36.499996185 -5.500000000 25.499996185 -36.499996185 -4.500000000 25.499996185 -36.499996185 -3.500000000 25.499996185 -36.499996185 -2.500000000 25.499996185 -36.499996185 -1.500000000 25.499996185 -36.499996185 -0.500000000 25.499996185 -36.499996185 0.500000000 25.499996185 -36.499996185 1.500000000 25.499996185 -36.499996185 2.500000000 25.499996185 -36.499996185 3.500000000 25.499996185 -36.499996185 4.500000000 25.499996185 -36.499996185 5.500000000 25.499996185 -36.499996185 6.500000000 25.499996185 -36.499996185 7.500000000 25.499996185 -36.499996185 8.500000000 25.499996185 -36.499996185 9.500000000 25.499996185 -36.499996185 10.500000000 25.499996185 -36.499996185 11.500000000 25.499996185 -36.499996185 12.500000000 25.499996185 -36.499996185 13.500000000 25.499996185 -36.499996185 14.500000000 25.499996185 -36.499996185 15.500000000 25.499996185 -36.499996185 16.500000000 25.499996185 -36.499996185 17.500000000 25.499996185 -36.499996185 18.500000000 25.499996185 -36.499996185 19.500000000 25.499996185 -36.499996185 20.500000000 25.499996185 -36.499996185 21.500000000 25.499996185 -36.499996185 22.500000000 25.499996185 -36.499996185 23.500000000 25.499996185 -36.499996185 24.500000000 25.499996185 -36.499996185 25.499996185 25.499996185 -36.499992371 26.499954224 25.499996185 -36.499950409 27.499591827 25.499996185 -36.499588013 28.497470856 25.499996185 -36.497467041 29.488407135 25.499996185 -36.488388062 30.458974838 25.499988556 -36.458934784 31.384405136 25.499948502 -36.384307861 32.233169556 25.499874115 -36.233074188 32.980976105 25.499824524 -35.980957031 -33.980327606 26.498950958 -35.980201721 -33.232860565 26.499225616 -36.232303619 -32.384296417 26.499618530 -36.383720398 -31.458948135 26.499858856 -36.458606720 -30.488397598 26.499938965 -36.488258362 -29.497472763 26.499954224 -36.497406006 -28.499593735 26.499954224 -36.499542236 -27.499954224 26.499954224 -36.499908447 -26.499996185 26.499954224 -36.499950409 -25.500000000 26.499954224 -36.499950409 -24.500000000 26.499954224 -36.499950409 -23.500000000 26.499954224 -36.499950409 -22.500000000 26.499954224 -36.499950409 -21.500000000 26.499954224 -36.499950409 -20.500000000 26.499954224 -36.499950409 -19.500000000 26.499954224 -36.499950409 -18.500000000 26.499954224 -36.499950409 -17.500000000 26.499954224 -36.499950409 -16.500000000 26.499954224 -36.499950409 -15.500000000 26.499954224 -36.499950409 -14.500000000 26.499954224 -36.499950409 -13.500000000 26.499954224 -36.499950409 -12.500000000 26.499954224 -36.499950409 -11.500000000 26.499954224 -36.499950409 -10.500000000 26.499954224 -36.499950409 -9.500000000 26.499954224 -36.499950409 -8.500000000 26.499954224 -36.499950409 -7.500000000 26.499954224 -36.499950409 -6.500000000 26.499954224 -36.499950409 -5.500000000 26.499954224 -36.499950409 -4.500000000 26.499954224 -36.499950409 -3.500000000 26.499954224 -36.499950409 -2.500000000 26.499954224 -36.499950409 -1.500000000 26.499954224 -36.499950409 -0.500000000 26.499954224 -36.499950409 0.500000000 26.499954224 -36.499950409 1.500000000 26.499954224 -36.499950409 2.500000000 26.499954224 -36.499950409 3.500000000 26.499954224 -36.499950409 4.500000000 26.499954224 -36.499950409 5.500000000 26.499954224 -36.499950409 6.500000000 26.499954224 -36.499950409 7.500000000 26.499954224 -36.499950409 8.500000000 26.499954224 -36.499950409 9.500000000 26.499954224 -36.499950409 10.500000000 26.499954224 -36.499950409 11.500000000 26.499954224 -36.499950409 12.500000000 26.499954224 -36.499950409 13.500000000 26.499954224 -36.499950409 14.500000000 26.499954224 -36.499950409 15.500000000 26.499954224 -36.499950409 16.500000000 26.499954224 -36.499950409 17.500000000 26.499954224 -36.499950409 18.500000000 26.499954224 -36.499950409 19.500000000 26.499954224 -36.499950409 20.500000000 26.499954224 -36.499950409 21.500000000 26.499954224 -36.499950409 22.500000000 26.499954224 -36.499950409 23.500000000 26.499954224 -36.499950409 24.500000000 26.499954224 -36.499950409 25.499996185 26.499954224 -36.499950409 26.499954224 26.499954224 -36.499908447 27.499591827 26.499954224 -36.499542236 28.497470856 26.499954224 -36.497406006 29.488399506 26.499938965 -36.488258362 30.458948135 26.499858856 -36.458606720 31.384298325 26.499622345 -36.383720398 32.232864380 26.499225616 -36.232303619 32.980335236 26.498950958 -35.980201721 -33.977615356 27.495168686 -35.976860046 -33.231597900 27.496377945 -36.228958130 -32.383811951 27.498052597 -36.381027222 -31.458766937 27.499073029 -36.456939697 -30.488346100 27.499475479 -36.487373352 -29.497461319 27.499576569 -36.496910095 -28.499593735 27.499591827 -36.499160767 -27.499954224 27.499591827 -36.499542236 -26.499996185 27.499591827 -36.499584198 -25.500000000 27.499591827 -36.499591827 -24.500000000 27.499591827 -36.499591827 -23.500000000 27.499591827 -36.499591827 -22.500000000 27.499591827 -36.499591827 -21.500000000 27.499591827 -36.499591827 -20.500000000 27.499591827 -36.499591827 -19.500000000 27.499591827 -36.499591827 -18.500000000 27.499591827 -36.499591827 -17.500000000 27.499591827 -36.499591827 -16.500000000 27.499591827 -36.499591827 -15.500000000 27.499591827 -36.499591827 -14.500000000 27.499591827 -36.499591827 -13.500000000 27.499591827 -36.499591827 -12.500000000 27.499591827 -36.499591827 -11.500000000 27.499591827 -36.499591827 -10.500000000 27.499591827 -36.499591827 -9.500000000 27.499591827 -36.499591827 -8.500000000 27.499591827 -36.499591827 -7.500000000 27.499591827 -36.499591827 -6.500000000 27.499591827 -36.499591827 -5.500000000 27.499591827 -36.499591827 -4.500000000 27.499591827 -36.499591827 -3.500000000 27.499591827 -36.499591827 -2.500000000 27.499591827 -36.499591827 -1.500000000 27.499591827 -36.499591827 -0.500000000 27.499591827 -36.499591827 0.500000000 27.499591827 -36.499591827 1.500000000 27.499591827 -36.499591827 2.500000000 27.499591827 -36.499591827 3.500000000 27.499591827 -36.499591827 4.500000000 27.499591827 -36.499591827 5.500000000 27.499591827 -36.499591827 6.500000000 27.499591827 -36.499591827 7.500000000 27.499591827 -36.499591827 8.500000000 27.499591827 -36.499591827 9.500000000 27.499591827 -36.499591827 10.500000000 27.499591827 -36.499591827 11.500000000 27.499591827 -36.499591827 12.500000000 27.499591827 -36.499591827 13.500000000 27.499591827 -36.499591827 14.500000000 27.499591827 -36.499591827 15.500000000 27.499591827 -36.499591827 16.500000000 27.499591827 -36.499591827 17.500000000 27.499591827 -36.499591827 18.500000000 27.499591827 -36.499591827 19.500000000 27.499591827 -36.499591827 20.500000000 27.499591827 -36.499591827 21.500000000 27.499591827 -36.499591827 22.500000000 27.499591827 -36.499591827 23.500000000 27.499591827 -36.499591827 24.500000000 27.499591827 -36.499591827 25.499996185 27.499591827 -36.499584198 26.499954224 27.499591827 -36.499542236 27.499591827 27.499591827 -36.499160767 28.497457504 27.499576569 -36.496910095 29.488346100 27.499475479 -36.487373352 30.458766937 27.499073029 -36.456939697 31.383813858 27.498052597 -36.381027222 32.231605530 27.496377945 -36.228958130 32.977619171 27.495168686 -35.976860046 -33.968864441 28.481933594 -35.965766907 -33.227874756 28.486719131 -36.217517853 -32.382312775 28.492321014 -36.371490479 -31.458078384 28.495611191 -36.450428009 -30.488048553 28.496957779 -36.483337402 -29.497375488 28.497371674 -36.494178772 -28.499578476 28.497461319 -36.496910095 -27.499954224 28.497470856 -36.497406006 -26.499996185 28.497470856 -36.497467041 -25.500000000 28.497470856 -36.497467041 -24.500000000 28.497470856 -36.497467041 -23.500000000 28.497470856 -36.497467041 -22.500000000 28.497470856 -36.497467041 -21.500000000 28.497470856 -36.497467041 -20.500000000 28.497470856 -36.497467041 -19.500000000 28.497470856 -36.497467041 -18.500000000 28.497470856 -36.497467041 -17.500000000 28.497470856 -36.497467041 -16.500000000 28.497470856 -36.497467041 -15.500000000 28.497470856 -36.497467041 -14.500000000 28.497470856 -36.497467041 -13.500000000 28.497470856 -36.497467041 -12.500000000 28.497470856 -36.497467041 -11.500000000 28.497470856 -36.497467041 -10.500000000 28.497470856 -36.497467041 -9.500000000 28.497470856 -36.497467041 -8.500000000 28.497470856 -36.497467041 -7.500000000 28.497470856 -36.497467041 -6.500000000 28.497470856 -36.497467041 -5.500000000 28.497470856 -36.497467041 -4.500000000 28.497470856 -36.497467041 -3.500000000 28.497470856 -36.497467041 -2.500000000 28.497470856 -36.497467041 -1.500000000 28.497470856 -36.497467041 -0.500000000 28.497470856 -36.497467041 0.500000000 28.497470856 -36.497467041 1.500000000 28.497470856 -36.497467041 2.500000000 28.497470856 -36.497467041 3.500000000 28.497470856 -36.497467041 4.500000000 28.497470856 -36.497467041 5.500000000 28.497470856 -36.497467041 6.500000000 28.497470856 -36.497467041 7.500000000 28.497470856 -36.497467041 8.500000000 28.497470856 -36.497467041 9.500000000 28.497470856 -36.497467041 10.500000000 28.497470856 -36.497467041 11.500000000 28.497470856 -36.497467041 12.500000000 28.497470856 -36.497467041 13.500000000 28.497470856 -36.497467041 14.500000000 28.497470856 -36.497467041 15.500000000 28.497470856 -36.497467041 16.500000000 28.497470856 -36.497467041 17.500000000 28.497470856 -36.497467041 18.500000000 28.497470856 -36.497467041 19.500000000 28.497470856 -36.497467041 20.500000000 28.497470856 -36.497467041 21.500000000 28.497470856 -36.497467041 22.500000000 28.497470856 -36.497467041 23.500000000 28.497470856 -36.497467041 24.500000000 28.497470856 -36.497467041 25.499996185 28.497470856 -36.497467041 26.499954224 28.497470856 -36.497406006 27.499576569 28.497457504 -36.496910095 28.497375488 28.497371674 -36.494178772 29.488048553 28.496957779 -36.483337402 30.458078384 28.495609283 -36.450428009 31.382312775 28.492321014 -36.371490479 32.227874756 28.486719131 -36.217510223 32.968864441 28.481933594 -35.965766907 -33.946815491 29.442840576 -35.937091827 -33.220714569 29.460592270 -36.185966492 -32.379222870 29.476003647 -36.344280243 -31.456085205 29.483789444 -36.430480957 -30.486968994 29.486965179 -36.469230652 -29.496959686 29.488052368 -36.483337402 -28.499475479 29.488346100 -36.487373352 -27.499938965 29.488399506 -36.488258362 -26.499996185 29.488407135 -36.488391876 -25.500000000 29.488407135 -36.488403320 -24.500000000 29.488407135 -36.488403320 -23.500000000 29.488407135 -36.488403320 -22.500000000 29.488407135 -36.488403320 -21.500000000 29.488407135 -36.488403320 -20.500000000 29.488407135 -36.488403320 -19.500000000 29.488407135 -36.488403320 -18.500000000 29.488407135 -36.488403320 -17.500000000 29.488407135 -36.488403320 -16.500000000 29.488407135 -36.488403320 -15.500000000 29.488407135 -36.488403320 -14.500000000 29.488407135 -36.488403320 -13.500000000 29.488407135 -36.488403320 -12.500000000 29.488407135 -36.488403320 -11.500000000 29.488407135 -36.488403320 -10.500000000 29.488407135 -36.488403320 -9.500000000 29.488407135 -36.488403320 -8.500000000 29.488407135 -36.488403320 -7.500000000 29.488407135 -36.488403320 -6.500000000 29.488407135 -36.488403320 -5.500000000 29.488407135 -36.488403320 -4.500000000 29.488407135 -36.488403320 -3.500000000 29.488407135 -36.488403320 -2.500000000 29.488407135 -36.488403320 -1.500000000 29.488407135 -36.488403320 -0.500000000 29.488407135 -36.488403320 0.500000000 29.488407135 -36.488403320 1.500000000 29.488407135 -36.488403320 2.500000000 29.488407135 -36.488403320 3.500000000 29.488407135 -36.488403320 4.500000000 29.488407135 -36.488403320 5.500000000 29.488407135 -36.488403320 6.500000000 29.488407135 -36.488403320 7.500000000 29.488407135 -36.488403320 8.500000000 29.488407135 -36.488403320 9.500000000 29.488407135 -36.488403320 10.500000000 29.488407135 -36.488403320 11.500000000 29.488407135 -36.488403320 12.500000000 29.488407135 -36.488403320 13.500000000 29.488407135 -36.488403320 14.500000000 29.488407135 -36.488403320 15.500000000 29.488407135 -36.488403320 16.500000000 29.488407135 -36.488403320 17.500000000 29.488407135 -36.488403320 18.500000000 29.488407135 -36.488403320 19.500000000 29.488407135 -36.488403320 20.500000000 29.488407135 -36.488403320 21.500000000 29.488407135 -36.488403320 22.500000000 29.488407135 -36.488403320 23.500000000 29.488407135 -36.488403320 24.500000000 29.488407135 -36.488403320 25.499996185 29.488407135 -36.488391876 26.499938965 29.488399506 -36.488258362 27.499475479 29.488348007 -36.487377167 28.496957779 29.488052368 -36.483337402 29.486968994 29.486968994 -36.469238281 30.456085205 29.483785629 -36.430473328 31.379222870 29.476003647 -36.344280243 32.220718384 29.460596085 -36.185966492 32.946807861 29.442840576 -35.937095642 -33.903377533 30.336599350 -35.879737854 -33.216842651 30.405670166 -36.112342834 -32.375358582 30.438953400 -36.280395508 -31.451217651 30.451217651 -36.380989075 -30.483789444 30.456085205 -36.430473328 -29.495611191 30.458078384 -36.450424194 -28.499073029 30.458770752 -36.456939697 -27.499858856 30.458950043 -36.458606720 -26.499988556 30.458980560 -36.458930969 -25.500000000 30.458980560 -36.458976746 -24.500000000 30.458980560 -36.458980560 -23.500000000 30.458980560 -36.458980560 -22.500000000 30.458980560 -36.458980560 -21.500000000 30.458980560 -36.458980560 -20.500000000 30.458980560 -36.458980560 -19.500000000 30.458980560 -36.458980560 -18.500000000 30.458980560 -36.458980560 -17.500000000 30.458980560 -36.458980560 -16.500000000 30.458980560 -36.458980560 -15.500000000 30.458980560 -36.458980560 -14.500000000 30.458980560 -36.458980560 -13.500000000 30.458980560 -36.458980560 -12.500000000 30.458980560 -36.458980560 -11.500000000 30.458980560 -36.458980560 -10.500000000 30.458980560 -36.458980560 -9.500000000 30.458980560 -36.458980560 -8.500000000 30.458980560 -36.458980560 -7.500000000 30.458980560 -36.458980560 -6.500000000 30.458980560 -36.458980560 -5.500000000 30.458980560 -36.458980560 -4.500000000 30.458980560 -36.458980560 -3.500000000 30.458980560 -36.458980560 -2.500000000 30.458980560 -36.458980560 -1.500000000 30.458980560 -36.458980560 -0.500000000 30.458980560 -36.458980560 0.500000000 30.458980560 -36.458980560 1.500000000 30.458980560 -36.458980560 2.500000000 30.458980560 -36.458980560 3.500000000 30.458980560 -36.458980560 4.500000000 30.458980560 -36.458980560 5.500000000 30.458980560 -36.458980560 6.500000000 30.458980560 -36.458980560 7.500000000 30.458980560 -36.458980560 8.500000000 30.458980560 -36.458980560 9.500000000 30.458980560 -36.458980560 10.500000000 30.458980560 -36.458980560 11.500000000 30.458980560 -36.458980560 12.500000000 30.458980560 -36.458980560 13.500000000 30.458980560 -36.458980560 14.500000000 30.458980560 -36.458980560 15.500000000 30.458980560 -36.458980560 16.500000000 30.458980560 -36.458980560 17.500000000 30.458980560 -36.458980560 18.500000000 30.458980560 -36.458980560 19.500000000 30.458980560 -36.458980560 20.500000000 30.458980560 -36.458980560 21.500000000 30.458980560 -36.458980560 22.500000000 30.458980560 -36.458980560 23.500000000 30.458980560 -36.458980560 24.500000000 30.458980560 -36.458976746 25.499988556 30.458978653 -36.458934784 26.499858856 30.458948135 -36.458606720 27.499073029 30.458770752 -36.456939697 28.495611191 30.458080292 -36.450428009 29.483789444 30.456085205 -36.430473328 30.451217651 30.451217651 -36.380989075 31.375360489 30.438953400 -36.280395508 32.216842651 30.405673981 -36.112346649 32.903381348 30.336599350 -35.879741669 -33.840934753 31.035345078 -35.797355652 -33.254272461 31.334243774 -35.954723358 -32.371025085 31.371026993 -36.154674530 -31.438953400 31.375360489 -36.280391693 -30.476007462 31.379222870 -36.344280243 -29.492321014 31.382312775 -36.371486664 -28.498050690 31.383813858 -36.381027222 -27.499618530 31.384296417 -36.383720398 -26.499948502 31.384403229 -36.384307861 -25.499996185 31.384418488 -36.384407043 -24.500000000 31.384418488 -36.384418488 -23.500000000 31.384418488 -36.384422302 -22.500000000 31.384418488 -36.384422302 -21.500000000 31.384418488 -36.384422302 -20.500000000 31.384418488 -36.384422302 -19.500000000 31.384418488 -36.384422302 -18.500000000 31.384418488 -36.384422302 -17.500000000 31.384418488 -36.384422302 -16.500000000 31.384418488 -36.384422302 -15.500000000 31.384418488 -36.384422302 -14.500000000 31.384418488 -36.384422302 -13.500000000 31.384418488 -36.384422302 -12.500000000 31.384418488 -36.384422302 -11.500000000 31.384418488 -36.384422302 -10.500000000 31.384418488 -36.384422302 -9.500000000 31.384418488 -36.384422302 -8.500000000 31.384418488 -36.384422302 -7.500000000 31.384418488 -36.384422302 -6.500000000 31.384418488 -36.384422302 -5.500000000 31.384418488 -36.384422302 -4.500000000 31.384418488 -36.384422302 -3.500000000 31.384418488 -36.384422302 -2.500000000 31.384418488 -36.384422302 -1.500000000 31.384418488 -36.384422302 -0.500000000 31.384418488 -36.384422302 0.500000000 31.384418488 -36.384422302 1.500000000 31.384418488 -36.384422302 2.500000000 31.384418488 -36.384422302 3.500000000 31.384418488 -36.384422302 4.500000000 31.384418488 -36.384422302 5.500000000 31.384418488 -36.384422302 6.500000000 31.384418488 -36.384422302 7.500000000 31.384418488 -36.384422302 8.500000000 31.384418488 -36.384422302 9.500000000 31.384418488 -36.384422302 10.500000000 31.384418488 -36.384422302 11.500000000 31.384418488 -36.384422302 12.500000000 31.384418488 -36.384422302 13.500000000 31.384418488 -36.384422302 14.500000000 31.384418488 -36.384422302 15.500000000 31.384418488 -36.384422302 16.500000000 31.384418488 -36.384422302 17.500000000 31.384418488 -36.384422302 18.500000000 31.384418488 -36.384422302 19.500000000 31.384418488 -36.384422302 20.500000000 31.384418488 -36.384422302 21.500000000 31.384418488 -36.384422302 22.500000000 31.384418488 -36.384422302 23.500000000 31.384418488 -36.384418488 24.499996185 31.384418488 -36.384407043 25.499948502 31.384405136 -36.384315491 26.499622345 31.384296417 -36.383720398 27.498052597 31.383813858 -36.381027222 28.492321014 31.382312775 -36.371486664 29.476007462 31.379222870 -36.344280243 30.438953400 31.375360489 -36.280395508 31.371026993 31.371028900 -36.154674530 32.254276276 31.334243774 -35.954723358 32.840934753 31.035345078 -35.797359467 -33.030693054 32.030693054 -35.846313477 -32.334243774 32.254276276 -35.954723358 -31.405673981 32.216838837 -36.112346649 -30.460596085 32.220714569 -36.185966492 -29.486719131 32.227874756 -36.217510223 -28.496377945 32.231605530 -36.228954315 -27.499221802 32.232860565 -36.232307434 -26.499872208 32.233165741 -36.233074188 -25.499986649 32.233219147 -36.233207703 -24.499998093 32.233222961 -36.233222961 -23.500000000 32.233222961 -36.233226776 -22.500000000 32.233222961 -36.233226776 -21.500000000 32.233222961 -36.233226776 -20.500000000 32.233222961 -36.233226776 -19.500000000 32.233222961 -36.233226776 -18.500000000 32.233222961 -36.233226776 -17.500000000 32.233222961 -36.233226776 -16.500000000 32.233222961 -36.233226776 -15.500000000 32.233222961 -36.233226776 -14.500000000 32.233222961 -36.233226776 -13.500000000 32.233222961 -36.233226776 -12.500000000 32.233222961 -36.233226776 -11.500000000 32.233222961 -36.233226776 -10.500000000 32.233222961 -36.233226776 -9.500000000 32.233222961 -36.233226776 -8.500000000 32.233222961 -36.233226776 -7.500000000 32.233222961 -36.233226776 -6.500000000 32.233222961 -36.233226776 -5.500000000 32.233222961 -36.233226776 -4.500000000 32.233222961 -36.233226776 -3.500000000 32.233222961 -36.233226776 -2.500000000 32.233222961 -36.233226776 -1.500000000 32.233222961 -36.233226776 -0.500000000 32.233222961 -36.233226776 0.500000000 32.233222961 -36.233226776 1.500000000 32.233222961 -36.233226776 2.500000000 32.233222961 -36.233226776 3.500000000 32.233222961 -36.233226776 4.500000000 32.233222961 -36.233226776 5.500000000 32.233222961 -36.233226776 6.500000000 32.233222961 -36.233226776 7.500000000 32.233222961 -36.233226776 8.500000000 32.233222961 -36.233226776 9.500000000 32.233222961 -36.233226776 10.500000000 32.233222961 -36.233226776 11.500000000 32.233222961 -36.233226776 12.500000000 32.233222961 -36.233226776 13.500000000 32.233222961 -36.233226776 14.500000000 32.233222961 -36.233226776 15.500000000 32.233222961 -36.233226776 16.500000000 32.233222961 -36.233226776 17.500000000 32.233222961 -36.233226776 18.500000000 32.233222961 -36.233226776 19.500000000 32.233222961 -36.233226776 20.500000000 32.233222961 -36.233226776 21.500000000 32.233222961 -36.233226776 22.500000000 32.233222961 -36.233226776 23.499998093 32.233222961 -36.233222961 24.499986649 32.233219147 -36.233207703 25.499872208 32.233165741 -36.233074188 26.499225616 32.232860565 -36.232303619 27.496377945 32.231597900 -36.228954315 28.486719131 32.227874756 -36.217510223 29.460592270 32.220714569 -36.185966492 30.405673981 32.216838837 -36.112342834 31.334241867 32.254276276 -35.954723358 32.030696869 32.030693054 -35.846317291 -32.035343170 32.840930939 -35.797355652 -31.336603165 32.903373718 -35.879737854 -30.442844391 32.946807861 -35.937095642 -29.481937408 32.968864441 -35.965759277 -28.495168686 32.977615356 -35.976863861 -27.498950958 32.980335236 -35.980205536 -26.499826431 32.980979919 -35.980964661 -25.499979019 32.981090546 -35.981090546 -24.499998093 32.981105804 -35.981105804 -23.500000000 32.981105804 -35.981105804 -22.500000000 32.981105804 -35.981105804 -21.500000000 32.981105804 -35.981105804 -20.500000000 32.981105804 -35.981105804 -19.500000000 32.981105804 -35.981105804 -18.500000000 32.981105804 -35.981105804 -17.500000000 32.981105804 -35.981105804 -16.500000000 32.981105804 -35.981105804 -15.500000000 32.981105804 -35.981105804 -14.500000000 32.981105804 -35.981105804 -13.500000000 32.981105804 -35.981105804 -12.500000000 32.981105804 -35.981105804 -11.500000000 32.981105804 -35.981105804 -10.500000000 32.981105804 -35.981105804 -9.500000000 32.981105804 -35.981105804 -8.500000000 32.981105804 -35.981105804 -7.500000000 32.981105804 -35.981105804 -6.500000000 32.981105804 -35.981105804 -5.500000000 32.981105804 -35.981105804 -4.500000000 32.981105804 -35.981105804 -3.500000000 32.981105804 -35.981105804 -2.500000000 32.981105804 -35.981105804 -1.500000000 32.981105804 -35.981105804 -0.500000000 32.981105804 -35.981105804 0.500000000 32.981105804 -35.981105804 1.500000000 32.981105804 -35.981105804 2.500000000 32.981105804 -35.981105804 3.500000000 32.981105804 -35.981105804 4.500000000 32.981105804 -35.981105804 5.500000000 32.981105804 -35.981105804 6.500000000 32.981105804 -35.981105804 7.500000000 32.981105804 -35.981105804 8.500000000 32.981105804 -35.981105804 9.500000000 32.981105804 -35.981105804 10.500000000 32.981105804 -35.981105804 11.500000000 32.981105804 -35.981105804 12.500000000 32.981105804 -35.981105804 13.500000000 32.981105804 -35.981105804 14.500000000 32.981105804 -35.981105804 15.500000000 32.981105804 -35.981105804 16.500000000 32.981105804 -35.981105804 17.500000000 32.981105804 -35.981105804 18.500000000 32.981105804 -35.981105804 19.500000000 32.981105804 -35.981105804 20.500000000 32.981105804 -35.981105804 21.500000000 32.981105804 -35.981105804 22.500000000 32.981105804 -35.981105804 23.499998093 32.981105804 -35.981105804 24.499979019 32.981090546 -35.981090546 25.499826431 32.980979919 -35.980960846 26.498950958 32.980335236 -35.980201721 27.495168686 32.977615356 -35.976860046 28.481937408 32.968864441 -35.965766907 29.442840576 32.946807861 -35.937091827 30.336603165 32.903373718 -35.879737854 31.035345078 32.840930939 -35.797355652 -33.006500244 -34.772159576 -34.772163391 -32.313602448 -34.912067413 -34.912067413 -31.413049698 -35.040893555 -35.040897369 -30.463253021 -35.115642548 -35.115646362 -29.487289429 -35.150257111 -35.150253296 -28.496557236 -35.163158417 -35.163158417 -27.499298096 -35.166961670 -35.166954041 -26.499902725 -35.167808533 -35.167808533 -25.499990463 -35.167949677 -35.167949677 -24.500000000 -35.167961121 -35.167961121 -23.500000000 -35.167968750 -35.167968750 -22.500000000 -35.167968750 -35.167968750 -21.500000000 -35.167968750 -35.167968750 -20.500000000 -35.167968750 -35.167968750 -19.500000000 -35.167968750 -35.167968750 -18.500000000 -35.167968750 -35.167968750 -17.500000000 -35.167968750 -35.167968750 -16.500000000 -35.167968750 -35.167968750 -15.500000000 -35.167968750 -35.167968750 -14.500000000 -35.167968750 -35.167968750 -13.500000000 -35.167968750 -35.167968750 -12.500000000 -35.167968750 -35.167968750 -11.500000000 -35.167968750 -35.167968750 -10.500000000 -35.167968750 -35.167968750 -9.500000000 -35.167968750 -35.167968750 -8.500000000 -35.167968750 -35.167968750 -7.500000000 -35.167968750 -35.167968750 -6.500000000 -35.167968750 -35.167968750 -5.500000000 -35.167968750 -35.167968750 -4.500000000 -35.167968750 -35.167968750 -3.500000000 -35.167968750 -35.167968750 -2.500000000 -35.167968750 -35.167968750 -1.500000000 -35.167968750 -35.167968750 -0.500000000 -35.167968750 -35.167968750 0.500000000 -35.167968750 -35.167968750 1.500000000 -35.167968750 -35.167968750 2.500000000 -35.167968750 -35.167968750 3.500000000 -35.167968750 -35.167968750 4.500000000 -35.167968750 -35.167968750 5.500000000 -35.167968750 -35.167968750 6.500000000 -35.167968750 -35.167968750 7.500000000 -35.167968750 -35.167968750 8.500000000 -35.167968750 -35.167968750 9.500000000 -35.167968750 -35.167968750 10.500000000 -35.167968750 -35.167968750 11.500000000 -35.167968750 -35.167968750 12.500000000 -35.167968750 -35.167968750 13.500000000 -35.167968750 -35.167968750 14.500000000 -35.167968750 -35.167968750 15.500000000 -35.167968750 -35.167968750 16.500000000 -35.167968750 -35.167968750 17.500000000 -35.167968750 -35.167968750 18.500000000 -35.167968750 -35.167968750 19.500000000 -35.167968750 -35.167968750 20.500000000 -35.167968750 -35.167968750 21.500000000 -35.167968750 -35.167968750 22.500000000 -35.167968750 -35.167968750 23.500000000 -35.167968750 -35.167968750 24.499992371 -35.167953491 -35.167949677 25.499898911 -35.167808533 -35.167804718 26.499298096 -35.166961670 -35.166957855 27.496557236 -35.163158417 -35.163158417 28.487289429 -35.150249481 -35.150253296 29.463253021 -35.115642548 -35.115642548 30.413049698 -35.040897369 -35.040897369 31.313602448 -34.912067413 -34.912059784 32.006500244 -34.772163391 -34.772159576 -33.980762482 -33.980758667 -34.842590332 -33.316951752 -34.231868744 -35.057430267 -32.380741119 -34.260547638 -35.428535461 -31.410833359 -34.477191925 -35.518615723 -30.459178925 -34.567749023 -35.577739716 -29.485630035 -34.604709625 -35.607204437 -28.496026993 -34.617927551 -35.618602753 -27.499156952 -34.621795654 -35.621986389 -26.499868393 -34.622692108 -35.622741699 -25.499986649 -34.622852325 -35.622856140 -24.500000000 -34.622871399 -35.622871399 -23.500000000 -34.622871399 -35.622871399 -22.500000000 -34.622871399 -35.622871399 -21.500000000 -34.622871399 -35.622871399 -20.500000000 -34.622871399 -35.622871399 -19.500000000 -34.622871399 -35.622871399 -18.500000000 -34.622871399 -35.622871399 -17.500000000 -34.622871399 -35.622871399 -16.500000000 -34.622871399 -35.622871399 -15.500000000 -34.622871399 -35.622871399 -14.500000000 -34.622871399 -35.622871399 -13.500000000 -34.622871399 -35.622871399 -12.500000000 -34.622871399 -35.622871399 -11.500000000 -34.622871399 -35.622871399 -10.500000000 -34.622871399 -35.622871399 -9.500000000 -34.622871399 -35.622871399 -8.500000000 -34.622871399 -35.622871399 -7.500000000 -34.622871399 -35.622871399 -6.500000000 -34.622871399 -35.622871399 -5.500000000 -34.622871399 -35.622871399 -4.500000000 -34.622871399 -35.622871399 -3.500000000 -34.622871399 -35.622871399 -2.500000000 -34.622871399 -35.622871399 -1.500000000 -34.622871399 -35.622871399 -0.500000000 -34.622871399 -35.622871399 0.500000000 -34.622871399 -35.622871399 1.500000000 -34.622871399 -35.622871399 2.500000000 -34.622871399 -35.622871399 3.500000000 -34.622871399 -35.622871399 4.500000000 -34.622871399 -35.622871399 5.500000000 -34.622871399 -35.622871399 6.500000000 -34.622871399 -35.622871399 7.500000000 -34.622871399 -35.622871399 8.500000000 -34.622871399 -35.622871399 9.500000000 -34.622871399 -35.622871399 10.500000000 -34.622871399 -35.622871399 11.500000000 -34.622871399 -35.622871399 12.500000000 -34.622871399 -35.622871399 13.500000000 -34.622871399 -35.622871399 14.500000000 -34.622871399 -35.622871399 15.500000000 -34.622871399 -35.622871399 16.500000000 -34.622871399 -35.622871399 17.500000000 -34.622871399 -35.622871399 18.500000000 -34.622871399 -35.622871399 19.500000000 -34.622871399 -35.622871399 20.500000000 -34.622871399 -35.622871399 21.500000000 -34.622871399 -35.622871399 22.500000000 -34.622871399 -35.622871399 23.500000000 -34.622871399 -35.622871399 24.499986649 -34.622852325 -35.622856140 25.499866486 -34.622695923 -35.622741699 26.499156952 -34.621795654 -35.621978760 27.496026993 -34.617927551 -35.618602753 28.485630035 -34.604709625 -35.607208252 29.459177017 -34.567745209 -35.577743530 30.410833359 -34.477191925 -35.518615723 31.380739212 -34.260547638 -35.428535461 32.316951752 -34.231872559 -35.057430267 32.980762482 -33.980762482 -34.842590332 -34.772163391 -33.006500244 -34.772163391 -34.231872559 -33.316951752 -35.057430267 -33.424442291 -33.424442291 -35.498542786 -32.736049652 -33.678356171 -35.670326233 31.736053467 -33.678352356 -35.670326233 32.424442291 -33.424442291 -35.498546600 33.231872559 -33.316947937 -35.057430267 33.772163391 -33.006500244 -34.772163391 -34.912059784 -32.313602448 -34.912059784 -34.260543823 -32.380741119 -35.428531647 -33.678352356 -32.736053467 -35.670322418 32.678352356 -32.736049652 -35.670326233 33.260547638 -32.380737305 -35.428535461 33.912059784 -32.313598633 -34.912067413 -35.040893555 -31.413049698 -35.040893555 -34.477191925 -31.410833359 -35.518615723 33.477191925 -31.410833359 -35.518615723 34.040893555 -31.413049698 -35.040893555 -35.115642548 -30.463253021 -35.115646362 -34.567745209 -30.459177017 -35.577739716 33.567749023 -30.459178925 -35.577739716 34.115642548 -30.463253021 -35.115646362 -35.150253296 -29.487289429 -35.150253296 -34.604705811 -29.485630035 -35.607208252 33.604709625 -29.485630035 -35.607204437 34.150257111 -29.487289429 -35.150253296 -35.163162231 -28.496557236 -35.163158417 -34.617927551 -28.496026993 -35.618602753 33.617927551 -28.496026993 -35.618602753 34.163158417 -28.496557236 -35.163158417 -35.166961670 -27.499298096 -35.166954041 -34.621799469 -27.499160767 -35.621978760 33.621795654 -27.499156952 -35.621986389 34.166961670 -27.499298096 -35.166954041 -35.167804718 -26.499902725 -35.167808533 -34.622692108 -26.499868393 -35.622734070 33.622692108 -26.499868393 -35.622741699 34.167808533 -26.499902725 -35.167808533 -35.167949677 -25.499990463 -35.167949677 -34.622844696 -25.499986649 -35.622856140 33.622844696 -25.499986649 -35.622856140 34.167949677 -25.499990463 -35.167949677 -35.167961121 -24.500000000 -35.167961121 -34.622871399 -24.500000000 -35.622871399 33.622871399 -24.500000000 -35.622871399 34.167961121 -24.500000000 -35.167961121 -35.167964935 -23.500000000 -35.167964935 -34.622871399 -23.500000000 -35.622871399 33.622871399 -23.500000000 -35.622871399 34.167968750 -23.500000000 -35.167968750 -35.167964935 -22.500000000 -35.167964935 -34.622871399 -22.500000000 -35.622871399 33.622871399 -22.500000000 -35.622871399 34.167968750 -22.500000000 -35.167968750 -35.167964935 -21.500000000 -35.167964935 -34.622871399 -21.500000000 -35.622871399 33.622871399 -21.500000000 -35.622871399 34.167968750 -21.500000000 -35.167968750 -35.167964935 -20.500000000 -35.167964935 -34.622871399 -20.500000000 -35.622871399 33.622871399 -20.500000000 -35.622871399 34.167968750 -20.500000000 -35.167968750 -35.167964935 -19.500000000 -35.167964935 -34.622871399 -19.500000000 -35.622871399 33.622871399 -19.500000000 -35.622871399 34.167968750 -19.500000000 -35.167968750 -35.167968750 -18.500000000 -35.167968750 -34.622871399 -18.500000000 -35.622871399 33.622871399 -18.500000000 -35.622871399 34.167968750 -18.500000000 -35.167968750 -35.167968750 -17.500000000 -35.167968750 -34.622871399 -17.500000000 -35.622871399 33.622871399 -17.500000000 -35.622871399 34.167968750 -17.500000000 -35.167968750 -35.167968750 -16.500000000 -35.167968750 -34.622871399 -16.500000000 -35.622871399 33.622871399 -16.500000000 -35.622871399 34.167968750 -16.500000000 -35.167968750 -35.167964935 -15.500000000 -35.167964935 -34.622871399 -15.500000000 -35.622871399 33.622871399 -15.500000000 -35.622871399 34.167968750 -15.500000000 -35.167968750 -35.167964935 -14.500000000 -35.167964935 -34.622871399 -14.500000000 -35.622871399 33.622871399 -14.500000000 -35.622871399 34.167968750 -14.500000000 -35.167968750 -35.167964935 -13.500000000 -35.167964935 -34.622871399 -13.500000000 -35.622871399 33.622871399 -13.500000000 -35.622871399 34.167968750 -13.500000000 -35.167968750 -35.167964935 -12.500000000 -35.167964935 -34.622871399 -12.500000000 -35.622871399 33.622871399 -12.500000000 -35.622871399 34.167968750 -12.500000000 -35.167968750 -35.167964935 -11.500000000 -35.167964935 -34.622871399 -11.500000000 -35.622871399 33.622871399 -11.500000000 -35.622871399 34.167968750 -11.500000000 -35.167968750 -35.167964935 -10.500000000 -35.167964935 -34.622871399 -10.500000000 -35.622871399 33.622871399 -10.500000000 -35.622871399 34.167968750 -10.500000000 -35.167968750 -35.167964935 -9.500000000 -35.167964935 -34.622871399 -9.500000000 -35.622871399 33.622871399 -9.500000000 -35.622871399 34.167968750 -9.500000000 -35.167968750 -35.167964935 -8.500000000 -35.167964935 -34.622871399 -8.500000000 -35.622871399 33.622871399 -8.500000000 -35.622871399 34.167968750 -8.500000000 -35.167968750 -35.167964935 -7.500000000 -35.167964935 -34.622871399 -7.500000000 -35.622871399 33.622871399 -7.500000000 -35.622871399 34.167968750 -7.500000000 -35.167968750 -35.167964935 -6.500000000 -35.167964935 -34.622871399 -6.500000000 -35.622871399 33.622871399 -6.500000000 -35.622871399 34.167968750 -6.500000000 -35.167968750 -35.167964935 -5.500000000 -35.167964935 -34.622871399 -5.500000000 -35.622871399 33.622871399 -5.500000000 -35.622871399 34.167968750 -5.500000000 -35.167968750 -35.167964935 -4.500000000 -35.167964935 -34.622871399 -4.500000000 -35.622871399 33.622871399 -4.500000000 -35.622871399 34.167968750 -4.500000000 -35.167968750 -35.167968750 -3.500000000 -35.167968750 -34.622871399 -3.500000000 -35.622871399 33.622871399 -3.500000000 -35.622871399 34.167968750 -3.500000000 -35.167968750 -35.167968750 -2.500000000 -35.167968750 -34.622871399 -2.500000000 -35.622871399 33.622871399 -2.500000000 -35.622871399 34.167968750 -2.500000000 -35.167968750 -35.167968750 -1.500000000 -35.167968750 -34.622871399 -1.500000000 -35.622871399 33.622871399 -1.500000000 -35.622871399 34.167968750 -1.500000000 -35.167968750 -35.167964935 -0.500000000 -35.167964935 -34.622871399 -0.500000000 -35.622871399 33.622871399 -0.500000000 -35.622871399 34.167968750 -0.500000000 -35.167968750 -35.167964935 0.500000000 -35.167964935 -34.622871399 0.500000000 -35.622871399 33.622871399 0.500000000 -35.622871399 34.167968750 0.500000000 -35.167968750 -35.167964935 1.500000000 -35.167964935 -34.622871399 1.500000000 -35.622871399 33.622871399 1.500000000 -35.622871399 34.167968750 1.500000000 -35.167968750 -35.167968750 2.500000000 -35.167968750 -34.622871399 2.500000000 -35.622871399 33.622871399 2.500000000 -35.622871399 34.167968750 2.500000000 -35.167968750 -35.167968750 3.500000000 -35.167968750 -34.622871399 3.500000000 -35.622871399 33.622871399 3.500000000 -35.622871399 34.167968750 3.500000000 -35.167968750 -35.167968750 4.500000000 -35.167968750 -34.622871399 4.500000000 -35.622871399 33.622871399 4.500000000 -35.622871399 34.167968750 4.500000000 -35.167968750 -35.167968750 5.500000000 -35.167968750 -34.622871399 5.500000000 -35.622871399 33.622871399 5.500000000 -35.622871399 34.167968750 5.500000000 -35.167968750 -35.167964935 6.500000000 -35.167964935 -34.622871399 6.500000000 -35.622871399 33.622871399 6.500000000 -35.622871399 34.167968750 6.500000000 -35.167968750 -35.167964935 7.500000000 -35.167964935 -34.622871399 7.500000000 -35.622871399 33.622871399 7.500000000 -35.622871399 34.167968750 7.500000000 -35.167968750 -35.167964935 8.500000000 -35.167964935 -34.622871399 8.500000000 -35.622871399 33.622871399 8.500000000 -35.622871399 34.167968750 8.500000000 -35.167968750 -35.167964935 9.500000000 -35.167964935 -34.622871399 9.500000000 -35.622871399 33.622871399 9.500000000 -35.622871399 34.167968750 9.500000000 -35.167968750 -35.167964935 10.500000000 -35.167964935 -34.622871399 10.500000000 -35.622871399 33.622871399 10.500000000 -35.622871399 34.167968750 10.500000000 -35.167968750 -35.167964935 11.500000000 -35.167964935 -34.622871399 11.500000000 -35.622871399 33.622871399 11.500000000 -35.622871399 34.167968750 11.500000000 -35.167968750 -35.167964935 12.500000000 -35.167964935 -34.622871399 12.500000000 -35.622871399 33.622871399 12.500000000 -35.622871399 34.167968750 12.500000000 -35.167968750 -35.167964935 13.500000000 -35.167964935 -34.622871399 13.500000000 -35.622871399 33.622871399 13.500000000 -35.622871399 34.167968750 13.500000000 -35.167968750 -35.167964935 14.500000000 -35.167964935 -34.622871399 14.500000000 -35.622871399 33.622871399 14.500000000 -35.622871399 34.167968750 14.500000000 -35.167968750 -35.167964935 15.500000000 -35.167964935 -34.622871399 15.500000000 -35.622871399 33.622871399 15.500000000 -35.622871399 34.167968750 15.500000000 -35.167968750 -35.167964935 16.500000000 -35.167964935 -34.622871399 16.500000000 -35.622871399 33.622871399 16.500000000 -35.622871399 34.167968750 16.500000000 -35.167968750 -35.167964935 17.500000000 -35.167964935 -34.622871399 17.500000000 -35.622871399 33.622871399 17.500000000 -35.622871399 34.167968750 17.500000000 -35.167968750 -35.167968750 18.500000000 -35.167968750 -34.622871399 18.500000000 -35.622871399 33.622871399 18.500000000 -35.622871399 34.167968750 18.500000000 -35.167968750 -35.167968750 19.500000000 -35.167968750 -34.622871399 19.500000000 -35.622871399 33.622871399 19.500000000 -35.622871399 34.167968750 19.500000000 -35.167968750 -35.167968750 20.500000000 -35.167968750 -34.622871399 20.500000000 -35.622871399 33.622871399 20.500000000 -35.622871399 34.167968750 20.500000000 -35.167968750 -35.167968750 21.500000000 -35.167968750 -34.622871399 21.500000000 -35.622871399 33.622871399 21.500000000 -35.622871399 34.167968750 21.500000000 -35.167968750 -35.167968750 22.500000000 -35.167968750 -34.622871399 22.500000000 -35.622871399 33.622871399 22.500000000 -35.622871399 34.167968750 22.500000000 -35.167968750 -35.167968750 23.500000000 -35.167968750 -34.622871399 23.500000000 -35.622871399 33.622871399 23.500000000 -35.622871399 34.167968750 23.500000000 -35.167968750 -35.167949677 24.499992371 -35.167949677 -34.622852325 24.499986649 -35.622859955 33.622852325 24.499986649 -35.622856140 34.167949677 24.499992371 -35.167949677 -35.167808533 25.499898911 -35.167808533 -34.622692108 25.499866486 -35.622734070 33.622695923 25.499866486 -35.622734070 34.167808533 25.499898911 -35.167804718 -35.166957855 26.499294281 -35.166957855 -34.621799469 26.499156952 -35.621986389 33.621795654 26.499156952 -35.621978760 34.166961670 26.499298096 -35.166957855 -35.163162231 27.496557236 -35.163162231 -34.617927551 27.496023178 -35.618602753 33.617927551 27.496026993 -35.618602753 34.163158417 27.496557236 -35.163158417 -35.150257111 28.487289429 -35.150253296 -34.604713440 28.485630035 -35.607208252 33.604709625 28.485630035 -35.607208252 34.150249481 28.487289429 -35.150253296 -35.115642548 29.463253021 -35.115642548 -34.567749023 29.459177017 -35.577743530 33.567745209 29.459177017 -35.577747345 34.115642548 29.463253021 -35.115642548 -35.040893555 30.413049698 -35.040897369 -34.477191925 30.410833359 -35.518615723 33.477191925 30.410833359 -35.518623352 34.040897369 30.413049698 -35.040897369 -34.912063599 31.313602448 -34.912063599 -34.260543823 31.380739212 -35.428535461 -33.678356171 31.736053467 -35.670326233 32.678356171 31.736053467 -35.670326233 33.260547638 31.380739212 -35.428535461 33.912067413 31.313602448 -34.912059784 -34.772159576 32.006500244 -34.772163391 -34.231868744 32.316951752 -35.057430267 -33.424442291 32.424442291 -35.498542786 -32.736049652 32.678352356 -35.670322418 31.736055374 32.678352356 -35.670326233 32.424442291 32.424442291 -35.498546600 33.231876373 32.316951752 -35.057430267 33.772163391 32.006500244 -34.772159576 -33.980758667 32.980762482 -34.842594147 -33.316947937 33.231868744 -35.057430267 -32.380737305 33.260547638 -35.428535461 -31.410833359 33.477191925 -35.518615723 -30.459177017 33.567745209 -35.577739716 -29.485630035 33.604705811 -35.607208252 -28.496026993 33.617927551 -35.618602753 -27.499160767 33.621803284 -35.621986389 -26.499868393 33.622692108 -35.622741699 -25.499986649 33.622852325 -35.622856140 -24.500000000 33.622871399 -35.622871399 -23.500000000 33.622871399 -35.622871399 -22.500000000 33.622871399 -35.622871399 -21.500000000 33.622871399 -35.622871399 -20.500000000 33.622871399 -35.622871399 -19.500000000 33.622871399 -35.622871399 -18.500000000 33.622871399 -35.622871399 -17.500000000 33.622871399 -35.622871399 -16.500000000 33.622871399 -35.622871399 -15.500000000 33.622871399 -35.622871399 -14.500000000 33.622871399 -35.622871399 -13.500000000 33.622871399 -35.622871399 -12.500000000 33.622871399 -35.622871399 -11.500000000 33.622871399 -35.622871399 -10.500000000 33.622871399 -35.622871399 -9.500000000 33.622871399 -35.622871399 -8.500000000 33.622871399 -35.622871399 -7.500000000 33.622871399 -35.622871399 -6.500000000 33.622871399 -35.622871399 -5.500000000 33.622871399 -35.622871399 -4.500000000 33.622871399 -35.622871399 -3.500000000 33.622871399 -35.622871399 -2.500000000 33.622871399 -35.622871399 -1.500000000 33.622871399 -35.622871399 -0.500000000 33.622871399 -35.622871399 0.500000000 33.622871399 -35.622871399 1.500000000 33.622871399 -35.622871399 2.500000000 33.622871399 -35.622871399 3.500000000 33.622871399 -35.622871399 4.500000000 33.622871399 -35.622871399 5.500000000 33.622871399 -35.622871399 6.500000000 33.622871399 -35.622871399 7.500000000 33.622871399 -35.622871399 8.500000000 33.622871399 -35.622871399 9.500000000 33.622871399 -35.622871399 10.500000000 33.622871399 -35.622871399 11.500000000 33.622871399 -35.622871399 12.500000000 33.622871399 -35.622871399 13.500000000 33.622871399 -35.622871399 14.500000000 33.622871399 -35.622871399 15.500000000 33.622871399 -35.622871399 16.500000000 33.622871399 -35.622871399 17.500000000 33.622871399 -35.622871399 18.500000000 33.622871399 -35.622871399 19.500000000 33.622871399 -35.622871399 20.500000000 33.622871399 -35.622871399 21.500000000 33.622871399 -35.622871399 22.500000000 33.622871399 -35.622871399 23.500000000 33.622871399 -35.622871399 24.499986649 33.622856140 -35.622856140 25.499868393 33.622695923 -35.622741699 26.499156952 33.621803284 -35.621986389 27.496026993 33.617927551 -35.618602753 28.485630035 33.604709625 -35.607208252 29.459178925 33.567749023 -35.577739716 30.410833359 33.477191925 -35.518615723 31.380737305 33.260547638 -35.428535461 32.316951752 33.231872559 -35.057430267 32.980758667 32.980762482 -34.842590332 -33.006500244 33.772163391 -34.772163391 -32.313598633 33.912063599 -34.912063599 -31.413049698 34.040893555 -35.040893555 -30.463253021 34.115642548 -35.115642548 -29.487289429 34.150249481 -35.150253296 -28.496557236 34.163158417 -35.163162231 -27.499298096 34.166954041 -35.166961670 -26.499898911 34.167808533 -35.167808533 -25.499990463 34.167949677 -35.167949677 -24.500000000 34.167968750 -35.167964935 -23.500000000 34.167968750 -35.167968750 -22.500000000 34.167968750 -35.167968750 -21.500000000 34.167968750 -35.167968750 -20.500000000 34.167968750 -35.167968750 -19.500000000 34.167968750 -35.167968750 -18.500000000 34.167968750 -35.167968750 -17.500000000 34.167968750 -35.167968750 -16.500000000 34.167968750 -35.167968750 -15.500000000 34.167968750 -35.167968750 -14.500000000 34.167968750 -35.167968750 -13.500000000 34.167968750 -35.167968750 -12.500000000 34.167968750 -35.167968750 -11.500000000 34.167968750 -35.167968750 -10.500000000 34.167968750 -35.167968750 -9.500000000 34.167968750 -35.167968750 -8.500000000 34.167968750 -35.167968750 -7.500000000 34.167968750 -35.167968750 -6.500000000 34.167968750 -35.167968750 -5.500000000 34.167968750 -35.167968750 -4.500000000 34.167968750 -35.167968750 -3.500000000 34.167968750 -35.167968750 -2.500000000 34.167968750 -35.167968750 -1.500000000 34.167968750 -35.167968750 -0.500000000 34.167968750 -35.167968750 0.500000000 34.167968750 -35.167968750 1.500000000 34.167968750 -35.167968750 2.500000000 34.167968750 -35.167968750 3.500000000 34.167968750 -35.167968750 4.500000000 34.167968750 -35.167968750 5.500000000 34.167968750 -35.167968750 6.500000000 34.167968750 -35.167968750 7.500000000 34.167968750 -35.167968750 8.500000000 34.167968750 -35.167968750 9.500000000 34.167968750 -35.167968750 10.500000000 34.167968750 -35.167968750 11.500000000 34.167968750 -35.167968750 12.500000000 34.167968750 -35.167968750 13.500000000 34.167968750 -35.167968750 14.500000000 34.167968750 -35.167968750 15.500000000 34.167968750 -35.167968750 16.500000000 34.167968750 -35.167968750 17.500000000 34.167968750 -35.167968750 18.500000000 34.167968750 -35.167968750 19.500000000 34.167968750 -35.167968750 20.500000000 34.167968750 -35.167968750 21.500000000 34.167968750 -35.167968750 22.500000000 34.167968750 -35.167968750 23.500000000 34.167968750 -35.167961121 24.499994278 34.167949677 -35.167949677 25.499898911 34.167808533 -35.167808533 26.499298096 34.166961670 -35.166961670 27.496557236 34.163162231 -35.163158417 28.487293243 34.150257111 -35.150253296 29.463256836 34.115638733 -35.115642548 30.413049698 34.040893555 -35.040893555 31.313602448 33.912063599 -34.912063599 32.006500244 33.772163391 -34.772163391 -32.035343170 -35.797355652 -33.840934753 -31.336603165 -35.879737854 -33.903385162 -30.442840576 -35.937091827 -33.946811676 -29.481933594 -35.965766907 -33.968872070 -28.495168686 -35.976860046 -33.977619171 -27.498950958 -35.980201721 -33.980335236 -26.499822617 -35.980957031 -33.980976105 -25.499977112 -35.981090546 -33.981090546 -24.499998093 -35.981101990 -33.981101990 -23.500000000 -35.981101990 -33.981101990 -22.500000000 -35.981101990 -33.981101990 -21.500000000 -35.981101990 -33.981101990 -20.500000000 -35.981101990 -33.981101990 -19.500000000 -35.981101990 -33.981101990 -18.500000000 -35.981101990 -33.981101990 -17.500000000 -35.981101990 -33.981101990 -16.500000000 -35.981101990 -33.981101990 -15.500000000 -35.981101990 -33.981101990 -14.500000000 -35.981101990 -33.981101990 -13.500000000 -35.981101990 -33.981101990 -12.500000000 -35.981101990 -33.981101990 -11.500000000 -35.981101990 -33.981101990 -10.500000000 -35.981101990 -33.981101990 -9.500000000 -35.981101990 -33.981101990 -8.500000000 -35.981101990 -33.981101990 -7.500000000 -35.981101990 -33.981101990 -6.500000000 -35.981101990 -33.981101990 -5.500000000 -35.981101990 -33.981101990 -4.500000000 -35.981101990 -33.981101990 -3.500000000 -35.981101990 -33.981101990 -2.500000000 -35.981101990 -33.981101990 -1.500000000 -35.981101990 -33.981101990 -0.500000000 -35.981101990 -33.981101990 0.500000000 -35.981101990 -33.981101990 1.500000000 -35.981101990 -33.981101990 2.500000000 -35.981101990 -33.981101990 3.500000000 -35.981101990 -33.981101990 4.500000000 -35.981101990 -33.981101990 5.500000000 -35.981101990 -33.981101990 6.500000000 -35.981101990 -33.981101990 7.500000000 -35.981101990 -33.981101990 8.500000000 -35.981101990 -33.981101990 9.500000000 -35.981101990 -33.981101990 10.500000000 -35.981101990 -33.981101990 11.500000000 -35.981101990 -33.981101990 12.500000000 -35.981101990 -33.981101990 13.500000000 -35.981101990 -33.981101990 14.500000000 -35.981101990 -33.981101990 15.500000000 -35.981101990 -33.981101990 16.500000000 -35.981101990 -33.981101990 17.500000000 -35.981101990 -33.981101990 18.500000000 -35.981101990 -33.981101990 19.500000000 -35.981101990 -33.981101990 20.500000000 -35.981101990 -33.981101990 21.500000000 -35.981101990 -33.981101990 22.500000000 -35.981101990 -33.981101990 23.499998093 -35.981101990 -33.981101990 24.499979019 -35.981086731 -33.981090546 25.499824524 -35.980957031 -33.980976105 26.498950958 -35.980201721 -33.980335236 27.495168686 -35.976860046 -33.977619171 28.481933594 -35.965766907 -33.968872070 29.442840576 -35.937091827 -33.946807861 30.336599350 -35.879737854 -33.903377533 31.035345078 -35.797355652 -33.840930939 -33.980762482 -34.842590332 -33.980762482 -33.316951752 -35.057430267 -34.231872559 -32.380741119 -35.428535461 -34.260547638 -31.410831451 -35.518615723 -34.477195740 -30.459177017 -35.577739716 -34.567749023 -29.485630035 -35.607204437 -34.604709625 -28.496023178 -35.618602753 -34.617927551 -27.499160767 -35.621982574 -34.621795654 -26.499868393 -35.622734070 -34.622692108 -25.499986649 -35.622856140 -34.622848511 -24.500000000 -35.622871399 -34.622871399 -23.500000000 -35.622871399 -34.622871399 -22.500000000 -35.622871399 -34.622871399 -21.500000000 -35.622871399 -34.622871399 -20.500000000 -35.622871399 -34.622871399 -19.500000000 -35.622871399 -34.622871399 -18.500000000 -35.622871399 -34.622871399 -17.500000000 -35.622871399 -34.622871399 -16.500000000 -35.622871399 -34.622871399 -15.500000000 -35.622871399 -34.622871399 -14.500000000 -35.622871399 -34.622871399 -13.500000000 -35.622871399 -34.622871399 -12.500000000 -35.622871399 -34.622871399 -11.500000000 -35.622871399 -34.622871399 -10.500000000 -35.622871399 -34.622871399 -9.500000000 -35.622871399 -34.622871399 -8.500000000 -35.622871399 -34.622871399 -7.500000000 -35.622871399 -34.622871399 -6.500000000 -35.622871399 -34.622871399 -5.500000000 -35.622871399 -34.622871399 -4.500000000 -35.622871399 -34.622871399 -3.500000000 -35.622871399 -34.622871399 -2.500000000 -35.622871399 -34.622871399 -1.500000000 -35.622871399 -34.622871399 -0.500000000 -35.622871399 -34.622871399 0.500000000 -35.622871399 -34.622871399 1.500000000 -35.622871399 -34.622871399 2.500000000 -35.622871399 -34.622871399 3.500000000 -35.622871399 -34.622871399 4.500000000 -35.622871399 -34.622871399 5.500000000 -35.622871399 -34.622871399 6.500000000 -35.622871399 -34.622871399 7.500000000 -35.622871399 -34.622871399 8.500000000 -35.622871399 -34.622871399 9.500000000 -35.622871399 -34.622871399 10.500000000 -35.622871399 -34.622871399 11.500000000 -35.622871399 -34.622871399 12.500000000 -35.622871399 -34.622871399 13.500000000 -35.622871399 -34.622871399 14.500000000 -35.622871399 -34.622871399 15.500000000 -35.622871399 -34.622871399 16.500000000 -35.622871399 -34.622871399 17.500000000 -35.622871399 -34.622871399 18.500000000 -35.622871399 -34.622871399 19.500000000 -35.622871399 -34.622871399 20.500000000 -35.622871399 -34.622871399 21.500000000 -35.622871399 -34.622871399 22.500000000 -35.622871399 -34.622871399 23.500000000 -35.622871399 -34.622871399 24.499986649 -35.622856140 -34.622844696 25.499866486 -35.622734070 -34.622692108 26.499156952 -35.621978760 -34.621803284 27.496023178 -35.618598938 -34.617927551 28.485630035 -35.607208252 -34.604709625 29.459178925 -35.577739716 -34.567745209 30.410833359 -35.518615723 -34.477191925 31.380739212 -35.428535461 -34.260547638 32.316951752 -35.057430267 -34.231872559 32.980762482 -34.842590332 -33.980758667 -34.842590332 -33.980758667 -33.980762482 -34.297924042 -34.297924042 -34.297924042 -33.672851562 -34.565631866 -34.565631866 32.672851562 -34.565631866 -34.565628052 33.297924042 -34.297924042 -34.297927856 33.842590332 -33.980758667 -33.980758667 -35.057430267 -33.316947937 -34.231876373 -34.565631866 -33.672851562 -34.565631866 33.565631866 -33.672851562 -34.565628052 34.057430267 -33.316947937 -34.231868744 -35.797355652 -32.035343170 -33.840934753 -35.428535461 -32.380741119 -34.260547638 34.428535461 -32.380741119 -34.260547638 34.797355652 -32.035343170 -33.840934753 -35.879734039 -31.336599350 -33.903385162 -35.518615723 -31.410831451 -34.477195740 34.518615723 -31.410831451 -34.477195740 34.879737854 -31.336599350 -33.903385162 -35.937091827 -30.442840576 -33.946811676 -35.577735901 -30.459177017 -34.567752838 34.577739716 -30.459177017 -34.567749023 34.937091827 -30.442840576 -33.946811676 -35.965759277 -29.481933594 -33.968864441 -35.607204437 -29.485630035 -34.604709625 34.607204437 -29.485630035 -34.604709625 34.965766907 -29.481933594 -33.968872070 -35.976860046 -28.495168686 -33.977619171 -35.618598938 -28.496023178 -34.617927551 34.618602753 -28.496023178 -34.617927551 34.976860046 -28.495168686 -33.977619171 -35.980201721 -27.498950958 -33.980335236 -35.621982574 -27.499156952 -34.621803284 34.621982574 -27.499160767 -34.621795654 34.980201721 -27.498950958 -33.980335236 -35.980957031 -26.499822617 -33.980976105 -35.622734070 -26.499868393 -34.622692108 34.622734070 -26.499868393 -34.622692108 34.980957031 -26.499822617 -33.980976105 -35.981090546 -25.499979019 -33.981090546 -35.622856140 -25.499986649 -34.622844696 34.622856140 -25.499986649 -34.622848511 34.981090546 -25.499977112 -33.981090546 -35.981101990 -24.499998093 -33.981101990 -35.622871399 -24.500000000 -34.622871399 34.622871399 -24.500000000 -34.622871399 34.981101990 -24.499998093 -33.981101990 -35.981101990 -23.500000000 -33.981101990 -35.622871399 -23.500000000 -34.622871399 34.622871399 -23.500000000 -34.622871399 34.981101990 -23.500000000 -33.981101990 -35.981101990 -22.500000000 -33.981101990 -35.622871399 -22.500000000 -34.622871399 34.622871399 -22.500000000 -34.622871399 34.981101990 -22.500000000 -33.981101990 -35.981101990 -21.500000000 -33.981101990 -35.622871399 -21.500000000 -34.622871399 34.622871399 -21.500000000 -34.622871399 34.981101990 -21.500000000 -33.981101990 -35.981101990 -20.500000000 -33.981101990 -35.622871399 -20.500000000 -34.622871399 34.622871399 -20.500000000 -34.622871399 34.981101990 -20.500000000 -33.981101990 -35.981101990 -19.500000000 -33.981101990 -35.622871399 -19.500000000 -34.622871399 34.622871399 -19.500000000 -34.622871399 34.981101990 -19.500000000 -33.981101990 -35.981101990 -18.500000000 -33.981101990 -35.622871399 -18.500000000 -34.622871399 34.622871399 -18.500000000 -34.622871399 34.981101990 -18.500000000 -33.981101990 -35.981101990 -17.500000000 -33.981101990 -35.622871399 -17.500000000 -34.622871399 34.622871399 -17.500000000 -34.622871399 34.981101990 -17.500000000 -33.981101990 -35.981101990 -16.500000000 -33.981101990 -35.622871399 -16.500000000 -34.622871399 34.622871399 -16.500000000 -34.622871399 34.981101990 -16.500000000 -33.981101990 -35.981101990 -15.500000000 -33.981101990 -35.622871399 -15.500000000 -34.622871399 34.622871399 -15.500000000 -34.622871399 34.981101990 -15.500000000 -33.981101990 -35.981101990 -14.500000000 -33.981101990 -35.622871399 -14.500000000 -34.622871399 34.622871399 -14.500000000 -34.622871399 34.981101990 -14.500000000 -33.981101990 -35.981101990 -13.500000000 -33.981101990 -35.622871399 -13.500000000 -34.622871399 34.622871399 -13.500000000 -34.622871399 34.981101990 -13.500000000 -33.981101990 -35.981101990 -12.500000000 -33.981101990 -35.622871399 -12.500000000 -34.622871399 34.622871399 -12.500000000 -34.622871399 34.981101990 -12.500000000 -33.981101990 -35.981101990 -11.500000000 -33.981101990 -35.622871399 -11.500000000 -34.622871399 34.622871399 -11.500000000 -34.622871399 34.981101990 -11.500000000 -33.981101990 -35.981101990 -10.500000000 -33.981101990 -35.622871399 -10.500000000 -34.622871399 34.622871399 -10.500000000 -34.622871399 34.981101990 -10.500000000 -33.981101990 -35.981101990 -9.500000000 -33.981101990 -35.622871399 -9.500000000 -34.622871399 34.622871399 -9.500000000 -34.622871399 34.981101990 -9.500000000 -33.981101990 -35.981101990 -8.500000000 -33.981101990 -35.622871399 -8.500000000 -34.622871399 34.622871399 -8.500000000 -34.622871399 34.981101990 -8.500000000 -33.981101990 -35.981101990 -7.500000000 -33.981101990 -35.622871399 -7.500000000 -34.622871399 34.622871399 -7.500000000 -34.622871399 34.981101990 -7.500000000 -33.981101990 -35.981101990 -6.500000000 -33.981101990 -35.622871399 -6.500000000 -34.622871399 34.622871399 -6.500000000 -34.622871399 34.981101990 -6.500000000 -33.981101990 -35.981101990 -5.500000000 -33.981101990 -35.622871399 -5.500000000 -34.622871399 34.622871399 -5.500000000 -34.622871399 34.981101990 -5.500000000 -33.981101990 -35.981101990 -4.500000000 -33.981101990 -35.622871399 -4.500000000 -34.622871399 34.622871399 -4.500000000 -34.622871399 34.981101990 -4.500000000 -33.981101990 -35.981101990 -3.500000000 -33.981101990 -35.622871399 -3.500000000 -34.622871399 34.622871399 -3.500000000 -34.622871399 34.981101990 -3.500000000 -33.981101990 -35.981101990 -2.500000000 -33.981101990 -35.622871399 -2.500000000 -34.622871399 34.622871399 -2.500000000 -34.622871399 34.981101990 -2.500000000 -33.981101990 -35.981101990 -1.500000000 -33.981101990 -35.622871399 -1.500000000 -34.622871399 34.622871399 -1.500000000 -34.622871399 34.981101990 -1.500000000 -33.981101990 -35.981101990 -0.500000000 -33.981101990 -35.622871399 -0.500000000 -34.622871399 34.622871399 -0.500000000 -34.622871399 34.981101990 -0.500000000 -33.981101990 -35.981101990 0.500000000 -33.981101990 -35.622871399 0.500000000 -34.622871399 34.622871399 0.500000000 -34.622871399 34.981101990 0.500000000 -33.981101990 -35.981101990 1.500000000 -33.981101990 -35.622871399 1.500000000 -34.622871399 34.622871399 1.500000000 -34.622871399 34.981101990 1.500000000 -33.981101990 -35.981101990 2.500000000 -33.981101990 -35.622871399 2.500000000 -34.622871399 34.622871399 2.500000000 -34.622871399 34.981101990 2.500000000 -33.981101990 -35.981101990 3.500000000 -33.981101990 -35.622871399 3.500000000 -34.622871399 34.622871399 3.500000000 -34.622871399 34.981101990 3.500000000 -33.981101990 -35.981101990 4.500000000 -33.981101990 -35.622871399 4.500000000 -34.622871399 34.622871399 4.500000000 -34.622871399 34.981101990 4.500000000 -33.981101990 -35.981101990 5.500000000 -33.981101990 -35.622871399 5.500000000 -34.622871399 34.622871399 5.500000000 -34.622871399 34.981101990 5.500000000 -33.981101990 -35.981101990 6.500000000 -33.981101990 -35.622871399 6.500000000 -34.622871399 34.622871399 6.500000000 -34.622871399 34.981101990 6.500000000 -33.981101990 -35.981101990 7.500000000 -33.981101990 -35.622871399 7.500000000 -34.622871399 34.622871399 7.500000000 -34.622871399 34.981101990 7.500000000 -33.981101990 -35.981101990 8.500000000 -33.981101990 -35.622871399 8.500000000 -34.622871399 34.622871399 8.500000000 -34.622871399 34.981101990 8.500000000 -33.981101990 -35.981101990 9.500000000 -33.981101990 -35.622871399 9.500000000 -34.622871399 34.622871399 9.500000000 -34.622871399 34.981101990 9.500000000 -33.981101990 -35.981101990 10.500000000 -33.981101990 -35.622871399 10.500000000 -34.622871399 34.622871399 10.500000000 -34.622871399 34.981101990 10.500000000 -33.981101990 -35.981101990 11.500000000 -33.981101990 -35.622871399 11.500000000 -34.622871399 34.622871399 11.500000000 -34.622871399 34.981101990 11.500000000 -33.981101990 -35.981101990 12.500000000 -33.981101990 -35.622871399 12.500000000 -34.622871399 34.622871399 12.500000000 -34.622871399 34.981101990 12.500000000 -33.981101990 -35.981101990 13.500000000 -33.981101990 -35.622871399 13.500000000 -34.622871399 34.622871399 13.500000000 -34.622871399 34.981101990 13.500000000 -33.981101990 -35.981101990 14.500000000 -33.981101990 -35.622871399 14.500000000 -34.622871399 34.622871399 14.500000000 -34.622871399 34.981101990 14.500000000 -33.981101990 -35.981101990 15.500000000 -33.981101990 -35.622871399 15.500000000 -34.622871399 34.622871399 15.500000000 -34.622871399 34.981101990 15.500000000 -33.981101990 -35.981101990 16.500000000 -33.981101990 -35.622871399 16.500000000 -34.622871399 34.622871399 16.500000000 -34.622871399 34.981101990 16.500000000 -33.981101990 -35.981101990 17.500000000 -33.981101990 -35.622871399 17.500000000 -34.622871399 34.622871399 17.500000000 -34.622871399 34.981101990 17.500000000 -33.981101990 -35.981101990 18.500000000 -33.981101990 -35.622871399 18.500000000 -34.622871399 34.622871399 18.500000000 -34.622871399 34.981101990 18.500000000 -33.981101990 -35.981101990 19.500000000 -33.981101990 -35.622871399 19.500000000 -34.622871399 34.622871399 19.500000000 -34.622871399 34.981101990 19.500000000 -33.981101990 -35.981101990 20.500000000 -33.981101990 -35.622871399 20.500000000 -34.622871399 34.622871399 20.500000000 -34.622871399 34.981101990 20.500000000 -33.981101990 -35.981101990 21.500000000 -33.981101990 -35.622871399 21.500000000 -34.622871399 34.622871399 21.500000000 -34.622871399 34.981101990 21.500000000 -33.981101990 -35.981101990 22.500000000 -33.981101990 -35.622871399 22.500000000 -34.622871399 34.622871399 22.500000000 -34.622871399 34.981101990 22.500000000 -33.981101990 -35.981101990 23.499998093 -33.981101990 -35.622871399 23.500000000 -34.622871399 34.622871399 23.500000000 -34.622871399 34.981101990 23.499998093 -33.981101990 -35.981086731 24.499979019 -33.981090546 -35.622856140 24.499986649 -34.622848511 34.622856140 24.499986649 -34.622844696 34.981086731 24.499979019 -33.981090546 -35.980957031 25.499824524 -33.980976105 -35.622734070 25.499868393 -34.622692108 34.622734070 25.499866486 -34.622692108 34.980957031 25.499824524 -33.980976105 -35.980201721 26.498950958 -33.980335236 -35.621982574 26.499156952 -34.621803284 34.621978760 26.499156952 -34.621803284 34.980201721 26.498950958 -33.980335236 -35.976860046 27.495168686 -33.977619171 -35.618602753 27.496026993 -34.617927551 34.618598938 27.496023178 -34.617927551 34.976860046 27.495168686 -33.977619171 -35.965766907 28.481937408 -33.968868256 -35.607208252 28.485630035 -34.604709625 34.607208252 28.485630035 -34.604709625 34.965766907 28.481933594 -33.968872070 -35.937091827 29.442840576 -33.946811676 -35.577739716 29.459177017 -34.567745209 34.577739716 29.459178925 -34.567745209 34.937091827 29.442840576 -33.946807861 -35.879737854 30.336603165 -33.903377533 -35.518615723 30.410833359 -34.477191925 34.518615723 30.410833359 -34.477191925 34.879737854 30.336599350 -33.903377533 -35.797355652 31.035345078 -33.840934753 -35.428531647 31.380737305 -34.260543823 34.428535461 31.380739212 -34.260547638 34.797355652 31.035345078 -33.840930939 -35.057430267 32.316951752 -34.231872559 -34.565628052 32.672851562 -34.565631866 33.565628052 32.672851562 -34.565628052 34.057430267 32.316951752 -34.231868744 -34.842590332 32.980762482 -33.980762482 -34.297924042 33.297924042 -34.297931671 -33.672851562 33.565631866 -34.565631866 32.672851562 33.565631866 -34.565628052 33.297924042 33.297924042 -34.297924042 33.842590332 32.980762482 -33.980758667 -33.980758667 33.842590332 -33.980762482 -33.316947937 34.057430267 -34.231876373 -32.380737305 34.428535461 -34.260547638 -31.410831451 34.518615723 -34.477191925 -30.459177017 34.577739716 -34.567749023 -29.485630035 34.607208252 -34.604709625 -28.496028900 34.618598938 -34.617931366 -27.499160767 34.621982574 -34.621803284 -26.499868393 34.622734070 -34.622692108 -25.499986649 34.622856140 -34.622844696 -24.500000000 34.622871399 -34.622863770 -23.500000000 34.622871399 -34.622871399 -22.500000000 34.622871399 -34.622871399 -21.500000000 34.622871399 -34.622871399 -20.500000000 34.622871399 -34.622871399 -19.500000000 34.622871399 -34.622871399 -18.500000000 34.622871399 -34.622871399 -17.500000000 34.622871399 -34.622871399 -16.500000000 34.622871399 -34.622871399 -15.500000000 34.622871399 -34.622871399 -14.500000000 34.622871399 -34.622871399 -13.500000000 34.622871399 -34.622871399 -12.500000000 34.622871399 -34.622871399 -11.500000000 34.622871399 -34.622871399 -10.500000000 34.622871399 -34.622871399 -9.500000000 34.622871399 -34.622871399 -8.500000000 34.622871399 -34.622871399 -7.500000000 34.622871399 -34.622871399 -6.500000000 34.622871399 -34.622871399 -5.500000000 34.622871399 -34.622871399 -4.500000000 34.622871399 -34.622871399 -3.500000000 34.622871399 -34.622871399 -2.500000000 34.622871399 -34.622871399 -1.500000000 34.622871399 -34.622871399 -0.500000000 34.622871399 -34.622871399 0.500000000 34.622871399 -34.622871399 1.500000000 34.622871399 -34.622871399 2.500000000 34.622871399 -34.622871399 3.500000000 34.622871399 -34.622871399 4.500000000 34.622871399 -34.622871399 5.500000000 34.622871399 -34.622871399 6.500000000 34.622871399 -34.622871399 7.500000000 34.622871399 -34.622871399 8.500000000 34.622871399 -34.622871399 9.500000000 34.622871399 -34.622871399 10.500000000 34.622871399 -34.622871399 11.500000000 34.622871399 -34.622871399 12.500000000 34.622871399 -34.622871399 13.500000000 34.622871399 -34.622871399 14.500000000 34.622871399 -34.622871399 15.500000000 34.622871399 -34.622871399 16.500000000 34.622871399 -34.622871399 17.500000000 34.622871399 -34.622871399 18.500000000 34.622871399 -34.622871399 19.500000000 34.622871399 -34.622871399 20.500000000 34.622871399 -34.622871399 21.500000000 34.622871399 -34.622871399 22.500000000 34.622871399 -34.622871399 23.500000000 34.622871399 -34.622871399 24.499986649 34.622856140 -34.622844696 25.499868393 34.622734070 -34.622692108 26.499156952 34.621982574 -34.621803284 27.496026993 34.618602753 -34.617927551 28.485631943 34.607208252 -34.604709625 29.459178925 34.577739716 -34.567752838 30.410833359 34.518615723 -34.477191925 31.380737305 34.428535461 -34.260547638 32.316947937 34.057430267 -34.231868744 32.980758667 33.842590332 -33.980758667 -32.035343170 34.797355652 -33.840934753 -31.336603165 34.879734039 -33.903381348 -30.442840576 34.937091827 -33.946807861 -29.481937408 34.965763092 -33.968864441 -28.495172501 34.976860046 -33.977611542 -27.498952866 34.980201721 -33.980331421 -26.499826431 34.980957031 -33.980972290 -25.499979019 34.981086731 -33.981086731 -24.499998093 34.981101990 -33.981098175 -23.500000000 34.981101990 -33.981101990 -22.500000000 34.981101990 -33.981101990 -21.500000000 34.981101990 -33.981101990 -20.500000000 34.981101990 -33.981101990 -19.500000000 34.981101990 -33.981101990 -18.500000000 34.981101990 -33.981101990 -17.500000000 34.981101990 -33.981101990 -16.500000000 34.981101990 -33.981101990 -15.500000000 34.981101990 -33.981101990 -14.500000000 34.981101990 -33.981101990 -13.500000000 34.981101990 -33.981101990 -12.500000000 34.981101990 -33.981101990 -11.500000000 34.981101990 -33.981101990 -10.500000000 34.981101990 -33.981101990 -9.500000000 34.981101990 -33.981101990 -8.500000000 34.981101990 -33.981101990 -7.500000000 34.981101990 -33.981101990 -6.500000000 34.981101990 -33.981101990 -5.500000000 34.981101990 -33.981101990 -4.500000000 34.981101990 -33.981101990 -3.500000000 34.981101990 -33.981101990 -2.500000000 34.981101990 -33.981101990 -1.500000000 34.981101990 -33.981101990 -0.500000000 34.981101990 -33.981101990 0.500000000 34.981101990 -33.981101990 1.500000000 34.981101990 -33.981101990 2.500000000 34.981101990 -33.981101990 3.500000000 34.981101990 -33.981101990 4.500000000 34.981101990 -33.981101990 5.500000000 34.981101990 -33.981101990 6.500000000 34.981101990 -33.981101990 7.500000000 34.981101990 -33.981101990 8.500000000 34.981101990 -33.981101990 9.500000000 34.981101990 -33.981101990 10.500000000 34.981101990 -33.981101990 11.500000000 34.981101990 -33.981101990 12.500000000 34.981101990 -33.981101990 13.500000000 34.981101990 -33.981101990 14.500000000 34.981101990 -33.981101990 15.500000000 34.981101990 -33.981101990 16.500000000 34.981101990 -33.981101990 17.500000000 34.981101990 -33.981101990 18.500000000 34.981101990 -33.981101990 19.500000000 34.981101990 -33.981101990 20.500000000 34.981101990 -33.981101990 21.500000000 34.981101990 -33.981101990 22.500000000 34.981101990 -33.981101990 23.499998093 34.981101990 -33.981101990 24.499979019 34.981086731 -33.981086731 25.499822617 34.980957031 -33.980972290 26.498952866 34.980201721 -33.980331421 27.495172501 34.976863861 -33.977619171 28.481937408 34.965763092 -33.968864441 29.442840576 34.937091827 -33.946811676 30.336603165 34.879737854 -33.903381348 31.035345078 34.797355652 -33.840934753 -33.030693054 -35.846317291 -33.030693054 -32.334243774 -35.954723358 -33.254272461 -31.405673981 -36.112342834 -33.216842651 -30.460596085 -36.185966492 -33.220710754 -29.486715317 -36.217514038 -33.227874756 -28.496374130 -36.228954315 -33.231601715 -27.499221802 -36.232299805 -33.232868195 -26.499872208 -36.233074188 -33.233169556 -25.499986649 -36.233207703 -33.233219147 -24.499998093 -36.233222961 -33.233222961 -23.500000000 -36.233222961 -33.233222961 -22.500000000 -36.233222961 -33.233222961 -21.500000000 -36.233222961 -33.233222961 -20.500000000 -36.233222961 -33.233222961 -19.500000000 -36.233222961 -33.233222961 -18.500000000 -36.233222961 -33.233222961 -17.500000000 -36.233222961 -33.233222961 -16.500000000 -36.233222961 -33.233222961 -15.500000000 -36.233222961 -33.233222961 -14.500000000 -36.233222961 -33.233222961 -13.500000000 -36.233222961 -33.233222961 -12.500000000 -36.233222961 -33.233222961 -11.500000000 -36.233222961 -33.233222961 -10.500000000 -36.233222961 -33.233222961 -9.500000000 -36.233222961 -33.233222961 -8.500000000 -36.233222961 -33.233222961 -7.500000000 -36.233222961 -33.233222961 -6.500000000 -36.233222961 -33.233222961 -5.500000000 -36.233222961 -33.233222961 -4.500000000 -36.233222961 -33.233222961 -3.500000000 -36.233222961 -33.233222961 -2.500000000 -36.233222961 -33.233222961 -1.500000000 -36.233222961 -33.233222961 -0.500000000 -36.233222961 -33.233222961 0.500000000 -36.233222961 -33.233222961 1.500000000 -36.233222961 -33.233222961 2.500000000 -36.233222961 -33.233222961 3.500000000 -36.233222961 -33.233222961 4.500000000 -36.233222961 -33.233222961 5.500000000 -36.233222961 -33.233222961 6.500000000 -36.233222961 -33.233222961 7.500000000 -36.233222961 -33.233222961 8.500000000 -36.233222961 -33.233222961 9.500000000 -36.233222961 -33.233222961 10.500000000 -36.233222961 -33.233222961 11.500000000 -36.233222961 -33.233222961 12.500000000 -36.233222961 -33.233222961 13.500000000 -36.233222961 -33.233222961 14.500000000 -36.233222961 -33.233222961 15.500000000 -36.233222961 -33.233222961 16.500000000 -36.233222961 -33.233222961 17.500000000 -36.233222961 -33.233222961 18.500000000 -36.233222961 -33.233222961 19.500000000 -36.233222961 -33.233222961 20.500000000 -36.233222961 -33.233222961 21.500000000 -36.233222961 -33.233222961 22.500000000 -36.233222961 -33.233222961 23.500000000 -36.233222961 -33.233222961 24.499984741 -36.233207703 -33.233219147 25.499872208 -36.233074188 -33.233173370 26.499225616 -36.232299805 -33.232868195 27.496377945 -36.228958130 -33.231605530 28.486719131 -36.217514038 -33.227878571 29.460596085 -36.185966492 -33.220718384 30.405673981 -36.112342834 -33.216842651 31.334243774 -35.954723358 -33.254276276 32.030693054 -35.846313477 -33.030693054 -34.772163391 -34.772159576 -33.006500244 -34.231872559 -35.057430267 -33.316947937 -33.424438477 -35.498546600 -33.424442291 -32.736049652 -35.670326233 -33.678356171 31.736053467 -35.670326233 -33.678352356 32.424442291 -35.498538971 -33.424442291 33.231872559 -35.057430267 -33.316951752 33.772163391 -34.772159576 -33.006500244 -35.057430267 -34.231872559 -33.316947937 -34.565628052 -34.565628052 -33.672851562 33.565631866 -34.565628052 -33.672847748 34.057430267 -34.231868744 -33.316947937 -35.846313477 -33.030693054 -33.030693054 -35.498542786 -33.424438477 -33.424438477 34.498546600 -33.424438477 -33.424438477 34.846317291 -33.030689240 -33.030693054 -35.954723358 -32.334243774 -33.254276276 -35.670326233 -32.736049652 -33.678352356 34.670322418 -32.736049652 -33.678352356 34.954723358 -32.334243774 -33.254272461 -36.112342834 -31.405673981 -33.216842651 35.112342834 -31.405673981 -33.216842651 -36.185966492 -30.460596085 -33.220722198 35.185966492 -30.460596085 -33.220710754 -36.217510223 -29.486719131 -33.227870941 35.217514038 -29.486715317 -33.227874756 -36.228954315 -28.496377945 -33.231601715 35.228954315 -28.496374130 -33.231601715 -36.232299805 -27.499221802 -33.232868195 35.232299805 -27.499221802 -33.232868195 -36.233074188 -26.499872208 -33.233165741 35.233074188 -26.499872208 -33.233169556 -36.233207703 -25.499984741 -33.233219147 35.233207703 -25.499986649 -33.233219147 -36.233222961 -24.500000000 -33.233222961 35.233222961 -24.499998093 -33.233222961 -36.233222961 -23.500000000 -33.233222961 35.233222961 -23.500000000 -33.233222961 -36.233222961 -22.500000000 -33.233222961 35.233222961 -22.500000000 -33.233222961 -36.233222961 -21.500000000 -33.233222961 35.233222961 -21.500000000 -33.233222961 -36.233222961 -20.500000000 -33.233222961 35.233222961 -20.500000000 -33.233222961 -36.233222961 -19.500000000 -33.233222961 35.233222961 -19.500000000 -33.233222961 -36.233222961 -18.500000000 -33.233222961 35.233222961 -18.500000000 -33.233222961 -36.233222961 -17.500000000 -33.233222961 35.233222961 -17.500000000 -33.233222961 -36.233222961 -16.500000000 -33.233222961 35.233222961 -16.500000000 -33.233222961 -36.233222961 -15.500000000 -33.233222961 35.233222961 -15.500000000 -33.233222961 -36.233222961 -14.500000000 -33.233222961 35.233222961 -14.500000000 -33.233222961 -36.233222961 -13.500000000 -33.233222961 35.233222961 -13.500000000 -33.233222961 -36.233222961 -12.500000000 -33.233222961 35.233222961 -12.500000000 -33.233222961 -36.233222961 -11.500000000 -33.233222961 35.233222961 -11.500000000 -33.233222961 -36.233222961 -10.500000000 -33.233222961 35.233222961 -10.500000000 -33.233222961 -36.233222961 -9.500000000 -33.233222961 35.233222961 -9.500000000 -33.233222961 -36.233222961 -8.500000000 -33.233222961 35.233222961 -8.500000000 -33.233222961 -36.233222961 -7.500000000 -33.233222961 35.233222961 -7.500000000 -33.233222961 -36.233222961 -6.500000000 -33.233222961 35.233222961 -6.500000000 -33.233222961 -36.233222961 -5.500000000 -33.233222961 35.233222961 -5.500000000 -33.233222961 -36.233222961 -4.500000000 -33.233222961 35.233222961 -4.500000000 -33.233222961 -36.233222961 -3.500000000 -33.233222961 35.233222961 -3.500000000 -33.233222961 -36.233222961 -2.500000000 -33.233222961 35.233222961 -2.500000000 -33.233222961 -36.233222961 -1.500000000 -33.233222961 35.233222961 -1.500000000 -33.233222961 -36.233222961 -0.500000000 -33.233222961 35.233222961 -0.500000000 -33.233222961 -36.233222961 0.500000000 -33.233222961 35.233222961 0.500000000 -33.233222961 -36.233222961 1.500000000 -33.233222961 35.233222961 1.500000000 -33.233222961 -36.233222961 2.500000000 -33.233222961 35.233222961 2.500000000 -33.233222961 -36.233222961 3.500000000 -33.233222961 35.233222961 3.500000000 -33.233222961 -36.233222961 4.500000000 -33.233222961 35.233222961 4.500000000 -33.233222961 -36.233222961 5.500000000 -33.233222961 35.233222961 5.500000000 -33.233222961 -36.233222961 6.500000000 -33.233222961 35.233222961 6.500000000 -33.233222961 -36.233222961 7.500000000 -33.233222961 35.233222961 7.500000000 -33.233222961 -36.233222961 8.500000000 -33.233222961 35.233222961 8.500000000 -33.233222961 -36.233222961 9.500000000 -33.233222961 35.233222961 9.500000000 -33.233222961 -36.233222961 10.500000000 -33.233222961 35.233222961 10.500000000 -33.233222961 -36.233222961 11.500000000 -33.233222961 35.233222961 11.500000000 -33.233222961 -36.233222961 12.500000000 -33.233222961 35.233222961 12.500000000 -33.233222961 -36.233222961 13.500000000 -33.233222961 35.233222961 13.500000000 -33.233222961 -36.233222961 14.500000000 -33.233222961 35.233222961 14.500000000 -33.233222961 -36.233222961 15.500000000 -33.233222961 35.233222961 15.500000000 -33.233222961 -36.233222961 16.500000000 -33.233222961 35.233222961 16.500000000 -33.233222961 -36.233222961 17.500000000 -33.233222961 35.233222961 17.500000000 -33.233222961 -36.233222961 18.500000000 -33.233222961 35.233222961 18.500000000 -33.233222961 -36.233222961 19.500000000 -33.233222961 35.233222961 19.500000000 -33.233222961 -36.233222961 20.500000000 -33.233222961 35.233222961 20.500000000 -33.233222961 -36.233222961 21.500000000 -33.233222961 35.233222961 21.500000000 -33.233222961 -36.233222961 22.500000000 -33.233222961 35.233222961 22.500000000 -33.233222961 -36.233222961 23.500000000 -33.233222961 35.233222961 23.500000000 -33.233222961 -36.233207703 24.499984741 -33.233219147 35.233207703 24.499984741 -33.233219147 -36.233074188 25.499872208 -33.233173370 35.233074188 25.499872208 -33.233173370 -36.232299805 26.499225616 -33.232868195 35.232299805 26.499225616 -33.232868195 -36.228958130 27.496377945 -33.231605530 35.228958130 27.496377945 -33.231605530 -36.217517853 28.486719131 -33.227874756 35.217514038 28.486719131 -33.227878571 -36.185966492 29.460596085 -33.220714569 35.185966492 29.460596085 -33.220718384 -36.112346649 30.405673981 -33.216838837 35.112342834 30.405673981 -33.216842651 -35.954723358 31.334243774 -33.254272461 -35.670326233 31.736053467 -33.678352356 34.670326233 31.736053467 -33.678352356 34.954723358 31.334243774 -33.254276276 -35.846317291 32.030693054 -33.030689240 -35.498538971 32.424442291 -33.424442291 34.498538971 32.424442291 -33.424442291 34.846313477 32.030693054 -33.030693054 -35.057430267 33.231872559 -33.316947937 -34.565628052 33.565628052 -33.672851562 33.565624237 33.565631866 -33.672851562 34.057430267 33.231872559 -33.316947937 -34.772159576 33.772163391 -33.006500244 -34.231872559 34.057430267 -33.316947937 -33.424438477 34.498542786 -33.424438477 -32.736049652 34.670326233 -33.678352356 31.736051559 34.670326233 -33.678356171 32.424438477 34.498546600 -33.424442291 33.231868744 34.057430267 -33.316951752 33.772159576 33.772163391 -33.006500244 -33.030693054 34.846313477 -33.030693054 -32.334243774 34.954723358 -33.254276276 -31.405670166 35.112342834 -33.216838837 -30.460596085 35.185966492 -33.220722198 -29.486719131 35.217517853 -33.227870941 -28.496377945 35.228958130 -33.231597900 -27.499225616 35.232299805 -33.232860565 -26.499874115 35.233074188 -33.233165741 -25.499984741 35.233203888 -33.233219147 -24.500000000 35.233222961 -33.233222961 -23.500000000 35.233222961 -33.233222961 -22.500000000 35.233222961 -33.233222961 -21.500000000 35.233222961 -33.233222961 -20.500000000 35.233222961 -33.233222961 -19.500000000 35.233222961 -33.233222961 -18.500000000 35.233222961 -33.233222961 -17.500000000 35.233222961 -33.233222961 -16.500000000 35.233222961 -33.233222961 -15.500000000 35.233222961 -33.233222961 -14.500000000 35.233222961 -33.233222961 -13.500000000 35.233222961 -33.233222961 -12.500000000 35.233222961 -33.233222961 -11.500000000 35.233222961 -33.233222961 -10.500000000 35.233222961 -33.233222961 -9.500000000 35.233222961 -33.233222961 -8.500000000 35.233222961 -33.233222961 -7.500000000 35.233222961 -33.233222961 -6.500000000 35.233222961 -33.233222961 -5.500000000 35.233222961 -33.233222961 -4.500000000 35.233222961 -33.233222961 -3.500000000 35.233222961 -33.233222961 -2.500000000 35.233222961 -33.233222961 -1.500000000 35.233222961 -33.233222961 -0.500000000 35.233222961 -33.233222961 0.500000000 35.233222961 -33.233222961 1.500000000 35.233222961 -33.233222961 2.500000000 35.233222961 -33.233222961 3.500000000 35.233222961 -33.233222961 4.500000000 35.233222961 -33.233222961 5.500000000 35.233222961 -33.233222961 6.500000000 35.233222961 -33.233222961 7.500000000 35.233222961 -33.233222961 8.500000000 35.233222961 -33.233222961 9.500000000 35.233222961 -33.233222961 10.500000000 35.233222961 -33.233222961 11.500000000 35.233222961 -33.233222961 12.500000000 35.233222961 -33.233222961 13.500000000 35.233222961 -33.233222961 14.500000000 35.233222961 -33.233222961 15.500000000 35.233222961 -33.233222961 16.500000000 35.233222961 -33.233222961 17.500000000 35.233222961 -33.233222961 18.500000000 35.233222961 -33.233222961 19.500000000 35.233222961 -33.233222961 20.500000000 35.233222961 -33.233222961 21.500000000 35.233222961 -33.233222961 22.500000000 35.233222961 -33.233222961 23.500000000 35.233222961 -33.233222961 24.499984741 35.233203888 -33.233215332 25.499872208 35.233074188 -33.233165741 26.499225616 35.232299805 -33.232860565 27.496377945 35.228958130 -33.231597900 28.486719131 35.217517853 -33.227867126 29.460596085 35.185966492 -33.220714569 30.405673981 35.112346649 -33.216838837 31.334243774 34.954723358 -33.254272461 32.030693054 34.846317291 -33.030693054 -33.840934753 -35.797355652 -32.035343170 -33.254276276 -35.954723358 -32.334243774 -32.371025085 -36.154674530 -32.371025085 -31.438955307 -36.280395508 -32.375358582 -30.476007462 -36.344284058 -32.379222870 -29.492319107 -36.371490479 -32.382308960 -28.498050690 -36.381023407 -32.383811951 -27.499622345 -36.383720398 -32.384300232 -26.499948502 -36.384311676 -32.384403229 -25.499996185 -36.384407043 -32.384422302 -24.500000000 -36.384418488 -32.384422302 -23.500000000 -36.384418488 -32.384422302 -22.500000000 -36.384418488 -32.384422302 -21.500000000 -36.384418488 -32.384422302 -20.500000000 -36.384418488 -32.384422302 -19.500000000 -36.384418488 -32.384422302 -18.500000000 -36.384418488 -32.384422302 -17.500000000 -36.384418488 -32.384422302 -16.500000000 -36.384418488 -32.384422302 -15.500000000 -36.384418488 -32.384422302 -14.500000000 -36.384418488 -32.384422302 -13.500000000 -36.384418488 -32.384422302 -12.500000000 -36.384418488 -32.384422302 -11.500000000 -36.384418488 -32.384422302 -10.500000000 -36.384418488 -32.384422302 -9.500000000 -36.384418488 -32.384422302 -8.500000000 -36.384418488 -32.384422302 -7.500000000 -36.384418488 -32.384422302 -6.500000000 -36.384418488 -32.384422302 -5.500000000 -36.384418488 -32.384422302 -4.500000000 -36.384418488 -32.384422302 -3.500000000 -36.384418488 -32.384422302 -2.500000000 -36.384418488 -32.384422302 -1.500000000 -36.384418488 -32.384422302 -0.500000000 -36.384418488 -32.384422302 0.500000000 -36.384418488 -32.384422302 1.500000000 -36.384418488 -32.384422302 2.500000000 -36.384418488 -32.384422302 3.500000000 -36.384418488 -32.384422302 4.500000000 -36.384418488 -32.384422302 5.500000000 -36.384418488 -32.384422302 6.500000000 -36.384418488 -32.384422302 7.500000000 -36.384418488 -32.384422302 8.500000000 -36.384418488 -32.384422302 9.500000000 -36.384418488 -32.384422302 10.500000000 -36.384418488 -32.384422302 11.500000000 -36.384418488 -32.384422302 12.500000000 -36.384418488 -32.384422302 13.500000000 -36.384418488 -32.384422302 14.500000000 -36.384418488 -32.384422302 15.500000000 -36.384418488 -32.384422302 16.500000000 -36.384418488 -32.384422302 17.500000000 -36.384418488 -32.384422302 18.500000000 -36.384418488 -32.384422302 19.500000000 -36.384418488 -32.384422302 20.500000000 -36.384418488 -32.384422302 21.500000000 -36.384418488 -32.384422302 22.500000000 -36.384418488 -32.384422302 23.500000000 -36.384418488 -32.384422302 24.499996185 -36.384407043 -32.384422302 25.499948502 -36.384307861 -32.384407043 26.499618530 -36.383720398 -32.384300232 27.498050690 -36.381023407 -32.383811951 28.492321014 -36.371490479 -32.382316589 29.476007462 -36.344280243 -32.379222870 30.438953400 -36.280391693 -32.375358582 31.371026993 -36.154674530 -32.371025085 32.254276276 -35.954723358 -32.334247589 32.840934753 -35.797351837 -32.035343170 -34.912067413 -34.912067413 -32.313598633 -34.260543823 -35.428531647 -32.380737305 -33.678352356 -35.670322418 -32.736049652 32.678356171 -35.670322418 -32.736053467 33.260543823 -35.428531647 -32.380737305 33.912067413 -34.912059784 -32.313602448 -35.797355652 -33.840934753 -32.035343170 -35.428531647 -34.260547638 -32.380737305 34.428535461 -34.260540009 -32.380737305 34.797355652 -33.840934753 -32.035343170 -35.954719543 -33.254276276 -32.334243774 -35.670322418 -33.678352356 -32.736053467 34.670322418 -33.678352356 -32.736053467 34.954723358 -33.254276276 -32.334243774 -36.154674530 -32.371025085 -32.371025085 35.154674530 -32.371025085 -32.371025085 -36.280395508 -31.438953400 -32.375358582 35.280395508 -31.438953400 -32.375358582 -36.344284058 -30.476003647 -32.379226685 35.344284058 -30.476007462 -32.379222870 -36.371490479 -29.492319107 -32.382312775 35.371490479 -29.492319107 -32.382308960 -36.381023407 -28.498050690 -32.383808136 35.381023407 -28.498050690 -32.383811951 -36.383724213 -27.499622345 -32.384296417 35.383720398 -27.499622345 -32.384300232 -36.384311676 -26.499948502 -32.384403229 35.384311676 -26.499948502 -32.384403229 -36.384407043 -25.499996185 -32.384418488 35.384407043 -25.499996185 -32.384422302 -36.384422302 -24.500000000 -32.384422302 35.384418488 -24.500000000 -32.384422302 -36.384422302 -23.500000000 -32.384422302 35.384418488 -23.500000000 -32.384422302 -36.384422302 -22.500000000 -32.384422302 35.384418488 -22.500000000 -32.384422302 -36.384422302 -21.500000000 -32.384422302 35.384418488 -21.500000000 -32.384422302 -36.384422302 -20.500000000 -32.384422302 35.384418488 -20.500000000 -32.384422302 -36.384422302 -19.500000000 -32.384422302 35.384418488 -19.500000000 -32.384422302 -36.384422302 -18.500000000 -32.384422302 35.384418488 -18.500000000 -32.384422302 -36.384422302 -17.500000000 -32.384422302 35.384418488 -17.500000000 -32.384422302 -36.384422302 -16.500000000 -32.384422302 35.384418488 -16.500000000 -32.384422302 -36.384422302 -15.500000000 -32.384422302 35.384418488 -15.500000000 -32.384422302 -36.384422302 -14.500000000 -32.384422302 35.384418488 -14.500000000 -32.384422302 -36.384422302 -13.500000000 -32.384422302 35.384418488 -13.500000000 -32.384422302 -36.384422302 -12.500000000 -32.384422302 35.384418488 -12.500000000 -32.384422302 -36.384422302 -11.500000000 -32.384422302 35.384418488 -11.500000000 -32.384422302 -36.384422302 -10.500000000 -32.384422302 35.384418488 -10.500000000 -32.384422302 -36.384422302 -9.500000000 -32.384422302 35.384418488 -9.500000000 -32.384422302 -36.384422302 -8.500000000 -32.384422302 35.384418488 -8.500000000 -32.384422302 -36.384422302 -7.500000000 -32.384422302 35.384418488 -7.500000000 -32.384422302 -36.384422302 -6.500000000 -32.384422302 35.384418488 -6.500000000 -32.384422302 -36.384422302 -5.500000000 -32.384422302 35.384418488 -5.500000000 -32.384422302 -36.384422302 -4.500000000 -32.384422302 35.384418488 -4.500000000 -32.384422302 -36.384422302 -3.500000000 -32.384422302 35.384418488 -3.500000000 -32.384422302 -36.384422302 -2.500000000 -32.384422302 35.384418488 -2.500000000 -32.384422302 -36.384422302 -1.500000000 -32.384422302 35.384418488 -1.500000000 -32.384422302 -36.384422302 -0.500000000 -32.384422302 35.384418488 -0.500000000 -32.384422302 -36.384422302 0.500000000 -32.384422302 35.384418488 0.500000000 -32.384422302 -36.384422302 1.500000000 -32.384422302 35.384418488 1.500000000 -32.384422302 -36.384422302 2.500000000 -32.384422302 35.384418488 2.500000000 -32.384422302 -36.384422302 3.500000000 -32.384422302 35.384418488 3.500000000 -32.384422302 -36.384422302 4.500000000 -32.384422302 35.384418488 4.500000000 -32.384422302 -36.384422302 5.500000000 -32.384422302 35.384418488 5.500000000 -32.384422302 -36.384422302 6.500000000 -32.384422302 35.384418488 6.500000000 -32.384422302 -36.384422302 7.500000000 -32.384422302 35.384418488 7.500000000 -32.384422302 -36.384422302 8.500000000 -32.384422302 35.384418488 8.500000000 -32.384422302 -36.384422302 9.500000000 -32.384422302 35.384418488 9.500000000 -32.384422302 -36.384422302 10.500000000 -32.384422302 35.384418488 10.500000000 -32.384422302 -36.384422302 11.500000000 -32.384422302 35.384418488 11.500000000 -32.384422302 -36.384422302 12.500000000 -32.384422302 35.384418488 12.500000000 -32.384422302 -36.384422302 13.500000000 -32.384422302 35.384418488 13.500000000 -32.384422302 -36.384422302 14.500000000 -32.384422302 35.384418488 14.500000000 -32.384422302 -36.384422302 15.500000000 -32.384422302 35.384418488 15.500000000 -32.384422302 -36.384422302 16.500000000 -32.384422302 35.384418488 16.500000000 -32.384422302 -36.384422302 17.500000000 -32.384422302 35.384418488 17.500000000 -32.384422302 -36.384422302 18.500000000 -32.384422302 35.384418488 18.500000000 -32.384422302 -36.384422302 19.500000000 -32.384422302 35.384418488 19.500000000 -32.384422302 -36.384422302 20.500000000 -32.384422302 35.384418488 20.500000000 -32.384422302 -36.384422302 21.500000000 -32.384422302 35.384418488 21.500000000 -32.384422302 -36.384422302 22.500000000 -32.384422302 35.384418488 22.500000000 -32.384422302 -36.384422302 23.500000000 -32.384422302 35.384418488 23.500000000 -32.384422302 -36.384407043 24.499996185 -32.384418488 35.384407043 24.499996185 -32.384422302 -36.384307861 25.499948502 -32.384403229 35.384307861 25.499948502 -32.384407043 -36.383720398 26.499622345 -32.384300232 35.383720398 26.499618530 -32.384300232 -36.381023407 27.498050690 -32.383811951 35.381023407 27.498050690 -32.383811951 -36.371490479 28.492321014 -32.382312775 35.371490479 28.492321014 -32.382316589 -36.344287872 29.476007462 -32.379222870 35.344280243 29.476007462 -32.379222870 -36.280395508 30.438953400 -32.375358582 35.280391693 30.438953400 -32.375358582 -36.154674530 31.371026993 -32.371025085 35.154674530 31.371026993 -32.371025085 -35.954723358 32.254276276 -32.334243774 -35.670322418 32.678356171 -32.736049652 34.670322418 32.678356171 -32.736053467 34.954723358 32.254276276 -32.334247589 -35.797355652 32.840934753 -32.035339355 -35.428535461 33.260543823 -32.380737305 34.428531647 33.260543823 -32.380737305 34.797351837 32.840934753 -32.035343170 -34.912067413 33.912067413 -32.313598633 -34.260547638 34.428531647 -32.380737305 -33.678352356 34.670322418 -32.736053467 32.678352356 34.670326233 -32.736053467 33.260543823 34.428535461 -32.380737305 33.912059784 33.912059784 -32.313602448 -33.840934753 34.797355652 -32.035343170 -33.254276276 34.954719543 -32.334243774 -32.371025085 35.154674530 -32.371025085 -31.438953400 35.280395508 -32.375358582 -30.476003647 35.344284058 -32.379226685 -29.492319107 35.371490479 -32.382312775 -28.498050690 35.381023407 -32.383808136 -27.499622345 35.383724213 -32.384296417 -26.499948502 35.384307861 -32.384403229 -25.499996185 35.384407043 -32.384418488 -24.500000000 35.384422302 -32.384422302 -23.500000000 35.384422302 -32.384422302 -22.500000000 35.384422302 -32.384422302 -21.500000000 35.384422302 -32.384422302 -20.500000000 35.384422302 -32.384422302 -19.500000000 35.384422302 -32.384422302 -18.500000000 35.384422302 -32.384422302 -17.500000000 35.384422302 -32.384422302 -16.500000000 35.384422302 -32.384422302 -15.500000000 35.384422302 -32.384422302 -14.500000000 35.384422302 -32.384422302 -13.500000000 35.384422302 -32.384422302 -12.500000000 35.384422302 -32.384422302 -11.500000000 35.384422302 -32.384422302 -10.500000000 35.384422302 -32.384422302 -9.500000000 35.384422302 -32.384422302 -8.500000000 35.384422302 -32.384422302 -7.500000000 35.384422302 -32.384422302 -6.500000000 35.384422302 -32.384422302 -5.500000000 35.384422302 -32.384422302 -4.500000000 35.384422302 -32.384422302 -3.500000000 35.384422302 -32.384422302 -2.500000000 35.384422302 -32.384422302 -1.500000000 35.384422302 -32.384422302 -0.500000000 35.384422302 -32.384422302 0.500000000 35.384422302 -32.384422302 1.500000000 35.384422302 -32.384422302 2.500000000 35.384422302 -32.384422302 3.500000000 35.384422302 -32.384422302 4.500000000 35.384422302 -32.384422302 5.500000000 35.384422302 -32.384422302 6.500000000 35.384422302 -32.384422302 7.500000000 35.384422302 -32.384422302 8.500000000 35.384422302 -32.384422302 9.500000000 35.384422302 -32.384422302 10.500000000 35.384422302 -32.384422302 11.500000000 35.384422302 -32.384422302 12.500000000 35.384422302 -32.384422302 13.500000000 35.384422302 -32.384422302 14.500000000 35.384422302 -32.384422302 15.500000000 35.384422302 -32.384422302 16.500000000 35.384422302 -32.384422302 17.500000000 35.384422302 -32.384422302 18.500000000 35.384422302 -32.384422302 19.500000000 35.384422302 -32.384422302 20.500000000 35.384422302 -32.384422302 21.500000000 35.384422302 -32.384422302 22.500000000 35.384422302 -32.384422302 23.500000000 35.384422302 -32.384422302 24.499996185 35.384407043 -32.384418488 25.499948502 35.384307861 -32.384403229 26.499622345 35.383720398 -32.384296417 27.498050690 35.381023407 -32.383808136 28.492321014 35.371490479 -32.382312775 29.476007462 35.344287872 -32.379222870 30.438953400 35.280395508 -32.375358582 31.371026993 35.154674530 -32.371025085 32.254276276 34.954723358 -32.334243774 32.840934753 34.797355652 -32.035346985 -33.903377533 -35.879737854 -31.336599350 -33.216838837 -36.112346649 -31.405673981 -32.375358582 -36.280395508 -31.438953400 -31.451217651 -36.380989075 -31.451221466 -30.483785629 -36.430477142 -31.456085205 -29.495611191 -36.450424194 -31.458078384 -28.499073029 -36.456939697 -31.458770752 -27.499858856 -36.458606720 -31.458948135 -26.499988556 -36.458930969 -31.458978653 -25.500000000 -36.458976746 -31.458980560 -24.500000000 -36.458976746 -31.458980560 -23.500000000 -36.458976746 -31.458980560 -22.500000000 -36.458976746 -31.458980560 -21.500000000 -36.458976746 -31.458980560 -20.500000000 -36.458976746 -31.458980560 -19.500000000 -36.458976746 -31.458980560 -18.500000000 -36.458976746 -31.458980560 -17.500000000 -36.458976746 -31.458980560 -16.500000000 -36.458976746 -31.458980560 -15.500000000 -36.458976746 -31.458980560 -14.500000000 -36.458976746 -31.458980560 -13.500000000 -36.458976746 -31.458980560 -12.500000000 -36.458976746 -31.458980560 -11.500000000 -36.458976746 -31.458980560 -10.500000000 -36.458976746 -31.458980560 -9.500000000 -36.458976746 -31.458980560 -8.500000000 -36.458976746 -31.458980560 -7.500000000 -36.458976746 -31.458980560 -6.500000000 -36.458976746 -31.458980560 -5.500000000 -36.458976746 -31.458980560 -4.500000000 -36.458976746 -31.458980560 -3.500000000 -36.458976746 -31.458980560 -2.500000000 -36.458976746 -31.458980560 -1.500000000 -36.458976746 -31.458980560 -0.500000000 -36.458976746 -31.458980560 0.500000000 -36.458976746 -31.458980560 1.500000000 -36.458976746 -31.458980560 2.500000000 -36.458976746 -31.458980560 3.500000000 -36.458976746 -31.458980560 4.500000000 -36.458976746 -31.458980560 5.500000000 -36.458976746 -31.458980560 6.500000000 -36.458976746 -31.458980560 7.500000000 -36.458976746 -31.458980560 8.500000000 -36.458976746 -31.458980560 9.500000000 -36.458976746 -31.458980560 10.500000000 -36.458976746 -31.458980560 11.500000000 -36.458976746 -31.458980560 12.500000000 -36.458976746 -31.458980560 13.500000000 -36.458976746 -31.458980560 14.500000000 -36.458976746 -31.458980560 15.500000000 -36.458976746 -31.458980560 16.500000000 -36.458976746 -31.458980560 17.500000000 -36.458976746 -31.458980560 18.500000000 -36.458976746 -31.458980560 19.500000000 -36.458976746 -31.458980560 20.500000000 -36.458976746 -31.458980560 21.500000000 -36.458976746 -31.458980560 22.500000000 -36.458976746 -31.458980560 23.500000000 -36.458976746 -31.458980560 24.500000000 -36.458976746 -31.458980560 25.499988556 -36.458930969 -31.458978653 26.499858856 -36.458606720 -31.458948135 27.499073029 -36.456939697 -31.458770752 28.495611191 -36.450424194 -31.458080292 29.483785629 -36.430473328 -31.456085205 30.451217651 -36.380989075 -31.451217651 31.375360489 -36.280395508 -31.438953400 32.216842651 -36.112346649 -31.405673981 32.903377533 -35.879737854 -31.336599350 -35.040893555 -35.040893555 -31.413045883 -34.477191925 -35.518615723 -31.410831451 33.477191925 -35.518611908 -31.410831451 34.040893555 -35.040893555 -31.413045883 -35.879737854 -33.903373718 -31.336599350 -35.518615723 -34.477191925 -31.410831451 34.518611908 -34.477191925 -31.410831451 34.879737854 -33.903381348 -31.336599350 -36.112342834 -33.216842651 -31.405673981 35.112346649 -33.216842651 -31.405673981 -36.280395508 -32.375358582 -31.438953400 35.280395508 -32.375358582 -31.438955307 -36.380989075 -31.451213837 -31.451221466 35.380989075 -31.451217651 -31.451221466 -36.430477142 -30.483785629 -31.456089020 35.430477142 -30.483785629 -31.456085205 -36.450424194 -29.495611191 -31.458080292 35.450424194 -29.495611191 -31.458078384 -36.456943512 -28.499073029 -31.458770752 35.456939697 -28.499073029 -31.458770752 -36.458606720 -27.499858856 -31.458948135 35.458606720 -27.499858856 -31.458948135 -36.458934784 -26.499988556 -31.458974838 35.458930969 -26.499988556 -31.458978653 -36.458976746 -25.500000000 -31.458978653 35.458976746 -25.500000000 -31.458980560 -36.458984375 -24.500000000 -31.458978653 35.458976746 -24.500000000 -31.458980560 -36.458984375 -23.500000000 -31.458978653 35.458976746 -23.500000000 -31.458980560 -36.458984375 -22.500000000 -31.458978653 35.458976746 -22.500000000 -31.458980560 -36.458984375 -21.500000000 -31.458978653 35.458976746 -21.500000000 -31.458980560 -36.458984375 -20.500000000 -31.458978653 35.458976746 -20.500000000 -31.458980560 -36.458984375 -19.500000000 -31.458978653 35.458976746 -19.500000000 -31.458980560 -36.458984375 -18.500000000 -31.458978653 35.458976746 -18.500000000 -31.458980560 -36.458984375 -17.500000000 -31.458978653 35.458976746 -17.500000000 -31.458980560 -36.458984375 -16.500000000 -31.458978653 35.458976746 -16.500000000 -31.458980560 -36.458984375 -15.500000000 -31.458978653 35.458976746 -15.500000000 -31.458980560 -36.458984375 -14.500000000 -31.458978653 35.458976746 -14.500000000 -31.458980560 -36.458984375 -13.500000000 -31.458978653 35.458976746 -13.500000000 -31.458980560 -36.458984375 -12.500000000 -31.458978653 35.458976746 -12.500000000 -31.458980560 -36.458984375 -11.500000000 -31.458978653 35.458976746 -11.500000000 -31.458980560 -36.458984375 -10.500000000 -31.458978653 35.458976746 -10.500000000 -31.458980560 -36.458984375 -9.500000000 -31.458978653 35.458976746 -9.500000000 -31.458980560 -36.458984375 -8.500000000 -31.458978653 35.458976746 -8.500000000 -31.458980560 -36.458984375 -7.500000000 -31.458978653 35.458976746 -7.500000000 -31.458980560 -36.458984375 -6.500000000 -31.458978653 35.458976746 -6.500000000 -31.458980560 -36.458984375 -5.500000000 -31.458978653 35.458976746 -5.500000000 -31.458980560 -36.458984375 -4.500000000 -31.458978653 35.458976746 -4.500000000 -31.458980560 -36.458984375 -3.500000000 -31.458978653 35.458976746 -3.500000000 -31.458980560 -36.458984375 -2.500000000 -31.458978653 35.458976746 -2.500000000 -31.458980560 -36.458984375 -1.500000000 -31.458978653 35.458976746 -1.500000000 -31.458980560 -36.458984375 -0.500000000 -31.458978653 35.458976746 -0.500000000 -31.458980560 -36.458984375 0.500000000 -31.458978653 35.458976746 0.500000000 -31.458980560 -36.458984375 1.500000000 -31.458978653 35.458976746 1.500000000 -31.458980560 -36.458984375 2.500000000 -31.458978653 35.458976746 2.500000000 -31.458980560 -36.458984375 3.500000000 -31.458978653 35.458976746 3.500000000 -31.458980560 -36.458984375 4.500000000 -31.458978653 35.458976746 4.500000000 -31.458980560 -36.458984375 5.500000000 -31.458978653 35.458976746 5.500000000 -31.458980560 -36.458984375 6.500000000 -31.458978653 35.458976746 6.500000000 -31.458980560 -36.458984375 7.500000000 -31.458978653 35.458976746 7.500000000 -31.458980560 -36.458984375 8.500000000 -31.458978653 35.458976746 8.500000000 -31.458980560 -36.458984375 9.500000000 -31.458978653 35.458976746 9.500000000 -31.458980560 -36.458984375 10.500000000 -31.458978653 35.458976746 10.500000000 -31.458980560 -36.458984375 11.500000000 -31.458978653 35.458976746 11.500000000 -31.458980560 -36.458984375 12.500000000 -31.458978653 35.458976746 12.500000000 -31.458980560 -36.458984375 13.500000000 -31.458978653 35.458976746 13.500000000 -31.458980560 -36.458984375 14.500000000 -31.458978653 35.458976746 14.500000000 -31.458980560 -36.458984375 15.500000000 -31.458978653 35.458976746 15.500000000 -31.458980560 -36.458984375 16.500000000 -31.458978653 35.458976746 16.500000000 -31.458980560 -36.458984375 17.500000000 -31.458978653 35.458976746 17.500000000 -31.458980560 -36.458984375 18.500000000 -31.458978653 35.458976746 18.500000000 -31.458980560 -36.458984375 19.500000000 -31.458978653 35.458976746 19.500000000 -31.458980560 -36.458984375 20.500000000 -31.458978653 35.458976746 20.500000000 -31.458980560 -36.458984375 21.500000000 -31.458978653 35.458976746 21.500000000 -31.458980560 -36.458984375 22.500000000 -31.458978653 35.458976746 22.500000000 -31.458980560 -36.458984375 23.500000000 -31.458978653 35.458976746 23.500000000 -31.458980560 -36.458976746 24.500000000 -31.458978653 35.458976746 24.500000000 -31.458980560 -36.458934784 25.499988556 -31.458974838 35.458930969 25.499988556 -31.458978653 -36.458606720 26.499858856 -31.458948135 35.458606720 26.499858856 -31.458948135 -36.456943512 27.499073029 -31.458770752 35.456939697 27.499073029 -31.458770752 -36.450424194 28.495611191 -31.458080292 35.450424194 28.495611191 -31.458080292 -36.430473328 29.483785629 -31.456085205 35.430473328 29.483785629 -31.456085205 -36.380989075 30.451217651 -31.451217651 35.380989075 30.451217651 -31.451217651 -36.280395508 31.375360489 -31.438953400 35.280395508 31.375360489 -31.438953400 -36.112342834 32.216842651 -31.405673981 35.112346649 32.216842651 -31.405673981 -35.879737854 32.903377533 -31.336603165 -35.518615723 33.477191925 -31.410833359 34.518611908 33.477191925 -31.410831451 34.879737854 32.903377533 -31.336599350 -35.040893555 34.040893555 -31.413049698 -34.477191925 34.518615723 -31.410831451 33.477191925 34.518611908 -31.410831451 34.040893555 34.040893555 -31.413045883 -33.903373718 34.879737854 -31.336599350 -33.216842651 35.112342834 -31.405673981 -32.375358582 35.280395508 -31.438953400 -31.451213837 35.380989075 -31.451221466 -30.483785629 35.430477142 -31.456089020 -29.495611191 35.450424194 -31.458080292 -28.499073029 35.456943512 -31.458766937 -27.499858856 35.458606720 -31.458948135 -26.499988556 35.458934784 -31.458974838 -25.500000000 35.458976746 -31.458978653 -24.500000000 35.458984375 -31.458978653 -23.500000000 35.458984375 -31.458978653 -22.500000000 35.458984375 -31.458978653 -21.500000000 35.458984375 -31.458978653 -20.500000000 35.458984375 -31.458978653 -19.500000000 35.458984375 -31.458978653 -18.500000000 35.458984375 -31.458978653 -17.500000000 35.458984375 -31.458978653 -16.500000000 35.458984375 -31.458978653 -15.500000000 35.458984375 -31.458978653 -14.500000000 35.458984375 -31.458978653 -13.500000000 35.458984375 -31.458978653 -12.500000000 35.458984375 -31.458978653 -11.500000000 35.458984375 -31.458978653 -10.500000000 35.458984375 -31.458978653 -9.500000000 35.458984375 -31.458978653 -8.500000000 35.458984375 -31.458978653 -7.500000000 35.458984375 -31.458978653 -6.500000000 35.458984375 -31.458978653 -5.500000000 35.458984375 -31.458978653 -4.500000000 35.458984375 -31.458978653 -3.500000000 35.458984375 -31.458978653 -2.500000000 35.458984375 -31.458978653 -1.500000000 35.458984375 -31.458978653 -0.500000000 35.458984375 -31.458978653 0.500000000 35.458984375 -31.458978653 1.500000000 35.458984375 -31.458978653 2.500000000 35.458984375 -31.458978653 3.500000000 35.458984375 -31.458978653 4.500000000 35.458984375 -31.458978653 5.500000000 35.458984375 -31.458978653 6.500000000 35.458984375 -31.458978653 7.500000000 35.458984375 -31.458978653 8.500000000 35.458984375 -31.458978653 9.500000000 35.458984375 -31.458978653 10.500000000 35.458984375 -31.458978653 11.500000000 35.458984375 -31.458978653 12.500000000 35.458984375 -31.458978653 13.500000000 35.458984375 -31.458978653 14.500000000 35.458984375 -31.458978653 15.500000000 35.458984375 -31.458978653 16.500000000 35.458984375 -31.458978653 17.500000000 35.458984375 -31.458978653 18.500000000 35.458984375 -31.458978653 19.500000000 35.458984375 -31.458978653 20.500000000 35.458984375 -31.458978653 21.500000000 35.458984375 -31.458978653 22.500000000 35.458984375 -31.458978653 23.500000000 35.458984375 -31.458978653 24.500000000 35.458976746 -31.458978653 25.499988556 35.458934784 -31.458974838 26.499858856 35.458606720 -31.458948135 27.499073029 35.456943512 -31.458770752 28.495611191 35.450424194 -31.458078384 29.483785629 35.430473328 -31.456085205 30.451217651 35.380989075 -31.451217651 31.375356674 35.280395508 -31.438953400 32.216842651 35.112342834 -31.405673981 32.903377533 34.879737854 -31.336599350 -33.946811676 -35.937088013 -30.442840576 -33.220714569 -36.185966492 -30.460596085 -32.379222870 -36.344284058 -30.476007462 -31.456081390 -36.430477142 -30.483789444 -30.486965179 -36.469234467 -30.486968994 -29.496957779 -36.483337402 -30.488048553 -28.499475479 -36.487373352 -30.488346100 -27.499938965 -36.488258362 -30.488399506 -26.499996185 -36.488391876 -30.488403320 -25.500000000 -36.488403320 -30.488403320 -24.500000000 -36.488403320 -30.488403320 -23.500000000 -36.488403320 -30.488403320 -22.500000000 -36.488403320 -30.488403320 -21.500000000 -36.488403320 -30.488403320 -20.500000000 -36.488403320 -30.488403320 -19.500000000 -36.488403320 -30.488403320 -18.500000000 -36.488403320 -30.488403320 -17.500000000 -36.488403320 -30.488403320 -16.500000000 -36.488403320 -30.488403320 -15.500000000 -36.488403320 -30.488403320 -14.500000000 -36.488403320 -30.488403320 -13.500000000 -36.488403320 -30.488403320 -12.500000000 -36.488403320 -30.488403320 -11.500000000 -36.488403320 -30.488403320 -10.500000000 -36.488403320 -30.488403320 -9.500000000 -36.488403320 -30.488403320 -8.500000000 -36.488403320 -30.488403320 -7.500000000 -36.488403320 -30.488403320 -6.500000000 -36.488403320 -30.488403320 -5.500000000 -36.488403320 -30.488403320 -4.500000000 -36.488403320 -30.488403320 -3.500000000 -36.488403320 -30.488403320 -2.500000000 -36.488403320 -30.488403320 -1.500000000 -36.488403320 -30.488403320 -0.500000000 -36.488403320 -30.488403320 0.500000000 -36.488403320 -30.488403320 1.500000000 -36.488403320 -30.488403320 2.500000000 -36.488403320 -30.488403320 3.500000000 -36.488403320 -30.488403320 4.500000000 -36.488403320 -30.488403320 5.500000000 -36.488403320 -30.488403320 6.500000000 -36.488403320 -30.488403320 7.500000000 -36.488403320 -30.488403320 8.500000000 -36.488403320 -30.488403320 9.500000000 -36.488403320 -30.488403320 10.500000000 -36.488403320 -30.488403320 11.500000000 -36.488403320 -30.488403320 12.500000000 -36.488403320 -30.488403320 13.500000000 -36.488403320 -30.488403320 14.500000000 -36.488403320 -30.488403320 15.500000000 -36.488403320 -30.488403320 16.500000000 -36.488403320 -30.488403320 17.500000000 -36.488403320 -30.488403320 18.500000000 -36.488403320 -30.488403320 19.500000000 -36.488403320 -30.488403320 20.500000000 -36.488403320 -30.488403320 21.500000000 -36.488403320 -30.488403320 22.500000000 -36.488403320 -30.488403320 23.500000000 -36.488403320 -30.488403320 24.500000000 -36.488403320 -30.488403320 25.499996185 -36.488391876 -30.488403320 26.499938965 -36.488258362 -30.488399506 27.499475479 -36.487373352 -30.488346100 28.496959686 -36.483337402 -30.488048553 29.486968994 -36.469234467 -30.486968994 30.456085205 -36.430473328 -30.483785629 31.379222870 -36.344284058 -30.476003647 32.220714569 -36.185966492 -30.460596085 32.946811676 -35.937088013 -30.442840576 -35.115646362 -35.115638733 -30.463253021 -34.567749023 -35.577739716 -30.459178925 33.567749023 -35.577739716 -30.459178925 34.115646362 -35.115642548 -30.463253021 -35.937091827 -33.946807861 -30.442840576 -35.577739716 -34.567741394 -30.459177017 34.577739716 -34.567749023 -30.459177017 34.937091827 -33.946811676 -30.442840576 -36.185966492 -33.220714569 -30.460592270 35.185966492 -33.220714569 -30.460596085 -36.344284058 -32.379222870 -30.476007462 35.344284058 -32.379222870 -30.476007462 -36.430477142 -31.456085205 -30.483789444 35.430477142 -31.456081390 -30.483789444 -36.469234467 -30.486968994 -30.486968994 35.469234467 -30.486965179 -30.486968994 -36.483337402 -29.496957779 -30.488048553 35.483337402 -29.496957779 -30.488048553 -36.487373352 -28.499475479 -30.488342285 35.487373352 -28.499475479 -30.488346100 -36.488258362 -27.499938965 -30.488397598 35.488258362 -27.499938965 -30.488399506 -36.488391876 -26.499996185 -30.488403320 35.488391876 -26.499996185 -30.488403320 -36.488410950 -25.500000000 -30.488403320 35.488403320 -25.500000000 -30.488403320 -36.488410950 -24.500000000 -30.488403320 35.488403320 -24.500000000 -30.488403320 -36.488410950 -23.500000000 -30.488403320 35.488403320 -23.500000000 -30.488403320 -36.488410950 -22.500000000 -30.488403320 35.488403320 -22.500000000 -30.488403320 -36.488410950 -21.500000000 -30.488403320 35.488403320 -21.500000000 -30.488403320 -36.488410950 -20.500000000 -30.488403320 35.488403320 -20.500000000 -30.488403320 -36.488410950 -19.500000000 -30.488403320 35.488403320 -19.500000000 -30.488403320 -36.488410950 -18.500000000 -30.488403320 35.488403320 -18.500000000 -30.488403320 -36.488410950 -17.500000000 -30.488403320 35.488403320 -17.500000000 -30.488403320 -36.488410950 -16.500000000 -30.488403320 35.488403320 -16.500000000 -30.488403320 -36.488410950 -15.500000000 -30.488403320 35.488403320 -15.500000000 -30.488403320 -36.488410950 -14.500000000 -30.488403320 35.488403320 -14.500000000 -30.488403320 -36.488410950 -13.500000000 -30.488403320 35.488403320 -13.500000000 -30.488403320 -36.488410950 -12.500000000 -30.488403320 35.488403320 -12.500000000 -30.488403320 -36.488410950 -11.500000000 -30.488403320 35.488403320 -11.500000000 -30.488403320 -36.488410950 -10.500000000 -30.488403320 35.488403320 -10.500000000 -30.488403320 -36.488410950 -9.500000000 -30.488403320 35.488403320 -9.500000000 -30.488403320 -36.488410950 -8.500000000 -30.488403320 35.488403320 -8.500000000 -30.488403320 -36.488410950 -7.500000000 -30.488403320 35.488403320 -7.500000000 -30.488403320 -36.488410950 -6.500000000 -30.488403320 35.488403320 -6.500000000 -30.488403320 -36.488410950 -5.500000000 -30.488403320 35.488403320 -5.500000000 -30.488403320 -36.488410950 -4.500000000 -30.488403320 35.488403320 -4.500000000 -30.488403320 -36.488410950 -3.500000000 -30.488403320 35.488403320 -3.500000000 -30.488403320 -36.488410950 -2.500000000 -30.488403320 35.488403320 -2.500000000 -30.488403320 -36.488410950 -1.500000000 -30.488403320 35.488403320 -1.500000000 -30.488403320 -36.488410950 -0.500000000 -30.488403320 35.488403320 -0.500000000 -30.488403320 -36.488410950 0.500000000 -30.488403320 35.488403320 0.500000000 -30.488403320 -36.488410950 1.500000000 -30.488403320 35.488403320 1.500000000 -30.488403320 -36.488410950 2.500000000 -30.488403320 35.488403320 2.500000000 -30.488403320 -36.488410950 3.500000000 -30.488403320 35.488403320 3.500000000 -30.488403320 -36.488410950 4.500000000 -30.488403320 35.488403320 4.500000000 -30.488403320 -36.488410950 5.500000000 -30.488403320 35.488403320 5.500000000 -30.488403320 -36.488410950 6.500000000 -30.488403320 35.488403320 6.500000000 -30.488403320 -36.488410950 7.500000000 -30.488403320 35.488403320 7.500000000 -30.488403320 -36.488410950 8.500000000 -30.488403320 35.488403320 8.500000000 -30.488403320 -36.488410950 9.500000000 -30.488403320 35.488403320 9.500000000 -30.488403320 -36.488410950 10.500000000 -30.488403320 35.488403320 10.500000000 -30.488403320 -36.488410950 11.500000000 -30.488403320 35.488403320 11.500000000 -30.488403320 -36.488410950 12.500000000 -30.488403320 35.488403320 12.500000000 -30.488403320 -36.488410950 13.500000000 -30.488403320 35.488403320 13.500000000 -30.488403320 -36.488410950 14.500000000 -30.488403320 35.488403320 14.500000000 -30.488403320 -36.488410950 15.500000000 -30.488403320 35.488403320 15.500000000 -30.488403320 -36.488410950 16.500000000 -30.488403320 35.488403320 16.500000000 -30.488403320 -36.488410950 17.500000000 -30.488403320 35.488403320 17.500000000 -30.488403320 -36.488410950 18.500000000 -30.488403320 35.488403320 18.500000000 -30.488403320 -36.488410950 19.500000000 -30.488403320 35.488403320 19.500000000 -30.488403320 -36.488410950 20.500000000 -30.488403320 35.488403320 20.500000000 -30.488403320 -36.488410950 21.500000000 -30.488403320 35.488403320 21.500000000 -30.488403320 -36.488410950 22.500000000 -30.488403320 35.488403320 22.500000000 -30.488403320 -36.488410950 23.500000000 -30.488403320 35.488403320 23.500000000 -30.488403320 -36.488410950 24.500000000 -30.488403320 35.488403320 24.500000000 -30.488403320 -36.488395691 25.499996185 -30.488403320 35.488391876 25.499996185 -30.488403320 -36.488258362 26.499938965 -30.488399506 35.488258362 26.499938965 -30.488399506 -36.487373352 27.499477386 -30.488346100 35.487373352 27.499475479 -30.488346100 -36.483337402 28.496959686 -30.488052368 35.483337402 28.496959686 -30.488048553 -36.469234467 29.486968994 -30.486968994 35.469234467 29.486968994 -30.486968994 -36.430477142 30.456085205 -30.483785629 35.430473328 30.456085205 -30.483785629 -36.344284058 31.379222870 -30.476007462 35.344284058 31.379222870 -30.476003647 -36.185966492 32.220714569 -30.460596085 35.185966492 32.220714569 -30.460596085 -35.937088013 32.946811676 -30.442840576 -35.577739716 33.567749023 -30.459178925 34.577739716 33.567749023 -30.459178925 34.937088013 32.946811676 -30.442840576 -35.115638733 34.115646362 -30.463253021 -34.567741394 34.577739716 -30.459177017 33.567749023 34.577739716 -30.459177017 34.115642548 34.115646362 -30.463253021 -33.946807861 34.937091827 -30.442840576 -33.220714569 35.185966492 -30.460592270 -32.379222870 35.344284058 -30.476007462 -31.456085205 35.430477142 -30.483789444 -30.486968994 35.469234467 -30.486968994 -29.496957779 35.483337402 -30.488048553 -28.499475479 35.487373352 -30.488342285 -27.499938965 35.488258362 -30.488397598 -26.499996185 35.488391876 -30.488403320 -25.500000000 35.488410950 -30.488403320 -24.500000000 35.488410950 -30.488403320 -23.500000000 35.488410950 -30.488403320 -22.500000000 35.488410950 -30.488403320 -21.500000000 35.488410950 -30.488403320 -20.500000000 35.488410950 -30.488403320 -19.500000000 35.488410950 -30.488403320 -18.500000000 35.488410950 -30.488403320 -17.500000000 35.488410950 -30.488403320 -16.500000000 35.488410950 -30.488403320 -15.500000000 35.488410950 -30.488403320 -14.500000000 35.488410950 -30.488403320 -13.500000000 35.488410950 -30.488403320 -12.500000000 35.488410950 -30.488403320 -11.500000000 35.488410950 -30.488403320 -10.500000000 35.488410950 -30.488403320 -9.500000000 35.488410950 -30.488403320 -8.500000000 35.488410950 -30.488403320 -7.500000000 35.488410950 -30.488403320 -6.500000000 35.488410950 -30.488403320 -5.500000000 35.488410950 -30.488403320 -4.500000000 35.488410950 -30.488403320 -3.500000000 35.488410950 -30.488403320 -2.500000000 35.488410950 -30.488403320 -1.500000000 35.488410950 -30.488403320 -0.500000000 35.488410950 -30.488403320 0.500000000 35.488410950 -30.488403320 1.500000000 35.488410950 -30.488403320 2.500000000 35.488410950 -30.488403320 3.500000000 35.488410950 -30.488403320 4.500000000 35.488410950 -30.488403320 5.500000000 35.488410950 -30.488403320 6.500000000 35.488410950 -30.488403320 7.500000000 35.488410950 -30.488403320 8.500000000 35.488410950 -30.488403320 9.500000000 35.488410950 -30.488403320 10.500000000 35.488410950 -30.488403320 11.500000000 35.488410950 -30.488403320 12.500000000 35.488410950 -30.488403320 13.500000000 35.488410950 -30.488403320 14.500000000 35.488410950 -30.488403320 15.500000000 35.488410950 -30.488403320 16.500000000 35.488410950 -30.488403320 17.500000000 35.488410950 -30.488403320 18.500000000 35.488410950 -30.488403320 19.500000000 35.488410950 -30.488403320 20.500000000 35.488410950 -30.488403320 21.500000000 35.488410950 -30.488403320 22.500000000 35.488410950 -30.488403320 23.500000000 35.488410950 -30.488403320 24.500000000 35.488410950 -30.488403320 25.499996185 35.488395691 -30.488403320 26.499938965 35.488258362 -30.488399506 27.499477386 35.487373352 -30.488346100 28.496959686 35.483337402 -30.488052368 29.486968994 35.469234467 -30.486968994 30.456081390 35.430477142 -30.483785629 31.379222870 35.344284058 -30.476007462 32.220714569 35.185966492 -30.460596085 32.946811676 34.937091827 -30.442840576 -33.968864441 -35.965759277 -29.481937408 -33.227874756 -36.217510223 -29.486719131 -32.382308960 -36.371490479 -29.492319107 -31.458078384 -36.450428009 -29.495611191 -30.488048553 -36.483337402 -29.496957779 -29.497375488 -36.494174957 -29.497371674 -28.499578476 -36.496910095 -29.497461319 -27.499954224 -36.497409821 -29.497470856 -26.499996185 -36.497467041 -29.497470856 -25.500000000 -36.497474670 -29.497470856 -24.500000000 -36.497474670 -29.497470856 -23.500000000 -36.497474670 -29.497470856 -22.500000000 -36.497474670 -29.497470856 -21.500000000 -36.497474670 -29.497470856 -20.500000000 -36.497474670 -29.497470856 -19.500000000 -36.497474670 -29.497470856 -18.500000000 -36.497474670 -29.497470856 -17.500000000 -36.497474670 -29.497470856 -16.500000000 -36.497474670 -29.497470856 -15.500000000 -36.497474670 -29.497470856 -14.500000000 -36.497474670 -29.497470856 -13.500000000 -36.497474670 -29.497470856 -12.500000000 -36.497474670 -29.497470856 -11.500000000 -36.497474670 -29.497470856 -10.500000000 -36.497474670 -29.497470856 -9.500000000 -36.497474670 -29.497470856 -8.500000000 -36.497474670 -29.497470856 -7.500000000 -36.497474670 -29.497470856 -6.500000000 -36.497474670 -29.497470856 -5.500000000 -36.497474670 -29.497470856 -4.500000000 -36.497474670 -29.497470856 -3.500000000 -36.497474670 -29.497470856 -2.500000000 -36.497474670 -29.497470856 -1.500000000 -36.497474670 -29.497470856 -0.500000000 -36.497474670 -29.497470856 0.500000000 -36.497474670 -29.497470856 1.500000000 -36.497474670 -29.497470856 2.500000000 -36.497474670 -29.497470856 3.500000000 -36.497474670 -29.497470856 4.500000000 -36.497474670 -29.497470856 5.500000000 -36.497474670 -29.497470856 6.500000000 -36.497474670 -29.497470856 7.500000000 -36.497474670 -29.497470856 8.500000000 -36.497474670 -29.497470856 9.500000000 -36.497474670 -29.497470856 10.500000000 -36.497474670 -29.497470856 11.500000000 -36.497474670 -29.497470856 12.500000000 -36.497474670 -29.497470856 13.500000000 -36.497474670 -29.497470856 14.500000000 -36.497474670 -29.497470856 15.500000000 -36.497474670 -29.497470856 16.500000000 -36.497474670 -29.497470856 17.500000000 -36.497474670 -29.497470856 18.500000000 -36.497474670 -29.497470856 19.500000000 -36.497474670 -29.497470856 20.500000000 -36.497474670 -29.497470856 21.500000000 -36.497474670 -29.497470856 22.500000000 -36.497474670 -29.497470856 23.500000000 -36.497474670 -29.497470856 24.500000000 -36.497474670 -29.497470856 25.499996185 -36.497470856 -29.497470856 26.499954224 -36.497406006 -29.497470856 27.499576569 -36.496910095 -29.497461319 28.497375488 -36.494174957 -29.497375488 29.488048553 -36.483337402 -29.496957779 30.458078384 -36.450428009 -29.495611191 31.382314682 -36.371490479 -29.492319107 32.227874756 -36.217510223 -29.486715317 32.968864441 -35.965759277 -29.481933594 -35.150257111 -35.150249481 -29.487293243 -34.604709625 -35.607204437 -29.485630035 33.604705811 -35.607208252 -29.485630035 34.150257111 -35.150253296 -29.487289429 -35.965759277 -33.968864441 -29.481937408 -35.607208252 -34.604705811 -29.485630035 34.607208252 -34.604709625 -29.485630035 34.965766907 -33.968864441 -29.481937408 -36.217514038 -33.227867126 -29.486715317 35.217514038 -33.227874756 -29.486719131 -36.371490479 -32.382312775 -29.492319107 35.371490479 -32.382308960 -29.492319107 -36.450428009 -31.458074570 -29.495611191 35.450428009 -31.458078384 -29.495611191 -36.483337402 -30.488048553 -29.496957779 35.483337402 -30.488048553 -29.496957779 -36.494171143 -29.497375488 -29.497371674 35.494174957 -29.497375488 -29.497371674 -36.496910095 -28.499578476 -29.497457504 35.496910095 -28.499578476 -29.497461319 -36.497406006 -27.499954224 -29.497470856 35.497409821 -27.499954224 -29.497470856 -36.497467041 -26.499996185 -29.497470856 35.497467041 -26.499996185 -29.497470856 -36.497470856 -25.500000000 -29.497470856 35.497474670 -25.500000000 -29.497470856 -36.497470856 -24.500000000 -29.497470856 35.497474670 -24.500000000 -29.497470856 -36.497470856 -23.500000000 -29.497470856 35.497474670 -23.500000000 -29.497470856 -36.497470856 -22.500000000 -29.497470856 35.497474670 -22.500000000 -29.497470856 -36.497470856 -21.500000000 -29.497470856 35.497474670 -21.500000000 -29.497470856 -36.497470856 -20.500000000 -29.497470856 35.497474670 -20.500000000 -29.497470856 -36.497470856 -19.500000000 -29.497470856 35.497474670 -19.500000000 -29.497470856 -36.497470856 -18.500000000 -29.497470856 35.497474670 -18.500000000 -29.497470856 -36.497470856 -17.500000000 -29.497470856 35.497474670 -17.500000000 -29.497470856 -36.497470856 -16.500000000 -29.497470856 35.497474670 -16.500000000 -29.497470856 -36.497470856 -15.500000000 -29.497470856 35.497474670 -15.500000000 -29.497470856 -36.497470856 -14.500000000 -29.497470856 35.497474670 -14.500000000 -29.497470856 -36.497470856 -13.500000000 -29.497470856 35.497474670 -13.500000000 -29.497470856 -36.497470856 -12.500000000 -29.497470856 35.497474670 -12.500000000 -29.497470856 -36.497470856 -11.500000000 -29.497470856 35.497474670 -11.500000000 -29.497470856 -36.497470856 -10.500000000 -29.497470856 35.497474670 -10.500000000 -29.497470856 -36.497470856 -9.500000000 -29.497470856 35.497474670 -9.500000000 -29.497470856 -36.497470856 -8.500000000 -29.497470856 35.497474670 -8.500000000 -29.497470856 -36.497470856 -7.500000000 -29.497470856 35.497474670 -7.500000000 -29.497470856 -36.497470856 -6.500000000 -29.497470856 35.497474670 -6.500000000 -29.497470856 -36.497470856 -5.500000000 -29.497470856 35.497474670 -5.500000000 -29.497470856 -36.497470856 -4.500000000 -29.497470856 35.497474670 -4.500000000 -29.497470856 -36.497470856 -3.500000000 -29.497470856 35.497474670 -3.500000000 -29.497470856 -36.497470856 -2.500000000 -29.497470856 35.497474670 -2.500000000 -29.497470856 -36.497470856 -1.500000000 -29.497470856 35.497474670 -1.500000000 -29.497470856 -36.497470856 -0.500000000 -29.497470856 35.497474670 -0.500000000 -29.497470856 -36.497470856 0.500000000 -29.497470856 35.497474670 0.500000000 -29.497470856 -36.497470856 1.500000000 -29.497470856 35.497474670 1.500000000 -29.497470856 -36.497470856 2.500000000 -29.497470856 35.497474670 2.500000000 -29.497470856 -36.497470856 3.500000000 -29.497470856 35.497474670 3.500000000 -29.497470856 -36.497470856 4.500000000 -29.497470856 35.497474670 4.500000000 -29.497470856 -36.497470856 5.500000000 -29.497470856 35.497474670 5.500000000 -29.497470856 -36.497470856 6.500000000 -29.497470856 35.497474670 6.500000000 -29.497470856 -36.497470856 7.500000000 -29.497470856 35.497474670 7.500000000 -29.497470856 -36.497470856 8.500000000 -29.497470856 35.497474670 8.500000000 -29.497470856 -36.497470856 9.500000000 -29.497470856 35.497474670 9.500000000 -29.497470856 -36.497470856 10.500000000 -29.497470856 35.497474670 10.500000000 -29.497470856 -36.497470856 11.500000000 -29.497470856 35.497474670 11.500000000 -29.497470856 -36.497470856 12.500000000 -29.497470856 35.497474670 12.500000000 -29.497470856 -36.497470856 13.500000000 -29.497470856 35.497474670 13.500000000 -29.497470856 -36.497470856 14.500000000 -29.497470856 35.497474670 14.500000000 -29.497470856 -36.497470856 15.500000000 -29.497470856 35.497474670 15.500000000 -29.497470856 -36.497470856 16.500000000 -29.497470856 35.497474670 16.500000000 -29.497470856 -36.497470856 17.500000000 -29.497470856 35.497474670 17.500000000 -29.497470856 -36.497470856 18.500000000 -29.497470856 35.497474670 18.500000000 -29.497470856 -36.497470856 19.500000000 -29.497470856 35.497474670 19.500000000 -29.497470856 -36.497470856 20.500000000 -29.497470856 35.497474670 20.500000000 -29.497470856 -36.497470856 21.500000000 -29.497470856 35.497474670 21.500000000 -29.497470856 -36.497470856 22.500000000 -29.497470856 35.497474670 22.500000000 -29.497470856 -36.497470856 23.500000000 -29.497470856 35.497474670 23.500000000 -29.497470856 -36.497470856 24.500000000 -29.497470856 35.497474670 24.500000000 -29.497470856 -36.497467041 25.499996185 -29.497470856 35.497470856 25.499996185 -29.497470856 -36.497409821 26.499954224 -29.497470856 35.497406006 26.499954224 -29.497470856 -36.496910095 27.499576569 -29.497461319 35.496910095 27.499576569 -29.497461319 -36.494174957 28.497371674 -29.497371674 35.494174957 28.497375488 -29.497375488 -36.483337402 29.488048553 -29.496959686 35.483337402 29.488048553 -29.496957779 -36.450428009 30.458074570 -29.495611191 35.450428009 30.458078384 -29.495611191 -36.371490479 31.382312775 -29.492319107 35.371490479 31.382314682 -29.492319107 -36.217514038 32.227874756 -29.486715317 35.217510223 32.227874756 -29.486715317 -35.965759277 32.968864441 -29.481937408 -35.607204437 33.604709625 -29.485630035 34.607208252 33.604709625 -29.485630035 34.965759277 32.968864441 -29.481933594 -35.150249481 34.150257111 -29.487293243 -34.604705811 34.607208252 -29.485630035 33.604709625 34.607208252 -29.485630035 34.150253296 34.150257111 -29.487289429 -33.968864441 34.965759277 -29.481937408 -33.227867126 35.217514038 -29.486715317 -32.382312775 35.371490479 -29.492319107 -31.458074570 35.450428009 -29.495611191 -30.488048553 35.483337402 -29.496957779 -29.497375488 35.494171143 -29.497371674 -28.499578476 35.496910095 -29.497457504 -27.499954224 35.497406006 -29.497470856 -26.499996185 35.497467041 -29.497470856 -25.500000000 35.497470856 -29.497470856 -24.500000000 35.497470856 -29.497470856 -23.500000000 35.497470856 -29.497470856 -22.500000000 35.497470856 -29.497470856 -21.500000000 35.497470856 -29.497470856 -20.500000000 35.497470856 -29.497470856 -19.500000000 35.497470856 -29.497470856 -18.500000000 35.497470856 -29.497470856 -17.500000000 35.497470856 -29.497470856 -16.500000000 35.497470856 -29.497470856 -15.500000000 35.497470856 -29.497470856 -14.500000000 35.497470856 -29.497470856 -13.500000000 35.497470856 -29.497470856 -12.500000000 35.497470856 -29.497470856 -11.500000000 35.497470856 -29.497470856 -10.500000000 35.497470856 -29.497470856 -9.500000000 35.497470856 -29.497470856 -8.500000000 35.497470856 -29.497470856 -7.500000000 35.497470856 -29.497470856 -6.500000000 35.497470856 -29.497470856 -5.500000000 35.497470856 -29.497470856 -4.500000000 35.497470856 -29.497470856 -3.500000000 35.497470856 -29.497470856 -2.500000000 35.497470856 -29.497470856 -1.500000000 35.497470856 -29.497470856 -0.500000000 35.497470856 -29.497470856 0.500000000 35.497470856 -29.497470856 1.500000000 35.497470856 -29.497470856 2.500000000 35.497470856 -29.497470856 3.500000000 35.497470856 -29.497470856 4.500000000 35.497470856 -29.497470856 5.500000000 35.497470856 -29.497470856 6.500000000 35.497470856 -29.497470856 7.500000000 35.497470856 -29.497470856 8.500000000 35.497470856 -29.497470856 9.500000000 35.497470856 -29.497470856 10.500000000 35.497470856 -29.497470856 11.500000000 35.497470856 -29.497470856 12.500000000 35.497470856 -29.497470856 13.500000000 35.497470856 -29.497470856 14.500000000 35.497470856 -29.497470856 15.500000000 35.497470856 -29.497470856 16.500000000 35.497470856 -29.497470856 17.500000000 35.497470856 -29.497470856 18.500000000 35.497470856 -29.497470856 19.500000000 35.497470856 -29.497470856 20.500000000 35.497470856 -29.497470856 21.500000000 35.497470856 -29.497470856 22.500000000 35.497470856 -29.497470856 23.500000000 35.497470856 -29.497470856 24.500000000 35.497470856 -29.497470856 25.499996185 35.497467041 -29.497470856 26.499954224 35.497409821 -29.497470856 27.499576569 35.496910095 -29.497461319 28.497371674 35.494174957 -29.497371674 29.488048553 35.483337402 -29.496959686 30.458074570 35.450428009 -29.495611191 31.382312775 35.371490479 -29.492319107 32.227874756 35.217514038 -29.486719131 32.968864441 34.965766907 -29.481937408 -33.977611542 -35.976860046 -28.495168686 -33.231597900 -36.228954315 -28.496379852 -32.383808136 -36.381023407 -28.498052597 -31.458766937 -36.456939697 -28.499073029 -30.488346100 -36.487373352 -28.499475479 -29.497461319 -36.496910095 -28.499576569 -28.499593735 -36.499164581 -28.499591827 -27.499954224 -36.499546051 -28.499591827 -26.499996185 -36.499588013 -28.499591827 -25.500000000 -36.499591827 -28.499591827 -24.500000000 -36.499591827 -28.499591827 -23.500000000 -36.499591827 -28.499591827 -22.500000000 -36.499591827 -28.499591827 -21.500000000 -36.499591827 -28.499591827 -20.500000000 -36.499591827 -28.499591827 -19.500000000 -36.499591827 -28.499591827 -18.500000000 -36.499591827 -28.499591827 -17.500000000 -36.499591827 -28.499591827 -16.500000000 -36.499591827 -28.499591827 -15.500000000 -36.499591827 -28.499591827 -14.500000000 -36.499591827 -28.499591827 -13.500000000 -36.499591827 -28.499591827 -12.500000000 -36.499591827 -28.499591827 -11.500000000 -36.499591827 -28.499591827 -10.500000000 -36.499591827 -28.499591827 -9.500000000 -36.499591827 -28.499591827 -8.500000000 -36.499591827 -28.499591827 -7.500000000 -36.499591827 -28.499591827 -6.500000000 -36.499591827 -28.499591827 -5.500000000 -36.499591827 -28.499591827 -4.500000000 -36.499591827 -28.499591827 -3.500000000 -36.499591827 -28.499591827 -2.500000000 -36.499591827 -28.499591827 -1.500000000 -36.499591827 -28.499591827 -0.500000000 -36.499591827 -28.499591827 0.500000000 -36.499591827 -28.499591827 1.500000000 -36.499591827 -28.499591827 2.500000000 -36.499591827 -28.499591827 3.500000000 -36.499591827 -28.499591827 4.500000000 -36.499591827 -28.499591827 5.500000000 -36.499591827 -28.499591827 6.500000000 -36.499591827 -28.499591827 7.500000000 -36.499591827 -28.499591827 8.500000000 -36.499591827 -28.499591827 9.500000000 -36.499591827 -28.499591827 10.500000000 -36.499591827 -28.499591827 11.500000000 -36.499591827 -28.499591827 12.500000000 -36.499591827 -28.499591827 13.500000000 -36.499591827 -28.499591827 14.500000000 -36.499591827 -28.499591827 15.500000000 -36.499591827 -28.499591827 16.500000000 -36.499591827 -28.499591827 17.500000000 -36.499591827 -28.499591827 18.500000000 -36.499591827 -28.499591827 19.500000000 -36.499591827 -28.499591827 20.500000000 -36.499591827 -28.499591827 21.500000000 -36.499591827 -28.499591827 22.500000000 -36.499591827 -28.499591827 23.500000000 -36.499591827 -28.499591827 24.500000000 -36.499591827 -28.499591827 25.499996185 -36.499588013 -28.499591827 26.499954224 -36.499542236 -28.499591827 27.499591827 -36.499160767 -28.499591827 28.497461319 -36.496910095 -28.499576569 29.488346100 -36.487377167 -28.499475479 30.458766937 -36.456939697 -28.499073029 31.383810043 -36.381023407 -28.498050690 32.231601715 -36.228954315 -28.496377945 32.977619171 -35.976860046 -28.495168686 -35.163158417 -35.163154602 -28.496557236 -34.617927551 -35.618598938 -28.496026993 33.617927551 -35.618602753 -28.496026993 34.163158417 -35.163158417 -28.496557236 -35.976860046 -33.977611542 -28.495172501 -35.618602753 -34.617927551 -28.496026993 34.618602753 -34.617931366 -28.496026993 34.976860046 -33.977619171 -28.495172501 -36.228954315 -33.231597900 -28.496377945 35.228958130 -33.231601715 -28.496379852 -36.381023407 -32.383808136 -28.498052597 35.381023407 -32.383808136 -28.498052597 -36.456939697 -31.458766937 -28.499073029 35.456939697 -31.458766937 -28.499073029 -36.487373352 -30.488346100 -28.499475479 35.487373352 -30.488346100 -28.499475479 -36.496910095 -29.497461319 -28.499576569 35.496910095 -29.497461319 -28.499576569 -36.499160767 -28.499593735 -28.499591827 35.499164581 -28.499593735 -28.499591827 -36.499546051 -27.499954224 -28.499591827 35.499546051 -27.499954224 -28.499591827 -36.499588013 -26.499996185 -28.499591827 35.499588013 -26.499996185 -28.499591827 -36.499595642 -25.500000000 -28.499591827 35.499591827 -25.500000000 -28.499591827 -36.499595642 -24.500000000 -28.499591827 35.499591827 -24.500000000 -28.499591827 -36.499595642 -23.500000000 -28.499591827 35.499591827 -23.500000000 -28.499591827 -36.499595642 -22.500000000 -28.499591827 35.499591827 -22.500000000 -28.499591827 -36.499595642 -21.500000000 -28.499591827 35.499591827 -21.500000000 -28.499591827 -36.499595642 -20.500000000 -28.499591827 35.499591827 -20.500000000 -28.499591827 -36.499595642 -19.500000000 -28.499591827 35.499591827 -19.500000000 -28.499591827 -36.499595642 -18.500000000 -28.499591827 35.499591827 -18.500000000 -28.499591827 -36.499595642 -17.500000000 -28.499591827 35.499591827 -17.500000000 -28.499591827 -36.499595642 -16.500000000 -28.499591827 35.499591827 -16.500000000 -28.499591827 -36.499595642 -15.500000000 -28.499591827 35.499591827 -15.500000000 -28.499591827 -36.499595642 -14.500000000 -28.499591827 35.499591827 -14.500000000 -28.499591827 -36.499595642 -13.500000000 -28.499591827 35.499591827 -13.500000000 -28.499591827 -36.499595642 -12.500000000 -28.499591827 35.499591827 -12.500000000 -28.499591827 -36.499595642 -11.500000000 -28.499591827 35.499591827 -11.500000000 -28.499591827 -36.499595642 -10.500000000 -28.499591827 35.499591827 -10.500000000 -28.499591827 -36.499595642 -9.500000000 -28.499591827 35.499591827 -9.500000000 -28.499591827 -36.499595642 -8.500000000 -28.499591827 35.499591827 -8.500000000 -28.499591827 -36.499595642 -7.500000000 -28.499591827 35.499591827 -7.500000000 -28.499591827 -36.499595642 -6.500000000 -28.499591827 35.499591827 -6.500000000 -28.499591827 -36.499595642 -5.500000000 -28.499591827 35.499591827 -5.500000000 -28.499591827 -36.499595642 -4.500000000 -28.499591827 35.499591827 -4.500000000 -28.499591827 -36.499595642 -3.500000000 -28.499591827 35.499591827 -3.500000000 -28.499591827 -36.499595642 -2.500000000 -28.499591827 35.499591827 -2.500000000 -28.499591827 -36.499595642 -1.500000000 -28.499591827 35.499591827 -1.500000000 -28.499591827 -36.499595642 -0.500000000 -28.499591827 35.499591827 -0.500000000 -28.499591827 -36.499595642 0.500000000 -28.499591827 35.499591827 0.500000000 -28.499591827 -36.499595642 1.500000000 -28.499591827 35.499591827 1.500000000 -28.499591827 -36.499595642 2.500000000 -28.499591827 35.499591827 2.500000000 -28.499591827 -36.499595642 3.500000000 -28.499591827 35.499591827 3.500000000 -28.499591827 -36.499595642 4.500000000 -28.499591827 35.499591827 4.500000000 -28.499591827 -36.499595642 5.500000000 -28.499591827 35.499591827 5.500000000 -28.499591827 -36.499595642 6.500000000 -28.499591827 35.499591827 6.500000000 -28.499591827 -36.499595642 7.500000000 -28.499591827 35.499591827 7.500000000 -28.499591827 -36.499595642 8.500000000 -28.499591827 35.499591827 8.500000000 -28.499591827 -36.499595642 9.500000000 -28.499591827 35.499591827 9.500000000 -28.499591827 -36.499595642 10.500000000 -28.499591827 35.499591827 10.500000000 -28.499591827 -36.499595642 11.500000000 -28.499591827 35.499591827 11.500000000 -28.499591827 -36.499595642 12.500000000 -28.499591827 35.499591827 12.500000000 -28.499591827 -36.499595642 13.500000000 -28.499591827 35.499591827 13.500000000 -28.499591827 -36.499595642 14.500000000 -28.499591827 35.499591827 14.500000000 -28.499591827 -36.499595642 15.500000000 -28.499591827 35.499591827 15.500000000 -28.499591827 -36.499595642 16.500000000 -28.499591827 35.499591827 16.500000000 -28.499591827 -36.499595642 17.500000000 -28.499591827 35.499591827 17.500000000 -28.499591827 -36.499595642 18.500000000 -28.499591827 35.499591827 18.500000000 -28.499591827 -36.499595642 19.500000000 -28.499591827 35.499591827 19.500000000 -28.499591827 -36.499595642 20.500000000 -28.499591827 35.499591827 20.500000000 -28.499591827 -36.499595642 21.500000000 -28.499591827 35.499591827 21.500000000 -28.499591827 -36.499595642 22.500000000 -28.499591827 35.499591827 22.500000000 -28.499591827 -36.499595642 23.500000000 -28.499591827 35.499591827 23.500000000 -28.499591827 -36.499595642 24.500000000 -28.499591827 35.499591827 24.500000000 -28.499591827 -36.499588013 25.499996185 -28.499591827 35.499588013 25.499996185 -28.499591827 -36.499546051 26.499954224 -28.499591827 35.499542236 26.499954224 -28.499591827 -36.499160767 27.499591827 -28.499591827 35.499160767 27.499591827 -28.499591827 -36.496910095 28.497461319 -28.499576569 35.496910095 28.497461319 -28.499576569 -36.487373352 29.488346100 -28.499475479 35.487377167 29.488346100 -28.499475479 -36.456939697 30.458766937 -28.499073029 35.456939697 30.458766937 -28.499073029 -36.381031036 31.383810043 -28.498050690 35.381023407 31.383810043 -28.498050690 -36.228958130 32.231597900 -28.496377945 35.228954315 32.231601715 -28.496377945 -35.976860046 32.977611542 -28.495168686 -35.618598938 33.617927551 -28.496026993 34.618602753 33.617927551 -28.496026993 34.976860046 32.977619171 -28.495168686 -35.163154602 34.163158417 -28.496557236 -34.617927551 34.618602753 -28.496026993 33.617927551 34.618602753 -28.496026993 34.163158417 34.163158417 -28.496557236 -33.977611542 34.976860046 -28.495172501 -33.231597900 35.228954315 -28.496377945 -32.383808136 35.381023407 -28.498052597 -31.458766937 35.456939697 -28.499073029 -30.488346100 35.487373352 -28.499475479 -29.497461319 35.496910095 -28.499576569 -28.499593735 35.499160767 -28.499591827 -27.499954224 35.499546051 -28.499591827 -26.499996185 35.499588013 -28.499591827 -25.500000000 35.499595642 -28.499591827 -24.500000000 35.499595642 -28.499591827 -23.500000000 35.499595642 -28.499591827 -22.500000000 35.499595642 -28.499591827 -21.500000000 35.499595642 -28.499591827 -20.500000000 35.499595642 -28.499591827 -19.500000000 35.499595642 -28.499591827 -18.500000000 35.499595642 -28.499591827 -17.500000000 35.499595642 -28.499591827 -16.500000000 35.499595642 -28.499591827 -15.500000000 35.499595642 -28.499591827 -14.500000000 35.499595642 -28.499591827 -13.500000000 35.499595642 -28.499591827 -12.500000000 35.499595642 -28.499591827 -11.500000000 35.499595642 -28.499591827 -10.500000000 35.499595642 -28.499591827 -9.500000000 35.499595642 -28.499591827 -8.500000000 35.499595642 -28.499591827 -7.500000000 35.499595642 -28.499591827 -6.500000000 35.499595642 -28.499591827 -5.500000000 35.499595642 -28.499591827 -4.500000000 35.499595642 -28.499591827 -3.500000000 35.499595642 -28.499591827 -2.500000000 35.499595642 -28.499591827 -1.500000000 35.499595642 -28.499591827 -0.500000000 35.499595642 -28.499591827 0.500000000 35.499595642 -28.499591827 1.500000000 35.499595642 -28.499591827 2.500000000 35.499595642 -28.499591827 3.500000000 35.499595642 -28.499591827 4.500000000 35.499595642 -28.499591827 5.500000000 35.499595642 -28.499591827 6.500000000 35.499595642 -28.499591827 7.500000000 35.499595642 -28.499591827 8.500000000 35.499595642 -28.499591827 9.500000000 35.499595642 -28.499591827 10.500000000 35.499595642 -28.499591827 11.500000000 35.499595642 -28.499591827 12.500000000 35.499595642 -28.499591827 13.500000000 35.499595642 -28.499591827 14.500000000 35.499595642 -28.499591827 15.500000000 35.499595642 -28.499591827 16.500000000 35.499595642 -28.499591827 17.500000000 35.499595642 -28.499591827 18.500000000 35.499595642 -28.499591827 19.500000000 35.499595642 -28.499591827 20.500000000 35.499595642 -28.499591827 21.500000000 35.499595642 -28.499591827 22.500000000 35.499595642 -28.499591827 23.500000000 35.499595642 -28.499591827 24.500000000 35.499595642 -28.499591827 25.499996185 35.499588013 -28.499591827 26.499954224 35.499546051 -28.499591827 27.499591827 35.499160767 -28.499591827 28.497461319 35.496910095 -28.499576569 29.488346100 35.487373352 -28.499475479 30.458766937 35.456939697 -28.499073029 31.383810043 35.381031036 -28.498050690 32.231597900 35.228958130 -28.496377945 32.977619171 34.976860046 -28.495172501 -33.980331421 -35.980201721 -27.498950958 -33.232864380 -36.232307434 -27.499221802 -32.384296417 -36.383720398 -27.499622345 -31.458948135 -36.458606720 -27.499858856 -30.488399506 -36.488258362 -27.499938965 -29.497472763 -36.497406006 -27.499954224 -28.499593735 -36.499549866 -27.499954224 -27.499954224 -36.499908447 -27.499954224 -26.499996185 -36.499950409 -27.499954224 -25.500000000 -36.499954224 -27.499954224 -24.500000000 -36.499954224 -27.499954224 -23.500000000 -36.499954224 -27.499954224 -22.500000000 -36.499954224 -27.499954224 -21.500000000 -36.499954224 -27.499954224 -20.500000000 -36.499954224 -27.499954224 -19.500000000 -36.499954224 -27.499954224 -18.500000000 -36.499954224 -27.499954224 -17.500000000 -36.499954224 -27.499954224 -16.500000000 -36.499954224 -27.499954224 -15.500000000 -36.499954224 -27.499954224 -14.500000000 -36.499954224 -27.499954224 -13.500000000 -36.499954224 -27.499954224 -12.500000000 -36.499954224 -27.499954224 -11.500000000 -36.499954224 -27.499954224 -10.500000000 -36.499954224 -27.499954224 -9.500000000 -36.499954224 -27.499954224 -8.500000000 -36.499954224 -27.499954224 -7.500000000 -36.499954224 -27.499954224 -6.500000000 -36.499954224 -27.499954224 -5.500000000 -36.499954224 -27.499954224 -4.500000000 -36.499954224 -27.499954224 -3.500000000 -36.499954224 -27.499954224 -2.500000000 -36.499954224 -27.499954224 -1.500000000 -36.499954224 -27.499954224 -0.500000000 -36.499954224 -27.499954224 0.500000000 -36.499954224 -27.499954224 1.500000000 -36.499954224 -27.499954224 2.500000000 -36.499954224 -27.499954224 3.500000000 -36.499954224 -27.499954224 4.500000000 -36.499954224 -27.499954224 5.500000000 -36.499954224 -27.499954224 6.500000000 -36.499954224 -27.499954224 7.500000000 -36.499954224 -27.499954224 8.500000000 -36.499954224 -27.499954224 9.500000000 -36.499954224 -27.499954224 10.500000000 -36.499954224 -27.499954224 11.500000000 -36.499954224 -27.499954224 12.500000000 -36.499954224 -27.499954224 13.500000000 -36.499954224 -27.499954224 14.500000000 -36.499954224 -27.499954224 15.500000000 -36.499954224 -27.499954224 16.500000000 -36.499954224 -27.499954224 17.500000000 -36.499954224 -27.499954224 18.500000000 -36.499954224 -27.499954224 19.500000000 -36.499954224 -27.499954224 20.500000000 -36.499954224 -27.499954224 21.500000000 -36.499954224 -27.499954224 22.500000000 -36.499954224 -27.499954224 23.500000000 -36.499954224 -27.499954224 24.500000000 -36.499954224 -27.499954224 25.499996185 -36.499950409 -27.499954224 26.499954224 -36.499908447 -27.499954224 27.499591827 -36.499546051 -27.499954224 28.497470856 -36.497413635 -27.499954224 29.488399506 -36.488258362 -27.499938965 30.458948135 -36.458606720 -27.499858856 31.384298325 -36.383720398 -27.499618530 32.232864380 -36.232307434 -27.499225616 32.980331421 -35.980201721 -27.498950958 -35.166961670 -35.166954041 -27.499298096 -34.621795654 -35.621982574 -27.499156952 33.621795654 -35.621982574 -27.499156952 34.166957855 -35.166961670 -27.499298096 -35.980201721 -33.980335236 -27.498950958 -35.621982574 -34.621795654 -27.499156952 34.621982574 -34.621795654 -27.499156952 34.980201721 -33.980331421 -27.498950958 -36.232307434 -33.232864380 -27.499221802 35.232307434 -33.232864380 -27.499221802 -36.383720398 -32.384300232 -27.499622345 35.383720398 -32.384296417 -27.499622345 -36.458606720 -31.458948135 -27.499858856 35.458606720 -31.458948135 -27.499858856 -36.488258362 -30.488399506 -27.499938965 35.488258362 -30.488399506 -27.499938965 -36.497406006 -29.497472763 -27.499954224 35.497406006 -29.497472763 -27.499954224 -36.499546051 -28.499593735 -27.499954224 35.499549866 -28.499593735 -27.499954224 -36.499908447 -27.499954224 -27.499954224 35.499908447 -27.499954224 -27.499954224 -36.499950409 -26.499996185 -27.499954224 35.499950409 -26.499996185 -27.499954224 -36.499954224 -25.500000000 -27.499954224 35.499954224 -25.500000000 -27.499954224 -36.499954224 -24.500000000 -27.499954224 35.499954224 -24.500000000 -27.499954224 -36.499954224 -23.500000000 -27.499954224 35.499954224 -23.500000000 -27.499954224 -36.499954224 -22.500000000 -27.499954224 35.499954224 -22.500000000 -27.499954224 -36.499954224 -21.500000000 -27.499954224 35.499954224 -21.500000000 -27.499954224 -36.499954224 -20.500000000 -27.499954224 35.499954224 -20.500000000 -27.499954224 -36.499954224 -19.500000000 -27.499954224 35.499954224 -19.500000000 -27.499954224 -36.499954224 -18.500000000 -27.499954224 35.499954224 -18.500000000 -27.499954224 -36.499954224 -17.500000000 -27.499954224 35.499954224 -17.500000000 -27.499954224 -36.499954224 -16.500000000 -27.499954224 35.499954224 -16.500000000 -27.499954224 -36.499954224 -15.500000000 -27.499954224 35.499954224 -15.500000000 -27.499954224 -36.499954224 -14.500000000 -27.499954224 35.499954224 -14.500000000 -27.499954224 -36.499954224 -13.500000000 -27.499954224 35.499954224 -13.500000000 -27.499954224 -36.499954224 -12.500000000 -27.499954224 35.499954224 -12.500000000 -27.499954224 -36.499954224 -11.500000000 -27.499954224 35.499954224 -11.500000000 -27.499954224 -36.499954224 -10.500000000 -27.499954224 35.499954224 -10.500000000 -27.499954224 -36.499954224 -9.500000000 -27.499954224 35.499954224 -9.500000000 -27.499954224 -36.499954224 -8.500000000 -27.499954224 35.499954224 -8.500000000 -27.499954224 -36.499954224 -7.500000000 -27.499954224 35.499954224 -7.500000000 -27.499954224 -36.499954224 -6.500000000 -27.499954224 35.499954224 -6.500000000 -27.499954224 -36.499954224 -5.500000000 -27.499954224 35.499954224 -5.500000000 -27.499954224 -36.499954224 -4.500000000 -27.499954224 35.499954224 -4.500000000 -27.499954224 -36.499954224 -3.500000000 -27.499954224 35.499954224 -3.500000000 -27.499954224 -36.499954224 -2.500000000 -27.499954224 35.499954224 -2.500000000 -27.499954224 -36.499954224 -1.500000000 -27.499954224 35.499954224 -1.500000000 -27.499954224 -36.499954224 -0.500000000 -27.499954224 35.499954224 -0.500000000 -27.499954224 -36.499954224 0.500000000 -27.499954224 35.499954224 0.500000000 -27.499954224 -36.499954224 1.500000000 -27.499954224 35.499954224 1.500000000 -27.499954224 -36.499954224 2.500000000 -27.499954224 35.499954224 2.500000000 -27.499954224 -36.499954224 3.500000000 -27.499954224 35.499954224 3.500000000 -27.499954224 -36.499954224 4.500000000 -27.499954224 35.499954224 4.500000000 -27.499954224 -36.499954224 5.500000000 -27.499954224 35.499954224 5.500000000 -27.499954224 -36.499954224 6.500000000 -27.499954224 35.499954224 6.500000000 -27.499954224 -36.499954224 7.500000000 -27.499954224 35.499954224 7.500000000 -27.499954224 -36.499954224 8.500000000 -27.499954224 35.499954224 8.500000000 -27.499954224 -36.499954224 9.500000000 -27.499954224 35.499954224 9.500000000 -27.499954224 -36.499954224 10.500000000 -27.499954224 35.499954224 10.500000000 -27.499954224 -36.499954224 11.500000000 -27.499954224 35.499954224 11.500000000 -27.499954224 -36.499954224 12.500000000 -27.499954224 35.499954224 12.500000000 -27.499954224 -36.499954224 13.500000000 -27.499954224 35.499954224 13.500000000 -27.499954224 -36.499954224 14.500000000 -27.499954224 35.499954224 14.500000000 -27.499954224 -36.499954224 15.500000000 -27.499954224 35.499954224 15.500000000 -27.499954224 -36.499954224 16.500000000 -27.499954224 35.499954224 16.500000000 -27.499954224 -36.499954224 17.500000000 -27.499954224 35.499954224 17.500000000 -27.499954224 -36.499954224 18.500000000 -27.499954224 35.499954224 18.500000000 -27.499954224 -36.499954224 19.500000000 -27.499954224 35.499954224 19.500000000 -27.499954224 -36.499954224 20.500000000 -27.499954224 35.499954224 20.500000000 -27.499954224 -36.499954224 21.500000000 -27.499954224 35.499954224 21.500000000 -27.499954224 -36.499954224 22.500000000 -27.499954224 35.499954224 22.500000000 -27.499954224 -36.499954224 23.500000000 -27.499954224 35.499954224 23.500000000 -27.499954224 -36.499954224 24.500000000 -27.499954224 35.499954224 24.500000000 -27.499954224 -36.499950409 25.499996185 -27.499954224 35.499950409 25.499996185 -27.499954224 -36.499908447 26.499954224 -27.499954224 35.499908447 26.499954224 -27.499954224 -36.499542236 27.499591827 -27.499954224 35.499546051 27.499591827 -27.499954224 -36.497406006 28.497470856 -27.499954224 35.497413635 28.497470856 -27.499954224 -36.488258362 29.488399506 -27.499938965 35.488258362 29.488399506 -27.499938965 -36.458606720 30.458948135 -27.499858856 35.458606720 30.458948135 -27.499858856 -36.383720398 31.384298325 -27.499618530 35.383720398 31.384298325 -27.499618530 -36.232307434 32.232864380 -27.499225616 35.232307434 32.232864380 -27.499225616 -35.980201721 32.980331421 -27.498950958 -35.621982574 33.621795654 -27.499156952 34.621982574 33.621795654 -27.499156952 34.980201721 32.980331421 -27.498950958 -35.166954041 34.166961670 -27.499298096 -34.621795654 34.621982574 -27.499156952 33.621795654 34.621982574 -27.499156952 34.166961670 34.166957855 -27.499298096 -33.980335236 34.980201721 -27.498950958 -33.232864380 35.232307434 -27.499221802 -32.384300232 35.383720398 -27.499622345 -31.458948135 35.458606720 -27.499858856 -30.488399506 35.488258362 -27.499938965 -29.497472763 35.497406006 -27.499954224 -28.499593735 35.499546051 -27.499954224 -27.499954224 35.499908447 -27.499954224 -26.499996185 35.499950409 -27.499954224 -25.500000000 35.499954224 -27.499954224 -24.500000000 35.499954224 -27.499954224 -23.500000000 35.499954224 -27.499954224 -22.500000000 35.499954224 -27.499954224 -21.500000000 35.499954224 -27.499954224 -20.500000000 35.499954224 -27.499954224 -19.500000000 35.499954224 -27.499954224 -18.500000000 35.499954224 -27.499954224 -17.500000000 35.499954224 -27.499954224 -16.500000000 35.499954224 -27.499954224 -15.500000000 35.499954224 -27.499954224 -14.500000000 35.499954224 -27.499954224 -13.500000000 35.499954224 -27.499954224 -12.500000000 35.499954224 -27.499954224 -11.500000000 35.499954224 -27.499954224 -10.500000000 35.499954224 -27.499954224 -9.500000000 35.499954224 -27.499954224 -8.500000000 35.499954224 -27.499954224 -7.500000000 35.499954224 -27.499954224 -6.500000000 35.499954224 -27.499954224 -5.500000000 35.499954224 -27.499954224 -4.500000000 35.499954224 -27.499954224 -3.500000000 35.499954224 -27.499954224 -2.500000000 35.499954224 -27.499954224 -1.500000000 35.499954224 -27.499954224 -0.500000000 35.499954224 -27.499954224 0.500000000 35.499954224 -27.499954224 1.500000000 35.499954224 -27.499954224 2.500000000 35.499954224 -27.499954224 3.500000000 35.499954224 -27.499954224 4.500000000 35.499954224 -27.499954224 5.500000000 35.499954224 -27.499954224 6.500000000 35.499954224 -27.499954224 7.500000000 35.499954224 -27.499954224 8.500000000 35.499954224 -27.499954224 9.500000000 35.499954224 -27.499954224 10.500000000 35.499954224 -27.499954224 11.500000000 35.499954224 -27.499954224 12.500000000 35.499954224 -27.499954224 13.500000000 35.499954224 -27.499954224 14.500000000 35.499954224 -27.499954224 15.500000000 35.499954224 -27.499954224 16.500000000 35.499954224 -27.499954224 17.500000000 35.499954224 -27.499954224 18.500000000 35.499954224 -27.499954224 19.500000000 35.499954224 -27.499954224 20.500000000 35.499954224 -27.499954224 21.500000000 35.499954224 -27.499954224 22.500000000 35.499954224 -27.499954224 23.500000000 35.499954224 -27.499954224 24.500000000 35.499954224 -27.499954224 25.499996185 35.499950409 -27.499954224 26.499954224 35.499908447 -27.499954224 27.499591827 35.499542236 -27.499954224 28.497470856 35.497406006 -27.499954224 29.488399506 35.488258362 -27.499938965 30.458948135 35.458606720 -27.499858856 31.384298325 35.383720398 -27.499618530 32.232864380 35.232307434 -27.499225616 32.980327606 34.980201721 -27.498950958 -33.980976105 -35.980957031 -26.499826431 -33.233165741 -36.233070374 -26.499872208 -32.384403229 -36.384307861 -26.499948502 -31.458978653 -36.458930969 -26.499988556 -30.488407135 -36.488384247 -26.499996185 -29.497472763 -36.497467041 -26.499996185 -28.499593735 -36.499591827 -26.499996185 -27.499954224 -36.499950409 -26.499996185 -26.499996185 -36.499992371 -26.499996185 -25.500000000 -36.499996185 -26.499996185 -24.500000000 -36.499996185 -26.499996185 -23.500000000 -36.499996185 -26.499996185 -22.500000000 -36.499996185 -26.499996185 -21.500000000 -36.499996185 -26.499996185 -20.500000000 -36.499996185 -26.499996185 -19.500000000 -36.499996185 -26.499996185 -18.500000000 -36.499996185 -26.499996185 -17.500000000 -36.499996185 -26.499996185 -16.500000000 -36.499996185 -26.499996185 -15.500000000 -36.499996185 -26.499996185 -14.500000000 -36.499996185 -26.499996185 -13.500000000 -36.499996185 -26.499996185 -12.500000000 -36.499996185 -26.499996185 -11.500000000 -36.499996185 -26.499996185 -10.500000000 -36.499996185 -26.499996185 -9.500000000 -36.499996185 -26.499996185 -8.500000000 -36.499996185 -26.499996185 -7.500000000 -36.499996185 -26.499996185 -6.500000000 -36.499996185 -26.499996185 -5.500000000 -36.499996185 -26.499996185 -4.500000000 -36.499996185 -26.499996185 -3.500000000 -36.499996185 -26.499996185 -2.500000000 -36.499996185 -26.499996185 -1.500000000 -36.499996185 -26.499996185 -0.500000000 -36.499996185 -26.499996185 0.500000000 -36.499996185 -26.499996185 1.500000000 -36.499996185 -26.499996185 2.500000000 -36.499996185 -26.499996185 3.500000000 -36.499996185 -26.499996185 4.500000000 -36.499996185 -26.499996185 5.500000000 -36.499996185 -26.499996185 6.500000000 -36.499996185 -26.499996185 7.500000000 -36.499996185 -26.499996185 8.500000000 -36.499996185 -26.499996185 9.500000000 -36.499996185 -26.499996185 10.500000000 -36.499996185 -26.499996185 11.500000000 -36.499996185 -26.499996185 12.500000000 -36.499996185 -26.499996185 13.500000000 -36.499996185 -26.499996185 14.500000000 -36.499996185 -26.499996185 15.500000000 -36.499996185 -26.499996185 16.500000000 -36.499996185 -26.499996185 17.500000000 -36.499996185 -26.499996185 18.500000000 -36.499996185 -26.499996185 19.500000000 -36.499996185 -26.499996185 20.500000000 -36.499996185 -26.499996185 21.500000000 -36.499996185 -26.499996185 22.500000000 -36.499996185 -26.499996185 23.500000000 -36.499996185 -26.499996185 24.500000000 -36.499996185 -26.499996185 25.499996185 -36.499992371 -26.499996185 26.499954224 -36.499950409 -26.499996185 27.499591827 -36.499591827 -26.499996185 28.497470856 -36.497467041 -26.499996185 29.488407135 -36.488391876 -26.499996185 30.458978653 -36.458934784 -26.499988556 31.384403229 -36.384307861 -26.499948502 32.233165741 -36.233070374 -26.499872208 32.980972290 -35.980960846 -26.499826431 -35.167808533 -35.167808533 -26.499902725 -34.622692108 -35.622734070 -26.499868393 33.622695923 -35.622734070 -26.499868393 34.167808533 -35.167808533 -26.499902725 -35.980957031 -33.980976105 -26.499822617 -35.622734070 -34.622692108 -26.499868393 34.622734070 -34.622692108 -26.499868393 34.980957031 -33.980976105 -26.499822617 -36.233070374 -33.233165741 -26.499874115 35.233070374 -33.233165741 -26.499872208 -36.384307861 -32.384403229 -26.499948502 35.384307861 -32.384403229 -26.499948502 -36.458930969 -31.458978653 -26.499988556 35.458930969 -31.458978653 -26.499988556 -36.488391876 -30.488407135 -26.499996185 35.488384247 -30.488407135 -26.499996185 -36.497467041 -29.497472763 -26.499996185 35.497467041 -29.497472763 -26.499996185 -36.499588013 -28.499593735 -26.499996185 35.499591827 -28.499593735 -26.499996185 -36.499950409 -27.499954224 -26.499996185 35.499950409 -27.499954224 -26.499996185 -36.499992371 -26.499996185 -26.499996185 35.499992371 -26.499996185 -26.499996185 -36.499996185 -25.500000000 -26.499996185 35.499996185 -25.500000000 -26.499996185 -36.499996185 -24.500000000 -26.499996185 35.499996185 -24.500000000 -26.499996185 -36.499996185 -23.500000000 -26.499996185 35.499996185 -23.500000000 -26.499996185 -36.499996185 -22.500000000 -26.499996185 35.499996185 -22.500000000 -26.499996185 -36.499996185 -21.500000000 -26.499996185 35.499996185 -21.500000000 -26.499996185 -36.499996185 -20.500000000 -26.499996185 35.499996185 -20.500000000 -26.499996185 -36.499996185 -19.500000000 -26.499996185 35.499996185 -19.500000000 -26.499996185 -36.499996185 -18.500000000 -26.499996185 35.499996185 -18.500000000 -26.499996185 -36.499996185 -17.500000000 -26.499996185 35.499996185 -17.500000000 -26.499996185 -36.499996185 -16.500000000 -26.499996185 35.499996185 -16.500000000 -26.499996185 -36.499996185 -15.500000000 -26.499996185 35.499996185 -15.500000000 -26.499996185 -36.499996185 -14.500000000 -26.499996185 35.499996185 -14.500000000 -26.499996185 -36.499996185 -13.500000000 -26.499996185 35.499996185 -13.500000000 -26.499996185 -36.499996185 -12.500000000 -26.499996185 35.499996185 -12.500000000 -26.499996185 -36.499996185 -11.500000000 -26.499996185 35.499996185 -11.500000000 -26.499996185 -36.499996185 -10.500000000 -26.499996185 35.499996185 -10.500000000 -26.499996185 -36.499996185 -9.500000000 -26.499996185 35.499996185 -9.500000000 -26.499996185 -36.499996185 -8.500000000 -26.499996185 35.499996185 -8.500000000 -26.499996185 -36.499996185 -7.500000000 -26.499996185 35.499996185 -7.500000000 -26.499996185 -36.499996185 -6.500000000 -26.499996185 35.499996185 -6.500000000 -26.499996185 -36.499996185 -5.500000000 -26.499996185 35.499996185 -5.500000000 -26.499996185 -36.499996185 -4.500000000 -26.499996185 35.499996185 -4.500000000 -26.499996185 -36.499996185 -3.500000000 -26.499996185 35.499996185 -3.500000000 -26.499996185 -36.499996185 -2.500000000 -26.499996185 35.499996185 -2.500000000 -26.499996185 -36.499996185 -1.500000000 -26.499996185 35.499996185 -1.500000000 -26.499996185 -36.499996185 -0.500000000 -26.499996185 35.499996185 -0.500000000 -26.499996185 -36.499996185 0.500000000 -26.499996185 35.499996185 0.500000000 -26.499996185 -36.499996185 1.500000000 -26.499996185 35.499996185 1.500000000 -26.499996185 -36.499996185 2.500000000 -26.499996185 35.499996185 2.500000000 -26.499996185 -36.499996185 3.500000000 -26.499996185 35.499996185 3.500000000 -26.499996185 -36.499996185 4.500000000 -26.499996185 35.499996185 4.500000000 -26.499996185 -36.499996185 5.500000000 -26.499996185 35.499996185 5.500000000 -26.499996185 -36.499996185 6.500000000 -26.499996185 35.499996185 6.500000000 -26.499996185 -36.499996185 7.500000000 -26.499996185 35.499996185 7.500000000 -26.499996185 -36.499996185 8.500000000 -26.499996185 35.499996185 8.500000000 -26.499996185 -36.499996185 9.500000000 -26.499996185 35.499996185 9.500000000 -26.499996185 -36.499996185 10.500000000 -26.499996185 35.499996185 10.500000000 -26.499996185 -36.499996185 11.500000000 -26.499996185 35.499996185 11.500000000 -26.499996185 -36.499996185 12.500000000 -26.499996185 35.499996185 12.500000000 -26.499996185 -36.499996185 13.500000000 -26.499996185 35.499996185 13.500000000 -26.499996185 -36.499996185 14.500000000 -26.499996185 35.499996185 14.500000000 -26.499996185 -36.499996185 15.500000000 -26.499996185 35.499996185 15.500000000 -26.499996185 -36.499996185 16.500000000 -26.499996185 35.499996185 16.500000000 -26.499996185 -36.499996185 17.500000000 -26.499996185 35.499996185 17.500000000 -26.499996185 -36.499996185 18.500000000 -26.499996185 35.499996185 18.500000000 -26.499996185 -36.499996185 19.500000000 -26.499996185 35.499996185 19.500000000 -26.499996185 -36.499996185 20.500000000 -26.499996185 35.499996185 20.500000000 -26.499996185 -36.499996185 21.500000000 -26.499996185 35.499996185 21.500000000 -26.499996185 -36.499996185 22.500000000 -26.499996185 35.499996185 22.500000000 -26.499996185 -36.499996185 23.500000000 -26.499996185 35.499996185 23.500000000 -26.499996185 -36.499996185 24.500000000 -26.499996185 35.499996185 24.500000000 -26.499996185 -36.499992371 25.499996185 -26.499996185 35.499992371 25.499996185 -26.499996185 -36.499950409 26.499954224 -26.499996185 35.499950409 26.499954224 -26.499996185 -36.499588013 27.499591827 -26.499996185 35.499591827 27.499591827 -26.499996185 -36.497467041 28.497470856 -26.499996185 35.497467041 28.497470856 -26.499996185 -36.488391876 29.488407135 -26.499996185 35.488391876 29.488407135 -26.499996185 -36.458930969 30.458978653 -26.499988556 35.458934784 30.458978653 -26.499988556 -36.384307861 31.384403229 -26.499948502 35.384307861 31.384403229 -26.499948502 -36.233070374 32.233165741 -26.499874115 35.233070374 32.233165741 -26.499872208 -35.980957031 32.980976105 -26.499826431 -35.622734070 33.622692108 -26.499868393 34.622734070 33.622695923 -26.499868393 34.980960846 32.980972290 -26.499826431 -35.167808533 34.167808533 -26.499902725 -34.622692108 34.622734070 -26.499868393 33.622692108 34.622734070 -26.499868393 34.167808533 34.167808533 -26.499902725 -33.980976105 34.980957031 -26.499822617 -33.233165741 35.233070374 -26.499874115 -32.384403229 35.384307861 -26.499948502 -31.458978653 35.458930969 -26.499988556 -30.488407135 35.488391876 -26.499996185 -29.497472763 35.497467041 -26.499996185 -28.499593735 35.499588013 -26.499996185 -27.499954224 35.499950409 -26.499996185 -26.499996185 35.499992371 -26.499996185 -25.500000000 35.499996185 -26.499996185 -24.500000000 35.499996185 -26.499996185 -23.500000000 35.499996185 -26.499996185 -22.500000000 35.499996185 -26.499996185 -21.500000000 35.499996185 -26.499996185 -20.500000000 35.499996185 -26.499996185 -19.500000000 35.499996185 -26.499996185 -18.500000000 35.499996185 -26.499996185 -17.500000000 35.499996185 -26.499996185 -16.500000000 35.499996185 -26.499996185 -15.500000000 35.499996185 -26.499996185 -14.500000000 35.499996185 -26.499996185 -13.500000000 35.499996185 -26.499996185 -12.500000000 35.499996185 -26.499996185 -11.500000000 35.499996185 -26.499996185 -10.500000000 35.499996185 -26.499996185 -9.500000000 35.499996185 -26.499996185 -8.500000000 35.499996185 -26.499996185 -7.500000000 35.499996185 -26.499996185 -6.500000000 35.499996185 -26.499996185 -5.500000000 35.499996185 -26.499996185 -4.500000000 35.499996185 -26.499996185 -3.500000000 35.499996185 -26.499996185 -2.500000000 35.499996185 -26.499996185 -1.500000000 35.499996185 -26.499996185 -0.500000000 35.499996185 -26.499996185 0.500000000 35.499996185 -26.499996185 1.500000000 35.499996185 -26.499996185 2.500000000 35.499996185 -26.499996185 3.500000000 35.499996185 -26.499996185 4.500000000 35.499996185 -26.499996185 5.500000000 35.499996185 -26.499996185 6.500000000 35.499996185 -26.499996185 7.500000000 35.499996185 -26.499996185 8.500000000 35.499996185 -26.499996185 9.500000000 35.499996185 -26.499996185 10.500000000 35.499996185 -26.499996185 11.500000000 35.499996185 -26.499996185 12.500000000 35.499996185 -26.499996185 13.500000000 35.499996185 -26.499996185 14.500000000 35.499996185 -26.499996185 15.500000000 35.499996185 -26.499996185 16.500000000 35.499996185 -26.499996185 17.500000000 35.499996185 -26.499996185 18.500000000 35.499996185 -26.499996185 19.500000000 35.499996185 -26.499996185 20.500000000 35.499996185 -26.499996185 21.500000000 35.499996185 -26.499996185 22.500000000 35.499996185 -26.499996185 23.500000000 35.499996185 -26.499996185 24.500000000 35.499996185 -26.499996185 25.499996185 35.499992371 -26.499996185 26.499954224 35.499950409 -26.499996185 27.499591827 35.499588013 -26.499996185 28.497470856 35.497467041 -26.499996185 29.488407135 35.488391876 -26.499996185 30.458978653 35.458930969 -26.499988556 31.384403229 35.384307861 -26.499948502 32.233165741 35.233070374 -26.499874115 32.980976105 34.980957031 -26.499822617 -33.981086731 -35.981086731 -25.499979019 -33.233215332 -36.233203888 -25.499984741 -32.384422302 -36.384407043 -25.499996185 -31.458978653 -36.458976746 -25.500000000 -30.488407135 -36.488403320 -25.500000000 -29.497472763 -36.497474670 -25.500000000 -28.499593735 -36.499591827 -25.500000000 -27.499954224 -36.499954224 -25.500000000 -26.499996185 -36.499996185 -25.500000000 -25.500000000 -36.500000000 -25.500000000 -24.500000000 -36.500000000 -25.500000000 -23.500000000 -36.500000000 -25.500000000 -22.500000000 -36.500000000 -25.500000000 -21.500000000 -36.500000000 -25.500000000 -20.500000000 -36.500000000 -25.500000000 -19.500000000 -36.500000000 -25.500000000 -18.500000000 -36.500000000 -25.500000000 -17.500000000 -36.500000000 -25.500000000 -16.500000000 -36.500000000 -25.500000000 -15.500000000 -36.500000000 -25.500000000 -14.500000000 -36.500000000 -25.500000000 -13.500000000 -36.500000000 -25.500000000 -12.500000000 -36.500000000 -25.500000000 -11.500000000 -36.500000000 -25.500000000 -10.500000000 -36.500000000 -25.500000000 -9.500000000 -36.500000000 -25.500000000 -8.500000000 -36.500000000 -25.500000000 -7.500000000 -36.500000000 -25.500000000 -6.500000000 -36.500000000 -25.500000000 -5.500000000 -36.500000000 -25.500000000 -4.500000000 -36.500000000 -25.500000000 -3.500000000 -36.500000000 -25.500000000 -2.500000000 -36.500000000 -25.500000000 -1.500000000 -36.500000000 -25.500000000 -0.500000000 -36.500000000 -25.500000000 0.500000000 -36.500000000 -25.500000000 1.500000000 -36.500000000 -25.500000000 2.500000000 -36.500000000 -25.500000000 3.500000000 -36.500000000 -25.500000000 4.500000000 -36.500000000 -25.500000000 5.500000000 -36.500000000 -25.500000000 6.500000000 -36.500000000 -25.500000000 7.500000000 -36.500000000 -25.500000000 8.500000000 -36.500000000 -25.500000000 9.500000000 -36.500000000 -25.500000000 10.500000000 -36.500000000 -25.500000000 11.500000000 -36.500000000 -25.500000000 12.500000000 -36.500000000 -25.500000000 13.500000000 -36.500000000 -25.500000000 14.500000000 -36.500000000 -25.500000000 15.500000000 -36.500000000 -25.500000000 16.500000000 -36.500000000 -25.500000000 17.500000000 -36.500000000 -25.500000000 18.500000000 -36.500000000 -25.500000000 19.500000000 -36.500000000 -25.500000000 20.500000000 -36.500000000 -25.500000000 21.500000000 -36.500000000 -25.500000000 22.500000000 -36.500000000 -25.500000000 23.500000000 -36.500000000 -25.500000000 24.500000000 -36.500000000 -25.500000000 25.499996185 -36.499996185 -25.500000000 26.499954224 -36.499954224 -25.500000000 27.499591827 -36.499591827 -25.500000000 28.497470856 -36.497467041 -25.500000000 29.488407135 -36.488403320 -25.500000000 30.458978653 -36.458976746 -25.500000000 31.384418488 -36.384407043 -25.499996185 32.233215332 -36.233203888 -25.499986649 32.981086731 -35.981086731 -25.499979019 -35.167949677 -35.167945862 -25.499990463 -34.622844696 -35.622852325 -25.499986649 33.622844696 -35.622852325 -25.499986649 34.167949677 -35.167949677 -25.499990463 -35.981086731 -33.981086731 -25.499977112 -35.622852325 -34.622844696 -25.499986649 34.622856140 -34.622844696 -25.499986649 34.981086731 -33.981086731 -25.499979019 -36.233203888 -33.233215332 -25.499986649 35.233203888 -33.233222961 -25.499984741 -36.384407043 -32.384422302 -25.499996185 35.384407043 -32.384422302 -25.499996185 -36.458972931 -31.458978653 -25.500000000 35.458976746 -31.458978653 -25.500000000 -36.488403320 -30.488407135 -25.500000000 35.488403320 -30.488407135 -25.500000000 -36.497467041 -29.497472763 -25.500000000 35.497474670 -29.497472763 -25.500000000 -36.499591827 -28.499593735 -25.500000000 35.499591827 -28.499593735 -25.500000000 -36.499954224 -27.499954224 -25.500000000 35.499954224 -27.499954224 -25.500000000 -36.499996185 -26.499996185 -25.500000000 35.499996185 -26.499996185 -25.500000000 -36.500000000 -25.500000000 -25.500000000 35.500000000 -25.500000000 -25.500000000 -36.500000000 -24.500000000 -25.500000000 35.500000000 -24.500000000 -25.500000000 -36.500000000 -23.500000000 -25.500000000 35.500000000 -23.500000000 -25.500000000 -36.500000000 -22.500000000 -25.500000000 35.500000000 -22.500000000 -25.500000000 -36.500000000 -21.500000000 -25.500000000 35.500000000 -21.500000000 -25.500000000 -36.500000000 -20.500000000 -25.500000000 35.500000000 -20.500000000 -25.500000000 -36.500000000 -19.500000000 -25.500000000 35.500000000 -19.500000000 -25.500000000 -36.500000000 -18.500000000 -25.500000000 35.500000000 -18.500000000 -25.500000000 -36.500000000 -17.500000000 -25.500000000 35.500000000 -17.500000000 -25.500000000 -36.500000000 -16.500000000 -25.500000000 35.500000000 -16.500000000 -25.500000000 -36.500000000 -15.500000000 -25.500000000 35.500000000 -15.500000000 -25.500000000 -36.500000000 -14.500000000 -25.500000000 35.500000000 -14.500000000 -25.500000000 -36.500000000 -13.500000000 -25.500000000 35.500000000 -13.500000000 -25.500000000 -36.500000000 -12.500000000 -25.500000000 35.500000000 -12.500000000 -25.500000000 -36.500000000 -11.500000000 -25.500000000 35.500000000 -11.500000000 -25.500000000 -36.500000000 -10.500000000 -25.500000000 35.500000000 -10.500000000 -25.500000000 -36.500000000 -9.500000000 -25.500000000 35.500000000 -9.500000000 -25.500000000 -36.500000000 -8.500000000 -25.500000000 35.500000000 -8.500000000 -25.500000000 -36.500000000 -7.500000000 -25.500000000 35.500000000 -7.500000000 -25.500000000 -36.500000000 -6.500000000 -25.500000000 35.500000000 -6.500000000 -25.500000000 -36.500000000 -5.500000000 -25.500000000 35.500000000 -5.500000000 -25.500000000 -36.500000000 -4.500000000 -25.500000000 35.500000000 -4.500000000 -25.500000000 -36.500000000 -3.500000000 -25.500000000 35.500000000 -3.500000000 -25.500000000 -36.500000000 -2.500000000 -25.500000000 35.500000000 -2.500000000 -25.500000000 -36.500000000 -1.500000000 -25.500000000 35.500000000 -1.500000000 -25.500000000 -36.500000000 -0.500000000 -25.500000000 35.500000000 -0.500000000 -25.500000000 -36.500000000 0.500000000 -25.500000000 35.500000000 0.500000000 -25.500000000 -36.500000000 1.500000000 -25.500000000 35.500000000 1.500000000 -25.500000000 -36.500000000 2.500000000 -25.500000000 35.500000000 2.500000000 -25.500000000 -36.500000000 3.500000000 -25.500000000 35.500000000 3.500000000 -25.500000000 -36.500000000 4.500000000 -25.500000000 35.500000000 4.500000000 -25.500000000 -36.500000000 5.500000000 -25.500000000 35.500000000 5.500000000 -25.500000000 -36.500000000 6.500000000 -25.500000000 35.500000000 6.500000000 -25.500000000 -36.500000000 7.500000000 -25.500000000 35.500000000 7.500000000 -25.500000000 -36.500000000 8.500000000 -25.500000000 35.500000000 8.500000000 -25.500000000 -36.500000000 9.500000000 -25.500000000 35.500000000 9.500000000 -25.500000000 -36.500000000 10.500000000 -25.500000000 35.500000000 10.500000000 -25.500000000 -36.500000000 11.500000000 -25.500000000 35.500000000 11.500000000 -25.500000000 -36.500000000 12.500000000 -25.500000000 35.500000000 12.500000000 -25.500000000 -36.500000000 13.500000000 -25.500000000 35.500000000 13.500000000 -25.500000000 -36.500000000 14.500000000 -25.500000000 35.500000000 14.500000000 -25.500000000 -36.500000000 15.500000000 -25.500000000 35.500000000 15.500000000 -25.500000000 -36.500000000 16.500000000 -25.500000000 35.500000000 16.500000000 -25.500000000 -36.500000000 17.500000000 -25.500000000 35.500000000 17.500000000 -25.500000000 -36.500000000 18.500000000 -25.500000000 35.500000000 18.500000000 -25.500000000 -36.500000000 19.500000000 -25.500000000 35.500000000 19.500000000 -25.500000000 -36.500000000 20.500000000 -25.500000000 35.500000000 20.500000000 -25.500000000 -36.500000000 21.500000000 -25.500000000 35.500000000 21.500000000 -25.500000000 -36.500000000 22.500000000 -25.500000000 35.500000000 22.500000000 -25.500000000 -36.500000000 23.500000000 -25.500000000 35.500000000 23.500000000 -25.500000000 -36.500000000 24.500000000 -25.500000000 35.500000000 24.500000000 -25.500000000 -36.499996185 25.499996185 -25.500000000 35.499996185 25.499996185 -25.500000000 -36.499954224 26.499954224 -25.500000000 35.499954224 26.499954224 -25.500000000 -36.499591827 27.499591827 -25.500000000 35.499591827 27.499591827 -25.500000000 -36.497474670 28.497470856 -25.500000000 35.497467041 28.497470856 -25.500000000 -36.488403320 29.488407135 -25.500000000 35.488403320 29.488407135 -25.500000000 -36.458976746 30.458978653 -25.500000000 35.458976746 30.458978653 -25.500000000 -36.384407043 31.384418488 -25.499996185 35.384407043 31.384418488 -25.499996185 -36.233203888 32.233215332 -25.499986649 35.233203888 32.233215332 -25.499986649 -35.981086731 32.981086731 -25.499975204 -35.622852325 33.622844696 -25.499986649 34.622852325 33.622844696 -25.499986649 34.981086731 32.981086731 -25.499979019 -35.167945862 34.167949677 -25.499990463 -34.622844696 34.622852325 -25.499986649 33.622844696 34.622852325 -25.499986649 34.167949677 34.167949677 -25.499990463 -33.981086731 34.981086731 -25.499977112 -33.233215332 35.233203888 -25.499986649 -32.384422302 35.384407043 -25.499996185 -31.458978653 35.458972931 -25.500000000 -30.488407135 35.488403320 -25.500000000 -29.497472763 35.497467041 -25.500000000 -28.499593735 35.499591827 -25.500000000 -27.499954224 35.499954224 -25.500000000 -26.499996185 35.499996185 -25.500000000 -25.500000000 35.500000000 -25.500000000 -24.500000000 35.500000000 -25.500000000 -23.500000000 35.500000000 -25.500000000 -22.500000000 35.500000000 -25.500000000 -21.500000000 35.500000000 -25.500000000 -20.500000000 35.500000000 -25.500000000 -19.500000000 35.500000000 -25.500000000 -18.500000000 35.500000000 -25.500000000 -17.500000000 35.500000000 -25.500000000 -16.500000000 35.500000000 -25.500000000 -15.500000000 35.500000000 -25.500000000 -14.500000000 35.500000000 -25.500000000 -13.500000000 35.500000000 -25.500000000 -12.500000000 35.500000000 -25.500000000 -11.500000000 35.500000000 -25.500000000 -10.500000000 35.500000000 -25.500000000 -9.500000000 35.500000000 -25.500000000 -8.500000000 35.500000000 -25.500000000 -7.500000000 35.500000000 -25.500000000 -6.500000000 35.500000000 -25.500000000 -5.500000000 35.500000000 -25.500000000 -4.500000000 35.500000000 -25.500000000 -3.500000000 35.500000000 -25.500000000 -2.500000000 35.500000000 -25.500000000 -1.500000000 35.500000000 -25.500000000 -0.500000000 35.500000000 -25.500000000 0.500000000 35.500000000 -25.500000000 1.500000000 35.500000000 -25.500000000 2.500000000 35.500000000 -25.500000000 3.500000000 35.500000000 -25.500000000 4.500000000 35.500000000 -25.500000000 5.500000000 35.500000000 -25.500000000 6.500000000 35.500000000 -25.500000000 7.500000000 35.500000000 -25.500000000 8.500000000 35.500000000 -25.500000000 9.500000000 35.500000000 -25.500000000 10.500000000 35.500000000 -25.500000000 11.500000000 35.500000000 -25.500000000 12.500000000 35.500000000 -25.500000000 13.500000000 35.500000000 -25.500000000 14.500000000 35.500000000 -25.500000000 15.500000000 35.500000000 -25.500000000 16.500000000 35.500000000 -25.500000000 17.500000000 35.500000000 -25.500000000 18.500000000 35.500000000 -25.500000000 19.500000000 35.500000000 -25.500000000 20.500000000 35.500000000 -25.500000000 21.500000000 35.500000000 -25.500000000 22.500000000 35.500000000 -25.500000000 23.500000000 35.500000000 -25.500000000 24.500000000 35.500000000 -25.500000000 25.499996185 35.499996185 -25.500000000 26.499954224 35.499954224 -25.500000000 27.499591827 35.499591827 -25.500000000 28.497470856 35.497474670 -25.500000000 29.488407135 35.488403320 -25.500000000 30.458978653 35.458976746 -25.500000000 31.384418488 35.384407043 -25.499996185 32.233215332 35.233203888 -25.499986649 32.981086731 34.981086731 -25.499977112 -33.981101990 -35.981101990 -24.499998093 -33.233226776 -36.233222961 -24.500000000 -32.384422302 -36.384418488 -24.500000000 -31.458978653 -36.458980560 -24.500000000 -30.488407135 -36.488403320 -24.500000000 -29.497472763 -36.497474670 -24.500000000 -28.499593735 -36.499591827 -24.500000000 -27.499954224 -36.499954224 -24.500000000 -26.499996185 -36.499996185 -24.500000000 -25.500000000 -36.500000000 -24.500000000 -24.500000000 -36.500000000 -24.500000000 -23.500000000 -36.500000000 -24.500000000 -22.500000000 -36.500000000 -24.500000000 -21.500000000 -36.500000000 -24.500000000 -20.500000000 -36.500000000 -24.500000000 -19.500000000 -36.500000000 -24.500000000 -18.500000000 -36.500000000 -24.500000000 -17.500000000 -36.500000000 -24.500000000 -16.500000000 -36.500000000 -24.500000000 -15.500000000 -36.500000000 -24.500000000 -14.500000000 -36.500000000 -24.500000000 -13.500000000 -36.500000000 -24.500000000 -12.500000000 -36.500000000 -24.500000000 -11.500000000 -36.500000000 -24.500000000 -10.500000000 -36.500000000 -24.500000000 -9.500000000 -36.500000000 -24.500000000 -8.500000000 -36.500000000 -24.500000000 -7.500000000 -36.500000000 -24.500000000 -6.500000000 -36.500000000 -24.500000000 -5.500000000 -36.500000000 -24.500000000 -4.500000000 -36.500000000 -24.500000000 -3.500000000 -36.500000000 -24.500000000 -2.500000000 -36.500000000 -24.500000000 -1.500000000 -36.500000000 -24.500000000 -0.500000000 -36.500000000 -24.500000000 0.500000000 -36.500000000 -24.500000000 1.500000000 -36.500000000 -24.500000000 2.500000000 -36.500000000 -24.500000000 3.500000000 -36.500000000 -24.500000000 4.500000000 -36.500000000 -24.500000000 5.500000000 -36.500000000 -24.500000000 6.500000000 -36.500000000 -24.500000000 7.500000000 -36.500000000 -24.500000000 8.500000000 -36.500000000 -24.500000000 9.500000000 -36.500000000 -24.500000000 10.500000000 -36.500000000 -24.500000000 11.500000000 -36.500000000 -24.500000000 12.500000000 -36.500000000 -24.500000000 13.500000000 -36.500000000 -24.500000000 14.500000000 -36.500000000 -24.500000000 15.500000000 -36.500000000 -24.500000000 16.500000000 -36.500000000 -24.500000000 17.500000000 -36.500000000 -24.500000000 18.500000000 -36.500000000 -24.500000000 19.500000000 -36.500000000 -24.500000000 20.500000000 -36.500000000 -24.500000000 21.500000000 -36.500000000 -24.500000000 22.500000000 -36.500000000 -24.500000000 23.500000000 -36.500000000 -24.500000000 24.500000000 -36.500000000 -24.500000000 25.499996185 -36.499996185 -24.500000000 26.499954224 -36.499954224 -24.500000000 27.499591827 -36.499591827 -24.500000000 28.497470856 -36.497467041 -24.500000000 29.488407135 -36.488403320 -24.500000000 30.458978653 -36.458980560 -24.500000000 31.384418488 -36.384418488 -24.500000000 32.233222961 -36.233222961 -24.499998093 32.981101990 -35.981101990 -24.499998093 -35.167961121 -35.167961121 -24.500000000 -34.622871399 -35.622871399 -24.500000000 33.622871399 -35.622871399 -24.500000000 34.167961121 -35.167961121 -24.500000000 -35.981101990 -33.981101990 -24.499998093 -35.622871399 -34.622871399 -24.500000000 34.622871399 -34.622863770 -24.500000000 34.981101990 -33.981101990 -24.499998093 -36.233222961 -33.233222961 -24.499998093 35.233222961 -33.233226776 -24.500000000 -36.384418488 -32.384422302 -24.500000000 35.384418488 -32.384422302 -24.500000000 -36.458976746 -31.458978653 -24.500000000 35.458980560 -31.458978653 -24.500000000 -36.488403320 -30.488407135 -24.500000000 35.488403320 -30.488407135 -24.500000000 -36.497467041 -29.497472763 -24.500000000 35.497474670 -29.497472763 -24.500000000 -36.499591827 -28.499593735 -24.500000000 35.499591827 -28.499593735 -24.500000000 -36.499954224 -27.499954224 -24.500000000 35.499954224 -27.499954224 -24.500000000 -36.499996185 -26.499996185 -24.500000000 35.499996185 -26.499996185 -24.500000000 -36.500000000 -25.500000000 -24.500000000 35.500000000 -25.500000000 -24.500000000 -36.500000000 -24.500000000 -24.500000000 35.500000000 -24.500000000 -24.500000000 -36.500000000 -23.500000000 -24.500000000 35.500000000 -23.500000000 -24.500000000 -36.500000000 -22.500000000 -24.500000000 35.500000000 -22.500000000 -24.500000000 -36.500000000 -21.500000000 -24.500000000 35.500000000 -21.500000000 -24.500000000 -36.500000000 -20.500000000 -24.500000000 35.500000000 -20.500000000 -24.500000000 -36.500000000 -19.500000000 -24.500000000 35.500000000 -19.500000000 -24.500000000 -36.500000000 -18.500000000 -24.500000000 35.500000000 -18.500000000 -24.500000000 -36.500000000 -17.500000000 -24.500000000 35.500000000 -17.500000000 -24.500000000 -36.500000000 -16.500000000 -24.500000000 35.500000000 -16.500000000 -24.500000000 -36.500000000 -15.500000000 -24.500000000 35.500000000 -15.500000000 -24.500000000 -36.500000000 -14.500000000 -24.500000000 35.500000000 -14.500000000 -24.500000000 -36.500000000 -13.500000000 -24.500000000 35.500000000 -13.500000000 -24.500000000 -36.500000000 -12.500000000 -24.500000000 35.500000000 -12.500000000 -24.500000000 -36.500000000 -11.500000000 -24.500000000 35.500000000 -11.500000000 -24.500000000 -36.500000000 -10.500000000 -24.500000000 35.500000000 -10.500000000 -24.500000000 -36.500000000 -9.500000000 -24.500000000 35.500000000 -9.500000000 -24.500000000 -36.500000000 -8.500000000 -24.500000000 35.500000000 -8.500000000 -24.500000000 -36.500000000 -7.500000000 -24.500000000 35.500000000 -7.500000000 -24.500000000 -36.500000000 -6.500000000 -24.500000000 35.500000000 -6.500000000 -24.500000000 -36.500000000 -5.500000000 -24.500000000 35.500000000 -5.500000000 -24.500000000 -36.500000000 -4.500000000 -24.500000000 35.500000000 -4.500000000 -24.500000000 -36.500000000 -3.500000000 -24.500000000 35.500000000 -3.500000000 -24.500000000 -36.500000000 -2.500000000 -24.500000000 35.500000000 -2.500000000 -24.500000000 -36.500000000 -1.500000000 -24.500000000 35.500000000 -1.500000000 -24.500000000 -36.500000000 -0.500000000 -24.500000000 35.500000000 -0.500000000 -24.500000000 -36.500000000 0.500000000 -24.500000000 35.500000000 0.500000000 -24.500000000 -36.500000000 1.500000000 -24.500000000 35.500000000 1.500000000 -24.500000000 -36.500000000 2.500000000 -24.500000000 35.500000000 2.500000000 -24.500000000 -36.500000000 3.500000000 -24.500000000 35.500000000 3.500000000 -24.500000000 -36.500000000 4.500000000 -24.500000000 35.500000000 4.500000000 -24.500000000 -36.500000000 5.500000000 -24.500000000 35.500000000 5.500000000 -24.500000000 -36.500000000 6.500000000 -24.500000000 35.500000000 6.500000000 -24.500000000 -36.500000000 7.500000000 -24.500000000 35.500000000 7.500000000 -24.500000000 -36.500000000 8.500000000 -24.500000000 35.500000000 8.500000000 -24.500000000 -36.500000000 9.500000000 -24.500000000 35.500000000 9.500000000 -24.500000000 -36.500000000 10.500000000 -24.500000000 35.500000000 10.500000000 -24.500000000 -36.500000000 11.500000000 -24.500000000 35.500000000 11.500000000 -24.500000000 -36.500000000 12.500000000 -24.500000000 35.500000000 12.500000000 -24.500000000 -36.500000000 13.500000000 -24.500000000 35.500000000 13.500000000 -24.500000000 -36.500000000 14.500000000 -24.500000000 35.500000000 14.500000000 -24.500000000 -36.500000000 15.500000000 -24.500000000 35.500000000 15.500000000 -24.500000000 -36.500000000 16.500000000 -24.500000000 35.500000000 16.500000000 -24.500000000 -36.500000000 17.500000000 -24.500000000 35.500000000 17.500000000 -24.500000000 -36.500000000 18.500000000 -24.500000000 35.500000000 18.500000000 -24.500000000 -36.500000000 19.500000000 -24.500000000 35.500000000 19.500000000 -24.500000000 -36.500000000 20.500000000 -24.500000000 35.500000000 20.500000000 -24.500000000 -36.500000000 21.500000000 -24.500000000 35.500000000 21.500000000 -24.500000000 -36.500000000 22.500000000 -24.500000000 35.500000000 22.500000000 -24.500000000 -36.500000000 23.500000000 -24.500000000 35.500000000 23.500000000 -24.500000000 -36.500000000 24.500000000 -24.500000000 35.500000000 24.500000000 -24.500000000 -36.499996185 25.499996185 -24.500000000 35.499996185 25.499996185 -24.500000000 -36.499954224 26.499954224 -24.500000000 35.499954224 26.499954224 -24.500000000 -36.499591827 27.499591827 -24.500000000 35.499591827 27.499591827 -24.500000000 -36.497474670 28.497470856 -24.500000000 35.497467041 28.497470856 -24.500000000 -36.488403320 29.488407135 -24.500000000 35.488403320 29.488407135 -24.500000000 -36.458980560 30.458978653 -24.500000000 35.458980560 30.458978653 -24.500000000 -36.384418488 31.384418488 -24.500000000 35.384418488 31.384418488 -24.500000000 -36.233222961 32.233222961 -24.499998093 35.233222961 32.233222961 -24.499998093 -35.981101990 32.981101990 -24.499998093 -35.622871399 33.622871399 -24.500000000 34.622871399 33.622871399 -24.500000000 34.981101990 32.981101990 -24.499998093 -35.167961121 34.167961121 -24.500000000 -34.622871399 34.622871399 -24.500000000 33.622863770 34.622871399 -24.500000000 34.167961121 34.167961121 -24.500000000 -33.981101990 34.981101990 -24.499998093 -33.233222961 35.233222961 -24.499998093 -32.384422302 35.384418488 -24.500000000 -31.458978653 35.458976746 -24.500000000 -30.488407135 35.488403320 -24.500000000 -29.497472763 35.497467041 -24.500000000 -28.499593735 35.499591827 -24.500000000 -27.499954224 35.499954224 -24.500000000 -26.499996185 35.499996185 -24.500000000 -25.500000000 35.500000000 -24.500000000 -24.500000000 35.500000000 -24.500000000 -23.500000000 35.500000000 -24.500000000 -22.500000000 35.500000000 -24.500000000 -21.500000000 35.500000000 -24.500000000 -20.500000000 35.500000000 -24.500000000 -19.500000000 35.500000000 -24.500000000 -18.500000000 35.500000000 -24.500000000 -17.500000000 35.500000000 -24.500000000 -16.500000000 35.500000000 -24.500000000 -15.500000000 35.500000000 -24.500000000 -14.500000000 35.500000000 -24.500000000 -13.500000000 35.500000000 -24.500000000 -12.500000000 35.500000000 -24.500000000 -11.500000000 35.500000000 -24.500000000 -10.500000000 35.500000000 -24.500000000 -9.500000000 35.500000000 -24.500000000 -8.500000000 35.500000000 -24.500000000 -7.500000000 35.500000000 -24.500000000 -6.500000000 35.500000000 -24.500000000 -5.500000000 35.500000000 -24.500000000 -4.500000000 35.500000000 -24.500000000 -3.500000000 35.500000000 -24.500000000 -2.500000000 35.500000000 -24.500000000 -1.500000000 35.500000000 -24.500000000 -0.500000000 35.500000000 -24.500000000 0.500000000 35.500000000 -24.500000000 1.500000000 35.500000000 -24.500000000 2.500000000 35.500000000 -24.500000000 3.500000000 35.500000000 -24.500000000 4.500000000 35.500000000 -24.500000000 5.500000000 35.500000000 -24.500000000 6.500000000 35.500000000 -24.500000000 7.500000000 35.500000000 -24.500000000 8.500000000 35.500000000 -24.500000000 9.500000000 35.500000000 -24.500000000 10.500000000 35.500000000 -24.500000000 11.500000000 35.500000000 -24.500000000 12.500000000 35.500000000 -24.500000000 13.500000000 35.500000000 -24.500000000 14.500000000 35.500000000 -24.500000000 15.500000000 35.500000000 -24.500000000 16.500000000 35.500000000 -24.500000000 17.500000000 35.500000000 -24.500000000 18.500000000 35.500000000 -24.500000000 19.500000000 35.500000000 -24.500000000 20.500000000 35.500000000 -24.500000000 21.500000000 35.500000000 -24.500000000 22.500000000 35.500000000 -24.500000000 23.500000000 35.500000000 -24.500000000 24.500000000 35.500000000 -24.500000000 25.499996185 35.499996185 -24.500000000 26.499954224 35.499954224 -24.500000000 27.499591827 35.499591827 -24.500000000 28.497470856 35.497474670 -24.500000000 29.488407135 35.488403320 -24.500000000 30.458978653 35.458980560 -24.500000000 31.384418488 35.384418488 -24.500000000 32.233222961 35.233222961 -24.499998093 32.981101990 34.981101990 -24.499998093 -33.981101990 -35.981101990 -23.500000000 -33.233226776 -36.233222961 -23.500000000 -32.384422302 -36.384418488 -23.500000000 -31.458978653 -36.458980560 -23.500000000 -30.488407135 -36.488403320 -23.500000000 -29.497472763 -36.497474670 -23.500000000 -28.499593735 -36.499591827 -23.500000000 -27.499954224 -36.499954224 -23.500000000 -26.499996185 -36.499996185 -23.500000000 -25.500000000 -36.500000000 -23.500000000 -24.500000000 -36.500000000 -23.500000000 -23.500000000 -36.500000000 -23.500000000 -22.500000000 -36.500000000 -23.500000000 -21.500000000 -36.500000000 -23.500000000 -20.500000000 -36.500000000 -23.500000000 -19.500000000 -36.500000000 -23.500000000 -18.500000000 -36.500000000 -23.500000000 -17.500000000 -36.500000000 -23.500000000 -16.500000000 -36.500000000 -23.500000000 -15.500000000 -36.500000000 -23.500000000 -14.500000000 -36.500000000 -23.500000000 -13.500000000 -36.500000000 -23.500000000 -12.500000000 -36.500000000 -23.500000000 -11.500000000 -36.500000000 -23.500000000 -10.500000000 -36.500000000 -23.500000000 -9.500000000 -36.500000000 -23.500000000 -8.500000000 -36.500000000 -23.500000000 -7.500000000 -36.500000000 -23.500000000 -6.500000000 -36.500000000 -23.500000000 -5.500000000 -36.500000000 -23.500000000 -4.500000000 -36.500000000 -23.500000000 -3.500000000 -36.500000000 -23.500000000 -2.500000000 -36.500000000 -23.500000000 -1.500000000 -36.500000000 -23.500000000 -0.500000000 -36.500000000 -23.500000000 0.500000000 -36.500000000 -23.500000000 1.500000000 -36.500000000 -23.500000000 2.500000000 -36.500000000 -23.500000000 3.500000000 -36.500000000 -23.500000000 4.500000000 -36.500000000 -23.500000000 5.500000000 -36.500000000 -23.500000000 6.500000000 -36.500000000 -23.500000000 7.500000000 -36.500000000 -23.500000000 8.500000000 -36.500000000 -23.500000000 9.500000000 -36.500000000 -23.500000000 10.500000000 -36.500000000 -23.500000000 11.500000000 -36.500000000 -23.500000000 12.500000000 -36.500000000 -23.500000000 13.500000000 -36.500000000 -23.500000000 14.500000000 -36.500000000 -23.500000000 15.500000000 -36.500000000 -23.500000000 16.500000000 -36.500000000 -23.500000000 17.500000000 -36.500000000 -23.500000000 18.500000000 -36.500000000 -23.500000000 19.500000000 -36.500000000 -23.500000000 20.500000000 -36.500000000 -23.500000000 21.500000000 -36.500000000 -23.500000000 22.500000000 -36.500000000 -23.500000000 23.500000000 -36.500000000 -23.500000000 24.500000000 -36.500000000 -23.500000000 25.499996185 -36.499996185 -23.500000000 26.499954224 -36.499954224 -23.500000000 27.499591827 -36.499591827 -23.500000000 28.497470856 -36.497467041 -23.500000000 29.488407135 -36.488403320 -23.500000000 30.458978653 -36.458980560 -23.500000000 31.384418488 -36.384422302 -23.500000000 32.233222961 -36.233222961 -23.500000000 32.981101990 -35.981101990 -23.500000000 -35.167964935 -35.167964935 -23.500000000 -34.622871399 -35.622871399 -23.500000000 33.622871399 -35.622871399 -23.500000000 34.167964935 -35.167964935 -23.500000000 -35.981101990 -33.981101990 -23.500000000 -35.622871399 -34.622871399 -23.500000000 34.622871399 -34.622871399 -23.500000000 34.981101990 -33.981101990 -23.500000000 -36.233222961 -33.233222961 -23.500000000 35.233222961 -33.233226776 -23.500000000 -36.384418488 -32.384422302 -23.500000000 35.384418488 -32.384422302 -23.500000000 -36.458976746 -31.458978653 -23.500000000 35.458980560 -31.458978653 -23.500000000 -36.488403320 -30.488407135 -23.500000000 35.488403320 -30.488407135 -23.500000000 -36.497467041 -29.497472763 -23.500000000 35.497474670 -29.497472763 -23.500000000 -36.499591827 -28.499593735 -23.500000000 35.499591827 -28.499593735 -23.500000000 -36.499954224 -27.499954224 -23.500000000 35.499954224 -27.499954224 -23.500000000 -36.499996185 -26.499996185 -23.500000000 35.499996185 -26.499996185 -23.500000000 -36.500000000 -25.500000000 -23.500000000 35.500000000 -25.500000000 -23.500000000 -36.500000000 -24.500000000 -23.500000000 35.500000000 -24.500000000 -23.500000000 -36.500000000 -23.500000000 -23.500000000 35.500000000 -23.500000000 -23.500000000 -36.500000000 -22.500000000 -23.500000000 35.500000000 -22.500000000 -23.500000000 -36.500000000 -21.500000000 -23.500000000 35.500000000 -21.500000000 -23.500000000 -36.500000000 -20.500000000 -23.500000000 35.500000000 -20.500000000 -23.500000000 -36.500000000 -19.500000000 -23.500000000 35.500000000 -19.500000000 -23.500000000 -36.500000000 -18.500000000 -23.500000000 35.500000000 -18.500000000 -23.500000000 -36.500000000 -17.500000000 -23.500000000 35.500000000 -17.500000000 -23.500000000 -36.500000000 -16.500000000 -23.500000000 35.500000000 -16.500000000 -23.500000000 -36.500000000 -15.500000000 -23.500000000 35.500000000 -15.500000000 -23.500000000 -36.500000000 -14.500000000 -23.500000000 35.500000000 -14.500000000 -23.500000000 -36.500000000 -13.500000000 -23.500000000 35.500000000 -13.500000000 -23.500000000 -36.500000000 -12.500000000 -23.500000000 35.500000000 -12.500000000 -23.500000000 -36.500000000 -11.500000000 -23.500000000 35.500000000 -11.500000000 -23.500000000 -36.500000000 -10.500000000 -23.500000000 35.500000000 -10.500000000 -23.500000000 -36.500000000 -9.500000000 -23.500000000 35.500000000 -9.500000000 -23.500000000 -36.500000000 -8.500000000 -23.500000000 35.500000000 -8.500000000 -23.500000000 -36.500000000 -7.500000000 -23.500000000 35.500000000 -7.500000000 -23.500000000 -36.500000000 -6.500000000 -23.500000000 35.500000000 -6.500000000 -23.500000000 -36.500000000 -5.500000000 -23.500000000 35.500000000 -5.500000000 -23.500000000 -36.500000000 -4.500000000 -23.500000000 35.500000000 -4.500000000 -23.500000000 -36.500000000 -3.500000000 -23.500000000 35.500000000 -3.500000000 -23.500000000 -36.500000000 -2.500000000 -23.500000000 35.500000000 -2.500000000 -23.500000000 -36.500000000 -1.500000000 -23.500000000 35.500000000 -1.500000000 -23.500000000 -36.500000000 -0.500000000 -23.500000000 35.500000000 -0.500000000 -23.500000000 -36.500000000 0.500000000 -23.500000000 35.500000000 0.500000000 -23.500000000 -36.500000000 1.500000000 -23.500000000 35.500000000 1.500000000 -23.500000000 -36.500000000 2.500000000 -23.500000000 35.500000000 2.500000000 -23.500000000 -36.500000000 3.500000000 -23.500000000 35.500000000 3.500000000 -23.500000000 -36.500000000 4.500000000 -23.500000000 35.500000000 4.500000000 -23.500000000 -36.500000000 5.500000000 -23.500000000 35.500000000 5.500000000 -23.500000000 -36.500000000 6.500000000 -23.500000000 35.500000000 6.500000000 -23.500000000 -36.500000000 7.500000000 -23.500000000 35.500000000 7.500000000 -23.500000000 -36.500000000 8.500000000 -23.500000000 35.500000000 8.500000000 -23.500000000 -36.500000000 9.500000000 -23.500000000 35.500000000 9.500000000 -23.500000000 -36.500000000 10.500000000 -23.500000000 35.500000000 10.500000000 -23.500000000 -36.500000000 11.500000000 -23.500000000 35.500000000 11.500000000 -23.500000000 -36.500000000 12.500000000 -23.500000000 35.500000000 12.500000000 -23.500000000 -36.500000000 13.500000000 -23.500000000 35.500000000 13.500000000 -23.500000000 -36.500000000 14.500000000 -23.500000000 35.500000000 14.500000000 -23.500000000 -36.500000000 15.500000000 -23.500000000 35.500000000 15.500000000 -23.500000000 -36.500000000 16.500000000 -23.500000000 35.500000000 16.500000000 -23.500000000 -36.500000000 17.500000000 -23.500000000 35.500000000 17.500000000 -23.500000000 -36.500000000 18.500000000 -23.500000000 35.500000000 18.500000000 -23.500000000 -36.500000000 19.500000000 -23.500000000 35.500000000 19.500000000 -23.500000000 -36.500000000 20.500000000 -23.500000000 35.500000000 20.500000000 -23.500000000 -36.500000000 21.500000000 -23.500000000 35.500000000 21.500000000 -23.500000000 -36.500000000 22.500000000 -23.500000000 35.500000000 22.500000000 -23.500000000 -36.500000000 23.500000000 -23.500000000 35.500000000 23.500000000 -23.500000000 -36.500000000 24.500000000 -23.500000000 35.500000000 24.500000000 -23.500000000 -36.499996185 25.499996185 -23.500000000 35.499996185 25.499996185 -23.500000000 -36.499954224 26.499954224 -23.500000000 35.499954224 26.499954224 -23.500000000 -36.499591827 27.499591827 -23.500000000 35.499591827 27.499591827 -23.500000000 -36.497474670 28.497470856 -23.500000000 35.497467041 28.497470856 -23.500000000 -36.488403320 29.488407135 -23.500000000 35.488403320 29.488407135 -23.500000000 -36.458980560 30.458978653 -23.500000000 35.458980560 30.458978653 -23.500000000 -36.384422302 31.384418488 -23.500000000 35.384422302 31.384418488 -23.500000000 -36.233222961 32.233222961 -23.500000000 35.233222961 32.233222961 -23.500000000 -35.981101990 32.981101990 -23.500000000 -35.622871399 33.622871399 -23.500000000 34.622871399 33.622871399 -23.500000000 34.981101990 32.981101990 -23.500000000 -35.167964935 34.167964935 -23.500000000 -34.622871399 34.622871399 -23.500000000 33.622871399 34.622871399 -23.500000000 34.167964935 34.167964935 -23.500000000 -33.981101990 34.981101990 -23.500000000 -33.233222961 35.233222961 -23.500000000 -32.384422302 35.384418488 -23.500000000 -31.458978653 35.458976746 -23.500000000 -30.488407135 35.488403320 -23.500000000 -29.497472763 35.497467041 -23.500000000 -28.499593735 35.499591827 -23.500000000 -27.499954224 35.499954224 -23.500000000 -26.499996185 35.499996185 -23.500000000 -25.500000000 35.500000000 -23.500000000 -24.500000000 35.500000000 -23.500000000 -23.500000000 35.500000000 -23.500000000 -22.500000000 35.500000000 -23.500000000 -21.500000000 35.500000000 -23.500000000 -20.500000000 35.500000000 -23.500000000 -19.500000000 35.500000000 -23.500000000 -18.500000000 35.500000000 -23.500000000 -17.500000000 35.500000000 -23.500000000 -16.500000000 35.500000000 -23.500000000 -15.500000000 35.500000000 -23.500000000 -14.500000000 35.500000000 -23.500000000 -13.500000000 35.500000000 -23.500000000 -12.500000000 35.500000000 -23.500000000 -11.500000000 35.500000000 -23.500000000 -10.500000000 35.500000000 -23.500000000 -9.500000000 35.500000000 -23.500000000 -8.500000000 35.500000000 -23.500000000 -7.500000000 35.500000000 -23.500000000 -6.500000000 35.500000000 -23.500000000 -5.500000000 35.500000000 -23.500000000 -4.500000000 35.500000000 -23.500000000 -3.500000000 35.500000000 -23.500000000 -2.500000000 35.500000000 -23.500000000 -1.500000000 35.500000000 -23.500000000 -0.500000000 35.500000000 -23.500000000 0.500000000 35.500000000 -23.500000000 1.500000000 35.500000000 -23.500000000 2.500000000 35.500000000 -23.500000000 3.500000000 35.500000000 -23.500000000 4.500000000 35.500000000 -23.500000000 5.500000000 35.500000000 -23.500000000 6.500000000 35.500000000 -23.500000000 7.500000000 35.500000000 -23.500000000 8.500000000 35.500000000 -23.500000000 9.500000000 35.500000000 -23.500000000 10.500000000 35.500000000 -23.500000000 11.500000000 35.500000000 -23.500000000 12.500000000 35.500000000 -23.500000000 13.500000000 35.500000000 -23.500000000 14.500000000 35.500000000 -23.500000000 15.500000000 35.500000000 -23.500000000 16.500000000 35.500000000 -23.500000000 17.500000000 35.500000000 -23.500000000 18.500000000 35.500000000 -23.500000000 19.500000000 35.500000000 -23.500000000 20.500000000 35.500000000 -23.500000000 21.500000000 35.500000000 -23.500000000 22.500000000 35.500000000 -23.500000000 23.500000000 35.500000000 -23.500000000 24.500000000 35.500000000 -23.500000000 25.499996185 35.499996185 -23.500000000 26.499954224 35.499954224 -23.500000000 27.499591827 35.499591827 -23.500000000 28.497470856 35.497474670 -23.500000000 29.488407135 35.488403320 -23.500000000 30.458978653 35.458980560 -23.500000000 31.384418488 35.384422302 -23.500000000 32.233222961 35.233222961 -23.500000000 32.981101990 34.981101990 -23.500000000 -33.981101990 -35.981101990 -22.500000000 -33.233226776 -36.233222961 -22.500000000 -32.384422302 -36.384418488 -22.500000000 -31.458978653 -36.458980560 -22.500000000 -30.488407135 -36.488403320 -22.500000000 -29.497472763 -36.497474670 -22.500000000 -28.499593735 -36.499591827 -22.500000000 -27.499954224 -36.499954224 -22.500000000 -26.499996185 -36.499996185 -22.500000000 -25.500000000 -36.500000000 -22.500000000 -24.500000000 -36.500000000 -22.500000000 -23.500000000 -36.500000000 -22.500000000 -22.500000000 -36.500000000 -22.500000000 -21.500000000 -36.500000000 -22.500000000 -20.500000000 -36.500000000 -22.500000000 -19.500000000 -36.500000000 -22.500000000 -18.500000000 -36.500000000 -22.500000000 -17.500000000 -36.500000000 -22.500000000 -16.500000000 -36.500000000 -22.500000000 -15.500000000 -36.500000000 -22.500000000 -14.500000000 -36.500000000 -22.500000000 -13.500000000 -36.500000000 -22.500000000 -12.500000000 -36.500000000 -22.500000000 -11.500000000 -36.500000000 -22.500000000 -10.500000000 -36.500000000 -22.500000000 -9.500000000 -36.500000000 -22.500000000 -8.500000000 -36.500000000 -22.500000000 -7.500000000 -36.500000000 -22.500000000 -6.500000000 -36.500000000 -22.500000000 -5.500000000 -36.500000000 -22.500000000 -4.500000000 -36.500000000 -22.500000000 -3.500000000 -36.500000000 -22.500000000 -2.500000000 -36.500000000 -22.500000000 -1.500000000 -36.500000000 -22.500000000 -0.500000000 -36.500000000 -22.500000000 0.500000000 -36.500000000 -22.500000000 1.500000000 -36.500000000 -22.500000000 2.500000000 -36.500000000 -22.500000000 3.500000000 -36.500000000 -22.500000000 4.500000000 -36.500000000 -22.500000000 5.500000000 -36.500000000 -22.500000000 6.500000000 -36.500000000 -22.500000000 7.500000000 -36.500000000 -22.500000000 8.500000000 -36.500000000 -22.500000000 9.500000000 -36.500000000 -22.500000000 10.500000000 -36.500000000 -22.500000000 11.500000000 -36.500000000 -22.500000000 12.500000000 -36.500000000 -22.500000000 13.500000000 -36.500000000 -22.500000000 14.500000000 -36.500000000 -22.500000000 15.500000000 -36.500000000 -22.500000000 16.500000000 -36.500000000 -22.500000000 17.500000000 -36.500000000 -22.500000000 18.500000000 -36.500000000 -22.500000000 19.500000000 -36.500000000 -22.500000000 20.500000000 -36.500000000 -22.500000000 21.500000000 -36.500000000 -22.500000000 22.500000000 -36.500000000 -22.500000000 23.500000000 -36.500000000 -22.500000000 24.500000000 -36.500000000 -22.500000000 25.499996185 -36.499996185 -22.500000000 26.499954224 -36.499954224 -22.500000000 27.499591827 -36.499591827 -22.500000000 28.497470856 -36.497467041 -22.500000000 29.488407135 -36.488403320 -22.500000000 30.458978653 -36.458980560 -22.500000000 31.384418488 -36.384422302 -22.500000000 32.233222961 -36.233222961 -22.500000000 32.981101990 -35.981101990 -22.500000000 -35.167964935 -35.167964935 -22.500000000 -34.622871399 -35.622871399 -22.500000000 33.622871399 -35.622871399 -22.500000000 34.167964935 -35.167964935 -22.500000000 -35.981101990 -33.981101990 -22.500000000 -35.622871399 -34.622871399 -22.500000000 34.622871399 -34.622871399 -22.500000000 34.981101990 -33.981101990 -22.500000000 -36.233222961 -33.233222961 -22.500000000 35.233222961 -33.233226776 -22.500000000 -36.384418488 -32.384422302 -22.500000000 35.384418488 -32.384422302 -22.500000000 -36.458976746 -31.458978653 -22.500000000 35.458980560 -31.458978653 -22.500000000 -36.488403320 -30.488407135 -22.500000000 35.488403320 -30.488407135 -22.500000000 -36.497467041 -29.497472763 -22.500000000 35.497474670 -29.497472763 -22.500000000 -36.499591827 -28.499593735 -22.500000000 35.499591827 -28.499593735 -22.500000000 -36.499954224 -27.499954224 -22.500000000 35.499954224 -27.499954224 -22.500000000 -36.499996185 -26.499996185 -22.500000000 35.499996185 -26.499996185 -22.500000000 -36.500000000 -25.500000000 -22.500000000 35.500000000 -25.500000000 -22.500000000 -36.500000000 -24.500000000 -22.500000000 35.500000000 -24.500000000 -22.500000000 -36.500000000 -23.500000000 -22.500000000 35.500000000 -23.500000000 -22.500000000 -36.500000000 -22.500000000 -22.500000000 35.500000000 -22.500000000 -22.500000000 -36.500000000 -21.500000000 -22.500000000 35.500000000 -21.500000000 -22.500000000 -36.500000000 -20.500000000 -22.500000000 35.500000000 -20.500000000 -22.500000000 -36.500000000 -19.500000000 -22.500000000 35.500000000 -19.500000000 -22.500000000 -36.500000000 -18.500000000 -22.500000000 35.500000000 -18.500000000 -22.500000000 -36.500000000 -17.500000000 -22.500000000 35.500000000 -17.500000000 -22.500000000 -36.500000000 -16.500000000 -22.500000000 35.500000000 -16.500000000 -22.500000000 -36.500000000 -15.500000000 -22.500000000 35.500000000 -15.500000000 -22.500000000 -36.500000000 -14.500000000 -22.500000000 35.500000000 -14.500000000 -22.500000000 -36.500000000 -13.500000000 -22.500000000 35.500000000 -13.500000000 -22.500000000 -36.500000000 -12.500000000 -22.500000000 35.500000000 -12.500000000 -22.500000000 -36.500000000 -11.500000000 -22.500000000 35.500000000 -11.500000000 -22.500000000 -36.500000000 -10.500000000 -22.500000000 35.500000000 -10.500000000 -22.500000000 -36.500000000 -9.500000000 -22.500000000 35.500000000 -9.500000000 -22.500000000 -36.500000000 -8.500000000 -22.500000000 35.500000000 -8.500000000 -22.500000000 -36.500000000 -7.500000000 -22.500000000 35.500000000 -7.500000000 -22.500000000 -36.500000000 -6.500000000 -22.500000000 35.500000000 -6.500000000 -22.500000000 -36.500000000 -5.500000000 -22.500000000 35.500000000 -5.500000000 -22.500000000 -36.500000000 -4.500000000 -22.500000000 35.500000000 -4.500000000 -22.500000000 -36.500000000 -3.500000000 -22.500000000 35.500000000 -3.500000000 -22.500000000 -36.500000000 -2.500000000 -22.500000000 35.500000000 -2.500000000 -22.500000000 -36.500000000 -1.500000000 -22.500000000 35.500000000 -1.500000000 -22.500000000 -36.500000000 -0.500000000 -22.500000000 35.500000000 -0.500000000 -22.500000000 -36.500000000 0.500000000 -22.500000000 35.500000000 0.500000000 -22.500000000 -36.500000000 1.500000000 -22.500000000 35.500000000 1.500000000 -22.500000000 -36.500000000 2.500000000 -22.500000000 35.500000000 2.500000000 -22.500000000 -36.500000000 3.500000000 -22.500000000 35.500000000 3.500000000 -22.500000000 -36.500000000 4.500000000 -22.500000000 35.500000000 4.500000000 -22.500000000 -36.500000000 5.500000000 -22.500000000 35.500000000 5.500000000 -22.500000000 -36.500000000 6.500000000 -22.500000000 35.500000000 6.500000000 -22.500000000 -36.500000000 7.500000000 -22.500000000 35.500000000 7.500000000 -22.500000000 -36.500000000 8.500000000 -22.500000000 35.500000000 8.500000000 -22.500000000 -36.500000000 9.500000000 -22.500000000 35.500000000 9.500000000 -22.500000000 -36.500000000 10.500000000 -22.500000000 35.500000000 10.500000000 -22.500000000 -36.500000000 11.500000000 -22.500000000 35.500000000 11.500000000 -22.500000000 -36.500000000 12.500000000 -22.500000000 35.500000000 12.500000000 -22.500000000 -36.500000000 13.500000000 -22.500000000 35.500000000 13.500000000 -22.500000000 -36.500000000 14.500000000 -22.500000000 35.500000000 14.500000000 -22.500000000 -36.500000000 15.500000000 -22.500000000 35.500000000 15.500000000 -22.500000000 -36.500000000 16.500000000 -22.500000000 35.500000000 16.500000000 -22.500000000 -36.500000000 17.500000000 -22.500000000 35.500000000 17.500000000 -22.500000000 -36.500000000 18.500000000 -22.500000000 35.500000000 18.500000000 -22.500000000 -36.500000000 19.500000000 -22.500000000 35.500000000 19.500000000 -22.500000000 -36.500000000 20.500000000 -22.500000000 35.500000000 20.500000000 -22.500000000 -36.500000000 21.500000000 -22.500000000 35.500000000 21.500000000 -22.500000000 -36.500000000 22.500000000 -22.500000000 35.500000000 22.500000000 -22.500000000 -36.500000000 23.500000000 -22.500000000 35.500000000 23.500000000 -22.500000000 -36.500000000 24.500000000 -22.500000000 35.500000000 24.500000000 -22.500000000 -36.499996185 25.499996185 -22.500000000 35.499996185 25.499996185 -22.500000000 -36.499954224 26.499954224 -22.500000000 35.499954224 26.499954224 -22.500000000 -36.499591827 27.499591827 -22.500000000 35.499591827 27.499591827 -22.500000000 -36.497474670 28.497470856 -22.500000000 35.497467041 28.497470856 -22.500000000 -36.488403320 29.488407135 -22.500000000 35.488403320 29.488407135 -22.500000000 -36.458980560 30.458978653 -22.500000000 35.458980560 30.458978653 -22.500000000 -36.384422302 31.384418488 -22.500000000 35.384422302 31.384418488 -22.500000000 -36.233222961 32.233222961 -22.500000000 35.233222961 32.233222961 -22.500000000 -35.981101990 32.981101990 -22.500000000 -35.622871399 33.622871399 -22.500000000 34.622871399 33.622871399 -22.500000000 34.981101990 32.981101990 -22.500000000 -35.167964935 34.167964935 -22.500000000 -34.622871399 34.622871399 -22.500000000 33.622871399 34.622871399 -22.500000000 34.167964935 34.167964935 -22.500000000 -33.981101990 34.981101990 -22.500000000 -33.233222961 35.233222961 -22.500000000 -32.384422302 35.384418488 -22.500000000 -31.458978653 35.458976746 -22.500000000 -30.488407135 35.488403320 -22.500000000 -29.497472763 35.497467041 -22.500000000 -28.499593735 35.499591827 -22.500000000 -27.499954224 35.499954224 -22.500000000 -26.499996185 35.499996185 -22.500000000 -25.500000000 35.500000000 -22.500000000 -24.500000000 35.500000000 -22.500000000 -23.500000000 35.500000000 -22.500000000 -22.500000000 35.500000000 -22.500000000 -21.500000000 35.500000000 -22.500000000 -20.500000000 35.500000000 -22.500000000 -19.500000000 35.500000000 -22.500000000 -18.500000000 35.500000000 -22.500000000 -17.500000000 35.500000000 -22.500000000 -16.500000000 35.500000000 -22.500000000 -15.500000000 35.500000000 -22.500000000 -14.500000000 35.500000000 -22.500000000 -13.500000000 35.500000000 -22.500000000 -12.500000000 35.500000000 -22.500000000 -11.500000000 35.500000000 -22.500000000 -10.500000000 35.500000000 -22.500000000 -9.500000000 35.500000000 -22.500000000 -8.500000000 35.500000000 -22.500000000 -7.500000000 35.500000000 -22.500000000 -6.500000000 35.500000000 -22.500000000 -5.500000000 35.500000000 -22.500000000 -4.500000000 35.500000000 -22.500000000 -3.500000000 35.500000000 -22.500000000 -2.500000000 35.500000000 -22.500000000 -1.500000000 35.500000000 -22.500000000 -0.500000000 35.500000000 -22.500000000 0.500000000 35.500000000 -22.500000000 1.500000000 35.500000000 -22.500000000 2.500000000 35.500000000 -22.500000000 3.500000000 35.500000000 -22.500000000 4.500000000 35.500000000 -22.500000000 5.500000000 35.500000000 -22.500000000 6.500000000 35.500000000 -22.500000000 7.500000000 35.500000000 -22.500000000 8.500000000 35.500000000 -22.500000000 9.500000000 35.500000000 -22.500000000 10.500000000 35.500000000 -22.500000000 11.500000000 35.500000000 -22.500000000 12.500000000 35.500000000 -22.500000000 13.500000000 35.500000000 -22.500000000 14.500000000 35.500000000 -22.500000000 15.500000000 35.500000000 -22.500000000 16.500000000 35.500000000 -22.500000000 17.500000000 35.500000000 -22.500000000 18.500000000 35.500000000 -22.500000000 19.500000000 35.500000000 -22.500000000 20.500000000 35.500000000 -22.500000000 21.500000000 35.500000000 -22.500000000 22.500000000 35.500000000 -22.500000000 23.500000000 35.500000000 -22.500000000 24.500000000 35.500000000 -22.500000000 25.499996185 35.499996185 -22.500000000 26.499954224 35.499954224 -22.500000000 27.499591827 35.499591827 -22.500000000 28.497470856 35.497474670 -22.500000000 29.488407135 35.488403320 -22.500000000 30.458978653 35.458980560 -22.500000000 31.384418488 35.384422302 -22.500000000 32.233222961 35.233222961 -22.500000000 32.981101990 34.981101990 -22.500000000 -33.981101990 -35.981101990 -21.500000000 -33.233226776 -36.233222961 -21.500000000 -32.384422302 -36.384418488 -21.500000000 -31.458978653 -36.458980560 -21.500000000 -30.488407135 -36.488403320 -21.500000000 -29.497472763 -36.497474670 -21.500000000 -28.499593735 -36.499591827 -21.500000000 -27.499954224 -36.499954224 -21.500000000 -26.499996185 -36.499996185 -21.500000000 -25.500000000 -36.500000000 -21.500000000 -24.500000000 -36.500000000 -21.500000000 -23.500000000 -36.500000000 -21.500000000 -22.500000000 -36.500000000 -21.500000000 -21.500000000 -36.500000000 -21.500000000 -20.500000000 -36.500000000 -21.500000000 -19.500000000 -36.500000000 -21.500000000 -18.500000000 -36.500000000 -21.500000000 -17.500000000 -36.500000000 -21.500000000 -16.500000000 -36.500000000 -21.500000000 -15.500000000 -36.500000000 -21.500000000 -14.500000000 -36.500000000 -21.500000000 -13.500000000 -36.500000000 -21.500000000 -12.500000000 -36.500000000 -21.500000000 -11.500000000 -36.500000000 -21.500000000 -10.500000000 -36.500000000 -21.500000000 -9.500000000 -36.500000000 -21.500000000 -8.500000000 -36.500000000 -21.500000000 -7.500000000 -36.500000000 -21.500000000 -6.500000000 -36.500000000 -21.500000000 -5.500000000 -36.500000000 -21.500000000 -4.500000000 -36.500000000 -21.500000000 -3.500000000 -36.500000000 -21.500000000 -2.500000000 -36.500000000 -21.500000000 -1.500000000 -36.500000000 -21.500000000 -0.500000000 -36.500000000 -21.500000000 0.500000000 -36.500000000 -21.500000000 1.500000000 -36.500000000 -21.500000000 2.500000000 -36.500000000 -21.500000000 3.500000000 -36.500000000 -21.500000000 4.500000000 -36.500000000 -21.500000000 5.500000000 -36.500000000 -21.500000000 6.500000000 -36.500000000 -21.500000000 7.500000000 -36.500000000 -21.500000000 8.500000000 -36.500000000 -21.500000000 9.500000000 -36.500000000 -21.500000000 10.500000000 -36.500000000 -21.500000000 11.500000000 -36.500000000 -21.500000000 12.500000000 -36.500000000 -21.500000000 13.500000000 -36.500000000 -21.500000000 14.500000000 -36.500000000 -21.500000000 15.500000000 -36.500000000 -21.500000000 16.500000000 -36.500000000 -21.500000000 17.500000000 -36.500000000 -21.500000000 18.500000000 -36.500000000 -21.500000000 19.500000000 -36.500000000 -21.500000000 20.500000000 -36.500000000 -21.500000000 21.500000000 -36.500000000 -21.500000000 22.500000000 -36.500000000 -21.500000000 23.500000000 -36.500000000 -21.500000000 24.500000000 -36.500000000 -21.500000000 25.499996185 -36.499996185 -21.500000000 26.499954224 -36.499954224 -21.500000000 27.499591827 -36.499591827 -21.500000000 28.497470856 -36.497467041 -21.500000000 29.488407135 -36.488403320 -21.500000000 30.458978653 -36.458980560 -21.500000000 31.384418488 -36.384422302 -21.500000000 32.233222961 -36.233222961 -21.500000000 32.981101990 -35.981101990 -21.500000000 -35.167964935 -35.167964935 -21.500000000 -34.622871399 -35.622871399 -21.500000000 33.622871399 -35.622871399 -21.500000000 34.167964935 -35.167964935 -21.500000000 -35.981101990 -33.981101990 -21.500000000 -35.622871399 -34.622871399 -21.500000000 34.622871399 -34.622871399 -21.500000000 34.981101990 -33.981101990 -21.500000000 -36.233222961 -33.233222961 -21.500000000 35.233222961 -33.233226776 -21.500000000 -36.384418488 -32.384422302 -21.500000000 35.384418488 -32.384422302 -21.500000000 -36.458976746 -31.458978653 -21.500000000 35.458980560 -31.458978653 -21.500000000 -36.488403320 -30.488407135 -21.500000000 35.488403320 -30.488407135 -21.500000000 -36.497467041 -29.497472763 -21.500000000 35.497474670 -29.497472763 -21.500000000 -36.499591827 -28.499593735 -21.500000000 35.499591827 -28.499593735 -21.500000000 -36.499954224 -27.499954224 -21.500000000 35.499954224 -27.499954224 -21.500000000 -36.499996185 -26.499996185 -21.500000000 35.499996185 -26.499996185 -21.500000000 -36.500000000 -25.500000000 -21.500000000 35.500000000 -25.500000000 -21.500000000 -36.500000000 -24.500000000 -21.500000000 35.500000000 -24.500000000 -21.500000000 -36.500000000 -23.500000000 -21.500000000 35.500000000 -23.500000000 -21.500000000 -36.500000000 -22.500000000 -21.500000000 35.500000000 -22.500000000 -21.500000000 -36.500000000 -21.500000000 -21.500000000 35.500000000 -21.500000000 -21.500000000 -36.500000000 -20.500000000 -21.500000000 35.500000000 -20.500000000 -21.500000000 -36.500000000 -19.500000000 -21.500000000 35.500000000 -19.500000000 -21.500000000 -36.500000000 -18.500000000 -21.500000000 35.500000000 -18.500000000 -21.500000000 -36.500000000 -17.500000000 -21.500000000 35.500000000 -17.500000000 -21.500000000 -36.500000000 -16.500000000 -21.500000000 35.500000000 -16.500000000 -21.500000000 -36.500000000 -15.500000000 -21.500000000 35.500000000 -15.500000000 -21.500000000 -36.500000000 -14.500000000 -21.500000000 35.500000000 -14.500000000 -21.500000000 -36.500000000 -13.500000000 -21.500000000 35.500000000 -13.500000000 -21.500000000 -36.500000000 -12.500000000 -21.500000000 35.500000000 -12.500000000 -21.500000000 -36.500000000 -11.500000000 -21.500000000 35.500000000 -11.500000000 -21.500000000 -36.500000000 -10.500000000 -21.500000000 35.500000000 -10.500000000 -21.500000000 -36.500000000 -9.500000000 -21.500000000 35.500000000 -9.500000000 -21.500000000 -36.500000000 -8.500000000 -21.500000000 35.500000000 -8.500000000 -21.500000000 -36.500000000 -7.500000000 -21.500000000 35.500000000 -7.500000000 -21.500000000 -36.500000000 -6.500000000 -21.500000000 35.500000000 -6.500000000 -21.500000000 -36.500000000 -5.500000000 -21.500000000 35.500000000 -5.500000000 -21.500000000 -36.500000000 -4.500000000 -21.500000000 35.500000000 -4.500000000 -21.500000000 -36.500000000 -3.500000000 -21.500000000 35.500000000 -3.500000000 -21.500000000 -36.500000000 -2.500000000 -21.500000000 35.500000000 -2.500000000 -21.500000000 -36.500000000 -1.500000000 -21.500000000 35.500000000 -1.500000000 -21.500000000 -36.500000000 -0.500000000 -21.500000000 35.500000000 -0.500000000 -21.500000000 -36.500000000 0.500000000 -21.500000000 35.500000000 0.500000000 -21.500000000 -36.500000000 1.500000000 -21.500000000 35.500000000 1.500000000 -21.500000000 -36.500000000 2.500000000 -21.500000000 35.500000000 2.500000000 -21.500000000 -36.500000000 3.500000000 -21.500000000 35.500000000 3.500000000 -21.500000000 -36.500000000 4.500000000 -21.500000000 35.500000000 4.500000000 -21.500000000 -36.500000000 5.500000000 -21.500000000 35.500000000 5.500000000 -21.500000000 -36.500000000 6.500000000 -21.500000000 35.500000000 6.500000000 -21.500000000 -36.500000000 7.500000000 -21.500000000 35.500000000 7.500000000 -21.500000000 -36.500000000 8.500000000 -21.500000000 35.500000000 8.500000000 -21.500000000 -36.500000000 9.500000000 -21.500000000 35.500000000 9.500000000 -21.500000000 -36.500000000 10.500000000 -21.500000000 35.500000000 10.500000000 -21.500000000 -36.500000000 11.500000000 -21.500000000 35.500000000 11.500000000 -21.500000000 -36.500000000 12.500000000 -21.500000000 35.500000000 12.500000000 -21.500000000 -36.500000000 13.500000000 -21.500000000 35.500000000 13.500000000 -21.500000000 -36.500000000 14.500000000 -21.500000000 35.500000000 14.500000000 -21.500000000 -36.500000000 15.500000000 -21.500000000 35.500000000 15.500000000 -21.500000000 -36.500000000 16.500000000 -21.500000000 35.500000000 16.500000000 -21.500000000 -36.500000000 17.500000000 -21.500000000 35.500000000 17.500000000 -21.500000000 -36.500000000 18.500000000 -21.500000000 35.500000000 18.500000000 -21.500000000 -36.500000000 19.500000000 -21.500000000 35.500000000 19.500000000 -21.500000000 -36.500000000 20.500000000 -21.500000000 35.500000000 20.500000000 -21.500000000 -36.500000000 21.500000000 -21.500000000 35.500000000 21.500000000 -21.500000000 -36.500000000 22.500000000 -21.500000000 35.500000000 22.500000000 -21.500000000 -36.500000000 23.500000000 -21.500000000 35.500000000 23.500000000 -21.500000000 -36.500000000 24.500000000 -21.500000000 35.500000000 24.500000000 -21.500000000 -36.499996185 25.499996185 -21.500000000 35.499996185 25.499996185 -21.500000000 -36.499954224 26.499954224 -21.500000000 35.499954224 26.499954224 -21.500000000 -36.499591827 27.499591827 -21.500000000 35.499591827 27.499591827 -21.500000000 -36.497474670 28.497470856 -21.500000000 35.497467041 28.497470856 -21.500000000 -36.488403320 29.488407135 -21.500000000 35.488403320 29.488407135 -21.500000000 -36.458980560 30.458978653 -21.500000000 35.458980560 30.458978653 -21.500000000 -36.384422302 31.384418488 -21.500000000 35.384422302 31.384418488 -21.500000000 -36.233222961 32.233222961 -21.500000000 35.233222961 32.233222961 -21.500000000 -35.981101990 32.981101990 -21.500000000 -35.622871399 33.622871399 -21.500000000 34.622871399 33.622871399 -21.500000000 34.981101990 32.981101990 -21.500000000 -35.167964935 34.167964935 -21.500000000 -34.622871399 34.622871399 -21.500000000 33.622871399 34.622871399 -21.500000000 34.167964935 34.167964935 -21.500000000 -33.981101990 34.981101990 -21.500000000 -33.233222961 35.233222961 -21.500000000 -32.384422302 35.384418488 -21.500000000 -31.458978653 35.458976746 -21.500000000 -30.488407135 35.488403320 -21.500000000 -29.497472763 35.497467041 -21.500000000 -28.499593735 35.499591827 -21.500000000 -27.499954224 35.499954224 -21.500000000 -26.499996185 35.499996185 -21.500000000 -25.500000000 35.500000000 -21.500000000 -24.500000000 35.500000000 -21.500000000 -23.500000000 35.500000000 -21.500000000 -22.500000000 35.500000000 -21.500000000 -21.500000000 35.500000000 -21.500000000 -20.500000000 35.500000000 -21.500000000 -19.500000000 35.500000000 -21.500000000 -18.500000000 35.500000000 -21.500000000 -17.500000000 35.500000000 -21.500000000 -16.500000000 35.500000000 -21.500000000 -15.500000000 35.500000000 -21.500000000 -14.500000000 35.500000000 -21.500000000 -13.500000000 35.500000000 -21.500000000 -12.500000000 35.500000000 -21.500000000 -11.500000000 35.500000000 -21.500000000 -10.500000000 35.500000000 -21.500000000 -9.500000000 35.500000000 -21.500000000 -8.500000000 35.500000000 -21.500000000 -7.500000000 35.500000000 -21.500000000 -6.500000000 35.500000000 -21.500000000 -5.500000000 35.500000000 -21.500000000 -4.500000000 35.500000000 -21.500000000 -3.500000000 35.500000000 -21.500000000 -2.500000000 35.500000000 -21.500000000 -1.500000000 35.500000000 -21.500000000 -0.500000000 35.500000000 -21.500000000 0.500000000 35.500000000 -21.500000000 1.500000000 35.500000000 -21.500000000 2.500000000 35.500000000 -21.500000000 3.500000000 35.500000000 -21.500000000 4.500000000 35.500000000 -21.500000000 5.500000000 35.500000000 -21.500000000 6.500000000 35.500000000 -21.500000000 7.500000000 35.500000000 -21.500000000 8.500000000 35.500000000 -21.500000000 9.500000000 35.500000000 -21.500000000 10.500000000 35.500000000 -21.500000000 11.500000000 35.500000000 -21.500000000 12.500000000 35.500000000 -21.500000000 13.500000000 35.500000000 -21.500000000 14.500000000 35.500000000 -21.500000000 15.500000000 35.500000000 -21.500000000 16.500000000 35.500000000 -21.500000000 17.500000000 35.500000000 -21.500000000 18.500000000 35.500000000 -21.500000000 19.500000000 35.500000000 -21.500000000 20.500000000 35.500000000 -21.500000000 21.500000000 35.500000000 -21.500000000 22.500000000 35.500000000 -21.500000000 23.500000000 35.500000000 -21.500000000 24.500000000 35.500000000 -21.500000000 25.499996185 35.499996185 -21.500000000 26.499954224 35.499954224 -21.500000000 27.499591827 35.499591827 -21.500000000 28.497470856 35.497474670 -21.500000000 29.488407135 35.488403320 -21.500000000 30.458978653 35.458980560 -21.500000000 31.384418488 35.384422302 -21.500000000 32.233222961 35.233222961 -21.500000000 32.981101990 34.981101990 -21.500000000 -33.981101990 -35.981101990 -20.500000000 -33.233226776 -36.233222961 -20.500000000 -32.384422302 -36.384418488 -20.500000000 -31.458978653 -36.458980560 -20.500000000 -30.488407135 -36.488403320 -20.500000000 -29.497472763 -36.497474670 -20.500000000 -28.499593735 -36.499591827 -20.500000000 -27.499954224 -36.499954224 -20.500000000 -26.499996185 -36.499996185 -20.500000000 -25.500000000 -36.500000000 -20.500000000 -24.500000000 -36.500000000 -20.500000000 -23.500000000 -36.500000000 -20.500000000 -22.500000000 -36.500000000 -20.500000000 -21.500000000 -36.500000000 -20.500000000 -20.500000000 -36.500000000 -20.500000000 -19.500000000 -36.500000000 -20.500000000 -18.500000000 -36.500000000 -20.500000000 -17.500000000 -36.500000000 -20.500000000 -16.500000000 -36.500000000 -20.500000000 -15.500000000 -36.500000000 -20.500000000 -14.500000000 -36.500000000 -20.500000000 -13.500000000 -36.500000000 -20.500000000 -12.500000000 -36.500000000 -20.500000000 -11.500000000 -36.500000000 -20.500000000 -10.500000000 -36.500000000 -20.500000000 -9.500000000 -36.500000000 -20.500000000 -8.500000000 -36.500000000 -20.500000000 -7.500000000 -36.500000000 -20.500000000 -6.500000000 -36.500000000 -20.500000000 -5.500000000 -36.500000000 -20.500000000 -4.500000000 -36.500000000 -20.500000000 -3.500000000 -36.500000000 -20.500000000 -2.500000000 -36.500000000 -20.500000000 -1.500000000 -36.500000000 -20.500000000 -0.500000000 -36.500000000 -20.500000000 0.500000000 -36.500000000 -20.500000000 1.500000000 -36.500000000 -20.500000000 2.500000000 -36.500000000 -20.500000000 3.500000000 -36.500000000 -20.500000000 4.500000000 -36.500000000 -20.500000000 5.500000000 -36.500000000 -20.500000000 6.500000000 -36.500000000 -20.500000000 7.500000000 -36.500000000 -20.500000000 8.500000000 -36.500000000 -20.500000000 9.500000000 -36.500000000 -20.500000000 10.500000000 -36.500000000 -20.500000000 11.500000000 -36.500000000 -20.500000000 12.500000000 -36.500000000 -20.500000000 13.500000000 -36.500000000 -20.500000000 14.500000000 -36.500000000 -20.500000000 15.500000000 -36.500000000 -20.500000000 16.500000000 -36.500000000 -20.500000000 17.500000000 -36.500000000 -20.500000000 18.500000000 -36.500000000 -20.500000000 19.500000000 -36.500000000 -20.500000000 20.500000000 -36.500000000 -20.500000000 21.500000000 -36.500000000 -20.500000000 22.500000000 -36.500000000 -20.500000000 23.500000000 -36.500000000 -20.500000000 24.500000000 -36.500000000 -20.500000000 25.499996185 -36.499996185 -20.500000000 26.499954224 -36.499954224 -20.500000000 27.499591827 -36.499591827 -20.500000000 28.497470856 -36.497467041 -20.500000000 29.488407135 -36.488403320 -20.500000000 30.458978653 -36.458980560 -20.500000000 31.384418488 -36.384422302 -20.500000000 32.233222961 -36.233222961 -20.500000000 32.981101990 -35.981101990 -20.500000000 -35.167964935 -35.167964935 -20.500000000 -34.622871399 -35.622871399 -20.500000000 33.622871399 -35.622871399 -20.500000000 34.167964935 -35.167964935 -20.500000000 -35.981101990 -33.981101990 -20.500000000 -35.622871399 -34.622871399 -20.500000000 34.622871399 -34.622871399 -20.500000000 34.981101990 -33.981101990 -20.500000000 -36.233222961 -33.233222961 -20.500000000 35.233222961 -33.233226776 -20.500000000 -36.384418488 -32.384422302 -20.500000000 35.384418488 -32.384422302 -20.500000000 -36.458976746 -31.458978653 -20.500000000 35.458980560 -31.458978653 -20.500000000 -36.488403320 -30.488407135 -20.500000000 35.488403320 -30.488407135 -20.500000000 -36.497467041 -29.497472763 -20.500000000 35.497474670 -29.497472763 -20.500000000 -36.499591827 -28.499593735 -20.500000000 35.499591827 -28.499593735 -20.500000000 -36.499954224 -27.499954224 -20.500000000 35.499954224 -27.499954224 -20.500000000 -36.499996185 -26.499996185 -20.500000000 35.499996185 -26.499996185 -20.500000000 -36.500000000 -25.500000000 -20.500000000 35.500000000 -25.500000000 -20.500000000 -36.500000000 -24.500000000 -20.500000000 35.500000000 -24.500000000 -20.500000000 -36.500000000 -23.500000000 -20.500000000 35.500000000 -23.500000000 -20.500000000 -36.500000000 -22.500000000 -20.500000000 35.500000000 -22.500000000 -20.500000000 -36.500000000 -21.500000000 -20.500000000 35.500000000 -21.500000000 -20.500000000 -36.500000000 -20.500000000 -20.500000000 35.500000000 -20.500000000 -20.500000000 -36.500000000 -19.500000000 -20.500000000 35.500000000 -19.500000000 -20.500000000 -36.500000000 -18.500000000 -20.500000000 35.500000000 -18.500000000 -20.500000000 -36.500000000 -17.500000000 -20.500000000 35.500000000 -17.500000000 -20.500000000 -36.500000000 -16.500000000 -20.500000000 35.500000000 -16.500000000 -20.500000000 -36.500000000 -15.500000000 -20.500000000 35.500000000 -15.500000000 -20.500000000 -36.500000000 -14.500000000 -20.500000000 35.500000000 -14.500000000 -20.500000000 -36.500000000 -13.500000000 -20.500000000 35.500000000 -13.500000000 -20.500000000 -36.500000000 -12.500000000 -20.500000000 35.500000000 -12.500000000 -20.500000000 -36.500000000 -11.500000000 -20.500000000 35.500000000 -11.500000000 -20.500000000 -36.500000000 -10.500000000 -20.500000000 35.500000000 -10.500000000 -20.500000000 -36.500000000 -9.500000000 -20.500000000 35.500000000 -9.500000000 -20.500000000 -36.500000000 -8.500000000 -20.500000000 35.500000000 -8.500000000 -20.500000000 -36.500000000 -7.500000000 -20.500000000 35.500000000 -7.500000000 -20.500000000 -36.500000000 -6.500000000 -20.500000000 35.500000000 -6.500000000 -20.500000000 -36.500000000 -5.500000000 -20.500000000 35.500000000 -5.500000000 -20.500000000 -36.500000000 -4.500000000 -20.500000000 35.500000000 -4.500000000 -20.500000000 -36.500000000 -3.500000000 -20.500000000 35.500000000 -3.500000000 -20.500000000 -36.500000000 -2.500000000 -20.500000000 35.500000000 -2.500000000 -20.500000000 -36.500000000 -1.500000000 -20.500000000 35.500000000 -1.500000000 -20.500000000 -36.500000000 -0.500000000 -20.500000000 35.500000000 -0.500000000 -20.500000000 -36.500000000 0.500000000 -20.500000000 35.500000000 0.500000000 -20.500000000 -36.500000000 1.500000000 -20.500000000 35.500000000 1.500000000 -20.500000000 -36.500000000 2.500000000 -20.500000000 35.500000000 2.500000000 -20.500000000 -36.500000000 3.500000000 -20.500000000 35.500000000 3.500000000 -20.500000000 -36.500000000 4.500000000 -20.500000000 35.500000000 4.500000000 -20.500000000 -36.500000000 5.500000000 -20.500000000 35.500000000 5.500000000 -20.500000000 -36.500000000 6.500000000 -20.500000000 35.500000000 6.500000000 -20.500000000 -36.500000000 7.500000000 -20.500000000 35.500000000 7.500000000 -20.500000000 -36.500000000 8.500000000 -20.500000000 35.500000000 8.500000000 -20.500000000 -36.500000000 9.500000000 -20.500000000 35.500000000 9.500000000 -20.500000000 -36.500000000 10.500000000 -20.500000000 35.500000000 10.500000000 -20.500000000 -36.500000000 11.500000000 -20.500000000 35.500000000 11.500000000 -20.500000000 -36.500000000 12.500000000 -20.500000000 35.500000000 12.500000000 -20.500000000 -36.500000000 13.500000000 -20.500000000 35.500000000 13.500000000 -20.500000000 -36.500000000 14.500000000 -20.500000000 35.500000000 14.500000000 -20.500000000 -36.500000000 15.500000000 -20.500000000 35.500000000 15.500000000 -20.500000000 -36.500000000 16.500000000 -20.500000000 35.500000000 16.500000000 -20.500000000 -36.500000000 17.500000000 -20.500000000 35.500000000 17.500000000 -20.500000000 -36.500000000 18.500000000 -20.500000000 35.500000000 18.500000000 -20.500000000 -36.500000000 19.500000000 -20.500000000 35.500000000 19.500000000 -20.500000000 -36.500000000 20.500000000 -20.500000000 35.500000000 20.500000000 -20.500000000 -36.500000000 21.500000000 -20.500000000 35.500000000 21.500000000 -20.500000000 -36.500000000 22.500000000 -20.500000000 35.500000000 22.500000000 -20.500000000 -36.500000000 23.500000000 -20.500000000 35.500000000 23.500000000 -20.500000000 -36.500000000 24.500000000 -20.500000000 35.500000000 24.500000000 -20.500000000 -36.499996185 25.499996185 -20.500000000 35.499996185 25.499996185 -20.500000000 -36.499954224 26.499954224 -20.500000000 35.499954224 26.499954224 -20.500000000 -36.499591827 27.499591827 -20.500000000 35.499591827 27.499591827 -20.500000000 -36.497474670 28.497470856 -20.500000000 35.497467041 28.497470856 -20.500000000 -36.488403320 29.488407135 -20.500000000 35.488403320 29.488407135 -20.500000000 -36.458980560 30.458978653 -20.500000000 35.458980560 30.458978653 -20.500000000 -36.384422302 31.384418488 -20.500000000 35.384422302 31.384418488 -20.500000000 -36.233222961 32.233222961 -20.500000000 35.233222961 32.233222961 -20.500000000 -35.981101990 32.981101990 -20.500000000 -35.622871399 33.622871399 -20.500000000 34.622871399 33.622871399 -20.500000000 34.981101990 32.981101990 -20.500000000 -35.167964935 34.167964935 -20.500000000 -34.622871399 34.622871399 -20.500000000 33.622871399 34.622871399 -20.500000000 34.167964935 34.167964935 -20.500000000 -33.981101990 34.981101990 -20.500000000 -33.233222961 35.233222961 -20.500000000 -32.384422302 35.384418488 -20.500000000 -31.458978653 35.458976746 -20.500000000 -30.488407135 35.488403320 -20.500000000 -29.497472763 35.497467041 -20.500000000 -28.499593735 35.499591827 -20.500000000 -27.499954224 35.499954224 -20.500000000 -26.499996185 35.499996185 -20.500000000 -25.500000000 35.500000000 -20.500000000 -24.500000000 35.500000000 -20.500000000 -23.500000000 35.500000000 -20.500000000 -22.500000000 35.500000000 -20.500000000 -21.500000000 35.500000000 -20.500000000 -20.500000000 35.500000000 -20.500000000 -19.500000000 35.500000000 -20.500000000 -18.500000000 35.500000000 -20.500000000 -17.500000000 35.500000000 -20.500000000 -16.500000000 35.500000000 -20.500000000 -15.500000000 35.500000000 -20.500000000 -14.500000000 35.500000000 -20.500000000 -13.500000000 35.500000000 -20.500000000 -12.500000000 35.500000000 -20.500000000 -11.500000000 35.500000000 -20.500000000 -10.500000000 35.500000000 -20.500000000 -9.500000000 35.500000000 -20.500000000 -8.500000000 35.500000000 -20.500000000 -7.500000000 35.500000000 -20.500000000 -6.500000000 35.500000000 -20.500000000 -5.500000000 35.500000000 -20.500000000 -4.500000000 35.500000000 -20.500000000 -3.500000000 35.500000000 -20.500000000 -2.500000000 35.500000000 -20.500000000 -1.500000000 35.500000000 -20.500000000 -0.500000000 35.500000000 -20.500000000 0.500000000 35.500000000 -20.500000000 1.500000000 35.500000000 -20.500000000 2.500000000 35.500000000 -20.500000000 3.500000000 35.500000000 -20.500000000 4.500000000 35.500000000 -20.500000000 5.500000000 35.500000000 -20.500000000 6.500000000 35.500000000 -20.500000000 7.500000000 35.500000000 -20.500000000 8.500000000 35.500000000 -20.500000000 9.500000000 35.500000000 -20.500000000 10.500000000 35.500000000 -20.500000000 11.500000000 35.500000000 -20.500000000 12.500000000 35.500000000 -20.500000000 13.500000000 35.500000000 -20.500000000 14.500000000 35.500000000 -20.500000000 15.500000000 35.500000000 -20.500000000 16.500000000 35.500000000 -20.500000000 17.500000000 35.500000000 -20.500000000 18.500000000 35.500000000 -20.500000000 19.500000000 35.500000000 -20.500000000 20.500000000 35.500000000 -20.500000000 21.500000000 35.500000000 -20.500000000 22.500000000 35.500000000 -20.500000000 23.500000000 35.500000000 -20.500000000 24.500000000 35.500000000 -20.500000000 25.499996185 35.499996185 -20.500000000 26.499954224 35.499954224 -20.500000000 27.499591827 35.499591827 -20.500000000 28.497470856 35.497474670 -20.500000000 29.488407135 35.488403320 -20.500000000 30.458978653 35.458980560 -20.500000000 31.384418488 35.384422302 -20.500000000 32.233222961 35.233222961 -20.500000000 32.981101990 34.981101990 -20.500000000 -33.981101990 -35.981101990 -19.500000000 -33.233226776 -36.233222961 -19.500000000 -32.384422302 -36.384418488 -19.500000000 -31.458978653 -36.458980560 -19.500000000 -30.488407135 -36.488403320 -19.500000000 -29.497472763 -36.497474670 -19.500000000 -28.499593735 -36.499591827 -19.500000000 -27.499954224 -36.499954224 -19.500000000 -26.499996185 -36.499996185 -19.500000000 -25.500000000 -36.500000000 -19.500000000 -24.500000000 -36.500000000 -19.500000000 -23.500000000 -36.500000000 -19.500000000 -22.500000000 -36.500000000 -19.500000000 -21.500000000 -36.500000000 -19.500000000 -20.500000000 -36.500000000 -19.500000000 -19.500000000 -36.500000000 -19.500000000 -18.500000000 -36.500000000 -19.500000000 -17.500000000 -36.500000000 -19.500000000 -16.500000000 -36.500000000 -19.500000000 -15.500000000 -36.500000000 -19.500000000 -14.500000000 -36.500000000 -19.500000000 -13.500000000 -36.500000000 -19.500000000 -12.500000000 -36.500000000 -19.500000000 -11.500000000 -36.500000000 -19.500000000 -10.500000000 -36.500000000 -19.500000000 -9.500000000 -36.500000000 -19.500000000 -8.500000000 -36.500000000 -19.500000000 -7.500000000 -36.500000000 -19.500000000 -6.500000000 -36.500000000 -19.500000000 -5.500000000 -36.500000000 -19.500000000 -4.500000000 -36.500000000 -19.500000000 -3.500000000 -36.500000000 -19.500000000 -2.500000000 -36.500000000 -19.500000000 -1.500000000 -36.500000000 -19.500000000 -0.500000000 -36.500000000 -19.500000000 0.500000000 -36.500000000 -19.500000000 1.500000000 -36.500000000 -19.500000000 2.500000000 -36.500000000 -19.500000000 3.500000000 -36.500000000 -19.500000000 4.500000000 -36.500000000 -19.500000000 5.500000000 -36.500000000 -19.500000000 6.500000000 -36.500000000 -19.500000000 7.500000000 -36.500000000 -19.500000000 8.500000000 -36.500000000 -19.500000000 9.500000000 -36.500000000 -19.500000000 10.500000000 -36.500000000 -19.500000000 11.500000000 -36.500000000 -19.500000000 12.500000000 -36.500000000 -19.500000000 13.500000000 -36.500000000 -19.500000000 14.500000000 -36.500000000 -19.500000000 15.500000000 -36.500000000 -19.500000000 16.500000000 -36.500000000 -19.500000000 17.500000000 -36.500000000 -19.500000000 18.500000000 -36.500000000 -19.500000000 19.500000000 -36.500000000 -19.500000000 20.500000000 -36.500000000 -19.500000000 21.500000000 -36.500000000 -19.500000000 22.500000000 -36.500000000 -19.500000000 23.500000000 -36.500000000 -19.500000000 24.500000000 -36.500000000 -19.500000000 25.499996185 -36.499996185 -19.500000000 26.499954224 -36.499954224 -19.500000000 27.499591827 -36.499591827 -19.500000000 28.497470856 -36.497467041 -19.500000000 29.488407135 -36.488403320 -19.500000000 30.458978653 -36.458980560 -19.500000000 31.384418488 -36.384422302 -19.500000000 32.233222961 -36.233222961 -19.500000000 32.981101990 -35.981101990 -19.500000000 -35.167964935 -35.167964935 -19.500000000 -34.622871399 -35.622871399 -19.500000000 33.622871399 -35.622871399 -19.500000000 34.167964935 -35.167964935 -19.500000000 -35.981101990 -33.981101990 -19.500000000 -35.622871399 -34.622871399 -19.500000000 34.622871399 -34.622871399 -19.500000000 34.981101990 -33.981101990 -19.500000000 -36.233222961 -33.233222961 -19.500000000 35.233222961 -33.233226776 -19.500000000 -36.384418488 -32.384422302 -19.500000000 35.384418488 -32.384422302 -19.500000000 -36.458976746 -31.458978653 -19.500000000 35.458980560 -31.458978653 -19.500000000 -36.488403320 -30.488407135 -19.500000000 35.488403320 -30.488407135 -19.500000000 -36.497467041 -29.497472763 -19.500000000 35.497474670 -29.497472763 -19.500000000 -36.499591827 -28.499593735 -19.500000000 35.499591827 -28.499593735 -19.500000000 -36.499954224 -27.499954224 -19.500000000 35.499954224 -27.499954224 -19.500000000 -36.499996185 -26.499996185 -19.500000000 35.499996185 -26.499996185 -19.500000000 -36.500000000 -25.500000000 -19.500000000 35.500000000 -25.500000000 -19.500000000 -36.500000000 -24.500000000 -19.500000000 35.500000000 -24.500000000 -19.500000000 -36.500000000 -23.500000000 -19.500000000 35.500000000 -23.500000000 -19.500000000 -36.500000000 -22.500000000 -19.500000000 35.500000000 -22.500000000 -19.500000000 -36.500000000 -21.500000000 -19.500000000 35.500000000 -21.500000000 -19.500000000 -36.500000000 -20.500000000 -19.500000000 35.500000000 -20.500000000 -19.500000000 -36.500000000 -19.500000000 -19.500000000 35.500000000 -19.500000000 -19.500000000 -36.500000000 -18.500000000 -19.500000000 35.500000000 -18.500000000 -19.500000000 -36.500000000 -17.500000000 -19.500000000 35.500000000 -17.500000000 -19.500000000 -36.500000000 -16.500000000 -19.500000000 35.500000000 -16.500000000 -19.500000000 -36.500000000 -15.500000000 -19.500000000 35.500000000 -15.500000000 -19.500000000 -36.500000000 -14.500000000 -19.500000000 35.500000000 -14.500000000 -19.500000000 -36.500000000 -13.500000000 -19.500000000 35.500000000 -13.500000000 -19.500000000 -36.500000000 -12.500000000 -19.500000000 35.500000000 -12.500000000 -19.500000000 -36.500000000 -11.500000000 -19.500000000 35.500000000 -11.500000000 -19.500000000 -36.500000000 -10.500000000 -19.500000000 35.500000000 -10.500000000 -19.500000000 -36.500000000 -9.500000000 -19.500000000 35.500000000 -9.500000000 -19.500000000 -36.500000000 -8.500000000 -19.500000000 35.500000000 -8.500000000 -19.500000000 -36.500000000 -7.500000000 -19.500000000 35.500000000 -7.500000000 -19.500000000 -36.500000000 -6.500000000 -19.500000000 35.500000000 -6.500000000 -19.500000000 -36.500000000 -5.500000000 -19.500000000 35.500000000 -5.500000000 -19.500000000 -36.500000000 -4.500000000 -19.500000000 35.500000000 -4.500000000 -19.500000000 -36.500000000 -3.500000000 -19.500000000 35.500000000 -3.500000000 -19.500000000 -36.500000000 -2.500000000 -19.500000000 35.500000000 -2.500000000 -19.500000000 -36.500000000 -1.500000000 -19.500000000 35.500000000 -1.500000000 -19.500000000 -36.500000000 -0.500000000 -19.500000000 35.500000000 -0.500000000 -19.500000000 -36.500000000 0.500000000 -19.500000000 35.500000000 0.500000000 -19.500000000 -36.500000000 1.500000000 -19.500000000 35.500000000 1.500000000 -19.500000000 -36.500000000 2.500000000 -19.500000000 35.500000000 2.500000000 -19.500000000 -36.500000000 3.500000000 -19.500000000 35.500000000 3.500000000 -19.500000000 -36.500000000 4.500000000 -19.500000000 35.500000000 4.500000000 -19.500000000 -36.500000000 5.500000000 -19.500000000 35.500000000 5.500000000 -19.500000000 -36.500000000 6.500000000 -19.500000000 35.500000000 6.500000000 -19.500000000 -36.500000000 7.500000000 -19.500000000 35.500000000 7.500000000 -19.500000000 -36.500000000 8.500000000 -19.500000000 35.500000000 8.500000000 -19.500000000 -36.500000000 9.500000000 -19.500000000 35.500000000 9.500000000 -19.500000000 -36.500000000 10.500000000 -19.500000000 35.500000000 10.500000000 -19.500000000 -36.500000000 11.500000000 -19.500000000 35.500000000 11.500000000 -19.500000000 -36.500000000 12.500000000 -19.500000000 35.500000000 12.500000000 -19.500000000 -36.500000000 13.500000000 -19.500000000 35.500000000 13.500000000 -19.500000000 -36.500000000 14.500000000 -19.500000000 35.500000000 14.500000000 -19.500000000 -36.500000000 15.500000000 -19.500000000 35.500000000 15.500000000 -19.500000000 -36.500000000 16.500000000 -19.500000000 35.500000000 16.500000000 -19.500000000 -36.500000000 17.500000000 -19.500000000 35.500000000 17.500000000 -19.500000000 -36.500000000 18.500000000 -19.500000000 35.500000000 18.500000000 -19.500000000 -36.500000000 19.500000000 -19.500000000 35.500000000 19.500000000 -19.500000000 -36.500000000 20.500000000 -19.500000000 35.500000000 20.500000000 -19.500000000 -36.500000000 21.500000000 -19.500000000 35.500000000 21.500000000 -19.500000000 -36.500000000 22.500000000 -19.500000000 35.500000000 22.500000000 -19.500000000 -36.500000000 23.500000000 -19.500000000 35.500000000 23.500000000 -19.500000000 -36.500000000 24.500000000 -19.500000000 35.500000000 24.500000000 -19.500000000 -36.499996185 25.499996185 -19.500000000 35.499996185 25.499996185 -19.500000000 -36.499954224 26.499954224 -19.500000000 35.499954224 26.499954224 -19.500000000 -36.499591827 27.499591827 -19.500000000 35.499591827 27.499591827 -19.500000000 -36.497474670 28.497470856 -19.500000000 35.497467041 28.497470856 -19.500000000 -36.488403320 29.488407135 -19.500000000 35.488403320 29.488407135 -19.500000000 -36.458980560 30.458978653 -19.500000000 35.458980560 30.458978653 -19.500000000 -36.384422302 31.384418488 -19.500000000 35.384422302 31.384418488 -19.500000000 -36.233222961 32.233222961 -19.500000000 35.233222961 32.233222961 -19.500000000 -35.981101990 32.981101990 -19.500000000 -35.622871399 33.622871399 -19.500000000 34.622871399 33.622871399 -19.500000000 34.981101990 32.981101990 -19.500000000 -35.167964935 34.167964935 -19.500000000 -34.622871399 34.622871399 -19.500000000 33.622871399 34.622871399 -19.500000000 34.167964935 34.167964935 -19.500000000 -33.981101990 34.981101990 -19.500000000 -33.233222961 35.233222961 -19.500000000 -32.384422302 35.384418488 -19.500000000 -31.458978653 35.458976746 -19.500000000 -30.488407135 35.488403320 -19.500000000 -29.497472763 35.497467041 -19.500000000 -28.499593735 35.499591827 -19.500000000 -27.499954224 35.499954224 -19.500000000 -26.499996185 35.499996185 -19.500000000 -25.500000000 35.500000000 -19.500000000 -24.500000000 35.500000000 -19.500000000 -23.500000000 35.500000000 -19.500000000 -22.500000000 35.500000000 -19.500000000 -21.500000000 35.500000000 -19.500000000 -20.500000000 35.500000000 -19.500000000 -19.500000000 35.500000000 -19.500000000 -18.500000000 35.500000000 -19.500000000 -17.500000000 35.500000000 -19.500000000 -16.500000000 35.500000000 -19.500000000 -15.500000000 35.500000000 -19.500000000 -14.500000000 35.500000000 -19.500000000 -13.500000000 35.500000000 -19.500000000 -12.500000000 35.500000000 -19.500000000 -11.500000000 35.500000000 -19.500000000 -10.500000000 35.500000000 -19.500000000 -9.500000000 35.500000000 -19.500000000 -8.500000000 35.500000000 -19.500000000 -7.500000000 35.500000000 -19.500000000 -6.500000000 35.500000000 -19.500000000 -5.500000000 35.500000000 -19.500000000 -4.500000000 35.500000000 -19.500000000 -3.500000000 35.500000000 -19.500000000 -2.500000000 35.500000000 -19.500000000 -1.500000000 35.500000000 -19.500000000 -0.500000000 35.500000000 -19.500000000 0.500000000 35.500000000 -19.500000000 1.500000000 35.500000000 -19.500000000 2.500000000 35.500000000 -19.500000000 3.500000000 35.500000000 -19.500000000 4.500000000 35.500000000 -19.500000000 5.500000000 35.500000000 -19.500000000 6.500000000 35.500000000 -19.500000000 7.500000000 35.500000000 -19.500000000 8.500000000 35.500000000 -19.500000000 9.500000000 35.500000000 -19.500000000 10.500000000 35.500000000 -19.500000000 11.500000000 35.500000000 -19.500000000 12.500000000 35.500000000 -19.500000000 13.500000000 35.500000000 -19.500000000 14.500000000 35.500000000 -19.500000000 15.500000000 35.500000000 -19.500000000 16.500000000 35.500000000 -19.500000000 17.500000000 35.500000000 -19.500000000 18.500000000 35.500000000 -19.500000000 19.500000000 35.500000000 -19.500000000 20.500000000 35.500000000 -19.500000000 21.500000000 35.500000000 -19.500000000 22.500000000 35.500000000 -19.500000000 23.500000000 35.500000000 -19.500000000 24.500000000 35.500000000 -19.500000000 25.499996185 35.499996185 -19.500000000 26.499954224 35.499954224 -19.500000000 27.499591827 35.499591827 -19.500000000 28.497470856 35.497474670 -19.500000000 29.488407135 35.488403320 -19.500000000 30.458978653 35.458980560 -19.500000000 31.384418488 35.384422302 -19.500000000 32.233222961 35.233222961 -19.500000000 32.981101990 34.981101990 -19.500000000 -33.981101990 -35.981101990 -18.500000000 -33.233226776 -36.233222961 -18.500000000 -32.384422302 -36.384418488 -18.500000000 -31.458978653 -36.458980560 -18.500000000 -30.488407135 -36.488403320 -18.500000000 -29.497472763 -36.497474670 -18.500000000 -28.499593735 -36.499591827 -18.500000000 -27.499954224 -36.499954224 -18.500000000 -26.499996185 -36.499996185 -18.500000000 -25.500000000 -36.500000000 -18.500000000 -24.500000000 -36.500000000 -18.500000000 -23.500000000 -36.500000000 -18.500000000 -22.500000000 -36.500000000 -18.500000000 -21.500000000 -36.500000000 -18.500000000 -20.500000000 -36.500000000 -18.500000000 -19.500000000 -36.500000000 -18.500000000 -18.500000000 -36.500000000 -18.500000000 -17.500000000 -36.500000000 -18.500000000 -16.500000000 -36.500000000 -18.500000000 -15.500000000 -36.500000000 -18.500000000 -14.500000000 -36.500000000 -18.500000000 -13.500000000 -36.500000000 -18.500000000 -12.500000000 -36.500000000 -18.500000000 -11.500000000 -36.500000000 -18.500000000 -10.500000000 -36.500000000 -18.500000000 -9.500000000 -36.500000000 -18.500000000 -8.500000000 -36.500000000 -18.500000000 -7.500000000 -36.500000000 -18.500000000 -6.500000000 -36.500000000 -18.500000000 -5.500000000 -36.500000000 -18.500000000 -4.500000000 -36.500000000 -18.500000000 -3.500000000 -36.500000000 -18.500000000 -2.500000000 -36.500000000 -18.500000000 -1.500000000 -36.500000000 -18.500000000 -0.500000000 -36.500000000 -18.500000000 0.500000000 -36.500000000 -18.500000000 1.500000000 -36.500000000 -18.500000000 2.500000000 -36.500000000 -18.500000000 3.500000000 -36.500000000 -18.500000000 4.500000000 -36.500000000 -18.500000000 5.500000000 -36.500000000 -18.500000000 6.500000000 -36.500000000 -18.500000000 7.500000000 -36.500000000 -18.500000000 8.500000000 -36.500000000 -18.500000000 9.500000000 -36.500000000 -18.500000000 10.500000000 -36.500000000 -18.500000000 11.500000000 -36.500000000 -18.500000000 12.500000000 -36.500000000 -18.500000000 13.500000000 -36.500000000 -18.500000000 14.500000000 -36.500000000 -18.500000000 15.500000000 -36.500000000 -18.500000000 16.500000000 -36.500000000 -18.500000000 17.500000000 -36.500000000 -18.500000000 18.500000000 -36.500000000 -18.500000000 19.500000000 -36.500000000 -18.500000000 20.500000000 -36.500000000 -18.500000000 21.500000000 -36.500000000 -18.500000000 22.500000000 -36.500000000 -18.500000000 23.500000000 -36.500000000 -18.500000000 24.500000000 -36.500000000 -18.500000000 25.499996185 -36.499996185 -18.500000000 26.499954224 -36.499954224 -18.500000000 27.499591827 -36.499591827 -18.500000000 28.497470856 -36.497467041 -18.500000000 29.488407135 -36.488403320 -18.500000000 30.458978653 -36.458980560 -18.500000000 31.384418488 -36.384422302 -18.500000000 32.233222961 -36.233222961 -18.500000000 32.981101990 -35.981101990 -18.500000000 -35.167964935 -35.167964935 -18.500000000 -34.622871399 -35.622871399 -18.500000000 33.622871399 -35.622871399 -18.500000000 34.167964935 -35.167964935 -18.500000000 -35.981101990 -33.981101990 -18.500000000 -35.622871399 -34.622871399 -18.500000000 34.622871399 -34.622871399 -18.500000000 34.981101990 -33.981101990 -18.500000000 -36.233222961 -33.233222961 -18.500000000 35.233222961 -33.233226776 -18.500000000 -36.384418488 -32.384422302 -18.500000000 35.384418488 -32.384422302 -18.500000000 -36.458976746 -31.458978653 -18.500000000 35.458980560 -31.458978653 -18.500000000 -36.488403320 -30.488407135 -18.500000000 35.488403320 -30.488407135 -18.500000000 -36.497467041 -29.497472763 -18.500000000 35.497474670 -29.497472763 -18.500000000 -36.499591827 -28.499593735 -18.500000000 35.499591827 -28.499593735 -18.500000000 -36.499954224 -27.499954224 -18.500000000 35.499954224 -27.499954224 -18.500000000 -36.499996185 -26.499996185 -18.500000000 35.499996185 -26.499996185 -18.500000000 -36.500000000 -25.500000000 -18.500000000 35.500000000 -25.500000000 -18.500000000 -36.500000000 -24.500000000 -18.500000000 35.500000000 -24.500000000 -18.500000000 -36.500000000 -23.500000000 -18.500000000 35.500000000 -23.500000000 -18.500000000 -36.500000000 -22.500000000 -18.500000000 35.500000000 -22.500000000 -18.500000000 -36.500000000 -21.500000000 -18.500000000 35.500000000 -21.500000000 -18.500000000 -36.500000000 -20.500000000 -18.500000000 35.500000000 -20.500000000 -18.500000000 -36.500000000 -19.500000000 -18.500000000 35.500000000 -19.500000000 -18.500000000 -36.500000000 -18.500000000 -18.500000000 35.500000000 -18.500000000 -18.500000000 -36.500000000 -17.500000000 -18.500000000 35.500000000 -17.500000000 -18.500000000 -36.500000000 -16.500000000 -18.500000000 35.500000000 -16.500000000 -18.500000000 -36.500000000 -15.500000000 -18.500000000 35.500000000 -15.500000000 -18.500000000 -36.500000000 -14.500000000 -18.500000000 35.500000000 -14.500000000 -18.500000000 -36.500000000 -13.500000000 -18.500000000 35.500000000 -13.500000000 -18.500000000 -36.500000000 -12.500000000 -18.500000000 35.500000000 -12.500000000 -18.500000000 -36.500000000 -11.500000000 -18.500000000 35.500000000 -11.500000000 -18.500000000 -36.500000000 -10.500000000 -18.500000000 35.500000000 -10.500000000 -18.500000000 -36.500000000 -9.500000000 -18.500000000 35.500000000 -9.500000000 -18.500000000 -36.500000000 -8.500000000 -18.500000000 35.500000000 -8.500000000 -18.500000000 -36.500000000 -7.500000000 -18.500000000 35.500000000 -7.500000000 -18.500000000 -36.500000000 -6.500000000 -18.500000000 35.500000000 -6.500000000 -18.500000000 -36.500000000 -5.500000000 -18.500000000 35.500000000 -5.500000000 -18.500000000 -36.500000000 -4.500000000 -18.500000000 35.500000000 -4.500000000 -18.500000000 -36.500000000 -3.500000000 -18.500000000 35.500000000 -3.500000000 -18.500000000 -36.500000000 -2.500000000 -18.500000000 35.500000000 -2.500000000 -18.500000000 -36.500000000 -1.500000000 -18.500000000 35.500000000 -1.500000000 -18.500000000 -36.500000000 -0.500000000 -18.500000000 35.500000000 -0.500000000 -18.500000000 -36.500000000 0.500000000 -18.500000000 35.500000000 0.500000000 -18.500000000 -36.500000000 1.500000000 -18.500000000 35.500000000 1.500000000 -18.500000000 -36.500000000 2.500000000 -18.500000000 35.500000000 2.500000000 -18.500000000 -36.500000000 3.500000000 -18.500000000 35.500000000 3.500000000 -18.500000000 -36.500000000 4.500000000 -18.500000000 35.500000000 4.500000000 -18.500000000 -36.500000000 5.500000000 -18.500000000 35.500000000 5.500000000 -18.500000000 -36.500000000 6.500000000 -18.500000000 35.500000000 6.500000000 -18.500000000 -36.500000000 7.500000000 -18.500000000 35.500000000 7.500000000 -18.500000000 -36.500000000 8.500000000 -18.500000000 35.500000000 8.500000000 -18.500000000 -36.500000000 9.500000000 -18.500000000 35.500000000 9.500000000 -18.500000000 -36.500000000 10.500000000 -18.500000000 35.500000000 10.500000000 -18.500000000 -36.500000000 11.500000000 -18.500000000 35.500000000 11.500000000 -18.500000000 -36.500000000 12.500000000 -18.500000000 35.500000000 12.500000000 -18.500000000 -36.500000000 13.500000000 -18.500000000 35.500000000 13.500000000 -18.500000000 -36.500000000 14.500000000 -18.500000000 35.500000000 14.500000000 -18.500000000 -36.500000000 15.500000000 -18.500000000 35.500000000 15.500000000 -18.500000000 -36.500000000 16.500000000 -18.500000000 35.500000000 16.500000000 -18.500000000 -36.500000000 17.500000000 -18.500000000 35.500000000 17.500000000 -18.500000000 -36.500000000 18.500000000 -18.500000000 35.500000000 18.500000000 -18.500000000 -36.500000000 19.500000000 -18.500000000 35.500000000 19.500000000 -18.500000000 -36.500000000 20.500000000 -18.500000000 35.500000000 20.500000000 -18.500000000 -36.500000000 21.500000000 -18.500000000 35.500000000 21.500000000 -18.500000000 -36.500000000 22.500000000 -18.500000000 35.500000000 22.500000000 -18.500000000 -36.500000000 23.500000000 -18.500000000 35.500000000 23.500000000 -18.500000000 -36.500000000 24.500000000 -18.500000000 35.500000000 24.500000000 -18.500000000 -36.499996185 25.499996185 -18.500000000 35.499996185 25.499996185 -18.500000000 -36.499954224 26.499954224 -18.500000000 35.499954224 26.499954224 -18.500000000 -36.499591827 27.499591827 -18.500000000 35.499591827 27.499591827 -18.500000000 -36.497474670 28.497470856 -18.500000000 35.497467041 28.497470856 -18.500000000 -36.488403320 29.488407135 -18.500000000 35.488403320 29.488407135 -18.500000000 -36.458980560 30.458978653 -18.500000000 35.458980560 30.458978653 -18.500000000 -36.384422302 31.384418488 -18.500000000 35.384422302 31.384418488 -18.500000000 -36.233222961 32.233222961 -18.500000000 35.233222961 32.233222961 -18.500000000 -35.981101990 32.981101990 -18.500000000 -35.622871399 33.622871399 -18.500000000 34.622871399 33.622871399 -18.500000000 34.981101990 32.981101990 -18.500000000 -35.167964935 34.167964935 -18.500000000 -34.622871399 34.622871399 -18.500000000 33.622871399 34.622871399 -18.500000000 34.167964935 34.167964935 -18.500000000 -33.981101990 34.981101990 -18.500000000 -33.233222961 35.233222961 -18.500000000 -32.384422302 35.384418488 -18.500000000 -31.458978653 35.458976746 -18.500000000 -30.488407135 35.488403320 -18.500000000 -29.497472763 35.497467041 -18.500000000 -28.499593735 35.499591827 -18.500000000 -27.499954224 35.499954224 -18.500000000 -26.499996185 35.499996185 -18.500000000 -25.500000000 35.500000000 -18.500000000 -24.500000000 35.500000000 -18.500000000 -23.500000000 35.500000000 -18.500000000 -22.500000000 35.500000000 -18.500000000 -21.500000000 35.500000000 -18.500000000 -20.500000000 35.500000000 -18.500000000 -19.500000000 35.500000000 -18.500000000 -18.500000000 35.500000000 -18.500000000 -17.500000000 35.500000000 -18.500000000 -16.500000000 35.500000000 -18.500000000 -15.500000000 35.500000000 -18.500000000 -14.500000000 35.500000000 -18.500000000 -13.500000000 35.500000000 -18.500000000 -12.500000000 35.500000000 -18.500000000 -11.500000000 35.500000000 -18.500000000 -10.500000000 35.500000000 -18.500000000 -9.500000000 35.500000000 -18.500000000 -8.500000000 35.500000000 -18.500000000 -7.500000000 35.500000000 -18.500000000 -6.500000000 35.500000000 -18.500000000 -5.500000000 35.500000000 -18.500000000 -4.500000000 35.500000000 -18.500000000 -3.500000000 35.500000000 -18.500000000 -2.500000000 35.500000000 -18.500000000 -1.500000000 35.500000000 -18.500000000 -0.500000000 35.500000000 -18.500000000 0.500000000 35.500000000 -18.500000000 1.500000000 35.500000000 -18.500000000 2.500000000 35.500000000 -18.500000000 3.500000000 35.500000000 -18.500000000 4.500000000 35.500000000 -18.500000000 5.500000000 35.500000000 -18.500000000 6.500000000 35.500000000 -18.500000000 7.500000000 35.500000000 -18.500000000 8.500000000 35.500000000 -18.500000000 9.500000000 35.500000000 -18.500000000 10.500000000 35.500000000 -18.500000000 11.500000000 35.500000000 -18.500000000 12.500000000 35.500000000 -18.500000000 13.500000000 35.500000000 -18.500000000 14.500000000 35.500000000 -18.500000000 15.500000000 35.500000000 -18.500000000 16.500000000 35.500000000 -18.500000000 17.500000000 35.500000000 -18.500000000 18.500000000 35.500000000 -18.500000000 19.500000000 35.500000000 -18.500000000 20.500000000 35.500000000 -18.500000000 21.500000000 35.500000000 -18.500000000 22.500000000 35.500000000 -18.500000000 23.500000000 35.500000000 -18.500000000 24.500000000 35.500000000 -18.500000000 25.499996185 35.499996185 -18.500000000 26.499954224 35.499954224 -18.500000000 27.499591827 35.499591827 -18.500000000 28.497470856 35.497474670 -18.500000000 29.488407135 35.488403320 -18.500000000 30.458978653 35.458980560 -18.500000000 31.384418488 35.384422302 -18.500000000 32.233222961 35.233222961 -18.500000000 32.981101990 34.981101990 -18.500000000 -33.981101990 -35.981101990 -17.500000000 -33.233226776 -36.233222961 -17.500000000 -32.384422302 -36.384418488 -17.500000000 -31.458978653 -36.458980560 -17.500000000 -30.488407135 -36.488403320 -17.500000000 -29.497472763 -36.497474670 -17.500000000 -28.499593735 -36.499591827 -17.500000000 -27.499954224 -36.499954224 -17.500000000 -26.499996185 -36.499996185 -17.500000000 -25.500000000 -36.500000000 -17.500000000 -24.500000000 -36.500000000 -17.500000000 -23.500000000 -36.500000000 -17.500000000 -22.500000000 -36.500000000 -17.500000000 -21.500000000 -36.500000000 -17.500000000 -20.500000000 -36.500000000 -17.500000000 -19.500000000 -36.500000000 -17.500000000 -18.500000000 -36.500000000 -17.500000000 -17.500000000 -36.500000000 -17.500000000 -16.500000000 -36.500000000 -17.500000000 -15.500000000 -36.500000000 -17.500000000 -14.500000000 -36.500000000 -17.500000000 -13.500000000 -36.500000000 -17.500000000 -12.500000000 -36.500000000 -17.500000000 -11.500000000 -36.500000000 -17.500000000 -10.500000000 -36.500000000 -17.500000000 -9.500000000 -36.500000000 -17.500000000 -8.500000000 -36.500000000 -17.500000000 -7.500000000 -36.500000000 -17.500000000 -6.500000000 -36.500000000 -17.500000000 -5.500000000 -36.500000000 -17.500000000 -4.500000000 -36.500000000 -17.500000000 -3.500000000 -36.500000000 -17.500000000 -2.500000000 -36.500000000 -17.500000000 -1.500000000 -36.500000000 -17.500000000 -0.500000000 -36.500000000 -17.500000000 0.500000000 -36.500000000 -17.500000000 1.500000000 -36.500000000 -17.500000000 2.500000000 -36.500000000 -17.500000000 3.500000000 -36.500000000 -17.500000000 4.500000000 -36.500000000 -17.500000000 5.500000000 -36.500000000 -17.500000000 6.500000000 -36.500000000 -17.500000000 7.500000000 -36.500000000 -17.500000000 8.500000000 -36.500000000 -17.500000000 9.500000000 -36.500000000 -17.500000000 10.500000000 -36.500000000 -17.500000000 11.500000000 -36.500000000 -17.500000000 12.500000000 -36.500000000 -17.500000000 13.500000000 -36.500000000 -17.500000000 14.500000000 -36.500000000 -17.500000000 15.500000000 -36.500000000 -17.500000000 16.500000000 -36.500000000 -17.500000000 17.500000000 -36.500000000 -17.500000000 18.500000000 -36.500000000 -17.500000000 19.500000000 -36.500000000 -17.500000000 20.500000000 -36.500000000 -17.500000000 21.500000000 -36.500000000 -17.500000000 22.500000000 -36.500000000 -17.500000000 23.500000000 -36.500000000 -17.500000000 24.500000000 -36.500000000 -17.500000000 25.499996185 -36.499996185 -17.500000000 26.499954224 -36.499954224 -17.500000000 27.499591827 -36.499591827 -17.500000000 28.497470856 -36.497467041 -17.500000000 29.488407135 -36.488403320 -17.500000000 30.458978653 -36.458980560 -17.500000000 31.384418488 -36.384422302 -17.500000000 32.233222961 -36.233222961 -17.500000000 32.981101990 -35.981101990 -17.500000000 -35.167964935 -35.167964935 -17.500000000 -34.622871399 -35.622871399 -17.500000000 33.622871399 -35.622871399 -17.500000000 34.167964935 -35.167964935 -17.500000000 -35.981101990 -33.981101990 -17.500000000 -35.622871399 -34.622871399 -17.500000000 34.622871399 -34.622871399 -17.500000000 34.981101990 -33.981101990 -17.500000000 -36.233222961 -33.233222961 -17.500000000 35.233222961 -33.233226776 -17.500000000 -36.384418488 -32.384422302 -17.500000000 35.384418488 -32.384422302 -17.500000000 -36.458976746 -31.458978653 -17.500000000 35.458980560 -31.458978653 -17.500000000 -36.488403320 -30.488407135 -17.500000000 35.488403320 -30.488407135 -17.500000000 -36.497467041 -29.497472763 -17.500000000 35.497474670 -29.497472763 -17.500000000 -36.499591827 -28.499593735 -17.500000000 35.499591827 -28.499593735 -17.500000000 -36.499954224 -27.499954224 -17.500000000 35.499954224 -27.499954224 -17.500000000 -36.499996185 -26.499996185 -17.500000000 35.499996185 -26.499996185 -17.500000000 -36.500000000 -25.500000000 -17.500000000 35.500000000 -25.500000000 -17.500000000 -36.500000000 -24.500000000 -17.500000000 35.500000000 -24.500000000 -17.500000000 -36.500000000 -23.500000000 -17.500000000 35.500000000 -23.500000000 -17.500000000 -36.500000000 -22.500000000 -17.500000000 35.500000000 -22.500000000 -17.500000000 -36.500000000 -21.500000000 -17.500000000 35.500000000 -21.500000000 -17.500000000 -36.500000000 -20.500000000 -17.500000000 35.500000000 -20.500000000 -17.500000000 -36.500000000 -19.500000000 -17.500000000 35.500000000 -19.500000000 -17.500000000 -36.500000000 -18.500000000 -17.500000000 35.500000000 -18.500000000 -17.500000000 -36.500000000 -17.500000000 -17.500000000 35.500000000 -17.500000000 -17.500000000 -36.500000000 -16.500000000 -17.500000000 35.500000000 -16.500000000 -17.500000000 -36.500000000 -15.500000000 -17.500000000 35.500000000 -15.500000000 -17.500000000 -36.500000000 -14.500000000 -17.500000000 35.500000000 -14.500000000 -17.500000000 -36.500000000 -13.500000000 -17.500000000 35.500000000 -13.500000000 -17.500000000 -36.500000000 -12.500000000 -17.500000000 35.500000000 -12.500000000 -17.500000000 -36.500000000 -11.500000000 -17.500000000 35.500000000 -11.500000000 -17.500000000 -36.500000000 -10.500000000 -17.500000000 35.500000000 -10.500000000 -17.500000000 -36.500000000 -9.500000000 -17.500000000 35.500000000 -9.500000000 -17.500000000 -36.500000000 -8.500000000 -17.500000000 35.500000000 -8.500000000 -17.500000000 -36.500000000 -7.500000000 -17.500000000 35.500000000 -7.500000000 -17.500000000 -36.500000000 -6.500000000 -17.500000000 35.500000000 -6.500000000 -17.500000000 -36.500000000 -5.500000000 -17.500000000 35.500000000 -5.500000000 -17.500000000 -36.500000000 -4.500000000 -17.500000000 35.500000000 -4.500000000 -17.500000000 -36.500000000 -3.500000000 -17.500000000 35.500000000 -3.500000000 -17.500000000 -36.500000000 -2.500000000 -17.500000000 35.500000000 -2.500000000 -17.500000000 -36.500000000 -1.500000000 -17.500000000 35.500000000 -1.500000000 -17.500000000 -36.500000000 -0.500000000 -17.500000000 35.500000000 -0.500000000 -17.500000000 -36.500000000 0.500000000 -17.500000000 35.500000000 0.500000000 -17.500000000 -36.500000000 1.500000000 -17.500000000 35.500000000 1.500000000 -17.500000000 -36.500000000 2.500000000 -17.500000000 35.500000000 2.500000000 -17.500000000 -36.500000000 3.500000000 -17.500000000 35.500000000 3.500000000 -17.500000000 -36.500000000 4.500000000 -17.500000000 35.500000000 4.500000000 -17.500000000 -36.500000000 5.500000000 -17.500000000 35.500000000 5.500000000 -17.500000000 -36.500000000 6.500000000 -17.500000000 35.500000000 6.500000000 -17.500000000 -36.500000000 7.500000000 -17.500000000 35.500000000 7.500000000 -17.500000000 -36.500000000 8.500000000 -17.500000000 35.500000000 8.500000000 -17.500000000 -36.500000000 9.500000000 -17.500000000 35.500000000 9.500000000 -17.500000000 -36.500000000 10.500000000 -17.500000000 35.500000000 10.500000000 -17.500000000 -36.500000000 11.500000000 -17.500000000 35.500000000 11.500000000 -17.500000000 -36.500000000 12.500000000 -17.500000000 35.500000000 12.500000000 -17.500000000 -36.500000000 13.500000000 -17.500000000 35.500000000 13.500000000 -17.500000000 -36.500000000 14.500000000 -17.500000000 35.500000000 14.500000000 -17.500000000 -36.500000000 15.500000000 -17.500000000 35.500000000 15.500000000 -17.500000000 -36.500000000 16.500000000 -17.500000000 35.500000000 16.500000000 -17.500000000 -36.500000000 17.500000000 -17.500000000 35.500000000 17.500000000 -17.500000000 -36.500000000 18.500000000 -17.500000000 35.500000000 18.500000000 -17.500000000 -36.500000000 19.500000000 -17.500000000 35.500000000 19.500000000 -17.500000000 -36.500000000 20.500000000 -17.500000000 35.500000000 20.500000000 -17.500000000 -36.500000000 21.500000000 -17.500000000 35.500000000 21.500000000 -17.500000000 -36.500000000 22.500000000 -17.500000000 35.500000000 22.500000000 -17.500000000 -36.500000000 23.500000000 -17.500000000 35.500000000 23.500000000 -17.500000000 -36.500000000 24.500000000 -17.500000000 35.500000000 24.500000000 -17.500000000 -36.499996185 25.499996185 -17.500000000 35.499996185 25.499996185 -17.500000000 -36.499954224 26.499954224 -17.500000000 35.499954224 26.499954224 -17.500000000 -36.499591827 27.499591827 -17.500000000 35.499591827 27.499591827 -17.500000000 -36.497474670 28.497470856 -17.500000000 35.497467041 28.497470856 -17.500000000 -36.488403320 29.488407135 -17.500000000 35.488403320 29.488407135 -17.500000000 -36.458980560 30.458978653 -17.500000000 35.458980560 30.458978653 -17.500000000 -36.384422302 31.384418488 -17.500000000 35.384422302 31.384418488 -17.500000000 -36.233222961 32.233222961 -17.500000000 35.233222961 32.233222961 -17.500000000 -35.981101990 32.981101990 -17.500000000 -35.622871399 33.622871399 -17.500000000 34.622871399 33.622871399 -17.500000000 34.981101990 32.981101990 -17.500000000 -35.167964935 34.167964935 -17.500000000 -34.622871399 34.622871399 -17.500000000 33.622871399 34.622871399 -17.500000000 34.167964935 34.167964935 -17.500000000 -33.981101990 34.981101990 -17.500000000 -33.233222961 35.233222961 -17.500000000 -32.384422302 35.384418488 -17.500000000 -31.458978653 35.458976746 -17.500000000 -30.488407135 35.488403320 -17.500000000 -29.497472763 35.497467041 -17.500000000 -28.499593735 35.499591827 -17.500000000 -27.499954224 35.499954224 -17.500000000 -26.499996185 35.499996185 -17.500000000 -25.500000000 35.500000000 -17.500000000 -24.500000000 35.500000000 -17.500000000 -23.500000000 35.500000000 -17.500000000 -22.500000000 35.500000000 -17.500000000 -21.500000000 35.500000000 -17.500000000 -20.500000000 35.500000000 -17.500000000 -19.500000000 35.500000000 -17.500000000 -18.500000000 35.500000000 -17.500000000 -17.500000000 35.500000000 -17.500000000 -16.500000000 35.500000000 -17.500000000 -15.500000000 35.500000000 -17.500000000 -14.500000000 35.500000000 -17.500000000 -13.500000000 35.500000000 -17.500000000 -12.500000000 35.500000000 -17.500000000 -11.500000000 35.500000000 -17.500000000 -10.500000000 35.500000000 -17.500000000 -9.500000000 35.500000000 -17.500000000 -8.500000000 35.500000000 -17.500000000 -7.500000000 35.500000000 -17.500000000 -6.500000000 35.500000000 -17.500000000 -5.500000000 35.500000000 -17.500000000 -4.500000000 35.500000000 -17.500000000 -3.500000000 35.500000000 -17.500000000 -2.500000000 35.500000000 -17.500000000 -1.500000000 35.500000000 -17.500000000 -0.500000000 35.500000000 -17.500000000 0.500000000 35.500000000 -17.500000000 1.500000000 35.500000000 -17.500000000 2.500000000 35.500000000 -17.500000000 3.500000000 35.500000000 -17.500000000 4.500000000 35.500000000 -17.500000000 5.500000000 35.500000000 -17.500000000 6.500000000 35.500000000 -17.500000000 7.500000000 35.500000000 -17.500000000 8.500000000 35.500000000 -17.500000000 9.500000000 35.500000000 -17.500000000 10.500000000 35.500000000 -17.500000000 11.500000000 35.500000000 -17.500000000 12.500000000 35.500000000 -17.500000000 13.500000000 35.500000000 -17.500000000 14.500000000 35.500000000 -17.500000000 15.500000000 35.500000000 -17.500000000 16.500000000 35.500000000 -17.500000000 17.500000000 35.500000000 -17.500000000 18.500000000 35.500000000 -17.500000000 19.500000000 35.500000000 -17.500000000 20.500000000 35.500000000 -17.500000000 21.500000000 35.500000000 -17.500000000 22.500000000 35.500000000 -17.500000000 23.500000000 35.500000000 -17.500000000 24.500000000 35.500000000 -17.500000000 25.499996185 35.499996185 -17.500000000 26.499954224 35.499954224 -17.500000000 27.499591827 35.499591827 -17.500000000 28.497470856 35.497474670 -17.500000000 29.488407135 35.488403320 -17.500000000 30.458978653 35.458980560 -17.500000000 31.384418488 35.384422302 -17.500000000 32.233222961 35.233222961 -17.500000000 32.981101990 34.981101990 -17.500000000 -33.981101990 -35.981101990 -16.500000000 -33.233226776 -36.233222961 -16.500000000 -32.384422302 -36.384418488 -16.500000000 -31.458978653 -36.458980560 -16.500000000 -30.488407135 -36.488403320 -16.500000000 -29.497472763 -36.497474670 -16.500000000 -28.499593735 -36.499591827 -16.500000000 -27.499954224 -36.499954224 -16.500000000 -26.499996185 -36.499996185 -16.500000000 -25.500000000 -36.500000000 -16.500000000 -24.500000000 -36.500000000 -16.500000000 -23.500000000 -36.500000000 -16.500000000 -22.500000000 -36.500000000 -16.500000000 -21.500000000 -36.500000000 -16.500000000 -20.500000000 -36.500000000 -16.500000000 -19.500000000 -36.500000000 -16.500000000 -18.500000000 -36.500000000 -16.500000000 -17.500000000 -36.500000000 -16.500000000 -16.500000000 -36.500000000 -16.500000000 -15.500000000 -36.500000000 -16.500000000 -14.500000000 -36.500000000 -16.500000000 -13.500000000 -36.500000000 -16.500000000 -12.500000000 -36.500000000 -16.500000000 -11.500000000 -36.500000000 -16.500000000 -10.500000000 -36.500000000 -16.500000000 -9.500000000 -36.500000000 -16.500000000 -8.500000000 -36.500000000 -16.500000000 -7.500000000 -36.500000000 -16.500000000 -6.500000000 -36.500000000 -16.500000000 -5.500000000 -36.500000000 -16.500000000 -4.500000000 -36.500000000 -16.500000000 -3.500000000 -36.500000000 -16.500000000 -2.500000000 -36.500000000 -16.500000000 -1.500000000 -36.500000000 -16.500000000 -0.500000000 -36.500000000 -16.500000000 0.500000000 -36.500000000 -16.500000000 1.500000000 -36.500000000 -16.500000000 2.500000000 -36.500000000 -16.500000000 3.500000000 -36.500000000 -16.500000000 4.500000000 -36.500000000 -16.500000000 5.500000000 -36.500000000 -16.500000000 6.500000000 -36.500000000 -16.500000000 7.500000000 -36.500000000 -16.500000000 8.500000000 -36.500000000 -16.500000000 9.500000000 -36.500000000 -16.500000000 10.500000000 -36.500000000 -16.500000000 11.500000000 -36.500000000 -16.500000000 12.500000000 -36.500000000 -16.500000000 13.500000000 -36.500000000 -16.500000000 14.500000000 -36.500000000 -16.500000000 15.500000000 -36.500000000 -16.500000000 16.500000000 -36.500000000 -16.500000000 17.500000000 -36.500000000 -16.500000000 18.500000000 -36.500000000 -16.500000000 19.500000000 -36.500000000 -16.500000000 20.500000000 -36.500000000 -16.500000000 21.500000000 -36.500000000 -16.500000000 22.500000000 -36.500000000 -16.500000000 23.500000000 -36.500000000 -16.500000000 24.500000000 -36.500000000 -16.500000000 25.499996185 -36.499996185 -16.500000000 26.499954224 -36.499954224 -16.500000000 27.499591827 -36.499591827 -16.500000000 28.497470856 -36.497467041 -16.500000000 29.488407135 -36.488403320 -16.500000000 30.458978653 -36.458980560 -16.500000000 31.384418488 -36.384422302 -16.500000000 32.233222961 -36.233222961 -16.500000000 32.981101990 -35.981101990 -16.500000000 -35.167964935 -35.167964935 -16.500000000 -34.622871399 -35.622871399 -16.500000000 33.622871399 -35.622871399 -16.500000000 34.167964935 -35.167964935 -16.500000000 -35.981101990 -33.981101990 -16.500000000 -35.622871399 -34.622871399 -16.500000000 34.622871399 -34.622871399 -16.500000000 34.981101990 -33.981101990 -16.500000000 -36.233222961 -33.233222961 -16.500000000 35.233222961 -33.233226776 -16.500000000 -36.384418488 -32.384422302 -16.500000000 35.384418488 -32.384422302 -16.500000000 -36.458976746 -31.458978653 -16.500000000 35.458980560 -31.458978653 -16.500000000 -36.488403320 -30.488407135 -16.500000000 35.488403320 -30.488407135 -16.500000000 -36.497467041 -29.497472763 -16.500000000 35.497474670 -29.497472763 -16.500000000 -36.499591827 -28.499593735 -16.500000000 35.499591827 -28.499593735 -16.500000000 -36.499954224 -27.499954224 -16.500000000 35.499954224 -27.499954224 -16.500000000 -36.499996185 -26.499996185 -16.500000000 35.499996185 -26.499996185 -16.500000000 -36.500000000 -25.500000000 -16.500000000 35.500000000 -25.500000000 -16.500000000 -36.500000000 -24.500000000 -16.500000000 35.500000000 -24.500000000 -16.500000000 -36.500000000 -23.500000000 -16.500000000 35.500000000 -23.500000000 -16.500000000 -36.500000000 -22.500000000 -16.500000000 35.500000000 -22.500000000 -16.500000000 -36.500000000 -21.500000000 -16.500000000 35.500000000 -21.500000000 -16.500000000 -36.500000000 -20.500000000 -16.500000000 35.500000000 -20.500000000 -16.500000000 -36.500000000 -19.500000000 -16.500000000 35.500000000 -19.500000000 -16.500000000 -36.500000000 -18.500000000 -16.500000000 35.500000000 -18.500000000 -16.500000000 -36.500000000 -17.500000000 -16.500000000 35.500000000 -17.500000000 -16.500000000 -36.500000000 -16.500000000 -16.500000000 35.500000000 -16.500000000 -16.500000000 -36.500000000 -15.500000000 -16.500000000 35.500000000 -15.500000000 -16.500000000 -36.500000000 -14.500000000 -16.500000000 35.500000000 -14.500000000 -16.500000000 -36.500000000 -13.500000000 -16.500000000 35.500000000 -13.500000000 -16.500000000 -36.500000000 -12.500000000 -16.500000000 35.500000000 -12.500000000 -16.500000000 -36.500000000 -11.500000000 -16.500000000 35.500000000 -11.500000000 -16.500000000 -36.500000000 -10.500000000 -16.500000000 35.500000000 -10.500000000 -16.500000000 -36.500000000 -9.500000000 -16.500000000 35.500000000 -9.500000000 -16.500000000 -36.500000000 -8.500000000 -16.500000000 35.500000000 -8.500000000 -16.500000000 -36.500000000 -7.500000000 -16.500000000 35.500000000 -7.500000000 -16.500000000 -36.500000000 -6.500000000 -16.500000000 35.500000000 -6.500000000 -16.500000000 -36.500000000 -5.500000000 -16.500000000 35.500000000 -5.500000000 -16.500000000 -36.500000000 -4.500000000 -16.500000000 35.500000000 -4.500000000 -16.500000000 -36.500000000 -3.500000000 -16.500000000 35.500000000 -3.500000000 -16.500000000 -36.500000000 -2.500000000 -16.500000000 35.500000000 -2.500000000 -16.500000000 -36.500000000 -1.500000000 -16.500000000 35.500000000 -1.500000000 -16.500000000 -36.500000000 -0.500000000 -16.500000000 35.500000000 -0.500000000 -16.500000000 -36.500000000 0.500000000 -16.500000000 35.500000000 0.500000000 -16.500000000 -36.500000000 1.500000000 -16.500000000 35.500000000 1.500000000 -16.500000000 -36.500000000 2.500000000 -16.500000000 35.500000000 2.500000000 -16.500000000 -36.500000000 3.500000000 -16.500000000 35.500000000 3.500000000 -16.500000000 -36.500000000 4.500000000 -16.500000000 35.500000000 4.500000000 -16.500000000 -36.500000000 5.500000000 -16.500000000 35.500000000 5.500000000 -16.500000000 -36.500000000 6.500000000 -16.500000000 35.500000000 6.500000000 -16.500000000 -36.500000000 7.500000000 -16.500000000 35.500000000 7.500000000 -16.500000000 -36.500000000 8.500000000 -16.500000000 35.500000000 8.500000000 -16.500000000 -36.500000000 9.500000000 -16.500000000 35.500000000 9.500000000 -16.500000000 -36.500000000 10.500000000 -16.500000000 35.500000000 10.500000000 -16.500000000 -36.500000000 11.500000000 -16.500000000 35.500000000 11.500000000 -16.500000000 -36.500000000 12.500000000 -16.500000000 35.500000000 12.500000000 -16.500000000 -36.500000000 13.500000000 -16.500000000 35.500000000 13.500000000 -16.500000000 -36.500000000 14.500000000 -16.500000000 35.500000000 14.500000000 -16.500000000 -36.500000000 15.500000000 -16.500000000 35.500000000 15.500000000 -16.500000000 -36.500000000 16.500000000 -16.500000000 35.500000000 16.500000000 -16.500000000 -36.500000000 17.500000000 -16.500000000 35.500000000 17.500000000 -16.500000000 -36.500000000 18.500000000 -16.500000000 35.500000000 18.500000000 -16.500000000 -36.500000000 19.500000000 -16.500000000 35.500000000 19.500000000 -16.500000000 -36.500000000 20.500000000 -16.500000000 35.500000000 20.500000000 -16.500000000 -36.500000000 21.500000000 -16.500000000 35.500000000 21.500000000 -16.500000000 -36.500000000 22.500000000 -16.500000000 35.500000000 22.500000000 -16.500000000 -36.500000000 23.500000000 -16.500000000 35.500000000 23.500000000 -16.500000000 -36.500000000 24.500000000 -16.500000000 35.500000000 24.500000000 -16.500000000 -36.499996185 25.499996185 -16.500000000 35.499996185 25.499996185 -16.500000000 -36.499954224 26.499954224 -16.500000000 35.499954224 26.499954224 -16.500000000 -36.499591827 27.499591827 -16.500000000 35.499591827 27.499591827 -16.500000000 -36.497474670 28.497470856 -16.500000000 35.497467041 28.497470856 -16.500000000 -36.488403320 29.488407135 -16.500000000 35.488403320 29.488407135 -16.500000000 -36.458980560 30.458978653 -16.500000000 35.458980560 30.458978653 -16.500000000 -36.384422302 31.384418488 -16.500000000 35.384422302 31.384418488 -16.500000000 -36.233222961 32.233222961 -16.500000000 35.233222961 32.233222961 -16.500000000 -35.981101990 32.981101990 -16.500000000 -35.622871399 33.622871399 -16.500000000 34.622871399 33.622871399 -16.500000000 34.981101990 32.981101990 -16.500000000 -35.167964935 34.167964935 -16.500000000 -34.622871399 34.622871399 -16.500000000 33.622871399 34.622871399 -16.500000000 34.167964935 34.167964935 -16.500000000 -33.981101990 34.981101990 -16.500000000 -33.233222961 35.233222961 -16.500000000 -32.384422302 35.384418488 -16.500000000 -31.458978653 35.458976746 -16.500000000 -30.488407135 35.488403320 -16.500000000 -29.497472763 35.497467041 -16.500000000 -28.499593735 35.499591827 -16.500000000 -27.499954224 35.499954224 -16.500000000 -26.499996185 35.499996185 -16.500000000 -25.500000000 35.500000000 -16.500000000 -24.500000000 35.500000000 -16.500000000 -23.500000000 35.500000000 -16.500000000 -22.500000000 35.500000000 -16.500000000 -21.500000000 35.500000000 -16.500000000 -20.500000000 35.500000000 -16.500000000 -19.500000000 35.500000000 -16.500000000 -18.500000000 35.500000000 -16.500000000 -17.500000000 35.500000000 -16.500000000 -16.500000000 35.500000000 -16.500000000 -15.500000000 35.500000000 -16.500000000 -14.500000000 35.500000000 -16.500000000 -13.500000000 35.500000000 -16.500000000 -12.500000000 35.500000000 -16.500000000 -11.500000000 35.500000000 -16.500000000 -10.500000000 35.500000000 -16.500000000 -9.500000000 35.500000000 -16.500000000 -8.500000000 35.500000000 -16.500000000 -7.500000000 35.500000000 -16.500000000 -6.500000000 35.500000000 -16.500000000 -5.500000000 35.500000000 -16.500000000 -4.500000000 35.500000000 -16.500000000 -3.500000000 35.500000000 -16.500000000 -2.500000000 35.500000000 -16.500000000 -1.500000000 35.500000000 -16.500000000 -0.500000000 35.500000000 -16.500000000 0.500000000 35.500000000 -16.500000000 1.500000000 35.500000000 -16.500000000 2.500000000 35.500000000 -16.500000000 3.500000000 35.500000000 -16.500000000 4.500000000 35.500000000 -16.500000000 5.500000000 35.500000000 -16.500000000 6.500000000 35.500000000 -16.500000000 7.500000000 35.500000000 -16.500000000 8.500000000 35.500000000 -16.500000000 9.500000000 35.500000000 -16.500000000 10.500000000 35.500000000 -16.500000000 11.500000000 35.500000000 -16.500000000 12.500000000 35.500000000 -16.500000000 13.500000000 35.500000000 -16.500000000 14.500000000 35.500000000 -16.500000000 15.500000000 35.500000000 -16.500000000 16.500000000 35.500000000 -16.500000000 17.500000000 35.500000000 -16.500000000 18.500000000 35.500000000 -16.500000000 19.500000000 35.500000000 -16.500000000 20.500000000 35.500000000 -16.500000000 21.500000000 35.500000000 -16.500000000 22.500000000 35.500000000 -16.500000000 23.500000000 35.500000000 -16.500000000 24.500000000 35.500000000 -16.500000000 25.499996185 35.499996185 -16.500000000 26.499954224 35.499954224 -16.500000000 27.499591827 35.499591827 -16.500000000 28.497470856 35.497474670 -16.500000000 29.488407135 35.488403320 -16.500000000 30.458978653 35.458980560 -16.500000000 31.384418488 35.384422302 -16.500000000 32.233222961 35.233222961 -16.500000000 32.981101990 34.981101990 -16.500000000 -33.981101990 -35.981101990 -15.500000000 -33.233226776 -36.233222961 -15.500000000 -32.384422302 -36.384418488 -15.500000000 -31.458978653 -36.458980560 -15.500000000 -30.488407135 -36.488403320 -15.500000000 -29.497472763 -36.497474670 -15.500000000 -28.499593735 -36.499591827 -15.500000000 -27.499954224 -36.499954224 -15.500000000 -26.499996185 -36.499996185 -15.500000000 -25.500000000 -36.500000000 -15.500000000 -24.500000000 -36.500000000 -15.500000000 -23.500000000 -36.500000000 -15.500000000 -22.500000000 -36.500000000 -15.500000000 -21.500000000 -36.500000000 -15.500000000 -20.500000000 -36.500000000 -15.500000000 -19.500000000 -36.500000000 -15.500000000 -18.500000000 -36.500000000 -15.500000000 -17.500000000 -36.500000000 -15.500000000 -16.500000000 -36.500000000 -15.500000000 -15.500000000 -36.500000000 -15.500000000 -14.500000000 -36.500000000 -15.500000000 -13.500000000 -36.500000000 -15.500000000 -12.500000000 -36.500000000 -15.500000000 -11.500000000 -36.500000000 -15.500000000 -10.500000000 -36.500000000 -15.500000000 -9.500000000 -36.500000000 -15.500000000 -8.500000000 -36.500000000 -15.500000000 -7.500000000 -36.500000000 -15.500000000 -6.500000000 -36.500000000 -15.500000000 -5.500000000 -36.500000000 -15.500000000 -4.500000000 -36.500000000 -15.500000000 -3.500000000 -36.500000000 -15.500000000 -2.500000000 -36.500000000 -15.500000000 -1.500000000 -36.500000000 -15.500000000 -0.500000000 -36.500000000 -15.500000000 0.500000000 -36.500000000 -15.500000000 1.500000000 -36.500000000 -15.500000000 2.500000000 -36.500000000 -15.500000000 3.500000000 -36.500000000 -15.500000000 4.500000000 -36.500000000 -15.500000000 5.500000000 -36.500000000 -15.500000000 6.500000000 -36.500000000 -15.500000000 7.500000000 -36.500000000 -15.500000000 8.500000000 -36.500000000 -15.500000000 9.500000000 -36.500000000 -15.500000000 10.500000000 -36.500000000 -15.500000000 11.500000000 -36.500000000 -15.500000000 12.500000000 -36.500000000 -15.500000000 13.500000000 -36.500000000 -15.500000000 14.500000000 -36.500000000 -15.500000000 15.500000000 -36.500000000 -15.500000000 16.500000000 -36.500000000 -15.500000000 17.500000000 -36.500000000 -15.500000000 18.500000000 -36.500000000 -15.500000000 19.500000000 -36.500000000 -15.500000000 20.500000000 -36.500000000 -15.500000000 21.500000000 -36.500000000 -15.500000000 22.500000000 -36.500000000 -15.500000000 23.500000000 -36.500000000 -15.500000000 24.500000000 -36.500000000 -15.500000000 25.499996185 -36.499996185 -15.500000000 26.499954224 -36.499954224 -15.500000000 27.499591827 -36.499591827 -15.500000000 28.497470856 -36.497467041 -15.500000000 29.488407135 -36.488403320 -15.500000000 30.458978653 -36.458980560 -15.500000000 31.384418488 -36.384422302 -15.500000000 32.233222961 -36.233222961 -15.500000000 32.981101990 -35.981101990 -15.500000000 -35.167964935 -35.167964935 -15.500000000 -34.622871399 -35.622871399 -15.500000000 33.622871399 -35.622871399 -15.500000000 34.167964935 -35.167964935 -15.500000000 -35.981101990 -33.981101990 -15.500000000 -35.622871399 -34.622871399 -15.500000000 34.622871399 -34.622871399 -15.500000000 34.981101990 -33.981101990 -15.500000000 -36.233222961 -33.233222961 -15.500000000 35.233222961 -33.233226776 -15.500000000 -36.384418488 -32.384422302 -15.500000000 35.384418488 -32.384422302 -15.500000000 -36.458976746 -31.458978653 -15.500000000 35.458980560 -31.458978653 -15.500000000 -36.488403320 -30.488407135 -15.500000000 35.488403320 -30.488407135 -15.500000000 -36.497467041 -29.497472763 -15.500000000 35.497474670 -29.497472763 -15.500000000 -36.499591827 -28.499593735 -15.500000000 35.499591827 -28.499593735 -15.500000000 -36.499954224 -27.499954224 -15.500000000 35.499954224 -27.499954224 -15.500000000 -36.499996185 -26.499996185 -15.500000000 35.499996185 -26.499996185 -15.500000000 -36.500000000 -25.500000000 -15.500000000 35.500000000 -25.500000000 -15.500000000 -36.500000000 -24.500000000 -15.500000000 35.500000000 -24.500000000 -15.500000000 -36.500000000 -23.500000000 -15.500000000 35.500000000 -23.500000000 -15.500000000 -36.500000000 -22.500000000 -15.500000000 35.500000000 -22.500000000 -15.500000000 -36.500000000 -21.500000000 -15.500000000 35.500000000 -21.500000000 -15.500000000 -36.500000000 -20.500000000 -15.500000000 35.500000000 -20.500000000 -15.500000000 -36.500000000 -19.500000000 -15.500000000 35.500000000 -19.500000000 -15.500000000 -36.500000000 -18.500000000 -15.500000000 35.500000000 -18.500000000 -15.500000000 -36.500000000 -17.500000000 -15.500000000 35.500000000 -17.500000000 -15.500000000 -36.500000000 -16.500000000 -15.500000000 35.500000000 -16.500000000 -15.500000000 -36.500000000 -15.500000000 -15.500000000 35.500000000 -15.500000000 -15.500000000 -36.500000000 -14.500000000 -15.500000000 35.500000000 -14.500000000 -15.500000000 -36.500000000 -13.500000000 -15.500000000 35.500000000 -13.500000000 -15.500000000 -36.500000000 -12.500000000 -15.500000000 35.500000000 -12.500000000 -15.500000000 -36.500000000 -11.500000000 -15.500000000 35.500000000 -11.500000000 -15.500000000 -36.500000000 -10.500000000 -15.500000000 35.500000000 -10.500000000 -15.500000000 -36.500000000 -9.500000000 -15.500000000 35.500000000 -9.500000000 -15.500000000 -36.500000000 -8.500000000 -15.500000000 35.500000000 -8.500000000 -15.500000000 -36.500000000 -7.500000000 -15.500000000 35.500000000 -7.500000000 -15.500000000 -36.500000000 -6.500000000 -15.500000000 35.500000000 -6.500000000 -15.500000000 -36.500000000 -5.500000000 -15.500000000 35.500000000 -5.500000000 -15.500000000 -36.500000000 -4.500000000 -15.500000000 35.500000000 -4.500000000 -15.500000000 -36.500000000 -3.500000000 -15.500000000 35.500000000 -3.500000000 -15.500000000 -36.500000000 -2.500000000 -15.500000000 35.500000000 -2.500000000 -15.500000000 -36.500000000 -1.500000000 -15.500000000 35.500000000 -1.500000000 -15.500000000 -36.500000000 -0.500000000 -15.500000000 35.500000000 -0.500000000 -15.500000000 -36.500000000 0.500000000 -15.500000000 35.500000000 0.500000000 -15.500000000 -36.500000000 1.500000000 -15.500000000 35.500000000 1.500000000 -15.500000000 -36.500000000 2.500000000 -15.500000000 35.500000000 2.500000000 -15.500000000 -36.500000000 3.500000000 -15.500000000 35.500000000 3.500000000 -15.500000000 -36.500000000 4.500000000 -15.500000000 35.500000000 4.500000000 -15.500000000 -36.500000000 5.500000000 -15.500000000 35.500000000 5.500000000 -15.500000000 -36.500000000 6.500000000 -15.500000000 35.500000000 6.500000000 -15.500000000 -36.500000000 7.500000000 -15.500000000 35.500000000 7.500000000 -15.500000000 -36.500000000 8.500000000 -15.500000000 35.500000000 8.500000000 -15.500000000 -36.500000000 9.500000000 -15.500000000 35.500000000 9.500000000 -15.500000000 -36.500000000 10.500000000 -15.500000000 35.500000000 10.500000000 -15.500000000 -36.500000000 11.500000000 -15.500000000 35.500000000 11.500000000 -15.500000000 -36.500000000 12.500000000 -15.500000000 35.500000000 12.500000000 -15.500000000 -36.500000000 13.500000000 -15.500000000 35.500000000 13.500000000 -15.500000000 -36.500000000 14.500000000 -15.500000000 35.500000000 14.500000000 -15.500000000 -36.500000000 15.500000000 -15.500000000 35.500000000 15.500000000 -15.500000000 -36.500000000 16.500000000 -15.500000000 35.500000000 16.500000000 -15.500000000 -36.500000000 17.500000000 -15.500000000 35.500000000 17.500000000 -15.500000000 -36.500000000 18.500000000 -15.500000000 35.500000000 18.500000000 -15.500000000 -36.500000000 19.500000000 -15.500000000 35.500000000 19.500000000 -15.500000000 -36.500000000 20.500000000 -15.500000000 35.500000000 20.500000000 -15.500000000 -36.500000000 21.500000000 -15.500000000 35.500000000 21.500000000 -15.500000000 -36.500000000 22.500000000 -15.500000000 35.500000000 22.500000000 -15.500000000 -36.500000000 23.500000000 -15.500000000 35.500000000 23.500000000 -15.500000000 -36.500000000 24.500000000 -15.500000000 35.500000000 24.500000000 -15.500000000 -36.499996185 25.499996185 -15.500000000 35.499996185 25.499996185 -15.500000000 -36.499954224 26.499954224 -15.500000000 35.499954224 26.499954224 -15.500000000 -36.499591827 27.499591827 -15.500000000 35.499591827 27.499591827 -15.500000000 -36.497474670 28.497470856 -15.500000000 35.497467041 28.497470856 -15.500000000 -36.488403320 29.488407135 -15.500000000 35.488403320 29.488407135 -15.500000000 -36.458980560 30.458978653 -15.500000000 35.458980560 30.458978653 -15.500000000 -36.384422302 31.384418488 -15.500000000 35.384422302 31.384418488 -15.500000000 -36.233222961 32.233222961 -15.500000000 35.233222961 32.233222961 -15.500000000 -35.981101990 32.981101990 -15.500000000 -35.622871399 33.622871399 -15.500000000 34.622871399 33.622871399 -15.500000000 34.981101990 32.981101990 -15.500000000 -35.167964935 34.167964935 -15.500000000 -34.622871399 34.622871399 -15.500000000 33.622871399 34.622871399 -15.500000000 34.167964935 34.167964935 -15.500000000 -33.981101990 34.981101990 -15.500000000 -33.233222961 35.233222961 -15.500000000 -32.384422302 35.384418488 -15.500000000 -31.458978653 35.458976746 -15.500000000 -30.488407135 35.488403320 -15.500000000 -29.497472763 35.497467041 -15.500000000 -28.499593735 35.499591827 -15.500000000 -27.499954224 35.499954224 -15.500000000 -26.499996185 35.499996185 -15.500000000 -25.500000000 35.500000000 -15.500000000 -24.500000000 35.500000000 -15.500000000 -23.500000000 35.500000000 -15.500000000 -22.500000000 35.500000000 -15.500000000 -21.500000000 35.500000000 -15.500000000 -20.500000000 35.500000000 -15.500000000 -19.500000000 35.500000000 -15.500000000 -18.500000000 35.500000000 -15.500000000 -17.500000000 35.500000000 -15.500000000 -16.500000000 35.500000000 -15.500000000 -15.500000000 35.500000000 -15.500000000 -14.500000000 35.500000000 -15.500000000 -13.500000000 35.500000000 -15.500000000 -12.500000000 35.500000000 -15.500000000 -11.500000000 35.500000000 -15.500000000 -10.500000000 35.500000000 -15.500000000 -9.500000000 35.500000000 -15.500000000 -8.500000000 35.500000000 -15.500000000 -7.500000000 35.500000000 -15.500000000 -6.500000000 35.500000000 -15.500000000 -5.500000000 35.500000000 -15.500000000 -4.500000000 35.500000000 -15.500000000 -3.500000000 35.500000000 -15.500000000 -2.500000000 35.500000000 -15.500000000 -1.500000000 35.500000000 -15.500000000 -0.500000000 35.500000000 -15.500000000 0.500000000 35.500000000 -15.500000000 1.500000000 35.500000000 -15.500000000 2.500000000 35.500000000 -15.500000000 3.500000000 35.500000000 -15.500000000 4.500000000 35.500000000 -15.500000000 5.500000000 35.500000000 -15.500000000 6.500000000 35.500000000 -15.500000000 7.500000000 35.500000000 -15.500000000 8.500000000 35.500000000 -15.500000000 9.500000000 35.500000000 -15.500000000 10.500000000 35.500000000 -15.500000000 11.500000000 35.500000000 -15.500000000 12.500000000 35.500000000 -15.500000000 13.500000000 35.500000000 -15.500000000 14.500000000 35.500000000 -15.500000000 15.500000000 35.500000000 -15.500000000 16.500000000 35.500000000 -15.500000000 17.500000000 35.500000000 -15.500000000 18.500000000 35.500000000 -15.500000000 19.500000000 35.500000000 -15.500000000 20.500000000 35.500000000 -15.500000000 21.500000000 35.500000000 -15.500000000 22.500000000 35.500000000 -15.500000000 23.500000000 35.500000000 -15.500000000 24.500000000 35.500000000 -15.500000000 25.499996185 35.499996185 -15.500000000 26.499954224 35.499954224 -15.500000000 27.499591827 35.499591827 -15.500000000 28.497470856 35.497474670 -15.500000000 29.488407135 35.488403320 -15.500000000 30.458978653 35.458980560 -15.500000000 31.384418488 35.384422302 -15.500000000 32.233222961 35.233222961 -15.500000000 32.981101990 34.981101990 -15.500000000 -33.981101990 -35.981101990 -14.500000000 -33.233226776 -36.233222961 -14.500000000 -32.384422302 -36.384418488 -14.500000000 -31.458978653 -36.458980560 -14.500000000 -30.488407135 -36.488403320 -14.500000000 -29.497472763 -36.497474670 -14.500000000 -28.499593735 -36.499591827 -14.500000000 -27.499954224 -36.499954224 -14.500000000 -26.499996185 -36.499996185 -14.500000000 -25.500000000 -36.500000000 -14.500000000 -24.500000000 -36.500000000 -14.500000000 -23.500000000 -36.500000000 -14.500000000 -22.500000000 -36.500000000 -14.500000000 -21.500000000 -36.500000000 -14.500000000 -20.500000000 -36.500000000 -14.500000000 -19.500000000 -36.500000000 -14.500000000 -18.500000000 -36.500000000 -14.500000000 -17.500000000 -36.500000000 -14.500000000 -16.500000000 -36.500000000 -14.500000000 -15.500000000 -36.500000000 -14.500000000 -14.500000000 -36.500000000 -14.500000000 -13.500000000 -36.500000000 -14.500000000 -12.500000000 -36.500000000 -14.500000000 -11.500000000 -36.500000000 -14.500000000 -10.500000000 -36.500000000 -14.500000000 -9.500000000 -36.500000000 -14.500000000 -8.500000000 -36.500000000 -14.500000000 -7.500000000 -36.500000000 -14.500000000 -6.500000000 -36.500000000 -14.500000000 -5.500000000 -36.500000000 -14.500000000 -4.500000000 -36.500000000 -14.500000000 -3.500000000 -36.500000000 -14.500000000 -2.500000000 -36.500000000 -14.500000000 -1.500000000 -36.500000000 -14.500000000 -0.500000000 -36.500000000 -14.500000000 0.500000000 -36.500000000 -14.500000000 1.500000000 -36.500000000 -14.500000000 2.500000000 -36.500000000 -14.500000000 3.500000000 -36.500000000 -14.500000000 4.500000000 -36.500000000 -14.500000000 5.500000000 -36.500000000 -14.500000000 6.500000000 -36.500000000 -14.500000000 7.500000000 -36.500000000 -14.500000000 8.500000000 -36.500000000 -14.500000000 9.500000000 -36.500000000 -14.500000000 10.500000000 -36.500000000 -14.500000000 11.500000000 -36.500000000 -14.500000000 12.500000000 -36.500000000 -14.500000000 13.500000000 -36.500000000 -14.500000000 14.500000000 -36.500000000 -14.500000000 15.500000000 -36.500000000 -14.500000000 16.500000000 -36.500000000 -14.500000000 17.500000000 -36.500000000 -14.500000000 18.500000000 -36.500000000 -14.500000000 19.500000000 -36.500000000 -14.500000000 20.500000000 -36.500000000 -14.500000000 21.500000000 -36.500000000 -14.500000000 22.500000000 -36.500000000 -14.500000000 23.500000000 -36.500000000 -14.500000000 24.500000000 -36.500000000 -14.500000000 25.499996185 -36.499996185 -14.500000000 26.499954224 -36.499954224 -14.500000000 27.499591827 -36.499591827 -14.500000000 28.497470856 -36.497467041 -14.500000000 29.488407135 -36.488403320 -14.500000000 30.458978653 -36.458980560 -14.500000000 31.384418488 -36.384422302 -14.500000000 32.233222961 -36.233222961 -14.500000000 32.981101990 -35.981101990 -14.500000000 -35.167964935 -35.167964935 -14.500000000 -34.622871399 -35.622871399 -14.500000000 33.622871399 -35.622871399 -14.500000000 34.167964935 -35.167964935 -14.500000000 -35.981101990 -33.981101990 -14.500000000 -35.622871399 -34.622871399 -14.500000000 34.622871399 -34.622871399 -14.500000000 34.981101990 -33.981101990 -14.500000000 -36.233222961 -33.233222961 -14.500000000 35.233222961 -33.233226776 -14.500000000 -36.384418488 -32.384422302 -14.500000000 35.384418488 -32.384422302 -14.500000000 -36.458976746 -31.458978653 -14.500000000 35.458980560 -31.458978653 -14.500000000 -36.488403320 -30.488407135 -14.500000000 35.488403320 -30.488407135 -14.500000000 -36.497467041 -29.497472763 -14.500000000 35.497474670 -29.497472763 -14.500000000 -36.499591827 -28.499593735 -14.500000000 35.499591827 -28.499593735 -14.500000000 -36.499954224 -27.499954224 -14.500000000 35.499954224 -27.499954224 -14.500000000 -36.499996185 -26.499996185 -14.500000000 35.499996185 -26.499996185 -14.500000000 -36.500000000 -25.500000000 -14.500000000 35.500000000 -25.500000000 -14.500000000 -36.500000000 -24.500000000 -14.500000000 35.500000000 -24.500000000 -14.500000000 -36.500000000 -23.500000000 -14.500000000 35.500000000 -23.500000000 -14.500000000 -36.500000000 -22.500000000 -14.500000000 35.500000000 -22.500000000 -14.500000000 -36.500000000 -21.500000000 -14.500000000 35.500000000 -21.500000000 -14.500000000 -36.500000000 -20.500000000 -14.500000000 35.500000000 -20.500000000 -14.500000000 -36.500000000 -19.500000000 -14.500000000 35.500000000 -19.500000000 -14.500000000 -36.500000000 -18.500000000 -14.500000000 35.500000000 -18.500000000 -14.500000000 -36.500000000 -17.500000000 -14.500000000 35.500000000 -17.500000000 -14.500000000 -36.500000000 -16.500000000 -14.500000000 35.500000000 -16.500000000 -14.500000000 -36.500000000 -15.500000000 -14.500000000 35.500000000 -15.500000000 -14.500000000 -36.500000000 -14.500000000 -14.500000000 35.500000000 -14.500000000 -14.500000000 -36.500000000 -13.500000000 -14.500000000 35.500000000 -13.500000000 -14.500000000 -36.500000000 -12.500000000 -14.500000000 35.500000000 -12.500000000 -14.500000000 -36.500000000 -11.500000000 -14.500000000 35.500000000 -11.500000000 -14.500000000 -36.500000000 -10.500000000 -14.500000000 35.500000000 -10.500000000 -14.500000000 -36.500000000 -9.500000000 -14.500000000 35.500000000 -9.500000000 -14.500000000 -36.500000000 -8.500000000 -14.500000000 35.500000000 -8.500000000 -14.500000000 -36.500000000 -7.500000000 -14.500000000 35.500000000 -7.500000000 -14.500000000 -36.500000000 -6.500000000 -14.500000000 35.500000000 -6.500000000 -14.500000000 -36.500000000 -5.500000000 -14.500000000 35.500000000 -5.500000000 -14.500000000 -36.500000000 -4.500000000 -14.500000000 35.500000000 -4.500000000 -14.500000000 -36.500000000 -3.500000000 -14.500000000 35.500000000 -3.500000000 -14.500000000 -36.500000000 -2.500000000 -14.500000000 35.500000000 -2.500000000 -14.500000000 -36.500000000 -1.500000000 -14.500000000 35.500000000 -1.500000000 -14.500000000 -36.500000000 -0.500000000 -14.500000000 35.500000000 -0.500000000 -14.500000000 -36.500000000 0.500000000 -14.500000000 35.500000000 0.500000000 -14.500000000 -36.500000000 1.500000000 -14.500000000 35.500000000 1.500000000 -14.500000000 -36.500000000 2.500000000 -14.500000000 35.500000000 2.500000000 -14.500000000 -36.500000000 3.500000000 -14.500000000 35.500000000 3.500000000 -14.500000000 -36.500000000 4.500000000 -14.500000000 35.500000000 4.500000000 -14.500000000 -36.500000000 5.500000000 -14.500000000 35.500000000 5.500000000 -14.500000000 -36.500000000 6.500000000 -14.500000000 35.500000000 6.500000000 -14.500000000 -36.500000000 7.500000000 -14.500000000 35.500000000 7.500000000 -14.500000000 -36.500000000 8.500000000 -14.500000000 35.500000000 8.500000000 -14.500000000 -36.500000000 9.500000000 -14.500000000 35.500000000 9.500000000 -14.500000000 -36.500000000 10.500000000 -14.500000000 35.500000000 10.500000000 -14.500000000 -36.500000000 11.500000000 -14.500000000 35.500000000 11.500000000 -14.500000000 -36.500000000 12.500000000 -14.500000000 35.500000000 12.500000000 -14.500000000 -36.500000000 13.500000000 -14.500000000 35.500000000 13.500000000 -14.500000000 -36.500000000 14.500000000 -14.500000000 35.500000000 14.500000000 -14.500000000 -36.500000000 15.500000000 -14.500000000 35.500000000 15.500000000 -14.500000000 -36.500000000 16.500000000 -14.500000000 35.500000000 16.500000000 -14.500000000 -36.500000000 17.500000000 -14.500000000 35.500000000 17.500000000 -14.500000000 -36.500000000 18.500000000 -14.500000000 35.500000000 18.500000000 -14.500000000 -36.500000000 19.500000000 -14.500000000 35.500000000 19.500000000 -14.500000000 -36.500000000 20.500000000 -14.500000000 35.500000000 20.500000000 -14.500000000 -36.500000000 21.500000000 -14.500000000 35.500000000 21.500000000 -14.500000000 -36.500000000 22.500000000 -14.500000000 35.500000000 22.500000000 -14.500000000 -36.500000000 23.500000000 -14.500000000 35.500000000 23.500000000 -14.500000000 -36.500000000 24.500000000 -14.500000000 35.500000000 24.500000000 -14.500000000 -36.499996185 25.499996185 -14.500000000 35.499996185 25.499996185 -14.500000000 -36.499954224 26.499954224 -14.500000000 35.499954224 26.499954224 -14.500000000 -36.499591827 27.499591827 -14.500000000 35.499591827 27.499591827 -14.500000000 -36.497474670 28.497470856 -14.500000000 35.497467041 28.497470856 -14.500000000 -36.488403320 29.488407135 -14.500000000 35.488403320 29.488407135 -14.500000000 -36.458980560 30.458978653 -14.500000000 35.458980560 30.458978653 -14.500000000 -36.384422302 31.384418488 -14.500000000 35.384422302 31.384418488 -14.500000000 -36.233222961 32.233222961 -14.500000000 35.233222961 32.233222961 -14.500000000 -35.981101990 32.981101990 -14.500000000 -35.622871399 33.622871399 -14.500000000 34.622871399 33.622871399 -14.500000000 34.981101990 32.981101990 -14.500000000 -35.167964935 34.167964935 -14.500000000 -34.622871399 34.622871399 -14.500000000 33.622871399 34.622871399 -14.500000000 34.167964935 34.167964935 -14.500000000 -33.981101990 34.981101990 -14.500000000 -33.233222961 35.233222961 -14.500000000 -32.384422302 35.384418488 -14.500000000 -31.458978653 35.458976746 -14.500000000 -30.488407135 35.488403320 -14.500000000 -29.497472763 35.497467041 -14.500000000 -28.499593735 35.499591827 -14.500000000 -27.499954224 35.499954224 -14.500000000 -26.499996185 35.499996185 -14.500000000 -25.500000000 35.500000000 -14.500000000 -24.500000000 35.500000000 -14.500000000 -23.500000000 35.500000000 -14.500000000 -22.500000000 35.500000000 -14.500000000 -21.500000000 35.500000000 -14.500000000 -20.500000000 35.500000000 -14.500000000 -19.500000000 35.500000000 -14.500000000 -18.500000000 35.500000000 -14.500000000 -17.500000000 35.500000000 -14.500000000 -16.500000000 35.500000000 -14.500000000 -15.500000000 35.500000000 -14.500000000 -14.500000000 35.500000000 -14.500000000 -13.500000000 35.500000000 -14.500000000 -12.500000000 35.500000000 -14.500000000 -11.500000000 35.500000000 -14.500000000 -10.500000000 35.500000000 -14.500000000 -9.500000000 35.500000000 -14.500000000 -8.500000000 35.500000000 -14.500000000 -7.500000000 35.500000000 -14.500000000 -6.500000000 35.500000000 -14.500000000 -5.500000000 35.500000000 -14.500000000 -4.500000000 35.500000000 -14.500000000 -3.500000000 35.500000000 -14.500000000 -2.500000000 35.500000000 -14.500000000 -1.500000000 35.500000000 -14.500000000 -0.500000000 35.500000000 -14.500000000 0.500000000 35.500000000 -14.500000000 1.500000000 35.500000000 -14.500000000 2.500000000 35.500000000 -14.500000000 3.500000000 35.500000000 -14.500000000 4.500000000 35.500000000 -14.500000000 5.500000000 35.500000000 -14.500000000 6.500000000 35.500000000 -14.500000000 7.500000000 35.500000000 -14.500000000 8.500000000 35.500000000 -14.500000000 9.500000000 35.500000000 -14.500000000 10.500000000 35.500000000 -14.500000000 11.500000000 35.500000000 -14.500000000 12.500000000 35.500000000 -14.500000000 13.500000000 35.500000000 -14.500000000 14.500000000 35.500000000 -14.500000000 15.500000000 35.500000000 -14.500000000 16.500000000 35.500000000 -14.500000000 17.500000000 35.500000000 -14.500000000 18.500000000 35.500000000 -14.500000000 19.500000000 35.500000000 -14.500000000 20.500000000 35.500000000 -14.500000000 21.500000000 35.500000000 -14.500000000 22.500000000 35.500000000 -14.500000000 23.500000000 35.500000000 -14.500000000 24.500000000 35.500000000 -14.500000000 25.499996185 35.499996185 -14.500000000 26.499954224 35.499954224 -14.500000000 27.499591827 35.499591827 -14.500000000 28.497470856 35.497474670 -14.500000000 29.488407135 35.488403320 -14.500000000 30.458978653 35.458980560 -14.500000000 31.384418488 35.384422302 -14.500000000 32.233222961 35.233222961 -14.500000000 32.981101990 34.981101990 -14.500000000 -33.981101990 -35.981101990 -13.500000000 -33.233226776 -36.233222961 -13.500000000 -32.384422302 -36.384418488 -13.500000000 -31.458978653 -36.458980560 -13.500000000 -30.488407135 -36.488403320 -13.500000000 -29.497472763 -36.497474670 -13.500000000 -28.499593735 -36.499591827 -13.500000000 -27.499954224 -36.499954224 -13.500000000 -26.499996185 -36.499996185 -13.500000000 -25.500000000 -36.500000000 -13.500000000 -24.500000000 -36.500000000 -13.500000000 -23.500000000 -36.500000000 -13.500000000 -22.500000000 -36.500000000 -13.500000000 -21.500000000 -36.500000000 -13.500000000 -20.500000000 -36.500000000 -13.500000000 -19.500000000 -36.500000000 -13.500000000 -18.500000000 -36.500000000 -13.500000000 -17.500000000 -36.500000000 -13.500000000 -16.500000000 -36.500000000 -13.500000000 -15.500000000 -36.500000000 -13.500000000 -14.500000000 -36.500000000 -13.500000000 -13.500000000 -36.500000000 -13.500000000 -12.500000000 -36.500000000 -13.500000000 -11.500000000 -36.500000000 -13.500000000 -10.500000000 -36.500000000 -13.500000000 -9.500000000 -36.500000000 -13.500000000 -8.500000000 -36.500000000 -13.500000000 -7.500000000 -36.500000000 -13.500000000 -6.500000000 -36.500000000 -13.500000000 -5.500000000 -36.500000000 -13.500000000 -4.500000000 -36.500000000 -13.500000000 -3.500000000 -36.500000000 -13.500000000 -2.500000000 -36.500000000 -13.500000000 -1.500000000 -36.500000000 -13.500000000 -0.500000000 -36.500000000 -13.500000000 0.500000000 -36.500000000 -13.500000000 1.500000000 -36.500000000 -13.500000000 2.500000000 -36.500000000 -13.500000000 3.500000000 -36.500000000 -13.500000000 4.500000000 -36.500000000 -13.500000000 5.500000000 -36.500000000 -13.500000000 6.500000000 -36.500000000 -13.500000000 7.500000000 -36.500000000 -13.500000000 8.500000000 -36.500000000 -13.500000000 9.500000000 -36.500000000 -13.500000000 10.500000000 -36.500000000 -13.500000000 11.500000000 -36.500000000 -13.500000000 12.500000000 -36.500000000 -13.500000000 13.500000000 -36.500000000 -13.500000000 14.500000000 -36.500000000 -13.500000000 15.500000000 -36.500000000 -13.500000000 16.500000000 -36.500000000 -13.500000000 17.500000000 -36.500000000 -13.500000000 18.500000000 -36.500000000 -13.500000000 19.500000000 -36.500000000 -13.500000000 20.500000000 -36.500000000 -13.500000000 21.500000000 -36.500000000 -13.500000000 22.500000000 -36.500000000 -13.500000000 23.500000000 -36.500000000 -13.500000000 24.500000000 -36.500000000 -13.500000000 25.499996185 -36.499996185 -13.500000000 26.499954224 -36.499954224 -13.500000000 27.499591827 -36.499591827 -13.500000000 28.497470856 -36.497467041 -13.500000000 29.488407135 -36.488403320 -13.500000000 30.458978653 -36.458980560 -13.500000000 31.384418488 -36.384422302 -13.500000000 32.233222961 -36.233222961 -13.500000000 32.981101990 -35.981101990 -13.500000000 -35.167964935 -35.167964935 -13.500000000 -34.622871399 -35.622871399 -13.500000000 33.622871399 -35.622871399 -13.500000000 34.167964935 -35.167964935 -13.500000000 -35.981101990 -33.981101990 -13.500000000 -35.622871399 -34.622871399 -13.500000000 34.622871399 -34.622871399 -13.500000000 34.981101990 -33.981101990 -13.500000000 -36.233222961 -33.233222961 -13.500000000 35.233222961 -33.233226776 -13.500000000 -36.384418488 -32.384422302 -13.500000000 35.384418488 -32.384422302 -13.500000000 -36.458976746 -31.458978653 -13.500000000 35.458980560 -31.458978653 -13.500000000 -36.488403320 -30.488407135 -13.500000000 35.488403320 -30.488407135 -13.500000000 -36.497467041 -29.497472763 -13.500000000 35.497474670 -29.497472763 -13.500000000 -36.499591827 -28.499593735 -13.500000000 35.499591827 -28.499593735 -13.500000000 -36.499954224 -27.499954224 -13.500000000 35.499954224 -27.499954224 -13.500000000 -36.499996185 -26.499996185 -13.500000000 35.499996185 -26.499996185 -13.500000000 -36.500000000 -25.500000000 -13.500000000 35.500000000 -25.500000000 -13.500000000 -36.500000000 -24.500000000 -13.500000000 35.500000000 -24.500000000 -13.500000000 -36.500000000 -23.500000000 -13.500000000 35.500000000 -23.500000000 -13.500000000 -36.500000000 -22.500000000 -13.500000000 35.500000000 -22.500000000 -13.500000000 -36.500000000 -21.500000000 -13.500000000 35.500000000 -21.500000000 -13.500000000 -36.500000000 -20.500000000 -13.500000000 35.500000000 -20.500000000 -13.500000000 -36.500000000 -19.500000000 -13.500000000 35.500000000 -19.500000000 -13.500000000 -36.500000000 -18.500000000 -13.500000000 35.500000000 -18.500000000 -13.500000000 -36.500000000 -17.500000000 -13.500000000 35.500000000 -17.500000000 -13.500000000 -36.500000000 -16.500000000 -13.500000000 35.500000000 -16.500000000 -13.500000000 -36.500000000 -15.500000000 -13.500000000 35.500000000 -15.500000000 -13.500000000 -36.500000000 -14.500000000 -13.500000000 35.500000000 -14.500000000 -13.500000000 -36.500000000 -13.500000000 -13.500000000 35.500000000 -13.500000000 -13.500000000 -36.500000000 -12.500000000 -13.500000000 35.500000000 -12.500000000 -13.500000000 -36.500000000 -11.500000000 -13.500000000 35.500000000 -11.500000000 -13.500000000 -36.500000000 -10.500000000 -13.500000000 35.500000000 -10.500000000 -13.500000000 -36.500000000 -9.500000000 -13.500000000 35.500000000 -9.500000000 -13.500000000 -36.500000000 -8.500000000 -13.500000000 35.500000000 -8.500000000 -13.500000000 -36.500000000 -7.500000000 -13.500000000 35.500000000 -7.500000000 -13.500000000 -36.500000000 -6.500000000 -13.500000000 35.500000000 -6.500000000 -13.500000000 -36.500000000 -5.500000000 -13.500000000 35.500000000 -5.500000000 -13.500000000 -36.500000000 -4.500000000 -13.500000000 35.500000000 -4.500000000 -13.500000000 -36.500000000 -3.500000000 -13.500000000 35.500000000 -3.500000000 -13.500000000 -36.500000000 -2.500000000 -13.500000000 35.500000000 -2.500000000 -13.500000000 -36.500000000 -1.500000000 -13.500000000 35.500000000 -1.500000000 -13.500000000 -36.500000000 -0.500000000 -13.500000000 35.500000000 -0.500000000 -13.500000000 -36.500000000 0.500000000 -13.500000000 35.500000000 0.500000000 -13.500000000 -36.500000000 1.500000000 -13.500000000 35.500000000 1.500000000 -13.500000000 -36.500000000 2.500000000 -13.500000000 35.500000000 2.500000000 -13.500000000 -36.500000000 3.500000000 -13.500000000 35.500000000 3.500000000 -13.500000000 -36.500000000 4.500000000 -13.500000000 35.500000000 4.500000000 -13.500000000 -36.500000000 5.500000000 -13.500000000 35.500000000 5.500000000 -13.500000000 -36.500000000 6.500000000 -13.500000000 35.500000000 6.500000000 -13.500000000 -36.500000000 7.500000000 -13.500000000 35.500000000 7.500000000 -13.500000000 -36.500000000 8.500000000 -13.500000000 35.500000000 8.500000000 -13.500000000 -36.500000000 9.500000000 -13.500000000 35.500000000 9.500000000 -13.500000000 -36.500000000 10.500000000 -13.500000000 35.500000000 10.500000000 -13.500000000 -36.500000000 11.500000000 -13.500000000 35.500000000 11.500000000 -13.500000000 -36.500000000 12.500000000 -13.500000000 35.500000000 12.500000000 -13.500000000 -36.500000000 13.500000000 -13.500000000 35.500000000 13.500000000 -13.500000000 -36.500000000 14.500000000 -13.500000000 35.500000000 14.500000000 -13.500000000 -36.500000000 15.500000000 -13.500000000 35.500000000 15.500000000 -13.500000000 -36.500000000 16.500000000 -13.500000000 35.500000000 16.500000000 -13.500000000 -36.500000000 17.500000000 -13.500000000 35.500000000 17.500000000 -13.500000000 -36.500000000 18.500000000 -13.500000000 35.500000000 18.500000000 -13.500000000 -36.500000000 19.500000000 -13.500000000 35.500000000 19.500000000 -13.500000000 -36.500000000 20.500000000 -13.500000000 35.500000000 20.500000000 -13.500000000 -36.500000000 21.500000000 -13.500000000 35.500000000 21.500000000 -13.500000000 -36.500000000 22.500000000 -13.500000000 35.500000000 22.500000000 -13.500000000 -36.500000000 23.500000000 -13.500000000 35.500000000 23.500000000 -13.500000000 -36.500000000 24.500000000 -13.500000000 35.500000000 24.500000000 -13.500000000 -36.499996185 25.499996185 -13.500000000 35.499996185 25.499996185 -13.500000000 -36.499954224 26.499954224 -13.500000000 35.499954224 26.499954224 -13.500000000 -36.499591827 27.499591827 -13.500000000 35.499591827 27.499591827 -13.500000000 -36.497474670 28.497470856 -13.500000000 35.497467041 28.497470856 -13.500000000 -36.488403320 29.488407135 -13.500000000 35.488403320 29.488407135 -13.500000000 -36.458980560 30.458978653 -13.500000000 35.458980560 30.458978653 -13.500000000 -36.384422302 31.384418488 -13.500000000 35.384422302 31.384418488 -13.500000000 -36.233222961 32.233222961 -13.500000000 35.233222961 32.233222961 -13.500000000 -35.981101990 32.981101990 -13.500000000 -35.622871399 33.622871399 -13.500000000 34.622871399 33.622871399 -13.500000000 34.981101990 32.981101990 -13.500000000 -35.167964935 34.167964935 -13.500000000 -34.622871399 34.622871399 -13.500000000 33.622871399 34.622871399 -13.500000000 34.167964935 34.167964935 -13.500000000 -33.981101990 34.981101990 -13.500000000 -33.233222961 35.233222961 -13.500000000 -32.384422302 35.384418488 -13.500000000 -31.458978653 35.458976746 -13.500000000 -30.488407135 35.488403320 -13.500000000 -29.497472763 35.497467041 -13.500000000 -28.499593735 35.499591827 -13.500000000 -27.499954224 35.499954224 -13.500000000 -26.499996185 35.499996185 -13.500000000 -25.500000000 35.500000000 -13.500000000 -24.500000000 35.500000000 -13.500000000 -23.500000000 35.500000000 -13.500000000 -22.500000000 35.500000000 -13.500000000 -21.500000000 35.500000000 -13.500000000 -20.500000000 35.500000000 -13.500000000 -19.500000000 35.500000000 -13.500000000 -18.500000000 35.500000000 -13.500000000 -17.500000000 35.500000000 -13.500000000 -16.500000000 35.500000000 -13.500000000 -15.500000000 35.500000000 -13.500000000 -14.500000000 35.500000000 -13.500000000 -13.500000000 35.500000000 -13.500000000 -12.500000000 35.500000000 -13.500000000 -11.500000000 35.500000000 -13.500000000 -10.500000000 35.500000000 -13.500000000 -9.500000000 35.500000000 -13.500000000 -8.500000000 35.500000000 -13.500000000 -7.500000000 35.500000000 -13.500000000 -6.500000000 35.500000000 -13.500000000 -5.500000000 35.500000000 -13.500000000 -4.500000000 35.500000000 -13.500000000 -3.500000000 35.500000000 -13.500000000 -2.500000000 35.500000000 -13.500000000 -1.500000000 35.500000000 -13.500000000 -0.500000000 35.500000000 -13.500000000 0.500000000 35.500000000 -13.500000000 1.500000000 35.500000000 -13.500000000 2.500000000 35.500000000 -13.500000000 3.500000000 35.500000000 -13.500000000 4.500000000 35.500000000 -13.500000000 5.500000000 35.500000000 -13.500000000 6.500000000 35.500000000 -13.500000000 7.500000000 35.500000000 -13.500000000 8.500000000 35.500000000 -13.500000000 9.500000000 35.500000000 -13.500000000 10.500000000 35.500000000 -13.500000000 11.500000000 35.500000000 -13.500000000 12.500000000 35.500000000 -13.500000000 13.500000000 35.500000000 -13.500000000 14.500000000 35.500000000 -13.500000000 15.500000000 35.500000000 -13.500000000 16.500000000 35.500000000 -13.500000000 17.500000000 35.500000000 -13.500000000 18.500000000 35.500000000 -13.500000000 19.500000000 35.500000000 -13.500000000 20.500000000 35.500000000 -13.500000000 21.500000000 35.500000000 -13.500000000 22.500000000 35.500000000 -13.500000000 23.500000000 35.500000000 -13.500000000 24.500000000 35.500000000 -13.500000000 25.499996185 35.499996185 -13.500000000 26.499954224 35.499954224 -13.500000000 27.499591827 35.499591827 -13.500000000 28.497470856 35.497474670 -13.500000000 29.488407135 35.488403320 -13.500000000 30.458978653 35.458980560 -13.500000000 31.384418488 35.384422302 -13.500000000 32.233222961 35.233222961 -13.500000000 32.981101990 34.981101990 -13.500000000 -33.981101990 -35.981101990 -12.500000000 -33.233226776 -36.233222961 -12.500000000 -32.384422302 -36.384418488 -12.500000000 -31.458978653 -36.458980560 -12.500000000 -30.488407135 -36.488403320 -12.500000000 -29.497472763 -36.497474670 -12.500000000 -28.499593735 -36.499591827 -12.500000000 -27.499954224 -36.499954224 -12.500000000 -26.499996185 -36.499996185 -12.500000000 -25.500000000 -36.500000000 -12.500000000 -24.500000000 -36.500000000 -12.500000000 -23.500000000 -36.500000000 -12.500000000 -22.500000000 -36.500000000 -12.500000000 -21.500000000 -36.500000000 -12.500000000 -20.500000000 -36.500000000 -12.500000000 -19.500000000 -36.500000000 -12.500000000 -18.500000000 -36.500000000 -12.500000000 -17.500000000 -36.500000000 -12.500000000 -16.500000000 -36.500000000 -12.500000000 -15.500000000 -36.500000000 -12.500000000 -14.500000000 -36.500000000 -12.500000000 -13.500000000 -36.500000000 -12.500000000 -12.500000000 -36.500000000 -12.500000000 -11.500000000 -36.500000000 -12.500000000 -10.500000000 -36.500000000 -12.500000000 -9.500000000 -36.500000000 -12.500000000 -8.500000000 -36.500000000 -12.500000000 -7.500000000 -36.500000000 -12.500000000 -6.500000000 -36.500000000 -12.500000000 -5.500000000 -36.500000000 -12.500000000 -4.500000000 -36.500000000 -12.500000000 -3.500000000 -36.500000000 -12.500000000 -2.500000000 -36.500000000 -12.500000000 -1.500000000 -36.500000000 -12.500000000 -0.500000000 -36.500000000 -12.500000000 0.500000000 -36.500000000 -12.500000000 1.500000000 -36.500000000 -12.500000000 2.500000000 -36.500000000 -12.500000000 3.500000000 -36.500000000 -12.500000000 4.500000000 -36.500000000 -12.500000000 5.500000000 -36.500000000 -12.500000000 6.500000000 -36.500000000 -12.500000000 7.500000000 -36.500000000 -12.500000000 8.500000000 -36.500000000 -12.500000000 9.500000000 -36.500000000 -12.500000000 10.500000000 -36.500000000 -12.500000000 11.500000000 -36.500000000 -12.500000000 12.500000000 -36.500000000 -12.500000000 13.500000000 -36.500000000 -12.500000000 14.500000000 -36.500000000 -12.500000000 15.500000000 -36.500000000 -12.500000000 16.500000000 -36.500000000 -12.500000000 17.500000000 -36.500000000 -12.500000000 18.500000000 -36.500000000 -12.500000000 19.500000000 -36.500000000 -12.500000000 20.500000000 -36.500000000 -12.500000000 21.500000000 -36.500000000 -12.500000000 22.500000000 -36.500000000 -12.500000000 23.500000000 -36.500000000 -12.500000000 24.500000000 -36.500000000 -12.500000000 25.499996185 -36.499996185 -12.500000000 26.499954224 -36.499954224 -12.500000000 27.499591827 -36.499591827 -12.500000000 28.497470856 -36.497467041 -12.500000000 29.488407135 -36.488403320 -12.500000000 30.458978653 -36.458980560 -12.500000000 31.384418488 -36.384422302 -12.500000000 32.233222961 -36.233222961 -12.500000000 32.981101990 -35.981101990 -12.500000000 -35.167964935 -35.167964935 -12.500000000 -34.622871399 -35.622871399 -12.500000000 33.622871399 -35.622871399 -12.500000000 34.167964935 -35.167964935 -12.500000000 -35.981101990 -33.981101990 -12.500000000 -35.622871399 -34.622871399 -12.500000000 34.622871399 -34.622871399 -12.500000000 34.981101990 -33.981101990 -12.500000000 -36.233222961 -33.233222961 -12.500000000 35.233222961 -33.233226776 -12.500000000 -36.384418488 -32.384422302 -12.500000000 35.384418488 -32.384422302 -12.500000000 -36.458976746 -31.458978653 -12.500000000 35.458980560 -31.458978653 -12.500000000 -36.488403320 -30.488407135 -12.500000000 35.488403320 -30.488407135 -12.500000000 -36.497467041 -29.497472763 -12.500000000 35.497474670 -29.497472763 -12.500000000 -36.499591827 -28.499593735 -12.500000000 35.499591827 -28.499593735 -12.500000000 -36.499954224 -27.499954224 -12.500000000 35.499954224 -27.499954224 -12.500000000 -36.499996185 -26.499996185 -12.500000000 35.499996185 -26.499996185 -12.500000000 -36.500000000 -25.500000000 -12.500000000 35.500000000 -25.500000000 -12.500000000 -36.500000000 -24.500000000 -12.500000000 35.500000000 -24.500000000 -12.500000000 -36.500000000 -23.500000000 -12.500000000 35.500000000 -23.500000000 -12.500000000 -36.500000000 -22.500000000 -12.500000000 35.500000000 -22.500000000 -12.500000000 -36.500000000 -21.500000000 -12.500000000 35.500000000 -21.500000000 -12.500000000 -36.500000000 -20.500000000 -12.500000000 35.500000000 -20.500000000 -12.500000000 -36.500000000 -19.500000000 -12.500000000 35.500000000 -19.500000000 -12.500000000 -36.500000000 -18.500000000 -12.500000000 35.500000000 -18.500000000 -12.500000000 -36.500000000 -17.500000000 -12.500000000 35.500000000 -17.500000000 -12.500000000 -36.500000000 -16.500000000 -12.500000000 35.500000000 -16.500000000 -12.500000000 -36.500000000 -15.500000000 -12.500000000 35.500000000 -15.500000000 -12.500000000 -36.500000000 -14.500000000 -12.500000000 35.500000000 -14.500000000 -12.500000000 -36.500000000 -13.500000000 -12.500000000 35.500000000 -13.500000000 -12.500000000 -36.500000000 -12.500000000 -12.500000000 35.500000000 -12.500000000 -12.500000000 -36.500000000 -11.500000000 -12.500000000 35.500000000 -11.500000000 -12.500000000 -36.500000000 -10.500000000 -12.500000000 35.500000000 -10.500000000 -12.500000000 -36.500000000 -9.500000000 -12.500000000 35.500000000 -9.500000000 -12.500000000 -36.500000000 -8.500000000 -12.500000000 35.500000000 -8.500000000 -12.500000000 -36.500000000 -7.500000000 -12.500000000 35.500000000 -7.500000000 -12.500000000 -36.500000000 -6.500000000 -12.500000000 35.500000000 -6.500000000 -12.500000000 -36.500000000 -5.500000000 -12.500000000 35.500000000 -5.500000000 -12.500000000 -36.500000000 -4.500000000 -12.500000000 35.500000000 -4.500000000 -12.500000000 -36.500000000 -3.500000000 -12.500000000 35.500000000 -3.500000000 -12.500000000 -36.500000000 -2.500000000 -12.500000000 35.500000000 -2.500000000 -12.500000000 -36.500000000 -1.500000000 -12.500000000 35.500000000 -1.500000000 -12.500000000 -36.500000000 -0.500000000 -12.500000000 35.500000000 -0.500000000 -12.500000000 -36.500000000 0.500000000 -12.500000000 35.500000000 0.500000000 -12.500000000 -36.500000000 1.500000000 -12.500000000 35.500000000 1.500000000 -12.500000000 -36.500000000 2.500000000 -12.500000000 35.500000000 2.500000000 -12.500000000 -36.500000000 3.500000000 -12.500000000 35.500000000 3.500000000 -12.500000000 -36.500000000 4.500000000 -12.500000000 35.500000000 4.500000000 -12.500000000 -36.500000000 5.500000000 -12.500000000 35.500000000 5.500000000 -12.500000000 -36.500000000 6.500000000 -12.500000000 35.500000000 6.500000000 -12.500000000 -36.500000000 7.500000000 -12.500000000 35.500000000 7.500000000 -12.500000000 -36.500000000 8.500000000 -12.500000000 35.500000000 8.500000000 -12.500000000 -36.500000000 9.500000000 -12.500000000 35.500000000 9.500000000 -12.500000000 -36.500000000 10.500000000 -12.500000000 35.500000000 10.500000000 -12.500000000 -36.500000000 11.500000000 -12.500000000 35.500000000 11.500000000 -12.500000000 -36.500000000 12.500000000 -12.500000000 35.500000000 12.500000000 -12.500000000 -36.500000000 13.500000000 -12.500000000 35.500000000 13.500000000 -12.500000000 -36.500000000 14.500000000 -12.500000000 35.500000000 14.500000000 -12.500000000 -36.500000000 15.500000000 -12.500000000 35.500000000 15.500000000 -12.500000000 -36.500000000 16.500000000 -12.500000000 35.500000000 16.500000000 -12.500000000 -36.500000000 17.500000000 -12.500000000 35.500000000 17.500000000 -12.500000000 -36.500000000 18.500000000 -12.500000000 35.500000000 18.500000000 -12.500000000 -36.500000000 19.500000000 -12.500000000 35.500000000 19.500000000 -12.500000000 -36.500000000 20.500000000 -12.500000000 35.500000000 20.500000000 -12.500000000 -36.500000000 21.500000000 -12.500000000 35.500000000 21.500000000 -12.500000000 -36.500000000 22.500000000 -12.500000000 35.500000000 22.500000000 -12.500000000 -36.500000000 23.500000000 -12.500000000 35.500000000 23.500000000 -12.500000000 -36.500000000 24.500000000 -12.500000000 35.500000000 24.500000000 -12.500000000 -36.499996185 25.499996185 -12.500000000 35.499996185 25.499996185 -12.500000000 -36.499954224 26.499954224 -12.500000000 35.499954224 26.499954224 -12.500000000 -36.499591827 27.499591827 -12.500000000 35.499591827 27.499591827 -12.500000000 -36.497474670 28.497470856 -12.500000000 35.497467041 28.497470856 -12.500000000 -36.488403320 29.488407135 -12.500000000 35.488403320 29.488407135 -12.500000000 -36.458980560 30.458978653 -12.500000000 35.458980560 30.458978653 -12.500000000 -36.384422302 31.384418488 -12.500000000 35.384422302 31.384418488 -12.500000000 -36.233222961 32.233222961 -12.500000000 35.233222961 32.233222961 -12.500000000 -35.981101990 32.981101990 -12.500000000 -35.622871399 33.622871399 -12.500000000 34.622871399 33.622871399 -12.500000000 34.981101990 32.981101990 -12.500000000 -35.167964935 34.167964935 -12.500000000 -34.622871399 34.622871399 -12.500000000 33.622871399 34.622871399 -12.500000000 34.167964935 34.167964935 -12.500000000 -33.981101990 34.981101990 -12.500000000 -33.233222961 35.233222961 -12.500000000 -32.384422302 35.384418488 -12.500000000 -31.458978653 35.458976746 -12.500000000 -30.488407135 35.488403320 -12.500000000 -29.497472763 35.497467041 -12.500000000 -28.499593735 35.499591827 -12.500000000 -27.499954224 35.499954224 -12.500000000 -26.499996185 35.499996185 -12.500000000 -25.500000000 35.500000000 -12.500000000 -24.500000000 35.500000000 -12.500000000 -23.500000000 35.500000000 -12.500000000 -22.500000000 35.500000000 -12.500000000 -21.500000000 35.500000000 -12.500000000 -20.500000000 35.500000000 -12.500000000 -19.500000000 35.500000000 -12.500000000 -18.500000000 35.500000000 -12.500000000 -17.500000000 35.500000000 -12.500000000 -16.500000000 35.500000000 -12.500000000 -15.500000000 35.500000000 -12.500000000 -14.500000000 35.500000000 -12.500000000 -13.500000000 35.500000000 -12.500000000 -12.500000000 35.500000000 -12.500000000 -11.500000000 35.500000000 -12.500000000 -10.500000000 35.500000000 -12.500000000 -9.500000000 35.500000000 -12.500000000 -8.500000000 35.500000000 -12.500000000 -7.500000000 35.500000000 -12.500000000 -6.500000000 35.500000000 -12.500000000 -5.500000000 35.500000000 -12.500000000 -4.500000000 35.500000000 -12.500000000 -3.500000000 35.500000000 -12.500000000 -2.500000000 35.500000000 -12.500000000 -1.500000000 35.500000000 -12.500000000 -0.500000000 35.500000000 -12.500000000 0.500000000 35.500000000 -12.500000000 1.500000000 35.500000000 -12.500000000 2.500000000 35.500000000 -12.500000000 3.500000000 35.500000000 -12.500000000 4.500000000 35.500000000 -12.500000000 5.500000000 35.500000000 -12.500000000 6.500000000 35.500000000 -12.500000000 7.500000000 35.500000000 -12.500000000 8.500000000 35.500000000 -12.500000000 9.500000000 35.500000000 -12.500000000 10.500000000 35.500000000 -12.500000000 11.500000000 35.500000000 -12.500000000 12.500000000 35.500000000 -12.500000000 13.500000000 35.500000000 -12.500000000 14.500000000 35.500000000 -12.500000000 15.500000000 35.500000000 -12.500000000 16.500000000 35.500000000 -12.500000000 17.500000000 35.500000000 -12.500000000 18.500000000 35.500000000 -12.500000000 19.500000000 35.500000000 -12.500000000 20.500000000 35.500000000 -12.500000000 21.500000000 35.500000000 -12.500000000 22.500000000 35.500000000 -12.500000000 23.500000000 35.500000000 -12.500000000 24.500000000 35.500000000 -12.500000000 25.499996185 35.499996185 -12.500000000 26.499954224 35.499954224 -12.500000000 27.499591827 35.499591827 -12.500000000 28.497470856 35.497474670 -12.500000000 29.488407135 35.488403320 -12.500000000 30.458978653 35.458980560 -12.500000000 31.384418488 35.384422302 -12.500000000 32.233222961 35.233222961 -12.500000000 32.981101990 34.981101990 -12.500000000 -33.981101990 -35.981101990 -11.500000000 -33.233226776 -36.233222961 -11.500000000 -32.384422302 -36.384418488 -11.500000000 -31.458978653 -36.458980560 -11.500000000 -30.488407135 -36.488403320 -11.500000000 -29.497472763 -36.497474670 -11.500000000 -28.499593735 -36.499591827 -11.500000000 -27.499954224 -36.499954224 -11.500000000 -26.499996185 -36.499996185 -11.500000000 -25.500000000 -36.500000000 -11.500000000 -24.500000000 -36.500000000 -11.500000000 -23.500000000 -36.500000000 -11.500000000 -22.500000000 -36.500000000 -11.500000000 -21.500000000 -36.500000000 -11.500000000 -20.500000000 -36.500000000 -11.500000000 -19.500000000 -36.500000000 -11.500000000 -18.500000000 -36.500000000 -11.500000000 -17.500000000 -36.500000000 -11.500000000 -16.500000000 -36.500000000 -11.500000000 -15.500000000 -36.500000000 -11.500000000 -14.500000000 -36.500000000 -11.500000000 -13.500000000 -36.500000000 -11.500000000 -12.500000000 -36.500000000 -11.500000000 -11.500000000 -36.500000000 -11.500000000 -10.500000000 -36.500000000 -11.500000000 -9.500000000 -36.500000000 -11.500000000 -8.500000000 -36.500000000 -11.500000000 -7.500000000 -36.500000000 -11.500000000 -6.500000000 -36.500000000 -11.500000000 -5.500000000 -36.500000000 -11.500000000 -4.500000000 -36.500000000 -11.500000000 -3.500000000 -36.500000000 -11.500000000 -2.500000000 -36.500000000 -11.500000000 -1.500000000 -36.500000000 -11.500000000 -0.500000000 -36.500000000 -11.500000000 0.500000000 -36.500000000 -11.500000000 1.500000000 -36.500000000 -11.500000000 2.500000000 -36.500000000 -11.500000000 3.500000000 -36.500000000 -11.500000000 4.500000000 -36.500000000 -11.500000000 5.500000000 -36.500000000 -11.500000000 6.500000000 -36.500000000 -11.500000000 7.500000000 -36.500000000 -11.500000000 8.500000000 -36.500000000 -11.500000000 9.500000000 -36.500000000 -11.500000000 10.500000000 -36.500000000 -11.500000000 11.500000000 -36.500000000 -11.500000000 12.500000000 -36.500000000 -11.500000000 13.500000000 -36.500000000 -11.500000000 14.500000000 -36.500000000 -11.500000000 15.500000000 -36.500000000 -11.500000000 16.500000000 -36.500000000 -11.500000000 17.500000000 -36.500000000 -11.500000000 18.500000000 -36.500000000 -11.500000000 19.500000000 -36.500000000 -11.500000000 20.500000000 -36.500000000 -11.500000000 21.500000000 -36.500000000 -11.500000000 22.500000000 -36.500000000 -11.500000000 23.500000000 -36.500000000 -11.500000000 24.500000000 -36.500000000 -11.500000000 25.499996185 -36.499996185 -11.500000000 26.499954224 -36.499954224 -11.500000000 27.499591827 -36.499591827 -11.500000000 28.497470856 -36.497467041 -11.500000000 29.488407135 -36.488403320 -11.500000000 30.458978653 -36.458980560 -11.500000000 31.384418488 -36.384422302 -11.500000000 32.233222961 -36.233222961 -11.500000000 32.981101990 -35.981101990 -11.500000000 -35.167964935 -35.167964935 -11.500000000 -34.622871399 -35.622871399 -11.500000000 33.622871399 -35.622871399 -11.500000000 34.167964935 -35.167964935 -11.500000000 -35.981101990 -33.981101990 -11.500000000 -35.622871399 -34.622871399 -11.500000000 34.622871399 -34.622871399 -11.500000000 34.981101990 -33.981101990 -11.500000000 -36.233222961 -33.233222961 -11.500000000 35.233222961 -33.233226776 -11.500000000 -36.384418488 -32.384422302 -11.500000000 35.384418488 -32.384422302 -11.500000000 -36.458976746 -31.458978653 -11.500000000 35.458980560 -31.458978653 -11.500000000 -36.488403320 -30.488407135 -11.500000000 35.488403320 -30.488407135 -11.500000000 -36.497467041 -29.497472763 -11.500000000 35.497474670 -29.497472763 -11.500000000 -36.499591827 -28.499593735 -11.500000000 35.499591827 -28.499593735 -11.500000000 -36.499954224 -27.499954224 -11.500000000 35.499954224 -27.499954224 -11.500000000 -36.499996185 -26.499996185 -11.500000000 35.499996185 -26.499996185 -11.500000000 -36.500000000 -25.500000000 -11.500000000 35.500000000 -25.500000000 -11.500000000 -36.500000000 -24.500000000 -11.500000000 35.500000000 -24.500000000 -11.500000000 -36.500000000 -23.500000000 -11.500000000 35.500000000 -23.500000000 -11.500000000 -36.500000000 -22.500000000 -11.500000000 35.500000000 -22.500000000 -11.500000000 -36.500000000 -21.500000000 -11.500000000 35.500000000 -21.500000000 -11.500000000 -36.500000000 -20.500000000 -11.500000000 35.500000000 -20.500000000 -11.500000000 -36.500000000 -19.500000000 -11.500000000 35.500000000 -19.500000000 -11.500000000 -36.500000000 -18.500000000 -11.500000000 35.500000000 -18.500000000 -11.500000000 -36.500000000 -17.500000000 -11.500000000 35.500000000 -17.500000000 -11.500000000 -36.500000000 -16.500000000 -11.500000000 35.500000000 -16.500000000 -11.500000000 -36.500000000 -15.500000000 -11.500000000 35.500000000 -15.500000000 -11.500000000 -36.500000000 -14.500000000 -11.500000000 35.500000000 -14.500000000 -11.500000000 -36.500000000 -13.500000000 -11.500000000 35.500000000 -13.500000000 -11.500000000 -36.500000000 -12.500000000 -11.500000000 35.500000000 -12.500000000 -11.500000000 -36.500000000 -11.500000000 -11.500000000 35.500000000 -11.500000000 -11.500000000 -36.500000000 -10.500000000 -11.500000000 35.500000000 -10.500000000 -11.500000000 -36.500000000 -9.500000000 -11.500000000 35.500000000 -9.500000000 -11.500000000 -36.500000000 -8.500000000 -11.500000000 35.500000000 -8.500000000 -11.500000000 -36.500000000 -7.500000000 -11.500000000 35.500000000 -7.500000000 -11.500000000 -36.500000000 -6.500000000 -11.500000000 35.500000000 -6.500000000 -11.500000000 -36.500000000 -5.500000000 -11.500000000 35.500000000 -5.500000000 -11.500000000 -36.500000000 -4.500000000 -11.500000000 35.500000000 -4.500000000 -11.500000000 -36.500000000 -3.500000000 -11.500000000 35.500000000 -3.500000000 -11.500000000 -36.500000000 -2.500000000 -11.500000000 35.500000000 -2.500000000 -11.500000000 -36.500000000 -1.500000000 -11.500000000 35.500000000 -1.500000000 -11.500000000 -36.500000000 -0.500000000 -11.500000000 35.500000000 -0.500000000 -11.500000000 -36.500000000 0.500000000 -11.500000000 35.500000000 0.500000000 -11.500000000 -36.500000000 1.500000000 -11.500000000 35.500000000 1.500000000 -11.500000000 -36.500000000 2.500000000 -11.500000000 35.500000000 2.500000000 -11.500000000 -36.500000000 3.500000000 -11.500000000 35.500000000 3.500000000 -11.500000000 -36.500000000 4.500000000 -11.500000000 35.500000000 4.500000000 -11.500000000 -36.500000000 5.500000000 -11.500000000 35.500000000 5.500000000 -11.500000000 -36.500000000 6.500000000 -11.500000000 35.500000000 6.500000000 -11.500000000 -36.500000000 7.500000000 -11.500000000 35.500000000 7.500000000 -11.500000000 -36.500000000 8.500000000 -11.500000000 35.500000000 8.500000000 -11.500000000 -36.500000000 9.500000000 -11.500000000 35.500000000 9.500000000 -11.500000000 -36.500000000 10.500000000 -11.500000000 35.500000000 10.500000000 -11.500000000 -36.500000000 11.500000000 -11.500000000 35.500000000 11.500000000 -11.500000000 -36.500000000 12.500000000 -11.500000000 35.500000000 12.500000000 -11.500000000 -36.500000000 13.500000000 -11.500000000 35.500000000 13.500000000 -11.500000000 -36.500000000 14.500000000 -11.500000000 35.500000000 14.500000000 -11.500000000 -36.500000000 15.500000000 -11.500000000 35.500000000 15.500000000 -11.500000000 -36.500000000 16.500000000 -11.500000000 35.500000000 16.500000000 -11.500000000 -36.500000000 17.500000000 -11.500000000 35.500000000 17.500000000 -11.500000000 -36.500000000 18.500000000 -11.500000000 35.500000000 18.500000000 -11.500000000 -36.500000000 19.500000000 -11.500000000 35.500000000 19.500000000 -11.500000000 -36.500000000 20.500000000 -11.500000000 35.500000000 20.500000000 -11.500000000 -36.500000000 21.500000000 -11.500000000 35.500000000 21.500000000 -11.500000000 -36.500000000 22.500000000 -11.500000000 35.500000000 22.500000000 -11.500000000 -36.500000000 23.500000000 -11.500000000 35.500000000 23.500000000 -11.500000000 -36.500000000 24.500000000 -11.500000000 35.500000000 24.500000000 -11.500000000 -36.499996185 25.499996185 -11.500000000 35.499996185 25.499996185 -11.500000000 -36.499954224 26.499954224 -11.500000000 35.499954224 26.499954224 -11.500000000 -36.499591827 27.499591827 -11.500000000 35.499591827 27.499591827 -11.500000000 -36.497474670 28.497470856 -11.500000000 35.497467041 28.497470856 -11.500000000 -36.488403320 29.488407135 -11.500000000 35.488403320 29.488407135 -11.500000000 -36.458980560 30.458978653 -11.500000000 35.458980560 30.458978653 -11.500000000 -36.384422302 31.384418488 -11.500000000 35.384422302 31.384418488 -11.500000000 -36.233222961 32.233222961 -11.500000000 35.233222961 32.233222961 -11.500000000 -35.981101990 32.981101990 -11.500000000 -35.622871399 33.622871399 -11.500000000 34.622871399 33.622871399 -11.500000000 34.981101990 32.981101990 -11.500000000 -35.167964935 34.167964935 -11.500000000 -34.622871399 34.622871399 -11.500000000 33.622871399 34.622871399 -11.500000000 34.167964935 34.167964935 -11.500000000 -33.981101990 34.981101990 -11.500000000 -33.233222961 35.233222961 -11.500000000 -32.384422302 35.384418488 -11.500000000 -31.458978653 35.458976746 -11.500000000 -30.488407135 35.488403320 -11.500000000 -29.497472763 35.497467041 -11.500000000 -28.499593735 35.499591827 -11.500000000 -27.499954224 35.499954224 -11.500000000 -26.499996185 35.499996185 -11.500000000 -25.500000000 35.500000000 -11.500000000 -24.500000000 35.500000000 -11.500000000 -23.500000000 35.500000000 -11.500000000 -22.500000000 35.500000000 -11.500000000 -21.500000000 35.500000000 -11.500000000 -20.500000000 35.500000000 -11.500000000 -19.500000000 35.500000000 -11.500000000 -18.500000000 35.500000000 -11.500000000 -17.500000000 35.500000000 -11.500000000 -16.500000000 35.500000000 -11.500000000 -15.500000000 35.500000000 -11.500000000 -14.500000000 35.500000000 -11.500000000 -13.500000000 35.500000000 -11.500000000 -12.500000000 35.500000000 -11.500000000 -11.500000000 35.500000000 -11.500000000 -10.500000000 35.500000000 -11.500000000 -9.500000000 35.500000000 -11.500000000 -8.500000000 35.500000000 -11.500000000 -7.500000000 35.500000000 -11.500000000 -6.500000000 35.500000000 -11.500000000 -5.500000000 35.500000000 -11.500000000 -4.500000000 35.500000000 -11.500000000 -3.500000000 35.500000000 -11.500000000 -2.500000000 35.500000000 -11.500000000 -1.500000000 35.500000000 -11.500000000 -0.500000000 35.500000000 -11.500000000 0.500000000 35.500000000 -11.500000000 1.500000000 35.500000000 -11.500000000 2.500000000 35.500000000 -11.500000000 3.500000000 35.500000000 -11.500000000 4.500000000 35.500000000 -11.500000000 5.500000000 35.500000000 -11.500000000 6.500000000 35.500000000 -11.500000000 7.500000000 35.500000000 -11.500000000 8.500000000 35.500000000 -11.500000000 9.500000000 35.500000000 -11.500000000 10.500000000 35.500000000 -11.500000000 11.500000000 35.500000000 -11.500000000 12.500000000 35.500000000 -11.500000000 13.500000000 35.500000000 -11.500000000 14.500000000 35.500000000 -11.500000000 15.500000000 35.500000000 -11.500000000 16.500000000 35.500000000 -11.500000000 17.500000000 35.500000000 -11.500000000 18.500000000 35.500000000 -11.500000000 19.500000000 35.500000000 -11.500000000 20.500000000 35.500000000 -11.500000000 21.500000000 35.500000000 -11.500000000 22.500000000 35.500000000 -11.500000000 23.500000000 35.500000000 -11.500000000 24.500000000 35.500000000 -11.500000000 25.499996185 35.499996185 -11.500000000 26.499954224 35.499954224 -11.500000000 27.499591827 35.499591827 -11.500000000 28.497470856 35.497474670 -11.500000000 29.488407135 35.488403320 -11.500000000 30.458978653 35.458980560 -11.500000000 31.384418488 35.384422302 -11.500000000 32.233222961 35.233222961 -11.500000000 32.981101990 34.981101990 -11.500000000 -33.981101990 -35.981101990 -10.500000000 -33.233226776 -36.233222961 -10.500000000 -32.384422302 -36.384418488 -10.500000000 -31.458978653 -36.458980560 -10.500000000 -30.488407135 -36.488403320 -10.500000000 -29.497472763 -36.497474670 -10.500000000 -28.499593735 -36.499591827 -10.500000000 -27.499954224 -36.499954224 -10.500000000 -26.499996185 -36.499996185 -10.500000000 -25.500000000 -36.500000000 -10.500000000 -24.500000000 -36.500000000 -10.500000000 -23.500000000 -36.500000000 -10.500000000 -22.500000000 -36.500000000 -10.500000000 -21.500000000 -36.500000000 -10.500000000 -20.500000000 -36.500000000 -10.500000000 -19.500000000 -36.500000000 -10.500000000 -18.500000000 -36.500000000 -10.500000000 -17.500000000 -36.500000000 -10.500000000 -16.500000000 -36.500000000 -10.500000000 -15.500000000 -36.500000000 -10.500000000 -14.500000000 -36.500000000 -10.500000000 -13.500000000 -36.500000000 -10.500000000 -12.500000000 -36.500000000 -10.500000000 -11.500000000 -36.500000000 -10.500000000 -10.500000000 -36.500000000 -10.500000000 -9.500000000 -36.500000000 -10.500000000 -8.500000000 -36.500000000 -10.500000000 -7.500000000 -36.500000000 -10.500000000 -6.500000000 -36.500000000 -10.500000000 -5.500000000 -36.500000000 -10.500000000 -4.500000000 -36.500000000 -10.500000000 -3.500000000 -36.500000000 -10.500000000 -2.500000000 -36.500000000 -10.500000000 -1.500000000 -36.500000000 -10.500000000 -0.500000000 -36.500000000 -10.500000000 0.500000000 -36.500000000 -10.500000000 1.500000000 -36.500000000 -10.500000000 2.500000000 -36.500000000 -10.500000000 3.500000000 -36.500000000 -10.500000000 4.500000000 -36.500000000 -10.500000000 5.500000000 -36.500000000 -10.500000000 6.500000000 -36.500000000 -10.500000000 7.500000000 -36.500000000 -10.500000000 8.500000000 -36.500000000 -10.500000000 9.500000000 -36.500000000 -10.500000000 10.500000000 -36.500000000 -10.500000000 11.500000000 -36.500000000 -10.500000000 12.500000000 -36.500000000 -10.500000000 13.500000000 -36.500000000 -10.500000000 14.500000000 -36.500000000 -10.500000000 15.500000000 -36.500000000 -10.500000000 16.500000000 -36.500000000 -10.500000000 17.500000000 -36.500000000 -10.500000000 18.500000000 -36.500000000 -10.500000000 19.500000000 -36.500000000 -10.500000000 20.500000000 -36.500000000 -10.500000000 21.500000000 -36.500000000 -10.500000000 22.500000000 -36.500000000 -10.500000000 23.500000000 -36.500000000 -10.500000000 24.500000000 -36.500000000 -10.500000000 25.499996185 -36.499996185 -10.500000000 26.499954224 -36.499954224 -10.500000000 27.499591827 -36.499591827 -10.500000000 28.497470856 -36.497467041 -10.500000000 29.488407135 -36.488403320 -10.500000000 30.458978653 -36.458980560 -10.500000000 31.384418488 -36.384422302 -10.500000000 32.233222961 -36.233222961 -10.500000000 32.981101990 -35.981101990 -10.500000000 -35.167964935 -35.167964935 -10.500000000 -34.622871399 -35.622871399 -10.500000000 33.622871399 -35.622871399 -10.500000000 34.167964935 -35.167964935 -10.500000000 -35.981101990 -33.981101990 -10.500000000 -35.622871399 -34.622871399 -10.500000000 34.622871399 -34.622871399 -10.500000000 34.981101990 -33.981101990 -10.500000000 -36.233222961 -33.233222961 -10.500000000 35.233222961 -33.233226776 -10.500000000 -36.384418488 -32.384422302 -10.500000000 35.384418488 -32.384422302 -10.500000000 -36.458976746 -31.458978653 -10.500000000 35.458980560 -31.458978653 -10.500000000 -36.488403320 -30.488407135 -10.500000000 35.488403320 -30.488407135 -10.500000000 -36.497467041 -29.497472763 -10.500000000 35.497474670 -29.497472763 -10.500000000 -36.499591827 -28.499593735 -10.500000000 35.499591827 -28.499593735 -10.500000000 -36.499954224 -27.499954224 -10.500000000 35.499954224 -27.499954224 -10.500000000 -36.499996185 -26.499996185 -10.500000000 35.499996185 -26.499996185 -10.500000000 -36.500000000 -25.500000000 -10.500000000 35.500000000 -25.500000000 -10.500000000 -36.500000000 -24.500000000 -10.500000000 35.500000000 -24.500000000 -10.500000000 -36.500000000 -23.500000000 -10.500000000 35.500000000 -23.500000000 -10.500000000 -36.500000000 -22.500000000 -10.500000000 35.500000000 -22.500000000 -10.500000000 -36.500000000 -21.500000000 -10.500000000 35.500000000 -21.500000000 -10.500000000 -36.500000000 -20.500000000 -10.500000000 35.500000000 -20.500000000 -10.500000000 -36.500000000 -19.500000000 -10.500000000 35.500000000 -19.500000000 -10.500000000 -36.500000000 -18.500000000 -10.500000000 35.500000000 -18.500000000 -10.500000000 -36.500000000 -17.500000000 -10.500000000 35.500000000 -17.500000000 -10.500000000 -36.500000000 -16.500000000 -10.500000000 35.500000000 -16.500000000 -10.500000000 -36.500000000 -15.500000000 -10.500000000 35.500000000 -15.500000000 -10.500000000 -36.500000000 -14.500000000 -10.500000000 35.500000000 -14.500000000 -10.500000000 -36.500000000 -13.500000000 -10.500000000 35.500000000 -13.500000000 -10.500000000 -36.500000000 -12.500000000 -10.500000000 35.500000000 -12.500000000 -10.500000000 -36.500000000 -11.500000000 -10.500000000 35.500000000 -11.500000000 -10.500000000 -36.500000000 -10.500000000 -10.500000000 35.500000000 -10.500000000 -10.500000000 -36.500000000 -9.500000000 -10.500000000 35.500000000 -9.500000000 -10.500000000 -36.500000000 -8.500000000 -10.500000000 35.500000000 -8.500000000 -10.500000000 -36.500000000 -7.500000000 -10.500000000 35.500000000 -7.500000000 -10.500000000 -36.500000000 -6.500000000 -10.500000000 35.500000000 -6.500000000 -10.500000000 -36.500000000 -5.500000000 -10.500000000 35.500000000 -5.500000000 -10.500000000 -36.500000000 -4.500000000 -10.500000000 35.500000000 -4.500000000 -10.500000000 -36.500000000 -3.500000000 -10.500000000 35.500000000 -3.500000000 -10.500000000 -36.500000000 -2.500000000 -10.500000000 35.500000000 -2.500000000 -10.500000000 -36.500000000 -1.500000000 -10.500000000 35.500000000 -1.500000000 -10.500000000 -36.500000000 -0.500000000 -10.500000000 35.500000000 -0.500000000 -10.500000000 -36.500000000 0.500000000 -10.500000000 35.500000000 0.500000000 -10.500000000 -36.500000000 1.500000000 -10.500000000 35.500000000 1.500000000 -10.500000000 -36.500000000 2.500000000 -10.500000000 35.500000000 2.500000000 -10.500000000 -36.500000000 3.500000000 -10.500000000 35.500000000 3.500000000 -10.500000000 -36.500000000 4.500000000 -10.500000000 35.500000000 4.500000000 -10.500000000 -36.500000000 5.500000000 -10.500000000 35.500000000 5.500000000 -10.500000000 -36.500000000 6.500000000 -10.500000000 35.500000000 6.500000000 -10.500000000 -36.500000000 7.500000000 -10.500000000 35.500000000 7.500000000 -10.500000000 -36.500000000 8.500000000 -10.500000000 35.500000000 8.500000000 -10.500000000 -36.500000000 9.500000000 -10.500000000 35.500000000 9.500000000 -10.500000000 -36.500000000 10.500000000 -10.500000000 35.500000000 10.500000000 -10.500000000 -36.500000000 11.500000000 -10.500000000 35.500000000 11.500000000 -10.500000000 -36.500000000 12.500000000 -10.500000000 35.500000000 12.500000000 -10.500000000 -36.500000000 13.500000000 -10.500000000 35.500000000 13.500000000 -10.500000000 -36.500000000 14.500000000 -10.500000000 35.500000000 14.500000000 -10.500000000 -36.500000000 15.500000000 -10.500000000 35.500000000 15.500000000 -10.500000000 -36.500000000 16.500000000 -10.500000000 35.500000000 16.500000000 -10.500000000 -36.500000000 17.500000000 -10.500000000 35.500000000 17.500000000 -10.500000000 -36.500000000 18.500000000 -10.500000000 35.500000000 18.500000000 -10.500000000 -36.500000000 19.500000000 -10.500000000 35.500000000 19.500000000 -10.500000000 -36.500000000 20.500000000 -10.500000000 35.500000000 20.500000000 -10.500000000 -36.500000000 21.500000000 -10.500000000 35.500000000 21.500000000 -10.500000000 -36.500000000 22.500000000 -10.500000000 35.500000000 22.500000000 -10.500000000 -36.500000000 23.500000000 -10.500000000 35.500000000 23.500000000 -10.500000000 -36.500000000 24.500000000 -10.500000000 35.500000000 24.500000000 -10.500000000 -36.499996185 25.499996185 -10.500000000 35.499996185 25.499996185 -10.500000000 -36.499954224 26.499954224 -10.500000000 35.499954224 26.499954224 -10.500000000 -36.499591827 27.499591827 -10.500000000 35.499591827 27.499591827 -10.500000000 -36.497474670 28.497470856 -10.500000000 35.497467041 28.497470856 -10.500000000 -36.488403320 29.488407135 -10.500000000 35.488403320 29.488407135 -10.500000000 -36.458980560 30.458978653 -10.500000000 35.458980560 30.458978653 -10.500000000 -36.384422302 31.384418488 -10.500000000 35.384422302 31.384418488 -10.500000000 -36.233222961 32.233222961 -10.500000000 35.233222961 32.233222961 -10.500000000 -35.981101990 32.981101990 -10.500000000 -35.622871399 33.622871399 -10.500000000 34.622871399 33.622871399 -10.500000000 34.981101990 32.981101990 -10.500000000 -35.167964935 34.167964935 -10.500000000 -34.622871399 34.622871399 -10.500000000 33.622871399 34.622871399 -10.500000000 34.167964935 34.167964935 -10.500000000 -33.981101990 34.981101990 -10.500000000 -33.233222961 35.233222961 -10.500000000 -32.384422302 35.384418488 -10.500000000 -31.458978653 35.458976746 -10.500000000 -30.488407135 35.488403320 -10.500000000 -29.497472763 35.497467041 -10.500000000 -28.499593735 35.499591827 -10.500000000 -27.499954224 35.499954224 -10.500000000 -26.499996185 35.499996185 -10.500000000 -25.500000000 35.500000000 -10.500000000 -24.500000000 35.500000000 -10.500000000 -23.500000000 35.500000000 -10.500000000 -22.500000000 35.500000000 -10.500000000 -21.500000000 35.500000000 -10.500000000 -20.500000000 35.500000000 -10.500000000 -19.500000000 35.500000000 -10.500000000 -18.500000000 35.500000000 -10.500000000 -17.500000000 35.500000000 -10.500000000 -16.500000000 35.500000000 -10.500000000 -15.500000000 35.500000000 -10.500000000 -14.500000000 35.500000000 -10.500000000 -13.500000000 35.500000000 -10.500000000 -12.500000000 35.500000000 -10.500000000 -11.500000000 35.500000000 -10.500000000 -10.500000000 35.500000000 -10.500000000 -9.500000000 35.500000000 -10.500000000 -8.500000000 35.500000000 -10.500000000 -7.500000000 35.500000000 -10.500000000 -6.500000000 35.500000000 -10.500000000 -5.500000000 35.500000000 -10.500000000 -4.500000000 35.500000000 -10.500000000 -3.500000000 35.500000000 -10.500000000 -2.500000000 35.500000000 -10.500000000 -1.500000000 35.500000000 -10.500000000 -0.500000000 35.500000000 -10.500000000 0.500000000 35.500000000 -10.500000000 1.500000000 35.500000000 -10.500000000 2.500000000 35.500000000 -10.500000000 3.500000000 35.500000000 -10.500000000 4.500000000 35.500000000 -10.500000000 5.500000000 35.500000000 -10.500000000 6.500000000 35.500000000 -10.500000000 7.500000000 35.500000000 -10.500000000 8.500000000 35.500000000 -10.500000000 9.500000000 35.500000000 -10.500000000 10.500000000 35.500000000 -10.500000000 11.500000000 35.500000000 -10.500000000 12.500000000 35.500000000 -10.500000000 13.500000000 35.500000000 -10.500000000 14.500000000 35.500000000 -10.500000000 15.500000000 35.500000000 -10.500000000 16.500000000 35.500000000 -10.500000000 17.500000000 35.500000000 -10.500000000 18.500000000 35.500000000 -10.500000000 19.500000000 35.500000000 -10.500000000 20.500000000 35.500000000 -10.500000000 21.500000000 35.500000000 -10.500000000 22.500000000 35.500000000 -10.500000000 23.500000000 35.500000000 -10.500000000 24.500000000 35.500000000 -10.500000000 25.499996185 35.499996185 -10.500000000 26.499954224 35.499954224 -10.500000000 27.499591827 35.499591827 -10.500000000 28.497470856 35.497474670 -10.500000000 29.488407135 35.488403320 -10.500000000 30.458978653 35.458980560 -10.500000000 31.384418488 35.384422302 -10.500000000 32.233222961 35.233222961 -10.500000000 32.981101990 34.981101990 -10.500000000 -33.981101990 -35.981101990 -9.500000000 -33.233226776 -36.233222961 -9.500000000 -32.384422302 -36.384418488 -9.500000000 -31.458978653 -36.458980560 -9.500000000 -30.488407135 -36.488403320 -9.500000000 -29.497472763 -36.497474670 -9.500000000 -28.499593735 -36.499591827 -9.500000000 -27.499954224 -36.499954224 -9.500000000 -26.499996185 -36.499996185 -9.500000000 -25.500000000 -36.500000000 -9.500000000 -24.500000000 -36.500000000 -9.500000000 -23.500000000 -36.500000000 -9.500000000 -22.500000000 -36.500000000 -9.500000000 -21.500000000 -36.500000000 -9.500000000 -20.500000000 -36.500000000 -9.500000000 -19.500000000 -36.500000000 -9.500000000 -18.500000000 -36.500000000 -9.500000000 -17.500000000 -36.500000000 -9.500000000 -16.500000000 -36.500000000 -9.500000000 -15.500000000 -36.500000000 -9.500000000 -14.500000000 -36.500000000 -9.500000000 -13.500000000 -36.500000000 -9.500000000 -12.500000000 -36.500000000 -9.500000000 -11.500000000 -36.500000000 -9.500000000 -10.500000000 -36.500000000 -9.500000000 -9.500000000 -36.500000000 -9.500000000 -8.500000000 -36.500000000 -9.500000000 -7.500000000 -36.500000000 -9.500000000 -6.500000000 -36.500000000 -9.500000000 -5.500000000 -36.500000000 -9.500000000 -4.500000000 -36.500000000 -9.500000000 -3.500000000 -36.500000000 -9.500000000 -2.500000000 -36.500000000 -9.500000000 -1.500000000 -36.500000000 -9.500000000 -0.500000000 -36.500000000 -9.500000000 0.500000000 -36.500000000 -9.500000000 1.500000000 -36.500000000 -9.500000000 2.500000000 -36.500000000 -9.500000000 3.500000000 -36.500000000 -9.500000000 4.500000000 -36.500000000 -9.500000000 5.500000000 -36.500000000 -9.500000000 6.500000000 -36.500000000 -9.500000000 7.500000000 -36.500000000 -9.500000000 8.500000000 -36.500000000 -9.500000000 9.500000000 -36.500000000 -9.500000000 10.500000000 -36.500000000 -9.500000000 11.500000000 -36.500000000 -9.500000000 12.500000000 -36.500000000 -9.500000000 13.500000000 -36.500000000 -9.500000000 14.500000000 -36.500000000 -9.500000000 15.500000000 -36.500000000 -9.500000000 16.500000000 -36.500000000 -9.500000000 17.500000000 -36.500000000 -9.500000000 18.500000000 -36.500000000 -9.500000000 19.500000000 -36.500000000 -9.500000000 20.500000000 -36.500000000 -9.500000000 21.500000000 -36.500000000 -9.500000000 22.500000000 -36.500000000 -9.500000000 23.500000000 -36.500000000 -9.500000000 24.500000000 -36.500000000 -9.500000000 25.499996185 -36.499996185 -9.500000000 26.499954224 -36.499954224 -9.500000000 27.499591827 -36.499591827 -9.500000000 28.497470856 -36.497467041 -9.500000000 29.488407135 -36.488403320 -9.500000000 30.458978653 -36.458980560 -9.500000000 31.384418488 -36.384422302 -9.500000000 32.233222961 -36.233222961 -9.500000000 32.981101990 -35.981101990 -9.500000000 -35.167964935 -35.167964935 -9.500000000 -34.622871399 -35.622871399 -9.500000000 33.622871399 -35.622871399 -9.500000000 34.167964935 -35.167964935 -9.500000000 -35.981101990 -33.981101990 -9.500000000 -35.622871399 -34.622871399 -9.500000000 34.622871399 -34.622871399 -9.500000000 34.981101990 -33.981101990 -9.500000000 -36.233222961 -33.233222961 -9.500000000 35.233222961 -33.233226776 -9.500000000 -36.384418488 -32.384422302 -9.500000000 35.384418488 -32.384422302 -9.500000000 -36.458976746 -31.458978653 -9.500000000 35.458980560 -31.458978653 -9.500000000 -36.488403320 -30.488407135 -9.500000000 35.488403320 -30.488407135 -9.500000000 -36.497467041 -29.497472763 -9.500000000 35.497474670 -29.497472763 -9.500000000 -36.499591827 -28.499593735 -9.500000000 35.499591827 -28.499593735 -9.500000000 -36.499954224 -27.499954224 -9.500000000 35.499954224 -27.499954224 -9.500000000 -36.499996185 -26.499996185 -9.500000000 35.499996185 -26.499996185 -9.500000000 -36.500000000 -25.500000000 -9.500000000 35.500000000 -25.500000000 -9.500000000 -36.500000000 -24.500000000 -9.500000000 35.500000000 -24.500000000 -9.500000000 -36.500000000 -23.500000000 -9.500000000 35.500000000 -23.500000000 -9.500000000 -36.500000000 -22.500000000 -9.500000000 35.500000000 -22.500000000 -9.500000000 -36.500000000 -21.500000000 -9.500000000 35.500000000 -21.500000000 -9.500000000 -36.500000000 -20.500000000 -9.500000000 35.500000000 -20.500000000 -9.500000000 -36.500000000 -19.500000000 -9.500000000 35.500000000 -19.500000000 -9.500000000 -36.500000000 -18.500000000 -9.500000000 35.500000000 -18.500000000 -9.500000000 -36.500000000 -17.500000000 -9.500000000 35.500000000 -17.500000000 -9.500000000 -36.500000000 -16.500000000 -9.500000000 35.500000000 -16.500000000 -9.500000000 -36.500000000 -15.500000000 -9.500000000 35.500000000 -15.500000000 -9.500000000 -36.500000000 -14.500000000 -9.500000000 35.500000000 -14.500000000 -9.500000000 -36.500000000 -13.500000000 -9.500000000 35.500000000 -13.500000000 -9.500000000 -36.500000000 -12.500000000 -9.500000000 35.500000000 -12.500000000 -9.500000000 -36.500000000 -11.500000000 -9.500000000 35.500000000 -11.500000000 -9.500000000 -36.500000000 -10.500000000 -9.500000000 35.500000000 -10.500000000 -9.500000000 -36.500000000 -9.500000000 -9.500000000 35.500000000 -9.500000000 -9.500000000 -36.500000000 -8.500000000 -9.500000000 35.500000000 -8.500000000 -9.500000000 -36.500000000 -7.500000000 -9.500000000 35.500000000 -7.500000000 -9.500000000 -36.500000000 -6.500000000 -9.500000000 35.500000000 -6.500000000 -9.500000000 -36.500000000 -5.500000000 -9.500000000 35.500000000 -5.500000000 -9.500000000 -36.500000000 -4.500000000 -9.500000000 35.500000000 -4.500000000 -9.500000000 -36.500000000 -3.500000000 -9.500000000 35.500000000 -3.500000000 -9.500000000 -36.500000000 -2.500000000 -9.500000000 35.500000000 -2.500000000 -9.500000000 -36.500000000 -1.500000000 -9.500000000 35.500000000 -1.500000000 -9.500000000 -36.500000000 -0.500000000 -9.500000000 35.500000000 -0.500000000 -9.500000000 -36.500000000 0.500000000 -9.500000000 35.500000000 0.500000000 -9.500000000 -36.500000000 1.500000000 -9.500000000 35.500000000 1.500000000 -9.500000000 -36.500000000 2.500000000 -9.500000000 35.500000000 2.500000000 -9.500000000 -36.500000000 3.500000000 -9.500000000 35.500000000 3.500000000 -9.500000000 -36.500000000 4.500000000 -9.500000000 35.500000000 4.500000000 -9.500000000 -36.500000000 5.500000000 -9.500000000 35.500000000 5.500000000 -9.500000000 -36.500000000 6.500000000 -9.500000000 35.500000000 6.500000000 -9.500000000 -36.500000000 7.500000000 -9.500000000 35.500000000 7.500000000 -9.500000000 -36.500000000 8.500000000 -9.500000000 35.500000000 8.500000000 -9.500000000 -36.500000000 9.500000000 -9.500000000 35.500000000 9.500000000 -9.500000000 -36.500000000 10.500000000 -9.500000000 35.500000000 10.500000000 -9.500000000 -36.500000000 11.500000000 -9.500000000 35.500000000 11.500000000 -9.500000000 -36.500000000 12.500000000 -9.500000000 35.500000000 12.500000000 -9.500000000 -36.500000000 13.500000000 -9.500000000 35.500000000 13.500000000 -9.500000000 -36.500000000 14.500000000 -9.500000000 35.500000000 14.500000000 -9.500000000 -36.500000000 15.500000000 -9.500000000 35.500000000 15.500000000 -9.500000000 -36.500000000 16.500000000 -9.500000000 35.500000000 16.500000000 -9.500000000 -36.500000000 17.500000000 -9.500000000 35.500000000 17.500000000 -9.500000000 -36.500000000 18.500000000 -9.500000000 35.500000000 18.500000000 -9.500000000 -36.500000000 19.500000000 -9.500000000 35.500000000 19.500000000 -9.500000000 -36.500000000 20.500000000 -9.500000000 35.500000000 20.500000000 -9.500000000 -36.500000000 21.500000000 -9.500000000 35.500000000 21.500000000 -9.500000000 -36.500000000 22.500000000 -9.500000000 35.500000000 22.500000000 -9.500000000 -36.500000000 23.500000000 -9.500000000 35.500000000 23.500000000 -9.500000000 -36.500000000 24.500000000 -9.500000000 35.500000000 24.500000000 -9.500000000 -36.499996185 25.499996185 -9.500000000 35.499996185 25.499996185 -9.500000000 -36.499954224 26.499954224 -9.500000000 35.499954224 26.499954224 -9.500000000 -36.499591827 27.499591827 -9.500000000 35.499591827 27.499591827 -9.500000000 -36.497474670 28.497470856 -9.500000000 35.497467041 28.497470856 -9.500000000 -36.488403320 29.488407135 -9.500000000 35.488403320 29.488407135 -9.500000000 -36.458980560 30.458978653 -9.500000000 35.458980560 30.458978653 -9.500000000 -36.384422302 31.384418488 -9.500000000 35.384422302 31.384418488 -9.500000000 -36.233222961 32.233222961 -9.500000000 35.233222961 32.233222961 -9.500000000 -35.981101990 32.981101990 -9.500000000 -35.622871399 33.622871399 -9.500000000 34.622871399 33.622871399 -9.500000000 34.981101990 32.981101990 -9.500000000 -35.167964935 34.167964935 -9.500000000 -34.622871399 34.622871399 -9.500000000 33.622871399 34.622871399 -9.500000000 34.167964935 34.167964935 -9.500000000 -33.981101990 34.981101990 -9.500000000 -33.233222961 35.233222961 -9.500000000 -32.384422302 35.384418488 -9.500000000 -31.458978653 35.458976746 -9.500000000 -30.488407135 35.488403320 -9.500000000 -29.497472763 35.497467041 -9.500000000 -28.499593735 35.499591827 -9.500000000 -27.499954224 35.499954224 -9.500000000 -26.499996185 35.499996185 -9.500000000 -25.500000000 35.500000000 -9.500000000 -24.500000000 35.500000000 -9.500000000 -23.500000000 35.500000000 -9.500000000 -22.500000000 35.500000000 -9.500000000 -21.500000000 35.500000000 -9.500000000 -20.500000000 35.500000000 -9.500000000 -19.500000000 35.500000000 -9.500000000 -18.500000000 35.500000000 -9.500000000 -17.500000000 35.500000000 -9.500000000 -16.500000000 35.500000000 -9.500000000 -15.500000000 35.500000000 -9.500000000 -14.500000000 35.500000000 -9.500000000 -13.500000000 35.500000000 -9.500000000 -12.500000000 35.500000000 -9.500000000 -11.500000000 35.500000000 -9.500000000 -10.500000000 35.500000000 -9.500000000 -9.500000000 35.500000000 -9.500000000 -8.500000000 35.500000000 -9.500000000 -7.500000000 35.500000000 -9.500000000 -6.500000000 35.500000000 -9.500000000 -5.500000000 35.500000000 -9.500000000 -4.500000000 35.500000000 -9.500000000 -3.500000000 35.500000000 -9.500000000 -2.500000000 35.500000000 -9.500000000 -1.500000000 35.500000000 -9.500000000 -0.500000000 35.500000000 -9.500000000 0.500000000 35.500000000 -9.500000000 1.500000000 35.500000000 -9.500000000 2.500000000 35.500000000 -9.500000000 3.500000000 35.500000000 -9.500000000 4.500000000 35.500000000 -9.500000000 5.500000000 35.500000000 -9.500000000 6.500000000 35.500000000 -9.500000000 7.500000000 35.500000000 -9.500000000 8.500000000 35.500000000 -9.500000000 9.500000000 35.500000000 -9.500000000 10.500000000 35.500000000 -9.500000000 11.500000000 35.500000000 -9.500000000 12.500000000 35.500000000 -9.500000000 13.500000000 35.500000000 -9.500000000 14.500000000 35.500000000 -9.500000000 15.500000000 35.500000000 -9.500000000 16.500000000 35.500000000 -9.500000000 17.500000000 35.500000000 -9.500000000 18.500000000 35.500000000 -9.500000000 19.500000000 35.500000000 -9.500000000 20.500000000 35.500000000 -9.500000000 21.500000000 35.500000000 -9.500000000 22.500000000 35.500000000 -9.500000000 23.500000000 35.500000000 -9.500000000 24.500000000 35.500000000 -9.500000000 25.499996185 35.499996185 -9.500000000 26.499954224 35.499954224 -9.500000000 27.499591827 35.499591827 -9.500000000 28.497470856 35.497474670 -9.500000000 29.488407135 35.488403320 -9.500000000 30.458978653 35.458980560 -9.500000000 31.384418488 35.384422302 -9.500000000 32.233222961 35.233222961 -9.500000000 32.981101990 34.981101990 -9.500000000 -33.981101990 -35.981101990 -8.500000000 -33.233226776 -36.233222961 -8.500000000 -32.384422302 -36.384418488 -8.500000000 -31.458978653 -36.458980560 -8.500000000 -30.488407135 -36.488403320 -8.500000000 -29.497472763 -36.497474670 -8.500000000 -28.499593735 -36.499591827 -8.500000000 -27.499954224 -36.499954224 -8.500000000 -26.499996185 -36.499996185 -8.500000000 -25.500000000 -36.500000000 -8.500000000 -24.500000000 -36.500000000 -8.500000000 -23.500000000 -36.500000000 -8.500000000 -22.500000000 -36.500000000 -8.500000000 -21.500000000 -36.500000000 -8.500000000 -20.500000000 -36.500000000 -8.500000000 -19.500000000 -36.500000000 -8.500000000 -18.500000000 -36.500000000 -8.500000000 -17.500000000 -36.500000000 -8.500000000 -16.500000000 -36.500000000 -8.500000000 -15.500000000 -36.500000000 -8.500000000 -14.500000000 -36.500000000 -8.500000000 -13.500000000 -36.500000000 -8.500000000 -12.500000000 -36.500000000 -8.500000000 -11.500000000 -36.500000000 -8.500000000 -10.500000000 -36.500000000 -8.500000000 -9.500000000 -36.500000000 -8.500000000 -8.500000000 -36.500000000 -8.500000000 -7.500000000 -36.500000000 -8.500000000 -6.500000000 -36.500000000 -8.500000000 -5.500000000 -36.500000000 -8.500000000 -4.500000000 -36.500000000 -8.500000000 -3.500000000 -36.500000000 -8.500000000 -2.500000000 -36.500000000 -8.500000000 -1.500000000 -36.500000000 -8.500000000 -0.500000000 -36.500000000 -8.500000000 0.500000000 -36.500000000 -8.500000000 1.500000000 -36.500000000 -8.500000000 2.500000000 -36.500000000 -8.500000000 3.500000000 -36.500000000 -8.500000000 4.500000000 -36.500000000 -8.500000000 5.500000000 -36.500000000 -8.500000000 6.500000000 -36.500000000 -8.500000000 7.500000000 -36.500000000 -8.500000000 8.500000000 -36.500000000 -8.500000000 9.500000000 -36.500000000 -8.500000000 10.500000000 -36.500000000 -8.500000000 11.500000000 -36.500000000 -8.500000000 12.500000000 -36.500000000 -8.500000000 13.500000000 -36.500000000 -8.500000000 14.500000000 -36.500000000 -8.500000000 15.500000000 -36.500000000 -8.500000000 16.500000000 -36.500000000 -8.500000000 17.500000000 -36.500000000 -8.500000000 18.500000000 -36.500000000 -8.500000000 19.500000000 -36.500000000 -8.500000000 20.500000000 -36.500000000 -8.500000000 21.500000000 -36.500000000 -8.500000000 22.500000000 -36.500000000 -8.500000000 23.500000000 -36.500000000 -8.500000000 24.500000000 -36.500000000 -8.500000000 25.499996185 -36.499996185 -8.500000000 26.499954224 -36.499954224 -8.500000000 27.499591827 -36.499591827 -8.500000000 28.497470856 -36.497467041 -8.500000000 29.488407135 -36.488403320 -8.500000000 30.458978653 -36.458980560 -8.500000000 31.384418488 -36.384422302 -8.500000000 32.233222961 -36.233222961 -8.500000000 32.981101990 -35.981101990 -8.500000000 -35.167964935 -35.167964935 -8.500000000 -34.622871399 -35.622871399 -8.500000000 33.622871399 -35.622871399 -8.500000000 34.167964935 -35.167964935 -8.500000000 -35.981101990 -33.981101990 -8.500000000 -35.622871399 -34.622871399 -8.500000000 34.622871399 -34.622871399 -8.500000000 34.981101990 -33.981101990 -8.500000000 -36.233222961 -33.233222961 -8.500000000 35.233222961 -33.233226776 -8.500000000 -36.384418488 -32.384422302 -8.500000000 35.384418488 -32.384422302 -8.500000000 -36.458976746 -31.458978653 -8.500000000 35.458980560 -31.458978653 -8.500000000 -36.488403320 -30.488407135 -8.500000000 35.488403320 -30.488407135 -8.500000000 -36.497467041 -29.497472763 -8.500000000 35.497474670 -29.497472763 -8.500000000 -36.499591827 -28.499593735 -8.500000000 35.499591827 -28.499593735 -8.500000000 -36.499954224 -27.499954224 -8.500000000 35.499954224 -27.499954224 -8.500000000 -36.499996185 -26.499996185 -8.500000000 35.499996185 -26.499996185 -8.500000000 -36.500000000 -25.500000000 -8.500000000 35.500000000 -25.500000000 -8.500000000 -36.500000000 -24.500000000 -8.500000000 35.500000000 -24.500000000 -8.500000000 -36.500000000 -23.500000000 -8.500000000 35.500000000 -23.500000000 -8.500000000 -36.500000000 -22.500000000 -8.500000000 35.500000000 -22.500000000 -8.500000000 -36.500000000 -21.500000000 -8.500000000 35.500000000 -21.500000000 -8.500000000 -36.500000000 -20.500000000 -8.500000000 35.500000000 -20.500000000 -8.500000000 -36.500000000 -19.500000000 -8.500000000 35.500000000 -19.500000000 -8.500000000 -36.500000000 -18.500000000 -8.500000000 35.500000000 -18.500000000 -8.500000000 -36.500000000 -17.500000000 -8.500000000 35.500000000 -17.500000000 -8.500000000 -36.500000000 -16.500000000 -8.500000000 35.500000000 -16.500000000 -8.500000000 -36.500000000 -15.500000000 -8.500000000 35.500000000 -15.500000000 -8.500000000 -36.500000000 -14.500000000 -8.500000000 35.500000000 -14.500000000 -8.500000000 -36.500000000 -13.500000000 -8.500000000 35.500000000 -13.500000000 -8.500000000 -36.500000000 -12.500000000 -8.500000000 35.500000000 -12.500000000 -8.500000000 -36.500000000 -11.500000000 -8.500000000 35.500000000 -11.500000000 -8.500000000 -36.500000000 -10.500000000 -8.500000000 35.500000000 -10.500000000 -8.500000000 -36.500000000 -9.500000000 -8.500000000 35.500000000 -9.500000000 -8.500000000 -36.500000000 -8.500000000 -8.500000000 35.500000000 -8.500000000 -8.500000000 -36.500000000 -7.500000000 -8.500000000 35.500000000 -7.500000000 -8.500000000 -36.500000000 -6.500000000 -8.500000000 35.500000000 -6.500000000 -8.500000000 -36.500000000 -5.500000000 -8.500000000 35.500000000 -5.500000000 -8.500000000 -36.500000000 -4.500000000 -8.500000000 35.500000000 -4.500000000 -8.500000000 -36.500000000 -3.500000000 -8.500000000 35.500000000 -3.500000000 -8.500000000 -36.500000000 -2.500000000 -8.500000000 35.500000000 -2.500000000 -8.500000000 -36.500000000 -1.500000000 -8.500000000 35.500000000 -1.500000000 -8.500000000 -36.500000000 -0.500000000 -8.500000000 35.500000000 -0.500000000 -8.500000000 -36.500000000 0.500000000 -8.500000000 35.500000000 0.500000000 -8.500000000 -36.500000000 1.500000000 -8.500000000 35.500000000 1.500000000 -8.500000000 -36.500000000 2.500000000 -8.500000000 35.500000000 2.500000000 -8.500000000 -36.500000000 3.500000000 -8.500000000 35.500000000 3.500000000 -8.500000000 -36.500000000 4.500000000 -8.500000000 35.500000000 4.500000000 -8.500000000 -36.500000000 5.500000000 -8.500000000 35.500000000 5.500000000 -8.500000000 -36.500000000 6.500000000 -8.500000000 35.500000000 6.500000000 -8.500000000 -36.500000000 7.500000000 -8.500000000 35.500000000 7.500000000 -8.500000000 -36.500000000 8.500000000 -8.500000000 35.500000000 8.500000000 -8.500000000 -36.500000000 9.500000000 -8.500000000 35.500000000 9.500000000 -8.500000000 -36.500000000 10.500000000 -8.500000000 35.500000000 10.500000000 -8.500000000 -36.500000000 11.500000000 -8.500000000 35.500000000 11.500000000 -8.500000000 -36.500000000 12.500000000 -8.500000000 35.500000000 12.500000000 -8.500000000 -36.500000000 13.500000000 -8.500000000 35.500000000 13.500000000 -8.500000000 -36.500000000 14.500000000 -8.500000000 35.500000000 14.500000000 -8.500000000 -36.500000000 15.500000000 -8.500000000 35.500000000 15.500000000 -8.500000000 -36.500000000 16.500000000 -8.500000000 35.500000000 16.500000000 -8.500000000 -36.500000000 17.500000000 -8.500000000 35.500000000 17.500000000 -8.500000000 -36.500000000 18.500000000 -8.500000000 35.500000000 18.500000000 -8.500000000 -36.500000000 19.500000000 -8.500000000 35.500000000 19.500000000 -8.500000000 -36.500000000 20.500000000 -8.500000000 35.500000000 20.500000000 -8.500000000 -36.500000000 21.500000000 -8.500000000 35.500000000 21.500000000 -8.500000000 -36.500000000 22.500000000 -8.500000000 35.500000000 22.500000000 -8.500000000 -36.500000000 23.500000000 -8.500000000 35.500000000 23.500000000 -8.500000000 -36.500000000 24.500000000 -8.500000000 35.500000000 24.500000000 -8.500000000 -36.499996185 25.499996185 -8.500000000 35.499996185 25.499996185 -8.500000000 -36.499954224 26.499954224 -8.500000000 35.499954224 26.499954224 -8.500000000 -36.499591827 27.499591827 -8.500000000 35.499591827 27.499591827 -8.500000000 -36.497474670 28.497470856 -8.500000000 35.497467041 28.497470856 -8.500000000 -36.488403320 29.488407135 -8.500000000 35.488403320 29.488407135 -8.500000000 -36.458980560 30.458978653 -8.500000000 35.458980560 30.458978653 -8.500000000 -36.384422302 31.384418488 -8.500000000 35.384422302 31.384418488 -8.500000000 -36.233222961 32.233222961 -8.500000000 35.233222961 32.233222961 -8.500000000 -35.981101990 32.981101990 -8.500000000 -35.622871399 33.622871399 -8.500000000 34.622871399 33.622871399 -8.500000000 34.981101990 32.981101990 -8.500000000 -35.167964935 34.167964935 -8.500000000 -34.622871399 34.622871399 -8.500000000 33.622871399 34.622871399 -8.500000000 34.167964935 34.167964935 -8.500000000 -33.981101990 34.981101990 -8.500000000 -33.233222961 35.233222961 -8.500000000 -32.384422302 35.384418488 -8.500000000 -31.458978653 35.458976746 -8.500000000 -30.488407135 35.488403320 -8.500000000 -29.497472763 35.497467041 -8.500000000 -28.499593735 35.499591827 -8.500000000 -27.499954224 35.499954224 -8.500000000 -26.499996185 35.499996185 -8.500000000 -25.500000000 35.500000000 -8.500000000 -24.500000000 35.500000000 -8.500000000 -23.500000000 35.500000000 -8.500000000 -22.500000000 35.500000000 -8.500000000 -21.500000000 35.500000000 -8.500000000 -20.500000000 35.500000000 -8.500000000 -19.500000000 35.500000000 -8.500000000 -18.500000000 35.500000000 -8.500000000 -17.500000000 35.500000000 -8.500000000 -16.500000000 35.500000000 -8.500000000 -15.500000000 35.500000000 -8.500000000 -14.500000000 35.500000000 -8.500000000 -13.500000000 35.500000000 -8.500000000 -12.500000000 35.500000000 -8.500000000 -11.500000000 35.500000000 -8.500000000 -10.500000000 35.500000000 -8.500000000 -9.500000000 35.500000000 -8.500000000 -8.500000000 35.500000000 -8.500000000 -7.500000000 35.500000000 -8.500000000 -6.500000000 35.500000000 -8.500000000 -5.500000000 35.500000000 -8.500000000 -4.500000000 35.500000000 -8.500000000 -3.500000000 35.500000000 -8.500000000 -2.500000000 35.500000000 -8.500000000 -1.500000000 35.500000000 -8.500000000 -0.500000000 35.500000000 -8.500000000 0.500000000 35.500000000 -8.500000000 1.500000000 35.500000000 -8.500000000 2.500000000 35.500000000 -8.500000000 3.500000000 35.500000000 -8.500000000 4.500000000 35.500000000 -8.500000000 5.500000000 35.500000000 -8.500000000 6.500000000 35.500000000 -8.500000000 7.500000000 35.500000000 -8.500000000 8.500000000 35.500000000 -8.500000000 9.500000000 35.500000000 -8.500000000 10.500000000 35.500000000 -8.500000000 11.500000000 35.500000000 -8.500000000 12.500000000 35.500000000 -8.500000000 13.500000000 35.500000000 -8.500000000 14.500000000 35.500000000 -8.500000000 15.500000000 35.500000000 -8.500000000 16.500000000 35.500000000 -8.500000000 17.500000000 35.500000000 -8.500000000 18.500000000 35.500000000 -8.500000000 19.500000000 35.500000000 -8.500000000 20.500000000 35.500000000 -8.500000000 21.500000000 35.500000000 -8.500000000 22.500000000 35.500000000 -8.500000000 23.500000000 35.500000000 -8.500000000 24.500000000 35.500000000 -8.500000000 25.499996185 35.499996185 -8.500000000 26.499954224 35.499954224 -8.500000000 27.499591827 35.499591827 -8.500000000 28.497470856 35.497474670 -8.500000000 29.488407135 35.488403320 -8.500000000 30.458978653 35.458980560 -8.500000000 31.384418488 35.384422302 -8.500000000 32.233222961 35.233222961 -8.500000000 32.981101990 34.981101990 -8.500000000 -33.981101990 -35.981101990 -7.500000000 -33.233226776 -36.233222961 -7.500000000 -32.384422302 -36.384418488 -7.500000000 -31.458978653 -36.458980560 -7.500000000 -30.488407135 -36.488403320 -7.500000000 -29.497472763 -36.497474670 -7.500000000 -28.499593735 -36.499591827 -7.500000000 -27.499954224 -36.499954224 -7.500000000 -26.499996185 -36.499996185 -7.500000000 -25.500000000 -36.500000000 -7.500000000 -24.500000000 -36.500000000 -7.500000000 -23.500000000 -36.500000000 -7.500000000 -22.500000000 -36.500000000 -7.500000000 -21.500000000 -36.500000000 -7.500000000 -20.500000000 -36.500000000 -7.500000000 -19.500000000 -36.500000000 -7.500000000 -18.500000000 -36.500000000 -7.500000000 -17.500000000 -36.500000000 -7.500000000 -16.500000000 -36.500000000 -7.500000000 -15.500000000 -36.500000000 -7.500000000 -14.500000000 -36.500000000 -7.500000000 -13.500000000 -36.500000000 -7.500000000 -12.500000000 -36.500000000 -7.500000000 -11.500000000 -36.500000000 -7.500000000 -10.500000000 -36.500000000 -7.500000000 -9.500000000 -36.500000000 -7.500000000 -8.500000000 -36.500000000 -7.500000000 -7.500000000 -36.500000000 -7.500000000 -6.500000000 -36.500000000 -7.500000000 -5.500000000 -36.500000000 -7.500000000 -4.500000000 -36.500000000 -7.500000000 -3.500000000 -36.500000000 -7.500000000 -2.500000000 -36.500000000 -7.500000000 -1.500000000 -36.500000000 -7.500000000 -0.500000000 -36.500000000 -7.500000000 0.500000000 -36.500000000 -7.500000000 1.500000000 -36.500000000 -7.500000000 2.500000000 -36.500000000 -7.500000000 3.500000000 -36.500000000 -7.500000000 4.500000000 -36.500000000 -7.500000000 5.500000000 -36.500000000 -7.500000000 6.500000000 -36.500000000 -7.500000000 7.500000000 -36.500000000 -7.500000000 8.500000000 -36.500000000 -7.500000000 9.500000000 -36.500000000 -7.500000000 10.500000000 -36.500000000 -7.500000000 11.500000000 -36.500000000 -7.500000000 12.500000000 -36.500000000 -7.500000000 13.500000000 -36.500000000 -7.500000000 14.500000000 -36.500000000 -7.500000000 15.500000000 -36.500000000 -7.500000000 16.500000000 -36.500000000 -7.500000000 17.500000000 -36.500000000 -7.500000000 18.500000000 -36.500000000 -7.500000000 19.500000000 -36.500000000 -7.500000000 20.500000000 -36.500000000 -7.500000000 21.500000000 -36.500000000 -7.500000000 22.500000000 -36.500000000 -7.500000000 23.500000000 -36.500000000 -7.500000000 24.500000000 -36.500000000 -7.500000000 25.499996185 -36.499996185 -7.500000000 26.499954224 -36.499954224 -7.500000000 27.499591827 -36.499591827 -7.500000000 28.497470856 -36.497467041 -7.500000000 29.488407135 -36.488403320 -7.500000000 30.458978653 -36.458980560 -7.500000000 31.384418488 -36.384422302 -7.500000000 32.233222961 -36.233222961 -7.500000000 32.981101990 -35.981101990 -7.500000000 -35.167964935 -35.167964935 -7.500000000 -34.622871399 -35.622871399 -7.500000000 33.622871399 -35.622871399 -7.500000000 34.167964935 -35.167964935 -7.500000000 -35.981101990 -33.981101990 -7.500000000 -35.622871399 -34.622871399 -7.500000000 34.622871399 -34.622871399 -7.500000000 34.981101990 -33.981101990 -7.500000000 -36.233222961 -33.233222961 -7.500000000 35.233222961 -33.233226776 -7.500000000 -36.384418488 -32.384422302 -7.500000000 35.384418488 -32.384422302 -7.500000000 -36.458976746 -31.458978653 -7.500000000 35.458980560 -31.458978653 -7.500000000 -36.488403320 -30.488407135 -7.500000000 35.488403320 -30.488407135 -7.500000000 -36.497467041 -29.497472763 -7.500000000 35.497474670 -29.497472763 -7.500000000 -36.499591827 -28.499593735 -7.500000000 35.499591827 -28.499593735 -7.500000000 -36.499954224 -27.499954224 -7.500000000 35.499954224 -27.499954224 -7.500000000 -36.499996185 -26.499996185 -7.500000000 35.499996185 -26.499996185 -7.500000000 -36.500000000 -25.500000000 -7.500000000 35.500000000 -25.500000000 -7.500000000 -36.500000000 -24.500000000 -7.500000000 35.500000000 -24.500000000 -7.500000000 -36.500000000 -23.500000000 -7.500000000 35.500000000 -23.500000000 -7.500000000 -36.500000000 -22.500000000 -7.500000000 35.500000000 -22.500000000 -7.500000000 -36.500000000 -21.500000000 -7.500000000 35.500000000 -21.500000000 -7.500000000 -36.500000000 -20.500000000 -7.500000000 35.500000000 -20.500000000 -7.500000000 -36.500000000 -19.500000000 -7.500000000 35.500000000 -19.500000000 -7.500000000 -36.500000000 -18.500000000 -7.500000000 35.500000000 -18.500000000 -7.500000000 -36.500000000 -17.500000000 -7.500000000 35.500000000 -17.500000000 -7.500000000 -36.500000000 -16.500000000 -7.500000000 35.500000000 -16.500000000 -7.500000000 -36.500000000 -15.500000000 -7.500000000 35.500000000 -15.500000000 -7.500000000 -36.500000000 -14.500000000 -7.500000000 35.500000000 -14.500000000 -7.500000000 -36.500000000 -13.500000000 -7.500000000 35.500000000 -13.500000000 -7.500000000 -36.500000000 -12.500000000 -7.500000000 35.500000000 -12.500000000 -7.500000000 -36.500000000 -11.500000000 -7.500000000 35.500000000 -11.500000000 -7.500000000 -36.500000000 -10.500000000 -7.500000000 35.500000000 -10.500000000 -7.500000000 -36.500000000 -9.500000000 -7.500000000 35.500000000 -9.500000000 -7.500000000 -36.500000000 -8.500000000 -7.500000000 35.500000000 -8.500000000 -7.500000000 -36.500000000 -7.500000000 -7.500000000 35.500000000 -7.500000000 -7.500000000 -36.500000000 -6.500000000 -7.500000000 35.500000000 -6.500000000 -7.500000000 -36.500000000 -5.500000000 -7.500000000 35.500000000 -5.500000000 -7.500000000 -36.500000000 -4.500000000 -7.500000000 35.500000000 -4.500000000 -7.500000000 -36.500000000 -3.500000000 -7.500000000 35.500000000 -3.500000000 -7.500000000 -36.500000000 -2.500000000 -7.500000000 35.500000000 -2.500000000 -7.500000000 -36.500000000 -1.500000000 -7.500000000 35.500000000 -1.500000000 -7.500000000 -36.500000000 -0.500000000 -7.500000000 35.500000000 -0.500000000 -7.500000000 -36.500000000 0.500000000 -7.500000000 35.500000000 0.500000000 -7.500000000 -36.500000000 1.500000000 -7.500000000 35.500000000 1.500000000 -7.500000000 -36.500000000 2.500000000 -7.500000000 35.500000000 2.500000000 -7.500000000 -36.500000000 3.500000000 -7.500000000 35.500000000 3.500000000 -7.500000000 -36.500000000 4.500000000 -7.500000000 35.500000000 4.500000000 -7.500000000 -36.500000000 5.500000000 -7.500000000 35.500000000 5.500000000 -7.500000000 -36.500000000 6.500000000 -7.500000000 35.500000000 6.500000000 -7.500000000 -36.500000000 7.500000000 -7.500000000 35.500000000 7.500000000 -7.500000000 -36.500000000 8.500000000 -7.500000000 35.500000000 8.500000000 -7.500000000 -36.500000000 9.500000000 -7.500000000 35.500000000 9.500000000 -7.500000000 -36.500000000 10.500000000 -7.500000000 35.500000000 10.500000000 -7.500000000 -36.500000000 11.500000000 -7.500000000 35.500000000 11.500000000 -7.500000000 -36.500000000 12.500000000 -7.500000000 35.500000000 12.500000000 -7.500000000 -36.500000000 13.500000000 -7.500000000 35.500000000 13.500000000 -7.500000000 -36.500000000 14.500000000 -7.500000000 35.500000000 14.500000000 -7.500000000 -36.500000000 15.500000000 -7.500000000 35.500000000 15.500000000 -7.500000000 -36.500000000 16.500000000 -7.500000000 35.500000000 16.500000000 -7.500000000 -36.500000000 17.500000000 -7.500000000 35.500000000 17.500000000 -7.500000000 -36.500000000 18.500000000 -7.500000000 35.500000000 18.500000000 -7.500000000 -36.500000000 19.500000000 -7.500000000 35.500000000 19.500000000 -7.500000000 -36.500000000 20.500000000 -7.500000000 35.500000000 20.500000000 -7.500000000 -36.500000000 21.500000000 -7.500000000 35.500000000 21.500000000 -7.500000000 -36.500000000 22.500000000 -7.500000000 35.500000000 22.500000000 -7.500000000 -36.500000000 23.500000000 -7.500000000 35.500000000 23.500000000 -7.500000000 -36.500000000 24.500000000 -7.500000000 35.500000000 24.500000000 -7.500000000 -36.499996185 25.499996185 -7.500000000 35.499996185 25.499996185 -7.500000000 -36.499954224 26.499954224 -7.500000000 35.499954224 26.499954224 -7.500000000 -36.499591827 27.499591827 -7.500000000 35.499591827 27.499591827 -7.500000000 -36.497474670 28.497470856 -7.500000000 35.497467041 28.497470856 -7.500000000 -36.488403320 29.488407135 -7.500000000 35.488403320 29.488407135 -7.500000000 -36.458980560 30.458978653 -7.500000000 35.458980560 30.458978653 -7.500000000 -36.384422302 31.384418488 -7.500000000 35.384422302 31.384418488 -7.500000000 -36.233222961 32.233222961 -7.500000000 35.233222961 32.233222961 -7.500000000 -35.981101990 32.981101990 -7.500000000 -35.622871399 33.622871399 -7.500000000 34.622871399 33.622871399 -7.500000000 34.981101990 32.981101990 -7.500000000 -35.167964935 34.167964935 -7.500000000 -34.622871399 34.622871399 -7.500000000 33.622871399 34.622871399 -7.500000000 34.167964935 34.167964935 -7.500000000 -33.981101990 34.981101990 -7.500000000 -33.233222961 35.233222961 -7.500000000 -32.384422302 35.384418488 -7.500000000 -31.458978653 35.458976746 -7.500000000 -30.488407135 35.488403320 -7.500000000 -29.497472763 35.497467041 -7.500000000 -28.499593735 35.499591827 -7.500000000 -27.499954224 35.499954224 -7.500000000 -26.499996185 35.499996185 -7.500000000 -25.500000000 35.500000000 -7.500000000 -24.500000000 35.500000000 -7.500000000 -23.500000000 35.500000000 -7.500000000 -22.500000000 35.500000000 -7.500000000 -21.500000000 35.500000000 -7.500000000 -20.500000000 35.500000000 -7.500000000 -19.500000000 35.500000000 -7.500000000 -18.500000000 35.500000000 -7.500000000 -17.500000000 35.500000000 -7.500000000 -16.500000000 35.500000000 -7.500000000 -15.500000000 35.500000000 -7.500000000 -14.500000000 35.500000000 -7.500000000 -13.500000000 35.500000000 -7.500000000 -12.500000000 35.500000000 -7.500000000 -11.500000000 35.500000000 -7.500000000 -10.500000000 35.500000000 -7.500000000 -9.500000000 35.500000000 -7.500000000 -8.500000000 35.500000000 -7.500000000 -7.500000000 35.500000000 -7.500000000 -6.500000000 35.500000000 -7.500000000 -5.500000000 35.500000000 -7.500000000 -4.500000000 35.500000000 -7.500000000 -3.500000000 35.500000000 -7.500000000 -2.500000000 35.500000000 -7.500000000 -1.500000000 35.500000000 -7.500000000 -0.500000000 35.500000000 -7.500000000 0.500000000 35.500000000 -7.500000000 1.500000000 35.500000000 -7.500000000 2.500000000 35.500000000 -7.500000000 3.500000000 35.500000000 -7.500000000 4.500000000 35.500000000 -7.500000000 5.500000000 35.500000000 -7.500000000 6.500000000 35.500000000 -7.500000000 7.500000000 35.500000000 -7.500000000 8.500000000 35.500000000 -7.500000000 9.500000000 35.500000000 -7.500000000 10.500000000 35.500000000 -7.500000000 11.500000000 35.500000000 -7.500000000 12.500000000 35.500000000 -7.500000000 13.500000000 35.500000000 -7.500000000 14.500000000 35.500000000 -7.500000000 15.500000000 35.500000000 -7.500000000 16.500000000 35.500000000 -7.500000000 17.500000000 35.500000000 -7.500000000 18.500000000 35.500000000 -7.500000000 19.500000000 35.500000000 -7.500000000 20.500000000 35.500000000 -7.500000000 21.500000000 35.500000000 -7.500000000 22.500000000 35.500000000 -7.500000000 23.500000000 35.500000000 -7.500000000 24.500000000 35.500000000 -7.500000000 25.499996185 35.499996185 -7.500000000 26.499954224 35.499954224 -7.500000000 27.499591827 35.499591827 -7.500000000 28.497470856 35.497474670 -7.500000000 29.488407135 35.488403320 -7.500000000 30.458978653 35.458980560 -7.500000000 31.384418488 35.384422302 -7.500000000 32.233222961 35.233222961 -7.500000000 32.981101990 34.981101990 -7.500000000 -33.981101990 -35.981101990 -6.500000000 -33.233226776 -36.233222961 -6.500000000 -32.384422302 -36.384418488 -6.500000000 -31.458978653 -36.458980560 -6.500000000 -30.488407135 -36.488403320 -6.500000000 -29.497472763 -36.497474670 -6.500000000 -28.499593735 -36.499591827 -6.500000000 -27.499954224 -36.499954224 -6.500000000 -26.499996185 -36.499996185 -6.500000000 -25.500000000 -36.500000000 -6.500000000 -24.500000000 -36.500000000 -6.500000000 -23.500000000 -36.500000000 -6.500000000 -22.500000000 -36.500000000 -6.500000000 -21.500000000 -36.500000000 -6.500000000 -20.500000000 -36.500000000 -6.500000000 -19.500000000 -36.500000000 -6.500000000 -18.500000000 -36.500000000 -6.500000000 -17.500000000 -36.500000000 -6.500000000 -16.500000000 -36.500000000 -6.500000000 -15.500000000 -36.500000000 -6.500000000 -14.500000000 -36.500000000 -6.500000000 -13.500000000 -36.500000000 -6.500000000 -12.500000000 -36.500000000 -6.500000000 -11.500000000 -36.500000000 -6.500000000 -10.500000000 -36.500000000 -6.500000000 -9.500000000 -36.500000000 -6.500000000 -8.500000000 -36.500000000 -6.500000000 -7.500000000 -36.500000000 -6.500000000 -6.500000000 -36.500000000 -6.500000000 -5.500000000 -36.500000000 -6.500000000 -4.500000000 -36.500000000 -6.500000000 -3.500000000 -36.500000000 -6.500000000 -2.500000000 -36.500000000 -6.500000000 -1.500000000 -36.500000000 -6.500000000 -0.500000000 -36.500000000 -6.500000000 0.500000000 -36.500000000 -6.500000000 1.500000000 -36.500000000 -6.500000000 2.500000000 -36.500000000 -6.500000000 3.500000000 -36.500000000 -6.500000000 4.500000000 -36.500000000 -6.500000000 5.500000000 -36.500000000 -6.500000000 6.500000000 -36.500000000 -6.500000000 7.500000000 -36.500000000 -6.500000000 8.500000000 -36.500000000 -6.500000000 9.500000000 -36.500000000 -6.500000000 10.500000000 -36.500000000 -6.500000000 11.500000000 -36.500000000 -6.500000000 12.500000000 -36.500000000 -6.500000000 13.500000000 -36.500000000 -6.500000000 14.500000000 -36.500000000 -6.500000000 15.500000000 -36.500000000 -6.500000000 16.500000000 -36.500000000 -6.500000000 17.500000000 -36.500000000 -6.500000000 18.500000000 -36.500000000 -6.500000000 19.500000000 -36.500000000 -6.500000000 20.500000000 -36.500000000 -6.500000000 21.500000000 -36.500000000 -6.500000000 22.500000000 -36.500000000 -6.500000000 23.500000000 -36.500000000 -6.500000000 24.500000000 -36.500000000 -6.500000000 25.499996185 -36.499996185 -6.500000000 26.499954224 -36.499954224 -6.500000000 27.499591827 -36.499591827 -6.500000000 28.497470856 -36.497467041 -6.500000000 29.488407135 -36.488403320 -6.500000000 30.458978653 -36.458980560 -6.500000000 31.384418488 -36.384422302 -6.500000000 32.233222961 -36.233222961 -6.500000000 32.981101990 -35.981101990 -6.500000000 -35.167964935 -35.167964935 -6.500000000 -34.622871399 -35.622871399 -6.500000000 33.622871399 -35.622871399 -6.500000000 34.167964935 -35.167964935 -6.500000000 -35.981101990 -33.981101990 -6.500000000 -35.622871399 -34.622871399 -6.500000000 34.622871399 -34.622871399 -6.500000000 34.981101990 -33.981101990 -6.500000000 -36.233222961 -33.233222961 -6.500000000 35.233222961 -33.233226776 -6.500000000 -36.384418488 -32.384422302 -6.500000000 35.384418488 -32.384422302 -6.500000000 -36.458976746 -31.458978653 -6.500000000 35.458980560 -31.458978653 -6.500000000 -36.488403320 -30.488407135 -6.500000000 35.488403320 -30.488407135 -6.500000000 -36.497467041 -29.497472763 -6.500000000 35.497474670 -29.497472763 -6.500000000 -36.499591827 -28.499593735 -6.500000000 35.499591827 -28.499593735 -6.500000000 -36.499954224 -27.499954224 -6.500000000 35.499954224 -27.499954224 -6.500000000 -36.499996185 -26.499996185 -6.500000000 35.499996185 -26.499996185 -6.500000000 -36.500000000 -25.500000000 -6.500000000 35.500000000 -25.500000000 -6.500000000 -36.500000000 -24.500000000 -6.500000000 35.500000000 -24.500000000 -6.500000000 -36.500000000 -23.500000000 -6.500000000 35.500000000 -23.500000000 -6.500000000 -36.500000000 -22.500000000 -6.500000000 35.500000000 -22.500000000 -6.500000000 -36.500000000 -21.500000000 -6.500000000 35.500000000 -21.500000000 -6.500000000 -36.500000000 -20.500000000 -6.500000000 35.500000000 -20.500000000 -6.500000000 -36.500000000 -19.500000000 -6.500000000 35.500000000 -19.500000000 -6.500000000 -36.500000000 -18.500000000 -6.500000000 35.500000000 -18.500000000 -6.500000000 -36.500000000 -17.500000000 -6.500000000 35.500000000 -17.500000000 -6.500000000 -36.500000000 -16.500000000 -6.500000000 35.500000000 -16.500000000 -6.500000000 -36.500000000 -15.500000000 -6.500000000 35.500000000 -15.500000000 -6.500000000 -36.500000000 -14.500000000 -6.500000000 35.500000000 -14.500000000 -6.500000000 -36.500000000 -13.500000000 -6.500000000 35.500000000 -13.500000000 -6.500000000 -36.500000000 -12.500000000 -6.500000000 35.500000000 -12.500000000 -6.500000000 -36.500000000 -11.500000000 -6.500000000 35.500000000 -11.500000000 -6.500000000 -36.500000000 -10.500000000 -6.500000000 35.500000000 -10.500000000 -6.500000000 -36.500000000 -9.500000000 -6.500000000 35.500000000 -9.500000000 -6.500000000 -36.500000000 -8.500000000 -6.500000000 35.500000000 -8.500000000 -6.500000000 -36.500000000 -7.500000000 -6.500000000 35.500000000 -7.500000000 -6.500000000 -36.500000000 -6.500000000 -6.500000000 35.500000000 -6.500000000 -6.500000000 -36.500000000 -5.500000000 -6.500000000 35.500000000 -5.500000000 -6.500000000 -36.500000000 -4.500000000 -6.500000000 35.500000000 -4.500000000 -6.500000000 -36.500000000 -3.500000000 -6.500000000 35.500000000 -3.500000000 -6.500000000 -36.500000000 -2.500000000 -6.500000000 35.500000000 -2.500000000 -6.500000000 -36.500000000 -1.500000000 -6.500000000 35.500000000 -1.500000000 -6.500000000 -36.500000000 -0.500000000 -6.500000000 35.500000000 -0.500000000 -6.500000000 -36.500000000 0.500000000 -6.500000000 35.500000000 0.500000000 -6.500000000 -36.500000000 1.500000000 -6.500000000 35.500000000 1.500000000 -6.500000000 -36.500000000 2.500000000 -6.500000000 35.500000000 2.500000000 -6.500000000 -36.500000000 3.500000000 -6.500000000 35.500000000 3.500000000 -6.500000000 -36.500000000 4.500000000 -6.500000000 35.500000000 4.500000000 -6.500000000 -36.500000000 5.500000000 -6.500000000 35.500000000 5.500000000 -6.500000000 -36.500000000 6.500000000 -6.500000000 35.500000000 6.500000000 -6.500000000 -36.500000000 7.500000000 -6.500000000 35.500000000 7.500000000 -6.500000000 -36.500000000 8.500000000 -6.500000000 35.500000000 8.500000000 -6.500000000 -36.500000000 9.500000000 -6.500000000 35.500000000 9.500000000 -6.500000000 -36.500000000 10.500000000 -6.500000000 35.500000000 10.500000000 -6.500000000 -36.500000000 11.500000000 -6.500000000 35.500000000 11.500000000 -6.500000000 -36.500000000 12.500000000 -6.500000000 35.500000000 12.500000000 -6.500000000 -36.500000000 13.500000000 -6.500000000 35.500000000 13.500000000 -6.500000000 -36.500000000 14.500000000 -6.500000000 35.500000000 14.500000000 -6.500000000 -36.500000000 15.500000000 -6.500000000 35.500000000 15.500000000 -6.500000000 -36.500000000 16.500000000 -6.500000000 35.500000000 16.500000000 -6.500000000 -36.500000000 17.500000000 -6.500000000 35.500000000 17.500000000 -6.500000000 -36.500000000 18.500000000 -6.500000000 35.500000000 18.500000000 -6.500000000 -36.500000000 19.500000000 -6.500000000 35.500000000 19.500000000 -6.500000000 -36.500000000 20.500000000 -6.500000000 35.500000000 20.500000000 -6.500000000 -36.500000000 21.500000000 -6.500000000 35.500000000 21.500000000 -6.500000000 -36.500000000 22.500000000 -6.500000000 35.500000000 22.500000000 -6.500000000 -36.500000000 23.500000000 -6.500000000 35.500000000 23.500000000 -6.500000000 -36.500000000 24.500000000 -6.500000000 35.500000000 24.500000000 -6.500000000 -36.499996185 25.499996185 -6.500000000 35.499996185 25.499996185 -6.500000000 -36.499954224 26.499954224 -6.500000000 35.499954224 26.499954224 -6.500000000 -36.499591827 27.499591827 -6.500000000 35.499591827 27.499591827 -6.500000000 -36.497474670 28.497470856 -6.500000000 35.497467041 28.497470856 -6.500000000 -36.488403320 29.488407135 -6.500000000 35.488403320 29.488407135 -6.500000000 -36.458980560 30.458978653 -6.500000000 35.458980560 30.458978653 -6.500000000 -36.384422302 31.384418488 -6.500000000 35.384422302 31.384418488 -6.500000000 -36.233222961 32.233222961 -6.500000000 35.233222961 32.233222961 -6.500000000 -35.981101990 32.981101990 -6.500000000 -35.622871399 33.622871399 -6.500000000 34.622871399 33.622871399 -6.500000000 34.981101990 32.981101990 -6.500000000 -35.167964935 34.167964935 -6.500000000 -34.622871399 34.622871399 -6.500000000 33.622871399 34.622871399 -6.500000000 34.167964935 34.167964935 -6.500000000 -33.981101990 34.981101990 -6.500000000 -33.233222961 35.233222961 -6.500000000 -32.384422302 35.384418488 -6.500000000 -31.458978653 35.458976746 -6.500000000 -30.488407135 35.488403320 -6.500000000 -29.497472763 35.497467041 -6.500000000 -28.499593735 35.499591827 -6.500000000 -27.499954224 35.499954224 -6.500000000 -26.499996185 35.499996185 -6.500000000 -25.500000000 35.500000000 -6.500000000 -24.500000000 35.500000000 -6.500000000 -23.500000000 35.500000000 -6.500000000 -22.500000000 35.500000000 -6.500000000 -21.500000000 35.500000000 -6.500000000 -20.500000000 35.500000000 -6.500000000 -19.500000000 35.500000000 -6.500000000 -18.500000000 35.500000000 -6.500000000 -17.500000000 35.500000000 -6.500000000 -16.500000000 35.500000000 -6.500000000 -15.500000000 35.500000000 -6.500000000 -14.500000000 35.500000000 -6.500000000 -13.500000000 35.500000000 -6.500000000 -12.500000000 35.500000000 -6.500000000 -11.500000000 35.500000000 -6.500000000 -10.500000000 35.500000000 -6.500000000 -9.500000000 35.500000000 -6.500000000 -8.500000000 35.500000000 -6.500000000 -7.500000000 35.500000000 -6.500000000 -6.500000000 35.500000000 -6.500000000 -5.500000000 35.500000000 -6.500000000 -4.500000000 35.500000000 -6.500000000 -3.500000000 35.500000000 -6.500000000 -2.500000000 35.500000000 -6.500000000 -1.500000000 35.500000000 -6.500000000 -0.500000000 35.500000000 -6.500000000 0.500000000 35.500000000 -6.500000000 1.500000000 35.500000000 -6.500000000 2.500000000 35.500000000 -6.500000000 3.500000000 35.500000000 -6.500000000 4.500000000 35.500000000 -6.500000000 5.500000000 35.500000000 -6.500000000 6.500000000 35.500000000 -6.500000000 7.500000000 35.500000000 -6.500000000 8.500000000 35.500000000 -6.500000000 9.500000000 35.500000000 -6.500000000 10.500000000 35.500000000 -6.500000000 11.500000000 35.500000000 -6.500000000 12.500000000 35.500000000 -6.500000000 13.500000000 35.500000000 -6.500000000 14.500000000 35.500000000 -6.500000000 15.500000000 35.500000000 -6.500000000 16.500000000 35.500000000 -6.500000000 17.500000000 35.500000000 -6.500000000 18.500000000 35.500000000 -6.500000000 19.500000000 35.500000000 -6.500000000 20.500000000 35.500000000 -6.500000000 21.500000000 35.500000000 -6.500000000 22.500000000 35.500000000 -6.500000000 23.500000000 35.500000000 -6.500000000 24.500000000 35.500000000 -6.500000000 25.499996185 35.499996185 -6.500000000 26.499954224 35.499954224 -6.500000000 27.499591827 35.499591827 -6.500000000 28.497470856 35.497474670 -6.500000000 29.488407135 35.488403320 -6.500000000 30.458978653 35.458980560 -6.500000000 31.384418488 35.384422302 -6.500000000 32.233222961 35.233222961 -6.500000000 32.981101990 34.981101990 -6.500000000 -33.981101990 -35.981101990 -5.500000000 -33.233226776 -36.233222961 -5.500000000 -32.384422302 -36.384418488 -5.500000000 -31.458978653 -36.458980560 -5.500000000 -30.488407135 -36.488403320 -5.500000000 -29.497472763 -36.497474670 -5.500000000 -28.499593735 -36.499591827 -5.500000000 -27.499954224 -36.499954224 -5.500000000 -26.499996185 -36.499996185 -5.500000000 -25.500000000 -36.500000000 -5.500000000 -24.500000000 -36.500000000 -5.500000000 -23.500000000 -36.500000000 -5.500000000 -22.500000000 -36.500000000 -5.500000000 -21.500000000 -36.500000000 -5.500000000 -20.500000000 -36.500000000 -5.500000000 -19.500000000 -36.500000000 -5.500000000 -18.500000000 -36.500000000 -5.500000000 -17.500000000 -36.500000000 -5.500000000 -16.500000000 -36.500000000 -5.500000000 -15.500000000 -36.500000000 -5.500000000 -14.500000000 -36.500000000 -5.500000000 -13.500000000 -36.500000000 -5.500000000 -12.500000000 -36.500000000 -5.500000000 -11.500000000 -36.500000000 -5.500000000 -10.500000000 -36.500000000 -5.500000000 -9.500000000 -36.500000000 -5.500000000 -8.500000000 -36.500000000 -5.500000000 -7.500000000 -36.500000000 -5.500000000 -6.500000000 -36.500000000 -5.500000000 -5.500000000 -36.500000000 -5.500000000 -4.500000000 -36.500000000 -5.500000000 -3.500000000 -36.500000000 -5.500000000 -2.500000000 -36.500000000 -5.500000000 -1.500000000 -36.500000000 -5.500000000 -0.500000000 -36.500000000 -5.500000000 0.500000000 -36.500000000 -5.500000000 1.500000000 -36.500000000 -5.500000000 2.500000000 -36.500000000 -5.500000000 3.500000000 -36.500000000 -5.500000000 4.500000000 -36.500000000 -5.500000000 5.500000000 -36.500000000 -5.500000000 6.500000000 -36.500000000 -5.500000000 7.500000000 -36.500000000 -5.500000000 8.500000000 -36.500000000 -5.500000000 9.500000000 -36.500000000 -5.500000000 10.500000000 -36.500000000 -5.500000000 11.500000000 -36.500000000 -5.500000000 12.500000000 -36.500000000 -5.500000000 13.500000000 -36.500000000 -5.500000000 14.500000000 -36.500000000 -5.500000000 15.500000000 -36.500000000 -5.500000000 16.500000000 -36.500000000 -5.500000000 17.500000000 -36.500000000 -5.500000000 18.500000000 -36.500000000 -5.500000000 19.500000000 -36.500000000 -5.500000000 20.500000000 -36.500000000 -5.500000000 21.500000000 -36.500000000 -5.500000000 22.500000000 -36.500000000 -5.500000000 23.500000000 -36.500000000 -5.500000000 24.500000000 -36.500000000 -5.500000000 25.499996185 -36.499996185 -5.500000000 26.499954224 -36.499954224 -5.500000000 27.499591827 -36.499591827 -5.500000000 28.497470856 -36.497467041 -5.500000000 29.488407135 -36.488403320 -5.500000000 30.458978653 -36.458980560 -5.500000000 31.384418488 -36.384422302 -5.500000000 32.233222961 -36.233222961 -5.500000000 32.981101990 -35.981101990 -5.500000000 -35.167964935 -35.167964935 -5.500000000 -34.622871399 -35.622871399 -5.500000000 33.622871399 -35.622871399 -5.500000000 34.167964935 -35.167964935 -5.500000000 -35.981101990 -33.981101990 -5.500000000 -35.622871399 -34.622871399 -5.500000000 34.622871399 -34.622871399 -5.500000000 34.981101990 -33.981101990 -5.500000000 -36.233222961 -33.233222961 -5.500000000 35.233222961 -33.233226776 -5.500000000 -36.384418488 -32.384422302 -5.500000000 35.384418488 -32.384422302 -5.500000000 -36.458976746 -31.458978653 -5.500000000 35.458980560 -31.458978653 -5.500000000 -36.488403320 -30.488407135 -5.500000000 35.488403320 -30.488407135 -5.500000000 -36.497467041 -29.497472763 -5.500000000 35.497474670 -29.497472763 -5.500000000 -36.499591827 -28.499593735 -5.500000000 35.499591827 -28.499593735 -5.500000000 -36.499954224 -27.499954224 -5.500000000 35.499954224 -27.499954224 -5.500000000 -36.499996185 -26.499996185 -5.500000000 35.499996185 -26.499996185 -5.500000000 -36.500000000 -25.500000000 -5.500000000 35.500000000 -25.500000000 -5.500000000 -36.500000000 -24.500000000 -5.500000000 35.500000000 -24.500000000 -5.500000000 -36.500000000 -23.500000000 -5.500000000 35.500000000 -23.500000000 -5.500000000 -36.500000000 -22.500000000 -5.500000000 35.500000000 -22.500000000 -5.500000000 -36.500000000 -21.500000000 -5.500000000 35.500000000 -21.500000000 -5.500000000 -36.500000000 -20.500000000 -5.500000000 35.500000000 -20.500000000 -5.500000000 -36.500000000 -19.500000000 -5.500000000 35.500000000 -19.500000000 -5.500000000 -36.500000000 -18.500000000 -5.500000000 35.500000000 -18.500000000 -5.500000000 -36.500000000 -17.500000000 -5.500000000 35.500000000 -17.500000000 -5.500000000 -36.500000000 -16.500000000 -5.500000000 35.500000000 -16.500000000 -5.500000000 -36.500000000 -15.500000000 -5.500000000 35.500000000 -15.500000000 -5.500000000 -36.500000000 -14.500000000 -5.500000000 35.500000000 -14.500000000 -5.500000000 -36.500000000 -13.500000000 -5.500000000 35.500000000 -13.500000000 -5.500000000 -36.500000000 -12.500000000 -5.500000000 35.500000000 -12.500000000 -5.500000000 -36.500000000 -11.500000000 -5.500000000 35.500000000 -11.500000000 -5.500000000 -36.500000000 -10.500000000 -5.500000000 35.500000000 -10.500000000 -5.500000000 -36.500000000 -9.500000000 -5.500000000 35.500000000 -9.500000000 -5.500000000 -36.500000000 -8.500000000 -5.500000000 35.500000000 -8.500000000 -5.500000000 -36.500000000 -7.500000000 -5.500000000 35.500000000 -7.500000000 -5.500000000 -36.500000000 -6.500000000 -5.500000000 35.500000000 -6.500000000 -5.500000000 -36.500000000 -5.500000000 -5.500000000 35.500000000 -5.500000000 -5.500000000 -36.500000000 -4.500000000 -5.500000000 35.500000000 -4.500000000 -5.500000000 -36.500000000 -3.500000000 -5.500000000 35.500000000 -3.500000000 -5.500000000 -36.500000000 -2.500000000 -5.500000000 35.500000000 -2.500000000 -5.500000000 -36.500000000 -1.500000000 -5.500000000 35.500000000 -1.500000000 -5.500000000 -36.500000000 -0.500000000 -5.500000000 35.500000000 -0.500000000 -5.500000000 -36.500000000 0.500000000 -5.500000000 35.500000000 0.500000000 -5.500000000 -36.500000000 1.500000000 -5.500000000 35.500000000 1.500000000 -5.500000000 -36.500000000 2.500000000 -5.500000000 35.500000000 2.500000000 -5.500000000 -36.500000000 3.500000000 -5.500000000 35.500000000 3.500000000 -5.500000000 -36.500000000 4.500000000 -5.500000000 35.500000000 4.500000000 -5.500000000 -36.500000000 5.500000000 -5.500000000 35.500000000 5.500000000 -5.500000000 -36.500000000 6.500000000 -5.500000000 35.500000000 6.500000000 -5.500000000 -36.500000000 7.500000000 -5.500000000 35.500000000 7.500000000 -5.500000000 -36.500000000 8.500000000 -5.500000000 35.500000000 8.500000000 -5.500000000 -36.500000000 9.500000000 -5.500000000 35.500000000 9.500000000 -5.500000000 -36.500000000 10.500000000 -5.500000000 35.500000000 10.500000000 -5.500000000 -36.500000000 11.500000000 -5.500000000 35.500000000 11.500000000 -5.500000000 -36.500000000 12.500000000 -5.500000000 35.500000000 12.500000000 -5.500000000 -36.500000000 13.500000000 -5.500000000 35.500000000 13.500000000 -5.500000000 -36.500000000 14.500000000 -5.500000000 35.500000000 14.500000000 -5.500000000 -36.500000000 15.500000000 -5.500000000 35.500000000 15.500000000 -5.500000000 -36.500000000 16.500000000 -5.500000000 35.500000000 16.500000000 -5.500000000 -36.500000000 17.500000000 -5.500000000 35.500000000 17.500000000 -5.500000000 -36.500000000 18.500000000 -5.500000000 35.500000000 18.500000000 -5.500000000 -36.500000000 19.500000000 -5.500000000 35.500000000 19.500000000 -5.500000000 -36.500000000 20.500000000 -5.500000000 35.500000000 20.500000000 -5.500000000 -36.500000000 21.500000000 -5.500000000 35.500000000 21.500000000 -5.500000000 -36.500000000 22.500000000 -5.500000000 35.500000000 22.500000000 -5.500000000 -36.500000000 23.500000000 -5.500000000 35.500000000 23.500000000 -5.500000000 -36.500000000 24.500000000 -5.500000000 35.500000000 24.500000000 -5.500000000 -36.499996185 25.499996185 -5.500000000 35.499996185 25.499996185 -5.500000000 -36.499954224 26.499954224 -5.500000000 35.499954224 26.499954224 -5.500000000 -36.499591827 27.499591827 -5.500000000 35.499591827 27.499591827 -5.500000000 -36.497474670 28.497470856 -5.500000000 35.497467041 28.497470856 -5.500000000 -36.488403320 29.488407135 -5.500000000 35.488403320 29.488407135 -5.500000000 -36.458980560 30.458978653 -5.500000000 35.458980560 30.458978653 -5.500000000 -36.384422302 31.384418488 -5.500000000 35.384422302 31.384418488 -5.500000000 -36.233222961 32.233222961 -5.500000000 35.233222961 32.233222961 -5.500000000 -35.981101990 32.981101990 -5.500000000 -35.622871399 33.622871399 -5.500000000 34.622871399 33.622871399 -5.500000000 34.981101990 32.981101990 -5.500000000 -35.167964935 34.167964935 -5.500000000 -34.622871399 34.622871399 -5.500000000 33.622871399 34.622871399 -5.500000000 34.167964935 34.167964935 -5.500000000 -33.981101990 34.981101990 -5.500000000 -33.233222961 35.233222961 -5.500000000 -32.384422302 35.384418488 -5.500000000 -31.458978653 35.458976746 -5.500000000 -30.488407135 35.488403320 -5.500000000 -29.497472763 35.497467041 -5.500000000 -28.499593735 35.499591827 -5.500000000 -27.499954224 35.499954224 -5.500000000 -26.499996185 35.499996185 -5.500000000 -25.500000000 35.500000000 -5.500000000 -24.500000000 35.500000000 -5.500000000 -23.500000000 35.500000000 -5.500000000 -22.500000000 35.500000000 -5.500000000 -21.500000000 35.500000000 -5.500000000 -20.500000000 35.500000000 -5.500000000 -19.500000000 35.500000000 -5.500000000 -18.500000000 35.500000000 -5.500000000 -17.500000000 35.500000000 -5.500000000 -16.500000000 35.500000000 -5.500000000 -15.500000000 35.500000000 -5.500000000 -14.500000000 35.500000000 -5.500000000 -13.500000000 35.500000000 -5.500000000 -12.500000000 35.500000000 -5.500000000 -11.500000000 35.500000000 -5.500000000 -10.500000000 35.500000000 -5.500000000 -9.500000000 35.500000000 -5.500000000 -8.500000000 35.500000000 -5.500000000 -7.500000000 35.500000000 -5.500000000 -6.500000000 35.500000000 -5.500000000 -5.500000000 35.500000000 -5.500000000 -4.500000000 35.500000000 -5.500000000 -3.500000000 35.500000000 -5.500000000 -2.500000000 35.500000000 -5.500000000 -1.500000000 35.500000000 -5.500000000 -0.500000000 35.500000000 -5.500000000 0.500000000 35.500000000 -5.500000000 1.500000000 35.500000000 -5.500000000 2.500000000 35.500000000 -5.500000000 3.500000000 35.500000000 -5.500000000 4.500000000 35.500000000 -5.500000000 5.500000000 35.500000000 -5.500000000 6.500000000 35.500000000 -5.500000000 7.500000000 35.500000000 -5.500000000 8.500000000 35.500000000 -5.500000000 9.500000000 35.500000000 -5.500000000 10.500000000 35.500000000 -5.500000000 11.500000000 35.500000000 -5.500000000 12.500000000 35.500000000 -5.500000000 13.500000000 35.500000000 -5.500000000 14.500000000 35.500000000 -5.500000000 15.500000000 35.500000000 -5.500000000 16.500000000 35.500000000 -5.500000000 17.500000000 35.500000000 -5.500000000 18.500000000 35.500000000 -5.500000000 19.500000000 35.500000000 -5.500000000 20.500000000 35.500000000 -5.500000000 21.500000000 35.500000000 -5.500000000 22.500000000 35.500000000 -5.500000000 23.500000000 35.500000000 -5.500000000 24.500000000 35.500000000 -5.500000000 25.499996185 35.499996185 -5.500000000 26.499954224 35.499954224 -5.500000000 27.499591827 35.499591827 -5.500000000 28.497470856 35.497474670 -5.500000000 29.488407135 35.488403320 -5.500000000 30.458978653 35.458980560 -5.500000000 31.384418488 35.384422302 -5.500000000 32.233222961 35.233222961 -5.500000000 32.981101990 34.981101990 -5.500000000 -33.981101990 -35.981101990 -4.500000000 -33.233226776 -36.233222961 -4.500000000 -32.384422302 -36.384418488 -4.500000000 -31.458978653 -36.458980560 -4.500000000 -30.488407135 -36.488403320 -4.500000000 -29.497472763 -36.497474670 -4.500000000 -28.499593735 -36.499591827 -4.500000000 -27.499954224 -36.499954224 -4.500000000 -26.499996185 -36.499996185 -4.500000000 -25.500000000 -36.500000000 -4.500000000 -24.500000000 -36.500000000 -4.500000000 -23.500000000 -36.500000000 -4.500000000 -22.500000000 -36.500000000 -4.500000000 -21.500000000 -36.500000000 -4.500000000 -20.500000000 -36.500000000 -4.500000000 -19.500000000 -36.500000000 -4.500000000 -18.500000000 -36.500000000 -4.500000000 -17.500000000 -36.500000000 -4.500000000 -16.500000000 -36.500000000 -4.500000000 -15.500000000 -36.500000000 -4.500000000 -14.500000000 -36.500000000 -4.500000000 -13.500000000 -36.500000000 -4.500000000 -12.500000000 -36.500000000 -4.500000000 -11.500000000 -36.500000000 -4.500000000 -10.500000000 -36.500000000 -4.500000000 -9.500000000 -36.500000000 -4.500000000 -8.500000000 -36.500000000 -4.500000000 -7.500000000 -36.500000000 -4.500000000 -6.500000000 -36.500000000 -4.500000000 -5.500000000 -36.500000000 -4.500000000 -4.500000000 -36.500000000 -4.500000000 -3.500000000 -36.500000000 -4.500000000 -2.500000000 -36.500000000 -4.500000000 -1.500000000 -36.500000000 -4.500000000 -0.500000000 -36.500000000 -4.500000000 0.500000000 -36.500000000 -4.500000000 1.500000000 -36.500000000 -4.500000000 2.500000000 -36.500000000 -4.500000000 3.500000000 -36.500000000 -4.500000000 4.500000000 -36.500000000 -4.500000000 5.500000000 -36.500000000 -4.500000000 6.500000000 -36.500000000 -4.500000000 7.500000000 -36.500000000 -4.500000000 8.500000000 -36.500000000 -4.500000000 9.500000000 -36.500000000 -4.500000000 10.500000000 -36.500000000 -4.500000000 11.500000000 -36.500000000 -4.500000000 12.500000000 -36.500000000 -4.500000000 13.500000000 -36.500000000 -4.500000000 14.500000000 -36.500000000 -4.500000000 15.500000000 -36.500000000 -4.500000000 16.500000000 -36.500000000 -4.500000000 17.500000000 -36.500000000 -4.500000000 18.500000000 -36.500000000 -4.500000000 19.500000000 -36.500000000 -4.500000000 20.500000000 -36.500000000 -4.500000000 21.500000000 -36.500000000 -4.500000000 22.500000000 -36.500000000 -4.500000000 23.500000000 -36.500000000 -4.500000000 24.500000000 -36.500000000 -4.500000000 25.499996185 -36.499996185 -4.500000000 26.499954224 -36.499954224 -4.500000000 27.499591827 -36.499591827 -4.500000000 28.497470856 -36.497467041 -4.500000000 29.488407135 -36.488403320 -4.500000000 30.458978653 -36.458980560 -4.500000000 31.384418488 -36.384422302 -4.500000000 32.233222961 -36.233222961 -4.500000000 32.981101990 -35.981101990 -4.500000000 -35.167964935 -35.167964935 -4.500000000 -34.622871399 -35.622871399 -4.500000000 33.622871399 -35.622871399 -4.500000000 34.167964935 -35.167964935 -4.500000000 -35.981101990 -33.981101990 -4.500000000 -35.622871399 -34.622871399 -4.500000000 34.622871399 -34.622871399 -4.500000000 34.981101990 -33.981101990 -4.500000000 -36.233222961 -33.233222961 -4.500000000 35.233222961 -33.233226776 -4.500000000 -36.384418488 -32.384422302 -4.500000000 35.384418488 -32.384422302 -4.500000000 -36.458976746 -31.458978653 -4.500000000 35.458980560 -31.458978653 -4.500000000 -36.488403320 -30.488407135 -4.500000000 35.488403320 -30.488407135 -4.500000000 -36.497467041 -29.497472763 -4.500000000 35.497474670 -29.497472763 -4.500000000 -36.499591827 -28.499593735 -4.500000000 35.499591827 -28.499593735 -4.500000000 -36.499954224 -27.499954224 -4.500000000 35.499954224 -27.499954224 -4.500000000 -36.499996185 -26.499996185 -4.500000000 35.499996185 -26.499996185 -4.500000000 -36.500000000 -25.500000000 -4.500000000 35.500000000 -25.500000000 -4.500000000 -36.500000000 -24.500000000 -4.500000000 35.500000000 -24.500000000 -4.500000000 -36.500000000 -23.500000000 -4.500000000 35.500000000 -23.500000000 -4.500000000 -36.500000000 -22.500000000 -4.500000000 35.500000000 -22.500000000 -4.500000000 -36.500000000 -21.500000000 -4.500000000 35.500000000 -21.500000000 -4.500000000 -36.500000000 -20.500000000 -4.500000000 35.500000000 -20.500000000 -4.500000000 -36.500000000 -19.500000000 -4.500000000 35.500000000 -19.500000000 -4.500000000 -36.500000000 -18.500000000 -4.500000000 35.500000000 -18.500000000 -4.500000000 -36.500000000 -17.500000000 -4.500000000 35.500000000 -17.500000000 -4.500000000 -36.500000000 -16.500000000 -4.500000000 35.500000000 -16.500000000 -4.500000000 -36.500000000 -15.500000000 -4.500000000 35.500000000 -15.500000000 -4.500000000 -36.500000000 -14.500000000 -4.500000000 35.500000000 -14.500000000 -4.500000000 -36.500000000 -13.500000000 -4.500000000 35.500000000 -13.500000000 -4.500000000 -36.500000000 -12.500000000 -4.500000000 35.500000000 -12.500000000 -4.500000000 -36.500000000 -11.500000000 -4.500000000 35.500000000 -11.500000000 -4.500000000 -36.500000000 -10.500000000 -4.500000000 35.500000000 -10.500000000 -4.500000000 -36.500000000 -9.500000000 -4.500000000 35.500000000 -9.500000000 -4.500000000 -36.500000000 -8.500000000 -4.500000000 35.500000000 -8.500000000 -4.500000000 -36.500000000 -7.500000000 -4.500000000 35.500000000 -7.500000000 -4.500000000 -36.500000000 -6.500000000 -4.500000000 35.500000000 -6.500000000 -4.500000000 -36.500000000 -5.500000000 -4.500000000 35.500000000 -5.500000000 -4.500000000 -36.500000000 -4.500000000 -4.500000000 35.500000000 -4.500000000 -4.500000000 -36.500000000 -3.500000000 -4.500000000 35.500000000 -3.500000000 -4.500000000 -36.500000000 -2.500000000 -4.500000000 35.500000000 -2.500000000 -4.500000000 -36.500000000 -1.500000000 -4.500000000 35.500000000 -1.500000000 -4.500000000 -36.500000000 -0.500000000 -4.500000000 35.500000000 -0.500000000 -4.500000000 -36.500000000 0.500000000 -4.500000000 35.500000000 0.500000000 -4.500000000 -36.500000000 1.500000000 -4.500000000 35.500000000 1.500000000 -4.500000000 -36.500000000 2.500000000 -4.500000000 35.500000000 2.500000000 -4.500000000 -36.500000000 3.500000000 -4.500000000 35.500000000 3.500000000 -4.500000000 -36.500000000 4.500000000 -4.500000000 35.500000000 4.500000000 -4.500000000 -36.500000000 5.500000000 -4.500000000 35.500000000 5.500000000 -4.500000000 -36.500000000 6.500000000 -4.500000000 35.500000000 6.500000000 -4.500000000 -36.500000000 7.500000000 -4.500000000 35.500000000 7.500000000 -4.500000000 -36.500000000 8.500000000 -4.500000000 35.500000000 8.500000000 -4.500000000 -36.500000000 9.500000000 -4.500000000 35.500000000 9.500000000 -4.500000000 -36.500000000 10.500000000 -4.500000000 35.500000000 10.500000000 -4.500000000 -36.500000000 11.500000000 -4.500000000 35.500000000 11.500000000 -4.500000000 -36.500000000 12.500000000 -4.500000000 35.500000000 12.500000000 -4.500000000 -36.500000000 13.500000000 -4.500000000 35.500000000 13.500000000 -4.500000000 -36.500000000 14.500000000 -4.500000000 35.500000000 14.500000000 -4.500000000 -36.500000000 15.500000000 -4.500000000 35.500000000 15.500000000 -4.500000000 -36.500000000 16.500000000 -4.500000000 35.500000000 16.500000000 -4.500000000 -36.500000000 17.500000000 -4.500000000 35.500000000 17.500000000 -4.500000000 -36.500000000 18.500000000 -4.500000000 35.500000000 18.500000000 -4.500000000 -36.500000000 19.500000000 -4.500000000 35.500000000 19.500000000 -4.500000000 -36.500000000 20.500000000 -4.500000000 35.500000000 20.500000000 -4.500000000 -36.500000000 21.500000000 -4.500000000 35.500000000 21.500000000 -4.500000000 -36.500000000 22.500000000 -4.500000000 35.500000000 22.500000000 -4.500000000 -36.500000000 23.500000000 -4.500000000 35.500000000 23.500000000 -4.500000000 -36.500000000 24.500000000 -4.500000000 35.500000000 24.500000000 -4.500000000 -36.499996185 25.499996185 -4.500000000 35.499996185 25.499996185 -4.500000000 -36.499954224 26.499954224 -4.500000000 35.499954224 26.499954224 -4.500000000 -36.499591827 27.499591827 -4.500000000 35.499591827 27.499591827 -4.500000000 -36.497474670 28.497470856 -4.500000000 35.497467041 28.497470856 -4.500000000 -36.488403320 29.488407135 -4.500000000 35.488403320 29.488407135 -4.500000000 -36.458980560 30.458978653 -4.500000000 35.458980560 30.458978653 -4.500000000 -36.384422302 31.384418488 -4.500000000 35.384422302 31.384418488 -4.500000000 -36.233222961 32.233222961 -4.500000000 35.233222961 32.233222961 -4.500000000 -35.981101990 32.981101990 -4.500000000 -35.622871399 33.622871399 -4.500000000 34.622871399 33.622871399 -4.500000000 34.981101990 32.981101990 -4.500000000 -35.167964935 34.167964935 -4.500000000 -34.622871399 34.622871399 -4.500000000 33.622871399 34.622871399 -4.500000000 34.167964935 34.167964935 -4.500000000 -33.981101990 34.981101990 -4.500000000 -33.233222961 35.233222961 -4.500000000 -32.384422302 35.384418488 -4.500000000 -31.458978653 35.458976746 -4.500000000 -30.488407135 35.488403320 -4.500000000 -29.497472763 35.497467041 -4.500000000 -28.499593735 35.499591827 -4.500000000 -27.499954224 35.499954224 -4.500000000 -26.499996185 35.499996185 -4.500000000 -25.500000000 35.500000000 -4.500000000 -24.500000000 35.500000000 -4.500000000 -23.500000000 35.500000000 -4.500000000 -22.500000000 35.500000000 -4.500000000 -21.500000000 35.500000000 -4.500000000 -20.500000000 35.500000000 -4.500000000 -19.500000000 35.500000000 -4.500000000 -18.500000000 35.500000000 -4.500000000 -17.500000000 35.500000000 -4.500000000 -16.500000000 35.500000000 -4.500000000 -15.500000000 35.500000000 -4.500000000 -14.500000000 35.500000000 -4.500000000 -13.500000000 35.500000000 -4.500000000 -12.500000000 35.500000000 -4.500000000 -11.500000000 35.500000000 -4.500000000 -10.500000000 35.500000000 -4.500000000 -9.500000000 35.500000000 -4.500000000 -8.500000000 35.500000000 -4.500000000 -7.500000000 35.500000000 -4.500000000 -6.500000000 35.500000000 -4.500000000 -5.500000000 35.500000000 -4.500000000 -4.500000000 35.500000000 -4.500000000 -3.500000000 35.500000000 -4.500000000 -2.500000000 35.500000000 -4.500000000 -1.500000000 35.500000000 -4.500000000 -0.500000000 35.500000000 -4.500000000 0.500000000 35.500000000 -4.500000000 1.500000000 35.500000000 -4.500000000 2.500000000 35.500000000 -4.500000000 3.500000000 35.500000000 -4.500000000 4.500000000 35.500000000 -4.500000000 5.500000000 35.500000000 -4.500000000 6.500000000 35.500000000 -4.500000000 7.500000000 35.500000000 -4.500000000 8.500000000 35.500000000 -4.500000000 9.500000000 35.500000000 -4.500000000 10.500000000 35.500000000 -4.500000000 11.500000000 35.500000000 -4.500000000 12.500000000 35.500000000 -4.500000000 13.500000000 35.500000000 -4.500000000 14.500000000 35.500000000 -4.500000000 15.500000000 35.500000000 -4.500000000 16.500000000 35.500000000 -4.500000000 17.500000000 35.500000000 -4.500000000 18.500000000 35.500000000 -4.500000000 19.500000000 35.500000000 -4.500000000 20.500000000 35.500000000 -4.500000000 21.500000000 35.500000000 -4.500000000 22.500000000 35.500000000 -4.500000000 23.500000000 35.500000000 -4.500000000 24.500000000 35.500000000 -4.500000000 25.499996185 35.499996185 -4.500000000 26.499954224 35.499954224 -4.500000000 27.499591827 35.499591827 -4.500000000 28.497470856 35.497474670 -4.500000000 29.488407135 35.488403320 -4.500000000 30.458978653 35.458980560 -4.500000000 31.384418488 35.384422302 -4.500000000 32.233222961 35.233222961 -4.500000000 32.981101990 34.981101990 -4.500000000 -33.981101990 -35.981101990 -3.500000000 -33.233226776 -36.233222961 -3.500000000 -32.384422302 -36.384418488 -3.500000000 -31.458978653 -36.458980560 -3.500000000 -30.488407135 -36.488403320 -3.500000000 -29.497472763 -36.497474670 -3.500000000 -28.499593735 -36.499591827 -3.500000000 -27.499954224 -36.499954224 -3.500000000 -26.499996185 -36.499996185 -3.500000000 -25.500000000 -36.500000000 -3.500000000 -24.500000000 -36.500000000 -3.500000000 -23.500000000 -36.500000000 -3.500000000 -22.500000000 -36.500000000 -3.500000000 -21.500000000 -36.500000000 -3.500000000 -20.500000000 -36.500000000 -3.500000000 -19.500000000 -36.500000000 -3.500000000 -18.500000000 -36.500000000 -3.500000000 -17.500000000 -36.500000000 -3.500000000 -16.500000000 -36.500000000 -3.500000000 -15.500000000 -36.500000000 -3.500000000 -14.500000000 -36.500000000 -3.500000000 -13.500000000 -36.500000000 -3.500000000 -12.500000000 -36.500000000 -3.500000000 -11.500000000 -36.500000000 -3.500000000 -10.500000000 -36.500000000 -3.500000000 -9.500000000 -36.500000000 -3.500000000 -8.500000000 -36.500000000 -3.500000000 -7.500000000 -36.500000000 -3.500000000 -6.500000000 -36.500000000 -3.500000000 -5.500000000 -36.500000000 -3.500000000 -4.500000000 -36.500000000 -3.500000000 -3.500000000 -36.500000000 -3.500000000 -2.500000000 -36.500000000 -3.500000000 -1.500000000 -36.500000000 -3.500000000 -0.500000000 -36.500000000 -3.500000000 0.500000000 -36.500000000 -3.500000000 1.500000000 -36.500000000 -3.500000000 2.500000000 -36.500000000 -3.500000000 3.500000000 -36.500000000 -3.500000000 4.500000000 -36.500000000 -3.500000000 5.500000000 -36.500000000 -3.500000000 6.500000000 -36.500000000 -3.500000000 7.500000000 -36.500000000 -3.500000000 8.500000000 -36.500000000 -3.500000000 9.500000000 -36.500000000 -3.500000000 10.500000000 -36.500000000 -3.500000000 11.500000000 -36.500000000 -3.500000000 12.500000000 -36.500000000 -3.500000000 13.500000000 -36.500000000 -3.500000000 14.500000000 -36.500000000 -3.500000000 15.500000000 -36.500000000 -3.500000000 16.500000000 -36.500000000 -3.500000000 17.500000000 -36.500000000 -3.500000000 18.500000000 -36.500000000 -3.500000000 19.500000000 -36.500000000 -3.500000000 20.500000000 -36.500000000 -3.500000000 21.500000000 -36.500000000 -3.500000000 22.500000000 -36.500000000 -3.500000000 23.500000000 -36.500000000 -3.500000000 24.500000000 -36.500000000 -3.500000000 25.499996185 -36.499996185 -3.500000000 26.499954224 -36.499954224 -3.500000000 27.499591827 -36.499591827 -3.500000000 28.497470856 -36.497467041 -3.500000000 29.488407135 -36.488403320 -3.500000000 30.458978653 -36.458980560 -3.500000000 31.384418488 -36.384422302 -3.500000000 32.233222961 -36.233222961 -3.500000000 32.981101990 -35.981101990 -3.500000000 -35.167964935 -35.167964935 -3.500000000 -34.622871399 -35.622871399 -3.500000000 33.622871399 -35.622871399 -3.500000000 34.167964935 -35.167964935 -3.500000000 -35.981101990 -33.981101990 -3.500000000 -35.622871399 -34.622871399 -3.500000000 34.622871399 -34.622871399 -3.500000000 34.981101990 -33.981101990 -3.500000000 -36.233222961 -33.233222961 -3.500000000 35.233222961 -33.233226776 -3.500000000 -36.384418488 -32.384422302 -3.500000000 35.384418488 -32.384422302 -3.500000000 -36.458976746 -31.458978653 -3.500000000 35.458980560 -31.458978653 -3.500000000 -36.488403320 -30.488407135 -3.500000000 35.488403320 -30.488407135 -3.500000000 -36.497467041 -29.497472763 -3.500000000 35.497474670 -29.497472763 -3.500000000 -36.499591827 -28.499593735 -3.500000000 35.499591827 -28.499593735 -3.500000000 -36.499954224 -27.499954224 -3.500000000 35.499954224 -27.499954224 -3.500000000 -36.499996185 -26.499996185 -3.500000000 35.499996185 -26.499996185 -3.500000000 -36.500000000 -25.500000000 -3.500000000 35.500000000 -25.500000000 -3.500000000 -36.500000000 -24.500000000 -3.500000000 35.500000000 -24.500000000 -3.500000000 -36.500000000 -23.500000000 -3.500000000 35.500000000 -23.500000000 -3.500000000 -36.500000000 -22.500000000 -3.500000000 35.500000000 -22.500000000 -3.500000000 -36.500000000 -21.500000000 -3.500000000 35.500000000 -21.500000000 -3.500000000 -36.500000000 -20.500000000 -3.500000000 35.500000000 -20.500000000 -3.500000000 -36.500000000 -19.500000000 -3.500000000 35.500000000 -19.500000000 -3.500000000 -36.500000000 -18.500000000 -3.500000000 35.500000000 -18.500000000 -3.500000000 -36.500000000 -17.500000000 -3.500000000 35.500000000 -17.500000000 -3.500000000 -36.500000000 -16.500000000 -3.500000000 35.500000000 -16.500000000 -3.500000000 -36.500000000 -15.500000000 -3.500000000 35.500000000 -15.500000000 -3.500000000 -36.500000000 -14.500000000 -3.500000000 35.500000000 -14.500000000 -3.500000000 -36.500000000 -13.500000000 -3.500000000 35.500000000 -13.500000000 -3.500000000 -36.500000000 -12.500000000 -3.500000000 35.500000000 -12.500000000 -3.500000000 -36.500000000 -11.500000000 -3.500000000 35.500000000 -11.500000000 -3.500000000 -36.500000000 -10.500000000 -3.500000000 35.500000000 -10.500000000 -3.500000000 -36.500000000 -9.500000000 -3.500000000 35.500000000 -9.500000000 -3.500000000 -36.500000000 -8.500000000 -3.500000000 35.500000000 -8.500000000 -3.500000000 -36.500000000 -7.500000000 -3.500000000 35.500000000 -7.500000000 -3.500000000 -36.500000000 -6.500000000 -3.500000000 35.500000000 -6.500000000 -3.500000000 -36.500000000 -5.500000000 -3.500000000 35.500000000 -5.500000000 -3.500000000 -36.500000000 -4.500000000 -3.500000000 35.500000000 -4.500000000 -3.500000000 -36.500000000 -3.500000000 -3.500000000 35.500000000 -3.500000000 -3.500000000 -36.500000000 -2.500000000 -3.500000000 35.500000000 -2.500000000 -3.500000000 -36.500000000 -1.500000000 -3.500000000 35.500000000 -1.500000000 -3.500000000 -36.500000000 -0.500000000 -3.500000000 35.500000000 -0.500000000 -3.500000000 -36.500000000 0.500000000 -3.500000000 35.500000000 0.500000000 -3.500000000 -36.500000000 1.500000000 -3.500000000 35.500000000 1.500000000 -3.500000000 -36.500000000 2.500000000 -3.500000000 35.500000000 2.500000000 -3.500000000 -36.500000000 3.500000000 -3.500000000 35.500000000 3.500000000 -3.500000000 -36.500000000 4.500000000 -3.500000000 35.500000000 4.500000000 -3.500000000 -36.500000000 5.500000000 -3.500000000 35.500000000 5.500000000 -3.500000000 -36.500000000 6.500000000 -3.500000000 35.500000000 6.500000000 -3.500000000 -36.500000000 7.500000000 -3.500000000 35.500000000 7.500000000 -3.500000000 -36.500000000 8.500000000 -3.500000000 35.500000000 8.500000000 -3.500000000 -36.500000000 9.500000000 -3.500000000 35.500000000 9.500000000 -3.500000000 -36.500000000 10.500000000 -3.500000000 35.500000000 10.500000000 -3.500000000 -36.500000000 11.500000000 -3.500000000 35.500000000 11.500000000 -3.500000000 -36.500000000 12.500000000 -3.500000000 35.500000000 12.500000000 -3.500000000 -36.500000000 13.500000000 -3.500000000 35.500000000 13.500000000 -3.500000000 -36.500000000 14.500000000 -3.500000000 35.500000000 14.500000000 -3.500000000 -36.500000000 15.500000000 -3.500000000 35.500000000 15.500000000 -3.500000000 -36.500000000 16.500000000 -3.500000000 35.500000000 16.500000000 -3.500000000 -36.500000000 17.500000000 -3.500000000 35.500000000 17.500000000 -3.500000000 -36.500000000 18.500000000 -3.500000000 35.500000000 18.500000000 -3.500000000 -36.500000000 19.500000000 -3.500000000 35.500000000 19.500000000 -3.500000000 -36.500000000 20.500000000 -3.500000000 35.500000000 20.500000000 -3.500000000 -36.500000000 21.500000000 -3.500000000 35.500000000 21.500000000 -3.500000000 -36.500000000 22.500000000 -3.500000000 35.500000000 22.500000000 -3.500000000 -36.500000000 23.500000000 -3.500000000 35.500000000 23.500000000 -3.500000000 -36.500000000 24.500000000 -3.500000000 35.500000000 24.500000000 -3.500000000 -36.499996185 25.499996185 -3.500000000 35.499996185 25.499996185 -3.500000000 -36.499954224 26.499954224 -3.500000000 35.499954224 26.499954224 -3.500000000 -36.499591827 27.499591827 -3.500000000 35.499591827 27.499591827 -3.500000000 -36.497474670 28.497470856 -3.500000000 35.497467041 28.497470856 -3.500000000 -36.488403320 29.488407135 -3.500000000 35.488403320 29.488407135 -3.500000000 -36.458980560 30.458978653 -3.500000000 35.458980560 30.458978653 -3.500000000 -36.384422302 31.384418488 -3.500000000 35.384422302 31.384418488 -3.500000000 -36.233222961 32.233222961 -3.500000000 35.233222961 32.233222961 -3.500000000 -35.981101990 32.981101990 -3.500000000 -35.622871399 33.622871399 -3.500000000 34.622871399 33.622871399 -3.500000000 34.981101990 32.981101990 -3.500000000 -35.167964935 34.167964935 -3.500000000 -34.622871399 34.622871399 -3.500000000 33.622871399 34.622871399 -3.500000000 34.167964935 34.167964935 -3.500000000 -33.981101990 34.981101990 -3.500000000 -33.233222961 35.233222961 -3.500000000 -32.384422302 35.384418488 -3.500000000 -31.458978653 35.458976746 -3.500000000 -30.488407135 35.488403320 -3.500000000 -29.497472763 35.497467041 -3.500000000 -28.499593735 35.499591827 -3.500000000 -27.499954224 35.499954224 -3.500000000 -26.499996185 35.499996185 -3.500000000 -25.500000000 35.500000000 -3.500000000 -24.500000000 35.500000000 -3.500000000 -23.500000000 35.500000000 -3.500000000 -22.500000000 35.500000000 -3.500000000 -21.500000000 35.500000000 -3.500000000 -20.500000000 35.500000000 -3.500000000 -19.500000000 35.500000000 -3.500000000 -18.500000000 35.500000000 -3.500000000 -17.500000000 35.500000000 -3.500000000 -16.500000000 35.500000000 -3.500000000 -15.500000000 35.500000000 -3.500000000 -14.500000000 35.500000000 -3.500000000 -13.500000000 35.500000000 -3.500000000 -12.500000000 35.500000000 -3.500000000 -11.500000000 35.500000000 -3.500000000 -10.500000000 35.500000000 -3.500000000 -9.500000000 35.500000000 -3.500000000 -8.500000000 35.500000000 -3.500000000 -7.500000000 35.500000000 -3.500000000 -6.500000000 35.500000000 -3.500000000 -5.500000000 35.500000000 -3.500000000 -4.500000000 35.500000000 -3.500000000 -3.500000000 35.500000000 -3.500000000 -2.500000000 35.500000000 -3.500000000 -1.500000000 35.500000000 -3.500000000 -0.500000000 35.500000000 -3.500000000 0.500000000 35.500000000 -3.500000000 1.500000000 35.500000000 -3.500000000 2.500000000 35.500000000 -3.500000000 3.500000000 35.500000000 -3.500000000 4.500000000 35.500000000 -3.500000000 5.500000000 35.500000000 -3.500000000 6.500000000 35.500000000 -3.500000000 7.500000000 35.500000000 -3.500000000 8.500000000 35.500000000 -3.500000000 9.500000000 35.500000000 -3.500000000 10.500000000 35.500000000 -3.500000000 11.500000000 35.500000000 -3.500000000 12.500000000 35.500000000 -3.500000000 13.500000000 35.500000000 -3.500000000 14.500000000 35.500000000 -3.500000000 15.500000000 35.500000000 -3.500000000 16.500000000 35.500000000 -3.500000000 17.500000000 35.500000000 -3.500000000 18.500000000 35.500000000 -3.500000000 19.500000000 35.500000000 -3.500000000 20.500000000 35.500000000 -3.500000000 21.500000000 35.500000000 -3.500000000 22.500000000 35.500000000 -3.500000000 23.500000000 35.500000000 -3.500000000 24.500000000 35.500000000 -3.500000000 25.499996185 35.499996185 -3.500000000 26.499954224 35.499954224 -3.500000000 27.499591827 35.499591827 -3.500000000 28.497470856 35.497474670 -3.500000000 29.488407135 35.488403320 -3.500000000 30.458978653 35.458980560 -3.500000000 31.384418488 35.384422302 -3.500000000 32.233222961 35.233222961 -3.500000000 32.981101990 34.981101990 -3.500000000 -33.981101990 -35.981101990 -2.500000000 -33.233226776 -36.233222961 -2.500000000 -32.384422302 -36.384418488 -2.500000000 -31.458978653 -36.458980560 -2.500000000 -30.488407135 -36.488403320 -2.500000000 -29.497472763 -36.497474670 -2.500000000 -28.499593735 -36.499591827 -2.500000000 -27.499954224 -36.499954224 -2.500000000 -26.499996185 -36.499996185 -2.500000000 -25.500000000 -36.500000000 -2.500000000 -24.500000000 -36.500000000 -2.500000000 -23.500000000 -36.500000000 -2.500000000 -22.500000000 -36.500000000 -2.500000000 -21.500000000 -36.500000000 -2.500000000 -20.500000000 -36.500000000 -2.500000000 -19.500000000 -36.500000000 -2.500000000 -18.500000000 -36.500000000 -2.500000000 -17.500000000 -36.500000000 -2.500000000 -16.500000000 -36.500000000 -2.500000000 -15.500000000 -36.500000000 -2.500000000 -14.500000000 -36.500000000 -2.500000000 -13.500000000 -36.500000000 -2.500000000 -12.500000000 -36.500000000 -2.500000000 -11.500000000 -36.500000000 -2.500000000 -10.500000000 -36.500000000 -2.500000000 -9.500000000 -36.500000000 -2.500000000 -8.500000000 -36.500000000 -2.500000000 -7.500000000 -36.500000000 -2.500000000 -6.500000000 -36.500000000 -2.500000000 -5.500000000 -36.500000000 -2.500000000 -4.500000000 -36.500000000 -2.500000000 -3.500000000 -36.500000000 -2.500000000 -2.500000000 -36.500000000 -2.500000000 -1.500000000 -36.500000000 -2.500000000 -0.500000000 -36.500000000 -2.500000000 0.500000000 -36.500000000 -2.500000000 1.500000000 -36.500000000 -2.500000000 2.500000000 -36.500000000 -2.500000000 3.500000000 -36.500000000 -2.500000000 4.500000000 -36.500000000 -2.500000000 5.500000000 -36.500000000 -2.500000000 6.500000000 -36.500000000 -2.500000000 7.500000000 -36.500000000 -2.500000000 8.500000000 -36.500000000 -2.500000000 9.500000000 -36.500000000 -2.500000000 10.500000000 -36.500000000 -2.500000000 11.500000000 -36.500000000 -2.500000000 12.500000000 -36.500000000 -2.500000000 13.500000000 -36.500000000 -2.500000000 14.500000000 -36.500000000 -2.500000000 15.500000000 -36.500000000 -2.500000000 16.500000000 -36.500000000 -2.500000000 17.500000000 -36.500000000 -2.500000000 18.500000000 -36.500000000 -2.500000000 19.500000000 -36.500000000 -2.500000000 20.500000000 -36.500000000 -2.500000000 21.500000000 -36.500000000 -2.500000000 22.500000000 -36.500000000 -2.500000000 23.500000000 -36.500000000 -2.500000000 24.500000000 -36.500000000 -2.500000000 25.499996185 -36.499996185 -2.500000000 26.499954224 -36.499954224 -2.500000000 27.499591827 -36.499591827 -2.500000000 28.497470856 -36.497467041 -2.500000000 29.488407135 -36.488403320 -2.500000000 30.458978653 -36.458980560 -2.500000000 31.384418488 -36.384422302 -2.500000000 32.233222961 -36.233222961 -2.500000000 32.981101990 -35.981101990 -2.500000000 -35.167964935 -35.167964935 -2.500000000 -34.622871399 -35.622871399 -2.500000000 33.622871399 -35.622871399 -2.500000000 34.167964935 -35.167964935 -2.500000000 -35.981101990 -33.981101990 -2.500000000 -35.622871399 -34.622871399 -2.500000000 34.622871399 -34.622871399 -2.500000000 34.981101990 -33.981101990 -2.500000000 -36.233222961 -33.233222961 -2.500000000 35.233222961 -33.233226776 -2.500000000 -36.384418488 -32.384422302 -2.500000000 35.384418488 -32.384422302 -2.500000000 -36.458976746 -31.458978653 -2.500000000 35.458980560 -31.458978653 -2.500000000 -36.488403320 -30.488407135 -2.500000000 35.488403320 -30.488407135 -2.500000000 -36.497467041 -29.497472763 -2.500000000 35.497474670 -29.497472763 -2.500000000 -36.499591827 -28.499593735 -2.500000000 35.499591827 -28.499593735 -2.500000000 -36.499954224 -27.499954224 -2.500000000 35.499954224 -27.499954224 -2.500000000 -36.499996185 -26.499996185 -2.500000000 35.499996185 -26.499996185 -2.500000000 -36.500000000 -25.500000000 -2.500000000 35.500000000 -25.500000000 -2.500000000 -36.500000000 -24.500000000 -2.500000000 35.500000000 -24.500000000 -2.500000000 -36.500000000 -23.500000000 -2.500000000 35.500000000 -23.500000000 -2.500000000 -36.500000000 -22.500000000 -2.500000000 35.500000000 -22.500000000 -2.500000000 -36.500000000 -21.500000000 -2.500000000 35.500000000 -21.500000000 -2.500000000 -36.500000000 -20.500000000 -2.500000000 35.500000000 -20.500000000 -2.500000000 -36.500000000 -19.500000000 -2.500000000 35.500000000 -19.500000000 -2.500000000 -36.500000000 -18.500000000 -2.500000000 35.500000000 -18.500000000 -2.500000000 -36.500000000 -17.500000000 -2.500000000 35.500000000 -17.500000000 -2.500000000 -36.500000000 -16.500000000 -2.500000000 35.500000000 -16.500000000 -2.500000000 -36.500000000 -15.500000000 -2.500000000 35.500000000 -15.500000000 -2.500000000 -36.500000000 -14.500000000 -2.500000000 35.500000000 -14.500000000 -2.500000000 -36.500000000 -13.500000000 -2.500000000 35.500000000 -13.500000000 -2.500000000 -36.500000000 -12.500000000 -2.500000000 35.500000000 -12.500000000 -2.500000000 -36.500000000 -11.500000000 -2.500000000 35.500000000 -11.500000000 -2.500000000 -36.500000000 -10.500000000 -2.500000000 35.500000000 -10.500000000 -2.500000000 -36.500000000 -9.500000000 -2.500000000 35.500000000 -9.500000000 -2.500000000 -36.500000000 -8.500000000 -2.500000000 35.500000000 -8.500000000 -2.500000000 -36.500000000 -7.500000000 -2.500000000 35.500000000 -7.500000000 -2.500000000 -36.500000000 -6.500000000 -2.500000000 35.500000000 -6.500000000 -2.500000000 -36.500000000 -5.500000000 -2.500000000 35.500000000 -5.500000000 -2.500000000 -36.500000000 -4.500000000 -2.500000000 35.500000000 -4.500000000 -2.500000000 -36.500000000 -3.500000000 -2.500000000 35.500000000 -3.500000000 -2.500000000 -36.500000000 -2.500000000 -2.500000000 35.500000000 -2.500000000 -2.500000000 -36.500000000 -1.500000000 -2.500000000 35.500000000 -1.500000000 -2.500000000 -36.500000000 -0.500000000 -2.500000000 35.500000000 -0.500000000 -2.500000000 -36.500000000 0.500000000 -2.500000000 35.500000000 0.500000000 -2.500000000 -36.500000000 1.500000000 -2.500000000 35.500000000 1.500000000 -2.500000000 -36.500000000 2.500000000 -2.500000000 35.500000000 2.500000000 -2.500000000 -36.500000000 3.500000000 -2.500000000 35.500000000 3.500000000 -2.500000000 -36.500000000 4.500000000 -2.500000000 35.500000000 4.500000000 -2.500000000 -36.500000000 5.500000000 -2.500000000 35.500000000 5.500000000 -2.500000000 -36.500000000 6.500000000 -2.500000000 35.500000000 6.500000000 -2.500000000 -36.500000000 7.500000000 -2.500000000 35.500000000 7.500000000 -2.500000000 -36.500000000 8.500000000 -2.500000000 35.500000000 8.500000000 -2.500000000 -36.500000000 9.500000000 -2.500000000 35.500000000 9.500000000 -2.500000000 -36.500000000 10.500000000 -2.500000000 35.500000000 10.500000000 -2.500000000 -36.500000000 11.500000000 -2.500000000 35.500000000 11.500000000 -2.500000000 -36.500000000 12.500000000 -2.500000000 35.500000000 12.500000000 -2.500000000 -36.500000000 13.500000000 -2.500000000 35.500000000 13.500000000 -2.500000000 -36.500000000 14.500000000 -2.500000000 35.500000000 14.500000000 -2.500000000 -36.500000000 15.500000000 -2.500000000 35.500000000 15.500000000 -2.500000000 -36.500000000 16.500000000 -2.500000000 35.500000000 16.500000000 -2.500000000 -36.500000000 17.500000000 -2.500000000 35.500000000 17.500000000 -2.500000000 -36.500000000 18.500000000 -2.500000000 35.500000000 18.500000000 -2.500000000 -36.500000000 19.500000000 -2.500000000 35.500000000 19.500000000 -2.500000000 -36.500000000 20.500000000 -2.500000000 35.500000000 20.500000000 -2.500000000 -36.500000000 21.500000000 -2.500000000 35.500000000 21.500000000 -2.500000000 -36.500000000 22.500000000 -2.500000000 35.500000000 22.500000000 -2.500000000 -36.500000000 23.500000000 -2.500000000 35.500000000 23.500000000 -2.500000000 -36.500000000 24.500000000 -2.500000000 35.500000000 24.500000000 -2.500000000 -36.499996185 25.499996185 -2.500000000 35.499996185 25.499996185 -2.500000000 -36.499954224 26.499954224 -2.500000000 35.499954224 26.499954224 -2.500000000 -36.499591827 27.499591827 -2.500000000 35.499591827 27.499591827 -2.500000000 -36.497474670 28.497470856 -2.500000000 35.497467041 28.497470856 -2.500000000 -36.488403320 29.488407135 -2.500000000 35.488403320 29.488407135 -2.500000000 -36.458980560 30.458978653 -2.500000000 35.458980560 30.458978653 -2.500000000 -36.384422302 31.384418488 -2.500000000 35.384422302 31.384418488 -2.500000000 -36.233222961 32.233222961 -2.500000000 35.233222961 32.233222961 -2.500000000 -35.981101990 32.981101990 -2.500000000 -35.622871399 33.622871399 -2.500000000 34.622871399 33.622871399 -2.500000000 34.981101990 32.981101990 -2.500000000 -35.167964935 34.167964935 -2.500000000 -34.622871399 34.622871399 -2.500000000 33.622871399 34.622871399 -2.500000000 34.167964935 34.167964935 -2.500000000 -33.981101990 34.981101990 -2.500000000 -33.233222961 35.233222961 -2.500000000 -32.384422302 35.384418488 -2.500000000 -31.458978653 35.458976746 -2.500000000 -30.488407135 35.488403320 -2.500000000 -29.497472763 35.497467041 -2.500000000 -28.499593735 35.499591827 -2.500000000 -27.499954224 35.499954224 -2.500000000 -26.499996185 35.499996185 -2.500000000 -25.500000000 35.500000000 -2.500000000 -24.500000000 35.500000000 -2.500000000 -23.500000000 35.500000000 -2.500000000 -22.500000000 35.500000000 -2.500000000 -21.500000000 35.500000000 -2.500000000 -20.500000000 35.500000000 -2.500000000 -19.500000000 35.500000000 -2.500000000 -18.500000000 35.500000000 -2.500000000 -17.500000000 35.500000000 -2.500000000 -16.500000000 35.500000000 -2.500000000 -15.500000000 35.500000000 -2.500000000 -14.500000000 35.500000000 -2.500000000 -13.500000000 35.500000000 -2.500000000 -12.500000000 35.500000000 -2.500000000 -11.500000000 35.500000000 -2.500000000 -10.500000000 35.500000000 -2.500000000 -9.500000000 35.500000000 -2.500000000 -8.500000000 35.500000000 -2.500000000 -7.500000000 35.500000000 -2.500000000 -6.500000000 35.500000000 -2.500000000 -5.500000000 35.500000000 -2.500000000 -4.500000000 35.500000000 -2.500000000 -3.500000000 35.500000000 -2.500000000 -2.500000000 35.500000000 -2.500000000 -1.500000000 35.500000000 -2.500000000 -0.500000000 35.500000000 -2.500000000 0.500000000 35.500000000 -2.500000000 1.500000000 35.500000000 -2.500000000 2.500000000 35.500000000 -2.500000000 3.500000000 35.500000000 -2.500000000 4.500000000 35.500000000 -2.500000000 5.500000000 35.500000000 -2.500000000 6.500000000 35.500000000 -2.500000000 7.500000000 35.500000000 -2.500000000 8.500000000 35.500000000 -2.500000000 9.500000000 35.500000000 -2.500000000 10.500000000 35.500000000 -2.500000000 11.500000000 35.500000000 -2.500000000 12.500000000 35.500000000 -2.500000000 13.500000000 35.500000000 -2.500000000 14.500000000 35.500000000 -2.500000000 15.500000000 35.500000000 -2.500000000 16.500000000 35.500000000 -2.500000000 17.500000000 35.500000000 -2.500000000 18.500000000 35.500000000 -2.500000000 19.500000000 35.500000000 -2.500000000 20.500000000 35.500000000 -2.500000000 21.500000000 35.500000000 -2.500000000 22.500000000 35.500000000 -2.500000000 23.500000000 35.500000000 -2.500000000 24.500000000 35.500000000 -2.500000000 25.499996185 35.499996185 -2.500000000 26.499954224 35.499954224 -2.500000000 27.499591827 35.499591827 -2.500000000 28.497470856 35.497474670 -2.500000000 29.488407135 35.488403320 -2.500000000 30.458978653 35.458980560 -2.500000000 31.384418488 35.384422302 -2.500000000 32.233222961 35.233222961 -2.500000000 32.981101990 34.981101990 -2.500000000 -33.981101990 -35.981101990 -1.500000000 -33.233226776 -36.233222961 -1.500000000 -32.384422302 -36.384418488 -1.500000000 -31.458978653 -36.458980560 -1.500000000 -30.488407135 -36.488403320 -1.500000000 -29.497472763 -36.497474670 -1.500000000 -28.499593735 -36.499591827 -1.500000000 -27.499954224 -36.499954224 -1.500000000 -26.499996185 -36.499996185 -1.500000000 -25.500000000 -36.500000000 -1.500000000 -24.500000000 -36.500000000 -1.500000000 -23.500000000 -36.500000000 -1.500000000 -22.500000000 -36.500000000 -1.500000000 -21.500000000 -36.500000000 -1.500000000 -20.500000000 -36.500000000 -1.500000000 -19.500000000 -36.500000000 -1.500000000 -18.500000000 -36.500000000 -1.500000000 -17.500000000 -36.500000000 -1.500000000 -16.500000000 -36.500000000 -1.500000000 -15.500000000 -36.500000000 -1.500000000 -14.500000000 -36.500000000 -1.500000000 -13.500000000 -36.500000000 -1.500000000 -12.500000000 -36.500000000 -1.500000000 -11.500000000 -36.500000000 -1.500000000 -10.500000000 -36.500000000 -1.500000000 -9.500000000 -36.500000000 -1.500000000 -8.500000000 -36.500000000 -1.500000000 -7.500000000 -36.500000000 -1.500000000 -6.500000000 -36.500000000 -1.500000000 -5.500000000 -36.500000000 -1.500000000 -4.500000000 -36.500000000 -1.500000000 -3.500000000 -36.500000000 -1.500000000 -2.500000000 -36.500000000 -1.500000000 -1.500000000 -36.500000000 -1.500000000 -0.500000000 -36.500000000 -1.500000000 0.500000000 -36.500000000 -1.500000000 1.500000000 -36.500000000 -1.500000000 2.500000000 -36.500000000 -1.500000000 3.500000000 -36.500000000 -1.500000000 4.500000000 -36.500000000 -1.500000000 5.500000000 -36.500000000 -1.500000000 6.500000000 -36.500000000 -1.500000000 7.500000000 -36.500000000 -1.500000000 8.500000000 -36.500000000 -1.500000000 9.500000000 -36.500000000 -1.500000000 10.500000000 -36.500000000 -1.500000000 11.500000000 -36.500000000 -1.500000000 12.500000000 -36.500000000 -1.500000000 13.500000000 -36.500000000 -1.500000000 14.500000000 -36.500000000 -1.500000000 15.500000000 -36.500000000 -1.500000000 16.500000000 -36.500000000 -1.500000000 17.500000000 -36.500000000 -1.500000000 18.500000000 -36.500000000 -1.500000000 19.500000000 -36.500000000 -1.500000000 20.500000000 -36.500000000 -1.500000000 21.500000000 -36.500000000 -1.500000000 22.500000000 -36.500000000 -1.500000000 23.500000000 -36.500000000 -1.500000000 24.500000000 -36.500000000 -1.500000000 25.499996185 -36.499996185 -1.500000000 26.499954224 -36.499954224 -1.500000000 27.499591827 -36.499591827 -1.500000000 28.497470856 -36.497467041 -1.500000000 29.488407135 -36.488403320 -1.500000000 30.458978653 -36.458980560 -1.500000000 31.384418488 -36.384422302 -1.500000000 32.233222961 -36.233222961 -1.500000000 32.981101990 -35.981101990 -1.500000000 -35.167964935 -35.167964935 -1.500000000 -34.622871399 -35.622871399 -1.500000000 33.622871399 -35.622871399 -1.500000000 34.167964935 -35.167964935 -1.500000000 -35.981101990 -33.981101990 -1.500000000 -35.622871399 -34.622871399 -1.500000000 34.622871399 -34.622871399 -1.500000000 34.981101990 -33.981101990 -1.500000000 -36.233222961 -33.233222961 -1.500000000 35.233222961 -33.233226776 -1.500000000 -36.384418488 -32.384422302 -1.500000000 35.384418488 -32.384422302 -1.500000000 -36.458976746 -31.458978653 -1.500000000 35.458980560 -31.458978653 -1.500000000 -36.488403320 -30.488407135 -1.500000000 35.488403320 -30.488407135 -1.500000000 -36.497467041 -29.497472763 -1.500000000 35.497474670 -29.497472763 -1.500000000 -36.499591827 -28.499593735 -1.500000000 35.499591827 -28.499593735 -1.500000000 -36.499954224 -27.499954224 -1.500000000 35.499954224 -27.499954224 -1.500000000 -36.499996185 -26.499996185 -1.500000000 35.499996185 -26.499996185 -1.500000000 -36.500000000 -25.500000000 -1.500000000 35.500000000 -25.500000000 -1.500000000 -36.500000000 -24.500000000 -1.500000000 35.500000000 -24.500000000 -1.500000000 -36.500000000 -23.500000000 -1.500000000 35.500000000 -23.500000000 -1.500000000 -36.500000000 -22.500000000 -1.500000000 35.500000000 -22.500000000 -1.500000000 -36.500000000 -21.500000000 -1.500000000 35.500000000 -21.500000000 -1.500000000 -36.500000000 -20.500000000 -1.500000000 35.500000000 -20.500000000 -1.500000000 -36.500000000 -19.500000000 -1.500000000 35.500000000 -19.500000000 -1.500000000 -36.500000000 -18.500000000 -1.500000000 35.500000000 -18.500000000 -1.500000000 -36.500000000 -17.500000000 -1.500000000 35.500000000 -17.500000000 -1.500000000 -36.500000000 -16.500000000 -1.500000000 35.500000000 -16.500000000 -1.500000000 -36.500000000 -15.500000000 -1.500000000 35.500000000 -15.500000000 -1.500000000 -36.500000000 -14.500000000 -1.500000000 35.500000000 -14.500000000 -1.500000000 -36.500000000 -13.500000000 -1.500000000 35.500000000 -13.500000000 -1.500000000 -36.500000000 -12.500000000 -1.500000000 35.500000000 -12.500000000 -1.500000000 -36.500000000 -11.500000000 -1.500000000 35.500000000 -11.500000000 -1.500000000 -36.500000000 -10.500000000 -1.500000000 35.500000000 -10.500000000 -1.500000000 -36.500000000 -9.500000000 -1.500000000 35.500000000 -9.500000000 -1.500000000 -36.500000000 -8.500000000 -1.500000000 35.500000000 -8.500000000 -1.500000000 -36.500000000 -7.500000000 -1.500000000 35.500000000 -7.500000000 -1.500000000 -36.500000000 -6.500000000 -1.500000000 35.500000000 -6.500000000 -1.500000000 -36.500000000 -5.500000000 -1.500000000 35.500000000 -5.500000000 -1.500000000 -36.500000000 -4.500000000 -1.500000000 35.500000000 -4.500000000 -1.500000000 -36.500000000 -3.500000000 -1.500000000 35.500000000 -3.500000000 -1.500000000 -36.500000000 -2.500000000 -1.500000000 35.500000000 -2.500000000 -1.500000000 -36.500000000 -1.500000000 -1.500000000 35.500000000 -1.500000000 -1.500000000 -36.500000000 -0.500000000 -1.500000000 35.500000000 -0.500000000 -1.500000000 -36.500000000 0.500000000 -1.500000000 35.500000000 0.500000000 -1.500000000 -36.500000000 1.500000000 -1.500000000 35.500000000 1.500000000 -1.500000000 -36.500000000 2.500000000 -1.500000000 35.500000000 2.500000000 -1.500000000 -36.500000000 3.500000000 -1.500000000 35.500000000 3.500000000 -1.500000000 -36.500000000 4.500000000 -1.500000000 35.500000000 4.500000000 -1.500000000 -36.500000000 5.500000000 -1.500000000 35.500000000 5.500000000 -1.500000000 -36.500000000 6.500000000 -1.500000000 35.500000000 6.500000000 -1.500000000 -36.500000000 7.500000000 -1.500000000 35.500000000 7.500000000 -1.500000000 -36.500000000 8.500000000 -1.500000000 35.500000000 8.500000000 -1.500000000 -36.500000000 9.500000000 -1.500000000 35.500000000 9.500000000 -1.500000000 -36.500000000 10.500000000 -1.500000000 35.500000000 10.500000000 -1.500000000 -36.500000000 11.500000000 -1.500000000 35.500000000 11.500000000 -1.500000000 -36.500000000 12.500000000 -1.500000000 35.500000000 12.500000000 -1.500000000 -36.500000000 13.500000000 -1.500000000 35.500000000 13.500000000 -1.500000000 -36.500000000 14.500000000 -1.500000000 35.500000000 14.500000000 -1.500000000 -36.500000000 15.500000000 -1.500000000 35.500000000 15.500000000 -1.500000000 -36.500000000 16.500000000 -1.500000000 35.500000000 16.500000000 -1.500000000 -36.500000000 17.500000000 -1.500000000 35.500000000 17.500000000 -1.500000000 -36.500000000 18.500000000 -1.500000000 35.500000000 18.500000000 -1.500000000 -36.500000000 19.500000000 -1.500000000 35.500000000 19.500000000 -1.500000000 -36.500000000 20.500000000 -1.500000000 35.500000000 20.500000000 -1.500000000 -36.500000000 21.500000000 -1.500000000 35.500000000 21.500000000 -1.500000000 -36.500000000 22.500000000 -1.500000000 35.500000000 22.500000000 -1.500000000 -36.500000000 23.500000000 -1.500000000 35.500000000 23.500000000 -1.500000000 -36.500000000 24.500000000 -1.500000000 35.500000000 24.500000000 -1.500000000 -36.499996185 25.499996185 -1.500000000 35.499996185 25.499996185 -1.500000000 -36.499954224 26.499954224 -1.500000000 35.499954224 26.499954224 -1.500000000 -36.499591827 27.499591827 -1.500000000 35.499591827 27.499591827 -1.500000000 -36.497474670 28.497470856 -1.500000000 35.497467041 28.497470856 -1.500000000 -36.488403320 29.488407135 -1.500000000 35.488403320 29.488407135 -1.500000000 -36.458980560 30.458978653 -1.500000000 35.458980560 30.458978653 -1.500000000 -36.384422302 31.384418488 -1.500000000 35.384422302 31.384418488 -1.500000000 -36.233222961 32.233222961 -1.500000000 35.233222961 32.233222961 -1.500000000 -35.981101990 32.981101990 -1.500000000 -35.622871399 33.622871399 -1.500000000 34.622871399 33.622871399 -1.500000000 34.981101990 32.981101990 -1.500000000 -35.167964935 34.167964935 -1.500000000 -34.622871399 34.622871399 -1.500000000 33.622871399 34.622871399 -1.500000000 34.167964935 34.167964935 -1.500000000 -33.981101990 34.981101990 -1.500000000 -33.233222961 35.233222961 -1.500000000 -32.384422302 35.384418488 -1.500000000 -31.458978653 35.458976746 -1.500000000 -30.488407135 35.488403320 -1.500000000 -29.497472763 35.497467041 -1.500000000 -28.499593735 35.499591827 -1.500000000 -27.499954224 35.499954224 -1.500000000 -26.499996185 35.499996185 -1.500000000 -25.500000000 35.500000000 -1.500000000 -24.500000000 35.500000000 -1.500000000 -23.500000000 35.500000000 -1.500000000 -22.500000000 35.500000000 -1.500000000 -21.500000000 35.500000000 -1.500000000 -20.500000000 35.500000000 -1.500000000 -19.500000000 35.500000000 -1.500000000 -18.500000000 35.500000000 -1.500000000 -17.500000000 35.500000000 -1.500000000 -16.500000000 35.500000000 -1.500000000 -15.500000000 35.500000000 -1.500000000 -14.500000000 35.500000000 -1.500000000 -13.500000000 35.500000000 -1.500000000 -12.500000000 35.500000000 -1.500000000 -11.500000000 35.500000000 -1.500000000 -10.500000000 35.500000000 -1.500000000 -9.500000000 35.500000000 -1.500000000 -8.500000000 35.500000000 -1.500000000 -7.500000000 35.500000000 -1.500000000 -6.500000000 35.500000000 -1.500000000 -5.500000000 35.500000000 -1.500000000 -4.500000000 35.500000000 -1.500000000 -3.500000000 35.500000000 -1.500000000 -2.500000000 35.500000000 -1.500000000 -1.500000000 35.500000000 -1.500000000 -0.500000000 35.500000000 -1.500000000 0.500000000 35.500000000 -1.500000000 1.500000000 35.500000000 -1.500000000 2.500000000 35.500000000 -1.500000000 3.500000000 35.500000000 -1.500000000 4.500000000 35.500000000 -1.500000000 5.500000000 35.500000000 -1.500000000 6.500000000 35.500000000 -1.500000000 7.500000000 35.500000000 -1.500000000 8.500000000 35.500000000 -1.500000000 9.500000000 35.500000000 -1.500000000 10.500000000 35.500000000 -1.500000000 11.500000000 35.500000000 -1.500000000 12.500000000 35.500000000 -1.500000000 13.500000000 35.500000000 -1.500000000 14.500000000 35.500000000 -1.500000000 15.500000000 35.500000000 -1.500000000 16.500000000 35.500000000 -1.500000000 17.500000000 35.500000000 -1.500000000 18.500000000 35.500000000 -1.500000000 19.500000000 35.500000000 -1.500000000 20.500000000 35.500000000 -1.500000000 21.500000000 35.500000000 -1.500000000 22.500000000 35.500000000 -1.500000000 23.500000000 35.500000000 -1.500000000 24.500000000 35.500000000 -1.500000000 25.499996185 35.499996185 -1.500000000 26.499954224 35.499954224 -1.500000000 27.499591827 35.499591827 -1.500000000 28.497470856 35.497474670 -1.500000000 29.488407135 35.488403320 -1.500000000 30.458978653 35.458980560 -1.500000000 31.384418488 35.384422302 -1.500000000 32.233222961 35.233222961 -1.500000000 32.981101990 34.981101990 -1.500000000 -33.981101990 -35.981101990 -0.500000000 -33.233226776 -36.233222961 -0.500000000 -32.384422302 -36.384418488 -0.500000000 -31.458978653 -36.458980560 -0.500000000 -30.488407135 -36.488403320 -0.500000000 -29.497472763 -36.497474670 -0.500000000 -28.499593735 -36.499591827 -0.500000000 -27.499954224 -36.499954224 -0.500000000 -26.499996185 -36.499996185 -0.500000000 -25.500000000 -36.500000000 -0.500000000 -24.500000000 -36.500000000 -0.500000000 -23.500000000 -36.500000000 -0.500000000 -22.500000000 -36.500000000 -0.500000000 -21.500000000 -36.500000000 -0.500000000 -20.500000000 -36.500000000 -0.500000000 -19.500000000 -36.500000000 -0.500000000 -18.500000000 -36.500000000 -0.500000000 -17.500000000 -36.500000000 -0.500000000 -16.500000000 -36.500000000 -0.500000000 -15.500000000 -36.500000000 -0.500000000 -14.500000000 -36.500000000 -0.500000000 -13.500000000 -36.500000000 -0.500000000 -12.500000000 -36.500000000 -0.500000000 -11.500000000 -36.500000000 -0.500000000 -10.500000000 -36.500000000 -0.500000000 -9.500000000 -36.500000000 -0.500000000 -8.500000000 -36.500000000 -0.500000000 -7.500000000 -36.500000000 -0.500000000 -6.500000000 -36.500000000 -0.500000000 -5.500000000 -36.500000000 -0.500000000 -4.500000000 -36.500000000 -0.500000000 -3.500000000 -36.500000000 -0.500000000 -2.500000000 -36.500000000 -0.500000000 -1.500000000 -36.500000000 -0.500000000 -0.500000000 -36.500000000 -0.500000000 0.500000000 -36.500000000 -0.500000000 1.500000000 -36.500000000 -0.500000000 2.500000000 -36.500000000 -0.500000000 3.500000000 -36.500000000 -0.500000000 4.500000000 -36.500000000 -0.500000000 5.500000000 -36.500000000 -0.500000000 6.500000000 -36.500000000 -0.500000000 7.500000000 -36.500000000 -0.500000000 8.500000000 -36.500000000 -0.500000000 9.500000000 -36.500000000 -0.500000000 10.500000000 -36.500000000 -0.500000000 11.500000000 -36.500000000 -0.500000000 12.500000000 -36.500000000 -0.500000000 13.500000000 -36.500000000 -0.500000000 14.500000000 -36.500000000 -0.500000000 15.500000000 -36.500000000 -0.500000000 16.500000000 -36.500000000 -0.500000000 17.500000000 -36.500000000 -0.500000000 18.500000000 -36.500000000 -0.500000000 19.500000000 -36.500000000 -0.500000000 20.500000000 -36.500000000 -0.500000000 21.500000000 -36.500000000 -0.500000000 22.500000000 -36.500000000 -0.500000000 23.500000000 -36.500000000 -0.500000000 24.500000000 -36.500000000 -0.500000000 25.499996185 -36.499996185 -0.500000000 26.499954224 -36.499954224 -0.500000000 27.499591827 -36.499591827 -0.500000000 28.497470856 -36.497467041 -0.500000000 29.488407135 -36.488403320 -0.500000000 30.458978653 -36.458980560 -0.500000000 31.384418488 -36.384422302 -0.500000000 32.233222961 -36.233222961 -0.500000000 32.981101990 -35.981101990 -0.500000000 -35.167964935 -35.167964935 -0.500000000 -34.622871399 -35.622871399 -0.500000000 33.622871399 -35.622871399 -0.500000000 34.167964935 -35.167964935 -0.500000000 -35.981101990 -33.981101990 -0.500000000 -35.622871399 -34.622871399 -0.500000000 34.622871399 -34.622871399 -0.500000000 34.981101990 -33.981101990 -0.500000000 -36.233222961 -33.233222961 -0.500000000 35.233222961 -33.233226776 -0.500000000 -36.384418488 -32.384422302 -0.500000000 35.384418488 -32.384422302 -0.500000000 -36.458976746 -31.458978653 -0.500000000 35.458980560 -31.458978653 -0.500000000 -36.488403320 -30.488407135 -0.500000000 35.488403320 -30.488407135 -0.500000000 -36.497467041 -29.497472763 -0.500000000 35.497474670 -29.497472763 -0.500000000 -36.499591827 -28.499593735 -0.500000000 35.499591827 -28.499593735 -0.500000000 -36.499954224 -27.499954224 -0.500000000 35.499954224 -27.499954224 -0.500000000 -36.499996185 -26.499996185 -0.500000000 35.499996185 -26.499996185 -0.500000000 -36.500000000 -25.500000000 -0.500000000 35.500000000 -25.500000000 -0.500000000 -36.500000000 -24.500000000 -0.500000000 35.500000000 -24.500000000 -0.500000000 -36.500000000 -23.500000000 -0.500000000 35.500000000 -23.500000000 -0.500000000 -36.500000000 -22.500000000 -0.500000000 35.500000000 -22.500000000 -0.500000000 -36.500000000 -21.500000000 -0.500000000 35.500000000 -21.500000000 -0.500000000 -36.500000000 -20.500000000 -0.500000000 35.500000000 -20.500000000 -0.500000000 -36.500000000 -19.500000000 -0.500000000 35.500000000 -19.500000000 -0.500000000 -36.500000000 -18.500000000 -0.500000000 35.500000000 -18.500000000 -0.500000000 -36.500000000 -17.500000000 -0.500000000 35.500000000 -17.500000000 -0.500000000 -36.500000000 -16.500000000 -0.500000000 35.500000000 -16.500000000 -0.500000000 -36.500000000 -15.500000000 -0.500000000 35.500000000 -15.500000000 -0.500000000 -36.500000000 -14.500000000 -0.500000000 35.500000000 -14.500000000 -0.500000000 -36.500000000 -13.500000000 -0.500000000 35.500000000 -13.500000000 -0.500000000 -36.500000000 -12.500000000 -0.500000000 35.500000000 -12.500000000 -0.500000000 -36.500000000 -11.500000000 -0.500000000 35.500000000 -11.500000000 -0.500000000 -36.500000000 -10.500000000 -0.500000000 35.500000000 -10.500000000 -0.500000000 -36.500000000 -9.500000000 -0.500000000 35.500000000 -9.500000000 -0.500000000 -36.500000000 -8.500000000 -0.500000000 35.500000000 -8.500000000 -0.500000000 -36.500000000 -7.500000000 -0.500000000 35.500000000 -7.500000000 -0.500000000 -36.500000000 -6.500000000 -0.500000000 35.500000000 -6.500000000 -0.500000000 -36.500000000 -5.500000000 -0.500000000 35.500000000 -5.500000000 -0.500000000 -36.500000000 -4.500000000 -0.500000000 35.500000000 -4.500000000 -0.500000000 -36.500000000 -3.500000000 -0.500000000 35.500000000 -3.500000000 -0.500000000 -36.500000000 -2.500000000 -0.500000000 35.500000000 -2.500000000 -0.500000000 -36.500000000 -1.500000000 -0.500000000 35.500000000 -1.500000000 -0.500000000 -36.500000000 -0.500000000 -0.500000000 35.500000000 -0.500000000 -0.500000000 -36.500000000 0.500000000 -0.500000000 35.500000000 0.500000000 -0.500000000 -36.500000000 1.500000000 -0.500000000 35.500000000 1.500000000 -0.500000000 -36.500000000 2.500000000 -0.500000000 35.500000000 2.500000000 -0.500000000 -36.500000000 3.500000000 -0.500000000 35.500000000 3.500000000 -0.500000000 -36.500000000 4.500000000 -0.500000000 35.500000000 4.500000000 -0.500000000 -36.500000000 5.500000000 -0.500000000 35.500000000 5.500000000 -0.500000000 -36.500000000 6.500000000 -0.500000000 35.500000000 6.500000000 -0.500000000 -36.500000000 7.500000000 -0.500000000 35.500000000 7.500000000 -0.500000000 -36.500000000 8.500000000 -0.500000000 35.500000000 8.500000000 -0.500000000 -36.500000000 9.500000000 -0.500000000 35.500000000 9.500000000 -0.500000000 -36.500000000 10.500000000 -0.500000000 35.500000000 10.500000000 -0.500000000 -36.500000000 11.500000000 -0.500000000 35.500000000 11.500000000 -0.500000000 -36.500000000 12.500000000 -0.500000000 35.500000000 12.500000000 -0.500000000 -36.500000000 13.500000000 -0.500000000 35.500000000 13.500000000 -0.500000000 -36.500000000 14.500000000 -0.500000000 35.500000000 14.500000000 -0.500000000 -36.500000000 15.500000000 -0.500000000 35.500000000 15.500000000 -0.500000000 -36.500000000 16.500000000 -0.500000000 35.500000000 16.500000000 -0.500000000 -36.500000000 17.500000000 -0.500000000 35.500000000 17.500000000 -0.500000000 -36.500000000 18.500000000 -0.500000000 35.500000000 18.500000000 -0.500000000 -36.500000000 19.500000000 -0.500000000 35.500000000 19.500000000 -0.500000000 -36.500000000 20.500000000 -0.500000000 35.500000000 20.500000000 -0.500000000 -36.500000000 21.500000000 -0.500000000 35.500000000 21.500000000 -0.500000000 -36.500000000 22.500000000 -0.500000000 35.500000000 22.500000000 -0.500000000 -36.500000000 23.500000000 -0.500000000 35.500000000 23.500000000 -0.500000000 -36.500000000 24.500000000 -0.500000000 35.500000000 24.500000000 -0.500000000 -36.499996185 25.499996185 -0.500000000 35.499996185 25.499996185 -0.500000000 -36.499954224 26.499954224 -0.500000000 35.499954224 26.499954224 -0.500000000 -36.499591827 27.499591827 -0.500000000 35.499591827 27.499591827 -0.500000000 -36.497474670 28.497470856 -0.500000000 35.497467041 28.497470856 -0.500000000 -36.488403320 29.488407135 -0.500000000 35.488403320 29.488407135 -0.500000000 -36.458980560 30.458978653 -0.500000000 35.458980560 30.458978653 -0.500000000 -36.384422302 31.384418488 -0.500000000 35.384422302 31.384418488 -0.500000000 -36.233222961 32.233222961 -0.500000000 35.233222961 32.233222961 -0.500000000 -35.981101990 32.981101990 -0.500000000 -35.622871399 33.622871399 -0.500000000 34.622871399 33.622871399 -0.500000000 34.981101990 32.981101990 -0.500000000 -35.167964935 34.167964935 -0.500000000 -34.622871399 34.622871399 -0.500000000 33.622871399 34.622871399 -0.500000000 34.167964935 34.167964935 -0.500000000 -33.981101990 34.981101990 -0.500000000 -33.233222961 35.233222961 -0.500000000 -32.384422302 35.384418488 -0.500000000 -31.458978653 35.458976746 -0.500000000 -30.488407135 35.488403320 -0.500000000 -29.497472763 35.497467041 -0.500000000 -28.499593735 35.499591827 -0.500000000 -27.499954224 35.499954224 -0.500000000 -26.499996185 35.499996185 -0.500000000 -25.500000000 35.500000000 -0.500000000 -24.500000000 35.500000000 -0.500000000 -23.500000000 35.500000000 -0.500000000 -22.500000000 35.500000000 -0.500000000 -21.500000000 35.500000000 -0.500000000 -20.500000000 35.500000000 -0.500000000 -19.500000000 35.500000000 -0.500000000 -18.500000000 35.500000000 -0.500000000 -17.500000000 35.500000000 -0.500000000 -16.500000000 35.500000000 -0.500000000 -15.500000000 35.500000000 -0.500000000 -14.500000000 35.500000000 -0.500000000 -13.500000000 35.500000000 -0.500000000 -12.500000000 35.500000000 -0.500000000 -11.500000000 35.500000000 -0.500000000 -10.500000000 35.500000000 -0.500000000 -9.500000000 35.500000000 -0.500000000 -8.500000000 35.500000000 -0.500000000 -7.500000000 35.500000000 -0.500000000 -6.500000000 35.500000000 -0.500000000 -5.500000000 35.500000000 -0.500000000 -4.500000000 35.500000000 -0.500000000 -3.500000000 35.500000000 -0.500000000 -2.500000000 35.500000000 -0.500000000 -1.500000000 35.500000000 -0.500000000 -0.500000000 35.500000000 -0.500000000 0.500000000 35.500000000 -0.500000000 1.500000000 35.500000000 -0.500000000 2.500000000 35.500000000 -0.500000000 3.500000000 35.500000000 -0.500000000 4.500000000 35.500000000 -0.500000000 5.500000000 35.500000000 -0.500000000 6.500000000 35.500000000 -0.500000000 7.500000000 35.500000000 -0.500000000 8.500000000 35.500000000 -0.500000000 9.500000000 35.500000000 -0.500000000 10.500000000 35.500000000 -0.500000000 11.500000000 35.500000000 -0.500000000 12.500000000 35.500000000 -0.500000000 13.500000000 35.500000000 -0.500000000 14.500000000 35.500000000 -0.500000000 15.500000000 35.500000000 -0.500000000 16.500000000 35.500000000 -0.500000000 17.500000000 35.500000000 -0.500000000 18.500000000 35.500000000 -0.500000000 19.500000000 35.500000000 -0.500000000 20.500000000 35.500000000 -0.500000000 21.500000000 35.500000000 -0.500000000 22.500000000 35.500000000 -0.500000000 23.500000000 35.500000000 -0.500000000 24.500000000 35.500000000 -0.500000000 25.499996185 35.499996185 -0.500000000 26.499954224 35.499954224 -0.500000000 27.499591827 35.499591827 -0.500000000 28.497470856 35.497474670 -0.500000000 29.488407135 35.488403320 -0.500000000 30.458978653 35.458980560 -0.500000000 31.384418488 35.384422302 -0.500000000 32.233222961 35.233222961 -0.500000000 32.981101990 34.981101990 -0.500000000 -33.981101990 -35.981101990 0.500000000 -33.233226776 -36.233222961 0.500000000 -32.384422302 -36.384418488 0.500000000 -31.458978653 -36.458980560 0.500000000 -30.488407135 -36.488403320 0.500000000 -29.497472763 -36.497474670 0.500000000 -28.499593735 -36.499591827 0.500000000 -27.499954224 -36.499954224 0.500000000 -26.499996185 -36.499996185 0.500000000 -25.500000000 -36.500000000 0.500000000 -24.500000000 -36.500000000 0.500000000 -23.500000000 -36.500000000 0.500000000 -22.500000000 -36.500000000 0.500000000 -21.500000000 -36.500000000 0.500000000 -20.500000000 -36.500000000 0.500000000 -19.500000000 -36.500000000 0.500000000 -18.500000000 -36.500000000 0.500000000 -17.500000000 -36.500000000 0.500000000 -16.500000000 -36.500000000 0.500000000 -15.500000000 -36.500000000 0.500000000 -14.500000000 -36.500000000 0.500000000 -13.500000000 -36.500000000 0.500000000 -12.500000000 -36.500000000 0.500000000 -11.500000000 -36.500000000 0.500000000 -10.500000000 -36.500000000 0.500000000 -9.500000000 -36.500000000 0.500000000 -8.500000000 -36.500000000 0.500000000 -7.500000000 -36.500000000 0.500000000 -6.500000000 -36.500000000 0.500000000 -5.500000000 -36.500000000 0.500000000 -4.500000000 -36.500000000 0.500000000 -3.500000000 -36.500000000 0.500000000 -2.500000000 -36.500000000 0.500000000 -1.500000000 -36.500000000 0.500000000 -0.500000000 -36.500000000 0.500000000 0.500000000 -36.500000000 0.500000000 1.500000000 -36.500000000 0.500000000 2.500000000 -36.500000000 0.500000000 3.500000000 -36.500000000 0.500000000 4.500000000 -36.500000000 0.500000000 5.500000000 -36.500000000 0.500000000 6.500000000 -36.500000000 0.500000000 7.500000000 -36.500000000 0.500000000 8.500000000 -36.500000000 0.500000000 9.500000000 -36.500000000 0.500000000 10.500000000 -36.500000000 0.500000000 11.500000000 -36.500000000 0.500000000 12.500000000 -36.500000000 0.500000000 13.500000000 -36.500000000 0.500000000 14.500000000 -36.500000000 0.500000000 15.500000000 -36.500000000 0.500000000 16.500000000 -36.500000000 0.500000000 17.500000000 -36.500000000 0.500000000 18.500000000 -36.500000000 0.500000000 19.500000000 -36.500000000 0.500000000 20.500000000 -36.500000000 0.500000000 21.500000000 -36.500000000 0.500000000 22.500000000 -36.500000000 0.500000000 23.500000000 -36.500000000 0.500000000 24.500000000 -36.500000000 0.500000000 25.499996185 -36.499996185 0.500000000 26.499954224 -36.499954224 0.500000000 27.499591827 -36.499591827 0.500000000 28.497470856 -36.497467041 0.500000000 29.488407135 -36.488403320 0.500000000 30.458978653 -36.458980560 0.500000000 31.384418488 -36.384422302 0.500000000 32.233222961 -36.233222961 0.500000000 32.981101990 -35.981101990 0.500000000 -35.167964935 -35.167964935 0.500000000 -34.622871399 -35.622871399 0.500000000 33.622871399 -35.622871399 0.500000000 34.167964935 -35.167964935 0.500000000 -35.981101990 -33.981101990 0.500000000 -35.622871399 -34.622871399 0.500000000 34.622871399 -34.622871399 0.500000000 34.981101990 -33.981101990 0.500000000 -36.233222961 -33.233222961 0.500000000 35.233222961 -33.233226776 0.500000000 -36.384418488 -32.384422302 0.500000000 35.384418488 -32.384422302 0.500000000 -36.458976746 -31.458978653 0.500000000 35.458980560 -31.458978653 0.500000000 -36.488403320 -30.488407135 0.500000000 35.488403320 -30.488407135 0.500000000 -36.497467041 -29.497472763 0.500000000 35.497474670 -29.497472763 0.500000000 -36.499591827 -28.499593735 0.500000000 35.499591827 -28.499593735 0.500000000 -36.499954224 -27.499954224 0.500000000 35.499954224 -27.499954224 0.500000000 -36.499996185 -26.499996185 0.500000000 35.499996185 -26.499996185 0.500000000 -36.500000000 -25.500000000 0.500000000 35.500000000 -25.500000000 0.500000000 -36.500000000 -24.500000000 0.500000000 35.500000000 -24.500000000 0.500000000 -36.500000000 -23.500000000 0.500000000 35.500000000 -23.500000000 0.500000000 -36.500000000 -22.500000000 0.500000000 35.500000000 -22.500000000 0.500000000 -36.500000000 -21.500000000 0.500000000 35.500000000 -21.500000000 0.500000000 -36.500000000 -20.500000000 0.500000000 35.500000000 -20.500000000 0.500000000 -36.500000000 -19.500000000 0.500000000 35.500000000 -19.500000000 0.500000000 -36.500000000 -18.500000000 0.500000000 35.500000000 -18.500000000 0.500000000 -36.500000000 -17.500000000 0.500000000 35.500000000 -17.500000000 0.500000000 -36.500000000 -16.500000000 0.500000000 35.500000000 -16.500000000 0.500000000 -36.500000000 -15.500000000 0.500000000 35.500000000 -15.500000000 0.500000000 -36.500000000 -14.500000000 0.500000000 35.500000000 -14.500000000 0.500000000 -36.500000000 -13.500000000 0.500000000 35.500000000 -13.500000000 0.500000000 -36.500000000 -12.500000000 0.500000000 35.500000000 -12.500000000 0.500000000 -36.500000000 -11.500000000 0.500000000 35.500000000 -11.500000000 0.500000000 -36.500000000 -10.500000000 0.500000000 35.500000000 -10.500000000 0.500000000 -36.500000000 -9.500000000 0.500000000 35.500000000 -9.500000000 0.500000000 -36.500000000 -8.500000000 0.500000000 35.500000000 -8.500000000 0.500000000 -36.500000000 -7.500000000 0.500000000 35.500000000 -7.500000000 0.500000000 -36.500000000 -6.500000000 0.500000000 35.500000000 -6.500000000 0.500000000 -36.500000000 -5.500000000 0.500000000 35.500000000 -5.500000000 0.500000000 -36.500000000 -4.500000000 0.500000000 35.500000000 -4.500000000 0.500000000 -36.500000000 -3.500000000 0.500000000 35.500000000 -3.500000000 0.500000000 -36.500000000 -2.500000000 0.500000000 35.500000000 -2.500000000 0.500000000 -36.500000000 -1.500000000 0.500000000 35.500000000 -1.500000000 0.500000000 -36.500000000 -0.500000000 0.500000000 35.500000000 -0.500000000 0.500000000 -36.500000000 0.500000000 0.500000000 35.500000000 0.500000000 0.500000000 -36.500000000 1.500000000 0.500000000 35.500000000 1.500000000 0.500000000 -36.500000000 2.500000000 0.500000000 35.500000000 2.500000000 0.500000000 -36.500000000 3.500000000 0.500000000 35.500000000 3.500000000 0.500000000 -36.500000000 4.500000000 0.500000000 35.500000000 4.500000000 0.500000000 -36.500000000 5.500000000 0.500000000 35.500000000 5.500000000 0.500000000 -36.500000000 6.500000000 0.500000000 35.500000000 6.500000000 0.500000000 -36.500000000 7.500000000 0.500000000 35.500000000 7.500000000 0.500000000 -36.500000000 8.500000000 0.500000000 35.500000000 8.500000000 0.500000000 -36.500000000 9.500000000 0.500000000 35.500000000 9.500000000 0.500000000 -36.500000000 10.500000000 0.500000000 35.500000000 10.500000000 0.500000000 -36.500000000 11.500000000 0.500000000 35.500000000 11.500000000 0.500000000 -36.500000000 12.500000000 0.500000000 35.500000000 12.500000000 0.500000000 -36.500000000 13.500000000 0.500000000 35.500000000 13.500000000 0.500000000 -36.500000000 14.500000000 0.500000000 35.500000000 14.500000000 0.500000000 -36.500000000 15.500000000 0.500000000 35.500000000 15.500000000 0.500000000 -36.500000000 16.500000000 0.500000000 35.500000000 16.500000000 0.500000000 -36.500000000 17.500000000 0.500000000 35.500000000 17.500000000 0.500000000 -36.500000000 18.500000000 0.500000000 35.500000000 18.500000000 0.500000000 -36.500000000 19.500000000 0.500000000 35.500000000 19.500000000 0.500000000 -36.500000000 20.500000000 0.500000000 35.500000000 20.500000000 0.500000000 -36.500000000 21.500000000 0.500000000 35.500000000 21.500000000 0.500000000 -36.500000000 22.500000000 0.500000000 35.500000000 22.500000000 0.500000000 -36.500000000 23.500000000 0.500000000 35.500000000 23.500000000 0.500000000 -36.500000000 24.500000000 0.500000000 35.500000000 24.500000000 0.500000000 -36.499996185 25.499996185 0.500000000 35.499996185 25.499996185 0.500000000 -36.499954224 26.499954224 0.500000000 35.499954224 26.499954224 0.500000000 -36.499591827 27.499591827 0.500000000 35.499591827 27.499591827 0.500000000 -36.497474670 28.497470856 0.500000000 35.497467041 28.497470856 0.500000000 -36.488403320 29.488407135 0.500000000 35.488403320 29.488407135 0.500000000 -36.458980560 30.458978653 0.500000000 35.458980560 30.458978653 0.500000000 -36.384422302 31.384418488 0.500000000 35.384422302 31.384418488 0.500000000 -36.233222961 32.233222961 0.500000000 35.233222961 32.233222961 0.500000000 -35.981101990 32.981101990 0.500000000 -35.622871399 33.622871399 0.500000000 34.622871399 33.622871399 0.500000000 34.981101990 32.981101990 0.500000000 -35.167964935 34.167964935 0.500000000 -34.622871399 34.622871399 0.500000000 33.622871399 34.622871399 0.500000000 34.167964935 34.167964935 0.500000000 -33.981101990 34.981101990 0.500000000 -33.233222961 35.233222961 0.500000000 -32.384422302 35.384418488 0.500000000 -31.458978653 35.458976746 0.500000000 -30.488407135 35.488403320 0.500000000 -29.497472763 35.497467041 0.500000000 -28.499593735 35.499591827 0.500000000 -27.499954224 35.499954224 0.500000000 -26.499996185 35.499996185 0.500000000 -25.500000000 35.500000000 0.500000000 -24.500000000 35.500000000 0.500000000 -23.500000000 35.500000000 0.500000000 -22.500000000 35.500000000 0.500000000 -21.500000000 35.500000000 0.500000000 -20.500000000 35.500000000 0.500000000 -19.500000000 35.500000000 0.500000000 -18.500000000 35.500000000 0.500000000 -17.500000000 35.500000000 0.500000000 -16.500000000 35.500000000 0.500000000 -15.500000000 35.500000000 0.500000000 -14.500000000 35.500000000 0.500000000 -13.500000000 35.500000000 0.500000000 -12.500000000 35.500000000 0.500000000 -11.500000000 35.500000000 0.500000000 -10.500000000 35.500000000 0.500000000 -9.500000000 35.500000000 0.500000000 -8.500000000 35.500000000 0.500000000 -7.500000000 35.500000000 0.500000000 -6.500000000 35.500000000 0.500000000 -5.500000000 35.500000000 0.500000000 -4.500000000 35.500000000 0.500000000 -3.500000000 35.500000000 0.500000000 -2.500000000 35.500000000 0.500000000 -1.500000000 35.500000000 0.500000000 -0.500000000 35.500000000 0.500000000 0.500000000 35.500000000 0.500000000 1.500000000 35.500000000 0.500000000 2.500000000 35.500000000 0.500000000 3.500000000 35.500000000 0.500000000 4.500000000 35.500000000 0.500000000 5.500000000 35.500000000 0.500000000 6.500000000 35.500000000 0.500000000 7.500000000 35.500000000 0.500000000 8.500000000 35.500000000 0.500000000 9.500000000 35.500000000 0.500000000 10.500000000 35.500000000 0.500000000 11.500000000 35.500000000 0.500000000 12.500000000 35.500000000 0.500000000 13.500000000 35.500000000 0.500000000 14.500000000 35.500000000 0.500000000 15.500000000 35.500000000 0.500000000 16.500000000 35.500000000 0.500000000 17.500000000 35.500000000 0.500000000 18.500000000 35.500000000 0.500000000 19.500000000 35.500000000 0.500000000 20.500000000 35.500000000 0.500000000 21.500000000 35.500000000 0.500000000 22.500000000 35.500000000 0.500000000 23.500000000 35.500000000 0.500000000 24.500000000 35.500000000 0.500000000 25.499996185 35.499996185 0.500000000 26.499954224 35.499954224 0.500000000 27.499591827 35.499591827 0.500000000 28.497470856 35.497474670 0.500000000 29.488407135 35.488403320 0.500000000 30.458978653 35.458980560 0.500000000 31.384418488 35.384422302 0.500000000 32.233222961 35.233222961 0.500000000 32.981101990 34.981101990 0.500000000 -33.981101990 -35.981101990 1.500000000 -33.233226776 -36.233222961 1.500000000 -32.384422302 -36.384418488 1.500000000 -31.458978653 -36.458980560 1.500000000 -30.488407135 -36.488403320 1.500000000 -29.497472763 -36.497474670 1.500000000 -28.499593735 -36.499591827 1.500000000 -27.499954224 -36.499954224 1.500000000 -26.499996185 -36.499996185 1.500000000 -25.500000000 -36.500000000 1.500000000 -24.500000000 -36.500000000 1.500000000 -23.500000000 -36.500000000 1.500000000 -22.500000000 -36.500000000 1.500000000 -21.500000000 -36.500000000 1.500000000 -20.500000000 -36.500000000 1.500000000 -19.500000000 -36.500000000 1.500000000 -18.500000000 -36.500000000 1.500000000 -17.500000000 -36.500000000 1.500000000 -16.500000000 -36.500000000 1.500000000 -15.500000000 -36.500000000 1.500000000 -14.500000000 -36.500000000 1.500000000 -13.500000000 -36.500000000 1.500000000 -12.500000000 -36.500000000 1.500000000 -11.500000000 -36.500000000 1.500000000 -10.500000000 -36.500000000 1.500000000 -9.500000000 -36.500000000 1.500000000 -8.500000000 -36.500000000 1.500000000 -7.500000000 -36.500000000 1.500000000 -6.500000000 -36.500000000 1.500000000 -5.500000000 -36.500000000 1.500000000 -4.500000000 -36.500000000 1.500000000 -3.500000000 -36.500000000 1.500000000 -2.500000000 -36.500000000 1.500000000 -1.500000000 -36.500000000 1.500000000 -0.500000000 -36.500000000 1.500000000 0.500000000 -36.500000000 1.500000000 1.500000000 -36.500000000 1.500000000 2.500000000 -36.500000000 1.500000000 3.500000000 -36.500000000 1.500000000 4.500000000 -36.500000000 1.500000000 5.500000000 -36.500000000 1.500000000 6.500000000 -36.500000000 1.500000000 7.500000000 -36.500000000 1.500000000 8.500000000 -36.500000000 1.500000000 9.500000000 -36.500000000 1.500000000 10.500000000 -36.500000000 1.500000000 11.500000000 -36.500000000 1.500000000 12.500000000 -36.500000000 1.500000000 13.500000000 -36.500000000 1.500000000 14.500000000 -36.500000000 1.500000000 15.500000000 -36.500000000 1.500000000 16.500000000 -36.500000000 1.500000000 17.500000000 -36.500000000 1.500000000 18.500000000 -36.500000000 1.500000000 19.500000000 -36.500000000 1.500000000 20.500000000 -36.500000000 1.500000000 21.500000000 -36.500000000 1.500000000 22.500000000 -36.500000000 1.500000000 23.500000000 -36.500000000 1.500000000 24.500000000 -36.500000000 1.500000000 25.499996185 -36.499996185 1.500000000 26.499954224 -36.499954224 1.500000000 27.499591827 -36.499591827 1.500000000 28.497470856 -36.497467041 1.500000000 29.488407135 -36.488403320 1.500000000 30.458978653 -36.458980560 1.500000000 31.384418488 -36.384422302 1.500000000 32.233222961 -36.233222961 1.500000000 32.981101990 -35.981101990 1.500000000 -35.167964935 -35.167964935 1.500000000 -34.622871399 -35.622871399 1.500000000 33.622871399 -35.622871399 1.500000000 34.167964935 -35.167964935 1.500000000 -35.981101990 -33.981101990 1.500000000 -35.622871399 -34.622871399 1.500000000 34.622871399 -34.622871399 1.500000000 34.981101990 -33.981101990 1.500000000 -36.233222961 -33.233222961 1.500000000 35.233222961 -33.233226776 1.500000000 -36.384418488 -32.384422302 1.500000000 35.384418488 -32.384422302 1.500000000 -36.458976746 -31.458978653 1.500000000 35.458980560 -31.458978653 1.500000000 -36.488403320 -30.488407135 1.500000000 35.488403320 -30.488407135 1.500000000 -36.497467041 -29.497472763 1.500000000 35.497474670 -29.497472763 1.500000000 -36.499591827 -28.499593735 1.500000000 35.499591827 -28.499593735 1.500000000 -36.499954224 -27.499954224 1.500000000 35.499954224 -27.499954224 1.500000000 -36.499996185 -26.499996185 1.500000000 35.499996185 -26.499996185 1.500000000 -36.500000000 -25.500000000 1.500000000 35.500000000 -25.500000000 1.500000000 -36.500000000 -24.500000000 1.500000000 35.500000000 -24.500000000 1.500000000 -36.500000000 -23.500000000 1.500000000 35.500000000 -23.500000000 1.500000000 -36.500000000 -22.500000000 1.500000000 35.500000000 -22.500000000 1.500000000 -36.500000000 -21.500000000 1.500000000 35.500000000 -21.500000000 1.500000000 -36.500000000 -20.500000000 1.500000000 35.500000000 -20.500000000 1.500000000 -36.500000000 -19.500000000 1.500000000 35.500000000 -19.500000000 1.500000000 -36.500000000 -18.500000000 1.500000000 35.500000000 -18.500000000 1.500000000 -36.500000000 -17.500000000 1.500000000 35.500000000 -17.500000000 1.500000000 -36.500000000 -16.500000000 1.500000000 35.500000000 -16.500000000 1.500000000 -36.500000000 -15.500000000 1.500000000 35.500000000 -15.500000000 1.500000000 -36.500000000 -14.500000000 1.500000000 35.500000000 -14.500000000 1.500000000 -36.500000000 -13.500000000 1.500000000 35.500000000 -13.500000000 1.500000000 -36.500000000 -12.500000000 1.500000000 35.500000000 -12.500000000 1.500000000 -36.500000000 -11.500000000 1.500000000 35.500000000 -11.500000000 1.500000000 -36.500000000 -10.500000000 1.500000000 35.500000000 -10.500000000 1.500000000 -36.500000000 -9.500000000 1.500000000 35.500000000 -9.500000000 1.500000000 -36.500000000 -8.500000000 1.500000000 35.500000000 -8.500000000 1.500000000 -36.500000000 -7.500000000 1.500000000 35.500000000 -7.500000000 1.500000000 -36.500000000 -6.500000000 1.500000000 35.500000000 -6.500000000 1.500000000 -36.500000000 -5.500000000 1.500000000 35.500000000 -5.500000000 1.500000000 -36.500000000 -4.500000000 1.500000000 35.500000000 -4.500000000 1.500000000 -36.500000000 -3.500000000 1.500000000 35.500000000 -3.500000000 1.500000000 -36.500000000 -2.500000000 1.500000000 35.500000000 -2.500000000 1.500000000 -36.500000000 -1.500000000 1.500000000 35.500000000 -1.500000000 1.500000000 -36.500000000 -0.500000000 1.500000000 35.500000000 -0.500000000 1.500000000 -36.500000000 0.500000000 1.500000000 35.500000000 0.500000000 1.500000000 -36.500000000 1.500000000 1.500000000 35.500000000 1.500000000 1.500000000 -36.500000000 2.500000000 1.500000000 35.500000000 2.500000000 1.500000000 -36.500000000 3.500000000 1.500000000 35.500000000 3.500000000 1.500000000 -36.500000000 4.500000000 1.500000000 35.500000000 4.500000000 1.500000000 -36.500000000 5.500000000 1.500000000 35.500000000 5.500000000 1.500000000 -36.500000000 6.500000000 1.500000000 35.500000000 6.500000000 1.500000000 -36.500000000 7.500000000 1.500000000 35.500000000 7.500000000 1.500000000 -36.500000000 8.500000000 1.500000000 35.500000000 8.500000000 1.500000000 -36.500000000 9.500000000 1.500000000 35.500000000 9.500000000 1.500000000 -36.500000000 10.500000000 1.500000000 35.500000000 10.500000000 1.500000000 -36.500000000 11.500000000 1.500000000 35.500000000 11.500000000 1.500000000 -36.500000000 12.500000000 1.500000000 35.500000000 12.500000000 1.500000000 -36.500000000 13.500000000 1.500000000 35.500000000 13.500000000 1.500000000 -36.500000000 14.500000000 1.500000000 35.500000000 14.500000000 1.500000000 -36.500000000 15.500000000 1.500000000 35.500000000 15.500000000 1.500000000 -36.500000000 16.500000000 1.500000000 35.500000000 16.500000000 1.500000000 -36.500000000 17.500000000 1.500000000 35.500000000 17.500000000 1.500000000 -36.500000000 18.500000000 1.500000000 35.500000000 18.500000000 1.500000000 -36.500000000 19.500000000 1.500000000 35.500000000 19.500000000 1.500000000 -36.500000000 20.500000000 1.500000000 35.500000000 20.500000000 1.500000000 -36.500000000 21.500000000 1.500000000 35.500000000 21.500000000 1.500000000 -36.500000000 22.500000000 1.500000000 35.500000000 22.500000000 1.500000000 -36.500000000 23.500000000 1.500000000 35.500000000 23.500000000 1.500000000 -36.500000000 24.500000000 1.500000000 35.500000000 24.500000000 1.500000000 -36.499996185 25.499996185 1.500000000 35.499996185 25.499996185 1.500000000 -36.499954224 26.499954224 1.500000000 35.499954224 26.499954224 1.500000000 -36.499591827 27.499591827 1.500000000 35.499591827 27.499591827 1.500000000 -36.497474670 28.497470856 1.500000000 35.497467041 28.497470856 1.500000000 -36.488403320 29.488407135 1.500000000 35.488403320 29.488407135 1.500000000 -36.458980560 30.458978653 1.500000000 35.458980560 30.458978653 1.500000000 -36.384422302 31.384418488 1.500000000 35.384422302 31.384418488 1.500000000 -36.233222961 32.233222961 1.500000000 35.233222961 32.233222961 1.500000000 -35.981101990 32.981101990 1.500000000 -35.622871399 33.622871399 1.500000000 34.622871399 33.622871399 1.500000000 34.981101990 32.981101990 1.500000000 -35.167964935 34.167964935 1.500000000 -34.622871399 34.622871399 1.500000000 33.622871399 34.622871399 1.500000000 34.167964935 34.167964935 1.500000000 -33.981101990 34.981101990 1.500000000 -33.233222961 35.233222961 1.500000000 -32.384422302 35.384418488 1.500000000 -31.458978653 35.458976746 1.500000000 -30.488407135 35.488403320 1.500000000 -29.497472763 35.497467041 1.500000000 -28.499593735 35.499591827 1.500000000 -27.499954224 35.499954224 1.500000000 -26.499996185 35.499996185 1.500000000 -25.500000000 35.500000000 1.500000000 -24.500000000 35.500000000 1.500000000 -23.500000000 35.500000000 1.500000000 -22.500000000 35.500000000 1.500000000 -21.500000000 35.500000000 1.500000000 -20.500000000 35.500000000 1.500000000 -19.500000000 35.500000000 1.500000000 -18.500000000 35.500000000 1.500000000 -17.500000000 35.500000000 1.500000000 -16.500000000 35.500000000 1.500000000 -15.500000000 35.500000000 1.500000000 -14.500000000 35.500000000 1.500000000 -13.500000000 35.500000000 1.500000000 -12.500000000 35.500000000 1.500000000 -11.500000000 35.500000000 1.500000000 -10.500000000 35.500000000 1.500000000 -9.500000000 35.500000000 1.500000000 -8.500000000 35.500000000 1.500000000 -7.500000000 35.500000000 1.500000000 -6.500000000 35.500000000 1.500000000 -5.500000000 35.500000000 1.500000000 -4.500000000 35.500000000 1.500000000 -3.500000000 35.500000000 1.500000000 -2.500000000 35.500000000 1.500000000 -1.500000000 35.500000000 1.500000000 -0.500000000 35.500000000 1.500000000 0.500000000 35.500000000 1.500000000 1.500000000 35.500000000 1.500000000 2.500000000 35.500000000 1.500000000 3.500000000 35.500000000 1.500000000 4.500000000 35.500000000 1.500000000 5.500000000 35.500000000 1.500000000 6.500000000 35.500000000 1.500000000 7.500000000 35.500000000 1.500000000 8.500000000 35.500000000 1.500000000 9.500000000 35.500000000 1.500000000 10.500000000 35.500000000 1.500000000 11.500000000 35.500000000 1.500000000 12.500000000 35.500000000 1.500000000 13.500000000 35.500000000 1.500000000 14.500000000 35.500000000 1.500000000 15.500000000 35.500000000 1.500000000 16.500000000 35.500000000 1.500000000 17.500000000 35.500000000 1.500000000 18.500000000 35.500000000 1.500000000 19.500000000 35.500000000 1.500000000 20.500000000 35.500000000 1.500000000 21.500000000 35.500000000 1.500000000 22.500000000 35.500000000 1.500000000 23.500000000 35.500000000 1.500000000 24.500000000 35.500000000 1.500000000 25.499996185 35.499996185 1.500000000 26.499954224 35.499954224 1.500000000 27.499591827 35.499591827 1.500000000 28.497470856 35.497474670 1.500000000 29.488407135 35.488403320 1.500000000 30.458978653 35.458980560 1.500000000 31.384418488 35.384422302 1.500000000 32.233222961 35.233222961 1.500000000 32.981101990 34.981101990 1.500000000 -33.981101990 -35.981101990 2.500000000 -33.233226776 -36.233222961 2.500000000 -32.384422302 -36.384418488 2.500000000 -31.458978653 -36.458980560 2.500000000 -30.488407135 -36.488403320 2.500000000 -29.497472763 -36.497474670 2.500000000 -28.499593735 -36.499591827 2.500000000 -27.499954224 -36.499954224 2.500000000 -26.499996185 -36.499996185 2.500000000 -25.500000000 -36.500000000 2.500000000 -24.500000000 -36.500000000 2.500000000 -23.500000000 -36.500000000 2.500000000 -22.500000000 -36.500000000 2.500000000 -21.500000000 -36.500000000 2.500000000 -20.500000000 -36.500000000 2.500000000 -19.500000000 -36.500000000 2.500000000 -18.500000000 -36.500000000 2.500000000 -17.500000000 -36.500000000 2.500000000 -16.500000000 -36.500000000 2.500000000 -15.500000000 -36.500000000 2.500000000 -14.500000000 -36.500000000 2.500000000 -13.500000000 -36.500000000 2.500000000 -12.500000000 -36.500000000 2.500000000 -11.500000000 -36.500000000 2.500000000 -10.500000000 -36.500000000 2.500000000 -9.500000000 -36.500000000 2.500000000 -8.500000000 -36.500000000 2.500000000 -7.500000000 -36.500000000 2.500000000 -6.500000000 -36.500000000 2.500000000 -5.500000000 -36.500000000 2.500000000 -4.500000000 -36.500000000 2.500000000 -3.500000000 -36.500000000 2.500000000 -2.500000000 -36.500000000 2.500000000 -1.500000000 -36.500000000 2.500000000 -0.500000000 -36.500000000 2.500000000 0.500000000 -36.500000000 2.500000000 1.500000000 -36.500000000 2.500000000 2.500000000 -36.500000000 2.500000000 3.500000000 -36.500000000 2.500000000 4.500000000 -36.500000000 2.500000000 5.500000000 -36.500000000 2.500000000 6.500000000 -36.500000000 2.500000000 7.500000000 -36.500000000 2.500000000 8.500000000 -36.500000000 2.500000000 9.500000000 -36.500000000 2.500000000 10.500000000 -36.500000000 2.500000000 11.500000000 -36.500000000 2.500000000 12.500000000 -36.500000000 2.500000000 13.500000000 -36.500000000 2.500000000 14.500000000 -36.500000000 2.500000000 15.500000000 -36.500000000 2.500000000 16.500000000 -36.500000000 2.500000000 17.500000000 -36.500000000 2.500000000 18.500000000 -36.500000000 2.500000000 19.500000000 -36.500000000 2.500000000 20.500000000 -36.500000000 2.500000000 21.500000000 -36.500000000 2.500000000 22.500000000 -36.500000000 2.500000000 23.500000000 -36.500000000 2.500000000 24.500000000 -36.500000000 2.500000000 25.499996185 -36.499996185 2.500000000 26.499954224 -36.499954224 2.500000000 27.499591827 -36.499591827 2.500000000 28.497470856 -36.497467041 2.500000000 29.488407135 -36.488403320 2.500000000 30.458978653 -36.458980560 2.500000000 31.384418488 -36.384422302 2.500000000 32.233222961 -36.233222961 2.500000000 32.981101990 -35.981101990 2.500000000 -35.167964935 -35.167964935 2.500000000 -34.622871399 -35.622871399 2.500000000 33.622871399 -35.622871399 2.500000000 34.167964935 -35.167964935 2.500000000 -35.981101990 -33.981101990 2.500000000 -35.622871399 -34.622871399 2.500000000 34.622871399 -34.622871399 2.500000000 34.981101990 -33.981101990 2.500000000 -36.233222961 -33.233222961 2.500000000 35.233222961 -33.233226776 2.500000000 -36.384418488 -32.384422302 2.500000000 35.384418488 -32.384422302 2.500000000 -36.458976746 -31.458978653 2.500000000 35.458980560 -31.458978653 2.500000000 -36.488403320 -30.488407135 2.500000000 35.488403320 -30.488407135 2.500000000 -36.497467041 -29.497472763 2.500000000 35.497474670 -29.497472763 2.500000000 -36.499591827 -28.499593735 2.500000000 35.499591827 -28.499593735 2.500000000 -36.499954224 -27.499954224 2.500000000 35.499954224 -27.499954224 2.500000000 -36.499996185 -26.499996185 2.500000000 35.499996185 -26.499996185 2.500000000 -36.500000000 -25.500000000 2.500000000 35.500000000 -25.500000000 2.500000000 -36.500000000 -24.500000000 2.500000000 35.500000000 -24.500000000 2.500000000 -36.500000000 -23.500000000 2.500000000 35.500000000 -23.500000000 2.500000000 -36.500000000 -22.500000000 2.500000000 35.500000000 -22.500000000 2.500000000 -36.500000000 -21.500000000 2.500000000 35.500000000 -21.500000000 2.500000000 -36.500000000 -20.500000000 2.500000000 35.500000000 -20.500000000 2.500000000 -36.500000000 -19.500000000 2.500000000 35.500000000 -19.500000000 2.500000000 -36.500000000 -18.500000000 2.500000000 35.500000000 -18.500000000 2.500000000 -36.500000000 -17.500000000 2.500000000 35.500000000 -17.500000000 2.500000000 -36.500000000 -16.500000000 2.500000000 35.500000000 -16.500000000 2.500000000 -36.500000000 -15.500000000 2.500000000 35.500000000 -15.500000000 2.500000000 -36.500000000 -14.500000000 2.500000000 35.500000000 -14.500000000 2.500000000 -36.500000000 -13.500000000 2.500000000 35.500000000 -13.500000000 2.500000000 -36.500000000 -12.500000000 2.500000000 35.500000000 -12.500000000 2.500000000 -36.500000000 -11.500000000 2.500000000 35.500000000 -11.500000000 2.500000000 -36.500000000 -10.500000000 2.500000000 35.500000000 -10.500000000 2.500000000 -36.500000000 -9.500000000 2.500000000 35.500000000 -9.500000000 2.500000000 -36.500000000 -8.500000000 2.500000000 35.500000000 -8.500000000 2.500000000 -36.500000000 -7.500000000 2.500000000 35.500000000 -7.500000000 2.500000000 -36.500000000 -6.500000000 2.500000000 35.500000000 -6.500000000 2.500000000 -36.500000000 -5.500000000 2.500000000 35.500000000 -5.500000000 2.500000000 -36.500000000 -4.500000000 2.500000000 35.500000000 -4.500000000 2.500000000 -36.500000000 -3.500000000 2.500000000 35.500000000 -3.500000000 2.500000000 -36.500000000 -2.500000000 2.500000000 35.500000000 -2.500000000 2.500000000 -36.500000000 -1.500000000 2.500000000 35.500000000 -1.500000000 2.500000000 -36.500000000 -0.500000000 2.500000000 35.500000000 -0.500000000 2.500000000 -36.500000000 0.500000000 2.500000000 35.500000000 0.500000000 2.500000000 -36.500000000 1.500000000 2.500000000 35.500000000 1.500000000 2.500000000 -36.500000000 2.500000000 2.500000000 35.500000000 2.500000000 2.500000000 -36.500000000 3.500000000 2.500000000 35.500000000 3.500000000 2.500000000 -36.500000000 4.500000000 2.500000000 35.500000000 4.500000000 2.500000000 -36.500000000 5.500000000 2.500000000 35.500000000 5.500000000 2.500000000 -36.500000000 6.500000000 2.500000000 35.500000000 6.500000000 2.500000000 -36.500000000 7.500000000 2.500000000 35.500000000 7.500000000 2.500000000 -36.500000000 8.500000000 2.500000000 35.500000000 8.500000000 2.500000000 -36.500000000 9.500000000 2.500000000 35.500000000 9.500000000 2.500000000 -36.500000000 10.500000000 2.500000000 35.500000000 10.500000000 2.500000000 -36.500000000 11.500000000 2.500000000 35.500000000 11.500000000 2.500000000 -36.500000000 12.500000000 2.500000000 35.500000000 12.500000000 2.500000000 -36.500000000 13.500000000 2.500000000 35.500000000 13.500000000 2.500000000 -36.500000000 14.500000000 2.500000000 35.500000000 14.500000000 2.500000000 -36.500000000 15.500000000 2.500000000 35.500000000 15.500000000 2.500000000 -36.500000000 16.500000000 2.500000000 35.500000000 16.500000000 2.500000000 -36.500000000 17.500000000 2.500000000 35.500000000 17.500000000 2.500000000 -36.500000000 18.500000000 2.500000000 35.500000000 18.500000000 2.500000000 -36.500000000 19.500000000 2.500000000 35.500000000 19.500000000 2.500000000 -36.500000000 20.500000000 2.500000000 35.500000000 20.500000000 2.500000000 -36.500000000 21.500000000 2.500000000 35.500000000 21.500000000 2.500000000 -36.500000000 22.500000000 2.500000000 35.500000000 22.500000000 2.500000000 -36.500000000 23.500000000 2.500000000 35.500000000 23.500000000 2.500000000 -36.500000000 24.500000000 2.500000000 35.500000000 24.500000000 2.500000000 -36.499996185 25.499996185 2.500000000 35.499996185 25.499996185 2.500000000 -36.499954224 26.499954224 2.500000000 35.499954224 26.499954224 2.500000000 -36.499591827 27.499591827 2.500000000 35.499591827 27.499591827 2.500000000 -36.497474670 28.497470856 2.500000000 35.497467041 28.497470856 2.500000000 -36.488403320 29.488407135 2.500000000 35.488403320 29.488407135 2.500000000 -36.458980560 30.458978653 2.500000000 35.458980560 30.458978653 2.500000000 -36.384422302 31.384418488 2.500000000 35.384422302 31.384418488 2.500000000 -36.233222961 32.233222961 2.500000000 35.233222961 32.233222961 2.500000000 -35.981101990 32.981101990 2.500000000 -35.622871399 33.622871399 2.500000000 34.622871399 33.622871399 2.500000000 34.981101990 32.981101990 2.500000000 -35.167964935 34.167964935 2.500000000 -34.622871399 34.622871399 2.500000000 33.622871399 34.622871399 2.500000000 34.167964935 34.167964935 2.500000000 -33.981101990 34.981101990 2.500000000 -33.233222961 35.233222961 2.500000000 -32.384422302 35.384418488 2.500000000 -31.458978653 35.458976746 2.500000000 -30.488407135 35.488403320 2.500000000 -29.497472763 35.497467041 2.500000000 -28.499593735 35.499591827 2.500000000 -27.499954224 35.499954224 2.500000000 -26.499996185 35.499996185 2.500000000 -25.500000000 35.500000000 2.500000000 -24.500000000 35.500000000 2.500000000 -23.500000000 35.500000000 2.500000000 -22.500000000 35.500000000 2.500000000 -21.500000000 35.500000000 2.500000000 -20.500000000 35.500000000 2.500000000 -19.500000000 35.500000000 2.500000000 -18.500000000 35.500000000 2.500000000 -17.500000000 35.500000000 2.500000000 -16.500000000 35.500000000 2.500000000 -15.500000000 35.500000000 2.500000000 -14.500000000 35.500000000 2.500000000 -13.500000000 35.500000000 2.500000000 -12.500000000 35.500000000 2.500000000 -11.500000000 35.500000000 2.500000000 -10.500000000 35.500000000 2.500000000 -9.500000000 35.500000000 2.500000000 -8.500000000 35.500000000 2.500000000 -7.500000000 35.500000000 2.500000000 -6.500000000 35.500000000 2.500000000 -5.500000000 35.500000000 2.500000000 -4.500000000 35.500000000 2.500000000 -3.500000000 35.500000000 2.500000000 -2.500000000 35.500000000 2.500000000 -1.500000000 35.500000000 2.500000000 -0.500000000 35.500000000 2.500000000 0.500000000 35.500000000 2.500000000 1.500000000 35.500000000 2.500000000 2.500000000 35.500000000 2.500000000 3.500000000 35.500000000 2.500000000 4.500000000 35.500000000 2.500000000 5.500000000 35.500000000 2.500000000 6.500000000 35.500000000 2.500000000 7.500000000 35.500000000 2.500000000 8.500000000 35.500000000 2.500000000 9.500000000 35.500000000 2.500000000 10.500000000 35.500000000 2.500000000 11.500000000 35.500000000 2.500000000 12.500000000 35.500000000 2.500000000 13.500000000 35.500000000 2.500000000 14.500000000 35.500000000 2.500000000 15.500000000 35.500000000 2.500000000 16.500000000 35.500000000 2.500000000 17.500000000 35.500000000 2.500000000 18.500000000 35.500000000 2.500000000 19.500000000 35.500000000 2.500000000 20.500000000 35.500000000 2.500000000 21.500000000 35.500000000 2.500000000 22.500000000 35.500000000 2.500000000 23.500000000 35.500000000 2.500000000 24.500000000 35.500000000 2.500000000 25.499996185 35.499996185 2.500000000 26.499954224 35.499954224 2.500000000 27.499591827 35.499591827 2.500000000 28.497470856 35.497474670 2.500000000 29.488407135 35.488403320 2.500000000 30.458978653 35.458980560 2.500000000 31.384418488 35.384422302 2.500000000 32.233222961 35.233222961 2.500000000 32.981101990 34.981101990 2.500000000 -33.981101990 -35.981101990 3.500000000 -33.233226776 -36.233222961 3.500000000 -32.384422302 -36.384418488 3.500000000 -31.458978653 -36.458980560 3.500000000 -30.488407135 -36.488403320 3.500000000 -29.497472763 -36.497474670 3.500000000 -28.499593735 -36.499591827 3.500000000 -27.499954224 -36.499954224 3.500000000 -26.499996185 -36.499996185 3.500000000 -25.500000000 -36.500000000 3.500000000 -24.500000000 -36.500000000 3.500000000 -23.500000000 -36.500000000 3.500000000 -22.500000000 -36.500000000 3.500000000 -21.500000000 -36.500000000 3.500000000 -20.500000000 -36.500000000 3.500000000 -19.500000000 -36.500000000 3.500000000 -18.500000000 -36.500000000 3.500000000 -17.500000000 -36.500000000 3.500000000 -16.500000000 -36.500000000 3.500000000 -15.500000000 -36.500000000 3.500000000 -14.500000000 -36.500000000 3.500000000 -13.500000000 -36.500000000 3.500000000 -12.500000000 -36.500000000 3.500000000 -11.500000000 -36.500000000 3.500000000 -10.500000000 -36.500000000 3.500000000 -9.500000000 -36.500000000 3.500000000 -8.500000000 -36.500000000 3.500000000 -7.500000000 -36.500000000 3.500000000 -6.500000000 -36.500000000 3.500000000 -5.500000000 -36.500000000 3.500000000 -4.500000000 -36.500000000 3.500000000 -3.500000000 -36.500000000 3.500000000 -2.500000000 -36.500000000 3.500000000 -1.500000000 -36.500000000 3.500000000 -0.500000000 -36.500000000 3.500000000 0.500000000 -36.500000000 3.500000000 1.500000000 -36.500000000 3.500000000 2.500000000 -36.500000000 3.500000000 3.500000000 -36.500000000 3.500000000 4.500000000 -36.500000000 3.500000000 5.500000000 -36.500000000 3.500000000 6.500000000 -36.500000000 3.500000000 7.500000000 -36.500000000 3.500000000 8.500000000 -36.500000000 3.500000000 9.500000000 -36.500000000 3.500000000 10.500000000 -36.500000000 3.500000000 11.500000000 -36.500000000 3.500000000 12.500000000 -36.500000000 3.500000000 13.500000000 -36.500000000 3.500000000 14.500000000 -36.500000000 3.500000000 15.500000000 -36.500000000 3.500000000 16.500000000 -36.500000000 3.500000000 17.500000000 -36.500000000 3.500000000 18.500000000 -36.500000000 3.500000000 19.500000000 -36.500000000 3.500000000 20.500000000 -36.500000000 3.500000000 21.500000000 -36.500000000 3.500000000 22.500000000 -36.500000000 3.500000000 23.500000000 -36.500000000 3.500000000 24.500000000 -36.500000000 3.500000000 25.499996185 -36.499996185 3.500000000 26.499954224 -36.499954224 3.500000000 27.499591827 -36.499591827 3.500000000 28.497470856 -36.497467041 3.500000000 29.488407135 -36.488403320 3.500000000 30.458978653 -36.458980560 3.500000000 31.384418488 -36.384422302 3.500000000 32.233222961 -36.233222961 3.500000000 32.981101990 -35.981101990 3.500000000 -35.167964935 -35.167964935 3.500000000 -34.622871399 -35.622871399 3.500000000 33.622871399 -35.622871399 3.500000000 34.167964935 -35.167964935 3.500000000 -35.981101990 -33.981101990 3.500000000 -35.622871399 -34.622871399 3.500000000 34.622871399 -34.622871399 3.500000000 34.981101990 -33.981101990 3.500000000 -36.233222961 -33.233222961 3.500000000 35.233222961 -33.233226776 3.500000000 -36.384418488 -32.384422302 3.500000000 35.384418488 -32.384422302 3.500000000 -36.458976746 -31.458978653 3.500000000 35.458980560 -31.458978653 3.500000000 -36.488403320 -30.488407135 3.500000000 35.488403320 -30.488407135 3.500000000 -36.497467041 -29.497472763 3.500000000 35.497474670 -29.497472763 3.500000000 -36.499591827 -28.499593735 3.500000000 35.499591827 -28.499593735 3.500000000 -36.499954224 -27.499954224 3.500000000 35.499954224 -27.499954224 3.500000000 -36.499996185 -26.499996185 3.500000000 35.499996185 -26.499996185 3.500000000 -36.500000000 -25.500000000 3.500000000 35.500000000 -25.500000000 3.500000000 -36.500000000 -24.500000000 3.500000000 35.500000000 -24.500000000 3.500000000 -36.500000000 -23.500000000 3.500000000 35.500000000 -23.500000000 3.500000000 -36.500000000 -22.500000000 3.500000000 35.500000000 -22.500000000 3.500000000 -36.500000000 -21.500000000 3.500000000 35.500000000 -21.500000000 3.500000000 -36.500000000 -20.500000000 3.500000000 35.500000000 -20.500000000 3.500000000 -36.500000000 -19.500000000 3.500000000 35.500000000 -19.500000000 3.500000000 -36.500000000 -18.500000000 3.500000000 35.500000000 -18.500000000 3.500000000 -36.500000000 -17.500000000 3.500000000 35.500000000 -17.500000000 3.500000000 -36.500000000 -16.500000000 3.500000000 35.500000000 -16.500000000 3.500000000 -36.500000000 -15.500000000 3.500000000 35.500000000 -15.500000000 3.500000000 -36.500000000 -14.500000000 3.500000000 35.500000000 -14.500000000 3.500000000 -36.500000000 -13.500000000 3.500000000 35.500000000 -13.500000000 3.500000000 -36.500000000 -12.500000000 3.500000000 35.500000000 -12.500000000 3.500000000 -36.500000000 -11.500000000 3.500000000 35.500000000 -11.500000000 3.500000000 -36.500000000 -10.500000000 3.500000000 35.500000000 -10.500000000 3.500000000 -36.500000000 -9.500000000 3.500000000 35.500000000 -9.500000000 3.500000000 -36.500000000 -8.500000000 3.500000000 35.500000000 -8.500000000 3.500000000 -36.500000000 -7.500000000 3.500000000 35.500000000 -7.500000000 3.500000000 -36.500000000 -6.500000000 3.500000000 35.500000000 -6.500000000 3.500000000 -36.500000000 -5.500000000 3.500000000 35.500000000 -5.500000000 3.500000000 -36.500000000 -4.500000000 3.500000000 35.500000000 -4.500000000 3.500000000 -36.500000000 -3.500000000 3.500000000 35.500000000 -3.500000000 3.500000000 -36.500000000 -2.500000000 3.500000000 35.500000000 -2.500000000 3.500000000 -36.500000000 -1.500000000 3.500000000 35.500000000 -1.500000000 3.500000000 -36.500000000 -0.500000000 3.500000000 35.500000000 -0.500000000 3.500000000 -36.500000000 0.500000000 3.500000000 35.500000000 0.500000000 3.500000000 -36.500000000 1.500000000 3.500000000 35.500000000 1.500000000 3.500000000 -36.500000000 2.500000000 3.500000000 35.500000000 2.500000000 3.500000000 -36.500000000 3.500000000 3.500000000 35.500000000 3.500000000 3.500000000 -36.500000000 4.500000000 3.500000000 35.500000000 4.500000000 3.500000000 -36.500000000 5.500000000 3.500000000 35.500000000 5.500000000 3.500000000 -36.500000000 6.500000000 3.500000000 35.500000000 6.500000000 3.500000000 -36.500000000 7.500000000 3.500000000 35.500000000 7.500000000 3.500000000 -36.500000000 8.500000000 3.500000000 35.500000000 8.500000000 3.500000000 -36.500000000 9.500000000 3.500000000 35.500000000 9.500000000 3.500000000 -36.500000000 10.500000000 3.500000000 35.500000000 10.500000000 3.500000000 -36.500000000 11.500000000 3.500000000 35.500000000 11.500000000 3.500000000 -36.500000000 12.500000000 3.500000000 35.500000000 12.500000000 3.500000000 -36.500000000 13.500000000 3.500000000 35.500000000 13.500000000 3.500000000 -36.500000000 14.500000000 3.500000000 35.500000000 14.500000000 3.500000000 -36.500000000 15.500000000 3.500000000 35.500000000 15.500000000 3.500000000 -36.500000000 16.500000000 3.500000000 35.500000000 16.500000000 3.500000000 -36.500000000 17.500000000 3.500000000 35.500000000 17.500000000 3.500000000 -36.500000000 18.500000000 3.500000000 35.500000000 18.500000000 3.500000000 -36.500000000 19.500000000 3.500000000 35.500000000 19.500000000 3.500000000 -36.500000000 20.500000000 3.500000000 35.500000000 20.500000000 3.500000000 -36.500000000 21.500000000 3.500000000 35.500000000 21.500000000 3.500000000 -36.500000000 22.500000000 3.500000000 35.500000000 22.500000000 3.500000000 -36.500000000 23.500000000 3.500000000 35.500000000 23.500000000 3.500000000 -36.500000000 24.500000000 3.500000000 35.500000000 24.500000000 3.500000000 -36.499996185 25.499996185 3.500000000 35.499996185 25.499996185 3.500000000 -36.499954224 26.499954224 3.500000000 35.499954224 26.499954224 3.500000000 -36.499591827 27.499591827 3.500000000 35.499591827 27.499591827 3.500000000 -36.497474670 28.497470856 3.500000000 35.497467041 28.497470856 3.500000000 -36.488403320 29.488407135 3.500000000 35.488403320 29.488407135 3.500000000 -36.458980560 30.458978653 3.500000000 35.458980560 30.458978653 3.500000000 -36.384422302 31.384418488 3.500000000 35.384422302 31.384418488 3.500000000 -36.233222961 32.233222961 3.500000000 35.233222961 32.233222961 3.500000000 -35.981101990 32.981101990 3.500000000 -35.622871399 33.622871399 3.500000000 34.622871399 33.622871399 3.500000000 34.981101990 32.981101990 3.500000000 -35.167964935 34.167964935 3.500000000 -34.622871399 34.622871399 3.500000000 33.622871399 34.622871399 3.500000000 34.167964935 34.167964935 3.500000000 -33.981101990 34.981101990 3.500000000 -33.233222961 35.233222961 3.500000000 -32.384422302 35.384418488 3.500000000 -31.458978653 35.458976746 3.500000000 -30.488407135 35.488403320 3.500000000 -29.497472763 35.497467041 3.500000000 -28.499593735 35.499591827 3.500000000 -27.499954224 35.499954224 3.500000000 -26.499996185 35.499996185 3.500000000 -25.500000000 35.500000000 3.500000000 -24.500000000 35.500000000 3.500000000 -23.500000000 35.500000000 3.500000000 -22.500000000 35.500000000 3.500000000 -21.500000000 35.500000000 3.500000000 -20.500000000 35.500000000 3.500000000 -19.500000000 35.500000000 3.500000000 -18.500000000 35.500000000 3.500000000 -17.500000000 35.500000000 3.500000000 -16.500000000 35.500000000 3.500000000 -15.500000000 35.500000000 3.500000000 -14.500000000 35.500000000 3.500000000 -13.500000000 35.500000000 3.500000000 -12.500000000 35.500000000 3.500000000 -11.500000000 35.500000000 3.500000000 -10.500000000 35.500000000 3.500000000 -9.500000000 35.500000000 3.500000000 -8.500000000 35.500000000 3.500000000 -7.500000000 35.500000000 3.500000000 -6.500000000 35.500000000 3.500000000 -5.500000000 35.500000000 3.500000000 -4.500000000 35.500000000 3.500000000 -3.500000000 35.500000000 3.500000000 -2.500000000 35.500000000 3.500000000 -1.500000000 35.500000000 3.500000000 -0.500000000 35.500000000 3.500000000 0.500000000 35.500000000 3.500000000 1.500000000 35.500000000 3.500000000 2.500000000 35.500000000 3.500000000 3.500000000 35.500000000 3.500000000 4.500000000 35.500000000 3.500000000 5.500000000 35.500000000 3.500000000 6.500000000 35.500000000 3.500000000 7.500000000 35.500000000 3.500000000 8.500000000 35.500000000 3.500000000 9.500000000 35.500000000 3.500000000 10.500000000 35.500000000 3.500000000 11.500000000 35.500000000 3.500000000 12.500000000 35.500000000 3.500000000 13.500000000 35.500000000 3.500000000 14.500000000 35.500000000 3.500000000 15.500000000 35.500000000 3.500000000 16.500000000 35.500000000 3.500000000 17.500000000 35.500000000 3.500000000 18.500000000 35.500000000 3.500000000 19.500000000 35.500000000 3.500000000 20.500000000 35.500000000 3.500000000 21.500000000 35.500000000 3.500000000 22.500000000 35.500000000 3.500000000 23.500000000 35.500000000 3.500000000 24.500000000 35.500000000 3.500000000 25.499996185 35.499996185 3.500000000 26.499954224 35.499954224 3.500000000 27.499591827 35.499591827 3.500000000 28.497470856 35.497474670 3.500000000 29.488407135 35.488403320 3.500000000 30.458978653 35.458980560 3.500000000 31.384418488 35.384422302 3.500000000 32.233222961 35.233222961 3.500000000 32.981101990 34.981101990 3.500000000 -33.981101990 -35.981101990 4.500000000 -33.233226776 -36.233222961 4.500000000 -32.384422302 -36.384418488 4.500000000 -31.458978653 -36.458980560 4.500000000 -30.488407135 -36.488403320 4.500000000 -29.497472763 -36.497474670 4.500000000 -28.499593735 -36.499591827 4.500000000 -27.499954224 -36.499954224 4.500000000 -26.499996185 -36.499996185 4.500000000 -25.500000000 -36.500000000 4.500000000 -24.500000000 -36.500000000 4.500000000 -23.500000000 -36.500000000 4.500000000 -22.500000000 -36.500000000 4.500000000 -21.500000000 -36.500000000 4.500000000 -20.500000000 -36.500000000 4.500000000 -19.500000000 -36.500000000 4.500000000 -18.500000000 -36.500000000 4.500000000 -17.500000000 -36.500000000 4.500000000 -16.500000000 -36.500000000 4.500000000 -15.500000000 -36.500000000 4.500000000 -14.500000000 -36.500000000 4.500000000 -13.500000000 -36.500000000 4.500000000 -12.500000000 -36.500000000 4.500000000 -11.500000000 -36.500000000 4.500000000 -10.500000000 -36.500000000 4.500000000 -9.500000000 -36.500000000 4.500000000 -8.500000000 -36.500000000 4.500000000 -7.500000000 -36.500000000 4.500000000 -6.500000000 -36.500000000 4.500000000 -5.500000000 -36.500000000 4.500000000 -4.500000000 -36.500000000 4.500000000 -3.500000000 -36.500000000 4.500000000 -2.500000000 -36.500000000 4.500000000 -1.500000000 -36.500000000 4.500000000 -0.500000000 -36.500000000 4.500000000 0.500000000 -36.500000000 4.500000000 1.500000000 -36.500000000 4.500000000 2.500000000 -36.500000000 4.500000000 3.500000000 -36.500000000 4.500000000 4.500000000 -36.500000000 4.500000000 5.500000000 -36.500000000 4.500000000 6.500000000 -36.500000000 4.500000000 7.500000000 -36.500000000 4.500000000 8.500000000 -36.500000000 4.500000000 9.500000000 -36.500000000 4.500000000 10.500000000 -36.500000000 4.500000000 11.500000000 -36.500000000 4.500000000 12.500000000 -36.500000000 4.500000000 13.500000000 -36.500000000 4.500000000 14.500000000 -36.500000000 4.500000000 15.500000000 -36.500000000 4.500000000 16.500000000 -36.500000000 4.500000000 17.500000000 -36.500000000 4.500000000 18.500000000 -36.500000000 4.500000000 19.500000000 -36.500000000 4.500000000 20.500000000 -36.500000000 4.500000000 21.500000000 -36.500000000 4.500000000 22.500000000 -36.500000000 4.500000000 23.500000000 -36.500000000 4.500000000 24.500000000 -36.500000000 4.500000000 25.499996185 -36.499996185 4.500000000 26.499954224 -36.499954224 4.500000000 27.499591827 -36.499591827 4.500000000 28.497470856 -36.497467041 4.500000000 29.488407135 -36.488403320 4.500000000 30.458978653 -36.458980560 4.500000000 31.384418488 -36.384422302 4.500000000 32.233222961 -36.233222961 4.500000000 32.981101990 -35.981101990 4.500000000 -35.167964935 -35.167964935 4.500000000 -34.622871399 -35.622871399 4.500000000 33.622871399 -35.622871399 4.500000000 34.167964935 -35.167964935 4.500000000 -35.981101990 -33.981101990 4.500000000 -35.622871399 -34.622871399 4.500000000 34.622871399 -34.622871399 4.500000000 34.981101990 -33.981101990 4.500000000 -36.233222961 -33.233222961 4.500000000 35.233222961 -33.233226776 4.500000000 -36.384418488 -32.384422302 4.500000000 35.384418488 -32.384422302 4.500000000 -36.458976746 -31.458978653 4.500000000 35.458980560 -31.458978653 4.500000000 -36.488403320 -30.488407135 4.500000000 35.488403320 -30.488407135 4.500000000 -36.497467041 -29.497472763 4.500000000 35.497474670 -29.497472763 4.500000000 -36.499591827 -28.499593735 4.500000000 35.499591827 -28.499593735 4.500000000 -36.499954224 -27.499954224 4.500000000 35.499954224 -27.499954224 4.500000000 -36.499996185 -26.499996185 4.500000000 35.499996185 -26.499996185 4.500000000 -36.500000000 -25.500000000 4.500000000 35.500000000 -25.500000000 4.500000000 -36.500000000 -24.500000000 4.500000000 35.500000000 -24.500000000 4.500000000 -36.500000000 -23.500000000 4.500000000 35.500000000 -23.500000000 4.500000000 -36.500000000 -22.500000000 4.500000000 35.500000000 -22.500000000 4.500000000 -36.500000000 -21.500000000 4.500000000 35.500000000 -21.500000000 4.500000000 -36.500000000 -20.500000000 4.500000000 35.500000000 -20.500000000 4.500000000 -36.500000000 -19.500000000 4.500000000 35.500000000 -19.500000000 4.500000000 -36.500000000 -18.500000000 4.500000000 35.500000000 -18.500000000 4.500000000 -36.500000000 -17.500000000 4.500000000 35.500000000 -17.500000000 4.500000000 -36.500000000 -16.500000000 4.500000000 35.500000000 -16.500000000 4.500000000 -36.500000000 -15.500000000 4.500000000 35.500000000 -15.500000000 4.500000000 -36.500000000 -14.500000000 4.500000000 35.500000000 -14.500000000 4.500000000 -36.500000000 -13.500000000 4.500000000 35.500000000 -13.500000000 4.500000000 -36.500000000 -12.500000000 4.500000000 35.500000000 -12.500000000 4.500000000 -36.500000000 -11.500000000 4.500000000 35.500000000 -11.500000000 4.500000000 -36.500000000 -10.500000000 4.500000000 35.500000000 -10.500000000 4.500000000 -36.500000000 -9.500000000 4.500000000 35.500000000 -9.500000000 4.500000000 -36.500000000 -8.500000000 4.500000000 35.500000000 -8.500000000 4.500000000 -36.500000000 -7.500000000 4.500000000 35.500000000 -7.500000000 4.500000000 -36.500000000 -6.500000000 4.500000000 35.500000000 -6.500000000 4.500000000 -36.500000000 -5.500000000 4.500000000 35.500000000 -5.500000000 4.500000000 -36.500000000 -4.500000000 4.500000000 35.500000000 -4.500000000 4.500000000 -36.500000000 -3.500000000 4.500000000 35.500000000 -3.500000000 4.500000000 -36.500000000 -2.500000000 4.500000000 35.500000000 -2.500000000 4.500000000 -36.500000000 -1.500000000 4.500000000 35.500000000 -1.500000000 4.500000000 -36.500000000 -0.500000000 4.500000000 35.500000000 -0.500000000 4.500000000 -36.500000000 0.500000000 4.500000000 35.500000000 0.500000000 4.500000000 -36.500000000 1.500000000 4.500000000 35.500000000 1.500000000 4.500000000 -36.500000000 2.500000000 4.500000000 35.500000000 2.500000000 4.500000000 -36.500000000 3.500000000 4.500000000 35.500000000 3.500000000 4.500000000 -36.500000000 4.500000000 4.500000000 35.500000000 4.500000000 4.500000000 -36.500000000 5.500000000 4.500000000 35.500000000 5.500000000 4.500000000 -36.500000000 6.500000000 4.500000000 35.500000000 6.500000000 4.500000000 -36.500000000 7.500000000 4.500000000 35.500000000 7.500000000 4.500000000 -36.500000000 8.500000000 4.500000000 35.500000000 8.500000000 4.500000000 -36.500000000 9.500000000 4.500000000 35.500000000 9.500000000 4.500000000 -36.500000000 10.500000000 4.500000000 35.500000000 10.500000000 4.500000000 -36.500000000 11.500000000 4.500000000 35.500000000 11.500000000 4.500000000 -36.500000000 12.500000000 4.500000000 35.500000000 12.500000000 4.500000000 -36.500000000 13.500000000 4.500000000 35.500000000 13.500000000 4.500000000 -36.500000000 14.500000000 4.500000000 35.500000000 14.500000000 4.500000000 -36.500000000 15.500000000 4.500000000 35.500000000 15.500000000 4.500000000 -36.500000000 16.500000000 4.500000000 35.500000000 16.500000000 4.500000000 -36.500000000 17.500000000 4.500000000 35.500000000 17.500000000 4.500000000 -36.500000000 18.500000000 4.500000000 35.500000000 18.500000000 4.500000000 -36.500000000 19.500000000 4.500000000 35.500000000 19.500000000 4.500000000 -36.500000000 20.500000000 4.500000000 35.500000000 20.500000000 4.500000000 -36.500000000 21.500000000 4.500000000 35.500000000 21.500000000 4.500000000 -36.500000000 22.500000000 4.500000000 35.500000000 22.500000000 4.500000000 -36.500000000 23.500000000 4.500000000 35.500000000 23.500000000 4.500000000 -36.500000000 24.500000000 4.500000000 35.500000000 24.500000000 4.500000000 -36.499996185 25.499996185 4.500000000 35.499996185 25.499996185 4.500000000 -36.499954224 26.499954224 4.500000000 35.499954224 26.499954224 4.500000000 -36.499591827 27.499591827 4.500000000 35.499591827 27.499591827 4.500000000 -36.497474670 28.497470856 4.500000000 35.497467041 28.497470856 4.500000000 -36.488403320 29.488407135 4.500000000 35.488403320 29.488407135 4.500000000 -36.458980560 30.458978653 4.500000000 35.458980560 30.458978653 4.500000000 -36.384422302 31.384418488 4.500000000 35.384422302 31.384418488 4.500000000 -36.233222961 32.233222961 4.500000000 35.233222961 32.233222961 4.500000000 -35.981101990 32.981101990 4.500000000 -35.622871399 33.622871399 4.500000000 34.622871399 33.622871399 4.500000000 34.981101990 32.981101990 4.500000000 -35.167964935 34.167964935 4.500000000 -34.622871399 34.622871399 4.500000000 33.622871399 34.622871399 4.500000000 34.167964935 34.167964935 4.500000000 -33.981101990 34.981101990 4.500000000 -33.233222961 35.233222961 4.500000000 -32.384422302 35.384418488 4.500000000 -31.458978653 35.458976746 4.500000000 -30.488407135 35.488403320 4.500000000 -29.497472763 35.497467041 4.500000000 -28.499593735 35.499591827 4.500000000 -27.499954224 35.499954224 4.500000000 -26.499996185 35.499996185 4.500000000 -25.500000000 35.500000000 4.500000000 -24.500000000 35.500000000 4.500000000 -23.500000000 35.500000000 4.500000000 -22.500000000 35.500000000 4.500000000 -21.500000000 35.500000000 4.500000000 -20.500000000 35.500000000 4.500000000 -19.500000000 35.500000000 4.500000000 -18.500000000 35.500000000 4.500000000 -17.500000000 35.500000000 4.500000000 -16.500000000 35.500000000 4.500000000 -15.500000000 35.500000000 4.500000000 -14.500000000 35.500000000 4.500000000 -13.500000000 35.500000000 4.500000000 -12.500000000 35.500000000 4.500000000 -11.500000000 35.500000000 4.500000000 -10.500000000 35.500000000 4.500000000 -9.500000000 35.500000000 4.500000000 -8.500000000 35.500000000 4.500000000 -7.500000000 35.500000000 4.500000000 -6.500000000 35.500000000 4.500000000 -5.500000000 35.500000000 4.500000000 -4.500000000 35.500000000 4.500000000 -3.500000000 35.500000000 4.500000000 -2.500000000 35.500000000 4.500000000 -1.500000000 35.500000000 4.500000000 -0.500000000 35.500000000 4.500000000 0.500000000 35.500000000 4.500000000 1.500000000 35.500000000 4.500000000 2.500000000 35.500000000 4.500000000 3.500000000 35.500000000 4.500000000 4.500000000 35.500000000 4.500000000 5.500000000 35.500000000 4.500000000 6.500000000 35.500000000 4.500000000 7.500000000 35.500000000 4.500000000 8.500000000 35.500000000 4.500000000 9.500000000 35.500000000 4.500000000 10.500000000 35.500000000 4.500000000 11.500000000 35.500000000 4.500000000 12.500000000 35.500000000 4.500000000 13.500000000 35.500000000 4.500000000 14.500000000 35.500000000 4.500000000 15.500000000 35.500000000 4.500000000 16.500000000 35.500000000 4.500000000 17.500000000 35.500000000 4.500000000 18.500000000 35.500000000 4.500000000 19.500000000 35.500000000 4.500000000 20.500000000 35.500000000 4.500000000 21.500000000 35.500000000 4.500000000 22.500000000 35.500000000 4.500000000 23.500000000 35.500000000 4.500000000 24.500000000 35.500000000 4.500000000 25.499996185 35.499996185 4.500000000 26.499954224 35.499954224 4.500000000 27.499591827 35.499591827 4.500000000 28.497470856 35.497474670 4.500000000 29.488407135 35.488403320 4.500000000 30.458978653 35.458980560 4.500000000 31.384418488 35.384422302 4.500000000 32.233222961 35.233222961 4.500000000 32.981101990 34.981101990 4.500000000 -33.981101990 -35.981101990 5.500000000 -33.233226776 -36.233222961 5.500000000 -32.384422302 -36.384418488 5.500000000 -31.458978653 -36.458980560 5.500000000 -30.488407135 -36.488403320 5.500000000 -29.497472763 -36.497474670 5.500000000 -28.499593735 -36.499591827 5.500000000 -27.499954224 -36.499954224 5.500000000 -26.499996185 -36.499996185 5.500000000 -25.500000000 -36.500000000 5.500000000 -24.500000000 -36.500000000 5.500000000 -23.500000000 -36.500000000 5.500000000 -22.500000000 -36.500000000 5.500000000 -21.500000000 -36.500000000 5.500000000 -20.500000000 -36.500000000 5.500000000 -19.500000000 -36.500000000 5.500000000 -18.500000000 -36.500000000 5.500000000 -17.500000000 -36.500000000 5.500000000 -16.500000000 -36.500000000 5.500000000 -15.500000000 -36.500000000 5.500000000 -14.500000000 -36.500000000 5.500000000 -13.500000000 -36.500000000 5.500000000 -12.500000000 -36.500000000 5.500000000 -11.500000000 -36.500000000 5.500000000 -10.500000000 -36.500000000 5.500000000 -9.500000000 -36.500000000 5.500000000 -8.500000000 -36.500000000 5.500000000 -7.500000000 -36.500000000 5.500000000 -6.500000000 -36.500000000 5.500000000 -5.500000000 -36.500000000 5.500000000 -4.500000000 -36.500000000 5.500000000 -3.500000000 -36.500000000 5.500000000 -2.500000000 -36.500000000 5.500000000 -1.500000000 -36.500000000 5.500000000 -0.500000000 -36.500000000 5.500000000 0.500000000 -36.500000000 5.500000000 1.500000000 -36.500000000 5.500000000 2.500000000 -36.500000000 5.500000000 3.500000000 -36.500000000 5.500000000 4.500000000 -36.500000000 5.500000000 5.500000000 -36.500000000 5.500000000 6.500000000 -36.500000000 5.500000000 7.500000000 -36.500000000 5.500000000 8.500000000 -36.500000000 5.500000000 9.500000000 -36.500000000 5.500000000 10.500000000 -36.500000000 5.500000000 11.500000000 -36.500000000 5.500000000 12.500000000 -36.500000000 5.500000000 13.500000000 -36.500000000 5.500000000 14.500000000 -36.500000000 5.500000000 15.500000000 -36.500000000 5.500000000 16.500000000 -36.500000000 5.500000000 17.500000000 -36.500000000 5.500000000 18.500000000 -36.500000000 5.500000000 19.500000000 -36.500000000 5.500000000 20.500000000 -36.500000000 5.500000000 21.500000000 -36.500000000 5.500000000 22.500000000 -36.500000000 5.500000000 23.500000000 -36.500000000 5.500000000 24.500000000 -36.500000000 5.500000000 25.499996185 -36.499996185 5.500000000 26.499954224 -36.499954224 5.500000000 27.499591827 -36.499591827 5.500000000 28.497470856 -36.497467041 5.500000000 29.488407135 -36.488403320 5.500000000 30.458978653 -36.458980560 5.500000000 31.384418488 -36.384422302 5.500000000 32.233222961 -36.233222961 5.500000000 32.981101990 -35.981101990 5.500000000 -35.167964935 -35.167964935 5.500000000 -34.622871399 -35.622871399 5.500000000 33.622871399 -35.622871399 5.500000000 34.167964935 -35.167964935 5.500000000 -35.981101990 -33.981101990 5.500000000 -35.622871399 -34.622871399 5.500000000 34.622871399 -34.622871399 5.500000000 34.981101990 -33.981101990 5.500000000 -36.233222961 -33.233222961 5.500000000 35.233222961 -33.233226776 5.500000000 -36.384418488 -32.384422302 5.500000000 35.384418488 -32.384422302 5.500000000 -36.458976746 -31.458978653 5.500000000 35.458980560 -31.458978653 5.500000000 -36.488403320 -30.488407135 5.500000000 35.488403320 -30.488407135 5.500000000 -36.497467041 -29.497472763 5.500000000 35.497474670 -29.497472763 5.500000000 -36.499591827 -28.499593735 5.500000000 35.499591827 -28.499593735 5.500000000 -36.499954224 -27.499954224 5.500000000 35.499954224 -27.499954224 5.500000000 -36.499996185 -26.499996185 5.500000000 35.499996185 -26.499996185 5.500000000 -36.500000000 -25.500000000 5.500000000 35.500000000 -25.500000000 5.500000000 -36.500000000 -24.500000000 5.500000000 35.500000000 -24.500000000 5.500000000 -36.500000000 -23.500000000 5.500000000 35.500000000 -23.500000000 5.500000000 -36.500000000 -22.500000000 5.500000000 35.500000000 -22.500000000 5.500000000 -36.500000000 -21.500000000 5.500000000 35.500000000 -21.500000000 5.500000000 -36.500000000 -20.500000000 5.500000000 35.500000000 -20.500000000 5.500000000 -36.500000000 -19.500000000 5.500000000 35.500000000 -19.500000000 5.500000000 -36.500000000 -18.500000000 5.500000000 35.500000000 -18.500000000 5.500000000 -36.500000000 -17.500000000 5.500000000 35.500000000 -17.500000000 5.500000000 -36.500000000 -16.500000000 5.500000000 35.500000000 -16.500000000 5.500000000 -36.500000000 -15.500000000 5.500000000 35.500000000 -15.500000000 5.500000000 -36.500000000 -14.500000000 5.500000000 35.500000000 -14.500000000 5.500000000 -36.500000000 -13.500000000 5.500000000 35.500000000 -13.500000000 5.500000000 -36.500000000 -12.500000000 5.500000000 35.500000000 -12.500000000 5.500000000 -36.500000000 -11.500000000 5.500000000 35.500000000 -11.500000000 5.500000000 -36.500000000 -10.500000000 5.500000000 35.500000000 -10.500000000 5.500000000 -36.500000000 -9.500000000 5.500000000 35.500000000 -9.500000000 5.500000000 -36.500000000 -8.500000000 5.500000000 35.500000000 -8.500000000 5.500000000 -36.500000000 -7.500000000 5.500000000 35.500000000 -7.500000000 5.500000000 -36.500000000 -6.500000000 5.500000000 35.500000000 -6.500000000 5.500000000 -36.500000000 -5.500000000 5.500000000 35.500000000 -5.500000000 5.500000000 -36.500000000 -4.500000000 5.500000000 35.500000000 -4.500000000 5.500000000 -36.500000000 -3.500000000 5.500000000 35.500000000 -3.500000000 5.500000000 -36.500000000 -2.500000000 5.500000000 35.500000000 -2.500000000 5.500000000 -36.500000000 -1.500000000 5.500000000 35.500000000 -1.500000000 5.500000000 -36.500000000 -0.500000000 5.500000000 35.500000000 -0.500000000 5.500000000 -36.500000000 0.500000000 5.500000000 35.500000000 0.500000000 5.500000000 -36.500000000 1.500000000 5.500000000 35.500000000 1.500000000 5.500000000 -36.500000000 2.500000000 5.500000000 35.500000000 2.500000000 5.500000000 -36.500000000 3.500000000 5.500000000 35.500000000 3.500000000 5.500000000 -36.500000000 4.500000000 5.500000000 35.500000000 4.500000000 5.500000000 -36.500000000 5.500000000 5.500000000 35.500000000 5.500000000 5.500000000 -36.500000000 6.500000000 5.500000000 35.500000000 6.500000000 5.500000000 -36.500000000 7.500000000 5.500000000 35.500000000 7.500000000 5.500000000 -36.500000000 8.500000000 5.500000000 35.500000000 8.500000000 5.500000000 -36.500000000 9.500000000 5.500000000 35.500000000 9.500000000 5.500000000 -36.500000000 10.500000000 5.500000000 35.500000000 10.500000000 5.500000000 -36.500000000 11.500000000 5.500000000 35.500000000 11.500000000 5.500000000 -36.500000000 12.500000000 5.500000000 35.500000000 12.500000000 5.500000000 -36.500000000 13.500000000 5.500000000 35.500000000 13.500000000 5.500000000 -36.500000000 14.500000000 5.500000000 35.500000000 14.500000000 5.500000000 -36.500000000 15.500000000 5.500000000 35.500000000 15.500000000 5.500000000 -36.500000000 16.500000000 5.500000000 35.500000000 16.500000000 5.500000000 -36.500000000 17.500000000 5.500000000 35.500000000 17.500000000 5.500000000 -36.500000000 18.500000000 5.500000000 35.500000000 18.500000000 5.500000000 -36.500000000 19.500000000 5.500000000 35.500000000 19.500000000 5.500000000 -36.500000000 20.500000000 5.500000000 35.500000000 20.500000000 5.500000000 -36.500000000 21.500000000 5.500000000 35.500000000 21.500000000 5.500000000 -36.500000000 22.500000000 5.500000000 35.500000000 22.500000000 5.500000000 -36.500000000 23.500000000 5.500000000 35.500000000 23.500000000 5.500000000 -36.500000000 24.500000000 5.500000000 35.500000000 24.500000000 5.500000000 -36.499996185 25.499996185 5.500000000 35.499996185 25.499996185 5.500000000 -36.499954224 26.499954224 5.500000000 35.499954224 26.499954224 5.500000000 -36.499591827 27.499591827 5.500000000 35.499591827 27.499591827 5.500000000 -36.497474670 28.497470856 5.500000000 35.497467041 28.497470856 5.500000000 -36.488403320 29.488407135 5.500000000 35.488403320 29.488407135 5.500000000 -36.458980560 30.458978653 5.500000000 35.458980560 30.458978653 5.500000000 -36.384422302 31.384418488 5.500000000 35.384422302 31.384418488 5.500000000 -36.233222961 32.233222961 5.500000000 35.233222961 32.233222961 5.500000000 -35.981101990 32.981101990 5.500000000 -35.622871399 33.622871399 5.500000000 34.622871399 33.622871399 5.500000000 34.981101990 32.981101990 5.500000000 -35.167964935 34.167964935 5.500000000 -34.622871399 34.622871399 5.500000000 33.622871399 34.622871399 5.500000000 34.167964935 34.167964935 5.500000000 -33.981101990 34.981101990 5.500000000 -33.233222961 35.233222961 5.500000000 -32.384422302 35.384418488 5.500000000 -31.458978653 35.458976746 5.500000000 -30.488407135 35.488403320 5.500000000 -29.497472763 35.497467041 5.500000000 -28.499593735 35.499591827 5.500000000 -27.499954224 35.499954224 5.500000000 -26.499996185 35.499996185 5.500000000 -25.500000000 35.500000000 5.500000000 -24.500000000 35.500000000 5.500000000 -23.500000000 35.500000000 5.500000000 -22.500000000 35.500000000 5.500000000 -21.500000000 35.500000000 5.500000000 -20.500000000 35.500000000 5.500000000 -19.500000000 35.500000000 5.500000000 -18.500000000 35.500000000 5.500000000 -17.500000000 35.500000000 5.500000000 -16.500000000 35.500000000 5.500000000 -15.500000000 35.500000000 5.500000000 -14.500000000 35.500000000 5.500000000 -13.500000000 35.500000000 5.500000000 -12.500000000 35.500000000 5.500000000 -11.500000000 35.500000000 5.500000000 -10.500000000 35.500000000 5.500000000 -9.500000000 35.500000000 5.500000000 -8.500000000 35.500000000 5.500000000 -7.500000000 35.500000000 5.500000000 -6.500000000 35.500000000 5.500000000 -5.500000000 35.500000000 5.500000000 -4.500000000 35.500000000 5.500000000 -3.500000000 35.500000000 5.500000000 -2.500000000 35.500000000 5.500000000 -1.500000000 35.500000000 5.500000000 -0.500000000 35.500000000 5.500000000 0.500000000 35.500000000 5.500000000 1.500000000 35.500000000 5.500000000 2.500000000 35.500000000 5.500000000 3.500000000 35.500000000 5.500000000 4.500000000 35.500000000 5.500000000 5.500000000 35.500000000 5.500000000 6.500000000 35.500000000 5.500000000 7.500000000 35.500000000 5.500000000 8.500000000 35.500000000 5.500000000 9.500000000 35.500000000 5.500000000 10.500000000 35.500000000 5.500000000 11.500000000 35.500000000 5.500000000 12.500000000 35.500000000 5.500000000 13.500000000 35.500000000 5.500000000 14.500000000 35.500000000 5.500000000 15.500000000 35.500000000 5.500000000 16.500000000 35.500000000 5.500000000 17.500000000 35.500000000 5.500000000 18.500000000 35.500000000 5.500000000 19.500000000 35.500000000 5.500000000 20.500000000 35.500000000 5.500000000 21.500000000 35.500000000 5.500000000 22.500000000 35.500000000 5.500000000 23.500000000 35.500000000 5.500000000 24.500000000 35.500000000 5.500000000 25.499996185 35.499996185 5.500000000 26.499954224 35.499954224 5.500000000 27.499591827 35.499591827 5.500000000 28.497470856 35.497474670 5.500000000 29.488407135 35.488403320 5.500000000 30.458978653 35.458980560 5.500000000 31.384418488 35.384422302 5.500000000 32.233222961 35.233222961 5.500000000 32.981101990 34.981101990 5.500000000 -33.981101990 -35.981101990 6.500000000 -33.233226776 -36.233222961 6.500000000 -32.384422302 -36.384418488 6.500000000 -31.458978653 -36.458980560 6.500000000 -30.488407135 -36.488403320 6.500000000 -29.497472763 -36.497474670 6.500000000 -28.499593735 -36.499591827 6.500000000 -27.499954224 -36.499954224 6.500000000 -26.499996185 -36.499996185 6.500000000 -25.500000000 -36.500000000 6.500000000 -24.500000000 -36.500000000 6.500000000 -23.500000000 -36.500000000 6.500000000 -22.500000000 -36.500000000 6.500000000 -21.500000000 -36.500000000 6.500000000 -20.500000000 -36.500000000 6.500000000 -19.500000000 -36.500000000 6.500000000 -18.500000000 -36.500000000 6.500000000 -17.500000000 -36.500000000 6.500000000 -16.500000000 -36.500000000 6.500000000 -15.500000000 -36.500000000 6.500000000 -14.500000000 -36.500000000 6.500000000 -13.500000000 -36.500000000 6.500000000 -12.500000000 -36.500000000 6.500000000 -11.500000000 -36.500000000 6.500000000 -10.500000000 -36.500000000 6.500000000 -9.500000000 -36.500000000 6.500000000 -8.500000000 -36.500000000 6.500000000 -7.500000000 -36.500000000 6.500000000 -6.500000000 -36.500000000 6.500000000 -5.500000000 -36.500000000 6.500000000 -4.500000000 -36.500000000 6.500000000 -3.500000000 -36.500000000 6.500000000 -2.500000000 -36.500000000 6.500000000 -1.500000000 -36.500000000 6.500000000 -0.500000000 -36.500000000 6.500000000 0.500000000 -36.500000000 6.500000000 1.500000000 -36.500000000 6.500000000 2.500000000 -36.500000000 6.500000000 3.500000000 -36.500000000 6.500000000 4.500000000 -36.500000000 6.500000000 5.500000000 -36.500000000 6.500000000 6.500000000 -36.500000000 6.500000000 7.500000000 -36.500000000 6.500000000 8.500000000 -36.500000000 6.500000000 9.500000000 -36.500000000 6.500000000 10.500000000 -36.500000000 6.500000000 11.500000000 -36.500000000 6.500000000 12.500000000 -36.500000000 6.500000000 13.500000000 -36.500000000 6.500000000 14.500000000 -36.500000000 6.500000000 15.500000000 -36.500000000 6.500000000 16.500000000 -36.500000000 6.500000000 17.500000000 -36.500000000 6.500000000 18.500000000 -36.500000000 6.500000000 19.500000000 -36.500000000 6.500000000 20.500000000 -36.500000000 6.500000000 21.500000000 -36.500000000 6.500000000 22.500000000 -36.500000000 6.500000000 23.500000000 -36.500000000 6.500000000 24.500000000 -36.500000000 6.500000000 25.499996185 -36.499996185 6.500000000 26.499954224 -36.499954224 6.500000000 27.499591827 -36.499591827 6.500000000 28.497470856 -36.497467041 6.500000000 29.488407135 -36.488403320 6.500000000 30.458978653 -36.458980560 6.500000000 31.384418488 -36.384422302 6.500000000 32.233222961 -36.233222961 6.500000000 32.981101990 -35.981101990 6.500000000 -35.167964935 -35.167964935 6.500000000 -34.622871399 -35.622871399 6.500000000 33.622871399 -35.622871399 6.500000000 34.167964935 -35.167964935 6.500000000 -35.981101990 -33.981101990 6.500000000 -35.622871399 -34.622871399 6.500000000 34.622871399 -34.622871399 6.500000000 34.981101990 -33.981101990 6.500000000 -36.233222961 -33.233222961 6.500000000 35.233222961 -33.233226776 6.500000000 -36.384418488 -32.384422302 6.500000000 35.384418488 -32.384422302 6.500000000 -36.458976746 -31.458978653 6.500000000 35.458980560 -31.458978653 6.500000000 -36.488403320 -30.488407135 6.500000000 35.488403320 -30.488407135 6.500000000 -36.497467041 -29.497472763 6.500000000 35.497474670 -29.497472763 6.500000000 -36.499591827 -28.499593735 6.500000000 35.499591827 -28.499593735 6.500000000 -36.499954224 -27.499954224 6.500000000 35.499954224 -27.499954224 6.500000000 -36.499996185 -26.499996185 6.500000000 35.499996185 -26.499996185 6.500000000 -36.500000000 -25.500000000 6.500000000 35.500000000 -25.500000000 6.500000000 -36.500000000 -24.500000000 6.500000000 35.500000000 -24.500000000 6.500000000 -36.500000000 -23.500000000 6.500000000 35.500000000 -23.500000000 6.500000000 -36.500000000 -22.500000000 6.500000000 35.500000000 -22.500000000 6.500000000 -36.500000000 -21.500000000 6.500000000 35.500000000 -21.500000000 6.500000000 -36.500000000 -20.500000000 6.500000000 35.500000000 -20.500000000 6.500000000 -36.500000000 -19.500000000 6.500000000 35.500000000 -19.500000000 6.500000000 -36.500000000 -18.500000000 6.500000000 35.500000000 -18.500000000 6.500000000 -36.500000000 -17.500000000 6.500000000 35.500000000 -17.500000000 6.500000000 -36.500000000 -16.500000000 6.500000000 35.500000000 -16.500000000 6.500000000 -36.500000000 -15.500000000 6.500000000 35.500000000 -15.500000000 6.500000000 -36.500000000 -14.500000000 6.500000000 35.500000000 -14.500000000 6.500000000 -36.500000000 -13.500000000 6.500000000 35.500000000 -13.500000000 6.500000000 -36.500000000 -12.500000000 6.500000000 35.500000000 -12.500000000 6.500000000 -36.500000000 -11.500000000 6.500000000 35.500000000 -11.500000000 6.500000000 -36.500000000 -10.500000000 6.500000000 35.500000000 -10.500000000 6.500000000 -36.500000000 -9.500000000 6.500000000 35.500000000 -9.500000000 6.500000000 -36.500000000 -8.500000000 6.500000000 35.500000000 -8.500000000 6.500000000 -36.500000000 -7.500000000 6.500000000 35.500000000 -7.500000000 6.500000000 -36.500000000 -6.500000000 6.500000000 35.500000000 -6.500000000 6.500000000 -36.500000000 -5.500000000 6.500000000 35.500000000 -5.500000000 6.500000000 -36.500000000 -4.500000000 6.500000000 35.500000000 -4.500000000 6.500000000 -36.500000000 -3.500000000 6.500000000 35.500000000 -3.500000000 6.500000000 -36.500000000 -2.500000000 6.500000000 35.500000000 -2.500000000 6.500000000 -36.500000000 -1.500000000 6.500000000 35.500000000 -1.500000000 6.500000000 -36.500000000 -0.500000000 6.500000000 35.500000000 -0.500000000 6.500000000 -36.500000000 0.500000000 6.500000000 35.500000000 0.500000000 6.500000000 -36.500000000 1.500000000 6.500000000 35.500000000 1.500000000 6.500000000 -36.500000000 2.500000000 6.500000000 35.500000000 2.500000000 6.500000000 -36.500000000 3.500000000 6.500000000 35.500000000 3.500000000 6.500000000 -36.500000000 4.500000000 6.500000000 35.500000000 4.500000000 6.500000000 -36.500000000 5.500000000 6.500000000 35.500000000 5.500000000 6.500000000 -36.500000000 6.500000000 6.500000000 35.500000000 6.500000000 6.500000000 -36.500000000 7.500000000 6.500000000 35.500000000 7.500000000 6.500000000 -36.500000000 8.500000000 6.500000000 35.500000000 8.500000000 6.500000000 -36.500000000 9.500000000 6.500000000 35.500000000 9.500000000 6.500000000 -36.500000000 10.500000000 6.500000000 35.500000000 10.500000000 6.500000000 -36.500000000 11.500000000 6.500000000 35.500000000 11.500000000 6.500000000 -36.500000000 12.500000000 6.500000000 35.500000000 12.500000000 6.500000000 -36.500000000 13.500000000 6.500000000 35.500000000 13.500000000 6.500000000 -36.500000000 14.500000000 6.500000000 35.500000000 14.500000000 6.500000000 -36.500000000 15.500000000 6.500000000 35.500000000 15.500000000 6.500000000 -36.500000000 16.500000000 6.500000000 35.500000000 16.500000000 6.500000000 -36.500000000 17.500000000 6.500000000 35.500000000 17.500000000 6.500000000 -36.500000000 18.500000000 6.500000000 35.500000000 18.500000000 6.500000000 -36.500000000 19.500000000 6.500000000 35.500000000 19.500000000 6.500000000 -36.500000000 20.500000000 6.500000000 35.500000000 20.500000000 6.500000000 -36.500000000 21.500000000 6.500000000 35.500000000 21.500000000 6.500000000 -36.500000000 22.500000000 6.500000000 35.500000000 22.500000000 6.500000000 -36.500000000 23.500000000 6.500000000 35.500000000 23.500000000 6.500000000 -36.500000000 24.500000000 6.500000000 35.500000000 24.500000000 6.500000000 -36.499996185 25.499996185 6.500000000 35.499996185 25.499996185 6.500000000 -36.499954224 26.499954224 6.500000000 35.499954224 26.499954224 6.500000000 -36.499591827 27.499591827 6.500000000 35.499591827 27.499591827 6.500000000 -36.497474670 28.497470856 6.500000000 35.497467041 28.497470856 6.500000000 -36.488403320 29.488407135 6.500000000 35.488403320 29.488407135 6.500000000 -36.458980560 30.458978653 6.500000000 35.458980560 30.458978653 6.500000000 -36.384422302 31.384418488 6.500000000 35.384422302 31.384418488 6.500000000 -36.233222961 32.233222961 6.500000000 35.233222961 32.233222961 6.500000000 -35.981101990 32.981101990 6.500000000 -35.622871399 33.622871399 6.500000000 34.622871399 33.622871399 6.500000000 34.981101990 32.981101990 6.500000000 -35.167964935 34.167964935 6.500000000 -34.622871399 34.622871399 6.500000000 33.622871399 34.622871399 6.500000000 34.167964935 34.167964935 6.500000000 -33.981101990 34.981101990 6.500000000 -33.233222961 35.233222961 6.500000000 -32.384422302 35.384418488 6.500000000 -31.458978653 35.458976746 6.500000000 -30.488407135 35.488403320 6.500000000 -29.497472763 35.497467041 6.500000000 -28.499593735 35.499591827 6.500000000 -27.499954224 35.499954224 6.500000000 -26.499996185 35.499996185 6.500000000 -25.500000000 35.500000000 6.500000000 -24.500000000 35.500000000 6.500000000 -23.500000000 35.500000000 6.500000000 -22.500000000 35.500000000 6.500000000 -21.500000000 35.500000000 6.500000000 -20.500000000 35.500000000 6.500000000 -19.500000000 35.500000000 6.500000000 -18.500000000 35.500000000 6.500000000 -17.500000000 35.500000000 6.500000000 -16.500000000 35.500000000 6.500000000 -15.500000000 35.500000000 6.500000000 -14.500000000 35.500000000 6.500000000 -13.500000000 35.500000000 6.500000000 -12.500000000 35.500000000 6.500000000 -11.500000000 35.500000000 6.500000000 -10.500000000 35.500000000 6.500000000 -9.500000000 35.500000000 6.500000000 -8.500000000 35.500000000 6.500000000 -7.500000000 35.500000000 6.500000000 -6.500000000 35.500000000 6.500000000 -5.500000000 35.500000000 6.500000000 -4.500000000 35.500000000 6.500000000 -3.500000000 35.500000000 6.500000000 -2.500000000 35.500000000 6.500000000 -1.500000000 35.500000000 6.500000000 -0.500000000 35.500000000 6.500000000 0.500000000 35.500000000 6.500000000 1.500000000 35.500000000 6.500000000 2.500000000 35.500000000 6.500000000 3.500000000 35.500000000 6.500000000 4.500000000 35.500000000 6.500000000 5.500000000 35.500000000 6.500000000 6.500000000 35.500000000 6.500000000 7.500000000 35.500000000 6.500000000 8.500000000 35.500000000 6.500000000 9.500000000 35.500000000 6.500000000 10.500000000 35.500000000 6.500000000 11.500000000 35.500000000 6.500000000 12.500000000 35.500000000 6.500000000 13.500000000 35.500000000 6.500000000 14.500000000 35.500000000 6.500000000 15.500000000 35.500000000 6.500000000 16.500000000 35.500000000 6.500000000 17.500000000 35.500000000 6.500000000 18.500000000 35.500000000 6.500000000 19.500000000 35.500000000 6.500000000 20.500000000 35.500000000 6.500000000 21.500000000 35.500000000 6.500000000 22.500000000 35.500000000 6.500000000 23.500000000 35.500000000 6.500000000 24.500000000 35.500000000 6.500000000 25.499996185 35.499996185 6.500000000 26.499954224 35.499954224 6.500000000 27.499591827 35.499591827 6.500000000 28.497470856 35.497474670 6.500000000 29.488407135 35.488403320 6.500000000 30.458978653 35.458980560 6.500000000 31.384418488 35.384422302 6.500000000 32.233222961 35.233222961 6.500000000 32.981101990 34.981101990 6.500000000 -33.981101990 -35.981101990 7.500000000 -33.233226776 -36.233222961 7.500000000 -32.384422302 -36.384418488 7.500000000 -31.458978653 -36.458980560 7.500000000 -30.488407135 -36.488403320 7.500000000 -29.497472763 -36.497474670 7.500000000 -28.499593735 -36.499591827 7.500000000 -27.499954224 -36.499954224 7.500000000 -26.499996185 -36.499996185 7.500000000 -25.500000000 -36.500000000 7.500000000 -24.500000000 -36.500000000 7.500000000 -23.500000000 -36.500000000 7.500000000 -22.500000000 -36.500000000 7.500000000 -21.500000000 -36.500000000 7.500000000 -20.500000000 -36.500000000 7.500000000 -19.500000000 -36.500000000 7.500000000 -18.500000000 -36.500000000 7.500000000 -17.500000000 -36.500000000 7.500000000 -16.500000000 -36.500000000 7.500000000 -15.500000000 -36.500000000 7.500000000 -14.500000000 -36.500000000 7.500000000 -13.500000000 -36.500000000 7.500000000 -12.500000000 -36.500000000 7.500000000 -11.500000000 -36.500000000 7.500000000 -10.500000000 -36.500000000 7.500000000 -9.500000000 -36.500000000 7.500000000 -8.500000000 -36.500000000 7.500000000 -7.500000000 -36.500000000 7.500000000 -6.500000000 -36.500000000 7.500000000 -5.500000000 -36.500000000 7.500000000 -4.500000000 -36.500000000 7.500000000 -3.500000000 -36.500000000 7.500000000 -2.500000000 -36.500000000 7.500000000 -1.500000000 -36.500000000 7.500000000 -0.500000000 -36.500000000 7.500000000 0.500000000 -36.500000000 7.500000000 1.500000000 -36.500000000 7.500000000 2.500000000 -36.500000000 7.500000000 3.500000000 -36.500000000 7.500000000 4.500000000 -36.500000000 7.500000000 5.500000000 -36.500000000 7.500000000 6.500000000 -36.500000000 7.500000000 7.500000000 -36.500000000 7.500000000 8.500000000 -36.500000000 7.500000000 9.500000000 -36.500000000 7.500000000 10.500000000 -36.500000000 7.500000000 11.500000000 -36.500000000 7.500000000 12.500000000 -36.500000000 7.500000000 13.500000000 -36.500000000 7.500000000 14.500000000 -36.500000000 7.500000000 15.500000000 -36.500000000 7.500000000 16.500000000 -36.500000000 7.500000000 17.500000000 -36.500000000 7.500000000 18.500000000 -36.500000000 7.500000000 19.500000000 -36.500000000 7.500000000 20.500000000 -36.500000000 7.500000000 21.500000000 -36.500000000 7.500000000 22.500000000 -36.500000000 7.500000000 23.500000000 -36.500000000 7.500000000 24.500000000 -36.500000000 7.500000000 25.499996185 -36.499996185 7.500000000 26.499954224 -36.499954224 7.500000000 27.499591827 -36.499591827 7.500000000 28.497470856 -36.497467041 7.500000000 29.488407135 -36.488403320 7.500000000 30.458978653 -36.458980560 7.500000000 31.384418488 -36.384422302 7.500000000 32.233222961 -36.233222961 7.500000000 32.981101990 -35.981101990 7.500000000 -35.167964935 -35.167964935 7.500000000 -34.622871399 -35.622871399 7.500000000 33.622871399 -35.622871399 7.500000000 34.167964935 -35.167964935 7.500000000 -35.981101990 -33.981101990 7.500000000 -35.622871399 -34.622871399 7.500000000 34.622871399 -34.622871399 7.500000000 34.981101990 -33.981101990 7.500000000 -36.233222961 -33.233222961 7.500000000 35.233222961 -33.233226776 7.500000000 -36.384418488 -32.384422302 7.500000000 35.384418488 -32.384422302 7.500000000 -36.458976746 -31.458978653 7.500000000 35.458980560 -31.458978653 7.500000000 -36.488403320 -30.488407135 7.500000000 35.488403320 -30.488407135 7.500000000 -36.497467041 -29.497472763 7.500000000 35.497474670 -29.497472763 7.500000000 -36.499591827 -28.499593735 7.500000000 35.499591827 -28.499593735 7.500000000 -36.499954224 -27.499954224 7.500000000 35.499954224 -27.499954224 7.500000000 -36.499996185 -26.499996185 7.500000000 35.499996185 -26.499996185 7.500000000 -36.500000000 -25.500000000 7.500000000 35.500000000 -25.500000000 7.500000000 -36.500000000 -24.500000000 7.500000000 35.500000000 -24.500000000 7.500000000 -36.500000000 -23.500000000 7.500000000 35.500000000 -23.500000000 7.500000000 -36.500000000 -22.500000000 7.500000000 35.500000000 -22.500000000 7.500000000 -36.500000000 -21.500000000 7.500000000 35.500000000 -21.500000000 7.500000000 -36.500000000 -20.500000000 7.500000000 35.500000000 -20.500000000 7.500000000 -36.500000000 -19.500000000 7.500000000 35.500000000 -19.500000000 7.500000000 -36.500000000 -18.500000000 7.500000000 35.500000000 -18.500000000 7.500000000 -36.500000000 -17.500000000 7.500000000 35.500000000 -17.500000000 7.500000000 -36.500000000 -16.500000000 7.500000000 35.500000000 -16.500000000 7.500000000 -36.500000000 -15.500000000 7.500000000 35.500000000 -15.500000000 7.500000000 -36.500000000 -14.500000000 7.500000000 35.500000000 -14.500000000 7.500000000 -36.500000000 -13.500000000 7.500000000 35.500000000 -13.500000000 7.500000000 -36.500000000 -12.500000000 7.500000000 35.500000000 -12.500000000 7.500000000 -36.500000000 -11.500000000 7.500000000 35.500000000 -11.500000000 7.500000000 -36.500000000 -10.500000000 7.500000000 35.500000000 -10.500000000 7.500000000 -36.500000000 -9.500000000 7.500000000 35.500000000 -9.500000000 7.500000000 -36.500000000 -8.500000000 7.500000000 35.500000000 -8.500000000 7.500000000 -36.500000000 -7.500000000 7.500000000 35.500000000 -7.500000000 7.500000000 -36.500000000 -6.500000000 7.500000000 35.500000000 -6.500000000 7.500000000 -36.500000000 -5.500000000 7.500000000 35.500000000 -5.500000000 7.500000000 -36.500000000 -4.500000000 7.500000000 35.500000000 -4.500000000 7.500000000 -36.500000000 -3.500000000 7.500000000 35.500000000 -3.500000000 7.500000000 -36.500000000 -2.500000000 7.500000000 35.500000000 -2.500000000 7.500000000 -36.500000000 -1.500000000 7.500000000 35.500000000 -1.500000000 7.500000000 -36.500000000 -0.500000000 7.500000000 35.500000000 -0.500000000 7.500000000 -36.500000000 0.500000000 7.500000000 35.500000000 0.500000000 7.500000000 -36.500000000 1.500000000 7.500000000 35.500000000 1.500000000 7.500000000 -36.500000000 2.500000000 7.500000000 35.500000000 2.500000000 7.500000000 -36.500000000 3.500000000 7.500000000 35.500000000 3.500000000 7.500000000 -36.500000000 4.500000000 7.500000000 35.500000000 4.500000000 7.500000000 -36.500000000 5.500000000 7.500000000 35.500000000 5.500000000 7.500000000 -36.500000000 6.500000000 7.500000000 35.500000000 6.500000000 7.500000000 -36.500000000 7.500000000 7.500000000 35.500000000 7.500000000 7.500000000 -36.500000000 8.500000000 7.500000000 35.500000000 8.500000000 7.500000000 -36.500000000 9.500000000 7.500000000 35.500000000 9.500000000 7.500000000 -36.500000000 10.500000000 7.500000000 35.500000000 10.500000000 7.500000000 -36.500000000 11.500000000 7.500000000 35.500000000 11.500000000 7.500000000 -36.500000000 12.500000000 7.500000000 35.500000000 12.500000000 7.500000000 -36.500000000 13.500000000 7.500000000 35.500000000 13.500000000 7.500000000 -36.500000000 14.500000000 7.500000000 35.500000000 14.500000000 7.500000000 -36.500000000 15.500000000 7.500000000 35.500000000 15.500000000 7.500000000 -36.500000000 16.500000000 7.500000000 35.500000000 16.500000000 7.500000000 -36.500000000 17.500000000 7.500000000 35.500000000 17.500000000 7.500000000 -36.500000000 18.500000000 7.500000000 35.500000000 18.500000000 7.500000000 -36.500000000 19.500000000 7.500000000 35.500000000 19.500000000 7.500000000 -36.500000000 20.500000000 7.500000000 35.500000000 20.500000000 7.500000000 -36.500000000 21.500000000 7.500000000 35.500000000 21.500000000 7.500000000 -36.500000000 22.500000000 7.500000000 35.500000000 22.500000000 7.500000000 -36.500000000 23.500000000 7.500000000 35.500000000 23.500000000 7.500000000 -36.500000000 24.500000000 7.500000000 35.500000000 24.500000000 7.500000000 -36.499996185 25.499996185 7.500000000 35.499996185 25.499996185 7.500000000 -36.499954224 26.499954224 7.500000000 35.499954224 26.499954224 7.500000000 -36.499591827 27.499591827 7.500000000 35.499591827 27.499591827 7.500000000 -36.497474670 28.497470856 7.500000000 35.497467041 28.497470856 7.500000000 -36.488403320 29.488407135 7.500000000 35.488403320 29.488407135 7.500000000 -36.458980560 30.458978653 7.500000000 35.458980560 30.458978653 7.500000000 -36.384422302 31.384418488 7.500000000 35.384422302 31.384418488 7.500000000 -36.233222961 32.233222961 7.500000000 35.233222961 32.233222961 7.500000000 -35.981101990 32.981101990 7.500000000 -35.622871399 33.622871399 7.500000000 34.622871399 33.622871399 7.500000000 34.981101990 32.981101990 7.500000000 -35.167964935 34.167964935 7.500000000 -34.622871399 34.622871399 7.500000000 33.622871399 34.622871399 7.500000000 34.167964935 34.167964935 7.500000000 -33.981101990 34.981101990 7.500000000 -33.233222961 35.233222961 7.500000000 -32.384422302 35.384418488 7.500000000 -31.458978653 35.458976746 7.500000000 -30.488407135 35.488403320 7.500000000 -29.497472763 35.497467041 7.500000000 -28.499593735 35.499591827 7.500000000 -27.499954224 35.499954224 7.500000000 -26.499996185 35.499996185 7.500000000 -25.500000000 35.500000000 7.500000000 -24.500000000 35.500000000 7.500000000 -23.500000000 35.500000000 7.500000000 -22.500000000 35.500000000 7.500000000 -21.500000000 35.500000000 7.500000000 -20.500000000 35.500000000 7.500000000 -19.500000000 35.500000000 7.500000000 -18.500000000 35.500000000 7.500000000 -17.500000000 35.500000000 7.500000000 -16.500000000 35.500000000 7.500000000 -15.500000000 35.500000000 7.500000000 -14.500000000 35.500000000 7.500000000 -13.500000000 35.500000000 7.500000000 -12.500000000 35.500000000 7.500000000 -11.500000000 35.500000000 7.500000000 -10.500000000 35.500000000 7.500000000 -9.500000000 35.500000000 7.500000000 -8.500000000 35.500000000 7.500000000 -7.500000000 35.500000000 7.500000000 -6.500000000 35.500000000 7.500000000 -5.500000000 35.500000000 7.500000000 -4.500000000 35.500000000 7.500000000 -3.500000000 35.500000000 7.500000000 -2.500000000 35.500000000 7.500000000 -1.500000000 35.500000000 7.500000000 -0.500000000 35.500000000 7.500000000 0.500000000 35.500000000 7.500000000 1.500000000 35.500000000 7.500000000 2.500000000 35.500000000 7.500000000 3.500000000 35.500000000 7.500000000 4.500000000 35.500000000 7.500000000 5.500000000 35.500000000 7.500000000 6.500000000 35.500000000 7.500000000 7.500000000 35.500000000 7.500000000 8.500000000 35.500000000 7.500000000 9.500000000 35.500000000 7.500000000 10.500000000 35.500000000 7.500000000 11.500000000 35.500000000 7.500000000 12.500000000 35.500000000 7.500000000 13.500000000 35.500000000 7.500000000 14.500000000 35.500000000 7.500000000 15.500000000 35.500000000 7.500000000 16.500000000 35.500000000 7.500000000 17.500000000 35.500000000 7.500000000 18.500000000 35.500000000 7.500000000 19.500000000 35.500000000 7.500000000 20.500000000 35.500000000 7.500000000 21.500000000 35.500000000 7.500000000 22.500000000 35.500000000 7.500000000 23.500000000 35.500000000 7.500000000 24.500000000 35.500000000 7.500000000 25.499996185 35.499996185 7.500000000 26.499954224 35.499954224 7.500000000 27.499591827 35.499591827 7.500000000 28.497470856 35.497474670 7.500000000 29.488407135 35.488403320 7.500000000 30.458978653 35.458980560 7.500000000 31.384418488 35.384422302 7.500000000 32.233222961 35.233222961 7.500000000 32.981101990 34.981101990 7.500000000 -33.981101990 -35.981101990 8.500000000 -33.233226776 -36.233222961 8.500000000 -32.384422302 -36.384418488 8.500000000 -31.458978653 -36.458980560 8.500000000 -30.488407135 -36.488403320 8.500000000 -29.497472763 -36.497474670 8.500000000 -28.499593735 -36.499591827 8.500000000 -27.499954224 -36.499954224 8.500000000 -26.499996185 -36.499996185 8.500000000 -25.500000000 -36.500000000 8.500000000 -24.500000000 -36.500000000 8.500000000 -23.500000000 -36.500000000 8.500000000 -22.500000000 -36.500000000 8.500000000 -21.500000000 -36.500000000 8.500000000 -20.500000000 -36.500000000 8.500000000 -19.500000000 -36.500000000 8.500000000 -18.500000000 -36.500000000 8.500000000 -17.500000000 -36.500000000 8.500000000 -16.500000000 -36.500000000 8.500000000 -15.500000000 -36.500000000 8.500000000 -14.500000000 -36.500000000 8.500000000 -13.500000000 -36.500000000 8.500000000 -12.500000000 -36.500000000 8.500000000 -11.500000000 -36.500000000 8.500000000 -10.500000000 -36.500000000 8.500000000 -9.500000000 -36.500000000 8.500000000 -8.500000000 -36.500000000 8.500000000 -7.500000000 -36.500000000 8.500000000 -6.500000000 -36.500000000 8.500000000 -5.500000000 -36.500000000 8.500000000 -4.500000000 -36.500000000 8.500000000 -3.500000000 -36.500000000 8.500000000 -2.500000000 -36.500000000 8.500000000 -1.500000000 -36.500000000 8.500000000 -0.500000000 -36.500000000 8.500000000 0.500000000 -36.500000000 8.500000000 1.500000000 -36.500000000 8.500000000 2.500000000 -36.500000000 8.500000000 3.500000000 -36.500000000 8.500000000 4.500000000 -36.500000000 8.500000000 5.500000000 -36.500000000 8.500000000 6.500000000 -36.500000000 8.500000000 7.500000000 -36.500000000 8.500000000 8.500000000 -36.500000000 8.500000000 9.500000000 -36.500000000 8.500000000 10.500000000 -36.500000000 8.500000000 11.500000000 -36.500000000 8.500000000 12.500000000 -36.500000000 8.500000000 13.500000000 -36.500000000 8.500000000 14.500000000 -36.500000000 8.500000000 15.500000000 -36.500000000 8.500000000 16.500000000 -36.500000000 8.500000000 17.500000000 -36.500000000 8.500000000 18.500000000 -36.500000000 8.500000000 19.500000000 -36.500000000 8.500000000 20.500000000 -36.500000000 8.500000000 21.500000000 -36.500000000 8.500000000 22.500000000 -36.500000000 8.500000000 23.500000000 -36.500000000 8.500000000 24.500000000 -36.500000000 8.500000000 25.499996185 -36.499996185 8.500000000 26.499954224 -36.499954224 8.500000000 27.499591827 -36.499591827 8.500000000 28.497470856 -36.497467041 8.500000000 29.488407135 -36.488403320 8.500000000 30.458978653 -36.458980560 8.500000000 31.384418488 -36.384422302 8.500000000 32.233222961 -36.233222961 8.500000000 32.981101990 -35.981101990 8.500000000 -35.167964935 -35.167964935 8.500000000 -34.622871399 -35.622871399 8.500000000 33.622871399 -35.622871399 8.500000000 34.167964935 -35.167964935 8.500000000 -35.981101990 -33.981101990 8.500000000 -35.622871399 -34.622871399 8.500000000 34.622871399 -34.622871399 8.500000000 34.981101990 -33.981101990 8.500000000 -36.233222961 -33.233222961 8.500000000 35.233222961 -33.233226776 8.500000000 -36.384418488 -32.384422302 8.500000000 35.384418488 -32.384422302 8.500000000 -36.458976746 -31.458978653 8.500000000 35.458980560 -31.458978653 8.500000000 -36.488403320 -30.488407135 8.500000000 35.488403320 -30.488407135 8.500000000 -36.497467041 -29.497472763 8.500000000 35.497474670 -29.497472763 8.500000000 -36.499591827 -28.499593735 8.500000000 35.499591827 -28.499593735 8.500000000 -36.499954224 -27.499954224 8.500000000 35.499954224 -27.499954224 8.500000000 -36.499996185 -26.499996185 8.500000000 35.499996185 -26.499996185 8.500000000 -36.500000000 -25.500000000 8.500000000 35.500000000 -25.500000000 8.500000000 -36.500000000 -24.500000000 8.500000000 35.500000000 -24.500000000 8.500000000 -36.500000000 -23.500000000 8.500000000 35.500000000 -23.500000000 8.500000000 -36.500000000 -22.500000000 8.500000000 35.500000000 -22.500000000 8.500000000 -36.500000000 -21.500000000 8.500000000 35.500000000 -21.500000000 8.500000000 -36.500000000 -20.500000000 8.500000000 35.500000000 -20.500000000 8.500000000 -36.500000000 -19.500000000 8.500000000 35.500000000 -19.500000000 8.500000000 -36.500000000 -18.500000000 8.500000000 35.500000000 -18.500000000 8.500000000 -36.500000000 -17.500000000 8.500000000 35.500000000 -17.500000000 8.500000000 -36.500000000 -16.500000000 8.500000000 35.500000000 -16.500000000 8.500000000 -36.500000000 -15.500000000 8.500000000 35.500000000 -15.500000000 8.500000000 -36.500000000 -14.500000000 8.500000000 35.500000000 -14.500000000 8.500000000 -36.500000000 -13.500000000 8.500000000 35.500000000 -13.500000000 8.500000000 -36.500000000 -12.500000000 8.500000000 35.500000000 -12.500000000 8.500000000 -36.500000000 -11.500000000 8.500000000 35.500000000 -11.500000000 8.500000000 -36.500000000 -10.500000000 8.500000000 35.500000000 -10.500000000 8.500000000 -36.500000000 -9.500000000 8.500000000 35.500000000 -9.500000000 8.500000000 -36.500000000 -8.500000000 8.500000000 35.500000000 -8.500000000 8.500000000 -36.500000000 -7.500000000 8.500000000 35.500000000 -7.500000000 8.500000000 -36.500000000 -6.500000000 8.500000000 35.500000000 -6.500000000 8.500000000 -36.500000000 -5.500000000 8.500000000 35.500000000 -5.500000000 8.500000000 -36.500000000 -4.500000000 8.500000000 35.500000000 -4.500000000 8.500000000 -36.500000000 -3.500000000 8.500000000 35.500000000 -3.500000000 8.500000000 -36.500000000 -2.500000000 8.500000000 35.500000000 -2.500000000 8.500000000 -36.500000000 -1.500000000 8.500000000 35.500000000 -1.500000000 8.500000000 -36.500000000 -0.500000000 8.500000000 35.500000000 -0.500000000 8.500000000 -36.500000000 0.500000000 8.500000000 35.500000000 0.500000000 8.500000000 -36.500000000 1.500000000 8.500000000 35.500000000 1.500000000 8.500000000 -36.500000000 2.500000000 8.500000000 35.500000000 2.500000000 8.500000000 -36.500000000 3.500000000 8.500000000 35.500000000 3.500000000 8.500000000 -36.500000000 4.500000000 8.500000000 35.500000000 4.500000000 8.500000000 -36.500000000 5.500000000 8.500000000 35.500000000 5.500000000 8.500000000 -36.500000000 6.500000000 8.500000000 35.500000000 6.500000000 8.500000000 -36.500000000 7.500000000 8.500000000 35.500000000 7.500000000 8.500000000 -36.500000000 8.500000000 8.500000000 35.500000000 8.500000000 8.500000000 -36.500000000 9.500000000 8.500000000 35.500000000 9.500000000 8.500000000 -36.500000000 10.500000000 8.500000000 35.500000000 10.500000000 8.500000000 -36.500000000 11.500000000 8.500000000 35.500000000 11.500000000 8.500000000 -36.500000000 12.500000000 8.500000000 35.500000000 12.500000000 8.500000000 -36.500000000 13.500000000 8.500000000 35.500000000 13.500000000 8.500000000 -36.500000000 14.500000000 8.500000000 35.500000000 14.500000000 8.500000000 -36.500000000 15.500000000 8.500000000 35.500000000 15.500000000 8.500000000 -36.500000000 16.500000000 8.500000000 35.500000000 16.500000000 8.500000000 -36.500000000 17.500000000 8.500000000 35.500000000 17.500000000 8.500000000 -36.500000000 18.500000000 8.500000000 35.500000000 18.500000000 8.500000000 -36.500000000 19.500000000 8.500000000 35.500000000 19.500000000 8.500000000 -36.500000000 20.500000000 8.500000000 35.500000000 20.500000000 8.500000000 -36.500000000 21.500000000 8.500000000 35.500000000 21.500000000 8.500000000 -36.500000000 22.500000000 8.500000000 35.500000000 22.500000000 8.500000000 -36.500000000 23.500000000 8.500000000 35.500000000 23.500000000 8.500000000 -36.500000000 24.500000000 8.500000000 35.500000000 24.500000000 8.500000000 -36.499996185 25.499996185 8.500000000 35.499996185 25.499996185 8.500000000 -36.499954224 26.499954224 8.500000000 35.499954224 26.499954224 8.500000000 -36.499591827 27.499591827 8.500000000 35.499591827 27.499591827 8.500000000 -36.497474670 28.497470856 8.500000000 35.497467041 28.497470856 8.500000000 -36.488403320 29.488407135 8.500000000 35.488403320 29.488407135 8.500000000 -36.458980560 30.458978653 8.500000000 35.458980560 30.458978653 8.500000000 -36.384422302 31.384418488 8.500000000 35.384422302 31.384418488 8.500000000 -36.233222961 32.233222961 8.500000000 35.233222961 32.233222961 8.500000000 -35.981101990 32.981101990 8.500000000 -35.622871399 33.622871399 8.500000000 34.622871399 33.622871399 8.500000000 34.981101990 32.981101990 8.500000000 -35.167964935 34.167964935 8.500000000 -34.622871399 34.622871399 8.500000000 33.622871399 34.622871399 8.500000000 34.167964935 34.167964935 8.500000000 -33.981101990 34.981101990 8.500000000 -33.233222961 35.233222961 8.500000000 -32.384422302 35.384418488 8.500000000 -31.458978653 35.458976746 8.500000000 -30.488407135 35.488403320 8.500000000 -29.497472763 35.497467041 8.500000000 -28.499593735 35.499591827 8.500000000 -27.499954224 35.499954224 8.500000000 -26.499996185 35.499996185 8.500000000 -25.500000000 35.500000000 8.500000000 -24.500000000 35.500000000 8.500000000 -23.500000000 35.500000000 8.500000000 -22.500000000 35.500000000 8.500000000 -21.500000000 35.500000000 8.500000000 -20.500000000 35.500000000 8.500000000 -19.500000000 35.500000000 8.500000000 -18.500000000 35.500000000 8.500000000 -17.500000000 35.500000000 8.500000000 -16.500000000 35.500000000 8.500000000 -15.500000000 35.500000000 8.500000000 -14.500000000 35.500000000 8.500000000 -13.500000000 35.500000000 8.500000000 -12.500000000 35.500000000 8.500000000 -11.500000000 35.500000000 8.500000000 -10.500000000 35.500000000 8.500000000 -9.500000000 35.500000000 8.500000000 -8.500000000 35.500000000 8.500000000 -7.500000000 35.500000000 8.500000000 -6.500000000 35.500000000 8.500000000 -5.500000000 35.500000000 8.500000000 -4.500000000 35.500000000 8.500000000 -3.500000000 35.500000000 8.500000000 -2.500000000 35.500000000 8.500000000 -1.500000000 35.500000000 8.500000000 -0.500000000 35.500000000 8.500000000 0.500000000 35.500000000 8.500000000 1.500000000 35.500000000 8.500000000 2.500000000 35.500000000 8.500000000 3.500000000 35.500000000 8.500000000 4.500000000 35.500000000 8.500000000 5.500000000 35.500000000 8.500000000 6.500000000 35.500000000 8.500000000 7.500000000 35.500000000 8.500000000 8.500000000 35.500000000 8.500000000 9.500000000 35.500000000 8.500000000 10.500000000 35.500000000 8.500000000 11.500000000 35.500000000 8.500000000 12.500000000 35.500000000 8.500000000 13.500000000 35.500000000 8.500000000 14.500000000 35.500000000 8.500000000 15.500000000 35.500000000 8.500000000 16.500000000 35.500000000 8.500000000 17.500000000 35.500000000 8.500000000 18.500000000 35.500000000 8.500000000 19.500000000 35.500000000 8.500000000 20.500000000 35.500000000 8.500000000 21.500000000 35.500000000 8.500000000 22.500000000 35.500000000 8.500000000 23.500000000 35.500000000 8.500000000 24.500000000 35.500000000 8.500000000 25.499996185 35.499996185 8.500000000 26.499954224 35.499954224 8.500000000 27.499591827 35.499591827 8.500000000 28.497470856 35.497474670 8.500000000 29.488407135 35.488403320 8.500000000 30.458978653 35.458980560 8.500000000 31.384418488 35.384422302 8.500000000 32.233222961 35.233222961 8.500000000 32.981101990 34.981101990 8.500000000 -33.981101990 -35.981101990 9.500000000 -33.233226776 -36.233222961 9.500000000 -32.384422302 -36.384418488 9.500000000 -31.458978653 -36.458980560 9.500000000 -30.488407135 -36.488403320 9.500000000 -29.497472763 -36.497474670 9.500000000 -28.499593735 -36.499591827 9.500000000 -27.499954224 -36.499954224 9.500000000 -26.499996185 -36.499996185 9.500000000 -25.500000000 -36.500000000 9.500000000 -24.500000000 -36.500000000 9.500000000 -23.500000000 -36.500000000 9.500000000 -22.500000000 -36.500000000 9.500000000 -21.500000000 -36.500000000 9.500000000 -20.500000000 -36.500000000 9.500000000 -19.500000000 -36.500000000 9.500000000 -18.500000000 -36.500000000 9.500000000 -17.500000000 -36.500000000 9.500000000 -16.500000000 -36.500000000 9.500000000 -15.500000000 -36.500000000 9.500000000 -14.500000000 -36.500000000 9.500000000 -13.500000000 -36.500000000 9.500000000 -12.500000000 -36.500000000 9.500000000 -11.500000000 -36.500000000 9.500000000 -10.500000000 -36.500000000 9.500000000 -9.500000000 -36.500000000 9.500000000 -8.500000000 -36.500000000 9.500000000 -7.500000000 -36.500000000 9.500000000 -6.500000000 -36.500000000 9.500000000 -5.500000000 -36.500000000 9.500000000 -4.500000000 -36.500000000 9.500000000 -3.500000000 -36.500000000 9.500000000 -2.500000000 -36.500000000 9.500000000 -1.500000000 -36.500000000 9.500000000 -0.500000000 -36.500000000 9.500000000 0.500000000 -36.500000000 9.500000000 1.500000000 -36.500000000 9.500000000 2.500000000 -36.500000000 9.500000000 3.500000000 -36.500000000 9.500000000 4.500000000 -36.500000000 9.500000000 5.500000000 -36.500000000 9.500000000 6.500000000 -36.500000000 9.500000000 7.500000000 -36.500000000 9.500000000 8.500000000 -36.500000000 9.500000000 9.500000000 -36.500000000 9.500000000 10.500000000 -36.500000000 9.500000000 11.500000000 -36.500000000 9.500000000 12.500000000 -36.500000000 9.500000000 13.500000000 -36.500000000 9.500000000 14.500000000 -36.500000000 9.500000000 15.500000000 -36.500000000 9.500000000 16.500000000 -36.500000000 9.500000000 17.500000000 -36.500000000 9.500000000 18.500000000 -36.500000000 9.500000000 19.500000000 -36.500000000 9.500000000 20.500000000 -36.500000000 9.500000000 21.500000000 -36.500000000 9.500000000 22.500000000 -36.500000000 9.500000000 23.500000000 -36.500000000 9.500000000 24.500000000 -36.500000000 9.500000000 25.499996185 -36.499996185 9.500000000 26.499954224 -36.499954224 9.500000000 27.499591827 -36.499591827 9.500000000 28.497470856 -36.497467041 9.500000000 29.488407135 -36.488403320 9.500000000 30.458978653 -36.458980560 9.500000000 31.384418488 -36.384422302 9.500000000 32.233222961 -36.233222961 9.500000000 32.981101990 -35.981101990 9.500000000 -35.167964935 -35.167964935 9.500000000 -34.622871399 -35.622871399 9.500000000 33.622871399 -35.622871399 9.500000000 34.167964935 -35.167964935 9.500000000 -35.981101990 -33.981101990 9.500000000 -35.622871399 -34.622871399 9.500000000 34.622871399 -34.622871399 9.500000000 34.981101990 -33.981101990 9.500000000 -36.233222961 -33.233222961 9.500000000 35.233222961 -33.233226776 9.500000000 -36.384418488 -32.384422302 9.500000000 35.384418488 -32.384422302 9.500000000 -36.458976746 -31.458978653 9.500000000 35.458980560 -31.458978653 9.500000000 -36.488403320 -30.488407135 9.500000000 35.488403320 -30.488407135 9.500000000 -36.497467041 -29.497472763 9.500000000 35.497474670 -29.497472763 9.500000000 -36.499591827 -28.499593735 9.500000000 35.499591827 -28.499593735 9.500000000 -36.499954224 -27.499954224 9.500000000 35.499954224 -27.499954224 9.500000000 -36.499996185 -26.499996185 9.500000000 35.499996185 -26.499996185 9.500000000 -36.500000000 -25.500000000 9.500000000 35.500000000 -25.500000000 9.500000000 -36.500000000 -24.500000000 9.500000000 35.500000000 -24.500000000 9.500000000 -36.500000000 -23.500000000 9.500000000 35.500000000 -23.500000000 9.500000000 -36.500000000 -22.500000000 9.500000000 35.500000000 -22.500000000 9.500000000 -36.500000000 -21.500000000 9.500000000 35.500000000 -21.500000000 9.500000000 -36.500000000 -20.500000000 9.500000000 35.500000000 -20.500000000 9.500000000 -36.500000000 -19.500000000 9.500000000 35.500000000 -19.500000000 9.500000000 -36.500000000 -18.500000000 9.500000000 35.500000000 -18.500000000 9.500000000 -36.500000000 -17.500000000 9.500000000 35.500000000 -17.500000000 9.500000000 -36.500000000 -16.500000000 9.500000000 35.500000000 -16.500000000 9.500000000 -36.500000000 -15.500000000 9.500000000 35.500000000 -15.500000000 9.500000000 -36.500000000 -14.500000000 9.500000000 35.500000000 -14.500000000 9.500000000 -36.500000000 -13.500000000 9.500000000 35.500000000 -13.500000000 9.500000000 -36.500000000 -12.500000000 9.500000000 35.500000000 -12.500000000 9.500000000 -36.500000000 -11.500000000 9.500000000 35.500000000 -11.500000000 9.500000000 -36.500000000 -10.500000000 9.500000000 35.500000000 -10.500000000 9.500000000 -36.500000000 -9.500000000 9.500000000 35.500000000 -9.500000000 9.500000000 -36.500000000 -8.500000000 9.500000000 35.500000000 -8.500000000 9.500000000 -36.500000000 -7.500000000 9.500000000 35.500000000 -7.500000000 9.500000000 -36.500000000 -6.500000000 9.500000000 35.500000000 -6.500000000 9.500000000 -36.500000000 -5.500000000 9.500000000 35.500000000 -5.500000000 9.500000000 -36.500000000 -4.500000000 9.500000000 35.500000000 -4.500000000 9.500000000 -36.500000000 -3.500000000 9.500000000 35.500000000 -3.500000000 9.500000000 -36.500000000 -2.500000000 9.500000000 35.500000000 -2.500000000 9.500000000 -36.500000000 -1.500000000 9.500000000 35.500000000 -1.500000000 9.500000000 -36.500000000 -0.500000000 9.500000000 35.500000000 -0.500000000 9.500000000 -36.500000000 0.500000000 9.500000000 35.500000000 0.500000000 9.500000000 -36.500000000 1.500000000 9.500000000 35.500000000 1.500000000 9.500000000 -36.500000000 2.500000000 9.500000000 35.500000000 2.500000000 9.500000000 -36.500000000 3.500000000 9.500000000 35.500000000 3.500000000 9.500000000 -36.500000000 4.500000000 9.500000000 35.500000000 4.500000000 9.500000000 -36.500000000 5.500000000 9.500000000 35.500000000 5.500000000 9.500000000 -36.500000000 6.500000000 9.500000000 35.500000000 6.500000000 9.500000000 -36.500000000 7.500000000 9.500000000 35.500000000 7.500000000 9.500000000 -36.500000000 8.500000000 9.500000000 35.500000000 8.500000000 9.500000000 -36.500000000 9.500000000 9.500000000 35.500000000 9.500000000 9.500000000 -36.500000000 10.500000000 9.500000000 35.500000000 10.500000000 9.500000000 -36.500000000 11.500000000 9.500000000 35.500000000 11.500000000 9.500000000 -36.500000000 12.500000000 9.500000000 35.500000000 12.500000000 9.500000000 -36.500000000 13.500000000 9.500000000 35.500000000 13.500000000 9.500000000 -36.500000000 14.500000000 9.500000000 35.500000000 14.500000000 9.500000000 -36.500000000 15.500000000 9.500000000 35.500000000 15.500000000 9.500000000 -36.500000000 16.500000000 9.500000000 35.500000000 16.500000000 9.500000000 -36.500000000 17.500000000 9.500000000 35.500000000 17.500000000 9.500000000 -36.500000000 18.500000000 9.500000000 35.500000000 18.500000000 9.500000000 -36.500000000 19.500000000 9.500000000 35.500000000 19.500000000 9.500000000 -36.500000000 20.500000000 9.500000000 35.500000000 20.500000000 9.500000000 -36.500000000 21.500000000 9.500000000 35.500000000 21.500000000 9.500000000 -36.500000000 22.500000000 9.500000000 35.500000000 22.500000000 9.500000000 -36.500000000 23.500000000 9.500000000 35.500000000 23.500000000 9.500000000 -36.500000000 24.500000000 9.500000000 35.500000000 24.500000000 9.500000000 -36.499996185 25.499996185 9.500000000 35.499996185 25.499996185 9.500000000 -36.499954224 26.499954224 9.500000000 35.499954224 26.499954224 9.500000000 -36.499591827 27.499591827 9.500000000 35.499591827 27.499591827 9.500000000 -36.497474670 28.497470856 9.500000000 35.497467041 28.497470856 9.500000000 -36.488403320 29.488407135 9.500000000 35.488403320 29.488407135 9.500000000 -36.458980560 30.458978653 9.500000000 35.458980560 30.458978653 9.500000000 -36.384422302 31.384418488 9.500000000 35.384422302 31.384418488 9.500000000 -36.233222961 32.233222961 9.500000000 35.233222961 32.233222961 9.500000000 -35.981101990 32.981101990 9.500000000 -35.622871399 33.622871399 9.500000000 34.622871399 33.622871399 9.500000000 34.981101990 32.981101990 9.500000000 -35.167964935 34.167964935 9.500000000 -34.622871399 34.622871399 9.500000000 33.622871399 34.622871399 9.500000000 34.167964935 34.167964935 9.500000000 -33.981101990 34.981101990 9.500000000 -33.233222961 35.233222961 9.500000000 -32.384422302 35.384418488 9.500000000 -31.458978653 35.458976746 9.500000000 -30.488407135 35.488403320 9.500000000 -29.497472763 35.497467041 9.500000000 -28.499593735 35.499591827 9.500000000 -27.499954224 35.499954224 9.500000000 -26.499996185 35.499996185 9.500000000 -25.500000000 35.500000000 9.500000000 -24.500000000 35.500000000 9.500000000 -23.500000000 35.500000000 9.500000000 -22.500000000 35.500000000 9.500000000 -21.500000000 35.500000000 9.500000000 -20.500000000 35.500000000 9.500000000 -19.500000000 35.500000000 9.500000000 -18.500000000 35.500000000 9.500000000 -17.500000000 35.500000000 9.500000000 -16.500000000 35.500000000 9.500000000 -15.500000000 35.500000000 9.500000000 -14.500000000 35.500000000 9.500000000 -13.500000000 35.500000000 9.500000000 -12.500000000 35.500000000 9.500000000 -11.500000000 35.500000000 9.500000000 -10.500000000 35.500000000 9.500000000 -9.500000000 35.500000000 9.500000000 -8.500000000 35.500000000 9.500000000 -7.500000000 35.500000000 9.500000000 -6.500000000 35.500000000 9.500000000 -5.500000000 35.500000000 9.500000000 -4.500000000 35.500000000 9.500000000 -3.500000000 35.500000000 9.500000000 -2.500000000 35.500000000 9.500000000 -1.500000000 35.500000000 9.500000000 -0.500000000 35.500000000 9.500000000 0.500000000 35.500000000 9.500000000 1.500000000 35.500000000 9.500000000 2.500000000 35.500000000 9.500000000 3.500000000 35.500000000 9.500000000 4.500000000 35.500000000 9.500000000 5.500000000 35.500000000 9.500000000 6.500000000 35.500000000 9.500000000 7.500000000 35.500000000 9.500000000 8.500000000 35.500000000 9.500000000 9.500000000 35.500000000 9.500000000 10.500000000 35.500000000 9.500000000 11.500000000 35.500000000 9.500000000 12.500000000 35.500000000 9.500000000 13.500000000 35.500000000 9.500000000 14.500000000 35.500000000 9.500000000 15.500000000 35.500000000 9.500000000 16.500000000 35.500000000 9.500000000 17.500000000 35.500000000 9.500000000 18.500000000 35.500000000 9.500000000 19.500000000 35.500000000 9.500000000 20.500000000 35.500000000 9.500000000 21.500000000 35.500000000 9.500000000 22.500000000 35.500000000 9.500000000 23.500000000 35.500000000 9.500000000 24.500000000 35.500000000 9.500000000 25.499996185 35.499996185 9.500000000 26.499954224 35.499954224 9.500000000 27.499591827 35.499591827 9.500000000 28.497470856 35.497474670 9.500000000 29.488407135 35.488403320 9.500000000 30.458978653 35.458980560 9.500000000 31.384418488 35.384422302 9.500000000 32.233222961 35.233222961 9.500000000 32.981101990 34.981101990 9.500000000 -33.981101990 -35.981101990 10.500000000 -33.233226776 -36.233222961 10.500000000 -32.384422302 -36.384418488 10.500000000 -31.458978653 -36.458980560 10.500000000 -30.488407135 -36.488403320 10.500000000 -29.497472763 -36.497474670 10.500000000 -28.499593735 -36.499591827 10.500000000 -27.499954224 -36.499954224 10.500000000 -26.499996185 -36.499996185 10.500000000 -25.500000000 -36.500000000 10.500000000 -24.500000000 -36.500000000 10.500000000 -23.500000000 -36.500000000 10.500000000 -22.500000000 -36.500000000 10.500000000 -21.500000000 -36.500000000 10.500000000 -20.500000000 -36.500000000 10.500000000 -19.500000000 -36.500000000 10.500000000 -18.500000000 -36.500000000 10.500000000 -17.500000000 -36.500000000 10.500000000 -16.500000000 -36.500000000 10.500000000 -15.500000000 -36.500000000 10.500000000 -14.500000000 -36.500000000 10.500000000 -13.500000000 -36.500000000 10.500000000 -12.500000000 -36.500000000 10.500000000 -11.500000000 -36.500000000 10.500000000 -10.500000000 -36.500000000 10.500000000 -9.500000000 -36.500000000 10.500000000 -8.500000000 -36.500000000 10.500000000 -7.500000000 -36.500000000 10.500000000 -6.500000000 -36.500000000 10.500000000 -5.500000000 -36.500000000 10.500000000 -4.500000000 -36.500000000 10.500000000 -3.500000000 -36.500000000 10.500000000 -2.500000000 -36.500000000 10.500000000 -1.500000000 -36.500000000 10.500000000 -0.500000000 -36.500000000 10.500000000 0.500000000 -36.500000000 10.500000000 1.500000000 -36.500000000 10.500000000 2.500000000 -36.500000000 10.500000000 3.500000000 -36.500000000 10.500000000 4.500000000 -36.500000000 10.500000000 5.500000000 -36.500000000 10.500000000 6.500000000 -36.500000000 10.500000000 7.500000000 -36.500000000 10.500000000 8.500000000 -36.500000000 10.500000000 9.500000000 -36.500000000 10.500000000 10.500000000 -36.500000000 10.500000000 11.500000000 -36.500000000 10.500000000 12.500000000 -36.500000000 10.500000000 13.500000000 -36.500000000 10.500000000 14.500000000 -36.500000000 10.500000000 15.500000000 -36.500000000 10.500000000 16.500000000 -36.500000000 10.500000000 17.500000000 -36.500000000 10.500000000 18.500000000 -36.500000000 10.500000000 19.500000000 -36.500000000 10.500000000 20.500000000 -36.500000000 10.500000000 21.500000000 -36.500000000 10.500000000 22.500000000 -36.500000000 10.500000000 23.500000000 -36.500000000 10.500000000 24.500000000 -36.500000000 10.500000000 25.499996185 -36.499996185 10.500000000 26.499954224 -36.499954224 10.500000000 27.499591827 -36.499591827 10.500000000 28.497470856 -36.497467041 10.500000000 29.488407135 -36.488403320 10.500000000 30.458978653 -36.458980560 10.500000000 31.384418488 -36.384422302 10.500000000 32.233222961 -36.233222961 10.500000000 32.981101990 -35.981101990 10.500000000 -35.167964935 -35.167964935 10.500000000 -34.622871399 -35.622871399 10.500000000 33.622871399 -35.622871399 10.500000000 34.167964935 -35.167964935 10.500000000 -35.981101990 -33.981101990 10.500000000 -35.622871399 -34.622871399 10.500000000 34.622871399 -34.622871399 10.500000000 34.981101990 -33.981101990 10.500000000 -36.233222961 -33.233222961 10.500000000 35.233222961 -33.233226776 10.500000000 -36.384418488 -32.384422302 10.500000000 35.384418488 -32.384422302 10.500000000 -36.458976746 -31.458978653 10.500000000 35.458980560 -31.458978653 10.500000000 -36.488403320 -30.488407135 10.500000000 35.488403320 -30.488407135 10.500000000 -36.497467041 -29.497472763 10.500000000 35.497474670 -29.497472763 10.500000000 -36.499591827 -28.499593735 10.500000000 35.499591827 -28.499593735 10.500000000 -36.499954224 -27.499954224 10.500000000 35.499954224 -27.499954224 10.500000000 -36.499996185 -26.499996185 10.500000000 35.499996185 -26.499996185 10.500000000 -36.500000000 -25.500000000 10.500000000 35.500000000 -25.500000000 10.500000000 -36.500000000 -24.500000000 10.500000000 35.500000000 -24.500000000 10.500000000 -36.500000000 -23.500000000 10.500000000 35.500000000 -23.500000000 10.500000000 -36.500000000 -22.500000000 10.500000000 35.500000000 -22.500000000 10.500000000 -36.500000000 -21.500000000 10.500000000 35.500000000 -21.500000000 10.500000000 -36.500000000 -20.500000000 10.500000000 35.500000000 -20.500000000 10.500000000 -36.500000000 -19.500000000 10.500000000 35.500000000 -19.500000000 10.500000000 -36.500000000 -18.500000000 10.500000000 35.500000000 -18.500000000 10.500000000 -36.500000000 -17.500000000 10.500000000 35.500000000 -17.500000000 10.500000000 -36.500000000 -16.500000000 10.500000000 35.500000000 -16.500000000 10.500000000 -36.500000000 -15.500000000 10.500000000 35.500000000 -15.500000000 10.500000000 -36.500000000 -14.500000000 10.500000000 35.500000000 -14.500000000 10.500000000 -36.500000000 -13.500000000 10.500000000 35.500000000 -13.500000000 10.500000000 -36.500000000 -12.500000000 10.500000000 35.500000000 -12.500000000 10.500000000 -36.500000000 -11.500000000 10.500000000 35.500000000 -11.500000000 10.500000000 -36.500000000 -10.500000000 10.500000000 35.500000000 -10.500000000 10.500000000 -36.500000000 -9.500000000 10.500000000 35.500000000 -9.500000000 10.500000000 -36.500000000 -8.500000000 10.500000000 35.500000000 -8.500000000 10.500000000 -36.500000000 -7.500000000 10.500000000 35.500000000 -7.500000000 10.500000000 -36.500000000 -6.500000000 10.500000000 35.500000000 -6.500000000 10.500000000 -36.500000000 -5.500000000 10.500000000 35.500000000 -5.500000000 10.500000000 -36.500000000 -4.500000000 10.500000000 35.500000000 -4.500000000 10.500000000 -36.500000000 -3.500000000 10.500000000 35.500000000 -3.500000000 10.500000000 -36.500000000 -2.500000000 10.500000000 35.500000000 -2.500000000 10.500000000 -36.500000000 -1.500000000 10.500000000 35.500000000 -1.500000000 10.500000000 -36.500000000 -0.500000000 10.500000000 35.500000000 -0.500000000 10.500000000 -36.500000000 0.500000000 10.500000000 35.500000000 0.500000000 10.500000000 -36.500000000 1.500000000 10.500000000 35.500000000 1.500000000 10.500000000 -36.500000000 2.500000000 10.500000000 35.500000000 2.500000000 10.500000000 -36.500000000 3.500000000 10.500000000 35.500000000 3.500000000 10.500000000 -36.500000000 4.500000000 10.500000000 35.500000000 4.500000000 10.500000000 -36.500000000 5.500000000 10.500000000 35.500000000 5.500000000 10.500000000 -36.500000000 6.500000000 10.500000000 35.500000000 6.500000000 10.500000000 -36.500000000 7.500000000 10.500000000 35.500000000 7.500000000 10.500000000 -36.500000000 8.500000000 10.500000000 35.500000000 8.500000000 10.500000000 -36.500000000 9.500000000 10.500000000 35.500000000 9.500000000 10.500000000 -36.500000000 10.500000000 10.500000000 35.500000000 10.500000000 10.500000000 -36.500000000 11.500000000 10.500000000 35.500000000 11.500000000 10.500000000 -36.500000000 12.500000000 10.500000000 35.500000000 12.500000000 10.500000000 -36.500000000 13.500000000 10.500000000 35.500000000 13.500000000 10.500000000 -36.500000000 14.500000000 10.500000000 35.500000000 14.500000000 10.500000000 -36.500000000 15.500000000 10.500000000 35.500000000 15.500000000 10.500000000 -36.500000000 16.500000000 10.500000000 35.500000000 16.500000000 10.500000000 -36.500000000 17.500000000 10.500000000 35.500000000 17.500000000 10.500000000 -36.500000000 18.500000000 10.500000000 35.500000000 18.500000000 10.500000000 -36.500000000 19.500000000 10.500000000 35.500000000 19.500000000 10.500000000 -36.500000000 20.500000000 10.500000000 35.500000000 20.500000000 10.500000000 -36.500000000 21.500000000 10.500000000 35.500000000 21.500000000 10.500000000 -36.500000000 22.500000000 10.500000000 35.500000000 22.500000000 10.500000000 -36.500000000 23.500000000 10.500000000 35.500000000 23.500000000 10.500000000 -36.500000000 24.500000000 10.500000000 35.500000000 24.500000000 10.500000000 -36.499996185 25.499996185 10.500000000 35.499996185 25.499996185 10.500000000 -36.499954224 26.499954224 10.500000000 35.499954224 26.499954224 10.500000000 -36.499591827 27.499591827 10.500000000 35.499591827 27.499591827 10.500000000 -36.497474670 28.497470856 10.500000000 35.497467041 28.497470856 10.500000000 -36.488403320 29.488407135 10.500000000 35.488403320 29.488407135 10.500000000 -36.458980560 30.458978653 10.500000000 35.458980560 30.458978653 10.500000000 -36.384422302 31.384418488 10.500000000 35.384422302 31.384418488 10.500000000 -36.233222961 32.233222961 10.500000000 35.233222961 32.233222961 10.500000000 -35.981101990 32.981101990 10.500000000 -35.622871399 33.622871399 10.500000000 34.622871399 33.622871399 10.500000000 34.981101990 32.981101990 10.500000000 -35.167964935 34.167964935 10.500000000 -34.622871399 34.622871399 10.500000000 33.622871399 34.622871399 10.500000000 34.167964935 34.167964935 10.500000000 -33.981101990 34.981101990 10.500000000 -33.233222961 35.233222961 10.500000000 -32.384422302 35.384418488 10.500000000 -31.458978653 35.458976746 10.500000000 -30.488407135 35.488403320 10.500000000 -29.497472763 35.497467041 10.500000000 -28.499593735 35.499591827 10.500000000 -27.499954224 35.499954224 10.500000000 -26.499996185 35.499996185 10.500000000 -25.500000000 35.500000000 10.500000000 -24.500000000 35.500000000 10.500000000 -23.500000000 35.500000000 10.500000000 -22.500000000 35.500000000 10.500000000 -21.500000000 35.500000000 10.500000000 -20.500000000 35.500000000 10.500000000 -19.500000000 35.500000000 10.500000000 -18.500000000 35.500000000 10.500000000 -17.500000000 35.500000000 10.500000000 -16.500000000 35.500000000 10.500000000 -15.500000000 35.500000000 10.500000000 -14.500000000 35.500000000 10.500000000 -13.500000000 35.500000000 10.500000000 -12.500000000 35.500000000 10.500000000 -11.500000000 35.500000000 10.500000000 -10.500000000 35.500000000 10.500000000 -9.500000000 35.500000000 10.500000000 -8.500000000 35.500000000 10.500000000 -7.500000000 35.500000000 10.500000000 -6.500000000 35.500000000 10.500000000 -5.500000000 35.500000000 10.500000000 -4.500000000 35.500000000 10.500000000 -3.500000000 35.500000000 10.500000000 -2.500000000 35.500000000 10.500000000 -1.500000000 35.500000000 10.500000000 -0.500000000 35.500000000 10.500000000 0.500000000 35.500000000 10.500000000 1.500000000 35.500000000 10.500000000 2.500000000 35.500000000 10.500000000 3.500000000 35.500000000 10.500000000 4.500000000 35.500000000 10.500000000 5.500000000 35.500000000 10.500000000 6.500000000 35.500000000 10.500000000 7.500000000 35.500000000 10.500000000 8.500000000 35.500000000 10.500000000 9.500000000 35.500000000 10.500000000 10.500000000 35.500000000 10.500000000 11.500000000 35.500000000 10.500000000 12.500000000 35.500000000 10.500000000 13.500000000 35.500000000 10.500000000 14.500000000 35.500000000 10.500000000 15.500000000 35.500000000 10.500000000 16.500000000 35.500000000 10.500000000 17.500000000 35.500000000 10.500000000 18.500000000 35.500000000 10.500000000 19.500000000 35.500000000 10.500000000 20.500000000 35.500000000 10.500000000 21.500000000 35.500000000 10.500000000 22.500000000 35.500000000 10.500000000 23.500000000 35.500000000 10.500000000 24.500000000 35.500000000 10.500000000 25.499996185 35.499996185 10.500000000 26.499954224 35.499954224 10.500000000 27.499591827 35.499591827 10.500000000 28.497470856 35.497474670 10.500000000 29.488407135 35.488403320 10.500000000 30.458978653 35.458980560 10.500000000 31.384418488 35.384422302 10.500000000 32.233222961 35.233222961 10.500000000 32.981101990 34.981101990 10.500000000 -33.981101990 -35.981101990 11.500000000 -33.233226776 -36.233222961 11.500000000 -32.384422302 -36.384418488 11.500000000 -31.458978653 -36.458980560 11.500000000 -30.488407135 -36.488403320 11.500000000 -29.497472763 -36.497474670 11.500000000 -28.499593735 -36.499591827 11.500000000 -27.499954224 -36.499954224 11.500000000 -26.499996185 -36.499996185 11.500000000 -25.500000000 -36.500000000 11.500000000 -24.500000000 -36.500000000 11.500000000 -23.500000000 -36.500000000 11.500000000 -22.500000000 -36.500000000 11.500000000 -21.500000000 -36.500000000 11.500000000 -20.500000000 -36.500000000 11.500000000 -19.500000000 -36.500000000 11.500000000 -18.500000000 -36.500000000 11.500000000 -17.500000000 -36.500000000 11.500000000 -16.500000000 -36.500000000 11.500000000 -15.500000000 -36.500000000 11.500000000 -14.500000000 -36.500000000 11.500000000 -13.500000000 -36.500000000 11.500000000 -12.500000000 -36.500000000 11.500000000 -11.500000000 -36.500000000 11.500000000 -10.500000000 -36.500000000 11.500000000 -9.500000000 -36.500000000 11.500000000 -8.500000000 -36.500000000 11.500000000 -7.500000000 -36.500000000 11.500000000 -6.500000000 -36.500000000 11.500000000 -5.500000000 -36.500000000 11.500000000 -4.500000000 -36.500000000 11.500000000 -3.500000000 -36.500000000 11.500000000 -2.500000000 -36.500000000 11.500000000 -1.500000000 -36.500000000 11.500000000 -0.500000000 -36.500000000 11.500000000 0.500000000 -36.500000000 11.500000000 1.500000000 -36.500000000 11.500000000 2.500000000 -36.500000000 11.500000000 3.500000000 -36.500000000 11.500000000 4.500000000 -36.500000000 11.500000000 5.500000000 -36.500000000 11.500000000 6.500000000 -36.500000000 11.500000000 7.500000000 -36.500000000 11.500000000 8.500000000 -36.500000000 11.500000000 9.500000000 -36.500000000 11.500000000 10.500000000 -36.500000000 11.500000000 11.500000000 -36.500000000 11.500000000 12.500000000 -36.500000000 11.500000000 13.500000000 -36.500000000 11.500000000 14.500000000 -36.500000000 11.500000000 15.500000000 -36.500000000 11.500000000 16.500000000 -36.500000000 11.500000000 17.500000000 -36.500000000 11.500000000 18.500000000 -36.500000000 11.500000000 19.500000000 -36.500000000 11.500000000 20.500000000 -36.500000000 11.500000000 21.500000000 -36.500000000 11.500000000 22.500000000 -36.500000000 11.500000000 23.500000000 -36.500000000 11.500000000 24.500000000 -36.500000000 11.500000000 25.499996185 -36.499996185 11.500000000 26.499954224 -36.499954224 11.500000000 27.499591827 -36.499591827 11.500000000 28.497470856 -36.497467041 11.500000000 29.488407135 -36.488403320 11.500000000 30.458978653 -36.458980560 11.500000000 31.384418488 -36.384422302 11.500000000 32.233222961 -36.233222961 11.500000000 32.981101990 -35.981101990 11.500000000 -35.167964935 -35.167964935 11.500000000 -34.622871399 -35.622871399 11.500000000 33.622871399 -35.622871399 11.500000000 34.167964935 -35.167964935 11.500000000 -35.981101990 -33.981101990 11.500000000 -35.622871399 -34.622871399 11.500000000 34.622871399 -34.622871399 11.500000000 34.981101990 -33.981101990 11.500000000 -36.233222961 -33.233222961 11.500000000 35.233222961 -33.233226776 11.500000000 -36.384418488 -32.384422302 11.500000000 35.384418488 -32.384422302 11.500000000 -36.458976746 -31.458978653 11.500000000 35.458980560 -31.458978653 11.500000000 -36.488403320 -30.488407135 11.500000000 35.488403320 -30.488407135 11.500000000 -36.497467041 -29.497472763 11.500000000 35.497474670 -29.497472763 11.500000000 -36.499591827 -28.499593735 11.500000000 35.499591827 -28.499593735 11.500000000 -36.499954224 -27.499954224 11.500000000 35.499954224 -27.499954224 11.500000000 -36.499996185 -26.499996185 11.500000000 35.499996185 -26.499996185 11.500000000 -36.500000000 -25.500000000 11.500000000 35.500000000 -25.500000000 11.500000000 -36.500000000 -24.500000000 11.500000000 35.500000000 -24.500000000 11.500000000 -36.500000000 -23.500000000 11.500000000 35.500000000 -23.500000000 11.500000000 -36.500000000 -22.500000000 11.500000000 35.500000000 -22.500000000 11.500000000 -36.500000000 -21.500000000 11.500000000 35.500000000 -21.500000000 11.500000000 -36.500000000 -20.500000000 11.500000000 35.500000000 -20.500000000 11.500000000 -36.500000000 -19.500000000 11.500000000 35.500000000 -19.500000000 11.500000000 -36.500000000 -18.500000000 11.500000000 35.500000000 -18.500000000 11.500000000 -36.500000000 -17.500000000 11.500000000 35.500000000 -17.500000000 11.500000000 -36.500000000 -16.500000000 11.500000000 35.500000000 -16.500000000 11.500000000 -36.500000000 -15.500000000 11.500000000 35.500000000 -15.500000000 11.500000000 -36.500000000 -14.500000000 11.500000000 35.500000000 -14.500000000 11.500000000 -36.500000000 -13.500000000 11.500000000 35.500000000 -13.500000000 11.500000000 -36.500000000 -12.500000000 11.500000000 35.500000000 -12.500000000 11.500000000 -36.500000000 -11.500000000 11.500000000 35.500000000 -11.500000000 11.500000000 -36.500000000 -10.500000000 11.500000000 35.500000000 -10.500000000 11.500000000 -36.500000000 -9.500000000 11.500000000 35.500000000 -9.500000000 11.500000000 -36.500000000 -8.500000000 11.500000000 35.500000000 -8.500000000 11.500000000 -36.500000000 -7.500000000 11.500000000 35.500000000 -7.500000000 11.500000000 -36.500000000 -6.500000000 11.500000000 35.500000000 -6.500000000 11.500000000 -36.500000000 -5.500000000 11.500000000 35.500000000 -5.500000000 11.500000000 -36.500000000 -4.500000000 11.500000000 35.500000000 -4.500000000 11.500000000 -36.500000000 -3.500000000 11.500000000 35.500000000 -3.500000000 11.500000000 -36.500000000 -2.500000000 11.500000000 35.500000000 -2.500000000 11.500000000 -36.500000000 -1.500000000 11.500000000 35.500000000 -1.500000000 11.500000000 -36.500000000 -0.500000000 11.500000000 35.500000000 -0.500000000 11.500000000 -36.500000000 0.500000000 11.500000000 35.500000000 0.500000000 11.500000000 -36.500000000 1.500000000 11.500000000 35.500000000 1.500000000 11.500000000 -36.500000000 2.500000000 11.500000000 35.500000000 2.500000000 11.500000000 -36.500000000 3.500000000 11.500000000 35.500000000 3.500000000 11.500000000 -36.500000000 4.500000000 11.500000000 35.500000000 4.500000000 11.500000000 -36.500000000 5.500000000 11.500000000 35.500000000 5.500000000 11.500000000 -36.500000000 6.500000000 11.500000000 35.500000000 6.500000000 11.500000000 -36.500000000 7.500000000 11.500000000 35.500000000 7.500000000 11.500000000 -36.500000000 8.500000000 11.500000000 35.500000000 8.500000000 11.500000000 -36.500000000 9.500000000 11.500000000 35.500000000 9.500000000 11.500000000 -36.500000000 10.500000000 11.500000000 35.500000000 10.500000000 11.500000000 -36.500000000 11.500000000 11.500000000 35.500000000 11.500000000 11.500000000 -36.500000000 12.500000000 11.500000000 35.500000000 12.500000000 11.500000000 -36.500000000 13.500000000 11.500000000 35.500000000 13.500000000 11.500000000 -36.500000000 14.500000000 11.500000000 35.500000000 14.500000000 11.500000000 -36.500000000 15.500000000 11.500000000 35.500000000 15.500000000 11.500000000 -36.500000000 16.500000000 11.500000000 35.500000000 16.500000000 11.500000000 -36.500000000 17.500000000 11.500000000 35.500000000 17.500000000 11.500000000 -36.500000000 18.500000000 11.500000000 35.500000000 18.500000000 11.500000000 -36.500000000 19.500000000 11.500000000 35.500000000 19.500000000 11.500000000 -36.500000000 20.500000000 11.500000000 35.500000000 20.500000000 11.500000000 -36.500000000 21.500000000 11.500000000 35.500000000 21.500000000 11.500000000 -36.500000000 22.500000000 11.500000000 35.500000000 22.500000000 11.500000000 -36.500000000 23.500000000 11.500000000 35.500000000 23.500000000 11.500000000 -36.500000000 24.500000000 11.500000000 35.500000000 24.500000000 11.500000000 -36.499996185 25.499996185 11.500000000 35.499996185 25.499996185 11.500000000 -36.499954224 26.499954224 11.500000000 35.499954224 26.499954224 11.500000000 -36.499591827 27.499591827 11.500000000 35.499591827 27.499591827 11.500000000 -36.497474670 28.497470856 11.500000000 35.497467041 28.497470856 11.500000000 -36.488403320 29.488407135 11.500000000 35.488403320 29.488407135 11.500000000 -36.458980560 30.458978653 11.500000000 35.458980560 30.458978653 11.500000000 -36.384422302 31.384418488 11.500000000 35.384422302 31.384418488 11.500000000 -36.233222961 32.233222961 11.500000000 35.233222961 32.233222961 11.500000000 -35.981101990 32.981101990 11.500000000 -35.622871399 33.622871399 11.500000000 34.622871399 33.622871399 11.500000000 34.981101990 32.981101990 11.500000000 -35.167964935 34.167964935 11.500000000 -34.622871399 34.622871399 11.500000000 33.622871399 34.622871399 11.500000000 34.167964935 34.167964935 11.500000000 -33.981101990 34.981101990 11.500000000 -33.233222961 35.233222961 11.500000000 -32.384422302 35.384418488 11.500000000 -31.458978653 35.458976746 11.500000000 -30.488407135 35.488403320 11.500000000 -29.497472763 35.497467041 11.500000000 -28.499593735 35.499591827 11.500000000 -27.499954224 35.499954224 11.500000000 -26.499996185 35.499996185 11.500000000 -25.500000000 35.500000000 11.500000000 -24.500000000 35.500000000 11.500000000 -23.500000000 35.500000000 11.500000000 -22.500000000 35.500000000 11.500000000 -21.500000000 35.500000000 11.500000000 -20.500000000 35.500000000 11.500000000 -19.500000000 35.500000000 11.500000000 -18.500000000 35.500000000 11.500000000 -17.500000000 35.500000000 11.500000000 -16.500000000 35.500000000 11.500000000 -15.500000000 35.500000000 11.500000000 -14.500000000 35.500000000 11.500000000 -13.500000000 35.500000000 11.500000000 -12.500000000 35.500000000 11.500000000 -11.500000000 35.500000000 11.500000000 -10.500000000 35.500000000 11.500000000 -9.500000000 35.500000000 11.500000000 -8.500000000 35.500000000 11.500000000 -7.500000000 35.500000000 11.500000000 -6.500000000 35.500000000 11.500000000 -5.500000000 35.500000000 11.500000000 -4.500000000 35.500000000 11.500000000 -3.500000000 35.500000000 11.500000000 -2.500000000 35.500000000 11.500000000 -1.500000000 35.500000000 11.500000000 -0.500000000 35.500000000 11.500000000 0.500000000 35.500000000 11.500000000 1.500000000 35.500000000 11.500000000 2.500000000 35.500000000 11.500000000 3.500000000 35.500000000 11.500000000 4.500000000 35.500000000 11.500000000 5.500000000 35.500000000 11.500000000 6.500000000 35.500000000 11.500000000 7.500000000 35.500000000 11.500000000 8.500000000 35.500000000 11.500000000 9.500000000 35.500000000 11.500000000 10.500000000 35.500000000 11.500000000 11.500000000 35.500000000 11.500000000 12.500000000 35.500000000 11.500000000 13.500000000 35.500000000 11.500000000 14.500000000 35.500000000 11.500000000 15.500000000 35.500000000 11.500000000 16.500000000 35.500000000 11.500000000 17.500000000 35.500000000 11.500000000 18.500000000 35.500000000 11.500000000 19.500000000 35.500000000 11.500000000 20.500000000 35.500000000 11.500000000 21.500000000 35.500000000 11.500000000 22.500000000 35.500000000 11.500000000 23.500000000 35.500000000 11.500000000 24.500000000 35.500000000 11.500000000 25.499996185 35.499996185 11.500000000 26.499954224 35.499954224 11.500000000 27.499591827 35.499591827 11.500000000 28.497470856 35.497474670 11.500000000 29.488407135 35.488403320 11.500000000 30.458978653 35.458980560 11.500000000 31.384418488 35.384422302 11.500000000 32.233222961 35.233222961 11.500000000 32.981101990 34.981101990 11.500000000 -33.981101990 -35.981101990 12.500000000 -33.233226776 -36.233222961 12.500000000 -32.384422302 -36.384418488 12.500000000 -31.458978653 -36.458980560 12.500000000 -30.488407135 -36.488403320 12.500000000 -29.497472763 -36.497474670 12.500000000 -28.499593735 -36.499591827 12.500000000 -27.499954224 -36.499954224 12.500000000 -26.499996185 -36.499996185 12.500000000 -25.500000000 -36.500000000 12.500000000 -24.500000000 -36.500000000 12.500000000 -23.500000000 -36.500000000 12.500000000 -22.500000000 -36.500000000 12.500000000 -21.500000000 -36.500000000 12.500000000 -20.500000000 -36.500000000 12.500000000 -19.500000000 -36.500000000 12.500000000 -18.500000000 -36.500000000 12.500000000 -17.500000000 -36.500000000 12.500000000 -16.500000000 -36.500000000 12.500000000 -15.500000000 -36.500000000 12.500000000 -14.500000000 -36.500000000 12.500000000 -13.500000000 -36.500000000 12.500000000 -12.500000000 -36.500000000 12.500000000 -11.500000000 -36.500000000 12.500000000 -10.500000000 -36.500000000 12.500000000 -9.500000000 -36.500000000 12.500000000 -8.500000000 -36.500000000 12.500000000 -7.500000000 -36.500000000 12.500000000 -6.500000000 -36.500000000 12.500000000 -5.500000000 -36.500000000 12.500000000 -4.500000000 -36.500000000 12.500000000 -3.500000000 -36.500000000 12.500000000 -2.500000000 -36.500000000 12.500000000 -1.500000000 -36.500000000 12.500000000 -0.500000000 -36.500000000 12.500000000 0.500000000 -36.500000000 12.500000000 1.500000000 -36.500000000 12.500000000 2.500000000 -36.500000000 12.500000000 3.500000000 -36.500000000 12.500000000 4.500000000 -36.500000000 12.500000000 5.500000000 -36.500000000 12.500000000 6.500000000 -36.500000000 12.500000000 7.500000000 -36.500000000 12.500000000 8.500000000 -36.500000000 12.500000000 9.500000000 -36.500000000 12.500000000 10.500000000 -36.500000000 12.500000000 11.500000000 -36.500000000 12.500000000 12.500000000 -36.500000000 12.500000000 13.500000000 -36.500000000 12.500000000 14.500000000 -36.500000000 12.500000000 15.500000000 -36.500000000 12.500000000 16.500000000 -36.500000000 12.500000000 17.500000000 -36.500000000 12.500000000 18.500000000 -36.500000000 12.500000000 19.500000000 -36.500000000 12.500000000 20.500000000 -36.500000000 12.500000000 21.500000000 -36.500000000 12.500000000 22.500000000 -36.500000000 12.500000000 23.500000000 -36.500000000 12.500000000 24.500000000 -36.500000000 12.500000000 25.499996185 -36.499996185 12.500000000 26.499954224 -36.499954224 12.500000000 27.499591827 -36.499591827 12.500000000 28.497470856 -36.497467041 12.500000000 29.488407135 -36.488403320 12.500000000 30.458978653 -36.458980560 12.500000000 31.384418488 -36.384422302 12.500000000 32.233222961 -36.233222961 12.500000000 32.981101990 -35.981101990 12.500000000 -35.167964935 -35.167964935 12.500000000 -34.622871399 -35.622871399 12.500000000 33.622871399 -35.622871399 12.500000000 34.167964935 -35.167964935 12.500000000 -35.981101990 -33.981101990 12.500000000 -35.622871399 -34.622871399 12.500000000 34.622871399 -34.622871399 12.500000000 34.981101990 -33.981101990 12.500000000 -36.233222961 -33.233222961 12.500000000 35.233222961 -33.233226776 12.500000000 -36.384418488 -32.384422302 12.500000000 35.384418488 -32.384422302 12.500000000 -36.458976746 -31.458978653 12.500000000 35.458980560 -31.458978653 12.500000000 -36.488403320 -30.488407135 12.500000000 35.488403320 -30.488407135 12.500000000 -36.497467041 -29.497472763 12.500000000 35.497474670 -29.497472763 12.500000000 -36.499591827 -28.499593735 12.500000000 35.499591827 -28.499593735 12.500000000 -36.499954224 -27.499954224 12.500000000 35.499954224 -27.499954224 12.500000000 -36.499996185 -26.499996185 12.500000000 35.499996185 -26.499996185 12.500000000 -36.500000000 -25.500000000 12.500000000 35.500000000 -25.500000000 12.500000000 -36.500000000 -24.500000000 12.500000000 35.500000000 -24.500000000 12.500000000 -36.500000000 -23.500000000 12.500000000 35.500000000 -23.500000000 12.500000000 -36.500000000 -22.500000000 12.500000000 35.500000000 -22.500000000 12.500000000 -36.500000000 -21.500000000 12.500000000 35.500000000 -21.500000000 12.500000000 -36.500000000 -20.500000000 12.500000000 35.500000000 -20.500000000 12.500000000 -36.500000000 -19.500000000 12.500000000 35.500000000 -19.500000000 12.500000000 -36.500000000 -18.500000000 12.500000000 35.500000000 -18.500000000 12.500000000 -36.500000000 -17.500000000 12.500000000 35.500000000 -17.500000000 12.500000000 -36.500000000 -16.500000000 12.500000000 35.500000000 -16.500000000 12.500000000 -36.500000000 -15.500000000 12.500000000 35.500000000 -15.500000000 12.500000000 -36.500000000 -14.500000000 12.500000000 35.500000000 -14.500000000 12.500000000 -36.500000000 -13.500000000 12.500000000 35.500000000 -13.500000000 12.500000000 -36.500000000 -12.500000000 12.500000000 35.500000000 -12.500000000 12.500000000 -36.500000000 -11.500000000 12.500000000 35.500000000 -11.500000000 12.500000000 -36.500000000 -10.500000000 12.500000000 35.500000000 -10.500000000 12.500000000 -36.500000000 -9.500000000 12.500000000 35.500000000 -9.500000000 12.500000000 -36.500000000 -8.500000000 12.500000000 35.500000000 -8.500000000 12.500000000 -36.500000000 -7.500000000 12.500000000 35.500000000 -7.500000000 12.500000000 -36.500000000 -6.500000000 12.500000000 35.500000000 -6.500000000 12.500000000 -36.500000000 -5.500000000 12.500000000 35.500000000 -5.500000000 12.500000000 -36.500000000 -4.500000000 12.500000000 35.500000000 -4.500000000 12.500000000 -36.500000000 -3.500000000 12.500000000 35.500000000 -3.500000000 12.500000000 -36.500000000 -2.500000000 12.500000000 35.500000000 -2.500000000 12.500000000 -36.500000000 -1.500000000 12.500000000 35.500000000 -1.500000000 12.500000000 -36.500000000 -0.500000000 12.500000000 35.500000000 -0.500000000 12.500000000 -36.500000000 0.500000000 12.500000000 35.500000000 0.500000000 12.500000000 -36.500000000 1.500000000 12.500000000 35.500000000 1.500000000 12.500000000 -36.500000000 2.500000000 12.500000000 35.500000000 2.500000000 12.500000000 -36.500000000 3.500000000 12.500000000 35.500000000 3.500000000 12.500000000 -36.500000000 4.500000000 12.500000000 35.500000000 4.500000000 12.500000000 -36.500000000 5.500000000 12.500000000 35.500000000 5.500000000 12.500000000 -36.500000000 6.500000000 12.500000000 35.500000000 6.500000000 12.500000000 -36.500000000 7.500000000 12.500000000 35.500000000 7.500000000 12.500000000 -36.500000000 8.500000000 12.500000000 35.500000000 8.500000000 12.500000000 -36.500000000 9.500000000 12.500000000 35.500000000 9.500000000 12.500000000 -36.500000000 10.500000000 12.500000000 35.500000000 10.500000000 12.500000000 -36.500000000 11.500000000 12.500000000 35.500000000 11.500000000 12.500000000 -36.500000000 12.500000000 12.500000000 35.500000000 12.500000000 12.500000000 -36.500000000 13.500000000 12.500000000 35.500000000 13.500000000 12.500000000 -36.500000000 14.500000000 12.500000000 35.500000000 14.500000000 12.500000000 -36.500000000 15.500000000 12.500000000 35.500000000 15.500000000 12.500000000 -36.500000000 16.500000000 12.500000000 35.500000000 16.500000000 12.500000000 -36.500000000 17.500000000 12.500000000 35.500000000 17.500000000 12.500000000 -36.500000000 18.500000000 12.500000000 35.500000000 18.500000000 12.500000000 -36.500000000 19.500000000 12.500000000 35.500000000 19.500000000 12.500000000 -36.500000000 20.500000000 12.500000000 35.500000000 20.500000000 12.500000000 -36.500000000 21.500000000 12.500000000 35.500000000 21.500000000 12.500000000 -36.500000000 22.500000000 12.500000000 35.500000000 22.500000000 12.500000000 -36.500000000 23.500000000 12.500000000 35.500000000 23.500000000 12.500000000 -36.500000000 24.500000000 12.500000000 35.500000000 24.500000000 12.500000000 -36.499996185 25.499996185 12.500000000 35.499996185 25.499996185 12.500000000 -36.499954224 26.499954224 12.500000000 35.499954224 26.499954224 12.500000000 -36.499591827 27.499591827 12.500000000 35.499591827 27.499591827 12.500000000 -36.497474670 28.497470856 12.500000000 35.497467041 28.497470856 12.500000000 -36.488403320 29.488407135 12.500000000 35.488403320 29.488407135 12.500000000 -36.458980560 30.458978653 12.500000000 35.458980560 30.458978653 12.500000000 -36.384422302 31.384418488 12.500000000 35.384422302 31.384418488 12.500000000 -36.233222961 32.233222961 12.500000000 35.233222961 32.233222961 12.500000000 -35.981101990 32.981101990 12.500000000 -35.622871399 33.622871399 12.500000000 34.622871399 33.622871399 12.500000000 34.981101990 32.981101990 12.500000000 -35.167964935 34.167964935 12.500000000 -34.622871399 34.622871399 12.500000000 33.622871399 34.622871399 12.500000000 34.167964935 34.167964935 12.500000000 -33.981101990 34.981101990 12.500000000 -33.233222961 35.233222961 12.500000000 -32.384422302 35.384418488 12.500000000 -31.458978653 35.458976746 12.500000000 -30.488407135 35.488403320 12.500000000 -29.497472763 35.497467041 12.500000000 -28.499593735 35.499591827 12.500000000 -27.499954224 35.499954224 12.500000000 -26.499996185 35.499996185 12.500000000 -25.500000000 35.500000000 12.500000000 -24.500000000 35.500000000 12.500000000 -23.500000000 35.500000000 12.500000000 -22.500000000 35.500000000 12.500000000 -21.500000000 35.500000000 12.500000000 -20.500000000 35.500000000 12.500000000 -19.500000000 35.500000000 12.500000000 -18.500000000 35.500000000 12.500000000 -17.500000000 35.500000000 12.500000000 -16.500000000 35.500000000 12.500000000 -15.500000000 35.500000000 12.500000000 -14.500000000 35.500000000 12.500000000 -13.500000000 35.500000000 12.500000000 -12.500000000 35.500000000 12.500000000 -11.500000000 35.500000000 12.500000000 -10.500000000 35.500000000 12.500000000 -9.500000000 35.500000000 12.500000000 -8.500000000 35.500000000 12.500000000 -7.500000000 35.500000000 12.500000000 -6.500000000 35.500000000 12.500000000 -5.500000000 35.500000000 12.500000000 -4.500000000 35.500000000 12.500000000 -3.500000000 35.500000000 12.500000000 -2.500000000 35.500000000 12.500000000 -1.500000000 35.500000000 12.500000000 -0.500000000 35.500000000 12.500000000 0.500000000 35.500000000 12.500000000 1.500000000 35.500000000 12.500000000 2.500000000 35.500000000 12.500000000 3.500000000 35.500000000 12.500000000 4.500000000 35.500000000 12.500000000 5.500000000 35.500000000 12.500000000 6.500000000 35.500000000 12.500000000 7.500000000 35.500000000 12.500000000 8.500000000 35.500000000 12.500000000 9.500000000 35.500000000 12.500000000 10.500000000 35.500000000 12.500000000 11.500000000 35.500000000 12.500000000 12.500000000 35.500000000 12.500000000 13.500000000 35.500000000 12.500000000 14.500000000 35.500000000 12.500000000 15.500000000 35.500000000 12.500000000 16.500000000 35.500000000 12.500000000 17.500000000 35.500000000 12.500000000 18.500000000 35.500000000 12.500000000 19.500000000 35.500000000 12.500000000 20.500000000 35.500000000 12.500000000 21.500000000 35.500000000 12.500000000 22.500000000 35.500000000 12.500000000 23.500000000 35.500000000 12.500000000 24.500000000 35.500000000 12.500000000 25.499996185 35.499996185 12.500000000 26.499954224 35.499954224 12.500000000 27.499591827 35.499591827 12.500000000 28.497470856 35.497474670 12.500000000 29.488407135 35.488403320 12.500000000 30.458978653 35.458980560 12.500000000 31.384418488 35.384422302 12.500000000 32.233222961 35.233222961 12.500000000 32.981101990 34.981101990 12.500000000 -33.981101990 -35.981101990 13.500000000 -33.233226776 -36.233222961 13.500000000 -32.384422302 -36.384418488 13.500000000 -31.458978653 -36.458980560 13.500000000 -30.488407135 -36.488403320 13.500000000 -29.497472763 -36.497474670 13.500000000 -28.499593735 -36.499591827 13.500000000 -27.499954224 -36.499954224 13.500000000 -26.499996185 -36.499996185 13.500000000 -25.500000000 -36.500000000 13.500000000 -24.500000000 -36.500000000 13.500000000 -23.500000000 -36.500000000 13.500000000 -22.500000000 -36.500000000 13.500000000 -21.500000000 -36.500000000 13.500000000 -20.500000000 -36.500000000 13.500000000 -19.500000000 -36.500000000 13.500000000 -18.500000000 -36.500000000 13.500000000 -17.500000000 -36.500000000 13.500000000 -16.500000000 -36.500000000 13.500000000 -15.500000000 -36.500000000 13.500000000 -14.500000000 -36.500000000 13.500000000 -13.500000000 -36.500000000 13.500000000 -12.500000000 -36.500000000 13.500000000 -11.500000000 -36.500000000 13.500000000 -10.500000000 -36.500000000 13.500000000 -9.500000000 -36.500000000 13.500000000 -8.500000000 -36.500000000 13.500000000 -7.500000000 -36.500000000 13.500000000 -6.500000000 -36.500000000 13.500000000 -5.500000000 -36.500000000 13.500000000 -4.500000000 -36.500000000 13.500000000 -3.500000000 -36.500000000 13.500000000 -2.500000000 -36.500000000 13.500000000 -1.500000000 -36.500000000 13.500000000 -0.500000000 -36.500000000 13.500000000 0.500000000 -36.500000000 13.500000000 1.500000000 -36.500000000 13.500000000 2.500000000 -36.500000000 13.500000000 3.500000000 -36.500000000 13.500000000 4.500000000 -36.500000000 13.500000000 5.500000000 -36.500000000 13.500000000 6.500000000 -36.500000000 13.500000000 7.500000000 -36.500000000 13.500000000 8.500000000 -36.500000000 13.500000000 9.500000000 -36.500000000 13.500000000 10.500000000 -36.500000000 13.500000000 11.500000000 -36.500000000 13.500000000 12.500000000 -36.500000000 13.500000000 13.500000000 -36.500000000 13.500000000 14.500000000 -36.500000000 13.500000000 15.500000000 -36.500000000 13.500000000 16.500000000 -36.500000000 13.500000000 17.500000000 -36.500000000 13.500000000 18.500000000 -36.500000000 13.500000000 19.500000000 -36.500000000 13.500000000 20.500000000 -36.500000000 13.500000000 21.500000000 -36.500000000 13.500000000 22.500000000 -36.500000000 13.500000000 23.500000000 -36.500000000 13.500000000 24.500000000 -36.500000000 13.500000000 25.499996185 -36.499996185 13.500000000 26.499954224 -36.499954224 13.500000000 27.499591827 -36.499591827 13.500000000 28.497470856 -36.497467041 13.500000000 29.488407135 -36.488403320 13.500000000 30.458978653 -36.458980560 13.500000000 31.384418488 -36.384422302 13.500000000 32.233222961 -36.233222961 13.500000000 32.981101990 -35.981101990 13.500000000 -35.167964935 -35.167964935 13.500000000 -34.622871399 -35.622871399 13.500000000 33.622871399 -35.622871399 13.500000000 34.167964935 -35.167964935 13.500000000 -35.981101990 -33.981101990 13.500000000 -35.622871399 -34.622871399 13.500000000 34.622871399 -34.622871399 13.500000000 34.981101990 -33.981101990 13.500000000 -36.233222961 -33.233222961 13.500000000 35.233222961 -33.233226776 13.500000000 -36.384418488 -32.384422302 13.500000000 35.384418488 -32.384422302 13.500000000 -36.458976746 -31.458978653 13.500000000 35.458980560 -31.458978653 13.500000000 -36.488403320 -30.488407135 13.500000000 35.488403320 -30.488407135 13.500000000 -36.497467041 -29.497472763 13.500000000 35.497474670 -29.497472763 13.500000000 -36.499591827 -28.499593735 13.500000000 35.499591827 -28.499593735 13.500000000 -36.499954224 -27.499954224 13.500000000 35.499954224 -27.499954224 13.500000000 -36.499996185 -26.499996185 13.500000000 35.499996185 -26.499996185 13.500000000 -36.500000000 -25.500000000 13.500000000 35.500000000 -25.500000000 13.500000000 -36.500000000 -24.500000000 13.500000000 35.500000000 -24.500000000 13.500000000 -36.500000000 -23.500000000 13.500000000 35.500000000 -23.500000000 13.500000000 -36.500000000 -22.500000000 13.500000000 35.500000000 -22.500000000 13.500000000 -36.500000000 -21.500000000 13.500000000 35.500000000 -21.500000000 13.500000000 -36.500000000 -20.500000000 13.500000000 35.500000000 -20.500000000 13.500000000 -36.500000000 -19.500000000 13.500000000 35.500000000 -19.500000000 13.500000000 -36.500000000 -18.500000000 13.500000000 35.500000000 -18.500000000 13.500000000 -36.500000000 -17.500000000 13.500000000 35.500000000 -17.500000000 13.500000000 -36.500000000 -16.500000000 13.500000000 35.500000000 -16.500000000 13.500000000 -36.500000000 -15.500000000 13.500000000 35.500000000 -15.500000000 13.500000000 -36.500000000 -14.500000000 13.500000000 35.500000000 -14.500000000 13.500000000 -36.500000000 -13.500000000 13.500000000 35.500000000 -13.500000000 13.500000000 -36.500000000 -12.500000000 13.500000000 35.500000000 -12.500000000 13.500000000 -36.500000000 -11.500000000 13.500000000 35.500000000 -11.500000000 13.500000000 -36.500000000 -10.500000000 13.500000000 35.500000000 -10.500000000 13.500000000 -36.500000000 -9.500000000 13.500000000 35.500000000 -9.500000000 13.500000000 -36.500000000 -8.500000000 13.500000000 35.500000000 -8.500000000 13.500000000 -36.500000000 -7.500000000 13.500000000 35.500000000 -7.500000000 13.500000000 -36.500000000 -6.500000000 13.500000000 35.500000000 -6.500000000 13.500000000 -36.500000000 -5.500000000 13.500000000 35.500000000 -5.500000000 13.500000000 -36.500000000 -4.500000000 13.500000000 35.500000000 -4.500000000 13.500000000 -36.500000000 -3.500000000 13.500000000 35.500000000 -3.500000000 13.500000000 -36.500000000 -2.500000000 13.500000000 35.500000000 -2.500000000 13.500000000 -36.500000000 -1.500000000 13.500000000 35.500000000 -1.500000000 13.500000000 -36.500000000 -0.500000000 13.500000000 35.500000000 -0.500000000 13.500000000 -36.500000000 0.500000000 13.500000000 35.500000000 0.500000000 13.500000000 -36.500000000 1.500000000 13.500000000 35.500000000 1.500000000 13.500000000 -36.500000000 2.500000000 13.500000000 35.500000000 2.500000000 13.500000000 -36.500000000 3.500000000 13.500000000 35.500000000 3.500000000 13.500000000 -36.500000000 4.500000000 13.500000000 35.500000000 4.500000000 13.500000000 -36.500000000 5.500000000 13.500000000 35.500000000 5.500000000 13.500000000 -36.500000000 6.500000000 13.500000000 35.500000000 6.500000000 13.500000000 -36.500000000 7.500000000 13.500000000 35.500000000 7.500000000 13.500000000 -36.500000000 8.500000000 13.500000000 35.500000000 8.500000000 13.500000000 -36.500000000 9.500000000 13.500000000 35.500000000 9.500000000 13.500000000 -36.500000000 10.500000000 13.500000000 35.500000000 10.500000000 13.500000000 -36.500000000 11.500000000 13.500000000 35.500000000 11.500000000 13.500000000 -36.500000000 12.500000000 13.500000000 35.500000000 12.500000000 13.500000000 -36.500000000 13.500000000 13.500000000 35.500000000 13.500000000 13.500000000 -36.500000000 14.500000000 13.500000000 35.500000000 14.500000000 13.500000000 -36.500000000 15.500000000 13.500000000 35.500000000 15.500000000 13.500000000 -36.500000000 16.500000000 13.500000000 35.500000000 16.500000000 13.500000000 -36.500000000 17.500000000 13.500000000 35.500000000 17.500000000 13.500000000 -36.500000000 18.500000000 13.500000000 35.500000000 18.500000000 13.500000000 -36.500000000 19.500000000 13.500000000 35.500000000 19.500000000 13.500000000 -36.500000000 20.500000000 13.500000000 35.500000000 20.500000000 13.500000000 -36.500000000 21.500000000 13.500000000 35.500000000 21.500000000 13.500000000 -36.500000000 22.500000000 13.500000000 35.500000000 22.500000000 13.500000000 -36.500000000 23.500000000 13.500000000 35.500000000 23.500000000 13.500000000 -36.500000000 24.500000000 13.500000000 35.500000000 24.500000000 13.500000000 -36.499996185 25.499996185 13.500000000 35.499996185 25.499996185 13.500000000 -36.499954224 26.499954224 13.500000000 35.499954224 26.499954224 13.500000000 -36.499591827 27.499591827 13.500000000 35.499591827 27.499591827 13.500000000 -36.497474670 28.497470856 13.500000000 35.497467041 28.497470856 13.500000000 -36.488403320 29.488407135 13.500000000 35.488403320 29.488407135 13.500000000 -36.458980560 30.458978653 13.500000000 35.458980560 30.458978653 13.500000000 -36.384422302 31.384418488 13.500000000 35.384422302 31.384418488 13.500000000 -36.233222961 32.233222961 13.500000000 35.233222961 32.233222961 13.500000000 -35.981101990 32.981101990 13.500000000 -35.622871399 33.622871399 13.500000000 34.622871399 33.622871399 13.500000000 34.981101990 32.981101990 13.500000000 -35.167964935 34.167964935 13.500000000 -34.622871399 34.622871399 13.500000000 33.622871399 34.622871399 13.500000000 34.167964935 34.167964935 13.500000000 -33.981101990 34.981101990 13.500000000 -33.233222961 35.233222961 13.500000000 -32.384422302 35.384418488 13.500000000 -31.458978653 35.458976746 13.500000000 -30.488407135 35.488403320 13.500000000 -29.497472763 35.497467041 13.500000000 -28.499593735 35.499591827 13.500000000 -27.499954224 35.499954224 13.500000000 -26.499996185 35.499996185 13.500000000 -25.500000000 35.500000000 13.500000000 -24.500000000 35.500000000 13.500000000 -23.500000000 35.500000000 13.500000000 -22.500000000 35.500000000 13.500000000 -21.500000000 35.500000000 13.500000000 -20.500000000 35.500000000 13.500000000 -19.500000000 35.500000000 13.500000000 -18.500000000 35.500000000 13.500000000 -17.500000000 35.500000000 13.500000000 -16.500000000 35.500000000 13.500000000 -15.500000000 35.500000000 13.500000000 -14.500000000 35.500000000 13.500000000 -13.500000000 35.500000000 13.500000000 -12.500000000 35.500000000 13.500000000 -11.500000000 35.500000000 13.500000000 -10.500000000 35.500000000 13.500000000 -9.500000000 35.500000000 13.500000000 -8.500000000 35.500000000 13.500000000 -7.500000000 35.500000000 13.500000000 -6.500000000 35.500000000 13.500000000 -5.500000000 35.500000000 13.500000000 -4.500000000 35.500000000 13.500000000 -3.500000000 35.500000000 13.500000000 -2.500000000 35.500000000 13.500000000 -1.500000000 35.500000000 13.500000000 -0.500000000 35.500000000 13.500000000 0.500000000 35.500000000 13.500000000 1.500000000 35.500000000 13.500000000 2.500000000 35.500000000 13.500000000 3.500000000 35.500000000 13.500000000 4.500000000 35.500000000 13.500000000 5.500000000 35.500000000 13.500000000 6.500000000 35.500000000 13.500000000 7.500000000 35.500000000 13.500000000 8.500000000 35.500000000 13.500000000 9.500000000 35.500000000 13.500000000 10.500000000 35.500000000 13.500000000 11.500000000 35.500000000 13.500000000 12.500000000 35.500000000 13.500000000 13.500000000 35.500000000 13.500000000 14.500000000 35.500000000 13.500000000 15.500000000 35.500000000 13.500000000 16.500000000 35.500000000 13.500000000 17.500000000 35.500000000 13.500000000 18.500000000 35.500000000 13.500000000 19.500000000 35.500000000 13.500000000 20.500000000 35.500000000 13.500000000 21.500000000 35.500000000 13.500000000 22.500000000 35.500000000 13.500000000 23.500000000 35.500000000 13.500000000 24.500000000 35.500000000 13.500000000 25.499996185 35.499996185 13.500000000 26.499954224 35.499954224 13.500000000 27.499591827 35.499591827 13.500000000 28.497470856 35.497474670 13.500000000 29.488407135 35.488403320 13.500000000 30.458978653 35.458980560 13.500000000 31.384418488 35.384422302 13.500000000 32.233222961 35.233222961 13.500000000 32.981101990 34.981101990 13.500000000 -33.981101990 -35.981101990 14.500000000 -33.233226776 -36.233222961 14.500000000 -32.384422302 -36.384418488 14.500000000 -31.458978653 -36.458980560 14.500000000 -30.488407135 -36.488403320 14.500000000 -29.497472763 -36.497474670 14.500000000 -28.499593735 -36.499591827 14.500000000 -27.499954224 -36.499954224 14.500000000 -26.499996185 -36.499996185 14.500000000 -25.500000000 -36.500000000 14.500000000 -24.500000000 -36.500000000 14.500000000 -23.500000000 -36.500000000 14.500000000 -22.500000000 -36.500000000 14.500000000 -21.500000000 -36.500000000 14.500000000 -20.500000000 -36.500000000 14.500000000 -19.500000000 -36.500000000 14.500000000 -18.500000000 -36.500000000 14.500000000 -17.500000000 -36.500000000 14.500000000 -16.500000000 -36.500000000 14.500000000 -15.500000000 -36.500000000 14.500000000 -14.500000000 -36.500000000 14.500000000 -13.500000000 -36.500000000 14.500000000 -12.500000000 -36.500000000 14.500000000 -11.500000000 -36.500000000 14.500000000 -10.500000000 -36.500000000 14.500000000 -9.500000000 -36.500000000 14.500000000 -8.500000000 -36.500000000 14.500000000 -7.500000000 -36.500000000 14.500000000 -6.500000000 -36.500000000 14.500000000 -5.500000000 -36.500000000 14.500000000 -4.500000000 -36.500000000 14.500000000 -3.500000000 -36.500000000 14.500000000 -2.500000000 -36.500000000 14.500000000 -1.500000000 -36.500000000 14.500000000 -0.500000000 -36.500000000 14.500000000 0.500000000 -36.500000000 14.500000000 1.500000000 -36.500000000 14.500000000 2.500000000 -36.500000000 14.500000000 3.500000000 -36.500000000 14.500000000 4.500000000 -36.500000000 14.500000000 5.500000000 -36.500000000 14.500000000 6.500000000 -36.500000000 14.500000000 7.500000000 -36.500000000 14.500000000 8.500000000 -36.500000000 14.500000000 9.500000000 -36.500000000 14.500000000 10.500000000 -36.500000000 14.500000000 11.500000000 -36.500000000 14.500000000 12.500000000 -36.500000000 14.500000000 13.500000000 -36.500000000 14.500000000 14.500000000 -36.500000000 14.500000000 15.500000000 -36.500000000 14.500000000 16.500000000 -36.500000000 14.500000000 17.500000000 -36.500000000 14.500000000 18.500000000 -36.500000000 14.500000000 19.500000000 -36.500000000 14.500000000 20.500000000 -36.500000000 14.500000000 21.500000000 -36.500000000 14.500000000 22.500000000 -36.500000000 14.500000000 23.500000000 -36.500000000 14.500000000 24.500000000 -36.500000000 14.500000000 25.499996185 -36.499996185 14.500000000 26.499954224 -36.499954224 14.500000000 27.499591827 -36.499591827 14.500000000 28.497470856 -36.497467041 14.500000000 29.488407135 -36.488403320 14.500000000 30.458978653 -36.458980560 14.500000000 31.384418488 -36.384422302 14.500000000 32.233222961 -36.233222961 14.500000000 32.981101990 -35.981101990 14.500000000 -35.167964935 -35.167964935 14.500000000 -34.622871399 -35.622871399 14.500000000 33.622871399 -35.622871399 14.500000000 34.167964935 -35.167964935 14.500000000 -35.981101990 -33.981101990 14.500000000 -35.622871399 -34.622871399 14.500000000 34.622871399 -34.622871399 14.500000000 34.981101990 -33.981101990 14.500000000 -36.233222961 -33.233222961 14.500000000 35.233222961 -33.233226776 14.500000000 -36.384418488 -32.384422302 14.500000000 35.384418488 -32.384422302 14.500000000 -36.458976746 -31.458978653 14.500000000 35.458980560 -31.458978653 14.500000000 -36.488403320 -30.488407135 14.500000000 35.488403320 -30.488407135 14.500000000 -36.497467041 -29.497472763 14.500000000 35.497474670 -29.497472763 14.500000000 -36.499591827 -28.499593735 14.500000000 35.499591827 -28.499593735 14.500000000 -36.499954224 -27.499954224 14.500000000 35.499954224 -27.499954224 14.500000000 -36.499996185 -26.499996185 14.500000000 35.499996185 -26.499996185 14.500000000 -36.500000000 -25.500000000 14.500000000 35.500000000 -25.500000000 14.500000000 -36.500000000 -24.500000000 14.500000000 35.500000000 -24.500000000 14.500000000 -36.500000000 -23.500000000 14.500000000 35.500000000 -23.500000000 14.500000000 -36.500000000 -22.500000000 14.500000000 35.500000000 -22.500000000 14.500000000 -36.500000000 -21.500000000 14.500000000 35.500000000 -21.500000000 14.500000000 -36.500000000 -20.500000000 14.500000000 35.500000000 -20.500000000 14.500000000 -36.500000000 -19.500000000 14.500000000 35.500000000 -19.500000000 14.500000000 -36.500000000 -18.500000000 14.500000000 35.500000000 -18.500000000 14.500000000 -36.500000000 -17.500000000 14.500000000 35.500000000 -17.500000000 14.500000000 -36.500000000 -16.500000000 14.500000000 35.500000000 -16.500000000 14.500000000 -36.500000000 -15.500000000 14.500000000 35.500000000 -15.500000000 14.500000000 -36.500000000 -14.500000000 14.500000000 35.500000000 -14.500000000 14.500000000 -36.500000000 -13.500000000 14.500000000 35.500000000 -13.500000000 14.500000000 -36.500000000 -12.500000000 14.500000000 35.500000000 -12.500000000 14.500000000 -36.500000000 -11.500000000 14.500000000 35.500000000 -11.500000000 14.500000000 -36.500000000 -10.500000000 14.500000000 35.500000000 -10.500000000 14.500000000 -36.500000000 -9.500000000 14.500000000 35.500000000 -9.500000000 14.500000000 -36.500000000 -8.500000000 14.500000000 35.500000000 -8.500000000 14.500000000 -36.500000000 -7.500000000 14.500000000 35.500000000 -7.500000000 14.500000000 -36.500000000 -6.500000000 14.500000000 35.500000000 -6.500000000 14.500000000 -36.500000000 -5.500000000 14.500000000 35.500000000 -5.500000000 14.500000000 -36.500000000 -4.500000000 14.500000000 35.500000000 -4.500000000 14.500000000 -36.500000000 -3.500000000 14.500000000 35.500000000 -3.500000000 14.500000000 -36.500000000 -2.500000000 14.500000000 35.500000000 -2.500000000 14.500000000 -36.500000000 -1.500000000 14.500000000 35.500000000 -1.500000000 14.500000000 -36.500000000 -0.500000000 14.500000000 35.500000000 -0.500000000 14.500000000 -36.500000000 0.500000000 14.500000000 35.500000000 0.500000000 14.500000000 -36.500000000 1.500000000 14.500000000 35.500000000 1.500000000 14.500000000 -36.500000000 2.500000000 14.500000000 35.500000000 2.500000000 14.500000000 -36.500000000 3.500000000 14.500000000 35.500000000 3.500000000 14.500000000 -36.500000000 4.500000000 14.500000000 35.500000000 4.500000000 14.500000000 -36.500000000 5.500000000 14.500000000 35.500000000 5.500000000 14.500000000 -36.500000000 6.500000000 14.500000000 35.500000000 6.500000000 14.500000000 -36.500000000 7.500000000 14.500000000 35.500000000 7.500000000 14.500000000 -36.500000000 8.500000000 14.500000000 35.500000000 8.500000000 14.500000000 -36.500000000 9.500000000 14.500000000 35.500000000 9.500000000 14.500000000 -36.500000000 10.500000000 14.500000000 35.500000000 10.500000000 14.500000000 -36.500000000 11.500000000 14.500000000 35.500000000 11.500000000 14.500000000 -36.500000000 12.500000000 14.500000000 35.500000000 12.500000000 14.500000000 -36.500000000 13.500000000 14.500000000 35.500000000 13.500000000 14.500000000 -36.500000000 14.500000000 14.500000000 35.500000000 14.500000000 14.500000000 -36.500000000 15.500000000 14.500000000 35.500000000 15.500000000 14.500000000 -36.500000000 16.500000000 14.500000000 35.500000000 16.500000000 14.500000000 -36.500000000 17.500000000 14.500000000 35.500000000 17.500000000 14.500000000 -36.500000000 18.500000000 14.500000000 35.500000000 18.500000000 14.500000000 -36.500000000 19.500000000 14.500000000 35.500000000 19.500000000 14.500000000 -36.500000000 20.500000000 14.500000000 35.500000000 20.500000000 14.500000000 -36.500000000 21.500000000 14.500000000 35.500000000 21.500000000 14.500000000 -36.500000000 22.500000000 14.500000000 35.500000000 22.500000000 14.500000000 -36.500000000 23.500000000 14.500000000 35.500000000 23.500000000 14.500000000 -36.500000000 24.500000000 14.500000000 35.500000000 24.500000000 14.500000000 -36.499996185 25.499996185 14.500000000 35.499996185 25.499996185 14.500000000 -36.499954224 26.499954224 14.500000000 35.499954224 26.499954224 14.500000000 -36.499591827 27.499591827 14.500000000 35.499591827 27.499591827 14.500000000 -36.497474670 28.497470856 14.500000000 35.497467041 28.497470856 14.500000000 -36.488403320 29.488407135 14.500000000 35.488403320 29.488407135 14.500000000 -36.458980560 30.458978653 14.500000000 35.458980560 30.458978653 14.500000000 -36.384422302 31.384418488 14.500000000 35.384422302 31.384418488 14.500000000 -36.233222961 32.233222961 14.500000000 35.233222961 32.233222961 14.500000000 -35.981101990 32.981101990 14.500000000 -35.622871399 33.622871399 14.500000000 34.622871399 33.622871399 14.500000000 34.981101990 32.981101990 14.500000000 -35.167964935 34.167964935 14.500000000 -34.622871399 34.622871399 14.500000000 33.622871399 34.622871399 14.500000000 34.167964935 34.167964935 14.500000000 -33.981101990 34.981101990 14.500000000 -33.233222961 35.233222961 14.500000000 -32.384422302 35.384418488 14.500000000 -31.458978653 35.458976746 14.500000000 -30.488407135 35.488403320 14.500000000 -29.497472763 35.497467041 14.500000000 -28.499593735 35.499591827 14.500000000 -27.499954224 35.499954224 14.500000000 -26.499996185 35.499996185 14.500000000 -25.500000000 35.500000000 14.500000000 -24.500000000 35.500000000 14.500000000 -23.500000000 35.500000000 14.500000000 -22.500000000 35.500000000 14.500000000 -21.500000000 35.500000000 14.500000000 -20.500000000 35.500000000 14.500000000 -19.500000000 35.500000000 14.500000000 -18.500000000 35.500000000 14.500000000 -17.500000000 35.500000000 14.500000000 -16.500000000 35.500000000 14.500000000 -15.500000000 35.500000000 14.500000000 -14.500000000 35.500000000 14.500000000 -13.500000000 35.500000000 14.500000000 -12.500000000 35.500000000 14.500000000 -11.500000000 35.500000000 14.500000000 -10.500000000 35.500000000 14.500000000 -9.500000000 35.500000000 14.500000000 -8.500000000 35.500000000 14.500000000 -7.500000000 35.500000000 14.500000000 -6.500000000 35.500000000 14.500000000 -5.500000000 35.500000000 14.500000000 -4.500000000 35.500000000 14.500000000 -3.500000000 35.500000000 14.500000000 -2.500000000 35.500000000 14.500000000 -1.500000000 35.500000000 14.500000000 -0.500000000 35.500000000 14.500000000 0.500000000 35.500000000 14.500000000 1.500000000 35.500000000 14.500000000 2.500000000 35.500000000 14.500000000 3.500000000 35.500000000 14.500000000 4.500000000 35.500000000 14.500000000 5.500000000 35.500000000 14.500000000 6.500000000 35.500000000 14.500000000 7.500000000 35.500000000 14.500000000 8.500000000 35.500000000 14.500000000 9.500000000 35.500000000 14.500000000 10.500000000 35.500000000 14.500000000 11.500000000 35.500000000 14.500000000 12.500000000 35.500000000 14.500000000 13.500000000 35.500000000 14.500000000 14.500000000 35.500000000 14.500000000 15.500000000 35.500000000 14.500000000 16.500000000 35.500000000 14.500000000 17.500000000 35.500000000 14.500000000 18.500000000 35.500000000 14.500000000 19.500000000 35.500000000 14.500000000 20.500000000 35.500000000 14.500000000 21.500000000 35.500000000 14.500000000 22.500000000 35.500000000 14.500000000 23.500000000 35.500000000 14.500000000 24.500000000 35.500000000 14.500000000 25.499996185 35.499996185 14.500000000 26.499954224 35.499954224 14.500000000 27.499591827 35.499591827 14.500000000 28.497470856 35.497474670 14.500000000 29.488407135 35.488403320 14.500000000 30.458978653 35.458980560 14.500000000 31.384418488 35.384422302 14.500000000 32.233222961 35.233222961 14.500000000 32.981101990 34.981101990 14.500000000 -33.981101990 -35.981101990 15.500000000 -33.233226776 -36.233222961 15.500000000 -32.384422302 -36.384418488 15.500000000 -31.458978653 -36.458980560 15.500000000 -30.488407135 -36.488403320 15.500000000 -29.497472763 -36.497474670 15.500000000 -28.499593735 -36.499591827 15.500000000 -27.499954224 -36.499954224 15.500000000 -26.499996185 -36.499996185 15.500000000 -25.500000000 -36.500000000 15.500000000 -24.500000000 -36.500000000 15.500000000 -23.500000000 -36.500000000 15.500000000 -22.500000000 -36.500000000 15.500000000 -21.500000000 -36.500000000 15.500000000 -20.500000000 -36.500000000 15.500000000 -19.500000000 -36.500000000 15.500000000 -18.500000000 -36.500000000 15.500000000 -17.500000000 -36.500000000 15.500000000 -16.500000000 -36.500000000 15.500000000 -15.500000000 -36.500000000 15.500000000 -14.500000000 -36.500000000 15.500000000 -13.500000000 -36.500000000 15.500000000 -12.500000000 -36.500000000 15.500000000 -11.500000000 -36.500000000 15.500000000 -10.500000000 -36.500000000 15.500000000 -9.500000000 -36.500000000 15.500000000 -8.500000000 -36.500000000 15.500000000 -7.500000000 -36.500000000 15.500000000 -6.500000000 -36.500000000 15.500000000 -5.500000000 -36.500000000 15.500000000 -4.500000000 -36.500000000 15.500000000 -3.500000000 -36.500000000 15.500000000 -2.500000000 -36.500000000 15.500000000 -1.500000000 -36.500000000 15.500000000 -0.500000000 -36.500000000 15.500000000 0.500000000 -36.500000000 15.500000000 1.500000000 -36.500000000 15.500000000 2.500000000 -36.500000000 15.500000000 3.500000000 -36.500000000 15.500000000 4.500000000 -36.500000000 15.500000000 5.500000000 -36.500000000 15.500000000 6.500000000 -36.500000000 15.500000000 7.500000000 -36.500000000 15.500000000 8.500000000 -36.500000000 15.500000000 9.500000000 -36.500000000 15.500000000 10.500000000 -36.500000000 15.500000000 11.500000000 -36.500000000 15.500000000 12.500000000 -36.500000000 15.500000000 13.500000000 -36.500000000 15.500000000 14.500000000 -36.500000000 15.500000000 15.500000000 -36.500000000 15.500000000 16.500000000 -36.500000000 15.500000000 17.500000000 -36.500000000 15.500000000 18.500000000 -36.500000000 15.500000000 19.500000000 -36.500000000 15.500000000 20.500000000 -36.500000000 15.500000000 21.500000000 -36.500000000 15.500000000 22.500000000 -36.500000000 15.500000000 23.500000000 -36.500000000 15.500000000 24.500000000 -36.500000000 15.500000000 25.499996185 -36.499996185 15.500000000 26.499954224 -36.499954224 15.500000000 27.499591827 -36.499591827 15.500000000 28.497470856 -36.497467041 15.500000000 29.488407135 -36.488403320 15.500000000 30.458978653 -36.458980560 15.500000000 31.384418488 -36.384422302 15.500000000 32.233222961 -36.233222961 15.500000000 32.981101990 -35.981101990 15.500000000 -35.167964935 -35.167964935 15.500000000 -34.622871399 -35.622871399 15.500000000 33.622871399 -35.622871399 15.500000000 34.167964935 -35.167964935 15.500000000 -35.981101990 -33.981101990 15.500000000 -35.622871399 -34.622871399 15.500000000 34.622871399 -34.622871399 15.500000000 34.981101990 -33.981101990 15.500000000 -36.233222961 -33.233222961 15.500000000 35.233222961 -33.233226776 15.500000000 -36.384418488 -32.384422302 15.500000000 35.384418488 -32.384422302 15.500000000 -36.458976746 -31.458978653 15.500000000 35.458980560 -31.458978653 15.500000000 -36.488403320 -30.488407135 15.500000000 35.488403320 -30.488407135 15.500000000 -36.497467041 -29.497472763 15.500000000 35.497474670 -29.497472763 15.500000000 -36.499591827 -28.499593735 15.500000000 35.499591827 -28.499593735 15.500000000 -36.499954224 -27.499954224 15.500000000 35.499954224 -27.499954224 15.500000000 -36.499996185 -26.499996185 15.500000000 35.499996185 -26.499996185 15.500000000 -36.500000000 -25.500000000 15.500000000 35.500000000 -25.500000000 15.500000000 -36.500000000 -24.500000000 15.500000000 35.500000000 -24.500000000 15.500000000 -36.500000000 -23.500000000 15.500000000 35.500000000 -23.500000000 15.500000000 -36.500000000 -22.500000000 15.500000000 35.500000000 -22.500000000 15.500000000 -36.500000000 -21.500000000 15.500000000 35.500000000 -21.500000000 15.500000000 -36.500000000 -20.500000000 15.500000000 35.500000000 -20.500000000 15.500000000 -36.500000000 -19.500000000 15.500000000 35.500000000 -19.500000000 15.500000000 -36.500000000 -18.500000000 15.500000000 35.500000000 -18.500000000 15.500000000 -36.500000000 -17.500000000 15.500000000 35.500000000 -17.500000000 15.500000000 -36.500000000 -16.500000000 15.500000000 35.500000000 -16.500000000 15.500000000 -36.500000000 -15.500000000 15.500000000 35.500000000 -15.500000000 15.500000000 -36.500000000 -14.500000000 15.500000000 35.500000000 -14.500000000 15.500000000 -36.500000000 -13.500000000 15.500000000 35.500000000 -13.500000000 15.500000000 -36.500000000 -12.500000000 15.500000000 35.500000000 -12.500000000 15.500000000 -36.500000000 -11.500000000 15.500000000 35.500000000 -11.500000000 15.500000000 -36.500000000 -10.500000000 15.500000000 35.500000000 -10.500000000 15.500000000 -36.500000000 -9.500000000 15.500000000 35.500000000 -9.500000000 15.500000000 -36.500000000 -8.500000000 15.500000000 35.500000000 -8.500000000 15.500000000 -36.500000000 -7.500000000 15.500000000 35.500000000 -7.500000000 15.500000000 -36.500000000 -6.500000000 15.500000000 35.500000000 -6.500000000 15.500000000 -36.500000000 -5.500000000 15.500000000 35.500000000 -5.500000000 15.500000000 -36.500000000 -4.500000000 15.500000000 35.500000000 -4.500000000 15.500000000 -36.500000000 -3.500000000 15.500000000 35.500000000 -3.500000000 15.500000000 -36.500000000 -2.500000000 15.500000000 35.500000000 -2.500000000 15.500000000 -36.500000000 -1.500000000 15.500000000 35.500000000 -1.500000000 15.500000000 -36.500000000 -0.500000000 15.500000000 35.500000000 -0.500000000 15.500000000 -36.500000000 0.500000000 15.500000000 35.500000000 0.500000000 15.500000000 -36.500000000 1.500000000 15.500000000 35.500000000 1.500000000 15.500000000 -36.500000000 2.500000000 15.500000000 35.500000000 2.500000000 15.500000000 -36.500000000 3.500000000 15.500000000 35.500000000 3.500000000 15.500000000 -36.500000000 4.500000000 15.500000000 35.500000000 4.500000000 15.500000000 -36.500000000 5.500000000 15.500000000 35.500000000 5.500000000 15.500000000 -36.500000000 6.500000000 15.500000000 35.500000000 6.500000000 15.500000000 -36.500000000 7.500000000 15.500000000 35.500000000 7.500000000 15.500000000 -36.500000000 8.500000000 15.500000000 35.500000000 8.500000000 15.500000000 -36.500000000 9.500000000 15.500000000 35.500000000 9.500000000 15.500000000 -36.500000000 10.500000000 15.500000000 35.500000000 10.500000000 15.500000000 -36.500000000 11.500000000 15.500000000 35.500000000 11.500000000 15.500000000 -36.500000000 12.500000000 15.500000000 35.500000000 12.500000000 15.500000000 -36.500000000 13.500000000 15.500000000 35.500000000 13.500000000 15.500000000 -36.500000000 14.500000000 15.500000000 35.500000000 14.500000000 15.500000000 -36.500000000 15.500000000 15.500000000 35.500000000 15.500000000 15.500000000 -36.500000000 16.500000000 15.500000000 35.500000000 16.500000000 15.500000000 -36.500000000 17.500000000 15.500000000 35.500000000 17.500000000 15.500000000 -36.500000000 18.500000000 15.500000000 35.500000000 18.500000000 15.500000000 -36.500000000 19.500000000 15.500000000 35.500000000 19.500000000 15.500000000 -36.500000000 20.500000000 15.500000000 35.500000000 20.500000000 15.500000000 -36.500000000 21.500000000 15.500000000 35.500000000 21.500000000 15.500000000 -36.500000000 22.500000000 15.500000000 35.500000000 22.500000000 15.500000000 -36.500000000 23.500000000 15.500000000 35.500000000 23.500000000 15.500000000 -36.500000000 24.500000000 15.500000000 35.500000000 24.500000000 15.500000000 -36.499996185 25.499996185 15.500000000 35.499996185 25.499996185 15.500000000 -36.499954224 26.499954224 15.500000000 35.499954224 26.499954224 15.500000000 -36.499591827 27.499591827 15.500000000 35.499591827 27.499591827 15.500000000 -36.497474670 28.497470856 15.500000000 35.497467041 28.497470856 15.500000000 -36.488403320 29.488407135 15.500000000 35.488403320 29.488407135 15.500000000 -36.458980560 30.458978653 15.500000000 35.458980560 30.458978653 15.500000000 -36.384422302 31.384418488 15.500000000 35.384422302 31.384418488 15.500000000 -36.233222961 32.233222961 15.500000000 35.233222961 32.233222961 15.500000000 -35.981101990 32.981101990 15.500000000 -35.622871399 33.622871399 15.500000000 34.622871399 33.622871399 15.500000000 34.981101990 32.981101990 15.500000000 -35.167964935 34.167964935 15.500000000 -34.622871399 34.622871399 15.500000000 33.622871399 34.622871399 15.500000000 34.167964935 34.167964935 15.500000000 -33.981101990 34.981101990 15.500000000 -33.233222961 35.233222961 15.500000000 -32.384422302 35.384418488 15.500000000 -31.458978653 35.458976746 15.500000000 -30.488407135 35.488403320 15.500000000 -29.497472763 35.497467041 15.500000000 -28.499593735 35.499591827 15.500000000 -27.499954224 35.499954224 15.500000000 -26.499996185 35.499996185 15.500000000 -25.500000000 35.500000000 15.500000000 -24.500000000 35.500000000 15.500000000 -23.500000000 35.500000000 15.500000000 -22.500000000 35.500000000 15.500000000 -21.500000000 35.500000000 15.500000000 -20.500000000 35.500000000 15.500000000 -19.500000000 35.500000000 15.500000000 -18.500000000 35.500000000 15.500000000 -17.500000000 35.500000000 15.500000000 -16.500000000 35.500000000 15.500000000 -15.500000000 35.500000000 15.500000000 -14.500000000 35.500000000 15.500000000 -13.500000000 35.500000000 15.500000000 -12.500000000 35.500000000 15.500000000 -11.500000000 35.500000000 15.500000000 -10.500000000 35.500000000 15.500000000 -9.500000000 35.500000000 15.500000000 -8.500000000 35.500000000 15.500000000 -7.500000000 35.500000000 15.500000000 -6.500000000 35.500000000 15.500000000 -5.500000000 35.500000000 15.500000000 -4.500000000 35.500000000 15.500000000 -3.500000000 35.500000000 15.500000000 -2.500000000 35.500000000 15.500000000 -1.500000000 35.500000000 15.500000000 -0.500000000 35.500000000 15.500000000 0.500000000 35.500000000 15.500000000 1.500000000 35.500000000 15.500000000 2.500000000 35.500000000 15.500000000 3.500000000 35.500000000 15.500000000 4.500000000 35.500000000 15.500000000 5.500000000 35.500000000 15.500000000 6.500000000 35.500000000 15.500000000 7.500000000 35.500000000 15.500000000 8.500000000 35.500000000 15.500000000 9.500000000 35.500000000 15.500000000 10.500000000 35.500000000 15.500000000 11.500000000 35.500000000 15.500000000 12.500000000 35.500000000 15.500000000 13.500000000 35.500000000 15.500000000 14.500000000 35.500000000 15.500000000 15.500000000 35.500000000 15.500000000 16.500000000 35.500000000 15.500000000 17.500000000 35.500000000 15.500000000 18.500000000 35.500000000 15.500000000 19.500000000 35.500000000 15.500000000 20.500000000 35.500000000 15.500000000 21.500000000 35.500000000 15.500000000 22.500000000 35.500000000 15.500000000 23.500000000 35.500000000 15.500000000 24.500000000 35.500000000 15.500000000 25.499996185 35.499996185 15.500000000 26.499954224 35.499954224 15.500000000 27.499591827 35.499591827 15.500000000 28.497470856 35.497474670 15.500000000 29.488407135 35.488403320 15.500000000 30.458978653 35.458980560 15.500000000 31.384418488 35.384422302 15.500000000 32.233222961 35.233222961 15.500000000 32.981101990 34.981101990 15.500000000 -33.981101990 -35.981101990 16.500000000 -33.233226776 -36.233222961 16.500000000 -32.384422302 -36.384418488 16.500000000 -31.458978653 -36.458980560 16.500000000 -30.488407135 -36.488403320 16.500000000 -29.497472763 -36.497474670 16.500000000 -28.499593735 -36.499591827 16.500000000 -27.499954224 -36.499954224 16.500000000 -26.499996185 -36.499996185 16.500000000 -25.500000000 -36.500000000 16.500000000 -24.500000000 -36.500000000 16.500000000 -23.500000000 -36.500000000 16.500000000 -22.500000000 -36.500000000 16.500000000 -21.500000000 -36.500000000 16.500000000 -20.500000000 -36.500000000 16.500000000 -19.500000000 -36.500000000 16.500000000 -18.500000000 -36.500000000 16.500000000 -17.500000000 -36.500000000 16.500000000 -16.500000000 -36.500000000 16.500000000 -15.500000000 -36.500000000 16.500000000 -14.500000000 -36.500000000 16.500000000 -13.500000000 -36.500000000 16.500000000 -12.500000000 -36.500000000 16.500000000 -11.500000000 -36.500000000 16.500000000 -10.500000000 -36.500000000 16.500000000 -9.500000000 -36.500000000 16.500000000 -8.500000000 -36.500000000 16.500000000 -7.500000000 -36.500000000 16.500000000 -6.500000000 -36.500000000 16.500000000 -5.500000000 -36.500000000 16.500000000 -4.500000000 -36.500000000 16.500000000 -3.500000000 -36.500000000 16.500000000 -2.500000000 -36.500000000 16.500000000 -1.500000000 -36.500000000 16.500000000 -0.500000000 -36.500000000 16.500000000 0.500000000 -36.500000000 16.500000000 1.500000000 -36.500000000 16.500000000 2.500000000 -36.500000000 16.500000000 3.500000000 -36.500000000 16.500000000 4.500000000 -36.500000000 16.500000000 5.500000000 -36.500000000 16.500000000 6.500000000 -36.500000000 16.500000000 7.500000000 -36.500000000 16.500000000 8.500000000 -36.500000000 16.500000000 9.500000000 -36.500000000 16.500000000 10.500000000 -36.500000000 16.500000000 11.500000000 -36.500000000 16.500000000 12.500000000 -36.500000000 16.500000000 13.500000000 -36.500000000 16.500000000 14.500000000 -36.500000000 16.500000000 15.500000000 -36.500000000 16.500000000 16.500000000 -36.500000000 16.500000000 17.500000000 -36.500000000 16.500000000 18.500000000 -36.500000000 16.500000000 19.500000000 -36.500000000 16.500000000 20.500000000 -36.500000000 16.500000000 21.500000000 -36.500000000 16.500000000 22.500000000 -36.500000000 16.500000000 23.500000000 -36.500000000 16.500000000 24.500000000 -36.500000000 16.500000000 25.499996185 -36.499996185 16.500000000 26.499954224 -36.499954224 16.500000000 27.499591827 -36.499591827 16.500000000 28.497470856 -36.497467041 16.500000000 29.488407135 -36.488403320 16.500000000 30.458978653 -36.458980560 16.500000000 31.384418488 -36.384422302 16.500000000 32.233222961 -36.233222961 16.500000000 32.981101990 -35.981101990 16.500000000 -35.167964935 -35.167964935 16.500000000 -34.622871399 -35.622871399 16.500000000 33.622871399 -35.622871399 16.500000000 34.167964935 -35.167964935 16.500000000 -35.981101990 -33.981101990 16.500000000 -35.622871399 -34.622871399 16.500000000 34.622871399 -34.622871399 16.500000000 34.981101990 -33.981101990 16.500000000 -36.233222961 -33.233222961 16.500000000 35.233222961 -33.233226776 16.500000000 -36.384418488 -32.384422302 16.500000000 35.384418488 -32.384422302 16.500000000 -36.458976746 -31.458978653 16.500000000 35.458980560 -31.458978653 16.500000000 -36.488403320 -30.488407135 16.500000000 35.488403320 -30.488407135 16.500000000 -36.497467041 -29.497472763 16.500000000 35.497474670 -29.497472763 16.500000000 -36.499591827 -28.499593735 16.500000000 35.499591827 -28.499593735 16.500000000 -36.499954224 -27.499954224 16.500000000 35.499954224 -27.499954224 16.500000000 -36.499996185 -26.499996185 16.500000000 35.499996185 -26.499996185 16.500000000 -36.500000000 -25.500000000 16.500000000 35.500000000 -25.500000000 16.500000000 -36.500000000 -24.500000000 16.500000000 35.500000000 -24.500000000 16.500000000 -36.500000000 -23.500000000 16.500000000 35.500000000 -23.500000000 16.500000000 -36.500000000 -22.500000000 16.500000000 35.500000000 -22.500000000 16.500000000 -36.500000000 -21.500000000 16.500000000 35.500000000 -21.500000000 16.500000000 -36.500000000 -20.500000000 16.500000000 35.500000000 -20.500000000 16.500000000 -36.500000000 -19.500000000 16.500000000 35.500000000 -19.500000000 16.500000000 -36.500000000 -18.500000000 16.500000000 35.500000000 -18.500000000 16.500000000 -36.500000000 -17.500000000 16.500000000 35.500000000 -17.500000000 16.500000000 -36.500000000 -16.500000000 16.500000000 35.500000000 -16.500000000 16.500000000 -36.500000000 -15.500000000 16.500000000 35.500000000 -15.500000000 16.500000000 -36.500000000 -14.500000000 16.500000000 35.500000000 -14.500000000 16.500000000 -36.500000000 -13.500000000 16.500000000 35.500000000 -13.500000000 16.500000000 -36.500000000 -12.500000000 16.500000000 35.500000000 -12.500000000 16.500000000 -36.500000000 -11.500000000 16.500000000 35.500000000 -11.500000000 16.500000000 -36.500000000 -10.500000000 16.500000000 35.500000000 -10.500000000 16.500000000 -36.500000000 -9.500000000 16.500000000 35.500000000 -9.500000000 16.500000000 -36.500000000 -8.500000000 16.500000000 35.500000000 -8.500000000 16.500000000 -36.500000000 -7.500000000 16.500000000 35.500000000 -7.500000000 16.500000000 -36.500000000 -6.500000000 16.500000000 35.500000000 -6.500000000 16.500000000 -36.500000000 -5.500000000 16.500000000 35.500000000 -5.500000000 16.500000000 -36.500000000 -4.500000000 16.500000000 35.500000000 -4.500000000 16.500000000 -36.500000000 -3.500000000 16.500000000 35.500000000 -3.500000000 16.500000000 -36.500000000 -2.500000000 16.500000000 35.500000000 -2.500000000 16.500000000 -36.500000000 -1.500000000 16.500000000 35.500000000 -1.500000000 16.500000000 -36.500000000 -0.500000000 16.500000000 35.500000000 -0.500000000 16.500000000 -36.500000000 0.500000000 16.500000000 35.500000000 0.500000000 16.500000000 -36.500000000 1.500000000 16.500000000 35.500000000 1.500000000 16.500000000 -36.500000000 2.500000000 16.500000000 35.500000000 2.500000000 16.500000000 -36.500000000 3.500000000 16.500000000 35.500000000 3.500000000 16.500000000 -36.500000000 4.500000000 16.500000000 35.500000000 4.500000000 16.500000000 -36.500000000 5.500000000 16.500000000 35.500000000 5.500000000 16.500000000 -36.500000000 6.500000000 16.500000000 35.500000000 6.500000000 16.500000000 -36.500000000 7.500000000 16.500000000 35.500000000 7.500000000 16.500000000 -36.500000000 8.500000000 16.500000000 35.500000000 8.500000000 16.500000000 -36.500000000 9.500000000 16.500000000 35.500000000 9.500000000 16.500000000 -36.500000000 10.500000000 16.500000000 35.500000000 10.500000000 16.500000000 -36.500000000 11.500000000 16.500000000 35.500000000 11.500000000 16.500000000 -36.500000000 12.500000000 16.500000000 35.500000000 12.500000000 16.500000000 -36.500000000 13.500000000 16.500000000 35.500000000 13.500000000 16.500000000 -36.500000000 14.500000000 16.500000000 35.500000000 14.500000000 16.500000000 -36.500000000 15.500000000 16.500000000 35.500000000 15.500000000 16.500000000 -36.500000000 16.500000000 16.500000000 35.500000000 16.500000000 16.500000000 -36.500000000 17.500000000 16.500000000 35.500000000 17.500000000 16.500000000 -36.500000000 18.500000000 16.500000000 35.500000000 18.500000000 16.500000000 -36.500000000 19.500000000 16.500000000 35.500000000 19.500000000 16.500000000 -36.500000000 20.500000000 16.500000000 35.500000000 20.500000000 16.500000000 -36.500000000 21.500000000 16.500000000 35.500000000 21.500000000 16.500000000 -36.500000000 22.500000000 16.500000000 35.500000000 22.500000000 16.500000000 -36.500000000 23.500000000 16.500000000 35.500000000 23.500000000 16.500000000 -36.500000000 24.500000000 16.500000000 35.500000000 24.500000000 16.500000000 -36.499996185 25.499996185 16.500000000 35.499996185 25.499996185 16.500000000 -36.499954224 26.499954224 16.500000000 35.499954224 26.499954224 16.500000000 -36.499591827 27.499591827 16.500000000 35.499591827 27.499591827 16.500000000 -36.497474670 28.497470856 16.500000000 35.497467041 28.497470856 16.500000000 -36.488403320 29.488407135 16.500000000 35.488403320 29.488407135 16.500000000 -36.458980560 30.458978653 16.500000000 35.458980560 30.458978653 16.500000000 -36.384422302 31.384418488 16.500000000 35.384422302 31.384418488 16.500000000 -36.233222961 32.233222961 16.500000000 35.233222961 32.233222961 16.500000000 -35.981101990 32.981101990 16.500000000 -35.622871399 33.622871399 16.500000000 34.622871399 33.622871399 16.500000000 34.981101990 32.981101990 16.500000000 -35.167964935 34.167964935 16.500000000 -34.622871399 34.622871399 16.500000000 33.622871399 34.622871399 16.500000000 34.167964935 34.167964935 16.500000000 -33.981101990 34.981101990 16.500000000 -33.233222961 35.233222961 16.500000000 -32.384422302 35.384418488 16.500000000 -31.458978653 35.458976746 16.500000000 -30.488407135 35.488403320 16.500000000 -29.497472763 35.497467041 16.500000000 -28.499593735 35.499591827 16.500000000 -27.499954224 35.499954224 16.500000000 -26.499996185 35.499996185 16.500000000 -25.500000000 35.500000000 16.500000000 -24.500000000 35.500000000 16.500000000 -23.500000000 35.500000000 16.500000000 -22.500000000 35.500000000 16.500000000 -21.500000000 35.500000000 16.500000000 -20.500000000 35.500000000 16.500000000 -19.500000000 35.500000000 16.500000000 -18.500000000 35.500000000 16.500000000 -17.500000000 35.500000000 16.500000000 -16.500000000 35.500000000 16.500000000 -15.500000000 35.500000000 16.500000000 -14.500000000 35.500000000 16.500000000 -13.500000000 35.500000000 16.500000000 -12.500000000 35.500000000 16.500000000 -11.500000000 35.500000000 16.500000000 -10.500000000 35.500000000 16.500000000 -9.500000000 35.500000000 16.500000000 -8.500000000 35.500000000 16.500000000 -7.500000000 35.500000000 16.500000000 -6.500000000 35.500000000 16.500000000 -5.500000000 35.500000000 16.500000000 -4.500000000 35.500000000 16.500000000 -3.500000000 35.500000000 16.500000000 -2.500000000 35.500000000 16.500000000 -1.500000000 35.500000000 16.500000000 -0.500000000 35.500000000 16.500000000 0.500000000 35.500000000 16.500000000 1.500000000 35.500000000 16.500000000 2.500000000 35.500000000 16.500000000 3.500000000 35.500000000 16.500000000 4.500000000 35.500000000 16.500000000 5.500000000 35.500000000 16.500000000 6.500000000 35.500000000 16.500000000 7.500000000 35.500000000 16.500000000 8.500000000 35.500000000 16.500000000 9.500000000 35.500000000 16.500000000 10.500000000 35.500000000 16.500000000 11.500000000 35.500000000 16.500000000 12.500000000 35.500000000 16.500000000 13.500000000 35.500000000 16.500000000 14.500000000 35.500000000 16.500000000 15.500000000 35.500000000 16.500000000 16.500000000 35.500000000 16.500000000 17.500000000 35.500000000 16.500000000 18.500000000 35.500000000 16.500000000 19.500000000 35.500000000 16.500000000 20.500000000 35.500000000 16.500000000 21.500000000 35.500000000 16.500000000 22.500000000 35.500000000 16.500000000 23.500000000 35.500000000 16.500000000 24.500000000 35.500000000 16.500000000 25.499996185 35.499996185 16.500000000 26.499954224 35.499954224 16.500000000 27.499591827 35.499591827 16.500000000 28.497470856 35.497474670 16.500000000 29.488407135 35.488403320 16.500000000 30.458978653 35.458980560 16.500000000 31.384418488 35.384422302 16.500000000 32.233222961 35.233222961 16.500000000 32.981101990 34.981101990 16.500000000 -33.981101990 -35.981101990 17.500000000 -33.233226776 -36.233222961 17.500000000 -32.384422302 -36.384418488 17.500000000 -31.458978653 -36.458980560 17.500000000 -30.488407135 -36.488403320 17.500000000 -29.497472763 -36.497474670 17.500000000 -28.499593735 -36.499591827 17.500000000 -27.499954224 -36.499954224 17.500000000 -26.499996185 -36.499996185 17.500000000 -25.500000000 -36.500000000 17.500000000 -24.500000000 -36.500000000 17.500000000 -23.500000000 -36.500000000 17.500000000 -22.500000000 -36.500000000 17.500000000 -21.500000000 -36.500000000 17.500000000 -20.500000000 -36.500000000 17.500000000 -19.500000000 -36.500000000 17.500000000 -18.500000000 -36.500000000 17.500000000 -17.500000000 -36.500000000 17.500000000 -16.500000000 -36.500000000 17.500000000 -15.500000000 -36.500000000 17.500000000 -14.500000000 -36.500000000 17.500000000 -13.500000000 -36.500000000 17.500000000 -12.500000000 -36.500000000 17.500000000 -11.500000000 -36.500000000 17.500000000 -10.500000000 -36.500000000 17.500000000 -9.500000000 -36.500000000 17.500000000 -8.500000000 -36.500000000 17.500000000 -7.500000000 -36.500000000 17.500000000 -6.500000000 -36.500000000 17.500000000 -5.500000000 -36.500000000 17.500000000 -4.500000000 -36.500000000 17.500000000 -3.500000000 -36.500000000 17.500000000 -2.500000000 -36.500000000 17.500000000 -1.500000000 -36.500000000 17.500000000 -0.500000000 -36.500000000 17.500000000 0.500000000 -36.500000000 17.500000000 1.500000000 -36.500000000 17.500000000 2.500000000 -36.500000000 17.500000000 3.500000000 -36.500000000 17.500000000 4.500000000 -36.500000000 17.500000000 5.500000000 -36.500000000 17.500000000 6.500000000 -36.500000000 17.500000000 7.500000000 -36.500000000 17.500000000 8.500000000 -36.500000000 17.500000000 9.500000000 -36.500000000 17.500000000 10.500000000 -36.500000000 17.500000000 11.500000000 -36.500000000 17.500000000 12.500000000 -36.500000000 17.500000000 13.500000000 -36.500000000 17.500000000 14.500000000 -36.500000000 17.500000000 15.500000000 -36.500000000 17.500000000 16.500000000 -36.500000000 17.500000000 17.500000000 -36.500000000 17.500000000 18.500000000 -36.500000000 17.500000000 19.500000000 -36.500000000 17.500000000 20.500000000 -36.500000000 17.500000000 21.500000000 -36.500000000 17.500000000 22.500000000 -36.500000000 17.500000000 23.500000000 -36.500000000 17.500000000 24.500000000 -36.500000000 17.500000000 25.499996185 -36.499996185 17.500000000 26.499954224 -36.499954224 17.500000000 27.499591827 -36.499591827 17.500000000 28.497470856 -36.497467041 17.500000000 29.488407135 -36.488403320 17.500000000 30.458978653 -36.458980560 17.500000000 31.384418488 -36.384422302 17.500000000 32.233222961 -36.233222961 17.500000000 32.981101990 -35.981101990 17.500000000 -35.167964935 -35.167964935 17.500000000 -34.622871399 -35.622871399 17.500000000 33.622871399 -35.622871399 17.500000000 34.167964935 -35.167964935 17.500000000 -35.981101990 -33.981101990 17.500000000 -35.622871399 -34.622871399 17.500000000 34.622871399 -34.622871399 17.500000000 34.981101990 -33.981101990 17.500000000 -36.233222961 -33.233222961 17.500000000 35.233222961 -33.233226776 17.500000000 -36.384418488 -32.384422302 17.500000000 35.384418488 -32.384422302 17.500000000 -36.458976746 -31.458978653 17.500000000 35.458980560 -31.458978653 17.500000000 -36.488403320 -30.488407135 17.500000000 35.488403320 -30.488407135 17.500000000 -36.497467041 -29.497472763 17.500000000 35.497474670 -29.497472763 17.500000000 -36.499591827 -28.499593735 17.500000000 35.499591827 -28.499593735 17.500000000 -36.499954224 -27.499954224 17.500000000 35.499954224 -27.499954224 17.500000000 -36.499996185 -26.499996185 17.500000000 35.499996185 -26.499996185 17.500000000 -36.500000000 -25.500000000 17.500000000 35.500000000 -25.500000000 17.500000000 -36.500000000 -24.500000000 17.500000000 35.500000000 -24.500000000 17.500000000 -36.500000000 -23.500000000 17.500000000 35.500000000 -23.500000000 17.500000000 -36.500000000 -22.500000000 17.500000000 35.500000000 -22.500000000 17.500000000 -36.500000000 -21.500000000 17.500000000 35.500000000 -21.500000000 17.500000000 -36.500000000 -20.500000000 17.500000000 35.500000000 -20.500000000 17.500000000 -36.500000000 -19.500000000 17.500000000 35.500000000 -19.500000000 17.500000000 -36.500000000 -18.500000000 17.500000000 35.500000000 -18.500000000 17.500000000 -36.500000000 -17.500000000 17.500000000 35.500000000 -17.500000000 17.500000000 -36.500000000 -16.500000000 17.500000000 35.500000000 -16.500000000 17.500000000 -36.500000000 -15.500000000 17.500000000 35.500000000 -15.500000000 17.500000000 -36.500000000 -14.500000000 17.500000000 35.500000000 -14.500000000 17.500000000 -36.500000000 -13.500000000 17.500000000 35.500000000 -13.500000000 17.500000000 -36.500000000 -12.500000000 17.500000000 35.500000000 -12.500000000 17.500000000 -36.500000000 -11.500000000 17.500000000 35.500000000 -11.500000000 17.500000000 -36.500000000 -10.500000000 17.500000000 35.500000000 -10.500000000 17.500000000 -36.500000000 -9.500000000 17.500000000 35.500000000 -9.500000000 17.500000000 -36.500000000 -8.500000000 17.500000000 35.500000000 -8.500000000 17.500000000 -36.500000000 -7.500000000 17.500000000 35.500000000 -7.500000000 17.500000000 -36.500000000 -6.500000000 17.500000000 35.500000000 -6.500000000 17.500000000 -36.500000000 -5.500000000 17.500000000 35.500000000 -5.500000000 17.500000000 -36.500000000 -4.500000000 17.500000000 35.500000000 -4.500000000 17.500000000 -36.500000000 -3.500000000 17.500000000 35.500000000 -3.500000000 17.500000000 -36.500000000 -2.500000000 17.500000000 35.500000000 -2.500000000 17.500000000 -36.500000000 -1.500000000 17.500000000 35.500000000 -1.500000000 17.500000000 -36.500000000 -0.500000000 17.500000000 35.500000000 -0.500000000 17.500000000 -36.500000000 0.500000000 17.500000000 35.500000000 0.500000000 17.500000000 -36.500000000 1.500000000 17.500000000 35.500000000 1.500000000 17.500000000 -36.500000000 2.500000000 17.500000000 35.500000000 2.500000000 17.500000000 -36.500000000 3.500000000 17.500000000 35.500000000 3.500000000 17.500000000 -36.500000000 4.500000000 17.500000000 35.500000000 4.500000000 17.500000000 -36.500000000 5.500000000 17.500000000 35.500000000 5.500000000 17.500000000 -36.500000000 6.500000000 17.500000000 35.500000000 6.500000000 17.500000000 -36.500000000 7.500000000 17.500000000 35.500000000 7.500000000 17.500000000 -36.500000000 8.500000000 17.500000000 35.500000000 8.500000000 17.500000000 -36.500000000 9.500000000 17.500000000 35.500000000 9.500000000 17.500000000 -36.500000000 10.500000000 17.500000000 35.500000000 10.500000000 17.500000000 -36.500000000 11.500000000 17.500000000 35.500000000 11.500000000 17.500000000 -36.500000000 12.500000000 17.500000000 35.500000000 12.500000000 17.500000000 -36.500000000 13.500000000 17.500000000 35.500000000 13.500000000 17.500000000 -36.500000000 14.500000000 17.500000000 35.500000000 14.500000000 17.500000000 -36.500000000 15.500000000 17.500000000 35.500000000 15.500000000 17.500000000 -36.500000000 16.500000000 17.500000000 35.500000000 16.500000000 17.500000000 -36.500000000 17.500000000 17.500000000 35.500000000 17.500000000 17.500000000 -36.500000000 18.500000000 17.500000000 35.500000000 18.500000000 17.500000000 -36.500000000 19.500000000 17.500000000 35.500000000 19.500000000 17.500000000 -36.500000000 20.500000000 17.500000000 35.500000000 20.500000000 17.500000000 -36.500000000 21.500000000 17.500000000 35.500000000 21.500000000 17.500000000 -36.500000000 22.500000000 17.500000000 35.500000000 22.500000000 17.500000000 -36.500000000 23.500000000 17.500000000 35.500000000 23.500000000 17.500000000 -36.500000000 24.500000000 17.500000000 35.500000000 24.500000000 17.500000000 -36.499996185 25.499996185 17.500000000 35.499996185 25.499996185 17.500000000 -36.499954224 26.499954224 17.500000000 35.499954224 26.499954224 17.500000000 -36.499591827 27.499591827 17.500000000 35.499591827 27.499591827 17.500000000 -36.497474670 28.497470856 17.500000000 35.497467041 28.497470856 17.500000000 -36.488403320 29.488407135 17.500000000 35.488403320 29.488407135 17.500000000 -36.458980560 30.458978653 17.500000000 35.458980560 30.458978653 17.500000000 -36.384422302 31.384418488 17.500000000 35.384422302 31.384418488 17.500000000 -36.233222961 32.233222961 17.500000000 35.233222961 32.233222961 17.500000000 -35.981101990 32.981101990 17.500000000 -35.622871399 33.622871399 17.500000000 34.622871399 33.622871399 17.500000000 34.981101990 32.981101990 17.500000000 -35.167964935 34.167964935 17.500000000 -34.622871399 34.622871399 17.500000000 33.622871399 34.622871399 17.500000000 34.167964935 34.167964935 17.500000000 -33.981101990 34.981101990 17.500000000 -33.233222961 35.233222961 17.500000000 -32.384422302 35.384418488 17.500000000 -31.458978653 35.458976746 17.500000000 -30.488407135 35.488403320 17.500000000 -29.497472763 35.497467041 17.500000000 -28.499593735 35.499591827 17.500000000 -27.499954224 35.499954224 17.500000000 -26.499996185 35.499996185 17.500000000 -25.500000000 35.500000000 17.500000000 -24.500000000 35.500000000 17.500000000 -23.500000000 35.500000000 17.500000000 -22.500000000 35.500000000 17.500000000 -21.500000000 35.500000000 17.500000000 -20.500000000 35.500000000 17.500000000 -19.500000000 35.500000000 17.500000000 -18.500000000 35.500000000 17.500000000 -17.500000000 35.500000000 17.500000000 -16.500000000 35.500000000 17.500000000 -15.500000000 35.500000000 17.500000000 -14.500000000 35.500000000 17.500000000 -13.500000000 35.500000000 17.500000000 -12.500000000 35.500000000 17.500000000 -11.500000000 35.500000000 17.500000000 -10.500000000 35.500000000 17.500000000 -9.500000000 35.500000000 17.500000000 -8.500000000 35.500000000 17.500000000 -7.500000000 35.500000000 17.500000000 -6.500000000 35.500000000 17.500000000 -5.500000000 35.500000000 17.500000000 -4.500000000 35.500000000 17.500000000 -3.500000000 35.500000000 17.500000000 -2.500000000 35.500000000 17.500000000 -1.500000000 35.500000000 17.500000000 -0.500000000 35.500000000 17.500000000 0.500000000 35.500000000 17.500000000 1.500000000 35.500000000 17.500000000 2.500000000 35.500000000 17.500000000 3.500000000 35.500000000 17.500000000 4.500000000 35.500000000 17.500000000 5.500000000 35.500000000 17.500000000 6.500000000 35.500000000 17.500000000 7.500000000 35.500000000 17.500000000 8.500000000 35.500000000 17.500000000 9.500000000 35.500000000 17.500000000 10.500000000 35.500000000 17.500000000 11.500000000 35.500000000 17.500000000 12.500000000 35.500000000 17.500000000 13.500000000 35.500000000 17.500000000 14.500000000 35.500000000 17.500000000 15.500000000 35.500000000 17.500000000 16.500000000 35.500000000 17.500000000 17.500000000 35.500000000 17.500000000 18.500000000 35.500000000 17.500000000 19.500000000 35.500000000 17.500000000 20.500000000 35.500000000 17.500000000 21.500000000 35.500000000 17.500000000 22.500000000 35.500000000 17.500000000 23.500000000 35.500000000 17.500000000 24.500000000 35.500000000 17.500000000 25.499996185 35.499996185 17.500000000 26.499954224 35.499954224 17.500000000 27.499591827 35.499591827 17.500000000 28.497470856 35.497474670 17.500000000 29.488407135 35.488403320 17.500000000 30.458978653 35.458980560 17.500000000 31.384418488 35.384422302 17.500000000 32.233222961 35.233222961 17.500000000 32.981101990 34.981101990 17.500000000 -33.981101990 -35.981101990 18.500000000 -33.233226776 -36.233222961 18.500000000 -32.384422302 -36.384418488 18.500000000 -31.458978653 -36.458980560 18.500000000 -30.488407135 -36.488403320 18.500000000 -29.497472763 -36.497474670 18.500000000 -28.499593735 -36.499591827 18.500000000 -27.499954224 -36.499954224 18.500000000 -26.499996185 -36.499996185 18.500000000 -25.500000000 -36.500000000 18.500000000 -24.500000000 -36.500000000 18.500000000 -23.500000000 -36.500000000 18.500000000 -22.500000000 -36.500000000 18.500000000 -21.500000000 -36.500000000 18.500000000 -20.500000000 -36.500000000 18.500000000 -19.500000000 -36.500000000 18.500000000 -18.500000000 -36.500000000 18.500000000 -17.500000000 -36.500000000 18.500000000 -16.500000000 -36.500000000 18.500000000 -15.500000000 -36.500000000 18.500000000 -14.500000000 -36.500000000 18.500000000 -13.500000000 -36.500000000 18.500000000 -12.500000000 -36.500000000 18.500000000 -11.500000000 -36.500000000 18.500000000 -10.500000000 -36.500000000 18.500000000 -9.500000000 -36.500000000 18.500000000 -8.500000000 -36.500000000 18.500000000 -7.500000000 -36.500000000 18.500000000 -6.500000000 -36.500000000 18.500000000 -5.500000000 -36.500000000 18.500000000 -4.500000000 -36.500000000 18.500000000 -3.500000000 -36.500000000 18.500000000 -2.500000000 -36.500000000 18.500000000 -1.500000000 -36.500000000 18.500000000 -0.500000000 -36.500000000 18.500000000 0.500000000 -36.500000000 18.500000000 1.500000000 -36.500000000 18.500000000 2.500000000 -36.500000000 18.500000000 3.500000000 -36.500000000 18.500000000 4.500000000 -36.500000000 18.500000000 5.500000000 -36.500000000 18.500000000 6.500000000 -36.500000000 18.500000000 7.500000000 -36.500000000 18.500000000 8.500000000 -36.500000000 18.500000000 9.500000000 -36.500000000 18.500000000 10.500000000 -36.500000000 18.500000000 11.500000000 -36.500000000 18.500000000 12.500000000 -36.500000000 18.500000000 13.500000000 -36.500000000 18.500000000 14.500000000 -36.500000000 18.500000000 15.500000000 -36.500000000 18.500000000 16.500000000 -36.500000000 18.500000000 17.500000000 -36.500000000 18.500000000 18.500000000 -36.500000000 18.500000000 19.500000000 -36.500000000 18.500000000 20.500000000 -36.500000000 18.500000000 21.500000000 -36.500000000 18.500000000 22.500000000 -36.500000000 18.500000000 23.500000000 -36.500000000 18.500000000 24.500000000 -36.500000000 18.500000000 25.499996185 -36.499996185 18.500000000 26.499954224 -36.499954224 18.500000000 27.499591827 -36.499591827 18.500000000 28.497470856 -36.497467041 18.500000000 29.488407135 -36.488403320 18.500000000 30.458978653 -36.458980560 18.500000000 31.384418488 -36.384422302 18.500000000 32.233222961 -36.233222961 18.500000000 32.981101990 -35.981101990 18.500000000 -35.167964935 -35.167964935 18.500000000 -34.622871399 -35.622871399 18.500000000 33.622871399 -35.622871399 18.500000000 34.167964935 -35.167964935 18.500000000 -35.981101990 -33.981101990 18.500000000 -35.622871399 -34.622871399 18.500000000 34.622871399 -34.622871399 18.500000000 34.981101990 -33.981101990 18.500000000 -36.233222961 -33.233222961 18.500000000 35.233222961 -33.233226776 18.500000000 -36.384418488 -32.384422302 18.500000000 35.384418488 -32.384422302 18.500000000 -36.458976746 -31.458978653 18.500000000 35.458980560 -31.458978653 18.500000000 -36.488403320 -30.488407135 18.500000000 35.488403320 -30.488407135 18.500000000 -36.497467041 -29.497472763 18.500000000 35.497474670 -29.497472763 18.500000000 -36.499591827 -28.499593735 18.500000000 35.499591827 -28.499593735 18.500000000 -36.499954224 -27.499954224 18.500000000 35.499954224 -27.499954224 18.500000000 -36.499996185 -26.499996185 18.500000000 35.499996185 -26.499996185 18.500000000 -36.500000000 -25.500000000 18.500000000 35.500000000 -25.500000000 18.500000000 -36.500000000 -24.500000000 18.500000000 35.500000000 -24.500000000 18.500000000 -36.500000000 -23.500000000 18.500000000 35.500000000 -23.500000000 18.500000000 -36.500000000 -22.500000000 18.500000000 35.500000000 -22.500000000 18.500000000 -36.500000000 -21.500000000 18.500000000 35.500000000 -21.500000000 18.500000000 -36.500000000 -20.500000000 18.500000000 35.500000000 -20.500000000 18.500000000 -36.500000000 -19.500000000 18.500000000 35.500000000 -19.500000000 18.500000000 -36.500000000 -18.500000000 18.500000000 35.500000000 -18.500000000 18.500000000 -36.500000000 -17.500000000 18.500000000 35.500000000 -17.500000000 18.500000000 -36.500000000 -16.500000000 18.500000000 35.500000000 -16.500000000 18.500000000 -36.500000000 -15.500000000 18.500000000 35.500000000 -15.500000000 18.500000000 -36.500000000 -14.500000000 18.500000000 35.500000000 -14.500000000 18.500000000 -36.500000000 -13.500000000 18.500000000 35.500000000 -13.500000000 18.500000000 -36.500000000 -12.500000000 18.500000000 35.500000000 -12.500000000 18.500000000 -36.500000000 -11.500000000 18.500000000 35.500000000 -11.500000000 18.500000000 -36.500000000 -10.500000000 18.500000000 35.500000000 -10.500000000 18.500000000 -36.500000000 -9.500000000 18.500000000 35.500000000 -9.500000000 18.500000000 -36.500000000 -8.500000000 18.500000000 35.500000000 -8.500000000 18.500000000 -36.500000000 -7.500000000 18.500000000 35.500000000 -7.500000000 18.500000000 -36.500000000 -6.500000000 18.500000000 35.500000000 -6.500000000 18.500000000 -36.500000000 -5.500000000 18.500000000 35.500000000 -5.500000000 18.500000000 -36.500000000 -4.500000000 18.500000000 35.500000000 -4.500000000 18.500000000 -36.500000000 -3.500000000 18.500000000 35.500000000 -3.500000000 18.500000000 -36.500000000 -2.500000000 18.500000000 35.500000000 -2.500000000 18.500000000 -36.500000000 -1.500000000 18.500000000 35.500000000 -1.500000000 18.500000000 -36.500000000 -0.500000000 18.500000000 35.500000000 -0.500000000 18.500000000 -36.500000000 0.500000000 18.500000000 35.500000000 0.500000000 18.500000000 -36.500000000 1.500000000 18.500000000 35.500000000 1.500000000 18.500000000 -36.500000000 2.500000000 18.500000000 35.500000000 2.500000000 18.500000000 -36.500000000 3.500000000 18.500000000 35.500000000 3.500000000 18.500000000 -36.500000000 4.500000000 18.500000000 35.500000000 4.500000000 18.500000000 -36.500000000 5.500000000 18.500000000 35.500000000 5.500000000 18.500000000 -36.500000000 6.500000000 18.500000000 35.500000000 6.500000000 18.500000000 -36.500000000 7.500000000 18.500000000 35.500000000 7.500000000 18.500000000 -36.500000000 8.500000000 18.500000000 35.500000000 8.500000000 18.500000000 -36.500000000 9.500000000 18.500000000 35.500000000 9.500000000 18.500000000 -36.500000000 10.500000000 18.500000000 35.500000000 10.500000000 18.500000000 -36.500000000 11.500000000 18.500000000 35.500000000 11.500000000 18.500000000 -36.500000000 12.500000000 18.500000000 35.500000000 12.500000000 18.500000000 -36.500000000 13.500000000 18.500000000 35.500000000 13.500000000 18.500000000 -36.500000000 14.500000000 18.500000000 35.500000000 14.500000000 18.500000000 -36.500000000 15.500000000 18.500000000 35.500000000 15.500000000 18.500000000 -36.500000000 16.500000000 18.500000000 35.500000000 16.500000000 18.500000000 -36.500000000 17.500000000 18.500000000 35.500000000 17.500000000 18.500000000 -36.500000000 18.500000000 18.500000000 35.500000000 18.500000000 18.500000000 -36.500000000 19.500000000 18.500000000 35.500000000 19.500000000 18.500000000 -36.500000000 20.500000000 18.500000000 35.500000000 20.500000000 18.500000000 -36.500000000 21.500000000 18.500000000 35.500000000 21.500000000 18.500000000 -36.500000000 22.500000000 18.500000000 35.500000000 22.500000000 18.500000000 -36.500000000 23.500000000 18.500000000 35.500000000 23.500000000 18.500000000 -36.500000000 24.500000000 18.500000000 35.500000000 24.500000000 18.500000000 -36.499996185 25.499996185 18.500000000 35.499996185 25.499996185 18.500000000 -36.499954224 26.499954224 18.500000000 35.499954224 26.499954224 18.500000000 -36.499591827 27.499591827 18.500000000 35.499591827 27.499591827 18.500000000 -36.497474670 28.497470856 18.500000000 35.497467041 28.497470856 18.500000000 -36.488403320 29.488407135 18.500000000 35.488403320 29.488407135 18.500000000 -36.458980560 30.458978653 18.500000000 35.458980560 30.458978653 18.500000000 -36.384422302 31.384418488 18.500000000 35.384422302 31.384418488 18.500000000 -36.233222961 32.233222961 18.500000000 35.233222961 32.233222961 18.500000000 -35.981101990 32.981101990 18.500000000 -35.622871399 33.622871399 18.500000000 34.622871399 33.622871399 18.500000000 34.981101990 32.981101990 18.500000000 -35.167964935 34.167964935 18.500000000 -34.622871399 34.622871399 18.500000000 33.622871399 34.622871399 18.500000000 34.167964935 34.167964935 18.500000000 -33.981101990 34.981101990 18.500000000 -33.233222961 35.233222961 18.500000000 -32.384422302 35.384418488 18.500000000 -31.458978653 35.458976746 18.500000000 -30.488407135 35.488403320 18.500000000 -29.497472763 35.497467041 18.500000000 -28.499593735 35.499591827 18.500000000 -27.499954224 35.499954224 18.500000000 -26.499996185 35.499996185 18.500000000 -25.500000000 35.500000000 18.500000000 -24.500000000 35.500000000 18.500000000 -23.500000000 35.500000000 18.500000000 -22.500000000 35.500000000 18.500000000 -21.500000000 35.500000000 18.500000000 -20.500000000 35.500000000 18.500000000 -19.500000000 35.500000000 18.500000000 -18.500000000 35.500000000 18.500000000 -17.500000000 35.500000000 18.500000000 -16.500000000 35.500000000 18.500000000 -15.500000000 35.500000000 18.500000000 -14.500000000 35.500000000 18.500000000 -13.500000000 35.500000000 18.500000000 -12.500000000 35.500000000 18.500000000 -11.500000000 35.500000000 18.500000000 -10.500000000 35.500000000 18.500000000 -9.500000000 35.500000000 18.500000000 -8.500000000 35.500000000 18.500000000 -7.500000000 35.500000000 18.500000000 -6.500000000 35.500000000 18.500000000 -5.500000000 35.500000000 18.500000000 -4.500000000 35.500000000 18.500000000 -3.500000000 35.500000000 18.500000000 -2.500000000 35.500000000 18.500000000 -1.500000000 35.500000000 18.500000000 -0.500000000 35.500000000 18.500000000 0.500000000 35.500000000 18.500000000 1.500000000 35.500000000 18.500000000 2.500000000 35.500000000 18.500000000 3.500000000 35.500000000 18.500000000 4.500000000 35.500000000 18.500000000 5.500000000 35.500000000 18.500000000 6.500000000 35.500000000 18.500000000 7.500000000 35.500000000 18.500000000 8.500000000 35.500000000 18.500000000 9.500000000 35.500000000 18.500000000 10.500000000 35.500000000 18.500000000 11.500000000 35.500000000 18.500000000 12.500000000 35.500000000 18.500000000 13.500000000 35.500000000 18.500000000 14.500000000 35.500000000 18.500000000 15.500000000 35.500000000 18.500000000 16.500000000 35.500000000 18.500000000 17.500000000 35.500000000 18.500000000 18.500000000 35.500000000 18.500000000 19.500000000 35.500000000 18.500000000 20.500000000 35.500000000 18.500000000 21.500000000 35.500000000 18.500000000 22.500000000 35.500000000 18.500000000 23.500000000 35.500000000 18.500000000 24.500000000 35.500000000 18.500000000 25.499996185 35.499996185 18.500000000 26.499954224 35.499954224 18.500000000 27.499591827 35.499591827 18.500000000 28.497470856 35.497474670 18.500000000 29.488407135 35.488403320 18.500000000 30.458978653 35.458980560 18.500000000 31.384418488 35.384422302 18.500000000 32.233222961 35.233222961 18.500000000 32.981101990 34.981101990 18.500000000 -33.981101990 -35.981101990 19.500000000 -33.233226776 -36.233222961 19.500000000 -32.384422302 -36.384418488 19.500000000 -31.458978653 -36.458980560 19.500000000 -30.488407135 -36.488403320 19.500000000 -29.497472763 -36.497474670 19.500000000 -28.499593735 -36.499591827 19.500000000 -27.499954224 -36.499954224 19.500000000 -26.499996185 -36.499996185 19.500000000 -25.500000000 -36.500000000 19.500000000 -24.500000000 -36.500000000 19.500000000 -23.500000000 -36.500000000 19.500000000 -22.500000000 -36.500000000 19.500000000 -21.500000000 -36.500000000 19.500000000 -20.500000000 -36.500000000 19.500000000 -19.500000000 -36.500000000 19.500000000 -18.500000000 -36.500000000 19.500000000 -17.500000000 -36.500000000 19.500000000 -16.500000000 -36.500000000 19.500000000 -15.500000000 -36.500000000 19.500000000 -14.500000000 -36.500000000 19.500000000 -13.500000000 -36.500000000 19.500000000 -12.500000000 -36.500000000 19.500000000 -11.500000000 -36.500000000 19.500000000 -10.500000000 -36.500000000 19.500000000 -9.500000000 -36.500000000 19.500000000 -8.500000000 -36.500000000 19.500000000 -7.500000000 -36.500000000 19.500000000 -6.500000000 -36.500000000 19.500000000 -5.500000000 -36.500000000 19.500000000 -4.500000000 -36.500000000 19.500000000 -3.500000000 -36.500000000 19.500000000 -2.500000000 -36.500000000 19.500000000 -1.500000000 -36.500000000 19.500000000 -0.500000000 -36.500000000 19.500000000 0.500000000 -36.500000000 19.500000000 1.500000000 -36.500000000 19.500000000 2.500000000 -36.500000000 19.500000000 3.500000000 -36.500000000 19.500000000 4.500000000 -36.500000000 19.500000000 5.500000000 -36.500000000 19.500000000 6.500000000 -36.500000000 19.500000000 7.500000000 -36.500000000 19.500000000 8.500000000 -36.500000000 19.500000000 9.500000000 -36.500000000 19.500000000 10.500000000 -36.500000000 19.500000000 11.500000000 -36.500000000 19.500000000 12.500000000 -36.500000000 19.500000000 13.500000000 -36.500000000 19.500000000 14.500000000 -36.500000000 19.500000000 15.500000000 -36.500000000 19.500000000 16.500000000 -36.500000000 19.500000000 17.500000000 -36.500000000 19.500000000 18.500000000 -36.500000000 19.500000000 19.500000000 -36.500000000 19.500000000 20.500000000 -36.500000000 19.500000000 21.500000000 -36.500000000 19.500000000 22.500000000 -36.500000000 19.500000000 23.500000000 -36.500000000 19.500000000 24.500000000 -36.500000000 19.500000000 25.499996185 -36.499996185 19.500000000 26.499954224 -36.499954224 19.500000000 27.499591827 -36.499591827 19.500000000 28.497470856 -36.497467041 19.500000000 29.488407135 -36.488403320 19.500000000 30.458978653 -36.458980560 19.500000000 31.384418488 -36.384422302 19.500000000 32.233222961 -36.233222961 19.500000000 32.981101990 -35.981101990 19.500000000 -35.167964935 -35.167964935 19.500000000 -34.622871399 -35.622871399 19.500000000 33.622871399 -35.622871399 19.500000000 34.167964935 -35.167964935 19.500000000 -35.981101990 -33.981101990 19.500000000 -35.622871399 -34.622871399 19.500000000 34.622871399 -34.622871399 19.500000000 34.981101990 -33.981101990 19.500000000 -36.233222961 -33.233222961 19.500000000 35.233222961 -33.233226776 19.500000000 -36.384418488 -32.384422302 19.500000000 35.384418488 -32.384422302 19.500000000 -36.458976746 -31.458978653 19.500000000 35.458980560 -31.458978653 19.500000000 -36.488403320 -30.488407135 19.500000000 35.488403320 -30.488407135 19.500000000 -36.497467041 -29.497472763 19.500000000 35.497474670 -29.497472763 19.500000000 -36.499591827 -28.499593735 19.500000000 35.499591827 -28.499593735 19.500000000 -36.499954224 -27.499954224 19.500000000 35.499954224 -27.499954224 19.500000000 -36.499996185 -26.499996185 19.500000000 35.499996185 -26.499996185 19.500000000 -36.500000000 -25.500000000 19.500000000 35.500000000 -25.500000000 19.500000000 -36.500000000 -24.500000000 19.500000000 35.500000000 -24.500000000 19.500000000 -36.500000000 -23.500000000 19.500000000 35.500000000 -23.500000000 19.500000000 -36.500000000 -22.500000000 19.500000000 35.500000000 -22.500000000 19.500000000 -36.500000000 -21.500000000 19.500000000 35.500000000 -21.500000000 19.500000000 -36.500000000 -20.500000000 19.500000000 35.500000000 -20.500000000 19.500000000 -36.500000000 -19.500000000 19.500000000 35.500000000 -19.500000000 19.500000000 -36.500000000 -18.500000000 19.500000000 35.500000000 -18.500000000 19.500000000 -36.500000000 -17.500000000 19.500000000 35.500000000 -17.500000000 19.500000000 -36.500000000 -16.500000000 19.500000000 35.500000000 -16.500000000 19.500000000 -36.500000000 -15.500000000 19.500000000 35.500000000 -15.500000000 19.500000000 -36.500000000 -14.500000000 19.500000000 35.500000000 -14.500000000 19.500000000 -36.500000000 -13.500000000 19.500000000 35.500000000 -13.500000000 19.500000000 -36.500000000 -12.500000000 19.500000000 35.500000000 -12.500000000 19.500000000 -36.500000000 -11.500000000 19.500000000 35.500000000 -11.500000000 19.500000000 -36.500000000 -10.500000000 19.500000000 35.500000000 -10.500000000 19.500000000 -36.500000000 -9.500000000 19.500000000 35.500000000 -9.500000000 19.500000000 -36.500000000 -8.500000000 19.500000000 35.500000000 -8.500000000 19.500000000 -36.500000000 -7.500000000 19.500000000 35.500000000 -7.500000000 19.500000000 -36.500000000 -6.500000000 19.500000000 35.500000000 -6.500000000 19.500000000 -36.500000000 -5.500000000 19.500000000 35.500000000 -5.500000000 19.500000000 -36.500000000 -4.500000000 19.500000000 35.500000000 -4.500000000 19.500000000 -36.500000000 -3.500000000 19.500000000 35.500000000 -3.500000000 19.500000000 -36.500000000 -2.500000000 19.500000000 35.500000000 -2.500000000 19.500000000 -36.500000000 -1.500000000 19.500000000 35.500000000 -1.500000000 19.500000000 -36.500000000 -0.500000000 19.500000000 35.500000000 -0.500000000 19.500000000 -36.500000000 0.500000000 19.500000000 35.500000000 0.500000000 19.500000000 -36.500000000 1.500000000 19.500000000 35.500000000 1.500000000 19.500000000 -36.500000000 2.500000000 19.500000000 35.500000000 2.500000000 19.500000000 -36.500000000 3.500000000 19.500000000 35.500000000 3.500000000 19.500000000 -36.500000000 4.500000000 19.500000000 35.500000000 4.500000000 19.500000000 -36.500000000 5.500000000 19.500000000 35.500000000 5.500000000 19.500000000 -36.500000000 6.500000000 19.500000000 35.500000000 6.500000000 19.500000000 -36.500000000 7.500000000 19.500000000 35.500000000 7.500000000 19.500000000 -36.500000000 8.500000000 19.500000000 35.500000000 8.500000000 19.500000000 -36.500000000 9.500000000 19.500000000 35.500000000 9.500000000 19.500000000 -36.500000000 10.500000000 19.500000000 35.500000000 10.500000000 19.500000000 -36.500000000 11.500000000 19.500000000 35.500000000 11.500000000 19.500000000 -36.500000000 12.500000000 19.500000000 35.500000000 12.500000000 19.500000000 -36.500000000 13.500000000 19.500000000 35.500000000 13.500000000 19.500000000 -36.500000000 14.500000000 19.500000000 35.500000000 14.500000000 19.500000000 -36.500000000 15.500000000 19.500000000 35.500000000 15.500000000 19.500000000 -36.500000000 16.500000000 19.500000000 35.500000000 16.500000000 19.500000000 -36.500000000 17.500000000 19.500000000 35.500000000 17.500000000 19.500000000 -36.500000000 18.500000000 19.500000000 35.500000000 18.500000000 19.500000000 -36.500000000 19.500000000 19.500000000 35.500000000 19.500000000 19.500000000 -36.500000000 20.500000000 19.500000000 35.500000000 20.500000000 19.500000000 -36.500000000 21.500000000 19.500000000 35.500000000 21.500000000 19.500000000 -36.500000000 22.500000000 19.500000000 35.500000000 22.500000000 19.500000000 -36.500000000 23.500000000 19.500000000 35.500000000 23.500000000 19.500000000 -36.500000000 24.500000000 19.500000000 35.500000000 24.500000000 19.500000000 -36.499996185 25.499996185 19.500000000 35.499996185 25.499996185 19.500000000 -36.499954224 26.499954224 19.500000000 35.499954224 26.499954224 19.500000000 -36.499591827 27.499591827 19.500000000 35.499591827 27.499591827 19.500000000 -36.497474670 28.497470856 19.500000000 35.497467041 28.497470856 19.500000000 -36.488403320 29.488407135 19.500000000 35.488403320 29.488407135 19.500000000 -36.458980560 30.458978653 19.500000000 35.458980560 30.458978653 19.500000000 -36.384422302 31.384418488 19.500000000 35.384422302 31.384418488 19.500000000 -36.233222961 32.233222961 19.500000000 35.233222961 32.233222961 19.500000000 -35.981101990 32.981101990 19.500000000 -35.622871399 33.622871399 19.500000000 34.622871399 33.622871399 19.500000000 34.981101990 32.981101990 19.500000000 -35.167964935 34.167964935 19.500000000 -34.622871399 34.622871399 19.500000000 33.622871399 34.622871399 19.500000000 34.167964935 34.167964935 19.500000000 -33.981101990 34.981101990 19.500000000 -33.233222961 35.233222961 19.500000000 -32.384422302 35.384418488 19.500000000 -31.458978653 35.458976746 19.500000000 -30.488407135 35.488403320 19.500000000 -29.497472763 35.497467041 19.500000000 -28.499593735 35.499591827 19.500000000 -27.499954224 35.499954224 19.500000000 -26.499996185 35.499996185 19.500000000 -25.500000000 35.500000000 19.500000000 -24.500000000 35.500000000 19.500000000 -23.500000000 35.500000000 19.500000000 -22.500000000 35.500000000 19.500000000 -21.500000000 35.500000000 19.500000000 -20.500000000 35.500000000 19.500000000 -19.500000000 35.500000000 19.500000000 -18.500000000 35.500000000 19.500000000 -17.500000000 35.500000000 19.500000000 -16.500000000 35.500000000 19.500000000 -15.500000000 35.500000000 19.500000000 -14.500000000 35.500000000 19.500000000 -13.500000000 35.500000000 19.500000000 -12.500000000 35.500000000 19.500000000 -11.500000000 35.500000000 19.500000000 -10.500000000 35.500000000 19.500000000 -9.500000000 35.500000000 19.500000000 -8.500000000 35.500000000 19.500000000 -7.500000000 35.500000000 19.500000000 -6.500000000 35.500000000 19.500000000 -5.500000000 35.500000000 19.500000000 -4.500000000 35.500000000 19.500000000 -3.500000000 35.500000000 19.500000000 -2.500000000 35.500000000 19.500000000 -1.500000000 35.500000000 19.500000000 -0.500000000 35.500000000 19.500000000 0.500000000 35.500000000 19.500000000 1.500000000 35.500000000 19.500000000 2.500000000 35.500000000 19.500000000 3.500000000 35.500000000 19.500000000 4.500000000 35.500000000 19.500000000 5.500000000 35.500000000 19.500000000 6.500000000 35.500000000 19.500000000 7.500000000 35.500000000 19.500000000 8.500000000 35.500000000 19.500000000 9.500000000 35.500000000 19.500000000 10.500000000 35.500000000 19.500000000 11.500000000 35.500000000 19.500000000 12.500000000 35.500000000 19.500000000 13.500000000 35.500000000 19.500000000 14.500000000 35.500000000 19.500000000 15.500000000 35.500000000 19.500000000 16.500000000 35.500000000 19.500000000 17.500000000 35.500000000 19.500000000 18.500000000 35.500000000 19.500000000 19.500000000 35.500000000 19.500000000 20.500000000 35.500000000 19.500000000 21.500000000 35.500000000 19.500000000 22.500000000 35.500000000 19.500000000 23.500000000 35.500000000 19.500000000 24.500000000 35.500000000 19.500000000 25.499996185 35.499996185 19.500000000 26.499954224 35.499954224 19.500000000 27.499591827 35.499591827 19.500000000 28.497470856 35.497474670 19.500000000 29.488407135 35.488403320 19.500000000 30.458978653 35.458980560 19.500000000 31.384418488 35.384422302 19.500000000 32.233222961 35.233222961 19.500000000 32.981101990 34.981101990 19.500000000 -33.981101990 -35.981101990 20.500000000 -33.233226776 -36.233222961 20.500000000 -32.384422302 -36.384418488 20.500000000 -31.458978653 -36.458980560 20.500000000 -30.488407135 -36.488403320 20.500000000 -29.497472763 -36.497474670 20.500000000 -28.499593735 -36.499591827 20.500000000 -27.499954224 -36.499954224 20.500000000 -26.499996185 -36.499996185 20.500000000 -25.500000000 -36.500000000 20.500000000 -24.500000000 -36.500000000 20.500000000 -23.500000000 -36.500000000 20.500000000 -22.500000000 -36.500000000 20.500000000 -21.500000000 -36.500000000 20.500000000 -20.500000000 -36.500000000 20.500000000 -19.500000000 -36.500000000 20.500000000 -18.500000000 -36.500000000 20.500000000 -17.500000000 -36.500000000 20.500000000 -16.500000000 -36.500000000 20.500000000 -15.500000000 -36.500000000 20.500000000 -14.500000000 -36.500000000 20.500000000 -13.500000000 -36.500000000 20.500000000 -12.500000000 -36.500000000 20.500000000 -11.500000000 -36.500000000 20.500000000 -10.500000000 -36.500000000 20.500000000 -9.500000000 -36.500000000 20.500000000 -8.500000000 -36.500000000 20.500000000 -7.500000000 -36.500000000 20.500000000 -6.500000000 -36.500000000 20.500000000 -5.500000000 -36.500000000 20.500000000 -4.500000000 -36.500000000 20.500000000 -3.500000000 -36.500000000 20.500000000 -2.500000000 -36.500000000 20.500000000 -1.500000000 -36.500000000 20.500000000 -0.500000000 -36.500000000 20.500000000 0.500000000 -36.500000000 20.500000000 1.500000000 -36.500000000 20.500000000 2.500000000 -36.500000000 20.500000000 3.500000000 -36.500000000 20.500000000 4.500000000 -36.500000000 20.500000000 5.500000000 -36.500000000 20.500000000 6.500000000 -36.500000000 20.500000000 7.500000000 -36.500000000 20.500000000 8.500000000 -36.500000000 20.500000000 9.500000000 -36.500000000 20.500000000 10.500000000 -36.500000000 20.500000000 11.500000000 -36.500000000 20.500000000 12.500000000 -36.500000000 20.500000000 13.500000000 -36.500000000 20.500000000 14.500000000 -36.500000000 20.500000000 15.500000000 -36.500000000 20.500000000 16.500000000 -36.500000000 20.500000000 17.500000000 -36.500000000 20.500000000 18.500000000 -36.500000000 20.500000000 19.500000000 -36.500000000 20.500000000 20.500000000 -36.500000000 20.500000000 21.500000000 -36.500000000 20.500000000 22.500000000 -36.500000000 20.500000000 23.500000000 -36.500000000 20.500000000 24.500000000 -36.500000000 20.500000000 25.499996185 -36.499996185 20.500000000 26.499954224 -36.499954224 20.500000000 27.499591827 -36.499591827 20.500000000 28.497470856 -36.497467041 20.500000000 29.488407135 -36.488403320 20.500000000 30.458978653 -36.458980560 20.500000000 31.384418488 -36.384422302 20.500000000 32.233222961 -36.233222961 20.500000000 32.981101990 -35.981101990 20.500000000 -35.167964935 -35.167964935 20.500000000 -34.622871399 -35.622871399 20.500000000 33.622871399 -35.622871399 20.500000000 34.167964935 -35.167964935 20.500000000 -35.981101990 -33.981101990 20.500000000 -35.622871399 -34.622871399 20.500000000 34.622871399 -34.622871399 20.500000000 34.981101990 -33.981101990 20.500000000 -36.233222961 -33.233222961 20.500000000 35.233222961 -33.233226776 20.500000000 -36.384418488 -32.384422302 20.500000000 35.384418488 -32.384422302 20.500000000 -36.458976746 -31.458978653 20.500000000 35.458980560 -31.458978653 20.500000000 -36.488403320 -30.488407135 20.500000000 35.488403320 -30.488407135 20.500000000 -36.497467041 -29.497472763 20.500000000 35.497474670 -29.497472763 20.500000000 -36.499591827 -28.499593735 20.500000000 35.499591827 -28.499593735 20.500000000 -36.499954224 -27.499954224 20.500000000 35.499954224 -27.499954224 20.500000000 -36.499996185 -26.499996185 20.500000000 35.499996185 -26.499996185 20.500000000 -36.500000000 -25.500000000 20.500000000 35.500000000 -25.500000000 20.500000000 -36.500000000 -24.500000000 20.500000000 35.500000000 -24.500000000 20.500000000 -36.500000000 -23.500000000 20.500000000 35.500000000 -23.500000000 20.500000000 -36.500000000 -22.500000000 20.500000000 35.500000000 -22.500000000 20.500000000 -36.500000000 -21.500000000 20.500000000 35.500000000 -21.500000000 20.500000000 -36.500000000 -20.500000000 20.500000000 35.500000000 -20.500000000 20.500000000 -36.500000000 -19.500000000 20.500000000 35.500000000 -19.500000000 20.500000000 -36.500000000 -18.500000000 20.500000000 35.500000000 -18.500000000 20.500000000 -36.500000000 -17.500000000 20.500000000 35.500000000 -17.500000000 20.500000000 -36.500000000 -16.500000000 20.500000000 35.500000000 -16.500000000 20.500000000 -36.500000000 -15.500000000 20.500000000 35.500000000 -15.500000000 20.500000000 -36.500000000 -14.500000000 20.500000000 35.500000000 -14.500000000 20.500000000 -36.500000000 -13.500000000 20.500000000 35.500000000 -13.500000000 20.500000000 -36.500000000 -12.500000000 20.500000000 35.500000000 -12.500000000 20.500000000 -36.500000000 -11.500000000 20.500000000 35.500000000 -11.500000000 20.500000000 -36.500000000 -10.500000000 20.500000000 35.500000000 -10.500000000 20.500000000 -36.500000000 -9.500000000 20.500000000 35.500000000 -9.500000000 20.500000000 -36.500000000 -8.500000000 20.500000000 35.500000000 -8.500000000 20.500000000 -36.500000000 -7.500000000 20.500000000 35.500000000 -7.500000000 20.500000000 -36.500000000 -6.500000000 20.500000000 35.500000000 -6.500000000 20.500000000 -36.500000000 -5.500000000 20.500000000 35.500000000 -5.500000000 20.500000000 -36.500000000 -4.500000000 20.500000000 35.500000000 -4.500000000 20.500000000 -36.500000000 -3.500000000 20.500000000 35.500000000 -3.500000000 20.500000000 -36.500000000 -2.500000000 20.500000000 35.500000000 -2.500000000 20.500000000 -36.500000000 -1.500000000 20.500000000 35.500000000 -1.500000000 20.500000000 -36.500000000 -0.500000000 20.500000000 35.500000000 -0.500000000 20.500000000 -36.500000000 0.500000000 20.500000000 35.500000000 0.500000000 20.500000000 -36.500000000 1.500000000 20.500000000 35.500000000 1.500000000 20.500000000 -36.500000000 2.500000000 20.500000000 35.500000000 2.500000000 20.500000000 -36.500000000 3.500000000 20.500000000 35.500000000 3.500000000 20.500000000 -36.500000000 4.500000000 20.500000000 35.500000000 4.500000000 20.500000000 -36.500000000 5.500000000 20.500000000 35.500000000 5.500000000 20.500000000 -36.500000000 6.500000000 20.500000000 35.500000000 6.500000000 20.500000000 -36.500000000 7.500000000 20.500000000 35.500000000 7.500000000 20.500000000 -36.500000000 8.500000000 20.500000000 35.500000000 8.500000000 20.500000000 -36.500000000 9.500000000 20.500000000 35.500000000 9.500000000 20.500000000 -36.500000000 10.500000000 20.500000000 35.500000000 10.500000000 20.500000000 -36.500000000 11.500000000 20.500000000 35.500000000 11.500000000 20.500000000 -36.500000000 12.500000000 20.500000000 35.500000000 12.500000000 20.500000000 -36.500000000 13.500000000 20.500000000 35.500000000 13.500000000 20.500000000 -36.500000000 14.500000000 20.500000000 35.500000000 14.500000000 20.500000000 -36.500000000 15.500000000 20.500000000 35.500000000 15.500000000 20.500000000 -36.500000000 16.500000000 20.500000000 35.500000000 16.500000000 20.500000000 -36.500000000 17.500000000 20.500000000 35.500000000 17.500000000 20.500000000 -36.500000000 18.500000000 20.500000000 35.500000000 18.500000000 20.500000000 -36.500000000 19.500000000 20.500000000 35.500000000 19.500000000 20.500000000 -36.500000000 20.500000000 20.500000000 35.500000000 20.500000000 20.500000000 -36.500000000 21.500000000 20.500000000 35.500000000 21.500000000 20.500000000 -36.500000000 22.500000000 20.500000000 35.500000000 22.500000000 20.500000000 -36.500000000 23.500000000 20.500000000 35.500000000 23.500000000 20.500000000 -36.500000000 24.500000000 20.500000000 35.500000000 24.500000000 20.500000000 -36.499996185 25.499996185 20.500000000 35.499996185 25.499996185 20.500000000 -36.499954224 26.499954224 20.500000000 35.499954224 26.499954224 20.500000000 -36.499591827 27.499591827 20.500000000 35.499591827 27.499591827 20.500000000 -36.497474670 28.497470856 20.500000000 35.497467041 28.497470856 20.500000000 -36.488403320 29.488407135 20.500000000 35.488403320 29.488407135 20.500000000 -36.458980560 30.458978653 20.500000000 35.458980560 30.458978653 20.500000000 -36.384422302 31.384418488 20.500000000 35.384422302 31.384418488 20.500000000 -36.233222961 32.233222961 20.500000000 35.233222961 32.233222961 20.500000000 -35.981101990 32.981101990 20.500000000 -35.622871399 33.622871399 20.500000000 34.622871399 33.622871399 20.500000000 34.981101990 32.981101990 20.500000000 -35.167964935 34.167964935 20.500000000 -34.622871399 34.622871399 20.500000000 33.622871399 34.622871399 20.500000000 34.167964935 34.167964935 20.500000000 -33.981101990 34.981101990 20.500000000 -33.233222961 35.233222961 20.500000000 -32.384422302 35.384418488 20.500000000 -31.458978653 35.458976746 20.500000000 -30.488407135 35.488403320 20.500000000 -29.497472763 35.497467041 20.500000000 -28.499593735 35.499591827 20.500000000 -27.499954224 35.499954224 20.500000000 -26.499996185 35.499996185 20.500000000 -25.500000000 35.500000000 20.500000000 -24.500000000 35.500000000 20.500000000 -23.500000000 35.500000000 20.500000000 -22.500000000 35.500000000 20.500000000 -21.500000000 35.500000000 20.500000000 -20.500000000 35.500000000 20.500000000 -19.500000000 35.500000000 20.500000000 -18.500000000 35.500000000 20.500000000 -17.500000000 35.500000000 20.500000000 -16.500000000 35.500000000 20.500000000 -15.500000000 35.500000000 20.500000000 -14.500000000 35.500000000 20.500000000 -13.500000000 35.500000000 20.500000000 -12.500000000 35.500000000 20.500000000 -11.500000000 35.500000000 20.500000000 -10.500000000 35.500000000 20.500000000 -9.500000000 35.500000000 20.500000000 -8.500000000 35.500000000 20.500000000 -7.500000000 35.500000000 20.500000000 -6.500000000 35.500000000 20.500000000 -5.500000000 35.500000000 20.500000000 -4.500000000 35.500000000 20.500000000 -3.500000000 35.500000000 20.500000000 -2.500000000 35.500000000 20.500000000 -1.500000000 35.500000000 20.500000000 -0.500000000 35.500000000 20.500000000 0.500000000 35.500000000 20.500000000 1.500000000 35.500000000 20.500000000 2.500000000 35.500000000 20.500000000 3.500000000 35.500000000 20.500000000 4.500000000 35.500000000 20.500000000 5.500000000 35.500000000 20.500000000 6.500000000 35.500000000 20.500000000 7.500000000 35.500000000 20.500000000 8.500000000 35.500000000 20.500000000 9.500000000 35.500000000 20.500000000 10.500000000 35.500000000 20.500000000 11.500000000 35.500000000 20.500000000 12.500000000 35.500000000 20.500000000 13.500000000 35.500000000 20.500000000 14.500000000 35.500000000 20.500000000 15.500000000 35.500000000 20.500000000 16.500000000 35.500000000 20.500000000 17.500000000 35.500000000 20.500000000 18.500000000 35.500000000 20.500000000 19.500000000 35.500000000 20.500000000 20.500000000 35.500000000 20.500000000 21.500000000 35.500000000 20.500000000 22.500000000 35.500000000 20.500000000 23.500000000 35.500000000 20.500000000 24.500000000 35.500000000 20.500000000 25.499996185 35.499996185 20.500000000 26.499954224 35.499954224 20.500000000 27.499591827 35.499591827 20.500000000 28.497470856 35.497474670 20.500000000 29.488407135 35.488403320 20.500000000 30.458978653 35.458980560 20.500000000 31.384418488 35.384422302 20.500000000 32.233222961 35.233222961 20.500000000 32.981101990 34.981101990 20.500000000 -33.981101990 -35.981101990 21.500000000 -33.233226776 -36.233222961 21.500000000 -32.384422302 -36.384418488 21.500000000 -31.458978653 -36.458980560 21.500000000 -30.488407135 -36.488403320 21.500000000 -29.497472763 -36.497474670 21.500000000 -28.499593735 -36.499591827 21.500000000 -27.499954224 -36.499954224 21.500000000 -26.499996185 -36.499996185 21.500000000 -25.500000000 -36.500000000 21.500000000 -24.500000000 -36.500000000 21.500000000 -23.500000000 -36.500000000 21.500000000 -22.500000000 -36.500000000 21.500000000 -21.500000000 -36.500000000 21.500000000 -20.500000000 -36.500000000 21.500000000 -19.500000000 -36.500000000 21.500000000 -18.500000000 -36.500000000 21.500000000 -17.500000000 -36.500000000 21.500000000 -16.500000000 -36.500000000 21.500000000 -15.500000000 -36.500000000 21.500000000 -14.500000000 -36.500000000 21.500000000 -13.500000000 -36.500000000 21.500000000 -12.500000000 -36.500000000 21.500000000 -11.500000000 -36.500000000 21.500000000 -10.500000000 -36.500000000 21.500000000 -9.500000000 -36.500000000 21.500000000 -8.500000000 -36.500000000 21.500000000 -7.500000000 -36.500000000 21.500000000 -6.500000000 -36.500000000 21.500000000 -5.500000000 -36.500000000 21.500000000 -4.500000000 -36.500000000 21.500000000 -3.500000000 -36.500000000 21.500000000 -2.500000000 -36.500000000 21.500000000 -1.500000000 -36.500000000 21.500000000 -0.500000000 -36.500000000 21.500000000 0.500000000 -36.500000000 21.500000000 1.500000000 -36.500000000 21.500000000 2.500000000 -36.500000000 21.500000000 3.500000000 -36.500000000 21.500000000 4.500000000 -36.500000000 21.500000000 5.500000000 -36.500000000 21.500000000 6.500000000 -36.500000000 21.500000000 7.500000000 -36.500000000 21.500000000 8.500000000 -36.500000000 21.500000000 9.500000000 -36.500000000 21.500000000 10.500000000 -36.500000000 21.500000000 11.500000000 -36.500000000 21.500000000 12.500000000 -36.500000000 21.500000000 13.500000000 -36.500000000 21.500000000 14.500000000 -36.500000000 21.500000000 15.500000000 -36.500000000 21.500000000 16.500000000 -36.500000000 21.500000000 17.500000000 -36.500000000 21.500000000 18.500000000 -36.500000000 21.500000000 19.500000000 -36.500000000 21.500000000 20.500000000 -36.500000000 21.500000000 21.500000000 -36.500000000 21.500000000 22.500000000 -36.500000000 21.500000000 23.500000000 -36.500000000 21.500000000 24.500000000 -36.500000000 21.500000000 25.499996185 -36.499996185 21.500000000 26.499954224 -36.499954224 21.500000000 27.499591827 -36.499591827 21.500000000 28.497470856 -36.497467041 21.500000000 29.488407135 -36.488403320 21.500000000 30.458978653 -36.458980560 21.500000000 31.384418488 -36.384422302 21.500000000 32.233222961 -36.233222961 21.500000000 32.981101990 -35.981101990 21.500000000 -35.167964935 -35.167964935 21.500000000 -34.622871399 -35.622871399 21.500000000 33.622871399 -35.622871399 21.500000000 34.167964935 -35.167964935 21.500000000 -35.981101990 -33.981101990 21.500000000 -35.622871399 -34.622871399 21.500000000 34.622871399 -34.622871399 21.500000000 34.981101990 -33.981101990 21.500000000 -36.233222961 -33.233222961 21.500000000 35.233222961 -33.233226776 21.500000000 -36.384418488 -32.384422302 21.500000000 35.384418488 -32.384422302 21.500000000 -36.458976746 -31.458978653 21.500000000 35.458980560 -31.458978653 21.500000000 -36.488403320 -30.488407135 21.500000000 35.488403320 -30.488407135 21.500000000 -36.497467041 -29.497472763 21.500000000 35.497474670 -29.497472763 21.500000000 -36.499591827 -28.499593735 21.500000000 35.499591827 -28.499593735 21.500000000 -36.499954224 -27.499954224 21.500000000 35.499954224 -27.499954224 21.500000000 -36.499996185 -26.499996185 21.500000000 35.499996185 -26.499996185 21.500000000 -36.500000000 -25.500000000 21.500000000 35.500000000 -25.500000000 21.500000000 -36.500000000 -24.500000000 21.500000000 35.500000000 -24.500000000 21.500000000 -36.500000000 -23.500000000 21.500000000 35.500000000 -23.500000000 21.500000000 -36.500000000 -22.500000000 21.500000000 35.500000000 -22.500000000 21.500000000 -36.500000000 -21.500000000 21.500000000 35.500000000 -21.500000000 21.500000000 -36.500000000 -20.500000000 21.500000000 35.500000000 -20.500000000 21.500000000 -36.500000000 -19.500000000 21.500000000 35.500000000 -19.500000000 21.500000000 -36.500000000 -18.500000000 21.500000000 35.500000000 -18.500000000 21.500000000 -36.500000000 -17.500000000 21.500000000 35.500000000 -17.500000000 21.500000000 -36.500000000 -16.500000000 21.500000000 35.500000000 -16.500000000 21.500000000 -36.500000000 -15.500000000 21.500000000 35.500000000 -15.500000000 21.500000000 -36.500000000 -14.500000000 21.500000000 35.500000000 -14.500000000 21.500000000 -36.500000000 -13.500000000 21.500000000 35.500000000 -13.500000000 21.500000000 -36.500000000 -12.500000000 21.500000000 35.500000000 -12.500000000 21.500000000 -36.500000000 -11.500000000 21.500000000 35.500000000 -11.500000000 21.500000000 -36.500000000 -10.500000000 21.500000000 35.500000000 -10.500000000 21.500000000 -36.500000000 -9.500000000 21.500000000 35.500000000 -9.500000000 21.500000000 -36.500000000 -8.500000000 21.500000000 35.500000000 -8.500000000 21.500000000 -36.500000000 -7.500000000 21.500000000 35.500000000 -7.500000000 21.500000000 -36.500000000 -6.500000000 21.500000000 35.500000000 -6.500000000 21.500000000 -36.500000000 -5.500000000 21.500000000 35.500000000 -5.500000000 21.500000000 -36.500000000 -4.500000000 21.500000000 35.500000000 -4.500000000 21.500000000 -36.500000000 -3.500000000 21.500000000 35.500000000 -3.500000000 21.500000000 -36.500000000 -2.500000000 21.500000000 35.500000000 -2.500000000 21.500000000 -36.500000000 -1.500000000 21.500000000 35.500000000 -1.500000000 21.500000000 -36.500000000 -0.500000000 21.500000000 35.500000000 -0.500000000 21.500000000 -36.500000000 0.500000000 21.500000000 35.500000000 0.500000000 21.500000000 -36.500000000 1.500000000 21.500000000 35.500000000 1.500000000 21.500000000 -36.500000000 2.500000000 21.500000000 35.500000000 2.500000000 21.500000000 -36.500000000 3.500000000 21.500000000 35.500000000 3.500000000 21.500000000 -36.500000000 4.500000000 21.500000000 35.500000000 4.500000000 21.500000000 -36.500000000 5.500000000 21.500000000 35.500000000 5.500000000 21.500000000 -36.500000000 6.500000000 21.500000000 35.500000000 6.500000000 21.500000000 -36.500000000 7.500000000 21.500000000 35.500000000 7.500000000 21.500000000 -36.500000000 8.500000000 21.500000000 35.500000000 8.500000000 21.500000000 -36.500000000 9.500000000 21.500000000 35.500000000 9.500000000 21.500000000 -36.500000000 10.500000000 21.500000000 35.500000000 10.500000000 21.500000000 -36.500000000 11.500000000 21.500000000 35.500000000 11.500000000 21.500000000 -36.500000000 12.500000000 21.500000000 35.500000000 12.500000000 21.500000000 -36.500000000 13.500000000 21.500000000 35.500000000 13.500000000 21.500000000 -36.500000000 14.500000000 21.500000000 35.500000000 14.500000000 21.500000000 -36.500000000 15.500000000 21.500000000 35.500000000 15.500000000 21.500000000 -36.500000000 16.500000000 21.500000000 35.500000000 16.500000000 21.500000000 -36.500000000 17.500000000 21.500000000 35.500000000 17.500000000 21.500000000 -36.500000000 18.500000000 21.500000000 35.500000000 18.500000000 21.500000000 -36.500000000 19.500000000 21.500000000 35.500000000 19.500000000 21.500000000 -36.500000000 20.500000000 21.500000000 35.500000000 20.500000000 21.500000000 -36.500000000 21.500000000 21.500000000 35.500000000 21.500000000 21.500000000 -36.500000000 22.500000000 21.500000000 35.500000000 22.500000000 21.500000000 -36.500000000 23.500000000 21.500000000 35.500000000 23.500000000 21.500000000 -36.500000000 24.500000000 21.500000000 35.500000000 24.500000000 21.500000000 -36.499996185 25.499996185 21.500000000 35.499996185 25.499996185 21.500000000 -36.499954224 26.499954224 21.500000000 35.499954224 26.499954224 21.500000000 -36.499591827 27.499591827 21.500000000 35.499591827 27.499591827 21.500000000 -36.497474670 28.497470856 21.500000000 35.497467041 28.497470856 21.500000000 -36.488403320 29.488407135 21.500000000 35.488403320 29.488407135 21.500000000 -36.458980560 30.458978653 21.500000000 35.458980560 30.458978653 21.500000000 -36.384422302 31.384418488 21.500000000 35.384422302 31.384418488 21.500000000 -36.233222961 32.233222961 21.500000000 35.233222961 32.233222961 21.500000000 -35.981101990 32.981101990 21.500000000 -35.622871399 33.622871399 21.500000000 34.622871399 33.622871399 21.500000000 34.981101990 32.981101990 21.500000000 -35.167964935 34.167964935 21.500000000 -34.622871399 34.622871399 21.500000000 33.622871399 34.622871399 21.500000000 34.167964935 34.167964935 21.500000000 -33.981101990 34.981101990 21.500000000 -33.233222961 35.233222961 21.500000000 -32.384422302 35.384418488 21.500000000 -31.458978653 35.458976746 21.500000000 -30.488407135 35.488403320 21.500000000 -29.497472763 35.497467041 21.500000000 -28.499593735 35.499591827 21.500000000 -27.499954224 35.499954224 21.500000000 -26.499996185 35.499996185 21.500000000 -25.500000000 35.500000000 21.500000000 -24.500000000 35.500000000 21.500000000 -23.500000000 35.500000000 21.500000000 -22.500000000 35.500000000 21.500000000 -21.500000000 35.500000000 21.500000000 -20.500000000 35.500000000 21.500000000 -19.500000000 35.500000000 21.500000000 -18.500000000 35.500000000 21.500000000 -17.500000000 35.500000000 21.500000000 -16.500000000 35.500000000 21.500000000 -15.500000000 35.500000000 21.500000000 -14.500000000 35.500000000 21.500000000 -13.500000000 35.500000000 21.500000000 -12.500000000 35.500000000 21.500000000 -11.500000000 35.500000000 21.500000000 -10.500000000 35.500000000 21.500000000 -9.500000000 35.500000000 21.500000000 -8.500000000 35.500000000 21.500000000 -7.500000000 35.500000000 21.500000000 -6.500000000 35.500000000 21.500000000 -5.500000000 35.500000000 21.500000000 -4.500000000 35.500000000 21.500000000 -3.500000000 35.500000000 21.500000000 -2.500000000 35.500000000 21.500000000 -1.500000000 35.500000000 21.500000000 -0.500000000 35.500000000 21.500000000 0.500000000 35.500000000 21.500000000 1.500000000 35.500000000 21.500000000 2.500000000 35.500000000 21.500000000 3.500000000 35.500000000 21.500000000 4.500000000 35.500000000 21.500000000 5.500000000 35.500000000 21.500000000 6.500000000 35.500000000 21.500000000 7.500000000 35.500000000 21.500000000 8.500000000 35.500000000 21.500000000 9.500000000 35.500000000 21.500000000 10.500000000 35.500000000 21.500000000 11.500000000 35.500000000 21.500000000 12.500000000 35.500000000 21.500000000 13.500000000 35.500000000 21.500000000 14.500000000 35.500000000 21.500000000 15.500000000 35.500000000 21.500000000 16.500000000 35.500000000 21.500000000 17.500000000 35.500000000 21.500000000 18.500000000 35.500000000 21.500000000 19.500000000 35.500000000 21.500000000 20.500000000 35.500000000 21.500000000 21.500000000 35.500000000 21.500000000 22.500000000 35.500000000 21.500000000 23.500000000 35.500000000 21.500000000 24.500000000 35.500000000 21.500000000 25.499996185 35.499996185 21.500000000 26.499954224 35.499954224 21.500000000 27.499591827 35.499591827 21.500000000 28.497470856 35.497474670 21.500000000 29.488407135 35.488403320 21.500000000 30.458978653 35.458980560 21.500000000 31.384418488 35.384422302 21.500000000 32.233222961 35.233222961 21.500000000 32.981101990 34.981101990 21.500000000 -33.981101990 -35.981101990 22.500000000 -33.233226776 -36.233222961 22.500000000 -32.384422302 -36.384418488 22.500000000 -31.458978653 -36.458980560 22.500000000 -30.488407135 -36.488403320 22.500000000 -29.497472763 -36.497474670 22.500000000 -28.499593735 -36.499591827 22.500000000 -27.499954224 -36.499954224 22.500000000 -26.499996185 -36.499996185 22.500000000 -25.500000000 -36.500000000 22.500000000 -24.500000000 -36.500000000 22.500000000 -23.500000000 -36.500000000 22.500000000 -22.500000000 -36.500000000 22.500000000 -21.500000000 -36.500000000 22.500000000 -20.500000000 -36.500000000 22.500000000 -19.500000000 -36.500000000 22.500000000 -18.500000000 -36.500000000 22.500000000 -17.500000000 -36.500000000 22.500000000 -16.500000000 -36.500000000 22.500000000 -15.500000000 -36.500000000 22.500000000 -14.500000000 -36.500000000 22.500000000 -13.500000000 -36.500000000 22.500000000 -12.500000000 -36.500000000 22.500000000 -11.500000000 -36.500000000 22.500000000 -10.500000000 -36.500000000 22.500000000 -9.500000000 -36.500000000 22.500000000 -8.500000000 -36.500000000 22.500000000 -7.500000000 -36.500000000 22.500000000 -6.500000000 -36.500000000 22.500000000 -5.500000000 -36.500000000 22.500000000 -4.500000000 -36.500000000 22.500000000 -3.500000000 -36.500000000 22.500000000 -2.500000000 -36.500000000 22.500000000 -1.500000000 -36.500000000 22.500000000 -0.500000000 -36.500000000 22.500000000 0.500000000 -36.500000000 22.500000000 1.500000000 -36.500000000 22.500000000 2.500000000 -36.500000000 22.500000000 3.500000000 -36.500000000 22.500000000 4.500000000 -36.500000000 22.500000000 5.500000000 -36.500000000 22.500000000 6.500000000 -36.500000000 22.500000000 7.500000000 -36.500000000 22.500000000 8.500000000 -36.500000000 22.500000000 9.500000000 -36.500000000 22.500000000 10.500000000 -36.500000000 22.500000000 11.500000000 -36.500000000 22.500000000 12.500000000 -36.500000000 22.500000000 13.500000000 -36.500000000 22.500000000 14.500000000 -36.500000000 22.500000000 15.500000000 -36.500000000 22.500000000 16.500000000 -36.500000000 22.500000000 17.500000000 -36.500000000 22.500000000 18.500000000 -36.500000000 22.500000000 19.500000000 -36.500000000 22.500000000 20.500000000 -36.500000000 22.500000000 21.500000000 -36.500000000 22.500000000 22.500000000 -36.500000000 22.500000000 23.500000000 -36.500000000 22.500000000 24.500000000 -36.500000000 22.500000000 25.499996185 -36.499996185 22.500000000 26.499954224 -36.499954224 22.500000000 27.499591827 -36.499591827 22.500000000 28.497470856 -36.497467041 22.500000000 29.488407135 -36.488403320 22.500000000 30.458978653 -36.458980560 22.500000000 31.384418488 -36.384422302 22.500000000 32.233222961 -36.233222961 22.500000000 32.981101990 -35.981101990 22.500000000 -35.167964935 -35.167964935 22.500000000 -34.622871399 -35.622871399 22.500000000 33.622871399 -35.622871399 22.500000000 34.167964935 -35.167964935 22.500000000 -35.981101990 -33.981101990 22.500000000 -35.622871399 -34.622871399 22.500000000 34.622871399 -34.622871399 22.500000000 34.981101990 -33.981101990 22.500000000 -36.233222961 -33.233222961 22.500000000 35.233222961 -33.233226776 22.500000000 -36.384418488 -32.384422302 22.500000000 35.384418488 -32.384422302 22.500000000 -36.458976746 -31.458978653 22.500000000 35.458980560 -31.458978653 22.500000000 -36.488403320 -30.488407135 22.500000000 35.488403320 -30.488407135 22.500000000 -36.497467041 -29.497472763 22.500000000 35.497474670 -29.497472763 22.500000000 -36.499591827 -28.499593735 22.500000000 35.499591827 -28.499593735 22.500000000 -36.499954224 -27.499954224 22.500000000 35.499954224 -27.499954224 22.500000000 -36.499996185 -26.499996185 22.500000000 35.499996185 -26.499996185 22.500000000 -36.500000000 -25.500000000 22.500000000 35.500000000 -25.500000000 22.500000000 -36.500000000 -24.500000000 22.500000000 35.500000000 -24.500000000 22.500000000 -36.500000000 -23.500000000 22.500000000 35.500000000 -23.500000000 22.500000000 -36.500000000 -22.500000000 22.500000000 35.500000000 -22.500000000 22.500000000 -36.500000000 -21.500000000 22.500000000 35.500000000 -21.500000000 22.500000000 -36.500000000 -20.500000000 22.500000000 35.500000000 -20.500000000 22.500000000 -36.500000000 -19.500000000 22.500000000 35.500000000 -19.500000000 22.500000000 -36.500000000 -18.500000000 22.500000000 35.500000000 -18.500000000 22.500000000 -36.500000000 -17.500000000 22.500000000 35.500000000 -17.500000000 22.500000000 -36.500000000 -16.500000000 22.500000000 35.500000000 -16.500000000 22.500000000 -36.500000000 -15.500000000 22.500000000 35.500000000 -15.500000000 22.500000000 -36.500000000 -14.500000000 22.500000000 35.500000000 -14.500000000 22.500000000 -36.500000000 -13.500000000 22.500000000 35.500000000 -13.500000000 22.500000000 -36.500000000 -12.500000000 22.500000000 35.500000000 -12.500000000 22.500000000 -36.500000000 -11.500000000 22.500000000 35.500000000 -11.500000000 22.500000000 -36.500000000 -10.500000000 22.500000000 35.500000000 -10.500000000 22.500000000 -36.500000000 -9.500000000 22.500000000 35.500000000 -9.500000000 22.500000000 -36.500000000 -8.500000000 22.500000000 35.500000000 -8.500000000 22.500000000 -36.500000000 -7.500000000 22.500000000 35.500000000 -7.500000000 22.500000000 -36.500000000 -6.500000000 22.500000000 35.500000000 -6.500000000 22.500000000 -36.500000000 -5.500000000 22.500000000 35.500000000 -5.500000000 22.500000000 -36.500000000 -4.500000000 22.500000000 35.500000000 -4.500000000 22.500000000 -36.500000000 -3.500000000 22.500000000 35.500000000 -3.500000000 22.500000000 -36.500000000 -2.500000000 22.500000000 35.500000000 -2.500000000 22.500000000 -36.500000000 -1.500000000 22.500000000 35.500000000 -1.500000000 22.500000000 -36.500000000 -0.500000000 22.500000000 35.500000000 -0.500000000 22.500000000 -36.500000000 0.500000000 22.500000000 35.500000000 0.500000000 22.500000000 -36.500000000 1.500000000 22.500000000 35.500000000 1.500000000 22.500000000 -36.500000000 2.500000000 22.500000000 35.500000000 2.500000000 22.500000000 -36.500000000 3.500000000 22.500000000 35.500000000 3.500000000 22.500000000 -36.500000000 4.500000000 22.500000000 35.500000000 4.500000000 22.500000000 -36.500000000 5.500000000 22.500000000 35.500000000 5.500000000 22.500000000 -36.500000000 6.500000000 22.500000000 35.500000000 6.500000000 22.500000000 -36.500000000 7.500000000 22.500000000 35.500000000 7.500000000 22.500000000 -36.500000000 8.500000000 22.500000000 35.500000000 8.500000000 22.500000000 -36.500000000 9.500000000 22.500000000 35.500000000 9.500000000 22.500000000 -36.500000000 10.500000000 22.500000000 35.500000000 10.500000000 22.500000000 -36.500000000 11.500000000 22.500000000 35.500000000 11.500000000 22.500000000 -36.500000000 12.500000000 22.500000000 35.500000000 12.500000000 22.500000000 -36.500000000 13.500000000 22.500000000 35.500000000 13.500000000 22.500000000 -36.500000000 14.500000000 22.500000000 35.500000000 14.500000000 22.500000000 -36.500000000 15.500000000 22.500000000 35.500000000 15.500000000 22.500000000 -36.500000000 16.500000000 22.500000000 35.500000000 16.500000000 22.500000000 -36.500000000 17.500000000 22.500000000 35.500000000 17.500000000 22.500000000 -36.500000000 18.500000000 22.500000000 35.500000000 18.500000000 22.500000000 -36.500000000 19.500000000 22.500000000 35.500000000 19.500000000 22.500000000 -36.500000000 20.500000000 22.500000000 35.500000000 20.500000000 22.500000000 -36.500000000 21.500000000 22.500000000 35.500000000 21.500000000 22.500000000 -36.500000000 22.500000000 22.500000000 35.500000000 22.500000000 22.500000000 -36.500000000 23.500000000 22.500000000 35.500000000 23.500000000 22.500000000 -36.500000000 24.500000000 22.500000000 35.500000000 24.500000000 22.500000000 -36.499996185 25.499996185 22.500000000 35.499996185 25.499996185 22.500000000 -36.499954224 26.499954224 22.500000000 35.499954224 26.499954224 22.500000000 -36.499591827 27.499591827 22.500000000 35.499591827 27.499591827 22.500000000 -36.497474670 28.497470856 22.500000000 35.497467041 28.497470856 22.500000000 -36.488403320 29.488407135 22.500000000 35.488403320 29.488407135 22.500000000 -36.458980560 30.458978653 22.500000000 35.458980560 30.458978653 22.500000000 -36.384422302 31.384418488 22.500000000 35.384422302 31.384418488 22.500000000 -36.233222961 32.233222961 22.500000000 35.233222961 32.233222961 22.500000000 -35.981101990 32.981101990 22.500000000 -35.622871399 33.622871399 22.500000000 34.622871399 33.622871399 22.500000000 34.981101990 32.981101990 22.500000000 -35.167964935 34.167964935 22.500000000 -34.622871399 34.622871399 22.500000000 33.622871399 34.622871399 22.500000000 34.167964935 34.167964935 22.500000000 -33.981101990 34.981101990 22.500000000 -33.233222961 35.233222961 22.500000000 -32.384422302 35.384418488 22.500000000 -31.458978653 35.458976746 22.500000000 -30.488407135 35.488403320 22.500000000 -29.497472763 35.497467041 22.500000000 -28.499593735 35.499591827 22.500000000 -27.499954224 35.499954224 22.500000000 -26.499996185 35.499996185 22.500000000 -25.500000000 35.500000000 22.500000000 -24.500000000 35.500000000 22.500000000 -23.500000000 35.500000000 22.500000000 -22.500000000 35.500000000 22.500000000 -21.500000000 35.500000000 22.500000000 -20.500000000 35.500000000 22.500000000 -19.500000000 35.500000000 22.500000000 -18.500000000 35.500000000 22.500000000 -17.500000000 35.500000000 22.500000000 -16.500000000 35.500000000 22.500000000 -15.500000000 35.500000000 22.500000000 -14.500000000 35.500000000 22.500000000 -13.500000000 35.500000000 22.500000000 -12.500000000 35.500000000 22.500000000 -11.500000000 35.500000000 22.500000000 -10.500000000 35.500000000 22.500000000 -9.500000000 35.500000000 22.500000000 -8.500000000 35.500000000 22.500000000 -7.500000000 35.500000000 22.500000000 -6.500000000 35.500000000 22.500000000 -5.500000000 35.500000000 22.500000000 -4.500000000 35.500000000 22.500000000 -3.500000000 35.500000000 22.500000000 -2.500000000 35.500000000 22.500000000 -1.500000000 35.500000000 22.500000000 -0.500000000 35.500000000 22.500000000 0.500000000 35.500000000 22.500000000 1.500000000 35.500000000 22.500000000 2.500000000 35.500000000 22.500000000 3.500000000 35.500000000 22.500000000 4.500000000 35.500000000 22.500000000 5.500000000 35.500000000 22.500000000 6.500000000 35.500000000 22.500000000 7.500000000 35.500000000 22.500000000 8.500000000 35.500000000 22.500000000 9.500000000 35.500000000 22.500000000 10.500000000 35.500000000 22.500000000 11.500000000 35.500000000 22.500000000 12.500000000 35.500000000 22.500000000 13.500000000 35.500000000 22.500000000 14.500000000 35.500000000 22.500000000 15.500000000 35.500000000 22.500000000 16.500000000 35.500000000 22.500000000 17.500000000 35.500000000 22.500000000 18.500000000 35.500000000 22.500000000 19.500000000 35.500000000 22.500000000 20.500000000 35.500000000 22.500000000 21.500000000 35.500000000 22.500000000 22.500000000 35.500000000 22.500000000 23.500000000 35.500000000 22.500000000 24.500000000 35.500000000 22.500000000 25.499996185 35.499996185 22.500000000 26.499954224 35.499954224 22.500000000 27.499591827 35.499591827 22.500000000 28.497470856 35.497474670 22.500000000 29.488407135 35.488403320 22.500000000 30.458978653 35.458980560 22.500000000 31.384418488 35.384422302 22.500000000 32.233222961 35.233222961 22.500000000 32.981101990 34.981101990 22.500000000 -33.981101990 -35.981101990 23.499998093 -33.233226776 -36.233222961 23.500000000 -32.384422302 -36.384418488 23.500000000 -31.458978653 -36.458980560 23.500000000 -30.488407135 -36.488403320 23.500000000 -29.497472763 -36.497474670 23.500000000 -28.499593735 -36.499591827 23.500000000 -27.499954224 -36.499954224 23.500000000 -26.499996185 -36.499996185 23.500000000 -25.500000000 -36.500000000 23.500000000 -24.500000000 -36.500000000 23.500000000 -23.500000000 -36.500000000 23.500000000 -22.500000000 -36.500000000 23.500000000 -21.500000000 -36.500000000 23.500000000 -20.500000000 -36.500000000 23.500000000 -19.500000000 -36.500000000 23.500000000 -18.500000000 -36.500000000 23.500000000 -17.500000000 -36.500000000 23.500000000 -16.500000000 -36.500000000 23.500000000 -15.500000000 -36.500000000 23.500000000 -14.500000000 -36.500000000 23.500000000 -13.500000000 -36.500000000 23.500000000 -12.500000000 -36.500000000 23.500000000 -11.500000000 -36.500000000 23.500000000 -10.500000000 -36.500000000 23.500000000 -9.500000000 -36.500000000 23.500000000 -8.500000000 -36.500000000 23.500000000 -7.500000000 -36.500000000 23.500000000 -6.500000000 -36.500000000 23.500000000 -5.500000000 -36.500000000 23.500000000 -4.500000000 -36.500000000 23.500000000 -3.500000000 -36.500000000 23.500000000 -2.500000000 -36.500000000 23.500000000 -1.500000000 -36.500000000 23.500000000 -0.500000000 -36.500000000 23.500000000 0.500000000 -36.500000000 23.500000000 1.500000000 -36.500000000 23.500000000 2.500000000 -36.500000000 23.500000000 3.500000000 -36.500000000 23.500000000 4.500000000 -36.500000000 23.500000000 5.500000000 -36.500000000 23.500000000 6.500000000 -36.500000000 23.500000000 7.500000000 -36.500000000 23.500000000 8.500000000 -36.500000000 23.500000000 9.500000000 -36.500000000 23.500000000 10.500000000 -36.500000000 23.500000000 11.500000000 -36.500000000 23.500000000 12.500000000 -36.500000000 23.500000000 13.500000000 -36.500000000 23.500000000 14.500000000 -36.500000000 23.500000000 15.500000000 -36.500000000 23.500000000 16.500000000 -36.500000000 23.500000000 17.500000000 -36.500000000 23.500000000 18.500000000 -36.500000000 23.500000000 19.500000000 -36.500000000 23.500000000 20.500000000 -36.500000000 23.500000000 21.500000000 -36.500000000 23.500000000 22.500000000 -36.500000000 23.500000000 23.500000000 -36.500000000 23.500000000 24.500000000 -36.500000000 23.500000000 25.499996185 -36.499996185 23.500000000 26.499954224 -36.499954224 23.500000000 27.499591827 -36.499591827 23.500000000 28.497470856 -36.497467041 23.500000000 29.488407135 -36.488403320 23.500000000 30.458978653 -36.458980560 23.500000000 31.384418488 -36.384422302 23.500000000 32.233222961 -36.233222961 23.500000000 32.981101990 -35.981101990 23.499998093 -35.167964935 -35.167964935 23.500000000 -34.622867584 -35.622867584 23.500000000 33.622871399 -35.622871399 23.500000000 34.167961121 -35.167961121 23.500000000 -35.981101990 -33.981101990 23.499998093 -35.622867584 -34.622867584 23.500000000 34.622867584 -34.622867584 23.500000000 34.981101990 -33.981101990 23.499998093 -36.233222961 -33.233222961 23.500000000 35.233222961 -33.233226776 23.500000000 -36.384418488 -32.384422302 23.500000000 35.384418488 -32.384422302 23.500000000 -36.458976746 -31.458978653 23.500000000 35.458980560 -31.458978653 23.500000000 -36.488403320 -30.488407135 23.500000000 35.488403320 -30.488407135 23.500000000 -36.497467041 -29.497472763 23.500000000 35.497474670 -29.497472763 23.500000000 -36.499591827 -28.499593735 23.500000000 35.499591827 -28.499593735 23.500000000 -36.499954224 -27.499954224 23.500000000 35.499954224 -27.499954224 23.500000000 -36.499996185 -26.499996185 23.500000000 35.499996185 -26.499996185 23.500000000 -36.500000000 -25.500000000 23.500000000 35.500000000 -25.500000000 23.500000000 -36.500000000 -24.500000000 23.500000000 35.500000000 -24.500000000 23.500000000 -36.500000000 -23.500000000 23.500000000 35.500000000 -23.500000000 23.500000000 -36.500000000 -22.500000000 23.500000000 35.500000000 -22.500000000 23.500000000 -36.500000000 -21.500000000 23.500000000 35.500000000 -21.500000000 23.500000000 -36.500000000 -20.500000000 23.500000000 35.500000000 -20.500000000 23.500000000 -36.500000000 -19.500000000 23.500000000 35.500000000 -19.500000000 23.500000000 -36.500000000 -18.500000000 23.500000000 35.500000000 -18.500000000 23.500000000 -36.500000000 -17.500000000 23.500000000 35.500000000 -17.500000000 23.500000000 -36.500000000 -16.500000000 23.500000000 35.500000000 -16.500000000 23.500000000 -36.500000000 -15.500000000 23.500000000 35.500000000 -15.500000000 23.500000000 -36.500000000 -14.500000000 23.500000000 35.500000000 -14.500000000 23.500000000 -36.500000000 -13.500000000 23.500000000 35.500000000 -13.500000000 23.500000000 -36.500000000 -12.500000000 23.500000000 35.500000000 -12.500000000 23.500000000 -36.500000000 -11.500000000 23.500000000 35.500000000 -11.500000000 23.500000000 -36.500000000 -10.500000000 23.500000000 35.500000000 -10.500000000 23.500000000 -36.500000000 -9.500000000 23.500000000 35.500000000 -9.500000000 23.500000000 -36.500000000 -8.500000000 23.500000000 35.500000000 -8.500000000 23.500000000 -36.500000000 -7.500000000 23.500000000 35.500000000 -7.500000000 23.500000000 -36.500000000 -6.500000000 23.500000000 35.500000000 -6.500000000 23.500000000 -36.500000000 -5.500000000 23.500000000 35.500000000 -5.500000000 23.500000000 -36.500000000 -4.500000000 23.500000000 35.500000000 -4.500000000 23.500000000 -36.500000000 -3.500000000 23.500000000 35.500000000 -3.500000000 23.500000000 -36.500000000 -2.500000000 23.500000000 35.500000000 -2.500000000 23.500000000 -36.500000000 -1.500000000 23.500000000 35.500000000 -1.500000000 23.500000000 -36.500000000 -0.500000000 23.500000000 35.500000000 -0.500000000 23.500000000 -36.500000000 0.500000000 23.500000000 35.500000000 0.500000000 23.500000000 -36.500000000 1.500000000 23.500000000 35.500000000 1.500000000 23.500000000 -36.500000000 2.500000000 23.500000000 35.500000000 2.500000000 23.500000000 -36.500000000 3.500000000 23.500000000 35.500000000 3.500000000 23.500000000 -36.500000000 4.500000000 23.500000000 35.500000000 4.500000000 23.500000000 -36.500000000 5.500000000 23.500000000 35.500000000 5.500000000 23.500000000 -36.500000000 6.500000000 23.500000000 35.500000000 6.500000000 23.500000000 -36.500000000 7.500000000 23.500000000 35.500000000 7.500000000 23.500000000 -36.500000000 8.500000000 23.500000000 35.500000000 8.500000000 23.500000000 -36.500000000 9.500000000 23.500000000 35.500000000 9.500000000 23.500000000 -36.500000000 10.500000000 23.500000000 35.500000000 10.500000000 23.500000000 -36.500000000 11.500000000 23.500000000 35.500000000 11.500000000 23.500000000 -36.500000000 12.500000000 23.500000000 35.500000000 12.500000000 23.500000000 -36.500000000 13.500000000 23.500000000 35.500000000 13.500000000 23.500000000 -36.500000000 14.500000000 23.500000000 35.500000000 14.500000000 23.500000000 -36.500000000 15.500000000 23.500000000 35.500000000 15.500000000 23.500000000 -36.500000000 16.500000000 23.500000000 35.500000000 16.500000000 23.500000000 -36.500000000 17.500000000 23.500000000 35.500000000 17.500000000 23.500000000 -36.500000000 18.500000000 23.500000000 35.500000000 18.500000000 23.500000000 -36.500000000 19.500000000 23.500000000 35.500000000 19.500000000 23.500000000 -36.500000000 20.500000000 23.500000000 35.500000000 20.500000000 23.500000000 -36.500000000 21.500000000 23.500000000 35.500000000 21.500000000 23.500000000 -36.500000000 22.500000000 23.500000000 35.500000000 22.500000000 23.500000000 -36.500000000 23.500000000 23.500000000 35.500000000 23.500000000 23.500000000 -36.500000000 24.500000000 23.500000000 35.500000000 24.500000000 23.500000000 -36.499996185 25.499996185 23.500000000 35.499996185 25.499996185 23.500000000 -36.499954224 26.499954224 23.500000000 35.499954224 26.499954224 23.500000000 -36.499591827 27.499591827 23.500000000 35.499591827 27.499591827 23.500000000 -36.497474670 28.497470856 23.500000000 35.497467041 28.497470856 23.500000000 -36.488403320 29.488407135 23.500000000 35.488403320 29.488407135 23.500000000 -36.458980560 30.458978653 23.500000000 35.458980560 30.458978653 23.500000000 -36.384422302 31.384418488 23.500000000 35.384422302 31.384418488 23.500000000 -36.233222961 32.233222961 23.500000000 35.233222961 32.233222961 23.500000000 -35.981101990 32.981101990 23.499998093 -35.622867584 33.622867584 23.500000000 34.622871399 33.622867584 23.500000000 34.981101990 32.981101990 23.499998093 -35.167964935 34.167964935 23.500000000 -34.622867584 34.622867584 23.500000000 33.622867584 34.622867584 23.500000000 34.167961121 34.167961121 23.500000000 -33.981101990 34.981101990 23.499998093 -33.233222961 35.233222961 23.500000000 -32.384422302 35.384418488 23.500000000 -31.458978653 35.458976746 23.500000000 -30.488407135 35.488403320 23.500000000 -29.497472763 35.497467041 23.500000000 -28.499593735 35.499591827 23.500000000 -27.499954224 35.499954224 23.500000000 -26.499996185 35.499996185 23.500000000 -25.500000000 35.500000000 23.500000000 -24.500000000 35.500000000 23.500000000 -23.500000000 35.500000000 23.500000000 -22.500000000 35.500000000 23.500000000 -21.500000000 35.500000000 23.500000000 -20.500000000 35.500000000 23.500000000 -19.500000000 35.500000000 23.500000000 -18.500000000 35.500000000 23.500000000 -17.500000000 35.500000000 23.500000000 -16.500000000 35.500000000 23.500000000 -15.500000000 35.500000000 23.500000000 -14.500000000 35.500000000 23.500000000 -13.500000000 35.500000000 23.500000000 -12.500000000 35.500000000 23.500000000 -11.500000000 35.500000000 23.500000000 -10.500000000 35.500000000 23.500000000 -9.500000000 35.500000000 23.500000000 -8.500000000 35.500000000 23.500000000 -7.500000000 35.500000000 23.500000000 -6.500000000 35.500000000 23.500000000 -5.500000000 35.500000000 23.500000000 -4.500000000 35.500000000 23.500000000 -3.500000000 35.500000000 23.500000000 -2.500000000 35.500000000 23.500000000 -1.500000000 35.500000000 23.500000000 -0.500000000 35.500000000 23.500000000 0.500000000 35.500000000 23.500000000 1.500000000 35.500000000 23.500000000 2.500000000 35.500000000 23.500000000 3.500000000 35.500000000 23.500000000 4.500000000 35.500000000 23.500000000 5.500000000 35.500000000 23.500000000 6.500000000 35.500000000 23.500000000 7.500000000 35.500000000 23.500000000 8.500000000 35.500000000 23.500000000 9.500000000 35.500000000 23.500000000 10.500000000 35.500000000 23.500000000 11.500000000 35.500000000 23.500000000 12.500000000 35.500000000 23.500000000 13.500000000 35.500000000 23.500000000 14.500000000 35.500000000 23.500000000 15.500000000 35.500000000 23.500000000 16.500000000 35.500000000 23.500000000 17.500000000 35.500000000 23.500000000 18.500000000 35.500000000 23.500000000 19.500000000 35.500000000 23.500000000 20.500000000 35.500000000 23.500000000 21.500000000 35.500000000 23.500000000 22.500000000 35.500000000 23.500000000 23.500000000 35.500000000 23.500000000 24.500000000 35.500000000 23.500000000 25.499996185 35.499996185 23.500000000 26.499954224 35.499954224 23.500000000 27.499591827 35.499591827 23.500000000 28.497470856 35.497474670 23.500000000 29.488407135 35.488403320 23.500000000 30.458978653 35.458980560 23.500000000 31.384418488 35.384422302 23.500000000 32.233222961 35.233222961 23.500000000 32.981101990 34.981101990 23.499998093 -33.981086731 -35.981086731 24.499979019 -33.233219147 -36.233203888 24.499984741 -32.384422302 -36.384407043 24.499996185 -31.458978653 -36.458972931 24.500000000 -30.488407135 -36.488403320 24.500000000 -29.497472763 -36.497474670 24.500000000 -28.499593735 -36.499591827 24.500000000 -27.499954224 -36.499954224 24.500000000 -26.499996185 -36.499996185 24.500000000 -25.500000000 -36.500000000 24.500000000 -24.500000000 -36.500000000 24.500000000 -23.500000000 -36.500000000 24.500000000 -22.500000000 -36.500000000 24.500000000 -21.500000000 -36.500000000 24.500000000 -20.500000000 -36.500000000 24.500000000 -19.500000000 -36.500000000 24.500000000 -18.500000000 -36.500000000 24.500000000 -17.500000000 -36.500000000 24.500000000 -16.500000000 -36.500000000 24.500000000 -15.500000000 -36.500000000 24.500000000 -14.500000000 -36.500000000 24.500000000 -13.500000000 -36.500000000 24.500000000 -12.500000000 -36.500000000 24.500000000 -11.500000000 -36.500000000 24.500000000 -10.500000000 -36.500000000 24.500000000 -9.500000000 -36.500000000 24.500000000 -8.500000000 -36.500000000 24.500000000 -7.500000000 -36.500000000 24.500000000 -6.500000000 -36.500000000 24.500000000 -5.500000000 -36.500000000 24.500000000 -4.500000000 -36.500000000 24.500000000 -3.500000000 -36.500000000 24.500000000 -2.500000000 -36.500000000 24.500000000 -1.500000000 -36.500000000 24.500000000 -0.500000000 -36.500000000 24.500000000 0.500000000 -36.500000000 24.500000000 1.500000000 -36.500000000 24.500000000 2.500000000 -36.500000000 24.500000000 3.500000000 -36.500000000 24.500000000 4.500000000 -36.500000000 24.500000000 5.500000000 -36.500000000 24.500000000 6.500000000 -36.500000000 24.500000000 7.500000000 -36.500000000 24.500000000 8.500000000 -36.500000000 24.500000000 9.500000000 -36.500000000 24.500000000 10.500000000 -36.500000000 24.500000000 11.500000000 -36.500000000 24.500000000 12.500000000 -36.500000000 24.500000000 13.500000000 -36.500000000 24.500000000 14.500000000 -36.500000000 24.500000000 15.500000000 -36.500000000 24.500000000 16.500000000 -36.500000000 24.500000000 17.500000000 -36.500000000 24.500000000 18.500000000 -36.500000000 24.500000000 19.500000000 -36.500000000 24.500000000 20.500000000 -36.500000000 24.500000000 21.500000000 -36.500000000 24.500000000 22.500000000 -36.500000000 24.500000000 23.500000000 -36.500000000 24.500000000 24.500000000 -36.500000000 24.500000000 25.499996185 -36.499996185 24.500000000 26.499954224 -36.499954224 24.500000000 27.499591827 -36.499591827 24.500000000 28.497470856 -36.497467041 24.500000000 29.488407135 -36.488403320 24.500000000 30.458978653 -36.458976746 24.500000000 31.384418488 -36.384407043 24.499996185 32.233219147 -36.233207703 24.499988556 32.981086731 -35.981086731 24.499979019 -35.167949677 -35.167949677 24.499992371 -34.622844696 -35.622856140 24.499986649 33.622844696 -35.622856140 24.499986649 34.167949677 -35.167949677 24.499992371 -35.981086731 -33.981086731 24.499979019 -35.622856140 -34.622844696 24.499988556 34.622856140 -34.622844696 24.499988556 34.981086731 -33.981086731 24.499979019 -36.233207703 -33.233219147 24.499984741 35.233203888 -33.233219147 24.499984741 -36.384407043 -32.384422302 24.499996185 35.384407043 -32.384422302 24.499996185 -36.458972931 -31.458978653 24.500000000 35.458972931 -31.458978653 24.500000000 -36.488403320 -30.488407135 24.500000000 35.488403320 -30.488407135 24.500000000 -36.497467041 -29.497472763 24.500000000 35.497474670 -29.497472763 24.500000000 -36.499591827 -28.499593735 24.500000000 35.499591827 -28.499593735 24.500000000 -36.499954224 -27.499954224 24.500000000 35.499954224 -27.499954224 24.500000000 -36.499996185 -26.499996185 24.500000000 35.499996185 -26.499996185 24.500000000 -36.500000000 -25.500000000 24.500000000 35.500000000 -25.500000000 24.500000000 -36.500000000 -24.500000000 24.500000000 35.500000000 -24.500000000 24.500000000 -36.500000000 -23.500000000 24.500000000 35.500000000 -23.500000000 24.500000000 -36.500000000 -22.500000000 24.500000000 35.500000000 -22.500000000 24.500000000 -36.500000000 -21.500000000 24.500000000 35.500000000 -21.500000000 24.500000000 -36.500000000 -20.500000000 24.500000000 35.500000000 -20.500000000 24.500000000 -36.500000000 -19.500000000 24.500000000 35.500000000 -19.500000000 24.500000000 -36.500000000 -18.500000000 24.500000000 35.500000000 -18.500000000 24.500000000 -36.500000000 -17.500000000 24.500000000 35.500000000 -17.500000000 24.500000000 -36.500000000 -16.500000000 24.500000000 35.500000000 -16.500000000 24.500000000 -36.500000000 -15.500000000 24.500000000 35.500000000 -15.500000000 24.500000000 -36.500000000 -14.500000000 24.500000000 35.500000000 -14.500000000 24.500000000 -36.500000000 -13.500000000 24.500000000 35.500000000 -13.500000000 24.500000000 -36.500000000 -12.500000000 24.500000000 35.500000000 -12.500000000 24.500000000 -36.500000000 -11.500000000 24.500000000 35.500000000 -11.500000000 24.500000000 -36.500000000 -10.500000000 24.500000000 35.500000000 -10.500000000 24.500000000 -36.500000000 -9.500000000 24.500000000 35.500000000 -9.500000000 24.500000000 -36.500000000 -8.500000000 24.500000000 35.500000000 -8.500000000 24.500000000 -36.500000000 -7.500000000 24.500000000 35.500000000 -7.500000000 24.500000000 -36.500000000 -6.500000000 24.500000000 35.500000000 -6.500000000 24.500000000 -36.500000000 -5.500000000 24.500000000 35.500000000 -5.500000000 24.500000000 -36.500000000 -4.500000000 24.500000000 35.500000000 -4.500000000 24.500000000 -36.500000000 -3.500000000 24.500000000 35.500000000 -3.500000000 24.500000000 -36.500000000 -2.500000000 24.500000000 35.500000000 -2.500000000 24.500000000 -36.500000000 -1.500000000 24.500000000 35.500000000 -1.500000000 24.500000000 -36.500000000 -0.500000000 24.500000000 35.500000000 -0.500000000 24.500000000 -36.500000000 0.500000000 24.500000000 35.500000000 0.500000000 24.500000000 -36.500000000 1.500000000 24.500000000 35.500000000 1.500000000 24.500000000 -36.500000000 2.500000000 24.500000000 35.500000000 2.500000000 24.500000000 -36.500000000 3.500000000 24.500000000 35.500000000 3.500000000 24.500000000 -36.500000000 4.500000000 24.500000000 35.500000000 4.500000000 24.500000000 -36.500000000 5.500000000 24.500000000 35.500000000 5.500000000 24.500000000 -36.500000000 6.500000000 24.500000000 35.500000000 6.500000000 24.500000000 -36.500000000 7.500000000 24.500000000 35.500000000 7.500000000 24.500000000 -36.500000000 8.500000000 24.500000000 35.500000000 8.500000000 24.500000000 -36.500000000 9.500000000 24.500000000 35.500000000 9.500000000 24.500000000 -36.500000000 10.500000000 24.500000000 35.500000000 10.500000000 24.500000000 -36.500000000 11.500000000 24.500000000 35.500000000 11.500000000 24.500000000 -36.500000000 12.500000000 24.500000000 35.500000000 12.500000000 24.500000000 -36.500000000 13.500000000 24.500000000 35.500000000 13.500000000 24.500000000 -36.500000000 14.500000000 24.500000000 35.500000000 14.500000000 24.500000000 -36.500000000 15.500000000 24.500000000 35.500000000 15.500000000 24.500000000 -36.500000000 16.500000000 24.500000000 35.500000000 16.500000000 24.500000000 -36.500000000 17.500000000 24.500000000 35.500000000 17.500000000 24.500000000 -36.500000000 18.500000000 24.500000000 35.500000000 18.500000000 24.500000000 -36.500000000 19.500000000 24.500000000 35.500000000 19.500000000 24.500000000 -36.500000000 20.500000000 24.500000000 35.500000000 20.500000000 24.500000000 -36.500000000 21.500000000 24.500000000 35.500000000 21.500000000 24.500000000 -36.500000000 22.500000000 24.500000000 35.500000000 22.500000000 24.500000000 -36.500000000 23.500000000 24.500000000 35.500000000 23.500000000 24.500000000 -36.500000000 24.500000000 24.500000000 35.500000000 24.500000000 24.500000000 -36.499996185 25.499996185 24.500000000 35.499996185 25.499996185 24.500000000 -36.499954224 26.499954224 24.500000000 35.499954224 26.499954224 24.500000000 -36.499591827 27.499591827 24.500000000 35.499591827 27.499591827 24.500000000 -36.497474670 28.497470856 24.500000000 35.497467041 28.497470856 24.500000000 -36.488403320 29.488407135 24.500000000 35.488403320 29.488407135 24.500000000 -36.458976746 30.458978653 24.500000000 35.458976746 30.458978653 24.500000000 -36.384407043 31.384418488 24.499996185 35.384407043 31.384418488 24.499996185 -36.233207703 32.233219147 24.499988556 35.233207703 32.233219147 24.499988556 -35.981086731 32.981086731 24.499979019 -35.622856140 33.622844696 24.499986649 34.622856140 33.622844696 24.499986649 34.981086731 32.981086731 24.499979019 -35.167949677 34.167949677 24.499992371 -34.622844696 34.622856140 24.499988556 33.622844696 34.622856140 24.499988556 34.167949677 34.167949677 24.499992371 -33.981086731 34.981086731 24.499979019 -33.233219147 35.233207703 24.499984741 -32.384422302 35.384407043 24.499996185 -31.458978653 35.458972931 24.500000000 -30.488407135 35.488403320 24.500000000 -29.497472763 35.497467041 24.500000000 -28.499593735 35.499591827 24.500000000 -27.499954224 35.499954224 24.500000000 -26.499996185 35.499996185 24.500000000 -25.500000000 35.500000000 24.500000000 -24.500000000 35.500000000 24.500000000 -23.500000000 35.500000000 24.500000000 -22.500000000 35.500000000 24.500000000 -21.500000000 35.500000000 24.500000000 -20.500000000 35.500000000 24.500000000 -19.500000000 35.500000000 24.500000000 -18.500000000 35.500000000 24.500000000 -17.500000000 35.500000000 24.500000000 -16.500000000 35.500000000 24.500000000 -15.500000000 35.500000000 24.500000000 -14.500000000 35.500000000 24.500000000 -13.500000000 35.500000000 24.500000000 -12.500000000 35.500000000 24.500000000 -11.500000000 35.500000000 24.500000000 -10.500000000 35.500000000 24.500000000 -9.500000000 35.500000000 24.500000000 -8.500000000 35.500000000 24.500000000 -7.500000000 35.500000000 24.500000000 -6.500000000 35.500000000 24.500000000 -5.500000000 35.500000000 24.500000000 -4.500000000 35.500000000 24.500000000 -3.500000000 35.500000000 24.500000000 -2.500000000 35.500000000 24.500000000 -1.500000000 35.500000000 24.500000000 -0.500000000 35.500000000 24.500000000 0.500000000 35.500000000 24.500000000 1.500000000 35.500000000 24.500000000 2.500000000 35.500000000 24.500000000 3.500000000 35.500000000 24.500000000 4.500000000 35.500000000 24.500000000 5.500000000 35.500000000 24.500000000 6.500000000 35.500000000 24.500000000 7.500000000 35.500000000 24.500000000 8.500000000 35.500000000 24.500000000 9.500000000 35.500000000 24.500000000 10.500000000 35.500000000 24.500000000 11.500000000 35.500000000 24.500000000 12.500000000 35.500000000 24.500000000 13.500000000 35.500000000 24.500000000 14.500000000 35.500000000 24.500000000 15.500000000 35.500000000 24.500000000 16.500000000 35.500000000 24.500000000 17.500000000 35.500000000 24.500000000 18.500000000 35.500000000 24.500000000 19.500000000 35.500000000 24.500000000 20.500000000 35.500000000 24.500000000 21.500000000 35.500000000 24.500000000 22.500000000 35.500000000 24.500000000 23.500000000 35.500000000 24.500000000 24.500000000 35.500000000 24.500000000 25.499996185 35.499996185 24.500000000 26.499954224 35.499954224 24.500000000 27.499591827 35.499591827 24.500000000 28.497470856 35.497474670 24.500000000 29.488407135 35.488403320 24.500000000 30.458978653 35.458976746 24.500000000 31.384418488 35.384407043 24.499996185 32.233219147 35.233207703 24.499988556 32.981086731 34.981086731 24.499979019 -33.980976105 -35.980957031 25.499824524 -33.233169556 -36.233074188 25.499874115 -32.384407043 -36.384307861 25.499948502 -31.458978653 -36.458930969 25.499988556 -30.488407135 -36.488388062 25.499996185 -29.497472763 -36.497470856 25.499996185 -28.499593735 -36.499588013 25.499996185 -27.499954224 -36.499950409 25.499996185 -26.499996185 -36.499992371 25.499996185 -25.500000000 -36.499996185 25.499996185 -24.500000000 -36.499996185 25.499996185 -23.500000000 -36.499996185 25.499996185 -22.500000000 -36.499996185 25.499996185 -21.500000000 -36.499996185 25.499996185 -20.500000000 -36.499996185 25.499996185 -19.500000000 -36.499996185 25.499996185 -18.500000000 -36.499996185 25.499996185 -17.500000000 -36.499996185 25.499996185 -16.500000000 -36.499996185 25.499996185 -15.500000000 -36.499996185 25.499996185 -14.500000000 -36.499996185 25.499996185 -13.500000000 -36.499996185 25.499996185 -12.500000000 -36.499996185 25.499996185 -11.500000000 -36.499996185 25.499996185 -10.500000000 -36.499996185 25.499996185 -9.500000000 -36.499996185 25.499996185 -8.500000000 -36.499996185 25.499996185 -7.500000000 -36.499996185 25.499996185 -6.500000000 -36.499996185 25.499996185 -5.500000000 -36.499996185 25.499996185 -4.500000000 -36.499996185 25.499996185 -3.500000000 -36.499996185 25.499996185 -2.500000000 -36.499996185 25.499996185 -1.500000000 -36.499996185 25.499996185 -0.500000000 -36.499996185 25.499996185 0.500000000 -36.499996185 25.499996185 1.500000000 -36.499996185 25.499996185 2.500000000 -36.499996185 25.499996185 3.500000000 -36.499996185 25.499996185 4.500000000 -36.499996185 25.499996185 5.500000000 -36.499996185 25.499996185 6.500000000 -36.499996185 25.499996185 7.500000000 -36.499996185 25.499996185 8.500000000 -36.499996185 25.499996185 9.500000000 -36.499996185 25.499996185 10.500000000 -36.499996185 25.499996185 11.500000000 -36.499996185 25.499996185 12.500000000 -36.499996185 25.499996185 13.500000000 -36.499996185 25.499996185 14.500000000 -36.499996185 25.499996185 15.500000000 -36.499996185 25.499996185 16.500000000 -36.499996185 25.499996185 17.500000000 -36.499996185 25.499996185 18.500000000 -36.499996185 25.499996185 19.500000000 -36.499996185 25.499996185 20.500000000 -36.499996185 25.499996185 21.500000000 -36.499996185 25.499996185 22.500000000 -36.499996185 25.499996185 23.500000000 -36.499996185 25.499996185 24.500000000 -36.499996185 25.499996185 25.499996185 -36.499992371 25.499996185 26.499954224 -36.499950409 25.499996185 27.499591827 -36.499588013 25.499996185 28.497470856 -36.497467041 25.499996185 29.488407135 -36.488391876 25.499996185 30.458974838 -36.458934784 25.499988556 31.384403229 -36.384307861 25.499948502 32.233165741 -36.233070374 25.499874115 32.980976105 -35.980957031 25.499826431 -35.167804718 -35.167808533 25.499902725 -34.622692108 -35.622734070 25.499866486 33.622692108 -35.622734070 25.499866486 34.167808533 -35.167804718 25.499902725 -35.980957031 -33.980976105 25.499824524 -35.622734070 -34.622692108 25.499866486 34.622734070 -34.622692108 25.499868393 34.980957031 -33.980976105 25.499824524 -36.233074188 -33.233169556 25.499874115 35.233074188 -33.233165741 25.499874115 -36.384307861 -32.384407043 25.499948502 35.384307861 -32.384407043 25.499948502 -36.458930969 -31.458978653 25.499988556 35.458930969 -31.458978653 25.499988556 -36.488388062 -30.488407135 25.499996185 35.488388062 -30.488407135 25.499996185 -36.497467041 -29.497472763 25.499996185 35.497470856 -29.497472763 25.499996185 -36.499584198 -28.499593735 25.499996185 35.499588013 -28.499593735 25.499996185 -36.499950409 -27.499954224 25.499996185 35.499950409 -27.499954224 25.499996185 -36.499992371 -26.499996185 25.499996185 35.499992371 -26.499996185 25.499996185 -36.499996185 -25.500000000 25.499996185 35.499996185 -25.500000000 25.499996185 -36.499996185 -24.500000000 25.499996185 35.499996185 -24.500000000 25.499996185 -36.499996185 -23.500000000 25.499996185 35.499996185 -23.500000000 25.499996185 -36.499996185 -22.500000000 25.499996185 35.499996185 -22.500000000 25.499996185 -36.499996185 -21.500000000 25.499996185 35.499996185 -21.500000000 25.499996185 -36.499996185 -20.500000000 25.499996185 35.499996185 -20.500000000 25.499996185 -36.499996185 -19.500000000 25.499996185 35.499996185 -19.500000000 25.499996185 -36.499996185 -18.500000000 25.499996185 35.499996185 -18.500000000 25.499996185 -36.499996185 -17.500000000 25.499996185 35.499996185 -17.500000000 25.499996185 -36.499996185 -16.500000000 25.499996185 35.499996185 -16.500000000 25.499996185 -36.499996185 -15.500000000 25.499996185 35.499996185 -15.500000000 25.499996185 -36.499996185 -14.500000000 25.499996185 35.499996185 -14.500000000 25.499996185 -36.499996185 -13.500000000 25.499996185 35.499996185 -13.500000000 25.499996185 -36.499996185 -12.500000000 25.499996185 35.499996185 -12.500000000 25.499996185 -36.499996185 -11.500000000 25.499996185 35.499996185 -11.500000000 25.499996185 -36.499996185 -10.500000000 25.499996185 35.499996185 -10.500000000 25.499996185 -36.499996185 -9.500000000 25.499996185 35.499996185 -9.500000000 25.499996185 -36.499996185 -8.500000000 25.499996185 35.499996185 -8.500000000 25.499996185 -36.499996185 -7.500000000 25.499996185 35.499996185 -7.500000000 25.499996185 -36.499996185 -6.500000000 25.499996185 35.499996185 -6.500000000 25.499996185 -36.499996185 -5.500000000 25.499996185 35.499996185 -5.500000000 25.499996185 -36.499996185 -4.500000000 25.499996185 35.499996185 -4.500000000 25.499996185 -36.499996185 -3.500000000 25.499996185 35.499996185 -3.500000000 25.499996185 -36.499996185 -2.500000000 25.499996185 35.499996185 -2.500000000 25.499996185 -36.499996185 -1.500000000 25.499996185 35.499996185 -1.500000000 25.499996185 -36.499996185 -0.500000000 25.499996185 35.499996185 -0.500000000 25.499996185 -36.499996185 0.500000000 25.499996185 35.499996185 0.500000000 25.499996185 -36.499996185 1.500000000 25.499996185 35.499996185 1.500000000 25.499996185 -36.499996185 2.500000000 25.499996185 35.499996185 2.500000000 25.499996185 -36.499996185 3.500000000 25.499996185 35.499996185 3.500000000 25.499996185 -36.499996185 4.500000000 25.499996185 35.499996185 4.500000000 25.499996185 -36.499996185 5.500000000 25.499996185 35.499996185 5.500000000 25.499996185 -36.499996185 6.500000000 25.499996185 35.499996185 6.500000000 25.499996185 -36.499996185 7.500000000 25.499996185 35.499996185 7.500000000 25.499996185 -36.499996185 8.500000000 25.499996185 35.499996185 8.500000000 25.499996185 -36.499996185 9.500000000 25.499996185 35.499996185 9.500000000 25.499996185 -36.499996185 10.500000000 25.499996185 35.499996185 10.500000000 25.499996185 -36.499996185 11.500000000 25.499996185 35.499996185 11.500000000 25.499996185 -36.499996185 12.500000000 25.499996185 35.499996185 12.500000000 25.499996185 -36.499996185 13.500000000 25.499996185 35.499996185 13.500000000 25.499996185 -36.499996185 14.500000000 25.499996185 35.499996185 14.500000000 25.499996185 -36.499996185 15.500000000 25.499996185 35.499996185 15.500000000 25.499996185 -36.499996185 16.500000000 25.499996185 35.499996185 16.500000000 25.499996185 -36.499996185 17.500000000 25.499996185 35.499996185 17.500000000 25.499996185 -36.499996185 18.500000000 25.499996185 35.499996185 18.500000000 25.499996185 -36.499996185 19.500000000 25.499996185 35.499996185 19.500000000 25.499996185 -36.499996185 20.500000000 25.499996185 35.499996185 20.500000000 25.499996185 -36.499996185 21.500000000 25.499996185 35.499996185 21.500000000 25.499996185 -36.499996185 22.500000000 25.499996185 35.499996185 22.500000000 25.499996185 -36.499996185 23.500000000 25.499996185 35.499996185 23.500000000 25.499996185 -36.499996185 24.500000000 25.499996185 35.499996185 24.500000000 25.499996185 -36.499992371 25.499996185 25.499996185 35.499992371 25.499996185 25.499996185 -36.499950409 26.499954224 25.499996185 35.499950409 26.499954224 25.499996185 -36.499588013 27.499591827 25.499996185 35.499588013 27.499591827 25.499996185 -36.497467041 28.497470856 25.499996185 35.497467041 28.497470856 25.499996185 -36.488388062 29.488407135 25.499996185 35.488391876 29.488407135 25.499996185 -36.458934784 30.458974838 25.499988556 35.458934784 30.458974838 25.499988556 -36.384307861 31.384399414 25.499948502 35.384307861 31.384403229 25.499948502 -36.233074188 32.233165741 25.499874115 35.233070374 32.233165741 25.499874115 -35.980957031 32.980976105 25.499824524 -35.622734070 33.622692108 25.499866486 34.622734070 33.622692108 25.499866486 34.980957031 32.980976105 25.499826431 -35.167808533 34.167804718 25.499902725 -34.622692108 34.622734070 25.499866486 33.622692108 34.622734070 25.499868393 34.167804718 34.167808533 25.499902725 -33.980976105 34.980957031 25.499824524 -33.233169556 35.233074188 25.499874115 -32.384407043 35.384307861 25.499948502 -31.458978653 35.458930969 25.499988556 -30.488407135 35.488388062 25.499996185 -29.497472763 35.497467041 25.499996185 -28.499593735 35.499584198 25.499996185 -27.499954224 35.499950409 25.499996185 -26.499996185 35.499992371 25.499996185 -25.500000000 35.499996185 25.499996185 -24.500000000 35.499996185 25.499996185 -23.500000000 35.499996185 25.499996185 -22.500000000 35.499996185 25.499996185 -21.500000000 35.499996185 25.499996185 -20.500000000 35.499996185 25.499996185 -19.500000000 35.499996185 25.499996185 -18.500000000 35.499996185 25.499996185 -17.500000000 35.499996185 25.499996185 -16.500000000 35.499996185 25.499996185 -15.500000000 35.499996185 25.499996185 -14.500000000 35.499996185 25.499996185 -13.500000000 35.499996185 25.499996185 -12.500000000 35.499996185 25.499996185 -11.500000000 35.499996185 25.499996185 -10.500000000 35.499996185 25.499996185 -9.500000000 35.499996185 25.499996185 -8.500000000 35.499996185 25.499996185 -7.500000000 35.499996185 25.499996185 -6.500000000 35.499996185 25.499996185 -5.500000000 35.499996185 25.499996185 -4.500000000 35.499996185 25.499996185 -3.500000000 35.499996185 25.499996185 -2.500000000 35.499996185 25.499996185 -1.500000000 35.499996185 25.499996185 -0.500000000 35.499996185 25.499996185 0.500000000 35.499996185 25.499996185 1.500000000 35.499996185 25.499996185 2.500000000 35.499996185 25.499996185 3.500000000 35.499996185 25.499996185 4.500000000 35.499996185 25.499996185 5.500000000 35.499996185 25.499996185 6.500000000 35.499996185 25.499996185 7.500000000 35.499996185 25.499996185 8.500000000 35.499996185 25.499996185 9.500000000 35.499996185 25.499996185 10.500000000 35.499996185 25.499996185 11.500000000 35.499996185 25.499996185 12.500000000 35.499996185 25.499996185 13.500000000 35.499996185 25.499996185 14.500000000 35.499996185 25.499996185 15.500000000 35.499996185 25.499996185 16.500000000 35.499996185 25.499996185 17.500000000 35.499996185 25.499996185 18.500000000 35.499996185 25.499996185 19.500000000 35.499996185 25.499996185 20.500000000 35.499996185 25.499996185 21.500000000 35.499996185 25.499996185 22.500000000 35.499996185 25.499996185 23.500000000 35.499996185 25.499996185 24.500000000 35.499996185 25.499996185 25.499996185 35.499992371 25.499996185 26.499954224 35.499950409 25.499996185 27.499591827 35.499588013 25.499996185 28.497470856 35.497467041 25.499996185 29.488407135 35.488388062 25.499996185 30.458974838 35.458934784 25.499988556 31.384403229 35.384307861 25.499948502 32.233165741 35.233074188 25.499874115 32.980968475 34.980957031 25.499824524 -33.980335236 -35.980194092 26.498950958 -33.232864380 -36.232299805 26.499225616 -32.384296417 -36.383720398 26.499622345 -31.458948135 -36.458606720 26.499858856 -30.488397598 -36.488258362 26.499938965 -29.497472763 -36.497406006 26.499954224 -28.499593735 -36.499549866 26.499954224 -27.499954224 -36.499908447 26.499954224 -26.499996185 -36.499950409 26.499954224 -25.500000000 -36.499954224 26.499954224 -24.500000000 -36.499954224 26.499954224 -23.500000000 -36.499954224 26.499954224 -22.500000000 -36.499954224 26.499954224 -21.500000000 -36.499954224 26.499954224 -20.500000000 -36.499954224 26.499954224 -19.500000000 -36.499954224 26.499954224 -18.500000000 -36.499954224 26.499954224 -17.500000000 -36.499954224 26.499954224 -16.500000000 -36.499954224 26.499954224 -15.500000000 -36.499954224 26.499954224 -14.500000000 -36.499954224 26.499954224 -13.500000000 -36.499954224 26.499954224 -12.500000000 -36.499954224 26.499954224 -11.500000000 -36.499954224 26.499954224 -10.500000000 -36.499954224 26.499954224 -9.500000000 -36.499954224 26.499954224 -8.500000000 -36.499954224 26.499954224 -7.500000000 -36.499954224 26.499954224 -6.500000000 -36.499954224 26.499954224 -5.500000000 -36.499954224 26.499954224 -4.500000000 -36.499954224 26.499954224 -3.500000000 -36.499954224 26.499954224 -2.500000000 -36.499954224 26.499954224 -1.500000000 -36.499954224 26.499954224 -0.500000000 -36.499954224 26.499954224 0.500000000 -36.499954224 26.499954224 1.500000000 -36.499954224 26.499954224 2.500000000 -36.499954224 26.499954224 3.500000000 -36.499954224 26.499954224 4.500000000 -36.499954224 26.499954224 5.500000000 -36.499954224 26.499954224 6.500000000 -36.499954224 26.499954224 7.500000000 -36.499954224 26.499954224 8.500000000 -36.499954224 26.499954224 9.500000000 -36.499954224 26.499954224 10.500000000 -36.499954224 26.499954224 11.500000000 -36.499954224 26.499954224 12.500000000 -36.499954224 26.499954224 13.500000000 -36.499954224 26.499954224 14.500000000 -36.499954224 26.499954224 15.500000000 -36.499954224 26.499954224 16.500000000 -36.499954224 26.499954224 17.500000000 -36.499954224 26.499954224 18.500000000 -36.499954224 26.499954224 19.500000000 -36.499954224 26.499954224 20.500000000 -36.499954224 26.499954224 21.500000000 -36.499954224 26.499954224 22.500000000 -36.499954224 26.499954224 23.500000000 -36.499954224 26.499954224 24.500000000 -36.499954224 26.499954224 25.499996185 -36.499950409 26.499954224 26.499954224 -36.499908447 26.499954224 27.499591827 -36.499542236 26.499954224 28.497470856 -36.497409821 26.499954224 29.488397598 -36.488258362 26.499938965 30.458948135 -36.458606720 26.499858856 31.384296417 -36.383720398 26.499622345 32.232860565 -36.232303619 26.499225616 32.980335236 -35.980201721 26.498950958 -35.166954041 -35.166954041 26.499298096 -34.621799469 -35.621978760 26.499156952 33.621799469 -35.621978760 26.499156952 34.166961670 -35.166957855 26.499298096 -35.980201721 -33.980327606 26.498950958 -35.621978760 -34.621799469 26.499160767 34.621982574 -34.621799469 26.499156952 34.980201721 -33.980331421 26.498950958 -36.232303619 -33.232860565 26.499225616 35.232303619 -33.232864380 26.499225616 -36.383720398 -32.384296417 26.499618530 35.383720398 -32.384296417 26.499622345 -36.458606720 -31.458948135 26.499858856 35.458606720 -31.458948135 26.499858856 -36.488258362 -30.488397598 26.499938965 35.488258362 -30.488397598 26.499938965 -36.497406006 -29.497472763 26.499954224 35.497406006 -29.497472763 26.499954224 -36.499542236 -28.499593735 26.499954224 35.499549866 -28.499593735 26.499954224 -36.499908447 -27.499954224 26.499954224 35.499908447 -27.499954224 26.499954224 -36.499950409 -26.499996185 26.499954224 35.499950409 -26.499996185 26.499954224 -36.499950409 -25.500000000 26.499954224 35.499954224 -25.500000000 26.499954224 -36.499950409 -24.500000000 26.499954224 35.499954224 -24.500000000 26.499954224 -36.499950409 -23.500000000 26.499954224 35.499954224 -23.500000000 26.499954224 -36.499950409 -22.500000000 26.499954224 35.499954224 -22.500000000 26.499954224 -36.499950409 -21.500000000 26.499954224 35.499954224 -21.500000000 26.499954224 -36.499950409 -20.500000000 26.499954224 35.499954224 -20.500000000 26.499954224 -36.499950409 -19.500000000 26.499954224 35.499954224 -19.500000000 26.499954224 -36.499950409 -18.500000000 26.499954224 35.499954224 -18.500000000 26.499954224 -36.499950409 -17.500000000 26.499954224 35.499954224 -17.500000000 26.499954224 -36.499950409 -16.500000000 26.499954224 35.499954224 -16.500000000 26.499954224 -36.499950409 -15.500000000 26.499954224 35.499954224 -15.500000000 26.499954224 -36.499950409 -14.500000000 26.499954224 35.499954224 -14.500000000 26.499954224 -36.499950409 -13.500000000 26.499954224 35.499954224 -13.500000000 26.499954224 -36.499950409 -12.500000000 26.499954224 35.499954224 -12.500000000 26.499954224 -36.499950409 -11.500000000 26.499954224 35.499954224 -11.500000000 26.499954224 -36.499950409 -10.500000000 26.499954224 35.499954224 -10.500000000 26.499954224 -36.499950409 -9.500000000 26.499954224 35.499954224 -9.500000000 26.499954224 -36.499950409 -8.500000000 26.499954224 35.499954224 -8.500000000 26.499954224 -36.499950409 -7.500000000 26.499954224 35.499954224 -7.500000000 26.499954224 -36.499950409 -6.500000000 26.499954224 35.499954224 -6.500000000 26.499954224 -36.499950409 -5.500000000 26.499954224 35.499954224 -5.500000000 26.499954224 -36.499950409 -4.500000000 26.499954224 35.499954224 -4.500000000 26.499954224 -36.499950409 -3.500000000 26.499954224 35.499954224 -3.500000000 26.499954224 -36.499950409 -2.500000000 26.499954224 35.499954224 -2.500000000 26.499954224 -36.499950409 -1.500000000 26.499954224 35.499954224 -1.500000000 26.499954224 -36.499950409 -0.500000000 26.499954224 35.499954224 -0.500000000 26.499954224 -36.499950409 0.500000000 26.499954224 35.499954224 0.500000000 26.499954224 -36.499950409 1.500000000 26.499954224 35.499954224 1.500000000 26.499954224 -36.499950409 2.500000000 26.499954224 35.499954224 2.500000000 26.499954224 -36.499950409 3.500000000 26.499954224 35.499954224 3.500000000 26.499954224 -36.499950409 4.500000000 26.499954224 35.499954224 4.500000000 26.499954224 -36.499950409 5.500000000 26.499954224 35.499954224 5.500000000 26.499954224 -36.499950409 6.500000000 26.499954224 35.499954224 6.500000000 26.499954224 -36.499950409 7.500000000 26.499954224 35.499954224 7.500000000 26.499954224 -36.499950409 8.500000000 26.499954224 35.499954224 8.500000000 26.499954224 -36.499950409 9.500000000 26.499954224 35.499954224 9.500000000 26.499954224 -36.499950409 10.500000000 26.499954224 35.499954224 10.500000000 26.499954224 -36.499950409 11.500000000 26.499954224 35.499954224 11.500000000 26.499954224 -36.499950409 12.500000000 26.499954224 35.499954224 12.500000000 26.499954224 -36.499950409 13.500000000 26.499954224 35.499954224 13.500000000 26.499954224 -36.499950409 14.500000000 26.499954224 35.499954224 14.500000000 26.499954224 -36.499950409 15.500000000 26.499954224 35.499954224 15.500000000 26.499954224 -36.499950409 16.500000000 26.499954224 35.499954224 16.500000000 26.499954224 -36.499950409 17.500000000 26.499954224 35.499954224 17.500000000 26.499954224 -36.499950409 18.500000000 26.499954224 35.499954224 18.500000000 26.499954224 -36.499950409 19.500000000 26.499954224 35.499954224 19.500000000 26.499954224 -36.499950409 20.500000000 26.499954224 35.499954224 20.500000000 26.499954224 -36.499950409 21.500000000 26.499954224 35.499954224 21.500000000 26.499954224 -36.499950409 22.500000000 26.499954224 35.499954224 22.500000000 26.499954224 -36.499950409 23.500000000 26.499954224 35.499954224 23.500000000 26.499954224 -36.499950409 24.500000000 26.499954224 35.499954224 24.500000000 26.499954224 -36.499950409 25.499996185 26.499954224 35.499950409 25.499996185 26.499954224 -36.499908447 26.499954224 26.499954224 35.499908447 26.499954224 26.499954224 -36.499542236 27.499591827 26.499954224 35.499542236 27.499591827 26.499954224 -36.497406006 28.497470856 26.499954224 35.497409821 28.497470856 26.499954224 -36.488258362 29.488397598 26.499938965 35.488258362 29.488397598 26.499938965 -36.458606720 30.458948135 26.499858856 35.458606720 30.458948135 26.499858856 -36.383720398 31.384296417 26.499622345 35.383720398 31.384296417 26.499622345 -36.232299805 32.232860565 26.499225616 35.232303619 32.232860565 26.499225616 -35.980194092 32.980335236 26.498950958 -35.621978760 33.621799469 26.499156952 34.621978760 33.621799469 26.499156952 34.980201721 32.980335236 26.498950958 -35.166954041 34.166954041 26.499298096 -34.621799469 34.621978760 26.499160767 33.621799469 34.621982574 26.499160767 34.166954041 34.166961670 26.499298096 -33.980327606 34.980201721 26.498950958 -33.232860565 35.232303619 26.499225616 -32.384296417 35.383720398 26.499618530 -31.458948135 35.458606720 26.499858856 -30.488397598 35.488258362 26.499938965 -29.497472763 35.497406006 26.499954224 -28.499593735 35.499542236 26.499954224 -27.499954224 35.499908447 26.499954224 -26.499996185 35.499950409 26.499954224 -25.500000000 35.499950409 26.499954224 -24.500000000 35.499950409 26.499954224 -23.500000000 35.499950409 26.499954224 -22.500000000 35.499950409 26.499954224 -21.500000000 35.499950409 26.499954224 -20.500000000 35.499950409 26.499954224 -19.500000000 35.499950409 26.499954224 -18.500000000 35.499950409 26.499954224 -17.500000000 35.499950409 26.499954224 -16.500000000 35.499950409 26.499954224 -15.500000000 35.499950409 26.499954224 -14.500000000 35.499950409 26.499954224 -13.500000000 35.499950409 26.499954224 -12.500000000 35.499950409 26.499954224 -11.500000000 35.499950409 26.499954224 -10.500000000 35.499950409 26.499954224 -9.500000000 35.499950409 26.499954224 -8.500000000 35.499950409 26.499954224 -7.500000000 35.499950409 26.499954224 -6.500000000 35.499950409 26.499954224 -5.500000000 35.499950409 26.499954224 -4.500000000 35.499950409 26.499954224 -3.500000000 35.499950409 26.499954224 -2.500000000 35.499950409 26.499954224 -1.500000000 35.499950409 26.499954224 -0.500000000 35.499950409 26.499954224 0.500000000 35.499950409 26.499954224 1.500000000 35.499950409 26.499954224 2.500000000 35.499950409 26.499954224 3.500000000 35.499950409 26.499954224 4.500000000 35.499950409 26.499954224 5.500000000 35.499950409 26.499954224 6.500000000 35.499950409 26.499954224 7.500000000 35.499950409 26.499954224 8.500000000 35.499950409 26.499954224 9.500000000 35.499950409 26.499954224 10.500000000 35.499950409 26.499954224 11.500000000 35.499950409 26.499954224 12.500000000 35.499950409 26.499954224 13.500000000 35.499950409 26.499954224 14.500000000 35.499950409 26.499954224 15.500000000 35.499950409 26.499954224 16.500000000 35.499950409 26.499954224 17.500000000 35.499950409 26.499954224 18.500000000 35.499950409 26.499954224 19.500000000 35.499950409 26.499954224 20.500000000 35.499950409 26.499954224 21.500000000 35.499950409 26.499954224 22.500000000 35.499950409 26.499954224 23.500000000 35.499950409 26.499954224 24.500000000 35.499950409 26.499954224 25.499996185 35.499950409 26.499954224 26.499954224 35.499908447 26.499954224 27.499591827 35.499542236 26.499954224 28.497470856 35.497406006 26.499954224 29.488397598 35.488258362 26.499938965 30.458948135 35.458606720 26.499858856 31.384296417 35.383720398 26.499622345 32.232860565 35.232303619 26.499225616 32.980327606 34.980201721 26.498950958 -33.977619171 -35.976856232 27.495168686 -33.231597900 -36.228954315 27.496377945 -32.383811951 -36.381027222 27.498052597 -31.458766937 -36.456939697 27.499073029 -30.488346100 -36.487373352 27.499475479 -29.497461319 -36.496910095 27.499576569 -28.499593735 -36.499160767 27.499591827 -27.499954224 -36.499542236 27.499591827 -26.499996185 -36.499591827 27.499591827 -25.500000000 -36.499591827 27.499591827 -24.500000000 -36.499591827 27.499591827 -23.500000000 -36.499591827 27.499591827 -22.500000000 -36.499591827 27.499591827 -21.500000000 -36.499591827 27.499591827 -20.500000000 -36.499591827 27.499591827 -19.500000000 -36.499591827 27.499591827 -18.500000000 -36.499591827 27.499591827 -17.500000000 -36.499591827 27.499591827 -16.500000000 -36.499591827 27.499591827 -15.500000000 -36.499591827 27.499591827 -14.500000000 -36.499591827 27.499591827 -13.500000000 -36.499591827 27.499591827 -12.500000000 -36.499591827 27.499591827 -11.500000000 -36.499591827 27.499591827 -10.500000000 -36.499591827 27.499591827 -9.500000000 -36.499591827 27.499591827 -8.500000000 -36.499591827 27.499591827 -7.500000000 -36.499591827 27.499591827 -6.500000000 -36.499591827 27.499591827 -5.500000000 -36.499591827 27.499591827 -4.500000000 -36.499591827 27.499591827 -3.500000000 -36.499591827 27.499591827 -2.500000000 -36.499591827 27.499591827 -1.500000000 -36.499591827 27.499591827 -0.500000000 -36.499591827 27.499591827 0.500000000 -36.499591827 27.499591827 1.500000000 -36.499591827 27.499591827 2.500000000 -36.499591827 27.499591827 3.500000000 -36.499591827 27.499591827 4.500000000 -36.499591827 27.499591827 5.500000000 -36.499591827 27.499591827 6.500000000 -36.499591827 27.499591827 7.500000000 -36.499591827 27.499591827 8.500000000 -36.499591827 27.499591827 9.500000000 -36.499591827 27.499591827 10.500000000 -36.499591827 27.499591827 11.500000000 -36.499591827 27.499591827 12.500000000 -36.499591827 27.499591827 13.500000000 -36.499591827 27.499591827 14.500000000 -36.499591827 27.499591827 15.500000000 -36.499591827 27.499591827 16.500000000 -36.499591827 27.499591827 17.500000000 -36.499591827 27.499591827 18.500000000 -36.499591827 27.499591827 19.500000000 -36.499591827 27.499591827 20.500000000 -36.499591827 27.499591827 21.500000000 -36.499591827 27.499591827 22.500000000 -36.499591827 27.499591827 23.500000000 -36.499591827 27.499591827 24.500000000 -36.499591827 27.499591827 25.499996185 -36.499591827 27.499591827 26.499954224 -36.499546051 27.499591827 27.499591827 -36.499164581 27.499591827 28.497457504 -36.496910095 27.499576569 29.488346100 -36.487373352 27.499475479 30.458766937 -36.456939697 27.499073029 31.383810043 -36.381027222 27.498052597 32.231597900 -36.228958130 27.496377945 32.977615356 -35.976860046 27.495168686 -35.163158417 -35.163158417 27.496557236 -34.617927551 -35.618598938 27.496026993 33.617927551 -35.618602753 27.496023178 34.163158417 -35.163158417 27.496557236 -35.976860046 -33.977615356 27.495168686 -35.618602753 -34.617927551 27.496026993 34.618602753 -34.617927551 27.496026993 34.976860046 -33.977619171 27.495168686 -36.228958130 -33.231597900 27.496377945 35.228958130 -33.231597900 27.496377945 -36.381027222 -32.383811951 27.498052597 35.381027222 -32.383811951 27.498052597 -36.456939697 -31.458766937 27.499073029 35.456939697 -31.458766937 27.499073029 -36.487373352 -30.488346100 27.499475479 35.487373352 -30.488346100 27.499475479 -36.496910095 -29.497461319 27.499576569 35.496910095 -29.497461319 27.499576569 -36.499160767 -28.499593735 27.499591827 35.499160767 -28.499593735 27.499591827 -36.499542236 -27.499954224 27.499591827 35.499542236 -27.499954224 27.499591827 -36.499584198 -26.499996185 27.499591827 35.499591827 -26.499996185 27.499591827 -36.499591827 -25.500000000 27.499591827 35.499591827 -25.500000000 27.499591827 -36.499591827 -24.500000000 27.499591827 35.499591827 -24.500000000 27.499591827 -36.499591827 -23.500000000 27.499591827 35.499591827 -23.500000000 27.499591827 -36.499591827 -22.500000000 27.499591827 35.499591827 -22.500000000 27.499591827 -36.499591827 -21.500000000 27.499591827 35.499591827 -21.500000000 27.499591827 -36.499591827 -20.500000000 27.499591827 35.499591827 -20.500000000 27.499591827 -36.499591827 -19.500000000 27.499591827 35.499591827 -19.500000000 27.499591827 -36.499591827 -18.500000000 27.499591827 35.499591827 -18.500000000 27.499591827 -36.499591827 -17.500000000 27.499591827 35.499591827 -17.500000000 27.499591827 -36.499591827 -16.500000000 27.499591827 35.499591827 -16.500000000 27.499591827 -36.499591827 -15.500000000 27.499591827 35.499591827 -15.500000000 27.499591827 -36.499591827 -14.500000000 27.499591827 35.499591827 -14.500000000 27.499591827 -36.499591827 -13.500000000 27.499591827 35.499591827 -13.500000000 27.499591827 -36.499591827 -12.500000000 27.499591827 35.499591827 -12.500000000 27.499591827 -36.499591827 -11.500000000 27.499591827 35.499591827 -11.500000000 27.499591827 -36.499591827 -10.500000000 27.499591827 35.499591827 -10.500000000 27.499591827 -36.499591827 -9.500000000 27.499591827 35.499591827 -9.500000000 27.499591827 -36.499591827 -8.500000000 27.499591827 35.499591827 -8.500000000 27.499591827 -36.499591827 -7.500000000 27.499591827 35.499591827 -7.500000000 27.499591827 -36.499591827 -6.500000000 27.499591827 35.499591827 -6.500000000 27.499591827 -36.499591827 -5.500000000 27.499591827 35.499591827 -5.500000000 27.499591827 -36.499591827 -4.500000000 27.499591827 35.499591827 -4.500000000 27.499591827 -36.499591827 -3.500000000 27.499591827 35.499591827 -3.500000000 27.499591827 -36.499591827 -2.500000000 27.499591827 35.499591827 -2.500000000 27.499591827 -36.499591827 -1.500000000 27.499591827 35.499591827 -1.500000000 27.499591827 -36.499591827 -0.500000000 27.499591827 35.499591827 -0.500000000 27.499591827 -36.499591827 0.500000000 27.499591827 35.499591827 0.500000000 27.499591827 -36.499591827 1.500000000 27.499591827 35.499591827 1.500000000 27.499591827 -36.499591827 2.500000000 27.499591827 35.499591827 2.500000000 27.499591827 -36.499591827 3.500000000 27.499591827 35.499591827 3.500000000 27.499591827 -36.499591827 4.500000000 27.499591827 35.499591827 4.500000000 27.499591827 -36.499591827 5.500000000 27.499591827 35.499591827 5.500000000 27.499591827 -36.499591827 6.500000000 27.499591827 35.499591827 6.500000000 27.499591827 -36.499591827 7.500000000 27.499591827 35.499591827 7.500000000 27.499591827 -36.499591827 8.500000000 27.499591827 35.499591827 8.500000000 27.499591827 -36.499591827 9.500000000 27.499591827 35.499591827 9.500000000 27.499591827 -36.499591827 10.500000000 27.499591827 35.499591827 10.500000000 27.499591827 -36.499591827 11.500000000 27.499591827 35.499591827 11.500000000 27.499591827 -36.499591827 12.500000000 27.499591827 35.499591827 12.500000000 27.499591827 -36.499591827 13.500000000 27.499591827 35.499591827 13.500000000 27.499591827 -36.499591827 14.500000000 27.499591827 35.499591827 14.500000000 27.499591827 -36.499591827 15.500000000 27.499591827 35.499591827 15.500000000 27.499591827 -36.499591827 16.500000000 27.499591827 35.499591827 16.500000000 27.499591827 -36.499591827 17.500000000 27.499591827 35.499591827 17.500000000 27.499591827 -36.499591827 18.500000000 27.499591827 35.499591827 18.500000000 27.499591827 -36.499591827 19.500000000 27.499591827 35.499591827 19.500000000 27.499591827 -36.499591827 20.500000000 27.499591827 35.499591827 20.500000000 27.499591827 -36.499591827 21.500000000 27.499591827 35.499591827 21.500000000 27.499591827 -36.499591827 22.500000000 27.499591827 35.499591827 22.500000000 27.499591827 -36.499591827 23.500000000 27.499591827 35.499591827 23.500000000 27.499591827 -36.499591827 24.500000000 27.499591827 35.499591827 24.500000000 27.499591827 -36.499584198 25.499996185 27.499591827 35.499591827 25.499996185 27.499591827 -36.499542236 26.499954224 27.499591827 35.499546051 26.499954224 27.499591827 -36.499160767 27.499591827 27.499591827 35.499164581 27.499591827 27.499591827 -36.496910095 28.497457504 27.499576569 35.496910095 28.497457504 27.499576569 -36.487373352 29.488346100 27.499475479 35.487373352 29.488346100 27.499475479 -36.456939697 30.458766937 27.499073029 35.456939697 30.458766937 27.499073029 -36.381027222 31.383810043 27.498052597 35.381027222 31.383810043 27.498052597 -36.228950500 32.231597900 27.496377945 35.228958130 32.231597900 27.496377945 -35.976856232 32.977611542 27.495168686 -35.618598938 33.617927551 27.496026993 34.618602753 33.617927551 27.496023178 34.976860046 32.977611542 27.495168686 -35.163158417 34.163158417 27.496557236 -34.617927551 34.618602753 27.496026993 33.617927551 34.618602753 27.496026993 34.163158417 34.163158417 27.496557236 -33.977615356 34.976860046 27.495168686 -33.231597900 35.228958130 27.496377945 -32.383811951 35.381027222 27.498052597 -31.458766937 35.456939697 27.499073029 -30.488346100 35.487373352 27.499475479 -29.497461319 35.496910095 27.499576569 -28.499593735 35.499160767 27.499591827 -27.499954224 35.499542236 27.499591827 -26.499996185 35.499584198 27.499591827 -25.500000000 35.499591827 27.499591827 -24.500000000 35.499591827 27.499591827 -23.500000000 35.499591827 27.499591827 -22.500000000 35.499591827 27.499591827 -21.500000000 35.499591827 27.499591827 -20.500000000 35.499591827 27.499591827 -19.500000000 35.499591827 27.499591827 -18.500000000 35.499591827 27.499591827 -17.500000000 35.499591827 27.499591827 -16.500000000 35.499591827 27.499591827 -15.500000000 35.499591827 27.499591827 -14.500000000 35.499591827 27.499591827 -13.500000000 35.499591827 27.499591827 -12.500000000 35.499591827 27.499591827 -11.500000000 35.499591827 27.499591827 -10.500000000 35.499591827 27.499591827 -9.500000000 35.499591827 27.499591827 -8.500000000 35.499591827 27.499591827 -7.500000000 35.499591827 27.499591827 -6.500000000 35.499591827 27.499591827 -5.500000000 35.499591827 27.499591827 -4.500000000 35.499591827 27.499591827 -3.500000000 35.499591827 27.499591827 -2.500000000 35.499591827 27.499591827 -1.500000000 35.499591827 27.499591827 -0.500000000 35.499591827 27.499591827 0.500000000 35.499591827 27.499591827 1.500000000 35.499591827 27.499591827 2.500000000 35.499591827 27.499591827 3.500000000 35.499591827 27.499591827 4.500000000 35.499591827 27.499591827 5.500000000 35.499591827 27.499591827 6.500000000 35.499591827 27.499591827 7.500000000 35.499591827 27.499591827 8.500000000 35.499591827 27.499591827 9.500000000 35.499591827 27.499591827 10.500000000 35.499591827 27.499591827 11.500000000 35.499591827 27.499591827 12.500000000 35.499591827 27.499591827 13.500000000 35.499591827 27.499591827 14.500000000 35.499591827 27.499591827 15.500000000 35.499591827 27.499591827 16.500000000 35.499591827 27.499591827 17.500000000 35.499591827 27.499591827 18.500000000 35.499591827 27.499591827 19.500000000 35.499591827 27.499591827 20.500000000 35.499591827 27.499591827 21.500000000 35.499591827 27.499591827 22.500000000 35.499591827 27.499591827 23.500000000 35.499591827 27.499591827 24.500000000 35.499591827 27.499591827 25.499996185 35.499584198 27.499591827 26.499954224 35.499542236 27.499591827 27.499591827 35.499160767 27.499591827 28.497457504 35.496910095 27.499576569 29.488346100 35.487373352 27.499475479 30.458766937 35.456939697 27.499073029 31.383810043 35.381027222 27.498052597 32.231597900 35.228958130 27.496377945 32.977615356 34.976860046 27.495168686 -33.968864441 -35.965759277 28.481937408 -33.227870941 -36.217510223 28.486719131 -32.382308960 -36.371490479 28.492321014 -31.458078384 -36.450428009 28.495611191 -30.488048553 -36.483341217 28.496957779 -29.497375488 -36.494178772 28.497371674 -28.499578476 -36.496910095 28.497461319 -27.499954224 -36.497402191 28.497470856 -26.499996185 -36.497467041 28.497470856 -25.500000000 -36.497470856 28.497470856 -24.500000000 -36.497470856 28.497470856 -23.500000000 -36.497470856 28.497470856 -22.500000000 -36.497470856 28.497470856 -21.500000000 -36.497470856 28.497470856 -20.500000000 -36.497470856 28.497470856 -19.500000000 -36.497470856 28.497470856 -18.500000000 -36.497470856 28.497470856 -17.500000000 -36.497470856 28.497470856 -16.500000000 -36.497470856 28.497470856 -15.500000000 -36.497470856 28.497470856 -14.500000000 -36.497470856 28.497470856 -13.500000000 -36.497470856 28.497470856 -12.500000000 -36.497470856 28.497470856 -11.500000000 -36.497470856 28.497470856 -10.500000000 -36.497470856 28.497470856 -9.500000000 -36.497470856 28.497470856 -8.500000000 -36.497470856 28.497470856 -7.500000000 -36.497470856 28.497470856 -6.500000000 -36.497470856 28.497470856 -5.500000000 -36.497470856 28.497470856 -4.500000000 -36.497470856 28.497470856 -3.500000000 -36.497470856 28.497470856 -2.500000000 -36.497470856 28.497470856 -1.500000000 -36.497470856 28.497470856 -0.500000000 -36.497470856 28.497470856 0.500000000 -36.497470856 28.497470856 1.500000000 -36.497470856 28.497470856 2.500000000 -36.497470856 28.497470856 3.500000000 -36.497470856 28.497470856 4.500000000 -36.497470856 28.497470856 5.500000000 -36.497470856 28.497470856 6.500000000 -36.497470856 28.497470856 7.500000000 -36.497470856 28.497470856 8.500000000 -36.497470856 28.497470856 9.500000000 -36.497470856 28.497470856 10.500000000 -36.497470856 28.497470856 11.500000000 -36.497470856 28.497470856 12.500000000 -36.497470856 28.497470856 13.500000000 -36.497470856 28.497470856 14.500000000 -36.497470856 28.497470856 15.500000000 -36.497470856 28.497470856 16.500000000 -36.497470856 28.497470856 17.500000000 -36.497470856 28.497470856 18.500000000 -36.497470856 28.497470856 19.500000000 -36.497470856 28.497470856 20.500000000 -36.497470856 28.497470856 21.500000000 -36.497470856 28.497470856 22.500000000 -36.497470856 28.497470856 23.500000000 -36.497470856 28.497470856 24.500000000 -36.497470856 28.497470856 25.499996185 -36.497467041 28.497470856 26.499954224 -36.497406006 28.497470856 27.499576569 -36.496910095 28.497457504 28.497371674 -36.494174957 28.497375488 29.488048553 -36.483337402 28.496957779 30.458078384 -36.450428009 28.495611191 31.382312775 -36.371490479 28.492321014 32.227874756 -36.217517853 28.486719131 32.968864441 -35.965766907 28.481933594 -35.150249481 -35.150249481 28.487289429 -34.604705811 -35.607204437 28.485630035 33.604705811 -35.607208252 28.485630035 34.150249481 -35.150249481 28.487289429 -35.965766907 -33.968864441 28.481937408 -35.607204437 -34.604705811 28.485631943 34.607204437 -34.604705811 28.485631943 34.965766907 -33.968868256 28.481937408 -36.217517853 -33.227874756 28.486719131 35.217517853 -33.227878571 28.486719131 -36.371490479 -32.382312775 28.492321014 35.371490479 -32.382308960 28.492321014 -36.450428009 -31.458078384 28.495611191 35.450428009 -31.458078384 28.495611191 -36.483337402 -30.488048553 28.496957779 35.483341217 -30.488048553 28.496957779 -36.494178772 -29.497375488 28.497371674 35.494178772 -29.497375488 28.497371674 -36.496910095 -28.499578476 28.497461319 35.496910095 -28.499578476 28.497461319 -36.497406006 -27.499954224 28.497470856 35.497402191 -27.499954224 28.497470856 -36.497467041 -26.499996185 28.497470856 35.497467041 -26.499996185 28.497470856 -36.497467041 -25.500000000 28.497470856 35.497470856 -25.500000000 28.497470856 -36.497467041 -24.500000000 28.497470856 35.497470856 -24.500000000 28.497470856 -36.497467041 -23.500000000 28.497470856 35.497470856 -23.500000000 28.497470856 -36.497467041 -22.500000000 28.497470856 35.497470856 -22.500000000 28.497470856 -36.497467041 -21.500000000 28.497470856 35.497470856 -21.500000000 28.497470856 -36.497467041 -20.500000000 28.497470856 35.497470856 -20.500000000 28.497470856 -36.497467041 -19.500000000 28.497470856 35.497470856 -19.500000000 28.497470856 -36.497467041 -18.500000000 28.497470856 35.497470856 -18.500000000 28.497470856 -36.497467041 -17.500000000 28.497470856 35.497470856 -17.500000000 28.497470856 -36.497467041 -16.500000000 28.497470856 35.497470856 -16.500000000 28.497470856 -36.497467041 -15.500000000 28.497470856 35.497470856 -15.500000000 28.497470856 -36.497467041 -14.500000000 28.497470856 35.497470856 -14.500000000 28.497470856 -36.497467041 -13.500000000 28.497470856 35.497470856 -13.500000000 28.497470856 -36.497467041 -12.500000000 28.497470856 35.497470856 -12.500000000 28.497470856 -36.497467041 -11.500000000 28.497470856 35.497470856 -11.500000000 28.497470856 -36.497467041 -10.500000000 28.497470856 35.497470856 -10.500000000 28.497470856 -36.497467041 -9.500000000 28.497470856 35.497470856 -9.500000000 28.497470856 -36.497467041 -8.500000000 28.497470856 35.497470856 -8.500000000 28.497470856 -36.497467041 -7.500000000 28.497470856 35.497470856 -7.500000000 28.497470856 -36.497467041 -6.500000000 28.497470856 35.497470856 -6.500000000 28.497470856 -36.497467041 -5.500000000 28.497470856 35.497470856 -5.500000000 28.497470856 -36.497467041 -4.500000000 28.497470856 35.497470856 -4.500000000 28.497470856 -36.497467041 -3.500000000 28.497470856 35.497470856 -3.500000000 28.497470856 -36.497467041 -2.500000000 28.497470856 35.497470856 -2.500000000 28.497470856 -36.497467041 -1.500000000 28.497470856 35.497470856 -1.500000000 28.497470856 -36.497467041 -0.500000000 28.497470856 35.497470856 -0.500000000 28.497470856 -36.497467041 0.500000000 28.497470856 35.497470856 0.500000000 28.497470856 -36.497467041 1.500000000 28.497470856 35.497470856 1.500000000 28.497470856 -36.497467041 2.500000000 28.497470856 35.497470856 2.500000000 28.497470856 -36.497467041 3.500000000 28.497470856 35.497470856 3.500000000 28.497470856 -36.497467041 4.500000000 28.497470856 35.497470856 4.500000000 28.497470856 -36.497467041 5.500000000 28.497470856 35.497470856 5.500000000 28.497470856 -36.497467041 6.500000000 28.497470856 35.497470856 6.500000000 28.497470856 -36.497467041 7.500000000 28.497470856 35.497470856 7.500000000 28.497470856 -36.497467041 8.500000000 28.497470856 35.497470856 8.500000000 28.497470856 -36.497467041 9.500000000 28.497470856 35.497470856 9.500000000 28.497470856 -36.497467041 10.500000000 28.497470856 35.497470856 10.500000000 28.497470856 -36.497467041 11.500000000 28.497470856 35.497470856 11.500000000 28.497470856 -36.497467041 12.500000000 28.497470856 35.497470856 12.500000000 28.497470856 -36.497467041 13.500000000 28.497470856 35.497470856 13.500000000 28.497470856 -36.497467041 14.500000000 28.497470856 35.497470856 14.500000000 28.497470856 -36.497467041 15.500000000 28.497470856 35.497470856 15.500000000 28.497470856 -36.497467041 16.500000000 28.497470856 35.497470856 16.500000000 28.497470856 -36.497467041 17.500000000 28.497470856 35.497470856 17.500000000 28.497470856 -36.497467041 18.500000000 28.497470856 35.497470856 18.500000000 28.497470856 -36.497467041 19.500000000 28.497470856 35.497470856 19.500000000 28.497470856 -36.497467041 20.500000000 28.497470856 35.497470856 20.500000000 28.497470856 -36.497467041 21.500000000 28.497470856 35.497470856 21.500000000 28.497470856 -36.497467041 22.500000000 28.497470856 35.497470856 22.500000000 28.497470856 -36.497467041 23.500000000 28.497470856 35.497470856 23.500000000 28.497470856 -36.497467041 24.500000000 28.497470856 35.497470856 24.500000000 28.497470856 -36.497467041 25.499996185 28.497470856 35.497467041 25.499996185 28.497470856 -36.497406006 26.499954224 28.497470856 35.497406006 26.499954224 28.497470856 -36.496910095 27.499576569 28.497457504 35.496910095 27.499576569 28.497457504 -36.494178772 28.497375488 28.497371674 35.494174957 28.497371674 28.497375488 -36.483337402 29.488048553 28.496957779 35.483337402 29.488048553 28.496957779 -36.450428009 30.458078384 28.495609283 35.450428009 30.458078384 28.495611191 -36.371490479 31.382312775 28.492321014 35.371490479 31.382312775 28.492321014 -36.217510223 32.227870941 28.486719131 35.217510223 32.227870941 28.486719131 -35.965759277 32.968864441 28.481937408 -35.607204437 33.604705811 28.485630035 34.607204437 33.604705811 28.485630035 34.965759277 32.968864441 28.481937408 -35.150249481 34.150249481 28.487289429 -34.604705811 34.607204437 28.485631943 33.604705811 34.607204437 28.485631943 34.150249481 34.150249481 28.487293243 -33.968864441 34.965766907 28.481937408 -33.227874756 35.217517853 28.486719131 -32.382312775 35.371490479 28.492321014 -31.458078384 35.450428009 28.495611191 -30.488048553 35.483337402 28.496957779 -29.497375488 35.494178772 28.497371674 -28.499578476 35.496910095 28.497461319 -27.499954224 35.497406006 28.497470856 -26.499996185 35.497467041 28.497470856 -25.500000000 35.497467041 28.497470856 -24.500000000 35.497467041 28.497470856 -23.500000000 35.497467041 28.497470856 -22.500000000 35.497467041 28.497470856 -21.500000000 35.497467041 28.497470856 -20.500000000 35.497467041 28.497470856 -19.500000000 35.497467041 28.497470856 -18.500000000 35.497467041 28.497470856 -17.500000000 35.497467041 28.497470856 -16.500000000 35.497467041 28.497470856 -15.500000000 35.497467041 28.497470856 -14.500000000 35.497467041 28.497470856 -13.500000000 35.497467041 28.497470856 -12.500000000 35.497467041 28.497470856 -11.500000000 35.497467041 28.497470856 -10.500000000 35.497467041 28.497470856 -9.500000000 35.497467041 28.497470856 -8.500000000 35.497467041 28.497470856 -7.500000000 35.497467041 28.497470856 -6.500000000 35.497467041 28.497470856 -5.500000000 35.497467041 28.497470856 -4.500000000 35.497467041 28.497470856 -3.500000000 35.497467041 28.497470856 -2.500000000 35.497467041 28.497470856 -1.500000000 35.497467041 28.497470856 -0.500000000 35.497467041 28.497470856 0.500000000 35.497467041 28.497470856 1.500000000 35.497467041 28.497470856 2.500000000 35.497467041 28.497470856 3.500000000 35.497467041 28.497470856 4.500000000 35.497467041 28.497470856 5.500000000 35.497467041 28.497470856 6.500000000 35.497467041 28.497470856 7.500000000 35.497467041 28.497470856 8.500000000 35.497467041 28.497470856 9.500000000 35.497467041 28.497470856 10.500000000 35.497467041 28.497470856 11.500000000 35.497467041 28.497470856 12.500000000 35.497467041 28.497470856 13.500000000 35.497467041 28.497470856 14.500000000 35.497467041 28.497470856 15.500000000 35.497467041 28.497470856 16.500000000 35.497467041 28.497470856 17.500000000 35.497467041 28.497470856 18.500000000 35.497467041 28.497470856 19.500000000 35.497467041 28.497470856 20.500000000 35.497467041 28.497470856 21.500000000 35.497467041 28.497470856 22.500000000 35.497467041 28.497470856 23.500000000 35.497467041 28.497470856 24.500000000 35.497467041 28.497470856 25.499996185 35.497467041 28.497470856 26.499954224 35.497406006 28.497470856 27.499576569 35.496910095 28.497457504 28.497375488 35.494178772 28.497371674 29.488048553 35.483337402 28.496957779 30.458078384 35.450428009 28.495609283 31.382308960 35.371490479 28.492321014 32.227870941 35.217517853 28.486719131 32.968864441 34.965766907 28.481937408 -33.946807861 -35.937091827 29.442840576 -33.220714569 -36.185966492 29.460592270 -32.379219055 -36.344280243 29.476003647 -31.456085205 -36.430480957 29.483789444 -30.486968994 -36.469238281 29.486968994 -29.496959686 -36.483337402 29.488048553 -28.499475479 -36.487373352 29.488346100 -27.499938965 -36.488258362 29.488399506 -26.499996185 -36.488391876 29.488407135 -25.500000000 -36.488403320 29.488407135 -24.500000000 -36.488407135 29.488407135 -23.500000000 -36.488407135 29.488407135 -22.500000000 -36.488407135 29.488407135 -21.500000000 -36.488407135 29.488407135 -20.500000000 -36.488407135 29.488407135 -19.500000000 -36.488407135 29.488407135 -18.500000000 -36.488407135 29.488407135 -17.500000000 -36.488407135 29.488407135 -16.500000000 -36.488407135 29.488407135 -15.500000000 -36.488407135 29.488407135 -14.500000000 -36.488407135 29.488407135 -13.500000000 -36.488407135 29.488407135 -12.500000000 -36.488407135 29.488407135 -11.500000000 -36.488407135 29.488407135 -10.500000000 -36.488407135 29.488407135 -9.500000000 -36.488407135 29.488407135 -8.500000000 -36.488407135 29.488407135 -7.500000000 -36.488407135 29.488407135 -6.500000000 -36.488407135 29.488407135 -5.500000000 -36.488407135 29.488407135 -4.500000000 -36.488407135 29.488407135 -3.500000000 -36.488407135 29.488407135 -2.500000000 -36.488407135 29.488407135 -1.500000000 -36.488407135 29.488407135 -0.500000000 -36.488407135 29.488407135 0.500000000 -36.488407135 29.488407135 1.500000000 -36.488407135 29.488407135 2.500000000 -36.488407135 29.488407135 3.500000000 -36.488407135 29.488407135 4.500000000 -36.488407135 29.488407135 5.500000000 -36.488407135 29.488407135 6.500000000 -36.488407135 29.488407135 7.500000000 -36.488407135 29.488407135 8.500000000 -36.488407135 29.488407135 9.500000000 -36.488407135 29.488407135 10.500000000 -36.488407135 29.488407135 11.500000000 -36.488407135 29.488407135 12.500000000 -36.488407135 29.488407135 13.500000000 -36.488407135 29.488407135 14.500000000 -36.488407135 29.488407135 15.500000000 -36.488407135 29.488407135 16.500000000 -36.488407135 29.488407135 17.500000000 -36.488407135 29.488407135 18.500000000 -36.488407135 29.488407135 19.500000000 -36.488407135 29.488407135 20.500000000 -36.488407135 29.488407135 21.500000000 -36.488407135 29.488407135 22.500000000 -36.488407135 29.488407135 23.500000000 -36.488407135 29.488407135 24.500000000 -36.488407135 29.488407135 25.499996185 -36.488391876 29.488407135 26.499938965 -36.488258362 29.488399506 27.499475479 -36.487373352 29.488346100 28.496959686 -36.483337402 29.488048553 29.486968994 -36.469238281 29.486965179 30.456085205 -36.430480957 29.483789444 31.379222870 -36.344280243 29.476003647 32.220714569 -36.185966492 29.460596085 32.946807861 -35.937091827 29.442840576 -35.115642548 -35.115642548 29.463253021 -34.567741394 -35.577739716 29.459178925 33.567741394 -35.577739716 29.459178925 34.115642548 -35.115642548 29.463253021 -35.937091827 -33.946807861 29.442840576 -35.577739716 -34.567741394 29.459178925 34.577739716 -34.567749023 29.459177017 34.937091827 -33.946807861 29.442840576 -36.185966492 -33.220714569 29.460592270 35.185966492 -33.220718384 29.460592270 -36.344280243 -32.379222870 29.476003647 35.344280243 -32.379222870 29.476003647 -36.430480957 -31.456085205 29.483789444 35.430480957 -31.456085205 29.483789444 -36.469230652 -30.486968994 29.486965179 35.469238281 -30.486968994 29.486968994 -36.483337402 -29.496959686 29.488052368 35.483337402 -29.496959686 29.488048553 -36.487373352 -28.499475479 29.488346100 35.487373352 -28.499475479 29.488346100 -36.488258362 -27.499938965 29.488399506 35.488258362 -27.499938965 29.488399506 -36.488391876 -26.499996185 29.488407135 35.488391876 -26.499996185 29.488407135 -36.488403320 -25.500000000 29.488407135 35.488403320 -25.500000000 29.488407135 -36.488403320 -24.500000000 29.488407135 35.488407135 -24.500000000 29.488407135 -36.488403320 -23.500000000 29.488407135 35.488407135 -23.500000000 29.488407135 -36.488403320 -22.500000000 29.488407135 35.488407135 -22.500000000 29.488407135 -36.488403320 -21.500000000 29.488407135 35.488407135 -21.500000000 29.488407135 -36.488403320 -20.500000000 29.488407135 35.488407135 -20.500000000 29.488407135 -36.488403320 -19.500000000 29.488407135 35.488407135 -19.500000000 29.488407135 -36.488403320 -18.500000000 29.488407135 35.488407135 -18.500000000 29.488407135 -36.488403320 -17.500000000 29.488407135 35.488407135 -17.500000000 29.488407135 -36.488403320 -16.500000000 29.488407135 35.488407135 -16.500000000 29.488407135 -36.488403320 -15.500000000 29.488407135 35.488407135 -15.500000000 29.488407135 -36.488403320 -14.500000000 29.488407135 35.488407135 -14.500000000 29.488407135 -36.488403320 -13.500000000 29.488407135 35.488407135 -13.500000000 29.488407135 -36.488403320 -12.500000000 29.488407135 35.488407135 -12.500000000 29.488407135 -36.488403320 -11.500000000 29.488407135 35.488407135 -11.500000000 29.488407135 -36.488403320 -10.500000000 29.488407135 35.488407135 -10.500000000 29.488407135 -36.488403320 -9.500000000 29.488407135 35.488407135 -9.500000000 29.488407135 -36.488403320 -8.500000000 29.488407135 35.488407135 -8.500000000 29.488407135 -36.488403320 -7.500000000 29.488407135 35.488407135 -7.500000000 29.488407135 -36.488403320 -6.500000000 29.488407135 35.488407135 -6.500000000 29.488407135 -36.488403320 -5.500000000 29.488407135 35.488407135 -5.500000000 29.488407135 -36.488403320 -4.500000000 29.488407135 35.488407135 -4.500000000 29.488407135 -36.488403320 -3.500000000 29.488407135 35.488407135 -3.500000000 29.488407135 -36.488403320 -2.500000000 29.488407135 35.488407135 -2.500000000 29.488407135 -36.488403320 -1.500000000 29.488407135 35.488407135 -1.500000000 29.488407135 -36.488403320 -0.500000000 29.488407135 35.488407135 -0.500000000 29.488407135 -36.488403320 0.500000000 29.488407135 35.488407135 0.500000000 29.488407135 -36.488403320 1.500000000 29.488407135 35.488407135 1.500000000 29.488407135 -36.488403320 2.500000000 29.488407135 35.488407135 2.500000000 29.488407135 -36.488403320 3.500000000 29.488407135 35.488407135 3.500000000 29.488407135 -36.488403320 4.500000000 29.488407135 35.488407135 4.500000000 29.488407135 -36.488403320 5.500000000 29.488407135 35.488407135 5.500000000 29.488407135 -36.488403320 6.500000000 29.488407135 35.488407135 6.500000000 29.488407135 -36.488403320 7.500000000 29.488407135 35.488407135 7.500000000 29.488407135 -36.488403320 8.500000000 29.488407135 35.488407135 8.500000000 29.488407135 -36.488403320 9.500000000 29.488407135 35.488407135 9.500000000 29.488407135 -36.488403320 10.500000000 29.488407135 35.488407135 10.500000000 29.488407135 -36.488403320 11.500000000 29.488407135 35.488407135 11.500000000 29.488407135 -36.488403320 12.500000000 29.488407135 35.488407135 12.500000000 29.488407135 -36.488403320 13.500000000 29.488407135 35.488407135 13.500000000 29.488407135 -36.488403320 14.500000000 29.488407135 35.488407135 14.500000000 29.488407135 -36.488403320 15.500000000 29.488407135 35.488407135 15.500000000 29.488407135 -36.488403320 16.500000000 29.488407135 35.488407135 16.500000000 29.488407135 -36.488403320 17.500000000 29.488407135 35.488407135 17.500000000 29.488407135 -36.488403320 18.500000000 29.488407135 35.488407135 18.500000000 29.488407135 -36.488403320 19.500000000 29.488407135 35.488407135 19.500000000 29.488407135 -36.488403320 20.500000000 29.488407135 35.488407135 20.500000000 29.488407135 -36.488403320 21.500000000 29.488407135 35.488407135 21.500000000 29.488407135 -36.488403320 22.500000000 29.488407135 35.488407135 22.500000000 29.488407135 -36.488403320 23.500000000 29.488407135 35.488407135 23.500000000 29.488407135 -36.488403320 24.500000000 29.488407135 35.488407135 24.500000000 29.488407135 -36.488391876 25.499996185 29.488407135 35.488391876 25.499996185 29.488407135 -36.488258362 26.499938965 29.488399506 35.488258362 26.499938965 29.488399506 -36.487377167 27.499475479 29.488348007 35.487373352 27.499475479 29.488346100 -36.483337402 28.496957779 29.488052368 35.483337402 28.496959686 29.488048553 -36.469238281 29.486965179 29.486968994 35.469238281 29.486968994 29.486965179 -36.430473328 30.456085205 29.483785629 35.430480957 30.456085205 29.483789444 -36.344280243 31.379220963 29.476003647 35.344280243 31.379222870 29.476003647 -36.185966492 32.220710754 29.460596085 35.185966492 32.220714569 29.460596085 -35.937091827 32.946807861 29.442840576 -35.577739716 33.567741394 29.459178925 34.577739716 33.567741394 29.459178925 34.937091827 32.946807861 29.442840576 -35.115642548 34.115642548 29.463253021 -34.567741394 34.577739716 29.459178925 33.567741394 34.577739716 29.459178925 34.115642548 34.115642548 29.463256836 -33.946807861 34.937091827 29.442840576 -33.220714569 35.185966492 29.460592270 -32.379222870 35.344280243 29.476003647 -31.456085205 35.430480957 29.483789444 -30.486968994 35.469230652 29.486965179 -29.496959686 35.483337402 29.488052368 -28.499475479 35.487373352 29.488346100 -27.499938965 35.488258362 29.488399506 -26.499996185 35.488391876 29.488407135 -25.500000000 35.488403320 29.488407135 -24.500000000 35.488403320 29.488407135 -23.500000000 35.488403320 29.488407135 -22.500000000 35.488403320 29.488407135 -21.500000000 35.488403320 29.488407135 -20.500000000 35.488403320 29.488407135 -19.500000000 35.488403320 29.488407135 -18.500000000 35.488403320 29.488407135 -17.500000000 35.488403320 29.488407135 -16.500000000 35.488403320 29.488407135 -15.500000000 35.488403320 29.488407135 -14.500000000 35.488403320 29.488407135 -13.500000000 35.488403320 29.488407135 -12.500000000 35.488403320 29.488407135 -11.500000000 35.488403320 29.488407135 -10.500000000 35.488403320 29.488407135 -9.500000000 35.488403320 29.488407135 -8.500000000 35.488403320 29.488407135 -7.500000000 35.488403320 29.488407135 -6.500000000 35.488403320 29.488407135 -5.500000000 35.488403320 29.488407135 -4.500000000 35.488403320 29.488407135 -3.500000000 35.488403320 29.488407135 -2.500000000 35.488403320 29.488407135 -1.500000000 35.488403320 29.488407135 -0.500000000 35.488403320 29.488407135 0.500000000 35.488403320 29.488407135 1.500000000 35.488403320 29.488407135 2.500000000 35.488403320 29.488407135 3.500000000 35.488403320 29.488407135 4.500000000 35.488403320 29.488407135 5.500000000 35.488403320 29.488407135 6.500000000 35.488403320 29.488407135 7.500000000 35.488403320 29.488407135 8.500000000 35.488403320 29.488407135 9.500000000 35.488403320 29.488407135 10.500000000 35.488403320 29.488407135 11.500000000 35.488403320 29.488407135 12.500000000 35.488403320 29.488407135 13.500000000 35.488403320 29.488407135 14.500000000 35.488403320 29.488407135 15.500000000 35.488403320 29.488407135 16.500000000 35.488403320 29.488407135 17.500000000 35.488403320 29.488407135 18.500000000 35.488403320 29.488407135 19.500000000 35.488403320 29.488407135 20.500000000 35.488403320 29.488407135 21.500000000 35.488403320 29.488407135 22.500000000 35.488403320 29.488407135 23.500000000 35.488403320 29.488407135 24.500000000 35.488403320 29.488407135 25.499996185 35.488391876 29.488407135 26.499938965 35.488258362 29.488399506 27.499475479 35.487377167 29.488348007 28.496957779 35.483337402 29.488052368 29.486965179 35.469238281 29.486968994 30.456085205 35.430473328 29.483785629 31.379220963 35.344280243 29.476003647 32.220710754 35.185966492 29.460596085 32.946807861 34.937091827 29.442840576 -33.903377533 -35.879737854 30.336599350 -33.216838837 -36.112342834 30.405670166 -32.375358582 -36.280395508 30.438953400 -31.451217651 -36.380989075 30.451217651 -30.483789444 -36.430473328 30.456085205 -29.495611191 -36.450424194 30.458078384 -28.499073029 -36.456939697 30.458770752 -27.499858856 -36.458606720 30.458950043 -26.499988556 -36.458930969 30.458980560 -25.500000000 -36.458976746 30.458980560 -24.500000000 -36.458976746 30.458980560 -23.500000000 -36.458976746 30.458980560 -22.500000000 -36.458976746 30.458980560 -21.500000000 -36.458976746 30.458980560 -20.500000000 -36.458976746 30.458980560 -19.500000000 -36.458976746 30.458980560 -18.500000000 -36.458976746 30.458980560 -17.500000000 -36.458976746 30.458980560 -16.500000000 -36.458976746 30.458980560 -15.500000000 -36.458976746 30.458980560 -14.500000000 -36.458976746 30.458980560 -13.500000000 -36.458976746 30.458980560 -12.500000000 -36.458976746 30.458980560 -11.500000000 -36.458976746 30.458980560 -10.500000000 -36.458976746 30.458980560 -9.500000000 -36.458976746 30.458980560 -8.500000000 -36.458976746 30.458980560 -7.500000000 -36.458976746 30.458980560 -6.500000000 -36.458976746 30.458980560 -5.500000000 -36.458976746 30.458980560 -4.500000000 -36.458976746 30.458980560 -3.500000000 -36.458976746 30.458980560 -2.500000000 -36.458976746 30.458980560 -1.500000000 -36.458976746 30.458980560 -0.500000000 -36.458976746 30.458980560 0.500000000 -36.458976746 30.458980560 1.500000000 -36.458976746 30.458980560 2.500000000 -36.458976746 30.458980560 3.500000000 -36.458976746 30.458980560 4.500000000 -36.458976746 30.458980560 5.500000000 -36.458976746 30.458980560 6.500000000 -36.458976746 30.458980560 7.500000000 -36.458976746 30.458980560 8.500000000 -36.458976746 30.458980560 9.500000000 -36.458976746 30.458980560 10.500000000 -36.458976746 30.458980560 11.500000000 -36.458976746 30.458980560 12.500000000 -36.458976746 30.458980560 13.500000000 -36.458976746 30.458980560 14.500000000 -36.458976746 30.458980560 15.500000000 -36.458976746 30.458980560 16.500000000 -36.458976746 30.458980560 17.500000000 -36.458976746 30.458980560 18.500000000 -36.458976746 30.458980560 19.500000000 -36.458976746 30.458980560 20.500000000 -36.458976746 30.458980560 21.500000000 -36.458976746 30.458980560 22.500000000 -36.458976746 30.458980560 23.500000000 -36.458976746 30.458980560 24.500000000 -36.458972931 30.458980560 25.499988556 -36.458930969 30.458978653 26.499858856 -36.458606720 30.458948135 27.499073029 -36.456939697 30.458770752 28.495611191 -36.450424194 30.458080292 29.483789444 -36.430473328 30.456085205 30.451217651 -36.380989075 30.451217651 31.375356674 -36.280395508 30.438949585 32.216838837 -36.112342834 30.405673981 32.903377533 -35.879737854 30.336599350 -35.040893555 -35.040893555 30.413049698 -34.477191925 -35.518615723 30.410833359 33.477191925 -35.518619537 30.410833359 34.040893555 -35.040897369 30.413049698 -35.879737854 -33.903377533 30.336599350 -35.518615723 -34.477191925 30.410833359 34.518619537 -34.477191925 30.410833359 34.879737854 -33.903381348 30.336603165 -36.112342834 -33.216838837 30.405670166 35.112342834 -33.216838837 30.405670166 -36.280395508 -32.375358582 30.438953400 35.280395508 -32.375358582 30.438953400 -36.380989075 -31.451217651 30.451217651 35.380989075 -31.451217651 30.451217651 -36.430473328 -30.483789444 30.456085205 35.430473328 -30.483789444 30.456085205 -36.450424194 -29.495611191 30.458078384 35.450424194 -29.495611191 30.458078384 -36.456939697 -28.499073029 30.458770752 35.456939697 -28.499073029 30.458770752 -36.458606720 -27.499858856 30.458950043 35.458606720 -27.499858856 30.458950043 -36.458930969 -26.499988556 30.458980560 35.458930969 -26.499988556 30.458980560 -36.458976746 -25.500000000 30.458980560 35.458976746 -25.500000000 30.458980560 -36.458980560 -24.500000000 30.458980560 35.458976746 -24.500000000 30.458980560 -36.458980560 -23.500000000 30.458980560 35.458976746 -23.500000000 30.458980560 -36.458980560 -22.500000000 30.458980560 35.458976746 -22.500000000 30.458980560 -36.458980560 -21.500000000 30.458980560 35.458976746 -21.500000000 30.458980560 -36.458980560 -20.500000000 30.458980560 35.458976746 -20.500000000 30.458980560 -36.458980560 -19.500000000 30.458980560 35.458976746 -19.500000000 30.458980560 -36.458980560 -18.500000000 30.458980560 35.458976746 -18.500000000 30.458980560 -36.458980560 -17.500000000 30.458980560 35.458976746 -17.500000000 30.458980560 -36.458980560 -16.500000000 30.458980560 35.458976746 -16.500000000 30.458980560 -36.458980560 -15.500000000 30.458980560 35.458976746 -15.500000000 30.458980560 -36.458980560 -14.500000000 30.458980560 35.458976746 -14.500000000 30.458980560 -36.458980560 -13.500000000 30.458980560 35.458976746 -13.500000000 30.458980560 -36.458980560 -12.500000000 30.458980560 35.458976746 -12.500000000 30.458980560 -36.458980560 -11.500000000 30.458980560 35.458976746 -11.500000000 30.458980560 -36.458980560 -10.500000000 30.458980560 35.458976746 -10.500000000 30.458980560 -36.458980560 -9.500000000 30.458980560 35.458976746 -9.500000000 30.458980560 -36.458980560 -8.500000000 30.458980560 35.458976746 -8.500000000 30.458980560 -36.458980560 -7.500000000 30.458980560 35.458976746 -7.500000000 30.458980560 -36.458980560 -6.500000000 30.458980560 35.458976746 -6.500000000 30.458980560 -36.458980560 -5.500000000 30.458980560 35.458976746 -5.500000000 30.458980560 -36.458980560 -4.500000000 30.458980560 35.458976746 -4.500000000 30.458980560 -36.458980560 -3.500000000 30.458980560 35.458976746 -3.500000000 30.458980560 -36.458980560 -2.500000000 30.458980560 35.458976746 -2.500000000 30.458980560 -36.458980560 -1.500000000 30.458980560 35.458976746 -1.500000000 30.458980560 -36.458980560 -0.500000000 30.458980560 35.458976746 -0.500000000 30.458980560 -36.458980560 0.500000000 30.458980560 35.458976746 0.500000000 30.458980560 -36.458980560 1.500000000 30.458980560 35.458976746 1.500000000 30.458980560 -36.458980560 2.500000000 30.458980560 35.458976746 2.500000000 30.458980560 -36.458980560 3.500000000 30.458980560 35.458976746 3.500000000 30.458980560 -36.458980560 4.500000000 30.458980560 35.458976746 4.500000000 30.458980560 -36.458980560 5.500000000 30.458980560 35.458976746 5.500000000 30.458980560 -36.458980560 6.500000000 30.458980560 35.458976746 6.500000000 30.458980560 -36.458980560 7.500000000 30.458980560 35.458976746 7.500000000 30.458980560 -36.458980560 8.500000000 30.458980560 35.458976746 8.500000000 30.458980560 -36.458980560 9.500000000 30.458980560 35.458976746 9.500000000 30.458980560 -36.458980560 10.500000000 30.458980560 35.458976746 10.500000000 30.458980560 -36.458980560 11.500000000 30.458980560 35.458976746 11.500000000 30.458980560 -36.458980560 12.500000000 30.458980560 35.458976746 12.500000000 30.458980560 -36.458980560 13.500000000 30.458980560 35.458976746 13.500000000 30.458980560 -36.458980560 14.500000000 30.458980560 35.458976746 14.500000000 30.458980560 -36.458980560 15.500000000 30.458980560 35.458976746 15.500000000 30.458980560 -36.458980560 16.500000000 30.458980560 35.458976746 16.500000000 30.458980560 -36.458980560 17.500000000 30.458980560 35.458976746 17.500000000 30.458980560 -36.458980560 18.500000000 30.458980560 35.458976746 18.500000000 30.458980560 -36.458980560 19.500000000 30.458980560 35.458976746 19.500000000 30.458980560 -36.458980560 20.500000000 30.458980560 35.458976746 20.500000000 30.458980560 -36.458980560 21.500000000 30.458980560 35.458976746 21.500000000 30.458980560 -36.458980560 22.500000000 30.458980560 35.458976746 22.500000000 30.458980560 -36.458980560 23.500000000 30.458980560 35.458976746 23.500000000 30.458980560 -36.458976746 24.500000000 30.458980560 35.458972931 24.500000000 30.458980560 -36.458934784 25.499988556 30.458978653 35.458930969 25.499988556 30.458978653 -36.458606720 26.499858856 30.458948135 35.458606720 26.499858856 30.458948135 -36.456939697 27.499073029 30.458770752 35.456939697 27.499073029 30.458770752 -36.450428009 28.495611191 30.458080292 35.450424194 28.495611191 30.458080292 -36.430473328 29.483789444 30.456085205 35.430473328 29.483789444 30.456085205 -36.380989075 30.451217651 30.451217651 35.380989075 30.451217651 30.451217651 -36.280395508 31.375356674 30.438953400 35.280395508 31.375356674 30.438949585 -36.112342834 32.216835022 30.405673981 35.112342834 32.216835022 30.405673981 -35.879737854 32.903377533 30.336599350 -35.518615723 33.477191925 30.410833359 34.518615723 33.477191925 30.410833359 34.879737854 32.903377533 30.336599350 -35.040893555 34.040893555 30.413049698 -34.477191925 34.518615723 30.410833359 33.477191925 34.518615723 30.410833359 34.040893555 34.040893555 30.413049698 -33.903377533 34.879737854 30.336599350 -33.216838837 35.112342834 30.405670166 -32.375358582 35.280395508 30.438953400 -31.451217651 35.380989075 30.451217651 -30.483789444 35.430473328 30.456085205 -29.495611191 35.450424194 30.458078384 -28.499073029 35.456939697 30.458770752 -27.499858856 35.458606720 30.458950043 -26.499988556 35.458930969 30.458980560 -25.500000000 35.458976746 30.458980560 -24.500000000 35.458980560 30.458980560 -23.500000000 35.458980560 30.458980560 -22.500000000 35.458980560 30.458980560 -21.500000000 35.458980560 30.458980560 -20.500000000 35.458980560 30.458980560 -19.500000000 35.458980560 30.458980560 -18.500000000 35.458980560 30.458980560 -17.500000000 35.458980560 30.458980560 -16.500000000 35.458980560 30.458980560 -15.500000000 35.458980560 30.458980560 -14.500000000 35.458980560 30.458980560 -13.500000000 35.458980560 30.458980560 -12.500000000 35.458980560 30.458980560 -11.500000000 35.458980560 30.458980560 -10.500000000 35.458980560 30.458980560 -9.500000000 35.458980560 30.458980560 -8.500000000 35.458980560 30.458980560 -7.500000000 35.458980560 30.458980560 -6.500000000 35.458980560 30.458980560 -5.500000000 35.458980560 30.458980560 -4.500000000 35.458980560 30.458980560 -3.500000000 35.458980560 30.458980560 -2.500000000 35.458980560 30.458980560 -1.500000000 35.458980560 30.458980560 -0.500000000 35.458980560 30.458980560 0.500000000 35.458980560 30.458980560 1.500000000 35.458980560 30.458980560 2.500000000 35.458980560 30.458980560 3.500000000 35.458980560 30.458980560 4.500000000 35.458980560 30.458980560 5.500000000 35.458980560 30.458980560 6.500000000 35.458980560 30.458980560 7.500000000 35.458980560 30.458980560 8.500000000 35.458980560 30.458980560 9.500000000 35.458980560 30.458980560 10.500000000 35.458980560 30.458980560 11.500000000 35.458980560 30.458980560 12.500000000 35.458980560 30.458980560 13.500000000 35.458980560 30.458980560 14.500000000 35.458980560 30.458980560 15.500000000 35.458980560 30.458980560 16.500000000 35.458980560 30.458980560 17.500000000 35.458980560 30.458980560 18.500000000 35.458980560 30.458980560 19.500000000 35.458980560 30.458980560 20.500000000 35.458980560 30.458980560 21.500000000 35.458980560 30.458980560 22.500000000 35.458980560 30.458980560 23.500000000 35.458980560 30.458980560 24.500000000 35.458976746 30.458980560 25.499988556 35.458934784 30.458978653 26.499858856 35.458606720 30.458948135 27.499073029 35.456939697 30.458770752 28.495611191 35.450428009 30.458080292 29.483789444 35.430473328 30.456085205 30.451217651 35.380989075 30.451217651 31.375360489 35.280395508 30.438953400 32.216842651 35.112342834 30.405673981 32.903377533 34.879737854 30.336603165 -33.840934753 -35.797355652 31.035345078 -33.254272461 -35.954723358 31.334243774 -32.371025085 -36.154674530 31.371026993 -31.438953400 -36.280391693 31.375360489 -30.476007462 -36.344280243 31.379222870 -29.492319107 -36.371486664 31.382312775 -28.498052597 -36.381027222 31.383813858 -27.499622345 -36.383720398 31.384298325 -26.499948502 -36.384304047 31.384403229 -25.499996185 -36.384407043 31.384418488 -24.500000000 -36.384418488 31.384418488 -23.500000000 -36.384418488 31.384418488 -22.500000000 -36.384418488 31.384418488 -21.500000000 -36.384418488 31.384418488 -20.500000000 -36.384418488 31.384418488 -19.500000000 -36.384418488 31.384418488 -18.500000000 -36.384418488 31.384418488 -17.500000000 -36.384418488 31.384418488 -16.500000000 -36.384418488 31.384418488 -15.500000000 -36.384418488 31.384418488 -14.500000000 -36.384418488 31.384418488 -13.500000000 -36.384418488 31.384418488 -12.500000000 -36.384418488 31.384418488 -11.500000000 -36.384418488 31.384418488 -10.500000000 -36.384418488 31.384418488 -9.500000000 -36.384418488 31.384418488 -8.500000000 -36.384418488 31.384418488 -7.500000000 -36.384418488 31.384418488 -6.500000000 -36.384418488 31.384418488 -5.500000000 -36.384418488 31.384418488 -4.500000000 -36.384418488 31.384418488 -3.500000000 -36.384418488 31.384418488 -2.500000000 -36.384418488 31.384418488 -1.500000000 -36.384418488 31.384418488 -0.500000000 -36.384418488 31.384418488 0.500000000 -36.384418488 31.384418488 1.500000000 -36.384418488 31.384418488 2.500000000 -36.384418488 31.384418488 3.500000000 -36.384418488 31.384418488 4.500000000 -36.384418488 31.384418488 5.500000000 -36.384418488 31.384418488 6.500000000 -36.384418488 31.384418488 7.500000000 -36.384418488 31.384418488 8.500000000 -36.384418488 31.384418488 9.500000000 -36.384418488 31.384418488 10.500000000 -36.384418488 31.384418488 11.500000000 -36.384418488 31.384418488 12.500000000 -36.384418488 31.384418488 13.500000000 -36.384418488 31.384418488 14.500000000 -36.384418488 31.384418488 15.500000000 -36.384418488 31.384418488 16.500000000 -36.384418488 31.384418488 17.500000000 -36.384418488 31.384418488 18.500000000 -36.384418488 31.384418488 19.500000000 -36.384418488 31.384418488 20.500000000 -36.384418488 31.384418488 21.500000000 -36.384418488 31.384418488 22.500000000 -36.384418488 31.384418488 23.500000000 -36.384410858 31.384418488 24.499996185 -36.384407043 31.384418488 25.499948502 -36.384307861 31.384405136 26.499618530 -36.383720398 31.384296417 27.498050690 -36.381027222 31.383813858 28.492321014 -36.371486664 31.382312775 29.476007462 -36.344284058 31.379222870 30.438953400 -36.280395508 31.375360489 31.371026993 -36.154670715 31.371026993 32.254276276 -35.954719543 31.334241867 32.840930939 -35.797355652 31.035345078 -34.912059784 -34.912059784 31.313602448 -34.260543823 -35.428531647 31.380739212 -33.678352356 -35.670326233 31.736053467 32.678352356 -35.670326233 31.736053467 33.260547638 -35.428535461 31.380739212 33.912063599 -34.912063599 31.313602448 -35.797355652 -33.840930939 31.035345078 -35.428535461 -34.260543823 31.380739212 34.428535461 -34.260543823 31.380739212 34.797355652 -33.840930939 31.035345078 -35.954723358 -33.254272461 31.334243774 -35.670322418 -33.678352356 31.736053467 34.670326233 -33.678352356 31.736053467 34.954723358 -33.254272461 31.334243774 -36.154674530 -32.371025085 31.371026993 35.154674530 -32.371025085 31.371026993 -36.280391693 -31.438953400 31.375360489 35.280395508 -31.438953400 31.375360489 -36.344280243 -30.476007462 31.379222870 35.344280243 -30.476007462 31.379222870 -36.371486664 -29.492321014 31.382312775 35.371486664 -29.492319107 31.382312775 -36.381027222 -28.498050690 31.383813858 35.381027222 -28.498052597 31.383813858 -36.383720398 -27.499618530 31.384296417 35.383720398 -27.499622345 31.384298325 -36.384307861 -26.499948502 31.384403229 35.384304047 -26.499948502 31.384403229 -36.384407043 -25.499996185 31.384418488 35.384407043 -25.499996185 31.384418488 -36.384418488 -24.500000000 31.384418488 35.384418488 -24.500000000 31.384418488 -36.384418488 -23.500000000 31.384418488 35.384418488 -23.500000000 31.384418488 -36.384418488 -22.500000000 31.384418488 35.384418488 -22.500000000 31.384418488 -36.384418488 -21.500000000 31.384418488 35.384418488 -21.500000000 31.384418488 -36.384418488 -20.500000000 31.384418488 35.384418488 -20.500000000 31.384418488 -36.384418488 -19.500000000 31.384418488 35.384418488 -19.500000000 31.384418488 -36.384418488 -18.500000000 31.384418488 35.384418488 -18.500000000 31.384418488 -36.384418488 -17.500000000 31.384418488 35.384418488 -17.500000000 31.384418488 -36.384418488 -16.500000000 31.384418488 35.384418488 -16.500000000 31.384418488 -36.384418488 -15.500000000 31.384418488 35.384418488 -15.500000000 31.384418488 -36.384418488 -14.500000000 31.384418488 35.384418488 -14.500000000 31.384418488 -36.384418488 -13.500000000 31.384418488 35.384418488 -13.500000000 31.384418488 -36.384418488 -12.500000000 31.384418488 35.384418488 -12.500000000 31.384418488 -36.384418488 -11.500000000 31.384418488 35.384418488 -11.500000000 31.384418488 -36.384418488 -10.500000000 31.384418488 35.384418488 -10.500000000 31.384418488 -36.384418488 -9.500000000 31.384418488 35.384418488 -9.500000000 31.384418488 -36.384418488 -8.500000000 31.384418488 35.384418488 -8.500000000 31.384418488 -36.384418488 -7.500000000 31.384418488 35.384418488 -7.500000000 31.384418488 -36.384418488 -6.500000000 31.384418488 35.384418488 -6.500000000 31.384418488 -36.384418488 -5.500000000 31.384418488 35.384418488 -5.500000000 31.384418488 -36.384418488 -4.500000000 31.384418488 35.384418488 -4.500000000 31.384418488 -36.384418488 -3.500000000 31.384418488 35.384418488 -3.500000000 31.384418488 -36.384418488 -2.500000000 31.384418488 35.384418488 -2.500000000 31.384418488 -36.384418488 -1.500000000 31.384418488 35.384418488 -1.500000000 31.384418488 -36.384418488 -0.500000000 31.384418488 35.384418488 -0.500000000 31.384418488 -36.384418488 0.500000000 31.384418488 35.384418488 0.500000000 31.384418488 -36.384418488 1.500000000 31.384418488 35.384418488 1.500000000 31.384418488 -36.384418488 2.500000000 31.384418488 35.384418488 2.500000000 31.384418488 -36.384418488 3.500000000 31.384418488 35.384418488 3.500000000 31.384418488 -36.384418488 4.500000000 31.384418488 35.384418488 4.500000000 31.384418488 -36.384418488 5.500000000 31.384418488 35.384418488 5.500000000 31.384418488 -36.384418488 6.500000000 31.384418488 35.384418488 6.500000000 31.384418488 -36.384418488 7.500000000 31.384418488 35.384418488 7.500000000 31.384418488 -36.384418488 8.500000000 31.384418488 35.384418488 8.500000000 31.384418488 -36.384418488 9.500000000 31.384418488 35.384418488 9.500000000 31.384418488 -36.384418488 10.500000000 31.384418488 35.384418488 10.500000000 31.384418488 -36.384418488 11.500000000 31.384418488 35.384418488 11.500000000 31.384418488 -36.384418488 12.500000000 31.384418488 35.384418488 12.500000000 31.384418488 -36.384418488 13.500000000 31.384418488 35.384418488 13.500000000 31.384418488 -36.384418488 14.500000000 31.384418488 35.384418488 14.500000000 31.384418488 -36.384418488 15.500000000 31.384418488 35.384418488 15.500000000 31.384418488 -36.384418488 16.500000000 31.384418488 35.384418488 16.500000000 31.384418488 -36.384418488 17.500000000 31.384418488 35.384418488 17.500000000 31.384418488 -36.384418488 18.500000000 31.384418488 35.384418488 18.500000000 31.384418488 -36.384418488 19.500000000 31.384418488 35.384418488 19.500000000 31.384418488 -36.384418488 20.500000000 31.384418488 35.384418488 20.500000000 31.384418488 -36.384418488 21.500000000 31.384418488 35.384418488 21.500000000 31.384418488 -36.384418488 22.500000000 31.384418488 35.384418488 22.500000000 31.384418488 -36.384418488 23.500000000 31.384418488 35.384410858 23.500000000 31.384418488 -36.384407043 24.499996185 31.384418488 35.384407043 24.499996185 31.384418488 -36.384311676 25.499948502 31.384403229 35.384307861 25.499948502 31.384405136 -36.383720398 26.499622345 31.384296417 35.383720398 26.499618530 31.384296417 -36.381027222 27.498052597 31.383813858 35.381023407 27.498050690 31.383813858 -36.371486664 28.492321014 31.382312775 35.371486664 28.492321014 31.382312775 -36.344280243 29.476007462 31.379222870 35.344280243 29.476007462 31.379222870 -36.280395508 30.438953400 31.375360489 35.280395508 30.438953400 31.375360489 -36.154670715 31.371026993 31.371028900 35.154670715 31.371026993 31.371026993 -35.954723358 32.254276276 31.334243774 -35.670322418 32.678352356 31.736053467 34.670326233 32.678352356 31.736053467 34.954719543 32.254276276 31.334241867 -35.797355652 32.840934753 31.035345078 -35.428531647 33.260543823 31.380739212 34.428531647 33.260543823 31.380739212 34.797351837 32.840930939 31.035345078 -34.912059784 33.912059784 31.313602448 -34.260543823 34.428535461 31.380739212 -33.678352356 34.670322418 31.736053467 32.678352356 34.670326233 31.736053467 33.260543823 34.428535461 31.380739212 33.912063599 33.912063599 31.313602448 -33.840930939 34.797355652 31.035345078 -33.254272461 34.954723358 31.334243774 -32.371025085 35.154674530 31.371026993 -31.438953400 35.280391693 31.375360489 -30.476007462 35.344280243 31.379222870 -29.492321014 35.371486664 31.382312775 -28.498050690 35.381027222 31.383813858 -27.499618530 35.383720398 31.384296417 -26.499948502 35.384307861 31.384403229 -25.499996185 35.384407043 31.384418488 -24.500000000 35.384418488 31.384418488 -23.500000000 35.384418488 31.384418488 -22.500000000 35.384418488 31.384418488 -21.500000000 35.384418488 31.384418488 -20.500000000 35.384418488 31.384418488 -19.500000000 35.384418488 31.384418488 -18.500000000 35.384418488 31.384418488 -17.500000000 35.384418488 31.384418488 -16.500000000 35.384418488 31.384418488 -15.500000000 35.384418488 31.384418488 -14.500000000 35.384418488 31.384418488 -13.500000000 35.384418488 31.384418488 -12.500000000 35.384418488 31.384418488 -11.500000000 35.384418488 31.384418488 -10.500000000 35.384418488 31.384418488 -9.500000000 35.384418488 31.384418488 -8.500000000 35.384418488 31.384418488 -7.500000000 35.384418488 31.384418488 -6.500000000 35.384418488 31.384418488 -5.500000000 35.384418488 31.384418488 -4.500000000 35.384418488 31.384418488 -3.500000000 35.384418488 31.384418488 -2.500000000 35.384418488 31.384418488 -1.500000000 35.384418488 31.384418488 -0.500000000 35.384418488 31.384418488 0.500000000 35.384418488 31.384418488 1.500000000 35.384418488 31.384418488 2.500000000 35.384418488 31.384418488 3.500000000 35.384418488 31.384418488 4.500000000 35.384418488 31.384418488 5.500000000 35.384418488 31.384418488 6.500000000 35.384418488 31.384418488 7.500000000 35.384418488 31.384418488 8.500000000 35.384418488 31.384418488 9.500000000 35.384418488 31.384418488 10.500000000 35.384418488 31.384418488 11.500000000 35.384418488 31.384418488 12.500000000 35.384418488 31.384418488 13.500000000 35.384418488 31.384418488 14.500000000 35.384418488 31.384418488 15.500000000 35.384418488 31.384418488 16.500000000 35.384418488 31.384418488 17.500000000 35.384418488 31.384418488 18.500000000 35.384418488 31.384418488 19.500000000 35.384418488 31.384418488 20.500000000 35.384418488 31.384418488 21.500000000 35.384418488 31.384418488 22.500000000 35.384418488 31.384418488 23.500000000 35.384418488 31.384418488 24.499996185 35.384407043 31.384418488 25.499948502 35.384311676 31.384403229 26.499622345 35.383720398 31.384296417 27.498052597 35.381027222 31.383813858 28.492321014 35.371486664 31.382312775 29.476007462 35.344280243 31.379222870 30.438953400 35.280395508 31.375360489 31.371026993 35.154674530 31.371028900 32.254272461 34.954723358 31.334243774 32.840934753 34.797355652 31.035345078 -33.030693054 -35.846317291 32.030693054 -32.334243774 -35.954723358 32.254276276 -31.405670166 -36.112342834 32.216838837 -30.460596085 -36.185962677 32.220710754 -29.486719131 -36.217510223 32.227870941 -28.496377945 -36.228950500 32.231601715 -27.499225616 -36.232303619 32.232860565 -26.499872208 -36.233070374 32.233165741 -25.499986649 -36.233203888 32.233215332 -24.499998093 -36.233222961 32.233222961 -23.500000000 -36.233222961 32.233222961 -22.500000000 -36.233222961 32.233222961 -21.500000000 -36.233222961 32.233222961 -20.500000000 -36.233222961 32.233222961 -19.500000000 -36.233222961 32.233222961 -18.500000000 -36.233222961 32.233222961 -17.500000000 -36.233222961 32.233222961 -16.500000000 -36.233222961 32.233222961 -15.500000000 -36.233222961 32.233222961 -14.500000000 -36.233222961 32.233222961 -13.500000000 -36.233222961 32.233222961 -12.500000000 -36.233222961 32.233222961 -11.500000000 -36.233222961 32.233222961 -10.500000000 -36.233222961 32.233222961 -9.500000000 -36.233222961 32.233222961 -8.500000000 -36.233222961 32.233222961 -7.500000000 -36.233222961 32.233222961 -6.500000000 -36.233222961 32.233222961 -5.500000000 -36.233222961 32.233222961 -4.500000000 -36.233222961 32.233222961 -3.500000000 -36.233222961 32.233222961 -2.500000000 -36.233222961 32.233222961 -1.500000000 -36.233222961 32.233222961 -0.500000000 -36.233222961 32.233222961 0.500000000 -36.233222961 32.233222961 1.500000000 -36.233222961 32.233222961 2.500000000 -36.233222961 32.233222961 3.500000000 -36.233222961 32.233222961 4.500000000 -36.233222961 32.233222961 5.500000000 -36.233222961 32.233222961 6.500000000 -36.233222961 32.233222961 7.500000000 -36.233222961 32.233222961 8.500000000 -36.233222961 32.233222961 9.500000000 -36.233222961 32.233222961 10.500000000 -36.233222961 32.233222961 11.500000000 -36.233222961 32.233222961 12.500000000 -36.233222961 32.233222961 13.500000000 -36.233222961 32.233222961 14.500000000 -36.233222961 32.233222961 15.500000000 -36.233222961 32.233222961 16.500000000 -36.233222961 32.233222961 17.500000000 -36.233222961 32.233222961 18.500000000 -36.233222961 32.233222961 19.500000000 -36.233222961 32.233222961 20.500000000 -36.233222961 32.233222961 21.500000000 -36.233222961 32.233222961 22.500000000 -36.233222961 32.233222961 23.499998093 -36.233222961 32.233222961 24.499986649 -36.233203888 32.233219147 25.499874115 -36.233070374 32.233165741 26.499225616 -36.232303619 32.232860565 27.496377945 -36.228954315 32.231597900 28.486715317 -36.217510223 32.227874756 29.460596085 -36.185966492 32.220710754 30.405673981 -36.112342834 32.216835022 31.334245682 -35.954723358 32.254276276 32.030693054 -35.846313477 32.030693054 -34.772159576 -34.772163391 32.006500244 -34.231872559 -35.057430267 32.316947937 -33.424438477 -35.498546600 32.424438477 -32.736053467 -35.670326233 32.678352356 31.736051559 -35.670322418 32.678352356 32.424442291 -35.498542786 32.424442291 33.231868744 -35.057430267 32.316951752 33.772163391 -34.772163391 32.006500244 -35.057430267 -34.231868744 32.316947937 -34.565631866 -34.565628052 32.672851562 33.565631866 -34.565631866 32.672851562 34.057430267 -34.231872559 32.316947937 -35.846313477 -33.030693054 32.030693054 -35.498538971 -33.424438477 32.424442291 34.498542786 -33.424442291 32.424438477 34.846317291 -33.030693054 32.030693054 -35.954715729 -32.334243774 32.254276276 -35.670322418 -32.736049652 32.678356171 34.670326233 -32.736049652 32.678352356 34.954723358 -32.334243774 32.254276276 -36.112346649 -31.405673981 32.216838837 35.112342834 -31.405673981 32.216838837 -36.185966492 -30.460596085 32.220714569 35.185966492 -30.460596085 32.220710754 -36.217510223 -29.486719131 32.227870941 35.217510223 -29.486719131 32.227870941 -36.228950500 -28.496377945 32.231597900 35.228954315 -28.496377945 32.231597900 -36.232299805 -27.499221802 32.232860565 35.232303619 -27.499225616 32.232860565 -36.233070374 -26.499872208 32.233165741 35.233070374 -26.499872208 32.233165741 -36.233207703 -25.499986649 32.233215332 35.233203888 -25.499986649 32.233215332 -36.233222961 -24.499998093 32.233222961 35.233222961 -24.499998093 32.233222961 -36.233222961 -23.500000000 32.233222961 35.233222961 -23.500000000 32.233222961 -36.233222961 -22.500000000 32.233222961 35.233222961 -22.500000000 32.233222961 -36.233222961 -21.500000000 32.233222961 35.233222961 -21.500000000 32.233222961 -36.233222961 -20.500000000 32.233222961 35.233222961 -20.500000000 32.233222961 -36.233222961 -19.500000000 32.233222961 35.233222961 -19.500000000 32.233222961 -36.233222961 -18.500000000 32.233222961 35.233222961 -18.500000000 32.233222961 -36.233222961 -17.500000000 32.233222961 35.233222961 -17.500000000 32.233222961 -36.233222961 -16.500000000 32.233222961 35.233222961 -16.500000000 32.233222961 -36.233222961 -15.500000000 32.233222961 35.233222961 -15.500000000 32.233222961 -36.233222961 -14.500000000 32.233222961 35.233222961 -14.500000000 32.233222961 -36.233222961 -13.500000000 32.233222961 35.233222961 -13.500000000 32.233222961 -36.233222961 -12.500000000 32.233222961 35.233222961 -12.500000000 32.233222961 -36.233222961 -11.500000000 32.233222961 35.233222961 -11.500000000 32.233222961 -36.233222961 -10.500000000 32.233222961 35.233222961 -10.500000000 32.233222961 -36.233222961 -9.500000000 32.233222961 35.233222961 -9.500000000 32.233222961 -36.233222961 -8.500000000 32.233222961 35.233222961 -8.500000000 32.233222961 -36.233222961 -7.500000000 32.233222961 35.233222961 -7.500000000 32.233222961 -36.233222961 -6.500000000 32.233222961 35.233222961 -6.500000000 32.233222961 -36.233222961 -5.500000000 32.233222961 35.233222961 -5.500000000 32.233222961 -36.233222961 -4.500000000 32.233222961 35.233222961 -4.500000000 32.233222961 -36.233222961 -3.500000000 32.233222961 35.233222961 -3.500000000 32.233222961 -36.233222961 -2.500000000 32.233222961 35.233222961 -2.500000000 32.233222961 -36.233222961 -1.500000000 32.233222961 35.233222961 -1.500000000 32.233222961 -36.233222961 -0.500000000 32.233222961 35.233222961 -0.500000000 32.233222961 -36.233222961 0.500000000 32.233222961 35.233222961 0.500000000 32.233222961 -36.233222961 1.500000000 32.233222961 35.233222961 1.500000000 32.233222961 -36.233222961 2.500000000 32.233222961 35.233222961 2.500000000 32.233222961 -36.233222961 3.500000000 32.233222961 35.233222961 3.500000000 32.233222961 -36.233222961 4.500000000 32.233222961 35.233222961 4.500000000 32.233222961 -36.233222961 5.500000000 32.233222961 35.233222961 5.500000000 32.233222961 -36.233222961 6.500000000 32.233222961 35.233222961 6.500000000 32.233222961 -36.233222961 7.500000000 32.233222961 35.233222961 7.500000000 32.233222961 -36.233222961 8.500000000 32.233222961 35.233222961 8.500000000 32.233222961 -36.233222961 9.500000000 32.233222961 35.233222961 9.500000000 32.233222961 -36.233222961 10.500000000 32.233222961 35.233222961 10.500000000 32.233222961 -36.233222961 11.500000000 32.233222961 35.233222961 11.500000000 32.233222961 -36.233222961 12.500000000 32.233222961 35.233222961 12.500000000 32.233222961 -36.233222961 13.500000000 32.233222961 35.233222961 13.500000000 32.233222961 -36.233222961 14.500000000 32.233222961 35.233222961 14.500000000 32.233222961 -36.233222961 15.500000000 32.233222961 35.233222961 15.500000000 32.233222961 -36.233222961 16.500000000 32.233222961 35.233222961 16.500000000 32.233222961 -36.233222961 17.500000000 32.233222961 35.233222961 17.500000000 32.233222961 -36.233222961 18.500000000 32.233222961 35.233222961 18.500000000 32.233222961 -36.233222961 19.500000000 32.233222961 35.233222961 19.500000000 32.233222961 -36.233222961 20.500000000 32.233222961 35.233222961 20.500000000 32.233222961 -36.233222961 21.500000000 32.233222961 35.233222961 21.500000000 32.233222961 -36.233222961 22.500000000 32.233222961 35.233222961 22.500000000 32.233222961 -36.233222961 23.499998093 32.233222961 35.233222961 23.499998093 32.233222961 -36.233207703 24.499986649 32.233219147 35.233203888 24.499986649 32.233219147 -36.233070374 25.499872208 32.233165741 35.233070374 25.499874115 32.233165741 -36.232303619 26.499225616 32.232860565 35.232303619 26.499225616 32.232860565 -36.228954315 27.496377945 32.231597900 35.228954315 27.496377945 32.231597900 -36.217510223 28.486719131 32.227874756 35.217510223 28.486715317 32.227874756 -36.185966492 29.460592270 32.220714569 35.185962677 29.460596085 32.220710754 -36.112342834 30.405673981 32.216838837 35.112342834 30.405673981 32.216835022 -35.954723358 31.334241867 32.254276276 -35.670322418 31.736051559 32.678356171 34.670322418 31.736051559 32.678352356 34.954723358 31.334245682 32.254276276 -35.846313477 32.030693054 32.030693054 -35.498542786 32.424438477 32.424442291 34.498542786 32.424442291 32.424438477 34.846313477 32.030693054 32.030693054 -35.057430267 33.231868744 32.316951752 -34.565628052 33.565628052 32.672851562 33.565628052 33.565628052 32.672851562 34.057430267 33.231868744 32.316951752 -34.772159576 33.772159576 32.006500244 -34.231868744 34.057430267 32.316947937 -33.424438477 34.498538971 32.424442291 -32.736049652 34.670322418 32.678356171 31.736051559 34.670322418 32.678356171 32.424438477 34.498542786 32.424442291 33.231868744 34.057430267 32.316947937 33.772163391 33.772163391 32.006500244 -33.030693054 34.846313477 32.030693054 -32.334243774 34.954715729 32.254276276 -31.405673981 35.112346649 32.216838837 -30.460596085 35.185966492 32.220714569 -29.486719131 35.217510223 32.227870941 -28.496377945 35.228954315 32.231597900 -27.499221802 35.232299805 32.232860565 -26.499872208 35.233070374 32.233165741 -25.499986649 35.233207703 32.233215332 -24.499998093 35.233222961 32.233222961 -23.500000000 35.233222961 32.233222961 -22.500000000 35.233222961 32.233222961 -21.500000000 35.233222961 32.233222961 -20.500000000 35.233222961 32.233222961 -19.500000000 35.233222961 32.233222961 -18.500000000 35.233222961 32.233222961 -17.500000000 35.233222961 32.233222961 -16.500000000 35.233222961 32.233222961 -15.500000000 35.233222961 32.233222961 -14.500000000 35.233222961 32.233222961 -13.500000000 35.233222961 32.233222961 -12.500000000 35.233222961 32.233222961 -11.500000000 35.233222961 32.233222961 -10.500000000 35.233222961 32.233222961 -9.500000000 35.233222961 32.233222961 -8.500000000 35.233222961 32.233222961 -7.500000000 35.233222961 32.233222961 -6.500000000 35.233222961 32.233222961 -5.500000000 35.233222961 32.233222961 -4.500000000 35.233222961 32.233222961 -3.500000000 35.233222961 32.233222961 -2.500000000 35.233222961 32.233222961 -1.500000000 35.233222961 32.233222961 -0.500000000 35.233222961 32.233222961 0.500000000 35.233222961 32.233222961 1.500000000 35.233222961 32.233222961 2.500000000 35.233222961 32.233222961 3.500000000 35.233222961 32.233222961 4.500000000 35.233222961 32.233222961 5.500000000 35.233222961 32.233222961 6.500000000 35.233222961 32.233222961 7.500000000 35.233222961 32.233222961 8.500000000 35.233222961 32.233222961 9.500000000 35.233222961 32.233222961 10.500000000 35.233222961 32.233222961 11.500000000 35.233222961 32.233222961 12.500000000 35.233222961 32.233222961 13.500000000 35.233222961 32.233222961 14.500000000 35.233222961 32.233222961 15.500000000 35.233222961 32.233222961 16.500000000 35.233222961 32.233222961 17.500000000 35.233222961 32.233222961 18.500000000 35.233222961 32.233222961 19.500000000 35.233222961 32.233222961 20.500000000 35.233222961 32.233222961 21.500000000 35.233222961 32.233222961 22.500000000 35.233222961 32.233222961 23.499998093 35.233222961 32.233222961 24.499986649 35.233207703 32.233219147 25.499872208 35.233070374 32.233165741 26.499225616 35.232303619 32.232860565 27.496377945 35.228954315 32.231597900 28.486719131 35.217510223 32.227874756 29.460592270 35.185966492 32.220714569 30.405673981 35.112346649 32.216838837 31.334241867 34.954723358 32.254276276 32.030689240 34.846317291 32.030693054 -32.035343170 -35.797355652 32.840930939 -31.336603165 -35.879737854 32.903373718 -30.442844391 -35.937091827 32.946807861 -29.481937408 -35.965759277 32.968868256 -28.495168686 -35.976860046 32.977619171 -27.498952866 -35.980201721 32.980335236 -26.499826431 -35.980957031 32.980976105 -25.499975204 -35.981086731 32.981086731 -24.499998093 -35.981101990 32.981105804 -23.500000000 -35.981105804 32.981105804 -22.500000000 -35.981105804 32.981105804 -21.500000000 -35.981105804 32.981105804 -20.500000000 -35.981105804 32.981105804 -19.500000000 -35.981105804 32.981105804 -18.500000000 -35.981105804 32.981105804 -17.500000000 -35.981105804 32.981105804 -16.500000000 -35.981105804 32.981105804 -15.500000000 -35.981105804 32.981105804 -14.500000000 -35.981105804 32.981105804 -13.500000000 -35.981105804 32.981105804 -12.500000000 -35.981105804 32.981105804 -11.500000000 -35.981105804 32.981105804 -10.500000000 -35.981105804 32.981105804 -9.500000000 -35.981105804 32.981105804 -8.500000000 -35.981105804 32.981105804 -7.500000000 -35.981105804 32.981105804 -6.500000000 -35.981105804 32.981105804 -5.500000000 -35.981105804 32.981105804 -4.500000000 -35.981105804 32.981105804 -3.500000000 -35.981105804 32.981105804 -2.500000000 -35.981105804 32.981105804 -1.500000000 -35.981105804 32.981105804 -0.500000000 -35.981105804 32.981105804 0.500000000 -35.981105804 32.981105804 1.500000000 -35.981105804 32.981105804 2.500000000 -35.981105804 32.981105804 3.500000000 -35.981105804 32.981105804 4.500000000 -35.981105804 32.981105804 5.500000000 -35.981105804 32.981105804 6.500000000 -35.981105804 32.981105804 7.500000000 -35.981105804 32.981105804 8.500000000 -35.981105804 32.981105804 9.500000000 -35.981105804 32.981105804 10.500000000 -35.981105804 32.981105804 11.500000000 -35.981105804 32.981105804 12.500000000 -35.981105804 32.981105804 13.500000000 -35.981105804 32.981105804 14.500000000 -35.981105804 32.981105804 15.500000000 -35.981105804 32.981105804 16.500000000 -35.981105804 32.981105804 17.500000000 -35.981105804 32.981105804 18.500000000 -35.981105804 32.981105804 19.500000000 -35.981105804 32.981105804 20.500000000 -35.981105804 32.981105804 21.500000000 -35.981105804 32.981105804 22.500000000 -35.981105804 32.981105804 23.499998093 -35.981105804 32.981101990 24.499979019 -35.981086731 32.981090546 25.499826431 -35.980960846 32.980976105 26.498950958 -35.980201721 32.980335236 27.495168686 -35.976860046 32.977615356 28.481937408 -35.965759277 32.968864441 29.442840576 -35.937095642 32.946807861 30.336603165 -35.879737854 32.903373718 31.035345078 -35.797355652 32.840927124 -33.980762482 -34.842590332 32.980762482 -33.316951752 -35.057430267 33.231868744 -32.380741119 -35.428535461 33.260547638 -31.410833359 -35.518615723 33.477191925 -30.459177017 -35.577739716 33.567745209 -29.485630035 -35.607204437 33.604709625 -28.496026993 -35.618598938 33.617927551 -27.499156952 -35.621978760 33.621795654 -26.499868393 -35.622734070 33.622692108 -25.499986649 -35.622856140 33.622852325 -24.500000000 -35.622871399 33.622871399 -23.500000000 -35.622871399 33.622871399 -22.500000000 -35.622871399 33.622871399 -21.500000000 -35.622871399 33.622871399 -20.500000000 -35.622871399 33.622871399 -19.500000000 -35.622871399 33.622871399 -18.500000000 -35.622871399 33.622871399 -17.500000000 -35.622871399 33.622871399 -16.500000000 -35.622871399 33.622871399 -15.500000000 -35.622871399 33.622871399 -14.500000000 -35.622871399 33.622871399 -13.500000000 -35.622871399 33.622871399 -12.500000000 -35.622871399 33.622871399 -11.500000000 -35.622871399 33.622871399 -10.500000000 -35.622871399 33.622871399 -9.500000000 -35.622871399 33.622871399 -8.500000000 -35.622871399 33.622871399 -7.500000000 -35.622871399 33.622871399 -6.500000000 -35.622871399 33.622871399 -5.500000000 -35.622871399 33.622871399 -4.500000000 -35.622871399 33.622871399 -3.500000000 -35.622871399 33.622871399 -2.500000000 -35.622871399 33.622871399 -1.500000000 -35.622871399 33.622871399 -0.500000000 -35.622871399 33.622871399 0.500000000 -35.622871399 33.622871399 1.500000000 -35.622871399 33.622871399 2.500000000 -35.622871399 33.622871399 3.500000000 -35.622871399 33.622871399 4.500000000 -35.622871399 33.622871399 5.500000000 -35.622871399 33.622871399 6.500000000 -35.622871399 33.622871399 7.500000000 -35.622871399 33.622871399 8.500000000 -35.622871399 33.622871399 9.500000000 -35.622871399 33.622871399 10.500000000 -35.622871399 33.622871399 11.500000000 -35.622871399 33.622871399 12.500000000 -35.622871399 33.622871399 13.500000000 -35.622871399 33.622871399 14.500000000 -35.622871399 33.622871399 15.500000000 -35.622871399 33.622871399 16.500000000 -35.622871399 33.622871399 17.500000000 -35.622871399 33.622871399 18.500000000 -35.622871399 33.622871399 19.500000000 -35.622871399 33.622871399 20.500000000 -35.622871399 33.622871399 21.500000000 -35.622871399 33.622871399 22.500000000 -35.622871399 33.622871399 23.500000000 -35.622871399 33.622871399 24.499986649 -35.622856140 33.622852325 25.499868393 -35.622741699 33.622692108 26.499156952 -35.621986389 33.621795654 27.496026993 -35.618598938 33.617927551 28.485630035 -35.607208252 33.604709625 29.459178925 -35.577739716 33.567745209 30.410833359 -35.518615723 33.477184296 31.380737305 -35.428535461 33.260547638 32.316951752 -35.057430267 33.231868744 32.980762482 -34.842594147 32.980762482 -34.842590332 -33.980758667 32.980762482 -34.297924042 -34.297924042 33.297924042 -33.672851562 -34.565624237 33.565631866 32.672851562 -34.565628052 33.565631866 33.297924042 -34.297924042 33.297924042 33.842590332 -33.980762482 32.980758667 -35.057430267 -33.316947937 33.231872559 -34.565628052 -33.672847748 33.565631866 33.565628052 -33.672851562 33.565628052 34.057430267 -33.316947937 33.231868744 -35.797355652 -32.035343170 32.840934753 -35.428535461 -32.380737305 33.260543823 34.428535461 -32.380741119 33.260540009 34.797359467 -32.035343170 32.840927124 -35.879737854 -31.336603165 32.903373718 -35.518615723 -31.410833359 33.477191925 34.518615723 -31.410833359 33.477188110 34.879737854 -31.336603165 32.903373718 -35.937095642 -30.442844391 32.946807861 -35.577735901 -30.459178925 33.567745209 34.577739716 -30.459178925 33.567745209 34.937091827 -30.442844391 32.946807861 -35.965759277 -29.481937408 32.968864441 -35.607208252 -29.485630035 33.604705811 34.607204437 -29.485630035 33.604709625 34.965766907 -29.481937408 32.968864441 -35.976860046 -28.495168686 32.977611542 -35.618598938 -28.496026993 33.617927551 34.618598938 -28.496026993 33.617927551 34.976860046 -28.495168686 32.977615356 -35.980201721 -27.498950958 32.980331421 -35.621982574 -27.499156952 33.621795654 34.621982574 -27.499156952 33.621799469 34.980201721 -27.498952866 32.980331421 -35.980957031 -26.499826431 32.980968475 -35.622734070 -26.499868393 33.622692108 34.622734070 -26.499868393 33.622692108 34.980957031 -26.499826431 32.980976105 -35.981086731 -25.499979019 32.981086731 -35.622856140 -25.499986649 33.622844696 34.622856140 -25.499986649 33.622852325 34.981086731 -25.499975204 32.981090546 -35.981101990 -24.499998093 32.981101990 -35.622871399 -24.500000000 33.622871399 34.622871399 -24.500000000 33.622871399 34.981101990 -24.499998093 32.981101990 -35.981101990 -23.500000000 32.981101990 -35.622871399 -23.500000000 33.622871399 34.622871399 -23.500000000 33.622871399 34.981101990 -23.500000000 32.981101990 -35.981101990 -22.500000000 32.981101990 -35.622871399 -22.500000000 33.622871399 34.622871399 -22.500000000 33.622871399 34.981101990 -22.500000000 32.981101990 -35.981101990 -21.500000000 32.981101990 -35.622871399 -21.500000000 33.622871399 34.622871399 -21.500000000 33.622871399 34.981101990 -21.500000000 32.981101990 -35.981101990 -20.500000000 32.981101990 -35.622871399 -20.500000000 33.622871399 34.622871399 -20.500000000 33.622871399 34.981101990 -20.500000000 32.981101990 -35.981101990 -19.500000000 32.981101990 -35.622871399 -19.500000000 33.622871399 34.622871399 -19.500000000 33.622871399 34.981101990 -19.500000000 32.981101990 -35.981101990 -18.500000000 32.981101990 -35.622871399 -18.500000000 33.622871399 34.622871399 -18.500000000 33.622871399 34.981101990 -18.500000000 32.981101990 -35.981101990 -17.500000000 32.981101990 -35.622871399 -17.500000000 33.622871399 34.622871399 -17.500000000 33.622871399 34.981101990 -17.500000000 32.981101990 -35.981101990 -16.500000000 32.981101990 -35.622871399 -16.500000000 33.622871399 34.622871399 -16.500000000 33.622871399 34.981101990 -16.500000000 32.981101990 -35.981101990 -15.500000000 32.981101990 -35.622871399 -15.500000000 33.622871399 34.622871399 -15.500000000 33.622871399 34.981101990 -15.500000000 32.981101990 -35.981101990 -14.500000000 32.981101990 -35.622871399 -14.500000000 33.622871399 34.622871399 -14.500000000 33.622871399 34.981101990 -14.500000000 32.981101990 -35.981101990 -13.500000000 32.981101990 -35.622871399 -13.500000000 33.622871399 34.622871399 -13.500000000 33.622871399 34.981101990 -13.500000000 32.981101990 -35.981101990 -12.500000000 32.981101990 -35.622871399 -12.500000000 33.622871399 34.622871399 -12.500000000 33.622871399 34.981101990 -12.500000000 32.981101990 -35.981101990 -11.500000000 32.981101990 -35.622871399 -11.500000000 33.622871399 34.622871399 -11.500000000 33.622871399 34.981101990 -11.500000000 32.981101990 -35.981101990 -10.500000000 32.981101990 -35.622871399 -10.500000000 33.622871399 34.622871399 -10.500000000 33.622871399 34.981101990 -10.500000000 32.981101990 -35.981101990 -9.500000000 32.981101990 -35.622871399 -9.500000000 33.622871399 34.622871399 -9.500000000 33.622871399 34.981101990 -9.500000000 32.981101990 -35.981101990 -8.500000000 32.981101990 -35.622871399 -8.500000000 33.622871399 34.622871399 -8.500000000 33.622871399 34.981101990 -8.500000000 32.981101990 -35.981101990 -7.500000000 32.981101990 -35.622871399 -7.500000000 33.622871399 34.622871399 -7.500000000 33.622871399 34.981101990 -7.500000000 32.981101990 -35.981101990 -6.500000000 32.981101990 -35.622871399 -6.500000000 33.622871399 34.622871399 -6.500000000 33.622871399 34.981101990 -6.500000000 32.981101990 -35.981101990 -5.500000000 32.981101990 -35.622871399 -5.500000000 33.622871399 34.622871399 -5.500000000 33.622871399 34.981101990 -5.500000000 32.981101990 -35.981101990 -4.500000000 32.981101990 -35.622871399 -4.500000000 33.622871399 34.622871399 -4.500000000 33.622871399 34.981101990 -4.500000000 32.981101990 -35.981101990 -3.500000000 32.981101990 -35.622871399 -3.500000000 33.622871399 34.622871399 -3.500000000 33.622871399 34.981101990 -3.500000000 32.981101990 -35.981101990 -2.500000000 32.981101990 -35.622871399 -2.500000000 33.622871399 34.622871399 -2.500000000 33.622871399 34.981101990 -2.500000000 32.981101990 -35.981101990 -1.500000000 32.981101990 -35.622871399 -1.500000000 33.622871399 34.622871399 -1.500000000 33.622871399 34.981101990 -1.500000000 32.981101990 -35.981101990 -0.500000000 32.981101990 -35.622871399 -0.500000000 33.622871399 34.622871399 -0.500000000 33.622871399 34.981101990 -0.500000000 32.981101990 -35.981101990 0.500000000 32.981101990 -35.622871399 0.500000000 33.622871399 34.622871399 0.500000000 33.622871399 34.981101990 0.500000000 32.981101990 -35.981101990 1.500000000 32.981101990 -35.622871399 1.500000000 33.622871399 34.622871399 1.500000000 33.622871399 34.981101990 1.500000000 32.981101990 -35.981101990 2.500000000 32.981101990 -35.622871399 2.500000000 33.622871399 34.622871399 2.500000000 33.622871399 34.981101990 2.500000000 32.981101990 -35.981101990 3.500000000 32.981101990 -35.622871399 3.500000000 33.622871399 34.622871399 3.500000000 33.622871399 34.981101990 3.500000000 32.981101990 -35.981101990 4.500000000 32.981101990 -35.622871399 4.500000000 33.622871399 34.622871399 4.500000000 33.622871399 34.981101990 4.500000000 32.981101990 -35.981101990 5.500000000 32.981101990 -35.622871399 5.500000000 33.622871399 34.622871399 5.500000000 33.622871399 34.981101990 5.500000000 32.981101990 -35.981101990 6.500000000 32.981101990 -35.622871399 6.500000000 33.622871399 34.622871399 6.500000000 33.622871399 34.981101990 6.500000000 32.981101990 -35.981101990 7.500000000 32.981101990 -35.622871399 7.500000000 33.622871399 34.622871399 7.500000000 33.622871399 34.981101990 7.500000000 32.981101990 -35.981101990 8.500000000 32.981101990 -35.622871399 8.500000000 33.622871399 34.622871399 8.500000000 33.622871399 34.981101990 8.500000000 32.981101990 -35.981101990 9.500000000 32.981101990 -35.622871399 9.500000000 33.622871399 34.622871399 9.500000000 33.622871399 34.981101990 9.500000000 32.981101990 -35.981101990 10.500000000 32.981101990 -35.622871399 10.500000000 33.622871399 34.622871399 10.500000000 33.622871399 34.981101990 10.500000000 32.981101990 -35.981101990 11.500000000 32.981101990 -35.622871399 11.500000000 33.622871399 34.622871399 11.500000000 33.622871399 34.981101990 11.500000000 32.981101990 -35.981101990 12.500000000 32.981101990 -35.622871399 12.500000000 33.622871399 34.622871399 12.500000000 33.622871399 34.981101990 12.500000000 32.981101990 -35.981101990 13.500000000 32.981101990 -35.622871399 13.500000000 33.622871399 34.622871399 13.500000000 33.622871399 34.981101990 13.500000000 32.981101990 -35.981101990 14.500000000 32.981101990 -35.622871399 14.500000000 33.622871399 34.622871399 14.500000000 33.622871399 34.981101990 14.500000000 32.981101990 -35.981101990 15.500000000 32.981101990 -35.622871399 15.500000000 33.622871399 34.622871399 15.500000000 33.622871399 34.981101990 15.500000000 32.981101990 -35.981101990 16.500000000 32.981101990 -35.622871399 16.500000000 33.622871399 34.622871399 16.500000000 33.622871399 34.981101990 16.500000000 32.981101990 -35.981101990 17.500000000 32.981101990 -35.622871399 17.500000000 33.622871399 34.622871399 17.500000000 33.622871399 34.981101990 17.500000000 32.981101990 -35.981101990 18.500000000 32.981101990 -35.622871399 18.500000000 33.622871399 34.622871399 18.500000000 33.622871399 34.981101990 18.500000000 32.981101990 -35.981101990 19.500000000 32.981101990 -35.622871399 19.500000000 33.622871399 34.622871399 19.500000000 33.622871399 34.981101990 19.500000000 32.981101990 -35.981101990 20.500000000 32.981101990 -35.622871399 20.500000000 33.622871399 34.622871399 20.500000000 33.622871399 34.981101990 20.500000000 32.981101990 -35.981101990 21.500000000 32.981101990 -35.622871399 21.500000000 33.622871399 34.622871399 21.500000000 33.622871399 34.981101990 21.500000000 32.981101990 -35.981101990 22.500000000 32.981101990 -35.622871399 22.500000000 33.622871399 34.622871399 22.500000000 33.622871399 34.981101990 22.500000000 32.981101990 -35.981101990 23.499998093 32.981101990 -35.622871399 23.500000000 33.622871399 34.622871399 23.500000000 33.622871399 34.981101990 23.499998093 32.981101990 -35.981086731 24.499979019 32.981086731 -35.622856140 24.499986649 33.622844696 34.622856140 24.499986649 33.622852325 34.981086731 24.499979019 32.981090546 -35.980957031 25.499826431 32.980968475 -35.622734070 25.499868393 33.622692108 34.622734070 25.499868393 33.622692108 34.980957031 25.499826431 32.980976105 -35.980201721 26.498950958 32.980335236 -35.621978760 26.499156952 33.621799469 34.621978760 26.499156952 33.621799469 34.980201721 26.498950958 32.980335236 -35.976860046 27.495168686 32.977615356 -35.618598938 27.496026993 33.617927551 34.618598938 27.496026993 33.617927551 34.976860046 27.495168686 32.977615356 -35.965766907 28.481937408 32.968864441 -35.607208252 28.485630035 33.604705811 34.607208252 28.485630035 33.604705811 34.965759277 28.481937408 32.968864441 -35.937091827 29.442840576 32.946807861 -35.577739716 29.459178925 33.567749023 34.577739716 29.459178925 33.567745209 34.937091827 29.442840576 32.946807861 -35.879737854 30.336603165 32.903373718 -35.518615723 30.410833359 33.477191925 34.518619537 30.410833359 33.477184296 34.879737854 30.336603165 32.903377533 -35.797355652 31.035345078 32.840930939 -35.428535461 31.380737305 33.260547638 34.428535461 31.380737305 33.260547638 34.797355652 31.035345078 32.840927124 -35.057430267 32.316951752 33.231872559 -34.565628052 32.672847748 33.565631866 33.565628052 32.672847748 33.565628052 34.057430267 32.316951752 33.231868744 -34.842590332 32.980758667 32.980762482 -34.297924042 33.297924042 33.297924042 -33.672851562 33.565624237 33.565628052 32.672851562 33.565624237 33.565628052 33.297924042 33.297924042 33.297924042 33.842590332 32.980758667 32.980762482 -33.980758667 33.842590332 32.980762482 -33.316947937 34.057430267 33.231872559 -32.380737305 34.428535461 33.260543823 -31.410833359 34.518615723 33.477188110 -30.459178925 34.577739716 33.567745209 -29.485630035 34.607204437 33.604709625 -28.496026993 34.618602753 33.617927551 -27.499156952 34.621982574 33.621795654 -26.499868393 34.622737885 33.622692108 -25.499986649 34.622856140 33.622844696 -24.500000000 34.622871399 33.622871399 -23.500000000 34.622871399 33.622871399 -22.500000000 34.622871399 33.622871399 -21.500000000 34.622871399 33.622871399 -20.500000000 34.622871399 33.622871399 -19.500000000 34.622871399 33.622871399 -18.500000000 34.622871399 33.622871399 -17.500000000 34.622871399 33.622871399 -16.500000000 34.622871399 33.622871399 -15.500000000 34.622871399 33.622871399 -14.500000000 34.622871399 33.622871399 -13.500000000 34.622871399 33.622871399 -12.500000000 34.622871399 33.622871399 -11.500000000 34.622871399 33.622871399 -10.500000000 34.622871399 33.622871399 -9.500000000 34.622871399 33.622871399 -8.500000000 34.622871399 33.622871399 -7.500000000 34.622871399 33.622871399 -6.500000000 34.622871399 33.622871399 -5.500000000 34.622871399 33.622871399 -4.500000000 34.622871399 33.622871399 -3.500000000 34.622871399 33.622871399 -2.500000000 34.622871399 33.622871399 -1.500000000 34.622871399 33.622871399 -0.500000000 34.622871399 33.622871399 0.500000000 34.622871399 33.622871399 1.500000000 34.622871399 33.622871399 2.500000000 34.622871399 33.622871399 3.500000000 34.622871399 33.622871399 4.500000000 34.622871399 33.622871399 5.500000000 34.622871399 33.622871399 6.500000000 34.622871399 33.622871399 7.500000000 34.622871399 33.622871399 8.500000000 34.622871399 33.622871399 9.500000000 34.622871399 33.622871399 10.500000000 34.622871399 33.622871399 11.500000000 34.622871399 33.622871399 12.500000000 34.622871399 33.622871399 13.500000000 34.622871399 33.622871399 14.500000000 34.622871399 33.622871399 15.500000000 34.622871399 33.622871399 16.500000000 34.622871399 33.622871399 17.500000000 34.622871399 33.622871399 18.500000000 34.622871399 33.622871399 19.500000000 34.622871399 33.622871399 20.500000000 34.622871399 33.622871399 21.500000000 34.622871399 33.622871399 22.500000000 34.622871399 33.622871399 23.500000000 34.622871399 33.622871399 24.499986649 34.622856140 33.622844696 25.499868393 34.622734070 33.622692108 26.499156952 34.621978760 33.621799469 27.496026993 34.618598938 33.617927551 28.485630035 34.607208252 33.604705811 29.459178925 34.577739716 33.567749023 30.410833359 34.518615723 33.477191925 31.380737305 34.428535461 33.260547638 32.316947937 34.057430267 33.231872559 32.980758667 33.842590332 32.980762482 -32.035343170 34.797355652 32.840934753 -31.336603165 34.879737854 32.903373718 -30.442844391 34.937095642 32.946804047 -29.481937408 34.965759277 32.968864441 -28.495168686 34.976860046 32.977615356 -27.498950958 34.980201721 32.980331421 -26.499826431 34.980957031 32.980968475 -25.499979019 34.981086731 32.981086731 -24.499998093 34.981101990 32.981101990 -23.500000000 34.981101990 32.981101990 -22.500000000 34.981101990 32.981101990 -21.500000000 34.981101990 32.981101990 -20.500000000 34.981101990 32.981101990 -19.500000000 34.981101990 32.981101990 -18.500000000 34.981101990 32.981101990 -17.500000000 34.981101990 32.981101990 -16.500000000 34.981101990 32.981101990 -15.500000000 34.981101990 32.981101990 -14.500000000 34.981101990 32.981101990 -13.500000000 34.981101990 32.981101990 -12.500000000 34.981101990 32.981101990 -11.500000000 34.981101990 32.981101990 -10.500000000 34.981101990 32.981101990 -9.500000000 34.981101990 32.981101990 -8.500000000 34.981101990 32.981101990 -7.500000000 34.981101990 32.981101990 -6.500000000 34.981101990 32.981101990 -5.500000000 34.981101990 32.981101990 -4.500000000 34.981101990 32.981101990 -3.500000000 34.981101990 32.981101990 -2.500000000 34.981101990 32.981101990 -1.500000000 34.981101990 32.981101990 -0.500000000 34.981101990 32.981101990 0.500000000 34.981101990 32.981101990 1.500000000 34.981101990 32.981101990 2.500000000 34.981101990 32.981101990 3.500000000 34.981101990 32.981101990 4.500000000 34.981101990 32.981101990 5.500000000 34.981101990 32.981101990 6.500000000 34.981101990 32.981101990 7.500000000 34.981101990 32.981101990 8.500000000 34.981101990 32.981101990 9.500000000 34.981101990 32.981101990 10.500000000 34.981101990 32.981101990 11.500000000 34.981101990 32.981101990 12.500000000 34.981101990 32.981101990 13.500000000 34.981101990 32.981101990 14.500000000 34.981101990 32.981101990 15.500000000 34.981101990 32.981101990 16.500000000 34.981101990 32.981101990 17.500000000 34.981101990 32.981101990 18.500000000 34.981101990 32.981101990 19.500000000 34.981101990 32.981101990 20.500000000 34.981101990 32.981101990 21.500000000 34.981101990 32.981101990 22.500000000 34.981101990 32.981101990 23.499998093 34.981101990 32.981101990 24.499979019 34.981086731 32.981086731 25.499826431 34.980957031 32.980968475 26.498950958 34.980201721 32.980335236 27.495168686 34.976860046 32.977615356 28.481937408 34.965766907 32.968864441 29.442840576 34.937091827 32.946807861 30.336603165 34.879737854 32.903373718 31.035345078 34.797359467 32.840934753 -33.006500244 -34.772159576 33.772163391 -32.313602448 -34.912063599 33.912063599 -31.413049698 -35.040893555 34.040893555 -30.463253021 -35.115642548 34.115642548 -29.487289429 -35.150253296 34.150257111 -28.496557236 -35.163162231 34.163158417 -27.499298096 -35.166961670 34.166954041 -26.499902725 -35.167808533 34.167808533 -25.499990463 -35.167949677 34.167949677 -24.500000000 -35.167968750 34.167968750 -23.500000000 -35.167968750 34.167968750 -22.500000000 -35.167968750 34.167968750 -21.500000000 -35.167968750 34.167968750 -20.500000000 -35.167968750 34.167968750 -19.500000000 -35.167968750 34.167968750 -18.500000000 -35.167968750 34.167968750 -17.500000000 -35.167968750 34.167968750 -16.500000000 -35.167968750 34.167968750 -15.500000000 -35.167968750 34.167968750 -14.500000000 -35.167968750 34.167968750 -13.500000000 -35.167968750 34.167968750 -12.500000000 -35.167968750 34.167968750 -11.500000000 -35.167968750 34.167968750 -10.500000000 -35.167968750 34.167968750 -9.500000000 -35.167968750 34.167968750 -8.500000000 -35.167968750 34.167968750 -7.500000000 -35.167968750 34.167968750 -6.500000000 -35.167968750 34.167968750 -5.500000000 -35.167968750 34.167968750 -4.500000000 -35.167968750 34.167968750 -3.500000000 -35.167968750 34.167968750 -2.500000000 -35.167968750 34.167968750 -1.500000000 -35.167968750 34.167968750 -0.500000000 -35.167968750 34.167968750 0.500000000 -35.167968750 34.167968750 1.500000000 -35.167968750 34.167968750 2.500000000 -35.167968750 34.167968750 3.500000000 -35.167968750 34.167968750 4.500000000 -35.167968750 34.167968750 5.500000000 -35.167968750 34.167968750 6.500000000 -35.167968750 34.167968750 7.500000000 -35.167968750 34.167968750 8.500000000 -35.167968750 34.167968750 9.500000000 -35.167968750 34.167968750 10.500000000 -35.167968750 34.167968750 11.500000000 -35.167968750 34.167968750 12.500000000 -35.167968750 34.167968750 13.500000000 -35.167968750 34.167968750 14.500000000 -35.167968750 34.167968750 15.500000000 -35.167968750 34.167968750 16.500000000 -35.167968750 34.167968750 17.500000000 -35.167968750 34.167968750 18.500000000 -35.167968750 34.167968750 19.500000000 -35.167968750 34.167968750 20.500000000 -35.167968750 34.167968750 21.500000000 -35.167968750 34.167968750 22.500000000 -35.167968750 34.167968750 23.500000000 -35.167968750 34.167968750 24.499994278 -35.167949677 34.167949677 25.499898911 -35.167804718 34.167808533 26.499298096 -35.166954041 34.166954041 27.496557236 -35.163154602 34.163158417 28.487289429 -35.150249481 34.150249481 29.463253021 -35.115642548 34.115642548 30.413049698 -35.040893555 34.040893555 31.313602448 -34.912059784 33.912063599 32.006500244 -34.772159576 33.772163391 -33.980758667 -33.980758667 33.842590332 -33.316947937 -34.231868744 34.057434082 -32.380737305 -34.260547638 34.428531647 -31.410831451 -34.477184296 34.518615723 -30.459177017 -34.567749023 34.577739716 -29.485630035 -34.604709625 34.607204437 -28.496026993 -34.617927551 34.618598938 -27.499160767 -34.621795654 34.621982574 -26.499868393 -34.622692108 34.622734070 -25.499986649 -34.622844696 34.622856140 -24.500000000 -34.622871399 34.622871399 -23.500000000 -34.622871399 34.622871399 -22.500000000 -34.622871399 34.622871399 -21.500000000 -34.622871399 34.622871399 -20.500000000 -34.622871399 34.622871399 -19.500000000 -34.622871399 34.622871399 -18.500000000 -34.622871399 34.622871399 -17.500000000 -34.622871399 34.622871399 -16.500000000 -34.622871399 34.622871399 -15.500000000 -34.622871399 34.622871399 -14.500000000 -34.622871399 34.622871399 -13.500000000 -34.622871399 34.622871399 -12.500000000 -34.622871399 34.622871399 -11.500000000 -34.622871399 34.622871399 -10.500000000 -34.622871399 34.622871399 -9.500000000 -34.622871399 34.622871399 -8.500000000 -34.622871399 34.622871399 -7.500000000 -34.622871399 34.622871399 -6.500000000 -34.622871399 34.622871399 -5.500000000 -34.622871399 34.622871399 -4.500000000 -34.622871399 34.622871399 -3.500000000 -34.622871399 34.622871399 -2.500000000 -34.622871399 34.622871399 -1.500000000 -34.622871399 34.622871399 -0.500000000 -34.622871399 34.622871399 0.500000000 -34.622871399 34.622871399 1.500000000 -34.622871399 34.622871399 2.500000000 -34.622871399 34.622871399 3.500000000 -34.622871399 34.622871399 4.500000000 -34.622871399 34.622871399 5.500000000 -34.622871399 34.622871399 6.500000000 -34.622871399 34.622871399 7.500000000 -34.622871399 34.622871399 8.500000000 -34.622871399 34.622871399 9.500000000 -34.622871399 34.622871399 10.500000000 -34.622871399 34.622871399 11.500000000 -34.622871399 34.622871399 12.500000000 -34.622871399 34.622871399 13.500000000 -34.622871399 34.622871399 14.500000000 -34.622871399 34.622871399 15.500000000 -34.622871399 34.622871399 16.500000000 -34.622871399 34.622871399 17.500000000 -34.622871399 34.622871399 18.500000000 -34.622871399 34.622871399 19.500000000 -34.622871399 34.622871399 20.500000000 -34.622871399 34.622871399 21.500000000 -34.622871399 34.622871399 22.500000000 -34.622871399 34.622871399 23.500000000 -34.622871399 34.622871399 24.499986649 -34.622844696 34.622856140 25.499868393 -34.622692108 34.622734070 26.499156952 -34.621795654 34.621978760 27.496026993 -34.617927551 34.618598938 28.485631943 -34.604705811 34.607204437 29.459178925 -34.567741394 34.577739716 30.410831451 -34.477191925 34.518615723 31.380739212 -34.260543823 34.428535461 32.316947937 -34.231868744 34.057430267 32.980758667 -33.980758667 33.842590332 -34.772159576 -33.006500244 33.772163391 -34.231868744 -33.316947937 34.057434082 -33.424438477 -33.424438477 34.498546600 -32.736049652 -33.678352356 34.670326233 31.736051559 -33.678352356 34.670322418 32.424438477 -33.424442291 34.498542786 33.231868744 -33.316947937 34.057430267 33.772159576 -33.006500244 33.772155762 -34.912063599 -32.313598633 33.912063599 -34.260547638 -32.380737305 34.428535461 -33.678352356 -32.736053467 34.670326233 32.678352356 -32.736053467 34.670322418 33.260543823 -32.380741119 34.428531647 33.912059784 -32.313602448 33.912059784 -35.040893555 -31.413049698 34.040893555 -34.477191925 -31.410831451 34.518615723 33.477191925 -31.410831451 34.518611908 34.040893555 -31.413049698 34.040893555 -35.115642548 -30.463253021 34.115642548 -34.567745209 -30.459178925 34.577739716 33.567745209 -30.459178925 34.577739716 34.115642548 -30.463253021 34.115638733 -35.150253296 -29.487289429 34.150249481 -34.604709625 -29.485630035 34.607204437 33.604709625 -29.485630035 34.607208252 34.150253296 -29.487293243 34.150257111 -35.163154602 -28.496557236 34.163158417 -34.617927551 -28.496026993 34.618598938 33.617927551 -28.496026993 34.618598938 34.163154602 -28.496557236 34.163158417 -35.166954041 -27.499298096 34.166954041 -34.621795654 -27.499156952 34.621982574 33.621795654 -27.499156952 34.621982574 34.166957855 -27.499298096 34.166961670 -35.167808533 -26.499898911 34.167808533 -34.622692108 -26.499868393 34.622734070 33.622692108 -26.499868393 34.622734070 34.167808533 -26.499902725 34.167808533 -35.167949677 -25.499990463 34.167949677 -34.622844696 -25.499986649 34.622856140 33.622844696 -25.499986649 34.622852325 34.167949677 -25.499990463 34.167945862 -35.167961121 -24.500000000 34.167961121 -34.622863770 -24.500000000 34.622871399 33.622871399 -24.500000000 34.622871399 34.167968750 -24.500000000 34.167968750 -35.167961121 -23.500000000 34.167961121 -34.622871399 -23.500000000 34.622871399 33.622871399 -23.500000000 34.622871399 34.167968750 -23.500000000 34.167968750 -35.167961121 -22.500000000 34.167961121 -34.622871399 -22.500000000 34.622871399 33.622871399 -22.500000000 34.622871399 34.167968750 -22.500000000 34.167968750 -35.167961121 -21.500000000 34.167961121 -34.622871399 -21.500000000 34.622871399 33.622871399 -21.500000000 34.622871399 34.167968750 -21.500000000 34.167968750 -35.167961121 -20.500000000 34.167961121 -34.622871399 -20.500000000 34.622871399 33.622871399 -20.500000000 34.622871399 34.167968750 -20.500000000 34.167968750 -35.167961121 -19.500000000 34.167961121 -34.622871399 -19.500000000 34.622871399 33.622871399 -19.500000000 34.622871399 34.167968750 -19.500000000 34.167968750 -35.167961121 -18.500000000 34.167961121 -34.622871399 -18.500000000 34.622871399 33.622871399 -18.500000000 34.622871399 34.167968750 -18.500000000 34.167968750 -35.167961121 -17.500000000 34.167961121 -34.622871399 -17.500000000 34.622871399 33.622871399 -17.500000000 34.622871399 34.167968750 -17.500000000 34.167968750 -35.167961121 -16.500000000 34.167961121 -34.622871399 -16.500000000 34.622871399 33.622871399 -16.500000000 34.622871399 34.167968750 -16.500000000 34.167968750 -35.167961121 -15.500000000 34.167961121 -34.622871399 -15.500000000 34.622871399 33.622871399 -15.500000000 34.622871399 34.167968750 -15.500000000 34.167968750 -35.167961121 -14.500000000 34.167961121 -34.622871399 -14.500000000 34.622871399 33.622871399 -14.500000000 34.622871399 34.167968750 -14.500000000 34.167968750 -35.167961121 -13.500000000 34.167961121 -34.622871399 -13.500000000 34.622871399 33.622871399 -13.500000000 34.622871399 34.167968750 -13.500000000 34.167968750 -35.167961121 -12.500000000 34.167961121 -34.622871399 -12.500000000 34.622871399 33.622871399 -12.500000000 34.622871399 34.167968750 -12.500000000 34.167968750 -35.167961121 -11.500000000 34.167961121 -34.622871399 -11.500000000 34.622871399 33.622871399 -11.500000000 34.622871399 34.167968750 -11.500000000 34.167968750 -35.167961121 -10.500000000 34.167961121 -34.622871399 -10.500000000 34.622871399 33.622871399 -10.500000000 34.622871399 34.167968750 -10.500000000 34.167968750 -35.167961121 -9.500000000 34.167961121 -34.622871399 -9.500000000 34.622871399 33.622871399 -9.500000000 34.622871399 34.167968750 -9.500000000 34.167968750 -35.167961121 -8.500000000 34.167961121 -34.622871399 -8.500000000 34.622871399 33.622871399 -8.500000000 34.622871399 34.167968750 -8.500000000 34.167968750 -35.167961121 -7.500000000 34.167961121 -34.622871399 -7.500000000 34.622871399 33.622871399 -7.500000000 34.622871399 34.167968750 -7.500000000 34.167968750 -35.167961121 -6.500000000 34.167961121 -34.622871399 -6.500000000 34.622871399 33.622871399 -6.500000000 34.622871399 34.167968750 -6.500000000 34.167968750 -35.167961121 -5.500000000 34.167961121 -34.622871399 -5.500000000 34.622871399 33.622871399 -5.500000000 34.622871399 34.167968750 -5.500000000 34.167968750 -35.167961121 -4.500000000 34.167961121 -34.622871399 -4.500000000 34.622871399 33.622871399 -4.500000000 34.622871399 34.167968750 -4.500000000 34.167968750 -35.167961121 -3.500000000 34.167961121 -34.622871399 -3.500000000 34.622871399 33.622871399 -3.500000000 34.622871399 34.167968750 -3.500000000 34.167968750 -35.167961121 -2.500000000 34.167961121 -34.622871399 -2.500000000 34.622871399 33.622871399 -2.500000000 34.622871399 34.167968750 -2.500000000 34.167968750 -35.167961121 -1.500000000 34.167961121 -34.622871399 -1.500000000 34.622871399 33.622871399 -1.500000000 34.622871399 34.167968750 -1.500000000 34.167968750 -35.167961121 -0.500000000 34.167961121 -34.622871399 -0.500000000 34.622871399 33.622871399 -0.500000000 34.622871399 34.167968750 -0.500000000 34.167968750 -35.167961121 0.500000000 34.167961121 -34.622871399 0.500000000 34.622871399 33.622871399 0.500000000 34.622871399 34.167968750 0.500000000 34.167968750 -35.167961121 1.500000000 34.167961121 -34.622871399 1.500000000 34.622871399 33.622871399 1.500000000 34.622871399 34.167968750 1.500000000 34.167968750 -35.167961121 2.500000000 34.167961121 -34.622871399 2.500000000 34.622871399 33.622871399 2.500000000 34.622871399 34.167968750 2.500000000 34.167968750 -35.167961121 3.500000000 34.167961121 -34.622871399 3.500000000 34.622871399 33.622871399 3.500000000 34.622871399 34.167968750 3.500000000 34.167968750 -35.167961121 4.500000000 34.167961121 -34.622871399 4.500000000 34.622871399 33.622871399 4.500000000 34.622871399 34.167968750 4.500000000 34.167968750 -35.167961121 5.500000000 34.167961121 -34.622871399 5.500000000 34.622871399 33.622871399 5.500000000 34.622871399 34.167968750 5.500000000 34.167968750 -35.167961121 6.500000000 34.167961121 -34.622871399 6.500000000 34.622871399 33.622871399 6.500000000 34.622871399 34.167968750 6.500000000 34.167968750 -35.167961121 7.500000000 34.167961121 -34.622871399 7.500000000 34.622871399 33.622871399 7.500000000 34.622871399 34.167968750 7.500000000 34.167968750 -35.167961121 8.500000000 34.167961121 -34.622871399 8.500000000 34.622871399 33.622871399 8.500000000 34.622871399 34.167968750 8.500000000 34.167968750 -35.167961121 9.500000000 34.167961121 -34.622871399 9.500000000 34.622871399 33.622871399 9.500000000 34.622871399 34.167968750 9.500000000 34.167968750 -35.167961121 10.500000000 34.167961121 -34.622871399 10.500000000 34.622871399 33.622871399 10.500000000 34.622871399 34.167968750 10.500000000 34.167968750 -35.167961121 11.500000000 34.167961121 -34.622871399 11.500000000 34.622871399 33.622871399 11.500000000 34.622871399 34.167968750 11.500000000 34.167968750 -35.167961121 12.500000000 34.167961121 -34.622871399 12.500000000 34.622871399 33.622871399 12.500000000 34.622871399 34.167968750 12.500000000 34.167968750 -35.167961121 13.500000000 34.167961121 -34.622871399 13.500000000 34.622871399 33.622871399 13.500000000 34.622871399 34.167968750 13.500000000 34.167968750 -35.167961121 14.500000000 34.167961121 -34.622871399 14.500000000 34.622871399 33.622871399 14.500000000 34.622871399 34.167968750 14.500000000 34.167968750 -35.167961121 15.500000000 34.167961121 -34.622871399 15.500000000 34.622871399 33.622871399 15.500000000 34.622871399 34.167968750 15.500000000 34.167968750 -35.167961121 16.500000000 34.167961121 -34.622871399 16.500000000 34.622871399 33.622871399 16.500000000 34.622871399 34.167968750 16.500000000 34.167968750 -35.167961121 17.500000000 34.167961121 -34.622871399 17.500000000 34.622871399 33.622871399 17.500000000 34.622871399 34.167968750 17.500000000 34.167968750 -35.167961121 18.500000000 34.167961121 -34.622871399 18.500000000 34.622871399 33.622871399 18.500000000 34.622871399 34.167968750 18.500000000 34.167968750 -35.167961121 19.500000000 34.167961121 -34.622871399 19.500000000 34.622871399 33.622871399 19.500000000 34.622871399 34.167968750 19.500000000 34.167968750 -35.167961121 20.500000000 34.167961121 -34.622871399 20.500000000 34.622871399 33.622871399 20.500000000 34.622871399 34.167968750 20.500000000 34.167968750 -35.167961121 21.500000000 34.167961121 -34.622871399 21.500000000 34.622871399 33.622871399 21.500000000 34.622871399 34.167968750 21.500000000 34.167968750 -35.167961121 22.500000000 34.167961121 -34.622871399 22.500000000 34.622871399 33.622871399 22.500000000 34.622871399 34.167968750 22.500000000 34.167968750 -35.167961121 23.500000000 34.167961121 -34.622867584 23.500000000 34.622867584 33.622867584 23.500000000 34.622867584 34.167968750 23.500000000 34.167968750 -35.167949677 24.499994278 34.167949677 -34.622844696 24.499988556 34.622856140 33.622844696 24.499988556 34.622856140 34.167949677 24.499994278 34.167949677 -35.167804718 25.499900818 34.167808533 -34.622692108 25.499868393 34.622734070 33.622692108 25.499868393 34.622734070 34.167804718 25.499900818 34.167808533 -35.166954041 26.499298096 34.166961670 -34.621799469 26.499156952 34.621982574 33.621799469 26.499160767 34.621982574 34.166954041 26.499298096 34.166954041 -35.163158417 27.496557236 34.163154602 -34.617927551 27.496026993 34.618598938 33.617927551 27.496026993 34.618598938 34.163158417 27.496557236 34.163158417 -35.150249481 28.487293243 34.150249481 -34.604705811 28.485630035 34.607204437 33.604705811 28.485631943 34.607204437 34.150249481 28.487289429 34.150249481 -35.115642548 29.463253021 34.115638733 -34.567741394 29.459178925 34.577739716 33.567741394 29.459178925 34.577739716 34.115638733 29.463256836 34.115642548 -35.040893555 30.413049698 34.040893555 -34.477191925 30.410831451 34.518619537 33.477191925 30.410833359 34.518615723 34.040893555 30.413049698 34.040893555 -34.912063599 31.313602448 33.912063599 -34.260543823 31.380737305 34.428535461 -33.678352356 31.736051559 34.670322418 32.678352356 31.736051559 34.670322418 33.260543823 31.380739212 34.428535461 33.912059784 31.313604355 33.912059784 -34.772159576 32.006500244 33.772163391 -34.231868744 32.316947937 34.057430267 -33.424438477 32.424438477 34.498542786 -32.736053467 32.678352356 34.670322418 31.736051559 32.678352356 34.670322418 32.424438477 32.424434662 34.498542786 33.231868744 32.316951752 34.057430267 33.772159576 32.006500244 33.772159576 -33.980758667 32.980758667 33.842590332 -33.316947937 33.231868744 34.057430267 -32.380737305 33.260543823 34.428539276 -31.410833359 33.477191925 34.518619537 -30.459178925 33.567745209 34.577747345 -29.485630035 33.604709625 34.607208252 -28.496026993 33.617927551 34.618598938 -27.499156952 33.621795654 34.621982574 -26.499868393 33.622692108 34.622734070 -25.499986649 33.622844696 34.622856140 -24.500000000 33.622871399 34.622871399 -23.500000000 33.622871399 34.622871399 -22.500000000 33.622871399 34.622871399 -21.500000000 33.622871399 34.622871399 -20.500000000 33.622871399 34.622871399 -19.500000000 33.622871399 34.622871399 -18.500000000 33.622871399 34.622871399 -17.500000000 33.622871399 34.622871399 -16.500000000 33.622871399 34.622871399 -15.500000000 33.622871399 34.622871399 -14.500000000 33.622871399 34.622871399 -13.500000000 33.622871399 34.622871399 -12.500000000 33.622871399 34.622871399 -11.500000000 33.622871399 34.622871399 -10.500000000 33.622871399 34.622871399 -9.500000000 33.622871399 34.622871399 -8.500000000 33.622871399 34.622871399 -7.500000000 33.622871399 34.622871399 -6.500000000 33.622871399 34.622871399 -5.500000000 33.622871399 34.622871399 -4.500000000 33.622871399 34.622871399 -3.500000000 33.622871399 34.622871399 -2.500000000 33.622871399 34.622871399 -1.500000000 33.622871399 34.622871399 -0.500000000 33.622871399 34.622871399 0.500000000 33.622871399 34.622871399 1.500000000 33.622871399 34.622871399 2.500000000 33.622871399 34.622871399 3.500000000 33.622871399 34.622871399 4.500000000 33.622871399 34.622871399 5.500000000 33.622871399 34.622871399 6.500000000 33.622871399 34.622871399 7.500000000 33.622871399 34.622871399 8.500000000 33.622871399 34.622871399 9.500000000 33.622871399 34.622871399 10.500000000 33.622871399 34.622871399 11.500000000 33.622871399 34.622871399 12.500000000 33.622871399 34.622871399 13.500000000 33.622871399 34.622871399 14.500000000 33.622871399 34.622871399 15.500000000 33.622871399 34.622871399 16.500000000 33.622871399 34.622871399 17.500000000 33.622871399 34.622871399 18.500000000 33.622871399 34.622871399 19.500000000 33.622871399 34.622871399 20.500000000 33.622871399 34.622871399 21.500000000 33.622871399 34.622871399 22.500000000 33.622871399 34.622871399 23.500000000 33.622867584 34.622867584 24.499988556 33.622844696 34.622856140 25.499868393 33.622692108 34.622734070 26.499160767 33.621799469 34.621982574 27.496026993 33.617927551 34.618598938 28.485631943 33.604705811 34.607204437 29.459178925 33.567749023 34.577739716 30.410833359 33.477184296 34.518615723 31.380737305 33.260543823 34.428535461 32.316947937 33.231868744 34.057430267 32.980758667 32.980758667 33.842590332 -33.006500244 33.772159576 33.772163391 -32.313598633 33.912063599 33.912063599 -31.413049698 34.040893555 34.040893555 -30.463253021 34.115642548 34.115638733 -29.487289429 34.150253296 34.150249481 -28.496557236 34.163162231 34.163158417 -27.499298096 34.166961670 34.166961670 -26.499898911 34.167808533 34.167808533 -25.499990463 34.167949677 34.167949677 -24.500000000 34.167961121 34.167961121 -23.500000000 34.167961121 34.167961121 -22.500000000 34.167961121 34.167961121 -21.500000000 34.167961121 34.167961121 -20.500000000 34.167961121 34.167961121 -19.500000000 34.167961121 34.167961121 -18.500000000 34.167961121 34.167961121 -17.500000000 34.167961121 34.167961121 -16.500000000 34.167961121 34.167961121 -15.500000000 34.167961121 34.167961121 -14.500000000 34.167961121 34.167961121 -13.500000000 34.167961121 34.167961121 -12.500000000 34.167961121 34.167961121 -11.500000000 34.167961121 34.167961121 -10.500000000 34.167961121 34.167961121 -9.500000000 34.167961121 34.167961121 -8.500000000 34.167961121 34.167961121 -7.500000000 34.167961121 34.167961121 -6.500000000 34.167961121 34.167961121 -5.500000000 34.167961121 34.167961121 -4.500000000 34.167961121 34.167961121 -3.500000000 34.167961121 34.167961121 -2.500000000 34.167961121 34.167961121 -1.500000000 34.167961121 34.167961121 -0.500000000 34.167961121 34.167961121 0.500000000 34.167961121 34.167961121 1.500000000 34.167961121 34.167961121 2.500000000 34.167961121 34.167961121 3.500000000 34.167961121 34.167961121 4.500000000 34.167961121 34.167961121 5.500000000 34.167961121 34.167961121 6.500000000 34.167961121 34.167961121 7.500000000 34.167961121 34.167961121 8.500000000 34.167961121 34.167961121 9.500000000 34.167961121 34.167961121 10.500000000 34.167961121 34.167961121 11.500000000 34.167961121 34.167961121 12.500000000 34.167961121 34.167961121 13.500000000 34.167961121 34.167961121 14.500000000 34.167961121 34.167961121 15.500000000 34.167961121 34.167961121 16.500000000 34.167961121 34.167961121 17.500000000 34.167961121 34.167961121 18.500000000 34.167961121 34.167961121 19.500000000 34.167961121 34.167961121 20.500000000 34.167961121 34.167961121 21.500000000 34.167961121 34.167961121 22.500000000 34.167961121 34.167961121 23.500000000 34.167961121 34.167961121 24.499994278 34.167949677 34.167949677 25.499900818 34.167804718 34.167808533 26.499298096 34.166954041 34.166961670 27.496557236 34.163158417 34.163154602 28.487293243 34.150249481 34.150249481 29.463253021 34.115642548 34.115638733 30.413049698 34.040893555 34.040893555 31.313604355 33.912059784 33.912063599 32.006500244 33.772159576 33.772163391 -32.035343170 -33.840930939 34.797355652 -31.336603165 -33.903373718 34.879734039 -30.442840576 -33.946807861 34.937091827 -29.481933594 -33.968864441 34.965763092 -28.495172501 -33.977615356 34.976860046 -27.498952866 -33.980331421 34.980201721 -26.499826431 -33.980972290 34.980957031 -25.499977112 -33.981090546 34.981086731 -24.499998093 -33.981101990 34.981101990 -23.500000000 -33.981101990 34.981101990 -22.500000000 -33.981101990 34.981101990 -21.500000000 -33.981101990 34.981101990 -20.500000000 -33.981101990 34.981101990 -19.500000000 -33.981101990 34.981101990 -18.500000000 -33.981101990 34.981101990 -17.500000000 -33.981101990 34.981101990 -16.500000000 -33.981101990 34.981101990 -15.500000000 -33.981101990 34.981101990 -14.500000000 -33.981101990 34.981101990 -13.500000000 -33.981101990 34.981101990 -12.500000000 -33.981101990 34.981101990 -11.500000000 -33.981101990 34.981101990 -10.500000000 -33.981101990 34.981101990 -9.500000000 -33.981101990 34.981101990 -8.500000000 -33.981101990 34.981101990 -7.500000000 -33.981101990 34.981101990 -6.500000000 -33.981101990 34.981101990 -5.500000000 -33.981101990 34.981101990 -4.500000000 -33.981101990 34.981101990 -3.500000000 -33.981101990 34.981101990 -2.500000000 -33.981101990 34.981101990 -1.500000000 -33.981101990 34.981101990 -0.500000000 -33.981101990 34.981101990 0.500000000 -33.981101990 34.981101990 1.500000000 -33.981101990 34.981101990 2.500000000 -33.981101990 34.981101990 3.500000000 -33.981101990 34.981101990 4.500000000 -33.981101990 34.981101990 5.500000000 -33.981101990 34.981101990 6.500000000 -33.981101990 34.981101990 7.500000000 -33.981101990 34.981101990 8.500000000 -33.981101990 34.981101990 9.500000000 -33.981101990 34.981101990 10.500000000 -33.981101990 34.981101990 11.500000000 -33.981101990 34.981101990 12.500000000 -33.981101990 34.981101990 13.500000000 -33.981101990 34.981101990 14.500000000 -33.981101990 34.981101990 15.500000000 -33.981101990 34.981101990 16.500000000 -33.981101990 34.981101990 17.500000000 -33.981101990 34.981101990 18.500000000 -33.981101990 34.981101990 19.500000000 -33.981101990 34.981101990 20.500000000 -33.981101990 34.981101990 21.500000000 -33.981101990 34.981101990 22.500000000 -33.981101990 34.981101990 23.499998093 -33.981101990 34.981101990 24.499979019 -33.981090546 34.981086731 25.499826431 -33.980972290 34.980957031 26.498950958 -33.980331421 34.980201721 27.495172501 -33.977611542 34.976860046 28.481937408 -33.968864441 34.965763092 29.442840576 -33.946807861 34.937091827 30.336599350 -33.903373718 34.879737854 31.035345078 -33.840927124 34.797355652 -33.030689240 -33.030693054 34.846317291 -32.334243774 -33.254272461 34.954723358 -31.405673981 -33.216838837 35.112342834 -30.460596085 -33.220710754 35.185966492 -29.486719131 -33.227874756 35.217510223 -28.496377945 -33.231601715 35.228954315 -27.499221802 -33.232868195 35.232299805 -26.499872208 -33.233169556 35.233074188 -25.499986649 -33.233219147 35.233207703 -24.499998093 -33.233222961 35.233222961 -23.500000000 -33.233222961 35.233222961 -22.500000000 -33.233222961 35.233222961 -21.500000000 -33.233222961 35.233222961 -20.500000000 -33.233222961 35.233222961 -19.500000000 -33.233222961 35.233222961 -18.500000000 -33.233222961 35.233222961 -17.500000000 -33.233222961 35.233222961 -16.500000000 -33.233222961 35.233222961 -15.500000000 -33.233222961 35.233222961 -14.500000000 -33.233222961 35.233222961 -13.500000000 -33.233222961 35.233222961 -12.500000000 -33.233222961 35.233222961 -11.500000000 -33.233222961 35.233222961 -10.500000000 -33.233222961 35.233222961 -9.500000000 -33.233222961 35.233222961 -8.500000000 -33.233222961 35.233222961 -7.500000000 -33.233222961 35.233222961 -6.500000000 -33.233222961 35.233222961 -5.500000000 -33.233222961 35.233222961 -4.500000000 -33.233222961 35.233222961 -3.500000000 -33.233222961 35.233222961 -2.500000000 -33.233222961 35.233222961 -1.500000000 -33.233222961 35.233222961 -0.500000000 -33.233222961 35.233222961 0.500000000 -33.233222961 35.233222961 1.500000000 -33.233222961 35.233222961 2.500000000 -33.233222961 35.233222961 3.500000000 -33.233222961 35.233222961 4.500000000 -33.233222961 35.233222961 5.500000000 -33.233222961 35.233222961 6.500000000 -33.233222961 35.233222961 7.500000000 -33.233222961 35.233222961 8.500000000 -33.233222961 35.233222961 9.500000000 -33.233222961 35.233222961 10.500000000 -33.233222961 35.233222961 11.500000000 -33.233222961 35.233222961 12.500000000 -33.233222961 35.233222961 13.500000000 -33.233222961 35.233222961 14.500000000 -33.233222961 35.233222961 15.500000000 -33.233222961 35.233222961 16.500000000 -33.233222961 35.233222961 17.500000000 -33.233222961 35.233222961 18.500000000 -33.233222961 35.233222961 19.500000000 -33.233222961 35.233222961 20.500000000 -33.233222961 35.233222961 21.500000000 -33.233222961 35.233222961 22.500000000 -33.233222961 35.233222961 23.500000000 -33.233222961 35.233222961 24.499984741 -33.233219147 35.233207703 25.499874115 -33.233169556 35.233074188 26.499225616 -33.232864380 35.232299805 27.496379852 -33.231597900 35.228954315 28.486719131 -33.227867126 35.217514038 29.460596085 -33.220710754 35.185966492 30.405673981 -33.216835022 35.112342834 31.334243774 -33.254272461 34.954723358 32.030693054 -33.030693054 34.846313477 -33.840934753 -32.035343170 34.797355652 -33.254272461 -32.334239960 34.954723358 -32.371025085 -32.371025085 35.154670715 -31.438953400 -32.375358582 35.280395508 -30.476007462 -32.379222870 35.344284058 -29.492319107 -32.382308960 35.371490479 -28.498050690 -32.383811951 35.381023407 -27.499622345 -32.384300232 35.383720398 -26.499948502 -32.384403229 35.384311676 -25.499996185 -32.384422302 35.384407043 -24.500000000 -32.384422302 35.384418488 -23.500000000 -32.384422302 35.384418488 -22.500000000 -32.384422302 35.384418488 -21.500000000 -32.384422302 35.384418488 -20.500000000 -32.384422302 35.384418488 -19.500000000 -32.384422302 35.384418488 -18.500000000 -32.384422302 35.384418488 -17.500000000 -32.384422302 35.384418488 -16.500000000 -32.384422302 35.384418488 -15.500000000 -32.384422302 35.384418488 -14.500000000 -32.384422302 35.384418488 -13.500000000 -32.384422302 35.384418488 -12.500000000 -32.384422302 35.384418488 -11.500000000 -32.384422302 35.384418488 -10.500000000 -32.384422302 35.384418488 -9.500000000 -32.384422302 35.384418488 -8.500000000 -32.384422302 35.384418488 -7.500000000 -32.384422302 35.384418488 -6.500000000 -32.384422302 35.384418488 -5.500000000 -32.384422302 35.384418488 -4.500000000 -32.384422302 35.384418488 -3.500000000 -32.384422302 35.384418488 -2.500000000 -32.384422302 35.384418488 -1.500000000 -32.384422302 35.384418488 -0.500000000 -32.384422302 35.384418488 0.500000000 -32.384422302 35.384418488 1.500000000 -32.384422302 35.384418488 2.500000000 -32.384422302 35.384418488 3.500000000 -32.384422302 35.384418488 4.500000000 -32.384422302 35.384418488 5.500000000 -32.384422302 35.384418488 6.500000000 -32.384422302 35.384418488 7.500000000 -32.384422302 35.384418488 8.500000000 -32.384422302 35.384418488 9.500000000 -32.384422302 35.384418488 10.500000000 -32.384422302 35.384418488 11.500000000 -32.384422302 35.384418488 12.500000000 -32.384422302 35.384418488 13.500000000 -32.384422302 35.384418488 14.500000000 -32.384422302 35.384418488 15.500000000 -32.384422302 35.384418488 16.500000000 -32.384422302 35.384418488 17.500000000 -32.384422302 35.384418488 18.500000000 -32.384422302 35.384418488 19.500000000 -32.384422302 35.384418488 20.500000000 -32.384422302 35.384418488 21.500000000 -32.384422302 35.384418488 22.500000000 -32.384422302 35.384418488 23.500000000 -32.384422302 35.384418488 24.499996185 -32.384418488 35.384407043 25.499948502 -32.384407043 35.384307861 26.499622345 -32.384300232 35.383720398 27.498052597 -32.383811951 35.381023407 28.492321014 -32.382316589 35.371486664 29.476007462 -32.379222870 35.344280243 30.438953400 -32.375358582 35.280395508 31.371026993 -32.371025085 35.154674530 32.254272461 -32.334243774 34.954723358 32.840930939 -32.035346985 34.797355652 -33.903373718 -31.336603165 34.879734039 -33.216838837 -31.405673981 35.112346649 -32.375358582 -31.438955307 35.280395508 -31.451217651 -31.451221466 35.380989075 -30.483785629 -31.456085205 35.430477142 -29.495611191 -31.458078384 35.450424194 -28.499073029 -31.458770752 35.456939697 -27.499858856 -31.458948135 35.458606720 -26.499988556 -31.458978653 35.458930969 -25.500000000 -31.458980560 35.458976746 -24.500000000 -31.458980560 35.458976746 -23.500000000 -31.458980560 35.458976746 -22.500000000 -31.458980560 35.458976746 -21.500000000 -31.458980560 35.458976746 -20.500000000 -31.458980560 35.458976746 -19.500000000 -31.458980560 35.458976746 -18.500000000 -31.458980560 35.458976746 -17.500000000 -31.458980560 35.458976746 -16.500000000 -31.458980560 35.458976746 -15.500000000 -31.458980560 35.458976746 -14.500000000 -31.458980560 35.458976746 -13.500000000 -31.458980560 35.458976746 -12.500000000 -31.458980560 35.458976746 -11.500000000 -31.458980560 35.458976746 -10.500000000 -31.458980560 35.458976746 -9.500000000 -31.458980560 35.458976746 -8.500000000 -31.458980560 35.458976746 -7.500000000 -31.458980560 35.458976746 -6.500000000 -31.458980560 35.458976746 -5.500000000 -31.458980560 35.458976746 -4.500000000 -31.458980560 35.458976746 -3.500000000 -31.458980560 35.458976746 -2.500000000 -31.458980560 35.458976746 -1.500000000 -31.458980560 35.458976746 -0.500000000 -31.458980560 35.458976746 0.500000000 -31.458980560 35.458976746 1.500000000 -31.458980560 35.458976746 2.500000000 -31.458980560 35.458976746 3.500000000 -31.458980560 35.458976746 4.500000000 -31.458980560 35.458976746 5.500000000 -31.458980560 35.458976746 6.500000000 -31.458980560 35.458976746 7.500000000 -31.458980560 35.458976746 8.500000000 -31.458980560 35.458976746 9.500000000 -31.458980560 35.458976746 10.500000000 -31.458980560 35.458976746 11.500000000 -31.458980560 35.458976746 12.500000000 -31.458980560 35.458976746 13.500000000 -31.458980560 35.458976746 14.500000000 -31.458980560 35.458976746 15.500000000 -31.458980560 35.458976746 16.500000000 -31.458980560 35.458976746 17.500000000 -31.458980560 35.458976746 18.500000000 -31.458980560 35.458976746 19.500000000 -31.458980560 35.458976746 20.500000000 -31.458980560 35.458976746 21.500000000 -31.458980560 35.458976746 22.500000000 -31.458980560 35.458976746 23.500000000 -31.458980560 35.458976746 24.500000000 -31.458980560 35.458976746 25.499988556 -31.458978653 35.458930969 26.499858856 -31.458948135 35.458606720 27.499073029 -31.458770752 35.456935883 28.495611191 -31.458078384 35.450424194 29.483785629 -31.456085205 35.430473328 30.451217651 -31.451217651 35.380989075 31.375356674 -31.438953400 35.280395508 32.216842651 -31.405675888 35.112346649 32.903373718 -31.336603165 34.879734039 -33.946807861 -30.442844391 34.937091827 -33.220714569 -30.460596085 35.185966492 -32.379222870 -30.476007462 35.344284058 -31.456081390 -30.483789444 35.430477142 -30.486965179 -30.486968994 35.469234467 -29.496957779 -30.488048553 35.483337402 -28.499475479 -30.488346100 35.487373352 -27.499938965 -30.488399506 35.488258362 -26.499996185 -30.488403320 35.488391876 -25.500000000 -30.488403320 35.488403320 -24.500000000 -30.488403320 35.488403320 -23.500000000 -30.488403320 35.488403320 -22.500000000 -30.488403320 35.488403320 -21.500000000 -30.488403320 35.488403320 -20.500000000 -30.488403320 35.488403320 -19.500000000 -30.488403320 35.488403320 -18.500000000 -30.488403320 35.488403320 -17.500000000 -30.488403320 35.488403320 -16.500000000 -30.488403320 35.488403320 -15.500000000 -30.488403320 35.488403320 -14.500000000 -30.488403320 35.488403320 -13.500000000 -30.488403320 35.488403320 -12.500000000 -30.488403320 35.488403320 -11.500000000 -30.488403320 35.488403320 -10.500000000 -30.488403320 35.488403320 -9.500000000 -30.488403320 35.488403320 -8.500000000 -30.488403320 35.488403320 -7.500000000 -30.488403320 35.488403320 -6.500000000 -30.488403320 35.488403320 -5.500000000 -30.488403320 35.488403320 -4.500000000 -30.488403320 35.488403320 -3.500000000 -30.488403320 35.488403320 -2.500000000 -30.488403320 35.488403320 -1.500000000 -30.488403320 35.488403320 -0.500000000 -30.488403320 35.488403320 0.500000000 -30.488403320 35.488403320 1.500000000 -30.488403320 35.488403320 2.500000000 -30.488403320 35.488403320 3.500000000 -30.488403320 35.488403320 4.500000000 -30.488403320 35.488403320 5.500000000 -30.488403320 35.488403320 6.500000000 -30.488403320 35.488403320 7.500000000 -30.488403320 35.488403320 8.500000000 -30.488403320 35.488403320 9.500000000 -30.488403320 35.488403320 10.500000000 -30.488403320 35.488403320 11.500000000 -30.488403320 35.488403320 12.500000000 -30.488403320 35.488403320 13.500000000 -30.488403320 35.488403320 14.500000000 -30.488403320 35.488403320 15.500000000 -30.488403320 35.488403320 16.500000000 -30.488403320 35.488403320 17.500000000 -30.488403320 35.488403320 18.500000000 -30.488403320 35.488403320 19.500000000 -30.488403320 35.488403320 20.500000000 -30.488403320 35.488403320 21.500000000 -30.488403320 35.488403320 22.500000000 -30.488403320 35.488403320 23.500000000 -30.488403320 35.488403320 24.500000000 -30.488403320 35.488403320 25.499996185 -30.488403320 35.488391876 26.499938965 -30.488399506 35.488258362 27.499475479 -30.488346100 35.487373352 28.496959686 -30.488048553 35.483337402 29.486968994 -30.486968994 35.469234467 30.456085205 -30.483785629 35.430473328 31.379222870 -30.476007462 35.344284058 32.220714569 -30.460596085 35.185966492 32.946807861 -30.442840576 34.937091827 -33.968864441 -29.481937408 34.965763092 -33.227874756 -29.486719131 35.217510223 -32.382308960 -29.492319107 35.371490479 -31.458078384 -29.495611191 35.450428009 -30.488048553 -29.496957779 35.483337402 -29.497375488 -29.497371674 35.494174957 -28.499578476 -29.497461319 35.496910095 -27.499954224 -29.497470856 35.497409821 -26.499996185 -29.497470856 35.497467041 -25.500000000 -29.497470856 35.497474670 -24.500000000 -29.497470856 35.497474670 -23.500000000 -29.497470856 35.497474670 -22.500000000 -29.497470856 35.497474670 -21.500000000 -29.497470856 35.497474670 -20.500000000 -29.497470856 35.497474670 -19.500000000 -29.497470856 35.497474670 -18.500000000 -29.497470856 35.497474670 -17.500000000 -29.497470856 35.497474670 -16.500000000 -29.497470856 35.497474670 -15.500000000 -29.497470856 35.497474670 -14.500000000 -29.497470856 35.497474670 -13.500000000 -29.497470856 35.497474670 -12.500000000 -29.497470856 35.497474670 -11.500000000 -29.497470856 35.497474670 -10.500000000 -29.497470856 35.497474670 -9.500000000 -29.497470856 35.497474670 -8.500000000 -29.497470856 35.497474670 -7.500000000 -29.497470856 35.497474670 -6.500000000 -29.497470856 35.497474670 -5.500000000 -29.497470856 35.497474670 -4.500000000 -29.497470856 35.497474670 -3.500000000 -29.497470856 35.497474670 -2.500000000 -29.497470856 35.497474670 -1.500000000 -29.497470856 35.497474670 -0.500000000 -29.497470856 35.497474670 0.500000000 -29.497470856 35.497474670 1.500000000 -29.497470856 35.497474670 2.500000000 -29.497470856 35.497474670 3.500000000 -29.497470856 35.497474670 4.500000000 -29.497470856 35.497474670 5.500000000 -29.497470856 35.497474670 6.500000000 -29.497470856 35.497474670 7.500000000 -29.497470856 35.497474670 8.500000000 -29.497470856 35.497474670 9.500000000 -29.497470856 35.497474670 10.500000000 -29.497470856 35.497474670 11.500000000 -29.497470856 35.497474670 12.500000000 -29.497470856 35.497474670 13.500000000 -29.497470856 35.497474670 14.500000000 -29.497470856 35.497474670 15.500000000 -29.497470856 35.497474670 16.500000000 -29.497470856 35.497474670 17.500000000 -29.497470856 35.497474670 18.500000000 -29.497470856 35.497474670 19.500000000 -29.497470856 35.497474670 20.500000000 -29.497470856 35.497474670 21.500000000 -29.497470856 35.497474670 22.500000000 -29.497470856 35.497474670 23.500000000 -29.497470856 35.497474670 24.500000000 -29.497470856 35.497474670 25.499996185 -29.497470856 35.497470856 26.499954224 -29.497470856 35.497406006 27.499576569 -29.497461319 35.496910095 28.497375488 -29.497375488 35.494174957 29.488048553 -29.496957779 35.483337402 30.458078384 -29.495611191 35.450428009 31.382312775 -29.492321014 35.371490479 32.227874756 -29.486719131 35.217510223 32.968864441 -29.481937408 34.965763092 -33.977611542 -28.495172501 34.976860046 -33.231597900 -28.496379852 35.228954315 -32.383808136 -28.498052597 35.381023407 -31.458766937 -28.499073029 35.456939697 -30.488346100 -28.499475479 35.487373352 -29.497461319 -28.499576569 35.496910095 -28.499593735 -28.499591827 35.499164581 -27.499954224 -28.499591827 35.499546051 -26.499996185 -28.499591827 35.499588013 -25.500000000 -28.499591827 35.499591827 -24.500000000 -28.499591827 35.499591827 -23.500000000 -28.499591827 35.499591827 -22.500000000 -28.499591827 35.499591827 -21.500000000 -28.499591827 35.499591827 -20.500000000 -28.499591827 35.499591827 -19.500000000 -28.499591827 35.499591827 -18.500000000 -28.499591827 35.499591827 -17.500000000 -28.499591827 35.499591827 -16.500000000 -28.499591827 35.499591827 -15.500000000 -28.499591827 35.499591827 -14.500000000 -28.499591827 35.499591827 -13.500000000 -28.499591827 35.499591827 -12.500000000 -28.499591827 35.499591827 -11.500000000 -28.499591827 35.499591827 -10.500000000 -28.499591827 35.499591827 -9.500000000 -28.499591827 35.499591827 -8.500000000 -28.499591827 35.499591827 -7.500000000 -28.499591827 35.499591827 -6.500000000 -28.499591827 35.499591827 -5.500000000 -28.499591827 35.499591827 -4.500000000 -28.499591827 35.499591827 -3.500000000 -28.499591827 35.499591827 -2.500000000 -28.499591827 35.499591827 -1.500000000 -28.499591827 35.499591827 -0.500000000 -28.499591827 35.499591827 0.500000000 -28.499591827 35.499591827 1.500000000 -28.499591827 35.499591827 2.500000000 -28.499591827 35.499591827 3.500000000 -28.499591827 35.499591827 4.500000000 -28.499591827 35.499591827 5.500000000 -28.499591827 35.499591827 6.500000000 -28.499591827 35.499591827 7.500000000 -28.499591827 35.499591827 8.500000000 -28.499591827 35.499591827 9.500000000 -28.499591827 35.499591827 10.500000000 -28.499591827 35.499591827 11.500000000 -28.499591827 35.499591827 12.500000000 -28.499591827 35.499591827 13.500000000 -28.499591827 35.499591827 14.500000000 -28.499591827 35.499591827 15.500000000 -28.499591827 35.499591827 16.500000000 -28.499591827 35.499591827 17.500000000 -28.499591827 35.499591827 18.500000000 -28.499591827 35.499591827 19.500000000 -28.499591827 35.499591827 20.500000000 -28.499591827 35.499591827 21.500000000 -28.499591827 35.499591827 22.500000000 -28.499591827 35.499591827 23.500000000 -28.499591827 35.499591827 24.500000000 -28.499591827 35.499591827 25.499996185 -28.499591827 35.499588013 26.499954224 -28.499591827 35.499542236 27.499591827 -28.499591827 35.499160767 28.497461319 -28.499576569 35.496910095 29.488346100 -28.499475479 35.487377167 30.458766937 -28.499073029 35.456939697 31.383810043 -28.498052597 35.381023407 32.231597900 -28.496377945 35.228954315 32.977611542 -28.495172501 34.976860046 -33.980331421 -27.498952866 34.980201721 -33.232864380 -27.499225616 35.232307434 -32.384296417 -27.499622345 35.383720398 -31.458948135 -27.499858856 35.458606720 -30.488399506 -27.499938965 35.488258362 -29.497472763 -27.499954224 35.497406006 -28.499593735 -27.499954224 35.499549866 -27.499954224 -27.499954224 35.499908447 -26.499996185 -27.499954224 35.499950409 -25.500000000 -27.499954224 35.499954224 -24.500000000 -27.499954224 35.499954224 -23.500000000 -27.499954224 35.499954224 -22.500000000 -27.499954224 35.499954224 -21.500000000 -27.499954224 35.499954224 -20.500000000 -27.499954224 35.499954224 -19.500000000 -27.499954224 35.499954224 -18.500000000 -27.499954224 35.499954224 -17.500000000 -27.499954224 35.499954224 -16.500000000 -27.499954224 35.499954224 -15.500000000 -27.499954224 35.499954224 -14.500000000 -27.499954224 35.499954224 -13.500000000 -27.499954224 35.499954224 -12.500000000 -27.499954224 35.499954224 -11.500000000 -27.499954224 35.499954224 -10.500000000 -27.499954224 35.499954224 -9.500000000 -27.499954224 35.499954224 -8.500000000 -27.499954224 35.499954224 -7.500000000 -27.499954224 35.499954224 -6.500000000 -27.499954224 35.499954224 -5.500000000 -27.499954224 35.499954224 -4.500000000 -27.499954224 35.499954224 -3.500000000 -27.499954224 35.499954224 -2.500000000 -27.499954224 35.499954224 -1.500000000 -27.499954224 35.499954224 -0.500000000 -27.499954224 35.499954224 0.500000000 -27.499954224 35.499954224 1.500000000 -27.499954224 35.499954224 2.500000000 -27.499954224 35.499954224 3.500000000 -27.499954224 35.499954224 4.500000000 -27.499954224 35.499954224 5.500000000 -27.499954224 35.499954224 6.500000000 -27.499954224 35.499954224 7.500000000 -27.499954224 35.499954224 8.500000000 -27.499954224 35.499954224 9.500000000 -27.499954224 35.499954224 10.500000000 -27.499954224 35.499954224 11.500000000 -27.499954224 35.499954224 12.500000000 -27.499954224 35.499954224 13.500000000 -27.499954224 35.499954224 14.500000000 -27.499954224 35.499954224 15.500000000 -27.499954224 35.499954224 16.500000000 -27.499954224 35.499954224 17.500000000 -27.499954224 35.499954224 18.500000000 -27.499954224 35.499954224 19.500000000 -27.499954224 35.499954224 20.500000000 -27.499954224 35.499954224 21.500000000 -27.499954224 35.499954224 22.500000000 -27.499954224 35.499954224 23.500000000 -27.499954224 35.499954224 24.500000000 -27.499954224 35.499954224 25.499996185 -27.499954224 35.499950409 26.499954224 -27.499954224 35.499908447 27.499591827 -27.499954224 35.499546051 28.497470856 -27.499954224 35.497413635 29.488399506 -27.499938965 35.488258362 30.458948135 -27.499858856 35.458606720 31.384298325 -27.499618530 35.383720398 32.232860565 -27.499225616 35.232307434 32.980335236 -27.498952866 34.980201721 -33.980972290 -26.499826431 34.980957031 -33.233165741 -26.499874115 35.233070374 -32.384403229 -26.499948502 35.384307861 -31.458978653 -26.499988556 35.458930969 -30.488407135 -26.499996185 35.488384247 -29.497472763 -26.499996185 35.497467041 -28.499593735 -26.499996185 35.499591827 -27.499954224 -26.499996185 35.499950409 -26.499996185 -26.499996185 35.499992371 -25.500000000 -26.499996185 35.499996185 -24.500000000 -26.499996185 35.499996185 -23.500000000 -26.499996185 35.499996185 -22.500000000 -26.499996185 35.499996185 -21.500000000 -26.499996185 35.499996185 -20.500000000 -26.499996185 35.499996185 -19.500000000 -26.499996185 35.499996185 -18.500000000 -26.499996185 35.499996185 -17.500000000 -26.499996185 35.499996185 -16.500000000 -26.499996185 35.499996185 -15.500000000 -26.499996185 35.499996185 -14.500000000 -26.499996185 35.499996185 -13.500000000 -26.499996185 35.499996185 -12.500000000 -26.499996185 35.499996185 -11.500000000 -26.499996185 35.499996185 -10.500000000 -26.499996185 35.499996185 -9.500000000 -26.499996185 35.499996185 -8.500000000 -26.499996185 35.499996185 -7.500000000 -26.499996185 35.499996185 -6.500000000 -26.499996185 35.499996185 -5.500000000 -26.499996185 35.499996185 -4.500000000 -26.499996185 35.499996185 -3.500000000 -26.499996185 35.499996185 -2.500000000 -26.499996185 35.499996185 -1.500000000 -26.499996185 35.499996185 -0.500000000 -26.499996185 35.499996185 0.500000000 -26.499996185 35.499996185 1.500000000 -26.499996185 35.499996185 2.500000000 -26.499996185 35.499996185 3.500000000 -26.499996185 35.499996185 4.500000000 -26.499996185 35.499996185 5.500000000 -26.499996185 35.499996185 6.500000000 -26.499996185 35.499996185 7.500000000 -26.499996185 35.499996185 8.500000000 -26.499996185 35.499996185 9.500000000 -26.499996185 35.499996185 10.500000000 -26.499996185 35.499996185 11.500000000 -26.499996185 35.499996185 12.500000000 -26.499996185 35.499996185 13.500000000 -26.499996185 35.499996185 14.500000000 -26.499996185 35.499996185 15.500000000 -26.499996185 35.499996185 16.500000000 -26.499996185 35.499996185 17.500000000 -26.499996185 35.499996185 18.500000000 -26.499996185 35.499996185 19.500000000 -26.499996185 35.499996185 20.500000000 -26.499996185 35.499996185 21.500000000 -26.499996185 35.499996185 22.500000000 -26.499996185 35.499996185 23.500000000 -26.499996185 35.499996185 24.500000000 -26.499996185 35.499996185 25.499996185 -26.499996185 35.499992371 26.499954224 -26.499996185 35.499950409 27.499591827 -26.499996185 35.499591827 28.497470856 -26.499996185 35.497467041 29.488407135 -26.499996185 35.488391876 30.458978653 -26.499988556 35.458934784 31.384403229 -26.499948502 35.384307861 32.233165741 -26.499872208 35.233070374 32.980972290 -26.499826431 34.980957031 -33.981090546 -25.499979019 34.981086731 -33.233222961 -25.499984741 35.233203888 -32.384422302 -25.499996185 35.384407043 -31.458978653 -25.500000000 35.458976746 -30.488407135 -25.500000000 35.488403320 -29.497472763 -25.500000000 35.497474670 -28.499593735 -25.500000000 35.499591827 -27.499954224 -25.500000000 35.499954224 -26.499996185 -25.500000000 35.499996185 -25.500000000 -25.500000000 35.500000000 -24.500000000 -25.500000000 35.500000000 -23.500000000 -25.500000000 35.500000000 -22.500000000 -25.500000000 35.500000000 -21.500000000 -25.500000000 35.500000000 -20.500000000 -25.500000000 35.500000000 -19.500000000 -25.500000000 35.500000000 -18.500000000 -25.500000000 35.500000000 -17.500000000 -25.500000000 35.500000000 -16.500000000 -25.500000000 35.500000000 -15.500000000 -25.500000000 35.500000000 -14.500000000 -25.500000000 35.500000000 -13.500000000 -25.500000000 35.500000000 -12.500000000 -25.500000000 35.500000000 -11.500000000 -25.500000000 35.500000000 -10.500000000 -25.500000000 35.500000000 -9.500000000 -25.500000000 35.500000000 -8.500000000 -25.500000000 35.500000000 -7.500000000 -25.500000000 35.500000000 -6.500000000 -25.500000000 35.500000000 -5.500000000 -25.500000000 35.500000000 -4.500000000 -25.500000000 35.500000000 -3.500000000 -25.500000000 35.500000000 -2.500000000 -25.500000000 35.500000000 -1.500000000 -25.500000000 35.500000000 -0.500000000 -25.500000000 35.500000000 0.500000000 -25.500000000 35.500000000 1.500000000 -25.500000000 35.500000000 2.500000000 -25.500000000 35.500000000 3.500000000 -25.500000000 35.500000000 4.500000000 -25.500000000 35.500000000 5.500000000 -25.500000000 35.500000000 6.500000000 -25.500000000 35.500000000 7.500000000 -25.500000000 35.500000000 8.500000000 -25.500000000 35.500000000 9.500000000 -25.500000000 35.500000000 10.500000000 -25.500000000 35.500000000 11.500000000 -25.500000000 35.500000000 12.500000000 -25.500000000 35.500000000 13.500000000 -25.500000000 35.500000000 14.500000000 -25.500000000 35.500000000 15.500000000 -25.500000000 35.500000000 16.500000000 -25.500000000 35.500000000 17.500000000 -25.500000000 35.500000000 18.500000000 -25.500000000 35.500000000 19.500000000 -25.500000000 35.500000000 20.500000000 -25.500000000 35.500000000 21.500000000 -25.500000000 35.500000000 22.500000000 -25.500000000 35.500000000 23.500000000 -25.500000000 35.500000000 24.500000000 -25.500000000 35.500000000 25.499996185 -25.500000000 35.499996185 26.499954224 -25.500000000 35.499954224 27.499591827 -25.500000000 35.499591827 28.497470856 -25.500000000 35.497467041 29.488407135 -25.500000000 35.488403320 30.458978653 -25.500000000 35.458976746 31.384418488 -25.499996185 35.384407043 32.233215332 -25.499986649 35.233203888 32.981086731 -25.499977112 34.981086731 -33.981101990 -24.499998093 34.981101990 -33.233226776 -24.500000000 35.233222961 -32.384422302 -24.500000000 35.384418488 -31.458978653 -24.500000000 35.458980560 -30.488407135 -24.500000000 35.488403320 -29.497472763 -24.500000000 35.497474670 -28.499593735 -24.500000000 35.499591827 -27.499954224 -24.500000000 35.499954224 -26.499996185 -24.500000000 35.499996185 -25.500000000 -24.500000000 35.500000000 -24.500000000 -24.500000000 35.500000000 -23.500000000 -24.500000000 35.500000000 -22.500000000 -24.500000000 35.500000000 -21.500000000 -24.500000000 35.500000000 -20.500000000 -24.500000000 35.500000000 -19.500000000 -24.500000000 35.500000000 -18.500000000 -24.500000000 35.500000000 -17.500000000 -24.500000000 35.500000000 -16.500000000 -24.500000000 35.500000000 -15.500000000 -24.500000000 35.500000000 -14.500000000 -24.500000000 35.500000000 -13.500000000 -24.500000000 35.500000000 -12.500000000 -24.500000000 35.500000000 -11.500000000 -24.500000000 35.500000000 -10.500000000 -24.500000000 35.500000000 -9.500000000 -24.500000000 35.500000000 -8.500000000 -24.500000000 35.500000000 -7.500000000 -24.500000000 35.500000000 -6.500000000 -24.500000000 35.500000000 -5.500000000 -24.500000000 35.500000000 -4.500000000 -24.500000000 35.500000000 -3.500000000 -24.500000000 35.500000000 -2.500000000 -24.500000000 35.500000000 -1.500000000 -24.500000000 35.500000000 -0.500000000 -24.500000000 35.500000000 0.500000000 -24.500000000 35.500000000 1.500000000 -24.500000000 35.500000000 2.500000000 -24.500000000 35.500000000 3.500000000 -24.500000000 35.500000000 4.500000000 -24.500000000 35.500000000 5.500000000 -24.500000000 35.500000000 6.500000000 -24.500000000 35.500000000 7.500000000 -24.500000000 35.500000000 8.500000000 -24.500000000 35.500000000 9.500000000 -24.500000000 35.500000000 10.500000000 -24.500000000 35.500000000 11.500000000 -24.500000000 35.500000000 12.500000000 -24.500000000 35.500000000 13.500000000 -24.500000000 35.500000000 14.500000000 -24.500000000 35.500000000 15.500000000 -24.500000000 35.500000000 16.500000000 -24.500000000 35.500000000 17.500000000 -24.500000000 35.500000000 18.500000000 -24.500000000 35.500000000 19.500000000 -24.500000000 35.500000000 20.500000000 -24.500000000 35.500000000 21.500000000 -24.500000000 35.500000000 22.500000000 -24.500000000 35.500000000 23.500000000 -24.500000000 35.500000000 24.500000000 -24.500000000 35.500000000 25.499996185 -24.500000000 35.499996185 26.499954224 -24.500000000 35.499954224 27.499591827 -24.500000000 35.499591827 28.497470856 -24.500000000 35.497467041 29.488407135 -24.500000000 35.488403320 30.458978653 -24.500000000 35.458980560 31.384418488 -24.500000000 35.384418488 32.233222961 -24.499998093 35.233222961 32.981101990 -24.499998093 34.981101990 -33.981101990 -23.500000000 34.981101990 -33.233226776 -23.500000000 35.233222961 -32.384422302 -23.500000000 35.384418488 -31.458978653 -23.500000000 35.458980560 -30.488407135 -23.500000000 35.488403320 -29.497472763 -23.500000000 35.497474670 -28.499593735 -23.500000000 35.499591827 -27.499954224 -23.500000000 35.499954224 -26.499996185 -23.500000000 35.499996185 -25.500000000 -23.500000000 35.500000000 -24.500000000 -23.500000000 35.500000000 -23.500000000 -23.500000000 35.500000000 -22.500000000 -23.500000000 35.500000000 -21.500000000 -23.500000000 35.500000000 -20.500000000 -23.500000000 35.500000000 -19.500000000 -23.500000000 35.500000000 -18.500000000 -23.500000000 35.500000000 -17.500000000 -23.500000000 35.500000000 -16.500000000 -23.500000000 35.500000000 -15.500000000 -23.500000000 35.500000000 -14.500000000 -23.500000000 35.500000000 -13.500000000 -23.500000000 35.500000000 -12.500000000 -23.500000000 35.500000000 -11.500000000 -23.500000000 35.500000000 -10.500000000 -23.500000000 35.500000000 -9.500000000 -23.500000000 35.500000000 -8.500000000 -23.500000000 35.500000000 -7.500000000 -23.500000000 35.500000000 -6.500000000 -23.500000000 35.500000000 -5.500000000 -23.500000000 35.500000000 -4.500000000 -23.500000000 35.500000000 -3.500000000 -23.500000000 35.500000000 -2.500000000 -23.500000000 35.500000000 -1.500000000 -23.500000000 35.500000000 -0.500000000 -23.500000000 35.500000000 0.500000000 -23.500000000 35.500000000 1.500000000 -23.500000000 35.500000000 2.500000000 -23.500000000 35.500000000 3.500000000 -23.500000000 35.500000000 4.500000000 -23.500000000 35.500000000 5.500000000 -23.500000000 35.500000000 6.500000000 -23.500000000 35.500000000 7.500000000 -23.500000000 35.500000000 8.500000000 -23.500000000 35.500000000 9.500000000 -23.500000000 35.500000000 10.500000000 -23.500000000 35.500000000 11.500000000 -23.500000000 35.500000000 12.500000000 -23.500000000 35.500000000 13.500000000 -23.500000000 35.500000000 14.500000000 -23.500000000 35.500000000 15.500000000 -23.500000000 35.500000000 16.500000000 -23.500000000 35.500000000 17.500000000 -23.500000000 35.500000000 18.500000000 -23.500000000 35.500000000 19.500000000 -23.500000000 35.500000000 20.500000000 -23.500000000 35.500000000 21.500000000 -23.500000000 35.500000000 22.500000000 -23.500000000 35.500000000 23.500000000 -23.500000000 35.500000000 24.500000000 -23.500000000 35.500000000 25.499996185 -23.500000000 35.499996185 26.499954224 -23.500000000 35.499954224 27.499591827 -23.500000000 35.499591827 28.497470856 -23.500000000 35.497467041 29.488407135 -23.500000000 35.488403320 30.458978653 -23.500000000 35.458980560 31.384418488 -23.500000000 35.384422302 32.233222961 -23.500000000 35.233222961 32.981101990 -23.500000000 34.981101990 -33.981101990 -22.500000000 34.981101990 -33.233226776 -22.500000000 35.233222961 -32.384422302 -22.500000000 35.384418488 -31.458978653 -22.500000000 35.458980560 -30.488407135 -22.500000000 35.488403320 -29.497472763 -22.500000000 35.497474670 -28.499593735 -22.500000000 35.499591827 -27.499954224 -22.500000000 35.499954224 -26.499996185 -22.500000000 35.499996185 -25.500000000 -22.500000000 35.500000000 -24.500000000 -22.500000000 35.500000000 -23.500000000 -22.500000000 35.500000000 -22.500000000 -22.500000000 35.500000000 -21.500000000 -22.500000000 35.500000000 -20.500000000 -22.500000000 35.500000000 -19.500000000 -22.500000000 35.500000000 -18.500000000 -22.500000000 35.500000000 -17.500000000 -22.500000000 35.500000000 -16.500000000 -22.500000000 35.500000000 -15.500000000 -22.500000000 35.500000000 -14.500000000 -22.500000000 35.500000000 -13.500000000 -22.500000000 35.500000000 -12.500000000 -22.500000000 35.500000000 -11.500000000 -22.500000000 35.500000000 -10.500000000 -22.500000000 35.500000000 -9.500000000 -22.500000000 35.500000000 -8.500000000 -22.500000000 35.500000000 -7.500000000 -22.500000000 35.500000000 -6.500000000 -22.500000000 35.500000000 -5.500000000 -22.500000000 35.500000000 -4.500000000 -22.500000000 35.500000000 -3.500000000 -22.500000000 35.500000000 -2.500000000 -22.500000000 35.500000000 -1.500000000 -22.500000000 35.500000000 -0.500000000 -22.500000000 35.500000000 0.500000000 -22.500000000 35.500000000 1.500000000 -22.500000000 35.500000000 2.500000000 -22.500000000 35.500000000 3.500000000 -22.500000000 35.500000000 4.500000000 -22.500000000 35.500000000 5.500000000 -22.500000000 35.500000000 6.500000000 -22.500000000 35.500000000 7.500000000 -22.500000000 35.500000000 8.500000000 -22.500000000 35.500000000 9.500000000 -22.500000000 35.500000000 10.500000000 -22.500000000 35.500000000 11.500000000 -22.500000000 35.500000000 12.500000000 -22.500000000 35.500000000 13.500000000 -22.500000000 35.500000000 14.500000000 -22.500000000 35.500000000 15.500000000 -22.500000000 35.500000000 16.500000000 -22.500000000 35.500000000 17.500000000 -22.500000000 35.500000000 18.500000000 -22.500000000 35.500000000 19.500000000 -22.500000000 35.500000000 20.500000000 -22.500000000 35.500000000 21.500000000 -22.500000000 35.500000000 22.500000000 -22.500000000 35.500000000 23.500000000 -22.500000000 35.500000000 24.500000000 -22.500000000 35.500000000 25.499996185 -22.500000000 35.499996185 26.499954224 -22.500000000 35.499954224 27.499591827 -22.500000000 35.499591827 28.497470856 -22.500000000 35.497467041 29.488407135 -22.500000000 35.488403320 30.458978653 -22.500000000 35.458980560 31.384418488 -22.500000000 35.384422302 32.233222961 -22.500000000 35.233222961 32.981101990 -22.500000000 34.981101990 -33.981101990 -21.500000000 34.981101990 -33.233226776 -21.500000000 35.233222961 -32.384422302 -21.500000000 35.384418488 -31.458978653 -21.500000000 35.458980560 -30.488407135 -21.500000000 35.488403320 -29.497472763 -21.500000000 35.497474670 -28.499593735 -21.500000000 35.499591827 -27.499954224 -21.500000000 35.499954224 -26.499996185 -21.500000000 35.499996185 -25.500000000 -21.500000000 35.500000000 -24.500000000 -21.500000000 35.500000000 -23.500000000 -21.500000000 35.500000000 -22.500000000 -21.500000000 35.500000000 -21.500000000 -21.500000000 35.500000000 -20.500000000 -21.500000000 35.500000000 -19.500000000 -21.500000000 35.500000000 -18.500000000 -21.500000000 35.500000000 -17.500000000 -21.500000000 35.500000000 -16.500000000 -21.500000000 35.500000000 -15.500000000 -21.500000000 35.500000000 -14.500000000 -21.500000000 35.500000000 -13.500000000 -21.500000000 35.500000000 -12.500000000 -21.500000000 35.500000000 -11.500000000 -21.500000000 35.500000000 -10.500000000 -21.500000000 35.500000000 -9.500000000 -21.500000000 35.500000000 -8.500000000 -21.500000000 35.500000000 -7.500000000 -21.500000000 35.500000000 -6.500000000 -21.500000000 35.500000000 -5.500000000 -21.500000000 35.500000000 -4.500000000 -21.500000000 35.500000000 -3.500000000 -21.500000000 35.500000000 -2.500000000 -21.500000000 35.500000000 -1.500000000 -21.500000000 35.500000000 -0.500000000 -21.500000000 35.500000000 0.500000000 -21.500000000 35.500000000 1.500000000 -21.500000000 35.500000000 2.500000000 -21.500000000 35.500000000 3.500000000 -21.500000000 35.500000000 4.500000000 -21.500000000 35.500000000 5.500000000 -21.500000000 35.500000000 6.500000000 -21.500000000 35.500000000 7.500000000 -21.500000000 35.500000000 8.500000000 -21.500000000 35.500000000 9.500000000 -21.500000000 35.500000000 10.500000000 -21.500000000 35.500000000 11.500000000 -21.500000000 35.500000000 12.500000000 -21.500000000 35.500000000 13.500000000 -21.500000000 35.500000000 14.500000000 -21.500000000 35.500000000 15.500000000 -21.500000000 35.500000000 16.500000000 -21.500000000 35.500000000 17.500000000 -21.500000000 35.500000000 18.500000000 -21.500000000 35.500000000 19.500000000 -21.500000000 35.500000000 20.500000000 -21.500000000 35.500000000 21.500000000 -21.500000000 35.500000000 22.500000000 -21.500000000 35.500000000 23.500000000 -21.500000000 35.500000000 24.500000000 -21.500000000 35.500000000 25.499996185 -21.500000000 35.499996185 26.499954224 -21.500000000 35.499954224 27.499591827 -21.500000000 35.499591827 28.497470856 -21.500000000 35.497467041 29.488407135 -21.500000000 35.488403320 30.458978653 -21.500000000 35.458980560 31.384418488 -21.500000000 35.384422302 32.233222961 -21.500000000 35.233222961 32.981101990 -21.500000000 34.981101990 -33.981101990 -20.500000000 34.981101990 -33.233226776 -20.500000000 35.233222961 -32.384422302 -20.500000000 35.384418488 -31.458978653 -20.500000000 35.458980560 -30.488407135 -20.500000000 35.488403320 -29.497472763 -20.500000000 35.497474670 -28.499593735 -20.500000000 35.499591827 -27.499954224 -20.500000000 35.499954224 -26.499996185 -20.500000000 35.499996185 -25.500000000 -20.500000000 35.500000000 -24.500000000 -20.500000000 35.500000000 -23.500000000 -20.500000000 35.500000000 -22.500000000 -20.500000000 35.500000000 -21.500000000 -20.500000000 35.500000000 -20.500000000 -20.500000000 35.500000000 -19.500000000 -20.500000000 35.500000000 -18.500000000 -20.500000000 35.500000000 -17.500000000 -20.500000000 35.500000000 -16.500000000 -20.500000000 35.500000000 -15.500000000 -20.500000000 35.500000000 -14.500000000 -20.500000000 35.500000000 -13.500000000 -20.500000000 35.500000000 -12.500000000 -20.500000000 35.500000000 -11.500000000 -20.500000000 35.500000000 -10.500000000 -20.500000000 35.500000000 -9.500000000 -20.500000000 35.500000000 -8.500000000 -20.500000000 35.500000000 -7.500000000 -20.500000000 35.500000000 -6.500000000 -20.500000000 35.500000000 -5.500000000 -20.500000000 35.500000000 -4.500000000 -20.500000000 35.500000000 -3.500000000 -20.500000000 35.500000000 -2.500000000 -20.500000000 35.500000000 -1.500000000 -20.500000000 35.500000000 -0.500000000 -20.500000000 35.500000000 0.500000000 -20.500000000 35.500000000 1.500000000 -20.500000000 35.500000000 2.500000000 -20.500000000 35.500000000 3.500000000 -20.500000000 35.500000000 4.500000000 -20.500000000 35.500000000 5.500000000 -20.500000000 35.500000000 6.500000000 -20.500000000 35.500000000 7.500000000 -20.500000000 35.500000000 8.500000000 -20.500000000 35.500000000 9.500000000 -20.500000000 35.500000000 10.500000000 -20.500000000 35.500000000 11.500000000 -20.500000000 35.500000000 12.500000000 -20.500000000 35.500000000 13.500000000 -20.500000000 35.500000000 14.500000000 -20.500000000 35.500000000 15.500000000 -20.500000000 35.500000000 16.500000000 -20.500000000 35.500000000 17.500000000 -20.500000000 35.500000000 18.500000000 -20.500000000 35.500000000 19.500000000 -20.500000000 35.500000000 20.500000000 -20.500000000 35.500000000 21.500000000 -20.500000000 35.500000000 22.500000000 -20.500000000 35.500000000 23.500000000 -20.500000000 35.500000000 24.500000000 -20.500000000 35.500000000 25.499996185 -20.500000000 35.499996185 26.499954224 -20.500000000 35.499954224 27.499591827 -20.500000000 35.499591827 28.497470856 -20.500000000 35.497467041 29.488407135 -20.500000000 35.488403320 30.458978653 -20.500000000 35.458980560 31.384418488 -20.500000000 35.384422302 32.233222961 -20.500000000 35.233222961 32.981101990 -20.500000000 34.981101990 -33.981101990 -19.500000000 34.981101990 -33.233226776 -19.500000000 35.233222961 -32.384422302 -19.500000000 35.384418488 -31.458978653 -19.500000000 35.458980560 -30.488407135 -19.500000000 35.488403320 -29.497472763 -19.500000000 35.497474670 -28.499593735 -19.500000000 35.499591827 -27.499954224 -19.500000000 35.499954224 -26.499996185 -19.500000000 35.499996185 -25.500000000 -19.500000000 35.500000000 -24.500000000 -19.500000000 35.500000000 -23.500000000 -19.500000000 35.500000000 -22.500000000 -19.500000000 35.500000000 -21.500000000 -19.500000000 35.500000000 -20.500000000 -19.500000000 35.500000000 -19.500000000 -19.500000000 35.500000000 -18.500000000 -19.500000000 35.500000000 -17.500000000 -19.500000000 35.500000000 -16.500000000 -19.500000000 35.500000000 -15.500000000 -19.500000000 35.500000000 -14.500000000 -19.500000000 35.500000000 -13.500000000 -19.500000000 35.500000000 -12.500000000 -19.500000000 35.500000000 -11.500000000 -19.500000000 35.500000000 -10.500000000 -19.500000000 35.500000000 -9.500000000 -19.500000000 35.500000000 -8.500000000 -19.500000000 35.500000000 -7.500000000 -19.500000000 35.500000000 -6.500000000 -19.500000000 35.500000000 -5.500000000 -19.500000000 35.500000000 -4.500000000 -19.500000000 35.500000000 -3.500000000 -19.500000000 35.500000000 -2.500000000 -19.500000000 35.500000000 -1.500000000 -19.500000000 35.500000000 -0.500000000 -19.500000000 35.500000000 0.500000000 -19.500000000 35.500000000 1.500000000 -19.500000000 35.500000000 2.500000000 -19.500000000 35.500000000 3.500000000 -19.500000000 35.500000000 4.500000000 -19.500000000 35.500000000 5.500000000 -19.500000000 35.500000000 6.500000000 -19.500000000 35.500000000 7.500000000 -19.500000000 35.500000000 8.500000000 -19.500000000 35.500000000 9.500000000 -19.500000000 35.500000000 10.500000000 -19.500000000 35.500000000 11.500000000 -19.500000000 35.500000000 12.500000000 -19.500000000 35.500000000 13.500000000 -19.500000000 35.500000000 14.500000000 -19.500000000 35.500000000 15.500000000 -19.500000000 35.500000000 16.500000000 -19.500000000 35.500000000 17.500000000 -19.500000000 35.500000000 18.500000000 -19.500000000 35.500000000 19.500000000 -19.500000000 35.500000000 20.500000000 -19.500000000 35.500000000 21.500000000 -19.500000000 35.500000000 22.500000000 -19.500000000 35.500000000 23.500000000 -19.500000000 35.500000000 24.500000000 -19.500000000 35.500000000 25.499996185 -19.500000000 35.499996185 26.499954224 -19.500000000 35.499954224 27.499591827 -19.500000000 35.499591827 28.497470856 -19.500000000 35.497467041 29.488407135 -19.500000000 35.488403320 30.458978653 -19.500000000 35.458980560 31.384418488 -19.500000000 35.384422302 32.233222961 -19.500000000 35.233222961 32.981101990 -19.500000000 34.981101990 -33.981101990 -18.500000000 34.981101990 -33.233226776 -18.500000000 35.233222961 -32.384422302 -18.500000000 35.384418488 -31.458978653 -18.500000000 35.458980560 -30.488407135 -18.500000000 35.488403320 -29.497472763 -18.500000000 35.497474670 -28.499593735 -18.500000000 35.499591827 -27.499954224 -18.500000000 35.499954224 -26.499996185 -18.500000000 35.499996185 -25.500000000 -18.500000000 35.500000000 -24.500000000 -18.500000000 35.500000000 -23.500000000 -18.500000000 35.500000000 -22.500000000 -18.500000000 35.500000000 -21.500000000 -18.500000000 35.500000000 -20.500000000 -18.500000000 35.500000000 -19.500000000 -18.500000000 35.500000000 -18.500000000 -18.500000000 35.500000000 -17.500000000 -18.500000000 35.500000000 -16.500000000 -18.500000000 35.500000000 -15.500000000 -18.500000000 35.500000000 -14.500000000 -18.500000000 35.500000000 -13.500000000 -18.500000000 35.500000000 -12.500000000 -18.500000000 35.500000000 -11.500000000 -18.500000000 35.500000000 -10.500000000 -18.500000000 35.500000000 -9.500000000 -18.500000000 35.500000000 -8.500000000 -18.500000000 35.500000000 -7.500000000 -18.500000000 35.500000000 -6.500000000 -18.500000000 35.500000000 -5.500000000 -18.500000000 35.500000000 -4.500000000 -18.500000000 35.500000000 -3.500000000 -18.500000000 35.500000000 -2.500000000 -18.500000000 35.500000000 -1.500000000 -18.500000000 35.500000000 -0.500000000 -18.500000000 35.500000000 0.500000000 -18.500000000 35.500000000 1.500000000 -18.500000000 35.500000000 2.500000000 -18.500000000 35.500000000 3.500000000 -18.500000000 35.500000000 4.500000000 -18.500000000 35.500000000 5.500000000 -18.500000000 35.500000000 6.500000000 -18.500000000 35.500000000 7.500000000 -18.500000000 35.500000000 8.500000000 -18.500000000 35.500000000 9.500000000 -18.500000000 35.500000000 10.500000000 -18.500000000 35.500000000 11.500000000 -18.500000000 35.500000000 12.500000000 -18.500000000 35.500000000 13.500000000 -18.500000000 35.500000000 14.500000000 -18.500000000 35.500000000 15.500000000 -18.500000000 35.500000000 16.500000000 -18.500000000 35.500000000 17.500000000 -18.500000000 35.500000000 18.500000000 -18.500000000 35.500000000 19.500000000 -18.500000000 35.500000000 20.500000000 -18.500000000 35.500000000 21.500000000 -18.500000000 35.500000000 22.500000000 -18.500000000 35.500000000 23.500000000 -18.500000000 35.500000000 24.500000000 -18.500000000 35.500000000 25.499996185 -18.500000000 35.499996185 26.499954224 -18.500000000 35.499954224 27.499591827 -18.500000000 35.499591827 28.497470856 -18.500000000 35.497467041 29.488407135 -18.500000000 35.488403320 30.458978653 -18.500000000 35.458980560 31.384418488 -18.500000000 35.384422302 32.233222961 -18.500000000 35.233222961 32.981101990 -18.500000000 34.981101990 -33.981101990 -17.500000000 34.981101990 -33.233226776 -17.500000000 35.233222961 -32.384422302 -17.500000000 35.384418488 -31.458978653 -17.500000000 35.458980560 -30.488407135 -17.500000000 35.488403320 -29.497472763 -17.500000000 35.497474670 -28.499593735 -17.500000000 35.499591827 -27.499954224 -17.500000000 35.499954224 -26.499996185 -17.500000000 35.499996185 -25.500000000 -17.500000000 35.500000000 -24.500000000 -17.500000000 35.500000000 -23.500000000 -17.500000000 35.500000000 -22.500000000 -17.500000000 35.500000000 -21.500000000 -17.500000000 35.500000000 -20.500000000 -17.500000000 35.500000000 -19.500000000 -17.500000000 35.500000000 -18.500000000 -17.500000000 35.500000000 -17.500000000 -17.500000000 35.500000000 -16.500000000 -17.500000000 35.500000000 -15.500000000 -17.500000000 35.500000000 -14.500000000 -17.500000000 35.500000000 -13.500000000 -17.500000000 35.500000000 -12.500000000 -17.500000000 35.500000000 -11.500000000 -17.500000000 35.500000000 -10.500000000 -17.500000000 35.500000000 -9.500000000 -17.500000000 35.500000000 -8.500000000 -17.500000000 35.500000000 -7.500000000 -17.500000000 35.500000000 -6.500000000 -17.500000000 35.500000000 -5.500000000 -17.500000000 35.500000000 -4.500000000 -17.500000000 35.500000000 -3.500000000 -17.500000000 35.500000000 -2.500000000 -17.500000000 35.500000000 -1.500000000 -17.500000000 35.500000000 -0.500000000 -17.500000000 35.500000000 0.500000000 -17.500000000 35.500000000 1.500000000 -17.500000000 35.500000000 2.500000000 -17.500000000 35.500000000 3.500000000 -17.500000000 35.500000000 4.500000000 -17.500000000 35.500000000 5.500000000 -17.500000000 35.500000000 6.500000000 -17.500000000 35.500000000 7.500000000 -17.500000000 35.500000000 8.500000000 -17.500000000 35.500000000 9.500000000 -17.500000000 35.500000000 10.500000000 -17.500000000 35.500000000 11.500000000 -17.500000000 35.500000000 12.500000000 -17.500000000 35.500000000 13.500000000 -17.500000000 35.500000000 14.500000000 -17.500000000 35.500000000 15.500000000 -17.500000000 35.500000000 16.500000000 -17.500000000 35.500000000 17.500000000 -17.500000000 35.500000000 18.500000000 -17.500000000 35.500000000 19.500000000 -17.500000000 35.500000000 20.500000000 -17.500000000 35.500000000 21.500000000 -17.500000000 35.500000000 22.500000000 -17.500000000 35.500000000 23.500000000 -17.500000000 35.500000000 24.500000000 -17.500000000 35.500000000 25.499996185 -17.500000000 35.499996185 26.499954224 -17.500000000 35.499954224 27.499591827 -17.500000000 35.499591827 28.497470856 -17.500000000 35.497467041 29.488407135 -17.500000000 35.488403320 30.458978653 -17.500000000 35.458980560 31.384418488 -17.500000000 35.384422302 32.233222961 -17.500000000 35.233222961 32.981101990 -17.500000000 34.981101990 -33.981101990 -16.500000000 34.981101990 -33.233226776 -16.500000000 35.233222961 -32.384422302 -16.500000000 35.384418488 -31.458978653 -16.500000000 35.458980560 -30.488407135 -16.500000000 35.488403320 -29.497472763 -16.500000000 35.497474670 -28.499593735 -16.500000000 35.499591827 -27.499954224 -16.500000000 35.499954224 -26.499996185 -16.500000000 35.499996185 -25.500000000 -16.500000000 35.500000000 -24.500000000 -16.500000000 35.500000000 -23.500000000 -16.500000000 35.500000000 -22.500000000 -16.500000000 35.500000000 -21.500000000 -16.500000000 35.500000000 -20.500000000 -16.500000000 35.500000000 -19.500000000 -16.500000000 35.500000000 -18.500000000 -16.500000000 35.500000000 -17.500000000 -16.500000000 35.500000000 -16.500000000 -16.500000000 35.500000000 -15.500000000 -16.500000000 35.500000000 -14.500000000 -16.500000000 35.500000000 -13.500000000 -16.500000000 35.500000000 -12.500000000 -16.500000000 35.500000000 -11.500000000 -16.500000000 35.500000000 -10.500000000 -16.500000000 35.500000000 -9.500000000 -16.500000000 35.500000000 -8.500000000 -16.500000000 35.500000000 -7.500000000 -16.500000000 35.500000000 -6.500000000 -16.500000000 35.500000000 -5.500000000 -16.500000000 35.500000000 -4.500000000 -16.500000000 35.500000000 -3.500000000 -16.500000000 35.500000000 -2.500000000 -16.500000000 35.500000000 -1.500000000 -16.500000000 35.500000000 -0.500000000 -16.500000000 35.500000000 0.500000000 -16.500000000 35.500000000 1.500000000 -16.500000000 35.500000000 2.500000000 -16.500000000 35.500000000 3.500000000 -16.500000000 35.500000000 4.500000000 -16.500000000 35.500000000 5.500000000 -16.500000000 35.500000000 6.500000000 -16.500000000 35.500000000 7.500000000 -16.500000000 35.500000000 8.500000000 -16.500000000 35.500000000 9.500000000 -16.500000000 35.500000000 10.500000000 -16.500000000 35.500000000 11.500000000 -16.500000000 35.500000000 12.500000000 -16.500000000 35.500000000 13.500000000 -16.500000000 35.500000000 14.500000000 -16.500000000 35.500000000 15.500000000 -16.500000000 35.500000000 16.500000000 -16.500000000 35.500000000 17.500000000 -16.500000000 35.500000000 18.500000000 -16.500000000 35.500000000 19.500000000 -16.500000000 35.500000000 20.500000000 -16.500000000 35.500000000 21.500000000 -16.500000000 35.500000000 22.500000000 -16.500000000 35.500000000 23.500000000 -16.500000000 35.500000000 24.500000000 -16.500000000 35.500000000 25.499996185 -16.500000000 35.499996185 26.499954224 -16.500000000 35.499954224 27.499591827 -16.500000000 35.499591827 28.497470856 -16.500000000 35.497467041 29.488407135 -16.500000000 35.488403320 30.458978653 -16.500000000 35.458980560 31.384418488 -16.500000000 35.384422302 32.233222961 -16.500000000 35.233222961 32.981101990 -16.500000000 34.981101990 -33.981101990 -15.500000000 34.981101990 -33.233226776 -15.500000000 35.233222961 -32.384422302 -15.500000000 35.384418488 -31.458978653 -15.500000000 35.458980560 -30.488407135 -15.500000000 35.488403320 -29.497472763 -15.500000000 35.497474670 -28.499593735 -15.500000000 35.499591827 -27.499954224 -15.500000000 35.499954224 -26.499996185 -15.500000000 35.499996185 -25.500000000 -15.500000000 35.500000000 -24.500000000 -15.500000000 35.500000000 -23.500000000 -15.500000000 35.500000000 -22.500000000 -15.500000000 35.500000000 -21.500000000 -15.500000000 35.500000000 -20.500000000 -15.500000000 35.500000000 -19.500000000 -15.500000000 35.500000000 -18.500000000 -15.500000000 35.500000000 -17.500000000 -15.500000000 35.500000000 -16.500000000 -15.500000000 35.500000000 -15.500000000 -15.500000000 35.500000000 -14.500000000 -15.500000000 35.500000000 -13.500000000 -15.500000000 35.500000000 -12.500000000 -15.500000000 35.500000000 -11.500000000 -15.500000000 35.500000000 -10.500000000 -15.500000000 35.500000000 -9.500000000 -15.500000000 35.500000000 -8.500000000 -15.500000000 35.500000000 -7.500000000 -15.500000000 35.500000000 -6.500000000 -15.500000000 35.500000000 -5.500000000 -15.500000000 35.500000000 -4.500000000 -15.500000000 35.500000000 -3.500000000 -15.500000000 35.500000000 -2.500000000 -15.500000000 35.500000000 -1.500000000 -15.500000000 35.500000000 -0.500000000 -15.500000000 35.500000000 0.500000000 -15.500000000 35.500000000 1.500000000 -15.500000000 35.500000000 2.500000000 -15.500000000 35.500000000 3.500000000 -15.500000000 35.500000000 4.500000000 -15.500000000 35.500000000 5.500000000 -15.500000000 35.500000000 6.500000000 -15.500000000 35.500000000 7.500000000 -15.500000000 35.500000000 8.500000000 -15.500000000 35.500000000 9.500000000 -15.500000000 35.500000000 10.500000000 -15.500000000 35.500000000 11.500000000 -15.500000000 35.500000000 12.500000000 -15.500000000 35.500000000 13.500000000 -15.500000000 35.500000000 14.500000000 -15.500000000 35.500000000 15.500000000 -15.500000000 35.500000000 16.500000000 -15.500000000 35.500000000 17.500000000 -15.500000000 35.500000000 18.500000000 -15.500000000 35.500000000 19.500000000 -15.500000000 35.500000000 20.500000000 -15.500000000 35.500000000 21.500000000 -15.500000000 35.500000000 22.500000000 -15.500000000 35.500000000 23.500000000 -15.500000000 35.500000000 24.500000000 -15.500000000 35.500000000 25.499996185 -15.500000000 35.499996185 26.499954224 -15.500000000 35.499954224 27.499591827 -15.500000000 35.499591827 28.497470856 -15.500000000 35.497467041 29.488407135 -15.500000000 35.488403320 30.458978653 -15.500000000 35.458980560 31.384418488 -15.500000000 35.384422302 32.233222961 -15.500000000 35.233222961 32.981101990 -15.500000000 34.981101990 -33.981101990 -14.500000000 34.981101990 -33.233226776 -14.500000000 35.233222961 -32.384422302 -14.500000000 35.384418488 -31.458978653 -14.500000000 35.458980560 -30.488407135 -14.500000000 35.488403320 -29.497472763 -14.500000000 35.497474670 -28.499593735 -14.500000000 35.499591827 -27.499954224 -14.500000000 35.499954224 -26.499996185 -14.500000000 35.499996185 -25.500000000 -14.500000000 35.500000000 -24.500000000 -14.500000000 35.500000000 -23.500000000 -14.500000000 35.500000000 -22.500000000 -14.500000000 35.500000000 -21.500000000 -14.500000000 35.500000000 -20.500000000 -14.500000000 35.500000000 -19.500000000 -14.500000000 35.500000000 -18.500000000 -14.500000000 35.500000000 -17.500000000 -14.500000000 35.500000000 -16.500000000 -14.500000000 35.500000000 -15.500000000 -14.500000000 35.500000000 -14.500000000 -14.500000000 35.500000000 -13.500000000 -14.500000000 35.500000000 -12.500000000 -14.500000000 35.500000000 -11.500000000 -14.500000000 35.500000000 -10.500000000 -14.500000000 35.500000000 -9.500000000 -14.500000000 35.500000000 -8.500000000 -14.500000000 35.500000000 -7.500000000 -14.500000000 35.500000000 -6.500000000 -14.500000000 35.500000000 -5.500000000 -14.500000000 35.500000000 -4.500000000 -14.500000000 35.500000000 -3.500000000 -14.500000000 35.500000000 -2.500000000 -14.500000000 35.500000000 -1.500000000 -14.500000000 35.500000000 -0.500000000 -14.500000000 35.500000000 0.500000000 -14.500000000 35.500000000 1.500000000 -14.500000000 35.500000000 2.500000000 -14.500000000 35.500000000 3.500000000 -14.500000000 35.500000000 4.500000000 -14.500000000 35.500000000 5.500000000 -14.500000000 35.500000000 6.500000000 -14.500000000 35.500000000 7.500000000 -14.500000000 35.500000000 8.500000000 -14.500000000 35.500000000 9.500000000 -14.500000000 35.500000000 10.500000000 -14.500000000 35.500000000 11.500000000 -14.500000000 35.500000000 12.500000000 -14.500000000 35.500000000 13.500000000 -14.500000000 35.500000000 14.500000000 -14.500000000 35.500000000 15.500000000 -14.500000000 35.500000000 16.500000000 -14.500000000 35.500000000 17.500000000 -14.500000000 35.500000000 18.500000000 -14.500000000 35.500000000 19.500000000 -14.500000000 35.500000000 20.500000000 -14.500000000 35.500000000 21.500000000 -14.500000000 35.500000000 22.500000000 -14.500000000 35.500000000 23.500000000 -14.500000000 35.500000000 24.500000000 -14.500000000 35.500000000 25.499996185 -14.500000000 35.499996185 26.499954224 -14.500000000 35.499954224 27.499591827 -14.500000000 35.499591827 28.497470856 -14.500000000 35.497467041 29.488407135 -14.500000000 35.488403320 30.458978653 -14.500000000 35.458980560 31.384418488 -14.500000000 35.384422302 32.233222961 -14.500000000 35.233222961 32.981101990 -14.500000000 34.981101990 -33.981101990 -13.500000000 34.981101990 -33.233226776 -13.500000000 35.233222961 -32.384422302 -13.500000000 35.384418488 -31.458978653 -13.500000000 35.458980560 -30.488407135 -13.500000000 35.488403320 -29.497472763 -13.500000000 35.497474670 -28.499593735 -13.500000000 35.499591827 -27.499954224 -13.500000000 35.499954224 -26.499996185 -13.500000000 35.499996185 -25.500000000 -13.500000000 35.500000000 -24.500000000 -13.500000000 35.500000000 -23.500000000 -13.500000000 35.500000000 -22.500000000 -13.500000000 35.500000000 -21.500000000 -13.500000000 35.500000000 -20.500000000 -13.500000000 35.500000000 -19.500000000 -13.500000000 35.500000000 -18.500000000 -13.500000000 35.500000000 -17.500000000 -13.500000000 35.500000000 -16.500000000 -13.500000000 35.500000000 -15.500000000 -13.500000000 35.500000000 -14.500000000 -13.500000000 35.500000000 -13.500000000 -13.500000000 35.500000000 -12.500000000 -13.500000000 35.500000000 -11.500000000 -13.500000000 35.500000000 -10.500000000 -13.500000000 35.500000000 -9.500000000 -13.500000000 35.500000000 -8.500000000 -13.500000000 35.500000000 -7.500000000 -13.500000000 35.500000000 -6.500000000 -13.500000000 35.500000000 -5.500000000 -13.500000000 35.500000000 -4.500000000 -13.500000000 35.500000000 -3.500000000 -13.500000000 35.500000000 -2.500000000 -13.500000000 35.500000000 -1.500000000 -13.500000000 35.500000000 -0.500000000 -13.500000000 35.500000000 0.500000000 -13.500000000 35.500000000 1.500000000 -13.500000000 35.500000000 2.500000000 -13.500000000 35.500000000 3.500000000 -13.500000000 35.500000000 4.500000000 -13.500000000 35.500000000 5.500000000 -13.500000000 35.500000000 6.500000000 -13.500000000 35.500000000 7.500000000 -13.500000000 35.500000000 8.500000000 -13.500000000 35.500000000 9.500000000 -13.500000000 35.500000000 10.500000000 -13.500000000 35.500000000 11.500000000 -13.500000000 35.500000000 12.500000000 -13.500000000 35.500000000 13.500000000 -13.500000000 35.500000000 14.500000000 -13.500000000 35.500000000 15.500000000 -13.500000000 35.500000000 16.500000000 -13.500000000 35.500000000 17.500000000 -13.500000000 35.500000000 18.500000000 -13.500000000 35.500000000 19.500000000 -13.500000000 35.500000000 20.500000000 -13.500000000 35.500000000 21.500000000 -13.500000000 35.500000000 22.500000000 -13.500000000 35.500000000 23.500000000 -13.500000000 35.500000000 24.500000000 -13.500000000 35.500000000 25.499996185 -13.500000000 35.499996185 26.499954224 -13.500000000 35.499954224 27.499591827 -13.500000000 35.499591827 28.497470856 -13.500000000 35.497467041 29.488407135 -13.500000000 35.488403320 30.458978653 -13.500000000 35.458980560 31.384418488 -13.500000000 35.384422302 32.233222961 -13.500000000 35.233222961 32.981101990 -13.500000000 34.981101990 -33.981101990 -12.500000000 34.981101990 -33.233226776 -12.500000000 35.233222961 -32.384422302 -12.500000000 35.384418488 -31.458978653 -12.500000000 35.458980560 -30.488407135 -12.500000000 35.488403320 -29.497472763 -12.500000000 35.497474670 -28.499593735 -12.500000000 35.499591827 -27.499954224 -12.500000000 35.499954224 -26.499996185 -12.500000000 35.499996185 -25.500000000 -12.500000000 35.500000000 -24.500000000 -12.500000000 35.500000000 -23.500000000 -12.500000000 35.500000000 -22.500000000 -12.500000000 35.500000000 -21.500000000 -12.500000000 35.500000000 -20.500000000 -12.500000000 35.500000000 -19.500000000 -12.500000000 35.500000000 -18.500000000 -12.500000000 35.500000000 -17.500000000 -12.500000000 35.500000000 -16.500000000 -12.500000000 35.500000000 -15.500000000 -12.500000000 35.500000000 -14.500000000 -12.500000000 35.500000000 -13.500000000 -12.500000000 35.500000000 -12.500000000 -12.500000000 35.500000000 -11.500000000 -12.500000000 35.500000000 -10.500000000 -12.500000000 35.500000000 -9.500000000 -12.500000000 35.500000000 -8.500000000 -12.500000000 35.500000000 -7.500000000 -12.500000000 35.500000000 -6.500000000 -12.500000000 35.500000000 -5.500000000 -12.500000000 35.500000000 -4.500000000 -12.500000000 35.500000000 -3.500000000 -12.500000000 35.500000000 -2.500000000 -12.500000000 35.500000000 -1.500000000 -12.500000000 35.500000000 -0.500000000 -12.500000000 35.500000000 0.500000000 -12.500000000 35.500000000 1.500000000 -12.500000000 35.500000000 2.500000000 -12.500000000 35.500000000 3.500000000 -12.500000000 35.500000000 4.500000000 -12.500000000 35.500000000 5.500000000 -12.500000000 35.500000000 6.500000000 -12.500000000 35.500000000 7.500000000 -12.500000000 35.500000000 8.500000000 -12.500000000 35.500000000 9.500000000 -12.500000000 35.500000000 10.500000000 -12.500000000 35.500000000 11.500000000 -12.500000000 35.500000000 12.500000000 -12.500000000 35.500000000 13.500000000 -12.500000000 35.500000000 14.500000000 -12.500000000 35.500000000 15.500000000 -12.500000000 35.500000000 16.500000000 -12.500000000 35.500000000 17.500000000 -12.500000000 35.500000000 18.500000000 -12.500000000 35.500000000 19.500000000 -12.500000000 35.500000000 20.500000000 -12.500000000 35.500000000 21.500000000 -12.500000000 35.500000000 22.500000000 -12.500000000 35.500000000 23.500000000 -12.500000000 35.500000000 24.500000000 -12.500000000 35.500000000 25.499996185 -12.500000000 35.499996185 26.499954224 -12.500000000 35.499954224 27.499591827 -12.500000000 35.499591827 28.497470856 -12.500000000 35.497467041 29.488407135 -12.500000000 35.488403320 30.458978653 -12.500000000 35.458980560 31.384418488 -12.500000000 35.384422302 32.233222961 -12.500000000 35.233222961 32.981101990 -12.500000000 34.981101990 -33.981101990 -11.500000000 34.981101990 -33.233226776 -11.500000000 35.233222961 -32.384422302 -11.500000000 35.384418488 -31.458978653 -11.500000000 35.458980560 -30.488407135 -11.500000000 35.488403320 -29.497472763 -11.500000000 35.497474670 -28.499593735 -11.500000000 35.499591827 -27.499954224 -11.500000000 35.499954224 -26.499996185 -11.500000000 35.499996185 -25.500000000 -11.500000000 35.500000000 -24.500000000 -11.500000000 35.500000000 -23.500000000 -11.500000000 35.500000000 -22.500000000 -11.500000000 35.500000000 -21.500000000 -11.500000000 35.500000000 -20.500000000 -11.500000000 35.500000000 -19.500000000 -11.500000000 35.500000000 -18.500000000 -11.500000000 35.500000000 -17.500000000 -11.500000000 35.500000000 -16.500000000 -11.500000000 35.500000000 -15.500000000 -11.500000000 35.500000000 -14.500000000 -11.500000000 35.500000000 -13.500000000 -11.500000000 35.500000000 -12.500000000 -11.500000000 35.500000000 -11.500000000 -11.500000000 35.500000000 -10.500000000 -11.500000000 35.500000000 -9.500000000 -11.500000000 35.500000000 -8.500000000 -11.500000000 35.500000000 -7.500000000 -11.500000000 35.500000000 -6.500000000 -11.500000000 35.500000000 -5.500000000 -11.500000000 35.500000000 -4.500000000 -11.500000000 35.500000000 -3.500000000 -11.500000000 35.500000000 -2.500000000 -11.500000000 35.500000000 -1.500000000 -11.500000000 35.500000000 -0.500000000 -11.500000000 35.500000000 0.500000000 -11.500000000 35.500000000 1.500000000 -11.500000000 35.500000000 2.500000000 -11.500000000 35.500000000 3.500000000 -11.500000000 35.500000000 4.500000000 -11.500000000 35.500000000 5.500000000 -11.500000000 35.500000000 6.500000000 -11.500000000 35.500000000 7.500000000 -11.500000000 35.500000000 8.500000000 -11.500000000 35.500000000 9.500000000 -11.500000000 35.500000000 10.500000000 -11.500000000 35.500000000 11.500000000 -11.500000000 35.500000000 12.500000000 -11.500000000 35.500000000 13.500000000 -11.500000000 35.500000000 14.500000000 -11.500000000 35.500000000 15.500000000 -11.500000000 35.500000000 16.500000000 -11.500000000 35.500000000 17.500000000 -11.500000000 35.500000000 18.500000000 -11.500000000 35.500000000 19.500000000 -11.500000000 35.500000000 20.500000000 -11.500000000 35.500000000 21.500000000 -11.500000000 35.500000000 22.500000000 -11.500000000 35.500000000 23.500000000 -11.500000000 35.500000000 24.500000000 -11.500000000 35.500000000 25.499996185 -11.500000000 35.499996185 26.499954224 -11.500000000 35.499954224 27.499591827 -11.500000000 35.499591827 28.497470856 -11.500000000 35.497467041 29.488407135 -11.500000000 35.488403320 30.458978653 -11.500000000 35.458980560 31.384418488 -11.500000000 35.384422302 32.233222961 -11.500000000 35.233222961 32.981101990 -11.500000000 34.981101990 -33.981101990 -10.500000000 34.981101990 -33.233226776 -10.500000000 35.233222961 -32.384422302 -10.500000000 35.384418488 -31.458978653 -10.500000000 35.458980560 -30.488407135 -10.500000000 35.488403320 -29.497472763 -10.500000000 35.497474670 -28.499593735 -10.500000000 35.499591827 -27.499954224 -10.500000000 35.499954224 -26.499996185 -10.500000000 35.499996185 -25.500000000 -10.500000000 35.500000000 -24.500000000 -10.500000000 35.500000000 -23.500000000 -10.500000000 35.500000000 -22.500000000 -10.500000000 35.500000000 -21.500000000 -10.500000000 35.500000000 -20.500000000 -10.500000000 35.500000000 -19.500000000 -10.500000000 35.500000000 -18.500000000 -10.500000000 35.500000000 -17.500000000 -10.500000000 35.500000000 -16.500000000 -10.500000000 35.500000000 -15.500000000 -10.500000000 35.500000000 -14.500000000 -10.500000000 35.500000000 -13.500000000 -10.500000000 35.500000000 -12.500000000 -10.500000000 35.500000000 -11.500000000 -10.500000000 35.500000000 -10.500000000 -10.500000000 35.500000000 -9.500000000 -10.500000000 35.500000000 -8.500000000 -10.500000000 35.500000000 -7.500000000 -10.500000000 35.500000000 -6.500000000 -10.500000000 35.500000000 -5.500000000 -10.500000000 35.500000000 -4.500000000 -10.500000000 35.500000000 -3.500000000 -10.500000000 35.500000000 -2.500000000 -10.500000000 35.500000000 -1.500000000 -10.500000000 35.500000000 -0.500000000 -10.500000000 35.500000000 0.500000000 -10.500000000 35.500000000 1.500000000 -10.500000000 35.500000000 2.500000000 -10.500000000 35.500000000 3.500000000 -10.500000000 35.500000000 4.500000000 -10.500000000 35.500000000 5.500000000 -10.500000000 35.500000000 6.500000000 -10.500000000 35.500000000 7.500000000 -10.500000000 35.500000000 8.500000000 -10.500000000 35.500000000 9.500000000 -10.500000000 35.500000000 10.500000000 -10.500000000 35.500000000 11.500000000 -10.500000000 35.500000000 12.500000000 -10.500000000 35.500000000 13.500000000 -10.500000000 35.500000000 14.500000000 -10.500000000 35.500000000 15.500000000 -10.500000000 35.500000000 16.500000000 -10.500000000 35.500000000 17.500000000 -10.500000000 35.500000000 18.500000000 -10.500000000 35.500000000 19.500000000 -10.500000000 35.500000000 20.500000000 -10.500000000 35.500000000 21.500000000 -10.500000000 35.500000000 22.500000000 -10.500000000 35.500000000 23.500000000 -10.500000000 35.500000000 24.500000000 -10.500000000 35.500000000 25.499996185 -10.500000000 35.499996185 26.499954224 -10.500000000 35.499954224 27.499591827 -10.500000000 35.499591827 28.497470856 -10.500000000 35.497467041 29.488407135 -10.500000000 35.488403320 30.458978653 -10.500000000 35.458980560 31.384418488 -10.500000000 35.384422302 32.233222961 -10.500000000 35.233222961 32.981101990 -10.500000000 34.981101990 -33.981101990 -9.500000000 34.981101990 -33.233226776 -9.500000000 35.233222961 -32.384422302 -9.500000000 35.384418488 -31.458978653 -9.500000000 35.458980560 -30.488407135 -9.500000000 35.488403320 -29.497472763 -9.500000000 35.497474670 -28.499593735 -9.500000000 35.499591827 -27.499954224 -9.500000000 35.499954224 -26.499996185 -9.500000000 35.499996185 -25.500000000 -9.500000000 35.500000000 -24.500000000 -9.500000000 35.500000000 -23.500000000 -9.500000000 35.500000000 -22.500000000 -9.500000000 35.500000000 -21.500000000 -9.500000000 35.500000000 -20.500000000 -9.500000000 35.500000000 -19.500000000 -9.500000000 35.500000000 -18.500000000 -9.500000000 35.500000000 -17.500000000 -9.500000000 35.500000000 -16.500000000 -9.500000000 35.500000000 -15.500000000 -9.500000000 35.500000000 -14.500000000 -9.500000000 35.500000000 -13.500000000 -9.500000000 35.500000000 -12.500000000 -9.500000000 35.500000000 -11.500000000 -9.500000000 35.500000000 -10.500000000 -9.500000000 35.500000000 -9.500000000 -9.500000000 35.500000000 -8.500000000 -9.500000000 35.500000000 -7.500000000 -9.500000000 35.500000000 -6.500000000 -9.500000000 35.500000000 -5.500000000 -9.500000000 35.500000000 -4.500000000 -9.500000000 35.500000000 -3.500000000 -9.500000000 35.500000000 -2.500000000 -9.500000000 35.500000000 -1.500000000 -9.500000000 35.500000000 -0.500000000 -9.500000000 35.500000000 0.500000000 -9.500000000 35.500000000 1.500000000 -9.500000000 35.500000000 2.500000000 -9.500000000 35.500000000 3.500000000 -9.500000000 35.500000000 4.500000000 -9.500000000 35.500000000 5.500000000 -9.500000000 35.500000000 6.500000000 -9.500000000 35.500000000 7.500000000 -9.500000000 35.500000000 8.500000000 -9.500000000 35.500000000 9.500000000 -9.500000000 35.500000000 10.500000000 -9.500000000 35.500000000 11.500000000 -9.500000000 35.500000000 12.500000000 -9.500000000 35.500000000 13.500000000 -9.500000000 35.500000000 14.500000000 -9.500000000 35.500000000 15.500000000 -9.500000000 35.500000000 16.500000000 -9.500000000 35.500000000 17.500000000 -9.500000000 35.500000000 18.500000000 -9.500000000 35.500000000 19.500000000 -9.500000000 35.500000000 20.500000000 -9.500000000 35.500000000 21.500000000 -9.500000000 35.500000000 22.500000000 -9.500000000 35.500000000 23.500000000 -9.500000000 35.500000000 24.500000000 -9.500000000 35.500000000 25.499996185 -9.500000000 35.499996185 26.499954224 -9.500000000 35.499954224 27.499591827 -9.500000000 35.499591827 28.497470856 -9.500000000 35.497467041 29.488407135 -9.500000000 35.488403320 30.458978653 -9.500000000 35.458980560 31.384418488 -9.500000000 35.384422302 32.233222961 -9.500000000 35.233222961 32.981101990 -9.500000000 34.981101990 -33.981101990 -8.500000000 34.981101990 -33.233226776 -8.500000000 35.233222961 -32.384422302 -8.500000000 35.384418488 -31.458978653 -8.500000000 35.458980560 -30.488407135 -8.500000000 35.488403320 -29.497472763 -8.500000000 35.497474670 -28.499593735 -8.500000000 35.499591827 -27.499954224 -8.500000000 35.499954224 -26.499996185 -8.500000000 35.499996185 -25.500000000 -8.500000000 35.500000000 -24.500000000 -8.500000000 35.500000000 -23.500000000 -8.500000000 35.500000000 -22.500000000 -8.500000000 35.500000000 -21.500000000 -8.500000000 35.500000000 -20.500000000 -8.500000000 35.500000000 -19.500000000 -8.500000000 35.500000000 -18.500000000 -8.500000000 35.500000000 -17.500000000 -8.500000000 35.500000000 -16.500000000 -8.500000000 35.500000000 -15.500000000 -8.500000000 35.500000000 -14.500000000 -8.500000000 35.500000000 -13.500000000 -8.500000000 35.500000000 -12.500000000 -8.500000000 35.500000000 -11.500000000 -8.500000000 35.500000000 -10.500000000 -8.500000000 35.500000000 -9.500000000 -8.500000000 35.500000000 -8.500000000 -8.500000000 35.500000000 -7.500000000 -8.500000000 35.500000000 -6.500000000 -8.500000000 35.500000000 -5.500000000 -8.500000000 35.500000000 -4.500000000 -8.500000000 35.500000000 -3.500000000 -8.500000000 35.500000000 -2.500000000 -8.500000000 35.500000000 -1.500000000 -8.500000000 35.500000000 -0.500000000 -8.500000000 35.500000000 0.500000000 -8.500000000 35.500000000 1.500000000 -8.500000000 35.500000000 2.500000000 -8.500000000 35.500000000 3.500000000 -8.500000000 35.500000000 4.500000000 -8.500000000 35.500000000 5.500000000 -8.500000000 35.500000000 6.500000000 -8.500000000 35.500000000 7.500000000 -8.500000000 35.500000000 8.500000000 -8.500000000 35.500000000 9.500000000 -8.500000000 35.500000000 10.500000000 -8.500000000 35.500000000 11.500000000 -8.500000000 35.500000000 12.500000000 -8.500000000 35.500000000 13.500000000 -8.500000000 35.500000000 14.500000000 -8.500000000 35.500000000 15.500000000 -8.500000000 35.500000000 16.500000000 -8.500000000 35.500000000 17.500000000 -8.500000000 35.500000000 18.500000000 -8.500000000 35.500000000 19.500000000 -8.500000000 35.500000000 20.500000000 -8.500000000 35.500000000 21.500000000 -8.500000000 35.500000000 22.500000000 -8.500000000 35.500000000 23.500000000 -8.500000000 35.500000000 24.500000000 -8.500000000 35.500000000 25.499996185 -8.500000000 35.499996185 26.499954224 -8.500000000 35.499954224 27.499591827 -8.500000000 35.499591827 28.497470856 -8.500000000 35.497467041 29.488407135 -8.500000000 35.488403320 30.458978653 -8.500000000 35.458980560 31.384418488 -8.500000000 35.384422302 32.233222961 -8.500000000 35.233222961 32.981101990 -8.500000000 34.981101990 -33.981101990 -7.500000000 34.981101990 -33.233226776 -7.500000000 35.233222961 -32.384422302 -7.500000000 35.384418488 -31.458978653 -7.500000000 35.458980560 -30.488407135 -7.500000000 35.488403320 -29.497472763 -7.500000000 35.497474670 -28.499593735 -7.500000000 35.499591827 -27.499954224 -7.500000000 35.499954224 -26.499996185 -7.500000000 35.499996185 -25.500000000 -7.500000000 35.500000000 -24.500000000 -7.500000000 35.500000000 -23.500000000 -7.500000000 35.500000000 -22.500000000 -7.500000000 35.500000000 -21.500000000 -7.500000000 35.500000000 -20.500000000 -7.500000000 35.500000000 -19.500000000 -7.500000000 35.500000000 -18.500000000 -7.500000000 35.500000000 -17.500000000 -7.500000000 35.500000000 -16.500000000 -7.500000000 35.500000000 -15.500000000 -7.500000000 35.500000000 -14.500000000 -7.500000000 35.500000000 -13.500000000 -7.500000000 35.500000000 -12.500000000 -7.500000000 35.500000000 -11.500000000 -7.500000000 35.500000000 -10.500000000 -7.500000000 35.500000000 -9.500000000 -7.500000000 35.500000000 -8.500000000 -7.500000000 35.500000000 -7.500000000 -7.500000000 35.500000000 -6.500000000 -7.500000000 35.500000000 -5.500000000 -7.500000000 35.500000000 -4.500000000 -7.500000000 35.500000000 -3.500000000 -7.500000000 35.500000000 -2.500000000 -7.500000000 35.500000000 -1.500000000 -7.500000000 35.500000000 -0.500000000 -7.500000000 35.500000000 0.500000000 -7.500000000 35.500000000 1.500000000 -7.500000000 35.500000000 2.500000000 -7.500000000 35.500000000 3.500000000 -7.500000000 35.500000000 4.500000000 -7.500000000 35.500000000 5.500000000 -7.500000000 35.500000000 6.500000000 -7.500000000 35.500000000 7.500000000 -7.500000000 35.500000000 8.500000000 -7.500000000 35.500000000 9.500000000 -7.500000000 35.500000000 10.500000000 -7.500000000 35.500000000 11.500000000 -7.500000000 35.500000000 12.500000000 -7.500000000 35.500000000 13.500000000 -7.500000000 35.500000000 14.500000000 -7.500000000 35.500000000 15.500000000 -7.500000000 35.500000000 16.500000000 -7.500000000 35.500000000 17.500000000 -7.500000000 35.500000000 18.500000000 -7.500000000 35.500000000 19.500000000 -7.500000000 35.500000000 20.500000000 -7.500000000 35.500000000 21.500000000 -7.500000000 35.500000000 22.500000000 -7.500000000 35.500000000 23.500000000 -7.500000000 35.500000000 24.500000000 -7.500000000 35.500000000 25.499996185 -7.500000000 35.499996185 26.499954224 -7.500000000 35.499954224 27.499591827 -7.500000000 35.499591827 28.497470856 -7.500000000 35.497467041 29.488407135 -7.500000000 35.488403320 30.458978653 -7.500000000 35.458980560 31.384418488 -7.500000000 35.384422302 32.233222961 -7.500000000 35.233222961 32.981101990 -7.500000000 34.981101990 -33.981101990 -6.500000000 34.981101990 -33.233226776 -6.500000000 35.233222961 -32.384422302 -6.500000000 35.384418488 -31.458978653 -6.500000000 35.458980560 -30.488407135 -6.500000000 35.488403320 -29.497472763 -6.500000000 35.497474670 -28.499593735 -6.500000000 35.499591827 -27.499954224 -6.500000000 35.499954224 -26.499996185 -6.500000000 35.499996185 -25.500000000 -6.500000000 35.500000000 -24.500000000 -6.500000000 35.500000000 -23.500000000 -6.500000000 35.500000000 -22.500000000 -6.500000000 35.500000000 -21.500000000 -6.500000000 35.500000000 -20.500000000 -6.500000000 35.500000000 -19.500000000 -6.500000000 35.500000000 -18.500000000 -6.500000000 35.500000000 -17.500000000 -6.500000000 35.500000000 -16.500000000 -6.500000000 35.500000000 -15.500000000 -6.500000000 35.500000000 -14.500000000 -6.500000000 35.500000000 -13.500000000 -6.500000000 35.500000000 -12.500000000 -6.500000000 35.500000000 -11.500000000 -6.500000000 35.500000000 -10.500000000 -6.500000000 35.500000000 -9.500000000 -6.500000000 35.500000000 -8.500000000 -6.500000000 35.500000000 -7.500000000 -6.500000000 35.500000000 -6.500000000 -6.500000000 35.500000000 -5.500000000 -6.500000000 35.500000000 -4.500000000 -6.500000000 35.500000000 -3.500000000 -6.500000000 35.500000000 -2.500000000 -6.500000000 35.500000000 -1.500000000 -6.500000000 35.500000000 -0.500000000 -6.500000000 35.500000000 0.500000000 -6.500000000 35.500000000 1.500000000 -6.500000000 35.500000000 2.500000000 -6.500000000 35.500000000 3.500000000 -6.500000000 35.500000000 4.500000000 -6.500000000 35.500000000 5.500000000 -6.500000000 35.500000000 6.500000000 -6.500000000 35.500000000 7.500000000 -6.500000000 35.500000000 8.500000000 -6.500000000 35.500000000 9.500000000 -6.500000000 35.500000000 10.500000000 -6.500000000 35.500000000 11.500000000 -6.500000000 35.500000000 12.500000000 -6.500000000 35.500000000 13.500000000 -6.500000000 35.500000000 14.500000000 -6.500000000 35.500000000 15.500000000 -6.500000000 35.500000000 16.500000000 -6.500000000 35.500000000 17.500000000 -6.500000000 35.500000000 18.500000000 -6.500000000 35.500000000 19.500000000 -6.500000000 35.500000000 20.500000000 -6.500000000 35.500000000 21.500000000 -6.500000000 35.500000000 22.500000000 -6.500000000 35.500000000 23.500000000 -6.500000000 35.500000000 24.500000000 -6.500000000 35.500000000 25.499996185 -6.500000000 35.499996185 26.499954224 -6.500000000 35.499954224 27.499591827 -6.500000000 35.499591827 28.497470856 -6.500000000 35.497467041 29.488407135 -6.500000000 35.488403320 30.458978653 -6.500000000 35.458980560 31.384418488 -6.500000000 35.384422302 32.233222961 -6.500000000 35.233222961 32.981101990 -6.500000000 34.981101990 -33.981101990 -5.500000000 34.981101990 -33.233226776 -5.500000000 35.233222961 -32.384422302 -5.500000000 35.384418488 -31.458978653 -5.500000000 35.458980560 -30.488407135 -5.500000000 35.488403320 -29.497472763 -5.500000000 35.497474670 -28.499593735 -5.500000000 35.499591827 -27.499954224 -5.500000000 35.499954224 -26.499996185 -5.500000000 35.499996185 -25.500000000 -5.500000000 35.500000000 -24.500000000 -5.500000000 35.500000000 -23.500000000 -5.500000000 35.500000000 -22.500000000 -5.500000000 35.500000000 -21.500000000 -5.500000000 35.500000000 -20.500000000 -5.500000000 35.500000000 -19.500000000 -5.500000000 35.500000000 -18.500000000 -5.500000000 35.500000000 -17.500000000 -5.500000000 35.500000000 -16.500000000 -5.500000000 35.500000000 -15.500000000 -5.500000000 35.500000000 -14.500000000 -5.500000000 35.500000000 -13.500000000 -5.500000000 35.500000000 -12.500000000 -5.500000000 35.500000000 -11.500000000 -5.500000000 35.500000000 -10.500000000 -5.500000000 35.500000000 -9.500000000 -5.500000000 35.500000000 -8.500000000 -5.500000000 35.500000000 -7.500000000 -5.500000000 35.500000000 -6.500000000 -5.500000000 35.500000000 -5.500000000 -5.500000000 35.500000000 -4.500000000 -5.500000000 35.500000000 -3.500000000 -5.500000000 35.500000000 -2.500000000 -5.500000000 35.500000000 -1.500000000 -5.500000000 35.500000000 -0.500000000 -5.500000000 35.500000000 0.500000000 -5.500000000 35.500000000 1.500000000 -5.500000000 35.500000000 2.500000000 -5.500000000 35.500000000 3.500000000 -5.500000000 35.500000000 4.500000000 -5.500000000 35.500000000 5.500000000 -5.500000000 35.500000000 6.500000000 -5.500000000 35.500000000 7.500000000 -5.500000000 35.500000000 8.500000000 -5.500000000 35.500000000 9.500000000 -5.500000000 35.500000000 10.500000000 -5.500000000 35.500000000 11.500000000 -5.500000000 35.500000000 12.500000000 -5.500000000 35.500000000 13.500000000 -5.500000000 35.500000000 14.500000000 -5.500000000 35.500000000 15.500000000 -5.500000000 35.500000000 16.500000000 -5.500000000 35.500000000 17.500000000 -5.500000000 35.500000000 18.500000000 -5.500000000 35.500000000 19.500000000 -5.500000000 35.500000000 20.500000000 -5.500000000 35.500000000 21.500000000 -5.500000000 35.500000000 22.500000000 -5.500000000 35.500000000 23.500000000 -5.500000000 35.500000000 24.500000000 -5.500000000 35.500000000 25.499996185 -5.500000000 35.499996185 26.499954224 -5.500000000 35.499954224 27.499591827 -5.500000000 35.499591827 28.497470856 -5.500000000 35.497467041 29.488407135 -5.500000000 35.488403320 30.458978653 -5.500000000 35.458980560 31.384418488 -5.500000000 35.384422302 32.233222961 -5.500000000 35.233222961 32.981101990 -5.500000000 34.981101990 -33.981101990 -4.500000000 34.981101990 -33.233226776 -4.500000000 35.233222961 -32.384422302 -4.500000000 35.384418488 -31.458978653 -4.500000000 35.458980560 -30.488407135 -4.500000000 35.488403320 -29.497472763 -4.500000000 35.497474670 -28.499593735 -4.500000000 35.499591827 -27.499954224 -4.500000000 35.499954224 -26.499996185 -4.500000000 35.499996185 -25.500000000 -4.500000000 35.500000000 -24.500000000 -4.500000000 35.500000000 -23.500000000 -4.500000000 35.500000000 -22.500000000 -4.500000000 35.500000000 -21.500000000 -4.500000000 35.500000000 -20.500000000 -4.500000000 35.500000000 -19.500000000 -4.500000000 35.500000000 -18.500000000 -4.500000000 35.500000000 -17.500000000 -4.500000000 35.500000000 -16.500000000 -4.500000000 35.500000000 -15.500000000 -4.500000000 35.500000000 -14.500000000 -4.500000000 35.500000000 -13.500000000 -4.500000000 35.500000000 -12.500000000 -4.500000000 35.500000000 -11.500000000 -4.500000000 35.500000000 -10.500000000 -4.500000000 35.500000000 -9.500000000 -4.500000000 35.500000000 -8.500000000 -4.500000000 35.500000000 -7.500000000 -4.500000000 35.500000000 -6.500000000 -4.500000000 35.500000000 -5.500000000 -4.500000000 35.500000000 -4.500000000 -4.500000000 35.500000000 -3.500000000 -4.500000000 35.500000000 -2.500000000 -4.500000000 35.500000000 -1.500000000 -4.500000000 35.500000000 -0.500000000 -4.500000000 35.500000000 0.500000000 -4.500000000 35.500000000 1.500000000 -4.500000000 35.500000000 2.500000000 -4.500000000 35.500000000 3.500000000 -4.500000000 35.500000000 4.500000000 -4.500000000 35.500000000 5.500000000 -4.500000000 35.500000000 6.500000000 -4.500000000 35.500000000 7.500000000 -4.500000000 35.500000000 8.500000000 -4.500000000 35.500000000 9.500000000 -4.500000000 35.500000000 10.500000000 -4.500000000 35.500000000 11.500000000 -4.500000000 35.500000000 12.500000000 -4.500000000 35.500000000 13.500000000 -4.500000000 35.500000000 14.500000000 -4.500000000 35.500000000 15.500000000 -4.500000000 35.500000000 16.500000000 -4.500000000 35.500000000 17.500000000 -4.500000000 35.500000000 18.500000000 -4.500000000 35.500000000 19.500000000 -4.500000000 35.500000000 20.500000000 -4.500000000 35.500000000 21.500000000 -4.500000000 35.500000000 22.500000000 -4.500000000 35.500000000 23.500000000 -4.500000000 35.500000000 24.500000000 -4.500000000 35.500000000 25.499996185 -4.500000000 35.499996185 26.499954224 -4.500000000 35.499954224 27.499591827 -4.500000000 35.499591827 28.497470856 -4.500000000 35.497467041 29.488407135 -4.500000000 35.488403320 30.458978653 -4.500000000 35.458980560 31.384418488 -4.500000000 35.384422302 32.233222961 -4.500000000 35.233222961 32.981101990 -4.500000000 34.981101990 -33.981101990 -3.500000000 34.981101990 -33.233226776 -3.500000000 35.233222961 -32.384422302 -3.500000000 35.384418488 -31.458978653 -3.500000000 35.458980560 -30.488407135 -3.500000000 35.488403320 -29.497472763 -3.500000000 35.497474670 -28.499593735 -3.500000000 35.499591827 -27.499954224 -3.500000000 35.499954224 -26.499996185 -3.500000000 35.499996185 -25.500000000 -3.500000000 35.500000000 -24.500000000 -3.500000000 35.500000000 -23.500000000 -3.500000000 35.500000000 -22.500000000 -3.500000000 35.500000000 -21.500000000 -3.500000000 35.500000000 -20.500000000 -3.500000000 35.500000000 -19.500000000 -3.500000000 35.500000000 -18.500000000 -3.500000000 35.500000000 -17.500000000 -3.500000000 35.500000000 -16.500000000 -3.500000000 35.500000000 -15.500000000 -3.500000000 35.500000000 -14.500000000 -3.500000000 35.500000000 -13.500000000 -3.500000000 35.500000000 -12.500000000 -3.500000000 35.500000000 -11.500000000 -3.500000000 35.500000000 -10.500000000 -3.500000000 35.500000000 -9.500000000 -3.500000000 35.500000000 -8.500000000 -3.500000000 35.500000000 -7.500000000 -3.500000000 35.500000000 -6.500000000 -3.500000000 35.500000000 -5.500000000 -3.500000000 35.500000000 -4.500000000 -3.500000000 35.500000000 -3.500000000 -3.500000000 35.500000000 -2.500000000 -3.500000000 35.500000000 -1.500000000 -3.500000000 35.500000000 -0.500000000 -3.500000000 35.500000000 0.500000000 -3.500000000 35.500000000 1.500000000 -3.500000000 35.500000000 2.500000000 -3.500000000 35.500000000 3.500000000 -3.500000000 35.500000000 4.500000000 -3.500000000 35.500000000 5.500000000 -3.500000000 35.500000000 6.500000000 -3.500000000 35.500000000 7.500000000 -3.500000000 35.500000000 8.500000000 -3.500000000 35.500000000 9.500000000 -3.500000000 35.500000000 10.500000000 -3.500000000 35.500000000 11.500000000 -3.500000000 35.500000000 12.500000000 -3.500000000 35.500000000 13.500000000 -3.500000000 35.500000000 14.500000000 -3.500000000 35.500000000 15.500000000 -3.500000000 35.500000000 16.500000000 -3.500000000 35.500000000 17.500000000 -3.500000000 35.500000000 18.500000000 -3.500000000 35.500000000 19.500000000 -3.500000000 35.500000000 20.500000000 -3.500000000 35.500000000 21.500000000 -3.500000000 35.500000000 22.500000000 -3.500000000 35.500000000 23.500000000 -3.500000000 35.500000000 24.500000000 -3.500000000 35.500000000 25.499996185 -3.500000000 35.499996185 26.499954224 -3.500000000 35.499954224 27.499591827 -3.500000000 35.499591827 28.497470856 -3.500000000 35.497467041 29.488407135 -3.500000000 35.488403320 30.458978653 -3.500000000 35.458980560 31.384418488 -3.500000000 35.384422302 32.233222961 -3.500000000 35.233222961 32.981101990 -3.500000000 34.981101990 -33.981101990 -2.500000000 34.981101990 -33.233226776 -2.500000000 35.233222961 -32.384422302 -2.500000000 35.384418488 -31.458978653 -2.500000000 35.458980560 -30.488407135 -2.500000000 35.488403320 -29.497472763 -2.500000000 35.497474670 -28.499593735 -2.500000000 35.499591827 -27.499954224 -2.500000000 35.499954224 -26.499996185 -2.500000000 35.499996185 -25.500000000 -2.500000000 35.500000000 -24.500000000 -2.500000000 35.500000000 -23.500000000 -2.500000000 35.500000000 -22.500000000 -2.500000000 35.500000000 -21.500000000 -2.500000000 35.500000000 -20.500000000 -2.500000000 35.500000000 -19.500000000 -2.500000000 35.500000000 -18.500000000 -2.500000000 35.500000000 -17.500000000 -2.500000000 35.500000000 -16.500000000 -2.500000000 35.500000000 -15.500000000 -2.500000000 35.500000000 -14.500000000 -2.500000000 35.500000000 -13.500000000 -2.500000000 35.500000000 -12.500000000 -2.500000000 35.500000000 -11.500000000 -2.500000000 35.500000000 -10.500000000 -2.500000000 35.500000000 -9.500000000 -2.500000000 35.500000000 -8.500000000 -2.500000000 35.500000000 -7.500000000 -2.500000000 35.500000000 -6.500000000 -2.500000000 35.500000000 -5.500000000 -2.500000000 35.500000000 -4.500000000 -2.500000000 35.500000000 -3.500000000 -2.500000000 35.500000000 -2.500000000 -2.500000000 35.500000000 -1.500000000 -2.500000000 35.500000000 -0.500000000 -2.500000000 35.500000000 0.500000000 -2.500000000 35.500000000 1.500000000 -2.500000000 35.500000000 2.500000000 -2.500000000 35.500000000 3.500000000 -2.500000000 35.500000000 4.500000000 -2.500000000 35.500000000 5.500000000 -2.500000000 35.500000000 6.500000000 -2.500000000 35.500000000 7.500000000 -2.500000000 35.500000000 8.500000000 -2.500000000 35.500000000 9.500000000 -2.500000000 35.500000000 10.500000000 -2.500000000 35.500000000 11.500000000 -2.500000000 35.500000000 12.500000000 -2.500000000 35.500000000 13.500000000 -2.500000000 35.500000000 14.500000000 -2.500000000 35.500000000 15.500000000 -2.500000000 35.500000000 16.500000000 -2.500000000 35.500000000 17.500000000 -2.500000000 35.500000000 18.500000000 -2.500000000 35.500000000 19.500000000 -2.500000000 35.500000000 20.500000000 -2.500000000 35.500000000 21.500000000 -2.500000000 35.500000000 22.500000000 -2.500000000 35.500000000 23.500000000 -2.500000000 35.500000000 24.500000000 -2.500000000 35.500000000 25.499996185 -2.500000000 35.499996185 26.499954224 -2.500000000 35.499954224 27.499591827 -2.500000000 35.499591827 28.497470856 -2.500000000 35.497467041 29.488407135 -2.500000000 35.488403320 30.458978653 -2.500000000 35.458980560 31.384418488 -2.500000000 35.384422302 32.233222961 -2.500000000 35.233222961 32.981101990 -2.500000000 34.981101990 -33.981101990 -1.500000000 34.981101990 -33.233226776 -1.500000000 35.233222961 -32.384422302 -1.500000000 35.384418488 -31.458978653 -1.500000000 35.458980560 -30.488407135 -1.500000000 35.488403320 -29.497472763 -1.500000000 35.497474670 -28.499593735 -1.500000000 35.499591827 -27.499954224 -1.500000000 35.499954224 -26.499996185 -1.500000000 35.499996185 -25.500000000 -1.500000000 35.500000000 -24.500000000 -1.500000000 35.500000000 -23.500000000 -1.500000000 35.500000000 -22.500000000 -1.500000000 35.500000000 -21.500000000 -1.500000000 35.500000000 -20.500000000 -1.500000000 35.500000000 -19.500000000 -1.500000000 35.500000000 -18.500000000 -1.500000000 35.500000000 -17.500000000 -1.500000000 35.500000000 -16.500000000 -1.500000000 35.500000000 -15.500000000 -1.500000000 35.500000000 -14.500000000 -1.500000000 35.500000000 -13.500000000 -1.500000000 35.500000000 -12.500000000 -1.500000000 35.500000000 -11.500000000 -1.500000000 35.500000000 -10.500000000 -1.500000000 35.500000000 -9.500000000 -1.500000000 35.500000000 -8.500000000 -1.500000000 35.500000000 -7.500000000 -1.500000000 35.500000000 -6.500000000 -1.500000000 35.500000000 -5.500000000 -1.500000000 35.500000000 -4.500000000 -1.500000000 35.500000000 -3.500000000 -1.500000000 35.500000000 -2.500000000 -1.500000000 35.500000000 -1.500000000 -1.500000000 35.500000000 -0.500000000 -1.500000000 35.500000000 0.500000000 -1.500000000 35.500000000 1.500000000 -1.500000000 35.500000000 2.500000000 -1.500000000 35.500000000 3.500000000 -1.500000000 35.500000000 4.500000000 -1.500000000 35.500000000 5.500000000 -1.500000000 35.500000000 6.500000000 -1.500000000 35.500000000 7.500000000 -1.500000000 35.500000000 8.500000000 -1.500000000 35.500000000 9.500000000 -1.500000000 35.500000000 10.500000000 -1.500000000 35.500000000 11.500000000 -1.500000000 35.500000000 12.500000000 -1.500000000 35.500000000 13.500000000 -1.500000000 35.500000000 14.500000000 -1.500000000 35.500000000 15.500000000 -1.500000000 35.500000000 16.500000000 -1.500000000 35.500000000 17.500000000 -1.500000000 35.500000000 18.500000000 -1.500000000 35.500000000 19.500000000 -1.500000000 35.500000000 20.500000000 -1.500000000 35.500000000 21.500000000 -1.500000000 35.500000000 22.500000000 -1.500000000 35.500000000 23.500000000 -1.500000000 35.500000000 24.500000000 -1.500000000 35.500000000 25.499996185 -1.500000000 35.499996185 26.499954224 -1.500000000 35.499954224 27.499591827 -1.500000000 35.499591827 28.497470856 -1.500000000 35.497467041 29.488407135 -1.500000000 35.488403320 30.458978653 -1.500000000 35.458980560 31.384418488 -1.500000000 35.384422302 32.233222961 -1.500000000 35.233222961 32.981101990 -1.500000000 34.981101990 -33.981101990 -0.500000000 34.981101990 -33.233226776 -0.500000000 35.233222961 -32.384422302 -0.500000000 35.384418488 -31.458978653 -0.500000000 35.458980560 -30.488407135 -0.500000000 35.488403320 -29.497472763 -0.500000000 35.497474670 -28.499593735 -0.500000000 35.499591827 -27.499954224 -0.500000000 35.499954224 -26.499996185 -0.500000000 35.499996185 -25.500000000 -0.500000000 35.500000000 -24.500000000 -0.500000000 35.500000000 -23.500000000 -0.500000000 35.500000000 -22.500000000 -0.500000000 35.500000000 -21.500000000 -0.500000000 35.500000000 -20.500000000 -0.500000000 35.500000000 -19.500000000 -0.500000000 35.500000000 -18.500000000 -0.500000000 35.500000000 -17.500000000 -0.500000000 35.500000000 -16.500000000 -0.500000000 35.500000000 -15.500000000 -0.500000000 35.500000000 -14.500000000 -0.500000000 35.500000000 -13.500000000 -0.500000000 35.500000000 -12.500000000 -0.500000000 35.500000000 -11.500000000 -0.500000000 35.500000000 -10.500000000 -0.500000000 35.500000000 -9.500000000 -0.500000000 35.500000000 -8.500000000 -0.500000000 35.500000000 -7.500000000 -0.500000000 35.500000000 -6.500000000 -0.500000000 35.500000000 -5.500000000 -0.500000000 35.500000000 -4.500000000 -0.500000000 35.500000000 -3.500000000 -0.500000000 35.500000000 -2.500000000 -0.500000000 35.500000000 -1.500000000 -0.500000000 35.500000000 -0.500000000 -0.500000000 35.500000000 0.500000000 -0.500000000 35.500000000 1.500000000 -0.500000000 35.500000000 2.500000000 -0.500000000 35.500000000 3.500000000 -0.500000000 35.500000000 4.500000000 -0.500000000 35.500000000 5.500000000 -0.500000000 35.500000000 6.500000000 -0.500000000 35.500000000 7.500000000 -0.500000000 35.500000000 8.500000000 -0.500000000 35.500000000 9.500000000 -0.500000000 35.500000000 10.500000000 -0.500000000 35.500000000 11.500000000 -0.500000000 35.500000000 12.500000000 -0.500000000 35.500000000 13.500000000 -0.500000000 35.500000000 14.500000000 -0.500000000 35.500000000 15.500000000 -0.500000000 35.500000000 16.500000000 -0.500000000 35.500000000 17.500000000 -0.500000000 35.500000000 18.500000000 -0.500000000 35.500000000 19.500000000 -0.500000000 35.500000000 20.500000000 -0.500000000 35.500000000 21.500000000 -0.500000000 35.500000000 22.500000000 -0.500000000 35.500000000 23.500000000 -0.500000000 35.500000000 24.500000000 -0.500000000 35.500000000 25.499996185 -0.500000000 35.499996185 26.499954224 -0.500000000 35.499954224 27.499591827 -0.500000000 35.499591827 28.497470856 -0.500000000 35.497467041 29.488407135 -0.500000000 35.488403320 30.458978653 -0.500000000 35.458980560 31.384418488 -0.500000000 35.384422302 32.233222961 -0.500000000 35.233222961 32.981101990 -0.500000000 34.981101990 -33.981101990 0.500000000 34.981101990 -33.233226776 0.500000000 35.233222961 -32.384422302 0.500000000 35.384418488 -31.458978653 0.500000000 35.458980560 -30.488407135 0.500000000 35.488403320 -29.497472763 0.500000000 35.497474670 -28.499593735 0.500000000 35.499591827 -27.499954224 0.500000000 35.499954224 -26.499996185 0.500000000 35.499996185 -25.500000000 0.500000000 35.500000000 -24.500000000 0.500000000 35.500000000 -23.500000000 0.500000000 35.500000000 -22.500000000 0.500000000 35.500000000 -21.500000000 0.500000000 35.500000000 -20.500000000 0.500000000 35.500000000 -19.500000000 0.500000000 35.500000000 -18.500000000 0.500000000 35.500000000 -17.500000000 0.500000000 35.500000000 -16.500000000 0.500000000 35.500000000 -15.500000000 0.500000000 35.500000000 -14.500000000 0.500000000 35.500000000 -13.500000000 0.500000000 35.500000000 -12.500000000 0.500000000 35.500000000 -11.500000000 0.500000000 35.500000000 -10.500000000 0.500000000 35.500000000 -9.500000000 0.500000000 35.500000000 -8.500000000 0.500000000 35.500000000 -7.500000000 0.500000000 35.500000000 -6.500000000 0.500000000 35.500000000 -5.500000000 0.500000000 35.500000000 -4.500000000 0.500000000 35.500000000 -3.500000000 0.500000000 35.500000000 -2.500000000 0.500000000 35.500000000 -1.500000000 0.500000000 35.500000000 -0.500000000 0.500000000 35.500000000 0.500000000 0.500000000 35.500000000 1.500000000 0.500000000 35.500000000 2.500000000 0.500000000 35.500000000 3.500000000 0.500000000 35.500000000 4.500000000 0.500000000 35.500000000 5.500000000 0.500000000 35.500000000 6.500000000 0.500000000 35.500000000 7.500000000 0.500000000 35.500000000 8.500000000 0.500000000 35.500000000 9.500000000 0.500000000 35.500000000 10.500000000 0.500000000 35.500000000 11.500000000 0.500000000 35.500000000 12.500000000 0.500000000 35.500000000 13.500000000 0.500000000 35.500000000 14.500000000 0.500000000 35.500000000 15.500000000 0.500000000 35.500000000 16.500000000 0.500000000 35.500000000 17.500000000 0.500000000 35.500000000 18.500000000 0.500000000 35.500000000 19.500000000 0.500000000 35.500000000 20.500000000 0.500000000 35.500000000 21.500000000 0.500000000 35.500000000 22.500000000 0.500000000 35.500000000 23.500000000 0.500000000 35.500000000 24.500000000 0.500000000 35.500000000 25.499996185 0.500000000 35.499996185 26.499954224 0.500000000 35.499954224 27.499591827 0.500000000 35.499591827 28.497470856 0.500000000 35.497467041 29.488407135 0.500000000 35.488403320 30.458978653 0.500000000 35.458980560 31.384418488 0.500000000 35.384422302 32.233222961 0.500000000 35.233222961 32.981101990 0.500000000 34.981101990 -33.981101990 1.500000000 34.981101990 -33.233226776 1.500000000 35.233222961 -32.384422302 1.500000000 35.384418488 -31.458978653 1.500000000 35.458980560 -30.488407135 1.500000000 35.488403320 -29.497472763 1.500000000 35.497474670 -28.499593735 1.500000000 35.499591827 -27.499954224 1.500000000 35.499954224 -26.499996185 1.500000000 35.499996185 -25.500000000 1.500000000 35.500000000 -24.500000000 1.500000000 35.500000000 -23.500000000 1.500000000 35.500000000 -22.500000000 1.500000000 35.500000000 -21.500000000 1.500000000 35.500000000 -20.500000000 1.500000000 35.500000000 -19.500000000 1.500000000 35.500000000 -18.500000000 1.500000000 35.500000000 -17.500000000 1.500000000 35.500000000 -16.500000000 1.500000000 35.500000000 -15.500000000 1.500000000 35.500000000 -14.500000000 1.500000000 35.500000000 -13.500000000 1.500000000 35.500000000 -12.500000000 1.500000000 35.500000000 -11.500000000 1.500000000 35.500000000 -10.500000000 1.500000000 35.500000000 -9.500000000 1.500000000 35.500000000 -8.500000000 1.500000000 35.500000000 -7.500000000 1.500000000 35.500000000 -6.500000000 1.500000000 35.500000000 -5.500000000 1.500000000 35.500000000 -4.500000000 1.500000000 35.500000000 -3.500000000 1.500000000 35.500000000 -2.500000000 1.500000000 35.500000000 -1.500000000 1.500000000 35.500000000 -0.500000000 1.500000000 35.500000000 0.500000000 1.500000000 35.500000000 1.500000000 1.500000000 35.500000000 2.500000000 1.500000000 35.500000000 3.500000000 1.500000000 35.500000000 4.500000000 1.500000000 35.500000000 5.500000000 1.500000000 35.500000000 6.500000000 1.500000000 35.500000000 7.500000000 1.500000000 35.500000000 8.500000000 1.500000000 35.500000000 9.500000000 1.500000000 35.500000000 10.500000000 1.500000000 35.500000000 11.500000000 1.500000000 35.500000000 12.500000000 1.500000000 35.500000000 13.500000000 1.500000000 35.500000000 14.500000000 1.500000000 35.500000000 15.500000000 1.500000000 35.500000000 16.500000000 1.500000000 35.500000000 17.500000000 1.500000000 35.500000000 18.500000000 1.500000000 35.500000000 19.500000000 1.500000000 35.500000000 20.500000000 1.500000000 35.500000000 21.500000000 1.500000000 35.500000000 22.500000000 1.500000000 35.500000000 23.500000000 1.500000000 35.500000000 24.500000000 1.500000000 35.500000000 25.499996185 1.500000000 35.499996185 26.499954224 1.500000000 35.499954224 27.499591827 1.500000000 35.499591827 28.497470856 1.500000000 35.497467041 29.488407135 1.500000000 35.488403320 30.458978653 1.500000000 35.458980560 31.384418488 1.500000000 35.384422302 32.233222961 1.500000000 35.233222961 32.981101990 1.500000000 34.981101990 -33.981101990 2.500000000 34.981101990 -33.233226776 2.500000000 35.233222961 -32.384422302 2.500000000 35.384418488 -31.458978653 2.500000000 35.458980560 -30.488407135 2.500000000 35.488403320 -29.497472763 2.500000000 35.497474670 -28.499593735 2.500000000 35.499591827 -27.499954224 2.500000000 35.499954224 -26.499996185 2.500000000 35.499996185 -25.500000000 2.500000000 35.500000000 -24.500000000 2.500000000 35.500000000 -23.500000000 2.500000000 35.500000000 -22.500000000 2.500000000 35.500000000 -21.500000000 2.500000000 35.500000000 -20.500000000 2.500000000 35.500000000 -19.500000000 2.500000000 35.500000000 -18.500000000 2.500000000 35.500000000 -17.500000000 2.500000000 35.500000000 -16.500000000 2.500000000 35.500000000 -15.500000000 2.500000000 35.500000000 -14.500000000 2.500000000 35.500000000 -13.500000000 2.500000000 35.500000000 -12.500000000 2.500000000 35.500000000 -11.500000000 2.500000000 35.500000000 -10.500000000 2.500000000 35.500000000 -9.500000000 2.500000000 35.500000000 -8.500000000 2.500000000 35.500000000 -7.500000000 2.500000000 35.500000000 -6.500000000 2.500000000 35.500000000 -5.500000000 2.500000000 35.500000000 -4.500000000 2.500000000 35.500000000 -3.500000000 2.500000000 35.500000000 -2.500000000 2.500000000 35.500000000 -1.500000000 2.500000000 35.500000000 -0.500000000 2.500000000 35.500000000 0.500000000 2.500000000 35.500000000 1.500000000 2.500000000 35.500000000 2.500000000 2.500000000 35.500000000 3.500000000 2.500000000 35.500000000 4.500000000 2.500000000 35.500000000 5.500000000 2.500000000 35.500000000 6.500000000 2.500000000 35.500000000 7.500000000 2.500000000 35.500000000 8.500000000 2.500000000 35.500000000 9.500000000 2.500000000 35.500000000 10.500000000 2.500000000 35.500000000 11.500000000 2.500000000 35.500000000 12.500000000 2.500000000 35.500000000 13.500000000 2.500000000 35.500000000 14.500000000 2.500000000 35.500000000 15.500000000 2.500000000 35.500000000 16.500000000 2.500000000 35.500000000 17.500000000 2.500000000 35.500000000 18.500000000 2.500000000 35.500000000 19.500000000 2.500000000 35.500000000 20.500000000 2.500000000 35.500000000 21.500000000 2.500000000 35.500000000 22.500000000 2.500000000 35.500000000 23.500000000 2.500000000 35.500000000 24.500000000 2.500000000 35.500000000 25.499996185 2.500000000 35.499996185 26.499954224 2.500000000 35.499954224 27.499591827 2.500000000 35.499591827 28.497470856 2.500000000 35.497467041 29.488407135 2.500000000 35.488403320 30.458978653 2.500000000 35.458980560 31.384418488 2.500000000 35.384422302 32.233222961 2.500000000 35.233222961 32.981101990 2.500000000 34.981101990 -33.981101990 3.500000000 34.981101990 -33.233226776 3.500000000 35.233222961 -32.384422302 3.500000000 35.384418488 -31.458978653 3.500000000 35.458980560 -30.488407135 3.500000000 35.488403320 -29.497472763 3.500000000 35.497474670 -28.499593735 3.500000000 35.499591827 -27.499954224 3.500000000 35.499954224 -26.499996185 3.500000000 35.499996185 -25.500000000 3.500000000 35.500000000 -24.500000000 3.500000000 35.500000000 -23.500000000 3.500000000 35.500000000 -22.500000000 3.500000000 35.500000000 -21.500000000 3.500000000 35.500000000 -20.500000000 3.500000000 35.500000000 -19.500000000 3.500000000 35.500000000 -18.500000000 3.500000000 35.500000000 -17.500000000 3.500000000 35.500000000 -16.500000000 3.500000000 35.500000000 -15.500000000 3.500000000 35.500000000 -14.500000000 3.500000000 35.500000000 -13.500000000 3.500000000 35.500000000 -12.500000000 3.500000000 35.500000000 -11.500000000 3.500000000 35.500000000 -10.500000000 3.500000000 35.500000000 -9.500000000 3.500000000 35.500000000 -8.500000000 3.500000000 35.500000000 -7.500000000 3.500000000 35.500000000 -6.500000000 3.500000000 35.500000000 -5.500000000 3.500000000 35.500000000 -4.500000000 3.500000000 35.500000000 -3.500000000 3.500000000 35.500000000 -2.500000000 3.500000000 35.500000000 -1.500000000 3.500000000 35.500000000 -0.500000000 3.500000000 35.500000000 0.500000000 3.500000000 35.500000000 1.500000000 3.500000000 35.500000000 2.500000000 3.500000000 35.500000000 3.500000000 3.500000000 35.500000000 4.500000000 3.500000000 35.500000000 5.500000000 3.500000000 35.500000000 6.500000000 3.500000000 35.500000000 7.500000000 3.500000000 35.500000000 8.500000000 3.500000000 35.500000000 9.500000000 3.500000000 35.500000000 10.500000000 3.500000000 35.500000000 11.500000000 3.500000000 35.500000000 12.500000000 3.500000000 35.500000000 13.500000000 3.500000000 35.500000000 14.500000000 3.500000000 35.500000000 15.500000000 3.500000000 35.500000000 16.500000000 3.500000000 35.500000000 17.500000000 3.500000000 35.500000000 18.500000000 3.500000000 35.500000000 19.500000000 3.500000000 35.500000000 20.500000000 3.500000000 35.500000000 21.500000000 3.500000000 35.500000000 22.500000000 3.500000000 35.500000000 23.500000000 3.500000000 35.500000000 24.500000000 3.500000000 35.500000000 25.499996185 3.500000000 35.499996185 26.499954224 3.500000000 35.499954224 27.499591827 3.500000000 35.499591827 28.497470856 3.500000000 35.497467041 29.488407135 3.500000000 35.488403320 30.458978653 3.500000000 35.458980560 31.384418488 3.500000000 35.384422302 32.233222961 3.500000000 35.233222961 32.981101990 3.500000000 34.981101990 -33.981101990 4.500000000 34.981101990 -33.233226776 4.500000000 35.233222961 -32.384422302 4.500000000 35.384418488 -31.458978653 4.500000000 35.458980560 -30.488407135 4.500000000 35.488403320 -29.497472763 4.500000000 35.497474670 -28.499593735 4.500000000 35.499591827 -27.499954224 4.500000000 35.499954224 -26.499996185 4.500000000 35.499996185 -25.500000000 4.500000000 35.500000000 -24.500000000 4.500000000 35.500000000 -23.500000000 4.500000000 35.500000000 -22.500000000 4.500000000 35.500000000 -21.500000000 4.500000000 35.500000000 -20.500000000 4.500000000 35.500000000 -19.500000000 4.500000000 35.500000000 -18.500000000 4.500000000 35.500000000 -17.500000000 4.500000000 35.500000000 -16.500000000 4.500000000 35.500000000 -15.500000000 4.500000000 35.500000000 -14.500000000 4.500000000 35.500000000 -13.500000000 4.500000000 35.500000000 -12.500000000 4.500000000 35.500000000 -11.500000000 4.500000000 35.500000000 -10.500000000 4.500000000 35.500000000 -9.500000000 4.500000000 35.500000000 -8.500000000 4.500000000 35.500000000 -7.500000000 4.500000000 35.500000000 -6.500000000 4.500000000 35.500000000 -5.500000000 4.500000000 35.500000000 -4.500000000 4.500000000 35.500000000 -3.500000000 4.500000000 35.500000000 -2.500000000 4.500000000 35.500000000 -1.500000000 4.500000000 35.500000000 -0.500000000 4.500000000 35.500000000 0.500000000 4.500000000 35.500000000 1.500000000 4.500000000 35.500000000 2.500000000 4.500000000 35.500000000 3.500000000 4.500000000 35.500000000 4.500000000 4.500000000 35.500000000 5.500000000 4.500000000 35.500000000 6.500000000 4.500000000 35.500000000 7.500000000 4.500000000 35.500000000 8.500000000 4.500000000 35.500000000 9.500000000 4.500000000 35.500000000 10.500000000 4.500000000 35.500000000 11.500000000 4.500000000 35.500000000 12.500000000 4.500000000 35.500000000 13.500000000 4.500000000 35.500000000 14.500000000 4.500000000 35.500000000 15.500000000 4.500000000 35.500000000 16.500000000 4.500000000 35.500000000 17.500000000 4.500000000 35.500000000 18.500000000 4.500000000 35.500000000 19.500000000 4.500000000 35.500000000 20.500000000 4.500000000 35.500000000 21.500000000 4.500000000 35.500000000 22.500000000 4.500000000 35.500000000 23.500000000 4.500000000 35.500000000 24.500000000 4.500000000 35.500000000 25.499996185 4.500000000 35.499996185 26.499954224 4.500000000 35.499954224 27.499591827 4.500000000 35.499591827 28.497470856 4.500000000 35.497467041 29.488407135 4.500000000 35.488403320 30.458978653 4.500000000 35.458980560 31.384418488 4.500000000 35.384422302 32.233222961 4.500000000 35.233222961 32.981101990 4.500000000 34.981101990 -33.981101990 5.500000000 34.981101990 -33.233226776 5.500000000 35.233222961 -32.384422302 5.500000000 35.384418488 -31.458978653 5.500000000 35.458980560 -30.488407135 5.500000000 35.488403320 -29.497472763 5.500000000 35.497474670 -28.499593735 5.500000000 35.499591827 -27.499954224 5.500000000 35.499954224 -26.499996185 5.500000000 35.499996185 -25.500000000 5.500000000 35.500000000 -24.500000000 5.500000000 35.500000000 -23.500000000 5.500000000 35.500000000 -22.500000000 5.500000000 35.500000000 -21.500000000 5.500000000 35.500000000 -20.500000000 5.500000000 35.500000000 -19.500000000 5.500000000 35.500000000 -18.500000000 5.500000000 35.500000000 -17.500000000 5.500000000 35.500000000 -16.500000000 5.500000000 35.500000000 -15.500000000 5.500000000 35.500000000 -14.500000000 5.500000000 35.500000000 -13.500000000 5.500000000 35.500000000 -12.500000000 5.500000000 35.500000000 -11.500000000 5.500000000 35.500000000 -10.500000000 5.500000000 35.500000000 -9.500000000 5.500000000 35.500000000 -8.500000000 5.500000000 35.500000000 -7.500000000 5.500000000 35.500000000 -6.500000000 5.500000000 35.500000000 -5.500000000 5.500000000 35.500000000 -4.500000000 5.500000000 35.500000000 -3.500000000 5.500000000 35.500000000 -2.500000000 5.500000000 35.500000000 -1.500000000 5.500000000 35.500000000 -0.500000000 5.500000000 35.500000000 0.500000000 5.500000000 35.500000000 1.500000000 5.500000000 35.500000000 2.500000000 5.500000000 35.500000000 3.500000000 5.500000000 35.500000000 4.500000000 5.500000000 35.500000000 5.500000000 5.500000000 35.500000000 6.500000000 5.500000000 35.500000000 7.500000000 5.500000000 35.500000000 8.500000000 5.500000000 35.500000000 9.500000000 5.500000000 35.500000000 10.500000000 5.500000000 35.500000000 11.500000000 5.500000000 35.500000000 12.500000000 5.500000000 35.500000000 13.500000000 5.500000000 35.500000000 14.500000000 5.500000000 35.500000000 15.500000000 5.500000000 35.500000000 16.500000000 5.500000000 35.500000000 17.500000000 5.500000000 35.500000000 18.500000000 5.500000000 35.500000000 19.500000000 5.500000000 35.500000000 20.500000000 5.500000000 35.500000000 21.500000000 5.500000000 35.500000000 22.500000000 5.500000000 35.500000000 23.500000000 5.500000000 35.500000000 24.500000000 5.500000000 35.500000000 25.499996185 5.500000000 35.499996185 26.499954224 5.500000000 35.499954224 27.499591827 5.500000000 35.499591827 28.497470856 5.500000000 35.497467041 29.488407135 5.500000000 35.488403320 30.458978653 5.500000000 35.458980560 31.384418488 5.500000000 35.384422302 32.233222961 5.500000000 35.233222961 32.981101990 5.500000000 34.981101990 -33.981101990 6.500000000 34.981101990 -33.233226776 6.500000000 35.233222961 -32.384422302 6.500000000 35.384418488 -31.458978653 6.500000000 35.458980560 -30.488407135 6.500000000 35.488403320 -29.497472763 6.500000000 35.497474670 -28.499593735 6.500000000 35.499591827 -27.499954224 6.500000000 35.499954224 -26.499996185 6.500000000 35.499996185 -25.500000000 6.500000000 35.500000000 -24.500000000 6.500000000 35.500000000 -23.500000000 6.500000000 35.500000000 -22.500000000 6.500000000 35.500000000 -21.500000000 6.500000000 35.500000000 -20.500000000 6.500000000 35.500000000 -19.500000000 6.500000000 35.500000000 -18.500000000 6.500000000 35.500000000 -17.500000000 6.500000000 35.500000000 -16.500000000 6.500000000 35.500000000 -15.500000000 6.500000000 35.500000000 -14.500000000 6.500000000 35.500000000 -13.500000000 6.500000000 35.500000000 -12.500000000 6.500000000 35.500000000 -11.500000000 6.500000000 35.500000000 -10.500000000 6.500000000 35.500000000 -9.500000000 6.500000000 35.500000000 -8.500000000 6.500000000 35.500000000 -7.500000000 6.500000000 35.500000000 -6.500000000 6.500000000 35.500000000 -5.500000000 6.500000000 35.500000000 -4.500000000 6.500000000 35.500000000 -3.500000000 6.500000000 35.500000000 -2.500000000 6.500000000 35.500000000 -1.500000000 6.500000000 35.500000000 -0.500000000 6.500000000 35.500000000 0.500000000 6.500000000 35.500000000 1.500000000 6.500000000 35.500000000 2.500000000 6.500000000 35.500000000 3.500000000 6.500000000 35.500000000 4.500000000 6.500000000 35.500000000 5.500000000 6.500000000 35.500000000 6.500000000 6.500000000 35.500000000 7.500000000 6.500000000 35.500000000 8.500000000 6.500000000 35.500000000 9.500000000 6.500000000 35.500000000 10.500000000 6.500000000 35.500000000 11.500000000 6.500000000 35.500000000 12.500000000 6.500000000 35.500000000 13.500000000 6.500000000 35.500000000 14.500000000 6.500000000 35.500000000 15.500000000 6.500000000 35.500000000 16.500000000 6.500000000 35.500000000 17.500000000 6.500000000 35.500000000 18.500000000 6.500000000 35.500000000 19.500000000 6.500000000 35.500000000 20.500000000 6.500000000 35.500000000 21.500000000 6.500000000 35.500000000 22.500000000 6.500000000 35.500000000 23.500000000 6.500000000 35.500000000 24.500000000 6.500000000 35.500000000 25.499996185 6.500000000 35.499996185 26.499954224 6.500000000 35.499954224 27.499591827 6.500000000 35.499591827 28.497470856 6.500000000 35.497467041 29.488407135 6.500000000 35.488403320 30.458978653 6.500000000 35.458980560 31.384418488 6.500000000 35.384422302 32.233222961 6.500000000 35.233222961 32.981101990 6.500000000 34.981101990 -33.981101990 7.500000000 34.981101990 -33.233226776 7.500000000 35.233222961 -32.384422302 7.500000000 35.384418488 -31.458978653 7.500000000 35.458980560 -30.488407135 7.500000000 35.488403320 -29.497472763 7.500000000 35.497474670 -28.499593735 7.500000000 35.499591827 -27.499954224 7.500000000 35.499954224 -26.499996185 7.500000000 35.499996185 -25.500000000 7.500000000 35.500000000 -24.500000000 7.500000000 35.500000000 -23.500000000 7.500000000 35.500000000 -22.500000000 7.500000000 35.500000000 -21.500000000 7.500000000 35.500000000 -20.500000000 7.500000000 35.500000000 -19.500000000 7.500000000 35.500000000 -18.500000000 7.500000000 35.500000000 -17.500000000 7.500000000 35.500000000 -16.500000000 7.500000000 35.500000000 -15.500000000 7.500000000 35.500000000 -14.500000000 7.500000000 35.500000000 -13.500000000 7.500000000 35.500000000 -12.500000000 7.500000000 35.500000000 -11.500000000 7.500000000 35.500000000 -10.500000000 7.500000000 35.500000000 -9.500000000 7.500000000 35.500000000 -8.500000000 7.500000000 35.500000000 -7.500000000 7.500000000 35.500000000 -6.500000000 7.500000000 35.500000000 -5.500000000 7.500000000 35.500000000 -4.500000000 7.500000000 35.500000000 -3.500000000 7.500000000 35.500000000 -2.500000000 7.500000000 35.500000000 -1.500000000 7.500000000 35.500000000 -0.500000000 7.500000000 35.500000000 0.500000000 7.500000000 35.500000000 1.500000000 7.500000000 35.500000000 2.500000000 7.500000000 35.500000000 3.500000000 7.500000000 35.500000000 4.500000000 7.500000000 35.500000000 5.500000000 7.500000000 35.500000000 6.500000000 7.500000000 35.500000000 7.500000000 7.500000000 35.500000000 8.500000000 7.500000000 35.500000000 9.500000000 7.500000000 35.500000000 10.500000000 7.500000000 35.500000000 11.500000000 7.500000000 35.500000000 12.500000000 7.500000000 35.500000000 13.500000000 7.500000000 35.500000000 14.500000000 7.500000000 35.500000000 15.500000000 7.500000000 35.500000000 16.500000000 7.500000000 35.500000000 17.500000000 7.500000000 35.500000000 18.500000000 7.500000000 35.500000000 19.500000000 7.500000000 35.500000000 20.500000000 7.500000000 35.500000000 21.500000000 7.500000000 35.500000000 22.500000000 7.500000000 35.500000000 23.500000000 7.500000000 35.500000000 24.500000000 7.500000000 35.500000000 25.499996185 7.500000000 35.499996185 26.499954224 7.500000000 35.499954224 27.499591827 7.500000000 35.499591827 28.497470856 7.500000000 35.497467041 29.488407135 7.500000000 35.488403320 30.458978653 7.500000000 35.458980560 31.384418488 7.500000000 35.384422302 32.233222961 7.500000000 35.233222961 32.981101990 7.500000000 34.981101990 -33.981101990 8.500000000 34.981101990 -33.233226776 8.500000000 35.233222961 -32.384422302 8.500000000 35.384418488 -31.458978653 8.500000000 35.458980560 -30.488407135 8.500000000 35.488403320 -29.497472763 8.500000000 35.497474670 -28.499593735 8.500000000 35.499591827 -27.499954224 8.500000000 35.499954224 -26.499996185 8.500000000 35.499996185 -25.500000000 8.500000000 35.500000000 -24.500000000 8.500000000 35.500000000 -23.500000000 8.500000000 35.500000000 -22.500000000 8.500000000 35.500000000 -21.500000000 8.500000000 35.500000000 -20.500000000 8.500000000 35.500000000 -19.500000000 8.500000000 35.500000000 -18.500000000 8.500000000 35.500000000 -17.500000000 8.500000000 35.500000000 -16.500000000 8.500000000 35.500000000 -15.500000000 8.500000000 35.500000000 -14.500000000 8.500000000 35.500000000 -13.500000000 8.500000000 35.500000000 -12.500000000 8.500000000 35.500000000 -11.500000000 8.500000000 35.500000000 -10.500000000 8.500000000 35.500000000 -9.500000000 8.500000000 35.500000000 -8.500000000 8.500000000 35.500000000 -7.500000000 8.500000000 35.500000000 -6.500000000 8.500000000 35.500000000 -5.500000000 8.500000000 35.500000000 -4.500000000 8.500000000 35.500000000 -3.500000000 8.500000000 35.500000000 -2.500000000 8.500000000 35.500000000 -1.500000000 8.500000000 35.500000000 -0.500000000 8.500000000 35.500000000 0.500000000 8.500000000 35.500000000 1.500000000 8.500000000 35.500000000 2.500000000 8.500000000 35.500000000 3.500000000 8.500000000 35.500000000 4.500000000 8.500000000 35.500000000 5.500000000 8.500000000 35.500000000 6.500000000 8.500000000 35.500000000 7.500000000 8.500000000 35.500000000 8.500000000 8.500000000 35.500000000 9.500000000 8.500000000 35.500000000 10.500000000 8.500000000 35.500000000 11.500000000 8.500000000 35.500000000 12.500000000 8.500000000 35.500000000 13.500000000 8.500000000 35.500000000 14.500000000 8.500000000 35.500000000 15.500000000 8.500000000 35.500000000 16.500000000 8.500000000 35.500000000 17.500000000 8.500000000 35.500000000 18.500000000 8.500000000 35.500000000 19.500000000 8.500000000 35.500000000 20.500000000 8.500000000 35.500000000 21.500000000 8.500000000 35.500000000 22.500000000 8.500000000 35.500000000 23.500000000 8.500000000 35.500000000 24.500000000 8.500000000 35.500000000 25.499996185 8.500000000 35.499996185 26.499954224 8.500000000 35.499954224 27.499591827 8.500000000 35.499591827 28.497470856 8.500000000 35.497467041 29.488407135 8.500000000 35.488403320 30.458978653 8.500000000 35.458980560 31.384418488 8.500000000 35.384422302 32.233222961 8.500000000 35.233222961 32.981101990 8.500000000 34.981101990 -33.981101990 9.500000000 34.981101990 -33.233226776 9.500000000 35.233222961 -32.384422302 9.500000000 35.384418488 -31.458978653 9.500000000 35.458980560 -30.488407135 9.500000000 35.488403320 -29.497472763 9.500000000 35.497474670 -28.499593735 9.500000000 35.499591827 -27.499954224 9.500000000 35.499954224 -26.499996185 9.500000000 35.499996185 -25.500000000 9.500000000 35.500000000 -24.500000000 9.500000000 35.500000000 -23.500000000 9.500000000 35.500000000 -22.500000000 9.500000000 35.500000000 -21.500000000 9.500000000 35.500000000 -20.500000000 9.500000000 35.500000000 -19.500000000 9.500000000 35.500000000 -18.500000000 9.500000000 35.500000000 -17.500000000 9.500000000 35.500000000 -16.500000000 9.500000000 35.500000000 -15.500000000 9.500000000 35.500000000 -14.500000000 9.500000000 35.500000000 -13.500000000 9.500000000 35.500000000 -12.500000000 9.500000000 35.500000000 -11.500000000 9.500000000 35.500000000 -10.500000000 9.500000000 35.500000000 -9.500000000 9.500000000 35.500000000 -8.500000000 9.500000000 35.500000000 -7.500000000 9.500000000 35.500000000 -6.500000000 9.500000000 35.500000000 -5.500000000 9.500000000 35.500000000 -4.500000000 9.500000000 35.500000000 -3.500000000 9.500000000 35.500000000 -2.500000000 9.500000000 35.500000000 -1.500000000 9.500000000 35.500000000 -0.500000000 9.500000000 35.500000000 0.500000000 9.500000000 35.500000000 1.500000000 9.500000000 35.500000000 2.500000000 9.500000000 35.500000000 3.500000000 9.500000000 35.500000000 4.500000000 9.500000000 35.500000000 5.500000000 9.500000000 35.500000000 6.500000000 9.500000000 35.500000000 7.500000000 9.500000000 35.500000000 8.500000000 9.500000000 35.500000000 9.500000000 9.500000000 35.500000000 10.500000000 9.500000000 35.500000000 11.500000000 9.500000000 35.500000000 12.500000000 9.500000000 35.500000000 13.500000000 9.500000000 35.500000000 14.500000000 9.500000000 35.500000000 15.500000000 9.500000000 35.500000000 16.500000000 9.500000000 35.500000000 17.500000000 9.500000000 35.500000000 18.500000000 9.500000000 35.500000000 19.500000000 9.500000000 35.500000000 20.500000000 9.500000000 35.500000000 21.500000000 9.500000000 35.500000000 22.500000000 9.500000000 35.500000000 23.500000000 9.500000000 35.500000000 24.500000000 9.500000000 35.500000000 25.499996185 9.500000000 35.499996185 26.499954224 9.500000000 35.499954224 27.499591827 9.500000000 35.499591827 28.497470856 9.500000000 35.497467041 29.488407135 9.500000000 35.488403320 30.458978653 9.500000000 35.458980560 31.384418488 9.500000000 35.384422302 32.233222961 9.500000000 35.233222961 32.981101990 9.500000000 34.981101990 -33.981101990 10.500000000 34.981101990 -33.233226776 10.500000000 35.233222961 -32.384422302 10.500000000 35.384418488 -31.458978653 10.500000000 35.458980560 -30.488407135 10.500000000 35.488403320 -29.497472763 10.500000000 35.497474670 -28.499593735 10.500000000 35.499591827 -27.499954224 10.500000000 35.499954224 -26.499996185 10.500000000 35.499996185 -25.500000000 10.500000000 35.500000000 -24.500000000 10.500000000 35.500000000 -23.500000000 10.500000000 35.500000000 -22.500000000 10.500000000 35.500000000 -21.500000000 10.500000000 35.500000000 -20.500000000 10.500000000 35.500000000 -19.500000000 10.500000000 35.500000000 -18.500000000 10.500000000 35.500000000 -17.500000000 10.500000000 35.500000000 -16.500000000 10.500000000 35.500000000 -15.500000000 10.500000000 35.500000000 -14.500000000 10.500000000 35.500000000 -13.500000000 10.500000000 35.500000000 -12.500000000 10.500000000 35.500000000 -11.500000000 10.500000000 35.500000000 -10.500000000 10.500000000 35.500000000 -9.500000000 10.500000000 35.500000000 -8.500000000 10.500000000 35.500000000 -7.500000000 10.500000000 35.500000000 -6.500000000 10.500000000 35.500000000 -5.500000000 10.500000000 35.500000000 -4.500000000 10.500000000 35.500000000 -3.500000000 10.500000000 35.500000000 -2.500000000 10.500000000 35.500000000 -1.500000000 10.500000000 35.500000000 -0.500000000 10.500000000 35.500000000 0.500000000 10.500000000 35.500000000 1.500000000 10.500000000 35.500000000 2.500000000 10.500000000 35.500000000 3.500000000 10.500000000 35.500000000 4.500000000 10.500000000 35.500000000 5.500000000 10.500000000 35.500000000 6.500000000 10.500000000 35.500000000 7.500000000 10.500000000 35.500000000 8.500000000 10.500000000 35.500000000 9.500000000 10.500000000 35.500000000 10.500000000 10.500000000 35.500000000 11.500000000 10.500000000 35.500000000 12.500000000 10.500000000 35.500000000 13.500000000 10.500000000 35.500000000 14.500000000 10.500000000 35.500000000 15.500000000 10.500000000 35.500000000 16.500000000 10.500000000 35.500000000 17.500000000 10.500000000 35.500000000 18.500000000 10.500000000 35.500000000 19.500000000 10.500000000 35.500000000 20.500000000 10.500000000 35.500000000 21.500000000 10.500000000 35.500000000 22.500000000 10.500000000 35.500000000 23.500000000 10.500000000 35.500000000 24.500000000 10.500000000 35.500000000 25.499996185 10.500000000 35.499996185 26.499954224 10.500000000 35.499954224 27.499591827 10.500000000 35.499591827 28.497470856 10.500000000 35.497467041 29.488407135 10.500000000 35.488403320 30.458978653 10.500000000 35.458980560 31.384418488 10.500000000 35.384422302 32.233222961 10.500000000 35.233222961 32.981101990 10.500000000 34.981101990 -33.981101990 11.500000000 34.981101990 -33.233226776 11.500000000 35.233222961 -32.384422302 11.500000000 35.384418488 -31.458978653 11.500000000 35.458980560 -30.488407135 11.500000000 35.488403320 -29.497472763 11.500000000 35.497474670 -28.499593735 11.500000000 35.499591827 -27.499954224 11.500000000 35.499954224 -26.499996185 11.500000000 35.499996185 -25.500000000 11.500000000 35.500000000 -24.500000000 11.500000000 35.500000000 -23.500000000 11.500000000 35.500000000 -22.500000000 11.500000000 35.500000000 -21.500000000 11.500000000 35.500000000 -20.500000000 11.500000000 35.500000000 -19.500000000 11.500000000 35.500000000 -18.500000000 11.500000000 35.500000000 -17.500000000 11.500000000 35.500000000 -16.500000000 11.500000000 35.500000000 -15.500000000 11.500000000 35.500000000 -14.500000000 11.500000000 35.500000000 -13.500000000 11.500000000 35.500000000 -12.500000000 11.500000000 35.500000000 -11.500000000 11.500000000 35.500000000 -10.500000000 11.500000000 35.500000000 -9.500000000 11.500000000 35.500000000 -8.500000000 11.500000000 35.500000000 -7.500000000 11.500000000 35.500000000 -6.500000000 11.500000000 35.500000000 -5.500000000 11.500000000 35.500000000 -4.500000000 11.500000000 35.500000000 -3.500000000 11.500000000 35.500000000 -2.500000000 11.500000000 35.500000000 -1.500000000 11.500000000 35.500000000 -0.500000000 11.500000000 35.500000000 0.500000000 11.500000000 35.500000000 1.500000000 11.500000000 35.500000000 2.500000000 11.500000000 35.500000000 3.500000000 11.500000000 35.500000000 4.500000000 11.500000000 35.500000000 5.500000000 11.500000000 35.500000000 6.500000000 11.500000000 35.500000000 7.500000000 11.500000000 35.500000000 8.500000000 11.500000000 35.500000000 9.500000000 11.500000000 35.500000000 10.500000000 11.500000000 35.500000000 11.500000000 11.500000000 35.500000000 12.500000000 11.500000000 35.500000000 13.500000000 11.500000000 35.500000000 14.500000000 11.500000000 35.500000000 15.500000000 11.500000000 35.500000000 16.500000000 11.500000000 35.500000000 17.500000000 11.500000000 35.500000000 18.500000000 11.500000000 35.500000000 19.500000000 11.500000000 35.500000000 20.500000000 11.500000000 35.500000000 21.500000000 11.500000000 35.500000000 22.500000000 11.500000000 35.500000000 23.500000000 11.500000000 35.500000000 24.500000000 11.500000000 35.500000000 25.499996185 11.500000000 35.499996185 26.499954224 11.500000000 35.499954224 27.499591827 11.500000000 35.499591827 28.497470856 11.500000000 35.497467041 29.488407135 11.500000000 35.488403320 30.458978653 11.500000000 35.458980560 31.384418488 11.500000000 35.384422302 32.233222961 11.500000000 35.233222961 32.981101990 11.500000000 34.981101990 -33.981101990 12.500000000 34.981101990 -33.233226776 12.500000000 35.233222961 -32.384422302 12.500000000 35.384418488 -31.458978653 12.500000000 35.458980560 -30.488407135 12.500000000 35.488403320 -29.497472763 12.500000000 35.497474670 -28.499593735 12.500000000 35.499591827 -27.499954224 12.500000000 35.499954224 -26.499996185 12.500000000 35.499996185 -25.500000000 12.500000000 35.500000000 -24.500000000 12.500000000 35.500000000 -23.500000000 12.500000000 35.500000000 -22.500000000 12.500000000 35.500000000 -21.500000000 12.500000000 35.500000000 -20.500000000 12.500000000 35.500000000 -19.500000000 12.500000000 35.500000000 -18.500000000 12.500000000 35.500000000 -17.500000000 12.500000000 35.500000000 -16.500000000 12.500000000 35.500000000 -15.500000000 12.500000000 35.500000000 -14.500000000 12.500000000 35.500000000 -13.500000000 12.500000000 35.500000000 -12.500000000 12.500000000 35.500000000 -11.500000000 12.500000000 35.500000000 -10.500000000 12.500000000 35.500000000 -9.500000000 12.500000000 35.500000000 -8.500000000 12.500000000 35.500000000 -7.500000000 12.500000000 35.500000000 -6.500000000 12.500000000 35.500000000 -5.500000000 12.500000000 35.500000000 -4.500000000 12.500000000 35.500000000 -3.500000000 12.500000000 35.500000000 -2.500000000 12.500000000 35.500000000 -1.500000000 12.500000000 35.500000000 -0.500000000 12.500000000 35.500000000 0.500000000 12.500000000 35.500000000 1.500000000 12.500000000 35.500000000 2.500000000 12.500000000 35.500000000 3.500000000 12.500000000 35.500000000 4.500000000 12.500000000 35.500000000 5.500000000 12.500000000 35.500000000 6.500000000 12.500000000 35.500000000 7.500000000 12.500000000 35.500000000 8.500000000 12.500000000 35.500000000 9.500000000 12.500000000 35.500000000 10.500000000 12.500000000 35.500000000 11.500000000 12.500000000 35.500000000 12.500000000 12.500000000 35.500000000 13.500000000 12.500000000 35.500000000 14.500000000 12.500000000 35.500000000 15.500000000 12.500000000 35.500000000 16.500000000 12.500000000 35.500000000 17.500000000 12.500000000 35.500000000 18.500000000 12.500000000 35.500000000 19.500000000 12.500000000 35.500000000 20.500000000 12.500000000 35.500000000 21.500000000 12.500000000 35.500000000 22.500000000 12.500000000 35.500000000 23.500000000 12.500000000 35.500000000 24.500000000 12.500000000 35.500000000 25.499996185 12.500000000 35.499996185 26.499954224 12.500000000 35.499954224 27.499591827 12.500000000 35.499591827 28.497470856 12.500000000 35.497467041 29.488407135 12.500000000 35.488403320 30.458978653 12.500000000 35.458980560 31.384418488 12.500000000 35.384422302 32.233222961 12.500000000 35.233222961 32.981101990 12.500000000 34.981101990 -33.981101990 13.500000000 34.981101990 -33.233226776 13.500000000 35.233222961 -32.384422302 13.500000000 35.384418488 -31.458978653 13.500000000 35.458980560 -30.488407135 13.500000000 35.488403320 -29.497472763 13.500000000 35.497474670 -28.499593735 13.500000000 35.499591827 -27.499954224 13.500000000 35.499954224 -26.499996185 13.500000000 35.499996185 -25.500000000 13.500000000 35.500000000 -24.500000000 13.500000000 35.500000000 -23.500000000 13.500000000 35.500000000 -22.500000000 13.500000000 35.500000000 -21.500000000 13.500000000 35.500000000 -20.500000000 13.500000000 35.500000000 -19.500000000 13.500000000 35.500000000 -18.500000000 13.500000000 35.500000000 -17.500000000 13.500000000 35.500000000 -16.500000000 13.500000000 35.500000000 -15.500000000 13.500000000 35.500000000 -14.500000000 13.500000000 35.500000000 -13.500000000 13.500000000 35.500000000 -12.500000000 13.500000000 35.500000000 -11.500000000 13.500000000 35.500000000 -10.500000000 13.500000000 35.500000000 -9.500000000 13.500000000 35.500000000 -8.500000000 13.500000000 35.500000000 -7.500000000 13.500000000 35.500000000 -6.500000000 13.500000000 35.500000000 -5.500000000 13.500000000 35.500000000 -4.500000000 13.500000000 35.500000000 -3.500000000 13.500000000 35.500000000 -2.500000000 13.500000000 35.500000000 -1.500000000 13.500000000 35.500000000 -0.500000000 13.500000000 35.500000000 0.500000000 13.500000000 35.500000000 1.500000000 13.500000000 35.500000000 2.500000000 13.500000000 35.500000000 3.500000000 13.500000000 35.500000000 4.500000000 13.500000000 35.500000000 5.500000000 13.500000000 35.500000000 6.500000000 13.500000000 35.500000000 7.500000000 13.500000000 35.500000000 8.500000000 13.500000000 35.500000000 9.500000000 13.500000000 35.500000000 10.500000000 13.500000000 35.500000000 11.500000000 13.500000000 35.500000000 12.500000000 13.500000000 35.500000000 13.500000000 13.500000000 35.500000000 14.500000000 13.500000000 35.500000000 15.500000000 13.500000000 35.500000000 16.500000000 13.500000000 35.500000000 17.500000000 13.500000000 35.500000000 18.500000000 13.500000000 35.500000000 19.500000000 13.500000000 35.500000000 20.500000000 13.500000000 35.500000000 21.500000000 13.500000000 35.500000000 22.500000000 13.500000000 35.500000000 23.500000000 13.500000000 35.500000000 24.500000000 13.500000000 35.500000000 25.499996185 13.500000000 35.499996185 26.499954224 13.500000000 35.499954224 27.499591827 13.500000000 35.499591827 28.497470856 13.500000000 35.497467041 29.488407135 13.500000000 35.488403320 30.458978653 13.500000000 35.458980560 31.384418488 13.500000000 35.384422302 32.233222961 13.500000000 35.233222961 32.981101990 13.500000000 34.981101990 -33.981101990 14.500000000 34.981101990 -33.233226776 14.500000000 35.233222961 -32.384422302 14.500000000 35.384418488 -31.458978653 14.500000000 35.458980560 -30.488407135 14.500000000 35.488403320 -29.497472763 14.500000000 35.497474670 -28.499593735 14.500000000 35.499591827 -27.499954224 14.500000000 35.499954224 -26.499996185 14.500000000 35.499996185 -25.500000000 14.500000000 35.500000000 -24.500000000 14.500000000 35.500000000 -23.500000000 14.500000000 35.500000000 -22.500000000 14.500000000 35.500000000 -21.500000000 14.500000000 35.500000000 -20.500000000 14.500000000 35.500000000 -19.500000000 14.500000000 35.500000000 -18.500000000 14.500000000 35.500000000 -17.500000000 14.500000000 35.500000000 -16.500000000 14.500000000 35.500000000 -15.500000000 14.500000000 35.500000000 -14.500000000 14.500000000 35.500000000 -13.500000000 14.500000000 35.500000000 -12.500000000 14.500000000 35.500000000 -11.500000000 14.500000000 35.500000000 -10.500000000 14.500000000 35.500000000 -9.500000000 14.500000000 35.500000000 -8.500000000 14.500000000 35.500000000 -7.500000000 14.500000000 35.500000000 -6.500000000 14.500000000 35.500000000 -5.500000000 14.500000000 35.500000000 -4.500000000 14.500000000 35.500000000 -3.500000000 14.500000000 35.500000000 -2.500000000 14.500000000 35.500000000 -1.500000000 14.500000000 35.500000000 -0.500000000 14.500000000 35.500000000 0.500000000 14.500000000 35.500000000 1.500000000 14.500000000 35.500000000 2.500000000 14.500000000 35.500000000 3.500000000 14.500000000 35.500000000 4.500000000 14.500000000 35.500000000 5.500000000 14.500000000 35.500000000 6.500000000 14.500000000 35.500000000 7.500000000 14.500000000 35.500000000 8.500000000 14.500000000 35.500000000 9.500000000 14.500000000 35.500000000 10.500000000 14.500000000 35.500000000 11.500000000 14.500000000 35.500000000 12.500000000 14.500000000 35.500000000 13.500000000 14.500000000 35.500000000 14.500000000 14.500000000 35.500000000 15.500000000 14.500000000 35.500000000 16.500000000 14.500000000 35.500000000 17.500000000 14.500000000 35.500000000 18.500000000 14.500000000 35.500000000 19.500000000 14.500000000 35.500000000 20.500000000 14.500000000 35.500000000 21.500000000 14.500000000 35.500000000 22.500000000 14.500000000 35.500000000 23.500000000 14.500000000 35.500000000 24.500000000 14.500000000 35.500000000 25.499996185 14.500000000 35.499996185 26.499954224 14.500000000 35.499954224 27.499591827 14.500000000 35.499591827 28.497470856 14.500000000 35.497467041 29.488407135 14.500000000 35.488403320 30.458978653 14.500000000 35.458980560 31.384418488 14.500000000 35.384422302 32.233222961 14.500000000 35.233222961 32.981101990 14.500000000 34.981101990 -33.981101990 15.500000000 34.981101990 -33.233226776 15.500000000 35.233222961 -32.384422302 15.500000000 35.384418488 -31.458978653 15.500000000 35.458980560 -30.488407135 15.500000000 35.488403320 -29.497472763 15.500000000 35.497474670 -28.499593735 15.500000000 35.499591827 -27.499954224 15.500000000 35.499954224 -26.499996185 15.500000000 35.499996185 -25.500000000 15.500000000 35.500000000 -24.500000000 15.500000000 35.500000000 -23.500000000 15.500000000 35.500000000 -22.500000000 15.500000000 35.500000000 -21.500000000 15.500000000 35.500000000 -20.500000000 15.500000000 35.500000000 -19.500000000 15.500000000 35.500000000 -18.500000000 15.500000000 35.500000000 -17.500000000 15.500000000 35.500000000 -16.500000000 15.500000000 35.500000000 -15.500000000 15.500000000 35.500000000 -14.500000000 15.500000000 35.500000000 -13.500000000 15.500000000 35.500000000 -12.500000000 15.500000000 35.500000000 -11.500000000 15.500000000 35.500000000 -10.500000000 15.500000000 35.500000000 -9.500000000 15.500000000 35.500000000 -8.500000000 15.500000000 35.500000000 -7.500000000 15.500000000 35.500000000 -6.500000000 15.500000000 35.500000000 -5.500000000 15.500000000 35.500000000 -4.500000000 15.500000000 35.500000000 -3.500000000 15.500000000 35.500000000 -2.500000000 15.500000000 35.500000000 -1.500000000 15.500000000 35.500000000 -0.500000000 15.500000000 35.500000000 0.500000000 15.500000000 35.500000000 1.500000000 15.500000000 35.500000000 2.500000000 15.500000000 35.500000000 3.500000000 15.500000000 35.500000000 4.500000000 15.500000000 35.500000000 5.500000000 15.500000000 35.500000000 6.500000000 15.500000000 35.500000000 7.500000000 15.500000000 35.500000000 8.500000000 15.500000000 35.500000000 9.500000000 15.500000000 35.500000000 10.500000000 15.500000000 35.500000000 11.500000000 15.500000000 35.500000000 12.500000000 15.500000000 35.500000000 13.500000000 15.500000000 35.500000000 14.500000000 15.500000000 35.500000000 15.500000000 15.500000000 35.500000000 16.500000000 15.500000000 35.500000000 17.500000000 15.500000000 35.500000000 18.500000000 15.500000000 35.500000000 19.500000000 15.500000000 35.500000000 20.500000000 15.500000000 35.500000000 21.500000000 15.500000000 35.500000000 22.500000000 15.500000000 35.500000000 23.500000000 15.500000000 35.500000000 24.500000000 15.500000000 35.500000000 25.499996185 15.500000000 35.499996185 26.499954224 15.500000000 35.499954224 27.499591827 15.500000000 35.499591827 28.497470856 15.500000000 35.497467041 29.488407135 15.500000000 35.488403320 30.458978653 15.500000000 35.458980560 31.384418488 15.500000000 35.384422302 32.233222961 15.500000000 35.233222961 32.981101990 15.500000000 34.981101990 -33.981101990 16.500000000 34.981101990 -33.233226776 16.500000000 35.233222961 -32.384422302 16.500000000 35.384418488 -31.458978653 16.500000000 35.458980560 -30.488407135 16.500000000 35.488403320 -29.497472763 16.500000000 35.497474670 -28.499593735 16.500000000 35.499591827 -27.499954224 16.500000000 35.499954224 -26.499996185 16.500000000 35.499996185 -25.500000000 16.500000000 35.500000000 -24.500000000 16.500000000 35.500000000 -23.500000000 16.500000000 35.500000000 -22.500000000 16.500000000 35.500000000 -21.500000000 16.500000000 35.500000000 -20.500000000 16.500000000 35.500000000 -19.500000000 16.500000000 35.500000000 -18.500000000 16.500000000 35.500000000 -17.500000000 16.500000000 35.500000000 -16.500000000 16.500000000 35.500000000 -15.500000000 16.500000000 35.500000000 -14.500000000 16.500000000 35.500000000 -13.500000000 16.500000000 35.500000000 -12.500000000 16.500000000 35.500000000 -11.500000000 16.500000000 35.500000000 -10.500000000 16.500000000 35.500000000 -9.500000000 16.500000000 35.500000000 -8.500000000 16.500000000 35.500000000 -7.500000000 16.500000000 35.500000000 -6.500000000 16.500000000 35.500000000 -5.500000000 16.500000000 35.500000000 -4.500000000 16.500000000 35.500000000 -3.500000000 16.500000000 35.500000000 -2.500000000 16.500000000 35.500000000 -1.500000000 16.500000000 35.500000000 -0.500000000 16.500000000 35.500000000 0.500000000 16.500000000 35.500000000 1.500000000 16.500000000 35.500000000 2.500000000 16.500000000 35.500000000 3.500000000 16.500000000 35.500000000 4.500000000 16.500000000 35.500000000 5.500000000 16.500000000 35.500000000 6.500000000 16.500000000 35.500000000 7.500000000 16.500000000 35.500000000 8.500000000 16.500000000 35.500000000 9.500000000 16.500000000 35.500000000 10.500000000 16.500000000 35.500000000 11.500000000 16.500000000 35.500000000 12.500000000 16.500000000 35.500000000 13.500000000 16.500000000 35.500000000 14.500000000 16.500000000 35.500000000 15.500000000 16.500000000 35.500000000 16.500000000 16.500000000 35.500000000 17.500000000 16.500000000 35.500000000 18.500000000 16.500000000 35.500000000 19.500000000 16.500000000 35.500000000 20.500000000 16.500000000 35.500000000 21.500000000 16.500000000 35.500000000 22.500000000 16.500000000 35.500000000 23.500000000 16.500000000 35.500000000 24.500000000 16.500000000 35.500000000 25.499996185 16.500000000 35.499996185 26.499954224 16.500000000 35.499954224 27.499591827 16.500000000 35.499591827 28.497470856 16.500000000 35.497467041 29.488407135 16.500000000 35.488403320 30.458978653 16.500000000 35.458980560 31.384418488 16.500000000 35.384422302 32.233222961 16.500000000 35.233222961 32.981101990 16.500000000 34.981101990 -33.981101990 17.500000000 34.981101990 -33.233226776 17.500000000 35.233222961 -32.384422302 17.500000000 35.384418488 -31.458978653 17.500000000 35.458980560 -30.488407135 17.500000000 35.488403320 -29.497472763 17.500000000 35.497474670 -28.499593735 17.500000000 35.499591827 -27.499954224 17.500000000 35.499954224 -26.499996185 17.500000000 35.499996185 -25.500000000 17.500000000 35.500000000 -24.500000000 17.500000000 35.500000000 -23.500000000 17.500000000 35.500000000 -22.500000000 17.500000000 35.500000000 -21.500000000 17.500000000 35.500000000 -20.500000000 17.500000000 35.500000000 -19.500000000 17.500000000 35.500000000 -18.500000000 17.500000000 35.500000000 -17.500000000 17.500000000 35.500000000 -16.500000000 17.500000000 35.500000000 -15.500000000 17.500000000 35.500000000 -14.500000000 17.500000000 35.500000000 -13.500000000 17.500000000 35.500000000 -12.500000000 17.500000000 35.500000000 -11.500000000 17.500000000 35.500000000 -10.500000000 17.500000000 35.500000000 -9.500000000 17.500000000 35.500000000 -8.500000000 17.500000000 35.500000000 -7.500000000 17.500000000 35.500000000 -6.500000000 17.500000000 35.500000000 -5.500000000 17.500000000 35.500000000 -4.500000000 17.500000000 35.500000000 -3.500000000 17.500000000 35.500000000 -2.500000000 17.500000000 35.500000000 -1.500000000 17.500000000 35.500000000 -0.500000000 17.500000000 35.500000000 0.500000000 17.500000000 35.500000000 1.500000000 17.500000000 35.500000000 2.500000000 17.500000000 35.500000000 3.500000000 17.500000000 35.500000000 4.500000000 17.500000000 35.500000000 5.500000000 17.500000000 35.500000000 6.500000000 17.500000000 35.500000000 7.500000000 17.500000000 35.500000000 8.500000000 17.500000000 35.500000000 9.500000000 17.500000000 35.500000000 10.500000000 17.500000000 35.500000000 11.500000000 17.500000000 35.500000000 12.500000000 17.500000000 35.500000000 13.500000000 17.500000000 35.500000000 14.500000000 17.500000000 35.500000000 15.500000000 17.500000000 35.500000000 16.500000000 17.500000000 35.500000000 17.500000000 17.500000000 35.500000000 18.500000000 17.500000000 35.500000000 19.500000000 17.500000000 35.500000000 20.500000000 17.500000000 35.500000000 21.500000000 17.500000000 35.500000000 22.500000000 17.500000000 35.500000000 23.500000000 17.500000000 35.500000000 24.500000000 17.500000000 35.500000000 25.499996185 17.500000000 35.499996185 26.499954224 17.500000000 35.499954224 27.499591827 17.500000000 35.499591827 28.497470856 17.500000000 35.497467041 29.488407135 17.500000000 35.488403320 30.458978653 17.500000000 35.458980560 31.384418488 17.500000000 35.384422302 32.233222961 17.500000000 35.233222961 32.981101990 17.500000000 34.981101990 -33.981101990 18.500000000 34.981101990 -33.233226776 18.500000000 35.233222961 -32.384422302 18.500000000 35.384418488 -31.458978653 18.500000000 35.458980560 -30.488407135 18.500000000 35.488403320 -29.497472763 18.500000000 35.497474670 -28.499593735 18.500000000 35.499591827 -27.499954224 18.500000000 35.499954224 -26.499996185 18.500000000 35.499996185 -25.500000000 18.500000000 35.500000000 -24.500000000 18.500000000 35.500000000 -23.500000000 18.500000000 35.500000000 -22.500000000 18.500000000 35.500000000 -21.500000000 18.500000000 35.500000000 -20.500000000 18.500000000 35.500000000 -19.500000000 18.500000000 35.500000000 -18.500000000 18.500000000 35.500000000 -17.500000000 18.500000000 35.500000000 -16.500000000 18.500000000 35.500000000 -15.500000000 18.500000000 35.500000000 -14.500000000 18.500000000 35.500000000 -13.500000000 18.500000000 35.500000000 -12.500000000 18.500000000 35.500000000 -11.500000000 18.500000000 35.500000000 -10.500000000 18.500000000 35.500000000 -9.500000000 18.500000000 35.500000000 -8.500000000 18.500000000 35.500000000 -7.500000000 18.500000000 35.500000000 -6.500000000 18.500000000 35.500000000 -5.500000000 18.500000000 35.500000000 -4.500000000 18.500000000 35.500000000 -3.500000000 18.500000000 35.500000000 -2.500000000 18.500000000 35.500000000 -1.500000000 18.500000000 35.500000000 -0.500000000 18.500000000 35.500000000 0.500000000 18.500000000 35.500000000 1.500000000 18.500000000 35.500000000 2.500000000 18.500000000 35.500000000 3.500000000 18.500000000 35.500000000 4.500000000 18.500000000 35.500000000 5.500000000 18.500000000 35.500000000 6.500000000 18.500000000 35.500000000 7.500000000 18.500000000 35.500000000 8.500000000 18.500000000 35.500000000 9.500000000 18.500000000 35.500000000 10.500000000 18.500000000 35.500000000 11.500000000 18.500000000 35.500000000 12.500000000 18.500000000 35.500000000 13.500000000 18.500000000 35.500000000 14.500000000 18.500000000 35.500000000 15.500000000 18.500000000 35.500000000 16.500000000 18.500000000 35.500000000 17.500000000 18.500000000 35.500000000 18.500000000 18.500000000 35.500000000 19.500000000 18.500000000 35.500000000 20.500000000 18.500000000 35.500000000 21.500000000 18.500000000 35.500000000 22.500000000 18.500000000 35.500000000 23.500000000 18.500000000 35.500000000 24.500000000 18.500000000 35.500000000 25.499996185 18.500000000 35.499996185 26.499954224 18.500000000 35.499954224 27.499591827 18.500000000 35.499591827 28.497470856 18.500000000 35.497467041 29.488407135 18.500000000 35.488403320 30.458978653 18.500000000 35.458980560 31.384418488 18.500000000 35.384422302 32.233222961 18.500000000 35.233222961 32.981101990 18.500000000 34.981101990 -33.981101990 19.500000000 34.981101990 -33.233226776 19.500000000 35.233222961 -32.384422302 19.500000000 35.384418488 -31.458978653 19.500000000 35.458980560 -30.488407135 19.500000000 35.488403320 -29.497472763 19.500000000 35.497474670 -28.499593735 19.500000000 35.499591827 -27.499954224 19.500000000 35.499954224 -26.499996185 19.500000000 35.499996185 -25.500000000 19.500000000 35.500000000 -24.500000000 19.500000000 35.500000000 -23.500000000 19.500000000 35.500000000 -22.500000000 19.500000000 35.500000000 -21.500000000 19.500000000 35.500000000 -20.500000000 19.500000000 35.500000000 -19.500000000 19.500000000 35.500000000 -18.500000000 19.500000000 35.500000000 -17.500000000 19.500000000 35.500000000 -16.500000000 19.500000000 35.500000000 -15.500000000 19.500000000 35.500000000 -14.500000000 19.500000000 35.500000000 -13.500000000 19.500000000 35.500000000 -12.500000000 19.500000000 35.500000000 -11.500000000 19.500000000 35.500000000 -10.500000000 19.500000000 35.500000000 -9.500000000 19.500000000 35.500000000 -8.500000000 19.500000000 35.500000000 -7.500000000 19.500000000 35.500000000 -6.500000000 19.500000000 35.500000000 -5.500000000 19.500000000 35.500000000 -4.500000000 19.500000000 35.500000000 -3.500000000 19.500000000 35.500000000 -2.500000000 19.500000000 35.500000000 -1.500000000 19.500000000 35.500000000 -0.500000000 19.500000000 35.500000000 0.500000000 19.500000000 35.500000000 1.500000000 19.500000000 35.500000000 2.500000000 19.500000000 35.500000000 3.500000000 19.500000000 35.500000000 4.500000000 19.500000000 35.500000000 5.500000000 19.500000000 35.500000000 6.500000000 19.500000000 35.500000000 7.500000000 19.500000000 35.500000000 8.500000000 19.500000000 35.500000000 9.500000000 19.500000000 35.500000000 10.500000000 19.500000000 35.500000000 11.500000000 19.500000000 35.500000000 12.500000000 19.500000000 35.500000000 13.500000000 19.500000000 35.500000000 14.500000000 19.500000000 35.500000000 15.500000000 19.500000000 35.500000000 16.500000000 19.500000000 35.500000000 17.500000000 19.500000000 35.500000000 18.500000000 19.500000000 35.500000000 19.500000000 19.500000000 35.500000000 20.500000000 19.500000000 35.500000000 21.500000000 19.500000000 35.500000000 22.500000000 19.500000000 35.500000000 23.500000000 19.500000000 35.500000000 24.500000000 19.500000000 35.500000000 25.499996185 19.500000000 35.499996185 26.499954224 19.500000000 35.499954224 27.499591827 19.500000000 35.499591827 28.497470856 19.500000000 35.497467041 29.488407135 19.500000000 35.488403320 30.458978653 19.500000000 35.458980560 31.384418488 19.500000000 35.384422302 32.233222961 19.500000000 35.233222961 32.981101990 19.500000000 34.981101990 -33.981101990 20.500000000 34.981101990 -33.233226776 20.500000000 35.233222961 -32.384422302 20.500000000 35.384418488 -31.458978653 20.500000000 35.458980560 -30.488407135 20.500000000 35.488403320 -29.497472763 20.500000000 35.497474670 -28.499593735 20.500000000 35.499591827 -27.499954224 20.500000000 35.499954224 -26.499996185 20.500000000 35.499996185 -25.500000000 20.500000000 35.500000000 -24.500000000 20.500000000 35.500000000 -23.500000000 20.500000000 35.500000000 -22.500000000 20.500000000 35.500000000 -21.500000000 20.500000000 35.500000000 -20.500000000 20.500000000 35.500000000 -19.500000000 20.500000000 35.500000000 -18.500000000 20.500000000 35.500000000 -17.500000000 20.500000000 35.500000000 -16.500000000 20.500000000 35.500000000 -15.500000000 20.500000000 35.500000000 -14.500000000 20.500000000 35.500000000 -13.500000000 20.500000000 35.500000000 -12.500000000 20.500000000 35.500000000 -11.500000000 20.500000000 35.500000000 -10.500000000 20.500000000 35.500000000 -9.500000000 20.500000000 35.500000000 -8.500000000 20.500000000 35.500000000 -7.500000000 20.500000000 35.500000000 -6.500000000 20.500000000 35.500000000 -5.500000000 20.500000000 35.500000000 -4.500000000 20.500000000 35.500000000 -3.500000000 20.500000000 35.500000000 -2.500000000 20.500000000 35.500000000 -1.500000000 20.500000000 35.500000000 -0.500000000 20.500000000 35.500000000 0.500000000 20.500000000 35.500000000 1.500000000 20.500000000 35.500000000 2.500000000 20.500000000 35.500000000 3.500000000 20.500000000 35.500000000 4.500000000 20.500000000 35.500000000 5.500000000 20.500000000 35.500000000 6.500000000 20.500000000 35.500000000 7.500000000 20.500000000 35.500000000 8.500000000 20.500000000 35.500000000 9.500000000 20.500000000 35.500000000 10.500000000 20.500000000 35.500000000 11.500000000 20.500000000 35.500000000 12.500000000 20.500000000 35.500000000 13.500000000 20.500000000 35.500000000 14.500000000 20.500000000 35.500000000 15.500000000 20.500000000 35.500000000 16.500000000 20.500000000 35.500000000 17.500000000 20.500000000 35.500000000 18.500000000 20.500000000 35.500000000 19.500000000 20.500000000 35.500000000 20.500000000 20.500000000 35.500000000 21.500000000 20.500000000 35.500000000 22.500000000 20.500000000 35.500000000 23.500000000 20.500000000 35.500000000 24.500000000 20.500000000 35.500000000 25.499996185 20.500000000 35.499996185 26.499954224 20.500000000 35.499954224 27.499591827 20.500000000 35.499591827 28.497470856 20.500000000 35.497467041 29.488407135 20.500000000 35.488403320 30.458978653 20.500000000 35.458980560 31.384418488 20.500000000 35.384422302 32.233222961 20.500000000 35.233222961 32.981101990 20.500000000 34.981101990 -33.981101990 21.500000000 34.981101990 -33.233226776 21.500000000 35.233222961 -32.384422302 21.500000000 35.384418488 -31.458978653 21.500000000 35.458980560 -30.488407135 21.500000000 35.488403320 -29.497472763 21.500000000 35.497474670 -28.499593735 21.500000000 35.499591827 -27.499954224 21.500000000 35.499954224 -26.499996185 21.500000000 35.499996185 -25.500000000 21.500000000 35.500000000 -24.500000000 21.500000000 35.500000000 -23.500000000 21.500000000 35.500000000 -22.500000000 21.500000000 35.500000000 -21.500000000 21.500000000 35.500000000 -20.500000000 21.500000000 35.500000000 -19.500000000 21.500000000 35.500000000 -18.500000000 21.500000000 35.500000000 -17.500000000 21.500000000 35.500000000 -16.500000000 21.500000000 35.500000000 -15.500000000 21.500000000 35.500000000 -14.500000000 21.500000000 35.500000000 -13.500000000 21.500000000 35.500000000 -12.500000000 21.500000000 35.500000000 -11.500000000 21.500000000 35.500000000 -10.500000000 21.500000000 35.500000000 -9.500000000 21.500000000 35.500000000 -8.500000000 21.500000000 35.500000000 -7.500000000 21.500000000 35.500000000 -6.500000000 21.500000000 35.500000000 -5.500000000 21.500000000 35.500000000 -4.500000000 21.500000000 35.500000000 -3.500000000 21.500000000 35.500000000 -2.500000000 21.500000000 35.500000000 -1.500000000 21.500000000 35.500000000 -0.500000000 21.500000000 35.500000000 0.500000000 21.500000000 35.500000000 1.500000000 21.500000000 35.500000000 2.500000000 21.500000000 35.500000000 3.500000000 21.500000000 35.500000000 4.500000000 21.500000000 35.500000000 5.500000000 21.500000000 35.500000000 6.500000000 21.500000000 35.500000000 7.500000000 21.500000000 35.500000000 8.500000000 21.500000000 35.500000000 9.500000000 21.500000000 35.500000000 10.500000000 21.500000000 35.500000000 11.500000000 21.500000000 35.500000000 12.500000000 21.500000000 35.500000000 13.500000000 21.500000000 35.500000000 14.500000000 21.500000000 35.500000000 15.500000000 21.500000000 35.500000000 16.500000000 21.500000000 35.500000000 17.500000000 21.500000000 35.500000000 18.500000000 21.500000000 35.500000000 19.500000000 21.500000000 35.500000000 20.500000000 21.500000000 35.500000000 21.500000000 21.500000000 35.500000000 22.500000000 21.500000000 35.500000000 23.500000000 21.500000000 35.500000000 24.500000000 21.500000000 35.500000000 25.499996185 21.500000000 35.499996185 26.499954224 21.500000000 35.499954224 27.499591827 21.500000000 35.499591827 28.497470856 21.500000000 35.497467041 29.488407135 21.500000000 35.488403320 30.458978653 21.500000000 35.458980560 31.384418488 21.500000000 35.384422302 32.233222961 21.500000000 35.233222961 32.981101990 21.500000000 34.981101990 -33.981101990 22.500000000 34.981101990 -33.233226776 22.500000000 35.233222961 -32.384422302 22.500000000 35.384418488 -31.458978653 22.500000000 35.458980560 -30.488407135 22.500000000 35.488403320 -29.497472763 22.500000000 35.497474670 -28.499593735 22.500000000 35.499591827 -27.499954224 22.500000000 35.499954224 -26.499996185 22.500000000 35.499996185 -25.500000000 22.500000000 35.500000000 -24.500000000 22.500000000 35.500000000 -23.500000000 22.500000000 35.500000000 -22.500000000 22.500000000 35.500000000 -21.500000000 22.500000000 35.500000000 -20.500000000 22.500000000 35.500000000 -19.500000000 22.500000000 35.500000000 -18.500000000 22.500000000 35.500000000 -17.500000000 22.500000000 35.500000000 -16.500000000 22.500000000 35.500000000 -15.500000000 22.500000000 35.500000000 -14.500000000 22.500000000 35.500000000 -13.500000000 22.500000000 35.500000000 -12.500000000 22.500000000 35.500000000 -11.500000000 22.500000000 35.500000000 -10.500000000 22.500000000 35.500000000 -9.500000000 22.500000000 35.500000000 -8.500000000 22.500000000 35.500000000 -7.500000000 22.500000000 35.500000000 -6.500000000 22.500000000 35.500000000 -5.500000000 22.500000000 35.500000000 -4.500000000 22.500000000 35.500000000 -3.500000000 22.500000000 35.500000000 -2.500000000 22.500000000 35.500000000 -1.500000000 22.500000000 35.500000000 -0.500000000 22.500000000 35.500000000 0.500000000 22.500000000 35.500000000 1.500000000 22.500000000 35.500000000 2.500000000 22.500000000 35.500000000 3.500000000 22.500000000 35.500000000 4.500000000 22.500000000 35.500000000 5.500000000 22.500000000 35.500000000 6.500000000 22.500000000 35.500000000 7.500000000 22.500000000 35.500000000 8.500000000 22.500000000 35.500000000 9.500000000 22.500000000 35.500000000 10.500000000 22.500000000 35.500000000 11.500000000 22.500000000 35.500000000 12.500000000 22.500000000 35.500000000 13.500000000 22.500000000 35.500000000 14.500000000 22.500000000 35.500000000 15.500000000 22.500000000 35.500000000 16.500000000 22.500000000 35.500000000 17.500000000 22.500000000 35.500000000 18.500000000 22.500000000 35.500000000 19.500000000 22.500000000 35.500000000 20.500000000 22.500000000 35.500000000 21.500000000 22.500000000 35.500000000 22.500000000 22.500000000 35.500000000 23.500000000 22.500000000 35.500000000 24.500000000 22.500000000 35.500000000 25.499996185 22.500000000 35.499996185 26.499954224 22.500000000 35.499954224 27.499591827 22.500000000 35.499591827 28.497470856 22.500000000 35.497467041 29.488407135 22.500000000 35.488403320 30.458978653 22.500000000 35.458980560 31.384418488 22.500000000 35.384422302 32.233222961 22.500000000 35.233222961 32.981101990 22.500000000 34.981101990 -33.981101990 23.499998093 34.981101990 -33.233226776 23.500000000 35.233222961 -32.384422302 23.500000000 35.384418488 -31.458978653 23.500000000 35.458980560 -30.488407135 23.500000000 35.488403320 -29.497472763 23.500000000 35.497474670 -28.499593735 23.500000000 35.499591827 -27.499954224 23.500000000 35.499954224 -26.499996185 23.500000000 35.499996185 -25.500000000 23.500000000 35.500000000 -24.500000000 23.500000000 35.500000000 -23.500000000 23.500000000 35.500000000 -22.500000000 23.500000000 35.500000000 -21.500000000 23.500000000 35.500000000 -20.500000000 23.500000000 35.500000000 -19.500000000 23.500000000 35.500000000 -18.500000000 23.500000000 35.500000000 -17.500000000 23.500000000 35.500000000 -16.500000000 23.500000000 35.500000000 -15.500000000 23.500000000 35.500000000 -14.500000000 23.500000000 35.500000000 -13.500000000 23.500000000 35.500000000 -12.500000000 23.500000000 35.500000000 -11.500000000 23.500000000 35.500000000 -10.500000000 23.500000000 35.500000000 -9.500000000 23.500000000 35.500000000 -8.500000000 23.500000000 35.500000000 -7.500000000 23.500000000 35.500000000 -6.500000000 23.500000000 35.500000000 -5.500000000 23.500000000 35.500000000 -4.500000000 23.500000000 35.500000000 -3.500000000 23.500000000 35.500000000 -2.500000000 23.500000000 35.500000000 -1.500000000 23.500000000 35.500000000 -0.500000000 23.500000000 35.500000000 0.500000000 23.500000000 35.500000000 1.500000000 23.500000000 35.500000000 2.500000000 23.500000000 35.500000000 3.500000000 23.500000000 35.500000000 4.500000000 23.500000000 35.500000000 5.500000000 23.500000000 35.500000000 6.500000000 23.500000000 35.500000000 7.500000000 23.500000000 35.500000000 8.500000000 23.500000000 35.500000000 9.500000000 23.500000000 35.500000000 10.500000000 23.500000000 35.500000000 11.500000000 23.500000000 35.500000000 12.500000000 23.500000000 35.500000000 13.500000000 23.500000000 35.500000000 14.500000000 23.500000000 35.500000000 15.500000000 23.500000000 35.500000000 16.500000000 23.500000000 35.500000000 17.500000000 23.500000000 35.500000000 18.500000000 23.500000000 35.500000000 19.500000000 23.500000000 35.500000000 20.500000000 23.500000000 35.500000000 21.500000000 23.500000000 35.500000000 22.500000000 23.500000000 35.500000000 23.500000000 23.500000000 35.500000000 24.500000000 23.500000000 35.500000000 25.499996185 23.500000000 35.499996185 26.499954224 23.500000000 35.499954224 27.499591827 23.500000000 35.499591827 28.497470856 23.500000000 35.497467041 29.488407135 23.500000000 35.488403320 30.458978653 23.500000000 35.458980560 31.384418488 23.500000000 35.384422302 32.233222961 23.500000000 35.233222961 32.981101990 23.499998093 34.981101990 -33.981086731 24.499979019 34.981086731 -33.233219147 24.499984741 35.233203888 -32.384422302 24.499996185 35.384407043 -31.458978653 24.500000000 35.458972931 -30.488407135 24.500000000 35.488403320 -29.497472763 24.500000000 35.497474670 -28.499593735 24.500000000 35.499591827 -27.499954224 24.500000000 35.499954224 -26.499996185 24.500000000 35.499996185 -25.500000000 24.500000000 35.500000000 -24.500000000 24.500000000 35.500000000 -23.500000000 24.500000000 35.500000000 -22.500000000 24.500000000 35.500000000 -21.500000000 24.500000000 35.500000000 -20.500000000 24.500000000 35.500000000 -19.500000000 24.500000000 35.500000000 -18.500000000 24.500000000 35.500000000 -17.500000000 24.500000000 35.500000000 -16.500000000 24.500000000 35.500000000 -15.500000000 24.500000000 35.500000000 -14.500000000 24.500000000 35.500000000 -13.500000000 24.500000000 35.500000000 -12.500000000 24.500000000 35.500000000 -11.500000000 24.500000000 35.500000000 -10.500000000 24.500000000 35.500000000 -9.500000000 24.500000000 35.500000000 -8.500000000 24.500000000 35.500000000 -7.500000000 24.500000000 35.500000000 -6.500000000 24.500000000 35.500000000 -5.500000000 24.500000000 35.500000000 -4.500000000 24.500000000 35.500000000 -3.500000000 24.500000000 35.500000000 -2.500000000 24.500000000 35.500000000 -1.500000000 24.500000000 35.500000000 -0.500000000 24.500000000 35.500000000 0.500000000 24.500000000 35.500000000 1.500000000 24.500000000 35.500000000 2.500000000 24.500000000 35.500000000 3.500000000 24.500000000 35.500000000 4.500000000 24.500000000 35.500000000 5.500000000 24.500000000 35.500000000 6.500000000 24.500000000 35.500000000 7.500000000 24.500000000 35.500000000 8.500000000 24.500000000 35.500000000 9.500000000 24.500000000 35.500000000 10.500000000 24.500000000 35.500000000 11.500000000 24.500000000 35.500000000 12.500000000 24.500000000 35.500000000 13.500000000 24.500000000 35.500000000 14.500000000 24.500000000 35.500000000 15.500000000 24.500000000 35.500000000 16.500000000 24.500000000 35.500000000 17.500000000 24.500000000 35.500000000 18.500000000 24.500000000 35.500000000 19.500000000 24.500000000 35.500000000 20.500000000 24.500000000 35.500000000 21.500000000 24.500000000 35.500000000 22.500000000 24.500000000 35.500000000 23.500000000 24.500000000 35.500000000 24.500000000 24.500000000 35.500000000 25.499996185 24.500000000 35.499996185 26.499954224 24.500000000 35.499954224 27.499591827 24.500000000 35.499591827 28.497470856 24.500000000 35.497467041 29.488407135 24.500000000 35.488403320 30.458978653 24.500000000 35.458976746 31.384418488 24.499996185 35.384407043 32.233219147 24.499988556 35.233207703 32.981086731 24.499979019 34.981086731 -33.980972290 25.499826431 34.980957031 -33.233169556 25.499874115 35.233074188 -32.384407043 25.499950409 35.384307861 -31.458978653 25.499988556 35.458930969 -30.488407135 25.499996185 35.488388062 -29.497472763 25.499996185 35.497470856 -28.499593735 25.499996185 35.499588013 -27.499954224 25.499996185 35.499950409 -26.499996185 25.499996185 35.499992371 -25.500000000 25.499996185 35.499996185 -24.500000000 25.499996185 35.499996185 -23.500000000 25.499996185 35.499996185 -22.500000000 25.499996185 35.499996185 -21.500000000 25.499996185 35.499996185 -20.500000000 25.499996185 35.499996185 -19.500000000 25.499996185 35.499996185 -18.500000000 25.499996185 35.499996185 -17.500000000 25.499996185 35.499996185 -16.500000000 25.499996185 35.499996185 -15.500000000 25.499996185 35.499996185 -14.500000000 25.499996185 35.499996185 -13.500000000 25.499996185 35.499996185 -12.500000000 25.499996185 35.499996185 -11.500000000 25.499996185 35.499996185 -10.500000000 25.499996185 35.499996185 -9.500000000 25.499996185 35.499996185 -8.500000000 25.499996185 35.499996185 -7.500000000 25.499996185 35.499996185 -6.500000000 25.499996185 35.499996185 -5.500000000 25.499996185 35.499996185 -4.500000000 25.499996185 35.499996185 -3.500000000 25.499996185 35.499996185 -2.500000000 25.499996185 35.499996185 -1.500000000 25.499996185 35.499996185 -0.500000000 25.499996185 35.499996185 0.500000000 25.499996185 35.499996185 1.500000000 25.499996185 35.499996185 2.500000000 25.499996185 35.499996185 3.500000000 25.499996185 35.499996185 4.500000000 25.499996185 35.499996185 5.500000000 25.499996185 35.499996185 6.500000000 25.499996185 35.499996185 7.500000000 25.499996185 35.499996185 8.500000000 25.499996185 35.499996185 9.500000000 25.499996185 35.499996185 10.500000000 25.499996185 35.499996185 11.500000000 25.499996185 35.499996185 12.500000000 25.499996185 35.499996185 13.500000000 25.499996185 35.499996185 14.500000000 25.499996185 35.499996185 15.500000000 25.499996185 35.499996185 16.500000000 25.499996185 35.499996185 17.500000000 25.499996185 35.499996185 18.500000000 25.499996185 35.499996185 19.500000000 25.499996185 35.499996185 20.500000000 25.499996185 35.499996185 21.500000000 25.499996185 35.499996185 22.500000000 25.499996185 35.499996185 23.500000000 25.499996185 35.499996185 24.500000000 25.499996185 35.499996185 25.499996185 25.499996185 35.499992371 26.499954224 25.499996185 35.499950409 27.499591827 25.499996185 35.499588013 28.497470856 25.499996185 35.497467041 29.488407135 25.499996185 35.488391876 30.458974838 25.499988556 35.458934784 31.384403229 25.499950409 35.384307861 32.233165741 25.499874115 35.233070374 32.980972290 25.499826431 34.980957031 -33.980331421 26.498952866 34.980201721 -33.232864380 26.499227524 35.232303619 -32.384296417 26.499622345 35.383720398 -31.458948135 26.499858856 35.458606720 -30.488397598 26.499938965 35.488258362 -29.497472763 26.499954224 35.497406006 -28.499593735 26.499954224 35.499549866 -27.499954224 26.499954224 35.499908447 -26.499996185 26.499954224 35.499950409 -25.500000000 26.499954224 35.499954224 -24.500000000 26.499954224 35.499954224 -23.500000000 26.499954224 35.499954224 -22.500000000 26.499954224 35.499954224 -21.500000000 26.499954224 35.499954224 -20.500000000 26.499954224 35.499954224 -19.500000000 26.499954224 35.499954224 -18.500000000 26.499954224 35.499954224 -17.500000000 26.499954224 35.499954224 -16.500000000 26.499954224 35.499954224 -15.500000000 26.499954224 35.499954224 -14.500000000 26.499954224 35.499954224 -13.500000000 26.499954224 35.499954224 -12.500000000 26.499954224 35.499954224 -11.500000000 26.499954224 35.499954224 -10.500000000 26.499954224 35.499954224 -9.500000000 26.499954224 35.499954224 -8.500000000 26.499954224 35.499954224 -7.500000000 26.499954224 35.499954224 -6.500000000 26.499954224 35.499954224 -5.500000000 26.499954224 35.499954224 -4.500000000 26.499954224 35.499954224 -3.500000000 26.499954224 35.499954224 -2.500000000 26.499954224 35.499954224 -1.500000000 26.499954224 35.499954224 -0.500000000 26.499954224 35.499954224 0.500000000 26.499954224 35.499954224 1.500000000 26.499954224 35.499954224 2.500000000 26.499954224 35.499954224 3.500000000 26.499954224 35.499954224 4.500000000 26.499954224 35.499954224 5.500000000 26.499954224 35.499954224 6.500000000 26.499954224 35.499954224 7.500000000 26.499954224 35.499954224 8.500000000 26.499954224 35.499954224 9.500000000 26.499954224 35.499954224 10.500000000 26.499954224 35.499954224 11.500000000 26.499954224 35.499954224 12.500000000 26.499954224 35.499954224 13.500000000 26.499954224 35.499954224 14.500000000 26.499954224 35.499954224 15.500000000 26.499954224 35.499954224 16.500000000 26.499954224 35.499954224 17.500000000 26.499954224 35.499954224 18.500000000 26.499954224 35.499954224 19.500000000 26.499954224 35.499954224 20.500000000 26.499954224 35.499954224 21.500000000 26.499954224 35.499954224 22.500000000 26.499954224 35.499954224 23.500000000 26.499954224 35.499954224 24.500000000 26.499954224 35.499954224 25.499996185 26.499954224 35.499950409 26.499954224 26.499954224 35.499908447 27.499591827 26.499954224 35.499542236 28.497470856 26.499954224 35.497409821 29.488397598 26.499938965 35.488258362 30.458948135 26.499862671 35.458606720 31.384296417 26.499622345 35.383720398 32.232860565 26.499225616 35.232303619 32.980327606 26.498952866 34.980201721 -33.977615356 27.495172501 34.976860046 -33.231597900 27.496379852 35.228954315 -32.383811951 27.498052597 35.381027222 -31.458766937 27.499073029 35.456939697 -30.488346100 27.499475479 35.487373352 -29.497461319 27.499576569 35.496910095 -28.499593735 27.499591827 35.499160767 -27.499954224 27.499591827 35.499542236 -26.499996185 27.499591827 35.499591827 -25.500000000 27.499591827 35.499591827 -24.500000000 27.499591827 35.499591827 -23.500000000 27.499591827 35.499591827 -22.500000000 27.499591827 35.499591827 -21.500000000 27.499591827 35.499591827 -20.500000000 27.499591827 35.499591827 -19.500000000 27.499591827 35.499591827 -18.500000000 27.499591827 35.499591827 -17.500000000 27.499591827 35.499591827 -16.500000000 27.499591827 35.499591827 -15.500000000 27.499591827 35.499591827 -14.500000000 27.499591827 35.499591827 -13.500000000 27.499591827 35.499591827 -12.500000000 27.499591827 35.499591827 -11.500000000 27.499591827 35.499591827 -10.500000000 27.499591827 35.499591827 -9.500000000 27.499591827 35.499591827 -8.500000000 27.499591827 35.499591827 -7.500000000 27.499591827 35.499591827 -6.500000000 27.499591827 35.499591827 -5.500000000 27.499591827 35.499591827 -4.500000000 27.499591827 35.499591827 -3.500000000 27.499591827 35.499591827 -2.500000000 27.499591827 35.499591827 -1.500000000 27.499591827 35.499591827 -0.500000000 27.499591827 35.499591827 0.500000000 27.499591827 35.499591827 1.500000000 27.499591827 35.499591827 2.500000000 27.499591827 35.499591827 3.500000000 27.499591827 35.499591827 4.500000000 27.499591827 35.499591827 5.500000000 27.499591827 35.499591827 6.500000000 27.499591827 35.499591827 7.500000000 27.499591827 35.499591827 8.500000000 27.499591827 35.499591827 9.500000000 27.499591827 35.499591827 10.500000000 27.499591827 35.499591827 11.500000000 27.499591827 35.499591827 12.500000000 27.499591827 35.499591827 13.500000000 27.499591827 35.499591827 14.500000000 27.499591827 35.499591827 15.500000000 27.499591827 35.499591827 16.500000000 27.499591827 35.499591827 17.500000000 27.499591827 35.499591827 18.500000000 27.499591827 35.499591827 19.500000000 27.499591827 35.499591827 20.500000000 27.499591827 35.499591827 21.500000000 27.499591827 35.499591827 22.500000000 27.499591827 35.499591827 23.500000000 27.499591827 35.499591827 24.500000000 27.499591827 35.499591827 25.499996185 27.499591827 35.499591827 26.499954224 27.499591827 35.499546051 27.499591827 27.499591827 35.499164581 28.497457504 27.499576569 35.496910095 29.488346100 27.499475479 35.487373352 30.458766937 27.499073029 35.456939697 31.383810043 27.498052597 35.381027222 32.231597900 27.496379852 35.228954315 32.977619171 27.495172501 34.976860046 -33.968864441 28.481937408 34.965763092 -33.227870941 28.486719131 35.217517853 -32.382308960 28.492321014 35.371490479 -31.458078384 28.495611191 35.450428009 -30.488048553 28.496957779 35.483341217 -29.497375488 28.497371674 35.494178772 -28.499578476 28.497461319 35.496910095 -27.499954224 28.497470856 35.497402191 -26.499996185 28.497470856 35.497467041 -25.500000000 28.497470856 35.497470856 -24.500000000 28.497470856 35.497470856 -23.500000000 28.497470856 35.497470856 -22.500000000 28.497470856 35.497470856 -21.500000000 28.497470856 35.497470856 -20.500000000 28.497470856 35.497470856 -19.500000000 28.497470856 35.497470856 -18.500000000 28.497470856 35.497470856 -17.500000000 28.497470856 35.497470856 -16.500000000 28.497470856 35.497470856 -15.500000000 28.497470856 35.497470856 -14.500000000 28.497470856 35.497470856 -13.500000000 28.497470856 35.497470856 -12.500000000 28.497470856 35.497470856 -11.500000000 28.497470856 35.497470856 -10.500000000 28.497470856 35.497470856 -9.500000000 28.497470856 35.497470856 -8.500000000 28.497470856 35.497470856 -7.500000000 28.497470856 35.497470856 -6.500000000 28.497470856 35.497470856 -5.500000000 28.497470856 35.497470856 -4.500000000 28.497470856 35.497470856 -3.500000000 28.497470856 35.497470856 -2.500000000 28.497470856 35.497470856 -1.500000000 28.497470856 35.497470856 -0.500000000 28.497470856 35.497470856 0.500000000 28.497470856 35.497470856 1.500000000 28.497470856 35.497470856 2.500000000 28.497470856 35.497470856 3.500000000 28.497470856 35.497470856 4.500000000 28.497470856 35.497470856 5.500000000 28.497470856 35.497470856 6.500000000 28.497470856 35.497470856 7.500000000 28.497470856 35.497470856 8.500000000 28.497470856 35.497470856 9.500000000 28.497470856 35.497470856 10.500000000 28.497470856 35.497470856 11.500000000 28.497470856 35.497470856 12.500000000 28.497470856 35.497470856 13.500000000 28.497470856 35.497470856 14.500000000 28.497470856 35.497470856 15.500000000 28.497470856 35.497470856 16.500000000 28.497470856 35.497470856 17.500000000 28.497470856 35.497470856 18.500000000 28.497470856 35.497470856 19.500000000 28.497470856 35.497470856 20.500000000 28.497470856 35.497470856 21.500000000 28.497470856 35.497470856 22.500000000 28.497470856 35.497470856 23.500000000 28.497470856 35.497470856 24.500000000 28.497470856 35.497470856 25.499996185 28.497470856 35.497467041 26.499954224 28.497470856 35.497406006 27.499576569 28.497457504 35.496910095 28.497371674 28.497375488 35.494174957 29.488048553 28.496957779 35.483337402 30.458078384 28.495611191 35.450428009 31.382312775 28.492321014 35.371490479 32.227874756 28.486719131 35.217510223 32.968864441 28.481939316 34.965759277 -33.946811676 29.442840576 34.937091827 -33.220714569 29.460596085 35.185966492 -32.379219055 29.476003647 35.344280243 -31.456085205 29.483789444 35.430480957 -30.486968994 29.486968994 35.469238281 -29.496959686 29.488048553 35.483337402 -28.499475479 29.488346100 35.487373352 -27.499938965 29.488399506 35.488258362 -26.499996185 29.488407135 35.488391876 -25.500000000 29.488407135 35.488403320 -24.500000000 29.488407135 35.488407135 -23.500000000 29.488407135 35.488407135 -22.500000000 29.488407135 35.488407135 -21.500000000 29.488407135 35.488407135 -20.500000000 29.488407135 35.488407135 -19.500000000 29.488407135 35.488407135 -18.500000000 29.488407135 35.488407135 -17.500000000 29.488407135 35.488407135 -16.500000000 29.488407135 35.488407135 -15.500000000 29.488407135 35.488407135 -14.500000000 29.488407135 35.488407135 -13.500000000 29.488407135 35.488407135 -12.500000000 29.488407135 35.488407135 -11.500000000 29.488407135 35.488407135 -10.500000000 29.488407135 35.488407135 -9.500000000 29.488407135 35.488407135 -8.500000000 29.488407135 35.488407135 -7.500000000 29.488407135 35.488407135 -6.500000000 29.488407135 35.488407135 -5.500000000 29.488407135 35.488407135 -4.500000000 29.488407135 35.488407135 -3.500000000 29.488407135 35.488407135 -2.500000000 29.488407135 35.488407135 -1.500000000 29.488407135 35.488407135 -0.500000000 29.488407135 35.488407135 0.500000000 29.488407135 35.488407135 1.500000000 29.488407135 35.488407135 2.500000000 29.488407135 35.488407135 3.500000000 29.488407135 35.488407135 4.500000000 29.488407135 35.488407135 5.500000000 29.488407135 35.488407135 6.500000000 29.488407135 35.488407135 7.500000000 29.488407135 35.488407135 8.500000000 29.488407135 35.488407135 9.500000000 29.488407135 35.488407135 10.500000000 29.488407135 35.488407135 11.500000000 29.488407135 35.488407135 12.500000000 29.488407135 35.488407135 13.500000000 29.488407135 35.488407135 14.500000000 29.488407135 35.488407135 15.500000000 29.488407135 35.488407135 16.500000000 29.488407135 35.488407135 17.500000000 29.488407135 35.488407135 18.500000000 29.488407135 35.488407135 19.500000000 29.488407135 35.488407135 20.500000000 29.488407135 35.488407135 21.500000000 29.488407135 35.488407135 22.500000000 29.488407135 35.488407135 23.500000000 29.488407135 35.488407135 24.500000000 29.488407135 35.488407135 25.499996185 29.488407135 35.488391876 26.499938965 29.488399506 35.488258362 27.499475479 29.488346100 35.487373352 28.496959686 29.488048553 35.483337402 29.486968994 29.486965179 35.469238281 30.456085205 29.483789444 35.430480957 31.379222870 29.476003647 35.344280243 32.220714569 29.460596085 35.185966492 32.946811676 29.442840576 34.937091827 -33.903377533 30.336603165 34.879737854 -33.216838837 30.405670166 35.112342834 -32.375358582 30.438953400 35.280399323 -31.451217651 30.451217651 35.380989075 -30.483789444 30.456085205 35.430473328 -29.495611191 30.458078384 35.450424194 -28.499073029 30.458770752 35.456939697 -27.499858856 30.458950043 35.458606720 -26.499988556 30.458980560 35.458930969 -25.500000000 30.458980560 35.458976746 -24.500000000 30.458980560 35.458976746 -23.500000000 30.458980560 35.458976746 -22.500000000 30.458980560 35.458976746 -21.500000000 30.458980560 35.458976746 -20.500000000 30.458980560 35.458976746 -19.500000000 30.458980560 35.458976746 -18.500000000 30.458980560 35.458976746 -17.500000000 30.458980560 35.458976746 -16.500000000 30.458980560 35.458976746 -15.500000000 30.458980560 35.458976746 -14.500000000 30.458980560 35.458976746 -13.500000000 30.458980560 35.458976746 -12.500000000 30.458980560 35.458976746 -11.500000000 30.458980560 35.458976746 -10.500000000 30.458980560 35.458976746 -9.500000000 30.458980560 35.458976746 -8.500000000 30.458980560 35.458976746 -7.500000000 30.458980560 35.458976746 -6.500000000 30.458980560 35.458976746 -5.500000000 30.458980560 35.458976746 -4.500000000 30.458980560 35.458976746 -3.500000000 30.458980560 35.458976746 -2.500000000 30.458980560 35.458976746 -1.500000000 30.458980560 35.458976746 -0.500000000 30.458980560 35.458976746 0.500000000 30.458980560 35.458976746 1.500000000 30.458980560 35.458976746 2.500000000 30.458980560 35.458976746 3.500000000 30.458980560 35.458976746 4.500000000 30.458980560 35.458976746 5.500000000 30.458980560 35.458976746 6.500000000 30.458980560 35.458976746 7.500000000 30.458980560 35.458976746 8.500000000 30.458980560 35.458976746 9.500000000 30.458980560 35.458976746 10.500000000 30.458980560 35.458976746 11.500000000 30.458980560 35.458976746 12.500000000 30.458980560 35.458976746 13.500000000 30.458980560 35.458976746 14.500000000 30.458980560 35.458976746 15.500000000 30.458980560 35.458976746 16.500000000 30.458980560 35.458976746 17.500000000 30.458980560 35.458976746 18.500000000 30.458980560 35.458976746 19.500000000 30.458980560 35.458976746 20.500000000 30.458980560 35.458976746 21.500000000 30.458980560 35.458976746 22.500000000 30.458980560 35.458976746 23.500000000 30.458980560 35.458976746 24.500000000 30.458980560 35.458972931 25.499988556 30.458978653 35.458930969 26.499858856 30.458948135 35.458606720 27.499073029 30.458770752 35.456939697 28.495611191 30.458080292 35.450424194 29.483789444 30.456085205 35.430473328 30.451217651 30.451217651 35.380989075 31.375356674 30.438949585 35.280395508 32.216835022 30.405673981 35.112342834 32.903373718 30.336603165 34.879737854 -33.840930939 31.035345078 34.797355652 -33.254276276 31.334241867 34.954723358 -32.371025085 31.371026993 35.154674530 -31.438953400 31.375360489 35.280391693 -30.476007462 31.379222870 35.344280243 -29.492319107 31.382312775 35.371486664 -28.498052597 31.383813858 35.381027222 -27.499622345 31.384298325 35.383720398 -26.499948502 31.384403229 35.384304047 -25.499996185 31.384418488 35.384407043 -24.500000000 31.384418488 35.384414673 -23.500000000 31.384418488 35.384414673 -22.500000000 31.384418488 35.384414673 -21.500000000 31.384418488 35.384414673 -20.500000000 31.384418488 35.384414673 -19.500000000 31.384418488 35.384414673 -18.500000000 31.384418488 35.384414673 -17.500000000 31.384418488 35.384414673 -16.500000000 31.384418488 35.384414673 -15.500000000 31.384418488 35.384414673 -14.500000000 31.384418488 35.384414673 -13.500000000 31.384418488 35.384414673 -12.500000000 31.384418488 35.384414673 -11.500000000 31.384418488 35.384414673 -10.500000000 31.384418488 35.384414673 -9.500000000 31.384418488 35.384414673 -8.500000000 31.384418488 35.384414673 -7.500000000 31.384418488 35.384414673 -6.500000000 31.384418488 35.384414673 -5.500000000 31.384418488 35.384414673 -4.500000000 31.384418488 35.384414673 -3.500000000 31.384418488 35.384414673 -2.500000000 31.384418488 35.384414673 -1.500000000 31.384418488 35.384414673 -0.500000000 31.384418488 35.384414673 0.500000000 31.384418488 35.384414673 1.500000000 31.384418488 35.384414673 2.500000000 31.384418488 35.384414673 3.500000000 31.384418488 35.384414673 4.500000000 31.384418488 35.384414673 5.500000000 31.384418488 35.384414673 6.500000000 31.384418488 35.384414673 7.500000000 31.384418488 35.384414673 8.500000000 31.384418488 35.384414673 9.500000000 31.384418488 35.384414673 10.500000000 31.384418488 35.384414673 11.500000000 31.384418488 35.384414673 12.500000000 31.384418488 35.384414673 13.500000000 31.384418488 35.384414673 14.500000000 31.384418488 35.384414673 15.500000000 31.384418488 35.384414673 16.500000000 31.384418488 35.384414673 17.500000000 31.384418488 35.384414673 18.500000000 31.384418488 35.384414673 19.500000000 31.384418488 35.384414673 20.500000000 31.384418488 35.384414673 21.500000000 31.384418488 35.384414673 22.500000000 31.384418488 35.384414673 23.500000000 31.384418488 35.384410858 24.499996185 31.384418488 35.384407043 25.499948502 31.384403229 35.384304047 26.499618530 31.384296417 35.383716583 27.498050690 31.383813858 35.381023407 28.492321014 31.382312775 35.371486664 29.476007462 31.379222870 35.344280243 30.438953400 31.375360489 35.280395508 31.371026993 31.371026993 35.154670715 32.254272461 31.334243774 34.954723358 32.840927124 31.035345078 34.797355652 -33.030693054 32.030693054 34.846317291 -32.334243774 32.254272461 34.954723358 -31.405673981 32.216838837 35.112342834 -30.460596085 32.220714569 35.185966492 -29.486719131 32.227870941 35.217510223 -28.496377945 32.231601715 35.228950500 -27.499225616 32.232860565 35.232303619 -26.499872208 32.233165741 35.233070374 -25.499986649 32.233215332 35.233203888 -24.499998093 32.233222961 35.233219147 -23.500000000 32.233222961 35.233219147 -22.500000000 32.233222961 35.233219147 -21.500000000 32.233222961 35.233219147 -20.500000000 32.233222961 35.233219147 -19.500000000 32.233222961 35.233219147 -18.500000000 32.233222961 35.233219147 -17.500000000 32.233222961 35.233219147 -16.500000000 32.233222961 35.233219147 -15.500000000 32.233222961 35.233219147 -14.500000000 32.233222961 35.233219147 -13.500000000 32.233222961 35.233219147 -12.500000000 32.233222961 35.233219147 -11.500000000 32.233222961 35.233219147 -10.500000000 32.233222961 35.233219147 -9.500000000 32.233222961 35.233219147 -8.500000000 32.233222961 35.233219147 -7.500000000 32.233222961 35.233219147 -6.500000000 32.233222961 35.233219147 -5.500000000 32.233222961 35.233219147 -4.500000000 32.233222961 35.233219147 -3.500000000 32.233222961 35.233219147 -2.500000000 32.233222961 35.233219147 -1.500000000 32.233222961 35.233219147 -0.500000000 32.233222961 35.233219147 0.500000000 32.233222961 35.233219147 1.500000000 32.233222961 35.233219147 2.500000000 32.233222961 35.233219147 3.500000000 32.233222961 35.233219147 4.500000000 32.233222961 35.233219147 5.500000000 32.233222961 35.233219147 6.500000000 32.233222961 35.233219147 7.500000000 32.233222961 35.233219147 8.500000000 32.233222961 35.233219147 9.500000000 32.233222961 35.233219147 10.500000000 32.233222961 35.233219147 11.500000000 32.233222961 35.233219147 12.500000000 32.233222961 35.233219147 13.500000000 32.233222961 35.233219147 14.500000000 32.233222961 35.233219147 15.500000000 32.233222961 35.233219147 16.500000000 32.233222961 35.233219147 17.500000000 32.233222961 35.233219147 18.500000000 32.233222961 35.233219147 19.500000000 32.233222961 35.233219147 20.500000000 32.233222961 35.233219147 21.500000000 32.233222961 35.233219147 22.500000000 32.233222961 35.233219147 23.499998093 32.233222961 35.233219147 24.499986649 32.233219147 35.233203888 25.499874115 32.233161926 35.233070374 26.499225616 32.232856750 35.232299805 27.496377945 32.231597900 35.228950500 28.486719131 32.227874756 35.217510223 29.460596085 32.220714569 35.185962677 30.405673981 32.216838837 35.112342834 31.334243774 32.254276276 34.954723358 32.030693054 32.030693054 34.846313477 -32.035343170 32.840934753 34.797355652 -31.336603165 32.903373718 34.879737854 -30.442840576 32.946811676 34.937095642 -29.481933594 32.968864441 34.965763092 -28.495172501 32.977619171 34.976860046 -27.498952866 32.980335236 34.980201721 -26.499826431 32.980972290 34.980957031 -25.499977112 32.981086731 34.981086731 -24.499998093 32.981101990 34.981098175 -23.500000000 32.981101990 34.981098175 -22.500000000 32.981101990 34.981098175 -21.500000000 32.981101990 34.981098175 -20.500000000 32.981101990 34.981098175 -19.500000000 32.981101990 34.981098175 -18.500000000 32.981101990 34.981098175 -17.500000000 32.981101990 34.981098175 -16.500000000 32.981101990 34.981098175 -15.500000000 32.981101990 34.981098175 -14.500000000 32.981101990 34.981098175 -13.500000000 32.981101990 34.981098175 -12.500000000 32.981101990 34.981098175 -11.500000000 32.981101990 34.981098175 -10.500000000 32.981101990 34.981098175 -9.500000000 32.981101990 34.981098175 -8.500000000 32.981101990 34.981098175 -7.500000000 32.981101990 34.981098175 -6.500000000 32.981101990 34.981098175 -5.500000000 32.981101990 34.981098175 -4.500000000 32.981101990 34.981098175 -3.500000000 32.981101990 34.981098175 -2.500000000 32.981101990 34.981098175 -1.500000000 32.981101990 34.981098175 -0.500000000 32.981101990 34.981098175 0.500000000 32.981101990 34.981098175 1.500000000 32.981101990 34.981098175 2.500000000 32.981101990 34.981098175 3.500000000 32.981101990 34.981098175 4.500000000 32.981101990 34.981098175 5.500000000 32.981101990 34.981098175 6.500000000 32.981101990 34.981098175 7.500000000 32.981101990 34.981098175 8.500000000 32.981101990 34.981098175 9.500000000 32.981101990 34.981098175 10.500000000 32.981101990 34.981098175 11.500000000 32.981101990 34.981098175 12.500000000 32.981101990 34.981098175 13.500000000 32.981101990 34.981098175 14.500000000 32.981101990 34.981098175 15.500000000 32.981101990 34.981098175 16.500000000 32.981101990 34.981098175 17.500000000 32.981101990 34.981098175 18.500000000 32.981101990 34.981098175 19.500000000 32.981101990 34.981098175 20.500000000 32.981101990 34.981098175 21.500000000 32.981101990 34.981098175 22.500000000 32.981101990 34.981098175 23.499998093 32.981101990 34.981098175 24.499977112 32.981086731 34.981086731 25.499826431 32.980972290 34.980957031 26.498952866 32.980327606 34.980201721 27.495172501 32.977611542 34.976860046 28.481937408 32.968864441 34.965763092 29.442840576 32.946811676 34.937091827 30.336603165 32.903381348 34.879737854 31.035345078 32.840930939 34.797355652 POLYGONS 62064 248256 3 0 1 66 3 67 66 1 3 0 4818 1 3 4819 1 4818 3 0 66 4888 3 0 4888 4818 3 1 2 67 3 68 67 2 3 1 4819 4820 3 1 4820 2 3 2 3 69 3 2 69 68 3 2 4820 3 3 4821 3 4820 3 3 4 69 3 70 69 4 3 3 4821 4 3 4822 4 4821 3 4 5 71 3 4 71 70 3 4 4822 4823 3 4 4823 5 3 5 6 71 3 72 71 6 3 5 4823 4824 3 5 4824 6 3 6 7 72 3 73 72 7 3 6 4824 4825 3 6 4825 7 3 7 8 74 3 7 74 73 3 7 4825 8 3 4826 8 4825 3 8 9 74 3 75 74 9 3 8 4826 9 3 4827 9 4826 3 9 10 75 3 76 75 10 3 9 4827 10 3 4828 10 4827 3 10 11 77 3 10 77 76 3 10 4828 11 3 4829 11 4828 3 11 12 78 3 11 78 77 3 11 4829 4830 3 11 4830 12 3 12 13 78 3 79 78 13 3 12 4830 4831 3 12 4831 13 3 13 14 79 3 80 79 14 3 13 4831 4832 3 13 4832 14 3 14 15 80 3 81 80 15 3 14 4832 4833 3 14 4833 15 3 15 16 82 3 15 82 81 3 15 4833 4834 3 15 4834 16 3 16 17 83 3 16 83 82 3 16 4834 17 3 4835 17 4834 3 17 18 83 3 84 83 18 3 17 4835 18 3 4836 18 4835 3 18 19 84 3 85 84 19 3 18 4836 19 3 4837 19 4836 3 19 20 85 3 86 85 20 3 19 4837 20 3 4838 20 4837 3 20 21 87 3 20 87 86 3 20 4838 21 3 4839 21 4838 3 21 22 88 3 21 88 87 3 21 4839 22 3 4840 22 4839 3 22 23 89 3 22 89 88 3 22 4840 4841 3 22 4841 23 3 23 24 89 3 90 89 24 3 23 4841 4842 3 23 4842 24 3 24 25 90 3 91 90 25 3 24 4842 4843 3 24 4843 25 3 25 26 91 3 92 91 26 3 25 4843 4844 3 25 4844 26 3 26 27 93 3 26 93 92 3 26 4844 4845 3 26 4845 27 3 27 28 94 3 27 94 93 3 27 4845 4846 3 27 4846 28 3 28 29 95 3 28 95 94 3 28 4846 29 3 4847 29 4846 3 29 30 95 3 96 95 30 3 29 4847 30 3 4848 30 4847 3 30 31 96 3 97 96 31 3 30 4848 31 3 4849 31 4848 3 31 32 97 3 98 97 32 3 31 4849 32 3 4850 32 4849 3 32 33 99 3 32 99 98 3 32 4850 33 3 4851 33 4850 3 33 34 100 3 33 100 99 3 33 4851 34 3 4852 34 4851 3 34 35 101 3 34 101 100 3 34 4852 35 3 4853 35 4852 3 35 36 102 3 35 102 101 3 35 4853 36 3 4854 36 4853 3 36 37 102 3 103 102 37 3 36 4854 4855 3 36 4855 37 3 37 38 103 3 104 103 38 3 37 4855 4856 3 37 4856 38 3 38 39 104 3 105 104 39 3 38 4856 4857 3 38 4857 39 3 39 40 105 3 106 105 40 3 39 4857 4858 3 39 4858 40 3 40 41 107 3 40 107 106 3 40 4858 4859 3 40 4859 41 3 41 42 108 3 41 108 107 3 41 4859 4860 3 41 4860 42 3 42 43 109 3 42 109 108 3 42 4860 4861 3 42 4861 43 3 43 44 110 3 43 110 109 3 43 4861 4862 3 43 4862 44 3 44 45 110 3 111 110 45 3 44 4862 45 3 4863 45 4862 3 45 46 111 3 112 111 46 3 45 4863 46 3 4864 46 4863 3 46 47 112 3 113 112 47 3 46 4864 47 3 4865 47 4864 3 47 48 113 3 114 113 48 3 47 4865 48 3 4866 48 4865 3 48 49 115 3 48 115 114 3 48 4866 49 3 4867 49 4866 3 49 50 116 3 49 116 115 3 49 4867 50 3 4868 50 4867 3 50 51 117 3 50 117 116 3 50 4868 51 3 4869 51 4868 3 51 52 118 3 51 118 117 3 51 4869 52 3 4870 52 4869 3 52 53 118 3 119 118 53 3 52 4870 53 3 4871 53 4870 3 53 54 119 3 120 119 54 3 53 4871 4872 3 53 4872 54 3 54 55 120 3 121 120 55 3 54 4872 4873 3 54 4873 55 3 55 56 121 3 122 121 56 3 55 4873 4874 3 55 4874 56 3 56 57 122 3 123 122 57 3 56 4874 4875 3 56 4875 57 3 57 58 124 3 57 124 123 3 57 4875 4876 3 57 4876 58 3 58 59 125 3 58 125 124 3 58 4876 4877 3 58 4877 59 3 59 60 126 3 59 126 125 3 59 4877 4878 3 59 4878 60 3 60 61 127 3 60 127 126 3 60 4878 4879 3 60 4879 61 3 61 62 128 3 61 128 127 3 61 4879 4880 3 61 4880 62 3 62 63 128 3 129 128 63 3 62 4880 63 3 4881 63 4880 3 63 64 129 3 130 129 64 3 63 4881 64 3 4882 64 4881 3 64 4882 130 3 4889 130 4882 3 65 66 133 3 134 133 66 3 65 4887 66 3 4888 66 4887 3 65 133 4895 3 65 4895 4887 3 66 67 135 3 66 135 134 3 67 68 136 3 67 136 135 3 68 69 137 3 68 137 136 3 69 70 138 3 69 138 137 3 70 71 139 3 70 139 138 3 71 72 140 3 71 140 139 3 72 73 140 3 141 140 73 3 73 74 141 3 142 141 74 3 74 75 142 3 143 142 75 3 75 76 143 3 144 143 76 3 76 77 144 3 145 144 77 3 77 78 146 3 77 146 145 3 78 79 147 3 78 147 146 3 79 80 148 3 79 148 147 3 80 81 149 3 80 149 148 3 81 82 150 3 81 150 149 3 82 83 150 3 151 150 83 3 83 84 151 3 152 151 84 3 84 85 152 3 153 152 85 3 85 86 153 3 154 153 86 3 86 87 154 3 155 154 87 3 87 88 155 3 156 155 88 3 88 89 157 3 88 157 156 3 89 90 158 3 89 158 157 3 90 91 159 3 90 159 158 3 91 92 160 3 91 160 159 3 92 93 161 3 92 161 160 3 93 94 162 3 93 162 161 3 94 95 162 3 163 162 95 3 95 96 163 3 164 163 96 3 96 97 164 3 165 164 97 3 97 98 165 3 166 165 98 3 98 99 166 3 167 166 99 3 99 100 167 3 168 167 100 3 100 101 169 3 100 169 168 3 101 102 170 3 101 170 169 3 102 103 171 3 102 171 170 3 103 104 172 3 103 172 171 3 104 105 173 3 104 173 172 3 105 106 174 3 105 174 173 3 106 107 174 3 175 174 107 3 107 108 175 3 176 175 108 3 108 109 176 3 177 176 109 3 109 110 177 3 178 177 110 3 110 111 178 3 179 178 111 3 111 112 179 3 180 179 112 3 112 113 180 3 181 180 113 3 113 114 182 3 113 182 181 3 114 115 183 3 114 183 182 3 115 116 184 3 115 184 183 3 116 117 185 3 116 185 184 3 117 118 186 3 117 186 185 3 118 119 187 3 118 187 186 3 119 120 187 3 188 187 120 3 120 121 188 3 189 188 121 3 121 122 189 3 190 189 122 3 122 123 190 3 191 190 123 3 123 124 191 3 192 191 124 3 124 125 192 3 193 192 125 3 125 126 193 3 194 193 126 3 126 127 195 3 126 195 194 3 127 128 196 3 127 196 195 3 128 129 197 3 128 197 196 3 129 130 198 3 129 198 197 3 130 131 199 3 130 199 198 3 130 4889 4890 3 130 4890 131 3 131 4890 4896 3 131 4896 199 3 132 133 202 3 132 202 201 3 132 4894 4895 3 132 4895 133 3 132 201 4894 3 4900 4894 201 3 133 134 202 3 203 202 134 3 134 135 203 3 204 203 135 3 135 136 204 3 205 204 136 3 136 137 205 3 206 205 137 3 137 138 206 3 207 206 138 3 138 139 207 3 208 207 139 3 139 140 208 3 209 208 140 3 140 141 210 3 140 210 209 3 141 142 211 3 141 211 210 3 142 143 212 3 142 212 211 3 143 144 213 3 143 213 212 3 144 145 214 3 144 214 213 3 145 146 215 3 145 215 214 3 146 147 216 3 146 216 215 3 147 148 217 3 147 217 216 3 148 149 217 3 218 217 149 3 149 150 218 3 219 218 150 3 150 151 219 3 220 219 151 3 151 152 220 3 221 220 152 3 152 153 221 3 222 221 153 3 153 154 222 3 223 222 154 3 154 155 223 3 224 223 155 3 155 156 225 3 155 225 224 3 156 157 226 3 156 226 225 3 157 158 227 3 157 227 226 3 158 159 228 3 158 228 227 3 159 160 229 3 159 229 228 3 160 161 230 3 160 230 229 3 161 162 231 3 161 231 230 3 162 163 232 3 162 232 231 3 163 164 232 3 233 232 164 3 164 165 233 3 234 233 165 3 165 166 234 3 235 234 166 3 166 167 235 3 236 235 167 3 167 168 236 3 237 236 168 3 168 169 237 3 238 237 169 3 169 170 238 3 239 238 170 3 170 171 239 3 240 239 171 3 171 172 241 3 171 241 240 3 172 173 242 3 172 242 241 3 173 174 243 3 173 243 242 3 174 175 244 3 174 244 243 3 175 176 245 3 175 245 244 3 176 177 246 3 176 246 245 3 177 178 247 3 177 247 246 3 178 179 248 3 178 248 247 3 179 180 248 3 249 248 180 3 180 181 249 3 250 249 181 3 181 182 250 3 251 250 182 3 182 183 251 3 252 251 183 3 183 184 252 3 253 252 184 3 184 185 253 3 254 253 185 3 185 186 254 3 255 254 186 3 186 187 255 3 256 255 187 3 187 188 257 3 187 257 256 3 188 189 258 3 188 258 257 3 189 190 259 3 189 259 258 3 190 191 260 3 190 260 259 3 191 192 261 3 191 261 260 3 192 193 262 3 192 262 261 3 193 194 263 3 193 263 262 3 194 195 264 3 194 264 263 3 195 196 265 3 195 265 264 3 196 197 265 3 266 265 197 3 197 198 266 3 267 266 198 3 198 199 267 3 268 267 199 3 199 200 268 3 269 268 200 3 199 4896 200 3 4897 200 4896 3 200 4897 269 3 4901 269 4897 3 201 202 270 3 271 270 202 3 201 270 4900 3 4904 4900 270 3 202 203 271 3 272 271 203 3 203 204 272 3 273 272 204 3 204 205 273 3 274 273 205 3 205 206 275 3 205 275 274 3 206 207 276 3 206 276 275 3 207 208 277 3 207 277 276 3 208 209 278 3 208 278 277 3 209 210 279 3 209 279 278 3 210 211 280 3 210 280 279 3 211 212 281 3 211 281 280 3 212 213 282 3 212 282 281 3 213 214 283 3 213 283 282 3 214 215 283 3 284 283 215 3 215 216 284 3 285 284 216 3 216 217 285 3 286 285 217 3 217 218 286 3 287 286 218 3 218 219 287 3 288 287 219 3 219 220 288 3 289 288 220 3 220 221 289 3 290 289 221 3 221 222 290 3 291 290 222 3 222 223 291 3 292 291 223 3 223 224 293 3 223 293 292 3 224 225 294 3 224 294 293 3 225 226 295 3 225 295 294 3 226 227 296 3 226 296 295 3 227 228 297 3 227 297 296 3 228 229 298 3 228 298 297 3 229 230 299 3 229 299 298 3 230 231 300 3 230 300 299 3 231 232 301 3 231 301 300 3 232 233 301 3 302 301 233 3 233 234 302 3 303 302 234 3 234 235 303 3 304 303 235 3 235 236 304 3 305 304 236 3 236 237 305 3 306 305 237 3 237 238 306 3 307 306 238 3 238 239 307 3 308 307 239 3 239 240 308 3 309 308 240 3 240 241 309 3 310 309 241 3 241 242 311 3 241 311 310 3 242 243 312 3 242 312 311 3 243 244 313 3 243 313 312 3 244 245 314 3 244 314 313 3 245 246 315 3 245 315 314 3 246 247 316 3 246 316 315 3 247 248 317 3 247 317 316 3 248 249 318 3 248 318 317 3 249 250 319 3 249 319 318 3 250 251 320 3 250 320 319 3 251 252 320 3 321 320 252 3 252 253 321 3 322 321 253 3 253 254 322 3 323 322 254 3 254 255 323 3 324 323 255 3 255 256 324 3 325 324 256 3 256 257 325 3 326 325 257 3 257 258 326 3 327 326 258 3 258 259 327 3 328 327 259 3 259 260 328 3 329 328 260 3 260 261 329 3 330 329 261 3 261 262 331 3 261 331 330 3 262 263 332 3 262 332 331 3 263 264 333 3 263 333 332 3 264 265 334 3 264 334 333 3 265 266 335 3 265 335 334 3 266 267 336 3 266 336 335 3 267 268 337 3 267 337 336 3 268 269 338 3 268 338 337 3 269 4901 338 3 4905 338 4901 3 270 271 340 3 270 340 339 3 270 339 4908 3 270 4908 4904 3 271 272 340 3 341 340 272 3 272 273 341 3 342 341 273 3 273 274 342 3 343 342 274 3 274 275 343 3 344 343 275 3 275 276 344 3 345 344 276 3 276 277 345 3 346 345 277 3 277 278 346 3 347 346 278 3 278 279 347 3 348 347 279 3 279 280 348 3 349 348 280 3 280 281 349 3 350 349 281 3 281 282 351 3 281 351 350 3 282 283 352 3 282 352 351 3 283 284 353 3 283 353 352 3 284 285 354 3 284 354 353 3 285 286 355 3 285 355 354 3 286 287 356 3 286 356 355 3 287 288 357 3 287 357 356 3 288 289 358 3 288 358 357 3 289 290 359 3 289 359 358 3 290 291 360 3 290 360 359 3 291 292 361 3 291 361 360 3 292 293 361 3 362 361 293 3 293 294 362 3 363 362 294 3 294 295 363 3 364 363 295 3 295 296 364 3 365 364 296 3 296 297 365 3 366 365 297 3 297 298 366 3 367 366 298 3 298 299 367 3 368 367 299 3 299 300 368 3 369 368 300 3 300 301 369 3 370 369 301 3 301 302 370 3 371 370 302 3 302 303 372 3 302 372 371 3 303 304 373 3 303 373 372 3 304 305 374 3 304 374 373 3 305 306 375 3 305 375 374 3 306 307 376 3 306 376 375 3 307 308 377 3 307 377 376 3 308 309 378 3 308 378 377 3 309 310 379 3 309 379 378 3 310 311 380 3 310 380 379 3 311 312 381 3 311 381 380 3 312 313 382 3 312 382 381 3 313 314 382 3 383 382 314 3 314 315 383 3 384 383 315 3 315 316 384 3 385 384 316 3 316 317 385 3 386 385 317 3 317 318 386 3 387 386 318 3 318 319 387 3 388 387 319 3 319 320 388 3 389 388 320 3 320 321 389 3 390 389 321 3 321 322 390 3 391 390 322 3 322 323 391 3 392 391 323 3 323 324 392 3 393 392 324 3 324 325 394 3 324 394 393 3 325 326 395 3 325 395 394 3 326 327 396 3 326 396 395 3 327 328 397 3 327 397 396 3 328 329 398 3 328 398 397 3 329 330 399 3 329 399 398 3 330 331 400 3 330 400 399 3 331 332 401 3 331 401 400 3 332 333 402 3 332 402 401 3 333 334 403 3 333 403 402 3 334 335 404 3 334 404 403 3 335 336 404 3 405 404 336 3 336 337 405 3 406 405 337 3 337 338 406 3 407 406 338 3 338 4905 407 3 4909 407 4905 3 339 340 408 3 409 408 340 3 339 408 4912 3 339 4912 4908 3 340 341 409 3 410 409 341 3 341 342 410 3 411 410 342 3 342 343 411 3 412 411 343 3 343 344 412 3 413 412 344 3 344 345 413 3 414 413 345 3 345 346 414 3 415 414 346 3 346 347 415 3 416 415 347 3 347 348 417 3 347 417 416 3 348 349 418 3 348 418 417 3 349 350 419 3 349 419 418 3 350 351 420 3 350 420 419 3 351 352 421 3 351 421 420 3 352 353 422 3 352 422 421 3 353 354 423 3 353 423 422 3 354 355 424 3 354 424 423 3 355 356 425 3 355 425 424 3 356 357 426 3 356 426 425 3 357 358 427 3 357 427 426 3 358 359 427 3 428 427 359 3 359 360 428 3 429 428 360 3 360 361 429 3 430 429 361 3 361 362 430 3 431 430 362 3 362 363 431 3 432 431 363 3 363 364 432 3 433 432 364 3 364 365 433 3 434 433 365 3 365 366 434 3 435 434 366 3 366 367 435 3 436 435 367 3 367 368 436 3 437 436 368 3 368 369 437 3 438 437 369 3 369 370 438 3 439 438 370 3 370 371 440 3 370 440 439 3 371 372 441 3 371 441 440 3 372 373 442 3 372 442 441 3 373 374 443 3 373 443 442 3 374 375 444 3 374 444 443 3 375 376 445 3 375 445 444 3 376 377 446 3 376 446 445 3 377 378 447 3 377 447 446 3 378 379 448 3 378 448 447 3 379 380 449 3 379 449 448 3 380 381 450 3 380 450 449 3 381 382 451 3 381 451 450 3 382 383 451 3 452 451 383 3 383 384 452 3 453 452 384 3 384 385 453 3 454 453 385 3 385 386 454 3 455 454 386 3 386 387 455 3 456 455 387 3 387 388 456 3 457 456 388 3 388 389 457 3 458 457 389 3 389 390 458 3 459 458 390 3 390 391 459 3 460 459 391 3 391 392 460 3 461 460 392 3 392 393 461 3 462 461 393 3 393 394 462 3 463 462 394 3 394 395 464 3 394 464 463 3 395 396 465 3 395 465 464 3 396 397 466 3 396 466 465 3 397 398 467 3 397 467 466 3 398 399 468 3 398 468 467 3 399 400 469 3 399 469 468 3 400 401 470 3 400 470 469 3 401 402 471 3 401 471 470 3 402 403 472 3 402 472 471 3 403 404 473 3 403 473 472 3 404 405 474 3 404 474 473 3 405 406 475 3 405 475 474 3 406 407 475 3 476 475 407 3 407 4909 4913 3 407 4913 476 3 408 409 477 3 478 477 409 3 408 477 4916 3 408 4916 4912 3 409 410 478 3 479 478 410 3 410 411 479 3 480 479 411 3 411 412 480 3 481 480 412 3 412 413 481 3 482 481 413 3 413 414 482 3 483 482 414 3 414 415 483 3 484 483 415 3 415 416 484 3 485 484 416 3 416 417 485 3 486 485 417 3 417 418 486 3 487 486 418 3 418 419 487 3 488 487 419 3 419 420 489 3 419 489 488 3 420 421 490 3 420 490 489 3 421 422 491 3 421 491 490 3 422 423 492 3 422 492 491 3 423 424 493 3 423 493 492 3 424 425 494 3 424 494 493 3 425 426 495 3 425 495 494 3 426 427 496 3 426 496 495 3 427 428 497 3 427 497 496 3 428 429 498 3 428 498 497 3 429 430 499 3 429 499 498 3 430 431 500 3 430 500 499 3 431 432 500 3 501 500 432 3 432 433 501 3 502 501 433 3 433 434 502 3 503 502 434 3 434 435 503 3 504 503 435 3 435 436 504 3 505 504 436 3 436 437 505 3 506 505 437 3 437 438 506 3 507 506 438 3 438 439 507 3 508 507 439 3 439 440 508 3 509 508 440 3 440 441 509 3 510 509 441 3 441 442 510 3 511 510 442 3 442 443 511 3 512 511 443 3 443 444 512 3 513 512 444 3 444 445 514 3 444 514 513 3 445 446 515 3 445 515 514 3 446 447 516 3 446 516 515 3 447 448 517 3 447 517 516 3 448 449 518 3 448 518 517 3 449 450 519 3 449 519 518 3 450 451 520 3 450 520 519 3 451 452 521 3 451 521 520 3 452 453 522 3 452 522 521 3 453 454 523 3 453 523 522 3 454 455 524 3 454 524 523 3 455 456 525 3 455 525 524 3 456 457 526 3 456 526 525 3 457 458 526 3 527 526 458 3 458 459 527 3 528 527 459 3 459 460 528 3 529 528 460 3 460 461 529 3 530 529 461 3 461 462 530 3 531 530 462 3 462 463 531 3 532 531 463 3 463 464 532 3 533 532 464 3 464 465 533 3 534 533 465 3 465 466 534 3 535 534 466 3 466 467 535 3 536 535 467 3 467 468 536 3 537 536 468 3 468 469 537 3 538 537 469 3 469 470 538 3 539 538 470 3 470 471 539 3 540 539 471 3 471 472 541 3 471 541 540 3 472 473 542 3 472 542 541 3 473 474 543 3 473 543 542 3 474 475 544 3 474 544 543 3 475 476 545 3 475 545 544 3 476 4913 4917 3 476 4917 545 3 477 478 547 3 477 547 546 3 477 546 4916 3 4920 4916 546 3 478 479 548 3 478 548 547 3 479 480 549 3 479 549 548 3 480 481 550 3 480 550 549 3 481 482 551 3 481 551 550 3 482 483 552 3 482 552 551 3 483 484 553 3 483 553 552 3 484 485 553 3 554 553 485 3 485 486 554 3 555 554 486 3 486 487 555 3 556 555 487 3 487 488 556 3 557 556 488 3 488 489 557 3 558 557 489 3 489 490 558 3 559 558 490 3 490 491 559 3 560 559 491 3 491 492 560 3 561 560 492 3 492 493 561 3 562 561 493 3 493 494 562 3 563 562 494 3 494 495 563 3 564 563 495 3 495 496 564 3 565 564 496 3 496 497 565 3 566 565 497 3 497 498 566 3 567 566 498 3 498 499 568 3 498 568 567 3 499 500 569 3 499 569 568 3 500 501 570 3 500 570 569 3 501 502 571 3 501 571 570 3 502 503 572 3 502 572 571 3 503 504 573 3 503 573 572 3 504 505 574 3 504 574 573 3 505 506 575 3 505 575 574 3 506 507 576 3 506 576 575 3 507 508 577 3 507 577 576 3 508 509 578 3 508 578 577 3 509 510 579 3 509 579 578 3 510 511 580 3 510 580 579 3 511 512 581 3 511 581 580 3 512 513 581 3 582 581 513 3 513 514 582 3 583 582 514 3 514 515 583 3 584 583 515 3 515 516 584 3 585 584 516 3 516 517 585 3 586 585 517 3 517 518 586 3 587 586 518 3 518 519 587 3 588 587 519 3 519 520 588 3 589 588 520 3 520 521 589 3 590 589 521 3 521 522 590 3 591 590 522 3 522 523 591 3 592 591 523 3 523 524 592 3 593 592 524 3 524 525 593 3 594 593 525 3 525 526 594 3 595 594 526 3 526 527 596 3 526 596 595 3 527 528 597 3 527 597 596 3 528 529 598 3 528 598 597 3 529 530 599 3 529 599 598 3 530 531 600 3 530 600 599 3 531 532 601 3 531 601 600 3 532 533 602 3 532 602 601 3 533 534 603 3 533 603 602 3 534 535 604 3 534 604 603 3 535 536 605 3 535 605 604 3 536 537 606 3 536 606 605 3 537 538 607 3 537 607 606 3 538 539 608 3 538 608 607 3 539 540 609 3 539 609 608 3 540 541 609 3 610 609 541 3 541 542 610 3 611 610 542 3 542 543 611 3 612 611 543 3 543 544 612 3 613 612 544 3 544 545 613 3 614 613 545 3 545 4917 4921 3 545 4921 614 3 546 547 615 3 616 615 547 3 546 615 4924 3 546 4924 4920 3 547 548 616 3 617 616 548 3 548 549 617 3 618 617 549 3 549 550 618 3 619 618 550 3 550 551 619 3 620 619 551 3 551 552 620 3 621 620 552 3 552 553 621 3 622 621 553 3 553 554 622 3 623 622 554 3 554 555 624 3 554 624 623 3 555 556 625 3 555 625 624 3 556 557 626 3 556 626 625 3 557 558 627 3 557 627 626 3 558 559 628 3 558 628 627 3 559 560 629 3 559 629 628 3 560 561 630 3 560 630 629 3 561 562 631 3 561 631 630 3 562 563 632 3 562 632 631 3 563 564 633 3 563 633 632 3 564 565 634 3 564 634 633 3 565 566 635 3 565 635 634 3 566 567 636 3 566 636 635 3 567 568 637 3 567 637 636 3 568 569 638 3 568 638 637 3 569 570 638 3 639 638 570 3 570 571 639 3 640 639 571 3 571 572 640 3 641 640 572 3 572 573 641 3 642 641 573 3 573 574 642 3 643 642 574 3 574 575 643 3 644 643 575 3 575 576 644 3 645 644 576 3 576 577 645 3 646 645 577 3 577 578 646 3 647 646 578 3 578 579 647 3 648 647 579 3 579 580 648 3 649 648 580 3 580 581 649 3 650 649 581 3 581 582 650 3 651 650 582 3 582 583 651 3 652 651 583 3 583 584 652 3 653 652 584 3 584 585 654 3 584 654 653 3 585 586 655 3 585 655 654 3 586 587 656 3 586 656 655 3 587 588 657 3 587 657 656 3 588 589 658 3 588 658 657 3 589 590 659 3 589 659 658 3 590 591 660 3 590 660 659 3 591 592 661 3 591 661 660 3 592 593 662 3 592 662 661 3 593 594 663 3 593 663 662 3 594 595 664 3 594 664 663 3 595 596 665 3 595 665 664 3 596 597 666 3 596 666 665 3 597 598 667 3 597 667 666 3 598 599 668 3 598 668 667 3 599 600 668 3 669 668 600 3 600 601 669 3 670 669 601 3 601 602 670 3 671 670 602 3 602 603 671 3 672 671 603 3 603 604 672 3 673 672 604 3 604 605 673 3 674 673 605 3 605 606 674 3 675 674 606 3 606 607 675 3 676 675 607 3 607 608 676 3 677 676 608 3 608 609 677 3 678 677 609 3 609 610 678 3 679 678 610 3 610 611 679 3 680 679 611 3 611 612 680 3 681 680 612 3 612 613 681 3 682 681 613 3 613 614 682 3 683 682 614 3 614 4921 4925 3 614 4925 683 3 615 616 685 3 615 685 684 3 615 684 4928 3 615 4928 4924 3 616 617 686 3 616 686 685 3 617 618 687 3 617 687 686 3 618 619 688 3 618 688 687 3 619 620 689 3 619 689 688 3 620 621 690 3 620 690 689 3 621 622 691 3 621 691 690 3 622 623 692 3 622 692 691 3 623 624 693 3 623 693 692 3 624 625 694 3 624 694 693 3 625 626 695 3 625 695 694 3 626 627 696 3 626 696 695 3 627 628 697 3 627 697 696 3 628 629 698 3 628 698 697 3 629 630 698 3 699 698 630 3 630 631 699 3 700 699 631 3 631 632 700 3 701 700 632 3 632 633 701 3 702 701 633 3 633 634 702 3 703 702 634 3 634 635 703 3 704 703 635 3 635 636 704 3 705 704 636 3 636 637 705 3 706 705 637 3 637 638 706 3 707 706 638 3 638 639 707 3 708 707 639 3 639 640 708 3 709 708 640 3 640 641 709 3 710 709 641 3 641 642 710 3 711 710 642 3 642 643 711 3 712 711 643 3 643 644 712 3 713 712 644 3 644 645 713 3 714 713 645 3 645 646 715 3 645 715 714 3 646 647 716 3 646 716 715 3 647 648 717 3 647 717 716 3 648 649 718 3 648 718 717 3 649 650 719 3 649 719 718 3 650 651 720 3 650 720 719 3 651 652 721 3 651 721 720 3 652 653 722 3 652 722 721 3 653 654 723 3 653 723 722 3 654 655 724 3 654 724 723 3 655 656 725 3 655 725 724 3 656 657 726 3 656 726 725 3 657 658 727 3 657 727 726 3 658 659 728 3 658 728 727 3 659 660 729 3 659 729 728 3 660 661 729 3 730 729 661 3 661 662 730 3 731 730 662 3 662 663 731 3 732 731 663 3 663 664 732 3 733 732 664 3 664 665 733 3 734 733 665 3 665 666 734 3 735 734 666 3 666 667 735 3 736 735 667 3 667 668 736 3 737 736 668 3 668 669 737 3 738 737 669 3 669 670 738 3 739 738 670 3 670 671 739 3 740 739 671 3 671 672 740 3 741 740 672 3 672 673 741 3 742 741 673 3 673 674 742 3 743 742 674 3 674 675 743 3 744 743 675 3 675 676 744 3 745 744 676 3 676 677 746 3 676 746 745 3 677 678 747 3 677 747 746 3 678 679 748 3 678 748 747 3 679 680 749 3 679 749 748 3 680 681 750 3 680 750 749 3 681 682 751 3 681 751 750 3 682 683 752 3 682 752 751 3 683 4925 4929 3 683 4929 752 3 684 685 754 3 684 754 753 3 684 753 4932 3 684 4932 4928 3 685 686 755 3 685 755 754 3 686 687 756 3 686 756 755 3 687 688 757 3 687 757 756 3 688 689 758 3 688 758 757 3 689 690 759 3 689 759 758 3 690 691 760 3 690 760 759 3 691 692 761 3 691 761 760 3 692 693 761 3 762 761 693 3 693 694 762 3 763 762 694 3 694 695 763 3 764 763 695 3 695 696 764 3 765 764 696 3 696 697 765 3 766 765 697 3 697 698 766 3 767 766 698 3 698 699 767 3 768 767 699 3 699 700 768 3 769 768 700 3 700 701 769 3 770 769 701 3 701 702 770 3 771 770 702 3 702 703 771 3 772 771 703 3 703 704 772 3 773 772 704 3 704 705 773 3 774 773 705 3 705 706 774 3 775 774 706 3 706 707 775 3 776 775 707 3 707 708 776 3 777 776 708 3 708 709 777 3 778 777 709 3 709 710 779 3 709 779 778 3 710 711 780 3 710 780 779 3 711 712 781 3 711 781 780 3 712 713 782 3 712 782 781 3 713 714 783 3 713 783 782 3 714 715 784 3 714 784 783 3 715 716 785 3 715 785 784 3 716 717 786 3 716 786 785 3 717 718 787 3 717 787 786 3 718 719 788 3 718 788 787 3 719 720 789 3 719 789 788 3 720 721 790 3 720 790 789 3 721 722 791 3 721 791 790 3 722 723 792 3 722 792 791 3 723 724 793 3 723 793 792 3 724 725 794 3 724 794 793 3 725 726 794 3 795 794 726 3 726 727 795 3 796 795 727 3 727 728 796 3 797 796 728 3 728 729 797 3 798 797 729 3 729 730 798 3 799 798 730 3 730 731 799 3 800 799 731 3 731 732 800 3 801 800 732 3 732 733 801 3 802 801 733 3 733 734 802 3 803 802 734 3 734 735 803 3 804 803 735 3 735 736 804 3 805 804 736 3 736 737 805 3 806 805 737 3 737 738 806 3 807 806 738 3 738 739 807 3 808 807 739 3 739 740 808 3 809 808 740 3 740 741 809 3 810 809 741 3 741 742 810 3 811 810 742 3 742 743 812 3 742 812 811 3 743 744 813 3 743 813 812 3 744 745 814 3 744 814 813 3 745 746 815 3 745 815 814 3 746 747 816 3 746 816 815 3 747 748 817 3 747 817 816 3 748 749 818 3 748 818 817 3 749 750 819 3 749 819 818 3 750 751 820 3 750 820 819 3 751 752 821 3 751 821 820 3 752 4929 4933 3 752 4933 821 3 753 754 823 3 753 823 822 3 753 822 4936 3 753 4936 4932 3 754 755 824 3 754 824 823 3 755 756 825 3 755 825 824 3 756 757 826 3 756 826 825 3 757 758 827 3 757 827 826 3 758 759 828 3 758 828 827 3 759 760 828 3 829 828 760 3 760 761 829 3 830 829 761 3 761 762 830 3 831 830 762 3 762 763 831 3 832 831 763 3 763 764 832 3 833 832 764 3 764 765 833 3 834 833 765 3 765 766 834 3 835 834 766 3 766 767 835 3 836 835 767 3 767 768 836 3 837 836 768 3 768 769 837 3 838 837 769 3 769 770 838 3 839 838 770 3 770 771 839 3 840 839 771 3 771 772 840 3 841 840 772 3 772 773 841 3 842 841 773 3 773 774 842 3 843 842 774 3 774 775 843 3 844 843 775 3 775 776 844 3 845 844 776 3 776 777 846 3 776 846 845 3 777 778 847 3 777 847 846 3 778 779 848 3 778 848 847 3 779 780 849 3 779 849 848 3 780 781 850 3 780 850 849 3 781 782 851 3 781 851 850 3 782 783 852 3 782 852 851 3 783 784 853 3 783 853 852 3 784 785 854 3 784 854 853 3 785 786 855 3 785 855 854 3 786 787 856 3 786 856 855 3 787 788 857 3 787 857 856 3 788 789 858 3 788 858 857 3 789 790 859 3 789 859 858 3 790 791 860 3 790 860 859 3 791 792 861 3 791 861 860 3 792 793 862 3 792 862 861 3 793 794 862 3 863 862 794 3 794 795 863 3 864 863 795 3 795 796 864 3 865 864 796 3 796 797 865 3 866 865 797 3 797 798 866 3 867 866 798 3 798 799 867 3 868 867 799 3 799 800 868 3 869 868 800 3 800 801 869 3 870 869 801 3 801 802 870 3 871 870 802 3 802 803 871 3 872 871 803 3 803 804 872 3 873 872 804 3 804 805 873 3 874 873 805 3 805 806 874 3 875 874 806 3 806 807 875 3 876 875 807 3 807 808 876 3 877 876 808 3 808 809 877 3 878 877 809 3 809 810 878 3 879 878 810 3 810 811 880 3 810 880 879 3 811 812 881 3 811 881 880 3 812 813 882 3 812 882 881 3 813 814 883 3 813 883 882 3 814 815 884 3 814 884 883 3 815 816 885 3 815 885 884 3 816 817 886 3 816 886 885 3 817 818 887 3 817 887 886 3 818 819 888 3 818 888 887 3 819 820 889 3 819 889 888 3 820 821 890 3 820 890 889 3 821 4933 4937 3 821 4937 890 3 822 823 892 3 822 892 891 3 822 891 4940 3 822 4940 4936 3 823 824 893 3 823 893 892 3 824 825 894 3 824 894 893 3 825 826 895 3 825 895 894 3 826 827 896 3 826 896 895 3 827 828 897 3 827 897 896 3 828 829 897 3 898 897 829 3 829 830 898 3 899 898 830 3 830 831 899 3 900 899 831 3 831 832 900 3 901 900 832 3 832 833 901 3 902 901 833 3 833 834 902 3 903 902 834 3 834 835 903 3 904 903 835 3 835 836 904 3 905 904 836 3 836 837 905 3 906 905 837 3 837 838 906 3 907 906 838 3 838 839 907 3 908 907 839 3 839 840 908 3 909 908 840 3 840 841 909 3 910 909 841 3 841 842 910 3 911 910 842 3 842 843 911 3 912 911 843 3 843 844 912 3 913 912 844 3 844 845 913 3 914 913 845 3 845 846 914 3 915 914 846 3 846 847 916 3 846 916 915 3 847 848 917 3 847 917 916 3 848 849 918 3 848 918 917 3 849 850 919 3 849 919 918 3 850 851 920 3 850 920 919 3 851 852 921 3 851 921 920 3 852 853 922 3 852 922 921 3 853 854 923 3 853 923 922 3 854 855 924 3 854 924 923 3 855 856 925 3 855 925 924 3 856 857 926 3 856 926 925 3 857 858 927 3 857 927 926 3 858 859 928 3 858 928 927 3 859 860 929 3 859 929 928 3 860 861 930 3 860 930 929 3 861 862 931 3 861 931 930 3 862 863 932 3 862 932 931 3 863 864 933 3 863 933 932 3 864 865 933 3 934 933 865 3 865 866 934 3 935 934 866 3 866 867 935 3 936 935 867 3 867 868 936 3 937 936 868 3 868 869 937 3 938 937 869 3 869 870 938 3 939 938 870 3 870 871 939 3 940 939 871 3 871 872 940 3 941 940 872 3 872 873 941 3 942 941 873 3 873 874 942 3 943 942 874 3 874 875 943 3 944 943 875 3 875 876 944 3 945 944 876 3 876 877 945 3 946 945 877 3 877 878 946 3 947 946 878 3 878 879 947 3 948 947 879 3 879 880 948 3 949 948 880 3 880 881 949 3 950 949 881 3 881 882 950 3 951 950 882 3 882 883 952 3 882 952 951 3 883 884 953 3 883 953 952 3 884 885 954 3 884 954 953 3 885 886 955 3 885 955 954 3 886 887 956 3 886 956 955 3 887 888 957 3 887 957 956 3 888 889 958 3 888 958 957 3 889 890 959 3 889 959 958 3 890 4937 4941 3 890 4941 959 3 891 892 961 3 891 961 960 3 891 960 4944 3 891 4944 4940 3 892 893 962 3 892 962 961 3 893 894 963 3 893 963 962 3 894 895 964 3 894 964 963 3 895 896 965 3 895 965 964 3 896 897 966 3 896 966 965 3 897 898 967 3 897 967 966 3 898 899 968 3 898 968 967 3 899 900 969 3 899 969 968 3 900 901 969 3 970 969 901 3 901 902 970 3 971 970 902 3 902 903 971 3 972 971 903 3 903 904 972 3 973 972 904 3 904 905 973 3 974 973 905 3 905 906 974 3 975 974 906 3 906 907 975 3 976 975 907 3 907 908 976 3 977 976 908 3 908 909 977 3 978 977 909 3 909 910 978 3 979 978 910 3 910 911 979 3 980 979 911 3 911 912 980 3 981 980 912 3 912 913 981 3 982 981 913 3 913 914 982 3 983 982 914 3 914 915 983 3 984 983 915 3 915 916 984 3 985 984 916 3 916 917 985 3 986 985 917 3 917 918 986 3 987 986 918 3 918 919 987 3 988 987 919 3 919 920 989 3 919 989 988 3 920 921 990 3 920 990 989 3 921 922 991 3 921 991 990 3 922 923 992 3 922 992 991 3 923 924 993 3 923 993 992 3 924 925 994 3 924 994 993 3 925 926 995 3 925 995 994 3 926 927 996 3 926 996 995 3 927 928 997 3 927 997 996 3 928 929 998 3 928 998 997 3 929 930 999 3 929 999 998 3 930 931 1000 3 930 1000 999 3 931 932 1001 3 931 1001 1000 3 932 933 1002 3 932 1002 1001 3 933 934 1003 3 933 1003 1002 3 934 935 1004 3 934 1004 1003 3 935 936 1005 3 935 1005 1004 3 936 937 1006 3 936 1006 1005 3 937 938 1007 3 937 1007 1006 3 938 939 1007 3 1008 1007 939 3 939 940 1008 3 1009 1008 940 3 940 941 1009 3 1010 1009 941 3 941 942 1010 3 1011 1010 942 3 942 943 1011 3 1012 1011 943 3 943 944 1012 3 1013 1012 944 3 944 945 1013 3 1014 1013 945 3 945 946 1014 3 1015 1014 946 3 946 947 1015 3 1016 1015 947 3 947 948 1016 3 1017 1016 948 3 948 949 1017 3 1018 1017 949 3 949 950 1018 3 1019 1018 950 3 950 951 1019 3 1020 1019 951 3 951 952 1020 3 1021 1020 952 3 952 953 1021 3 1022 1021 953 3 953 954 1022 3 1023 1022 954 3 954 955 1023 3 1024 1023 955 3 955 956 1024 3 1025 1024 956 3 956 957 1025 3 1026 1025 957 3 957 958 1027 3 957 1027 1026 3 958 959 1028 3 958 1028 1027 3 959 4941 1028 3 4945 1028 4941 3 960 961 1030 3 960 1030 1029 3 960 1029 4948 3 960 4948 4944 3 961 962 1031 3 961 1031 1030 3 962 963 1032 3 962 1032 1031 3 963 964 1033 3 963 1033 1032 3 964 965 1034 3 964 1034 1033 3 965 966 1035 3 965 1035 1034 3 966 967 1036 3 966 1036 1035 3 967 968 1037 3 967 1037 1036 3 968 969 1038 3 968 1038 1037 3 969 970 1039 3 969 1039 1038 3 970 971 1040 3 970 1040 1039 3 971 972 1041 3 971 1041 1040 3 972 973 1042 3 972 1042 1041 3 973 974 1043 3 973 1043 1042 3 974 975 1044 3 974 1044 1043 3 975 976 1045 3 975 1045 1044 3 976 977 1045 3 1046 1045 977 3 977 978 1046 3 1047 1046 978 3 978 979 1047 3 1048 1047 979 3 979 980 1048 3 1049 1048 980 3 980 981 1049 3 1050 1049 981 3 981 982 1050 3 1051 1050 982 3 982 983 1051 3 1052 1051 983 3 983 984 1052 3 1053 1052 984 3 984 985 1053 3 1054 1053 985 3 985 986 1054 3 1055 1054 986 3 986 987 1055 3 1056 1055 987 3 987 988 1056 3 1057 1056 988 3 988 989 1057 3 1058 1057 989 3 989 990 1058 3 1059 1058 990 3 990 991 1059 3 1060 1059 991 3 991 992 1060 3 1061 1060 992 3 992 993 1061 3 1062 1061 993 3 993 994 1062 3 1063 1062 994 3 994 995 1063 3 1064 1063 995 3 995 996 1065 3 995 1065 1064 3 996 997 1066 3 996 1066 1065 3 997 998 1067 3 997 1067 1066 3 998 999 1068 3 998 1068 1067 3 999 1000 1069 3 999 1069 1068 3 1000 1001 1070 3 1000 1070 1069 3 1001 1002 1071 3 1001 1071 1070 3 1002 1003 1072 3 1002 1072 1071 3 1003 1004 1073 3 1003 1073 1072 3 1004 1005 1074 3 1004 1074 1073 3 1005 1006 1075 3 1005 1075 1074 3 1006 1007 1076 3 1006 1076 1075 3 1007 1008 1077 3 1007 1077 1076 3 1008 1009 1078 3 1008 1078 1077 3 1009 1010 1079 3 1009 1079 1078 3 1010 1011 1080 3 1010 1080 1079 3 1011 1012 1081 3 1011 1081 1080 3 1012 1013 1082 3 1012 1082 1081 3 1013 1014 1083 3 1013 1083 1082 3 1014 1015 1084 3 1014 1084 1083 3 1015 1016 1084 3 1085 1084 1016 3 1016 1017 1085 3 1086 1085 1017 3 1017 1018 1086 3 1087 1086 1018 3 1018 1019 1087 3 1088 1087 1019 3 1019 1020 1088 3 1089 1088 1020 3 1020 1021 1089 3 1090 1089 1021 3 1021 1022 1090 3 1091 1090 1022 3 1022 1023 1091 3 1092 1091 1023 3 1023 1024 1092 3 1093 1092 1024 3 1024 1025 1093 3 1094 1093 1025 3 1025 1026 1094 3 1095 1094 1026 3 1026 1027 1095 3 1096 1095 1027 3 1027 1028 1096 3 1097 1096 1028 3 1028 4945 1097 3 4949 1097 4945 3 1029 1030 1098 3 1099 1098 1030 3 1029 1098 4948 3 4952 4948 1098 3 1030 1031 1099 3 1100 1099 1031 3 1031 1032 1100 3 1101 1100 1032 3 1032 1033 1101 3 1102 1101 1033 3 1033 1034 1102 3 1103 1102 1034 3 1034 1035 1104 3 1034 1104 1103 3 1035 1036 1105 3 1035 1105 1104 3 1036 1037 1106 3 1036 1106 1105 3 1037 1038 1107 3 1037 1107 1106 3 1038 1039 1108 3 1038 1108 1107 3 1039 1040 1109 3 1039 1109 1108 3 1040 1041 1110 3 1040 1110 1109 3 1041 1042 1111 3 1041 1111 1110 3 1042 1043 1112 3 1042 1112 1111 3 1043 1044 1113 3 1043 1113 1112 3 1044 1045 1114 3 1044 1114 1113 3 1045 1046 1115 3 1045 1115 1114 3 1046 1047 1116 3 1046 1116 1115 3 1047 1048 1117 3 1047 1117 1116 3 1048 1049 1118 3 1048 1118 1117 3 1049 1050 1119 3 1049 1119 1118 3 1050 1051 1120 3 1050 1120 1119 3 1051 1052 1121 3 1051 1121 1120 3 1052 1053 1122 3 1052 1122 1121 3 1053 1054 1123 3 1053 1123 1122 3 1054 1055 1123 3 1124 1123 1055 3 1055 1056 1124 3 1125 1124 1056 3 1056 1057 1125 3 1126 1125 1057 3 1057 1058 1126 3 1127 1126 1058 3 1058 1059 1127 3 1128 1127 1059 3 1059 1060 1128 3 1129 1128 1060 3 1060 1061 1129 3 1130 1129 1061 3 1061 1062 1130 3 1131 1130 1062 3 1062 1063 1131 3 1132 1131 1063 3 1063 1064 1132 3 1133 1132 1064 3 1064 1065 1133 3 1134 1133 1065 3 1065 1066 1134 3 1135 1134 1066 3 1066 1067 1135 3 1136 1135 1067 3 1067 1068 1136 3 1137 1136 1068 3 1068 1069 1137 3 1138 1137 1069 3 1069 1070 1138 3 1139 1138 1070 3 1070 1071 1139 3 1140 1139 1071 3 1071 1072 1140 3 1141 1140 1072 3 1072 1073 1141 3 1142 1141 1073 3 1073 1074 1142 3 1143 1142 1074 3 1074 1075 1144 3 1074 1144 1143 3 1075 1076 1145 3 1075 1145 1144 3 1076 1077 1146 3 1076 1146 1145 3 1077 1078 1147 3 1077 1147 1146 3 1078 1079 1148 3 1078 1148 1147 3 1079 1080 1149 3 1079 1149 1148 3 1080 1081 1150 3 1080 1150 1149 3 1081 1082 1151 3 1081 1151 1150 3 1082 1083 1152 3 1082 1152 1151 3 1083 1084 1153 3 1083 1153 1152 3 1084 1085 1154 3 1084 1154 1153 3 1085 1086 1155 3 1085 1155 1154 3 1086 1087 1156 3 1086 1156 1155 3 1087 1088 1157 3 1087 1157 1156 3 1088 1089 1158 3 1088 1158 1157 3 1089 1090 1159 3 1089 1159 1158 3 1090 1091 1160 3 1090 1160 1159 3 1091 1092 1161 3 1091 1161 1160 3 1092 1093 1162 3 1092 1162 1161 3 1093 1094 1163 3 1093 1163 1162 3 1094 1095 1164 3 1094 1164 1163 3 1095 1096 1164 3 1165 1164 1096 3 1096 1097 1165 3 1166 1165 1097 3 1097 4949 4953 3 1097 4953 1166 3 1098 1099 1167 3 1168 1167 1099 3 1098 1167 4952 3 4956 4952 1167 3 1099 1100 1168 3 1169 1168 1100 3 1100 1101 1169 3 1170 1169 1101 3 1101 1102 1170 3 1171 1170 1102 3 1102 1103 1171 3 1172 1171 1103 3 1103 1104 1172 3 1173 1172 1104 3 1104 1105 1173 3 1174 1173 1105 3 1105 1106 1174 3 1175 1174 1106 3 1106 1107 1175 3 1176 1175 1107 3 1107 1108 1176 3 1177 1176 1108 3 1108 1109 1177 3 1178 1177 1109 3 1109 1110 1178 3 1179 1178 1110 3 1110 1111 1179 3 1180 1179 1111 3 1111 1112 1180 3 1181 1180 1112 3 1112 1113 1181 3 1182 1181 1113 3 1113 1114 1182 3 1183 1182 1114 3 1114 1115 1183 3 1184 1183 1115 3 1115 1116 1185 3 1115 1185 1184 3 1116 1117 1186 3 1116 1186 1185 3 1117 1118 1187 3 1117 1187 1186 3 1118 1119 1188 3 1118 1188 1187 3 1119 1120 1189 3 1119 1189 1188 3 1120 1121 1190 3 1120 1190 1189 3 1121 1122 1191 3 1121 1191 1190 3 1122 1123 1192 3 1122 1192 1191 3 1123 1124 1193 3 1123 1193 1192 3 1124 1125 1194 3 1124 1194 1193 3 1125 1126 1195 3 1125 1195 1194 3 1126 1127 1196 3 1126 1196 1195 3 1127 1128 1197 3 1127 1197 1196 3 1128 1129 1198 3 1128 1198 1197 3 1129 1130 1199 3 1129 1199 1198 3 1130 1131 1200 3 1130 1200 1199 3 1131 1132 1201 3 1131 1201 1200 3 1132 1133 1202 3 1132 1202 1201 3 1133 1134 1203 3 1133 1203 1202 3 1134 1135 1204 3 1134 1204 1203 3 1135 1136 1205 3 1135 1205 1204 3 1136 1137 1205 3 1206 1205 1137 3 1137 1138 1206 3 1207 1206 1138 3 1138 1139 1207 3 1208 1207 1139 3 1139 1140 1208 3 1209 1208 1140 3 1140 1141 1209 3 1210 1209 1141 3 1141 1142 1210 3 1211 1210 1142 3 1142 1143 1211 3 1212 1211 1143 3 1143 1144 1212 3 1213 1212 1144 3 1144 1145 1213 3 1214 1213 1145 3 1145 1146 1214 3 1215 1214 1146 3 1146 1147 1215 3 1216 1215 1147 3 1147 1148 1216 3 1217 1216 1148 3 1148 1149 1217 3 1218 1217 1149 3 1149 1150 1218 3 1219 1218 1150 3 1150 1151 1219 3 1220 1219 1151 3 1151 1152 1220 3 1221 1220 1152 3 1152 1153 1221 3 1222 1221 1153 3 1153 1154 1222 3 1223 1222 1154 3 1154 1155 1223 3 1224 1223 1155 3 1155 1156 1224 3 1225 1224 1156 3 1156 1157 1226 3 1156 1226 1225 3 1157 1158 1227 3 1157 1227 1226 3 1158 1159 1228 3 1158 1228 1227 3 1159 1160 1229 3 1159 1229 1228 3 1160 1161 1230 3 1160 1230 1229 3 1161 1162 1231 3 1161 1231 1230 3 1162 1163 1232 3 1162 1232 1231 3 1163 1164 1233 3 1163 1233 1232 3 1164 1165 1234 3 1164 1234 1233 3 1165 1166 1235 3 1165 1235 1234 3 1166 4953 4957 3 1166 4957 1235 3 1167 1168 1237 3 1167 1237 1236 3 1167 1236 4960 3 1167 4960 4956 3 1168 1169 1238 3 1168 1238 1237 3 1169 1170 1239 3 1169 1239 1238 3 1170 1171 1240 3 1170 1240 1239 3 1171 1172 1241 3 1171 1241 1240 3 1172 1173 1242 3 1172 1242 1241 3 1173 1174 1243 3 1173 1243 1242 3 1174 1175 1244 3 1174 1244 1243 3 1175 1176 1245 3 1175 1245 1244 3 1176 1177 1246 3 1176 1246 1245 3 1177 1178 1246 3 1247 1246 1178 3 1178 1179 1247 3 1248 1247 1179 3 1179 1180 1248 3 1249 1248 1180 3 1180 1181 1249 3 1250 1249 1181 3 1181 1182 1250 3 1251 1250 1182 3 1182 1183 1251 3 1252 1251 1183 3 1183 1184 1252 3 1253 1252 1184 3 1184 1185 1253 3 1254 1253 1185 3 1185 1186 1254 3 1255 1254 1186 3 1186 1187 1255 3 1256 1255 1187 3 1187 1188 1256 3 1257 1256 1188 3 1188 1189 1257 3 1258 1257 1189 3 1189 1190 1258 3 1259 1258 1190 3 1190 1191 1259 3 1260 1259 1191 3 1191 1192 1260 3 1261 1260 1192 3 1192 1193 1261 3 1262 1261 1193 3 1193 1194 1262 3 1263 1262 1194 3 1194 1195 1263 3 1264 1263 1195 3 1195 1196 1264 3 1265 1264 1196 3 1196 1197 1265 3 1266 1265 1197 3 1197 1198 1266 3 1267 1266 1198 3 1198 1199 1267 3 1268 1267 1199 3 1199 1200 1269 3 1199 1269 1268 3 1200 1201 1270 3 1200 1270 1269 3 1201 1202 1271 3 1201 1271 1270 3 1202 1203 1272 3 1202 1272 1271 3 1203 1204 1273 3 1203 1273 1272 3 1204 1205 1274 3 1204 1274 1273 3 1205 1206 1275 3 1205 1275 1274 3 1206 1207 1276 3 1206 1276 1275 3 1207 1208 1277 3 1207 1277 1276 3 1208 1209 1278 3 1208 1278 1277 3 1209 1210 1279 3 1209 1279 1278 3 1210 1211 1280 3 1210 1280 1279 3 1211 1212 1281 3 1211 1281 1280 3 1212 1213 1282 3 1212 1282 1281 3 1213 1214 1283 3 1213 1283 1282 3 1214 1215 1284 3 1214 1284 1283 3 1215 1216 1285 3 1215 1285 1284 3 1216 1217 1286 3 1216 1286 1285 3 1217 1218 1287 3 1217 1287 1286 3 1218 1219 1288 3 1218 1288 1287 3 1219 1220 1289 3 1219 1289 1288 3 1220 1221 1289 3 1290 1289 1221 3 1221 1222 1290 3 1291 1290 1222 3 1222 1223 1291 3 1292 1291 1223 3 1223 1224 1292 3 1293 1292 1224 3 1224 1225 1293 3 1294 1293 1225 3 1225 1226 1294 3 1295 1294 1226 3 1226 1227 1295 3 1296 1295 1227 3 1227 1228 1296 3 1297 1296 1228 3 1228 1229 1297 3 1298 1297 1229 3 1229 1230 1298 3 1299 1298 1230 3 1230 1231 1299 3 1300 1299 1231 3 1231 1232 1300 3 1301 1300 1232 3 1232 1233 1301 3 1302 1301 1233 3 1233 1234 1302 3 1303 1302 1234 3 1234 1235 1303 3 1304 1303 1235 3 1235 4957 1304 3 4961 1304 4957 3 1236 1237 1305 3 1306 1305 1237 3 1236 1305 4960 3 4964 4960 1305 3 1237 1238 1306 3 1307 1306 1238 3 1238 1239 1307 3 1308 1307 1239 3 1239 1240 1308 3 1309 1308 1240 3 1240 1241 1309 3 1310 1309 1241 3 1241 1242 1310 3 1311 1310 1242 3 1242 1243 1312 3 1242 1312 1311 3 1243 1244 1313 3 1243 1313 1312 3 1244 1245 1314 3 1244 1314 1313 3 1245 1246 1315 3 1245 1315 1314 3 1246 1247 1316 3 1246 1316 1315 3 1247 1248 1317 3 1247 1317 1316 3 1248 1249 1318 3 1248 1318 1317 3 1249 1250 1319 3 1249 1319 1318 3 1250 1251 1320 3 1250 1320 1319 3 1251 1252 1321 3 1251 1321 1320 3 1252 1253 1322 3 1252 1322 1321 3 1253 1254 1323 3 1253 1323 1322 3 1254 1255 1324 3 1254 1324 1323 3 1255 1256 1325 3 1255 1325 1324 3 1256 1257 1326 3 1256 1326 1325 3 1257 1258 1327 3 1257 1327 1326 3 1258 1259 1328 3 1258 1328 1327 3 1259 1260 1329 3 1259 1329 1328 3 1260 1261 1330 3 1260 1330 1329 3 1261 1262 1331 3 1261 1331 1330 3 1262 1263 1332 3 1262 1332 1331 3 1263 1264 1333 3 1263 1333 1332 3 1264 1265 1333 3 1334 1333 1265 3 1265 1266 1334 3 1335 1334 1266 3 1266 1267 1335 3 1336 1335 1267 3 1267 1268 1336 3 1337 1336 1268 3 1268 1269 1337 3 1338 1337 1269 3 1269 1270 1338 3 1339 1338 1270 3 1270 1271 1339 3 1340 1339 1271 3 1271 1272 1340 3 1341 1340 1272 3 1272 1273 1341 3 1342 1341 1273 3 1273 1274 1342 3 1343 1342 1274 3 1274 1275 1343 3 1344 1343 1275 3 1275 1276 1344 3 1345 1344 1276 3 1276 1277 1345 3 1346 1345 1277 3 1277 1278 1346 3 1347 1346 1278 3 1278 1279 1347 3 1348 1347 1279 3 1279 1280 1348 3 1349 1348 1280 3 1280 1281 1349 3 1350 1349 1281 3 1281 1282 1350 3 1351 1350 1282 3 1282 1283 1351 3 1352 1351 1283 3 1283 1284 1352 3 1353 1352 1284 3 1284 1285 1353 3 1354 1353 1285 3 1285 1286 1355 3 1285 1355 1354 3 1286 1287 1356 3 1286 1356 1355 3 1287 1288 1357 3 1287 1357 1356 3 1288 1289 1358 3 1288 1358 1357 3 1289 1290 1359 3 1289 1359 1358 3 1290 1291 1360 3 1290 1360 1359 3 1291 1292 1361 3 1291 1361 1360 3 1292 1293 1362 3 1292 1362 1361 3 1293 1294 1363 3 1293 1363 1362 3 1294 1295 1364 3 1294 1364 1363 3 1295 1296 1365 3 1295 1365 1364 3 1296 1297 1366 3 1296 1366 1365 3 1297 1298 1367 3 1297 1367 1366 3 1298 1299 1368 3 1298 1368 1367 3 1299 1300 1369 3 1299 1369 1368 3 1300 1301 1370 3 1300 1370 1369 3 1301 1302 1371 3 1301 1371 1370 3 1302 1303 1372 3 1302 1372 1371 3 1303 1304 1373 3 1303 1373 1372 3 1304 4961 1373 3 4965 1373 4961 3 1305 1306 1375 3 1305 1375 1374 3 1305 1374 4968 3 1305 4968 4964 3 1306 1307 1376 3 1306 1376 1375 3 1307 1308 1377 3 1307 1377 1376 3 1308 1309 1377 3 1378 1377 1309 3 1309 1310 1378 3 1379 1378 1310 3 1310 1311 1379 3 1380 1379 1311 3 1311 1312 1380 3 1381 1380 1312 3 1312 1313 1381 3 1382 1381 1313 3 1313 1314 1382 3 1383 1382 1314 3 1314 1315 1383 3 1384 1383 1315 3 1315 1316 1384 3 1385 1384 1316 3 1316 1317 1385 3 1386 1385 1317 3 1317 1318 1386 3 1387 1386 1318 3 1318 1319 1387 3 1388 1387 1319 3 1319 1320 1388 3 1389 1388 1320 3 1320 1321 1389 3 1390 1389 1321 3 1321 1322 1390 3 1391 1390 1322 3 1322 1323 1391 3 1392 1391 1323 3 1323 1324 1392 3 1393 1392 1324 3 1324 1325 1393 3 1394 1393 1325 3 1325 1326 1394 3 1395 1394 1326 3 1326 1327 1395 3 1396 1395 1327 3 1327 1328 1396 3 1397 1396 1328 3 1328 1329 1397 3 1398 1397 1329 3 1329 1330 1398 3 1399 1398 1330 3 1330 1331 1400 3 1330 1400 1399 3 1331 1332 1401 3 1331 1401 1400 3 1332 1333 1402 3 1332 1402 1401 3 1333 1334 1403 3 1333 1403 1402 3 1334 1335 1404 3 1334 1404 1403 3 1335 1336 1405 3 1335 1405 1404 3 1336 1337 1406 3 1336 1406 1405 3 1337 1338 1407 3 1337 1407 1406 3 1338 1339 1408 3 1338 1408 1407 3 1339 1340 1409 3 1339 1409 1408 3 1340 1341 1410 3 1340 1410 1409 3 1341 1342 1411 3 1341 1411 1410 3 1342 1343 1412 3 1342 1412 1411 3 1343 1344 1413 3 1343 1413 1412 3 1344 1345 1414 3 1344 1414 1413 3 1345 1346 1415 3 1345 1415 1414 3 1346 1347 1416 3 1346 1416 1415 3 1347 1348 1417 3 1347 1417 1416 3 1348 1349 1418 3 1348 1418 1417 3 1349 1350 1419 3 1349 1419 1418 3 1350 1351 1420 3 1350 1420 1419 3 1351 1352 1421 3 1351 1421 1420 3 1352 1353 1422 3 1352 1422 1421 3 1353 1354 1422 3 1423 1422 1354 3 1354 1355 1423 3 1424 1423 1355 3 1355 1356 1424 3 1425 1424 1356 3 1356 1357 1425 3 1426 1425 1357 3 1357 1358 1426 3 1427 1426 1358 3 1358 1359 1427 3 1428 1427 1359 3 1359 1360 1428 3 1429 1428 1360 3 1360 1361 1429 3 1430 1429 1361 3 1361 1362 1430 3 1431 1430 1362 3 1362 1363 1431 3 1432 1431 1363 3 1363 1364 1432 3 1433 1432 1364 3 1364 1365 1433 3 1434 1433 1365 3 1365 1366 1434 3 1435 1434 1366 3 1366 1367 1435 3 1436 1435 1367 3 1367 1368 1436 3 1437 1436 1368 3 1368 1369 1437 3 1438 1437 1369 3 1369 1370 1438 3 1439 1438 1370 3 1370 1371 1439 3 1440 1439 1371 3 1371 1372 1440 3 1441 1440 1372 3 1372 1373 1441 3 1442 1441 1373 3 1373 4965 4969 3 1373 4969 1442 3 1374 1375 1443 3 1444 1443 1375 3 1374 1443 4968 3 4972 4968 1443 3 1375 1376 1445 3 1375 1445 1444 3 1376 1377 1446 3 1376 1446 1445 3 1377 1378 1447 3 1377 1447 1446 3 1378 1379 1448 3 1378 1448 1447 3 1379 1380 1449 3 1379 1449 1448 3 1380 1381 1450 3 1380 1450 1449 3 1381 1382 1451 3 1381 1451 1450 3 1382 1383 1452 3 1382 1452 1451 3 1383 1384 1453 3 1383 1453 1452 3 1384 1385 1454 3 1384 1454 1453 3 1385 1386 1455 3 1385 1455 1454 3 1386 1387 1456 3 1386 1456 1455 3 1387 1388 1457 3 1387 1457 1456 3 1388 1389 1458 3 1388 1458 1457 3 1389 1390 1459 3 1389 1459 1458 3 1390 1391 1460 3 1390 1460 1459 3 1391 1392 1461 3 1391 1461 1460 3 1392 1393 1462 3 1392 1462 1461 3 1393 1394 1463 3 1393 1463 1462 3 1394 1395 1464 3 1394 1464 1463 3 1395 1396 1465 3 1395 1465 1464 3 1396 1397 1466 3 1396 1466 1465 3 1397 1398 1467 3 1397 1467 1466 3 1398 1399 1467 3 1468 1467 1399 3 1399 1400 1468 3 1469 1468 1400 3 1400 1401 1469 3 1470 1469 1401 3 1401 1402 1470 3 1471 1470 1402 3 1402 1403 1471 3 1472 1471 1403 3 1403 1404 1472 3 1473 1472 1404 3 1404 1405 1473 3 1474 1473 1405 3 1405 1406 1474 3 1475 1474 1406 3 1406 1407 1475 3 1476 1475 1407 3 1407 1408 1476 3 1477 1476 1408 3 1408 1409 1477 3 1478 1477 1409 3 1409 1410 1478 3 1479 1478 1410 3 1410 1411 1479 3 1480 1479 1411 3 1411 1412 1480 3 1481 1480 1412 3 1412 1413 1481 3 1482 1481 1413 3 1413 1414 1482 3 1483 1482 1414 3 1414 1415 1483 3 1484 1483 1415 3 1415 1416 1484 3 1485 1484 1416 3 1416 1417 1485 3 1486 1485 1417 3 1417 1418 1486 3 1487 1486 1418 3 1418 1419 1487 3 1488 1487 1419 3 1419 1420 1488 3 1489 1488 1420 3 1420 1421 1489 3 1490 1489 1421 3 1421 1422 1491 3 1421 1491 1490 3 1422 1423 1492 3 1422 1492 1491 3 1423 1424 1493 3 1423 1493 1492 3 1424 1425 1494 3 1424 1494 1493 3 1425 1426 1495 3 1425 1495 1494 3 1426 1427 1496 3 1426 1496 1495 3 1427 1428 1497 3 1427 1497 1496 3 1428 1429 1498 3 1428 1498 1497 3 1429 1430 1499 3 1429 1499 1498 3 1430 1431 1500 3 1430 1500 1499 3 1431 1432 1501 3 1431 1501 1500 3 1432 1433 1502 3 1432 1502 1501 3 1433 1434 1503 3 1433 1503 1502 3 1434 1435 1504 3 1434 1504 1503 3 1435 1436 1505 3 1435 1505 1504 3 1436 1437 1506 3 1436 1506 1505 3 1437 1438 1507 3 1437 1507 1506 3 1438 1439 1508 3 1438 1508 1507 3 1439 1440 1509 3 1439 1509 1508 3 1440 1441 1510 3 1440 1510 1509 3 1441 1442 1511 3 1441 1511 1510 3 1442 4969 1511 3 4973 1511 4969 3 1443 1444 1513 3 1443 1513 1512 3 1443 1512 4976 3 1443 4976 4972 3 1444 1445 1514 3 1444 1514 1513 3 1445 1446 1514 3 1515 1514 1446 3 1446 1447 1515 3 1516 1515 1447 3 1447 1448 1516 3 1517 1516 1448 3 1448 1449 1517 3 1518 1517 1449 3 1449 1450 1518 3 1519 1518 1450 3 1450 1451 1519 3 1520 1519 1451 3 1451 1452 1520 3 1521 1520 1452 3 1452 1453 1521 3 1522 1521 1453 3 1453 1454 1522 3 1523 1522 1454 3 1454 1455 1523 3 1524 1523 1455 3 1455 1456 1524 3 1525 1524 1456 3 1456 1457 1525 3 1526 1525 1457 3 1457 1458 1526 3 1527 1526 1458 3 1458 1459 1527 3 1528 1527 1459 3 1459 1460 1528 3 1529 1528 1460 3 1460 1461 1529 3 1530 1529 1461 3 1461 1462 1530 3 1531 1530 1462 3 1462 1463 1531 3 1532 1531 1463 3 1463 1464 1532 3 1533 1532 1464 3 1464 1465 1533 3 1534 1533 1465 3 1465 1466 1534 3 1535 1534 1466 3 1466 1467 1535 3 1536 1535 1467 3 1467 1468 1536 3 1537 1536 1468 3 1468 1469 1538 3 1468 1538 1537 3 1469 1470 1539 3 1469 1539 1538 3 1470 1471 1540 3 1470 1540 1539 3 1471 1472 1541 3 1471 1541 1540 3 1472 1473 1542 3 1472 1542 1541 3 1473 1474 1543 3 1473 1543 1542 3 1474 1475 1544 3 1474 1544 1543 3 1475 1476 1545 3 1475 1545 1544 3 1476 1477 1546 3 1476 1546 1545 3 1477 1478 1547 3 1477 1547 1546 3 1478 1479 1548 3 1478 1548 1547 3 1479 1480 1549 3 1479 1549 1548 3 1480 1481 1550 3 1480 1550 1549 3 1481 1482 1551 3 1481 1551 1550 3 1482 1483 1552 3 1482 1552 1551 3 1483 1484 1553 3 1483 1553 1552 3 1484 1485 1554 3 1484 1554 1553 3 1485 1486 1555 3 1485 1555 1554 3 1486 1487 1556 3 1486 1556 1555 3 1487 1488 1557 3 1487 1557 1556 3 1488 1489 1558 3 1488 1558 1557 3 1489 1490 1559 3 1489 1559 1558 3 1490 1491 1560 3 1490 1560 1559 3 1491 1492 1561 3 1491 1561 1560 3 1492 1493 1561 3 1562 1561 1493 3 1493 1494 1562 3 1563 1562 1494 3 1494 1495 1563 3 1564 1563 1495 3 1495 1496 1564 3 1565 1564 1496 3 1496 1497 1565 3 1566 1565 1497 3 1497 1498 1566 3 1567 1566 1498 3 1498 1499 1567 3 1568 1567 1499 3 1499 1500 1568 3 1569 1568 1500 3 1500 1501 1569 3 1570 1569 1501 3 1501 1502 1570 3 1571 1570 1502 3 1502 1503 1571 3 1572 1571 1503 3 1503 1504 1572 3 1573 1572 1504 3 1504 1505 1573 3 1574 1573 1505 3 1505 1506 1574 3 1575 1574 1506 3 1506 1507 1575 3 1576 1575 1507 3 1507 1508 1576 3 1577 1576 1508 3 1508 1509 1577 3 1578 1577 1509 3 1509 1510 1578 3 1579 1578 1510 3 1510 1511 1579 3 1580 1579 1511 3 1511 4973 1580 3 4977 1580 4973 3 1512 1513 1581 3 1582 1581 1513 3 1512 1581 4976 3 4980 4976 1581 3 1513 1514 1582 3 1583 1582 1514 3 1514 1515 1583 3 1584 1583 1515 3 1515 1516 1584 3 1585 1584 1516 3 1516 1517 1586 3 1516 1586 1585 3 1517 1518 1587 3 1517 1587 1586 3 1518 1519 1588 3 1518 1588 1587 3 1519 1520 1589 3 1519 1589 1588 3 1520 1521 1590 3 1520 1590 1589 3 1521 1522 1591 3 1521 1591 1590 3 1522 1523 1592 3 1522 1592 1591 3 1523 1524 1593 3 1523 1593 1592 3 1524 1525 1594 3 1524 1594 1593 3 1525 1526 1595 3 1525 1595 1594 3 1526 1527 1596 3 1526 1596 1595 3 1527 1528 1597 3 1527 1597 1596 3 1528 1529 1598 3 1528 1598 1597 3 1529 1530 1599 3 1529 1599 1598 3 1530 1531 1600 3 1530 1600 1599 3 1531 1532 1601 3 1531 1601 1600 3 1532 1533 1602 3 1532 1602 1601 3 1533 1534 1603 3 1533 1603 1602 3 1534 1535 1604 3 1534 1604 1603 3 1535 1536 1605 3 1535 1605 1604 3 1536 1537 1606 3 1536 1606 1605 3 1537 1538 1607 3 1537 1607 1606 3 1538 1539 1608 3 1538 1608 1607 3 1539 1540 1609 3 1539 1609 1608 3 1540 1541 1609 3 1610 1609 1541 3 1541 1542 1610 3 1611 1610 1542 3 1542 1543 1611 3 1612 1611 1543 3 1543 1544 1612 3 1613 1612 1544 3 1544 1545 1613 3 1614 1613 1545 3 1545 1546 1614 3 1615 1614 1546 3 1546 1547 1615 3 1616 1615 1547 3 1547 1548 1616 3 1617 1616 1548 3 1548 1549 1617 3 1618 1617 1549 3 1549 1550 1618 3 1619 1618 1550 3 1550 1551 1619 3 1620 1619 1551 3 1551 1552 1620 3 1621 1620 1552 3 1552 1553 1621 3 1622 1621 1553 3 1553 1554 1622 3 1623 1622 1554 3 1554 1555 1623 3 1624 1623 1555 3 1555 1556 1624 3 1625 1624 1556 3 1556 1557 1625 3 1626 1625 1557 3 1557 1558 1626 3 1627 1626 1558 3 1558 1559 1627 3 1628 1627 1559 3 1559 1560 1628 3 1629 1628 1560 3 1560 1561 1629 3 1630 1629 1561 3 1561 1562 1630 3 1631 1630 1562 3 1562 1563 1631 3 1632 1631 1563 3 1563 1564 1632 3 1633 1632 1564 3 1564 1565 1634 3 1564 1634 1633 3 1565 1566 1635 3 1565 1635 1634 3 1566 1567 1636 3 1566 1636 1635 3 1567 1568 1637 3 1567 1637 1636 3 1568 1569 1638 3 1568 1638 1637 3 1569 1570 1639 3 1569 1639 1638 3 1570 1571 1640 3 1570 1640 1639 3 1571 1572 1641 3 1571 1641 1640 3 1572 1573 1642 3 1572 1642 1641 3 1573 1574 1643 3 1573 1643 1642 3 1574 1575 1644 3 1574 1644 1643 3 1575 1576 1645 3 1575 1645 1644 3 1576 1577 1646 3 1576 1646 1645 3 1577 1578 1647 3 1577 1647 1646 3 1578 1579 1648 3 1578 1648 1647 3 1579 1580 1649 3 1579 1649 1648 3 1580 4977 4981 3 1580 4981 1649 3 1581 1582 1651 3 1581 1651 1650 3 1581 1650 4984 3 1581 4984 4980 3 1582 1583 1652 3 1582 1652 1651 3 1583 1584 1653 3 1583 1653 1652 3 1584 1585 1654 3 1584 1654 1653 3 1585 1586 1655 3 1585 1655 1654 3 1586 1587 1656 3 1586 1656 1655 3 1587 1588 1657 3 1587 1657 1656 3 1588 1589 1657 3 1658 1657 1589 3 1589 1590 1658 3 1659 1658 1590 3 1590 1591 1659 3 1660 1659 1591 3 1591 1592 1660 3 1661 1660 1592 3 1592 1593 1661 3 1662 1661 1593 3 1593 1594 1662 3 1663 1662 1594 3 1594 1595 1663 3 1664 1663 1595 3 1595 1596 1664 3 1665 1664 1596 3 1596 1597 1665 3 1666 1665 1597 3 1597 1598 1666 3 1667 1666 1598 3 1598 1599 1667 3 1668 1667 1599 3 1599 1600 1668 3 1669 1668 1600 3 1600 1601 1669 3 1670 1669 1601 3 1601 1602 1670 3 1671 1670 1602 3 1602 1603 1671 3 1672 1671 1603 3 1603 1604 1672 3 1673 1672 1604 3 1604 1605 1673 3 1674 1673 1605 3 1605 1606 1674 3 1675 1674 1606 3 1606 1607 1675 3 1676 1675 1607 3 1607 1608 1676 3 1677 1676 1608 3 1608 1609 1677 3 1678 1677 1609 3 1609 1610 1678 3 1679 1678 1610 3 1610 1611 1679 3 1680 1679 1611 3 1611 1612 1680 3 1681 1680 1612 3 1612 1613 1681 3 1682 1681 1613 3 1613 1614 1683 3 1613 1683 1682 3 1614 1615 1684 3 1614 1684 1683 3 1615 1616 1685 3 1615 1685 1684 3 1616 1617 1686 3 1616 1686 1685 3 1617 1618 1687 3 1617 1687 1686 3 1618 1619 1688 3 1618 1688 1687 3 1619 1620 1689 3 1619 1689 1688 3 1620 1621 1690 3 1620 1690 1689 3 1621 1622 1691 3 1621 1691 1690 3 1622 1623 1692 3 1622 1692 1691 3 1623 1624 1693 3 1623 1693 1692 3 1624 1625 1694 3 1624 1694 1693 3 1625 1626 1695 3 1625 1695 1694 3 1626 1627 1696 3 1626 1696 1695 3 1627 1628 1697 3 1627 1697 1696 3 1628 1629 1698 3 1628 1698 1697 3 1629 1630 1699 3 1629 1699 1698 3 1630 1631 1700 3 1630 1700 1699 3 1631 1632 1701 3 1631 1701 1700 3 1632 1633 1702 3 1632 1702 1701 3 1633 1634 1703 3 1633 1703 1702 3 1634 1635 1704 3 1634 1704 1703 3 1635 1636 1705 3 1635 1705 1704 3 1636 1637 1706 3 1636 1706 1705 3 1637 1638 1707 3 1637 1707 1706 3 1638 1639 1707 3 1708 1707 1639 3 1639 1640 1708 3 1709 1708 1640 3 1640 1641 1709 3 1710 1709 1641 3 1641 1642 1710 3 1711 1710 1642 3 1642 1643 1711 3 1712 1711 1643 3 1643 1644 1712 3 1713 1712 1644 3 1644 1645 1713 3 1714 1713 1645 3 1645 1646 1714 3 1715 1714 1646 3 1646 1647 1715 3 1716 1715 1647 3 1647 1648 1716 3 1717 1716 1648 3 1648 1649 1717 3 1718 1717 1649 3 1649 4981 1718 3 4985 1718 4981 3 1650 1651 1719 3 1720 1719 1651 3 1650 1719 4984 3 4988 4984 1719 3 1651 1652 1720 3 1721 1720 1652 3 1652 1653 1721 3 1722 1721 1653 3 1653 1654 1722 3 1723 1722 1654 3 1654 1655 1723 3 1724 1723 1655 3 1655 1656 1724 3 1725 1724 1656 3 1656 1657 1725 3 1726 1725 1657 3 1657 1658 1726 3 1727 1726 1658 3 1658 1659 1727 3 1728 1727 1659 3 1659 1660 1728 3 1729 1728 1660 3 1660 1661 1729 3 1730 1729 1661 3 1661 1662 1730 3 1731 1730 1662 3 1662 1663 1731 3 1732 1731 1663 3 1663 1664 1733 3 1663 1733 1732 3 1664 1665 1734 3 1664 1734 1733 3 1665 1666 1735 3 1665 1735 1734 3 1666 1667 1736 3 1666 1736 1735 3 1667 1668 1737 3 1667 1737 1736 3 1668 1669 1738 3 1668 1738 1737 3 1669 1670 1739 3 1669 1739 1738 3 1670 1671 1740 3 1670 1740 1739 3 1671 1672 1741 3 1671 1741 1740 3 1672 1673 1742 3 1672 1742 1741 3 1673 1674 1743 3 1673 1743 1742 3 1674 1675 1744 3 1674 1744 1743 3 1675 1676 1745 3 1675 1745 1744 3 1676 1677 1746 3 1676 1746 1745 3 1677 1678 1747 3 1677 1747 1746 3 1678 1679 1748 3 1678 1748 1747 3 1679 1680 1749 3 1679 1749 1748 3 1680 1681 1750 3 1680 1750 1749 3 1681 1682 1751 3 1681 1751 1750 3 1682 1683 1752 3 1682 1752 1751 3 1683 1684 1753 3 1683 1753 1752 3 1684 1685 1754 3 1684 1754 1753 3 1685 1686 1755 3 1685 1755 1754 3 1686 1687 1756 3 1686 1756 1755 3 1687 1688 1757 3 1687 1757 1756 3 1688 1689 1757 3 1758 1757 1689 3 1689 1690 1758 3 1759 1758 1690 3 1690 1691 1759 3 1760 1759 1691 3 1691 1692 1760 3 1761 1760 1692 3 1692 1693 1761 3 1762 1761 1693 3 1693 1694 1762 3 1763 1762 1694 3 1694 1695 1763 3 1764 1763 1695 3 1695 1696 1764 3 1765 1764 1696 3 1696 1697 1765 3 1766 1765 1697 3 1697 1698 1766 3 1767 1766 1698 3 1698 1699 1767 3 1768 1767 1699 3 1699 1700 1768 3 1769 1768 1700 3 1700 1701 1769 3 1770 1769 1701 3 1701 1702 1770 3 1771 1770 1702 3 1702 1703 1771 3 1772 1771 1703 3 1703 1704 1772 3 1773 1772 1704 3 1704 1705 1773 3 1774 1773 1705 3 1705 1706 1774 3 1775 1774 1706 3 1706 1707 1775 3 1776 1775 1707 3 1707 1708 1776 3 1777 1776 1708 3 1708 1709 1777 3 1778 1777 1709 3 1709 1710 1778 3 1779 1778 1710 3 1710 1711 1779 3 1780 1779 1711 3 1711 1712 1780 3 1781 1780 1712 3 1712 1713 1781 3 1782 1781 1713 3 1713 1714 1783 3 1713 1783 1782 3 1714 1715 1784 3 1714 1784 1783 3 1715 1716 1785 3 1715 1785 1784 3 1716 1717 1786 3 1716 1786 1785 3 1717 1718 1787 3 1717 1787 1786 3 1718 4985 4989 3 1718 4989 1787 3 1719 1720 1789 3 1719 1789 1788 3 1719 1788 4988 3 4992 4988 1788 3 1720 1721 1790 3 1720 1790 1789 3 1721 1722 1791 3 1721 1791 1790 3 1722 1723 1792 3 1722 1792 1791 3 1723 1724 1793 3 1723 1793 1792 3 1724 1725 1794 3 1724 1794 1793 3 1725 1726 1795 3 1725 1795 1794 3 1726 1727 1796 3 1726 1796 1795 3 1727 1728 1797 3 1727 1797 1796 3 1728 1729 1798 3 1728 1798 1797 3 1729 1730 1799 3 1729 1799 1798 3 1730 1731 1800 3 1730 1800 1799 3 1731 1732 1801 3 1731 1801 1800 3 1732 1733 1802 3 1732 1802 1801 3 1733 1734 1803 3 1733 1803 1802 3 1734 1735 1804 3 1734 1804 1803 3 1735 1736 1805 3 1735 1805 1804 3 1736 1737 1806 3 1736 1806 1805 3 1737 1738 1807 3 1737 1807 1806 3 1738 1739 1808 3 1738 1808 1807 3 1739 1740 1808 3 1809 1808 1740 3 1740 1741 1809 3 1810 1809 1741 3 1741 1742 1810 3 1811 1810 1742 3 1742 1743 1811 3 1812 1811 1743 3 1743 1744 1812 3 1813 1812 1744 3 1744 1745 1813 3 1814 1813 1745 3 1745 1746 1814 3 1815 1814 1746 3 1746 1747 1815 3 1816 1815 1747 3 1747 1748 1816 3 1817 1816 1748 3 1748 1749 1817 3 1818 1817 1749 3 1749 1750 1818 3 1819 1818 1750 3 1750 1751 1819 3 1820 1819 1751 3 1751 1752 1820 3 1821 1820 1752 3 1752 1753 1821 3 1822 1821 1753 3 1753 1754 1822 3 1823 1822 1754 3 1754 1755 1823 3 1824 1823 1755 3 1755 1756 1824 3 1825 1824 1756 3 1756 1757 1825 3 1826 1825 1757 3 1757 1758 1826 3 1827 1826 1758 3 1758 1759 1827 3 1828 1827 1759 3 1759 1760 1828 3 1829 1828 1760 3 1760 1761 1829 3 1830 1829 1761 3 1761 1762 1830 3 1831 1830 1762 3 1762 1763 1831 3 1832 1831 1763 3 1763 1764 1832 3 1833 1832 1764 3 1764 1765 1833 3 1834 1833 1765 3 1765 1766 1835 3 1765 1835 1834 3 1766 1767 1836 3 1766 1836 1835 3 1767 1768 1837 3 1767 1837 1836 3 1768 1769 1838 3 1768 1838 1837 3 1769 1770 1839 3 1769 1839 1838 3 1770 1771 1840 3 1770 1840 1839 3 1771 1772 1841 3 1771 1841 1840 3 1772 1773 1842 3 1772 1842 1841 3 1773 1774 1843 3 1773 1843 1842 3 1774 1775 1844 3 1774 1844 1843 3 1775 1776 1845 3 1775 1845 1844 3 1776 1777 1846 3 1776 1846 1845 3 1777 1778 1847 3 1777 1847 1846 3 1778 1779 1848 3 1778 1848 1847 3 1779 1780 1849 3 1779 1849 1848 3 1780 1781 1850 3 1780 1850 1849 3 1781 1782 1851 3 1781 1851 1850 3 1782 1783 1852 3 1782 1852 1851 3 1783 1784 1853 3 1783 1853 1852 3 1784 1785 1854 3 1784 1854 1853 3 1785 1786 1855 3 1785 1855 1854 3 1786 1787 1856 3 1786 1856 1855 3 1787 4989 1856 3 4993 1856 4989 3 1788 1789 1858 3 1788 1858 1857 3 1788 1857 4996 3 1788 4996 4992 3 1789 1790 1859 3 1789 1859 1858 3 1790 1791 1860 3 1790 1860 1859 3 1791 1792 1860 3 1861 1860 1792 3 1792 1793 1861 3 1862 1861 1793 3 1793 1794 1862 3 1863 1862 1794 3 1794 1795 1863 3 1864 1863 1795 3 1795 1796 1864 3 1865 1864 1796 3 1796 1797 1865 3 1866 1865 1797 3 1797 1798 1866 3 1867 1866 1798 3 1798 1799 1867 3 1868 1867 1799 3 1799 1800 1868 3 1869 1868 1800 3 1800 1801 1869 3 1870 1869 1801 3 1801 1802 1870 3 1871 1870 1802 3 1802 1803 1871 3 1872 1871 1803 3 1803 1804 1872 3 1873 1872 1804 3 1804 1805 1873 3 1874 1873 1805 3 1805 1806 1874 3 1875 1874 1806 3 1806 1807 1875 3 1876 1875 1807 3 1807 1808 1876 3 1877 1876 1808 3 1808 1809 1877 3 1878 1877 1809 3 1809 1810 1878 3 1879 1878 1810 3 1810 1811 1879 3 1880 1879 1811 3 1811 1812 1880 3 1881 1880 1812 3 1812 1813 1881 3 1882 1881 1813 3 1813 1814 1882 3 1883 1882 1814 3 1814 1815 1883 3 1884 1883 1815 3 1815 1816 1884 3 1885 1884 1816 3 1816 1817 1885 3 1886 1885 1817 3 1817 1818 1887 3 1817 1887 1886 3 1818 1819 1888 3 1818 1888 1887 3 1819 1820 1889 3 1819 1889 1888 3 1820 1821 1890 3 1820 1890 1889 3 1821 1822 1891 3 1821 1891 1890 3 1822 1823 1892 3 1822 1892 1891 3 1823 1824 1893 3 1823 1893 1892 3 1824 1825 1894 3 1824 1894 1893 3 1825 1826 1895 3 1825 1895 1894 3 1826 1827 1896 3 1826 1896 1895 3 1827 1828 1897 3 1827 1897 1896 3 1828 1829 1898 3 1828 1898 1897 3 1829 1830 1899 3 1829 1899 1898 3 1830 1831 1900 3 1830 1900 1899 3 1831 1832 1901 3 1831 1901 1900 3 1832 1833 1902 3 1832 1902 1901 3 1833 1834 1903 3 1833 1903 1902 3 1834 1835 1904 3 1834 1904 1903 3 1835 1836 1905 3 1835 1905 1904 3 1836 1837 1906 3 1836 1906 1905 3 1837 1838 1907 3 1837 1907 1906 3 1838 1839 1908 3 1838 1908 1907 3 1839 1840 1909 3 1839 1909 1908 3 1840 1841 1910 3 1840 1910 1909 3 1841 1842 1911 3 1841 1911 1910 3 1842 1843 1912 3 1842 1912 1911 3 1843 1844 1912 3 1913 1912 1844 3 1844 1845 1913 3 1914 1913 1845 3 1845 1846 1914 3 1915 1914 1846 3 1846 1847 1915 3 1916 1915 1847 3 1847 1848 1916 3 1917 1916 1848 3 1848 1849 1917 3 1918 1917 1849 3 1849 1850 1918 3 1919 1918 1850 3 1850 1851 1919 3 1920 1919 1851 3 1851 1852 1920 3 1921 1920 1852 3 1852 1853 1921 3 1922 1921 1853 3 1853 1854 1922 3 1923 1922 1854 3 1854 1855 1923 3 1924 1923 1855 3 1855 1856 1924 3 1925 1924 1856 3 1856 4993 1925 3 4997 1925 4993 3 1857 1858 1926 3 1927 1926 1858 3 1857 1926 4996 3 5000 4996 1926 3 1858 1859 1927 3 1928 1927 1859 3 1859 1860 1928 3 1929 1928 1860 3 1860 1861 1929 3 1930 1929 1861 3 1861 1862 1930 3 1931 1930 1862 3 1862 1863 1931 3 1932 1931 1863 3 1863 1864 1932 3 1933 1932 1864 3 1864 1865 1933 3 1934 1933 1865 3 1865 1866 1934 3 1935 1934 1866 3 1866 1867 1935 3 1936 1935 1867 3 1867 1868 1936 3 1937 1936 1868 3 1868 1869 1937 3 1938 1937 1869 3 1869 1870 1938 3 1939 1938 1870 3 1870 1871 1940 3 1870 1940 1939 3 1871 1872 1941 3 1871 1941 1940 3 1872 1873 1942 3 1872 1942 1941 3 1873 1874 1943 3 1873 1943 1942 3 1874 1875 1944 3 1874 1944 1943 3 1875 1876 1945 3 1875 1945 1944 3 1876 1877 1946 3 1876 1946 1945 3 1877 1878 1947 3 1877 1947 1946 3 1878 1879 1948 3 1878 1948 1947 3 1879 1880 1949 3 1879 1949 1948 3 1880 1881 1950 3 1880 1950 1949 3 1881 1882 1951 3 1881 1951 1950 3 1882 1883 1952 3 1882 1952 1951 3 1883 1884 1953 3 1883 1953 1952 3 1884 1885 1954 3 1884 1954 1953 3 1885 1886 1955 3 1885 1955 1954 3 1886 1887 1956 3 1886 1956 1955 3 1887 1888 1957 3 1887 1957 1956 3 1888 1889 1958 3 1888 1958 1957 3 1889 1890 1959 3 1889 1959 1958 3 1890 1891 1960 3 1890 1960 1959 3 1891 1892 1961 3 1891 1961 1960 3 1892 1893 1962 3 1892 1962 1961 3 1893 1894 1963 3 1893 1963 1962 3 1894 1895 1964 3 1894 1964 1963 3 1895 1896 1965 3 1895 1965 1964 3 1896 1897 1965 3 1966 1965 1897 3 1897 1898 1966 3 1967 1966 1898 3 1898 1899 1967 3 1968 1967 1899 3 1899 1900 1968 3 1969 1968 1900 3 1900 1901 1969 3 1970 1969 1901 3 1901 1902 1970 3 1971 1970 1902 3 1902 1903 1971 3 1972 1971 1903 3 1903 1904 1972 3 1973 1972 1904 3 1904 1905 1973 3 1974 1973 1905 3 1905 1906 1974 3 1975 1974 1906 3 1906 1907 1975 3 1976 1975 1907 3 1907 1908 1976 3 1977 1976 1908 3 1908 1909 1977 3 1978 1977 1909 3 1909 1910 1978 3 1979 1978 1910 3 1910 1911 1979 3 1980 1979 1911 3 1911 1912 1980 3 1981 1980 1912 3 1912 1913 1981 3 1982 1981 1913 3 1913 1914 1982 3 1983 1982 1914 3 1914 1915 1983 3 1984 1983 1915 3 1915 1916 1984 3 1985 1984 1916 3 1916 1917 1985 3 1986 1985 1917 3 1917 1918 1986 3 1987 1986 1918 3 1918 1919 1987 3 1988 1987 1919 3 1919 1920 1988 3 1989 1988 1920 3 1920 1921 1989 3 1990 1989 1921 3 1921 1922 1990 3 1991 1990 1922 3 1922 1923 1991 3 1992 1991 1923 3 1923 1924 1993 3 1923 1993 1992 3 1924 1925 1994 3 1924 1994 1993 3 1925 4997 5001 3 1925 5001 1994 3 1926 1927 1996 3 1926 1996 1995 3 1926 1995 5000 3 5004 5000 1995 3 1927 1928 1997 3 1927 1997 1996 3 1928 1929 1998 3 1928 1998 1997 3 1929 1930 1999 3 1929 1999 1998 3 1930 1931 2000 3 1930 2000 1999 3 1931 1932 2001 3 1931 2001 2000 3 1932 1933 2002 3 1932 2002 2001 3 1933 1934 2003 3 1933 2003 2002 3 1934 1935 2004 3 1934 2004 2003 3 1935 1936 2005 3 1935 2005 2004 3 1936 1937 2006 3 1936 2006 2005 3 1937 1938 2007 3 1937 2007 2006 3 1938 1939 2008 3 1938 2008 2007 3 1939 1940 2009 3 1939 2009 2008 3 1940 1941 2010 3 1940 2010 2009 3 1941 1942 2011 3 1941 2011 2010 3 1942 1943 2012 3 1942 2012 2011 3 1943 1944 2013 3 1943 2013 2012 3 1944 1945 2014 3 1944 2014 2013 3 1945 1946 2015 3 1945 2015 2014 3 1946 1947 2016 3 1946 2016 2015 3 1947 1948 2017 3 1947 2017 2016 3 1948 1949 2018 3 1948 2018 2017 3 1949 1950 2019 3 1949 2019 2018 3 1950 1951 2019 3 2020 2019 1951 3 1951 1952 2020 3 2021 2020 1952 3 1952 1953 2021 3 2022 2021 1953 3 1953 1954 2022 3 2023 2022 1954 3 1954 1955 2023 3 2024 2023 1955 3 1955 1956 2024 3 2025 2024 1956 3 1956 1957 2025 3 2026 2025 1957 3 1957 1958 2026 3 2027 2026 1958 3 1958 1959 2027 3 2028 2027 1959 3 1959 1960 2028 3 2029 2028 1960 3 1960 1961 2029 3 2030 2029 1961 3 1961 1962 2030 3 2031 2030 1962 3 1962 1963 2031 3 2032 2031 1963 3 1963 1964 2032 3 2033 2032 1964 3 1964 1965 2033 3 2034 2033 1965 3 1965 1966 2034 3 2035 2034 1966 3 1966 1967 2035 3 2036 2035 1967 3 1967 1968 2036 3 2037 2036 1968 3 1968 1969 2037 3 2038 2037 1969 3 1969 1970 2038 3 2039 2038 1970 3 1970 1971 2039 3 2040 2039 1971 3 1971 1972 2040 3 2041 2040 1972 3 1972 1973 2041 3 2042 2041 1973 3 1973 1974 2042 3 2043 2042 1974 3 1974 1975 2043 3 2044 2043 1975 3 1975 1976 2044 3 2045 2044 1976 3 1976 1977 2045 3 2046 2045 1977 3 1977 1978 2046 3 2047 2046 1978 3 1978 1979 2048 3 1978 2048 2047 3 1979 1980 2049 3 1979 2049 2048 3 1980 1981 2050 3 1980 2050 2049 3 1981 1982 2051 3 1981 2051 2050 3 1982 1983 2052 3 1982 2052 2051 3 1983 1984 2053 3 1983 2053 2052 3 1984 1985 2054 3 1984 2054 2053 3 1985 1986 2055 3 1985 2055 2054 3 1986 1987 2056 3 1986 2056 2055 3 1987 1988 2057 3 1987 2057 2056 3 1988 1989 2058 3 1988 2058 2057 3 1989 1990 2059 3 1989 2059 2058 3 1990 1991 2060 3 1990 2060 2059 3 1991 1992 2061 3 1991 2061 2060 3 1992 1993 2062 3 1992 2062 2061 3 1993 1994 2063 3 1993 2063 2062 3 1994 5001 2063 3 5005 2063 5001 3 1995 1996 2065 3 1995 2065 2064 3 1995 2064 5008 3 1995 5008 5004 3 1996 1997 2066 3 1996 2066 2065 3 1997 1998 2067 3 1997 2067 2066 3 1998 1999 2068 3 1998 2068 2067 3 1999 2000 2069 3 1999 2069 2068 3 2000 2001 2070 3 2000 2070 2069 3 2001 2002 2071 3 2001 2071 2070 3 2002 2003 2072 3 2002 2072 2071 3 2003 2004 2073 3 2003 2073 2072 3 2004 2005 2074 3 2004 2074 2073 3 2005 2006 2074 3 2075 2074 2006 3 2006 2007 2075 3 2076 2075 2007 3 2007 2008 2076 3 2077 2076 2008 3 2008 2009 2077 3 2078 2077 2009 3 2009 2010 2078 3 2079 2078 2010 3 2010 2011 2079 3 2080 2079 2011 3 2011 2012 2080 3 2081 2080 2012 3 2012 2013 2081 3 2082 2081 2013 3 2013 2014 2082 3 2083 2082 2014 3 2014 2015 2083 3 2084 2083 2015 3 2015 2016 2084 3 2085 2084 2016 3 2016 2017 2085 3 2086 2085 2017 3 2017 2018 2086 3 2087 2086 2018 3 2018 2019 2087 3 2088 2087 2019 3 2019 2020 2088 3 2089 2088 2020 3 2020 2021 2089 3 2090 2089 2021 3 2021 2022 2090 3 2091 2090 2022 3 2022 2023 2091 3 2092 2091 2023 3 2023 2024 2092 3 2093 2092 2024 3 2024 2025 2093 3 2094 2093 2025 3 2025 2026 2094 3 2095 2094 2026 3 2026 2027 2095 3 2096 2095 2027 3 2027 2028 2096 3 2097 2096 2028 3 2028 2029 2097 3 2098 2097 2029 3 2029 2030 2098 3 2099 2098 2030 3 2030 2031 2099 3 2100 2099 2031 3 2031 2032 2100 3 2101 2100 2032 3 2032 2033 2101 3 2102 2101 2033 3 2033 2034 2103 3 2033 2103 2102 3 2034 2035 2104 3 2034 2104 2103 3 2035 2036 2105 3 2035 2105 2104 3 2036 2037 2106 3 2036 2106 2105 3 2037 2038 2107 3 2037 2107 2106 3 2038 2039 2108 3 2038 2108 2107 3 2039 2040 2109 3 2039 2109 2108 3 2040 2041 2110 3 2040 2110 2109 3 2041 2042 2111 3 2041 2111 2110 3 2042 2043 2112 3 2042 2112 2111 3 2043 2044 2113 3 2043 2113 2112 3 2044 2045 2114 3 2044 2114 2113 3 2045 2046 2115 3 2045 2115 2114 3 2046 2047 2116 3 2046 2116 2115 3 2047 2048 2117 3 2047 2117 2116 3 2048 2049 2118 3 2048 2118 2117 3 2049 2050 2119 3 2049 2119 2118 3 2050 2051 2120 3 2050 2120 2119 3 2051 2052 2121 3 2051 2121 2120 3 2052 2053 2122 3 2052 2122 2121 3 2053 2054 2123 3 2053 2123 2122 3 2054 2055 2124 3 2054 2124 2123 3 2055 2056 2125 3 2055 2125 2124 3 2056 2057 2126 3 2056 2126 2125 3 2057 2058 2127 3 2057 2127 2126 3 2058 2059 2128 3 2058 2128 2127 3 2059 2060 2129 3 2059 2129 2128 3 2060 2061 2130 3 2060 2130 2129 3 2061 2062 2130 3 2131 2130 2062 3 2062 2063 2131 3 2132 2131 2063 3 2063 5005 5009 3 2063 5009 2132 3 2064 2065 2133 3 2134 2133 2065 3 2064 2133 5012 3 2064 5012 5008 3 2065 2066 2134 3 2135 2134 2066 3 2066 2067 2135 3 2136 2135 2067 3 2067 2068 2136 3 2137 2136 2068 3 2068 2069 2137 3 2138 2137 2069 3 2069 2070 2138 3 2139 2138 2070 3 2070 2071 2139 3 2140 2139 2071 3 2071 2072 2140 3 2141 2140 2072 3 2072 2073 2141 3 2142 2141 2073 3 2073 2074 2142 3 2143 2142 2074 3 2074 2075 2143 3 2144 2143 2075 3 2075 2076 2144 3 2145 2144 2076 3 2076 2077 2145 3 2146 2145 2077 3 2077 2078 2146 3 2147 2146 2078 3 2078 2079 2147 3 2148 2147 2079 3 2079 2080 2148 3 2149 2148 2080 3 2080 2081 2149 3 2150 2149 2081 3 2081 2082 2150 3 2151 2150 2082 3 2082 2083 2151 3 2152 2151 2083 3 2083 2084 2152 3 2153 2152 2084 3 2084 2085 2153 3 2154 2153 2085 3 2085 2086 2154 3 2155 2154 2086 3 2086 2087 2155 3 2156 2155 2087 3 2087 2088 2156 3 2157 2156 2088 3 2088 2089 2157 3 2158 2157 2089 3 2089 2090 2159 3 2089 2159 2158 3 2090 2091 2160 3 2090 2160 2159 3 2091 2092 2161 3 2091 2161 2160 3 2092 2093 2162 3 2092 2162 2161 3 2093 2094 2163 3 2093 2163 2162 3 2094 2095 2164 3 2094 2164 2163 3 2095 2096 2165 3 2095 2165 2164 3 2096 2097 2166 3 2096 2166 2165 3 2097 2098 2167 3 2097 2167 2166 3 2098 2099 2168 3 2098 2168 2167 3 2099 2100 2169 3 2099 2169 2168 3 2100 2101 2170 3 2100 2170 2169 3 2101 2102 2171 3 2101 2171 2170 3 2102 2103 2172 3 2102 2172 2171 3 2103 2104 2173 3 2103 2173 2172 3 2104 2105 2174 3 2104 2174 2173 3 2105 2106 2175 3 2105 2175 2174 3 2106 2107 2176 3 2106 2176 2175 3 2107 2108 2177 3 2107 2177 2176 3 2108 2109 2178 3 2108 2178 2177 3 2109 2110 2179 3 2109 2179 2178 3 2110 2111 2180 3 2110 2180 2179 3 2111 2112 2181 3 2111 2181 2180 3 2112 2113 2182 3 2112 2182 2181 3 2113 2114 2183 3 2113 2183 2182 3 2114 2115 2184 3 2114 2184 2183 3 2115 2116 2185 3 2115 2185 2184 3 2116 2117 2186 3 2116 2186 2185 3 2117 2118 2186 3 2187 2186 2118 3 2118 2119 2187 3 2188 2187 2119 3 2119 2120 2188 3 2189 2188 2120 3 2120 2121 2189 3 2190 2189 2121 3 2121 2122 2190 3 2191 2190 2122 3 2122 2123 2191 3 2192 2191 2123 3 2123 2124 2192 3 2193 2192 2124 3 2124 2125 2193 3 2194 2193 2125 3 2125 2126 2194 3 2195 2194 2126 3 2126 2127 2195 3 2196 2195 2127 3 2127 2128 2196 3 2197 2196 2128 3 2128 2129 2197 3 2198 2197 2129 3 2129 2130 2198 3 2199 2198 2130 3 2130 2131 2199 3 2200 2199 2131 3 2131 2132 2200 3 2201 2200 2132 3 2132 5009 2201 3 5013 2201 5009 3 2133 2134 2202 3 2203 2202 2134 3 2133 2202 5016 3 2133 5016 5012 3 2134 2135 2203 3 2204 2203 2135 3 2135 2136 2204 3 2205 2204 2136 3 2136 2137 2205 3 2206 2205 2137 3 2137 2138 2206 3 2207 2206 2138 3 2138 2139 2207 3 2208 2207 2139 3 2139 2140 2208 3 2209 2208 2140 3 2140 2141 2209 3 2210 2209 2141 3 2141 2142 2210 3 2211 2210 2142 3 2142 2143 2211 3 2212 2211 2143 3 2143 2144 2212 3 2213 2212 2144 3 2144 2145 2213 3 2214 2213 2145 3 2145 2146 2215 3 2145 2215 2214 3 2146 2147 2216 3 2146 2216 2215 3 2147 2148 2217 3 2147 2217 2216 3 2148 2149 2218 3 2148 2218 2217 3 2149 2150 2219 3 2149 2219 2218 3 2150 2151 2220 3 2150 2220 2219 3 2151 2152 2221 3 2151 2221 2220 3 2152 2153 2222 3 2152 2222 2221 3 2153 2154 2223 3 2153 2223 2222 3 2154 2155 2224 3 2154 2224 2223 3 2155 2156 2225 3 2155 2225 2224 3 2156 2157 2226 3 2156 2226 2225 3 2157 2158 2227 3 2157 2227 2226 3 2158 2159 2228 3 2158 2228 2227 3 2159 2160 2229 3 2159 2229 2228 3 2160 2161 2230 3 2160 2230 2229 3 2161 2162 2231 3 2161 2231 2230 3 2162 2163 2232 3 2162 2232 2231 3 2163 2164 2233 3 2163 2233 2232 3 2164 2165 2234 3 2164 2234 2233 3 2165 2166 2235 3 2165 2235 2234 3 2166 2167 2236 3 2166 2236 2235 3 2167 2168 2237 3 2167 2237 2236 3 2168 2169 2238 3 2168 2238 2237 3 2169 2170 2239 3 2169 2239 2238 3 2170 2171 2240 3 2170 2240 2239 3 2171 2172 2241 3 2171 2241 2240 3 2172 2173 2242 3 2172 2242 2241 3 2173 2174 2243 3 2173 2243 2242 3 2174 2175 2243 3 2244 2243 2175 3 2175 2176 2244 3 2245 2244 2176 3 2176 2177 2245 3 2246 2245 2177 3 2177 2178 2246 3 2247 2246 2178 3 2178 2179 2247 3 2248 2247 2179 3 2179 2180 2248 3 2249 2248 2180 3 2180 2181 2249 3 2250 2249 2181 3 2181 2182 2250 3 2251 2250 2182 3 2182 2183 2251 3 2252 2251 2183 3 2183 2184 2252 3 2253 2252 2184 3 2184 2185 2253 3 2254 2253 2185 3 2185 2186 2254 3 2255 2254 2186 3 2186 2187 2255 3 2256 2255 2187 3 2187 2188 2256 3 2257 2256 2188 3 2188 2189 2257 3 2258 2257 2189 3 2189 2190 2258 3 2259 2258 2190 3 2190 2191 2259 3 2260 2259 2191 3 2191 2192 2260 3 2261 2260 2192 3 2192 2193 2261 3 2262 2261 2193 3 2193 2194 2262 3 2263 2262 2194 3 2194 2195 2263 3 2264 2263 2195 3 2195 2196 2264 3 2265 2264 2196 3 2196 2197 2265 3 2266 2265 2197 3 2197 2198 2266 3 2267 2266 2198 3 2198 2199 2267 3 2268 2267 2199 3 2199 2200 2268 3 2269 2268 2200 3 2200 2201 2269 3 2270 2269 2201 3 2201 5013 5017 3 2201 5017 2270 3 2202 2203 2271 3 2272 2271 2203 3 2202 2271 5016 3 5020 5016 2271 3 2203 2204 2273 3 2203 2273 2272 3 2204 2205 2274 3 2204 2274 2273 3 2205 2206 2275 3 2205 2275 2274 3 2206 2207 2276 3 2206 2276 2275 3 2207 2208 2277 3 2207 2277 2276 3 2208 2209 2278 3 2208 2278 2277 3 2209 2210 2279 3 2209 2279 2278 3 2210 2211 2280 3 2210 2280 2279 3 2211 2212 2281 3 2211 2281 2280 3 2212 2213 2282 3 2212 2282 2281 3 2213 2214 2283 3 2213 2283 2282 3 2214 2215 2284 3 2214 2284 2283 3 2215 2216 2285 3 2215 2285 2284 3 2216 2217 2286 3 2216 2286 2285 3 2217 2218 2287 3 2217 2287 2286 3 2218 2219 2288 3 2218 2288 2287 3 2219 2220 2289 3 2219 2289 2288 3 2220 2221 2290 3 2220 2290 2289 3 2221 2222 2291 3 2221 2291 2290 3 2222 2223 2292 3 2222 2292 2291 3 2223 2224 2293 3 2223 2293 2292 3 2224 2225 2294 3 2224 2294 2293 3 2225 2226 2295 3 2225 2295 2294 3 2226 2227 2296 3 2226 2296 2295 3 2227 2228 2297 3 2227 2297 2296 3 2228 2229 2298 3 2228 2298 2297 3 2229 2230 2299 3 2229 2299 2298 3 2230 2231 2300 3 2230 2300 2299 3 2231 2232 2301 3 2231 2301 2300 3 2232 2233 2301 3 2302 2301 2233 3 2233 2234 2302 3 2303 2302 2234 3 2234 2235 2303 3 2304 2303 2235 3 2235 2236 2304 3 2305 2304 2236 3 2236 2237 2305 3 2306 2305 2237 3 2237 2238 2306 3 2307 2306 2238 3 2238 2239 2307 3 2308 2307 2239 3 2239 2240 2308 3 2309 2308 2240 3 2240 2241 2309 3 2310 2309 2241 3 2241 2242 2310 3 2311 2310 2242 3 2242 2243 2311 3 2312 2311 2243 3 2243 2244 2312 3 2313 2312 2244 3 2244 2245 2313 3 2314 2313 2245 3 2245 2246 2314 3 2315 2314 2246 3 2246 2247 2315 3 2316 2315 2247 3 2247 2248 2316 3 2317 2316 2248 3 2248 2249 2317 3 2318 2317 2249 3 2249 2250 2318 3 2319 2318 2250 3 2250 2251 2319 3 2320 2319 2251 3 2251 2252 2320 3 2321 2320 2252 3 2252 2253 2321 3 2322 2321 2253 3 2253 2254 2322 3 2323 2322 2254 3 2254 2255 2323 3 2324 2323 2255 3 2255 2256 2324 3 2325 2324 2256 3 2256 2257 2325 3 2326 2325 2257 3 2257 2258 2326 3 2327 2326 2258 3 2258 2259 2327 3 2328 2327 2259 3 2259 2260 2328 3 2329 2328 2260 3 2260 2261 2329 3 2330 2329 2261 3 2261 2262 2331 3 2261 2331 2330 3 2262 2263 2332 3 2262 2332 2331 3 2263 2264 2333 3 2263 2333 2332 3 2264 2265 2334 3 2264 2334 2333 3 2265 2266 2335 3 2265 2335 2334 3 2266 2267 2336 3 2266 2336 2335 3 2267 2268 2337 3 2267 2337 2336 3 2268 2269 2338 3 2268 2338 2337 3 2269 2270 2339 3 2269 2339 2338 3 2270 5017 2339 3 5021 2339 5017 3 2271 2272 2341 3 2271 2341 2340 3 2271 2340 5020 3 5024 5020 2340 3 2272 2273 2342 3 2272 2342 2341 3 2273 2274 2343 3 2273 2343 2342 3 2274 2275 2344 3 2274 2344 2343 3 2275 2276 2345 3 2275 2345 2344 3 2276 2277 2346 3 2276 2346 2345 3 2277 2278 2347 3 2277 2347 2346 3 2278 2279 2348 3 2278 2348 2347 3 2279 2280 2349 3 2279 2349 2348 3 2280 2281 2350 3 2280 2350 2349 3 2281 2282 2351 3 2281 2351 2350 3 2282 2283 2352 3 2282 2352 2351 3 2283 2284 2353 3 2283 2353 2352 3 2284 2285 2354 3 2284 2354 2353 3 2285 2286 2355 3 2285 2355 2354 3 2286 2287 2356 3 2286 2356 2355 3 2287 2288 2357 3 2287 2357 2356 3 2288 2289 2358 3 2288 2358 2357 3 2289 2290 2359 3 2289 2359 2358 3 2290 2291 2359 3 2360 2359 2291 3 2291 2292 2360 3 2361 2360 2292 3 2292 2293 2361 3 2362 2361 2293 3 2293 2294 2362 3 2363 2362 2294 3 2294 2295 2363 3 2364 2363 2295 3 2295 2296 2364 3 2365 2364 2296 3 2296 2297 2365 3 2366 2365 2297 3 2297 2298 2366 3 2367 2366 2298 3 2298 2299 2367 3 2368 2367 2299 3 2299 2300 2368 3 2369 2368 2300 3 2300 2301 2369 3 2370 2369 2301 3 2301 2302 2370 3 2371 2370 2302 3 2302 2303 2371 3 2372 2371 2303 3 2303 2304 2372 3 2373 2372 2304 3 2304 2305 2373 3 2374 2373 2305 3 2305 2306 2374 3 2375 2374 2306 3 2306 2307 2375 3 2376 2375 2307 3 2307 2308 2376 3 2377 2376 2308 3 2308 2309 2377 3 2378 2377 2309 3 2309 2310 2378 3 2379 2378 2310 3 2310 2311 2379 3 2380 2379 2311 3 2311 2312 2380 3 2381 2380 2312 3 2312 2313 2381 3 2382 2381 2313 3 2313 2314 2382 3 2383 2382 2314 3 2314 2315 2383 3 2384 2383 2315 3 2315 2316 2384 3 2385 2384 2316 3 2316 2317 2385 3 2386 2385 2317 3 2317 2318 2386 3 2387 2386 2318 3 2318 2319 2387 3 2388 2387 2319 3 2319 2320 2388 3 2389 2388 2320 3 2320 2321 2390 3 2320 2390 2389 3 2321 2322 2391 3 2321 2391 2390 3 2322 2323 2392 3 2322 2392 2391 3 2323 2324 2393 3 2323 2393 2392 3 2324 2325 2394 3 2324 2394 2393 3 2325 2326 2395 3 2325 2395 2394 3 2326 2327 2396 3 2326 2396 2395 3 2327 2328 2397 3 2327 2397 2396 3 2328 2329 2398 3 2328 2398 2397 3 2329 2330 2399 3 2329 2399 2398 3 2330 2331 2400 3 2330 2400 2399 3 2331 2332 2401 3 2331 2401 2400 3 2332 2333 2402 3 2332 2402 2401 3 2333 2334 2403 3 2333 2403 2402 3 2334 2335 2404 3 2334 2404 2403 3 2335 2336 2405 3 2335 2405 2404 3 2336 2337 2406 3 2336 2406 2405 3 2337 2338 2407 3 2337 2407 2406 3 2338 2339 2408 3 2338 2408 2407 3 2339 5021 5025 3 2339 5025 2408 3 2340 2341 2410 3 2340 2410 2409 3 2340 2409 5028 3 2340 5028 5024 3 2341 2342 2411 3 2341 2411 2410 3 2342 2343 2412 3 2342 2412 2411 3 2343 2344 2413 3 2343 2413 2412 3 2344 2345 2414 3 2344 2414 2413 3 2345 2346 2415 3 2345 2415 2414 3 2346 2347 2416 3 2346 2416 2415 3 2347 2348 2417 3 2347 2417 2416 3 2348 2349 2418 3 2348 2418 2417 3 2349 2350 2419 3 2349 2419 2418 3 2350 2351 2419 3 2420 2419 2351 3 2351 2352 2420 3 2421 2420 2352 3 2352 2353 2421 3 2422 2421 2353 3 2353 2354 2422 3 2423 2422 2354 3 2354 2355 2423 3 2424 2423 2355 3 2355 2356 2424 3 2425 2424 2356 3 2356 2357 2425 3 2426 2425 2357 3 2357 2358 2426 3 2427 2426 2358 3 2358 2359 2427 3 2428 2427 2359 3 2359 2360 2428 3 2429 2428 2360 3 2360 2361 2429 3 2430 2429 2361 3 2361 2362 2430 3 2431 2430 2362 3 2362 2363 2431 3 2432 2431 2363 3 2363 2364 2432 3 2433 2432 2364 3 2364 2365 2433 3 2434 2433 2365 3 2365 2366 2434 3 2435 2434 2366 3 2366 2367 2435 3 2436 2435 2367 3 2367 2368 2436 3 2437 2436 2368 3 2368 2369 2437 3 2438 2437 2369 3 2369 2370 2438 3 2439 2438 2370 3 2370 2371 2439 3 2440 2439 2371 3 2371 2372 2440 3 2441 2440 2372 3 2372 2373 2441 3 2442 2441 2373 3 2373 2374 2442 3 2443 2442 2374 3 2374 2375 2443 3 2444 2443 2375 3 2375 2376 2444 3 2445 2444 2376 3 2376 2377 2445 3 2446 2445 2377 3 2377 2378 2446 3 2447 2446 2378 3 2378 2379 2447 3 2448 2447 2379 3 2379 2380 2449 3 2379 2449 2448 3 2380 2381 2450 3 2380 2450 2449 3 2381 2382 2451 3 2381 2451 2450 3 2382 2383 2452 3 2382 2452 2451 3 2383 2384 2453 3 2383 2453 2452 3 2384 2385 2454 3 2384 2454 2453 3 2385 2386 2455 3 2385 2455 2454 3 2386 2387 2456 3 2386 2456 2455 3 2387 2388 2457 3 2387 2457 2456 3 2388 2389 2458 3 2388 2458 2457 3 2389 2390 2459 3 2389 2459 2458 3 2390 2391 2460 3 2390 2460 2459 3 2391 2392 2461 3 2391 2461 2460 3 2392 2393 2462 3 2392 2462 2461 3 2393 2394 2463 3 2393 2463 2462 3 2394 2395 2464 3 2394 2464 2463 3 2395 2396 2465 3 2395 2465 2464 3 2396 2397 2466 3 2396 2466 2465 3 2397 2398 2467 3 2397 2467 2466 3 2398 2399 2468 3 2398 2468 2467 3 2399 2400 2469 3 2399 2469 2468 3 2400 2401 2470 3 2400 2470 2469 3 2401 2402 2471 3 2401 2471 2470 3 2402 2403 2472 3 2402 2472 2471 3 2403 2404 2473 3 2403 2473 2472 3 2404 2405 2474 3 2404 2474 2473 3 2405 2406 2475 3 2405 2475 2474 3 2406 2407 2476 3 2406 2476 2475 3 2407 2408 2477 3 2407 2477 2476 3 2408 5025 2477 3 5029 2477 5025 3 2409 2410 2479 3 2409 2479 2478 3 2409 2478 5032 3 2409 5032 5028 3 2410 2411 2479 3 2480 2479 2411 3 2411 2412 2480 3 2481 2480 2412 3 2412 2413 2481 3 2482 2481 2413 3 2413 2414 2482 3 2483 2482 2414 3 2414 2415 2483 3 2484 2483 2415 3 2415 2416 2484 3 2485 2484 2416 3 2416 2417 2485 3 2486 2485 2417 3 2417 2418 2486 3 2487 2486 2418 3 2418 2419 2487 3 2488 2487 2419 3 2419 2420 2488 3 2489 2488 2420 3 2420 2421 2489 3 2490 2489 2421 3 2421 2422 2490 3 2491 2490 2422 3 2422 2423 2491 3 2492 2491 2423 3 2423 2424 2492 3 2493 2492 2424 3 2424 2425 2493 3 2494 2493 2425 3 2425 2426 2494 3 2495 2494 2426 3 2426 2427 2495 3 2496 2495 2427 3 2427 2428 2496 3 2497 2496 2428 3 2428 2429 2497 3 2498 2497 2429 3 2429 2430 2498 3 2499 2498 2430 3 2430 2431 2499 3 2500 2499 2431 3 2431 2432 2500 3 2501 2500 2432 3 2432 2433 2501 3 2502 2501 2433 3 2433 2434 2502 3 2503 2502 2434 3 2434 2435 2503 3 2504 2503 2435 3 2435 2436 2504 3 2505 2504 2436 3 2436 2437 2505 3 2506 2505 2437 3 2437 2438 2506 3 2507 2506 2438 3 2438 2439 2507 3 2508 2507 2439 3 2439 2440 2508 3 2509 2508 2440 3 2440 2441 2510 3 2440 2510 2509 3 2441 2442 2511 3 2441 2511 2510 3 2442 2443 2512 3 2442 2512 2511 3 2443 2444 2513 3 2443 2513 2512 3 2444 2445 2514 3 2444 2514 2513 3 2445 2446 2515 3 2445 2515 2514 3 2446 2447 2516 3 2446 2516 2515 3 2447 2448 2517 3 2447 2517 2516 3 2448 2449 2518 3 2448 2518 2517 3 2449 2450 2519 3 2449 2519 2518 3 2450 2451 2520 3 2450 2520 2519 3 2451 2452 2521 3 2451 2521 2520 3 2452 2453 2522 3 2452 2522 2521 3 2453 2454 2523 3 2453 2523 2522 3 2454 2455 2524 3 2454 2524 2523 3 2455 2456 2525 3 2455 2525 2524 3 2456 2457 2526 3 2456 2526 2525 3 2457 2458 2527 3 2457 2527 2526 3 2458 2459 2528 3 2458 2528 2527 3 2459 2460 2529 3 2459 2529 2528 3 2460 2461 2530 3 2460 2530 2529 3 2461 2462 2531 3 2461 2531 2530 3 2462 2463 2532 3 2462 2532 2531 3 2463 2464 2533 3 2463 2533 2532 3 2464 2465 2534 3 2464 2534 2533 3 2465 2466 2535 3 2465 2535 2534 3 2466 2467 2536 3 2466 2536 2535 3 2467 2468 2537 3 2467 2537 2536 3 2468 2469 2538 3 2468 2538 2537 3 2469 2470 2539 3 2469 2539 2538 3 2470 2471 2539 3 2540 2539 2471 3 2471 2472 2540 3 2541 2540 2472 3 2472 2473 2541 3 2542 2541 2473 3 2473 2474 2542 3 2543 2542 2474 3 2474 2475 2543 3 2544 2543 2475 3 2475 2476 2544 3 2545 2544 2476 3 2476 2477 2545 3 2546 2545 2477 3 2477 5029 5033 3 2477 5033 2546 3 2478 2479 2547 3 2548 2547 2479 3 2478 2547 5036 3 2478 5036 5032 3 2479 2480 2548 3 2549 2548 2480 3 2480 2481 2549 3 2550 2549 2481 3 2481 2482 2550 3 2551 2550 2482 3 2482 2483 2551 3 2552 2551 2483 3 2483 2484 2552 3 2553 2552 2484 3 2484 2485 2553 3 2554 2553 2485 3 2485 2486 2554 3 2555 2554 2486 3 2486 2487 2555 3 2556 2555 2487 3 2487 2488 2556 3 2557 2556 2488 3 2488 2489 2557 3 2558 2557 2489 3 2489 2490 2558 3 2559 2558 2490 3 2490 2491 2559 3 2560 2559 2491 3 2491 2492 2560 3 2561 2560 2492 3 2492 2493 2561 3 2562 2561 2493 3 2493 2494 2562 3 2563 2562 2494 3 2494 2495 2563 3 2564 2563 2495 3 2495 2496 2564 3 2565 2564 2496 3 2496 2497 2565 3 2566 2565 2497 3 2497 2498 2566 3 2567 2566 2498 3 2498 2499 2567 3 2568 2567 2499 3 2499 2500 2568 3 2569 2568 2500 3 2500 2501 2569 3 2570 2569 2501 3 2501 2502 2571 3 2501 2571 2570 3 2502 2503 2572 3 2502 2572 2571 3 2503 2504 2573 3 2503 2573 2572 3 2504 2505 2574 3 2504 2574 2573 3 2505 2506 2575 3 2505 2575 2574 3 2506 2507 2576 3 2506 2576 2575 3 2507 2508 2577 3 2507 2577 2576 3 2508 2509 2578 3 2508 2578 2577 3 2509 2510 2579 3 2509 2579 2578 3 2510 2511 2580 3 2510 2580 2579 3 2511 2512 2581 3 2511 2581 2580 3 2512 2513 2582 3 2512 2582 2581 3 2513 2514 2583 3 2513 2583 2582 3 2514 2515 2584 3 2514 2584 2583 3 2515 2516 2585 3 2515 2585 2584 3 2516 2517 2586 3 2516 2586 2585 3 2517 2518 2587 3 2517 2587 2586 3 2518 2519 2588 3 2518 2588 2587 3 2519 2520 2589 3 2519 2589 2588 3 2520 2521 2590 3 2520 2590 2589 3 2521 2522 2591 3 2521 2591 2590 3 2522 2523 2592 3 2522 2592 2591 3 2523 2524 2593 3 2523 2593 2592 3 2524 2525 2594 3 2524 2594 2593 3 2525 2526 2595 3 2525 2595 2594 3 2526 2527 2596 3 2526 2596 2595 3 2527 2528 2597 3 2527 2597 2596 3 2528 2529 2598 3 2528 2598 2597 3 2529 2530 2599 3 2529 2599 2598 3 2530 2531 2600 3 2530 2600 2599 3 2531 2532 2601 3 2531 2601 2600 3 2532 2533 2601 3 2602 2601 2533 3 2533 2534 2602 3 2603 2602 2534 3 2534 2535 2603 3 2604 2603 2535 3 2535 2536 2604 3 2605 2604 2536 3 2536 2537 2605 3 2606 2605 2537 3 2537 2538 2606 3 2607 2606 2538 3 2538 2539 2607 3 2608 2607 2539 3 2539 2540 2608 3 2609 2608 2540 3 2540 2541 2609 3 2610 2609 2541 3 2541 2542 2610 3 2611 2610 2542 3 2542 2543 2611 3 2612 2611 2543 3 2543 2544 2612 3 2613 2612 2544 3 2544 2545 2613 3 2614 2613 2545 3 2545 2546 2614 3 2615 2614 2546 3 2546 5033 2615 3 5037 2615 5033 3 2547 2548 2616 3 2617 2616 2548 3 2547 2616 5040 3 2547 5040 5036 3 2548 2549 2617 3 2618 2617 2549 3 2549 2550 2618 3 2619 2618 2550 3 2550 2551 2619 3 2620 2619 2551 3 2551 2552 2620 3 2621 2620 2552 3 2552 2553 2621 3 2622 2621 2553 3 2553 2554 2622 3 2623 2622 2554 3 2554 2555 2623 3 2624 2623 2555 3 2555 2556 2624 3 2625 2624 2556 3 2556 2557 2625 3 2626 2625 2557 3 2557 2558 2626 3 2627 2626 2558 3 2558 2559 2627 3 2628 2627 2559 3 2559 2560 2628 3 2629 2628 2560 3 2560 2561 2629 3 2630 2629 2561 3 2561 2562 2630 3 2631 2630 2562 3 2562 2563 2631 3 2632 2631 2563 3 2563 2564 2633 3 2563 2633 2632 3 2564 2565 2634 3 2564 2634 2633 3 2565 2566 2635 3 2565 2635 2634 3 2566 2567 2636 3 2566 2636 2635 3 2567 2568 2637 3 2567 2637 2636 3 2568 2569 2638 3 2568 2638 2637 3 2569 2570 2639 3 2569 2639 2638 3 2570 2571 2640 3 2570 2640 2639 3 2571 2572 2641 3 2571 2641 2640 3 2572 2573 2642 3 2572 2642 2641 3 2573 2574 2643 3 2573 2643 2642 3 2574 2575 2644 3 2574 2644 2643 3 2575 2576 2645 3 2575 2645 2644 3 2576 2577 2646 3 2576 2646 2645 3 2577 2578 2647 3 2577 2647 2646 3 2578 2579 2648 3 2578 2648 2647 3 2579 2580 2649 3 2579 2649 2648 3 2580 2581 2650 3 2580 2650 2649 3 2581 2582 2651 3 2581 2651 2650 3 2582 2583 2652 3 2582 2652 2651 3 2583 2584 2653 3 2583 2653 2652 3 2584 2585 2654 3 2584 2654 2653 3 2585 2586 2655 3 2585 2655 2654 3 2586 2587 2656 3 2586 2656 2655 3 2587 2588 2657 3 2587 2657 2656 3 2588 2589 2658 3 2588 2658 2657 3 2589 2590 2659 3 2589 2659 2658 3 2590 2591 2660 3 2590 2660 2659 3 2591 2592 2661 3 2591 2661 2660 3 2592 2593 2662 3 2592 2662 2661 3 2593 2594 2663 3 2593 2663 2662 3 2594 2595 2663 3 2664 2663 2595 3 2595 2596 2664 3 2665 2664 2596 3 2596 2597 2665 3 2666 2665 2597 3 2597 2598 2666 3 2667 2666 2598 3 2598 2599 2667 3 2668 2667 2599 3 2599 2600 2668 3 2669 2668 2600 3 2600 2601 2669 3 2670 2669 2601 3 2601 2602 2670 3 2671 2670 2602 3 2602 2603 2671 3 2672 2671 2603 3 2603 2604 2672 3 2673 2672 2604 3 2604 2605 2673 3 2674 2673 2605 3 2605 2606 2674 3 2675 2674 2606 3 2606 2607 2675 3 2676 2675 2607 3 2607 2608 2676 3 2677 2676 2608 3 2608 2609 2677 3 2678 2677 2609 3 2609 2610 2678 3 2679 2678 2610 3 2610 2611 2679 3 2680 2679 2611 3 2611 2612 2680 3 2681 2680 2612 3 2612 2613 2681 3 2682 2681 2613 3 2613 2614 2682 3 2683 2682 2614 3 2614 2615 2683 3 2684 2683 2615 3 2615 5037 5041 3 2615 5041 2684 3 2616 2617 2685 3 2686 2685 2617 3 2616 2685 5044 3 2616 5044 5040 3 2617 2618 2686 3 2687 2686 2618 3 2618 2619 2687 3 2688 2687 2619 3 2619 2620 2688 3 2689 2688 2620 3 2620 2621 2689 3 2690 2689 2621 3 2621 2622 2690 3 2691 2690 2622 3 2622 2623 2691 3 2692 2691 2623 3 2623 2624 2692 3 2693 2692 2624 3 2624 2625 2693 3 2694 2693 2625 3 2625 2626 2694 3 2695 2694 2626 3 2626 2627 2696 3 2626 2696 2695 3 2627 2628 2697 3 2627 2697 2696 3 2628 2629 2698 3 2628 2698 2697 3 2629 2630 2699 3 2629 2699 2698 3 2630 2631 2700 3 2630 2700 2699 3 2631 2632 2701 3 2631 2701 2700 3 2632 2633 2702 3 2632 2702 2701 3 2633 2634 2703 3 2633 2703 2702 3 2634 2635 2704 3 2634 2704 2703 3 2635 2636 2705 3 2635 2705 2704 3 2636 2637 2706 3 2636 2706 2705 3 2637 2638 2707 3 2637 2707 2706 3 2638 2639 2708 3 2638 2708 2707 3 2639 2640 2709 3 2639 2709 2708 3 2640 2641 2710 3 2640 2710 2709 3 2641 2642 2711 3 2641 2711 2710 3 2642 2643 2712 3 2642 2712 2711 3 2643 2644 2713 3 2643 2713 2712 3 2644 2645 2714 3 2644 2714 2713 3 2645 2646 2715 3 2645 2715 2714 3 2646 2647 2716 3 2646 2716 2715 3 2647 2648 2717 3 2647 2717 2716 3 2648 2649 2718 3 2648 2718 2717 3 2649 2650 2719 3 2649 2719 2718 3 2650 2651 2720 3 2650 2720 2719 3 2651 2652 2721 3 2651 2721 2720 3 2652 2653 2722 3 2652 2722 2721 3 2653 2654 2723 3 2653 2723 2722 3 2654 2655 2724 3 2654 2724 2723 3 2655 2656 2725 3 2655 2725 2724 3 2656 2657 2726 3 2656 2726 2725 3 2657 2658 2726 3 2727 2726 2658 3 2658 2659 2727 3 2728 2727 2659 3 2659 2660 2728 3 2729 2728 2660 3 2660 2661 2729 3 2730 2729 2661 3 2661 2662 2730 3 2731 2730 2662 3 2662 2663 2731 3 2732 2731 2663 3 2663 2664 2732 3 2733 2732 2664 3 2664 2665 2733 3 2734 2733 2665 3 2665 2666 2734 3 2735 2734 2666 3 2666 2667 2735 3 2736 2735 2667 3 2667 2668 2736 3 2737 2736 2668 3 2668 2669 2737 3 2738 2737 2669 3 2669 2670 2738 3 2739 2738 2670 3 2670 2671 2739 3 2740 2739 2671 3 2671 2672 2740 3 2741 2740 2672 3 2672 2673 2741 3 2742 2741 2673 3 2673 2674 2742 3 2743 2742 2674 3 2674 2675 2743 3 2744 2743 2675 3 2675 2676 2744 3 2745 2744 2676 3 2676 2677 2745 3 2746 2745 2677 3 2677 2678 2746 3 2747 2746 2678 3 2678 2679 2747 3 2748 2747 2679 3 2679 2680 2748 3 2749 2748 2680 3 2680 2681 2749 3 2750 2749 2681 3 2681 2682 2750 3 2751 2750 2682 3 2682 2683 2751 3 2752 2751 2683 3 2683 2684 2752 3 2753 2752 2684 3 2684 5041 2753 3 5045 2753 5041 3 2685 2686 2754 3 2755 2754 2686 3 2685 2754 5044 3 5048 5044 2754 3 2686 2687 2755 3 2756 2755 2687 3 2687 2688 2756 3 2757 2756 2688 3 2688 2689 2757 3 2758 2757 2689 3 2689 2690 2759 3 2689 2759 2758 3 2690 2691 2760 3 2690 2760 2759 3 2691 2692 2761 3 2691 2761 2760 3 2692 2693 2762 3 2692 2762 2761 3 2693 2694 2763 3 2693 2763 2762 3 2694 2695 2764 3 2694 2764 2763 3 2695 2696 2765 3 2695 2765 2764 3 2696 2697 2766 3 2696 2766 2765 3 2697 2698 2767 3 2697 2767 2766 3 2698 2699 2768 3 2698 2768 2767 3 2699 2700 2769 3 2699 2769 2768 3 2700 2701 2770 3 2700 2770 2769 3 2701 2702 2771 3 2701 2771 2770 3 2702 2703 2772 3 2702 2772 2771 3 2703 2704 2773 3 2703 2773 2772 3 2704 2705 2774 3 2704 2774 2773 3 2705 2706 2775 3 2705 2775 2774 3 2706 2707 2776 3 2706 2776 2775 3 2707 2708 2777 3 2707 2777 2776 3 2708 2709 2778 3 2708 2778 2777 3 2709 2710 2779 3 2709 2779 2778 3 2710 2711 2780 3 2710 2780 2779 3 2711 2712 2781 3 2711 2781 2780 3 2712 2713 2782 3 2712 2782 2781 3 2713 2714 2783 3 2713 2783 2782 3 2714 2715 2784 3 2714 2784 2783 3 2715 2716 2785 3 2715 2785 2784 3 2716 2717 2786 3 2716 2786 2785 3 2717 2718 2787 3 2717 2787 2786 3 2718 2719 2788 3 2718 2788 2787 3 2719 2720 2789 3 2719 2789 2788 3 2720 2721 2790 3 2720 2790 2789 3 2721 2722 2790 3 2791 2790 2722 3 2722 2723 2791 3 2792 2791 2723 3 2723 2724 2792 3 2793 2792 2724 3 2724 2725 2793 3 2794 2793 2725 3 2725 2726 2794 3 2795 2794 2726 3 2726 2727 2795 3 2796 2795 2727 3 2727 2728 2796 3 2797 2796 2728 3 2728 2729 2797 3 2798 2797 2729 3 2729 2730 2798 3 2799 2798 2730 3 2730 2731 2799 3 2800 2799 2731 3 2731 2732 2800 3 2801 2800 2732 3 2732 2733 2801 3 2802 2801 2733 3 2733 2734 2802 3 2803 2802 2734 3 2734 2735 2803 3 2804 2803 2735 3 2735 2736 2804 3 2805 2804 2736 3 2736 2737 2805 3 2806 2805 2737 3 2737 2738 2806 3 2807 2806 2738 3 2738 2739 2807 3 2808 2807 2739 3 2739 2740 2808 3 2809 2808 2740 3 2740 2741 2809 3 2810 2809 2741 3 2741 2742 2810 3 2811 2810 2742 3 2742 2743 2811 3 2812 2811 2743 3 2743 2744 2812 3 2813 2812 2744 3 2744 2745 2813 3 2814 2813 2745 3 2745 2746 2814 3 2815 2814 2746 3 2746 2747 2815 3 2816 2815 2747 3 2747 2748 2816 3 2817 2816 2748 3 2748 2749 2817 3 2818 2817 2749 3 2749 2750 2818 3 2819 2818 2750 3 2750 2751 2819 3 2820 2819 2751 3 2751 2752 2820 3 2821 2820 2752 3 2752 2753 2821 3 2822 2821 2753 3 2753 5045 5049 3 2753 5049 2822 3 2754 2755 2824 3 2754 2824 2823 3 2754 2823 5048 3 5052 5048 2823 3 2755 2756 2825 3 2755 2825 2824 3 2756 2757 2826 3 2756 2826 2825 3 2757 2758 2827 3 2757 2827 2826 3 2758 2759 2828 3 2758 2828 2827 3 2759 2760 2829 3 2759 2829 2828 3 2760 2761 2830 3 2760 2830 2829 3 2761 2762 2831 3 2761 2831 2830 3 2762 2763 2832 3 2762 2832 2831 3 2763 2764 2833 3 2763 2833 2832 3 2764 2765 2834 3 2764 2834 2833 3 2765 2766 2835 3 2765 2835 2834 3 2766 2767 2836 3 2766 2836 2835 3 2767 2768 2837 3 2767 2837 2836 3 2768 2769 2838 3 2768 2838 2837 3 2769 2770 2839 3 2769 2839 2838 3 2770 2771 2840 3 2770 2840 2839 3 2771 2772 2841 3 2771 2841 2840 3 2772 2773 2842 3 2772 2842 2841 3 2773 2774 2843 3 2773 2843 2842 3 2774 2775 2844 3 2774 2844 2843 3 2775 2776 2845 3 2775 2845 2844 3 2776 2777 2846 3 2776 2846 2845 3 2777 2778 2847 3 2777 2847 2846 3 2778 2779 2848 3 2778 2848 2847 3 2779 2780 2849 3 2779 2849 2848 3 2780 2781 2850 3 2780 2850 2849 3 2781 2782 2851 3 2781 2851 2850 3 2782 2783 2852 3 2782 2852 2851 3 2783 2784 2853 3 2783 2853 2852 3 2784 2785 2854 3 2784 2854 2853 3 2785 2786 2855 3 2785 2855 2854 3 2786 2787 2855 3 2856 2855 2787 3 2787 2788 2856 3 2857 2856 2788 3 2788 2789 2857 3 2858 2857 2789 3 2789 2790 2858 3 2859 2858 2790 3 2790 2791 2859 3 2860 2859 2791 3 2791 2792 2860 3 2861 2860 2792 3 2792 2793 2861 3 2862 2861 2793 3 2793 2794 2862 3 2863 2862 2794 3 2794 2795 2863 3 2864 2863 2795 3 2795 2796 2864 3 2865 2864 2796 3 2796 2797 2865 3 2866 2865 2797 3 2797 2798 2866 3 2867 2866 2798 3 2798 2799 2867 3 2868 2867 2799 3 2799 2800 2868 3 2869 2868 2800 3 2800 2801 2869 3 2870 2869 2801 3 2801 2802 2870 3 2871 2870 2802 3 2802 2803 2871 3 2872 2871 2803 3 2803 2804 2872 3 2873 2872 2804 3 2804 2805 2873 3 2874 2873 2805 3 2805 2806 2874 3 2875 2874 2806 3 2806 2807 2875 3 2876 2875 2807 3 2807 2808 2876 3 2877 2876 2808 3 2808 2809 2877 3 2878 2877 2809 3 2809 2810 2878 3 2879 2878 2810 3 2810 2811 2879 3 2880 2879 2811 3 2811 2812 2880 3 2881 2880 2812 3 2812 2813 2881 3 2882 2881 2813 3 2813 2814 2882 3 2883 2882 2814 3 2814 2815 2883 3 2884 2883 2815 3 2815 2816 2884 3 2885 2884 2816 3 2816 2817 2885 3 2886 2885 2817 3 2817 2818 2886 3 2887 2886 2818 3 2818 2819 2888 3 2818 2888 2887 3 2819 2820 2889 3 2819 2889 2888 3 2820 2821 2890 3 2820 2890 2889 3 2821 2822 2891 3 2821 2891 2890 3 2822 5049 2891 3 5053 2891 5049 3 2823 2824 2893 3 2823 2893 2892 3 2823 2892 5052 3 5056 5052 2892 3 2824 2825 2894 3 2824 2894 2893 3 2825 2826 2895 3 2825 2895 2894 3 2826 2827 2896 3 2826 2896 2895 3 2827 2828 2897 3 2827 2897 2896 3 2828 2829 2898 3 2828 2898 2897 3 2829 2830 2899 3 2829 2899 2898 3 2830 2831 2900 3 2830 2900 2899 3 2831 2832 2901 3 2831 2901 2900 3 2832 2833 2902 3 2832 2902 2901 3 2833 2834 2903 3 2833 2903 2902 3 2834 2835 2904 3 2834 2904 2903 3 2835 2836 2905 3 2835 2905 2904 3 2836 2837 2906 3 2836 2906 2905 3 2837 2838 2907 3 2837 2907 2906 3 2838 2839 2908 3 2838 2908 2907 3 2839 2840 2909 3 2839 2909 2908 3 2840 2841 2910 3 2840 2910 2909 3 2841 2842 2911 3 2841 2911 2910 3 2842 2843 2912 3 2842 2912 2911 3 2843 2844 2913 3 2843 2913 2912 3 2844 2845 2914 3 2844 2914 2913 3 2845 2846 2915 3 2845 2915 2914 3 2846 2847 2916 3 2846 2916 2915 3 2847 2848 2917 3 2847 2917 2916 3 2848 2849 2918 3 2848 2918 2917 3 2849 2850 2919 3 2849 2919 2918 3 2850 2851 2920 3 2850 2920 2919 3 2851 2852 2920 3 2921 2920 2852 3 2852 2853 2921 3 2922 2921 2853 3 2853 2854 2922 3 2923 2922 2854 3 2854 2855 2923 3 2924 2923 2855 3 2855 2856 2924 3 2925 2924 2856 3 2856 2857 2925 3 2926 2925 2857 3 2857 2858 2926 3 2927 2926 2858 3 2858 2859 2927 3 2928 2927 2859 3 2859 2860 2928 3 2929 2928 2860 3 2860 2861 2929 3 2930 2929 2861 3 2861 2862 2930 3 2931 2930 2862 3 2862 2863 2931 3 2932 2931 2863 3 2863 2864 2932 3 2933 2932 2864 3 2864 2865 2933 3 2934 2933 2865 3 2865 2866 2934 3 2935 2934 2866 3 2866 2867 2935 3 2936 2935 2867 3 2867 2868 2936 3 2937 2936 2868 3 2868 2869 2937 3 2938 2937 2869 3 2869 2870 2938 3 2939 2938 2870 3 2870 2871 2939 3 2940 2939 2871 3 2871 2872 2940 3 2941 2940 2872 3 2872 2873 2941 3 2942 2941 2873 3 2873 2874 2942 3 2943 2942 2874 3 2874 2875 2943 3 2944 2943 2875 3 2875 2876 2944 3 2945 2944 2876 3 2876 2877 2945 3 2946 2945 2877 3 2877 2878 2946 3 2947 2946 2878 3 2878 2879 2947 3 2948 2947 2879 3 2879 2880 2948 3 2949 2948 2880 3 2880 2881 2949 3 2950 2949 2881 3 2881 2882 2950 3 2951 2950 2882 3 2882 2883 2951 3 2952 2951 2883 3 2883 2884 2952 3 2953 2952 2884 3 2884 2885 2954 3 2884 2954 2953 3 2885 2886 2955 3 2885 2955 2954 3 2886 2887 2956 3 2886 2956 2955 3 2887 2888 2957 3 2887 2957 2956 3 2888 2889 2958 3 2888 2958 2957 3 2889 2890 2959 3 2889 2959 2958 3 2890 2891 2960 3 2890 2960 2959 3 2891 5053 5057 3 2891 5057 2960 3 2892 2893 2962 3 2892 2962 2961 3 2892 2961 5056 3 5060 5056 2961 3 2893 2894 2963 3 2893 2963 2962 3 2894 2895 2964 3 2894 2964 2963 3 2895 2896 2965 3 2895 2965 2964 3 2896 2897 2966 3 2896 2966 2965 3 2897 2898 2967 3 2897 2967 2966 3 2898 2899 2968 3 2898 2968 2967 3 2899 2900 2969 3 2899 2969 2968 3 2900 2901 2970 3 2900 2970 2969 3 2901 2902 2971 3 2901 2971 2970 3 2902 2903 2972 3 2902 2972 2971 3 2903 2904 2973 3 2903 2973 2972 3 2904 2905 2974 3 2904 2974 2973 3 2905 2906 2975 3 2905 2975 2974 3 2906 2907 2976 3 2906 2976 2975 3 2907 2908 2977 3 2907 2977 2976 3 2908 2909 2978 3 2908 2978 2977 3 2909 2910 2979 3 2909 2979 2978 3 2910 2911 2980 3 2910 2980 2979 3 2911 2912 2981 3 2911 2981 2980 3 2912 2913 2982 3 2912 2982 2981 3 2913 2914 2983 3 2913 2983 2982 3 2914 2915 2984 3 2914 2984 2983 3 2915 2916 2985 3 2915 2985 2984 3 2916 2917 2986 3 2916 2986 2985 3 2917 2918 2986 3 2987 2986 2918 3 2918 2919 2987 3 2988 2987 2919 3 2919 2920 2988 3 2989 2988 2920 3 2920 2921 2989 3 2990 2989 2921 3 2921 2922 2990 3 2991 2990 2922 3 2922 2923 2991 3 2992 2991 2923 3 2923 2924 2992 3 2993 2992 2924 3 2924 2925 2993 3 2994 2993 2925 3 2925 2926 2994 3 2995 2994 2926 3 2926 2927 2995 3 2996 2995 2927 3 2927 2928 2996 3 2997 2996 2928 3 2928 2929 2997 3 2998 2997 2929 3 2929 2930 2998 3 2999 2998 2930 3 2930 2931 2999 3 3000 2999 2931 3 2931 2932 3000 3 3001 3000 2932 3 2932 2933 3001 3 3002 3001 2933 3 2933 2934 3002 3 3003 3002 2934 3 2934 2935 3003 3 3004 3003 2935 3 2935 2936 3004 3 3005 3004 2936 3 2936 2937 3005 3 3006 3005 2937 3 2937 2938 3006 3 3007 3006 2938 3 2938 2939 3007 3 3008 3007 2939 3 2939 2940 3008 3 3009 3008 2940 3 2940 2941 3009 3 3010 3009 2941 3 2941 2942 3010 3 3011 3010 2942 3 2942 2943 3011 3 3012 3011 2943 3 2943 2944 3012 3 3013 3012 2944 3 2944 2945 3013 3 3014 3013 2945 3 2945 2946 3014 3 3015 3014 2946 3 2946 2947 3015 3 3016 3015 2947 3 2947 2948 3016 3 3017 3016 2948 3 2948 2949 3017 3 3018 3017 2949 3 2949 2950 3018 3 3019 3018 2950 3 2950 2951 3019 3 3020 3019 2951 3 2951 2952 3021 3 2951 3021 3020 3 2952 2953 3022 3 2952 3022 3021 3 2953 2954 3023 3 2953 3023 3022 3 2954 2955 3024 3 2954 3024 3023 3 2955 2956 3025 3 2955 3025 3024 3 2956 2957 3026 3 2956 3026 3025 3 2957 2958 3027 3 2957 3027 3026 3 2958 2959 3028 3 2958 3028 3027 3 2959 2960 3029 3 2959 3029 3028 3 2960 5057 3029 3 5061 3029 5057 3 2961 2962 3031 3 2961 3031 3030 3 2961 3030 5060 3 5064 5060 3030 3 2962 2963 3032 3 2962 3032 3031 3 2963 2964 3033 3 2963 3033 3032 3 2964 2965 3034 3 2964 3034 3033 3 2965 2966 3035 3 2965 3035 3034 3 2966 2967 3036 3 2966 3036 3035 3 2967 2968 3037 3 2967 3037 3036 3 2968 2969 3038 3 2968 3038 3037 3 2969 2970 3039 3 2969 3039 3038 3 2970 2971 3040 3 2970 3040 3039 3 2971 2972 3041 3 2971 3041 3040 3 2972 2973 3042 3 2972 3042 3041 3 2973 2974 3043 3 2973 3043 3042 3 2974 2975 3044 3 2974 3044 3043 3 2975 2976 3045 3 2975 3045 3044 3 2976 2977 3046 3 2976 3046 3045 3 2977 2978 3047 3 2977 3047 3046 3 2978 2979 3048 3 2978 3048 3047 3 2979 2980 3049 3 2979 3049 3048 3 2980 2981 3050 3 2980 3050 3049 3 2981 2982 3051 3 2981 3051 3050 3 2982 2983 3052 3 2982 3052 3051 3 2983 2984 3053 3 2983 3053 3052 3 2984 2985 3053 3 3054 3053 2985 3 2985 2986 3054 3 3055 3054 2986 3 2986 2987 3055 3 3056 3055 2987 3 2987 2988 3056 3 3057 3056 2988 3 2988 2989 3057 3 3058 3057 2989 3 2989 2990 3058 3 3059 3058 2990 3 2990 2991 3059 3 3060 3059 2991 3 2991 2992 3060 3 3061 3060 2992 3 2992 2993 3061 3 3062 3061 2993 3 2993 2994 3062 3 3063 3062 2994 3 2994 2995 3063 3 3064 3063 2995 3 2995 2996 3064 3 3065 3064 2996 3 2996 2997 3065 3 3066 3065 2997 3 2997 2998 3066 3 3067 3066 2998 3 2998 2999 3067 3 3068 3067 2999 3 2999 3000 3068 3 3069 3068 3000 3 3000 3001 3069 3 3070 3069 3001 3 3001 3002 3070 3 3071 3070 3002 3 3002 3003 3071 3 3072 3071 3003 3 3003 3004 3072 3 3073 3072 3004 3 3004 3005 3073 3 3074 3073 3005 3 3005 3006 3074 3 3075 3074 3006 3 3006 3007 3075 3 3076 3075 3007 3 3007 3008 3076 3 3077 3076 3008 3 3008 3009 3077 3 3078 3077 3009 3 3009 3010 3078 3 3079 3078 3010 3 3010 3011 3079 3 3080 3079 3011 3 3011 3012 3080 3 3081 3080 3012 3 3012 3013 3081 3 3082 3081 3013 3 3013 3014 3082 3 3083 3082 3014 3 3014 3015 3083 3 3084 3083 3015 3 3015 3016 3084 3 3085 3084 3016 3 3016 3017 3085 3 3086 3085 3017 3 3017 3018 3086 3 3087 3086 3018 3 3018 3019 3088 3 3018 3088 3087 3 3019 3020 3089 3 3019 3089 3088 3 3020 3021 3090 3 3020 3090 3089 3 3021 3022 3091 3 3021 3091 3090 3 3022 3023 3092 3 3022 3092 3091 3 3023 3024 3093 3 3023 3093 3092 3 3024 3025 3094 3 3024 3094 3093 3 3025 3026 3095 3 3025 3095 3094 3 3026 3027 3096 3 3026 3096 3095 3 3027 3028 3097 3 3027 3097 3096 3 3028 3029 3098 3 3028 3098 3097 3 3029 5061 5065 3 3029 5065 3098 3 3030 3031 3100 3 3030 3100 3099 3 3030 3099 5064 3 5068 5064 3099 3 3031 3032 3101 3 3031 3101 3100 3 3032 3033 3102 3 3032 3102 3101 3 3033 3034 3103 3 3033 3103 3102 3 3034 3035 3104 3 3034 3104 3103 3 3035 3036 3105 3 3035 3105 3104 3 3036 3037 3106 3 3036 3106 3105 3 3037 3038 3107 3 3037 3107 3106 3 3038 3039 3108 3 3038 3108 3107 3 3039 3040 3109 3 3039 3109 3108 3 3040 3041 3110 3 3040 3110 3109 3 3041 3042 3111 3 3041 3111 3110 3 3042 3043 3112 3 3042 3112 3111 3 3043 3044 3113 3 3043 3113 3112 3 3044 3045 3114 3 3044 3114 3113 3 3045 3046 3115 3 3045 3115 3114 3 3046 3047 3116 3 3046 3116 3115 3 3047 3048 3117 3 3047 3117 3116 3 3048 3049 3118 3 3048 3118 3117 3 3049 3050 3119 3 3049 3119 3118 3 3050 3051 3120 3 3050 3120 3119 3 3051 3052 3121 3 3051 3121 3120 3 3052 3053 3121 3 3122 3121 3053 3 3053 3054 3122 3 3123 3122 3054 3 3054 3055 3123 3 3124 3123 3055 3 3055 3056 3124 3 3125 3124 3056 3 3056 3057 3125 3 3126 3125 3057 3 3057 3058 3126 3 3127 3126 3058 3 3058 3059 3127 3 3128 3127 3059 3 3059 3060 3128 3 3129 3128 3060 3 3060 3061 3129 3 3130 3129 3061 3 3061 3062 3130 3 3131 3130 3062 3 3062 3063 3131 3 3132 3131 3063 3 3063 3064 3132 3 3133 3132 3064 3 3064 3065 3133 3 3134 3133 3065 3 3065 3066 3134 3 3135 3134 3066 3 3066 3067 3135 3 3136 3135 3067 3 3067 3068 3136 3 3137 3136 3068 3 3068 3069 3137 3 3138 3137 3069 3 3069 3070 3138 3 3139 3138 3070 3 3070 3071 3139 3 3140 3139 3071 3 3071 3072 3140 3 3141 3140 3072 3 3072 3073 3141 3 3142 3141 3073 3 3073 3074 3142 3 3143 3142 3074 3 3074 3075 3143 3 3144 3143 3075 3 3075 3076 3144 3 3145 3144 3076 3 3076 3077 3145 3 3146 3145 3077 3 3077 3078 3146 3 3147 3146 3078 3 3078 3079 3147 3 3148 3147 3079 3 3079 3080 3148 3 3149 3148 3080 3 3080 3081 3149 3 3150 3149 3081 3 3081 3082 3150 3 3151 3150 3082 3 3082 3083 3151 3 3152 3151 3083 3 3083 3084 3152 3 3153 3152 3084 3 3084 3085 3153 3 3154 3153 3085 3 3085 3086 3154 3 3155 3154 3086 3 3086 3087 3156 3 3086 3156 3155 3 3087 3088 3157 3 3087 3157 3156 3 3088 3089 3158 3 3088 3158 3157 3 3089 3090 3159 3 3089 3159 3158 3 3090 3091 3160 3 3090 3160 3159 3 3091 3092 3161 3 3091 3161 3160 3 3092 3093 3162 3 3092 3162 3161 3 3093 3094 3163 3 3093 3163 3162 3 3094 3095 3164 3 3094 3164 3163 3 3095 3096 3165 3 3095 3165 3164 3 3096 3097 3166 3 3096 3166 3165 3 3097 3098 3167 3 3097 3167 3166 3 3098 5065 3167 3 5069 3167 5065 3 3099 3100 3169 3 3099 3169 3168 3 3099 3168 5068 3 5072 5068 3168 3 3100 3101 3170 3 3100 3170 3169 3 3101 3102 3171 3 3101 3171 3170 3 3102 3103 3172 3 3102 3172 3171 3 3103 3104 3173 3 3103 3173 3172 3 3104 3105 3174 3 3104 3174 3173 3 3105 3106 3175 3 3105 3175 3174 3 3106 3107 3176 3 3106 3176 3175 3 3107 3108 3177 3 3107 3177 3176 3 3108 3109 3178 3 3108 3178 3177 3 3109 3110 3179 3 3109 3179 3178 3 3110 3111 3180 3 3110 3180 3179 3 3111 3112 3181 3 3111 3181 3180 3 3112 3113 3182 3 3112 3182 3181 3 3113 3114 3183 3 3113 3183 3182 3 3114 3115 3184 3 3114 3184 3183 3 3115 3116 3185 3 3115 3185 3184 3 3116 3117 3186 3 3116 3186 3185 3 3117 3118 3187 3 3117 3187 3186 3 3118 3119 3188 3 3118 3188 3187 3 3119 3120 3189 3 3119 3189 3188 3 3120 3121 3189 3 3190 3189 3121 3 3121 3122 3190 3 3191 3190 3122 3 3122 3123 3191 3 3192 3191 3123 3 3123 3124 3192 3 3193 3192 3124 3 3124 3125 3193 3 3194 3193 3125 3 3125 3126 3194 3 3195 3194 3126 3 3126 3127 3195 3 3196 3195 3127 3 3127 3128 3196 3 3197 3196 3128 3 3128 3129 3197 3 3198 3197 3129 3 3129 3130 3198 3 3199 3198 3130 3 3130 3131 3199 3 3200 3199 3131 3 3131 3132 3200 3 3201 3200 3132 3 3132 3133 3201 3 3202 3201 3133 3 3133 3134 3202 3 3203 3202 3134 3 3134 3135 3203 3 3204 3203 3135 3 3135 3136 3204 3 3205 3204 3136 3 3136 3137 3205 3 3206 3205 3137 3 3137 3138 3206 3 3207 3206 3138 3 3138 3139 3207 3 3208 3207 3139 3 3139 3140 3208 3 3209 3208 3140 3 3140 3141 3209 3 3210 3209 3141 3 3141 3142 3210 3 3211 3210 3142 3 3142 3143 3211 3 3212 3211 3143 3 3143 3144 3212 3 3213 3212 3144 3 3144 3145 3213 3 3214 3213 3145 3 3145 3146 3214 3 3215 3214 3146 3 3146 3147 3215 3 3216 3215 3147 3 3147 3148 3216 3 3217 3216 3148 3 3148 3149 3217 3 3218 3217 3149 3 3149 3150 3218 3 3219 3218 3150 3 3150 3151 3219 3 3220 3219 3151 3 3151 3152 3220 3 3221 3220 3152 3 3152 3153 3221 3 3222 3221 3153 3 3153 3154 3222 3 3223 3222 3154 3 3154 3155 3223 3 3224 3223 3155 3 3155 3156 3225 3 3155 3225 3224 3 3156 3157 3226 3 3156 3226 3225 3 3157 3158 3227 3 3157 3227 3226 3 3158 3159 3228 3 3158 3228 3227 3 3159 3160 3229 3 3159 3229 3228 3 3160 3161 3230 3 3160 3230 3229 3 3161 3162 3231 3 3161 3231 3230 3 3162 3163 3232 3 3162 3232 3231 3 3163 3164 3233 3 3163 3233 3232 3 3164 3165 3234 3 3164 3234 3233 3 3165 3166 3235 3 3165 3235 3234 3 3166 3167 3236 3 3166 3236 3235 3 3167 5069 5073 3 3167 5073 3236 3 3168 3169 3238 3 3168 3238 3237 3 3168 3237 5072 3 5076 5072 3237 3 3169 3170 3239 3 3169 3239 3238 3 3170 3171 3240 3 3170 3240 3239 3 3171 3172 3241 3 3171 3241 3240 3 3172 3173 3242 3 3172 3242 3241 3 3173 3174 3243 3 3173 3243 3242 3 3174 3175 3244 3 3174 3244 3243 3 3175 3176 3245 3 3175 3245 3244 3 3176 3177 3246 3 3176 3246 3245 3 3177 3178 3247 3 3177 3247 3246 3 3178 3179 3248 3 3178 3248 3247 3 3179 3180 3249 3 3179 3249 3248 3 3180 3181 3250 3 3180 3250 3249 3 3181 3182 3251 3 3181 3251 3250 3 3182 3183 3252 3 3182 3252 3251 3 3183 3184 3253 3 3183 3253 3252 3 3184 3185 3254 3 3184 3254 3253 3 3185 3186 3255 3 3185 3255 3254 3 3186 3187 3256 3 3186 3256 3255 3 3187 3188 3257 3 3187 3257 3256 3 3188 3189 3258 3 3188 3258 3257 3 3189 3190 3258 3 3259 3258 3190 3 3190 3191 3259 3 3260 3259 3191 3 3191 3192 3260 3 3261 3260 3192 3 3192 3193 3261 3 3262 3261 3193 3 3193 3194 3262 3 3263 3262 3194 3 3194 3195 3263 3 3264 3263 3195 3 3195 3196 3264 3 3265 3264 3196 3 3196 3197 3265 3 3266 3265 3197 3 3197 3198 3266 3 3267 3266 3198 3 3198 3199 3267 3 3268 3267 3199 3 3199 3200 3268 3 3269 3268 3200 3 3200 3201 3269 3 3270 3269 3201 3 3201 3202 3270 3 3271 3270 3202 3 3202 3203 3271 3 3272 3271 3203 3 3203 3204 3272 3 3273 3272 3204 3 3204 3205 3273 3 3274 3273 3205 3 3205 3206 3274 3 3275 3274 3206 3 3206 3207 3275 3 3276 3275 3207 3 3207 3208 3276 3 3277 3276 3208 3 3208 3209 3277 3 3278 3277 3209 3 3209 3210 3278 3 3279 3278 3210 3 3210 3211 3279 3 3280 3279 3211 3 3211 3212 3280 3 3281 3280 3212 3 3212 3213 3281 3 3282 3281 3213 3 3213 3214 3282 3 3283 3282 3214 3 3214 3215 3283 3 3284 3283 3215 3 3215 3216 3284 3 3285 3284 3216 3 3216 3217 3285 3 3286 3285 3217 3 3217 3218 3286 3 3287 3286 3218 3 3218 3219 3287 3 3288 3287 3219 3 3219 3220 3288 3 3289 3288 3220 3 3220 3221 3289 3 3290 3289 3221 3 3221 3222 3290 3 3291 3290 3222 3 3222 3223 3291 3 3292 3291 3223 3 3223 3224 3292 3 3293 3292 3224 3 3224 3225 3294 3 3224 3294 3293 3 3225 3226 3295 3 3225 3295 3294 3 3226 3227 3296 3 3226 3296 3295 3 3227 3228 3297 3 3227 3297 3296 3 3228 3229 3298 3 3228 3298 3297 3 3229 3230 3299 3 3229 3299 3298 3 3230 3231 3300 3 3230 3300 3299 3 3231 3232 3301 3 3231 3301 3300 3 3232 3233 3302 3 3232 3302 3301 3 3233 3234 3303 3 3233 3303 3302 3 3234 3235 3304 3 3234 3304 3303 3 3235 3236 3305 3 3235 3305 3304 3 3236 5073 3305 3 5077 3305 5073 3 3237 3238 3307 3 3237 3307 3306 3 3237 3306 5076 3 5080 5076 3306 3 3238 3239 3308 3 3238 3308 3307 3 3239 3240 3309 3 3239 3309 3308 3 3240 3241 3310 3 3240 3310 3309 3 3241 3242 3311 3 3241 3311 3310 3 3242 3243 3312 3 3242 3312 3311 3 3243 3244 3313 3 3243 3313 3312 3 3244 3245 3314 3 3244 3314 3313 3 3245 3246 3315 3 3245 3315 3314 3 3246 3247 3316 3 3246 3316 3315 3 3247 3248 3317 3 3247 3317 3316 3 3248 3249 3318 3 3248 3318 3317 3 3249 3250 3319 3 3249 3319 3318 3 3250 3251 3320 3 3250 3320 3319 3 3251 3252 3321 3 3251 3321 3320 3 3252 3253 3322 3 3252 3322 3321 3 3253 3254 3323 3 3253 3323 3322 3 3254 3255 3324 3 3254 3324 3323 3 3255 3256 3325 3 3255 3325 3324 3 3256 3257 3326 3 3256 3326 3325 3 3257 3258 3327 3 3257 3327 3326 3 3258 3259 3328 3 3258 3328 3327 3 3259 3260 3328 3 3329 3328 3260 3 3260 3261 3329 3 3330 3329 3261 3 3261 3262 3330 3 3331 3330 3262 3 3262 3263 3331 3 3332 3331 3263 3 3263 3264 3332 3 3333 3332 3264 3 3264 3265 3333 3 3334 3333 3265 3 3265 3266 3334 3 3335 3334 3266 3 3266 3267 3335 3 3336 3335 3267 3 3267 3268 3336 3 3337 3336 3268 3 3268 3269 3337 3 3338 3337 3269 3 3269 3270 3338 3 3339 3338 3270 3 3270 3271 3339 3 3340 3339 3271 3 3271 3272 3340 3 3341 3340 3272 3 3272 3273 3341 3 3342 3341 3273 3 3273 3274 3342 3 3343 3342 3274 3 3274 3275 3343 3 3344 3343 3275 3 3275 3276 3344 3 3345 3344 3276 3 3276 3277 3345 3 3346 3345 3277 3 3277 3278 3346 3 3347 3346 3278 3 3278 3279 3347 3 3348 3347 3279 3 3279 3280 3348 3 3349 3348 3280 3 3280 3281 3349 3 3350 3349 3281 3 3281 3282 3350 3 3351 3350 3282 3 3282 3283 3351 3 3352 3351 3283 3 3283 3284 3352 3 3353 3352 3284 3 3284 3285 3353 3 3354 3353 3285 3 3285 3286 3354 3 3355 3354 3286 3 3286 3287 3355 3 3356 3355 3287 3 3287 3288 3356 3 3357 3356 3288 3 3288 3289 3357 3 3358 3357 3289 3 3289 3290 3358 3 3359 3358 3290 3 3290 3291 3359 3 3360 3359 3291 3 3291 3292 3360 3 3361 3360 3292 3 3292 3293 3361 3 3362 3361 3293 3 3293 3294 3362 3 3363 3362 3294 3 3294 3295 3364 3 3294 3364 3363 3 3295 3296 3365 3 3295 3365 3364 3 3296 3297 3366 3 3296 3366 3365 3 3297 3298 3367 3 3297 3367 3366 3 3298 3299 3368 3 3298 3368 3367 3 3299 3300 3369 3 3299 3369 3368 3 3300 3301 3370 3 3300 3370 3369 3 3301 3302 3371 3 3301 3371 3370 3 3302 3303 3372 3 3302 3372 3371 3 3303 3304 3373 3 3303 3373 3372 3 3304 3305 3374 3 3304 3374 3373 3 3305 5077 5081 3 3305 5081 3374 3 3306 3307 3376 3 3306 3376 3375 3 3306 3375 5080 3 5084 5080 3375 3 3307 3308 3377 3 3307 3377 3376 3 3308 3309 3378 3 3308 3378 3377 3 3309 3310 3379 3 3309 3379 3378 3 3310 3311 3380 3 3310 3380 3379 3 3311 3312 3381 3 3311 3381 3380 3 3312 3313 3382 3 3312 3382 3381 3 3313 3314 3383 3 3313 3383 3382 3 3314 3315 3384 3 3314 3384 3383 3 3315 3316 3385 3 3315 3385 3384 3 3316 3317 3386 3 3316 3386 3385 3 3317 3318 3387 3 3317 3387 3386 3 3318 3319 3388 3 3318 3388 3387 3 3319 3320 3389 3 3319 3389 3388 3 3320 3321 3390 3 3320 3390 3389 3 3321 3322 3391 3 3321 3391 3390 3 3322 3323 3392 3 3322 3392 3391 3 3323 3324 3393 3 3323 3393 3392 3 3324 3325 3394 3 3324 3394 3393 3 3325 3326 3395 3 3325 3395 3394 3 3326 3327 3396 3 3326 3396 3395 3 3327 3328 3397 3 3327 3397 3396 3 3328 3329 3398 3 3328 3398 3397 3 3329 3330 3399 3 3329 3399 3398 3 3330 3331 3399 3 3400 3399 3331 3 3331 3332 3400 3 3401 3400 3332 3 3332 3333 3401 3 3402 3401 3333 3 3333 3334 3402 3 3403 3402 3334 3 3334 3335 3403 3 3404 3403 3335 3 3335 3336 3404 3 3405 3404 3336 3 3336 3337 3405 3 3406 3405 3337 3 3337 3338 3406 3 3407 3406 3338 3 3338 3339 3407 3 3408 3407 3339 3 3339 3340 3408 3 3409 3408 3340 3 3340 3341 3409 3 3410 3409 3341 3 3341 3342 3410 3 3411 3410 3342 3 3342 3343 3411 3 3412 3411 3343 3 3343 3344 3412 3 3413 3412 3344 3 3344 3345 3413 3 3414 3413 3345 3 3345 3346 3414 3 3415 3414 3346 3 3346 3347 3415 3 3416 3415 3347 3 3347 3348 3416 3 3417 3416 3348 3 3348 3349 3417 3 3418 3417 3349 3 3349 3350 3418 3 3419 3418 3350 3 3350 3351 3419 3 3420 3419 3351 3 3351 3352 3420 3 3421 3420 3352 3 3352 3353 3421 3 3422 3421 3353 3 3353 3354 3422 3 3423 3422 3354 3 3354 3355 3423 3 3424 3423 3355 3 3355 3356 3424 3 3425 3424 3356 3 3356 3357 3425 3 3426 3425 3357 3 3357 3358 3426 3 3427 3426 3358 3 3358 3359 3427 3 3428 3427 3359 3 3359 3360 3428 3 3429 3428 3360 3 3360 3361 3429 3 3430 3429 3361 3 3361 3362 3430 3 3431 3430 3362 3 3362 3363 3431 3 3432 3431 3363 3 3363 3364 3432 3 3433 3432 3364 3 3364 3365 3433 3 3434 3433 3365 3 3365 3366 3434 3 3435 3434 3366 3 3366 3367 3436 3 3366 3436 3435 3 3367 3368 3437 3 3367 3437 3436 3 3368 3369 3438 3 3368 3438 3437 3 3369 3370 3439 3 3369 3439 3438 3 3370 3371 3440 3 3370 3440 3439 3 3371 3372 3441 3 3371 3441 3440 3 3372 3373 3442 3 3372 3442 3441 3 3373 3374 3443 3 3373 3443 3442 3 3374 5081 5085 3 3374 5085 3443 3 3375 3376 3445 3 3375 3445 3444 3 3375 3444 5084 3 5088 5084 3444 3 3376 3377 3446 3 3376 3446 3445 3 3377 3378 3447 3 3377 3447 3446 3 3378 3379 3448 3 3378 3448 3447 3 3379 3380 3449 3 3379 3449 3448 3 3380 3381 3450 3 3380 3450 3449 3 3381 3382 3451 3 3381 3451 3450 3 3382 3383 3452 3 3382 3452 3451 3 3383 3384 3453 3 3383 3453 3452 3 3384 3385 3454 3 3384 3454 3453 3 3385 3386 3455 3 3385 3455 3454 3 3386 3387 3456 3 3386 3456 3455 3 3387 3388 3457 3 3387 3457 3456 3 3388 3389 3458 3 3388 3458 3457 3 3389 3390 3459 3 3389 3459 3458 3 3390 3391 3460 3 3390 3460 3459 3 3391 3392 3461 3 3391 3461 3460 3 3392 3393 3462 3 3392 3462 3461 3 3393 3394 3463 3 3393 3463 3462 3 3394 3395 3464 3 3394 3464 3463 3 3395 3396 3465 3 3395 3465 3464 3 3396 3397 3466 3 3396 3466 3465 3 3397 3398 3467 3 3397 3467 3466 3 3398 3399 3468 3 3398 3468 3467 3 3399 3400 3469 3 3399 3469 3468 3 3400 3401 3470 3 3400 3470 3469 3 3401 3402 3470 3 3471 3470 3402 3 3402 3403 3471 3 3472 3471 3403 3 3403 3404 3472 3 3473 3472 3404 3 3404 3405 3473 3 3474 3473 3405 3 3405 3406 3474 3 3475 3474 3406 3 3406 3407 3475 3 3476 3475 3407 3 3407 3408 3476 3 3477 3476 3408 3 3408 3409 3477 3 3478 3477 3409 3 3409 3410 3478 3 3479 3478 3410 3 3410 3411 3479 3 3480 3479 3411 3 3411 3412 3480 3 3481 3480 3412 3 3412 3413 3481 3 3482 3481 3413 3 3413 3414 3482 3 3483 3482 3414 3 3414 3415 3483 3 3484 3483 3415 3 3415 3416 3484 3 3485 3484 3416 3 3416 3417 3485 3 3486 3485 3417 3 3417 3418 3486 3 3487 3486 3418 3 3418 3419 3487 3 3488 3487 3419 3 3419 3420 3488 3 3489 3488 3420 3 3420 3421 3489 3 3490 3489 3421 3 3421 3422 3490 3 3491 3490 3422 3 3422 3423 3491 3 3492 3491 3423 3 3423 3424 3492 3 3493 3492 3424 3 3424 3425 3493 3 3494 3493 3425 3 3425 3426 3494 3 3495 3494 3426 3 3426 3427 3495 3 3496 3495 3427 3 3427 3428 3496 3 3497 3496 3428 3 3428 3429 3497 3 3498 3497 3429 3 3429 3430 3498 3 3499 3498 3430 3 3430 3431 3499 3 3500 3499 3431 3 3431 3432 3500 3 3501 3500 3432 3 3432 3433 3501 3 3502 3501 3433 3 3433 3434 3502 3 3503 3502 3434 3 3434 3435 3503 3 3504 3503 3435 3 3435 3436 3504 3 3505 3504 3436 3 3436 3437 3505 3 3506 3505 3437 3 3437 3438 3507 3 3437 3507 3506 3 3438 3439 3508 3 3438 3508 3507 3 3439 3440 3509 3 3439 3509 3508 3 3440 3441 3510 3 3440 3510 3509 3 3441 3442 3511 3 3441 3511 3510 3 3442 3443 3512 3 3442 3512 3511 3 3443 5085 3512 3 5089 3512 5085 3 3444 3445 3514 3 3444 3514 3513 3 3444 3513 5088 3 5092 5088 3513 3 3445 3446 3515 3 3445 3515 3514 3 3446 3447 3516 3 3446 3516 3515 3 3447 3448 3517 3 3447 3517 3516 3 3448 3449 3518 3 3448 3518 3517 3 3449 3450 3519 3 3449 3519 3518 3 3450 3451 3520 3 3450 3520 3519 3 3451 3452 3521 3 3451 3521 3520 3 3452 3453 3522 3 3452 3522 3521 3 3453 3454 3523 3 3453 3523 3522 3 3454 3455 3524 3 3454 3524 3523 3 3455 3456 3525 3 3455 3525 3524 3 3456 3457 3526 3 3456 3526 3525 3 3457 3458 3527 3 3457 3527 3526 3 3458 3459 3528 3 3458 3528 3527 3 3459 3460 3529 3 3459 3529 3528 3 3460 3461 3530 3 3460 3530 3529 3 3461 3462 3531 3 3461 3531 3530 3 3462 3463 3532 3 3462 3532 3531 3 3463 3464 3533 3 3463 3533 3532 3 3464 3465 3534 3 3464 3534 3533 3 3465 3466 3535 3 3465 3535 3534 3 3466 3467 3536 3 3466 3536 3535 3 3467 3468 3537 3 3467 3537 3536 3 3468 3469 3538 3 3468 3538 3537 3 3469 3470 3539 3 3469 3539 3538 3 3470 3471 3540 3 3470 3540 3539 3 3471 3472 3541 3 3471 3541 3540 3 3472 3473 3542 3 3472 3542 3541 3 3473 3474 3542 3 3543 3542 3474 3 3474 3475 3543 3 3544 3543 3475 3 3475 3476 3544 3 3545 3544 3476 3 3476 3477 3545 3 3546 3545 3477 3 3477 3478 3546 3 3547 3546 3478 3 3478 3479 3547 3 3548 3547 3479 3 3479 3480 3548 3 3549 3548 3480 3 3480 3481 3549 3 3550 3549 3481 3 3481 3482 3550 3 3551 3550 3482 3 3482 3483 3551 3 3552 3551 3483 3 3483 3484 3552 3 3553 3552 3484 3 3484 3485 3553 3 3554 3553 3485 3 3485 3486 3554 3 3555 3554 3486 3 3486 3487 3555 3 3556 3555 3487 3 3487 3488 3556 3 3557 3556 3488 3 3488 3489 3557 3 3558 3557 3489 3 3489 3490 3558 3 3559 3558 3490 3 3490 3491 3559 3 3560 3559 3491 3 3491 3492 3560 3 3561 3560 3492 3 3492 3493 3561 3 3562 3561 3493 3 3493 3494 3562 3 3563 3562 3494 3 3494 3495 3563 3 3564 3563 3495 3 3495 3496 3564 3 3565 3564 3496 3 3496 3497 3565 3 3566 3565 3497 3 3497 3498 3566 3 3567 3566 3498 3 3498 3499 3567 3 3568 3567 3499 3 3499 3500 3568 3 3569 3568 3500 3 3500 3501 3569 3 3570 3569 3501 3 3501 3502 3570 3 3571 3570 3502 3 3502 3503 3571 3 3572 3571 3503 3 3503 3504 3572 3 3573 3572 3504 3 3504 3505 3573 3 3574 3573 3505 3 3505 3506 3574 3 3575 3574 3506 3 3506 3507 3575 3 3576 3575 3507 3 3507 3508 3576 3 3577 3576 3508 3 3508 3509 3577 3 3578 3577 3509 3 3509 3510 3578 3 3579 3578 3510 3 3510 3511 3580 3 3510 3580 3579 3 3511 3512 3581 3 3511 3581 3580 3 3512 5089 5093 3 3512 5093 3581 3 3513 3514 3583 3 3513 3583 3582 3 3513 3582 5092 3 5096 5092 3582 3 3514 3515 3584 3 3514 3584 3583 3 3515 3516 3585 3 3515 3585 3584 3 3516 3517 3586 3 3516 3586 3585 3 3517 3518 3587 3 3517 3587 3586 3 3518 3519 3588 3 3518 3588 3587 3 3519 3520 3589 3 3519 3589 3588 3 3520 3521 3590 3 3520 3590 3589 3 3521 3522 3591 3 3521 3591 3590 3 3522 3523 3592 3 3522 3592 3591 3 3523 3524 3593 3 3523 3593 3592 3 3524 3525 3594 3 3524 3594 3593 3 3525 3526 3595 3 3525 3595 3594 3 3526 3527 3596 3 3526 3596 3595 3 3527 3528 3597 3 3527 3597 3596 3 3528 3529 3598 3 3528 3598 3597 3 3529 3530 3599 3 3529 3599 3598 3 3530 3531 3600 3 3530 3600 3599 3 3531 3532 3601 3 3531 3601 3600 3 3532 3533 3602 3 3532 3602 3601 3 3533 3534 3603 3 3533 3603 3602 3 3534 3535 3604 3 3534 3604 3603 3 3535 3536 3605 3 3535 3605 3604 3 3536 3537 3606 3 3536 3606 3605 3 3537 3538 3607 3 3537 3607 3606 3 3538 3539 3608 3 3538 3608 3607 3 3539 3540 3609 3 3539 3609 3608 3 3540 3541 3610 3 3540 3610 3609 3 3541 3542 3611 3 3541 3611 3610 3 3542 3543 3612 3 3542 3612 3611 3 3543 3544 3613 3 3543 3613 3612 3 3544 3545 3614 3 3544 3614 3613 3 3545 3546 3615 3 3545 3615 3614 3 3546 3547 3615 3 3616 3615 3547 3 3547 3548 3616 3 3617 3616 3548 3 3548 3549 3617 3 3618 3617 3549 3 3549 3550 3618 3 3619 3618 3550 3 3550 3551 3619 3 3620 3619 3551 3 3551 3552 3620 3 3621 3620 3552 3 3552 3553 3621 3 3622 3621 3553 3 3553 3554 3622 3 3623 3622 3554 3 3554 3555 3623 3 3624 3623 3555 3 3555 3556 3624 3 3625 3624 3556 3 3556 3557 3625 3 3626 3625 3557 3 3557 3558 3626 3 3627 3626 3558 3 3558 3559 3627 3 3628 3627 3559 3 3559 3560 3628 3 3629 3628 3560 3 3560 3561 3629 3 3630 3629 3561 3 3561 3562 3630 3 3631 3630 3562 3 3562 3563 3631 3 3632 3631 3563 3 3563 3564 3632 3 3633 3632 3564 3 3564 3565 3633 3 3634 3633 3565 3 3565 3566 3634 3 3635 3634 3566 3 3566 3567 3635 3 3636 3635 3567 3 3567 3568 3636 3 3637 3636 3568 3 3568 3569 3637 3 3638 3637 3569 3 3569 3570 3638 3 3639 3638 3570 3 3570 3571 3639 3 3640 3639 3571 3 3571 3572 3640 3 3641 3640 3572 3 3572 3573 3641 3 3642 3641 3573 3 3573 3574 3642 3 3643 3642 3574 3 3574 3575 3643 3 3644 3643 3575 3 3575 3576 3644 3 3645 3644 3576 3 3576 3577 3645 3 3646 3645 3577 3 3577 3578 3646 3 3647 3646 3578 3 3578 3579 3647 3 3648 3647 3579 3 3579 3580 3648 3 3649 3648 3580 3 3580 3581 3649 3 3650 3649 3581 3 3581 5093 3650 3 5097 3650 5093 3 3582 3583 3651 3 3652 3651 3583 3 3582 3651 5096 3 5100 5096 3651 3 3583 3584 3653 3 3583 3653 3652 3 3584 3585 3654 3 3584 3654 3653 3 3585 3586 3655 3 3585 3655 3654 3 3586 3587 3656 3 3586 3656 3655 3 3587 3588 3657 3 3587 3657 3656 3 3588 3589 3658 3 3588 3658 3657 3 3589 3590 3659 3 3589 3659 3658 3 3590 3591 3660 3 3590 3660 3659 3 3591 3592 3661 3 3591 3661 3660 3 3592 3593 3662 3 3592 3662 3661 3 3593 3594 3663 3 3593 3663 3662 3 3594 3595 3664 3 3594 3664 3663 3 3595 3596 3665 3 3595 3665 3664 3 3596 3597 3666 3 3596 3666 3665 3 3597 3598 3667 3 3597 3667 3666 3 3598 3599 3668 3 3598 3668 3667 3 3599 3600 3669 3 3599 3669 3668 3 3600 3601 3670 3 3600 3670 3669 3 3601 3602 3671 3 3601 3671 3670 3 3602 3603 3672 3 3602 3672 3671 3 3603 3604 3673 3 3603 3673 3672 3 3604 3605 3674 3 3604 3674 3673 3 3605 3606 3675 3 3605 3675 3674 3 3606 3607 3676 3 3606 3676 3675 3 3607 3608 3677 3 3607 3677 3676 3 3608 3609 3678 3 3608 3678 3677 3 3609 3610 3679 3 3609 3679 3678 3 3610 3611 3680 3 3610 3680 3679 3 3611 3612 3681 3 3611 3681 3680 3 3612 3613 3682 3 3612 3682 3681 3 3613 3614 3683 3 3613 3683 3682 3 3614 3615 3684 3 3614 3684 3683 3 3615 3616 3685 3 3615 3685 3684 3 3616 3617 3686 3 3616 3686 3685 3 3617 3618 3687 3 3617 3687 3686 3 3618 3619 3688 3 3618 3688 3687 3 3619 3620 3689 3 3619 3689 3688 3 3620 3621 3689 3 3690 3689 3621 3 3621 3622 3690 3 3691 3690 3622 3 3622 3623 3691 3 3692 3691 3623 3 3623 3624 3692 3 3693 3692 3624 3 3624 3625 3693 3 3694 3693 3625 3 3625 3626 3694 3 3695 3694 3626 3 3626 3627 3695 3 3696 3695 3627 3 3627 3628 3696 3 3697 3696 3628 3 3628 3629 3697 3 3698 3697 3629 3 3629 3630 3698 3 3699 3698 3630 3 3630 3631 3699 3 3700 3699 3631 3 3631 3632 3700 3 3701 3700 3632 3 3632 3633 3701 3 3702 3701 3633 3 3633 3634 3702 3 3703 3702 3634 3 3634 3635 3703 3 3704 3703 3635 3 3635 3636 3704 3 3705 3704 3636 3 3636 3637 3705 3 3706 3705 3637 3 3637 3638 3706 3 3707 3706 3638 3 3638 3639 3707 3 3708 3707 3639 3 3639 3640 3708 3 3709 3708 3640 3 3640 3641 3709 3 3710 3709 3641 3 3641 3642 3710 3 3711 3710 3642 3 3642 3643 3711 3 3712 3711 3643 3 3643 3644 3712 3 3713 3712 3644 3 3644 3645 3713 3 3714 3713 3645 3 3645 3646 3714 3 3715 3714 3646 3 3646 3647 3715 3 3716 3715 3647 3 3647 3648 3716 3 3717 3716 3648 3 3648 3649 3717 3 3718 3717 3649 3 3649 3650 3718 3 3719 3718 3650 3 3650 5097 5101 3 3650 5101 3719 3 3651 3652 3720 3 3721 3720 3652 3 3651 3720 5104 3 3651 5104 5100 3 3652 3653 3721 3 3722 3721 3653 3 3653 3654 3722 3 3723 3722 3654 3 3654 3655 3723 3 3724 3723 3655 3 3655 3656 3724 3 3725 3724 3656 3 3656 3657 3725 3 3726 3725 3657 3 3657 3658 3727 3 3657 3727 3726 3 3658 3659 3728 3 3658 3728 3727 3 3659 3660 3729 3 3659 3729 3728 3 3660 3661 3730 3 3660 3730 3729 3 3661 3662 3731 3 3661 3731 3730 3 3662 3663 3732 3 3662 3732 3731 3 3663 3664 3733 3 3663 3733 3732 3 3664 3665 3734 3 3664 3734 3733 3 3665 3666 3735 3 3665 3735 3734 3 3666 3667 3736 3 3666 3736 3735 3 3667 3668 3737 3 3667 3737 3736 3 3668 3669 3738 3 3668 3738 3737 3 3669 3670 3739 3 3669 3739 3738 3 3670 3671 3740 3 3670 3740 3739 3 3671 3672 3741 3 3671 3741 3740 3 3672 3673 3742 3 3672 3742 3741 3 3673 3674 3743 3 3673 3743 3742 3 3674 3675 3744 3 3674 3744 3743 3 3675 3676 3745 3 3675 3745 3744 3 3676 3677 3746 3 3676 3746 3745 3 3677 3678 3747 3 3677 3747 3746 3 3678 3679 3748 3 3678 3748 3747 3 3679 3680 3749 3 3679 3749 3748 3 3680 3681 3750 3 3680 3750 3749 3 3681 3682 3751 3 3681 3751 3750 3 3682 3683 3752 3 3682 3752 3751 3 3683 3684 3753 3 3683 3753 3752 3 3684 3685 3754 3 3684 3754 3753 3 3685 3686 3755 3 3685 3755 3754 3 3686 3687 3756 3 3686 3756 3755 3 3687 3688 3757 3 3687 3757 3756 3 3688 3689 3758 3 3688 3758 3757 3 3689 3690 3759 3 3689 3759 3758 3 3690 3691 3760 3 3690 3760 3759 3 3691 3692 3761 3 3691 3761 3760 3 3692 3693 3762 3 3692 3762 3761 3 3693 3694 3763 3 3693 3763 3762 3 3694 3695 3764 3 3694 3764 3763 3 3695 3696 3764 3 3765 3764 3696 3 3696 3697 3765 3 3766 3765 3697 3 3697 3698 3766 3 3767 3766 3698 3 3698 3699 3767 3 3768 3767 3699 3 3699 3700 3768 3 3769 3768 3700 3 3700 3701 3769 3 3770 3769 3701 3 3701 3702 3770 3 3771 3770 3702 3 3702 3703 3771 3 3772 3771 3703 3 3703 3704 3772 3 3773 3772 3704 3 3704 3705 3773 3 3774 3773 3705 3 3705 3706 3774 3 3775 3774 3706 3 3706 3707 3775 3 3776 3775 3707 3 3707 3708 3776 3 3777 3776 3708 3 3708 3709 3777 3 3778 3777 3709 3 3709 3710 3778 3 3779 3778 3710 3 3710 3711 3779 3 3780 3779 3711 3 3711 3712 3780 3 3781 3780 3712 3 3712 3713 3781 3 3782 3781 3713 3 3713 3714 3782 3 3783 3782 3714 3 3714 3715 3783 3 3784 3783 3715 3 3715 3716 3784 3 3785 3784 3716 3 3716 3717 3785 3 3786 3785 3717 3 3717 3718 3786 3 3787 3786 3718 3 3718 3719 3787 3 3788 3787 3719 3 3719 5101 3788 3 5105 3788 5101 3 3720 3721 3789 3 3790 3789 3721 3 3720 3789 5108 3 3720 5108 5104 3 3721 3722 3790 3 3791 3790 3722 3 3722 3723 3791 3 3792 3791 3723 3 3723 3724 3792 3 3793 3792 3724 3 3724 3725 3793 3 3794 3793 3725 3 3725 3726 3794 3 3795 3794 3726 3 3726 3727 3795 3 3796 3795 3727 3 3727 3728 3796 3 3797 3796 3728 3 3728 3729 3797 3 3798 3797 3729 3 3729 3730 3798 3 3799 3798 3730 3 3730 3731 3799 3 3800 3799 3731 3 3731 3732 3800 3 3801 3800 3732 3 3732 3733 3802 3 3732 3802 3801 3 3733 3734 3803 3 3733 3803 3802 3 3734 3735 3804 3 3734 3804 3803 3 3735 3736 3805 3 3735 3805 3804 3 3736 3737 3806 3 3736 3806 3805 3 3737 3738 3807 3 3737 3807 3806 3 3738 3739 3808 3 3738 3808 3807 3 3739 3740 3809 3 3739 3809 3808 3 3740 3741 3810 3 3740 3810 3809 3 3741 3742 3811 3 3741 3811 3810 3 3742 3743 3812 3 3742 3812 3811 3 3743 3744 3813 3 3743 3813 3812 3 3744 3745 3814 3 3744 3814 3813 3 3745 3746 3815 3 3745 3815 3814 3 3746 3747 3816 3 3746 3816 3815 3 3747 3748 3817 3 3747 3817 3816 3 3748 3749 3818 3 3748 3818 3817 3 3749 3750 3819 3 3749 3819 3818 3 3750 3751 3820 3 3750 3820 3819 3 3751 3752 3821 3 3751 3821 3820 3 3752 3753 3822 3 3752 3822 3821 3 3753 3754 3823 3 3753 3823 3822 3 3754 3755 3824 3 3754 3824 3823 3 3755 3756 3825 3 3755 3825 3824 3 3756 3757 3826 3 3756 3826 3825 3 3757 3758 3827 3 3757 3827 3826 3 3758 3759 3828 3 3758 3828 3827 3 3759 3760 3829 3 3759 3829 3828 3 3760 3761 3830 3 3760 3830 3829 3 3761 3762 3831 3 3761 3831 3830 3 3762 3763 3832 3 3762 3832 3831 3 3763 3764 3833 3 3763 3833 3832 3 3764 3765 3834 3 3764 3834 3833 3 3765 3766 3835 3 3765 3835 3834 3 3766 3767 3836 3 3766 3836 3835 3 3767 3768 3837 3 3767 3837 3836 3 3768 3769 3838 3 3768 3838 3837 3 3769 3770 3839 3 3769 3839 3838 3 3770 3771 3839 3 3840 3839 3771 3 3771 3772 3840 3 3841 3840 3772 3 3772 3773 3841 3 3842 3841 3773 3 3773 3774 3842 3 3843 3842 3774 3 3774 3775 3843 3 3844 3843 3775 3 3775 3776 3844 3 3845 3844 3776 3 3776 3777 3845 3 3846 3845 3777 3 3777 3778 3846 3 3847 3846 3778 3 3778 3779 3847 3 3848 3847 3779 3 3779 3780 3848 3 3849 3848 3780 3 3780 3781 3849 3 3850 3849 3781 3 3781 3782 3850 3 3851 3850 3782 3 3782 3783 3851 3 3852 3851 3783 3 3783 3784 3852 3 3853 3852 3784 3 3784 3785 3853 3 3854 3853 3785 3 3785 3786 3854 3 3855 3854 3786 3 3786 3787 3855 3 3856 3855 3787 3 3787 3788 3856 3 3857 3856 3788 3 3788 5105 5109 3 3788 5109 3857 3 3789 3790 3858 3 3859 3858 3790 3 3789 3858 5112 3 3789 5112 5108 3 3790 3791 3859 3 3860 3859 3791 3 3791 3792 3860 3 3861 3860 3792 3 3792 3793 3861 3 3862 3861 3793 3 3793 3794 3862 3 3863 3862 3794 3 3794 3795 3863 3 3864 3863 3795 3 3795 3796 3864 3 3865 3864 3796 3 3796 3797 3865 3 3866 3865 3797 3 3797 3798 3866 3 3867 3866 3798 3 3798 3799 3867 3 3868 3867 3799 3 3799 3800 3868 3 3869 3868 3800 3 3800 3801 3869 3 3870 3869 3801 3 3801 3802 3870 3 3871 3870 3802 3 3802 3803 3871 3 3872 3871 3803 3 3803 3804 3872 3 3873 3872 3804 3 3804 3805 3873 3 3874 3873 3805 3 3805 3806 3874 3 3875 3874 3806 3 3806 3807 3875 3 3876 3875 3807 3 3807 3808 3876 3 3877 3876 3808 3 3808 3809 3878 3 3808 3878 3877 3 3809 3810 3879 3 3809 3879 3878 3 3810 3811 3880 3 3810 3880 3879 3 3811 3812 3881 3 3811 3881 3880 3 3812 3813 3882 3 3812 3882 3881 3 3813 3814 3883 3 3813 3883 3882 3 3814 3815 3884 3 3814 3884 3883 3 3815 3816 3885 3 3815 3885 3884 3 3816 3817 3886 3 3816 3886 3885 3 3817 3818 3887 3 3817 3887 3886 3 3818 3819 3888 3 3818 3888 3887 3 3819 3820 3889 3 3819 3889 3888 3 3820 3821 3890 3 3820 3890 3889 3 3821 3822 3891 3 3821 3891 3890 3 3822 3823 3892 3 3822 3892 3891 3 3823 3824 3893 3 3823 3893 3892 3 3824 3825 3894 3 3824 3894 3893 3 3825 3826 3895 3 3825 3895 3894 3 3826 3827 3896 3 3826 3896 3895 3 3827 3828 3897 3 3827 3897 3896 3 3828 3829 3898 3 3828 3898 3897 3 3829 3830 3899 3 3829 3899 3898 3 3830 3831 3900 3 3830 3900 3899 3 3831 3832 3901 3 3831 3901 3900 3 3832 3833 3902 3 3832 3902 3901 3 3833 3834 3903 3 3833 3903 3902 3 3834 3835 3904 3 3834 3904 3903 3 3835 3836 3905 3 3835 3905 3904 3 3836 3837 3906 3 3836 3906 3905 3 3837 3838 3907 3 3837 3907 3906 3 3838 3839 3908 3 3838 3908 3907 3 3839 3840 3909 3 3839 3909 3908 3 3840 3841 3910 3 3840 3910 3909 3 3841 3842 3911 3 3841 3911 3910 3 3842 3843 3912 3 3842 3912 3911 3 3843 3844 3913 3 3843 3913 3912 3 3844 3845 3914 3 3844 3914 3913 3 3845 3846 3915 3 3845 3915 3914 3 3846 3847 3915 3 3916 3915 3847 3 3847 3848 3916 3 3917 3916 3848 3 3848 3849 3917 3 3918 3917 3849 3 3849 3850 3918 3 3919 3918 3850 3 3850 3851 3919 3 3920 3919 3851 3 3851 3852 3920 3 3921 3920 3852 3 3852 3853 3921 3 3922 3921 3853 3 3853 3854 3922 3 3923 3922 3854 3 3854 3855 3923 3 3924 3923 3855 3 3855 3856 3924 3 3925 3924 3856 3 3856 3857 3925 3 3926 3925 3857 3 3857 5109 5113 3 3857 5113 3926 3 3858 3859 3927 3 3928 3927 3859 3 3858 3927 5116 3 3858 5116 5112 3 3859 3860 3928 3 3929 3928 3860 3 3860 3861 3929 3 3930 3929 3861 3 3861 3862 3930 3 3931 3930 3862 3 3862 3863 3931 3 3932 3931 3863 3 3863 3864 3932 3 3933 3932 3864 3 3864 3865 3933 3 3934 3933 3865 3 3865 3866 3934 3 3935 3934 3866 3 3866 3867 3935 3 3936 3935 3867 3 3867 3868 3936 3 3937 3936 3868 3 3868 3869 3937 3 3938 3937 3869 3 3869 3870 3938 3 3939 3938 3870 3 3870 3871 3939 3 3940 3939 3871 3 3871 3872 3940 3 3941 3940 3872 3 3872 3873 3941 3 3942 3941 3873 3 3873 3874 3942 3 3943 3942 3874 3 3874 3875 3943 3 3944 3943 3875 3 3875 3876 3944 3 3945 3944 3876 3 3876 3877 3945 3 3946 3945 3877 3 3877 3878 3946 3 3947 3946 3878 3 3878 3879 3947 3 3948 3947 3879 3 3879 3880 3948 3 3949 3948 3880 3 3880 3881 3949 3 3950 3949 3881 3 3881 3882 3950 3 3951 3950 3882 3 3882 3883 3951 3 3952 3951 3883 3 3883 3884 3952 3 3953 3952 3884 3 3884 3885 3954 3 3884 3954 3953 3 3885 3886 3955 3 3885 3955 3954 3 3886 3887 3956 3 3886 3956 3955 3 3887 3888 3957 3 3887 3957 3956 3 3888 3889 3958 3 3888 3958 3957 3 3889 3890 3959 3 3889 3959 3958 3 3890 3891 3960 3 3890 3960 3959 3 3891 3892 3961 3 3891 3961 3960 3 3892 3893 3962 3 3892 3962 3961 3 3893 3894 3963 3 3893 3963 3962 3 3894 3895 3964 3 3894 3964 3963 3 3895 3896 3965 3 3895 3965 3964 3 3896 3897 3966 3 3896 3966 3965 3 3897 3898 3967 3 3897 3967 3966 3 3898 3899 3968 3 3898 3968 3967 3 3899 3900 3969 3 3899 3969 3968 3 3900 3901 3970 3 3900 3970 3969 3 3901 3902 3971 3 3901 3971 3970 3 3902 3903 3972 3 3902 3972 3971 3 3903 3904 3973 3 3903 3973 3972 3 3904 3905 3974 3 3904 3974 3973 3 3905 3906 3975 3 3905 3975 3974 3 3906 3907 3976 3 3906 3976 3975 3 3907 3908 3977 3 3907 3977 3976 3 3908 3909 3978 3 3908 3978 3977 3 3909 3910 3979 3 3909 3979 3978 3 3910 3911 3980 3 3910 3980 3979 3 3911 3912 3981 3 3911 3981 3980 3 3912 3913 3982 3 3912 3982 3981 3 3913 3914 3983 3 3913 3983 3982 3 3914 3915 3984 3 3914 3984 3983 3 3915 3916 3985 3 3915 3985 3984 3 3916 3917 3986 3 3916 3986 3985 3 3917 3918 3987 3 3917 3987 3986 3 3918 3919 3988 3 3918 3988 3987 3 3919 3920 3989 3 3919 3989 3988 3 3920 3921 3990 3 3920 3990 3989 3 3921 3922 3991 3 3921 3991 3990 3 3922 3923 3991 3 3992 3991 3923 3 3923 3924 3992 3 3993 3992 3924 3 3924 3925 3993 3 3994 3993 3925 3 3925 3926 3994 3 3995 3994 3926 3 3926 5113 3995 3 5117 3995 5113 3 3927 3928 3996 3 3997 3996 3928 3 3927 3996 5120 3 3927 5120 5116 3 3928 3929 3997 3 3998 3997 3929 3 3929 3930 3998 3 3999 3998 3930 3 3930 3931 3999 3 4000 3999 3931 3 3931 3932 4000 3 4001 4000 3932 3 3932 3933 4001 3 4002 4001 3933 3 3933 3934 4002 3 4003 4002 3934 3 3934 3935 4003 3 4004 4003 3935 3 3935 3936 4004 3 4005 4004 3936 3 3936 3937 4005 3 4006 4005 3937 3 3937 3938 4006 3 4007 4006 3938 3 3938 3939 4007 3 4008 4007 3939 3 3939 3940 4008 3 4009 4008 3940 3 3940 3941 4009 3 4010 4009 3941 3 3941 3942 4010 3 4011 4010 3942 3 3942 3943 4011 3 4012 4011 3943 3 3943 3944 4012 3 4013 4012 3944 3 3944 3945 4013 3 4014 4013 3945 3 3945 3946 4014 3 4015 4014 3946 3 3946 3947 4015 3 4016 4015 3947 3 3947 3948 4016 3 4017 4016 3948 3 3948 3949 4017 3 4018 4017 3949 3 3949 3950 4018 3 4019 4018 3950 3 3950 3951 4019 3 4020 4019 3951 3 3951 3952 4020 3 4021 4020 3952 3 3952 3953 4021 3 4022 4021 3953 3 3953 3954 4022 3 4023 4022 3954 3 3954 3955 4023 3 4024 4023 3955 3 3955 3956 4024 3 4025 4024 3956 3 3956 3957 4025 3 4026 4025 3957 3 3957 3958 4026 3 4027 4026 3958 3 3958 3959 4027 3 4028 4027 3959 3 3959 3960 4028 3 4029 4028 3960 3 3960 3961 4029 3 4030 4029 3961 3 3961 3962 4031 3 3961 4031 4030 3 3962 3963 4032 3 3962 4032 4031 3 3963 3964 4033 3 3963 4033 4032 3 3964 3965 4034 3 3964 4034 4033 3 3965 3966 4035 3 3965 4035 4034 3 3966 3967 4036 3 3966 4036 4035 3 3967 3968 4037 3 3967 4037 4036 3 3968 3969 4038 3 3968 4038 4037 3 3969 3970 4039 3 3969 4039 4038 3 3970 3971 4040 3 3970 4040 4039 3 3971 3972 4041 3 3971 4041 4040 3 3972 3973 4042 3 3972 4042 4041 3 3973 3974 4043 3 3973 4043 4042 3 3974 3975 4044 3 3974 4044 4043 3 3975 3976 4045 3 3975 4045 4044 3 3976 3977 4046 3 3976 4046 4045 3 3977 3978 4047 3 3977 4047 4046 3 3978 3979 4048 3 3978 4048 4047 3 3979 3980 4049 3 3979 4049 4048 3 3980 3981 4050 3 3980 4050 4049 3 3981 3982 4051 3 3981 4051 4050 3 3982 3983 4052 3 3982 4052 4051 3 3983 3984 4053 3 3983 4053 4052 3 3984 3985 4054 3 3984 4054 4053 3 3985 3986 4055 3 3985 4055 4054 3 3986 3987 4056 3 3986 4056 4055 3 3987 3988 4057 3 3987 4057 4056 3 3988 3989 4058 3 3988 4058 4057 3 3989 3990 4059 3 3989 4059 4058 3 3990 3991 4060 3 3990 4060 4059 3 3991 3992 4061 3 3991 4061 4060 3 3992 3993 4062 3 3992 4062 4061 3 3993 3994 4063 3 3993 4063 4062 3 3994 3995 4064 3 3994 4064 4063 3 3995 5117 5121 3 3995 5121 4064 3 3996 3997 4066 3 3996 4066 4065 3 3996 4065 5120 3 5124 5120 4065 3 3997 3998 4067 3 3997 4067 4066 3 3998 3999 4068 3 3998 4068 4067 3 3999 4000 4069 3 3999 4069 4068 3 4000 4001 4069 3 4070 4069 4001 3 4001 4002 4070 3 4071 4070 4002 3 4002 4003 4071 3 4072 4071 4003 3 4003 4004 4072 3 4073 4072 4004 3 4004 4005 4073 3 4074 4073 4005 3 4005 4006 4074 3 4075 4074 4006 3 4006 4007 4075 3 4076 4075 4007 3 4007 4008 4076 3 4077 4076 4008 3 4008 4009 4077 3 4078 4077 4009 3 4009 4010 4078 3 4079 4078 4010 3 4010 4011 4079 3 4080 4079 4011 3 4011 4012 4080 3 4081 4080 4012 3 4012 4013 4081 3 4082 4081 4013 3 4013 4014 4082 3 4083 4082 4014 3 4014 4015 4083 3 4084 4083 4015 3 4015 4016 4084 3 4085 4084 4016 3 4016 4017 4085 3 4086 4085 4017 3 4017 4018 4086 3 4087 4086 4018 3 4018 4019 4087 3 4088 4087 4019 3 4019 4020 4088 3 4089 4088 4020 3 4020 4021 4089 3 4090 4089 4021 3 4021 4022 4090 3 4091 4090 4022 3 4022 4023 4091 3 4092 4091 4023 3 4023 4024 4092 3 4093 4092 4024 3 4024 4025 4093 3 4094 4093 4025 3 4025 4026 4094 3 4095 4094 4026 3 4026 4027 4095 3 4096 4095 4027 3 4027 4028 4096 3 4097 4096 4028 3 4028 4029 4097 3 4098 4097 4029 3 4029 4030 4098 3 4099 4098 4030 3 4030 4031 4099 3 4100 4099 4031 3 4031 4032 4100 3 4101 4100 4032 3 4032 4033 4101 3 4102 4101 4033 3 4033 4034 4102 3 4103 4102 4034 3 4034 4035 4103 3 4104 4103 4035 3 4035 4036 4104 3 4105 4104 4036 3 4036 4037 4105 3 4106 4105 4037 3 4037 4038 4106 3 4107 4106 4038 3 4038 4039 4107 3 4108 4107 4039 3 4039 4040 4109 3 4039 4109 4108 3 4040 4041 4110 3 4040 4110 4109 3 4041 4042 4111 3 4041 4111 4110 3 4042 4043 4112 3 4042 4112 4111 3 4043 4044 4113 3 4043 4113 4112 3 4044 4045 4114 3 4044 4114 4113 3 4045 4046 4115 3 4045 4115 4114 3 4046 4047 4116 3 4046 4116 4115 3 4047 4048 4117 3 4047 4117 4116 3 4048 4049 4118 3 4048 4118 4117 3 4049 4050 4119 3 4049 4119 4118 3 4050 4051 4120 3 4050 4120 4119 3 4051 4052 4121 3 4051 4121 4120 3 4052 4053 4122 3 4052 4122 4121 3 4053 4054 4123 3 4053 4123 4122 3 4054 4055 4124 3 4054 4124 4123 3 4055 4056 4125 3 4055 4125 4124 3 4056 4057 4126 3 4056 4126 4125 3 4057 4058 4127 3 4057 4127 4126 3 4058 4059 4128 3 4058 4128 4127 3 4059 4060 4129 3 4059 4129 4128 3 4060 4061 4130 3 4060 4130 4129 3 4061 4062 4131 3 4061 4131 4130 3 4062 4063 4132 3 4062 4132 4131 3 4063 4064 4133 3 4063 4133 4132 3 4064 5121 4133 3 5125 4133 5121 3 4065 4066 4135 3 4065 4135 4134 3 4065 4134 5124 3 5128 5124 4134 3 4066 4067 4136 3 4066 4136 4135 3 4067 4068 4137 3 4067 4137 4136 3 4068 4069 4138 3 4068 4138 4137 3 4069 4070 4139 3 4069 4139 4138 3 4070 4071 4140 3 4070 4140 4139 3 4071 4072 4141 3 4071 4141 4140 3 4072 4073 4142 3 4072 4142 4141 3 4073 4074 4143 3 4073 4143 4142 3 4074 4075 4144 3 4074 4144 4143 3 4075 4076 4145 3 4075 4145 4144 3 4076 4077 4146 3 4076 4146 4145 3 4077 4078 4147 3 4077 4147 4146 3 4078 4079 4147 3 4148 4147 4079 3 4079 4080 4148 3 4149 4148 4080 3 4080 4081 4149 3 4150 4149 4081 3 4081 4082 4150 3 4151 4150 4082 3 4082 4083 4151 3 4152 4151 4083 3 4083 4084 4152 3 4153 4152 4084 3 4084 4085 4153 3 4154 4153 4085 3 4085 4086 4154 3 4155 4154 4086 3 4086 4087 4155 3 4156 4155 4087 3 4087 4088 4156 3 4157 4156 4088 3 4088 4089 4157 3 4158 4157 4089 3 4089 4090 4158 3 4159 4158 4090 3 4090 4091 4159 3 4160 4159 4091 3 4091 4092 4160 3 4161 4160 4092 3 4092 4093 4161 3 4162 4161 4093 3 4093 4094 4162 3 4163 4162 4094 3 4094 4095 4163 3 4164 4163 4095 3 4095 4096 4164 3 4165 4164 4096 3 4096 4097 4165 3 4166 4165 4097 3 4097 4098 4166 3 4167 4166 4098 3 4098 4099 4167 3 4168 4167 4099 3 4099 4100 4168 3 4169 4168 4100 3 4100 4101 4169 3 4170 4169 4101 3 4101 4102 4170 3 4171 4170 4102 3 4102 4103 4171 3 4172 4171 4103 3 4103 4104 4172 3 4173 4172 4104 3 4104 4105 4173 3 4174 4173 4105 3 4105 4106 4174 3 4175 4174 4106 3 4106 4107 4175 3 4176 4175 4107 3 4107 4108 4176 3 4177 4176 4108 3 4108 4109 4177 3 4178 4177 4109 3 4109 4110 4178 3 4179 4178 4110 3 4110 4111 4179 3 4180 4179 4111 3 4111 4112 4180 3 4181 4180 4112 3 4112 4113 4181 3 4182 4181 4113 3 4113 4114 4182 3 4183 4182 4114 3 4114 4115 4183 3 4184 4183 4115 3 4115 4116 4184 3 4185 4184 4116 3 4116 4117 4185 3 4186 4185 4117 3 4117 4118 4186 3 4187 4186 4118 3 4118 4119 4188 3 4118 4188 4187 3 4119 4120 4189 3 4119 4189 4188 3 4120 4121 4190 3 4120 4190 4189 3 4121 4122 4191 3 4121 4191 4190 3 4122 4123 4192 3 4122 4192 4191 3 4123 4124 4193 3 4123 4193 4192 3 4124 4125 4194 3 4124 4194 4193 3 4125 4126 4195 3 4125 4195 4194 3 4126 4127 4196 3 4126 4196 4195 3 4127 4128 4197 3 4127 4197 4196 3 4128 4129 4198 3 4128 4198 4197 3 4129 4130 4199 3 4129 4199 4198 3 4130 4131 4200 3 4130 4200 4199 3 4131 4132 4201 3 4131 4201 4200 3 4132 4133 4202 3 4132 4202 4201 3 4133 5125 5129 3 4133 5129 4202 3 4134 4135 4204 3 4134 4204 4203 3 4134 4203 5128 3 5132 5128 4203 3 4135 4136 4205 3 4135 4205 4204 3 4136 4137 4206 3 4136 4206 4205 3 4137 4138 4207 3 4137 4207 4206 3 4138 4139 4208 3 4138 4208 4207 3 4139 4140 4209 3 4139 4209 4208 3 4140 4141 4210 3 4140 4210 4209 3 4141 4142 4211 3 4141 4211 4210 3 4142 4143 4212 3 4142 4212 4211 3 4143 4144 4213 3 4143 4213 4212 3 4144 4145 4214 3 4144 4214 4213 3 4145 4146 4215 3 4145 4215 4214 3 4146 4147 4216 3 4146 4216 4215 3 4147 4148 4217 3 4147 4217 4216 3 4148 4149 4218 3 4148 4218 4217 3 4149 4150 4219 3 4149 4219 4218 3 4150 4151 4220 3 4150 4220 4219 3 4151 4152 4221 3 4151 4221 4220 3 4152 4153 4222 3 4152 4222 4221 3 4153 4154 4223 3 4153 4223 4222 3 4154 4155 4224 3 4154 4224 4223 3 4155 4156 4225 3 4155 4225 4224 3 4156 4157 4226 3 4156 4226 4225 3 4157 4158 4226 3 4227 4226 4158 3 4158 4159 4227 3 4228 4227 4159 3 4159 4160 4228 3 4229 4228 4160 3 4160 4161 4229 3 4230 4229 4161 3 4161 4162 4230 3 4231 4230 4162 3 4162 4163 4231 3 4232 4231 4163 3 4163 4164 4232 3 4233 4232 4164 3 4164 4165 4233 3 4234 4233 4165 3 4165 4166 4234 3 4235 4234 4166 3 4166 4167 4235 3 4236 4235 4167 3 4167 4168 4236 3 4237 4236 4168 3 4168 4169 4237 3 4238 4237 4169 3 4169 4170 4238 3 4239 4238 4170 3 4170 4171 4239 3 4240 4239 4171 3 4171 4172 4240 3 4241 4240 4172 3 4172 4173 4241 3 4242 4241 4173 3 4173 4174 4242 3 4243 4242 4174 3 4174 4175 4243 3 4244 4243 4175 3 4175 4176 4244 3 4245 4244 4176 3 4176 4177 4245 3 4246 4245 4177 3 4177 4178 4246 3 4247 4246 4178 3 4178 4179 4247 3 4248 4247 4179 3 4179 4180 4248 3 4249 4248 4180 3 4180 4181 4249 3 4250 4249 4181 3 4181 4182 4250 3 4251 4250 4182 3 4182 4183 4251 3 4252 4251 4183 3 4183 4184 4252 3 4253 4252 4184 3 4184 4185 4253 3 4254 4253 4185 3 4185 4186 4254 3 4255 4254 4186 3 4186 4187 4255 3 4256 4255 4187 3 4187 4188 4256 3 4257 4256 4188 3 4188 4189 4257 3 4258 4257 4189 3 4189 4190 4258 3 4259 4258 4190 3 4190 4191 4259 3 4260 4259 4191 3 4191 4192 4260 3 4261 4260 4192 3 4192 4193 4261 3 4262 4261 4193 3 4193 4194 4262 3 4263 4262 4194 3 4194 4195 4263 3 4264 4263 4195 3 4195 4196 4264 3 4265 4264 4196 3 4196 4197 4265 3 4266 4265 4197 3 4197 4198 4267 3 4197 4267 4266 3 4198 4199 4268 3 4198 4268 4267 3 4199 4200 4269 3 4199 4269 4268 3 4200 4201 4270 3 4200 4270 4269 3 4201 4202 4271 3 4201 4271 4270 3 4202 5129 5133 3 4202 5133 4271 3 4203 4204 4273 3 4203 4273 4272 3 4203 4272 5132 3 5136 5132 4272 3 4204 4205 4274 3 4204 4274 4273 3 4205 4206 4275 3 4205 4275 4274 3 4206 4207 4276 3 4206 4276 4275 3 4207 4208 4277 3 4207 4277 4276 3 4208 4209 4278 3 4208 4278 4277 3 4209 4210 4279 3 4209 4279 4278 3 4210 4211 4280 3 4210 4280 4279 3 4211 4212 4281 3 4211 4281 4280 3 4212 4213 4282 3 4212 4282 4281 3 4213 4214 4283 3 4213 4283 4282 3 4214 4215 4284 3 4214 4284 4283 3 4215 4216 4285 3 4215 4285 4284 3 4216 4217 4286 3 4216 4286 4285 3 4217 4218 4287 3 4217 4287 4286 3 4218 4219 4288 3 4218 4288 4287 3 4219 4220 4289 3 4219 4289 4288 3 4220 4221 4290 3 4220 4290 4289 3 4221 4222 4291 3 4221 4291 4290 3 4222 4223 4292 3 4222 4292 4291 3 4223 4224 4293 3 4223 4293 4292 3 4224 4225 4294 3 4224 4294 4293 3 4225 4226 4295 3 4225 4295 4294 3 4226 4227 4296 3 4226 4296 4295 3 4227 4228 4297 3 4227 4297 4296 3 4228 4229 4298 3 4228 4298 4297 3 4229 4230 4299 3 4229 4299 4298 3 4230 4231 4300 3 4230 4300 4299 3 4231 4232 4301 3 4231 4301 4300 3 4232 4233 4302 3 4232 4302 4301 3 4233 4234 4303 3 4233 4303 4302 3 4234 4235 4304 3 4234 4304 4303 3 4235 4236 4305 3 4235 4305 4304 3 4236 4237 4306 3 4236 4306 4305 3 4237 4238 4306 3 4307 4306 4238 3 4238 4239 4307 3 4308 4307 4239 3 4239 4240 4308 3 4309 4308 4240 3 4240 4241 4309 3 4310 4309 4241 3 4241 4242 4310 3 4311 4310 4242 3 4242 4243 4311 3 4312 4311 4243 3 4243 4244 4312 3 4313 4312 4244 3 4244 4245 4313 3 4314 4313 4245 3 4245 4246 4314 3 4315 4314 4246 3 4246 4247 4315 3 4316 4315 4247 3 4247 4248 4316 3 4317 4316 4248 3 4248 4249 4317 3 4318 4317 4249 3 4249 4250 4318 3 4319 4318 4250 3 4250 4251 4319 3 4320 4319 4251 3 4251 4252 4320 3 4321 4320 4252 3 4252 4253 4321 3 4322 4321 4253 3 4253 4254 4322 3 4323 4322 4254 3 4254 4255 4323 3 4324 4323 4255 3 4255 4256 4324 3 4325 4324 4256 3 4256 4257 4325 3 4326 4325 4257 3 4257 4258 4326 3 4327 4326 4258 3 4258 4259 4327 3 4328 4327 4259 3 4259 4260 4328 3 4329 4328 4260 3 4260 4261 4329 3 4330 4329 4261 3 4261 4262 4330 3 4331 4330 4262 3 4262 4263 4331 3 4332 4331 4263 3 4263 4264 4332 3 4333 4332 4264 3 4264 4265 4333 3 4334 4333 4265 3 4265 4266 4334 3 4335 4334 4266 3 4266 4267 4335 3 4336 4335 4267 3 4267 4268 4336 3 4337 4336 4268 3 4268 4269 4337 3 4338 4337 4269 3 4269 4270 4338 3 4339 4338 4270 3 4270 4271 4339 3 4340 4339 4271 3 4271 5133 4340 3 5137 4340 5133 3 4272 4273 4341 3 4342 4341 4273 3 4272 4341 5140 3 4272 5140 5136 3 4273 4274 4342 3 4343 4342 4274 3 4274 4275 4343 3 4344 4343 4275 3 4275 4276 4344 3 4345 4344 4276 3 4276 4277 4345 3 4346 4345 4277 3 4277 4278 4347 3 4277 4347 4346 3 4278 4279 4348 3 4278 4348 4347 3 4279 4280 4349 3 4279 4349 4348 3 4280 4281 4350 3 4280 4350 4349 3 4281 4282 4351 3 4281 4351 4350 3 4282 4283 4352 3 4282 4352 4351 3 4283 4284 4353 3 4283 4353 4352 3 4284 4285 4354 3 4284 4354 4353 3 4285 4286 4355 3 4285 4355 4354 3 4286 4287 4356 3 4286 4356 4355 3 4287 4288 4357 3 4287 4357 4356 3 4288 4289 4358 3 4288 4358 4357 3 4289 4290 4359 3 4289 4359 4358 3 4290 4291 4360 3 4290 4360 4359 3 4291 4292 4361 3 4291 4361 4360 3 4292 4293 4362 3 4292 4362 4361 3 4293 4294 4363 3 4293 4363 4362 3 4294 4295 4364 3 4294 4364 4363 3 4295 4296 4365 3 4295 4365 4364 3 4296 4297 4366 3 4296 4366 4365 3 4297 4298 4367 3 4297 4367 4366 3 4298 4299 4368 3 4298 4368 4367 3 4299 4300 4369 3 4299 4369 4368 3 4300 4301 4370 3 4300 4370 4369 3 4301 4302 4371 3 4301 4371 4370 3 4302 4303 4372 3 4302 4372 4371 3 4303 4304 4373 3 4303 4373 4372 3 4304 4305 4374 3 4304 4374 4373 3 4305 4306 4375 3 4305 4375 4374 3 4306 4307 4376 3 4306 4376 4375 3 4307 4308 4377 3 4307 4377 4376 3 4308 4309 4378 3 4308 4378 4377 3 4309 4310 4379 3 4309 4379 4378 3 4310 4311 4380 3 4310 4380 4379 3 4311 4312 4381 3 4311 4381 4380 3 4312 4313 4382 3 4312 4382 4381 3 4313 4314 4383 3 4313 4383 4382 3 4314 4315 4384 3 4314 4384 4383 3 4315 4316 4385 3 4315 4385 4384 3 4316 4317 4386 3 4316 4386 4385 3 4317 4318 4386 3 4387 4386 4318 3 4318 4319 4387 3 4388 4387 4319 3 4319 4320 4388 3 4389 4388 4320 3 4320 4321 4389 3 4390 4389 4321 3 4321 4322 4390 3 4391 4390 4322 3 4322 4323 4391 3 4392 4391 4323 3 4323 4324 4392 3 4393 4392 4324 3 4324 4325 4393 3 4394 4393 4325 3 4325 4326 4394 3 4395 4394 4326 3 4326 4327 4395 3 4396 4395 4327 3 4327 4328 4396 3 4397 4396 4328 3 4328 4329 4397 3 4398 4397 4329 3 4329 4330 4398 3 4399 4398 4330 3 4330 4331 4399 3 4400 4399 4331 3 4331 4332 4400 3 4401 4400 4332 3 4332 4333 4401 3 4402 4401 4333 3 4333 4334 4402 3 4403 4402 4334 3 4334 4335 4403 3 4404 4403 4335 3 4335 4336 4404 3 4405 4404 4336 3 4336 4337 4405 3 4406 4405 4337 3 4337 4338 4406 3 4407 4406 4338 3 4338 4339 4407 3 4408 4407 4339 3 4339 4340 4408 3 4409 4408 4340 3 4340 5137 5141 3 4340 5141 4409 3 4341 4342 4410 3 4411 4410 4342 3 4341 4410 5144 3 4341 5144 5140 3 4342 4343 4411 3 4412 4411 4343 3 4343 4344 4412 3 4413 4412 4344 3 4344 4345 4413 3 4414 4413 4345 3 4345 4346 4414 3 4415 4414 4346 3 4346 4347 4415 3 4416 4415 4347 3 4347 4348 4416 3 4417 4416 4348 3 4348 4349 4417 3 4418 4417 4349 3 4349 4350 4418 3 4419 4418 4350 3 4350 4351 4419 3 4420 4419 4351 3 4351 4352 4420 3 4421 4420 4352 3 4352 4353 4421 3 4422 4421 4353 3 4353 4354 4422 3 4423 4422 4354 3 4354 4355 4423 3 4424 4423 4355 3 4355 4356 4424 3 4425 4424 4356 3 4356 4357 4425 3 4426 4425 4357 3 4357 4358 4426 3 4427 4426 4358 3 4358 4359 4428 3 4358 4428 4427 3 4359 4360 4429 3 4359 4429 4428 3 4360 4361 4430 3 4360 4430 4429 3 4361 4362 4431 3 4361 4431 4430 3 4362 4363 4432 3 4362 4432 4431 3 4363 4364 4433 3 4363 4433 4432 3 4364 4365 4434 3 4364 4434 4433 3 4365 4366 4435 3 4365 4435 4434 3 4366 4367 4436 3 4366 4436 4435 3 4367 4368 4437 3 4367 4437 4436 3 4368 4369 4438 3 4368 4438 4437 3 4369 4370 4439 3 4369 4439 4438 3 4370 4371 4440 3 4370 4440 4439 3 4371 4372 4441 3 4371 4441 4440 3 4372 4373 4442 3 4372 4442 4441 3 4373 4374 4443 3 4373 4443 4442 3 4374 4375 4444 3 4374 4444 4443 3 4375 4376 4445 3 4375 4445 4444 3 4376 4377 4446 3 4376 4446 4445 3 4377 4378 4447 3 4377 4447 4446 3 4378 4379 4448 3 4378 4448 4447 3 4379 4380 4449 3 4379 4449 4448 3 4380 4381 4450 3 4380 4450 4449 3 4381 4382 4451 3 4381 4451 4450 3 4382 4383 4452 3 4382 4452 4451 3 4383 4384 4453 3 4383 4453 4452 3 4384 4385 4454 3 4384 4454 4453 3 4385 4386 4455 3 4385 4455 4454 3 4386 4387 4456 3 4386 4456 4455 3 4387 4388 4457 3 4387 4457 4456 3 4388 4389 4458 3 4388 4458 4457 3 4389 4390 4459 3 4389 4459 4458 3 4390 4391 4460 3 4390 4460 4459 3 4391 4392 4461 3 4391 4461 4460 3 4392 4393 4462 3 4392 4462 4461 3 4393 4394 4463 3 4393 4463 4462 3 4394 4395 4464 3 4394 4464 4463 3 4395 4396 4465 3 4395 4465 4464 3 4396 4397 4466 3 4396 4466 4465 3 4397 4398 4467 3 4397 4467 4466 3 4398 4399 4468 3 4398 4468 4467 3 4399 4400 4468 3 4469 4468 4400 3 4400 4401 4469 3 4470 4469 4401 3 4401 4402 4470 3 4471 4470 4402 3 4402 4403 4471 3 4472 4471 4403 3 4403 4404 4472 3 4473 4472 4404 3 4404 4405 4473 3 4474 4473 4405 3 4405 4406 4474 3 4475 4474 4406 3 4406 4407 4475 3 4476 4475 4407 3 4407 4408 4476 3 4477 4476 4408 3 4408 4409 4477 3 4478 4477 4409 3 4409 5141 4478 3 5145 4478 5141 3 4410 4411 4479 3 4480 4479 4411 3 4410 4479 5148 3 4410 5148 5144 3 4411 4412 4480 3 4481 4480 4412 3 4412 4413 4481 3 4482 4481 4413 3 4413 4414 4482 3 4483 4482 4414 3 4414 4415 4483 3 4484 4483 4415 3 4415 4416 4484 3 4485 4484 4416 3 4416 4417 4485 3 4486 4485 4417 3 4417 4418 4486 3 4487 4486 4418 3 4418 4419 4487 3 4488 4487 4419 3 4419 4420 4488 3 4489 4488 4420 3 4420 4421 4489 3 4490 4489 4421 3 4421 4422 4490 3 4491 4490 4422 3 4422 4423 4491 3 4492 4491 4423 3 4423 4424 4492 3 4493 4492 4424 3 4424 4425 4493 3 4494 4493 4425 3 4425 4426 4494 3 4495 4494 4426 3 4426 4427 4495 3 4496 4495 4427 3 4427 4428 4496 3 4497 4496 4428 3 4428 4429 4497 3 4498 4497 4429 3 4429 4430 4498 3 4499 4498 4430 3 4430 4431 4499 3 4500 4499 4431 3 4431 4432 4500 3 4501 4500 4432 3 4432 4433 4501 3 4502 4501 4433 3 4433 4434 4502 3 4503 4502 4434 3 4434 4435 4503 3 4504 4503 4435 3 4435 4436 4504 3 4505 4504 4436 3 4436 4437 4505 3 4506 4505 4437 3 4437 4438 4506 3 4507 4506 4438 3 4438 4439 4507 3 4508 4507 4439 3 4439 4440 4508 3 4509 4508 4440 3 4440 4441 4510 3 4440 4510 4509 3 4441 4442 4511 3 4441 4511 4510 3 4442 4443 4512 3 4442 4512 4511 3 4443 4444 4513 3 4443 4513 4512 3 4444 4445 4514 3 4444 4514 4513 3 4445 4446 4515 3 4445 4515 4514 3 4446 4447 4516 3 4446 4516 4515 3 4447 4448 4517 3 4447 4517 4516 3 4448 4449 4518 3 4448 4518 4517 3 4449 4450 4519 3 4449 4519 4518 3 4450 4451 4520 3 4450 4520 4519 3 4451 4452 4521 3 4451 4521 4520 3 4452 4453 4522 3 4452 4522 4521 3 4453 4454 4523 3 4453 4523 4522 3 4454 4455 4524 3 4454 4524 4523 3 4455 4456 4525 3 4455 4525 4524 3 4456 4457 4526 3 4456 4526 4525 3 4457 4458 4527 3 4457 4527 4526 3 4458 4459 4528 3 4458 4528 4527 3 4459 4460 4529 3 4459 4529 4528 3 4460 4461 4530 3 4460 4530 4529 3 4461 4462 4531 3 4461 4531 4530 3 4462 4463 4532 3 4462 4532 4531 3 4463 4464 4533 3 4463 4533 4532 3 4464 4465 4534 3 4464 4534 4533 3 4465 4466 4535 3 4465 4535 4534 3 4466 4467 4536 3 4466 4536 4535 3 4467 4468 4537 3 4467 4537 4536 3 4468 4469 4538 3 4468 4538 4537 3 4469 4470 4539 3 4469 4539 4538 3 4470 4471 4540 3 4470 4540 4539 3 4471 4472 4541 3 4471 4541 4540 3 4472 4473 4542 3 4472 4542 4541 3 4473 4474 4543 3 4473 4543 4542 3 4474 4475 4544 3 4474 4544 4543 3 4475 4476 4545 3 4475 4545 4544 3 4476 4477 4546 3 4476 4546 4545 3 4477 4478 4547 3 4477 4547 4546 3 4478 5145 4547 3 5149 4547 5145 3 4479 4480 4549 3 4479 4549 4548 3 4479 4548 5148 3 5152 5148 4548 3 4480 4481 4550 3 4480 4550 4549 3 4481 4482 4550 3 4551 4550 4482 3 4482 4483 4551 3 4552 4551 4483 3 4483 4484 4552 3 4553 4552 4484 3 4484 4485 4553 3 4554 4553 4485 3 4485 4486 4554 3 4555 4554 4486 3 4486 4487 4555 3 4556 4555 4487 3 4487 4488 4556 3 4557 4556 4488 3 4488 4489 4557 3 4558 4557 4489 3 4489 4490 4558 3 4559 4558 4490 3 4490 4491 4559 3 4560 4559 4491 3 4491 4492 4560 3 4561 4560 4492 3 4492 4493 4561 3 4562 4561 4493 3 4493 4494 4562 3 4563 4562 4494 3 4494 4495 4563 3 4564 4563 4495 3 4495 4496 4564 3 4565 4564 4496 3 4496 4497 4565 3 4566 4565 4497 3 4497 4498 4566 3 4567 4566 4498 3 4498 4499 4567 3 4568 4567 4499 3 4499 4500 4568 3 4569 4568 4500 3 4500 4501 4569 3 4570 4569 4501 3 4501 4502 4570 3 4571 4570 4502 3 4502 4503 4571 3 4572 4571 4503 3 4503 4504 4572 3 4573 4572 4504 3 4504 4505 4573 3 4574 4573 4505 3 4505 4506 4574 3 4575 4574 4506 3 4506 4507 4575 3 4576 4575 4507 3 4507 4508 4576 3 4577 4576 4508 3 4508 4509 4577 3 4578 4577 4509 3 4509 4510 4578 3 4579 4578 4510 3 4510 4511 4579 3 4580 4579 4511 3 4511 4512 4580 3 4581 4580 4512 3 4512 4513 4581 3 4582 4581 4513 3 4513 4514 4582 3 4583 4582 4514 3 4514 4515 4583 3 4584 4583 4515 3 4515 4516 4584 3 4585 4584 4516 3 4516 4517 4585 3 4586 4585 4517 3 4517 4518 4586 3 4587 4586 4518 3 4518 4519 4587 3 4588 4587 4519 3 4519 4520 4588 3 4589 4588 4520 3 4520 4521 4589 3 4590 4589 4521 3 4521 4522 4590 3 4591 4590 4522 3 4522 4523 4592 3 4522 4592 4591 3 4523 4524 4593 3 4523 4593 4592 3 4524 4525 4594 3 4524 4594 4593 3 4525 4526 4595 3 4525 4595 4594 3 4526 4527 4596 3 4526 4596 4595 3 4527 4528 4597 3 4527 4597 4596 3 4528 4529 4598 3 4528 4598 4597 3 4529 4530 4599 3 4529 4599 4598 3 4530 4531 4600 3 4530 4600 4599 3 4531 4532 4601 3 4531 4601 4600 3 4532 4533 4602 3 4532 4602 4601 3 4533 4534 4603 3 4533 4603 4602 3 4534 4535 4604 3 4534 4604 4603 3 4535 4536 4605 3 4535 4605 4604 3 4536 4537 4606 3 4536 4606 4605 3 4537 4538 4607 3 4537 4607 4606 3 4538 4539 4608 3 4538 4608 4607 3 4539 4540 4609 3 4539 4609 4608 3 4540 4541 4610 3 4540 4610 4609 3 4541 4542 4611 3 4541 4611 4610 3 4542 4543 4612 3 4542 4612 4611 3 4543 4544 4613 3 4543 4613 4612 3 4544 4545 4614 3 4544 4614 4613 3 4545 4546 4615 3 4545 4615 4614 3 4546 4547 4616 3 4546 4616 4615 3 4547 5149 5155 3 4547 5155 4616 3 4548 4549 5153 3 4548 5153 5152 3 4549 4550 4618 3 4549 4618 4617 3 4549 4617 5153 3 5159 5153 4617 3 4550 4551 4619 3 4550 4619 4618 3 4551 4552 4620 3 4551 4620 4619 3 4552 4553 4621 3 4552 4621 4620 3 4553 4554 4622 3 4553 4622 4621 3 4554 4555 4623 3 4554 4623 4622 3 4555 4556 4624 3 4555 4624 4623 3 4556 4557 4625 3 4556 4625 4624 3 4557 4558 4626 3 4557 4626 4625 3 4558 4559 4627 3 4558 4627 4626 3 4559 4560 4628 3 4559 4628 4627 3 4560 4561 4629 3 4560 4629 4628 3 4561 4562 4630 3 4561 4630 4629 3 4562 4563 4631 3 4562 4631 4630 3 4563 4564 4632 3 4563 4632 4631 3 4564 4565 4632 3 4633 4632 4565 3 4565 4566 4633 3 4634 4633 4566 3 4566 4567 4634 3 4635 4634 4567 3 4567 4568 4635 3 4636 4635 4568 3 4568 4569 4636 3 4637 4636 4569 3 4569 4570 4637 3 4638 4637 4570 3 4570 4571 4638 3 4639 4638 4571 3 4571 4572 4639 3 4640 4639 4572 3 4572 4573 4640 3 4641 4640 4573 3 4573 4574 4641 3 4642 4641 4574 3 4574 4575 4642 3 4643 4642 4575 3 4575 4576 4643 3 4644 4643 4576 3 4576 4577 4644 3 4645 4644 4577 3 4577 4578 4645 3 4646 4645 4578 3 4578 4579 4646 3 4647 4646 4579 3 4579 4580 4647 3 4648 4647 4580 3 4580 4581 4648 3 4649 4648 4581 3 4581 4582 4649 3 4650 4649 4582 3 4582 4583 4650 3 4651 4650 4583 3 4583 4584 4651 3 4652 4651 4584 3 4584 4585 4652 3 4653 4652 4585 3 4585 4586 4653 3 4654 4653 4586 3 4586 4587 4654 3 4655 4654 4587 3 4587 4588 4655 3 4656 4655 4588 3 4588 4589 4656 3 4657 4656 4589 3 4589 4590 4657 3 4658 4657 4590 3 4590 4591 4658 3 4659 4658 4591 3 4591 4592 4659 3 4660 4659 4592 3 4592 4593 4660 3 4661 4660 4593 3 4593 4594 4661 3 4662 4661 4594 3 4594 4595 4662 3 4663 4662 4595 3 4595 4596 4663 3 4664 4663 4596 3 4596 4597 4664 3 4665 4664 4597 3 4597 4598 4665 3 4666 4665 4598 3 4598 4599 4666 3 4667 4666 4599 3 4599 4600 4667 3 4668 4667 4600 3 4600 4601 4668 3 4669 4668 4601 3 4601 4602 4669 3 4670 4669 4602 3 4602 4603 4670 3 4671 4670 4603 3 4603 4604 4671 3 4672 4671 4604 3 4604 4605 4672 3 4673 4672 4605 3 4605 4606 4674 3 4605 4674 4673 3 4606 4607 4675 3 4606 4675 4674 3 4607 4608 4676 3 4607 4676 4675 3 4608 4609 4677 3 4608 4677 4676 3 4609 4610 4678 3 4609 4678 4677 3 4610 4611 4679 3 4610 4679 4678 3 4611 4612 4680 3 4611 4680 4679 3 4612 4613 4681 3 4612 4681 4680 3 4613 4614 4682 3 4613 4682 4681 3 4614 4615 4683 3 4614 4683 4682 3 4615 4616 5155 3 4615 5155 5154 3 4615 5154 4683 3 5162 4683 5154 3 4617 4618 5160 3 4617 5160 5159 3 4618 4619 4685 3 4618 4685 4684 3 4618 4684 5160 3 5167 5160 4684 3 4619 4620 4686 3 4619 4686 4685 3 4620 4621 4687 3 4620 4687 4686 3 4621 4622 4688 3 4621 4688 4687 3 4622 4623 4689 3 4622 4689 4688 3 4623 4624 4690 3 4623 4690 4689 3 4624 4625 4691 3 4624 4691 4690 3 4625 4626 4692 3 4625 4692 4691 3 4626 4627 4693 3 4626 4693 4692 3 4627 4628 4694 3 4627 4694 4693 3 4628 4629 4695 3 4628 4695 4694 3 4629 4630 4696 3 4629 4696 4695 3 4630 4631 4697 3 4630 4697 4696 3 4631 4632 4698 3 4631 4698 4697 3 4632 4633 4699 3 4632 4699 4698 3 4633 4634 4700 3 4633 4700 4699 3 4634 4635 4701 3 4634 4701 4700 3 4635 4636 4702 3 4635 4702 4701 3 4636 4637 4703 3 4636 4703 4702 3 4637 4638 4704 3 4637 4704 4703 3 4638 4639 4705 3 4638 4705 4704 3 4639 4640 4706 3 4639 4706 4705 3 4640 4641 4707 3 4640 4707 4706 3 4641 4642 4708 3 4641 4708 4707 3 4642 4643 4709 3 4642 4709 4708 3 4643 4644 4710 3 4643 4710 4709 3 4644 4645 4711 3 4644 4711 4710 3 4645 4646 4712 3 4645 4712 4711 3 4646 4647 4713 3 4646 4713 4712 3 4647 4648 4713 3 4714 4713 4648 3 4648 4649 4714 3 4715 4714 4649 3 4649 4650 4715 3 4716 4715 4650 3 4650 4651 4716 3 4717 4716 4651 3 4651 4652 4717 3 4718 4717 4652 3 4652 4653 4718 3 4719 4718 4653 3 4653 4654 4719 3 4720 4719 4654 3 4654 4655 4720 3 4721 4720 4655 3 4655 4656 4721 3 4722 4721 4656 3 4656 4657 4722 3 4723 4722 4657 3 4657 4658 4723 3 4724 4723 4658 3 4658 4659 4724 3 4725 4724 4659 3 4659 4660 4725 3 4726 4725 4660 3 4660 4661 4726 3 4727 4726 4661 3 4661 4662 4727 3 4728 4727 4662 3 4662 4663 4728 3 4729 4728 4663 3 4663 4664 4729 3 4730 4729 4664 3 4664 4665 4730 3 4731 4730 4665 3 4665 4666 4731 3 4732 4731 4666 3 4666 4667 4732 3 4733 4732 4667 3 4667 4668 4733 3 4734 4733 4668 3 4668 4669 4734 3 4735 4734 4669 3 4669 4670 4735 3 4736 4735 4670 3 4670 4671 4736 3 4737 4736 4671 3 4671 4672 4737 3 4738 4737 4672 3 4672 4673 4738 3 4739 4738 4673 3 4673 4674 4739 3 4740 4739 4674 3 4674 4675 4740 3 4741 4740 4675 3 4675 4676 4741 3 4742 4741 4676 3 4676 4677 4742 3 4743 4742 4677 3 4677 4678 4743 3 4744 4743 4678 3 4678 4679 4744 3 4745 4744 4679 3 4679 4680 4745 3 4746 4745 4680 3 4680 4681 4746 3 4747 4746 4681 3 4681 4682 4747 3 4748 4747 4682 3 4682 4683 5161 3 5162 5161 4683 3 4682 5161 5231 3 4682 5231 4748 3 4684 4685 5167 3 5168 5167 4685 3 4685 4686 5168 3 5169 5168 4686 3 4686 4687 5169 3 5170 5169 4687 3 4687 4688 5170 3 5171 5170 4688 3 4688 4689 5171 3 5172 5171 4689 3 4689 4690 5173 3 4689 5173 5172 3 4690 4691 5174 3 4690 5174 5173 3 4691 4692 5175 3 4691 5175 5174 3 4692 4693 5176 3 4692 5176 5175 3 4693 4694 5177 3 4693 5177 5176 3 4694 4695 5178 3 4694 5178 5177 3 4695 4696 5179 3 4695 5179 5178 3 4696 4697 5180 3 4696 5180 5179 3 4697 4698 5181 3 4697 5181 5180 3 4698 4699 5182 3 4698 5182 5181 3 4699 4700 5183 3 4699 5183 5182 3 4700 4701 5184 3 4700 5184 5183 3 4701 4702 5185 3 4701 5185 5184 3 4702 4703 5186 3 4702 5186 5185 3 4703 4704 5187 3 4703 5187 5186 3 4704 4705 5188 3 4704 5188 5187 3 4705 4706 5189 3 4705 5189 5188 3 4706 4707 5190 3 4706 5190 5189 3 4707 4708 5191 3 4707 5191 5190 3 4708 4709 5192 3 4708 5192 5191 3 4709 4710 5193 3 4709 5193 5192 3 4710 4711 5194 3 4710 5194 5193 3 4711 4712 5195 3 4711 5195 5194 3 4712 4713 5196 3 4712 5196 5195 3 4713 4714 5197 3 4713 5197 5196 3 4714 4715 5198 3 4714 5198 5197 3 4715 4716 5199 3 4715 5199 5198 3 4716 4717 5200 3 4716 5200 5199 3 4717 4718 5201 3 4717 5201 5200 3 4718 4719 5202 3 4718 5202 5201 3 4719 4720 5203 3 4719 5203 5202 3 4720 4721 5204 3 4720 5204 5203 3 4721 4722 5205 3 4721 5205 5204 3 4722 4723 5206 3 4722 5206 5205 3 4723 4724 5207 3 4723 5207 5206 3 4724 4725 5208 3 4724 5208 5207 3 4725 4726 5209 3 4725 5209 5208 3 4726 4727 5210 3 4726 5210 5209 3 4727 4728 5211 3 4727 5211 5210 3 4728 4729 5212 3 4728 5212 5211 3 4729 4730 5213 3 4729 5213 5212 3 4730 4731 5214 3 4730 5214 5213 3 4731 4732 5214 3 5215 5214 4732 3 4732 4733 5215 3 5216 5215 4733 3 4733 4734 5216 3 5217 5216 4734 3 4734 4735 5217 3 5218 5217 4735 3 4735 4736 5218 3 5219 5218 4736 3 4736 4737 5219 3 5220 5219 4737 3 4737 4738 5220 3 5221 5220 4738 3 4738 4739 5221 3 5222 5221 4739 3 4739 4740 5222 3 5223 5222 4740 3 4740 4741 5223 3 5224 5223 4741 3 4741 4742 5224 3 5225 5224 4742 3 4742 4743 5225 3 5226 5225 4743 3 4743 4744 5226 3 5227 5226 4744 3 4744 4745 5227 3 5228 5227 4745 3 4745 4746 5228 3 5229 5228 4746 3 4746 4747 5229 3 5230 5229 4747 3 4747 4748 5230 3 5231 5230 4748 3 4749 4750 4817 3 4818 4817 4750 3 4749 5367 4750 3 5368 4750 5367 3 4749 4817 5437 3 4749 5437 5367 3 4750 4751 4818 3 4819 4818 4751 3 4750 5368 4751 3 5369 4751 5368 3 4751 4752 4819 3 4820 4819 4752 3 4751 5369 4752 3 5370 4752 5369 3 4752 4753 4820 3 4821 4820 4753 3 4752 5370 4753 3 5371 4753 5370 3 4753 4754 4821 3 4822 4821 4754 3 4753 5371 4754 3 5372 4754 5371 3 4754 4755 4822 3 4823 4822 4755 3 4754 5372 4755 3 5373 4755 5372 3 4755 4756 4823 3 4824 4823 4756 3 4755 5373 4756 3 5374 4756 5373 3 4756 4757 4824 3 4825 4824 4757 3 4756 5374 4757 3 5375 4757 5374 3 4757 4758 4825 3 4826 4825 4758 3 4757 5375 4758 3 5376 4758 5375 3 4758 4759 4826 3 4827 4826 4759 3 4758 5376 4759 3 5377 4759 5376 3 4759 4760 4827 3 4828 4827 4760 3 4759 5377 4760 3 5378 4760 5377 3 4760 4761 4828 3 4829 4828 4761 3 4760 5378 4761 3 5379 4761 5378 3 4761 4762 4829 3 4830 4829 4762 3 4761 5379 4762 3 5380 4762 5379 3 4762 4763 4830 3 4831 4830 4763 3 4762 5380 4763 3 5381 4763 5380 3 4763 4764 4831 3 4832 4831 4764 3 4763 5381 4764 3 5382 4764 5381 3 4764 4765 4832 3 4833 4832 4765 3 4764 5382 4765 3 5383 4765 5382 3 4765 4766 4833 3 4834 4833 4766 3 4765 5383 4766 3 5384 4766 5383 3 4766 4767 4834 3 4835 4834 4767 3 4766 5384 4767 3 5385 4767 5384 3 4767 4768 4835 3 4836 4835 4768 3 4767 5385 4768 3 5386 4768 5385 3 4768 4769 4836 3 4837 4836 4769 3 4768 5386 4769 3 5387 4769 5386 3 4769 4770 4837 3 4838 4837 4770 3 4769 5387 5388 3 4769 5388 4770 3 4770 4771 4838 3 4839 4838 4771 3 4770 5388 5389 3 4770 5389 4771 3 4771 4772 4839 3 4840 4839 4772 3 4771 5389 5390 3 4771 5390 4772 3 4772 4773 4840 3 4841 4840 4773 3 4772 5390 5391 3 4772 5391 4773 3 4773 4774 4841 3 4842 4841 4774 3 4773 5391 5392 3 4773 5392 4774 3 4774 4775 4843 3 4774 4843 4842 3 4774 5392 5393 3 4774 5393 4775 3 4775 4776 4844 3 4775 4844 4843 3 4775 5393 5394 3 4775 5394 4776 3 4776 4777 4845 3 4776 4845 4844 3 4776 5394 5395 3 4776 5395 4777 3 4777 4778 4846 3 4777 4846 4845 3 4777 5395 5396 3 4777 5396 4778 3 4778 4779 4847 3 4778 4847 4846 3 4778 5396 5397 3 4778 5397 4779 3 4779 4780 4848 3 4779 4848 4847 3 4779 5397 5398 3 4779 5398 4780 3 4780 4781 4849 3 4780 4849 4848 3 4780 5398 5399 3 4780 5399 4781 3 4781 4782 4850 3 4781 4850 4849 3 4781 5399 5400 3 4781 5400 4782 3 4782 4783 4851 3 4782 4851 4850 3 4782 5400 5401 3 4782 5401 4783 3 4783 4784 4852 3 4783 4852 4851 3 4783 5401 5402 3 4783 5402 4784 3 4784 4785 4853 3 4784 4853 4852 3 4784 5402 5403 3 4784 5403 4785 3 4785 4786 4854 3 4785 4854 4853 3 4785 5403 5404 3 4785 5404 4786 3 4786 4787 4855 3 4786 4855 4854 3 4786 5404 5405 3 4786 5405 4787 3 4787 4788 4856 3 4787 4856 4855 3 4787 5405 5406 3 4787 5406 4788 3 4788 4789 4857 3 4788 4857 4856 3 4788 5406 5407 3 4788 5407 4789 3 4789 4790 4858 3 4789 4858 4857 3 4789 5407 5408 3 4789 5408 4790 3 4790 4791 4859 3 4790 4859 4858 3 4790 5408 5409 3 4790 5409 4791 3 4791 4792 4860 3 4791 4860 4859 3 4791 5409 5410 3 4791 5410 4792 3 4792 4793 4861 3 4792 4861 4860 3 4792 5410 5411 3 4792 5411 4793 3 4793 4794 4862 3 4793 4862 4861 3 4793 5411 5412 3 4793 5412 4794 3 4794 4795 4863 3 4794 4863 4862 3 4794 5412 5413 3 4794 5413 4795 3 4795 4796 4864 3 4795 4864 4863 3 4795 5413 5414 3 4795 5414 4796 3 4796 4797 4865 3 4796 4865 4864 3 4796 5414 5415 3 4796 5415 4797 3 4797 4798 4866 3 4797 4866 4865 3 4797 5415 5416 3 4797 5416 4798 3 4798 4799 4867 3 4798 4867 4866 3 4798 5416 5417 3 4798 5417 4799 3 4799 4800 4868 3 4799 4868 4867 3 4799 5417 5418 3 4799 5418 4800 3 4800 4801 4869 3 4800 4869 4868 3 4800 5418 5419 3 4800 5419 4801 3 4801 4802 4870 3 4801 4870 4869 3 4801 5419 5420 3 4801 5420 4802 3 4802 4803 4871 3 4802 4871 4870 3 4802 5420 5421 3 4802 5421 4803 3 4803 4804 4872 3 4803 4872 4871 3 4803 5421 5422 3 4803 5422 4804 3 4804 4805 4873 3 4804 4873 4872 3 4804 5422 5423 3 4804 5423 4805 3 4805 4806 4874 3 4805 4874 4873 3 4805 5423 5424 3 4805 5424 4806 3 4806 4807 4875 3 4806 4875 4874 3 4806 5424 5425 3 4806 5425 4807 3 4807 4808 4876 3 4807 4876 4875 3 4807 5425 5426 3 4807 5426 4808 3 4808 4809 4877 3 4808 4877 4876 3 4808 5426 5427 3 4808 5427 4809 3 4809 4810 4878 3 4809 4878 4877 3 4809 5427 5428 3 4809 5428 4810 3 4810 4811 4879 3 4810 4879 4878 3 4810 5428 5429 3 4810 5429 4811 3 4811 4812 4880 3 4811 4880 4879 3 4811 5429 5430 3 4811 5430 4812 3 4812 4813 4881 3 4812 4881 4880 3 4812 5430 5431 3 4812 5431 4813 3 4813 4814 4882 3 4813 4882 4881 3 4813 5431 5432 3 4813 5432 4814 3 4814 4815 4883 3 4814 4883 4882 3 4814 5432 4815 3 5433 4815 5432 3 4815 5433 4883 3 5438 4883 5433 3 4816 4817 4886 3 4887 4886 4817 3 4816 5436 4817 3 5437 4817 5436 3 4816 4886 5436 3 5442 5436 4886 3 4817 4818 4887 3 4888 4887 4818 3 4882 4883 4890 3 4882 4890 4889 3 4883 4884 4891 3 4883 4891 4890 3 4883 5438 4884 3 5439 4884 5438 3 4884 5439 4891 3 5443 4891 5439 3 4885 4886 4894 3 4885 4894 4893 3 4885 5441 4886 3 5442 4886 5441 3 4885 4893 5446 3 4885 5446 5441 3 4886 4887 4895 3 4886 4895 4894 3 4890 4891 4897 3 4890 4897 4896 3 4891 4892 4898 3 4891 4898 4897 3 4891 5443 4892 3 5444 4892 5443 3 4892 5444 4898 3 5447 4898 5444 3 4893 4894 4900 3 4893 4900 4899 3 4893 4899 5450 3 4893 5450 5446 3 4897 4898 4902 3 4897 4902 4901 3 4898 5447 5451 3 4898 5451 4902 3 4899 4900 4904 3 4899 4904 4903 3 4899 4903 5454 3 4899 5454 5450 3 4901 4902 4906 3 4901 4906 4905 3 4902 5451 5455 3 4902 5455 4906 3 4903 4904 4907 3 4908 4907 4904 3 4903 4907 5454 3 5458 5454 4907 3 4905 4906 4909 3 4910 4909 4906 3 4906 5455 5459 3 4906 5459 4910 3 4907 4908 4911 3 4912 4911 4908 3 4907 4911 5458 3 5462 5458 4911 3 4909 4910 4913 3 4914 4913 4910 3 4910 5459 5463 3 4910 5463 4914 3 4911 4912 4915 3 4916 4915 4912 3 4911 4915 5462 3 5466 5462 4915 3 4913 4914 4917 3 4918 4917 4914 3 4914 5463 5467 3 4914 5467 4918 3 4915 4916 4919 3 4920 4919 4916 3 4915 4919 5466 3 5470 5466 4919 3 4917 4918 4921 3 4922 4921 4918 3 4918 5467 5471 3 4918 5471 4922 3 4919 4920 4923 3 4924 4923 4920 3 4919 4923 5470 3 5474 5470 4923 3 4921 4922 4925 3 4926 4925 4922 3 4922 5471 5475 3 4922 5475 4926 3 4923 4924 4927 3 4928 4927 4924 3 4923 4927 5474 3 5478 5474 4927 3 4925 4926 4929 3 4930 4929 4926 3 4926 5475 5479 3 4926 5479 4930 3 4927 4928 4931 3 4932 4931 4928 3 4927 4931 5478 3 5482 5478 4931 3 4929 4930 4933 3 4934 4933 4930 3 4930 5479 5483 3 4930 5483 4934 3 4931 4932 4935 3 4936 4935 4932 3 4931 4935 5482 3 5486 5482 4935 3 4933 4934 4937 3 4938 4937 4934 3 4934 5483 5487 3 4934 5487 4938 3 4935 4936 4939 3 4940 4939 4936 3 4935 4939 5486 3 5490 5486 4939 3 4937 4938 4941 3 4942 4941 4938 3 4938 5487 5491 3 4938 5491 4942 3 4939 4940 4943 3 4944 4943 4940 3 4939 4943 5490 3 5494 5490 4943 3 4941 4942 4945 3 4946 4945 4942 3 4942 5491 4946 3 5495 4946 5491 3 4943 4944 4947 3 4948 4947 4944 3 4943 4947 5494 3 5498 5494 4947 3 4945 4946 4950 3 4945 4950 4949 3 4946 5495 4950 3 5499 4950 5495 3 4947 4948 4952 3 4947 4952 4951 3 4947 4951 5502 3 4947 5502 5498 3 4949 4950 4954 3 4949 4954 4953 3 4950 5499 4954 3 5503 4954 5499 3 4951 4952 4956 3 4951 4956 4955 3 4951 4955 5506 3 4951 5506 5502 3 4953 4954 4958 3 4953 4958 4957 3 4954 5503 4958 3 5507 4958 5503 3 4955 4956 4960 3 4955 4960 4959 3 4955 4959 5510 3 4955 5510 5506 3 4957 4958 4962 3 4957 4962 4961 3 4958 5507 4962 3 5511 4962 5507 3 4959 4960 4964 3 4959 4964 4963 3 4959 4963 5514 3 4959 5514 5510 3 4961 4962 4966 3 4961 4966 4965 3 4962 5511 4966 3 5515 4966 5511 3 4963 4964 4968 3 4963 4968 4967 3 4963 4967 5518 3 4963 5518 5514 3 4965 4966 4970 3 4965 4970 4969 3 4966 5515 4970 3 5519 4970 5515 3 4967 4968 4972 3 4967 4972 4971 3 4967 4971 5522 3 4967 5522 5518 3 4969 4970 4974 3 4969 4974 4973 3 4970 5519 4974 3 5523 4974 5519 3 4971 4972 4976 3 4971 4976 4975 3 4971 4975 5526 3 4971 5526 5522 3 4973 4974 4978 3 4973 4978 4977 3 4974 5523 4978 3 5527 4978 5523 3 4975 4976 4980 3 4975 4980 4979 3 4975 4979 5530 3 4975 5530 5526 3 4977 4978 4982 3 4977 4982 4981 3 4978 5527 4982 3 5531 4982 5527 3 4979 4980 4984 3 4979 4984 4983 3 4979 4983 5534 3 4979 5534 5530 3 4981 4982 4986 3 4981 4986 4985 3 4982 5531 4986 3 5535 4986 5531 3 4983 4984 4988 3 4983 4988 4987 3 4983 4987 5538 3 4983 5538 5534 3 4985 4986 4990 3 4985 4990 4989 3 4986 5535 5539 3 4986 5539 4990 3 4987 4988 4992 3 4987 4992 4991 3 4987 4991 5538 3 5542 5538 4991 3 4989 4990 4993 3 4994 4993 4990 3 4990 5539 5543 3 4990 5543 4994 3 4991 4992 4995 3 4996 4995 4992 3 4991 4995 5542 3 5546 5542 4995 3 4993 4994 4997 3 4998 4997 4994 3 4994 5543 5547 3 4994 5547 4998 3 4995 4996 4999 3 5000 4999 4996 3 4995 4999 5546 3 5550 5546 4999 3 4997 4998 5001 3 5002 5001 4998 3 4998 5547 5551 3 4998 5551 5002 3 4999 5000 5003 3 5004 5003 5000 3 4999 5003 5550 3 5554 5550 5003 3 5001 5002 5005 3 5006 5005 5002 3 5002 5551 5555 3 5002 5555 5006 3 5003 5004 5007 3 5008 5007 5004 3 5003 5007 5554 3 5558 5554 5007 3 5005 5006 5009 3 5010 5009 5006 3 5006 5555 5559 3 5006 5559 5010 3 5007 5008 5011 3 5012 5011 5008 3 5007 5011 5558 3 5562 5558 5011 3 5009 5010 5013 3 5014 5013 5010 3 5010 5559 5563 3 5010 5563 5014 3 5011 5012 5015 3 5016 5015 5012 3 5011 5015 5562 3 5566 5562 5015 3 5013 5014 5017 3 5018 5017 5014 3 5014 5563 5567 3 5014 5567 5018 3 5015 5016 5019 3 5020 5019 5016 3 5015 5019 5566 3 5570 5566 5019 3 5017 5018 5021 3 5022 5021 5018 3 5018 5567 5571 3 5018 5571 5022 3 5019 5020 5023 3 5024 5023 5020 3 5019 5023 5570 3 5574 5570 5023 3 5021 5022 5025 3 5026 5025 5022 3 5022 5571 5575 3 5022 5575 5026 3 5023 5024 5027 3 5028 5027 5024 3 5023 5027 5574 3 5578 5574 5027 3 5025 5026 5029 3 5030 5029 5026 3 5026 5575 5579 3 5026 5579 5030 3 5027 5028 5031 3 5032 5031 5028 3 5027 5031 5578 3 5582 5578 5031 3 5029 5030 5033 3 5034 5033 5030 3 5030 5579 5583 3 5030 5583 5034 3 5031 5032 5035 3 5036 5035 5032 3 5031 5035 5586 3 5031 5586 5582 3 5033 5034 5038 3 5033 5038 5037 3 5034 5583 5038 3 5587 5038 5583 3 5035 5036 5040 3 5035 5040 5039 3 5035 5039 5590 3 5035 5590 5586 3 5037 5038 5042 3 5037 5042 5041 3 5038 5587 5042 3 5591 5042 5587 3 5039 5040 5044 3 5039 5044 5043 3 5039 5043 5594 3 5039 5594 5590 3 5041 5042 5046 3 5041 5046 5045 3 5042 5591 5046 3 5595 5046 5591 3 5043 5044 5048 3 5043 5048 5047 3 5043 5047 5598 3 5043 5598 5594 3 5045 5046 5050 3 5045 5050 5049 3 5046 5595 5050 3 5599 5050 5595 3 5047 5048 5052 3 5047 5052 5051 3 5047 5051 5602 3 5047 5602 5598 3 5049 5050 5054 3 5049 5054 5053 3 5050 5599 5054 3 5603 5054 5599 3 5051 5052 5056 3 5051 5056 5055 3 5051 5055 5606 3 5051 5606 5602 3 5053 5054 5058 3 5053 5058 5057 3 5054 5603 5058 3 5607 5058 5603 3 5055 5056 5060 3 5055 5060 5059 3 5055 5059 5610 3 5055 5610 5606 3 5057 5058 5062 3 5057 5062 5061 3 5058 5607 5062 3 5611 5062 5607 3 5059 5060 5064 3 5059 5064 5063 3 5059 5063 5614 3 5059 5614 5610 3 5061 5062 5066 3 5061 5066 5065 3 5062 5611 5066 3 5615 5066 5611 3 5063 5064 5068 3 5063 5068 5067 3 5063 5067 5618 3 5063 5618 5614 3 5065 5066 5070 3 5065 5070 5069 3 5066 5615 5070 3 5619 5070 5615 3 5067 5068 5072 3 5067 5072 5071 3 5067 5071 5622 3 5067 5622 5618 3 5069 5070 5074 3 5069 5074 5073 3 5070 5619 5074 3 5623 5074 5619 3 5071 5072 5076 3 5071 5076 5075 3 5071 5075 5626 3 5071 5626 5622 3 5073 5074 5078 3 5073 5078 5077 3 5074 5623 5078 3 5627 5078 5623 3 5075 5076 5080 3 5075 5080 5079 3 5075 5079 5626 3 5630 5626 5079 3 5077 5078 5081 3 5082 5081 5078 3 5078 5627 5631 3 5078 5631 5082 3 5079 5080 5083 3 5084 5083 5080 3 5079 5083 5630 3 5634 5630 5083 3 5081 5082 5085 3 5086 5085 5082 3 5082 5631 5635 3 5082 5635 5086 3 5083 5084 5087 3 5088 5087 5084 3 5083 5087 5634 3 5638 5634 5087 3 5085 5086 5089 3 5090 5089 5086 3 5086 5635 5639 3 5086 5639 5090 3 5087 5088 5091 3 5092 5091 5088 3 5087 5091 5638 3 5642 5638 5091 3 5089 5090 5093 3 5094 5093 5090 3 5090 5639 5643 3 5090 5643 5094 3 5091 5092 5095 3 5096 5095 5092 3 5091 5095 5642 3 5646 5642 5095 3 5093 5094 5097 3 5098 5097 5094 3 5094 5643 5647 3 5094 5647 5098 3 5095 5096 5099 3 5100 5099 5096 3 5095 5099 5646 3 5650 5646 5099 3 5097 5098 5101 3 5102 5101 5098 3 5098 5647 5651 3 5098 5651 5102 3 5099 5100 5103 3 5104 5103 5100 3 5099 5103 5650 3 5654 5650 5103 3 5101 5102 5105 3 5106 5105 5102 3 5102 5651 5655 3 5102 5655 5106 3 5103 5104 5107 3 5108 5107 5104 3 5103 5107 5654 3 5658 5654 5107 3 5105 5106 5109 3 5110 5109 5106 3 5106 5655 5659 3 5106 5659 5110 3 5107 5108 5111 3 5112 5111 5108 3 5107 5111 5658 3 5662 5658 5111 3 5109 5110 5113 3 5114 5113 5110 3 5110 5659 5663 3 5110 5663 5114 3 5111 5112 5115 3 5116 5115 5112 3 5111 5115 5662 3 5666 5662 5115 3 5113 5114 5117 3 5118 5117 5114 3 5114 5663 5667 3 5114 5667 5118 3 5115 5116 5119 3 5120 5119 5116 3 5115 5119 5666 3 5670 5666 5119 3 5117 5118 5121 3 5122 5121 5118 3 5118 5667 5671 3 5118 5671 5122 3 5119 5120 5123 3 5124 5123 5120 3 5119 5123 5674 3 5119 5674 5670 3 5121 5122 5126 3 5121 5126 5125 3 5122 5671 5126 3 5675 5126 5671 3 5123 5124 5128 3 5123 5128 5127 3 5123 5127 5678 3 5123 5678 5674 3 5125 5126 5130 3 5125 5130 5129 3 5126 5675 5130 3 5679 5130 5675 3 5127 5128 5132 3 5127 5132 5131 3 5127 5131 5682 3 5127 5682 5678 3 5129 5130 5134 3 5129 5134 5133 3 5130 5679 5134 3 5683 5134 5679 3 5131 5132 5136 3 5131 5136 5135 3 5131 5135 5686 3 5131 5686 5682 3 5133 5134 5138 3 5133 5138 5137 3 5134 5683 5138 3 5687 5138 5683 3 5135 5136 5140 3 5135 5140 5139 3 5135 5139 5690 3 5135 5690 5686 3 5137 5138 5142 3 5137 5142 5141 3 5138 5687 5142 3 5691 5142 5687 3 5139 5140 5144 3 5139 5144 5143 3 5139 5143 5694 3 5139 5694 5690 3 5141 5142 5146 3 5141 5146 5145 3 5142 5691 5146 3 5695 5146 5691 3 5143 5144 5148 3 5143 5148 5147 3 5143 5147 5698 3 5143 5698 5694 3 5145 5146 5150 3 5145 5150 5149 3 5146 5695 5150 3 5699 5150 5695 3 5147 5148 5152 3 5147 5152 5151 3 5147 5151 5702 3 5147 5702 5698 3 5149 5150 5156 3 5149 5156 5155 3 5150 5699 5156 3 5703 5156 5699 3 5151 5152 5158 3 5151 5158 5157 3 5151 5157 5705 3 5151 5705 5702 3 5152 5153 5159 3 5152 5159 5158 3 5154 5155 5163 3 5154 5163 5162 3 5155 5156 5164 3 5155 5164 5163 3 5156 5703 5164 3 5708 5164 5703 3 5157 5158 5706 3 5157 5706 5705 3 5158 5159 5166 3 5158 5166 5165 3 5158 5165 5710 3 5158 5710 5706 3 5159 5160 5167 3 5159 5167 5166 3 5161 5162 5232 3 5161 5232 5231 3 5162 5163 5233 3 5162 5233 5232 3 5163 5164 5708 3 5163 5708 5707 3 5163 5707 5233 3 5713 5233 5707 3 5165 5166 5710 3 5711 5710 5166 3 5166 5167 5234 3 5235 5234 5167 3 5166 5234 5711 3 5716 5711 5234 3 5167 5168 5235 3 5236 5235 5168 3 5168 5169 5236 3 5237 5236 5169 3 5169 5170 5237 3 5238 5237 5170 3 5170 5171 5238 3 5239 5238 5171 3 5171 5172 5239 3 5240 5239 5172 3 5172 5173 5240 3 5241 5240 5173 3 5173 5174 5241 3 5242 5241 5174 3 5174 5175 5242 3 5243 5242 5175 3 5175 5176 5243 3 5244 5243 5176 3 5176 5177 5244 3 5245 5244 5177 3 5177 5178 5245 3 5246 5245 5178 3 5178 5179 5246 3 5247 5246 5179 3 5179 5180 5247 3 5248 5247 5180 3 5180 5181 5248 3 5249 5248 5181 3 5181 5182 5249 3 5250 5249 5182 3 5182 5183 5250 3 5251 5250 5183 3 5183 5184 5251 3 5252 5251 5184 3 5184 5185 5252 3 5253 5252 5185 3 5185 5186 5253 3 5254 5253 5186 3 5186 5187 5254 3 5255 5254 5187 3 5187 5188 5255 3 5256 5255 5188 3 5188 5189 5256 3 5257 5256 5189 3 5189 5190 5257 3 5258 5257 5190 3 5190 5191 5258 3 5259 5258 5191 3 5191 5192 5259 3 5260 5259 5192 3 5192 5193 5260 3 5261 5260 5193 3 5193 5194 5261 3 5262 5261 5194 3 5194 5195 5262 3 5263 5262 5195 3 5195 5196 5263 3 5264 5263 5196 3 5196 5197 5264 3 5265 5264 5197 3 5197 5198 5265 3 5266 5265 5198 3 5198 5199 5266 3 5267 5266 5199 3 5199 5200 5267 3 5268 5267 5200 3 5200 5201 5268 3 5269 5268 5201 3 5201 5202 5269 3 5270 5269 5202 3 5202 5203 5270 3 5271 5270 5203 3 5203 5204 5271 3 5272 5271 5204 3 5204 5205 5272 3 5273 5272 5205 3 5205 5206 5273 3 5274 5273 5206 3 5206 5207 5274 3 5275 5274 5207 3 5207 5208 5275 3 5276 5275 5208 3 5208 5209 5276 3 5277 5276 5209 3 5209 5210 5278 3 5209 5278 5277 3 5210 5211 5279 3 5210 5279 5278 3 5211 5212 5280 3 5211 5280 5279 3 5212 5213 5281 3 5212 5281 5280 3 5213 5214 5282 3 5213 5282 5281 3 5214 5215 5283 3 5214 5283 5282 3 5215 5216 5284 3 5215 5284 5283 3 5216 5217 5285 3 5216 5285 5284 3 5217 5218 5286 3 5217 5286 5285 3 5218 5219 5287 3 5218 5287 5286 3 5219 5220 5288 3 5219 5288 5287 3 5220 5221 5289 3 5220 5289 5288 3 5221 5222 5290 3 5221 5290 5289 3 5222 5223 5291 3 5222 5291 5290 3 5223 5224 5292 3 5223 5292 5291 3 5224 5225 5293 3 5224 5293 5292 3 5225 5226 5294 3 5225 5294 5293 3 5226 5227 5295 3 5226 5295 5294 3 5227 5228 5296 3 5227 5296 5295 3 5228 5229 5297 3 5228 5297 5296 3 5229 5230 5298 3 5229 5298 5297 3 5230 5231 5299 3 5230 5299 5298 3 5231 5232 5300 3 5231 5300 5299 3 5232 5233 5713 3 5232 5713 5712 3 5232 5712 5782 3 5232 5782 5300 3 5234 5235 5717 3 5234 5717 5716 3 5235 5236 5718 3 5235 5718 5717 3 5236 5237 5719 3 5236 5719 5718 3 5237 5238 5720 3 5237 5720 5719 3 5238 5239 5721 3 5238 5721 5720 3 5239 5240 5722 3 5239 5722 5721 3 5240 5241 5723 3 5240 5723 5722 3 5241 5242 5724 3 5241 5724 5723 3 5242 5243 5725 3 5242 5725 5724 3 5243 5244 5726 3 5243 5726 5725 3 5244 5245 5727 3 5244 5727 5726 3 5245 5246 5728 3 5245 5728 5727 3 5246 5247 5729 3 5246 5729 5728 3 5247 5248 5730 3 5247 5730 5729 3 5248 5249 5731 3 5248 5731 5730 3 5249 5250 5732 3 5249 5732 5731 3 5250 5251 5733 3 5250 5733 5732 3 5251 5252 5734 3 5251 5734 5733 3 5252 5253 5735 3 5252 5735 5734 3 5253 5254 5735 3 5736 5735 5254 3 5254 5255 5736 3 5737 5736 5255 3 5255 5256 5737 3 5738 5737 5256 3 5256 5257 5738 3 5739 5738 5257 3 5257 5258 5739 3 5740 5739 5258 3 5258 5259 5740 3 5741 5740 5259 3 5259 5260 5741 3 5742 5741 5260 3 5260 5261 5742 3 5743 5742 5261 3 5261 5262 5743 3 5744 5743 5262 3 5262 5263 5744 3 5745 5744 5263 3 5263 5264 5745 3 5746 5745 5264 3 5264 5265 5746 3 5747 5746 5265 3 5265 5266 5747 3 5748 5747 5266 3 5266 5267 5748 3 5749 5748 5267 3 5267 5268 5749 3 5750 5749 5268 3 5268 5269 5750 3 5751 5750 5269 3 5269 5270 5751 3 5752 5751 5270 3 5270 5271 5752 3 5753 5752 5271 3 5271 5272 5753 3 5754 5753 5272 3 5272 5273 5754 3 5755 5754 5273 3 5273 5274 5755 3 5756 5755 5274 3 5274 5275 5756 3 5757 5756 5275 3 5275 5276 5757 3 5758 5757 5276 3 5276 5277 5758 3 5759 5758 5277 3 5277 5278 5759 3 5760 5759 5278 3 5278 5279 5760 3 5761 5760 5279 3 5279 5280 5761 3 5762 5761 5280 3 5280 5281 5762 3 5763 5762 5281 3 5281 5282 5763 3 5764 5763 5282 3 5282 5283 5764 3 5765 5764 5283 3 5283 5284 5765 3 5766 5765 5284 3 5284 5285 5766 3 5767 5766 5285 3 5285 5286 5767 3 5768 5767 5286 3 5286 5287 5768 3 5769 5768 5287 3 5287 5288 5769 3 5770 5769 5288 3 5288 5289 5770 3 5771 5770 5289 3 5289 5290 5771 3 5772 5771 5290 3 5290 5291 5772 3 5773 5772 5291 3 5291 5292 5773 3 5774 5773 5292 3 5292 5293 5774 3 5775 5774 5293 3 5293 5294 5775 3 5776 5775 5294 3 5294 5295 5776 3 5777 5776 5295 3 5295 5296 5777 3 5778 5777 5296 3 5296 5297 5778 3 5779 5778 5297 3 5297 5298 5779 3 5780 5779 5298 3 5298 5299 5781 3 5298 5781 5780 3 5299 5300 5782 3 5299 5782 5781 3 5301 5302 5369 3 5301 5369 5368 3 5301 5850 5851 3 5301 5851 5302 3 5301 5368 5919 3 5301 5919 5850 3 5302 5303 5370 3 5302 5370 5369 3 5302 5851 5852 3 5302 5852 5303 3 5303 5304 5371 3 5303 5371 5370 3 5303 5852 5853 3 5303 5853 5304 3 5304 5305 5372 3 5304 5372 5371 3 5304 5853 5305 3 5854 5305 5853 3 5305 5306 5373 3 5305 5373 5372 3 5305 5854 5306 3 5855 5306 5854 3 5306 5307 5374 3 5306 5374 5373 3 5306 5855 5307 3 5856 5307 5855 3 5307 5308 5375 3 5307 5375 5374 3 5307 5856 5308 3 5857 5308 5856 3 5308 5309 5376 3 5308 5376 5375 3 5308 5857 5309 3 5858 5309 5857 3 5309 5310 5377 3 5309 5377 5376 3 5309 5858 5310 3 5859 5310 5858 3 5310 5311 5378 3 5310 5378 5377 3 5310 5859 5311 3 5860 5311 5859 3 5311 5312 5379 3 5311 5379 5378 3 5311 5860 5312 3 5861 5312 5860 3 5312 5313 5380 3 5312 5380 5379 3 5312 5861 5313 3 5862 5313 5861 3 5313 5314 5381 3 5313 5381 5380 3 5313 5862 5314 3 5863 5314 5862 3 5314 5315 5382 3 5314 5382 5381 3 5314 5863 5315 3 5864 5315 5863 3 5315 5316 5383 3 5315 5383 5382 3 5315 5864 5316 3 5865 5316 5864 3 5316 5317 5384 3 5316 5384 5383 3 5316 5865 5317 3 5866 5317 5865 3 5317 5318 5385 3 5317 5385 5384 3 5317 5866 5318 3 5867 5318 5866 3 5318 5319 5386 3 5318 5386 5385 3 5318 5867 5319 3 5868 5319 5867 3 5319 5320 5387 3 5319 5387 5386 3 5319 5868 5320 3 5869 5320 5868 3 5320 5321 5388 3 5320 5388 5387 3 5320 5869 5321 3 5870 5321 5869 3 5321 5322 5389 3 5321 5389 5388 3 5321 5870 5322 3 5871 5322 5870 3 5322 5323 5390 3 5322 5390 5389 3 5322 5871 5323 3 5872 5323 5871 3 5323 5324 5391 3 5323 5391 5390 3 5323 5872 5324 3 5873 5324 5872 3 5324 5325 5392 3 5324 5392 5391 3 5324 5873 5325 3 5874 5325 5873 3 5325 5326 5393 3 5325 5393 5392 3 5325 5874 5326 3 5875 5326 5874 3 5326 5327 5394 3 5326 5394 5393 3 5326 5875 5327 3 5876 5327 5875 3 5327 5328 5395 3 5327 5395 5394 3 5327 5876 5328 3 5877 5328 5876 3 5328 5329 5396 3 5328 5396 5395 3 5328 5877 5329 3 5878 5329 5877 3 5329 5330 5397 3 5329 5397 5396 3 5329 5878 5330 3 5879 5330 5878 3 5330 5331 5398 3 5330 5398 5397 3 5330 5879 5331 3 5880 5331 5879 3 5331 5332 5399 3 5331 5399 5398 3 5331 5880 5332 3 5881 5332 5880 3 5332 5333 5400 3 5332 5400 5399 3 5332 5881 5333 3 5882 5333 5881 3 5333 5334 5401 3 5333 5401 5400 3 5333 5882 5334 3 5883 5334 5882 3 5334 5335 5402 3 5334 5402 5401 3 5334 5883 5335 3 5884 5335 5883 3 5335 5336 5403 3 5335 5403 5402 3 5335 5884 5336 3 5885 5336 5884 3 5336 5337 5404 3 5336 5404 5403 3 5336 5885 5337 3 5886 5337 5885 3 5337 5338 5405 3 5337 5405 5404 3 5337 5886 5338 3 5887 5338 5886 3 5338 5339 5406 3 5338 5406 5405 3 5338 5887 5339 3 5888 5339 5887 3 5339 5340 5407 3 5339 5407 5406 3 5339 5888 5340 3 5889 5340 5888 3 5340 5341 5408 3 5340 5408 5407 3 5340 5889 5341 3 5890 5341 5889 3 5341 5342 5409 3 5341 5409 5408 3 5341 5890 5342 3 5891 5342 5890 3 5342 5343 5410 3 5342 5410 5409 3 5342 5891 5343 3 5892 5343 5891 3 5343 5344 5410 3 5411 5410 5344 3 5343 5892 5344 3 5893 5344 5892 3 5344 5345 5411 3 5412 5411 5345 3 5344 5893 5345 3 5894 5345 5893 3 5345 5346 5412 3 5413 5412 5346 3 5345 5894 5346 3 5895 5346 5894 3 5346 5347 5413 3 5414 5413 5347 3 5346 5895 5347 3 5896 5347 5895 3 5347 5348 5414 3 5415 5414 5348 3 5347 5896 5348 3 5897 5348 5896 3 5348 5349 5415 3 5416 5415 5349 3 5348 5897 5349 3 5898 5349 5897 3 5349 5350 5416 3 5417 5416 5350 3 5349 5898 5350 3 5899 5350 5898 3 5350 5351 5417 3 5418 5417 5351 3 5350 5899 5900 3 5350 5900 5351 3 5351 5352 5418 3 5419 5418 5352 3 5351 5900 5901 3 5351 5901 5352 3 5352 5353 5419 3 5420 5419 5353 3 5352 5901 5902 3 5352 5902 5353 3 5353 5354 5420 3 5421 5420 5354 3 5353 5902 5903 3 5353 5903 5354 3 5354 5355 5421 3 5422 5421 5355 3 5354 5903 5904 3 5354 5904 5355 3 5355 5356 5422 3 5423 5422 5356 3 5355 5904 5905 3 5355 5905 5356 3 5356 5357 5423 3 5424 5423 5357 3 5356 5905 5906 3 5356 5906 5357 3 5357 5358 5424 3 5425 5424 5358 3 5357 5906 5907 3 5357 5907 5358 3 5358 5359 5425 3 5426 5425 5359 3 5358 5907 5908 3 5358 5908 5359 3 5359 5360 5426 3 5427 5426 5360 3 5359 5908 5909 3 5359 5909 5360 3 5360 5361 5427 3 5428 5427 5361 3 5360 5909 5910 3 5360 5910 5361 3 5361 5362 5428 3 5429 5428 5362 3 5361 5910 5911 3 5361 5911 5362 3 5362 5363 5429 3 5430 5429 5363 3 5362 5911 5912 3 5362 5912 5363 3 5363 5364 5430 3 5431 5430 5364 3 5363 5912 5913 3 5363 5913 5364 3 5364 5365 5431 3 5432 5431 5365 3 5364 5913 5914 3 5364 5914 5365 3 5365 5914 5920 3 5365 5920 5432 3 5366 5367 5436 3 5437 5436 5367 3 5366 5917 5918 3 5366 5918 5367 3 5366 5436 5925 3 5366 5925 5917 3 5367 5918 5919 3 5367 5919 5368 3 5432 5920 5433 3 5921 5433 5920 3 5433 5434 5438 3 5439 5438 5434 3 5433 5921 5434 3 5922 5434 5921 3 5434 5922 5439 3 5926 5439 5922 3 5435 5436 5441 3 5442 5441 5436 3 5435 5924 5436 3 5925 5436 5924 3 5435 5441 5924 3 5929 5924 5441 3 5439 5440 5443 3 5444 5443 5440 3 5439 5926 5440 3 5927 5440 5926 3 5440 5927 5444 3 5930 5444 5927 3 5441 5446 5929 3 5933 5929 5446 3 5444 5930 5447 3 5934 5447 5930 3 5445 5446 5449 3 5450 5449 5446 3 5445 5932 5446 3 5933 5446 5932 3 5445 5449 5932 3 5936 5932 5449 3 5447 5448 5451 3 5452 5451 5448 3 5447 5934 5448 3 5935 5448 5934 3 5448 5935 5452 3 5937 5452 5935 3 5449 5450 5453 3 5454 5453 5450 3 5449 5453 5936 3 5938 5936 5453 3 5451 5452 5455 3 5456 5455 5452 3 5452 5937 5456 3 5939 5456 5937 3 5453 5454 5457 3 5458 5457 5454 3 5453 5457 5938 3 5940 5938 5457 3 5455 5456 5459 3 5460 5459 5456 3 5456 5939 5460 3 5941 5460 5939 3 5457 5458 5461 3 5462 5461 5458 3 5457 5461 5940 3 5942 5940 5461 3 5459 5460 5463 3 5464 5463 5460 3 5460 5941 5464 3 5943 5464 5941 3 5461 5462 5465 3 5466 5465 5462 3 5461 5465 5942 3 5944 5942 5465 3 5463 5464 5467 3 5468 5467 5464 3 5464 5943 5468 3 5945 5468 5943 3 5465 5466 5469 3 5470 5469 5466 3 5465 5469 5944 3 5946 5944 5469 3 5467 5468 5471 3 5472 5471 5468 3 5468 5945 5472 3 5947 5472 5945 3 5469 5470 5473 3 5474 5473 5470 3 5469 5473 5946 3 5948 5946 5473 3 5471 5472 5475 3 5476 5475 5472 3 5472 5947 5476 3 5949 5476 5947 3 5473 5474 5477 3 5478 5477 5474 3 5473 5477 5948 3 5950 5948 5477 3 5475 5476 5479 3 5480 5479 5476 3 5476 5949 5480 3 5951 5480 5949 3 5477 5478 5481 3 5482 5481 5478 3 5477 5481 5952 3 5477 5952 5950 3 5479 5480 5484 3 5479 5484 5483 3 5480 5951 5484 3 5953 5484 5951 3 5481 5482 5486 3 5481 5486 5485 3 5481 5485 5954 3 5481 5954 5952 3 5483 5484 5488 3 5483 5488 5487 3 5484 5953 5488 3 5955 5488 5953 3 5485 5486 5490 3 5485 5490 5489 3 5485 5489 5956 3 5485 5956 5954 3 5487 5488 5492 3 5487 5492 5491 3 5488 5955 5492 3 5957 5492 5955 3 5489 5490 5494 3 5489 5494 5493 3 5489 5493 5958 3 5489 5958 5956 3 5491 5492 5496 3 5491 5496 5495 3 5492 5957 5959 3 5492 5959 5496 3 5493 5494 5498 3 5493 5498 5497 3 5493 5497 5960 3 5493 5960 5958 3 5495 5496 5500 3 5495 5500 5499 3 5496 5959 5961 3 5496 5961 5500 3 5497 5498 5502 3 5497 5502 5501 3 5497 5501 5962 3 5497 5962 5960 3 5499 5500 5504 3 5499 5504 5503 3 5500 5961 5963 3 5500 5963 5504 3 5501 5502 5506 3 5501 5506 5505 3 5501 5505 5964 3 5501 5964 5962 3 5503 5504 5508 3 5503 5508 5507 3 5504 5963 5965 3 5504 5965 5508 3 5505 5506 5510 3 5505 5510 5509 3 5505 5509 5966 3 5505 5966 5964 3 5507 5508 5512 3 5507 5512 5511 3 5508 5965 5967 3 5508 5967 5512 3 5509 5510 5514 3 5509 5514 5513 3 5509 5513 5968 3 5509 5968 5966 3 5511 5512 5516 3 5511 5516 5515 3 5512 5967 5969 3 5512 5969 5516 3 5513 5514 5518 3 5513 5518 5517 3 5513 5517 5970 3 5513 5970 5968 3 5515 5516 5520 3 5515 5520 5519 3 5516 5969 5971 3 5516 5971 5520 3 5517 5518 5522 3 5517 5522 5521 3 5517 5521 5972 3 5517 5972 5970 3 5519 5520 5524 3 5519 5524 5523 3 5520 5971 5973 3 5520 5973 5524 3 5521 5522 5526 3 5521 5526 5525 3 5521 5525 5974 3 5521 5974 5972 3 5523 5524 5528 3 5523 5528 5527 3 5524 5973 5975 3 5524 5975 5528 3 5525 5526 5529 3 5530 5529 5526 3 5525 5529 5974 3 5976 5974 5529 3 5527 5528 5531 3 5532 5531 5528 3 5528 5975 5977 3 5528 5977 5532 3 5529 5530 5533 3 5534 5533 5530 3 5529 5533 5976 3 5978 5976 5533 3 5531 5532 5535 3 5536 5535 5532 3 5532 5977 5979 3 5532 5979 5536 3 5533 5534 5537 3 5538 5537 5534 3 5533 5537 5978 3 5980 5978 5537 3 5535 5536 5539 3 5540 5539 5536 3 5536 5979 5981 3 5536 5981 5540 3 5537 5538 5541 3 5542 5541 5538 3 5537 5541 5980 3 5982 5980 5541 3 5539 5540 5543 3 5544 5543 5540 3 5540 5981 5983 3 5540 5983 5544 3 5541 5542 5545 3 5546 5545 5542 3 5541 5545 5982 3 5984 5982 5545 3 5543 5544 5547 3 5548 5547 5544 3 5544 5983 5985 3 5544 5985 5548 3 5545 5546 5549 3 5550 5549 5546 3 5545 5549 5984 3 5986 5984 5549 3 5547 5548 5551 3 5552 5551 5548 3 5548 5985 5987 3 5548 5987 5552 3 5549 5550 5553 3 5554 5553 5550 3 5549 5553 5986 3 5988 5986 5553 3 5551 5552 5555 3 5556 5555 5552 3 5552 5987 5989 3 5552 5989 5556 3 5553 5554 5557 3 5558 5557 5554 3 5553 5557 5988 3 5990 5988 5557 3 5555 5556 5559 3 5560 5559 5556 3 5556 5989 5560 3 5991 5560 5989 3 5557 5558 5561 3 5562 5561 5558 3 5557 5561 5990 3 5992 5990 5561 3 5559 5560 5563 3 5564 5563 5560 3 5560 5991 5564 3 5993 5564 5991 3 5561 5562 5565 3 5566 5565 5562 3 5561 5565 5992 3 5994 5992 5565 3 5563 5564 5567 3 5568 5567 5564 3 5564 5993 5568 3 5995 5568 5993 3 5565 5566 5569 3 5570 5569 5566 3 5565 5569 5994 3 5996 5994 5569 3 5567 5568 5571 3 5572 5571 5568 3 5568 5995 5572 3 5997 5572 5995 3 5569 5570 5573 3 5574 5573 5570 3 5569 5573 5998 3 5569 5998 5996 3 5571 5572 5576 3 5571 5576 5575 3 5572 5997 5576 3 5999 5576 5997 3 5573 5574 5578 3 5573 5578 5577 3 5573 5577 6000 3 5573 6000 5998 3 5575 5576 5580 3 5575 5580 5579 3 5576 5999 5580 3 6001 5580 5999 3 5577 5578 5582 3 5577 5582 5581 3 5577 5581 6002 3 5577 6002 6000 3 5579 5580 5584 3 5579 5584 5583 3 5580 6001 5584 3 6003 5584 6001 3 5581 5582 5586 3 5581 5586 5585 3 5581 5585 6004 3 5581 6004 6002 3 5583 5584 5588 3 5583 5588 5587 3 5584 6003 5588 3 6005 5588 6003 3 5585 5586 5590 3 5585 5590 5589 3 5585 5589 6006 3 5585 6006 6004 3 5587 5588 5592 3 5587 5592 5591 3 5588 6005 5592 3 6007 5592 6005 3 5589 5590 5594 3 5589 5594 5593 3 5589 5593 6008 3 5589 6008 6006 3 5591 5592 5596 3 5591 5596 5595 3 5592 6007 5596 3 6009 5596 6007 3 5593 5594 5598 3 5593 5598 5597 3 5593 5597 6010 3 5593 6010 6008 3 5595 5596 5600 3 5595 5600 5599 3 5596 6009 5600 3 6011 5600 6009 3 5597 5598 5602 3 5597 5602 5601 3 5597 5601 6012 3 5597 6012 6010 3 5599 5600 5604 3 5599 5604 5603 3 5600 6011 5604 3 6013 5604 6011 3 5601 5602 5606 3 5601 5606 5605 3 5601 5605 6014 3 5601 6014 6012 3 5603 5604 5608 3 5603 5608 5607 3 5604 6013 5608 3 6015 5608 6013 3 5605 5606 5610 3 5605 5610 5609 3 5605 5609 6016 3 5605 6016 6014 3 5607 5608 5612 3 5607 5612 5611 3 5608 6015 5612 3 6017 5612 6015 3 5609 5610 5614 3 5609 5614 5613 3 5609 5613 6018 3 5609 6018 6016 3 5611 5612 5616 3 5611 5616 5615 3 5612 6017 5616 3 6019 5616 6017 3 5613 5614 5618 3 5613 5618 5617 3 5613 5617 6020 3 5613 6020 6018 3 5615 5616 5620 3 5615 5620 5619 3 5616 6019 5620 3 6021 5620 6019 3 5617 5618 5621 3 5622 5621 5618 3 5617 5621 6020 3 6022 6020 5621 3 5619 5620 5623 3 5624 5623 5620 3 5620 6021 6023 3 5620 6023 5624 3 5621 5622 5625 3 5626 5625 5622 3 5621 5625 6022 3 6024 6022 5625 3 5623 5624 5627 3 5628 5627 5624 3 5624 6023 6025 3 5624 6025 5628 3 5625 5626 5629 3 5630 5629 5626 3 5625 5629 6024 3 6026 6024 5629 3 5627 5628 5631 3 5632 5631 5628 3 5628 6025 6027 3 5628 6027 5632 3 5629 5630 5633 3 5634 5633 5630 3 5629 5633 6026 3 6028 6026 5633 3 5631 5632 5635 3 5636 5635 5632 3 5632 6027 6029 3 5632 6029 5636 3 5633 5634 5637 3 5638 5637 5634 3 5633 5637 6028 3 6030 6028 5637 3 5635 5636 5639 3 5640 5639 5636 3 5636 6029 6031 3 5636 6031 5640 3 5637 5638 5641 3 5642 5641 5638 3 5637 5641 6030 3 6032 6030 5641 3 5639 5640 5643 3 5644 5643 5640 3 5640 6031 6033 3 5640 6033 5644 3 5641 5642 5645 3 5646 5645 5642 3 5641 5645 6032 3 6034 6032 5645 3 5643 5644 5647 3 5648 5647 5644 3 5644 6033 6035 3 5644 6035 5648 3 5645 5646 5649 3 5650 5649 5646 3 5645 5649 6034 3 6036 6034 5649 3 5647 5648 5651 3 5652 5651 5648 3 5648 6035 6037 3 5648 6037 5652 3 5649 5650 5653 3 5654 5653 5650 3 5649 5653 6036 3 6038 6036 5653 3 5651 5652 5655 3 5656 5655 5652 3 5652 6037 6039 3 5652 6039 5656 3 5653 5654 5657 3 5658 5657 5654 3 5653 5657 6038 3 6040 6038 5657 3 5655 5656 5659 3 5660 5659 5656 3 5656 6039 6041 3 5656 6041 5660 3 5657 5658 5661 3 5662 5661 5658 3 5657 5661 6040 3 6042 6040 5661 3 5659 5660 5663 3 5664 5663 5660 3 5660 6041 6043 3 5660 6043 5664 3 5661 5662 5665 3 5666 5665 5662 3 5661 5665 6044 3 5661 6044 6042 3 5663 5664 5668 3 5663 5668 5667 3 5664 6043 6045 3 5664 6045 5668 3 5665 5666 5670 3 5665 5670 5669 3 5665 5669 6046 3 5665 6046 6044 3 5667 5668 5672 3 5667 5672 5671 3 5668 6045 6047 3 5668 6047 5672 3 5669 5670 5674 3 5669 5674 5673 3 5669 5673 6048 3 5669 6048 6046 3 5671 5672 5676 3 5671 5676 5675 3 5672 6047 6049 3 5672 6049 5676 3 5673 5674 5678 3 5673 5678 5677 3 5673 5677 6050 3 5673 6050 6048 3 5675 5676 5680 3 5675 5680 5679 3 5676 6049 6051 3 5676 6051 5680 3 5677 5678 5682 3 5677 5682 5681 3 5677 5681 6052 3 5677 6052 6050 3 5679 5680 5684 3 5679 5684 5683 3 5680 6051 6053 3 5680 6053 5684 3 5681 5682 5686 3 5681 5686 5685 3 5681 5685 6054 3 5681 6054 6052 3 5683 5684 5688 3 5683 5688 5687 3 5684 6053 6055 3 5684 6055 5688 3 5685 5686 5690 3 5685 5690 5689 3 5685 5689 6056 3 5685 6056 6054 3 5687 5688 5692 3 5687 5692 5691 3 5688 6055 5692 3 6057 5692 6055 3 5689 5690 5694 3 5689 5694 5693 3 5689 5693 6058 3 5689 6058 6056 3 5691 5692 5696 3 5691 5696 5695 3 5692 6057 5696 3 6059 5696 6057 3 5693 5694 5698 3 5693 5698 5697 3 5693 5697 6060 3 5693 6060 6058 3 5695 5696 5700 3 5695 5700 5699 3 5696 6059 5700 3 6061 5700 6059 3 5697 5698 5702 3 5697 5702 5701 3 5697 5701 6062 3 5697 6062 6060 3 5699 5700 5704 3 5699 5704 5703 3 5700 6061 5704 3 6065 5704 6061 3 5701 5702 6063 3 5701 6063 6062 3 5702 5705 6067 3 5702 6067 6063 3 5703 5704 6065 3 5703 6065 6064 3 5703 6064 5708 3 6068 5708 6064 3 5705 5706 5710 3 5705 5710 5709 3 5705 5709 6070 3 5705 6070 6067 3 5707 5708 5714 3 5707 5714 5713 3 5708 6068 5714 3 6073 5714 6068 3 5709 5710 6070 3 6071 6070 5710 3 5710 5711 5715 3 5716 5715 5711 3 5710 5715 6071 3 6075 6071 5715 3 5712 5713 5782 3 5783 5782 5713 3 5713 5714 6072 3 6073 6072 5714 3 5713 6072 5783 3 6080 5783 6072 3 5715 5716 6075 3 6076 6075 5716 3 5716 5717 6076 3 6077 6076 5717 3 5717 5718 5784 3 5785 5784 5718 3 5717 5784 6083 3 5717 6083 6077 3 5718 5719 5785 3 5786 5785 5719 3 5719 5720 5786 3 5787 5786 5720 3 5720 5721 5787 3 5788 5787 5721 3 5721 5722 5788 3 5789 5788 5722 3 5722 5723 5789 3 5790 5789 5723 3 5723 5724 5790 3 5791 5790 5724 3 5724 5725 5791 3 5792 5791 5725 3 5725 5726 5792 3 5793 5792 5726 3 5726 5727 5793 3 5794 5793 5727 3 5727 5728 5794 3 5795 5794 5728 3 5728 5729 5795 3 5796 5795 5729 3 5729 5730 5796 3 5797 5796 5730 3 5730 5731 5797 3 5798 5797 5731 3 5731 5732 5798 3 5799 5798 5732 3 5732 5733 5799 3 5800 5799 5733 3 5733 5734 5800 3 5801 5800 5734 3 5734 5735 5801 3 5802 5801 5735 3 5735 5736 5802 3 5803 5802 5736 3 5736 5737 5803 3 5804 5803 5737 3 5737 5738 5804 3 5805 5804 5738 3 5738 5739 5805 3 5806 5805 5739 3 5739 5740 5806 3 5807 5806 5740 3 5740 5741 5807 3 5808 5807 5741 3 5741 5742 5808 3 5809 5808 5742 3 5742 5743 5809 3 5810 5809 5743 3 5743 5744 5810 3 5811 5810 5744 3 5744 5745 5811 3 5812 5811 5745 3 5745 5746 5812 3 5813 5812 5746 3 5746 5747 5813 3 5814 5813 5747 3 5747 5748 5814 3 5815 5814 5748 3 5748 5749 5815 3 5816 5815 5749 3 5749 5750 5816 3 5817 5816 5750 3 5750 5751 5817 3 5818 5817 5751 3 5751 5752 5818 3 5819 5818 5752 3 5752 5753 5819 3 5820 5819 5753 3 5753 5754 5820 3 5821 5820 5754 3 5754 5755 5821 3 5822 5821 5755 3 5755 5756 5823 3 5755 5823 5822 3 5756 5757 5824 3 5756 5824 5823 3 5757 5758 5825 3 5757 5825 5824 3 5758 5759 5826 3 5758 5826 5825 3 5759 5760 5827 3 5759 5827 5826 3 5760 5761 5828 3 5760 5828 5827 3 5761 5762 5829 3 5761 5829 5828 3 5762 5763 5830 3 5762 5830 5829 3 5763 5764 5831 3 5763 5831 5830 3 5764 5765 5832 3 5764 5832 5831 3 5765 5766 5833 3 5765 5833 5832 3 5766 5767 5834 3 5766 5834 5833 3 5767 5768 5835 3 5767 5835 5834 3 5768 5769 5836 3 5768 5836 5835 3 5769 5770 5837 3 5769 5837 5836 3 5770 5771 5838 3 5770 5838 5837 3 5771 5772 5839 3 5771 5839 5838 3 5772 5773 5840 3 5772 5840 5839 3 5773 5774 5841 3 5773 5841 5840 3 5774 5775 5842 3 5774 5842 5841 3 5775 5776 5843 3 5775 5843 5842 3 5776 5777 5844 3 5776 5844 5843 3 5777 5778 5845 3 5777 5845 5844 3 5778 5779 5846 3 5778 5846 5845 3 5779 5780 5847 3 5779 5847 5846 3 5780 5781 5848 3 5780 5848 5847 3 5781 5782 6079 3 5781 6079 6078 3 5781 6078 6147 3 5781 6147 5848 3 5782 5783 6080 3 5782 6080 6079 3 5784 5785 6084 3 5784 6084 6083 3 5785 5786 6085 3 5785 6085 6084 3 5786 5787 6086 3 5786 6086 6085 3 5787 5788 6087 3 5787 6087 6086 3 5788 5789 6088 3 5788 6088 6087 3 5789 5790 6089 3 5789 6089 6088 3 5790 5791 6090 3 5790 6090 6089 3 5791 5792 6091 3 5791 6091 6090 3 5792 5793 6092 3 5792 6092 6091 3 5793 5794 6093 3 5793 6093 6092 3 5794 5795 6094 3 5794 6094 6093 3 5795 5796 6095 3 5795 6095 6094 3 5796 5797 6096 3 5796 6096 6095 3 5797 5798 6097 3 5797 6097 6096 3 5798 5799 6098 3 5798 6098 6097 3 5799 5800 6099 3 5799 6099 6098 3 5800 5801 6100 3 5800 6100 6099 3 5801 5802 6101 3 5801 6101 6100 3 5802 5803 6101 3 6102 6101 5803 3 5803 5804 6102 3 6103 6102 5804 3 5804 5805 6103 3 6104 6103 5805 3 5805 5806 6104 3 6105 6104 5806 3 5806 5807 6105 3 6106 6105 5807 3 5807 5808 6106 3 6107 6106 5808 3 5808 5809 6107 3 6108 6107 5809 3 5809 5810 6108 3 6109 6108 5810 3 5810 5811 6109 3 6110 6109 5811 3 5811 5812 6110 3 6111 6110 5812 3 5812 5813 6111 3 6112 6111 5813 3 5813 5814 6112 3 6113 6112 5814 3 5814 5815 6113 3 6114 6113 5815 3 5815 5816 6114 3 6115 6114 5816 3 5816 5817 6115 3 6116 6115 5817 3 5817 5818 6116 3 6117 6116 5818 3 5818 5819 6117 3 6118 6117 5819 3 5819 5820 6118 3 6119 6118 5820 3 5820 5821 6119 3 6120 6119 5821 3 5821 5822 6120 3 6121 6120 5822 3 5822 5823 6121 3 6122 6121 5823 3 5823 5824 6122 3 6123 6122 5824 3 5824 5825 6123 3 6124 6123 5825 3 5825 5826 6124 3 6125 6124 5826 3 5826 5827 6125 3 6126 6125 5827 3 5827 5828 6126 3 6127 6126 5828 3 5828 5829 6127 3 6128 6127 5829 3 5829 5830 6128 3 6129 6128 5830 3 5830 5831 6129 3 6130 6129 5831 3 5831 5832 6130 3 6131 6130 5832 3 5832 5833 6131 3 6132 6131 5833 3 5833 5834 6132 3 6133 6132 5834 3 5834 5835 6133 3 6134 6133 5835 3 5835 5836 6134 3 6135 6134 5836 3 5836 5837 6135 3 6136 6135 5837 3 5837 5838 6136 3 6137 6136 5838 3 5838 5839 6137 3 6138 6137 5839 3 5839 5840 6138 3 6139 6138 5840 3 5840 5841 6139 3 6140 6139 5841 3 5841 5842 6140 3 6141 6140 5842 3 5842 5843 6141 3 6142 6141 5843 3 5843 5844 6142 3 6143 6142 5844 3 5844 5845 6143 3 6144 6143 5845 3 5845 5846 6144 3 6145 6144 5846 3 5846 5847 6145 3 6146 6145 5847 3 5847 5848 6146 3 6147 6146 5848 3 5849 5850 5919 3 5849 5919 5918 3 5849 6150 5850 3 6151 5850 6150 3 5849 5918 6220 3 5849 6220 6150 3 5850 6151 5851 3 6152 5851 6151 3 5851 6152 5852 3 6153 5852 6152 3 5852 6153 5853 3 6154 5853 6153 3 5853 6154 5854 3 6155 5854 6154 3 5854 6155 5855 3 6156 5855 6155 3 5855 6156 5856 3 6157 5856 6156 3 5856 6157 5857 3 6158 5857 6157 3 5857 6158 5858 3 6159 5858 6158 3 5858 6159 5859 3 6160 5859 6159 3 5859 6160 5860 3 6161 5860 6160 3 5860 6161 5861 3 6162 5861 6161 3 5861 6162 5862 3 6163 5862 6162 3 5862 6163 5863 3 6164 5863 6163 3 5863 6164 5864 3 6165 5864 6164 3 5864 6165 5865 3 6166 5865 6165 3 5865 6166 5866 3 6167 5866 6166 3 5866 6167 5867 3 6168 5867 6167 3 5867 6168 6169 3 5867 6169 5868 3 5868 6169 6170 3 5868 6170 5869 3 5869 6170 6171 3 5869 6171 5870 3 5870 6171 6172 3 5870 6172 5871 3 5871 6172 6173 3 5871 6173 5872 3 5872 6173 6174 3 5872 6174 5873 3 5873 6174 6175 3 5873 6175 5874 3 5874 6175 6176 3 5874 6176 5875 3 5875 6176 6177 3 5875 6177 5876 3 5876 6177 6178 3 5876 6178 5877 3 5877 6178 6179 3 5877 6179 5878 3 5878 6179 6180 3 5878 6180 5879 3 5879 6180 6181 3 5879 6181 5880 3 5880 6181 6182 3 5880 6182 5881 3 5881 6182 6183 3 5881 6183 5882 3 5882 6183 6184 3 5882 6184 5883 3 5883 6184 6185 3 5883 6185 5884 3 5884 6185 6186 3 5884 6186 5885 3 5885 6186 6187 3 5885 6187 5886 3 5886 6187 6188 3 5886 6188 5887 3 5887 6188 6189 3 5887 6189 5888 3 5888 6189 6190 3 5888 6190 5889 3 5889 6190 6191 3 5889 6191 5890 3 5890 6191 6192 3 5890 6192 5891 3 5891 6192 6193 3 5891 6193 5892 3 5892 6193 6194 3 5892 6194 5893 3 5893 6194 6195 3 5893 6195 5894 3 5894 6195 6196 3 5894 6196 5895 3 5895 6196 6197 3 5895 6197 5896 3 5896 6197 6198 3 5896 6198 5897 3 5897 6198 6199 3 5897 6199 5898 3 5898 6199 6200 3 5898 6200 5899 3 5899 6200 6201 3 5899 6201 5900 3 5900 6201 6202 3 5900 6202 5901 3 5901 6202 6203 3 5901 6203 5902 3 5902 6203 6204 3 5902 6204 5903 3 5903 6204 6205 3 5903 6205 5904 3 5904 6205 6206 3 5904 6206 5905 3 5905 6206 6207 3 5905 6207 5906 3 5906 6207 6208 3 5906 6208 5907 3 5907 6208 6209 3 5907 6209 5908 3 5908 6209 6210 3 5908 6210 5909 3 5909 6210 6211 3 5909 6211 5910 3 5910 6211 6212 3 5910 6212 5911 3 5911 6212 6213 3 5911 6213 5912 3 5912 6213 6214 3 5912 6214 5913 3 5913 6214 6215 3 5913 6215 5914 3 5914 5915 5920 3 5921 5920 5915 3 5914 6215 6216 3 5914 6216 5915 3 5915 6216 5921 3 6221 5921 6216 3 5916 5917 5924 3 5925 5924 5917 3 5916 6218 5917 3 6219 5917 6218 3 5916 5924 6218 3 6225 6218 5924 3 5917 6219 5918 3 6220 5918 6219 3 5921 6221 5922 3 6222 5922 6221 3 5922 5923 5926 3 5927 5926 5923 3 5922 6222 5923 3 6223 5923 6222 3 5923 6223 5927 3 6226 5927 6223 3 5924 5929 6225 3 6229 6225 5929 3 5927 6226 5930 3 6230 5930 6226 3 5928 5929 5932 3 5933 5932 5929 3 5928 6228 5929 3 6229 5929 6228 3 5928 5932 6228 3 6232 6228 5932 3 5930 5931 5934 3 5935 5934 5931 3 5930 6230 5931 3 6231 5931 6230 3 5931 6231 5935 3 6233 5935 6231 3 5932 5936 6232 3 6234 6232 5936 3 5935 6233 5937 3 6235 5937 6233 3 5936 5938 6234 3 6236 6234 5938 3 5937 6235 5939 3 6237 5939 6235 3 5938 5940 6236 3 6238 6236 5940 3 5939 6237 5941 3 6239 5941 6237 3 5940 5942 6238 3 6240 6238 5942 3 5941 6239 5943 3 6241 5943 6239 3 5942 5944 6240 3 6242 6240 5944 3 5943 6241 5945 3 6243 5945 6241 3 5944 5946 6244 3 5944 6244 6242 3 5945 6243 5947 3 6245 5947 6243 3 5946 5948 6246 3 5946 6246 6244 3 5947 6245 5949 3 6247 5949 6245 3 5948 5950 6248 3 5948 6248 6246 3 5949 6247 5951 3 6249 5951 6247 3 5950 5952 6250 3 5950 6250 6248 3 5951 6249 5953 3 6251 5953 6249 3 5952 5954 6252 3 5952 6252 6250 3 5953 6251 5955 3 6253 5955 6251 3 5954 5956 6254 3 5954 6254 6252 3 5955 6253 5957 3 6255 5957 6253 3 5956 5958 6256 3 5956 6256 6254 3 5957 6255 5959 3 6257 5959 6255 3 5958 5960 6258 3 5958 6258 6256 3 5959 6257 5961 3 6259 5961 6257 3 5960 5962 6260 3 5960 6260 6258 3 5961 6259 5963 3 6261 5963 6259 3 5962 5964 6262 3 5962 6262 6260 3 5963 6261 5965 3 6263 5965 6261 3 5964 5966 6264 3 5964 6264 6262 3 5965 6263 6265 3 5965 6265 5967 3 5966 5968 6266 3 5966 6266 6264 3 5967 6265 6267 3 5967 6267 5969 3 5968 5970 6268 3 5968 6268 6266 3 5969 6267 6269 3 5969 6269 5971 3 5970 5972 6270 3 5970 6270 6268 3 5971 6269 6271 3 5971 6271 5973 3 5972 5974 6272 3 5972 6272 6270 3 5973 6271 6273 3 5973 6273 5975 3 5974 5976 6274 3 5974 6274 6272 3 5975 6273 6275 3 5975 6275 5977 3 5976 5978 6276 3 5976 6276 6274 3 5977 6275 6277 3 5977 6277 5979 3 5978 5980 6278 3 5978 6278 6276 3 5979 6277 6279 3 5979 6279 5981 3 5980 5982 6280 3 5980 6280 6278 3 5981 6279 6281 3 5981 6281 5983 3 5982 5984 6282 3 5982 6282 6280 3 5983 6281 6283 3 5983 6283 5985 3 5984 5986 6284 3 5984 6284 6282 3 5985 6283 6285 3 5985 6285 5987 3 5986 5988 6286 3 5986 6286 6284 3 5987 6285 6287 3 5987 6287 5989 3 5988 5990 6288 3 5988 6288 6286 3 5989 6287 6289 3 5989 6289 5991 3 5990 5992 6290 3 5990 6290 6288 3 5991 6289 6291 3 5991 6291 5993 3 5992 5994 6290 3 6292 6290 5994 3 5993 6291 6293 3 5993 6293 5995 3 5994 5996 6292 3 6294 6292 5996 3 5995 6293 6295 3 5995 6295 5997 3 5996 5998 6294 3 6296 6294 5998 3 5997 6295 6297 3 5997 6297 5999 3 5998 6000 6296 3 6298 6296 6000 3 5999 6297 6299 3 5999 6299 6001 3 6000 6002 6298 3 6300 6298 6002 3 6001 6299 6301 3 6001 6301 6003 3 6002 6004 6300 3 6302 6300 6004 3 6003 6301 6303 3 6003 6303 6005 3 6004 6006 6302 3 6304 6302 6006 3 6005 6303 6305 3 6005 6305 6007 3 6006 6008 6304 3 6306 6304 6008 3 6007 6305 6307 3 6007 6307 6009 3 6008 6010 6306 3 6308 6306 6010 3 6009 6307 6309 3 6009 6309 6011 3 6010 6012 6308 3 6310 6308 6012 3 6011 6309 6311 3 6011 6311 6013 3 6012 6014 6310 3 6312 6310 6014 3 6013 6311 6015 3 6313 6015 6311 3 6014 6016 6312 3 6314 6312 6016 3 6015 6313 6017 3 6315 6017 6313 3 6016 6018 6314 3 6316 6314 6018 3 6017 6315 6019 3 6317 6019 6315 3 6018 6020 6316 3 6318 6316 6020 3 6019 6317 6021 3 6319 6021 6317 3 6020 6022 6318 3 6320 6318 6022 3 6021 6319 6023 3 6321 6023 6319 3 6022 6024 6320 3 6322 6320 6024 3 6023 6321 6025 3 6323 6025 6321 3 6024 6026 6322 3 6324 6322 6026 3 6025 6323 6027 3 6325 6027 6323 3 6026 6028 6324 3 6326 6324 6028 3 6027 6325 6029 3 6327 6029 6325 3 6028 6030 6326 3 6328 6326 6030 3 6029 6327 6031 3 6329 6031 6327 3 6030 6032 6328 3 6330 6328 6032 3 6031 6329 6033 3 6331 6033 6329 3 6032 6034 6330 3 6332 6330 6034 3 6033 6331 6035 3 6333 6035 6331 3 6034 6036 6332 3 6334 6332 6036 3 6035 6333 6037 3 6335 6037 6333 3 6036 6038 6334 3 6336 6334 6038 3 6037 6335 6039 3 6337 6039 6335 3 6038 6040 6338 3 6038 6338 6336 3 6039 6337 6041 3 6339 6041 6337 3 6040 6042 6340 3 6040 6340 6338 3 6041 6339 6043 3 6341 6043 6339 3 6042 6044 6342 3 6042 6342 6340 3 6043 6341 6045 3 6343 6045 6341 3 6044 6046 6344 3 6044 6344 6342 3 6045 6343 6047 3 6345 6047 6343 3 6046 6048 6346 3 6046 6346 6344 3 6047 6345 6049 3 6347 6049 6345 3 6048 6050 6348 3 6048 6348 6346 3 6049 6347 6051 3 6349 6051 6347 3 6050 6052 6350 3 6050 6350 6348 3 6051 6349 6053 3 6351 6053 6349 3 6052 6054 6352 3 6052 6352 6350 3 6053 6351 6055 3 6353 6055 6351 3 6054 6056 6354 3 6054 6354 6352 3 6055 6353 6057 3 6355 6057 6353 3 6056 6058 6356 3 6056 6356 6354 3 6057 6355 6059 3 6357 6059 6355 3 6058 6060 6358 3 6058 6358 6356 3 6059 6357 6061 3 6359 6061 6357 3 6060 6062 6360 3 6060 6360 6358 3 6061 6359 6065 3 6361 6065 6359 3 6062 6063 6067 3 6062 6067 6066 3 6062 6066 6362 3 6062 6362 6360 3 6064 6065 6069 3 6064 6069 6068 3 6065 6361 6365 3 6065 6365 6069 3 6066 6067 6363 3 6066 6363 6362 3 6067 6070 6367 3 6067 6367 6363 3 6068 6069 6365 3 6068 6365 6364 3 6068 6364 6368 3 6068 6368 6073 3 6070 6071 6075 3 6070 6075 6074 3 6070 6074 6370 3 6070 6370 6367 3 6072 6073 6081 3 6072 6081 6080 3 6073 6368 6375 3 6073 6375 6081 3 6074 6075 6371 3 6074 6371 6370 3 6075 6076 6372 3 6075 6372 6371 3 6076 6077 6083 3 6076 6083 6082 3 6076 6082 6377 3 6076 6377 6372 3 6078 6079 6148 3 6078 6148 6147 3 6079 6080 6374 3 6079 6374 6373 3 6079 6373 6443 3 6079 6443 6148 3 6080 6081 6375 3 6080 6375 6374 3 6082 6083 6378 3 6082 6378 6377 3 6083 6084 6379 3 6083 6379 6378 3 6084 6085 6380 3 6084 6380 6379 3 6085 6086 6381 3 6085 6381 6380 3 6086 6087 6382 3 6086 6382 6381 3 6087 6088 6382 3 6383 6382 6088 3 6088 6089 6383 3 6384 6383 6089 3 6089 6090 6384 3 6385 6384 6090 3 6090 6091 6385 3 6386 6385 6091 3 6091 6092 6386 3 6387 6386 6092 3 6092 6093 6387 3 6388 6387 6093 3 6093 6094 6388 3 6389 6388 6094 3 6094 6095 6389 3 6390 6389 6095 3 6095 6096 6390 3 6391 6390 6096 3 6096 6097 6391 3 6392 6391 6097 3 6097 6098 6392 3 6393 6392 6098 3 6098 6099 6393 3 6394 6393 6099 3 6099 6100 6394 3 6395 6394 6100 3 6100 6101 6395 3 6396 6395 6101 3 6101 6102 6396 3 6397 6396 6102 3 6102 6103 6397 3 6398 6397 6103 3 6103 6104 6398 3 6399 6398 6104 3 6104 6105 6399 3 6400 6399 6105 3 6105 6106 6400 3 6401 6400 6106 3 6106 6107 6401 3 6402 6401 6107 3 6107 6108 6402 3 6403 6402 6108 3 6108 6109 6403 3 6404 6403 6109 3 6109 6110 6404 3 6405 6404 6110 3 6110 6111 6405 3 6406 6405 6111 3 6111 6112 6406 3 6407 6406 6112 3 6112 6113 6407 3 6408 6407 6113 3 6113 6114 6408 3 6409 6408 6114 3 6114 6115 6409 3 6410 6409 6115 3 6115 6116 6410 3 6411 6410 6116 3 6116 6117 6411 3 6412 6411 6117 3 6117 6118 6412 3 6413 6412 6118 3 6118 6119 6413 3 6414 6413 6119 3 6119 6120 6414 3 6415 6414 6120 3 6120 6121 6415 3 6416 6415 6121 3 6121 6122 6416 3 6417 6416 6122 3 6122 6123 6417 3 6418 6417 6123 3 6123 6124 6418 3 6419 6418 6124 3 6124 6125 6419 3 6420 6419 6125 3 6125 6126 6420 3 6421 6420 6126 3 6126 6127 6421 3 6422 6421 6127 3 6127 6128 6422 3 6423 6422 6128 3 6128 6129 6423 3 6424 6423 6129 3 6129 6130 6424 3 6425 6424 6130 3 6130 6131 6425 3 6426 6425 6131 3 6131 6132 6426 3 6427 6426 6132 3 6132 6133 6427 3 6428 6427 6133 3 6133 6134 6428 3 6429 6428 6134 3 6134 6135 6429 3 6430 6429 6135 3 6135 6136 6431 3 6135 6431 6430 3 6136 6137 6432 3 6136 6432 6431 3 6137 6138 6433 3 6137 6433 6432 3 6138 6139 6434 3 6138 6434 6433 3 6139 6140 6435 3 6139 6435 6434 3 6140 6141 6436 3 6140 6436 6435 3 6141 6142 6437 3 6141 6437 6436 3 6142 6143 6438 3 6142 6438 6437 3 6143 6144 6439 3 6143 6439 6438 3 6144 6145 6440 3 6144 6440 6439 3 6145 6146 6441 3 6145 6441 6440 3 6146 6147 6442 3 6146 6442 6441 3 6147 6148 6443 3 6147 6443 6442 3 6149 6150 6220 3 6149 6220 6219 3 6149 6445 6150 3 6446 6150 6445 3 6149 6219 6445 3 6515 6445 6219 3 6150 6446 6151 3 6447 6151 6446 3 6151 6447 6152 3 6448 6152 6447 3 6152 6448 6153 3 6449 6153 6448 3 6153 6449 6154 3 6450 6154 6449 3 6154 6450 6155 3 6451 6155 6450 3 6155 6451 6156 3 6452 6156 6451 3 6156 6452 6157 3 6453 6157 6452 3 6157 6453 6158 3 6454 6158 6453 3 6158 6454 6159 3 6455 6159 6454 3 6159 6455 6160 3 6456 6160 6455 3 6160 6456 6457 3 6160 6457 6161 3 6161 6457 6458 3 6161 6458 6162 3 6162 6458 6459 3 6162 6459 6163 3 6163 6459 6460 3 6163 6460 6164 3 6164 6460 6461 3 6164 6461 6165 3 6165 6461 6462 3 6165 6462 6166 3 6166 6462 6463 3 6166 6463 6167 3 6167 6463 6464 3 6167 6464 6168 3 6168 6464 6465 3 6168 6465 6169 3 6169 6465 6466 3 6169 6466 6170 3 6170 6466 6467 3 6170 6467 6171 3 6171 6467 6468 3 6171 6468 6172 3 6172 6468 6469 3 6172 6469 6173 3 6173 6469 6470 3 6173 6470 6174 3 6174 6470 6471 3 6174 6471 6175 3 6175 6471 6472 3 6175 6472 6176 3 6176 6472 6473 3 6176 6473 6177 3 6177 6473 6474 3 6177 6474 6178 3 6178 6474 6475 3 6178 6475 6179 3 6179 6475 6476 3 6179 6476 6180 3 6180 6476 6477 3 6180 6477 6181 3 6181 6477 6478 3 6181 6478 6182 3 6182 6478 6479 3 6182 6479 6183 3 6183 6479 6480 3 6183 6480 6184 3 6184 6480 6481 3 6184 6481 6185 3 6185 6481 6482 3 6185 6482 6186 3 6186 6482 6483 3 6186 6483 6187 3 6187 6483 6484 3 6187 6484 6188 3 6188 6484 6485 3 6188 6485 6189 3 6189 6485 6486 3 6189 6486 6190 3 6190 6486 6487 3 6190 6487 6191 3 6191 6487 6488 3 6191 6488 6192 3 6192 6488 6489 3 6192 6489 6193 3 6193 6489 6490 3 6193 6490 6194 3 6194 6490 6491 3 6194 6491 6195 3 6195 6491 6492 3 6195 6492 6196 3 6196 6492 6493 3 6196 6493 6197 3 6197 6493 6494 3 6197 6494 6198 3 6198 6494 6495 3 6198 6495 6199 3 6199 6495 6496 3 6199 6496 6200 3 6200 6496 6497 3 6200 6497 6201 3 6201 6497 6498 3 6201 6498 6202 3 6202 6498 6499 3 6202 6499 6203 3 6203 6499 6500 3 6203 6500 6204 3 6204 6500 6501 3 6204 6501 6205 3 6205 6501 6502 3 6205 6502 6206 3 6206 6502 6503 3 6206 6503 6207 3 6207 6503 6504 3 6207 6504 6208 3 6208 6504 6505 3 6208 6505 6209 3 6209 6505 6210 3 6506 6210 6505 3 6210 6506 6211 3 6507 6211 6506 3 6211 6507 6212 3 6508 6212 6507 3 6212 6508 6213 3 6509 6213 6508 3 6213 6509 6214 3 6510 6214 6509 3 6214 6510 6215 3 6511 6215 6510 3 6215 6511 6216 3 6512 6216 6511 3 6216 6217 6221 3 6222 6221 6217 3 6216 6512 6217 3 6513 6217 6512 3 6217 6513 6222 3 6516 6222 6513 3 6218 6514 6219 3 6515 6219 6514 3 6218 6225 6514 3 6519 6514 6225 3 6222 6516 6223 3 6517 6223 6516 3 6223 6517 6226 3 6520 6226 6517 3 6224 6225 6228 3 6229 6228 6225 3 6224 6518 6225 3 6519 6225 6518 3 6224 6228 6518 3 6522 6518 6228 3 6226 6227 6230 3 6231 6230 6227 3 6226 6520 6227 3 6521 6227 6520 3 6227 6521 6231 3 6523 6231 6521 3 6228 6232 6522 3 6524 6522 6232 3 6231 6523 6233 3 6525 6233 6523 3 6232 6234 6526 3 6232 6526 6524 3 6233 6525 6235 3 6527 6235 6525 3 6234 6236 6528 3 6234 6528 6526 3 6235 6527 6237 3 6529 6237 6527 3 6236 6238 6530 3 6236 6530 6528 3 6237 6529 6239 3 6531 6239 6529 3 6238 6240 6532 3 6238 6532 6530 3 6239 6531 6241 3 6533 6241 6531 3 6240 6242 6534 3 6240 6534 6532 3 6241 6533 6243 3 6535 6243 6533 3 6242 6244 6536 3 6242 6536 6534 3 6243 6535 6245 3 6537 6245 6535 3 6244 6246 6538 3 6244 6538 6536 3 6245 6537 6247 3 6539 6247 6537 3 6246 6248 6540 3 6246 6540 6538 3 6247 6539 6249 3 6541 6249 6539 3 6248 6250 6542 3 6248 6542 6540 3 6249 6541 6251 3 6543 6251 6541 3 6250 6252 6544 3 6250 6544 6542 3 6251 6543 6253 3 6545 6253 6543 3 6252 6254 6546 3 6252 6546 6544 3 6253 6545 6255 3 6547 6255 6545 3 6254 6256 6548 3 6254 6548 6546 3 6255 6547 6257 3 6549 6257 6547 3 6256 6258 6550 3 6256 6550 6548 3 6257 6549 6259 3 6551 6259 6549 3 6258 6260 6552 3 6258 6552 6550 3 6259 6551 6261 3 6553 6261 6551 3 6260 6262 6554 3 6260 6554 6552 3 6261 6553 6555 3 6261 6555 6263 3 6262 6264 6556 3 6262 6556 6554 3 6263 6555 6557 3 6263 6557 6265 3 6264 6266 6558 3 6264 6558 6556 3 6265 6557 6559 3 6265 6559 6267 3 6266 6268 6560 3 6266 6560 6558 3 6267 6559 6561 3 6267 6561 6269 3 6268 6270 6562 3 6268 6562 6560 3 6269 6561 6563 3 6269 6563 6271 3 6270 6272 6564 3 6270 6564 6562 3 6271 6563 6565 3 6271 6565 6273 3 6272 6274 6566 3 6272 6566 6564 3 6273 6565 6567 3 6273 6567 6275 3 6274 6276 6568 3 6274 6568 6566 3 6275 6567 6569 3 6275 6569 6277 3 6276 6278 6570 3 6276 6570 6568 3 6277 6569 6571 3 6277 6571 6279 3 6278 6280 6572 3 6278 6572 6570 3 6279 6571 6573 3 6279 6573 6281 3 6280 6282 6572 3 6574 6572 6282 3 6281 6573 6575 3 6281 6575 6283 3 6282 6284 6574 3 6576 6574 6284 3 6283 6575 6577 3 6283 6577 6285 3 6284 6286 6576 3 6578 6576 6286 3 6285 6577 6579 3 6285 6579 6287 3 6286 6288 6578 3 6580 6578 6288 3 6287 6579 6581 3 6287 6581 6289 3 6288 6290 6580 3 6582 6580 6290 3 6289 6581 6583 3 6289 6583 6291 3 6290 6292 6582 3 6584 6582 6292 3 6291 6583 6585 3 6291 6585 6293 3 6292 6294 6584 3 6586 6584 6294 3 6293 6585 6587 3 6293 6587 6295 3 6294 6296 6586 3 6588 6586 6296 3 6295 6587 6589 3 6295 6589 6297 3 6296 6298 6588 3 6590 6588 6298 3 6297 6589 6591 3 6297 6591 6299 3 6298 6300 6590 3 6592 6590 6300 3 6299 6591 6593 3 6299 6593 6301 3 6300 6302 6592 3 6594 6592 6302 3 6301 6593 6595 3 6301 6595 6303 3 6302 6304 6594 3 6596 6594 6304 3 6303 6595 6597 3 6303 6597 6305 3 6304 6306 6596 3 6598 6596 6306 3 6305 6597 6599 3 6305 6599 6307 3 6306 6308 6598 3 6600 6598 6308 3 6307 6599 6601 3 6307 6601 6309 3 6308 6310 6600 3 6602 6600 6310 3 6309 6601 6603 3 6309 6603 6311 3 6310 6312 6602 3 6604 6602 6312 3 6311 6603 6313 3 6605 6313 6603 3 6312 6314 6604 3 6606 6604 6314 3 6313 6605 6315 3 6607 6315 6605 3 6314 6316 6606 3 6608 6606 6316 3 6315 6607 6317 3 6609 6317 6607 3 6316 6318 6608 3 6610 6608 6318 3 6317 6609 6319 3 6611 6319 6609 3 6318 6320 6610 3 6612 6610 6320 3 6319 6611 6321 3 6613 6321 6611 3 6320 6322 6612 3 6614 6612 6322 3 6321 6613 6323 3 6615 6323 6613 3 6322 6324 6614 3 6616 6614 6324 3 6323 6615 6325 3 6617 6325 6615 3 6324 6326 6616 3 6618 6616 6326 3 6325 6617 6327 3 6619 6327 6617 3 6326 6328 6618 3 6620 6618 6328 3 6327 6619 6329 3 6621 6329 6619 3 6328 6330 6620 3 6622 6620 6330 3 6329 6621 6331 3 6623 6331 6621 3 6330 6332 6624 3 6330 6624 6622 3 6331 6623 6333 3 6625 6333 6623 3 6332 6334 6626 3 6332 6626 6624 3 6333 6625 6335 3 6627 6335 6625 3 6334 6336 6628 3 6334 6628 6626 3 6335 6627 6337 3 6629 6337 6627 3 6336 6338 6630 3 6336 6630 6628 3 6337 6629 6339 3 6631 6339 6629 3 6338 6340 6632 3 6338 6632 6630 3 6339 6631 6341 3 6633 6341 6631 3 6340 6342 6634 3 6340 6634 6632 3 6341 6633 6343 3 6635 6343 6633 3 6342 6344 6636 3 6342 6636 6634 3 6343 6635 6345 3 6637 6345 6635 3 6344 6346 6638 3 6344 6638 6636 3 6345 6637 6347 3 6639 6347 6637 3 6346 6348 6640 3 6346 6640 6638 3 6347 6639 6349 3 6641 6349 6639 3 6348 6350 6642 3 6348 6642 6640 3 6349 6641 6351 3 6643 6351 6641 3 6350 6352 6644 3 6350 6644 6642 3 6351 6643 6353 3 6645 6353 6643 3 6352 6354 6646 3 6352 6646 6644 3 6353 6645 6355 3 6647 6355 6645 3 6354 6356 6648 3 6354 6648 6646 3 6355 6647 6357 3 6649 6357 6647 3 6356 6358 6650 3 6356 6650 6648 3 6357 6649 6359 3 6651 6359 6649 3 6358 6360 6652 3 6358 6652 6650 3 6359 6651 6361 3 6653 6361 6651 3 6360 6362 6654 3 6360 6654 6652 3 6361 6653 6655 3 6361 6655 6365 3 6362 6363 6367 3 6362 6367 6366 3 6362 6366 6656 3 6362 6656 6654 3 6364 6365 6369 3 6364 6369 6368 3 6365 6655 6659 3 6365 6659 6369 3 6366 6367 6657 3 6366 6657 6656 3 6367 6370 6660 3 6367 6660 6657 3 6368 6369 6659 3 6368 6659 6658 3 6368 6658 6663 3 6368 6663 6375 3 6370 6371 6661 3 6370 6661 6660 3 6371 6372 6377 3 6371 6377 6376 3 6371 6376 6664 3 6371 6664 6661 3 6373 6374 6444 3 6373 6444 6443 3 6374 6375 6663 3 6374 6663 6662 3 6374 6662 6732 3 6374 6732 6444 3 6376 6377 6665 3 6376 6665 6664 3 6377 6378 6666 3 6377 6666 6665 3 6378 6379 6666 3 6667 6666 6379 3 6379 6380 6667 3 6668 6667 6380 3 6380 6381 6668 3 6669 6668 6381 3 6381 6382 6669 3 6670 6669 6382 3 6382 6383 6670 3 6671 6670 6383 3 6383 6384 6671 3 6672 6671 6384 3 6384 6385 6672 3 6673 6672 6385 3 6385 6386 6673 3 6674 6673 6386 3 6386 6387 6674 3 6675 6674 6387 3 6387 6388 6675 3 6676 6675 6388 3 6388 6389 6676 3 6677 6676 6389 3 6389 6390 6677 3 6678 6677 6390 3 6390 6391 6678 3 6679 6678 6391 3 6391 6392 6679 3 6680 6679 6392 3 6392 6393 6680 3 6681 6680 6393 3 6393 6394 6681 3 6682 6681 6394 3 6394 6395 6682 3 6683 6682 6395 3 6395 6396 6683 3 6684 6683 6396 3 6396 6397 6684 3 6685 6684 6397 3 6397 6398 6685 3 6686 6685 6398 3 6398 6399 6686 3 6687 6686 6399 3 6399 6400 6687 3 6688 6687 6400 3 6400 6401 6688 3 6689 6688 6401 3 6401 6402 6689 3 6690 6689 6402 3 6402 6403 6690 3 6691 6690 6403 3 6403 6404 6691 3 6692 6691 6404 3 6404 6405 6692 3 6693 6692 6405 3 6405 6406 6693 3 6694 6693 6406 3 6406 6407 6694 3 6695 6694 6407 3 6407 6408 6695 3 6696 6695 6408 3 6408 6409 6696 3 6697 6696 6409 3 6409 6410 6697 3 6698 6697 6410 3 6410 6411 6698 3 6699 6698 6411 3 6411 6412 6699 3 6700 6699 6412 3 6412 6413 6700 3 6701 6700 6413 3 6413 6414 6701 3 6702 6701 6414 3 6414 6415 6702 3 6703 6702 6415 3 6415 6416 6703 3 6704 6703 6416 3 6416 6417 6704 3 6705 6704 6417 3 6417 6418 6705 3 6706 6705 6418 3 6418 6419 6706 3 6707 6706 6419 3 6419 6420 6707 3 6708 6707 6420 3 6420 6421 6708 3 6709 6708 6421 3 6421 6422 6709 3 6710 6709 6422 3 6422 6423 6710 3 6711 6710 6423 3 6423 6424 6711 3 6712 6711 6424 3 6424 6425 6712 3 6713 6712 6425 3 6425 6426 6713 3 6714 6713 6426 3 6426 6427 6714 3 6715 6714 6427 3 6427 6428 6715 3 6716 6715 6428 3 6428 6429 6717 3 6428 6717 6716 3 6429 6430 6718 3 6429 6718 6717 3 6430 6431 6719 3 6430 6719 6718 3 6431 6432 6720 3 6431 6720 6719 3 6432 6433 6721 3 6432 6721 6720 3 6433 6434 6722 3 6433 6722 6721 3 6434 6435 6723 3 6434 6723 6722 3 6435 6436 6724 3 6435 6724 6723 3 6436 6437 6725 3 6436 6725 6724 3 6437 6438 6726 3 6437 6726 6725 3 6438 6439 6727 3 6438 6727 6726 3 6439 6440 6728 3 6439 6728 6727 3 6440 6441 6729 3 6440 6729 6728 3 6441 6442 6730 3 6441 6730 6729 3 6442 6443 6731 3 6442 6731 6730 3 6443 6444 6732 3 6443 6732 6731 3 6445 6733 6446 3 6734 6446 6733 3 6445 6515 6733 3 6803 6733 6515 3 6446 6734 6447 3 6735 6447 6734 3 6447 6735 6448 3 6736 6448 6735 3 6448 6736 6449 3 6737 6449 6736 3 6449 6737 6450 3 6738 6450 6737 3 6450 6738 6451 3 6739 6451 6738 3 6451 6739 6452 3 6740 6452 6739 3 6452 6740 6453 3 6741 6453 6740 3 6453 6741 6454 3 6742 6454 6741 3 6454 6742 6455 3 6743 6455 6742 3 6455 6743 6456 3 6744 6456 6743 3 6456 6744 6457 3 6745 6457 6744 3 6457 6745 6458 3 6746 6458 6745 3 6458 6746 6459 3 6747 6459 6746 3 6459 6747 6460 3 6748 6460 6747 3 6460 6748 6461 3 6749 6461 6748 3 6461 6749 6462 3 6750 6462 6749 3 6462 6750 6751 3 6462 6751 6463 3 6463 6751 6752 3 6463 6752 6464 3 6464 6752 6753 3 6464 6753 6465 3 6465 6753 6754 3 6465 6754 6466 3 6466 6754 6755 3 6466 6755 6467 3 6467 6755 6756 3 6467 6756 6468 3 6468 6756 6757 3 6468 6757 6469 3 6469 6757 6758 3 6469 6758 6470 3 6470 6758 6759 3 6470 6759 6471 3 6471 6759 6760 3 6471 6760 6472 3 6472 6760 6761 3 6472 6761 6473 3 6473 6761 6762 3 6473 6762 6474 3 6474 6762 6763 3 6474 6763 6475 3 6475 6763 6764 3 6475 6764 6476 3 6476 6764 6765 3 6476 6765 6477 3 6477 6765 6766 3 6477 6766 6478 3 6478 6766 6767 3 6478 6767 6479 3 6479 6767 6768 3 6479 6768 6480 3 6480 6768 6769 3 6480 6769 6481 3 6481 6769 6770 3 6481 6770 6482 3 6482 6770 6771 3 6482 6771 6483 3 6483 6771 6772 3 6483 6772 6484 3 6484 6772 6773 3 6484 6773 6485 3 6485 6773 6774 3 6485 6774 6486 3 6486 6774 6775 3 6486 6775 6487 3 6487 6775 6776 3 6487 6776 6488 3 6488 6776 6777 3 6488 6777 6489 3 6489 6777 6778 3 6489 6778 6490 3 6490 6778 6779 3 6490 6779 6491 3 6491 6779 6780 3 6491 6780 6492 3 6492 6780 6781 3 6492 6781 6493 3 6493 6781 6782 3 6493 6782 6494 3 6494 6782 6783 3 6494 6783 6495 3 6495 6783 6784 3 6495 6784 6496 3 6496 6784 6785 3 6496 6785 6497 3 6497 6785 6786 3 6497 6786 6498 3 6498 6786 6787 3 6498 6787 6499 3 6499 6787 6788 3 6499 6788 6500 3 6500 6788 6789 3 6500 6789 6501 3 6501 6789 6790 3 6501 6790 6502 3 6502 6790 6791 3 6502 6791 6503 3 6503 6791 6792 3 6503 6792 6504 3 6504 6792 6793 3 6504 6793 6505 3 6505 6793 6794 3 6505 6794 6506 3 6506 6794 6795 3 6506 6795 6507 3 6507 6795 6796 3 6507 6796 6508 3 6508 6796 6797 3 6508 6797 6509 3 6509 6797 6798 3 6509 6798 6510 3 6510 6798 6799 3 6510 6799 6511 3 6511 6799 6800 3 6511 6800 6512 3 6512 6800 6513 3 6801 6513 6800 3 6513 6801 6516 3 6804 6516 6801 3 6514 6802 6515 3 6803 6515 6802 3 6514 6519 6802 3 6807 6802 6519 3 6516 6804 6517 3 6805 6517 6804 3 6517 6805 6520 3 6808 6520 6805 3 6518 6806 6519 3 6807 6519 6806 3 6518 6522 6806 3 6810 6806 6522 3 6520 6808 6521 3 6809 6521 6808 3 6521 6809 6523 3 6811 6523 6809 3 6522 6524 6810 3 6812 6810 6524 3 6523 6811 6525 3 6813 6525 6811 3 6524 6526 6812 3 6814 6812 6526 3 6525 6813 6527 3 6815 6527 6813 3 6526 6528 6816 3 6526 6816 6814 3 6527 6815 6529 3 6817 6529 6815 3 6528 6530 6818 3 6528 6818 6816 3 6529 6817 6531 3 6819 6531 6817 3 6530 6532 6820 3 6530 6820 6818 3 6531 6819 6533 3 6821 6533 6819 3 6532 6534 6822 3 6532 6822 6820 3 6533 6821 6535 3 6823 6535 6821 3 6534 6536 6824 3 6534 6824 6822 3 6535 6823 6537 3 6825 6537 6823 3 6536 6538 6826 3 6536 6826 6824 3 6537 6825 6539 3 6827 6539 6825 3 6538 6540 6828 3 6538 6828 6826 3 6539 6827 6541 3 6829 6541 6827 3 6540 6542 6830 3 6540 6830 6828 3 6541 6829 6543 3 6831 6543 6829 3 6542 6544 6832 3 6542 6832 6830 3 6543 6831 6545 3 6833 6545 6831 3 6544 6546 6834 3 6544 6834 6832 3 6545 6833 6547 3 6835 6547 6833 3 6546 6548 6836 3 6546 6836 6834 3 6547 6835 6549 3 6837 6549 6835 3 6548 6550 6838 3 6548 6838 6836 3 6549 6837 6551 3 6839 6551 6837 3 6550 6552 6840 3 6550 6840 6838 3 6551 6839 6553 3 6841 6553 6839 3 6552 6554 6842 3 6552 6842 6840 3 6553 6841 6555 3 6843 6555 6841 3 6554 6556 6844 3 6554 6844 6842 3 6555 6843 6557 3 6845 6557 6843 3 6556 6558 6846 3 6556 6846 6844 3 6557 6845 6559 3 6847 6559 6845 3 6558 6560 6848 3 6558 6848 6846 3 6559 6847 6561 3 6849 6561 6847 3 6560 6562 6850 3 6560 6850 6848 3 6561 6849 6563 3 6851 6563 6849 3 6562 6564 6852 3 6562 6852 6850 3 6563 6851 6853 3 6563 6853 6565 3 6564 6566 6854 3 6564 6854 6852 3 6565 6853 6855 3 6565 6855 6567 3 6566 6568 6856 3 6566 6856 6854 3 6567 6855 6857 3 6567 6857 6569 3 6568 6570 6858 3 6568 6858 6856 3 6569 6857 6859 3 6569 6859 6571 3 6570 6572 6860 3 6570 6860 6858 3 6571 6859 6861 3 6571 6861 6573 3 6572 6574 6862 3 6572 6862 6860 3 6573 6861 6863 3 6573 6863 6575 3 6574 6576 6864 3 6574 6864 6862 3 6575 6863 6865 3 6575 6865 6577 3 6576 6578 6864 3 6866 6864 6578 3 6577 6865 6867 3 6577 6867 6579 3 6578 6580 6866 3 6868 6866 6580 3 6579 6867 6869 3 6579 6869 6581 3 6580 6582 6868 3 6870 6868 6582 3 6581 6869 6871 3 6581 6871 6583 3 6582 6584 6870 3 6872 6870 6584 3 6583 6871 6873 3 6583 6873 6585 3 6584 6586 6872 3 6874 6872 6586 3 6585 6873 6875 3 6585 6875 6587 3 6586 6588 6874 3 6876 6874 6588 3 6587 6875 6877 3 6587 6877 6589 3 6588 6590 6876 3 6878 6876 6590 3 6589 6877 6879 3 6589 6879 6591 3 6590 6592 6878 3 6880 6878 6592 3 6591 6879 6881 3 6591 6881 6593 3 6592 6594 6880 3 6882 6880 6594 3 6593 6881 6883 3 6593 6883 6595 3 6594 6596 6882 3 6884 6882 6596 3 6595 6883 6885 3 6595 6885 6597 3 6596 6598 6884 3 6886 6884 6598 3 6597 6885 6887 3 6597 6887 6599 3 6598 6600 6886 3 6888 6886 6600 3 6599 6887 6889 3 6599 6889 6601 3 6600 6602 6888 3 6890 6888 6602 3 6601 6889 6891 3 6601 6891 6603 3 6602 6604 6890 3 6892 6890 6604 3 6603 6891 6893 3 6603 6893 6605 3 6604 6606 6892 3 6894 6892 6606 3 6605 6893 6895 3 6605 6895 6607 3 6606 6608 6894 3 6896 6894 6608 3 6607 6895 6897 3 6607 6897 6609 3 6608 6610 6896 3 6898 6896 6610 3 6609 6897 6899 3 6609 6899 6611 3 6610 6612 6898 3 6900 6898 6612 3 6611 6899 6901 3 6611 6901 6613 3 6612 6614 6900 3 6902 6900 6614 3 6613 6901 6615 3 6903 6615 6901 3 6614 6616 6902 3 6904 6902 6616 3 6615 6903 6617 3 6905 6617 6903 3 6616 6618 6904 3 6906 6904 6618 3 6617 6905 6619 3 6907 6619 6905 3 6618 6620 6906 3 6908 6906 6620 3 6619 6907 6621 3 6909 6621 6907 3 6620 6622 6908 3 6910 6908 6622 3 6621 6909 6623 3 6911 6623 6909 3 6622 6624 6910 3 6912 6910 6624 3 6623 6911 6625 3 6913 6625 6911 3 6624 6626 6912 3 6914 6912 6626 3 6625 6913 6627 3 6915 6627 6913 3 6626 6628 6916 3 6626 6916 6914 3 6627 6915 6629 3 6917 6629 6915 3 6628 6630 6918 3 6628 6918 6916 3 6629 6917 6631 3 6919 6631 6917 3 6630 6632 6920 3 6630 6920 6918 3 6631 6919 6633 3 6921 6633 6919 3 6632 6634 6922 3 6632 6922 6920 3 6633 6921 6635 3 6923 6635 6921 3 6634 6636 6924 3 6634 6924 6922 3 6635 6923 6637 3 6925 6637 6923 3 6636 6638 6926 3 6636 6926 6924 3 6637 6925 6639 3 6927 6639 6925 3 6638 6640 6928 3 6638 6928 6926 3 6639 6927 6641 3 6929 6641 6927 3 6640 6642 6930 3 6640 6930 6928 3 6641 6929 6643 3 6931 6643 6929 3 6642 6644 6932 3 6642 6932 6930 3 6643 6931 6645 3 6933 6645 6931 3 6644 6646 6934 3 6644 6934 6932 3 6645 6933 6647 3 6935 6647 6933 3 6646 6648 6936 3 6646 6936 6934 3 6647 6935 6649 3 6937 6649 6935 3 6648 6650 6938 3 6648 6938 6936 3 6649 6937 6651 3 6939 6651 6937 3 6650 6652 6940 3 6650 6940 6938 3 6651 6939 6653 3 6941 6653 6939 3 6652 6654 6942 3 6652 6942 6940 3 6653 6941 6655 3 6943 6655 6941 3 6654 6656 6944 3 6654 6944 6942 3 6655 6943 6659 3 6947 6659 6943 3 6656 6657 6945 3 6656 6945 6944 3 6657 6660 6948 3 6657 6948 6945 3 6658 6659 6947 3 6658 6947 6946 3 6658 6946 6663 3 6951 6663 6946 3 6660 6661 6949 3 6660 6949 6948 3 6661 6664 6952 3 6661 6952 6949 3 6662 6663 6951 3 6662 6951 6950 3 6662 6950 6732 3 7020 6732 6950 3 6664 6665 6953 3 6664 6953 6952 3 6665 6666 6954 3 6665 6954 6953 3 6666 6667 6955 3 6666 6955 6954 3 6667 6668 6956 3 6667 6956 6955 3 6668 6669 6957 3 6668 6957 6956 3 6669 6670 6958 3 6669 6958 6957 3 6670 6671 6959 3 6670 6959 6958 3 6671 6672 6960 3 6671 6960 6959 3 6672 6673 6961 3 6672 6961 6960 3 6673 6674 6962 3 6673 6962 6961 3 6674 6675 6963 3 6674 6963 6962 3 6675 6676 6964 3 6675 6964 6963 3 6676 6677 6965 3 6676 6965 6964 3 6677 6678 6965 3 6966 6965 6678 3 6678 6679 6966 3 6967 6966 6679 3 6679 6680 6967 3 6968 6967 6680 3 6680 6681 6968 3 6969 6968 6681 3 6681 6682 6969 3 6970 6969 6682 3 6682 6683 6970 3 6971 6970 6683 3 6683 6684 6971 3 6972 6971 6684 3 6684 6685 6972 3 6973 6972 6685 3 6685 6686 6973 3 6974 6973 6686 3 6686 6687 6974 3 6975 6974 6687 3 6687 6688 6975 3 6976 6975 6688 3 6688 6689 6976 3 6977 6976 6689 3 6689 6690 6977 3 6978 6977 6690 3 6690 6691 6978 3 6979 6978 6691 3 6691 6692 6979 3 6980 6979 6692 3 6692 6693 6980 3 6981 6980 6693 3 6693 6694 6981 3 6982 6981 6694 3 6694 6695 6982 3 6983 6982 6695 3 6695 6696 6983 3 6984 6983 6696 3 6696 6697 6984 3 6985 6984 6697 3 6697 6698 6985 3 6986 6985 6698 3 6698 6699 6986 3 6987 6986 6699 3 6699 6700 6987 3 6988 6987 6700 3 6700 6701 6988 3 6989 6988 6701 3 6701 6702 6989 3 6990 6989 6702 3 6702 6703 6990 3 6991 6990 6703 3 6703 6704 6991 3 6992 6991 6704 3 6704 6705 6992 3 6993 6992 6705 3 6705 6706 6993 3 6994 6993 6706 3 6706 6707 6994 3 6995 6994 6707 3 6707 6708 6995 3 6996 6995 6708 3 6708 6709 6996 3 6997 6996 6709 3 6709 6710 6997 3 6998 6997 6710 3 6710 6711 6998 3 6999 6998 6711 3 6711 6712 6999 3 7000 6999 6712 3 6712 6713 7000 3 7001 7000 6713 3 6713 6714 7001 3 7002 7001 6714 3 6714 6715 7002 3 7003 7002 6715 3 6715 6716 7003 3 7004 7003 6716 3 6716 6717 7004 3 7005 7004 6717 3 6717 6718 7005 3 7006 7005 6718 3 6718 6719 7006 3 7007 7006 6719 3 6719 6720 7007 3 7008 7007 6720 3 6720 6721 7008 3 7009 7008 6721 3 6721 6722 7009 3 7010 7009 6722 3 6722 6723 7010 3 7011 7010 6723 3 6723 6724 7011 3 7012 7011 6724 3 6724 6725 7012 3 7013 7012 6725 3 6725 6726 7013 3 7014 7013 6726 3 6726 6727 7014 3 7015 7014 6727 3 6727 6728 7016 3 6727 7016 7015 3 6728 6729 7017 3 6728 7017 7016 3 6729 6730 7018 3 6729 7018 7017 3 6730 6731 7019 3 6730 7019 7018 3 6731 6732 7020 3 6731 7020 7019 3 6733 7021 6734 3 7022 6734 7021 3 6733 6803 7091 3 6733 7091 7021 3 6734 7022 6735 3 7023 6735 7022 3 6735 7023 6736 3 7024 6736 7023 3 6736 7024 6737 3 7025 6737 7024 3 6737 7025 6738 3 7026 6738 7025 3 6738 7026 6739 3 7027 6739 7026 3 6739 7027 6740 3 7028 6740 7027 3 6740 7028 6741 3 7029 6741 7028 3 6741 7029 6742 3 7030 6742 7029 3 6742 7030 6743 3 7031 6743 7030 3 6743 7031 6744 3 7032 6744 7031 3 6744 7032 6745 3 7033 6745 7032 3 6745 7033 6746 3 7034 6746 7033 3 6746 7034 6747 3 7035 6747 7034 3 6747 7035 6748 3 7036 6748 7035 3 6748 7036 6749 3 7037 6749 7036 3 6749 7037 6750 3 7038 6750 7037 3 6750 7038 6751 3 7039 6751 7038 3 6751 7039 6752 3 7040 6752 7039 3 6752 7040 6753 3 7041 6753 7040 3 6753 7041 6754 3 7042 6754 7041 3 6754 7042 6755 3 7043 6755 7042 3 6755 7043 6756 3 7044 6756 7043 3 6756 7044 6757 3 7045 6757 7044 3 6757 7045 6758 3 7046 6758 7045 3 6758 7046 6759 3 7047 6759 7046 3 6759 7047 6760 3 7048 6760 7047 3 6760 7048 6761 3 7049 6761 7048 3 6761 7049 6762 3 7050 6762 7049 3 6762 7050 6763 3 7051 6763 7050 3 6763 7051 6764 3 7052 6764 7051 3 6764 7052 6765 3 7053 6765 7052 3 6765 7053 6766 3 7054 6766 7053 3 6766 7054 7055 3 6766 7055 6767 3 6767 7055 7056 3 6767 7056 6768 3 6768 7056 7057 3 6768 7057 6769 3 6769 7057 7058 3 6769 7058 6770 3 6770 7058 7059 3 6770 7059 6771 3 6771 7059 7060 3 6771 7060 6772 3 6772 7060 7061 3 6772 7061 6773 3 6773 7061 7062 3 6773 7062 6774 3 6774 7062 7063 3 6774 7063 6775 3 6775 7063 7064 3 6775 7064 6776 3 6776 7064 7065 3 6776 7065 6777 3 6777 7065 7066 3 6777 7066 6778 3 6778 7066 7067 3 6778 7067 6779 3 6779 7067 7068 3 6779 7068 6780 3 6780 7068 7069 3 6780 7069 6781 3 6781 7069 7070 3 6781 7070 6782 3 6782 7070 7071 3 6782 7071 6783 3 6783 7071 7072 3 6783 7072 6784 3 6784 7072 7073 3 6784 7073 6785 3 6785 7073 7074 3 6785 7074 6786 3 6786 7074 7075 3 6786 7075 6787 3 6787 7075 7076 3 6787 7076 6788 3 6788 7076 7077 3 6788 7077 6789 3 6789 7077 7078 3 6789 7078 6790 3 6790 7078 7079 3 6790 7079 6791 3 6791 7079 7080 3 6791 7080 6792 3 6792 7080 7081 3 6792 7081 6793 3 6793 7081 7082 3 6793 7082 6794 3 6794 7082 7083 3 6794 7083 6795 3 6795 7083 7084 3 6795 7084 6796 3 6796 7084 7085 3 6796 7085 6797 3 6797 7085 7086 3 6797 7086 6798 3 6798 7086 7087 3 6798 7087 6799 3 6799 7087 7088 3 6799 7088 6800 3 6800 7088 7089 3 6800 7089 6801 3 6801 7089 7092 3 6801 7092 6804 3 6802 7090 7091 3 6802 7091 6803 3 6802 6807 7090 3 7095 7090 6807 3 6804 7092 7093 3 6804 7093 6805 3 6805 7093 7096 3 6805 7096 6808 3 6806 7094 7095 3 6806 7095 6807 3 6806 6810 7094 3 7098 7094 6810 3 6808 7096 7097 3 6808 7097 6809 3 6809 7097 7099 3 6809 7099 6811 3 6810 6812 7098 3 7100 7098 6812 3 6811 7099 7101 3 6811 7101 6813 3 6812 6814 7100 3 7102 7100 6814 3 6813 7101 7103 3 6813 7103 6815 3 6814 6816 7102 3 7104 7102 6816 3 6815 7103 7105 3 6815 7105 6817 3 6816 6818 7104 3 7106 7104 6818 3 6817 7105 6819 3 7107 6819 7105 3 6818 6820 7106 3 7108 7106 6820 3 6819 7107 6821 3 7109 6821 7107 3 6820 6822 7108 3 7110 7108 6822 3 6821 7109 6823 3 7111 6823 7109 3 6822 6824 7110 3 7112 7110 6824 3 6823 7111 6825 3 7113 6825 7111 3 6824 6826 7112 3 7114 7112 6826 3 6825 7113 6827 3 7115 6827 7113 3 6826 6828 7114 3 7116 7114 6828 3 6827 7115 6829 3 7117 6829 7115 3 6828 6830 7118 3 6828 7118 7116 3 6829 7117 6831 3 7119 6831 7117 3 6830 6832 7120 3 6830 7120 7118 3 6831 7119 6833 3 7121 6833 7119 3 6832 6834 7122 3 6832 7122 7120 3 6833 7121 6835 3 7123 6835 7121 3 6834 6836 7124 3 6834 7124 7122 3 6835 7123 6837 3 7125 6837 7123 3 6836 6838 7126 3 6836 7126 7124 3 6837 7125 6839 3 7127 6839 7125 3 6838 6840 7128 3 6838 7128 7126 3 6839 7127 6841 3 7129 6841 7127 3 6840 6842 7130 3 6840 7130 7128 3 6841 7129 6843 3 7131 6843 7129 3 6842 6844 7132 3 6842 7132 7130 3 6843 7131 6845 3 7133 6845 7131 3 6844 6846 7134 3 6844 7134 7132 3 6845 7133 6847 3 7135 6847 7133 3 6846 6848 7136 3 6846 7136 7134 3 6847 7135 6849 3 7137 6849 7135 3 6848 6850 7138 3 6848 7138 7136 3 6849 7137 6851 3 7139 6851 7137 3 6850 6852 7140 3 6850 7140 7138 3 6851 7139 6853 3 7141 6853 7139 3 6852 6854 7142 3 6852 7142 7140 3 6853 7141 6855 3 7143 6855 7141 3 6854 6856 7144 3 6854 7144 7142 3 6855 7143 6857 3 7145 6857 7143 3 6856 6858 7146 3 6856 7146 7144 3 6857 7145 6859 3 7147 6859 7145 3 6858 6860 7148 3 6858 7148 7146 3 6859 7147 6861 3 7149 6861 7147 3 6860 6862 7150 3 6860 7150 7148 3 6861 7149 6863 3 7151 6863 7149 3 6862 6864 7152 3 6862 7152 7150 3 6863 7151 6865 3 7153 6865 7151 3 6864 6866 7154 3 6864 7154 7152 3 6865 7153 6867 3 7155 6867 7153 3 6866 6868 7156 3 6866 7156 7154 3 6867 7155 6869 3 7157 6869 7155 3 6868 6870 7158 3 6868 7158 7156 3 6869 7157 7159 3 6869 7159 6871 3 6870 6872 7160 3 6870 7160 7158 3 6871 7159 7161 3 6871 7161 6873 3 6872 6874 7162 3 6872 7162 7160 3 6873 7161 7163 3 6873 7163 6875 3 6874 6876 7164 3 6874 7164 7162 3 6875 7163 7165 3 6875 7165 6877 3 6876 6878 7166 3 6876 7166 7164 3 6877 7165 7167 3 6877 7167 6879 3 6878 6880 7168 3 6878 7168 7166 3 6879 7167 7169 3 6879 7169 6881 3 6880 6882 7168 3 7170 7168 6882 3 6881 7169 7171 3 6881 7171 6883 3 6882 6884 7170 3 7172 7170 6884 3 6883 7171 7173 3 6883 7173 6885 3 6884 6886 7172 3 7174 7172 6886 3 6885 7173 7175 3 6885 7175 6887 3 6886 6888 7174 3 7176 7174 6888 3 6887 7175 7177 3 6887 7177 6889 3 6888 6890 7176 3 7178 7176 6890 3 6889 7177 7179 3 6889 7179 6891 3 6890 6892 7178 3 7180 7178 6892 3 6891 7179 7181 3 6891 7181 6893 3 6892 6894 7180 3 7182 7180 6894 3 6893 7181 7183 3 6893 7183 6895 3 6894 6896 7182 3 7184 7182 6896 3 6895 7183 7185 3 6895 7185 6897 3 6896 6898 7184 3 7186 7184 6898 3 6897 7185 7187 3 6897 7187 6899 3 6898 6900 7186 3 7188 7186 6900 3 6899 7187 7189 3 6899 7189 6901 3 6900 6902 7188 3 7190 7188 6902 3 6901 7189 7191 3 6901 7191 6903 3 6902 6904 7190 3 7192 7190 6904 3 6903 7191 7193 3 6903 7193 6905 3 6904 6906 7192 3 7194 7192 6906 3 6905 7193 7195 3 6905 7195 6907 3 6906 6908 7194 3 7196 7194 6908 3 6907 7195 7197 3 6907 7197 6909 3 6908 6910 7196 3 7198 7196 6910 3 6909 7197 7199 3 6909 7199 6911 3 6910 6912 7198 3 7200 7198 6912 3 6911 7199 7201 3 6911 7201 6913 3 6912 6914 7200 3 7202 7200 6914 3 6913 7201 7203 3 6913 7203 6915 3 6914 6916 7202 3 7204 7202 6916 3 6915 7203 7205 3 6915 7205 6917 3 6916 6918 7204 3 7206 7204 6918 3 6917 7205 7207 3 6917 7207 6919 3 6918 6920 7206 3 7208 7206 6920 3 6919 7207 7209 3 6919 7209 6921 3 6920 6922 7208 3 7210 7208 6922 3 6921 7209 6923 3 7211 6923 7209 3 6922 6924 7210 3 7212 7210 6924 3 6923 7211 6925 3 7213 6925 7211 3 6924 6926 7212 3 7214 7212 6926 3 6925 7213 6927 3 7215 6927 7213 3 6926 6928 7214 3 7216 7214 6928 3 6927 7215 6929 3 7217 6929 7215 3 6928 6930 7216 3 7218 7216 6930 3 6929 7217 6931 3 7219 6931 7217 3 6930 6932 7220 3 6930 7220 7218 3 6931 7219 6933 3 7221 6933 7219 3 6932 6934 7222 3 6932 7222 7220 3 6933 7221 6935 3 7223 6935 7221 3 6934 6936 7224 3 6934 7224 7222 3 6935 7223 6937 3 7225 6937 7223 3 6936 6938 7226 3 6936 7226 7224 3 6937 7225 6939 3 7227 6939 7225 3 6938 6940 7228 3 6938 7228 7226 3 6939 7227 6941 3 7229 6941 7227 3 6940 6942 7230 3 6940 7230 7228 3 6941 7229 6943 3 7231 6943 7229 3 6942 6944 7232 3 6942 7232 7230 3 6943 7231 6947 3 7235 6947 7231 3 6944 6945 7233 3 6944 7233 7232 3 6945 6948 7236 3 6945 7236 7233 3 6946 6947 7235 3 6946 7235 7234 3 6946 7234 6951 3 7239 6951 7234 3 6948 6949 7237 3 6948 7237 7236 3 6949 6952 7240 3 6949 7240 7237 3 6950 6951 7239 3 6950 7239 7238 3 6950 7238 7020 3 7308 7020 7238 3 6952 6953 7241 3 6952 7241 7240 3 6953 6954 7242 3 6953 7242 7241 3 6954 6955 7243 3 6954 7243 7242 3 6955 6956 7244 3 6955 7244 7243 3 6956 6957 7245 3 6956 7245 7244 3 6957 6958 7246 3 6957 7246 7245 3 6958 6959 7247 3 6958 7247 7246 3 6959 6960 7248 3 6959 7248 7247 3 6960 6961 7249 3 6960 7249 7248 3 6961 6962 7250 3 6961 7250 7249 3 6962 6963 7251 3 6962 7251 7250 3 6963 6964 7252 3 6963 7252 7251 3 6964 6965 7253 3 6964 7253 7252 3 6965 6966 7254 3 6965 7254 7253 3 6966 6967 7255 3 6966 7255 7254 3 6967 6968 7256 3 6967 7256 7255 3 6968 6969 7257 3 6968 7257 7256 3 6969 6970 7258 3 6969 7258 7257 3 6970 6971 7259 3 6970 7259 7258 3 6971 6972 7260 3 6971 7260 7259 3 6972 6973 7261 3 6972 7261 7260 3 6973 6974 7262 3 6973 7262 7261 3 6974 6975 7263 3 6974 7263 7262 3 6975 6976 7264 3 6975 7264 7263 3 6976 6977 7265 3 6976 7265 7264 3 6977 6978 7266 3 6977 7266 7265 3 6978 6979 7267 3 6978 7267 7266 3 6979 6980 7268 3 6979 7268 7267 3 6980 6981 7269 3 6980 7269 7268 3 6981 6982 7270 3 6981 7270 7269 3 6982 6983 7270 3 7271 7270 6983 3 6983 6984 7271 3 7272 7271 6984 3 6984 6985 7272 3 7273 7272 6985 3 6985 6986 7273 3 7274 7273 6986 3 6986 6987 7274 3 7275 7274 6987 3 6987 6988 7275 3 7276 7275 6988 3 6988 6989 7276 3 7277 7276 6989 3 6989 6990 7277 3 7278 7277 6990 3 6990 6991 7278 3 7279 7278 6991 3 6991 6992 7279 3 7280 7279 6992 3 6992 6993 7280 3 7281 7280 6993 3 6993 6994 7281 3 7282 7281 6994 3 6994 6995 7282 3 7283 7282 6995 3 6995 6996 7283 3 7284 7283 6996 3 6996 6997 7284 3 7285 7284 6997 3 6997 6998 7285 3 7286 7285 6998 3 6998 6999 7286 3 7287 7286 6999 3 6999 7000 7287 3 7288 7287 7000 3 7000 7001 7288 3 7289 7288 7001 3 7001 7002 7289 3 7290 7289 7002 3 7002 7003 7290 3 7291 7290 7003 3 7003 7004 7291 3 7292 7291 7004 3 7004 7005 7292 3 7293 7292 7005 3 7005 7006 7293 3 7294 7293 7006 3 7006 7007 7294 3 7295 7294 7007 3 7007 7008 7295 3 7296 7295 7008 3 7008 7009 7296 3 7297 7296 7009 3 7009 7010 7297 3 7298 7297 7010 3 7010 7011 7298 3 7299 7298 7011 3 7011 7012 7299 3 7300 7299 7012 3 7012 7013 7300 3 7301 7300 7013 3 7013 7014 7301 3 7302 7301 7014 3 7014 7015 7302 3 7303 7302 7015 3 7015 7016 7303 3 7304 7303 7016 3 7016 7017 7304 3 7305 7304 7017 3 7017 7018 7305 3 7306 7305 7018 3 7018 7019 7306 3 7307 7306 7019 3 7019 7020 7307 3 7308 7307 7020 3 7021 7309 7310 3 7021 7310 7022 3 7021 7091 7379 3 7021 7379 7309 3 7022 7310 7311 3 7022 7311 7023 3 7023 7311 7312 3 7023 7312 7024 3 7024 7312 7313 3 7024 7313 7025 3 7025 7313 7026 3 7314 7026 7313 3 7026 7314 7027 3 7315 7027 7314 3 7027 7315 7028 3 7316 7028 7315 3 7028 7316 7029 3 7317 7029 7316 3 7029 7317 7030 3 7318 7030 7317 3 7030 7318 7031 3 7319 7031 7318 3 7031 7319 7032 3 7320 7032 7319 3 7032 7320 7033 3 7321 7033 7320 3 7033 7321 7034 3 7322 7034 7321 3 7034 7322 7035 3 7323 7035 7322 3 7035 7323 7036 3 7324 7036 7323 3 7036 7324 7037 3 7325 7037 7324 3 7037 7325 7038 3 7326 7038 7325 3 7038 7326 7039 3 7327 7039 7326 3 7039 7327 7040 3 7328 7040 7327 3 7040 7328 7041 3 7329 7041 7328 3 7041 7329 7042 3 7330 7042 7329 3 7042 7330 7043 3 7331 7043 7330 3 7043 7331 7044 3 7332 7044 7331 3 7044 7332 7045 3 7333 7045 7332 3 7045 7333 7046 3 7334 7046 7333 3 7046 7334 7047 3 7335 7047 7334 3 7047 7335 7048 3 7336 7048 7335 3 7048 7336 7049 3 7337 7049 7336 3 7049 7337 7050 3 7338 7050 7337 3 7050 7338 7051 3 7339 7051 7338 3 7051 7339 7052 3 7340 7052 7339 3 7052 7340 7053 3 7341 7053 7340 3 7053 7341 7054 3 7342 7054 7341 3 7054 7342 7055 3 7343 7055 7342 3 7055 7343 7056 3 7344 7056 7343 3 7056 7344 7057 3 7345 7057 7344 3 7057 7345 7058 3 7346 7058 7345 3 7058 7346 7059 3 7347 7059 7346 3 7059 7347 7060 3 7348 7060 7347 3 7060 7348 7061 3 7349 7061 7348 3 7061 7349 7062 3 7350 7062 7349 3 7062 7350 7063 3 7351 7063 7350 3 7063 7351 7064 3 7352 7064 7351 3 7064 7352 7065 3 7353 7065 7352 3 7065 7353 7066 3 7354 7066 7353 3 7066 7354 7067 3 7355 7067 7354 3 7067 7355 7068 3 7356 7068 7355 3 7068 7356 7069 3 7357 7069 7356 3 7069 7357 7070 3 7358 7070 7357 3 7070 7358 7071 3 7359 7071 7358 3 7071 7359 7072 3 7360 7072 7359 3 7072 7360 7073 3 7361 7073 7360 3 7073 7361 7074 3 7362 7074 7361 3 7074 7362 7075 3 7363 7075 7362 3 7075 7363 7076 3 7364 7076 7363 3 7076 7364 7077 3 7365 7077 7364 3 7077 7365 7366 3 7077 7366 7078 3 7078 7366 7367 3 7078 7367 7079 3 7079 7367 7368 3 7079 7368 7080 3 7080 7368 7369 3 7080 7369 7081 3 7081 7369 7370 3 7081 7370 7082 3 7082 7370 7371 3 7082 7371 7083 3 7083 7371 7372 3 7083 7372 7084 3 7084 7372 7373 3 7084 7373 7085 3 7085 7373 7374 3 7085 7374 7086 3 7086 7374 7375 3 7086 7375 7087 3 7087 7375 7376 3 7087 7376 7088 3 7088 7376 7377 3 7088 7377 7089 3 7089 7377 7380 3 7089 7380 7092 3 7090 7378 7379 3 7090 7379 7091 3 7090 7095 7378 3 7383 7378 7095 3 7092 7380 7381 3 7092 7381 7093 3 7093 7381 7384 3 7093 7384 7096 3 7094 7382 7383 3 7094 7383 7095 3 7094 7098 7382 3 7386 7382 7098 3 7096 7384 7385 3 7096 7385 7097 3 7097 7385 7387 3 7097 7387 7099 3 7098 7100 7386 3 7388 7386 7100 3 7099 7387 7389 3 7099 7389 7101 3 7100 7102 7388 3 7390 7388 7102 3 7101 7389 7391 3 7101 7391 7103 3 7102 7104 7390 3 7392 7390 7104 3 7103 7391 7393 3 7103 7393 7105 3 7104 7106 7392 3 7394 7392 7106 3 7105 7393 7395 3 7105 7395 7107 3 7106 7108 7394 3 7396 7394 7108 3 7107 7395 7397 3 7107 7397 7109 3 7108 7110 7396 3 7398 7396 7110 3 7109 7397 7399 3 7109 7399 7111 3 7110 7112 7398 3 7400 7398 7112 3 7111 7399 7401 3 7111 7401 7113 3 7112 7114 7400 3 7402 7400 7114 3 7113 7401 7403 3 7113 7403 7115 3 7114 7116 7402 3 7404 7402 7116 3 7115 7403 7405 3 7115 7405 7117 3 7116 7118 7404 3 7406 7404 7118 3 7117 7405 7407 3 7117 7407 7119 3 7118 7120 7406 3 7408 7406 7120 3 7119 7407 7409 3 7119 7409 7121 3 7120 7122 7408 3 7410 7408 7122 3 7121 7409 7411 3 7121 7411 7123 3 7122 7124 7410 3 7412 7410 7124 3 7123 7411 7413 3 7123 7413 7125 3 7124 7126 7412 3 7414 7412 7126 3 7125 7413 7415 3 7125 7415 7127 3 7126 7128 7414 3 7416 7414 7128 3 7127 7415 7417 3 7127 7417 7129 3 7128 7130 7416 3 7418 7416 7130 3 7129 7417 7131 3 7419 7131 7417 3 7130 7132 7418 3 7420 7418 7132 3 7131 7419 7133 3 7421 7133 7419 3 7132 7134 7420 3 7422 7420 7134 3 7133 7421 7135 3 7423 7135 7421 3 7134 7136 7422 3 7424 7422 7136 3 7135 7423 7137 3 7425 7137 7423 3 7136 7138 7426 3 7136 7426 7424 3 7137 7425 7139 3 7427 7139 7425 3 7138 7140 7428 3 7138 7428 7426 3 7139 7427 7141 3 7429 7141 7427 3 7140 7142 7430 3 7140 7430 7428 3 7141 7429 7143 3 7431 7143 7429 3 7142 7144 7432 3 7142 7432 7430 3 7143 7431 7145 3 7433 7145 7431 3 7144 7146 7434 3 7144 7434 7432 3 7145 7433 7147 3 7435 7147 7433 3 7146 7148 7436 3 7146 7436 7434 3 7147 7435 7149 3 7437 7149 7435 3 7148 7150 7438 3 7148 7438 7436 3 7149 7437 7151 3 7439 7151 7437 3 7150 7152 7440 3 7150 7440 7438 3 7151 7439 7153 3 7441 7153 7439 3 7152 7154 7442 3 7152 7442 7440 3 7153 7441 7155 3 7443 7155 7441 3 7154 7156 7444 3 7154 7444 7442 3 7155 7443 7157 3 7445 7157 7443 3 7156 7158 7446 3 7156 7446 7444 3 7157 7445 7159 3 7447 7159 7445 3 7158 7160 7448 3 7158 7448 7446 3 7159 7447 7161 3 7449 7161 7447 3 7160 7162 7450 3 7160 7450 7448 3 7161 7449 7163 3 7451 7163 7449 3 7162 7164 7452 3 7162 7452 7450 3 7163 7451 7165 3 7453 7165 7451 3 7164 7166 7454 3 7164 7454 7452 3 7165 7453 7167 3 7455 7167 7453 3 7166 7168 7456 3 7166 7456 7454 3 7167 7455 7169 3 7457 7169 7455 3 7168 7170 7458 3 7168 7458 7456 3 7169 7457 7171 3 7459 7171 7457 3 7170 7172 7460 3 7170 7460 7458 3 7171 7459 7173 3 7461 7173 7459 3 7172 7174 7462 3 7172 7462 7460 3 7173 7461 7175 3 7463 7175 7461 3 7174 7176 7464 3 7174 7464 7462 3 7175 7463 7177 3 7465 7177 7463 3 7176 7178 7466 3 7176 7466 7464 3 7177 7465 7179 3 7467 7179 7465 3 7178 7180 7468 3 7178 7468 7466 3 7179 7467 7181 3 7469 7181 7467 3 7180 7182 7470 3 7180 7470 7468 3 7181 7469 7183 3 7471 7183 7469 3 7182 7184 7472 3 7182 7472 7470 3 7183 7471 7473 3 7183 7473 7185 3 7184 7186 7474 3 7184 7474 7472 3 7185 7473 7475 3 7185 7475 7187 3 7186 7188 7476 3 7186 7476 7474 3 7187 7475 7477 3 7187 7477 7189 3 7188 7190 7478 3 7188 7478 7476 3 7189 7477 7479 3 7189 7479 7191 3 7190 7192 7478 3 7480 7478 7192 3 7191 7479 7481 3 7191 7481 7193 3 7192 7194 7480 3 7482 7480 7194 3 7193 7481 7483 3 7193 7483 7195 3 7194 7196 7482 3 7484 7482 7196 3 7195 7483 7485 3 7195 7485 7197 3 7196 7198 7484 3 7486 7484 7198 3 7197 7485 7487 3 7197 7487 7199 3 7198 7200 7486 3 7488 7486 7200 3 7199 7487 7489 3 7199 7489 7201 3 7200 7202 7488 3 7490 7488 7202 3 7201 7489 7491 3 7201 7491 7203 3 7202 7204 7490 3 7492 7490 7204 3 7203 7491 7493 3 7203 7493 7205 3 7204 7206 7492 3 7494 7492 7206 3 7205 7493 7495 3 7205 7495 7207 3 7206 7208 7494 3 7496 7494 7208 3 7207 7495 7497 3 7207 7497 7209 3 7208 7210 7496 3 7498 7496 7210 3 7209 7497 7499 3 7209 7499 7211 3 7210 7212 7498 3 7500 7498 7212 3 7211 7499 7501 3 7211 7501 7213 3 7212 7214 7500 3 7502 7500 7214 3 7213 7501 7503 3 7213 7503 7215 3 7214 7216 7502 3 7504 7502 7216 3 7215 7503 7505 3 7215 7505 7217 3 7216 7218 7504 3 7506 7504 7218 3 7217 7505 7507 3 7217 7507 7219 3 7218 7220 7506 3 7508 7506 7220 3 7219 7507 7509 3 7219 7509 7221 3 7220 7222 7508 3 7510 7508 7222 3 7221 7509 7511 3 7221 7511 7223 3 7222 7224 7510 3 7512 7510 7224 3 7223 7511 7513 3 7223 7513 7225 3 7224 7226 7512 3 7514 7512 7226 3 7225 7513 7515 3 7225 7515 7227 3 7226 7228 7514 3 7516 7514 7228 3 7227 7515 7517 3 7227 7517 7229 3 7228 7230 7516 3 7518 7516 7230 3 7229 7517 7519 3 7229 7519 7231 3 7230 7232 7518 3 7520 7518 7232 3 7231 7519 7523 3 7231 7523 7235 3 7232 7233 7520 3 7521 7520 7233 3 7233 7236 7521 3 7524 7521 7236 3 7234 7235 7522 3 7523 7522 7235 3 7234 7522 7527 3 7234 7527 7239 3 7236 7237 7524 3 7525 7524 7237 3 7237 7240 7525 3 7528 7525 7240 3 7238 7239 7526 3 7527 7526 7239 3 7238 7526 7308 3 7596 7308 7526 3 7240 7241 7528 3 7529 7528 7241 3 7241 7242 7530 3 7241 7530 7529 3 7242 7243 7531 3 7242 7531 7530 3 7243 7244 7532 3 7243 7532 7531 3 7244 7245 7533 3 7244 7533 7532 3 7245 7246 7534 3 7245 7534 7533 3 7246 7247 7535 3 7246 7535 7534 3 7247 7248 7536 3 7247 7536 7535 3 7248 7249 7537 3 7248 7537 7536 3 7249 7250 7538 3 7249 7538 7537 3 7250 7251 7539 3 7250 7539 7538 3 7251 7252 7540 3 7251 7540 7539 3 7252 7253 7541 3 7252 7541 7540 3 7253 7254 7542 3 7253 7542 7541 3 7254 7255 7543 3 7254 7543 7542 3 7255 7256 7544 3 7255 7544 7543 3 7256 7257 7545 3 7256 7545 7544 3 7257 7258 7546 3 7257 7546 7545 3 7258 7259 7547 3 7258 7547 7546 3 7259 7260 7548 3 7259 7548 7547 3 7260 7261 7549 3 7260 7549 7548 3 7261 7262 7550 3 7261 7550 7549 3 7262 7263 7551 3 7262 7551 7550 3 7263 7264 7552 3 7263 7552 7551 3 7264 7265 7553 3 7264 7553 7552 3 7265 7266 7554 3 7265 7554 7553 3 7266 7267 7555 3 7266 7555 7554 3 7267 7268 7556 3 7267 7556 7555 3 7268 7269 7557 3 7268 7557 7556 3 7269 7270 7558 3 7269 7558 7557 3 7270 7271 7559 3 7270 7559 7558 3 7271 7272 7560 3 7271 7560 7559 3 7272 7273 7561 3 7272 7561 7560 3 7273 7274 7562 3 7273 7562 7561 3 7274 7275 7563 3 7274 7563 7562 3 7275 7276 7564 3 7275 7564 7563 3 7276 7277 7565 3 7276 7565 7564 3 7277 7278 7566 3 7277 7566 7565 3 7278 7279 7567 3 7278 7567 7566 3 7279 7280 7568 3 7279 7568 7567 3 7280 7281 7569 3 7280 7569 7568 3 7281 7282 7570 3 7281 7570 7569 3 7282 7283 7571 3 7282 7571 7570 3 7283 7284 7572 3 7283 7572 7571 3 7284 7285 7573 3 7284 7573 7572 3 7285 7286 7574 3 7285 7574 7573 3 7286 7287 7575 3 7286 7575 7574 3 7287 7288 7576 3 7287 7576 7575 3 7288 7289 7577 3 7288 7577 7576 3 7289 7290 7578 3 7289 7578 7577 3 7290 7291 7579 3 7290 7579 7578 3 7291 7292 7580 3 7291 7580 7579 3 7292 7293 7581 3 7292 7581 7580 3 7293 7294 7582 3 7293 7582 7581 3 7294 7295 7582 3 7583 7582 7295 3 7295 7296 7583 3 7584 7583 7296 3 7296 7297 7584 3 7585 7584 7297 3 7297 7298 7585 3 7586 7585 7298 3 7298 7299 7586 3 7587 7586 7299 3 7299 7300 7587 3 7588 7587 7300 3 7300 7301 7588 3 7589 7588 7301 3 7301 7302 7589 3 7590 7589 7302 3 7302 7303 7590 3 7591 7590 7303 3 7303 7304 7591 3 7592 7591 7304 3 7304 7305 7592 3 7593 7592 7305 3 7305 7306 7593 3 7594 7593 7306 3 7306 7307 7594 3 7595 7594 7307 3 7307 7308 7595 3 7596 7595 7308 3 7309 7597 7598 3 7309 7598 7310 3 7309 7379 7667 3 7309 7667 7597 3 7310 7598 7599 3 7310 7599 7311 3 7311 7599 7600 3 7311 7600 7312 3 7312 7600 7601 3 7312 7601 7313 3 7313 7601 7602 3 7313 7602 7314 3 7314 7602 7603 3 7314 7603 7315 3 7315 7603 7604 3 7315 7604 7316 3 7316 7604 7605 3 7316 7605 7317 3 7317 7605 7606 3 7317 7606 7318 3 7318 7606 7607 3 7318 7607 7319 3 7319 7607 7608 3 7319 7608 7320 3 7320 7608 7609 3 7320 7609 7321 3 7321 7609 7610 3 7321 7610 7322 3 7322 7610 7611 3 7322 7611 7323 3 7323 7611 7612 3 7323 7612 7324 3 7324 7612 7613 3 7324 7613 7325 3 7325 7613 7614 3 7325 7614 7326 3 7326 7614 7615 3 7326 7615 7327 3 7327 7615 7616 3 7327 7616 7328 3 7328 7616 7617 3 7328 7617 7329 3 7329 7617 7618 3 7329 7618 7330 3 7330 7618 7619 3 7330 7619 7331 3 7331 7619 7620 3 7331 7620 7332 3 7332 7620 7621 3 7332 7621 7333 3 7333 7621 7622 3 7333 7622 7334 3 7334 7622 7623 3 7334 7623 7335 3 7335 7623 7624 3 7335 7624 7336 3 7336 7624 7625 3 7336 7625 7337 3 7337 7625 7626 3 7337 7626 7338 3 7338 7626 7627 3 7338 7627 7339 3 7339 7627 7628 3 7339 7628 7340 3 7340 7628 7629 3 7340 7629 7341 3 7341 7629 7342 3 7630 7342 7629 3 7342 7630 7343 3 7631 7343 7630 3 7343 7631 7344 3 7632 7344 7631 3 7344 7632 7345 3 7633 7345 7632 3 7345 7633 7346 3 7634 7346 7633 3 7346 7634 7347 3 7635 7347 7634 3 7347 7635 7348 3 7636 7348 7635 3 7348 7636 7349 3 7637 7349 7636 3 7349 7637 7350 3 7638 7350 7637 3 7350 7638 7351 3 7639 7351 7638 3 7351 7639 7352 3 7640 7352 7639 3 7352 7640 7353 3 7641 7353 7640 3 7353 7641 7354 3 7642 7354 7641 3 7354 7642 7355 3 7643 7355 7642 3 7355 7643 7356 3 7644 7356 7643 3 7356 7644 7357 3 7645 7357 7644 3 7357 7645 7358 3 7646 7358 7645 3 7358 7646 7359 3 7647 7359 7646 3 7359 7647 7360 3 7648 7360 7647 3 7360 7648 7361 3 7649 7361 7648 3 7361 7649 7362 3 7650 7362 7649 3 7362 7650 7363 3 7651 7363 7650 3 7363 7651 7364 3 7652 7364 7651 3 7364 7652 7365 3 7653 7365 7652 3 7365 7653 7366 3 7654 7366 7653 3 7366 7654 7367 3 7655 7367 7654 3 7367 7655 7368 3 7656 7368 7655 3 7368 7656 7369 3 7657 7369 7656 3 7369 7657 7370 3 7658 7370 7657 3 7370 7658 7371 3 7659 7371 7658 3 7371 7659 7372 3 7660 7372 7659 3 7372 7660 7373 3 7661 7373 7660 3 7373 7661 7374 3 7662 7374 7661 3 7374 7662 7375 3 7663 7375 7662 3 7375 7663 7376 3 7664 7376 7663 3 7376 7664 7377 3 7665 7377 7664 3 7377 7665 7380 3 7668 7380 7665 3 7378 7666 7379 3 7667 7379 7666 3 7378 7383 7671 3 7378 7671 7666 3 7380 7668 7381 3 7669 7381 7668 3 7381 7669 7384 3 7672 7384 7669 3 7382 7670 7383 3 7671 7383 7670 3 7382 7386 7674 3 7382 7674 7670 3 7384 7672 7385 3 7673 7385 7672 3 7385 7673 7387 3 7675 7387 7673 3 7386 7388 7676 3 7386 7676 7674 3 7387 7675 7389 3 7677 7389 7675 3 7388 7390 7678 3 7388 7678 7676 3 7389 7677 7391 3 7679 7391 7677 3 7390 7392 7680 3 7390 7680 7678 3 7391 7679 7393 3 7681 7393 7679 3 7392 7394 7682 3 7392 7682 7680 3 7393 7681 7395 3 7683 7395 7681 3 7394 7396 7684 3 7394 7684 7682 3 7395 7683 7685 3 7395 7685 7397 3 7396 7398 7686 3 7396 7686 7684 3 7397 7685 7687 3 7397 7687 7399 3 7398 7400 7688 3 7398 7688 7686 3 7399 7687 7689 3 7399 7689 7401 3 7400 7402 7688 3 7690 7688 7402 3 7401 7689 7691 3 7401 7691 7403 3 7402 7404 7690 3 7692 7690 7404 3 7403 7691 7693 3 7403 7693 7405 3 7404 7406 7692 3 7694 7692 7406 3 7405 7693 7695 3 7405 7695 7407 3 7406 7408 7694 3 7696 7694 7408 3 7407 7695 7697 3 7407 7697 7409 3 7408 7410 7696 3 7698 7696 7410 3 7409 7697 7699 3 7409 7699 7411 3 7410 7412 7698 3 7700 7698 7412 3 7411 7699 7701 3 7411 7701 7413 3 7412 7414 7700 3 7702 7700 7414 3 7413 7701 7703 3 7413 7703 7415 3 7414 7416 7702 3 7704 7702 7416 3 7415 7703 7705 3 7415 7705 7417 3 7416 7418 7704 3 7706 7704 7418 3 7417 7705 7707 3 7417 7707 7419 3 7418 7420 7706 3 7708 7706 7420 3 7419 7707 7709 3 7419 7709 7421 3 7420 7422 7708 3 7710 7708 7422 3 7421 7709 7711 3 7421 7711 7423 3 7422 7424 7710 3 7712 7710 7424 3 7423 7711 7713 3 7423 7713 7425 3 7424 7426 7712 3 7714 7712 7426 3 7425 7713 7715 3 7425 7715 7427 3 7426 7428 7714 3 7716 7714 7428 3 7427 7715 7717 3 7427 7717 7429 3 7428 7430 7716 3 7718 7716 7430 3 7429 7717 7719 3 7429 7719 7431 3 7430 7432 7718 3 7720 7718 7432 3 7431 7719 7721 3 7431 7721 7433 3 7432 7434 7720 3 7722 7720 7434 3 7433 7721 7723 3 7433 7723 7435 3 7434 7436 7722 3 7724 7722 7436 3 7435 7723 7725 3 7435 7725 7437 3 7436 7438 7724 3 7726 7724 7438 3 7437 7725 7727 3 7437 7727 7439 3 7438 7440 7726 3 7728 7726 7440 3 7439 7727 7729 3 7439 7729 7441 3 7440 7442 7728 3 7730 7728 7442 3 7441 7729 7731 3 7441 7731 7443 3 7442 7444 7730 3 7732 7730 7444 3 7443 7731 7733 3 7443 7733 7445 3 7444 7446 7732 3 7734 7732 7446 3 7445 7733 7735 3 7445 7735 7447 3 7446 7448 7734 3 7736 7734 7448 3 7447 7735 7737 3 7447 7737 7449 3 7448 7450 7736 3 7738 7736 7450 3 7449 7737 7451 3 7739 7451 7737 3 7450 7452 7738 3 7740 7738 7452 3 7451 7739 7453 3 7741 7453 7739 3 7452 7454 7742 3 7452 7742 7740 3 7453 7741 7455 3 7743 7455 7741 3 7454 7456 7744 3 7454 7744 7742 3 7455 7743 7457 3 7745 7457 7743 3 7456 7458 7746 3 7456 7746 7744 3 7457 7745 7459 3 7747 7459 7745 3 7458 7460 7748 3 7458 7748 7746 3 7459 7747 7461 3 7749 7461 7747 3 7460 7462 7750 3 7460 7750 7748 3 7461 7749 7463 3 7751 7463 7749 3 7462 7464 7752 3 7462 7752 7750 3 7463 7751 7465 3 7753 7465 7751 3 7464 7466 7754 3 7464 7754 7752 3 7465 7753 7467 3 7755 7467 7753 3 7466 7468 7756 3 7466 7756 7754 3 7467 7755 7469 3 7757 7469 7755 3 7468 7470 7758 3 7468 7758 7756 3 7469 7757 7471 3 7759 7471 7757 3 7470 7472 7760 3 7470 7760 7758 3 7471 7759 7473 3 7761 7473 7759 3 7472 7474 7762 3 7472 7762 7760 3 7473 7761 7475 3 7763 7475 7761 3 7474 7476 7764 3 7474 7764 7762 3 7475 7763 7477 3 7765 7477 7763 3 7476 7478 7766 3 7476 7766 7764 3 7477 7765 7479 3 7767 7479 7765 3 7478 7480 7768 3 7478 7768 7766 3 7479 7767 7481 3 7769 7481 7767 3 7480 7482 7770 3 7480 7770 7768 3 7481 7769 7483 3 7771 7483 7769 3 7482 7484 7772 3 7482 7772 7770 3 7483 7771 7485 3 7773 7485 7771 3 7484 7486 7774 3 7484 7774 7772 3 7485 7773 7487 3 7775 7487 7773 3 7486 7488 7776 3 7486 7776 7774 3 7487 7775 7489 3 7777 7489 7775 3 7488 7490 7778 3 7488 7778 7776 3 7489 7777 7491 3 7779 7491 7777 3 7490 7492 7780 3 7490 7780 7778 3 7491 7779 7493 3 7781 7493 7779 3 7492 7494 7782 3 7492 7782 7780 3 7493 7781 7495 3 7783 7495 7781 3 7494 7496 7784 3 7494 7784 7782 3 7495 7783 7497 3 7785 7497 7783 3 7496 7498 7786 3 7496 7786 7784 3 7497 7785 7499 3 7787 7499 7785 3 7498 7500 7788 3 7498 7788 7786 3 7499 7787 7501 3 7789 7501 7787 3 7500 7502 7790 3 7500 7790 7788 3 7501 7789 7503 3 7791 7503 7789 3 7502 7504 7792 3 7502 7792 7790 3 7503 7791 7793 3 7503 7793 7505 3 7504 7506 7794 3 7504 7794 7792 3 7505 7793 7795 3 7505 7795 7507 3 7506 7508 7794 3 7796 7794 7508 3 7507 7795 7797 3 7507 7797 7509 3 7508 7510 7796 3 7798 7796 7510 3 7509 7797 7799 3 7509 7799 7511 3 7510 7512 7798 3 7800 7798 7512 3 7511 7799 7801 3 7511 7801 7513 3 7512 7514 7800 3 7802 7800 7514 3 7513 7801 7803 3 7513 7803 7515 3 7514 7516 7802 3 7804 7802 7516 3 7515 7803 7805 3 7515 7805 7517 3 7516 7518 7804 3 7806 7804 7518 3 7517 7805 7807 3 7517 7807 7519 3 7518 7520 7806 3 7808 7806 7520 3 7519 7807 7811 3 7519 7811 7523 3 7520 7521 7808 3 7809 7808 7521 3 7521 7524 7809 3 7812 7809 7524 3 7522 7523 7810 3 7811 7810 7523 3 7522 7810 7815 3 7522 7815 7527 3 7524 7525 7812 3 7813 7812 7525 3 7525 7528 7813 3 7816 7813 7528 3 7526 7527 7814 3 7815 7814 7527 3 7526 7814 7884 3 7526 7884 7596 3 7528 7529 7816 3 7817 7816 7529 3 7529 7530 7817 3 7818 7817 7530 3 7530 7531 7818 3 7819 7818 7531 3 7531 7532 7819 3 7820 7819 7532 3 7532 7533 7820 3 7821 7820 7533 3 7533 7534 7821 3 7822 7821 7534 3 7534 7535 7822 3 7823 7822 7535 3 7535 7536 7823 3 7824 7823 7536 3 7536 7537 7824 3 7825 7824 7537 3 7537 7538 7825 3 7826 7825 7538 3 7538 7539 7826 3 7827 7826 7539 3 7539 7540 7827 3 7828 7827 7540 3 7540 7541 7828 3 7829 7828 7541 3 7541 7542 7829 3 7830 7829 7542 3 7542 7543 7830 3 7831 7830 7543 3 7543 7544 7831 3 7832 7831 7544 3 7544 7545 7832 3 7833 7832 7545 3 7545 7546 7833 3 7834 7833 7546 3 7546 7547 7834 3 7835 7834 7547 3 7547 7548 7835 3 7836 7835 7548 3 7548 7549 7836 3 7837 7836 7549 3 7549 7550 7837 3 7838 7837 7550 3 7550 7551 7838 3 7839 7838 7551 3 7551 7552 7839 3 7840 7839 7552 3 7552 7553 7840 3 7841 7840 7553 3 7553 7554 7841 3 7842 7841 7554 3 7554 7555 7842 3 7843 7842 7555 3 7555 7556 7843 3 7844 7843 7556 3 7556 7557 7844 3 7845 7844 7557 3 7557 7558 7845 3 7846 7845 7558 3 7558 7559 7846 3 7847 7846 7559 3 7559 7560 7848 3 7559 7848 7847 3 7560 7561 7849 3 7560 7849 7848 3 7561 7562 7850 3 7561 7850 7849 3 7562 7563 7851 3 7562 7851 7850 3 7563 7564 7852 3 7563 7852 7851 3 7564 7565 7853 3 7564 7853 7852 3 7565 7566 7854 3 7565 7854 7853 3 7566 7567 7855 3 7566 7855 7854 3 7567 7568 7856 3 7567 7856 7855 3 7568 7569 7857 3 7568 7857 7856 3 7569 7570 7858 3 7569 7858 7857 3 7570 7571 7859 3 7570 7859 7858 3 7571 7572 7860 3 7571 7860 7859 3 7572 7573 7861 3 7572 7861 7860 3 7573 7574 7862 3 7573 7862 7861 3 7574 7575 7863 3 7574 7863 7862 3 7575 7576 7864 3 7575 7864 7863 3 7576 7577 7865 3 7576 7865 7864 3 7577 7578 7866 3 7577 7866 7865 3 7578 7579 7867 3 7578 7867 7866 3 7579 7580 7868 3 7579 7868 7867 3 7580 7581 7869 3 7580 7869 7868 3 7581 7582 7870 3 7581 7870 7869 3 7582 7583 7871 3 7582 7871 7870 3 7583 7584 7872 3 7583 7872 7871 3 7584 7585 7873 3 7584 7873 7872 3 7585 7586 7874 3 7585 7874 7873 3 7586 7587 7875 3 7586 7875 7874 3 7587 7588 7876 3 7587 7876 7875 3 7588 7589 7877 3 7588 7877 7876 3 7589 7590 7878 3 7589 7878 7877 3 7590 7591 7879 3 7590 7879 7878 3 7591 7592 7880 3 7591 7880 7879 3 7592 7593 7881 3 7592 7881 7880 3 7593 7594 7882 3 7593 7882 7881 3 7594 7595 7883 3 7594 7883 7882 3 7595 7596 7884 3 7595 7884 7883 3 7597 7885 7598 3 7886 7598 7885 3 7597 7667 7885 3 7955 7885 7667 3 7598 7886 7599 3 7887 7599 7886 3 7599 7887 7600 3 7888 7600 7887 3 7600 7888 7601 3 7889 7601 7888 3 7601 7889 7602 3 7890 7602 7889 3 7602 7890 7603 3 7891 7603 7890 3 7603 7891 7604 3 7892 7604 7891 3 7604 7892 7605 3 7893 7605 7892 3 7605 7893 7606 3 7894 7606 7893 3 7606 7894 7607 3 7895 7607 7894 3 7607 7895 7608 3 7896 7608 7895 3 7608 7896 7609 3 7897 7609 7896 3 7609 7897 7610 3 7898 7610 7897 3 7610 7898 7899 3 7610 7899 7611 3 7611 7899 7900 3 7611 7900 7612 3 7612 7900 7901 3 7612 7901 7613 3 7613 7901 7902 3 7613 7902 7614 3 7614 7902 7903 3 7614 7903 7615 3 7615 7903 7904 3 7615 7904 7616 3 7616 7904 7905 3 7616 7905 7617 3 7617 7905 7906 3 7617 7906 7618 3 7618 7906 7907 3 7618 7907 7619 3 7619 7907 7908 3 7619 7908 7620 3 7620 7908 7909 3 7620 7909 7621 3 7621 7909 7910 3 7621 7910 7622 3 7622 7910 7911 3 7622 7911 7623 3 7623 7911 7912 3 7623 7912 7624 3 7624 7912 7913 3 7624 7913 7625 3 7625 7913 7914 3 7625 7914 7626 3 7626 7914 7915 3 7626 7915 7627 3 7627 7915 7916 3 7627 7916 7628 3 7628 7916 7917 3 7628 7917 7629 3 7629 7917 7918 3 7629 7918 7630 3 7630 7918 7919 3 7630 7919 7631 3 7631 7919 7920 3 7631 7920 7632 3 7632 7920 7921 3 7632 7921 7633 3 7633 7921 7922 3 7633 7922 7634 3 7634 7922 7923 3 7634 7923 7635 3 7635 7923 7924 3 7635 7924 7636 3 7636 7924 7925 3 7636 7925 7637 3 7637 7925 7926 3 7637 7926 7638 3 7638 7926 7927 3 7638 7927 7639 3 7639 7927 7928 3 7639 7928 7640 3 7640 7928 7929 3 7640 7929 7641 3 7641 7929 7930 3 7641 7930 7642 3 7642 7930 7931 3 7642 7931 7643 3 7643 7931 7932 3 7643 7932 7644 3 7644 7932 7933 3 7644 7933 7645 3 7645 7933 7934 3 7645 7934 7646 3 7646 7934 7935 3 7646 7935 7647 3 7647 7935 7936 3 7647 7936 7648 3 7648 7936 7937 3 7648 7937 7649 3 7649 7937 7938 3 7649 7938 7650 3 7650 7938 7939 3 7650 7939 7651 3 7651 7939 7940 3 7651 7940 7652 3 7652 7940 7941 3 7652 7941 7653 3 7653 7941 7942 3 7653 7942 7654 3 7654 7942 7943 3 7654 7943 7655 3 7655 7943 7944 3 7655 7944 7656 3 7656 7944 7945 3 7656 7945 7657 3 7657 7945 7946 3 7657 7946 7658 3 7658 7946 7947 3 7658 7947 7659 3 7659 7947 7948 3 7659 7948 7660 3 7660 7948 7949 3 7660 7949 7661 3 7661 7949 7950 3 7661 7950 7662 3 7662 7950 7951 3 7662 7951 7663 3 7663 7951 7952 3 7663 7952 7664 3 7664 7952 7665 3 7953 7665 7952 3 7665 7953 7668 3 7956 7668 7953 3 7666 7954 7667 3 7955 7667 7954 3 7666 7671 7959 3 7666 7959 7954 3 7668 7956 7669 3 7957 7669 7956 3 7669 7957 7672 3 7960 7672 7957 3 7670 7958 7671 3 7959 7671 7958 3 7670 7674 7962 3 7670 7962 7958 3 7672 7960 7673 3 7961 7673 7960 3 7673 7961 7675 3 7963 7675 7961 3 7674 7676 7964 3 7674 7964 7962 3 7675 7963 7677 3 7965 7677 7963 3 7676 7678 7966 3 7676 7966 7964 3 7677 7965 7679 3 7967 7679 7965 3 7678 7680 7968 3 7678 7968 7966 3 7679 7967 7681 3 7969 7681 7967 3 7680 7682 7970 3 7680 7970 7968 3 7681 7969 7683 3 7971 7683 7969 3 7682 7684 7972 3 7682 7972 7970 3 7683 7971 7685 3 7973 7685 7971 3 7684 7686 7974 3 7684 7974 7972 3 7685 7973 7687 3 7975 7687 7973 3 7686 7688 7976 3 7686 7976 7974 3 7687 7975 7689 3 7977 7689 7975 3 7688 7690 7978 3 7688 7978 7976 3 7689 7977 7691 3 7979 7691 7977 3 7690 7692 7980 3 7690 7980 7978 3 7691 7979 7693 3 7981 7693 7979 3 7692 7694 7982 3 7692 7982 7980 3 7693 7981 7695 3 7983 7695 7981 3 7694 7696 7984 3 7694 7984 7982 3 7695 7983 7697 3 7985 7697 7983 3 7696 7698 7986 3 7696 7986 7984 3 7697 7985 7699 3 7987 7699 7985 3 7698 7700 7988 3 7698 7988 7986 3 7699 7987 7701 3 7989 7701 7987 3 7700 7702 7990 3 7700 7990 7988 3 7701 7989 7703 3 7991 7703 7989 3 7702 7704 7992 3 7702 7992 7990 3 7703 7991 7705 3 7993 7705 7991 3 7704 7706 7994 3 7704 7994 7992 3 7705 7993 7707 3 7995 7707 7993 3 7706 7708 7996 3 7706 7996 7994 3 7707 7995 7709 3 7997 7709 7995 3 7708 7710 7998 3 7708 7998 7996 3 7709 7997 7711 3 7999 7711 7997 3 7710 7712 8000 3 7710 8000 7998 3 7711 7999 7713 3 8001 7713 7999 3 7712 7714 8002 3 7712 8002 8000 3 7713 8001 7715 3 8003 7715 8001 3 7714 7716 8004 3 7714 8004 8002 3 7715 8003 7717 3 8005 7717 8003 3 7716 7718 8006 3 7716 8006 8004 3 7717 8005 7719 3 8007 7719 8005 3 7718 7720 8008 3 7718 8008 8006 3 7719 8007 8009 3 7719 8009 7721 3 7720 7722 8008 3 8010 8008 7722 3 7721 8009 8011 3 7721 8011 7723 3 7722 7724 8010 3 8012 8010 7724 3 7723 8011 8013 3 7723 8013 7725 3 7724 7726 8012 3 8014 8012 7726 3 7725 8013 8015 3 7725 8015 7727 3 7726 7728 8014 3 8016 8014 7728 3 7727 8015 8017 3 7727 8017 7729 3 7728 7730 8016 3 8018 8016 7730 3 7729 8017 8019 3 7729 8019 7731 3 7730 7732 8018 3 8020 8018 7732 3 7731 8019 8021 3 7731 8021 7733 3 7732 7734 8020 3 8022 8020 7734 3 7733 8021 8023 3 7733 8023 7735 3 7734 7736 8022 3 8024 8022 7736 3 7735 8023 8025 3 7735 8025 7737 3 7736 7738 8024 3 8026 8024 7738 3 7737 8025 8027 3 7737 8027 7739 3 7738 7740 8026 3 8028 8026 7740 3 7739 8027 8029 3 7739 8029 7741 3 7740 7742 8028 3 8030 8028 7742 3 7741 8029 8031 3 7741 8031 7743 3 7742 7744 8030 3 8032 8030 7744 3 7743 8031 8033 3 7743 8033 7745 3 7744 7746 8032 3 8034 8032 7746 3 7745 8033 8035 3 7745 8035 7747 3 7746 7748 8034 3 8036 8034 7748 3 7747 8035 8037 3 7747 8037 7749 3 7748 7750 8036 3 8038 8036 7750 3 7749 8037 8039 3 7749 8039 7751 3 7750 7752 8038 3 8040 8038 7752 3 7751 8039 8041 3 7751 8041 7753 3 7752 7754 8040 3 8042 8040 7754 3 7753 8041 8043 3 7753 8043 7755 3 7754 7756 8042 3 8044 8042 7756 3 7755 8043 8045 3 7755 8045 7757 3 7756 7758 8044 3 8046 8044 7758 3 7757 8045 8047 3 7757 8047 7759 3 7758 7760 8046 3 8048 8046 7760 3 7759 8047 8049 3 7759 8049 7761 3 7760 7762 8048 3 8050 8048 7762 3 7761 8049 8051 3 7761 8051 7763 3 7762 7764 8050 3 8052 8050 7764 3 7763 8051 8053 3 7763 8053 7765 3 7764 7766 8052 3 8054 8052 7766 3 7765 8053 8055 3 7765 8055 7767 3 7766 7768 8054 3 8056 8054 7768 3 7767 8055 8057 3 7767 8057 7769 3 7768 7770 8056 3 8058 8056 7770 3 7769 8057 8059 3 7769 8059 7771 3 7770 7772 8058 3 8060 8058 7772 3 7771 8059 8061 3 7771 8061 7773 3 7772 7774 8060 3 8062 8060 7774 3 7773 8061 8063 3 7773 8063 7775 3 7774 7776 8064 3 7774 8064 8062 3 7775 8063 7777 3 8065 7777 8063 3 7776 7778 8066 3 7776 8066 8064 3 7777 8065 7779 3 8067 7779 8065 3 7778 7780 8068 3 7778 8068 8066 3 7779 8067 7781 3 8069 7781 8067 3 7780 7782 8070 3 7780 8070 8068 3 7781 8069 7783 3 8071 7783 8069 3 7782 7784 8072 3 7782 8072 8070 3 7783 8071 7785 3 8073 7785 8071 3 7784 7786 8074 3 7784 8074 8072 3 7785 8073 7787 3 8075 7787 8073 3 7786 7788 8076 3 7786 8076 8074 3 7787 8075 7789 3 8077 7789 8075 3 7788 7790 8078 3 7788 8078 8076 3 7789 8077 7791 3 8079 7791 8077 3 7790 7792 8080 3 7790 8080 8078 3 7791 8079 7793 3 8081 7793 8079 3 7792 7794 8082 3 7792 8082 8080 3 7793 8081 7795 3 8083 7795 8081 3 7794 7796 8084 3 7794 8084 8082 3 7795 8083 7797 3 8085 7797 8083 3 7796 7798 8086 3 7796 8086 8084 3 7797 8085 7799 3 8087 7799 8085 3 7798 7800 8088 3 7798 8088 8086 3 7799 8087 7801 3 8089 7801 8087 3 7800 7802 8090 3 7800 8090 8088 3 7801 8089 7803 3 8091 7803 8089 3 7802 7804 8092 3 7802 8092 8090 3 7803 8091 7805 3 8093 7805 8091 3 7804 7806 8094 3 7804 8094 8092 3 7805 8093 7807 3 8095 7807 8093 3 7806 7808 8096 3 7806 8096 8094 3 7807 8095 7811 3 8099 7811 8095 3 7808 7809 8097 3 7808 8097 8096 3 7809 7812 8100 3 7809 8100 8097 3 7810 7811 8099 3 7810 8099 8098 3 7810 8098 7815 3 8103 7815 8098 3 7812 7813 8101 3 7812 8101 8100 3 7813 7816 8104 3 7813 8104 8101 3 7814 7815 8103 3 7814 8103 8102 3 7814 8102 7884 3 8172 7884 8102 3 7816 7817 8105 3 7816 8105 8104 3 7817 7818 8106 3 7817 8106 8105 3 7818 7819 8107 3 7818 8107 8106 3 7819 7820 8108 3 7819 8108 8107 3 7820 7821 8109 3 7820 8109 8108 3 7821 7822 8110 3 7821 8110 8109 3 7822 7823 8111 3 7822 8111 8110 3 7823 7824 8112 3 7823 8112 8111 3 7824 7825 8113 3 7824 8113 8112 3 7825 7826 8114 3 7825 8114 8113 3 7826 7827 8115 3 7826 8115 8114 3 7827 7828 8116 3 7827 8116 8115 3 7828 7829 8117 3 7828 8117 8116 3 7829 7830 8117 3 8118 8117 7830 3 7830 7831 8118 3 8119 8118 7831 3 7831 7832 8119 3 8120 8119 7832 3 7832 7833 8120 3 8121 8120 7833 3 7833 7834 8121 3 8122 8121 7834 3 7834 7835 8122 3 8123 8122 7835 3 7835 7836 8123 3 8124 8123 7836 3 7836 7837 8124 3 8125 8124 7837 3 7837 7838 8125 3 8126 8125 7838 3 7838 7839 8126 3 8127 8126 7839 3 7839 7840 8127 3 8128 8127 7840 3 7840 7841 8128 3 8129 8128 7841 3 7841 7842 8129 3 8130 8129 7842 3 7842 7843 8130 3 8131 8130 7843 3 7843 7844 8131 3 8132 8131 7844 3 7844 7845 8132 3 8133 8132 7845 3 7845 7846 8133 3 8134 8133 7846 3 7846 7847 8134 3 8135 8134 7847 3 7847 7848 8135 3 8136 8135 7848 3 7848 7849 8136 3 8137 8136 7849 3 7849 7850 8137 3 8138 8137 7850 3 7850 7851 8138 3 8139 8138 7851 3 7851 7852 8139 3 8140 8139 7852 3 7852 7853 8140 3 8141 8140 7853 3 7853 7854 8141 3 8142 8141 7854 3 7854 7855 8142 3 8143 8142 7855 3 7855 7856 8143 3 8144 8143 7856 3 7856 7857 8144 3 8145 8144 7857 3 7857 7858 8145 3 8146 8145 7858 3 7858 7859 8146 3 8147 8146 7859 3 7859 7860 8147 3 8148 8147 7860 3 7860 7861 8148 3 8149 8148 7861 3 7861 7862 8149 3 8150 8149 7862 3 7862 7863 8150 3 8151 8150 7863 3 7863 7864 8151 3 8152 8151 7864 3 7864 7865 8152 3 8153 8152 7865 3 7865 7866 8153 3 8154 8153 7866 3 7866 7867 8154 3 8155 8154 7867 3 7867 7868 8155 3 8156 8155 7868 3 7868 7869 8156 3 8157 8156 7869 3 7869 7870 8157 3 8158 8157 7870 3 7870 7871 8158 3 8159 8158 7871 3 7871 7872 8159 3 8160 8159 7872 3 7872 7873 8160 3 8161 8160 7873 3 7873 7874 8161 3 8162 8161 7874 3 7874 7875 8162 3 8163 8162 7875 3 7875 7876 8163 3 8164 8163 7876 3 7876 7877 8164 3 8165 8164 7877 3 7877 7878 8165 3 8166 8165 7878 3 7878 7879 8166 3 8167 8166 7879 3 7879 7880 8167 3 8168 8167 7880 3 7880 7881 8168 3 8169 8168 7881 3 7881 7882 8169 3 8170 8169 7882 3 7882 7883 8170 3 8171 8170 7883 3 7883 7884 8171 3 8172 8171 7884 3 7885 8173 7886 3 8174 7886 8173 3 7885 7955 8243 3 7885 8243 8173 3 7886 8174 7887 3 8175 7887 8174 3 7887 8175 7888 3 8176 7888 8175 3 7888 8176 7889 3 8177 7889 8176 3 7889 8177 7890 3 8178 7890 8177 3 7890 8178 7891 3 8179 7891 8178 3 7891 8179 7892 3 8180 7892 8179 3 7892 8180 7893 3 8181 7893 8180 3 7893 8181 7894 3 8182 7894 8181 3 7894 8182 7895 3 8183 7895 8182 3 7895 8183 7896 3 8184 7896 8183 3 7896 8184 7897 3 8185 7897 8184 3 7897 8185 7898 3 8186 7898 8185 3 7898 8186 7899 3 8187 7899 8186 3 7899 8187 7900 3 8188 7900 8187 3 7900 8188 7901 3 8189 7901 8188 3 7901 8189 7902 3 8190 7902 8189 3 7902 8190 7903 3 8191 7903 8190 3 7903 8191 7904 3 8192 7904 8191 3 7904 8192 7905 3 8193 7905 8192 3 7905 8193 7906 3 8194 7906 8193 3 7906 8194 7907 3 8195 7907 8194 3 7907 8195 7908 3 8196 7908 8195 3 7908 8196 7909 3 8197 7909 8196 3 7909 8197 7910 3 8198 7910 8197 3 7910 8198 7911 3 8199 7911 8198 3 7911 8199 7912 3 8200 7912 8199 3 7912 8200 7913 3 8201 7913 8200 3 7913 8201 7914 3 8202 7914 8201 3 7914 8202 7915 3 8203 7915 8202 3 7915 8203 7916 3 8204 7916 8203 3 7916 8204 7917 3 8205 7917 8204 3 7917 8205 7918 3 8206 7918 8205 3 7918 8206 7919 3 8207 7919 8206 3 7919 8207 7920 3 8208 7920 8207 3 7920 8208 7921 3 8209 7921 8208 3 7921 8209 7922 3 8210 7922 8209 3 7922 8210 7923 3 8211 7923 8210 3 7923 8211 7924 3 8212 7924 8211 3 7924 8212 7925 3 8213 7925 8212 3 7925 8213 7926 3 8214 7926 8213 3 7926 8214 7927 3 8215 7927 8214 3 7927 8215 7928 3 8216 7928 8215 3 7928 8216 7929 3 8217 7929 8216 3 7929 8217 7930 3 8218 7930 8217 3 7930 8218 7931 3 8219 7931 8218 3 7931 8219 7932 3 8220 7932 8219 3 7932 8220 7933 3 8221 7933 8220 3 7933 8221 7934 3 8222 7934 8221 3 7934 8222 7935 3 8223 7935 8222 3 7935 8223 7936 3 8224 7936 8223 3 7936 8224 7937 3 8225 7937 8224 3 7937 8225 7938 3 8226 7938 8225 3 7938 8226 7939 3 8227 7939 8226 3 7939 8227 8228 3 7939 8228 7940 3 7940 8228 8229 3 7940 8229 7941 3 7941 8229 8230 3 7941 8230 7942 3 7942 8230 8231 3 7942 8231 7943 3 7943 8231 8232 3 7943 8232 7944 3 7944 8232 8233 3 7944 8233 7945 3 7945 8233 8234 3 7945 8234 7946 3 7946 8234 8235 3 7946 8235 7947 3 7947 8235 8236 3 7947 8236 7948 3 7948 8236 8237 3 7948 8237 7949 3 7949 8237 8238 3 7949 8238 7950 3 7950 8238 8239 3 7950 8239 7951 3 7951 8239 8240 3 7951 8240 7952 3 7952 8240 8241 3 7952 8241 7953 3 7953 8241 8244 3 7953 8244 7956 3 7954 8242 8243 3 7954 8243 7955 3 7954 7959 8242 3 8247 8242 7959 3 7956 8244 8245 3 7956 8245 7957 3 7957 8245 8248 3 7957 8248 7960 3 7958 8246 8247 3 7958 8247 7959 3 7958 7962 8246 3 8250 8246 7962 3 7960 8248 8249 3 7960 8249 7961 3 7961 8249 8251 3 7961 8251 7963 3 7962 7964 8250 3 8252 8250 7964 3 7963 8251 8253 3 7963 8253 7965 3 7964 7966 8252 3 8254 8252 7966 3 7965 8253 8255 3 7965 8255 7967 3 7966 7968 8254 3 8256 8254 7968 3 7967 8255 8257 3 7967 8257 7969 3 7968 7970 8256 3 8258 8256 7970 3 7969 8257 8259 3 7969 8259 7971 3 7970 7972 8258 3 8260 8258 7972 3 7971 8259 8261 3 7971 8261 7973 3 7972 7974 8260 3 8262 8260 7974 3 7973 8261 8263 3 7973 8263 7975 3 7974 7976 8262 3 8264 8262 7976 3 7975 8263 8265 3 7975 8265 7977 3 7976 7978 8264 3 8266 8264 7978 3 7977 8265 8267 3 7977 8267 7979 3 7978 7980 8266 3 8268 8266 7980 3 7979 8267 8269 3 7979 8269 7981 3 7980 7982 8268 3 8270 8268 7982 3 7981 8269 8271 3 7981 8271 7983 3 7982 7984 8270 3 8272 8270 7984 3 7983 8271 8273 3 7983 8273 7985 3 7984 7986 8272 3 8274 8272 7986 3 7985 8273 8275 3 7985 8275 7987 3 7986 7988 8274 3 8276 8274 7988 3 7987 8275 8277 3 7987 8277 7989 3 7988 7990 8276 3 8278 8276 7990 3 7989 8277 8279 3 7989 8279 7991 3 7990 7992 8278 3 8280 8278 7992 3 7991 8279 8281 3 7991 8281 7993 3 7992 7994 8280 3 8282 8280 7994 3 7993 8281 8283 3 7993 8283 7995 3 7994 7996 8284 3 7994 8284 8282 3 7995 8283 7997 3 8285 7997 8283 3 7996 7998 8286 3 7996 8286 8284 3 7997 8285 7999 3 8287 7999 8285 3 7998 8000 8288 3 7998 8288 8286 3 7999 8287 8001 3 8289 8001 8287 3 8000 8002 8290 3 8000 8290 8288 3 8001 8289 8003 3 8291 8003 8289 3 8002 8004 8292 3 8002 8292 8290 3 8003 8291 8005 3 8293 8005 8291 3 8004 8006 8294 3 8004 8294 8292 3 8005 8293 8007 3 8295 8007 8293 3 8006 8008 8296 3 8006 8296 8294 3 8007 8295 8009 3 8297 8009 8295 3 8008 8010 8298 3 8008 8298 8296 3 8009 8297 8011 3 8299 8011 8297 3 8010 8012 8300 3 8010 8300 8298 3 8011 8299 8013 3 8301 8013 8299 3 8012 8014 8302 3 8012 8302 8300 3 8013 8301 8015 3 8303 8015 8301 3 8014 8016 8304 3 8014 8304 8302 3 8015 8303 8017 3 8305 8017 8303 3 8016 8018 8306 3 8016 8306 8304 3 8017 8305 8019 3 8307 8019 8305 3 8018 8020 8308 3 8018 8308 8306 3 8019 8307 8021 3 8309 8021 8307 3 8020 8022 8310 3 8020 8310 8308 3 8021 8309 8023 3 8311 8023 8309 3 8022 8024 8312 3 8022 8312 8310 3 8023 8311 8025 3 8313 8025 8311 3 8024 8026 8314 3 8024 8314 8312 3 8025 8313 8027 3 8315 8027 8313 3 8026 8028 8316 3 8026 8316 8314 3 8027 8315 8029 3 8317 8029 8315 3 8028 8030 8318 3 8028 8318 8316 3 8029 8317 8031 3 8319 8031 8317 3 8030 8032 8320 3 8030 8320 8318 3 8031 8319 8033 3 8321 8033 8319 3 8032 8034 8322 3 8032 8322 8320 3 8033 8321 8035 3 8323 8035 8321 3 8034 8036 8324 3 8034 8324 8322 3 8035 8323 8037 3 8325 8037 8323 3 8036 8038 8326 3 8036 8326 8324 3 8037 8325 8039 3 8327 8039 8325 3 8038 8040 8328 3 8038 8328 8326 3 8039 8327 8041 3 8329 8041 8327 3 8040 8042 8330 3 8040 8330 8328 3 8041 8329 8043 3 8331 8043 8329 3 8042 8044 8332 3 8042 8332 8330 3 8043 8331 8045 3 8333 8045 8331 3 8044 8046 8334 3 8044 8334 8332 3 8045 8333 8047 3 8335 8047 8333 3 8046 8048 8336 3 8046 8336 8334 3 8047 8335 8049 3 8337 8049 8335 3 8048 8050 8336 3 8338 8336 8050 3 8049 8337 8051 3 8339 8051 8337 3 8050 8052 8338 3 8340 8338 8052 3 8051 8339 8341 3 8051 8341 8053 3 8052 8054 8340 3 8342 8340 8054 3 8053 8341 8343 3 8053 8343 8055 3 8054 8056 8342 3 8344 8342 8056 3 8055 8343 8345 3 8055 8345 8057 3 8056 8058 8344 3 8346 8344 8058 3 8057 8345 8347 3 8057 8347 8059 3 8058 8060 8346 3 8348 8346 8060 3 8059 8347 8349 3 8059 8349 8061 3 8060 8062 8348 3 8350 8348 8062 3 8061 8349 8351 3 8061 8351 8063 3 8062 8064 8350 3 8352 8350 8064 3 8063 8351 8353 3 8063 8353 8065 3 8064 8066 8352 3 8354 8352 8066 3 8065 8353 8355 3 8065 8355 8067 3 8066 8068 8354 3 8356 8354 8068 3 8067 8355 8357 3 8067 8357 8069 3 8068 8070 8356 3 8358 8356 8070 3 8069 8357 8359 3 8069 8359 8071 3 8070 8072 8358 3 8360 8358 8072 3 8071 8359 8361 3 8071 8361 8073 3 8072 8074 8360 3 8362 8360 8074 3 8073 8361 8363 3 8073 8363 8075 3 8074 8076 8362 3 8364 8362 8076 3 8075 8363 8365 3 8075 8365 8077 3 8076 8078 8364 3 8366 8364 8078 3 8077 8365 8367 3 8077 8367 8079 3 8078 8080 8366 3 8368 8366 8080 3 8079 8367 8369 3 8079 8369 8081 3 8080 8082 8368 3 8370 8368 8082 3 8081 8369 8371 3 8081 8371 8083 3 8082 8084 8370 3 8372 8370 8084 3 8083 8371 8373 3 8083 8373 8085 3 8084 8086 8372 3 8374 8372 8086 3 8085 8373 8375 3 8085 8375 8087 3 8086 8088 8374 3 8376 8374 8088 3 8087 8375 8377 3 8087 8377 8089 3 8088 8090 8376 3 8378 8376 8090 3 8089 8377 8379 3 8089 8379 8091 3 8090 8092 8378 3 8380 8378 8092 3 8091 8379 8381 3 8091 8381 8093 3 8092 8094 8380 3 8382 8380 8094 3 8093 8381 8383 3 8093 8383 8095 3 8094 8096 8382 3 8384 8382 8096 3 8095 8383 8387 3 8095 8387 8099 3 8096 8097 8384 3 8385 8384 8097 3 8097 8100 8385 3 8388 8385 8100 3 8098 8099 8386 3 8387 8386 8099 3 8098 8386 8391 3 8098 8391 8103 3 8100 8101 8388 3 8389 8388 8101 3 8101 8104 8389 3 8392 8389 8104 3 8102 8103 8390 3 8391 8390 8103 3 8102 8390 8460 3 8102 8460 8172 3 8104 8105 8393 3 8104 8393 8392 3 8105 8106 8394 3 8105 8394 8393 3 8106 8107 8395 3 8106 8395 8394 3 8107 8108 8396 3 8107 8396 8395 3 8108 8109 8397 3 8108 8397 8396 3 8109 8110 8398 3 8109 8398 8397 3 8110 8111 8399 3 8110 8399 8398 3 8111 8112 8400 3 8111 8400 8399 3 8112 8113 8401 3 8112 8401 8400 3 8113 8114 8402 3 8113 8402 8401 3 8114 8115 8403 3 8114 8403 8402 3 8115 8116 8404 3 8115 8404 8403 3 8116 8117 8405 3 8116 8405 8404 3 8117 8118 8406 3 8117 8406 8405 3 8118 8119 8407 3 8118 8407 8406 3 8119 8120 8408 3 8119 8408 8407 3 8120 8121 8409 3 8120 8409 8408 3 8121 8122 8410 3 8121 8410 8409 3 8122 8123 8411 3 8122 8411 8410 3 8123 8124 8412 3 8123 8412 8411 3 8124 8125 8413 3 8124 8413 8412 3 8125 8126 8414 3 8125 8414 8413 3 8126 8127 8415 3 8126 8415 8414 3 8127 8128 8416 3 8127 8416 8415 3 8128 8129 8417 3 8128 8417 8416 3 8129 8130 8418 3 8129 8418 8417 3 8130 8131 8419 3 8130 8419 8418 3 8131 8132 8420 3 8131 8420 8419 3 8132 8133 8421 3 8132 8421 8420 3 8133 8134 8422 3 8133 8422 8421 3 8134 8135 8423 3 8134 8423 8422 3 8135 8136 8424 3 8135 8424 8423 3 8136 8137 8425 3 8136 8425 8424 3 8137 8138 8426 3 8137 8426 8425 3 8138 8139 8427 3 8138 8427 8426 3 8139 8140 8428 3 8139 8428 8427 3 8140 8141 8429 3 8140 8429 8428 3 8141 8142 8430 3 8141 8430 8429 3 8142 8143 8431 3 8142 8431 8430 3 8143 8144 8432 3 8143 8432 8431 3 8144 8145 8433 3 8144 8433 8432 3 8145 8146 8434 3 8145 8434 8433 3 8146 8147 8435 3 8146 8435 8434 3 8147 8148 8436 3 8147 8436 8435 3 8148 8149 8437 3 8148 8437 8436 3 8149 8150 8438 3 8149 8438 8437 3 8150 8151 8439 3 8150 8439 8438 3 8151 8152 8440 3 8151 8440 8439 3 8152 8153 8441 3 8152 8441 8440 3 8153 8154 8442 3 8153 8442 8441 3 8154 8155 8443 3 8154 8443 8442 3 8155 8156 8444 3 8155 8444 8443 3 8156 8157 8445 3 8156 8445 8444 3 8157 8158 8446 3 8157 8446 8445 3 8158 8159 8447 3 8158 8447 8446 3 8159 8160 8447 3 8448 8447 8160 3 8160 8161 8448 3 8449 8448 8161 3 8161 8162 8449 3 8450 8449 8162 3 8162 8163 8450 3 8451 8450 8163 3 8163 8164 8451 3 8452 8451 8164 3 8164 8165 8452 3 8453 8452 8165 3 8165 8166 8453 3 8454 8453 8166 3 8166 8167 8454 3 8455 8454 8167 3 8167 8168 8455 3 8456 8455 8168 3 8168 8169 8456 3 8457 8456 8169 3 8169 8170 8457 3 8458 8457 8170 3 8170 8171 8458 3 8459 8458 8171 3 8171 8172 8459 3 8460 8459 8172 3 8173 8461 8462 3 8173 8462 8174 3 8173 8243 8461 3 8531 8461 8243 3 8174 8462 8463 3 8174 8463 8175 3 8175 8463 8464 3 8175 8464 8176 3 8176 8464 8465 3 8176 8465 8177 3 8177 8465 8466 3 8177 8466 8178 3 8178 8466 8467 3 8178 8467 8179 3 8179 8467 8468 3 8179 8468 8180 3 8180 8468 8469 3 8180 8469 8181 3 8181 8469 8470 3 8181 8470 8182 3 8182 8470 8471 3 8182 8471 8183 3 8183 8471 8472 3 8183 8472 8184 3 8184 8472 8473 3 8184 8473 8185 3 8185 8473 8474 3 8185 8474 8186 3 8186 8474 8475 3 8186 8475 8187 3 8187 8475 8476 3 8187 8476 8188 3 8188 8476 8477 3 8188 8477 8189 3 8189 8477 8478 3 8189 8478 8190 3 8190 8478 8479 3 8190 8479 8191 3 8191 8479 8480 3 8191 8480 8192 3 8192 8480 8481 3 8192 8481 8193 3 8193 8481 8482 3 8193 8482 8194 3 8194 8482 8483 3 8194 8483 8195 3 8195 8483 8484 3 8195 8484 8196 3 8196 8484 8485 3 8196 8485 8197 3 8197 8485 8486 3 8197 8486 8198 3 8198 8486 8487 3 8198 8487 8199 3 8199 8487 8488 3 8199 8488 8200 3 8200 8488 8489 3 8200 8489 8201 3 8201 8489 8490 3 8201 8490 8202 3 8202 8490 8491 3 8202 8491 8203 3 8203 8491 8492 3 8203 8492 8204 3 8204 8492 8493 3 8204 8493 8205 3 8205 8493 8494 3 8205 8494 8206 3 8206 8494 8495 3 8206 8495 8207 3 8207 8495 8496 3 8207 8496 8208 3 8208 8496 8497 3 8208 8497 8209 3 8209 8497 8498 3 8209 8498 8210 3 8210 8498 8499 3 8210 8499 8211 3 8211 8499 8500 3 8211 8500 8212 3 8212 8500 8501 3 8212 8501 8213 3 8213 8501 8502 3 8213 8502 8214 3 8214 8502 8503 3 8214 8503 8215 3 8215 8503 8504 3 8215 8504 8216 3 8216 8504 8505 3 8216 8505 8217 3 8217 8505 8506 3 8217 8506 8218 3 8218 8506 8507 3 8218 8507 8219 3 8219 8507 8220 3 8508 8220 8507 3 8220 8508 8221 3 8509 8221 8508 3 8221 8509 8222 3 8510 8222 8509 3 8222 8510 8223 3 8511 8223 8510 3 8223 8511 8224 3 8512 8224 8511 3 8224 8512 8225 3 8513 8225 8512 3 8225 8513 8226 3 8514 8226 8513 3 8226 8514 8227 3 8515 8227 8514 3 8227 8515 8228 3 8516 8228 8515 3 8228 8516 8229 3 8517 8229 8516 3 8229 8517 8230 3 8518 8230 8517 3 8230 8518 8231 3 8519 8231 8518 3 8231 8519 8232 3 8520 8232 8519 3 8232 8520 8233 3 8521 8233 8520 3 8233 8521 8234 3 8522 8234 8521 3 8234 8522 8235 3 8523 8235 8522 3 8235 8523 8236 3 8524 8236 8523 3 8236 8524 8237 3 8525 8237 8524 3 8237 8525 8238 3 8526 8238 8525 3 8238 8526 8239 3 8527 8239 8526 3 8239 8527 8240 3 8528 8240 8527 3 8240 8528 8241 3 8529 8241 8528 3 8241 8529 8244 3 8532 8244 8529 3 8242 8530 8243 3 8531 8243 8530 3 8242 8247 8535 3 8242 8535 8530 3 8244 8532 8245 3 8533 8245 8532 3 8245 8533 8248 3 8536 8248 8533 3 8246 8534 8247 3 8535 8247 8534 3 8246 8250 8538 3 8246 8538 8534 3 8248 8536 8249 3 8537 8249 8536 3 8249 8537 8251 3 8539 8251 8537 3 8250 8252 8540 3 8250 8540 8538 3 8251 8539 8253 3 8541 8253 8539 3 8252 8254 8542 3 8252 8542 8540 3 8253 8541 8255 3 8543 8255 8541 3 8254 8256 8544 3 8254 8544 8542 3 8255 8543 8257 3 8545 8257 8543 3 8256 8258 8546 3 8256 8546 8544 3 8257 8545 8259 3 8547 8259 8545 3 8258 8260 8548 3 8258 8548 8546 3 8259 8547 8261 3 8549 8261 8547 3 8260 8262 8550 3 8260 8550 8548 3 8261 8549 8263 3 8551 8263 8549 3 8262 8264 8552 3 8262 8552 8550 3 8263 8551 8265 3 8553 8265 8551 3 8264 8266 8554 3 8264 8554 8552 3 8265 8553 8267 3 8555 8267 8553 3 8266 8268 8556 3 8266 8556 8554 3 8267 8555 8269 3 8557 8269 8555 3 8268 8270 8558 3 8268 8558 8556 3 8269 8557 8271 3 8559 8271 8557 3 8270 8272 8558 3 8560 8558 8272 3 8271 8559 8273 3 8561 8273 8559 3 8272 8274 8560 3 8562 8560 8274 3 8273 8561 8275 3 8563 8275 8561 3 8274 8276 8562 3 8564 8562 8276 3 8275 8563 8565 3 8275 8565 8277 3 8276 8278 8564 3 8566 8564 8278 3 8277 8565 8567 3 8277 8567 8279 3 8278 8280 8566 3 8568 8566 8280 3 8279 8567 8569 3 8279 8569 8281 3 8280 8282 8568 3 8570 8568 8282 3 8281 8569 8571 3 8281 8571 8283 3 8282 8284 8570 3 8572 8570 8284 3 8283 8571 8573 3 8283 8573 8285 3 8284 8286 8572 3 8574 8572 8286 3 8285 8573 8575 3 8285 8575 8287 3 8286 8288 8574 3 8576 8574 8288 3 8287 8575 8577 3 8287 8577 8289 3 8288 8290 8576 3 8578 8576 8290 3 8289 8577 8579 3 8289 8579 8291 3 8290 8292 8578 3 8580 8578 8292 3 8291 8579 8581 3 8291 8581 8293 3 8292 8294 8580 3 8582 8580 8294 3 8293 8581 8583 3 8293 8583 8295 3 8294 8296 8582 3 8584 8582 8296 3 8295 8583 8585 3 8295 8585 8297 3 8296 8298 8584 3 8586 8584 8298 3 8297 8585 8587 3 8297 8587 8299 3 8298 8300 8586 3 8588 8586 8300 3 8299 8587 8589 3 8299 8589 8301 3 8300 8302 8588 3 8590 8588 8302 3 8301 8589 8591 3 8301 8591 8303 3 8302 8304 8590 3 8592 8590 8304 3 8303 8591 8593 3 8303 8593 8305 3 8304 8306 8592 3 8594 8592 8306 3 8305 8593 8595 3 8305 8595 8307 3 8306 8308 8594 3 8596 8594 8308 3 8307 8595 8597 3 8307 8597 8309 3 8308 8310 8596 3 8598 8596 8310 3 8309 8597 8599 3 8309 8599 8311 3 8310 8312 8598 3 8600 8598 8312 3 8311 8599 8601 3 8311 8601 8313 3 8312 8314 8600 3 8602 8600 8314 3 8313 8601 8603 3 8313 8603 8315 3 8314 8316 8602 3 8604 8602 8316 3 8315 8603 8605 3 8315 8605 8317 3 8316 8318 8604 3 8606 8604 8318 3 8317 8605 8607 3 8317 8607 8319 3 8318 8320 8606 3 8608 8606 8320 3 8319 8607 8609 3 8319 8609 8321 3 8320 8322 8608 3 8610 8608 8322 3 8321 8609 8611 3 8321 8611 8323 3 8322 8324 8610 3 8612 8610 8324 3 8323 8611 8613 3 8323 8613 8325 3 8324 8326 8612 3 8614 8612 8326 3 8325 8613 8615 3 8325 8615 8327 3 8326 8328 8616 3 8326 8616 8614 3 8327 8615 8617 3 8327 8617 8329 3 8328 8330 8618 3 8328 8618 8616 3 8329 8617 8619 3 8329 8619 8331 3 8330 8332 8620 3 8330 8620 8618 3 8331 8619 8621 3 8331 8621 8333 3 8332 8334 8622 3 8332 8622 8620 3 8333 8621 8335 3 8623 8335 8621 3 8334 8336 8624 3 8334 8624 8622 3 8335 8623 8337 3 8625 8337 8623 3 8336 8338 8626 3 8336 8626 8624 3 8337 8625 8339 3 8627 8339 8625 3 8338 8340 8628 3 8338 8628 8626 3 8339 8627 8341 3 8629 8341 8627 3 8340 8342 8630 3 8340 8630 8628 3 8341 8629 8343 3 8631 8343 8629 3 8342 8344 8632 3 8342 8632 8630 3 8343 8631 8345 3 8633 8345 8631 3 8344 8346 8634 3 8344 8634 8632 3 8345 8633 8347 3 8635 8347 8633 3 8346 8348 8636 3 8346 8636 8634 3 8347 8635 8349 3 8637 8349 8635 3 8348 8350 8638 3 8348 8638 8636 3 8349 8637 8351 3 8639 8351 8637 3 8350 8352 8640 3 8350 8640 8638 3 8351 8639 8353 3 8641 8353 8639 3 8352 8354 8642 3 8352 8642 8640 3 8353 8641 8355 3 8643 8355 8641 3 8354 8356 8644 3 8354 8644 8642 3 8355 8643 8357 3 8645 8357 8643 3 8356 8358 8646 3 8356 8646 8644 3 8357 8645 8359 3 8647 8359 8645 3 8358 8360 8648 3 8358 8648 8646 3 8359 8647 8361 3 8649 8361 8647 3 8360 8362 8650 3 8360 8650 8648 3 8361 8649 8363 3 8651 8363 8649 3 8362 8364 8652 3 8362 8652 8650 3 8363 8651 8365 3 8653 8365 8651 3 8364 8366 8654 3 8364 8654 8652 3 8365 8653 8367 3 8655 8367 8653 3 8366 8368 8656 3 8366 8656 8654 3 8367 8655 8369 3 8657 8369 8655 3 8368 8370 8658 3 8368 8658 8656 3 8369 8657 8371 3 8659 8371 8657 3 8370 8372 8660 3 8370 8660 8658 3 8371 8659 8373 3 8661 8373 8659 3 8372 8374 8662 3 8372 8662 8660 3 8373 8661 8375 3 8663 8375 8661 3 8374 8376 8664 3 8374 8664 8662 3 8375 8663 8377 3 8665 8377 8663 3 8376 8378 8666 3 8376 8666 8664 3 8377 8665 8379 3 8667 8379 8665 3 8378 8380 8668 3 8378 8668 8666 3 8379 8667 8381 3 8669 8381 8667 3 8380 8382 8670 3 8380 8670 8668 3 8381 8669 8383 3 8671 8383 8669 3 8382 8384 8672 3 8382 8672 8670 3 8383 8671 8387 3 8675 8387 8671 3 8384 8385 8672 3 8673 8672 8385 3 8385 8388 8673 3 8676 8673 8388 3 8386 8387 8674 3 8675 8674 8387 3 8386 8674 8391 3 8679 8391 8674 3 8388 8389 8676 3 8677 8676 8389 3 8389 8392 8677 3 8680 8677 8392 3 8390 8391 8678 3 8679 8678 8391 3 8390 8678 8748 3 8390 8748 8460 3 8392 8393 8680 3 8681 8680 8393 3 8393 8394 8681 3 8682 8681 8394 3 8394 8395 8682 3 8683 8682 8395 3 8395 8396 8683 3 8684 8683 8396 3 8396 8397 8684 3 8685 8684 8397 3 8397 8398 8685 3 8686 8685 8398 3 8398 8399 8686 3 8687 8686 8399 3 8399 8400 8687 3 8688 8687 8400 3 8400 8401 8688 3 8689 8688 8401 3 8401 8402 8689 3 8690 8689 8402 3 8402 8403 8690 3 8691 8690 8403 3 8403 8404 8691 3 8692 8691 8404 3 8404 8405 8692 3 8693 8692 8405 3 8405 8406 8693 3 8694 8693 8406 3 8406 8407 8694 3 8695 8694 8407 3 8407 8408 8695 3 8696 8695 8408 3 8408 8409 8696 3 8697 8696 8409 3 8409 8410 8697 3 8698 8697 8410 3 8410 8411 8698 3 8699 8698 8411 3 8411 8412 8699 3 8700 8699 8412 3 8412 8413 8700 3 8701 8700 8413 3 8413 8414 8701 3 8702 8701 8414 3 8414 8415 8702 3 8703 8702 8415 3 8415 8416 8703 3 8704 8703 8416 3 8416 8417 8704 3 8705 8704 8417 3 8417 8418 8705 3 8706 8705 8418 3 8418 8419 8706 3 8707 8706 8419 3 8419 8420 8707 3 8708 8707 8420 3 8420 8421 8708 3 8709 8708 8421 3 8421 8422 8709 3 8710 8709 8422 3 8422 8423 8710 3 8711 8710 8423 3 8423 8424 8711 3 8712 8711 8424 3 8424 8425 8712 3 8713 8712 8425 3 8425 8426 8713 3 8714 8713 8426 3 8426 8427 8714 3 8715 8714 8427 3 8427 8428 8715 3 8716 8715 8428 3 8428 8429 8716 3 8717 8716 8429 3 8429 8430 8717 3 8718 8717 8430 3 8430 8431 8718 3 8719 8718 8431 3 8431 8432 8719 3 8720 8719 8432 3 8432 8433 8720 3 8721 8720 8433 3 8433 8434 8721 3 8722 8721 8434 3 8434 8435 8722 3 8723 8722 8435 3 8435 8436 8723 3 8724 8723 8436 3 8436 8437 8724 3 8725 8724 8437 3 8437 8438 8725 3 8726 8725 8438 3 8438 8439 8726 3 8727 8726 8439 3 8439 8440 8727 3 8728 8727 8440 3 8440 8441 8729 3 8440 8729 8728 3 8441 8442 8730 3 8441 8730 8729 3 8442 8443 8731 3 8442 8731 8730 3 8443 8444 8732 3 8443 8732 8731 3 8444 8445 8733 3 8444 8733 8732 3 8445 8446 8734 3 8445 8734 8733 3 8446 8447 8735 3 8446 8735 8734 3 8447 8448 8736 3 8447 8736 8735 3 8448 8449 8737 3 8448 8737 8736 3 8449 8450 8738 3 8449 8738 8737 3 8450 8451 8739 3 8450 8739 8738 3 8451 8452 8740 3 8451 8740 8739 3 8452 8453 8741 3 8452 8741 8740 3 8453 8454 8742 3 8453 8742 8741 3 8454 8455 8743 3 8454 8743 8742 3 8455 8456 8744 3 8455 8744 8743 3 8456 8457 8745 3 8456 8745 8744 3 8457 8458 8746 3 8457 8746 8745 3 8458 8459 8747 3 8458 8747 8746 3 8459 8460 8748 3 8459 8748 8747 3 8461 8749 8462 3 8750 8462 8749 3 8461 8531 8749 3 8819 8749 8531 3 8462 8750 8463 3 8751 8463 8750 3 8463 8751 8464 3 8752 8464 8751 3 8464 8752 8465 3 8753 8465 8752 3 8465 8753 8466 3 8754 8466 8753 3 8466 8754 8467 3 8755 8467 8754 3 8467 8755 8468 3 8756 8468 8755 3 8468 8756 8469 3 8757 8469 8756 3 8469 8757 8470 3 8758 8470 8757 3 8470 8758 8471 3 8759 8471 8758 3 8471 8759 8472 3 8760 8472 8759 3 8472 8760 8473 3 8761 8473 8760 3 8473 8761 8474 3 8762 8474 8761 3 8474 8762 8475 3 8763 8475 8762 3 8475 8763 8476 3 8764 8476 8763 3 8476 8764 8477 3 8765 8477 8764 3 8477 8765 8478 3 8766 8478 8765 3 8478 8766 8479 3 8767 8479 8766 3 8479 8767 8480 3 8768 8480 8767 3 8480 8768 8481 3 8769 8481 8768 3 8481 8769 8482 3 8770 8482 8769 3 8482 8770 8483 3 8771 8483 8770 3 8483 8771 8484 3 8772 8484 8771 3 8484 8772 8485 3 8773 8485 8772 3 8485 8773 8486 3 8774 8486 8773 3 8486 8774 8487 3 8775 8487 8774 3 8487 8775 8488 3 8776 8488 8775 3 8488 8776 8489 3 8777 8489 8776 3 8489 8777 8490 3 8778 8490 8777 3 8490 8778 8491 3 8779 8491 8778 3 8491 8779 8492 3 8780 8492 8779 3 8492 8780 8493 3 8781 8493 8780 3 8493 8781 8494 3 8782 8494 8781 3 8494 8782 8495 3 8783 8495 8782 3 8495 8783 8496 3 8784 8496 8783 3 8496 8784 8497 3 8785 8497 8784 3 8497 8785 8498 3 8786 8498 8785 3 8498 8786 8499 3 8787 8499 8786 3 8499 8787 8500 3 8788 8500 8787 3 8500 8788 8501 3 8789 8501 8788 3 8501 8789 8502 3 8790 8502 8789 3 8502 8790 8503 3 8791 8503 8790 3 8503 8791 8792 3 8503 8792 8504 3 8504 8792 8793 3 8504 8793 8505 3 8505 8793 8794 3 8505 8794 8506 3 8506 8794 8795 3 8506 8795 8507 3 8507 8795 8796 3 8507 8796 8508 3 8508 8796 8797 3 8508 8797 8509 3 8509 8797 8798 3 8509 8798 8510 3 8510 8798 8799 3 8510 8799 8511 3 8511 8799 8800 3 8511 8800 8512 3 8512 8800 8801 3 8512 8801 8513 3 8513 8801 8802 3 8513 8802 8514 3 8514 8802 8803 3 8514 8803 8515 3 8515 8803 8804 3 8515 8804 8516 3 8516 8804 8805 3 8516 8805 8517 3 8517 8805 8806 3 8517 8806 8518 3 8518 8806 8807 3 8518 8807 8519 3 8519 8807 8808 3 8519 8808 8520 3 8520 8808 8809 3 8520 8809 8521 3 8521 8809 8810 3 8521 8810 8522 3 8522 8810 8811 3 8522 8811 8523 3 8523 8811 8812 3 8523 8812 8524 3 8524 8812 8813 3 8524 8813 8525 3 8525 8813 8814 3 8525 8814 8526 3 8526 8814 8815 3 8526 8815 8527 3 8527 8815 8816 3 8527 8816 8528 3 8528 8816 8817 3 8528 8817 8529 3 8529 8817 8820 3 8529 8820 8532 3 8530 8818 8819 3 8530 8819 8531 3 8530 8535 8818 3 8823 8818 8535 3 8532 8820 8821 3 8532 8821 8533 3 8533 8821 8824 3 8533 8824 8536 3 8534 8822 8823 3 8534 8823 8535 3 8534 8538 8822 3 8826 8822 8538 3 8536 8824 8825 3 8536 8825 8537 3 8537 8825 8827 3 8537 8827 8539 3 8538 8540 8826 3 8828 8826 8540 3 8539 8827 8829 3 8539 8829 8541 3 8540 8542 8828 3 8830 8828 8542 3 8541 8829 8831 3 8541 8831 8543 3 8542 8544 8830 3 8832 8830 8544 3 8543 8831 8833 3 8543 8833 8545 3 8544 8546 8832 3 8834 8832 8546 3 8545 8833 8835 3 8545 8835 8547 3 8546 8548 8834 3 8836 8834 8548 3 8547 8835 8837 3 8547 8837 8549 3 8548 8550 8836 3 8838 8836 8550 3 8549 8837 8839 3 8549 8839 8551 3 8550 8552 8838 3 8840 8838 8552 3 8551 8839 8841 3 8551 8841 8553 3 8552 8554 8840 3 8842 8840 8554 3 8553 8841 8843 3 8553 8843 8555 3 8554 8556 8844 3 8554 8844 8842 3 8555 8843 8845 3 8555 8845 8557 3 8556 8558 8846 3 8556 8846 8844 3 8557 8845 8847 3 8557 8847 8559 3 8558 8560 8848 3 8558 8848 8846 3 8559 8847 8849 3 8559 8849 8561 3 8560 8562 8850 3 8560 8850 8848 3 8561 8849 8563 3 8851 8563 8849 3 8562 8564 8852 3 8562 8852 8850 3 8563 8851 8565 3 8853 8565 8851 3 8564 8566 8854 3 8564 8854 8852 3 8565 8853 8567 3 8855 8567 8853 3 8566 8568 8856 3 8566 8856 8854 3 8567 8855 8569 3 8857 8569 8855 3 8568 8570 8858 3 8568 8858 8856 3 8569 8857 8571 3 8859 8571 8857 3 8570 8572 8860 3 8570 8860 8858 3 8571 8859 8573 3 8861 8573 8859 3 8572 8574 8862 3 8572 8862 8860 3 8573 8861 8575 3 8863 8575 8861 3 8574 8576 8864 3 8574 8864 8862 3 8575 8863 8577 3 8865 8577 8863 3 8576 8578 8866 3 8576 8866 8864 3 8577 8865 8579 3 8867 8579 8865 3 8578 8580 8868 3 8578 8868 8866 3 8579 8867 8581 3 8869 8581 8867 3 8580 8582 8870 3 8580 8870 8868 3 8581 8869 8583 3 8871 8583 8869 3 8582 8584 8872 3 8582 8872 8870 3 8583 8871 8585 3 8873 8585 8871 3 8584 8586 8874 3 8584 8874 8872 3 8585 8873 8587 3 8875 8587 8873 3 8586 8588 8876 3 8586 8876 8874 3 8587 8875 8589 3 8877 8589 8875 3 8588 8590 8878 3 8588 8878 8876 3 8589 8877 8591 3 8879 8591 8877 3 8590 8592 8880 3 8590 8880 8878 3 8591 8879 8593 3 8881 8593 8879 3 8592 8594 8882 3 8592 8882 8880 3 8593 8881 8595 3 8883 8595 8881 3 8594 8596 8884 3 8594 8884 8882 3 8595 8883 8597 3 8885 8597 8883 3 8596 8598 8886 3 8596 8886 8884 3 8597 8885 8599 3 8887 8599 8885 3 8598 8600 8888 3 8598 8888 8886 3 8599 8887 8601 3 8889 8601 8887 3 8600 8602 8890 3 8600 8890 8888 3 8601 8889 8603 3 8891 8603 8889 3 8602 8604 8892 3 8602 8892 8890 3 8603 8891 8605 3 8893 8605 8891 3 8604 8606 8894 3 8604 8894 8892 3 8605 8893 8607 3 8895 8607 8893 3 8606 8608 8896 3 8606 8896 8894 3 8607 8895 8609 3 8897 8609 8895 3 8608 8610 8898 3 8608 8898 8896 3 8609 8897 8611 3 8899 8611 8897 3 8610 8612 8898 3 8900 8898 8612 3 8611 8899 8613 3 8901 8613 8899 3 8612 8614 8900 3 8902 8900 8614 3 8613 8901 8615 3 8903 8615 8901 3 8614 8616 8902 3 8904 8902 8616 3 8615 8903 8617 3 8905 8617 8903 3 8616 8618 8904 3 8906 8904 8618 3 8617 8905 8619 3 8907 8619 8905 3 8618 8620 8906 3 8908 8906 8620 3 8619 8907 8909 3 8619 8909 8621 3 8620 8622 8908 3 8910 8908 8622 3 8621 8909 8911 3 8621 8911 8623 3 8622 8624 8910 3 8912 8910 8624 3 8623 8911 8913 3 8623 8913 8625 3 8624 8626 8912 3 8914 8912 8626 3 8625 8913 8915 3 8625 8915 8627 3 8626 8628 8914 3 8916 8914 8628 3 8627 8915 8917 3 8627 8917 8629 3 8628 8630 8916 3 8918 8916 8630 3 8629 8917 8919 3 8629 8919 8631 3 8630 8632 8918 3 8920 8918 8632 3 8631 8919 8921 3 8631 8921 8633 3 8632 8634 8920 3 8922 8920 8634 3 8633 8921 8923 3 8633 8923 8635 3 8634 8636 8922 3 8924 8922 8636 3 8635 8923 8925 3 8635 8925 8637 3 8636 8638 8924 3 8926 8924 8638 3 8637 8925 8927 3 8637 8927 8639 3 8638 8640 8926 3 8928 8926 8640 3 8639 8927 8929 3 8639 8929 8641 3 8640 8642 8928 3 8930 8928 8642 3 8641 8929 8931 3 8641 8931 8643 3 8642 8644 8930 3 8932 8930 8644 3 8643 8931 8933 3 8643 8933 8645 3 8644 8646 8932 3 8934 8932 8646 3 8645 8933 8935 3 8645 8935 8647 3 8646 8648 8934 3 8936 8934 8648 3 8647 8935 8937 3 8647 8937 8649 3 8648 8650 8936 3 8938 8936 8650 3 8649 8937 8939 3 8649 8939 8651 3 8650 8652 8938 3 8940 8938 8652 3 8651 8939 8941 3 8651 8941 8653 3 8652 8654 8940 3 8942 8940 8654 3 8653 8941 8943 3 8653 8943 8655 3 8654 8656 8942 3 8944 8942 8656 3 8655 8943 8945 3 8655 8945 8657 3 8656 8658 8944 3 8946 8944 8658 3 8657 8945 8947 3 8657 8947 8659 3 8658 8660 8946 3 8948 8946 8660 3 8659 8947 8949 3 8659 8949 8661 3 8660 8662 8948 3 8950 8948 8662 3 8661 8949 8951 3 8661 8951 8663 3 8662 8664 8950 3 8952 8950 8664 3 8663 8951 8953 3 8663 8953 8665 3 8664 8666 8952 3 8954 8952 8666 3 8665 8953 8955 3 8665 8955 8667 3 8666 8668 8954 3 8956 8954 8668 3 8667 8955 8957 3 8667 8957 8669 3 8668 8670 8958 3 8668 8958 8956 3 8669 8957 8959 3 8669 8959 8671 3 8670 8672 8960 3 8670 8960 8958 3 8671 8959 8963 3 8671 8963 8675 3 8672 8673 8961 3 8672 8961 8960 3 8673 8676 8964 3 8673 8964 8961 3 8674 8675 8963 3 8674 8963 8962 3 8674 8962 8967 3 8674 8967 8679 3 8676 8677 8965 3 8676 8965 8964 3 8677 8680 8968 3 8677 8968 8965 3 8678 8679 8967 3 8678 8967 8966 3 8678 8966 8748 3 9036 8748 8966 3 8680 8681 8969 3 8680 8969 8968 3 8681 8682 8970 3 8681 8970 8969 3 8682 8683 8971 3 8682 8971 8970 3 8683 8684 8972 3 8683 8972 8971 3 8684 8685 8973 3 8684 8973 8972 3 8685 8686 8974 3 8685 8974 8973 3 8686 8687 8975 3 8686 8975 8974 3 8687 8688 8976 3 8687 8976 8975 3 8688 8689 8977 3 8688 8977 8976 3 8689 8690 8978 3 8689 8978 8977 3 8690 8691 8979 3 8690 8979 8978 3 8691 8692 8980 3 8691 8980 8979 3 8692 8693 8981 3 8692 8981 8980 3 8693 8694 8982 3 8693 8982 8981 3 8694 8695 8983 3 8694 8983 8982 3 8695 8696 8984 3 8695 8984 8983 3 8696 8697 8985 3 8696 8985 8984 3 8697 8698 8986 3 8697 8986 8985 3 8698 8699 8987 3 8698 8987 8986 3 8699 8700 8988 3 8699 8988 8987 3 8700 8701 8989 3 8700 8989 8988 3 8701 8702 8990 3 8701 8990 8989 3 8702 8703 8991 3 8702 8991 8990 3 8703 8704 8992 3 8703 8992 8991 3 8704 8705 8993 3 8704 8993 8992 3 8705 8706 8994 3 8705 8994 8993 3 8706 8707 8995 3 8706 8995 8994 3 8707 8708 8996 3 8707 8996 8995 3 8708 8709 8997 3 8708 8997 8996 3 8709 8710 8998 3 8709 8998 8997 3 8710 8711 8999 3 8710 8999 8998 3 8711 8712 9000 3 8711 9000 8999 3 8712 8713 9001 3 8712 9001 9000 3 8713 8714 9002 3 8713 9002 9001 3 8714 8715 9003 3 8714 9003 9002 3 8715 8716 9004 3 8715 9004 9003 3 8716 8717 9005 3 8716 9005 9004 3 8717 8718 9006 3 8717 9006 9005 3 8718 8719 9007 3 8718 9007 9006 3 8719 8720 9008 3 8719 9008 9007 3 8720 8721 9009 3 8720 9009 9008 3 8721 8722 9010 3 8721 9010 9009 3 8722 8723 9011 3 8722 9011 9010 3 8723 8724 9012 3 8723 9012 9011 3 8724 8725 9013 3 8724 9013 9012 3 8725 8726 9013 3 9014 9013 8726 3 8726 8727 9014 3 9015 9014 8727 3 8727 8728 9015 3 9016 9015 8728 3 8728 8729 9016 3 9017 9016 8729 3 8729 8730 9017 3 9018 9017 8730 3 8730 8731 9018 3 9019 9018 8731 3 8731 8732 9019 3 9020 9019 8732 3 8732 8733 9020 3 9021 9020 8733 3 8733 8734 9021 3 9022 9021 8734 3 8734 8735 9022 3 9023 9022 8735 3 8735 8736 9023 3 9024 9023 8736 3 8736 8737 9024 3 9025 9024 8737 3 8737 8738 9025 3 9026 9025 8738 3 8738 8739 9026 3 9027 9026 8739 3 8739 8740 9027 3 9028 9027 8740 3 8740 8741 9028 3 9029 9028 8741 3 8741 8742 9029 3 9030 9029 8742 3 8742 8743 9030 3 9031 9030 8743 3 8743 8744 9031 3 9032 9031 8744 3 8744 8745 9032 3 9033 9032 8745 3 8745 8746 9033 3 9034 9033 8746 3 8746 8747 9034 3 9035 9034 8747 3 8747 8748 9035 3 9036 9035 8748 3 8749 9037 9038 3 8749 9038 8750 3 8749 8819 9107 3 8749 9107 9037 3 8750 9038 9039 3 8750 9039 8751 3 8751 9039 9040 3 8751 9040 8752 3 8752 9040 9041 3 8752 9041 8753 3 8753 9041 9042 3 8753 9042 8754 3 8754 9042 9043 3 8754 9043 8755 3 8755 9043 9044 3 8755 9044 8756 3 8756 9044 9045 3 8756 9045 8757 3 8757 9045 9046 3 8757 9046 8758 3 8758 9046 9047 3 8758 9047 8759 3 8759 9047 9048 3 8759 9048 8760 3 8760 9048 9049 3 8760 9049 8761 3 8761 9049 9050 3 8761 9050 8762 3 8762 9050 9051 3 8762 9051 8763 3 8763 9051 9052 3 8763 9052 8764 3 8764 9052 9053 3 8764 9053 8765 3 8765 9053 9054 3 8765 9054 8766 3 8766 9054 9055 3 8766 9055 8767 3 8767 9055 9056 3 8767 9056 8768 3 8768 9056 9057 3 8768 9057 8769 3 8769 9057 9058 3 8769 9058 8770 3 8770 9058 9059 3 8770 9059 8771 3 8771 9059 9060 3 8771 9060 8772 3 8772 9060 9061 3 8772 9061 8773 3 8773 9061 9062 3 8773 9062 8774 3 8774 9062 9063 3 8774 9063 8775 3 8775 9063 9064 3 8775 9064 8776 3 8776 9064 9065 3 8776 9065 8777 3 8777 9065 9066 3 8777 9066 8778 3 8778 9066 9067 3 8778 9067 8779 3 8779 9067 9068 3 8779 9068 8780 3 8780 9068 9069 3 8780 9069 8781 3 8781 9069 9070 3 8781 9070 8782 3 8782 9070 9071 3 8782 9071 8783 3 8783 9071 9072 3 8783 9072 8784 3 8784 9072 9073 3 8784 9073 8785 3 8785 9073 9074 3 8785 9074 8786 3 8786 9074 9075 3 8786 9075 8787 3 8787 9075 9076 3 8787 9076 8788 3 8788 9076 9077 3 8788 9077 8789 3 8789 9077 9078 3 8789 9078 8790 3 8790 9078 9079 3 8790 9079 8791 3 8791 9079 9080 3 8791 9080 8792 3 8792 9080 8793 3 9081 8793 9080 3 8793 9081 8794 3 9082 8794 9081 3 8794 9082 8795 3 9083 8795 9082 3 8795 9083 8796 3 9084 8796 9083 3 8796 9084 8797 3 9085 8797 9084 3 8797 9085 8798 3 9086 8798 9085 3 8798 9086 8799 3 9087 8799 9086 3 8799 9087 8800 3 9088 8800 9087 3 8800 9088 8801 3 9089 8801 9088 3 8801 9089 8802 3 9090 8802 9089 3 8802 9090 8803 3 9091 8803 9090 3 8803 9091 8804 3 9092 8804 9091 3 8804 9092 8805 3 9093 8805 9092 3 8805 9093 8806 3 9094 8806 9093 3 8806 9094 8807 3 9095 8807 9094 3 8807 9095 8808 3 9096 8808 9095 3 8808 9096 8809 3 9097 8809 9096 3 8809 9097 8810 3 9098 8810 9097 3 8810 9098 8811 3 9099 8811 9098 3 8811 9099 8812 3 9100 8812 9099 3 8812 9100 8813 3 9101 8813 9100 3 8813 9101 8814 3 9102 8814 9101 3 8814 9102 8815 3 9103 8815 9102 3 8815 9103 8816 3 9104 8816 9103 3 8816 9104 8817 3 9105 8817 9104 3 8817 9105 8820 3 9108 8820 9105 3 8818 9106 8819 3 9107 8819 9106 3 8818 8823 9111 3 8818 9111 9106 3 8820 9108 8821 3 9109 8821 9108 3 8821 9109 8824 3 9112 8824 9109 3 8822 9110 8823 3 9111 8823 9110 3 8822 8826 9114 3 8822 9114 9110 3 8824 9112 8825 3 9113 8825 9112 3 8825 9113 8827 3 9115 8827 9113 3 8826 8828 9116 3 8826 9116 9114 3 8827 9115 8829 3 9117 8829 9115 3 8828 8830 9118 3 8828 9118 9116 3 8829 9117 8831 3 9119 8831 9117 3 8830 8832 9120 3 8830 9120 9118 3 8831 9119 8833 3 9121 8833 9119 3 8832 8834 9122 3 8832 9122 9120 3 8833 9121 8835 3 9123 8835 9121 3 8834 8836 9124 3 8834 9124 9122 3 8835 9123 8837 3 9125 8837 9123 3 8836 8838 9126 3 8836 9126 9124 3 8837 9125 8839 3 9127 8839 9125 3 8838 8840 9128 3 8838 9128 9126 3 8839 9127 8841 3 9129 8841 9127 3 8840 8842 9128 3 9130 9128 8842 3 8841 9129 8843 3 9131 8843 9129 3 8842 8844 9130 3 9132 9130 8844 3 8843 9131 8845 3 9133 8845 9131 3 8844 8846 9132 3 9134 9132 8846 3 8845 9133 8847 3 9135 8847 9133 3 8846 8848 9134 3 9136 9134 8848 3 8847 9135 8849 3 9137 8849 9135 3 8848 8850 9136 3 9138 9136 8850 3 8849 9137 8851 3 9139 8851 9137 3 8850 8852 9138 3 9140 9138 8852 3 8851 9139 9141 3 8851 9141 8853 3 8852 8854 9140 3 9142 9140 8854 3 8853 9141 9143 3 8853 9143 8855 3 8854 8856 9142 3 9144 9142 8856 3 8855 9143 9145 3 8855 9145 8857 3 8856 8858 9144 3 9146 9144 8858 3 8857 9145 9147 3 8857 9147 8859 3 8858 8860 9146 3 9148 9146 8860 3 8859 9147 9149 3 8859 9149 8861 3 8860 8862 9148 3 9150 9148 8862 3 8861 9149 9151 3 8861 9151 8863 3 8862 8864 9150 3 9152 9150 8864 3 8863 9151 9153 3 8863 9153 8865 3 8864 8866 9152 3 9154 9152 8866 3 8865 9153 9155 3 8865 9155 8867 3 8866 8868 9154 3 9156 9154 8868 3 8867 9155 9157 3 8867 9157 8869 3 8868 8870 9156 3 9158 9156 8870 3 8869 9157 9159 3 8869 9159 8871 3 8870 8872 9158 3 9160 9158 8872 3 8871 9159 9161 3 8871 9161 8873 3 8872 8874 9160 3 9162 9160 8874 3 8873 9161 9163 3 8873 9163 8875 3 8874 8876 9162 3 9164 9162 8876 3 8875 9163 9165 3 8875 9165 8877 3 8876 8878 9164 3 9166 9164 8878 3 8877 9165 9167 3 8877 9167 8879 3 8878 8880 9166 3 9168 9166 8880 3 8879 9167 9169 3 8879 9169 8881 3 8880 8882 9168 3 9170 9168 8882 3 8881 9169 9171 3 8881 9171 8883 3 8882 8884 9170 3 9172 9170 8884 3 8883 9171 9173 3 8883 9173 8885 3 8884 8886 9172 3 9174 9172 8886 3 8885 9173 9175 3 8885 9175 8887 3 8886 8888 9174 3 9176 9174 8888 3 8887 9175 9177 3 8887 9177 8889 3 8888 8890 9176 3 9178 9176 8890 3 8889 9177 9179 3 8889 9179 8891 3 8890 8892 9178 3 9180 9178 8892 3 8891 9179 9181 3 8891 9181 8893 3 8892 8894 9180 3 9182 9180 8894 3 8893 9181 9183 3 8893 9183 8895 3 8894 8896 9182 3 9184 9182 8896 3 8895 9183 9185 3 8895 9185 8897 3 8896 8898 9184 3 9186 9184 8898 3 8897 9185 9187 3 8897 9187 8899 3 8898 8900 9188 3 8898 9188 9186 3 8899 9187 9189 3 8899 9189 8901 3 8900 8902 9190 3 8900 9190 9188 3 8901 9189 9191 3 8901 9191 8903 3 8902 8904 9192 3 8902 9192 9190 3 8903 9191 9193 3 8903 9193 8905 3 8904 8906 9194 3 8904 9194 9192 3 8905 9193 9195 3 8905 9195 8907 3 8906 8908 9196 3 8906 9196 9194 3 8907 9195 9197 3 8907 9197 8909 3 8908 8910 9198 3 8908 9198 9196 3 8909 9197 8911 3 9199 8911 9197 3 8910 8912 9200 3 8910 9200 9198 3 8911 9199 8913 3 9201 8913 9199 3 8912 8914 9202 3 8912 9202 9200 3 8913 9201 8915 3 9203 8915 9201 3 8914 8916 9204 3 8914 9204 9202 3 8915 9203 8917 3 9205 8917 9203 3 8916 8918 9206 3 8916 9206 9204 3 8917 9205 8919 3 9207 8919 9205 3 8918 8920 9208 3 8918 9208 9206 3 8919 9207 8921 3 9209 8921 9207 3 8920 8922 9210 3 8920 9210 9208 3 8921 9209 8923 3 9211 8923 9209 3 8922 8924 9212 3 8922 9212 9210 3 8923 9211 8925 3 9213 8925 9211 3 8924 8926 9214 3 8924 9214 9212 3 8925 9213 8927 3 9215 8927 9213 3 8926 8928 9216 3 8926 9216 9214 3 8927 9215 8929 3 9217 8929 9215 3 8928 8930 9218 3 8928 9218 9216 3 8929 9217 8931 3 9219 8931 9217 3 8930 8932 9220 3 8930 9220 9218 3 8931 9219 8933 3 9221 8933 9219 3 8932 8934 9222 3 8932 9222 9220 3 8933 9221 8935 3 9223 8935 9221 3 8934 8936 9224 3 8934 9224 9222 3 8935 9223 8937 3 9225 8937 9223 3 8936 8938 9226 3 8936 9226 9224 3 8937 9225 8939 3 9227 8939 9225 3 8938 8940 9228 3 8938 9228 9226 3 8939 9227 8941 3 9229 8941 9227 3 8940 8942 9230 3 8940 9230 9228 3 8941 9229 8943 3 9231 8943 9229 3 8942 8944 9232 3 8942 9232 9230 3 8943 9231 8945 3 9233 8945 9231 3 8944 8946 9234 3 8944 9234 9232 3 8945 9233 8947 3 9235 8947 9233 3 8946 8948 9236 3 8946 9236 9234 3 8947 9235 8949 3 9237 8949 9235 3 8948 8950 9238 3 8948 9238 9236 3 8949 9237 8951 3 9239 8951 9237 3 8950 8952 9240 3 8950 9240 9238 3 8951 9239 8953 3 9241 8953 9239 3 8952 8954 9242 3 8952 9242 9240 3 8953 9241 8955 3 9243 8955 9241 3 8954 8956 9244 3 8954 9244 9242 3 8955 9243 8957 3 9245 8957 9243 3 8956 8958 9244 3 9246 9244 8958 3 8957 9245 8959 3 9247 8959 9245 3 8958 8960 9246 3 9248 9246 8960 3 8959 9247 8963 3 9251 8963 9247 3 8960 8961 9248 3 9249 9248 8961 3 8961 8964 9249 3 9252 9249 8964 3 8962 8963 9250 3 9251 9250 8963 3 8962 9250 8967 3 9255 8967 9250 3 8964 8965 9252 3 9253 9252 8965 3 8965 8968 9253 3 9256 9253 8968 3 8966 8967 9254 3 9255 9254 8967 3 8966 9254 9036 3 9324 9036 9254 3 8968 8969 9256 3 9257 9256 8969 3 8969 8970 9257 3 9258 9257 8970 3 8970 8971 9258 3 9259 9258 8971 3 8971 8972 9259 3 9260 9259 8972 3 8972 8973 9260 3 9261 9260 8973 3 8973 8974 9261 3 9262 9261 8974 3 8974 8975 9262 3 9263 9262 8975 3 8975 8976 9263 3 9264 9263 8976 3 8976 8977 9264 3 9265 9264 8977 3 8977 8978 9265 3 9266 9265 8978 3 8978 8979 9266 3 9267 9266 8979 3 8979 8980 9267 3 9268 9267 8980 3 8980 8981 9268 3 9269 9268 8981 3 8981 8982 9269 3 9270 9269 8982 3 8982 8983 9270 3 9271 9270 8983 3 8983 8984 9271 3 9272 9271 8984 3 8984 8985 9272 3 9273 9272 8985 3 8985 8986 9273 3 9274 9273 8986 3 8986 8987 9274 3 9275 9274 8987 3 8987 8988 9275 3 9276 9275 8988 3 8988 8989 9276 3 9277 9276 8989 3 8989 8990 9277 3 9278 9277 8990 3 8990 8991 9278 3 9279 9278 8991 3 8991 8992 9279 3 9280 9279 8992 3 8992 8993 9280 3 9281 9280 8993 3 8993 8994 9281 3 9282 9281 8994 3 8994 8995 9282 3 9283 9282 8995 3 8995 8996 9283 3 9284 9283 8996 3 8996 8997 9284 3 9285 9284 8997 3 8997 8998 9285 3 9286 9285 8998 3 8998 8999 9286 3 9287 9286 8999 3 8999 9000 9287 3 9288 9287 9000 3 9000 9001 9288 3 9289 9288 9001 3 9001 9002 9289 3 9290 9289 9002 3 9002 9003 9290 3 9291 9290 9003 3 9003 9004 9291 3 9292 9291 9004 3 9004 9005 9292 3 9293 9292 9005 3 9005 9006 9293 3 9294 9293 9006 3 9006 9007 9294 3 9295 9294 9007 3 9007 9008 9295 3 9296 9295 9008 3 9008 9009 9296 3 9297 9296 9009 3 9009 9010 9297 3 9298 9297 9010 3 9010 9011 9298 3 9299 9298 9011 3 9011 9012 9299 3 9300 9299 9012 3 9012 9013 9300 3 9301 9300 9013 3 9013 9014 9301 3 9302 9301 9014 3 9014 9015 9302 3 9303 9302 9015 3 9015 9016 9304 3 9015 9304 9303 3 9016 9017 9305 3 9016 9305 9304 3 9017 9018 9306 3 9017 9306 9305 3 9018 9019 9307 3 9018 9307 9306 3 9019 9020 9308 3 9019 9308 9307 3 9020 9021 9309 3 9020 9309 9308 3 9021 9022 9310 3 9021 9310 9309 3 9022 9023 9311 3 9022 9311 9310 3 9023 9024 9312 3 9023 9312 9311 3 9024 9025 9313 3 9024 9313 9312 3 9025 9026 9314 3 9025 9314 9313 3 9026 9027 9315 3 9026 9315 9314 3 9027 9028 9316 3 9027 9316 9315 3 9028 9029 9317 3 9028 9317 9316 3 9029 9030 9318 3 9029 9318 9317 3 9030 9031 9319 3 9030 9319 9318 3 9031 9032 9320 3 9031 9320 9319 3 9032 9033 9321 3 9032 9321 9320 3 9033 9034 9322 3 9033 9322 9321 3 9034 9035 9323 3 9034 9323 9322 3 9035 9036 9324 3 9035 9324 9323 3 9037 9325 9038 3 9326 9038 9325 3 9037 9107 9325 3 9395 9325 9107 3 9038 9326 9039 3 9327 9039 9326 3 9039 9327 9040 3 9328 9040 9327 3 9040 9328 9041 3 9329 9041 9328 3 9041 9329 9042 3 9330 9042 9329 3 9042 9330 9043 3 9331 9043 9330 3 9043 9331 9044 3 9332 9044 9331 3 9044 9332 9045 3 9333 9045 9332 3 9045 9333 9046 3 9334 9046 9333 3 9046 9334 9047 3 9335 9047 9334 3 9047 9335 9048 3 9336 9048 9335 3 9048 9336 9049 3 9337 9049 9336 3 9049 9337 9050 3 9338 9050 9337 3 9050 9338 9051 3 9339 9051 9338 3 9051 9339 9052 3 9340 9052 9339 3 9052 9340 9053 3 9341 9053 9340 3 9053 9341 9054 3 9342 9054 9341 3 9054 9342 9055 3 9343 9055 9342 3 9055 9343 9056 3 9344 9056 9343 3 9056 9344 9057 3 9345 9057 9344 3 9057 9345 9058 3 9346 9058 9345 3 9058 9346 9059 3 9347 9059 9346 3 9059 9347 9060 3 9348 9060 9347 3 9060 9348 9061 3 9349 9061 9348 3 9061 9349 9062 3 9350 9062 9349 3 9062 9350 9063 3 9351 9063 9350 3 9063 9351 9064 3 9352 9064 9351 3 9064 9352 9065 3 9353 9065 9352 3 9065 9353 9066 3 9354 9066 9353 3 9066 9354 9067 3 9355 9067 9354 3 9067 9355 9068 3 9356 9068 9355 3 9068 9356 9069 3 9357 9069 9356 3 9069 9357 9070 3 9358 9070 9357 3 9070 9358 9071 3 9359 9071 9358 3 9071 9359 9072 3 9360 9072 9359 3 9072 9360 9073 3 9361 9073 9360 3 9073 9361 9074 3 9362 9074 9361 3 9074 9362 9075 3 9363 9075 9362 3 9075 9363 9076 3 9364 9076 9363 3 9076 9364 9077 3 9365 9077 9364 3 9077 9365 9078 3 9366 9078 9365 3 9078 9366 9079 3 9367 9079 9366 3 9079 9367 9080 3 9368 9080 9367 3 9080 9368 9081 3 9369 9081 9368 3 9081 9369 9082 3 9370 9082 9369 3 9082 9370 9083 3 9371 9083 9370 3 9083 9371 9084 3 9372 9084 9371 3 9084 9372 9085 3 9373 9085 9372 3 9085 9373 9374 3 9085 9374 9086 3 9086 9374 9375 3 9086 9375 9087 3 9087 9375 9376 3 9087 9376 9088 3 9088 9376 9377 3 9088 9377 9089 3 9089 9377 9378 3 9089 9378 9090 3 9090 9378 9379 3 9090 9379 9091 3 9091 9379 9380 3 9091 9380 9092 3 9092 9380 9381 3 9092 9381 9093 3 9093 9381 9382 3 9093 9382 9094 3 9094 9382 9383 3 9094 9383 9095 3 9095 9383 9384 3 9095 9384 9096 3 9096 9384 9385 3 9096 9385 9097 3 9097 9385 9386 3 9097 9386 9098 3 9098 9386 9387 3 9098 9387 9099 3 9099 9387 9388 3 9099 9388 9100 3 9100 9388 9389 3 9100 9389 9101 3 9101 9389 9390 3 9101 9390 9102 3 9102 9390 9391 3 9102 9391 9103 3 9103 9391 9392 3 9103 9392 9104 3 9104 9392 9393 3 9104 9393 9105 3 9105 9393 9396 3 9105 9396 9108 3 9106 9394 9395 3 9106 9395 9107 3 9106 9111 9394 3 9399 9394 9111 3 9108 9396 9397 3 9108 9397 9109 3 9109 9397 9400 3 9109 9400 9112 3 9110 9398 9399 3 9110 9399 9111 3 9110 9114 9398 3 9402 9398 9114 3 9112 9400 9401 3 9112 9401 9113 3 9113 9401 9403 3 9113 9403 9115 3 9114 9116 9402 3 9404 9402 9116 3 9115 9403 9405 3 9115 9405 9117 3 9116 9118 9404 3 9406 9404 9118 3 9117 9405 9407 3 9117 9407 9119 3 9118 9120 9406 3 9408 9406 9120 3 9119 9407 9409 3 9119 9409 9121 3 9120 9122 9408 3 9410 9408 9122 3 9121 9409 9411 3 9121 9411 9123 3 9122 9124 9410 3 9412 9410 9124 3 9123 9411 9413 3 9123 9413 9125 3 9124 9126 9412 3 9414 9412 9126 3 9125 9413 9415 3 9125 9415 9127 3 9126 9128 9414 3 9416 9414 9128 3 9127 9415 9417 3 9127 9417 9129 3 9128 9130 9416 3 9418 9416 9130 3 9129 9417 9419 3 9129 9419 9131 3 9130 9132 9418 3 9420 9418 9132 3 9131 9419 9421 3 9131 9421 9133 3 9132 9134 9422 3 9132 9422 9420 3 9133 9421 9423 3 9133 9423 9135 3 9134 9136 9424 3 9134 9424 9422 3 9135 9423 9425 3 9135 9425 9137 3 9136 9138 9426 3 9136 9426 9424 3 9137 9425 9427 3 9137 9427 9139 3 9138 9140 9428 3 9138 9428 9426 3 9139 9427 9429 3 9139 9429 9141 3 9140 9142 9430 3 9140 9430 9428 3 9141 9429 9431 3 9141 9431 9143 3 9142 9144 9432 3 9142 9432 9430 3 9143 9431 9433 3 9143 9433 9145 3 9144 9146 9434 3 9144 9434 9432 3 9145 9433 9147 3 9435 9147 9433 3 9146 9148 9436 3 9146 9436 9434 3 9147 9435 9149 3 9437 9149 9435 3 9148 9150 9438 3 9148 9438 9436 3 9149 9437 9151 3 9439 9151 9437 3 9150 9152 9440 3 9150 9440 9438 3 9151 9439 9153 3 9441 9153 9439 3 9152 9154 9442 3 9152 9442 9440 3 9153 9441 9155 3 9443 9155 9441 3 9154 9156 9444 3 9154 9444 9442 3 9155 9443 9157 3 9445 9157 9443 3 9156 9158 9446 3 9156 9446 9444 3 9157 9445 9159 3 9447 9159 9445 3 9158 9160 9448 3 9158 9448 9446 3 9159 9447 9161 3 9449 9161 9447 3 9160 9162 9450 3 9160 9450 9448 3 9161 9449 9163 3 9451 9163 9449 3 9162 9164 9452 3 9162 9452 9450 3 9163 9451 9165 3 9453 9165 9451 3 9164 9166 9454 3 9164 9454 9452 3 9165 9453 9167 3 9455 9167 9453 3 9166 9168 9456 3 9166 9456 9454 3 9167 9455 9169 3 9457 9169 9455 3 9168 9170 9458 3 9168 9458 9456 3 9169 9457 9171 3 9459 9171 9457 3 9170 9172 9460 3 9170 9460 9458 3 9171 9459 9173 3 9461 9173 9459 3 9172 9174 9462 3 9172 9462 9460 3 9173 9461 9175 3 9463 9175 9461 3 9174 9176 9464 3 9174 9464 9462 3 9175 9463 9177 3 9465 9177 9463 3 9176 9178 9466 3 9176 9466 9464 3 9177 9465 9179 3 9467 9179 9465 3 9178 9180 9468 3 9178 9468 9466 3 9179 9467 9181 3 9469 9181 9467 3 9180 9182 9470 3 9180 9470 9468 3 9181 9469 9183 3 9471 9183 9469 3 9182 9184 9472 3 9182 9472 9470 3 9183 9471 9185 3 9473 9185 9471 3 9184 9186 9474 3 9184 9474 9472 3 9185 9473 9187 3 9475 9187 9473 3 9186 9188 9476 3 9186 9476 9474 3 9187 9475 9189 3 9477 9189 9475 3 9188 9190 9478 3 9188 9478 9476 3 9189 9477 9191 3 9479 9191 9477 3 9190 9192 9478 3 9480 9478 9192 3 9191 9479 9193 3 9481 9193 9479 3 9192 9194 9480 3 9482 9480 9194 3 9193 9481 9195 3 9483 9195 9481 3 9194 9196 9482 3 9484 9482 9196 3 9195 9483 9197 3 9485 9197 9483 3 9196 9198 9484 3 9486 9484 9198 3 9197 9485 9199 3 9487 9199 9485 3 9198 9200 9486 3 9488 9486 9200 3 9199 9487 9201 3 9489 9201 9487 3 9200 9202 9488 3 9490 9488 9202 3 9201 9489 9203 3 9491 9203 9489 3 9202 9204 9490 3 9492 9490 9204 3 9203 9491 9205 3 9493 9205 9491 3 9204 9206 9492 3 9494 9492 9206 3 9205 9493 9495 3 9205 9495 9207 3 9206 9208 9494 3 9496 9494 9208 3 9207 9495 9497 3 9207 9497 9209 3 9208 9210 9496 3 9498 9496 9210 3 9209 9497 9499 3 9209 9499 9211 3 9210 9212 9498 3 9500 9498 9212 3 9211 9499 9501 3 9211 9501 9213 3 9212 9214 9500 3 9502 9500 9214 3 9213 9501 9503 3 9213 9503 9215 3 9214 9216 9502 3 9504 9502 9216 3 9215 9503 9505 3 9215 9505 9217 3 9216 9218 9504 3 9506 9504 9218 3 9217 9505 9507 3 9217 9507 9219 3 9218 9220 9506 3 9508 9506 9220 3 9219 9507 9509 3 9219 9509 9221 3 9220 9222 9508 3 9510 9508 9222 3 9221 9509 9511 3 9221 9511 9223 3 9222 9224 9510 3 9512 9510 9224 3 9223 9511 9513 3 9223 9513 9225 3 9224 9226 9512 3 9514 9512 9226 3 9225 9513 9515 3 9225 9515 9227 3 9226 9228 9514 3 9516 9514 9228 3 9227 9515 9517 3 9227 9517 9229 3 9228 9230 9516 3 9518 9516 9230 3 9229 9517 9519 3 9229 9519 9231 3 9230 9232 9518 3 9520 9518 9232 3 9231 9519 9521 3 9231 9521 9233 3 9232 9234 9520 3 9522 9520 9234 3 9233 9521 9523 3 9233 9523 9235 3 9234 9236 9522 3 9524 9522 9236 3 9235 9523 9525 3 9235 9525 9237 3 9236 9238 9524 3 9526 9524 9238 3 9237 9525 9527 3 9237 9527 9239 3 9238 9240 9526 3 9528 9526 9240 3 9239 9527 9529 3 9239 9529 9241 3 9240 9242 9528 3 9530 9528 9242 3 9241 9529 9531 3 9241 9531 9243 3 9242 9244 9530 3 9532 9530 9244 3 9243 9531 9533 3 9243 9533 9245 3 9244 9246 9532 3 9534 9532 9246 3 9245 9533 9535 3 9245 9535 9247 3 9246 9248 9534 3 9536 9534 9248 3 9247 9535 9539 3 9247 9539 9251 3 9248 9249 9536 3 9537 9536 9249 3 9249 9252 9540 3 9249 9540 9537 3 9250 9251 9539 3 9250 9539 9538 3 9250 9538 9543 3 9250 9543 9255 3 9252 9253 9541 3 9252 9541 9540 3 9253 9256 9544 3 9253 9544 9541 3 9254 9255 9543 3 9254 9543 9542 3 9254 9542 9612 3 9254 9612 9324 3 9256 9257 9545 3 9256 9545 9544 3 9257 9258 9546 3 9257 9546 9545 3 9258 9259 9547 3 9258 9547 9546 3 9259 9260 9548 3 9259 9548 9547 3 9260 9261 9549 3 9260 9549 9548 3 9261 9262 9550 3 9261 9550 9549 3 9262 9263 9551 3 9262 9551 9550 3 9263 9264 9552 3 9263 9552 9551 3 9264 9265 9553 3 9264 9553 9552 3 9265 9266 9554 3 9265 9554 9553 3 9266 9267 9555 3 9266 9555 9554 3 9267 9268 9556 3 9267 9556 9555 3 9268 9269 9557 3 9268 9557 9556 3 9269 9270 9558 3 9269 9558 9557 3 9270 9271 9559 3 9270 9559 9558 3 9271 9272 9560 3 9271 9560 9559 3 9272 9273 9561 3 9272 9561 9560 3 9273 9274 9562 3 9273 9562 9561 3 9274 9275 9563 3 9274 9563 9562 3 9275 9276 9564 3 9275 9564 9563 3 9276 9277 9565 3 9276 9565 9564 3 9277 9278 9566 3 9277 9566 9565 3 9278 9279 9567 3 9278 9567 9566 3 9279 9280 9568 3 9279 9568 9567 3 9280 9281 9569 3 9280 9569 9568 3 9281 9282 9570 3 9281 9570 9569 3 9282 9283 9571 3 9282 9571 9570 3 9283 9284 9572 3 9283 9572 9571 3 9284 9285 9573 3 9284 9573 9572 3 9285 9286 9574 3 9285 9574 9573 3 9286 9287 9575 3 9286 9575 9574 3 9287 9288 9576 3 9287 9576 9575 3 9288 9289 9577 3 9288 9577 9576 3 9289 9290 9578 3 9289 9578 9577 3 9290 9291 9579 3 9290 9579 9578 3 9291 9292 9580 3 9291 9580 9579 3 9292 9293 9581 3 9292 9581 9580 3 9293 9294 9582 3 9293 9582 9581 3 9294 9295 9583 3 9294 9583 9582 3 9295 9296 9584 3 9295 9584 9583 3 9296 9297 9585 3 9296 9585 9584 3 9297 9298 9586 3 9297 9586 9585 3 9298 9299 9587 3 9298 9587 9586 3 9299 9300 9588 3 9299 9588 9587 3 9300 9301 9589 3 9300 9589 9588 3 9301 9302 9590 3 9301 9590 9589 3 9302 9303 9591 3 9302 9591 9590 3 9303 9304 9592 3 9303 9592 9591 3 9304 9305 9593 3 9304 9593 9592 3 9305 9306 9594 3 9305 9594 9593 3 9306 9307 9595 3 9306 9595 9594 3 9307 9308 9596 3 9307 9596 9595 3 9308 9309 9597 3 9308 9597 9596 3 9309 9310 9597 3 9598 9597 9310 3 9310 9311 9598 3 9599 9598 9311 3 9311 9312 9599 3 9600 9599 9312 3 9312 9313 9600 3 9601 9600 9313 3 9313 9314 9601 3 9602 9601 9314 3 9314 9315 9602 3 9603 9602 9315 3 9315 9316 9603 3 9604 9603 9316 3 9316 9317 9604 3 9605 9604 9317 3 9317 9318 9605 3 9606 9605 9318 3 9318 9319 9606 3 9607 9606 9319 3 9319 9320 9607 3 9608 9607 9320 3 9320 9321 9608 3 9609 9608 9321 3 9321 9322 9609 3 9610 9609 9322 3 9322 9323 9610 3 9611 9610 9323 3 9323 9324 9611 3 9612 9611 9324 3 9325 9613 9614 3 9325 9614 9326 3 9325 9395 9613 3 9683 9613 9395 3 9326 9614 9615 3 9326 9615 9327 3 9327 9615 9616 3 9327 9616 9328 3 9328 9616 9617 3 9328 9617 9329 3 9329 9617 9618 3 9329 9618 9330 3 9330 9618 9619 3 9330 9619 9331 3 9331 9619 9620 3 9331 9620 9332 3 9332 9620 9621 3 9332 9621 9333 3 9333 9621 9622 3 9333 9622 9334 3 9334 9622 9623 3 9334 9623 9335 3 9335 9623 9624 3 9335 9624 9336 3 9336 9624 9625 3 9336 9625 9337 3 9337 9625 9626 3 9337 9626 9338 3 9338 9626 9627 3 9338 9627 9339 3 9339 9627 9628 3 9339 9628 9340 3 9340 9628 9629 3 9340 9629 9341 3 9341 9629 9630 3 9341 9630 9342 3 9342 9630 9631 3 9342 9631 9343 3 9343 9631 9632 3 9343 9632 9344 3 9344 9632 9633 3 9344 9633 9345 3 9345 9633 9634 3 9345 9634 9346 3 9346 9634 9635 3 9346 9635 9347 3 9347 9635 9636 3 9347 9636 9348 3 9348 9636 9637 3 9348 9637 9349 3 9349 9637 9638 3 9349 9638 9350 3 9350 9638 9639 3 9350 9639 9351 3 9351 9639 9640 3 9351 9640 9352 3 9352 9640 9641 3 9352 9641 9353 3 9353 9641 9642 3 9353 9642 9354 3 9354 9642 9643 3 9354 9643 9355 3 9355 9643 9644 3 9355 9644 9356 3 9356 9644 9645 3 9356 9645 9357 3 9357 9645 9646 3 9357 9646 9358 3 9358 9646 9647 3 9358 9647 9359 3 9359 9647 9648 3 9359 9648 9360 3 9360 9648 9649 3 9360 9649 9361 3 9361 9649 9650 3 9361 9650 9362 3 9362 9650 9651 3 9362 9651 9363 3 9363 9651 9652 3 9363 9652 9364 3 9364 9652 9653 3 9364 9653 9365 3 9365 9653 9654 3 9365 9654 9366 3 9366 9654 9655 3 9366 9655 9367 3 9367 9655 9656 3 9367 9656 9368 3 9368 9656 9657 3 9368 9657 9369 3 9369 9657 9658 3 9369 9658 9370 3 9370 9658 9659 3 9370 9659 9371 3 9371 9659 9660 3 9371 9660 9372 3 9372 9660 9661 3 9372 9661 9373 3 9373 9661 9662 3 9373 9662 9374 3 9374 9662 9663 3 9374 9663 9375 3 9375 9663 9664 3 9375 9664 9376 3 9376 9664 9665 3 9376 9665 9377 3 9377 9665 9666 3 9377 9666 9378 3 9378 9666 9667 3 9378 9667 9379 3 9379 9667 9668 3 9379 9668 9380 3 9380 9668 9669 3 9380 9669 9381 3 9381 9669 9670 3 9381 9670 9382 3 9382 9670 9671 3 9382 9671 9383 3 9383 9671 9384 3 9672 9384 9671 3 9384 9672 9385 3 9673 9385 9672 3 9385 9673 9386 3 9674 9386 9673 3 9386 9674 9387 3 9675 9387 9674 3 9387 9675 9388 3 9676 9388 9675 3 9388 9676 9389 3 9677 9389 9676 3 9389 9677 9390 3 9678 9390 9677 3 9390 9678 9391 3 9679 9391 9678 3 9391 9679 9392 3 9680 9392 9679 3 9392 9680 9393 3 9681 9393 9680 3 9393 9681 9396 3 9684 9396 9681 3 9394 9682 9395 3 9683 9395 9682 3 9394 9399 9687 3 9394 9687 9682 3 9396 9684 9397 3 9685 9397 9684 3 9397 9685 9400 3 9688 9400 9685 3 9398 9686 9399 3 9687 9399 9686 3 9398 9402 9690 3 9398 9690 9686 3 9400 9688 9401 3 9689 9401 9688 3 9401 9689 9403 3 9691 9403 9689 3 9402 9404 9692 3 9402 9692 9690 3 9403 9691 9405 3 9693 9405 9691 3 9404 9406 9694 3 9404 9694 9692 3 9405 9693 9407 3 9695 9407 9693 3 9406 9408 9696 3 9406 9696 9694 3 9407 9695 9409 3 9697 9409 9695 3 9408 9410 9698 3 9408 9698 9696 3 9409 9697 9411 3 9699 9411 9697 3 9410 9412 9700 3 9410 9700 9698 3 9411 9699 9413 3 9701 9413 9699 3 9412 9414 9702 3 9412 9702 9700 3 9413 9701 9415 3 9703 9415 9701 3 9414 9416 9704 3 9414 9704 9702 3 9415 9703 9417 3 9705 9417 9703 3 9416 9418 9706 3 9416 9706 9704 3 9417 9705 9419 3 9707 9419 9705 3 9418 9420 9708 3 9418 9708 9706 3 9419 9707 9421 3 9709 9421 9707 3 9420 9422 9710 3 9420 9710 9708 3 9421 9709 9423 3 9711 9423 9709 3 9422 9424 9712 3 9422 9712 9710 3 9423 9711 9425 3 9713 9425 9711 3 9424 9426 9714 3 9424 9714 9712 3 9425 9713 9427 3 9715 9427 9713 3 9426 9428 9716 3 9426 9716 9714 3 9427 9715 9429 3 9717 9429 9715 3 9428 9430 9716 3 9718 9716 9430 3 9429 9717 9431 3 9719 9431 9717 3 9430 9432 9718 3 9720 9718 9432 3 9431 9719 9433 3 9721 9433 9719 3 9432 9434 9720 3 9722 9720 9434 3 9433 9721 9435 3 9723 9435 9721 3 9434 9436 9722 3 9724 9722 9436 3 9435 9723 9437 3 9725 9437 9723 3 9436 9438 9724 3 9726 9724 9438 3 9437 9725 9439 3 9727 9439 9725 3 9438 9440 9726 3 9728 9726 9440 3 9439 9727 9441 3 9729 9441 9727 3 9440 9442 9728 3 9730 9728 9442 3 9441 9729 9443 3 9731 9443 9729 3 9442 9444 9730 3 9732 9730 9444 3 9443 9731 9445 3 9733 9445 9731 3 9444 9446 9732 3 9734 9732 9446 3 9445 9733 9735 3 9445 9735 9447 3 9446 9448 9734 3 9736 9734 9448 3 9447 9735 9737 3 9447 9737 9449 3 9448 9450 9736 3 9738 9736 9450 3 9449 9737 9739 3 9449 9739 9451 3 9450 9452 9738 3 9740 9738 9452 3 9451 9739 9741 3 9451 9741 9453 3 9452 9454 9740 3 9742 9740 9454 3 9453 9741 9743 3 9453 9743 9455 3 9454 9456 9742 3 9744 9742 9456 3 9455 9743 9745 3 9455 9745 9457 3 9456 9458 9744 3 9746 9744 9458 3 9457 9745 9747 3 9457 9747 9459 3 9458 9460 9746 3 9748 9746 9460 3 9459 9747 9749 3 9459 9749 9461 3 9460 9462 9748 3 9750 9748 9462 3 9461 9749 9751 3 9461 9751 9463 3 9462 9464 9750 3 9752 9750 9464 3 9463 9751 9753 3 9463 9753 9465 3 9464 9466 9752 3 9754 9752 9466 3 9465 9753 9755 3 9465 9755 9467 3 9466 9468 9754 3 9756 9754 9468 3 9467 9755 9757 3 9467 9757 9469 3 9468 9470 9756 3 9758 9756 9470 3 9469 9757 9759 3 9469 9759 9471 3 9470 9472 9758 3 9760 9758 9472 3 9471 9759 9761 3 9471 9761 9473 3 9472 9474 9760 3 9762 9760 9474 3 9473 9761 9763 3 9473 9763 9475 3 9474 9476 9762 3 9764 9762 9476 3 9475 9763 9765 3 9475 9765 9477 3 9476 9478 9764 3 9766 9764 9478 3 9477 9765 9767 3 9477 9767 9479 3 9478 9480 9766 3 9768 9766 9480 3 9479 9767 9769 3 9479 9769 9481 3 9480 9482 9768 3 9770 9768 9482 3 9481 9769 9771 3 9481 9771 9483 3 9482 9484 9770 3 9772 9770 9484 3 9483 9771 9773 3 9483 9773 9485 3 9484 9486 9772 3 9774 9772 9486 3 9485 9773 9775 3 9485 9775 9487 3 9486 9488 9774 3 9776 9774 9488 3 9487 9775 9777 3 9487 9777 9489 3 9488 9490 9778 3 9488 9778 9776 3 9489 9777 9779 3 9489 9779 9491 3 9490 9492 9780 3 9490 9780 9778 3 9491 9779 9781 3 9491 9781 9493 3 9492 9494 9782 3 9492 9782 9780 3 9493 9781 9783 3 9493 9783 9495 3 9494 9496 9784 3 9494 9784 9782 3 9495 9783 9785 3 9495 9785 9497 3 9496 9498 9786 3 9496 9786 9784 3 9497 9785 9787 3 9497 9787 9499 3 9498 9500 9788 3 9498 9788 9786 3 9499 9787 9789 3 9499 9789 9501 3 9500 9502 9790 3 9500 9790 9788 3 9501 9789 9791 3 9501 9791 9503 3 9502 9504 9792 3 9502 9792 9790 3 9503 9791 9793 3 9503 9793 9505 3 9504 9506 9794 3 9504 9794 9792 3 9505 9793 9507 3 9795 9507 9793 3 9506 9508 9796 3 9506 9796 9794 3 9507 9795 9509 3 9797 9509 9795 3 9508 9510 9798 3 9508 9798 9796 3 9509 9797 9511 3 9799 9511 9797 3 9510 9512 9800 3 9510 9800 9798 3 9511 9799 9513 3 9801 9513 9799 3 9512 9514 9802 3 9512 9802 9800 3 9513 9801 9515 3 9803 9515 9801 3 9514 9516 9804 3 9514 9804 9802 3 9515 9803 9517 3 9805 9517 9803 3 9516 9518 9806 3 9516 9806 9804 3 9517 9805 9519 3 9807 9519 9805 3 9518 9520 9808 3 9518 9808 9806 3 9519 9807 9521 3 9809 9521 9807 3 9520 9522 9810 3 9520 9810 9808 3 9521 9809 9523 3 9811 9523 9809 3 9522 9524 9812 3 9522 9812 9810 3 9523 9811 9525 3 9813 9525 9811 3 9524 9526 9814 3 9524 9814 9812 3 9525 9813 9527 3 9815 9527 9813 3 9526 9528 9816 3 9526 9816 9814 3 9527 9815 9529 3 9817 9529 9815 3 9528 9530 9818 3 9528 9818 9816 3 9529 9817 9531 3 9819 9531 9817 3 9530 9532 9820 3 9530 9820 9818 3 9531 9819 9533 3 9821 9533 9819 3 9532 9534 9822 3 9532 9822 9820 3 9533 9821 9535 3 9823 9535 9821 3 9534 9536 9824 3 9534 9824 9822 3 9535 9823 9539 3 9827 9539 9823 3 9536 9537 9825 3 9536 9825 9824 3 9537 9540 9828 3 9537 9828 9825 3 9538 9539 9827 3 9538 9827 9826 3 9538 9826 9543 3 9831 9543 9826 3 9540 9541 9829 3 9540 9829 9828 3 9541 9544 9832 3 9541 9832 9829 3 9542 9543 9831 3 9542 9831 9830 3 9542 9830 9612 3 9900 9612 9830 3 9544 9545 9833 3 9544 9833 9832 3 9545 9546 9834 3 9545 9834 9833 3 9546 9547 9835 3 9546 9835 9834 3 9547 9548 9836 3 9547 9836 9835 3 9548 9549 9836 3 9837 9836 9549 3 9549 9550 9837 3 9838 9837 9550 3 9550 9551 9838 3 9839 9838 9551 3 9551 9552 9839 3 9840 9839 9552 3 9552 9553 9840 3 9841 9840 9553 3 9553 9554 9841 3 9842 9841 9554 3 9554 9555 9842 3 9843 9842 9555 3 9555 9556 9843 3 9844 9843 9556 3 9556 9557 9844 3 9845 9844 9557 3 9557 9558 9845 3 9846 9845 9558 3 9558 9559 9846 3 9847 9846 9559 3 9559 9560 9847 3 9848 9847 9560 3 9560 9561 9848 3 9849 9848 9561 3 9561 9562 9849 3 9850 9849 9562 3 9562 9563 9850 3 9851 9850 9563 3 9563 9564 9851 3 9852 9851 9564 3 9564 9565 9852 3 9853 9852 9565 3 9565 9566 9853 3 9854 9853 9566 3 9566 9567 9854 3 9855 9854 9567 3 9567 9568 9855 3 9856 9855 9568 3 9568 9569 9856 3 9857 9856 9569 3 9569 9570 9857 3 9858 9857 9570 3 9570 9571 9858 3 9859 9858 9571 3 9571 9572 9859 3 9860 9859 9572 3 9572 9573 9860 3 9861 9860 9573 3 9573 9574 9861 3 9862 9861 9574 3 9574 9575 9862 3 9863 9862 9575 3 9575 9576 9863 3 9864 9863 9576 3 9576 9577 9864 3 9865 9864 9577 3 9577 9578 9865 3 9866 9865 9578 3 9578 9579 9866 3 9867 9866 9579 3 9579 9580 9867 3 9868 9867 9580 3 9580 9581 9868 3 9869 9868 9581 3 9581 9582 9869 3 9870 9869 9582 3 9582 9583 9870 3 9871 9870 9583 3 9583 9584 9871 3 9872 9871 9584 3 9584 9585 9872 3 9873 9872 9585 3 9585 9586 9873 3 9874 9873 9586 3 9586 9587 9874 3 9875 9874 9587 3 9587 9588 9875 3 9876 9875 9588 3 9588 9589 9876 3 9877 9876 9589 3 9589 9590 9877 3 9878 9877 9590 3 9590 9591 9878 3 9879 9878 9591 3 9591 9592 9879 3 9880 9879 9592 3 9592 9593 9880 3 9881 9880 9593 3 9593 9594 9881 3 9882 9881 9594 3 9594 9595 9882 3 9883 9882 9595 3 9595 9596 9883 3 9884 9883 9596 3 9596 9597 9884 3 9885 9884 9597 3 9597 9598 9885 3 9886 9885 9598 3 9598 9599 9886 3 9887 9886 9599 3 9599 9600 9887 3 9888 9887 9600 3 9600 9601 9888 3 9889 9888 9601 3 9601 9602 9889 3 9890 9889 9602 3 9602 9603 9890 3 9891 9890 9603 3 9603 9604 9891 3 9892 9891 9604 3 9604 9605 9892 3 9893 9892 9605 3 9605 9606 9893 3 9894 9893 9606 3 9606 9607 9894 3 9895 9894 9607 3 9607 9608 9895 3 9896 9895 9608 3 9608 9609 9897 3 9608 9897 9896 3 9609 9610 9898 3 9609 9898 9897 3 9610 9611 9899 3 9610 9899 9898 3 9611 9612 9900 3 9611 9900 9899 3 9613 9901 9902 3 9613 9902 9614 3 9613 9683 9971 3 9613 9971 9901 3 9614 9902 9903 3 9614 9903 9615 3 9615 9903 9904 3 9615 9904 9616 3 9616 9904 9905 3 9616 9905 9617 3 9617 9905 9906 3 9617 9906 9618 3 9618 9906 9907 3 9618 9907 9619 3 9619 9907 9908 3 9619 9908 9620 3 9620 9908 9909 3 9620 9909 9621 3 9621 9909 9910 3 9621 9910 9622 3 9622 9910 9911 3 9622 9911 9623 3 9623 9911 9912 3 9623 9912 9624 3 9624 9912 9913 3 9624 9913 9625 3 9625 9913 9914 3 9625 9914 9626 3 9626 9914 9627 3 9915 9627 9914 3 9627 9915 9628 3 9916 9628 9915 3 9628 9916 9629 3 9917 9629 9916 3 9629 9917 9630 3 9918 9630 9917 3 9630 9918 9631 3 9919 9631 9918 3 9631 9919 9632 3 9920 9632 9919 3 9632 9920 9633 3 9921 9633 9920 3 9633 9921 9634 3 9922 9634 9921 3 9634 9922 9635 3 9923 9635 9922 3 9635 9923 9636 3 9924 9636 9923 3 9636 9924 9637 3 9925 9637 9924 3 9637 9925 9638 3 9926 9638 9925 3 9638 9926 9639 3 9927 9639 9926 3 9639 9927 9640 3 9928 9640 9927 3 9640 9928 9641 3 9929 9641 9928 3 9641 9929 9642 3 9930 9642 9929 3 9642 9930 9643 3 9931 9643 9930 3 9643 9931 9644 3 9932 9644 9931 3 9644 9932 9645 3 9933 9645 9932 3 9645 9933 9646 3 9934 9646 9933 3 9646 9934 9647 3 9935 9647 9934 3 9647 9935 9648 3 9936 9648 9935 3 9648 9936 9649 3 9937 9649 9936 3 9649 9937 9650 3 9938 9650 9937 3 9650 9938 9651 3 9939 9651 9938 3 9651 9939 9652 3 9940 9652 9939 3 9652 9940 9653 3 9941 9653 9940 3 9653 9941 9654 3 9942 9654 9941 3 9654 9942 9655 3 9943 9655 9942 3 9655 9943 9656 3 9944 9656 9943 3 9656 9944 9657 3 9945 9657 9944 3 9657 9945 9658 3 9946 9658 9945 3 9658 9946 9659 3 9947 9659 9946 3 9659 9947 9660 3 9948 9660 9947 3 9660 9948 9661 3 9949 9661 9948 3 9661 9949 9662 3 9950 9662 9949 3 9662 9950 9663 3 9951 9663 9950 3 9663 9951 9664 3 9952 9664 9951 3 9664 9952 9665 3 9953 9665 9952 3 9665 9953 9666 3 9954 9666 9953 3 9666 9954 9667 3 9955 9667 9954 3 9667 9955 9668 3 9956 9668 9955 3 9668 9956 9669 3 9957 9669 9956 3 9669 9957 9670 3 9958 9670 9957 3 9670 9958 9671 3 9959 9671 9958 3 9671 9959 9672 3 9960 9672 9959 3 9672 9960 9673 3 9961 9673 9960 3 9673 9961 9674 3 9962 9674 9961 3 9674 9962 9675 3 9963 9675 9962 3 9675 9963 9676 3 9964 9676 9963 3 9676 9964 9677 3 9965 9677 9964 3 9677 9965 9678 3 9966 9678 9965 3 9678 9966 9679 3 9967 9679 9966 3 9679 9967 9680 3 9968 9680 9967 3 9680 9968 9681 3 9969 9681 9968 3 9681 9969 9684 3 9972 9684 9969 3 9682 9970 9683 3 9971 9683 9970 3 9682 9687 9970 3 9975 9970 9687 3 9684 9972 9685 3 9973 9685 9972 3 9685 9973 9688 3 9976 9688 9973 3 9686 9974 9687 3 9975 9687 9974 3 9686 9690 9974 3 9978 9974 9690 3 9688 9976 9977 3 9688 9977 9689 3 9689 9977 9979 3 9689 9979 9691 3 9690 9692 9978 3 9980 9978 9692 3 9691 9979 9981 3 9691 9981 9693 3 9692 9694 9980 3 9982 9980 9694 3 9693 9981 9983 3 9693 9983 9695 3 9694 9696 9982 3 9984 9982 9696 3 9695 9983 9985 3 9695 9985 9697 3 9696 9698 9984 3 9986 9984 9698 3 9697 9985 9987 3 9697 9987 9699 3 9698 9700 9986 3 9988 9986 9700 3 9699 9987 9989 3 9699 9989 9701 3 9700 9702 9988 3 9990 9988 9702 3 9701 9989 9991 3 9701 9991 9703 3 9702 9704 9990 3 9992 9990 9704 3 9703 9991 9993 3 9703 9993 9705 3 9704 9706 9992 3 9994 9992 9706 3 9705 9993 9995 3 9705 9995 9707 3 9706 9708 9994 3 9996 9994 9708 3 9707 9995 9997 3 9707 9997 9709 3 9708 9710 9996 3 9998 9996 9710 3 9709 9997 9999 3 9709 9999 9711 3 9710 9712 9998 3 10000 9998 9712 3 9711 9999 10001 3 9711 10001 9713 3 9712 9714 10000 3 10002 10000 9714 3 9713 10001 10003 3 9713 10003 9715 3 9714 9716 10002 3 10004 10002 9716 3 9715 10003 10005 3 9715 10005 9717 3 9716 9718 10004 3 10006 10004 9718 3 9717 10005 10007 3 9717 10007 9719 3 9718 9720 10006 3 10008 10006 9720 3 9719 10007 10009 3 9719 10009 9721 3 9720 9722 10008 3 10010 10008 9722 3 9721 10009 10011 3 9721 10011 9723 3 9722 9724 10010 3 10012 10010 9724 3 9723 10011 10013 3 9723 10013 9725 3 9724 9726 10012 3 10014 10012 9726 3 9725 10013 10015 3 9725 10015 9727 3 9726 9728 10014 3 10016 10014 9728 3 9727 10015 10017 3 9727 10017 9729 3 9728 9730 10016 3 10018 10016 9730 3 9729 10017 10019 3 9729 10019 9731 3 9730 9732 10020 3 9730 10020 10018 3 9731 10019 10021 3 9731 10021 9733 3 9732 9734 10022 3 9732 10022 10020 3 9733 10021 10023 3 9733 10023 9735 3 9734 9736 10024 3 9734 10024 10022 3 9735 10023 10025 3 9735 10025 9737 3 9736 9738 10026 3 9736 10026 10024 3 9737 10025 10027 3 9737 10027 9739 3 9738 9740 10028 3 9738 10028 10026 3 9739 10027 10029 3 9739 10029 9741 3 9740 9742 10030 3 9740 10030 10028 3 9741 10029 10031 3 9741 10031 9743 3 9742 9744 10032 3 9742 10032 10030 3 9743 10031 10033 3 9743 10033 9745 3 9744 9746 10034 3 9744 10034 10032 3 9745 10033 10035 3 9745 10035 9747 3 9746 9748 10036 3 9746 10036 10034 3 9747 10035 10037 3 9747 10037 9749 3 9748 9750 10038 3 9748 10038 10036 3 9749 10037 9751 3 10039 9751 10037 3 9750 9752 10040 3 9750 10040 10038 3 9751 10039 9753 3 10041 9753 10039 3 9752 9754 10042 3 9752 10042 10040 3 9753 10041 9755 3 10043 9755 10041 3 9754 9756 10044 3 9754 10044 10042 3 9755 10043 9757 3 10045 9757 10043 3 9756 9758 10046 3 9756 10046 10044 3 9757 10045 9759 3 10047 9759 10045 3 9758 9760 10048 3 9758 10048 10046 3 9759 10047 9761 3 10049 9761 10047 3 9760 9762 10050 3 9760 10050 10048 3 9761 10049 9763 3 10051 9763 10049 3 9762 9764 10052 3 9762 10052 10050 3 9763 10051 9765 3 10053 9765 10051 3 9764 9766 10054 3 9764 10054 10052 3 9765 10053 9767 3 10055 9767 10053 3 9766 9768 10056 3 9766 10056 10054 3 9767 10055 9769 3 10057 9769 10055 3 9768 9770 10058 3 9768 10058 10056 3 9769 10057 9771 3 10059 9771 10057 3 9770 9772 10060 3 9770 10060 10058 3 9771 10059 9773 3 10061 9773 10059 3 9772 9774 10062 3 9772 10062 10060 3 9773 10061 9775 3 10063 9775 10061 3 9774 9776 10064 3 9774 10064 10062 3 9775 10063 9777 3 10065 9777 10063 3 9776 9778 10066 3 9776 10066 10064 3 9777 10065 9779 3 10067 9779 10065 3 9778 9780 10068 3 9778 10068 10066 3 9779 10067 9781 3 10069 9781 10067 3 9780 9782 10070 3 9780 10070 10068 3 9781 10069 9783 3 10071 9783 10069 3 9782 9784 10072 3 9782 10072 10070 3 9783 10071 9785 3 10073 9785 10071 3 9784 9786 10074 3 9784 10074 10072 3 9785 10073 9787 3 10075 9787 10073 3 9786 9788 10076 3 9786 10076 10074 3 9787 10075 9789 3 10077 9789 10075 3 9788 9790 10078 3 9788 10078 10076 3 9789 10077 9791 3 10079 9791 10077 3 9790 9792 10078 3 10080 10078 9792 3 9791 10079 9793 3 10081 9793 10079 3 9792 9794 10080 3 10082 10080 9794 3 9793 10081 9795 3 10083 9795 10081 3 9794 9796 10082 3 10084 10082 9796 3 9795 10083 9797 3 10085 9797 10083 3 9796 9798 10084 3 10086 10084 9798 3 9797 10085 9799 3 10087 9799 10085 3 9798 9800 10086 3 10088 10086 9800 3 9799 10087 9801 3 10089 9801 10087 3 9800 9802 10088 3 10090 10088 9802 3 9801 10089 9803 3 10091 9803 10089 3 9802 9804 10090 3 10092 10090 9804 3 9803 10091 9805 3 10093 9805 10091 3 9804 9806 10092 3 10094 10092 9806 3 9805 10093 9807 3 10095 9807 10093 3 9806 9808 10094 3 10096 10094 9808 3 9807 10095 9809 3 10097 9809 10095 3 9808 9810 10096 3 10098 10096 9810 3 9809 10097 10099 3 9809 10099 9811 3 9810 9812 10098 3 10100 10098 9812 3 9811 10099 10101 3 9811 10101 9813 3 9812 9814 10100 3 10102 10100 9814 3 9813 10101 10103 3 9813 10103 9815 3 9814 9816 10102 3 10104 10102 9816 3 9815 10103 10105 3 9815 10105 9817 3 9816 9818 10104 3 10106 10104 9818 3 9817 10105 10107 3 9817 10107 9819 3 9818 9820 10106 3 10108 10106 9820 3 9819 10107 10109 3 9819 10109 9821 3 9820 9822 10108 3 10110 10108 9822 3 9821 10109 10111 3 9821 10111 9823 3 9822 9824 10110 3 10112 10110 9824 3 9823 10111 10115 3 9823 10115 9827 3 9824 9825 10112 3 10113 10112 9825 3 9825 9828 10113 3 10116 10113 9828 3 9826 9827 10114 3 10115 10114 9827 3 9826 10114 10119 3 9826 10119 9831 3 9828 9829 10116 3 10117 10116 9829 3 9829 9832 10117 3 10120 10117 9832 3 9830 9831 10118 3 10119 10118 9831 3 9830 10118 10188 3 9830 10188 9900 3 9832 9833 10120 3 10121 10120 9833 3 9833 9834 10121 3 10122 10121 9834 3 9834 9835 10122 3 10123 10122 9835 3 9835 9836 10123 3 10124 10123 9836 3 9836 9837 10124 3 10125 10124 9837 3 9837 9838 10125 3 10126 10125 9838 3 9838 9839 10126 3 10127 10126 9839 3 9839 9840 10127 3 10128 10127 9840 3 9840 9841 10128 3 10129 10128 9841 3 9841 9842 10129 3 10130 10129 9842 3 9842 9843 10130 3 10131 10130 9843 3 9843 9844 10131 3 10132 10131 9844 3 9844 9845 10132 3 10133 10132 9845 3 9845 9846 10133 3 10134 10133 9846 3 9846 9847 10134 3 10135 10134 9847 3 9847 9848 10135 3 10136 10135 9848 3 9848 9849 10136 3 10137 10136 9849 3 9849 9850 10137 3 10138 10137 9850 3 9850 9851 10138 3 10139 10138 9851 3 9851 9852 10140 3 9851 10140 10139 3 9852 9853 10141 3 9852 10141 10140 3 9853 9854 10142 3 9853 10142 10141 3 9854 9855 10143 3 9854 10143 10142 3 9855 9856 10144 3 9855 10144 10143 3 9856 9857 10145 3 9856 10145 10144 3 9857 9858 10146 3 9857 10146 10145 3 9858 9859 10147 3 9858 10147 10146 3 9859 9860 10148 3 9859 10148 10147 3 9860 9861 10149 3 9860 10149 10148 3 9861 9862 10150 3 9861 10150 10149 3 9862 9863 10151 3 9862 10151 10150 3 9863 9864 10152 3 9863 10152 10151 3 9864 9865 10153 3 9864 10153 10152 3 9865 9866 10154 3 9865 10154 10153 3 9866 9867 10155 3 9866 10155 10154 3 9867 9868 10156 3 9867 10156 10155 3 9868 9869 10157 3 9868 10157 10156 3 9869 9870 10158 3 9869 10158 10157 3 9870 9871 10159 3 9870 10159 10158 3 9871 9872 10160 3 9871 10160 10159 3 9872 9873 10161 3 9872 10161 10160 3 9873 9874 10162 3 9873 10162 10161 3 9874 9875 10163 3 9874 10163 10162 3 9875 9876 10164 3 9875 10164 10163 3 9876 9877 10165 3 9876 10165 10164 3 9877 9878 10166 3 9877 10166 10165 3 9878 9879 10167 3 9878 10167 10166 3 9879 9880 10168 3 9879 10168 10167 3 9880 9881 10169 3 9880 10169 10168 3 9881 9882 10170 3 9881 10170 10169 3 9882 9883 10171 3 9882 10171 10170 3 9883 9884 10172 3 9883 10172 10171 3 9884 9885 10173 3 9884 10173 10172 3 9885 9886 10174 3 9885 10174 10173 3 9886 9887 10175 3 9886 10175 10174 3 9887 9888 10176 3 9887 10176 10175 3 9888 9889 10177 3 9888 10177 10176 3 9889 9890 10178 3 9889 10178 10177 3 9890 9891 10179 3 9890 10179 10178 3 9891 9892 10180 3 9891 10180 10179 3 9892 9893 10181 3 9892 10181 10180 3 9893 9894 10182 3 9893 10182 10181 3 9894 9895 10183 3 9894 10183 10182 3 9895 9896 10184 3 9895 10184 10183 3 9896 9897 10185 3 9896 10185 10184 3 9897 9898 10186 3 9897 10186 10185 3 9898 9899 10187 3 9898 10187 10186 3 9899 9900 10188 3 9899 10188 10187 3 9901 10189 9902 3 10190 9902 10189 3 9901 9971 10189 3 10259 10189 9971 3 9902 10190 9903 3 10191 9903 10190 3 9903 10191 9904 3 10192 9904 10191 3 9904 10192 9905 3 10193 9905 10192 3 9905 10193 9906 3 10194 9906 10193 3 9906 10194 9907 3 10195 9907 10194 3 9907 10195 9908 3 10196 9908 10195 3 9908 10196 9909 3 10197 9909 10196 3 9909 10197 9910 3 10198 9910 10197 3 9910 10198 9911 3 10199 9911 10198 3 9911 10199 9912 3 10200 9912 10199 3 9912 10200 9913 3 10201 9913 10200 3 9913 10201 9914 3 10202 9914 10201 3 9914 10202 9915 3 10203 9915 10202 3 9915 10203 9916 3 10204 9916 10203 3 9916 10204 9917 3 10205 9917 10204 3 9917 10205 9918 3 10206 9918 10205 3 9918 10206 9919 3 10207 9919 10206 3 9919 10207 9920 3 10208 9920 10207 3 9920 10208 9921 3 10209 9921 10208 3 9921 10209 9922 3 10210 9922 10209 3 9922 10210 9923 3 10211 9923 10210 3 9923 10211 9924 3 10212 9924 10211 3 9924 10212 9925 3 10213 9925 10212 3 9925 10213 9926 3 10214 9926 10213 3 9926 10214 9927 3 10215 9927 10214 3 9927 10215 9928 3 10216 9928 10215 3 9928 10216 9929 3 10217 9929 10216 3 9929 10217 9930 3 10218 9930 10217 3 9930 10218 9931 3 10219 9931 10218 3 9931 10219 9932 3 10220 9932 10219 3 9932 10220 10221 3 9932 10221 9933 3 9933 10221 10222 3 9933 10222 9934 3 9934 10222 10223 3 9934 10223 9935 3 9935 10223 10224 3 9935 10224 9936 3 9936 10224 10225 3 9936 10225 9937 3 9937 10225 10226 3 9937 10226 9938 3 9938 10226 10227 3 9938 10227 9939 3 9939 10227 10228 3 9939 10228 9940 3 9940 10228 10229 3 9940 10229 9941 3 9941 10229 10230 3 9941 10230 9942 3 9942 10230 10231 3 9942 10231 9943 3 9943 10231 10232 3 9943 10232 9944 3 9944 10232 10233 3 9944 10233 9945 3 9945 10233 10234 3 9945 10234 9946 3 9946 10234 10235 3 9946 10235 9947 3 9947 10235 10236 3 9947 10236 9948 3 9948 10236 10237 3 9948 10237 9949 3 9949 10237 10238 3 9949 10238 9950 3 9950 10238 10239 3 9950 10239 9951 3 9951 10239 10240 3 9951 10240 9952 3 9952 10240 10241 3 9952 10241 9953 3 9953 10241 10242 3 9953 10242 9954 3 9954 10242 10243 3 9954 10243 9955 3 9955 10243 10244 3 9955 10244 9956 3 9956 10244 10245 3 9956 10245 9957 3 9957 10245 10246 3 9957 10246 9958 3 9958 10246 10247 3 9958 10247 9959 3 9959 10247 10248 3 9959 10248 9960 3 9960 10248 10249 3 9960 10249 9961 3 9961 10249 10250 3 9961 10250 9962 3 9962 10250 10251 3 9962 10251 9963 3 9963 10251 10252 3 9963 10252 9964 3 9964 10252 10253 3 9964 10253 9965 3 9965 10253 10254 3 9965 10254 9966 3 9966 10254 10255 3 9966 10255 9967 3 9967 10255 10256 3 9967 10256 9968 3 9968 10256 10257 3 9968 10257 9969 3 9969 10257 10260 3 9969 10260 9972 3 9970 10258 10259 3 9970 10259 9971 3 9970 9975 10258 3 10263 10258 9975 3 9972 10260 10261 3 9972 10261 9973 3 9973 10261 10264 3 9973 10264 9976 3 9974 10262 10263 3 9974 10263 9975 3 9974 9978 10266 3 9974 10266 10262 3 9976 10264 10265 3 9976 10265 9977 3 9977 10265 10267 3 9977 10267 9979 3 9978 9980 10268 3 9978 10268 10266 3 9979 10267 10269 3 9979 10269 9981 3 9980 9982 10270 3 9980 10270 10268 3 9981 10269 10271 3 9981 10271 9983 3 9982 9984 10272 3 9982 10272 10270 3 9983 10271 10273 3 9983 10273 9985 3 9984 9986 10274 3 9984 10274 10272 3 9985 10273 10275 3 9985 10275 9987 3 9986 9988 10276 3 9986 10276 10274 3 9987 10275 10277 3 9987 10277 9989 3 9988 9990 10278 3 9988 10278 10276 3 9989 10277 10279 3 9989 10279 9991 3 9990 9992 10280 3 9990 10280 10278 3 9991 10279 10281 3 9991 10281 9993 3 9992 9994 10282 3 9992 10282 10280 3 9993 10281 10283 3 9993 10283 9995 3 9994 9996 10284 3 9994 10284 10282 3 9995 10283 9997 3 10285 9997 10283 3 9996 9998 10286 3 9996 10286 10284 3 9997 10285 9999 3 10287 9999 10285 3 9998 10000 10288 3 9998 10288 10286 3 9999 10287 10001 3 10289 10001 10287 3 10000 10002 10290 3 10000 10290 10288 3 10001 10289 10003 3 10291 10003 10289 3 10002 10004 10292 3 10002 10292 10290 3 10003 10291 10005 3 10293 10005 10291 3 10004 10006 10294 3 10004 10294 10292 3 10005 10293 10007 3 10295 10007 10293 3 10006 10008 10296 3 10006 10296 10294 3 10007 10295 10009 3 10297 10009 10295 3 10008 10010 10298 3 10008 10298 10296 3 10009 10297 10011 3 10299 10011 10297 3 10010 10012 10300 3 10010 10300 10298 3 10011 10299 10013 3 10301 10013 10299 3 10012 10014 10302 3 10012 10302 10300 3 10013 10301 10015 3 10303 10015 10301 3 10014 10016 10304 3 10014 10304 10302 3 10015 10303 10017 3 10305 10017 10303 3 10016 10018 10306 3 10016 10306 10304 3 10017 10305 10019 3 10307 10019 10305 3 10018 10020 10308 3 10018 10308 10306 3 10019 10307 10021 3 10309 10021 10307 3 10020 10022 10310 3 10020 10310 10308 3 10021 10309 10023 3 10311 10023 10309 3 10022 10024 10312 3 10022 10312 10310 3 10023 10311 10025 3 10313 10025 10311 3 10024 10026 10314 3 10024 10314 10312 3 10025 10313 10027 3 10315 10027 10313 3 10026 10028 10316 3 10026 10316 10314 3 10027 10315 10029 3 10317 10029 10315 3 10028 10030 10318 3 10028 10318 10316 3 10029 10317 10031 3 10319 10031 10317 3 10030 10032 10320 3 10030 10320 10318 3 10031 10319 10033 3 10321 10033 10319 3 10032 10034 10322 3 10032 10322 10320 3 10033 10321 10035 3 10323 10035 10321 3 10034 10036 10324 3 10034 10324 10322 3 10035 10323 10037 3 10325 10037 10323 3 10036 10038 10324 3 10326 10324 10038 3 10037 10325 10039 3 10327 10039 10325 3 10038 10040 10326 3 10328 10326 10040 3 10039 10327 10041 3 10329 10041 10327 3 10040 10042 10328 3 10330 10328 10042 3 10041 10329 10043 3 10331 10043 10329 3 10042 10044 10330 3 10332 10330 10044 3 10043 10331 10045 3 10333 10045 10331 3 10044 10046 10332 3 10334 10332 10046 3 10045 10333 10047 3 10335 10047 10333 3 10046 10048 10334 3 10336 10334 10048 3 10047 10335 10049 3 10337 10049 10335 3 10048 10050 10336 3 10338 10336 10050 3 10049 10337 10051 3 10339 10051 10337 3 10050 10052 10338 3 10340 10338 10052 3 10051 10339 10053 3 10341 10053 10339 3 10052 10054 10340 3 10342 10340 10054 3 10053 10341 10055 3 10343 10055 10341 3 10054 10056 10342 3 10344 10342 10056 3 10055 10343 10057 3 10345 10057 10343 3 10056 10058 10344 3 10346 10344 10058 3 10057 10345 10347 3 10057 10347 10059 3 10058 10060 10346 3 10348 10346 10060 3 10059 10347 10349 3 10059 10349 10061 3 10060 10062 10348 3 10350 10348 10062 3 10061 10349 10351 3 10061 10351 10063 3 10062 10064 10350 3 10352 10350 10064 3 10063 10351 10353 3 10063 10353 10065 3 10064 10066 10352 3 10354 10352 10066 3 10065 10353 10355 3 10065 10355 10067 3 10066 10068 10354 3 10356 10354 10068 3 10067 10355 10357 3 10067 10357 10069 3 10068 10070 10356 3 10358 10356 10070 3 10069 10357 10359 3 10069 10359 10071 3 10070 10072 10358 3 10360 10358 10072 3 10071 10359 10361 3 10071 10361 10073 3 10072 10074 10360 3 10362 10360 10074 3 10073 10361 10363 3 10073 10363 10075 3 10074 10076 10362 3 10364 10362 10076 3 10075 10363 10365 3 10075 10365 10077 3 10076 10078 10364 3 10366 10364 10078 3 10077 10365 10367 3 10077 10367 10079 3 10078 10080 10366 3 10368 10366 10080 3 10079 10367 10369 3 10079 10369 10081 3 10080 10082 10368 3 10370 10368 10082 3 10081 10369 10371 3 10081 10371 10083 3 10082 10084 10370 3 10372 10370 10084 3 10083 10371 10373 3 10083 10373 10085 3 10084 10086 10372 3 10374 10372 10086 3 10085 10373 10375 3 10085 10375 10087 3 10086 10088 10374 3 10376 10374 10088 3 10087 10375 10377 3 10087 10377 10089 3 10088 10090 10376 3 10378 10376 10090 3 10089 10377 10379 3 10089 10379 10091 3 10090 10092 10378 3 10380 10378 10092 3 10091 10379 10381 3 10091 10381 10093 3 10092 10094 10380 3 10382 10380 10094 3 10093 10381 10383 3 10093 10383 10095 3 10094 10096 10382 3 10384 10382 10096 3 10095 10383 10385 3 10095 10385 10097 3 10096 10098 10384 3 10386 10384 10098 3 10097 10385 10387 3 10097 10387 10099 3 10098 10100 10388 3 10098 10388 10386 3 10099 10387 10389 3 10099 10389 10101 3 10100 10102 10390 3 10100 10390 10388 3 10101 10389 10391 3 10101 10391 10103 3 10102 10104 10392 3 10102 10392 10390 3 10103 10391 10393 3 10103 10393 10105 3 10104 10106 10394 3 10104 10394 10392 3 10105 10393 10395 3 10105 10395 10107 3 10106 10108 10396 3 10106 10396 10394 3 10107 10395 10397 3 10107 10397 10109 3 10108 10110 10398 3 10108 10398 10396 3 10109 10397 10399 3 10109 10399 10111 3 10110 10112 10400 3 10110 10400 10398 3 10111 10399 10403 3 10111 10403 10115 3 10112 10113 10401 3 10112 10401 10400 3 10113 10116 10404 3 10113 10404 10401 3 10114 10115 10403 3 10114 10403 10402 3 10114 10402 10407 3 10114 10407 10119 3 10116 10117 10405 3 10116 10405 10404 3 10117 10120 10408 3 10117 10408 10405 3 10118 10119 10407 3 10118 10407 10406 3 10118 10406 10476 3 10118 10476 10188 3 10120 10121 10409 3 10120 10409 10408 3 10121 10122 10410 3 10121 10410 10409 3 10122 10123 10411 3 10122 10411 10410 3 10123 10124 10412 3 10123 10412 10411 3 10124 10125 10413 3 10124 10413 10412 3 10125 10126 10414 3 10125 10414 10413 3 10126 10127 10415 3 10126 10415 10414 3 10127 10128 10416 3 10127 10416 10415 3 10128 10129 10417 3 10128 10417 10416 3 10129 10130 10418 3 10129 10418 10417 3 10130 10131 10419 3 10130 10419 10418 3 10131 10132 10420 3 10131 10420 10419 3 10132 10133 10421 3 10132 10421 10420 3 10133 10134 10422 3 10133 10422 10421 3 10134 10135 10423 3 10134 10423 10422 3 10135 10136 10424 3 10135 10424 10423 3 10136 10137 10425 3 10136 10425 10424 3 10137 10138 10426 3 10137 10426 10425 3 10138 10139 10427 3 10138 10427 10426 3 10139 10140 10428 3 10139 10428 10427 3 10140 10141 10429 3 10140 10429 10428 3 10141 10142 10430 3 10141 10430 10429 3 10142 10143 10431 3 10142 10431 10430 3 10143 10144 10432 3 10143 10432 10431 3 10144 10145 10433 3 10144 10433 10432 3 10145 10146 10434 3 10145 10434 10433 3 10146 10147 10435 3 10146 10435 10434 3 10147 10148 10436 3 10147 10436 10435 3 10148 10149 10437 3 10148 10437 10436 3 10149 10150 10438 3 10149 10438 10437 3 10150 10151 10439 3 10150 10439 10438 3 10151 10152 10440 3 10151 10440 10439 3 10152 10153 10441 3 10152 10441 10440 3 10153 10154 10442 3 10153 10442 10441 3 10154 10155 10443 3 10154 10443 10442 3 10155 10156 10444 3 10155 10444 10443 3 10156 10157 10445 3 10156 10445 10444 3 10157 10158 10446 3 10157 10446 10445 3 10158 10159 10447 3 10158 10447 10446 3 10159 10160 10447 3 10448 10447 10160 3 10160 10161 10448 3 10449 10448 10161 3 10161 10162 10449 3 10450 10449 10162 3 10162 10163 10450 3 10451 10450 10163 3 10163 10164 10451 3 10452 10451 10164 3 10164 10165 10452 3 10453 10452 10165 3 10165 10166 10453 3 10454 10453 10166 3 10166 10167 10454 3 10455 10454 10167 3 10167 10168 10455 3 10456 10455 10168 3 10168 10169 10456 3 10457 10456 10169 3 10169 10170 10457 3 10458 10457 10170 3 10170 10171 10458 3 10459 10458 10171 3 10171 10172 10459 3 10460 10459 10172 3 10172 10173 10460 3 10461 10460 10173 3 10173 10174 10461 3 10462 10461 10174 3 10174 10175 10462 3 10463 10462 10175 3 10175 10176 10463 3 10464 10463 10176 3 10176 10177 10464 3 10465 10464 10177 3 10177 10178 10465 3 10466 10465 10178 3 10178 10179 10466 3 10467 10466 10179 3 10179 10180 10467 3 10468 10467 10180 3 10180 10181 10468 3 10469 10468 10181 3 10181 10182 10469 3 10470 10469 10182 3 10182 10183 10470 3 10471 10470 10183 3 10183 10184 10471 3 10472 10471 10184 3 10184 10185 10472 3 10473 10472 10185 3 10185 10186 10473 3 10474 10473 10186 3 10186 10187 10474 3 10475 10474 10187 3 10187 10188 10475 3 10476 10475 10188 3 10189 10477 10478 3 10189 10478 10190 3 10189 10259 10547 3 10189 10547 10477 3 10190 10478 10479 3 10190 10479 10191 3 10191 10479 10480 3 10191 10480 10192 3 10192 10480 10481 3 10192 10481 10193 3 10193 10481 10482 3 10193 10482 10194 3 10194 10482 10483 3 10194 10483 10195 3 10195 10483 10484 3 10195 10484 10196 3 10196 10484 10485 3 10196 10485 10197 3 10197 10485 10486 3 10197 10486 10198 3 10198 10486 10487 3 10198 10487 10199 3 10199 10487 10488 3 10199 10488 10200 3 10200 10488 10489 3 10200 10489 10201 3 10201 10489 10490 3 10201 10490 10202 3 10202 10490 10491 3 10202 10491 10203 3 10203 10491 10492 3 10203 10492 10204 3 10204 10492 10493 3 10204 10493 10205 3 10205 10493 10494 3 10205 10494 10206 3 10206 10494 10495 3 10206 10495 10207 3 10207 10495 10496 3 10207 10496 10208 3 10208 10496 10497 3 10208 10497 10209 3 10209 10497 10498 3 10209 10498 10210 3 10210 10498 10499 3 10210 10499 10211 3 10211 10499 10500 3 10211 10500 10212 3 10212 10500 10501 3 10212 10501 10213 3 10213 10501 10502 3 10213 10502 10214 3 10214 10502 10503 3 10214 10503 10215 3 10215 10503 10504 3 10215 10504 10216 3 10216 10504 10505 3 10216 10505 10217 3 10217 10505 10506 3 10217 10506 10218 3 10218 10506 10507 3 10218 10507 10219 3 10219 10507 10508 3 10219 10508 10220 3 10220 10508 10509 3 10220 10509 10221 3 10221 10509 10510 3 10221 10510 10222 3 10222 10510 10511 3 10222 10511 10223 3 10223 10511 10512 3 10223 10512 10224 3 10224 10512 10513 3 10224 10513 10225 3 10225 10513 10514 3 10225 10514 10226 3 10226 10514 10515 3 10226 10515 10227 3 10227 10515 10516 3 10227 10516 10228 3 10228 10516 10517 3 10228 10517 10229 3 10229 10517 10518 3 10229 10518 10230 3 10230 10518 10519 3 10230 10519 10231 3 10231 10519 10520 3 10231 10520 10232 3 10232 10520 10521 3 10232 10521 10233 3 10233 10521 10522 3 10233 10522 10234 3 10234 10522 10523 3 10234 10523 10235 3 10235 10523 10524 3 10235 10524 10236 3 10236 10524 10525 3 10236 10525 10237 3 10237 10525 10526 3 10237 10526 10238 3 10238 10526 10527 3 10238 10527 10239 3 10239 10527 10528 3 10239 10528 10240 3 10240 10528 10529 3 10240 10529 10241 3 10241 10529 10530 3 10241 10530 10242 3 10242 10530 10531 3 10242 10531 10243 3 10243 10531 10532 3 10243 10532 10244 3 10244 10532 10245 3 10533 10245 10532 3 10245 10533 10246 3 10534 10246 10533 3 10246 10534 10247 3 10535 10247 10534 3 10247 10535 10248 3 10536 10248 10535 3 10248 10536 10249 3 10537 10249 10536 3 10249 10537 10250 3 10538 10250 10537 3 10250 10538 10251 3 10539 10251 10538 3 10251 10539 10252 3 10540 10252 10539 3 10252 10540 10253 3 10541 10253 10540 3 10253 10541 10254 3 10542 10254 10541 3 10254 10542 10255 3 10543 10255 10542 3 10255 10543 10256 3 10544 10256 10543 3 10256 10544 10257 3 10545 10257 10544 3 10257 10545 10260 3 10548 10260 10545 3 10258 10546 10259 3 10547 10259 10546 3 10258 10263 10551 3 10258 10551 10546 3 10260 10548 10261 3 10549 10261 10548 3 10261 10549 10264 3 10552 10264 10549 3 10262 10550 10263 3 10551 10263 10550 3 10262 10266 10554 3 10262 10554 10550 3 10264 10552 10265 3 10553 10265 10552 3 10265 10553 10267 3 10555 10267 10553 3 10266 10268 10556 3 10266 10556 10554 3 10267 10555 10269 3 10557 10269 10555 3 10268 10270 10558 3 10268 10558 10556 3 10269 10557 10271 3 10559 10271 10557 3 10270 10272 10560 3 10270 10560 10558 3 10271 10559 10273 3 10561 10273 10559 3 10272 10274 10562 3 10272 10562 10560 3 10273 10561 10275 3 10563 10275 10561 3 10274 10276 10564 3 10274 10564 10562 3 10275 10563 10277 3 10565 10277 10563 3 10276 10278 10566 3 10276 10566 10564 3 10277 10565 10279 3 10567 10279 10565 3 10278 10280 10568 3 10278 10568 10566 3 10279 10567 10281 3 10569 10281 10567 3 10280 10282 10570 3 10280 10570 10568 3 10281 10569 10283 3 10571 10283 10569 3 10282 10284 10572 3 10282 10572 10570 3 10283 10571 10285 3 10573 10285 10571 3 10284 10286 10572 3 10574 10572 10286 3 10285 10573 10287 3 10575 10287 10573 3 10286 10288 10574 3 10576 10574 10288 3 10287 10575 10289 3 10577 10289 10575 3 10288 10290 10576 3 10578 10576 10290 3 10289 10577 10291 3 10579 10291 10577 3 10290 10292 10578 3 10580 10578 10292 3 10291 10579 10293 3 10581 10293 10579 3 10292 10294 10580 3 10582 10580 10294 3 10293 10581 10295 3 10583 10295 10581 3 10294 10296 10582 3 10584 10582 10296 3 10295 10583 10297 3 10585 10297 10583 3 10296 10298 10584 3 10586 10584 10298 3 10297 10585 10299 3 10587 10299 10585 3 10298 10300 10586 3 10588 10586 10300 3 10299 10587 10301 3 10589 10301 10587 3 10300 10302 10588 3 10590 10588 10302 3 10301 10589 10303 3 10591 10303 10589 3 10302 10304 10590 3 10592 10590 10304 3 10303 10591 10305 3 10593 10305 10591 3 10304 10306 10592 3 10594 10592 10306 3 10305 10593 10307 3 10595 10307 10593 3 10306 10308 10594 3 10596 10594 10308 3 10307 10595 10597 3 10307 10597 10309 3 10308 10310 10596 3 10598 10596 10310 3 10309 10597 10599 3 10309 10599 10311 3 10310 10312 10598 3 10600 10598 10312 3 10311 10599 10601 3 10311 10601 10313 3 10312 10314 10600 3 10602 10600 10314 3 10313 10601 10603 3 10313 10603 10315 3 10314 10316 10602 3 10604 10602 10316 3 10315 10603 10605 3 10315 10605 10317 3 10316 10318 10604 3 10606 10604 10318 3 10317 10605 10607 3 10317 10607 10319 3 10318 10320 10606 3 10608 10606 10320 3 10319 10607 10609 3 10319 10609 10321 3 10320 10322 10608 3 10610 10608 10322 3 10321 10609 10611 3 10321 10611 10323 3 10322 10324 10610 3 10612 10610 10324 3 10323 10611 10613 3 10323 10613 10325 3 10324 10326 10612 3 10614 10612 10326 3 10325 10613 10615 3 10325 10615 10327 3 10326 10328 10614 3 10616 10614 10328 3 10327 10615 10617 3 10327 10617 10329 3 10328 10330 10616 3 10618 10616 10330 3 10329 10617 10619 3 10329 10619 10331 3 10330 10332 10618 3 10620 10618 10332 3 10331 10619 10621 3 10331 10621 10333 3 10332 10334 10620 3 10622 10620 10334 3 10333 10621 10623 3 10333 10623 10335 3 10334 10336 10622 3 10624 10622 10336 3 10335 10623 10625 3 10335 10625 10337 3 10336 10338 10624 3 10626 10624 10338 3 10337 10625 10627 3 10337 10627 10339 3 10338 10340 10626 3 10628 10626 10340 3 10339 10627 10629 3 10339 10629 10341 3 10340 10342 10628 3 10630 10628 10342 3 10341 10629 10631 3 10341 10631 10343 3 10342 10344 10630 3 10632 10630 10344 3 10343 10631 10633 3 10343 10633 10345 3 10344 10346 10632 3 10634 10632 10346 3 10345 10633 10635 3 10345 10635 10347 3 10346 10348 10636 3 10346 10636 10634 3 10347 10635 10637 3 10347 10637 10349 3 10348 10350 10638 3 10348 10638 10636 3 10349 10637 10639 3 10349 10639 10351 3 10350 10352 10640 3 10350 10640 10638 3 10351 10639 10641 3 10351 10641 10353 3 10352 10354 10642 3 10352 10642 10640 3 10353 10641 10643 3 10353 10643 10355 3 10354 10356 10644 3 10354 10644 10642 3 10355 10643 10645 3 10355 10645 10357 3 10356 10358 10646 3 10356 10646 10644 3 10357 10645 10647 3 10357 10647 10359 3 10358 10360 10648 3 10358 10648 10646 3 10359 10647 10649 3 10359 10649 10361 3 10360 10362 10650 3 10360 10650 10648 3 10361 10649 10651 3 10361 10651 10363 3 10362 10364 10652 3 10362 10652 10650 3 10363 10651 10653 3 10363 10653 10365 3 10364 10366 10654 3 10364 10654 10652 3 10365 10653 10655 3 10365 10655 10367 3 10366 10368 10656 3 10366 10656 10654 3 10367 10655 10657 3 10367 10657 10369 3 10368 10370 10658 3 10368 10658 10656 3 10369 10657 10659 3 10369 10659 10371 3 10370 10372 10660 3 10370 10660 10658 3 10371 10659 10373 3 10661 10373 10659 3 10372 10374 10662 3 10372 10662 10660 3 10373 10661 10375 3 10663 10375 10661 3 10374 10376 10664 3 10374 10664 10662 3 10375 10663 10377 3 10665 10377 10663 3 10376 10378 10666 3 10376 10666 10664 3 10377 10665 10379 3 10667 10379 10665 3 10378 10380 10668 3 10378 10668 10666 3 10379 10667 10381 3 10669 10381 10667 3 10380 10382 10670 3 10380 10670 10668 3 10381 10669 10383 3 10671 10383 10669 3 10382 10384 10672 3 10382 10672 10670 3 10383 10671 10385 3 10673 10385 10671 3 10384 10386 10674 3 10384 10674 10672 3 10385 10673 10387 3 10675 10387 10673 3 10386 10388 10676 3 10386 10676 10674 3 10387 10675 10389 3 10677 10389 10675 3 10388 10390 10678 3 10388 10678 10676 3 10389 10677 10391 3 10679 10391 10677 3 10390 10392 10680 3 10390 10680 10678 3 10391 10679 10393 3 10681 10393 10679 3 10392 10394 10682 3 10392 10682 10680 3 10393 10681 10395 3 10683 10395 10681 3 10394 10396 10684 3 10394 10684 10682 3 10395 10683 10397 3 10685 10397 10683 3 10396 10398 10686 3 10396 10686 10684 3 10397 10685 10399 3 10687 10399 10685 3 10398 10400 10688 3 10398 10688 10686 3 10399 10687 10403 3 10691 10403 10687 3 10400 10401 10689 3 10400 10689 10688 3 10401 10404 10692 3 10401 10692 10689 3 10402 10403 10691 3 10402 10691 10690 3 10402 10690 10407 3 10695 10407 10690 3 10404 10405 10693 3 10404 10693 10692 3 10405 10408 10696 3 10405 10696 10693 3 10406 10407 10695 3 10406 10695 10694 3 10406 10694 10476 3 10764 10476 10694 3 10408 10409 10697 3 10408 10697 10696 3 10409 10410 10697 3 10698 10697 10410 3 10410 10411 10698 3 10699 10698 10411 3 10411 10412 10699 3 10700 10699 10412 3 10412 10413 10700 3 10701 10700 10413 3 10413 10414 10701 3 10702 10701 10414 3 10414 10415 10702 3 10703 10702 10415 3 10415 10416 10703 3 10704 10703 10416 3 10416 10417 10704 3 10705 10704 10417 3 10417 10418 10705 3 10706 10705 10418 3 10418 10419 10706 3 10707 10706 10419 3 10419 10420 10707 3 10708 10707 10420 3 10420 10421 10708 3 10709 10708 10421 3 10421 10422 10709 3 10710 10709 10422 3 10422 10423 10710 3 10711 10710 10423 3 10423 10424 10711 3 10712 10711 10424 3 10424 10425 10712 3 10713 10712 10425 3 10425 10426 10713 3 10714 10713 10426 3 10426 10427 10714 3 10715 10714 10427 3 10427 10428 10715 3 10716 10715 10428 3 10428 10429 10716 3 10717 10716 10429 3 10429 10430 10717 3 10718 10717 10430 3 10430 10431 10718 3 10719 10718 10431 3 10431 10432 10719 3 10720 10719 10432 3 10432 10433 10720 3 10721 10720 10433 3 10433 10434 10721 3 10722 10721 10434 3 10434 10435 10722 3 10723 10722 10435 3 10435 10436 10723 3 10724 10723 10436 3 10436 10437 10724 3 10725 10724 10437 3 10437 10438 10725 3 10726 10725 10438 3 10438 10439 10726 3 10727 10726 10439 3 10439 10440 10727 3 10728 10727 10440 3 10440 10441 10728 3 10729 10728 10441 3 10441 10442 10729 3 10730 10729 10442 3 10442 10443 10730 3 10731 10730 10443 3 10443 10444 10731 3 10732 10731 10444 3 10444 10445 10732 3 10733 10732 10445 3 10445 10446 10733 3 10734 10733 10446 3 10446 10447 10734 3 10735 10734 10447 3 10447 10448 10735 3 10736 10735 10448 3 10448 10449 10736 3 10737 10736 10449 3 10449 10450 10737 3 10738 10737 10450 3 10450 10451 10738 3 10739 10738 10451 3 10451 10452 10739 3 10740 10739 10452 3 10452 10453 10740 3 10741 10740 10453 3 10453 10454 10741 3 10742 10741 10454 3 10454 10455 10742 3 10743 10742 10455 3 10455 10456 10743 3 10744 10743 10456 3 10456 10457 10744 3 10745 10744 10457 3 10457 10458 10745 3 10746 10745 10458 3 10458 10459 10746 3 10747 10746 10459 3 10459 10460 10747 3 10748 10747 10460 3 10460 10461 10748 3 10749 10748 10461 3 10461 10462 10749 3 10750 10749 10462 3 10462 10463 10750 3 10751 10750 10463 3 10463 10464 10751 3 10752 10751 10464 3 10464 10465 10752 3 10753 10752 10465 3 10465 10466 10753 3 10754 10753 10466 3 10466 10467 10754 3 10755 10754 10467 3 10467 10468 10755 3 10756 10755 10468 3 10468 10469 10756 3 10757 10756 10469 3 10469 10470 10757 3 10758 10757 10470 3 10470 10471 10758 3 10759 10758 10471 3 10471 10472 10759 3 10760 10759 10472 3 10472 10473 10761 3 10472 10761 10760 3 10473 10474 10762 3 10473 10762 10761 3 10474 10475 10763 3 10474 10763 10762 3 10475 10476 10764 3 10475 10764 10763 3 10477 10765 10766 3 10477 10766 10478 3 10477 10547 10835 3 10477 10835 10765 3 10478 10766 10767 3 10478 10767 10479 3 10479 10767 10768 3 10479 10768 10480 3 10480 10768 10769 3 10480 10769 10481 3 10481 10769 10770 3 10481 10770 10482 3 10482 10770 10771 3 10482 10771 10483 3 10483 10771 10772 3 10483 10772 10484 3 10484 10772 10773 3 10484 10773 10485 3 10485 10773 10774 3 10485 10774 10486 3 10486 10774 10775 3 10486 10775 10487 3 10487 10775 10776 3 10487 10776 10488 3 10488 10776 10777 3 10488 10777 10489 3 10489 10777 10778 3 10489 10778 10490 3 10490 10778 10779 3 10490 10779 10491 3 10491 10779 10780 3 10491 10780 10492 3 10492 10780 10781 3 10492 10781 10493 3 10493 10781 10782 3 10493 10782 10494 3 10494 10782 10783 3 10494 10783 10495 3 10495 10783 10784 3 10495 10784 10496 3 10496 10784 10785 3 10496 10785 10497 3 10497 10785 10498 3 10786 10498 10785 3 10498 10786 10499 3 10787 10499 10786 3 10499 10787 10500 3 10788 10500 10787 3 10500 10788 10501 3 10789 10501 10788 3 10501 10789 10502 3 10790 10502 10789 3 10502 10790 10503 3 10791 10503 10790 3 10503 10791 10504 3 10792 10504 10791 3 10504 10792 10505 3 10793 10505 10792 3 10505 10793 10506 3 10794 10506 10793 3 10506 10794 10507 3 10795 10507 10794 3 10507 10795 10508 3 10796 10508 10795 3 10508 10796 10509 3 10797 10509 10796 3 10509 10797 10510 3 10798 10510 10797 3 10510 10798 10511 3 10799 10511 10798 3 10511 10799 10512 3 10800 10512 10799 3 10512 10800 10513 3 10801 10513 10800 3 10513 10801 10514 3 10802 10514 10801 3 10514 10802 10515 3 10803 10515 10802 3 10515 10803 10516 3 10804 10516 10803 3 10516 10804 10517 3 10805 10517 10804 3 10517 10805 10518 3 10806 10518 10805 3 10518 10806 10519 3 10807 10519 10806 3 10519 10807 10520 3 10808 10520 10807 3 10520 10808 10521 3 10809 10521 10808 3 10521 10809 10522 3 10810 10522 10809 3 10522 10810 10523 3 10811 10523 10810 3 10523 10811 10524 3 10812 10524 10811 3 10524 10812 10525 3 10813 10525 10812 3 10525 10813 10526 3 10814 10526 10813 3 10526 10814 10527 3 10815 10527 10814 3 10527 10815 10528 3 10816 10528 10815 3 10528 10816 10529 3 10817 10529 10816 3 10529 10817 10530 3 10818 10530 10817 3 10530 10818 10531 3 10819 10531 10818 3 10531 10819 10532 3 10820 10532 10819 3 10532 10820 10533 3 10821 10533 10820 3 10533 10821 10534 3 10822 10534 10821 3 10534 10822 10535 3 10823 10535 10822 3 10535 10823 10536 3 10824 10536 10823 3 10536 10824 10537 3 10825 10537 10824 3 10537 10825 10538 3 10826 10538 10825 3 10538 10826 10539 3 10827 10539 10826 3 10539 10827 10540 3 10828 10540 10827 3 10540 10828 10541 3 10829 10541 10828 3 10541 10829 10542 3 10830 10542 10829 3 10542 10830 10543 3 10831 10543 10830 3 10543 10831 10544 3 10832 10544 10831 3 10544 10832 10545 3 10833 10545 10832 3 10545 10833 10548 3 10836 10548 10833 3 10546 10834 10547 3 10835 10547 10834 3 10546 10551 10834 3 10839 10834 10551 3 10548 10836 10549 3 10837 10549 10836 3 10549 10837 10552 3 10840 10552 10837 3 10550 10838 10551 3 10839 10551 10838 3 10550 10554 10838 3 10842 10838 10554 3 10552 10840 10553 3 10841 10553 10840 3 10553 10841 10555 3 10843 10555 10841 3 10554 10556 10842 3 10844 10842 10556 3 10555 10843 10557 3 10845 10557 10843 3 10556 10558 10844 3 10846 10844 10558 3 10557 10845 10559 3 10847 10559 10845 3 10558 10560 10846 3 10848 10846 10560 3 10559 10847 10561 3 10849 10561 10847 3 10560 10562 10848 3 10850 10848 10562 3 10561 10849 10851 3 10561 10851 10563 3 10562 10564 10850 3 10852 10850 10564 3 10563 10851 10853 3 10563 10853 10565 3 10564 10566 10852 3 10854 10852 10566 3 10565 10853 10855 3 10565 10855 10567 3 10566 10568 10854 3 10856 10854 10568 3 10567 10855 10857 3 10567 10857 10569 3 10568 10570 10856 3 10858 10856 10570 3 10569 10857 10859 3 10569 10859 10571 3 10570 10572 10858 3 10860 10858 10572 3 10571 10859 10861 3 10571 10861 10573 3 10572 10574 10860 3 10862 10860 10574 3 10573 10861 10863 3 10573 10863 10575 3 10574 10576 10862 3 10864 10862 10576 3 10575 10863 10865 3 10575 10865 10577 3 10576 10578 10864 3 10866 10864 10578 3 10577 10865 10867 3 10577 10867 10579 3 10578 10580 10866 3 10868 10866 10580 3 10579 10867 10869 3 10579 10869 10581 3 10580 10582 10868 3 10870 10868 10582 3 10581 10869 10871 3 10581 10871 10583 3 10582 10584 10870 3 10872 10870 10584 3 10583 10871 10873 3 10583 10873 10585 3 10584 10586 10872 3 10874 10872 10586 3 10585 10873 10875 3 10585 10875 10587 3 10586 10588 10874 3 10876 10874 10588 3 10587 10875 10877 3 10587 10877 10589 3 10588 10590 10876 3 10878 10876 10590 3 10589 10877 10879 3 10589 10879 10591 3 10590 10592 10878 3 10880 10878 10592 3 10591 10879 10881 3 10591 10881 10593 3 10592 10594 10880 3 10882 10880 10594 3 10593 10881 10883 3 10593 10883 10595 3 10594 10596 10882 3 10884 10882 10596 3 10595 10883 10885 3 10595 10885 10597 3 10596 10598 10884 3 10886 10884 10598 3 10597 10885 10887 3 10597 10887 10599 3 10598 10600 10888 3 10598 10888 10886 3 10599 10887 10889 3 10599 10889 10601 3 10600 10602 10890 3 10600 10890 10888 3 10601 10889 10891 3 10601 10891 10603 3 10602 10604 10892 3 10602 10892 10890 3 10603 10891 10893 3 10603 10893 10605 3 10604 10606 10894 3 10604 10894 10892 3 10605 10893 10895 3 10605 10895 10607 3 10606 10608 10896 3 10606 10896 10894 3 10607 10895 10897 3 10607 10897 10609 3 10608 10610 10898 3 10608 10898 10896 3 10609 10897 10899 3 10609 10899 10611 3 10610 10612 10900 3 10610 10900 10898 3 10611 10899 10901 3 10611 10901 10613 3 10612 10614 10902 3 10612 10902 10900 3 10613 10901 10903 3 10613 10903 10615 3 10614 10616 10904 3 10614 10904 10902 3 10615 10903 10905 3 10615 10905 10617 3 10616 10618 10906 3 10616 10906 10904 3 10617 10905 10907 3 10617 10907 10619 3 10618 10620 10908 3 10618 10908 10906 3 10619 10907 10909 3 10619 10909 10621 3 10620 10622 10910 3 10620 10910 10908 3 10621 10909 10911 3 10621 10911 10623 3 10622 10624 10912 3 10622 10912 10910 3 10623 10911 10913 3 10623 10913 10625 3 10624 10626 10914 3 10624 10914 10912 3 10625 10913 10627 3 10915 10627 10913 3 10626 10628 10916 3 10626 10916 10914 3 10627 10915 10629 3 10917 10629 10915 3 10628 10630 10918 3 10628 10918 10916 3 10629 10917 10631 3 10919 10631 10917 3 10630 10632 10920 3 10630 10920 10918 3 10631 10919 10633 3 10921 10633 10919 3 10632 10634 10922 3 10632 10922 10920 3 10633 10921 10635 3 10923 10635 10921 3 10634 10636 10924 3 10634 10924 10922 3 10635 10923 10637 3 10925 10637 10923 3 10636 10638 10926 3 10636 10926 10924 3 10637 10925 10639 3 10927 10639 10925 3 10638 10640 10928 3 10638 10928 10926 3 10639 10927 10641 3 10929 10641 10927 3 10640 10642 10930 3 10640 10930 10928 3 10641 10929 10643 3 10931 10643 10929 3 10642 10644 10932 3 10642 10932 10930 3 10643 10931 10645 3 10933 10645 10931 3 10644 10646 10934 3 10644 10934 10932 3 10645 10933 10647 3 10935 10647 10933 3 10646 10648 10936 3 10646 10936 10934 3 10647 10935 10649 3 10937 10649 10935 3 10648 10650 10938 3 10648 10938 10936 3 10649 10937 10651 3 10939 10651 10937 3 10650 10652 10940 3 10650 10940 10938 3 10651 10939 10653 3 10941 10653 10939 3 10652 10654 10942 3 10652 10942 10940 3 10653 10941 10655 3 10943 10655 10941 3 10654 10656 10944 3 10654 10944 10942 3 10655 10943 10657 3 10945 10657 10943 3 10656 10658 10946 3 10656 10946 10944 3 10657 10945 10659 3 10947 10659 10945 3 10658 10660 10948 3 10658 10948 10946 3 10659 10947 10661 3 10949 10661 10947 3 10660 10662 10950 3 10660 10950 10948 3 10661 10949 10663 3 10951 10663 10949 3 10662 10664 10950 3 10952 10950 10664 3 10663 10951 10665 3 10953 10665 10951 3 10664 10666 10952 3 10954 10952 10666 3 10665 10953 10667 3 10955 10667 10953 3 10666 10668 10954 3 10956 10954 10668 3 10667 10955 10669 3 10957 10669 10955 3 10668 10670 10956 3 10958 10956 10670 3 10669 10957 10671 3 10959 10671 10957 3 10670 10672 10958 3 10960 10958 10672 3 10671 10959 10673 3 10961 10673 10959 3 10672 10674 10960 3 10962 10960 10674 3 10673 10961 10675 3 10963 10675 10961 3 10674 10676 10962 3 10964 10962 10676 3 10675 10963 10677 3 10965 10677 10963 3 10676 10678 10964 3 10966 10964 10678 3 10677 10965 10679 3 10967 10679 10965 3 10678 10680 10966 3 10968 10966 10680 3 10679 10967 10681 3 10969 10681 10967 3 10680 10682 10968 3 10970 10968 10682 3 10681 10969 10683 3 10971 10683 10969 3 10682 10684 10970 3 10972 10970 10684 3 10683 10971 10685 3 10973 10685 10971 3 10684 10686 10972 3 10974 10972 10686 3 10685 10973 10687 3 10975 10687 10973 3 10686 10688 10974 3 10976 10974 10688 3 10687 10975 10691 3 10979 10691 10975 3 10688 10689 10976 3 10977 10976 10689 3 10689 10692 10977 3 10980 10977 10692 3 10690 10691 10978 3 10979 10978 10691 3 10690 10978 10983 3 10690 10983 10695 3 10692 10693 10980 3 10981 10980 10693 3 10693 10696 10981 3 10984 10981 10696 3 10694 10695 10982 3 10983 10982 10695 3 10694 10982 11052 3 10694 11052 10764 3 10696 10697 10984 3 10985 10984 10697 3 10697 10698 10985 3 10986 10985 10698 3 10698 10699 10986 3 10987 10986 10699 3 10699 10700 10987 3 10988 10987 10700 3 10700 10701 10988 3 10989 10988 10701 3 10701 10702 10989 3 10990 10989 10702 3 10702 10703 10990 3 10991 10990 10703 3 10703 10704 10991 3 10992 10991 10704 3 10704 10705 10992 3 10993 10992 10705 3 10705 10706 10993 3 10994 10993 10706 3 10706 10707 10994 3 10995 10994 10707 3 10707 10708 10995 3 10996 10995 10708 3 10708 10709 10996 3 10997 10996 10709 3 10709 10710 10997 3 10998 10997 10710 3 10710 10711 10998 3 10999 10998 10711 3 10711 10712 10999 3 11000 10999 10712 3 10712 10713 11000 3 11001 11000 10713 3 10713 10714 11001 3 11002 11001 10714 3 10714 10715 11002 3 11003 11002 10715 3 10715 10716 11003 3 11004 11003 10716 3 10716 10717 11004 3 11005 11004 10717 3 10717 10718 11005 3 11006 11005 10718 3 10718 10719 11006 3 11007 11006 10719 3 10719 10720 11007 3 11008 11007 10720 3 10720 10721 11008 3 11009 11008 10721 3 10721 10722 11009 3 11010 11009 10722 3 10722 10723 11010 3 11011 11010 10723 3 10723 10724 11011 3 11012 11011 10724 3 10724 10725 11012 3 11013 11012 10725 3 10725 10726 11014 3 10725 11014 11013 3 10726 10727 11015 3 10726 11015 11014 3 10727 10728 11016 3 10727 11016 11015 3 10728 10729 11017 3 10728 11017 11016 3 10729 10730 11018 3 10729 11018 11017 3 10730 10731 11019 3 10730 11019 11018 3 10731 10732 11020 3 10731 11020 11019 3 10732 10733 11021 3 10732 11021 11020 3 10733 10734 11022 3 10733 11022 11021 3 10734 10735 11023 3 10734 11023 11022 3 10735 10736 11024 3 10735 11024 11023 3 10736 10737 11025 3 10736 11025 11024 3 10737 10738 11026 3 10737 11026 11025 3 10738 10739 11027 3 10738 11027 11026 3 10739 10740 11028 3 10739 11028 11027 3 10740 10741 11029 3 10740 11029 11028 3 10741 10742 11030 3 10741 11030 11029 3 10742 10743 11031 3 10742 11031 11030 3 10743 10744 11032 3 10743 11032 11031 3 10744 10745 11033 3 10744 11033 11032 3 10745 10746 11034 3 10745 11034 11033 3 10746 10747 11035 3 10746 11035 11034 3 10747 10748 11036 3 10747 11036 11035 3 10748 10749 11037 3 10748 11037 11036 3 10749 10750 11038 3 10749 11038 11037 3 10750 10751 11039 3 10750 11039 11038 3 10751 10752 11040 3 10751 11040 11039 3 10752 10753 11041 3 10752 11041 11040 3 10753 10754 11042 3 10753 11042 11041 3 10754 10755 11043 3 10754 11043 11042 3 10755 10756 11044 3 10755 11044 11043 3 10756 10757 11045 3 10756 11045 11044 3 10757 10758 11046 3 10757 11046 11045 3 10758 10759 11047 3 10758 11047 11046 3 10759 10760 11048 3 10759 11048 11047 3 10760 10761 11049 3 10760 11049 11048 3 10761 10762 11050 3 10761 11050 11049 3 10762 10763 11051 3 10762 11051 11050 3 10763 10764 11052 3 10763 11052 11051 3 10765 11053 10766 3 11054 10766 11053 3 10765 10835 11053 3 11123 11053 10835 3 10766 11054 10767 3 11055 10767 11054 3 10767 11055 10768 3 11056 10768 11055 3 10768 11056 10769 3 11057 10769 11056 3 10769 11057 10770 3 11058 10770 11057 3 10770 11058 10771 3 11059 10771 11058 3 10771 11059 10772 3 11060 10772 11059 3 10772 11060 10773 3 11061 10773 11060 3 10773 11061 10774 3 11062 10774 11061 3 10774 11062 10775 3 11063 10775 11062 3 10775 11063 10776 3 11064 10776 11063 3 10776 11064 10777 3 11065 10777 11064 3 10777 11065 10778 3 11066 10778 11065 3 10778 11066 10779 3 11067 10779 11066 3 10779 11067 10780 3 11068 10780 11067 3 10780 11068 10781 3 11069 10781 11068 3 10781 11069 10782 3 11070 10782 11069 3 10782 11070 10783 3 11071 10783 11070 3 10783 11071 10784 3 11072 10784 11071 3 10784 11072 10785 3 11073 10785 11072 3 10785 11073 10786 3 11074 10786 11073 3 10786 11074 10787 3 11075 10787 11074 3 10787 11075 10788 3 11076 10788 11075 3 10788 11076 10789 3 11077 10789 11076 3 10789 11077 10790 3 11078 10790 11077 3 10790 11078 10791 3 11079 10791 11078 3 10791 11079 10792 3 11080 10792 11079 3 10792 11080 10793 3 11081 10793 11080 3 10793 11081 10794 3 11082 10794 11081 3 10794 11082 10795 3 11083 10795 11082 3 10795 11083 10796 3 11084 10796 11083 3 10796 11084 10797 3 11085 10797 11084 3 10797 11085 10798 3 11086 10798 11085 3 10798 11086 10799 3 11087 10799 11086 3 10799 11087 10800 3 11088 10800 11087 3 10800 11088 10801 3 11089 10801 11088 3 10801 11089 10802 3 11090 10802 11089 3 10802 11090 10803 3 11091 10803 11090 3 10803 11091 10804 3 11092 10804 11091 3 10804 11092 10805 3 11093 10805 11092 3 10805 11093 10806 3 11094 10806 11093 3 10806 11094 10807 3 11095 10807 11094 3 10807 11095 10808 3 11096 10808 11095 3 10808 11096 10809 3 11097 10809 11096 3 10809 11097 10810 3 11098 10810 11097 3 10810 11098 10811 3 11099 10811 11098 3 10811 11099 10812 3 11100 10812 11099 3 10812 11100 10813 3 11101 10813 11100 3 10813 11101 10814 3 11102 10814 11101 3 10814 11102 10815 3 11103 10815 11102 3 10815 11103 10816 3 11104 10816 11103 3 10816 11104 10817 3 11105 10817 11104 3 10817 11105 11106 3 10817 11106 10818 3 10818 11106 11107 3 10818 11107 10819 3 10819 11107 11108 3 10819 11108 10820 3 10820 11108 11109 3 10820 11109 10821 3 10821 11109 11110 3 10821 11110 10822 3 10822 11110 11111 3 10822 11111 10823 3 10823 11111 11112 3 10823 11112 10824 3 10824 11112 11113 3 10824 11113 10825 3 10825 11113 11114 3 10825 11114 10826 3 10826 11114 11115 3 10826 11115 10827 3 10827 11115 11116 3 10827 11116 10828 3 10828 11116 11117 3 10828 11117 10829 3 10829 11117 11118 3 10829 11118 10830 3 10830 11118 11119 3 10830 11119 10831 3 10831 11119 11120 3 10831 11120 10832 3 10832 11120 11121 3 10832 11121 10833 3 10833 11121 11124 3 10833 11124 10836 3 10834 11122 11123 3 10834 11123 10835 3 10834 10839 11122 3 11127 11122 10839 3 10836 11124 11125 3 10836 11125 10837 3 10837 11125 11128 3 10837 11128 10840 3 10838 11126 11127 3 10838 11127 10839 3 10838 10842 11126 3 11130 11126 10842 3 10840 11128 11129 3 10840 11129 10841 3 10841 11129 11131 3 10841 11131 10843 3 10842 10844 11130 3 11132 11130 10844 3 10843 11131 11133 3 10843 11133 10845 3 10844 10846 11132 3 11134 11132 10846 3 10845 11133 11135 3 10845 11135 10847 3 10846 10848 11134 3 11136 11134 10848 3 10847 11135 11137 3 10847 11137 10849 3 10848 10850 11136 3 11138 11136 10850 3 10849 11137 11139 3 10849 11139 10851 3 10850 10852 11138 3 11140 11138 10852 3 10851 11139 11141 3 10851 11141 10853 3 10852 10854 11142 3 10852 11142 11140 3 10853 11141 11143 3 10853 11143 10855 3 10854 10856 11144 3 10854 11144 11142 3 10855 11143 11145 3 10855 11145 10857 3 10856 10858 11146 3 10856 11146 11144 3 10857 11145 11147 3 10857 11147 10859 3 10858 10860 11148 3 10858 11148 11146 3 10859 11147 11149 3 10859 11149 10861 3 10860 10862 11150 3 10860 11150 11148 3 10861 11149 11151 3 10861 11151 10863 3 10862 10864 11152 3 10862 11152 11150 3 10863 11151 11153 3 10863 11153 10865 3 10864 10866 11154 3 10864 11154 11152 3 10865 11153 11155 3 10865 11155 10867 3 10866 10868 11156 3 10866 11156 11154 3 10867 11155 11157 3 10867 11157 10869 3 10868 10870 11158 3 10868 11158 11156 3 10869 11157 11159 3 10869 11159 10871 3 10870 10872 11160 3 10870 11160 11158 3 10871 11159 11161 3 10871 11161 10873 3 10872 10874 11162 3 10872 11162 11160 3 10873 11161 11163 3 10873 11163 10875 3 10874 10876 11164 3 10874 11164 11162 3 10875 11163 11165 3 10875 11165 10877 3 10876 10878 11166 3 10876 11166 11164 3 10877 11165 11167 3 10877 11167 10879 3 10878 10880 11168 3 10878 11168 11166 3 10879 11167 11169 3 10879 11169 10881 3 10880 10882 11170 3 10880 11170 11168 3 10881 11169 11171 3 10881 11171 10883 3 10882 10884 11172 3 10882 11172 11170 3 10883 11171 10885 3 11173 10885 11171 3 10884 10886 11174 3 10884 11174 11172 3 10885 11173 10887 3 11175 10887 11173 3 10886 10888 11176 3 10886 11176 11174 3 10887 11175 10889 3 11177 10889 11175 3 10888 10890 11178 3 10888 11178 11176 3 10889 11177 10891 3 11179 10891 11177 3 10890 10892 11180 3 10890 11180 11178 3 10891 11179 10893 3 11181 10893 11179 3 10892 10894 11182 3 10892 11182 11180 3 10893 11181 10895 3 11183 10895 11181 3 10894 10896 11184 3 10894 11184 11182 3 10895 11183 10897 3 11185 10897 11183 3 10896 10898 11186 3 10896 11186 11184 3 10897 11185 10899 3 11187 10899 11185 3 10898 10900 11188 3 10898 11188 11186 3 10899 11187 10901 3 11189 10901 11187 3 10900 10902 11190 3 10900 11190 11188 3 10901 11189 10903 3 11191 10903 11189 3 10902 10904 11192 3 10902 11192 11190 3 10903 11191 10905 3 11193 10905 11191 3 10904 10906 11194 3 10904 11194 11192 3 10905 11193 10907 3 11195 10907 11193 3 10906 10908 11196 3 10906 11196 11194 3 10907 11195 10909 3 11197 10909 11195 3 10908 10910 11198 3 10908 11198 11196 3 10909 11197 10911 3 11199 10911 11197 3 10910 10912 11200 3 10910 11200 11198 3 10911 11199 10913 3 11201 10913 11199 3 10912 10914 11202 3 10912 11202 11200 3 10913 11201 10915 3 11203 10915 11201 3 10914 10916 11204 3 10914 11204 11202 3 10915 11203 10917 3 11205 10917 11203 3 10916 10918 11206 3 10916 11206 11204 3 10917 11205 10919 3 11207 10919 11205 3 10918 10920 11206 3 11208 11206 10920 3 10919 11207 10921 3 11209 10921 11207 3 10920 10922 11208 3 11210 11208 10922 3 10921 11209 10923 3 11211 10923 11209 3 10922 10924 11210 3 11212 11210 10924 3 10923 11211 10925 3 11213 10925 11211 3 10924 10926 11212 3 11214 11212 10926 3 10925 11213 10927 3 11215 10927 11213 3 10926 10928 11214 3 11216 11214 10928 3 10927 11215 10929 3 11217 10929 11215 3 10928 10930 11216 3 11218 11216 10930 3 10929 11217 10931 3 11219 10931 11217 3 10930 10932 11218 3 11220 11218 10932 3 10931 11219 10933 3 11221 10933 11219 3 10932 10934 11220 3 11222 11220 10934 3 10933 11221 10935 3 11223 10935 11221 3 10934 10936 11222 3 11224 11222 10936 3 10935 11223 10937 3 11225 10937 11223 3 10936 10938 11224 3 11226 11224 10938 3 10937 11225 10939 3 11227 10939 11225 3 10938 10940 11226 3 11228 11226 10940 3 10939 11227 10941 3 11229 10941 11227 3 10940 10942 11228 3 11230 11228 10942 3 10941 11229 10943 3 11231 10943 11229 3 10942 10944 11230 3 11232 11230 10944 3 10943 11231 10945 3 11233 10945 11231 3 10944 10946 11232 3 11234 11232 10946 3 10945 11233 10947 3 11235 10947 11233 3 10946 10948 11234 3 11236 11234 10948 3 10947 11235 11237 3 10947 11237 10949 3 10948 10950 11236 3 11238 11236 10950 3 10949 11237 11239 3 10949 11239 10951 3 10950 10952 11238 3 11240 11238 10952 3 10951 11239 11241 3 10951 11241 10953 3 10952 10954 11240 3 11242 11240 10954 3 10953 11241 11243 3 10953 11243 10955 3 10954 10956 11242 3 11244 11242 10956 3 10955 11243 11245 3 10955 11245 10957 3 10956 10958 11244 3 11246 11244 10958 3 10957 11245 11247 3 10957 11247 10959 3 10958 10960 11246 3 11248 11246 10960 3 10959 11247 11249 3 10959 11249 10961 3 10960 10962 11248 3 11250 11248 10962 3 10961 11249 11251 3 10961 11251 10963 3 10962 10964 11250 3 11252 11250 10964 3 10963 11251 11253 3 10963 11253 10965 3 10964 10966 11252 3 11254 11252 10966 3 10965 11253 11255 3 10965 11255 10967 3 10966 10968 11254 3 11256 11254 10968 3 10967 11255 11257 3 10967 11257 10969 3 10968 10970 11256 3 11258 11256 10970 3 10969 11257 11259 3 10969 11259 10971 3 10970 10972 11258 3 11260 11258 10972 3 10971 11259 11261 3 10971 11261 10973 3 10972 10974 11260 3 11262 11260 10974 3 10973 11261 11263 3 10973 11263 10975 3 10974 10976 11262 3 11264 11262 10976 3 10975 11263 11267 3 10975 11267 10979 3 10976 10977 11264 3 11265 11264 10977 3 10977 10980 11265 3 11268 11265 10980 3 10978 10979 11266 3 11267 11266 10979 3 10978 11266 11271 3 10978 11271 10983 3 10980 10981 11268 3 11269 11268 10981 3 10981 10984 11272 3 10981 11272 11269 3 10982 10983 11271 3 10982 11271 11270 3 10982 11270 11340 3 10982 11340 11052 3 10984 10985 11273 3 10984 11273 11272 3 10985 10986 11274 3 10985 11274 11273 3 10986 10987 11275 3 10986 11275 11274 3 10987 10988 11276 3 10987 11276 11275 3 10988 10989 11277 3 10988 11277 11276 3 10989 10990 11278 3 10989 11278 11277 3 10990 10991 11279 3 10990 11279 11278 3 10991 10992 11280 3 10991 11280 11279 3 10992 10993 11281 3 10992 11281 11280 3 10993 10994 11282 3 10993 11282 11281 3 10994 10995 11283 3 10994 11283 11282 3 10995 10996 11284 3 10995 11284 11283 3 10996 10997 11285 3 10996 11285 11284 3 10997 10998 11286 3 10997 11286 11285 3 10998 10999 11287 3 10998 11287 11286 3 10999 11000 11288 3 10999 11288 11287 3 11000 11001 11289 3 11000 11289 11288 3 11001 11002 11290 3 11001 11290 11289 3 11002 11003 11291 3 11002 11291 11290 3 11003 11004 11292 3 11003 11292 11291 3 11004 11005 11293 3 11004 11293 11292 3 11005 11006 11294 3 11005 11294 11293 3 11006 11007 11295 3 11006 11295 11294 3 11007 11008 11296 3 11007 11296 11295 3 11008 11009 11297 3 11008 11297 11296 3 11009 11010 11298 3 11009 11298 11297 3 11010 11011 11299 3 11010 11299 11298 3 11011 11012 11300 3 11011 11300 11299 3 11012 11013 11301 3 11012 11301 11300 3 11013 11014 11302 3 11013 11302 11301 3 11014 11015 11303 3 11014 11303 11302 3 11015 11016 11304 3 11015 11304 11303 3 11016 11017 11305 3 11016 11305 11304 3 11017 11018 11306 3 11017 11306 11305 3 11018 11019 11307 3 11018 11307 11306 3 11019 11020 11308 3 11019 11308 11307 3 11020 11021 11309 3 11020 11309 11308 3 11021 11022 11310 3 11021 11310 11309 3 11022 11023 11311 3 11022 11311 11310 3 11023 11024 11312 3 11023 11312 11311 3 11024 11025 11313 3 11024 11313 11312 3 11025 11026 11314 3 11025 11314 11313 3 11026 11027 11315 3 11026 11315 11314 3 11027 11028 11316 3 11027 11316 11315 3 11028 11029 11317 3 11028 11317 11316 3 11029 11030 11318 3 11029 11318 11317 3 11030 11031 11319 3 11030 11319 11318 3 11031 11032 11320 3 11031 11320 11319 3 11032 11033 11321 3 11032 11321 11320 3 11033 11034 11322 3 11033 11322 11321 3 11034 11035 11323 3 11034 11323 11322 3 11035 11036 11324 3 11035 11324 11323 3 11036 11037 11325 3 11036 11325 11324 3 11037 11038 11326 3 11037 11326 11325 3 11038 11039 11327 3 11038 11327 11326 3 11039 11040 11328 3 11039 11328 11327 3 11040 11041 11329 3 11040 11329 11328 3 11041 11042 11330 3 11041 11330 11329 3 11042 11043 11331 3 11042 11331 11330 3 11043 11044 11332 3 11043 11332 11331 3 11044 11045 11333 3 11044 11333 11332 3 11045 11046 11334 3 11045 11334 11333 3 11046 11047 11334 3 11335 11334 11047 3 11047 11048 11335 3 11336 11335 11048 3 11048 11049 11336 3 11337 11336 11049 3 11049 11050 11337 3 11338 11337 11050 3 11050 11051 11338 3 11339 11338 11051 3 11051 11052 11339 3 11340 11339 11052 3 11053 11341 11054 3 11342 11054 11341 3 11053 11123 11341 3 11411 11341 11123 3 11054 11342 11055 3 11343 11055 11342 3 11055 11343 11056 3 11344 11056 11343 3 11056 11344 11057 3 11345 11057 11344 3 11057 11345 11058 3 11346 11058 11345 3 11058 11346 11059 3 11347 11059 11346 3 11059 11347 11060 3 11348 11060 11347 3 11060 11348 11061 3 11349 11061 11348 3 11061 11349 11062 3 11350 11062 11349 3 11062 11350 11063 3 11351 11063 11350 3 11063 11351 11064 3 11352 11064 11351 3 11064 11352 11065 3 11353 11065 11352 3 11065 11353 11066 3 11354 11066 11353 3 11066 11354 11067 3 11355 11067 11354 3 11067 11355 11068 3 11356 11068 11355 3 11068 11356 11069 3 11357 11069 11356 3 11069 11357 11070 3 11358 11070 11357 3 11070 11358 11071 3 11359 11071 11358 3 11071 11359 11072 3 11360 11072 11359 3 11072 11360 11073 3 11361 11073 11360 3 11073 11361 11074 3 11362 11074 11361 3 11074 11362 11075 3 11363 11075 11362 3 11075 11363 11076 3 11364 11076 11363 3 11076 11364 11365 3 11076 11365 11077 3 11077 11365 11366 3 11077 11366 11078 3 11078 11366 11367 3 11078 11367 11079 3 11079 11367 11368 3 11079 11368 11080 3 11080 11368 11369 3 11080 11369 11081 3 11081 11369 11370 3 11081 11370 11082 3 11082 11370 11371 3 11082 11371 11083 3 11083 11371 11372 3 11083 11372 11084 3 11084 11372 11373 3 11084 11373 11085 3 11085 11373 11374 3 11085 11374 11086 3 11086 11374 11375 3 11086 11375 11087 3 11087 11375 11376 3 11087 11376 11088 3 11088 11376 11377 3 11088 11377 11089 3 11089 11377 11378 3 11089 11378 11090 3 11090 11378 11379 3 11090 11379 11091 3 11091 11379 11380 3 11091 11380 11092 3 11092 11380 11381 3 11092 11381 11093 3 11093 11381 11382 3 11093 11382 11094 3 11094 11382 11383 3 11094 11383 11095 3 11095 11383 11384 3 11095 11384 11096 3 11096 11384 11385 3 11096 11385 11097 3 11097 11385 11386 3 11097 11386 11098 3 11098 11386 11387 3 11098 11387 11099 3 11099 11387 11388 3 11099 11388 11100 3 11100 11388 11389 3 11100 11389 11101 3 11101 11389 11390 3 11101 11390 11102 3 11102 11390 11391 3 11102 11391 11103 3 11103 11391 11392 3 11103 11392 11104 3 11104 11392 11393 3 11104 11393 11105 3 11105 11393 11394 3 11105 11394 11106 3 11106 11394 11395 3 11106 11395 11107 3 11107 11395 11396 3 11107 11396 11108 3 11108 11396 11397 3 11108 11397 11109 3 11109 11397 11398 3 11109 11398 11110 3 11110 11398 11399 3 11110 11399 11111 3 11111 11399 11400 3 11111 11400 11112 3 11112 11400 11401 3 11112 11401 11113 3 11113 11401 11402 3 11113 11402 11114 3 11114 11402 11403 3 11114 11403 11115 3 11115 11403 11404 3 11115 11404 11116 3 11116 11404 11405 3 11116 11405 11117 3 11117 11405 11406 3 11117 11406 11118 3 11118 11406 11407 3 11118 11407 11119 3 11119 11407 11408 3 11119 11408 11120 3 11120 11408 11409 3 11120 11409 11121 3 11121 11409 11412 3 11121 11412 11124 3 11122 11410 11411 3 11122 11411 11123 3 11122 11127 11415 3 11122 11415 11410 3 11124 11412 11413 3 11124 11413 11125 3 11125 11413 11416 3 11125 11416 11128 3 11126 11414 11415 3 11126 11415 11127 3 11126 11130 11418 3 11126 11418 11414 3 11128 11416 11417 3 11128 11417 11129 3 11129 11417 11419 3 11129 11419 11131 3 11130 11132 11420 3 11130 11420 11418 3 11131 11419 11421 3 11131 11421 11133 3 11132 11134 11422 3 11132 11422 11420 3 11133 11421 11423 3 11133 11423 11135 3 11134 11136 11424 3 11134 11424 11422 3 11135 11423 11425 3 11135 11425 11137 3 11136 11138 11426 3 11136 11426 11424 3 11137 11425 11427 3 11137 11427 11139 3 11138 11140 11428 3 11138 11428 11426 3 11139 11427 11429 3 11139 11429 11141 3 11140 11142 11430 3 11140 11430 11428 3 11141 11429 11431 3 11141 11431 11143 3 11142 11144 11432 3 11142 11432 11430 3 11143 11431 11145 3 11433 11145 11431 3 11144 11146 11434 3 11144 11434 11432 3 11145 11433 11147 3 11435 11147 11433 3 11146 11148 11436 3 11146 11436 11434 3 11147 11435 11149 3 11437 11149 11435 3 11148 11150 11438 3 11148 11438 11436 3 11149 11437 11151 3 11439 11151 11437 3 11150 11152 11440 3 11150 11440 11438 3 11151 11439 11153 3 11441 11153 11439 3 11152 11154 11442 3 11152 11442 11440 3 11153 11441 11155 3 11443 11155 11441 3 11154 11156 11444 3 11154 11444 11442 3 11155 11443 11157 3 11445 11157 11443 3 11156 11158 11446 3 11156 11446 11444 3 11157 11445 11159 3 11447 11159 11445 3 11158 11160 11448 3 11158 11448 11446 3 11159 11447 11161 3 11449 11161 11447 3 11160 11162 11450 3 11160 11450 11448 3 11161 11449 11163 3 11451 11163 11449 3 11162 11164 11452 3 11162 11452 11450 3 11163 11451 11165 3 11453 11165 11451 3 11164 11166 11454 3 11164 11454 11452 3 11165 11453 11167 3 11455 11167 11453 3 11166 11168 11456 3 11166 11456 11454 3 11167 11455 11169 3 11457 11169 11455 3 11168 11170 11458 3 11168 11458 11456 3 11169 11457 11171 3 11459 11171 11457 3 11170 11172 11460 3 11170 11460 11458 3 11171 11459 11173 3 11461 11173 11459 3 11172 11174 11462 3 11172 11462 11460 3 11173 11461 11175 3 11463 11175 11461 3 11174 11176 11464 3 11174 11464 11462 3 11175 11463 11177 3 11465 11177 11463 3 11176 11178 11464 3 11466 11464 11178 3 11177 11465 11179 3 11467 11179 11465 3 11178 11180 11466 3 11468 11466 11180 3 11179 11467 11181 3 11469 11181 11467 3 11180 11182 11468 3 11470 11468 11182 3 11181 11469 11183 3 11471 11183 11469 3 11182 11184 11470 3 11472 11470 11184 3 11183 11471 11185 3 11473 11185 11471 3 11184 11186 11472 3 11474 11472 11186 3 11185 11473 11187 3 11475 11187 11473 3 11186 11188 11474 3 11476 11474 11188 3 11187 11475 11189 3 11477 11189 11475 3 11188 11190 11476 3 11478 11476 11190 3 11189 11477 11191 3 11479 11191 11477 3 11190 11192 11478 3 11480 11478 11192 3 11191 11479 11193 3 11481 11193 11479 3 11192 11194 11480 3 11482 11480 11194 3 11193 11481 11195 3 11483 11195 11481 3 11194 11196 11482 3 11484 11482 11196 3 11195 11483 11197 3 11485 11197 11483 3 11196 11198 11484 3 11486 11484 11198 3 11197 11485 11199 3 11487 11199 11485 3 11198 11200 11486 3 11488 11486 11200 3 11199 11487 11201 3 11489 11201 11487 3 11200 11202 11488 3 11490 11488 11202 3 11201 11489 11203 3 11491 11203 11489 3 11202 11204 11490 3 11492 11490 11204 3 11203 11491 11205 3 11493 11205 11491 3 11204 11206 11492 3 11494 11492 11206 3 11205 11493 11207 3 11495 11207 11493 3 11206 11208 11494 3 11496 11494 11208 3 11207 11495 11497 3 11207 11497 11209 3 11208 11210 11496 3 11498 11496 11210 3 11209 11497 11499 3 11209 11499 11211 3 11210 11212 11498 3 11500 11498 11212 3 11211 11499 11501 3 11211 11501 11213 3 11212 11214 11500 3 11502 11500 11214 3 11213 11501 11503 3 11213 11503 11215 3 11214 11216 11502 3 11504 11502 11216 3 11215 11503 11505 3 11215 11505 11217 3 11216 11218 11504 3 11506 11504 11218 3 11217 11505 11507 3 11217 11507 11219 3 11218 11220 11506 3 11508 11506 11220 3 11219 11507 11509 3 11219 11509 11221 3 11220 11222 11508 3 11510 11508 11222 3 11221 11509 11511 3 11221 11511 11223 3 11222 11224 11510 3 11512 11510 11224 3 11223 11511 11513 3 11223 11513 11225 3 11224 11226 11512 3 11514 11512 11226 3 11225 11513 11515 3 11225 11515 11227 3 11226 11228 11514 3 11516 11514 11228 3 11227 11515 11517 3 11227 11517 11229 3 11228 11230 11516 3 11518 11516 11230 3 11229 11517 11519 3 11229 11519 11231 3 11230 11232 11518 3 11520 11518 11232 3 11231 11519 11521 3 11231 11521 11233 3 11232 11234 11520 3 11522 11520 11234 3 11233 11521 11523 3 11233 11523 11235 3 11234 11236 11522 3 11524 11522 11236 3 11235 11523 11525 3 11235 11525 11237 3 11236 11238 11524 3 11526 11524 11238 3 11237 11525 11527 3 11237 11527 11239 3 11238 11240 11526 3 11528 11526 11240 3 11239 11527 11529 3 11239 11529 11241 3 11240 11242 11528 3 11530 11528 11242 3 11241 11529 11531 3 11241 11531 11243 3 11242 11244 11532 3 11242 11532 11530 3 11243 11531 11533 3 11243 11533 11245 3 11244 11246 11534 3 11244 11534 11532 3 11245 11533 11535 3 11245 11535 11247 3 11246 11248 11536 3 11246 11536 11534 3 11247 11535 11537 3 11247 11537 11249 3 11248 11250 11538 3 11248 11538 11536 3 11249 11537 11539 3 11249 11539 11251 3 11250 11252 11540 3 11250 11540 11538 3 11251 11539 11541 3 11251 11541 11253 3 11252 11254 11542 3 11252 11542 11540 3 11253 11541 11543 3 11253 11543 11255 3 11254 11256 11544 3 11254 11544 11542 3 11255 11543 11545 3 11255 11545 11257 3 11256 11258 11546 3 11256 11546 11544 3 11257 11545 11547 3 11257 11547 11259 3 11258 11260 11548 3 11258 11548 11546 3 11259 11547 11549 3 11259 11549 11261 3 11260 11262 11550 3 11260 11550 11548 3 11261 11549 11551 3 11261 11551 11263 3 11262 11264 11552 3 11262 11552 11550 3 11263 11551 11555 3 11263 11555 11267 3 11264 11265 11553 3 11264 11553 11552 3 11265 11268 11556 3 11265 11556 11553 3 11266 11267 11555 3 11266 11555 11554 3 11266 11554 11559 3 11266 11559 11271 3 11268 11269 11557 3 11268 11557 11556 3 11269 11272 11560 3 11269 11560 11557 3 11270 11271 11559 3 11270 11559 11558 3 11270 11558 11628 3 11270 11628 11340 3 11272 11273 11561 3 11272 11561 11560 3 11273 11274 11562 3 11273 11562 11561 3 11274 11275 11563 3 11274 11563 11562 3 11275 11276 11564 3 11275 11564 11563 3 11276 11277 11565 3 11276 11565 11564 3 11277 11278 11566 3 11277 11566 11565 3 11278 11279 11567 3 11278 11567 11566 3 11279 11280 11568 3 11279 11568 11567 3 11280 11281 11569 3 11280 11569 11568 3 11281 11282 11570 3 11281 11570 11569 3 11282 11283 11571 3 11282 11571 11570 3 11283 11284 11572 3 11283 11572 11571 3 11284 11285 11573 3 11284 11573 11572 3 11285 11286 11574 3 11285 11574 11573 3 11286 11287 11575 3 11286 11575 11574 3 11287 11288 11576 3 11287 11576 11575 3 11288 11289 11577 3 11288 11577 11576 3 11289 11290 11578 3 11289 11578 11577 3 11290 11291 11579 3 11290 11579 11578 3 11291 11292 11580 3 11291 11580 11579 3 11292 11293 11581 3 11292 11581 11580 3 11293 11294 11582 3 11293 11582 11581 3 11294 11295 11583 3 11294 11583 11582 3 11295 11296 11584 3 11295 11584 11583 3 11296 11297 11585 3 11296 11585 11584 3 11297 11298 11586 3 11297 11586 11585 3 11298 11299 11587 3 11298 11587 11586 3 11299 11300 11588 3 11299 11588 11587 3 11300 11301 11589 3 11300 11589 11588 3 11301 11302 11590 3 11301 11590 11589 3 11302 11303 11591 3 11302 11591 11590 3 11303 11304 11592 3 11303 11592 11591 3 11304 11305 11593 3 11304 11593 11592 3 11305 11306 11594 3 11305 11594 11593 3 11306 11307 11595 3 11306 11595 11594 3 11307 11308 11595 3 11596 11595 11308 3 11308 11309 11596 3 11597 11596 11309 3 11309 11310 11597 3 11598 11597 11310 3 11310 11311 11598 3 11599 11598 11311 3 11311 11312 11599 3 11600 11599 11312 3 11312 11313 11600 3 11601 11600 11313 3 11313 11314 11601 3 11602 11601 11314 3 11314 11315 11602 3 11603 11602 11315 3 11315 11316 11603 3 11604 11603 11316 3 11316 11317 11604 3 11605 11604 11317 3 11317 11318 11605 3 11606 11605 11318 3 11318 11319 11606 3 11607 11606 11319 3 11319 11320 11607 3 11608 11607 11320 3 11320 11321 11608 3 11609 11608 11321 3 11321 11322 11609 3 11610 11609 11322 3 11322 11323 11610 3 11611 11610 11323 3 11323 11324 11611 3 11612 11611 11324 3 11324 11325 11612 3 11613 11612 11325 3 11325 11326 11613 3 11614 11613 11326 3 11326 11327 11614 3 11615 11614 11327 3 11327 11328 11615 3 11616 11615 11328 3 11328 11329 11616 3 11617 11616 11329 3 11329 11330 11617 3 11618 11617 11330 3 11330 11331 11618 3 11619 11618 11331 3 11331 11332 11619 3 11620 11619 11332 3 11332 11333 11620 3 11621 11620 11333 3 11333 11334 11621 3 11622 11621 11334 3 11334 11335 11622 3 11623 11622 11335 3 11335 11336 11623 3 11624 11623 11336 3 11336 11337 11624 3 11625 11624 11337 3 11337 11338 11625 3 11626 11625 11338 3 11338 11339 11626 3 11627 11626 11339 3 11339 11340 11627 3 11628 11627 11340 3 11341 11629 11630 3 11341 11630 11342 3 11341 11411 11699 3 11341 11699 11629 3 11342 11630 11631 3 11342 11631 11343 3 11343 11631 11632 3 11343 11632 11344 3 11344 11632 11633 3 11344 11633 11345 3 11345 11633 11634 3 11345 11634 11346 3 11346 11634 11635 3 11346 11635 11347 3 11347 11635 11636 3 11347 11636 11348 3 11348 11636 11637 3 11348 11637 11349 3 11349 11637 11638 3 11349 11638 11350 3 11350 11638 11639 3 11350 11639 11351 3 11351 11639 11640 3 11351 11640 11352 3 11352 11640 11641 3 11352 11641 11353 3 11353 11641 11642 3 11353 11642 11354 3 11354 11642 11643 3 11354 11643 11355 3 11355 11643 11644 3 11355 11644 11356 3 11356 11644 11645 3 11356 11645 11357 3 11357 11645 11646 3 11357 11646 11358 3 11358 11646 11647 3 11358 11647 11359 3 11359 11647 11648 3 11359 11648 11360 3 11360 11648 11649 3 11360 11649 11361 3 11361 11649 11650 3 11361 11650 11362 3 11362 11650 11651 3 11362 11651 11363 3 11363 11651 11652 3 11363 11652 11364 3 11364 11652 11653 3 11364 11653 11365 3 11365 11653 11654 3 11365 11654 11366 3 11366 11654 11655 3 11366 11655 11367 3 11367 11655 11656 3 11367 11656 11368 3 11368 11656 11657 3 11368 11657 11369 3 11369 11657 11658 3 11369 11658 11370 3 11370 11658 11659 3 11370 11659 11371 3 11371 11659 11660 3 11371 11660 11372 3 11372 11660 11661 3 11372 11661 11373 3 11373 11661 11662 3 11373 11662 11374 3 11374 11662 11663 3 11374 11663 11375 3 11375 11663 11664 3 11375 11664 11376 3 11376 11664 11665 3 11376 11665 11377 3 11377 11665 11666 3 11377 11666 11378 3 11378 11666 11667 3 11378 11667 11379 3 11379 11667 11668 3 11379 11668 11380 3 11380 11668 11669 3 11380 11669 11381 3 11381 11669 11670 3 11381 11670 11382 3 11382 11670 11671 3 11382 11671 11383 3 11383 11671 11672 3 11383 11672 11384 3 11384 11672 11673 3 11384 11673 11385 3 11385 11673 11674 3 11385 11674 11386 3 11386 11674 11675 3 11386 11675 11387 3 11387 11675 11676 3 11387 11676 11388 3 11388 11676 11677 3 11388 11677 11389 3 11389 11677 11678 3 11389 11678 11390 3 11390 11678 11679 3 11390 11679 11391 3 11391 11679 11680 3 11391 11680 11392 3 11392 11680 11681 3 11392 11681 11393 3 11393 11681 11682 3 11393 11682 11394 3 11394 11682 11683 3 11394 11683 11395 3 11395 11683 11684 3 11395 11684 11396 3 11396 11684 11685 3 11396 11685 11397 3 11397 11685 11686 3 11397 11686 11398 3 11398 11686 11687 3 11398 11687 11399 3 11399 11687 11688 3 11399 11688 11400 3 11400 11688 11689 3 11400 11689 11401 3 11401 11689 11690 3 11401 11690 11402 3 11402 11690 11691 3 11402 11691 11403 3 11403 11691 11692 3 11403 11692 11404 3 11404 11692 11693 3 11404 11693 11405 3 11405 11693 11406 3 11694 11406 11693 3 11406 11694 11407 3 11695 11407 11694 3 11407 11695 11408 3 11696 11408 11695 3 11408 11696 11409 3 11697 11409 11696 3 11409 11697 11412 3 11700 11412 11697 3 11410 11698 11411 3 11699 11411 11698 3 11410 11415 11703 3 11410 11703 11698 3 11412 11700 11413 3 11701 11413 11700 3 11413 11701 11416 3 11704 11416 11701 3 11414 11702 11415 3 11703 11415 11702 3 11414 11418 11706 3 11414 11706 11702 3 11416 11704 11417 3 11705 11417 11704 3 11417 11705 11419 3 11707 11419 11705 3 11418 11420 11708 3 11418 11708 11706 3 11419 11707 11421 3 11709 11421 11707 3 11420 11422 11710 3 11420 11710 11708 3 11421 11709 11423 3 11711 11423 11709 3 11422 11424 11712 3 11422 11712 11710 3 11423 11711 11425 3 11713 11425 11711 3 11424 11426 11714 3 11424 11714 11712 3 11425 11713 11427 3 11715 11427 11713 3 11426 11428 11716 3 11426 11716 11714 3 11427 11715 11429 3 11717 11429 11715 3 11428 11430 11718 3 11428 11718 11716 3 11429 11717 11431 3 11719 11431 11717 3 11430 11432 11720 3 11430 11720 11718 3 11431 11719 11433 3 11721 11433 11719 3 11432 11434 11722 3 11432 11722 11720 3 11433 11721 11435 3 11723 11435 11721 3 11434 11436 11724 3 11434 11724 11722 3 11435 11723 11437 3 11725 11437 11723 3 11436 11438 11726 3 11436 11726 11724 3 11437 11725 11439 3 11727 11439 11725 3 11438 11440 11726 3 11728 11726 11440 3 11439 11727 11441 3 11729 11441 11727 3 11440 11442 11728 3 11730 11728 11442 3 11441 11729 11443 3 11731 11443 11729 3 11442 11444 11730 3 11732 11730 11444 3 11443 11731 11445 3 11733 11445 11731 3 11444 11446 11732 3 11734 11732 11446 3 11445 11733 11447 3 11735 11447 11733 3 11446 11448 11734 3 11736 11734 11448 3 11447 11735 11449 3 11737 11449 11735 3 11448 11450 11736 3 11738 11736 11450 3 11449 11737 11451 3 11739 11451 11737 3 11450 11452 11738 3 11740 11738 11452 3 11451 11739 11453 3 11741 11453 11739 3 11452 11454 11740 3 11742 11740 11454 3 11453 11741 11455 3 11743 11455 11741 3 11454 11456 11742 3 11744 11742 11456 3 11455 11743 11457 3 11745 11457 11743 3 11456 11458 11744 3 11746 11744 11458 3 11457 11745 11459 3 11747 11459 11745 3 11458 11460 11746 3 11748 11746 11460 3 11459 11747 11461 3 11749 11461 11747 3 11460 11462 11748 3 11750 11748 11462 3 11461 11749 11463 3 11751 11463 11749 3 11462 11464 11750 3 11752 11750 11464 3 11463 11751 11465 3 11753 11465 11751 3 11464 11466 11752 3 11754 11752 11466 3 11465 11753 11467 3 11755 11467 11753 3 11466 11468 11754 3 11756 11754 11468 3 11467 11755 11469 3 11757 11469 11755 3 11468 11470 11756 3 11758 11756 11470 3 11469 11757 11471 3 11759 11471 11757 3 11470 11472 11758 3 11760 11758 11472 3 11471 11759 11761 3 11471 11761 11473 3 11472 11474 11760 3 11762 11760 11474 3 11473 11761 11763 3 11473 11763 11475 3 11474 11476 11762 3 11764 11762 11476 3 11475 11763 11765 3 11475 11765 11477 3 11476 11478 11764 3 11766 11764 11478 3 11477 11765 11767 3 11477 11767 11479 3 11478 11480 11766 3 11768 11766 11480 3 11479 11767 11769 3 11479 11769 11481 3 11480 11482 11768 3 11770 11768 11482 3 11481 11769 11771 3 11481 11771 11483 3 11482 11484 11770 3 11772 11770 11484 3 11483 11771 11773 3 11483 11773 11485 3 11484 11486 11772 3 11774 11772 11486 3 11485 11773 11775 3 11485 11775 11487 3 11486 11488 11774 3 11776 11774 11488 3 11487 11775 11777 3 11487 11777 11489 3 11488 11490 11776 3 11778 11776 11490 3 11489 11777 11779 3 11489 11779 11491 3 11490 11492 11778 3 11780 11778 11492 3 11491 11779 11781 3 11491 11781 11493 3 11492 11494 11780 3 11782 11780 11494 3 11493 11781 11783 3 11493 11783 11495 3 11494 11496 11782 3 11784 11782 11496 3 11495 11783 11785 3 11495 11785 11497 3 11496 11498 11784 3 11786 11784 11498 3 11497 11785 11787 3 11497 11787 11499 3 11498 11500 11786 3 11788 11786 11500 3 11499 11787 11789 3 11499 11789 11501 3 11500 11502 11788 3 11790 11788 11502 3 11501 11789 11791 3 11501 11791 11503 3 11502 11504 11790 3 11792 11790 11504 3 11503 11791 11793 3 11503 11793 11505 3 11504 11506 11794 3 11504 11794 11792 3 11505 11793 11795 3 11505 11795 11507 3 11506 11508 11796 3 11506 11796 11794 3 11507 11795 11797 3 11507 11797 11509 3 11508 11510 11798 3 11508 11798 11796 3 11509 11797 11799 3 11509 11799 11511 3 11510 11512 11800 3 11510 11800 11798 3 11511 11799 11801 3 11511 11801 11513 3 11512 11514 11802 3 11512 11802 11800 3 11513 11801 11803 3 11513 11803 11515 3 11514 11516 11804 3 11514 11804 11802 3 11515 11803 11805 3 11515 11805 11517 3 11516 11518 11806 3 11516 11806 11804 3 11517 11805 11807 3 11517 11807 11519 3 11518 11520 11808 3 11518 11808 11806 3 11519 11807 11809 3 11519 11809 11521 3 11520 11522 11810 3 11520 11810 11808 3 11521 11809 11811 3 11521 11811 11523 3 11522 11524 11812 3 11522 11812 11810 3 11523 11811 11813 3 11523 11813 11525 3 11524 11526 11814 3 11524 11814 11812 3 11525 11813 11815 3 11525 11815 11527 3 11526 11528 11816 3 11526 11816 11814 3 11527 11815 11817 3 11527 11817 11529 3 11528 11530 11818 3 11528 11818 11816 3 11529 11817 11819 3 11529 11819 11531 3 11530 11532 11820 3 11530 11820 11818 3 11531 11819 11821 3 11531 11821 11533 3 11532 11534 11822 3 11532 11822 11820 3 11533 11821 11823 3 11533 11823 11535 3 11534 11536 11824 3 11534 11824 11822 3 11535 11823 11825 3 11535 11825 11537 3 11536 11538 11826 3 11536 11826 11824 3 11537 11825 11827 3 11537 11827 11539 3 11538 11540 11828 3 11538 11828 11826 3 11539 11827 11541 3 11829 11541 11827 3 11540 11542 11830 3 11540 11830 11828 3 11541 11829 11543 3 11831 11543 11829 3 11542 11544 11832 3 11542 11832 11830 3 11543 11831 11545 3 11833 11545 11831 3 11544 11546 11834 3 11544 11834 11832 3 11545 11833 11547 3 11835 11547 11833 3 11546 11548 11836 3 11546 11836 11834 3 11547 11835 11549 3 11837 11549 11835 3 11548 11550 11838 3 11548 11838 11836 3 11549 11837 11551 3 11839 11551 11837 3 11550 11552 11840 3 11550 11840 11838 3 11551 11839 11555 3 11843 11555 11839 3 11552 11553 11841 3 11552 11841 11840 3 11553 11556 11844 3 11553 11844 11841 3 11554 11555 11843 3 11554 11843 11842 3 11554 11842 11559 3 11847 11559 11842 3 11556 11557 11845 3 11556 11845 11844 3 11557 11560 11848 3 11557 11848 11845 3 11558 11559 11847 3 11558 11847 11846 3 11558 11846 11628 3 11916 11628 11846 3 11560 11561 11849 3 11560 11849 11848 3 11561 11562 11850 3 11561 11850 11849 3 11562 11563 11851 3 11562 11851 11850 3 11563 11564 11852 3 11563 11852 11851 3 11564 11565 11853 3 11564 11853 11852 3 11565 11566 11854 3 11565 11854 11853 3 11566 11567 11855 3 11566 11855 11854 3 11567 11568 11856 3 11567 11856 11855 3 11568 11569 11857 3 11568 11857 11856 3 11569 11570 11858 3 11569 11858 11857 3 11570 11571 11858 3 11859 11858 11571 3 11571 11572 11859 3 11860 11859 11572 3 11572 11573 11860 3 11861 11860 11573 3 11573 11574 11861 3 11862 11861 11574 3 11574 11575 11862 3 11863 11862 11575 3 11575 11576 11863 3 11864 11863 11576 3 11576 11577 11864 3 11865 11864 11577 3 11577 11578 11865 3 11866 11865 11578 3 11578 11579 11866 3 11867 11866 11579 3 11579 11580 11867 3 11868 11867 11580 3 11580 11581 11868 3 11869 11868 11581 3 11581 11582 11869 3 11870 11869 11582 3 11582 11583 11870 3 11871 11870 11583 3 11583 11584 11871 3 11872 11871 11584 3 11584 11585 11872 3 11873 11872 11585 3 11585 11586 11873 3 11874 11873 11586 3 11586 11587 11874 3 11875 11874 11587 3 11587 11588 11875 3 11876 11875 11588 3 11588 11589 11876 3 11877 11876 11589 3 11589 11590 11877 3 11878 11877 11590 3 11590 11591 11878 3 11879 11878 11591 3 11591 11592 11879 3 11880 11879 11592 3 11592 11593 11880 3 11881 11880 11593 3 11593 11594 11881 3 11882 11881 11594 3 11594 11595 11882 3 11883 11882 11595 3 11595 11596 11883 3 11884 11883 11596 3 11596 11597 11884 3 11885 11884 11597 3 11597 11598 11885 3 11886 11885 11598 3 11598 11599 11886 3 11887 11886 11599 3 11599 11600 11887 3 11888 11887 11600 3 11600 11601 11888 3 11889 11888 11601 3 11601 11602 11889 3 11890 11889 11602 3 11602 11603 11890 3 11891 11890 11603 3 11603 11604 11891 3 11892 11891 11604 3 11604 11605 11892 3 11893 11892 11605 3 11605 11606 11893 3 11894 11893 11606 3 11606 11607 11894 3 11895 11894 11607 3 11607 11608 11895 3 11896 11895 11608 3 11608 11609 11896 3 11897 11896 11609 3 11609 11610 11897 3 11898 11897 11610 3 11610 11611 11898 3 11899 11898 11611 3 11611 11612 11899 3 11900 11899 11612 3 11612 11613 11900 3 11901 11900 11613 3 11613 11614 11901 3 11902 11901 11614 3 11614 11615 11902 3 11903 11902 11615 3 11615 11616 11903 3 11904 11903 11616 3 11616 11617 11904 3 11905 11904 11617 3 11617 11618 11905 3 11906 11905 11618 3 11618 11619 11906 3 11907 11906 11619 3 11619 11620 11907 3 11908 11907 11620 3 11620 11621 11908 3 11909 11908 11621 3 11621 11622 11909 3 11910 11909 11622 3 11622 11623 11910 3 11911 11910 11623 3 11623 11624 11911 3 11912 11911 11624 3 11624 11625 11912 3 11913 11912 11625 3 11625 11626 11913 3 11914 11913 11626 3 11626 11627 11914 3 11915 11914 11627 3 11627 11628 11915 3 11916 11915 11628 3 11629 11917 11918 3 11629 11918 11630 3 11629 11699 11987 3 11629 11987 11917 3 11630 11918 11919 3 11630 11919 11631 3 11631 11919 11920 3 11631 11920 11632 3 11632 11920 11921 3 11632 11921 11633 3 11633 11921 11922 3 11633 11922 11634 3 11634 11922 11923 3 11634 11923 11635 3 11635 11923 11924 3 11635 11924 11636 3 11636 11924 11925 3 11636 11925 11637 3 11637 11925 11926 3 11637 11926 11638 3 11638 11926 11927 3 11638 11927 11639 3 11639 11927 11928 3 11639 11928 11640 3 11640 11928 11929 3 11640 11929 11641 3 11641 11929 11930 3 11641 11930 11642 3 11642 11930 11931 3 11642 11931 11643 3 11643 11931 11932 3 11643 11932 11644 3 11644 11932 11933 3 11644 11933 11645 3 11645 11933 11934 3 11645 11934 11646 3 11646 11934 11935 3 11646 11935 11647 3 11647 11935 11936 3 11647 11936 11648 3 11648 11936 11937 3 11648 11937 11649 3 11649 11937 11938 3 11649 11938 11650 3 11650 11938 11939 3 11650 11939 11651 3 11651 11939 11940 3 11651 11940 11652 3 11652 11940 11941 3 11652 11941 11653 3 11653 11941 11942 3 11653 11942 11654 3 11654 11942 11943 3 11654 11943 11655 3 11655 11943 11944 3 11655 11944 11656 3 11656 11944 11945 3 11656 11945 11657 3 11657 11945 11946 3 11657 11946 11658 3 11658 11946 11947 3 11658 11947 11659 3 11659 11947 11948 3 11659 11948 11660 3 11660 11948 11949 3 11660 11949 11661 3 11661 11949 11950 3 11661 11950 11662 3 11662 11950 11951 3 11662 11951 11663 3 11663 11951 11952 3 11663 11952 11664 3 11664 11952 11953 3 11664 11953 11665 3 11665 11953 11954 3 11665 11954 11666 3 11666 11954 11955 3 11666 11955 11667 3 11667 11955 11956 3 11667 11956 11668 3 11668 11956 11957 3 11668 11957 11669 3 11669 11957 11958 3 11669 11958 11670 3 11670 11958 11959 3 11670 11959 11671 3 11671 11959 11672 3 11960 11672 11959 3 11672 11960 11673 3 11961 11673 11960 3 11673 11961 11674 3 11962 11674 11961 3 11674 11962 11675 3 11963 11675 11962 3 11675 11963 11676 3 11964 11676 11963 3 11676 11964 11677 3 11965 11677 11964 3 11677 11965 11678 3 11966 11678 11965 3 11678 11966 11679 3 11967 11679 11966 3 11679 11967 11680 3 11968 11680 11967 3 11680 11968 11681 3 11969 11681 11968 3 11681 11969 11682 3 11970 11682 11969 3 11682 11970 11683 3 11971 11683 11970 3 11683 11971 11684 3 11972 11684 11971 3 11684 11972 11685 3 11973 11685 11972 3 11685 11973 11686 3 11974 11686 11973 3 11686 11974 11687 3 11975 11687 11974 3 11687 11975 11688 3 11976 11688 11975 3 11688 11976 11689 3 11977 11689 11976 3 11689 11977 11690 3 11978 11690 11977 3 11690 11978 11691 3 11979 11691 11978 3 11691 11979 11692 3 11980 11692 11979 3 11692 11980 11693 3 11981 11693 11980 3 11693 11981 11694 3 11982 11694 11981 3 11694 11982 11695 3 11983 11695 11982 3 11695 11983 11696 3 11984 11696 11983 3 11696 11984 11697 3 11985 11697 11984 3 11697 11985 11700 3 11988 11700 11985 3 11698 11986 11699 3 11987 11699 11986 3 11698 11703 11991 3 11698 11991 11986 3 11700 11988 11701 3 11989 11701 11988 3 11701 11989 11704 3 11992 11704 11989 3 11702 11990 11703 3 11991 11703 11990 3 11702 11706 11990 3 11994 11990 11706 3 11704 11992 11705 3 11993 11705 11992 3 11705 11993 11707 3 11995 11707 11993 3 11706 11708 11994 3 11996 11994 11708 3 11707 11995 11709 3 11997 11709 11995 3 11708 11710 11996 3 11998 11996 11710 3 11709 11997 11711 3 11999 11711 11997 3 11710 11712 11998 3 12000 11998 11712 3 11711 11999 11713 3 12001 11713 11999 3 11712 11714 12000 3 12002 12000 11714 3 11713 12001 11715 3 12003 11715 12001 3 11714 11716 12002 3 12004 12002 11716 3 11715 12003 11717 3 12005 11717 12003 3 11716 11718 12004 3 12006 12004 11718 3 11717 12005 11719 3 12007 11719 12005 3 11718 11720 12006 3 12008 12006 11720 3 11719 12007 11721 3 12009 11721 12007 3 11720 11722 12008 3 12010 12008 11722 3 11721 12009 11723 3 12011 11723 12009 3 11722 11724 12010 3 12012 12010 11724 3 11723 12011 11725 3 12013 11725 12011 3 11724 11726 12012 3 12014 12012 11726 3 11725 12013 11727 3 12015 11727 12013 3 11726 11728 12014 3 12016 12014 11728 3 11727 12015 11729 3 12017 11729 12015 3 11728 11730 12016 3 12018 12016 11730 3 11729 12017 11731 3 12019 11731 12017 3 11730 11732 12018 3 12020 12018 11732 3 11731 12019 11733 3 12021 11733 12019 3 11732 11734 12020 3 12022 12020 11734 3 11733 12021 11735 3 12023 11735 12021 3 11734 11736 12022 3 12024 12022 11736 3 11735 12023 11737 3 12025 11737 12023 3 11736 11738 12024 3 12026 12024 11738 3 11737 12025 11739 3 12027 11739 12025 3 11738 11740 12026 3 12028 12026 11740 3 11739 12027 12029 3 11739 12029 11741 3 11740 11742 12028 3 12030 12028 11742 3 11741 12029 12031 3 11741 12031 11743 3 11742 11744 12030 3 12032 12030 11744 3 11743 12031 12033 3 11743 12033 11745 3 11744 11746 12032 3 12034 12032 11746 3 11745 12033 12035 3 11745 12035 11747 3 11746 11748 12034 3 12036 12034 11748 3 11747 12035 12037 3 11747 12037 11749 3 11748 11750 12036 3 12038 12036 11750 3 11749 12037 12039 3 11749 12039 11751 3 11750 11752 12038 3 12040 12038 11752 3 11751 12039 12041 3 11751 12041 11753 3 11752 11754 12040 3 12042 12040 11754 3 11753 12041 12043 3 11753 12043 11755 3 11754 11756 12042 3 12044 12042 11756 3 11755 12043 12045 3 11755 12045 11757 3 11756 11758 12044 3 12046 12044 11758 3 11757 12045 12047 3 11757 12047 11759 3 11758 11760 12046 3 12048 12046 11760 3 11759 12047 12049 3 11759 12049 11761 3 11760 11762 12048 3 12050 12048 11762 3 11761 12049 12051 3 11761 12051 11763 3 11762 11764 12050 3 12052 12050 11764 3 11763 12051 12053 3 11763 12053 11765 3 11764 11766 12052 3 12054 12052 11766 3 11765 12053 12055 3 11765 12055 11767 3 11766 11768 12054 3 12056 12054 11768 3 11767 12055 12057 3 11767 12057 11769 3 11768 11770 12056 3 12058 12056 11770 3 11769 12057 12059 3 11769 12059 11771 3 11770 11772 12060 3 11770 12060 12058 3 11771 12059 12061 3 11771 12061 11773 3 11772 11774 12062 3 11772 12062 12060 3 11773 12061 12063 3 11773 12063 11775 3 11774 11776 12064 3 11774 12064 12062 3 11775 12063 12065 3 11775 12065 11777 3 11776 11778 12066 3 11776 12066 12064 3 11777 12065 12067 3 11777 12067 11779 3 11778 11780 12068 3 11778 12068 12066 3 11779 12067 12069 3 11779 12069 11781 3 11780 11782 12070 3 11780 12070 12068 3 11781 12069 12071 3 11781 12071 11783 3 11782 11784 12072 3 11782 12072 12070 3 11783 12071 12073 3 11783 12073 11785 3 11784 11786 12074 3 11784 12074 12072 3 11785 12073 12075 3 11785 12075 11787 3 11786 11788 12076 3 11786 12076 12074 3 11787 12075 12077 3 11787 12077 11789 3 11788 11790 12078 3 11788 12078 12076 3 11789 12077 12079 3 11789 12079 11791 3 11790 11792 12080 3 11790 12080 12078 3 11791 12079 12081 3 11791 12081 11793 3 11792 11794 12082 3 11792 12082 12080 3 11793 12081 12083 3 11793 12083 11795 3 11794 11796 12084 3 11794 12084 12082 3 11795 12083 12085 3 11795 12085 11797 3 11796 11798 12086 3 11796 12086 12084 3 11797 12085 12087 3 11797 12087 11799 3 11798 11800 12088 3 11798 12088 12086 3 11799 12087 12089 3 11799 12089 11801 3 11800 11802 12090 3 11800 12090 12088 3 11801 12089 12091 3 11801 12091 11803 3 11802 11804 12092 3 11802 12092 12090 3 11803 12091 12093 3 11803 12093 11805 3 11804 11806 12094 3 11804 12094 12092 3 11805 12093 12095 3 11805 12095 11807 3 11806 11808 12096 3 11806 12096 12094 3 11807 12095 11809 3 12097 11809 12095 3 11808 11810 12098 3 11808 12098 12096 3 11809 12097 11811 3 12099 11811 12097 3 11810 11812 12100 3 11810 12100 12098 3 11811 12099 11813 3 12101 11813 12099 3 11812 11814 12102 3 11812 12102 12100 3 11813 12101 11815 3 12103 11815 12101 3 11814 11816 12104 3 11814 12104 12102 3 11815 12103 11817 3 12105 11817 12103 3 11816 11818 12106 3 11816 12106 12104 3 11817 12105 11819 3 12107 11819 12105 3 11818 11820 12108 3 11818 12108 12106 3 11819 12107 11821 3 12109 11821 12107 3 11820 11822 12110 3 11820 12110 12108 3 11821 12109 11823 3 12111 11823 12109 3 11822 11824 12112 3 11822 12112 12110 3 11823 12111 11825 3 12113 11825 12111 3 11824 11826 12114 3 11824 12114 12112 3 11825 12113 11827 3 12115 11827 12113 3 11826 11828 12116 3 11826 12116 12114 3 11827 12115 11829 3 12117 11829 12115 3 11828 11830 12118 3 11828 12118 12116 3 11829 12117 11831 3 12119 11831 12117 3 11830 11832 12120 3 11830 12120 12118 3 11831 12119 11833 3 12121 11833 12119 3 11832 11834 12122 3 11832 12122 12120 3 11833 12121 11835 3 12123 11835 12121 3 11834 11836 12124 3 11834 12124 12122 3 11835 12123 11837 3 12125 11837 12123 3 11836 11838 12124 3 12126 12124 11838 3 11837 12125 11839 3 12127 11839 12125 3 11838 11840 12126 3 12128 12126 11840 3 11839 12127 11843 3 12131 11843 12127 3 11840 11841 12128 3 12129 12128 11841 3 11841 11844 12129 3 12132 12129 11844 3 11842 11843 12130 3 12131 12130 11843 3 11842 12130 11847 3 12135 11847 12130 3 11844 11845 12132 3 12133 12132 11845 3 11845 11848 12133 3 12136 12133 11848 3 11846 11847 12134 3 12135 12134 11847 3 11846 12134 11916 3 12204 11916 12134 3 11848 11849 12136 3 12137 12136 11849 3 11849 11850 12137 3 12138 12137 11850 3 11850 11851 12138 3 12139 12138 11851 3 11851 11852 12139 3 12140 12139 11852 3 11852 11853 12140 3 12141 12140 11853 3 11853 11854 12141 3 12142 12141 11854 3 11854 11855 12142 3 12143 12142 11855 3 11855 11856 12143 3 12144 12143 11856 3 11856 11857 12144 3 12145 12144 11857 3 11857 11858 12145 3 12146 12145 11858 3 11858 11859 12146 3 12147 12146 11859 3 11859 11860 12147 3 12148 12147 11860 3 11860 11861 12148 3 12149 12148 11861 3 11861 11862 12149 3 12150 12149 11862 3 11862 11863 12150 3 12151 12150 11863 3 11863 11864 12151 3 12152 12151 11864 3 11864 11865 12152 3 12153 12152 11865 3 11865 11866 12153 3 12154 12153 11866 3 11866 11867 12154 3 12155 12154 11867 3 11867 11868 12155 3 12156 12155 11868 3 11868 11869 12156 3 12157 12156 11869 3 11869 11870 12157 3 12158 12157 11870 3 11870 11871 12158 3 12159 12158 11871 3 11871 11872 12159 3 12160 12159 11872 3 11872 11873 12160 3 12161 12160 11873 3 11873 11874 12161 3 12162 12161 11874 3 11874 11875 12162 3 12163 12162 11875 3 11875 11876 12163 3 12164 12163 11876 3 11876 11877 12164 3 12165 12164 11877 3 11877 11878 12165 3 12166 12165 11878 3 11878 11879 12166 3 12167 12166 11879 3 11879 11880 12167 3 12168 12167 11880 3 11880 11881 12168 3 12169 12168 11881 3 11881 11882 12169 3 12170 12169 11882 3 11882 11883 12170 3 12171 12170 11883 3 11883 11884 12171 3 12172 12171 11884 3 11884 11885 12172 3 12173 12172 11885 3 11885 11886 12173 3 12174 12173 11886 3 11886 11887 12174 3 12175 12174 11887 3 11887 11888 12175 3 12176 12175 11888 3 11888 11889 12176 3 12177 12176 11889 3 11889 11890 12177 3 12178 12177 11890 3 11890 11891 12178 3 12179 12178 11891 3 11891 11892 12179 3 12180 12179 11892 3 11892 11893 12180 3 12181 12180 11893 3 11893 11894 12181 3 12182 12181 11894 3 11894 11895 12182 3 12183 12182 11895 3 11895 11896 12183 3 12184 12183 11896 3 11896 11897 12184 3 12185 12184 11897 3 11897 11898 12185 3 12186 12185 11898 3 11898 11899 12186 3 12187 12186 11899 3 11899 11900 12187 3 12188 12187 11900 3 11900 11901 12188 3 12189 12188 11901 3 11901 11902 12189 3 12190 12189 11902 3 11902 11903 12190 3 12191 12190 11903 3 11903 11904 12192 3 11903 12192 12191 3 11904 11905 12193 3 11904 12193 12192 3 11905 11906 12194 3 11905 12194 12193 3 11906 11907 12195 3 11906 12195 12194 3 11907 11908 12196 3 11907 12196 12195 3 11908 11909 12197 3 11908 12197 12196 3 11909 11910 12198 3 11909 12198 12197 3 11910 11911 12199 3 11910 12199 12198 3 11911 11912 12200 3 11911 12200 12199 3 11912 11913 12201 3 11912 12201 12200 3 11913 11914 12202 3 11913 12202 12201 3 11914 11915 12203 3 11914 12203 12202 3 11915 11916 12204 3 11915 12204 12203 3 11917 12205 12206 3 11917 12206 11918 3 11917 11987 12275 3 11917 12275 12205 3 11918 12206 12207 3 11918 12207 11919 3 11919 12207 12208 3 11919 12208 11920 3 11920 12208 12209 3 11920 12209 11921 3 11921 12209 12210 3 11921 12210 11922 3 11922 12210 12211 3 11922 12211 11923 3 11923 12211 12212 3 11923 12212 11924 3 11924 12212 12213 3 11924 12213 11925 3 11925 12213 12214 3 11925 12214 11926 3 11926 12214 12215 3 11926 12215 11927 3 11927 12215 12216 3 11927 12216 11928 3 11928 12216 12217 3 11928 12217 11929 3 11929 12217 12218 3 11929 12218 11930 3 11930 12218 12219 3 11930 12219 11931 3 11931 12219 12220 3 11931 12220 11932 3 11932 12220 12221 3 11932 12221 11933 3 11933 12221 12222 3 11933 12222 11934 3 11934 12222 12223 3 11934 12223 11935 3 11935 12223 12224 3 11935 12224 11936 3 11936 12224 12225 3 11936 12225 11937 3 11937 12225 12226 3 11937 12226 11938 3 11938 12226 12227 3 11938 12227 11939 3 11939 12227 12228 3 11939 12228 11940 3 11940 12228 12229 3 11940 12229 11941 3 11941 12229 11942 3 12230 11942 12229 3 11942 12230 11943 3 12231 11943 12230 3 11943 12231 11944 3 12232 11944 12231 3 11944 12232 11945 3 12233 11945 12232 3 11945 12233 11946 3 12234 11946 12233 3 11946 12234 11947 3 12235 11947 12234 3 11947 12235 11948 3 12236 11948 12235 3 11948 12236 11949 3 12237 11949 12236 3 11949 12237 11950 3 12238 11950 12237 3 11950 12238 11951 3 12239 11951 12238 3 11951 12239 11952 3 12240 11952 12239 3 11952 12240 11953 3 12241 11953 12240 3 11953 12241 11954 3 12242 11954 12241 3 11954 12242 11955 3 12243 11955 12242 3 11955 12243 11956 3 12244 11956 12243 3 11956 12244 11957 3 12245 11957 12244 3 11957 12245 11958 3 12246 11958 12245 3 11958 12246 11959 3 12247 11959 12246 3 11959 12247 11960 3 12248 11960 12247 3 11960 12248 11961 3 12249 11961 12248 3 11961 12249 11962 3 12250 11962 12249 3 11962 12250 11963 3 12251 11963 12250 3 11963 12251 11964 3 12252 11964 12251 3 11964 12252 11965 3 12253 11965 12252 3 11965 12253 11966 3 12254 11966 12253 3 11966 12254 11967 3 12255 11967 12254 3 11967 12255 11968 3 12256 11968 12255 3 11968 12256 11969 3 12257 11969 12256 3 11969 12257 11970 3 12258 11970 12257 3 11970 12258 11971 3 12259 11971 12258 3 11971 12259 11972 3 12260 11972 12259 3 11972 12260 11973 3 12261 11973 12260 3 11973 12261 11974 3 12262 11974 12261 3 11974 12262 11975 3 12263 11975 12262 3 11975 12263 11976 3 12264 11976 12263 3 11976 12264 11977 3 12265 11977 12264 3 11977 12265 11978 3 12266 11978 12265 3 11978 12266 11979 3 12267 11979 12266 3 11979 12267 11980 3 12268 11980 12267 3 11980 12268 11981 3 12269 11981 12268 3 11981 12269 11982 3 12270 11982 12269 3 11982 12270 11983 3 12271 11983 12270 3 11983 12271 11984 3 12272 11984 12271 3 11984 12272 11985 3 12273 11985 12272 3 11985 12273 11988 3 12276 11988 12273 3 11986 12274 11987 3 12275 11987 12274 3 11986 11991 12274 3 12279 12274 11991 3 11988 12276 11989 3 12277 11989 12276 3 11989 12277 11992 3 12280 11992 12277 3 11990 12278 11991 3 12279 11991 12278 3 11990 11994 12278 3 12282 12278 11994 3 11992 12280 11993 3 12281 11993 12280 3 11993 12281 11995 3 12283 11995 12281 3 11994 11996 12282 3 12284 12282 11996 3 11995 12283 11997 3 12285 11997 12283 3 11996 11998 12284 3 12286 12284 11998 3 11997 12285 11999 3 12287 11999 12285 3 11998 12000 12286 3 12288 12286 12000 3 11999 12287 12001 3 12289 12001 12287 3 12000 12002 12288 3 12290 12288 12002 3 12001 12289 12003 3 12291 12003 12289 3 12002 12004 12290 3 12292 12290 12004 3 12003 12291 12005 3 12293 12005 12291 3 12004 12006 12292 3 12294 12292 12006 3 12005 12293 12007 3 12295 12007 12293 3 12006 12008 12294 3 12296 12294 12008 3 12007 12295 12009 3 12297 12009 12295 3 12008 12010 12296 3 12298 12296 12010 3 12009 12297 12299 3 12009 12299 12011 3 12010 12012 12298 3 12300 12298 12012 3 12011 12299 12301 3 12011 12301 12013 3 12012 12014 12300 3 12302 12300 12014 3 12013 12301 12303 3 12013 12303 12015 3 12014 12016 12302 3 12304 12302 12016 3 12015 12303 12305 3 12015 12305 12017 3 12016 12018 12304 3 12306 12304 12018 3 12017 12305 12307 3 12017 12307 12019 3 12018 12020 12306 3 12308 12306 12020 3 12019 12307 12309 3 12019 12309 12021 3 12020 12022 12308 3 12310 12308 12022 3 12021 12309 12311 3 12021 12311 12023 3 12022 12024 12310 3 12312 12310 12024 3 12023 12311 12313 3 12023 12313 12025 3 12024 12026 12312 3 12314 12312 12026 3 12025 12313 12315 3 12025 12315 12027 3 12026 12028 12314 3 12316 12314 12028 3 12027 12315 12317 3 12027 12317 12029 3 12028 12030 12316 3 12318 12316 12030 3 12029 12317 12319 3 12029 12319 12031 3 12030 12032 12318 3 12320 12318 12032 3 12031 12319 12321 3 12031 12321 12033 3 12032 12034 12320 3 12322 12320 12034 3 12033 12321 12323 3 12033 12323 12035 3 12034 12036 12322 3 12324 12322 12036 3 12035 12323 12325 3 12035 12325 12037 3 12036 12038 12324 3 12326 12324 12038 3 12037 12325 12327 3 12037 12327 12039 3 12038 12040 12328 3 12038 12328 12326 3 12039 12327 12329 3 12039 12329 12041 3 12040 12042 12330 3 12040 12330 12328 3 12041 12329 12331 3 12041 12331 12043 3 12042 12044 12332 3 12042 12332 12330 3 12043 12331 12333 3 12043 12333 12045 3 12044 12046 12334 3 12044 12334 12332 3 12045 12333 12335 3 12045 12335 12047 3 12046 12048 12336 3 12046 12336 12334 3 12047 12335 12337 3 12047 12337 12049 3 12048 12050 12338 3 12048 12338 12336 3 12049 12337 12339 3 12049 12339 12051 3 12050 12052 12340 3 12050 12340 12338 3 12051 12339 12341 3 12051 12341 12053 3 12052 12054 12342 3 12052 12342 12340 3 12053 12341 12343 3 12053 12343 12055 3 12054 12056 12344 3 12054 12344 12342 3 12055 12343 12345 3 12055 12345 12057 3 12056 12058 12346 3 12056 12346 12344 3 12057 12345 12347 3 12057 12347 12059 3 12058 12060 12348 3 12058 12348 12346 3 12059 12347 12349 3 12059 12349 12061 3 12060 12062 12350 3 12060 12350 12348 3 12061 12349 12351 3 12061 12351 12063 3 12062 12064 12352 3 12062 12352 12350 3 12063 12351 12353 3 12063 12353 12065 3 12064 12066 12354 3 12064 12354 12352 3 12065 12353 12355 3 12065 12355 12067 3 12066 12068 12356 3 12066 12356 12354 3 12067 12355 12357 3 12067 12357 12069 3 12068 12070 12358 3 12068 12358 12356 3 12069 12357 12359 3 12069 12359 12071 3 12070 12072 12360 3 12070 12360 12358 3 12071 12359 12361 3 12071 12361 12073 3 12072 12074 12362 3 12072 12362 12360 3 12073 12361 12363 3 12073 12363 12075 3 12074 12076 12364 3 12074 12364 12362 3 12075 12363 12365 3 12075 12365 12077 3 12076 12078 12366 3 12076 12366 12364 3 12077 12365 12079 3 12367 12079 12365 3 12078 12080 12368 3 12078 12368 12366 3 12079 12367 12081 3 12369 12081 12367 3 12080 12082 12370 3 12080 12370 12368 3 12081 12369 12083 3 12371 12083 12369 3 12082 12084 12372 3 12082 12372 12370 3 12083 12371 12085 3 12373 12085 12371 3 12084 12086 12374 3 12084 12374 12372 3 12085 12373 12087 3 12375 12087 12373 3 12086 12088 12376 3 12086 12376 12374 3 12087 12375 12089 3 12377 12089 12375 3 12088 12090 12378 3 12088 12378 12376 3 12089 12377 12091 3 12379 12091 12377 3 12090 12092 12380 3 12090 12380 12378 3 12091 12379 12093 3 12381 12093 12379 3 12092 12094 12382 3 12092 12382 12380 3 12093 12381 12095 3 12383 12095 12381 3 12094 12096 12384 3 12094 12384 12382 3 12095 12383 12097 3 12385 12097 12383 3 12096 12098 12386 3 12096 12386 12384 3 12097 12385 12099 3 12387 12099 12385 3 12098 12100 12388 3 12098 12388 12386 3 12099 12387 12101 3 12389 12101 12387 3 12100 12102 12390 3 12100 12390 12388 3 12101 12389 12103 3 12391 12103 12389 3 12102 12104 12392 3 12102 12392 12390 3 12103 12391 12105 3 12393 12105 12391 3 12104 12106 12394 3 12104 12394 12392 3 12105 12393 12107 3 12395 12107 12393 3 12106 12108 12394 3 12396 12394 12108 3 12107 12395 12109 3 12397 12109 12395 3 12108 12110 12396 3 12398 12396 12110 3 12109 12397 12111 3 12399 12111 12397 3 12110 12112 12398 3 12400 12398 12112 3 12111 12399 12113 3 12401 12113 12399 3 12112 12114 12400 3 12402 12400 12114 3 12113 12401 12115 3 12403 12115 12401 3 12114 12116 12402 3 12404 12402 12116 3 12115 12403 12117 3 12405 12117 12403 3 12116 12118 12404 3 12406 12404 12118 3 12117 12405 12119 3 12407 12119 12405 3 12118 12120 12406 3 12408 12406 12120 3 12119 12407 12121 3 12409 12121 12407 3 12120 12122 12408 3 12410 12408 12122 3 12121 12409 12123 3 12411 12123 12409 3 12122 12124 12410 3 12412 12410 12124 3 12123 12411 12125 3 12413 12125 12411 3 12124 12126 12412 3 12414 12412 12126 3 12125 12413 12127 3 12415 12127 12413 3 12126 12128 12414 3 12416 12414 12128 3 12127 12415 12131 3 12419 12131 12415 3 12128 12129 12416 3 12417 12416 12129 3 12129 12132 12417 3 12420 12417 12132 3 12130 12131 12418 3 12419 12418 12131 3 12130 12418 12135 3 12423 12135 12418 3 12132 12133 12420 3 12421 12420 12133 3 12133 12136 12421 3 12424 12421 12136 3 12134 12135 12422 3 12423 12422 12135 3 12134 12422 12204 3 12492 12204 12422 3 12136 12137 12424 3 12425 12424 12137 3 12137 12138 12425 3 12426 12425 12138 3 12138 12139 12426 3 12427 12426 12139 3 12139 12140 12427 3 12428 12427 12140 3 12140 12141 12428 3 12429 12428 12141 3 12141 12142 12429 3 12430 12429 12142 3 12142 12143 12430 3 12431 12430 12143 3 12143 12144 12431 3 12432 12431 12144 3 12144 12145 12432 3 12433 12432 12145 3 12145 12146 12433 3 12434 12433 12146 3 12146 12147 12434 3 12435 12434 12147 3 12147 12148 12435 3 12436 12435 12148 3 12148 12149 12436 3 12437 12436 12149 3 12149 12150 12437 3 12438 12437 12150 3 12150 12151 12438 3 12439 12438 12151 3 12151 12152 12439 3 12440 12439 12152 3 12152 12153 12440 3 12441 12440 12153 3 12153 12154 12441 3 12442 12441 12154 3 12154 12155 12442 3 12443 12442 12155 3 12155 12156 12443 3 12444 12443 12156 3 12156 12157 12444 3 12445 12444 12157 3 12157 12158 12445 3 12446 12445 12158 3 12158 12159 12446 3 12447 12446 12159 3 12159 12160 12447 3 12448 12447 12160 3 12160 12161 12448 3 12449 12448 12161 3 12161 12162 12449 3 12450 12449 12162 3 12162 12163 12450 3 12451 12450 12163 3 12163 12164 12451 3 12452 12451 12164 3 12164 12165 12452 3 12453 12452 12165 3 12165 12166 12453 3 12454 12453 12166 3 12166 12167 12454 3 12455 12454 12167 3 12167 12168 12455 3 12456 12455 12168 3 12168 12169 12456 3 12457 12456 12169 3 12169 12170 12457 3 12458 12457 12170 3 12170 12171 12458 3 12459 12458 12171 3 12171 12172 12459 3 12460 12459 12172 3 12172 12173 12460 3 12461 12460 12173 3 12173 12174 12462 3 12173 12462 12461 3 12174 12175 12463 3 12174 12463 12462 3 12175 12176 12464 3 12175 12464 12463 3 12176 12177 12465 3 12176 12465 12464 3 12177 12178 12466 3 12177 12466 12465 3 12178 12179 12467 3 12178 12467 12466 3 12179 12180 12468 3 12179 12468 12467 3 12180 12181 12469 3 12180 12469 12468 3 12181 12182 12470 3 12181 12470 12469 3 12182 12183 12471 3 12182 12471 12470 3 12183 12184 12472 3 12183 12472 12471 3 12184 12185 12473 3 12184 12473 12472 3 12185 12186 12474 3 12185 12474 12473 3 12186 12187 12475 3 12186 12475 12474 3 12187 12188 12476 3 12187 12476 12475 3 12188 12189 12477 3 12188 12477 12476 3 12189 12190 12478 3 12189 12478 12477 3 12190 12191 12479 3 12190 12479 12478 3 12191 12192 12480 3 12191 12480 12479 3 12192 12193 12481 3 12192 12481 12480 3 12193 12194 12482 3 12193 12482 12481 3 12194 12195 12483 3 12194 12483 12482 3 12195 12196 12484 3 12195 12484 12483 3 12196 12197 12485 3 12196 12485 12484 3 12197 12198 12486 3 12197 12486 12485 3 12198 12199 12487 3 12198 12487 12486 3 12199 12200 12488 3 12199 12488 12487 3 12200 12201 12489 3 12200 12489 12488 3 12201 12202 12490 3 12201 12490 12489 3 12202 12203 12491 3 12202 12491 12490 3 12203 12204 12492 3 12203 12492 12491 3 12205 12493 12494 3 12205 12494 12206 3 12205 12275 12493 3 12563 12493 12275 3 12206 12494 12495 3 12206 12495 12207 3 12207 12495 12496 3 12207 12496 12208 3 12208 12496 12497 3 12208 12497 12209 3 12209 12497 12498 3 12209 12498 12210 3 12210 12498 12499 3 12210 12499 12211 3 12211 12499 12500 3 12211 12500 12212 3 12212 12500 12501 3 12212 12501 12213 3 12213 12501 12214 3 12502 12214 12501 3 12214 12502 12215 3 12503 12215 12502 3 12215 12503 12216 3 12504 12216 12503 3 12216 12504 12217 3 12505 12217 12504 3 12217 12505 12218 3 12506 12218 12505 3 12218 12506 12219 3 12507 12219 12506 3 12219 12507 12220 3 12508 12220 12507 3 12220 12508 12221 3 12509 12221 12508 3 12221 12509 12222 3 12510 12222 12509 3 12222 12510 12223 3 12511 12223 12510 3 12223 12511 12224 3 12512 12224 12511 3 12224 12512 12225 3 12513 12225 12512 3 12225 12513 12226 3 12514 12226 12513 3 12226 12514 12227 3 12515 12227 12514 3 12227 12515 12228 3 12516 12228 12515 3 12228 12516 12229 3 12517 12229 12516 3 12229 12517 12230 3 12518 12230 12517 3 12230 12518 12231 3 12519 12231 12518 3 12231 12519 12232 3 12520 12232 12519 3 12232 12520 12233 3 12521 12233 12520 3 12233 12521 12234 3 12522 12234 12521 3 12234 12522 12235 3 12523 12235 12522 3 12235 12523 12236 3 12524 12236 12523 3 12236 12524 12237 3 12525 12237 12524 3 12237 12525 12238 3 12526 12238 12525 3 12238 12526 12239 3 12527 12239 12526 3 12239 12527 12240 3 12528 12240 12527 3 12240 12528 12241 3 12529 12241 12528 3 12241 12529 12242 3 12530 12242 12529 3 12242 12530 12243 3 12531 12243 12530 3 12243 12531 12244 3 12532 12244 12531 3 12244 12532 12245 3 12533 12245 12532 3 12245 12533 12246 3 12534 12246 12533 3 12246 12534 12247 3 12535 12247 12534 3 12247 12535 12248 3 12536 12248 12535 3 12248 12536 12249 3 12537 12249 12536 3 12249 12537 12250 3 12538 12250 12537 3 12250 12538 12251 3 12539 12251 12538 3 12251 12539 12252 3 12540 12252 12539 3 12252 12540 12253 3 12541 12253 12540 3 12253 12541 12254 3 12542 12254 12541 3 12254 12542 12255 3 12543 12255 12542 3 12255 12543 12256 3 12544 12256 12543 3 12256 12544 12257 3 12545 12257 12544 3 12257 12545 12258 3 12546 12258 12545 3 12258 12546 12259 3 12547 12259 12546 3 12259 12547 12260 3 12548 12260 12547 3 12260 12548 12261 3 12549 12261 12548 3 12261 12549 12262 3 12550 12262 12549 3 12262 12550 12263 3 12551 12263 12550 3 12263 12551 12264 3 12552 12264 12551 3 12264 12552 12265 3 12553 12265 12552 3 12265 12553 12266 3 12554 12266 12553 3 12266 12554 12267 3 12555 12267 12554 3 12267 12555 12268 3 12556 12268 12555 3 12268 12556 12269 3 12557 12269 12556 3 12269 12557 12270 3 12558 12270 12557 3 12270 12558 12271 3 12559 12271 12558 3 12271 12559 12272 3 12560 12272 12559 3 12272 12560 12273 3 12561 12273 12560 3 12273 12561 12276 3 12564 12276 12561 3 12274 12562 12275 3 12563 12275 12562 3 12274 12279 12562 3 12567 12562 12279 3 12276 12564 12277 3 12565 12277 12564 3 12277 12565 12280 3 12568 12280 12565 3 12278 12566 12279 3 12567 12279 12566 3 12278 12282 12566 3 12570 12566 12282 3 12280 12568 12281 3 12569 12281 12568 3 12281 12569 12283 3 12571 12283 12569 3 12282 12284 12570 3 12572 12570 12284 3 12283 12571 12573 3 12283 12573 12285 3 12284 12286 12572 3 12574 12572 12286 3 12285 12573 12575 3 12285 12575 12287 3 12286 12288 12574 3 12576 12574 12288 3 12287 12575 12577 3 12287 12577 12289 3 12288 12290 12576 3 12578 12576 12290 3 12289 12577 12579 3 12289 12579 12291 3 12290 12292 12578 3 12580 12578 12292 3 12291 12579 12581 3 12291 12581 12293 3 12292 12294 12580 3 12582 12580 12294 3 12293 12581 12583 3 12293 12583 12295 3 12294 12296 12582 3 12584 12582 12296 3 12295 12583 12585 3 12295 12585 12297 3 12296 12298 12584 3 12586 12584 12298 3 12297 12585 12587 3 12297 12587 12299 3 12298 12300 12586 3 12588 12586 12300 3 12299 12587 12589 3 12299 12589 12301 3 12300 12302 12588 3 12590 12588 12302 3 12301 12589 12591 3 12301 12591 12303 3 12302 12304 12590 3 12592 12590 12304 3 12303 12591 12593 3 12303 12593 12305 3 12304 12306 12592 3 12594 12592 12306 3 12305 12593 12595 3 12305 12595 12307 3 12306 12308 12594 3 12596 12594 12308 3 12307 12595 12597 3 12307 12597 12309 3 12308 12310 12596 3 12598 12596 12310 3 12309 12597 12599 3 12309 12599 12311 3 12310 12312 12600 3 12310 12600 12598 3 12311 12599 12601 3 12311 12601 12313 3 12312 12314 12602 3 12312 12602 12600 3 12313 12601 12603 3 12313 12603 12315 3 12314 12316 12604 3 12314 12604 12602 3 12315 12603 12605 3 12315 12605 12317 3 12316 12318 12606 3 12316 12606 12604 3 12317 12605 12607 3 12317 12607 12319 3 12318 12320 12608 3 12318 12608 12606 3 12319 12607 12609 3 12319 12609 12321 3 12320 12322 12610 3 12320 12610 12608 3 12321 12609 12611 3 12321 12611 12323 3 12322 12324 12612 3 12322 12612 12610 3 12323 12611 12613 3 12323 12613 12325 3 12324 12326 12614 3 12324 12614 12612 3 12325 12613 12615 3 12325 12615 12327 3 12326 12328 12616 3 12326 12616 12614 3 12327 12615 12617 3 12327 12617 12329 3 12328 12330 12618 3 12328 12618 12616 3 12329 12617 12619 3 12329 12619 12331 3 12330 12332 12620 3 12330 12620 12618 3 12331 12619 12621 3 12331 12621 12333 3 12332 12334 12622 3 12332 12622 12620 3 12333 12621 12623 3 12333 12623 12335 3 12334 12336 12624 3 12334 12624 12622 3 12335 12623 12625 3 12335 12625 12337 3 12336 12338 12626 3 12336 12626 12624 3 12337 12625 12627 3 12337 12627 12339 3 12338 12340 12628 3 12338 12628 12626 3 12339 12627 12629 3 12339 12629 12341 3 12340 12342 12630 3 12340 12630 12628 3 12341 12629 12631 3 12341 12631 12343 3 12342 12344 12632 3 12342 12632 12630 3 12343 12631 12633 3 12343 12633 12345 3 12344 12346 12634 3 12344 12634 12632 3 12345 12633 12635 3 12345 12635 12347 3 12346 12348 12636 3 12346 12636 12634 3 12347 12635 12637 3 12347 12637 12349 3 12348 12350 12638 3 12348 12638 12636 3 12349 12637 12639 3 12349 12639 12351 3 12350 12352 12640 3 12350 12640 12638 3 12351 12639 12353 3 12641 12353 12639 3 12352 12354 12642 3 12352 12642 12640 3 12353 12641 12355 3 12643 12355 12641 3 12354 12356 12644 3 12354 12644 12642 3 12355 12643 12357 3 12645 12357 12643 3 12356 12358 12646 3 12356 12646 12644 3 12357 12645 12359 3 12647 12359 12645 3 12358 12360 12648 3 12358 12648 12646 3 12359 12647 12361 3 12649 12361 12647 3 12360 12362 12650 3 12360 12650 12648 3 12361 12649 12363 3 12651 12363 12649 3 12362 12364 12652 3 12362 12652 12650 3 12363 12651 12365 3 12653 12365 12651 3 12364 12366 12654 3 12364 12654 12652 3 12365 12653 12367 3 12655 12367 12653 3 12366 12368 12656 3 12366 12656 12654 3 12367 12655 12369 3 12657 12369 12655 3 12368 12370 12658 3 12368 12658 12656 3 12369 12657 12371 3 12659 12371 12657 3 12370 12372 12660 3 12370 12660 12658 3 12371 12659 12373 3 12661 12373 12659 3 12372 12374 12662 3 12372 12662 12660 3 12373 12661 12375 3 12663 12375 12661 3 12374 12376 12664 3 12374 12664 12662 3 12375 12663 12377 3 12665 12377 12663 3 12376 12378 12666 3 12376 12666 12664 3 12377 12665 12379 3 12667 12379 12665 3 12378 12380 12666 3 12668 12666 12380 3 12379 12667 12381 3 12669 12381 12667 3 12380 12382 12668 3 12670 12668 12382 3 12381 12669 12383 3 12671 12383 12669 3 12382 12384 12670 3 12672 12670 12384 3 12383 12671 12385 3 12673 12385 12671 3 12384 12386 12672 3 12674 12672 12386 3 12385 12673 12387 3 12675 12387 12673 3 12386 12388 12674 3 12676 12674 12388 3 12387 12675 12389 3 12677 12389 12675 3 12388 12390 12676 3 12678 12676 12390 3 12389 12677 12391 3 12679 12391 12677 3 12390 12392 12678 3 12680 12678 12392 3 12391 12679 12393 3 12681 12393 12679 3 12392 12394 12680 3 12682 12680 12394 3 12393 12681 12395 3 12683 12395 12681 3 12394 12396 12682 3 12684 12682 12396 3 12395 12683 12397 3 12685 12397 12683 3 12396 12398 12684 3 12686 12684 12398 3 12397 12685 12399 3 12687 12399 12685 3 12398 12400 12686 3 12688 12686 12400 3 12399 12687 12401 3 12689 12401 12687 3 12400 12402 12688 3 12690 12688 12402 3 12401 12689 12403 3 12691 12403 12689 3 12402 12404 12690 3 12692 12690 12404 3 12403 12691 12405 3 12693 12405 12691 3 12404 12406 12692 3 12694 12692 12406 3 12405 12693 12407 3 12695 12407 12693 3 12406 12408 12694 3 12696 12694 12408 3 12407 12695 12409 3 12697 12409 12695 3 12408 12410 12696 3 12698 12696 12410 3 12409 12697 12411 3 12699 12411 12697 3 12410 12412 12698 3 12700 12698 12412 3 12411 12699 12413 3 12701 12413 12699 3 12412 12414 12700 3 12702 12700 12414 3 12413 12701 12415 3 12703 12415 12701 3 12414 12416 12702 3 12704 12702 12416 3 12415 12703 12419 3 12707 12419 12703 3 12416 12417 12704 3 12705 12704 12417 3 12417 12420 12705 3 12708 12705 12420 3 12418 12419 12706 3 12707 12706 12419 3 12418 12706 12423 3 12711 12423 12706 3 12420 12421 12708 3 12709 12708 12421 3 12421 12424 12709 3 12712 12709 12424 3 12422 12423 12710 3 12711 12710 12423 3 12422 12710 12780 3 12422 12780 12492 3 12424 12425 12712 3 12713 12712 12425 3 12425 12426 12713 3 12714 12713 12426 3 12426 12427 12714 3 12715 12714 12427 3 12427 12428 12715 3 12716 12715 12428 3 12428 12429 12716 3 12717 12716 12429 3 12429 12430 12717 3 12718 12717 12430 3 12430 12431 12718 3 12719 12718 12431 3 12431 12432 12719 3 12720 12719 12432 3 12432 12433 12720 3 12721 12720 12433 3 12433 12434 12721 3 12722 12721 12434 3 12434 12435 12722 3 12723 12722 12435 3 12435 12436 12723 3 12724 12723 12436 3 12436 12437 12724 3 12725 12724 12437 3 12437 12438 12725 3 12726 12725 12438 3 12438 12439 12726 3 12727 12726 12439 3 12439 12440 12727 3 12728 12727 12440 3 12440 12441 12728 3 12729 12728 12441 3 12441 12442 12729 3 12730 12729 12442 3 12442 12443 12730 3 12731 12730 12443 3 12443 12444 12731 3 12732 12731 12444 3 12444 12445 12732 3 12733 12732 12445 3 12445 12446 12733 3 12734 12733 12446 3 12446 12447 12734 3 12735 12734 12447 3 12447 12448 12736 3 12447 12736 12735 3 12448 12449 12737 3 12448 12737 12736 3 12449 12450 12738 3 12449 12738 12737 3 12450 12451 12739 3 12450 12739 12738 3 12451 12452 12740 3 12451 12740 12739 3 12452 12453 12741 3 12452 12741 12740 3 12453 12454 12742 3 12453 12742 12741 3 12454 12455 12743 3 12454 12743 12742 3 12455 12456 12744 3 12455 12744 12743 3 12456 12457 12745 3 12456 12745 12744 3 12457 12458 12746 3 12457 12746 12745 3 12458 12459 12747 3 12458 12747 12746 3 12459 12460 12748 3 12459 12748 12747 3 12460 12461 12749 3 12460 12749 12748 3 12461 12462 12750 3 12461 12750 12749 3 12462 12463 12751 3 12462 12751 12750 3 12463 12464 12752 3 12463 12752 12751 3 12464 12465 12753 3 12464 12753 12752 3 12465 12466 12754 3 12465 12754 12753 3 12466 12467 12755 3 12466 12755 12754 3 12467 12468 12756 3 12467 12756 12755 3 12468 12469 12757 3 12468 12757 12756 3 12469 12470 12758 3 12469 12758 12757 3 12470 12471 12759 3 12470 12759 12758 3 12471 12472 12760 3 12471 12760 12759 3 12472 12473 12761 3 12472 12761 12760 3 12473 12474 12762 3 12473 12762 12761 3 12474 12475 12763 3 12474 12763 12762 3 12475 12476 12764 3 12475 12764 12763 3 12476 12477 12765 3 12476 12765 12764 3 12477 12478 12766 3 12477 12766 12765 3 12478 12479 12767 3 12478 12767 12766 3 12479 12480 12768 3 12479 12768 12767 3 12480 12481 12769 3 12480 12769 12768 3 12481 12482 12770 3 12481 12770 12769 3 12482 12483 12771 3 12482 12771 12770 3 12483 12484 12772 3 12483 12772 12771 3 12484 12485 12773 3 12484 12773 12772 3 12485 12486 12774 3 12485 12774 12773 3 12486 12487 12775 3 12486 12775 12774 3 12487 12488 12776 3 12487 12776 12775 3 12488 12489 12777 3 12488 12777 12776 3 12489 12490 12778 3 12489 12778 12777 3 12490 12491 12779 3 12490 12779 12778 3 12491 12492 12780 3 12491 12780 12779 3 12493 12781 12494 3 12782 12494 12781 3 12493 12563 12781 3 12851 12781 12563 3 12494 12782 12495 3 12783 12495 12782 3 12495 12783 12496 3 12784 12496 12783 3 12496 12784 12497 3 12785 12497 12784 3 12497 12785 12498 3 12786 12498 12785 3 12498 12786 12499 3 12787 12499 12786 3 12499 12787 12500 3 12788 12500 12787 3 12500 12788 12501 3 12789 12501 12788 3 12501 12789 12502 3 12790 12502 12789 3 12502 12790 12503 3 12791 12503 12790 3 12503 12791 12504 3 12792 12504 12791 3 12504 12792 12505 3 12793 12505 12792 3 12505 12793 12506 3 12794 12506 12793 3 12506 12794 12507 3 12795 12507 12794 3 12507 12795 12508 3 12796 12508 12795 3 12508 12796 12509 3 12797 12509 12796 3 12509 12797 12510 3 12798 12510 12797 3 12510 12798 12511 3 12799 12511 12798 3 12511 12799 12512 3 12800 12512 12799 3 12512 12800 12513 3 12801 12513 12800 3 12513 12801 12514 3 12802 12514 12801 3 12514 12802 12515 3 12803 12515 12802 3 12515 12803 12516 3 12804 12516 12803 3 12516 12804 12517 3 12805 12517 12804 3 12517 12805 12518 3 12806 12518 12805 3 12518 12806 12519 3 12807 12519 12806 3 12519 12807 12520 3 12808 12520 12807 3 12520 12808 12521 3 12809 12521 12808 3 12521 12809 12522 3 12810 12522 12809 3 12522 12810 12523 3 12811 12523 12810 3 12523 12811 12524 3 12812 12524 12811 3 12524 12812 12525 3 12813 12525 12812 3 12525 12813 12526 3 12814 12526 12813 3 12526 12814 12527 3 12815 12527 12814 3 12527 12815 12528 3 12816 12528 12815 3 12528 12816 12529 3 12817 12529 12816 3 12529 12817 12530 3 12818 12530 12817 3 12530 12818 12531 3 12819 12531 12818 3 12531 12819 12532 3 12820 12532 12819 3 12532 12820 12533 3 12821 12533 12820 3 12533 12821 12534 3 12822 12534 12821 3 12534 12822 12535 3 12823 12535 12822 3 12535 12823 12536 3 12824 12536 12823 3 12536 12824 12537 3 12825 12537 12824 3 12537 12825 12538 3 12826 12538 12825 3 12538 12826 12539 3 12827 12539 12826 3 12539 12827 12540 3 12828 12540 12827 3 12540 12828 12541 3 12829 12541 12828 3 12541 12829 12542 3 12830 12542 12829 3 12542 12830 12543 3 12831 12543 12830 3 12543 12831 12544 3 12832 12544 12831 3 12544 12832 12545 3 12833 12545 12832 3 12545 12833 12546 3 12834 12546 12833 3 12546 12834 12547 3 12835 12547 12834 3 12547 12835 12548 3 12836 12548 12835 3 12548 12836 12549 3 12837 12549 12836 3 12549 12837 12550 3 12838 12550 12837 3 12550 12838 12551 3 12839 12551 12838 3 12551 12839 12552 3 12840 12552 12839 3 12552 12840 12553 3 12841 12553 12840 3 12553 12841 12554 3 12842 12554 12841 3 12554 12842 12555 3 12843 12555 12842 3 12555 12843 12556 3 12844 12556 12843 3 12556 12844 12557 3 12845 12557 12844 3 12557 12845 12558 3 12846 12558 12845 3 12558 12846 12847 3 12558 12847 12559 3 12559 12847 12848 3 12559 12848 12560 3 12560 12848 12849 3 12560 12849 12561 3 12561 12849 12852 3 12561 12852 12564 3 12562 12850 12851 3 12562 12851 12563 3 12562 12567 12850 3 12855 12850 12567 3 12564 12852 12853 3 12564 12853 12565 3 12565 12853 12856 3 12565 12856 12568 3 12566 12854 12855 3 12566 12855 12567 3 12566 12570 12854 3 12858 12854 12570 3 12568 12856 12857 3 12568 12857 12569 3 12569 12857 12859 3 12569 12859 12571 3 12570 12572 12858 3 12860 12858 12572 3 12571 12859 12861 3 12571 12861 12573 3 12572 12574 12860 3 12862 12860 12574 3 12573 12861 12863 3 12573 12863 12575 3 12574 12576 12862 3 12864 12862 12576 3 12575 12863 12865 3 12575 12865 12577 3 12576 12578 12864 3 12866 12864 12578 3 12577 12865 12867 3 12577 12867 12579 3 12578 12580 12866 3 12868 12866 12580 3 12579 12867 12869 3 12579 12869 12581 3 12580 12582 12868 3 12870 12868 12582 3 12581 12869 12871 3 12581 12871 12583 3 12582 12584 12870 3 12872 12870 12584 3 12583 12871 12873 3 12583 12873 12585 3 12584 12586 12874 3 12584 12874 12872 3 12585 12873 12875 3 12585 12875 12587 3 12586 12588 12876 3 12586 12876 12874 3 12587 12875 12877 3 12587 12877 12589 3 12588 12590 12878 3 12588 12878 12876 3 12589 12877 12879 3 12589 12879 12591 3 12590 12592 12880 3 12590 12880 12878 3 12591 12879 12881 3 12591 12881 12593 3 12592 12594 12882 3 12592 12882 12880 3 12593 12881 12883 3 12593 12883 12595 3 12594 12596 12884 3 12594 12884 12882 3 12595 12883 12885 3 12595 12885 12597 3 12596 12598 12886 3 12596 12886 12884 3 12597 12885 12887 3 12597 12887 12599 3 12598 12600 12888 3 12598 12888 12886 3 12599 12887 12889 3 12599 12889 12601 3 12600 12602 12890 3 12600 12890 12888 3 12601 12889 12891 3 12601 12891 12603 3 12602 12604 12892 3 12602 12892 12890 3 12603 12891 12893 3 12603 12893 12605 3 12604 12606 12894 3 12604 12894 12892 3 12605 12893 12895 3 12605 12895 12607 3 12606 12608 12896 3 12606 12896 12894 3 12607 12895 12897 3 12607 12897 12609 3 12608 12610 12898 3 12608 12898 12896 3 12609 12897 12899 3 12609 12899 12611 3 12610 12612 12900 3 12610 12900 12898 3 12611 12899 12901 3 12611 12901 12613 3 12612 12614 12902 3 12612 12902 12900 3 12613 12901 12903 3 12613 12903 12615 3 12614 12616 12904 3 12614 12904 12902 3 12615 12903 12905 3 12615 12905 12617 3 12616 12618 12906 3 12616 12906 12904 3 12617 12905 12907 3 12617 12907 12619 3 12618 12620 12908 3 12618 12908 12906 3 12619 12907 12909 3 12619 12909 12621 3 12620 12622 12910 3 12620 12910 12908 3 12621 12909 12911 3 12621 12911 12623 3 12622 12624 12912 3 12622 12912 12910 3 12623 12911 12913 3 12623 12913 12625 3 12624 12626 12914 3 12624 12914 12912 3 12625 12913 12915 3 12625 12915 12627 3 12626 12628 12916 3 12626 12916 12914 3 12627 12915 12629 3 12917 12629 12915 3 12628 12630 12918 3 12628 12918 12916 3 12629 12917 12631 3 12919 12631 12917 3 12630 12632 12920 3 12630 12920 12918 3 12631 12919 12633 3 12921 12633 12919 3 12632 12634 12922 3 12632 12922 12920 3 12633 12921 12635 3 12923 12635 12921 3 12634 12636 12924 3 12634 12924 12922 3 12635 12923 12637 3 12925 12637 12923 3 12636 12638 12926 3 12636 12926 12924 3 12637 12925 12639 3 12927 12639 12925 3 12638 12640 12928 3 12638 12928 12926 3 12639 12927 12641 3 12929 12641 12927 3 12640 12642 12930 3 12640 12930 12928 3 12641 12929 12643 3 12931 12643 12929 3 12642 12644 12932 3 12642 12932 12930 3 12643 12931 12645 3 12933 12645 12931 3 12644 12646 12934 3 12644 12934 12932 3 12645 12933 12647 3 12935 12647 12933 3 12646 12648 12936 3 12646 12936 12934 3 12647 12935 12649 3 12937 12649 12935 3 12648 12650 12938 3 12648 12938 12936 3 12649 12937 12651 3 12939 12651 12937 3 12650 12652 12940 3 12650 12940 12938 3 12651 12939 12653 3 12941 12653 12939 3 12652 12654 12942 3 12652 12942 12940 3 12653 12941 12655 3 12943 12655 12941 3 12654 12656 12942 3 12944 12942 12656 3 12655 12943 12657 3 12945 12657 12943 3 12656 12658 12944 3 12946 12944 12658 3 12657 12945 12659 3 12947 12659 12945 3 12658 12660 12946 3 12948 12946 12660 3 12659 12947 12661 3 12949 12661 12947 3 12660 12662 12948 3 12950 12948 12662 3 12661 12949 12663 3 12951 12663 12949 3 12662 12664 12950 3 12952 12950 12664 3 12663 12951 12665 3 12953 12665 12951 3 12664 12666 12952 3 12954 12952 12666 3 12665 12953 12667 3 12955 12667 12953 3 12666 12668 12954 3 12956 12954 12668 3 12667 12955 12669 3 12957 12669 12955 3 12668 12670 12956 3 12958 12956 12670 3 12669 12957 12671 3 12959 12671 12957 3 12670 12672 12958 3 12960 12958 12672 3 12671 12959 12673 3 12961 12673 12959 3 12672 12674 12960 3 12962 12960 12674 3 12673 12961 12675 3 12963 12675 12961 3 12674 12676 12962 3 12964 12962 12676 3 12675 12963 12677 3 12965 12677 12963 3 12676 12678 12964 3 12966 12964 12678 3 12677 12965 12679 3 12967 12679 12965 3 12678 12680 12966 3 12968 12966 12680 3 12679 12967 12681 3 12969 12681 12967 3 12680 12682 12968 3 12970 12968 12682 3 12681 12969 12683 3 12971 12683 12969 3 12682 12684 12970 3 12972 12970 12684 3 12683 12971 12685 3 12973 12685 12971 3 12684 12686 12972 3 12974 12972 12686 3 12685 12973 12687 3 12975 12687 12973 3 12686 12688 12974 3 12976 12974 12688 3 12687 12975 12689 3 12977 12689 12975 3 12688 12690 12976 3 12978 12976 12690 3 12689 12977 12691 3 12979 12691 12977 3 12690 12692 12978 3 12980 12978 12692 3 12691 12979 12693 3 12981 12693 12979 3 12692 12694 12980 3 12982 12980 12694 3 12693 12981 12695 3 12983 12695 12981 3 12694 12696 12982 3 12984 12982 12696 3 12695 12983 12697 3 12985 12697 12983 3 12696 12698 12984 3 12986 12984 12698 3 12697 12985 12987 3 12697 12987 12699 3 12698 12700 12986 3 12988 12986 12700 3 12699 12987 12989 3 12699 12989 12701 3 12700 12702 12988 3 12990 12988 12702 3 12701 12989 12991 3 12701 12991 12703 3 12702 12704 12990 3 12992 12990 12704 3 12703 12991 12995 3 12703 12995 12707 3 12704 12705 12992 3 12993 12992 12705 3 12705 12708 12993 3 12996 12993 12708 3 12706 12707 12994 3 12995 12994 12707 3 12706 12994 12999 3 12706 12999 12711 3 12708 12709 12996 3 12997 12996 12709 3 12709 12712 12997 3 13000 12997 12712 3 12710 12711 12998 3 12999 12998 12711 3 12710 12998 13068 3 12710 13068 12780 3 12712 12713 13000 3 13001 13000 12713 3 12713 12714 13001 3 13002 13001 12714 3 12714 12715 13002 3 13003 13002 12715 3 12715 12716 13003 3 13004 13003 12716 3 12716 12717 13004 3 13005 13004 12717 3 12717 12718 13005 3 13006 13005 12718 3 12718 12719 13006 3 13007 13006 12719 3 12719 12720 13007 3 13008 13007 12720 3 12720 12721 13008 3 13009 13008 12721 3 12721 12722 13009 3 13010 13009 12722 3 12722 12723 13010 3 13011 13010 12723 3 12723 12724 13012 3 12723 13012 13011 3 12724 12725 13013 3 12724 13013 13012 3 12725 12726 13014 3 12725 13014 13013 3 12726 12727 13015 3 12726 13015 13014 3 12727 12728 13016 3 12727 13016 13015 3 12728 12729 13017 3 12728 13017 13016 3 12729 12730 13018 3 12729 13018 13017 3 12730 12731 13019 3 12730 13019 13018 3 12731 12732 13020 3 12731 13020 13019 3 12732 12733 13021 3 12732 13021 13020 3 12733 12734 13022 3 12733 13022 13021 3 12734 12735 13023 3 12734 13023 13022 3 12735 12736 13024 3 12735 13024 13023 3 12736 12737 13025 3 12736 13025 13024 3 12737 12738 13026 3 12737 13026 13025 3 12738 12739 13027 3 12738 13027 13026 3 12739 12740 13028 3 12739 13028 13027 3 12740 12741 13029 3 12740 13029 13028 3 12741 12742 13030 3 12741 13030 13029 3 12742 12743 13031 3 12742 13031 13030 3 12743 12744 13032 3 12743 13032 13031 3 12744 12745 13033 3 12744 13033 13032 3 12745 12746 13034 3 12745 13034 13033 3 12746 12747 13035 3 12746 13035 13034 3 12747 12748 13036 3 12747 13036 13035 3 12748 12749 13037 3 12748 13037 13036 3 12749 12750 13038 3 12749 13038 13037 3 12750 12751 13039 3 12750 13039 13038 3 12751 12752 13040 3 12751 13040 13039 3 12752 12753 13041 3 12752 13041 13040 3 12753 12754 13042 3 12753 13042 13041 3 12754 12755 13043 3 12754 13043 13042 3 12755 12756 13044 3 12755 13044 13043 3 12756 12757 13045 3 12756 13045 13044 3 12757 12758 13046 3 12757 13046 13045 3 12758 12759 13047 3 12758 13047 13046 3 12759 12760 13048 3 12759 13048 13047 3 12760 12761 13049 3 12760 13049 13048 3 12761 12762 13050 3 12761 13050 13049 3 12762 12763 13051 3 12762 13051 13050 3 12763 12764 13052 3 12763 13052 13051 3 12764 12765 13053 3 12764 13053 13052 3 12765 12766 13054 3 12765 13054 13053 3 12766 12767 13055 3 12766 13055 13054 3 12767 12768 13056 3 12767 13056 13055 3 12768 12769 13057 3 12768 13057 13056 3 12769 12770 13058 3 12769 13058 13057 3 12770 12771 13059 3 12770 13059 13058 3 12771 12772 13060 3 12771 13060 13059 3 12772 12773 13061 3 12772 13061 13060 3 12773 12774 13062 3 12773 13062 13061 3 12774 12775 13063 3 12774 13063 13062 3 12775 12776 13064 3 12775 13064 13063 3 12776 12777 13065 3 12776 13065 13064 3 12777 12778 13066 3 12777 13066 13065 3 12778 12779 13067 3 12778 13067 13066 3 12779 12780 13068 3 12779 13068 13067 3 12781 13069 12782 3 13070 12782 13069 3 12781 12851 13069 3 13139 13069 12851 3 12782 13070 12783 3 13071 12783 13070 3 12783 13071 12784 3 13072 12784 13071 3 12784 13072 12785 3 13073 12785 13072 3 12785 13073 12786 3 13074 12786 13073 3 12786 13074 12787 3 13075 12787 13074 3 12787 13075 12788 3 13076 12788 13075 3 12788 13076 12789 3 13077 12789 13076 3 12789 13077 12790 3 13078 12790 13077 3 12790 13078 12791 3 13079 12791 13078 3 12791 13079 12792 3 13080 12792 13079 3 12792 13080 12793 3 13081 12793 13080 3 12793 13081 12794 3 13082 12794 13081 3 12794 13082 12795 3 13083 12795 13082 3 12795 13083 12796 3 13084 12796 13083 3 12796 13084 12797 3 13085 12797 13084 3 12797 13085 12798 3 13086 12798 13085 3 12798 13086 12799 3 13087 12799 13086 3 12799 13087 12800 3 13088 12800 13087 3 12800 13088 12801 3 13089 12801 13088 3 12801 13089 12802 3 13090 12802 13089 3 12802 13090 12803 3 13091 12803 13090 3 12803 13091 12804 3 13092 12804 13091 3 12804 13092 12805 3 13093 12805 13092 3 12805 13093 12806 3 13094 12806 13093 3 12806 13094 12807 3 13095 12807 13094 3 12807 13095 12808 3 13096 12808 13095 3 12808 13096 12809 3 13097 12809 13096 3 12809 13097 12810 3 13098 12810 13097 3 12810 13098 12811 3 13099 12811 13098 3 12811 13099 12812 3 13100 12812 13099 3 12812 13100 12813 3 13101 12813 13100 3 12813 13101 12814 3 13102 12814 13101 3 12814 13102 12815 3 13103 12815 13102 3 12815 13103 12816 3 13104 12816 13103 3 12816 13104 12817 3 13105 12817 13104 3 12817 13105 12818 3 13106 12818 13105 3 12818 13106 12819 3 13107 12819 13106 3 12819 13107 12820 3 13108 12820 13107 3 12820 13108 12821 3 13109 12821 13108 3 12821 13109 12822 3 13110 12822 13109 3 12822 13110 12823 3 13111 12823 13110 3 12823 13111 12824 3 13112 12824 13111 3 12824 13112 12825 3 13113 12825 13112 3 12825 13113 12826 3 13114 12826 13113 3 12826 13114 12827 3 13115 12827 13114 3 12827 13115 12828 3 13116 12828 13115 3 12828 13116 12829 3 13117 12829 13116 3 12829 13117 12830 3 13118 12830 13117 3 12830 13118 12831 3 13119 12831 13118 3 12831 13119 12832 3 13120 12832 13119 3 12832 13120 12833 3 13121 12833 13120 3 12833 13121 12834 3 13122 12834 13121 3 12834 13122 12835 3 13123 12835 13122 3 12835 13123 12836 3 13124 12836 13123 3 12836 13124 12837 3 13125 12837 13124 3 12837 13125 13126 3 12837 13126 12838 3 12838 13126 13127 3 12838 13127 12839 3 12839 13127 13128 3 12839 13128 12840 3 12840 13128 13129 3 12840 13129 12841 3 12841 13129 13130 3 12841 13130 12842 3 12842 13130 13131 3 12842 13131 12843 3 12843 13131 13132 3 12843 13132 12844 3 12844 13132 13133 3 12844 13133 12845 3 12845 13133 13134 3 12845 13134 12846 3 12846 13134 13135 3 12846 13135 12847 3 12847 13135 13136 3 12847 13136 12848 3 12848 13136 13137 3 12848 13137 12849 3 12849 13137 13140 3 12849 13140 12852 3 12850 13138 13139 3 12850 13139 12851 3 12850 12855 13138 3 13143 13138 12855 3 12852 13140 13141 3 12852 13141 12853 3 12853 13141 13144 3 12853 13144 12856 3 12854 13142 13143 3 12854 13143 12855 3 12854 12858 13142 3 13146 13142 12858 3 12856 13144 13145 3 12856 13145 12857 3 12857 13145 13147 3 12857 13147 12859 3 12858 12860 13146 3 13148 13146 12860 3 12859 13147 13149 3 12859 13149 12861 3 12860 12862 13148 3 13150 13148 12862 3 12861 13149 13151 3 12861 13151 12863 3 12862 12864 13152 3 12862 13152 13150 3 12863 13151 13153 3 12863 13153 12865 3 12864 12866 13154 3 12864 13154 13152 3 12865 13153 13155 3 12865 13155 12867 3 12866 12868 13156 3 12866 13156 13154 3 12867 13155 13157 3 12867 13157 12869 3 12868 12870 13158 3 12868 13158 13156 3 12869 13157 13159 3 12869 13159 12871 3 12870 12872 13160 3 12870 13160 13158 3 12871 13159 13161 3 12871 13161 12873 3 12872 12874 13162 3 12872 13162 13160 3 12873 13161 13163 3 12873 13163 12875 3 12874 12876 13164 3 12874 13164 13162 3 12875 13163 13165 3 12875 13165 12877 3 12876 12878 13166 3 12876 13166 13164 3 12877 13165 13167 3 12877 13167 12879 3 12878 12880 13168 3 12878 13168 13166 3 12879 13167 13169 3 12879 13169 12881 3 12880 12882 13170 3 12880 13170 13168 3 12881 13169 13171 3 12881 13171 12883 3 12882 12884 13172 3 12882 13172 13170 3 12883 13171 13173 3 12883 13173 12885 3 12884 12886 13174 3 12884 13174 13172 3 12885 13173 13175 3 12885 13175 12887 3 12886 12888 13176 3 12886 13176 13174 3 12887 13175 13177 3 12887 13177 12889 3 12888 12890 13178 3 12888 13178 13176 3 12889 13177 13179 3 12889 13179 12891 3 12890 12892 13180 3 12890 13180 13178 3 12891 13179 13181 3 12891 13181 12893 3 12892 12894 13182 3 12892 13182 13180 3 12893 13181 13183 3 12893 13183 12895 3 12894 12896 13184 3 12894 13184 13182 3 12895 13183 13185 3 12895 13185 12897 3 12896 12898 13186 3 12896 13186 13184 3 12897 13185 13187 3 12897 13187 12899 3 12898 12900 13188 3 12898 13188 13186 3 12899 13187 13189 3 12899 13189 12901 3 12900 12902 13190 3 12900 13190 13188 3 12901 13189 13191 3 12901 13191 12903 3 12902 12904 13192 3 12902 13192 13190 3 12903 13191 13193 3 12903 13193 12905 3 12904 12906 13194 3 12904 13194 13192 3 12905 13193 13195 3 12905 13195 12907 3 12906 12908 13196 3 12906 13196 13194 3 12907 13195 12909 3 13197 12909 13195 3 12908 12910 13198 3 12908 13198 13196 3 12909 13197 12911 3 13199 12911 13197 3 12910 12912 13200 3 12910 13200 13198 3 12911 13199 12913 3 13201 12913 13199 3 12912 12914 13202 3 12912 13202 13200 3 12913 13201 12915 3 13203 12915 13201 3 12914 12916 13204 3 12914 13204 13202 3 12915 13203 12917 3 13205 12917 13203 3 12916 12918 13206 3 12916 13206 13204 3 12917 13205 12919 3 13207 12919 13205 3 12918 12920 13208 3 12918 13208 13206 3 12919 13207 12921 3 13209 12921 13207 3 12920 12922 13210 3 12920 13210 13208 3 12921 13209 12923 3 13211 12923 13209 3 12922 12924 13212 3 12922 13212 13210 3 12923 13211 12925 3 13213 12925 13211 3 12924 12926 13214 3 12924 13214 13212 3 12925 13213 12927 3 13215 12927 13213 3 12926 12928 13216 3 12926 13216 13214 3 12927 13215 12929 3 13217 12929 13215 3 12928 12930 13218 3 12928 13218 13216 3 12929 13217 12931 3 13219 12931 13217 3 12930 12932 13220 3 12930 13220 13218 3 12931 13219 12933 3 13221 12933 13219 3 12932 12934 13220 3 13222 13220 12934 3 12933 13221 12935 3 13223 12935 13221 3 12934 12936 13222 3 13224 13222 12936 3 12935 13223 12937 3 13225 12937 13223 3 12936 12938 13224 3 13226 13224 12938 3 12937 13225 12939 3 13227 12939 13225 3 12938 12940 13226 3 13228 13226 12940 3 12939 13227 12941 3 13229 12941 13227 3 12940 12942 13228 3 13230 13228 12942 3 12941 13229 12943 3 13231 12943 13229 3 12942 12944 13230 3 13232 13230 12944 3 12943 13231 12945 3 13233 12945 13231 3 12944 12946 13232 3 13234 13232 12946 3 12945 13233 12947 3 13235 12947 13233 3 12946 12948 13234 3 13236 13234 12948 3 12947 13235 12949 3 13237 12949 13235 3 12948 12950 13236 3 13238 13236 12950 3 12949 13237 12951 3 13239 12951 13237 3 12950 12952 13238 3 13240 13238 12952 3 12951 13239 12953 3 13241 12953 13239 3 12952 12954 13240 3 13242 13240 12954 3 12953 13241 12955 3 13243 12955 13241 3 12954 12956 13242 3 13244 13242 12956 3 12955 13243 12957 3 13245 12957 13243 3 12956 12958 13244 3 13246 13244 12958 3 12957 13245 12959 3 13247 12959 13245 3 12958 12960 13246 3 13248 13246 12960 3 12959 13247 12961 3 13249 12961 13247 3 12960 12962 13248 3 13250 13248 12962 3 12961 13249 12963 3 13251 12963 13249 3 12962 12964 13250 3 13252 13250 12964 3 12963 13251 12965 3 13253 12965 13251 3 12964 12966 13252 3 13254 13252 12966 3 12965 13253 12967 3 13255 12967 13253 3 12966 12968 13254 3 13256 13254 12968 3 12967 13255 12969 3 13257 12969 13255 3 12968 12970 13256 3 13258 13256 12970 3 12969 13257 12971 3 13259 12971 13257 3 12970 12972 13258 3 13260 13258 12972 3 12971 13259 12973 3 13261 12973 13259 3 12972 12974 13260 3 13262 13260 12974 3 12973 13261 12975 3 13263 12975 13261 3 12974 12976 13262 3 13264 13262 12976 3 12975 13263 12977 3 13265 12977 13263 3 12976 12978 13264 3 13266 13264 12978 3 12977 13265 12979 3 13267 12979 13265 3 12978 12980 13266 3 13268 13266 12980 3 12979 13267 13269 3 12979 13269 12981 3 12980 12982 13268 3 13270 13268 12982 3 12981 13269 13271 3 12981 13271 12983 3 12982 12984 13270 3 13272 13270 12984 3 12983 13271 13273 3 12983 13273 12985 3 12984 12986 13272 3 13274 13272 12986 3 12985 13273 13275 3 12985 13275 12987 3 12986 12988 13274 3 13276 13274 12988 3 12987 13275 13277 3 12987 13277 12989 3 12988 12990 13276 3 13278 13276 12990 3 12989 13277 13279 3 12989 13279 12991 3 12990 12992 13278 3 13280 13278 12992 3 12991 13279 13283 3 12991 13283 12995 3 12992 12993 13280 3 13281 13280 12993 3 12993 12996 13281 3 13284 13281 12996 3 12994 12995 13282 3 13283 13282 12995 3 12994 13282 13287 3 12994 13287 12999 3 12996 12997 13284 3 13285 13284 12997 3 12997 13000 13285 3 13288 13285 13000 3 12998 12999 13286 3 13287 13286 12999 3 12998 13286 13356 3 12998 13356 13068 3 13000 13001 13288 3 13289 13288 13001 3 13001 13002 13289 3 13290 13289 13002 3 13002 13003 13291 3 13002 13291 13290 3 13003 13004 13292 3 13003 13292 13291 3 13004 13005 13293 3 13004 13293 13292 3 13005 13006 13294 3 13005 13294 13293 3 13006 13007 13295 3 13006 13295 13294 3 13007 13008 13296 3 13007 13296 13295 3 13008 13009 13297 3 13008 13297 13296 3 13009 13010 13298 3 13009 13298 13297 3 13010 13011 13299 3 13010 13299 13298 3 13011 13012 13300 3 13011 13300 13299 3 13012 13013 13301 3 13012 13301 13300 3 13013 13014 13302 3 13013 13302 13301 3 13014 13015 13303 3 13014 13303 13302 3 13015 13016 13304 3 13015 13304 13303 3 13016 13017 13305 3 13016 13305 13304 3 13017 13018 13306 3 13017 13306 13305 3 13018 13019 13307 3 13018 13307 13306 3 13019 13020 13308 3 13019 13308 13307 3 13020 13021 13309 3 13020 13309 13308 3 13021 13022 13310 3 13021 13310 13309 3 13022 13023 13311 3 13022 13311 13310 3 13023 13024 13312 3 13023 13312 13311 3 13024 13025 13313 3 13024 13313 13312 3 13025 13026 13314 3 13025 13314 13313 3 13026 13027 13315 3 13026 13315 13314 3 13027 13028 13316 3 13027 13316 13315 3 13028 13029 13317 3 13028 13317 13316 3 13029 13030 13318 3 13029 13318 13317 3 13030 13031 13319 3 13030 13319 13318 3 13031 13032 13320 3 13031 13320 13319 3 13032 13033 13321 3 13032 13321 13320 3 13033 13034 13322 3 13033 13322 13321 3 13034 13035 13323 3 13034 13323 13322 3 13035 13036 13324 3 13035 13324 13323 3 13036 13037 13325 3 13036 13325 13324 3 13037 13038 13326 3 13037 13326 13325 3 13038 13039 13327 3 13038 13327 13326 3 13039 13040 13328 3 13039 13328 13327 3 13040 13041 13329 3 13040 13329 13328 3 13041 13042 13330 3 13041 13330 13329 3 13042 13043 13331 3 13042 13331 13330 3 13043 13044 13332 3 13043 13332 13331 3 13044 13045 13333 3 13044 13333 13332 3 13045 13046 13334 3 13045 13334 13333 3 13046 13047 13335 3 13046 13335 13334 3 13047 13048 13336 3 13047 13336 13335 3 13048 13049 13337 3 13048 13337 13336 3 13049 13050 13338 3 13049 13338 13337 3 13050 13051 13339 3 13050 13339 13338 3 13051 13052 13340 3 13051 13340 13339 3 13052 13053 13341 3 13052 13341 13340 3 13053 13054 13342 3 13053 13342 13341 3 13054 13055 13343 3 13054 13343 13342 3 13055 13056 13344 3 13055 13344 13343 3 13056 13057 13345 3 13056 13345 13344 3 13057 13058 13346 3 13057 13346 13345 3 13058 13059 13347 3 13058 13347 13346 3 13059 13060 13348 3 13059 13348 13347 3 13060 13061 13349 3 13060 13349 13348 3 13061 13062 13350 3 13061 13350 13349 3 13062 13063 13351 3 13062 13351 13350 3 13063 13064 13352 3 13063 13352 13351 3 13064 13065 13353 3 13064 13353 13352 3 13065 13066 13354 3 13065 13354 13353 3 13066 13067 13355 3 13066 13355 13354 3 13067 13068 13356 3 13067 13356 13355 3 13069 13357 13070 3 13358 13070 13357 3 13069 13139 13357 3 13427 13357 13139 3 13070 13358 13071 3 13359 13071 13358 3 13071 13359 13072 3 13360 13072 13359 3 13072 13360 13073 3 13361 13073 13360 3 13073 13361 13074 3 13362 13074 13361 3 13074 13362 13075 3 13363 13075 13362 3 13075 13363 13076 3 13364 13076 13363 3 13076 13364 13077 3 13365 13077 13364 3 13077 13365 13078 3 13366 13078 13365 3 13078 13366 13079 3 13367 13079 13366 3 13079 13367 13080 3 13368 13080 13367 3 13080 13368 13081 3 13369 13081 13368 3 13081 13369 13082 3 13370 13082 13369 3 13082 13370 13083 3 13371 13083 13370 3 13083 13371 13084 3 13372 13084 13371 3 13084 13372 13085 3 13373 13085 13372 3 13085 13373 13086 3 13374 13086 13373 3 13086 13374 13087 3 13375 13087 13374 3 13087 13375 13088 3 13376 13088 13375 3 13088 13376 13089 3 13377 13089 13376 3 13089 13377 13090 3 13378 13090 13377 3 13090 13378 13091 3 13379 13091 13378 3 13091 13379 13092 3 13380 13092 13379 3 13092 13380 13093 3 13381 13093 13380 3 13093 13381 13094 3 13382 13094 13381 3 13094 13382 13095 3 13383 13095 13382 3 13095 13383 13096 3 13384 13096 13383 3 13096 13384 13097 3 13385 13097 13384 3 13097 13385 13098 3 13386 13098 13385 3 13098 13386 13099 3 13387 13099 13386 3 13099 13387 13100 3 13388 13100 13387 3 13100 13388 13101 3 13389 13101 13388 3 13101 13389 13102 3 13390 13102 13389 3 13102 13390 13103 3 13391 13103 13390 3 13103 13391 13104 3 13392 13104 13391 3 13104 13392 13105 3 13393 13105 13392 3 13105 13393 13106 3 13394 13106 13393 3 13106 13394 13107 3 13395 13107 13394 3 13107 13395 13108 3 13396 13108 13395 3 13108 13396 13109 3 13397 13109 13396 3 13109 13397 13110 3 13398 13110 13397 3 13110 13398 13111 3 13399 13111 13398 3 13111 13399 13112 3 13400 13112 13399 3 13112 13400 13113 3 13401 13113 13400 3 13113 13401 13114 3 13402 13114 13401 3 13114 13402 13115 3 13403 13115 13402 3 13115 13403 13116 3 13404 13116 13403 3 13116 13404 13117 3 13405 13117 13404 3 13117 13405 13118 3 13406 13118 13405 3 13118 13406 13119 3 13407 13119 13406 3 13119 13407 13408 3 13119 13408 13120 3 13120 13408 13409 3 13120 13409 13121 3 13121 13409 13410 3 13121 13410 13122 3 13122 13410 13411 3 13122 13411 13123 3 13123 13411 13412 3 13123 13412 13124 3 13124 13412 13413 3 13124 13413 13125 3 13125 13413 13414 3 13125 13414 13126 3 13126 13414 13415 3 13126 13415 13127 3 13127 13415 13416 3 13127 13416 13128 3 13128 13416 13417 3 13128 13417 13129 3 13129 13417 13418 3 13129 13418 13130 3 13130 13418 13419 3 13130 13419 13131 3 13131 13419 13420 3 13131 13420 13132 3 13132 13420 13421 3 13132 13421 13133 3 13133 13421 13422 3 13133 13422 13134 3 13134 13422 13423 3 13134 13423 13135 3 13135 13423 13424 3 13135 13424 13136 3 13136 13424 13425 3 13136 13425 13137 3 13137 13425 13428 3 13137 13428 13140 3 13138 13426 13427 3 13138 13427 13139 3 13138 13143 13426 3 13431 13426 13143 3 13140 13428 13429 3 13140 13429 13141 3 13141 13429 13432 3 13141 13432 13144 3 13142 13430 13431 3 13142 13431 13143 3 13142 13146 13434 3 13142 13434 13430 3 13144 13432 13433 3 13144 13433 13145 3 13145 13433 13435 3 13145 13435 13147 3 13146 13148 13436 3 13146 13436 13434 3 13147 13435 13437 3 13147 13437 13149 3 13148 13150 13438 3 13148 13438 13436 3 13149 13437 13439 3 13149 13439 13151 3 13150 13152 13440 3 13150 13440 13438 3 13151 13439 13441 3 13151 13441 13153 3 13152 13154 13442 3 13152 13442 13440 3 13153 13441 13443 3 13153 13443 13155 3 13154 13156 13444 3 13154 13444 13442 3 13155 13443 13445 3 13155 13445 13157 3 13156 13158 13446 3 13156 13446 13444 3 13157 13445 13447 3 13157 13447 13159 3 13158 13160 13448 3 13158 13448 13446 3 13159 13447 13449 3 13159 13449 13161 3 13160 13162 13450 3 13160 13450 13448 3 13161 13449 13451 3 13161 13451 13163 3 13162 13164 13452 3 13162 13452 13450 3 13163 13451 13453 3 13163 13453 13165 3 13164 13166 13454 3 13164 13454 13452 3 13165 13453 13455 3 13165 13455 13167 3 13166 13168 13456 3 13166 13456 13454 3 13167 13455 13457 3 13167 13457 13169 3 13168 13170 13458 3 13168 13458 13456 3 13169 13457 13459 3 13169 13459 13171 3 13170 13172 13460 3 13170 13460 13458 3 13171 13459 13461 3 13171 13461 13173 3 13172 13174 13462 3 13172 13462 13460 3 13173 13461 13463 3 13173 13463 13175 3 13174 13176 13464 3 13174 13464 13462 3 13175 13463 13465 3 13175 13465 13177 3 13176 13178 13466 3 13176 13466 13464 3 13177 13465 13467 3 13177 13467 13179 3 13178 13180 13468 3 13178 13468 13466 3 13179 13467 13469 3 13179 13469 13181 3 13180 13182 13470 3 13180 13470 13468 3 13181 13469 13471 3 13181 13471 13183 3 13182 13184 13472 3 13182 13472 13470 3 13183 13471 13473 3 13183 13473 13185 3 13184 13186 13474 3 13184 13474 13472 3 13185 13473 13475 3 13185 13475 13187 3 13186 13188 13476 3 13186 13476 13474 3 13187 13475 13477 3 13187 13477 13189 3 13188 13190 13478 3 13188 13478 13476 3 13189 13477 13479 3 13189 13479 13191 3 13190 13192 13480 3 13190 13480 13478 3 13191 13479 13193 3 13481 13193 13479 3 13192 13194 13482 3 13192 13482 13480 3 13193 13481 13195 3 13483 13195 13481 3 13194 13196 13484 3 13194 13484 13482 3 13195 13483 13197 3 13485 13197 13483 3 13196 13198 13486 3 13196 13486 13484 3 13197 13485 13199 3 13487 13199 13485 3 13198 13200 13488 3 13198 13488 13486 3 13199 13487 13201 3 13489 13201 13487 3 13200 13202 13490 3 13200 13490 13488 3 13201 13489 13203 3 13491 13203 13489 3 13202 13204 13492 3 13202 13492 13490 3 13203 13491 13205 3 13493 13205 13491 3 13204 13206 13494 3 13204 13494 13492 3 13205 13493 13207 3 13495 13207 13493 3 13206 13208 13496 3 13206 13496 13494 3 13207 13495 13209 3 13497 13209 13495 3 13208 13210 13498 3 13208 13498 13496 3 13209 13497 13211 3 13499 13211 13497 3 13210 13212 13500 3 13210 13500 13498 3 13211 13499 13213 3 13501 13213 13499 3 13212 13214 13502 3 13212 13502 13500 3 13213 13501 13215 3 13503 13215 13501 3 13214 13216 13502 3 13504 13502 13216 3 13215 13503 13217 3 13505 13217 13503 3 13216 13218 13504 3 13506 13504 13218 3 13217 13505 13219 3 13507 13219 13505 3 13218 13220 13506 3 13508 13506 13220 3 13219 13507 13221 3 13509 13221 13507 3 13220 13222 13508 3 13510 13508 13222 3 13221 13509 13223 3 13511 13223 13509 3 13222 13224 13510 3 13512 13510 13224 3 13223 13511 13225 3 13513 13225 13511 3 13224 13226 13512 3 13514 13512 13226 3 13225 13513 13227 3 13515 13227 13513 3 13226 13228 13514 3 13516 13514 13228 3 13227 13515 13229 3 13517 13229 13515 3 13228 13230 13516 3 13518 13516 13230 3 13229 13517 13231 3 13519 13231 13517 3 13230 13232 13518 3 13520 13518 13232 3 13231 13519 13233 3 13521 13233 13519 3 13232 13234 13520 3 13522 13520 13234 3 13233 13521 13235 3 13523 13235 13521 3 13234 13236 13522 3 13524 13522 13236 3 13235 13523 13237 3 13525 13237 13523 3 13236 13238 13524 3 13526 13524 13238 3 13237 13525 13239 3 13527 13239 13525 3 13238 13240 13526 3 13528 13526 13240 3 13239 13527 13241 3 13529 13241 13527 3 13240 13242 13528 3 13530 13528 13242 3 13241 13529 13243 3 13531 13243 13529 3 13242 13244 13530 3 13532 13530 13244 3 13243 13531 13245 3 13533 13245 13531 3 13244 13246 13532 3 13534 13532 13246 3 13245 13533 13247 3 13535 13247 13533 3 13246 13248 13534 3 13536 13534 13248 3 13247 13535 13249 3 13537 13249 13535 3 13248 13250 13536 3 13538 13536 13250 3 13249 13537 13251 3 13539 13251 13537 3 13250 13252 13538 3 13540 13538 13252 3 13251 13539 13253 3 13541 13253 13539 3 13252 13254 13540 3 13542 13540 13254 3 13253 13541 13255 3 13543 13255 13541 3 13254 13256 13542 3 13544 13542 13256 3 13255 13543 13257 3 13545 13257 13543 3 13256 13258 13544 3 13546 13544 13258 3 13257 13545 13259 3 13547 13259 13545 3 13258 13260 13546 3 13548 13546 13260 3 13259 13547 13261 3 13549 13261 13547 3 13260 13262 13548 3 13550 13548 13262 3 13261 13549 13263 3 13551 13263 13549 3 13262 13264 13550 3 13552 13550 13264 3 13263 13551 13553 3 13263 13553 13265 3 13264 13266 13552 3 13554 13552 13266 3 13265 13553 13555 3 13265 13555 13267 3 13266 13268 13554 3 13556 13554 13268 3 13267 13555 13557 3 13267 13557 13269 3 13268 13270 13556 3 13558 13556 13270 3 13269 13557 13559 3 13269 13559 13271 3 13270 13272 13558 3 13560 13558 13272 3 13271 13559 13561 3 13271 13561 13273 3 13272 13274 13560 3 13562 13560 13274 3 13273 13561 13563 3 13273 13563 13275 3 13274 13276 13562 3 13564 13562 13276 3 13275 13563 13565 3 13275 13565 13277 3 13276 13278 13564 3 13566 13564 13278 3 13277 13565 13567 3 13277 13567 13279 3 13278 13280 13566 3 13568 13566 13280 3 13279 13567 13571 3 13279 13571 13283 3 13280 13281 13568 3 13569 13568 13281 3 13281 13284 13569 3 13572 13569 13284 3 13282 13283 13570 3 13571 13570 13283 3 13282 13570 13575 3 13282 13575 13287 3 13284 13285 13573 3 13284 13573 13572 3 13285 13288 13576 3 13285 13576 13573 3 13286 13287 13575 3 13286 13575 13574 3 13286 13574 13644 3 13286 13644 13356 3 13288 13289 13577 3 13288 13577 13576 3 13289 13290 13578 3 13289 13578 13577 3 13290 13291 13579 3 13290 13579 13578 3 13291 13292 13580 3 13291 13580 13579 3 13292 13293 13581 3 13292 13581 13580 3 13293 13294 13582 3 13293 13582 13581 3 13294 13295 13583 3 13294 13583 13582 3 13295 13296 13584 3 13295 13584 13583 3 13296 13297 13585 3 13296 13585 13584 3 13297 13298 13586 3 13297 13586 13585 3 13298 13299 13587 3 13298 13587 13586 3 13299 13300 13588 3 13299 13588 13587 3 13300 13301 13589 3 13300 13589 13588 3 13301 13302 13590 3 13301 13590 13589 3 13302 13303 13591 3 13302 13591 13590 3 13303 13304 13592 3 13303 13592 13591 3 13304 13305 13593 3 13304 13593 13592 3 13305 13306 13594 3 13305 13594 13593 3 13306 13307 13595 3 13306 13595 13594 3 13307 13308 13596 3 13307 13596 13595 3 13308 13309 13597 3 13308 13597 13596 3 13309 13310 13598 3 13309 13598 13597 3 13310 13311 13599 3 13310 13599 13598 3 13311 13312 13600 3 13311 13600 13599 3 13312 13313 13601 3 13312 13601 13600 3 13313 13314 13602 3 13313 13602 13601 3 13314 13315 13603 3 13314 13603 13602 3 13315 13316 13604 3 13315 13604 13603 3 13316 13317 13605 3 13316 13605 13604 3 13317 13318 13606 3 13317 13606 13605 3 13318 13319 13607 3 13318 13607 13606 3 13319 13320 13608 3 13319 13608 13607 3 13320 13321 13609 3 13320 13609 13608 3 13321 13322 13610 3 13321 13610 13609 3 13322 13323 13611 3 13322 13611 13610 3 13323 13324 13612 3 13323 13612 13611 3 13324 13325 13613 3 13324 13613 13612 3 13325 13326 13614 3 13325 13614 13613 3 13326 13327 13615 3 13326 13615 13614 3 13327 13328 13616 3 13327 13616 13615 3 13328 13329 13617 3 13328 13617 13616 3 13329 13330 13618 3 13329 13618 13617 3 13330 13331 13619 3 13330 13619 13618 3 13331 13332 13620 3 13331 13620 13619 3 13332 13333 13621 3 13332 13621 13620 3 13333 13334 13622 3 13333 13622 13621 3 13334 13335 13623 3 13334 13623 13622 3 13335 13336 13624 3 13335 13624 13623 3 13336 13337 13625 3 13336 13625 13624 3 13337 13338 13626 3 13337 13626 13625 3 13338 13339 13627 3 13338 13627 13626 3 13339 13340 13628 3 13339 13628 13627 3 13340 13341 13629 3 13340 13629 13628 3 13341 13342 13630 3 13341 13630 13629 3 13342 13343 13631 3 13342 13631 13630 3 13343 13344 13632 3 13343 13632 13631 3 13344 13345 13633 3 13344 13633 13632 3 13345 13346 13634 3 13345 13634 13633 3 13346 13347 13635 3 13346 13635 13634 3 13347 13348 13636 3 13347 13636 13635 3 13348 13349 13637 3 13348 13637 13636 3 13349 13350 13638 3 13349 13638 13637 3 13350 13351 13639 3 13350 13639 13638 3 13351 13352 13640 3 13351 13640 13639 3 13352 13353 13641 3 13352 13641 13640 3 13353 13354 13642 3 13353 13642 13641 3 13354 13355 13643 3 13354 13643 13642 3 13355 13356 13643 3 13644 13643 13356 3 13357 13645 13358 3 13646 13358 13645 3 13357 13427 13645 3 13715 13645 13427 3 13358 13646 13359 3 13647 13359 13646 3 13359 13647 13360 3 13648 13360 13647 3 13360 13648 13361 3 13649 13361 13648 3 13361 13649 13362 3 13650 13362 13649 3 13362 13650 13363 3 13651 13363 13650 3 13363 13651 13364 3 13652 13364 13651 3 13364 13652 13365 3 13653 13365 13652 3 13365 13653 13366 3 13654 13366 13653 3 13366 13654 13367 3 13655 13367 13654 3 13367 13655 13368 3 13656 13368 13655 3 13368 13656 13369 3 13657 13369 13656 3 13369 13657 13370 3 13658 13370 13657 3 13370 13658 13371 3 13659 13371 13658 3 13371 13659 13372 3 13660 13372 13659 3 13372 13660 13373 3 13661 13373 13660 3 13373 13661 13374 3 13662 13374 13661 3 13374 13662 13375 3 13663 13375 13662 3 13375 13663 13376 3 13664 13376 13663 3 13376 13664 13377 3 13665 13377 13664 3 13377 13665 13378 3 13666 13378 13665 3 13378 13666 13379 3 13667 13379 13666 3 13379 13667 13380 3 13668 13380 13667 3 13380 13668 13381 3 13669 13381 13668 3 13381 13669 13382 3 13670 13382 13669 3 13382 13670 13383 3 13671 13383 13670 3 13383 13671 13384 3 13672 13384 13671 3 13384 13672 13385 3 13673 13385 13672 3 13385 13673 13386 3 13674 13386 13673 3 13386 13674 13387 3 13675 13387 13674 3 13387 13675 13388 3 13676 13388 13675 3 13388 13676 13389 3 13677 13389 13676 3 13389 13677 13390 3 13678 13390 13677 3 13390 13678 13391 3 13679 13391 13678 3 13391 13679 13392 3 13680 13392 13679 3 13392 13680 13393 3 13681 13393 13680 3 13393 13681 13394 3 13682 13394 13681 3 13394 13682 13395 3 13683 13395 13682 3 13395 13683 13396 3 13684 13396 13683 3 13396 13684 13397 3 13685 13397 13684 3 13397 13685 13398 3 13686 13398 13685 3 13398 13686 13399 3 13687 13399 13686 3 13399 13687 13400 3 13688 13400 13687 3 13400 13688 13401 3 13689 13401 13688 3 13401 13689 13402 3 13690 13402 13689 3 13402 13690 13403 3 13691 13403 13690 3 13403 13691 13404 3 13692 13404 13691 3 13404 13692 13405 3 13693 13405 13692 3 13405 13693 13694 3 13405 13694 13406 3 13406 13694 13695 3 13406 13695 13407 3 13407 13695 13696 3 13407 13696 13408 3 13408 13696 13697 3 13408 13697 13409 3 13409 13697 13698 3 13409 13698 13410 3 13410 13698 13699 3 13410 13699 13411 3 13411 13699 13700 3 13411 13700 13412 3 13412 13700 13701 3 13412 13701 13413 3 13413 13701 13702 3 13413 13702 13414 3 13414 13702 13703 3 13414 13703 13415 3 13415 13703 13704 3 13415 13704 13416 3 13416 13704 13705 3 13416 13705 13417 3 13417 13705 13706 3 13417 13706 13418 3 13418 13706 13707 3 13418 13707 13419 3 13419 13707 13708 3 13419 13708 13420 3 13420 13708 13709 3 13420 13709 13421 3 13421 13709 13710 3 13421 13710 13422 3 13422 13710 13711 3 13422 13711 13423 3 13423 13711 13712 3 13423 13712 13424 3 13424 13712 13713 3 13424 13713 13425 3 13425 13713 13716 3 13425 13716 13428 3 13426 13714 13715 3 13426 13715 13427 3 13426 13431 13719 3 13426 13719 13714 3 13428 13716 13717 3 13428 13717 13429 3 13429 13717 13720 3 13429 13720 13432 3 13430 13718 13719 3 13430 13719 13431 3 13430 13434 13722 3 13430 13722 13718 3 13432 13720 13721 3 13432 13721 13433 3 13433 13721 13723 3 13433 13723 13435 3 13434 13436 13724 3 13434 13724 13722 3 13435 13723 13725 3 13435 13725 13437 3 13436 13438 13726 3 13436 13726 13724 3 13437 13725 13727 3 13437 13727 13439 3 13438 13440 13728 3 13438 13728 13726 3 13439 13727 13729 3 13439 13729 13441 3 13440 13442 13730 3 13440 13730 13728 3 13441 13729 13731 3 13441 13731 13443 3 13442 13444 13732 3 13442 13732 13730 3 13443 13731 13733 3 13443 13733 13445 3 13444 13446 13734 3 13444 13734 13732 3 13445 13733 13735 3 13445 13735 13447 3 13446 13448 13736 3 13446 13736 13734 3 13447 13735 13737 3 13447 13737 13449 3 13448 13450 13738 3 13448 13738 13736 3 13449 13737 13739 3 13449 13739 13451 3 13450 13452 13740 3 13450 13740 13738 3 13451 13739 13741 3 13451 13741 13453 3 13452 13454 13742 3 13452 13742 13740 3 13453 13741 13743 3 13453 13743 13455 3 13454 13456 13744 3 13454 13744 13742 3 13455 13743 13745 3 13455 13745 13457 3 13456 13458 13746 3 13456 13746 13744 3 13457 13745 13747 3 13457 13747 13459 3 13458 13460 13748 3 13458 13748 13746 3 13459 13747 13749 3 13459 13749 13461 3 13460 13462 13750 3 13460 13750 13748 3 13461 13749 13751 3 13461 13751 13463 3 13462 13464 13752 3 13462 13752 13750 3 13463 13751 13753 3 13463 13753 13465 3 13464 13466 13754 3 13464 13754 13752 3 13465 13753 13755 3 13465 13755 13467 3 13466 13468 13756 3 13466 13756 13754 3 13467 13755 13757 3 13467 13757 13469 3 13468 13470 13758 3 13468 13758 13756 3 13469 13757 13759 3 13469 13759 13471 3 13470 13472 13760 3 13470 13760 13758 3 13471 13759 13761 3 13471 13761 13473 3 13472 13474 13762 3 13472 13762 13760 3 13473 13761 13763 3 13473 13763 13475 3 13474 13476 13764 3 13474 13764 13762 3 13475 13763 13765 3 13475 13765 13477 3 13476 13478 13766 3 13476 13766 13764 3 13477 13765 13479 3 13767 13479 13765 3 13478 13480 13768 3 13478 13768 13766 3 13479 13767 13481 3 13769 13481 13767 3 13480 13482 13770 3 13480 13770 13768 3 13481 13769 13483 3 13771 13483 13769 3 13482 13484 13772 3 13482 13772 13770 3 13483 13771 13485 3 13773 13485 13771 3 13484 13486 13774 3 13484 13774 13772 3 13485 13773 13487 3 13775 13487 13773 3 13486 13488 13776 3 13486 13776 13774 3 13487 13775 13489 3 13777 13489 13775 3 13488 13490 13778 3 13488 13778 13776 3 13489 13777 13491 3 13779 13491 13777 3 13490 13492 13780 3 13490 13780 13778 3 13491 13779 13493 3 13781 13493 13779 3 13492 13494 13782 3 13492 13782 13780 3 13493 13781 13495 3 13783 13495 13781 3 13494 13496 13784 3 13494 13784 13782 3 13495 13783 13497 3 13785 13497 13783 3 13496 13498 13786 3 13496 13786 13784 3 13497 13785 13499 3 13787 13499 13785 3 13498 13500 13786 3 13788 13786 13500 3 13499 13787 13501 3 13789 13501 13787 3 13500 13502 13788 3 13790 13788 13502 3 13501 13789 13503 3 13791 13503 13789 3 13502 13504 13790 3 13792 13790 13504 3 13503 13791 13505 3 13793 13505 13791 3 13504 13506 13792 3 13794 13792 13506 3 13505 13793 13507 3 13795 13507 13793 3 13506 13508 13794 3 13796 13794 13508 3 13507 13795 13509 3 13797 13509 13795 3 13508 13510 13796 3 13798 13796 13510 3 13509 13797 13511 3 13799 13511 13797 3 13510 13512 13798 3 13800 13798 13512 3 13511 13799 13513 3 13801 13513 13799 3 13512 13514 13800 3 13802 13800 13514 3 13513 13801 13515 3 13803 13515 13801 3 13514 13516 13802 3 13804 13802 13516 3 13515 13803 13517 3 13805 13517 13803 3 13516 13518 13804 3 13806 13804 13518 3 13517 13805 13519 3 13807 13519 13805 3 13518 13520 13806 3 13808 13806 13520 3 13519 13807 13521 3 13809 13521 13807 3 13520 13522 13808 3 13810 13808 13522 3 13521 13809 13523 3 13811 13523 13809 3 13522 13524 13810 3 13812 13810 13524 3 13523 13811 13525 3 13813 13525 13811 3 13524 13526 13812 3 13814 13812 13526 3 13525 13813 13527 3 13815 13527 13813 3 13526 13528 13814 3 13816 13814 13528 3 13527 13815 13529 3 13817 13529 13815 3 13528 13530 13816 3 13818 13816 13530 3 13529 13817 13531 3 13819 13531 13817 3 13530 13532 13818 3 13820 13818 13532 3 13531 13819 13533 3 13821 13533 13819 3 13532 13534 13820 3 13822 13820 13534 3 13533 13821 13535 3 13823 13535 13821 3 13534 13536 13822 3 13824 13822 13536 3 13535 13823 13537 3 13825 13537 13823 3 13536 13538 13824 3 13826 13824 13538 3 13537 13825 13539 3 13827 13539 13825 3 13538 13540 13826 3 13828 13826 13540 3 13539 13827 13541 3 13829 13541 13827 3 13540 13542 13828 3 13830 13828 13542 3 13541 13829 13543 3 13831 13543 13829 3 13542 13544 13830 3 13832 13830 13544 3 13543 13831 13545 3 13833 13545 13831 3 13544 13546 13832 3 13834 13832 13546 3 13545 13833 13547 3 13835 13547 13833 3 13546 13548 13834 3 13836 13834 13548 3 13547 13835 13549 3 13837 13549 13835 3 13548 13550 13836 3 13838 13836 13550 3 13549 13837 13839 3 13549 13839 13551 3 13550 13552 13838 3 13840 13838 13552 3 13551 13839 13841 3 13551 13841 13553 3 13552 13554 13840 3 13842 13840 13554 3 13553 13841 13843 3 13553 13843 13555 3 13554 13556 13842 3 13844 13842 13556 3 13555 13843 13845 3 13555 13845 13557 3 13556 13558 13844 3 13846 13844 13558 3 13557 13845 13847 3 13557 13847 13559 3 13558 13560 13846 3 13848 13846 13560 3 13559 13847 13849 3 13559 13849 13561 3 13560 13562 13848 3 13850 13848 13562 3 13561 13849 13851 3 13561 13851 13563 3 13562 13564 13850 3 13852 13850 13564 3 13563 13851 13853 3 13563 13853 13565 3 13564 13566 13852 3 13854 13852 13566 3 13565 13853 13855 3 13565 13855 13567 3 13566 13568 13854 3 13856 13854 13568 3 13567 13855 13859 3 13567 13859 13571 3 13568 13569 13856 3 13857 13856 13569 3 13569 13572 13860 3 13569 13860 13857 3 13570 13571 13859 3 13570 13859 13858 3 13570 13858 13863 3 13570 13863 13575 3 13572 13573 13861 3 13572 13861 13860 3 13573 13576 13864 3 13573 13864 13861 3 13574 13575 13863 3 13574 13863 13862 3 13574 13862 13932 3 13574 13932 13644 3 13576 13577 13865 3 13576 13865 13864 3 13577 13578 13866 3 13577 13866 13865 3 13578 13579 13867 3 13578 13867 13866 3 13579 13580 13868 3 13579 13868 13867 3 13580 13581 13869 3 13580 13869 13868 3 13581 13582 13870 3 13581 13870 13869 3 13582 13583 13871 3 13582 13871 13870 3 13583 13584 13872 3 13583 13872 13871 3 13584 13585 13873 3 13584 13873 13872 3 13585 13586 13874 3 13585 13874 13873 3 13586 13587 13875 3 13586 13875 13874 3 13587 13588 13876 3 13587 13876 13875 3 13588 13589 13877 3 13588 13877 13876 3 13589 13590 13878 3 13589 13878 13877 3 13590 13591 13879 3 13590 13879 13878 3 13591 13592 13880 3 13591 13880 13879 3 13592 13593 13881 3 13592 13881 13880 3 13593 13594 13882 3 13593 13882 13881 3 13594 13595 13883 3 13594 13883 13882 3 13595 13596 13884 3 13595 13884 13883 3 13596 13597 13885 3 13596 13885 13884 3 13597 13598 13886 3 13597 13886 13885 3 13598 13599 13887 3 13598 13887 13886 3 13599 13600 13888 3 13599 13888 13887 3 13600 13601 13889 3 13600 13889 13888 3 13601 13602 13890 3 13601 13890 13889 3 13602 13603 13891 3 13602 13891 13890 3 13603 13604 13892 3 13603 13892 13891 3 13604 13605 13893 3 13604 13893 13892 3 13605 13606 13894 3 13605 13894 13893 3 13606 13607 13895 3 13606 13895 13894 3 13607 13608 13896 3 13607 13896 13895 3 13608 13609 13897 3 13608 13897 13896 3 13609 13610 13898 3 13609 13898 13897 3 13610 13611 13899 3 13610 13899 13898 3 13611 13612 13900 3 13611 13900 13899 3 13612 13613 13901 3 13612 13901 13900 3 13613 13614 13902 3 13613 13902 13901 3 13614 13615 13903 3 13614 13903 13902 3 13615 13616 13904 3 13615 13904 13903 3 13616 13617 13905 3 13616 13905 13904 3 13617 13618 13906 3 13617 13906 13905 3 13618 13619 13907 3 13618 13907 13906 3 13619 13620 13908 3 13619 13908 13907 3 13620 13621 13909 3 13620 13909 13908 3 13621 13622 13910 3 13621 13910 13909 3 13622 13623 13911 3 13622 13911 13910 3 13623 13624 13912 3 13623 13912 13911 3 13624 13625 13913 3 13624 13913 13912 3 13625 13626 13914 3 13625 13914 13913 3 13626 13627 13915 3 13626 13915 13914 3 13627 13628 13916 3 13627 13916 13915 3 13628 13629 13917 3 13628 13917 13916 3 13629 13630 13918 3 13629 13918 13917 3 13630 13631 13919 3 13630 13919 13918 3 13631 13632 13920 3 13631 13920 13919 3 13632 13633 13921 3 13632 13921 13920 3 13633 13634 13922 3 13633 13922 13921 3 13634 13635 13923 3 13634 13923 13922 3 13635 13636 13924 3 13635 13924 13923 3 13636 13637 13925 3 13636 13925 13924 3 13637 13638 13926 3 13637 13926 13925 3 13638 13639 13927 3 13638 13927 13926 3 13639 13640 13928 3 13639 13928 13927 3 13640 13641 13929 3 13640 13929 13928 3 13641 13642 13929 3 13930 13929 13642 3 13642 13643 13930 3 13931 13930 13643 3 13643 13644 13931 3 13932 13931 13644 3 13645 13933 13646 3 13934 13646 13933 3 13645 13715 13933 3 14003 13933 13715 3 13646 13934 13647 3 13935 13647 13934 3 13647 13935 13648 3 13936 13648 13935 3 13648 13936 13649 3 13937 13649 13936 3 13649 13937 13650 3 13938 13650 13937 3 13650 13938 13651 3 13939 13651 13938 3 13651 13939 13652 3 13940 13652 13939 3 13652 13940 13653 3 13941 13653 13940 3 13653 13941 13654 3 13942 13654 13941 3 13654 13942 13655 3 13943 13655 13942 3 13655 13943 13656 3 13944 13656 13943 3 13656 13944 13657 3 13945 13657 13944 3 13657 13945 13658 3 13946 13658 13945 3 13658 13946 13659 3 13947 13659 13946 3 13659 13947 13660 3 13948 13660 13947 3 13660 13948 13661 3 13949 13661 13948 3 13661 13949 13662 3 13950 13662 13949 3 13662 13950 13663 3 13951 13663 13950 3 13663 13951 13664 3 13952 13664 13951 3 13664 13952 13665 3 13953 13665 13952 3 13665 13953 13666 3 13954 13666 13953 3 13666 13954 13667 3 13955 13667 13954 3 13667 13955 13668 3 13956 13668 13955 3 13668 13956 13669 3 13957 13669 13956 3 13669 13957 13670 3 13958 13670 13957 3 13670 13958 13671 3 13959 13671 13958 3 13671 13959 13672 3 13960 13672 13959 3 13672 13960 13673 3 13961 13673 13960 3 13673 13961 13674 3 13962 13674 13961 3 13674 13962 13675 3 13963 13675 13962 3 13675 13963 13676 3 13964 13676 13963 3 13676 13964 13677 3 13965 13677 13964 3 13677 13965 13678 3 13966 13678 13965 3 13678 13966 13679 3 13967 13679 13966 3 13679 13967 13680 3 13968 13680 13967 3 13680 13968 13681 3 13969 13681 13968 3 13681 13969 13682 3 13970 13682 13969 3 13682 13970 13683 3 13971 13683 13970 3 13683 13971 13684 3 13972 13684 13971 3 13684 13972 13685 3 13973 13685 13972 3 13685 13973 13686 3 13974 13686 13973 3 13686 13974 13687 3 13975 13687 13974 3 13687 13975 13688 3 13976 13688 13975 3 13688 13976 13689 3 13977 13689 13976 3 13689 13977 13690 3 13978 13690 13977 3 13690 13978 13691 3 13979 13691 13978 3 13691 13979 13692 3 13980 13692 13979 3 13692 13980 13693 3 13981 13693 13980 3 13693 13981 13982 3 13693 13982 13694 3 13694 13982 13983 3 13694 13983 13695 3 13695 13983 13984 3 13695 13984 13696 3 13696 13984 13985 3 13696 13985 13697 3 13697 13985 13986 3 13697 13986 13698 3 13698 13986 13987 3 13698 13987 13699 3 13699 13987 13988 3 13699 13988 13700 3 13700 13988 13989 3 13700 13989 13701 3 13701 13989 13990 3 13701 13990 13702 3 13702 13990 13991 3 13702 13991 13703 3 13703 13991 13992 3 13703 13992 13704 3 13704 13992 13993 3 13704 13993 13705 3 13705 13993 13994 3 13705 13994 13706 3 13706 13994 13995 3 13706 13995 13707 3 13707 13995 13996 3 13707 13996 13708 3 13708 13996 13997 3 13708 13997 13709 3 13709 13997 13998 3 13709 13998 13710 3 13710 13998 13999 3 13710 13999 13711 3 13711 13999 14000 3 13711 14000 13712 3 13712 14000 14001 3 13712 14001 13713 3 13713 14001 14004 3 13713 14004 13716 3 13714 14002 14003 3 13714 14003 13715 3 13714 13719 14007 3 13714 14007 14002 3 13716 14004 14005 3 13716 14005 13717 3 13717 14005 14008 3 13717 14008 13720 3 13718 14006 14007 3 13718 14007 13719 3 13718 13722 14010 3 13718 14010 14006 3 13720 14008 14009 3 13720 14009 13721 3 13721 14009 14011 3 13721 14011 13723 3 13722 13724 14012 3 13722 14012 14010 3 13723 14011 14013 3 13723 14013 13725 3 13724 13726 14014 3 13724 14014 14012 3 13725 14013 14015 3 13725 14015 13727 3 13726 13728 14016 3 13726 14016 14014 3 13727 14015 14017 3 13727 14017 13729 3 13728 13730 14018 3 13728 14018 14016 3 13729 14017 14019 3 13729 14019 13731 3 13730 13732 14020 3 13730 14020 14018 3 13731 14019 14021 3 13731 14021 13733 3 13732 13734 14022 3 13732 14022 14020 3 13733 14021 14023 3 13733 14023 13735 3 13734 13736 14024 3 13734 14024 14022 3 13735 14023 14025 3 13735 14025 13737 3 13736 13738 14026 3 13736 14026 14024 3 13737 14025 14027 3 13737 14027 13739 3 13738 13740 14028 3 13738 14028 14026 3 13739 14027 14029 3 13739 14029 13741 3 13740 13742 14030 3 13740 14030 14028 3 13741 14029 14031 3 13741 14031 13743 3 13742 13744 14032 3 13742 14032 14030 3 13743 14031 14033 3 13743 14033 13745 3 13744 13746 14034 3 13744 14034 14032 3 13745 14033 14035 3 13745 14035 13747 3 13746 13748 14036 3 13746 14036 14034 3 13747 14035 14037 3 13747 14037 13749 3 13748 13750 14038 3 13748 14038 14036 3 13749 14037 14039 3 13749 14039 13751 3 13750 13752 14040 3 13750 14040 14038 3 13751 14039 14041 3 13751 14041 13753 3 13752 13754 14042 3 13752 14042 14040 3 13753 14041 14043 3 13753 14043 13755 3 13754 13756 14044 3 13754 14044 14042 3 13755 14043 14045 3 13755 14045 13757 3 13756 13758 14046 3 13756 14046 14044 3 13757 14045 14047 3 13757 14047 13759 3 13758 13760 14048 3 13758 14048 14046 3 13759 14047 14049 3 13759 14049 13761 3 13760 13762 14050 3 13760 14050 14048 3 13761 14049 14051 3 13761 14051 13763 3 13762 13764 14052 3 13762 14052 14050 3 13763 14051 14053 3 13763 14053 13765 3 13764 13766 14054 3 13764 14054 14052 3 13765 14053 14055 3 13765 14055 13767 3 13766 13768 14056 3 13766 14056 14054 3 13767 14055 13769 3 14057 13769 14055 3 13768 13770 14058 3 13768 14058 14056 3 13769 14057 13771 3 14059 13771 14057 3 13770 13772 14060 3 13770 14060 14058 3 13771 14059 13773 3 14061 13773 14059 3 13772 13774 14062 3 13772 14062 14060 3 13773 14061 13775 3 14063 13775 14061 3 13774 13776 14064 3 13774 14064 14062 3 13775 14063 13777 3 14065 13777 14063 3 13776 13778 14066 3 13776 14066 14064 3 13777 14065 13779 3 14067 13779 14065 3 13778 13780 14068 3 13778 14068 14066 3 13779 14067 13781 3 14069 13781 14067 3 13780 13782 14070 3 13780 14070 14068 3 13781 14069 13783 3 14071 13783 14069 3 13782 13784 14072 3 13782 14072 14070 3 13783 14071 13785 3 14073 13785 14071 3 13784 13786 14074 3 13784 14074 14072 3 13785 14073 13787 3 14075 13787 14073 3 13786 13788 14074 3 14076 14074 13788 3 13787 14075 13789 3 14077 13789 14075 3 13788 13790 14076 3 14078 14076 13790 3 13789 14077 13791 3 14079 13791 14077 3 13790 13792 14078 3 14080 14078 13792 3 13791 14079 13793 3 14081 13793 14079 3 13792 13794 14080 3 14082 14080 13794 3 13793 14081 13795 3 14083 13795 14081 3 13794 13796 14082 3 14084 14082 13796 3 13795 14083 13797 3 14085 13797 14083 3 13796 13798 14084 3 14086 14084 13798 3 13797 14085 13799 3 14087 13799 14085 3 13798 13800 14086 3 14088 14086 13800 3 13799 14087 13801 3 14089 13801 14087 3 13800 13802 14088 3 14090 14088 13802 3 13801 14089 13803 3 14091 13803 14089 3 13802 13804 14090 3 14092 14090 13804 3 13803 14091 13805 3 14093 13805 14091 3 13804 13806 14092 3 14094 14092 13806 3 13805 14093 13807 3 14095 13807 14093 3 13806 13808 14094 3 14096 14094 13808 3 13807 14095 13809 3 14097 13809 14095 3 13808 13810 14096 3 14098 14096 13810 3 13809 14097 13811 3 14099 13811 14097 3 13810 13812 14098 3 14100 14098 13812 3 13811 14099 13813 3 14101 13813 14099 3 13812 13814 14100 3 14102 14100 13814 3 13813 14101 13815 3 14103 13815 14101 3 13814 13816 14102 3 14104 14102 13816 3 13815 14103 13817 3 14105 13817 14103 3 13816 13818 14104 3 14106 14104 13818 3 13817 14105 13819 3 14107 13819 14105 3 13818 13820 14106 3 14108 14106 13820 3 13819 14107 13821 3 14109 13821 14107 3 13820 13822 14108 3 14110 14108 13822 3 13821 14109 13823 3 14111 13823 14109 3 13822 13824 14110 3 14112 14110 13824 3 13823 14111 13825 3 14113 13825 14111 3 13824 13826 14112 3 14114 14112 13826 3 13825 14113 13827 3 14115 13827 14113 3 13826 13828 14114 3 14116 14114 13828 3 13827 14115 13829 3 14117 13829 14115 3 13828 13830 14116 3 14118 14116 13830 3 13829 14117 13831 3 14119 13831 14117 3 13830 13832 14118 3 14120 14118 13832 3 13831 14119 13833 3 14121 13833 14119 3 13832 13834 14120 3 14122 14120 13834 3 13833 14121 13835 3 14123 13835 14121 3 13834 13836 14122 3 14124 14122 13836 3 13835 14123 13837 3 14125 13837 14123 3 13836 13838 14124 3 14126 14124 13838 3 13837 14125 13839 3 14127 13839 14125 3 13838 13840 14126 3 14128 14126 13840 3 13839 14127 14129 3 13839 14129 13841 3 13840 13842 14128 3 14130 14128 13842 3 13841 14129 14131 3 13841 14131 13843 3 13842 13844 14130 3 14132 14130 13844 3 13843 14131 14133 3 13843 14133 13845 3 13844 13846 14132 3 14134 14132 13846 3 13845 14133 14135 3 13845 14135 13847 3 13846 13848 14134 3 14136 14134 13848 3 13847 14135 14137 3 13847 14137 13849 3 13848 13850 14136 3 14138 14136 13850 3 13849 14137 14139 3 13849 14139 13851 3 13850 13852 14138 3 14140 14138 13852 3 13851 14139 14141 3 13851 14141 13853 3 13852 13854 14140 3 14142 14140 13854 3 13853 14141 14143 3 13853 14143 13855 3 13854 13856 14142 3 14144 14142 13856 3 13855 14143 14147 3 13855 14147 13859 3 13856 13857 14144 3 14145 14144 13857 3 13857 13860 14148 3 13857 14148 14145 3 13858 13859 14147 3 13858 14147 14146 3 13858 14146 14151 3 13858 14151 13863 3 13860 13861 14149 3 13860 14149 14148 3 13861 13864 14152 3 13861 14152 14149 3 13862 13863 14151 3 13862 14151 14150 3 13862 14150 14220 3 13862 14220 13932 3 13864 13865 14153 3 13864 14153 14152 3 13865 13866 14154 3 13865 14154 14153 3 13866 13867 14155 3 13866 14155 14154 3 13867 13868 14156 3 13867 14156 14155 3 13868 13869 14157 3 13868 14157 14156 3 13869 13870 14158 3 13869 14158 14157 3 13870 13871 14159 3 13870 14159 14158 3 13871 13872 14160 3 13871 14160 14159 3 13872 13873 14161 3 13872 14161 14160 3 13873 13874 14162 3 13873 14162 14161 3 13874 13875 14163 3 13874 14163 14162 3 13875 13876 14164 3 13875 14164 14163 3 13876 13877 14165 3 13876 14165 14164 3 13877 13878 14166 3 13877 14166 14165 3 13878 13879 14167 3 13878 14167 14166 3 13879 13880 14168 3 13879 14168 14167 3 13880 13881 14169 3 13880 14169 14168 3 13881 13882 14170 3 13881 14170 14169 3 13882 13883 14171 3 13882 14171 14170 3 13883 13884 14172 3 13883 14172 14171 3 13884 13885 14173 3 13884 14173 14172 3 13885 13886 14174 3 13885 14174 14173 3 13886 13887 14175 3 13886 14175 14174 3 13887 13888 14176 3 13887 14176 14175 3 13888 13889 14177 3 13888 14177 14176 3 13889 13890 14178 3 13889 14178 14177 3 13890 13891 14179 3 13890 14179 14178 3 13891 13892 14180 3 13891 14180 14179 3 13892 13893 14181 3 13892 14181 14180 3 13893 13894 14182 3 13893 14182 14181 3 13894 13895 14183 3 13894 14183 14182 3 13895 13896 14184 3 13895 14184 14183 3 13896 13897 14185 3 13896 14185 14184 3 13897 13898 14186 3 13897 14186 14185 3 13898 13899 14187 3 13898 14187 14186 3 13899 13900 14188 3 13899 14188 14187 3 13900 13901 14189 3 13900 14189 14188 3 13901 13902 14190 3 13901 14190 14189 3 13902 13903 14191 3 13902 14191 14190 3 13903 13904 14192 3 13903 14192 14191 3 13904 13905 14193 3 13904 14193 14192 3 13905 13906 14194 3 13905 14194 14193 3 13906 13907 14195 3 13906 14195 14194 3 13907 13908 14196 3 13907 14196 14195 3 13908 13909 14197 3 13908 14197 14196 3 13909 13910 14198 3 13909 14198 14197 3 13910 13911 14199 3 13910 14199 14198 3 13911 13912 14200 3 13911 14200 14199 3 13912 13913 14201 3 13912 14201 14200 3 13913 13914 14202 3 13913 14202 14201 3 13914 13915 14203 3 13914 14203 14202 3 13915 13916 14204 3 13915 14204 14203 3 13916 13917 14205 3 13916 14205 14204 3 13917 13918 14206 3 13917 14206 14205 3 13918 13919 14207 3 13918 14207 14206 3 13919 13920 14208 3 13919 14208 14207 3 13920 13921 14209 3 13920 14209 14208 3 13921 13922 14210 3 13921 14210 14209 3 13922 13923 14211 3 13922 14211 14210 3 13923 13924 14212 3 13923 14212 14211 3 13924 13925 14213 3 13924 14213 14212 3 13925 13926 14214 3 13925 14214 14213 3 13926 13927 14215 3 13926 14215 14214 3 13927 13928 14216 3 13927 14216 14215 3 13928 13929 14217 3 13928 14217 14216 3 13929 13930 14218 3 13929 14218 14217 3 13930 13931 14218 3 14219 14218 13931 3 13931 13932 14219 3 14220 14219 13932 3 13933 14221 13934 3 14222 13934 14221 3 13933 14003 14221 3 14291 14221 14003 3 13934 14222 13935 3 14223 13935 14222 3 13935 14223 13936 3 14224 13936 14223 3 13936 14224 13937 3 14225 13937 14224 3 13937 14225 13938 3 14226 13938 14225 3 13938 14226 13939 3 14227 13939 14226 3 13939 14227 13940 3 14228 13940 14227 3 13940 14228 13941 3 14229 13941 14228 3 13941 14229 13942 3 14230 13942 14229 3 13942 14230 13943 3 14231 13943 14230 3 13943 14231 13944 3 14232 13944 14231 3 13944 14232 13945 3 14233 13945 14232 3 13945 14233 13946 3 14234 13946 14233 3 13946 14234 13947 3 14235 13947 14234 3 13947 14235 13948 3 14236 13948 14235 3 13948 14236 13949 3 14237 13949 14236 3 13949 14237 13950 3 14238 13950 14237 3 13950 14238 13951 3 14239 13951 14238 3 13951 14239 13952 3 14240 13952 14239 3 13952 14240 13953 3 14241 13953 14240 3 13953 14241 13954 3 14242 13954 14241 3 13954 14242 13955 3 14243 13955 14242 3 13955 14243 13956 3 14244 13956 14243 3 13956 14244 13957 3 14245 13957 14244 3 13957 14245 13958 3 14246 13958 14245 3 13958 14246 13959 3 14247 13959 14246 3 13959 14247 13960 3 14248 13960 14247 3 13960 14248 13961 3 14249 13961 14248 3 13961 14249 13962 3 14250 13962 14249 3 13962 14250 13963 3 14251 13963 14250 3 13963 14251 13964 3 14252 13964 14251 3 13964 14252 13965 3 14253 13965 14252 3 13965 14253 13966 3 14254 13966 14253 3 13966 14254 13967 3 14255 13967 14254 3 13967 14255 13968 3 14256 13968 14255 3 13968 14256 13969 3 14257 13969 14256 3 13969 14257 13970 3 14258 13970 14257 3 13970 14258 13971 3 14259 13971 14258 3 13971 14259 13972 3 14260 13972 14259 3 13972 14260 13973 3 14261 13973 14260 3 13973 14261 13974 3 14262 13974 14261 3 13974 14262 13975 3 14263 13975 14262 3 13975 14263 13976 3 14264 13976 14263 3 13976 14264 13977 3 14265 13977 14264 3 13977 14265 13978 3 14266 13978 14265 3 13978 14266 13979 3 14267 13979 14266 3 13979 14267 13980 3 14268 13980 14267 3 13980 14268 13981 3 14269 13981 14268 3 13981 14269 13982 3 14270 13982 14269 3 13982 14270 13983 3 14271 13983 14270 3 13983 14271 13984 3 14272 13984 14271 3 13984 14272 14273 3 13984 14273 13985 3 13985 14273 14274 3 13985 14274 13986 3 13986 14274 14275 3 13986 14275 13987 3 13987 14275 14276 3 13987 14276 13988 3 13988 14276 14277 3 13988 14277 13989 3 13989 14277 14278 3 13989 14278 13990 3 13990 14278 14279 3 13990 14279 13991 3 13991 14279 14280 3 13991 14280 13992 3 13992 14280 14281 3 13992 14281 13993 3 13993 14281 14282 3 13993 14282 13994 3 13994 14282 14283 3 13994 14283 13995 3 13995 14283 14284 3 13995 14284 13996 3 13996 14284 14285 3 13996 14285 13997 3 13997 14285 14286 3 13997 14286 13998 3 13998 14286 14287 3 13998 14287 13999 3 13999 14287 14288 3 13999 14288 14000 3 14000 14288 14289 3 14000 14289 14001 3 14001 14289 14292 3 14001 14292 14004 3 14002 14290 14291 3 14002 14291 14003 3 14002 14007 14295 3 14002 14295 14290 3 14004 14292 14293 3 14004 14293 14005 3 14005 14293 14296 3 14005 14296 14008 3 14006 14294 14295 3 14006 14295 14007 3 14006 14010 14298 3 14006 14298 14294 3 14008 14296 14297 3 14008 14297 14009 3 14009 14297 14299 3 14009 14299 14011 3 14010 14012 14300 3 14010 14300 14298 3 14011 14299 14301 3 14011 14301 14013 3 14012 14014 14302 3 14012 14302 14300 3 14013 14301 14303 3 14013 14303 14015 3 14014 14016 14304 3 14014 14304 14302 3 14015 14303 14305 3 14015 14305 14017 3 14016 14018 14306 3 14016 14306 14304 3 14017 14305 14307 3 14017 14307 14019 3 14018 14020 14308 3 14018 14308 14306 3 14019 14307 14309 3 14019 14309 14021 3 14020 14022 14310 3 14020 14310 14308 3 14021 14309 14311 3 14021 14311 14023 3 14022 14024 14312 3 14022 14312 14310 3 14023 14311 14313 3 14023 14313 14025 3 14024 14026 14314 3 14024 14314 14312 3 14025 14313 14315 3 14025 14315 14027 3 14026 14028 14316 3 14026 14316 14314 3 14027 14315 14317 3 14027 14317 14029 3 14028 14030 14318 3 14028 14318 14316 3 14029 14317 14319 3 14029 14319 14031 3 14030 14032 14320 3 14030 14320 14318 3 14031 14319 14321 3 14031 14321 14033 3 14032 14034 14322 3 14032 14322 14320 3 14033 14321 14323 3 14033 14323 14035 3 14034 14036 14324 3 14034 14324 14322 3 14035 14323 14325 3 14035 14325 14037 3 14036 14038 14326 3 14036 14326 14324 3 14037 14325 14327 3 14037 14327 14039 3 14038 14040 14328 3 14038 14328 14326 3 14039 14327 14329 3 14039 14329 14041 3 14040 14042 14330 3 14040 14330 14328 3 14041 14329 14331 3 14041 14331 14043 3 14042 14044 14332 3 14042 14332 14330 3 14043 14331 14333 3 14043 14333 14045 3 14044 14046 14334 3 14044 14334 14332 3 14045 14333 14335 3 14045 14335 14047 3 14046 14048 14336 3 14046 14336 14334 3 14047 14335 14337 3 14047 14337 14049 3 14048 14050 14338 3 14048 14338 14336 3 14049 14337 14339 3 14049 14339 14051 3 14050 14052 14340 3 14050 14340 14338 3 14051 14339 14341 3 14051 14341 14053 3 14052 14054 14342 3 14052 14342 14340 3 14053 14341 14343 3 14053 14343 14055 3 14054 14056 14344 3 14054 14344 14342 3 14055 14343 14345 3 14055 14345 14057 3 14056 14058 14346 3 14056 14346 14344 3 14057 14345 14347 3 14057 14347 14059 3 14058 14060 14348 3 14058 14348 14346 3 14059 14347 14061 3 14349 14061 14347 3 14060 14062 14350 3 14060 14350 14348 3 14061 14349 14063 3 14351 14063 14349 3 14062 14064 14352 3 14062 14352 14350 3 14063 14351 14065 3 14353 14065 14351 3 14064 14066 14354 3 14064 14354 14352 3 14065 14353 14067 3 14355 14067 14353 3 14066 14068 14356 3 14066 14356 14354 3 14067 14355 14069 3 14357 14069 14355 3 14068 14070 14358 3 14068 14358 14356 3 14069 14357 14071 3 14359 14071 14357 3 14070 14072 14360 3 14070 14360 14358 3 14071 14359 14073 3 14361 14073 14359 3 14072 14074 14362 3 14072 14362 14360 3 14073 14361 14075 3 14363 14075 14361 3 14074 14076 14364 3 14074 14364 14362 3 14075 14363 14077 3 14365 14077 14363 3 14076 14078 14364 3 14366 14364 14078 3 14077 14365 14079 3 14367 14079 14365 3 14078 14080 14366 3 14368 14366 14080 3 14079 14367 14081 3 14369 14081 14367 3 14080 14082 14368 3 14370 14368 14082 3 14081 14369 14083 3 14371 14083 14369 3 14082 14084 14370 3 14372 14370 14084 3 14083 14371 14085 3 14373 14085 14371 3 14084 14086 14372 3 14374 14372 14086 3 14085 14373 14087 3 14375 14087 14373 3 14086 14088 14374 3 14376 14374 14088 3 14087 14375 14089 3 14377 14089 14375 3 14088 14090 14376 3 14378 14376 14090 3 14089 14377 14091 3 14379 14091 14377 3 14090 14092 14378 3 14380 14378 14092 3 14091 14379 14093 3 14381 14093 14379 3 14092 14094 14380 3 14382 14380 14094 3 14093 14381 14095 3 14383 14095 14381 3 14094 14096 14382 3 14384 14382 14096 3 14095 14383 14097 3 14385 14097 14383 3 14096 14098 14384 3 14386 14384 14098 3 14097 14385 14099 3 14387 14099 14385 3 14098 14100 14386 3 14388 14386 14100 3 14099 14387 14101 3 14389 14101 14387 3 14100 14102 14388 3 14390 14388 14102 3 14101 14389 14103 3 14391 14103 14389 3 14102 14104 14390 3 14392 14390 14104 3 14103 14391 14105 3 14393 14105 14391 3 14104 14106 14392 3 14394 14392 14106 3 14105 14393 14107 3 14395 14107 14393 3 14106 14108 14394 3 14396 14394 14108 3 14107 14395 14109 3 14397 14109 14395 3 14108 14110 14396 3 14398 14396 14110 3 14109 14397 14111 3 14399 14111 14397 3 14110 14112 14398 3 14400 14398 14112 3 14111 14399 14113 3 14401 14113 14399 3 14112 14114 14400 3 14402 14400 14114 3 14113 14401 14115 3 14403 14115 14401 3 14114 14116 14402 3 14404 14402 14116 3 14115 14403 14117 3 14405 14117 14403 3 14116 14118 14404 3 14406 14404 14118 3 14117 14405 14119 3 14407 14119 14405 3 14118 14120 14406 3 14408 14406 14120 3 14119 14407 14121 3 14409 14121 14407 3 14120 14122 14408 3 14410 14408 14122 3 14121 14409 14123 3 14411 14123 14409 3 14122 14124 14410 3 14412 14410 14124 3 14123 14411 14125 3 14413 14125 14411 3 14124 14126 14412 3 14414 14412 14126 3 14125 14413 14127 3 14415 14127 14413 3 14126 14128 14414 3 14416 14414 14128 3 14127 14415 14129 3 14417 14129 14415 3 14128 14130 14416 3 14418 14416 14130 3 14129 14417 14131 3 14419 14131 14417 3 14130 14132 14418 3 14420 14418 14132 3 14131 14419 14421 3 14131 14421 14133 3 14132 14134 14420 3 14422 14420 14134 3 14133 14421 14423 3 14133 14423 14135 3 14134 14136 14422 3 14424 14422 14136 3 14135 14423 14425 3 14135 14425 14137 3 14136 14138 14424 3 14426 14424 14138 3 14137 14425 14427 3 14137 14427 14139 3 14138 14140 14426 3 14428 14426 14140 3 14139 14427 14429 3 14139 14429 14141 3 14140 14142 14428 3 14430 14428 14142 3 14141 14429 14431 3 14141 14431 14143 3 14142 14144 14430 3 14432 14430 14144 3 14143 14431 14435 3 14143 14435 14147 3 14144 14145 14432 3 14433 14432 14145 3 14145 14148 14433 3 14436 14433 14148 3 14146 14147 14434 3 14435 14434 14147 3 14146 14434 14439 3 14146 14439 14151 3 14148 14149 14436 3 14437 14436 14149 3 14149 14152 14440 3 14149 14440 14437 3 14150 14151 14439 3 14150 14439 14438 3 14150 14438 14508 3 14150 14508 14220 3 14152 14153 14441 3 14152 14441 14440 3 14153 14154 14442 3 14153 14442 14441 3 14154 14155 14443 3 14154 14443 14442 3 14155 14156 14444 3 14155 14444 14443 3 14156 14157 14445 3 14156 14445 14444 3 14157 14158 14446 3 14157 14446 14445 3 14158 14159 14447 3 14158 14447 14446 3 14159 14160 14448 3 14159 14448 14447 3 14160 14161 14449 3 14160 14449 14448 3 14161 14162 14450 3 14161 14450 14449 3 14162 14163 14451 3 14162 14451 14450 3 14163 14164 14452 3 14163 14452 14451 3 14164 14165 14453 3 14164 14453 14452 3 14165 14166 14454 3 14165 14454 14453 3 14166 14167 14455 3 14166 14455 14454 3 14167 14168 14456 3 14167 14456 14455 3 14168 14169 14457 3 14168 14457 14456 3 14169 14170 14458 3 14169 14458 14457 3 14170 14171 14459 3 14170 14459 14458 3 14171 14172 14460 3 14171 14460 14459 3 14172 14173 14461 3 14172 14461 14460 3 14173 14174 14462 3 14173 14462 14461 3 14174 14175 14463 3 14174 14463 14462 3 14175 14176 14464 3 14175 14464 14463 3 14176 14177 14465 3 14176 14465 14464 3 14177 14178 14466 3 14177 14466 14465 3 14178 14179 14467 3 14178 14467 14466 3 14179 14180 14468 3 14179 14468 14467 3 14180 14181 14469 3 14180 14469 14468 3 14181 14182 14470 3 14181 14470 14469 3 14182 14183 14471 3 14182 14471 14470 3 14183 14184 14472 3 14183 14472 14471 3 14184 14185 14473 3 14184 14473 14472 3 14185 14186 14474 3 14185 14474 14473 3 14186 14187 14475 3 14186 14475 14474 3 14187 14188 14476 3 14187 14476 14475 3 14188 14189 14477 3 14188 14477 14476 3 14189 14190 14478 3 14189 14478 14477 3 14190 14191 14479 3 14190 14479 14478 3 14191 14192 14480 3 14191 14480 14479 3 14192 14193 14481 3 14192 14481 14480 3 14193 14194 14482 3 14193 14482 14481 3 14194 14195 14483 3 14194 14483 14482 3 14195 14196 14484 3 14195 14484 14483 3 14196 14197 14485 3 14196 14485 14484 3 14197 14198 14486 3 14197 14486 14485 3 14198 14199 14487 3 14198 14487 14486 3 14199 14200 14488 3 14199 14488 14487 3 14200 14201 14489 3 14200 14489 14488 3 14201 14202 14490 3 14201 14490 14489 3 14202 14203 14491 3 14202 14491 14490 3 14203 14204 14492 3 14203 14492 14491 3 14204 14205 14493 3 14204 14493 14492 3 14205 14206 14494 3 14205 14494 14493 3 14206 14207 14495 3 14206 14495 14494 3 14207 14208 14496 3 14207 14496 14495 3 14208 14209 14497 3 14208 14497 14496 3 14209 14210 14498 3 14209 14498 14497 3 14210 14211 14499 3 14210 14499 14498 3 14211 14212 14500 3 14211 14500 14499 3 14212 14213 14501 3 14212 14501 14500 3 14213 14214 14502 3 14213 14502 14501 3 14214 14215 14503 3 14214 14503 14502 3 14215 14216 14504 3 14215 14504 14503 3 14216 14217 14505 3 14216 14505 14504 3 14217 14218 14506 3 14217 14506 14505 3 14218 14219 14507 3 14218 14507 14506 3 14219 14220 14508 3 14219 14508 14507 3 14221 14509 14222 3 14510 14222 14509 3 14221 14291 14509 3 14579 14509 14291 3 14222 14510 14223 3 14511 14223 14510 3 14223 14511 14224 3 14512 14224 14511 3 14224 14512 14225 3 14513 14225 14512 3 14225 14513 14226 3 14514 14226 14513 3 14226 14514 14227 3 14515 14227 14514 3 14227 14515 14228 3 14516 14228 14515 3 14228 14516 14229 3 14517 14229 14516 3 14229 14517 14230 3 14518 14230 14517 3 14230 14518 14231 3 14519 14231 14518 3 14231 14519 14232 3 14520 14232 14519 3 14232 14520 14233 3 14521 14233 14520 3 14233 14521 14234 3 14522 14234 14521 3 14234 14522 14235 3 14523 14235 14522 3 14235 14523 14236 3 14524 14236 14523 3 14236 14524 14237 3 14525 14237 14524 3 14237 14525 14238 3 14526 14238 14525 3 14238 14526 14239 3 14527 14239 14526 3 14239 14527 14240 3 14528 14240 14527 3 14240 14528 14241 3 14529 14241 14528 3 14241 14529 14242 3 14530 14242 14529 3 14242 14530 14243 3 14531 14243 14530 3 14243 14531 14244 3 14532 14244 14531 3 14244 14532 14245 3 14533 14245 14532 3 14245 14533 14246 3 14534 14246 14533 3 14246 14534 14247 3 14535 14247 14534 3 14247 14535 14248 3 14536 14248 14535 3 14248 14536 14249 3 14537 14249 14536 3 14249 14537 14250 3 14538 14250 14537 3 14250 14538 14251 3 14539 14251 14538 3 14251 14539 14252 3 14540 14252 14539 3 14252 14540 14253 3 14541 14253 14540 3 14253 14541 14254 3 14542 14254 14541 3 14254 14542 14255 3 14543 14255 14542 3 14255 14543 14256 3 14544 14256 14543 3 14256 14544 14257 3 14545 14257 14544 3 14257 14545 14258 3 14546 14258 14545 3 14258 14546 14259 3 14547 14259 14546 3 14259 14547 14260 3 14548 14260 14547 3 14260 14548 14261 3 14549 14261 14548 3 14261 14549 14262 3 14550 14262 14549 3 14262 14550 14263 3 14551 14263 14550 3 14263 14551 14264 3 14552 14264 14551 3 14264 14552 14265 3 14553 14265 14552 3 14265 14553 14266 3 14554 14266 14553 3 14266 14554 14267 3 14555 14267 14554 3 14267 14555 14268 3 14556 14268 14555 3 14268 14556 14269 3 14557 14269 14556 3 14269 14557 14270 3 14558 14270 14557 3 14270 14558 14271 3 14559 14271 14558 3 14271 14559 14272 3 14560 14272 14559 3 14272 14560 14273 3 14561 14273 14560 3 14273 14561 14274 3 14562 14274 14561 3 14274 14562 14275 3 14563 14275 14562 3 14275 14563 14276 3 14564 14276 14563 3 14276 14564 14277 3 14565 14277 14564 3 14277 14565 14278 3 14566 14278 14565 3 14278 14566 14279 3 14567 14279 14566 3 14279 14567 14568 3 14279 14568 14280 3 14280 14568 14569 3 14280 14569 14281 3 14281 14569 14570 3 14281 14570 14282 3 14282 14570 14571 3 14282 14571 14283 3 14283 14571 14572 3 14283 14572 14284 3 14284 14572 14573 3 14284 14573 14285 3 14285 14573 14574 3 14285 14574 14286 3 14286 14574 14575 3 14286 14575 14287 3 14287 14575 14576 3 14287 14576 14288 3 14288 14576 14577 3 14288 14577 14289 3 14289 14577 14580 3 14289 14580 14292 3 14290 14578 14579 3 14290 14579 14291 3 14290 14295 14578 3 14583 14578 14295 3 14292 14580 14581 3 14292 14581 14293 3 14293 14581 14584 3 14293 14584 14296 3 14294 14582 14583 3 14294 14583 14295 3 14294 14298 14586 3 14294 14586 14582 3 14296 14584 14585 3 14296 14585 14297 3 14297 14585 14587 3 14297 14587 14299 3 14298 14300 14588 3 14298 14588 14586 3 14299 14587 14589 3 14299 14589 14301 3 14300 14302 14590 3 14300 14590 14588 3 14301 14589 14591 3 14301 14591 14303 3 14302 14304 14592 3 14302 14592 14590 3 14303 14591 14593 3 14303 14593 14305 3 14304 14306 14594 3 14304 14594 14592 3 14305 14593 14595 3 14305 14595 14307 3 14306 14308 14596 3 14306 14596 14594 3 14307 14595 14597 3 14307 14597 14309 3 14308 14310 14598 3 14308 14598 14596 3 14309 14597 14599 3 14309 14599 14311 3 14310 14312 14600 3 14310 14600 14598 3 14311 14599 14601 3 14311 14601 14313 3 14312 14314 14602 3 14312 14602 14600 3 14313 14601 14603 3 14313 14603 14315 3 14314 14316 14604 3 14314 14604 14602 3 14315 14603 14605 3 14315 14605 14317 3 14316 14318 14606 3 14316 14606 14604 3 14317 14605 14607 3 14317 14607 14319 3 14318 14320 14608 3 14318 14608 14606 3 14319 14607 14609 3 14319 14609 14321 3 14320 14322 14610 3 14320 14610 14608 3 14321 14609 14611 3 14321 14611 14323 3 14322 14324 14612 3 14322 14612 14610 3 14323 14611 14613 3 14323 14613 14325 3 14324 14326 14614 3 14324 14614 14612 3 14325 14613 14615 3 14325 14615 14327 3 14326 14328 14616 3 14326 14616 14614 3 14327 14615 14617 3 14327 14617 14329 3 14328 14330 14618 3 14328 14618 14616 3 14329 14617 14619 3 14329 14619 14331 3 14330 14332 14620 3 14330 14620 14618 3 14331 14619 14621 3 14331 14621 14333 3 14332 14334 14622 3 14332 14622 14620 3 14333 14621 14623 3 14333 14623 14335 3 14334 14336 14624 3 14334 14624 14622 3 14335 14623 14625 3 14335 14625 14337 3 14336 14338 14626 3 14336 14626 14624 3 14337 14625 14627 3 14337 14627 14339 3 14338 14340 14628 3 14338 14628 14626 3 14339 14627 14629 3 14339 14629 14341 3 14340 14342 14630 3 14340 14630 14628 3 14341 14629 14631 3 14341 14631 14343 3 14342 14344 14632 3 14342 14632 14630 3 14343 14631 14633 3 14343 14633 14345 3 14344 14346 14634 3 14344 14634 14632 3 14345 14633 14635 3 14345 14635 14347 3 14346 14348 14636 3 14346 14636 14634 3 14347 14635 14637 3 14347 14637 14349 3 14348 14350 14638 3 14348 14638 14636 3 14349 14637 14639 3 14349 14639 14351 3 14350 14352 14640 3 14350 14640 14638 3 14351 14639 14641 3 14351 14641 14353 3 14352 14354 14642 3 14352 14642 14640 3 14353 14641 14355 3 14643 14355 14641 3 14354 14356 14644 3 14354 14644 14642 3 14355 14643 14357 3 14645 14357 14643 3 14356 14358 14646 3 14356 14646 14644 3 14357 14645 14359 3 14647 14359 14645 3 14358 14360 14648 3 14358 14648 14646 3 14359 14647 14361 3 14649 14361 14647 3 14360 14362 14650 3 14360 14650 14648 3 14361 14649 14363 3 14651 14363 14649 3 14362 14364 14652 3 14362 14652 14650 3 14363 14651 14365 3 14653 14365 14651 3 14364 14366 14654 3 14364 14654 14652 3 14365 14653 14367 3 14655 14367 14653 3 14366 14368 14656 3 14366 14656 14654 3 14367 14655 14369 3 14657 14369 14655 3 14368 14370 14658 3 14368 14658 14656 3 14369 14657 14371 3 14659 14371 14657 3 14370 14372 14658 3 14660 14658 14372 3 14371 14659 14373 3 14661 14373 14659 3 14372 14374 14660 3 14662 14660 14374 3 14373 14661 14375 3 14663 14375 14661 3 14374 14376 14662 3 14664 14662 14376 3 14375 14663 14377 3 14665 14377 14663 3 14376 14378 14664 3 14666 14664 14378 3 14377 14665 14379 3 14667 14379 14665 3 14378 14380 14666 3 14668 14666 14380 3 14379 14667 14381 3 14669 14381 14667 3 14380 14382 14668 3 14670 14668 14382 3 14381 14669 14383 3 14671 14383 14669 3 14382 14384 14670 3 14672 14670 14384 3 14383 14671 14385 3 14673 14385 14671 3 14384 14386 14672 3 14674 14672 14386 3 14385 14673 14387 3 14675 14387 14673 3 14386 14388 14674 3 14676 14674 14388 3 14387 14675 14389 3 14677 14389 14675 3 14388 14390 14676 3 14678 14676 14390 3 14389 14677 14391 3 14679 14391 14677 3 14390 14392 14678 3 14680 14678 14392 3 14391 14679 14393 3 14681 14393 14679 3 14392 14394 14680 3 14682 14680 14394 3 14393 14681 14395 3 14683 14395 14681 3 14394 14396 14682 3 14684 14682 14396 3 14395 14683 14397 3 14685 14397 14683 3 14396 14398 14684 3 14686 14684 14398 3 14397 14685 14399 3 14687 14399 14685 3 14398 14400 14686 3 14688 14686 14400 3 14399 14687 14401 3 14689 14401 14687 3 14400 14402 14688 3 14690 14688 14402 3 14401 14689 14403 3 14691 14403 14689 3 14402 14404 14690 3 14692 14690 14404 3 14403 14691 14405 3 14693 14405 14691 3 14404 14406 14692 3 14694 14692 14406 3 14405 14693 14407 3 14695 14407 14693 3 14406 14408 14694 3 14696 14694 14408 3 14407 14695 14409 3 14697 14409 14695 3 14408 14410 14696 3 14698 14696 14410 3 14409 14697 14411 3 14699 14411 14697 3 14410 14412 14698 3 14700 14698 14412 3 14411 14699 14413 3 14701 14413 14699 3 14412 14414 14700 3 14702 14700 14414 3 14413 14701 14415 3 14703 14415 14701 3 14414 14416 14702 3 14704 14702 14416 3 14415 14703 14417 3 14705 14417 14703 3 14416 14418 14704 3 14706 14704 14418 3 14417 14705 14419 3 14707 14419 14705 3 14418 14420 14706 3 14708 14706 14420 3 14419 14707 14421 3 14709 14421 14707 3 14420 14422 14708 3 14710 14708 14422 3 14421 14709 14423 3 14711 14423 14709 3 14422 14424 14710 3 14712 14710 14424 3 14423 14711 14425 3 14713 14425 14711 3 14424 14426 14712 3 14714 14712 14426 3 14425 14713 14427 3 14715 14427 14713 3 14426 14428 14714 3 14716 14714 14428 3 14427 14715 14717 3 14427 14717 14429 3 14428 14430 14716 3 14718 14716 14430 3 14429 14717 14719 3 14429 14719 14431 3 14430 14432 14718 3 14720 14718 14432 3 14431 14719 14723 3 14431 14723 14435 3 14432 14433 14720 3 14721 14720 14433 3 14433 14436 14721 3 14724 14721 14436 3 14434 14435 14722 3 14723 14722 14435 3 14434 14722 14727 3 14434 14727 14439 3 14436 14437 14724 3 14725 14724 14437 3 14437 14440 14725 3 14728 14725 14440 3 14438 14439 14726 3 14727 14726 14439 3 14438 14726 14796 3 14438 14796 14508 3 14440 14441 14728 3 14729 14728 14441 3 14441 14442 14729 3 14730 14729 14442 3 14442 14443 14730 3 14731 14730 14443 3 14443 14444 14731 3 14732 14731 14444 3 14444 14445 14733 3 14444 14733 14732 3 14445 14446 14734 3 14445 14734 14733 3 14446 14447 14735 3 14446 14735 14734 3 14447 14448 14736 3 14447 14736 14735 3 14448 14449 14737 3 14448 14737 14736 3 14449 14450 14738 3 14449 14738 14737 3 14450 14451 14739 3 14450 14739 14738 3 14451 14452 14740 3 14451 14740 14739 3 14452 14453 14741 3 14452 14741 14740 3 14453 14454 14742 3 14453 14742 14741 3 14454 14455 14743 3 14454 14743 14742 3 14455 14456 14744 3 14455 14744 14743 3 14456 14457 14745 3 14456 14745 14744 3 14457 14458 14746 3 14457 14746 14745 3 14458 14459 14747 3 14458 14747 14746 3 14459 14460 14748 3 14459 14748 14747 3 14460 14461 14749 3 14460 14749 14748 3 14461 14462 14750 3 14461 14750 14749 3 14462 14463 14751 3 14462 14751 14750 3 14463 14464 14752 3 14463 14752 14751 3 14464 14465 14753 3 14464 14753 14752 3 14465 14466 14754 3 14465 14754 14753 3 14466 14467 14755 3 14466 14755 14754 3 14467 14468 14756 3 14467 14756 14755 3 14468 14469 14757 3 14468 14757 14756 3 14469 14470 14758 3 14469 14758 14757 3 14470 14471 14759 3 14470 14759 14758 3 14471 14472 14760 3 14471 14760 14759 3 14472 14473 14761 3 14472 14761 14760 3 14473 14474 14762 3 14473 14762 14761 3 14474 14475 14763 3 14474 14763 14762 3 14475 14476 14764 3 14475 14764 14763 3 14476 14477 14765 3 14476 14765 14764 3 14477 14478 14766 3 14477 14766 14765 3 14478 14479 14767 3 14478 14767 14766 3 14479 14480 14768 3 14479 14768 14767 3 14480 14481 14769 3 14480 14769 14768 3 14481 14482 14770 3 14481 14770 14769 3 14482 14483 14771 3 14482 14771 14770 3 14483 14484 14772 3 14483 14772 14771 3 14484 14485 14773 3 14484 14773 14772 3 14485 14486 14774 3 14485 14774 14773 3 14486 14487 14775 3 14486 14775 14774 3 14487 14488 14776 3 14487 14776 14775 3 14488 14489 14777 3 14488 14777 14776 3 14489 14490 14778 3 14489 14778 14777 3 14490 14491 14779 3 14490 14779 14778 3 14491 14492 14780 3 14491 14780 14779 3 14492 14493 14781 3 14492 14781 14780 3 14493 14494 14782 3 14493 14782 14781 3 14494 14495 14783 3 14494 14783 14782 3 14495 14496 14784 3 14495 14784 14783 3 14496 14497 14785 3 14496 14785 14784 3 14497 14498 14786 3 14497 14786 14785 3 14498 14499 14787 3 14498 14787 14786 3 14499 14500 14788 3 14499 14788 14787 3 14500 14501 14789 3 14500 14789 14788 3 14501 14502 14790 3 14501 14790 14789 3 14502 14503 14791 3 14502 14791 14790 3 14503 14504 14792 3 14503 14792 14791 3 14504 14505 14793 3 14504 14793 14792 3 14505 14506 14794 3 14505 14794 14793 3 14506 14507 14795 3 14506 14795 14794 3 14507 14508 14796 3 14507 14796 14795 3 14509 14797 14510 3 14798 14510 14797 3 14509 14579 14797 3 14867 14797 14579 3 14510 14798 14511 3 14799 14511 14798 3 14511 14799 14512 3 14800 14512 14799 3 14512 14800 14513 3 14801 14513 14800 3 14513 14801 14514 3 14802 14514 14801 3 14514 14802 14515 3 14803 14515 14802 3 14515 14803 14516 3 14804 14516 14803 3 14516 14804 14517 3 14805 14517 14804 3 14517 14805 14518 3 14806 14518 14805 3 14518 14806 14519 3 14807 14519 14806 3 14519 14807 14520 3 14808 14520 14807 3 14520 14808 14521 3 14809 14521 14808 3 14521 14809 14522 3 14810 14522 14809 3 14522 14810 14523 3 14811 14523 14810 3 14523 14811 14524 3 14812 14524 14811 3 14524 14812 14525 3 14813 14525 14812 3 14525 14813 14526 3 14814 14526 14813 3 14526 14814 14527 3 14815 14527 14814 3 14527 14815 14528 3 14816 14528 14815 3 14528 14816 14529 3 14817 14529 14816 3 14529 14817 14530 3 14818 14530 14817 3 14530 14818 14531 3 14819 14531 14818 3 14531 14819 14532 3 14820 14532 14819 3 14532 14820 14533 3 14821 14533 14820 3 14533 14821 14534 3 14822 14534 14821 3 14534 14822 14535 3 14823 14535 14822 3 14535 14823 14536 3 14824 14536 14823 3 14536 14824 14537 3 14825 14537 14824 3 14537 14825 14538 3 14826 14538 14825 3 14538 14826 14539 3 14827 14539 14826 3 14539 14827 14540 3 14828 14540 14827 3 14540 14828 14541 3 14829 14541 14828 3 14541 14829 14542 3 14830 14542 14829 3 14542 14830 14543 3 14831 14543 14830 3 14543 14831 14544 3 14832 14544 14831 3 14544 14832 14545 3 14833 14545 14832 3 14545 14833 14546 3 14834 14546 14833 3 14546 14834 14547 3 14835 14547 14834 3 14547 14835 14548 3 14836 14548 14835 3 14548 14836 14549 3 14837 14549 14836 3 14549 14837 14550 3 14838 14550 14837 3 14550 14838 14551 3 14839 14551 14838 3 14551 14839 14552 3 14840 14552 14839 3 14552 14840 14553 3 14841 14553 14840 3 14553 14841 14554 3 14842 14554 14841 3 14554 14842 14555 3 14843 14555 14842 3 14555 14843 14556 3 14844 14556 14843 3 14556 14844 14557 3 14845 14557 14844 3 14557 14845 14558 3 14846 14558 14845 3 14558 14846 14559 3 14847 14559 14846 3 14559 14847 14560 3 14848 14560 14847 3 14560 14848 14561 3 14849 14561 14848 3 14561 14849 14562 3 14850 14562 14849 3 14562 14850 14563 3 14851 14563 14850 3 14563 14851 14564 3 14852 14564 14851 3 14564 14852 14565 3 14853 14565 14852 3 14565 14853 14566 3 14854 14566 14853 3 14566 14854 14567 3 14855 14567 14854 3 14567 14855 14568 3 14856 14568 14855 3 14568 14856 14569 3 14857 14569 14856 3 14569 14857 14570 3 14858 14570 14857 3 14570 14858 14571 3 14859 14571 14858 3 14571 14859 14572 3 14860 14572 14859 3 14572 14860 14573 3 14861 14573 14860 3 14573 14861 14574 3 14862 14574 14861 3 14574 14862 14575 3 14863 14575 14862 3 14575 14863 14576 3 14864 14576 14863 3 14576 14864 14865 3 14576 14865 14577 3 14577 14865 14868 3 14577 14868 14580 3 14578 14866 14867 3 14578 14867 14579 3 14578 14583 14866 3 14871 14866 14583 3 14580 14868 14869 3 14580 14869 14581 3 14581 14869 14872 3 14581 14872 14584 3 14582 14870 14871 3 14582 14871 14583 3 14582 14586 14870 3 14874 14870 14586 3 14584 14872 14873 3 14584 14873 14585 3 14585 14873 14875 3 14585 14875 14587 3 14586 14588 14874 3 14876 14874 14588 3 14587 14875 14877 3 14587 14877 14589 3 14588 14590 14876 3 14878 14876 14590 3 14589 14877 14879 3 14589 14879 14591 3 14590 14592 14878 3 14880 14878 14592 3 14591 14879 14881 3 14591 14881 14593 3 14592 14594 14882 3 14592 14882 14880 3 14593 14881 14883 3 14593 14883 14595 3 14594 14596 14884 3 14594 14884 14882 3 14595 14883 14885 3 14595 14885 14597 3 14596 14598 14886 3 14596 14886 14884 3 14597 14885 14887 3 14597 14887 14599 3 14598 14600 14888 3 14598 14888 14886 3 14599 14887 14889 3 14599 14889 14601 3 14600 14602 14890 3 14600 14890 14888 3 14601 14889 14891 3 14601 14891 14603 3 14602 14604 14892 3 14602 14892 14890 3 14603 14891 14893 3 14603 14893 14605 3 14604 14606 14894 3 14604 14894 14892 3 14605 14893 14895 3 14605 14895 14607 3 14606 14608 14896 3 14606 14896 14894 3 14607 14895 14897 3 14607 14897 14609 3 14608 14610 14898 3 14608 14898 14896 3 14609 14897 14899 3 14609 14899 14611 3 14610 14612 14900 3 14610 14900 14898 3 14611 14899 14901 3 14611 14901 14613 3 14612 14614 14902 3 14612 14902 14900 3 14613 14901 14903 3 14613 14903 14615 3 14614 14616 14904 3 14614 14904 14902 3 14615 14903 14905 3 14615 14905 14617 3 14616 14618 14906 3 14616 14906 14904 3 14617 14905 14907 3 14617 14907 14619 3 14618 14620 14908 3 14618 14908 14906 3 14619 14907 14909 3 14619 14909 14621 3 14620 14622 14910 3 14620 14910 14908 3 14621 14909 14911 3 14621 14911 14623 3 14622 14624 14912 3 14622 14912 14910 3 14623 14911 14913 3 14623 14913 14625 3 14624 14626 14914 3 14624 14914 14912 3 14625 14913 14915 3 14625 14915 14627 3 14626 14628 14916 3 14626 14916 14914 3 14627 14915 14917 3 14627 14917 14629 3 14628 14630 14918 3 14628 14918 14916 3 14629 14917 14919 3 14629 14919 14631 3 14630 14632 14920 3 14630 14920 14918 3 14631 14919 14921 3 14631 14921 14633 3 14632 14634 14922 3 14632 14922 14920 3 14633 14921 14923 3 14633 14923 14635 3 14634 14636 14924 3 14634 14924 14922 3 14635 14923 14925 3 14635 14925 14637 3 14636 14638 14926 3 14636 14926 14924 3 14637 14925 14927 3 14637 14927 14639 3 14638 14640 14928 3 14638 14928 14926 3 14639 14927 14929 3 14639 14929 14641 3 14640 14642 14930 3 14640 14930 14928 3 14641 14929 14931 3 14641 14931 14643 3 14642 14644 14932 3 14642 14932 14930 3 14643 14931 14933 3 14643 14933 14645 3 14644 14646 14934 3 14644 14934 14932 3 14645 14933 14935 3 14645 14935 14647 3 14646 14648 14936 3 14646 14936 14934 3 14647 14935 14937 3 14647 14937 14649 3 14648 14650 14938 3 14648 14938 14936 3 14649 14937 14939 3 14649 14939 14651 3 14650 14652 14940 3 14650 14940 14938 3 14651 14939 14653 3 14941 14653 14939 3 14652 14654 14942 3 14652 14942 14940 3 14653 14941 14655 3 14943 14655 14941 3 14654 14656 14944 3 14654 14944 14942 3 14655 14943 14657 3 14945 14657 14943 3 14656 14658 14946 3 14656 14946 14944 3 14657 14945 14659 3 14947 14659 14945 3 14658 14660 14948 3 14658 14948 14946 3 14659 14947 14661 3 14949 14661 14947 3 14660 14662 14950 3 14660 14950 14948 3 14661 14949 14663 3 14951 14663 14949 3 14662 14664 14952 3 14662 14952 14950 3 14663 14951 14665 3 14953 14665 14951 3 14664 14666 14954 3 14664 14954 14952 3 14665 14953 14667 3 14955 14667 14953 3 14666 14668 14954 3 14956 14954 14668 3 14667 14955 14669 3 14957 14669 14955 3 14668 14670 14956 3 14958 14956 14670 3 14669 14957 14671 3 14959 14671 14957 3 14670 14672 14958 3 14960 14958 14672 3 14671 14959 14673 3 14961 14673 14959 3 14672 14674 14960 3 14962 14960 14674 3 14673 14961 14675 3 14963 14675 14961 3 14674 14676 14962 3 14964 14962 14676 3 14675 14963 14677 3 14965 14677 14963 3 14676 14678 14964 3 14966 14964 14678 3 14677 14965 14679 3 14967 14679 14965 3 14678 14680 14966 3 14968 14966 14680 3 14679 14967 14681 3 14969 14681 14967 3 14680 14682 14968 3 14970 14968 14682 3 14681 14969 14683 3 14971 14683 14969 3 14682 14684 14970 3 14972 14970 14684 3 14683 14971 14685 3 14973 14685 14971 3 14684 14686 14972 3 14974 14972 14686 3 14685 14973 14687 3 14975 14687 14973 3 14686 14688 14974 3 14976 14974 14688 3 14687 14975 14689 3 14977 14689 14975 3 14688 14690 14976 3 14978 14976 14690 3 14689 14977 14691 3 14979 14691 14977 3 14690 14692 14978 3 14980 14978 14692 3 14691 14979 14693 3 14981 14693 14979 3 14692 14694 14980 3 14982 14980 14694 3 14693 14981 14695 3 14983 14695 14981 3 14694 14696 14982 3 14984 14982 14696 3 14695 14983 14697 3 14985 14697 14983 3 14696 14698 14984 3 14986 14984 14698 3 14697 14985 14699 3 14987 14699 14985 3 14698 14700 14986 3 14988 14986 14700 3 14699 14987 14701 3 14989 14701 14987 3 14700 14702 14988 3 14990 14988 14702 3 14701 14989 14703 3 14991 14703 14989 3 14702 14704 14990 3 14992 14990 14704 3 14703 14991 14705 3 14993 14705 14991 3 14704 14706 14992 3 14994 14992 14706 3 14705 14993 14707 3 14995 14707 14993 3 14706 14708 14994 3 14996 14994 14708 3 14707 14995 14709 3 14997 14709 14995 3 14708 14710 14996 3 14998 14996 14710 3 14709 14997 14711 3 14999 14711 14997 3 14710 14712 14998 3 15000 14998 14712 3 14711 14999 14713 3 15001 14713 14999 3 14712 14714 15000 3 15002 15000 14714 3 14713 15001 14715 3 15003 14715 15001 3 14714 14716 15002 3 15004 15002 14716 3 14715 15003 14717 3 15005 14717 15003 3 14716 14718 15004 3 15006 15004 14718 3 14717 15005 14719 3 15007 14719 15005 3 14718 14720 15006 3 15008 15006 14720 3 14719 15007 14723 3 15011 14723 15007 3 14720 14721 15008 3 15009 15008 14721 3 14721 14724 15009 3 15012 15009 14724 3 14722 14723 15010 3 15011 15010 14723 3 14722 15010 14727 3 15015 14727 15010 3 14724 14725 15012 3 15013 15012 14725 3 14725 14728 15013 3 15016 15013 14728 3 14726 14727 15014 3 15015 15014 14727 3 14726 15014 15084 3 14726 15084 14796 3 14728 14729 15016 3 15017 15016 14729 3 14729 14730 15017 3 15018 15017 14730 3 14730 14731 15018 3 15019 15018 14731 3 14731 14732 15019 3 15020 15019 14732 3 14732 14733 15020 3 15021 15020 14733 3 14733 14734 15021 3 15022 15021 14734 3 14734 14735 15022 3 15023 15022 14735 3 14735 14736 15023 3 15024 15023 14736 3 14736 14737 15024 3 15025 15024 14737 3 14737 14738 15025 3 15026 15025 14738 3 14738 14739 15026 3 15027 15026 14739 3 14739 14740 15027 3 15028 15027 14740 3 14740 14741 15028 3 15029 15028 14741 3 14741 14742 15030 3 14741 15030 15029 3 14742 14743 15031 3 14742 15031 15030 3 14743 14744 15032 3 14743 15032 15031 3 14744 14745 15033 3 14744 15033 15032 3 14745 14746 15034 3 14745 15034 15033 3 14746 14747 15035 3 14746 15035 15034 3 14747 14748 15036 3 14747 15036 15035 3 14748 14749 15037 3 14748 15037 15036 3 14749 14750 15038 3 14749 15038 15037 3 14750 14751 15039 3 14750 15039 15038 3 14751 14752 15040 3 14751 15040 15039 3 14752 14753 15041 3 14752 15041 15040 3 14753 14754 15042 3 14753 15042 15041 3 14754 14755 15043 3 14754 15043 15042 3 14755 14756 15044 3 14755 15044 15043 3 14756 14757 15045 3 14756 15045 15044 3 14757 14758 15046 3 14757 15046 15045 3 14758 14759 15047 3 14758 15047 15046 3 14759 14760 15048 3 14759 15048 15047 3 14760 14761 15049 3 14760 15049 15048 3 14761 14762 15050 3 14761 15050 15049 3 14762 14763 15051 3 14762 15051 15050 3 14763 14764 15052 3 14763 15052 15051 3 14764 14765 15053 3 14764 15053 15052 3 14765 14766 15054 3 14765 15054 15053 3 14766 14767 15055 3 14766 15055 15054 3 14767 14768 15056 3 14767 15056 15055 3 14768 14769 15057 3 14768 15057 15056 3 14769 14770 15058 3 14769 15058 15057 3 14770 14771 15059 3 14770 15059 15058 3 14771 14772 15060 3 14771 15060 15059 3 14772 14773 15061 3 14772 15061 15060 3 14773 14774 15062 3 14773 15062 15061 3 14774 14775 15063 3 14774 15063 15062 3 14775 14776 15064 3 14775 15064 15063 3 14776 14777 15065 3 14776 15065 15064 3 14777 14778 15066 3 14777 15066 15065 3 14778 14779 15067 3 14778 15067 15066 3 14779 14780 15068 3 14779 15068 15067 3 14780 14781 15069 3 14780 15069 15068 3 14781 14782 15070 3 14781 15070 15069 3 14782 14783 15071 3 14782 15071 15070 3 14783 14784 15072 3 14783 15072 15071 3 14784 14785 15073 3 14784 15073 15072 3 14785 14786 15074 3 14785 15074 15073 3 14786 14787 15075 3 14786 15075 15074 3 14787 14788 15076 3 14787 15076 15075 3 14788 14789 15077 3 14788 15077 15076 3 14789 14790 15078 3 14789 15078 15077 3 14790 14791 15079 3 14790 15079 15078 3 14791 14792 15080 3 14791 15080 15079 3 14792 14793 15081 3 14792 15081 15080 3 14793 14794 15082 3 14793 15082 15081 3 14794 14795 15083 3 14794 15083 15082 3 14795 14796 15084 3 14795 15084 15083 3 14797 15085 15086 3 14797 15086 14798 3 14797 14867 15085 3 15155 15085 14867 3 14798 15086 15087 3 14798 15087 14799 3 14799 15087 15088 3 14799 15088 14800 3 14800 15088 15089 3 14800 15089 14801 3 14801 15089 14802 3 15090 14802 15089 3 14802 15090 14803 3 15091 14803 15090 3 14803 15091 14804 3 15092 14804 15091 3 14804 15092 14805 3 15093 14805 15092 3 14805 15093 14806 3 15094 14806 15093 3 14806 15094 14807 3 15095 14807 15094 3 14807 15095 14808 3 15096 14808 15095 3 14808 15096 14809 3 15097 14809 15096 3 14809 15097 14810 3 15098 14810 15097 3 14810 15098 14811 3 15099 14811 15098 3 14811 15099 14812 3 15100 14812 15099 3 14812 15100 14813 3 15101 14813 15100 3 14813 15101 14814 3 15102 14814 15101 3 14814 15102 14815 3 15103 14815 15102 3 14815 15103 14816 3 15104 14816 15103 3 14816 15104 14817 3 15105 14817 15104 3 14817 15105 14818 3 15106 14818 15105 3 14818 15106 14819 3 15107 14819 15106 3 14819 15107 14820 3 15108 14820 15107 3 14820 15108 14821 3 15109 14821 15108 3 14821 15109 14822 3 15110 14822 15109 3 14822 15110 14823 3 15111 14823 15110 3 14823 15111 14824 3 15112 14824 15111 3 14824 15112 14825 3 15113 14825 15112 3 14825 15113 14826 3 15114 14826 15113 3 14826 15114 14827 3 15115 14827 15114 3 14827 15115 14828 3 15116 14828 15115 3 14828 15116 14829 3 15117 14829 15116 3 14829 15117 14830 3 15118 14830 15117 3 14830 15118 14831 3 15119 14831 15118 3 14831 15119 14832 3 15120 14832 15119 3 14832 15120 14833 3 15121 14833 15120 3 14833 15121 14834 3 15122 14834 15121 3 14834 15122 14835 3 15123 14835 15122 3 14835 15123 14836 3 15124 14836 15123 3 14836 15124 14837 3 15125 14837 15124 3 14837 15125 14838 3 15126 14838 15125 3 14838 15126 14839 3 15127 14839 15126 3 14839 15127 14840 3 15128 14840 15127 3 14840 15128 14841 3 15129 14841 15128 3 14841 15129 14842 3 15130 14842 15129 3 14842 15130 14843 3 15131 14843 15130 3 14843 15131 14844 3 15132 14844 15131 3 14844 15132 14845 3 15133 14845 15132 3 14845 15133 14846 3 15134 14846 15133 3 14846 15134 14847 3 15135 14847 15134 3 14847 15135 14848 3 15136 14848 15135 3 14848 15136 14849 3 15137 14849 15136 3 14849 15137 14850 3 15138 14850 15137 3 14850 15138 14851 3 15139 14851 15138 3 14851 15139 14852 3 15140 14852 15139 3 14852 15140 14853 3 15141 14853 15140 3 14853 15141 14854 3 15142 14854 15141 3 14854 15142 14855 3 15143 14855 15142 3 14855 15143 14856 3 15144 14856 15143 3 14856 15144 14857 3 15145 14857 15144 3 14857 15145 14858 3 15146 14858 15145 3 14858 15146 14859 3 15147 14859 15146 3 14859 15147 14860 3 15148 14860 15147 3 14860 15148 14861 3 15149 14861 15148 3 14861 15149 14862 3 15150 14862 15149 3 14862 15150 14863 3 15151 14863 15150 3 14863 15151 14864 3 15152 14864 15151 3 14864 15152 14865 3 15153 14865 15152 3 14865 15153 14868 3 15156 14868 15153 3 14866 15154 14867 3 15155 14867 15154 3 14866 14871 15154 3 15159 15154 14871 3 14868 15156 14869 3 15157 14869 15156 3 14869 15157 14872 3 15160 14872 15157 3 14870 15158 14871 3 15159 14871 15158 3 14870 14874 15158 3 15162 15158 14874 3 14872 15160 14873 3 15161 14873 15160 3 14873 15161 14875 3 15163 14875 15161 3 14874 14876 15162 3 15164 15162 14876 3 14875 15163 14877 3 15165 14877 15163 3 14876 14878 15164 3 15166 15164 14878 3 14877 15165 15167 3 14877 15167 14879 3 14878 14880 15166 3 15168 15166 14880 3 14879 15167 15169 3 14879 15169 14881 3 14880 14882 15168 3 15170 15168 14882 3 14881 15169 15171 3 14881 15171 14883 3 14882 14884 15170 3 15172 15170 14884 3 14883 15171 15173 3 14883 15173 14885 3 14884 14886 15172 3 15174 15172 14886 3 14885 15173 15175 3 14885 15175 14887 3 14886 14888 15174 3 15176 15174 14888 3 14887 15175 15177 3 14887 15177 14889 3 14888 14890 15176 3 15178 15176 14890 3 14889 15177 15179 3 14889 15179 14891 3 14890 14892 15180 3 14890 15180 15178 3 14891 15179 15181 3 14891 15181 14893 3 14892 14894 15182 3 14892 15182 15180 3 14893 15181 15183 3 14893 15183 14895 3 14894 14896 15184 3 14894 15184 15182 3 14895 15183 15185 3 14895 15185 14897 3 14896 14898 15186 3 14896 15186 15184 3 14897 15185 15187 3 14897 15187 14899 3 14898 14900 15188 3 14898 15188 15186 3 14899 15187 15189 3 14899 15189 14901 3 14900 14902 15190 3 14900 15190 15188 3 14901 15189 15191 3 14901 15191 14903 3 14902 14904 15192 3 14902 15192 15190 3 14903 15191 15193 3 14903 15193 14905 3 14904 14906 15194 3 14904 15194 15192 3 14905 15193 15195 3 14905 15195 14907 3 14906 14908 15196 3 14906 15196 15194 3 14907 15195 15197 3 14907 15197 14909 3 14908 14910 15198 3 14908 15198 15196 3 14909 15197 15199 3 14909 15199 14911 3 14910 14912 15200 3 14910 15200 15198 3 14911 15199 15201 3 14911 15201 14913 3 14912 14914 15202 3 14912 15202 15200 3 14913 15201 15203 3 14913 15203 14915 3 14914 14916 15204 3 14914 15204 15202 3 14915 15203 15205 3 14915 15205 14917 3 14916 14918 15206 3 14916 15206 15204 3 14917 15205 15207 3 14917 15207 14919 3 14918 14920 15208 3 14918 15208 15206 3 14919 15207 15209 3 14919 15209 14921 3 14920 14922 15210 3 14920 15210 15208 3 14921 15209 15211 3 14921 15211 14923 3 14922 14924 15212 3 14922 15212 15210 3 14923 15211 15213 3 14923 15213 14925 3 14924 14926 15214 3 14924 15214 15212 3 14925 15213 15215 3 14925 15215 14927 3 14926 14928 15216 3 14926 15216 15214 3 14927 15215 15217 3 14927 15217 14929 3 14928 14930 15218 3 14928 15218 15216 3 14929 15217 15219 3 14929 15219 14931 3 14930 14932 15220 3 14930 15220 15218 3 14931 15219 15221 3 14931 15221 14933 3 14932 14934 15222 3 14932 15222 15220 3 14933 15221 15223 3 14933 15223 14935 3 14934 14936 15224 3 14934 15224 15222 3 14935 15223 15225 3 14935 15225 14937 3 14936 14938 15226 3 14936 15226 15224 3 14937 15225 15227 3 14937 15227 14939 3 14938 14940 15228 3 14938 15228 15226 3 14939 15227 15229 3 14939 15229 14941 3 14940 14942 15230 3 14940 15230 15228 3 14941 15229 15231 3 14941 15231 14943 3 14942 14944 15232 3 14942 15232 15230 3 14943 15231 15233 3 14943 15233 14945 3 14944 14946 15234 3 14944 15234 15232 3 14945 15233 15235 3 14945 15235 14947 3 14946 14948 15236 3 14946 15236 15234 3 14947 15235 15237 3 14947 15237 14949 3 14948 14950 15238 3 14948 15238 15236 3 14949 15237 15239 3 14949 15239 14951 3 14950 14952 15240 3 14950 15240 15238 3 14951 15239 15241 3 14951 15241 14953 3 14952 14954 15242 3 14952 15242 15240 3 14953 15241 14955 3 15243 14955 15241 3 14954 14956 15244 3 14954 15244 15242 3 14955 15243 14957 3 15245 14957 15243 3 14956 14958 15246 3 14956 15246 15244 3 14957 15245 14959 3 15247 14959 15245 3 14958 14960 15248 3 14958 15248 15246 3 14959 15247 14961 3 15249 14961 15247 3 14960 14962 15250 3 14960 15250 15248 3 14961 15249 14963 3 15251 14963 15249 3 14962 14964 15252 3 14962 15252 15250 3 14963 15251 14965 3 15253 14965 15251 3 14964 14966 15254 3 14964 15254 15252 3 14965 15253 14967 3 15255 14967 15253 3 14966 14968 15254 3 15256 15254 14968 3 14967 15255 14969 3 15257 14969 15255 3 14968 14970 15256 3 15258 15256 14970 3 14969 15257 14971 3 15259 14971 15257 3 14970 14972 15258 3 15260 15258 14972 3 14971 15259 14973 3 15261 14973 15259 3 14972 14974 15260 3 15262 15260 14974 3 14973 15261 14975 3 15263 14975 15261 3 14974 14976 15262 3 15264 15262 14976 3 14975 15263 14977 3 15265 14977 15263 3 14976 14978 15264 3 15266 15264 14978 3 14977 15265 14979 3 15267 14979 15265 3 14978 14980 15266 3 15268 15266 14980 3 14979 15267 14981 3 15269 14981 15267 3 14980 14982 15268 3 15270 15268 14982 3 14981 15269 14983 3 15271 14983 15269 3 14982 14984 15270 3 15272 15270 14984 3 14983 15271 14985 3 15273 14985 15271 3 14984 14986 15272 3 15274 15272 14986 3 14985 15273 14987 3 15275 14987 15273 3 14986 14988 15274 3 15276 15274 14988 3 14987 15275 14989 3 15277 14989 15275 3 14988 14990 15276 3 15278 15276 14990 3 14989 15277 14991 3 15279 14991 15277 3 14990 14992 15278 3 15280 15278 14992 3 14991 15279 14993 3 15281 14993 15279 3 14992 14994 15280 3 15282 15280 14994 3 14993 15281 14995 3 15283 14995 15281 3 14994 14996 15282 3 15284 15282 14996 3 14995 15283 14997 3 15285 14997 15283 3 14996 14998 15284 3 15286 15284 14998 3 14997 15285 14999 3 15287 14999 15285 3 14998 15000 15286 3 15288 15286 15000 3 14999 15287 15001 3 15289 15001 15287 3 15000 15002 15288 3 15290 15288 15002 3 15001 15289 15003 3 15291 15003 15289 3 15002 15004 15290 3 15292 15290 15004 3 15003 15291 15005 3 15293 15005 15291 3 15004 15006 15292 3 15294 15292 15006 3 15005 15293 15007 3 15295 15007 15293 3 15006 15008 15294 3 15296 15294 15008 3 15007 15295 15011 3 15299 15011 15295 3 15008 15009 15296 3 15297 15296 15009 3 15009 15012 15297 3 15300 15297 15012 3 15010 15011 15298 3 15299 15298 15011 3 15010 15298 15015 3 15303 15015 15298 3 15012 15013 15300 3 15301 15300 15013 3 15013 15016 15301 3 15304 15301 15016 3 15014 15015 15302 3 15303 15302 15015 3 15014 15302 15084 3 15372 15084 15302 3 15016 15017 15304 3 15305 15304 15017 3 15017 15018 15305 3 15306 15305 15018 3 15018 15019 15306 3 15307 15306 15019 3 15019 15020 15307 3 15308 15307 15020 3 15020 15021 15308 3 15309 15308 15021 3 15021 15022 15309 3 15310 15309 15022 3 15022 15023 15310 3 15311 15310 15023 3 15023 15024 15311 3 15312 15311 15024 3 15024 15025 15312 3 15313 15312 15025 3 15025 15026 15313 3 15314 15313 15026 3 15026 15027 15314 3 15315 15314 15027 3 15027 15028 15315 3 15316 15315 15028 3 15028 15029 15316 3 15317 15316 15029 3 15029 15030 15317 3 15318 15317 15030 3 15030 15031 15318 3 15319 15318 15031 3 15031 15032 15319 3 15320 15319 15032 3 15032 15033 15320 3 15321 15320 15033 3 15033 15034 15321 3 15322 15321 15034 3 15034 15035 15322 3 15323 15322 15035 3 15035 15036 15323 3 15324 15323 15036 3 15036 15037 15324 3 15325 15324 15037 3 15037 15038 15325 3 15326 15325 15038 3 15038 15039 15326 3 15327 15326 15039 3 15039 15040 15327 3 15328 15327 15040 3 15040 15041 15328 3 15329 15328 15041 3 15041 15042 15329 3 15330 15329 15042 3 15042 15043 15331 3 15042 15331 15330 3 15043 15044 15332 3 15043 15332 15331 3 15044 15045 15333 3 15044 15333 15332 3 15045 15046 15334 3 15045 15334 15333 3 15046 15047 15335 3 15046 15335 15334 3 15047 15048 15336 3 15047 15336 15335 3 15048 15049 15337 3 15048 15337 15336 3 15049 15050 15338 3 15049 15338 15337 3 15050 15051 15339 3 15050 15339 15338 3 15051 15052 15340 3 15051 15340 15339 3 15052 15053 15341 3 15052 15341 15340 3 15053 15054 15342 3 15053 15342 15341 3 15054 15055 15343 3 15054 15343 15342 3 15055 15056 15344 3 15055 15344 15343 3 15056 15057 15345 3 15056 15345 15344 3 15057 15058 15346 3 15057 15346 15345 3 15058 15059 15347 3 15058 15347 15346 3 15059 15060 15348 3 15059 15348 15347 3 15060 15061 15349 3 15060 15349 15348 3 15061 15062 15350 3 15061 15350 15349 3 15062 15063 15351 3 15062 15351 15350 3 15063 15064 15352 3 15063 15352 15351 3 15064 15065 15353 3 15064 15353 15352 3 15065 15066 15354 3 15065 15354 15353 3 15066 15067 15355 3 15066 15355 15354 3 15067 15068 15356 3 15067 15356 15355 3 15068 15069 15357 3 15068 15357 15356 3 15069 15070 15358 3 15069 15358 15357 3 15070 15071 15359 3 15070 15359 15358 3 15071 15072 15360 3 15071 15360 15359 3 15072 15073 15361 3 15072 15361 15360 3 15073 15074 15362 3 15073 15362 15361 3 15074 15075 15363 3 15074 15363 15362 3 15075 15076 15364 3 15075 15364 15363 3 15076 15077 15365 3 15076 15365 15364 3 15077 15078 15366 3 15077 15366 15365 3 15078 15079 15367 3 15078 15367 15366 3 15079 15080 15368 3 15079 15368 15367 3 15080 15081 15369 3 15080 15369 15368 3 15081 15082 15370 3 15081 15370 15369 3 15082 15083 15371 3 15082 15371 15370 3 15083 15084 15372 3 15083 15372 15371 3 15085 15373 15374 3 15085 15374 15086 3 15085 15155 15373 3 15443 15373 15155 3 15086 15374 15375 3 15086 15375 15087 3 15087 15375 15376 3 15087 15376 15088 3 15088 15376 15377 3 15088 15377 15089 3 15089 15377 15378 3 15089 15378 15090 3 15090 15378 15379 3 15090 15379 15091 3 15091 15379 15380 3 15091 15380 15092 3 15092 15380 15381 3 15092 15381 15093 3 15093 15381 15382 3 15093 15382 15094 3 15094 15382 15383 3 15094 15383 15095 3 15095 15383 15384 3 15095 15384 15096 3 15096 15384 15385 3 15096 15385 15097 3 15097 15385 15386 3 15097 15386 15098 3 15098 15386 15387 3 15098 15387 15099 3 15099 15387 15388 3 15099 15388 15100 3 15100 15388 15389 3 15100 15389 15101 3 15101 15389 15390 3 15101 15390 15102 3 15102 15390 15391 3 15102 15391 15103 3 15103 15391 15392 3 15103 15392 15104 3 15104 15392 15105 3 15393 15105 15392 3 15105 15393 15106 3 15394 15106 15393 3 15106 15394 15107 3 15395 15107 15394 3 15107 15395 15108 3 15396 15108 15395 3 15108 15396 15109 3 15397 15109 15396 3 15109 15397 15110 3 15398 15110 15397 3 15110 15398 15111 3 15399 15111 15398 3 15111 15399 15112 3 15400 15112 15399 3 15112 15400 15113 3 15401 15113 15400 3 15113 15401 15114 3 15402 15114 15401 3 15114 15402 15115 3 15403 15115 15402 3 15115 15403 15116 3 15404 15116 15403 3 15116 15404 15117 3 15405 15117 15404 3 15117 15405 15118 3 15406 15118 15405 3 15118 15406 15119 3 15407 15119 15406 3 15119 15407 15120 3 15408 15120 15407 3 15120 15408 15121 3 15409 15121 15408 3 15121 15409 15122 3 15410 15122 15409 3 15122 15410 15123 3 15411 15123 15410 3 15123 15411 15124 3 15412 15124 15411 3 15124 15412 15125 3 15413 15125 15412 3 15125 15413 15126 3 15414 15126 15413 3 15126 15414 15127 3 15415 15127 15414 3 15127 15415 15128 3 15416 15128 15415 3 15128 15416 15129 3 15417 15129 15416 3 15129 15417 15130 3 15418 15130 15417 3 15130 15418 15131 3 15419 15131 15418 3 15131 15419 15132 3 15420 15132 15419 3 15132 15420 15133 3 15421 15133 15420 3 15133 15421 15134 3 15422 15134 15421 3 15134 15422 15135 3 15423 15135 15422 3 15135 15423 15136 3 15424 15136 15423 3 15136 15424 15137 3 15425 15137 15424 3 15137 15425 15138 3 15426 15138 15425 3 15138 15426 15139 3 15427 15139 15426 3 15139 15427 15140 3 15428 15140 15427 3 15140 15428 15141 3 15429 15141 15428 3 15141 15429 15142 3 15430 15142 15429 3 15142 15430 15143 3 15431 15143 15430 3 15143 15431 15144 3 15432 15144 15431 3 15144 15432 15145 3 15433 15145 15432 3 15145 15433 15146 3 15434 15146 15433 3 15146 15434 15147 3 15435 15147 15434 3 15147 15435 15148 3 15436 15148 15435 3 15148 15436 15149 3 15437 15149 15436 3 15149 15437 15150 3 15438 15150 15437 3 15150 15438 15151 3 15439 15151 15438 3 15151 15439 15152 3 15440 15152 15439 3 15152 15440 15153 3 15441 15153 15440 3 15153 15441 15156 3 15444 15156 15441 3 15154 15442 15155 3 15443 15155 15442 3 15154 15159 15442 3 15447 15442 15159 3 15156 15444 15157 3 15445 15157 15444 3 15157 15445 15160 3 15448 15160 15445 3 15158 15446 15159 3 15447 15159 15446 3 15158 15162 15446 3 15450 15446 15162 3 15160 15448 15161 3 15449 15161 15448 3 15161 15449 15163 3 15451 15163 15449 3 15162 15164 15450 3 15452 15450 15164 3 15163 15451 15165 3 15453 15165 15451 3 15164 15166 15452 3 15454 15452 15166 3 15165 15453 15167 3 15455 15167 15453 3 15166 15168 15454 3 15456 15454 15168 3 15167 15455 15169 3 15457 15169 15455 3 15168 15170 15456 3 15458 15456 15170 3 15169 15457 15171 3 15459 15171 15457 3 15170 15172 15458 3 15460 15458 15172 3 15171 15459 15173 3 15461 15173 15459 3 15172 15174 15460 3 15462 15460 15174 3 15173 15461 15175 3 15463 15175 15461 3 15174 15176 15462 3 15464 15462 15176 3 15175 15463 15177 3 15465 15177 15463 3 15176 15178 15464 3 15466 15464 15178 3 15177 15465 15179 3 15467 15179 15465 3 15178 15180 15466 3 15468 15466 15180 3 15179 15467 15181 3 15469 15181 15467 3 15180 15182 15468 3 15470 15468 15182 3 15181 15469 15471 3 15181 15471 15183 3 15182 15184 15470 3 15472 15470 15184 3 15183 15471 15473 3 15183 15473 15185 3 15184 15186 15472 3 15474 15472 15186 3 15185 15473 15475 3 15185 15475 15187 3 15186 15188 15474 3 15476 15474 15188 3 15187 15475 15477 3 15187 15477 15189 3 15188 15190 15476 3 15478 15476 15190 3 15189 15477 15479 3 15189 15479 15191 3 15190 15192 15478 3 15480 15478 15192 3 15191 15479 15481 3 15191 15481 15193 3 15192 15194 15482 3 15192 15482 15480 3 15193 15481 15483 3 15193 15483 15195 3 15194 15196 15484 3 15194 15484 15482 3 15195 15483 15485 3 15195 15485 15197 3 15196 15198 15486 3 15196 15486 15484 3 15197 15485 15487 3 15197 15487 15199 3 15198 15200 15488 3 15198 15488 15486 3 15199 15487 15489 3 15199 15489 15201 3 15200 15202 15490 3 15200 15490 15488 3 15201 15489 15491 3 15201 15491 15203 3 15202 15204 15492 3 15202 15492 15490 3 15203 15491 15493 3 15203 15493 15205 3 15204 15206 15494 3 15204 15494 15492 3 15205 15493 15495 3 15205 15495 15207 3 15206 15208 15496 3 15206 15496 15494 3 15207 15495 15497 3 15207 15497 15209 3 15208 15210 15498 3 15208 15498 15496 3 15209 15497 15499 3 15209 15499 15211 3 15210 15212 15500 3 15210 15500 15498 3 15211 15499 15501 3 15211 15501 15213 3 15212 15214 15502 3 15212 15502 15500 3 15213 15501 15503 3 15213 15503 15215 3 15214 15216 15504 3 15214 15504 15502 3 15215 15503 15505 3 15215 15505 15217 3 15216 15218 15506 3 15216 15506 15504 3 15217 15505 15507 3 15217 15507 15219 3 15218 15220 15508 3 15218 15508 15506 3 15219 15507 15509 3 15219 15509 15221 3 15220 15222 15510 3 15220 15510 15508 3 15221 15509 15511 3 15221 15511 15223 3 15222 15224 15512 3 15222 15512 15510 3 15223 15511 15513 3 15223 15513 15225 3 15224 15226 15514 3 15224 15514 15512 3 15225 15513 15515 3 15225 15515 15227 3 15226 15228 15516 3 15226 15516 15514 3 15227 15515 15517 3 15227 15517 15229 3 15228 15230 15518 3 15228 15518 15516 3 15229 15517 15519 3 15229 15519 15231 3 15230 15232 15520 3 15230 15520 15518 3 15231 15519 15521 3 15231 15521 15233 3 15232 15234 15522 3 15232 15522 15520 3 15233 15521 15523 3 15233 15523 15235 3 15234 15236 15524 3 15234 15524 15522 3 15235 15523 15525 3 15235 15525 15237 3 15236 15238 15526 3 15236 15526 15524 3 15237 15525 15527 3 15237 15527 15239 3 15238 15240 15528 3 15238 15528 15526 3 15239 15527 15529 3 15239 15529 15241 3 15240 15242 15530 3 15240 15530 15528 3 15241 15529 15531 3 15241 15531 15243 3 15242 15244 15532 3 15242 15532 15530 3 15243 15531 15533 3 15243 15533 15245 3 15244 15246 15534 3 15244 15534 15532 3 15245 15533 15535 3 15245 15535 15247 3 15246 15248 15536 3 15246 15536 15534 3 15247 15535 15537 3 15247 15537 15249 3 15248 15250 15538 3 15248 15538 15536 3 15249 15537 15539 3 15249 15539 15251 3 15250 15252 15540 3 15250 15540 15538 3 15251 15539 15541 3 15251 15541 15253 3 15252 15254 15542 3 15252 15542 15540 3 15253 15541 15543 3 15253 15543 15255 3 15254 15256 15544 3 15254 15544 15542 3 15255 15543 15545 3 15255 15545 15257 3 15256 15258 15546 3 15256 15546 15544 3 15257 15545 15259 3 15547 15259 15545 3 15258 15260 15548 3 15258 15548 15546 3 15259 15547 15261 3 15549 15261 15547 3 15260 15262 15550 3 15260 15550 15548 3 15261 15549 15263 3 15551 15263 15549 3 15262 15264 15552 3 15262 15552 15550 3 15263 15551 15265 3 15553 15265 15551 3 15264 15266 15554 3 15264 15554 15552 3 15265 15553 15267 3 15555 15267 15553 3 15266 15268 15556 3 15266 15556 15554 3 15267 15555 15269 3 15557 15269 15555 3 15268 15270 15556 3 15558 15556 15270 3 15269 15557 15271 3 15559 15271 15557 3 15270 15272 15558 3 15560 15558 15272 3 15271 15559 15273 3 15561 15273 15559 3 15272 15274 15560 3 15562 15560 15274 3 15273 15561 15275 3 15563 15275 15561 3 15274 15276 15562 3 15564 15562 15276 3 15275 15563 15277 3 15565 15277 15563 3 15276 15278 15564 3 15566 15564 15278 3 15277 15565 15279 3 15567 15279 15565 3 15278 15280 15566 3 15568 15566 15280 3 15279 15567 15281 3 15569 15281 15567 3 15280 15282 15568 3 15570 15568 15282 3 15281 15569 15283 3 15571 15283 15569 3 15282 15284 15570 3 15572 15570 15284 3 15283 15571 15285 3 15573 15285 15571 3 15284 15286 15572 3 15574 15572 15286 3 15285 15573 15287 3 15575 15287 15573 3 15286 15288 15574 3 15576 15574 15288 3 15287 15575 15289 3 15577 15289 15575 3 15288 15290 15576 3 15578 15576 15290 3 15289 15577 15291 3 15579 15291 15577 3 15290 15292 15578 3 15580 15578 15292 3 15291 15579 15293 3 15581 15293 15579 3 15292 15294 15580 3 15582 15580 15294 3 15293 15581 15295 3 15583 15295 15581 3 15294 15296 15582 3 15584 15582 15296 3 15295 15583 15299 3 15587 15299 15583 3 15296 15297 15584 3 15585 15584 15297 3 15297 15300 15585 3 15588 15585 15300 3 15298 15299 15586 3 15587 15586 15299 3 15298 15586 15303 3 15591 15303 15586 3 15300 15301 15588 3 15589 15588 15301 3 15301 15304 15589 3 15592 15589 15304 3 15302 15303 15590 3 15591 15590 15303 3 15302 15590 15372 3 15660 15372 15590 3 15304 15305 15592 3 15593 15592 15305 3 15305 15306 15593 3 15594 15593 15306 3 15306 15307 15594 3 15595 15594 15307 3 15307 15308 15595 3 15596 15595 15308 3 15308 15309 15596 3 15597 15596 15309 3 15309 15310 15597 3 15598 15597 15310 3 15310 15311 15598 3 15599 15598 15311 3 15311 15312 15599 3 15600 15599 15312 3 15312 15313 15600 3 15601 15600 15313 3 15313 15314 15601 3 15602 15601 15314 3 15314 15315 15602 3 15603 15602 15315 3 15315 15316 15603 3 15604 15603 15316 3 15316 15317 15604 3 15605 15604 15317 3 15317 15318 15605 3 15606 15605 15318 3 15318 15319 15606 3 15607 15606 15319 3 15319 15320 15607 3 15608 15607 15320 3 15320 15321 15608 3 15609 15608 15321 3 15321 15322 15609 3 15610 15609 15322 3 15322 15323 15610 3 15611 15610 15323 3 15323 15324 15611 3 15612 15611 15324 3 15324 15325 15612 3 15613 15612 15325 3 15325 15326 15613 3 15614 15613 15326 3 15326 15327 15614 3 15615 15614 15327 3 15327 15328 15615 3 15616 15615 15328 3 15328 15329 15616 3 15617 15616 15329 3 15329 15330 15617 3 15618 15617 15330 3 15330 15331 15618 3 15619 15618 15331 3 15331 15332 15619 3 15620 15619 15332 3 15332 15333 15620 3 15621 15620 15333 3 15333 15334 15621 3 15622 15621 15334 3 15334 15335 15622 3 15623 15622 15335 3 15335 15336 15623 3 15624 15623 15336 3 15336 15337 15624 3 15625 15624 15337 3 15337 15338 15625 3 15626 15625 15338 3 15338 15339 15626 3 15627 15626 15339 3 15339 15340 15627 3 15628 15627 15340 3 15340 15341 15628 3 15629 15628 15341 3 15341 15342 15629 3 15630 15629 15342 3 15342 15343 15630 3 15631 15630 15343 3 15343 15344 15631 3 15632 15631 15344 3 15344 15345 15632 3 15633 15632 15345 3 15345 15346 15634 3 15345 15634 15633 3 15346 15347 15635 3 15346 15635 15634 3 15347 15348 15636 3 15347 15636 15635 3 15348 15349 15637 3 15348 15637 15636 3 15349 15350 15638 3 15349 15638 15637 3 15350 15351 15639 3 15350 15639 15638 3 15351 15352 15640 3 15351 15640 15639 3 15352 15353 15641 3 15352 15641 15640 3 15353 15354 15642 3 15353 15642 15641 3 15354 15355 15643 3 15354 15643 15642 3 15355 15356 15644 3 15355 15644 15643 3 15356 15357 15645 3 15356 15645 15644 3 15357 15358 15646 3 15357 15646 15645 3 15358 15359 15647 3 15358 15647 15646 3 15359 15360 15648 3 15359 15648 15647 3 15360 15361 15649 3 15360 15649 15648 3 15361 15362 15650 3 15361 15650 15649 3 15362 15363 15651 3 15362 15651 15650 3 15363 15364 15652 3 15363 15652 15651 3 15364 15365 15653 3 15364 15653 15652 3 15365 15366 15654 3 15365 15654 15653 3 15366 15367 15655 3 15366 15655 15654 3 15367 15368 15656 3 15367 15656 15655 3 15368 15369 15657 3 15368 15657 15656 3 15369 15370 15658 3 15369 15658 15657 3 15370 15371 15659 3 15370 15659 15658 3 15371 15372 15660 3 15371 15660 15659 3 15373 15661 15662 3 15373 15662 15374 3 15373 15443 15731 3 15373 15731 15661 3 15374 15662 15663 3 15374 15663 15375 3 15375 15663 15664 3 15375 15664 15376 3 15376 15664 15665 3 15376 15665 15377 3 15377 15665 15666 3 15377 15666 15378 3 15378 15666 15667 3 15378 15667 15379 3 15379 15667 15668 3 15379 15668 15380 3 15380 15668 15669 3 15380 15669 15381 3 15381 15669 15670 3 15381 15670 15382 3 15382 15670 15671 3 15382 15671 15383 3 15383 15671 15672 3 15383 15672 15384 3 15384 15672 15673 3 15384 15673 15385 3 15385 15673 15674 3 15385 15674 15386 3 15386 15674 15675 3 15386 15675 15387 3 15387 15675 15676 3 15387 15676 15388 3 15388 15676 15677 3 15388 15677 15389 3 15389 15677 15678 3 15389 15678 15390 3 15390 15678 15679 3 15390 15679 15391 3 15391 15679 15680 3 15391 15680 15392 3 15392 15680 15681 3 15392 15681 15393 3 15393 15681 15682 3 15393 15682 15394 3 15394 15682 15683 3 15394 15683 15395 3 15395 15683 15684 3 15395 15684 15396 3 15396 15684 15685 3 15396 15685 15397 3 15397 15685 15686 3 15397 15686 15398 3 15398 15686 15687 3 15398 15687 15399 3 15399 15687 15688 3 15399 15688 15400 3 15400 15688 15689 3 15400 15689 15401 3 15401 15689 15690 3 15401 15690 15402 3 15402 15690 15691 3 15402 15691 15403 3 15403 15691 15692 3 15403 15692 15404 3 15404 15692 15693 3 15404 15693 15405 3 15405 15693 15694 3 15405 15694 15406 3 15406 15694 15695 3 15406 15695 15407 3 15407 15695 15696 3 15407 15696 15408 3 15408 15696 15697 3 15408 15697 15409 3 15409 15697 15698 3 15409 15698 15410 3 15410 15698 15411 3 15699 15411 15698 3 15411 15699 15412 3 15700 15412 15699 3 15412 15700 15413 3 15701 15413 15700 3 15413 15701 15414 3 15702 15414 15701 3 15414 15702 15415 3 15703 15415 15702 3 15415 15703 15416 3 15704 15416 15703 3 15416 15704 15417 3 15705 15417 15704 3 15417 15705 15418 3 15706 15418 15705 3 15418 15706 15419 3 15707 15419 15706 3 15419 15707 15420 3 15708 15420 15707 3 15420 15708 15421 3 15709 15421 15708 3 15421 15709 15422 3 15710 15422 15709 3 15422 15710 15423 3 15711 15423 15710 3 15423 15711 15424 3 15712 15424 15711 3 15424 15712 15425 3 15713 15425 15712 3 15425 15713 15426 3 15714 15426 15713 3 15426 15714 15427 3 15715 15427 15714 3 15427 15715 15428 3 15716 15428 15715 3 15428 15716 15429 3 15717 15429 15716 3 15429 15717 15430 3 15718 15430 15717 3 15430 15718 15431 3 15719 15431 15718 3 15431 15719 15432 3 15720 15432 15719 3 15432 15720 15433 3 15721 15433 15720 3 15433 15721 15434 3 15722 15434 15721 3 15434 15722 15435 3 15723 15435 15722 3 15435 15723 15436 3 15724 15436 15723 3 15436 15724 15437 3 15725 15437 15724 3 15437 15725 15438 3 15726 15438 15725 3 15438 15726 15439 3 15727 15439 15726 3 15439 15727 15440 3 15728 15440 15727 3 15440 15728 15441 3 15729 15441 15728 3 15441 15729 15444 3 15732 15444 15729 3 15442 15730 15443 3 15731 15443 15730 3 15442 15447 15730 3 15735 15730 15447 3 15444 15732 15445 3 15733 15445 15732 3 15445 15733 15448 3 15736 15448 15733 3 15446 15734 15447 3 15735 15447 15734 3 15446 15450 15734 3 15738 15734 15450 3 15448 15736 15449 3 15737 15449 15736 3 15449 15737 15451 3 15739 15451 15737 3 15450 15452 15738 3 15740 15738 15452 3 15451 15739 15453 3 15741 15453 15739 3 15452 15454 15740 3 15742 15740 15454 3 15453 15741 15455 3 15743 15455 15741 3 15454 15456 15742 3 15744 15742 15456 3 15455 15743 15457 3 15745 15457 15743 3 15456 15458 15744 3 15746 15744 15458 3 15457 15745 15459 3 15747 15459 15745 3 15458 15460 15746 3 15748 15746 15460 3 15459 15747 15461 3 15749 15461 15747 3 15460 15462 15748 3 15750 15748 15462 3 15461 15749 15463 3 15751 15463 15749 3 15462 15464 15750 3 15752 15750 15464 3 15463 15751 15465 3 15753 15465 15751 3 15464 15466 15752 3 15754 15752 15466 3 15465 15753 15467 3 15755 15467 15753 3 15466 15468 15754 3 15756 15754 15468 3 15467 15755 15469 3 15757 15469 15755 3 15468 15470 15756 3 15758 15756 15470 3 15469 15757 15471 3 15759 15471 15757 3 15470 15472 15758 3 15760 15758 15472 3 15471 15759 15473 3 15761 15473 15759 3 15472 15474 15760 3 15762 15760 15474 3 15473 15761 15475 3 15763 15475 15761 3 15474 15476 15762 3 15764 15762 15476 3 15475 15763 15477 3 15765 15477 15763 3 15476 15478 15764 3 15766 15764 15478 3 15477 15765 15479 3 15767 15479 15765 3 15478 15480 15766 3 15768 15766 15480 3 15479 15767 15481 3 15769 15481 15767 3 15480 15482 15768 3 15770 15768 15482 3 15481 15769 15483 3 15771 15483 15769 3 15482 15484 15770 3 15772 15770 15484 3 15483 15771 15485 3 15773 15485 15771 3 15484 15486 15772 3 15774 15772 15486 3 15485 15773 15487 3 15775 15487 15773 3 15486 15488 15774 3 15776 15774 15488 3 15487 15775 15777 3 15487 15777 15489 3 15488 15490 15776 3 15778 15776 15490 3 15489 15777 15779 3 15489 15779 15491 3 15490 15492 15778 3 15780 15778 15492 3 15491 15779 15781 3 15491 15781 15493 3 15492 15494 15780 3 15782 15780 15494 3 15493 15781 15783 3 15493 15783 15495 3 15494 15496 15782 3 15784 15782 15496 3 15495 15783 15785 3 15495 15785 15497 3 15496 15498 15784 3 15786 15784 15498 3 15497 15785 15787 3 15497 15787 15499 3 15498 15500 15788 3 15498 15788 15786 3 15499 15787 15789 3 15499 15789 15501 3 15500 15502 15790 3 15500 15790 15788 3 15501 15789 15791 3 15501 15791 15503 3 15502 15504 15792 3 15502 15792 15790 3 15503 15791 15793 3 15503 15793 15505 3 15504 15506 15794 3 15504 15794 15792 3 15505 15793 15795 3 15505 15795 15507 3 15506 15508 15796 3 15506 15796 15794 3 15507 15795 15797 3 15507 15797 15509 3 15508 15510 15798 3 15508 15798 15796 3 15509 15797 15799 3 15509 15799 15511 3 15510 15512 15800 3 15510 15800 15798 3 15511 15799 15801 3 15511 15801 15513 3 15512 15514 15802 3 15512 15802 15800 3 15513 15801 15803 3 15513 15803 15515 3 15514 15516 15804 3 15514 15804 15802 3 15515 15803 15805 3 15515 15805 15517 3 15516 15518 15806 3 15516 15806 15804 3 15517 15805 15807 3 15517 15807 15519 3 15518 15520 15808 3 15518 15808 15806 3 15519 15807 15809 3 15519 15809 15521 3 15520 15522 15810 3 15520 15810 15808 3 15521 15809 15811 3 15521 15811 15523 3 15522 15524 15812 3 15522 15812 15810 3 15523 15811 15813 3 15523 15813 15525 3 15524 15526 15814 3 15524 15814 15812 3 15525 15813 15815 3 15525 15815 15527 3 15526 15528 15816 3 15526 15816 15814 3 15527 15815 15817 3 15527 15817 15529 3 15528 15530 15818 3 15528 15818 15816 3 15529 15817 15819 3 15529 15819 15531 3 15530 15532 15820 3 15530 15820 15818 3 15531 15819 15821 3 15531 15821 15533 3 15532 15534 15822 3 15532 15822 15820 3 15533 15821 15823 3 15533 15823 15535 3 15534 15536 15824 3 15534 15824 15822 3 15535 15823 15825 3 15535 15825 15537 3 15536 15538 15826 3 15536 15826 15824 3 15537 15825 15827 3 15537 15827 15539 3 15538 15540 15828 3 15538 15828 15826 3 15539 15827 15829 3 15539 15829 15541 3 15540 15542 15830 3 15540 15830 15828 3 15541 15829 15831 3 15541 15831 15543 3 15542 15544 15832 3 15542 15832 15830 3 15543 15831 15833 3 15543 15833 15545 3 15544 15546 15834 3 15544 15834 15832 3 15545 15833 15835 3 15545 15835 15547 3 15546 15548 15836 3 15546 15836 15834 3 15547 15835 15837 3 15547 15837 15549 3 15548 15550 15838 3 15548 15838 15836 3 15549 15837 15839 3 15549 15839 15551 3 15550 15552 15840 3 15550 15840 15838 3 15551 15839 15841 3 15551 15841 15553 3 15552 15554 15842 3 15552 15842 15840 3 15553 15841 15843 3 15553 15843 15555 3 15554 15556 15844 3 15554 15844 15842 3 15555 15843 15845 3 15555 15845 15557 3 15556 15558 15846 3 15556 15846 15844 3 15557 15845 15847 3 15557 15847 15559 3 15558 15560 15848 3 15558 15848 15846 3 15559 15847 15849 3 15559 15849 15561 3 15560 15562 15850 3 15560 15850 15848 3 15561 15849 15851 3 15561 15851 15563 3 15562 15564 15852 3 15562 15852 15850 3 15563 15851 15853 3 15563 15853 15565 3 15564 15566 15854 3 15564 15854 15852 3 15565 15853 15567 3 15855 15567 15853 3 15566 15568 15856 3 15566 15856 15854 3 15567 15855 15569 3 15857 15569 15855 3 15568 15570 15858 3 15568 15858 15856 3 15569 15857 15571 3 15859 15571 15857 3 15570 15572 15860 3 15570 15860 15858 3 15571 15859 15573 3 15861 15573 15859 3 15572 15574 15862 3 15572 15862 15860 3 15573 15861 15575 3 15863 15575 15861 3 15574 15576 15862 3 15864 15862 15576 3 15575 15863 15577 3 15865 15577 15863 3 15576 15578 15864 3 15866 15864 15578 3 15577 15865 15579 3 15867 15579 15865 3 15578 15580 15866 3 15868 15866 15580 3 15579 15867 15581 3 15869 15581 15867 3 15580 15582 15868 3 15870 15868 15582 3 15581 15869 15583 3 15871 15583 15869 3 15582 15584 15870 3 15872 15870 15584 3 15583 15871 15587 3 15875 15587 15871 3 15584 15585 15872 3 15873 15872 15585 3 15585 15588 15873 3 15876 15873 15588 3 15586 15587 15874 3 15875 15874 15587 3 15586 15874 15591 3 15879 15591 15874 3 15588 15589 15876 3 15877 15876 15589 3 15589 15592 15877 3 15880 15877 15592 3 15590 15591 15878 3 15879 15878 15591 3 15590 15878 15660 3 15948 15660 15878 3 15592 15593 15880 3 15881 15880 15593 3 15593 15594 15881 3 15882 15881 15594 3 15594 15595 15882 3 15883 15882 15595 3 15595 15596 15883 3 15884 15883 15596 3 15596 15597 15884 3 15885 15884 15597 3 15597 15598 15885 3 15886 15885 15598 3 15598 15599 15886 3 15887 15886 15599 3 15599 15600 15887 3 15888 15887 15600 3 15600 15601 15888 3 15889 15888 15601 3 15601 15602 15889 3 15890 15889 15602 3 15602 15603 15890 3 15891 15890 15603 3 15603 15604 15891 3 15892 15891 15604 3 15604 15605 15892 3 15893 15892 15605 3 15605 15606 15893 3 15894 15893 15606 3 15606 15607 15894 3 15895 15894 15607 3 15607 15608 15895 3 15896 15895 15608 3 15608 15609 15896 3 15897 15896 15609 3 15609 15610 15897 3 15898 15897 15610 3 15610 15611 15898 3 15899 15898 15611 3 15611 15612 15899 3 15900 15899 15612 3 15612 15613 15900 3 15901 15900 15613 3 15613 15614 15901 3 15902 15901 15614 3 15614 15615 15902 3 15903 15902 15615 3 15615 15616 15903 3 15904 15903 15616 3 15616 15617 15904 3 15905 15904 15617 3 15617 15618 15905 3 15906 15905 15618 3 15618 15619 15906 3 15907 15906 15619 3 15619 15620 15907 3 15908 15907 15620 3 15620 15621 15908 3 15909 15908 15621 3 15621 15622 15909 3 15910 15909 15622 3 15622 15623 15910 3 15911 15910 15623 3 15623 15624 15911 3 15912 15911 15624 3 15624 15625 15912 3 15913 15912 15625 3 15625 15626 15913 3 15914 15913 15626 3 15626 15627 15914 3 15915 15914 15627 3 15627 15628 15915 3 15916 15915 15628 3 15628 15629 15916 3 15917 15916 15629 3 15629 15630 15917 3 15918 15917 15630 3 15630 15631 15918 3 15919 15918 15631 3 15631 15632 15919 3 15920 15919 15632 3 15632 15633 15920 3 15921 15920 15633 3 15633 15634 15921 3 15922 15921 15634 3 15634 15635 15922 3 15923 15922 15635 3 15635 15636 15923 3 15924 15923 15636 3 15636 15637 15924 3 15925 15924 15637 3 15637 15638 15925 3 15926 15925 15638 3 15638 15639 15926 3 15927 15926 15639 3 15639 15640 15927 3 15928 15927 15640 3 15640 15641 15928 3 15929 15928 15641 3 15641 15642 15929 3 15930 15929 15642 3 15642 15643 15930 3 15931 15930 15643 3 15643 15644 15931 3 15932 15931 15644 3 15644 15645 15932 3 15933 15932 15645 3 15645 15646 15933 3 15934 15933 15646 3 15646 15647 15934 3 15935 15934 15647 3 15647 15648 15935 3 15936 15935 15648 3 15648 15649 15936 3 15937 15936 15649 3 15649 15650 15937 3 15938 15937 15650 3 15650 15651 15938 3 15939 15938 15651 3 15651 15652 15939 3 15940 15939 15652 3 15652 15653 15941 3 15652 15941 15940 3 15653 15654 15942 3 15653 15942 15941 3 15654 15655 15943 3 15654 15943 15942 3 15655 15656 15944 3 15655 15944 15943 3 15656 15657 15945 3 15656 15945 15944 3 15657 15658 15946 3 15657 15946 15945 3 15658 15659 15947 3 15658 15947 15946 3 15659 15660 15948 3 15659 15948 15947 3 15661 15949 15950 3 15661 15950 15662 3 15661 15731 16019 3 15661 16019 15949 3 15662 15950 15951 3 15662 15951 15663 3 15663 15951 15952 3 15663 15952 15664 3 15664 15952 15953 3 15664 15953 15665 3 15665 15953 15954 3 15665 15954 15666 3 15666 15954 15955 3 15666 15955 15667 3 15667 15955 15956 3 15667 15956 15668 3 15668 15956 15957 3 15668 15957 15669 3 15669 15957 15958 3 15669 15958 15670 3 15670 15958 15959 3 15670 15959 15671 3 15671 15959 15960 3 15671 15960 15672 3 15672 15960 15961 3 15672 15961 15673 3 15673 15961 15962 3 15673 15962 15674 3 15674 15962 15963 3 15674 15963 15675 3 15675 15963 15964 3 15675 15964 15676 3 15676 15964 15965 3 15676 15965 15677 3 15677 15965 15966 3 15677 15966 15678 3 15678 15966 15967 3 15678 15967 15679 3 15679 15967 15968 3 15679 15968 15680 3 15680 15968 15969 3 15680 15969 15681 3 15681 15969 15970 3 15681 15970 15682 3 15682 15970 15971 3 15682 15971 15683 3 15683 15971 15972 3 15683 15972 15684 3 15684 15972 15973 3 15684 15973 15685 3 15685 15973 15974 3 15685 15974 15686 3 15686 15974 15975 3 15686 15975 15687 3 15687 15975 15976 3 15687 15976 15688 3 15688 15976 15977 3 15688 15977 15689 3 15689 15977 15978 3 15689 15978 15690 3 15690 15978 15979 3 15690 15979 15691 3 15691 15979 15980 3 15691 15980 15692 3 15692 15980 15981 3 15692 15981 15693 3 15693 15981 15982 3 15693 15982 15694 3 15694 15982 15983 3 15694 15983 15695 3 15695 15983 15984 3 15695 15984 15696 3 15696 15984 15985 3 15696 15985 15697 3 15697 15985 15986 3 15697 15986 15698 3 15698 15986 15987 3 15698 15987 15699 3 15699 15987 15988 3 15699 15988 15700 3 15700 15988 15989 3 15700 15989 15701 3 15701 15989 15990 3 15701 15990 15702 3 15702 15990 15991 3 15702 15991 15703 3 15703 15991 15992 3 15703 15992 15704 3 15704 15992 15993 3 15704 15993 15705 3 15705 15993 15994 3 15705 15994 15706 3 15706 15994 15995 3 15706 15995 15707 3 15707 15995 15996 3 15707 15996 15708 3 15708 15996 15997 3 15708 15997 15709 3 15709 15997 15998 3 15709 15998 15710 3 15710 15998 15999 3 15710 15999 15711 3 15711 15999 16000 3 15711 16000 15712 3 15712 16000 16001 3 15712 16001 15713 3 15713 16001 16002 3 15713 16002 15714 3 15714 16002 16003 3 15714 16003 15715 3 15715 16003 16004 3 15715 16004 15716 3 15716 16004 16005 3 15716 16005 15717 3 15717 16005 16006 3 15717 16006 15718 3 15718 16006 15719 3 16007 15719 16006 3 15719 16007 15720 3 16008 15720 16007 3 15720 16008 15721 3 16009 15721 16008 3 15721 16009 15722 3 16010 15722 16009 3 15722 16010 15723 3 16011 15723 16010 3 15723 16011 15724 3 16012 15724 16011 3 15724 16012 15725 3 16013 15725 16012 3 15725 16013 15726 3 16014 15726 16013 3 15726 16014 15727 3 16015 15727 16014 3 15727 16015 15728 3 16016 15728 16015 3 15728 16016 15729 3 16017 15729 16016 3 15729 16017 15732 3 16020 15732 16017 3 15730 16018 15731 3 16019 15731 16018 3 15730 15735 16018 3 16023 16018 15735 3 15732 16020 15733 3 16021 15733 16020 3 15733 16021 15736 3 16024 15736 16021 3 15734 16022 15735 3 16023 15735 16022 3 15734 15738 16022 3 16026 16022 15738 3 15736 16024 15737 3 16025 15737 16024 3 15737 16025 15739 3 16027 15739 16025 3 15738 15740 16026 3 16028 16026 15740 3 15739 16027 15741 3 16029 15741 16027 3 15740 15742 16028 3 16030 16028 15742 3 15741 16029 15743 3 16031 15743 16029 3 15742 15744 16030 3 16032 16030 15744 3 15743 16031 15745 3 16033 15745 16031 3 15744 15746 16032 3 16034 16032 15746 3 15745 16033 15747 3 16035 15747 16033 3 15746 15748 16034 3 16036 16034 15748 3 15747 16035 15749 3 16037 15749 16035 3 15748 15750 16036 3 16038 16036 15750 3 15749 16037 15751 3 16039 15751 16037 3 15750 15752 16038 3 16040 16038 15752 3 15751 16039 15753 3 16041 15753 16039 3 15752 15754 16040 3 16042 16040 15754 3 15753 16041 15755 3 16043 15755 16041 3 15754 15756 16042 3 16044 16042 15756 3 15755 16043 15757 3 16045 15757 16043 3 15756 15758 16044 3 16046 16044 15758 3 15757 16045 15759 3 16047 15759 16045 3 15758 15760 16046 3 16048 16046 15760 3 15759 16047 15761 3 16049 15761 16047 3 15760 15762 16048 3 16050 16048 15762 3 15761 16049 15763 3 16051 15763 16049 3 15762 15764 16050 3 16052 16050 15764 3 15763 16051 15765 3 16053 15765 16051 3 15764 15766 16052 3 16054 16052 15766 3 15765 16053 15767 3 16055 15767 16053 3 15766 15768 16054 3 16056 16054 15768 3 15767 16055 15769 3 16057 15769 16055 3 15768 15770 16056 3 16058 16056 15770 3 15769 16057 15771 3 16059 15771 16057 3 15770 15772 16058 3 16060 16058 15772 3 15771 16059 15773 3 16061 15773 16059 3 15772 15774 16060 3 16062 16060 15774 3 15773 16061 15775 3 16063 15775 16061 3 15774 15776 16062 3 16064 16062 15776 3 15775 16063 15777 3 16065 15777 16063 3 15776 15778 16064 3 16066 16064 15778 3 15777 16065 15779 3 16067 15779 16065 3 15778 15780 16066 3 16068 16066 15780 3 15779 16067 15781 3 16069 15781 16067 3 15780 15782 16068 3 16070 16068 15782 3 15781 16069 15783 3 16071 15783 16069 3 15782 15784 16070 3 16072 16070 15784 3 15783 16071 15785 3 16073 15785 16071 3 15784 15786 16072 3 16074 16072 15786 3 15785 16073 15787 3 16075 15787 16073 3 15786 15788 16074 3 16076 16074 15788 3 15787 16075 15789 3 16077 15789 16075 3 15788 15790 16076 3 16078 16076 15790 3 15789 16077 15791 3 16079 15791 16077 3 15790 15792 16078 3 16080 16078 15792 3 15791 16079 15793 3 16081 15793 16079 3 15792 15794 16080 3 16082 16080 15794 3 15793 16081 15795 3 16083 15795 16081 3 15794 15796 16082 3 16084 16082 15796 3 15795 16083 15797 3 16085 15797 16083 3 15796 15798 16084 3 16086 16084 15798 3 15797 16085 16087 3 15797 16087 15799 3 15798 15800 16086 3 16088 16086 15800 3 15799 16087 16089 3 15799 16089 15801 3 15800 15802 16088 3 16090 16088 15802 3 15801 16089 16091 3 15801 16091 15803 3 15802 15804 16090 3 16092 16090 15804 3 15803 16091 16093 3 15803 16093 15805 3 15804 15806 16092 3 16094 16092 15806 3 15805 16093 16095 3 15805 16095 15807 3 15806 15808 16096 3 15806 16096 16094 3 15807 16095 16097 3 15807 16097 15809 3 15808 15810 16098 3 15808 16098 16096 3 15809 16097 16099 3 15809 16099 15811 3 15810 15812 16100 3 15810 16100 16098 3 15811 16099 16101 3 15811 16101 15813 3 15812 15814 16102 3 15812 16102 16100 3 15813 16101 16103 3 15813 16103 15815 3 15814 15816 16104 3 15814 16104 16102 3 15815 16103 16105 3 15815 16105 15817 3 15816 15818 16106 3 15816 16106 16104 3 15817 16105 16107 3 15817 16107 15819 3 15818 15820 16108 3 15818 16108 16106 3 15819 16107 16109 3 15819 16109 15821 3 15820 15822 16110 3 15820 16110 16108 3 15821 16109 16111 3 15821 16111 15823 3 15822 15824 16112 3 15822 16112 16110 3 15823 16111 16113 3 15823 16113 15825 3 15824 15826 16114 3 15824 16114 16112 3 15825 16113 16115 3 15825 16115 15827 3 15826 15828 16116 3 15826 16116 16114 3 15827 16115 16117 3 15827 16117 15829 3 15828 15830 16118 3 15828 16118 16116 3 15829 16117 16119 3 15829 16119 15831 3 15830 15832 16120 3 15830 16120 16118 3 15831 16119 16121 3 15831 16121 15833 3 15832 15834 16122 3 15832 16122 16120 3 15833 16121 16123 3 15833 16123 15835 3 15834 15836 16124 3 15834 16124 16122 3 15835 16123 16125 3 15835 16125 15837 3 15836 15838 16126 3 15836 16126 16124 3 15837 16125 16127 3 15837 16127 15839 3 15838 15840 16128 3 15838 16128 16126 3 15839 16127 16129 3 15839 16129 15841 3 15840 15842 16130 3 15840 16130 16128 3 15841 16129 16131 3 15841 16131 15843 3 15842 15844 16132 3 15842 16132 16130 3 15843 16131 16133 3 15843 16133 15845 3 15844 15846 16134 3 15844 16134 16132 3 15845 16133 16135 3 15845 16135 15847 3 15846 15848 16136 3 15846 16136 16134 3 15847 16135 16137 3 15847 16137 15849 3 15848 15850 16138 3 15848 16138 16136 3 15849 16137 16139 3 15849 16139 15851 3 15850 15852 16140 3 15850 16140 16138 3 15851 16139 16141 3 15851 16141 15853 3 15852 15854 16142 3 15852 16142 16140 3 15853 16141 16143 3 15853 16143 15855 3 15854 15856 16144 3 15854 16144 16142 3 15855 16143 16145 3 15855 16145 15857 3 15856 15858 16146 3 15856 16146 16144 3 15857 16145 16147 3 15857 16147 15859 3 15858 15860 16148 3 15858 16148 16146 3 15859 16147 16149 3 15859 16149 15861 3 15860 15862 16150 3 15860 16150 16148 3 15861 16149 16151 3 15861 16151 15863 3 15862 15864 16152 3 15862 16152 16150 3 15863 16151 16153 3 15863 16153 15865 3 15864 15866 16154 3 15864 16154 16152 3 15865 16153 16155 3 15865 16155 15867 3 15866 15868 16156 3 15866 16156 16154 3 15867 16155 16157 3 15867 16157 15869 3 15868 15870 16158 3 15868 16158 16156 3 15869 16157 16159 3 15869 16159 15871 3 15870 15872 16160 3 15870 16160 16158 3 15871 16159 16163 3 15871 16163 15875 3 15872 15873 16161 3 15872 16161 16160 3 15873 15876 16164 3 15873 16164 16161 3 15874 15875 16163 3 15874 16163 16162 3 15874 16162 15879 3 16167 15879 16162 3 15876 15877 16165 3 15876 16165 16164 3 15877 15880 16168 3 15877 16168 16165 3 15878 15879 16167 3 15878 16167 16166 3 15878 16166 15948 3 16236 15948 16166 3 15880 15881 16169 3 15880 16169 16168 3 15881 15882 16170 3 15881 16170 16169 3 15882 15883 16171 3 15882 16171 16170 3 15883 15884 16171 3 16172 16171 15884 3 15884 15885 16172 3 16173 16172 15885 3 15885 15886 16173 3 16174 16173 15886 3 15886 15887 16174 3 16175 16174 15887 3 15887 15888 16175 3 16176 16175 15888 3 15888 15889 16176 3 16177 16176 15889 3 15889 15890 16177 3 16178 16177 15890 3 15890 15891 16178 3 16179 16178 15891 3 15891 15892 16179 3 16180 16179 15892 3 15892 15893 16180 3 16181 16180 15893 3 15893 15894 16181 3 16182 16181 15894 3 15894 15895 16182 3 16183 16182 15895 3 15895 15896 16183 3 16184 16183 15896 3 15896 15897 16184 3 16185 16184 15897 3 15897 15898 16185 3 16186 16185 15898 3 15898 15899 16186 3 16187 16186 15899 3 15899 15900 16187 3 16188 16187 15900 3 15900 15901 16188 3 16189 16188 15901 3 15901 15902 16189 3 16190 16189 15902 3 15902 15903 16190 3 16191 16190 15903 3 15903 15904 16191 3 16192 16191 15904 3 15904 15905 16192 3 16193 16192 15905 3 15905 15906 16193 3 16194 16193 15906 3 15906 15907 16194 3 16195 16194 15907 3 15907 15908 16195 3 16196 16195 15908 3 15908 15909 16196 3 16197 16196 15909 3 15909 15910 16197 3 16198 16197 15910 3 15910 15911 16198 3 16199 16198 15911 3 15911 15912 16199 3 16200 16199 15912 3 15912 15913 16200 3 16201 16200 15913 3 15913 15914 16201 3 16202 16201 15914 3 15914 15915 16202 3 16203 16202 15915 3 15915 15916 16203 3 16204 16203 15916 3 15916 15917 16204 3 16205 16204 15917 3 15917 15918 16205 3 16206 16205 15918 3 15918 15919 16206 3 16207 16206 15919 3 15919 15920 16207 3 16208 16207 15920 3 15920 15921 16208 3 16209 16208 15921 3 15921 15922 16209 3 16210 16209 15922 3 15922 15923 16210 3 16211 16210 15923 3 15923 15924 16211 3 16212 16211 15924 3 15924 15925 16212 3 16213 16212 15925 3 15925 15926 16213 3 16214 16213 15926 3 15926 15927 16214 3 16215 16214 15927 3 15927 15928 16215 3 16216 16215 15928 3 15928 15929 16216 3 16217 16216 15929 3 15929 15930 16217 3 16218 16217 15930 3 15930 15931 16218 3 16219 16218 15931 3 15931 15932 16219 3 16220 16219 15932 3 15932 15933 16220 3 16221 16220 15933 3 15933 15934 16221 3 16222 16221 15934 3 15934 15935 16222 3 16223 16222 15935 3 15935 15936 16223 3 16224 16223 15936 3 15936 15937 16224 3 16225 16224 15937 3 15937 15938 16225 3 16226 16225 15938 3 15938 15939 16226 3 16227 16226 15939 3 15939 15940 16227 3 16228 16227 15940 3 15940 15941 16228 3 16229 16228 15941 3 15941 15942 16229 3 16230 16229 15942 3 15942 15943 16230 3 16231 16230 15943 3 15943 15944 16231 3 16232 16231 15944 3 15944 15945 16232 3 16233 16232 15945 3 15945 15946 16233 3 16234 16233 15946 3 15946 15947 16234 3 16235 16234 15947 3 15947 15948 16235 3 16236 16235 15948 3 15949 16237 15950 3 16238 15950 16237 3 15949 16019 16307 3 15949 16307 16237 3 15950 16238 15951 3 16239 15951 16238 3 15951 16239 15952 3 16240 15952 16239 3 15952 16240 16241 3 15952 16241 15953 3 15953 16241 16242 3 15953 16242 15954 3 15954 16242 16243 3 15954 16243 15955 3 15955 16243 16244 3 15955 16244 15956 3 15956 16244 16245 3 15956 16245 15957 3 15957 16245 16246 3 15957 16246 15958 3 15958 16246 16247 3 15958 16247 15959 3 15959 16247 16248 3 15959 16248 15960 3 15960 16248 16249 3 15960 16249 15961 3 15961 16249 16250 3 15961 16250 15962 3 15962 16250 16251 3 15962 16251 15963 3 15963 16251 16252 3 15963 16252 15964 3 15964 16252 16253 3 15964 16253 15965 3 15965 16253 16254 3 15965 16254 15966 3 15966 16254 16255 3 15966 16255 15967 3 15967 16255 16256 3 15967 16256 15968 3 15968 16256 16257 3 15968 16257 15969 3 15969 16257 16258 3 15969 16258 15970 3 15970 16258 16259 3 15970 16259 15971 3 15971 16259 16260 3 15971 16260 15972 3 15972 16260 16261 3 15972 16261 15973 3 15973 16261 16262 3 15973 16262 15974 3 15974 16262 16263 3 15974 16263 15975 3 15975 16263 16264 3 15975 16264 15976 3 15976 16264 16265 3 15976 16265 15977 3 15977 16265 16266 3 15977 16266 15978 3 15978 16266 16267 3 15978 16267 15979 3 15979 16267 16268 3 15979 16268 15980 3 15980 16268 16269 3 15980 16269 15981 3 15981 16269 16270 3 15981 16270 15982 3 15982 16270 16271 3 15982 16271 15983 3 15983 16271 16272 3 15983 16272 15984 3 15984 16272 16273 3 15984 16273 15985 3 15985 16273 16274 3 15985 16274 15986 3 15986 16274 16275 3 15986 16275 15987 3 15987 16275 16276 3 15987 16276 15988 3 15988 16276 16277 3 15988 16277 15989 3 15989 16277 16278 3 15989 16278 15990 3 15990 16278 16279 3 15990 16279 15991 3 15991 16279 16280 3 15991 16280 15992 3 15992 16280 16281 3 15992 16281 15993 3 15993 16281 16282 3 15993 16282 15994 3 15994 16282 16283 3 15994 16283 15995 3 15995 16283 16284 3 15995 16284 15996 3 15996 16284 16285 3 15996 16285 15997 3 15997 16285 16286 3 15997 16286 15998 3 15998 16286 16287 3 15998 16287 15999 3 15999 16287 16288 3 15999 16288 16000 3 16000 16288 16289 3 16000 16289 16001 3 16001 16289 16290 3 16001 16290 16002 3 16002 16290 16291 3 16002 16291 16003 3 16003 16291 16292 3 16003 16292 16004 3 16004 16292 16293 3 16004 16293 16005 3 16005 16293 16294 3 16005 16294 16006 3 16006 16294 16295 3 16006 16295 16007 3 16007 16295 16296 3 16007 16296 16008 3 16008 16296 16297 3 16008 16297 16009 3 16009 16297 16298 3 16009 16298 16010 3 16010 16298 16299 3 16010 16299 16011 3 16011 16299 16300 3 16011 16300 16012 3 16012 16300 16301 3 16012 16301 16013 3 16013 16301 16302 3 16013 16302 16014 3 16014 16302 16303 3 16014 16303 16015 3 16015 16303 16304 3 16015 16304 16016 3 16016 16304 16305 3 16016 16305 16017 3 16017 16305 16308 3 16017 16308 16020 3 16018 16306 16307 3 16018 16307 16019 3 16018 16023 16311 3 16018 16311 16306 3 16020 16308 16309 3 16020 16309 16021 3 16021 16309 16312 3 16021 16312 16024 3 16022 16310 16311 3 16022 16311 16023 3 16022 16026 16314 3 16022 16314 16310 3 16024 16312 16313 3 16024 16313 16025 3 16025 16313 16315 3 16025 16315 16027 3 16026 16028 16316 3 16026 16316 16314 3 16027 16315 16317 3 16027 16317 16029 3 16028 16030 16318 3 16028 16318 16316 3 16029 16317 16319 3 16029 16319 16031 3 16030 16032 16320 3 16030 16320 16318 3 16031 16319 16033 3 16321 16033 16319 3 16032 16034 16322 3 16032 16322 16320 3 16033 16321 16035 3 16323 16035 16321 3 16034 16036 16324 3 16034 16324 16322 3 16035 16323 16037 3 16325 16037 16323 3 16036 16038 16326 3 16036 16326 16324 3 16037 16325 16039 3 16327 16039 16325 3 16038 16040 16326 3 16328 16326 16040 3 16039 16327 16041 3 16329 16041 16327 3 16040 16042 16328 3 16330 16328 16042 3 16041 16329 16043 3 16331 16043 16329 3 16042 16044 16330 3 16332 16330 16044 3 16043 16331 16045 3 16333 16045 16331 3 16044 16046 16332 3 16334 16332 16046 3 16045 16333 16047 3 16335 16047 16333 3 16046 16048 16334 3 16336 16334 16048 3 16047 16335 16049 3 16337 16049 16335 3 16048 16050 16336 3 16338 16336 16050 3 16049 16337 16051 3 16339 16051 16337 3 16050 16052 16338 3 16340 16338 16052 3 16051 16339 16053 3 16341 16053 16339 3 16052 16054 16340 3 16342 16340 16054 3 16053 16341 16055 3 16343 16055 16341 3 16054 16056 16342 3 16344 16342 16056 3 16055 16343 16057 3 16345 16057 16343 3 16056 16058 16344 3 16346 16344 16058 3 16057 16345 16059 3 16347 16059 16345 3 16058 16060 16346 3 16348 16346 16060 3 16059 16347 16061 3 16349 16061 16347 3 16060 16062 16348 3 16350 16348 16062 3 16061 16349 16063 3 16351 16063 16349 3 16062 16064 16350 3 16352 16350 16064 3 16063 16351 16065 3 16353 16065 16351 3 16064 16066 16352 3 16354 16352 16066 3 16065 16353 16067 3 16355 16067 16353 3 16066 16068 16354 3 16356 16354 16068 3 16067 16355 16069 3 16357 16069 16355 3 16068 16070 16356 3 16358 16356 16070 3 16069 16357 16071 3 16359 16071 16357 3 16070 16072 16358 3 16360 16358 16072 3 16071 16359 16073 3 16361 16073 16359 3 16072 16074 16360 3 16362 16360 16074 3 16073 16361 16075 3 16363 16075 16361 3 16074 16076 16362 3 16364 16362 16076 3 16075 16363 16077 3 16365 16077 16363 3 16076 16078 16364 3 16366 16364 16078 3 16077 16365 16079 3 16367 16079 16365 3 16078 16080 16366 3 16368 16366 16080 3 16079 16367 16081 3 16369 16081 16367 3 16080 16082 16368 3 16370 16368 16082 3 16081 16369 16083 3 16371 16083 16369 3 16082 16084 16370 3 16372 16370 16084 3 16083 16371 16085 3 16373 16085 16371 3 16084 16086 16372 3 16374 16372 16086 3 16085 16373 16087 3 16375 16087 16373 3 16086 16088 16374 3 16376 16374 16088 3 16087 16375 16089 3 16377 16089 16375 3 16088 16090 16376 3 16378 16376 16090 3 16089 16377 16091 3 16379 16091 16377 3 16090 16092 16378 3 16380 16378 16092 3 16091 16379 16093 3 16381 16093 16379 3 16092 16094 16380 3 16382 16380 16094 3 16093 16381 16095 3 16383 16095 16381 3 16094 16096 16382 3 16384 16382 16096 3 16095 16383 16097 3 16385 16097 16383 3 16096 16098 16384 3 16386 16384 16098 3 16097 16385 16099 3 16387 16099 16385 3 16098 16100 16386 3 16388 16386 16100 3 16099 16387 16101 3 16389 16101 16387 3 16100 16102 16388 3 16390 16388 16102 3 16101 16389 16103 3 16391 16103 16389 3 16102 16104 16390 3 16392 16390 16104 3 16103 16391 16105 3 16393 16105 16391 3 16104 16106 16392 3 16394 16392 16106 3 16105 16393 16107 3 16395 16107 16393 3 16106 16108 16394 3 16396 16394 16108 3 16107 16395 16109 3 16397 16109 16395 3 16108 16110 16396 3 16398 16396 16110 3 16109 16397 16399 3 16109 16399 16111 3 16110 16112 16398 3 16400 16398 16112 3 16111 16399 16401 3 16111 16401 16113 3 16112 16114 16400 3 16402 16400 16114 3 16113 16401 16403 3 16113 16403 16115 3 16114 16116 16402 3 16404 16402 16116 3 16115 16403 16405 3 16115 16405 16117 3 16116 16118 16406 3 16116 16406 16404 3 16117 16405 16407 3 16117 16407 16119 3 16118 16120 16408 3 16118 16408 16406 3 16119 16407 16409 3 16119 16409 16121 3 16120 16122 16410 3 16120 16410 16408 3 16121 16409 16411 3 16121 16411 16123 3 16122 16124 16412 3 16122 16412 16410 3 16123 16411 16413 3 16123 16413 16125 3 16124 16126 16414 3 16124 16414 16412 3 16125 16413 16415 3 16125 16415 16127 3 16126 16128 16416 3 16126 16416 16414 3 16127 16415 16417 3 16127 16417 16129 3 16128 16130 16418 3 16128 16418 16416 3 16129 16417 16419 3 16129 16419 16131 3 16130 16132 16420 3 16130 16420 16418 3 16131 16419 16421 3 16131 16421 16133 3 16132 16134 16422 3 16132 16422 16420 3 16133 16421 16423 3 16133 16423 16135 3 16134 16136 16424 3 16134 16424 16422 3 16135 16423 16425 3 16135 16425 16137 3 16136 16138 16426 3 16136 16426 16424 3 16137 16425 16427 3 16137 16427 16139 3 16138 16140 16428 3 16138 16428 16426 3 16139 16427 16429 3 16139 16429 16141 3 16140 16142 16430 3 16140 16430 16428 3 16141 16429 16431 3 16141 16431 16143 3 16142 16144 16432 3 16142 16432 16430 3 16143 16431 16433 3 16143 16433 16145 3 16144 16146 16434 3 16144 16434 16432 3 16145 16433 16435 3 16145 16435 16147 3 16146 16148 16436 3 16146 16436 16434 3 16147 16435 16437 3 16147 16437 16149 3 16148 16150 16438 3 16148 16438 16436 3 16149 16437 16439 3 16149 16439 16151 3 16150 16152 16440 3 16150 16440 16438 3 16151 16439 16441 3 16151 16441 16153 3 16152 16154 16442 3 16152 16442 16440 3 16153 16441 16443 3 16153 16443 16155 3 16154 16156 16444 3 16154 16444 16442 3 16155 16443 16445 3 16155 16445 16157 3 16156 16158 16446 3 16156 16446 16444 3 16157 16445 16447 3 16157 16447 16159 3 16158 16160 16448 3 16158 16448 16446 3 16159 16447 16451 3 16159 16451 16163 3 16160 16161 16449 3 16160 16449 16448 3 16161 16164 16452 3 16161 16452 16449 3 16162 16163 16451 3 16162 16451 16450 3 16162 16450 16455 3 16162 16455 16167 3 16164 16165 16453 3 16164 16453 16452 3 16165 16168 16456 3 16165 16456 16453 3 16166 16167 16455 3 16166 16455 16454 3 16166 16454 16524 3 16166 16524 16236 3 16168 16169 16457 3 16168 16457 16456 3 16169 16170 16458 3 16169 16458 16457 3 16170 16171 16459 3 16170 16459 16458 3 16171 16172 16460 3 16171 16460 16459 3 16172 16173 16461 3 16172 16461 16460 3 16173 16174 16462 3 16173 16462 16461 3 16174 16175 16463 3 16174 16463 16462 3 16175 16176 16464 3 16175 16464 16463 3 16176 16177 16465 3 16176 16465 16464 3 16177 16178 16466 3 16177 16466 16465 3 16178 16179 16467 3 16178 16467 16466 3 16179 16180 16468 3 16179 16468 16467 3 16180 16181 16469 3 16180 16469 16468 3 16181 16182 16470 3 16181 16470 16469 3 16182 16183 16471 3 16182 16471 16470 3 16183 16184 16472 3 16183 16472 16471 3 16184 16185 16473 3 16184 16473 16472 3 16185 16186 16474 3 16185 16474 16473 3 16186 16187 16475 3 16186 16475 16474 3 16187 16188 16476 3 16187 16476 16475 3 16188 16189 16477 3 16188 16477 16476 3 16189 16190 16478 3 16189 16478 16477 3 16190 16191 16479 3 16190 16479 16478 3 16191 16192 16480 3 16191 16480 16479 3 16192 16193 16481 3 16192 16481 16480 3 16193 16194 16482 3 16193 16482 16481 3 16194 16195 16483 3 16194 16483 16482 3 16195 16196 16483 3 16484 16483 16196 3 16196 16197 16484 3 16485 16484 16197 3 16197 16198 16485 3 16486 16485 16198 3 16198 16199 16486 3 16487 16486 16199 3 16199 16200 16487 3 16488 16487 16200 3 16200 16201 16488 3 16489 16488 16201 3 16201 16202 16489 3 16490 16489 16202 3 16202 16203 16490 3 16491 16490 16203 3 16203 16204 16491 3 16492 16491 16204 3 16204 16205 16492 3 16493 16492 16205 3 16205 16206 16493 3 16494 16493 16206 3 16206 16207 16494 3 16495 16494 16207 3 16207 16208 16495 3 16496 16495 16208 3 16208 16209 16496 3 16497 16496 16209 3 16209 16210 16497 3 16498 16497 16210 3 16210 16211 16498 3 16499 16498 16211 3 16211 16212 16499 3 16500 16499 16212 3 16212 16213 16500 3 16501 16500 16213 3 16213 16214 16501 3 16502 16501 16214 3 16214 16215 16502 3 16503 16502 16215 3 16215 16216 16503 3 16504 16503 16216 3 16216 16217 16504 3 16505 16504 16217 3 16217 16218 16505 3 16506 16505 16218 3 16218 16219 16506 3 16507 16506 16219 3 16219 16220 16507 3 16508 16507 16220 3 16220 16221 16508 3 16509 16508 16221 3 16221 16222 16509 3 16510 16509 16222 3 16222 16223 16510 3 16511 16510 16223 3 16223 16224 16511 3 16512 16511 16224 3 16224 16225 16512 3 16513 16512 16225 3 16225 16226 16513 3 16514 16513 16226 3 16226 16227 16514 3 16515 16514 16227 3 16227 16228 16515 3 16516 16515 16228 3 16228 16229 16516 3 16517 16516 16229 3 16229 16230 16517 3 16518 16517 16230 3 16230 16231 16518 3 16519 16518 16231 3 16231 16232 16519 3 16520 16519 16232 3 16232 16233 16520 3 16521 16520 16233 3 16233 16234 16521 3 16522 16521 16234 3 16234 16235 16522 3 16523 16522 16235 3 16235 16236 16523 3 16524 16523 16236 3 16237 16525 16238 3 16526 16238 16525 3 16237 16307 16595 3 16237 16595 16525 3 16238 16526 16239 3 16527 16239 16526 3 16239 16527 16240 3 16528 16240 16527 3 16240 16528 16241 3 16529 16241 16528 3 16241 16529 16242 3 16530 16242 16529 3 16242 16530 16243 3 16531 16243 16530 3 16243 16531 16244 3 16532 16244 16531 3 16244 16532 16245 3 16533 16245 16532 3 16245 16533 16246 3 16534 16246 16533 3 16246 16534 16247 3 16535 16247 16534 3 16247 16535 16248 3 16536 16248 16535 3 16248 16536 16249 3 16537 16249 16536 3 16249 16537 16250 3 16538 16250 16537 3 16250 16538 16251 3 16539 16251 16538 3 16251 16539 16252 3 16540 16252 16539 3 16252 16540 16253 3 16541 16253 16540 3 16253 16541 16254 3 16542 16254 16541 3 16254 16542 16255 3 16543 16255 16542 3 16255 16543 16256 3 16544 16256 16543 3 16256 16544 16257 3 16545 16257 16544 3 16257 16545 16258 3 16546 16258 16545 3 16258 16546 16259 3 16547 16259 16546 3 16259 16547 16260 3 16548 16260 16547 3 16260 16548 16261 3 16549 16261 16548 3 16261 16549 16262 3 16550 16262 16549 3 16262 16550 16263 3 16551 16263 16550 3 16263 16551 16264 3 16552 16264 16551 3 16264 16552 16265 3 16553 16265 16552 3 16265 16553 16266 3 16554 16266 16553 3 16266 16554 16555 3 16266 16555 16267 3 16267 16555 16556 3 16267 16556 16268 3 16268 16556 16557 3 16268 16557 16269 3 16269 16557 16558 3 16269 16558 16270 3 16270 16558 16559 3 16270 16559 16271 3 16271 16559 16560 3 16271 16560 16272 3 16272 16560 16561 3 16272 16561 16273 3 16273 16561 16562 3 16273 16562 16274 3 16274 16562 16563 3 16274 16563 16275 3 16275 16563 16564 3 16275 16564 16276 3 16276 16564 16565 3 16276 16565 16277 3 16277 16565 16566 3 16277 16566 16278 3 16278 16566 16567 3 16278 16567 16279 3 16279 16567 16568 3 16279 16568 16280 3 16280 16568 16569 3 16280 16569 16281 3 16281 16569 16570 3 16281 16570 16282 3 16282 16570 16571 3 16282 16571 16283 3 16283 16571 16572 3 16283 16572 16284 3 16284 16572 16573 3 16284 16573 16285 3 16285 16573 16574 3 16285 16574 16286 3 16286 16574 16575 3 16286 16575 16287 3 16287 16575 16576 3 16287 16576 16288 3 16288 16576 16577 3 16288 16577 16289 3 16289 16577 16578 3 16289 16578 16290 3 16290 16578 16579 3 16290 16579 16291 3 16291 16579 16580 3 16291 16580 16292 3 16292 16580 16581 3 16292 16581 16293 3 16293 16581 16582 3 16293 16582 16294 3 16294 16582 16583 3 16294 16583 16295 3 16295 16583 16584 3 16295 16584 16296 3 16296 16584 16585 3 16296 16585 16297 3 16297 16585 16586 3 16297 16586 16298 3 16298 16586 16587 3 16298 16587 16299 3 16299 16587 16588 3 16299 16588 16300 3 16300 16588 16589 3 16300 16589 16301 3 16301 16589 16590 3 16301 16590 16302 3 16302 16590 16591 3 16302 16591 16303 3 16303 16591 16592 3 16303 16592 16304 3 16304 16592 16593 3 16304 16593 16305 3 16305 16593 16596 3 16305 16596 16308 3 16306 16594 16595 3 16306 16595 16307 3 16306 16311 16599 3 16306 16599 16594 3 16308 16596 16597 3 16308 16597 16309 3 16309 16597 16600 3 16309 16600 16312 3 16310 16598 16599 3 16310 16599 16311 3 16310 16314 16602 3 16310 16602 16598 3 16312 16600 16601 3 16312 16601 16313 3 16313 16601 16603 3 16313 16603 16315 3 16314 16316 16604 3 16314 16604 16602 3 16315 16603 16605 3 16315 16605 16317 3 16316 16318 16606 3 16316 16606 16604 3 16317 16605 16607 3 16317 16607 16319 3 16318 16320 16608 3 16318 16608 16606 3 16319 16607 16609 3 16319 16609 16321 3 16320 16322 16610 3 16320 16610 16608 3 16321 16609 16611 3 16321 16611 16323 3 16322 16324 16612 3 16322 16612 16610 3 16323 16611 16613 3 16323 16613 16325 3 16324 16326 16614 3 16324 16614 16612 3 16325 16613 16615 3 16325 16615 16327 3 16326 16328 16616 3 16326 16616 16614 3 16327 16615 16617 3 16327 16617 16329 3 16328 16330 16618 3 16328 16618 16616 3 16329 16617 16619 3 16329 16619 16331 3 16330 16332 16620 3 16330 16620 16618 3 16331 16619 16621 3 16331 16621 16333 3 16332 16334 16622 3 16332 16622 16620 3 16333 16621 16623 3 16333 16623 16335 3 16334 16336 16624 3 16334 16624 16622 3 16335 16623 16625 3 16335 16625 16337 3 16336 16338 16626 3 16336 16626 16624 3 16337 16625 16627 3 16337 16627 16339 3 16338 16340 16628 3 16338 16628 16626 3 16339 16627 16629 3 16339 16629 16341 3 16340 16342 16630 3 16340 16630 16628 3 16341 16629 16631 3 16341 16631 16343 3 16342 16344 16632 3 16342 16632 16630 3 16343 16631 16633 3 16343 16633 16345 3 16344 16346 16634 3 16344 16634 16632 3 16345 16633 16347 3 16635 16347 16633 3 16346 16348 16636 3 16346 16636 16634 3 16347 16635 16349 3 16637 16349 16635 3 16348 16350 16638 3 16348 16638 16636 3 16349 16637 16351 3 16639 16351 16637 3 16350 16352 16640 3 16350 16640 16638 3 16351 16639 16353 3 16641 16353 16639 3 16352 16354 16640 3 16642 16640 16354 3 16353 16641 16355 3 16643 16355 16641 3 16354 16356 16642 3 16644 16642 16356 3 16355 16643 16357 3 16645 16357 16643 3 16356 16358 16644 3 16646 16644 16358 3 16357 16645 16359 3 16647 16359 16645 3 16358 16360 16646 3 16648 16646 16360 3 16359 16647 16361 3 16649 16361 16647 3 16360 16362 16648 3 16650 16648 16362 3 16361 16649 16363 3 16651 16363 16649 3 16362 16364 16650 3 16652 16650 16364 3 16363 16651 16365 3 16653 16365 16651 3 16364 16366 16652 3 16654 16652 16366 3 16365 16653 16367 3 16655 16367 16653 3 16366 16368 16654 3 16656 16654 16368 3 16367 16655 16369 3 16657 16369 16655 3 16368 16370 16656 3 16658 16656 16370 3 16369 16657 16371 3 16659 16371 16657 3 16370 16372 16658 3 16660 16658 16372 3 16371 16659 16373 3 16661 16373 16659 3 16372 16374 16660 3 16662 16660 16374 3 16373 16661 16375 3 16663 16375 16661 3 16374 16376 16662 3 16664 16662 16376 3 16375 16663 16377 3 16665 16377 16663 3 16376 16378 16664 3 16666 16664 16378 3 16377 16665 16379 3 16667 16379 16665 3 16378 16380 16666 3 16668 16666 16380 3 16379 16667 16381 3 16669 16381 16667 3 16380 16382 16668 3 16670 16668 16382 3 16381 16669 16383 3 16671 16383 16669 3 16382 16384 16670 3 16672 16670 16384 3 16383 16671 16385 3 16673 16385 16671 3 16384 16386 16672 3 16674 16672 16386 3 16385 16673 16387 3 16675 16387 16673 3 16386 16388 16674 3 16676 16674 16388 3 16387 16675 16389 3 16677 16389 16675 3 16388 16390 16676 3 16678 16676 16390 3 16389 16677 16391 3 16679 16391 16677 3 16390 16392 16678 3 16680 16678 16392 3 16391 16679 16393 3 16681 16393 16679 3 16392 16394 16680 3 16682 16680 16394 3 16393 16681 16395 3 16683 16395 16681 3 16394 16396 16682 3 16684 16682 16396 3 16395 16683 16397 3 16685 16397 16683 3 16396 16398 16684 3 16686 16684 16398 3 16397 16685 16399 3 16687 16399 16685 3 16398 16400 16686 3 16688 16686 16400 3 16399 16687 16401 3 16689 16401 16687 3 16400 16402 16688 3 16690 16688 16402 3 16401 16689 16403 3 16691 16403 16689 3 16402 16404 16690 3 16692 16690 16404 3 16403 16691 16405 3 16693 16405 16691 3 16404 16406 16692 3 16694 16692 16406 3 16405 16693 16407 3 16695 16407 16693 3 16406 16408 16694 3 16696 16694 16408 3 16407 16695 16409 3 16697 16409 16695 3 16408 16410 16696 3 16698 16696 16410 3 16409 16697 16411 3 16699 16411 16697 3 16410 16412 16698 3 16700 16698 16412 3 16411 16699 16413 3 16701 16413 16699 3 16412 16414 16700 3 16702 16700 16414 3 16413 16701 16415 3 16703 16415 16701 3 16414 16416 16702 3 16704 16702 16416 3 16415 16703 16417 3 16705 16417 16703 3 16416 16418 16704 3 16706 16704 16418 3 16417 16705 16419 3 16707 16419 16705 3 16418 16420 16706 3 16708 16706 16420 3 16419 16707 16421 3 16709 16421 16707 3 16420 16422 16708 3 16710 16708 16422 3 16421 16709 16423 3 16711 16423 16709 3 16422 16424 16710 3 16712 16710 16424 3 16423 16711 16425 3 16713 16425 16711 3 16424 16426 16712 3 16714 16712 16426 3 16425 16713 16715 3 16425 16715 16427 3 16426 16428 16714 3 16716 16714 16428 3 16427 16715 16717 3 16427 16717 16429 3 16428 16430 16716 3 16718 16716 16430 3 16429 16717 16719 3 16429 16719 16431 3 16430 16432 16718 3 16720 16718 16432 3 16431 16719 16721 3 16431 16721 16433 3 16432 16434 16722 3 16432 16722 16720 3 16433 16721 16723 3 16433 16723 16435 3 16434 16436 16724 3 16434 16724 16722 3 16435 16723 16725 3 16435 16725 16437 3 16436 16438 16726 3 16436 16726 16724 3 16437 16725 16727 3 16437 16727 16439 3 16438 16440 16728 3 16438 16728 16726 3 16439 16727 16729 3 16439 16729 16441 3 16440 16442 16730 3 16440 16730 16728 3 16441 16729 16731 3 16441 16731 16443 3 16442 16444 16732 3 16442 16732 16730 3 16443 16731 16733 3 16443 16733 16445 3 16444 16446 16734 3 16444 16734 16732 3 16445 16733 16735 3 16445 16735 16447 3 16446 16448 16736 3 16446 16736 16734 3 16447 16735 16739 3 16447 16739 16451 3 16448 16449 16737 3 16448 16737 16736 3 16449 16452 16740 3 16449 16740 16737 3 16450 16451 16739 3 16450 16739 16738 3 16450 16738 16743 3 16450 16743 16455 3 16452 16453 16741 3 16452 16741 16740 3 16453 16456 16744 3 16453 16744 16741 3 16454 16455 16743 3 16454 16743 16742 3 16454 16742 16812 3 16454 16812 16524 3 16456 16457 16745 3 16456 16745 16744 3 16457 16458 16746 3 16457 16746 16745 3 16458 16459 16747 3 16458 16747 16746 3 16459 16460 16748 3 16459 16748 16747 3 16460 16461 16749 3 16460 16749 16748 3 16461 16462 16750 3 16461 16750 16749 3 16462 16463 16751 3 16462 16751 16750 3 16463 16464 16752 3 16463 16752 16751 3 16464 16465 16753 3 16464 16753 16752 3 16465 16466 16754 3 16465 16754 16753 3 16466 16467 16755 3 16466 16755 16754 3 16467 16468 16756 3 16467 16756 16755 3 16468 16469 16757 3 16468 16757 16756 3 16469 16470 16758 3 16469 16758 16757 3 16470 16471 16759 3 16470 16759 16758 3 16471 16472 16760 3 16471 16760 16759 3 16472 16473 16761 3 16472 16761 16760 3 16473 16474 16762 3 16473 16762 16761 3 16474 16475 16763 3 16474 16763 16762 3 16475 16476 16764 3 16475 16764 16763 3 16476 16477 16765 3 16476 16765 16764 3 16477 16478 16766 3 16477 16766 16765 3 16478 16479 16767 3 16478 16767 16766 3 16479 16480 16768 3 16479 16768 16767 3 16480 16481 16769 3 16480 16769 16768 3 16481 16482 16770 3 16481 16770 16769 3 16482 16483 16771 3 16482 16771 16770 3 16483 16484 16772 3 16483 16772 16771 3 16484 16485 16773 3 16484 16773 16772 3 16485 16486 16774 3 16485 16774 16773 3 16486 16487 16775 3 16486 16775 16774 3 16487 16488 16776 3 16487 16776 16775 3 16488 16489 16777 3 16488 16777 16776 3 16489 16490 16778 3 16489 16778 16777 3 16490 16491 16779 3 16490 16779 16778 3 16491 16492 16780 3 16491 16780 16779 3 16492 16493 16781 3 16492 16781 16780 3 16493 16494 16782 3 16493 16782 16781 3 16494 16495 16783 3 16494 16783 16782 3 16495 16496 16784 3 16495 16784 16783 3 16496 16497 16785 3 16496 16785 16784 3 16497 16498 16786 3 16497 16786 16785 3 16498 16499 16787 3 16498 16787 16786 3 16499 16500 16788 3 16499 16788 16787 3 16500 16501 16789 3 16500 16789 16788 3 16501 16502 16790 3 16501 16790 16789 3 16502 16503 16791 3 16502 16791 16790 3 16503 16504 16792 3 16503 16792 16791 3 16504 16505 16793 3 16504 16793 16792 3 16505 16506 16794 3 16505 16794 16793 3 16506 16507 16795 3 16506 16795 16794 3 16507 16508 16796 3 16507 16796 16795 3 16508 16509 16797 3 16508 16797 16796 3 16509 16510 16798 3 16509 16798 16797 3 16510 16511 16798 3 16799 16798 16511 3 16511 16512 16799 3 16800 16799 16512 3 16512 16513 16800 3 16801 16800 16513 3 16513 16514 16801 3 16802 16801 16514 3 16514 16515 16802 3 16803 16802 16515 3 16515 16516 16803 3 16804 16803 16516 3 16516 16517 16804 3 16805 16804 16517 3 16517 16518 16805 3 16806 16805 16518 3 16518 16519 16806 3 16807 16806 16519 3 16519 16520 16807 3 16808 16807 16520 3 16520 16521 16808 3 16809 16808 16521 3 16521 16522 16809 3 16810 16809 16522 3 16522 16523 16810 3 16811 16810 16523 3 16523 16524 16811 3 16812 16811 16524 3 16525 16813 16526 3 16814 16526 16813 3 16525 16595 16813 3 16883 16813 16595 3 16526 16814 16527 3 16815 16527 16814 3 16527 16815 16528 3 16816 16528 16815 3 16528 16816 16529 3 16817 16529 16816 3 16529 16817 16530 3 16818 16530 16817 3 16530 16818 16531 3 16819 16531 16818 3 16531 16819 16532 3 16820 16532 16819 3 16532 16820 16533 3 16821 16533 16820 3 16533 16821 16534 3 16822 16534 16821 3 16534 16822 16535 3 16823 16535 16822 3 16535 16823 16536 3 16824 16536 16823 3 16536 16824 16537 3 16825 16537 16824 3 16537 16825 16538 3 16826 16538 16825 3 16538 16826 16539 3 16827 16539 16826 3 16539 16827 16540 3 16828 16540 16827 3 16540 16828 16541 3 16829 16541 16828 3 16541 16829 16542 3 16830 16542 16829 3 16542 16830 16543 3 16831 16543 16830 3 16543 16831 16544 3 16832 16544 16831 3 16544 16832 16545 3 16833 16545 16832 3 16545 16833 16546 3 16834 16546 16833 3 16546 16834 16547 3 16835 16547 16834 3 16547 16835 16548 3 16836 16548 16835 3 16548 16836 16549 3 16837 16549 16836 3 16549 16837 16550 3 16838 16550 16837 3 16550 16838 16551 3 16839 16551 16838 3 16551 16839 16552 3 16840 16552 16839 3 16552 16840 16553 3 16841 16553 16840 3 16553 16841 16554 3 16842 16554 16841 3 16554 16842 16555 3 16843 16555 16842 3 16555 16843 16556 3 16844 16556 16843 3 16556 16844 16557 3 16845 16557 16844 3 16557 16845 16558 3 16846 16558 16845 3 16558 16846 16559 3 16847 16559 16846 3 16559 16847 16560 3 16848 16560 16847 3 16560 16848 16561 3 16849 16561 16848 3 16561 16849 16562 3 16850 16562 16849 3 16562 16850 16563 3 16851 16563 16850 3 16563 16851 16564 3 16852 16564 16851 3 16564 16852 16565 3 16853 16565 16852 3 16565 16853 16566 3 16854 16566 16853 3 16566 16854 16567 3 16855 16567 16854 3 16567 16855 16568 3 16856 16568 16855 3 16568 16856 16569 3 16857 16569 16856 3 16569 16857 16570 3 16858 16570 16857 3 16570 16858 16571 3 16859 16571 16858 3 16571 16859 16572 3 16860 16572 16859 3 16572 16860 16573 3 16861 16573 16860 3 16573 16861 16574 3 16862 16574 16861 3 16574 16862 16575 3 16863 16575 16862 3 16575 16863 16576 3 16864 16576 16863 3 16576 16864 16577 3 16865 16577 16864 3 16577 16865 16578 3 16866 16578 16865 3 16578 16866 16579 3 16867 16579 16866 3 16579 16867 16580 3 16868 16580 16867 3 16580 16868 16581 3 16869 16581 16868 3 16581 16869 16582 3 16870 16582 16869 3 16582 16870 16583 3 16871 16583 16870 3 16583 16871 16872 3 16583 16872 16584 3 16584 16872 16873 3 16584 16873 16585 3 16585 16873 16874 3 16585 16874 16586 3 16586 16874 16875 3 16586 16875 16587 3 16587 16875 16876 3 16587 16876 16588 3 16588 16876 16877 3 16588 16877 16589 3 16589 16877 16878 3 16589 16878 16590 3 16590 16878 16879 3 16590 16879 16591 3 16591 16879 16880 3 16591 16880 16592 3 16592 16880 16881 3 16592 16881 16593 3 16593 16881 16884 3 16593 16884 16596 3 16594 16882 16883 3 16594 16883 16595 3 16594 16599 16887 3 16594 16887 16882 3 16596 16884 16885 3 16596 16885 16597 3 16597 16885 16888 3 16597 16888 16600 3 16598 16886 16887 3 16598 16887 16599 3 16598 16602 16890 3 16598 16890 16886 3 16600 16888 16889 3 16600 16889 16601 3 16601 16889 16891 3 16601 16891 16603 3 16602 16604 16892 3 16602 16892 16890 3 16603 16891 16893 3 16603 16893 16605 3 16604 16606 16894 3 16604 16894 16892 3 16605 16893 16895 3 16605 16895 16607 3 16606 16608 16896 3 16606 16896 16894 3 16607 16895 16897 3 16607 16897 16609 3 16608 16610 16898 3 16608 16898 16896 3 16609 16897 16899 3 16609 16899 16611 3 16610 16612 16900 3 16610 16900 16898 3 16611 16899 16901 3 16611 16901 16613 3 16612 16614 16902 3 16612 16902 16900 3 16613 16901 16903 3 16613 16903 16615 3 16614 16616 16904 3 16614 16904 16902 3 16615 16903 16905 3 16615 16905 16617 3 16616 16618 16906 3 16616 16906 16904 3 16617 16905 16907 3 16617 16907 16619 3 16618 16620 16908 3 16618 16908 16906 3 16619 16907 16909 3 16619 16909 16621 3 16620 16622 16910 3 16620 16910 16908 3 16621 16909 16911 3 16621 16911 16623 3 16622 16624 16912 3 16622 16912 16910 3 16623 16911 16913 3 16623 16913 16625 3 16624 16626 16914 3 16624 16914 16912 3 16625 16913 16915 3 16625 16915 16627 3 16626 16628 16916 3 16626 16916 16914 3 16627 16915 16917 3 16627 16917 16629 3 16628 16630 16918 3 16628 16918 16916 3 16629 16917 16919 3 16629 16919 16631 3 16630 16632 16920 3 16630 16920 16918 3 16631 16919 16921 3 16631 16921 16633 3 16632 16634 16922 3 16632 16922 16920 3 16633 16921 16923 3 16633 16923 16635 3 16634 16636 16924 3 16634 16924 16922 3 16635 16923 16925 3 16635 16925 16637 3 16636 16638 16926 3 16636 16926 16924 3 16637 16925 16927 3 16637 16927 16639 3 16638 16640 16928 3 16638 16928 16926 3 16639 16927 16929 3 16639 16929 16641 3 16640 16642 16930 3 16640 16930 16928 3 16641 16929 16931 3 16641 16931 16643 3 16642 16644 16932 3 16642 16932 16930 3 16643 16931 16933 3 16643 16933 16645 3 16644 16646 16934 3 16644 16934 16932 3 16645 16933 16935 3 16645 16935 16647 3 16646 16648 16936 3 16646 16936 16934 3 16647 16935 16937 3 16647 16937 16649 3 16648 16650 16938 3 16648 16938 16936 3 16649 16937 16939 3 16649 16939 16651 3 16650 16652 16940 3 16650 16940 16938 3 16651 16939 16941 3 16651 16941 16653 3 16652 16654 16942 3 16652 16942 16940 3 16653 16941 16943 3 16653 16943 16655 3 16654 16656 16944 3 16654 16944 16942 3 16655 16943 16945 3 16655 16945 16657 3 16656 16658 16946 3 16656 16946 16944 3 16657 16945 16947 3 16657 16947 16659 3 16658 16660 16948 3 16658 16948 16946 3 16659 16947 16949 3 16659 16949 16661 3 16660 16662 16950 3 16660 16950 16948 3 16661 16949 16951 3 16661 16951 16663 3 16662 16664 16952 3 16662 16952 16950 3 16663 16951 16665 3 16953 16665 16951 3 16664 16666 16954 3 16664 16954 16952 3 16665 16953 16667 3 16955 16667 16953 3 16666 16668 16956 3 16666 16956 16954 3 16667 16955 16669 3 16957 16669 16955 3 16668 16670 16956 3 16958 16956 16670 3 16669 16957 16671 3 16959 16671 16957 3 16670 16672 16958 3 16960 16958 16672 3 16671 16959 16673 3 16961 16673 16959 3 16672 16674 16960 3 16962 16960 16674 3 16673 16961 16675 3 16963 16675 16961 3 16674 16676 16962 3 16964 16962 16676 3 16675 16963 16677 3 16965 16677 16963 3 16676 16678 16964 3 16966 16964 16678 3 16677 16965 16679 3 16967 16679 16965 3 16678 16680 16966 3 16968 16966 16680 3 16679 16967 16681 3 16969 16681 16967 3 16680 16682 16968 3 16970 16968 16682 3 16681 16969 16683 3 16971 16683 16969 3 16682 16684 16970 3 16972 16970 16684 3 16683 16971 16685 3 16973 16685 16971 3 16684 16686 16972 3 16974 16972 16686 3 16685 16973 16687 3 16975 16687 16973 3 16686 16688 16974 3 16976 16974 16688 3 16687 16975 16689 3 16977 16689 16975 3 16688 16690 16976 3 16978 16976 16690 3 16689 16977 16691 3 16979 16691 16977 3 16690 16692 16978 3 16980 16978 16692 3 16691 16979 16693 3 16981 16693 16979 3 16692 16694 16980 3 16982 16980 16694 3 16693 16981 16695 3 16983 16695 16981 3 16694 16696 16982 3 16984 16982 16696 3 16695 16983 16697 3 16985 16697 16983 3 16696 16698 16984 3 16986 16984 16698 3 16697 16985 16699 3 16987 16699 16985 3 16698 16700 16986 3 16988 16986 16700 3 16699 16987 16701 3 16989 16701 16987 3 16700 16702 16988 3 16990 16988 16702 3 16701 16989 16703 3 16991 16703 16989 3 16702 16704 16990 3 16992 16990 16704 3 16703 16991 16705 3 16993 16705 16991 3 16704 16706 16992 3 16994 16992 16706 3 16705 16993 16707 3 16995 16707 16993 3 16706 16708 16994 3 16996 16994 16708 3 16707 16995 16709 3 16997 16709 16995 3 16708 16710 16996 3 16998 16996 16710 3 16709 16997 16711 3 16999 16711 16997 3 16710 16712 16998 3 17000 16998 16712 3 16711 16999 16713 3 17001 16713 16999 3 16712 16714 17000 3 17002 17000 16714 3 16713 17001 16715 3 17003 16715 17001 3 16714 16716 17002 3 17004 17002 16716 3 16715 17003 16717 3 17005 16717 17003 3 16716 16718 17004 3 17006 17004 16718 3 16717 17005 16719 3 17007 16719 17005 3 16718 16720 17006 3 17008 17006 16720 3 16719 17007 16721 3 17009 16721 17007 3 16720 16722 17008 3 17010 17008 16722 3 16721 17009 16723 3 17011 16723 17009 3 16722 16724 17010 3 17012 17010 16724 3 16723 17011 16725 3 17013 16725 17011 3 16724 16726 17012 3 17014 17012 16726 3 16725 17013 16727 3 17015 16727 17013 3 16726 16728 17014 3 17016 17014 16728 3 16727 17015 16729 3 17017 16729 17015 3 16728 16730 17016 3 17018 17016 16730 3 16729 17017 16731 3 17019 16731 17017 3 16730 16732 17018 3 17020 17018 16732 3 16731 17019 16733 3 17021 16733 17019 3 16732 16734 17020 3 17022 17020 16734 3 16733 17021 16735 3 17023 16735 17021 3 16734 16736 17022 3 17024 17022 16736 3 16735 17023 16739 3 17027 16739 17023 3 16736 16737 17024 3 17025 17024 16737 3 16737 16740 17025 3 17028 17025 16740 3 16738 16739 17026 3 17027 17026 16739 3 16738 17026 16743 3 17031 16743 17026 3 16740 16741 17028 3 17029 17028 16741 3 16741 16744 17029 3 17032 17029 16744 3 16742 16743 17030 3 17031 17030 16743 3 16742 17030 16812 3 17100 16812 17030 3 16744 16745 17032 3 17033 17032 16745 3 16745 16746 17033 3 17034 17033 16746 3 16746 16747 17034 3 17035 17034 16747 3 16747 16748 17035 3 17036 17035 16748 3 16748 16749 17037 3 16748 17037 17036 3 16749 16750 17038 3 16749 17038 17037 3 16750 16751 17039 3 16750 17039 17038 3 16751 16752 17040 3 16751 17040 17039 3 16752 16753 17041 3 16752 17041 17040 3 16753 16754 17042 3 16753 17042 17041 3 16754 16755 17043 3 16754 17043 17042 3 16755 16756 17044 3 16755 17044 17043 3 16756 16757 17045 3 16756 17045 17044 3 16757 16758 17046 3 16757 17046 17045 3 16758 16759 17047 3 16758 17047 17046 3 16759 16760 17048 3 16759 17048 17047 3 16760 16761 17049 3 16760 17049 17048 3 16761 16762 17050 3 16761 17050 17049 3 16762 16763 17051 3 16762 17051 17050 3 16763 16764 17052 3 16763 17052 17051 3 16764 16765 17053 3 16764 17053 17052 3 16765 16766 17054 3 16765 17054 17053 3 16766 16767 17055 3 16766 17055 17054 3 16767 16768 17056 3 16767 17056 17055 3 16768 16769 17057 3 16768 17057 17056 3 16769 16770 17058 3 16769 17058 17057 3 16770 16771 17059 3 16770 17059 17058 3 16771 16772 17060 3 16771 17060 17059 3 16772 16773 17061 3 16772 17061 17060 3 16773 16774 17062 3 16773 17062 17061 3 16774 16775 17063 3 16774 17063 17062 3 16775 16776 17064 3 16775 17064 17063 3 16776 16777 17065 3 16776 17065 17064 3 16777 16778 17066 3 16777 17066 17065 3 16778 16779 17067 3 16778 17067 17066 3 16779 16780 17068 3 16779 17068 17067 3 16780 16781 17069 3 16780 17069 17068 3 16781 16782 17070 3 16781 17070 17069 3 16782 16783 17071 3 16782 17071 17070 3 16783 16784 17072 3 16783 17072 17071 3 16784 16785 17073 3 16784 17073 17072 3 16785 16786 17074 3 16785 17074 17073 3 16786 16787 17075 3 16786 17075 17074 3 16787 16788 17076 3 16787 17076 17075 3 16788 16789 17077 3 16788 17077 17076 3 16789 16790 17078 3 16789 17078 17077 3 16790 16791 17079 3 16790 17079 17078 3 16791 16792 17080 3 16791 17080 17079 3 16792 16793 17081 3 16792 17081 17080 3 16793 16794 17082 3 16793 17082 17081 3 16794 16795 17083 3 16794 17083 17082 3 16795 16796 17084 3 16795 17084 17083 3 16796 16797 17085 3 16796 17085 17084 3 16797 16798 17086 3 16797 17086 17085 3 16798 16799 17087 3 16798 17087 17086 3 16799 16800 17088 3 16799 17088 17087 3 16800 16801 17089 3 16800 17089 17088 3 16801 16802 17090 3 16801 17090 17089 3 16802 16803 17091 3 16802 17091 17090 3 16803 16804 17092 3 16803 17092 17091 3 16804 16805 17093 3 16804 17093 17092 3 16805 16806 17094 3 16805 17094 17093 3 16806 16807 17095 3 16806 17095 17094 3 16807 16808 17096 3 16807 17096 17095 3 16808 16809 17097 3 16808 17097 17096 3 16809 16810 17098 3 16809 17098 17097 3 16810 16811 17099 3 16810 17099 17098 3 16811 16812 17100 3 16811 17100 17099 3 16813 17101 17102 3 16813 17102 16814 3 16813 16883 17101 3 17171 17101 16883 3 16814 17102 17103 3 16814 17103 16815 3 16815 17103 17104 3 16815 17104 16816 3 16816 17104 17105 3 16816 17105 16817 3 16817 17105 17106 3 16817 17106 16818 3 16818 17106 17107 3 16818 17107 16819 3 16819 17107 17108 3 16819 17108 16820 3 16820 17108 17109 3 16820 17109 16821 3 16821 17109 17110 3 16821 17110 16822 3 16822 17110 17111 3 16822 17111 16823 3 16823 17111 16824 3 17112 16824 17111 3 16824 17112 16825 3 17113 16825 17112 3 16825 17113 16826 3 17114 16826 17113 3 16826 17114 16827 3 17115 16827 17114 3 16827 17115 16828 3 17116 16828 17115 3 16828 17116 16829 3 17117 16829 17116 3 16829 17117 16830 3 17118 16830 17117 3 16830 17118 16831 3 17119 16831 17118 3 16831 17119 16832 3 17120 16832 17119 3 16832 17120 16833 3 17121 16833 17120 3 16833 17121 16834 3 17122 16834 17121 3 16834 17122 16835 3 17123 16835 17122 3 16835 17123 16836 3 17124 16836 17123 3 16836 17124 16837 3 17125 16837 17124 3 16837 17125 16838 3 17126 16838 17125 3 16838 17126 16839 3 17127 16839 17126 3 16839 17127 16840 3 17128 16840 17127 3 16840 17128 16841 3 17129 16841 17128 3 16841 17129 16842 3 17130 16842 17129 3 16842 17130 16843 3 17131 16843 17130 3 16843 17131 16844 3 17132 16844 17131 3 16844 17132 16845 3 17133 16845 17132 3 16845 17133 16846 3 17134 16846 17133 3 16846 17134 16847 3 17135 16847 17134 3 16847 17135 16848 3 17136 16848 17135 3 16848 17136 16849 3 17137 16849 17136 3 16849 17137 16850 3 17138 16850 17137 3 16850 17138 16851 3 17139 16851 17138 3 16851 17139 16852 3 17140 16852 17139 3 16852 17140 16853 3 17141 16853 17140 3 16853 17141 16854 3 17142 16854 17141 3 16854 17142 16855 3 17143 16855 17142 3 16855 17143 16856 3 17144 16856 17143 3 16856 17144 16857 3 17145 16857 17144 3 16857 17145 16858 3 17146 16858 17145 3 16858 17146 16859 3 17147 16859 17146 3 16859 17147 16860 3 17148 16860 17147 3 16860 17148 16861 3 17149 16861 17148 3 16861 17149 16862 3 17150 16862 17149 3 16862 17150 16863 3 17151 16863 17150 3 16863 17151 16864 3 17152 16864 17151 3 16864 17152 16865 3 17153 16865 17152 3 16865 17153 16866 3 17154 16866 17153 3 16866 17154 16867 3 17155 16867 17154 3 16867 17155 16868 3 17156 16868 17155 3 16868 17156 16869 3 17157 16869 17156 3 16869 17157 16870 3 17158 16870 17157 3 16870 17158 16871 3 17159 16871 17158 3 16871 17159 16872 3 17160 16872 17159 3 16872 17160 16873 3 17161 16873 17160 3 16873 17161 16874 3 17162 16874 17161 3 16874 17162 16875 3 17163 16875 17162 3 16875 17163 16876 3 17164 16876 17163 3 16876 17164 16877 3 17165 16877 17164 3 16877 17165 16878 3 17166 16878 17165 3 16878 17166 16879 3 17167 16879 17166 3 16879 17167 16880 3 17168 16880 17167 3 16880 17168 16881 3 17169 16881 17168 3 16881 17169 16884 3 17172 16884 17169 3 16882 17170 16883 3 17171 16883 17170 3 16882 16887 17170 3 17175 17170 16887 3 16884 17172 16885 3 17173 16885 17172 3 16885 17173 16888 3 17176 16888 17173 3 16886 17174 16887 3 17175 16887 17174 3 16886 16890 17174 3 17178 17174 16890 3 16888 17176 16889 3 17177 16889 17176 3 16889 17177 16891 3 17179 16891 17177 3 16890 16892 17178 3 17180 17178 16892 3 16891 17179 16893 3 17181 16893 17179 3 16892 16894 17180 3 17182 17180 16894 3 16893 17181 16895 3 17183 16895 17181 3 16894 16896 17182 3 17184 17182 16896 3 16895 17183 16897 3 17185 16897 17183 3 16896 16898 17184 3 17186 17184 16898 3 16897 17185 16899 3 17187 16899 17185 3 16898 16900 17186 3 17188 17186 16900 3 16899 17187 16901 3 17189 16901 17187 3 16900 16902 17188 3 17190 17188 16902 3 16901 17189 16903 3 17191 16903 17189 3 16902 16904 17190 3 17192 17190 16904 3 16903 17191 17193 3 16903 17193 16905 3 16904 16906 17192 3 17194 17192 16906 3 16905 17193 17195 3 16905 17195 16907 3 16906 16908 17194 3 17196 17194 16908 3 16907 17195 17197 3 16907 17197 16909 3 16908 16910 17198 3 16908 17198 17196 3 16909 17197 17199 3 16909 17199 16911 3 16910 16912 17200 3 16910 17200 17198 3 16911 17199 17201 3 16911 17201 16913 3 16912 16914 17202 3 16912 17202 17200 3 16913 17201 17203 3 16913 17203 16915 3 16914 16916 17204 3 16914 17204 17202 3 16915 17203 17205 3 16915 17205 16917 3 16916 16918 17206 3 16916 17206 17204 3 16917 17205 17207 3 16917 17207 16919 3 16918 16920 17208 3 16918 17208 17206 3 16919 17207 17209 3 16919 17209 16921 3 16920 16922 17210 3 16920 17210 17208 3 16921 17209 17211 3 16921 17211 16923 3 16922 16924 17212 3 16922 17212 17210 3 16923 17211 17213 3 16923 17213 16925 3 16924 16926 17214 3 16924 17214 17212 3 16925 17213 17215 3 16925 17215 16927 3 16926 16928 17216 3 16926 17216 17214 3 16927 17215 17217 3 16927 17217 16929 3 16928 16930 17218 3 16928 17218 17216 3 16929 17217 17219 3 16929 17219 16931 3 16930 16932 17220 3 16930 17220 17218 3 16931 17219 17221 3 16931 17221 16933 3 16932 16934 17222 3 16932 17222 17220 3 16933 17221 17223 3 16933 17223 16935 3 16934 16936 17224 3 16934 17224 17222 3 16935 17223 17225 3 16935 17225 16937 3 16936 16938 17226 3 16936 17226 17224 3 16937 17225 17227 3 16937 17227 16939 3 16938 16940 17228 3 16938 17228 17226 3 16939 17227 17229 3 16939 17229 16941 3 16940 16942 17230 3 16940 17230 17228 3 16941 17229 17231 3 16941 17231 16943 3 16942 16944 17232 3 16942 17232 17230 3 16943 17231 17233 3 16943 17233 16945 3 16944 16946 17234 3 16944 17234 17232 3 16945 17233 17235 3 16945 17235 16947 3 16946 16948 17236 3 16946 17236 17234 3 16947 17235 17237 3 16947 17237 16949 3 16948 16950 17238 3 16948 17238 17236 3 16949 17237 17239 3 16949 17239 16951 3 16950 16952 17240 3 16950 17240 17238 3 16951 17239 17241 3 16951 17241 16953 3 16952 16954 17242 3 16952 17242 17240 3 16953 17241 17243 3 16953 17243 16955 3 16954 16956 17244 3 16954 17244 17242 3 16955 17243 17245 3 16955 17245 16957 3 16956 16958 17246 3 16956 17246 17244 3 16957 17245 17247 3 16957 17247 16959 3 16958 16960 17248 3 16958 17248 17246 3 16959 17247 17249 3 16959 17249 16961 3 16960 16962 17250 3 16960 17250 17248 3 16961 17249 17251 3 16961 17251 16963 3 16962 16964 17252 3 16962 17252 17250 3 16963 17251 17253 3 16963 17253 16965 3 16964 16966 17254 3 16964 17254 17252 3 16965 17253 17255 3 16965 17255 16967 3 16966 16968 17256 3 16966 17256 17254 3 16967 17255 17257 3 16967 17257 16969 3 16968 16970 17258 3 16968 17258 17256 3 16969 17257 17259 3 16969 17259 16971 3 16970 16972 17260 3 16970 17260 17258 3 16971 17259 17261 3 16971 17261 16973 3 16972 16974 17262 3 16972 17262 17260 3 16973 17261 17263 3 16973 17263 16975 3 16974 16976 17264 3 16974 17264 17262 3 16975 17263 17265 3 16975 17265 16977 3 16976 16978 17266 3 16976 17266 17264 3 16977 17265 17267 3 16977 17267 16979 3 16978 16980 17268 3 16978 17268 17266 3 16979 17267 17269 3 16979 17269 16981 3 16980 16982 17270 3 16980 17270 17268 3 16981 17269 17271 3 16981 17271 16983 3 16982 16984 17272 3 16982 17272 17270 3 16983 17271 17273 3 16983 17273 16985 3 16984 16986 17274 3 16984 17274 17272 3 16985 17273 16987 3 17275 16987 17273 3 16986 16988 17276 3 16986 17276 17274 3 16987 17275 16989 3 17277 16989 17275 3 16988 16990 17276 3 17278 17276 16990 3 16989 17277 16991 3 17279 16991 17277 3 16990 16992 17278 3 17280 17278 16992 3 16991 17279 16993 3 17281 16993 17279 3 16992 16994 17280 3 17282 17280 16994 3 16993 17281 16995 3 17283 16995 17281 3 16994 16996 17282 3 17284 17282 16996 3 16995 17283 16997 3 17285 16997 17283 3 16996 16998 17284 3 17286 17284 16998 3 16997 17285 16999 3 17287 16999 17285 3 16998 17000 17286 3 17288 17286 17000 3 16999 17287 17001 3 17289 17001 17287 3 17000 17002 17288 3 17290 17288 17002 3 17001 17289 17003 3 17291 17003 17289 3 17002 17004 17290 3 17292 17290 17004 3 17003 17291 17005 3 17293 17005 17291 3 17004 17006 17292 3 17294 17292 17006 3 17005 17293 17007 3 17295 17007 17293 3 17006 17008 17294 3 17296 17294 17008 3 17007 17295 17009 3 17297 17009 17295 3 17008 17010 17296 3 17298 17296 17010 3 17009 17297 17011 3 17299 17011 17297 3 17010 17012 17298 3 17300 17298 17012 3 17011 17299 17013 3 17301 17013 17299 3 17012 17014 17300 3 17302 17300 17014 3 17013 17301 17015 3 17303 17015 17301 3 17014 17016 17302 3 17304 17302 17016 3 17015 17303 17017 3 17305 17017 17303 3 17016 17018 17304 3 17306 17304 17018 3 17017 17305 17019 3 17307 17019 17305 3 17018 17020 17306 3 17308 17306 17020 3 17019 17307 17021 3 17309 17021 17307 3 17020 17022 17308 3 17310 17308 17022 3 17021 17309 17023 3 17311 17023 17309 3 17022 17024 17310 3 17312 17310 17024 3 17023 17311 17027 3 17315 17027 17311 3 17024 17025 17312 3 17313 17312 17025 3 17025 17028 17313 3 17316 17313 17028 3 17026 17027 17314 3 17315 17314 17027 3 17026 17314 17031 3 17319 17031 17314 3 17028 17029 17316 3 17317 17316 17029 3 17029 17032 17317 3 17320 17317 17032 3 17030 17031 17318 3 17319 17318 17031 3 17030 17318 17100 3 17388 17100 17318 3 17032 17033 17320 3 17321 17320 17033 3 17033 17034 17321 3 17322 17321 17034 3 17034 17035 17322 3 17323 17322 17035 3 17035 17036 17323 3 17324 17323 17036 3 17036 17037 17324 3 17325 17324 17037 3 17037 17038 17325 3 17326 17325 17038 3 17038 17039 17326 3 17327 17326 17039 3 17039 17040 17327 3 17328 17327 17040 3 17040 17041 17328 3 17329 17328 17041 3 17041 17042 17329 3 17330 17329 17042 3 17042 17043 17330 3 17331 17330 17043 3 17043 17044 17331 3 17332 17331 17044 3 17044 17045 17332 3 17333 17332 17045 3 17045 17046 17333 3 17334 17333 17046 3 17046 17047 17334 3 17335 17334 17047 3 17047 17048 17335 3 17336 17335 17048 3 17048 17049 17336 3 17337 17336 17049 3 17049 17050 17337 3 17338 17337 17050 3 17050 17051 17338 3 17339 17338 17051 3 17051 17052 17339 3 17340 17339 17052 3 17052 17053 17340 3 17341 17340 17053 3 17053 17054 17341 3 17342 17341 17054 3 17054 17055 17342 3 17343 17342 17055 3 17055 17056 17343 3 17344 17343 17056 3 17056 17057 17344 3 17345 17344 17057 3 17057 17058 17345 3 17346 17345 17058 3 17058 17059 17346 3 17347 17346 17059 3 17059 17060 17347 3 17348 17347 17060 3 17060 17061 17348 3 17349 17348 17061 3 17061 17062 17349 3 17350 17349 17062 3 17062 17063 17350 3 17351 17350 17063 3 17063 17064 17351 3 17352 17351 17064 3 17064 17065 17352 3 17353 17352 17065 3 17065 17066 17353 3 17354 17353 17066 3 17066 17067 17354 3 17355 17354 17067 3 17067 17068 17355 3 17356 17355 17068 3 17068 17069 17357 3 17068 17357 17356 3 17069 17070 17358 3 17069 17358 17357 3 17070 17071 17359 3 17070 17359 17358 3 17071 17072 17360 3 17071 17360 17359 3 17072 17073 17361 3 17072 17361 17360 3 17073 17074 17362 3 17073 17362 17361 3 17074 17075 17363 3 17074 17363 17362 3 17075 17076 17364 3 17075 17364 17363 3 17076 17077 17365 3 17076 17365 17364 3 17077 17078 17366 3 17077 17366 17365 3 17078 17079 17367 3 17078 17367 17366 3 17079 17080 17368 3 17079 17368 17367 3 17080 17081 17369 3 17080 17369 17368 3 17081 17082 17370 3 17081 17370 17369 3 17082 17083 17371 3 17082 17371 17370 3 17083 17084 17372 3 17083 17372 17371 3 17084 17085 17373 3 17084 17373 17372 3 17085 17086 17374 3 17085 17374 17373 3 17086 17087 17375 3 17086 17375 17374 3 17087 17088 17376 3 17087 17376 17375 3 17088 17089 17377 3 17088 17377 17376 3 17089 17090 17378 3 17089 17378 17377 3 17090 17091 17379 3 17090 17379 17378 3 17091 17092 17380 3 17091 17380 17379 3 17092 17093 17381 3 17092 17381 17380 3 17093 17094 17382 3 17093 17382 17381 3 17094 17095 17383 3 17094 17383 17382 3 17095 17096 17384 3 17095 17384 17383 3 17096 17097 17385 3 17096 17385 17384 3 17097 17098 17386 3 17097 17386 17385 3 17098 17099 17387 3 17098 17387 17386 3 17099 17100 17388 3 17099 17388 17387 3 17101 17389 17390 3 17101 17390 17102 3 17101 17171 17459 3 17101 17459 17389 3 17102 17390 17391 3 17102 17391 17103 3 17103 17391 17392 3 17103 17392 17104 3 17104 17392 17393 3 17104 17393 17105 3 17105 17393 17394 3 17105 17394 17106 3 17106 17394 17395 3 17106 17395 17107 3 17107 17395 17396 3 17107 17396 17108 3 17108 17396 17397 3 17108 17397 17109 3 17109 17397 17398 3 17109 17398 17110 3 17110 17398 17399 3 17110 17399 17111 3 17111 17399 17400 3 17111 17400 17112 3 17112 17400 17401 3 17112 17401 17113 3 17113 17401 17402 3 17113 17402 17114 3 17114 17402 17403 3 17114 17403 17115 3 17115 17403 17404 3 17115 17404 17116 3 17116 17404 17405 3 17116 17405 17117 3 17117 17405 17406 3 17117 17406 17118 3 17118 17406 17407 3 17118 17407 17119 3 17119 17407 17408 3 17119 17408 17120 3 17120 17408 17409 3 17120 17409 17121 3 17121 17409 17410 3 17121 17410 17122 3 17122 17410 17411 3 17122 17411 17123 3 17123 17411 17412 3 17123 17412 17124 3 17124 17412 17413 3 17124 17413 17125 3 17125 17413 17414 3 17125 17414 17126 3 17126 17414 17415 3 17126 17415 17127 3 17127 17415 17416 3 17127 17416 17128 3 17128 17416 17417 3 17128 17417 17129 3 17129 17417 17418 3 17129 17418 17130 3 17130 17418 17419 3 17130 17419 17131 3 17131 17419 17420 3 17131 17420 17132 3 17132 17420 17421 3 17132 17421 17133 3 17133 17421 17422 3 17133 17422 17134 3 17134 17422 17423 3 17134 17423 17135 3 17135 17423 17424 3 17135 17424 17136 3 17136 17424 17425 3 17136 17425 17137 3 17137 17425 17426 3 17137 17426 17138 3 17138 17426 17427 3 17138 17427 17139 3 17139 17427 17428 3 17139 17428 17140 3 17140 17428 17429 3 17140 17429 17141 3 17141 17429 17430 3 17141 17430 17142 3 17142 17430 17431 3 17142 17431 17143 3 17143 17431 17432 3 17143 17432 17144 3 17144 17432 17433 3 17144 17433 17145 3 17145 17433 17434 3 17145 17434 17146 3 17146 17434 17147 3 17435 17147 17434 3 17147 17435 17148 3 17436 17148 17435 3 17148 17436 17149 3 17437 17149 17436 3 17149 17437 17150 3 17438 17150 17437 3 17150 17438 17151 3 17439 17151 17438 3 17151 17439 17152 3 17440 17152 17439 3 17152 17440 17153 3 17441 17153 17440 3 17153 17441 17154 3 17442 17154 17441 3 17154 17442 17155 3 17443 17155 17442 3 17155 17443 17156 3 17444 17156 17443 3 17156 17444 17157 3 17445 17157 17444 3 17157 17445 17158 3 17446 17158 17445 3 17158 17446 17159 3 17447 17159 17446 3 17159 17447 17160 3 17448 17160 17447 3 17160 17448 17161 3 17449 17161 17448 3 17161 17449 17162 3 17450 17162 17449 3 17162 17450 17163 3 17451 17163 17450 3 17163 17451 17164 3 17452 17164 17451 3 17164 17452 17165 3 17453 17165 17452 3 17165 17453 17166 3 17454 17166 17453 3 17166 17454 17167 3 17455 17167 17454 3 17167 17455 17168 3 17456 17168 17455 3 17168 17456 17169 3 17457 17169 17456 3 17169 17457 17172 3 17460 17172 17457 3 17170 17458 17171 3 17459 17171 17458 3 17170 17175 17458 3 17463 17458 17175 3 17172 17460 17173 3 17461 17173 17460 3 17173 17461 17176 3 17464 17176 17461 3 17174 17462 17175 3 17463 17175 17462 3 17174 17178 17462 3 17466 17462 17178 3 17176 17464 17177 3 17465 17177 17464 3 17177 17465 17179 3 17467 17179 17465 3 17178 17180 17466 3 17468 17466 17180 3 17179 17467 17181 3 17469 17181 17467 3 17180 17182 17468 3 17470 17468 17182 3 17181 17469 17183 3 17471 17183 17469 3 17182 17184 17470 3 17472 17470 17184 3 17183 17471 17185 3 17473 17185 17471 3 17184 17186 17472 3 17474 17472 17186 3 17185 17473 17187 3 17475 17187 17473 3 17186 17188 17474 3 17476 17474 17188 3 17187 17475 17189 3 17477 17189 17475 3 17188 17190 17476 3 17478 17476 17190 3 17189 17477 17191 3 17479 17191 17477 3 17190 17192 17478 3 17480 17478 17192 3 17191 17479 17193 3 17481 17193 17479 3 17192 17194 17480 3 17482 17480 17194 3 17193 17481 17195 3 17483 17195 17481 3 17194 17196 17482 3 17484 17482 17196 3 17195 17483 17197 3 17485 17197 17483 3 17196 17198 17484 3 17486 17484 17198 3 17197 17485 17199 3 17487 17199 17485 3 17198 17200 17486 3 17488 17486 17200 3 17199 17487 17201 3 17489 17201 17487 3 17200 17202 17488 3 17490 17488 17202 3 17201 17489 17203 3 17491 17203 17489 3 17202 17204 17490 3 17492 17490 17204 3 17203 17491 17205 3 17493 17205 17491 3 17204 17206 17492 3 17494 17492 17206 3 17205 17493 17207 3 17495 17207 17493 3 17206 17208 17494 3 17496 17494 17208 3 17207 17495 17209 3 17497 17209 17495 3 17208 17210 17496 3 17498 17496 17210 3 17209 17497 17211 3 17499 17211 17497 3 17210 17212 17498 3 17500 17498 17212 3 17211 17499 17213 3 17501 17213 17499 3 17212 17214 17500 3 17502 17500 17214 3 17213 17501 17215 3 17503 17215 17501 3 17214 17216 17502 3 17504 17502 17216 3 17215 17503 17217 3 17505 17217 17503 3 17216 17218 17504 3 17506 17504 17218 3 17217 17505 17219 3 17507 17219 17505 3 17218 17220 17506 3 17508 17506 17220 3 17219 17507 17221 3 17509 17221 17507 3 17220 17222 17508 3 17510 17508 17222 3 17221 17509 17223 3 17511 17223 17509 3 17222 17224 17510 3 17512 17510 17224 3 17223 17511 17225 3 17513 17225 17511 3 17224 17226 17512 3 17514 17512 17226 3 17225 17513 17227 3 17515 17227 17513 3 17226 17228 17514 3 17516 17514 17228 3 17227 17515 17517 3 17227 17517 17229 3 17228 17230 17516 3 17518 17516 17230 3 17229 17517 17519 3 17229 17519 17231 3 17230 17232 17520 3 17230 17520 17518 3 17231 17519 17521 3 17231 17521 17233 3 17232 17234 17522 3 17232 17522 17520 3 17233 17521 17523 3 17233 17523 17235 3 17234 17236 17524 3 17234 17524 17522 3 17235 17523 17525 3 17235 17525 17237 3 17236 17238 17526 3 17236 17526 17524 3 17237 17525 17527 3 17237 17527 17239 3 17238 17240 17528 3 17238 17528 17526 3 17239 17527 17529 3 17239 17529 17241 3 17240 17242 17530 3 17240 17530 17528 3 17241 17529 17531 3 17241 17531 17243 3 17242 17244 17532 3 17242 17532 17530 3 17243 17531 17533 3 17243 17533 17245 3 17244 17246 17534 3 17244 17534 17532 3 17245 17533 17535 3 17245 17535 17247 3 17246 17248 17536 3 17246 17536 17534 3 17247 17535 17537 3 17247 17537 17249 3 17248 17250 17538 3 17248 17538 17536 3 17249 17537 17539 3 17249 17539 17251 3 17250 17252 17540 3 17250 17540 17538 3 17251 17539 17541 3 17251 17541 17253 3 17252 17254 17542 3 17252 17542 17540 3 17253 17541 17543 3 17253 17543 17255 3 17254 17256 17544 3 17254 17544 17542 3 17255 17543 17545 3 17255 17545 17257 3 17256 17258 17546 3 17256 17546 17544 3 17257 17545 17547 3 17257 17547 17259 3 17258 17260 17548 3 17258 17548 17546 3 17259 17547 17549 3 17259 17549 17261 3 17260 17262 17550 3 17260 17550 17548 3 17261 17549 17551 3 17261 17551 17263 3 17262 17264 17552 3 17262 17552 17550 3 17263 17551 17553 3 17263 17553 17265 3 17264 17266 17554 3 17264 17554 17552 3 17265 17553 17555 3 17265 17555 17267 3 17266 17268 17556 3 17266 17556 17554 3 17267 17555 17557 3 17267 17557 17269 3 17268 17270 17558 3 17268 17558 17556 3 17269 17557 17559 3 17269 17559 17271 3 17270 17272 17560 3 17270 17560 17558 3 17271 17559 17561 3 17271 17561 17273 3 17272 17274 17562 3 17272 17562 17560 3 17273 17561 17563 3 17273 17563 17275 3 17274 17276 17564 3 17274 17564 17562 3 17275 17563 17565 3 17275 17565 17277 3 17276 17278 17566 3 17276 17566 17564 3 17277 17565 17567 3 17277 17567 17279 3 17278 17280 17568 3 17278 17568 17566 3 17279 17567 17569 3 17279 17569 17281 3 17280 17282 17570 3 17280 17570 17568 3 17281 17569 17571 3 17281 17571 17283 3 17282 17284 17572 3 17282 17572 17570 3 17283 17571 17573 3 17283 17573 17285 3 17284 17286 17574 3 17284 17574 17572 3 17285 17573 17575 3 17285 17575 17287 3 17286 17288 17576 3 17286 17576 17574 3 17287 17575 17577 3 17287 17577 17289 3 17288 17290 17578 3 17288 17578 17576 3 17289 17577 17579 3 17289 17579 17291 3 17290 17292 17580 3 17290 17580 17578 3 17291 17579 17581 3 17291 17581 17293 3 17292 17294 17582 3 17292 17582 17580 3 17293 17581 17583 3 17293 17583 17295 3 17294 17296 17584 3 17294 17584 17582 3 17295 17583 17585 3 17295 17585 17297 3 17296 17298 17586 3 17296 17586 17584 3 17297 17585 17587 3 17297 17587 17299 3 17298 17300 17588 3 17298 17588 17586 3 17299 17587 17589 3 17299 17589 17301 3 17300 17302 17590 3 17300 17590 17588 3 17301 17589 17591 3 17301 17591 17303 3 17302 17304 17592 3 17302 17592 17590 3 17303 17591 17593 3 17303 17593 17305 3 17304 17306 17594 3 17304 17594 17592 3 17305 17593 17595 3 17305 17595 17307 3 17306 17308 17596 3 17306 17596 17594 3 17307 17595 17597 3 17307 17597 17309 3 17308 17310 17598 3 17308 17598 17596 3 17309 17597 17311 3 17599 17311 17597 3 17310 17312 17598 3 17600 17598 17312 3 17311 17599 17315 3 17603 17315 17599 3 17312 17313 17600 3 17601 17600 17313 3 17313 17316 17601 3 17604 17601 17316 3 17314 17315 17602 3 17603 17602 17315 3 17314 17602 17319 3 17607 17319 17602 3 17316 17317 17604 3 17605 17604 17317 3 17317 17320 17605 3 17608 17605 17320 3 17318 17319 17606 3 17607 17606 17319 3 17318 17606 17388 3 17676 17388 17606 3 17320 17321 17608 3 17609 17608 17321 3 17321 17322 17609 3 17610 17609 17322 3 17322 17323 17610 3 17611 17610 17323 3 17323 17324 17611 3 17612 17611 17324 3 17324 17325 17612 3 17613 17612 17325 3 17325 17326 17613 3 17614 17613 17326 3 17326 17327 17614 3 17615 17614 17327 3 17327 17328 17615 3 17616 17615 17328 3 17328 17329 17616 3 17617 17616 17329 3 17329 17330 17617 3 17618 17617 17330 3 17330 17331 17618 3 17619 17618 17331 3 17331 17332 17619 3 17620 17619 17332 3 17332 17333 17620 3 17621 17620 17333 3 17333 17334 17621 3 17622 17621 17334 3 17334 17335 17622 3 17623 17622 17335 3 17335 17336 17623 3 17624 17623 17336 3 17336 17337 17624 3 17625 17624 17337 3 17337 17338 17625 3 17626 17625 17338 3 17338 17339 17626 3 17627 17626 17339 3 17339 17340 17627 3 17628 17627 17340 3 17340 17341 17628 3 17629 17628 17341 3 17341 17342 17629 3 17630 17629 17342 3 17342 17343 17630 3 17631 17630 17343 3 17343 17344 17631 3 17632 17631 17344 3 17344 17345 17632 3 17633 17632 17345 3 17345 17346 17633 3 17634 17633 17346 3 17346 17347 17634 3 17635 17634 17347 3 17347 17348 17635 3 17636 17635 17348 3 17348 17349 17636 3 17637 17636 17349 3 17349 17350 17637 3 17638 17637 17350 3 17350 17351 17638 3 17639 17638 17351 3 17351 17352 17639 3 17640 17639 17352 3 17352 17353 17640 3 17641 17640 17353 3 17353 17354 17641 3 17642 17641 17354 3 17354 17355 17642 3 17643 17642 17355 3 17355 17356 17643 3 17644 17643 17356 3 17356 17357 17644 3 17645 17644 17357 3 17357 17358 17645 3 17646 17645 17358 3 17358 17359 17646 3 17647 17646 17359 3 17359 17360 17647 3 17648 17647 17360 3 17360 17361 17648 3 17649 17648 17361 3 17361 17362 17649 3 17650 17649 17362 3 17362 17363 17650 3 17651 17650 17363 3 17363 17364 17651 3 17652 17651 17364 3 17364 17365 17652 3 17653 17652 17365 3 17365 17366 17653 3 17654 17653 17366 3 17366 17367 17654 3 17655 17654 17367 3 17367 17368 17655 3 17656 17655 17368 3 17368 17369 17656 3 17657 17656 17369 3 17369 17370 17657 3 17658 17657 17370 3 17370 17371 17658 3 17659 17658 17371 3 17371 17372 17659 3 17660 17659 17372 3 17372 17373 17660 3 17661 17660 17373 3 17373 17374 17661 3 17662 17661 17374 3 17374 17375 17662 3 17663 17662 17375 3 17375 17376 17663 3 17664 17663 17376 3 17376 17377 17664 3 17665 17664 17377 3 17377 17378 17665 3 17666 17665 17378 3 17378 17379 17666 3 17667 17666 17379 3 17379 17380 17667 3 17668 17667 17380 3 17380 17381 17668 3 17669 17668 17381 3 17381 17382 17669 3 17670 17669 17382 3 17382 17383 17670 3 17671 17670 17383 3 17383 17384 17671 3 17672 17671 17384 3 17384 17385 17672 3 17673 17672 17385 3 17385 17386 17673 3 17674 17673 17386 3 17386 17387 17674 3 17675 17674 17387 3 17387 17388 17675 3 17676 17675 17388 3 17389 17677 17678 3 17389 17678 17390 3 17389 17459 17747 3 17389 17747 17677 3 17390 17678 17679 3 17390 17679 17391 3 17391 17679 17680 3 17391 17680 17392 3 17392 17680 17681 3 17392 17681 17393 3 17393 17681 17682 3 17393 17682 17394 3 17394 17682 17683 3 17394 17683 17395 3 17395 17683 17684 3 17395 17684 17396 3 17396 17684 17685 3 17396 17685 17397 3 17397 17685 17686 3 17397 17686 17398 3 17398 17686 17687 3 17398 17687 17399 3 17399 17687 17688 3 17399 17688 17400 3 17400 17688 17689 3 17400 17689 17401 3 17401 17689 17690 3 17401 17690 17402 3 17402 17690 17691 3 17402 17691 17403 3 17403 17691 17692 3 17403 17692 17404 3 17404 17692 17693 3 17404 17693 17405 3 17405 17693 17694 3 17405 17694 17406 3 17406 17694 17695 3 17406 17695 17407 3 17407 17695 17696 3 17407 17696 17408 3 17408 17696 17697 3 17408 17697 17409 3 17409 17697 17698 3 17409 17698 17410 3 17410 17698 17699 3 17410 17699 17411 3 17411 17699 17700 3 17411 17700 17412 3 17412 17700 17701 3 17412 17701 17413 3 17413 17701 17702 3 17413 17702 17414 3 17414 17702 17703 3 17414 17703 17415 3 17415 17703 17704 3 17415 17704 17416 3 17416 17704 17705 3 17416 17705 17417 3 17417 17705 17706 3 17417 17706 17418 3 17418 17706 17707 3 17418 17707 17419 3 17419 17707 17708 3 17419 17708 17420 3 17420 17708 17709 3 17420 17709 17421 3 17421 17709 17710 3 17421 17710 17422 3 17422 17710 17711 3 17422 17711 17423 3 17423 17711 17712 3 17423 17712 17424 3 17424 17712 17713 3 17424 17713 17425 3 17425 17713 17714 3 17425 17714 17426 3 17426 17714 17715 3 17426 17715 17427 3 17427 17715 17716 3 17427 17716 17428 3 17428 17716 17717 3 17428 17717 17429 3 17429 17717 17718 3 17429 17718 17430 3 17430 17718 17719 3 17430 17719 17431 3 17431 17719 17720 3 17431 17720 17432 3 17432 17720 17721 3 17432 17721 17433 3 17433 17721 17722 3 17433 17722 17434 3 17434 17722 17723 3 17434 17723 17435 3 17435 17723 17724 3 17435 17724 17436 3 17436 17724 17725 3 17436 17725 17437 3 17437 17725 17726 3 17437 17726 17438 3 17438 17726 17727 3 17438 17727 17439 3 17439 17727 17728 3 17439 17728 17440 3 17440 17728 17729 3 17440 17729 17441 3 17441 17729 17730 3 17441 17730 17442 3 17442 17730 17731 3 17442 17731 17443 3 17443 17731 17732 3 17443 17732 17444 3 17444 17732 17733 3 17444 17733 17445 3 17445 17733 17734 3 17445 17734 17446 3 17446 17734 17735 3 17446 17735 17447 3 17447 17735 17736 3 17447 17736 17448 3 17448 17736 17737 3 17448 17737 17449 3 17449 17737 17738 3 17449 17738 17450 3 17450 17738 17739 3 17450 17739 17451 3 17451 17739 17740 3 17451 17740 17452 3 17452 17740 17741 3 17452 17741 17453 3 17453 17741 17742 3 17453 17742 17454 3 17454 17742 17743 3 17454 17743 17455 3 17455 17743 17744 3 17455 17744 17456 3 17456 17744 17745 3 17456 17745 17457 3 17457 17745 17748 3 17457 17748 17460 3 17458 17746 17747 3 17458 17747 17459 3 17458 17463 17751 3 17458 17751 17746 3 17460 17748 17749 3 17460 17749 17461 3 17461 17749 17752 3 17461 17752 17464 3 17462 17750 17751 3 17462 17751 17463 3 17462 17466 17754 3 17462 17754 17750 3 17464 17752 17753 3 17464 17753 17465 3 17465 17753 17755 3 17465 17755 17467 3 17466 17468 17756 3 17466 17756 17754 3 17467 17755 17757 3 17467 17757 17469 3 17468 17470 17758 3 17468 17758 17756 3 17469 17757 17759 3 17469 17759 17471 3 17470 17472 17760 3 17470 17760 17758 3 17471 17759 17473 3 17761 17473 17759 3 17472 17474 17760 3 17762 17760 17474 3 17473 17761 17475 3 17763 17475 17761 3 17474 17476 17762 3 17764 17762 17476 3 17475 17763 17477 3 17765 17477 17763 3 17476 17478 17764 3 17766 17764 17478 3 17477 17765 17479 3 17767 17479 17765 3 17478 17480 17766 3 17768 17766 17480 3 17479 17767 17481 3 17769 17481 17767 3 17480 17482 17768 3 17770 17768 17482 3 17481 17769 17483 3 17771 17483 17769 3 17482 17484 17770 3 17772 17770 17484 3 17483 17771 17485 3 17773 17485 17771 3 17484 17486 17772 3 17774 17772 17486 3 17485 17773 17487 3 17775 17487 17773 3 17486 17488 17774 3 17776 17774 17488 3 17487 17775 17489 3 17777 17489 17775 3 17488 17490 17776 3 17778 17776 17490 3 17489 17777 17491 3 17779 17491 17777 3 17490 17492 17778 3 17780 17778 17492 3 17491 17779 17493 3 17781 17493 17779 3 17492 17494 17780 3 17782 17780 17494 3 17493 17781 17495 3 17783 17495 17781 3 17494 17496 17782 3 17784 17782 17496 3 17495 17783 17497 3 17785 17497 17783 3 17496 17498 17784 3 17786 17784 17498 3 17497 17785 17499 3 17787 17499 17785 3 17498 17500 17786 3 17788 17786 17500 3 17499 17787 17501 3 17789 17501 17787 3 17500 17502 17788 3 17790 17788 17502 3 17501 17789 17503 3 17791 17503 17789 3 17502 17504 17790 3 17792 17790 17504 3 17503 17791 17505 3 17793 17505 17791 3 17504 17506 17792 3 17794 17792 17506 3 17505 17793 17507 3 17795 17507 17793 3 17506 17508 17794 3 17796 17794 17508 3 17507 17795 17509 3 17797 17509 17795 3 17508 17510 17796 3 17798 17796 17510 3 17509 17797 17511 3 17799 17511 17797 3 17510 17512 17798 3 17800 17798 17512 3 17511 17799 17513 3 17801 17513 17799 3 17512 17514 17800 3 17802 17800 17514 3 17513 17801 17515 3 17803 17515 17801 3 17514 17516 17802 3 17804 17802 17516 3 17515 17803 17517 3 17805 17517 17803 3 17516 17518 17804 3 17806 17804 17518 3 17517 17805 17519 3 17807 17519 17805 3 17518 17520 17806 3 17808 17806 17520 3 17519 17807 17521 3 17809 17521 17807 3 17520 17522 17808 3 17810 17808 17522 3 17521 17809 17523 3 17811 17523 17809 3 17522 17524 17810 3 17812 17810 17524 3 17523 17811 17525 3 17813 17525 17811 3 17524 17526 17812 3 17814 17812 17526 3 17525 17813 17527 3 17815 17527 17813 3 17526 17528 17814 3 17816 17814 17528 3 17527 17815 17529 3 17817 17529 17815 3 17528 17530 17816 3 17818 17816 17530 3 17529 17817 17531 3 17819 17531 17817 3 17530 17532 17818 3 17820 17818 17532 3 17531 17819 17533 3 17821 17533 17819 3 17532 17534 17820 3 17822 17820 17534 3 17533 17821 17535 3 17823 17535 17821 3 17534 17536 17822 3 17824 17822 17536 3 17535 17823 17537 3 17825 17537 17823 3 17536 17538 17824 3 17826 17824 17538 3 17537 17825 17539 3 17827 17539 17825 3 17538 17540 17826 3 17828 17826 17540 3 17539 17827 17541 3 17829 17541 17827 3 17540 17542 17828 3 17830 17828 17542 3 17541 17829 17543 3 17831 17543 17829 3 17542 17544 17830 3 17832 17830 17544 3 17543 17831 17545 3 17833 17545 17831 3 17544 17546 17832 3 17834 17832 17546 3 17545 17833 17547 3 17835 17547 17833 3 17546 17548 17834 3 17836 17834 17548 3 17547 17835 17549 3 17837 17549 17835 3 17548 17550 17836 3 17838 17836 17550 3 17549 17837 17551 3 17839 17551 17837 3 17550 17552 17838 3 17840 17838 17552 3 17551 17839 17553 3 17841 17553 17839 3 17552 17554 17840 3 17842 17840 17554 3 17553 17841 17843 3 17553 17843 17555 3 17554 17556 17844 3 17554 17844 17842 3 17555 17843 17845 3 17555 17845 17557 3 17556 17558 17846 3 17556 17846 17844 3 17557 17845 17847 3 17557 17847 17559 3 17558 17560 17848 3 17558 17848 17846 3 17559 17847 17849 3 17559 17849 17561 3 17560 17562 17850 3 17560 17850 17848 3 17561 17849 17851 3 17561 17851 17563 3 17562 17564 17852 3 17562 17852 17850 3 17563 17851 17853 3 17563 17853 17565 3 17564 17566 17854 3 17564 17854 17852 3 17565 17853 17855 3 17565 17855 17567 3 17566 17568 17856 3 17566 17856 17854 3 17567 17855 17857 3 17567 17857 17569 3 17568 17570 17858 3 17568 17858 17856 3 17569 17857 17859 3 17569 17859 17571 3 17570 17572 17860 3 17570 17860 17858 3 17571 17859 17861 3 17571 17861 17573 3 17572 17574 17862 3 17572 17862 17860 3 17573 17861 17863 3 17573 17863 17575 3 17574 17576 17864 3 17574 17864 17862 3 17575 17863 17865 3 17575 17865 17577 3 17576 17578 17866 3 17576 17866 17864 3 17577 17865 17867 3 17577 17867 17579 3 17578 17580 17868 3 17578 17868 17866 3 17579 17867 17869 3 17579 17869 17581 3 17580 17582 17870 3 17580 17870 17868 3 17581 17869 17871 3 17581 17871 17583 3 17582 17584 17872 3 17582 17872 17870 3 17583 17871 17873 3 17583 17873 17585 3 17584 17586 17874 3 17584 17874 17872 3 17585 17873 17875 3 17585 17875 17587 3 17586 17588 17876 3 17586 17876 17874 3 17587 17875 17877 3 17587 17877 17589 3 17588 17590 17878 3 17588 17878 17876 3 17589 17877 17879 3 17589 17879 17591 3 17590 17592 17880 3 17590 17880 17878 3 17591 17879 17881 3 17591 17881 17593 3 17592 17594 17882 3 17592 17882 17880 3 17593 17881 17883 3 17593 17883 17595 3 17594 17596 17884 3 17594 17884 17882 3 17595 17883 17885 3 17595 17885 17597 3 17596 17598 17886 3 17596 17886 17884 3 17597 17885 17887 3 17597 17887 17599 3 17598 17600 17888 3 17598 17888 17886 3 17599 17887 17891 3 17599 17891 17603 3 17600 17601 17889 3 17600 17889 17888 3 17601 17604 17892 3 17601 17892 17889 3 17602 17603 17891 3 17602 17891 17890 3 17602 17890 17895 3 17602 17895 17607 3 17604 17605 17893 3 17604 17893 17892 3 17605 17608 17896 3 17605 17896 17893 3 17606 17607 17895 3 17606 17895 17894 3 17606 17894 17964 3 17606 17964 17676 3 17608 17609 17897 3 17608 17897 17896 3 17609 17610 17898 3 17609 17898 17897 3 17610 17611 17899 3 17610 17899 17898 3 17611 17612 17900 3 17611 17900 17899 3 17612 17613 17901 3 17612 17901 17900 3 17613 17614 17902 3 17613 17902 17901 3 17614 17615 17903 3 17614 17903 17902 3 17615 17616 17904 3 17615 17904 17903 3 17616 17617 17905 3 17616 17905 17904 3 17617 17618 17906 3 17617 17906 17905 3 17618 17619 17907 3 17618 17907 17906 3 17619 17620 17908 3 17619 17908 17907 3 17620 17621 17909 3 17620 17909 17908 3 17621 17622 17910 3 17621 17910 17909 3 17622 17623 17911 3 17622 17911 17910 3 17623 17624 17912 3 17623 17912 17911 3 17624 17625 17913 3 17624 17913 17912 3 17625 17626 17914 3 17625 17914 17913 3 17626 17627 17915 3 17626 17915 17914 3 17627 17628 17916 3 17627 17916 17915 3 17628 17629 17917 3 17628 17917 17916 3 17629 17630 17918 3 17629 17918 17917 3 17630 17631 17919 3 17630 17919 17918 3 17631 17632 17920 3 17631 17920 17919 3 17632 17633 17921 3 17632 17921 17920 3 17633 17634 17922 3 17633 17922 17921 3 17634 17635 17923 3 17634 17923 17922 3 17635 17636 17924 3 17635 17924 17923 3 17636 17637 17924 3 17925 17924 17637 3 17637 17638 17925 3 17926 17925 17638 3 17638 17639 17926 3 17927 17926 17639 3 17639 17640 17927 3 17928 17927 17640 3 17640 17641 17928 3 17929 17928 17641 3 17641 17642 17929 3 17930 17929 17642 3 17642 17643 17930 3 17931 17930 17643 3 17643 17644 17931 3 17932 17931 17644 3 17644 17645 17932 3 17933 17932 17645 3 17645 17646 17933 3 17934 17933 17646 3 17646 17647 17934 3 17935 17934 17647 3 17647 17648 17935 3 17936 17935 17648 3 17648 17649 17936 3 17937 17936 17649 3 17649 17650 17937 3 17938 17937 17650 3 17650 17651 17938 3 17939 17938 17651 3 17651 17652 17939 3 17940 17939 17652 3 17652 17653 17940 3 17941 17940 17653 3 17653 17654 17941 3 17942 17941 17654 3 17654 17655 17942 3 17943 17942 17655 3 17655 17656 17943 3 17944 17943 17656 3 17656 17657 17944 3 17945 17944 17657 3 17657 17658 17945 3 17946 17945 17658 3 17658 17659 17946 3 17947 17946 17659 3 17659 17660 17947 3 17948 17947 17660 3 17660 17661 17948 3 17949 17948 17661 3 17661 17662 17949 3 17950 17949 17662 3 17662 17663 17950 3 17951 17950 17663 3 17663 17664 17951 3 17952 17951 17664 3 17664 17665 17952 3 17953 17952 17665 3 17665 17666 17953 3 17954 17953 17666 3 17666 17667 17954 3 17955 17954 17667 3 17667 17668 17955 3 17956 17955 17668 3 17668 17669 17956 3 17957 17956 17669 3 17669 17670 17957 3 17958 17957 17670 3 17670 17671 17958 3 17959 17958 17671 3 17671 17672 17959 3 17960 17959 17672 3 17672 17673 17960 3 17961 17960 17673 3 17673 17674 17961 3 17962 17961 17674 3 17674 17675 17962 3 17963 17962 17675 3 17675 17676 17963 3 17964 17963 17676 3 17677 17965 17678 3 17966 17678 17965 3 17677 17747 17965 3 18035 17965 17747 3 17678 17966 17679 3 17967 17679 17966 3 17679 17967 17680 3 17968 17680 17967 3 17680 17968 17681 3 17969 17681 17968 3 17681 17969 17682 3 17970 17682 17969 3 17682 17970 17683 3 17971 17683 17970 3 17683 17971 17684 3 17972 17684 17971 3 17684 17972 17685 3 17973 17685 17972 3 17685 17973 17686 3 17974 17686 17973 3 17686 17974 17687 3 17975 17687 17974 3 17687 17975 17688 3 17976 17688 17975 3 17688 17976 17689 3 17977 17689 17976 3 17689 17977 17690 3 17978 17690 17977 3 17690 17978 17691 3 17979 17691 17978 3 17691 17979 17692 3 17980 17692 17979 3 17692 17980 17693 3 17981 17693 17980 3 17693 17981 17694 3 17982 17694 17981 3 17694 17982 17695 3 17983 17695 17982 3 17695 17983 17696 3 17984 17696 17983 3 17696 17984 17697 3 17985 17697 17984 3 17697 17985 17698 3 17986 17698 17985 3 17698 17986 17699 3 17987 17699 17986 3 17699 17987 17700 3 17988 17700 17987 3 17700 17988 17701 3 17989 17701 17988 3 17701 17989 17702 3 17990 17702 17989 3 17702 17990 17703 3 17991 17703 17990 3 17703 17991 17704 3 17992 17704 17991 3 17704 17992 17705 3 17993 17705 17992 3 17705 17993 17706 3 17994 17706 17993 3 17706 17994 17707 3 17995 17707 17994 3 17707 17995 17708 3 17996 17708 17995 3 17708 17996 17709 3 17997 17709 17996 3 17709 17997 17710 3 17998 17710 17997 3 17710 17998 17711 3 17999 17711 17998 3 17711 17999 17712 3 18000 17712 17999 3 17712 18000 17713 3 18001 17713 18000 3 17713 18001 17714 3 18002 17714 18001 3 17714 18002 17715 3 18003 17715 18002 3 17715 18003 17716 3 18004 17716 18003 3 17716 18004 17717 3 18005 17717 18004 3 17717 18005 18006 3 17717 18006 17718 3 17718 18006 18007 3 17718 18007 17719 3 17719 18007 18008 3 17719 18008 17720 3 17720 18008 18009 3 17720 18009 17721 3 17721 18009 18010 3 17721 18010 17722 3 17722 18010 18011 3 17722 18011 17723 3 17723 18011 18012 3 17723 18012 17724 3 17724 18012 18013 3 17724 18013 17725 3 17725 18013 18014 3 17725 18014 17726 3 17726 18014 18015 3 17726 18015 17727 3 17727 18015 18016 3 17727 18016 17728 3 17728 18016 18017 3 17728 18017 17729 3 17729 18017 18018 3 17729 18018 17730 3 17730 18018 18019 3 17730 18019 17731 3 17731 18019 18020 3 17731 18020 17732 3 17732 18020 18021 3 17732 18021 17733 3 17733 18021 18022 3 17733 18022 17734 3 17734 18022 18023 3 17734 18023 17735 3 17735 18023 18024 3 17735 18024 17736 3 17736 18024 18025 3 17736 18025 17737 3 17737 18025 18026 3 17737 18026 17738 3 17738 18026 18027 3 17738 18027 17739 3 17739 18027 18028 3 17739 18028 17740 3 17740 18028 18029 3 17740 18029 17741 3 17741 18029 18030 3 17741 18030 17742 3 17742 18030 18031 3 17742 18031 17743 3 17743 18031 18032 3 17743 18032 17744 3 17744 18032 18033 3 17744 18033 17745 3 17745 18033 18036 3 17745 18036 17748 3 17746 18034 18035 3 17746 18035 17747 3 17746 17751 18039 3 17746 18039 18034 3 17748 18036 18037 3 17748 18037 17749 3 17749 18037 18040 3 17749 18040 17752 3 17750 18038 18039 3 17750 18039 17751 3 17750 17754 18042 3 17750 18042 18038 3 17752 18040 18041 3 17752 18041 17753 3 17753 18041 18043 3 17753 18043 17755 3 17754 17756 18044 3 17754 18044 18042 3 17755 18043 18045 3 17755 18045 17757 3 17756 17758 18046 3 17756 18046 18044 3 17757 18045 18047 3 17757 18047 17759 3 17758 17760 18048 3 17758 18048 18046 3 17759 18047 18049 3 17759 18049 17761 3 17760 17762 18050 3 17760 18050 18048 3 17761 18049 18051 3 17761 18051 17763 3 17762 17764 18052 3 17762 18052 18050 3 17763 18051 18053 3 17763 18053 17765 3 17764 17766 18054 3 17764 18054 18052 3 17765 18053 18055 3 17765 18055 17767 3 17766 17768 18056 3 17766 18056 18054 3 17767 18055 18057 3 17767 18057 17769 3 17768 17770 18058 3 17768 18058 18056 3 17769 18057 18059 3 17769 18059 17771 3 17770 17772 18060 3 17770 18060 18058 3 17771 18059 18061 3 17771 18061 17773 3 17772 17774 18062 3 17772 18062 18060 3 17773 18061 18063 3 17773 18063 17775 3 17774 17776 18064 3 17774 18064 18062 3 17775 18063 18065 3 17775 18065 17777 3 17776 17778 18066 3 17776 18066 18064 3 17777 18065 18067 3 17777 18067 17779 3 17778 17780 18068 3 17778 18068 18066 3 17779 18067 18069 3 17779 18069 17781 3 17780 17782 18070 3 17780 18070 18068 3 17781 18069 18071 3 17781 18071 17783 3 17782 17784 18072 3 17782 18072 18070 3 17783 18071 18073 3 17783 18073 17785 3 17784 17786 18074 3 17784 18074 18072 3 17785 18073 18075 3 17785 18075 17787 3 17786 17788 18076 3 17786 18076 18074 3 17787 18075 18077 3 17787 18077 17789 3 17788 17790 18078 3 17788 18078 18076 3 17789 18077 18079 3 17789 18079 17791 3 17790 17792 18080 3 17790 18080 18078 3 17791 18079 18081 3 17791 18081 17793 3 17792 17794 18082 3 17792 18082 18080 3 17793 18081 18083 3 17793 18083 17795 3 17794 17796 18084 3 17794 18084 18082 3 17795 18083 18085 3 17795 18085 17797 3 17796 17798 18086 3 17796 18086 18084 3 17797 18085 18087 3 17797 18087 17799 3 17798 17800 18088 3 17798 18088 18086 3 17799 18087 17801 3 18089 17801 18087 3 17800 17802 18088 3 18090 18088 17802 3 17801 18089 17803 3 18091 17803 18089 3 17802 17804 18090 3 18092 18090 17804 3 17803 18091 17805 3 18093 17805 18091 3 17804 17806 18092 3 18094 18092 17806 3 17805 18093 17807 3 18095 17807 18093 3 17806 17808 18094 3 18096 18094 17808 3 17807 18095 17809 3 18097 17809 18095 3 17808 17810 18096 3 18098 18096 17810 3 17809 18097 17811 3 18099 17811 18097 3 17810 17812 18098 3 18100 18098 17812 3 17811 18099 17813 3 18101 17813 18099 3 17812 17814 18100 3 18102 18100 17814 3 17813 18101 17815 3 18103 17815 18101 3 17814 17816 18102 3 18104 18102 17816 3 17815 18103 17817 3 18105 17817 18103 3 17816 17818 18104 3 18106 18104 17818 3 17817 18105 17819 3 18107 17819 18105 3 17818 17820 18106 3 18108 18106 17820 3 17819 18107 17821 3 18109 17821 18107 3 17820 17822 18108 3 18110 18108 17822 3 17821 18109 17823 3 18111 17823 18109 3 17822 17824 18110 3 18112 18110 17824 3 17823 18111 17825 3 18113 17825 18111 3 17824 17826 18112 3 18114 18112 17826 3 17825 18113 17827 3 18115 17827 18113 3 17826 17828 18114 3 18116 18114 17828 3 17827 18115 17829 3 18117 17829 18115 3 17828 17830 18116 3 18118 18116 17830 3 17829 18117 17831 3 18119 17831 18117 3 17830 17832 18118 3 18120 18118 17832 3 17831 18119 17833 3 18121 17833 18119 3 17832 17834 18120 3 18122 18120 17834 3 17833 18121 17835 3 18123 17835 18121 3 17834 17836 18122 3 18124 18122 17836 3 17835 18123 17837 3 18125 17837 18123 3 17836 17838 18124 3 18126 18124 17838 3 17837 18125 17839 3 18127 17839 18125 3 17838 17840 18126 3 18128 18126 17840 3 17839 18127 17841 3 18129 17841 18127 3 17840 17842 18128 3 18130 18128 17842 3 17841 18129 17843 3 18131 17843 18129 3 17842 17844 18130 3 18132 18130 17844 3 17843 18131 17845 3 18133 17845 18131 3 17844 17846 18132 3 18134 18132 17846 3 17845 18133 17847 3 18135 17847 18133 3 17846 17848 18134 3 18136 18134 17848 3 17847 18135 17849 3 18137 17849 18135 3 17848 17850 18136 3 18138 18136 17850 3 17849 18137 17851 3 18139 17851 18137 3 17850 17852 18138 3 18140 18138 17852 3 17851 18139 17853 3 18141 17853 18139 3 17852 17854 18140 3 18142 18140 17854 3 17853 18141 17855 3 18143 17855 18141 3 17854 17856 18142 3 18144 18142 17856 3 17855 18143 17857 3 18145 17857 18143 3 17856 17858 18144 3 18146 18144 17858 3 17857 18145 17859 3 18147 17859 18145 3 17858 17860 18146 3 18148 18146 17860 3 17859 18147 17861 3 18149 17861 18147 3 17860 17862 18148 3 18150 18148 17862 3 17861 18149 17863 3 18151 17863 18149 3 17862 17864 18150 3 18152 18150 17864 3 17863 18151 17865 3 18153 17865 18151 3 17864 17866 18152 3 18154 18152 17866 3 17865 18153 17867 3 18155 17867 18153 3 17866 17868 18154 3 18156 18154 17868 3 17867 18155 17869 3 18157 17869 18155 3 17868 17870 18156 3 18158 18156 17870 3 17869 18157 17871 3 18159 17871 18157 3 17870 17872 18158 3 18160 18158 17872 3 17871 18159 17873 3 18161 17873 18159 3 17872 17874 18160 3 18162 18160 17874 3 17873 18161 17875 3 18163 17875 18161 3 17874 17876 18162 3 18164 18162 17876 3 17875 18163 17877 3 18165 17877 18163 3 17876 17878 18164 3 18166 18164 17878 3 17877 18165 17879 3 18167 17879 18165 3 17878 17880 18166 3 18168 18166 17880 3 17879 18167 17881 3 18169 17881 18167 3 17880 17882 18168 3 18170 18168 17882 3 17881 18169 17883 3 18171 17883 18169 3 17882 17884 18172 3 17882 18172 18170 3 17883 18171 18173 3 17883 18173 17885 3 17884 17886 18174 3 17884 18174 18172 3 17885 18173 18175 3 17885 18175 17887 3 17886 17888 18176 3 17886 18176 18174 3 17887 18175 18179 3 17887 18179 17891 3 17888 17889 18177 3 17888 18177 18176 3 17889 17892 18180 3 17889 18180 18177 3 17890 17891 18179 3 17890 18179 18178 3 17890 18178 18183 3 17890 18183 17895 3 17892 17893 18181 3 17892 18181 18180 3 17893 17896 18184 3 17893 18184 18181 3 17894 17895 18183 3 17894 18183 18182 3 17894 18182 18252 3 17894 18252 17964 3 17896 17897 18185 3 17896 18185 18184 3 17897 17898 18186 3 17897 18186 18185 3 17898 17899 18187 3 17898 18187 18186 3 17899 17900 18188 3 17899 18188 18187 3 17900 17901 18189 3 17900 18189 18188 3 17901 17902 18190 3 17901 18190 18189 3 17902 17903 18191 3 17902 18191 18190 3 17903 17904 18192 3 17903 18192 18191 3 17904 17905 18193 3 17904 18193 18192 3 17905 17906 18194 3 17905 18194 18193 3 17906 17907 18195 3 17906 18195 18194 3 17907 17908 18196 3 17907 18196 18195 3 17908 17909 18197 3 17908 18197 18196 3 17909 17910 18198 3 17909 18198 18197 3 17910 17911 18199 3 17910 18199 18198 3 17911 17912 18200 3 17911 18200 18199 3 17912 17913 18201 3 17912 18201 18200 3 17913 17914 18202 3 17913 18202 18201 3 17914 17915 18203 3 17914 18203 18202 3 17915 17916 18204 3 17915 18204 18203 3 17916 17917 18205 3 17916 18205 18204 3 17917 17918 18206 3 17917 18206 18205 3 17918 17919 18207 3 17918 18207 18206 3 17919 17920 18208 3 17919 18208 18207 3 17920 17921 18209 3 17920 18209 18208 3 17921 17922 18210 3 17921 18210 18209 3 17922 17923 18211 3 17922 18211 18210 3 17923 17924 18212 3 17923 18212 18211 3 17924 17925 18213 3 17924 18213 18212 3 17925 17926 18214 3 17925 18214 18213 3 17926 17927 18215 3 17926 18215 18214 3 17927 17928 18216 3 17927 18216 18215 3 17928 17929 18217 3 17928 18217 18216 3 17929 17930 18218 3 17929 18218 18217 3 17930 17931 18219 3 17930 18219 18218 3 17931 17932 18220 3 17931 18220 18219 3 17932 17933 18221 3 17932 18221 18220 3 17933 17934 18222 3 17933 18222 18221 3 17934 17935 18223 3 17934 18223 18222 3 17935 17936 18224 3 17935 18224 18223 3 17936 17937 18225 3 17936 18225 18224 3 17937 17938 18226 3 17937 18226 18225 3 17938 17939 18227 3 17938 18227 18226 3 17939 17940 18228 3 17939 18228 18227 3 17940 17941 18229 3 17940 18229 18228 3 17941 17942 18230 3 17941 18230 18229 3 17942 17943 18231 3 17942 18231 18230 3 17943 17944 18232 3 17943 18232 18231 3 17944 17945 18233 3 17944 18233 18232 3 17945 17946 18234 3 17945 18234 18233 3 17946 17947 18235 3 17946 18235 18234 3 17947 17948 18236 3 17947 18236 18235 3 17948 17949 18237 3 17948 18237 18236 3 17949 17950 18238 3 17949 18238 18237 3 17950 17951 18239 3 17950 18239 18238 3 17951 17952 18240 3 17951 18240 18239 3 17952 17953 18241 3 17952 18241 18240 3 17953 17954 18242 3 17953 18242 18241 3 17954 17955 18243 3 17954 18243 18242 3 17955 17956 18244 3 17955 18244 18243 3 17956 17957 18245 3 17956 18245 18244 3 17957 17958 18246 3 17957 18246 18245 3 17958 17959 18247 3 17958 18247 18246 3 17959 17960 18248 3 17959 18248 18247 3 17960 17961 18249 3 17960 18249 18248 3 17961 17962 18250 3 17961 18250 18249 3 17962 17963 18251 3 17962 18251 18250 3 17963 17964 18252 3 17963 18252 18251 3 17965 18253 17966 3 18254 17966 18253 3 17965 18035 18253 3 18323 18253 18035 3 17966 18254 17967 3 18255 17967 18254 3 17967 18255 17968 3 18256 17968 18255 3 17968 18256 17969 3 18257 17969 18256 3 17969 18257 17970 3 18258 17970 18257 3 17970 18258 17971 3 18259 17971 18258 3 17971 18259 17972 3 18260 17972 18259 3 17972 18260 17973 3 18261 17973 18260 3 17973 18261 17974 3 18262 17974 18261 3 17974 18262 17975 3 18263 17975 18262 3 17975 18263 17976 3 18264 17976 18263 3 17976 18264 17977 3 18265 17977 18264 3 17977 18265 17978 3 18266 17978 18265 3 17978 18266 17979 3 18267 17979 18266 3 17979 18267 17980 3 18268 17980 18267 3 17980 18268 17981 3 18269 17981 18268 3 17981 18269 17982 3 18270 17982 18269 3 17982 18270 17983 3 18271 17983 18270 3 17983 18271 17984 3 18272 17984 18271 3 17984 18272 17985 3 18273 17985 18272 3 17985 18273 17986 3 18274 17986 18273 3 17986 18274 17987 3 18275 17987 18274 3 17987 18275 17988 3 18276 17988 18275 3 17988 18276 17989 3 18277 17989 18276 3 17989 18277 17990 3 18278 17990 18277 3 17990 18278 17991 3 18279 17991 18278 3 17991 18279 17992 3 18280 17992 18279 3 17992 18280 17993 3 18281 17993 18280 3 17993 18281 17994 3 18282 17994 18281 3 17994 18282 17995 3 18283 17995 18282 3 17995 18283 17996 3 18284 17996 18283 3 17996 18284 17997 3 18285 17997 18284 3 17997 18285 17998 3 18286 17998 18285 3 17998 18286 17999 3 18287 17999 18286 3 17999 18287 18000 3 18288 18000 18287 3 18000 18288 18001 3 18289 18001 18288 3 18001 18289 18002 3 18290 18002 18289 3 18002 18290 18003 3 18291 18003 18290 3 18003 18291 18004 3 18292 18004 18291 3 18004 18292 18005 3 18293 18005 18292 3 18005 18293 18006 3 18294 18006 18293 3 18006 18294 18007 3 18295 18007 18294 3 18007 18295 18008 3 18296 18008 18295 3 18008 18296 18009 3 18297 18009 18296 3 18009 18297 18010 3 18298 18010 18297 3 18010 18298 18011 3 18299 18011 18298 3 18011 18299 18012 3 18300 18012 18299 3 18012 18300 18013 3 18301 18013 18300 3 18013 18301 18014 3 18302 18014 18301 3 18014 18302 18015 3 18303 18015 18302 3 18015 18303 18016 3 18304 18016 18303 3 18016 18304 18017 3 18305 18017 18304 3 18017 18305 18018 3 18306 18018 18305 3 18018 18306 18019 3 18307 18019 18306 3 18019 18307 18020 3 18308 18020 18307 3 18020 18308 18021 3 18309 18021 18308 3 18021 18309 18022 3 18310 18022 18309 3 18022 18310 18023 3 18311 18023 18310 3 18023 18311 18024 3 18312 18024 18311 3 18024 18312 18025 3 18313 18025 18312 3 18025 18313 18026 3 18314 18026 18313 3 18026 18314 18027 3 18315 18027 18314 3 18027 18315 18028 3 18316 18028 18315 3 18028 18316 18029 3 18317 18029 18316 3 18029 18317 18030 3 18318 18030 18317 3 18030 18318 18031 3 18319 18031 18318 3 18031 18319 18032 3 18320 18032 18319 3 18032 18320 18033 3 18321 18033 18320 3 18033 18321 18036 3 18324 18036 18321 3 18034 18322 18035 3 18323 18035 18322 3 18034 18039 18322 3 18327 18322 18039 3 18036 18324 18037 3 18325 18037 18324 3 18037 18325 18040 3 18328 18040 18325 3 18038 18326 18039 3 18327 18039 18326 3 18038 18042 18326 3 18330 18326 18042 3 18040 18328 18041 3 18329 18041 18328 3 18041 18329 18043 3 18331 18043 18329 3 18042 18044 18330 3 18332 18330 18044 3 18043 18331 18045 3 18333 18045 18331 3 18044 18046 18332 3 18334 18332 18046 3 18045 18333 18047 3 18335 18047 18333 3 18046 18048 18336 3 18046 18336 18334 3 18047 18335 18049 3 18337 18049 18335 3 18048 18050 18338 3 18048 18338 18336 3 18049 18337 18339 3 18049 18339 18051 3 18050 18052 18340 3 18050 18340 18338 3 18051 18339 18341 3 18051 18341 18053 3 18052 18054 18342 3 18052 18342 18340 3 18053 18341 18343 3 18053 18343 18055 3 18054 18056 18344 3 18054 18344 18342 3 18055 18343 18345 3 18055 18345 18057 3 18056 18058 18346 3 18056 18346 18344 3 18057 18345 18347 3 18057 18347 18059 3 18058 18060 18348 3 18058 18348 18346 3 18059 18347 18349 3 18059 18349 18061 3 18060 18062 18350 3 18060 18350 18348 3 18061 18349 18351 3 18061 18351 18063 3 18062 18064 18352 3 18062 18352 18350 3 18063 18351 18353 3 18063 18353 18065 3 18064 18066 18354 3 18064 18354 18352 3 18065 18353 18355 3 18065 18355 18067 3 18066 18068 18356 3 18066 18356 18354 3 18067 18355 18357 3 18067 18357 18069 3 18068 18070 18358 3 18068 18358 18356 3 18069 18357 18359 3 18069 18359 18071 3 18070 18072 18360 3 18070 18360 18358 3 18071 18359 18361 3 18071 18361 18073 3 18072 18074 18362 3 18072 18362 18360 3 18073 18361 18363 3 18073 18363 18075 3 18074 18076 18364 3 18074 18364 18362 3 18075 18363 18365 3 18075 18365 18077 3 18076 18078 18366 3 18076 18366 18364 3 18077 18365 18367 3 18077 18367 18079 3 18078 18080 18368 3 18078 18368 18366 3 18079 18367 18369 3 18079 18369 18081 3 18080 18082 18370 3 18080 18370 18368 3 18081 18369 18371 3 18081 18371 18083 3 18082 18084 18372 3 18082 18372 18370 3 18083 18371 18373 3 18083 18373 18085 3 18084 18086 18374 3 18084 18374 18372 3 18085 18373 18375 3 18085 18375 18087 3 18086 18088 18376 3 18086 18376 18374 3 18087 18375 18377 3 18087 18377 18089 3 18088 18090 18378 3 18088 18378 18376 3 18089 18377 18379 3 18089 18379 18091 3 18090 18092 18380 3 18090 18380 18378 3 18091 18379 18381 3 18091 18381 18093 3 18092 18094 18382 3 18092 18382 18380 3 18093 18381 18383 3 18093 18383 18095 3 18094 18096 18384 3 18094 18384 18382 3 18095 18383 18385 3 18095 18385 18097 3 18096 18098 18386 3 18096 18386 18384 3 18097 18385 18387 3 18097 18387 18099 3 18098 18100 18388 3 18098 18388 18386 3 18099 18387 18389 3 18099 18389 18101 3 18100 18102 18390 3 18100 18390 18388 3 18101 18389 18391 3 18101 18391 18103 3 18102 18104 18392 3 18102 18392 18390 3 18103 18391 18393 3 18103 18393 18105 3 18104 18106 18394 3 18104 18394 18392 3 18105 18393 18395 3 18105 18395 18107 3 18106 18108 18396 3 18106 18396 18394 3 18107 18395 18397 3 18107 18397 18109 3 18108 18110 18398 3 18108 18398 18396 3 18109 18397 18399 3 18109 18399 18111 3 18110 18112 18400 3 18110 18400 18398 3 18111 18399 18401 3 18111 18401 18113 3 18112 18114 18402 3 18112 18402 18400 3 18113 18401 18403 3 18113 18403 18115 3 18114 18116 18404 3 18114 18404 18402 3 18115 18403 18405 3 18115 18405 18117 3 18116 18118 18406 3 18116 18406 18404 3 18117 18405 18407 3 18117 18407 18119 3 18118 18120 18408 3 18118 18408 18406 3 18119 18407 18409 3 18119 18409 18121 3 18120 18122 18410 3 18120 18410 18408 3 18121 18409 18411 3 18121 18411 18123 3 18122 18124 18412 3 18122 18412 18410 3 18123 18411 18413 3 18123 18413 18125 3 18124 18126 18414 3 18124 18414 18412 3 18125 18413 18415 3 18125 18415 18127 3 18126 18128 18416 3 18126 18416 18414 3 18127 18415 18417 3 18127 18417 18129 3 18128 18130 18418 3 18128 18418 18416 3 18129 18417 18419 3 18129 18419 18131 3 18130 18132 18418 3 18420 18418 18132 3 18131 18419 18133 3 18421 18133 18419 3 18132 18134 18420 3 18422 18420 18134 3 18133 18421 18135 3 18423 18135 18421 3 18134 18136 18422 3 18424 18422 18136 3 18135 18423 18137 3 18425 18137 18423 3 18136 18138 18424 3 18426 18424 18138 3 18137 18425 18139 3 18427 18139 18425 3 18138 18140 18426 3 18428 18426 18140 3 18139 18427 18141 3 18429 18141 18427 3 18140 18142 18428 3 18430 18428 18142 3 18141 18429 18143 3 18431 18143 18429 3 18142 18144 18430 3 18432 18430 18144 3 18143 18431 18145 3 18433 18145 18431 3 18144 18146 18432 3 18434 18432 18146 3 18145 18433 18147 3 18435 18147 18433 3 18146 18148 18434 3 18436 18434 18148 3 18147 18435 18149 3 18437 18149 18435 3 18148 18150 18436 3 18438 18436 18150 3 18149 18437 18151 3 18439 18151 18437 3 18150 18152 18438 3 18440 18438 18152 3 18151 18439 18153 3 18441 18153 18439 3 18152 18154 18440 3 18442 18440 18154 3 18153 18441 18155 3 18443 18155 18441 3 18154 18156 18442 3 18444 18442 18156 3 18155 18443 18157 3 18445 18157 18443 3 18156 18158 18444 3 18446 18444 18158 3 18157 18445 18159 3 18447 18159 18445 3 18158 18160 18446 3 18448 18446 18160 3 18159 18447 18161 3 18449 18161 18447 3 18160 18162 18448 3 18450 18448 18162 3 18161 18449 18163 3 18451 18163 18449 3 18162 18164 18450 3 18452 18450 18164 3 18163 18451 18165 3 18453 18165 18451 3 18164 18166 18452 3 18454 18452 18166 3 18165 18453 18167 3 18455 18167 18453 3 18166 18168 18454 3 18456 18454 18168 3 18167 18455 18169 3 18457 18169 18455 3 18168 18170 18456 3 18458 18456 18170 3 18169 18457 18171 3 18459 18171 18457 3 18170 18172 18458 3 18460 18458 18172 3 18171 18459 18173 3 18461 18173 18459 3 18172 18174 18460 3 18462 18460 18174 3 18173 18461 18175 3 18463 18175 18461 3 18174 18176 18462 3 18464 18462 18176 3 18175 18463 18179 3 18467 18179 18463 3 18176 18177 18464 3 18465 18464 18177 3 18177 18180 18465 3 18468 18465 18180 3 18178 18179 18466 3 18467 18466 18179 3 18178 18466 18183 3 18471 18183 18466 3 18180 18181 18468 3 18469 18468 18181 3 18181 18184 18469 3 18472 18469 18184 3 18182 18183 18470 3 18471 18470 18183 3 18182 18470 18252 3 18540 18252 18470 3 18184 18185 18472 3 18473 18472 18185 3 18185 18186 18473 3 18474 18473 18186 3 18186 18187 18474 3 18475 18474 18187 3 18187 18188 18475 3 18476 18475 18188 3 18188 18189 18476 3 18477 18476 18189 3 18189 18190 18477 3 18478 18477 18190 3 18190 18191 18478 3 18479 18478 18191 3 18191 18192 18479 3 18480 18479 18192 3 18192 18193 18480 3 18481 18480 18193 3 18193 18194 18481 3 18482 18481 18194 3 18194 18195 18482 3 18483 18482 18195 3 18195 18196 18483 3 18484 18483 18196 3 18196 18197 18484 3 18485 18484 18197 3 18197 18198 18485 3 18486 18485 18198 3 18198 18199 18486 3 18487 18486 18199 3 18199 18200 18487 3 18488 18487 18200 3 18200 18201 18488 3 18489 18488 18201 3 18201 18202 18489 3 18490 18489 18202 3 18202 18203 18490 3 18491 18490 18203 3 18203 18204 18491 3 18492 18491 18204 3 18204 18205 18492 3 18493 18492 18205 3 18205 18206 18493 3 18494 18493 18206 3 18206 18207 18494 3 18495 18494 18207 3 18207 18208 18495 3 18496 18495 18208 3 18208 18209 18496 3 18497 18496 18209 3 18209 18210 18497 3 18498 18497 18210 3 18210 18211 18498 3 18499 18498 18211 3 18211 18212 18499 3 18500 18499 18212 3 18212 18213 18500 3 18501 18500 18213 3 18213 18214 18502 3 18213 18502 18501 3 18214 18215 18503 3 18214 18503 18502 3 18215 18216 18504 3 18215 18504 18503 3 18216 18217 18505 3 18216 18505 18504 3 18217 18218 18506 3 18217 18506 18505 3 18218 18219 18507 3 18218 18507 18506 3 18219 18220 18508 3 18219 18508 18507 3 18220 18221 18509 3 18220 18509 18508 3 18221 18222 18510 3 18221 18510 18509 3 18222 18223 18511 3 18222 18511 18510 3 18223 18224 18512 3 18223 18512 18511 3 18224 18225 18513 3 18224 18513 18512 3 18225 18226 18514 3 18225 18514 18513 3 18226 18227 18515 3 18226 18515 18514 3 18227 18228 18516 3 18227 18516 18515 3 18228 18229 18517 3 18228 18517 18516 3 18229 18230 18518 3 18229 18518 18517 3 18230 18231 18519 3 18230 18519 18518 3 18231 18232 18520 3 18231 18520 18519 3 18232 18233 18521 3 18232 18521 18520 3 18233 18234 18522 3 18233 18522 18521 3 18234 18235 18523 3 18234 18523 18522 3 18235 18236 18524 3 18235 18524 18523 3 18236 18237 18525 3 18236 18525 18524 3 18237 18238 18526 3 18237 18526 18525 3 18238 18239 18527 3 18238 18527 18526 3 18239 18240 18528 3 18239 18528 18527 3 18240 18241 18529 3 18240 18529 18528 3 18241 18242 18530 3 18241 18530 18529 3 18242 18243 18531 3 18242 18531 18530 3 18243 18244 18532 3 18243 18532 18531 3 18244 18245 18533 3 18244 18533 18532 3 18245 18246 18534 3 18245 18534 18533 3 18246 18247 18535 3 18246 18535 18534 3 18247 18248 18536 3 18247 18536 18535 3 18248 18249 18537 3 18248 18537 18536 3 18249 18250 18538 3 18249 18538 18537 3 18250 18251 18539 3 18250 18539 18538 3 18251 18252 18540 3 18251 18540 18539 3 18253 18541 18542 3 18253 18542 18254 3 18253 18323 18611 3 18253 18611 18541 3 18254 18542 18543 3 18254 18543 18255 3 18255 18543 18544 3 18255 18544 18256 3 18256 18544 18545 3 18256 18545 18257 3 18257 18545 18546 3 18257 18546 18258 3 18258 18546 18547 3 18258 18547 18259 3 18259 18547 18548 3 18259 18548 18260 3 18260 18548 18549 3 18260 18549 18261 3 18261 18549 18550 3 18261 18550 18262 3 18262 18550 18551 3 18262 18551 18263 3 18263 18551 18552 3 18263 18552 18264 3 18264 18552 18553 3 18264 18553 18265 3 18265 18553 18554 3 18265 18554 18266 3 18266 18554 18555 3 18266 18555 18267 3 18267 18555 18556 3 18267 18556 18268 3 18268 18556 18557 3 18268 18557 18269 3 18269 18557 18558 3 18269 18558 18270 3 18270 18558 18559 3 18270 18559 18271 3 18271 18559 18560 3 18271 18560 18272 3 18272 18560 18561 3 18272 18561 18273 3 18273 18561 18562 3 18273 18562 18274 3 18274 18562 18563 3 18274 18563 18275 3 18275 18563 18564 3 18275 18564 18276 3 18276 18564 18565 3 18276 18565 18277 3 18277 18565 18566 3 18277 18566 18278 3 18278 18566 18567 3 18278 18567 18279 3 18279 18567 18568 3 18279 18568 18280 3 18280 18568 18569 3 18280 18569 18281 3 18281 18569 18570 3 18281 18570 18282 3 18282 18570 18571 3 18282 18571 18283 3 18283 18571 18572 3 18283 18572 18284 3 18284 18572 18573 3 18284 18573 18285 3 18285 18573 18574 3 18285 18574 18286 3 18286 18574 18575 3 18286 18575 18287 3 18287 18575 18576 3 18287 18576 18288 3 18288 18576 18577 3 18288 18577 18289 3 18289 18577 18578 3 18289 18578 18290 3 18290 18578 18579 3 18290 18579 18291 3 18291 18579 18580 3 18291 18580 18292 3 18292 18580 18581 3 18292 18581 18293 3 18293 18581 18582 3 18293 18582 18294 3 18294 18582 18583 3 18294 18583 18295 3 18295 18583 18584 3 18295 18584 18296 3 18296 18584 18585 3 18296 18585 18297 3 18297 18585 18586 3 18297 18586 18298 3 18298 18586 18299 3 18587 18299 18586 3 18299 18587 18300 3 18588 18300 18587 3 18300 18588 18301 3 18589 18301 18588 3 18301 18589 18302 3 18590 18302 18589 3 18302 18590 18303 3 18591 18303 18590 3 18303 18591 18304 3 18592 18304 18591 3 18304 18592 18305 3 18593 18305 18592 3 18305 18593 18306 3 18594 18306 18593 3 18306 18594 18307 3 18595 18307 18594 3 18307 18595 18308 3 18596 18308 18595 3 18308 18596 18309 3 18597 18309 18596 3 18309 18597 18310 3 18598 18310 18597 3 18310 18598 18311 3 18599 18311 18598 3 18311 18599 18312 3 18600 18312 18599 3 18312 18600 18313 3 18601 18313 18600 3 18313 18601 18314 3 18602 18314 18601 3 18314 18602 18315 3 18603 18315 18602 3 18315 18603 18316 3 18604 18316 18603 3 18316 18604 18317 3 18605 18317 18604 3 18317 18605 18318 3 18606 18318 18605 3 18318 18606 18319 3 18607 18319 18606 3 18319 18607 18320 3 18608 18320 18607 3 18320 18608 18321 3 18609 18321 18608 3 18321 18609 18324 3 18612 18324 18609 3 18322 18610 18323 3 18611 18323 18610 3 18322 18327 18610 3 18615 18610 18327 3 18324 18612 18325 3 18613 18325 18612 3 18325 18613 18328 3 18616 18328 18613 3 18326 18614 18327 3 18615 18327 18614 3 18326 18330 18614 3 18618 18614 18330 3 18328 18616 18329 3 18617 18329 18616 3 18329 18617 18331 3 18619 18331 18617 3 18330 18332 18618 3 18620 18618 18332 3 18331 18619 18333 3 18621 18333 18619 3 18332 18334 18620 3 18622 18620 18334 3 18333 18621 18335 3 18623 18335 18621 3 18334 18336 18622 3 18624 18622 18336 3 18335 18623 18337 3 18625 18337 18623 3 18336 18338 18624 3 18626 18624 18338 3 18337 18625 18339 3 18627 18339 18625 3 18338 18340 18626 3 18628 18626 18340 3 18339 18627 18341 3 18629 18341 18627 3 18340 18342 18628 3 18630 18628 18342 3 18341 18629 18343 3 18631 18343 18629 3 18342 18344 18630 3 18632 18630 18344 3 18343 18631 18345 3 18633 18345 18631 3 18344 18346 18632 3 18634 18632 18346 3 18345 18633 18347 3 18635 18347 18633 3 18346 18348 18634 3 18636 18634 18348 3 18347 18635 18349 3 18637 18349 18635 3 18348 18350 18636 3 18638 18636 18350 3 18349 18637 18351 3 18639 18351 18637 3 18350 18352 18638 3 18640 18638 18352 3 18351 18639 18353 3 18641 18353 18639 3 18352 18354 18640 3 18642 18640 18354 3 18353 18641 18355 3 18643 18355 18641 3 18354 18356 18642 3 18644 18642 18356 3 18355 18643 18357 3 18645 18357 18643 3 18356 18358 18644 3 18646 18644 18358 3 18357 18645 18359 3 18647 18359 18645 3 18358 18360 18646 3 18648 18646 18360 3 18359 18647 18361 3 18649 18361 18647 3 18360 18362 18648 3 18650 18648 18362 3 18361 18649 18363 3 18651 18363 18649 3 18362 18364 18650 3 18652 18650 18364 3 18363 18651 18365 3 18653 18365 18651 3 18364 18366 18652 3 18654 18652 18366 3 18365 18653 18367 3 18655 18367 18653 3 18366 18368 18654 3 18656 18654 18368 3 18367 18655 18369 3 18657 18369 18655 3 18368 18370 18656 3 18658 18656 18370 3 18369 18657 18371 3 18659 18371 18657 3 18370 18372 18658 3 18660 18658 18372 3 18371 18659 18373 3 18661 18373 18659 3 18372 18374 18660 3 18662 18660 18374 3 18373 18661 18375 3 18663 18375 18661 3 18374 18376 18662 3 18664 18662 18376 3 18375 18663 18377 3 18665 18377 18663 3 18376 18378 18664 3 18666 18664 18378 3 18377 18665 18379 3 18667 18379 18665 3 18378 18380 18666 3 18668 18666 18380 3 18379 18667 18381 3 18669 18381 18667 3 18380 18382 18670 3 18380 18670 18668 3 18381 18669 18383 3 18671 18383 18669 3 18382 18384 18672 3 18382 18672 18670 3 18383 18671 18673 3 18383 18673 18385 3 18384 18386 18674 3 18384 18674 18672 3 18385 18673 18675 3 18385 18675 18387 3 18386 18388 18676 3 18386 18676 18674 3 18387 18675 18677 3 18387 18677 18389 3 18388 18390 18678 3 18388 18678 18676 3 18389 18677 18679 3 18389 18679 18391 3 18390 18392 18680 3 18390 18680 18678 3 18391 18679 18681 3 18391 18681 18393 3 18392 18394 18682 3 18392 18682 18680 3 18393 18681 18683 3 18393 18683 18395 3 18394 18396 18684 3 18394 18684 18682 3 18395 18683 18685 3 18395 18685 18397 3 18396 18398 18686 3 18396 18686 18684 3 18397 18685 18687 3 18397 18687 18399 3 18398 18400 18688 3 18398 18688 18686 3 18399 18687 18689 3 18399 18689 18401 3 18400 18402 18690 3 18400 18690 18688 3 18401 18689 18691 3 18401 18691 18403 3 18402 18404 18692 3 18402 18692 18690 3 18403 18691 18693 3 18403 18693 18405 3 18404 18406 18694 3 18404 18694 18692 3 18405 18693 18695 3 18405 18695 18407 3 18406 18408 18696 3 18406 18696 18694 3 18407 18695 18697 3 18407 18697 18409 3 18408 18410 18698 3 18408 18698 18696 3 18409 18697 18699 3 18409 18699 18411 3 18410 18412 18700 3 18410 18700 18698 3 18411 18699 18701 3 18411 18701 18413 3 18412 18414 18702 3 18412 18702 18700 3 18413 18701 18703 3 18413 18703 18415 3 18414 18416 18704 3 18414 18704 18702 3 18415 18703 18705 3 18415 18705 18417 3 18416 18418 18706 3 18416 18706 18704 3 18417 18705 18707 3 18417 18707 18419 3 18418 18420 18708 3 18418 18708 18706 3 18419 18707 18709 3 18419 18709 18421 3 18420 18422 18710 3 18420 18710 18708 3 18421 18709 18711 3 18421 18711 18423 3 18422 18424 18712 3 18422 18712 18710 3 18423 18711 18713 3 18423 18713 18425 3 18424 18426 18714 3 18424 18714 18712 3 18425 18713 18715 3 18425 18715 18427 3 18426 18428 18716 3 18426 18716 18714 3 18427 18715 18717 3 18427 18717 18429 3 18428 18430 18718 3 18428 18718 18716 3 18429 18717 18719 3 18429 18719 18431 3 18430 18432 18720 3 18430 18720 18718 3 18431 18719 18721 3 18431 18721 18433 3 18432 18434 18722 3 18432 18722 18720 3 18433 18721 18723 3 18433 18723 18435 3 18434 18436 18724 3 18434 18724 18722 3 18435 18723 18725 3 18435 18725 18437 3 18436 18438 18726 3 18436 18726 18724 3 18437 18725 18727 3 18437 18727 18439 3 18438 18440 18728 3 18438 18728 18726 3 18439 18727 18729 3 18439 18729 18441 3 18440 18442 18730 3 18440 18730 18728 3 18441 18729 18731 3 18441 18731 18443 3 18442 18444 18732 3 18442 18732 18730 3 18443 18731 18733 3 18443 18733 18445 3 18444 18446 18734 3 18444 18734 18732 3 18445 18733 18735 3 18445 18735 18447 3 18446 18448 18736 3 18446 18736 18734 3 18447 18735 18737 3 18447 18737 18449 3 18448 18450 18738 3 18448 18738 18736 3 18449 18737 18739 3 18449 18739 18451 3 18450 18452 18740 3 18450 18740 18738 3 18451 18739 18741 3 18451 18741 18453 3 18452 18454 18742 3 18452 18742 18740 3 18453 18741 18743 3 18453 18743 18455 3 18454 18456 18744 3 18454 18744 18742 3 18455 18743 18745 3 18455 18745 18457 3 18456 18458 18746 3 18456 18746 18744 3 18457 18745 18747 3 18457 18747 18459 3 18458 18460 18748 3 18458 18748 18746 3 18459 18747 18749 3 18459 18749 18461 3 18460 18462 18750 3 18460 18750 18748 3 18461 18749 18751 3 18461 18751 18463 3 18462 18464 18750 3 18752 18750 18464 3 18463 18751 18755 3 18463 18755 18467 3 18464 18465 18752 3 18753 18752 18465 3 18465 18468 18753 3 18756 18753 18468 3 18466 18467 18754 3 18755 18754 18467 3 18466 18754 18471 3 18759 18471 18754 3 18468 18469 18756 3 18757 18756 18469 3 18469 18472 18757 3 18760 18757 18472 3 18470 18471 18758 3 18759 18758 18471 3 18470 18758 18540 3 18828 18540 18758 3 18472 18473 18760 3 18761 18760 18473 3 18473 18474 18761 3 18762 18761 18474 3 18474 18475 18762 3 18763 18762 18475 3 18475 18476 18763 3 18764 18763 18476 3 18476 18477 18764 3 18765 18764 18477 3 18477 18478 18765 3 18766 18765 18478 3 18478 18479 18766 3 18767 18766 18479 3 18479 18480 18767 3 18768 18767 18480 3 18480 18481 18768 3 18769 18768 18481 3 18481 18482 18769 3 18770 18769 18482 3 18482 18483 18770 3 18771 18770 18483 3 18483 18484 18771 3 18772 18771 18484 3 18484 18485 18772 3 18773 18772 18485 3 18485 18486 18773 3 18774 18773 18486 3 18486 18487 18774 3 18775 18774 18487 3 18487 18488 18775 3 18776 18775 18488 3 18488 18489 18776 3 18777 18776 18489 3 18489 18490 18777 3 18778 18777 18490 3 18490 18491 18778 3 18779 18778 18491 3 18491 18492 18779 3 18780 18779 18492 3 18492 18493 18780 3 18781 18780 18493 3 18493 18494 18781 3 18782 18781 18494 3 18494 18495 18782 3 18783 18782 18495 3 18495 18496 18783 3 18784 18783 18496 3 18496 18497 18784 3 18785 18784 18497 3 18497 18498 18785 3 18786 18785 18498 3 18498 18499 18786 3 18787 18786 18499 3 18499 18500 18787 3 18788 18787 18500 3 18500 18501 18788 3 18789 18788 18501 3 18501 18502 18789 3 18790 18789 18502 3 18502 18503 18790 3 18791 18790 18503 3 18503 18504 18791 3 18792 18791 18504 3 18504 18505 18792 3 18793 18792 18505 3 18505 18506 18793 3 18794 18793 18506 3 18506 18507 18794 3 18795 18794 18507 3 18507 18508 18795 3 18796 18795 18508 3 18508 18509 18796 3 18797 18796 18509 3 18509 18510 18797 3 18798 18797 18510 3 18510 18511 18798 3 18799 18798 18511 3 18511 18512 18799 3 18800 18799 18512 3 18512 18513 18800 3 18801 18800 18513 3 18513 18514 18801 3 18802 18801 18514 3 18514 18515 18802 3 18803 18802 18515 3 18515 18516 18803 3 18804 18803 18516 3 18516 18517 18804 3 18805 18804 18517 3 18517 18518 18805 3 18806 18805 18518 3 18518 18519 18806 3 18807 18806 18519 3 18519 18520 18807 3 18808 18807 18520 3 18520 18521 18808 3 18809 18808 18521 3 18521 18522 18809 3 18810 18809 18522 3 18522 18523 18810 3 18811 18810 18523 3 18523 18524 18811 3 18812 18811 18524 3 18524 18525 18812 3 18813 18812 18525 3 18525 18526 18813 3 18814 18813 18526 3 18526 18527 18814 3 18815 18814 18527 3 18527 18528 18815 3 18816 18815 18528 3 18528 18529 18816 3 18817 18816 18529 3 18529 18530 18817 3 18818 18817 18530 3 18530 18531 18818 3 18819 18818 18531 3 18531 18532 18819 3 18820 18819 18532 3 18532 18533 18820 3 18821 18820 18533 3 18533 18534 18821 3 18822 18821 18534 3 18534 18535 18822 3 18823 18822 18535 3 18535 18536 18823 3 18824 18823 18536 3 18536 18537 18824 3 18825 18824 18537 3 18537 18538 18825 3 18826 18825 18538 3 18538 18539 18826 3 18827 18826 18539 3 18539 18540 18827 3 18828 18827 18540 3 18541 18829 18542 3 18830 18542 18829 3 18541 18611 18899 3 18541 18899 18829 3 18542 18830 18543 3 18831 18543 18830 3 18543 18831 18544 3 18832 18544 18831 3 18544 18832 18545 3 18833 18545 18832 3 18545 18833 18546 3 18834 18546 18833 3 18546 18834 18547 3 18835 18547 18834 3 18547 18835 18548 3 18836 18548 18835 3 18548 18836 18549 3 18837 18549 18836 3 18549 18837 18550 3 18838 18550 18837 3 18550 18838 18839 3 18550 18839 18551 3 18551 18839 18840 3 18551 18840 18552 3 18552 18840 18841 3 18552 18841 18553 3 18553 18841 18842 3 18553 18842 18554 3 18554 18842 18843 3 18554 18843 18555 3 18555 18843 18844 3 18555 18844 18556 3 18556 18844 18845 3 18556 18845 18557 3 18557 18845 18846 3 18557 18846 18558 3 18558 18846 18847 3 18558 18847 18559 3 18559 18847 18848 3 18559 18848 18560 3 18560 18848 18849 3 18560 18849 18561 3 18561 18849 18850 3 18561 18850 18562 3 18562 18850 18851 3 18562 18851 18563 3 18563 18851 18852 3 18563 18852 18564 3 18564 18852 18853 3 18564 18853 18565 3 18565 18853 18854 3 18565 18854 18566 3 18566 18854 18855 3 18566 18855 18567 3 18567 18855 18856 3 18567 18856 18568 3 18568 18856 18857 3 18568 18857 18569 3 18569 18857 18858 3 18569 18858 18570 3 18570 18858 18859 3 18570 18859 18571 3 18571 18859 18860 3 18571 18860 18572 3 18572 18860 18861 3 18572 18861 18573 3 18573 18861 18862 3 18573 18862 18574 3 18574 18862 18863 3 18574 18863 18575 3 18575 18863 18864 3 18575 18864 18576 3 18576 18864 18865 3 18576 18865 18577 3 18577 18865 18866 3 18577 18866 18578 3 18578 18866 18867 3 18578 18867 18579 3 18579 18867 18868 3 18579 18868 18580 3 18580 18868 18869 3 18580 18869 18581 3 18581 18869 18870 3 18581 18870 18582 3 18582 18870 18871 3 18582 18871 18583 3 18583 18871 18872 3 18583 18872 18584 3 18584 18872 18873 3 18584 18873 18585 3 18585 18873 18874 3 18585 18874 18586 3 18586 18874 18875 3 18586 18875 18587 3 18587 18875 18876 3 18587 18876 18588 3 18588 18876 18877 3 18588 18877 18589 3 18589 18877 18878 3 18589 18878 18590 3 18590 18878 18879 3 18590 18879 18591 3 18591 18879 18880 3 18591 18880 18592 3 18592 18880 18881 3 18592 18881 18593 3 18593 18881 18882 3 18593 18882 18594 3 18594 18882 18883 3 18594 18883 18595 3 18595 18883 18884 3 18595 18884 18596 3 18596 18884 18885 3 18596 18885 18597 3 18597 18885 18886 3 18597 18886 18598 3 18598 18886 18887 3 18598 18887 18599 3 18599 18887 18888 3 18599 18888 18600 3 18600 18888 18889 3 18600 18889 18601 3 18601 18889 18890 3 18601 18890 18602 3 18602 18890 18891 3 18602 18891 18603 3 18603 18891 18892 3 18603 18892 18604 3 18604 18892 18893 3 18604 18893 18605 3 18605 18893 18894 3 18605 18894 18606 3 18606 18894 18895 3 18606 18895 18607 3 18607 18895 18896 3 18607 18896 18608 3 18608 18896 18897 3 18608 18897 18609 3 18609 18897 18900 3 18609 18900 18612 3 18610 18898 18899 3 18610 18899 18611 3 18610 18615 18903 3 18610 18903 18898 3 18612 18900 18901 3 18612 18901 18613 3 18613 18901 18904 3 18613 18904 18616 3 18614 18902 18903 3 18614 18903 18615 3 18614 18618 18906 3 18614 18906 18902 3 18616 18904 18905 3 18616 18905 18617 3 18617 18905 18907 3 18617 18907 18619 3 18618 18620 18908 3 18618 18908 18906 3 18619 18907 18909 3 18619 18909 18621 3 18620 18622 18910 3 18620 18910 18908 3 18621 18909 18911 3 18621 18911 18623 3 18622 18624 18912 3 18622 18912 18910 3 18623 18911 18913 3 18623 18913 18625 3 18624 18626 18914 3 18624 18914 18912 3 18625 18913 18915 3 18625 18915 18627 3 18626 18628 18916 3 18626 18916 18914 3 18627 18915 18917 3 18627 18917 18629 3 18628 18630 18918 3 18628 18918 18916 3 18629 18917 18919 3 18629 18919 18631 3 18630 18632 18918 3 18920 18918 18632 3 18631 18919 18921 3 18631 18921 18633 3 18632 18634 18920 3 18922 18920 18634 3 18633 18921 18923 3 18633 18923 18635 3 18634 18636 18922 3 18924 18922 18636 3 18635 18923 18637 3 18925 18637 18923 3 18636 18638 18924 3 18926 18924 18638 3 18637 18925 18639 3 18927 18639 18925 3 18638 18640 18926 3 18928 18926 18640 3 18639 18927 18641 3 18929 18641 18927 3 18640 18642 18928 3 18930 18928 18642 3 18641 18929 18643 3 18931 18643 18929 3 18642 18644 18930 3 18932 18930 18644 3 18643 18931 18645 3 18933 18645 18931 3 18644 18646 18932 3 18934 18932 18646 3 18645 18933 18647 3 18935 18647 18933 3 18646 18648 18934 3 18936 18934 18648 3 18647 18935 18649 3 18937 18649 18935 3 18648 18650 18936 3 18938 18936 18650 3 18649 18937 18651 3 18939 18651 18937 3 18650 18652 18938 3 18940 18938 18652 3 18651 18939 18653 3 18941 18653 18939 3 18652 18654 18940 3 18942 18940 18654 3 18653 18941 18655 3 18943 18655 18941 3 18654 18656 18942 3 18944 18942 18656 3 18655 18943 18657 3 18945 18657 18943 3 18656 18658 18944 3 18946 18944 18658 3 18657 18945 18659 3 18947 18659 18945 3 18658 18660 18946 3 18948 18946 18660 3 18659 18947 18661 3 18949 18661 18947 3 18660 18662 18948 3 18950 18948 18662 3 18661 18949 18663 3 18951 18663 18949 3 18662 18664 18950 3 18952 18950 18664 3 18663 18951 18665 3 18953 18665 18951 3 18664 18666 18952 3 18954 18952 18666 3 18665 18953 18667 3 18955 18667 18953 3 18666 18668 18954 3 18956 18954 18668 3 18667 18955 18669 3 18957 18669 18955 3 18668 18670 18956 3 18958 18956 18670 3 18669 18957 18671 3 18959 18671 18957 3 18670 18672 18958 3 18960 18958 18672 3 18671 18959 18673 3 18961 18673 18959 3 18672 18674 18960 3 18962 18960 18674 3 18673 18961 18675 3 18963 18675 18961 3 18674 18676 18962 3 18964 18962 18676 3 18675 18963 18677 3 18965 18677 18963 3 18676 18678 18964 3 18966 18964 18678 3 18677 18965 18679 3 18967 18679 18965 3 18678 18680 18966 3 18968 18966 18680 3 18679 18967 18681 3 18969 18681 18967 3 18680 18682 18968 3 18970 18968 18682 3 18681 18969 18683 3 18971 18683 18969 3 18682 18684 18970 3 18972 18970 18684 3 18683 18971 18685 3 18973 18685 18971 3 18684 18686 18972 3 18974 18972 18686 3 18685 18973 18687 3 18975 18687 18973 3 18686 18688 18974 3 18976 18974 18688 3 18687 18975 18689 3 18977 18689 18975 3 18688 18690 18976 3 18978 18976 18690 3 18689 18977 18691 3 18979 18691 18977 3 18690 18692 18978 3 18980 18978 18692 3 18691 18979 18693 3 18981 18693 18979 3 18692 18694 18980 3 18982 18980 18694 3 18693 18981 18695 3 18983 18695 18981 3 18694 18696 18982 3 18984 18982 18696 3 18695 18983 18697 3 18985 18697 18983 3 18696 18698 18984 3 18986 18984 18698 3 18697 18985 18699 3 18987 18699 18985 3 18698 18700 18986 3 18988 18986 18700 3 18699 18987 18701 3 18989 18701 18987 3 18700 18702 18988 3 18990 18988 18702 3 18701 18989 18703 3 18991 18703 18989 3 18702 18704 18990 3 18992 18990 18704 3 18703 18991 18705 3 18993 18705 18991 3 18704 18706 18992 3 18994 18992 18706 3 18705 18993 18707 3 18995 18707 18993 3 18706 18708 18994 3 18996 18994 18708 3 18707 18995 18709 3 18997 18709 18995 3 18708 18710 18996 3 18998 18996 18710 3 18709 18997 18711 3 18999 18711 18997 3 18710 18712 18998 3 19000 18998 18712 3 18711 18999 18713 3 19001 18713 18999 3 18712 18714 19000 3 19002 19000 18714 3 18713 19001 18715 3 19003 18715 19001 3 18714 18716 19004 3 18714 19004 19002 3 18715 19003 18717 3 19005 18717 19003 3 18716 18718 19006 3 18716 19006 19004 3 18717 19005 18719 3 19007 18719 19005 3 18718 18720 19008 3 18718 19008 19006 3 18719 19007 19009 3 18719 19009 18721 3 18720 18722 19010 3 18720 19010 19008 3 18721 19009 19011 3 18721 19011 18723 3 18722 18724 19012 3 18722 19012 19010 3 18723 19011 19013 3 18723 19013 18725 3 18724 18726 19014 3 18724 19014 19012 3 18725 19013 19015 3 18725 19015 18727 3 18726 18728 19016 3 18726 19016 19014 3 18727 19015 19017 3 18727 19017 18729 3 18728 18730 19018 3 18728 19018 19016 3 18729 19017 19019 3 18729 19019 18731 3 18730 18732 19020 3 18730 19020 19018 3 18731 19019 19021 3 18731 19021 18733 3 18732 18734 19022 3 18732 19022 19020 3 18733 19021 19023 3 18733 19023 18735 3 18734 18736 19024 3 18734 19024 19022 3 18735 19023 19025 3 18735 19025 18737 3 18736 18738 19026 3 18736 19026 19024 3 18737 19025 19027 3 18737 19027 18739 3 18738 18740 19028 3 18738 19028 19026 3 18739 19027 19029 3 18739 19029 18741 3 18740 18742 19030 3 18740 19030 19028 3 18741 19029 19031 3 18741 19031 18743 3 18742 18744 19032 3 18742 19032 19030 3 18743 19031 19033 3 18743 19033 18745 3 18744 18746 19034 3 18744 19034 19032 3 18745 19033 19035 3 18745 19035 18747 3 18746 18748 19036 3 18746 19036 19034 3 18747 19035 19037 3 18747 19037 18749 3 18748 18750 19038 3 18748 19038 19036 3 18749 19037 19039 3 18749 19039 18751 3 18750 18752 19040 3 18750 19040 19038 3 18751 19039 19043 3 18751 19043 18755 3 18752 18753 19041 3 18752 19041 19040 3 18753 18756 19044 3 18753 19044 19041 3 18754 18755 19043 3 18754 19043 19042 3 18754 19042 19047 3 18754 19047 18759 3 18756 18757 19045 3 18756 19045 19044 3 18757 18760 19048 3 18757 19048 19045 3 18758 18759 19047 3 18758 19047 19046 3 18758 19046 19116 3 18758 19116 18828 3 18760 18761 19049 3 18760 19049 19048 3 18761 18762 19050 3 18761 19050 19049 3 18762 18763 19051 3 18762 19051 19050 3 18763 18764 19052 3 18763 19052 19051 3 18764 18765 19053 3 18764 19053 19052 3 18765 18766 19054 3 18765 19054 19053 3 18766 18767 19055 3 18766 19055 19054 3 18767 18768 19056 3 18767 19056 19055 3 18768 18769 19057 3 18768 19057 19056 3 18769 18770 19058 3 18769 19058 19057 3 18770 18771 19059 3 18770 19059 19058 3 18771 18772 19060 3 18771 19060 19059 3 18772 18773 19061 3 18772 19061 19060 3 18773 18774 19062 3 18773 19062 19061 3 18774 18775 19063 3 18774 19063 19062 3 18775 18776 19064 3 18775 19064 19063 3 18776 18777 19065 3 18776 19065 19064 3 18777 18778 19066 3 18777 19066 19065 3 18778 18779 19067 3 18778 19067 19066 3 18779 18780 19068 3 18779 19068 19067 3 18780 18781 19069 3 18780 19069 19068 3 18781 18782 19070 3 18781 19070 19069 3 18782 18783 19071 3 18782 19071 19070 3 18783 18784 19072 3 18783 19072 19071 3 18784 18785 19073 3 18784 19073 19072 3 18785 18786 19074 3 18785 19074 19073 3 18786 18787 19075 3 18786 19075 19074 3 18787 18788 19076 3 18787 19076 19075 3 18788 18789 19077 3 18788 19077 19076 3 18789 18790 19078 3 18789 19078 19077 3 18790 18791 19079 3 18790 19079 19078 3 18791 18792 19080 3 18791 19080 19079 3 18792 18793 19081 3 18792 19081 19080 3 18793 18794 19082 3 18793 19082 19081 3 18794 18795 19083 3 18794 19083 19082 3 18795 18796 19084 3 18795 19084 19083 3 18796 18797 19085 3 18796 19085 19084 3 18797 18798 19086 3 18797 19086 19085 3 18798 18799 19087 3 18798 19087 19086 3 18799 18800 19087 3 19088 19087 18800 3 18800 18801 19088 3 19089 19088 18801 3 18801 18802 19089 3 19090 19089 18802 3 18802 18803 19090 3 19091 19090 18803 3 18803 18804 19091 3 19092 19091 18804 3 18804 18805 19092 3 19093 19092 18805 3 18805 18806 19093 3 19094 19093 18806 3 18806 18807 19094 3 19095 19094 18807 3 18807 18808 19095 3 19096 19095 18808 3 18808 18809 19096 3 19097 19096 18809 3 18809 18810 19097 3 19098 19097 18810 3 18810 18811 19098 3 19099 19098 18811 3 18811 18812 19099 3 19100 19099 18812 3 18812 18813 19100 3 19101 19100 18813 3 18813 18814 19101 3 19102 19101 18814 3 18814 18815 19102 3 19103 19102 18815 3 18815 18816 19103 3 19104 19103 18816 3 18816 18817 19104 3 19105 19104 18817 3 18817 18818 19105 3 19106 19105 18818 3 18818 18819 19106 3 19107 19106 18819 3 18819 18820 19107 3 19108 19107 18820 3 18820 18821 19108 3 19109 19108 18821 3 18821 18822 19109 3 19110 19109 18822 3 18822 18823 19110 3 19111 19110 18823 3 18823 18824 19111 3 19112 19111 18824 3 18824 18825 19112 3 19113 19112 18825 3 18825 18826 19113 3 19114 19113 18826 3 18826 18827 19114 3 19115 19114 18827 3 18827 18828 19115 3 19116 19115 18828 3 18829 19117 18830 3 19118 18830 19117 3 18829 18899 19117 3 19187 19117 18899 3 18830 19118 18831 3 19119 18831 19118 3 18831 19119 18832 3 19120 18832 19119 3 18832 19120 18833 3 19121 18833 19120 3 18833 19121 18834 3 19122 18834 19121 3 18834 19122 18835 3 19123 18835 19122 3 18835 19123 18836 3 19124 18836 19123 3 18836 19124 18837 3 19125 18837 19124 3 18837 19125 18838 3 19126 18838 19125 3 18838 19126 18839 3 19127 18839 19126 3 18839 19127 18840 3 19128 18840 19127 3 18840 19128 18841 3 19129 18841 19128 3 18841 19129 18842 3 19130 18842 19129 3 18842 19130 18843 3 19131 18843 19130 3 18843 19131 18844 3 19132 18844 19131 3 18844 19132 18845 3 19133 18845 19132 3 18845 19133 18846 3 19134 18846 19133 3 18846 19134 18847 3 19135 18847 19134 3 18847 19135 18848 3 19136 18848 19135 3 18848 19136 18849 3 19137 18849 19136 3 18849 19137 18850 3 19138 18850 19137 3 18850 19138 18851 3 19139 18851 19138 3 18851 19139 18852 3 19140 18852 19139 3 18852 19140 18853 3 19141 18853 19140 3 18853 19141 18854 3 19142 18854 19141 3 18854 19142 18855 3 19143 18855 19142 3 18855 19143 18856 3 19144 18856 19143 3 18856 19144 18857 3 19145 18857 19144 3 18857 19145 18858 3 19146 18858 19145 3 18858 19146 18859 3 19147 18859 19146 3 18859 19147 18860 3 19148 18860 19147 3 18860 19148 18861 3 19149 18861 19148 3 18861 19149 18862 3 19150 18862 19149 3 18862 19150 18863 3 19151 18863 19150 3 18863 19151 18864 3 19152 18864 19151 3 18864 19152 18865 3 19153 18865 19152 3 18865 19153 18866 3 19154 18866 19153 3 18866 19154 18867 3 19155 18867 19154 3 18867 19155 18868 3 19156 18868 19155 3 18868 19156 18869 3 19157 18869 19156 3 18869 19157 18870 3 19158 18870 19157 3 18870 19158 18871 3 19159 18871 19158 3 18871 19159 18872 3 19160 18872 19159 3 18872 19160 18873 3 19161 18873 19160 3 18873 19161 18874 3 19162 18874 19161 3 18874 19162 18875 3 19163 18875 19162 3 18875 19163 18876 3 19164 18876 19163 3 18876 19164 18877 3 19165 18877 19164 3 18877 19165 18878 3 19166 18878 19165 3 18878 19166 18879 3 19167 18879 19166 3 18879 19167 18880 3 19168 18880 19167 3 18880 19168 18881 3 19169 18881 19168 3 18881 19169 18882 3 19170 18882 19169 3 18882 19170 18883 3 19171 18883 19170 3 18883 19171 18884 3 19172 18884 19171 3 18884 19172 18885 3 19173 18885 19172 3 18885 19173 18886 3 19174 18886 19173 3 18886 19174 18887 3 19175 18887 19174 3 18887 19175 18888 3 19176 18888 19175 3 18888 19176 19177 3 18888 19177 18889 3 18889 19177 19178 3 18889 19178 18890 3 18890 19178 19179 3 18890 19179 18891 3 18891 19179 19180 3 18891 19180 18892 3 18892 19180 19181 3 18892 19181 18893 3 18893 19181 19182 3 18893 19182 18894 3 18894 19182 19183 3 18894 19183 18895 3 18895 19183 19184 3 18895 19184 18896 3 18896 19184 19185 3 18896 19185 18897 3 18897 19185 19188 3 18897 19188 18900 3 18898 19186 19187 3 18898 19187 18899 3 18898 18903 19191 3 18898 19191 19186 3 18900 19188 19189 3 18900 19189 18901 3 18901 19189 19192 3 18901 19192 18904 3 18902 19190 19191 3 18902 19191 18903 3 18902 18906 19194 3 18902 19194 19190 3 18904 19192 19193 3 18904 19193 18905 3 18905 19193 19195 3 18905 19195 18907 3 18906 18908 19196 3 18906 19196 19194 3 18907 19195 19197 3 18907 19197 18909 3 18908 18910 19198 3 18908 19198 19196 3 18909 19197 19199 3 18909 19199 18911 3 18910 18912 19200 3 18910 19200 19198 3 18911 19199 19201 3 18911 19201 18913 3 18912 18914 19202 3 18912 19202 19200 3 18913 19201 19203 3 18913 19203 18915 3 18914 18916 19204 3 18914 19204 19202 3 18915 19203 19205 3 18915 19205 18917 3 18916 18918 19206 3 18916 19206 19204 3 18917 19205 19207 3 18917 19207 18919 3 18918 18920 19208 3 18918 19208 19206 3 18919 19207 19209 3 18919 19209 18921 3 18920 18922 19210 3 18920 19210 19208 3 18921 19209 19211 3 18921 19211 18923 3 18922 18924 19212 3 18922 19212 19210 3 18923 19211 19213 3 18923 19213 18925 3 18924 18926 19214 3 18924 19214 19212 3 18925 19213 19215 3 18925 19215 18927 3 18926 18928 19216 3 18926 19216 19214 3 18927 19215 19217 3 18927 19217 18929 3 18928 18930 19218 3 18928 19218 19216 3 18929 19217 19219 3 18929 19219 18931 3 18930 18932 19220 3 18930 19220 19218 3 18931 19219 19221 3 18931 19221 18933 3 18932 18934 19222 3 18932 19222 19220 3 18933 19221 19223 3 18933 19223 18935 3 18934 18936 19224 3 18934 19224 19222 3 18935 19223 19225 3 18935 19225 18937 3 18936 18938 19226 3 18936 19226 19224 3 18937 19225 19227 3 18937 19227 18939 3 18938 18940 19228 3 18938 19228 19226 3 18939 19227 19229 3 18939 19229 18941 3 18940 18942 19230 3 18940 19230 19228 3 18941 19229 19231 3 18941 19231 18943 3 18942 18944 19232 3 18942 19232 19230 3 18943 19231 19233 3 18943 19233 18945 3 18944 18946 19234 3 18944 19234 19232 3 18945 19233 19235 3 18945 19235 18947 3 18946 18948 19236 3 18946 19236 19234 3 18947 19235 19237 3 18947 19237 18949 3 18948 18950 19238 3 18948 19238 19236 3 18949 19237 19239 3 18949 19239 18951 3 18950 18952 19240 3 18950 19240 19238 3 18951 19239 19241 3 18951 19241 18953 3 18952 18954 19242 3 18952 19242 19240 3 18953 19241 19243 3 18953 19243 18955 3 18954 18956 19244 3 18954 19244 19242 3 18955 19243 19245 3 18955 19245 18957 3 18956 18958 19246 3 18956 19246 19244 3 18957 19245 19247 3 18957 19247 18959 3 18958 18960 19248 3 18958 19248 19246 3 18959 19247 19249 3 18959 19249 18961 3 18960 18962 19250 3 18960 19250 19248 3 18961 19249 19251 3 18961 19251 18963 3 18962 18964 19252 3 18962 19252 19250 3 18963 19251 19253 3 18963 19253 18965 3 18964 18966 19254 3 18964 19254 19252 3 18965 19253 19255 3 18965 19255 18967 3 18966 18968 19256 3 18966 19256 19254 3 18967 19255 19257 3 18967 19257 18969 3 18968 18970 19256 3 19258 19256 18970 3 18969 19257 19259 3 18969 19259 18971 3 18970 18972 19258 3 19260 19258 18972 3 18971 19259 19261 3 18971 19261 18973 3 18972 18974 19260 3 19262 19260 18974 3 18973 19261 18975 3 19263 18975 19261 3 18974 18976 19262 3 19264 19262 18976 3 18975 19263 18977 3 19265 18977 19263 3 18976 18978 19264 3 19266 19264 18978 3 18977 19265 18979 3 19267 18979 19265 3 18978 18980 19266 3 19268 19266 18980 3 18979 19267 18981 3 19269 18981 19267 3 18980 18982 19268 3 19270 19268 18982 3 18981 19269 18983 3 19271 18983 19269 3 18982 18984 19270 3 19272 19270 18984 3 18983 19271 18985 3 19273 18985 19271 3 18984 18986 19272 3 19274 19272 18986 3 18985 19273 18987 3 19275 18987 19273 3 18986 18988 19274 3 19276 19274 18988 3 18987 19275 18989 3 19277 18989 19275 3 18988 18990 19276 3 19278 19276 18990 3 18989 19277 18991 3 19279 18991 19277 3 18990 18992 19278 3 19280 19278 18992 3 18991 19279 18993 3 19281 18993 19279 3 18992 18994 19280 3 19282 19280 18994 3 18993 19281 18995 3 19283 18995 19281 3 18994 18996 19282 3 19284 19282 18996 3 18995 19283 18997 3 19285 18997 19283 3 18996 18998 19284 3 19286 19284 18998 3 18997 19285 18999 3 19287 18999 19285 3 18998 19000 19286 3 19288 19286 19000 3 18999 19287 19001 3 19289 19001 19287 3 19000 19002 19288 3 19290 19288 19002 3 19001 19289 19003 3 19291 19003 19289 3 19002 19004 19290 3 19292 19290 19004 3 19003 19291 19005 3 19293 19005 19291 3 19004 19006 19292 3 19294 19292 19006 3 19005 19293 19007 3 19295 19007 19293 3 19006 19008 19294 3 19296 19294 19008 3 19007 19295 19009 3 19297 19009 19295 3 19008 19010 19296 3 19298 19296 19010 3 19009 19297 19011 3 19299 19011 19297 3 19010 19012 19298 3 19300 19298 19012 3 19011 19299 19013 3 19301 19013 19299 3 19012 19014 19300 3 19302 19300 19014 3 19013 19301 19015 3 19303 19015 19301 3 19014 19016 19302 3 19304 19302 19016 3 19015 19303 19017 3 19305 19017 19303 3 19016 19018 19304 3 19306 19304 19018 3 19017 19305 19019 3 19307 19019 19305 3 19018 19020 19306 3 19308 19306 19020 3 19019 19307 19021 3 19309 19021 19307 3 19020 19022 19308 3 19310 19308 19022 3 19021 19309 19023 3 19311 19023 19309 3 19022 19024 19310 3 19312 19310 19024 3 19023 19311 19025 3 19313 19025 19311 3 19024 19026 19312 3 19314 19312 19026 3 19025 19313 19027 3 19315 19027 19313 3 19026 19028 19314 3 19316 19314 19028 3 19027 19315 19029 3 19317 19029 19315 3 19028 19030 19316 3 19318 19316 19030 3 19029 19317 19031 3 19319 19031 19317 3 19030 19032 19318 3 19320 19318 19032 3 19031 19319 19033 3 19321 19033 19319 3 19032 19034 19320 3 19322 19320 19034 3 19033 19321 19035 3 19323 19035 19321 3 19034 19036 19322 3 19324 19322 19036 3 19035 19323 19037 3 19325 19037 19323 3 19036 19038 19324 3 19326 19324 19038 3 19037 19325 19039 3 19327 19039 19325 3 19038 19040 19326 3 19328 19326 19040 3 19039 19327 19043 3 19331 19043 19327 3 19040 19041 19328 3 19329 19328 19041 3 19041 19044 19329 3 19332 19329 19044 3 19042 19043 19330 3 19331 19330 19043 3 19042 19330 19047 3 19335 19047 19330 3 19044 19045 19332 3 19333 19332 19045 3 19045 19048 19333 3 19336 19333 19048 3 19046 19047 19334 3 19335 19334 19047 3 19046 19334 19116 3 19404 19116 19334 3 19048 19049 19336 3 19337 19336 19049 3 19049 19050 19337 3 19338 19337 19050 3 19050 19051 19338 3 19339 19338 19051 3 19051 19052 19339 3 19340 19339 19052 3 19052 19053 19340 3 19341 19340 19053 3 19053 19054 19342 3 19053 19342 19341 3 19054 19055 19343 3 19054 19343 19342 3 19055 19056 19344 3 19055 19344 19343 3 19056 19057 19345 3 19056 19345 19344 3 19057 19058 19346 3 19057 19346 19345 3 19058 19059 19347 3 19058 19347 19346 3 19059 19060 19348 3 19059 19348 19347 3 19060 19061 19349 3 19060 19349 19348 3 19061 19062 19350 3 19061 19350 19349 3 19062 19063 19351 3 19062 19351 19350 3 19063 19064 19352 3 19063 19352 19351 3 19064 19065 19353 3 19064 19353 19352 3 19065 19066 19354 3 19065 19354 19353 3 19066 19067 19355 3 19066 19355 19354 3 19067 19068 19356 3 19067 19356 19355 3 19068 19069 19357 3 19068 19357 19356 3 19069 19070 19358 3 19069 19358 19357 3 19070 19071 19359 3 19070 19359 19358 3 19071 19072 19360 3 19071 19360 19359 3 19072 19073 19361 3 19072 19361 19360 3 19073 19074 19362 3 19073 19362 19361 3 19074 19075 19363 3 19074 19363 19362 3 19075 19076 19364 3 19075 19364 19363 3 19076 19077 19365 3 19076 19365 19364 3 19077 19078 19366 3 19077 19366 19365 3 19078 19079 19367 3 19078 19367 19366 3 19079 19080 19368 3 19079 19368 19367 3 19080 19081 19369 3 19080 19369 19368 3 19081 19082 19370 3 19081 19370 19369 3 19082 19083 19371 3 19082 19371 19370 3 19083 19084 19372 3 19083 19372 19371 3 19084 19085 19373 3 19084 19373 19372 3 19085 19086 19374 3 19085 19374 19373 3 19086 19087 19375 3 19086 19375 19374 3 19087 19088 19376 3 19087 19376 19375 3 19088 19089 19377 3 19088 19377 19376 3 19089 19090 19378 3 19089 19378 19377 3 19090 19091 19379 3 19090 19379 19378 3 19091 19092 19380 3 19091 19380 19379 3 19092 19093 19381 3 19092 19381 19380 3 19093 19094 19382 3 19093 19382 19381 3 19094 19095 19383 3 19094 19383 19382 3 19095 19096 19384 3 19095 19384 19383 3 19096 19097 19385 3 19096 19385 19384 3 19097 19098 19386 3 19097 19386 19385 3 19098 19099 19387 3 19098 19387 19386 3 19099 19100 19388 3 19099 19388 19387 3 19100 19101 19389 3 19100 19389 19388 3 19101 19102 19390 3 19101 19390 19389 3 19102 19103 19391 3 19102 19391 19390 3 19103 19104 19392 3 19103 19392 19391 3 19104 19105 19393 3 19104 19393 19392 3 19105 19106 19394 3 19105 19394 19393 3 19106 19107 19395 3 19106 19395 19394 3 19107 19108 19396 3 19107 19396 19395 3 19108 19109 19397 3 19108 19397 19396 3 19109 19110 19398 3 19109 19398 19397 3 19110 19111 19399 3 19110 19399 19398 3 19111 19112 19400 3 19111 19400 19399 3 19112 19113 19401 3 19112 19401 19400 3 19113 19114 19402 3 19113 19402 19401 3 19114 19115 19403 3 19114 19403 19402 3 19115 19116 19404 3 19115 19404 19403 3 19117 19405 19406 3 19117 19406 19118 3 19117 19187 19405 3 19475 19405 19187 3 19118 19406 19407 3 19118 19407 19119 3 19119 19407 19408 3 19119 19408 19120 3 19120 19408 19409 3 19120 19409 19121 3 19121 19409 19410 3 19121 19410 19122 3 19122 19410 19411 3 19122 19411 19123 3 19123 19411 19412 3 19123 19412 19124 3 19124 19412 19413 3 19124 19413 19125 3 19125 19413 19414 3 19125 19414 19126 3 19126 19414 19415 3 19126 19415 19127 3 19127 19415 19416 3 19127 19416 19128 3 19128 19416 19417 3 19128 19417 19129 3 19129 19417 19418 3 19129 19418 19130 3 19130 19418 19419 3 19130 19419 19131 3 19131 19419 19420 3 19131 19420 19132 3 19132 19420 19421 3 19132 19421 19133 3 19133 19421 19422 3 19133 19422 19134 3 19134 19422 19423 3 19134 19423 19135 3 19135 19423 19424 3 19135 19424 19136 3 19136 19424 19425 3 19136 19425 19137 3 19137 19425 19426 3 19137 19426 19138 3 19138 19426 19427 3 19138 19427 19139 3 19139 19427 19428 3 19139 19428 19140 3 19140 19428 19429 3 19140 19429 19141 3 19141 19429 19430 3 19141 19430 19142 3 19142 19430 19431 3 19142 19431 19143 3 19143 19431 19432 3 19143 19432 19144 3 19144 19432 19145 3 19433 19145 19432 3 19145 19433 19146 3 19434 19146 19433 3 19146 19434 19147 3 19435 19147 19434 3 19147 19435 19148 3 19436 19148 19435 3 19148 19436 19149 3 19437 19149 19436 3 19149 19437 19150 3 19438 19150 19437 3 19150 19438 19151 3 19439 19151 19438 3 19151 19439 19152 3 19440 19152 19439 3 19152 19440 19153 3 19441 19153 19440 3 19153 19441 19154 3 19442 19154 19441 3 19154 19442 19155 3 19443 19155 19442 3 19155 19443 19156 3 19444 19156 19443 3 19156 19444 19157 3 19445 19157 19444 3 19157 19445 19158 3 19446 19158 19445 3 19158 19446 19159 3 19447 19159 19446 3 19159 19447 19160 3 19448 19160 19447 3 19160 19448 19161 3 19449 19161 19448 3 19161 19449 19162 3 19450 19162 19449 3 19162 19450 19163 3 19451 19163 19450 3 19163 19451 19164 3 19452 19164 19451 3 19164 19452 19165 3 19453 19165 19452 3 19165 19453 19166 3 19454 19166 19453 3 19166 19454 19167 3 19455 19167 19454 3 19167 19455 19168 3 19456 19168 19455 3 19168 19456 19169 3 19457 19169 19456 3 19169 19457 19170 3 19458 19170 19457 3 19170 19458 19171 3 19459 19171 19458 3 19171 19459 19172 3 19460 19172 19459 3 19172 19460 19173 3 19461 19173 19460 3 19173 19461 19174 3 19462 19174 19461 3 19174 19462 19175 3 19463 19175 19462 3 19175 19463 19176 3 19464 19176 19463 3 19176 19464 19177 3 19465 19177 19464 3 19177 19465 19178 3 19466 19178 19465 3 19178 19466 19179 3 19467 19179 19466 3 19179 19467 19180 3 19468 19180 19467 3 19180 19468 19181 3 19469 19181 19468 3 19181 19469 19182 3 19470 19182 19469 3 19182 19470 19183 3 19471 19183 19470 3 19183 19471 19184 3 19472 19184 19471 3 19184 19472 19185 3 19473 19185 19472 3 19185 19473 19188 3 19476 19188 19473 3 19186 19474 19187 3 19475 19187 19474 3 19186 19191 19474 3 19479 19474 19191 3 19188 19476 19189 3 19477 19189 19476 3 19189 19477 19192 3 19480 19192 19477 3 19190 19478 19191 3 19479 19191 19478 3 19190 19194 19478 3 19482 19478 19194 3 19192 19480 19193 3 19481 19193 19480 3 19193 19481 19195 3 19483 19195 19481 3 19194 19196 19482 3 19484 19482 19196 3 19195 19483 19197 3 19485 19197 19483 3 19196 19198 19484 3 19486 19484 19198 3 19197 19485 19199 3 19487 19199 19485 3 19198 19200 19486 3 19488 19486 19200 3 19199 19487 19201 3 19489 19201 19487 3 19200 19202 19488 3 19490 19488 19202 3 19201 19489 19203 3 19491 19203 19489 3 19202 19204 19490 3 19492 19490 19204 3 19203 19491 19205 3 19493 19205 19491 3 19204 19206 19492 3 19494 19492 19206 3 19205 19493 19207 3 19495 19207 19493 3 19206 19208 19494 3 19496 19494 19208 3 19207 19495 19209 3 19497 19209 19495 3 19208 19210 19496 3 19498 19496 19210 3 19209 19497 19211 3 19499 19211 19497 3 19210 19212 19498 3 19500 19498 19212 3 19211 19499 19213 3 19501 19213 19499 3 19212 19214 19500 3 19502 19500 19214 3 19213 19501 19215 3 19503 19215 19501 3 19214 19216 19502 3 19504 19502 19216 3 19215 19503 19217 3 19505 19217 19503 3 19216 19218 19504 3 19506 19504 19218 3 19217 19505 19219 3 19507 19219 19505 3 19218 19220 19506 3 19508 19506 19220 3 19219 19507 19221 3 19509 19221 19507 3 19220 19222 19508 3 19510 19508 19222 3 19221 19509 19223 3 19511 19223 19509 3 19222 19224 19510 3 19512 19510 19224 3 19223 19511 19225 3 19513 19225 19511 3 19224 19226 19514 3 19224 19514 19512 3 19225 19513 19227 3 19515 19227 19513 3 19226 19228 19516 3 19226 19516 19514 3 19227 19515 19229 3 19517 19229 19515 3 19228 19230 19518 3 19228 19518 19516 3 19229 19517 19519 3 19229 19519 19231 3 19230 19232 19520 3 19230 19520 19518 3 19231 19519 19521 3 19231 19521 19233 3 19232 19234 19522 3 19232 19522 19520 3 19233 19521 19523 3 19233 19523 19235 3 19234 19236 19524 3 19234 19524 19522 3 19235 19523 19525 3 19235 19525 19237 3 19236 19238 19526 3 19236 19526 19524 3 19237 19525 19527 3 19237 19527 19239 3 19238 19240 19528 3 19238 19528 19526 3 19239 19527 19529 3 19239 19529 19241 3 19240 19242 19530 3 19240 19530 19528 3 19241 19529 19531 3 19241 19531 19243 3 19242 19244 19532 3 19242 19532 19530 3 19243 19531 19533 3 19243 19533 19245 3 19244 19246 19534 3 19244 19534 19532 3 19245 19533 19535 3 19245 19535 19247 3 19246 19248 19536 3 19246 19536 19534 3 19247 19535 19537 3 19247 19537 19249 3 19248 19250 19538 3 19248 19538 19536 3 19249 19537 19539 3 19249 19539 19251 3 19250 19252 19540 3 19250 19540 19538 3 19251 19539 19541 3 19251 19541 19253 3 19252 19254 19542 3 19252 19542 19540 3 19253 19541 19543 3 19253 19543 19255 3 19254 19256 19544 3 19254 19544 19542 3 19255 19543 19545 3 19255 19545 19257 3 19256 19258 19546 3 19256 19546 19544 3 19257 19545 19547 3 19257 19547 19259 3 19258 19260 19548 3 19258 19548 19546 3 19259 19547 19549 3 19259 19549 19261 3 19260 19262 19550 3 19260 19550 19548 3 19261 19549 19551 3 19261 19551 19263 3 19262 19264 19552 3 19262 19552 19550 3 19263 19551 19553 3 19263 19553 19265 3 19264 19266 19554 3 19264 19554 19552 3 19265 19553 19555 3 19265 19555 19267 3 19266 19268 19556 3 19266 19556 19554 3 19267 19555 19557 3 19267 19557 19269 3 19268 19270 19558 3 19268 19558 19556 3 19269 19557 19559 3 19269 19559 19271 3 19270 19272 19560 3 19270 19560 19558 3 19271 19559 19561 3 19271 19561 19273 3 19272 19274 19562 3 19272 19562 19560 3 19273 19561 19563 3 19273 19563 19275 3 19274 19276 19564 3 19274 19564 19562 3 19275 19563 19565 3 19275 19565 19277 3 19276 19278 19566 3 19276 19566 19564 3 19277 19565 19567 3 19277 19567 19279 3 19278 19280 19568 3 19278 19568 19566 3 19279 19567 19569 3 19279 19569 19281 3 19280 19282 19570 3 19280 19570 19568 3 19281 19569 19571 3 19281 19571 19283 3 19282 19284 19572 3 19282 19572 19570 3 19283 19571 19573 3 19283 19573 19285 3 19284 19286 19574 3 19284 19574 19572 3 19285 19573 19575 3 19285 19575 19287 3 19286 19288 19576 3 19286 19576 19574 3 19287 19575 19577 3 19287 19577 19289 3 19288 19290 19578 3 19288 19578 19576 3 19289 19577 19579 3 19289 19579 19291 3 19290 19292 19580 3 19290 19580 19578 3 19291 19579 19581 3 19291 19581 19293 3 19292 19294 19582 3 19292 19582 19580 3 19293 19581 19583 3 19293 19583 19295 3 19294 19296 19584 3 19294 19584 19582 3 19295 19583 19585 3 19295 19585 19297 3 19296 19298 19586 3 19296 19586 19584 3 19297 19585 19587 3 19297 19587 19299 3 19298 19300 19588 3 19298 19588 19586 3 19299 19587 19589 3 19299 19589 19301 3 19300 19302 19590 3 19300 19590 19588 3 19301 19589 19591 3 19301 19591 19303 3 19302 19304 19592 3 19302 19592 19590 3 19303 19591 19593 3 19303 19593 19305 3 19304 19306 19594 3 19304 19594 19592 3 19305 19593 19595 3 19305 19595 19307 3 19306 19308 19596 3 19306 19596 19594 3 19307 19595 19597 3 19307 19597 19309 3 19308 19310 19596 3 19598 19596 19310 3 19309 19597 19599 3 19309 19599 19311 3 19310 19312 19598 3 19600 19598 19312 3 19311 19599 19601 3 19311 19601 19313 3 19312 19314 19600 3 19602 19600 19314 3 19313 19601 19603 3 19313 19603 19315 3 19314 19316 19602 3 19604 19602 19316 3 19315 19603 19317 3 19605 19317 19603 3 19316 19318 19604 3 19606 19604 19318 3 19317 19605 19319 3 19607 19319 19605 3 19318 19320 19606 3 19608 19606 19320 3 19319 19607 19321 3 19609 19321 19607 3 19320 19322 19608 3 19610 19608 19322 3 19321 19609 19323 3 19611 19323 19609 3 19322 19324 19610 3 19612 19610 19324 3 19323 19611 19325 3 19613 19325 19611 3 19324 19326 19612 3 19614 19612 19326 3 19325 19613 19327 3 19615 19327 19613 3 19326 19328 19614 3 19616 19614 19328 3 19327 19615 19331 3 19619 19331 19615 3 19328 19329 19616 3 19617 19616 19329 3 19329 19332 19617 3 19620 19617 19332 3 19330 19331 19618 3 19619 19618 19331 3 19330 19618 19335 3 19623 19335 19618 3 19332 19333 19620 3 19621 19620 19333 3 19333 19336 19621 3 19624 19621 19336 3 19334 19335 19622 3 19623 19622 19335 3 19334 19622 19404 3 19692 19404 19622 3 19336 19337 19624 3 19625 19624 19337 3 19337 19338 19625 3 19626 19625 19338 3 19338 19339 19626 3 19627 19626 19339 3 19339 19340 19627 3 19628 19627 19340 3 19340 19341 19628 3 19629 19628 19341 3 19341 19342 19629 3 19630 19629 19342 3 19342 19343 19630 3 19631 19630 19343 3 19343 19344 19631 3 19632 19631 19344 3 19344 19345 19632 3 19633 19632 19345 3 19345 19346 19633 3 19634 19633 19346 3 19346 19347 19634 3 19635 19634 19347 3 19347 19348 19635 3 19636 19635 19348 3 19348 19349 19636 3 19637 19636 19349 3 19349 19350 19637 3 19638 19637 19350 3 19350 19351 19638 3 19639 19638 19351 3 19351 19352 19639 3 19640 19639 19352 3 19352 19353 19640 3 19641 19640 19353 3 19353 19354 19641 3 19642 19641 19354 3 19354 19355 19642 3 19643 19642 19355 3 19355 19356 19643 3 19644 19643 19356 3 19356 19357 19644 3 19645 19644 19357 3 19357 19358 19645 3 19646 19645 19358 3 19358 19359 19646 3 19647 19646 19359 3 19359 19360 19647 3 19648 19647 19360 3 19360 19361 19648 3 19649 19648 19361 3 19361 19362 19649 3 19650 19649 19362 3 19362 19363 19650 3 19651 19650 19363 3 19363 19364 19651 3 19652 19651 19364 3 19364 19365 19652 3 19653 19652 19365 3 19365 19366 19653 3 19654 19653 19366 3 19366 19367 19654 3 19655 19654 19367 3 19367 19368 19655 3 19656 19655 19368 3 19368 19369 19656 3 19657 19656 19369 3 19369 19370 19657 3 19658 19657 19370 3 19370 19371 19658 3 19659 19658 19371 3 19371 19372 19659 3 19660 19659 19372 3 19372 19373 19660 3 19661 19660 19373 3 19373 19374 19661 3 19662 19661 19374 3 19374 19375 19662 3 19663 19662 19375 3 19375 19376 19663 3 19664 19663 19376 3 19376 19377 19664 3 19665 19664 19377 3 19377 19378 19665 3 19666 19665 19378 3 19378 19379 19666 3 19667 19666 19379 3 19379 19380 19667 3 19668 19667 19380 3 19380 19381 19668 3 19669 19668 19381 3 19381 19382 19669 3 19670 19669 19382 3 19382 19383 19670 3 19671 19670 19383 3 19383 19384 19671 3 19672 19671 19384 3 19384 19385 19672 3 19673 19672 19385 3 19385 19386 19673 3 19674 19673 19386 3 19386 19387 19674 3 19675 19674 19387 3 19387 19388 19675 3 19676 19675 19388 3 19388 19389 19676 3 19677 19676 19389 3 19389 19390 19677 3 19678 19677 19390 3 19390 19391 19678 3 19679 19678 19391 3 19391 19392 19679 3 19680 19679 19392 3 19392 19393 19680 3 19681 19680 19393 3 19393 19394 19681 3 19682 19681 19394 3 19394 19395 19683 3 19394 19683 19682 3 19395 19396 19684 3 19395 19684 19683 3 19396 19397 19685 3 19396 19685 19684 3 19397 19398 19686 3 19397 19686 19685 3 19398 19399 19687 3 19398 19687 19686 3 19399 19400 19688 3 19399 19688 19687 3 19400 19401 19689 3 19400 19689 19688 3 19401 19402 19690 3 19401 19690 19689 3 19402 19403 19691 3 19402 19691 19690 3 19403 19404 19692 3 19403 19692 19691 3 19405 19693 19694 3 19405 19694 19406 3 19405 19475 19763 3 19405 19763 19693 3 19406 19694 19695 3 19406 19695 19407 3 19407 19695 19696 3 19407 19696 19408 3 19408 19696 19697 3 19408 19697 19409 3 19409 19697 19698 3 19409 19698 19410 3 19410 19698 19699 3 19410 19699 19411 3 19411 19699 19700 3 19411 19700 19412 3 19412 19700 19701 3 19412 19701 19413 3 19413 19701 19702 3 19413 19702 19414 3 19414 19702 19703 3 19414 19703 19415 3 19415 19703 19704 3 19415 19704 19416 3 19416 19704 19705 3 19416 19705 19417 3 19417 19705 19706 3 19417 19706 19418 3 19418 19706 19707 3 19418 19707 19419 3 19419 19707 19708 3 19419 19708 19420 3 19420 19708 19709 3 19420 19709 19421 3 19421 19709 19710 3 19421 19710 19422 3 19422 19710 19711 3 19422 19711 19423 3 19423 19711 19712 3 19423 19712 19424 3 19424 19712 19713 3 19424 19713 19425 3 19425 19713 19714 3 19425 19714 19426 3 19426 19714 19715 3 19426 19715 19427 3 19427 19715 19716 3 19427 19716 19428 3 19428 19716 19717 3 19428 19717 19429 3 19429 19717 19718 3 19429 19718 19430 3 19430 19718 19719 3 19430 19719 19431 3 19431 19719 19720 3 19431 19720 19432 3 19432 19720 19721 3 19432 19721 19433 3 19433 19721 19722 3 19433 19722 19434 3 19434 19722 19723 3 19434 19723 19435 3 19435 19723 19724 3 19435 19724 19436 3 19436 19724 19725 3 19436 19725 19437 3 19437 19725 19726 3 19437 19726 19438 3 19438 19726 19727 3 19438 19727 19439 3 19439 19727 19728 3 19439 19728 19440 3 19440 19728 19729 3 19440 19729 19441 3 19441 19729 19730 3 19441 19730 19442 3 19442 19730 19731 3 19442 19731 19443 3 19443 19731 19732 3 19443 19732 19444 3 19444 19732 19733 3 19444 19733 19445 3 19445 19733 19734 3 19445 19734 19446 3 19446 19734 19735 3 19446 19735 19447 3 19447 19735 19736 3 19447 19736 19448 3 19448 19736 19737 3 19448 19737 19449 3 19449 19737 19738 3 19449 19738 19450 3 19450 19738 19739 3 19450 19739 19451 3 19451 19739 19740 3 19451 19740 19452 3 19452 19740 19741 3 19452 19741 19453 3 19453 19741 19742 3 19453 19742 19454 3 19454 19742 19743 3 19454 19743 19455 3 19455 19743 19744 3 19455 19744 19456 3 19456 19744 19745 3 19456 19745 19457 3 19457 19745 19746 3 19457 19746 19458 3 19458 19746 19747 3 19458 19747 19459 3 19459 19747 19748 3 19459 19748 19460 3 19460 19748 19749 3 19460 19749 19461 3 19461 19749 19750 3 19461 19750 19462 3 19462 19750 19751 3 19462 19751 19463 3 19463 19751 19752 3 19463 19752 19464 3 19464 19752 19753 3 19464 19753 19465 3 19465 19753 19754 3 19465 19754 19466 3 19466 19754 19755 3 19466 19755 19467 3 19467 19755 19756 3 19467 19756 19468 3 19468 19756 19757 3 19468 19757 19469 3 19469 19757 19758 3 19469 19758 19470 3 19470 19758 19759 3 19470 19759 19471 3 19471 19759 19760 3 19471 19760 19472 3 19472 19760 19761 3 19472 19761 19473 3 19473 19761 19764 3 19473 19764 19476 3 19474 19762 19763 3 19474 19763 19475 3 19474 19479 19767 3 19474 19767 19762 3 19476 19764 19765 3 19476 19765 19477 3 19477 19765 19768 3 19477 19768 19480 3 19478 19766 19767 3 19478 19767 19479 3 19478 19482 19766 3 19770 19766 19482 3 19480 19768 19769 3 19480 19769 19481 3 19481 19769 19771 3 19481 19771 19483 3 19482 19484 19770 3 19772 19770 19484 3 19483 19771 19773 3 19483 19773 19485 3 19484 19486 19772 3 19774 19772 19486 3 19485 19773 19775 3 19485 19775 19487 3 19486 19488 19774 3 19776 19774 19488 3 19487 19775 19489 3 19777 19489 19775 3 19488 19490 19776 3 19778 19776 19490 3 19489 19777 19491 3 19779 19491 19777 3 19490 19492 19778 3 19780 19778 19492 3 19491 19779 19493 3 19781 19493 19779 3 19492 19494 19780 3 19782 19780 19494 3 19493 19781 19495 3 19783 19495 19781 3 19494 19496 19782 3 19784 19782 19496 3 19495 19783 19497 3 19785 19497 19783 3 19496 19498 19784 3 19786 19784 19498 3 19497 19785 19499 3 19787 19499 19785 3 19498 19500 19786 3 19788 19786 19500 3 19499 19787 19501 3 19789 19501 19787 3 19500 19502 19788 3 19790 19788 19502 3 19501 19789 19503 3 19791 19503 19789 3 19502 19504 19790 3 19792 19790 19504 3 19503 19791 19505 3 19793 19505 19791 3 19504 19506 19792 3 19794 19792 19506 3 19505 19793 19507 3 19795 19507 19793 3 19506 19508 19794 3 19796 19794 19508 3 19507 19795 19509 3 19797 19509 19795 3 19508 19510 19796 3 19798 19796 19510 3 19509 19797 19511 3 19799 19511 19797 3 19510 19512 19798 3 19800 19798 19512 3 19511 19799 19513 3 19801 19513 19799 3 19512 19514 19800 3 19802 19800 19514 3 19513 19801 19515 3 19803 19515 19801 3 19514 19516 19802 3 19804 19802 19516 3 19515 19803 19517 3 19805 19517 19803 3 19516 19518 19804 3 19806 19804 19518 3 19517 19805 19519 3 19807 19519 19805 3 19518 19520 19806 3 19808 19806 19520 3 19519 19807 19521 3 19809 19521 19807 3 19520 19522 19808 3 19810 19808 19522 3 19521 19809 19523 3 19811 19523 19809 3 19522 19524 19810 3 19812 19810 19524 3 19523 19811 19525 3 19813 19525 19811 3 19524 19526 19812 3 19814 19812 19526 3 19525 19813 19527 3 19815 19527 19813 3 19526 19528 19814 3 19816 19814 19528 3 19527 19815 19529 3 19817 19529 19815 3 19528 19530 19816 3 19818 19816 19530 3 19529 19817 19531 3 19819 19531 19817 3 19530 19532 19818 3 19820 19818 19532 3 19531 19819 19533 3 19821 19533 19819 3 19532 19534 19820 3 19822 19820 19534 3 19533 19821 19535 3 19823 19535 19821 3 19534 19536 19822 3 19824 19822 19536 3 19535 19823 19537 3 19825 19537 19823 3 19536 19538 19824 3 19826 19824 19538 3 19537 19825 19539 3 19827 19539 19825 3 19538 19540 19826 3 19828 19826 19540 3 19539 19827 19541 3 19829 19541 19827 3 19540 19542 19828 3 19830 19828 19542 3 19541 19829 19543 3 19831 19543 19829 3 19542 19544 19830 3 19832 19830 19544 3 19543 19831 19545 3 19833 19545 19831 3 19544 19546 19832 3 19834 19832 19546 3 19545 19833 19547 3 19835 19547 19833 3 19546 19548 19834 3 19836 19834 19548 3 19547 19835 19549 3 19837 19549 19835 3 19548 19550 19836 3 19838 19836 19550 3 19549 19837 19551 3 19839 19551 19837 3 19550 19552 19838 3 19840 19838 19552 3 19551 19839 19553 3 19841 19553 19839 3 19552 19554 19840 3 19842 19840 19554 3 19553 19841 19555 3 19843 19555 19841 3 19554 19556 19842 3 19844 19842 19556 3 19555 19843 19557 3 19845 19557 19843 3 19556 19558 19844 3 19846 19844 19558 3 19557 19845 19559 3 19847 19559 19845 3 19558 19560 19846 3 19848 19846 19560 3 19559 19847 19561 3 19849 19561 19847 3 19560 19562 19848 3 19850 19848 19562 3 19561 19849 19563 3 19851 19563 19849 3 19562 19564 19850 3 19852 19850 19564 3 19563 19851 19565 3 19853 19565 19851 3 19564 19566 19852 3 19854 19852 19566 3 19565 19853 19567 3 19855 19567 19853 3 19566 19568 19856 3 19566 19856 19854 3 19567 19855 19569 3 19857 19569 19855 3 19568 19570 19858 3 19568 19858 19856 3 19569 19857 19571 3 19859 19571 19857 3 19570 19572 19860 3 19570 19860 19858 3 19571 19859 19573 3 19861 19573 19859 3 19572 19574 19862 3 19572 19862 19860 3 19573 19861 19575 3 19863 19575 19861 3 19574 19576 19864 3 19574 19864 19862 3 19575 19863 19865 3 19575 19865 19577 3 19576 19578 19866 3 19576 19866 19864 3 19577 19865 19867 3 19577 19867 19579 3 19578 19580 19868 3 19578 19868 19866 3 19579 19867 19869 3 19579 19869 19581 3 19580 19582 19870 3 19580 19870 19868 3 19581 19869 19871 3 19581 19871 19583 3 19582 19584 19872 3 19582 19872 19870 3 19583 19871 19873 3 19583 19873 19585 3 19584 19586 19874 3 19584 19874 19872 3 19585 19873 19875 3 19585 19875 19587 3 19586 19588 19876 3 19586 19876 19874 3 19587 19875 19877 3 19587 19877 19589 3 19588 19590 19878 3 19588 19878 19876 3 19589 19877 19879 3 19589 19879 19591 3 19590 19592 19880 3 19590 19880 19878 3 19591 19879 19881 3 19591 19881 19593 3 19592 19594 19882 3 19592 19882 19880 3 19593 19881 19883 3 19593 19883 19595 3 19594 19596 19884 3 19594 19884 19882 3 19595 19883 19885 3 19595 19885 19597 3 19596 19598 19886 3 19596 19886 19884 3 19597 19885 19887 3 19597 19887 19599 3 19598 19600 19888 3 19598 19888 19886 3 19599 19887 19889 3 19599 19889 19601 3 19600 19602 19890 3 19600 19890 19888 3 19601 19889 19891 3 19601 19891 19603 3 19602 19604 19892 3 19602 19892 19890 3 19603 19891 19893 3 19603 19893 19605 3 19604 19606 19894 3 19604 19894 19892 3 19605 19893 19895 3 19605 19895 19607 3 19606 19608 19896 3 19606 19896 19894 3 19607 19895 19897 3 19607 19897 19609 3 19608 19610 19898 3 19608 19898 19896 3 19609 19897 19899 3 19609 19899 19611 3 19610 19612 19900 3 19610 19900 19898 3 19611 19899 19901 3 19611 19901 19613 3 19612 19614 19902 3 19612 19902 19900 3 19613 19901 19903 3 19613 19903 19615 3 19614 19616 19904 3 19614 19904 19902 3 19615 19903 19907 3 19615 19907 19619 3 19616 19617 19905 3 19616 19905 19904 3 19617 19620 19908 3 19617 19908 19905 3 19618 19619 19907 3 19618 19907 19906 3 19618 19906 19911 3 19618 19911 19623 3 19620 19621 19909 3 19620 19909 19908 3 19621 19624 19912 3 19621 19912 19909 3 19622 19623 19911 3 19622 19911 19910 3 19622 19910 19980 3 19622 19980 19692 3 19624 19625 19913 3 19624 19913 19912 3 19625 19626 19914 3 19625 19914 19913 3 19626 19627 19915 3 19626 19915 19914 3 19627 19628 19916 3 19627 19916 19915 3 19628 19629 19917 3 19628 19917 19916 3 19629 19630 19918 3 19629 19918 19917 3 19630 19631 19919 3 19630 19919 19918 3 19631 19632 19920 3 19631 19920 19919 3 19632 19633 19921 3 19632 19921 19920 3 19633 19634 19922 3 19633 19922 19921 3 19634 19635 19923 3 19634 19923 19922 3 19635 19636 19924 3 19635 19924 19923 3 19636 19637 19925 3 19636 19925 19924 3 19637 19638 19926 3 19637 19926 19925 3 19638 19639 19927 3 19638 19927 19926 3 19639 19640 19928 3 19639 19928 19927 3 19640 19641 19929 3 19640 19929 19928 3 19641 19642 19930 3 19641 19930 19929 3 19642 19643 19931 3 19642 19931 19930 3 19643 19644 19932 3 19643 19932 19931 3 19644 19645 19933 3 19644 19933 19932 3 19645 19646 19934 3 19645 19934 19933 3 19646 19647 19935 3 19646 19935 19934 3 19647 19648 19936 3 19647 19936 19935 3 19648 19649 19937 3 19648 19937 19936 3 19649 19650 19938 3 19649 19938 19937 3 19650 19651 19939 3 19650 19939 19938 3 19651 19652 19940 3 19651 19940 19939 3 19652 19653 19940 3 19941 19940 19653 3 19653 19654 19941 3 19942 19941 19654 3 19654 19655 19942 3 19943 19942 19655 3 19655 19656 19943 3 19944 19943 19656 3 19656 19657 19944 3 19945 19944 19657 3 19657 19658 19945 3 19946 19945 19658 3 19658 19659 19946 3 19947 19946 19659 3 19659 19660 19947 3 19948 19947 19660 3 19660 19661 19948 3 19949 19948 19661 3 19661 19662 19949 3 19950 19949 19662 3 19662 19663 19950 3 19951 19950 19663 3 19663 19664 19951 3 19952 19951 19664 3 19664 19665 19952 3 19953 19952 19665 3 19665 19666 19953 3 19954 19953 19666 3 19666 19667 19954 3 19955 19954 19667 3 19667 19668 19955 3 19956 19955 19668 3 19668 19669 19956 3 19957 19956 19669 3 19669 19670 19957 3 19958 19957 19670 3 19670 19671 19958 3 19959 19958 19671 3 19671 19672 19959 3 19960 19959 19672 3 19672 19673 19960 3 19961 19960 19673 3 19673 19674 19961 3 19962 19961 19674 3 19674 19675 19962 3 19963 19962 19675 3 19675 19676 19963 3 19964 19963 19676 3 19676 19677 19964 3 19965 19964 19677 3 19677 19678 19965 3 19966 19965 19678 3 19678 19679 19966 3 19967 19966 19679 3 19679 19680 19967 3 19968 19967 19680 3 19680 19681 19968 3 19969 19968 19681 3 19681 19682 19969 3 19970 19969 19682 3 19682 19683 19970 3 19971 19970 19683 3 19683 19684 19971 3 19972 19971 19684 3 19684 19685 19972 3 19973 19972 19685 3 19685 19686 19973 3 19974 19973 19686 3 19686 19687 19974 3 19975 19974 19687 3 19687 19688 19975 3 19976 19975 19688 3 19688 19689 19976 3 19977 19976 19689 3 19689 19690 19977 3 19978 19977 19690 3 19690 19691 19978 3 19979 19978 19691 3 19691 19692 19979 3 19980 19979 19692 3 19693 19981 19694 3 19982 19694 19981 3 19693 19763 19981 3 20051 19981 19763 3 19694 19982 19695 3 19983 19695 19982 3 19695 19983 19696 3 19984 19696 19983 3 19696 19984 19697 3 19985 19697 19984 3 19697 19985 19698 3 19986 19698 19985 3 19698 19986 19699 3 19987 19699 19986 3 19699 19987 19700 3 19988 19700 19987 3 19700 19988 19701 3 19989 19701 19988 3 19701 19989 19702 3 19990 19702 19989 3 19702 19990 19703 3 19991 19703 19990 3 19703 19991 19704 3 19992 19704 19991 3 19704 19992 19705 3 19993 19705 19992 3 19705 19993 19706 3 19994 19706 19993 3 19706 19994 19707 3 19995 19707 19994 3 19707 19995 19708 3 19996 19708 19995 3 19708 19996 19709 3 19997 19709 19996 3 19709 19997 19710 3 19998 19710 19997 3 19710 19998 19711 3 19999 19711 19998 3 19711 19999 19712 3 20000 19712 19999 3 19712 20000 19713 3 20001 19713 20000 3 19713 20001 19714 3 20002 19714 20001 3 19714 20002 19715 3 20003 19715 20002 3 19715 20003 19716 3 20004 19716 20003 3 19716 20004 19717 3 20005 19717 20004 3 19717 20005 19718 3 20006 19718 20005 3 19718 20006 19719 3 20007 19719 20006 3 19719 20007 19720 3 20008 19720 20007 3 19720 20008 19721 3 20009 19721 20008 3 19721 20009 19722 3 20010 19722 20009 3 19722 20010 19723 3 20011 19723 20010 3 19723 20011 19724 3 20012 19724 20011 3 19724 20012 19725 3 20013 19725 20012 3 19725 20013 19726 3 20014 19726 20013 3 19726 20014 19727 3 20015 19727 20014 3 19727 20015 19728 3 20016 19728 20015 3 19728 20016 19729 3 20017 19729 20016 3 19729 20017 19730 3 20018 19730 20017 3 19730 20018 19731 3 20019 19731 20018 3 19731 20019 19732 3 20020 19732 20019 3 19732 20020 19733 3 20021 19733 20020 3 19733 20021 19734 3 20022 19734 20021 3 19734 20022 19735 3 20023 19735 20022 3 19735 20023 19736 3 20024 19736 20023 3 19736 20024 19737 3 20025 19737 20024 3 19737 20025 19738 3 20026 19738 20025 3 19738 20026 19739 3 20027 19739 20026 3 19739 20027 19740 3 20028 19740 20027 3 19740 20028 19741 3 20029 19741 20028 3 19741 20029 19742 3 20030 19742 20029 3 19742 20030 19743 3 20031 19743 20030 3 19743 20031 19744 3 20032 19744 20031 3 19744 20032 19745 3 20033 19745 20032 3 19745 20033 19746 3 20034 19746 20033 3 19746 20034 19747 3 20035 19747 20034 3 19747 20035 20036 3 19747 20036 19748 3 19748 20036 20037 3 19748 20037 19749 3 19749 20037 20038 3 19749 20038 19750 3 19750 20038 20039 3 19750 20039 19751 3 19751 20039 20040 3 19751 20040 19752 3 19752 20040 20041 3 19752 20041 19753 3 19753 20041 20042 3 19753 20042 19754 3 19754 20042 20043 3 19754 20043 19755 3 19755 20043 20044 3 19755 20044 19756 3 19756 20044 20045 3 19756 20045 19757 3 19757 20045 20046 3 19757 20046 19758 3 19758 20046 20047 3 19758 20047 19759 3 19759 20047 20048 3 19759 20048 19760 3 19760 20048 20049 3 19760 20049 19761 3 19761 20049 20052 3 19761 20052 19764 3 19762 20050 20051 3 19762 20051 19763 3 19762 19767 20055 3 19762 20055 20050 3 19764 20052 20053 3 19764 20053 19765 3 19765 20053 20056 3 19765 20056 19768 3 19766 20054 20055 3 19766 20055 19767 3 19766 19770 20058 3 19766 20058 20054 3 19768 20056 20057 3 19768 20057 19769 3 19769 20057 20059 3 19769 20059 19771 3 19770 19772 20060 3 19770 20060 20058 3 19771 20059 20061 3 19771 20061 19773 3 19772 19774 20062 3 19772 20062 20060 3 19773 20061 20063 3 19773 20063 19775 3 19774 19776 20064 3 19774 20064 20062 3 19775 20063 20065 3 19775 20065 19777 3 19776 19778 20066 3 19776 20066 20064 3 19777 20065 20067 3 19777 20067 19779 3 19778 19780 20068 3 19778 20068 20066 3 19779 20067 20069 3 19779 20069 19781 3 19780 19782 20070 3 19780 20070 20068 3 19781 20069 20071 3 19781 20071 19783 3 19782 19784 20072 3 19782 20072 20070 3 19783 20071 20073 3 19783 20073 19785 3 19784 19786 20074 3 19784 20074 20072 3 19785 20073 20075 3 19785 20075 19787 3 19786 19788 20076 3 19786 20076 20074 3 19787 20075 20077 3 19787 20077 19789 3 19788 19790 20078 3 19788 20078 20076 3 19789 20077 20079 3 19789 20079 19791 3 19790 19792 20080 3 19790 20080 20078 3 19791 20079 20081 3 19791 20081 19793 3 19792 19794 20082 3 19792 20082 20080 3 19793 20081 20083 3 19793 20083 19795 3 19794 19796 20084 3 19794 20084 20082 3 19795 20083 20085 3 19795 20085 19797 3 19796 19798 20086 3 19796 20086 20084 3 19797 20085 20087 3 19797 20087 19799 3 19798 19800 20088 3 19798 20088 20086 3 19799 20087 20089 3 19799 20089 19801 3 19800 19802 20090 3 19800 20090 20088 3 19801 20089 20091 3 19801 20091 19803 3 19802 19804 20092 3 19802 20092 20090 3 19803 20091 20093 3 19803 20093 19805 3 19804 19806 20094 3 19804 20094 20092 3 19805 20093 20095 3 19805 20095 19807 3 19806 19808 20096 3 19806 20096 20094 3 19807 20095 20097 3 19807 20097 19809 3 19808 19810 20098 3 19808 20098 20096 3 19809 20097 20099 3 19809 20099 19811 3 19810 19812 20100 3 19810 20100 20098 3 19811 20099 20101 3 19811 20101 19813 3 19812 19814 20102 3 19812 20102 20100 3 19813 20101 20103 3 19813 20103 19815 3 19814 19816 20104 3 19814 20104 20102 3 19815 20103 20105 3 19815 20105 19817 3 19816 19818 20106 3 19816 20106 20104 3 19817 20105 20107 3 19817 20107 19819 3 19818 19820 20108 3 19818 20108 20106 3 19819 20107 20109 3 19819 20109 19821 3 19820 19822 20110 3 19820 20110 20108 3 19821 20109 20111 3 19821 20111 19823 3 19822 19824 20112 3 19822 20112 20110 3 19823 20111 20113 3 19823 20113 19825 3 19824 19826 20114 3 19824 20114 20112 3 19825 20113 20115 3 19825 20115 19827 3 19826 19828 20114 3 20116 20114 19828 3 19827 20115 20117 3 19827 20117 19829 3 19828 19830 20116 3 20118 20116 19830 3 19829 20117 20119 3 19829 20119 19831 3 19830 19832 20118 3 20120 20118 19832 3 19831 20119 20121 3 19831 20121 19833 3 19832 19834 20120 3 20122 20120 19834 3 19833 20121 20123 3 19833 20123 19835 3 19834 19836 20122 3 20124 20122 19836 3 19835 20123 19837 3 20125 19837 20123 3 19836 19838 20124 3 20126 20124 19838 3 19837 20125 19839 3 20127 19839 20125 3 19838 19840 20126 3 20128 20126 19840 3 19839 20127 19841 3 20129 19841 20127 3 19840 19842 20128 3 20130 20128 19842 3 19841 20129 19843 3 20131 19843 20129 3 19842 19844 20130 3 20132 20130 19844 3 19843 20131 19845 3 20133 19845 20131 3 19844 19846 20132 3 20134 20132 19846 3 19845 20133 19847 3 20135 19847 20133 3 19846 19848 20134 3 20136 20134 19848 3 19847 20135 19849 3 20137 19849 20135 3 19848 19850 20136 3 20138 20136 19850 3 19849 20137 19851 3 20139 19851 20137 3 19850 19852 20138 3 20140 20138 19852 3 19851 20139 19853 3 20141 19853 20139 3 19852 19854 20140 3 20142 20140 19854 3 19853 20141 19855 3 20143 19855 20141 3 19854 19856 20142 3 20144 20142 19856 3 19855 20143 19857 3 20145 19857 20143 3 19856 19858 20144 3 20146 20144 19858 3 19857 20145 19859 3 20147 19859 20145 3 19858 19860 20146 3 20148 20146 19860 3 19859 20147 19861 3 20149 19861 20147 3 19860 19862 20148 3 20150 20148 19862 3 19861 20149 19863 3 20151 19863 20149 3 19862 19864 20150 3 20152 20150 19864 3 19863 20151 19865 3 20153 19865 20151 3 19864 19866 20152 3 20154 20152 19866 3 19865 20153 19867 3 20155 19867 20153 3 19866 19868 20154 3 20156 20154 19868 3 19867 20155 19869 3 20157 19869 20155 3 19868 19870 20156 3 20158 20156 19870 3 19869 20157 19871 3 20159 19871 20157 3 19870 19872 20158 3 20160 20158 19872 3 19871 20159 19873 3 20161 19873 20159 3 19872 19874 20160 3 20162 20160 19874 3 19873 20161 19875 3 20163 19875 20161 3 19874 19876 20162 3 20164 20162 19876 3 19875 20163 19877 3 20165 19877 20163 3 19876 19878 20164 3 20166 20164 19878 3 19877 20165 19879 3 20167 19879 20165 3 19878 19880 20166 3 20168 20166 19880 3 19879 20167 19881 3 20169 19881 20167 3 19880 19882 20168 3 20170 20168 19882 3 19881 20169 19883 3 20171 19883 20169 3 19882 19884 20170 3 20172 20170 19884 3 19883 20171 19885 3 20173 19885 20171 3 19884 19886 20172 3 20174 20172 19886 3 19885 20173 19887 3 20175 19887 20173 3 19886 19888 20174 3 20176 20174 19888 3 19887 20175 19889 3 20177 19889 20175 3 19888 19890 20176 3 20178 20176 19890 3 19889 20177 19891 3 20179 19891 20177 3 19890 19892 20178 3 20180 20178 19892 3 19891 20179 19893 3 20181 19893 20179 3 19892 19894 20180 3 20182 20180 19894 3 19893 20181 19895 3 20183 19895 20181 3 19894 19896 20182 3 20184 20182 19896 3 19895 20183 19897 3 20185 19897 20183 3 19896 19898 20184 3 20186 20184 19898 3 19897 20185 19899 3 20187 19899 20185 3 19898 19900 20186 3 20188 20186 19900 3 19899 20187 19901 3 20189 19901 20187 3 19900 19902 20188 3 20190 20188 19902 3 19901 20189 19903 3 20191 19903 20189 3 19902 19904 20190 3 20192 20190 19904 3 19903 20191 19907 3 20195 19907 20191 3 19904 19905 20192 3 20193 20192 19905 3 19905 19908 20193 3 20196 20193 19908 3 19906 19907 20194 3 20195 20194 19907 3 19906 20194 19911 3 20199 19911 20194 3 19908 19909 20196 3 20197 20196 19909 3 19909 19912 20197 3 20200 20197 19912 3 19910 19911 20198 3 20199 20198 19911 3 19910 20198 19980 3 20268 19980 20198 3 19912 19913 20201 3 19912 20201 20200 3 19913 19914 20202 3 19913 20202 20201 3 19914 19915 20203 3 19914 20203 20202 3 19915 19916 20204 3 19915 20204 20203 3 19916 19917 20205 3 19916 20205 20204 3 19917 19918 20206 3 19917 20206 20205 3 19918 19919 20207 3 19918 20207 20206 3 19919 19920 20208 3 19919 20208 20207 3 19920 19921 20209 3 19920 20209 20208 3 19921 19922 20210 3 19921 20210 20209 3 19922 19923 20211 3 19922 20211 20210 3 19923 19924 20212 3 19923 20212 20211 3 19924 19925 20213 3 19924 20213 20212 3 19925 19926 20214 3 19925 20214 20213 3 19926 19927 20215 3 19926 20215 20214 3 19927 19928 20216 3 19927 20216 20215 3 19928 19929 20217 3 19928 20217 20216 3 19929 19930 20218 3 19929 20218 20217 3 19930 19931 20219 3 19930 20219 20218 3 19931 19932 20220 3 19931 20220 20219 3 19932 19933 20221 3 19932 20221 20220 3 19933 19934 20222 3 19933 20222 20221 3 19934 19935 20223 3 19934 20223 20222 3 19935 19936 20224 3 19935 20224 20223 3 19936 19937 20225 3 19936 20225 20224 3 19937 19938 20226 3 19937 20226 20225 3 19938 19939 20227 3 19938 20227 20226 3 19939 19940 20228 3 19939 20228 20227 3 19940 19941 20229 3 19940 20229 20228 3 19941 19942 20230 3 19941 20230 20229 3 19942 19943 20231 3 19942 20231 20230 3 19943 19944 20232 3 19943 20232 20231 3 19944 19945 20233 3 19944 20233 20232 3 19945 19946 20234 3 19945 20234 20233 3 19946 19947 20235 3 19946 20235 20234 3 19947 19948 20236 3 19947 20236 20235 3 19948 19949 20237 3 19948 20237 20236 3 19949 19950 20238 3 19949 20238 20237 3 19950 19951 20239 3 19950 20239 20238 3 19951 19952 20240 3 19951 20240 20239 3 19952 19953 20241 3 19952 20241 20240 3 19953 19954 20242 3 19953 20242 20241 3 19954 19955 20243 3 19954 20243 20242 3 19955 19956 20244 3 19955 20244 20243 3 19956 19957 20245 3 19956 20245 20244 3 19957 19958 20246 3 19957 20246 20245 3 19958 19959 20247 3 19958 20247 20246 3 19959 19960 20248 3 19959 20248 20247 3 19960 19961 20249 3 19960 20249 20248 3 19961 19962 20250 3 19961 20250 20249 3 19962 19963 20251 3 19962 20251 20250 3 19963 19964 20252 3 19963 20252 20251 3 19964 19965 20253 3 19964 20253 20252 3 19965 19966 20254 3 19965 20254 20253 3 19966 19967 20255 3 19966 20255 20254 3 19967 19968 20256 3 19967 20256 20255 3 19968 19969 20257 3 19968 20257 20256 3 19969 19970 20258 3 19969 20258 20257 3 19970 19971 20259 3 19970 20259 20258 3 19971 19972 20260 3 19971 20260 20259 3 19972 19973 20261 3 19972 20261 20260 3 19973 19974 20262 3 19973 20262 20261 3 19974 19975 20263 3 19974 20263 20262 3 19975 19976 20264 3 19975 20264 20263 3 19976 19977 20265 3 19976 20265 20264 3 19977 19978 20266 3 19977 20266 20265 3 19978 19979 20267 3 19978 20267 20266 3 19979 19980 20268 3 19979 20268 20267 3 19981 20269 20270 3 19981 20270 19982 3 19981 20051 20269 3 20339 20269 20051 3 19982 20270 20271 3 19982 20271 19983 3 19983 20271 20272 3 19983 20272 19984 3 19984 20272 20273 3 19984 20273 19985 3 19985 20273 20274 3 19985 20274 19986 3 19986 20274 20275 3 19986 20275 19987 3 19987 20275 20276 3 19987 20276 19988 3 19988 20276 20277 3 19988 20277 19989 3 19989 20277 20278 3 19989 20278 19990 3 19990 20278 20279 3 19990 20279 19991 3 19991 20279 20280 3 19991 20280 19992 3 19992 20280 20281 3 19992 20281 19993 3 19993 20281 20282 3 19993 20282 19994 3 19994 20282 20283 3 19994 20283 19995 3 19995 20283 20284 3 19995 20284 19996 3 19996 20284 20285 3 19996 20285 19997 3 19997 20285 20286 3 19997 20286 19998 3 19998 20286 20287 3 19998 20287 19999 3 19999 20287 20288 3 19999 20288 20000 3 20000 20288 20289 3 20000 20289 20001 3 20001 20289 20290 3 20001 20290 20002 3 20002 20290 20291 3 20002 20291 20003 3 20003 20291 20292 3 20003 20292 20004 3 20004 20292 20293 3 20004 20293 20005 3 20005 20293 20294 3 20005 20294 20006 3 20006 20294 20295 3 20006 20295 20007 3 20007 20295 20296 3 20007 20296 20008 3 20008 20296 20009 3 20297 20009 20296 3 20009 20297 20010 3 20298 20010 20297 3 20010 20298 20011 3 20299 20011 20298 3 20011 20299 20012 3 20300 20012 20299 3 20012 20300 20013 3 20301 20013 20300 3 20013 20301 20014 3 20302 20014 20301 3 20014 20302 20015 3 20303 20015 20302 3 20015 20303 20016 3 20304 20016 20303 3 20016 20304 20017 3 20305 20017 20304 3 20017 20305 20018 3 20306 20018 20305 3 20018 20306 20019 3 20307 20019 20306 3 20019 20307 20020 3 20308 20020 20307 3 20020 20308 20021 3 20309 20021 20308 3 20021 20309 20022 3 20310 20022 20309 3 20022 20310 20023 3 20311 20023 20310 3 20023 20311 20024 3 20312 20024 20311 3 20024 20312 20025 3 20313 20025 20312 3 20025 20313 20026 3 20314 20026 20313 3 20026 20314 20027 3 20315 20027 20314 3 20027 20315 20028 3 20316 20028 20315 3 20028 20316 20029 3 20317 20029 20316 3 20029 20317 20030 3 20318 20030 20317 3 20030 20318 20031 3 20319 20031 20318 3 20031 20319 20032 3 20320 20032 20319 3 20032 20320 20033 3 20321 20033 20320 3 20033 20321 20034 3 20322 20034 20321 3 20034 20322 20035 3 20323 20035 20322 3 20035 20323 20036 3 20324 20036 20323 3 20036 20324 20037 3 20325 20037 20324 3 20037 20325 20038 3 20326 20038 20325 3 20038 20326 20039 3 20327 20039 20326 3 20039 20327 20040 3 20328 20040 20327 3 20040 20328 20041 3 20329 20041 20328 3 20041 20329 20042 3 20330 20042 20329 3 20042 20330 20043 3 20331 20043 20330 3 20043 20331 20044 3 20332 20044 20331 3 20044 20332 20045 3 20333 20045 20332 3 20045 20333 20046 3 20334 20046 20333 3 20046 20334 20047 3 20335 20047 20334 3 20047 20335 20048 3 20336 20048 20335 3 20048 20336 20049 3 20337 20049 20336 3 20049 20337 20052 3 20340 20052 20337 3 20050 20338 20051 3 20339 20051 20338 3 20050 20055 20338 3 20343 20338 20055 3 20052 20340 20053 3 20341 20053 20340 3 20053 20341 20056 3 20344 20056 20341 3 20054 20342 20055 3 20343 20055 20342 3 20054 20058 20342 3 20346 20342 20058 3 20056 20344 20057 3 20345 20057 20344 3 20057 20345 20059 3 20347 20059 20345 3 20058 20060 20346 3 20348 20346 20060 3 20059 20347 20061 3 20349 20061 20347 3 20060 20062 20348 3 20350 20348 20062 3 20061 20349 20063 3 20351 20063 20349 3 20062 20064 20350 3 20352 20350 20064 3 20063 20351 20065 3 20353 20065 20351 3 20064 20066 20352 3 20354 20352 20066 3 20065 20353 20067 3 20355 20067 20353 3 20066 20068 20354 3 20356 20354 20068 3 20067 20355 20069 3 20357 20069 20355 3 20068 20070 20356 3 20358 20356 20070 3 20069 20357 20071 3 20359 20071 20357 3 20070 20072 20358 3 20360 20358 20072 3 20071 20359 20073 3 20361 20073 20359 3 20072 20074 20360 3 20362 20360 20074 3 20073 20361 20075 3 20363 20075 20361 3 20074 20076 20362 3 20364 20362 20076 3 20075 20363 20077 3 20365 20077 20363 3 20076 20078 20364 3 20366 20364 20078 3 20077 20365 20079 3 20367 20079 20365 3 20078 20080 20366 3 20368 20366 20080 3 20079 20367 20081 3 20369 20081 20367 3 20080 20082 20368 3 20370 20368 20082 3 20081 20369 20083 3 20371 20083 20369 3 20082 20084 20370 3 20372 20370 20084 3 20083 20371 20085 3 20373 20085 20371 3 20084 20086 20372 3 20374 20372 20086 3 20085 20373 20087 3 20375 20087 20373 3 20086 20088 20376 3 20086 20376 20374 3 20087 20375 20089 3 20377 20089 20375 3 20088 20090 20378 3 20088 20378 20376 3 20089 20377 20091 3 20379 20091 20377 3 20090 20092 20380 3 20090 20380 20378 3 20091 20379 20093 3 20381 20093 20379 3 20092 20094 20382 3 20092 20382 20380 3 20093 20381 20095 3 20383 20095 20381 3 20094 20096 20384 3 20094 20384 20382 3 20095 20383 20097 3 20385 20097 20383 3 20096 20098 20386 3 20096 20386 20384 3 20097 20385 20387 3 20097 20387 20099 3 20098 20100 20388 3 20098 20388 20386 3 20099 20387 20389 3 20099 20389 20101 3 20100 20102 20390 3 20100 20390 20388 3 20101 20389 20391 3 20101 20391 20103 3 20102 20104 20392 3 20102 20392 20390 3 20103 20391 20393 3 20103 20393 20105 3 20104 20106 20394 3 20104 20394 20392 3 20105 20393 20395 3 20105 20395 20107 3 20106 20108 20396 3 20106 20396 20394 3 20107 20395 20397 3 20107 20397 20109 3 20108 20110 20398 3 20108 20398 20396 3 20109 20397 20399 3 20109 20399 20111 3 20110 20112 20400 3 20110 20400 20398 3 20111 20399 20401 3 20111 20401 20113 3 20112 20114 20402 3 20112 20402 20400 3 20113 20401 20403 3 20113 20403 20115 3 20114 20116 20404 3 20114 20404 20402 3 20115 20403 20405 3 20115 20405 20117 3 20116 20118 20406 3 20116 20406 20404 3 20117 20405 20407 3 20117 20407 20119 3 20118 20120 20408 3 20118 20408 20406 3 20119 20407 20409 3 20119 20409 20121 3 20120 20122 20410 3 20120 20410 20408 3 20121 20409 20411 3 20121 20411 20123 3 20122 20124 20412 3 20122 20412 20410 3 20123 20411 20413 3 20123 20413 20125 3 20124 20126 20414 3 20124 20414 20412 3 20125 20413 20415 3 20125 20415 20127 3 20126 20128 20416 3 20126 20416 20414 3 20127 20415 20417 3 20127 20417 20129 3 20128 20130 20418 3 20128 20418 20416 3 20129 20417 20419 3 20129 20419 20131 3 20130 20132 20420 3 20130 20420 20418 3 20131 20419 20421 3 20131 20421 20133 3 20132 20134 20422 3 20132 20422 20420 3 20133 20421 20423 3 20133 20423 20135 3 20134 20136 20424 3 20134 20424 20422 3 20135 20423 20425 3 20135 20425 20137 3 20136 20138 20426 3 20136 20426 20424 3 20137 20425 20427 3 20137 20427 20139 3 20138 20140 20428 3 20138 20428 20426 3 20139 20427 20429 3 20139 20429 20141 3 20140 20142 20430 3 20140 20430 20428 3 20141 20429 20431 3 20141 20431 20143 3 20142 20144 20432 3 20142 20432 20430 3 20143 20431 20433 3 20143 20433 20145 3 20144 20146 20434 3 20144 20434 20432 3 20145 20433 20435 3 20145 20435 20147 3 20146 20148 20436 3 20146 20436 20434 3 20147 20435 20437 3 20147 20437 20149 3 20148 20150 20438 3 20148 20438 20436 3 20149 20437 20439 3 20149 20439 20151 3 20150 20152 20440 3 20150 20440 20438 3 20151 20439 20441 3 20151 20441 20153 3 20152 20154 20442 3 20152 20442 20440 3 20153 20441 20443 3 20153 20443 20155 3 20154 20156 20444 3 20154 20444 20442 3 20155 20443 20445 3 20155 20445 20157 3 20156 20158 20446 3 20156 20446 20444 3 20157 20445 20447 3 20157 20447 20159 3 20158 20160 20448 3 20158 20448 20446 3 20159 20447 20449 3 20159 20449 20161 3 20160 20162 20450 3 20160 20450 20448 3 20161 20449 20451 3 20161 20451 20163 3 20162 20164 20452 3 20162 20452 20450 3 20163 20451 20453 3 20163 20453 20165 3 20164 20166 20454 3 20164 20454 20452 3 20165 20453 20455 3 20165 20455 20167 3 20166 20168 20456 3 20166 20456 20454 3 20167 20455 20457 3 20167 20457 20169 3 20168 20170 20458 3 20168 20458 20456 3 20169 20457 20459 3 20169 20459 20171 3 20170 20172 20460 3 20170 20460 20458 3 20171 20459 20461 3 20171 20461 20173 3 20172 20174 20462 3 20172 20462 20460 3 20173 20461 20463 3 20173 20463 20175 3 20174 20176 20462 3 20464 20462 20176 3 20175 20463 20465 3 20175 20465 20177 3 20176 20178 20464 3 20466 20464 20178 3 20177 20465 20467 3 20177 20467 20179 3 20178 20180 20466 3 20468 20466 20180 3 20179 20467 20469 3 20179 20469 20181 3 20180 20182 20468 3 20470 20468 20182 3 20181 20469 20471 3 20181 20471 20183 3 20182 20184 20470 3 20472 20470 20184 3 20183 20471 20473 3 20183 20473 20185 3 20184 20186 20472 3 20474 20472 20186 3 20185 20473 20187 3 20475 20187 20473 3 20186 20188 20474 3 20476 20474 20188 3 20187 20475 20189 3 20477 20189 20475 3 20188 20190 20476 3 20478 20476 20190 3 20189 20477 20191 3 20479 20191 20477 3 20190 20192 20478 3 20480 20478 20192 3 20191 20479 20195 3 20483 20195 20479 3 20192 20193 20480 3 20481 20480 20193 3 20193 20196 20481 3 20484 20481 20196 3 20194 20195 20482 3 20483 20482 20195 3 20194 20482 20199 3 20487 20199 20482 3 20196 20197 20484 3 20485 20484 20197 3 20197 20200 20485 3 20488 20485 20200 3 20198 20199 20486 3 20487 20486 20199 3 20198 20486 20268 3 20556 20268 20486 3 20200 20201 20488 3 20489 20488 20201 3 20201 20202 20489 3 20490 20489 20202 3 20202 20203 20490 3 20491 20490 20203 3 20203 20204 20491 3 20492 20491 20204 3 20204 20205 20492 3 20493 20492 20205 3 20205 20206 20493 3 20494 20493 20206 3 20206 20207 20494 3 20495 20494 20207 3 20207 20208 20495 3 20496 20495 20208 3 20208 20209 20496 3 20497 20496 20209 3 20209 20210 20497 3 20498 20497 20210 3 20210 20211 20498 3 20499 20498 20211 3 20211 20212 20499 3 20500 20499 20212 3 20212 20213 20500 3 20501 20500 20213 3 20213 20214 20501 3 20502 20501 20214 3 20214 20215 20502 3 20503 20502 20215 3 20215 20216 20503 3 20504 20503 20216 3 20216 20217 20504 3 20505 20504 20217 3 20217 20218 20505 3 20506 20505 20218 3 20218 20219 20506 3 20507 20506 20219 3 20219 20220 20507 3 20508 20507 20220 3 20220 20221 20508 3 20509 20508 20221 3 20221 20222 20509 3 20510 20509 20222 3 20222 20223 20510 3 20511 20510 20223 3 20223 20224 20511 3 20512 20511 20224 3 20224 20225 20512 3 20513 20512 20225 3 20225 20226 20513 3 20514 20513 20226 3 20226 20227 20514 3 20515 20514 20227 3 20227 20228 20515 3 20516 20515 20228 3 20228 20229 20516 3 20517 20516 20229 3 20229 20230 20517 3 20518 20517 20230 3 20230 20231 20518 3 20519 20518 20231 3 20231 20232 20519 3 20520 20519 20232 3 20232 20233 20520 3 20521 20520 20233 3 20233 20234 20521 3 20522 20521 20234 3 20234 20235 20522 3 20523 20522 20235 3 20235 20236 20523 3 20524 20523 20236 3 20236 20237 20524 3 20525 20524 20237 3 20237 20238 20525 3 20526 20525 20238 3 20238 20239 20526 3 20527 20526 20239 3 20239 20240 20527 3 20528 20527 20240 3 20240 20241 20528 3 20529 20528 20241 3 20241 20242 20529 3 20530 20529 20242 3 20242 20243 20530 3 20531 20530 20243 3 20243 20244 20531 3 20532 20531 20244 3 20244 20245 20532 3 20533 20532 20245 3 20245 20246 20533 3 20534 20533 20246 3 20246 20247 20534 3 20535 20534 20247 3 20247 20248 20535 3 20536 20535 20248 3 20248 20249 20536 3 20537 20536 20249 3 20249 20250 20537 3 20538 20537 20250 3 20250 20251 20538 3 20539 20538 20251 3 20251 20252 20539 3 20540 20539 20252 3 20252 20253 20540 3 20541 20540 20253 3 20253 20254 20541 3 20542 20541 20254 3 20254 20255 20542 3 20543 20542 20255 3 20255 20256 20543 3 20544 20543 20256 3 20256 20257 20544 3 20545 20544 20257 3 20257 20258 20545 3 20546 20545 20258 3 20258 20259 20546 3 20547 20546 20259 3 20259 20260 20547 3 20548 20547 20260 3 20260 20261 20548 3 20549 20548 20261 3 20261 20262 20550 3 20261 20550 20549 3 20262 20263 20551 3 20262 20551 20550 3 20263 20264 20552 3 20263 20552 20551 3 20264 20265 20553 3 20264 20553 20552 3 20265 20266 20554 3 20265 20554 20553 3 20266 20267 20555 3 20266 20555 20554 3 20267 20268 20556 3 20267 20556 20555 3 20269 20557 20270 3 20558 20270 20557 3 20269 20339 20627 3 20269 20627 20557 3 20270 20558 20271 3 20559 20271 20558 3 20271 20559 20272 3 20560 20272 20559 3 20272 20560 20561 3 20272 20561 20273 3 20273 20561 20562 3 20273 20562 20274 3 20274 20562 20563 3 20274 20563 20275 3 20275 20563 20564 3 20275 20564 20276 3 20276 20564 20565 3 20276 20565 20277 3 20277 20565 20566 3 20277 20566 20278 3 20278 20566 20567 3 20278 20567 20279 3 20279 20567 20568 3 20279 20568 20280 3 20280 20568 20569 3 20280 20569 20281 3 20281 20569 20570 3 20281 20570 20282 3 20282 20570 20571 3 20282 20571 20283 3 20283 20571 20572 3 20283 20572 20284 3 20284 20572 20573 3 20284 20573 20285 3 20285 20573 20574 3 20285 20574 20286 3 20286 20574 20575 3 20286 20575 20287 3 20287 20575 20576 3 20287 20576 20288 3 20288 20576 20577 3 20288 20577 20289 3 20289 20577 20578 3 20289 20578 20290 3 20290 20578 20579 3 20290 20579 20291 3 20291 20579 20580 3 20291 20580 20292 3 20292 20580 20581 3 20292 20581 20293 3 20293 20581 20582 3 20293 20582 20294 3 20294 20582 20583 3 20294 20583 20295 3 20295 20583 20584 3 20295 20584 20296 3 20296 20584 20585 3 20296 20585 20297 3 20297 20585 20586 3 20297 20586 20298 3 20298 20586 20587 3 20298 20587 20299 3 20299 20587 20588 3 20299 20588 20300 3 20300 20588 20589 3 20300 20589 20301 3 20301 20589 20590 3 20301 20590 20302 3 20302 20590 20591 3 20302 20591 20303 3 20303 20591 20592 3 20303 20592 20304 3 20304 20592 20593 3 20304 20593 20305 3 20305 20593 20594 3 20305 20594 20306 3 20306 20594 20595 3 20306 20595 20307 3 20307 20595 20596 3 20307 20596 20308 3 20308 20596 20597 3 20308 20597 20309 3 20309 20597 20598 3 20309 20598 20310 3 20310 20598 20599 3 20310 20599 20311 3 20311 20599 20600 3 20311 20600 20312 3 20312 20600 20601 3 20312 20601 20313 3 20313 20601 20602 3 20313 20602 20314 3 20314 20602 20603 3 20314 20603 20315 3 20315 20603 20604 3 20315 20604 20316 3 20316 20604 20605 3 20316 20605 20317 3 20317 20605 20606 3 20317 20606 20318 3 20318 20606 20607 3 20318 20607 20319 3 20319 20607 20608 3 20319 20608 20320 3 20320 20608 20609 3 20320 20609 20321 3 20321 20609 20610 3 20321 20610 20322 3 20322 20610 20611 3 20322 20611 20323 3 20323 20611 20612 3 20323 20612 20324 3 20324 20612 20613 3 20324 20613 20325 3 20325 20613 20614 3 20325 20614 20326 3 20326 20614 20615 3 20326 20615 20327 3 20327 20615 20616 3 20327 20616 20328 3 20328 20616 20617 3 20328 20617 20329 3 20329 20617 20618 3 20329 20618 20330 3 20330 20618 20619 3 20330 20619 20331 3 20331 20619 20620 3 20331 20620 20332 3 20332 20620 20621 3 20332 20621 20333 3 20333 20621 20622 3 20333 20622 20334 3 20334 20622 20623 3 20334 20623 20335 3 20335 20623 20624 3 20335 20624 20336 3 20336 20624 20625 3 20336 20625 20337 3 20337 20625 20628 3 20337 20628 20340 3 20338 20626 20627 3 20338 20627 20339 3 20338 20343 20631 3 20338 20631 20626 3 20340 20628 20629 3 20340 20629 20341 3 20341 20629 20632 3 20341 20632 20344 3 20342 20630 20631 3 20342 20631 20343 3 20342 20346 20634 3 20342 20634 20630 3 20344 20632 20633 3 20344 20633 20345 3 20345 20633 20635 3 20345 20635 20347 3 20346 20348 20636 3 20346 20636 20634 3 20347 20635 20637 3 20347 20637 20349 3 20348 20350 20636 3 20638 20636 20350 3 20349 20637 20639 3 20349 20639 20351 3 20350 20352 20638 3 20640 20638 20352 3 20351 20639 20641 3 20351 20641 20353 3 20352 20354 20640 3 20642 20640 20354 3 20353 20641 20643 3 20353 20643 20355 3 20354 20356 20642 3 20644 20642 20356 3 20355 20643 20645 3 20355 20645 20357 3 20356 20358 20644 3 20646 20644 20358 3 20357 20645 20647 3 20357 20647 20359 3 20358 20360 20646 3 20648 20646 20360 3 20359 20647 20649 3 20359 20649 20361 3 20360 20362 20648 3 20650 20648 20362 3 20361 20649 20363 3 20651 20363 20649 3 20362 20364 20650 3 20652 20650 20364 3 20363 20651 20365 3 20653 20365 20651 3 20364 20366 20652 3 20654 20652 20366 3 20365 20653 20367 3 20655 20367 20653 3 20366 20368 20654 3 20656 20654 20368 3 20367 20655 20369 3 20657 20369 20655 3 20368 20370 20656 3 20658 20656 20370 3 20369 20657 20371 3 20659 20371 20657 3 20370 20372 20658 3 20660 20658 20372 3 20371 20659 20373 3 20661 20373 20659 3 20372 20374 20660 3 20662 20660 20374 3 20373 20661 20375 3 20663 20375 20661 3 20374 20376 20662 3 20664 20662 20376 3 20375 20663 20377 3 20665 20377 20663 3 20376 20378 20664 3 20666 20664 20378 3 20377 20665 20379 3 20667 20379 20665 3 20378 20380 20666 3 20668 20666 20380 3 20379 20667 20381 3 20669 20381 20667 3 20380 20382 20668 3 20670 20668 20382 3 20381 20669 20383 3 20671 20383 20669 3 20382 20384 20670 3 20672 20670 20384 3 20383 20671 20385 3 20673 20385 20671 3 20384 20386 20672 3 20674 20672 20386 3 20385 20673 20387 3 20675 20387 20673 3 20386 20388 20674 3 20676 20674 20388 3 20387 20675 20389 3 20677 20389 20675 3 20388 20390 20676 3 20678 20676 20390 3 20389 20677 20391 3 20679 20391 20677 3 20390 20392 20678 3 20680 20678 20392 3 20391 20679 20393 3 20681 20393 20679 3 20392 20394 20680 3 20682 20680 20394 3 20393 20681 20395 3 20683 20395 20681 3 20394 20396 20682 3 20684 20682 20396 3 20395 20683 20397 3 20685 20397 20683 3 20396 20398 20684 3 20686 20684 20398 3 20397 20685 20399 3 20687 20399 20685 3 20398 20400 20686 3 20688 20686 20400 3 20399 20687 20401 3 20689 20401 20687 3 20400 20402 20688 3 20690 20688 20402 3 20401 20689 20403 3 20691 20403 20689 3 20402 20404 20690 3 20692 20690 20404 3 20403 20691 20405 3 20693 20405 20691 3 20404 20406 20692 3 20694 20692 20406 3 20405 20693 20407 3 20695 20407 20693 3 20406 20408 20694 3 20696 20694 20408 3 20407 20695 20409 3 20697 20409 20695 3 20408 20410 20696 3 20698 20696 20410 3 20409 20697 20411 3 20699 20411 20697 3 20410 20412 20698 3 20700 20698 20412 3 20411 20699 20413 3 20701 20413 20699 3 20412 20414 20700 3 20702 20700 20414 3 20413 20701 20415 3 20703 20415 20701 3 20414 20416 20702 3 20704 20702 20416 3 20415 20703 20417 3 20705 20417 20703 3 20416 20418 20704 3 20706 20704 20418 3 20417 20705 20419 3 20707 20419 20705 3 20418 20420 20706 3 20708 20706 20420 3 20419 20707 20421 3 20709 20421 20707 3 20420 20422 20708 3 20710 20708 20422 3 20421 20709 20423 3 20711 20423 20709 3 20422 20424 20710 3 20712 20710 20424 3 20423 20711 20425 3 20713 20425 20711 3 20424 20426 20712 3 20714 20712 20426 3 20425 20713 20427 3 20715 20427 20713 3 20426 20428 20714 3 20716 20714 20428 3 20427 20715 20429 3 20717 20429 20715 3 20428 20430 20716 3 20718 20716 20430 3 20429 20717 20431 3 20719 20431 20717 3 20430 20432 20718 3 20720 20718 20432 3 20431 20719 20433 3 20721 20433 20719 3 20432 20434 20720 3 20722 20720 20434 3 20433 20721 20435 3 20723 20435 20721 3 20434 20436 20722 3 20724 20722 20436 3 20435 20723 20437 3 20725 20437 20723 3 20436 20438 20726 3 20436 20726 20724 3 20437 20725 20439 3 20727 20439 20725 3 20438 20440 20728 3 20438 20728 20726 3 20439 20727 20441 3 20729 20441 20727 3 20440 20442 20730 3 20440 20730 20728 3 20441 20729 20443 3 20731 20443 20729 3 20442 20444 20732 3 20442 20732 20730 3 20443 20731 20445 3 20733 20445 20731 3 20444 20446 20734 3 20444 20734 20732 3 20445 20733 20447 3 20735 20447 20733 3 20446 20448 20736 3 20446 20736 20734 3 20447 20735 20449 3 20737 20449 20735 3 20448 20450 20738 3 20448 20738 20736 3 20449 20737 20739 3 20449 20739 20451 3 20450 20452 20740 3 20450 20740 20738 3 20451 20739 20741 3 20451 20741 20453 3 20452 20454 20742 3 20452 20742 20740 3 20453 20741 20743 3 20453 20743 20455 3 20454 20456 20744 3 20454 20744 20742 3 20455 20743 20745 3 20455 20745 20457 3 20456 20458 20746 3 20456 20746 20744 3 20457 20745 20747 3 20457 20747 20459 3 20458 20460 20748 3 20458 20748 20746 3 20459 20747 20749 3 20459 20749 20461 3 20460 20462 20750 3 20460 20750 20748 3 20461 20749 20751 3 20461 20751 20463 3 20462 20464 20752 3 20462 20752 20750 3 20463 20751 20753 3 20463 20753 20465 3 20464 20466 20754 3 20464 20754 20752 3 20465 20753 20755 3 20465 20755 20467 3 20466 20468 20756 3 20466 20756 20754 3 20467 20755 20757 3 20467 20757 20469 3 20468 20470 20758 3 20468 20758 20756 3 20469 20757 20759 3 20469 20759 20471 3 20470 20472 20760 3 20470 20760 20758 3 20471 20759 20761 3 20471 20761 20473 3 20472 20474 20762 3 20472 20762 20760 3 20473 20761 20763 3 20473 20763 20475 3 20474 20476 20764 3 20474 20764 20762 3 20475 20763 20765 3 20475 20765 20477 3 20476 20478 20766 3 20476 20766 20764 3 20477 20765 20767 3 20477 20767 20479 3 20478 20480 20768 3 20478 20768 20766 3 20479 20767 20771 3 20479 20771 20483 3 20480 20481 20769 3 20480 20769 20768 3 20481 20484 20772 3 20481 20772 20769 3 20482 20483 20771 3 20482 20771 20770 3 20482 20770 20775 3 20482 20775 20487 3 20484 20485 20773 3 20484 20773 20772 3 20485 20488 20776 3 20485 20776 20773 3 20486 20487 20775 3 20486 20775 20774 3 20486 20774 20844 3 20486 20844 20556 3 20488 20489 20777 3 20488 20777 20776 3 20489 20490 20778 3 20489 20778 20777 3 20490 20491 20779 3 20490 20779 20778 3 20491 20492 20780 3 20491 20780 20779 3 20492 20493 20781 3 20492 20781 20780 3 20493 20494 20782 3 20493 20782 20781 3 20494 20495 20783 3 20494 20783 20782 3 20495 20496 20784 3 20495 20784 20783 3 20496 20497 20785 3 20496 20785 20784 3 20497 20498 20786 3 20497 20786 20785 3 20498 20499 20787 3 20498 20787 20786 3 20499 20500 20788 3 20499 20788 20787 3 20500 20501 20789 3 20500 20789 20788 3 20501 20502 20790 3 20501 20790 20789 3 20502 20503 20791 3 20502 20791 20790 3 20503 20504 20792 3 20503 20792 20791 3 20504 20505 20793 3 20504 20793 20792 3 20505 20506 20794 3 20505 20794 20793 3 20506 20507 20795 3 20506 20795 20794 3 20507 20508 20796 3 20507 20796 20795 3 20508 20509 20797 3 20508 20797 20796 3 20509 20510 20798 3 20509 20798 20797 3 20510 20511 20799 3 20510 20799 20798 3 20511 20512 20800 3 20511 20800 20799 3 20512 20513 20801 3 20512 20801 20800 3 20513 20514 20802 3 20513 20802 20801 3 20514 20515 20803 3 20514 20803 20802 3 20515 20516 20804 3 20515 20804 20803 3 20516 20517 20805 3 20516 20805 20804 3 20517 20518 20806 3 20517 20806 20805 3 20518 20519 20807 3 20518 20807 20806 3 20519 20520 20808 3 20519 20808 20807 3 20520 20521 20809 3 20520 20809 20808 3 20521 20522 20810 3 20521 20810 20809 3 20522 20523 20811 3 20522 20811 20810 3 20523 20524 20812 3 20523 20812 20811 3 20524 20525 20813 3 20524 20813 20812 3 20525 20526 20813 3 20814 20813 20526 3 20526 20527 20814 3 20815 20814 20527 3 20527 20528 20815 3 20816 20815 20528 3 20528 20529 20816 3 20817 20816 20529 3 20529 20530 20817 3 20818 20817 20530 3 20530 20531 20818 3 20819 20818 20531 3 20531 20532 20819 3 20820 20819 20532 3 20532 20533 20820 3 20821 20820 20533 3 20533 20534 20821 3 20822 20821 20534 3 20534 20535 20822 3 20823 20822 20535 3 20535 20536 20823 3 20824 20823 20536 3 20536 20537 20824 3 20825 20824 20537 3 20537 20538 20825 3 20826 20825 20538 3 20538 20539 20826 3 20827 20826 20539 3 20539 20540 20827 3 20828 20827 20540 3 20540 20541 20828 3 20829 20828 20541 3 20541 20542 20829 3 20830 20829 20542 3 20542 20543 20830 3 20831 20830 20543 3 20543 20544 20831 3 20832 20831 20544 3 20544 20545 20832 3 20833 20832 20545 3 20545 20546 20833 3 20834 20833 20546 3 20546 20547 20834 3 20835 20834 20547 3 20547 20548 20835 3 20836 20835 20548 3 20548 20549 20836 3 20837 20836 20549 3 20549 20550 20837 3 20838 20837 20550 3 20550 20551 20838 3 20839 20838 20551 3 20551 20552 20839 3 20840 20839 20552 3 20552 20553 20840 3 20841 20840 20553 3 20553 20554 20841 3 20842 20841 20554 3 20554 20555 20842 3 20843 20842 20555 3 20555 20556 20843 3 20844 20843 20556 3 20557 20845 20558 3 20846 20558 20845 3 20557 20627 20845 3 20915 20845 20627 3 20558 20846 20559 3 20847 20559 20846 3 20559 20847 20560 3 20848 20560 20847 3 20560 20848 20561 3 20849 20561 20848 3 20561 20849 20562 3 20850 20562 20849 3 20562 20850 20563 3 20851 20563 20850 3 20563 20851 20564 3 20852 20564 20851 3 20564 20852 20565 3 20853 20565 20852 3 20565 20853 20566 3 20854 20566 20853 3 20566 20854 20567 3 20855 20567 20854 3 20567 20855 20568 3 20856 20568 20855 3 20568 20856 20569 3 20857 20569 20856 3 20569 20857 20570 3 20858 20570 20857 3 20570 20858 20571 3 20859 20571 20858 3 20571 20859 20572 3 20860 20572 20859 3 20572 20860 20573 3 20861 20573 20860 3 20573 20861 20574 3 20862 20574 20861 3 20574 20862 20575 3 20863 20575 20862 3 20575 20863 20576 3 20864 20576 20863 3 20576 20864 20577 3 20865 20577 20864 3 20577 20865 20578 3 20866 20578 20865 3 20578 20866 20579 3 20867 20579 20866 3 20579 20867 20580 3 20868 20580 20867 3 20580 20868 20581 3 20869 20581 20868 3 20581 20869 20582 3 20870 20582 20869 3 20582 20870 20583 3 20871 20583 20870 3 20583 20871 20584 3 20872 20584 20871 3 20584 20872 20585 3 20873 20585 20872 3 20585 20873 20586 3 20874 20586 20873 3 20586 20874 20587 3 20875 20587 20874 3 20587 20875 20588 3 20876 20588 20875 3 20588 20876 20589 3 20877 20589 20876 3 20589 20877 20590 3 20878 20590 20877 3 20590 20878 20591 3 20879 20591 20878 3 20591 20879 20592 3 20880 20592 20879 3 20592 20880 20593 3 20881 20593 20880 3 20593 20881 20594 3 20882 20594 20881 3 20594 20882 20595 3 20883 20595 20882 3 20595 20883 20596 3 20884 20596 20883 3 20596 20884 20597 3 20885 20597 20884 3 20597 20885 20598 3 20886 20598 20885 3 20598 20886 20599 3 20887 20599 20886 3 20599 20887 20600 3 20888 20600 20887 3 20600 20888 20601 3 20889 20601 20888 3 20601 20889 20602 3 20890 20602 20889 3 20602 20890 20603 3 20891 20603 20890 3 20603 20891 20604 3 20892 20604 20891 3 20604 20892 20605 3 20893 20605 20892 3 20605 20893 20606 3 20894 20606 20893 3 20606 20894 20607 3 20895 20607 20894 3 20607 20895 20608 3 20896 20608 20895 3 20608 20896 20609 3 20897 20609 20896 3 20609 20897 20610 3 20898 20610 20897 3 20610 20898 20611 3 20899 20611 20898 3 20611 20899 20612 3 20900 20612 20899 3 20612 20900 20613 3 20901 20613 20900 3 20613 20901 20614 3 20902 20614 20901 3 20614 20902 20615 3 20903 20615 20902 3 20615 20903 20616 3 20904 20616 20903 3 20616 20904 20617 3 20905 20617 20904 3 20617 20905 20618 3 20906 20618 20905 3 20618 20906 20619 3 20907 20619 20906 3 20619 20907 20620 3 20908 20620 20907 3 20620 20908 20621 3 20909 20621 20908 3 20621 20909 20622 3 20910 20622 20909 3 20622 20910 20623 3 20911 20623 20910 3 20623 20911 20624 3 20912 20624 20911 3 20624 20912 20625 3 20913 20625 20912 3 20625 20913 20916 3 20625 20916 20628 3 20626 20914 20915 3 20626 20915 20627 3 20626 20631 20919 3 20626 20919 20914 3 20628 20916 20917 3 20628 20917 20629 3 20629 20917 20920 3 20629 20920 20632 3 20630 20918 20919 3 20630 20919 20631 3 20630 20634 20922 3 20630 20922 20918 3 20632 20920 20921 3 20632 20921 20633 3 20633 20921 20923 3 20633 20923 20635 3 20634 20636 20924 3 20634 20924 20922 3 20635 20923 20925 3 20635 20925 20637 3 20636 20638 20926 3 20636 20926 20924 3 20637 20925 20927 3 20637 20927 20639 3 20638 20640 20928 3 20638 20928 20926 3 20639 20927 20929 3 20639 20929 20641 3 20640 20642 20930 3 20640 20930 20928 3 20641 20929 20931 3 20641 20931 20643 3 20642 20644 20932 3 20642 20932 20930 3 20643 20931 20933 3 20643 20933 20645 3 20644 20646 20934 3 20644 20934 20932 3 20645 20933 20935 3 20645 20935 20647 3 20646 20648 20936 3 20646 20936 20934 3 20647 20935 20937 3 20647 20937 20649 3 20648 20650 20938 3 20648 20938 20936 3 20649 20937 20939 3 20649 20939 20651 3 20650 20652 20940 3 20650 20940 20938 3 20651 20939 20941 3 20651 20941 20653 3 20652 20654 20942 3 20652 20942 20940 3 20653 20941 20943 3 20653 20943 20655 3 20654 20656 20944 3 20654 20944 20942 3 20655 20943 20945 3 20655 20945 20657 3 20656 20658 20946 3 20656 20946 20944 3 20657 20945 20947 3 20657 20947 20659 3 20658 20660 20948 3 20658 20948 20946 3 20659 20947 20949 3 20659 20949 20661 3 20660 20662 20950 3 20660 20950 20948 3 20661 20949 20951 3 20661 20951 20663 3 20662 20664 20952 3 20662 20952 20950 3 20663 20951 20953 3 20663 20953 20665 3 20664 20666 20954 3 20664 20954 20952 3 20665 20953 20955 3 20665 20955 20667 3 20666 20668 20956 3 20666 20956 20954 3 20667 20955 20957 3 20667 20957 20669 3 20668 20670 20958 3 20668 20958 20956 3 20669 20957 20959 3 20669 20959 20671 3 20670 20672 20960 3 20670 20960 20958 3 20671 20959 20961 3 20671 20961 20673 3 20672 20674 20962 3 20672 20962 20960 3 20673 20961 20963 3 20673 20963 20675 3 20674 20676 20964 3 20674 20964 20962 3 20675 20963 20965 3 20675 20965 20677 3 20676 20678 20966 3 20676 20966 20964 3 20677 20965 20967 3 20677 20967 20679 3 20678 20680 20968 3 20678 20968 20966 3 20679 20967 20969 3 20679 20969 20681 3 20680 20682 20970 3 20680 20970 20968 3 20681 20969 20971 3 20681 20971 20683 3 20682 20684 20972 3 20682 20972 20970 3 20683 20971 20973 3 20683 20973 20685 3 20684 20686 20974 3 20684 20974 20972 3 20685 20973 20975 3 20685 20975 20687 3 20686 20688 20976 3 20686 20976 20974 3 20687 20975 20977 3 20687 20977 20689 3 20688 20690 20978 3 20688 20978 20976 3 20689 20977 20979 3 20689 20979 20691 3 20690 20692 20980 3 20690 20980 20978 3 20691 20979 20981 3 20691 20981 20693 3 20692 20694 20982 3 20692 20982 20980 3 20693 20981 20983 3 20693 20983 20695 3 20694 20696 20984 3 20694 20984 20982 3 20695 20983 20985 3 20695 20985 20697 3 20696 20698 20986 3 20696 20986 20984 3 20697 20985 20987 3 20697 20987 20699 3 20698 20700 20988 3 20698 20988 20986 3 20699 20987 20989 3 20699 20989 20701 3 20700 20702 20990 3 20700 20990 20988 3 20701 20989 20991 3 20701 20991 20703 3 20702 20704 20990 3 20992 20990 20704 3 20703 20991 20993 3 20703 20993 20705 3 20704 20706 20992 3 20994 20992 20706 3 20705 20993 20995 3 20705 20995 20707 3 20706 20708 20994 3 20996 20994 20708 3 20707 20995 20997 3 20707 20997 20709 3 20708 20710 20996 3 20998 20996 20710 3 20709 20997 20999 3 20709 20999 20711 3 20710 20712 20998 3 21000 20998 20712 3 20711 20999 21001 3 20711 21001 20713 3 20712 20714 21000 3 21002 21000 20714 3 20713 21001 21003 3 20713 21003 20715 3 20714 20716 21002 3 21004 21002 20716 3 20715 21003 20717 3 21005 20717 21003 3 20716 20718 21004 3 21006 21004 20718 3 20717 21005 20719 3 21007 20719 21005 3 20718 20720 21006 3 21008 21006 20720 3 20719 21007 20721 3 21009 20721 21007 3 20720 20722 21008 3 21010 21008 20722 3 20721 21009 20723 3 21011 20723 21009 3 20722 20724 21010 3 21012 21010 20724 3 20723 21011 20725 3 21013 20725 21011 3 20724 20726 21012 3 21014 21012 20726 3 20725 21013 20727 3 21015 20727 21013 3 20726 20728 21014 3 21016 21014 20728 3 20727 21015 20729 3 21017 20729 21015 3 20728 20730 21016 3 21018 21016 20730 3 20729 21017 20731 3 21019 20731 21017 3 20730 20732 21018 3 21020 21018 20732 3 20731 21019 20733 3 21021 20733 21019 3 20732 20734 21020 3 21022 21020 20734 3 20733 21021 20735 3 21023 20735 21021 3 20734 20736 21022 3 21024 21022 20736 3 20735 21023 20737 3 21025 20737 21023 3 20736 20738 21024 3 21026 21024 20738 3 20737 21025 20739 3 21027 20739 21025 3 20738 20740 21026 3 21028 21026 20740 3 20739 21027 20741 3 21029 20741 21027 3 20740 20742 21028 3 21030 21028 20742 3 20741 21029 20743 3 21031 20743 21029 3 20742 20744 21030 3 21032 21030 20744 3 20743 21031 20745 3 21033 20745 21031 3 20744 20746 21032 3 21034 21032 20746 3 20745 21033 20747 3 21035 20747 21033 3 20746 20748 21034 3 21036 21034 20748 3 20747 21035 20749 3 21037 20749 21035 3 20748 20750 21036 3 21038 21036 20750 3 20749 21037 20751 3 21039 20751 21037 3 20750 20752 21038 3 21040 21038 20752 3 20751 21039 20753 3 21041 20753 21039 3 20752 20754 21040 3 21042 21040 20754 3 20753 21041 20755 3 21043 20755 21041 3 20754 20756 21042 3 21044 21042 20756 3 20755 21043 20757 3 21045 20757 21043 3 20756 20758 21044 3 21046 21044 20758 3 20757 21045 20759 3 21047 20759 21045 3 20758 20760 21046 3 21048 21046 20760 3 20759 21047 20761 3 21049 20761 21047 3 20760 20762 21048 3 21050 21048 20762 3 20761 21049 20763 3 21051 20763 21049 3 20762 20764 21050 3 21052 21050 20764 3 20763 21051 20765 3 21053 20765 21051 3 20764 20766 21052 3 21054 21052 20766 3 20765 21053 20767 3 21055 20767 21053 3 20766 20768 21054 3 21056 21054 20768 3 20767 21055 20771 3 21059 20771 21055 3 20768 20769 21056 3 21057 21056 20769 3 20769 20772 21057 3 21060 21057 20772 3 20770 20771 21058 3 21059 21058 20771 3 20770 21058 20775 3 21063 20775 21058 3 20772 20773 21060 3 21061 21060 20773 3 20773 20776 21061 3 21064 21061 20776 3 20774 20775 21062 3 21063 21062 20775 3 20774 21062 20844 3 21132 20844 21062 3 20776 20777 21064 3 21065 21064 20777 3 20777 20778 21065 3 21066 21065 20778 3 20778 20779 21066 3 21067 21066 20779 3 20779 20780 21067 3 21068 21067 20780 3 20780 20781 21068 3 21069 21068 20781 3 20781 20782 21069 3 21070 21069 20782 3 20782 20783 21070 3 21071 21070 20783 3 20783 20784 21071 3 21072 21071 20784 3 20784 20785 21072 3 21073 21072 20785 3 20785 20786 21073 3 21074 21073 20786 3 20786 20787 21074 3 21075 21074 20787 3 20787 20788 21075 3 21076 21075 20788 3 20788 20789 21076 3 21077 21076 20789 3 20789 20790 21077 3 21078 21077 20790 3 20790 20791 21079 3 20790 21079 21078 3 20791 20792 21080 3 20791 21080 21079 3 20792 20793 21081 3 20792 21081 21080 3 20793 20794 21082 3 20793 21082 21081 3 20794 20795 21083 3 20794 21083 21082 3 20795 20796 21084 3 20795 21084 21083 3 20796 20797 21085 3 20796 21085 21084 3 20797 20798 21086 3 20797 21086 21085 3 20798 20799 21087 3 20798 21087 21086 3 20799 20800 21088 3 20799 21088 21087 3 20800 20801 21089 3 20800 21089 21088 3 20801 20802 21090 3 20801 21090 21089 3 20802 20803 21091 3 20802 21091 21090 3 20803 20804 21092 3 20803 21092 21091 3 20804 20805 21093 3 20804 21093 21092 3 20805 20806 21094 3 20805 21094 21093 3 20806 20807 21095 3 20806 21095 21094 3 20807 20808 21096 3 20807 21096 21095 3 20808 20809 21097 3 20808 21097 21096 3 20809 20810 21098 3 20809 21098 21097 3 20810 20811 21099 3 20810 21099 21098 3 20811 20812 21100 3 20811 21100 21099 3 20812 20813 21101 3 20812 21101 21100 3 20813 20814 21102 3 20813 21102 21101 3 20814 20815 21103 3 20814 21103 21102 3 20815 20816 21104 3 20815 21104 21103 3 20816 20817 21105 3 20816 21105 21104 3 20817 20818 21106 3 20817 21106 21105 3 20818 20819 21107 3 20818 21107 21106 3 20819 20820 21108 3 20819 21108 21107 3 20820 20821 21109 3 20820 21109 21108 3 20821 20822 21110 3 20821 21110 21109 3 20822 20823 21111 3 20822 21111 21110 3 20823 20824 21112 3 20823 21112 21111 3 20824 20825 21113 3 20824 21113 21112 3 20825 20826 21114 3 20825 21114 21113 3 20826 20827 21115 3 20826 21115 21114 3 20827 20828 21116 3 20827 21116 21115 3 20828 20829 21117 3 20828 21117 21116 3 20829 20830 21118 3 20829 21118 21117 3 20830 20831 21119 3 20830 21119 21118 3 20831 20832 21120 3 20831 21120 21119 3 20832 20833 21121 3 20832 21121 21120 3 20833 20834 21122 3 20833 21122 21121 3 20834 20835 21123 3 20834 21123 21122 3 20835 20836 21124 3 20835 21124 21123 3 20836 20837 21125 3 20836 21125 21124 3 20837 20838 21126 3 20837 21126 21125 3 20838 20839 21127 3 20838 21127 21126 3 20839 20840 21128 3 20839 21128 21127 3 20840 20841 21129 3 20840 21129 21128 3 20841 20842 21130 3 20841 21130 21129 3 20842 20843 21131 3 20842 21131 21130 3 20843 20844 21132 3 20843 21132 21131 3 20845 21133 21134 3 20845 21134 20846 3 20845 20915 21133 3 21203 21133 20915 3 20846 21134 21135 3 20846 21135 20847 3 20847 21135 21136 3 20847 21136 20848 3 20848 21136 21137 3 20848 21137 20849 3 20849 21137 21138 3 20849 21138 20850 3 20850 21138 21139 3 20850 21139 20851 3 20851 21139 21140 3 20851 21140 20852 3 20852 21140 21141 3 20852 21141 20853 3 20853 21141 21142 3 20853 21142 20854 3 20854 21142 21143 3 20854 21143 20855 3 20855 21143 21144 3 20855 21144 20856 3 20856 21144 21145 3 20856 21145 20857 3 20857 21145 21146 3 20857 21146 20858 3 20858 21146 21147 3 20858 21147 20859 3 20859 21147 21148 3 20859 21148 20860 3 20860 21148 21149 3 20860 21149 20861 3 20861 21149 21150 3 20861 21150 20862 3 20862 21150 21151 3 20862 21151 20863 3 20863 21151 21152 3 20863 21152 20864 3 20864 21152 21153 3 20864 21153 20865 3 20865 21153 21154 3 20865 21154 20866 3 20866 21154 21155 3 20866 21155 20867 3 20867 21155 21156 3 20867 21156 20868 3 20868 21156 21157 3 20868 21157 20869 3 20869 21157 21158 3 20869 21158 20870 3 20870 21158 21159 3 20870 21159 20871 3 20871 21159 21160 3 20871 21160 20872 3 20872 21160 21161 3 20872 21161 20873 3 20873 21161 21162 3 20873 21162 20874 3 20874 21162 21163 3 20874 21163 20875 3 20875 21163 21164 3 20875 21164 20876 3 20876 21164 21165 3 20876 21165 20877 3 20877 21165 21166 3 20877 21166 20878 3 20878 21166 21167 3 20878 21167 20879 3 20879 21167 21168 3 20879 21168 20880 3 20880 21168 21169 3 20880 21169 20881 3 20881 21169 21170 3 20881 21170 20882 3 20882 21170 21171 3 20882 21171 20883 3 20883 21171 21172 3 20883 21172 20884 3 20884 21172 21173 3 20884 21173 20885 3 20885 21173 21174 3 20885 21174 20886 3 20886 21174 21175 3 20886 21175 20887 3 20887 21175 21176 3 20887 21176 20888 3 20888 21176 21177 3 20888 21177 20889 3 20889 21177 21178 3 20889 21178 20890 3 20890 21178 21179 3 20890 21179 20891 3 20891 21179 21180 3 20891 21180 20892 3 20892 21180 20893 3 21181 20893 21180 3 20893 21181 20894 3 21182 20894 21181 3 20894 21182 20895 3 21183 20895 21182 3 20895 21183 20896 3 21184 20896 21183 3 20896 21184 20897 3 21185 20897 21184 3 20897 21185 20898 3 21186 20898 21185 3 20898 21186 20899 3 21187 20899 21186 3 20899 21187 20900 3 21188 20900 21187 3 20900 21188 20901 3 21189 20901 21188 3 20901 21189 20902 3 21190 20902 21189 3 20902 21190 20903 3 21191 20903 21190 3 20903 21191 20904 3 21192 20904 21191 3 20904 21192 20905 3 21193 20905 21192 3 20905 21193 20906 3 21194 20906 21193 3 20906 21194 20907 3 21195 20907 21194 3 20907 21195 20908 3 21196 20908 21195 3 20908 21196 20909 3 21197 20909 21196 3 20909 21197 20910 3 21198 20910 21197 3 20910 21198 20911 3 21199 20911 21198 3 20911 21199 20912 3 21200 20912 21199 3 20912 21200 20913 3 21201 20913 21200 3 20913 21201 20916 3 21204 20916 21201 3 20914 21202 20915 3 21203 20915 21202 3 20914 20919 21202 3 21207 21202 20919 3 20916 21204 20917 3 21205 20917 21204 3 20917 21205 20920 3 21208 20920 21205 3 20918 21206 20919 3 21207 20919 21206 3 20918 20922 21206 3 21210 21206 20922 3 20920 21208 20921 3 21209 20921 21208 3 20921 21209 20923 3 21211 20923 21209 3 20922 20924 21210 3 21212 21210 20924 3 20923 21211 20925 3 21213 20925 21211 3 20924 20926 21212 3 21214 21212 20926 3 20925 21213 20927 3 21215 20927 21213 3 20926 20928 21214 3 21216 21214 20928 3 20927 21215 20929 3 21217 20929 21215 3 20928 20930 21216 3 21218 21216 20930 3 20929 21217 20931 3 21219 20931 21217 3 20930 20932 21218 3 21220 21218 20932 3 20931 21219 20933 3 21221 20933 21219 3 20932 20934 21220 3 21222 21220 20934 3 20933 21221 20935 3 21223 20935 21221 3 20934 20936 21222 3 21224 21222 20936 3 20935 21223 20937 3 21225 20937 21223 3 20936 20938 21224 3 21226 21224 20938 3 20937 21225 20939 3 21227 20939 21225 3 20938 20940 21226 3 21228 21226 20940 3 20939 21227 20941 3 21229 20941 21227 3 20940 20942 21228 3 21230 21228 20942 3 20941 21229 20943 3 21231 20943 21229 3 20942 20944 21230 3 21232 21230 20944 3 20943 21231 20945 3 21233 20945 21231 3 20944 20946 21232 3 21234 21232 20946 3 20945 21233 20947 3 21235 20947 21233 3 20946 20948 21234 3 21236 21234 20948 3 20947 21235 20949 3 21237 20949 21235 3 20948 20950 21236 3 21238 21236 20950 3 20949 21237 20951 3 21239 20951 21237 3 20950 20952 21238 3 21240 21238 20952 3 20951 21239 20953 3 21241 20953 21239 3 20952 20954 21240 3 21242 21240 20954 3 20953 21241 20955 3 21243 20955 21241 3 20954 20956 21242 3 21244 21242 20956 3 20955 21243 20957 3 21245 20957 21243 3 20956 20958 21244 3 21246 21244 20958 3 20957 21245 20959 3 21247 20959 21245 3 20958 20960 21246 3 21248 21246 20960 3 20959 21247 20961 3 21249 20961 21247 3 20960 20962 21248 3 21250 21248 20962 3 20961 21249 20963 3 21251 20963 21249 3 20962 20964 21250 3 21252 21250 20964 3 20963 21251 20965 3 21253 20965 21251 3 20964 20966 21252 3 21254 21252 20966 3 20965 21253 20967 3 21255 20967 21253 3 20966 20968 21254 3 21256 21254 20968 3 20967 21255 20969 3 21257 20969 21255 3 20968 20970 21258 3 20968 21258 21256 3 20969 21257 20971 3 21259 20971 21257 3 20970 20972 21260 3 20970 21260 21258 3 20971 21259 20973 3 21261 20973 21259 3 20972 20974 21262 3 20972 21262 21260 3 20973 21261 20975 3 21263 20975 21261 3 20974 20976 21264 3 20974 21264 21262 3 20975 21263 20977 3 21265 20977 21263 3 20976 20978 21266 3 20976 21266 21264 3 20977 21265 20979 3 21267 20979 21265 3 20978 20980 21268 3 20978 21268 21266 3 20979 21267 20981 3 21269 20981 21267 3 20980 20982 21270 3 20980 21270 21268 3 20981 21269 20983 3 21271 20983 21269 3 20982 20984 21272 3 20982 21272 21270 3 20983 21271 21273 3 20983 21273 20985 3 20984 20986 21274 3 20984 21274 21272 3 20985 21273 21275 3 20985 21275 20987 3 20986 20988 21276 3 20986 21276 21274 3 20987 21275 21277 3 20987 21277 20989 3 20988 20990 21278 3 20988 21278 21276 3 20989 21277 21279 3 20989 21279 20991 3 20990 20992 21280 3 20990 21280 21278 3 20991 21279 21281 3 20991 21281 20993 3 20992 20994 21282 3 20992 21282 21280 3 20993 21281 21283 3 20993 21283 20995 3 20994 20996 21284 3 20994 21284 21282 3 20995 21283 21285 3 20995 21285 20997 3 20996 20998 21286 3 20996 21286 21284 3 20997 21285 21287 3 20997 21287 20999 3 20998 21000 21288 3 20998 21288 21286 3 20999 21287 21289 3 20999 21289 21001 3 21000 21002 21290 3 21000 21290 21288 3 21001 21289 21291 3 21001 21291 21003 3 21002 21004 21292 3 21002 21292 21290 3 21003 21291 21293 3 21003 21293 21005 3 21004 21006 21294 3 21004 21294 21292 3 21005 21293 21295 3 21005 21295 21007 3 21006 21008 21296 3 21006 21296 21294 3 21007 21295 21297 3 21007 21297 21009 3 21008 21010 21298 3 21008 21298 21296 3 21009 21297 21299 3 21009 21299 21011 3 21010 21012 21300 3 21010 21300 21298 3 21011 21299 21301 3 21011 21301 21013 3 21012 21014 21302 3 21012 21302 21300 3 21013 21301 21303 3 21013 21303 21015 3 21014 21016 21304 3 21014 21304 21302 3 21015 21303 21305 3 21015 21305 21017 3 21016 21018 21306 3 21016 21306 21304 3 21017 21305 21307 3 21017 21307 21019 3 21018 21020 21308 3 21018 21308 21306 3 21019 21307 21309 3 21019 21309 21021 3 21020 21022 21310 3 21020 21310 21308 3 21021 21309 21311 3 21021 21311 21023 3 21022 21024 21312 3 21022 21312 21310 3 21023 21311 21313 3 21023 21313 21025 3 21024 21026 21314 3 21024 21314 21312 3 21025 21313 21315 3 21025 21315 21027 3 21026 21028 21316 3 21026 21316 21314 3 21027 21315 21317 3 21027 21317 21029 3 21028 21030 21318 3 21028 21318 21316 3 21029 21317 21319 3 21029 21319 21031 3 21030 21032 21320 3 21030 21320 21318 3 21031 21319 21321 3 21031 21321 21033 3 21032 21034 21322 3 21032 21322 21320 3 21033 21321 21323 3 21033 21323 21035 3 21034 21036 21324 3 21034 21324 21322 3 21035 21323 21325 3 21035 21325 21037 3 21036 21038 21326 3 21036 21326 21324 3 21037 21325 21327 3 21037 21327 21039 3 21038 21040 21328 3 21038 21328 21326 3 21039 21327 21329 3 21039 21329 21041 3 21040 21042 21330 3 21040 21330 21328 3 21041 21329 21331 3 21041 21331 21043 3 21042 21044 21332 3 21042 21332 21330 3 21043 21331 21333 3 21043 21333 21045 3 21044 21046 21334 3 21044 21334 21332 3 21045 21333 21335 3 21045 21335 21047 3 21046 21048 21336 3 21046 21336 21334 3 21047 21335 21337 3 21047 21337 21049 3 21048 21050 21338 3 21048 21338 21336 3 21049 21337 21339 3 21049 21339 21051 3 21050 21052 21340 3 21050 21340 21338 3 21051 21339 21341 3 21051 21341 21053 3 21052 21054 21342 3 21052 21342 21340 3 21053 21341 21343 3 21053 21343 21055 3 21054 21056 21344 3 21054 21344 21342 3 21055 21343 21347 3 21055 21347 21059 3 21056 21057 21345 3 21056 21345 21344 3 21057 21060 21345 3 21348 21345 21060 3 21058 21059 21346 3 21347 21346 21059 3 21058 21346 21351 3 21058 21351 21063 3 21060 21061 21348 3 21349 21348 21061 3 21061 21064 21349 3 21352 21349 21064 3 21062 21063 21350 3 21351 21350 21063 3 21062 21350 21420 3 21062 21420 21132 3 21064 21065 21352 3 21353 21352 21065 3 21065 21066 21353 3 21354 21353 21066 3 21066 21067 21354 3 21355 21354 21067 3 21067 21068 21355 3 21356 21355 21068 3 21068 21069 21356 3 21357 21356 21069 3 21069 21070 21357 3 21358 21357 21070 3 21070 21071 21358 3 21359 21358 21071 3 21071 21072 21359 3 21360 21359 21072 3 21072 21073 21360 3 21361 21360 21073 3 21073 21074 21361 3 21362 21361 21074 3 21074 21075 21362 3 21363 21362 21075 3 21075 21076 21363 3 21364 21363 21076 3 21076 21077 21364 3 21365 21364 21077 3 21077 21078 21365 3 21366 21365 21078 3 21078 21079 21366 3 21367 21366 21079 3 21079 21080 21367 3 21368 21367 21080 3 21080 21081 21368 3 21369 21368 21081 3 21081 21082 21369 3 21370 21369 21082 3 21082 21083 21370 3 21371 21370 21083 3 21083 21084 21371 3 21372 21371 21084 3 21084 21085 21372 3 21373 21372 21085 3 21085 21086 21373 3 21374 21373 21086 3 21086 21087 21374 3 21375 21374 21087 3 21087 21088 21375 3 21376 21375 21088 3 21088 21089 21376 3 21377 21376 21089 3 21089 21090 21377 3 21378 21377 21090 3 21090 21091 21378 3 21379 21378 21091 3 21091 21092 21379 3 21380 21379 21092 3 21092 21093 21380 3 21381 21380 21093 3 21093 21094 21381 3 21382 21381 21094 3 21094 21095 21382 3 21383 21382 21095 3 21095 21096 21383 3 21384 21383 21096 3 21096 21097 21384 3 21385 21384 21097 3 21097 21098 21385 3 21386 21385 21098 3 21098 21099 21386 3 21387 21386 21099 3 21099 21100 21387 3 21388 21387 21100 3 21100 21101 21388 3 21389 21388 21101 3 21101 21102 21389 3 21390 21389 21102 3 21102 21103 21390 3 21391 21390 21103 3 21103 21104 21391 3 21392 21391 21104 3 21104 21105 21392 3 21393 21392 21105 3 21105 21106 21393 3 21394 21393 21106 3 21106 21107 21394 3 21395 21394 21107 3 21107 21108 21395 3 21396 21395 21108 3 21108 21109 21396 3 21397 21396 21109 3 21109 21110 21397 3 21398 21397 21110 3 21110 21111 21398 3 21399 21398 21111 3 21111 21112 21399 3 21400 21399 21112 3 21112 21113 21400 3 21401 21400 21113 3 21113 21114 21401 3 21402 21401 21114 3 21114 21115 21402 3 21403 21402 21115 3 21115 21116 21403 3 21404 21403 21116 3 21116 21117 21404 3 21405 21404 21117 3 21117 21118 21405 3 21406 21405 21118 3 21118 21119 21406 3 21407 21406 21119 3 21119 21120 21407 3 21408 21407 21120 3 21120 21121 21408 3 21409 21408 21121 3 21121 21122 21409 3 21410 21409 21122 3 21122 21123 21410 3 21411 21410 21123 3 21123 21124 21411 3 21412 21411 21124 3 21124 21125 21412 3 21413 21412 21125 3 21125 21126 21413 3 21414 21413 21126 3 21126 21127 21414 3 21415 21414 21127 3 21127 21128 21415 3 21416 21415 21128 3 21128 21129 21416 3 21417 21416 21129 3 21129 21130 21417 3 21418 21417 21130 3 21130 21131 21418 3 21419 21418 21131 3 21131 21132 21419 3 21420 21419 21132 3 21133 21421 21134 3 21422 21134 21421 3 21133 21203 21491 3 21133 21491 21421 3 21134 21422 21135 3 21423 21135 21422 3 21135 21423 21136 3 21424 21136 21423 3 21136 21424 21137 3 21425 21137 21424 3 21137 21425 21138 3 21426 21138 21425 3 21138 21426 21139 3 21427 21139 21426 3 21139 21427 21140 3 21428 21140 21427 3 21140 21428 21141 3 21429 21141 21428 3 21141 21429 21142 3 21430 21142 21429 3 21142 21430 21143 3 21431 21143 21430 3 21143 21431 21144 3 21432 21144 21431 3 21144 21432 21145 3 21433 21145 21432 3 21145 21433 21146 3 21434 21146 21433 3 21146 21434 21147 3 21435 21147 21434 3 21147 21435 21148 3 21436 21148 21435 3 21148 21436 21149 3 21437 21149 21436 3 21149 21437 21150 3 21438 21150 21437 3 21150 21438 21151 3 21439 21151 21438 3 21151 21439 21152 3 21440 21152 21439 3 21152 21440 21153 3 21441 21153 21440 3 21153 21441 21154 3 21442 21154 21441 3 21154 21442 21155 3 21443 21155 21442 3 21155 21443 21156 3 21444 21156 21443 3 21156 21444 21157 3 21445 21157 21444 3 21157 21445 21158 3 21446 21158 21445 3 21158 21446 21159 3 21447 21159 21446 3 21159 21447 21160 3 21448 21160 21447 3 21160 21448 21161 3 21449 21161 21448 3 21161 21449 21450 3 21161 21450 21162 3 21162 21450 21451 3 21162 21451 21163 3 21163 21451 21452 3 21163 21452 21164 3 21164 21452 21453 3 21164 21453 21165 3 21165 21453 21454 3 21165 21454 21166 3 21166 21454 21455 3 21166 21455 21167 3 21167 21455 21456 3 21167 21456 21168 3 21168 21456 21457 3 21168 21457 21169 3 21169 21457 21458 3 21169 21458 21170 3 21170 21458 21459 3 21170 21459 21171 3 21171 21459 21460 3 21171 21460 21172 3 21172 21460 21461 3 21172 21461 21173 3 21173 21461 21462 3 21173 21462 21174 3 21174 21462 21463 3 21174 21463 21175 3 21175 21463 21464 3 21175 21464 21176 3 21176 21464 21465 3 21176 21465 21177 3 21177 21465 21466 3 21177 21466 21178 3 21178 21466 21467 3 21178 21467 21179 3 21179 21467 21468 3 21179 21468 21180 3 21180 21468 21469 3 21180 21469 21181 3 21181 21469 21470 3 21181 21470 21182 3 21182 21470 21471 3 21182 21471 21183 3 21183 21471 21472 3 21183 21472 21184 3 21184 21472 21473 3 21184 21473 21185 3 21185 21473 21474 3 21185 21474 21186 3 21186 21474 21475 3 21186 21475 21187 3 21187 21475 21476 3 21187 21476 21188 3 21188 21476 21477 3 21188 21477 21189 3 21189 21477 21478 3 21189 21478 21190 3 21190 21478 21479 3 21190 21479 21191 3 21191 21479 21480 3 21191 21480 21192 3 21192 21480 21481 3 21192 21481 21193 3 21193 21481 21482 3 21193 21482 21194 3 21194 21482 21483 3 21194 21483 21195 3 21195 21483 21484 3 21195 21484 21196 3 21196 21484 21485 3 21196 21485 21197 3 21197 21485 21486 3 21197 21486 21198 3 21198 21486 21487 3 21198 21487 21199 3 21199 21487 21488 3 21199 21488 21200 3 21200 21488 21489 3 21200 21489 21201 3 21201 21489 21492 3 21201 21492 21204 3 21202 21490 21491 3 21202 21491 21203 3 21202 21207 21495 3 21202 21495 21490 3 21204 21492 21493 3 21204 21493 21205 3 21205 21493 21496 3 21205 21496 21208 3 21206 21494 21495 3 21206 21495 21207 3 21206 21210 21498 3 21206 21498 21494 3 21208 21496 21497 3 21208 21497 21209 3 21209 21497 21499 3 21209 21499 21211 3 21210 21212 21500 3 21210 21500 21498 3 21211 21499 21501 3 21211 21501 21213 3 21212 21214 21502 3 21212 21502 21500 3 21213 21501 21503 3 21213 21503 21215 3 21214 21216 21504 3 21214 21504 21502 3 21215 21503 21505 3 21215 21505 21217 3 21216 21218 21506 3 21216 21506 21504 3 21217 21505 21507 3 21217 21507 21219 3 21218 21220 21508 3 21218 21508 21506 3 21219 21507 21509 3 21219 21509 21221 3 21220 21222 21510 3 21220 21510 21508 3 21221 21509 21511 3 21221 21511 21223 3 21222 21224 21512 3 21222 21512 21510 3 21223 21511 21513 3 21223 21513 21225 3 21224 21226 21514 3 21224 21514 21512 3 21225 21513 21515 3 21225 21515 21227 3 21226 21228 21516 3 21226 21516 21514 3 21227 21515 21517 3 21227 21517 21229 3 21228 21230 21518 3 21228 21518 21516 3 21229 21517 21519 3 21229 21519 21231 3 21230 21232 21520 3 21230 21520 21518 3 21231 21519 21521 3 21231 21521 21233 3 21232 21234 21522 3 21232 21522 21520 3 21233 21521 21523 3 21233 21523 21235 3 21234 21236 21524 3 21234 21524 21522 3 21235 21523 21525 3 21235 21525 21237 3 21236 21238 21524 3 21526 21524 21238 3 21237 21525 21527 3 21237 21527 21239 3 21238 21240 21526 3 21528 21526 21240 3 21239 21527 21529 3 21239 21529 21241 3 21240 21242 21528 3 21530 21528 21242 3 21241 21529 21531 3 21241 21531 21243 3 21242 21244 21530 3 21532 21530 21244 3 21243 21531 21533 3 21243 21533 21245 3 21244 21246 21532 3 21534 21532 21246 3 21245 21533 21535 3 21245 21535 21247 3 21246 21248 21534 3 21536 21534 21248 3 21247 21535 21537 3 21247 21537 21249 3 21248 21250 21536 3 21538 21536 21250 3 21249 21537 21539 3 21249 21539 21251 3 21250 21252 21538 3 21540 21538 21252 3 21251 21539 21253 3 21541 21253 21539 3 21252 21254 21540 3 21542 21540 21254 3 21253 21541 21255 3 21543 21255 21541 3 21254 21256 21542 3 21544 21542 21256 3 21255 21543 21257 3 21545 21257 21543 3 21256 21258 21544 3 21546 21544 21258 3 21257 21545 21259 3 21547 21259 21545 3 21258 21260 21546 3 21548 21546 21260 3 21259 21547 21261 3 21549 21261 21547 3 21260 21262 21548 3 21550 21548 21262 3 21261 21549 21263 3 21551 21263 21549 3 21262 21264 21550 3 21552 21550 21264 3 21263 21551 21265 3 21553 21265 21551 3 21264 21266 21552 3 21554 21552 21266 3 21265 21553 21267 3 21555 21267 21553 3 21266 21268 21554 3 21556 21554 21268 3 21267 21555 21269 3 21557 21269 21555 3 21268 21270 21556 3 21558 21556 21270 3 21269 21557 21271 3 21559 21271 21557 3 21270 21272 21558 3 21560 21558 21272 3 21271 21559 21273 3 21561 21273 21559 3 21272 21274 21560 3 21562 21560 21274 3 21273 21561 21275 3 21563 21275 21561 3 21274 21276 21562 3 21564 21562 21276 3 21275 21563 21277 3 21565 21277 21563 3 21276 21278 21564 3 21566 21564 21278 3 21277 21565 21279 3 21567 21279 21565 3 21278 21280 21566 3 21568 21566 21280 3 21279 21567 21281 3 21569 21281 21567 3 21280 21282 21568 3 21570 21568 21282 3 21281 21569 21283 3 21571 21283 21569 3 21282 21284 21570 3 21572 21570 21284 3 21283 21571 21285 3 21573 21285 21571 3 21284 21286 21572 3 21574 21572 21286 3 21285 21573 21287 3 21575 21287 21573 3 21286 21288 21574 3 21576 21574 21288 3 21287 21575 21289 3 21577 21289 21575 3 21288 21290 21576 3 21578 21576 21290 3 21289 21577 21291 3 21579 21291 21577 3 21290 21292 21578 3 21580 21578 21292 3 21291 21579 21293 3 21581 21293 21579 3 21292 21294 21580 3 21582 21580 21294 3 21293 21581 21295 3 21583 21295 21581 3 21294 21296 21582 3 21584 21582 21296 3 21295 21583 21297 3 21585 21297 21583 3 21296 21298 21584 3 21586 21584 21298 3 21297 21585 21299 3 21587 21299 21585 3 21298 21300 21586 3 21588 21586 21300 3 21299 21587 21301 3 21589 21301 21587 3 21300 21302 21588 3 21590 21588 21302 3 21301 21589 21303 3 21591 21303 21589 3 21302 21304 21590 3 21592 21590 21304 3 21303 21591 21305 3 21593 21305 21591 3 21304 21306 21592 3 21594 21592 21306 3 21305 21593 21307 3 21595 21307 21593 3 21306 21308 21594 3 21596 21594 21308 3 21307 21595 21309 3 21597 21309 21595 3 21308 21310 21596 3 21598 21596 21310 3 21309 21597 21311 3 21599 21311 21597 3 21310 21312 21598 3 21600 21598 21312 3 21311 21599 21313 3 21601 21313 21599 3 21312 21314 21600 3 21602 21600 21314 3 21313 21601 21315 3 21603 21315 21601 3 21314 21316 21602 3 21604 21602 21316 3 21315 21603 21317 3 21605 21317 21603 3 21316 21318 21604 3 21606 21604 21318 3 21317 21605 21319 3 21607 21319 21605 3 21318 21320 21606 3 21608 21606 21320 3 21319 21607 21321 3 21609 21321 21607 3 21320 21322 21608 3 21610 21608 21322 3 21321 21609 21323 3 21611 21323 21609 3 21322 21324 21610 3 21612 21610 21324 3 21323 21611 21325 3 21613 21325 21611 3 21324 21326 21612 3 21614 21612 21326 3 21325 21613 21327 3 21615 21327 21613 3 21326 21328 21616 3 21326 21616 21614 3 21327 21615 21329 3 21617 21329 21615 3 21328 21330 21618 3 21328 21618 21616 3 21329 21617 21331 3 21619 21331 21617 3 21330 21332 21620 3 21330 21620 21618 3 21331 21619 21333 3 21621 21333 21619 3 21332 21334 21622 3 21332 21622 21620 3 21333 21621 21335 3 21623 21335 21621 3 21334 21336 21624 3 21334 21624 21622 3 21335 21623 21337 3 21625 21337 21623 3 21336 21338 21626 3 21336 21626 21624 3 21337 21625 21339 3 21627 21339 21625 3 21338 21340 21628 3 21338 21628 21626 3 21339 21627 21341 3 21629 21341 21627 3 21340 21342 21630 3 21340 21630 21628 3 21341 21629 21631 3 21341 21631 21343 3 21342 21344 21632 3 21342 21632 21630 3 21343 21631 21635 3 21343 21635 21347 3 21344 21345 21633 3 21344 21633 21632 3 21345 21348 21636 3 21345 21636 21633 3 21346 21347 21635 3 21346 21635 21634 3 21346 21634 21639 3 21346 21639 21351 3 21348 21349 21637 3 21348 21637 21636 3 21349 21352 21640 3 21349 21640 21637 3 21350 21351 21639 3 21350 21639 21638 3 21350 21638 21708 3 21350 21708 21420 3 21352 21353 21641 3 21352 21641 21640 3 21353 21354 21642 3 21353 21642 21641 3 21354 21355 21643 3 21354 21643 21642 3 21355 21356 21644 3 21355 21644 21643 3 21356 21357 21645 3 21356 21645 21644 3 21357 21358 21646 3 21357 21646 21645 3 21358 21359 21647 3 21358 21647 21646 3 21359 21360 21648 3 21359 21648 21647 3 21360 21361 21649 3 21360 21649 21648 3 21361 21362 21650 3 21361 21650 21649 3 21362 21363 21651 3 21362 21651 21650 3 21363 21364 21652 3 21363 21652 21651 3 21364 21365 21653 3 21364 21653 21652 3 21365 21366 21654 3 21365 21654 21653 3 21366 21367 21655 3 21366 21655 21654 3 21367 21368 21656 3 21367 21656 21655 3 21368 21369 21657 3 21368 21657 21656 3 21369 21370 21658 3 21369 21658 21657 3 21370 21371 21659 3 21370 21659 21658 3 21371 21372 21660 3 21371 21660 21659 3 21372 21373 21661 3 21372 21661 21660 3 21373 21374 21662 3 21373 21662 21661 3 21374 21375 21663 3 21374 21663 21662 3 21375 21376 21664 3 21375 21664 21663 3 21376 21377 21665 3 21376 21665 21664 3 21377 21378 21666 3 21377 21666 21665 3 21378 21379 21667 3 21378 21667 21666 3 21379 21380 21668 3 21379 21668 21667 3 21380 21381 21669 3 21380 21669 21668 3 21381 21382 21670 3 21381 21670 21669 3 21382 21383 21671 3 21382 21671 21670 3 21383 21384 21672 3 21383 21672 21671 3 21384 21385 21673 3 21384 21673 21672 3 21385 21386 21674 3 21385 21674 21673 3 21386 21387 21675 3 21386 21675 21674 3 21387 21388 21676 3 21387 21676 21675 3 21388 21389 21677 3 21388 21677 21676 3 21389 21390 21678 3 21389 21678 21677 3 21390 21391 21679 3 21390 21679 21678 3 21391 21392 21680 3 21391 21680 21679 3 21392 21393 21681 3 21392 21681 21680 3 21393 21394 21682 3 21393 21682 21681 3 21394 21395 21683 3 21394 21683 21682 3 21395 21396 21684 3 21395 21684 21683 3 21396 21397 21685 3 21396 21685 21684 3 21397 21398 21686 3 21397 21686 21685 3 21398 21399 21687 3 21398 21687 21686 3 21399 21400 21688 3 21399 21688 21687 3 21400 21401 21689 3 21400 21689 21688 3 21401 21402 21690 3 21401 21690 21689 3 21402 21403 21691 3 21402 21691 21690 3 21403 21404 21692 3 21403 21692 21691 3 21404 21405 21693 3 21404 21693 21692 3 21405 21406 21694 3 21405 21694 21693 3 21406 21407 21695 3 21406 21695 21694 3 21407 21408 21696 3 21407 21696 21695 3 21408 21409 21697 3 21408 21697 21696 3 21409 21410 21698 3 21409 21698 21697 3 21410 21411 21699 3 21410 21699 21698 3 21411 21412 21700 3 21411 21700 21699 3 21412 21413 21701 3 21412 21701 21700 3 21413 21414 21702 3 21413 21702 21701 3 21414 21415 21703 3 21414 21703 21702 3 21415 21416 21704 3 21415 21704 21703 3 21416 21417 21704 3 21705 21704 21417 3 21417 21418 21705 3 21706 21705 21418 3 21418 21419 21706 3 21707 21706 21419 3 21419 21420 21707 3 21708 21707 21420 3 21421 21709 21710 3 21421 21710 21422 3 21421 21491 21709 3 21779 21709 21491 3 21422 21710 21711 3 21422 21711 21423 3 21423 21711 21712 3 21423 21712 21424 3 21424 21712 21713 3 21424 21713 21425 3 21425 21713 21714 3 21425 21714 21426 3 21426 21714 21715 3 21426 21715 21427 3 21427 21715 21716 3 21427 21716 21428 3 21428 21716 21717 3 21428 21717 21429 3 21429 21717 21718 3 21429 21718 21430 3 21430 21718 21719 3 21430 21719 21431 3 21431 21719 21432 3 21720 21432 21719 3 21432 21720 21433 3 21721 21433 21720 3 21433 21721 21434 3 21722 21434 21721 3 21434 21722 21435 3 21723 21435 21722 3 21435 21723 21436 3 21724 21436 21723 3 21436 21724 21437 3 21725 21437 21724 3 21437 21725 21438 3 21726 21438 21725 3 21438 21726 21439 3 21727 21439 21726 3 21439 21727 21440 3 21728 21440 21727 3 21440 21728 21441 3 21729 21441 21728 3 21441 21729 21442 3 21730 21442 21729 3 21442 21730 21443 3 21731 21443 21730 3 21443 21731 21444 3 21732 21444 21731 3 21444 21732 21445 3 21733 21445 21732 3 21445 21733 21446 3 21734 21446 21733 3 21446 21734 21447 3 21735 21447 21734 3 21447 21735 21448 3 21736 21448 21735 3 21448 21736 21449 3 21737 21449 21736 3 21449 21737 21450 3 21738 21450 21737 3 21450 21738 21451 3 21739 21451 21738 3 21451 21739 21452 3 21740 21452 21739 3 21452 21740 21453 3 21741 21453 21740 3 21453 21741 21454 3 21742 21454 21741 3 21454 21742 21455 3 21743 21455 21742 3 21455 21743 21456 3 21744 21456 21743 3 21456 21744 21457 3 21745 21457 21744 3 21457 21745 21458 3 21746 21458 21745 3 21458 21746 21459 3 21747 21459 21746 3 21459 21747 21460 3 21748 21460 21747 3 21460 21748 21461 3 21749 21461 21748 3 21461 21749 21462 3 21750 21462 21749 3 21462 21750 21463 3 21751 21463 21750 3 21463 21751 21464 3 21752 21464 21751 3 21464 21752 21465 3 21753 21465 21752 3 21465 21753 21466 3 21754 21466 21753 3 21466 21754 21467 3 21755 21467 21754 3 21467 21755 21468 3 21756 21468 21755 3 21468 21756 21469 3 21757 21469 21756 3 21469 21757 21470 3 21758 21470 21757 3 21470 21758 21471 3 21759 21471 21758 3 21471 21759 21472 3 21760 21472 21759 3 21472 21760 21473 3 21761 21473 21760 3 21473 21761 21474 3 21762 21474 21761 3 21474 21762 21475 3 21763 21475 21762 3 21475 21763 21476 3 21764 21476 21763 3 21476 21764 21477 3 21765 21477 21764 3 21477 21765 21478 3 21766 21478 21765 3 21478 21766 21479 3 21767 21479 21766 3 21479 21767 21480 3 21768 21480 21767 3 21480 21768 21481 3 21769 21481 21768 3 21481 21769 21482 3 21770 21482 21769 3 21482 21770 21483 3 21771 21483 21770 3 21483 21771 21484 3 21772 21484 21771 3 21484 21772 21485 3 21773 21485 21772 3 21485 21773 21486 3 21774 21486 21773 3 21486 21774 21487 3 21775 21487 21774 3 21487 21775 21488 3 21776 21488 21775 3 21488 21776 21489 3 21777 21489 21776 3 21489 21777 21492 3 21780 21492 21777 3 21490 21778 21491 3 21779 21491 21778 3 21490 21495 21778 3 21783 21778 21495 3 21492 21780 21493 3 21781 21493 21780 3 21493 21781 21496 3 21784 21496 21781 3 21494 21782 21495 3 21783 21495 21782 3 21494 21498 21782 3 21786 21782 21498 3 21496 21784 21497 3 21785 21497 21784 3 21497 21785 21499 3 21787 21499 21785 3 21498 21500 21786 3 21788 21786 21500 3 21499 21787 21501 3 21789 21501 21787 3 21500 21502 21788 3 21790 21788 21502 3 21501 21789 21503 3 21791 21503 21789 3 21502 21504 21790 3 21792 21790 21504 3 21503 21791 21505 3 21793 21505 21791 3 21504 21506 21792 3 21794 21792 21506 3 21505 21793 21507 3 21795 21507 21793 3 21506 21508 21796 3 21506 21796 21794 3 21507 21795 21509 3 21797 21509 21795 3 21508 21510 21798 3 21508 21798 21796 3 21509 21797 21511 3 21799 21511 21797 3 21510 21512 21800 3 21510 21800 21798 3 21511 21799 21513 3 21801 21513 21799 3 21512 21514 21802 3 21512 21802 21800 3 21513 21801 21515 3 21803 21515 21801 3 21514 21516 21804 3 21514 21804 21802 3 21515 21803 21517 3 21805 21517 21803 3 21516 21518 21806 3 21516 21806 21804 3 21517 21805 21519 3 21807 21519 21805 3 21518 21520 21808 3 21518 21808 21806 3 21519 21807 21521 3 21809 21521 21807 3 21520 21522 21810 3 21520 21810 21808 3 21521 21809 21523 3 21811 21523 21809 3 21522 21524 21812 3 21522 21812 21810 3 21523 21811 21813 3 21523 21813 21525 3 21524 21526 21814 3 21524 21814 21812 3 21525 21813 21815 3 21525 21815 21527 3 21526 21528 21816 3 21526 21816 21814 3 21527 21815 21817 3 21527 21817 21529 3 21528 21530 21818 3 21528 21818 21816 3 21529 21817 21819 3 21529 21819 21531 3 21530 21532 21820 3 21530 21820 21818 3 21531 21819 21821 3 21531 21821 21533 3 21532 21534 21822 3 21532 21822 21820 3 21533 21821 21823 3 21533 21823 21535 3 21534 21536 21824 3 21534 21824 21822 3 21535 21823 21825 3 21535 21825 21537 3 21536 21538 21826 3 21536 21826 21824 3 21537 21825 21827 3 21537 21827 21539 3 21538 21540 21828 3 21538 21828 21826 3 21539 21827 21829 3 21539 21829 21541 3 21540 21542 21830 3 21540 21830 21828 3 21541 21829 21831 3 21541 21831 21543 3 21542 21544 21832 3 21542 21832 21830 3 21543 21831 21833 3 21543 21833 21545 3 21544 21546 21834 3 21544 21834 21832 3 21545 21833 21835 3 21545 21835 21547 3 21546 21548 21836 3 21546 21836 21834 3 21547 21835 21837 3 21547 21837 21549 3 21548 21550 21838 3 21548 21838 21836 3 21549 21837 21839 3 21549 21839 21551 3 21550 21552 21840 3 21550 21840 21838 3 21551 21839 21841 3 21551 21841 21553 3 21552 21554 21842 3 21552 21842 21840 3 21553 21841 21843 3 21553 21843 21555 3 21554 21556 21844 3 21554 21844 21842 3 21555 21843 21845 3 21555 21845 21557 3 21556 21558 21846 3 21556 21846 21844 3 21557 21845 21847 3 21557 21847 21559 3 21558 21560 21848 3 21558 21848 21846 3 21559 21847 21849 3 21559 21849 21561 3 21560 21562 21850 3 21560 21850 21848 3 21561 21849 21851 3 21561 21851 21563 3 21562 21564 21852 3 21562 21852 21850 3 21563 21851 21853 3 21563 21853 21565 3 21564 21566 21854 3 21564 21854 21852 3 21565 21853 21855 3 21565 21855 21567 3 21566 21568 21856 3 21566 21856 21854 3 21567 21855 21857 3 21567 21857 21569 3 21568 21570 21858 3 21568 21858 21856 3 21569 21857 21859 3 21569 21859 21571 3 21570 21572 21860 3 21570 21860 21858 3 21571 21859 21861 3 21571 21861 21573 3 21572 21574 21862 3 21572 21862 21860 3 21573 21861 21863 3 21573 21863 21575 3 21574 21576 21864 3 21574 21864 21862 3 21575 21863 21865 3 21575 21865 21577 3 21576 21578 21866 3 21576 21866 21864 3 21577 21865 21867 3 21577 21867 21579 3 21578 21580 21868 3 21578 21868 21866 3 21579 21867 21869 3 21579 21869 21581 3 21580 21582 21870 3 21580 21870 21868 3 21581 21869 21871 3 21581 21871 21583 3 21582 21584 21872 3 21582 21872 21870 3 21583 21871 21873 3 21583 21873 21585 3 21584 21586 21874 3 21584 21874 21872 3 21585 21873 21875 3 21585 21875 21587 3 21586 21588 21876 3 21586 21876 21874 3 21587 21875 21877 3 21587 21877 21589 3 21588 21590 21878 3 21588 21878 21876 3 21589 21877 21879 3 21589 21879 21591 3 21590 21592 21880 3 21590 21880 21878 3 21591 21879 21881 3 21591 21881 21593 3 21592 21594 21882 3 21592 21882 21880 3 21593 21881 21883 3 21593 21883 21595 3 21594 21596 21884 3 21594 21884 21882 3 21595 21883 21885 3 21595 21885 21597 3 21596 21598 21884 3 21886 21884 21598 3 21597 21885 21887 3 21597 21887 21599 3 21598 21600 21886 3 21888 21886 21600 3 21599 21887 21889 3 21599 21889 21601 3 21600 21602 21888 3 21890 21888 21602 3 21601 21889 21891 3 21601 21891 21603 3 21602 21604 21890 3 21892 21890 21604 3 21603 21891 21893 3 21603 21893 21605 3 21604 21606 21892 3 21894 21892 21606 3 21605 21893 21895 3 21605 21895 21607 3 21606 21608 21894 3 21896 21894 21608 3 21607 21895 21897 3 21607 21897 21609 3 21608 21610 21896 3 21898 21896 21610 3 21609 21897 21899 3 21609 21899 21611 3 21610 21612 21898 3 21900 21898 21612 3 21611 21899 21901 3 21611 21901 21613 3 21612 21614 21900 3 21902 21900 21614 3 21613 21901 21615 3 21903 21615 21901 3 21614 21616 21902 3 21904 21902 21616 3 21615 21903 21617 3 21905 21617 21903 3 21616 21618 21904 3 21906 21904 21618 3 21617 21905 21619 3 21907 21619 21905 3 21618 21620 21906 3 21908 21906 21620 3 21619 21907 21621 3 21909 21621 21907 3 21620 21622 21908 3 21910 21908 21622 3 21621 21909 21623 3 21911 21623 21909 3 21622 21624 21910 3 21912 21910 21624 3 21623 21911 21625 3 21913 21625 21911 3 21624 21626 21912 3 21914 21912 21626 3 21625 21913 21627 3 21915 21627 21913 3 21626 21628 21914 3 21916 21914 21628 3 21627 21915 21629 3 21917 21629 21915 3 21628 21630 21916 3 21918 21916 21630 3 21629 21917 21631 3 21919 21631 21917 3 21630 21632 21918 3 21920 21918 21632 3 21631 21919 21635 3 21923 21635 21919 3 21632 21633 21920 3 21921 21920 21633 3 21633 21636 21921 3 21924 21921 21636 3 21634 21635 21922 3 21923 21922 21635 3 21634 21922 21639 3 21927 21639 21922 3 21636 21637 21924 3 21925 21924 21637 3 21637 21640 21925 3 21928 21925 21640 3 21638 21639 21926 3 21927 21926 21639 3 21638 21926 21708 3 21996 21708 21926 3 21640 21641 21928 3 21929 21928 21641 3 21641 21642 21929 3 21930 21929 21642 3 21642 21643 21930 3 21931 21930 21643 3 21643 21644 21931 3 21932 21931 21644 3 21644 21645 21932 3 21933 21932 21645 3 21645 21646 21933 3 21934 21933 21646 3 21646 21647 21934 3 21935 21934 21647 3 21647 21648 21935 3 21936 21935 21648 3 21648 21649 21936 3 21937 21936 21649 3 21649 21650 21937 3 21938 21937 21650 3 21650 21651 21938 3 21939 21938 21651 3 21651 21652 21939 3 21940 21939 21652 3 21652 21653 21940 3 21941 21940 21653 3 21653 21654 21941 3 21942 21941 21654 3 21654 21655 21942 3 21943 21942 21655 3 21655 21656 21943 3 21944 21943 21656 3 21656 21657 21944 3 21945 21944 21657 3 21657 21658 21945 3 21946 21945 21658 3 21658 21659 21946 3 21947 21946 21659 3 21659 21660 21947 3 21948 21947 21660 3 21660 21661 21948 3 21949 21948 21661 3 21661 21662 21949 3 21950 21949 21662 3 21662 21663 21950 3 21951 21950 21663 3 21663 21664 21951 3 21952 21951 21664 3 21664 21665 21952 3 21953 21952 21665 3 21665 21666 21953 3 21954 21953 21666 3 21666 21667 21954 3 21955 21954 21667 3 21667 21668 21955 3 21956 21955 21668 3 21668 21669 21956 3 21957 21956 21669 3 21669 21670 21957 3 21958 21957 21670 3 21670 21671 21958 3 21959 21958 21671 3 21671 21672 21959 3 21960 21959 21672 3 21672 21673 21960 3 21961 21960 21673 3 21673 21674 21961 3 21962 21961 21674 3 21674 21675 21962 3 21963 21962 21675 3 21675 21676 21963 3 21964 21963 21676 3 21676 21677 21964 3 21965 21964 21677 3 21677 21678 21965 3 21966 21965 21678 3 21678 21679 21966 3 21967 21966 21679 3 21679 21680 21967 3 21968 21967 21680 3 21680 21681 21968 3 21969 21968 21681 3 21681 21682 21969 3 21970 21969 21682 3 21682 21683 21970 3 21971 21970 21683 3 21683 21684 21971 3 21972 21971 21684 3 21684 21685 21972 3 21973 21972 21685 3 21685 21686 21973 3 21974 21973 21686 3 21686 21687 21974 3 21975 21974 21687 3 21687 21688 21976 3 21687 21976 21975 3 21688 21689 21977 3 21688 21977 21976 3 21689 21690 21978 3 21689 21978 21977 3 21690 21691 21979 3 21690 21979 21978 3 21691 21692 21980 3 21691 21980 21979 3 21692 21693 21981 3 21692 21981 21980 3 21693 21694 21982 3 21693 21982 21981 3 21694 21695 21983 3 21694 21983 21982 3 21695 21696 21984 3 21695 21984 21983 3 21696 21697 21985 3 21696 21985 21984 3 21697 21698 21986 3 21697 21986 21985 3 21698 21699 21987 3 21698 21987 21986 3 21699 21700 21988 3 21699 21988 21987 3 21700 21701 21989 3 21700 21989 21988 3 21701 21702 21990 3 21701 21990 21989 3 21702 21703 21991 3 21702 21991 21990 3 21703 21704 21992 3 21703 21992 21991 3 21704 21705 21993 3 21704 21993 21992 3 21705 21706 21994 3 21705 21994 21993 3 21706 21707 21995 3 21706 21995 21994 3 21707 21708 21996 3 21707 21996 21995 3 21709 21997 21998 3 21709 21998 21710 3 21709 21779 22067 3 21709 22067 21997 3 21710 21998 21999 3 21710 21999 21711 3 21711 21999 22000 3 21711 22000 21712 3 21712 22000 22001 3 21712 22001 21713 3 21713 22001 22002 3 21713 22002 21714 3 21714 22002 22003 3 21714 22003 21715 3 21715 22003 22004 3 21715 22004 21716 3 21716 22004 22005 3 21716 22005 21717 3 21717 22005 22006 3 21717 22006 21718 3 21718 22006 22007 3 21718 22007 21719 3 21719 22007 22008 3 21719 22008 21720 3 21720 22008 22009 3 21720 22009 21721 3 21721 22009 22010 3 21721 22010 21722 3 21722 22010 22011 3 21722 22011 21723 3 21723 22011 22012 3 21723 22012 21724 3 21724 22012 22013 3 21724 22013 21725 3 21725 22013 22014 3 21725 22014 21726 3 21726 22014 22015 3 21726 22015 21727 3 21727 22015 22016 3 21727 22016 21728 3 21728 22016 22017 3 21728 22017 21729 3 21729 22017 22018 3 21729 22018 21730 3 21730 22018 22019 3 21730 22019 21731 3 21731 22019 22020 3 21731 22020 21732 3 21732 22020 22021 3 21732 22021 21733 3 21733 22021 22022 3 21733 22022 21734 3 21734 22022 22023 3 21734 22023 21735 3 21735 22023 22024 3 21735 22024 21736 3 21736 22024 22025 3 21736 22025 21737 3 21737 22025 22026 3 21737 22026 21738 3 21738 22026 22027 3 21738 22027 21739 3 21739 22027 22028 3 21739 22028 21740 3 21740 22028 22029 3 21740 22029 21741 3 21741 22029 22030 3 21741 22030 21742 3 21742 22030 22031 3 21742 22031 21743 3 21743 22031 22032 3 21743 22032 21744 3 21744 22032 22033 3 21744 22033 21745 3 21745 22033 22034 3 21745 22034 21746 3 21746 22034 22035 3 21746 22035 21747 3 21747 22035 22036 3 21747 22036 21748 3 21748 22036 22037 3 21748 22037 21749 3 21749 22037 22038 3 21749 22038 21750 3 21750 22038 22039 3 21750 22039 21751 3 21751 22039 22040 3 21751 22040 21752 3 21752 22040 22041 3 21752 22041 21753 3 21753 22041 22042 3 21753 22042 21754 3 21754 22042 22043 3 21754 22043 21755 3 21755 22043 22044 3 21755 22044 21756 3 21756 22044 22045 3 21756 22045 21757 3 21757 22045 22046 3 21757 22046 21758 3 21758 22046 22047 3 21758 22047 21759 3 21759 22047 22048 3 21759 22048 21760 3 21760 22048 22049 3 21760 22049 21761 3 21761 22049 22050 3 21761 22050 21762 3 21762 22050 22051 3 21762 22051 21763 3 21763 22051 22052 3 21763 22052 21764 3 21764 22052 22053 3 21764 22053 21765 3 21765 22053 22054 3 21765 22054 21766 3 21766 22054 22055 3 21766 22055 21767 3 21767 22055 22056 3 21767 22056 21768 3 21768 22056 22057 3 21768 22057 21769 3 21769 22057 22058 3 21769 22058 21770 3 21770 22058 22059 3 21770 22059 21771 3 21771 22059 22060 3 21771 22060 21772 3 21772 22060 22061 3 21772 22061 21773 3 21773 22061 22062 3 21773 22062 21774 3 21774 22062 22063 3 21774 22063 21775 3 21775 22063 22064 3 21775 22064 21776 3 21776 22064 22065 3 21776 22065 21777 3 21777 22065 22068 3 21777 22068 21780 3 21778 22066 22067 3 21778 22067 21779 3 21778 21783 22066 3 22071 22066 21783 3 21780 22068 22069 3 21780 22069 21781 3 21781 22069 22072 3 21781 22072 21784 3 21782 22070 22071 3 21782 22071 21783 3 21782 21786 22070 3 22074 22070 21786 3 21784 22072 22073 3 21784 22073 21785 3 21785 22073 22075 3 21785 22075 21787 3 21786 21788 22074 3 22076 22074 21788 3 21787 22075 22077 3 21787 22077 21789 3 21788 21790 22076 3 22078 22076 21790 3 21789 22077 22079 3 21789 22079 21791 3 21790 21792 22078 3 22080 22078 21792 3 21791 22079 22081 3 21791 22081 21793 3 21792 21794 22080 3 22082 22080 21794 3 21793 22081 22083 3 21793 22083 21795 3 21794 21796 22082 3 22084 22082 21796 3 21795 22083 21797 3 22085 21797 22083 3 21796 21798 22084 3 22086 22084 21798 3 21797 22085 21799 3 22087 21799 22085 3 21798 21800 22086 3 22088 22086 21800 3 21799 22087 21801 3 22089 21801 22087 3 21800 21802 22088 3 22090 22088 21802 3 21801 22089 21803 3 22091 21803 22089 3 21802 21804 22090 3 22092 22090 21804 3 21803 22091 21805 3 22093 21805 22091 3 21804 21806 22092 3 22094 22092 21806 3 21805 22093 21807 3 22095 21807 22093 3 21806 21808 22094 3 22096 22094 21808 3 21807 22095 21809 3 22097 21809 22095 3 21808 21810 22096 3 22098 22096 21810 3 21809 22097 21811 3 22099 21811 22097 3 21810 21812 22098 3 22100 22098 21812 3 21811 22099 21813 3 22101 21813 22099 3 21812 21814 22100 3 22102 22100 21814 3 21813 22101 21815 3 22103 21815 22101 3 21814 21816 22102 3 22104 22102 21816 3 21815 22103 21817 3 22105 21817 22103 3 21816 21818 22104 3 22106 22104 21818 3 21817 22105 21819 3 22107 21819 22105 3 21818 21820 22106 3 22108 22106 21820 3 21819 22107 21821 3 22109 21821 22107 3 21820 21822 22108 3 22110 22108 21822 3 21821 22109 21823 3 22111 21823 22109 3 21822 21824 22110 3 22112 22110 21824 3 21823 22111 21825 3 22113 21825 22111 3 21824 21826 22112 3 22114 22112 21826 3 21825 22113 21827 3 22115 21827 22113 3 21826 21828 22114 3 22116 22114 21828 3 21827 22115 21829 3 22117 21829 22115 3 21828 21830 22116 3 22118 22116 21830 3 21829 22117 21831 3 22119 21831 22117 3 21830 21832 22118 3 22120 22118 21832 3 21831 22119 21833 3 22121 21833 22119 3 21832 21834 22120 3 22122 22120 21834 3 21833 22121 21835 3 22123 21835 22121 3 21834 21836 22122 3 22124 22122 21836 3 21835 22123 21837 3 22125 21837 22123 3 21836 21838 22124 3 22126 22124 21838 3 21837 22125 21839 3 22127 21839 22125 3 21838 21840 22126 3 22128 22126 21840 3 21839 22127 21841 3 22129 21841 22127 3 21840 21842 22128 3 22130 22128 21842 3 21841 22129 21843 3 22131 21843 22129 3 21842 21844 22130 3 22132 22130 21844 3 21843 22131 21845 3 22133 21845 22131 3 21844 21846 22132 3 22134 22132 21846 3 21845 22133 21847 3 22135 21847 22133 3 21846 21848 22134 3 22136 22134 21848 3 21847 22135 21849 3 22137 21849 22135 3 21848 21850 22136 3 22138 22136 21850 3 21849 22137 21851 3 22139 21851 22137 3 21850 21852 22138 3 22140 22138 21852 3 21851 22139 21853 3 22141 21853 22139 3 21852 21854 22140 3 22142 22140 21854 3 21853 22141 21855 3 22143 21855 22141 3 21854 21856 22142 3 22144 22142 21856 3 21855 22143 21857 3 22145 21857 22143 3 21856 21858 22144 3 22146 22144 21858 3 21857 22145 21859 3 22147 21859 22145 3 21858 21860 22146 3 22148 22146 21860 3 21859 22147 21861 3 22149 21861 22147 3 21860 21862 22148 3 22150 22148 21862 3 21861 22149 21863 3 22151 21863 22149 3 21862 21864 22150 3 22152 22150 21864 3 21863 22151 21865 3 22153 21865 22151 3 21864 21866 22152 3 22154 22152 21866 3 21865 22153 21867 3 22155 21867 22153 3 21866 21868 22154 3 22156 22154 21868 3 21867 22155 21869 3 22157 21869 22155 3 21868 21870 22158 3 21868 22158 22156 3 21869 22157 21871 3 22159 21871 22157 3 21870 21872 22160 3 21870 22160 22158 3 21871 22159 21873 3 22161 21873 22159 3 21872 21874 22162 3 21872 22162 22160 3 21873 22161 21875 3 22163 21875 22161 3 21874 21876 22164 3 21874 22164 22162 3 21875 22163 21877 3 22165 21877 22163 3 21876 21878 22166 3 21876 22166 22164 3 21877 22165 21879 3 22167 21879 22165 3 21878 21880 22168 3 21878 22168 22166 3 21879 22167 21881 3 22169 21881 22167 3 21880 21882 22170 3 21880 22170 22168 3 21881 22169 21883 3 22171 21883 22169 3 21882 21884 22172 3 21882 22172 22170 3 21883 22171 21885 3 22173 21885 22171 3 21884 21886 22174 3 21884 22174 22172 3 21885 22173 21887 3 22175 21887 22173 3 21886 21888 22176 3 21886 22176 22174 3 21887 22175 22177 3 21887 22177 21889 3 21888 21890 22178 3 21888 22178 22176 3 21889 22177 22179 3 21889 22179 21891 3 21890 21892 22180 3 21890 22180 22178 3 21891 22179 22181 3 21891 22181 21893 3 21892 21894 22182 3 21892 22182 22180 3 21893 22181 22183 3 21893 22183 21895 3 21894 21896 22184 3 21894 22184 22182 3 21895 22183 22185 3 21895 22185 21897 3 21896 21898 22186 3 21896 22186 22184 3 21897 22185 22187 3 21897 22187 21899 3 21898 21900 22188 3 21898 22188 22186 3 21899 22187 22189 3 21899 22189 21901 3 21900 21902 22190 3 21900 22190 22188 3 21901 22189 22191 3 21901 22191 21903 3 21902 21904 22192 3 21902 22192 22190 3 21903 22191 22193 3 21903 22193 21905 3 21904 21906 22194 3 21904 22194 22192 3 21905 22193 22195 3 21905 22195 21907 3 21906 21908 22196 3 21906 22196 22194 3 21907 22195 22197 3 21907 22197 21909 3 21908 21910 22198 3 21908 22198 22196 3 21909 22197 22199 3 21909 22199 21911 3 21910 21912 22200 3 21910 22200 22198 3 21911 22199 22201 3 21911 22201 21913 3 21912 21914 22202 3 21912 22202 22200 3 21913 22201 22203 3 21913 22203 21915 3 21914 21916 22204 3 21914 22204 22202 3 21915 22203 22205 3 21915 22205 21917 3 21916 21918 22206 3 21916 22206 22204 3 21917 22205 22207 3 21917 22207 21919 3 21918 21920 22208 3 21918 22208 22206 3 21919 22207 22211 3 21919 22211 21923 3 21920 21921 22209 3 21920 22209 22208 3 21921 21924 22212 3 21921 22212 22209 3 21922 21923 22211 3 21922 22211 22210 3 21922 22210 22215 3 21922 22215 21927 3 21924 21925 22213 3 21924 22213 22212 3 21925 21928 22216 3 21925 22216 22213 3 21926 21927 22215 3 21926 22215 22214 3 21926 22214 22284 3 21926 22284 21996 3 21928 21929 22217 3 21928 22217 22216 3 21929 21930 22218 3 21929 22218 22217 3 21930 21931 22219 3 21930 22219 22218 3 21931 21932 22220 3 21931 22220 22219 3 21932 21933 22221 3 21932 22221 22220 3 21933 21934 22222 3 21933 22222 22221 3 21934 21935 22223 3 21934 22223 22222 3 21935 21936 22224 3 21935 22224 22223 3 21936 21937 22225 3 21936 22225 22224 3 21937 21938 22226 3 21937 22226 22225 3 21938 21939 22227 3 21938 22227 22226 3 21939 21940 22228 3 21939 22228 22227 3 21940 21941 22229 3 21940 22229 22228 3 21941 21942 22230 3 21941 22230 22229 3 21942 21943 22231 3 21942 22231 22230 3 21943 21944 22232 3 21943 22232 22231 3 21944 21945 22233 3 21944 22233 22232 3 21945 21946 22234 3 21945 22234 22233 3 21946 21947 22235 3 21946 22235 22234 3 21947 21948 22236 3 21947 22236 22235 3 21948 21949 22237 3 21948 22237 22236 3 21949 21950 22238 3 21949 22238 22237 3 21950 21951 22239 3 21950 22239 22238 3 21951 21952 22240 3 21951 22240 22239 3 21952 21953 22241 3 21952 22241 22240 3 21953 21954 22242 3 21953 22242 22241 3 21954 21955 22243 3 21954 22243 22242 3 21955 21956 22244 3 21955 22244 22243 3 21956 21957 22245 3 21956 22245 22244 3 21957 21958 22246 3 21957 22246 22245 3 21958 21959 22247 3 21958 22247 22246 3 21959 21960 22248 3 21959 22248 22247 3 21960 21961 22248 3 22249 22248 21961 3 21961 21962 22249 3 22250 22249 21962 3 21962 21963 22250 3 22251 22250 21963 3 21963 21964 22251 3 22252 22251 21964 3 21964 21965 22252 3 22253 22252 21965 3 21965 21966 22253 3 22254 22253 21966 3 21966 21967 22254 3 22255 22254 21967 3 21967 21968 22255 3 22256 22255 21968 3 21968 21969 22256 3 22257 22256 21969 3 21969 21970 22257 3 22258 22257 21970 3 21970 21971 22258 3 22259 22258 21971 3 21971 21972 22259 3 22260 22259 21972 3 21972 21973 22260 3 22261 22260 21973 3 21973 21974 22261 3 22262 22261 21974 3 21974 21975 22262 3 22263 22262 21975 3 21975 21976 22263 3 22264 22263 21976 3 21976 21977 22264 3 22265 22264 21977 3 21977 21978 22265 3 22266 22265 21978 3 21978 21979 22266 3 22267 22266 21979 3 21979 21980 22267 3 22268 22267 21980 3 21980 21981 22268 3 22269 22268 21981 3 21981 21982 22269 3 22270 22269 21982 3 21982 21983 22270 3 22271 22270 21983 3 21983 21984 22271 3 22272 22271 21984 3 21984 21985 22272 3 22273 22272 21985 3 21985 21986 22273 3 22274 22273 21986 3 21986 21987 22274 3 22275 22274 21987 3 21987 21988 22275 3 22276 22275 21988 3 21988 21989 22276 3 22277 22276 21989 3 21989 21990 22277 3 22278 22277 21990 3 21990 21991 22278 3 22279 22278 21991 3 21991 21992 22279 3 22280 22279 21992 3 21992 21993 22280 3 22281 22280 21993 3 21993 21994 22281 3 22282 22281 21994 3 21994 21995 22282 3 22283 22282 21995 3 21995 21996 22283 3 22284 22283 21996 3 21997 22285 21998 3 22286 21998 22285 3 21997 22067 22285 3 22355 22285 22067 3 21998 22286 21999 3 22287 21999 22286 3 21999 22287 22000 3 22288 22000 22287 3 22000 22288 22001 3 22289 22001 22288 3 22001 22289 22002 3 22290 22002 22289 3 22002 22290 22003 3 22291 22003 22290 3 22003 22291 22004 3 22292 22004 22291 3 22004 22292 22005 3 22293 22005 22292 3 22005 22293 22006 3 22294 22006 22293 3 22006 22294 22007 3 22295 22007 22294 3 22007 22295 22008 3 22296 22008 22295 3 22008 22296 22009 3 22297 22009 22296 3 22009 22297 22010 3 22298 22010 22297 3 22010 22298 22011 3 22299 22011 22298 3 22011 22299 22012 3 22300 22012 22299 3 22012 22300 22013 3 22301 22013 22300 3 22013 22301 22014 3 22302 22014 22301 3 22014 22302 22015 3 22303 22015 22302 3 22015 22303 22016 3 22304 22016 22303 3 22016 22304 22017 3 22305 22017 22304 3 22017 22305 22018 3 22306 22018 22305 3 22018 22306 22019 3 22307 22019 22306 3 22019 22307 22020 3 22308 22020 22307 3 22020 22308 22021 3 22309 22021 22308 3 22021 22309 22022 3 22310 22022 22309 3 22022 22310 22023 3 22311 22023 22310 3 22023 22311 22024 3 22312 22024 22311 3 22024 22312 22025 3 22313 22025 22312 3 22025 22313 22026 3 22314 22026 22313 3 22026 22314 22027 3 22315 22027 22314 3 22027 22315 22028 3 22316 22028 22315 3 22028 22316 22029 3 22317 22029 22316 3 22029 22317 22030 3 22318 22030 22317 3 22030 22318 22031 3 22319 22031 22318 3 22031 22319 22032 3 22320 22032 22319 3 22032 22320 22033 3 22321 22033 22320 3 22033 22321 22034 3 22322 22034 22321 3 22034 22322 22035 3 22323 22035 22322 3 22035 22323 22036 3 22324 22036 22323 3 22036 22324 22037 3 22325 22037 22324 3 22037 22325 22038 3 22326 22038 22325 3 22038 22326 22039 3 22327 22039 22326 3 22039 22327 22040 3 22328 22040 22327 3 22040 22328 22041 3 22329 22041 22328 3 22041 22329 22042 3 22330 22042 22329 3 22042 22330 22043 3 22331 22043 22330 3 22043 22331 22044 3 22332 22044 22331 3 22044 22332 22045 3 22333 22045 22332 3 22045 22333 22046 3 22334 22046 22333 3 22046 22334 22047 3 22335 22047 22334 3 22047 22335 22048 3 22336 22048 22335 3 22048 22336 22049 3 22337 22049 22336 3 22049 22337 22050 3 22338 22050 22337 3 22050 22338 22051 3 22339 22051 22338 3 22051 22339 22052 3 22340 22052 22339 3 22052 22340 22053 3 22341 22053 22340 3 22053 22341 22054 3 22342 22054 22341 3 22054 22342 22055 3 22343 22055 22342 3 22055 22343 22056 3 22344 22056 22343 3 22056 22344 22057 3 22345 22057 22344 3 22057 22345 22058 3 22346 22058 22345 3 22058 22346 22059 3 22347 22059 22346 3 22059 22347 22060 3 22348 22060 22347 3 22060 22348 22061 3 22349 22061 22348 3 22061 22349 22062 3 22350 22062 22349 3 22062 22350 22063 3 22351 22063 22350 3 22063 22351 22064 3 22352 22064 22351 3 22064 22352 22065 3 22353 22065 22352 3 22065 22353 22068 3 22356 22068 22353 3 22066 22354 22067 3 22355 22067 22354 3 22066 22071 22359 3 22066 22359 22354 3 22068 22356 22069 3 22357 22069 22356 3 22069 22357 22360 3 22069 22360 22072 3 22070 22358 22359 3 22070 22359 22071 3 22070 22074 22362 3 22070 22362 22358 3 22072 22360 22361 3 22072 22361 22073 3 22073 22361 22363 3 22073 22363 22075 3 22074 22076 22364 3 22074 22364 22362 3 22075 22363 22365 3 22075 22365 22077 3 22076 22078 22366 3 22076 22366 22364 3 22077 22365 22367 3 22077 22367 22079 3 22078 22080 22368 3 22078 22368 22366 3 22079 22367 22369 3 22079 22369 22081 3 22080 22082 22370 3 22080 22370 22368 3 22081 22369 22371 3 22081 22371 22083 3 22082 22084 22372 3 22082 22372 22370 3 22083 22371 22373 3 22083 22373 22085 3 22084 22086 22374 3 22084 22374 22372 3 22085 22373 22375 3 22085 22375 22087 3 22086 22088 22376 3 22086 22376 22374 3 22087 22375 22377 3 22087 22377 22089 3 22088 22090 22378 3 22088 22378 22376 3 22089 22377 22379 3 22089 22379 22091 3 22090 22092 22380 3 22090 22380 22378 3 22091 22379 22381 3 22091 22381 22093 3 22092 22094 22382 3 22092 22382 22380 3 22093 22381 22383 3 22093 22383 22095 3 22094 22096 22384 3 22094 22384 22382 3 22095 22383 22385 3 22095 22385 22097 3 22096 22098 22386 3 22096 22386 22384 3 22097 22385 22387 3 22097 22387 22099 3 22098 22100 22388 3 22098 22388 22386 3 22099 22387 22389 3 22099 22389 22101 3 22100 22102 22390 3 22100 22390 22388 3 22101 22389 22391 3 22101 22391 22103 3 22102 22104 22392 3 22102 22392 22390 3 22103 22391 22393 3 22103 22393 22105 3 22104 22106 22394 3 22104 22394 22392 3 22105 22393 22395 3 22105 22395 22107 3 22106 22108 22396 3 22106 22396 22394 3 22107 22395 22397 3 22107 22397 22109 3 22108 22110 22398 3 22108 22398 22396 3 22109 22397 22399 3 22109 22399 22111 3 22110 22112 22400 3 22110 22400 22398 3 22111 22399 22401 3 22111 22401 22113 3 22112 22114 22402 3 22112 22402 22400 3 22113 22401 22403 3 22113 22403 22115 3 22114 22116 22404 3 22114 22404 22402 3 22115 22403 22405 3 22115 22405 22117 3 22116 22118 22406 3 22116 22406 22404 3 22117 22405 22407 3 22117 22407 22119 3 22118 22120 22408 3 22118 22408 22406 3 22119 22407 22409 3 22119 22409 22121 3 22120 22122 22410 3 22120 22410 22408 3 22121 22409 22411 3 22121 22411 22123 3 22122 22124 22412 3 22122 22412 22410 3 22123 22411 22413 3 22123 22413 22125 3 22124 22126 22414 3 22124 22414 22412 3 22125 22413 22415 3 22125 22415 22127 3 22126 22128 22416 3 22126 22416 22414 3 22127 22415 22417 3 22127 22417 22129 3 22128 22130 22418 3 22128 22418 22416 3 22129 22417 22419 3 22129 22419 22131 3 22130 22132 22420 3 22130 22420 22418 3 22131 22419 22421 3 22131 22421 22133 3 22132 22134 22422 3 22132 22422 22420 3 22133 22421 22423 3 22133 22423 22135 3 22134 22136 22424 3 22134 22424 22422 3 22135 22423 22425 3 22135 22425 22137 3 22136 22138 22426 3 22136 22426 22424 3 22137 22425 22427 3 22137 22427 22139 3 22138 22140 22428 3 22138 22428 22426 3 22139 22427 22429 3 22139 22429 22141 3 22140 22142 22430 3 22140 22430 22428 3 22141 22429 22431 3 22141 22431 22143 3 22142 22144 22430 3 22432 22430 22144 3 22143 22431 22433 3 22143 22433 22145 3 22144 22146 22432 3 22434 22432 22146 3 22145 22433 22435 3 22145 22435 22147 3 22146 22148 22434 3 22436 22434 22148 3 22147 22435 22437 3 22147 22437 22149 3 22148 22150 22436 3 22438 22436 22150 3 22149 22437 22439 3 22149 22439 22151 3 22150 22152 22438 3 22440 22438 22152 3 22151 22439 22441 3 22151 22441 22153 3 22152 22154 22440 3 22442 22440 22154 3 22153 22441 22443 3 22153 22443 22155 3 22154 22156 22442 3 22444 22442 22156 3 22155 22443 22445 3 22155 22445 22157 3 22156 22158 22444 3 22446 22444 22158 3 22157 22445 22447 3 22157 22447 22159 3 22158 22160 22446 3 22448 22446 22160 3 22159 22447 22449 3 22159 22449 22161 3 22160 22162 22448 3 22450 22448 22162 3 22161 22449 22163 3 22451 22163 22449 3 22162 22164 22450 3 22452 22450 22164 3 22163 22451 22165 3 22453 22165 22451 3 22164 22166 22452 3 22454 22452 22166 3 22165 22453 22167 3 22455 22167 22453 3 22166 22168 22454 3 22456 22454 22168 3 22167 22455 22169 3 22457 22169 22455 3 22168 22170 22456 3 22458 22456 22170 3 22169 22457 22171 3 22459 22171 22457 3 22170 22172 22458 3 22460 22458 22172 3 22171 22459 22173 3 22461 22173 22459 3 22172 22174 22460 3 22462 22460 22174 3 22173 22461 22175 3 22463 22175 22461 3 22174 22176 22462 3 22464 22462 22176 3 22175 22463 22177 3 22465 22177 22463 3 22176 22178 22464 3 22466 22464 22178 3 22177 22465 22179 3 22467 22179 22465 3 22178 22180 22466 3 22468 22466 22180 3 22179 22467 22181 3 22469 22181 22467 3 22180 22182 22468 3 22470 22468 22182 3 22181 22469 22183 3 22471 22183 22469 3 22182 22184 22470 3 22472 22470 22184 3 22183 22471 22185 3 22473 22185 22471 3 22184 22186 22472 3 22474 22472 22186 3 22185 22473 22187 3 22475 22187 22473 3 22186 22188 22474 3 22476 22474 22188 3 22187 22475 22189 3 22477 22189 22475 3 22188 22190 22476 3 22478 22476 22190 3 22189 22477 22191 3 22479 22191 22477 3 22190 22192 22478 3 22480 22478 22192 3 22191 22479 22193 3 22481 22193 22479 3 22192 22194 22480 3 22482 22480 22194 3 22193 22481 22195 3 22483 22195 22481 3 22194 22196 22482 3 22484 22482 22196 3 22195 22483 22197 3 22485 22197 22483 3 22196 22198 22484 3 22486 22484 22198 3 22197 22485 22199 3 22487 22199 22485 3 22198 22200 22486 3 22488 22486 22200 3 22199 22487 22201 3 22489 22201 22487 3 22200 22202 22488 3 22490 22488 22202 3 22201 22489 22203 3 22491 22203 22489 3 22202 22204 22490 3 22492 22490 22204 3 22203 22491 22205 3 22493 22205 22491 3 22204 22206 22492 3 22494 22492 22206 3 22205 22493 22207 3 22495 22207 22493 3 22206 22208 22494 3 22496 22494 22208 3 22207 22495 22211 3 22499 22211 22495 3 22208 22209 22496 3 22497 22496 22209 3 22209 22212 22497 3 22500 22497 22212 3 22210 22211 22498 3 22499 22498 22211 3 22210 22498 22215 3 22503 22215 22498 3 22212 22213 22500 3 22501 22500 22213 3 22213 22216 22501 3 22504 22501 22216 3 22214 22215 22502 3 22503 22502 22215 3 22214 22502 22284 3 22572 22284 22502 3 22216 22217 22504 3 22505 22504 22217 3 22217 22218 22505 3 22506 22505 22218 3 22218 22219 22506 3 22507 22506 22219 3 22219 22220 22507 3 22508 22507 22220 3 22220 22221 22508 3 22509 22508 22221 3 22221 22222 22509 3 22510 22509 22222 3 22222 22223 22510 3 22511 22510 22223 3 22223 22224 22511 3 22512 22511 22224 3 22224 22225 22512 3 22513 22512 22225 3 22225 22226 22513 3 22514 22513 22226 3 22226 22227 22514 3 22515 22514 22227 3 22227 22228 22515 3 22516 22515 22228 3 22228 22229 22516 3 22517 22516 22229 3 22229 22230 22517 3 22518 22517 22230 3 22230 22231 22518 3 22519 22518 22231 3 22231 22232 22519 3 22520 22519 22232 3 22232 22233 22520 3 22521 22520 22233 3 22233 22234 22521 3 22522 22521 22234 3 22234 22235 22523 3 22234 22523 22522 3 22235 22236 22524 3 22235 22524 22523 3 22236 22237 22525 3 22236 22525 22524 3 22237 22238 22526 3 22237 22526 22525 3 22238 22239 22527 3 22238 22527 22526 3 22239 22240 22528 3 22239 22528 22527 3 22240 22241 22529 3 22240 22529 22528 3 22241 22242 22530 3 22241 22530 22529 3 22242 22243 22531 3 22242 22531 22530 3 22243 22244 22532 3 22243 22532 22531 3 22244 22245 22533 3 22244 22533 22532 3 22245 22246 22534 3 22245 22534 22533 3 22246 22247 22535 3 22246 22535 22534 3 22247 22248 22536 3 22247 22536 22535 3 22248 22249 22537 3 22248 22537 22536 3 22249 22250 22538 3 22249 22538 22537 3 22250 22251 22539 3 22250 22539 22538 3 22251 22252 22540 3 22251 22540 22539 3 22252 22253 22541 3 22252 22541 22540 3 22253 22254 22542 3 22253 22542 22541 3 22254 22255 22543 3 22254 22543 22542 3 22255 22256 22544 3 22255 22544 22543 3 22256 22257 22545 3 22256 22545 22544 3 22257 22258 22546 3 22257 22546 22545 3 22258 22259 22547 3 22258 22547 22546 3 22259 22260 22548 3 22259 22548 22547 3 22260 22261 22549 3 22260 22549 22548 3 22261 22262 22550 3 22261 22550 22549 3 22262 22263 22551 3 22262 22551 22550 3 22263 22264 22552 3 22263 22552 22551 3 22264 22265 22553 3 22264 22553 22552 3 22265 22266 22554 3 22265 22554 22553 3 22266 22267 22555 3 22266 22555 22554 3 22267 22268 22556 3 22267 22556 22555 3 22268 22269 22557 3 22268 22557 22556 3 22269 22270 22558 3 22269 22558 22557 3 22270 22271 22559 3 22270 22559 22558 3 22271 22272 22560 3 22271 22560 22559 3 22272 22273 22561 3 22272 22561 22560 3 22273 22274 22562 3 22273 22562 22561 3 22274 22275 22563 3 22274 22563 22562 3 22275 22276 22564 3 22275 22564 22563 3 22276 22277 22565 3 22276 22565 22564 3 22277 22278 22566 3 22277 22566 22565 3 22278 22279 22567 3 22278 22567 22566 3 22279 22280 22568 3 22279 22568 22567 3 22280 22281 22569 3 22280 22569 22568 3 22281 22282 22570 3 22281 22570 22569 3 22282 22283 22571 3 22282 22571 22570 3 22283 22284 22572 3 22283 22572 22571 3 22285 22573 22574 3 22285 22574 22286 3 22285 22355 22643 3 22285 22643 22573 3 22286 22574 22575 3 22286 22575 22287 3 22287 22575 22576 3 22287 22576 22288 3 22288 22576 22577 3 22288 22577 22289 3 22289 22577 22578 3 22289 22578 22290 3 22290 22578 22579 3 22290 22579 22291 3 22291 22579 22580 3 22291 22580 22292 3 22292 22580 22581 3 22292 22581 22293 3 22293 22581 22582 3 22293 22582 22294 3 22294 22582 22583 3 22294 22583 22295 3 22295 22583 22584 3 22295 22584 22296 3 22296 22584 22585 3 22296 22585 22297 3 22297 22585 22586 3 22297 22586 22298 3 22298 22586 22587 3 22298 22587 22299 3 22299 22587 22588 3 22299 22588 22300 3 22300 22588 22589 3 22300 22589 22301 3 22301 22589 22590 3 22301 22590 22302 3 22302 22590 22591 3 22302 22591 22303 3 22303 22591 22592 3 22303 22592 22304 3 22304 22592 22593 3 22304 22593 22305 3 22305 22593 22594 3 22305 22594 22306 3 22306 22594 22595 3 22306 22595 22307 3 22307 22595 22596 3 22307 22596 22308 3 22308 22596 22597 3 22308 22597 22309 3 22309 22597 22598 3 22309 22598 22310 3 22310 22598 22599 3 22310 22599 22311 3 22311 22599 22600 3 22311 22600 22312 3 22312 22600 22601 3 22312 22601 22313 3 22313 22601 22602 3 22313 22602 22314 3 22314 22602 22603 3 22314 22603 22315 3 22315 22603 22604 3 22315 22604 22316 3 22316 22604 22605 3 22316 22605 22317 3 22317 22605 22606 3 22317 22606 22318 3 22318 22606 22607 3 22318 22607 22319 3 22319 22607 22608 3 22319 22608 22320 3 22320 22608 22609 3 22320 22609 22321 3 22321 22609 22610 3 22321 22610 22322 3 22322 22610 22611 3 22322 22611 22323 3 22323 22611 22612 3 22323 22612 22324 3 22324 22612 22613 3 22324 22613 22325 3 22325 22613 22614 3 22325 22614 22326 3 22326 22614 22615 3 22326 22615 22327 3 22327 22615 22616 3 22327 22616 22328 3 22328 22616 22617 3 22328 22617 22329 3 22329 22617 22618 3 22329 22618 22330 3 22330 22618 22619 3 22330 22619 22331 3 22331 22619 22620 3 22331 22620 22332 3 22332 22620 22621 3 22332 22621 22333 3 22333 22621 22622 3 22333 22622 22334 3 22334 22622 22623 3 22334 22623 22335 3 22335 22623 22624 3 22335 22624 22336 3 22336 22624 22625 3 22336 22625 22337 3 22337 22625 22626 3 22337 22626 22338 3 22338 22626 22627 3 22338 22627 22339 3 22339 22627 22628 3 22339 22628 22340 3 22340 22628 22629 3 22340 22629 22341 3 22341 22629 22630 3 22341 22630 22342 3 22342 22630 22631 3 22342 22631 22343 3 22343 22631 22632 3 22343 22632 22344 3 22344 22632 22633 3 22344 22633 22345 3 22345 22633 22634 3 22345 22634 22346 3 22346 22634 22347 3 22635 22347 22634 3 22347 22635 22348 3 22636 22348 22635 3 22348 22636 22349 3 22637 22349 22636 3 22349 22637 22350 3 22638 22350 22637 3 22350 22638 22351 3 22639 22351 22638 3 22351 22639 22352 3 22640 22352 22639 3 22352 22640 22353 3 22641 22353 22640 3 22353 22641 22356 3 22644 22356 22641 3 22354 22642 22355 3 22643 22355 22642 3 22354 22359 22642 3 22647 22642 22359 3 22356 22644 22357 3 22645 22357 22644 3 22357 22645 22360 3 22648 22360 22645 3 22358 22646 22359 3 22647 22359 22646 3 22358 22362 22646 3 22650 22646 22362 3 22360 22648 22361 3 22649 22361 22648 3 22361 22649 22363 3 22651 22363 22649 3 22362 22364 22650 3 22652 22650 22364 3 22363 22651 22365 3 22653 22365 22651 3 22364 22366 22652 3 22654 22652 22366 3 22365 22653 22367 3 22655 22367 22653 3 22366 22368 22654 3 22656 22654 22368 3 22367 22655 22369 3 22657 22369 22655 3 22368 22370 22656 3 22658 22656 22370 3 22369 22657 22371 3 22659 22371 22657 3 22370 22372 22658 3 22660 22658 22372 3 22371 22659 22373 3 22661 22373 22659 3 22372 22374 22660 3 22662 22660 22374 3 22373 22661 22375 3 22663 22375 22661 3 22374 22376 22662 3 22664 22662 22376 3 22375 22663 22377 3 22665 22377 22663 3 22376 22378 22664 3 22666 22664 22378 3 22377 22665 22379 3 22667 22379 22665 3 22378 22380 22666 3 22668 22666 22380 3 22379 22667 22381 3 22669 22381 22667 3 22380 22382 22668 3 22670 22668 22382 3 22381 22669 22383 3 22671 22383 22669 3 22382 22384 22670 3 22672 22670 22384 3 22383 22671 22385 3 22673 22385 22671 3 22384 22386 22672 3 22674 22672 22386 3 22385 22673 22387 3 22675 22387 22673 3 22386 22388 22674 3 22676 22674 22388 3 22387 22675 22389 3 22677 22389 22675 3 22388 22390 22676 3 22678 22676 22390 3 22389 22677 22391 3 22679 22391 22677 3 22390 22392 22678 3 22680 22678 22392 3 22391 22679 22393 3 22681 22393 22679 3 22392 22394 22680 3 22682 22680 22394 3 22393 22681 22395 3 22683 22395 22681 3 22394 22396 22682 3 22684 22682 22396 3 22395 22683 22397 3 22685 22397 22683 3 22396 22398 22684 3 22686 22684 22398 3 22397 22685 22399 3 22687 22399 22685 3 22398 22400 22686 3 22688 22686 22400 3 22399 22687 22401 3 22689 22401 22687 3 22400 22402 22688 3 22690 22688 22402 3 22401 22689 22403 3 22691 22403 22689 3 22402 22404 22690 3 22692 22690 22404 3 22403 22691 22405 3 22693 22405 22691 3 22404 22406 22692 3 22694 22692 22406 3 22405 22693 22407 3 22695 22407 22693 3 22406 22408 22694 3 22696 22694 22408 3 22407 22695 22409 3 22697 22409 22695 3 22408 22410 22696 3 22698 22696 22410 3 22409 22697 22411 3 22699 22411 22697 3 22410 22412 22698 3 22700 22698 22412 3 22411 22699 22413 3 22701 22413 22699 3 22412 22414 22700 3 22702 22700 22414 3 22413 22701 22415 3 22703 22415 22701 3 22414 22416 22702 3 22704 22702 22416 3 22415 22703 22417 3 22705 22417 22703 3 22416 22418 22704 3 22706 22704 22418 3 22417 22705 22419 3 22707 22419 22705 3 22418 22420 22708 3 22418 22708 22706 3 22419 22707 22421 3 22709 22421 22707 3 22420 22422 22710 3 22420 22710 22708 3 22421 22709 22423 3 22711 22423 22709 3 22422 22424 22712 3 22422 22712 22710 3 22423 22711 22425 3 22713 22425 22711 3 22424 22426 22714 3 22424 22714 22712 3 22425 22713 22427 3 22715 22427 22713 3 22426 22428 22716 3 22426 22716 22714 3 22427 22715 22429 3 22717 22429 22715 3 22428 22430 22718 3 22428 22718 22716 3 22429 22717 22431 3 22719 22431 22717 3 22430 22432 22720 3 22430 22720 22718 3 22431 22719 22433 3 22721 22433 22719 3 22432 22434 22722 3 22432 22722 22720 3 22433 22721 22435 3 22723 22435 22721 3 22434 22436 22724 3 22434 22724 22722 3 22435 22723 22437 3 22725 22437 22723 3 22436 22438 22726 3 22436 22726 22724 3 22437 22725 22439 3 22727 22439 22725 3 22438 22440 22728 3 22438 22728 22726 3 22439 22727 22729 3 22439 22729 22441 3 22440 22442 22730 3 22440 22730 22728 3 22441 22729 22731 3 22441 22731 22443 3 22442 22444 22732 3 22442 22732 22730 3 22443 22731 22733 3 22443 22733 22445 3 22444 22446 22734 3 22444 22734 22732 3 22445 22733 22735 3 22445 22735 22447 3 22446 22448 22736 3 22446 22736 22734 3 22447 22735 22737 3 22447 22737 22449 3 22448 22450 22738 3 22448 22738 22736 3 22449 22737 22739 3 22449 22739 22451 3 22450 22452 22740 3 22450 22740 22738 3 22451 22739 22741 3 22451 22741 22453 3 22452 22454 22742 3 22452 22742 22740 3 22453 22741 22743 3 22453 22743 22455 3 22454 22456 22744 3 22454 22744 22742 3 22455 22743 22745 3 22455 22745 22457 3 22456 22458 22746 3 22456 22746 22744 3 22457 22745 22747 3 22457 22747 22459 3 22458 22460 22748 3 22458 22748 22746 3 22459 22747 22749 3 22459 22749 22461 3 22460 22462 22750 3 22460 22750 22748 3 22461 22749 22751 3 22461 22751 22463 3 22462 22464 22752 3 22462 22752 22750 3 22463 22751 22753 3 22463 22753 22465 3 22464 22466 22754 3 22464 22754 22752 3 22465 22753 22755 3 22465 22755 22467 3 22466 22468 22756 3 22466 22756 22754 3 22467 22755 22757 3 22467 22757 22469 3 22468 22470 22758 3 22468 22758 22756 3 22469 22757 22759 3 22469 22759 22471 3 22470 22472 22760 3 22470 22760 22758 3 22471 22759 22761 3 22471 22761 22473 3 22472 22474 22762 3 22472 22762 22760 3 22473 22761 22763 3 22473 22763 22475 3 22474 22476 22764 3 22474 22764 22762 3 22475 22763 22765 3 22475 22765 22477 3 22476 22478 22766 3 22476 22766 22764 3 22477 22765 22767 3 22477 22767 22479 3 22478 22480 22768 3 22478 22768 22766 3 22479 22767 22769 3 22479 22769 22481 3 22480 22482 22770 3 22480 22770 22768 3 22481 22769 22771 3 22481 22771 22483 3 22482 22484 22772 3 22482 22772 22770 3 22483 22771 22773 3 22483 22773 22485 3 22484 22486 22774 3 22484 22774 22772 3 22485 22773 22775 3 22485 22775 22487 3 22486 22488 22776 3 22486 22776 22774 3 22487 22775 22777 3 22487 22777 22489 3 22488 22490 22778 3 22488 22778 22776 3 22489 22777 22779 3 22489 22779 22491 3 22490 22492 22780 3 22490 22780 22778 3 22491 22779 22781 3 22491 22781 22493 3 22492 22494 22782 3 22492 22782 22780 3 22493 22781 22783 3 22493 22783 22495 3 22494 22496 22784 3 22494 22784 22782 3 22495 22783 22787 3 22495 22787 22499 3 22496 22497 22785 3 22496 22785 22784 3 22497 22500 22788 3 22497 22788 22785 3 22498 22499 22787 3 22498 22787 22786 3 22498 22786 22791 3 22498 22791 22503 3 22500 22501 22789 3 22500 22789 22788 3 22501 22504 22792 3 22501 22792 22789 3 22502 22503 22791 3 22502 22791 22790 3 22502 22790 22860 3 22502 22860 22572 3 22504 22505 22793 3 22504 22793 22792 3 22505 22506 22794 3 22505 22794 22793 3 22506 22507 22795 3 22506 22795 22794 3 22507 22508 22796 3 22507 22796 22795 3 22508 22509 22797 3 22508 22797 22796 3 22509 22510 22798 3 22509 22798 22797 3 22510 22511 22799 3 22510 22799 22798 3 22511 22512 22799 3 22800 22799 22512 3 22512 22513 22800 3 22801 22800 22513 3 22513 22514 22801 3 22802 22801 22514 3 22514 22515 22802 3 22803 22802 22515 3 22515 22516 22803 3 22804 22803 22516 3 22516 22517 22804 3 22805 22804 22517 3 22517 22518 22805 3 22806 22805 22518 3 22518 22519 22806 3 22807 22806 22519 3 22519 22520 22807 3 22808 22807 22520 3 22520 22521 22808 3 22809 22808 22521 3 22521 22522 22809 3 22810 22809 22522 3 22522 22523 22810 3 22811 22810 22523 3 22523 22524 22811 3 22812 22811 22524 3 22524 22525 22812 3 22813 22812 22525 3 22525 22526 22813 3 22814 22813 22526 3 22526 22527 22814 3 22815 22814 22527 3 22527 22528 22815 3 22816 22815 22528 3 22528 22529 22816 3 22817 22816 22529 3 22529 22530 22817 3 22818 22817 22530 3 22530 22531 22818 3 22819 22818 22531 3 22531 22532 22819 3 22820 22819 22532 3 22532 22533 22820 3 22821 22820 22533 3 22533 22534 22821 3 22822 22821 22534 3 22534 22535 22822 3 22823 22822 22535 3 22535 22536 22823 3 22824 22823 22536 3 22536 22537 22824 3 22825 22824 22537 3 22537 22538 22825 3 22826 22825 22538 3 22538 22539 22826 3 22827 22826 22539 3 22539 22540 22827 3 22828 22827 22540 3 22540 22541 22828 3 22829 22828 22541 3 22541 22542 22829 3 22830 22829 22542 3 22542 22543 22830 3 22831 22830 22543 3 22543 22544 22831 3 22832 22831 22544 3 22544 22545 22832 3 22833 22832 22545 3 22545 22546 22833 3 22834 22833 22546 3 22546 22547 22834 3 22835 22834 22547 3 22547 22548 22835 3 22836 22835 22548 3 22548 22549 22836 3 22837 22836 22549 3 22549 22550 22837 3 22838 22837 22550 3 22550 22551 22838 3 22839 22838 22551 3 22551 22552 22839 3 22840 22839 22552 3 22552 22553 22840 3 22841 22840 22553 3 22553 22554 22841 3 22842 22841 22554 3 22554 22555 22842 3 22843 22842 22555 3 22555 22556 22843 3 22844 22843 22556 3 22556 22557 22844 3 22845 22844 22557 3 22557 22558 22845 3 22846 22845 22558 3 22558 22559 22846 3 22847 22846 22559 3 22559 22560 22847 3 22848 22847 22560 3 22560 22561 22848 3 22849 22848 22561 3 22561 22562 22849 3 22850 22849 22562 3 22562 22563 22850 3 22851 22850 22563 3 22563 22564 22851 3 22852 22851 22564 3 22564 22565 22852 3 22853 22852 22565 3 22565 22566 22853 3 22854 22853 22566 3 22566 22567 22854 3 22855 22854 22567 3 22567 22568 22855 3 22856 22855 22568 3 22568 22569 22856 3 22857 22856 22569 3 22569 22570 22857 3 22858 22857 22570 3 22570 22571 22858 3 22859 22858 22571 3 22571 22572 22859 3 22860 22859 22572 3 22573 22861 22574 3 22862 22574 22861 3 22573 22643 22931 3 22573 22931 22861 3 22574 22862 22575 3 22863 22575 22862 3 22575 22863 22576 3 22864 22576 22863 3 22576 22864 22577 3 22865 22577 22864 3 22577 22865 22578 3 22866 22578 22865 3 22578 22866 22579 3 22867 22579 22866 3 22579 22867 22580 3 22868 22580 22867 3 22580 22868 22581 3 22869 22581 22868 3 22581 22869 22582 3 22870 22582 22869 3 22582 22870 22583 3 22871 22583 22870 3 22583 22871 22584 3 22872 22584 22871 3 22584 22872 22585 3 22873 22585 22872 3 22585 22873 22586 3 22874 22586 22873 3 22586 22874 22587 3 22875 22587 22874 3 22587 22875 22588 3 22876 22588 22875 3 22588 22876 22589 3 22877 22589 22876 3 22589 22877 22590 3 22878 22590 22877 3 22590 22878 22591 3 22879 22591 22878 3 22591 22879 22592 3 22880 22592 22879 3 22592 22880 22593 3 22881 22593 22880 3 22593 22881 22594 3 22882 22594 22881 3 22594 22882 22595 3 22883 22595 22882 3 22595 22883 22596 3 22884 22596 22883 3 22596 22884 22597 3 22885 22597 22884 3 22597 22885 22598 3 22886 22598 22885 3 22598 22886 22599 3 22887 22599 22886 3 22599 22887 22600 3 22888 22600 22887 3 22600 22888 22601 3 22889 22601 22888 3 22601 22889 22602 3 22890 22602 22889 3 22602 22890 22603 3 22891 22603 22890 3 22603 22891 22604 3 22892 22604 22891 3 22604 22892 22605 3 22893 22605 22892 3 22605 22893 22606 3 22894 22606 22893 3 22606 22894 22607 3 22895 22607 22894 3 22607 22895 22608 3 22896 22608 22895 3 22608 22896 22609 3 22897 22609 22896 3 22609 22897 22610 3 22898 22610 22897 3 22610 22898 22611 3 22899 22611 22898 3 22611 22899 22612 3 22900 22612 22899 3 22612 22900 22613 3 22901 22613 22900 3 22613 22901 22614 3 22902 22614 22901 3 22614 22902 22615 3 22903 22615 22902 3 22615 22903 22616 3 22904 22616 22903 3 22616 22904 22617 3 22905 22617 22904 3 22617 22905 22618 3 22906 22618 22905 3 22618 22906 22619 3 22907 22619 22906 3 22619 22907 22620 3 22908 22620 22907 3 22620 22908 22621 3 22909 22621 22908 3 22621 22909 22622 3 22910 22622 22909 3 22622 22910 22623 3 22911 22623 22910 3 22623 22911 22912 3 22623 22912 22624 3 22624 22912 22913 3 22624 22913 22625 3 22625 22913 22914 3 22625 22914 22626 3 22626 22914 22915 3 22626 22915 22627 3 22627 22915 22916 3 22627 22916 22628 3 22628 22916 22917 3 22628 22917 22629 3 22629 22917 22918 3 22629 22918 22630 3 22630 22918 22919 3 22630 22919 22631 3 22631 22919 22920 3 22631 22920 22632 3 22632 22920 22921 3 22632 22921 22633 3 22633 22921 22922 3 22633 22922 22634 3 22634 22922 22923 3 22634 22923 22635 3 22635 22923 22924 3 22635 22924 22636 3 22636 22924 22925 3 22636 22925 22637 3 22637 22925 22926 3 22637 22926 22638 3 22638 22926 22927 3 22638 22927 22639 3 22639 22927 22928 3 22639 22928 22640 3 22640 22928 22929 3 22640 22929 22641 3 22641 22929 22932 3 22641 22932 22644 3 22642 22930 22931 3 22642 22931 22643 3 22642 22647 22935 3 22642 22935 22930 3 22644 22932 22933 3 22644 22933 22645 3 22645 22933 22936 3 22645 22936 22648 3 22646 22934 22935 3 22646 22935 22647 3 22646 22650 22938 3 22646 22938 22934 3 22648 22936 22937 3 22648 22937 22649 3 22649 22937 22939 3 22649 22939 22651 3 22650 22652 22940 3 22650 22940 22938 3 22651 22939 22941 3 22651 22941 22653 3 22652 22654 22942 3 22652 22942 22940 3 22653 22941 22943 3 22653 22943 22655 3 22654 22656 22944 3 22654 22944 22942 3 22655 22943 22945 3 22655 22945 22657 3 22656 22658 22946 3 22656 22946 22944 3 22657 22945 22947 3 22657 22947 22659 3 22658 22660 22948 3 22658 22948 22946 3 22659 22947 22949 3 22659 22949 22661 3 22660 22662 22950 3 22660 22950 22948 3 22661 22949 22951 3 22661 22951 22663 3 22662 22664 22952 3 22662 22952 22950 3 22663 22951 22953 3 22663 22953 22665 3 22664 22666 22954 3 22664 22954 22952 3 22665 22953 22955 3 22665 22955 22667 3 22666 22668 22956 3 22666 22956 22954 3 22667 22955 22957 3 22667 22957 22669 3 22668 22670 22958 3 22668 22958 22956 3 22669 22957 22959 3 22669 22959 22671 3 22670 22672 22960 3 22670 22960 22958 3 22671 22959 22961 3 22671 22961 22673 3 22672 22674 22962 3 22672 22962 22960 3 22673 22961 22963 3 22673 22963 22675 3 22674 22676 22964 3 22674 22964 22962 3 22675 22963 22965 3 22675 22965 22677 3 22676 22678 22966 3 22676 22966 22964 3 22677 22965 22967 3 22677 22967 22679 3 22678 22680 22968 3 22678 22968 22966 3 22679 22967 22969 3 22679 22969 22681 3 22680 22682 22970 3 22680 22970 22968 3 22681 22969 22971 3 22681 22971 22683 3 22682 22684 22972 3 22682 22972 22970 3 22683 22971 22973 3 22683 22973 22685 3 22684 22686 22974 3 22684 22974 22972 3 22685 22973 22975 3 22685 22975 22687 3 22686 22688 22976 3 22686 22976 22974 3 22687 22975 22977 3 22687 22977 22689 3 22688 22690 22978 3 22688 22978 22976 3 22689 22977 22979 3 22689 22979 22691 3 22690 22692 22980 3 22690 22980 22978 3 22691 22979 22981 3 22691 22981 22693 3 22692 22694 22982 3 22692 22982 22980 3 22693 22981 22983 3 22693 22983 22695 3 22694 22696 22984 3 22694 22984 22982 3 22695 22983 22985 3 22695 22985 22697 3 22696 22698 22984 3 22986 22984 22698 3 22697 22985 22987 3 22697 22987 22699 3 22698 22700 22986 3 22988 22986 22700 3 22699 22987 22989 3 22699 22989 22701 3 22700 22702 22988 3 22990 22988 22702 3 22701 22989 22991 3 22701 22991 22703 3 22702 22704 22990 3 22992 22990 22704 3 22703 22991 22993 3 22703 22993 22705 3 22704 22706 22992 3 22994 22992 22706 3 22705 22993 22995 3 22705 22995 22707 3 22706 22708 22994 3 22996 22994 22708 3 22707 22995 22997 3 22707 22997 22709 3 22708 22710 22996 3 22998 22996 22710 3 22709 22997 22999 3 22709 22999 22711 3 22710 22712 22998 3 23000 22998 22712 3 22711 22999 23001 3 22711 23001 22713 3 22712 22714 23000 3 23002 23000 22714 3 22713 23001 23003 3 22713 23003 22715 3 22714 22716 23002 3 23004 23002 22716 3 22715 23003 23005 3 22715 23005 22717 3 22716 22718 23004 3 23006 23004 22718 3 22717 23005 22719 3 23007 22719 23005 3 22718 22720 23006 3 23008 23006 22720 3 22719 23007 22721 3 23009 22721 23007 3 22720 22722 23008 3 23010 23008 22722 3 22721 23009 22723 3 23011 22723 23009 3 22722 22724 23010 3 23012 23010 22724 3 22723 23011 22725 3 23013 22725 23011 3 22724 22726 23012 3 23014 23012 22726 3 22725 23013 22727 3 23015 22727 23013 3 22726 22728 23014 3 23016 23014 22728 3 22727 23015 22729 3 23017 22729 23015 3 22728 22730 23016 3 23018 23016 22730 3 22729 23017 22731 3 23019 22731 23017 3 22730 22732 23018 3 23020 23018 22732 3 22731 23019 22733 3 23021 22733 23019 3 22732 22734 23020 3 23022 23020 22734 3 22733 23021 22735 3 23023 22735 23021 3 22734 22736 23022 3 23024 23022 22736 3 22735 23023 22737 3 23025 22737 23023 3 22736 22738 23024 3 23026 23024 22738 3 22737 23025 22739 3 23027 22739 23025 3 22738 22740 23026 3 23028 23026 22740 3 22739 23027 22741 3 23029 22741 23027 3 22740 22742 23028 3 23030 23028 22742 3 22741 23029 22743 3 23031 22743 23029 3 22742 22744 23030 3 23032 23030 22744 3 22743 23031 22745 3 23033 22745 23031 3 22744 22746 23032 3 23034 23032 22746 3 22745 23033 22747 3 23035 22747 23033 3 22746 22748 23034 3 23036 23034 22748 3 22747 23035 22749 3 23037 22749 23035 3 22748 22750 23036 3 23038 23036 22750 3 22749 23037 22751 3 23039 22751 23037 3 22750 22752 23038 3 23040 23038 22752 3 22751 23039 22753 3 23041 22753 23039 3 22752 22754 23040 3 23042 23040 22754 3 22753 23041 22755 3 23043 22755 23041 3 22754 22756 23042 3 23044 23042 22756 3 22755 23043 22757 3 23045 22757 23043 3 22756 22758 23044 3 23046 23044 22758 3 22757 23045 22759 3 23047 22759 23045 3 22758 22760 23046 3 23048 23046 22760 3 22759 23047 22761 3 23049 22761 23047 3 22760 22762 23048 3 23050 23048 22762 3 22761 23049 22763 3 23051 22763 23049 3 22762 22764 23050 3 23052 23050 22764 3 22763 23051 22765 3 23053 22765 23051 3 22764 22766 23052 3 23054 23052 22766 3 22765 23053 22767 3 23055 22767 23053 3 22766 22768 23054 3 23056 23054 22768 3 22767 23055 22769 3 23057 22769 23055 3 22768 22770 23056 3 23058 23056 22770 3 22769 23057 22771 3 23059 22771 23057 3 22770 22772 23058 3 23060 23058 22772 3 22771 23059 22773 3 23061 22773 23059 3 22772 22774 23060 3 23062 23060 22774 3 22773 23061 22775 3 23063 22775 23061 3 22774 22776 23062 3 23064 23062 22776 3 22775 23063 22777 3 23065 22777 23063 3 22776 22778 23064 3 23066 23064 22778 3 22777 23065 22779 3 23067 22779 23065 3 22778 22780 23066 3 23068 23066 22780 3 22779 23067 22781 3 23069 22781 23067 3 22780 22782 23068 3 23070 23068 22782 3 22781 23069 22783 3 23071 22783 23069 3 22782 22784 23070 3 23072 23070 22784 3 22783 23071 22787 3 23075 22787 23071 3 22784 22785 23072 3 23073 23072 22785 3 22785 22788 23073 3 23076 23073 22788 3 22786 22787 23074 3 23075 23074 22787 3 22786 23074 22791 3 23079 22791 23074 3 22788 22789 23077 3 22788 23077 23076 3 22789 22792 23080 3 22789 23080 23077 3 22790 22791 23079 3 22790 23079 23078 3 22790 23078 22860 3 23148 22860 23078 3 22792 22793 23081 3 22792 23081 23080 3 22793 22794 23082 3 22793 23082 23081 3 22794 22795 23083 3 22794 23083 23082 3 22795 22796 23084 3 22795 23084 23083 3 22796 22797 23085 3 22796 23085 23084 3 22797 22798 23086 3 22797 23086 23085 3 22798 22799 23087 3 22798 23087 23086 3 22799 22800 23088 3 22799 23088 23087 3 22800 22801 23089 3 22800 23089 23088 3 22801 22802 23090 3 22801 23090 23089 3 22802 22803 23091 3 22802 23091 23090 3 22803 22804 23092 3 22803 23092 23091 3 22804 22805 23093 3 22804 23093 23092 3 22805 22806 23094 3 22805 23094 23093 3 22806 22807 23095 3 22806 23095 23094 3 22807 22808 23096 3 22807 23096 23095 3 22808 22809 23097 3 22808 23097 23096 3 22809 22810 23098 3 22809 23098 23097 3 22810 22811 23099 3 22810 23099 23098 3 22811 22812 23100 3 22811 23100 23099 3 22812 22813 23101 3 22812 23101 23100 3 22813 22814 23102 3 22813 23102 23101 3 22814 22815 23103 3 22814 23103 23102 3 22815 22816 23104 3 22815 23104 23103 3 22816 22817 23105 3 22816 23105 23104 3 22817 22818 23106 3 22817 23106 23105 3 22818 22819 23107 3 22818 23107 23106 3 22819 22820 23108 3 22819 23108 23107 3 22820 22821 23109 3 22820 23109 23108 3 22821 22822 23110 3 22821 23110 23109 3 22822 22823 23111 3 22822 23111 23110 3 22823 22824 23112 3 22823 23112 23111 3 22824 22825 23113 3 22824 23113 23112 3 22825 22826 23114 3 22825 23114 23113 3 22826 22827 23115 3 22826 23115 23114 3 22827 22828 23116 3 22827 23116 23115 3 22828 22829 23117 3 22828 23117 23116 3 22829 22830 23118 3 22829 23118 23117 3 22830 22831 23119 3 22830 23119 23118 3 22831 22832 23120 3 22831 23120 23119 3 22832 22833 23121 3 22832 23121 23120 3 22833 22834 23122 3 22833 23122 23121 3 22834 22835 23123 3 22834 23123 23122 3 22835 22836 23124 3 22835 23124 23123 3 22836 22837 23125 3 22836 23125 23124 3 22837 22838 23126 3 22837 23126 23125 3 22838 22839 23127 3 22838 23127 23126 3 22839 22840 23128 3 22839 23128 23127 3 22840 22841 23129 3 22840 23129 23128 3 22841 22842 23130 3 22841 23130 23129 3 22842 22843 23131 3 22842 23131 23130 3 22843 22844 23132 3 22843 23132 23131 3 22844 22845 23133 3 22844 23133 23132 3 22845 22846 23134 3 22845 23134 23133 3 22846 22847 23135 3 22846 23135 23134 3 22847 22848 23136 3 22847 23136 23135 3 22848 22849 23137 3 22848 23137 23136 3 22849 22850 23138 3 22849 23138 23137 3 22850 22851 23139 3 22850 23139 23138 3 22851 22852 23140 3 22851 23140 23139 3 22852 22853 23141 3 22852 23141 23140 3 22853 22854 23142 3 22853 23142 23141 3 22854 22855 23143 3 22854 23143 23142 3 22855 22856 23144 3 22855 23144 23143 3 22856 22857 23145 3 22856 23145 23144 3 22857 22858 23146 3 22857 23146 23145 3 22858 22859 23147 3 22858 23147 23146 3 22859 22860 23148 3 22859 23148 23147 3 22861 23149 23150 3 22861 23150 22862 3 22861 22931 23149 3 23219 23149 22931 3 22862 23150 23151 3 22862 23151 22863 3 22863 23151 23152 3 22863 23152 22864 3 22864 23152 23153 3 22864 23153 22865 3 22865 23153 23154 3 22865 23154 22866 3 22866 23154 23155 3 22866 23155 22867 3 22867 23155 23156 3 22867 23156 22868 3 22868 23156 23157 3 22868 23157 22869 3 22869 23157 23158 3 22869 23158 22870 3 22870 23158 23159 3 22870 23159 22871 3 22871 23159 23160 3 22871 23160 22872 3 22872 23160 23161 3 22872 23161 22873 3 22873 23161 23162 3 22873 23162 22874 3 22874 23162 23163 3 22874 23163 22875 3 22875 23163 23164 3 22875 23164 22876 3 22876 23164 23165 3 22876 23165 22877 3 22877 23165 23166 3 22877 23166 22878 3 22878 23166 23167 3 22878 23167 22879 3 22879 23167 23168 3 22879 23168 22880 3 22880 23168 23169 3 22880 23169 22881 3 22881 23169 23170 3 22881 23170 22882 3 22882 23170 23171 3 22882 23171 22883 3 22883 23171 23172 3 22883 23172 22884 3 22884 23172 23173 3 22884 23173 22885 3 22885 23173 23174 3 22885 23174 22886 3 22886 23174 23175 3 22886 23175 22887 3 22887 23175 23176 3 22887 23176 22888 3 22888 23176 23177 3 22888 23177 22889 3 22889 23177 23178 3 22889 23178 22890 3 22890 23178 23179 3 22890 23179 22891 3 22891 23179 23180 3 22891 23180 22892 3 22892 23180 23181 3 22892 23181 22893 3 22893 23181 23182 3 22893 23182 22894 3 22894 23182 23183 3 22894 23183 22895 3 22895 23183 23184 3 22895 23184 22896 3 22896 23184 23185 3 22896 23185 22897 3 22897 23185 23186 3 22897 23186 22898 3 22898 23186 23187 3 22898 23187 22899 3 22899 23187 23188 3 22899 23188 22900 3 22900 23188 23189 3 22900 23189 22901 3 22901 23189 23190 3 22901 23190 22902 3 22902 23190 23191 3 22902 23191 22903 3 22903 23191 22904 3 23192 22904 23191 3 22904 23192 22905 3 23193 22905 23192 3 22905 23193 22906 3 23194 22906 23193 3 22906 23194 22907 3 23195 22907 23194 3 22907 23195 22908 3 23196 22908 23195 3 22908 23196 22909 3 23197 22909 23196 3 22909 23197 22910 3 23198 22910 23197 3 22910 23198 22911 3 23199 22911 23198 3 22911 23199 22912 3 23200 22912 23199 3 22912 23200 22913 3 23201 22913 23200 3 22913 23201 22914 3 23202 22914 23201 3 22914 23202 22915 3 23203 22915 23202 3 22915 23203 22916 3 23204 22916 23203 3 22916 23204 22917 3 23205 22917 23204 3 22917 23205 22918 3 23206 22918 23205 3 22918 23206 22919 3 23207 22919 23206 3 22919 23207 22920 3 23208 22920 23207 3 22920 23208 22921 3 23209 22921 23208 3 22921 23209 22922 3 23210 22922 23209 3 22922 23210 22923 3 23211 22923 23210 3 22923 23211 22924 3 23212 22924 23211 3 22924 23212 22925 3 23213 22925 23212 3 22925 23213 22926 3 23214 22926 23213 3 22926 23214 22927 3 23215 22927 23214 3 22927 23215 22928 3 23216 22928 23215 3 22928 23216 22929 3 23217 22929 23216 3 22929 23217 22932 3 23220 22932 23217 3 22930 23218 22931 3 23219 22931 23218 3 22930 22935 23218 3 23223 23218 22935 3 22932 23220 22933 3 23221 22933 23220 3 22933 23221 22936 3 23224 22936 23221 3 22934 23222 22935 3 23223 22935 23222 3 22934 22938 23222 3 23226 23222 22938 3 22936 23224 22937 3 23225 22937 23224 3 22937 23225 22939 3 23227 22939 23225 3 22938 22940 23226 3 23228 23226 22940 3 22939 23227 22941 3 23229 22941 23227 3 22940 22942 23228 3 23230 23228 22942 3 22941 23229 22943 3 23231 22943 23229 3 22942 22944 23230 3 23232 23230 22944 3 22943 23231 22945 3 23233 22945 23231 3 22944 22946 23232 3 23234 23232 22946 3 22945 23233 22947 3 23235 22947 23233 3 22946 22948 23234 3 23236 23234 22948 3 22947 23235 22949 3 23237 22949 23235 3 22948 22950 23236 3 23238 23236 22950 3 22949 23237 22951 3 23239 22951 23237 3 22950 22952 23238 3 23240 23238 22952 3 22951 23239 22953 3 23241 22953 23239 3 22952 22954 23240 3 23242 23240 22954 3 22953 23241 22955 3 23243 22955 23241 3 22954 22956 23242 3 23244 23242 22956 3 22955 23243 22957 3 23245 22957 23243 3 22956 22958 23244 3 23246 23244 22958 3 22957 23245 22959 3 23247 22959 23245 3 22958 22960 23246 3 23248 23246 22960 3 22959 23247 22961 3 23249 22961 23247 3 22960 22962 23248 3 23250 23248 22962 3 22961 23249 22963 3 23251 22963 23249 3 22962 22964 23250 3 23252 23250 22964 3 22963 23251 22965 3 23253 22965 23251 3 22964 22966 23252 3 23254 23252 22966 3 22965 23253 22967 3 23255 22967 23253 3 22966 22968 23254 3 23256 23254 22968 3 22967 23255 22969 3 23257 22969 23255 3 22968 22970 23256 3 23258 23256 22970 3 22969 23257 22971 3 23259 22971 23257 3 22970 22972 23258 3 23260 23258 22972 3 22971 23259 22973 3 23261 22973 23259 3 22972 22974 23260 3 23262 23260 22974 3 22973 23261 22975 3 23263 22975 23261 3 22974 22976 23264 3 22974 23264 23262 3 22975 23263 22977 3 23265 22977 23263 3 22976 22978 23266 3 22976 23266 23264 3 22977 23265 22979 3 23267 22979 23265 3 22978 22980 23268 3 22978 23268 23266 3 22979 23267 22981 3 23269 22981 23267 3 22980 22982 23270 3 22980 23270 23268 3 22981 23269 22983 3 23271 22983 23269 3 22982 22984 23272 3 22982 23272 23270 3 22983 23271 22985 3 23273 22985 23271 3 22984 22986 23274 3 22984 23274 23272 3 22985 23273 22987 3 23275 22987 23273 3 22986 22988 23276 3 22986 23276 23274 3 22987 23275 22989 3 23277 22989 23275 3 22988 22990 23278 3 22988 23278 23276 3 22989 23277 22991 3 23279 22991 23277 3 22990 22992 23280 3 22990 23280 23278 3 22991 23279 22993 3 23281 22993 23279 3 22992 22994 23282 3 22992 23282 23280 3 22993 23281 22995 3 23283 22995 23281 3 22994 22996 23284 3 22994 23284 23282 3 22995 23283 22997 3 23285 22997 23283 3 22996 22998 23286 3 22996 23286 23284 3 22997 23285 23287 3 22997 23287 22999 3 22998 23000 23288 3 22998 23288 23286 3 22999 23287 23289 3 22999 23289 23001 3 23000 23002 23290 3 23000 23290 23288 3 23001 23289 23291 3 23001 23291 23003 3 23002 23004 23292 3 23002 23292 23290 3 23003 23291 23293 3 23003 23293 23005 3 23004 23006 23294 3 23004 23294 23292 3 23005 23293 23295 3 23005 23295 23007 3 23006 23008 23296 3 23006 23296 23294 3 23007 23295 23297 3 23007 23297 23009 3 23008 23010 23298 3 23008 23298 23296 3 23009 23297 23299 3 23009 23299 23011 3 23010 23012 23300 3 23010 23300 23298 3 23011 23299 23301 3 23011 23301 23013 3 23012 23014 23302 3 23012 23302 23300 3 23013 23301 23303 3 23013 23303 23015 3 23014 23016 23304 3 23014 23304 23302 3 23015 23303 23305 3 23015 23305 23017 3 23016 23018 23306 3 23016 23306 23304 3 23017 23305 23307 3 23017 23307 23019 3 23018 23020 23308 3 23018 23308 23306 3 23019 23307 23309 3 23019 23309 23021 3 23020 23022 23310 3 23020 23310 23308 3 23021 23309 23311 3 23021 23311 23023 3 23022 23024 23312 3 23022 23312 23310 3 23023 23311 23313 3 23023 23313 23025 3 23024 23026 23314 3 23024 23314 23312 3 23025 23313 23315 3 23025 23315 23027 3 23026 23028 23316 3 23026 23316 23314 3 23027 23315 23317 3 23027 23317 23029 3 23028 23030 23318 3 23028 23318 23316 3 23029 23317 23319 3 23029 23319 23031 3 23030 23032 23320 3 23030 23320 23318 3 23031 23319 23321 3 23031 23321 23033 3 23032 23034 23322 3 23032 23322 23320 3 23033 23321 23323 3 23033 23323 23035 3 23034 23036 23324 3 23034 23324 23322 3 23035 23323 23325 3 23035 23325 23037 3 23036 23038 23326 3 23036 23326 23324 3 23037 23325 23327 3 23037 23327 23039 3 23038 23040 23328 3 23038 23328 23326 3 23039 23327 23329 3 23039 23329 23041 3 23040 23042 23330 3 23040 23330 23328 3 23041 23329 23331 3 23041 23331 23043 3 23042 23044 23332 3 23042 23332 23330 3 23043 23331 23333 3 23043 23333 23045 3 23044 23046 23334 3 23044 23334 23332 3 23045 23333 23335 3 23045 23335 23047 3 23046 23048 23336 3 23046 23336 23334 3 23047 23335 23337 3 23047 23337 23049 3 23048 23050 23338 3 23048 23338 23336 3 23049 23337 23339 3 23049 23339 23051 3 23050 23052 23340 3 23050 23340 23338 3 23051 23339 23341 3 23051 23341 23053 3 23052 23054 23342 3 23052 23342 23340 3 23053 23341 23343 3 23053 23343 23055 3 23054 23056 23344 3 23054 23344 23342 3 23055 23343 23345 3 23055 23345 23057 3 23056 23058 23346 3 23056 23346 23344 3 23057 23345 23347 3 23057 23347 23059 3 23058 23060 23348 3 23058 23348 23346 3 23059 23347 23349 3 23059 23349 23061 3 23060 23062 23350 3 23060 23350 23348 3 23061 23349 23351 3 23061 23351 23063 3 23062 23064 23352 3 23062 23352 23350 3 23063 23351 23353 3 23063 23353 23065 3 23064 23066 23354 3 23064 23354 23352 3 23065 23353 23355 3 23065 23355 23067 3 23066 23068 23356 3 23066 23356 23354 3 23067 23355 23357 3 23067 23357 23069 3 23068 23070 23356 3 23358 23356 23070 3 23069 23357 23359 3 23069 23359 23071 3 23070 23072 23358 3 23360 23358 23072 3 23071 23359 23363 3 23071 23363 23075 3 23072 23073 23360 3 23361 23360 23073 3 23073 23076 23361 3 23364 23361 23076 3 23074 23075 23362 3 23363 23362 23075 3 23074 23362 23367 3 23074 23367 23079 3 23076 23077 23364 3 23365 23364 23077 3 23077 23080 23365 3 23368 23365 23080 3 23078 23079 23366 3 23367 23366 23079 3 23078 23366 23436 3 23078 23436 23148 3 23080 23081 23368 3 23369 23368 23081 3 23081 23082 23369 3 23370 23369 23082 3 23082 23083 23370 3 23371 23370 23083 3 23083 23084 23371 3 23372 23371 23084 3 23084 23085 23372 3 23373 23372 23085 3 23085 23086 23373 3 23374 23373 23086 3 23086 23087 23374 3 23375 23374 23087 3 23087 23088 23375 3 23376 23375 23088 3 23088 23089 23376 3 23377 23376 23089 3 23089 23090 23377 3 23378 23377 23090 3 23090 23091 23378 3 23379 23378 23091 3 23091 23092 23379 3 23380 23379 23092 3 23092 23093 23380 3 23381 23380 23093 3 23093 23094 23381 3 23382 23381 23094 3 23094 23095 23382 3 23383 23382 23095 3 23095 23096 23383 3 23384 23383 23096 3 23096 23097 23384 3 23385 23384 23097 3 23097 23098 23385 3 23386 23385 23098 3 23098 23099 23386 3 23387 23386 23099 3 23099 23100 23387 3 23388 23387 23100 3 23100 23101 23388 3 23389 23388 23101 3 23101 23102 23389 3 23390 23389 23102 3 23102 23103 23390 3 23391 23390 23103 3 23103 23104 23391 3 23392 23391 23104 3 23104 23105 23392 3 23393 23392 23105 3 23105 23106 23393 3 23394 23393 23106 3 23106 23107 23394 3 23395 23394 23107 3 23107 23108 23395 3 23396 23395 23108 3 23108 23109 23396 3 23397 23396 23109 3 23109 23110 23397 3 23398 23397 23110 3 23110 23111 23398 3 23399 23398 23111 3 23111 23112 23399 3 23400 23399 23112 3 23112 23113 23400 3 23401 23400 23113 3 23113 23114 23401 3 23402 23401 23114 3 23114 23115 23402 3 23403 23402 23115 3 23115 23116 23403 3 23404 23403 23116 3 23116 23117 23404 3 23405 23404 23117 3 23117 23118 23405 3 23406 23405 23118 3 23118 23119 23406 3 23407 23406 23119 3 23119 23120 23407 3 23408 23407 23120 3 23120 23121 23408 3 23409 23408 23121 3 23121 23122 23409 3 23410 23409 23122 3 23122 23123 23410 3 23411 23410 23123 3 23123 23124 23411 3 23412 23411 23124 3 23124 23125 23412 3 23413 23412 23125 3 23125 23126 23413 3 23414 23413 23126 3 23126 23127 23414 3 23415 23414 23127 3 23127 23128 23415 3 23416 23415 23128 3 23128 23129 23416 3 23417 23416 23129 3 23129 23130 23417 3 23418 23417 23130 3 23130 23131 23418 3 23419 23418 23131 3 23131 23132 23419 3 23420 23419 23132 3 23132 23133 23420 3 23421 23420 23133 3 23133 23134 23421 3 23422 23421 23134 3 23134 23135 23422 3 23423 23422 23135 3 23135 23136 23423 3 23424 23423 23136 3 23136 23137 23424 3 23425 23424 23137 3 23137 23138 23425 3 23426 23425 23138 3 23138 23139 23426 3 23427 23426 23139 3 23139 23140 23427 3 23428 23427 23140 3 23140 23141 23428 3 23429 23428 23141 3 23141 23142 23429 3 23430 23429 23142 3 23142 23143 23430 3 23431 23430 23143 3 23143 23144 23431 3 23432 23431 23144 3 23144 23145 23432 3 23433 23432 23145 3 23145 23146 23433 3 23434 23433 23146 3 23146 23147 23434 3 23435 23434 23147 3 23147 23148 23435 3 23436 23435 23148 3 23149 23437 23150 3 23438 23150 23437 3 23149 23219 23507 3 23149 23507 23437 3 23150 23438 23151 3 23439 23151 23438 3 23151 23439 23152 3 23440 23152 23439 3 23152 23440 23153 3 23441 23153 23440 3 23153 23441 23154 3 23442 23154 23441 3 23154 23442 23155 3 23443 23155 23442 3 23155 23443 23156 3 23444 23156 23443 3 23156 23444 23157 3 23445 23157 23444 3 23157 23445 23158 3 23446 23158 23445 3 23158 23446 23159 3 23447 23159 23446 3 23159 23447 23160 3 23448 23160 23447 3 23160 23448 23161 3 23449 23161 23448 3 23161 23449 23162 3 23450 23162 23449 3 23162 23450 23163 3 23451 23163 23450 3 23163 23451 23164 3 23452 23164 23451 3 23164 23452 23165 3 23453 23165 23452 3 23165 23453 23166 3 23454 23166 23453 3 23166 23454 23167 3 23455 23167 23454 3 23167 23455 23168 3 23456 23168 23455 3 23168 23456 23169 3 23457 23169 23456 3 23169 23457 23170 3 23458 23170 23457 3 23170 23458 23171 3 23459 23171 23458 3 23171 23459 23172 3 23460 23172 23459 3 23172 23460 23173 3 23461 23173 23460 3 23173 23461 23174 3 23462 23174 23461 3 23174 23462 23175 3 23463 23175 23462 3 23175 23463 23176 3 23464 23176 23463 3 23176 23464 23177 3 23465 23177 23464 3 23177 23465 23178 3 23466 23178 23465 3 23178 23466 23179 3 23467 23179 23466 3 23179 23467 23180 3 23468 23180 23467 3 23180 23468 23181 3 23469 23181 23468 3 23181 23469 23182 3 23470 23182 23469 3 23182 23470 23183 3 23471 23183 23470 3 23183 23471 23184 3 23472 23184 23471 3 23184 23472 23473 3 23184 23473 23185 3 23185 23473 23474 3 23185 23474 23186 3 23186 23474 23475 3 23186 23475 23187 3 23187 23475 23476 3 23187 23476 23188 3 23188 23476 23477 3 23188 23477 23189 3 23189 23477 23478 3 23189 23478 23190 3 23190 23478 23479 3 23190 23479 23191 3 23191 23479 23480 3 23191 23480 23192 3 23192 23480 23481 3 23192 23481 23193 3 23193 23481 23482 3 23193 23482 23194 3 23194 23482 23483 3 23194 23483 23195 3 23195 23483 23484 3 23195 23484 23196 3 23196 23484 23485 3 23196 23485 23197 3 23197 23485 23486 3 23197 23486 23198 3 23198 23486 23487 3 23198 23487 23199 3 23199 23487 23488 3 23199 23488 23200 3 23200 23488 23489 3 23200 23489 23201 3 23201 23489 23490 3 23201 23490 23202 3 23202 23490 23491 3 23202 23491 23203 3 23203 23491 23492 3 23203 23492 23204 3 23204 23492 23493 3 23204 23493 23205 3 23205 23493 23494 3 23205 23494 23206 3 23206 23494 23495 3 23206 23495 23207 3 23207 23495 23496 3 23207 23496 23208 3 23208 23496 23497 3 23208 23497 23209 3 23209 23497 23498 3 23209 23498 23210 3 23210 23498 23499 3 23210 23499 23211 3 23211 23499 23500 3 23211 23500 23212 3 23212 23500 23501 3 23212 23501 23213 3 23213 23501 23502 3 23213 23502 23214 3 23214 23502 23503 3 23214 23503 23215 3 23215 23503 23504 3 23215 23504 23216 3 23216 23504 23505 3 23216 23505 23217 3 23217 23505 23508 3 23217 23508 23220 3 23218 23506 23507 3 23218 23507 23219 3 23218 23223 23511 3 23218 23511 23506 3 23220 23508 23509 3 23220 23509 23221 3 23221 23509 23512 3 23221 23512 23224 3 23222 23510 23511 3 23222 23511 23223 3 23222 23226 23514 3 23222 23514 23510 3 23224 23512 23513 3 23224 23513 23225 3 23225 23513 23515 3 23225 23515 23227 3 23226 23228 23516 3 23226 23516 23514 3 23227 23515 23517 3 23227 23517 23229 3 23228 23230 23518 3 23228 23518 23516 3 23229 23517 23519 3 23229 23519 23231 3 23230 23232 23520 3 23230 23520 23518 3 23231 23519 23521 3 23231 23521 23233 3 23232 23234 23522 3 23232 23522 23520 3 23233 23521 23523 3 23233 23523 23235 3 23234 23236 23524 3 23234 23524 23522 3 23235 23523 23525 3 23235 23525 23237 3 23236 23238 23526 3 23236 23526 23524 3 23237 23525 23527 3 23237 23527 23239 3 23238 23240 23528 3 23238 23528 23526 3 23239 23527 23529 3 23239 23529 23241 3 23240 23242 23530 3 23240 23530 23528 3 23241 23529 23531 3 23241 23531 23243 3 23242 23244 23532 3 23242 23532 23530 3 23243 23531 23533 3 23243 23533 23245 3 23244 23246 23534 3 23244 23534 23532 3 23245 23533 23535 3 23245 23535 23247 3 23246 23248 23536 3 23246 23536 23534 3 23247 23535 23537 3 23247 23537 23249 3 23248 23250 23538 3 23248 23538 23536 3 23249 23537 23539 3 23249 23539 23251 3 23250 23252 23540 3 23250 23540 23538 3 23251 23539 23541 3 23251 23541 23253 3 23252 23254 23542 3 23252 23542 23540 3 23253 23541 23543 3 23253 23543 23255 3 23254 23256 23544 3 23254 23544 23542 3 23255 23543 23545 3 23255 23545 23257 3 23256 23258 23544 3 23546 23544 23258 3 23257 23545 23547 3 23257 23547 23259 3 23258 23260 23546 3 23548 23546 23260 3 23259 23547 23549 3 23259 23549 23261 3 23260 23262 23548 3 23550 23548 23262 3 23261 23549 23551 3 23261 23551 23263 3 23262 23264 23550 3 23552 23550 23264 3 23263 23551 23553 3 23263 23553 23265 3 23264 23266 23552 3 23554 23552 23266 3 23265 23553 23555 3 23265 23555 23267 3 23266 23268 23554 3 23556 23554 23268 3 23267 23555 23557 3 23267 23557 23269 3 23268 23270 23556 3 23558 23556 23270 3 23269 23557 23559 3 23269 23559 23271 3 23270 23272 23558 3 23560 23558 23272 3 23271 23559 23561 3 23271 23561 23273 3 23272 23274 23560 3 23562 23560 23274 3 23273 23561 23563 3 23273 23563 23275 3 23274 23276 23562 3 23564 23562 23276 3 23275 23563 23565 3 23275 23565 23277 3 23276 23278 23564 3 23566 23564 23278 3 23277 23565 23567 3 23277 23567 23279 3 23278 23280 23566 3 23568 23566 23280 3 23279 23567 23281 3 23569 23281 23567 3 23280 23282 23568 3 23570 23568 23282 3 23281 23569 23283 3 23571 23283 23569 3 23282 23284 23570 3 23572 23570 23284 3 23283 23571 23285 3 23573 23285 23571 3 23284 23286 23572 3 23574 23572 23286 3 23285 23573 23287 3 23575 23287 23573 3 23286 23288 23574 3 23576 23574 23288 3 23287 23575 23289 3 23577 23289 23575 3 23288 23290 23576 3 23578 23576 23290 3 23289 23577 23291 3 23579 23291 23577 3 23290 23292 23578 3 23580 23578 23292 3 23291 23579 23293 3 23581 23293 23579 3 23292 23294 23580 3 23582 23580 23294 3 23293 23581 23295 3 23583 23295 23581 3 23294 23296 23582 3 23584 23582 23296 3 23295 23583 23297 3 23585 23297 23583 3 23296 23298 23584 3 23586 23584 23298 3 23297 23585 23299 3 23587 23299 23585 3 23298 23300 23586 3 23588 23586 23300 3 23299 23587 23301 3 23589 23301 23587 3 23300 23302 23588 3 23590 23588 23302 3 23301 23589 23303 3 23591 23303 23589 3 23302 23304 23590 3 23592 23590 23304 3 23303 23591 23305 3 23593 23305 23591 3 23304 23306 23592 3 23594 23592 23306 3 23305 23593 23307 3 23595 23307 23593 3 23306 23308 23594 3 23596 23594 23308 3 23307 23595 23309 3 23597 23309 23595 3 23308 23310 23596 3 23598 23596 23310 3 23309 23597 23311 3 23599 23311 23597 3 23310 23312 23598 3 23600 23598 23312 3 23311 23599 23313 3 23601 23313 23599 3 23312 23314 23600 3 23602 23600 23314 3 23313 23601 23315 3 23603 23315 23601 3 23314 23316 23602 3 23604 23602 23316 3 23315 23603 23317 3 23605 23317 23603 3 23316 23318 23604 3 23606 23604 23318 3 23317 23605 23319 3 23607 23319 23605 3 23318 23320 23606 3 23608 23606 23320 3 23319 23607 23321 3 23609 23321 23607 3 23320 23322 23608 3 23610 23608 23322 3 23321 23609 23323 3 23611 23323 23609 3 23322 23324 23610 3 23612 23610 23324 3 23323 23611 23325 3 23613 23325 23611 3 23324 23326 23612 3 23614 23612 23326 3 23325 23613 23327 3 23615 23327 23613 3 23326 23328 23614 3 23616 23614 23328 3 23327 23615 23329 3 23617 23329 23615 3 23328 23330 23616 3 23618 23616 23330 3 23329 23617 23331 3 23619 23331 23617 3 23330 23332 23618 3 23620 23618 23332 3 23331 23619 23333 3 23621 23333 23619 3 23332 23334 23620 3 23622 23620 23334 3 23333 23621 23335 3 23623 23335 23621 3 23334 23336 23622 3 23624 23622 23336 3 23335 23623 23337 3 23625 23337 23623 3 23336 23338 23624 3 23626 23624 23338 3 23337 23625 23339 3 23627 23339 23625 3 23338 23340 23626 3 23628 23626 23340 3 23339 23627 23341 3 23629 23341 23627 3 23340 23342 23628 3 23630 23628 23342 3 23341 23629 23343 3 23631 23343 23629 3 23342 23344 23630 3 23632 23630 23344 3 23343 23631 23345 3 23633 23345 23631 3 23344 23346 23632 3 23634 23632 23346 3 23345 23633 23347 3 23635 23347 23633 3 23346 23348 23634 3 23636 23634 23348 3 23347 23635 23349 3 23637 23349 23635 3 23348 23350 23636 3 23638 23636 23350 3 23349 23637 23351 3 23639 23351 23637 3 23350 23352 23640 3 23350 23640 23638 3 23351 23639 23353 3 23641 23353 23639 3 23352 23354 23642 3 23352 23642 23640 3 23353 23641 23355 3 23643 23355 23641 3 23354 23356 23644 3 23354 23644 23642 3 23355 23643 23357 3 23645 23357 23643 3 23356 23358 23646 3 23356 23646 23644 3 23357 23645 23359 3 23647 23359 23645 3 23358 23360 23648 3 23358 23648 23646 3 23359 23647 23363 3 23651 23363 23647 3 23360 23361 23649 3 23360 23649 23648 3 23361 23364 23652 3 23361 23652 23649 3 23362 23363 23651 3 23362 23651 23650 3 23362 23650 23367 3 23655 23367 23650 3 23364 23365 23653 3 23364 23653 23652 3 23365 23368 23656 3 23365 23656 23653 3 23366 23367 23655 3 23366 23655 23654 3 23366 23654 23436 3 23724 23436 23654 3 23368 23369 23657 3 23368 23657 23656 3 23369 23370 23658 3 23369 23658 23657 3 23370 23371 23659 3 23370 23659 23658 3 23371 23372 23660 3 23371 23660 23659 3 23372 23373 23661 3 23372 23661 23660 3 23373 23374 23662 3 23373 23662 23661 3 23374 23375 23663 3 23374 23663 23662 3 23375 23376 23664 3 23375 23664 23663 3 23376 23377 23665 3 23376 23665 23664 3 23377 23378 23666 3 23377 23666 23665 3 23378 23379 23667 3 23378 23667 23666 3 23379 23380 23668 3 23379 23668 23667 3 23380 23381 23669 3 23380 23669 23668 3 23381 23382 23670 3 23381 23670 23669 3 23382 23383 23671 3 23382 23671 23670 3 23383 23384 23672 3 23383 23672 23671 3 23384 23385 23673 3 23384 23673 23672 3 23385 23386 23674 3 23385 23674 23673 3 23386 23387 23675 3 23386 23675 23674 3 23387 23388 23676 3 23387 23676 23675 3 23388 23389 23677 3 23388 23677 23676 3 23389 23390 23678 3 23389 23678 23677 3 23390 23391 23679 3 23390 23679 23678 3 23391 23392 23680 3 23391 23680 23679 3 23392 23393 23681 3 23392 23681 23680 3 23393 23394 23682 3 23393 23682 23681 3 23394 23395 23683 3 23394 23683 23682 3 23395 23396 23684 3 23395 23684 23683 3 23396 23397 23685 3 23396 23685 23684 3 23397 23398 23686 3 23397 23686 23685 3 23398 23399 23687 3 23398 23687 23686 3 23399 23400 23688 3 23399 23688 23687 3 23400 23401 23689 3 23400 23689 23688 3 23401 23402 23690 3 23401 23690 23689 3 23402 23403 23691 3 23402 23691 23690 3 23403 23404 23692 3 23403 23692 23691 3 23404 23405 23693 3 23404 23693 23692 3 23405 23406 23694 3 23405 23694 23693 3 23406 23407 23695 3 23406 23695 23694 3 23407 23408 23696 3 23407 23696 23695 3 23408 23409 23697 3 23408 23697 23696 3 23409 23410 23698 3 23409 23698 23697 3 23410 23411 23699 3 23410 23699 23698 3 23411 23412 23700 3 23411 23700 23699 3 23412 23413 23701 3 23412 23701 23700 3 23413 23414 23702 3 23413 23702 23701 3 23414 23415 23703 3 23414 23703 23702 3 23415 23416 23704 3 23415 23704 23703 3 23416 23417 23705 3 23416 23705 23704 3 23417 23418 23706 3 23417 23706 23705 3 23418 23419 23707 3 23418 23707 23706 3 23419 23420 23708 3 23419 23708 23707 3 23420 23421 23709 3 23420 23709 23708 3 23421 23422 23710 3 23421 23710 23709 3 23422 23423 23711 3 23422 23711 23710 3 23423 23424 23712 3 23423 23712 23711 3 23424 23425 23713 3 23424 23713 23712 3 23425 23426 23714 3 23425 23714 23713 3 23426 23427 23715 3 23426 23715 23714 3 23427 23428 23716 3 23427 23716 23715 3 23428 23429 23717 3 23428 23717 23716 3 23429 23430 23718 3 23429 23718 23717 3 23430 23431 23719 3 23430 23719 23718 3 23431 23432 23720 3 23431 23720 23719 3 23432 23433 23721 3 23432 23721 23720 3 23433 23434 23722 3 23433 23722 23721 3 23434 23435 23723 3 23434 23723 23722 3 23435 23436 23724 3 23435 23724 23723 3 23437 23725 23726 3 23437 23726 23438 3 23437 23507 23725 3 23795 23725 23507 3 23438 23726 23727 3 23438 23727 23439 3 23439 23727 23728 3 23439 23728 23440 3 23440 23728 23729 3 23440 23729 23441 3 23441 23729 23730 3 23441 23730 23442 3 23442 23730 23731 3 23442 23731 23443 3 23443 23731 23732 3 23443 23732 23444 3 23444 23732 23733 3 23444 23733 23445 3 23445 23733 23734 3 23445 23734 23446 3 23446 23734 23735 3 23446 23735 23447 3 23447 23735 23736 3 23447 23736 23448 3 23448 23736 23737 3 23448 23737 23449 3 23449 23737 23738 3 23449 23738 23450 3 23450 23738 23739 3 23450 23739 23451 3 23451 23739 23740 3 23451 23740 23452 3 23452 23740 23741 3 23452 23741 23453 3 23453 23741 23742 3 23453 23742 23454 3 23454 23742 23743 3 23454 23743 23455 3 23455 23743 23744 3 23455 23744 23456 3 23456 23744 23745 3 23456 23745 23457 3 23457 23745 23746 3 23457 23746 23458 3 23458 23746 23747 3 23458 23747 23459 3 23459 23747 23748 3 23459 23748 23460 3 23460 23748 23749 3 23460 23749 23461 3 23461 23749 23750 3 23461 23750 23462 3 23462 23750 23751 3 23462 23751 23463 3 23463 23751 23752 3 23463 23752 23464 3 23464 23752 23753 3 23464 23753 23465 3 23465 23753 23754 3 23465 23754 23466 3 23466 23754 23755 3 23466 23755 23467 3 23467 23755 23468 3 23756 23468 23755 3 23468 23756 23469 3 23757 23469 23756 3 23469 23757 23470 3 23758 23470 23757 3 23470 23758 23471 3 23759 23471 23758 3 23471 23759 23472 3 23760 23472 23759 3 23472 23760 23473 3 23761 23473 23760 3 23473 23761 23474 3 23762 23474 23761 3 23474 23762 23475 3 23763 23475 23762 3 23475 23763 23476 3 23764 23476 23763 3 23476 23764 23477 3 23765 23477 23764 3 23477 23765 23478 3 23766 23478 23765 3 23478 23766 23479 3 23767 23479 23766 3 23479 23767 23480 3 23768 23480 23767 3 23480 23768 23481 3 23769 23481 23768 3 23481 23769 23482 3 23770 23482 23769 3 23482 23770 23483 3 23771 23483 23770 3 23483 23771 23484 3 23772 23484 23771 3 23484 23772 23485 3 23773 23485 23772 3 23485 23773 23486 3 23774 23486 23773 3 23486 23774 23487 3 23775 23487 23774 3 23487 23775 23488 3 23776 23488 23775 3 23488 23776 23489 3 23777 23489 23776 3 23489 23777 23490 3 23778 23490 23777 3 23490 23778 23491 3 23779 23491 23778 3 23491 23779 23492 3 23780 23492 23779 3 23492 23780 23493 3 23781 23493 23780 3 23493 23781 23494 3 23782 23494 23781 3 23494 23782 23495 3 23783 23495 23782 3 23495 23783 23496 3 23784 23496 23783 3 23496 23784 23497 3 23785 23497 23784 3 23497 23785 23498 3 23786 23498 23785 3 23498 23786 23499 3 23787 23499 23786 3 23499 23787 23500 3 23788 23500 23787 3 23500 23788 23501 3 23789 23501 23788 3 23501 23789 23502 3 23790 23502 23789 3 23502 23790 23503 3 23791 23503 23790 3 23503 23791 23504 3 23792 23504 23791 3 23504 23792 23505 3 23793 23505 23792 3 23505 23793 23508 3 23796 23508 23793 3 23506 23794 23507 3 23795 23507 23794 3 23506 23511 23794 3 23799 23794 23511 3 23508 23796 23509 3 23797 23509 23796 3 23509 23797 23512 3 23800 23512 23797 3 23510 23798 23511 3 23799 23511 23798 3 23510 23514 23798 3 23802 23798 23514 3 23512 23800 23513 3 23801 23513 23800 3 23513 23801 23515 3 23803 23515 23801 3 23514 23516 23802 3 23804 23802 23516 3 23515 23803 23517 3 23805 23517 23803 3 23516 23518 23804 3 23806 23804 23518 3 23517 23805 23519 3 23807 23519 23805 3 23518 23520 23806 3 23808 23806 23520 3 23519 23807 23521 3 23809 23521 23807 3 23520 23522 23808 3 23810 23808 23522 3 23521 23809 23523 3 23811 23523 23809 3 23522 23524 23810 3 23812 23810 23524 3 23523 23811 23525 3 23813 23525 23811 3 23524 23526 23812 3 23814 23812 23526 3 23525 23813 23527 3 23815 23527 23813 3 23526 23528 23814 3 23816 23814 23528 3 23527 23815 23529 3 23817 23529 23815 3 23528 23530 23816 3 23818 23816 23530 3 23529 23817 23531 3 23819 23531 23817 3 23530 23532 23818 3 23820 23818 23532 3 23531 23819 23533 3 23821 23533 23819 3 23532 23534 23820 3 23822 23820 23534 3 23533 23821 23535 3 23823 23535 23821 3 23534 23536 23822 3 23824 23822 23536 3 23535 23823 23537 3 23825 23537 23823 3 23536 23538 23824 3 23826 23824 23538 3 23537 23825 23539 3 23827 23539 23825 3 23538 23540 23828 3 23538 23828 23826 3 23539 23827 23541 3 23829 23541 23827 3 23540 23542 23830 3 23540 23830 23828 3 23541 23829 23543 3 23831 23543 23829 3 23542 23544 23832 3 23542 23832 23830 3 23543 23831 23545 3 23833 23545 23831 3 23544 23546 23834 3 23544 23834 23832 3 23545 23833 23547 3 23835 23547 23833 3 23546 23548 23836 3 23546 23836 23834 3 23547 23835 23549 3 23837 23549 23835 3 23548 23550 23838 3 23548 23838 23836 3 23549 23837 23551 3 23839 23551 23837 3 23550 23552 23840 3 23550 23840 23838 3 23551 23839 23553 3 23841 23553 23839 3 23552 23554 23842 3 23552 23842 23840 3 23553 23841 23555 3 23843 23555 23841 3 23554 23556 23844 3 23554 23844 23842 3 23555 23843 23557 3 23845 23557 23843 3 23556 23558 23846 3 23556 23846 23844 3 23557 23845 23559 3 23847 23559 23845 3 23558 23560 23848 3 23558 23848 23846 3 23559 23847 23561 3 23849 23561 23847 3 23560 23562 23850 3 23560 23850 23848 3 23561 23849 23563 3 23851 23563 23849 3 23562 23564 23852 3 23562 23852 23850 3 23563 23851 23853 3 23563 23853 23565 3 23564 23566 23854 3 23564 23854 23852 3 23565 23853 23855 3 23565 23855 23567 3 23566 23568 23856 3 23566 23856 23854 3 23567 23855 23857 3 23567 23857 23569 3 23568 23570 23858 3 23568 23858 23856 3 23569 23857 23859 3 23569 23859 23571 3 23570 23572 23860 3 23570 23860 23858 3 23571 23859 23861 3 23571 23861 23573 3 23572 23574 23862 3 23572 23862 23860 3 23573 23861 23863 3 23573 23863 23575 3 23574 23576 23864 3 23574 23864 23862 3 23575 23863 23865 3 23575 23865 23577 3 23576 23578 23866 3 23576 23866 23864 3 23577 23865 23867 3 23577 23867 23579 3 23578 23580 23868 3 23578 23868 23866 3 23579 23867 23869 3 23579 23869 23581 3 23580 23582 23870 3 23580 23870 23868 3 23581 23869 23871 3 23581 23871 23583 3 23582 23584 23872 3 23582 23872 23870 3 23583 23871 23873 3 23583 23873 23585 3 23584 23586 23874 3 23584 23874 23872 3 23585 23873 23875 3 23585 23875 23587 3 23586 23588 23876 3 23586 23876 23874 3 23587 23875 23877 3 23587 23877 23589 3 23588 23590 23878 3 23588 23878 23876 3 23589 23877 23879 3 23589 23879 23591 3 23590 23592 23880 3 23590 23880 23878 3 23591 23879 23881 3 23591 23881 23593 3 23592 23594 23882 3 23592 23882 23880 3 23593 23881 23883 3 23593 23883 23595 3 23594 23596 23884 3 23594 23884 23882 3 23595 23883 23885 3 23595 23885 23597 3 23596 23598 23886 3 23596 23886 23884 3 23597 23885 23887 3 23597 23887 23599 3 23598 23600 23888 3 23598 23888 23886 3 23599 23887 23889 3 23599 23889 23601 3 23600 23602 23890 3 23600 23890 23888 3 23601 23889 23891 3 23601 23891 23603 3 23602 23604 23892 3 23602 23892 23890 3 23603 23891 23893 3 23603 23893 23605 3 23604 23606 23894 3 23604 23894 23892 3 23605 23893 23895 3 23605 23895 23607 3 23606 23608 23896 3 23606 23896 23894 3 23607 23895 23897 3 23607 23897 23609 3 23608 23610 23898 3 23608 23898 23896 3 23609 23897 23899 3 23609 23899 23611 3 23610 23612 23900 3 23610 23900 23898 3 23611 23899 23901 3 23611 23901 23613 3 23612 23614 23902 3 23612 23902 23900 3 23613 23901 23903 3 23613 23903 23615 3 23614 23616 23904 3 23614 23904 23902 3 23615 23903 23905 3 23615 23905 23617 3 23616 23618 23906 3 23616 23906 23904 3 23617 23905 23907 3 23617 23907 23619 3 23618 23620 23908 3 23618 23908 23906 3 23619 23907 23909 3 23619 23909 23621 3 23620 23622 23910 3 23620 23910 23908 3 23621 23909 23911 3 23621 23911 23623 3 23622 23624 23912 3 23622 23912 23910 3 23623 23911 23913 3 23623 23913 23625 3 23624 23626 23914 3 23624 23914 23912 3 23625 23913 23915 3 23625 23915 23627 3 23626 23628 23916 3 23626 23916 23914 3 23627 23915 23917 3 23627 23917 23629 3 23628 23630 23918 3 23628 23918 23916 3 23629 23917 23919 3 23629 23919 23631 3 23630 23632 23920 3 23630 23920 23918 3 23631 23919 23921 3 23631 23921 23633 3 23632 23634 23920 3 23922 23920 23634 3 23633 23921 23923 3 23633 23923 23635 3 23634 23636 23922 3 23924 23922 23636 3 23635 23923 23925 3 23635 23925 23637 3 23636 23638 23924 3 23926 23924 23638 3 23637 23925 23927 3 23637 23927 23639 3 23638 23640 23926 3 23928 23926 23640 3 23639 23927 23929 3 23639 23929 23641 3 23640 23642 23928 3 23930 23928 23642 3 23641 23929 23931 3 23641 23931 23643 3 23642 23644 23930 3 23932 23930 23644 3 23643 23931 23933 3 23643 23933 23645 3 23644 23646 23932 3 23934 23932 23646 3 23645 23933 23935 3 23645 23935 23647 3 23646 23648 23934 3 23936 23934 23648 3 23647 23935 23939 3 23647 23939 23651 3 23648 23649 23936 3 23937 23936 23649 3 23649 23652 23937 3 23940 23937 23652 3 23650 23651 23938 3 23939 23938 23651 3 23650 23938 23943 3 23650 23943 23655 3 23652 23653 23940 3 23941 23940 23653 3 23653 23656 23941 3 23944 23941 23656 3 23654 23655 23942 3 23943 23942 23655 3 23654 23942 24012 3 23654 24012 23724 3 23656 23657 23944 3 23945 23944 23657 3 23657 23658 23945 3 23946 23945 23658 3 23658 23659 23946 3 23947 23946 23659 3 23659 23660 23947 3 23948 23947 23660 3 23660 23661 23948 3 23949 23948 23661 3 23661 23662 23949 3 23950 23949 23662 3 23662 23663 23950 3 23951 23950 23663 3 23663 23664 23951 3 23952 23951 23664 3 23664 23665 23952 3 23953 23952 23665 3 23665 23666 23953 3 23954 23953 23666 3 23666 23667 23954 3 23955 23954 23667 3 23667 23668 23955 3 23956 23955 23668 3 23668 23669 23956 3 23957 23956 23669 3 23669 23670 23957 3 23958 23957 23670 3 23670 23671 23958 3 23959 23958 23671 3 23671 23672 23959 3 23960 23959 23672 3 23672 23673 23960 3 23961 23960 23673 3 23673 23674 23961 3 23962 23961 23674 3 23674 23675 23962 3 23963 23962 23675 3 23675 23676 23963 3 23964 23963 23676 3 23676 23677 23964 3 23965 23964 23677 3 23677 23678 23965 3 23966 23965 23678 3 23678 23679 23966 3 23967 23966 23679 3 23679 23680 23967 3 23968 23967 23680 3 23680 23681 23968 3 23969 23968 23681 3 23681 23682 23969 3 23970 23969 23682 3 23682 23683 23970 3 23971 23970 23683 3 23683 23684 23971 3 23972 23971 23684 3 23684 23685 23972 3 23973 23972 23685 3 23685 23686 23973 3 23974 23973 23686 3 23686 23687 23974 3 23975 23974 23687 3 23687 23688 23975 3 23976 23975 23688 3 23688 23689 23976 3 23977 23976 23689 3 23689 23690 23977 3 23978 23977 23690 3 23690 23691 23978 3 23979 23978 23691 3 23691 23692 23979 3 23980 23979 23692 3 23692 23693 23980 3 23981 23980 23693 3 23693 23694 23981 3 23982 23981 23694 3 23694 23695 23982 3 23983 23982 23695 3 23695 23696 23983 3 23984 23983 23696 3 23696 23697 23984 3 23985 23984 23697 3 23697 23698 23985 3 23986 23985 23698 3 23698 23699 23986 3 23987 23986 23699 3 23699 23700 23987 3 23988 23987 23700 3 23700 23701 23988 3 23989 23988 23701 3 23701 23702 23989 3 23990 23989 23702 3 23702 23703 23990 3 23991 23990 23703 3 23703 23704 23991 3 23992 23991 23704 3 23704 23705 23992 3 23993 23992 23705 3 23705 23706 23993 3 23994 23993 23706 3 23706 23707 23994 3 23995 23994 23707 3 23707 23708 23995 3 23996 23995 23708 3 23708 23709 23996 3 23997 23996 23709 3 23709 23710 23997 3 23998 23997 23710 3 23710 23711 23998 3 23999 23998 23711 3 23711 23712 23999 3 24000 23999 23712 3 23712 23713 24000 3 24001 24000 23713 3 23713 23714 24001 3 24002 24001 23714 3 23714 23715 24002 3 24003 24002 23715 3 23715 23716 24003 3 24004 24003 23716 3 23716 23717 24004 3 24005 24004 23717 3 23717 23718 24005 3 24006 24005 23718 3 23718 23719 24006 3 24007 24006 23719 3 23719 23720 24007 3 24008 24007 23720 3 23720 23721 24008 3 24009 24008 23721 3 23721 23722 24009 3 24010 24009 23722 3 23722 23723 24010 3 24011 24010 23723 3 23723 23724 24011 3 24012 24011 23724 3 23725 24013 23726 3 24014 23726 24013 3 23725 23795 24083 3 23725 24083 24013 3 23726 24014 23727 3 24015 23727 24014 3 23727 24015 23728 3 24016 23728 24015 3 23728 24016 23729 3 24017 23729 24016 3 23729 24017 23730 3 24018 23730 24017 3 23730 24018 23731 3 24019 23731 24018 3 23731 24019 23732 3 24020 23732 24019 3 23732 24020 23733 3 24021 23733 24020 3 23733 24021 23734 3 24022 23734 24021 3 23734 24022 23735 3 24023 23735 24022 3 23735 24023 23736 3 24024 23736 24023 3 23736 24024 23737 3 24025 23737 24024 3 23737 24025 23738 3 24026 23738 24025 3 23738 24026 23739 3 24027 23739 24026 3 23739 24027 23740 3 24028 23740 24027 3 23740 24028 23741 3 24029 23741 24028 3 23741 24029 23742 3 24030 23742 24029 3 23742 24030 23743 3 24031 23743 24030 3 23743 24031 23744 3 24032 23744 24031 3 23744 24032 23745 3 24033 23745 24032 3 23745 24033 23746 3 24034 23746 24033 3 23746 24034 23747 3 24035 23747 24034 3 23747 24035 23748 3 24036 23748 24035 3 23748 24036 23749 3 24037 23749 24036 3 23749 24037 23750 3 24038 23750 24037 3 23750 24038 23751 3 24039 23751 24038 3 23751 24039 23752 3 24040 23752 24039 3 23752 24040 24041 3 23752 24041 23753 3 23753 24041 24042 3 23753 24042 23754 3 23754 24042 24043 3 23754 24043 23755 3 23755 24043 24044 3 23755 24044 23756 3 23756 24044 24045 3 23756 24045 23757 3 23757 24045 24046 3 23757 24046 23758 3 23758 24046 24047 3 23758 24047 23759 3 23759 24047 24048 3 23759 24048 23760 3 23760 24048 24049 3 23760 24049 23761 3 23761 24049 24050 3 23761 24050 23762 3 23762 24050 24051 3 23762 24051 23763 3 23763 24051 24052 3 23763 24052 23764 3 23764 24052 24053 3 23764 24053 23765 3 23765 24053 24054 3 23765 24054 23766 3 23766 24054 24055 3 23766 24055 23767 3 23767 24055 24056 3 23767 24056 23768 3 23768 24056 24057 3 23768 24057 23769 3 23769 24057 24058 3 23769 24058 23770 3 23770 24058 24059 3 23770 24059 23771 3 23771 24059 24060 3 23771 24060 23772 3 23772 24060 24061 3 23772 24061 23773 3 23773 24061 24062 3 23773 24062 23774 3 23774 24062 24063 3 23774 24063 23775 3 23775 24063 24064 3 23775 24064 23776 3 23776 24064 24065 3 23776 24065 23777 3 23777 24065 24066 3 23777 24066 23778 3 23778 24066 24067 3 23778 24067 23779 3 23779 24067 24068 3 23779 24068 23780 3 23780 24068 24069 3 23780 24069 23781 3 23781 24069 24070 3 23781 24070 23782 3 23782 24070 24071 3 23782 24071 23783 3 23783 24071 24072 3 23783 24072 23784 3 23784 24072 24073 3 23784 24073 23785 3 23785 24073 24074 3 23785 24074 23786 3 23786 24074 24075 3 23786 24075 23787 3 23787 24075 24076 3 23787 24076 23788 3 23788 24076 24077 3 23788 24077 23789 3 23789 24077 24078 3 23789 24078 23790 3 23790 24078 24079 3 23790 24079 23791 3 23791 24079 24080 3 23791 24080 23792 3 23792 24080 24081 3 23792 24081 23793 3 23793 24081 24084 3 23793 24084 23796 3 23794 24082 24083 3 23794 24083 23795 3 23794 23799 24087 3 23794 24087 24082 3 23796 24084 24085 3 23796 24085 23797 3 23797 24085 24088 3 23797 24088 23800 3 23798 24086 24087 3 23798 24087 23799 3 23798 23802 24090 3 23798 24090 24086 3 23800 24088 24089 3 23800 24089 23801 3 23801 24089 24091 3 23801 24091 23803 3 23802 23804 24092 3 23802 24092 24090 3 23803 24091 24093 3 23803 24093 23805 3 23804 23806 24094 3 23804 24094 24092 3 23805 24093 24095 3 23805 24095 23807 3 23806 23808 24096 3 23806 24096 24094 3 23807 24095 24097 3 23807 24097 23809 3 23808 23810 24098 3 23808 24098 24096 3 23809 24097 24099 3 23809 24099 23811 3 23810 23812 24100 3 23810 24100 24098 3 23811 24099 24101 3 23811 24101 23813 3 23812 23814 24102 3 23812 24102 24100 3 23813 24101 24103 3 23813 24103 23815 3 23814 23816 24104 3 23814 24104 24102 3 23815 24103 24105 3 23815 24105 23817 3 23816 23818 24106 3 23816 24106 24104 3 23817 24105 24107 3 23817 24107 23819 3 23818 23820 24108 3 23818 24108 24106 3 23819 24107 24109 3 23819 24109 23821 3 23820 23822 24110 3 23820 24110 24108 3 23821 24109 24111 3 23821 24111 23823 3 23822 23824 24110 3 24112 24110 23824 3 23823 24111 24113 3 23823 24113 23825 3 23824 23826 24112 3 24114 24112 23826 3 23825 24113 24115 3 23825 24115 23827 3 23826 23828 24114 3 24116 24114 23828 3 23827 24115 24117 3 23827 24117 23829 3 23828 23830 24116 3 24118 24116 23830 3 23829 24117 24119 3 23829 24119 23831 3 23830 23832 24118 3 24120 24118 23832 3 23831 24119 24121 3 23831 24121 23833 3 23832 23834 24120 3 24122 24120 23834 3 23833 24121 24123 3 23833 24123 23835 3 23834 23836 24122 3 24124 24122 23836 3 23835 24123 24125 3 23835 24125 23837 3 23836 23838 24124 3 24126 24124 23838 3 23837 24125 24127 3 23837 24127 23839 3 23838 23840 24126 3 24128 24126 23840 3 23839 24127 24129 3 23839 24129 23841 3 23840 23842 24128 3 24130 24128 23842 3 23841 24129 24131 3 23841 24131 23843 3 23842 23844 24130 3 24132 24130 23844 3 23843 24131 24133 3 23843 24133 23845 3 23844 23846 24132 3 24134 24132 23846 3 23845 24133 24135 3 23845 24135 23847 3 23846 23848 24134 3 24136 24134 23848 3 23847 24135 23849 3 24137 23849 24135 3 23848 23850 24136 3 24138 24136 23850 3 23849 24137 23851 3 24139 23851 24137 3 23850 23852 24138 3 24140 24138 23852 3 23851 24139 23853 3 24141 23853 24139 3 23852 23854 24140 3 24142 24140 23854 3 23853 24141 23855 3 24143 23855 24141 3 23854 23856 24142 3 24144 24142 23856 3 23855 24143 23857 3 24145 23857 24143 3 23856 23858 24144 3 24146 24144 23858 3 23857 24145 23859 3 24147 23859 24145 3 23858 23860 24146 3 24148 24146 23860 3 23859 24147 23861 3 24149 23861 24147 3 23860 23862 24148 3 24150 24148 23862 3 23861 24149 23863 3 24151 23863 24149 3 23862 23864 24150 3 24152 24150 23864 3 23863 24151 23865 3 24153 23865 24151 3 23864 23866 24152 3 24154 24152 23866 3 23865 24153 23867 3 24155 23867 24153 3 23866 23868 24154 3 24156 24154 23868 3 23867 24155 23869 3 24157 23869 24155 3 23868 23870 24156 3 24158 24156 23870 3 23869 24157 23871 3 24159 23871 24157 3 23870 23872 24158 3 24160 24158 23872 3 23871 24159 23873 3 24161 23873 24159 3 23872 23874 24160 3 24162 24160 23874 3 23873 24161 23875 3 24163 23875 24161 3 23874 23876 24162 3 24164 24162 23876 3 23875 24163 23877 3 24165 23877 24163 3 23876 23878 24164 3 24166 24164 23878 3 23877 24165 23879 3 24167 23879 24165 3 23878 23880 24166 3 24168 24166 23880 3 23879 24167 23881 3 24169 23881 24167 3 23880 23882 24168 3 24170 24168 23882 3 23881 24169 23883 3 24171 23883 24169 3 23882 23884 24170 3 24172 24170 23884 3 23883 24171 23885 3 24173 23885 24171 3 23884 23886 24172 3 24174 24172 23886 3 23885 24173 23887 3 24175 23887 24173 3 23886 23888 24174 3 24176 24174 23888 3 23887 24175 23889 3 24177 23889 24175 3 23888 23890 24176 3 24178 24176 23890 3 23889 24177 23891 3 24179 23891 24177 3 23890 23892 24178 3 24180 24178 23892 3 23891 24179 23893 3 24181 23893 24179 3 23892 23894 24180 3 24182 24180 23894 3 23893 24181 23895 3 24183 23895 24181 3 23894 23896 24182 3 24184 24182 23896 3 23895 24183 23897 3 24185 23897 24183 3 23896 23898 24184 3 24186 24184 23898 3 23897 24185 23899 3 24187 23899 24185 3 23898 23900 24186 3 24188 24186 23900 3 23899 24187 23901 3 24189 23901 24187 3 23900 23902 24188 3 24190 24188 23902 3 23901 24189 23903 3 24191 23903 24189 3 23902 23904 24190 3 24192 24190 23904 3 23903 24191 23905 3 24193 23905 24191 3 23904 23906 24192 3 24194 24192 23906 3 23905 24193 23907 3 24195 23907 24193 3 23906 23908 24194 3 24196 24194 23908 3 23907 24195 23909 3 24197 23909 24195 3 23908 23910 24196 3 24198 24196 23910 3 23909 24197 23911 3 24199 23911 24197 3 23910 23912 24198 3 24200 24198 23912 3 23911 24199 23913 3 24201 23913 24199 3 23912 23914 24200 3 24202 24200 23914 3 23913 24201 23915 3 24203 23915 24201 3 23914 23916 24202 3 24204 24202 23916 3 23915 24203 23917 3 24205 23917 24203 3 23916 23918 24204 3 24206 24204 23918 3 23917 24205 23919 3 24207 23919 24205 3 23918 23920 24208 3 23918 24208 24206 3 23919 24207 23921 3 24209 23921 24207 3 23920 23922 24210 3 23920 24210 24208 3 23921 24209 23923 3 24211 23923 24209 3 23922 23924 24212 3 23922 24212 24210 3 23923 24211 23925 3 24213 23925 24211 3 23924 23926 24214 3 23924 24214 24212 3 23925 24213 23927 3 24215 23927 24213 3 23926 23928 24216 3 23926 24216 24214 3 23927 24215 23929 3 24217 23929 24215 3 23928 23930 24218 3 23928 24218 24216 3 23929 24217 23931 3 24219 23931 24217 3 23930 23932 24220 3 23930 24220 24218 3 23931 24219 23933 3 24221 23933 24219 3 23932 23934 24222 3 23932 24222 24220 3 23933 24221 23935 3 24223 23935 24221 3 23934 23936 24224 3 23934 24224 24222 3 23935 24223 23939 3 24227 23939 24223 3 23936 23937 24225 3 23936 24225 24224 3 23937 23940 24228 3 23937 24228 24225 3 23938 23939 24227 3 23938 24227 24226 3 23938 24226 23943 3 24231 23943 24226 3 23940 23941 24229 3 23940 24229 24228 3 23941 23944 24232 3 23941 24232 24229 3 23942 23943 24231 3 23942 24231 24230 3 23942 24230 24012 3 24300 24012 24230 3 23944 23945 24233 3 23944 24233 24232 3 23945 23946 24234 3 23945 24234 24233 3 23946 23947 24235 3 23946 24235 24234 3 23947 23948 24236 3 23947 24236 24235 3 23948 23949 24237 3 23948 24237 24236 3 23949 23950 24238 3 23949 24238 24237 3 23950 23951 24239 3 23950 24239 24238 3 23951 23952 24240 3 23951 24240 24239 3 23952 23953 24241 3 23952 24241 24240 3 23953 23954 24242 3 23953 24242 24241 3 23954 23955 24243 3 23954 24243 24242 3 23955 23956 24244 3 23955 24244 24243 3 23956 23957 24245 3 23956 24245 24244 3 23957 23958 24246 3 23957 24246 24245 3 23958 23959 24247 3 23958 24247 24246 3 23959 23960 24248 3 23959 24248 24247 3 23960 23961 24249 3 23960 24249 24248 3 23961 23962 24250 3 23961 24250 24249 3 23962 23963 24251 3 23962 24251 24250 3 23963 23964 24252 3 23963 24252 24251 3 23964 23965 24253 3 23964 24253 24252 3 23965 23966 24254 3 23965 24254 24253 3 23966 23967 24255 3 23966 24255 24254 3 23967 23968 24256 3 23967 24256 24255 3 23968 23969 24257 3 23968 24257 24256 3 23969 23970 24258 3 23969 24258 24257 3 23970 23971 24259 3 23970 24259 24258 3 23971 23972 24260 3 23971 24260 24259 3 23972 23973 24261 3 23972 24261 24260 3 23973 23974 24262 3 23973 24262 24261 3 23974 23975 24263 3 23974 24263 24262 3 23975 23976 24264 3 23975 24264 24263 3 23976 23977 24265 3 23976 24265 24264 3 23977 23978 24266 3 23977 24266 24265 3 23978 23979 24267 3 23978 24267 24266 3 23979 23980 24268 3 23979 24268 24267 3 23980 23981 24269 3 23980 24269 24268 3 23981 23982 24270 3 23981 24270 24269 3 23982 23983 24271 3 23982 24271 24270 3 23983 23984 24272 3 23983 24272 24271 3 23984 23985 24273 3 23984 24273 24272 3 23985 23986 24274 3 23985 24274 24273 3 23986 23987 24275 3 23986 24275 24274 3 23987 23988 24276 3 23987 24276 24275 3 23988 23989 24277 3 23988 24277 24276 3 23989 23990 24278 3 23989 24278 24277 3 23990 23991 24279 3 23990 24279 24278 3 23991 23992 24280 3 23991 24280 24279 3 23992 23993 24281 3 23992 24281 24280 3 23993 23994 24282 3 23993 24282 24281 3 23994 23995 24283 3 23994 24283 24282 3 23995 23996 24284 3 23995 24284 24283 3 23996 23997 24285 3 23996 24285 24284 3 23997 23998 24286 3 23997 24286 24285 3 23998 23999 24287 3 23998 24287 24286 3 23999 24000 24288 3 23999 24288 24287 3 24000 24001 24289 3 24000 24289 24288 3 24001 24002 24290 3 24001 24290 24289 3 24002 24003 24291 3 24002 24291 24290 3 24003 24004 24292 3 24003 24292 24291 3 24004 24005 24293 3 24004 24293 24292 3 24005 24006 24294 3 24005 24294 24293 3 24006 24007 24295 3 24006 24295 24294 3 24007 24008 24296 3 24007 24296 24295 3 24008 24009 24297 3 24008 24297 24296 3 24009 24010 24298 3 24009 24298 24297 3 24010 24011 24299 3 24010 24299 24298 3 24011 24012 24300 3 24011 24300 24299 3 24013 24301 24302 3 24013 24302 24014 3 24013 24083 24301 3 24371 24301 24083 3 24014 24302 24303 3 24014 24303 24015 3 24015 24303 24304 3 24015 24304 24016 3 24016 24304 24305 3 24016 24305 24017 3 24017 24305 24306 3 24017 24306 24018 3 24018 24306 24307 3 24018 24307 24019 3 24019 24307 24308 3 24019 24308 24020 3 24020 24308 24309 3 24020 24309 24021 3 24021 24309 24310 3 24021 24310 24022 3 24022 24310 24311 3 24022 24311 24023 3 24023 24311 24312 3 24023 24312 24024 3 24024 24312 24313 3 24024 24313 24025 3 24025 24313 24314 3 24025 24314 24026 3 24026 24314 24315 3 24026 24315 24027 3 24027 24315 24316 3 24027 24316 24028 3 24028 24316 24317 3 24028 24317 24029 3 24029 24317 24318 3 24029 24318 24030 3 24030 24318 24319 3 24030 24319 24031 3 24031 24319 24320 3 24031 24320 24032 3 24032 24320 24321 3 24032 24321 24033 3 24033 24321 24322 3 24033 24322 24034 3 24034 24322 24323 3 24034 24323 24035 3 24035 24323 24324 3 24035 24324 24036 3 24036 24324 24325 3 24036 24325 24037 3 24037 24325 24326 3 24037 24326 24038 3 24038 24326 24327 3 24038 24327 24039 3 24039 24327 24040 3 24328 24040 24327 3 24040 24328 24041 3 24329 24041 24328 3 24041 24329 24042 3 24330 24042 24329 3 24042 24330 24043 3 24331 24043 24330 3 24043 24331 24044 3 24332 24044 24331 3 24044 24332 24045 3 24333 24045 24332 3 24045 24333 24046 3 24334 24046 24333 3 24046 24334 24047 3 24335 24047 24334 3 24047 24335 24048 3 24336 24048 24335 3 24048 24336 24049 3 24337 24049 24336 3 24049 24337 24050 3 24338 24050 24337 3 24050 24338 24051 3 24339 24051 24338 3 24051 24339 24052 3 24340 24052 24339 3 24052 24340 24053 3 24341 24053 24340 3 24053 24341 24054 3 24342 24054 24341 3 24054 24342 24055 3 24343 24055 24342 3 24055 24343 24056 3 24344 24056 24343 3 24056 24344 24057 3 24345 24057 24344 3 24057 24345 24058 3 24346 24058 24345 3 24058 24346 24059 3 24347 24059 24346 3 24059 24347 24060 3 24348 24060 24347 3 24060 24348 24061 3 24349 24061 24348 3 24061 24349 24062 3 24350 24062 24349 3 24062 24350 24063 3 24351 24063 24350 3 24063 24351 24064 3 24352 24064 24351 3 24064 24352 24065 3 24353 24065 24352 3 24065 24353 24066 3 24354 24066 24353 3 24066 24354 24067 3 24355 24067 24354 3 24067 24355 24068 3 24356 24068 24355 3 24068 24356 24069 3 24357 24069 24356 3 24069 24357 24070 3 24358 24070 24357 3 24070 24358 24071 3 24359 24071 24358 3 24071 24359 24072 3 24360 24072 24359 3 24072 24360 24073 3 24361 24073 24360 3 24073 24361 24074 3 24362 24074 24361 3 24074 24362 24075 3 24363 24075 24362 3 24075 24363 24076 3 24364 24076 24363 3 24076 24364 24077 3 24365 24077 24364 3 24077 24365 24078 3 24366 24078 24365 3 24078 24366 24079 3 24367 24079 24366 3 24079 24367 24080 3 24368 24080 24367 3 24080 24368 24081 3 24369 24081 24368 3 24081 24369 24084 3 24372 24084 24369 3 24082 24370 24083 3 24371 24083 24370 3 24082 24087 24370 3 24375 24370 24087 3 24084 24372 24085 3 24373 24085 24372 3 24085 24373 24088 3 24376 24088 24373 3 24086 24374 24087 3 24375 24087 24374 3 24086 24090 24374 3 24378 24374 24090 3 24088 24376 24089 3 24377 24089 24376 3 24089 24377 24091 3 24379 24091 24377 3 24090 24092 24378 3 24380 24378 24092 3 24091 24379 24093 3 24381 24093 24379 3 24092 24094 24380 3 24382 24380 24094 3 24093 24381 24095 3 24383 24095 24381 3 24094 24096 24382 3 24384 24382 24096 3 24095 24383 24097 3 24385 24097 24383 3 24096 24098 24384 3 24386 24384 24098 3 24097 24385 24099 3 24387 24099 24385 3 24098 24100 24386 3 24388 24386 24100 3 24099 24387 24101 3 24389 24101 24387 3 24100 24102 24388 3 24390 24388 24102 3 24101 24389 24103 3 24391 24103 24389 3 24102 24104 24390 3 24392 24390 24104 3 24103 24391 24105 3 24393 24105 24391 3 24104 24106 24392 3 24394 24392 24106 3 24105 24393 24107 3 24395 24107 24393 3 24106 24108 24394 3 24396 24394 24108 3 24107 24395 24109 3 24397 24109 24395 3 24108 24110 24398 3 24108 24398 24396 3 24109 24397 24111 3 24399 24111 24397 3 24110 24112 24400 3 24110 24400 24398 3 24111 24399 24113 3 24401 24113 24399 3 24112 24114 24402 3 24112 24402 24400 3 24113 24401 24115 3 24403 24115 24401 3 24114 24116 24404 3 24114 24404 24402 3 24115 24403 24117 3 24405 24117 24403 3 24116 24118 24406 3 24116 24406 24404 3 24117 24405 24119 3 24407 24119 24405 3 24118 24120 24408 3 24118 24408 24406 3 24119 24407 24121 3 24409 24121 24407 3 24120 24122 24410 3 24120 24410 24408 3 24121 24409 24123 3 24411 24123 24409 3 24122 24124 24412 3 24122 24412 24410 3 24123 24411 24125 3 24413 24125 24411 3 24124 24126 24414 3 24124 24414 24412 3 24125 24413 24127 3 24415 24127 24413 3 24126 24128 24416 3 24126 24416 24414 3 24127 24415 24129 3 24417 24129 24415 3 24128 24130 24418 3 24128 24418 24416 3 24129 24417 24131 3 24419 24131 24417 3 24130 24132 24420 3 24130 24420 24418 3 24131 24419 24133 3 24421 24133 24419 3 24132 24134 24422 3 24132 24422 24420 3 24133 24421 24135 3 24423 24135 24421 3 24134 24136 24424 3 24134 24424 24422 3 24135 24423 24425 3 24135 24425 24137 3 24136 24138 24426 3 24136 24426 24424 3 24137 24425 24427 3 24137 24427 24139 3 24138 24140 24428 3 24138 24428 24426 3 24139 24427 24429 3 24139 24429 24141 3 24140 24142 24430 3 24140 24430 24428 3 24141 24429 24431 3 24141 24431 24143 3 24142 24144 24432 3 24142 24432 24430 3 24143 24431 24433 3 24143 24433 24145 3 24144 24146 24434 3 24144 24434 24432 3 24145 24433 24435 3 24145 24435 24147 3 24146 24148 24436 3 24146 24436 24434 3 24147 24435 24437 3 24147 24437 24149 3 24148 24150 24438 3 24148 24438 24436 3 24149 24437 24439 3 24149 24439 24151 3 24150 24152 24440 3 24150 24440 24438 3 24151 24439 24441 3 24151 24441 24153 3 24152 24154 24442 3 24152 24442 24440 3 24153 24441 24443 3 24153 24443 24155 3 24154 24156 24444 3 24154 24444 24442 3 24155 24443 24445 3 24155 24445 24157 3 24156 24158 24446 3 24156 24446 24444 3 24157 24445 24447 3 24157 24447 24159 3 24158 24160 24448 3 24158 24448 24446 3 24159 24447 24449 3 24159 24449 24161 3 24160 24162 24450 3 24160 24450 24448 3 24161 24449 24451 3 24161 24451 24163 3 24162 24164 24452 3 24162 24452 24450 3 24163 24451 24453 3 24163 24453 24165 3 24164 24166 24454 3 24164 24454 24452 3 24165 24453 24455 3 24165 24455 24167 3 24166 24168 24456 3 24166 24456 24454 3 24167 24455 24457 3 24167 24457 24169 3 24168 24170 24458 3 24168 24458 24456 3 24169 24457 24459 3 24169 24459 24171 3 24170 24172 24460 3 24170 24460 24458 3 24171 24459 24461 3 24171 24461 24173 3 24172 24174 24462 3 24172 24462 24460 3 24173 24461 24463 3 24173 24463 24175 3 24174 24176 24464 3 24174 24464 24462 3 24175 24463 24465 3 24175 24465 24177 3 24176 24178 24466 3 24176 24466 24464 3 24177 24465 24467 3 24177 24467 24179 3 24178 24180 24468 3 24178 24468 24466 3 24179 24467 24469 3 24179 24469 24181 3 24180 24182 24470 3 24180 24470 24468 3 24181 24469 24471 3 24181 24471 24183 3 24182 24184 24472 3 24182 24472 24470 3 24183 24471 24473 3 24183 24473 24185 3 24184 24186 24474 3 24184 24474 24472 3 24185 24473 24475 3 24185 24475 24187 3 24186 24188 24476 3 24186 24476 24474 3 24187 24475 24477 3 24187 24477 24189 3 24188 24190 24478 3 24188 24478 24476 3 24189 24477 24479 3 24189 24479 24191 3 24190 24192 24480 3 24190 24480 24478 3 24191 24479 24481 3 24191 24481 24193 3 24192 24194 24482 3 24192 24482 24480 3 24193 24481 24483 3 24193 24483 24195 3 24194 24196 24484 3 24194 24484 24482 3 24195 24483 24485 3 24195 24485 24197 3 24196 24198 24486 3 24196 24486 24484 3 24197 24485 24487 3 24197 24487 24199 3 24198 24200 24488 3 24198 24488 24486 3 24199 24487 24489 3 24199 24489 24201 3 24200 24202 24490 3 24200 24490 24488 3 24201 24489 24491 3 24201 24491 24203 3 24202 24204 24492 3 24202 24492 24490 3 24203 24491 24493 3 24203 24493 24205 3 24204 24206 24492 3 24494 24492 24206 3 24205 24493 24495 3 24205 24495 24207 3 24206 24208 24494 3 24496 24494 24208 3 24207 24495 24497 3 24207 24497 24209 3 24208 24210 24496 3 24498 24496 24210 3 24209 24497 24499 3 24209 24499 24211 3 24210 24212 24498 3 24500 24498 24212 3 24211 24499 24501 3 24211 24501 24213 3 24212 24214 24500 3 24502 24500 24214 3 24213 24501 24503 3 24213 24503 24215 3 24214 24216 24502 3 24504 24502 24216 3 24215 24503 24505 3 24215 24505 24217 3 24216 24218 24504 3 24506 24504 24218 3 24217 24505 24507 3 24217 24507 24219 3 24218 24220 24506 3 24508 24506 24220 3 24219 24507 24509 3 24219 24509 24221 3 24220 24222 24508 3 24510 24508 24222 3 24221 24509 24511 3 24221 24511 24223 3 24222 24224 24510 3 24512 24510 24224 3 24223 24511 24515 3 24223 24515 24227 3 24224 24225 24512 3 24513 24512 24225 3 24225 24228 24513 3 24516 24513 24228 3 24226 24227 24514 3 24515 24514 24227 3 24226 24514 24519 3 24226 24519 24231 3 24228 24229 24516 3 24517 24516 24229 3 24229 24232 24517 3 24520 24517 24232 3 24230 24231 24518 3 24519 24518 24231 3 24230 24518 24300 3 24588 24300 24518 3 24232 24233 24520 3 24521 24520 24233 3 24233 24234 24521 3 24522 24521 24234 3 24234 24235 24522 3 24523 24522 24235 3 24235 24236 24523 3 24524 24523 24236 3 24236 24237 24524 3 24525 24524 24237 3 24237 24238 24525 3 24526 24525 24238 3 24238 24239 24526 3 24527 24526 24239 3 24239 24240 24527 3 24528 24527 24240 3 24240 24241 24528 3 24529 24528 24241 3 24241 24242 24529 3 24530 24529 24242 3 24242 24243 24530 3 24531 24530 24243 3 24243 24244 24531 3 24532 24531 24244 3 24244 24245 24532 3 24533 24532 24245 3 24245 24246 24533 3 24534 24533 24246 3 24246 24247 24534 3 24535 24534 24247 3 24247 24248 24535 3 24536 24535 24248 3 24248 24249 24536 3 24537 24536 24249 3 24249 24250 24537 3 24538 24537 24250 3 24250 24251 24538 3 24539 24538 24251 3 24251 24252 24539 3 24540 24539 24252 3 24252 24253 24540 3 24541 24540 24253 3 24253 24254 24541 3 24542 24541 24254 3 24254 24255 24542 3 24543 24542 24255 3 24255 24256 24543 3 24544 24543 24256 3 24256 24257 24544 3 24545 24544 24257 3 24257 24258 24545 3 24546 24545 24258 3 24258 24259 24546 3 24547 24546 24259 3 24259 24260 24547 3 24548 24547 24260 3 24260 24261 24548 3 24549 24548 24261 3 24261 24262 24549 3 24550 24549 24262 3 24262 24263 24550 3 24551 24550 24263 3 24263 24264 24551 3 24552 24551 24264 3 24264 24265 24552 3 24553 24552 24265 3 24265 24266 24553 3 24554 24553 24266 3 24266 24267 24554 3 24555 24554 24267 3 24267 24268 24555 3 24556 24555 24268 3 24268 24269 24556 3 24557 24556 24269 3 24269 24270 24557 3 24558 24557 24270 3 24270 24271 24558 3 24559 24558 24271 3 24271 24272 24559 3 24560 24559 24272 3 24272 24273 24560 3 24561 24560 24273 3 24273 24274 24561 3 24562 24561 24274 3 24274 24275 24562 3 24563 24562 24275 3 24275 24276 24563 3 24564 24563 24276 3 24276 24277 24564 3 24565 24564 24277 3 24277 24278 24565 3 24566 24565 24278 3 24278 24279 24566 3 24567 24566 24279 3 24279 24280 24567 3 24568 24567 24280 3 24280 24281 24568 3 24569 24568 24281 3 24281 24282 24569 3 24570 24569 24282 3 24282 24283 24570 3 24571 24570 24283 3 24283 24284 24571 3 24572 24571 24284 3 24284 24285 24572 3 24573 24572 24285 3 24285 24286 24573 3 24574 24573 24286 3 24286 24287 24574 3 24575 24574 24287 3 24287 24288 24575 3 24576 24575 24288 3 24288 24289 24576 3 24577 24576 24289 3 24289 24290 24577 3 24578 24577 24290 3 24290 24291 24578 3 24579 24578 24291 3 24291 24292 24579 3 24580 24579 24292 3 24292 24293 24580 3 24581 24580 24293 3 24293 24294 24581 3 24582 24581 24294 3 24294 24295 24582 3 24583 24582 24295 3 24295 24296 24583 3 24584 24583 24296 3 24296 24297 24584 3 24585 24584 24297 3 24297 24298 24585 3 24586 24585 24298 3 24298 24299 24586 3 24587 24586 24299 3 24299 24300 24588 3 24299 24588 24587 3 24301 24589 24302 3 24590 24302 24589 3 24301 24371 24659 3 24301 24659 24589 3 24302 24590 24303 3 24591 24303 24590 3 24303 24591 24304 3 24592 24304 24591 3 24304 24592 24305 3 24593 24305 24592 3 24305 24593 24306 3 24594 24306 24593 3 24306 24594 24307 3 24595 24307 24594 3 24307 24595 24308 3 24596 24308 24595 3 24308 24596 24309 3 24597 24309 24596 3 24309 24597 24310 3 24598 24310 24597 3 24310 24598 24311 3 24599 24311 24598 3 24311 24599 24312 3 24600 24312 24599 3 24312 24600 24313 3 24601 24313 24600 3 24313 24601 24314 3 24602 24314 24601 3 24314 24602 24315 3 24603 24315 24602 3 24315 24603 24316 3 24604 24316 24603 3 24316 24604 24317 3 24605 24317 24604 3 24317 24605 24318 3 24606 24318 24605 3 24318 24606 24319 3 24607 24319 24606 3 24319 24607 24320 3 24608 24320 24607 3 24320 24608 24321 3 24609 24321 24608 3 24321 24609 24322 3 24610 24322 24609 3 24322 24610 24323 3 24611 24323 24610 3 24323 24611 24324 3 24612 24324 24611 3 24324 24612 24325 3 24613 24325 24612 3 24325 24613 24326 3 24614 24326 24613 3 24326 24614 24327 3 24615 24327 24614 3 24327 24615 24616 3 24327 24616 24328 3 24328 24616 24617 3 24328 24617 24329 3 24329 24617 24618 3 24329 24618 24330 3 24330 24618 24619 3 24330 24619 24331 3 24331 24619 24620 3 24331 24620 24332 3 24332 24620 24621 3 24332 24621 24333 3 24333 24621 24622 3 24333 24622 24334 3 24334 24622 24623 3 24334 24623 24335 3 24335 24623 24624 3 24335 24624 24336 3 24336 24624 24625 3 24336 24625 24337 3 24337 24625 24626 3 24337 24626 24338 3 24338 24626 24627 3 24338 24627 24339 3 24339 24627 24628 3 24339 24628 24340 3 24340 24628 24629 3 24340 24629 24341 3 24341 24629 24630 3 24341 24630 24342 3 24342 24630 24631 3 24342 24631 24343 3 24343 24631 24632 3 24343 24632 24344 3 24344 24632 24633 3 24344 24633 24345 3 24345 24633 24634 3 24345 24634 24346 3 24346 24634 24635 3 24346 24635 24347 3 24347 24635 24636 3 24347 24636 24348 3 24348 24636 24637 3 24348 24637 24349 3 24349 24637 24638 3 24349 24638 24350 3 24350 24638 24639 3 24350 24639 24351 3 24351 24639 24640 3 24351 24640 24352 3 24352 24640 24641 3 24352 24641 24353 3 24353 24641 24642 3 24353 24642 24354 3 24354 24642 24643 3 24354 24643 24355 3 24355 24643 24644 3 24355 24644 24356 3 24356 24644 24645 3 24356 24645 24357 3 24357 24645 24646 3 24357 24646 24358 3 24358 24646 24647 3 24358 24647 24359 3 24359 24647 24648 3 24359 24648 24360 3 24360 24648 24649 3 24360 24649 24361 3 24361 24649 24650 3 24361 24650 24362 3 24362 24650 24651 3 24362 24651 24363 3 24363 24651 24652 3 24363 24652 24364 3 24364 24652 24653 3 24364 24653 24365 3 24365 24653 24654 3 24365 24654 24366 3 24366 24654 24655 3 24366 24655 24367 3 24367 24655 24656 3 24367 24656 24368 3 24368 24656 24657 3 24368 24657 24369 3 24369 24657 24662 3 24369 24662 24372 3 24370 24658 24659 3 24370 24659 24371 3 24370 24375 24665 3 24370 24665 24658 3 24372 24662 24663 3 24372 24663 24373 3 24373 24663 24666 3 24373 24666 24376 3 24374 24664 24665 3 24374 24665 24375 3 24374 24378 24668 3 24374 24668 24664 3 24376 24666 24667 3 24376 24667 24377 3 24377 24667 24671 3 24377 24671 24379 3 24378 24380 24672 3 24378 24672 24668 3 24379 24671 24673 3 24379 24673 24381 3 24380 24382 24674 3 24380 24674 24672 3 24381 24673 24675 3 24381 24675 24383 3 24382 24384 24676 3 24382 24676 24674 3 24383 24675 24677 3 24383 24677 24385 3 24384 24386 24678 3 24384 24678 24676 3 24385 24677 24679 3 24385 24679 24387 3 24386 24388 24680 3 24386 24680 24678 3 24387 24679 24681 3 24387 24681 24389 3 24388 24390 24682 3 24388 24682 24680 3 24389 24681 24683 3 24389 24683 24391 3 24390 24392 24684 3 24390 24684 24682 3 24391 24683 24685 3 24391 24685 24393 3 24392 24394 24686 3 24392 24686 24684 3 24393 24685 24687 3 24393 24687 24395 3 24394 24396 24688 3 24394 24688 24686 3 24395 24687 24689 3 24395 24689 24397 3 24396 24398 24688 3 24690 24688 24398 3 24397 24689 24691 3 24397 24691 24399 3 24398 24400 24690 3 24692 24690 24400 3 24399 24691 24693 3 24399 24693 24401 3 24400 24402 24692 3 24694 24692 24402 3 24401 24693 24695 3 24401 24695 24403 3 24402 24404 24694 3 24696 24694 24404 3 24403 24695 24697 3 24403 24697 24405 3 24404 24406 24696 3 24698 24696 24406 3 24405 24697 24699 3 24405 24699 24407 3 24406 24408 24698 3 24700 24698 24408 3 24407 24699 24701 3 24407 24701 24409 3 24408 24410 24700 3 24702 24700 24410 3 24409 24701 24703 3 24409 24703 24411 3 24410 24412 24702 3 24704 24702 24412 3 24411 24703 24705 3 24411 24705 24413 3 24412 24414 24704 3 24706 24704 24414 3 24413 24705 24707 3 24413 24707 24415 3 24414 24416 24706 3 24708 24706 24416 3 24415 24707 24709 3 24415 24709 24417 3 24416 24418 24708 3 24710 24708 24418 3 24417 24709 24711 3 24417 24711 24419 3 24418 24420 24710 3 24712 24710 24420 3 24419 24711 24713 3 24419 24713 24421 3 24420 24422 24712 3 24714 24712 24422 3 24421 24713 24423 3 24715 24423 24713 3 24422 24424 24714 3 24716 24714 24424 3 24423 24715 24425 3 24717 24425 24715 3 24424 24426 24716 3 24718 24716 24426 3 24425 24717 24427 3 24719 24427 24717 3 24426 24428 24718 3 24720 24718 24428 3 24427 24719 24429 3 24721 24429 24719 3 24428 24430 24720 3 24722 24720 24430 3 24429 24721 24431 3 24723 24431 24721 3 24430 24432 24722 3 24724 24722 24432 3 24431 24723 24433 3 24725 24433 24723 3 24432 24434 24724 3 24726 24724 24434 3 24433 24725 24435 3 24727 24435 24725 3 24434 24436 24726 3 24728 24726 24436 3 24435 24727 24437 3 24729 24437 24727 3 24436 24438 24728 3 24730 24728 24438 3 24437 24729 24439 3 24731 24439 24729 3 24438 24440 24730 3 24732 24730 24440 3 24439 24731 24441 3 24733 24441 24731 3 24440 24442 24732 3 24734 24732 24442 3 24441 24733 24443 3 24735 24443 24733 3 24442 24444 24734 3 24736 24734 24444 3 24443 24735 24445 3 24737 24445 24735 3 24444 24446 24736 3 24738 24736 24446 3 24445 24737 24447 3 24739 24447 24737 3 24446 24448 24738 3 24740 24738 24448 3 24447 24739 24449 3 24741 24449 24739 3 24448 24450 24740 3 24742 24740 24450 3 24449 24741 24451 3 24743 24451 24741 3 24450 24452 24742 3 24744 24742 24452 3 24451 24743 24453 3 24745 24453 24743 3 24452 24454 24744 3 24746 24744 24454 3 24453 24745 24455 3 24747 24455 24745 3 24454 24456 24746 3 24748 24746 24456 3 24455 24747 24457 3 24749 24457 24747 3 24456 24458 24748 3 24750 24748 24458 3 24457 24749 24459 3 24751 24459 24749 3 24458 24460 24750 3 24752 24750 24460 3 24459 24751 24461 3 24753 24461 24751 3 24460 24462 24752 3 24754 24752 24462 3 24461 24753 24463 3 24755 24463 24753 3 24462 24464 24754 3 24756 24754 24464 3 24463 24755 24465 3 24757 24465 24755 3 24464 24466 24756 3 24758 24756 24466 3 24465 24757 24467 3 24759 24467 24757 3 24466 24468 24758 3 24760 24758 24468 3 24467 24759 24469 3 24761 24469 24759 3 24468 24470 24760 3 24762 24760 24470 3 24469 24761 24471 3 24763 24471 24761 3 24470 24472 24762 3 24764 24762 24472 3 24471 24763 24473 3 24765 24473 24763 3 24472 24474 24764 3 24766 24764 24474 3 24473 24765 24475 3 24767 24475 24765 3 24474 24476 24766 3 24768 24766 24476 3 24475 24767 24477 3 24769 24477 24767 3 24476 24478 24768 3 24770 24768 24478 3 24477 24769 24479 3 24771 24479 24769 3 24478 24480 24770 3 24772 24770 24480 3 24479 24771 24481 3 24773 24481 24771 3 24480 24482 24772 3 24774 24772 24482 3 24481 24773 24483 3 24775 24483 24773 3 24482 24484 24774 3 24776 24774 24484 3 24483 24775 24485 3 24777 24485 24775 3 24484 24486 24776 3 24778 24776 24486 3 24485 24777 24487 3 24779 24487 24777 3 24486 24488 24778 3 24780 24778 24488 3 24487 24779 24489 3 24781 24489 24779 3 24488 24490 24780 3 24782 24780 24490 3 24489 24781 24491 3 24783 24491 24781 3 24490 24492 24782 3 24784 24782 24492 3 24491 24783 24493 3 24785 24493 24783 3 24492 24494 24786 3 24492 24786 24784 3 24493 24785 24495 3 24787 24495 24785 3 24494 24496 24788 3 24494 24788 24786 3 24495 24787 24497 3 24789 24497 24787 3 24496 24498 24790 3 24496 24790 24788 3 24497 24789 24499 3 24791 24499 24789 3 24498 24500 24792 3 24498 24792 24790 3 24499 24791 24501 3 24793 24501 24791 3 24500 24502 24794 3 24500 24794 24792 3 24501 24793 24503 3 24795 24503 24793 3 24502 24504 24796 3 24502 24796 24794 3 24503 24795 24505 3 24797 24505 24795 3 24504 24506 24798 3 24504 24798 24796 3 24505 24797 24507 3 24799 24507 24797 3 24506 24508 24800 3 24506 24800 24798 3 24507 24799 24509 3 24801 24509 24799 3 24508 24510 24802 3 24508 24802 24800 3 24509 24801 24511 3 24805 24511 24801 3 24510 24512 24806 3 24510 24806 24802 3 24511 24805 24515 3 24809 24515 24805 3 24512 24513 24807 3 24512 24807 24806 3 24513 24516 24810 3 24513 24810 24807 3 24514 24515 24809 3 24514 24809 24808 3 24514 24808 24519 3 24815 24519 24808 3 24516 24517 24811 3 24516 24811 24810 3 24517 24520 24816 3 24517 24816 24811 3 24518 24519 24815 3 24518 24815 24814 3 24518 24814 24884 3 24518 24884 24588 3 24520 24521 24817 3 24520 24817 24816 3 24521 24522 24818 3 24521 24818 24817 3 24522 24523 24819 3 24522 24819 24818 3 24523 24524 24820 3 24523 24820 24819 3 24524 24525 24821 3 24524 24821 24820 3 24525 24526 24822 3 24525 24822 24821 3 24526 24527 24823 3 24526 24823 24822 3 24527 24528 24824 3 24527 24824 24823 3 24528 24529 24825 3 24528 24825 24824 3 24529 24530 24826 3 24529 24826 24825 3 24530 24531 24827 3 24530 24827 24826 3 24531 24532 24828 3 24531 24828 24827 3 24532 24533 24829 3 24532 24829 24828 3 24533 24534 24830 3 24533 24830 24829 3 24534 24535 24831 3 24534 24831 24830 3 24535 24536 24832 3 24535 24832 24831 3 24536 24537 24833 3 24536 24833 24832 3 24537 24538 24834 3 24537 24834 24833 3 24538 24539 24835 3 24538 24835 24834 3 24539 24540 24836 3 24539 24836 24835 3 24540 24541 24837 3 24540 24837 24836 3 24541 24542 24838 3 24541 24838 24837 3 24542 24543 24839 3 24542 24839 24838 3 24543 24544 24840 3 24543 24840 24839 3 24544 24545 24841 3 24544 24841 24840 3 24545 24546 24842 3 24545 24842 24841 3 24546 24547 24843 3 24546 24843 24842 3 24547 24548 24844 3 24547 24844 24843 3 24548 24549 24845 3 24548 24845 24844 3 24549 24550 24846 3 24549 24846 24845 3 24550 24551 24847 3 24550 24847 24846 3 24551 24552 24848 3 24551 24848 24847 3 24552 24553 24849 3 24552 24849 24848 3 24553 24554 24850 3 24553 24850 24849 3 24554 24555 24851 3 24554 24851 24850 3 24555 24556 24852 3 24555 24852 24851 3 24556 24557 24853 3 24556 24853 24852 3 24557 24558 24854 3 24557 24854 24853 3 24558 24559 24855 3 24558 24855 24854 3 24559 24560 24856 3 24559 24856 24855 3 24560 24561 24857 3 24560 24857 24856 3 24561 24562 24858 3 24561 24858 24857 3 24562 24563 24859 3 24562 24859 24858 3 24563 24564 24860 3 24563 24860 24859 3 24564 24565 24861 3 24564 24861 24860 3 24565 24566 24862 3 24565 24862 24861 3 24566 24567 24863 3 24566 24863 24862 3 24567 24568 24864 3 24567 24864 24863 3 24568 24569 24865 3 24568 24865 24864 3 24569 24570 24866 3 24569 24866 24865 3 24570 24571 24867 3 24570 24867 24866 3 24571 24572 24868 3 24571 24868 24867 3 24572 24573 24869 3 24572 24869 24868 3 24573 24574 24870 3 24573 24870 24869 3 24574 24575 24871 3 24574 24871 24870 3 24575 24576 24872 3 24575 24872 24871 3 24576 24577 24873 3 24576 24873 24872 3 24577 24578 24874 3 24577 24874 24873 3 24578 24579 24875 3 24578 24875 24874 3 24579 24580 24876 3 24579 24876 24875 3 24580 24581 24877 3 24580 24877 24876 3 24581 24582 24878 3 24581 24878 24877 3 24582 24583 24879 3 24582 24879 24878 3 24583 24584 24880 3 24583 24880 24879 3 24584 24585 24881 3 24584 24881 24880 3 24585 24586 24882 3 24585 24882 24881 3 24586 24587 24883 3 24586 24883 24882 3 24587 24588 24884 3 24587 24884 24883 3 24589 24659 24590 3 24660 24590 24659 3 24590 24885 24886 3 24590 24886 24591 3 24590 24660 24885 3 24954 24885 24660 3 24591 24886 24887 3 24591 24887 24592 3 24592 24887 24888 3 24592 24888 24593 3 24593 24888 24889 3 24593 24889 24594 3 24594 24889 24890 3 24594 24890 24595 3 24595 24890 24891 3 24595 24891 24596 3 24596 24891 24892 3 24596 24892 24597 3 24597 24892 24893 3 24597 24893 24598 3 24598 24893 24894 3 24598 24894 24599 3 24599 24894 24895 3 24599 24895 24600 3 24600 24895 24896 3 24600 24896 24601 3 24601 24896 24897 3 24601 24897 24602 3 24602 24897 24898 3 24602 24898 24603 3 24603 24898 24899 3 24603 24899 24604 3 24604 24899 24900 3 24604 24900 24605 3 24605 24900 24901 3 24605 24901 24606 3 24606 24901 24902 3 24606 24902 24607 3 24607 24902 24903 3 24607 24903 24608 3 24608 24903 24904 3 24608 24904 24609 3 24609 24904 24905 3 24609 24905 24610 3 24610 24905 24906 3 24610 24906 24611 3 24611 24906 24907 3 24611 24907 24612 3 24612 24907 24613 3 24908 24613 24907 3 24613 24908 24614 3 24909 24614 24908 3 24614 24909 24615 3 24910 24615 24909 3 24615 24910 24616 3 24911 24616 24910 3 24616 24911 24617 3 24912 24617 24911 3 24617 24912 24618 3 24913 24618 24912 3 24618 24913 24619 3 24914 24619 24913 3 24619 24914 24620 3 24915 24620 24914 3 24620 24915 24621 3 24916 24621 24915 3 24621 24916 24622 3 24917 24622 24916 3 24622 24917 24623 3 24918 24623 24917 3 24623 24918 24624 3 24919 24624 24918 3 24624 24919 24625 3 24920 24625 24919 3 24625 24920 24626 3 24921 24626 24920 3 24626 24921 24627 3 24922 24627 24921 3 24627 24922 24628 3 24923 24628 24922 3 24628 24923 24629 3 24924 24629 24923 3 24629 24924 24630 3 24925 24630 24924 3 24630 24925 24631 3 24926 24631 24925 3 24631 24926 24632 3 24927 24632 24926 3 24632 24927 24633 3 24928 24633 24927 3 24633 24928 24634 3 24929 24634 24928 3 24634 24929 24635 3 24930 24635 24929 3 24635 24930 24636 3 24931 24636 24930 3 24636 24931 24637 3 24932 24637 24931 3 24637 24932 24638 3 24933 24638 24932 3 24638 24933 24639 3 24934 24639 24933 3 24639 24934 24640 3 24935 24640 24934 3 24640 24935 24641 3 24936 24641 24935 3 24641 24936 24642 3 24937 24642 24936 3 24642 24937 24643 3 24938 24643 24937 3 24643 24938 24644 3 24939 24644 24938 3 24644 24939 24645 3 24940 24645 24939 3 24645 24940 24646 3 24941 24646 24940 3 24646 24941 24647 3 24942 24647 24941 3 24647 24942 24648 3 24943 24648 24942 3 24648 24943 24649 3 24944 24649 24943 3 24649 24944 24650 3 24945 24650 24944 3 24650 24945 24651 3 24946 24651 24945 3 24651 24946 24652 3 24947 24652 24946 3 24652 24947 24653 3 24948 24653 24947 3 24653 24948 24654 3 24949 24654 24948 3 24654 24949 24655 3 24950 24655 24949 3 24655 24950 24656 3 24951 24656 24950 3 24656 24661 24657 3 24662 24657 24661 3 24656 24951 24661 3 24957 24661 24951 3 24658 24952 24659 3 24953 24659 24952 3 24658 24665 24952 3 24960 24952 24665 3 24659 24953 24660 3 24954 24660 24953 3 24661 24957 24662 3 24958 24662 24957 3 24662 24958 24663 3 24959 24663 24958 3 24663 24959 24666 3 24963 24666 24959 3 24664 24668 24665 3 24669 24665 24668 3 24665 24669 24960 3 24965 24960 24669 3 24666 24670 24667 3 24671 24667 24670 3 24666 24963 24670 3 24966 24670 24963 3 24668 24964 24669 3 24965 24669 24964 3 24668 24672 24964 3 24968 24964 24672 3 24670 24966 24671 3 24967 24671 24966 3 24671 24967 24673 3 24971 24673 24967 3 24672 24674 24968 3 24972 24968 24674 3 24673 24971 24675 3 24973 24675 24971 3 24674 24676 24972 3 24974 24972 24676 3 24675 24973 24677 3 24975 24677 24973 3 24676 24678 24974 3 24976 24974 24678 3 24677 24975 24679 3 24977 24679 24975 3 24678 24680 24976 3 24978 24976 24680 3 24679 24977 24681 3 24979 24681 24977 3 24680 24682 24978 3 24980 24978 24682 3 24681 24979 24683 3 24981 24683 24979 3 24682 24684 24980 3 24982 24980 24684 3 24683 24981 24685 3 24983 24685 24981 3 24684 24686 24984 3 24684 24984 24982 3 24685 24983 24687 3 24985 24687 24983 3 24686 24688 24986 3 24686 24986 24984 3 24687 24985 24689 3 24987 24689 24985 3 24688 24690 24988 3 24688 24988 24986 3 24689 24987 24691 3 24989 24691 24987 3 24690 24692 24990 3 24690 24990 24988 3 24691 24989 24693 3 24991 24693 24989 3 24692 24694 24992 3 24692 24992 24990 3 24693 24991 24695 3 24993 24695 24991 3 24694 24696 24994 3 24694 24994 24992 3 24695 24993 24697 3 24995 24697 24993 3 24696 24698 24996 3 24696 24996 24994 3 24697 24995 24699 3 24997 24699 24995 3 24698 24700 24998 3 24698 24998 24996 3 24699 24997 24701 3 24999 24701 24997 3 24700 24702 25000 3 24700 25000 24998 3 24701 24999 24703 3 25001 24703 24999 3 24702 24704 25002 3 24702 25002 25000 3 24703 25001 24705 3 25003 24705 25001 3 24704 24706 25004 3 24704 25004 25002 3 24705 25003 24707 3 25005 24707 25003 3 24706 24708 25006 3 24706 25006 25004 3 24707 25005 24709 3 25007 24709 25005 3 24708 24710 25008 3 24708 25008 25006 3 24709 25007 25009 3 24709 25009 24711 3 24710 24712 25010 3 24710 25010 25008 3 24711 25009 25011 3 24711 25011 24713 3 24712 24714 25012 3 24712 25012 25010 3 24713 25011 25013 3 24713 25013 24715 3 24714 24716 25014 3 24714 25014 25012 3 24715 25013 25015 3 24715 25015 24717 3 24716 24718 25016 3 24716 25016 25014 3 24717 25015 25017 3 24717 25017 24719 3 24718 24720 25018 3 24718 25018 25016 3 24719 25017 25019 3 24719 25019 24721 3 24720 24722 25020 3 24720 25020 25018 3 24721 25019 25021 3 24721 25021 24723 3 24722 24724 25022 3 24722 25022 25020 3 24723 25021 25023 3 24723 25023 24725 3 24724 24726 25024 3 24724 25024 25022 3 24725 25023 25025 3 24725 25025 24727 3 24726 24728 25026 3 24726 25026 25024 3 24727 25025 25027 3 24727 25027 24729 3 24728 24730 25028 3 24728 25028 25026 3 24729 25027 25029 3 24729 25029 24731 3 24730 24732 25030 3 24730 25030 25028 3 24731 25029 25031 3 24731 25031 24733 3 24732 24734 25032 3 24732 25032 25030 3 24733 25031 25033 3 24733 25033 24735 3 24734 24736 25034 3 24734 25034 25032 3 24735 25033 25035 3 24735 25035 24737 3 24736 24738 25036 3 24736 25036 25034 3 24737 25035 25037 3 24737 25037 24739 3 24738 24740 25038 3 24738 25038 25036 3 24739 25037 25039 3 24739 25039 24741 3 24740 24742 25040 3 24740 25040 25038 3 24741 25039 25041 3 24741 25041 24743 3 24742 24744 25042 3 24742 25042 25040 3 24743 25041 25043 3 24743 25043 24745 3 24744 24746 25044 3 24744 25044 25042 3 24745 25043 25045 3 24745 25045 24747 3 24746 24748 25046 3 24746 25046 25044 3 24747 25045 25047 3 24747 25047 24749 3 24748 24750 25048 3 24748 25048 25046 3 24749 25047 25049 3 24749 25049 24751 3 24750 24752 25050 3 24750 25050 25048 3 24751 25049 25051 3 24751 25051 24753 3 24752 24754 25052 3 24752 25052 25050 3 24753 25051 25053 3 24753 25053 24755 3 24754 24756 25054 3 24754 25054 25052 3 24755 25053 25055 3 24755 25055 24757 3 24756 24758 25056 3 24756 25056 25054 3 24757 25055 25057 3 24757 25057 24759 3 24758 24760 25058 3 24758 25058 25056 3 24759 25057 25059 3 24759 25059 24761 3 24760 24762 25060 3 24760 25060 25058 3 24761 25059 25061 3 24761 25061 24763 3 24762 24764 25062 3 24762 25062 25060 3 24763 25061 25063 3 24763 25063 24765 3 24764 24766 25064 3 24764 25064 25062 3 24765 25063 25065 3 24765 25065 24767 3 24766 24768 25066 3 24766 25066 25064 3 24767 25065 25067 3 24767 25067 24769 3 24768 24770 25068 3 24768 25068 25066 3 24769 25067 25069 3 24769 25069 24771 3 24770 24772 25070 3 24770 25070 25068 3 24771 25069 25071 3 24771 25071 24773 3 24772 24774 25072 3 24772 25072 25070 3 24773 25071 25073 3 24773 25073 24775 3 24774 24776 25074 3 24774 25074 25072 3 24775 25073 25075 3 24775 25075 24777 3 24776 24778 25076 3 24776 25076 25074 3 24777 25075 25077 3 24777 25077 24779 3 24778 24780 25078 3 24778 25078 25076 3 24779 25077 25079 3 24779 25079 24781 3 24780 24782 25080 3 24780 25080 25078 3 24781 25079 25081 3 24781 25081 24783 3 24782 24784 25080 3 25082 25080 24784 3 24783 25081 25083 3 24783 25083 24785 3 24784 24786 25082 3 25084 25082 24786 3 24785 25083 25085 3 24785 25085 24787 3 24786 24788 25084 3 25086 25084 24788 3 24787 25085 25087 3 24787 25087 24789 3 24788 24790 25086 3 25088 25086 24790 3 24789 25087 25089 3 24789 25089 24791 3 24790 24792 25088 3 25090 25088 24792 3 24791 25089 25091 3 24791 25091 24793 3 24792 24794 25090 3 25092 25090 24794 3 24793 25091 25093 3 24793 25093 24795 3 24794 24796 25092 3 25094 25092 24796 3 24795 25093 25095 3 24795 25095 24797 3 24796 24798 25094 3 25096 25094 24798 3 24797 25095 25097 3 24797 25097 24799 3 24798 24800 25096 3 25098 25096 24800 3 24799 25097 25101 3 24799 25101 24801 3 24800 24802 25098 3 25102 25098 24802 3 24801 25101 25105 3 24801 25105 24805 3 24802 24806 24803 3 24807 24803 24806 3 24802 24803 25102 3 25103 25102 24803 3 24803 24807 25103 3 25106 25103 24807 3 24804 24808 24805 3 24809 24805 24808 3 24804 24805 25104 3 25105 25104 24805 3 24804 25104 24808 3 25109 24808 25104 3 24807 24810 25106 3 25110 25106 24810 3 24808 25109 24815 3 25117 24815 25109 3 24810 24811 25110 3 25111 25110 24811 3 24811 24816 24812 3 24817 24812 24816 3 24811 24812 25111 3 25112 25111 24812 3 24812 24817 25112 3 25118 25112 24817 3 24813 24883 24814 3 24884 24814 24883 3 24813 24814 25115 3 25116 25115 24814 3 24813 25115 24883 3 25184 24883 25115 3 24814 24815 25116 3 25117 25116 24815 3 24817 24818 25118 3 25119 25118 24818 3 24818 24819 25119 3 25120 25119 24819 3 24819 24820 25120 3 25121 25120 24820 3 24820 24821 25121 3 25122 25121 24821 3 24821 24822 25122 3 25123 25122 24822 3 24822 24823 25123 3 25124 25123 24823 3 24823 24824 25124 3 25125 25124 24824 3 24824 24825 25125 3 25126 25125 24825 3 24825 24826 25126 3 25127 25126 24826 3 24826 24827 25127 3 25128 25127 24827 3 24827 24828 25128 3 25129 25128 24828 3 24828 24829 25129 3 25130 25129 24829 3 24829 24830 25130 3 25131 25130 24830 3 24830 24831 25131 3 25132 25131 24831 3 24831 24832 25132 3 25133 25132 24832 3 24832 24833 25133 3 25134 25133 24833 3 24833 24834 25134 3 25135 25134 24834 3 24834 24835 25135 3 25136 25135 24835 3 24835 24836 25136 3 25137 25136 24836 3 24836 24837 25137 3 25138 25137 24837 3 24837 24838 25138 3 25139 25138 24838 3 24838 24839 25139 3 25140 25139 24839 3 24839 24840 25140 3 25141 25140 24840 3 24840 24841 25141 3 25142 25141 24841 3 24841 24842 25142 3 25143 25142 24842 3 24842 24843 25143 3 25144 25143 24843 3 24843 24844 25144 3 25145 25144 24844 3 24844 24845 25145 3 25146 25145 24845 3 24845 24846 25146 3 25147 25146 24846 3 24846 24847 25147 3 25148 25147 24847 3 24847 24848 25148 3 25149 25148 24848 3 24848 24849 25149 3 25150 25149 24849 3 24849 24850 25150 3 25151 25150 24850 3 24850 24851 25151 3 25152 25151 24851 3 24851 24852 25152 3 25153 25152 24852 3 24852 24853 25153 3 25154 25153 24853 3 24853 24854 25154 3 25155 25154 24854 3 24854 24855 25155 3 25156 25155 24855 3 24855 24856 25156 3 25157 25156 24856 3 24856 24857 25157 3 25158 25157 24857 3 24857 24858 25158 3 25159 25158 24858 3 24858 24859 25159 3 25160 25159 24859 3 24859 24860 25160 3 25161 25160 24860 3 24860 24861 25161 3 25162 25161 24861 3 24861 24862 25162 3 25163 25162 24862 3 24862 24863 25163 3 25164 25163 24863 3 24863 24864 25164 3 25165 25164 24864 3 24864 24865 25165 3 25166 25165 24865 3 24865 24866 25166 3 25167 25166 24866 3 24866 24867 25167 3 25168 25167 24867 3 24867 24868 25168 3 25169 25168 24868 3 24868 24869 25169 3 25170 25169 24869 3 24869 24870 25170 3 25171 25170 24870 3 24870 24871 25171 3 25172 25171 24871 3 24871 24872 25172 3 25173 25172 24872 3 24872 24873 25173 3 25174 25173 24873 3 24873 24874 25174 3 25175 25174 24874 3 24874 24875 25175 3 25176 25175 24875 3 24875 24876 25176 3 25177 25176 24876 3 24876 24877 25177 3 25178 25177 24877 3 24877 24878 25178 3 25179 25178 24878 3 24878 24879 25179 3 25180 25179 24879 3 24879 24880 25181 3 24879 25181 25180 3 24880 24881 25182 3 24880 25182 25181 3 24881 24882 25183 3 24881 25183 25182 3 24882 24883 25184 3 24882 25184 25183 3 24885 24954 24955 3 24885 24955 24886 3 24886 25185 24887 3 25186 24887 25185 3 24886 24955 25252 3 24886 25252 25185 3 24887 25186 24888 3 25187 24888 25186 3 24888 25187 24889 3 25188 24889 25187 3 24889 25188 24890 3 25189 24890 25188 3 24890 25189 24891 3 25190 24891 25189 3 24891 25190 24892 3 25191 24892 25190 3 24892 25191 24893 3 25192 24893 25191 3 24893 25192 24894 3 25193 24894 25192 3 24894 25193 24895 3 25194 24895 25193 3 24895 25194 24896 3 25195 24896 25194 3 24896 25195 24897 3 25196 24897 25195 3 24897 25196 24898 3 25197 24898 25196 3 24898 25197 24899 3 25198 24899 25197 3 24899 25198 24900 3 25199 24900 25198 3 24900 25199 24901 3 25200 24901 25199 3 24901 25200 24902 3 25201 24902 25200 3 24902 25201 25202 3 24902 25202 24903 3 24903 25202 25203 3 24903 25203 24904 3 24904 25203 25204 3 24904 25204 24905 3 24905 25204 25205 3 24905 25205 24906 3 24906 25205 25206 3 24906 25206 24907 3 24907 25206 25207 3 24907 25207 24908 3 24908 25207 25208 3 24908 25208 24909 3 24909 25208 25209 3 24909 25209 24910 3 24910 25209 25210 3 24910 25210 24911 3 24911 25210 25211 3 24911 25211 24912 3 24912 25211 25212 3 24912 25212 24913 3 24913 25212 25213 3 24913 25213 24914 3 24914 25213 25214 3 24914 25214 24915 3 24915 25214 25215 3 24915 25215 24916 3 24916 25215 25216 3 24916 25216 24917 3 24917 25216 25217 3 24917 25217 24918 3 24918 25217 25218 3 24918 25218 24919 3 24919 25218 25219 3 24919 25219 24920 3 24920 25219 25220 3 24920 25220 24921 3 24921 25220 25221 3 24921 25221 24922 3 24922 25221 25222 3 24922 25222 24923 3 24923 25222 25223 3 24923 25223 24924 3 24924 25223 25224 3 24924 25224 24925 3 24925 25224 25225 3 24925 25225 24926 3 24926 25225 25226 3 24926 25226 24927 3 24927 25226 25227 3 24927 25227 24928 3 24928 25227 25228 3 24928 25228 24929 3 24929 25228 25229 3 24929 25229 24930 3 24930 25229 25230 3 24930 25230 24931 3 24931 25230 25231 3 24931 25231 24932 3 24932 25231 25232 3 24932 25232 24933 3 24933 25232 25233 3 24933 25233 24934 3 24934 25233 25234 3 24934 25234 24935 3 24935 25234 25235 3 24935 25235 24936 3 24936 25235 25236 3 24936 25236 24937 3 24937 25236 25237 3 24937 25237 24938 3 24938 25237 25238 3 24938 25238 24939 3 24939 25238 25239 3 24939 25239 24940 3 24940 25239 25240 3 24940 25240 24941 3 24941 25240 25241 3 24941 25241 24942 3 24942 25241 25242 3 24942 25242 24943 3 24943 25242 25243 3 24943 25243 24944 3 24944 25243 25244 3 24944 25244 24945 3 24945 25244 25245 3 24945 25245 24946 3 24946 25245 25246 3 24946 25246 24947 3 24947 25246 25247 3 24947 25247 24948 3 24948 25247 25248 3 24948 25248 24949 3 24949 25248 25249 3 24949 25249 24950 3 24950 24956 24957 3 24950 24957 24951 3 24950 25249 25316 3 24950 25316 24956 3 24952 24960 24961 3 24952 24961 24953 3 24953 25250 25251 3 24953 25251 24954 3 24953 24961 25320 3 24953 25320 25250 3 24954 25251 25252 3 24954 25252 24955 3 24956 25316 25317 3 24956 25317 24957 3 24957 25317 25318 3 24957 25318 24958 3 24958 24962 24963 3 24958 24963 24959 3 24958 25318 25323 3 24958 25323 24962 3 24960 25319 25320 3 24960 25320 24961 3 24960 24965 25325 3 24960 25325 25319 3 24962 25323 25324 3 24962 25324 24963 3 24963 25324 25328 3 24963 25328 24966 3 24964 24968 24969 3 24964 24969 24965 3 24965 24969 25330 3 24965 25330 25325 3 24966 24970 24971 3 24966 24971 24967 3 24966 25328 24970 3 25331 24970 25328 3 24968 25329 24969 3 25330 24969 25329 3 24968 24972 25333 3 24968 25333 25329 3 24970 25331 24971 3 25332 24971 25331 3 24971 25332 24973 3 25336 24973 25332 3 24972 24974 25337 3 24972 25337 25333 3 24973 25336 24975 3 25340 24975 25336 3 24974 24976 25341 3 24974 25341 25337 3 24975 25340 24977 3 25344 24977 25340 3 24976 24978 25341 3 25345 25341 24978 3 24977 25344 24979 3 25348 24979 25344 3 24978 24980 25345 3 25349 25345 24980 3 24979 25348 24981 3 25352 24981 25348 3 24980 24982 25349 3 25353 25349 24982 3 24981 25352 24983 3 25356 24983 25352 3 24982 24984 25353 3 25357 25353 24984 3 24983 25356 24985 3 25360 24985 25356 3 24984 24986 25357 3 25361 25357 24986 3 24985 25360 24987 3 25364 24987 25360 3 24986 24988 25361 3 25365 25361 24988 3 24987 25364 24989 3 25368 24989 25364 3 24988 24990 25365 3 25369 25365 24990 3 24989 25368 24991 3 25372 24991 25368 3 24990 24992 25369 3 25373 25369 24992 3 24991 25372 24993 3 25376 24993 25372 3 24992 24994 25373 3 25377 25373 24994 3 24993 25376 24995 3 25380 24995 25376 3 24994 24996 25377 3 25381 25377 24996 3 24995 25380 24997 3 25384 24997 25380 3 24996 24998 25381 3 25385 25381 24998 3 24997 25384 24999 3 25388 24999 25384 3 24998 25000 25385 3 25389 25385 25000 3 24999 25388 25001 3 25392 25001 25388 3 25000 25002 25389 3 25393 25389 25002 3 25001 25392 25003 3 25396 25003 25392 3 25002 25004 25393 3 25397 25393 25004 3 25003 25396 25005 3 25400 25005 25396 3 25004 25006 25397 3 25401 25397 25006 3 25005 25400 25007 3 25404 25007 25400 3 25006 25008 25401 3 25405 25401 25008 3 25007 25404 25009 3 25408 25009 25404 3 25008 25010 25405 3 25409 25405 25010 3 25009 25408 25011 3 25412 25011 25408 3 25010 25012 25409 3 25413 25409 25012 3 25011 25412 25013 3 25416 25013 25412 3 25012 25014 25413 3 25417 25413 25014 3 25013 25416 25015 3 25420 25015 25416 3 25014 25016 25417 3 25421 25417 25016 3 25015 25420 25017 3 25424 25017 25420 3 25016 25018 25421 3 25425 25421 25018 3 25017 25424 25019 3 25428 25019 25424 3 25018 25020 25425 3 25429 25425 25020 3 25019 25428 25021 3 25432 25021 25428 3 25020 25022 25429 3 25433 25429 25022 3 25021 25432 25023 3 25436 25023 25432 3 25022 25024 25433 3 25437 25433 25024 3 25023 25436 25025 3 25440 25025 25436 3 25024 25026 25437 3 25441 25437 25026 3 25025 25440 25027 3 25444 25027 25440 3 25026 25028 25441 3 25445 25441 25028 3 25027 25444 25029 3 25448 25029 25444 3 25028 25030 25445 3 25449 25445 25030 3 25029 25448 25452 3 25029 25452 25031 3 25030 25032 25449 3 25453 25449 25032 3 25031 25452 25456 3 25031 25456 25033 3 25032 25034 25453 3 25457 25453 25034 3 25033 25456 25460 3 25033 25460 25035 3 25034 25036 25457 3 25461 25457 25036 3 25035 25460 25464 3 25035 25464 25037 3 25036 25038 25461 3 25465 25461 25038 3 25037 25464 25468 3 25037 25468 25039 3 25038 25040 25465 3 25469 25465 25040 3 25039 25468 25472 3 25039 25472 25041 3 25040 25042 25469 3 25473 25469 25042 3 25041 25472 25476 3 25041 25476 25043 3 25042 25044 25473 3 25477 25473 25044 3 25043 25476 25480 3 25043 25480 25045 3 25044 25046 25477 3 25481 25477 25046 3 25045 25480 25484 3 25045 25484 25047 3 25046 25048 25481 3 25485 25481 25048 3 25047 25484 25488 3 25047 25488 25049 3 25048 25050 25485 3 25489 25485 25050 3 25049 25488 25492 3 25049 25492 25051 3 25050 25052 25489 3 25493 25489 25052 3 25051 25492 25496 3 25051 25496 25053 3 25052 25054 25493 3 25497 25493 25054 3 25053 25496 25500 3 25053 25500 25055 3 25054 25056 25497 3 25501 25497 25056 3 25055 25500 25504 3 25055 25504 25057 3 25056 25058 25501 3 25505 25501 25058 3 25057 25504 25508 3 25057 25508 25059 3 25058 25060 25505 3 25509 25505 25060 3 25059 25508 25512 3 25059 25512 25061 3 25060 25062 25509 3 25513 25509 25062 3 25061 25512 25516 3 25061 25516 25063 3 25062 25064 25513 3 25517 25513 25064 3 25063 25516 25520 3 25063 25520 25065 3 25064 25066 25517 3 25521 25517 25066 3 25065 25520 25524 3 25065 25524 25067 3 25066 25068 25521 3 25525 25521 25068 3 25067 25524 25528 3 25067 25528 25069 3 25068 25070 25525 3 25529 25525 25070 3 25069 25528 25532 3 25069 25532 25071 3 25070 25072 25529 3 25533 25529 25072 3 25071 25532 25536 3 25071 25536 25073 3 25072 25074 25537 3 25072 25537 25533 3 25073 25536 25540 3 25073 25540 25075 3 25074 25076 25541 3 25074 25541 25537 3 25075 25540 25544 3 25075 25544 25077 3 25076 25078 25545 3 25076 25545 25541 3 25077 25544 25548 3 25077 25548 25079 3 25078 25080 25549 3 25078 25549 25545 3 25079 25548 25552 3 25079 25552 25081 3 25080 25082 25553 3 25080 25553 25549 3 25081 25552 25556 3 25081 25556 25083 3 25082 25084 25557 3 25082 25557 25553 3 25083 25556 25560 3 25083 25560 25085 3 25084 25086 25561 3 25084 25561 25557 3 25085 25560 25564 3 25085 25564 25087 3 25086 25088 25565 3 25086 25565 25561 3 25087 25564 25568 3 25087 25568 25089 3 25088 25090 25569 3 25088 25569 25565 3 25089 25568 25572 3 25089 25572 25091 3 25090 25092 25573 3 25090 25573 25569 3 25091 25572 25093 3 25576 25093 25572 3 25092 25094 25577 3 25092 25577 25573 3 25093 25576 25095 3 25580 25095 25576 3 25094 25096 25581 3 25094 25581 25577 3 25095 25580 25097 3 25584 25097 25580 3 25096 25098 25585 3 25096 25585 25581 3 25097 25584 25101 3 25588 25101 25584 3 25098 25102 25103 3 25098 25103 25099 3 25098 25099 25586 3 25098 25586 25585 3 25099 25103 25589 3 25099 25589 25586 3 25100 25104 25105 3 25100 25105 25101 3 25100 25101 25588 3 25100 25588 25587 3 25100 25587 25104 3 25592 25104 25587 3 25103 25106 25593 3 25103 25593 25589 3 25104 25592 25109 3 25598 25109 25592 3 25106 25110 25111 3 25106 25111 25107 3 25106 25107 25594 3 25106 25594 25593 3 25107 25111 25599 3 25107 25599 25594 3 25108 25116 25117 3 25108 25117 25109 3 25108 25109 25598 3 25108 25598 25597 3 25108 25597 25116 3 25667 25116 25597 3 25111 25112 25600 3 25111 25600 25599 3 25112 25118 25119 3 25112 25119 25113 3 25112 25113 25601 3 25112 25601 25600 3 25113 25119 25668 3 25113 25668 25601 3 25114 25183 25184 3 25114 25184 25115 3 25114 25115 25666 3 25114 25666 25665 3 25114 25665 25183 3 25732 25183 25665 3 25115 25116 25667 3 25115 25667 25666 3 25119 25120 25669 3 25119 25669 25668 3 25120 25121 25670 3 25120 25670 25669 3 25121 25122 25671 3 25121 25671 25670 3 25122 25123 25672 3 25122 25672 25671 3 25123 25124 25673 3 25123 25673 25672 3 25124 25125 25674 3 25124 25674 25673 3 25125 25126 25675 3 25125 25675 25674 3 25126 25127 25676 3 25126 25676 25675 3 25127 25128 25677 3 25127 25677 25676 3 25128 25129 25678 3 25128 25678 25677 3 25129 25130 25679 3 25129 25679 25678 3 25130 25131 25680 3 25130 25680 25679 3 25131 25132 25681 3 25131 25681 25680 3 25132 25133 25682 3 25132 25682 25681 3 25133 25134 25683 3 25133 25683 25682 3 25134 25135 25684 3 25134 25684 25683 3 25135 25136 25685 3 25135 25685 25684 3 25136 25137 25686 3 25136 25686 25685 3 25137 25138 25687 3 25137 25687 25686 3 25138 25139 25688 3 25138 25688 25687 3 25139 25140 25689 3 25139 25689 25688 3 25140 25141 25690 3 25140 25690 25689 3 25141 25142 25691 3 25141 25691 25690 3 25142 25143 25692 3 25142 25692 25691 3 25143 25144 25693 3 25143 25693 25692 3 25144 25145 25694 3 25144 25694 25693 3 25145 25146 25695 3 25145 25695 25694 3 25146 25147 25696 3 25146 25696 25695 3 25147 25148 25697 3 25147 25697 25696 3 25148 25149 25698 3 25148 25698 25697 3 25149 25150 25699 3 25149 25699 25698 3 25150 25151 25700 3 25150 25700 25699 3 25151 25152 25701 3 25151 25701 25700 3 25152 25153 25702 3 25152 25702 25701 3 25153 25154 25703 3 25153 25703 25702 3 25154 25155 25704 3 25154 25704 25703 3 25155 25156 25705 3 25155 25705 25704 3 25156 25157 25706 3 25156 25706 25705 3 25157 25158 25707 3 25157 25707 25706 3 25158 25159 25708 3 25158 25708 25707 3 25159 25160 25709 3 25159 25709 25708 3 25160 25161 25710 3 25160 25710 25709 3 25161 25162 25711 3 25161 25711 25710 3 25162 25163 25712 3 25162 25712 25711 3 25163 25164 25713 3 25163 25713 25712 3 25164 25165 25714 3 25164 25714 25713 3 25165 25166 25715 3 25165 25715 25714 3 25166 25167 25716 3 25166 25716 25715 3 25167 25168 25717 3 25167 25717 25716 3 25168 25169 25718 3 25168 25718 25717 3 25169 25170 25719 3 25169 25719 25718 3 25170 25171 25720 3 25170 25720 25719 3 25171 25172 25720 3 25721 25720 25172 3 25172 25173 25721 3 25722 25721 25173 3 25173 25174 25722 3 25723 25722 25174 3 25174 25175 25723 3 25724 25723 25175 3 25175 25176 25724 3 25725 25724 25176 3 25176 25177 25725 3 25726 25725 25177 3 25177 25178 25726 3 25727 25726 25178 3 25178 25179 25727 3 25728 25727 25179 3 25179 25180 25728 3 25729 25728 25180 3 25180 25181 25729 3 25730 25729 25181 3 25181 25182 25730 3 25731 25730 25182 3 25182 25183 25731 3 25732 25731 25183 3 25185 25252 25186 3 25253 25186 25252 3 25186 25253 25187 3 25254 25187 25253 3 25187 25254 25188 3 25255 25188 25254 3 25188 25255 25189 3 25256 25189 25255 3 25189 25256 25190 3 25257 25190 25256 3 25190 25257 25191 3 25258 25191 25257 3 25191 25258 25192 3 25259 25192 25258 3 25192 25259 25193 3 25260 25193 25259 3 25193 25260 25194 3 25261 25194 25260 3 25194 25261 25195 3 25262 25195 25261 3 25195 25262 25196 3 25263 25196 25262 3 25196 25263 25197 3 25264 25197 25263 3 25197 25264 25198 3 25265 25198 25264 3 25198 25265 25199 3 25266 25199 25265 3 25199 25266 25200 3 25267 25200 25266 3 25200 25267 25201 3 25268 25201 25267 3 25201 25268 25202 3 25269 25202 25268 3 25202 25269 25203 3 25270 25203 25269 3 25203 25270 25204 3 25271 25204 25270 3 25204 25271 25205 3 25272 25205 25271 3 25205 25272 25206 3 25273 25206 25272 3 25206 25273 25207 3 25274 25207 25273 3 25207 25274 25208 3 25275 25208 25274 3 25208 25275 25209 3 25276 25209 25275 3 25209 25276 25210 3 25277 25210 25276 3 25210 25277 25211 3 25278 25211 25277 3 25211 25278 25212 3 25279 25212 25278 3 25212 25279 25213 3 25280 25213 25279 3 25213 25280 25214 3 25281 25214 25280 3 25214 25281 25215 3 25282 25215 25281 3 25215 25282 25216 3 25283 25216 25282 3 25216 25283 25217 3 25284 25217 25283 3 25217 25284 25218 3 25285 25218 25284 3 25218 25285 25219 3 25286 25219 25285 3 25219 25286 25220 3 25287 25220 25286 3 25220 25287 25221 3 25288 25221 25287 3 25221 25288 25222 3 25289 25222 25288 3 25222 25289 25223 3 25290 25223 25289 3 25223 25290 25224 3 25291 25224 25290 3 25224 25291 25225 3 25292 25225 25291 3 25225 25292 25226 3 25293 25226 25292 3 25226 25293 25227 3 25294 25227 25293 3 25227 25294 25228 3 25295 25228 25294 3 25228 25295 25229 3 25296 25229 25295 3 25229 25296 25230 3 25297 25230 25296 3 25230 25297 25298 3 25230 25298 25231 3 25231 25298 25299 3 25231 25299 25232 3 25232 25299 25300 3 25232 25300 25233 3 25233 25300 25301 3 25233 25301 25234 3 25234 25301 25302 3 25234 25302 25235 3 25235 25302 25303 3 25235 25303 25236 3 25236 25303 25304 3 25236 25304 25237 3 25237 25304 25305 3 25237 25305 25238 3 25238 25305 25306 3 25238 25306 25239 3 25239 25306 25307 3 25239 25307 25240 3 25240 25307 25308 3 25240 25308 25241 3 25241 25308 25309 3 25241 25309 25242 3 25242 25309 25310 3 25242 25310 25243 3 25243 25310 25311 3 25243 25311 25244 3 25244 25311 25312 3 25244 25312 25245 3 25245 25312 25313 3 25245 25313 25246 3 25246 25313 25314 3 25246 25314 25247 3 25247 25314 25315 3 25247 25315 25248 3 25248 25315 25316 3 25248 25316 25249 3 25250 25320 25321 3 25250 25321 25251 3 25251 25733 25734 3 25251 25734 25252 3 25251 25321 25801 3 25251 25801 25733 3 25252 25734 25735 3 25252 25735 25253 3 25253 25735 25736 3 25253 25736 25254 3 25254 25736 25737 3 25254 25737 25255 3 25255 25737 25738 3 25255 25738 25256 3 25256 25738 25739 3 25256 25739 25257 3 25257 25739 25740 3 25257 25740 25258 3 25258 25740 25741 3 25258 25741 25259 3 25259 25741 25742 3 25259 25742 25260 3 25260 25742 25743 3 25260 25743 25261 3 25261 25743 25744 3 25261 25744 25262 3 25262 25744 25745 3 25262 25745 25263 3 25263 25745 25746 3 25263 25746 25264 3 25264 25746 25747 3 25264 25747 25265 3 25265 25747 25748 3 25265 25748 25266 3 25266 25748 25749 3 25266 25749 25267 3 25267 25749 25750 3 25267 25750 25268 3 25268 25750 25751 3 25268 25751 25269 3 25269 25751 25752 3 25269 25752 25270 3 25270 25752 25753 3 25270 25753 25271 3 25271 25753 25754 3 25271 25754 25272 3 25272 25754 25755 3 25272 25755 25273 3 25273 25755 25756 3 25273 25756 25274 3 25274 25756 25757 3 25274 25757 25275 3 25275 25757 25758 3 25275 25758 25276 3 25276 25758 25759 3 25276 25759 25277 3 25277 25759 25760 3 25277 25760 25278 3 25278 25760 25761 3 25278 25761 25279 3 25279 25761 25762 3 25279 25762 25280 3 25280 25762 25763 3 25280 25763 25281 3 25281 25763 25764 3 25281 25764 25282 3 25282 25764 25765 3 25282 25765 25283 3 25283 25765 25766 3 25283 25766 25284 3 25284 25766 25767 3 25284 25767 25285 3 25285 25767 25768 3 25285 25768 25286 3 25286 25768 25287 3 25769 25287 25768 3 25287 25769 25288 3 25770 25288 25769 3 25288 25770 25289 3 25771 25289 25770 3 25289 25771 25290 3 25772 25290 25771 3 25290 25772 25291 3 25773 25291 25772 3 25291 25773 25292 3 25774 25292 25773 3 25292 25774 25293 3 25775 25293 25774 3 25293 25775 25294 3 25776 25294 25775 3 25294 25776 25295 3 25777 25295 25776 3 25295 25777 25296 3 25778 25296 25777 3 25296 25778 25297 3 25779 25297 25778 3 25297 25779 25298 3 25780 25298 25779 3 25298 25780 25299 3 25781 25299 25780 3 25299 25781 25300 3 25782 25300 25781 3 25300 25782 25301 3 25783 25301 25782 3 25301 25783 25302 3 25784 25302 25783 3 25302 25784 25303 3 25785 25303 25784 3 25303 25785 25304 3 25786 25304 25785 3 25304 25786 25305 3 25787 25305 25786 3 25305 25787 25306 3 25788 25306 25787 3 25306 25788 25307 3 25789 25307 25788 3 25307 25789 25308 3 25790 25308 25789 3 25308 25790 25309 3 25791 25309 25790 3 25309 25791 25310 3 25792 25310 25791 3 25310 25792 25311 3 25793 25311 25792 3 25311 25793 25312 3 25794 25312 25793 3 25312 25794 25313 3 25795 25313 25794 3 25313 25795 25314 3 25796 25314 25795 3 25314 25796 25315 3 25797 25315 25796 3 25315 25797 25316 3 25798 25316 25797 3 25316 25798 25317 3 25799 25317 25798 3 25317 25322 25323 3 25317 25323 25318 3 25317 25799 25322 3 25867 25322 25799 3 25319 25325 25326 3 25319 25326 25320 3 25320 25800 25321 3 25801 25321 25800 3 25320 25326 25870 3 25320 25870 25800 3 25322 25867 25323 3 25868 25323 25867 3 25323 25327 25328 3 25323 25328 25324 3 25323 25868 25327 3 25875 25327 25868 3 25325 25869 25326 3 25870 25326 25869 3 25325 25330 25877 3 25325 25877 25869 3 25327 25875 25328 3 25876 25328 25875 3 25328 25876 25331 3 25882 25331 25876 3 25329 25333 25334 3 25329 25334 25330 3 25330 25334 25883 3 25330 25883 25877 3 25331 25335 25336 3 25331 25336 25332 3 25331 25882 25335 3 25886 25335 25882 3 25333 25337 25338 3 25333 25338 25334 3 25334 25338 25887 3 25334 25887 25883 3 25335 25339 25340 3 25335 25340 25336 3 25335 25886 25339 3 25890 25339 25886 3 25337 25341 25342 3 25337 25342 25338 3 25338 25342 25891 3 25338 25891 25887 3 25339 25343 25344 3 25339 25344 25340 3 25339 25890 25343 3 25894 25343 25890 3 25341 25345 25346 3 25341 25346 25342 3 25342 25346 25895 3 25342 25895 25891 3 25343 25347 25348 3 25343 25348 25344 3 25343 25894 25347 3 25898 25347 25894 3 25345 25349 25350 3 25345 25350 25346 3 25346 25350 25899 3 25346 25899 25895 3 25347 25351 25352 3 25347 25352 25348 3 25347 25898 25902 3 25347 25902 25351 3 25349 25353 25354 3 25349 25354 25350 3 25350 25354 25903 3 25350 25903 25899 3 25351 25355 25356 3 25351 25356 25352 3 25351 25902 25906 3 25351 25906 25355 3 25353 25357 25358 3 25353 25358 25354 3 25354 25358 25907 3 25354 25907 25903 3 25355 25359 25360 3 25355 25360 25356 3 25355 25906 25910 3 25355 25910 25359 3 25357 25361 25362 3 25357 25362 25358 3 25358 25362 25911 3 25358 25911 25907 3 25359 25363 25364 3 25359 25364 25360 3 25359 25910 25914 3 25359 25914 25363 3 25361 25365 25366 3 25361 25366 25362 3 25362 25366 25915 3 25362 25915 25911 3 25363 25367 25368 3 25363 25368 25364 3 25363 25914 25918 3 25363 25918 25367 3 25365 25369 25366 3 25370 25366 25369 3 25366 25370 25915 3 25919 25915 25370 3 25367 25371 25368 3 25372 25368 25371 3 25367 25918 25922 3 25367 25922 25371 3 25369 25373 25370 3 25374 25370 25373 3 25370 25374 25919 3 25923 25919 25374 3 25371 25375 25372 3 25376 25372 25375 3 25371 25922 25926 3 25371 25926 25375 3 25373 25377 25374 3 25378 25374 25377 3 25374 25378 25923 3 25927 25923 25378 3 25375 25379 25376 3 25380 25376 25379 3 25375 25926 25930 3 25375 25930 25379 3 25377 25381 25378 3 25382 25378 25381 3 25378 25382 25927 3 25931 25927 25382 3 25379 25383 25380 3 25384 25380 25383 3 25379 25930 25934 3 25379 25934 25383 3 25381 25385 25382 3 25386 25382 25385 3 25382 25386 25931 3 25935 25931 25386 3 25383 25387 25384 3 25388 25384 25387 3 25383 25934 25938 3 25383 25938 25387 3 25385 25389 25386 3 25390 25386 25389 3 25386 25390 25935 3 25939 25935 25390 3 25387 25391 25388 3 25392 25388 25391 3 25387 25938 25942 3 25387 25942 25391 3 25389 25393 25390 3 25394 25390 25393 3 25390 25394 25939 3 25943 25939 25394 3 25391 25395 25392 3 25396 25392 25395 3 25391 25942 25946 3 25391 25946 25395 3 25393 25397 25394 3 25398 25394 25397 3 25394 25398 25943 3 25947 25943 25398 3 25395 25399 25396 3 25400 25396 25399 3 25395 25946 25950 3 25395 25950 25399 3 25397 25401 25398 3 25402 25398 25401 3 25398 25402 25947 3 25951 25947 25402 3 25399 25403 25400 3 25404 25400 25403 3 25399 25950 25954 3 25399 25954 25403 3 25401 25405 25402 3 25406 25402 25405 3 25402 25406 25951 3 25955 25951 25406 3 25403 25407 25404 3 25408 25404 25407 3 25403 25954 25958 3 25403 25958 25407 3 25405 25409 25406 3 25410 25406 25409 3 25406 25410 25955 3 25959 25955 25410 3 25407 25411 25408 3 25412 25408 25411 3 25407 25958 25962 3 25407 25962 25411 3 25409 25413 25410 3 25414 25410 25413 3 25410 25414 25959 3 25963 25959 25414 3 25411 25415 25412 3 25416 25412 25415 3 25411 25962 25966 3 25411 25966 25415 3 25413 25417 25414 3 25418 25414 25417 3 25414 25418 25963 3 25967 25963 25418 3 25415 25419 25416 3 25420 25416 25419 3 25415 25966 25970 3 25415 25970 25419 3 25417 25421 25418 3 25422 25418 25421 3 25418 25422 25967 3 25971 25967 25422 3 25419 25423 25420 3 25424 25420 25423 3 25419 25970 25974 3 25419 25974 25423 3 25421 25425 25422 3 25426 25422 25425 3 25422 25426 25971 3 25975 25971 25426 3 25423 25427 25424 3 25428 25424 25427 3 25423 25974 25978 3 25423 25978 25427 3 25425 25429 25426 3 25430 25426 25429 3 25426 25430 25975 3 25979 25975 25430 3 25427 25431 25428 3 25432 25428 25431 3 25427 25978 25982 3 25427 25982 25431 3 25429 25433 25430 3 25434 25430 25433 3 25430 25434 25979 3 25983 25979 25434 3 25431 25435 25432 3 25436 25432 25435 3 25431 25982 25986 3 25431 25986 25435 3 25433 25437 25434 3 25438 25434 25437 3 25434 25438 25983 3 25987 25983 25438 3 25435 25439 25436 3 25440 25436 25439 3 25435 25986 25990 3 25435 25990 25439 3 25437 25441 25438 3 25442 25438 25441 3 25438 25442 25987 3 25991 25987 25442 3 25439 25443 25440 3 25444 25440 25443 3 25439 25990 25994 3 25439 25994 25443 3 25441 25445 25442 3 25446 25442 25445 3 25442 25446 25991 3 25995 25991 25446 3 25443 25447 25444 3 25448 25444 25447 3 25443 25994 25998 3 25443 25998 25447 3 25445 25449 25446 3 25450 25446 25449 3 25446 25450 25995 3 25999 25995 25450 3 25447 25451 25448 3 25452 25448 25451 3 25447 25998 25451 3 26002 25451 25998 3 25449 25453 25450 3 25454 25450 25453 3 25450 25454 25999 3 26003 25999 25454 3 25451 25455 25452 3 25456 25452 25455 3 25451 26002 25455 3 26006 25455 26002 3 25453 25457 25454 3 25458 25454 25457 3 25454 25458 26003 3 26007 26003 25458 3 25455 25459 25456 3 25460 25456 25459 3 25455 26006 25459 3 26010 25459 26006 3 25457 25461 25458 3 25462 25458 25461 3 25458 25462 26007 3 26011 26007 25462 3 25459 25463 25460 3 25464 25460 25463 3 25459 26010 25463 3 26014 25463 26010 3 25461 25465 25462 3 25466 25462 25465 3 25462 25466 26011 3 26015 26011 25466 3 25463 25467 25468 3 25463 25468 25464 3 25463 26014 25467 3 26018 25467 26014 3 25465 25469 25470 3 25465 25470 25466 3 25466 25470 26019 3 25466 26019 26015 3 25467 25471 25472 3 25467 25472 25468 3 25467 26018 25471 3 26022 25471 26018 3 25469 25473 25474 3 25469 25474 25470 3 25470 25474 26023 3 25470 26023 26019 3 25471 25475 25476 3 25471 25476 25472 3 25471 26022 25475 3 26026 25475 26022 3 25473 25477 25478 3 25473 25478 25474 3 25474 25478 26027 3 25474 26027 26023 3 25475 25479 25480 3 25475 25480 25476 3 25475 26026 25479 3 26030 25479 26026 3 25477 25481 25482 3 25477 25482 25478 3 25478 25482 26031 3 25478 26031 26027 3 25479 25483 25484 3 25479 25484 25480 3 25479 26030 25483 3 26034 25483 26030 3 25481 25485 25486 3 25481 25486 25482 3 25482 25486 26035 3 25482 26035 26031 3 25483 25487 25488 3 25483 25488 25484 3 25483 26034 25487 3 26038 25487 26034 3 25485 25489 25490 3 25485 25490 25486 3 25486 25490 26039 3 25486 26039 26035 3 25487 25491 25492 3 25487 25492 25488 3 25487 26038 25491 3 26042 25491 26038 3 25489 25493 25494 3 25489 25494 25490 3 25490 25494 26043 3 25490 26043 26039 3 25491 25495 25496 3 25491 25496 25492 3 25491 26042 25495 3 26046 25495 26042 3 25493 25497 25498 3 25493 25498 25494 3 25494 25498 26047 3 25494 26047 26043 3 25495 25499 25500 3 25495 25500 25496 3 25495 26046 25499 3 26050 25499 26046 3 25497 25501 25502 3 25497 25502 25498 3 25498 25502 26051 3 25498 26051 26047 3 25499 25503 25504 3 25499 25504 25500 3 25499 26050 25503 3 26054 25503 26050 3 25501 25505 25506 3 25501 25506 25502 3 25502 25506 26055 3 25502 26055 26051 3 25503 25507 25508 3 25503 25508 25504 3 25503 26054 25507 3 26058 25507 26054 3 25505 25509 25510 3 25505 25510 25506 3 25506 25510 26059 3 25506 26059 26055 3 25507 25511 25512 3 25507 25512 25508 3 25507 26058 25511 3 26062 25511 26058 3 25509 25513 25514 3 25509 25514 25510 3 25510 25514 26063 3 25510 26063 26059 3 25511 25515 25516 3 25511 25516 25512 3 25511 26062 25515 3 26066 25515 26062 3 25513 25517 25518 3 25513 25518 25514 3 25514 25518 26067 3 25514 26067 26063 3 25515 25519 25520 3 25515 25520 25516 3 25515 26066 25519 3 26070 25519 26066 3 25517 25521 25522 3 25517 25522 25518 3 25518 25522 26071 3 25518 26071 26067 3 25519 25523 25524 3 25519 25524 25520 3 25519 26070 25523 3 26074 25523 26070 3 25521 25525 25526 3 25521 25526 25522 3 25522 25526 26075 3 25522 26075 26071 3 25523 25527 25528 3 25523 25528 25524 3 25523 26074 25527 3 26078 25527 26074 3 25525 25529 25530 3 25525 25530 25526 3 25526 25530 26079 3 25526 26079 26075 3 25527 25531 25532 3 25527 25532 25528 3 25527 26078 25531 3 26082 25531 26078 3 25529 25533 25534 3 25529 25534 25530 3 25530 25534 26083 3 25530 26083 26079 3 25531 25535 25536 3 25531 25536 25532 3 25531 26082 25535 3 26086 25535 26082 3 25533 25537 25538 3 25533 25538 25534 3 25534 25538 26087 3 25534 26087 26083 3 25535 25539 25540 3 25535 25540 25536 3 25535 26086 25539 3 26090 25539 26086 3 25537 25541 25542 3 25537 25542 25538 3 25538 25542 26091 3 25538 26091 26087 3 25539 25543 25544 3 25539 25544 25540 3 25539 26090 25543 3 26094 25543 26090 3 25541 25545 25546 3 25541 25546 25542 3 25542 25546 26095 3 25542 26095 26091 3 25543 25547 25548 3 25543 25548 25544 3 25543 26094 26098 3 25543 26098 25547 3 25545 25549 25550 3 25545 25550 25546 3 25546 25550 26099 3 25546 26099 26095 3 25547 25551 25552 3 25547 25552 25548 3 25547 26098 26102 3 25547 26102 25551 3 25549 25553 25554 3 25549 25554 25550 3 25550 25554 26103 3 25550 26103 26099 3 25551 25555 25556 3 25551 25556 25552 3 25551 26102 26106 3 25551 26106 25555 3 25553 25557 25558 3 25553 25558 25554 3 25554 25558 26107 3 25554 26107 26103 3 25555 25559 25560 3 25555 25560 25556 3 25555 26106 26110 3 25555 26110 25559 3 25557 25561 25562 3 25557 25562 25558 3 25558 25562 26111 3 25558 26111 26107 3 25559 25563 25564 3 25559 25564 25560 3 25559 26110 26114 3 25559 26114 25563 3 25561 25565 25562 3 25566 25562 25565 3 25562 25566 26111 3 26115 26111 25566 3 25563 25567 25564 3 25568 25564 25567 3 25563 26114 26118 3 25563 26118 25567 3 25565 25569 25566 3 25570 25566 25569 3 25566 25570 26115 3 26119 26115 25570 3 25567 25571 25568 3 25572 25568 25571 3 25567 26118 26122 3 25567 26122 25571 3 25569 25573 25570 3 25574 25570 25573 3 25570 25574 26119 3 26123 26119 25574 3 25571 25575 25572 3 25576 25572 25575 3 25571 26122 26126 3 25571 26126 25575 3 25573 25577 25574 3 25578 25574 25577 3 25574 25578 26123 3 26127 26123 25578 3 25575 25579 25576 3 25580 25576 25579 3 25575 26126 26130 3 25575 26130 25579 3 25577 25581 25578 3 25582 25578 25581 3 25578 25582 26127 3 26131 26127 25582 3 25579 25583 25580 3 25584 25580 25583 3 25579 26130 26134 3 25579 26134 25583 3 25581 25585 25582 3 25586 25582 25585 3 25582 25586 26131 3 26135 26131 25586 3 25583 25587 25584 3 25588 25584 25587 3 25583 26134 26140 3 25583 26140 25587 3 25586 25589 26135 3 26141 26135 25589 3 25587 26140 26148 3 25587 26148 25592 3 25589 25593 25590 3 25594 25590 25593 3 25589 25590 26141 3 26142 26141 25590 3 25590 25594 26142 3 26149 26142 25594 3 25591 25597 25592 3 25598 25592 25597 3 25591 25592 26147 3 26148 26147 25592 3 25591 26147 26217 3 25591 26217 25597 3 25594 25599 25595 3 25600 25595 25599 3 25594 25595 26149 3 26150 26149 25595 3 25595 25600 26150 3 26218 26150 25600 3 25596 25666 25597 3 25667 25597 25666 3 25596 25597 26216 3 26217 26216 25597 3 25596 26216 26284 3 25596 26284 25666 3 25600 25601 26218 3 26219 26218 25601 3 25601 25668 25602 3 25669 25602 25668 3 25601 25602 26219 3 26220 26219 25602 3 25602 25669 25603 3 25670 25603 25669 3 25602 25603 26220 3 26221 26220 25603 3 25603 25670 25604 3 25671 25604 25670 3 25603 25604 26221 3 26222 26221 25604 3 25604 25671 25605 3 25672 25605 25671 3 25604 25605 26222 3 26223 26222 25605 3 25605 25672 25606 3 25673 25606 25672 3 25605 25606 26223 3 26224 26223 25606 3 25606 25673 25607 3 25674 25607 25673 3 25606 25607 26224 3 26225 26224 25607 3 25607 25674 25608 3 25675 25608 25674 3 25607 25608 26225 3 26226 26225 25608 3 25608 25675 25609 3 25676 25609 25675 3 25608 25609 26226 3 26227 26226 25609 3 25609 25676 25610 3 25677 25610 25676 3 25609 25610 26227 3 26228 26227 25610 3 25610 25677 25611 3 25678 25611 25677 3 25610 25611 26228 3 26229 26228 25611 3 25611 25678 25612 3 25679 25612 25678 3 25611 25612 26229 3 26230 26229 25612 3 25612 25679 25613 3 25680 25613 25679 3 25612 25613 26230 3 26231 26230 25613 3 25613 25680 25614 3 25681 25614 25680 3 25613 25614 26231 3 26232 26231 25614 3 25614 25681 25615 3 25682 25615 25681 3 25614 25615 26232 3 26233 26232 25615 3 25615 25682 25616 3 25683 25616 25682 3 25615 25616 26233 3 26234 26233 25616 3 25616 25683 25617 3 25684 25617 25683 3 25616 25617 26234 3 26235 26234 25617 3 25617 25684 25618 3 25685 25618 25684 3 25617 25618 26235 3 26236 26235 25618 3 25618 25685 25619 3 25686 25619 25685 3 25618 25619 26236 3 26237 26236 25619 3 25619 25686 25620 3 25687 25620 25686 3 25619 25620 26237 3 26238 26237 25620 3 25620 25687 25621 3 25688 25621 25687 3 25620 25621 26238 3 26239 26238 25621 3 25621 25688 25622 3 25689 25622 25688 3 25621 25622 26239 3 26240 26239 25622 3 25622 25689 25623 3 25690 25623 25689 3 25622 25623 26240 3 26241 26240 25623 3 25623 25690 25691 3 25623 25691 25624 3 25623 25624 26241 3 26242 26241 25624 3 25624 25691 25692 3 25624 25692 25625 3 25624 25625 26242 3 26243 26242 25625 3 25625 25692 25693 3 25625 25693 25626 3 25625 25626 26243 3 26244 26243 25626 3 25626 25693 25694 3 25626 25694 25627 3 25626 25627 26244 3 26245 26244 25627 3 25627 25694 25695 3 25627 25695 25628 3 25627 25628 26245 3 26246 26245 25628 3 25628 25695 25696 3 25628 25696 25629 3 25628 25629 26246 3 26247 26246 25629 3 25629 25696 25697 3 25629 25697 25630 3 25629 25630 26247 3 26248 26247 25630 3 25630 25697 25698 3 25630 25698 25631 3 25630 25631 26248 3 26249 26248 25631 3 25631 25698 25699 3 25631 25699 25632 3 25631 25632 26249 3 26250 26249 25632 3 25632 25699 25700 3 25632 25700 25633 3 25632 25633 26250 3 26251 26250 25633 3 25633 25700 25701 3 25633 25701 25634 3 25633 25634 26251 3 26252 26251 25634 3 25634 25701 25702 3 25634 25702 25635 3 25634 25635 26252 3 26253 26252 25635 3 25635 25702 25703 3 25635 25703 25636 3 25635 25636 26253 3 26254 26253 25636 3 25636 25703 25704 3 25636 25704 25637 3 25636 25637 26254 3 26255 26254 25637 3 25637 25704 25705 3 25637 25705 25638 3 25637 25638 26255 3 26256 26255 25638 3 25638 25705 25706 3 25638 25706 25639 3 25638 25639 26256 3 26257 26256 25639 3 25639 25706 25707 3 25639 25707 25640 3 25639 25640 26257 3 26258 26257 25640 3 25640 25707 25708 3 25640 25708 25641 3 25640 25641 26258 3 26259 26258 25641 3 25641 25708 25709 3 25641 25709 25642 3 25641 25642 26259 3 26260 26259 25642 3 25642 25709 25710 3 25642 25710 25643 3 25642 25643 26260 3 26261 26260 25643 3 25643 25710 25711 3 25643 25711 25644 3 25643 25644 26261 3 26262 26261 25644 3 25644 25711 25712 3 25644 25712 25645 3 25644 25645 26262 3 26263 26262 25645 3 25645 25712 25713 3 25645 25713 25646 3 25645 25646 26263 3 26264 26263 25646 3 25646 25713 25714 3 25646 25714 25647 3 25646 25647 26264 3 26265 26264 25647 3 25647 25714 25715 3 25647 25715 25648 3 25647 25648 26265 3 26266 26265 25648 3 25648 25715 25716 3 25648 25716 25649 3 25648 25649 26266 3 26267 26266 25649 3 25649 25716 25717 3 25649 25717 25650 3 25649 25650 26267 3 26268 26267 25650 3 25650 25717 25718 3 25650 25718 25651 3 25650 25651 26268 3 26269 26268 25651 3 25651 25718 25719 3 25651 25719 25652 3 25651 25652 26269 3 26270 26269 25652 3 25652 25719 25720 3 25652 25720 25653 3 25652 25653 26270 3 26271 26270 25653 3 25653 25720 25721 3 25653 25721 25654 3 25653 25654 26271 3 26272 26271 25654 3 25654 25721 25722 3 25654 25722 25655 3 25654 25655 26272 3 26273 26272 25655 3 25655 25722 25723 3 25655 25723 25656 3 25655 25656 26273 3 26274 26273 25656 3 25656 25723 25724 3 25656 25724 25657 3 25656 25657 26274 3 26275 26274 25657 3 25657 25724 25725 3 25657 25725 25658 3 25657 25658 26275 3 26276 26275 25658 3 25658 25725 25726 3 25658 25726 25659 3 25658 25659 26276 3 26277 26276 25659 3 25659 25726 25727 3 25659 25727 25660 3 25659 25660 26277 3 26278 26277 25660 3 25660 25727 25728 3 25660 25728 25661 3 25660 25661 26278 3 26279 26278 25661 3 25661 25728 25729 3 25661 25729 25662 3 25661 25662 26280 3 25661 26280 26279 3 25662 25729 25730 3 25662 25730 25663 3 25662 25663 26281 3 25662 26281 26280 3 25663 25730 25731 3 25663 25731 25664 3 25663 25664 26282 3 25663 26282 26281 3 25664 25731 25732 3 25664 25732 25665 3 25664 25665 26283 3 25664 26283 26282 3 25665 25666 26284 3 25665 26284 26283 3 25733 25801 25734 3 25802 25734 25801 3 25734 25802 25735 3 25803 25735 25802 3 25735 25803 25736 3 25804 25736 25803 3 25736 25804 25737 3 25805 25737 25804 3 25737 25805 25738 3 25806 25738 25805 3 25738 25806 25739 3 25807 25739 25806 3 25739 25807 25740 3 25808 25740 25807 3 25740 25808 25741 3 25809 25741 25808 3 25741 25809 25742 3 25810 25742 25809 3 25742 25810 25743 3 25811 25743 25810 3 25743 25811 25744 3 25812 25744 25811 3 25744 25812 25745 3 25813 25745 25812 3 25745 25813 25746 3 25814 25746 25813 3 25746 25814 25747 3 25815 25747 25814 3 25747 25815 25748 3 25816 25748 25815 3 25748 25816 25749 3 25817 25749 25816 3 25749 25817 25750 3 25818 25750 25817 3 25750 25818 25751 3 25819 25751 25818 3 25751 25819 25752 3 25820 25752 25819 3 25752 25820 25753 3 25821 25753 25820 3 25753 25821 25754 3 25822 25754 25821 3 25754 25822 25755 3 25823 25755 25822 3 25755 25823 25756 3 25824 25756 25823 3 25756 25824 25757 3 25825 25757 25824 3 25757 25825 25758 3 25826 25758 25825 3 25758 25826 25759 3 25827 25759 25826 3 25759 25827 25760 3 25828 25760 25827 3 25760 25828 25761 3 25829 25761 25828 3 25761 25829 25762 3 25830 25762 25829 3 25762 25830 25763 3 25831 25763 25830 3 25763 25831 25764 3 25832 25764 25831 3 25764 25832 25765 3 25833 25765 25832 3 25765 25833 25766 3 25834 25766 25833 3 25766 25834 25767 3 25835 25767 25834 3 25767 25835 25768 3 25836 25768 25835 3 25768 25836 25769 3 25837 25769 25836 3 25769 25837 25770 3 25838 25770 25837 3 25770 25838 25771 3 25839 25771 25838 3 25771 25839 25772 3 25840 25772 25839 3 25772 25840 25773 3 25841 25773 25840 3 25773 25841 25774 3 25842 25774 25841 3 25774 25842 25775 3 25843 25775 25842 3 25775 25843 25776 3 25844 25776 25843 3 25776 25844 25777 3 25845 25777 25844 3 25777 25845 25778 3 25846 25778 25845 3 25778 25846 25779 3 25847 25779 25846 3 25779 25847 25780 3 25848 25780 25847 3 25780 25848 25781 3 25849 25781 25848 3 25781 25849 25782 3 25850 25782 25849 3 25782 25850 25783 3 25851 25783 25850 3 25783 25851 25784 3 25852 25784 25851 3 25784 25852 25785 3 25853 25785 25852 3 25785 25853 25786 3 25854 25786 25853 3 25786 25854 25787 3 25855 25787 25854 3 25787 25855 25788 3 25856 25788 25855 3 25788 25856 25789 3 25857 25789 25856 3 25789 25857 25790 3 25858 25790 25857 3 25790 25858 25791 3 25859 25791 25858 3 25791 25859 25792 3 25860 25792 25859 3 25792 25860 25793 3 25861 25793 25860 3 25793 25861 25794 3 25862 25794 25861 3 25794 25862 25795 3 25863 25795 25862 3 25795 25863 25796 3 25864 25796 25863 3 25796 25864 25797 3 25865 25797 25864 3 25797 25865 25798 3 25866 25798 25865 3 25798 25866 25799 3 25867 25799 25866 3 25800 25870 25801 3 25871 25801 25870 3 25801 25871 25802 3 25872 25802 25871 3 25802 26285 26286 3 25802 26286 25803 3 25802 25872 26285 3 26351 26285 25872 3 25803 26286 26287 3 25803 26287 25804 3 25804 26287 26288 3 25804 26288 25805 3 25805 26288 26289 3 25805 26289 25806 3 25806 26289 26290 3 25806 26290 25807 3 25807 26290 26291 3 25807 26291 25808 3 25808 26291 26292 3 25808 26292 25809 3 25809 26292 26293 3 25809 26293 25810 3 25810 26293 26294 3 25810 26294 25811 3 25811 26294 26295 3 25811 26295 25812 3 25812 26295 26296 3 25812 26296 25813 3 25813 26296 26297 3 25813 26297 25814 3 25814 26297 26298 3 25814 26298 25815 3 25815 26298 26299 3 25815 26299 25816 3 25816 26299 26300 3 25816 26300 25817 3 25817 26300 26301 3 25817 26301 25818 3 25818 26301 26302 3 25818 26302 25819 3 25819 26302 26303 3 25819 26303 25820 3 25820 26303 26304 3 25820 26304 25821 3 25821 26304 26305 3 25821 26305 25822 3 25822 26305 26306 3 25822 26306 25823 3 25823 26306 26307 3 25823 26307 25824 3 25824 26307 26308 3 25824 26308 25825 3 25825 26308 26309 3 25825 26309 25826 3 25826 26309 26310 3 25826 26310 25827 3 25827 26310 26311 3 25827 26311 25828 3 25828 26311 26312 3 25828 26312 25829 3 25829 26312 26313 3 25829 26313 25830 3 25830 26313 26314 3 25830 26314 25831 3 25831 26314 26315 3 25831 26315 25832 3 25832 26315 26316 3 25832 26316 25833 3 25833 26316 26317 3 25833 26317 25834 3 25834 26317 26318 3 25834 26318 25835 3 25835 26318 26319 3 25835 26319 25836 3 25836 26319 26320 3 25836 26320 25837 3 25837 26320 26321 3 25837 26321 25838 3 25838 26321 26322 3 25838 26322 25839 3 25839 26322 26323 3 25839 26323 25840 3 25840 26323 26324 3 25840 26324 25841 3 25841 26324 26325 3 25841 26325 25842 3 25842 26325 26326 3 25842 26326 25843 3 25843 26326 26327 3 25843 26327 25844 3 25844 26327 26328 3 25844 26328 25845 3 25845 26328 26329 3 25845 26329 25846 3 25846 26329 26330 3 25846 26330 25847 3 25847 26330 26331 3 25847 26331 25848 3 25848 26331 26332 3 25848 26332 25849 3 25849 26332 26333 3 25849 26333 25850 3 25850 26333 26334 3 25850 26334 25851 3 25851 26334 26335 3 25851 26335 25852 3 25852 26335 26336 3 25852 26336 25853 3 25853 26336 26337 3 25853 26337 25854 3 25854 26337 26338 3 25854 26338 25855 3 25855 26338 26339 3 25855 26339 25856 3 25856 26339 26340 3 25856 26340 25857 3 25857 26340 26341 3 25857 26341 25858 3 25858 26341 26342 3 25858 26342 25859 3 25859 26342 26343 3 25859 26343 25860 3 25860 26343 26344 3 25860 26344 25861 3 25861 26344 26345 3 25861 26345 25862 3 25862 26345 26346 3 25862 26346 25863 3 25863 26346 26347 3 25863 26347 25864 3 25864 26347 26348 3 25864 26348 25865 3 25865 26348 26349 3 25865 26349 25866 3 25866 25873 25874 3 25866 25874 25867 3 25866 26349 26415 3 25866 26415 25873 3 25867 25874 25875 3 25867 25875 25868 3 25869 25877 25878 3 25869 25878 25870 3 25870 25878 25879 3 25870 25879 25871 3 25871 26350 26351 3 25871 26351 25872 3 25871 25879 26418 3 25871 26418 26350 3 25873 26415 25874 3 26416 25874 26415 3 25874 25880 25881 3 25874 25881 25875 3 25874 26416 25880 3 26484 25880 26416 3 25875 25881 25882 3 25875 25882 25876 3 25877 25883 25884 3 25877 25884 25878 3 25878 26417 25879 3 26418 25879 26417 3 25878 25884 26486 3 25878 26486 26417 3 25880 26484 25881 3 26485 25881 26484 3 25881 25885 25886 3 25881 25886 25882 3 25881 26485 25885 3 26554 25885 26485 3 25883 25887 25888 3 25883 25888 25884 3 25884 25888 26555 3 25884 26555 26486 3 25885 25889 25890 3 25885 25890 25886 3 25885 26554 26623 3 25885 26623 25889 3 25887 25891 25892 3 25887 25892 25888 3 25888 25892 26624 3 25888 26624 26555 3 25889 25893 25894 3 25889 25894 25890 3 25889 26623 26692 3 25889 26692 25893 3 25891 25895 25896 3 25891 25896 25892 3 25892 25896 26693 3 25892 26693 26624 3 25893 25897 25898 3 25893 25898 25894 3 25893 26692 26761 3 25893 26761 25897 3 25895 25899 25900 3 25895 25900 25896 3 25896 25900 26762 3 25896 26762 26693 3 25897 25901 25902 3 25897 25902 25898 3 25897 26761 25901 3 26830 25901 26761 3 25899 25903 25904 3 25899 25904 25900 3 25900 25904 26831 3 25900 26831 26762 3 25901 25905 25906 3 25901 25906 25902 3 25901 26830 25905 3 26899 25905 26830 3 25903 25907 25908 3 25903 25908 25904 3 25904 25908 26900 3 25904 26900 26831 3 25905 25909 25910 3 25905 25910 25906 3 25905 26899 26968 3 25905 26968 25909 3 25907 25911 25912 3 25907 25912 25908 3 25908 25912 26969 3 25908 26969 26900 3 25909 25913 25914 3 25909 25914 25910 3 25909 26968 27037 3 25909 27037 25913 3 25911 25915 25916 3 25911 25916 25912 3 25912 25916 27038 3 25912 27038 26969 3 25913 25917 25918 3 25913 25918 25914 3 25913 27037 25917 3 27106 25917 27037 3 25915 25919 25920 3 25915 25920 25916 3 25916 25920 27107 3 25916 27107 27038 3 25917 25921 25922 3 25917 25922 25918 3 25917 27106 25921 3 27175 25921 27106 3 25919 25923 25924 3 25919 25924 25920 3 25920 25924 27176 3 25920 27176 27107 3 25921 25925 25926 3 25921 25926 25922 3 25921 27175 25925 3 27244 25925 27175 3 25923 25927 25928 3 25923 25928 25924 3 25924 25928 27245 3 25924 27245 27176 3 25925 25929 25930 3 25925 25930 25926 3 25925 27244 27313 3 25925 27313 25929 3 25927 25931 25932 3 25927 25932 25928 3 25928 25932 27314 3 25928 27314 27245 3 25929 25933 25934 3 25929 25934 25930 3 25929 27313 27382 3 25929 27382 25933 3 25931 25935 25936 3 25931 25936 25932 3 25932 25936 27383 3 25932 27383 27314 3 25933 25937 25938 3 25933 25938 25934 3 25933 27382 25937 3 27451 25937 27382 3 25935 25939 25940 3 25935 25940 25936 3 25936 25940 27452 3 25936 27452 27383 3 25937 25941 25942 3 25937 25942 25938 3 25937 27451 25941 3 27520 25941 27451 3 25939 25943 25944 3 25939 25944 25940 3 25940 25944 27521 3 25940 27521 27452 3 25941 25945 25946 3 25941 25946 25942 3 25941 27520 25945 3 27589 25945 27520 3 25943 25947 25948 3 25943 25948 25944 3 25944 25948 27590 3 25944 27590 27521 3 25945 25949 25950 3 25945 25950 25946 3 25945 27589 27658 3 25945 27658 25949 3 25947 25951 25952 3 25947 25952 25948 3 25948 25952 27659 3 25948 27659 27590 3 25949 25953 25954 3 25949 25954 25950 3 25949 27658 27727 3 25949 27727 25953 3 25951 25955 25956 3 25951 25956 25952 3 25952 25956 27728 3 25952 27728 27659 3 25953 25957 25958 3 25953 25958 25954 3 25953 27727 25957 3 27796 25957 27727 3 25955 25959 25960 3 25955 25960 25956 3 25956 25960 27728 3 27797 27728 25960 3 25957 25961 25958 3 25962 25958 25961 3 25957 27796 25961 3 27865 25961 27796 3 25959 25963 25960 3 25964 25960 25963 3 25960 25964 27797 3 27866 27797 25964 3 25961 25965 25962 3 25966 25962 25965 3 25961 27865 25965 3 27934 25965 27865 3 25963 25967 25964 3 25968 25964 25967 3 25964 25968 27866 3 27935 27866 25968 3 25965 25969 25966 3 25970 25966 25969 3 25965 27934 28003 3 25965 28003 25969 3 25967 25971 25968 3 25972 25968 25971 3 25968 25972 27935 3 28004 27935 25972 3 25969 25973 25970 3 25974 25970 25973 3 25969 28003 28072 3 25969 28072 25973 3 25971 25975 25972 3 25976 25972 25975 3 25972 25976 28004 3 28073 28004 25976 3 25973 25977 25974 3 25978 25974 25977 3 25973 28072 25977 3 28141 25977 28072 3 25975 25979 25976 3 25980 25976 25979 3 25976 25980 28073 3 28142 28073 25980 3 25977 25981 25978 3 25982 25978 25981 3 25977 28141 25981 3 28210 25981 28141 3 25979 25983 25980 3 25984 25980 25983 3 25980 25984 28142 3 28211 28142 25984 3 25981 25985 25982 3 25986 25982 25985 3 25981 28210 25985 3 28279 25985 28210 3 25983 25987 25984 3 25988 25984 25987 3 25984 25988 28211 3 28280 28211 25988 3 25985 25989 25986 3 25990 25986 25989 3 25985 28279 28348 3 25985 28348 25989 3 25987 25991 25988 3 25992 25988 25991 3 25988 25992 28280 3 28349 28280 25992 3 25989 25993 25990 3 25994 25990 25993 3 25989 28348 28417 3 25989 28417 25993 3 25991 25995 25992 3 25996 25992 25995 3 25992 25996 28349 3 28418 28349 25996 3 25993 25997 25994 3 25998 25994 25997 3 25993 28417 25997 3 28486 25997 28417 3 25995 25999 25996 3 26000 25996 25999 3 25996 26000 28418 3 28487 28418 26000 3 25997 26001 25998 3 26002 25998 26001 3 25997 28486 26001 3 28555 26001 28486 3 25999 26003 26000 3 26004 26000 26003 3 26000 26004 28487 3 28556 28487 26004 3 26001 26005 26002 3 26006 26002 26005 3 26001 28555 26005 3 28624 26005 28555 3 26003 26007 26004 3 26008 26004 26007 3 26004 26008 28556 3 28625 28556 26008 3 26005 26009 26006 3 26010 26006 26009 3 26005 28624 28693 3 26005 28693 26009 3 26007 26011 26008 3 26012 26008 26011 3 26008 26012 28625 3 28694 28625 26012 3 26009 26013 26010 3 26014 26010 26013 3 26009 28693 28762 3 26009 28762 26013 3 26011 26015 26012 3 26016 26012 26015 3 26012 26016 28694 3 28763 28694 26016 3 26013 26017 26014 3 26018 26014 26017 3 26013 28762 26017 3 28831 26017 28762 3 26015 26019 26016 3 26020 26016 26019 3 26016 26020 28763 3 28832 28763 26020 3 26017 26021 26018 3 26022 26018 26021 3 26017 28831 26021 3 28900 26021 28831 3 26019 26023 26020 3 26024 26020 26023 3 26020 26024 28832 3 28901 28832 26024 3 26021 26025 26022 3 26026 26022 26025 3 26021 28900 26025 3 28969 26025 28900 3 26023 26027 26024 3 26028 26024 26027 3 26024 26028 28901 3 28970 28901 26028 3 26025 26029 26026 3 26030 26026 26029 3 26025 28969 29038 3 26025 29038 26029 3 26027 26031 26028 3 26032 26028 26031 3 26028 26032 28970 3 29039 28970 26032 3 26029 26033 26030 3 26034 26030 26033 3 26029 29038 29107 3 26029 29107 26033 3 26031 26035 26032 3 26036 26032 26035 3 26032 26036 29039 3 29108 29039 26036 3 26033 26037 26034 3 26038 26034 26037 3 26033 29107 26037 3 29176 26037 29107 3 26035 26039 26036 3 26040 26036 26039 3 26036 26040 29108 3 29177 29108 26040 3 26037 26041 26038 3 26042 26038 26041 3 26037 29176 26041 3 29245 26041 29176 3 26039 26043 26040 3 26044 26040 26043 3 26040 26044 29177 3 29246 29177 26044 3 26041 26045 26042 3 26046 26042 26045 3 26041 29245 26045 3 29314 26045 29245 3 26043 26047 26044 3 26048 26044 26047 3 26044 26048 29246 3 29315 29246 26048 3 26045 26049 26046 3 26050 26046 26049 3 26045 29314 29383 3 26045 29383 26049 3 26047 26051 26048 3 26052 26048 26051 3 26048 26052 29315 3 29384 29315 26052 3 26049 26053 26050 3 26054 26050 26053 3 26049 29383 29452 3 26049 29452 26053 3 26051 26055 26052 3 26056 26052 26055 3 26052 26056 29384 3 29453 29384 26056 3 26053 26057 26054 3 26058 26054 26057 3 26053 29452 26057 3 29521 26057 29452 3 26055 26059 26060 3 26055 26060 26056 3 26056 26060 29522 3 26056 29522 29453 3 26057 26061 26062 3 26057 26062 26058 3 26057 29521 26061 3 29590 26061 29521 3 26059 26063 26064 3 26059 26064 26060 3 26060 26064 29591 3 26060 29591 29522 3 26061 26065 26066 3 26061 26066 26062 3 26061 29590 26065 3 29659 26065 29590 3 26063 26067 26068 3 26063 26068 26064 3 26064 26068 29660 3 26064 29660 29591 3 26065 26069 26070 3 26065 26070 26066 3 26065 29659 29728 3 26065 29728 26069 3 26067 26071 26072 3 26067 26072 26068 3 26068 26072 29729 3 26068 29729 29660 3 26069 26073 26074 3 26069 26074 26070 3 26069 29728 29797 3 26069 29797 26073 3 26071 26075 26076 3 26071 26076 26072 3 26072 26076 29798 3 26072 29798 29729 3 26073 26077 26078 3 26073 26078 26074 3 26073 29797 26077 3 29866 26077 29797 3 26075 26079 26080 3 26075 26080 26076 3 26076 26080 29867 3 26076 29867 29798 3 26077 26081 26082 3 26077 26082 26078 3 26077 29866 26081 3 29935 26081 29866 3 26079 26083 26084 3 26079 26084 26080 3 26080 26084 29936 3 26080 29936 29867 3 26081 26085 26086 3 26081 26086 26082 3 26081 29935 26085 3 30004 26085 29935 3 26083 26087 26088 3 26083 26088 26084 3 26084 26088 30005 3 26084 30005 29936 3 26085 26089 26090 3 26085 26090 26086 3 26085 30004 30073 3 26085 30073 26089 3 26087 26091 26092 3 26087 26092 26088 3 26088 26092 30074 3 26088 30074 30005 3 26089 26093 26094 3 26089 26094 26090 3 26089 30073 30142 3 26089 30142 26093 3 26091 26095 26096 3 26091 26096 26092 3 26092 26096 30143 3 26092 30143 30074 3 26093 26097 26098 3 26093 26098 26094 3 26093 30142 30211 3 26093 30211 26097 3 26095 26099 26100 3 26095 26100 26096 3 26096 26100 30212 3 26096 30212 30143 3 26097 26101 26102 3 26097 26102 26098 3 26097 30211 26101 3 30280 26101 30211 3 26099 26103 26104 3 26099 26104 26100 3 26100 26104 30281 3 26100 30281 30212 3 26101 26105 26106 3 26101 26106 26102 3 26101 30280 26105 3 30349 26105 30280 3 26103 26107 26108 3 26103 26108 26104 3 26104 26108 30350 3 26104 30350 30281 3 26105 26109 26110 3 26105 26110 26106 3 26105 30349 30418 3 26105 30418 26109 3 26107 26111 26112 3 26107 26112 26108 3 26108 26112 30419 3 26108 30419 30350 3 26109 26113 26114 3 26109 26114 26110 3 26109 30418 30487 3 26109 30487 26113 3 26111 26115 26116 3 26111 26116 26112 3 26112 26116 30488 3 26112 30488 30419 3 26113 26117 26118 3 26113 26118 26114 3 26113 30487 30556 3 26113 30556 26117 3 26115 26119 26120 3 26115 26120 26116 3 26116 26120 30557 3 26116 30557 30488 3 26117 26121 26122 3 26117 26122 26118 3 26117 30556 26121 3 30625 26121 30556 3 26119 26123 26124 3 26119 26124 26120 3 26120 26124 30626 3 26120 30626 30557 3 26121 26125 26126 3 26121 26126 26122 3 26121 30625 26125 3 30694 26125 30625 3 26123 26127 26128 3 26123 26128 26124 3 26124 26128 30695 3 26124 30695 30626 3 26125 26129 26130 3 26125 26130 26126 3 26125 30694 30763 3 26125 30763 26129 3 26127 26131 26132 3 26127 26132 26128 3 26128 26132 30764 3 26128 30764 30695 3 26129 26133 26134 3 26129 26134 26130 3 26129 30763 30832 3 26129 30832 26133 3 26131 26135 26136 3 26131 26136 26132 3 26132 26136 30833 3 26132 30833 30764 3 26133 26139 26140 3 26133 26140 26134 3 26133 30832 30901 3 26133 30901 26139 3 26135 26141 26142 3 26135 26142 26136 3 26136 26142 26143 3 26136 26143 26137 3 26136 26137 30834 3 26136 30834 30833 3 26137 26143 30902 3 26137 30902 30834 3 26138 26146 26147 3 26138 26147 26139 3 26138 26139 30901 3 26138 30901 30900 3 26138 30900 26146 3 30968 26146 30900 3 26139 26147 26148 3 26139 26148 26140 3 26142 26149 26150 3 26142 26150 26143 3 26143 26150 26151 3 26143 26151 26144 3 26143 26144 30903 3 26143 30903 30902 3 26144 26151 30969 3 26144 30969 30903 3 26145 26215 26146 3 26216 26146 26215 3 26145 26146 30968 3 26145 30968 30967 3 26145 30967 26215 3 31033 26215 30967 3 26146 26216 26147 3 26217 26147 26216 3 26150 26218 26151 3 26219 26151 26218 3 26151 26219 26152 3 26220 26152 26219 3 26151 26152 30970 3 26151 30970 30969 3 26152 26220 26153 3 26221 26153 26220 3 26152 26153 30971 3 26152 30971 30970 3 26153 26221 26154 3 26222 26154 26221 3 26153 26154 30972 3 26153 30972 30971 3 26154 26222 26155 3 26223 26155 26222 3 26154 26155 30973 3 26154 30973 30972 3 26155 26223 26156 3 26224 26156 26223 3 26155 26156 30974 3 26155 30974 30973 3 26156 26224 26157 3 26225 26157 26224 3 26156 26157 30975 3 26156 30975 30974 3 26157 26225 26158 3 26226 26158 26225 3 26157 26158 30975 3 30976 30975 26158 3 26158 26226 26159 3 26227 26159 26226 3 26158 26159 30976 3 30977 30976 26159 3 26159 26227 26160 3 26228 26160 26227 3 26159 26160 30977 3 30978 30977 26160 3 26160 26228 26161 3 26229 26161 26228 3 26160 26161 30978 3 30979 30978 26161 3 26161 26229 26162 3 26230 26162 26229 3 26161 26162 30979 3 30980 30979 26162 3 26162 26230 26163 3 26231 26163 26230 3 26162 26163 30980 3 30981 30980 26163 3 26163 26231 26164 3 26232 26164 26231 3 26163 26164 30981 3 30982 30981 26164 3 26164 26232 26165 3 26233 26165 26232 3 26164 26165 30982 3 30983 30982 26165 3 26165 26233 26166 3 26234 26166 26233 3 26165 26166 30983 3 30984 30983 26166 3 26166 26234 26167 3 26235 26167 26234 3 26166 26167 30984 3 30985 30984 26167 3 26167 26235 26168 3 26236 26168 26235 3 26167 26168 30985 3 30986 30985 26168 3 26168 26236 26169 3 26237 26169 26236 3 26168 26169 30986 3 30987 30986 26169 3 26169 26237 26170 3 26238 26170 26237 3 26169 26170 30987 3 30988 30987 26170 3 26170 26238 26171 3 26239 26171 26238 3 26170 26171 30988 3 30989 30988 26171 3 26171 26239 26172 3 26240 26172 26239 3 26171 26172 30989 3 30990 30989 26172 3 26172 26240 26173 3 26241 26173 26240 3 26172 26173 30990 3 30991 30990 26173 3 26173 26241 26174 3 26242 26174 26241 3 26173 26174 30991 3 30992 30991 26174 3 26174 26242 26175 3 26243 26175 26242 3 26174 26175 30992 3 30993 30992 26175 3 26175 26243 26176 3 26244 26176 26243 3 26175 26176 30993 3 30994 30993 26176 3 26176 26244 26177 3 26245 26177 26244 3 26176 26177 30994 3 30995 30994 26177 3 26177 26245 26178 3 26246 26178 26245 3 26177 26178 30995 3 30996 30995 26178 3 26178 26246 26179 3 26247 26179 26246 3 26178 26179 30996 3 30997 30996 26179 3 26179 26247 26180 3 26248 26180 26247 3 26179 26180 30997 3 30998 30997 26180 3 26180 26248 26181 3 26249 26181 26248 3 26180 26181 30998 3 30999 30998 26181 3 26181 26249 26182 3 26250 26182 26249 3 26181 26182 30999 3 31000 30999 26182 3 26182 26250 26183 3 26251 26183 26250 3 26182 26183 31000 3 31001 31000 26183 3 26183 26251 26184 3 26252 26184 26251 3 26183 26184 31001 3 31002 31001 26184 3 26184 26252 26185 3 26253 26185 26252 3 26184 26185 31002 3 31003 31002 26185 3 26185 26253 26186 3 26254 26186 26253 3 26185 26186 31003 3 31004 31003 26186 3 26186 26254 26187 3 26255 26187 26254 3 26186 26187 31004 3 31005 31004 26187 3 26187 26255 26188 3 26256 26188 26255 3 26187 26188 31005 3 31006 31005 26188 3 26188 26256 26189 3 26257 26189 26256 3 26188 26189 31006 3 31007 31006 26189 3 26189 26257 26190 3 26258 26190 26257 3 26189 26190 31007 3 31008 31007 26190 3 26190 26258 26191 3 26259 26191 26258 3 26190 26191 31008 3 31009 31008 26191 3 26191 26259 26192 3 26260 26192 26259 3 26191 26192 31009 3 31010 31009 26192 3 26192 26260 26193 3 26261 26193 26260 3 26192 26193 31010 3 31011 31010 26193 3 26193 26261 26194 3 26262 26194 26261 3 26193 26194 31011 3 31012 31011 26194 3 26194 26262 26195 3 26263 26195 26262 3 26194 26195 31012 3 31013 31012 26195 3 26195 26263 26196 3 26264 26196 26263 3 26195 26196 31013 3 31014 31013 26196 3 26196 26264 26197 3 26265 26197 26264 3 26196 26197 31014 3 31015 31014 26197 3 26197 26265 26198 3 26266 26198 26265 3 26197 26198 31015 3 31016 31015 26198 3 26198 26266 26199 3 26267 26199 26266 3 26198 26199 31016 3 31017 31016 26199 3 26199 26267 26200 3 26268 26200 26267 3 26199 26200 31017 3 31018 31017 26200 3 26200 26268 26201 3 26269 26201 26268 3 26200 26201 31018 3 31019 31018 26201 3 26201 26269 26202 3 26270 26202 26269 3 26201 26202 31019 3 31020 31019 26202 3 26202 26270 26203 3 26271 26203 26270 3 26202 26203 31020 3 31021 31020 26203 3 26203 26271 26204 3 26272 26204 26271 3 26203 26204 31021 3 31022 31021 26204 3 26204 26272 26205 3 26273 26205 26272 3 26204 26205 31022 3 31023 31022 26205 3 26205 26273 26206 3 26274 26206 26273 3 26205 26206 31023 3 31024 31023 26206 3 26206 26274 26207 3 26275 26207 26274 3 26206 26207 31024 3 31025 31024 26207 3 26207 26275 26208 3 26276 26208 26275 3 26207 26208 31025 3 31026 31025 26208 3 26208 26276 26209 3 26277 26209 26276 3 26208 26209 31026 3 31027 31026 26209 3 26209 26277 26210 3 26278 26210 26277 3 26209 26210 31027 3 31028 31027 26210 3 26210 26278 26211 3 26279 26211 26278 3 26210 26211 31028 3 31029 31028 26211 3 26211 26279 26212 3 26280 26212 26279 3 26211 26212 31029 3 31030 31029 26212 3 26212 26280 26213 3 26281 26213 26280 3 26212 26213 31030 3 31031 31030 26213 3 26213 26281 26214 3 26282 26214 26281 3 26213 26214 31031 3 31032 31031 26214 3 26214 26282 26215 3 26283 26215 26282 3 26214 26215 31032 3 31033 31032 26215 3 26215 26283 26216 3 26284 26216 26283 3 26285 26351 26352 3 26285 26352 26286 3 26286 26352 26353 3 26286 26353 26287 3 26287 26353 26354 3 26287 26354 26288 3 26288 26354 26355 3 26288 26355 26289 3 26289 26355 26356 3 26289 26356 26290 3 26290 26356 26357 3 26290 26357 26291 3 26291 26357 26358 3 26291 26358 26292 3 26292 26358 26359 3 26292 26359 26293 3 26293 26359 26360 3 26293 26360 26294 3 26294 26360 26361 3 26294 26361 26295 3 26295 26361 26362 3 26295 26362 26296 3 26296 26362 26363 3 26296 26363 26297 3 26297 26363 26364 3 26297 26364 26298 3 26298 26364 26365 3 26298 26365 26299 3 26299 26365 26366 3 26299 26366 26300 3 26300 26366 26367 3 26300 26367 26301 3 26301 26367 26368 3 26301 26368 26302 3 26302 26368 26369 3 26302 26369 26303 3 26303 26369 26370 3 26303 26370 26304 3 26304 26370 26371 3 26304 26371 26305 3 26305 26371 26372 3 26305 26372 26306 3 26306 26372 26373 3 26306 26373 26307 3 26307 26373 26374 3 26307 26374 26308 3 26308 26374 26375 3 26308 26375 26309 3 26309 26375 26376 3 26309 26376 26310 3 26310 26376 26377 3 26310 26377 26311 3 26311 26377 26378 3 26311 26378 26312 3 26312 26378 26379 3 26312 26379 26313 3 26313 26379 26380 3 26313 26380 26314 3 26314 26380 26381 3 26314 26381 26315 3 26315 26381 26382 3 26315 26382 26316 3 26316 26382 26383 3 26316 26383 26317 3 26317 26383 26384 3 26317 26384 26318 3 26318 26384 26385 3 26318 26385 26319 3 26319 26385 26320 3 26386 26320 26385 3 26320 26386 26321 3 26387 26321 26386 3 26321 26387 26322 3 26388 26322 26387 3 26322 26388 26323 3 26389 26323 26388 3 26323 26389 26324 3 26390 26324 26389 3 26324 26390 26325 3 26391 26325 26390 3 26325 26391 26326 3 26392 26326 26391 3 26326 26392 26327 3 26393 26327 26392 3 26327 26393 26328 3 26394 26328 26393 3 26328 26394 26329 3 26395 26329 26394 3 26329 26395 26330 3 26396 26330 26395 3 26330 26396 26331 3 26397 26331 26396 3 26331 26397 26332 3 26398 26332 26397 3 26332 26398 26333 3 26399 26333 26398 3 26333 26399 26334 3 26400 26334 26399 3 26334 26400 26335 3 26401 26335 26400 3 26335 26401 26336 3 26402 26336 26401 3 26336 26402 26337 3 26403 26337 26402 3 26337 26403 26338 3 26404 26338 26403 3 26338 26404 26339 3 26405 26339 26404 3 26339 26405 26340 3 26406 26340 26405 3 26340 26406 26341 3 26407 26341 26406 3 26341 26407 26342 3 26408 26342 26407 3 26342 26408 26343 3 26409 26343 26408 3 26343 26409 26344 3 26410 26344 26409 3 26344 26410 26345 3 26411 26345 26410 3 26345 26411 26346 3 26412 26346 26411 3 26346 26412 26347 3 26413 26347 26412 3 26347 26413 26348 3 26414 26348 26413 3 26348 26414 26349 3 26415 26349 26414 3 26350 26418 26351 3 26419 26351 26418 3 26351 26419 26352 3 26420 26352 26419 3 26352 26420 26353 3 26421 26353 26420 3 26353 26421 26354 3 26422 26354 26421 3 26354 26422 26355 3 26423 26355 26422 3 26355 26423 26356 3 26424 26356 26423 3 26356 26424 26357 3 26425 26357 26424 3 26357 26425 26358 3 26426 26358 26425 3 26358 26426 26359 3 26427 26359 26426 3 26359 26427 26360 3 26428 26360 26427 3 26360 26428 26361 3 26429 26361 26428 3 26361 26429 26362 3 26430 26362 26429 3 26362 26430 26363 3 26431 26363 26430 3 26363 26431 26364 3 26432 26364 26431 3 26364 26432 26365 3 26433 26365 26432 3 26365 26433 26366 3 26434 26366 26433 3 26366 26434 26367 3 26435 26367 26434 3 26367 26435 26368 3 26436 26368 26435 3 26368 26436 26369 3 26437 26369 26436 3 26369 26437 26370 3 26438 26370 26437 3 26370 26438 26371 3 26439 26371 26438 3 26371 26439 26372 3 26440 26372 26439 3 26372 26440 26373 3 26441 26373 26440 3 26373 26441 26374 3 26442 26374 26441 3 26374 26442 26375 3 26443 26375 26442 3 26375 26443 26376 3 26444 26376 26443 3 26376 26444 26377 3 26445 26377 26444 3 26377 26445 26378 3 26446 26378 26445 3 26378 26446 26379 3 26447 26379 26446 3 26379 26447 26380 3 26448 26380 26447 3 26380 26448 26381 3 26449 26381 26448 3 26381 26449 26382 3 26450 26382 26449 3 26382 26450 26383 3 26451 26383 26450 3 26383 26451 26384 3 26452 26384 26451 3 26384 26452 26385 3 26453 26385 26452 3 26385 26453 26386 3 26454 26386 26453 3 26386 26454 26387 3 26455 26387 26454 3 26387 26455 26388 3 26456 26388 26455 3 26388 26456 26389 3 26457 26389 26456 3 26389 26457 26390 3 26458 26390 26457 3 26390 26458 26391 3 26459 26391 26458 3 26391 26459 26392 3 26460 26392 26459 3 26392 26460 26393 3 26461 26393 26460 3 26393 26461 26394 3 26462 26394 26461 3 26394 26462 26395 3 26463 26395 26462 3 26395 26463 26396 3 26464 26396 26463 3 26396 26464 26397 3 26465 26397 26464 3 26397 26465 26398 3 26466 26398 26465 3 26398 26466 26399 3 26467 26399 26466 3 26399 26467 26400 3 26468 26400 26467 3 26400 26468 26401 3 26469 26401 26468 3 26401 26469 26402 3 26470 26402 26469 3 26402 26470 26403 3 26471 26403 26470 3 26403 26471 26404 3 26472 26404 26471 3 26404 26472 26405 3 26473 26405 26472 3 26405 26473 26406 3 26474 26406 26473 3 26406 26474 26407 3 26475 26407 26474 3 26407 26475 26408 3 26476 26408 26475 3 26408 26476 26409 3 26477 26409 26476 3 26409 26477 26410 3 26478 26410 26477 3 26410 26478 26411 3 26479 26411 26478 3 26411 26479 26412 3 26480 26412 26479 3 26412 26480 26413 3 26481 26413 26480 3 26413 26481 26414 3 26482 26414 26481 3 26414 26482 26415 3 26483 26415 26482 3 26415 26483 26416 3 26484 26416 26483 3 26417 26486 26487 3 26417 26487 26418 3 26418 26487 26488 3 26418 26488 26419 3 26419 26488 26489 3 26419 26489 26420 3 26420 26489 26490 3 26420 26490 26421 3 26421 26490 26491 3 26421 26491 26422 3 26422 26491 26492 3 26422 26492 26423 3 26423 26492 26493 3 26423 26493 26424 3 26424 26493 26494 3 26424 26494 26425 3 26425 26494 26495 3 26425 26495 26426 3 26426 26495 26496 3 26426 26496 26427 3 26427 26496 26497 3 26427 26497 26428 3 26428 26497 26498 3 26428 26498 26429 3 26429 26498 26499 3 26429 26499 26430 3 26430 26499 26500 3 26430 26500 26431 3 26431 26500 26501 3 26431 26501 26432 3 26432 26501 26502 3 26432 26502 26433 3 26433 26502 26503 3 26433 26503 26434 3 26434 26503 26504 3 26434 26504 26435 3 26435 26504 26505 3 26435 26505 26436 3 26436 26505 26506 3 26436 26506 26437 3 26437 26506 26507 3 26437 26507 26438 3 26438 26507 26508 3 26438 26508 26439 3 26439 26508 26509 3 26439 26509 26440 3 26440 26509 26510 3 26440 26510 26441 3 26441 26510 26511 3 26441 26511 26442 3 26442 26511 26512 3 26442 26512 26443 3 26443 26512 26513 3 26443 26513 26444 3 26444 26513 26514 3 26444 26514 26445 3 26445 26514 26515 3 26445 26515 26446 3 26446 26515 26516 3 26446 26516 26447 3 26447 26516 26517 3 26447 26517 26448 3 26448 26517 26518 3 26448 26518 26449 3 26449 26518 26519 3 26449 26519 26450 3 26450 26519 26520 3 26450 26520 26451 3 26451 26520 26521 3 26451 26521 26452 3 26452 26521 26522 3 26452 26522 26453 3 26453 26522 26523 3 26453 26523 26454 3 26454 26523 26524 3 26454 26524 26455 3 26455 26524 26525 3 26455 26525 26456 3 26456 26525 26526 3 26456 26526 26457 3 26457 26526 26527 3 26457 26527 26458 3 26458 26527 26528 3 26458 26528 26459 3 26459 26528 26529 3 26459 26529 26460 3 26460 26529 26530 3 26460 26530 26461 3 26461 26530 26531 3 26461 26531 26462 3 26462 26531 26532 3 26462 26532 26463 3 26463 26532 26533 3 26463 26533 26464 3 26464 26533 26534 3 26464 26534 26465 3 26465 26534 26535 3 26465 26535 26466 3 26466 26535 26536 3 26466 26536 26467 3 26467 26536 26537 3 26467 26537 26468 3 26468 26537 26538 3 26468 26538 26469 3 26469 26538 26539 3 26469 26539 26470 3 26470 26539 26540 3 26470 26540 26471 3 26471 26540 26541 3 26471 26541 26472 3 26472 26541 26542 3 26472 26542 26473 3 26473 26542 26543 3 26473 26543 26474 3 26474 26543 26544 3 26474 26544 26475 3 26475 26544 26545 3 26475 26545 26476 3 26476 26545 26546 3 26476 26546 26477 3 26477 26546 26547 3 26477 26547 26478 3 26478 26547 26548 3 26478 26548 26479 3 26479 26548 26549 3 26479 26549 26480 3 26480 26549 26550 3 26480 26550 26481 3 26481 26550 26551 3 26481 26551 26482 3 26482 26551 26552 3 26482 26552 26483 3 26483 26552 26553 3 26483 26553 26484 3 26484 26553 26554 3 26484 26554 26485 3 26486 26555 26556 3 26486 26556 26487 3 26487 26556 26557 3 26487 26557 26488 3 26488 26557 26558 3 26488 26558 26489 3 26489 26558 26559 3 26489 26559 26490 3 26490 26559 26560 3 26490 26560 26491 3 26491 26560 26561 3 26491 26561 26492 3 26492 26561 26562 3 26492 26562 26493 3 26493 26562 26563 3 26493 26563 26494 3 26494 26563 26564 3 26494 26564 26495 3 26495 26564 26565 3 26495 26565 26496 3 26496 26565 26566 3 26496 26566 26497 3 26497 26566 26567 3 26497 26567 26498 3 26498 26567 26568 3 26498 26568 26499 3 26499 26568 26569 3 26499 26569 26500 3 26500 26569 26570 3 26500 26570 26501 3 26501 26570 26571 3 26501 26571 26502 3 26502 26571 26572 3 26502 26572 26503 3 26503 26572 26573 3 26503 26573 26504 3 26504 26573 26574 3 26504 26574 26505 3 26505 26574 26575 3 26505 26575 26506 3 26506 26575 26576 3 26506 26576 26507 3 26507 26576 26577 3 26507 26577 26508 3 26508 26577 26578 3 26508 26578 26509 3 26509 26578 26579 3 26509 26579 26510 3 26510 26579 26580 3 26510 26580 26511 3 26511 26580 26581 3 26511 26581 26512 3 26512 26581 26582 3 26512 26582 26513 3 26513 26582 26583 3 26513 26583 26514 3 26514 26583 26584 3 26514 26584 26515 3 26515 26584 26585 3 26515 26585 26516 3 26516 26585 26586 3 26516 26586 26517 3 26517 26586 26518 3 26587 26518 26586 3 26518 26587 26519 3 26588 26519 26587 3 26519 26588 26520 3 26589 26520 26588 3 26520 26589 26521 3 26590 26521 26589 3 26521 26590 26522 3 26591 26522 26590 3 26522 26591 26523 3 26592 26523 26591 3 26523 26592 26524 3 26593 26524 26592 3 26524 26593 26525 3 26594 26525 26593 3 26525 26594 26526 3 26595 26526 26594 3 26526 26595 26527 3 26596 26527 26595 3 26527 26596 26528 3 26597 26528 26596 3 26528 26597 26529 3 26598 26529 26597 3 26529 26598 26530 3 26599 26530 26598 3 26530 26599 26531 3 26600 26531 26599 3 26531 26600 26532 3 26601 26532 26600 3 26532 26601 26533 3 26602 26533 26601 3 26533 26602 26534 3 26603 26534 26602 3 26534 26603 26535 3 26604 26535 26603 3 26535 26604 26536 3 26605 26536 26604 3 26536 26605 26537 3 26606 26537 26605 3 26537 26606 26538 3 26607 26538 26606 3 26538 26607 26539 3 26608 26539 26607 3 26539 26608 26540 3 26609 26540 26608 3 26540 26609 26541 3 26610 26541 26609 3 26541 26610 26542 3 26611 26542 26610 3 26542 26611 26543 3 26612 26543 26611 3 26543 26612 26544 3 26613 26544 26612 3 26544 26613 26545 3 26614 26545 26613 3 26545 26614 26546 3 26615 26546 26614 3 26546 26615 26547 3 26616 26547 26615 3 26547 26616 26548 3 26617 26548 26616 3 26548 26617 26549 3 26618 26549 26617 3 26549 26618 26550 3 26619 26550 26618 3 26550 26619 26551 3 26620 26551 26619 3 26551 26620 26552 3 26621 26552 26620 3 26552 26621 26553 3 26622 26553 26621 3 26553 26622 26554 3 26623 26554 26622 3 26555 26624 26556 3 26625 26556 26624 3 26556 26625 26557 3 26626 26557 26625 3 26557 26626 26558 3 26627 26558 26626 3 26558 26627 26559 3 26628 26559 26627 3 26559 26628 26560 3 26629 26560 26628 3 26560 26629 26561 3 26630 26561 26629 3 26561 26630 26562 3 26631 26562 26630 3 26562 26631 26563 3 26632 26563 26631 3 26563 26632 26564 3 26633 26564 26632 3 26564 26633 26565 3 26634 26565 26633 3 26565 26634 26566 3 26635 26566 26634 3 26566 26635 26567 3 26636 26567 26635 3 26567 26636 26568 3 26637 26568 26636 3 26568 26637 26569 3 26638 26569 26637 3 26569 26638 26570 3 26639 26570 26638 3 26570 26639 26571 3 26640 26571 26639 3 26571 26640 26572 3 26641 26572 26640 3 26572 26641 26573 3 26642 26573 26641 3 26573 26642 26574 3 26643 26574 26642 3 26574 26643 26575 3 26644 26575 26643 3 26575 26644 26576 3 26645 26576 26644 3 26576 26645 26577 3 26646 26577 26645 3 26577 26646 26578 3 26647 26578 26646 3 26578 26647 26579 3 26648 26579 26647 3 26579 26648 26580 3 26649 26580 26648 3 26580 26649 26581 3 26650 26581 26649 3 26581 26650 26582 3 26651 26582 26650 3 26582 26651 26583 3 26652 26583 26651 3 26583 26652 26584 3 26653 26584 26652 3 26584 26653 26585 3 26654 26585 26653 3 26585 26654 26586 3 26655 26586 26654 3 26586 26655 26587 3 26656 26587 26655 3 26587 26656 26588 3 26657 26588 26656 3 26588 26657 26589 3 26658 26589 26657 3 26589 26658 26590 3 26659 26590 26658 3 26590 26659 26591 3 26660 26591 26659 3 26591 26660 26592 3 26661 26592 26660 3 26592 26661 26593 3 26662 26593 26661 3 26593 26662 26594 3 26663 26594 26662 3 26594 26663 26595 3 26664 26595 26663 3 26595 26664 26596 3 26665 26596 26664 3 26596 26665 26597 3 26666 26597 26665 3 26597 26666 26598 3 26667 26598 26666 3 26598 26667 26599 3 26668 26599 26667 3 26599 26668 26600 3 26669 26600 26668 3 26600 26669 26601 3 26670 26601 26669 3 26601 26670 26602 3 26671 26602 26670 3 26602 26671 26603 3 26672 26603 26671 3 26603 26672 26604 3 26673 26604 26672 3 26604 26673 26605 3 26674 26605 26673 3 26605 26674 26606 3 26675 26606 26674 3 26606 26675 26607 3 26676 26607 26675 3 26607 26676 26608 3 26677 26608 26676 3 26608 26677 26609 3 26678 26609 26677 3 26609 26678 26610 3 26679 26610 26678 3 26610 26679 26611 3 26680 26611 26679 3 26611 26680 26612 3 26681 26612 26680 3 26612 26681 26613 3 26682 26613 26681 3 26613 26682 26614 3 26683 26614 26682 3 26614 26683 26615 3 26684 26615 26683 3 26615 26684 26616 3 26685 26616 26684 3 26616 26685 26617 3 26686 26617 26685 3 26617 26686 26618 3 26687 26618 26686 3 26618 26687 26688 3 26618 26688 26619 3 26619 26688 26689 3 26619 26689 26620 3 26620 26689 26690 3 26620 26690 26621 3 26621 26690 26691 3 26621 26691 26622 3 26622 26691 26692 3 26622 26692 26623 3 26624 26693 26694 3 26624 26694 26625 3 26625 26694 26695 3 26625 26695 26626 3 26626 26695 26696 3 26626 26696 26627 3 26627 26696 26697 3 26627 26697 26628 3 26628 26697 26698 3 26628 26698 26629 3 26629 26698 26699 3 26629 26699 26630 3 26630 26699 26700 3 26630 26700 26631 3 26631 26700 26701 3 26631 26701 26632 3 26632 26701 26702 3 26632 26702 26633 3 26633 26702 26703 3 26633 26703 26634 3 26634 26703 26704 3 26634 26704 26635 3 26635 26704 26705 3 26635 26705 26636 3 26636 26705 26706 3 26636 26706 26637 3 26637 26706 26707 3 26637 26707 26638 3 26638 26707 26708 3 26638 26708 26639 3 26639 26708 26709 3 26639 26709 26640 3 26640 26709 26710 3 26640 26710 26641 3 26641 26710 26711 3 26641 26711 26642 3 26642 26711 26712 3 26642 26712 26643 3 26643 26712 26713 3 26643 26713 26644 3 26644 26713 26714 3 26644 26714 26645 3 26645 26714 26715 3 26645 26715 26646 3 26646 26715 26716 3 26646 26716 26647 3 26647 26716 26717 3 26647 26717 26648 3 26648 26717 26718 3 26648 26718 26649 3 26649 26718 26719 3 26649 26719 26650 3 26650 26719 26720 3 26650 26720 26651 3 26651 26720 26721 3 26651 26721 26652 3 26652 26721 26722 3 26652 26722 26653 3 26653 26722 26723 3 26653 26723 26654 3 26654 26723 26724 3 26654 26724 26655 3 26655 26724 26725 3 26655 26725 26656 3 26656 26725 26726 3 26656 26726 26657 3 26657 26726 26727 3 26657 26727 26658 3 26658 26727 26728 3 26658 26728 26659 3 26659 26728 26729 3 26659 26729 26660 3 26660 26729 26730 3 26660 26730 26661 3 26661 26730 26731 3 26661 26731 26662 3 26662 26731 26732 3 26662 26732 26663 3 26663 26732 26733 3 26663 26733 26664 3 26664 26733 26734 3 26664 26734 26665 3 26665 26734 26735 3 26665 26735 26666 3 26666 26735 26736 3 26666 26736 26667 3 26667 26736 26737 3 26667 26737 26668 3 26668 26737 26738 3 26668 26738 26669 3 26669 26738 26739 3 26669 26739 26670 3 26670 26739 26740 3 26670 26740 26671 3 26671 26740 26741 3 26671 26741 26672 3 26672 26741 26742 3 26672 26742 26673 3 26673 26742 26743 3 26673 26743 26674 3 26674 26743 26744 3 26674 26744 26675 3 26675 26744 26745 3 26675 26745 26676 3 26676 26745 26746 3 26676 26746 26677 3 26677 26746 26747 3 26677 26747 26678 3 26678 26747 26748 3 26678 26748 26679 3 26679 26748 26749 3 26679 26749 26680 3 26680 26749 26750 3 26680 26750 26681 3 26681 26750 26751 3 26681 26751 26682 3 26682 26751 26752 3 26682 26752 26683 3 26683 26752 26753 3 26683 26753 26684 3 26684 26753 26754 3 26684 26754 26685 3 26685 26754 26755 3 26685 26755 26686 3 26686 26755 26756 3 26686 26756 26687 3 26687 26756 26757 3 26687 26757 26688 3 26688 26757 26758 3 26688 26758 26689 3 26689 26758 26759 3 26689 26759 26690 3 26690 26759 26760 3 26690 26760 26691 3 26691 26760 26761 3 26691 26761 26692 3 26693 26762 26763 3 26693 26763 26694 3 26694 26763 26764 3 26694 26764 26695 3 26695 26764 26765 3 26695 26765 26696 3 26696 26765 26766 3 26696 26766 26697 3 26697 26766 26767 3 26697 26767 26698 3 26698 26767 26768 3 26698 26768 26699 3 26699 26768 26769 3 26699 26769 26700 3 26700 26769 26770 3 26700 26770 26701 3 26701 26770 26771 3 26701 26771 26702 3 26702 26771 26772 3 26702 26772 26703 3 26703 26772 26773 3 26703 26773 26704 3 26704 26773 26774 3 26704 26774 26705 3 26705 26774 26775 3 26705 26775 26706 3 26706 26775 26776 3 26706 26776 26707 3 26707 26776 26777 3 26707 26777 26708 3 26708 26777 26778 3 26708 26778 26709 3 26709 26778 26779 3 26709 26779 26710 3 26710 26779 26780 3 26710 26780 26711 3 26711 26780 26781 3 26711 26781 26712 3 26712 26781 26782 3 26712 26782 26713 3 26713 26782 26783 3 26713 26783 26714 3 26714 26783 26784 3 26714 26784 26715 3 26715 26784 26785 3 26715 26785 26716 3 26716 26785 26786 3 26716 26786 26717 3 26717 26786 26787 3 26717 26787 26718 3 26718 26787 26719 3 26788 26719 26787 3 26719 26788 26720 3 26789 26720 26788 3 26720 26789 26721 3 26790 26721 26789 3 26721 26790 26722 3 26791 26722 26790 3 26722 26791 26723 3 26792 26723 26791 3 26723 26792 26724 3 26793 26724 26792 3 26724 26793 26725 3 26794 26725 26793 3 26725 26794 26726 3 26795 26726 26794 3 26726 26795 26727 3 26796 26727 26795 3 26727 26796 26728 3 26797 26728 26796 3 26728 26797 26729 3 26798 26729 26797 3 26729 26798 26730 3 26799 26730 26798 3 26730 26799 26731 3 26800 26731 26799 3 26731 26800 26732 3 26801 26732 26800 3 26732 26801 26733 3 26802 26733 26801 3 26733 26802 26734 3 26803 26734 26802 3 26734 26803 26735 3 26804 26735 26803 3 26735 26804 26736 3 26805 26736 26804 3 26736 26805 26737 3 26806 26737 26805 3 26737 26806 26738 3 26807 26738 26806 3 26738 26807 26739 3 26808 26739 26807 3 26739 26808 26740 3 26809 26740 26808 3 26740 26809 26741 3 26810 26741 26809 3 26741 26810 26742 3 26811 26742 26810 3 26742 26811 26743 3 26812 26743 26811 3 26743 26812 26744 3 26813 26744 26812 3 26744 26813 26745 3 26814 26745 26813 3 26745 26814 26746 3 26815 26746 26814 3 26746 26815 26747 3 26816 26747 26815 3 26747 26816 26748 3 26817 26748 26816 3 26748 26817 26749 3 26818 26749 26817 3 26749 26818 26750 3 26819 26750 26818 3 26750 26819 26751 3 26820 26751 26819 3 26751 26820 26752 3 26821 26752 26820 3 26752 26821 26753 3 26822 26753 26821 3 26753 26822 26754 3 26823 26754 26822 3 26754 26823 26755 3 26824 26755 26823 3 26755 26824 26756 3 26825 26756 26824 3 26756 26825 26757 3 26826 26757 26825 3 26757 26826 26758 3 26827 26758 26826 3 26758 26827 26759 3 26828 26759 26827 3 26759 26828 26760 3 26829 26760 26828 3 26760 26829 26761 3 26830 26761 26829 3 26762 26831 26763 3 26832 26763 26831 3 26763 26832 26764 3 26833 26764 26832 3 26764 26833 26765 3 26834 26765 26833 3 26765 26834 26766 3 26835 26766 26834 3 26766 26835 26767 3 26836 26767 26835 3 26767 26836 26768 3 26837 26768 26836 3 26768 26837 26769 3 26838 26769 26837 3 26769 26838 26770 3 26839 26770 26838 3 26770 26839 26771 3 26840 26771 26839 3 26771 26840 26772 3 26841 26772 26840 3 26772 26841 26773 3 26842 26773 26841 3 26773 26842 26774 3 26843 26774 26842 3 26774 26843 26775 3 26844 26775 26843 3 26775 26844 26776 3 26845 26776 26844 3 26776 26845 26777 3 26846 26777 26845 3 26777 26846 26778 3 26847 26778 26846 3 26778 26847 26779 3 26848 26779 26847 3 26779 26848 26780 3 26849 26780 26848 3 26780 26849 26781 3 26850 26781 26849 3 26781 26850 26782 3 26851 26782 26850 3 26782 26851 26783 3 26852 26783 26851 3 26783 26852 26784 3 26853 26784 26852 3 26784 26853 26785 3 26854 26785 26853 3 26785 26854 26786 3 26855 26786 26854 3 26786 26855 26787 3 26856 26787 26855 3 26787 26856 26788 3 26857 26788 26856 3 26788 26857 26789 3 26858 26789 26857 3 26789 26858 26790 3 26859 26790 26858 3 26790 26859 26791 3 26860 26791 26859 3 26791 26860 26792 3 26861 26792 26860 3 26792 26861 26793 3 26862 26793 26861 3 26793 26862 26794 3 26863 26794 26862 3 26794 26863 26795 3 26864 26795 26863 3 26795 26864 26796 3 26865 26796 26864 3 26796 26865 26797 3 26866 26797 26865 3 26797 26866 26798 3 26867 26798 26866 3 26798 26867 26799 3 26868 26799 26867 3 26799 26868 26800 3 26869 26800 26868 3 26800 26869 26801 3 26870 26801 26869 3 26801 26870 26802 3 26871 26802 26870 3 26802 26871 26803 3 26872 26803 26871 3 26803 26872 26804 3 26873 26804 26872 3 26804 26873 26805 3 26874 26805 26873 3 26805 26874 26806 3 26875 26806 26874 3 26806 26875 26807 3 26876 26807 26875 3 26807 26876 26808 3 26877 26808 26876 3 26808 26877 26809 3 26878 26809 26877 3 26809 26878 26810 3 26879 26810 26878 3 26810 26879 26811 3 26880 26811 26879 3 26811 26880 26812 3 26881 26812 26880 3 26812 26881 26813 3 26882 26813 26881 3 26813 26882 26814 3 26883 26814 26882 3 26814 26883 26815 3 26884 26815 26883 3 26815 26884 26816 3 26885 26816 26884 3 26816 26885 26817 3 26886 26817 26885 3 26817 26886 26818 3 26887 26818 26886 3 26818 26887 26819 3 26888 26819 26887 3 26819 26888 26889 3 26819 26889 26820 3 26820 26889 26890 3 26820 26890 26821 3 26821 26890 26891 3 26821 26891 26822 3 26822 26891 26892 3 26822 26892 26823 3 26823 26892 26893 3 26823 26893 26824 3 26824 26893 26894 3 26824 26894 26825 3 26825 26894 26895 3 26825 26895 26826 3 26826 26895 26896 3 26826 26896 26827 3 26827 26896 26897 3 26827 26897 26828 3 26828 26897 26898 3 26828 26898 26829 3 26829 26898 26899 3 26829 26899 26830 3 26831 26900 26901 3 26831 26901 26832 3 26832 26901 26902 3 26832 26902 26833 3 26833 26902 26903 3 26833 26903 26834 3 26834 26903 26904 3 26834 26904 26835 3 26835 26904 26905 3 26835 26905 26836 3 26836 26905 26906 3 26836 26906 26837 3 26837 26906 26907 3 26837 26907 26838 3 26838 26907 26908 3 26838 26908 26839 3 26839 26908 26909 3 26839 26909 26840 3 26840 26909 26910 3 26840 26910 26841 3 26841 26910 26911 3 26841 26911 26842 3 26842 26911 26912 3 26842 26912 26843 3 26843 26912 26913 3 26843 26913 26844 3 26844 26913 26914 3 26844 26914 26845 3 26845 26914 26915 3 26845 26915 26846 3 26846 26915 26916 3 26846 26916 26847 3 26847 26916 26917 3 26847 26917 26848 3 26848 26917 26918 3 26848 26918 26849 3 26849 26918 26919 3 26849 26919 26850 3 26850 26919 26920 3 26850 26920 26851 3 26851 26920 26921 3 26851 26921 26852 3 26852 26921 26922 3 26852 26922 26853 3 26853 26922 26923 3 26853 26923 26854 3 26854 26923 26924 3 26854 26924 26855 3 26855 26924 26925 3 26855 26925 26856 3 26856 26925 26926 3 26856 26926 26857 3 26857 26926 26927 3 26857 26927 26858 3 26858 26927 26928 3 26858 26928 26859 3 26859 26928 26929 3 26859 26929 26860 3 26860 26929 26930 3 26860 26930 26861 3 26861 26930 26931 3 26861 26931 26862 3 26862 26931 26932 3 26862 26932 26863 3 26863 26932 26933 3 26863 26933 26864 3 26864 26933 26934 3 26864 26934 26865 3 26865 26934 26935 3 26865 26935 26866 3 26866 26935 26936 3 26866 26936 26867 3 26867 26936 26937 3 26867 26937 26868 3 26868 26937 26938 3 26868 26938 26869 3 26869 26938 26939 3 26869 26939 26870 3 26870 26939 26940 3 26870 26940 26871 3 26871 26940 26941 3 26871 26941 26872 3 26872 26941 26942 3 26872 26942 26873 3 26873 26942 26943 3 26873 26943 26874 3 26874 26943 26944 3 26874 26944 26875 3 26875 26944 26945 3 26875 26945 26876 3 26876 26945 26946 3 26876 26946 26877 3 26877 26946 26947 3 26877 26947 26878 3 26878 26947 26948 3 26878 26948 26879 3 26879 26948 26949 3 26879 26949 26880 3 26880 26949 26950 3 26880 26950 26881 3 26881 26950 26951 3 26881 26951 26882 3 26882 26951 26952 3 26882 26952 26883 3 26883 26952 26953 3 26883 26953 26884 3 26884 26953 26954 3 26884 26954 26885 3 26885 26954 26955 3 26885 26955 26886 3 26886 26955 26956 3 26886 26956 26887 3 26887 26956 26957 3 26887 26957 26888 3 26888 26957 26958 3 26888 26958 26889 3 26889 26958 26959 3 26889 26959 26890 3 26890 26959 26960 3 26890 26960 26891 3 26891 26960 26961 3 26891 26961 26892 3 26892 26961 26962 3 26892 26962 26893 3 26893 26962 26963 3 26893 26963 26894 3 26894 26963 26964 3 26894 26964 26895 3 26895 26964 26965 3 26895 26965 26896 3 26896 26965 26966 3 26896 26966 26897 3 26897 26966 26967 3 26897 26967 26898 3 26898 26967 26968 3 26898 26968 26899 3 26900 26969 26970 3 26900 26970 26901 3 26901 26970 26971 3 26901 26971 26902 3 26902 26971 26972 3 26902 26972 26903 3 26903 26972 26973 3 26903 26973 26904 3 26904 26973 26974 3 26904 26974 26905 3 26905 26974 26975 3 26905 26975 26906 3 26906 26975 26976 3 26906 26976 26907 3 26907 26976 26977 3 26907 26977 26908 3 26908 26977 26978 3 26908 26978 26909 3 26909 26978 26979 3 26909 26979 26910 3 26910 26979 26980 3 26910 26980 26911 3 26911 26980 26981 3 26911 26981 26912 3 26912 26981 26982 3 26912 26982 26913 3 26913 26982 26983 3 26913 26983 26914 3 26914 26983 26984 3 26914 26984 26915 3 26915 26984 26985 3 26915 26985 26916 3 26916 26985 26986 3 26916 26986 26917 3 26917 26986 26987 3 26917 26987 26918 3 26918 26987 26988 3 26918 26988 26919 3 26919 26988 26989 3 26919 26989 26920 3 26920 26989 26921 3 26990 26921 26989 3 26921 26990 26922 3 26991 26922 26990 3 26922 26991 26923 3 26992 26923 26991 3 26923 26992 26924 3 26993 26924 26992 3 26924 26993 26925 3 26994 26925 26993 3 26925 26994 26926 3 26995 26926 26994 3 26926 26995 26927 3 26996 26927 26995 3 26927 26996 26928 3 26997 26928 26996 3 26928 26997 26929 3 26998 26929 26997 3 26929 26998 26930 3 26999 26930 26998 3 26930 26999 26931 3 27000 26931 26999 3 26931 27000 26932 3 27001 26932 27000 3 26932 27001 26933 3 27002 26933 27001 3 26933 27002 26934 3 27003 26934 27002 3 26934 27003 26935 3 27004 26935 27003 3 26935 27004 26936 3 27005 26936 27004 3 26936 27005 26937 3 27006 26937 27005 3 26937 27006 26938 3 27007 26938 27006 3 26938 27007 26939 3 27008 26939 27007 3 26939 27008 26940 3 27009 26940 27008 3 26940 27009 26941 3 27010 26941 27009 3 26941 27010 26942 3 27011 26942 27010 3 26942 27011 26943 3 27012 26943 27011 3 26943 27012 26944 3 27013 26944 27012 3 26944 27013 26945 3 27014 26945 27013 3 26945 27014 26946 3 27015 26946 27014 3 26946 27015 26947 3 27016 26947 27015 3 26947 27016 26948 3 27017 26948 27016 3 26948 27017 26949 3 27018 26949 27017 3 26949 27018 26950 3 27019 26950 27018 3 26950 27019 26951 3 27020 26951 27019 3 26951 27020 26952 3 27021 26952 27020 3 26952 27021 26953 3 27022 26953 27021 3 26953 27022 26954 3 27023 26954 27022 3 26954 27023 26955 3 27024 26955 27023 3 26955 27024 26956 3 27025 26956 27024 3 26956 27025 26957 3 27026 26957 27025 3 26957 27026 26958 3 27027 26958 27026 3 26958 27027 26959 3 27028 26959 27027 3 26959 27028 26960 3 27029 26960 27028 3 26960 27029 26961 3 27030 26961 27029 3 26961 27030 26962 3 27031 26962 27030 3 26962 27031 26963 3 27032 26963 27031 3 26963 27032 26964 3 27033 26964 27032 3 26964 27033 26965 3 27034 26965 27033 3 26965 27034 26966 3 27035 26966 27034 3 26966 27035 26967 3 27036 26967 27035 3 26967 27036 26968 3 27037 26968 27036 3 26969 27038 26970 3 27039 26970 27038 3 26970 27039 26971 3 27040 26971 27039 3 26971 27040 26972 3 27041 26972 27040 3 26972 27041 26973 3 27042 26973 27041 3 26973 27042 26974 3 27043 26974 27042 3 26974 27043 26975 3 27044 26975 27043 3 26975 27044 26976 3 27045 26976 27044 3 26976 27045 26977 3 27046 26977 27045 3 26977 27046 26978 3 27047 26978 27046 3 26978 27047 26979 3 27048 26979 27047 3 26979 27048 26980 3 27049 26980 27048 3 26980 27049 26981 3 27050 26981 27049 3 26981 27050 26982 3 27051 26982 27050 3 26982 27051 26983 3 27052 26983 27051 3 26983 27052 26984 3 27053 26984 27052 3 26984 27053 26985 3 27054 26985 27053 3 26985 27054 26986 3 27055 26986 27054 3 26986 27055 26987 3 27056 26987 27055 3 26987 27056 26988 3 27057 26988 27056 3 26988 27057 26989 3 27058 26989 27057 3 26989 27058 26990 3 27059 26990 27058 3 26990 27059 26991 3 27060 26991 27059 3 26991 27060 26992 3 27061 26992 27060 3 26992 27061 26993 3 27062 26993 27061 3 26993 27062 26994 3 27063 26994 27062 3 26994 27063 26995 3 27064 26995 27063 3 26995 27064 26996 3 27065 26996 27064 3 26996 27065 26997 3 27066 26997 27065 3 26997 27066 26998 3 27067 26998 27066 3 26998 27067 26999 3 27068 26999 27067 3 26999 27068 27000 3 27069 27000 27068 3 27000 27069 27001 3 27070 27001 27069 3 27001 27070 27002 3 27071 27002 27070 3 27002 27071 27003 3 27072 27003 27071 3 27003 27072 27004 3 27073 27004 27072 3 27004 27073 27005 3 27074 27005 27073 3 27005 27074 27006 3 27075 27006 27074 3 27006 27075 27007 3 27076 27007 27075 3 27007 27076 27008 3 27077 27008 27076 3 27008 27077 27009 3 27078 27009 27077 3 27009 27078 27010 3 27079 27010 27078 3 27010 27079 27011 3 27080 27011 27079 3 27011 27080 27012 3 27081 27012 27080 3 27012 27081 27013 3 27082 27013 27081 3 27013 27082 27014 3 27083 27014 27082 3 27014 27083 27015 3 27084 27015 27083 3 27015 27084 27016 3 27085 27016 27084 3 27016 27085 27017 3 27086 27017 27085 3 27017 27086 27018 3 27087 27018 27086 3 27018 27087 27019 3 27088 27019 27087 3 27019 27088 27020 3 27089 27020 27088 3 27020 27089 27021 3 27090 27021 27089 3 27021 27090 27091 3 27021 27091 27022 3 27022 27091 27092 3 27022 27092 27023 3 27023 27092 27093 3 27023 27093 27024 3 27024 27093 27094 3 27024 27094 27025 3 27025 27094 27095 3 27025 27095 27026 3 27026 27095 27096 3 27026 27096 27027 3 27027 27096 27097 3 27027 27097 27028 3 27028 27097 27098 3 27028 27098 27029 3 27029 27098 27099 3 27029 27099 27030 3 27030 27099 27100 3 27030 27100 27031 3 27031 27100 27101 3 27031 27101 27032 3 27032 27101 27102 3 27032 27102 27033 3 27033 27102 27103 3 27033 27103 27034 3 27034 27103 27104 3 27034 27104 27035 3 27035 27104 27105 3 27035 27105 27036 3 27036 27105 27106 3 27036 27106 27037 3 27038 27107 27108 3 27038 27108 27039 3 27039 27108 27109 3 27039 27109 27040 3 27040 27109 27110 3 27040 27110 27041 3 27041 27110 27111 3 27041 27111 27042 3 27042 27111 27112 3 27042 27112 27043 3 27043 27112 27113 3 27043 27113 27044 3 27044 27113 27114 3 27044 27114 27045 3 27045 27114 27115 3 27045 27115 27046 3 27046 27115 27116 3 27046 27116 27047 3 27047 27116 27117 3 27047 27117 27048 3 27048 27117 27118 3 27048 27118 27049 3 27049 27118 27119 3 27049 27119 27050 3 27050 27119 27120 3 27050 27120 27051 3 27051 27120 27121 3 27051 27121 27052 3 27052 27121 27122 3 27052 27122 27053 3 27053 27122 27123 3 27053 27123 27054 3 27054 27123 27124 3 27054 27124 27055 3 27055 27124 27125 3 27055 27125 27056 3 27056 27125 27126 3 27056 27126 27057 3 27057 27126 27127 3 27057 27127 27058 3 27058 27127 27128 3 27058 27128 27059 3 27059 27128 27129 3 27059 27129 27060 3 27060 27129 27130 3 27060 27130 27061 3 27061 27130 27131 3 27061 27131 27062 3 27062 27131 27132 3 27062 27132 27063 3 27063 27132 27133 3 27063 27133 27064 3 27064 27133 27134 3 27064 27134 27065 3 27065 27134 27135 3 27065 27135 27066 3 27066 27135 27136 3 27066 27136 27067 3 27067 27136 27137 3 27067 27137 27068 3 27068 27137 27138 3 27068 27138 27069 3 27069 27138 27139 3 27069 27139 27070 3 27070 27139 27140 3 27070 27140 27071 3 27071 27140 27141 3 27071 27141 27072 3 27072 27141 27142 3 27072 27142 27073 3 27073 27142 27143 3 27073 27143 27074 3 27074 27143 27144 3 27074 27144 27075 3 27075 27144 27145 3 27075 27145 27076 3 27076 27145 27146 3 27076 27146 27077 3 27077 27146 27147 3 27077 27147 27078 3 27078 27147 27148 3 27078 27148 27079 3 27079 27148 27149 3 27079 27149 27080 3 27080 27149 27150 3 27080 27150 27081 3 27081 27150 27151 3 27081 27151 27082 3 27082 27151 27152 3 27082 27152 27083 3 27083 27152 27153 3 27083 27153 27084 3 27084 27153 27154 3 27084 27154 27085 3 27085 27154 27155 3 27085 27155 27086 3 27086 27155 27156 3 27086 27156 27087 3 27087 27156 27157 3 27087 27157 27088 3 27088 27157 27158 3 27088 27158 27089 3 27089 27158 27159 3 27089 27159 27090 3 27090 27159 27160 3 27090 27160 27091 3 27091 27160 27161 3 27091 27161 27092 3 27092 27161 27162 3 27092 27162 27093 3 27093 27162 27163 3 27093 27163 27094 3 27094 27163 27164 3 27094 27164 27095 3 27095 27164 27165 3 27095 27165 27096 3 27096 27165 27166 3 27096 27166 27097 3 27097 27166 27167 3 27097 27167 27098 3 27098 27167 27168 3 27098 27168 27099 3 27099 27168 27169 3 27099 27169 27100 3 27100 27169 27170 3 27100 27170 27101 3 27101 27170 27171 3 27101 27171 27102 3 27102 27171 27172 3 27102 27172 27103 3 27103 27172 27173 3 27103 27173 27104 3 27104 27173 27174 3 27104 27174 27105 3 27105 27174 27175 3 27105 27175 27106 3 27107 27176 27177 3 27107 27177 27108 3 27108 27177 27178 3 27108 27178 27109 3 27109 27178 27179 3 27109 27179 27110 3 27110 27179 27180 3 27110 27180 27111 3 27111 27180 27181 3 27111 27181 27112 3 27112 27181 27182 3 27112 27182 27113 3 27113 27182 27183 3 27113 27183 27114 3 27114 27183 27184 3 27114 27184 27115 3 27115 27184 27185 3 27115 27185 27116 3 27116 27185 27186 3 27116 27186 27117 3 27117 27186 27187 3 27117 27187 27118 3 27118 27187 27188 3 27118 27188 27119 3 27119 27188 27189 3 27119 27189 27120 3 27120 27189 27190 3 27120 27190 27121 3 27121 27190 27191 3 27121 27191 27122 3 27122 27191 27123 3 27192 27123 27191 3 27123 27192 27124 3 27193 27124 27192 3 27124 27193 27125 3 27194 27125 27193 3 27125 27194 27126 3 27195 27126 27194 3 27126 27195 27127 3 27196 27127 27195 3 27127 27196 27128 3 27197 27128 27196 3 27128 27197 27129 3 27198 27129 27197 3 27129 27198 27130 3 27199 27130 27198 3 27130 27199 27131 3 27200 27131 27199 3 27131 27200 27132 3 27201 27132 27200 3 27132 27201 27133 3 27202 27133 27201 3 27133 27202 27134 3 27203 27134 27202 3 27134 27203 27135 3 27204 27135 27203 3 27135 27204 27136 3 27205 27136 27204 3 27136 27205 27137 3 27206 27137 27205 3 27137 27206 27138 3 27207 27138 27206 3 27138 27207 27139 3 27208 27139 27207 3 27139 27208 27140 3 27209 27140 27208 3 27140 27209 27141 3 27210 27141 27209 3 27141 27210 27142 3 27211 27142 27210 3 27142 27211 27143 3 27212 27143 27211 3 27143 27212 27144 3 27213 27144 27212 3 27144 27213 27145 3 27214 27145 27213 3 27145 27214 27146 3 27215 27146 27214 3 27146 27215 27147 3 27216 27147 27215 3 27147 27216 27148 3 27217 27148 27216 3 27148 27217 27149 3 27218 27149 27217 3 27149 27218 27150 3 27219 27150 27218 3 27150 27219 27151 3 27220 27151 27219 3 27151 27220 27152 3 27221 27152 27220 3 27152 27221 27153 3 27222 27153 27221 3 27153 27222 27154 3 27223 27154 27222 3 27154 27223 27155 3 27224 27155 27223 3 27155 27224 27156 3 27225 27156 27224 3 27156 27225 27157 3 27226 27157 27225 3 27157 27226 27158 3 27227 27158 27226 3 27158 27227 27159 3 27228 27159 27227 3 27159 27228 27160 3 27229 27160 27228 3 27160 27229 27161 3 27230 27161 27229 3 27161 27230 27162 3 27231 27162 27230 3 27162 27231 27163 3 27232 27163 27231 3 27163 27232 27164 3 27233 27164 27232 3 27164 27233 27165 3 27234 27165 27233 3 27165 27234 27166 3 27235 27166 27234 3 27166 27235 27167 3 27236 27167 27235 3 27167 27236 27168 3 27237 27168 27236 3 27168 27237 27169 3 27238 27169 27237 3 27169 27238 27170 3 27239 27170 27238 3 27170 27239 27171 3 27240 27171 27239 3 27171 27240 27172 3 27241 27172 27240 3 27172 27241 27173 3 27242 27173 27241 3 27173 27242 27174 3 27243 27174 27242 3 27174 27243 27175 3 27244 27175 27243 3 27176 27245 27177 3 27246 27177 27245 3 27177 27246 27178 3 27247 27178 27246 3 27178 27247 27179 3 27248 27179 27247 3 27179 27248 27180 3 27249 27180 27248 3 27180 27249 27181 3 27250 27181 27249 3 27181 27250 27182 3 27251 27182 27250 3 27182 27251 27183 3 27252 27183 27251 3 27183 27252 27184 3 27253 27184 27252 3 27184 27253 27185 3 27254 27185 27253 3 27185 27254 27186 3 27255 27186 27254 3 27186 27255 27187 3 27256 27187 27255 3 27187 27256 27188 3 27257 27188 27256 3 27188 27257 27189 3 27258 27189 27257 3 27189 27258 27190 3 27259 27190 27258 3 27190 27259 27191 3 27260 27191 27259 3 27191 27260 27192 3 27261 27192 27260 3 27192 27261 27193 3 27262 27193 27261 3 27193 27262 27194 3 27263 27194 27262 3 27194 27263 27195 3 27264 27195 27263 3 27195 27264 27196 3 27265 27196 27264 3 27196 27265 27197 3 27266 27197 27265 3 27197 27266 27198 3 27267 27198 27266 3 27198 27267 27199 3 27268 27199 27267 3 27199 27268 27200 3 27269 27200 27268 3 27200 27269 27201 3 27270 27201 27269 3 27201 27270 27202 3 27271 27202 27270 3 27202 27271 27203 3 27272 27203 27271 3 27203 27272 27204 3 27273 27204 27272 3 27204 27273 27205 3 27274 27205 27273 3 27205 27274 27206 3 27275 27206 27274 3 27206 27275 27207 3 27276 27207 27275 3 27207 27276 27208 3 27277 27208 27276 3 27208 27277 27209 3 27278 27209 27277 3 27209 27278 27210 3 27279 27210 27278 3 27210 27279 27211 3 27280 27211 27279 3 27211 27280 27212 3 27281 27212 27280 3 27212 27281 27213 3 27282 27213 27281 3 27213 27282 27214 3 27283 27214 27282 3 27214 27283 27215 3 27284 27215 27283 3 27215 27284 27216 3 27285 27216 27284 3 27216 27285 27217 3 27286 27217 27285 3 27217 27286 27218 3 27287 27218 27286 3 27218 27287 27219 3 27288 27219 27287 3 27219 27288 27220 3 27289 27220 27288 3 27220 27289 27221 3 27290 27221 27289 3 27221 27290 27222 3 27291 27222 27290 3 27222 27291 27223 3 27292 27223 27291 3 27223 27292 27224 3 27293 27224 27292 3 27224 27293 27294 3 27224 27294 27225 3 27225 27294 27295 3 27225 27295 27226 3 27226 27295 27296 3 27226 27296 27227 3 27227 27296 27297 3 27227 27297 27228 3 27228 27297 27298 3 27228 27298 27229 3 27229 27298 27299 3 27229 27299 27230 3 27230 27299 27300 3 27230 27300 27231 3 27231 27300 27301 3 27231 27301 27232 3 27232 27301 27302 3 27232 27302 27233 3 27233 27302 27303 3 27233 27303 27234 3 27234 27303 27304 3 27234 27304 27235 3 27235 27304 27305 3 27235 27305 27236 3 27236 27305 27306 3 27236 27306 27237 3 27237 27306 27307 3 27237 27307 27238 3 27238 27307 27308 3 27238 27308 27239 3 27239 27308 27309 3 27239 27309 27240 3 27240 27309 27310 3 27240 27310 27241 3 27241 27310 27311 3 27241 27311 27242 3 27242 27311 27312 3 27242 27312 27243 3 27243 27312 27313 3 27243 27313 27244 3 27245 27314 27315 3 27245 27315 27246 3 27246 27315 27316 3 27246 27316 27247 3 27247 27316 27317 3 27247 27317 27248 3 27248 27317 27318 3 27248 27318 27249 3 27249 27318 27319 3 27249 27319 27250 3 27250 27319 27320 3 27250 27320 27251 3 27251 27320 27321 3 27251 27321 27252 3 27252 27321 27322 3 27252 27322 27253 3 27253 27322 27323 3 27253 27323 27254 3 27254 27323 27324 3 27254 27324 27255 3 27255 27324 27325 3 27255 27325 27256 3 27256 27325 27326 3 27256 27326 27257 3 27257 27326 27327 3 27257 27327 27258 3 27258 27327 27328 3 27258 27328 27259 3 27259 27328 27329 3 27259 27329 27260 3 27260 27329 27330 3 27260 27330 27261 3 27261 27330 27331 3 27261 27331 27262 3 27262 27331 27332 3 27262 27332 27263 3 27263 27332 27333 3 27263 27333 27264 3 27264 27333 27334 3 27264 27334 27265 3 27265 27334 27335 3 27265 27335 27266 3 27266 27335 27336 3 27266 27336 27267 3 27267 27336 27337 3 27267 27337 27268 3 27268 27337 27338 3 27268 27338 27269 3 27269 27338 27339 3 27269 27339 27270 3 27270 27339 27340 3 27270 27340 27271 3 27271 27340 27341 3 27271 27341 27272 3 27272 27341 27342 3 27272 27342 27273 3 27273 27342 27343 3 27273 27343 27274 3 27274 27343 27344 3 27274 27344 27275 3 27275 27344 27345 3 27275 27345 27276 3 27276 27345 27346 3 27276 27346 27277 3 27277 27346 27347 3 27277 27347 27278 3 27278 27347 27348 3 27278 27348 27279 3 27279 27348 27349 3 27279 27349 27280 3 27280 27349 27350 3 27280 27350 27281 3 27281 27350 27351 3 27281 27351 27282 3 27282 27351 27352 3 27282 27352 27283 3 27283 27352 27353 3 27283 27353 27284 3 27284 27353 27354 3 27284 27354 27285 3 27285 27354 27355 3 27285 27355 27286 3 27286 27355 27356 3 27286 27356 27287 3 27287 27356 27357 3 27287 27357 27288 3 27288 27357 27358 3 27288 27358 27289 3 27289 27358 27359 3 27289 27359 27290 3 27290 27359 27360 3 27290 27360 27291 3 27291 27360 27361 3 27291 27361 27292 3 27292 27361 27362 3 27292 27362 27293 3 27293 27362 27363 3 27293 27363 27294 3 27294 27363 27364 3 27294 27364 27295 3 27295 27364 27365 3 27295 27365 27296 3 27296 27365 27366 3 27296 27366 27297 3 27297 27366 27367 3 27297 27367 27298 3 27298 27367 27368 3 27298 27368 27299 3 27299 27368 27369 3 27299 27369 27300 3 27300 27369 27370 3 27300 27370 27301 3 27301 27370 27371 3 27301 27371 27302 3 27302 27371 27372 3 27302 27372 27303 3 27303 27372 27373 3 27303 27373 27304 3 27304 27373 27374 3 27304 27374 27305 3 27305 27374 27375 3 27305 27375 27306 3 27306 27375 27376 3 27306 27376 27307 3 27307 27376 27377 3 27307 27377 27308 3 27308 27377 27378 3 27308 27378 27309 3 27309 27378 27379 3 27309 27379 27310 3 27310 27379 27380 3 27310 27380 27311 3 27311 27380 27381 3 27311 27381 27312 3 27312 27381 27382 3 27312 27382 27313 3 27314 27383 27384 3 27314 27384 27315 3 27315 27384 27385 3 27315 27385 27316 3 27316 27385 27386 3 27316 27386 27317 3 27317 27386 27387 3 27317 27387 27318 3 27318 27387 27388 3 27318 27388 27319 3 27319 27388 27389 3 27319 27389 27320 3 27320 27389 27390 3 27320 27390 27321 3 27321 27390 27391 3 27321 27391 27322 3 27322 27391 27392 3 27322 27392 27323 3 27323 27392 27393 3 27323 27393 27324 3 27324 27393 27394 3 27324 27394 27325 3 27325 27394 27395 3 27325 27395 27326 3 27326 27395 27327 3 27396 27327 27395 3 27327 27396 27328 3 27397 27328 27396 3 27328 27397 27329 3 27398 27329 27397 3 27329 27398 27330 3 27399 27330 27398 3 27330 27399 27331 3 27400 27331 27399 3 27331 27400 27332 3 27401 27332 27400 3 27332 27401 27333 3 27402 27333 27401 3 27333 27402 27334 3 27403 27334 27402 3 27334 27403 27335 3 27404 27335 27403 3 27335 27404 27336 3 27405 27336 27404 3 27336 27405 27337 3 27406 27337 27405 3 27337 27406 27338 3 27407 27338 27406 3 27338 27407 27339 3 27408 27339 27407 3 27339 27408 27340 3 27409 27340 27408 3 27340 27409 27341 3 27410 27341 27409 3 27341 27410 27342 3 27411 27342 27410 3 27342 27411 27343 3 27412 27343 27411 3 27343 27412 27344 3 27413 27344 27412 3 27344 27413 27345 3 27414 27345 27413 3 27345 27414 27346 3 27415 27346 27414 3 27346 27415 27347 3 27416 27347 27415 3 27347 27416 27348 3 27417 27348 27416 3 27348 27417 27349 3 27418 27349 27417 3 27349 27418 27350 3 27419 27350 27418 3 27350 27419 27351 3 27420 27351 27419 3 27351 27420 27352 3 27421 27352 27420 3 27352 27421 27353 3 27422 27353 27421 3 27353 27422 27354 3 27423 27354 27422 3 27354 27423 27355 3 27424 27355 27423 3 27355 27424 27356 3 27425 27356 27424 3 27356 27425 27357 3 27426 27357 27425 3 27357 27426 27358 3 27427 27358 27426 3 27358 27427 27359 3 27428 27359 27427 3 27359 27428 27360 3 27429 27360 27428 3 27360 27429 27361 3 27430 27361 27429 3 27361 27430 27362 3 27431 27362 27430 3 27362 27431 27363 3 27432 27363 27431 3 27363 27432 27364 3 27433 27364 27432 3 27364 27433 27365 3 27434 27365 27433 3 27365 27434 27366 3 27435 27366 27434 3 27366 27435 27367 3 27436 27367 27435 3 27367 27436 27368 3 27437 27368 27436 3 27368 27437 27369 3 27438 27369 27437 3 27369 27438 27370 3 27439 27370 27438 3 27370 27439 27371 3 27440 27371 27439 3 27371 27440 27372 3 27441 27372 27440 3 27372 27441 27373 3 27442 27373 27441 3 27373 27442 27374 3 27443 27374 27442 3 27374 27443 27375 3 27444 27375 27443 3 27375 27444 27376 3 27445 27376 27444 3 27376 27445 27377 3 27446 27377 27445 3 27377 27446 27378 3 27447 27378 27446 3 27378 27447 27379 3 27448 27379 27447 3 27379 27448 27380 3 27449 27380 27448 3 27380 27449 27381 3 27450 27381 27449 3 27381 27450 27382 3 27451 27382 27450 3 27383 27452 27384 3 27453 27384 27452 3 27384 27453 27385 3 27454 27385 27453 3 27385 27454 27386 3 27455 27386 27454 3 27386 27455 27387 3 27456 27387 27455 3 27387 27456 27388 3 27457 27388 27456 3 27388 27457 27389 3 27458 27389 27457 3 27389 27458 27390 3 27459 27390 27458 3 27390 27459 27391 3 27460 27391 27459 3 27391 27460 27392 3 27461 27392 27460 3 27392 27461 27393 3 27462 27393 27461 3 27393 27462 27394 3 27463 27394 27462 3 27394 27463 27395 3 27464 27395 27463 3 27395 27464 27396 3 27465 27396 27464 3 27396 27465 27397 3 27466 27397 27465 3 27397 27466 27398 3 27467 27398 27466 3 27398 27467 27399 3 27468 27399 27467 3 27399 27468 27400 3 27469 27400 27468 3 27400 27469 27401 3 27470 27401 27469 3 27401 27470 27402 3 27471 27402 27470 3 27402 27471 27403 3 27472 27403 27471 3 27403 27472 27404 3 27473 27404 27472 3 27404 27473 27405 3 27474 27405 27473 3 27405 27474 27406 3 27475 27406 27474 3 27406 27475 27407 3 27476 27407 27475 3 27407 27476 27408 3 27477 27408 27476 3 27408 27477 27409 3 27478 27409 27477 3 27409 27478 27410 3 27479 27410 27478 3 27410 27479 27411 3 27480 27411 27479 3 27411 27480 27412 3 27481 27412 27480 3 27412 27481 27413 3 27482 27413 27481 3 27413 27482 27414 3 27483 27414 27482 3 27414 27483 27415 3 27484 27415 27483 3 27415 27484 27416 3 27485 27416 27484 3 27416 27485 27417 3 27486 27417 27485 3 27417 27486 27418 3 27487 27418 27486 3 27418 27487 27419 3 27488 27419 27487 3 27419 27488 27420 3 27489 27420 27488 3 27420 27489 27421 3 27490 27421 27489 3 27421 27490 27422 3 27491 27422 27490 3 27422 27491 27423 3 27492 27423 27491 3 27423 27492 27424 3 27493 27424 27492 3 27424 27493 27425 3 27494 27425 27493 3 27425 27494 27426 3 27495 27426 27494 3 27426 27495 27427 3 27496 27427 27495 3 27427 27496 27428 3 27497 27428 27496 3 27428 27497 27498 3 27428 27498 27429 3 27429 27498 27499 3 27429 27499 27430 3 27430 27499 27500 3 27430 27500 27431 3 27431 27500 27501 3 27431 27501 27432 3 27432 27501 27502 3 27432 27502 27433 3 27433 27502 27503 3 27433 27503 27434 3 27434 27503 27504 3 27434 27504 27435 3 27435 27504 27505 3 27435 27505 27436 3 27436 27505 27506 3 27436 27506 27437 3 27437 27506 27507 3 27437 27507 27438 3 27438 27507 27508 3 27438 27508 27439 3 27439 27508 27509 3 27439 27509 27440 3 27440 27509 27510 3 27440 27510 27441 3 27441 27510 27511 3 27441 27511 27442 3 27442 27511 27512 3 27442 27512 27443 3 27443 27512 27513 3 27443 27513 27444 3 27444 27513 27514 3 27444 27514 27445 3 27445 27514 27515 3 27445 27515 27446 3 27446 27515 27516 3 27446 27516 27447 3 27447 27516 27517 3 27447 27517 27448 3 27448 27517 27518 3 27448 27518 27449 3 27449 27518 27519 3 27449 27519 27450 3 27450 27519 27520 3 27450 27520 27451 3 27452 27521 27522 3 27452 27522 27453 3 27453 27522 27523 3 27453 27523 27454 3 27454 27523 27524 3 27454 27524 27455 3 27455 27524 27525 3 27455 27525 27456 3 27456 27525 27526 3 27456 27526 27457 3 27457 27526 27527 3 27457 27527 27458 3 27458 27527 27528 3 27458 27528 27459 3 27459 27528 27529 3 27459 27529 27460 3 27460 27529 27530 3 27460 27530 27461 3 27461 27530 27531 3 27461 27531 27462 3 27462 27531 27532 3 27462 27532 27463 3 27463 27532 27533 3 27463 27533 27464 3 27464 27533 27534 3 27464 27534 27465 3 27465 27534 27535 3 27465 27535 27466 3 27466 27535 27536 3 27466 27536 27467 3 27467 27536 27537 3 27467 27537 27468 3 27468 27537 27538 3 27468 27538 27469 3 27469 27538 27539 3 27469 27539 27470 3 27470 27539 27540 3 27470 27540 27471 3 27471 27540 27541 3 27471 27541 27472 3 27472 27541 27542 3 27472 27542 27473 3 27473 27542 27543 3 27473 27543 27474 3 27474 27543 27544 3 27474 27544 27475 3 27475 27544 27545 3 27475 27545 27476 3 27476 27545 27546 3 27476 27546 27477 3 27477 27546 27547 3 27477 27547 27478 3 27478 27547 27548 3 27478 27548 27479 3 27479 27548 27549 3 27479 27549 27480 3 27480 27549 27550 3 27480 27550 27481 3 27481 27550 27551 3 27481 27551 27482 3 27482 27551 27552 3 27482 27552 27483 3 27483 27552 27553 3 27483 27553 27484 3 27484 27553 27554 3 27484 27554 27485 3 27485 27554 27555 3 27485 27555 27486 3 27486 27555 27556 3 27486 27556 27487 3 27487 27556 27557 3 27487 27557 27488 3 27488 27557 27558 3 27488 27558 27489 3 27489 27558 27559 3 27489 27559 27490 3 27490 27559 27560 3 27490 27560 27491 3 27491 27560 27561 3 27491 27561 27492 3 27492 27561 27562 3 27492 27562 27493 3 27493 27562 27563 3 27493 27563 27494 3 27494 27563 27564 3 27494 27564 27495 3 27495 27564 27565 3 27495 27565 27496 3 27496 27565 27566 3 27496 27566 27497 3 27497 27566 27567 3 27497 27567 27498 3 27498 27567 27568 3 27498 27568 27499 3 27499 27568 27569 3 27499 27569 27500 3 27500 27569 27570 3 27500 27570 27501 3 27501 27570 27571 3 27501 27571 27502 3 27502 27571 27572 3 27502 27572 27503 3 27503 27572 27573 3 27503 27573 27504 3 27504 27573 27574 3 27504 27574 27505 3 27505 27574 27575 3 27505 27575 27506 3 27506 27575 27576 3 27506 27576 27507 3 27507 27576 27577 3 27507 27577 27508 3 27508 27577 27578 3 27508 27578 27509 3 27509 27578 27579 3 27509 27579 27510 3 27510 27579 27580 3 27510 27580 27511 3 27511 27580 27581 3 27511 27581 27512 3 27512 27581 27582 3 27512 27582 27513 3 27513 27582 27583 3 27513 27583 27514 3 27514 27583 27584 3 27514 27584 27515 3 27515 27584 27585 3 27515 27585 27516 3 27516 27585 27586 3 27516 27586 27517 3 27517 27586 27587 3 27517 27587 27518 3 27518 27587 27588 3 27518 27588 27519 3 27519 27588 27589 3 27519 27589 27520 3 27521 27590 27591 3 27521 27591 27522 3 27522 27591 27592 3 27522 27592 27523 3 27523 27592 27593 3 27523 27593 27524 3 27524 27593 27594 3 27524 27594 27525 3 27525 27594 27595 3 27525 27595 27526 3 27526 27595 27596 3 27526 27596 27527 3 27527 27596 27597 3 27527 27597 27528 3 27528 27597 27598 3 27528 27598 27529 3 27529 27598 27599 3 27529 27599 27530 3 27530 27599 27531 3 27600 27531 27599 3 27531 27600 27532 3 27601 27532 27600 3 27532 27601 27533 3 27602 27533 27601 3 27533 27602 27534 3 27603 27534 27602 3 27534 27603 27535 3 27604 27535 27603 3 27535 27604 27536 3 27605 27536 27604 3 27536 27605 27537 3 27606 27537 27605 3 27537 27606 27538 3 27607 27538 27606 3 27538 27607 27539 3 27608 27539 27607 3 27539 27608 27540 3 27609 27540 27608 3 27540 27609 27541 3 27610 27541 27609 3 27541 27610 27542 3 27611 27542 27610 3 27542 27611 27543 3 27612 27543 27611 3 27543 27612 27544 3 27613 27544 27612 3 27544 27613 27545 3 27614 27545 27613 3 27545 27614 27546 3 27615 27546 27614 3 27546 27615 27547 3 27616 27547 27615 3 27547 27616 27548 3 27617 27548 27616 3 27548 27617 27549 3 27618 27549 27617 3 27549 27618 27550 3 27619 27550 27618 3 27550 27619 27551 3 27620 27551 27619 3 27551 27620 27552 3 27621 27552 27620 3 27552 27621 27553 3 27622 27553 27621 3 27553 27622 27554 3 27623 27554 27622 3 27554 27623 27555 3 27624 27555 27623 3 27555 27624 27556 3 27625 27556 27624 3 27556 27625 27557 3 27626 27557 27625 3 27557 27626 27558 3 27627 27558 27626 3 27558 27627 27559 3 27628 27559 27627 3 27559 27628 27560 3 27629 27560 27628 3 27560 27629 27561 3 27630 27561 27629 3 27561 27630 27562 3 27631 27562 27630 3 27562 27631 27563 3 27632 27563 27631 3 27563 27632 27564 3 27633 27564 27632 3 27564 27633 27565 3 27634 27565 27633 3 27565 27634 27566 3 27635 27566 27634 3 27566 27635 27567 3 27636 27567 27635 3 27567 27636 27568 3 27637 27568 27636 3 27568 27637 27569 3 27638 27569 27637 3 27569 27638 27570 3 27639 27570 27638 3 27570 27639 27571 3 27640 27571 27639 3 27571 27640 27572 3 27641 27572 27640 3 27572 27641 27573 3 27642 27573 27641 3 27573 27642 27574 3 27643 27574 27642 3 27574 27643 27575 3 27644 27575 27643 3 27575 27644 27576 3 27645 27576 27644 3 27576 27645 27577 3 27646 27577 27645 3 27577 27646 27578 3 27647 27578 27646 3 27578 27647 27579 3 27648 27579 27647 3 27579 27648 27580 3 27649 27580 27648 3 27580 27649 27581 3 27650 27581 27649 3 27581 27650 27582 3 27651 27582 27650 3 27582 27651 27583 3 27652 27583 27651 3 27583 27652 27584 3 27653 27584 27652 3 27584 27653 27585 3 27654 27585 27653 3 27585 27654 27586 3 27655 27586 27654 3 27586 27655 27587 3 27656 27587 27655 3 27587 27656 27588 3 27657 27588 27656 3 27588 27657 27589 3 27658 27589 27657 3 27590 27659 27591 3 27660 27591 27659 3 27591 27660 27592 3 27661 27592 27660 3 27592 27661 27593 3 27662 27593 27661 3 27593 27662 27594 3 27663 27594 27662 3 27594 27663 27595 3 27664 27595 27663 3 27595 27664 27596 3 27665 27596 27664 3 27596 27665 27597 3 27666 27597 27665 3 27597 27666 27598 3 27667 27598 27666 3 27598 27667 27599 3 27668 27599 27667 3 27599 27668 27600 3 27669 27600 27668 3 27600 27669 27601 3 27670 27601 27669 3 27601 27670 27602 3 27671 27602 27670 3 27602 27671 27603 3 27672 27603 27671 3 27603 27672 27604 3 27673 27604 27672 3 27604 27673 27605 3 27674 27605 27673 3 27605 27674 27606 3 27675 27606 27674 3 27606 27675 27607 3 27676 27607 27675 3 27607 27676 27608 3 27677 27608 27676 3 27608 27677 27609 3 27678 27609 27677 3 27609 27678 27610 3 27679 27610 27678 3 27610 27679 27611 3 27680 27611 27679 3 27611 27680 27612 3 27681 27612 27680 3 27612 27681 27613 3 27682 27613 27681 3 27613 27682 27614 3 27683 27614 27682 3 27614 27683 27615 3 27684 27615 27683 3 27615 27684 27616 3 27685 27616 27684 3 27616 27685 27617 3 27686 27617 27685 3 27617 27686 27618 3 27687 27618 27686 3 27618 27687 27619 3 27688 27619 27687 3 27619 27688 27620 3 27689 27620 27688 3 27620 27689 27621 3 27690 27621 27689 3 27621 27690 27622 3 27691 27622 27690 3 27622 27691 27623 3 27692 27623 27691 3 27623 27692 27624 3 27693 27624 27692 3 27624 27693 27625 3 27694 27625 27693 3 27625 27694 27626 3 27695 27626 27694 3 27626 27695 27627 3 27696 27627 27695 3 27627 27696 27628 3 27697 27628 27696 3 27628 27697 27629 3 27698 27629 27697 3 27629 27698 27630 3 27699 27630 27698 3 27630 27699 27631 3 27700 27631 27699 3 27631 27700 27632 3 27701 27632 27700 3 27632 27701 27702 3 27632 27702 27633 3 27633 27702 27703 3 27633 27703 27634 3 27634 27703 27704 3 27634 27704 27635 3 27635 27704 27705 3 27635 27705 27636 3 27636 27705 27706 3 27636 27706 27637 3 27637 27706 27707 3 27637 27707 27638 3 27638 27707 27708 3 27638 27708 27639 3 27639 27708 27709 3 27639 27709 27640 3 27640 27709 27710 3 27640 27710 27641 3 27641 27710 27711 3 27641 27711 27642 3 27642 27711 27712 3 27642 27712 27643 3 27643 27712 27713 3 27643 27713 27644 3 27644 27713 27714 3 27644 27714 27645 3 27645 27714 27715 3 27645 27715 27646 3 27646 27715 27716 3 27646 27716 27647 3 27647 27716 27717 3 27647 27717 27648 3 27648 27717 27718 3 27648 27718 27649 3 27649 27718 27719 3 27649 27719 27650 3 27650 27719 27720 3 27650 27720 27651 3 27651 27720 27721 3 27651 27721 27652 3 27652 27721 27722 3 27652 27722 27653 3 27653 27722 27723 3 27653 27723 27654 3 27654 27723 27724 3 27654 27724 27655 3 27655 27724 27725 3 27655 27725 27656 3 27656 27725 27726 3 27656 27726 27657 3 27657 27726 27727 3 27657 27727 27658 3 27659 27728 27729 3 27659 27729 27660 3 27660 27729 27730 3 27660 27730 27661 3 27661 27730 27731 3 27661 27731 27662 3 27662 27731 27732 3 27662 27732 27663 3 27663 27732 27733 3 27663 27733 27664 3 27664 27733 27734 3 27664 27734 27665 3 27665 27734 27735 3 27665 27735 27666 3 27666 27735 27736 3 27666 27736 27667 3 27667 27736 27737 3 27667 27737 27668 3 27668 27737 27738 3 27668 27738 27669 3 27669 27738 27739 3 27669 27739 27670 3 27670 27739 27740 3 27670 27740 27671 3 27671 27740 27741 3 27671 27741 27672 3 27672 27741 27742 3 27672 27742 27673 3 27673 27742 27743 3 27673 27743 27674 3 27674 27743 27744 3 27674 27744 27675 3 27675 27744 27745 3 27675 27745 27676 3 27676 27745 27746 3 27676 27746 27677 3 27677 27746 27747 3 27677 27747 27678 3 27678 27747 27748 3 27678 27748 27679 3 27679 27748 27749 3 27679 27749 27680 3 27680 27749 27750 3 27680 27750 27681 3 27681 27750 27751 3 27681 27751 27682 3 27682 27751 27752 3 27682 27752 27683 3 27683 27752 27753 3 27683 27753 27684 3 27684 27753 27754 3 27684 27754 27685 3 27685 27754 27755 3 27685 27755 27686 3 27686 27755 27756 3 27686 27756 27687 3 27687 27756 27757 3 27687 27757 27688 3 27688 27757 27758 3 27688 27758 27689 3 27689 27758 27759 3 27689 27759 27690 3 27690 27759 27760 3 27690 27760 27691 3 27691 27760 27761 3 27691 27761 27692 3 27692 27761 27762 3 27692 27762 27693 3 27693 27762 27763 3 27693 27763 27694 3 27694 27763 27764 3 27694 27764 27695 3 27695 27764 27765 3 27695 27765 27696 3 27696 27765 27766 3 27696 27766 27697 3 27697 27766 27767 3 27697 27767 27698 3 27698 27767 27768 3 27698 27768 27699 3 27699 27768 27769 3 27699 27769 27700 3 27700 27769 27770 3 27700 27770 27701 3 27701 27770 27771 3 27701 27771 27702 3 27702 27771 27772 3 27702 27772 27703 3 27703 27772 27773 3 27703 27773 27704 3 27704 27773 27774 3 27704 27774 27705 3 27705 27774 27775 3 27705 27775 27706 3 27706 27775 27776 3 27706 27776 27707 3 27707 27776 27777 3 27707 27777 27708 3 27708 27777 27778 3 27708 27778 27709 3 27709 27778 27779 3 27709 27779 27710 3 27710 27779 27780 3 27710 27780 27711 3 27711 27780 27781 3 27711 27781 27712 3 27712 27781 27782 3 27712 27782 27713 3 27713 27782 27783 3 27713 27783 27714 3 27714 27783 27784 3 27714 27784 27715 3 27715 27784 27785 3 27715 27785 27716 3 27716 27785 27786 3 27716 27786 27717 3 27717 27786 27787 3 27717 27787 27718 3 27718 27787 27788 3 27718 27788 27719 3 27719 27788 27789 3 27719 27789 27720 3 27720 27789 27790 3 27720 27790 27721 3 27721 27790 27791 3 27721 27791 27722 3 27722 27791 27792 3 27722 27792 27723 3 27723 27792 27793 3 27723 27793 27724 3 27724 27793 27794 3 27724 27794 27725 3 27725 27794 27795 3 27725 27795 27726 3 27726 27795 27796 3 27726 27796 27727 3 27728 27797 27798 3 27728 27798 27729 3 27729 27798 27799 3 27729 27799 27730 3 27730 27799 27800 3 27730 27800 27731 3 27731 27800 27801 3 27731 27801 27732 3 27732 27801 27802 3 27732 27802 27733 3 27733 27802 27803 3 27733 27803 27734 3 27734 27803 27804 3 27734 27804 27735 3 27735 27804 27736 3 27805 27736 27804 3 27736 27805 27737 3 27806 27737 27805 3 27737 27806 27738 3 27807 27738 27806 3 27738 27807 27739 3 27808 27739 27807 3 27739 27808 27740 3 27809 27740 27808 3 27740 27809 27741 3 27810 27741 27809 3 27741 27810 27742 3 27811 27742 27810 3 27742 27811 27743 3 27812 27743 27811 3 27743 27812 27744 3 27813 27744 27812 3 27744 27813 27745 3 27814 27745 27813 3 27745 27814 27746 3 27815 27746 27814 3 27746 27815 27747 3 27816 27747 27815 3 27747 27816 27748 3 27817 27748 27816 3 27748 27817 27749 3 27818 27749 27817 3 27749 27818 27750 3 27819 27750 27818 3 27750 27819 27751 3 27820 27751 27819 3 27751 27820 27752 3 27821 27752 27820 3 27752 27821 27753 3 27822 27753 27821 3 27753 27822 27754 3 27823 27754 27822 3 27754 27823 27755 3 27824 27755 27823 3 27755 27824 27756 3 27825 27756 27824 3 27756 27825 27757 3 27826 27757 27825 3 27757 27826 27758 3 27827 27758 27826 3 27758 27827 27759 3 27828 27759 27827 3 27759 27828 27760 3 27829 27760 27828 3 27760 27829 27761 3 27830 27761 27829 3 27761 27830 27762 3 27831 27762 27830 3 27762 27831 27763 3 27832 27763 27831 3 27763 27832 27764 3 27833 27764 27832 3 27764 27833 27765 3 27834 27765 27833 3 27765 27834 27766 3 27835 27766 27834 3 27766 27835 27767 3 27836 27767 27835 3 27767 27836 27768 3 27837 27768 27836 3 27768 27837 27769 3 27838 27769 27837 3 27769 27838 27770 3 27839 27770 27838 3 27770 27839 27771 3 27840 27771 27839 3 27771 27840 27772 3 27841 27772 27840 3 27772 27841 27773 3 27842 27773 27841 3 27773 27842 27774 3 27843 27774 27842 3 27774 27843 27775 3 27844 27775 27843 3 27775 27844 27776 3 27845 27776 27844 3 27776 27845 27777 3 27846 27777 27845 3 27777 27846 27778 3 27847 27778 27846 3 27778 27847 27779 3 27848 27779 27847 3 27779 27848 27780 3 27849 27780 27848 3 27780 27849 27781 3 27850 27781 27849 3 27781 27850 27782 3 27851 27782 27850 3 27782 27851 27783 3 27852 27783 27851 3 27783 27852 27784 3 27853 27784 27852 3 27784 27853 27785 3 27854 27785 27853 3 27785 27854 27786 3 27855 27786 27854 3 27786 27855 27787 3 27856 27787 27855 3 27787 27856 27788 3 27857 27788 27856 3 27788 27857 27789 3 27858 27789 27857 3 27789 27858 27790 3 27859 27790 27858 3 27790 27859 27791 3 27860 27791 27859 3 27791 27860 27792 3 27861 27792 27860 3 27792 27861 27793 3 27862 27793 27861 3 27793 27862 27794 3 27863 27794 27862 3 27794 27863 27795 3 27864 27795 27863 3 27795 27864 27796 3 27865 27796 27864 3 27797 27866 27798 3 27867 27798 27866 3 27798 27867 27799 3 27868 27799 27867 3 27799 27868 27800 3 27869 27800 27868 3 27800 27869 27801 3 27870 27801 27869 3 27801 27870 27802 3 27871 27802 27870 3 27802 27871 27803 3 27872 27803 27871 3 27803 27872 27804 3 27873 27804 27872 3 27804 27873 27805 3 27874 27805 27873 3 27805 27874 27806 3 27875 27806 27874 3 27806 27875 27807 3 27876 27807 27875 3 27807 27876 27808 3 27877 27808 27876 3 27808 27877 27809 3 27878 27809 27877 3 27809 27878 27810 3 27879 27810 27878 3 27810 27879 27811 3 27880 27811 27879 3 27811 27880 27812 3 27881 27812 27880 3 27812 27881 27813 3 27882 27813 27881 3 27813 27882 27814 3 27883 27814 27882 3 27814 27883 27815 3 27884 27815 27883 3 27815 27884 27816 3 27885 27816 27884 3 27816 27885 27817 3 27886 27817 27885 3 27817 27886 27818 3 27887 27818 27886 3 27818 27887 27819 3 27888 27819 27887 3 27819 27888 27820 3 27889 27820 27888 3 27820 27889 27821 3 27890 27821 27889 3 27821 27890 27822 3 27891 27822 27890 3 27822 27891 27823 3 27892 27823 27891 3 27823 27892 27824 3 27893 27824 27892 3 27824 27893 27825 3 27894 27825 27893 3 27825 27894 27826 3 27895 27826 27894 3 27826 27895 27827 3 27896 27827 27895 3 27827 27896 27828 3 27897 27828 27896 3 27828 27897 27829 3 27898 27829 27897 3 27829 27898 27830 3 27899 27830 27898 3 27830 27899 27831 3 27900 27831 27899 3 27831 27900 27832 3 27901 27832 27900 3 27832 27901 27833 3 27902 27833 27901 3 27833 27902 27834 3 27903 27834 27902 3 27834 27903 27835 3 27904 27835 27903 3 27835 27904 27836 3 27905 27836 27904 3 27836 27905 27837 3 27906 27837 27905 3 27837 27906 27907 3 27837 27907 27838 3 27838 27907 27908 3 27838 27908 27839 3 27839 27908 27909 3 27839 27909 27840 3 27840 27909 27910 3 27840 27910 27841 3 27841 27910 27911 3 27841 27911 27842 3 27842 27911 27912 3 27842 27912 27843 3 27843 27912 27913 3 27843 27913 27844 3 27844 27913 27914 3 27844 27914 27845 3 27845 27914 27915 3 27845 27915 27846 3 27846 27915 27916 3 27846 27916 27847 3 27847 27916 27917 3 27847 27917 27848 3 27848 27917 27918 3 27848 27918 27849 3 27849 27918 27919 3 27849 27919 27850 3 27850 27919 27920 3 27850 27920 27851 3 27851 27920 27921 3 27851 27921 27852 3 27852 27921 27922 3 27852 27922 27853 3 27853 27922 27923 3 27853 27923 27854 3 27854 27923 27924 3 27854 27924 27855 3 27855 27924 27925 3 27855 27925 27856 3 27856 27925 27926 3 27856 27926 27857 3 27857 27926 27927 3 27857 27927 27858 3 27858 27927 27928 3 27858 27928 27859 3 27859 27928 27929 3 27859 27929 27860 3 27860 27929 27930 3 27860 27930 27861 3 27861 27930 27931 3 27861 27931 27862 3 27862 27931 27932 3 27862 27932 27863 3 27863 27932 27933 3 27863 27933 27864 3 27864 27933 27934 3 27864 27934 27865 3 27866 27935 27936 3 27866 27936 27867 3 27867 27936 27937 3 27867 27937 27868 3 27868 27937 27938 3 27868 27938 27869 3 27869 27938 27939 3 27869 27939 27870 3 27870 27939 27940 3 27870 27940 27871 3 27871 27940 27941 3 27871 27941 27872 3 27872 27941 27942 3 27872 27942 27873 3 27873 27942 27943 3 27873 27943 27874 3 27874 27943 27944 3 27874 27944 27875 3 27875 27944 27945 3 27875 27945 27876 3 27876 27945 27946 3 27876 27946 27877 3 27877 27946 27947 3 27877 27947 27878 3 27878 27947 27948 3 27878 27948 27879 3 27879 27948 27949 3 27879 27949 27880 3 27880 27949 27950 3 27880 27950 27881 3 27881 27950 27951 3 27881 27951 27882 3 27882 27951 27952 3 27882 27952 27883 3 27883 27952 27953 3 27883 27953 27884 3 27884 27953 27954 3 27884 27954 27885 3 27885 27954 27955 3 27885 27955 27886 3 27886 27955 27956 3 27886 27956 27887 3 27887 27956 27957 3 27887 27957 27888 3 27888 27957 27958 3 27888 27958 27889 3 27889 27958 27959 3 27889 27959 27890 3 27890 27959 27960 3 27890 27960 27891 3 27891 27960 27961 3 27891 27961 27892 3 27892 27961 27962 3 27892 27962 27893 3 27893 27962 27963 3 27893 27963 27894 3 27894 27963 27964 3 27894 27964 27895 3 27895 27964 27965 3 27895 27965 27896 3 27896 27965 27966 3 27896 27966 27897 3 27897 27966 27967 3 27897 27967 27898 3 27898 27967 27968 3 27898 27968 27899 3 27899 27968 27969 3 27899 27969 27900 3 27900 27969 27970 3 27900 27970 27901 3 27901 27970 27971 3 27901 27971 27902 3 27902 27971 27972 3 27902 27972 27903 3 27903 27972 27973 3 27903 27973 27904 3 27904 27973 27974 3 27904 27974 27905 3 27905 27974 27975 3 27905 27975 27906 3 27906 27975 27976 3 27906 27976 27907 3 27907 27976 27977 3 27907 27977 27908 3 27908 27977 27978 3 27908 27978 27909 3 27909 27978 27979 3 27909 27979 27910 3 27910 27979 27980 3 27910 27980 27911 3 27911 27980 27981 3 27911 27981 27912 3 27912 27981 27982 3 27912 27982 27913 3 27913 27982 27983 3 27913 27983 27914 3 27914 27983 27984 3 27914 27984 27915 3 27915 27984 27985 3 27915 27985 27916 3 27916 27985 27986 3 27916 27986 27917 3 27917 27986 27987 3 27917 27987 27918 3 27918 27987 27988 3 27918 27988 27919 3 27919 27988 27989 3 27919 27989 27920 3 27920 27989 27990 3 27920 27990 27921 3 27921 27990 27991 3 27921 27991 27922 3 27922 27991 27992 3 27922 27992 27923 3 27923 27992 27993 3 27923 27993 27924 3 27924 27993 27994 3 27924 27994 27925 3 27925 27994 27995 3 27925 27995 27926 3 27926 27995 27996 3 27926 27996 27927 3 27927 27996 27997 3 27927 27997 27928 3 27928 27997 27998 3 27928 27998 27929 3 27929 27998 27999 3 27929 27999 27930 3 27930 27999 28000 3 27930 28000 27931 3 27931 28000 28001 3 27931 28001 27932 3 27932 28001 28002 3 27932 28002 27933 3 27933 28002 28003 3 27933 28003 27934 3 27935 28004 28005 3 27935 28005 27936 3 27936 28005 28006 3 27936 28006 27937 3 27937 28006 28007 3 27937 28007 27938 3 27938 28007 28008 3 27938 28008 27939 3 27939 28008 28009 3 27939 28009 27940 3 27940 28009 27941 3 28010 27941 28009 3 27941 28010 27942 3 28011 27942 28010 3 27942 28011 27943 3 28012 27943 28011 3 27943 28012 27944 3 28013 27944 28012 3 27944 28013 27945 3 28014 27945 28013 3 27945 28014 27946 3 28015 27946 28014 3 27946 28015 27947 3 28016 27947 28015 3 27947 28016 27948 3 28017 27948 28016 3 27948 28017 27949 3 28018 27949 28017 3 27949 28018 27950 3 28019 27950 28018 3 27950 28019 27951 3 28020 27951 28019 3 27951 28020 27952 3 28021 27952 28020 3 27952 28021 27953 3 28022 27953 28021 3 27953 28022 27954 3 28023 27954 28022 3 27954 28023 27955 3 28024 27955 28023 3 27955 28024 27956 3 28025 27956 28024 3 27956 28025 27957 3 28026 27957 28025 3 27957 28026 27958 3 28027 27958 28026 3 27958 28027 27959 3 28028 27959 28027 3 27959 28028 27960 3 28029 27960 28028 3 27960 28029 27961 3 28030 27961 28029 3 27961 28030 27962 3 28031 27962 28030 3 27962 28031 27963 3 28032 27963 28031 3 27963 28032 27964 3 28033 27964 28032 3 27964 28033 27965 3 28034 27965 28033 3 27965 28034 27966 3 28035 27966 28034 3 27966 28035 27967 3 28036 27967 28035 3 27967 28036 27968 3 28037 27968 28036 3 27968 28037 27969 3 28038 27969 28037 3 27969 28038 27970 3 28039 27970 28038 3 27970 28039 27971 3 28040 27971 28039 3 27971 28040 27972 3 28041 27972 28040 3 27972 28041 27973 3 28042 27973 28041 3 27973 28042 27974 3 28043 27974 28042 3 27974 28043 27975 3 28044 27975 28043 3 27975 28044 27976 3 28045 27976 28044 3 27976 28045 27977 3 28046 27977 28045 3 27977 28046 27978 3 28047 27978 28046 3 27978 28047 27979 3 28048 27979 28047 3 27979 28048 27980 3 28049 27980 28048 3 27980 28049 27981 3 28050 27981 28049 3 27981 28050 27982 3 28051 27982 28050 3 27982 28051 27983 3 28052 27983 28051 3 27983 28052 27984 3 28053 27984 28052 3 27984 28053 27985 3 28054 27985 28053 3 27985 28054 27986 3 28055 27986 28054 3 27986 28055 27987 3 28056 27987 28055 3 27987 28056 27988 3 28057 27988 28056 3 27988 28057 27989 3 28058 27989 28057 3 27989 28058 27990 3 28059 27990 28058 3 27990 28059 27991 3 28060 27991 28059 3 27991 28060 27992 3 28061 27992 28060 3 27992 28061 27993 3 28062 27993 28061 3 27993 28062 27994 3 28063 27994 28062 3 27994 28063 27995 3 28064 27995 28063 3 27995 28064 27996 3 28065 27996 28064 3 27996 28065 27997 3 28066 27997 28065 3 27997 28066 27998 3 28067 27998 28066 3 27998 28067 27999 3 28068 27999 28067 3 27999 28068 28000 3 28069 28000 28068 3 28000 28069 28001 3 28070 28001 28069 3 28001 28070 28002 3 28071 28002 28070 3 28002 28071 28003 3 28072 28003 28071 3 28004 28073 28005 3 28074 28005 28073 3 28005 28074 28006 3 28075 28006 28074 3 28006 28075 28007 3 28076 28007 28075 3 28007 28076 28008 3 28077 28008 28076 3 28008 28077 28009 3 28078 28009 28077 3 28009 28078 28010 3 28079 28010 28078 3 28010 28079 28011 3 28080 28011 28079 3 28011 28080 28012 3 28081 28012 28080 3 28012 28081 28013 3 28082 28013 28081 3 28013 28082 28014 3 28083 28014 28082 3 28014 28083 28015 3 28084 28015 28083 3 28015 28084 28016 3 28085 28016 28084 3 28016 28085 28017 3 28086 28017 28085 3 28017 28086 28018 3 28087 28018 28086 3 28018 28087 28019 3 28088 28019 28087 3 28019 28088 28020 3 28089 28020 28088 3 28020 28089 28021 3 28090 28021 28089 3 28021 28090 28022 3 28091 28022 28090 3 28022 28091 28023 3 28092 28023 28091 3 28023 28092 28024 3 28093 28024 28092 3 28024 28093 28025 3 28094 28025 28093 3 28025 28094 28026 3 28095 28026 28094 3 28026 28095 28027 3 28096 28027 28095 3 28027 28096 28028 3 28097 28028 28096 3 28028 28097 28029 3 28098 28029 28097 3 28029 28098 28030 3 28099 28030 28098 3 28030 28099 28031 3 28100 28031 28099 3 28031 28100 28032 3 28101 28032 28100 3 28032 28101 28033 3 28102 28033 28101 3 28033 28102 28034 3 28103 28034 28102 3 28034 28103 28035 3 28104 28035 28103 3 28035 28104 28036 3 28105 28036 28104 3 28036 28105 28037 3 28106 28037 28105 3 28037 28106 28038 3 28107 28038 28106 3 28038 28107 28039 3 28108 28039 28107 3 28039 28108 28040 3 28109 28040 28108 3 28040 28109 28041 3 28110 28041 28109 3 28041 28110 28042 3 28111 28042 28110 3 28042 28111 28043 3 28112 28043 28111 3 28043 28112 28113 3 28043 28113 28044 3 28044 28113 28114 3 28044 28114 28045 3 28045 28114 28115 3 28045 28115 28046 3 28046 28115 28116 3 28046 28116 28047 3 28047 28116 28117 3 28047 28117 28048 3 28048 28117 28118 3 28048 28118 28049 3 28049 28118 28119 3 28049 28119 28050 3 28050 28119 28120 3 28050 28120 28051 3 28051 28120 28121 3 28051 28121 28052 3 28052 28121 28122 3 28052 28122 28053 3 28053 28122 28123 3 28053 28123 28054 3 28054 28123 28124 3 28054 28124 28055 3 28055 28124 28125 3 28055 28125 28056 3 28056 28125 28126 3 28056 28126 28057 3 28057 28126 28127 3 28057 28127 28058 3 28058 28127 28128 3 28058 28128 28059 3 28059 28128 28129 3 28059 28129 28060 3 28060 28129 28130 3 28060 28130 28061 3 28061 28130 28131 3 28061 28131 28062 3 28062 28131 28132 3 28062 28132 28063 3 28063 28132 28133 3 28063 28133 28064 3 28064 28133 28134 3 28064 28134 28065 3 28065 28134 28135 3 28065 28135 28066 3 28066 28135 28136 3 28066 28136 28067 3 28067 28136 28137 3 28067 28137 28068 3 28068 28137 28138 3 28068 28138 28069 3 28069 28138 28139 3 28069 28139 28070 3 28070 28139 28140 3 28070 28140 28071 3 28071 28140 28141 3 28071 28141 28072 3 28073 28142 28143 3 28073 28143 28074 3 28074 28143 28144 3 28074 28144 28075 3 28075 28144 28145 3 28075 28145 28076 3 28076 28145 28146 3 28076 28146 28077 3 28077 28146 28147 3 28077 28147 28078 3 28078 28147 28148 3 28078 28148 28079 3 28079 28148 28149 3 28079 28149 28080 3 28080 28149 28150 3 28080 28150 28081 3 28081 28150 28151 3 28081 28151 28082 3 28082 28151 28152 3 28082 28152 28083 3 28083 28152 28153 3 28083 28153 28084 3 28084 28153 28154 3 28084 28154 28085 3 28085 28154 28155 3 28085 28155 28086 3 28086 28155 28156 3 28086 28156 28087 3 28087 28156 28157 3 28087 28157 28088 3 28088 28157 28158 3 28088 28158 28089 3 28089 28158 28159 3 28089 28159 28090 3 28090 28159 28160 3 28090 28160 28091 3 28091 28160 28161 3 28091 28161 28092 3 28092 28161 28162 3 28092 28162 28093 3 28093 28162 28163 3 28093 28163 28094 3 28094 28163 28164 3 28094 28164 28095 3 28095 28164 28165 3 28095 28165 28096 3 28096 28165 28166 3 28096 28166 28097 3 28097 28166 28167 3 28097 28167 28098 3 28098 28167 28168 3 28098 28168 28099 3 28099 28168 28169 3 28099 28169 28100 3 28100 28169 28170 3 28100 28170 28101 3 28101 28170 28171 3 28101 28171 28102 3 28102 28171 28172 3 28102 28172 28103 3 28103 28172 28173 3 28103 28173 28104 3 28104 28173 28174 3 28104 28174 28105 3 28105 28174 28175 3 28105 28175 28106 3 28106 28175 28176 3 28106 28176 28107 3 28107 28176 28177 3 28107 28177 28108 3 28108 28177 28178 3 28108 28178 28109 3 28109 28178 28179 3 28109 28179 28110 3 28110 28179 28180 3 28110 28180 28111 3 28111 28180 28181 3 28111 28181 28112 3 28112 28181 28182 3 28112 28182 28113 3 28113 28182 28183 3 28113 28183 28114 3 28114 28183 28184 3 28114 28184 28115 3 28115 28184 28185 3 28115 28185 28116 3 28116 28185 28186 3 28116 28186 28117 3 28117 28186 28187 3 28117 28187 28118 3 28118 28187 28188 3 28118 28188 28119 3 28119 28188 28189 3 28119 28189 28120 3 28120 28189 28190 3 28120 28190 28121 3 28121 28190 28191 3 28121 28191 28122 3 28122 28191 28192 3 28122 28192 28123 3 28123 28192 28193 3 28123 28193 28124 3 28124 28193 28194 3 28124 28194 28125 3 28125 28194 28195 3 28125 28195 28126 3 28126 28195 28196 3 28126 28196 28127 3 28127 28196 28197 3 28127 28197 28128 3 28128 28197 28198 3 28128 28198 28129 3 28129 28198 28199 3 28129 28199 28130 3 28130 28199 28200 3 28130 28200 28131 3 28131 28200 28201 3 28131 28201 28132 3 28132 28201 28202 3 28132 28202 28133 3 28133 28202 28203 3 28133 28203 28134 3 28134 28203 28204 3 28134 28204 28135 3 28135 28204 28205 3 28135 28205 28136 3 28136 28205 28206 3 28136 28206 28137 3 28137 28206 28207 3 28137 28207 28138 3 28138 28207 28208 3 28138 28208 28139 3 28139 28208 28209 3 28139 28209 28140 3 28140 28209 28210 3 28140 28210 28141 3 28142 28211 28212 3 28142 28212 28143 3 28143 28212 28213 3 28143 28213 28144 3 28144 28213 28214 3 28144 28214 28145 3 28145 28214 28215 3 28145 28215 28146 3 28146 28215 28147 3 28216 28147 28215 3 28147 28216 28148 3 28217 28148 28216 3 28148 28217 28149 3 28218 28149 28217 3 28149 28218 28150 3 28219 28150 28218 3 28150 28219 28151 3 28220 28151 28219 3 28151 28220 28152 3 28221 28152 28220 3 28152 28221 28153 3 28222 28153 28221 3 28153 28222 28154 3 28223 28154 28222 3 28154 28223 28155 3 28224 28155 28223 3 28155 28224 28156 3 28225 28156 28224 3 28156 28225 28157 3 28226 28157 28225 3 28157 28226 28158 3 28227 28158 28226 3 28158 28227 28159 3 28228 28159 28227 3 28159 28228 28160 3 28229 28160 28228 3 28160 28229 28161 3 28230 28161 28229 3 28161 28230 28162 3 28231 28162 28230 3 28162 28231 28163 3 28232 28163 28231 3 28163 28232 28164 3 28233 28164 28232 3 28164 28233 28165 3 28234 28165 28233 3 28165 28234 28166 3 28235 28166 28234 3 28166 28235 28167 3 28236 28167 28235 3 28167 28236 28168 3 28237 28168 28236 3 28168 28237 28169 3 28238 28169 28237 3 28169 28238 28170 3 28239 28170 28238 3 28170 28239 28171 3 28240 28171 28239 3 28171 28240 28172 3 28241 28172 28240 3 28172 28241 28173 3 28242 28173 28241 3 28173 28242 28174 3 28243 28174 28242 3 28174 28243 28175 3 28244 28175 28243 3 28175 28244 28176 3 28245 28176 28244 3 28176 28245 28177 3 28246 28177 28245 3 28177 28246 28178 3 28247 28178 28246 3 28178 28247 28179 3 28248 28179 28247 3 28179 28248 28180 3 28249 28180 28248 3 28180 28249 28181 3 28250 28181 28249 3 28181 28250 28182 3 28251 28182 28250 3 28182 28251 28183 3 28252 28183 28251 3 28183 28252 28184 3 28253 28184 28252 3 28184 28253 28185 3 28254 28185 28253 3 28185 28254 28186 3 28255 28186 28254 3 28186 28255 28187 3 28256 28187 28255 3 28187 28256 28188 3 28257 28188 28256 3 28188 28257 28189 3 28258 28189 28257 3 28189 28258 28190 3 28259 28190 28258 3 28190 28259 28191 3 28260 28191 28259 3 28191 28260 28192 3 28261 28192 28260 3 28192 28261 28193 3 28262 28193 28261 3 28193 28262 28194 3 28263 28194 28262 3 28194 28263 28195 3 28264 28195 28263 3 28195 28264 28196 3 28265 28196 28264 3 28196 28265 28197 3 28266 28197 28265 3 28197 28266 28198 3 28267 28198 28266 3 28198 28267 28199 3 28268 28199 28267 3 28199 28268 28200 3 28269 28200 28268 3 28200 28269 28201 3 28270 28201 28269 3 28201 28270 28202 3 28271 28202 28270 3 28202 28271 28203 3 28272 28203 28271 3 28203 28272 28204 3 28273 28204 28272 3 28204 28273 28205 3 28274 28205 28273 3 28205 28274 28206 3 28275 28206 28274 3 28206 28275 28207 3 28276 28207 28275 3 28207 28276 28208 3 28277 28208 28276 3 28208 28277 28209 3 28278 28209 28277 3 28209 28278 28210 3 28279 28210 28278 3 28211 28280 28212 3 28281 28212 28280 3 28212 28281 28213 3 28282 28213 28281 3 28213 28282 28214 3 28283 28214 28282 3 28214 28283 28215 3 28284 28215 28283 3 28215 28284 28216 3 28285 28216 28284 3 28216 28285 28217 3 28286 28217 28285 3 28217 28286 28218 3 28287 28218 28286 3 28218 28287 28219 3 28288 28219 28287 3 28219 28288 28220 3 28289 28220 28288 3 28220 28289 28221 3 28290 28221 28289 3 28221 28290 28222 3 28291 28222 28290 3 28222 28291 28223 3 28292 28223 28291 3 28223 28292 28224 3 28293 28224 28292 3 28224 28293 28225 3 28294 28225 28293 3 28225 28294 28226 3 28295 28226 28294 3 28226 28295 28227 3 28296 28227 28295 3 28227 28296 28228 3 28297 28228 28296 3 28228 28297 28229 3 28298 28229 28297 3 28229 28298 28230 3 28299 28230 28298 3 28230 28299 28231 3 28300 28231 28299 3 28231 28300 28232 3 28301 28232 28300 3 28232 28301 28233 3 28302 28233 28301 3 28233 28302 28234 3 28303 28234 28302 3 28234 28303 28235 3 28304 28235 28303 3 28235 28304 28236 3 28305 28236 28304 3 28236 28305 28237 3 28306 28237 28305 3 28237 28306 28238 3 28307 28238 28306 3 28238 28307 28239 3 28308 28239 28307 3 28239 28308 28240 3 28309 28240 28308 3 28240 28309 28241 3 28310 28241 28309 3 28241 28310 28242 3 28311 28242 28310 3 28242 28311 28243 3 28312 28243 28311 3 28243 28312 28244 3 28313 28244 28312 3 28244 28313 28245 3 28314 28245 28313 3 28245 28314 28246 3 28315 28246 28314 3 28246 28315 28247 3 28316 28247 28315 3 28247 28316 28248 3 28317 28248 28316 3 28248 28317 28249 3 28318 28249 28317 3 28249 28318 28250 3 28319 28250 28318 3 28250 28319 28320 3 28250 28320 28251 3 28251 28320 28321 3 28251 28321 28252 3 28252 28321 28322 3 28252 28322 28253 3 28253 28322 28323 3 28253 28323 28254 3 28254 28323 28324 3 28254 28324 28255 3 28255 28324 28325 3 28255 28325 28256 3 28256 28325 28326 3 28256 28326 28257 3 28257 28326 28327 3 28257 28327 28258 3 28258 28327 28328 3 28258 28328 28259 3 28259 28328 28329 3 28259 28329 28260 3 28260 28329 28330 3 28260 28330 28261 3 28261 28330 28331 3 28261 28331 28262 3 28262 28331 28332 3 28262 28332 28263 3 28263 28332 28333 3 28263 28333 28264 3 28264 28333 28334 3 28264 28334 28265 3 28265 28334 28335 3 28265 28335 28266 3 28266 28335 28336 3 28266 28336 28267 3 28267 28336 28337 3 28267 28337 28268 3 28268 28337 28338 3 28268 28338 28269 3 28269 28338 28339 3 28269 28339 28270 3 28270 28339 28340 3 28270 28340 28271 3 28271 28340 28341 3 28271 28341 28272 3 28272 28341 28342 3 28272 28342 28273 3 28273 28342 28343 3 28273 28343 28274 3 28274 28343 28344 3 28274 28344 28275 3 28275 28344 28345 3 28275 28345 28276 3 28276 28345 28346 3 28276 28346 28277 3 28277 28346 28347 3 28277 28347 28278 3 28278 28347 28348 3 28278 28348 28279 3 28280 28349 28350 3 28280 28350 28281 3 28281 28350 28351 3 28281 28351 28282 3 28282 28351 28352 3 28282 28352 28283 3 28283 28352 28353 3 28283 28353 28284 3 28284 28353 28354 3 28284 28354 28285 3 28285 28354 28355 3 28285 28355 28286 3 28286 28355 28356 3 28286 28356 28287 3 28287 28356 28357 3 28287 28357 28288 3 28288 28357 28358 3 28288 28358 28289 3 28289 28358 28359 3 28289 28359 28290 3 28290 28359 28360 3 28290 28360 28291 3 28291 28360 28361 3 28291 28361 28292 3 28292 28361 28362 3 28292 28362 28293 3 28293 28362 28363 3 28293 28363 28294 3 28294 28363 28364 3 28294 28364 28295 3 28295 28364 28365 3 28295 28365 28296 3 28296 28365 28366 3 28296 28366 28297 3 28297 28366 28367 3 28297 28367 28298 3 28298 28367 28368 3 28298 28368 28299 3 28299 28368 28369 3 28299 28369 28300 3 28300 28369 28370 3 28300 28370 28301 3 28301 28370 28371 3 28301 28371 28302 3 28302 28371 28372 3 28302 28372 28303 3 28303 28372 28373 3 28303 28373 28304 3 28304 28373 28374 3 28304 28374 28305 3 28305 28374 28375 3 28305 28375 28306 3 28306 28375 28376 3 28306 28376 28307 3 28307 28376 28377 3 28307 28377 28308 3 28308 28377 28378 3 28308 28378 28309 3 28309 28378 28379 3 28309 28379 28310 3 28310 28379 28380 3 28310 28380 28311 3 28311 28380 28381 3 28311 28381 28312 3 28312 28381 28382 3 28312 28382 28313 3 28313 28382 28383 3 28313 28383 28314 3 28314 28383 28384 3 28314 28384 28315 3 28315 28384 28385 3 28315 28385 28316 3 28316 28385 28386 3 28316 28386 28317 3 28317 28386 28387 3 28317 28387 28318 3 28318 28387 28388 3 28318 28388 28319 3 28319 28388 28389 3 28319 28389 28320 3 28320 28389 28390 3 28320 28390 28321 3 28321 28390 28391 3 28321 28391 28322 3 28322 28391 28392 3 28322 28392 28323 3 28323 28392 28393 3 28323 28393 28324 3 28324 28393 28394 3 28324 28394 28325 3 28325 28394 28395 3 28325 28395 28326 3 28326 28395 28396 3 28326 28396 28327 3 28327 28396 28397 3 28327 28397 28328 3 28328 28397 28398 3 28328 28398 28329 3 28329 28398 28399 3 28329 28399 28330 3 28330 28399 28400 3 28330 28400 28331 3 28331 28400 28401 3 28331 28401 28332 3 28332 28401 28402 3 28332 28402 28333 3 28333 28402 28403 3 28333 28403 28334 3 28334 28403 28404 3 28334 28404 28335 3 28335 28404 28405 3 28335 28405 28336 3 28336 28405 28406 3 28336 28406 28337 3 28337 28406 28407 3 28337 28407 28338 3 28338 28407 28408 3 28338 28408 28339 3 28339 28408 28409 3 28339 28409 28340 3 28340 28409 28410 3 28340 28410 28341 3 28341 28410 28411 3 28341 28411 28342 3 28342 28411 28412 3 28342 28412 28343 3 28343 28412 28413 3 28343 28413 28344 3 28344 28413 28414 3 28344 28414 28345 3 28345 28414 28415 3 28345 28415 28346 3 28346 28415 28416 3 28346 28416 28347 3 28347 28416 28417 3 28347 28417 28348 3 28349 28418 28419 3 28349 28419 28350 3 28350 28419 28420 3 28350 28420 28351 3 28351 28420 28421 3 28351 28421 28352 3 28352 28421 28422 3 28352 28422 28353 3 28353 28422 28354 3 28423 28354 28422 3 28354 28423 28355 3 28424 28355 28423 3 28355 28424 28356 3 28425 28356 28424 3 28356 28425 28357 3 28426 28357 28425 3 28357 28426 28358 3 28427 28358 28426 3 28358 28427 28359 3 28428 28359 28427 3 28359 28428 28360 3 28429 28360 28428 3 28360 28429 28361 3 28430 28361 28429 3 28361 28430 28362 3 28431 28362 28430 3 28362 28431 28363 3 28432 28363 28431 3 28363 28432 28364 3 28433 28364 28432 3 28364 28433 28365 3 28434 28365 28433 3 28365 28434 28366 3 28435 28366 28434 3 28366 28435 28367 3 28436 28367 28435 3 28367 28436 28368 3 28437 28368 28436 3 28368 28437 28369 3 28438 28369 28437 3 28369 28438 28370 3 28439 28370 28438 3 28370 28439 28371 3 28440 28371 28439 3 28371 28440 28372 3 28441 28372 28440 3 28372 28441 28373 3 28442 28373 28441 3 28373 28442 28374 3 28443 28374 28442 3 28374 28443 28375 3 28444 28375 28443 3 28375 28444 28376 3 28445 28376 28444 3 28376 28445 28377 3 28446 28377 28445 3 28377 28446 28378 3 28447 28378 28446 3 28378 28447 28379 3 28448 28379 28447 3 28379 28448 28380 3 28449 28380 28448 3 28380 28449 28381 3 28450 28381 28449 3 28381 28450 28382 3 28451 28382 28450 3 28382 28451 28383 3 28452 28383 28451 3 28383 28452 28384 3 28453 28384 28452 3 28384 28453 28385 3 28454 28385 28453 3 28385 28454 28386 3 28455 28386 28454 3 28386 28455 28387 3 28456 28387 28455 3 28387 28456 28388 3 28457 28388 28456 3 28388 28457 28389 3 28458 28389 28457 3 28389 28458 28390 3 28459 28390 28458 3 28390 28459 28391 3 28460 28391 28459 3 28391 28460 28392 3 28461 28392 28460 3 28392 28461 28393 3 28462 28393 28461 3 28393 28462 28394 3 28463 28394 28462 3 28394 28463 28395 3 28464 28395 28463 3 28395 28464 28396 3 28465 28396 28464 3 28396 28465 28397 3 28466 28397 28465 3 28397 28466 28398 3 28467 28398 28466 3 28398 28467 28399 3 28468 28399 28467 3 28399 28468 28400 3 28469 28400 28468 3 28400 28469 28401 3 28470 28401 28469 3 28401 28470 28402 3 28471 28402 28470 3 28402 28471 28403 3 28472 28403 28471 3 28403 28472 28404 3 28473 28404 28472 3 28404 28473 28405 3 28474 28405 28473 3 28405 28474 28406 3 28475 28406 28474 3 28406 28475 28407 3 28476 28407 28475 3 28407 28476 28408 3 28477 28408 28476 3 28408 28477 28409 3 28478 28409 28477 3 28409 28478 28410 3 28479 28410 28478 3 28410 28479 28411 3 28480 28411 28479 3 28411 28480 28412 3 28481 28412 28480 3 28412 28481 28413 3 28482 28413 28481 3 28413 28482 28414 3 28483 28414 28482 3 28414 28483 28415 3 28484 28415 28483 3 28415 28484 28416 3 28485 28416 28484 3 28416 28485 28417 3 28486 28417 28485 3 28418 28487 28419 3 28488 28419 28487 3 28419 28488 28420 3 28489 28420 28488 3 28420 28489 28421 3 28490 28421 28489 3 28421 28490 28422 3 28491 28422 28490 3 28422 28491 28423 3 28492 28423 28491 3 28423 28492 28424 3 28493 28424 28492 3 28424 28493 28425 3 28494 28425 28493 3 28425 28494 28426 3 28495 28426 28494 3 28426 28495 28427 3 28496 28427 28495 3 28427 28496 28428 3 28497 28428 28496 3 28428 28497 28429 3 28498 28429 28497 3 28429 28498 28430 3 28499 28430 28498 3 28430 28499 28431 3 28500 28431 28499 3 28431 28500 28432 3 28501 28432 28500 3 28432 28501 28433 3 28502 28433 28501 3 28433 28502 28434 3 28503 28434 28502 3 28434 28503 28435 3 28504 28435 28503 3 28435 28504 28436 3 28505 28436 28504 3 28436 28505 28437 3 28506 28437 28505 3 28437 28506 28438 3 28507 28438 28506 3 28438 28507 28439 3 28508 28439 28507 3 28439 28508 28440 3 28509 28440 28508 3 28440 28509 28441 3 28510 28441 28509 3 28441 28510 28442 3 28511 28442 28510 3 28442 28511 28443 3 28512 28443 28511 3 28443 28512 28444 3 28513 28444 28512 3 28444 28513 28445 3 28514 28445 28513 3 28445 28514 28446 3 28515 28446 28514 3 28446 28515 28447 3 28516 28447 28515 3 28447 28516 28448 3 28517 28448 28516 3 28448 28517 28449 3 28518 28449 28517 3 28449 28518 28450 3 28519 28450 28518 3 28450 28519 28451 3 28520 28451 28519 3 28451 28520 28452 3 28521 28452 28520 3 28452 28521 28453 3 28522 28453 28521 3 28453 28522 28454 3 28523 28454 28522 3 28454 28523 28455 3 28524 28455 28523 3 28455 28524 28456 3 28525 28456 28524 3 28456 28525 28457 3 28526 28457 28525 3 28457 28526 28527 3 28457 28527 28458 3 28458 28527 28528 3 28458 28528 28459 3 28459 28528 28529 3 28459 28529 28460 3 28460 28529 28530 3 28460 28530 28461 3 28461 28530 28531 3 28461 28531 28462 3 28462 28531 28532 3 28462 28532 28463 3 28463 28532 28533 3 28463 28533 28464 3 28464 28533 28534 3 28464 28534 28465 3 28465 28534 28535 3 28465 28535 28466 3 28466 28535 28536 3 28466 28536 28467 3 28467 28536 28537 3 28467 28537 28468 3 28468 28537 28538 3 28468 28538 28469 3 28469 28538 28539 3 28469 28539 28470 3 28470 28539 28540 3 28470 28540 28471 3 28471 28540 28541 3 28471 28541 28472 3 28472 28541 28542 3 28472 28542 28473 3 28473 28542 28543 3 28473 28543 28474 3 28474 28543 28544 3 28474 28544 28475 3 28475 28544 28545 3 28475 28545 28476 3 28476 28545 28546 3 28476 28546 28477 3 28477 28546 28547 3 28477 28547 28478 3 28478 28547 28548 3 28478 28548 28479 3 28479 28548 28549 3 28479 28549 28480 3 28480 28549 28550 3 28480 28550 28481 3 28481 28550 28551 3 28481 28551 28482 3 28482 28551 28552 3 28482 28552 28483 3 28483 28552 28553 3 28483 28553 28484 3 28484 28553 28554 3 28484 28554 28485 3 28485 28554 28555 3 28485 28555 28486 3 28487 28556 28557 3 28487 28557 28488 3 28488 28557 28558 3 28488 28558 28489 3 28489 28558 28559 3 28489 28559 28490 3 28490 28559 28560 3 28490 28560 28491 3 28491 28560 28561 3 28491 28561 28492 3 28492 28561 28562 3 28492 28562 28493 3 28493 28562 28563 3 28493 28563 28494 3 28494 28563 28564 3 28494 28564 28495 3 28495 28564 28565 3 28495 28565 28496 3 28496 28565 28566 3 28496 28566 28497 3 28497 28566 28567 3 28497 28567 28498 3 28498 28567 28568 3 28498 28568 28499 3 28499 28568 28569 3 28499 28569 28500 3 28500 28569 28570 3 28500 28570 28501 3 28501 28570 28571 3 28501 28571 28502 3 28502 28571 28572 3 28502 28572 28503 3 28503 28572 28573 3 28503 28573 28504 3 28504 28573 28574 3 28504 28574 28505 3 28505 28574 28575 3 28505 28575 28506 3 28506 28575 28576 3 28506 28576 28507 3 28507 28576 28577 3 28507 28577 28508 3 28508 28577 28578 3 28508 28578 28509 3 28509 28578 28579 3 28509 28579 28510 3 28510 28579 28580 3 28510 28580 28511 3 28511 28580 28581 3 28511 28581 28512 3 28512 28581 28582 3 28512 28582 28513 3 28513 28582 28583 3 28513 28583 28514 3 28514 28583 28584 3 28514 28584 28515 3 28515 28584 28585 3 28515 28585 28516 3 28516 28585 28586 3 28516 28586 28517 3 28517 28586 28587 3 28517 28587 28518 3 28518 28587 28588 3 28518 28588 28519 3 28519 28588 28589 3 28519 28589 28520 3 28520 28589 28590 3 28520 28590 28521 3 28521 28590 28591 3 28521 28591 28522 3 28522 28591 28592 3 28522 28592 28523 3 28523 28592 28593 3 28523 28593 28524 3 28524 28593 28594 3 28524 28594 28525 3 28525 28594 28595 3 28525 28595 28526 3 28526 28595 28596 3 28526 28596 28527 3 28527 28596 28597 3 28527 28597 28528 3 28528 28597 28598 3 28528 28598 28529 3 28529 28598 28599 3 28529 28599 28530 3 28530 28599 28600 3 28530 28600 28531 3 28531 28600 28601 3 28531 28601 28532 3 28532 28601 28602 3 28532 28602 28533 3 28533 28602 28603 3 28533 28603 28534 3 28534 28603 28604 3 28534 28604 28535 3 28535 28604 28605 3 28535 28605 28536 3 28536 28605 28606 3 28536 28606 28537 3 28537 28606 28607 3 28537 28607 28538 3 28538 28607 28608 3 28538 28608 28539 3 28539 28608 28609 3 28539 28609 28540 3 28540 28609 28610 3 28540 28610 28541 3 28541 28610 28611 3 28541 28611 28542 3 28542 28611 28612 3 28542 28612 28543 3 28543 28612 28613 3 28543 28613 28544 3 28544 28613 28614 3 28544 28614 28545 3 28545 28614 28615 3 28545 28615 28546 3 28546 28615 28616 3 28546 28616 28547 3 28547 28616 28617 3 28547 28617 28548 3 28548 28617 28618 3 28548 28618 28549 3 28549 28618 28619 3 28549 28619 28550 3 28550 28619 28620 3 28550 28620 28551 3 28551 28620 28621 3 28551 28621 28552 3 28552 28621 28622 3 28552 28622 28553 3 28553 28622 28623 3 28553 28623 28554 3 28554 28623 28624 3 28554 28624 28555 3 28556 28625 28626 3 28556 28626 28557 3 28557 28626 28627 3 28557 28627 28558 3 28558 28627 28628 3 28558 28628 28559 3 28559 28628 28629 3 28559 28629 28560 3 28560 28629 28630 3 28560 28630 28561 3 28561 28630 28562 3 28631 28562 28630 3 28562 28631 28563 3 28632 28563 28631 3 28563 28632 28564 3 28633 28564 28632 3 28564 28633 28565 3 28634 28565 28633 3 28565 28634 28566 3 28635 28566 28634 3 28566 28635 28567 3 28636 28567 28635 3 28567 28636 28568 3 28637 28568 28636 3 28568 28637 28569 3 28638 28569 28637 3 28569 28638 28570 3 28639 28570 28638 3 28570 28639 28571 3 28640 28571 28639 3 28571 28640 28572 3 28641 28572 28640 3 28572 28641 28573 3 28642 28573 28641 3 28573 28642 28574 3 28643 28574 28642 3 28574 28643 28575 3 28644 28575 28643 3 28575 28644 28576 3 28645 28576 28644 3 28576 28645 28577 3 28646 28577 28645 3 28577 28646 28578 3 28647 28578 28646 3 28578 28647 28579 3 28648 28579 28647 3 28579 28648 28580 3 28649 28580 28648 3 28580 28649 28581 3 28650 28581 28649 3 28581 28650 28582 3 28651 28582 28650 3 28582 28651 28583 3 28652 28583 28651 3 28583 28652 28584 3 28653 28584 28652 3 28584 28653 28585 3 28654 28585 28653 3 28585 28654 28586 3 28655 28586 28654 3 28586 28655 28587 3 28656 28587 28655 3 28587 28656 28588 3 28657 28588 28656 3 28588 28657 28589 3 28658 28589 28657 3 28589 28658 28590 3 28659 28590 28658 3 28590 28659 28591 3 28660 28591 28659 3 28591 28660 28592 3 28661 28592 28660 3 28592 28661 28593 3 28662 28593 28661 3 28593 28662 28594 3 28663 28594 28662 3 28594 28663 28595 3 28664 28595 28663 3 28595 28664 28596 3 28665 28596 28664 3 28596 28665 28597 3 28666 28597 28665 3 28597 28666 28598 3 28667 28598 28666 3 28598 28667 28599 3 28668 28599 28667 3 28599 28668 28600 3 28669 28600 28668 3 28600 28669 28601 3 28670 28601 28669 3 28601 28670 28602 3 28671 28602 28670 3 28602 28671 28603 3 28672 28603 28671 3 28603 28672 28604 3 28673 28604 28672 3 28604 28673 28605 3 28674 28605 28673 3 28605 28674 28606 3 28675 28606 28674 3 28606 28675 28607 3 28676 28607 28675 3 28607 28676 28608 3 28677 28608 28676 3 28608 28677 28609 3 28678 28609 28677 3 28609 28678 28610 3 28679 28610 28678 3 28610 28679 28611 3 28680 28611 28679 3 28611 28680 28612 3 28681 28612 28680 3 28612 28681 28613 3 28682 28613 28681 3 28613 28682 28614 3 28683 28614 28682 3 28614 28683 28615 3 28684 28615 28683 3 28615 28684 28616 3 28685 28616 28684 3 28616 28685 28617 3 28686 28617 28685 3 28617 28686 28618 3 28687 28618 28686 3 28618 28687 28619 3 28688 28619 28687 3 28619 28688 28620 3 28689 28620 28688 3 28620 28689 28621 3 28690 28621 28689 3 28621 28690 28622 3 28691 28622 28690 3 28622 28691 28623 3 28692 28623 28691 3 28623 28692 28624 3 28693 28624 28692 3 28625 28694 28626 3 28695 28626 28694 3 28626 28695 28627 3 28696 28627 28695 3 28627 28696 28628 3 28697 28628 28696 3 28628 28697 28629 3 28698 28629 28697 3 28629 28698 28630 3 28699 28630 28698 3 28630 28699 28631 3 28700 28631 28699 3 28631 28700 28632 3 28701 28632 28700 3 28632 28701 28633 3 28702 28633 28701 3 28633 28702 28634 3 28703 28634 28702 3 28634 28703 28635 3 28704 28635 28703 3 28635 28704 28636 3 28705 28636 28704 3 28636 28705 28637 3 28706 28637 28705 3 28637 28706 28638 3 28707 28638 28706 3 28638 28707 28639 3 28708 28639 28707 3 28639 28708 28640 3 28709 28640 28708 3 28640 28709 28641 3 28710 28641 28709 3 28641 28710 28642 3 28711 28642 28710 3 28642 28711 28643 3 28712 28643 28711 3 28643 28712 28644 3 28713 28644 28712 3 28644 28713 28645 3 28714 28645 28713 3 28645 28714 28646 3 28715 28646 28714 3 28646 28715 28647 3 28716 28647 28715 3 28647 28716 28648 3 28717 28648 28716 3 28648 28717 28649 3 28718 28649 28717 3 28649 28718 28650 3 28719 28650 28718 3 28650 28719 28651 3 28720 28651 28719 3 28651 28720 28652 3 28721 28652 28720 3 28652 28721 28653 3 28722 28653 28721 3 28653 28722 28654 3 28723 28654 28722 3 28654 28723 28655 3 28724 28655 28723 3 28655 28724 28656 3 28725 28656 28724 3 28656 28725 28657 3 28726 28657 28725 3 28657 28726 28658 3 28727 28658 28726 3 28658 28727 28659 3 28728 28659 28727 3 28659 28728 28660 3 28729 28660 28728 3 28660 28729 28661 3 28730 28661 28729 3 28661 28730 28662 3 28731 28662 28730 3 28662 28731 28663 3 28732 28663 28731 3 28663 28732 28664 3 28733 28664 28732 3 28664 28733 28665 3 28734 28665 28733 3 28665 28734 28735 3 28665 28735 28666 3 28666 28735 28736 3 28666 28736 28667 3 28667 28736 28737 3 28667 28737 28668 3 28668 28737 28738 3 28668 28738 28669 3 28669 28738 28739 3 28669 28739 28670 3 28670 28739 28740 3 28670 28740 28671 3 28671 28740 28741 3 28671 28741 28672 3 28672 28741 28742 3 28672 28742 28673 3 28673 28742 28743 3 28673 28743 28674 3 28674 28743 28744 3 28674 28744 28675 3 28675 28744 28745 3 28675 28745 28676 3 28676 28745 28746 3 28676 28746 28677 3 28677 28746 28747 3 28677 28747 28678 3 28678 28747 28748 3 28678 28748 28679 3 28679 28748 28749 3 28679 28749 28680 3 28680 28749 28750 3 28680 28750 28681 3 28681 28750 28751 3 28681 28751 28682 3 28682 28751 28752 3 28682 28752 28683 3 28683 28752 28753 3 28683 28753 28684 3 28684 28753 28754 3 28684 28754 28685 3 28685 28754 28755 3 28685 28755 28686 3 28686 28755 28756 3 28686 28756 28687 3 28687 28756 28757 3 28687 28757 28688 3 28688 28757 28758 3 28688 28758 28689 3 28689 28758 28759 3 28689 28759 28690 3 28690 28759 28760 3 28690 28760 28691 3 28691 28760 28761 3 28691 28761 28692 3 28692 28761 28762 3 28692 28762 28693 3 28694 28763 28764 3 28694 28764 28695 3 28695 28764 28765 3 28695 28765 28696 3 28696 28765 28766 3 28696 28766 28697 3 28697 28766 28767 3 28697 28767 28698 3 28698 28767 28768 3 28698 28768 28699 3 28699 28768 28769 3 28699 28769 28700 3 28700 28769 28770 3 28700 28770 28701 3 28701 28770 28771 3 28701 28771 28702 3 28702 28771 28772 3 28702 28772 28703 3 28703 28772 28773 3 28703 28773 28704 3 28704 28773 28774 3 28704 28774 28705 3 28705 28774 28775 3 28705 28775 28706 3 28706 28775 28776 3 28706 28776 28707 3 28707 28776 28777 3 28707 28777 28708 3 28708 28777 28778 3 28708 28778 28709 3 28709 28778 28779 3 28709 28779 28710 3 28710 28779 28780 3 28710 28780 28711 3 28711 28780 28781 3 28711 28781 28712 3 28712 28781 28782 3 28712 28782 28713 3 28713 28782 28783 3 28713 28783 28714 3 28714 28783 28784 3 28714 28784 28715 3 28715 28784 28785 3 28715 28785 28716 3 28716 28785 28786 3 28716 28786 28717 3 28717 28786 28787 3 28717 28787 28718 3 28718 28787 28788 3 28718 28788 28719 3 28719 28788 28789 3 28719 28789 28720 3 28720 28789 28790 3 28720 28790 28721 3 28721 28790 28791 3 28721 28791 28722 3 28722 28791 28792 3 28722 28792 28723 3 28723 28792 28793 3 28723 28793 28724 3 28724 28793 28794 3 28724 28794 28725 3 28725 28794 28795 3 28725 28795 28726 3 28726 28795 28796 3 28726 28796 28727 3 28727 28796 28797 3 28727 28797 28728 3 28728 28797 28798 3 28728 28798 28729 3 28729 28798 28799 3 28729 28799 28730 3 28730 28799 28800 3 28730 28800 28731 3 28731 28800 28801 3 28731 28801 28732 3 28732 28801 28802 3 28732 28802 28733 3 28733 28802 28803 3 28733 28803 28734 3 28734 28803 28804 3 28734 28804 28735 3 28735 28804 28805 3 28735 28805 28736 3 28736 28805 28806 3 28736 28806 28737 3 28737 28806 28807 3 28737 28807 28738 3 28738 28807 28808 3 28738 28808 28739 3 28739 28808 28809 3 28739 28809 28740 3 28740 28809 28810 3 28740 28810 28741 3 28741 28810 28811 3 28741 28811 28742 3 28742 28811 28812 3 28742 28812 28743 3 28743 28812 28813 3 28743 28813 28744 3 28744 28813 28814 3 28744 28814 28745 3 28745 28814 28815 3 28745 28815 28746 3 28746 28815 28816 3 28746 28816 28747 3 28747 28816 28817 3 28747 28817 28748 3 28748 28817 28818 3 28748 28818 28749 3 28749 28818 28819 3 28749 28819 28750 3 28750 28819 28820 3 28750 28820 28751 3 28751 28820 28821 3 28751 28821 28752 3 28752 28821 28822 3 28752 28822 28753 3 28753 28822 28823 3 28753 28823 28754 3 28754 28823 28824 3 28754 28824 28755 3 28755 28824 28825 3 28755 28825 28756 3 28756 28825 28826 3 28756 28826 28757 3 28757 28826 28827 3 28757 28827 28758 3 28758 28827 28828 3 28758 28828 28759 3 28759 28828 28829 3 28759 28829 28760 3 28760 28829 28830 3 28760 28830 28761 3 28761 28830 28831 3 28761 28831 28762 3 28763 28832 28833 3 28763 28833 28764 3 28764 28833 28834 3 28764 28834 28765 3 28765 28834 28835 3 28765 28835 28766 3 28766 28835 28836 3 28766 28836 28767 3 28767 28836 28837 3 28767 28837 28768 3 28768 28837 28838 3 28768 28838 28769 3 28769 28838 28839 3 28769 28839 28770 3 28770 28839 28771 3 28840 28771 28839 3 28771 28840 28772 3 28841 28772 28840 3 28772 28841 28773 3 28842 28773 28841 3 28773 28842 28774 3 28843 28774 28842 3 28774 28843 28775 3 28844 28775 28843 3 28775 28844 28776 3 28845 28776 28844 3 28776 28845 28777 3 28846 28777 28845 3 28777 28846 28778 3 28847 28778 28846 3 28778 28847 28779 3 28848 28779 28847 3 28779 28848 28780 3 28849 28780 28848 3 28780 28849 28781 3 28850 28781 28849 3 28781 28850 28782 3 28851 28782 28850 3 28782 28851 28783 3 28852 28783 28851 3 28783 28852 28784 3 28853 28784 28852 3 28784 28853 28785 3 28854 28785 28853 3 28785 28854 28786 3 28855 28786 28854 3 28786 28855 28787 3 28856 28787 28855 3 28787 28856 28788 3 28857 28788 28856 3 28788 28857 28789 3 28858 28789 28857 3 28789 28858 28790 3 28859 28790 28858 3 28790 28859 28791 3 28860 28791 28859 3 28791 28860 28792 3 28861 28792 28860 3 28792 28861 28793 3 28862 28793 28861 3 28793 28862 28794 3 28863 28794 28862 3 28794 28863 28795 3 28864 28795 28863 3 28795 28864 28796 3 28865 28796 28864 3 28796 28865 28797 3 28866 28797 28865 3 28797 28866 28798 3 28867 28798 28866 3 28798 28867 28799 3 28868 28799 28867 3 28799 28868 28800 3 28869 28800 28868 3 28800 28869 28801 3 28870 28801 28869 3 28801 28870 28802 3 28871 28802 28870 3 28802 28871 28803 3 28872 28803 28871 3 28803 28872 28804 3 28873 28804 28872 3 28804 28873 28805 3 28874 28805 28873 3 28805 28874 28806 3 28875 28806 28874 3 28806 28875 28807 3 28876 28807 28875 3 28807 28876 28808 3 28877 28808 28876 3 28808 28877 28809 3 28878 28809 28877 3 28809 28878 28810 3 28879 28810 28878 3 28810 28879 28811 3 28880 28811 28879 3 28811 28880 28812 3 28881 28812 28880 3 28812 28881 28813 3 28882 28813 28881 3 28813 28882 28814 3 28883 28814 28882 3 28814 28883 28815 3 28884 28815 28883 3 28815 28884 28816 3 28885 28816 28884 3 28816 28885 28817 3 28886 28817 28885 3 28817 28886 28818 3 28887 28818 28886 3 28818 28887 28819 3 28888 28819 28887 3 28819 28888 28820 3 28889 28820 28888 3 28820 28889 28821 3 28890 28821 28889 3 28821 28890 28822 3 28891 28822 28890 3 28822 28891 28823 3 28892 28823 28891 3 28823 28892 28824 3 28893 28824 28892 3 28824 28893 28825 3 28894 28825 28893 3 28825 28894 28826 3 28895 28826 28894 3 28826 28895 28827 3 28896 28827 28895 3 28827 28896 28828 3 28897 28828 28896 3 28828 28897 28829 3 28898 28829 28897 3 28829 28898 28830 3 28899 28830 28898 3 28830 28899 28831 3 28900 28831 28899 3 28832 28901 28833 3 28902 28833 28901 3 28833 28902 28834 3 28903 28834 28902 3 28834 28903 28835 3 28904 28835 28903 3 28835 28904 28836 3 28905 28836 28904 3 28836 28905 28837 3 28906 28837 28905 3 28837 28906 28838 3 28907 28838 28906 3 28838 28907 28839 3 28908 28839 28907 3 28839 28908 28840 3 28909 28840 28908 3 28840 28909 28841 3 28910 28841 28909 3 28841 28910 28842 3 28911 28842 28910 3 28842 28911 28843 3 28912 28843 28911 3 28843 28912 28844 3 28913 28844 28912 3 28844 28913 28845 3 28914 28845 28913 3 28845 28914 28846 3 28915 28846 28914 3 28846 28915 28847 3 28916 28847 28915 3 28847 28916 28848 3 28917 28848 28916 3 28848 28917 28849 3 28918 28849 28917 3 28849 28918 28850 3 28919 28850 28918 3 28850 28919 28851 3 28920 28851 28919 3 28851 28920 28852 3 28921 28852 28920 3 28852 28921 28853 3 28922 28853 28921 3 28853 28922 28854 3 28923 28854 28922 3 28854 28923 28855 3 28924 28855 28923 3 28855 28924 28856 3 28925 28856 28924 3 28856 28925 28857 3 28926 28857 28925 3 28857 28926 28858 3 28927 28858 28926 3 28858 28927 28859 3 28928 28859 28927 3 28859 28928 28860 3 28929 28860 28928 3 28860 28929 28861 3 28930 28861 28929 3 28861 28930 28862 3 28931 28862 28930 3 28862 28931 28863 3 28932 28863 28931 3 28863 28932 28864 3 28933 28864 28932 3 28864 28933 28865 3 28934 28865 28933 3 28865 28934 28866 3 28935 28866 28934 3 28866 28935 28867 3 28936 28867 28935 3 28867 28936 28868 3 28937 28868 28936 3 28868 28937 28869 3 28938 28869 28937 3 28869 28938 28870 3 28939 28870 28938 3 28870 28939 28871 3 28940 28871 28939 3 28871 28940 28872 3 28941 28872 28940 3 28872 28941 28873 3 28942 28873 28941 3 28873 28942 28874 3 28943 28874 28942 3 28874 28943 28944 3 28874 28944 28875 3 28875 28944 28945 3 28875 28945 28876 3 28876 28945 28946 3 28876 28946 28877 3 28877 28946 28947 3 28877 28947 28878 3 28878 28947 28948 3 28878 28948 28879 3 28879 28948 28949 3 28879 28949 28880 3 28880 28949 28950 3 28880 28950 28881 3 28881 28950 28951 3 28881 28951 28882 3 28882 28951 28952 3 28882 28952 28883 3 28883 28952 28953 3 28883 28953 28884 3 28884 28953 28954 3 28884 28954 28885 3 28885 28954 28955 3 28885 28955 28886 3 28886 28955 28956 3 28886 28956 28887 3 28887 28956 28957 3 28887 28957 28888 3 28888 28957 28958 3 28888 28958 28889 3 28889 28958 28959 3 28889 28959 28890 3 28890 28959 28960 3 28890 28960 28891 3 28891 28960 28961 3 28891 28961 28892 3 28892 28961 28962 3 28892 28962 28893 3 28893 28962 28963 3 28893 28963 28894 3 28894 28963 28964 3 28894 28964 28895 3 28895 28964 28965 3 28895 28965 28896 3 28896 28965 28966 3 28896 28966 28897 3 28897 28966 28967 3 28897 28967 28898 3 28898 28967 28968 3 28898 28968 28899 3 28899 28968 28969 3 28899 28969 28900 3 28901 28970 28971 3 28901 28971 28902 3 28902 28971 28972 3 28902 28972 28903 3 28903 28972 28973 3 28903 28973 28904 3 28904 28973 28974 3 28904 28974 28905 3 28905 28974 28975 3 28905 28975 28906 3 28906 28975 28976 3 28906 28976 28907 3 28907 28976 28977 3 28907 28977 28908 3 28908 28977 28978 3 28908 28978 28909 3 28909 28978 28979 3 28909 28979 28910 3 28910 28979 28980 3 28910 28980 28911 3 28911 28980 28981 3 28911 28981 28912 3 28912 28981 28982 3 28912 28982 28913 3 28913 28982 28983 3 28913 28983 28914 3 28914 28983 28984 3 28914 28984 28915 3 28915 28984 28985 3 28915 28985 28916 3 28916 28985 28986 3 28916 28986 28917 3 28917 28986 28987 3 28917 28987 28918 3 28918 28987 28988 3 28918 28988 28919 3 28919 28988 28989 3 28919 28989 28920 3 28920 28989 28990 3 28920 28990 28921 3 28921 28990 28991 3 28921 28991 28922 3 28922 28991 28992 3 28922 28992 28923 3 28923 28992 28993 3 28923 28993 28924 3 28924 28993 28994 3 28924 28994 28925 3 28925 28994 28995 3 28925 28995 28926 3 28926 28995 28996 3 28926 28996 28927 3 28927 28996 28997 3 28927 28997 28928 3 28928 28997 28998 3 28928 28998 28929 3 28929 28998 28999 3 28929 28999 28930 3 28930 28999 29000 3 28930 29000 28931 3 28931 29000 29001 3 28931 29001 28932 3 28932 29001 29002 3 28932 29002 28933 3 28933 29002 29003 3 28933 29003 28934 3 28934 29003 29004 3 28934 29004 28935 3 28935 29004 29005 3 28935 29005 28936 3 28936 29005 29006 3 28936 29006 28937 3 28937 29006 29007 3 28937 29007 28938 3 28938 29007 29008 3 28938 29008 28939 3 28939 29008 29009 3 28939 29009 28940 3 28940 29009 29010 3 28940 29010 28941 3 28941 29010 29011 3 28941 29011 28942 3 28942 29011 29012 3 28942 29012 28943 3 28943 29012 29013 3 28943 29013 28944 3 28944 29013 29014 3 28944 29014 28945 3 28945 29014 29015 3 28945 29015 28946 3 28946 29015 29016 3 28946 29016 28947 3 28947 29016 29017 3 28947 29017 28948 3 28948 29017 29018 3 28948 29018 28949 3 28949 29018 29019 3 28949 29019 28950 3 28950 29019 29020 3 28950 29020 28951 3 28951 29020 29021 3 28951 29021 28952 3 28952 29021 29022 3 28952 29022 28953 3 28953 29022 29023 3 28953 29023 28954 3 28954 29023 29024 3 28954 29024 28955 3 28955 29024 29025 3 28955 29025 28956 3 28956 29025 29026 3 28956 29026 28957 3 28957 29026 29027 3 28957 29027 28958 3 28958 29027 29028 3 28958 29028 28959 3 28959 29028 29029 3 28959 29029 28960 3 28960 29029 29030 3 28960 29030 28961 3 28961 29030 29031 3 28961 29031 28962 3 28962 29031 29032 3 28962 29032 28963 3 28963 29032 29033 3 28963 29033 28964 3 28964 29033 29034 3 28964 29034 28965 3 28965 29034 29035 3 28965 29035 28966 3 28966 29035 29036 3 28966 29036 28967 3 28967 29036 29037 3 28967 29037 28968 3 28968 29037 29038 3 28968 29038 28969 3 28970 29039 29040 3 28970 29040 28971 3 28971 29040 29041 3 28971 29041 28972 3 28972 29041 29042 3 28972 29042 28973 3 28973 29042 29043 3 28973 29043 28974 3 28974 29043 29044 3 28974 29044 28975 3 28975 29044 29045 3 28975 29045 28976 3 28976 29045 29046 3 28976 29046 28977 3 28977 29046 29047 3 28977 29047 28978 3 28978 29047 29048 3 28978 29048 28979 3 28979 29048 28980 3 29049 28980 29048 3 28980 29049 28981 3 29050 28981 29049 3 28981 29050 28982 3 29051 28982 29050 3 28982 29051 28983 3 29052 28983 29051 3 28983 29052 28984 3 29053 28984 29052 3 28984 29053 28985 3 29054 28985 29053 3 28985 29054 28986 3 29055 28986 29054 3 28986 29055 28987 3 29056 28987 29055 3 28987 29056 28988 3 29057 28988 29056 3 28988 29057 28989 3 29058 28989 29057 3 28989 29058 28990 3 29059 28990 29058 3 28990 29059 28991 3 29060 28991 29059 3 28991 29060 28992 3 29061 28992 29060 3 28992 29061 28993 3 29062 28993 29061 3 28993 29062 28994 3 29063 28994 29062 3 28994 29063 28995 3 29064 28995 29063 3 28995 29064 28996 3 29065 28996 29064 3 28996 29065 28997 3 29066 28997 29065 3 28997 29066 28998 3 29067 28998 29066 3 28998 29067 28999 3 29068 28999 29067 3 28999 29068 29000 3 29069 29000 29068 3 29000 29069 29001 3 29070 29001 29069 3 29001 29070 29002 3 29071 29002 29070 3 29002 29071 29003 3 29072 29003 29071 3 29003 29072 29004 3 29073 29004 29072 3 29004 29073 29005 3 29074 29005 29073 3 29005 29074 29006 3 29075 29006 29074 3 29006 29075 29007 3 29076 29007 29075 3 29007 29076 29008 3 29077 29008 29076 3 29008 29077 29009 3 29078 29009 29077 3 29009 29078 29010 3 29079 29010 29078 3 29010 29079 29011 3 29080 29011 29079 3 29011 29080 29012 3 29081 29012 29080 3 29012 29081 29013 3 29082 29013 29081 3 29013 29082 29014 3 29083 29014 29082 3 29014 29083 29015 3 29084 29015 29083 3 29015 29084 29016 3 29085 29016 29084 3 29016 29085 29017 3 29086 29017 29085 3 29017 29086 29018 3 29087 29018 29086 3 29018 29087 29019 3 29088 29019 29087 3 29019 29088 29020 3 29089 29020 29088 3 29020 29089 29021 3 29090 29021 29089 3 29021 29090 29022 3 29091 29022 29090 3 29022 29091 29023 3 29092 29023 29091 3 29023 29092 29024 3 29093 29024 29092 3 29024 29093 29025 3 29094 29025 29093 3 29025 29094 29026 3 29095 29026 29094 3 29026 29095 29027 3 29096 29027 29095 3 29027 29096 29028 3 29097 29028 29096 3 29028 29097 29029 3 29098 29029 29097 3 29029 29098 29030 3 29099 29030 29098 3 29030 29099 29031 3 29100 29031 29099 3 29031 29100 29032 3 29101 29032 29100 3 29032 29101 29033 3 29102 29033 29101 3 29033 29102 29034 3 29103 29034 29102 3 29034 29103 29035 3 29104 29035 29103 3 29035 29104 29036 3 29105 29036 29104 3 29036 29105 29037 3 29106 29037 29105 3 29037 29106 29038 3 29107 29038 29106 3 29039 29108 29040 3 29109 29040 29108 3 29040 29109 29041 3 29110 29041 29109 3 29041 29110 29042 3 29111 29042 29110 3 29042 29111 29043 3 29112 29043 29111 3 29043 29112 29044 3 29113 29044 29112 3 29044 29113 29045 3 29114 29045 29113 3 29045 29114 29046 3 29115 29046 29114 3 29046 29115 29047 3 29116 29047 29115 3 29047 29116 29048 3 29117 29048 29116 3 29048 29117 29049 3 29118 29049 29117 3 29049 29118 29050 3 29119 29050 29118 3 29050 29119 29051 3 29120 29051 29119 3 29051 29120 29052 3 29121 29052 29120 3 29052 29121 29053 3 29122 29053 29121 3 29053 29122 29054 3 29123 29054 29122 3 29054 29123 29055 3 29124 29055 29123 3 29055 29124 29056 3 29125 29056 29124 3 29056 29125 29057 3 29126 29057 29125 3 29057 29126 29058 3 29127 29058 29126 3 29058 29127 29059 3 29128 29059 29127 3 29059 29128 29060 3 29129 29060 29128 3 29060 29129 29061 3 29130 29061 29129 3 29061 29130 29062 3 29131 29062 29130 3 29062 29131 29063 3 29132 29063 29131 3 29063 29132 29064 3 29133 29064 29132 3 29064 29133 29065 3 29134 29065 29133 3 29065 29134 29066 3 29135 29066 29134 3 29066 29135 29067 3 29136 29067 29135 3 29067 29136 29068 3 29137 29068 29136 3 29068 29137 29069 3 29138 29069 29137 3 29069 29138 29070 3 29139 29070 29138 3 29070 29139 29071 3 29140 29071 29139 3 29071 29140 29072 3 29141 29072 29140 3 29072 29141 29073 3 29142 29073 29141 3 29073 29142 29074 3 29143 29074 29142 3 29074 29143 29075 3 29144 29075 29143 3 29075 29144 29076 3 29145 29076 29144 3 29076 29145 29077 3 29146 29077 29145 3 29077 29146 29078 3 29147 29078 29146 3 29078 29147 29079 3 29148 29079 29147 3 29079 29148 29080 3 29149 29080 29148 3 29080 29149 29081 3 29150 29081 29149 3 29081 29150 29082 3 29151 29082 29150 3 29082 29151 29083 3 29152 29083 29151 3 29083 29152 29084 3 29153 29084 29152 3 29084 29153 29154 3 29084 29154 29085 3 29085 29154 29155 3 29085 29155 29086 3 29086 29155 29156 3 29086 29156 29087 3 29087 29156 29157 3 29087 29157 29088 3 29088 29157 29158 3 29088 29158 29089 3 29089 29158 29159 3 29089 29159 29090 3 29090 29159 29160 3 29090 29160 29091 3 29091 29160 29161 3 29091 29161 29092 3 29092 29161 29162 3 29092 29162 29093 3 29093 29162 29163 3 29093 29163 29094 3 29094 29163 29164 3 29094 29164 29095 3 29095 29164 29165 3 29095 29165 29096 3 29096 29165 29166 3 29096 29166 29097 3 29097 29166 29167 3 29097 29167 29098 3 29098 29167 29168 3 29098 29168 29099 3 29099 29168 29169 3 29099 29169 29100 3 29100 29169 29170 3 29100 29170 29101 3 29101 29170 29171 3 29101 29171 29102 3 29102 29171 29172 3 29102 29172 29103 3 29103 29172 29173 3 29103 29173 29104 3 29104 29173 29174 3 29104 29174 29105 3 29105 29174 29175 3 29105 29175 29106 3 29106 29175 29176 3 29106 29176 29107 3 29108 29177 29178 3 29108 29178 29109 3 29109 29178 29179 3 29109 29179 29110 3 29110 29179 29180 3 29110 29180 29111 3 29111 29180 29181 3 29111 29181 29112 3 29112 29181 29182 3 29112 29182 29113 3 29113 29182 29183 3 29113 29183 29114 3 29114 29183 29184 3 29114 29184 29115 3 29115 29184 29185 3 29115 29185 29116 3 29116 29185 29186 3 29116 29186 29117 3 29117 29186 29187 3 29117 29187 29118 3 29118 29187 29188 3 29118 29188 29119 3 29119 29188 29189 3 29119 29189 29120 3 29120 29189 29190 3 29120 29190 29121 3 29121 29190 29191 3 29121 29191 29122 3 29122 29191 29192 3 29122 29192 29123 3 29123 29192 29193 3 29123 29193 29124 3 29124 29193 29194 3 29124 29194 29125 3 29125 29194 29195 3 29125 29195 29126 3 29126 29195 29196 3 29126 29196 29127 3 29127 29196 29197 3 29127 29197 29128 3 29128 29197 29198 3 29128 29198 29129 3 29129 29198 29199 3 29129 29199 29130 3 29130 29199 29200 3 29130 29200 29131 3 29131 29200 29201 3 29131 29201 29132 3 29132 29201 29202 3 29132 29202 29133 3 29133 29202 29203 3 29133 29203 29134 3 29134 29203 29204 3 29134 29204 29135 3 29135 29204 29205 3 29135 29205 29136 3 29136 29205 29206 3 29136 29206 29137 3 29137 29206 29207 3 29137 29207 29138 3 29138 29207 29208 3 29138 29208 29139 3 29139 29208 29209 3 29139 29209 29140 3 29140 29209 29210 3 29140 29210 29141 3 29141 29210 29211 3 29141 29211 29142 3 29142 29211 29212 3 29142 29212 29143 3 29143 29212 29213 3 29143 29213 29144 3 29144 29213 29214 3 29144 29214 29145 3 29145 29214 29215 3 29145 29215 29146 3 29146 29215 29216 3 29146 29216 29147 3 29147 29216 29217 3 29147 29217 29148 3 29148 29217 29218 3 29148 29218 29149 3 29149 29218 29219 3 29149 29219 29150 3 29150 29219 29220 3 29150 29220 29151 3 29151 29220 29221 3 29151 29221 29152 3 29152 29221 29222 3 29152 29222 29153 3 29153 29222 29223 3 29153 29223 29154 3 29154 29223 29224 3 29154 29224 29155 3 29155 29224 29225 3 29155 29225 29156 3 29156 29225 29226 3 29156 29226 29157 3 29157 29226 29227 3 29157 29227 29158 3 29158 29227 29228 3 29158 29228 29159 3 29159 29228 29229 3 29159 29229 29160 3 29160 29229 29230 3 29160 29230 29161 3 29161 29230 29231 3 29161 29231 29162 3 29162 29231 29232 3 29162 29232 29163 3 29163 29232 29233 3 29163 29233 29164 3 29164 29233 29234 3 29164 29234 29165 3 29165 29234 29235 3 29165 29235 29166 3 29166 29235 29236 3 29166 29236 29167 3 29167 29236 29237 3 29167 29237 29168 3 29168 29237 29238 3 29168 29238 29169 3 29169 29238 29239 3 29169 29239 29170 3 29170 29239 29240 3 29170 29240 29171 3 29171 29240 29241 3 29171 29241 29172 3 29172 29241 29242 3 29172 29242 29173 3 29173 29242 29243 3 29173 29243 29174 3 29174 29243 29244 3 29174 29244 29175 3 29175 29244 29245 3 29175 29245 29176 3 29177 29246 29247 3 29177 29247 29178 3 29178 29247 29248 3 29178 29248 29179 3 29179 29248 29249 3 29179 29249 29180 3 29180 29249 29250 3 29180 29250 29181 3 29181 29250 29251 3 29181 29251 29182 3 29182 29251 29252 3 29182 29252 29183 3 29183 29252 29253 3 29183 29253 29184 3 29184 29253 29254 3 29184 29254 29185 3 29185 29254 29255 3 29185 29255 29186 3 29186 29255 29256 3 29186 29256 29187 3 29187 29256 29257 3 29187 29257 29188 3 29188 29257 29258 3 29188 29258 29189 3 29189 29258 29190 3 29259 29190 29258 3 29190 29259 29191 3 29260 29191 29259 3 29191 29260 29192 3 29261 29192 29260 3 29192 29261 29193 3 29262 29193 29261 3 29193 29262 29194 3 29263 29194 29262 3 29194 29263 29195 3 29264 29195 29263 3 29195 29264 29196 3 29265 29196 29264 3 29196 29265 29197 3 29266 29197 29265 3 29197 29266 29198 3 29267 29198 29266 3 29198 29267 29199 3 29268 29199 29267 3 29199 29268 29200 3 29269 29200 29268 3 29200 29269 29201 3 29270 29201 29269 3 29201 29270 29202 3 29271 29202 29270 3 29202 29271 29203 3 29272 29203 29271 3 29203 29272 29204 3 29273 29204 29272 3 29204 29273 29205 3 29274 29205 29273 3 29205 29274 29206 3 29275 29206 29274 3 29206 29275 29207 3 29276 29207 29275 3 29207 29276 29208 3 29277 29208 29276 3 29208 29277 29209 3 29278 29209 29277 3 29209 29278 29210 3 29279 29210 29278 3 29210 29279 29211 3 29280 29211 29279 3 29211 29280 29212 3 29281 29212 29280 3 29212 29281 29213 3 29282 29213 29281 3 29213 29282 29214 3 29283 29214 29282 3 29214 29283 29215 3 29284 29215 29283 3 29215 29284 29216 3 29285 29216 29284 3 29216 29285 29217 3 29286 29217 29285 3 29217 29286 29218 3 29287 29218 29286 3 29218 29287 29219 3 29288 29219 29287 3 29219 29288 29220 3 29289 29220 29288 3 29220 29289 29221 3 29290 29221 29289 3 29221 29290 29222 3 29291 29222 29290 3 29222 29291 29223 3 29292 29223 29291 3 29223 29292 29224 3 29293 29224 29292 3 29224 29293 29225 3 29294 29225 29293 3 29225 29294 29226 3 29295 29226 29294 3 29226 29295 29227 3 29296 29227 29295 3 29227 29296 29228 3 29297 29228 29296 3 29228 29297 29229 3 29298 29229 29297 3 29229 29298 29230 3 29299 29230 29298 3 29230 29299 29231 3 29300 29231 29299 3 29231 29300 29232 3 29301 29232 29300 3 29232 29301 29233 3 29302 29233 29301 3 29233 29302 29234 3 29303 29234 29302 3 29234 29303 29235 3 29304 29235 29303 3 29235 29304 29236 3 29305 29236 29304 3 29236 29305 29237 3 29306 29237 29305 3 29237 29306 29238 3 29307 29238 29306 3 29238 29307 29239 3 29308 29239 29307 3 29239 29308 29240 3 29309 29240 29308 3 29240 29309 29241 3 29310 29241 29309 3 29241 29310 29242 3 29311 29242 29310 3 29242 29311 29243 3 29312 29243 29311 3 29243 29312 29244 3 29313 29244 29312 3 29244 29313 29245 3 29314 29245 29313 3 29246 29315 29247 3 29316 29247 29315 3 29247 29316 29248 3 29317 29248 29316 3 29248 29317 29249 3 29318 29249 29317 3 29249 29318 29250 3 29319 29250 29318 3 29250 29319 29251 3 29320 29251 29319 3 29251 29320 29252 3 29321 29252 29320 3 29252 29321 29253 3 29322 29253 29321 3 29253 29322 29254 3 29323 29254 29322 3 29254 29323 29255 3 29324 29255 29323 3 29255 29324 29256 3 29325 29256 29324 3 29256 29325 29257 3 29326 29257 29325 3 29257 29326 29258 3 29327 29258 29326 3 29258 29327 29259 3 29328 29259 29327 3 29259 29328 29260 3 29329 29260 29328 3 29260 29329 29261 3 29330 29261 29329 3 29261 29330 29262 3 29331 29262 29330 3 29262 29331 29263 3 29332 29263 29331 3 29263 29332 29264 3 29333 29264 29332 3 29264 29333 29265 3 29334 29265 29333 3 29265 29334 29266 3 29335 29266 29334 3 29266 29335 29267 3 29336 29267 29335 3 29267 29336 29268 3 29337 29268 29336 3 29268 29337 29269 3 29338 29269 29337 3 29269 29338 29270 3 29339 29270 29338 3 29270 29339 29271 3 29340 29271 29339 3 29271 29340 29272 3 29341 29272 29340 3 29272 29341 29273 3 29342 29273 29341 3 29273 29342 29274 3 29343 29274 29342 3 29274 29343 29275 3 29344 29275 29343 3 29275 29344 29276 3 29345 29276 29344 3 29276 29345 29277 3 29346 29277 29345 3 29277 29346 29278 3 29347 29278 29346 3 29278 29347 29279 3 29348 29279 29347 3 29279 29348 29280 3 29349 29280 29348 3 29280 29349 29281 3 29350 29281 29349 3 29281 29350 29282 3 29351 29282 29350 3 29282 29351 29283 3 29352 29283 29351 3 29283 29352 29284 3 29353 29284 29352 3 29284 29353 29285 3 29354 29285 29353 3 29285 29354 29286 3 29355 29286 29354 3 29286 29355 29287 3 29356 29287 29355 3 29287 29356 29288 3 29357 29288 29356 3 29288 29357 29289 3 29358 29289 29357 3 29289 29358 29290 3 29359 29290 29358 3 29290 29359 29291 3 29360 29291 29359 3 29291 29360 29292 3 29361 29292 29360 3 29292 29361 29293 3 29362 29293 29361 3 29293 29362 29294 3 29363 29294 29362 3 29294 29363 29295 3 29364 29295 29363 3 29295 29364 29365 3 29295 29365 29296 3 29296 29365 29366 3 29296 29366 29297 3 29297 29366 29367 3 29297 29367 29298 3 29298 29367 29368 3 29298 29368 29299 3 29299 29368 29369 3 29299 29369 29300 3 29300 29369 29370 3 29300 29370 29301 3 29301 29370 29371 3 29301 29371 29302 3 29302 29371 29372 3 29302 29372 29303 3 29303 29372 29373 3 29303 29373 29304 3 29304 29373 29374 3 29304 29374 29305 3 29305 29374 29375 3 29305 29375 29306 3 29306 29375 29376 3 29306 29376 29307 3 29307 29376 29377 3 29307 29377 29308 3 29308 29377 29378 3 29308 29378 29309 3 29309 29378 29379 3 29309 29379 29310 3 29310 29379 29380 3 29310 29380 29311 3 29311 29380 29381 3 29311 29381 29312 3 29312 29381 29382 3 29312 29382 29313 3 29313 29382 29383 3 29313 29383 29314 3 29315 29384 29385 3 29315 29385 29316 3 29316 29385 29386 3 29316 29386 29317 3 29317 29386 29387 3 29317 29387 29318 3 29318 29387 29388 3 29318 29388 29319 3 29319 29388 29389 3 29319 29389 29320 3 29320 29389 29390 3 29320 29390 29321 3 29321 29390 29391 3 29321 29391 29322 3 29322 29391 29392 3 29322 29392 29323 3 29323 29392 29393 3 29323 29393 29324 3 29324 29393 29394 3 29324 29394 29325 3 29325 29394 29395 3 29325 29395 29326 3 29326 29395 29396 3 29326 29396 29327 3 29327 29396 29397 3 29327 29397 29328 3 29328 29397 29398 3 29328 29398 29329 3 29329 29398 29399 3 29329 29399 29330 3 29330 29399 29400 3 29330 29400 29331 3 29331 29400 29401 3 29331 29401 29332 3 29332 29401 29402 3 29332 29402 29333 3 29333 29402 29403 3 29333 29403 29334 3 29334 29403 29404 3 29334 29404 29335 3 29335 29404 29405 3 29335 29405 29336 3 29336 29405 29406 3 29336 29406 29337 3 29337 29406 29407 3 29337 29407 29338 3 29338 29407 29408 3 29338 29408 29339 3 29339 29408 29409 3 29339 29409 29340 3 29340 29409 29410 3 29340 29410 29341 3 29341 29410 29411 3 29341 29411 29342 3 29342 29411 29412 3 29342 29412 29343 3 29343 29412 29413 3 29343 29413 29344 3 29344 29413 29414 3 29344 29414 29345 3 29345 29414 29415 3 29345 29415 29346 3 29346 29415 29416 3 29346 29416 29347 3 29347 29416 29417 3 29347 29417 29348 3 29348 29417 29418 3 29348 29418 29349 3 29349 29418 29419 3 29349 29419 29350 3 29350 29419 29420 3 29350 29420 29351 3 29351 29420 29421 3 29351 29421 29352 3 29352 29421 29422 3 29352 29422 29353 3 29353 29422 29423 3 29353 29423 29354 3 29354 29423 29424 3 29354 29424 29355 3 29355 29424 29425 3 29355 29425 29356 3 29356 29425 29426 3 29356 29426 29357 3 29357 29426 29427 3 29357 29427 29358 3 29358 29427 29428 3 29358 29428 29359 3 29359 29428 29429 3 29359 29429 29360 3 29360 29429 29430 3 29360 29430 29361 3 29361 29430 29431 3 29361 29431 29362 3 29362 29431 29432 3 29362 29432 29363 3 29363 29432 29433 3 29363 29433 29364 3 29364 29433 29434 3 29364 29434 29365 3 29365 29434 29435 3 29365 29435 29366 3 29366 29435 29436 3 29366 29436 29367 3 29367 29436 29437 3 29367 29437 29368 3 29368 29437 29438 3 29368 29438 29369 3 29369 29438 29439 3 29369 29439 29370 3 29370 29439 29440 3 29370 29440 29371 3 29371 29440 29441 3 29371 29441 29372 3 29372 29441 29442 3 29372 29442 29373 3 29373 29442 29443 3 29373 29443 29374 3 29374 29443 29444 3 29374 29444 29375 3 29375 29444 29445 3 29375 29445 29376 3 29376 29445 29446 3 29376 29446 29377 3 29377 29446 29447 3 29377 29447 29378 3 29378 29447 29448 3 29378 29448 29379 3 29379 29448 29449 3 29379 29449 29380 3 29380 29449 29450 3 29380 29450 29381 3 29381 29450 29451 3 29381 29451 29382 3 29382 29451 29452 3 29382 29452 29383 3 29384 29453 29454 3 29384 29454 29385 3 29385 29454 29455 3 29385 29455 29386 3 29386 29455 29456 3 29386 29456 29387 3 29387 29456 29457 3 29387 29457 29388 3 29388 29457 29458 3 29388 29458 29389 3 29389 29458 29459 3 29389 29459 29390 3 29390 29459 29460 3 29390 29460 29391 3 29391 29460 29461 3 29391 29461 29392 3 29392 29461 29462 3 29392 29462 29393 3 29393 29462 29463 3 29393 29463 29394 3 29394 29463 29464 3 29394 29464 29395 3 29395 29464 29465 3 29395 29465 29396 3 29396 29465 29466 3 29396 29466 29397 3 29397 29466 29467 3 29397 29467 29398 3 29398 29467 29468 3 29398 29468 29399 3 29399 29468 29469 3 29399 29469 29400 3 29400 29469 29401 3 29470 29401 29469 3 29401 29470 29402 3 29471 29402 29470 3 29402 29471 29403 3 29472 29403 29471 3 29403 29472 29404 3 29473 29404 29472 3 29404 29473 29405 3 29474 29405 29473 3 29405 29474 29406 3 29475 29406 29474 3 29406 29475 29407 3 29476 29407 29475 3 29407 29476 29408 3 29477 29408 29476 3 29408 29477 29409 3 29478 29409 29477 3 29409 29478 29410 3 29479 29410 29478 3 29410 29479 29411 3 29480 29411 29479 3 29411 29480 29412 3 29481 29412 29480 3 29412 29481 29413 3 29482 29413 29481 3 29413 29482 29414 3 29483 29414 29482 3 29414 29483 29415 3 29484 29415 29483 3 29415 29484 29416 3 29485 29416 29484 3 29416 29485 29417 3 29486 29417 29485 3 29417 29486 29418 3 29487 29418 29486 3 29418 29487 29419 3 29488 29419 29487 3 29419 29488 29420 3 29489 29420 29488 3 29420 29489 29421 3 29490 29421 29489 3 29421 29490 29422 3 29491 29422 29490 3 29422 29491 29423 3 29492 29423 29491 3 29423 29492 29424 3 29493 29424 29492 3 29424 29493 29425 3 29494 29425 29493 3 29425 29494 29426 3 29495 29426 29494 3 29426 29495 29427 3 29496 29427 29495 3 29427 29496 29428 3 29497 29428 29496 3 29428 29497 29429 3 29498 29429 29497 3 29429 29498 29430 3 29499 29430 29498 3 29430 29499 29431 3 29500 29431 29499 3 29431 29500 29432 3 29501 29432 29500 3 29432 29501 29433 3 29502 29433 29501 3 29433 29502 29434 3 29503 29434 29502 3 29434 29503 29435 3 29504 29435 29503 3 29435 29504 29436 3 29505 29436 29504 3 29436 29505 29437 3 29506 29437 29505 3 29437 29506 29438 3 29507 29438 29506 3 29438 29507 29439 3 29508 29439 29507 3 29439 29508 29440 3 29509 29440 29508 3 29440 29509 29441 3 29510 29441 29509 3 29441 29510 29442 3 29511 29442 29510 3 29442 29511 29443 3 29512 29443 29511 3 29443 29512 29444 3 29513 29444 29512 3 29444 29513 29445 3 29514 29445 29513 3 29445 29514 29446 3 29515 29446 29514 3 29446 29515 29447 3 29516 29447 29515 3 29447 29516 29448 3 29517 29448 29516 3 29448 29517 29449 3 29518 29449 29517 3 29449 29518 29450 3 29519 29450 29518 3 29450 29519 29451 3 29520 29451 29519 3 29451 29520 29452 3 29521 29452 29520 3 29453 29522 29454 3 29523 29454 29522 3 29454 29523 29455 3 29524 29455 29523 3 29455 29524 29456 3 29525 29456 29524 3 29456 29525 29457 3 29526 29457 29525 3 29457 29526 29458 3 29527 29458 29526 3 29458 29527 29459 3 29528 29459 29527 3 29459 29528 29460 3 29529 29460 29528 3 29460 29529 29461 3 29530 29461 29529 3 29461 29530 29462 3 29531 29462 29530 3 29462 29531 29463 3 29532 29463 29531 3 29463 29532 29464 3 29533 29464 29532 3 29464 29533 29465 3 29534 29465 29533 3 29465 29534 29466 3 29535 29466 29534 3 29466 29535 29467 3 29536 29467 29535 3 29467 29536 29468 3 29537 29468 29536 3 29468 29537 29469 3 29538 29469 29537 3 29469 29538 29470 3 29539 29470 29538 3 29470 29539 29471 3 29540 29471 29539 3 29471 29540 29472 3 29541 29472 29540 3 29472 29541 29473 3 29542 29473 29541 3 29473 29542 29474 3 29543 29474 29542 3 29474 29543 29475 3 29544 29475 29543 3 29475 29544 29476 3 29545 29476 29544 3 29476 29545 29477 3 29546 29477 29545 3 29477 29546 29478 3 29547 29478 29546 3 29478 29547 29479 3 29548 29479 29547 3 29479 29548 29480 3 29549 29480 29548 3 29480 29549 29481 3 29550 29481 29549 3 29481 29550 29482 3 29551 29482 29550 3 29482 29551 29483 3 29552 29483 29551 3 29483 29552 29484 3 29553 29484 29552 3 29484 29553 29485 3 29554 29485 29553 3 29485 29554 29486 3 29555 29486 29554 3 29486 29555 29487 3 29556 29487 29555 3 29487 29556 29488 3 29557 29488 29556 3 29488 29557 29489 3 29558 29489 29557 3 29489 29558 29490 3 29559 29490 29558 3 29490 29559 29491 3 29560 29491 29559 3 29491 29560 29492 3 29561 29492 29560 3 29492 29561 29493 3 29562 29493 29561 3 29493 29562 29494 3 29563 29494 29562 3 29494 29563 29495 3 29564 29495 29563 3 29495 29564 29496 3 29565 29496 29564 3 29496 29565 29497 3 29566 29497 29565 3 29497 29566 29498 3 29567 29498 29566 3 29498 29567 29499 3 29568 29499 29567 3 29499 29568 29500 3 29569 29500 29568 3 29500 29569 29501 3 29570 29501 29569 3 29501 29570 29502 3 29571 29502 29570 3 29502 29571 29503 3 29572 29503 29571 3 29503 29572 29504 3 29573 29504 29572 3 29504 29573 29505 3 29574 29505 29573 3 29505 29574 29506 3 29575 29506 29574 3 29506 29575 29576 3 29506 29576 29507 3 29507 29576 29577 3 29507 29577 29508 3 29508 29577 29578 3 29508 29578 29509 3 29509 29578 29579 3 29509 29579 29510 3 29510 29579 29580 3 29510 29580 29511 3 29511 29580 29581 3 29511 29581 29512 3 29512 29581 29582 3 29512 29582 29513 3 29513 29582 29583 3 29513 29583 29514 3 29514 29583 29584 3 29514 29584 29515 3 29515 29584 29585 3 29515 29585 29516 3 29516 29585 29586 3 29516 29586 29517 3 29517 29586 29587 3 29517 29587 29518 3 29518 29587 29588 3 29518 29588 29519 3 29519 29588 29589 3 29519 29589 29520 3 29520 29589 29590 3 29520 29590 29521 3 29522 29591 29592 3 29522 29592 29523 3 29523 29592 29593 3 29523 29593 29524 3 29524 29593 29594 3 29524 29594 29525 3 29525 29594 29595 3 29525 29595 29526 3 29526 29595 29596 3 29526 29596 29527 3 29527 29596 29597 3 29527 29597 29528 3 29528 29597 29598 3 29528 29598 29529 3 29529 29598 29599 3 29529 29599 29530 3 29530 29599 29600 3 29530 29600 29531 3 29531 29600 29601 3 29531 29601 29532 3 29532 29601 29602 3 29532 29602 29533 3 29533 29602 29603 3 29533 29603 29534 3 29534 29603 29604 3 29534 29604 29535 3 29535 29604 29605 3 29535 29605 29536 3 29536 29605 29606 3 29536 29606 29537 3 29537 29606 29607 3 29537 29607 29538 3 29538 29607 29608 3 29538 29608 29539 3 29539 29608 29609 3 29539 29609 29540 3 29540 29609 29610 3 29540 29610 29541 3 29541 29610 29611 3 29541 29611 29542 3 29542 29611 29612 3 29542 29612 29543 3 29543 29612 29613 3 29543 29613 29544 3 29544 29613 29614 3 29544 29614 29545 3 29545 29614 29615 3 29545 29615 29546 3 29546 29615 29616 3 29546 29616 29547 3 29547 29616 29617 3 29547 29617 29548 3 29548 29617 29618 3 29548 29618 29549 3 29549 29618 29619 3 29549 29619 29550 3 29550 29619 29620 3 29550 29620 29551 3 29551 29620 29621 3 29551 29621 29552 3 29552 29621 29622 3 29552 29622 29553 3 29553 29622 29623 3 29553 29623 29554 3 29554 29623 29624 3 29554 29624 29555 3 29555 29624 29625 3 29555 29625 29556 3 29556 29625 29626 3 29556 29626 29557 3 29557 29626 29627 3 29557 29627 29558 3 29558 29627 29628 3 29558 29628 29559 3 29559 29628 29629 3 29559 29629 29560 3 29560 29629 29630 3 29560 29630 29561 3 29561 29630 29631 3 29561 29631 29562 3 29562 29631 29632 3 29562 29632 29563 3 29563 29632 29633 3 29563 29633 29564 3 29564 29633 29634 3 29564 29634 29565 3 29565 29634 29635 3 29565 29635 29566 3 29566 29635 29636 3 29566 29636 29567 3 29567 29636 29637 3 29567 29637 29568 3 29568 29637 29638 3 29568 29638 29569 3 29569 29638 29639 3 29569 29639 29570 3 29570 29639 29640 3 29570 29640 29571 3 29571 29640 29641 3 29571 29641 29572 3 29572 29641 29642 3 29572 29642 29573 3 29573 29642 29643 3 29573 29643 29574 3 29574 29643 29644 3 29574 29644 29575 3 29575 29644 29645 3 29575 29645 29576 3 29576 29645 29646 3 29576 29646 29577 3 29577 29646 29647 3 29577 29647 29578 3 29578 29647 29648 3 29578 29648 29579 3 29579 29648 29649 3 29579 29649 29580 3 29580 29649 29650 3 29580 29650 29581 3 29581 29650 29651 3 29581 29651 29582 3 29582 29651 29652 3 29582 29652 29583 3 29583 29652 29653 3 29583 29653 29584 3 29584 29653 29654 3 29584 29654 29585 3 29585 29654 29655 3 29585 29655 29586 3 29586 29655 29656 3 29586 29656 29587 3 29587 29656 29657 3 29587 29657 29588 3 29588 29657 29658 3 29588 29658 29589 3 29589 29658 29659 3 29589 29659 29590 3 29591 29660 29661 3 29591 29661 29592 3 29592 29661 29662 3 29592 29662 29593 3 29593 29662 29663 3 29593 29663 29594 3 29594 29663 29664 3 29594 29664 29595 3 29595 29664 29665 3 29595 29665 29596 3 29596 29665 29666 3 29596 29666 29597 3 29597 29666 29667 3 29597 29667 29598 3 29598 29667 29668 3 29598 29668 29599 3 29599 29668 29669 3 29599 29669 29600 3 29600 29669 29670 3 29600 29670 29601 3 29601 29670 29671 3 29601 29671 29602 3 29602 29671 29672 3 29602 29672 29603 3 29603 29672 29673 3 29603 29673 29604 3 29604 29673 29674 3 29604 29674 29605 3 29605 29674 29675 3 29605 29675 29606 3 29606 29675 29676 3 29606 29676 29607 3 29607 29676 29677 3 29607 29677 29608 3 29608 29677 29678 3 29608 29678 29609 3 29609 29678 29679 3 29609 29679 29610 3 29610 29679 29680 3 29610 29680 29611 3 29611 29680 29681 3 29611 29681 29612 3 29612 29681 29613 3 29682 29613 29681 3 29613 29682 29614 3 29683 29614 29682 3 29614 29683 29615 3 29684 29615 29683 3 29615 29684 29616 3 29685 29616 29684 3 29616 29685 29617 3 29686 29617 29685 3 29617 29686 29618 3 29687 29618 29686 3 29618 29687 29619 3 29688 29619 29687 3 29619 29688 29620 3 29689 29620 29688 3 29620 29689 29621 3 29690 29621 29689 3 29621 29690 29622 3 29691 29622 29690 3 29622 29691 29623 3 29692 29623 29691 3 29623 29692 29624 3 29693 29624 29692 3 29624 29693 29625 3 29694 29625 29693 3 29625 29694 29626 3 29695 29626 29694 3 29626 29695 29627 3 29696 29627 29695 3 29627 29696 29628 3 29697 29628 29696 3 29628 29697 29629 3 29698 29629 29697 3 29629 29698 29630 3 29699 29630 29698 3 29630 29699 29631 3 29700 29631 29699 3 29631 29700 29632 3 29701 29632 29700 3 29632 29701 29633 3 29702 29633 29701 3 29633 29702 29634 3 29703 29634 29702 3 29634 29703 29635 3 29704 29635 29703 3 29635 29704 29636 3 29705 29636 29704 3 29636 29705 29637 3 29706 29637 29705 3 29637 29706 29638 3 29707 29638 29706 3 29638 29707 29639 3 29708 29639 29707 3 29639 29708 29640 3 29709 29640 29708 3 29640 29709 29641 3 29710 29641 29709 3 29641 29710 29642 3 29711 29642 29710 3 29642 29711 29643 3 29712 29643 29711 3 29643 29712 29644 3 29713 29644 29712 3 29644 29713 29645 3 29714 29645 29713 3 29645 29714 29646 3 29715 29646 29714 3 29646 29715 29647 3 29716 29647 29715 3 29647 29716 29648 3 29717 29648 29716 3 29648 29717 29649 3 29718 29649 29717 3 29649 29718 29650 3 29719 29650 29718 3 29650 29719 29651 3 29720 29651 29719 3 29651 29720 29652 3 29721 29652 29720 3 29652 29721 29653 3 29722 29653 29721 3 29653 29722 29654 3 29723 29654 29722 3 29654 29723 29655 3 29724 29655 29723 3 29655 29724 29656 3 29725 29656 29724 3 29656 29725 29657 3 29726 29657 29725 3 29657 29726 29658 3 29727 29658 29726 3 29658 29727 29659 3 29728 29659 29727 3 29660 29729 29661 3 29730 29661 29729 3 29661 29730 29662 3 29731 29662 29730 3 29662 29731 29663 3 29732 29663 29731 3 29663 29732 29664 3 29733 29664 29732 3 29664 29733 29665 3 29734 29665 29733 3 29665 29734 29666 3 29735 29666 29734 3 29666 29735 29667 3 29736 29667 29735 3 29667 29736 29668 3 29737 29668 29736 3 29668 29737 29669 3 29738 29669 29737 3 29669 29738 29670 3 29739 29670 29738 3 29670 29739 29671 3 29740 29671 29739 3 29671 29740 29672 3 29741 29672 29740 3 29672 29741 29673 3 29742 29673 29741 3 29673 29742 29674 3 29743 29674 29742 3 29674 29743 29675 3 29744 29675 29743 3 29675 29744 29676 3 29745 29676 29744 3 29676 29745 29677 3 29746 29677 29745 3 29677 29746 29678 3 29747 29678 29746 3 29678 29747 29679 3 29748 29679 29747 3 29679 29748 29680 3 29749 29680 29748 3 29680 29749 29681 3 29750 29681 29749 3 29681 29750 29682 3 29751 29682 29750 3 29682 29751 29683 3 29752 29683 29751 3 29683 29752 29684 3 29753 29684 29752 3 29684 29753 29685 3 29754 29685 29753 3 29685 29754 29686 3 29755 29686 29754 3 29686 29755 29687 3 29756 29687 29755 3 29687 29756 29688 3 29757 29688 29756 3 29688 29757 29689 3 29758 29689 29757 3 29689 29758 29690 3 29759 29690 29758 3 29690 29759 29691 3 29760 29691 29759 3 29691 29760 29692 3 29761 29692 29760 3 29692 29761 29693 3 29762 29693 29761 3 29693 29762 29694 3 29763 29694 29762 3 29694 29763 29695 3 29764 29695 29763 3 29695 29764 29696 3 29765 29696 29764 3 29696 29765 29697 3 29766 29697 29765 3 29697 29766 29698 3 29767 29698 29766 3 29698 29767 29699 3 29768 29699 29767 3 29699 29768 29700 3 29769 29700 29768 3 29700 29769 29701 3 29770 29701 29769 3 29701 29770 29702 3 29771 29702 29770 3 29702 29771 29703 3 29772 29703 29771 3 29703 29772 29704 3 29773 29704 29772 3 29704 29773 29705 3 29774 29705 29773 3 29705 29774 29706 3 29775 29706 29774 3 29706 29775 29707 3 29776 29707 29775 3 29707 29776 29708 3 29777 29708 29776 3 29708 29777 29709 3 29778 29709 29777 3 29709 29778 29710 3 29779 29710 29778 3 29710 29779 29711 3 29780 29711 29779 3 29711 29780 29712 3 29781 29712 29780 3 29712 29781 29713 3 29782 29713 29781 3 29713 29782 29714 3 29783 29714 29782 3 29714 29783 29715 3 29784 29715 29783 3 29715 29784 29716 3 29785 29716 29784 3 29716 29785 29717 3 29786 29717 29785 3 29717 29786 29718 3 29787 29718 29786 3 29718 29787 29788 3 29718 29788 29719 3 29719 29788 29789 3 29719 29789 29720 3 29720 29789 29790 3 29720 29790 29721 3 29721 29790 29791 3 29721 29791 29722 3 29722 29791 29792 3 29722 29792 29723 3 29723 29792 29793 3 29723 29793 29724 3 29724 29793 29794 3 29724 29794 29725 3 29725 29794 29795 3 29725 29795 29726 3 29726 29795 29796 3 29726 29796 29727 3 29727 29796 29797 3 29727 29797 29728 3 29729 29798 29799 3 29729 29799 29730 3 29730 29799 29800 3 29730 29800 29731 3 29731 29800 29801 3 29731 29801 29732 3 29732 29801 29802 3 29732 29802 29733 3 29733 29802 29803 3 29733 29803 29734 3 29734 29803 29804 3 29734 29804 29735 3 29735 29804 29805 3 29735 29805 29736 3 29736 29805 29806 3 29736 29806 29737 3 29737 29806 29807 3 29737 29807 29738 3 29738 29807 29808 3 29738 29808 29739 3 29739 29808 29809 3 29739 29809 29740 3 29740 29809 29810 3 29740 29810 29741 3 29741 29810 29811 3 29741 29811 29742 3 29742 29811 29812 3 29742 29812 29743 3 29743 29812 29813 3 29743 29813 29744 3 29744 29813 29814 3 29744 29814 29745 3 29745 29814 29815 3 29745 29815 29746 3 29746 29815 29816 3 29746 29816 29747 3 29747 29816 29817 3 29747 29817 29748 3 29748 29817 29818 3 29748 29818 29749 3 29749 29818 29819 3 29749 29819 29750 3 29750 29819 29820 3 29750 29820 29751 3 29751 29820 29821 3 29751 29821 29752 3 29752 29821 29822 3 29752 29822 29753 3 29753 29822 29823 3 29753 29823 29754 3 29754 29823 29824 3 29754 29824 29755 3 29755 29824 29825 3 29755 29825 29756 3 29756 29825 29826 3 29756 29826 29757 3 29757 29826 29827 3 29757 29827 29758 3 29758 29827 29828 3 29758 29828 29759 3 29759 29828 29829 3 29759 29829 29760 3 29760 29829 29830 3 29760 29830 29761 3 29761 29830 29831 3 29761 29831 29762 3 29762 29831 29832 3 29762 29832 29763 3 29763 29832 29833 3 29763 29833 29764 3 29764 29833 29834 3 29764 29834 29765 3 29765 29834 29835 3 29765 29835 29766 3 29766 29835 29836 3 29766 29836 29767 3 29767 29836 29837 3 29767 29837 29768 3 29768 29837 29838 3 29768 29838 29769 3 29769 29838 29839 3 29769 29839 29770 3 29770 29839 29840 3 29770 29840 29771 3 29771 29840 29841 3 29771 29841 29772 3 29772 29841 29842 3 29772 29842 29773 3 29773 29842 29843 3 29773 29843 29774 3 29774 29843 29844 3 29774 29844 29775 3 29775 29844 29845 3 29775 29845 29776 3 29776 29845 29846 3 29776 29846 29777 3 29777 29846 29847 3 29777 29847 29778 3 29778 29847 29848 3 29778 29848 29779 3 29779 29848 29849 3 29779 29849 29780 3 29780 29849 29850 3 29780 29850 29781 3 29781 29850 29851 3 29781 29851 29782 3 29782 29851 29852 3 29782 29852 29783 3 29783 29852 29853 3 29783 29853 29784 3 29784 29853 29854 3 29784 29854 29785 3 29785 29854 29855 3 29785 29855 29786 3 29786 29855 29856 3 29786 29856 29787 3 29787 29856 29857 3 29787 29857 29788 3 29788 29857 29858 3 29788 29858 29789 3 29789 29858 29859 3 29789 29859 29790 3 29790 29859 29860 3 29790 29860 29791 3 29791 29860 29861 3 29791 29861 29792 3 29792 29861 29862 3 29792 29862 29793 3 29793 29862 29863 3 29793 29863 29794 3 29794 29863 29864 3 29794 29864 29795 3 29795 29864 29865 3 29795 29865 29796 3 29796 29865 29866 3 29796 29866 29797 3 29798 29867 29868 3 29798 29868 29799 3 29799 29868 29869 3 29799 29869 29800 3 29800 29869 29870 3 29800 29870 29801 3 29801 29870 29871 3 29801 29871 29802 3 29802 29871 29872 3 29802 29872 29803 3 29803 29872 29873 3 29803 29873 29804 3 29804 29873 29874 3 29804 29874 29805 3 29805 29874 29875 3 29805 29875 29806 3 29806 29875 29876 3 29806 29876 29807 3 29807 29876 29877 3 29807 29877 29808 3 29808 29877 29878 3 29808 29878 29809 3 29809 29878 29879 3 29809 29879 29810 3 29810 29879 29880 3 29810 29880 29811 3 29811 29880 29881 3 29811 29881 29812 3 29812 29881 29882 3 29812 29882 29813 3 29813 29882 29883 3 29813 29883 29814 3 29814 29883 29884 3 29814 29884 29815 3 29815 29884 29885 3 29815 29885 29816 3 29816 29885 29886 3 29816 29886 29817 3 29817 29886 29887 3 29817 29887 29818 3 29818 29887 29888 3 29818 29888 29819 3 29819 29888 29889 3 29819 29889 29820 3 29820 29889 29890 3 29820 29890 29821 3 29821 29890 29891 3 29821 29891 29822 3 29822 29891 29892 3 29822 29892 29823 3 29823 29892 29893 3 29823 29893 29824 3 29824 29893 29825 3 29894 29825 29893 3 29825 29894 29826 3 29895 29826 29894 3 29826 29895 29827 3 29896 29827 29895 3 29827 29896 29828 3 29897 29828 29896 3 29828 29897 29829 3 29898 29829 29897 3 29829 29898 29830 3 29899 29830 29898 3 29830 29899 29831 3 29900 29831 29899 3 29831 29900 29832 3 29901 29832 29900 3 29832 29901 29833 3 29902 29833 29901 3 29833 29902 29834 3 29903 29834 29902 3 29834 29903 29835 3 29904 29835 29903 3 29835 29904 29836 3 29905 29836 29904 3 29836 29905 29837 3 29906 29837 29905 3 29837 29906 29838 3 29907 29838 29906 3 29838 29907 29839 3 29908 29839 29907 3 29839 29908 29840 3 29909 29840 29908 3 29840 29909 29841 3 29910 29841 29909 3 29841 29910 29842 3 29911 29842 29910 3 29842 29911 29843 3 29912 29843 29911 3 29843 29912 29844 3 29913 29844 29912 3 29844 29913 29845 3 29914 29845 29913 3 29845 29914 29846 3 29915 29846 29914 3 29846 29915 29847 3 29916 29847 29915 3 29847 29916 29848 3 29917 29848 29916 3 29848 29917 29849 3 29918 29849 29917 3 29849 29918 29850 3 29919 29850 29918 3 29850 29919 29851 3 29920 29851 29919 3 29851 29920 29852 3 29921 29852 29920 3 29852 29921 29853 3 29922 29853 29921 3 29853 29922 29854 3 29923 29854 29922 3 29854 29923 29855 3 29924 29855 29923 3 29855 29924 29856 3 29925 29856 29924 3 29856 29925 29857 3 29926 29857 29925 3 29857 29926 29858 3 29927 29858 29926 3 29858 29927 29859 3 29928 29859 29927 3 29859 29928 29860 3 29929 29860 29928 3 29860 29929 29861 3 29930 29861 29929 3 29861 29930 29862 3 29931 29862 29930 3 29862 29931 29863 3 29932 29863 29931 3 29863 29932 29864 3 29933 29864 29932 3 29864 29933 29865 3 29934 29865 29933 3 29865 29934 29866 3 29935 29866 29934 3 29867 29936 29868 3 29937 29868 29936 3 29868 29937 29869 3 29938 29869 29937 3 29869 29938 29870 3 29939 29870 29938 3 29870 29939 29871 3 29940 29871 29939 3 29871 29940 29872 3 29941 29872 29940 3 29872 29941 29873 3 29942 29873 29941 3 29873 29942 29874 3 29943 29874 29942 3 29874 29943 29875 3 29944 29875 29943 3 29875 29944 29876 3 29945 29876 29944 3 29876 29945 29877 3 29946 29877 29945 3 29877 29946 29878 3 29947 29878 29946 3 29878 29947 29879 3 29948 29879 29947 3 29879 29948 29880 3 29949 29880 29948 3 29880 29949 29881 3 29950 29881 29949 3 29881 29950 29882 3 29951 29882 29950 3 29882 29951 29883 3 29952 29883 29951 3 29883 29952 29884 3 29953 29884 29952 3 29884 29953 29885 3 29954 29885 29953 3 29885 29954 29886 3 29955 29886 29954 3 29886 29955 29887 3 29956 29887 29955 3 29887 29956 29888 3 29957 29888 29956 3 29888 29957 29889 3 29958 29889 29957 3 29889 29958 29890 3 29959 29890 29958 3 29890 29959 29891 3 29960 29891 29959 3 29891 29960 29892 3 29961 29892 29960 3 29892 29961 29893 3 29962 29893 29961 3 29893 29962 29894 3 29963 29894 29962 3 29894 29963 29895 3 29964 29895 29963 3 29895 29964 29896 3 29965 29896 29964 3 29896 29965 29897 3 29966 29897 29965 3 29897 29966 29898 3 29967 29898 29966 3 29898 29967 29899 3 29968 29899 29967 3 29899 29968 29900 3 29969 29900 29968 3 29900 29969 29901 3 29970 29901 29969 3 29901 29970 29902 3 29971 29902 29970 3 29902 29971 29903 3 29972 29903 29971 3 29903 29972 29904 3 29973 29904 29972 3 29904 29973 29905 3 29974 29905 29973 3 29905 29974 29906 3 29975 29906 29974 3 29906 29975 29907 3 29976 29907 29975 3 29907 29976 29908 3 29977 29908 29976 3 29908 29977 29909 3 29978 29909 29977 3 29909 29978 29910 3 29979 29910 29978 3 29910 29979 29911 3 29980 29911 29979 3 29911 29980 29912 3 29981 29912 29980 3 29912 29981 29913 3 29982 29913 29981 3 29913 29982 29914 3 29983 29914 29982 3 29914 29983 29915 3 29984 29915 29983 3 29915 29984 29916 3 29985 29916 29984 3 29916 29985 29917 3 29986 29917 29985 3 29917 29986 29918 3 29987 29918 29986 3 29918 29987 29919 3 29988 29919 29987 3 29919 29988 29920 3 29989 29920 29988 3 29920 29989 29921 3 29990 29921 29989 3 29921 29990 29922 3 29991 29922 29990 3 29922 29991 29923 3 29992 29923 29991 3 29923 29992 29924 3 29993 29924 29992 3 29924 29993 29925 3 29994 29925 29993 3 29925 29994 29926 3 29995 29926 29994 3 29926 29995 29927 3 29996 29927 29995 3 29927 29996 29928 3 29997 29928 29996 3 29928 29997 29929 3 29998 29929 29997 3 29929 29998 29930 3 29999 29930 29998 3 29930 29999 29931 3 30000 29931 29999 3 29931 30000 30001 3 29931 30001 29932 3 29932 30001 30002 3 29932 30002 29933 3 29933 30002 30003 3 29933 30003 29934 3 29934 30003 30004 3 29934 30004 29935 3 29936 30005 30006 3 29936 30006 29937 3 29937 30006 30007 3 29937 30007 29938 3 29938 30007 30008 3 29938 30008 29939 3 29939 30008 30009 3 29939 30009 29940 3 29940 30009 30010 3 29940 30010 29941 3 29941 30010 30011 3 29941 30011 29942 3 29942 30011 30012 3 29942 30012 29943 3 29943 30012 30013 3 29943 30013 29944 3 29944 30013 30014 3 29944 30014 29945 3 29945 30014 30015 3 29945 30015 29946 3 29946 30015 30016 3 29946 30016 29947 3 29947 30016 30017 3 29947 30017 29948 3 29948 30017 30018 3 29948 30018 29949 3 29949 30018 30019 3 29949 30019 29950 3 29950 30019 30020 3 29950 30020 29951 3 29951 30020 30021 3 29951 30021 29952 3 29952 30021 30022 3 29952 30022 29953 3 29953 30022 30023 3 29953 30023 29954 3 29954 30023 30024 3 29954 30024 29955 3 29955 30024 30025 3 29955 30025 29956 3 29956 30025 30026 3 29956 30026 29957 3 29957 30026 30027 3 29957 30027 29958 3 29958 30027 30028 3 29958 30028 29959 3 29959 30028 30029 3 29959 30029 29960 3 29960 30029 30030 3 29960 30030 29961 3 29961 30030 30031 3 29961 30031 29962 3 29962 30031 30032 3 29962 30032 29963 3 29963 30032 30033 3 29963 30033 29964 3 29964 30033 30034 3 29964 30034 29965 3 29965 30034 30035 3 29965 30035 29966 3 29966 30035 30036 3 29966 30036 29967 3 29967 30036 30037 3 29967 30037 29968 3 29968 30037 30038 3 29968 30038 29969 3 29969 30038 30039 3 29969 30039 29970 3 29970 30039 30040 3 29970 30040 29971 3 29971 30040 30041 3 29971 30041 29972 3 29972 30041 30042 3 29972 30042 29973 3 29973 30042 30043 3 29973 30043 29974 3 29974 30043 30044 3 29974 30044 29975 3 29975 30044 30045 3 29975 30045 29976 3 29976 30045 30046 3 29976 30046 29977 3 29977 30046 30047 3 29977 30047 29978 3 29978 30047 30048 3 29978 30048 29979 3 29979 30048 30049 3 29979 30049 29980 3 29980 30049 30050 3 29980 30050 29981 3 29981 30050 30051 3 29981 30051 29982 3 29982 30051 30052 3 29982 30052 29983 3 29983 30052 30053 3 29983 30053 29984 3 29984 30053 30054 3 29984 30054 29985 3 29985 30054 30055 3 29985 30055 29986 3 29986 30055 30056 3 29986 30056 29987 3 29987 30056 30057 3 29987 30057 29988 3 29988 30057 30058 3 29988 30058 29989 3 29989 30058 30059 3 29989 30059 29990 3 29990 30059 30060 3 29990 30060 29991 3 29991 30060 30061 3 29991 30061 29992 3 29992 30061 30062 3 29992 30062 29993 3 29993 30062 30063 3 29993 30063 29994 3 29994 30063 30064 3 29994 30064 29995 3 29995 30064 30065 3 29995 30065 29996 3 29996 30065 30066 3 29996 30066 29997 3 29997 30066 30067 3 29997 30067 29998 3 29998 30067 30068 3 29998 30068 29999 3 29999 30068 30069 3 29999 30069 30000 3 30000 30069 30070 3 30000 30070 30001 3 30001 30070 30071 3 30001 30071 30002 3 30002 30071 30072 3 30002 30072 30003 3 30003 30072 30073 3 30003 30073 30004 3 30005 30074 30075 3 30005 30075 30006 3 30006 30075 30076 3 30006 30076 30007 3 30007 30076 30077 3 30007 30077 30008 3 30008 30077 30078 3 30008 30078 30009 3 30009 30078 30079 3 30009 30079 30010 3 30010 30079 30080 3 30010 30080 30011 3 30011 30080 30081 3 30011 30081 30012 3 30012 30081 30082 3 30012 30082 30013 3 30013 30082 30083 3 30013 30083 30014 3 30014 30083 30084 3 30014 30084 30015 3 30015 30084 30085 3 30015 30085 30016 3 30016 30085 30086 3 30016 30086 30017 3 30017 30086 30087 3 30017 30087 30018 3 30018 30087 30088 3 30018 30088 30019 3 30019 30088 30089 3 30019 30089 30020 3 30020 30089 30090 3 30020 30090 30021 3 30021 30090 30091 3 30021 30091 30022 3 30022 30091 30092 3 30022 30092 30023 3 30023 30092 30093 3 30023 30093 30024 3 30024 30093 30094 3 30024 30094 30025 3 30025 30094 30095 3 30025 30095 30026 3 30026 30095 30096 3 30026 30096 30027 3 30027 30096 30097 3 30027 30097 30028 3 30028 30097 30098 3 30028 30098 30029 3 30029 30098 30099 3 30029 30099 30030 3 30030 30099 30100 3 30030 30100 30031 3 30031 30100 30101 3 30031 30101 30032 3 30032 30101 30102 3 30032 30102 30033 3 30033 30102 30103 3 30033 30103 30034 3 30034 30103 30104 3 30034 30104 30035 3 30035 30104 30105 3 30035 30105 30036 3 30036 30105 30106 3 30036 30106 30037 3 30037 30106 30038 3 30107 30038 30106 3 30038 30107 30039 3 30108 30039 30107 3 30039 30108 30040 3 30109 30040 30108 3 30040 30109 30041 3 30110 30041 30109 3 30041 30110 30042 3 30111 30042 30110 3 30042 30111 30043 3 30112 30043 30111 3 30043 30112 30044 3 30113 30044 30112 3 30044 30113 30045 3 30114 30045 30113 3 30045 30114 30046 3 30115 30046 30114 3 30046 30115 30047 3 30116 30047 30115 3 30047 30116 30048 3 30117 30048 30116 3 30048 30117 30049 3 30118 30049 30117 3 30049 30118 30050 3 30119 30050 30118 3 30050 30119 30051 3 30120 30051 30119 3 30051 30120 30052 3 30121 30052 30120 3 30052 30121 30053 3 30122 30053 30121 3 30053 30122 30054 3 30123 30054 30122 3 30054 30123 30055 3 30124 30055 30123 3 30055 30124 30056 3 30125 30056 30124 3 30056 30125 30057 3 30126 30057 30125 3 30057 30126 30058 3 30127 30058 30126 3 30058 30127 30059 3 30128 30059 30127 3 30059 30128 30060 3 30129 30060 30128 3 30060 30129 30061 3 30130 30061 30129 3 30061 30130 30062 3 30131 30062 30130 3 30062 30131 30063 3 30132 30063 30131 3 30063 30132 30064 3 30133 30064 30132 3 30064 30133 30065 3 30134 30065 30133 3 30065 30134 30066 3 30135 30066 30134 3 30066 30135 30067 3 30136 30067 30135 3 30067 30136 30068 3 30137 30068 30136 3 30068 30137 30069 3 30138 30069 30137 3 30069 30138 30070 3 30139 30070 30138 3 30070 30139 30071 3 30140 30071 30139 3 30071 30140 30072 3 30141 30072 30140 3 30072 30141 30073 3 30142 30073 30141 3 30074 30143 30075 3 30144 30075 30143 3 30075 30144 30076 3 30145 30076 30144 3 30076 30145 30077 3 30146 30077 30145 3 30077 30146 30078 3 30147 30078 30146 3 30078 30147 30079 3 30148 30079 30147 3 30079 30148 30080 3 30149 30080 30148 3 30080 30149 30081 3 30150 30081 30149 3 30081 30150 30082 3 30151 30082 30150 3 30082 30151 30083 3 30152 30083 30151 3 30083 30152 30084 3 30153 30084 30152 3 30084 30153 30085 3 30154 30085 30153 3 30085 30154 30086 3 30155 30086 30154 3 30086 30155 30087 3 30156 30087 30155 3 30087 30156 30088 3 30157 30088 30156 3 30088 30157 30089 3 30158 30089 30157 3 30089 30158 30090 3 30159 30090 30158 3 30090 30159 30091 3 30160 30091 30159 3 30091 30160 30092 3 30161 30092 30160 3 30092 30161 30093 3 30162 30093 30161 3 30093 30162 30094 3 30163 30094 30162 3 30094 30163 30095 3 30164 30095 30163 3 30095 30164 30096 3 30165 30096 30164 3 30096 30165 30097 3 30166 30097 30165 3 30097 30166 30098 3 30167 30098 30166 3 30098 30167 30099 3 30168 30099 30167 3 30099 30168 30100 3 30169 30100 30168 3 30100 30169 30101 3 30170 30101 30169 3 30101 30170 30102 3 30171 30102 30170 3 30102 30171 30103 3 30172 30103 30171 3 30103 30172 30104 3 30173 30104 30172 3 30104 30173 30105 3 30174 30105 30173 3 30105 30174 30106 3 30175 30106 30174 3 30106 30175 30107 3 30176 30107 30175 3 30107 30176 30108 3 30177 30108 30176 3 30108 30177 30109 3 30178 30109 30177 3 30109 30178 30110 3 30179 30110 30178 3 30110 30179 30111 3 30180 30111 30179 3 30111 30180 30112 3 30181 30112 30180 3 30112 30181 30113 3 30182 30113 30181 3 30113 30182 30114 3 30183 30114 30182 3 30114 30183 30115 3 30184 30115 30183 3 30115 30184 30116 3 30185 30116 30184 3 30116 30185 30117 3 30186 30117 30185 3 30117 30186 30118 3 30187 30118 30186 3 30118 30187 30119 3 30188 30119 30187 3 30119 30188 30120 3 30189 30120 30188 3 30120 30189 30121 3 30190 30121 30189 3 30121 30190 30122 3 30191 30122 30190 3 30122 30191 30123 3 30192 30123 30191 3 30123 30192 30124 3 30193 30124 30192 3 30124 30193 30125 3 30194 30125 30193 3 30125 30194 30126 3 30195 30126 30194 3 30126 30195 30127 3 30196 30127 30195 3 30127 30196 30128 3 30197 30128 30196 3 30128 30197 30129 3 30198 30129 30197 3 30129 30198 30130 3 30199 30130 30198 3 30130 30199 30131 3 30200 30131 30199 3 30131 30200 30132 3 30201 30132 30200 3 30132 30201 30133 3 30202 30133 30201 3 30133 30202 30134 3 30203 30134 30202 3 30134 30203 30135 3 30204 30135 30203 3 30135 30204 30136 3 30205 30136 30204 3 30136 30205 30137 3 30206 30137 30205 3 30137 30206 30138 3 30207 30138 30206 3 30138 30207 30139 3 30208 30139 30207 3 30139 30208 30140 3 30209 30140 30208 3 30140 30209 30141 3 30210 30141 30209 3 30141 30210 30142 3 30211 30142 30210 3 30143 30212 30144 3 30213 30144 30212 3 30144 30213 30214 3 30144 30214 30145 3 30145 30214 30215 3 30145 30215 30146 3 30146 30215 30216 3 30146 30216 30147 3 30147 30216 30217 3 30147 30217 30148 3 30148 30217 30218 3 30148 30218 30149 3 30149 30218 30219 3 30149 30219 30150 3 30150 30219 30220 3 30150 30220 30151 3 30151 30220 30221 3 30151 30221 30152 3 30152 30221 30222 3 30152 30222 30153 3 30153 30222 30223 3 30153 30223 30154 3 30154 30223 30224 3 30154 30224 30155 3 30155 30224 30225 3 30155 30225 30156 3 30156 30225 30226 3 30156 30226 30157 3 30157 30226 30227 3 30157 30227 30158 3 30158 30227 30228 3 30158 30228 30159 3 30159 30228 30229 3 30159 30229 30160 3 30160 30229 30230 3 30160 30230 30161 3 30161 30230 30231 3 30161 30231 30162 3 30162 30231 30232 3 30162 30232 30163 3 30163 30232 30233 3 30163 30233 30164 3 30164 30233 30234 3 30164 30234 30165 3 30165 30234 30235 3 30165 30235 30166 3 30166 30235 30236 3 30166 30236 30167 3 30167 30236 30237 3 30167 30237 30168 3 30168 30237 30238 3 30168 30238 30169 3 30169 30238 30239 3 30169 30239 30170 3 30170 30239 30240 3 30170 30240 30171 3 30171 30240 30241 3 30171 30241 30172 3 30172 30241 30242 3 30172 30242 30173 3 30173 30242 30243 3 30173 30243 30174 3 30174 30243 30244 3 30174 30244 30175 3 30175 30244 30245 3 30175 30245 30176 3 30176 30245 30246 3 30176 30246 30177 3 30177 30246 30247 3 30177 30247 30178 3 30178 30247 30248 3 30178 30248 30179 3 30179 30248 30249 3 30179 30249 30180 3 30180 30249 30250 3 30180 30250 30181 3 30181 30250 30251 3 30181 30251 30182 3 30182 30251 30252 3 30182 30252 30183 3 30183 30252 30253 3 30183 30253 30184 3 30184 30253 30254 3 30184 30254 30185 3 30185 30254 30255 3 30185 30255 30186 3 30186 30255 30256 3 30186 30256 30187 3 30187 30256 30257 3 30187 30257 30188 3 30188 30257 30258 3 30188 30258 30189 3 30189 30258 30259 3 30189 30259 30190 3 30190 30259 30260 3 30190 30260 30191 3 30191 30260 30261 3 30191 30261 30192 3 30192 30261 30262 3 30192 30262 30193 3 30193 30262 30263 3 30193 30263 30194 3 30194 30263 30264 3 30194 30264 30195 3 30195 30264 30265 3 30195 30265 30196 3 30196 30265 30266 3 30196 30266 30197 3 30197 30266 30267 3 30197 30267 30198 3 30198 30267 30268 3 30198 30268 30199 3 30199 30268 30269 3 30199 30269 30200 3 30200 30269 30270 3 30200 30270 30201 3 30201 30270 30271 3 30201 30271 30202 3 30202 30271 30272 3 30202 30272 30203 3 30203 30272 30273 3 30203 30273 30204 3 30204 30273 30274 3 30204 30274 30205 3 30205 30274 30275 3 30205 30275 30206 3 30206 30275 30276 3 30206 30276 30207 3 30207 30276 30277 3 30207 30277 30208 3 30208 30277 30278 3 30208 30278 30209 3 30209 30278 30279 3 30209 30279 30210 3 30210 30279 30280 3 30210 30280 30211 3 30212 30281 30282 3 30212 30282 30213 3 30213 30282 30283 3 30213 30283 30214 3 30214 30283 30284 3 30214 30284 30215 3 30215 30284 30285 3 30215 30285 30216 3 30216 30285 30286 3 30216 30286 30217 3 30217 30286 30287 3 30217 30287 30218 3 30218 30287 30288 3 30218 30288 30219 3 30219 30288 30289 3 30219 30289 30220 3 30220 30289 30290 3 30220 30290 30221 3 30221 30290 30291 3 30221 30291 30222 3 30222 30291 30292 3 30222 30292 30223 3 30223 30292 30293 3 30223 30293 30224 3 30224 30293 30294 3 30224 30294 30225 3 30225 30294 30295 3 30225 30295 30226 3 30226 30295 30296 3 30226 30296 30227 3 30227 30296 30297 3 30227 30297 30228 3 30228 30297 30298 3 30228 30298 30229 3 30229 30298 30299 3 30229 30299 30230 3 30230 30299 30300 3 30230 30300 30231 3 30231 30300 30301 3 30231 30301 30232 3 30232 30301 30302 3 30232 30302 30233 3 30233 30302 30303 3 30233 30303 30234 3 30234 30303 30304 3 30234 30304 30235 3 30235 30304 30305 3 30235 30305 30236 3 30236 30305 30306 3 30236 30306 30237 3 30237 30306 30307 3 30237 30307 30238 3 30238 30307 30308 3 30238 30308 30239 3 30239 30308 30309 3 30239 30309 30240 3 30240 30309 30310 3 30240 30310 30241 3 30241 30310 30311 3 30241 30311 30242 3 30242 30311 30312 3 30242 30312 30243 3 30243 30312 30313 3 30243 30313 30244 3 30244 30313 30314 3 30244 30314 30245 3 30245 30314 30315 3 30245 30315 30246 3 30246 30315 30316 3 30246 30316 30247 3 30247 30316 30317 3 30247 30317 30248 3 30248 30317 30318 3 30248 30318 30249 3 30249 30318 30319 3 30249 30319 30250 3 30250 30319 30320 3 30250 30320 30251 3 30251 30320 30252 3 30321 30252 30320 3 30252 30321 30253 3 30322 30253 30321 3 30253 30322 30254 3 30323 30254 30322 3 30254 30323 30255 3 30324 30255 30323 3 30255 30324 30256 3 30325 30256 30324 3 30256 30325 30257 3 30326 30257 30325 3 30257 30326 30258 3 30327 30258 30326 3 30258 30327 30259 3 30328 30259 30327 3 30259 30328 30260 3 30329 30260 30328 3 30260 30329 30261 3 30330 30261 30329 3 30261 30330 30262 3 30331 30262 30330 3 30262 30331 30263 3 30332 30263 30331 3 30263 30332 30264 3 30333 30264 30332 3 30264 30333 30265 3 30334 30265 30333 3 30265 30334 30266 3 30335 30266 30334 3 30266 30335 30267 3 30336 30267 30335 3 30267 30336 30268 3 30337 30268 30336 3 30268 30337 30269 3 30338 30269 30337 3 30269 30338 30270 3 30339 30270 30338 3 30270 30339 30271 3 30340 30271 30339 3 30271 30340 30272 3 30341 30272 30340 3 30272 30341 30273 3 30342 30273 30341 3 30273 30342 30274 3 30343 30274 30342 3 30274 30343 30275 3 30344 30275 30343 3 30275 30344 30276 3 30345 30276 30344 3 30276 30345 30277 3 30346 30277 30345 3 30277 30346 30278 3 30347 30278 30346 3 30278 30347 30279 3 30348 30279 30347 3 30279 30348 30280 3 30349 30280 30348 3 30281 30350 30282 3 30351 30282 30350 3 30282 30351 30283 3 30352 30283 30351 3 30283 30352 30284 3 30353 30284 30352 3 30284 30353 30285 3 30354 30285 30353 3 30285 30354 30286 3 30355 30286 30354 3 30286 30355 30287 3 30356 30287 30355 3 30287 30356 30288 3 30357 30288 30356 3 30288 30357 30289 3 30358 30289 30357 3 30289 30358 30290 3 30359 30290 30358 3 30290 30359 30291 3 30360 30291 30359 3 30291 30360 30292 3 30361 30292 30360 3 30292 30361 30293 3 30362 30293 30361 3 30293 30362 30294 3 30363 30294 30362 3 30294 30363 30295 3 30364 30295 30363 3 30295 30364 30296 3 30365 30296 30364 3 30296 30365 30297 3 30366 30297 30365 3 30297 30366 30298 3 30367 30298 30366 3 30298 30367 30299 3 30368 30299 30367 3 30299 30368 30300 3 30369 30300 30368 3 30300 30369 30301 3 30370 30301 30369 3 30301 30370 30302 3 30371 30302 30370 3 30302 30371 30303 3 30372 30303 30371 3 30303 30372 30304 3 30373 30304 30372 3 30304 30373 30305 3 30374 30305 30373 3 30305 30374 30306 3 30375 30306 30374 3 30306 30375 30307 3 30376 30307 30375 3 30307 30376 30308 3 30377 30308 30376 3 30308 30377 30309 3 30378 30309 30377 3 30309 30378 30310 3 30379 30310 30378 3 30310 30379 30311 3 30380 30311 30379 3 30311 30380 30312 3 30381 30312 30380 3 30312 30381 30313 3 30382 30313 30381 3 30313 30382 30314 3 30383 30314 30382 3 30314 30383 30315 3 30384 30315 30383 3 30315 30384 30316 3 30385 30316 30384 3 30316 30385 30317 3 30386 30317 30385 3 30317 30386 30318 3 30387 30318 30386 3 30318 30387 30319 3 30388 30319 30387 3 30319 30388 30320 3 30389 30320 30388 3 30320 30389 30321 3 30390 30321 30389 3 30321 30390 30322 3 30391 30322 30390 3 30322 30391 30323 3 30392 30323 30391 3 30323 30392 30324 3 30393 30324 30392 3 30324 30393 30325 3 30394 30325 30393 3 30325 30394 30326 3 30395 30326 30394 3 30326 30395 30327 3 30396 30327 30395 3 30327 30396 30328 3 30397 30328 30396 3 30328 30397 30329 3 30398 30329 30397 3 30329 30398 30330 3 30399 30330 30398 3 30330 30399 30331 3 30400 30331 30399 3 30331 30400 30332 3 30401 30332 30400 3 30332 30401 30333 3 30402 30333 30401 3 30333 30402 30334 3 30403 30334 30402 3 30334 30403 30335 3 30404 30335 30403 3 30335 30404 30336 3 30405 30336 30404 3 30336 30405 30337 3 30406 30337 30405 3 30337 30406 30338 3 30407 30338 30406 3 30338 30407 30339 3 30408 30339 30407 3 30339 30408 30340 3 30409 30340 30408 3 30340 30409 30341 3 30410 30341 30409 3 30341 30410 30342 3 30411 30342 30410 3 30342 30411 30343 3 30412 30343 30411 3 30343 30412 30344 3 30413 30344 30412 3 30344 30413 30345 3 30414 30345 30413 3 30345 30414 30346 3 30415 30346 30414 3 30346 30415 30347 3 30416 30347 30415 3 30347 30416 30348 3 30417 30348 30416 3 30348 30417 30349 3 30418 30349 30417 3 30350 30419 30351 3 30420 30351 30419 3 30351 30420 30352 3 30421 30352 30420 3 30352 30421 30353 3 30422 30353 30421 3 30353 30422 30354 3 30423 30354 30422 3 30354 30423 30355 3 30424 30355 30423 3 30355 30424 30356 3 30425 30356 30424 3 30356 30425 30357 3 30426 30357 30425 3 30357 30426 30358 3 30427 30358 30426 3 30358 30427 30428 3 30358 30428 30359 3 30359 30428 30429 3 30359 30429 30360 3 30360 30429 30430 3 30360 30430 30361 3 30361 30430 30431 3 30361 30431 30362 3 30362 30431 30432 3 30362 30432 30363 3 30363 30432 30433 3 30363 30433 30364 3 30364 30433 30434 3 30364 30434 30365 3 30365 30434 30435 3 30365 30435 30366 3 30366 30435 30436 3 30366 30436 30367 3 30367 30436 30437 3 30367 30437 30368 3 30368 30437 30438 3 30368 30438 30369 3 30369 30438 30439 3 30369 30439 30370 3 30370 30439 30440 3 30370 30440 30371 3 30371 30440 30441 3 30371 30441 30372 3 30372 30441 30442 3 30372 30442 30373 3 30373 30442 30443 3 30373 30443 30374 3 30374 30443 30444 3 30374 30444 30375 3 30375 30444 30445 3 30375 30445 30376 3 30376 30445 30446 3 30376 30446 30377 3 30377 30446 30447 3 30377 30447 30378 3 30378 30447 30448 3 30378 30448 30379 3 30379 30448 30449 3 30379 30449 30380 3 30380 30449 30450 3 30380 30450 30381 3 30381 30450 30451 3 30381 30451 30382 3 30382 30451 30452 3 30382 30452 30383 3 30383 30452 30453 3 30383 30453 30384 3 30384 30453 30454 3 30384 30454 30385 3 30385 30454 30455 3 30385 30455 30386 3 30386 30455 30456 3 30386 30456 30387 3 30387 30456 30457 3 30387 30457 30388 3 30388 30457 30458 3 30388 30458 30389 3 30389 30458 30459 3 30389 30459 30390 3 30390 30459 30460 3 30390 30460 30391 3 30391 30460 30461 3 30391 30461 30392 3 30392 30461 30462 3 30392 30462 30393 3 30393 30462 30463 3 30393 30463 30394 3 30394 30463 30464 3 30394 30464 30395 3 30395 30464 30465 3 30395 30465 30396 3 30396 30465 30466 3 30396 30466 30397 3 30397 30466 30467 3 30397 30467 30398 3 30398 30467 30468 3 30398 30468 30399 3 30399 30468 30469 3 30399 30469 30400 3 30400 30469 30470 3 30400 30470 30401 3 30401 30470 30471 3 30401 30471 30402 3 30402 30471 30472 3 30402 30472 30403 3 30403 30472 30473 3 30403 30473 30404 3 30404 30473 30474 3 30404 30474 30405 3 30405 30474 30475 3 30405 30475 30406 3 30406 30475 30476 3 30406 30476 30407 3 30407 30476 30477 3 30407 30477 30408 3 30408 30477 30478 3 30408 30478 30409 3 30409 30478 30479 3 30409 30479 30410 3 30410 30479 30480 3 30410 30480 30411 3 30411 30480 30481 3 30411 30481 30412 3 30412 30481 30482 3 30412 30482 30413 3 30413 30482 30483 3 30413 30483 30414 3 30414 30483 30484 3 30414 30484 30415 3 30415 30484 30485 3 30415 30485 30416 3 30416 30485 30486 3 30416 30486 30417 3 30417 30486 30487 3 30417 30487 30418 3 30419 30488 30489 3 30419 30489 30420 3 30420 30489 30490 3 30420 30490 30421 3 30421 30490 30491 3 30421 30491 30422 3 30422 30491 30492 3 30422 30492 30423 3 30423 30492 30493 3 30423 30493 30424 3 30424 30493 30494 3 30424 30494 30425 3 30425 30494 30495 3 30425 30495 30426 3 30426 30495 30496 3 30426 30496 30427 3 30427 30496 30497 3 30427 30497 30428 3 30428 30497 30498 3 30428 30498 30429 3 30429 30498 30499 3 30429 30499 30430 3 30430 30499 30500 3 30430 30500 30431 3 30431 30500 30501 3 30431 30501 30432 3 30432 30501 30502 3 30432 30502 30433 3 30433 30502 30503 3 30433 30503 30434 3 30434 30503 30504 3 30434 30504 30435 3 30435 30504 30505 3 30435 30505 30436 3 30436 30505 30506 3 30436 30506 30437 3 30437 30506 30507 3 30437 30507 30438 3 30438 30507 30508 3 30438 30508 30439 3 30439 30508 30509 3 30439 30509 30440 3 30440 30509 30510 3 30440 30510 30441 3 30441 30510 30511 3 30441 30511 30442 3 30442 30511 30512 3 30442 30512 30443 3 30443 30512 30513 3 30443 30513 30444 3 30444 30513 30514 3 30444 30514 30445 3 30445 30514 30515 3 30445 30515 30446 3 30446 30515 30516 3 30446 30516 30447 3 30447 30516 30517 3 30447 30517 30448 3 30448 30517 30518 3 30448 30518 30449 3 30449 30518 30519 3 30449 30519 30450 3 30450 30519 30520 3 30450 30520 30451 3 30451 30520 30521 3 30451 30521 30452 3 30452 30521 30522 3 30452 30522 30453 3 30453 30522 30523 3 30453 30523 30454 3 30454 30523 30524 3 30454 30524 30455 3 30455 30524 30525 3 30455 30525 30456 3 30456 30525 30526 3 30456 30526 30457 3 30457 30526 30527 3 30457 30527 30458 3 30458 30527 30528 3 30458 30528 30459 3 30459 30528 30529 3 30459 30529 30460 3 30460 30529 30530 3 30460 30530 30461 3 30461 30530 30531 3 30461 30531 30462 3 30462 30531 30532 3 30462 30532 30463 3 30463 30532 30533 3 30463 30533 30464 3 30464 30533 30534 3 30464 30534 30465 3 30465 30534 30535 3 30465 30535 30466 3 30466 30535 30467 3 30536 30467 30535 3 30467 30536 30468 3 30537 30468 30536 3 30468 30537 30469 3 30538 30469 30537 3 30469 30538 30470 3 30539 30470 30538 3 30470 30539 30471 3 30540 30471 30539 3 30471 30540 30472 3 30541 30472 30540 3 30472 30541 30473 3 30542 30473 30541 3 30473 30542 30474 3 30543 30474 30542 3 30474 30543 30475 3 30544 30475 30543 3 30475 30544 30476 3 30545 30476 30544 3 30476 30545 30477 3 30546 30477 30545 3 30477 30546 30478 3 30547 30478 30546 3 30478 30547 30479 3 30548 30479 30547 3 30479 30548 30480 3 30549 30480 30548 3 30480 30549 30481 3 30550 30481 30549 3 30481 30550 30482 3 30551 30482 30550 3 30482 30551 30483 3 30552 30483 30551 3 30483 30552 30484 3 30553 30484 30552 3 30484 30553 30485 3 30554 30485 30553 3 30485 30554 30486 3 30555 30486 30554 3 30486 30555 30487 3 30556 30487 30555 3 30488 30557 30489 3 30558 30489 30557 3 30489 30558 30490 3 30559 30490 30558 3 30490 30559 30491 3 30560 30491 30559 3 30491 30560 30492 3 30561 30492 30560 3 30492 30561 30493 3 30562 30493 30561 3 30493 30562 30494 3 30563 30494 30562 3 30494 30563 30495 3 30564 30495 30563 3 30495 30564 30496 3 30565 30496 30564 3 30496 30565 30497 3 30566 30497 30565 3 30497 30566 30498 3 30567 30498 30566 3 30498 30567 30499 3 30568 30499 30567 3 30499 30568 30500 3 30569 30500 30568 3 30500 30569 30501 3 30570 30501 30569 3 30501 30570 30502 3 30571 30502 30570 3 30502 30571 30503 3 30572 30503 30571 3 30503 30572 30504 3 30573 30504 30572 3 30504 30573 30505 3 30574 30505 30573 3 30505 30574 30506 3 30575 30506 30574 3 30506 30575 30507 3 30576 30507 30575 3 30507 30576 30508 3 30577 30508 30576 3 30508 30577 30509 3 30578 30509 30577 3 30509 30578 30510 3 30579 30510 30578 3 30510 30579 30511 3 30580 30511 30579 3 30511 30580 30512 3 30581 30512 30580 3 30512 30581 30513 3 30582 30513 30581 3 30513 30582 30514 3 30583 30514 30582 3 30514 30583 30515 3 30584 30515 30583 3 30515 30584 30516 3 30585 30516 30584 3 30516 30585 30517 3 30586 30517 30585 3 30517 30586 30518 3 30587 30518 30586 3 30518 30587 30519 3 30588 30519 30587 3 30519 30588 30520 3 30589 30520 30588 3 30520 30589 30521 3 30590 30521 30589 3 30521 30590 30522 3 30591 30522 30590 3 30522 30591 30523 3 30592 30523 30591 3 30523 30592 30524 3 30593 30524 30592 3 30524 30593 30525 3 30594 30525 30593 3 30525 30594 30526 3 30595 30526 30594 3 30526 30595 30527 3 30596 30527 30595 3 30527 30596 30528 3 30597 30528 30596 3 30528 30597 30529 3 30598 30529 30597 3 30529 30598 30530 3 30599 30530 30598 3 30530 30599 30531 3 30600 30531 30599 3 30531 30600 30532 3 30601 30532 30600 3 30532 30601 30533 3 30602 30533 30601 3 30533 30602 30534 3 30603 30534 30602 3 30534 30603 30535 3 30604 30535 30603 3 30535 30604 30536 3 30605 30536 30604 3 30536 30605 30537 3 30606 30537 30605 3 30537 30606 30538 3 30607 30538 30606 3 30538 30607 30539 3 30608 30539 30607 3 30539 30608 30540 3 30609 30540 30608 3 30540 30609 30541 3 30610 30541 30609 3 30541 30610 30542 3 30611 30542 30610 3 30542 30611 30543 3 30612 30543 30611 3 30543 30612 30544 3 30613 30544 30612 3 30544 30613 30545 3 30614 30545 30613 3 30545 30614 30546 3 30615 30546 30614 3 30546 30615 30547 3 30616 30547 30615 3 30547 30616 30548 3 30617 30548 30616 3 30548 30617 30549 3 30618 30549 30617 3 30549 30618 30550 3 30619 30550 30618 3 30550 30619 30551 3 30620 30551 30619 3 30551 30620 30552 3 30621 30552 30620 3 30552 30621 30553 3 30622 30553 30621 3 30553 30622 30554 3 30623 30554 30622 3 30554 30623 30555 3 30624 30555 30623 3 30555 30624 30556 3 30625 30556 30624 3 30557 30626 30558 3 30627 30558 30626 3 30558 30627 30559 3 30628 30559 30627 3 30559 30628 30560 3 30629 30560 30628 3 30560 30629 30561 3 30630 30561 30629 3 30561 30630 30562 3 30631 30562 30630 3 30562 30631 30563 3 30632 30563 30631 3 30563 30632 30564 3 30633 30564 30632 3 30564 30633 30565 3 30634 30565 30633 3 30565 30634 30566 3 30635 30566 30634 3 30566 30635 30567 3 30636 30567 30635 3 30567 30636 30568 3 30637 30568 30636 3 30568 30637 30569 3 30638 30569 30637 3 30569 30638 30570 3 30639 30570 30638 3 30570 30639 30571 3 30640 30571 30639 3 30571 30640 30572 3 30641 30572 30640 3 30572 30641 30573 3 30642 30573 30641 3 30573 30642 30643 3 30573 30643 30574 3 30574 30643 30644 3 30574 30644 30575 3 30575 30644 30645 3 30575 30645 30576 3 30576 30645 30646 3 30576 30646 30577 3 30577 30646 30647 3 30577 30647 30578 3 30578 30647 30648 3 30578 30648 30579 3 30579 30648 30649 3 30579 30649 30580 3 30580 30649 30650 3 30580 30650 30581 3 30581 30650 30651 3 30581 30651 30582 3 30582 30651 30652 3 30582 30652 30583 3 30583 30652 30653 3 30583 30653 30584 3 30584 30653 30654 3 30584 30654 30585 3 30585 30654 30655 3 30585 30655 30586 3 30586 30655 30656 3 30586 30656 30587 3 30587 30656 30657 3 30587 30657 30588 3 30588 30657 30658 3 30588 30658 30589 3 30589 30658 30659 3 30589 30659 30590 3 30590 30659 30660 3 30590 30660 30591 3 30591 30660 30661 3 30591 30661 30592 3 30592 30661 30662 3 30592 30662 30593 3 30593 30662 30663 3 30593 30663 30594 3 30594 30663 30664 3 30594 30664 30595 3 30595 30664 30665 3 30595 30665 30596 3 30596 30665 30666 3 30596 30666 30597 3 30597 30666 30667 3 30597 30667 30598 3 30598 30667 30668 3 30598 30668 30599 3 30599 30668 30669 3 30599 30669 30600 3 30600 30669 30670 3 30600 30670 30601 3 30601 30670 30671 3 30601 30671 30602 3 30602 30671 30672 3 30602 30672 30603 3 30603 30672 30673 3 30603 30673 30604 3 30604 30673 30674 3 30604 30674 30605 3 30605 30674 30675 3 30605 30675 30606 3 30606 30675 30676 3 30606 30676 30607 3 30607 30676 30677 3 30607 30677 30608 3 30608 30677 30678 3 30608 30678 30609 3 30609 30678 30679 3 30609 30679 30610 3 30610 30679 30680 3 30610 30680 30611 3 30611 30680 30681 3 30611 30681 30612 3 30612 30681 30682 3 30612 30682 30613 3 30613 30682 30683 3 30613 30683 30614 3 30614 30683 30684 3 30614 30684 30615 3 30615 30684 30685 3 30615 30685 30616 3 30616 30685 30686 3 30616 30686 30617 3 30617 30686 30687 3 30617 30687 30618 3 30618 30687 30688 3 30618 30688 30619 3 30619 30688 30689 3 30619 30689 30620 3 30620 30689 30690 3 30620 30690 30621 3 30621 30690 30691 3 30621 30691 30622 3 30622 30691 30692 3 30622 30692 30623 3 30623 30692 30693 3 30623 30693 30624 3 30624 30693 30694 3 30624 30694 30625 3 30626 30695 30696 3 30626 30696 30627 3 30627 30696 30697 3 30627 30697 30628 3 30628 30697 30698 3 30628 30698 30629 3 30629 30698 30699 3 30629 30699 30630 3 30630 30699 30700 3 30630 30700 30631 3 30631 30700 30701 3 30631 30701 30632 3 30632 30701 30702 3 30632 30702 30633 3 30633 30702 30703 3 30633 30703 30634 3 30634 30703 30704 3 30634 30704 30635 3 30635 30704 30705 3 30635 30705 30636 3 30636 30705 30706 3 30636 30706 30637 3 30637 30706 30707 3 30637 30707 30638 3 30638 30707 30708 3 30638 30708 30639 3 30639 30708 30709 3 30639 30709 30640 3 30640 30709 30710 3 30640 30710 30641 3 30641 30710 30711 3 30641 30711 30642 3 30642 30711 30712 3 30642 30712 30643 3 30643 30712 30713 3 30643 30713 30644 3 30644 30713 30714 3 30644 30714 30645 3 30645 30714 30715 3 30645 30715 30646 3 30646 30715 30716 3 30646 30716 30647 3 30647 30716 30717 3 30647 30717 30648 3 30648 30717 30718 3 30648 30718 30649 3 30649 30718 30719 3 30649 30719 30650 3 30650 30719 30720 3 30650 30720 30651 3 30651 30720 30721 3 30651 30721 30652 3 30652 30721 30722 3 30652 30722 30653 3 30653 30722 30723 3 30653 30723 30654 3 30654 30723 30724 3 30654 30724 30655 3 30655 30724 30725 3 30655 30725 30656 3 30656 30725 30726 3 30656 30726 30657 3 30657 30726 30727 3 30657 30727 30658 3 30658 30727 30728 3 30658 30728 30659 3 30659 30728 30729 3 30659 30729 30660 3 30660 30729 30730 3 30660 30730 30661 3 30661 30730 30731 3 30661 30731 30662 3 30662 30731 30732 3 30662 30732 30663 3 30663 30732 30733 3 30663 30733 30664 3 30664 30733 30734 3 30664 30734 30665 3 30665 30734 30735 3 30665 30735 30666 3 30666 30735 30736 3 30666 30736 30667 3 30667 30736 30737 3 30667 30737 30668 3 30668 30737 30738 3 30668 30738 30669 3 30669 30738 30739 3 30669 30739 30670 3 30670 30739 30740 3 30670 30740 30671 3 30671 30740 30741 3 30671 30741 30672 3 30672 30741 30742 3 30672 30742 30673 3 30673 30742 30743 3 30673 30743 30674 3 30674 30743 30744 3 30674 30744 30675 3 30675 30744 30745 3 30675 30745 30676 3 30676 30745 30746 3 30676 30746 30677 3 30677 30746 30747 3 30677 30747 30678 3 30678 30747 30748 3 30678 30748 30679 3 30679 30748 30749 3 30679 30749 30680 3 30680 30749 30750 3 30680 30750 30681 3 30681 30750 30682 3 30751 30682 30750 3 30682 30751 30683 3 30752 30683 30751 3 30683 30752 30684 3 30753 30684 30752 3 30684 30753 30685 3 30754 30685 30753 3 30685 30754 30686 3 30755 30686 30754 3 30686 30755 30687 3 30756 30687 30755 3 30687 30756 30688 3 30757 30688 30756 3 30688 30757 30689 3 30758 30689 30757 3 30689 30758 30690 3 30759 30690 30758 3 30690 30759 30691 3 30760 30691 30759 3 30691 30760 30692 3 30761 30692 30760 3 30692 30761 30693 3 30762 30693 30761 3 30693 30762 30694 3 30763 30694 30762 3 30695 30764 30696 3 30765 30696 30764 3 30696 30765 30697 3 30766 30697 30765 3 30697 30766 30698 3 30767 30698 30766 3 30698 30767 30699 3 30768 30699 30767 3 30699 30768 30700 3 30769 30700 30768 3 30700 30769 30701 3 30770 30701 30769 3 30701 30770 30702 3 30771 30702 30770 3 30702 30771 30703 3 30772 30703 30771 3 30703 30772 30704 3 30773 30704 30772 3 30704 30773 30705 3 30774 30705 30773 3 30705 30774 30706 3 30775 30706 30774 3 30706 30775 30707 3 30776 30707 30775 3 30707 30776 30708 3 30777 30708 30776 3 30708 30777 30709 3 30778 30709 30777 3 30709 30778 30710 3 30779 30710 30778 3 30710 30779 30711 3 30780 30711 30779 3 30711 30780 30712 3 30781 30712 30780 3 30712 30781 30713 3 30782 30713 30781 3 30713 30782 30714 3 30783 30714 30782 3 30714 30783 30715 3 30784 30715 30783 3 30715 30784 30716 3 30785 30716 30784 3 30716 30785 30717 3 30786 30717 30785 3 30717 30786 30718 3 30787 30718 30786 3 30718 30787 30719 3 30788 30719 30787 3 30719 30788 30720 3 30789 30720 30788 3 30720 30789 30721 3 30790 30721 30789 3 30721 30790 30722 3 30791 30722 30790 3 30722 30791 30723 3 30792 30723 30791 3 30723 30792 30724 3 30793 30724 30792 3 30724 30793 30725 3 30794 30725 30793 3 30725 30794 30726 3 30795 30726 30794 3 30726 30795 30727 3 30796 30727 30795 3 30727 30796 30728 3 30797 30728 30796 3 30728 30797 30729 3 30798 30729 30797 3 30729 30798 30730 3 30799 30730 30798 3 30730 30799 30731 3 30800 30731 30799 3 30731 30800 30732 3 30801 30732 30800 3 30732 30801 30733 3 30802 30733 30801 3 30733 30802 30734 3 30803 30734 30802 3 30734 30803 30735 3 30804 30735 30803 3 30735 30804 30736 3 30805 30736 30804 3 30736 30805 30737 3 30806 30737 30805 3 30737 30806 30738 3 30807 30738 30806 3 30738 30807 30739 3 30808 30739 30807 3 30739 30808 30740 3 30809 30740 30808 3 30740 30809 30741 3 30810 30741 30809 3 30741 30810 30742 3 30811 30742 30810 3 30742 30811 30743 3 30812 30743 30811 3 30743 30812 30744 3 30813 30744 30812 3 30744 30813 30745 3 30814 30745 30813 3 30745 30814 30746 3 30815 30746 30814 3 30746 30815 30747 3 30816 30747 30815 3 30747 30816 30748 3 30817 30748 30816 3 30748 30817 30749 3 30818 30749 30817 3 30749 30818 30750 3 30819 30750 30818 3 30750 30819 30751 3 30820 30751 30819 3 30751 30820 30752 3 30821 30752 30820 3 30752 30821 30753 3 30822 30753 30821 3 30753 30822 30754 3 30823 30754 30822 3 30754 30823 30755 3 30824 30755 30823 3 30755 30824 30756 3 30825 30756 30824 3 30756 30825 30757 3 30826 30757 30825 3 30757 30826 30758 3 30827 30758 30826 3 30758 30827 30759 3 30828 30759 30827 3 30759 30828 30760 3 30829 30760 30828 3 30760 30829 30761 3 30830 30761 30829 3 30761 30830 30762 3 30831 30762 30830 3 30762 30831 30763 3 30832 30763 30831 3 30764 30833 30765 3 30834 30765 30833 3 30765 30834 30766 3 30835 30766 30834 3 30766 30835 30767 3 30836 30767 30835 3 30767 30836 30768 3 30837 30768 30836 3 30768 30837 30769 3 30838 30769 30837 3 30769 30838 30770 3 30839 30770 30838 3 30770 30839 30771 3 30840 30771 30839 3 30771 30840 30772 3 30841 30772 30840 3 30772 30841 30773 3 30842 30773 30841 3 30773 30842 30774 3 30843 30774 30842 3 30774 30843 30775 3 30844 30775 30843 3 30775 30844 30776 3 30845 30776 30844 3 30776 30845 30777 3 30846 30777 30845 3 30777 30846 30778 3 30847 30778 30846 3 30778 30847 30779 3 30848 30779 30847 3 30779 30848 30780 3 30849 30780 30848 3 30780 30849 30781 3 30850 30781 30849 3 30781 30850 30782 3 30851 30782 30850 3 30782 30851 30783 3 30852 30783 30851 3 30783 30852 30784 3 30853 30784 30852 3 30784 30853 30785 3 30854 30785 30853 3 30785 30854 30786 3 30855 30786 30854 3 30786 30855 30787 3 30856 30787 30855 3 30787 30856 30788 3 30857 30788 30856 3 30788 30857 30789 3 30858 30789 30857 3 30789 30858 30859 3 30789 30859 30790 3 30790 30859 30860 3 30790 30860 30791 3 30791 30860 30861 3 30791 30861 30792 3 30792 30861 30862 3 30792 30862 30793 3 30793 30862 30863 3 30793 30863 30794 3 30794 30863 30864 3 30794 30864 30795 3 30795 30864 30865 3 30795 30865 30796 3 30796 30865 30866 3 30796 30866 30797 3 30797 30866 30867 3 30797 30867 30798 3 30798 30867 30868 3 30798 30868 30799 3 30799 30868 30869 3 30799 30869 30800 3 30800 30869 30870 3 30800 30870 30801 3 30801 30870 30871 3 30801 30871 30802 3 30802 30871 30872 3 30802 30872 30803 3 30803 30872 30873 3 30803 30873 30804 3 30804 30873 30874 3 30804 30874 30805 3 30805 30874 30875 3 30805 30875 30806 3 30806 30875 30876 3 30806 30876 30807 3 30807 30876 30877 3 30807 30877 30808 3 30808 30877 30878 3 30808 30878 30809 3 30809 30878 30879 3 30809 30879 30810 3 30810 30879 30880 3 30810 30880 30811 3 30811 30880 30881 3 30811 30881 30812 3 30812 30881 30882 3 30812 30882 30813 3 30813 30882 30883 3 30813 30883 30814 3 30814 30883 30884 3 30814 30884 30815 3 30815 30884 30885 3 30815 30885 30816 3 30816 30885 30886 3 30816 30886 30817 3 30817 30886 30887 3 30817 30887 30818 3 30818 30887 30888 3 30818 30888 30819 3 30819 30888 30889 3 30819 30889 30820 3 30820 30889 30890 3 30820 30890 30821 3 30821 30890 30891 3 30821 30891 30822 3 30822 30891 30892 3 30822 30892 30823 3 30823 30892 30893 3 30823 30893 30824 3 30824 30893 30894 3 30824 30894 30825 3 30825 30894 30895 3 30825 30895 30826 3 30826 30895 30896 3 30826 30896 30827 3 30827 30896 30897 3 30827 30897 30828 3 30828 30897 30898 3 30828 30898 30829 3 30829 30898 30899 3 30829 30899 30830 3 30830 30899 30900 3 30830 30900 30831 3 30831 30900 30901 3 30831 30901 30832 3 30834 30902 30903 3 30834 30903 30835 3 30835 30903 30904 3 30835 30904 30836 3 30836 30904 30905 3 30836 30905 30837 3 30837 30905 30906 3 30837 30906 30838 3 30838 30906 30907 3 30838 30907 30839 3 30839 30907 30908 3 30839 30908 30840 3 30840 30908 30909 3 30840 30909 30841 3 30841 30909 30910 3 30841 30910 30842 3 30842 30910 30911 3 30842 30911 30843 3 30843 30911 30912 3 30843 30912 30844 3 30844 30912 30913 3 30844 30913 30845 3 30845 30913 30914 3 30845 30914 30846 3 30846 30914 30915 3 30846 30915 30847 3 30847 30915 30916 3 30847 30916 30848 3 30848 30916 30917 3 30848 30917 30849 3 30849 30917 30918 3 30849 30918 30850 3 30850 30918 30919 3 30850 30919 30851 3 30851 30919 30920 3 30851 30920 30852 3 30852 30920 30921 3 30852 30921 30853 3 30853 30921 30922 3 30853 30922 30854 3 30854 30922 30923 3 30854 30923 30855 3 30855 30923 30924 3 30855 30924 30856 3 30856 30924 30925 3 30856 30925 30857 3 30857 30925 30926 3 30857 30926 30858 3 30858 30926 30927 3 30858 30927 30859 3 30859 30927 30928 3 30859 30928 30860 3 30860 30928 30929 3 30860 30929 30861 3 30861 30929 30930 3 30861 30930 30862 3 30862 30930 30931 3 30862 30931 30863 3 30863 30931 30932 3 30863 30932 30864 3 30864 30932 30933 3 30864 30933 30865 3 30865 30933 30934 3 30865 30934 30866 3 30866 30934 30935 3 30866 30935 30867 3 30867 30935 30936 3 30867 30936 30868 3 30868 30936 30937 3 30868 30937 30869 3 30869 30937 30938 3 30869 30938 30870 3 30870 30938 30939 3 30870 30939 30871 3 30871 30939 30940 3 30871 30940 30872 3 30872 30940 30941 3 30872 30941 30873 3 30873 30941 30942 3 30873 30942 30874 3 30874 30942 30943 3 30874 30943 30875 3 30875 30943 30944 3 30875 30944 30876 3 30876 30944 30945 3 30876 30945 30877 3 30877 30945 30946 3 30877 30946 30878 3 30878 30946 30947 3 30878 30947 30879 3 30879 30947 30948 3 30879 30948 30880 3 30880 30948 30949 3 30880 30949 30881 3 30881 30949 30950 3 30881 30950 30882 3 30882 30950 30951 3 30882 30951 30883 3 30883 30951 30952 3 30883 30952 30884 3 30884 30952 30953 3 30884 30953 30885 3 30885 30953 30954 3 30885 30954 30886 3 30886 30954 30955 3 30886 30955 30887 3 30887 30955 30956 3 30887 30956 30888 3 30888 30956 30957 3 30888 30957 30889 3 30889 30957 30958 3 30889 30958 30890 3 30890 30958 30959 3 30890 30959 30891 3 30891 30959 30960 3 30891 30960 30892 3 30892 30960 30961 3 30892 30961 30893 3 30893 30961 30962 3 30893 30962 30894 3 30894 30962 30963 3 30894 30963 30895 3 30895 30963 30964 3 30895 30964 30896 3 30896 30964 30965 3 30896 30965 30897 3 30897 30965 30966 3 30897 30966 30898 3 30898 30966 30899 3 30967 30899 30966 3 30899 30967 30900 3 30968 30900 30967 3 30903 30969 30904 3 30970 30904 30969 3 30904 30970 30905 3 30971 30905 30970 3 30905 30971 30906 3 30972 30906 30971 3 30906 30972 30907 3 30973 30907 30972 3 30907 30973 30908 3 30974 30908 30973 3 30908 30974 30909 3 30975 30909 30974 3 30909 30975 30910 3 30976 30910 30975 3 30910 30976 30911 3 30977 30911 30976 3 30911 30977 30912 3 30978 30912 30977 3 30912 30978 30913 3 30979 30913 30978 3 30913 30979 30914 3 30980 30914 30979 3 30914 30980 30915 3 30981 30915 30980 3 30915 30981 30916 3 30982 30916 30981 3 30916 30982 30917 3 30983 30917 30982 3 30917 30983 30918 3 30984 30918 30983 3 30918 30984 30919 3 30985 30919 30984 3 30919 30985 30920 3 30986 30920 30985 3 30920 30986 30921 3 30987 30921 30986 3 30921 30987 30922 3 30988 30922 30987 3 30922 30988 30923 3 30989 30923 30988 3 30923 30989 30924 3 30990 30924 30989 3 30924 30990 30925 3 30991 30925 30990 3 30925 30991 30926 3 30992 30926 30991 3 30926 30992 30927 3 30993 30927 30992 3 30927 30993 30928 3 30994 30928 30993 3 30928 30994 30929 3 30995 30929 30994 3 30929 30995 30930 3 30996 30930 30995 3 30930 30996 30931 3 30997 30931 30996 3 30931 30997 30932 3 30998 30932 30997 3 30932 30998 30933 3 30999 30933 30998 3 30933 30999 30934 3 31000 30934 30999 3 30934 31000 30935 3 31001 30935 31000 3 30935 31001 30936 3 31002 30936 31001 3 30936 31002 30937 3 31003 30937 31002 3 30937 31003 30938 3 31004 30938 31003 3 30938 31004 30939 3 31005 30939 31004 3 30939 31005 30940 3 31006 30940 31005 3 30940 31006 30941 3 31007 30941 31006 3 30941 31007 30942 3 31008 30942 31007 3 30942 31008 30943 3 31009 30943 31008 3 30943 31009 30944 3 31010 30944 31009 3 30944 31010 30945 3 31011 30945 31010 3 30945 31011 30946 3 31012 30946 31011 3 30946 31012 30947 3 31013 30947 31012 3 30947 31013 30948 3 31014 30948 31013 3 30948 31014 30949 3 31015 30949 31014 3 30949 31015 30950 3 31016 30950 31015 3 30950 31016 30951 3 31017 30951 31016 3 30951 31017 30952 3 31018 30952 31017 3 30952 31018 30953 3 31019 30953 31018 3 30953 31019 30954 3 31020 30954 31019 3 30954 31020 30955 3 31021 30955 31020 3 30955 31021 30956 3 31022 30956 31021 3 30956 31022 30957 3 31023 30957 31022 3 30957 31023 30958 3 31024 30958 31023 3 30958 31024 30959 3 31025 30959 31024 3 30959 31025 30960 3 31026 30960 31025 3 30960 31026 30961 3 31027 30961 31026 3 30961 31027 30962 3 31028 30962 31027 3 30962 31028 30963 3 31029 30963 31028 3 30963 31029 30964 3 31030 30964 31029 3 30964 31030 30965 3 31031 30965 31030 3 30965 31031 30966 3 31032 30966 31031 3 30966 31032 30967 3 31033 30967 31032 nipype-0.11.0/nipype/testing/data/surf1.vtk000066400000000000000000000000001257611314500205500ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/surf2.vtk000066400000000000000000000000001257611314500205510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/targets_MASK1.nii000066400000000000000000000000001257611314500220300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/targets_MASK2.nii000066400000000000000000000000001257611314500220310ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tbss_dir/000077500000000000000000000000001257611314500206055ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tbss_dir/do_not_delete.txt000066400000000000000000000000731257611314500241520ustar00rootroot00000000000000This file has to be here because git ignores empty folders.nipype-0.11.0/nipype/testing/data/tdi.mif000066400000000000000000000000001257611314500202370ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tensor_fitted_data.Bdouble000066400000000000000000000000001257611314500241220ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/timeDesign.con000066400000000000000000000000001257611314500215530ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/timeDesign.mat000066400000000000000000000000001257611314500215550ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/timeseries.txt000066400000000000000000000000001257611314500216740ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/topup_encoding.txt000066400000000000000000000000001257611314500225400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/topup_fieldcoef.nii.gz000066400000000000000000000000001257611314500232510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/topup_movpar.txt000066400000000000000000000000001257611314500222560ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tpm_00.nii.gz000066400000000000000000004726171257611314500212340ustar00rootroot00000000000000‹|†S˙normtpm_00.niiě] |›UąĎ„ů0 ’®m’÷MAI‡[0§´SD‚ĘG;Y@á’‚řôf‚–!)0LHdfЏv€@Ć—7Ý˝x! WHAD2!E˝\îóNÎűľIŰ}°¦íŕĽűuď×yĎyž˙sľsž˙9y†Íć˙młÇlólźˇż•Őěi;Ä6ŰQG™xgňďç Ä5nŕ˙ÇřďS=_ýęľŃsĆW{Ztę·ň·Ô¦ű#ŕ6>‚.ć!eäó:Ňáľęw¸“ĎFĐ7N᫏sZýŐÔťB@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P(¶;âA›Mţmw“ŔRvyŢ”2L<Ř›HĚďĎśĺ_űíÄüM}1}ß™şlZFî«Ű‚×öőÍ‹hźĐ3™—|+–˝1oÓßMĹ[«NÖë±d±ľŻľN.ß-ř?\<+ٶ»”^ô!†ÁDŇ?VLS÷ rŰ‚·ţÔm”Á×_‹צ\ŐúŐćů?˝ôŇüűď»Ď°çęŐ«§užvćҰëů ’V jőłŢçţ'ő>}ţ`âX•\çóŮÄmú\˝óÎ;¤g[ygč »Yuďz(lPčmłAßV:çż@ů;9-Ëp-ć›Î»ăéŚçzéŚŕ}”ŻQo ¬ýřüë®Ý7řŰ»`˙íáŘĽŢ=ÎťőţĚ˝ş3÷eeŔŠę.łLlúJˇ7ŽŃú÷ĺ»ôÎHPłŮîńt‡bŢţĚď´Ň«_çň\^İ}ý/ő­ŐÝÔ"tý7Ľ;^§Ł„j,üE‹hOłîŮÔßô ]/O-ÂOݱ±t6ó/ü‘dśÁ>ľ…ŽuČ=ZWÓžŁßŮwÜŔ-çßÁđMoů ⸟źeSÇď¦Fóxr®K\ ĄZ1đYí€lĘ#eˇňHü*ÎůŇ—˝şlĆ(łx–6¤Üţvš~rŮv±ˇŰĘ G °$ť™§E¦1gÎg’[dMŤHĺ#ww›ł/â°x>BqóŮq©&Ăâ~*ŹÇÉO»±°ç9Ô=ý™ýXŢ í.˛ßz]ĘŽ}°i1°;Ő7ó÷Ź,?yŢP×ţéâľ%gĽ4ő+‰Ľ‘ä}€ę5Ř}ôqĂÖx780ŹËDűăŰő>ňt–G{ňűľŢň•üý0m}ŕ{3Ę<:ŕţP~©Lóú4”v2l/őCÔß•ĽţO ¶ťę˛kĘ·ą+łŽ˛ÖWâÚfseS­%×á­eAě‘J}7úŕ·ą”¦Ď{)?$’×â|BřŁl㡮łĽáđ“܎æµá$>ÓG§ÍI"ő­łµĚ¦®b‹ü,ż±ž7—Ît|o•߼Fť;®¤şgQŻ™ďM›OGť6%“©ę3Sóą|&1Ŕ}ŮjëĎ4P]ŤpŰŰ!ułŮŞyýäóńÎ>ˇvl{Ôy,Ť§§x.Ć c}·˝?Ű”ŢŰ»n›’,˝7~{~7–®ňŮö¬×¦d—úÉ3ÂZŻ7ő­z§P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P(  ס㼥‡ő›Úë-Ťc*ÂŤĄŁUţMÉd†Żč0ů¸?ý48*Ěç›úzňßYĺׯüůĚŕ=·Fćx>˝Žéׇ?0íýqöîĎĽbřÎög ~đúOľ†Ő) á‹ ţaúg‡ô6卋Źx‡ďđ,›şÂŰXŘźýž‰ă@ďýKëĎśEÜă·ú[šßOöU<řĺĂ ]Âż©÷gćęý™ăüđU·úšú[e´bńě!ť/wöE¨ˇ®|ZúmćD >ň)=J×Ňó8/Xc™Ěkđ-„ĂGłMĆJţüđ˙7ő…ŽÖCč,ą´ôWŤ¸:#×úŰ+|řRKź˘Ďś"‡ÜĂźbů{Ë ţ-]2¸I źä €Í«ő6í‹w1»—uͦŽňˇˇôUC_Ä<×ćއĂoN?‰°ń°ř Ł–ţ;Ë|žsˇg¨ë8ćcȦň†Ü 7çGÁÓ ô˝ő§î`8|µĚ$źGgDÓzśűčSh*ţ(z˛68Ć΄ľüZ˛8ÇČÖpőĽ~ýŞĹAČŘ©Çy‰ćÎ.dü›˛ß4ä™Yč7ô†<ů®ą:¸`óľ|ăĐů×—OR]ő¨·äĘr^‘yߎڔ\7ë¨çÜŮëĎăg“në?řT®c­ľ¬ŕŞ€|âXĚ2 u}PĽgjKµĹˇ#5đŤpńŕňĺ»U•mik|ßž<Ś8+®aL†»W8l¶#v?¦-=đIÓJb“vŻ„L,›úçĎ6őjU™FľüŤ¤Ă\Ö_č&ň÷ąN‘'‡…1z¦#î[›(·v‡śś?¬¶‡?Ę4χL{2ϰS_ţ{ŚůPWHC›…ô;#Ý$Ż®…biíFâFęşTsţG‡rP°ôŻP¦ĄĚ ĄŮž#ÄÉŃěz.÷IN-„©đźÇĎ[UĺE~?Yç%k~1ö¦~o8°‘ätV•3هçJć:ů\ŘNŘ\Öň÷ˇŘ? ťJ.Űú\F¶‹Q'…bË*eß CßQ~Ü5čź’§vźZí6•ş)żµ"xÓ+Ęáô:sB×¶s+eaěo6•Ęô{7Z”ŰîĐBŁ|ÚK;±ľĂ;éŮčđÓO§-‘h´˛ÜŠöJÄńŢád>BgQ>Í{ů|¬ó’ČŮ\–Ĺ;Éöóż´±Í&ů:ÇұöĘ<ć¶oťˇ;ëYâ1úśä6I>_n˙o™®ŐöŢţ´[âÍ鎯d±cŘţžZőÁµőOjc #źmďg«žÖkčő^ÔWęő~Ńu{ĎźJ~…€B@! P( …€B@! P( …€B@! P( …€B@! P( …€B@! P( ÷ďŐuʵ–˛®Y¶^׆ýőýö†O­ěŁďÇŢ“Ţ ż3řé`ďďjż«±°šĘg¦ĚV›ŁÄzŹë—xŹořtßâ·Ťďm쟣§{-Ďm¶†ŇCš˝ÔËf|S©+Ňú‡wMęXí„đ“qŠďó˘ 'ÁŘxďĚď±8|ëJłôôŔ×ődń[zc!Ćľˇs“Eö#Mď±řNĄŢěżĘ~˝™ü\}C]×Rá™đŐ¶ęn•W<ż|Ă­O ·±/Ąŕ$±ŮH_ďăÎʉ™ő«É¸†Ľ6Ű ¤ÎäŰĚ>ľ'„÷b?~<@¶şň[ň9ŢX1Á­łki Ű5fźçyËń¨×Wဏxg$HĽ W3gbüCč îŠ}9ËZüÖßů,eYQ|Ëŕ5Ľ µşâ<'Đ«ÇůWăű;2;ßR桑ń ?y›mF3|+'őÂoß^z‘1OĎŻÂ~¨«AÓŇł¨ţů5ëň>üd‘˙!yD[§ťă\ČyĹť=Źm*5LĽ˘‰;÷%×Uľç;>2L}ĎÂĆ•ř€ŞŇ¶—Z¶´EcáŤę V-˝ű=ĂŢ+Éö'8w:#Ň­\ ݡ“ ?x©G{ň'̱ˇËg`űLÇËUi˰ő8ŁŤ•:u‡öŰKŕş©"gܦňÜź1ą’€ÍňâXg”…öäi^ŕůböÝȦŐů¤3ňÖçâň ş,uřąöfl$G âš,kÓA»ÚX¸ŚtşÂ{¦v¨0qĺ·/ł˝†şľÂçÇĄžö"ń6ěeÉ‹˘­˛r˛Xăvgw&ý˙›ńˇ˛ěCtı·žĄľ©5Üd_#Ą±ĐˇwFrY“eÜ*ÇšÔ§5â ň“ݱp÷ÍĐçĺYč ^đ–ŕ»ÂW{‡ş.âř´ônZDűŚ~ÉßćZ°˛sŃ ż·¦3™×Ä=á—mŤôáGF_Ţ\ôă,k_~%ë#ąď"Úµ:Ć’»Ăť˝Uçá¬Üź«°C9L\ËqĚM.`›Żý6ú`S\ćŰ/M]Ä\gőZ8|ő»5~~–×_‹˛mě=Ój3[*˙\kŮqŤ.ôv' 9씟Ąv'„]UßÉçS{ň‚7ý äßŇ«_ŻĘò} ‡gůôô ­ÍEíÚG‰§hwŞźÄ÷cźmĎt?Ć“ßfËEWúK®µ=ů#Îď¦&ă}çŰĂ1ľügjQns …˝¦ü˙e?q©mÎÎŰŇă댼+¸ăA´sÖr˙Ç&UÎŃ×đń‡dµľ6[_ţĂ?űŰŻK”Ůďl-ńłÔ†ťz˝ăÁYą/´AgÎÎ>cđ‘ŤŮ¦K_Şj™'´—m)y:śąÄđ3Ňó ­/˙M}8đüś{śűč˝ĺű+xH §RkČ`łiéŚď¦Ă7VúÉ:s?ôÜţăĂaMú}šşă+)żOpĽŘťxYvôö8ż¨9 ë<˝ĺ«|Čá;,ľá'óřkgSçű{ś+´dńKz­ďy顥l›px t&W«ŽŐ×ÎÜÝz_ţrâ ů*éşłgQä®Ö%Ú©>űϢěŠ}†ýŢű3Vßçj¬ęŻ{ź ¸=d?8F´Gt˛łŃ·“őâ}Ě}}Ýëj¤3ޱp§ůAâÎb}B±ĺ$gH—\yŕ)ÁCň4”\‡yeqgźEüń ěKăp u1§…ÍŢ1á‡9ž$“˙üő«źęčŮԱ̣łšěî™Zn!gîĂÔ®-ĺü[$"w6ÇרeÇşKî`—6đš|í6—âŘýičaíżóÎ +«Đńż”OĆ˙ns)Nź÷cëĐźů—k%d;ĽŔbúh5ľ$ăËÎłýşŕčX¬*•çńĂżtţ—1ŠĎÔşüŤ…•Ó÷‚Î2lZ—•Ô.oďś,§Ď”s•ĐyÓúnÝ{‰áô;c>SĚçM¤ľTßs;V«/ŇĚCę$Ó´¦Ż´«¶ŕŐÜ—–aßýYĚőĘ´¦ę,ĺŻM_>ŹŃźDQđ€â9óýčksfбš7´ö{Vü/ßYźMćµÔ i ˝ÍÔĺ;y–oä}<: 8%ĘWj·;T`#â«\˙^á1ŕűÉ>dš¦ě˛.FźŃ”Ë|?ž„A_Í™ÝÇ}1ď†úÁ˘{PđŰ‚fÜăĹVŹçV]żÔ sÖËWvŇďň™´â›Ú·Sy/tÂÚGČőÇXű‰ő¨Ó3SDZu‡ß?ÖwJÉĆB«áOŠ-㵞…Ž9~ř’ §^Wč)°&źxEŘVşÚř,Ö§ţQÇzôjÝń…Ŕ ›ú›a_{éöŻÓŇ˙d˝g¦|ü˝…ŽÇ®˛†ßOö!äm,ěęÇšj¬E8I¦ű,ąôúHÖˇ®µžÄŢŢ –żĚG+zŤe뼾ˇë"^›8ťý'ÝŮť˝äĚúżĺ8±Ąěhđ"˙ĂWThŠx&űiÂk­Ű“ŹÍ^†ď˛Uš dŁôŔ×őŃĽAB˙ĘÚ{ë'6ň#5ü˝ÓyOD{ž8ľç{‹ň’X·Źŕ“©7ů§çw÷Kl)l(ö0ŰĄ·|7çK”ĎëčŹ(t”sÁ'"ô”ůg¬q¤÷s“ őÁÄFĆ­·|çiw6M< ,‡şľÂĺű;öł}QçF™2Ôë,ý[ NżÇů9–iAěÍ…ŽO{Fgi#ŽŻ°<‰—|kRyĆÂťý,=­3ž?ŹŠ˝Čńô¬Ü“őĄr3§·ĽĘ°·Up˛űɱu.ęä˛7¸>žÄ31Ű‹ř4šíĄ[YGgn™çBűgX6Ôo¦/I<(ýTŕc€úŕâĘdZř»ô@bŽU?ë5¸—pß[^ÍJ^k‰ľ&}Ů#ęü‰Ţůkës[W?bč-ÓtćNőnč:”Ătî2׏r+ý)`[Yß›@đ:Řl„qśt7Ź8ö6řld|8·‡ńóTŇĄÓ¨Ó¬ˇęs ŢÄ,ýÔq=Ô%ô&>â%ůŰĘť}˘5f_äéq}äŹăëŚěA\A{ůá?‚2ľ –ö§4ÚcçÎĚŐQríÍ6µ—Nn¦üÓJśEž’ëy®ÇŇ{Züęźżű3-zÉőIÎ[eÇwŞäH|Šó§ýżÝöŇnĚŻB ٵ—(OË:®=ą†ă(ąv$ű^Ńň…pÇśŐ©ős 'â!PܡŘý-%WŇłż­ˇśt‡žň#_‡Ăó,ş#týŽ5©źłÎąčJ®ŁÂá'I¦ă[rŃĂIÎĹMÄăę-_ÚÔž\ĐLĺ”ę¶—›{ś Y‡ń™ o—ŤĘ ç—ˇ®«CłK§¶Ç)źźTůćŞJ=~€żBä´[Zúm–Ł~šŠű3×q:T×pŢKĺçkÄCý¤µ­öŇ<Ď á««xdđUgäßYv\‹ö8D;ł_Í:'‹§Wĺ„Ăqˇ}/ă;ń„xäHgŮF§¸o&_ŐíĽ(r€mžúĹňşĐżěËöş¸|•˝C =ÜŮKQçö |đ'!{YąŔ"wÝŻÇ^2tŤhć8Ń˙,’ŢőŃ uY˙ŐMÉ1"îË˙^›YřÍ™ű#ń`ˇ/-ň­c=©ĺOň ôţ±"ŚđyzĂć•~Xp0ńK­ĐqłźúÜŻěčďŚ|Ž8Ov¨ÔÓ_ůkŢ\-•źŢ©çbÚĂ=[ŞŁ>&îˇ6k› <`Kü‰đwě?łđ7›úß—žÇř &®«čŠqŚgpđĺ4´áÔNUÂYßOÝuq Ť8îŐaŁŐ$_6ősm¨ë^­·ü"ŮFŘcÍç/*uÁ'YßÎČ:/8˛3‹żEXä hâÎţqţťÁcŃ©ńÝ2<{SpĎ ˙¶Rf©7bHtqŮîéiOŢĹžć{úi(ĐŐZv¶LŠ©eňYuA?¤;ô •Ů] Í:'"ô´†­ľž ¶6Íńt°ŮF 4vÚ›tŢĄ-˘}‚˧žľÚo­×ŞőE\ŰÓQ«»ÍF}Đ1ë!k?ü˝¦s.z>×aÔOŁ©”˙ĺzĚ^ZcÔsŁőťîv¶ĘWkcqŹţ“đĎůmłWN}­úÉň&ž˝Ds·cËoĹÁĆmĐćĂŤ•ŽLoŞĎB6ŮŽbĚ$ú!V=·ćúXĂKýD:ňnrÎcÉ”Íç;B›şeö6żłĆ!®ĄFfĚ î=ůL†©÷éŮlyĺ¬Jţ´ŮŔ=qľ‘äÂ{Ń—aq/ąţFë&ĺŹÁI"ߣ?ľúëŕÄ|ŤÚ÷oŮKŢÇ/y,ZŤ R¨÷ŻôˇĄNń 9÷,ŇżKČ÷x&u[¶Çum˘lpŔ¬/ż7ć4Ń~›ßI^EóI}Ż^1ěkŐÇfMrˇăKÔĎÎ0Ďřş­ŻŠ_Ĺ‹•úOöąŤÓ}¨ßi®„xžË4^»źÇSaçę4…mD;ôŕ!Őf;—x;n¬äCńdó˙Çř˝á†/xC1»1"ż•ďcöRĄ]—oę}6m<Ö~ Č×ÄĄĚăç­“ÄŚ7f_îíĽí&đlSß%ÎýÄ®’á€ŕ‹ťŃ|6ç­­Kă݆6e1ÄÝx×?ˇ×—đ<ôľÜ·ßVĘDőXe,yLd‰ŽßJ"?ľešç„čÄi Ź»E¤=U˙ůgłăôÝJľëCłűđxs¨kúŞFÜźOvýµi= óÄË|÷ň3ŹYŻO\:Ó1&ÁÓ+óĐÄâ:őU2) …€B@! P( …€B@! P( …€B@! P( …€B@! P(¶/̵=+ź~Qćš1óťx&5‹“?V­ĺśÝ ź±’kf›Xkł™ű`˰ÓíçuÇéWŰú3ŹęŤ…Ăôg:žbwv‰eí±Ôň‹=(ˇ#|©°vW·ˇXś}7JEćÍà !¦îŔš5ř Ňľć¬#Ö b˝ő­ÝżD»_ÉbźßęŰ/¤…ţXËú;^Ë˙|ş;»ŻL´VűDo{rĂWg‰¶t+×ĚN,.?ýś ;;˘‡Ăa–)_ńĺtćfłC]×đóöä ™…ݍ´µŘďĽ//ě™M]á);v`}{Ë'yµôĽ´’ýc»C˙ň‘˙4żłâ5±mylý™‹X§ÇĄ´öx¶Źüŕ[ß!Ž éđÚ§ľŃ·kéjů’iđy¶–q±.ßf+ş8ň±c˝bö˝Hç·-:Úl”ŹKňÖÄ:X‘O¶\Ňm )×§Ź8Z´UŮŠm’|îĎ<Ë>éąčÇyíuÉő¸ŻĐ±^ď¬HŐ´3t–~+ëgé´&ŰXłÜjŞZ»ŃfůĹf»É+9C¶M“-ýZäÉöäNľ°,G{ňąýűťą¬7Ąă;!ü<­ĺţZ7)ëäŘZř–ظţ!YÉŻ˙űFěq^2Š[DK{ŮOÁęËičśř¤?;šů ×6†Fݡq\ý™XďôŔaúĐüÓYçL…_@– ‰@}ÎqâPicľś¦ěmˇKëËßič<^šąčĺ:üąÁ˝rˇýTĂVČź°s.Ú§ĎZř¦‘w©\ЏúňĎ܉˙ă÷7ĄňFzVźĽńŇŢÖçđA:Ŕ&źőýä·íçĽHţ",«łéŁÍçůŮ‹˝}ÎÜ—Ůo$Kß ź#ń(Ą}r=6ü¦¬˛­(Üň~ĺswöŹ•W ﯇¸\Ŕ+Pßü ľüI˝‘ÇfŘâžáŔ ÁąyzËŻ»JíMÉâ`łűř㉓ĺńyPž8@¦ľÂś@÷Éâ.zřę‰ŕ3Ú`âPÎĂ1űŮŘąĐäĚýŘ­Ą\O$‹ßŞĘ˙¨ćÍřü„®•‡lÖş˘żű€;BúŔ ĚP×Î!ÎŽćödĘČŹ1»¸Nçť~cŕ‚z ĺ™Ę¬‘ĎÓ¶Đ÷\† ÷™k8ź,ÍnZYŃüBŕSžľü˙::ŽŇE~‰ďëŞó#îëç•\wů‘§đŃ6oÁî^wöj—› 'Í);] bź94˘56•Ç´ =w ú-áđŐŢÁÄ.े<˝Éö\6gŘôJý|±‹–.55eżŘTč8~T˝ŚËÔŔyÉš_T• <›čü/°±čSŤ{ĎĘă›ú3÷˛ť:"w¶AźTp‹şśIÖÂá#Ywů̝ݧ);’mîË»ÉĆ=©üń•yá°'ş _Ż3Ů„Ć˙i¤›,ľě]5°cëP×ĂÄ«µ‡ˇűř==…Žô ˙‹#ë,Ůż\D[Fu°Qg:D‹řZB±fĆ ?sŚQW#˘¦¬ŕŻ©—Ž›Š÷…Ŕ9¬#őą‰ăęÓ†ÜÖoD˝‡úŐfűĘ×µľ˘ŕöaF®Ü‡ű&/’śÇC±3µě>ç1ľĎGۦň–5Íz^Çě^-w÷2Şw{YVř¬÷ĺoák-ý]Ćc0qŁž,ެGß—e=ô›źý.Č7¸Ü7âx€ź{Ͱ©ävyľWőÔgkâF=đqŔď ö ýŘ}¤'Ű~Ő€G×ŇFyđĄgi4fđ/ëWčH On芴3™K5ˇ+Úßxp9µ[#Óä„…ß×Ęů”áJ}ă“XÇÁÄýs“EŁśC–b`wŁ_>Đ ,¨ďJßµň}wč7„Ëžú¬ÜÝú0mě;–/&.ĐŃ šęPˇŘ#†ľÔwńd2Wée‡O_uú†;ř1'„ň n€ęë-Üiţ4´oµN˛N–gŮď’ˇŽH.đd©ĎśMٸN\Dó`‡ű´ô2ć̓ߙgůĺt>‹ňgĘlö‡ O±žGG>×zÓŔU­4G@śC{řrŻ%u1^¨ţăôµßܸÓOcS/S6Sţç\'w‡®6ę©\ôÂÖPě og䛕6Î _Ť—Ś[ľ7S>W’ÇRĘ(Ϧ„éašCúŠÖăÜ•őE}?ZO©«ü®ö^>źúóő_üw–m–Uč…q$|8ú,µ]ß`Ű›óŘyFȱôëÂÖë°Ę#Ó¨ćŘŘX‚ż˝ ÷nĎ2nq¶ň NÄĽEuzŢ1Ç‚ˇÚ"´É»–"^×5:Ťź¸¶fŰô–:.2Ě%Ź*Ď©áŤŕß‹Í9sľ>ç6Ây˛·üOý-ëśńĂkŕçŔŘAĚŤŽgg«lc‡AYžĂźrEr=ÎMîë˝ĆuŔ•ĆŞôß×ócöĄ4'ű×=gÉCâÎé]QśCs”Oj‚ʦVźMÉVü ©Ý–_@mésÄ_ţC ý``¶o2T=ÎS9?"l,ňÍéň!ĺ\Ôˇyhkě ôF]GýNÍ—î%®ńk|ČOëŁ7jwdÎ2Ú:łî«‡žŐqО*žýŽć«­÷˝$iîţM–kfá$MĚ»oťÎăŤ{ËWzŰÓóŚy9ÇR˙Ľ ]eű+y”„ţ…Žgu9§)žl=gx#;#^?ý¦Ç¸Y§Dś˘/?ßßžÜŐ—<}Ńdđ˛ü‡:óô雍ôku–şoůyě<gŠŁRW‰ô‘żD}˛ĺ±OLHâÖŻô3v-őj‹CGňo1Ű7Íúűň/u~›łę֔ݙëĎßLa?\rîČzm"ËׂŘ#¬;ęĘDyľźř˝Yßľü5ţÉďËv¦=^ź‘Ďč·WżŕŔ;Žőýćžő8ĺďíńŕşDŮ(C›ű®ţďăAđ ˇţ™H[ĺFŢŢk­G´>W× …€B@! P( …€B@! P( …€B@! P( …€B@! P(Ű ń ą/ˇXĎ5ţZÚŰ˝âcl]ó=üűŻÖyíęD`)t/3ííĚke¬îěumBg©?ŢÄ×ÓڲƮŕ1ĐÖG?N·đÚ îĐçőîP#Ç!ÖjOÜZ$)Ó¶ťi­_&. ˝Çů߼~ ń &̽ȱ†kCˇ§\Ž5Vđ““{ˇG4Më I>ä˝Ţˇ®6^–,Ţ#Ö‡%>¦›ľ–Ű&í¶Â˛Çął±v«/ßBţsyâR9­µ·ü ö4péam7öĘ”÷ăťËŽýtg.Ęß“ž&}jÇ _ďçb?_řz‡´¶ŹřČ>Äçpíëţ%mQäOĽFuV.ęm,ÂxdS+pÖ­%ÂŇf[—¸†|Ž~ái(=ď ‡÷ňő–×°G'ÖbmŘ‘É"ůń ˙zŠŁnëĐ6ŤY<ńú7ś9#˙[­цŘg¶äĘ2ĎIwčľfňą•gśąąţáŔ9z”ÚÇPlĆ$ŘÚf»=ÓÂú‘ß ŰŔ*·Í–wE´ťÜŤ…łŁ/źd}eźÄĘÁ#ľ3ű3 ±Öô@vN˘Ľšu.Ý2x?6Q~ťňÂĆ[OżÍľ)ŐiOüÝ Á…Ä–±Ţý™WWä´fÚ™m{B¸÷Pw6Ĺ2·'?ŔvÓŇ»±ś(ű´ż­źú/ľĆÂ3^˛'sÉ-ŚÝP×qdן»“ĹŁ\TVXßáŔ s’Ĺ4ź©-eoZÓNĽ‚K`âµ1†bóXvâyň>]9fţDHęK,e 5#µ˝üý`‚÷µÉş©·ś'N´ĄŢYąŮÄcr ëںݨړłŚ8F ڵÍv÷Q†şö®kŢnO nPěĂFžÎ¦˘zçOlŞ 9J5•\§·Đ{–±Đqź‰Ă€řöâ:`¤RŻ:^®čałőg®âĽAľňśW$vý™ýŞě ź3Ô}S±–ťti™•;”úČł-hßf¶SďŢǶ殾ÄóÓÇNÖe{äĚ}^ęzŔ'ü‚kŚ<ŠíŰŃîgáűţµčŻŠöuîĂá79żË¶»äúÇŃú×˙漄íŰXřç­Ţň/5Ů/Ě= ‘ňđ!~F ×/ćźŘ™Ä×@㋆îC\ś—ч’ő·őŚ~7qęř“?ŞÔń6›ýě¤ú}‡˝Dg´ë/ö Fě“{€sI¤(l†ţQɵV/ąv¤ľ÷ýę_´ć˘7eUJ‡ţl,m‹ç1űŰľîPĚŰ[>ÎĐ•ús”Ě|Î_1~2®©;Ç‹Cżaůjů9°/»”«·ě0®źîK@#N8§:_Px'}P‹T_‰<"cšgä5Č…ţ0díŚü—SSş™F]/ź >Ë6ÍEwŻäéű<˝ĺ6Âŕć±@^x•ţ¦˘n–2nţlćĂżS˝ŐźY­7”ޤq¤Ă÷b…7‰ÚĄ9T×}Sę?rE}⡒mV<ń”Ͷü}Ó$/oJ{So”o’8©ż®č*8Ňú3ş#\1°±â[kĆ!żźŢg«Ľ¸GĚ.xxq×[>—ű4ßĹí0ŢążG_EÜ—Ö:ËĽ®D2mOŐ:Ë1ÄíĎlhŮč:žxßžcťG«PýmµÎ&~Łż›ę'ŁĺÖÓÍŁĘdˇăď-˝Í‰ą S?ë÷µşL•ŢcĄk•łšĎĂÔĹ”ż˙¬ďÓüŮńTWë4Gz…6šăB†•i‰řE˙\¦%ĂÔűÎM~6ăţ”śŁ¦ůw}0qHĹ–‡·mŠ—EÎŃßýe© ÎÖ#qdüĹ€Źú:NăĽg[üŔIö—}ăĚšo¬ßoŰ5¸"Fß1Ćîě©[ôIŤĆ<ľ;RÇr›c/ťŞŮKWWqĽŤ­—UDZŻQďw‡ţÇh×F6ć€ĺ8㫡ü±uÓůęë†b·2AŚzś˝F?Ď~™:WCx·şâ;̵9sűúÁ›g/ýLn’G€809=š7¬’i×ű 1.Ą íByî#°·Ácű8ŹAƲ_­T"ڵLcÖI?ć”\?ç>hĚľŰ(N ęçQ_ç#šH§6Ή»óş71Ć룯JŰň<{gdÉ(ĚEž“zoJÁq*ó…Ě·ň‹PLp`Ę{âD®¤}2sËçő8Cż6^â,d]sÄç·j ÁvIŰ‹HčPűĹx÷Ŕ†Ć¦•ľ›+»ŹçUWÖł:őýću;ĺˇ$ývµ”ćnđ‡Ă;ř.ŠY׹!i‡lęrť¸U9݇˘Żâ÷8ěqěYî77Äă 9ß?ž–µĎ1,uLś ˇ˙ťM%uÔ]ř ‡xho…ó‰/4@<ÎÇOđ_´É™7 Î.oVÚ&ć÷gűJ©nńv‡ţî{Ô_×j7ţ=ćnŘ‘ă;S›]5Vr%4ŕ"ÇݵüŠăÇş­odů|ž2¶ÎČ縌ɲHż3Ęň.lŃyćÚ•ó©n˘öľĚúć˘ĎzMî›í<ç ťĆᜏn‘ăăy~é·ÎÓË6tśĎ¶č±śë“–s$Ř3#ýë]dŇn1‘‹ăďŚü×gőř˝ěŕÜÝĐŃh/‡źĆ&łŢUą™4`TB …€B@! P( …€B@! P( …€B@! P( …€B@! P(hżIZĂ•‹^ÎëÇN ßHąžÎĐö íűg:>b¬5Ă{¬?‹ŕő°~1˝®áăf•|`Ťő‰é™zD‹ú­k}±öĐĎ›>…×ééyĆš ¬ Ă»ÉŮ[Đ*ůćŻáC[_qu|€ÖD>Gţ˙¤˝`…-bXó«•:íL>é÷ëXű  -ýßať>ůjů®ł|Г±ͱ>Vřk _ŇŢrČ˙¶…`ó’Ő'„Ř~%óJ`Ť\(öCzŕŻ6ĹTţ{ĆkX«Ź˝Đá÷Š-%śîä<‘ž÷ńđ„ýŔë;ác…5ÎĂ„â#Nz}‰±vŞ6ťzŢcĎLČů°öy\Â÷Ŕfk(ÝB~ě7’יִ|.Žâ<;(łßśôO°—n ›ŢLkŇoń &.&îžKu¬ů“k ;_~M댬ĐĺZő í^Z÷xťQfę©_mÜkR÷ů±®yOÚôe’€WĎzśçńşµÎHĐc/mř}b˝˝¬ĎŔy¸ií»‡öo÷ ßócs(­îŢá.ăđ1N”Wq\á°×¨ë¬ţҵňŐűžĘŁŽu¶ý™GµÁŁl@~-îě Ö\°Ł\ŠüŃ„ąčÉ.ąčď}‰´ĆB+ëJ~^ň?Ł÷bŤ4ůËňóç*ŐWÇ굜´Wą®§ďf=#Úďh]ů Ţc#w59.gůőôĎŘw¬/˙YěŹňŰăldű•\÷ńw/m¶_oů–žü-ů‚×ôbťăXúôĺYgĽ{ŤöÂ+ĚD=#ßü6gî®{‡W’żDŹĹ®ë=ť‘»ŚőÖÄ]áęËŻj\Ŕr×ćEâ «Č}×ß±·ĽůK >–ÇY-˝ĺcČç,Ěq/ĹŻmY6µÖ’öDi8:±/­xž8Ţ»j`GďW]‡ÓžŔ7v‰:s‡ d.:̶Fťvˇ}™VZúCm8đF8rVâëÁÄîä»sK(¶Ěŕ$qg†kRkťIůśx>8=˛?ź) ÚřŁ%Ţö'Č›ť‘ĺF="ctćÚ=ąč˝‰; ;‹wDz¨ WŰŽˇĎˇ§]†˝ăĂuîĚşuí@Xě͸\›ÔŔňś/;şj-µLg"ĎčÁďLÍÂ;PšÍ8Gś'{ž}{‡ş.jJ$\H;›Ę0´ď­ö˛Ř÷Ő¶â´‹}é9üť\űNu;ßŰK.*W0OGD{žő$ĂďB±F ĽD©Óćâ’~äÇďmĘňşjţ$˘=9PŢ ;ɸ쥝ŕźÂö_|6"Ú©†˝`k„íËoäg#Ž. …Żi¬Ż˝t‘‡¸âĆÔ“ü||ů®Fĺ;™öDś“8AGţF\í!#Oî\úO–÷ m6Ë˙ĐU踯©;ÔŃLeŻe80č#ż߬Ü´Źń‚Š’ÍfíŁké[¨ś›e#Y|Öŕw©•Ýť]HţoâJźô{© 3‘÷˘ĎołĄO9™ÚЧ|C]_ˇţֆݬi%‹Ď±Ý?ž,uÖµůç+îâň•>W.Ú©Ó˝§Ç™2ęP,Ę:÷gvág ĄŮÖť‘˘†vŻ·ü(c>\ÉeopßÉA•łrÍÄOŮK€űqú˝ĺ‰jG¶5t×Ň;±Ľ1ű):ú¦ĐcŚŻ$? ü–ÜŮ&Îű´—t+qĘ5ç» vnţśóś ›{ś·x˝ü·ś¨c ‚xѯɦî«{ý…´¬ÇÁ—yŚ€~·(ç:ůy}¬ĘŢäOŘŇ}đĹä?qŹüyIFôiF˙A‡›|n[ĂaW őżć u]YĹu€~=ńPéşVQů­îYĺŞ˙u<(ëbkZ×ćŻß_\‡6/tÜDmË'ŞĆĐRöYąÇ«ţŚĂ(˝ĺkĽĂ‡µ˝ á<=â¸ČʱÉÚ)ÜëÚŞ#ŐK~gîZÎkÝ!»QŹŇX¸Š· ä:ÔČđă¦z—xŠ–łŤEsqëĂŃ;§ęyÖťřZü4&ÓgŘö4â´¦;Ő×Úź`żFŚő%Źdrgä2íKĎ#î†Ý©ž˛{©˙ÄϨm#ľťElÇljO~ÖXř_jçýT‡gÚPÖÇŠJ‚ëéwXËŞhsł©¸‘_ż¤2zŨ6z¸ł»µ&‹ű{KY[Ąnqý–ć̦źžV‰¬:‹z†ĆüśźsŃKŞę$šSaÝ 7Ďi(µĎ Ĺž¤ú+ŞÉ…·ĆcŤ:_ ™kű T6ąN+;n˘ć!ÄSÂýSűŮË[EľĚŘ_W«Îňz:ë+e3e=>ćüÝwě®-}ů™loꏳť‹ÁćĆJÝü4µŰk1í,ă™ćiÎÍúdň®ˇKí&HVÁI`}'ąJ¬Ď0—÷]+eąÎŞ~gŽVن™ďâ4Oú"—s´ÓŁß›!'ú ýp’RĽ•t…-1K>˛Ü怋۴“xßŔs}đ彨j¬đ‹ÔߌúŤúX'Í—UĹŤ¸dúČ6AřĂljKóęHgâČDśŚşôĺîâGy%_tž—\“:6ć°„ÝgŠĐß»łëüąčĚJ˝l•Q„ě‚sMÜCÁ©%ÂşłłąťĆxcqô»Ă᫉ŰřŁué›ýô“Röćůâ‹Ö0˙çHżäšé»=ó ߣ?]]6M˝jóĽÇül >^”Ýpx7?ń7pݶˇkĐ'y9Âáođ3)Ź8#ţ‰=¬x‘<ŹúĎćo3Ö”ÜŮ §/˙>ôMDťły]eŢ„Ťˇ3ľłćgÄź‹Ţ[á—·ŮB±§˝4Ń0ć@Ţż YĄkQn0ďń%CúÇo%qJ|“ń~Ů•%˙óŐFY­Ěyo•Îř=yYâ„rÓžü-qWÜCcUsÜu™óůąčkśžĎOĽŤjń`6ő”ż?óCš¶Ű¸Bî§9ąqgśÎżł! •u–CΧuěX¶Ććs””čŠ3ňy8|•Öúăj/U竵ô›ńöűrţ_ץ,C:R&ĐĽÔYĚ·÷żn׎6e¬bg›ŕˇÁ—R7\Ź}€Źý”~Áo7r>Ćş/żŚë?9O žĽŻç^ť‘[1·Cő58°ľ¦÷ĺ7°žÄmč‹ßS‡ÇĐÜ÷ľÇ¶’KăÓ;Í.'Ř\·Óo7´Är żiCż’ë9í§@cő_úŻ[eoęsś>sI0fźĺď-źč‡mţÖLśĂ'3ţkR3ą-™KűDŘK§lµÎząď^ž ±jŃüZřÉŻqݡSůś(˙‡¶ž~ł”őź5|®ąžA] ˝+żCr;ŃźÉxEű„zv–m[Ň'ŢmŞ//đȲb/íkä'{éEš/îÜć4¶T>ëŘᆹ//cydýîM×oKă•áÂáĎűi ÂúŹ–NąÎČô›ýggýâő9Ň“,~ÉsžóŁ­ßÖó<7Yäô"Zý~q»Öo<iŽŹÚz˙âzĂ‹9đŘÝ;pą!Nß Ok<ĆzNé“GGúUmÔXaßÍ3üćçĚý揼z†6Íq们ż ʧďťó@üFąÝč2ç]Ţ;Z*MŰ3őlĎ(Ů߼ó¶Ňů˝‘w7§ĹűŃΛĂD˝W( …€B@! P( …€B@! P( éć°­ëtÇ“J„3×ÍmŹsßŐ2’E^ó‚ő¨µkąÚ“˙ĆűŞaĎĆdń-ňCĽ†×P`˝•\ź=RS˙<\˛ćŕŽ™Y±^ \ ݡ뉋ĺy­řž&×xaťźÔ]úÄÎĘÝŻÍĘ=ÍúJ.ąĐÔ­KóůÔ\aťké–uřÁ‹uę¶ |+°Vk±Éż_?8»ůŐôWËBM®WŹ $fźO˛-x0°/ěěĚ}×FĹě?Ł5ŽAí&Úßo0ńAz6µş;ÉG2ư+®qŕëćĆÚ/y@Ř<„Oň4îá÷€8Ňß}‘q1ăŕľ§5pĆş0¬ •ď'ů¬ u­˘}-Ľ…ţ˘Čš;ű M®tnňďÔĘ&×ü’oŹlŞŻŹŠµ˘2®Lf®ˇcí·â~ríMë´ [ĐÚu–͗ދϵëô"Ú÷y˝í+ëÝč:źĂČýĺ:o‹N•µŚ3 ßůŽÖBzÚ“?!ßń Ç1Ô5Čy_ľź¬óŁŔ2ÚK‚ßŔ™~TáđG˝…ŽűűűS݇…ľX ŤĽ?řŠ!789Ë€ő‘ňgSÇzäްňYzŕrĆ»ˇ4~’a'⌺YĆß\'ʦ˙îÜä×Ř>ZzyëŠâ‡ć >Čë“EÚ˙ňüv |5¨«ĺÚw¬ OSÉuĽ‘o'qoUěŤ;qPąöŇiňőčâ°Zú»Ą­­_~˛QŹČ°y¶—zýwd^á4K®˙ňaźOküŘG÷méyůűÎ!?_ű®N ţůęŻţĚäÇ~ăŐ—?ĘÓXŘź±j,ě@ű*x§Z|ç9Ż7pé-’ö‚>śÚôĹF>‘ńŐăś,ÚŤ´‡şö3ňb.ú*=ĎďdÚ#Žąś·ĂËţ‹ővg˙Í›qPžćoËĂXĂJk¶ŮŻ’lIű˛.Ą:ňZ«ď5Ö|Ę5űhËe:ő:żk#ákŤżűE†,ÎÜ™ŢÎČ[K®µsŢtĚśÓ[ľ˛éöĚŁ¬óÉľ†Ň7*aóžď_ ü ÜŻ˝´”ľűJ‹–ţCł6űĆi8pť–Mőé´—¶ż;´?­U˙?=Őáo5č©«­‡ţĄ $žcËŽą´GďE>möjĘŹi3lGUaůĎu~“ý@‰ăó-•[ňçx›ő&OÓů+ŚoW˛~´ż0ł.Ń@nÁńQ>•Ť…˘Ż·Ľą/P7śľÚŔiNäaíŘÝJx7ękR{úgÚŹý8ÝőѫچŇŃ­Ť…Ëř|jŔ}€z»;´+ë*}‘PÎűňgđłPl¨9=đq:ŔÓQřQĺýnŇ®Ě]†ľŢDęiŤ«ýž/“/ß-äWu­áĎFĺŽmŢXřŤ®Ąź$ż«µâ) Ľ<ż™ÚQ–»äztţą†~)|7Đý0;0ý“’ëoŮq —ëÁĐŁ|K9·ÂČr?ŐzůĐÉ4ĺţźŤ…Ç4g®ŕŹŮ­Ë~—|ź¸Ç·±đňűŤWĘl<(Çđƾ;˘˙üi;*Ď®–Yą×܉Ďr=ŕĚý•ż?Ţ`â÷ĚC<ÚŤűn$żL™n}΢ż'ĺF/` ¤ő-żŽQţhLŐDĽ;UyTč‡8Ş˙F¦ÎďĽó#.ϵň#MkşčÓ lLß”R™ľÉ´gł7=ˇţ׈ŢRîöäa†ťkőĹ=ů_·áÁކ’»µě(7çŇ'ˉÍG&‹ÍíÉ˙$‹ů\_1[<¸ˇ+¤“­ŤĽ!Ó©˙9ÎţnHßšÖ`Âôă¶>Ϧű~Kůa´Î6ΛZúŔ .6Ť9Z oĺĂ:–FżMKď_ç=Ü­’×^Ç(WV™;ǨgšĘ=—K\gSĂTĎ˝Aíě,3]“OŢMäS$|¦ĆťýŐâÚ@Ü\˙Á8l¤6~Â#ŽGɶČgSy|Žş“ĆŘŹśęµj3 ýÚĹeáKŮź9ŃČë”ď‰Ăüy÷Ď_+c“MýśŰehAU­ÔimOţu=4»Źď-Ç ”ŹÔËŽ+*úNµÎVĽ…ţ¨g„émcćżŢr›‘gËŽ×[J®ődÓ‹¨Ţ:бi,\Ďú˘~Âś‰YnEü֧ǵ”KžÇ’jÎś’ëÍŤ'ŠvXOżíîťÄuő3·µşł§éŕÜ~î2ëy¬8§ň™U¶8ő·N˘|)xhÚ“Gpą&^GůqWµaݡť›;#»y|t='â\ ¸žĚ#üëĆsĆHSpfů«ŢB6{I·č#žő–M Ą'ÝíÉŽćlj÷O‡şîôߢVgŮwë=ŁaŽ­T:{ &‡Út„˙«Đs<ÄĺÇu’¨ĂĄŢÄůG2–'íЂد[zhňüňÇč{X9YDHs 4b\¤O.ć xpužú´]§[űČC]‚‹Čšóť{z!mŘ‹řuŞÚę—ł˝“Eů}Îâk_úg4‡›­|Żô˝…ľ’Ĺ:N–s©â7‚jŰÎhžxű—\ŹWµ˝ÔćĚĆ1űóÄ čeą»ČWu.ęo1v0m iN[8zŤ?Iţń{Ҹ8N|Ó—XÚ!Sď"Íý>«Iţf=}?Í™Ă2PߌĎ4î`ě"Ú ýă§ŹUîŞqŮš;š/¨ęoá[ĚĹ»s»T?qúČëÄŻ«Ë±˘µ|JîC™¬ďpmľ·e–ĆÔŢb`óuH™i,Â:Sź€8d÷iéźn{śŢÉOÜW¬q*°M×GO&^’“inäGÄš‡ę%ÍS1G<Ýű`§±ô®ŐÓzŹr‰|KîÎkćô‘lžf\7eĚĺ×8.$.•G‰“ĺÖžS*ăzÉófÍß"ěaoF˙~đ©ČÇF™ÜŢ"”řő$ě/ó€xZ_;#ŤţĚ2¦ÉýŔ+fűO4ÎçëëKÎĽfóf|>ý~ń Üóˇűź®ŕ®_i ^ćŰŹúŮm•|z…agdŞ›/÷­Źţ/ŹOd_ć*iÖOgȝˎ˝ń›$—×ز]ýÔĎ"ţˇS˝îěz#ś< §(ÇňIíYÚžv ŚđvQdćĘęËCë¦nŘ5­ŕx~8z›7˘]FéżŕĄ=&¨ÝđŚjCkcßÖ{ůűPfaçQUú>RĹ5dę4vúŐďÁŚ:íĚ~7ýŢ{§‘–3·[ĄľŚHýúťă7u×2ot]e¤~ň¶wᤠɲćü/đ ugĽ7uÜ\ţ«~Ź6±Đ1G[˘-Ą˝3~Kś]7ôÎwť1áýSÎńŻö^‹ąt!çŠb„xfüIgC¶ńżŢ˛7öŇâ{ÉUĺźÁ„MĂC¦˝e1Md¨x0.ę[Štq%ĎMdüŕĹlä|„X»8ś~ żkOl**6…€B@! ęvxüpďĄ7Đůý¦÷ű]ç÷‹˝­v~?éŚúÉŞű{©ľRş( …€B@! P( …€B@! P( ÷b.÷UňsĂzĆńŻáäÚ¶±×ÄO_\~ş~ ď[.÷ÄşF{é^uŢŕí0uŹ~“ˇX3ď}&××ÍĘ-ŐÁmb®Źť~:cÝÖ!’ß2ů­ŇÂá'i ®“ůF°ţ'˘ÝMű¸}–×á9l*Ö€’Ďkâ^Ż‹5ĚXsBx‡ęrhĎt˘2Ë#ůµĐúlĂÖ" üżVĎ ­g>’>Ný•óś ý˘ßb†žč+Ô·ŮÔAz•_[ŕą 6۬ÜóFťłŁâŰ{Ys˛xëťMŮó IĺýˇŞú r‚áKŘPšÍďcö'8”„g‡źřĄěĄ'uř\÷Űĺ‡đ®úZä_ĄßA\VčS§ŠÖXhňSť«Y}#†ş0ÚňC#×ĎőX_ţ{F2ßóÖ/ýŻQ6&yţ–¸ĄtŃÖťÍ:./Ţă˙â0}eŚwĆ8x§ČÖ˛}uř}†ÎÔ§ŕ˛M¨_ŇŮB>Cl;ň_÷ŃţĹţ×Č·Ú&–µˇ´Ößď˘>˙Yó8Ż´'©”;ç´'—x¨='?„»9ďHîÉ«G>W:|7L˙Ť‰ÓŐŚ)Îü~Đ»·üu–8HÓ^ŞÍ}ůŇľÜ÷y"Ú"ĂÖÔ_f=¨M"żw1†Bś]3ýB~ňŹěe´;ôą–ţĚŁshďĐ÷—xW śK~±ÎeG†Ç!%סmħWÉ/2>ł^0ĺť+Ś çšT/×_Čăűç^#^Kýc/­©ßąŞśľá8‘ókDűö(Ś”Ů”Ż/Îś†Ňýü]z@ěi-ߢß.űćđ 51¬źÎHm#ŇÍEď ˛  pS\VĄkzŕ6Úçu©QŽŰwß…Ęßm¤·ÔŃ<Dză,]O×ăMWŻÁĎEúĚBůĘ˙›QO ß4›MŚÉmäo|zEw‰ĚDź…?;8B¤ďů…˛<îěőÚCŃ•UăŃ©›şJýaď˛ă8*;z‰łpZÜJ>žÁĉś§  ů)=đ!Ł˙{Ă—´·|8?«öńťę¶>©ô÷¸îc#›íbN›ürÉ·oŤ§–˛îý™źpąveýŚ‹đ×®Ö{¬öuC×Eäř(ůDZ)š|ĐhnúăíĺÜäyţŮ쏅8ëyTË,ě%ö·GŞíjťú‘äĽ?Ű)›Ú…ĎR˘\ôĐ6YwaŽ€řŐ,zaśrŠçBűŮŚřŮČ'ÓČ×"?Ź•~˝u–Ňăl¦Ź6:Žu1đo,Ćď쥯ę˘n—| ŕ(=ßhĂÜYÁł#eŇŇßçţ)qëů˘Îďs>–z`ţ¸­Łöáű3 <~“}Ô…ÄżÄxô8›Ú$€Ś{ŰÎq˛×mWPç،禊ţ»°ŻŹ3Fś%ęŹ}CGżAÖ±…ŽńyGOÜ‘ó9Ťý=ŕmă5Q7SŚ+†IŻě{!m\Sż\§ů)âůř´Nc® +Sľm˝ŠŃŽbţ’ř˝XW/y‰É#űľŮÔZĆő,ů+˙Čîm˛ŢéŚő“˝ôa·öd»··\đ8sŤ4FŰ×čŹ/pw®N[‰sĺüîĐí| Űké}Śü&5 ‡×Śz&ß˝»ł(WŔxčĆÇtw¶‘Ű\#ŃřIř“/2Ë$Ú^qźĄ4ô×OÁqi/=¤ă÷ ¤Ż×8q˝éą¨•UŘá1nqgĎÔĹď(ëÇo˛]3u»Ţ4ßoÍ•ŕő±—FĎy˝Ř݇yŹlęNo(¶żËÍ›sVîčcr®:îaŞŁdůĹá1'é0GŃPбý·•ů2“§ŮőŢ3î$®Ţ¸ĘŔÄĎ s)ňÉĄ<™¦vő3F^Ĺ|;Ú&›ZjpXőÚÔ5ĘĐ`âc†>Zú?ć†ú3ßẊ8ν‹C‡0ç%Ň Ĺüuů]KÔŃ„{~ËB\´Ä‹‰ˇ+¸qzËÇ÷RçqŃúÇĚ·›Ň6–ăqΰˇ;{+Í)%¸LĄžĺłäůcŕNßDŰyݵ+ ŰAŞ ZŻÍ?GcźŞęŤäďgm“ě3J]QŢ©ÍócŹĽ“íŢăůqČ#ÜC_AsAň^žď$Ţ\Q_'’oJľŻ×ą/?ß×wĹ®>ŞŻćP˙ćľ4n{B±çY÷ —}„ů—P.‘g‘_›ÝŹ~[D[NżQťč‡Î(ă(×čď n°Ęk/á7 ›-ŢËŔq8°/ç7„Eű&~šČúKHđÖӻҞ Ż1ŢŕŕíË˙’eÁŰš[ůúâ ě­ť‘ëY¶™…gĽRWŚ=oE}ΚŇ\ýËÚ‚Ř^\Fą= ÷Č«ř¦;´€¸?~ȸќR+•oľ&nkâ/>”Ż‘.ĺš‹8ľRžńd⏹ÉŮÄĎű&ë—M]AósvĆ»)›:—“†<żG~ĹÜ˝´Đ9N\cOňwÄ÷ S9ˇň!Ć#ŽďTĆǰëšJ~ţ:ńh%[¨1–öŇŃ|}zË« ě'^cšż>ŕ€ŞrŤ4"Ú),ĺďÖîĐ ú-µ‰Ë88ë ‹(źŐuň8Ęµěł EEmřWYg˛­u™SHM^đ•…–˛ă;F§z´®úĘ”­çö;“ľ íO/JŃ´ŻCĚ V¸ýOźą„űoBŻńĘśh«Ĺܱ‘Z(¶ŻQWŇ8”1&ŢS~6âX]ÉVÉ&öšúŠţU7Ó<ČcÜßGůC Ť…ß?VĂAßäD_dÝäCz•żÓÁžBFs^ż·|‘ćO?áŁ5‘ü]e}ë.÷†›L˝6—-ő¬Z3D>śĽž&“ąÔŰłŇÎŁĐń-żđYŽ“? ­ ¶Äú_?­gä5WĐwVnŻŤÄ;¬‹DŞ·/ż”cĽó@­;+r‘?7íó}Łvmţw´ó\c­ľ%vňť}¬˛×$Öi^Í{•ăÖ@ŃľnlWÜăpć.cühŻ.]ú &^ágČ÷SĄ7öl(˝¨ŻđřQ^ťąŁő’ërň—4ý-J®×Ąý‚.—Öç’łs>üĆ ý†ńŢz \Óžş´ß»ŕ‡űxľęĘźJą°~QßëĘľśH8|5ăźM˝\e+«ZúiŤüG˝ÖµŮ´¦™¸fü ňm…Ç",€M‰öKü—ŽuŁÎÜľŚM_^đzTâž4˝±/˘˝´ĚO{h¶AZß+miëü‡Ľ%O6%|“’EřAŰl´g  K>&Wh´ç-íß(ör'Jż˝ô¶?ÉĘZWŽĎşFeű3Z±­×5Öb#n¬ŹLH+ÁĄ Ą—°ÍiMŞľ.q§ˇÂßži1|ŔQ†a׆ŇNďíĄťŚőş˝ĺEüm{ňű´Ž;Ęő_.úń¶˛cÝ/őťG~Öőŕřľ^¸+ÂO~ýä‡ţĹň†ĂE?ň˘5MZcěy(úgZëŰĺMnčBe^sľf”*ۆδ÷»QďŃÚôÖpŘE>;°î~ŇWŁ/ßĺEyŔ:ŕĆX_m•e[ŻQ¶ěĄ_ńşřôŔ±,/úXđ5[QüßSe©­"źś“řú™Ž—Ůgˇ;ôöU@^‘ňC&mv‚đŮuţqAŕ™žŢËCő˝§=ŮJľw‘“s~‚ň3ŢÉzm<ň8žŐă¦č3‰5÷"+7Ȇ®6âÜą˛•|ýČoÁ笢ý?KÜ_7{zśK›á_źĹvł~'eÝ/漡]ř¦…b×2«v¤ďvo“žďşylä7čŁŐć1ůnbÎbŹvŮĚîăŐĺ5â8ú#צ×P:ş…87ZÉÇ‘l·»‘‡ťąG<Ť…UľŰÝX÷ľ˘ŘDľwsčq~Ŕ» ˙™‚ěÇĘű‰>‹±úýČ›Éâ~m”ʉď*G{>îBű|ÎdŮŔ)´˘¸'ůäźEűąľŘ,ýş…4Giîě`Ąn{ŠüI÷˘2{śŻ=)xČ÷’m­Ą÷­ÂŻě÷d[áĎ!äAľ“űŘN¬ĆÂă”äs\“Šźö÷f]iWŁ>j<ńb¶QDಠYzśżňÍĘ-çĽŮ}ŃIm}ÇîÚF}ţĆI{„—\_n}1p]%|Ä›űđNşđšhéű9NéSŽu˙đ%E(íßDë ˙'˛ůĎ-ÔQg±?7µĎÖtW‚řďÔŠWŚşąäĘ’ĎĚE”§ď$~´UÖ®‹<Éľ(‰KŚľ–ľ‹ülOf˝W ĽÁ¶•~(Ôž3>čł@_ŚS°_<Ú<Ć«XeÚ¶ëę8ŃkE¬Eâ\˛Ć?8§’×/1Ę©x/Ë <Űląč…Ôg]Îá˘ő„đŐž3´Ů|ß[n©j Ę´5PĽÔ7©–Ď*Ë»żľ}ň{ęú€5| ·±­ĎF]\^űňIÖ™řÎXööĽ¶ŃőF•ť!§ěĘxqîĎ\Ęq$•÷ő[ĎńŁÎm“đ»·—®­Ô „ĺCks-üľ¬ţ±ćZUs¤P{jŘš|Ą˙R´M´'8ĺKřĘďnřu »ÄÉ—đD˙Kä˙7ĂvËO>bÔ?™xďnÓ.$żyŮĂ®đS+;®Ô¤<&|OQO|“ż~JŁ©ŚE¶Ëwd.5ę*¤‹ögÔ's“§:ă;â!ň®Ůçzö‰–yŻzŢGćÇx0yÚN„‡y š,ţ€yĂ€łÔQr!CĎîĐ3äsd«Č$ă3ăy÷WŐq{Ń?A_´ŰđĹ—>Tč'DťżbÎƆł÷`y ÷H#/ĺף#ř3ÔIRFâ>4°­ÔŃünäĘË+qÄą#Š÷_Ä%&|ęĺ÷Űv†ľBgčŠü…Ľ˛…ň YëŘ߶݉ŚäřŤf-cݡ/rů¦ľ íľšÚä] ý!ßpŔÁś<e–¸kŘ·;tź8?t<lŕńĄ,řVôSL9ńlŰW<vČ]ešŕÇÔďäń1Ę8t5ů”ŞS'^[âćŘĄRŻ™|[…¶í/ú¸ő•ÍöLÇTľoö–Iîë#Ěpń4â˙)äśžš—¨mx–ň\gäV}ă-+8ż‰v‚óô<¶-é qČwńü˘í‘÷ä+=çMGÁ-ďq&^.®ăPNŹ·ÎĘÍ2ę đ:ŕňüé$0őátg6ĺËw}ĄŞ^°ĆżĄ×/YĘü&~ÓĎÎÔvă¶„xżxüüvK–‰ôŔăÄ?śi%n Űßĺ˘'7Ń['ż}.ýá‡Ú—wsů¤÷†Ť‘l3łđcjS÷®đŃ`®ó©*ڤ<äŰ[Ą/҂ΰscAg»C§ŕ[ÎëÔ§ÓÁw‰ď‰—Ĺ· öQ–÷…đ5ŰlŐśSx˛ő‡(»řîCţJ^ăôńsEO6ęW<“Ť…żűPßѸ‘Ă7®÷’ťŤ±‚˝´ĽR§nČ-mŚx(ě(ś¨ífľ!â ü/oí-·1˙/0*tÜĂcs|»­‡u®žú‡dżďUňń=4fčÝçÎe‡ŕS'./äíčpŕ÷ŚM8ü?q±ř‰S×Ň^ęź_¬9ss¸CgY×ŰKÂĎůöĚŠâňŃ0ß‚ň†: uť»í:#Ô-ŇĆ"ơá/žkóÉÖŘ™s<«nó^fđ/D´/3ż¸ PÖ*˛ ¶Do› üÝ»XĂżIuUŞďižâC4&Źržď&ĆÎ2ťÄŢÚ·+ż%á™˝$řqÝ—˙”gE1Ŕů‹ü»+ů¬Źň˙˝š¨÷D?Qę`â`b ʢ”ů&ýĚWëÄ×ÁůÉĘłť<Íí ďu¤]â1pŁ6+ç÷ ^"Ţň˸śCž‰8Đ—vćNŃbvŻQÇRdÖ_©|S_ţ'šłˇyĘÔ·1ŢIťĄľ8c ,űÇ‚ÁÔť¸«iúIšë|ÄűÎ;AO&sŔlč°jŕJ#Î޲ŕéhŞđzu‡H¶EUĺj"ôF˙§ě¸×¨7dś?fYJ{Ů ™ä;ŞçĆĺXBYm­6Äu©ĺ[ÁŹJóm­%×ů\g€WOĆMü>ţ7Rč°7ŁRÉřĹ9NsC§é…Žľ*˝ĺ|¶5¬µŢŞ­—Ą˝ˇłµßŽç‚›ÁfČŽţ7qTű6t=`č·>úIâp\]4^ççîě%nc«>ĎtěiŃyŰÖť]G\,;ós1˙kćUĚJ=Ç:öÖçry tôÚč÷­/˙ÓQeżc@® ]â·«Śymý=ň¦Dk1p©w0!8·+}Đ*ůˇ‹Ô íśč[VK„±1Ţ­¦ńÔÝŁR^9îóţ¶{ ťŤb8<Ëx^k}îrч|łšn%.¸­żMŢ@Č\=¦Ť‰sś~źNŚ!ٍ«ffţŔŘ T†™[˝8é·z/ř%Ń#?ˇ-_î»·Ş «‡¶rţs"ţ›hý‡Ď'ÖH™ńF^ÇŮÔÚV đŢdËÚáôCĹSó|ŹzAÎOô–w3úaÖzŻ6¶úŢC>ĚoüÎ×PrQy7gíç5R˛]8XĂ:Ân"ďËg"śŔ8\Oó%×QÔfĎĐÖ3·ŹHßŰôąŽ_ůó™\VĹ1©“8Ëůy1—.űÂn˙ÇËZÂ:[ó;Ę<Ę+ĆQ¨ĂЦÝJ{~m˙ÚJ Lۢ ¸úÇńoďĽóÚ .ň»íő\Ý׆®Ä!Ďë% s¸?Ž68Ś.ďŰŻÎČż˛íÂ\ę]ämšĎâů#¬•1ŰŞíUĎZąÍĽmí§Éńň;ćWß;v¶ęoęn­ĎĚkkŘ÷Ňu­Ţ6›¨×ßK:ŽĄ‹Uď±ŢżźĹW矣~t?Vż_t~?ŘUé¨P( …€B@! P( …€B@! PĽ·ksń›2ţÄďS6ĚcŹó{ůÜP8ů›;ÖSŕ·Kěźú鍍X“‹ßŰ '~_ĹZČü'^×.ćµĹZeqŤ9}č‹0đ Ä:UčŚßß­şăýt;`čßń»ŞUľd1ÂkmđľŤ×ć7TńŃ–Ţ[^Ą=Óńam|€ÖXÁöŔvźN{ü``čł˙LßеʲŽ&Nk?Ą‘ß(ŻĄŠŮŹfž\tnŰńűzśö¸íöÓz(^O?˘Ť8.2ÖÜŃţČěG ˝ń'ö¶":ů×XűŠßĘĹďĺ"}ZłÇ2Ă?ë§h˙8ľź•Ű—ýݰöi¬uDrÝ6bÁšGśőô z*ź¤ue6żüF–ĽźŠĂ*g{˛źü„wÖ±ŽĎá_%ÖKŘl3 ?1ěŹőµ˛¬ô[7x PŽág‚ĽP©˙l»–„źâC~_R¶vhEYŮ Ôm ô}aŚW6P‘9Ř Fž·ťčźŽý‘géšŘmâx?ŕ¤ăL:_ę._ş×UF⺸‰s‚ą3/4SďI^ě»XĎä}g!Ff]iŚĆ=ćĄń/fŹÓÚúŐÇb?Ä˝€ňˇ{·K=%úß `źs)oĚ·RŽŔۦĐŰN[xˇ•t¤Ű–Ĺ×ĺů@—٧| Ëčţďřň ±o@žŘ'RO°ľÉkňß«GGĆŇ4Lś»ÚN´VA‡"Ňmß/ôňý¶p3°EÎs»Ř;č®UŹŘçĽř¦}ß| \ä;Gâ€Ĺ„8⧸ײs(â3ÍWzď’tMZŤ>×ř3µéJK;WlłÔ—ęŰĆ|˝<čŞ*ˇń*r]™©_ţpěrľAˇî—Ú÷—$/D,Ýă‹»…{fÖ…cOżáÝĆřg¨őkvokôMŮď ÍŠ=ůúrh°u±Mk4hŐ4H3ő.ű]ÚęĎÇç™ć“ Ł~gľóăťŰşĺŔĘÂŢÜ%úHÓň§Ż–z^Ń|·çą‰CL·ÍĘckéú™\3?ĘrˇĎ–vŤ=ˇ÷L߀´ĺžć±ąÇřŐoJě9óťC¦×ßus66őg‡˙@é_‰q†8[fľ{´nnřZbAv'ĐŢÓˇű’ŁÁčhmqtÜa" ¨o¤q٤ü*92oęÉs¦=„X `A4ˇĹ­O;źmîOŰí‰pĚ'e \ë‰z…vfc|[WËĂĽ­b¬âi ůă`‡żkSřVÚemVě”áhů±śY™Ëć\wJě`<´đán :Ŕ٤î$­ôCf9ĽmŰ›büęśÄ7ĄtzâŘ…~Úťh ÖöŇ÷“9ř€Ľ‰<.ÄE`>jĎ}ÉyňmúGÚwáŘ÷€ˇą#ř@}6?ă‹ L Đ»«‰|vÇÁß ˝IÚ{˙(vB¦y‘ĄŁ%ú1‘”x É`ďŕžR/l¦lăĄ-|ťŁ˛^ }¦Ô“DVaËâ»Î¦%ÉlŹ=ă´cě~ąţôţÁęý.é&_F‹fb>‰v?e›őůxűçއgĹnp9N§Śů8G ó,·›0říb›ý3‡ZĂň úťŔŘ60ůđłb{NGßŮŢb3‡ŔąSĘuař˝sܵíK°ă±W‚K’¦˙cľ.úęď&“–Z–Ť9r|OťSťúŤĺeÔŮĄ„fŐcL—,šţ$ yxۦ޿Đ×?ň|–;-ĆiĚ×n¤Č7ëšú ‰HZ¬oňv‹ä«:}—ČۢÁźÉýY裙‡ÁĐÜ6ţ荣nŚDĽÂą>"ö´Äk®/eĆäÓţ`ůNďŕa«nńÍsŐçÔÁ,á­~OuŽáTĆaţô+b»°Ź_]qŤsľżÇ«őłw|TĚçjŕřđ#ÎQG#Wő)Ř%Owó é»vš0'€ü˝K{> ĽÉU˝‰űE= ĽŘŮ·ăŮËťY±ż#ťşJllµcpś[^—č˙i-ŇZ‹nŐŹč›kĺQR,#ŰŹ›úÓŘŢÁ[· 8űď*eĐą M7Ó|4úÓ[%/Ś…ţ‡ ĺQ›\ß%N·žkś¸ą6uĚő ^ŻŔ¸YßÓ>6»ş˘Ż¨Ďő¨ńČz˝9Ç–hŹÍźéŠŽÉ&x‘/ u´˘ůQi‹™§vDźô(řr•Đ| ±ËM]«Üţ§c±¤çcî2ű8ô¤ĘKefaI݇c“_ţżßĚłý±ďÚĽHw˘˙F{Ťz.Ř?Ŕ÷C{c^?n«?GżÁ>Ű=¨ř~ƾвŻ˙Č9xö`bЬhz-Qˇ×“˙&yëő¬XcÝ4ĚCŞüëýŃ8&“ĺ¶]窢R÷Ă ď“>CÓ‡ŚŮ몔ŃF—®źV­{ęAŕnW©Ń­éĆ|ź°yŁ^1°<XZ‹…öňÜăÄéByÇh˙ş°VV/ó±ś5kĚi¨ő`Oěëło‰®ŻŽ‹8rE^pĚĘtWW˝*3EśHĄdiĎí"W‘Č$´ťFá{®ę° ¶=ýv㏦lË9÷Ůzlčöţo[ľ=—ŘZ’Ż?éĐ:ÜĐ‘sOg™K`?ÍľPĺ»-|Ą›Ż8 ,}I k{`Ąî)côă…{÷ż¦iłúĺő󣳉ksÚĂŞË6üRňĹXÓ5óýăÖ·xéŤg‰5bxBZynú{sŹuÍ{†foĽ8ń¦Š}Ewţ1ě±Qşn¶ţroÎŽ-ý-äz00Ôz°´§óýéçf ë…eXżpŮźqěĎÜtNqíˇçšŁ–f]CźTÖi÷IáűnâKň]ŞçQű.çiř ءŔź{Yň5>(Ľ;¶?Ž8'9ŕŇŐcţ@©g®i0çá†Ě™ ¬á†ŁM˙eöˇ¬¶möGZĎ: cü8˛Ô°Ń°.ąFÚyƵ›D˙ďDG`ütľˇ|ŚíďŻ7˛Ý™ßňÖ˝9ź ¬Ń[d­•wăŮHY°ăĐŽ=Üű"ıAáł2¶Ę5ćAÝ–č÷°F·ô«XŻŁľÇ㪪y2žÖö¤Ďş>ęî‰ń˝^ŹýŃ´˝Ćřů ďnç‰F ë‘ý’ÚĚ(řłźĐA{uľs‚;ţ#śČWśTŹő\y¦ľee§¸|Ćv‘«2؇l×EÝ_B™ĺ}ÉÝqľŕzÇű±_ĹWĵaťs FµÚ'«ŞNůÔůŃęÔbGíŐŠĚŰFŚË¨‰[\(>ö „0G8jvĺč˛ĹÔż¶Wő§Ŕ¸ClPĘ'}jý;ÚyY̡¸*÷Š…gĘÄ´ĘĘžÝRŽMjJ;e»řŁžýmłÁű§ ĎŠ}]ęśňKYĐ7ŁŻŢĐű[ţ±ł‰xcń¬YWby٦«SŽČ¬·ou˙‡ąm3—·ž¶»ĺ“+%´u]¶fÍ{ÄŹŠ4«Űş“8Ô}ą`W_̉gw.ě3bäz+!´¤ţë<Đ·ýűYťď1cjěź‚57~t‘ď7`âđîÖKo‘x/ đi͢ϫęmŽY¸ľË}Ö5gPLgë9#vöS¬Cô˝¨Wő1ţ€©žąđ?‰ü—Ô±Ö ëÚ`ĆŮ5×BűĆ×Ď̉čű˙-Ç"ť¤őřéńĚjúţ—Ő±Ö™ˇą8höwĂü†¬ˇ˙úĚ’ľ\żÚúŹťMĆź—ôs-ď¬&]›Űúiۆ^ó†Ęű†Ţźx6Á Lp`‚ŕŔ&80Á Lp`‚ŕŔ&80Á­…:ßĄÇ •ŰĽcâÉyľuü^Zy¦Ä3Ň×€ëŽę;õ9P {“Ń?Rçő >0M|.ëw;ĺ‘~ňôS÷Î oy°Ř*B›Ň@úH;Ëoâ¤ţŻĹ<;K08H×)ąvE˙GúŮp=‹>6üNý‹¶ş ˝ôc˝±Ü¤™>üăz2×ÔËsÝđYEĚ ¬Cެw6ŃÇľŞ˛&=ĐőÁ ť¤—ň˘éPN űĄĽ«¤źDËFZ¸÷ HÄ =&~Ë[Íľ˘Ľ?TřUéÍ^úŰn¦SôĄáŰfýŽ÷Yďô?ăůxa¬ýźů˙Ő2©Wř§ĘZ3哲J>PnYď‘Čţň¬×hh§ßTĎŕó.×.)ůŠ™!b/°Ëřľř7ŻDű0őí˙îG»viĆçůNčŰDş ôcżÉCqá»&2˶I}Fą×vKy7ë6¦¬†/6÷Ňj=Ŕú•ŔŮFÎUh}3îk|(,Í…üöę¶ŐĄżl y±Ď.ŤM&_Ľ˛ źúĘĚľydob?ßăL‹ąîK&ťIp…ä3ňŠű3NŤ<_72Ézcź˘˛Ír!Ž»nź’˝Ly·řć0¤Ž Q†Ă±vëĽř¸ź)>”Ő)łpş˝!Ä˝WŐrÁ¶˘ëzSL},ĎĚ^‚ěřgę­Ěčú •I–ʱ#ÔO”űąáiˇňÜđE {×Ýč?ËiŚ?l†὇´s-1đ;ăţ§şęTŃ7qM…ř´NÁ×b?Çş¦ďť~7vGSÇĆ®(“¶Iť›Ż¨ůcű\˝ţzű9yÄ2řr¦îXžTĎ–'Ľ~[t5÷W,+[_ec•x­?ă7ĄW ]Ôű¬÷±”ńĆ‹öu±Ú¦®Ëŕżü?B7pÄDF+3+śdňlKç2řďGťŻXźkÄžÂ?öäzřČ–Ôs z˘Heń¬@żôĚű čű˘ťC>ŚÍ1n3ŚyČŢběSŃ×XÚó‚|Ňť’ąKhAě äxáGuę(‡şýËÍż‹°w¸–öX»ś·DĘűôqF źřFR_.l|Ço–öŹX‹$Ö\Ó‹#ű'¶aę`ňžÔ'ęŰ9R»dlqřWŁŘĎ!ź4Ż:5Mä‚ßUf*…O}ÉNˇýcŤůŢË{ŇŽHĎĚxÖĆFűÓß˙î–čź-ßĆŽfĆN^R~łß$ŠĹĐ˙‰ěoş0ű ĐĂr,î˙ăŹl ď—i­8%ĘöęŠURĎ|'ÓázűňX~]]dË‚ö‹Řín)#żá/ć»X$‹JîešĎ ¦ q›BąŞř«c/Q¤gľ ^×^‚E§×z Ç~ëŽćŢ”&.q7Űz;2v bóŠĎűćMţ“vőIîÝíł—I"včÁt{Ńľâ»ÝůwNä_×1x$ĽçýQÖÁc§‘in±ü Ç.łrŕOŚ…ďŃ5Ţ46őś:ýíZzQ}®„řuˇ™şTĺŽuÍ<ń vHtöţ"×°'ĄÍÎ*ŕŮřÓĎźŕyů^íŹH$çň\msöóůŻ™xc–gvô!čüÉŽĆĄl*múŽĺ‡ţµĽĺ»Jűä`Ą÷Ć6Çűj'ó=•ůóaSńÚű{¤kű÷čć=ňŽ{ÁrĽ¸$ůsÉ‹i!VĂe,}Kô=‹Ŕ›#JĘÁoÉ›ÍĆF5qĽ»éż…ŮAô5•b/j*ńě­ďĘkÄE -ĹŽÔ±wÂ1ź±ĚŤńk˝´ŠĽ°Ťâ1ęëdô×g5©îă7Ő©f雼mxU1—×%0-ő'‡ă6^ëOÇ6ŚÇŃ{›sśQ5gůGŽŮµ[˘ŰĘXź×ěł(÷^ś'q±C› ľ»!Ř)mµĄ¦Ű‹ůţ˛cĆ ¦´ÔßŐ©kÝĐlëµ-ĽŻ=ç[óťI¶X]1vß.Î@×·ĄílÍúí|'ŚÄ5,Ę˙·íNŰ6ß-Ďť)uÂq–/÷xíű'ŕE°n'ŕ)ę·zě|źÔŻĘr˘˙ŃőŤM;jż˝Ěş×%_â±3Ř9‡—Ś€Ű‰ą,‰fĺLy7цË=ŽË„yž{l}­«4C­K¤ž‡Z÷‘ţ ř/ á§+»vţdĚîáľU±Ŕ}±aW`z%¤-ŻŞZ¬Đílť·…Ú`ëĘwä=ŽŐ.„]RW6×Ôq‡˙˛B>ŰÔQÎŘ? ¶žXß}ĘÖ;ůĺËmÇ2Hy®ů-©kÎik˙ lŰ?Ó¦ôĘd[¸VâaŮç¦ÝI°Ý?ZĎ˝ÁYÎÓÂo×_ ů˙Ö¶gęÚż#éŘë…ĸ̿(y ~k€ťPŰö[9›ŽI~…>±$/ęî|Eő´łÔźŇ9ňhĆŁF_RN[˘Ďnp~…GHőÔa.%HŰ ňfytDĚWKů#=ţ˘ľź°ĺÚ7ô.xjń(Öý^§âbËăD˙+śăr”ç.D}«íµî#é5ŘŤŮʨłtbÝćRá©“ŘzŕtôOż ´…?+é7Ä·E úŃŁŇžYxÎłóóýKęă`¶eŕVvX™jŚźę¤Ű—Xą~XKż/á;íę Ń­ó&·÷ß ŚÁ7”ńąÚ•™‡Đ¦wÇ|ËM–÷ý]ńŔŰ,ĚŢW,‹Ě۱ěţëđ?Ę4q­ cśîü‘;¦:5}B ć+l9€˙‰qŔ^5Ŕ7…îąUčnŚrňM^0ľŠíź}Žw̡%_ŮîĘŢ6ź9‘;Ą^coyËř}4ŽŔ‹’´a?{píµ¬Éˇ­Ç¤Lź÷OÎÖRď,qyÝr­őO9¦í× ĽŔ‘e†î¨îu-pj;üw`ěúOI¨u±ĄŮ¤3ňËM»ÖXdµąú’‚ËWHě×čkK1zů€c m‹JÓ;9’fb3źĽXÚ(ćdŢcŻ7L;7ćű˝ ěy{żřţhť™:ęÎ˙Ŕťç|/<ŕě^%vÎĎ™úď”9JĘ(i.öAZÇĄĺŃo”´Ű(ÔÓ›Wć´ŰÂ}ŔBřęvćË ¦”‘“^şý§Vź”ć°yWĆâŹă9™kŃ?\ćrśË~\iăÜ5°—1v*Ö×:eÎáPńe…cKÚÍKôłáéĄíą¬ý }ˇ|2G#7††|Ĺ˙:\'l‰îUśs«ç7ŹÂµżćZF8öá'pg¬®TĚ«‚úËt‰Ľ‘NÖg<{DČč'CC×`Hß&64ů2ÜpyIŮM[*Ň­őZž»ZÚđEľń‹ĄÍ6< ;ˇ8žaýć{°.ő`‰Ś!ţÓˇMůGĽ÷łî’äJÁŻĺ˝ęÔŔS~]bÝŮĽ\Ć:lmĄ±eqŰĐÍ< c!Ĺén(wgŽBßäÍwÝç/K]ĚwĚš }((łÝXŻńę[ĚcĽŰĽĂ»ńw»Ě© o—úa[h ݱżeś7Ę6T—đJó&Ţ©9ďlÂZ4âćϲ˛ŕĹ®Ó÷Çęř7`ŃP—wř˙ŕŇ–P™c~‰ţa¬µ˙źĐF|®oi:ţá;ś7^m3řŇďqYçqě-ń+щş·ě1ŕaN•vÂöŻë&LăÝü]›śătö,GĎŕĺB/ěÎő.ÖgPß>Y›ăs'ql•ŰDG« sv ěÜe‚ďÄ®ľuy¬­OŢS]1Ôşkčâ1ŢůmřÇ˝şę›f0áŘ.©_ŰÂ×`χÖĎw †›Ë:¸ĐdŇënĹÇÝĹý]ro%ľ‚Ő}śëĹ÷NW^ä„:nËŮĂĘčÖ)u2ý=ĐÚ:ĆĐA?ިSÜ‚tĎŽ>#ô’>Ż˝É~ŽĎUŻ•ç:E.Ľ¸˛|ţî˙ í:VŕXŇI”aŤeü)*× Kɨű}ťađ†ýąžŮ†:LËŻk]ĽÖ>_ő¶ľłĄźtBÇůGa_‚mQV¦ó·,ďpĂŢőlźSÓof{EďŻh~Yäű/đbńšyµĄ˙Š{ÄhI»/8IęӖ؇ .ň¬XR|‡ú@÷7c?Ď^ď¶V`~€˛łµüLYŐ÷€ĄÎ6 „X·ŘëČÍĽÖí° pöaĺąIő5©˝°źÄß/ŢPą5Ńë­SnĹ×zk _ëRoÁÖ Rźtý[už¬ĺšy‚­•f´]´Ď"NV‘ÓŢ#!®ýKáŘ bßżĆâ{^n-ç^őů¦™ń»0w´ł«¶±_ĚüYq]˘3Hyź4ăś­¨ ŻżhočÓěy`Ö–Y—¦>cľ©ŕÉńÔńöžľżő mśĺOŔP}đc¬:2L)Ěł|X|Weř>ďîţ ˛gśč!ňžuLZá?"ľ Ă IŹżLvF~AâŔA›ĄyŃŕó!Ęë‘4Ó˙Öm,Ö«îkÓť˙~q:Bs_ňIÄŠ,’řiú— vGäXĺVůâ$®ýçíŹČ_ň4ÓĽ7özŞ?…xŚ3%Ţ_|LĄź»~›Xm”cţ±\Ő©C '¶ůMŢIúvÓň‹˛F$®•ýűsŇĚtkBüŚČ÷@מ¶Ý7ĆŰeŻ>đDx«Ľ ÇÎtŮ·Óž!źµŹĐçŁuDübaΓňŚ´cľWä>Ű6ŰYuĘěűHޤzZ„–ŢÁ.ě‡ü)Ä>_\7B䍖ŐIDl{n(ĆU˛ěÚG·…ĂRü‘ŻQçæ<đ˙Žg;mÜUń­Ń=#˝)"ŢDöĹ=ř7¶Ł/ľÜi‰ţŇĄßűîžÁĎ ]Ťqł˙ÜśČ1n®ę ˛‡wďŕqÎŔä[Bô%a›N‘—>»ÔP«Á4Ň|'˙á]GhhͶÍ}»ňÂÓplĐÖ5Ű1ë<ąÓI=P&÷Y/ôSÎW\(¸ ľÜ˙!Žnń$qwUŐŻäť/WG˙‘ć¨čÎeŤşú>‡:0ąľÝ÷H¤ňaőaKôS¨´S—ĐWt´m•î|ńćÍťâźH]Ęó§OçŞ2’w;đÍLnć?uxşýf713ÔÍäăd©gřVyî#!Ö?ĎŮŽ©‹Y?¸DśpNčă3ôEđçşIŕĂQΩç´ďĂžšuŤńĎ}˶˙ĘĚW•™%Đ?~ĐVc:›ó‹ův˛ĺ!év#ĂL3†ďyĘbv¤Ű\3ęjęUřóş®Ňý‚˝‘ęąi=‡vnöZd_I_}˝ţ̬?ęAöĂŘŮ҉τ.ÄXzÝź ˙‡ZOš»óşs˙QµYtgš,Í,±“ýoJ>Ř+Ö>ĂľóÎŇžÝ`GĽÇ]Ús}€ü)Ô#ö¨*îŃÜťż\Ƥ—?ę8Äřşçűż"şś÷Ř'3/Ö™ęv¶Ą¨ó]g⪨ñ!)°äěŢďŔ›˛q…LgSNb»PďŕĎ kÂŔ[ÉĘx‡űýjzŘÓ˛x˝Öű<˛­Łţç¶Žşó˝¶ÍůÓC.mXľË±•Ęe-đP8F­Ným˙Á b´Ë[· ÎŚż-uŮá?Tô:đOź·ńbű˛şÓÉAöďńl±žöĆüKŐŢÉö°wä?Űhuęáł „u›LľŠ˝3źY7OăÝá†Ŕ˝3m™öńĎ6ăCę~Ú,°Ű,ßhźÇ|OŘ|‰cx=ł@ú’w§!.±Ň:VŇśĐ"´ťűíĆĐ«ď2^î­Š™Â_•łĆř ´+ęŘ'“|—şFżÁ^©R~čˇ iŇűŞS‡Zk$¶ŽôŁnĐŢ˙†2š9ęicËK[:ˇŻÓq—ś÷ş§Y™ŃtgĹŚý^ťz 0+öݵžë{ďä8ÔjbCř.dĚaś…~×—l>đZĺł/y6p*zśóŃĎ?¬[Úf†ÖÎ 0M‡ÇAÁ0ecţžń%nâŁÂż˙ëŇýô›îü‰Ŕ%ű‰Č™Ţ‹ů VI‡ö®Ý›ÖgÍŽĘŘ­ěßkÖXúzŹŹ W6\ |Ź:ű"ĘÓŘĄ,um8vsl Ę·áI'°kgŰ:¨Ě\,ßďŻn ëIŘâ‚Oľ™óĄţc[ÉW|Zt>ĺi¸aWŰG\ä;Ľ.ŃßU—Ż81›‡ fô V&ÇéŤPľĽ“Ł™ë*ľIŰ‚Ĺ;;ü—AöźŤńďÚö~ă@9Ź. H9ĚÜvOV—čUŚŻjrUßFĽř)ňžI—~Żoş}ÉrŽ%ĺ}Ĺ/˘>‰Ţű!áÚż<››06«ÁĐŐ¶óE6Ńţ6ó“,Ë´ÔÓnÔůEˇžîF\çÓ–ĆţÂX(ęl‡›íśE—Źĺşľ¤±S×%g}Éal¸ŻČç±Wj†ľůđ+‘ľŚĎDGxyËsŕ(ŃXľA|´Čç\tN…ýǬŘ÷Jd~dďäşwp®•G}ż2Ó'ůAÖj{ěë…~ĺń °a.öť#uL‘Ů¶Ç ÖĄ¦AŮMôu-ýĘv@6Üđ;I3ž­GL÷GśĘ ˙.´ ®VĘ{qôĎJ]cÓ]Űö€u çéÍŘśepJŮ:.şNŇs× Kwľbi@Śđ˛nµúŤí1^upGËĘV·#p+OCzłÔ§Ö?0±-/ďŤřńç ér¦­öĚ@×ó¶żă}`zZ:‰Ý‚¶]Ó—ä|±řŢެşÖľĆźľ:Ř;Ř*|hˇĐÚ;xsí@×ď1éJő¤s~ŹΦ)™kC•Óoł\ćýΦĘ̶ÂOâ÷šűeM´ß çö@}ڱ┞¶ítNäpč®7Y`d4Ŕ[]±ŘŁě§}ҢP_ćSĚ×ZţňNľâl䵏”ĽFż˝;l˘mÜÍW -Ŕ°±ő}-bIŤmRě—´Męťł˝Vć(+:văřĂ´zΩ› X4 Vö4`…긙q©—ďŕÜ@/Ž™ćÎ’2›´7ţ?dř*;ŕĎŚńBynĄÔ7χZo .íŮĎĄŽ6ssĽkúŢv˙QŔKąŞ Ezµ®őH}Ďî(ĺ]]AŚ%Ś›Qç/#Mö ‰ţ«„Ź-ŃKĄ>›%×|ŹżŐFŻÄ|ßT™16á˙Ď®űÔá]ůŻłě6­™ńÓĺ|eĂÍ"ď1ßŔĐčq憿üľka7]‰8ďg1l`ÖÇŽJŰúŽÔk¤ h÷+aGu“;”čŻn@íÉ‘˙ Đŕł>ă1WŐĽë§6»žŻĆueĆmĆÍh×!łľVVÖ}?1źßü÷™ďKÖcLr°[– ÍëŁsä}S×_F˙sćMëËÚo•tgĹý€`˝śŽ>ýe±O8V×1:iÖµžŹćĎ;Ű{|©Ž¬*č·Hä±Ďh?{é˘ýZSĆTkËşöyŔ±:‰-„ŘÂ:`ůĚůŢ€Ýeđ\YĎ´QSlëőÚŕ>%6ÓćŇÍůdŤ¬Nmkĺś4™±qxÚĄź0ăBŇcÖĽtŻhţ˛č^µĎüé7Đ.‹´“ĎxË\Žą©ęÔć…%áűňpě wVlělÎ ŤöOhîßѶ˙?Ř”/ŇI=Ěľ†z—ąg€Í‰|şöŘzŁŁ‹´yéôžłŤň]Úä3ű~ţQźÉzŽ­Ź ÍĚtGťŮî2č^ŹöOĺ®ÂĽŞŕ”•Ýś{ÂęDcůĘĽH'l_čČ⾣M«¦Ç=kČ_öŔ”ş M…>CôĎ«SfžŹqý\«äxŚő‹úĆř„ř"†~‹}4„VÎ;“GóŇc®ęvé÷őµŹR¬}w,Ź©žr×I|ÓéK~ÇÎŻG"Ź ·©wÎqíč6#ć˛ÄÍťůŢę21ŻťÖ2’']őčÁ˛uĘç…µJĐi°Ç9Ĺ<ŞSóŔżZݢiŤĺ±!*w _äŮ—Űs“;ľÜ°Ń_…=>YÖŁý_¶}Š™?a˙~ŻČ?Ż㳀»ŤĐ0Đő#Ű/¬®ř+ćZ†ýŮűzŠŕ Rż˝¸ď{ßűD'±_áü§ňWńÇ9‡Żú›Ď0ŻşX§óĚĚ]•ç"Bç¬ŘŐŔĂ< ¶Č”c¨–čCÍç‰1ŇÓšţşŹ¦MVfv©O·űi+‡Z«e^ż~ú ć7Ýă÷rUfÜĎv©ó^/ čujęZćŇh[ĄĹľĹü©đ•¶7ů<ŢX%‡ťńyY/Ě6ä]®Ëq\‘mx6㙲ŢôVĹĺđ‘ř”Ő˝¤ŹúKů@ ®Y`^6íC¨óω.ĐçÜŰý1.¦dú‚S^ě‘oˇC/}LýëX?ątÜńw:µyČ*ËÎöĹňR{ç}…†Î¸ŕťďżóK/`ŹĎą¬Ó–č¤úD˙aNuę.©×ŽOýÜí¸őZ‘cösXłä…¬ăK´~ŻĐWÓŢ»ÁË=_”÷#Ź‘ČR¬—^çR—‘fĚŐ`.üÔPq® ¬ě­Š>Ś5z­śÓ†isÔŇÁÜÉśŽß•âőó]oZXç,&đCŇ;}ĘĽQµ­‹e[˙űę(Ž9{ âöMżr°ÉĹxđ:·ĺĺC!ďÝ‚^~ĎŁůĽÓ®ÓÄłź”6şŞjçÂüÇ~Ž›jőˇW^x;s¨µĽ  ©OŢŤ_Ń>R{ڞŽ5C‘_-Ń´Ô•Đq_ş˘ÎŽ“ř^hôźŁVđĂô]=˛Ďf›¦ éR©­«oľGĺw‘~ęU–×ŘÂśłó‹\>ü?-ˇ®uaŘY/a‰RL=~ëË-•6Üßu\¨%zzó(2¦Ń4Ţíă?ź<őV¤›ý3uZ¦ůaˇSí3-'Öč 2Ę9DúˇĚuźh÷C‡o׹L_föéŇń)ű McË8š_{őlńK5s~đt±× çxÍ/_­§>ŕUuŞ >vŢłđFY™Y72ôĘźć5˝Ž4íĂ-ęĔѩXç“Ęvs‰ŤIě,>ăşô«ŻĚGÝú,rU7Ă4!xzĄß›«­çżŇ],1ćxĹőJřz'|P_F¶úŇ—sË“ă">3{?đť›Ô+ö9ÂŃ+š‚ňh]Ďôť­éŘ٤űďüä^báú*3WŠ.cß´5Q3QÖ Lp`‚ŕŔ&80Á Lp`‚ŕŔ6‡Ć7جíü·Ě}¬›śó /|]íšćv s÷ë›˙)úTfV¸Gm÷ˇ­bŢdĺĘ3%vV9ÁuÓź·†íú1| ę9˙K?)ÎWß+Ă]çĂş:âíĚ>đ1ßő«€ń˘émyÇNě…ůs¬5ÔYűjz-Îx‡˙d‰…äĽ&ýéµ.ŇĎąnú›IĆ< ?…̇rŤë“["˝©ž»e.kËđ™ieZËÚýĚy’fÎőŇ÷K}oHŻ®Ei}ó»‡ŕWł˘ŮÄ]®{žTSߣÖâç<>ۦ ąŞą}ˇč»Çő+ú»˛Ţ(׬[ýăú¦ŢcŚ)ľüŹĹýĂ"3]s„‡şö1ľ–ćĆz2ĺ0:9·tW©kř˝JY˙Â5x¶[ÎŮSŽąnËşdÝňH}Çş'Oŕ÷,7ăś9Ĺ|MŘě@»Öˇ{ă––b<Ż:müWÔůĆZ˛Ě’.ň…ţŚO6>5E˝­zŚ|™=(Äu<Żl+>BdăĎŻÔ©ď‰^Źß±łI}éS'úĆ›7ăU'ůÓĎ OÔG–mYçôˇ§u}R>_—ü’W\ßE<™Ľ ńő¬xK0vçľÂţíĚajz†řް~ůÇú`šúĄżÔ,wb?É‹9‘őFo™˛éZ5×_Ü^Ü“{A!^ňáý\ł _ĽcA»iOcGY1ĺ\ŐŢ?â==Sü^“ÎŮŃ+€Ű°˝Ô Ű+űćHäzę=Ę5ß3±ŕĎÉ;ůrâ‡aÖq>‹Řďkl›áž)·aŰ.ÜšÓđCk‰^WŹýRť–«jBNÂě ÇU7±b@:áËwˇ”‰u©˛LÚŕĚ'÷á‡\4¸«`ŚP§é5ăá´®ż~°?#ß®Ř3lé&ߢÎ|iGýâ?6¶tźQđÓA¬|›Ý"fLYŮŞŞ;]o˦멋ŕKŢ(:ÔeÔIáŘţ‰őĄs˘˙‘Äż"F¶OŇ`› ýđY–ú'Ďô?ł@8ö[«ËÇRĆ»óŻzň)+c™ăżBŰ —$˙Ú/žµöű`Ćőł-łW6< L‡)đk*´Ă˘î&/śÄG$í,ü“IżÉU}Ŕć—n?ÉęH´e`'Dä=Ö;ĺAmĺËhýBó!-S2OÁ.Ţ>ÔŰ[ç ŮĎĄ;˙ś”Ół»L|•ٱţgĆŰdO'–•ý·ÚÜ,wŞG|KĘ^Ď´Ü*űz­>cÔăÚo˙ĆźEßť#bĆl="Td1Vž)ŹÔ±ĚŤ~Řęs¬:›÷Cm9l”·Ä†®N}LâÉ Ţ&6:ń[°o—¤·ĽŐěĎ4ô§ţď°S¤\ÄiŇg›{lĎľ%rFZÚÂßóťâOż74Ô:9DŢł>KňíĽ‚<’2!ŽĆň 2ę’7űî µ.ĽĘĺľ®"3ÝůíŃ&ŽşTǵĽ|2|·ă¸×)ţŻÝÜézű˝’Ľ7á‚ůł}ŽüTm!'ń{ˇ!WµżI3űŽť€-%xHůŠ$÷9— ¦Cű[}z«SÓ\ľŹ1ŰúđíyóĂ>­I|^hf›ň§÷ńČtöŤggĐżĽ źŤ­Ă'›ţ#ŰňÖâľµ•™ť˙ţŔF9HÚ6óbůüéK[cö™cnŤń÷°ŽÄŹt,đ˝¶đߤîŘ^É3c›ě!÷h!î!¤ľĘßď¬[łć ůvEó[Bó|gÄçí-íjyëyF;E)4íhóú/ÄŢKy4Í‘Ç.©0ŇߍúEużQťFĽo” •—ůΧĘą±GŞCÜ÷ů†fş3ăó€ĹŃßč™v»ě]w­ČuăqU°Ó^żéű{v¶íĆ›Ď;='V‡÷ÝlCPřŠý¦„ç|_[9ďÎß?ĺ7óŐ#±ŃÄ]âľd¬[öÉ´7"‘|ÄĘ…‡”M¶[¦XS‰Ď±űmÂGřL);ćÖ˘!űD°-µ×´xö"É 1çR_ÎěĄ>Đő× Öó\ߏö2íBmwÄ{ă»}ÉťŞÖö>4n%¦†‘·®ĽĽË:d:‹•¶LŮă5ëťĎŘ_aO]7öĘퟆúCË9Ä Ţ€ý ŮoŔEŚÇđ÷RĎçűŻ”Ľë˘ßmęŃ—3şIżGüe𰄦ňÜś¨EßěĚsn<ůŢPë6{SáÜżsÄŮ ~â`»\î{Ľhʍ Ő—|Uö“56¸iŹ) Čň=~˙Ďü8?F<„‰©Sťž«ňQ–ȨŇđźŽ{˛učOO"]ŔÔx\b ĘĘöĂkg ź‰<Ó bФL:~dúFźú?Äv«ĺHô˙ĽP¦NÄÚě[obŞ 8Ż@„ďłÝr<Ę#ÓB<—đ¸NÓyíýˇ˙+á‡ćĺ}çťž;‰‹±§ď.¶ý ĐvČv˝ww™×`zđi,É—ĺć»&ţÄĐÔ;¸JęÎźľ,t‘ďÓő‹ í4SF3ľCLŹ:€ô«MĂX-Ř(¶,|Gő‘ĽQ¦eؤzŽ:O{ă@`…$k±¨ä…9ęµÚĚNą•ĐŻ‹SŤeĆVç†ďBżŇ4}©‘5ŕ&•”8rRFĆÚ‘nŁłÉżékĺŁôyŹĐĺVy{ÍKú»g6uO{ÄĘL>ľľú˘6›żöýÄ٦—¤?Ôz đvV6,Ǹ¨ą@Óńus"ň¬ĎN@yg :ˇŢňAçH&ˇíxi‹ův±ş±żhß5W€±]‰ţkÖ‰cť|‡yâőŽń˝é®}Ţ)űű˛=Ń®#>eşý>ŕž <ŔÝŇž˝ßˇC›/ę4bŮKElÖđŠšĘĚ7lYÍw{KĂsú‰%S»őŘlŚ_nhkql}’1ŹĽÂćKśÍ_÷ĆÖëM;u_ľb1äÔďü±áŁ(÷´şpěăÚn€ťp‰ěş˛Á`;˛Ç|{†ĚŘňš}öEb0Ę7ţ{í·,0"…Ŕ -”żłé™Öm¤^µ-źď?Ä1zĐP’č?Ł$ Ţ­N˝fĺŃĽµ)˙;›ë9ňË©éI’_ďŕGkgĹţ%ĎŮÇ Ţ5ý‰~sµ[öčáÄ;•ţ‡ßÇ\ůxÔ–sý4ďCKd8Wő9‡v ëă+Kl.ôŃ{Ę5űH~ËúmĚ_ü8ЦśQçÓRžţ®_۶`Ţ|ç˙ÉۨBĽ‰eÖ/§¦/‡žjµüčKšŘÄůYĐć$_Ťűç·y-|cô8bÇC«ŞŢkżá;˙úuą‡ýÁ%Ťá†V9¶…ż şŻ¦çî2ޤMCű|1pÚÂ_ž,í9Ţ–‹éměŹóAjó[úÓbO5Ć/ĹÜŢ‚ŔNą;m{äsâŮQO›}Pąoč­Ň×úrßťóm2ó†fŤwFÝ!öěU—}í>ť'(´m`µŚâsKęŽzf·L3č,ę{–a´~1ß °ă{]ÎÍ1MŕwÂĆ*Ć«úŹşŘ|“˙íÂkľţJtęe5ěÚ#^Xžý}0ßĺŹôµ… ¶Hˇ#/Ć(î)üZŢj0şřnĚWÄ áX†m‹uÎg‰ţHÚ<ßÔźĆI0·j=Ä|Ăöý)ć1ź¶m•ůôţIÂţN…íÍz7e¬¬&ŽźhW›q ©s¦OZQßΊće×MsnšÔmď`u‰ü3µ˝˘Î{CěhĂđţYg­=ÖçýŤű‰ţRžt\¨i¨ťŰ?´ń¬˘_˘Îß!«[žó]śÓŐ÷É7µ»Ť]©˛Ů)ĺ+€ĎŔ8qľlbÄŠžX7ĎIHÂüźČ0Žä9őbö0>1ăŻn×ü6ýhęBÓö¦Łs2•™vĚÁ~·¶/yM‰žRyÖcc|M!žHxYv⦍ýeň ŚłľËsŹ»=ý“ŃfĚŘÍIĽ$˛dřdJ@]õ0ʶ)›IÓ[ľÍ9WÚĽi:/ć¸P«3SŔ\ŇwŮŠďÚČďş•ňÄ{dżĄi,ĹxŤçlkĆŐű,W±ŤčÝŃ:i‹Dľś:şÂě%@›ë.¶ÇĹOŻÎëZm%1Ľ+ŇÍoYOĽĎýżuĚÍ}!Ěe'ĆŘ'Ň6ßQżt™ąPÚgE~Ž­šŽˇ9Ń˙ú:eW۵ľÍ#đY ßŹ·şĽ×آŹÉ/ÎP÷śçOcÄŘX§°Ľęđďz uMy6ëZ†fť‹B»—˛ÄMćÍw4ĎŻŚ9ÖŁÝ^'uě•CŘÚ!µ?˘ÎeVŹëŘÓ—ű„ĐÎ:ŐďX?éöo»‹=sç,o®ę«öűćhtřaXďi‘g‘˛eí?°xgôÎĺG\`ÝYŻÄ2 ÎáeSu\şýaŰ®I3u5őRŃwŞ(Ű,ëŃźţ1đ^ú0~Ý‹:_ô4h‘tZ˘ ]ę¶eę|Ę<}0±âľŁGĺÚ)=…µIâdP.ëę|ŢĘb8v±«ë.ěcâY3ŢD*MÝů©gě‰!k9«ŞRŇFˇČíJń1`nXϤš:ĄžŮVąŽž˘ŐÚ«+^uG®5¬]ŇŃ˝3s˘:ÖŐ”gĆ?,ą0GGśmóË6<_~ča‰gŽDžŤ~ŞĐÂöČżˇÖ ťÓ;Qdó–Ŕ¶éŻť’ů¸•ň•)NŇÄÜş<ŁÜĚŰŁPĐwp  eąĂ˙'©+/N ?_łćJĐÇ1üëŻüşĹáŕÜMuj‹ą˛ ¬ŐőšmŞçËVnôŹX±ă)^/k˙ŞK¬žŹçŹëbčÚ:ôŚ­#–#Ős|mu* ťw5×?äć0ŃĎM–ąoęłîĽúG>1¶Ń}ÔJć^€ó¸xř˘|Ďuř VU}Ő;SszgÇťrSĄž€q¸­PÎľäqőÚoešŹ“rbňČÖQ8öwĐüm|gě÷đ'Í'sč2vűÔô^2®  uN>g¬8ŹĹźé?‹×cu¦ö“Iß>v<Ű \OCN›Ëk_Ç|®´aŕź[¨ĚTKżĂvŮ®-đͬĹ0ŐÔo:;ÔQ˛Ö9ަ–É·Ă˙ţBße®Çöżö3&ĚąŘwě‹őĄ®i‹ZĎ|Ł/9SęXÇAÄOőÜ.\mŰěguqľâ1áMcü@Ë`vĘóé©˝0~ąDĆxnŰ»ú{Ś-˝&uö“Ü3AÇN´‹icUf~)uC@ľY™ąmůśÚ–čßáłş‹ř±żV¬Ě)™]¬fÖ˝€é ěá;ن”¬y4ĆwrĽóGÁ\Đn˝7^˛Mj“Ý"më§%*©ÚáÜŹíiĚÍÂ|ĘŻˇ«Ó¶î\Ě™;ŚoŃć:Ř>Γş¦ý½a8GD۶J`eĂYâL[”ë~l&…ńüß)ëËéöíáCdp7†Z·G?t+pOöÎ9AŐç ł u,ŕ˛NÉ*:›ňĎą,–}3ŰŻĐËkcźňĚŘhćěđĐôÓű§y2ľ˙ÍÜí$oľ+QZÇ~ h‹ÜË8éâF9oŚ÷J;Ŕú¤Őíô­oŠÜ'}ůŠ?B¦¶¶ÎúÖ ĽeŰsŁÓZ˘łD¦'Y?=®Ą9ţ;lYŃGĂNąřY=˛·ËŞ縀Ç ­IŮeyşňňťÚb††Rý9¶tý§Ô9Ć5öłľ©vÇz~íčŞĹ96ó8ćulźęÓKůA`=›§GĽK:KK˝ÁcÓꊙˇ‡»ňRFޱÜÄă…rŻôěáq.đŹÂóµë‹şP×čFćbćKřÍ–řëlâxÇ´ďÎ&ÚMáŘXŰ\l囥Ć:ÚцŠ0"dn\}dŚśl©tţ'Ţw6q-†ľ×ţ´Ů—eč’/ ͤ[ýjĐO ¶ ·űO)o=Ď˝ugdü%™ öŢßz¨™(é&80Á Lp`‚ŕŔ&80Á Ś%ţűNJ꣆y7~`}~_E_’uó–~ůf?¦­Ť?k—·-|:ö‹űćyĎůďu̇ٹ.ĹôE¬ű'`PŻ›;[Î]ÎĹgvD\ôĹđĂÝ'€=ĽęZĂo׾7ýF푱'°Oá˛ĆČő¶‚Ż'h2{ʤ‚>řô©ŕýá_źąEŇ>rž=擸!…k‹€9Ť;Ę9>ÎíŇŹ†> şÇ˘?=CćÉů!c©$ů·¶üźŤ˙™i§śĎÜÝY|x7±ť]bičG±ş" Z&Ëü'×lČ#~Çy\úký‰LůŁ÷n/ëÜë~Án<űA‰!ęÖΑkÍźä:i‡˙ÄŇĚŔ<ö<ÁjŔľĚôSvt}–ëÓ¬WÖŻÎg«Ď¬?ý}Ě WH h$˛]ó˙Â#ěł(<4~¬ďn}ŻŔš,}té{=oxŞČ˘“č¶ëm^˙orŚkޤ—k|ĆkŢOőěmçŔş^‚źëp! ;ß7żlײ +…yb~5Ţ?`˛`}Is%<ÇţLB/ý'”Ę2ç¸Ů†éSfc5°ţ¦ďđČ?ňPÓäűČ–´Ţ›CüĂ8˙ÔŚëgQÇÄfz‹ŕË=^č‹Yfł7(ăë(ßÄ~0üˇŚ,®óô%O VÜŽő»†ßÁ^!¶Ţă'ĂgľÁę3ú§x6~2νu¸wiäú2|ÓĺűĂ·ó›‹XŔţˇ!ÄĘŠţeŰ%MĆGĐĐ©ëOŚÓ˘|«żąň {V[zyonx;ćuŔ9žú/š±/;d”{ĘĂżSd¸;˙˘§¦ÔşVLÝÄ5féSEąeRÖcľˇÂšśéźU÷ß‚~ŁôúYűK»Ćn0Ä+Ť[›¦žĺ^̆2ăuî—úä=î żc[ΨSiăđőŕČűô©'/XĎ”ő9ŕ{ě«áWjÓß™Kř"÷—Ů}Ý5ͱ:Ň×0Ő3«Řo‹^ѵeěK[¨óßŔLós%ecÖ:§ăŰ$i‡żb˙ŽŔ~~BŻúŔt}~)ĎX޲żOőśç >öŔ­¶F“ö'±Wxw~ěM´üv°zTu.lĘ:_îÓ¶^4oęiÖ%âµáÝj÷4Ăó¦b6űEb˙[ę(±Qřýě蕢łb>ëĐqëî–f>çoZęyG×ęÍÝŃűż šă‡`Ź–_ ^î’x>ŘôĆ÷qę~cÖźëŽô#X’Ľ\öNôŽqc.×aY÷ôµŕš5ŰĺĽ2câW'4A?Š-p-¤^á—c÷1•"3ŁG­I)Ý~öćMbŹqł0ëoUŐÁŐş§ăd/ţ„ńĹĄ\Ƥh?“>`× ®đ[.|©€Eô yŹűÎ!ĆSü{˝>CĚ1±"WËÚ/’#ű;Ęĺ„1©a©m Ówaô~ŠĺPťÚeĽ©ŽL=vu›ČZeĆěM}ďěsž©S[Śec»ă»<§üß< |˘$ÚÉ"7ŞŻů~c {^I>Nâşîüĺr®m qĄR˙ćó˙[ź4:ýWĚ×/ă?ć—n˙ťäĎ-˛6ÜđżRîjěE˝Şj ü·ź‘˛UÇ„:‹uĆşf߼ ‡ľl}ÉmęýéŞŇĘ{Ô[ŔÚ?LL‹—=Oô)ikÜF˘ßě‡Íçôá`Lé#_#ýfSŹţô|ě ŰŽô-éö/ŔVÚ+PsőcŠŢ{?ĆG•ÄN†c— ‡iźµvŹUoźÄö}Ňk‹c«ëĐžÉ+Žť§€očç±—ę!B+Ë˙©ÂůŽŘ{ř\đßěńÎg(Ćç{:Üë“ףńKőĽlŰ ü§ĹćOôú¬ÝÍ4/s¦d&×EťKý3ż‹|gJů8î26ŰćT—}Żú2¶‚sHˇÄl‘žs~(WŘ?8_‘ (Nâ¨-Oˇ WđbßułU7&ţ¦¬óŮŁyS饿^<»LdYűáőĄĎ^śTv»”iEóÝđÍżÁ¶7¶cőÍôÖq_˛\č¤NŮć>ńŞżÇ,ϨźĽyĆO7mg¸a•ĉGžÝs)ź‡:źíOůéýîťžŁżŔXîÁ…Ů3BěgkA|')CećV9"N°}bßWŘú…Fy]‘ Đ.ýiQýöחĽ0„x$—~ş¦<ťMsĂ1ÁŇňĆ<˘ ŁŤî†~mgô;ˇÎŻŞÎޢNJ0;†Zć$‰{řË&bübś€řĚď‹|µfl˝)Ď`{Iž1źŻnfüűśuĘ1&mJöÓ¬gÖ#ďý˙ĚXĂŚŤ:›Šc-ě]‡oÉcęzćĹ1¨ć9ňčOźP LáöĽ—2 ×Q˙É‘ďoüőőč3~ÝňY©_®[ň¶'ĆSź‚Śí_¨3“2Ű9Ëoę×ĐxF!^ëĽ%şÚÖ3éÇ^±:ó„ÂďŢÁÉĐ™ă¸,uĐk"×s†_ř˝ą›dyŽŘŇ đŻÄĎzci¤?Ë<'˛·‹řÚUUoÖúwřXAošÔ0Ć­€ç WöéKíúrWôďG`{bĺJÇĄlowŔč9ňŢčŃË’đWä][ř$Ś™/“|VbócĐ×÷V`ĚcŢ5˙»óaۧëý–¨Ů:Śi*Ž&ÇÄÇSÝĆ6Ío"‘g×’eŽSTGs3ď÷ČD±śšç¦MZÄ©ZRŔůd™˙,c6îRÔ]šG¦ŮôźQç‡aŢ?řŻ5kPľĘŃ×LĎĚQOaŚhůC –뱦Ҟ‰•Šy(`}~QÚ«¶‹%É!^ÇĚÇjľŁ}ôbIi™™G_ňG–×]?Łqu…ÁHŰ/µ—Ř.Ťń‚č× ňjhV;‚iܬ&ęvŕ‡ˇÝ›n_áCÔŮ :íRů붇OšŽŤ’“ě1&{bůŻ™l=€kĐÁ“#ĎZ]ˇíVcŢá»âᣦ2zǡÖ0qŐ ujhf:ükdŽpfü‡hë÷Iy»/xľ†ócjcţ®| ° 뺍¶ŰÜť č㏶‡™g[qm˝ĐHüV`yXz‡ž?uoň5GC›xsŁGeiJŔ״щáu‡”ÁÔ0H`3ň~dha`ÍšKE¦{ĎF,řAVöKÇ,?ç,źĚ ŻďoVě·5Ŕ§z‡Zgş‘mË:wĆďÇúwؤD˙xóacćůnwÇËgX»©Η­#Ţ Ç¸ĎĂ-uŰ&ő/ćB…OćΗ$ëk€i+ß‘?ÜBű§|Ĺ…Ŕ>Přžč'ťáÓËß_oś+ucúXŮ÷ňwś»˘ů«ŔăH`}§ýéß1FšÄ8}éW{Źş°Ź†Ô%ńŁĐOŰş×ňžďß sŐµnbˇ™6`uęýXßŰŐ¬.b@gĘ`ˇăűńˇyŠG—q Ať9+¶HhѲóţ«®^Ń<9dö,‰]N&O´4cžÚ\Őb©Oň‹vq+|÷Ěw˝‹yłćL-K+Ö´ě÷1đŹsĹŞűśÄTwÖůHźéŻÇŠŇŇta×C—,ŕDIţĄo+ř„8“ĘŢ´´¤V·‹}nćąÍ;]u/ôÍ4ĽóôÚp­{äHŰ÷ĺŞ,/řuˇż0 Ťń]9bő ľăČ,ŁÎ«Ł0Y…9(1w„6ÖŮ…ľnYłg›$ÝĂ ·H{Ć:´ť/y¸ëBËϮϋ¬ä ŘTĚO×6Gć=úם˛żÓ˝żg·öo@YţâbýţǰM7ÝWÄţ†˙ÚŇOk9śÄiNW~‹%ŻĺF?¶^¦ßę1WŐĺ̉ě!¸őzo쏦Źčşvى¶.ćÂAuËĐ;ht-Ď/ňŐCO^ôÜËĐŰěŻH/}Ä‚‰¤AĚ~ľK_Jědĺ¤-\ô™mÖö_p đÍřôU,“ůu6U§ Á‡Éö7Ľ˙]řpěŹńĄ”ŮIě˙©Ýčkd5íTyfđ80~˛iśX°­ÓÜ—» űNÔÁâm«ʶ/žŹßĎ”›ómáü·‚˙‰IŮY×XŻp§˘_őĺľX}xę'Šż‚‘býpÎNËĚ5A¬}†č“Ŕ{w%_µt&úwv’ŕ'}U"‘*wUôŰń:ć v¦®rn9~ú)Áň@H0*ýsQG·blôűš®sdťk˘\ż’őś~‘íyÎMÁ©éË„^®µ)ęëićäČŻ"Ďôťń;2o/f }ZoÇ8ů@‘ăő•Cç†ŘżRocź9Ě'Ě€Ň5¶/‚®^LaŤ±čŰź«:LÖ‚Ö—îřÝďlJ&ˡ›ž џ؜ŔYźeëh]ĺPű‚cIžűw¨qÜDS“évŕ‹\—µż}7ëwíŇPŢh/ńIě‰ÜÇ@ĆĽĆś‚C™†ö6ëuf„ú48®“őš˝ŮT/qĄcl#Ç[­¤Şř{ő•ůŇŢHżÚR¬KbE˛^[ëgř5Č…Áˇńĺît3Ťď›yÁ-›Ć"µ:# 毨ĂĘĘ8‡Ďń"y2vŘĘ*×Äł Lp`‚ŕŔ&80Á Lp`‚Ř9 ăiKn‰e­2qžó^\—öÎyß„±˛ˇß›“ŽŻ9§ňS‰ ô>ÝňĎŮÎĘÜ˝·¬Q§óBo87Ŕą?®Y9‰ŹÔ]ň¦2SÉ5V`Ź×Č\ÖćlŽ7ť-í\çĂX®p쇬kČş|Ě1Żgöi6óÂf^Čř¦Ę<ĚŁĹł_v8'ß˙ 3éIˇ} «:Äý_¶4Z)«śłĄ ż/ůQÔ׉v>Ţ[^ř©Ö, –ëśóCś˙3óF÷Ůů^xPÉ»ęüÚ«g oĽé˝;睲Ż*ićşéČ2´D±ëđ[—şK·_&űÔsýÝÄSu˙Ô°+ć˛?.ô2ÎfAެŃci±mwKX‘ąĂ‘yŚď5öOxućş|yßžśďĽPű]ěń˘kóŤńźČţ ©žíĄťsmŽrÍv<ÜđQě‡}¬ťżČw‚¬w˙Č"5Ă.‚ż\źcöî*ŢĎłoüBöYű Öă°ľ.ô .Ć®©˛î×U&ĆÉ96OŁ,ů°Č1bÉkékďý1m’¦Y (+cLĄ÷ůxť‡cW–čfťË~«âG–ćňśYcUp-uçňőšÇvěE™i>^d»íűçzŇî¬ÍÝů—şÍűř°7ýgµź"MÔő…8е ̵ÄoŰ6ž8|qęsI|‡»B^ꔵŐŚ» ţ>żGű}Kę“qęÝůS¤NWŘ$i—đµ÷Č'|ŕχ˘ťlô×ćžr¤»/ą›ř´7<Ź=WOBüí•đYo„ßŰrŰNHFef‘ě3P$Iúöâĺśu–`A!4p@Á·Oł#.ŹękŢc[ćµ×ţ4ő ‚J9ŤDĚş3öÉ•8`éyeI“/ăÚg䦛‰Ý üË>›ň6˛ E"»ý{ÝaőIuęŠ mKÄÉ˝xö!‘OöM‡ţ‰ú^íëâQy˘ş>®ŰEđâě9ۇ/w&䡽őňŕŇvŔ~â%|ź{6â‰Áť±·+>yµę3¦}Š“ř˘řöP® ÍE©»yßĐjpYź#yĐÖä~á łçÁß7"é#ö> sKĘŔ|ŁĂăh˙fĹBRoŔ[€â1űč} úcKĐżÖúÓ¶mĎs]¨?«ç˙Ćş$fCă®°mžşśzűYÁg䥠öo}É_Ce€ň)üIlťç+ľ"ľQuŞĎFŻms/°~ÄzőbI3°4\ Ä^ż‰řäSĄĂ ?—ţ$ Ďó‡ue9'}*ŻŚ5a}Pď9‰ÇĹţä5}^YçKńš?Ţ3gĹ˙Ú˙‘Źf}ţöŹgß .kXĘR|{ÓφZ+ őô…µŇ¤ żUŔĂ«ĚÔ Ť‘Ć‹|×9ŚY!ýlĎ:ćęΗ۸#–Jďłž|ąÓ°O×tÄ Ü"Q±ě\ʇÍ-˛5еx2=:uŤřMÉĂÄËü§¦o€Ď׍V–§d‚¬ż`eŽúľBŘgő=!údňš_j}łűĎ{<×}P ›äĺZe‚ďđw$â-ÍYYYľč _‚]…¸77»X ÄÜAě1p¤>aý¬ű»>juĆ>đĎ>3ŘUŔ?byN‚p“.¶MŁăŤÝˇşJă/ĚľfĆź¸ÄáL#öńes"ĆÖ¦ź q‰kß;Ë_úÓ–·ż‰˝ÁĎ4 ¶R±|ĘźM9F"»ËižČç0†Ž´t3='ńwř99u·v ^fgŮ VóˇĎ2Ű Ç^ęËńy >2”b‡1~uŢÄvZčßEďçÇ欩ëá†xp|ĎDť•rOű -ĂĆ!kµáX‘Żü>_q,ôUo‰ßęúŇĄą)C'bsţi±zú’fţÇ|gÚ í1îKĘţťvĺ´Ô^V¬®8  +.°ňÍo‡Z Ć–7úYoއmae ~ÚrĽŚ’|˝ů±~Ř>I'Ű0ë’:VÇŤ¤‹ç°Ĺ]bĐż•ďa?·&b…˛˙âx„v‡ÖW_2˘Ź8÷Ďnxźôž†{źgł‡0ˡú˘¨˝Ą{gç˝?Îż×ě‡Ř'ˇv‡çh*ŠeÇkŕŮIť¬ŞzPd’r\ŕ…̨L›ş06 ešĽnřôUŘ«ířv+ÓoU”‡Úű•Ô{ę7aŕ’Ě”˛´ě8×¶m- yĚ~BŻ7ćx€gĎݨ‘ürU~čëAôĎÇ›Ţ đkg%ôbM)KĎŕ%…q•ˇŤď'ú%´ nEčcűf¶0Ű+÷ŁcéëÚ{sFoKţ1ß+Ŕ¸Yä _íąţß QPo·ßÂ\ńPë>%ýˇ·ś:?¶>&ľ)ůŔîgĚÔZőL9| ú}Hˇl9ŕZÍAŮo¤ÎÇ=Á:´éńýTĚ Wô|Vâ-W‡żÇÖ-ŻŰ%<Äśš‡¶GšŃ’üI'ÓďłçŰĎIl1ÓرKőýo öłüˇä ĚŇ’<őôĹî ů†c'Řü‹c ęśm$ îáÎď~|¦vżÁ‹#_ţ‰ňω<‹řŚëŕ'űu©o`ĎA®¦ą ň3Ełş1(˘?aŹ‚˙s`„Ď¸Ô Ól‚} \ŇçőĆü=–iľe|]đ•á“,tLM?…¸Ż +đĽčĘĚ!đŐżu¶BčŃ<¨{Ťî*ÚFńl™ĐQ™ůşĽ‹¶/ü‹źţ’ě×Î~ť´Sh:Ţ#ěÄżop=¦·D?V;Üđ+ě=›ń0ŻąÜU]běRď—ďě\±:üßBĚút)ăěčÇAoŃĆ×”âŮŢľb?Őz#ë;<khbH„Nŕ…Á^÷—ČLúŤGÂ;½&Őçźi€>ÔőÔ+íSʶ¶eř:[{ťďnüOëç©›u}‰,]gżŰ ľö'„VUŐaĚÓSňđě5öDžŽjoÚńěń°YOFŮw ĺ+>‡ŁÁ»*ě± ^ľ/Řă6¦Ť¶ŞiGŢÔ6öÜěĂÍŻŇí§Řöé$εuęË]‡z?›±7uQÇÄ8Cľě»ńěn%ňî-ÇhC­É’z®N5ŰëTĎUˇčą`>ż8nÇ^ŇăžL‹÷H=P–Řż#–Á%Ţć3m}mĂ›˙†Îˇw­~đľ—«:6î÷,MNâ›RŢÖđľBsď ‰ŹCśw]c\ÇýKäťUUżréÚíđ`žýLę Ř$¶ţąŻ´“08Ěíxt×””cu…ÁHÓ2őÎÁüÂďŐôýúdăŽs® (<%ďú’_ ĺŞl=·Lč#ß“iŹgź“rő%+±6q¶< Ço“_ ipžI§™qł'ć„Q§{ÁRWł8<ÇX\ŢÉU•…Ř~) K,śD;bĆ §±yřŐ¦˙8v16݇]b«ř±ď¦|$çöîVćDďÝMʧĎJŹĆ!m=2ٶ%pŔlŮůMećR} bŠwÄßËö1¤ĚşŤŮ—TÓ×±š^ŹÍ#ĺÄ—{8e;8  G}Éy.ÔcđąćŁ1ćkmüe+,⣄ě›Ńôĺ>)ş™61č˛m_ˬs•®ÁŢXł~90ÔjćŹÍçűŹ’x©i)ěŹ0h°t}ąi˛N±®4˛ ˙ ¬Äűű`~ŘŚ+µ_`¬tѦĐoýéO ďămˇĎŕłP6ĚüÁňźŤh”zí—W˝ůz[s71ką*Ř&­ě{j{ę§Xîxv*ÖUZĺľWoö ~ýđ+÷ľs®‘}îYϤÁź6c’bnćŚYQÇŘäS2§×ˇ? ¬‹.đŽ›ĐľKxj`UŐ)®b ŹLkS®wúŚŮŻ˝2óIÚ_…ölčíđ˙ęˇ;.žíÄÔč/eÖŁÎ=µs"» _[%eć™c‹l±AY¦ň\7âđ®NîËÁ|Ĺ-™«îwÍŃštűžěDćŰ)s JK®jß]TҦôŮća;Ř4‹sŐ&Ĺ©évŰgi•™~`Ŕ5Ě€í5Kű>sÄżpťÄ™2çM]8AˇŤ¶zwţ6âz?/ň-’ôZ˘ďĹ<âíu°Ýj€űâÍCčî=ľËÚ]­Ř3[ó­c®jG›ľŃk\»úmó¶ś'ŔŘŔĘďÔô¤š¶pßt¬_ÍŔ^ÖÓ´ ÷Â8ád™?*¬k”ń[>ď«ém~űŚý}jĽ}„¦ujY“gKXC`Ö<ĺßXß˝Ł‘eęjćgÖŤśqíŃIě"uZ1®ÝÝögŔÔ“ó)™ĺ˝PŔ^č´x¶(c­ÎI°ĽŔ*1÷d°Ý#kYĘ󑾣G«7%C#÷mh†<ň çů8—Ă?ÎăĄzŠë´°Y¤ěđ’~ÖIDD´źőö­śGEüˇĺ•ćjƧ˭Ü*Ď ˝¦ôݱ:’F¦í7ÝŠą>Ž…8‡Éy÷ęÔş×µL,/űµKôľ«SçŠę"&ŢŚ±°/ćRČ+Îťń=ňľIžö¦_ŹÝ‘uur’'Öl[^_ŽáŘź¤Q×_µëűŔXĂšÔ©3šâŮč˝e»O‘ôM"2•ݏDć|†Z †éęŠ÷˛>mç6ô»±8.Č˙Ct(çf™>âžë€Ulő*üi0&Xhő‘–t7´×QđŇČ`ŔŮďô˝ď4ÔónR׍ńűĺą“0ë_đ?ţbť8qg»ű{ćíôűŃ<ţä^㿦ięÚáęŠË1Żđ(|`öĆř°BĘ4ĐuptËA÷\;^ŇďhC’^Ó6ÍÝTôŘßóm}ý(ćwž­Ž–o±6µ–q\9~©Mw,Ž×]ý¦ô+°KJĘ@yĹ^ŔĹ,]ł>bŢü#‘m%Ćť÷PV—óśK{ę‹÷"‘ąĚቾËU]‡ľřŃyÄÜăsţ€;.ić+ćŚ9ť&Gó_ń•Ŕ_)ËPë÷©“nn»\c×!`†ĽsB^_5öOútqŕ[Ŕ@őľËg7'ň€őU[ŻS?Ófĺ¸MÇšÖ»{$ß1öÝŇ’s—öµ™ł,+ăÇćŤNěß”VIضâµđiÄÚIȬϴÇWG—ŇđźŻ:eśHŮĺü;ęGřˇećn& úíábOAˇ“{°c_ŔřI˝»ňűźéÜĐÜφsĹý¸ĚÚ6yĂxŚăB¤]ů ĽŮPŠ[˙3•Ý­ź’ &80Á Lp`‚ŕŔ&80Á Ś>:›č‡PšîÖ<..Ądä•wŚ|Ž9™(ú(čW&& ó2ß…8śĐXÄ}jnŁ4ő5ńPw~íý™ßyŔŁç:ťćMĚŽ~Vć †°ŻÖ( s|cK–‹bٰ¨Ă}L•&=fnq^ĆÜH×ĺ€>Śű6ó{ďßß;oꬅ•çŃ>ĽšŢ»yěKľęć·á?$rśm¸Ä®_Ä|űĂĎőé`¶!ZÖ^WĎz41…ő‚mę™V?H٧ÎĐq_đ™ÖĎŔOěIřuśˇÖĎŚ‘oЦqNă9ŁŘW“)p˙Íxö<;OŹýé°ľüfI˝óÓ®ËÄW~ÁđUxk÷ĆWŰË~á_—4™.ý†&Íxw0ĺ™?:;2žÓJ‹3ćWSi]Ů ?’v<ő(łž=%|gępľ[żáŢ™đ j»`LŠ>{«bŮŮŮŠÔ{w~ˇ{çBŚ=ßĎľLq"ĘsßÂRöÍĽ™>ňR^-ż–ÝIĽ.ýmujř<*®5sVqKŕ+ tAŘöŹővÜŰQú+Ä©Řux¦Ű?Hňr‡Űv ůŤő‘q^şĎ$óęÎFĘrž/©ăëwůâ°/‚oIhjú ÇřŃŻCŐáośą ű/ÖőżąáťŔ×ĘšnîÎÓ¸ç‹óNüŃF‹~µ­Ôo˛Ýbđ84ŹČłç[Ő{Ő©íBq-f]‡ńŕÜźŤm“kp}É'×YgsĂeB˙’ä«đ%ŞA,Ë,g°u±çݢM yŤö‘z'Ó|»Čü|=y—ćĵeŇĂ»XźŞM·&ď’>Ňjl+–xqgY=uÚŕcb|ňŃż ˝đ3±~8ĄąčŐXŇm°Âč«ÉuCͱ1^ôać=•ÉY±cl}ÓßĆÄL:˝4ó\Ű6dű-ľ%qđűĆ~…‡Â'ĺŰž{míęCţŤô%×rmî‘m±Ź¤UăŞMš˝–.^CŻHlŚŮďad®†^Ę@˘˙¶‚nŰK⡫µř?#>ę_’ŢPaŹ®üň6ěkebŠ*3ŹX7Ői0ßyc{®Ś,ĹF\KŚ2ßGě^‰LűÓKmY[)ň¨í^ÓÇ^ ˛ĎzQ!¶iößQç~Ę6üßot±Obş·Çů!můŠklýjšz„?YďŁ+ă™ćŁaoôÁďău8_Bó„Ť%ôÂ/ĘúĘš# >Ôçżz¶ Ę ë™ňlÚ€)'ý(?łbŹ =w[١Ľ0Ö5ž]fůŞ´ň8Ü´÷GňŮűަśsß[~G[suĹ2ěk?ńóŹr‰Đ˙pW~zĚ×'x9Ká›§y¸Ř—´xéÓg<ŮÎ&ňŁ%z6ü3."€qŻÝ®î# ©˙ňÜB}çîęź\SžŰţ‹pŻSb$Ůç›~Лæťc_oŘú3ż¸‹ĐâŐ_Ë[O„ď޵3† Îě(‹y¸˛aĽ«8T¬[Ć$Co”Ž!WAO¨źČpĂ•őţgŕËxĆ'oŘč/×—,·őN ŕVŮăKÂkĘ>ÓăţĎî@×ŮVľ6ŤZĘÝŁŘë~ŕ9&ůÂW« ×Ëueć!ÄĘ\aő*óÖŘô§ÖŢ6ňĚRY^ ßÄV††®Á ĺ4u-üh51Z úëy+3#i nPžľŤ|cÓ®cľ•.ýŢôkĆLŔ7]ô Ę:}uĹ‹5ϩŞĹóŰl|ëQżK·˙\âlŘŢŕ ,˘[Ąž ýÜß­Gb KíÖ?B®^™f?¦ŘZÍţ×lÓŹ÷R=_ăž_ëĺßůOż¨łüŇŠŘÍ_ŻţD‘č*–‘¶ ŰńŠćeÁĄS?“fě ,©ł$Fm„oËŕëŹsގů‡ţnßPˇż–4xŻß3Ί:Ä÷W×ůÓWs?w«Ăřžţ67~t—í¶@ęmŃž—Ą{¸a?›'°vĄ-ÍVgeĆŕÜyűrîĺDY¤ľbS6µ®Í=©;Ű'LÉÜ%ő¬txʙ㓠_‘ĽaĂŰ2đť• {®÷;oë:?0:üýĄrrük–^~Ó>0đ~Äí’ŻŘo=;I臔c¸á6ÄAw¸Şź•Fď‘smá×€“–Ç>ŞOŔ~żWú=`FÔµű{°'ßű-–‡–ł-|:pRz1§r}VlŞĐĆ=oéâŢd~rNC\čŤ8>`ˡtçy©ĎôŹţ°o_ĺ+ŔsÝSôŁ?ý%Äu?_¨ĂN©»żńg9¨/©ŰŮFz_ ©ż,ô™«ĐňnĚĺö”Ů|™«š,ĺ/K°°gž”u¤Ý©ńc¤ŻwđŮ’ľ$Óü&ĺHúUęl-bßëč¬1ÂQ(Đ®oŹ˝~Šą–âÝÍ;ż1ĆŻ?ł´#ŢQdý ęú`9_’<ý™ÁűŚg§K{`=Nö]śËîŢŐěU^bOü6Äý@!/’.mb.ń}mŰŔ´Ý;Ák(ˇc%ă,Îhě8|ˇ{ć f™űnÚý2Ć9×C?€8݇oţ}ě‰űś”×ŔEYműfćĐ5ńo#sël VżyĘvtÝňÖ6`•~^Ę„6,i µţĽ§[Ýóůěyęóěą7ÝTĎëËCŢňŹm6Ś÷ťÍ9ź‡=ËW°Šv‰‰ĺD_$zŤóDĚc¨Ő`7đĽ2ó7Ěg÷zĺ˝xöV+3˙ĎŢ›ŔÇU•ďăS(Ë´¬I‘i)ĄŮ3sg–°¦*KR¬Â €ß¤ČTţ, ČT Ę2-LŘ;“˛O± “"ŰPLŠlSQ$)› ‹ŔEĺ˙<ď™sî˝IÁ6M úËý|’{ç.çś÷,ďyĎ{Ţ÷yµŚťGä{ŕÍąř#ßĺOIWý"~ŮŤŇ·ĂůóřLÁüéě-’şI·/ 龢żYŰóI߇-ć!J'ĹozÚ2nZ| €˙ľ5l©_G»O¦×–(÷ń¦ĽµU=)Ű ¶C`A˙—Ąaw/ĺtćťJ´k?ŕT6Fź24Bżč¸ßöÇĐXűÎtx=93ÇÔŁ^Ă }gm狎äş]Ňă¸$źéîzAĘJ<<¦c%WK],éę2~ÎCÓoŚáúy]üř+(Ě!}Ď— U!N´Đ~`<˙Ť©OŕřhkĂó6řěM^áUŔąĽ~îËP˙6—No¤g®´ţiLD¬Ţ~Äź§Ś¦ů4¦(ř]SLíXÉX·|ţ­XTUÂoßUŹbŽ]ÂĂ;öR¸$XĘ;i Ť“3‡®/B\ŕcĹÇ”|ŽiÓ@űó7çsž9ßóĽ>G|ÓÉâ##ňcűϱć+↶±vÎ1Có Çú…vřTŻO ôx9Ů«âZ•“3Đď?‚ýĘ1/O~Bšm˝żőCƵJUőëŽü©Á ą—ŚM„7÷üž[ yŃČ ŔÉ+ZĆôP}Ôý<É|g?yąz ¤»‡ß›[ę/K˝V3Ş ©Äłč˙J.˛ż­+=ż¨ĽXÇj.¤Nk WźjĎo‚ř Ăĺ2Ä6‚Îđ—éŐă…Ą›”­ľŻ`őx<łŞ€/gä`BČsřúąNVëăB˝cŢ"FĄăŁE«3MŻ}Źş,ČĐüHôĚŔ Ś3ęË{Úß6ň†öŐe.č˝ěÄ WÍámĄ˝ďÝEú<ńz–Cî(ÎưŹmaM¦ËˇĎĂ’ĹĚCÉ4Ç”:(#P^ŕ4´ĎfZN¶ŁŤuL˝†.łÂ*Ń©Pö5čó˙U‰dę‰íĘő7ü©![ß*őÉţ \É˙ŕÍ0e˛S˝+âsYď=‚=ŕcŕÇú+Č>7@FŘUółŢ§N>W0|xqúy¶"~ŇL[÷ xňŚr)t<ć]jŽęˇ'˛=ő¦ÁäĎ,_ć¬-ţč‡îÁ5'ęďFë¶Aë˘ xFˇćĚč5öá»ű©”úŰ ŕ| ÝÉôVŘ'ßrLSĹ5˙|Ď„ô[µ¶®,zł XźF¦éČ—aŹđ~jďM«:ňGĎç{U“3‘ô±ć†\:ő3Ë3´|ëţ›öłM[ýľ#±Đ7Xô¤)s]üi_ú¬k| ŇLťç,ňü¦p·ŚŮ4útĄ}MßB['+°×cŇa^©DÇđm{ČyůŇë8‡–˙Ó~Ł˙BöRö|g°hĽôMě™Ce×ĘÓ}żŢ“mřŽáa°O0ŇČ˝;Ę­ÄÓ1±‰uÓUŔ“Ľ±ă*ŕ˙Ż‚m}uo“Ôá5…sqö.iÓ…ý/c˝ł3đp®¶4~ô§•w4îSNĆXQęaŢ–ÓmŚî+ý ®¨˝:âG]mTČ[Öbś_٧uyŁ1igŕVb,TůëLßÁHs;´ëfŘÓą®śöK?Ł^—eŃilčóŚX™ł?ůW´(ěa`‹`˙čđčͨ¶}ŘC\$}›mË~Ěąö-ěµS†‰÷oěÜŽx2ö‰L~âuŇW†Ć°aaŞľ6† f—‹6äöŻáWXI›ó ě8Ąüę­ąˇH¤$ÄvNd Ęd¤Ď±-őś"`"ž#ăĎęâ›sOXŇĽ żňńol™PĄ˝a˙ď ýKcô5Ř>~1RćZ|·xg[=py1Ö>64ű2ß:X˘Ć¨ÚłË´(;Pg)çXż2߬j°c^°~”ĽJ|óÄůÝĆ˝n«×<vćŕcŞŢÁ˰gt%ő2F±–6sIQ¶AčǶHŤZgxJ2=Khçxć~,Úά °–d *čî4}‚ą„?®,Čť ă‚zöŃÄ!vR˛nפUýqţá·N;GÝžĽNKńZý 画#ݰí˝ Ź‡|ĽĽ0vůÍńĐ´čł»ŚÍá‰ŇÖĘnNŃ@ÝŰ^ż©m\_>ąćtô»_ĽłŠu »Őŕ>ń…`ŢĆúd^~BPc˛h›‹Tb?ŘîlŃ^AńpU_<šÖĄDş˝ôY«;ĎúŮŘy¬Ćj`¬Ćj`¬Ćj`¬Ćj`¬Ćj`¬ţ_ŻĄŰ;"A<ľůÁ¦đÇýmfF¸ôśîZâúężńPëfŘąÁď_ů¸b/ú˘ç ŻÜö(çYZ_dS×VO{ čBĐŹ‡X?ZżfżóżҶdaÚrŘŁNŠ~‹>°/3zÍŽüJ‰÷5±-¨;˘ u'ů)ÁDÁ!W2±ď. ćˇGřbR«bvcŻ2 EoG=|•ಝˇ•˙Śe]żĽCݶ+éČď[RĆď\XŸoú>éubÖ|čg5F·«É©Ř(î2«W×ްç.űN܇Č6xGŁ6űçnź}¸ôÍÇî"Łn?ź¦_ĂŹîi©/Ú-¨tżă}x¶Ď~,ĺ‹y2í묇Ř÷ŇGHÚ™¶˝¨ëšŢk]ű…+ß".’ś‰5ß}űÍ}FŹîLó󸆟•ŕĹ뼧Ąv4{’EvÜŘ&¶Ěm&ôj…řľRGţäţ˛ÇŁcنcef/^§Űžż~¶Jź¬ďmĚóŰ9…Łý„ťyG-/â?˙´¤ ô)?âx˙ Cuŕ%Í6Ż^Đż1F*aß>QÚű˛ŘŰTńłűŘôĆ>wꉝynřkesh%— °G?PćK_YžŃ?Ířäo—ÚŠNČ•H]ŔÖMδ]‡że“ňcQo«˙đ«^ ď-J˙vۇ׼şúÄŤ8—«ŘąŘ{7mXFčŁ[— ±R\4O5>řú ŹçČ}Ř?‚-NlÝľjy {]ĂŹYŮđŇÇ‚oĂ7 ˘8»»cÓNcc\©}řŞbďˇŐ7H.ţçËĽ‹ýö+aÓ-lűĎşiďG=˙đŰ}âýآľTęHď;ęňOČkę3ÓňU“¶~nź‡óPűŮh]µŐż]ňlĐórY°#ß˝‡}MŮC¦enđK¤m†ć¸ŘĨ(ři»ă’Şý ű‹Ą‰ýj­fß±Żŕw"őD^ćÜ łßÝ+ÝĆŔ‚-OŤyű^Ň™–ĆJđäŇ} PÎ\3„2÷ŰT˝Ü›üOřPµg «?ŕ’‰_Hw×+f9óÍkÚ*vöz ĺÇľ:ä…W¬ĹéZ黑ȡ•Ř7ó}b’éGý[gź‚íĎLŘş´Jů$űŁúă~l¦Ą'n…?âŃěPŘ‚˙(ÄŘ0Kż†ÍY˝«ocoÓő»Ő·cč?ŐÝČęAŤ›ÎŢ×![*yb¨Ź0î#~ć“RžĄ e+8˛p _†–»%ö‘ňiTşÎŐäeşŹOČÝ_ëUŐŚĺ>P{lq¶ŻT¶ÓóňĂ˙j¦řßg˝®˛Ťó´YŁĹËR‰rkoŘëKÁ‚]/0&'ćˇ2$ěow„ ŰÇUľŚÂą´’7Ť´ď$ÍŻé͛Ŭť• 7 O}X —°O™wY·ä=Żb<¬+­CßO·©Ŕ ·sŃŁßëi·×ϼǸXkš$~ä-ć›Tâ"¬Aż%őŽ)Lu+ąMľ’>tĐ‹ű1?O¬†ď űj%tü•Đ–gZ–•;ý)óEŤżăŔKi<#57žźŹăÖ°g Kşög®' ‡7ő9)»…ˇ#Ţ;|Ô Ď-«×¶tiBĹŞÖ©Ł\Ň÷ñąÝ6AiëŞ0¨ô;ŔĽwřö±oÜř™ĽOĽ2žť±ř»·é9n§c=éSÎ/>űÚ—ů;Ň[„>twó-x±Đ şŕëň/CóĚčrÄüÜÓĹłŕ\ő÷˘c «|ShékÚKú&|¤ ´)¬Pk×}‘’á:°“¬óŞs«§W®lš‡Ř9—>L—zFě ą?Óč¸Ö|Cżąögú<;߶λŃÁ_śOěk` ň5F­}-Ö€8Ć<íÖ˙ŚúR2vÇYó ¶\çýŔbů†ńðS¤ß~‹ńëH%~ »Ńmá/z'ęą>ĺAKŃ©ľ€_âÔ*źJgër ]´çańţjíHvř|:g­”g\'LČM öő7üĂBÝ·`<¦Ťx§ĐµĄśëâ_Cµ…7÷‘)řŁ} tŮ~:şŚŔ0‘ôV´ô í ¶ęüVĐŤK˙!ďŇëyŕŐxŹ~kÝÎËŰϒﵾ ulúS˘®™ţ/ĹŮ @âŁŐŔ„˙ňŁK_6mĂ÷JS‹e,fŢű?ů^áY«˛Ă>Ń’?•ͱ~3=Ó2i´›± ť |Č=2v(g’żő˝őe&ĆÚ"đŚť×‹f–—y´úVŃ—ÜAŻj'΋|'™~Ůđ Tâ#SŢplűJć7ßU‡úž×ŰgWÉ·•©§C—oú·Ö‹đťdz“ľŠ™˝&L´6©řŮţÇ1Č4?ë^ú_Ľô†ćEçő|󞼆żůS§lô «ďЬř¨¨Rúč+ËŢ »äť·‰!˘Úz}ř ć¤^t\pÄČ5|!ňěqćZ§Íö¦üßYřgüĹĹ?ő;ŁqĆÚ]hFśk©GĄăž2鿲÷O•ěź™–ţ2o.bĘ\śý–?·t<úžjgČ‹X jęrEËw…öŇÔ=Ŕ&[P~`Ěć_đ󨂞Qú0űÇŐ‚~bT\Śy„kî>ôë+–ŞËá%[÷;ŔŠ•ü4& ÓćZUŻ;ś)ždmoú"ď7‡/ş˝9ĄWř䓟J;÷Ü’4ý8Ű`â¦oó»ÎŢ·1ÖgHť.ňŰŽ_Ń4)×Q‘ť<śßŹĆqÍ»ýÖ\ď˙ >+ýM€Ç eδśŹ:>żrźĂ‹á›űKđa/1ź€gűšk,cM"ý0۰9ě.ŽCśď ĄĽ,[¶a;Ěka>ö›~ˇËÜąpžÔˇćĄęľZ“YÉHđŇţs€ßń&ě7f­7˙Ňy’Ź ÔNÍőž| Á%ŐűUÝ]S CX ?ˇoV4‡«„_‡¶_/ôÓŚi»T˘ÍÚ ëŁ"wHŰEž=:K%Së¤}WŢŐţĆŔL>‰¬–z¨ý9ń٤Ţ4¶"×g@Ç­Ë:zg5ţě~¬t¶ÔÁ5Fżv—”c öW»2˙Tâ×=˝ÎÇn]üë›Á- }~Íĺ](2 ôn𽜇qű~P÷o¦Ĺ=0ĄW]ó×ëwWŃ­ůĎŬվ¦ĂL-Mť$4Ćű7™63úδˇyÎËŻüM–[Żů0J{BÇ$:ÔdúLé/=_ýJ°†$˝ľ¦ˇëߪ0¶_²ˣtj|Íoý~Űyčü8W˛ÜľĚĐYí)tT¤üÚ×”Wgo+TĂÓŁhą‰ďAźbx^_SÜ%«:Ó70P®?€zS­×eQgçŰŁumÓMZ)wržL%Ţ…ţ÷V¬kź7í]ߪ6S»Ą‡—Ă[Úńqŕ×íÄ⺏őuo"Šą˙Ć@çÝó…f+yŢţőn9úÖĄ*ĚL®ÇÝtę2ŤŤCÓQöä1ďqÂł©ßČ6ĚF €˝±öUń¦`÷VíÍĺ .*ë?[č­‹«8(Đ+ öŽNy1ÖkXűC7Ńç_ĐŻpškÄŐÖĹYµż™úJ™ßYßJ7˛ái.ě›9úoÁ0|rMth21}˝ĄÁËúo—ç«kEoVż&<®âě.¦ź0­Tâ5ÉX°Íšoř4űů “N2ĺŃe­3řv=÷‡¸žÇކNâ<á)zŢ ^xŐđáýHhÍ´l/4ĚyCŔx•wUYŘ6ęĚ;^i~V¸Ť}ŞýĄŢ°…ŢŻ]tŮÄ‹Äoę…íĚĽ‰ŹŁżí3Űůč=`\IyŁÖ=r†L.ĺ>§ÔJţBčfbŢżC.Ţóřf"Ďpńţý OçýËú—‰ co .°˛L]bďľl®WɬĐq ÍŔ.]»¦+_F\–ýËjoóť~¶!Δ…ćX-fľčěťbh…N¶˛ďßËsľiögŽ;Ę/,ŹÂ‡Slgŕs"î€m†ŘgRWĹŮݤďgËЦĘvpe“ÂŇş=Ý.ýf˙qßÜ`<Ű®;řä÷ ĺní‘ň` K;źű8ňâtű©ŔgT¶ËÄáw¬#žgF÷–.łĂ …uď®ů ¶Ž7÷žéśĎm[O-‡lŘqě,Ů`Ńą5ť˝ß—>Uśm°)Ć6ÔăRżKÜK^SÎÔřúywOűŇWř]_“Oč>‡é3äÍú}ěsK=Ůű@Ź^–a÷[ĐÖgŃ·D覾LĎŮĐcBßs˘ô;蹀ď§öÝ'„2“ĂŞťô«ĺČ9°í-Ć>~ť|Ď~_b®5éM±¶ŤäĹľdĎËşF6Öą­ţ%”‰ąQGÔę«NđĐUĚ“>O[¬+ý+• L¦eó`ń1iŘŇÝi˝}ë/EfƧ"W ]˙Ňńd$ÖÓpŠ6n»óWíĄęÝă!.Űëĉą=­U Q`UĚ‚Ťöż±OeŻ;ň´PĺvÚťŔĆDú·ćuÜŰ Çö‰]Vjbg~žô:©·ig×ö$ú ČĐoěŚýµfT÷U١’~Ě{ě/ŻÇ´Ăă=ěâOŰéóŢëPe#‘ëş|ĹŮC!O+ŰűDaL§6Q҇9ź‘fŽmĄOpŇ©ęG§őĹtââűĘŘ]ę˝ŮĆ÷ńľÄÝ~ŇÚÝul”íźł_čt?ż3×üęĐúJýöܰĺôĂFNŮ6‡/¬‚ľ¦WüEŁ~Úę©÷V~“ú+Ź>ĐýřĺROĐ“Łĺ0yß~ëóş˘OëRřt‡]ýĄˇŻĎĄ© ôúűWys «4ý—:żŇT7b÷<6ěűw|3?1ý±­sĺtó-Óţ"ڱ˙„Â^qŻě·uwígtşŞ¬v˙@ś/˙ŞOuçvŹÉ7ť˝_B,âŁä}Ć(ăűěC´GT6ÁźµŞĚ—Ňž­ľça:°8I9áaCKĹŘÂuń3é/Đu_g0”şş~ ´MČÍŞ†żM%üÜ+[}ÇJšáX‡śťńíŐ~ŐĐÔ7üoîbĎ[úŮÝ]•»Ŕ×LĘ l Óá#űúeUÚŹ—Ą˘= ĎĐÓ†ęýy?W˛źĐčń<$퍽/iăHä/?l0J;ű!bŰÁ÷7Ţa÷IćyO˘ľ…)ˇ…{jĽL¨J`ňČ>,|ë`÷ó¬ŕÔlżčĎš{ŕĂ&4Ă~~lăäűŮáK€ÇňľÜďi~”çcÎ{ŢŕŢ0ż }¨ýŃÓáWľµ´)ĺ*on{ ~čB7üíĄ|đ‰‘çuńRöÁ˘Ľ‰ŐÇzO—·1ÚŚŠ ä]}ŹgÔCüŹA÷'ŇćúY]|ąÄ/Ôż7ÜąMb,–¤đőą>~qˇ 6Ű…>I߉5Ć|‘"‘OOĘ>eěµÍň#ŕOŘixw_Óf…tUl‘î®s…^ŘľMFŮŐąűÝhŇ®1Ť¬ä­ÂŁšÂOÁ‡RŮ70řT–"®©ŚĂkz§H{…cÓý«)íźL˙íŘ$ď弬ö¤%´ThŤZß„_Ç8ŕ4\†_[3a`úĽ-u _*Ä͸PŇa^dř$ö¬ ţźŤćŔ°/ßîľpĽL›0Ří0UkpŘzŞ=wÄo‘2Çű_Gů{`ďŢi=^Ŕm Ýن¦ÝŁÜĐÄ}{¦ŰÝU#u×ę»KŇß¶šÂ­âóTâOňŤö˙á˝Ń:¸>BüĎ@ľčbés:]IJ1´ăńcŇÎá.†MĚÍŐS2«ÍřÔ2š˛Yg”>É8Ť’fgďÓŘŻßţÄ-My­ÜűkÉ[B+b.Hş:_ži‹€¶‡ßÜU°Żą¸7×ůĆú\·Ő{s›šö`J“L›gw&ĆúdÎĐßM˙5Ŕ(éě}8@!öcř2Ăgť6Š^Ű.„ý{âjŰ>SŔÖ2iµúŢ1×3bű§$ZAů]SÔÝő&0%~+{ýúŢhśáË›Ä]MŢ´=&öK_ÓxÉvž.žęĚ~âcZšşÍrîł’~5(ßZٰÉ0őÉtşşóźd…$oĚë’bbě+űZbďđ=°F±gçőúáÂŚĐţö°˝űKęâ««>*şs˝s o)›ŢîĘ:±ÉíČ˙ eSôé¶V6ŁęĆj€ňě°%¬fśT–1¤.&g’čçwWZÇu"vlă Ôđ1ľ‡r™qĆß#=ŘSŤ5ÄÝ’>°…$]đ_gŔ"pŤ3ĚS2Đ®¶bţz^aśEm›¬ĘŐVßŮ{§¤µZ€ł¦lŰůĚwđľŕÉmőłĂ7›±Ž]ڞ0cę*ŘĆÂĎ»˙˘Q™ŻI3m\¸ľ§ĽI;/UNő?jÝ!m ß(”YŮőéçsČô˝Ô˛™¶‘Ňý™6ŃÚ§‚y,Nď9çˇeqz1h8Gbc3Ýř5Ă6PžŐĹ÷”(řiţ}ş\źuţbšCWŰ,Ă'Тďĺ®dúz?p+:ňĎ9ú5âuˇ^¬ä»ăeűÁ«~ěńVíK@~ĹyZń-é۲GĚ=ËąžPß*9eĹ´P˝4±¬"Ó˘bk÷×ŢčŻý˝´ŻŠń4;řý†ÄgŃöiĎbŢ ,ň7űÖAŘ!IşĹŮnÉ<S;Hyŕ›Â8ęrťiŮOăxŘ•±öWŔ:úŇi†”âü>X3%ůźŔĹĂ蛫“ďěý d¶K%v°ň×đ¸Ú—m¨}´oÝQŰe“’ő:{ßŕÚCŇ…|îĘŹyő´ź*ĐC ÍĽ×ńřm®şă˝µ9ÇłŔK·÷Ď+éYÉť°ŢżDć)ŘęĂ'˛§P†‡äŢ\ďi°­żIŮůoÂ7˛#m¸e°űóš®OŠ÷o üŤ;Ůžőěżk·ľ‰’>ěˤołüđaz Ěs†Ż ¸DĘgc°ŔűÖ†Ę5żóBĂëҧ8΀ż őŕńlVřKk|C÷…ĎDŁĽÇT Ă3íÝ=Iú ü ݚ‡Ű´«Ľ3-Ó%ŤćđÁŇ&ň"îĂIÄG‡VßíZ—¶ł÷ęĐ>ńă°9üĄÔ!e;«ßX·3ôvđő;]p?ŽŠĽ\š ,…bÍSičcŠ°Ë¬€ď´Á`‘ś­ Ą] 'cţĽŁŞŻé9č>­Đň‚ëOŻŻZ}ż]Óűü;ľkú&xż!ş›iÓަW#}đáţeřóEĽmŕŔXś>Ó˘]_ÓâB]łO­ű1óő7a—:\!ë áßcígʤźĆĽ«Ë’飤=xŻ1:±»Ű+'枆_§ż(ű@}EÚ[ëKŕźahŐéđ\śm&Ŕ&2vŔ€é”0ůłÍßV;Ŕů-Đ©|ź{ÚźF˙ÍŔş˙ˇ>Ź{1ż€|äśsUéJSW@Ćü‘áXCV`y5Ŕ .^ĚW©Čč…ţˇÇ6}ŕß§n XĆ—©CŢ’ßŔť“oá; ţb-ů{Iëx˙Ŕ9߼›Ôč`€?„:ÍO•^ ŽÝ̸d98ßdZÚŕűá•¶!źQk%>ĄŻP¶bvř)ÓÎWŚďŤzzľŐ 9±:Z}E|ŮË*ˇß54/čďE,äăĘÝ.iE"[K~”yt:ă<Śź Ő_>|u/Źí,<@ë7ô»ërŽy+BE'ćČëőE©ŇÔ5‚ŰĺŚoéÍíiú^wדÄ’ée†nřWAoňşô%ٰ4Ä˙W9đ ä=+ůc󾳬©Ä&ô-wőŰ{JwŢęűDtˇ\ŁSvϰÁťßŻíőŔߡNţpRüî=_ůP˵Í«řÓ«;Çšůd¸ŇâlSYÇYw”ô׎Ç8źäŕ?mőÔm ž$fßçŢ<í¨ČUÓ1”­jH™vWOŐň?»ď* ~`}şxŞóý‘^ç~<Áß÷§ťŕ+q“ŕ 3Očîe,Ń–>Ţ?şŮÍ€d­±ŤŔĚ}č1Q>Eł.O¶áË®ńĎűă ýĄůÄIČ\Đ~Ęę?˝Fń}ňş‰x·ôÁx˙tĂ_túëzîě}VҨU~MŞŽąOµÜ¤ôČŮěM_é˘´Ż¤ŻéI)óĄýßqµ3ËśJ,¦ŢĂř6pÚ$ ŕb”ÄĽu2¦›Ă'ă=…UżşöTW§ďé@­Â´[WúÖô>×u‡+<7MŻ>sýŔ5Öď.^Çt2-©2`#NŻ‹^ęËĽXľĽ}óÖ©µ^pňíKpž©ŹÚM†őéÚ‰Ő™÷ţ úµfQßë¶źŚ«î®¸ębMô¬Í=®‹ xḦ”=ž€ËZ»Ă±« sěäĎĐŮH[%Ó(@ú.đ7 mjÓÜÝĄÖĹ, üL§CNE űŻ”zsYĂ˙u9‹Ź9[ú”öĂcÝż_꛸‹čçŁB3ÓŐţOĚŰn'U褱ž_Ů»Vč6đě.¨Ě6|µ0Ď<+}{ öŹşüÍáżJůůűŽ®ĘrÄÂ÷1ŽKŔŰ]ţ´úžkăÇWaśa\ÉĚą z–‡‡ő3ç7#»–ô±†ŮKćÎQŔ° .éZöź‹gB?HźŘéµÇ›rCßPEďŇe…_3ýŰŕ—5 ~Y[JĄ©2$÷ük§TćJ&•7?üty$˛'dś?T.J_$ó#ca¨}13WsŽÂ\Žőf…©Ç‘Ńéü xÂYŐ±ęźZ†Ě•ü‰X•ŢÜ_Ęş+oŃ|Ěł4ńByĚűĂŞćđx¬5n2®×–ĹŮŽ˝¶§~xBU+›ľWŽ…°7uĽŚ“lĂoá/˙RŮ‘gǢpµ>‰eČ6\\ś® »LÎrŻĎµ OZŃ)xłŕ—q?tůđŰĚŚçplÜtgnŔŽ7|IůMŞtT9Ő›đ‹­F@i¦e Ć˙ ¬)ň& Γ[p[ř6y ýŻČOŚ1 ]Főktţ«4™ŹZ«ń·Ňe° ن6čđ˙Ť5eúŞjÓŻuŢĹŮŐAČŰÔjL÷ľ đ÷íĄnjßĆ•tĄAą×Ö‰«T™/qęÔ/Uu=Z˙Űę±Y~Ş,¤ő¶¬[ĄÇTySJçµ®‘2·úvŞN¦^y«ŚYĘĚů˘}BŔµ–9đµ&ä"ňť•\Zń×’Cŕ3˙ćô%];šÁ#`[˘ä'?e^jŻoCĐëńLü±XťG›´7÷W—&Ţľ™»CíSćJ®Ĺ:©Ľçv¬ĄmL=˝N…±»! Đm¸ř 3^żąćđÍăęâ±…śŘÎ—Žż±®(´±ŇŹ÷´o%u9P«0zçü~\°ň^•~¬­äŰ·#îŮýŘÝmç(g)ŰęéŰI| }×9¶‹z!›\%y/čWXű“V~ÎÇ$tŔ˛ËżÍ÷L2đ¬§:"‘Żk®Ĺžŕ`˘şcݬj¸]Ć=×íÜ_¸ż«ă2Ś/]¦Ń>łç‹ć™>MY”c4jýŘÔs®dčšçę“,ě1 3{{Ř•A¦S–ú¶|Ľö*ŕ†şd4`M•ĂÎÎĚo°±’ľPś-*¬­ž1ů)7 cÚáXI¸)҇ůígxŹ^Wń>ôµ†çň7đJˇ\ƨSVžëť)eţ«™Űů~qö ŕz+ě5ţ†mĐ j9ÇĽf~ŕó yжÁ™>Ë2!·´z_`3?*ňr¦ĺ»"…c› ÝŔęÚćÂôܬ÷tşŰÍűĄGn[µž•öîkR6h™ËźžőąP ŽÇŢś­Ôßo¨3ö`Ú'kŠÂÜş™`×ę<ˇĎÜ-wâĘ‹zĚ:‘Ď(Gp˙‚ű•ä_äô‘vb^@O˝îPü4~ý-łWůYsßísĺúHd3¶×”ÇP¬KŘ:™±@Ű ¶5˙(—‘ćî®p–ďÁŢÓí®zĘý ńíoC×Ě” lyhĂŤe›&•uÁń~…}Ĺ˝x%q?«ĚEÄŮ8ä>``öa˙ôÝp,+›†×S*ΙNë(+°ëŤXg\'ă1ŽĚx%¶˝~ďĹcĘ·ÜÜň—ÎďłÎ…}u™/8ΠŰö©˛çĘ•taűµáłŘW‡ßbN ôžú[`«(›MŽ}=—+™‹}Ą ‚—™ş&/3mËtô^?ôŇ뫃 ö ýlcôićf\_‘÷—č=1Ú\çJTLźŽü›¦O†cżrŃ=,Đ*ňş´e0y l#Úgâ<™łĘR ŹäŢ36¨ý}MŹ Pő ęË.ÉĆľŇů·Őc_űyS±ďÚéĎfů1© áw 'ľÍđŻĆč7…fŇM~¨yÖĚUĐŹTOδ`MŢä:BŮchşt~ú÷çyV>(űbOôÓJůzBżîËŇ·µ1j=%ßq-ş q8†¦!xLßXGCź}ţżí2ő5ÍĹ^ą˛kĚ6ě!´Úđîö‚nLúý“`ĂŹ9űpˇ›ĽQa7Ůé~ţ4®©n=©•T±Ě9źĆ}ˇ˝¸˛“Y[Bß)tB^ą±Z×”ÇőžŇ)(:u»ę3ˬŻŰęQá é{_TšF«\šNžÇޱ«±«±«±«±«±ř¬h«oÇ^kÔš)kƱ·©ě›Ö´žPqůľzϢŃă™˙Ă9ő¬•cŢ—«Éö9Ô:@űk›nÖ‹ľ_šRű|˙-´Ýôć=঻'ŐPçˇév<ě<Ë\ůdÄoľÖě pď˛#Ďş’:©ßoŁŕ¨ë’­ýůă' řÎý— c÷lŚ•ľ‹)b_ľŻŻ‰NÄŢ“°óňć”˙<÷;;\ëϤ˙Řo}ŢWmőe'Úă™ë˝!x†oĽŃă5?ü;Sněa@ďőŃ:űoĽ˙ĺ|¬E§dd˛č†©ŐÔÁŢô}ďó8Óö\cęŔ&Fú1âDgöS*‰˝=m!âN˝jtÝQëĎAŘÇę„v9÷¨ë‡Úáű©p?¨7§ż+őř¤ë¨Čj©í“ôyĐęĚ“ş=ţöen |TôŠ´agďă°»ź;ôżVŔöçť…ćĆč;ň8h{e#Ćř9©]jĄ/”¦N­ŠD:°‡ł t¦mđSZ»‰żĘ·Ŕ-ˇÝÜçÚÖÔµ·úÎ r˙{F¬Ć?×»?ÚVĹĎĽgÇ|AŚQřęÜŠx7´oUc5ą@üŇKS»„ZŕĹ:ł’YÝ]_‘}Ś9Ö8×<źëĂé ďmŚsľhĘîÎ|ŕ!}ĽŠ±ÖË€i űä°Í—ű|7•Pq·ߡ__nĆ}O{{ygU/N_*ô¶Đe׋8"ŇŢľĚĂimĐKbf1ÄäŽŔfśrĎ5ć˝řO·6Š÷+ť5bgÚ;{=Á 9řÖŢYPÚMô5휇ëa·Đý={Ďă_x[OűxIř6Ř:ŮčĆťélkŤÁX3°%04’š}TÄúűŁ"*F]ię§ň^w×&¦Ť¸×Î8ÚłĂcO'űämäřä9řşMAÇ^Gôy·8űËŕëŁĂÜÎáÓ®('ŘňßęîĘV|t1l!~lě|`o!mÝýöĹu°÷ť©xřqYęöĐěđ†“Fęv(¦ţ˛ Š/čR÷DŇ®‹ß‡9a†ŚîOĎőŇË]ýÍčśUÚ=˝eoXGhźËŔc/ú€óWş¤ë c˙ď?ÓŐ^Ź"Ą¶ÉpĘšzO|ŮŹůÎŚ đó=°ĂĘŻé˝Qę„ňśţ¸fĚŚŤîT”ObÝ|K6ip•öI¦?0íăń(ٍ5>ܰŕÎ ¬®ť`ĘÎ5FĎ:Ž6Úʤѽ˼?3ú đµzÄŮ϶uâ L>8|»dvph\wÉGö‹{NuńzcĆTş».»ů\É«đť™^ťÚńOŇFنűĄ.–tő쥫8ZvŃv×Î>ą8=ךÓrŠ*ŁŠ˙ýcÓŽ:¶bM#ž˛’]h{Ó×t;|W¦äȨ[ÓWÄ•xNŹ?iŕ+H[ŔŹSĆbL/ë@ř^W€—Úă &RfĚ_‡ĘoŰŽťĐ&2:sÔëŘ řr-d·˙OňČ´üľw‡€Ç= żÄ]ŕgr†Ômnő<{žăŢ<úŔšJ?’{*~ÇšżěŻÝů+;şm:Đľ°;ĹäÍ,zö§?Ö׎Ö—¶_űľcŻ-ěúéČĎôić;ó»8[ĺĽbjőĚč]ŇĎ5¶ŕĐRi;»ˇ÷Gú»Żé{¦^áglĘ›UÇBÚęcĚJ‹]€;7µ†Vďhż ÖQ¶ˇ+{™4›ĂÝîĘEŔŮŁß} Ž_™ç:ŐÚĹŇ/Ł*.e|F?ůąMđ:(SżR{#řuM°«ëC;Óí8KĹc÷e*ôkŇü/ Ú¶›°u^ ÜČuŰ™kEÇ><ůb}=âż™ÂxÂhWýë©_Äß®üÖ­†Çłą’†Ő ďŻűˇúüŕ„NÎ´Ź ,Űz“ç`Ń&ĆŹ’훿wÍŠ–[¤ ŚëŇÝ5­ 3©6¶mşŐďýĘ&Ľ8{’đE˝Wx§°ën*ZŁĚŐ×ô-á÷Ż—ěÁµ blď$¦ĘşÓiÁů¶/A`Jůű XŢÜ|ÄĐúłéÓô+sö[oni p$d 35;换‘őâţ-đ9»h>i đ^qvmZ«ěvęy¶ä›mX {ţ׫ËRBwľ( ›ŞMĐź¦®±~‰~ę%ý/Ř˙`‡_„çÁ“ćę; łnO’˙$€˙%zoFZ‹ “?žÉRô×}ßÄi §éuÚ©*NUśŐµ˙6i©wŐ}Äz“ľŐüđUf|ŃĚíš7FÉi'Ž?í뽎+}˝ö‰ť÷źńÇ­CNľIű@”öö›Ę7´můŰ#v®ĚŁö ,s$ňlŐC°{€üXyŕ RÇ´ŻĽ/Ń‹µőN¦/ťî=ĄzôNLc¤ëMȵţä)m®¶ezú@úXß? ]ČDř)ü?ŘÜ#.Ů™m3é÷DűöyĄßXÍęÇlY‰:%0Xt…đ1Ä…őĂ®sHţwWö׺}p€7NÎn—ŕ91ߡk6]ćµ9Ăď±rR¶*đxł4a˝gÇî„ĎŚác:=´á˝Ś—ČűE?ŔůÝi”çtż¶Ď¶wá8Ph|µ°^Â86}XżÁx`ěCüóćüAř*[ZWSx§‡ţbÝÎçÎWřÔKiY‰)0ŹćWv˛fFż˙)ĺŰčL9ć}eź$ĺÍ6Ľ`ęŔ‰›ä ¶şsM{ZÉS WąÍôYť.°śE‡Đę»öĐ_“ç QKň~ cýv{ŕď%ĺě?ë~ÄűW#näř é#vSh«zgLA`¦¦Ő\Łq}Ćtćá8@ŽzÍĎ2GÔ‹”`­—6Îsşič†őo–ŻŐwâÇî żŢĚşš÷Őˇ|©´Ż#&˘ŠbŇŽ1ďrľ˝ëÍŇVß…%™–C őP!y&Ó_•ü¨ccZśËŮ.ůmŁ´żŔcGF3qß56Ó† ââŮÎ؉\[?˝4užëťşx]ć­‚_đËÂs™e¶čńŘ?żižE­ŁËfÄęĘjO…ď÷TÓ_§§[-¶–·ćĘcđŢ4ôˇ{bß@áޢNĐV#Ł™ß9}úŇíł¤žá'CYß´í5Đ:yHcôŘ ôU‡ŻŃÓářȧV"¸1tŔ7/#ő`’˙ĚĐ —ię®ýż,µ…yN˝TĚ{*ünjLßGÜtĵď“_Ę×ýézĐĚ|Űę›Â1éC—¤ŻŁVa,Cšj°%»ź|ZŢŃ%… ·´-0=wC˝O/MÝ$uţ*úĹSÖéî:Fä®Á˘‡‘žň‹ Ç^44#–(|ß3ľăL›cĽ´»ëKFf[ŃbăYá‰O9ňvf.jÝÇ+}\ÓűđÇ×--ëűúl%/™^·Í¸¬Ť¦ĎË?< ţUÓb×l^–+‰~Šw _…ž }fżňlĂ9%ľ ehĆz˘¤8ű#Ű×–kú3ţŞ•üŤ´k'p’s%[–&f™¶×eé9Sţ—=ímđc€®3/˛µÖůÖĹ-i¬w+ŽĽTťuI]üg»ąó;Íđ±Vß×$^dFŚÁ‰Rnľ źRiS`˛ąÚ–Ϭäö¦ó·öŹDîó[I……ĘűđŁ­NîŻ÷rygä°c€”“ň1?ö1ĘN”wŕ§-43ő¨őiťbďćË$ÄG1“+0ô0î~(ľŢ|§4uü…ďT§ôč˝ĺ]lŐMĂĹ´ąNŻřm1ž|P×ýäŰÓ®dTb/Óßőű#?+_Ę?ˇŰ;šâ{]Ŕů3ICÇkÚłł·˛¤§=> ë˛ÝzÚŹ,«‹w›ľMyë Ä=† pdđiQWłć>ÉG¦Ź >„á…ů˘_çăÄY¦n|YńćH$aę\d¤<Ű ŘÝç‰CŁ´—´·ÖYrή‹ďnř¸~ďłĎJ‡´ó/o”u__Ó®ć{¬[…fčeLďkú’éŰĐ˝ &°.j”ź“co™j=Ĺgç˙źžŞzkőÝ$Ľ™ŘŃz,‡cýO{şxG˙G~řH®,ĂüQ‚9«Ä›K—y*6efbź¶P‡v›ŔW}áćŇ|Ń˝B3t+¦Ď„cď9ľW˛/KŤő”‰}¦ë]E‰ťć˘lmžÔŞ5Ç2Ö3’G*ńGé[ŔŘ1üľ¦žćË”žá«’2ÓçOúÍý/ÖĽ†9‡×W?jĄĺč·K!‡łýiç¦pźŚ‰čiG‡č{¤Ë‰0đK.¶Ă ü(ýR–‡ěéw×÷̵ýP˝‡ćŁů^ÓG­dÎĐÝţ¸˘ŻIa§+¶E[=ŻÉ s€_čď\mą¦r˛®ÉĂ(cłĂ>›[ÉşjUĂEˇőYCÍŹ6Nż±¤Oo‘8ó”9ů®Žýň!°ĺŐ·[J…c> ÍĚ“G*±ÄŚ!µo |¢֡Ś%ŰŻ¤^’ű?"´NČmâşQë´Qw5ť˝Icµ¸čV9p­~1=ĘZ :ĂŰhoĽŕ?®pŐýQ‘­ýK§2:gö§7"|Ě›«ś?YâęqíĎő$ŰŻ9g\ęm%ęŐznX.Đ \6¬ěĐ},3őy”cúk§É‹)çaO1VO«îŻUŘ5X?@źđ¦ô+ČeÂëąO}‚äŻö;ěvVŠQ»!yßîŐÖő;“ö ě>Ŕb/ IädC;±AjĎ‚˝ş´Ť´5ű7lË„†w>bb]$´ĄŰkŔ»Őţ#ôő~ěŃI:ŮŹĽ›č%.ńĆ ×IťÇsPĚ űÎS źŐň7çOŘJ{CĹË•ĚýX‹ĎŕŐÍU`­˘÷#ŻŞö\íYB3çÝoˇ?… Ňë°Ói7üĂ]’ŤńkxýrŤĹy“{‘´-H¦Ő^G?p9őÚS­9ů­Ň§RnĎ•\)íuě˙m|Ş t©<°_‰ůČŤgĄ(^† O9óĽ(tÔU›Ő‚ţ&—„H3Ç)ĎEż†®ëJŚëS„Úč~ tĘ=“}TSÜćp5bú°Ěžń®ůă#@Ż(˛‹ů`Ł_¨6Óí6!÷Xč ŘüšçQđÔšŔňö˝Śś‰}jiS®+4¶ů® ż#oc3]­wă3%ż~íË܇Šv`Ę36đňľ/¸ĆEŹ Ť|[ďź˝]2=¤ËÎöĆ#ł÷C}ľ›JĽŕżÚDGŞřŐ…^–R źë{öeŇTúÁĎs`ŽĐÂ>›ďBś)ÝG<Üç%S™ ô\ÁÔŽ8äRóžÎä xVeä:(j);eo.‚±ť‚Ík­{m=Ž’M´<¦‰ásÖ™zOßýo8Ű´SŻ€=· ÷l:tű)ĚçÎY‡@é řěĺĐtjzôou&Nµ~2v«±«±«±«±«±«ˇ5ŤŞX ´Sŕš_ë Ôúßýö@˙ńő*6źűţŃ/×úh&bJ2žâIĚo_¦{Šj˝Č}Zµg®¨[z›żFšPĎżč4sŹyÂ)E5ť ŰŰ"ě«*:ęMXöžö•˘+*ÎŢll·yßU?|Źú±ąŢ=Éś ­OÜD¦µ!e/ Úć$ëhŁă^űtG:źÄݢĄ^@÷sęSjă3Ŕ&ţĚ×ĺy¶áJ×6°«ˇëübr«ŤţJŰM±„1ďD)ű«÷%Ě^ďSOfciÓîčů¸~ÄîöÆ~Š9ě·_!ýd öMS‡üţó>´Î¶1z”ďEě7twŮń®é/´ş6Ž8ąU÷¤Řî´˙ ľ+•†°?ačż°č…Égs˝wTS—ä¦ďóă¤WĹ8öÔ7‡Á>ÔwŕgđřÎ)żŃWánŹ@|D[}ßŢeŰĽ<*ýŕ+™ăä ;řW}ĎčĂIoq¶6Ď÷!&îŮýŻ»&6Ö/¶ěĄOzďĚ•¨Ř4áŘiŘşNĘÝÓ>MtĽ¤{ňâĂĂňŐĹßÁwŚEw0ôŔóĺZăě´ú,ŕ˛_$c>ÇŐ‡Eß.G ĐžDóĂŤE§3źLËO`'¤l„şş” 5ě+Ľą«*`#S†X’ÂŹ¨ÓÖ¶\ŘC…ť‚Š÷Cý'|łÄ¶OÓXŚŇ–ů}0–WĘ6÷$uľŮ†šPwe”ď ăőúť yĽ"¬‚My>-/Đ‘Cŕóţˇ~`§÷6veNüř~K$÷1Î8oĹŮ˝áËecż\Ó{©öÜŁ”>öiůŽö}/ř4÷ç$Đ‘ź`čFüiÄţaĺŁíůŠü&é;Q Řg3ďéňŔ†XJObß1&Ď=NžîË첒Ib ^áľ ú•˙ŻţŽűüËŰĎ’1ˇďm¸s[ý˝/‚É=CŔĂ‘z†Ýšôa+y˘±YŚyĎ(đâ6ĐÜ˙™Ľ{ô¦.ŐŢŻ›jř9é-|őΆßu"Hż9Ţëě˝4řćs6`?WóD®dşĹ9„{qĚ—âY"VÓćƆţE˛G?őÎŢ'UÝĽž3}ř-°˝~\ÚżŻéć>Ó"oDĽ.±álď&tÓţ¦8»i ű‘ /„ď;ă`ó÷hä™uń÷ýđń[»^&6 ‰Ţ?I™ĆyśńŹ ĂçQbÄ©9Ęăˇí9úşĐĘń|®÷ŕhUJ{Ă–×Ř"°üůYŐÝ]ß“g¬›¦EĂVńżáůŮďŤěŠë´Ť«=| 1î^vź>‡°—a;JLgY­äjÜgU9ás„¸”S»S}DäCü6Ó”~ŕ,1ä4ŕ[Ü ;Ăłá;űl€{ÓĘObôićĽ>řě(ôŃćŁsÖźaű´Ö/Iô5ułÍ!ŁřB”?9?QfŃ{ęNßKŇË4c^%WëXX¤Źk,ÚŁđš˛ÚŇÄE®qÍx+|¦Ć˝ĐZĎĄ.L3ľ3ňCĹ»`ţěßÎtR‰"{,M\‰ąă«–ŢcŁŹić:4‹ďů1ěƆě=«öY”~öîw‰Źçs;»ýđÜđ ÖËŞ†NÓúš+đIű}g9×ő±Ijŕ«çoŚţBÚcQŰ\çJŢ‘6FĽ±ę}„?Űy˛­ą~b;§Űż*ĺÓk)»oßłý~ÓŽť˝_ŢÇúQĺTé˝]’rńţ¨ukŕGŢăé7 \«ýčRÖďşŇ7ü}›ç3ö+ŇŇ3ţfĆi‘ą*Ó2uÂ÷ío¸NÔőĂţĘßö;ú]Űťéé<ŘÖ|;*nčÂż`|ß,téwjçUĎőz…f-żeZ”}ł~gdç¶zŘ-J;Ŕ®É•g2˝źÜ‡´ČĆÉôoRt33mX˙ôĄ°y¬M/Ç ć"IkqúLéűűńţC }׮ÏŠî… °ţôWYś´­Żż‘€âÜ˙*bďÄ\ýË™ô"Žń¤éQoxs[˘ŢHŰšzŰVQżŁđ.‹łŹŔntbńB•ťE'dŐů›(E3ńł Ż—ĎőIżrćß ÷gţöćnýÔşpľ˙Ů×*żVß;’ćŔDÁZXŇ,şVx eM¦ďČômÝźyř«RFňfĹ»mzŮi?7Ôž„ßé1Ŕy®˝€;˘î{<?MŕW)]E¦ĺÔëćťőeȲŚc?ň#W˘d}¤PŻm­'mÚݵ•Đąş˘g|guÝ6Oaîܦ†ĺY]Ű[Đ&©'ćŢę{zˇí$ť¦…göuĸv•±1z°|§°ˇ+í˙VÍňö.¬«µĎdąiKřЬĘúäa^1ďf5Ôˇňz$íU} żŤúÔ|w·[—V_=čh«^Ň•-_śî¨‚lţ6ŁoŽ‹Ő&î¶uŇ­ËŞËçÍ%„ćqžEA]ĎĄ©zé+ńăă¨}Ëř–Ą;ĎőŢaę–cŔ.ř­ú§Ns]ΰ1•Ľ@ďÇ2pŕd~~C%dU®ţ%¦ Ě 2%ôĽ—ŔţŘ[ăÄÓtłż§__ô®Ž–Gśĺěi˙’™›E›˙$ĹßŐ›µĹ°=2ů|‹úcç÷k{˝ŞAÖ悿¶ Śˇ}Łż‡ŢâA—‡éNĘ>%k+Č'ŐQk8Ćü§Ě'ÍäkźVžî.{ž^TE*q‚ŕż‚XŞ~ŘqK;Ŕ®ĐŐ©·´ś˛î§Ąż¦ű‹ŇWJťcľ7íމ5­=OG6…x™ů˘Ă€©’«„/ńŁŻ?ěŻĎpo%lá„ĎÁgŮEł’QTîX—Ij»^¤+m _q©ÇLKJŇČĽgc`ŇźÎYvđËÂď‘öm÷wľĚÂ;ŕă*őę´Ďg¬bئĂ}[WŰ7‡Ď0kj]6ŰćŤüéűĐVÁ˙z†?:ăűg`nâą.žD˝*= ó(Źpiŕgů¤áiĽŻÖÖî˛óţÚô?›s¤»ď Á•Ś÷w‰n®ř â{*˙”Žü«eđ51ľŔ:żľ¦W{s˙B[¨2•¦&ąřdX‡˙ĘÎĺĐ˙Tô6=,ő¨u ŔĐľˇÓ䙲'â-;h)ÍË“é~%ó"ưľđ;P:?čňˇZYżřçŠ0îvCüć‰ŔÎ9ŘA÷Š%]Ó¤Ľz Ń×t`BW÷6I{ĐI¤đó˘ř­đ'yJĽ_é˘ÖĺB0]uF?µ4t-ZçîLkmŻÉSˇ„1»PĘŠ=É+WB_âźCŐ)Ö¶ëŰłox,ěϧň=ڇČPŇombÚ:}ąn.•ö…ź´ÁŞî8p?ĆU4‡ŻD|Í]”s¸nI% Ĺű·ôÇwî±–t…]{:u!/>`úó^÷Ł­~I×y’.Ę,tż_¦ŁÖ *ĹřŚFĚ/Źáťĺí÷O¸«zęń,Nź0s–k¬ęgÎ3°Ą_8i·’vÜs¶µšŰ ZÉ·ŕßT Żó rą3Ą‘÷í‹뢯Iá~€ÇqÍą`(>„/Ó‡óµŔ›ń”BWiÚë˘sÍ5KŐ‘˙C€cł9|Ľ‹çĆĽsÄŻú]s%íňM*±¨s…ôú)!î»|Łä·‹¤_ĎË/¶8§×Ĺď@űď>©tNÎX×ëÚĂL=G>¤ç>đLéCŔB R¶,ú'ĆńžŇŻ›Ă÷MCův…éťßŢńźV`Ý]^C@ëřÁŁ(_ţŢ0 rή=í_Ý­Ż©]|čęâŻÉsÔĄŁŽlü§\Éwĺ>yëbh[čü×ĺ¬äŢá_twBşŻ>Éă¤ä‹ŢEnsađkěE ˙ťëő[ÄŻŕŘ„Ż‰é;|§ő»©éĐ™Oĺµ:ţ.Ľ-•Xmb©SŹHú€cÔőĎwÁŢ+|ľ'î+i¬ďĆ¨ŠŤ@Ě7b „c;I=OČ=+47g:Öđ»aŢ™Şłlőm…ąűcáWš§jŢÍw˛ wů;Ş’öôe6~Ăł»B–Ű­.ľ3漜™ă‰ă@żoťżU}FŮmŘ1WůdämA2-µ5j˝o§C]łÖ×§oÁOę-?îuĚQ\˙XřžZ3´ŐŻŔ~›JIńř`@żĐČ3VrÖŮ4ČÖŕÝ{ŇżTľç:Šß±E­:ř_ëę'Ł×ÎmŔQşIĆ4q á7%ůPoÉ5Çőęđą1ůŁÚđhŕDV$ÓI™ŐX#ťöëض%q9úÂSfžłkW]ŃďPËŞŹfěkńť+9A®ˇ»Ŕyä<{hžú7řڤßž!|sµč±T>Ř/­B_„ yeigďť®1ťiŹůlač5ÁXµi&nvĚűÔWGţ¨a4cýZóţÎO]6 XdŢ$ź>"ň¬éWšo•Ąš żŐĺé¸sAŕĂIđµĆŘ^nÚk#ŮWË´ šÎ‘öÄ;2ż¤ĺ%QTóţJĆ*őcÎ6ć5ÖGRwβĹűo—ú"¦¤ľĎľD›®kőW?ł’÷&Ůh¶±3Fuś_s%mľÝ.uŰ‘ď2}M—Ĺ—™LÜ$¬§ Í1ď«AŤ_aÓţéz,đ˛ŠÁÂÚ‚|žéŇćB§?1×!yŇ·4µĘ1şýZď5°Ą?mťfÄ~O3¶“G"_Ďú©đmß eś ˙`ĺ›nÓŞú70äkčóJ:ęâĎK·żjĆĹľG ‹4I3ćnW˝R.#?ŕy´éey ‰±Čkč-÷"ôoµ_Zś˝NôE^Ä7ńý^ů bKÚë )§Â»·Ç±›vŇ»›Ś—ćpäą7Mźž>VöHČ“9/QßĎ~¦ćf•ç/bL°lŁytä•íxŁáL_é,í>EüŘÚ8ôĘ{Ą©\Źşxµ.—š˙Ô3-_Äűź˛2ď•aoâ¶ ŕˇJ?&˝ŔłŔ¸_(ő\IĆĆq•ăÉŇëĚž€N}Ďe)ĄŰ×é÷IĘŁm¸ô<˝…-` âţ¨=qE—Öu-…ž-•P±Nr›˝Ľ)ý©¬+áß®ýť’/nđ/L»—¦žě±#ćjÚFSoúö¨ÚEM*?--ÖyÔęü¨ăć{ˡ”LĹ”qč·i`Â;-@ů‚ú|ňqę~I3Ż3-w¶ó&Řő^.}Ą8;:¶…~áN 8^ź:>ÜoŽĆ/ě‘CěáŕĽü&®ňPgÖ˝¤zA§Ôsëk:_Ć1ĺrݶܳc;‘“fĘoäËą’a?¤0Ľ±ß8Ă7A°ł˛ ßĆ—'KŚĆ ٧ÝuĹýS}2µE 4ŕňÉآ­Ťž‡ő;Ŕ…,Ś;-ĂđIdŐëĹ^F­ű9oť„şj~‚=0Č}óź|˛­±Ťý‘ŕ3y<»[^É›:‡ŤqfýŞ?§ŚŤ6›-]čşQţŰŃΛ›vňe¸ŢSߪqé¬ýÍĐ3돺NđGé;á‘ÖÝŇO†ľ»á«rëúÎÍ:qVO”e€ ›îĘeWňšzoB—˛LŐ¤c&ësGŘCűĹ–Dě´ 1’÷‹şUgú«ĎăLÚ±îŇe‰÷ż‚íi[bm©’˝,ăźcXŻ 'än g™<§~)Óň[ůŽ1ľ¬żÄĄO°.űkožŐŢŤG˙çšTmNž”iyËĹ×řm$r™Đ]‚´=ô]5N=ŢŰ%GBÎ:<Đ.6}vHň®N{Ť˙\žŤůF[}jÇka qô[»Bv™‰~:şŃ_`_1ë‡ň jEËV†¬DŽj ź,műVÉ™|&8CÍ s?U}nL*Ö=/…SĘů¶/!nˇË‡|«#ż ä§w Ł˝&tžfäJ¨oÔtŞqłîeřĽľPĺ¦$ĺEúŘ(Ě_M‡Műy÷Ş@+ý\ýúßűoÓýżOë˙^ëŤQ4Vc50Vc50Vc50Vc50VźO ‡uő‰őĘßLŻ)>ź’lŘ\©o÷ČÚp¨”:Îó?0ű¦ ^é@Y¦^/¬ź7l G3uęęa7šc˝Tq†ź«a±č± Ď˝Ń‡E×ű5ęĆ2}¦č ˛ 7ýÁh–käĄtô‹Óż i}5ô`¦üV˛ú’‡°ÇxžąÇŘ”ĘW”6Nômř+ö2ݍ¨ű1č//ĽűĹÓ#ĐgóâM z»Fą÷†˝*ą‰(;hĆčĘ•ÜjŚ2ž ăcČ^Gś9…É5Qâ‘Îőf†ő“Hä8ř˙ 6–b÷ěĘKż1ĎŹęźyú2Ęľ#ż-tš ÝđÁŘ,2űělKîŐĐÖŞ§ý"ˇ“ßB7»Ś€é»3ż+ÉI[cď1Kg¸_ ôŮ®ţÁď7ÖA=nO»=~5ĆbC"Í#đQ±Î—·? žŐ{„ŁBĘOg¶řŔĂÎ-(ýĽáuѦ.ţpLž ,óYÁ䦰GyŃôqMW¶ÜŰŘú}Ť“űC)/‚ľ›q _3sÍrÂWí˘°á±%ö‰đÍ—±PBN®d¦•[†Ô^ý+H:3bO”ϱĆUÔî·˝+mç>®“ uîČO3ă.Ó˘â-NÎl‰{«W´\_KŘ˙mř+|+uą¸Ç˝gö¶)÷˘ŮĎÉ—`§-ýµ ń!Ë#×ů˘'M¤1CĚáď÷Ä‚-ĎpţÉçŁ{¨8ŞÉôó!Ú>ŢŃŐ ‡Ç¤ţëâÇšľ~Ŕ"6 b~JŮi»Ç=[ŘVńJÔ…V5ü\ž“~îŮŐĹ7©AŚtÚűšîĹľGka~VTdšĄŻ4Fß±öŠ÷ęaĂŃMĽŽ ąĄĚ‡!n}®d’”¶ÍđĂxÄŘ÷ÄűÇkÜ;)(Ű6{ň]q–ń-ěXŔş=˛ ăáŹöJ6Ś$ő°ćą‰1  ź›˙“zn>wwŘ“d7č^e_S«Eź=Ś?Éł1zRŕ×íy±—J¦?€Ď˝ŠÓE>Lv„čÓ‘Č]!Ú% Bfż¸ oeĺź6uőaĘ0Oá[]×ônîčqżĆ{@Ľějř_=ń.6Ô7·4_OäŰ"V”.—>ĂF˝˛.~˛đµEé[ä9üYĄ/ŔwT|™Ă×m*ÝŁ ĎT {†i ÔţÄ"›w?ëAębuíßďýVYęŰ2n:ň×!FŮ\Ľ ¶đĂʢ˴~g5f’#?X4Očbzđý«†Ź·ÇĽ§puî^VĆĽ·Şáuiµćŕ[Loř8¤ĎźbnÇţĺÚçĹĐl­Şć‡Ťä‰Üď&źho]Łí.ůýú¦lő«.9Xę˙ ßr X9†—NÉ”ů˝= ‘ňóµË ›5ˇą»KŮ °ä×,§¦ŮYN>ă;Ŕ—wk4ŢĂ~¶É‹4zsÄ–Ă»łnpŤ Ţ­ľşŹ"ľâ7CÜ[­‹,÷úš®4ĺ!-Ř[·óvXÓvRĘFW·łŞOřX˘]{áß i˛Ü‹Óu"żÔĹ7µ`?$ytöŞ>9 ö„waL»c$k{ŤŃ˘›éhě§ľ&ĺżźJ¨ůŮÎŁ­žľ™– Íś—őU¦˝¸ď¤·­^˰Úţ‘öđŤŃ_Šýý§â[iٱ7a»p˛ŚÄŽ·ôw,C0ů’©3»LëzĹľ:Ipě_téKđ92mK˙ŁĆčMţňT}Ҧ§łwóěĚĄër©ţkżŁŢWe"6űßŃ2ëL÷˙ĹŔ @śtá3b!Č >Ň'6”Ú^ 8f…:]W:ťď·Ő÷6-b›Őg/9bŹi^ŔŘ+đŻôÖ†ćE\ ™5ĂBőĹr¦ďaą9ďäJVč¶’qŻľQ)-N·9Ŕă9Т ß?őTý§=–ó÷ş^§!OpýŔ9ü}îřÜx±ˇvÔOVĎŚľS>P{ ‹o;۶řĆÁ¦Dő g;ĂîxĽJ®aąŕ—LËÉíě đ›kŮRčĘ6Ü.yěĘH›ÄňŁŻČĚčŽAÖ–wוVľOźAĘŚ” ™|őĄ_§ĄűŞ/Łx ßGĚÄ!ĺĺ]üî)cŹ× ú÷EŠ5o){±ćđÎBS_Óv…6łiîěÝFúżç3ŕ@fa›”üXFÍůśľ»<Źäxä.Î)j~Ńv¨Lź÷U6Â:wgˇöĹâ'S÷ô»ÇĄÖ‡Żó{R˙šÖ5ť5ż-M]¸Ë¬-sSkt^ĚOť˝?7} ľ>ţPrá+3ďOżŁÎ¬łu?&=x=ćÁ[Äa;sĽń/Űp˝kü`Í#ůő6m\–ëĄr%×C~ţwp öíŕ*肆ĎOv;ę: |Íy˝9¬0OéAýl]ѦZ!ŰĂWëFđł+%/č% ˝áŘžŇö#Ĺ–ÚÜ7e­Ă6ŕź/sÄeyř‰ ď=„¨ Ż–µŰÍŔN{ř)ŘţĽŻdڎô˛ßä­ű[Jź<ĹÚŐŚ…Ú&ĚÁ-Ć× ţŕ×ĆS¤Ě¶|3~dz`…žli˙IőĆşüo«˙üś_sŁň!š=ÍâXçóćđŇ3ŔľŃđV`ŹUž\Ŕçá{X?ˇŢÜ4#^2äWźˇŁł÷i¬ĹłŇgł©†f¦ţ8íßŔ5÷KUĘi%gĘ3§>‚߬í±ß §bý«üČ`;oú3űŰťöą\ëzs{ÂÎüëX#nž„”uUĂtC7ězĄ_†c-hŹ ¶ÝšnŹg"°¶úkkŞcŢ´|mľĽbŽĺ:Á§Ę'e÷ůßLť 6x çEÚ‘Fäţ`QQ`Fě&¬?®µč‹®ęum)uż|x`Ź~Kd@¦Łez§Í˛ţ˘§ýÉĐ>ń*©ďÉ™PygŻÇĺGŇžčh/…ŁĄżímZŚg§›çhwř–n 1GůŮ’'Bč„l+}ź|Uéą&ËK›ËËÁ÷uęëvvöÚÔł/“nĘ‘ýµŚťë„ÂüŁŇîiżYÚ ŘpÓcŢ—v{»äLńEţHÚž~ĽÄHHôŇ6ů4ô“ˇŤo†N)]‚X‹ňîĐR2oŢŁ­(ĎE(Śą6ń;×cl°čÉő¦™mË~ŚuŤäAţ­çüplŰb÷.čŻ '8mł ĺv|{Ţřö7ľ~g)ú(h鬄žKęCű e–@÷ ÖÝď›>ymÖŹߣ§ýZŕ¶ĎßŰÉ(ćÝŘěÓCçzO | ¸Y,#Ëı_ ôď)č;#=Úę߆,w®wü‹vľŠ}¬Ť·^¬mřwŔżQŤ+ćĚ´onW`ĎěÂßÝ];ąÚnBn3˙}‰Yąx«YÚŘŕSاĄD­_” Î2° &ď ŔÝšĂ×ÁGióJbg1-ę÷)«ąŹwTlQúÄh™@Ý]ź˙Š× łőxËĐ+s±­>ą.8!wşŚsu{ţ.ĺęäŃ˝ĐOwŘ5ć˝fZgďqĆ· ó7ü|ĎL–jiâěĂm¶?ŔĚżĽŹąk*ĎŔ‘öGŰ™>Äű,–Yxfßg¤<¦|Ô[ëóż#_ž| đIJF<܉rÍ4‡ęę #öĘOK{Úă¦#F„´cqöĚăwaŽ#6ÉĄ®ůľ‘ĺ}M•hçłwŤÍżŕŰ˙|0/…g-č?ż¦1z2p‡T˝ł˝ąŻI:ą^EĚpi=öÖ‡^ý-1cr%§K[ÂŇÔ;× ‘:˛9Ŕ7şŹ>ŔÂcŢť¤Ü÷ßYŢW­ tZşZÉ;P—ß5iaž5}")+‹ZăĄýKSŻů©Ą¬‘mJ}ż…}@®Żő·Ăö¨óZßóäŚĆaS8ŮLăSĘÜÓ®|&uuńź˙üÎŢÇ!/^ë⩏·(?Qĺ3(~îŇžĄ©çÍřľąfşű…ńĺńż±h•¶ Çv…_ŁŠsuđqźžÁă‚ŮFů/ű™”}I×+Ő=ă_ ć?üa!Îś“fŹgśgËÂścß×ú řő‚ëć+üÇÉSΗ4Y~ĚűAŕ0bŢú­Ü Çf˘ţß±ůÁú9ä[¶ĹěđX˙mßÇk!7wžµv sDö‹~\Ňu7ěŮbÎAąlšdGţ9S~oÎĆTć¸á»‘Hź´ý‚٧í€=š3†ĐóÎ.Đ9BWxôÍĎ殡żdŇRô˙Äë©‹$ŘO€ž *±F> >Č0Ďřçĺ—JŢ´§Á«@3× 3B}M?—ľŇüđeŔMúÄEK°Y¸`2oö”k`]~ qTŃţBç\ďÖŔw¨ÇZôđŕč­©†VŰË>âýĺ2^á˙ŠĽg_Ó%¦Ţ=ž[ ő5×1˙Z±N’ošĂ«¤^ô^–ťŞ}UśÝ˘lŕŁež«‹?exßŔ:¶‚’WîÄ$Öî‡Kß°ż˝+Úč5śJu6â„(ž­sńćv0}^ß‹DfJ™­äB»šcÚdŻ ™V8Ĺú]}Ć>źČbŔ”¶Ć~ě®h#¦´s€2ŻŇˇ¸ŰCż3ç]¦L őaÝ]›XK ˇÓ] Üáˤ/zsŹ!>Ę×LűBć.÷úiROşT”›jăý†Ř\ÁîqoůíËÔɶ’^`üüYŇÓőڵ¤¤‰¨Ř}:˝ nCĽˇ^23OîË;eŕćđűŇ®‹ÓăE¶ŕ3îżŢś/şýĆhł«4F°]|0•đÔ`®,`ię6ßŇ9 =ż;ćtűs¦Ěýµ˙Ću›řń}×ů{1ě:99®cŢÉgž6iđ˝LKŁđxěóůn? 8§ Ř#y$¤íńřŽ^×đús8`{Ń Çę:†‡âQ´Łz¸ZzŢR6ëş|Ôsż@é,}Ś>cěşř_¦rڶ±«±«±«±«±« Y˙Ëë&µfęęşŃ¬‘[};tńNşŐ{J/H[Vő{CÖúh§ýĆs ±˝·üRC/óŃ>iĐCç§čvęőKSŹ.pvx_lw§`‡1Ú%Ýô^/čFZ}—pOCl"zÚË şË%Ő°˙uéĂ˙öľ>®Şú?…˛LA,IZ§´3YgŢLdIĘ I]Đ© 2)2EQ—A %)k§ěIˇ ĂÎeŠ$E@¦€âÁeŞü€ Č6E§(˙ď÷Üwď{“†ĄMZŞ˙ĽĎ'yoŢrď=÷ž{ďąçžó=ČÝŽUłn9ZÎw˛¤±îÓţŽÂOzçrŔfڱZę˝Ůť¤ů&bś‰~×°g6uá)nűIĄëĹŢě~˝eĽÂ÷7Çń˙°súNđ:Äżpq†ÉçěÚ§5ű»´5|Š/'ĄŮ¦a“bÇOR|Ćô7ö‘Nnę~ŞSŰ/ĺ[ŮĆ܇ż¨ÜS:z§DÔéł}Ű#S,î[¤öä7v]ü 1t>nĆčľÜŢeőćˬ€ŇŤ’÷ߥçx'‡ŤqŐ%IŻW>cĆăHâ|Ś«#–ÍígĄÇăO[´íF|fˇam哦>XŞ4l3ô~Nü˘yŻ*ż:ÔSrű2_dx>n݆e[Ă_î<ŕôź,‹™ô† ÇlÔ=m‡5/~<öŰ×6ě‘é{ŘĐ7XöÉáżgĘJZč;Íöć^÷±x]hú·iOŢS1*i«^úá+; e·Ŕ4€ĎÁ}]Ăß´!ÚńÉřlc¶5÷ ‘·Ôo(u!b"ěee‡ţ(e|˝r擳€Éň áéű1†«ň¨˙¤“{¬sKĂž˘c[ĺßó9ůľ§ÖNŁ\ó‹?Űű×RwWÁö¦?ýĂÚŞ|BhÄü.yŔ&,pő@·\o,şaŰ_®máżš“XƤCď?& ?–Ľ!w@ľÜĆ"?ĚČ~#DŰ=oöOâgĂ1ĘSĽPÚ—ţómńjńO€ e{¤UíCRF›‹8|[IýÂŻľŔµánžšRd<uŔ֤ڧôýń9wˇŚß‚̧Ą-š“űJ^°EEyâ§×W—8«=pPb1bĂ-Ńî¸-ľĄµ3x?nu`ŚżxIż–>Ě=X¶ ëL— >‚AĹşb=Â&ضUŮ-<-dň¨~—gOîÓÁkŘă<uűeë9`şßëu§÷{Ň>+…gď5ă‡7»]ö1đuŰBúZŃw¦´ÝĚl‡U°c 3ođĄÔmžasŤ´8ĎtÁ×ďÚFÚ™Ą!ŹĂ7ö˘†¶\LĹâ…MľiW¦Ĺ2š‚RUĽK?ceg­~ŤíżöÓ-‹Ý¶M’źćkť:üÎťR[¶ţCśÉ˛ňî—đŘżͤŰŮ›•1č 1>°Ľ§ý<:˝[®^0AiK§ótźO&ôŞÂ'tßŢ kŽ»ůV…y„yBxţŢëô#>ÓvůÖŚđü¤ý#üeèhT4sżymĺyw7<Ď".Lu¦㡪›‘6°k+Ż”üáëo!ĆJóŁ”ţĘŔ¸|Ţ'|¶A„šŹX6úríú0lÁTmővÜ °Ĺś2ü¨p=ĂM-ŔŘ2sŚÂ»pÚXń8ýó˙mŢA_qń†ĘźkJćJbžéżŹVëvT"ßĐ^˛źŹĺ < ™˙cV6'çŐ#ÖuM¸̇v뺯ň ,éí‘ áŁ¤ě`ősęâÖ«°S-{Óeó®›/JÝaĐ2vr#)‹ Ŷ&~•ä=g‡ííqFŐÓXč¦M)żg\"ŘKţA ›óCĺC5CŤM'đ đ\—UĺŤ8}đ3«ĂŘ~ä¨3É›öř5+ڱNŇlĎĎ„Ý}•´§ÂťPé OȤ'á3^çÍţRÚ™k¸h”řę@Lů`öŐŘ[YÖs.[ ý|}ĎťŢěúS_CČňÔZ(ß:Ýđ!ÚÚćO‡fŕÖŘs°ÂěËM·Ç8§Ś¸é´ňGëôî^ز嫦ŢÜľ4Ď6Ĺŕ~GÝjYsTŔ6đj`X\aúDjŕóĐĹ cb]lÔőˇ™ëň70ĚLť˘O:uZ îűśäť<ň-Ë–Ádťä)z!sH[ŔĹ{N˝€Vąßé}¸ 3,%ź¨ç7CŚy´ŐT7Ŕ>W•ĽÁĎhď{ĄÍŰďű¦ˇ›ďvÜ3éńű ;¸Ćç8 ž)këó¬­Ś„ÔÖţJ¤58'y?p–ö“rĐnŹuµĐzZĘ<»[ę s—Đď)fÜ*]޸ő]ÁpáořČ‹mÜßăaČqŔ…mCźŠĂŻđ4ůVă>S]Ń{—y>–ueěľÜ †Ţ)EWNĺ9Zúf[ü ňbb‹|¸¸¤â4'ľ)ţý‰¬9í{É{që ôËC…_KÚŚŐęűŠ bIro`d¶)Emˇu>0oÎ q.ěËÍż—V§őNçůŃ‚' lĚ g@ć^ ĽŐ0üÓC¦ý“…óŁq…żVv˙ŰŚĺ릫h%ýzMŃSD™ż$ßZ©¨©ŻŐ­^Ś÷—b\zkô xĆĎô„µlČ´=EęŐŮeŇéë»ë{Öß+=ýuľu·í÷<ĹóĂ™ŢgÇR?sźűÓ ^îę:řoÔez÷Ŕ|t«=Ţ(}i[üb¬-O,^úşć ‡ źč4€•‰÷ďµí¤ő]‹Ô¶­”X¤¬Ö咱ےfuTgËIµs1Ţ|­‘cű;˙€ł_ÍŻšú®čzłĚכߵĹ÷qŃÓŐň(ĘÉű°–zĄćŐ3Ňô]>ËôN—o˛Ź Żezłeř›ěo¸e~–‡z'Čꡱ­±šY†öČK‚Mȵ óŕ¸9Íđ8ß)4í0ăłÁTIxVTSŹýr×ě´ůŰBËŇg…—o…<ě.ß‚H•ë/ó=ßoʬĐő)ŢĚ{4ć8é^ŁňŰő?oÓßq €M±»Ś—đsß"Ý'U(ť>â—•9Ó»›ŚEŔ9?J:HľěV2żéô:vŢţĚ+ŔA¸j§Üî:=îűčkÚssľ QźJv˙g~ y‚WŁßݰłjg¶‰=źHźaZ+ôłľÉSs’CË?EźlżŠľ®YĂM3ÖáqUgüB¸i{č…Ż!ź®eŔot JÎűüŤ <Ś{×J€+&çda:Ć:…Íw6ěpx›ńiuŃ.ĺ„ç·äEý}ŔősžOňľ1»?=ÇĐ ¸ŹYOÚľk$I«9ů9řc­˙3řŁh+ě÷ě„˝ŚCD·Äz?ŢJYŠŻ>G{DÍ‘đť”rôĺ’đcŕöŘÄr…Hůî/$¤ěś 9G3u+5 X<;żÚíşPyV'Ź™…řÖµC±ţ]xsň7ď»Zćľ±chÁ˘łE>!ž$ßŢ'ůuĐwV5|9|}ąE6.Éľđ-JšJź­Ňoú'o“ÇoŞŁ,ŻüťÔ[c˙OÝS!F’NMűĹ`ž1÷ ŹWĂ—Đ´o¶ckÔŃM6ƬÔů"ë~öMoöZź•~Ű˙âöŔ+şŰ”Íó¬cĘăţĚ]Đ—m‡uŘĚ ĺůç0> …&Á§r’.߆žĎ Ţ-:iµżĆ~u=äß\m¶#.uM^ăśŢ` r`µ”ŚłJŹíZ3'y‡)÷‹°A ťŞ\Š~ţVe»Aę q”«±¶ô 7m-mŤ˝{˙04_iZ"‰şög:Ŕ‹;‰ż˝~ľˇçöű¤L+zĄ-ŕ·ó8řPákŔźHîëąrJńh`t_%ĺ„XvÎż^˙ľĐ¬čT4“/˝ŮyX#'ĺŠ^,-ůÎJť-őGZąf¦8Đ9ßťaµÔ9ű›¶żż†Śűť÷şřA7âöö#†Ĺ¦ Ĺ~]ÇůĂźYjĆ%–©7÷°ŢűÖőĎ5%eü…ľ łuŘk ŞýwűJŰí,:˘Ú˘ŻCĆ1Śy>đNÍĘî˝%`•Iż'.š»Ěä=BOV&+¸ß[ßk`ˇ„t^h©Ţě$ĂW¬˙ëO€év×™zŕo`PˇÍű€±ô{?ćngâť5'Ď‚lw‹|Jg|źů=t2&ţŽ\6ş‚ŰĄýE®«›á{{˙“ŻŤĂˇűś“ôîRßď!őOţă|µĆw%ĆďŹ5ř3—ÔÎĚîŹůçŕO|qŻ)c¶›^çšén)éD·Ő@_ZI `Ź*Ú`Ąv4mW™ChĺŰĚŹý ó¦čËÓâc=Ę÷Öß)ŮFĆ^ę7l ¤ĚŔv&<‡`^: »BîzQî;eÉŰ]-\˛„Ŕŕ‘6=É[ŤŤ"ŁŔW\p۱o„¸7ßúźiÚűY§Ë»7ą•<¶¨=Ńô“±RĚďŃw%]Ę›”AčÓś;)ĂěĚ6¦ţµŹ(ż©®ĎëŇË5 Ł÷âs7_vz>ÇŢbY•űvSžÖă÷‚Ú»V›]Ż*·ńúOüw¦…ąúó‡Ŕ{4:u,ˇźű]€uAýÇI6îQżěϻە먳€!˙HYŐŢ„zoe÷Ô0öčĘúđh4ô§×Hmńޞ´F{wĽîRÚâ٦ęĐŁ1X¶¬±&q4l~¨÷ëj!®ťä{ŕď¤|Ŕžô—ˇż=żl ć;«1Ď^nĆÁ˘Źi?ięľß°7Ů:Ł·Ě;ÜóŠF˙aúýxŃȲë9¸Ó»Ż”}föˇŕqc?㓲‡n`[™źGË»9©ö˝ř,(XůWbąĐŤ±ę!ˇ¶‚ s/“,\mźoôÓHúPű˘5¨ĎĄ({şukŁĺąá÷Ö»™V$±öYCRÇx@"{.\húy4zcĂŇ ÁlÇ7lݎ«ĚôN>­yťönÁěgšb’âŻH'S—!Üékwě}oĽÎ”3łß¶ů÷^Ů'¤śÁ~ě)fMż‚޲lŽeţŃč˛:čě;ć Úk°·o7ßiŹ|ďěTŰSÚAä°)Ĺ7«‹ľ×düN§_z˙mx8‰1Ą˘bŞ=2…Ťq¨q†cgjŕ®Đ‚Čý’˙ĚěgŚĚŇźžmęź%$ öÜą Řn9áGî7iىď°Ď€W -ĽűĚÓÍuqk°;ľ ]ŕßÄßď ~ řăÁĎPĎŁóÓݞŢKľŚiSęzßiOyzŠłj±ŻŇ€ňłv2Ć'ĄkἎő—ŕrýâ9ńňPE×öŇ–“*şŞoďýLőź[ău'žFíĂ%<űKťq?ŕe轟fÖ3iéô~B|ą5nÜp“‰š«¬ťů.쀰/sőš˝çęŘv9˛Î˛Ü˝flć7îŁ*_E|6“.ö§ĄnĆcÝčÎçÝŻŹSOó`Çž›q7Öł‡-Ŕ9Đ×ř¬|ëSÖLŘÎč4´ ÁßŔß=˘–˝ô;É1Ťďĺ_ZÚ0'y„´çâvS_Ë=wŔ~´âQHßOxĂśÜj =©dmG¶S|¬ękăó´M¬ëÔ{±mÍţP.”µĐ:m­°ÍôSŠÇ‹ýŻÖą»iF\Já[ĆG(ú`/z€ÔëăÇLęq•=¨â1ťî¦>Óć+éReŢ,ô–ů/‚}ýŹJ•‡›DŰxÉ÷x˙%Ä5hq Đmž…ÍëžcŢôµ°)ŚJzLsŽÁ$Ň´~íË’8‡íÄ8N—ŮSńënÁÇb‹¤Íë…±]`sp‹ôsŽ…ěZw«SĽjŕîщ-™–Ż łçŕž^]Nu¦ý˛×äoÚĎÁľAÓfĽ·ĎŁ«ĺ$ď÷BĎ6©:(UŽ5輠•z±˙ ł.6^Ve}·˙]˛'ă¶KĐoű3+…vŘ7fŧ\k' _4s”?ó y‡ćJç¨ůY§˛9źuYŐ™cPOéáĐ*ÄË#6ś¦™´ĹŻ·Ř¦z*×™mÎ4ľ[ŮúŮ÷ő>„¦[é śwÔýwKoâŮD LÔŔD LÔŔD LÔŔD LÔŔD LÔŔD LÔŔ˙v ŔŢÖ:kD®G;şZž˙ëńďđl´÷7·{ÚJ—ë3˘˙€ |GŽÁ>¤cëÉý Ą˘î˙LŃ÷ĺľnľkÓ`Ćënřţ4ĐcĂ'ÄöĺŢĚ‚ČjŁŰ÷f·1×Uůď7rĎJűÖ ţŃÁç8Řś|Éř…oxy6ö—jĆí[Rý©xăâŇ"içRĺ±Ďü¦\ł4ş}éűĽşµ¦ű ő·Ř1żTüw]ćwęúůqV{É w±¤°·ÁR4'·Ľ…ÔŔ°ˇÓ]şˇŘ%˛'Ť~DžG*fßAüAáóÁîbűUmäýVw©ŢýúŚ9ĐÝÉ>?uxs’[Š~»§¤b©Ż¶ćG÷ TÍpbÇ ĹζFî“[©ŹŢ®Ę\čĺ÷Łůs˝{©6ćSĹoŔ ˛C>S-ő4tÔ—ĂNĹ0ŰÁ¶‡Őţř܇Ńűu˘ …>”%„źôÚ“¤Żç[ď1¶ şô3łK§”;ŕ6yŤŮ7ĐĎ7Ĺ™ľ<°qDU¬ZŽ˝:ߪ|?řôLŘ*|ůÁî˝ŃOź0mŘŤřLÜßářE?Dřń_ż{ľ›l[BŘÜ ÝĐ #6Ů×°ß®|€uŽîTßŮ4gmď_X)öX…‹ľ{Ě>±»$jOňěm|&í8עÎńL s/‡cżď4x?1 ¶'ż†^•Ô ú 0ůŹłaź‘ém ŹĹWÎ]®÷s­qŽZă?mŔD+ĺYŮýXPű”ô”j…ćI7 Ćń_Lű2mř«ŔWęűÂĂäń%ĺÉgÝwÂç(*Ď`W)őř«Áć[üro(Ů…Űäšű\Üäw›â`l#•OÜ:Áe»Łó†Ý^™żľ?©bÄnË·n-ý#đ}vâ‡÷ĺśq±Ďdď}Zţţ†âµ*–z˛đ”Ř˝#wöfôAqd;ťËřźőţ©Ú_Qé'<˝B}yy6kÄ’ëęL»đ.IúĽ«ö,ŘNL‡ü‘,laĆĄ„g—z`9”Ů}{ł7".úő–ލçĞҷ׹ĆťĎxťąďRŞl3ýoRĹnbOËýŇĄ…ŐR5ăiÄT}1Ľ~+4ĎĚ.g´©ĹďهµĎüy…Îlxqę@?®?É{$lě×oHľŐĎô7|Š.‡_BŻôˇ„稖mô;ăuN 4Ánä+6nHEĹĚě«ÁľóT ¸9Ie óz°cŢű™”ŮSügř ŘG?Ně HłÚs¤|=3¬mpč'Äďóç|Cú,Ż­ÔÓđ ¨A=žż´sĄŹWĺ·ĂX¦l#»ĎoŃŚ2^âwăstQöąµ-ľĐzëíßI>“+t ¬đľt^Ţ3ĚŘ·ŞĹOš6>ä Ő?şZ苇xB0¤­żf}ÖđxÜZ(iôĺÎZuÚ+z+`·q&ţ2đ>Öš–˙)ä‚~óť~o<Îđ[˝âÉrWĺ«áW·ĆZŹÍ·ÂžâşmJ˛‡<Ĺ}‚ŤŔAú>â®óýõ͠îÓ”Q)›ĚŹîô®e¦]bŔ9v 7ĹBUů}C´%d9hŻĂóřň·’·ŕ7î)ÍÝÓĄm˛_?˝eą›¬Çb÷ÁĆďÚ€ˇ˝FŹmÄą‰űĚ‘Ä$ЧĆ1¶EţĺgĺnŘýI=¶Ĺ«`×|d´ŘĹ}ĚđĽzw·0ÇĚëF¶s§1–ëlG·´ëqiáXÄŻü üĎ+ŕ[&ĺčžjúS_î^Cdą·žĹ¤ü¬Ôo0?Óvۡ9Ű1Uřă—Í/NiőZ…w˛ű_jŠy>ĆR¬KŇ |©oçë ˝ęť6ő«ń˝tjÍÉí€ÓŚÖŰÂűîŔ*Řějzŕ·Ţx`âđŃKż„ *uŕĚ«]-ZľazĐ% fĺ1fpěf%ôGˇ¶ŁŇ·Ż8DÚýB—EŮÍ*žÔ÷6ä¬q ő·U_nĆZţęú„çGĆ^O?ăyüĐuě[E»ó4KśQ]'ěăŢěQ°Ź;$ ¦ýÖř&Ű׊°Ţ†ďéĐoްÇí}Äć2YP8 đ}vıi€ÍCNľë{»ź0}H^ݬţsĺ2şá˙[VVҶö2ĄĘ'QOó®ŞÇ.‘GÜéńş-ľ˛Ç12—ó{ňcŽ|ţ8¦?ń™[Fi=ňŰ÷úŤ~+<¤ctű3g4<;ÂäźÓ>ѨŹ×vźRmÄţ8Vć}ćç¶â|ŐS:ˇěą*“Óß{JĘçötíţQ3oő”–ÁÔ#ż‰cúźú~,˙?)4ë¬ÔĎáC¤ÖQę^ąŻ·~OóŻ:;w˝ŮӾ܉sÚ—SRŔŘ0uçţ6n I' ż®ĎôŢdčeŠ}ąŹjWu\€1ňd3ŚĚÓÉýý]áăX×ńí¸Š?ľŻmŘQůłĐôhsóÖú=~Ă#-J›ÂOAěĺÔ]őżč›NúěuCW 0‡bgűI}ă—˛ÓFß aŕ—ÝGYÝk Ín[x>_˙Ł«ĺßžXÇľ,é'<˙Ň|hŻ­TŠÚFŃť>őĽOů«/w…`0đůpӓ‡ŮW/0üH{îhôY›(›ň=ꇢQĺ§,ś(U^ q©M˝°ř.e’RĺtŘx˙S—Ź·7čpüĽvŰcćAôÚž‰j{Mđ)půüÂź(mląĐŤé#\ýCőSŽcśWťyë5áabń/ÔC˛ q+UĆĎjÍÜ%XF´ fĚ?ŇKąş“Ą…ĆF&ZfkĽţ„w pk8áŮ*ôm§‹i4'‰“^QA˙ÎľÜÎ’ׄ©Çä~¦w SÖţôĄâŇÆs&ŢÓc“sf΋·Í´ëfş+zw\§ü:´Ís˛đ:ÖŰbťs°©CŽ‘ä ŽŐä+ÖˇŞG¦˛ˇń”?$Sđg.µţÔZÓ€˘ ¬Űľ\Zűb´üĐŁ|đů^ńÚíáÓ{¬č»Ď†M癪O f«C/ë á9Ő´Kfí#đ›JŢ‹ä[`|Úý”ßTTPżDúh'»Ş#gúź…ŽţŕMޱ„w6ěŕÚ_ÖŇ«w–şőěŻÚW§6Ąx•¬™(űA· UŃöRFŚ7Ć·_ż«Ď”Et{“ÇÓ麀µű^R'˙ đý›Ň÷`ŕŮ ű’Ö=ńţĚě“á9ÉYđŽAŞ0Ë»ď–ń@ĄÍ·Ć~„RvlÂó4lϵ?qšÓ›žâ×%syM{$!ţޡTkmÂĹ<úPĂŰoźŠúř[€xş_ęRUç±Ó{4Ę˙jýĽ8±¶ő' Wř{J‡J{ëxĂä-ý őĆĽÖ>}Ü #˝nůDż»>g˝>ăx·ţaÝŢ›3ňŰ–ýÉçČű75`Ś­é˝퇾» gd¸é-čx´ůQó·* đżd€N©q­Ĺ'O:˝+ŤoZ¦w{`ČŇ_Oń9źł\<óŔZSxÄJeú»z˛~˙Ď?ëµý# âë.‘ĆLď]v™µ>ü‘ݵšwř«äA™J§Ťî%eí)ý^ĘŇWT\dŕ) »Ç&…4·•tU`ę”iď ýk+éGM_€´ˇ ľş‘.4óÓpÓŮŔâ:Ú<×ĺYźóîg·uËhßÍ>ž~VŔR“|­ÔwMţ‰Ă"¦O|™~pŔăü°‰•|Ëô§ĺ—ÔyqC§ÎS·§ŤK'úŽ×ěăÝ5ŇŻô»ăuvAĐ?\Ž ëĎlbŰę>ÖźľqÎ?lhcŢĐÖ·¶áĘî€čJ0/±Ťc‘}xkŁĎŔÓ°e˙;x`ŞđçpSĐč=áźbĆ5o¶Úđ±ę‰çEą§č†źj·U<îQSçcˇřEíđ ăMŮkNňŁĂN¶p„Ż Bw0ôäTř^[ťčńCwçž|÷’2OŞh0óó=Đ—¨~©úµ^ “ZŢť›¸Ö÷öŰ-łXîöČď$/Oq/‰uO} ď÷”ęŕ='x’—}Źýůdě1Ü,zFţËÁůD­ÍŐر >í‘ŢŔ‚ČŇ÷N@ĽĘgđ«Ŕ:÷&ĐüDMj`yuUľmu ©UEŁ›^…ÓB9GÉĎůÖoWgű§JżđgŞ…Ďá ýĘ9Ŕ ů}pZŢŮ×…O!úG0ü źö­7ű]»^ÇB1żU´ŞT°ÎzęVÓµ|Jŕ ß?˙)Đď*˝>úB5ä&_úďRfÄ ĎÝÖ84nšÝéC^oĄ~T“đěä/4ýxv{äc2Ż˘á™¦5X—ü cÔaÔŹ SŢěO«ý€„çhkµĚeîňníÓîYŽřÚ·@ÇsđĐPěβ>ËT»KÄ°Łžäč,><Űšq¨/—~íűĚ!…M¸n[·G~ŞXđ°¤ÁtxżÜŚ3ł·Iž¨“wúř˘}¦‘8Rc_K©<Ý˙Yź\Wňp2ę;˝í’w©˛Żae÷RńáÖú:Ä4oľü=YÚ¨ĐtKC ör±:Ě!ëŇË{Đç ď$ w•ÍUŔěŻ^Döúž"¶yMöA%Ý?|mĺÉöC°îűڬŰF®]Ý4¬ď5ö$¤L•ůí¤­ą‡Á4ff)´cźAÚX5«:ö NŞŘV~Ż­Ľňóíľ0:˝¤YŤß\_?¸'‹…/ çÚtYˇf­_{Á.¦N8š>%i«5ĄN_1Öł˛Źá‡kĘún[Ď Ę}‘pD›ČĐnşÍŚ×¤Źë¨W|ߦ˾aĹެzÝ|Gď•Áa`qßynč Bď$u Ý”á˙iůŕţQ’ŻCÓż±ŕďz[tëµ:S_99cĘÁߥʝĄ| Ďîr.çgľˇŘËçDĹßśÔ‹Âť§ ëěýč÷K•?–ôâ–ÂŐ÷Oń…/ôďŤu&†N¸^†ß¬ÔÍÁä1‹P˙Q`1Ľ‰˝C®yşłDáŐA_+ĺÎĹľjó{EĹÄ-jŹ8-đź4iCYÓś|HhjżďE“ŹÎ›gĆjŕ95Ŕ}Ţń=°!ĺěöšň&<“°~ś†±zZc‹”)Y¸Cčěľ]Çń%ßÚeŢg‰°§8‚±öM9ömqK¦*¤‘Ĺř0/°7ů2đnŽÎâ}őžâĺĐý]^yu¶ŻőÉ­Wľfž+»oG¬©Řć5Šř 6ď~»Ś&ľ{Šg d±×Ě|Ĺ{<Ľźč·¸Ô2'ĺőĎ0Ţëë„GáĂfÁßś<©L®©Ęż*ÉzC饀y˝q7ơpĐ×€Űű ›Î[ĄÍ€1ŠÍßörikŘÉČÜší)żűroăŇW “ď"{ő¤7沋Ţ´đtş˘¶Ó»vöęÖéłó˝ şřŁÉ’F¶c—ŕř†s Őş—°çŚé?b¦Éµr4Ú#űäĚ»9™Ú1_[ř¦c­P—íčŞE÷C^y™ßűÝ´×$lkę=ĹC ŹxłKäÚ›ý¶ôßHâ Čq ű3_¨vŻÍWÜĺ÷ťŢÝÍ÷ĚgăJGĆô3˝żÇzf{á«HâgŔěM—}@čK&×ÇČR|_ŰŚQvr뇡ăoľ}­ş›ŇgKż8ĹszÝŞŽ S_©Űˇ…bOÉąc(v2ňßů‰eX÷Px¤¬kĘ|Ú> ú]ě+Ě5}25p ěJ¬uú4Ók‹ďćš’ruŰz}śP1‚TžOg‘I/Óű!sť,,¶ŰwSĐËŇ(Đ*mśÚ?kćľţŽuÇѸwlA®….ăŁÓçseCâ`3óž>€çëÇľ'ęëzěóž/ă0U…ŢžŇQ°tô" ‹Fą±ĎÔ{W˝“*n%VTÍXkŔ¦q`Ł`ú qGK•_Ć:űdô}źEťŞú` ”}ۗ˱ú,`ËËs`J•ᕺuQ›Zť~4š"Î&öZ/şÖřVź“ßW·žf ČĐŔIZ!ĺć}ʛܠlnĄ{‡1¨ 2ç›°‰ @úSIß›}Z°zU_ÚT<­©Őçň|űÓ[s’XTz}Sľ_¨żÓqŞÔ¸ mVv7aŢ© ŢŐ}2Ö%jî×x6ë ÷»Óô+'±M~Ą0x¬ÔvŔ=ó_‚ľś˛‘ĂZX# ·“EsŤW‚)8\MĄězů´aĎ} ý“-Ěw¦_¨1ns —ĄäAyÚ{€ŇqUT Ö´•ňF٧!ƦÚ3oŹś%÷”mÓr3Ţg;N’q zmŕŮô‰üAÜL`4Ëű—Q•ă¤óQ%ż˙]Ňv”[¸OA™eäžt‡öřË}Xgžg´= »<ĂMr­CÝO6§kÍ*ž Ö<ëŚQŔ¶µÖř<đąůâ«ěýöĄ2ľ…•Ťß\Ł«ţ»9Ń÷neqh§\Ť=»´ëç* ÄÁ’yŹúŕĹ«˙kö>޻屹?Ó4ęł*ŻłW§ďóö×DÇGĚtŘBÁ/ŞüŢň÷e×V®.\áßŰćHBűOnî´«ňezÄţđĂÚßw4Ţ‹EÁeĐísĎŠ¶Úć¸ű ŮŽiěŐ‹nŚzDěcž-­ęu^:Žą.ŰŹşýHb¦čşxźú\ꪹoŁm…žÓl>P_ fĹ‹ĘîńÉŘbŞ´ÇëżŢ—ěËĄś ĎĹŘźĽ_tÓz?yŃŠçá¦ßKź¦m4»ÄŮ]0÷¶xż*†¤żŁý-Ś*÷W›îZÇnŤ«8VĚ™včŻfĎ´/wö#±—ˇâ«éŇÁ§Ă˘rOéšđPlOřmo×ppBĹ ŇďŻő5ü\`/ýËPâ#§žŃĎ6ĺYď3ÁÎĺpĆŕŤ›}E–±Őä7ęCę‚{ĺmń%aú(ô”¶ ncTTLF|ĺ×ĺťć¤˛×ˇýľ7ŰĽź»ÇůME3őĐw0ćHy:˝đŹ Ě,Ë=)< ߢZŘ2"ĘEď'® .9ćRđü«Îţ“SâŞü;ű<®F¬¨á¦ť¬Ą…éov°}.©ůÁů~c^‘§éóÎţXBlVř•µô÷˛çÄ2sĂ\#Ž3b^(Śćä?BÜ·‚Ýö2{…`;(c5âŠ[ ¦Á÷R*lŃ÷}Äß»40?z1b0ܸÉřś{PäOţył Ă:Îc¦÷–Çđu¶##|š,dŕßLtu}ۇą÷Ěżxţj%ÎÚ+Ä}ŕeÁţűϨ—+O’íX#iźíOŕN Í;¨ţžíč3Ľ˘ç8ťöĆ8k˙ž÷“öpÓŢ Ŕ‹«ź™ýl`RĹWÂśĎn…Mż%osţć8 ˙@`o¨Ř‘đY±zNţÚđ†?`żQ×—ŰŐü®.ĘŹ<Ę®®?ýb+Ý}ĽŤutµ 7=»řiŕ-s˝Ó; | ;ĽŔź9MĘeĄţPSôu›2ÎŹ~WÚŰ‚ýlÍĄ˝ésČqOĎe“UL7í;č¦`°»Sx=”ÚżX’–ľŤ{ u;Ökî13ŤˇŘÖđHÂŕ;’[üÔŘŞIąç>Ëa7ł“<ŠÍ3żC,[‹}“ňy’ňíĄÜ6SSËö&Wu\aú ÓŔ^ĽI±Ioń‚Đeŕ™ľÜ­­É“äŃdAaM°úč)]RÓé]bĘ»±şReŢ”QËß|źóy[űĽĂf3Ô]:sůB3ctw7ćZ“żű‘Gůl,üŔŚ__hgÇçăyP.ÂÜcuţgWkđ7Ĺ·Ą=2#Ľ¸¤|™™WsňëŔŠHÍvÜ*e…­2~;s7í%úrţ¦öge^Ëd-Ä[I ě˛R_B<Ôk`c1WúâÍ3Ö9d<éO:投ú˘üľĎĆŹfÇŽžifzom ,ČkÚ˙đÜ›ű&ÖmҦŕO´ÁˇĎł;ůgř¨…q×cevQ؝ĆS~tŞ.âÖůôcB T…#Ašßö&Ěü7»AęOÇ6g~<Ó[]ŃŢűëćZßËqĂaÓĂö€ śjť^©ňÉ 5ŁAsŤŘíÂG2ОŐĽ¦GęqÖ±^JŔßđ2¤Ez5Íáw,/â@ 0żţt-â%%%-5öuµŔ'Ĺíđ'řŔ¤ŃśTöşŁ—Ăů–~’ÄB€m¬đS4Úo!Ö°đŠŢýpŽ´łJ§ ~ývţ٧üţîv!¦Ţ?M_ÁÚ,B·ÓJÎ"Ž”¸®NźUt“JÚľŁ¦]×ř¦aě){küvŮżuÁfj«Ź3]ćŻ.şx§üčµc3Î.ü‹óő=ÓgĘß|żżş žőôű˘\0Ř­0ű S@ţŰĂ*ÖV.0˛ć)Ô·j/µöŃt_ »ţŻHž`Ńľ›ş˘AŘ=źhÓ[!uĺĎdáýIS×ŃčđźµŕŁdÚQŹ˙ě'njĐ.ć;÷ý÷{MŰ´öÓ9Yř˛äI™ŚPťŢs„Ď(Cj˝Ó¶•Ý–ŞOłďţďđŮŔĺ™–ż, ,¬°öÁdýP6uűX7'w n_ÁúĄkgiÁÉżä÷ĺ;¬WLS)¬ß˙¦¤ŠuĚŻŘOB© Ą{:áą¶×[™ňUg”<Íw•"ë‚dááůQŐ©;ĺ+zXüĂ—üŽş`@Ę7Eß«yźőÎł>VvďŤyó“·ľ?/ţYř>(ĚQ}o}ĎžbOhEď]R—đŰĽü݆…ÖiőđGh(úfÁ·2łLťŢeĂO—w!s–ůń"–&đ)ë]ô©1Ťýą/§ř`pňAv;ó®ÇĐË2ç[â:{äšńŕ%?MűHsň•1µs(u”ŚűUůYR§Í;ěŐ€ľZ·N Ä"o{s×Ij–ÇSü•ĽăÍľ L–+|đ]‡Nk?¬­v,kŹrý}Y¦‡±—rN~‡˛Ţ*cée?Đş‹lGÖ¤ ¬#`ô(Śď×+ß!]3ďç<*ť{ç^FěÚíÄÉŃ_µĹgš|y/Ó;lžńw{DůŤú÷T|+‹cp ¤\÷86ń/Uz&`†™6Ž[ź5×îńt°űécžâĹ&żPjKsÍĽ7ôčÚăh[t/Öđźśs0+Ôü9ÔĚ#§xvvDżđY{¤Ţ”~fđ ŰCîS¦TsüÇK×‰Ż «8 Š×u93żKWű2×K˙XÝ:Ť±uá [: ¸!8ć% 3}ýĆČx:Ťń8CÎÁšév`Ö^/yÍI^(őZ•˙¨ÔůB«VňµRóüŔ—÷a ]Óźž#÷Př†téż ×µÂwd M%ř&T|˙ÚĘ/ ^ŃŇÂŁ¦nŐaú/ôDć:űŞZ_LË·ÜřScĄ›ü§ĺﶸ’á/W7üüŻţ=?góÚ µÝ~ńë„o#|<ëLyz5ÝΙcOÜz}č`CG:}¬«2ł!·I{ĂO«XĎđ7‡NFá××ev1<Ąé+źăőÝő;SwĄä%%SA‡cxę˝R*wF]ű˘s…ÖŮ;Ń­ç˘á&…wČt±6–v~Ů—1~¦€íUiu…ýŹ?@˙z‰?CSě±ŃÎă˝Jö^Ď»€·ú#·GŁ’ń'5đě[¨śźÝôÓP݉€ź%Ľ‘,t•aq±”Ř߬Om™ý®EyÖ- ŃÚYÇľMďőĽËđ4đĎź##‰„żŕűlîA.¨†ŻŁĐŚ1ßŰ^vÓËk®C Ŕ™aIJ•˙®Ĺ–đóPě*ÝĘ÷Šď¸÷{ßŔúĆ=¦óůřO o­ęH–µí`÷ Če§+°OĘ ßĆZŕ˘ăOő;…E즹˘ÂÁÉŃ÷ť’&Ó´-ć °Z'(Q+•ľM}ß÷gî¨-UVV#Ć™đ5öN$m` Ęü~—´v…®„ď#V†M÷řň5ÓľçŽ;ÇŚU÷HY•^ŠX2çaťą»ôc®«ň­ź’2óŰ×+§ Ü]ÇżB,k‘a9Çđll{ˇĺď ,-t>á3},Ëý¸ě>eÚ)p\éËý>§ÓĆa-Ąs+?C-iS°ĺ3žąß„ŽĘ–?çűwÍ5žQżÔ-łßąyÜťŻ“ĹżŔ%„Ě©ä0ާ\M˝‹Ţ7Ὅs¨9…mŰSrô"Ě řBŘ_ŮsĘ͵1¬ťy±oŚÜČßŃč6!¶Ť[†  ď–§`jQ‡uT5ÚÎđ żĺ‘N—ďąuŞęŤŤóźsőLk;9ó0ćz°ű\éÓC±˙T—*˙.×=ĄNŚŰŤđż^ŢăxÎ~-ő‡:Ô: Ąß"Łśý™ëë'+Y¨:ăŕ‡2Ďńž›TšŁýď‚ ç6aµźî<żŁ7gË [Xóâ÷5xł»ĚŘ‘Ě = ýŔPěQ3Şň*˝ůxćň űo5‡ä[¦LZ3V:ąńţtôłń·Üy¸ŻŰ#/IżŠÝ‹ůußôBS€˝â~gäőIŢź†ôÚ–ş$Gý7Ă«`Ź1ç­=…/ / ’ü™ÂíµĎ÷20ßűÓ6üĐsµůfd>ď÷şűÝ”9ŘO±ۢ=ťË=¦M—Ôşň°Ř•Oťk?ÄÄ—Ú˶R/4xŠ;ÖaßŐĚu´kŐ2ꦶS6˝›®ŤuŢ<'<!FŢ-Ŕř’u0p&ś¶SvËîw×ř^“ůćgŹn9ôb_“XI´#qż—‹-’÷ć1Ć ęv˘Rwµ°G`×ăCŻ»śE_†x1y–´p±_¬‘߉ĽPô9ëŔ˝°ďü岾,¨Ř.ÝŇ?ČÔw0-îLŞŠýČ6zőĽýrĹ۲–÷bGÉlSŠ~ôu-+©šÂvnó đí Źśü­ă‰$|X+-?@ŰU)Y˝«ĺϨă×]ŰÜ5÷č”Jíc¶Ĺ/ aľ6˛°.Ç0˝żIzÚí9Źq$ŁŃörc_Tă»đ;5‡}đĽ¬i(?ł\ęŹí2E0w”vÓs °‹-Ę_ŽnŚ{7Řńm8Çź$žeöe-——çł9ţRt+;”Żť6űzÜ:2ÄqO•ZµÝöŔŐ"ź“Ćrjt–ßÝ|éň*ÜDÝţ,Żš{ÔsŐŢjŹł«EÇNa;kŢŘ|i|Ż’9uPNË;ÝŻô&žOÔŔD LÔŔD LÔŔD LÔŔD LÔŔD LÔŔD LÔŔ˙R čő1¬±#őaÄď’˝€r ő;Óşć›ăľ‡\ž×ĆűĄ}ŃâV9ôBeűÇí9±ctë…菸©öŢĆŁ¸7ÁýQ¦uö4üOhqé>ŃűńőBZŹK} uĄÜGnŹ|úë)¦>°—+:3ťżÝÜĺÓË}ŤÉŢ.őąŘ‡<ŘŃ3—ýĘtżÔ×ă=ŘóFmť ú*ßúEÄŽů7ügo QwŽřťárűgťúwľmŤÖŠÍÁÚ ^ýt–fJq/Ä›ý˧„&Ä;h“ś¤ÎžíͰB˙ţó¨{{j/]ŃŐśśRţ'ěűěÁľ'qŐPŚI°Ťx>şDnűÖAŘ™đ~Oi.tý÷JŚfżöąčq°JK4'zěË©ý۶ř+'4,öß:ŹâŤ¶‡ž‚ţŢ­ËŠ©ŘI'ĽŤ~·¶řu°gÄ>jPĆmâ+éoÚý;ö‡Ť‘UßSş@öťłC¨Ąě=KŸZpßkq+üęvłcůmZŠ9§ř3–´ý,8îÂqz/6ňßD{Ý _˙ź!ťŠo\qئ~>Ě9ŚUz~˘MÜdŘ»ŰŐçM_Ńűˇý$ďGĂÜďa_`3łű ŹĽ*ľZ›šĎ‰‡69„ŠfüéË){Ö>â6ËňÜÄCh?çX· ËÎń‹ú|bëčű#ĎEßß`CęřéX9|o°{–Ô÷Čo6Öoî'q~aú°ă±fŰ82ŁĺW•_iÚŽĎi“šđ(|ŇŤÉížúÓ·›şă>üZ±­b łĚřÖ—« ´oń0ĆAĺăÁô¸ďÁóĆMFŽĺ=Ś×ŔäyÍÔ|ôL]bľ$>fhĽ×ßţĚm!Úw¨2«’A¦*+ďÎA6őTýG4|žđüľýĆs%‡ŃžFŹăk|@Ö\ Ě´'Mšéôr3N»Óü…m;žđĐ^ěqÄ…Ţ!Ě>DŮÁýކ\síŹ1 Ďb\™¸j ŘO{c˝´]pme50•®®Č/áW¤bť{ł)Ĥ>_ĆgEWy®ŔżĂ‘kEóPL­“!WŹĹÔ pôÄ–Š_čŠýC¬.Ţ[\zĆ´7“^žŁOüŇ{[w!Žöś00žĘúÓçŃSz¶ŠŹ‹oLö¶»¤}ňŹ„Ëhf,ŞRĺĂKr·2ŔłĐs ×& ÓđDUţ që#v>ŞN‡?óiŕQÜP3-˙Ńęá¦?Öxłgˇ]ěŞźŠŠj¬_ř.Ťű¤~mČĄËŕX«ĺ®tz)WsRůj'۰CÚ ľcźŽÖMaĘČZĆĆš U°YĽx)â¶ _uN ŹŇÖ*Č壶“*›CŻćyČܦnřř[ľ'Ž’—ó=u‹l·NiChî¶ÇCŕ7™˛{6ęŔUU8;V*eŃ'5qŘ_Âk+†Ř–ć]w[«kUŠ\ě*Ă#Ű×ýŢľ†žÜYÖ›ś×Ú#_ =»*čďžáĘCĄą¶ňkUÇçxChŐß#]ű±ë{…Ľgâ®®n}ş–0ün=´/:ů¨ÔAÜ:ü*űži¬ĎˇtŤě»l¦ş‘…Bc$ń9S†č)UÁONŤŁkeMPy÷4«ů­ëÂw]Ů<;éZˇů%[ŹĆ<ÇCzŐz’rý‹ŔZW˛ 0OËře°űĺżű1\&ôZ©ťä>𬠭­úÝU§:űĽK ·˛rč÷ˇ—6÷;˝ż…LőśŕŐ]ö›ŻŮô¨6ĺ¸Oň”MĹätÚšt,Üň °đ~jÖSŢěLÚyĂŹáőúţt'ÖUۧĺgŮ´î/s%bʉVM>·0o˝UęxµşMyřŽ{¬Ä<]˙¨+ő+k9¶¨˝7딝{ś…)ĺηŢ)ßÂWQä®Nď§‘ĺÔĐMéŹJ—öogź‡lcÚI精g¬eM?îfmÜj©ĎŶ0ëF¦·ş5<Ç_qĄÓ{bÍwĽYÔKź}ϡMµ)żyŹż‰c0ϤĂß+»O–úťRüĐŤ:s=ź{Š‘÷K•J‡Ŕ{c9Ô^™“‚7[kxţUÂSŔŁ–{‘ÄłŕÇ}ĺ^ľő`ŕtÔH[ezAY}ô±â5äÓĎő3%“:yé+`'Išü ˝ôŰ· Ť˙ë€ycžaţŃ”Ożľç滾„q´`Ć ~Ť*LMoö_uͤ˝'UüýLáÇÇ­§}©3ŤśXhÚ"Ä1PÓ¦ĎĎ>ËŘ N[—ŽčśÔŔ%Rnč›üŘ»Ş¶R­†.ćśěg\Čv|QĘŐ—;YžS;ńn×/ßűśÖuô-HuL…ŻÜ,ĚŃ—Ö[§Žůjöéfů÷|ŮřIĆW~)¤üAúH«?ŁďWTÄ­5XV7śâ9¬fďä1ł°›=Ü4Ą{¦/Ąn7ů1ßhôMůŤuH n±=ŢřC±)ŁŽ ÷„‡™KÂój™N {V ™Ţç-ËÜÝ®ë^‡űÓ;„nH§kˇß4é vo=úĂ7ĚóF ŘžĽć±¸ôUč UáńˇYĎ'*ýöČŐX?·B]É8ßŕ±ĺÂ[ůÖçĄ-0ćĚâ›Ŕ5<©öśu{*lŽui®¨x,v©u°MC©™yˇíů(đ©Ľć·*…Ň)ň:ߪ|łŻŤc«˛şýtľzŚ“ŕlW¨Ří|Ţ—[ŇÍŚŤĂ{ęčjÉôzÍďlÇÎÂĎđ=…Żü…ŢţôUeyń;gźĐđ‹ťŢŘNÔ±[úxG–…l(ůŻ­ś#gĚ+uŘŹKŹüÎĹCŕ č>˙ζ”včÍíjä›á¦+X‡fěôničei‹ľç0ößë·R[až„9˘„˝«$1@L{Sñ‚ú -ĎŹŤRçkÎÓ”ŢkmJT›NŞXć^CÜ:Ut\Ýbôđm@UúiĂţgţ‘şHâ|Ä ŮŇĽÇ8^›3O°]ÇŔě/Ŕvßčy—™ëßťľn=mçøťĽ×ŮNös¶l/@˝żyőî÷Ó_v%ĐMoĚÇvŽĺţF …¦)ŘĂ;ʦSůV’'ň˙Č„ţŘúMŘěN®¦–Iýź>R´ĹŘx>˝UÄžX˝•7ÍZUž>“ę(ú^ˇź0đ+Ş„vŽezď¦9 ›Ŕms°·ă~…~ß‹w}ů´Čđ cäô”ľ _Ě7éžł.“s.ç7ÄB4}‘zŰBS‡ĐQ•±¦‚¦­aWnóxů÷NşęjiˇOľˇM÷¸ţÔú| ż]9^ÄČo6öoesĎ\f_ Řř Ýs’o[Ń'>VÖů&¶ŇM˝°­ű`‹8”Bâ|É3đ p˛ Í;(| ~ÇCŮ«ëflSm¤m#ôţ‹.Q§·ĹĐĆ{ˇÔŃđ‘ü:â[ř‚,»?SŰČ9jć÷¶oqyÇ?¦Ă}xřąX‹ď¬šç&~ ;¬}›WŐKľ5čvb'ˇż7Ęţ&żŰ¸‡Úo¦…Ć kJ$óíË퍽ÖKm{‚~ˇ™cňŕä°o®bT·G®DLîÉaĘ7Ą§Í ­‡Âôdße˙€Ý0ä—#ĚIĽŠqđBkZţđFřÇšńq¸©ßżű¸0Öú í 0CĚxʱţn6¶”“úĚlަč;UÚŠó0°‰Âł3»H<Ä˝˙JHíwŠľlŇŽFBsţŤ4âY)żXň ëŠuĂ}~ćż1í,Ü>óMÉc‡í4đă~đy»‚|Ů€řtbçă¶QťTAçĐľŢěAaµ‡®žŻAh…o•eĄh㮎á¦L[wŠquô3÷y¸pŚ‘eÝ÷Çăqţ,Ć%áë\§éĎbŹ˝ŞmŹ\[ŤńŞvukśńŔĄŚämW5©â)đî‰}t)|˘ďEĆŚďđŮ tď-ńęB»“čÝř¦”Ő黿˝ľOUźćF »TNX(Ţ5Lţ"ýýéť'}cş±aCÔ˝Úiů*ˇ…~}#ń$(Sé1żńRVýe )ű)žŁ,âłP–łvźihĆx¶é©7Αäm7«[żrŰ »źmȵňkuľĚvś"c,ěŔ0žÖ™rM)^[ŰźŽÔb°/ŕIŰóËžŇ ňyCő?5:©:WŚ%>ŘýŤ˛öË·*ů„o!N«<ý°_DĚŇ”Gă{9)mřU©ňî0윤Ě3ŕŰnú›;U`•řáűfl<1I»ĂĆ[ʤ޽WĘ«é&ź´ĹŹ Ńź>p°wţ'üЦ}ů |©¤y=Ą¨lăŕ/»ńka'üYřÎm!k85~Źß^ô|,¶(@[ ćMą‚ôóÚ}Ä­>3ćđ~{DĹ?çőpÓ®đi>̦_ĘÜÇ_>I ,ç$ď€ďE 0«>ëlᕸ5 öú é±’>h–3ËŁÇEćˇ|yµáÇrř-k,6¬{ =:SnNŢ!m›ířxűđ›’'t®ŮŽIąa;$ç¶řŰ SŮëwŢzűÔ´k5ć3&·hĺäăžO6ůvz“çŮŽÇ ďŔżOx<9ĺîQyPçó~ĎzlŔz8•“żGĽâz_¦Wl­Ń—[rIĂMç® :””‡kă¶řő°“Ú%ÜÜ6Ö!‘ÄByî.Kj€iŁŢz&dqmŻŢ€Í~M[ü˙L˝Ŕ®VĘŤž%ő™đ†4–;ÍőżV˛&igz\/SÎĐëäII~L<¨çĚ—äß.ŘC^-u?Đ­ÚËž—C >XŁ´‹úÎ]NŘÇK˝.>ůwXŻó€\ţaÓ70¦ĘµmOéţ|˝Żµ-“ţ0rd3|%űÖiźĄ…OJýn+ȦóJŃ7óńěÄ$”ňŢŹ±kRĹy†Ţą …I ë‰ç)Ĺűðů5|ŐSúq]çź/‘ď)DZîoÇŰľŘÂ,Ł[nĐe^ßsú‹¦lü–ň0řq¶ksPáÎŔĎHúÜĚěĎM›»ËŻó\[ąČ´ďšv÷—ScçˇŰgçRüĆ/ĺ_Ý~ß6FĄßxDä#ĺ›čÓôóő;SyMY›vz·łöL#4®­\墑ؔ{§őMč3vŤćßěθdđ›ş6ßűÚé;ôr+ú”Ťśűř”ŐĆOágĺŞŢm>q§ń^×ěłĂM·`| ń.U–źű[ĚÁŹŘjÓň_—z‰µňöۧJŰyŠ ­­<Ó:čśm€ĺrChRĹ÷mť·C3l 3˛˝ä—íXQÍXŽVŕ$›Hç]ôŤľ~ Ý úŤéŰúů†ś)#ľÓwĐÍ™ńsEﭵݿ§˙üŢźŔ:čëv?tčĐĽţÖŰ˙&έ“nů;ô9FÜöQË_µŰTĂWđoĂz3"őrSşNřőbúż“ţú]qüňf—O?×ËZ&Ń©'ÜĚťúĎűA·‘íŘÍWĘiR´WŔź°ş×}FĽKŕżÂÎ˙9ř%ZFs§ŻŻŰ#ýÁĚobTţG[ĆLłžKŘn™Ţé›HüŹó-¬#‰VWŞürM¶ăsB7|ČL»ë2©óştĹ­_…·Ołŕ3nx>ěBópSÄ´o{d¸®Ó»ş~AäăőđĄ1Žfśń¶\?Řqʨ |ń.?úŁ8‘5Ť©y¦Ö÷ĺô}ËĂ˙1ţîg*'ŔbHťS©Ě¶ţŔMý>Ú|`€xĺ®Cˇ;Ă>ÇöŘ=,Důldy7ô·žë{JĎŔßíËX38Éî4c‘Ëି¤ëámŤ¤ÚQÓ§żĐżőYß'ßN^iNöĎĆBr¶7{Žü†ţ}xč’w­?°— jť‹úšiŤíŕ­ă°ĂwJč(úfYÉc†ˇú$čoŁż·• φ˙PYŰ8ţ2ëŇĺ”Ńy¶¶2ěüóꇞĽ¸{ą’Vľ5)<“đ̬ŹŘ#©‚ükAĎżŽ\:ň˝÷÷[Őے¶ŇĎŔo!Ž‘ŢěP(˙ČŐĂ„żů+Ä;Í)ßPěěę˘ď=žYożý¶ě5łť3˝ĘřŚŕMźyě±ĐpÓÎfÎJÎ4ó”µűáµÍÉkĘęţhŔ;^öúÓg›wI‡7»—Ťkôţ¨z÷·şZč©÷*CÚyÁŚ3Śá0Üt7üý¶¨›› î9ŔÖxŘŁç×ÓGPé;U˝ĄöźoĆTt~éŹÍI…ŤŻőz‘„ e™˘Ń%F×Tu©ÚŰ;ÉűŰÖ‡s Ąű\Ť­?wZŢßÓc§/ýăb5ělaţ€ŢódžćîŇF€ďśôąNď·ja7?ďźâŮ~Ť»SC/t.ćű‘ĄČôŢ˙Đ{íľ\/gľÓ”<˝ŢźyÄäĹ{+ w}Ű7rN®ĘźnŇçł±C±F¤ý¬—&aŻí2ĂSŕŲ˛c‡Ü]’ő}ľőáďůŃéë”%ßzOk_`U—ŃL?čRo¬Ë˙# ,©>ÓĆqëŐ˛y ř’Ŕ˙yöĄ!s˙x›[5Ş9JńÓXéĺ÷Ätl‹o ¦Ž‚ľQaĐtz«m™Cĺ™sć@çSÖˇX‡đ/߀ľË~_ÉáŚýÂ5#ôµŔ{éjH§ď–wá[(ß{ł2m<Ř˝Cp^|;ř'ĐýşĘQýç-{bŁĚýtĂŻĎ Î ·@ľ–vÁŢKö4€/ţČF Ď{gŐXSU÷§/•2CÇQ·n?¦‚ťËű°ż¨pwU)¤=„fţF,{S7ę9űňżLÝ‘®ćä?ĘxBżÇł•Rřî{ăqÝ9Ux:áy”o°;)倶§%+č¶gÁÝ]®´öÚ±Źst¸ĎI_ŕ¸Ďő °‰‚“*n"^x=üi ˙§Ó‡ů׏ńQć( !‚Y \řVźfĄKV•o6ý 6YcĆ2­Ž’…߇¬Ě.†6(Ĺ ßYęˇ=r‹đřWú2ćjÁéxş)éëË­‘o°˙"4q݇ţ”­ăVů~óť™˝ :ßA?ú*p?~Q˝™ŕ®p|η6°Ž oĎ­rÜ˝ŃJ>–{]qs†ż¨_äxŚ9ř4ˤ˝ăÖ2i·\_háQĆ+˘žIˢĘţ‹x\'JŇ×ŘÚ Ŕ>Ă|7ĂôeŘ^«^áü§˛×ĹH‡ľý™Ţ{±öŮ^ö®ÇBŮ;ŰŐB}%ź˙öÉp –ĐyÓ'ĚlĄNž÷gޤ=a?%ňDU~®ÔżŁ<ˇö€‡vöŠřČjżiľ3ňĐó¶ľ˙lÓ Ř·lý8ď% ŚS2~ăµÎÇ9—§=Ąř†´ŻŢăOŢwľq®ĽŮÄűg}iţÖzłâµű‡űrwŁ ŔÜ~V 1 ř%ű~/đ`‹ľ=%/'5^±<ĺe*>^żL>-ämµVäŢăśŔłŻÉŇßłĘSüŤÔAOéLčúÎ…Ž»X2ź˙Má.Az /§d÷‘%íOĎi˝u§÷8ákč&Q›‚^UęV_„>Ć`WL=ýŞ˘ű ÂÇŔRn>ˇl śň«ň•*w±ü™ď…Tě«!Ö‘óŽşňg^Á\üç†ęĚ.ő[Śů˙’wH·»aÓŃk—OäQ`lż‹FĘ”đÔJfđč—ĺtEŇĎťőU…Ěő”Ă1GËz+ŕy+|bíL)ž(ďĎĚvąK× ě.B\ç)ŢÚÔ4w ¶©. öď,ÄbB[˙8´ k&}źgčRě˛O_źg1† qŇI3ô>ĐťO bí…ůąŇĐŘ߲, ŘZI=P6áwłÚťĎ¦¸¦ĽŚ;»ť§˘MŻ”‚#óîO÷aźjO3vëçşóř ϲŻnűĎă$ÝůODĚÜČď8ž9¸™:ĄM{ąČý2–‹ëN­DĽ:#CpMŔ..÷_aŚkýU(58p“‚śŮŔ÷ÁůŃ‹–žş1–Űéljž­NJpĽ˘ŃĂĚ|Ý—[,ýŮý…·÷6čß/fĘűk|ÇĂz»PľuoiWŕóúŽYîÁź±ýfŘénôjŠX–.ěˇ+ŚŇÖř6Ŕ‘ŰVlý´Láßs©¶řŐ˘g!ÝĐ•ˇ#…n«z=…›®S\[Ů(4«ůHĄŻźm>ge ´d– şIÁŻKxÖJs űhçą˙CŮm€9 Řťg#6Ěí×<‹ôů°Ú'Ú\iu׺ÚÖw€ů&m·łŰ –c•Bv¤­ÓoVTÜmŰuĹNpĹIÝśxŮ)ëčW? ą…r±–±Ô{ íjěS|{36WĺżV{ć˙M´ŽVŠ?&ŹŽŹŁyv´óhiü/ÝűooĎ˙Ą¶ e˘&j`˘&j`˘&j`˘&j`˘&j`˘&j`˘6] `ßAöx´Ź„?sZXßÓĄ ˙#őHÔ R×íöżŐďlţgŤźNߙ〻î…-f%üUÖX­ńźý5u¸ÜËŕŢ“ň%¤ÚýŘżÚIôcŚ‘ ôĽ›3ĹJĎŁ÷fYŇ\ěľ0lĹŚÎ1$˛ż¬†Ťâ)÷ś?BßNÚš”m ż‹$:ô~čßőG,SWK[üĂŘwj†-ż`äĂż,_ľ#ŕK˛\ök`{Ś1ßZ¸Ů˙–č8/Fę„ţľ¤wEďtŘÜ= Úă-ö ŘN…aZć#Î÷>¸Ăi¶ç/6ňű_lű'coe˙-b ě'ô`żŠ1Éĺz°űĐ2÷BëiŮ{ěô:±h{ö4ę}ęŽF'gĆ˝EÜŘ~ľQż,—†íé. ł`_ěÖgĂć¦aEďŞbĚţÖ)pĽ*úÎďN]çß)úĽc[żź8ěłaDEÂ^ĎfOL?Űtg§ŤužůÖŻZ*îĹd٧ç3ę¶—fö"&m<«“>é=\Ţ#Ă×ŁŚ–}]cŇhŹx,ŰĎR˛Ňű¸:ßMsVô˛ďb/-Ôż(v†˙ŔVBü¬¤ßÂNö‚°WĆ>ą.WóŁ‹`7Úfđ ô}5Në_´•üŠĄ}×[ť{ĽW \#<Á#ýžś/7ƕӾś[iëĐ˙?ŚW‡Ăt‰ôÉ‘ą’fŘžH=ŔoWĘÍ=ę|ë)0­{\ÚÓ=oĂ6± ľ*őç)`[rŹ\3]úżŞýé]ŔNYFć9^ż‰m°kö|)ăPěAÝEî`đů¬ńJ…gl8C?yxBňŰ‹u@ź…i¨îQr®Ň~SŠ=Ś 5ůVíçó2Ć˝f`ô¬ˇ<#öiä/úcë}Ţń˘o´t†›oDüLŕţ|öů!©űą‰‡°Ź~l‹˙"4V͸ş>áŮżx%łŹ˛ë…±n?€ô*v8\:ź9ÉÉ˙G˙<řĂŔ#yHl2ĐΦţôsÖö=ÇĹĎF§ąîą«…<Ő—; ˙éçC‰łľ|‰ůBwućę†Ç6‹SëVv_Ľ° =oŘ–lG¶7ÓĹ»°·ů6ćóWđĄ’÷úrż7ô»ó†ż‰±ä}ĆRůŽ÷ôµ’Ľ»4cťű»ń¸ĆÜjŇf›ŃNKc®9Şóm™ l;Ąm`»"­śĂ~Ń}2h}JhÓ{îÄ'aůúrź‚ŻŢßס¶ÁŐůÖ»Ś Î[ożmú6űČZÄyŢćůń ÓIŁ«%á©Áü[lďRÄ+ů=䏅oioKĚ ç]çŞ=Ň*ń$ɇĽ›‹=&ďiŢĎŶ•ş„-¬Ô|]MZŕ#icÔ·©ĎĚ.űČűÚăĽ{a3®8%Řđ«Ţ\ ö˙Q‹¶¸ž˘v^ŕY‚ýéNÉ}»Á&ĹŽ25bMľ?ˇ¬±÷bÎUůĎÉěź„}{ŰâAeóňȱ?µ˙îB÷Â7šöĹře|Šň­Ę}·,´á”ę/»Z`#.´A–řŐ7çĹźĆ<ł=äć?Ŕ~ó”˛>§żÖˇiŢC>i#ŇJĚ4¶•Ó€˙XĚóţŞŽ{j`›ď_h]/uŮSşţ[bü~k´·«[Ď„ďĆ×ŕs˝â[ŢŐyŹń Ű·AáăŞü¦®5.gŰ Ç˝ €­”đÇ­ňńFŃYcú˘§x>l´›e^Őüî)®°€­6ąIčM üGŢ÷g,ůÝśü8â°î€¸ŤÝŐ°gŻ[Ń{%ü"orppÓ6^ňěĎĄŁŃb>QuŔbEżë3´—¶xÄĐ”đ81šż‰ĺA˙4ĎaëkËjĐĺíËUH?ŔZ±…»Ëu‘éÓÖŃ+`ç:~ ¸Ţ[ןţ Ö]K™"‰ph>â'͇})ě­Ě7:Ý =C®ç:BÚy(ĆţëŠýůéÓĽmńöšÇb÷ÍÖéĂ—˘l.ŤFů,`·a7žM‡çíhŰ9É71&~ń•O)°Á =č7*'Ó…/µ¤ź=Ĥ-;ŕăKĎľ’?ÉÄě1X“+|X]–±śá†zU1šČ“­ńoˇźÁĄ¦˙1}Ś?ň;ůř˝®ę¸®±č{ŮÔ?â—a>ţˇŕ^išuąVNţ<Ę˝ë¦ůˇ}“Çoôó„çăGXhú&lÍ&c,yĹ–y¨gHąl¬ôW~Ćş_üú™|e¬íŠ—CV¸/°M„múµâsąQř8ßZaËÂĺň°7űsÝ'FŘPUTo 2NŤ¬©áWŰL ŕ,}}WĹćdŢc¤ĐŻă ÇRöaĘ±Žť]yžün}Ž«”sé/Ăo±~ŞďË9ĄC±űjُm¦ßžäĄŻ óV¶řü~B—§ŐCv…śŞěxÁżO—"~4q@mŁľáűťŢÇáŹp0ô WÂOáa»y_ąŠ× ś2ÔżÂ%žŕŘDZ®3T˰I-ëŻ,ĂęÖçŤ˙Ç-Ć6Őĺ§?ěëfFß4ý6ßŇnţĚgíçú¦B›ÁňîĚěͶďŽăKż lEßăőŔ™~Đůśđ9|L^*•őűĎ>×7µĺWbr›ţŁďŤ5˝<ÓĎ*%ĎúÓţÚľăą? ův>üúcř«é)aę~u«ňSćwWą|Qů{}Ytď,tć®XŽF¦,¬C»–™öPLŸću4Z۸¦x˘đ7éˇ>4”šűUĺ miźÁîËŢQő…¶¸’/™ŹĄđçďô~Ż~Jń»µ©™óĄíłżž†SVźĂJ}6´˘w)—úrý˙kĘ‹\«r]ÁT—Ž´á‰8×VuOiŔđ+źĂß&xŐ@EXa :íw’w—ƸőK뱲ÍN“ÍCÎ;ü>YPXC©#:˝Ź .rG ĺZŕ˶ ţޱ98Žé~ÇoÇz赏?ÓbőśĽ3ęr¦´Múᆸuś™Oć&ÂŚ[Źu~ÜŐŻFđkW cc˛LMöZ BFĐ™S5ÝŞÔs?ÇüÁš«ń c ™«řFj Ěą#t bĚCn5eŻ×úł^«ÔCţră“@W_‹u¬´m˛đ(°SľLĄMzJiČRź—ľ¨âDkZş€Oío ĄŽ’2qŤĆ˛+ŢqŢá=f­|Ďk°ç–´1Áß˙~3?đY:ť6ďb=>:…O2tĹë!făŔĘřÄĽÜÖőBˇiŤ«-ÔoäŘäţ¸vű84ĎŹúBwŰrk|Ű›µK4: ~V»cݡđAt:ob=Íą™żc~ĚýY§«ĎŘ{˛ëTá9¦¦—ŐüĘüţ=» ż;ĐŚ©îq¬7÷VČS|Ö‚N'‹Ľ$ĺó— ÝšK•‹CđŰ’ď!ăŘóňËŐ©IőXÓš:`™Ž·/śű\ÇZ•_ďŽíČvě)>·óŁçľ2-ß/ôbMT=Ř˝ł´/Ę(gŕ±J»·Ćµn˛ËŕG˛$ÚĎ5ßZ#cj'µ·ü})[|emm¦wľŕBtVĂ·©úcŕ“+rř#9Öź´C(pń źŽýĐë\ťŇ”â’`{d–Ýž§B|ž»×H[ĚIjżvŐ†WLÍ…LĚą ëb)ߎŘű –öŞDćôg>!ş€zŠRgŔµńuz˙ęĎ·>Ulв6nŹlş2çSÎÔ˝(ü]±śYfú5^!őOüΡŘm†—r±ŰQî_Hů^_.)cw˛đ”Ý4ßňiů±,ÚäůMđAěÇńi¦wŤŐźŢ¶áĎö&Mć#ą2QʬźýnýÚJ?Ö“·b‘ŹÂ÷ň xż{ µűHyň‹XÔńŰŞüAŔqČZ>€ÝĎÚ+*Î3e\Ů}°wÂĐóß.ĎW·Ö47]?Şň˝)ŕÖř¶y’2v•đ:đŞ$-`yJŰ6'/4cóPěßŕçÓĺ=ŕşbM©öüúÓŰŹ¬­jqZč›Í_Ô×6%· AĄ ý鏼q¬ď̸՟ľOÚş=r‡Ľ‡öíĘ˙¤=BWu˛Szl›@?í ŚŽ0e#bŰP¶ŮßĆOÇŻě8¶ŠOjAĹ3ĐřĚWëhVôľ_żéz¦VcO óöĹ2εĹ÷:“…´ě;qź†}Oëíć$碽»!o!ďăŮŚ [Qşr°ÁĐ×ęÜŐ˛Ö–uŽ_qG™®¨ü˝őűŐSšbď1¨ľÉ˝p®-±ĆĽr›Őöý…tŞXŰůzJŰŐ”*Ő[»_'ĽIXŔn\jMÍ?"úO˝^Óß씯Ż_Ń{uÝâŇ"щ§rí+đţáëęĚQ’–ĆŢŃ߲ÝŐ~{ôý±žS?ЇbŹľěqôŹ {cUGüÄn†,öár#— 7]\ŰöüĹŔÔŁNČ9XgZ¸ňđÍóS<­ŐáÔ›& ýŐIŢß™Ľő˝öČ.R3łçăŮ;Ź•úýń9;ş±Hb™Ś;ŢěmF7Ć<0/—ĺ Ńjż–OÓĚw˘O<,e‡\ićŁćä$3&ň\O×" yź÷Şňß˝ÝÖĚěrŁóćýń8°7 ýâo„Ď8~ŘëÓ·âV3p™/÷ĂFHÚ}ÓźŃęBS¬q¤üđ™ uz'ë!Ž7´AaŮ€Ű5Śňłäođô˙cď[ŕ۬Ę˙;HŠrI‡ă’KďÉ› vť*Ң(d(`:@$C‡´(ŠZ  $ ´qÉ[:ä– ")€¨¤( á˘a’) )‚Ę˙ű}NÎÉ›nŘұýţy?źö}ó^Î9ĎsžóśŰó|÷„Şkëĺ$í±@lu\”_–!y±@ń>ÓŹz‹s8ě+›±ĘZq$ë¶Şę)©kć?+ň€¬ój~ŃĎ™kk+â3}şmcÍľyyňR©kbgb¬BśT‰żÁ1%ÇXG*ŃJwŹ˝Ĺtk2•¸[ś‘n¬J=¬ě?ÂĚy°+őŤ1¸ąGÚ±îë{˛ {Wö·ú5ď¸ć¶ú°¶źŔ2úNF®µ=żŚ†¶fžďPŐ=ö4ŔbŮř^y…ŹNŢ‚n«ęn…Ó óŔŘČč˘P`ŚK¦}ęwx&ť\‡ ťëă(áú¶ĆQçŰ 5™ÝD¦‡z'm‰űŹVěv‘'îß úŚ#>É*ÇFö´ËM~ö@ľ.o·łµ1•S·ëź*Ű ÄďróInĺ¨y^`ěČě7cm*5íŁ1Ţś\čżTyřÍřE9šg°Ý?íˇÍôśŘ¶Ř×jfG¦b=7iéń´®SňŽőÝ}öD‰ćĂĂ–´Ář÷ Ż4Ý®}ˇŔ;ްŹýę—÷­Ú÷ŇďŚ÷±)DŹpź…yˇŤJ9“˝ź1˛Ťőô×®&Ě…;Ę–„2Ę>Šm˛Íoc˘ýö6? ĽŇI;&†~ÎwôřF>₪9r‘÷úůxž'Ý»ě`ŘŔ¦«ĂČdŞ«8îXŹC-Ćč%gśŹ±Řu°ąŃđe+ĄéŁĐĎŻHŰŢö«vń Ćw0ú9âř*ěę^Ťă8˝69ž4®+mµvWUuÖ„iŁ­Ńk iĽoöu¤Ö7ĎÚv1Ś7ř°Ąűk`ńö÷Ěh ű8GÁ^VĹ‘ř`e,˙ŰO“̸„9°ŽŮŮsăţCGř<‘oŤQĽ8{żůnnŕ<`4ýr1E0¤ď öX&/Ďě§3߇1Á×͸Ϟö‡qÍą!b»ĚĐý®˝ ŘŻđĚn$ń¤yřŻ@<“źű\©mĺw_ţ/Ţ+1ľášcJ˝'ÍVÍŕ=m3gOűĂżVX:u‰JÝů7wŇÇÖ9ö× {ĹşÔçcîuÜăŮú0mgŁĆX›VGëR˝żłŠéÂr˛?ˇžcŮYO§»ę¤Í·F?»Łą~Ť3¤ă1ĐŢJ­spýÓőˇc)˝?ző[zl¤ĎěżsŘ÷9Ř·Wxăń ĽjĽ­ęmÜâFŤ!ő7ú¬ÓÜRÎŞÜÚŢ1–ÔřŚšžž¶‡1>QÔď)YŢRhüßĺ|őŐy2V/mźšÖ˙ýmĺi…T8Pá@…T8Pá@…T8Pá@…T8đ=mMř˘ěÇMI=°ž=®—lé‡ňăĐkaŔZ[Řř¸ç~ď™˝˛Ţ˙ĂiÇ‹Í9ífG¸Ď(Gţ-\‹_5ŢÜ6ż“umŘŐĂ^"lŽňÂŢ]Ó$„qO‚6N\捜űŤÂZ?íbÎŁŻâL~Lě@ĺÍ“;á·®Ö¨źšághčŕ:=ă%č˘smWáuü6®7ČÚ7â@ÉŢÎŁŤ1;˛›ěŰpÍ1S6§őPm/®iˇý‡Ţs_šŢľTŻ ©®b¬břY o¸×ĂďVb_óúŮöűe˙r0ţ_ŻŠŤŁpÇIËßű°˝'S“9KĘ©~÷ŻAâH±ç{Ë·Á~îA¬égŕË•şç×˙*7ě´ ţŹĹ·ŕďR¨űâ˝M{ĄńŁŞŞĽ±ËĚ~:lÁ͏#üY#×”K-×sÇ"ľZ^b0şNV¶ŁşľÇ–ź{?Ŕy@LŻO FâZaź˙†őčţ±_—űwbĽăëË+‹śűB©çś[ĹÜD¬E‰¶Â·î'29p„ÂřĐ%!=ł ÉK›‰q‹x úťűz?ݵńN=AÜ·MJ÷jěG ‡ţýďă<®Ô‹B+Kű{ŘĐ(?>ÚŚ ¤«EŹŤ´l yTXv_XîÝń=Úٓ桉W•ču¦‰ľ ¸ Gu•Äąâ=m“1şg­÷ů|<ŽŻDłă§§&#ňÜźţ’őŐŔ±Íđă7ň=6ß5îífč=GĆx¦ŽëËß!'Ó ˙„ĆYĆ{`÷ˇ|ęi« űŕĎ×jkS>{hIYsîCEÁyb/IĂ ä;Ä—•ýXĘxGř@ż+őc©Křëż<ŘOI;‚-ĽČÇkđT†©óőń~cîł<c Ďą\tčPď đůßĂ Dn‘ňĂÎGĘ4Ô{šśź MEÜő'`ű3ľh— N‰Îź6ú—˛=ë{0ô„»Ţ˝bßíR€«Z~иŔ1żŢŠuÁđ›Bź›ęď>nĘv[ŮúŹĎ8>t°•(ÚwŇ€ú‡eîvMFŚ\ú㨾~HM°ŁxóáŻl ߢŮR^č[kĎBś/ú9 ŽąÔYg źÇë›ă—Ż·Ţţűî·`źp›yNýŔ1JŢą\ědË?NSľ¤6€^`ôIÝľűî±lśľ‚¸¶ßk]˛±MkÇ–Řňň;Ŕxcc±“ązKÝ˝Ö׏Ho93Ć–WÝç|żZŕ6ôĺo0şĎ8'Ńďđ\“ůá…ýţ†^żĽę$±ˇĺ÷,/Ď™öeđÚ[ň}Ś“'7Ŕçľq‘iÓW;ę|°x-†řő#FUŹÁBcZÄĆĂŘ z˙aщţý·ź˙|óţ ›w‡ńQpĄŔ*:BäB}GŰöżľRß+ÇYŹ‘2íŰIú´ŮfßJŮÔéĂľµ~Nuđí•2ćÜG:ůüŤ^Sý«jčŁ 3 ‹É•šÚ8ćuéĐ °ő˙‡Ń]‡k –ÁŢRŽĺÉEÖ˛-ż> ýŕ\ľv=ü‚ŠŰÉň›Tňšgť)őÜ—_$r×<Í•JÖ"¦ŕ:m¶ů-Ę„yĺß˝fś)ŘöË÷čŻ×ůř9=yŘ ź­u=}\Ń_¦ţZÇáRe.ýß—Ă.}*|%ýRŁÎ/IýŔF×´żľü)hŹÓä7ĆmÍ…ݲÖ}‡ ˛Ü™9ŔîiŻ{Í˝â˘77‡św?ťĐŚűwÂoišĽ±Ő÷ýŕ÷ ©ß'C/I˝Ă?µlmz¤ĺé_ćg[D DŘŘÎôGZ®n>†‘Ă'C7J]t„űčÓ'Ľ'—04:­Űu€Ĺ¶U?˙©ë,§˛;gIĎ•zFüO5ÇW .0Ż;_R6°a+yÍźéęw6öLydđíöc|eôĆ[Î ş]ŚsMŰúŐđÓőÔSÄ´e`Ú żFťWŁ= ľňťň-çŘëš cś»ŢĽáŐáávI }±ńi˘Č ±$­ôńËŇ6’úś:—ĺ)ďˇý]é#´ż©?ćaĹž/isí$ô Ń_—¦_™7Ć…ş\ág]0Sh}öĎúţŘ30†Jň‹8¦Š|Ăg:ýK"3oŞćCcóćď°u‰äźč?Gęb¨wOˇ÷Ń®7ŕďĆZÖr?ÇZČ…3`÷+eł§<ˇ ň ě‘Ď#öőÓđĺ¸ËĽ7'4ň›` CgI~xż„n¦ ,*Ś{öY/Żěůľ÷uOŰÂü4Sč™ćU-^tÎKż÷ó=߉8ž0i,OţHä{Ô©ŇE|ořrě!÷¬Ř|Ä’ţ lôwýýŔ`ů™ČüOä ?Éc9ǦŔď3ŕ}ŚČÓC¶ńě{—oí7¸Öu‘ ÓŠoS@bTÇk™Á¦G»†ČÚ_óűËč« ÄŻo8´~Śŕm€/ŞEěl x6BâTŠü ŹŻŹ%?‰ńűőš»0w/úťĎ 8SÓE¶ßkÍiÝĺ´ßUeŕ\€zőŕW›ŹëÔżčÍ/éçđ—ą ő±­” řµXK Î%0b®*Đ |˛*°Îó¤ˇ|Ąě9iţxc7îĎ<ëxŕ+µ”č‡ńjäUëŮŘrz~˘Ç†*ýł ßJÓţ żJÇ5ôĐ_×dÎő­q«1‘ľ7;ňz]îúż7Ž´,)čvUϤgJŞ:żŢ|~SZł#yĂźw0Źq í0ÍÖ蝆ćîe{ÖĂzCęźëd:_Ýß«u…Ň2ëwŢďů“_;ő}éý•ý^)ęߌ†z/·tsťßłŔńűˇMôv_~k$—tŹćĺá"ClßM?µť:ÓuŢ#tłŽąöÍů$Ö™¦´%ťßFś…îgÚk%{:‘Ç®‡˙TđH^"Đ Ě‚řśŘŢU|o‰^çť’Úâ=]h|¤ë5`Í-ö1¶0üŞ ë ęÝÖ豓~óé­€W±ă°%f®ÍiřÁuDĘĐ?ĺ]śk©4ěĺÜë`đ;ŢšĚÚ}Am⌟wÂÚŔgë¦\йҟqcď–: ¶·0(Aśç|#ľćăWČu4KĽ1u żÂĽcşčečÉéđŤ•zζ|ľľff cÝšŻeŢďvťŽ=°ă}϶?ŠąŢžľ‘ě‰ďK6u~ë:[Ç'ĐLśQťS8Aú¶'+–Áđfř)Ďŕśjj_~Čȡ~ďř÷Jʵ¬¦ÇşţŤµ…€…qlIKÎ5tčoyŚW»ÁđŤţ]ľµĘ“iźct°žĺšcĂOFOÄř‚’±Ž=ťrÝĎ5J¬I@×J™P~čÓ·¤ŇWĂ/˙ܵĆđgGűŢ©iRf{)iTyž†óý‚-Ů04Îć!p©-bDˇnĄ]`ĎGÚ üyĚŘřćZëkŤďľmduYhf{ńĹţĚŁ<; ­/b %¨§§MŰJô×/ć­}0ŹßíądÜ <čćÇ„–ÁřLÁ]#†úŇô'üč $Ťdď×1ą ą ë‚<źđs8tigŠshVtf:DlúGeĽŔz)ź˙•Ň #-'`Ľ´=°‰o5}#K°4‹ąENxˇJĵřiu#-+Mťđ>ĆVđáí_wîGoIč¨M(|$`ݡď>@ř2^-u|SŇÇťwRç9±éÉk˝©×Ůç—G1úŁ2ŻŮ‘ł-µ6Żr.ú!sü“ň%úŻ•ňÂŻQĆ‹ŰĺNj.b7¨ďčËő®]bí~± ĎXű‰ň­Žđ5…6Ó_Cݵ4}µŮ—täî„Üâ§|ń90őÇŐÖFµ]®ý†0ŹŢşć [}ökŕî4Ŕ—YÚt_ţ‚Â>˛Ş“á.ôQľíý*÷A€ĽŽÇ1TÝ 2~ö…ĽmhĄţÓkiXkńŹW;Ö˛ r\ë§.ŇĎx†Xó¨ł[Ú,ÖD±<¸Z=¦®ř΄Ş…n~Ż÷×tŚ—Ľs&äáś&ŕ4űb}FŻö :y–Č:Óî¨OŰŮđ÷ř¬źž¶› +gî°v_ŔľË®w$őŠ=KŽ­Mż9ż§ ţŢđ_ď…­…€edŮX?ôëć¸ćĐéÇŁźVkl|Îř <óXšţ™Ě»`C=r‚ˇů4ŘfڧîRąó«™żhSÁ5üˇŢR\>«KÜ5Ţ‹±&ř"öc»Ĺg?Ó~}Á vd 1źü÷‰P8Ő‰†Á¸ÂTâ·Ŕ1)é÷¨\©Éţ)©›…zÉw7ĹQ»ßčY®ďß.ň\JčëgäZ×çŘrč5h¬•Ëޤ¶'ü›ń żé^đi%!Ú°˝č%˝™öóĹ6ˇŰŐ/÷Ůßńů¦:ž‡<꼰÷lÚk·ëŹŇVőZUôÄ>¬_Nn aČ»8»Fl>• ]ŹŚ!¨Ź´ý\Îýí’zĄ<ŐdŤÄÝ×ëýă×/işÖ>[ş°ŔgŃě1R¶ĺÉCŚŢa=ÖŁć±äđă©C̱dÜ~˛u‰LaąK^Ń|j«?­öÇć©í„2íŹ}ě›â7°ťź™13zpcvF}Z^Ä[ň,pxóXD· ëóŇWUU=Ö ›PŘT-ťĹşŽ>ôa­đ‹s.ěËŠü ó‹iÂOŽĎuĚMAÝúň`üKÝ_->·ß‡që±^Ę+űµís[uçĦ̅Yŕă5'N?çU¤™ëÇ쇠ł1ŢřڧaĎëă:…Î3ç~ë„V¦ý!żŇ[úɇyVý—˝X+ŚŞŞNwÝ{‹ĺÚ‹đÝ'“ćśŰŘl3ŢWދภmWtÖĄ5CĆ~ö<6‡kÖÁŁ]Żů9ÇQő¨JĄmOř ý)ÖzŹźzř2[ažř9iĎŚkÜŚµŃ/rm´ üjmžňîćs¨ňąRŸC,ŰĘţó}şo™¸ }Üĺ2âş^×*Ňp±mÝws§W—Z•Sʉy÷>™WĐŢMĹ-἗ő·6˝UUĹ}¦łĄşŽzÚsRcm“ MWKtÇu‰ű`W§ö‘µnŰŇ(]wy{$u“ÂÜ)ňŁŘ^·Äz]7µ˙űî˙/tţo.TžV8Pá@…T8Pá@…T8Pá@…T8Pá@…˙×8Đz÷Wß+‹}WĆäˇđôšŻş‡ŘsŞtŤ±Ńôó-ăÜ—]ü§9r˛łŞEÇQë€\óWv\*>hZ/}ďC3îĂŢi»ÄěĹ~ÚH˟;2׺i7‚rűŐ˛¦ŻÖ<ąż0ľ¶,%qŕo!±˝Šë˘ă^ţ÷ťcfŢ×;(ň›sRâ ¤wóŹ.Qń-úň«}Á ń ®„Ý­¶ď­ŞâšŻ¶3Ďąo’˝ÇU-ż…=ĘjŮËa¸D_%ŕ•Ź«]Đű&V^Tí0ŐőQSNî™ÂWĆÔ1ýN`Ł\°APŘB*݆˙n­jY#ű¶SR °GyvfEŰnÄ7~pŻ^ůęď>XIËó6öR»TŚ@älł× ľiöbą?Ú)ŁŃěVBy¤ě čÖ#2¶žgLĐćľü ĐĽks4;ËşvIiĆm‘¸÷Ĺrt—ćŮVqň€é ´sď™ĺsĄ.‚Í÷€1çdR—±A-î=ó·ŢSF|zĽ{›÷‘®o™±ďgi=Rvq:­Ms&MŃO6Ě˘ź‰ť?¦^O‡}uGřÜ‚ísO[ë‰î@Uy˛ z­öů϶ßVχűłv?TŇ N¶Ö=ľt6ŻĎ __±Ů´Ś7Ýs;› ć›[ÄńYnlnáS íĎ^GîŘuLý…­˙Xş‰í2żVx_zořÖzĐuŞĐK^űUĺű9řvLŇŤ%ż-éŔ'ÚG;L{>ăqMyě÷Ă×řÉ?ŃߌëL[i ÁîôF)żŰźö% Ú`ď]ľq䂨ł·×ÂŚŇ:Ů– Ďč?šęúš¤GŰ WJŮôŹ:w+ŚsĆĘŇ4KŤeŁm)íˇt|ýÖ÷ŹX|ŇŤRťët×Éô[ެ c#›°µł/ŽĽLţ“Ćf”ż;; /Řż‘‡ŮB˙ŻŰ9ß)÷Áţv~ÚÇĐŽśé#öł©ţ¦˝Ď™ö­ŚówÍ=ĂFř›‡Ţ“OôűäÝôK˘×`o|›>řD^ŹŘ«»şĂŞ$Ż˘]ŮBŘ%ŚOěź‘–?<ąR1SţGşî‘ňň^mâ—ka‘¶@ä\±ťŢ™Ôe_>SRö))żáO0řáĺČÝNŘťÜ×0;ňŞŘľ/ĚÜč‹yÖä¦ źMŕâ„$˝eż)7ÝÔŐĐž 1_î16âńjˇvA¦L,Ëph‰üväNŞC|{c'Č>—jl1 <ś’jE˝Ţ'|děôăpy?çţ(mßa·I}gŕUą ž'ôUçnORţv1ügľăqčľ”iĂn ±¦TřĆpč6S˙ꋍů˙ĺŢźy¤ ۢƺcĘvűhöň:WŞ ±×—…k“‡Hy7'8ÁŻçKE;)eźÍŞ|Ŕ­šîČíbhF}š´ě”P—Ń&šzDŮ敎•ěď~°ëŇtúň;”đ¸Ađ—|YĘ×ţˇ)›+ő:âÄ ›Ż.ó>ü†ŕkş˝‡eĺ>b¸Á˙ęŢLűÓ°‡Îׯ..ěúéŰ0·Ž÷€+ĐxşëĽ¦Ääü á»ë`bŽŤ´üĘÔGąt8ĺţ6RnŘč?ĺr‘á‘–VßňłîZ«=a ięc´‚ť'ěĄză°áŽcŃ,12Çň}áűޱëĄ?ŢĺđëhżÓ‘–ýŚű-“~=O[×ó ˝—č_fęLő;™ßLvͦžçüá?kÚ4|ÂĄM˛l±äQ2žVŹŃ“î ".®ň i  ÂO—ô€+t·F÷2t×d¶~"·Ënvä+>»ýá†Ň¨żŁ/Q—ëł°K?WňˇlňŮŔ‰ŞŞş[Ę _Ś™Ţ€ďČ_ u{ đ~íRVěěĆś{˘Ľ«ć›?5:vűFfÄ’ k§µäG—¸mđŮX-égB7Üq0LJÔ1:V©~wcÎŔnôş ~܉ţ|¬Ű¤Ľ®”ňgwťWô=Dvk¨ÎąMÝ2ßĂ“ŤĽĎŚ^'Ř–±dŹż:· x =Ŕ<}ÚÔ_Ţů6lbĎÁśŇiî鲻Rż+I7çţ=âźMńłĐcÚë÷7ôL[ăÎŔ…RgO†–YFĚSS¦Ářdá»Î#| ľŹ—Łňzó~çׂ¶‰/ngŃ6Žş›í#l}EtĐňäĹđ/~ŘĽLÎÜÖ¦ţuÚ<ĂDh‡ĎłĽŻüłÔöţÔţÍűż.ęlň4Ú4Íé(p*˘őC˝N©ËÁxoĂÂü¦>‚˙yĐСóUsgĚ/Ł7K }?ňYçĺB?đI¤=@ş8¶‘±X4» üTFŚĚĂĄą7•ňdÚAö¶‘oőTçőÁĎEšS· ĺ[đŘůđü„¤?ŢóČ_IůŕWgä>…°Oż‡8y~Ä…-ű®đ-LÉ\š}éË…ńqđ©Ł1;YĘ u፽®Yޚ̾µÇ™úNu]Џ×/ÁOö k°‘öÁUU©®Y8_[Đ5öő'>ý G‘f®íP†8—ęv=hôSěßnęUçꀯcŁĽ7'č.yźcĎᄇǩ‚7ĶÍoçW íX'Şďď%|LôRh§Ę3®9đŹú‹c˝ć˘ň¶—Y—ćťąFË/–ˇíQ_s~EÚ9ŻiˇŹăw±~•¶Ýí:r¸ĆEĽ0~‹ú.ˇYŻńň™>ćöő!˛/ď<k'łDvęZćî ś ě´í€yń[ŕ©M3mk©r ťé#¶ç¸ĺÄŇâËG,š7śÓ®x˛eÓgK¤O%ćĘchĺŰUU\Űiń§óD+u‰ÂáXeăߊřË’Ö?M_ĎogďYrĄö—4űňÇ””﬋—ęţűĎx ±d#°¤ŠţÜXÓ lĎZ®GťËĺŰD˙+MľŘW±žŹő ×ˇ oŔÚ’Č9qśőĽF—c4y–ę:JüRíăOýÎĆśWöß˝›°?ú€ˇóµô¶Î#lýkúŠřÓkšń“~V›`˙ŐÓö:č¦{kôwÂÇ#fęWż»o,iôDMćÓ~Ž=óXmĎÁGÓďAß ňQ¦ű1.["éęoËyžźt¦Çµ}ŕŠ.±§ŹXä óďkáKéwbɇd=} äő8_î¤?xÖ¸—5cý[hŽfwĹ:Á ¬-ݶ\-yqžCąxaîÍńkkôY`HÜČX2Ŕ9{˝>+O_ŲŇÖ!Z‚}d‡¬oł zM˘#ü®ÔS0¸kÓîIżP›¸Uh°bOI9ŕYĺW¦÷şóKľ$żĂVŤěϲlÜ!żěľŻäA,ů™™Éą]RÇ”晀˙as››ăq¬Ź¶K~ł#ź+ĺ”÷ăAó@ZaŻRç’Çě^Ă uĺN?ôXnĹĄÎŔîŔ;Ź›ö¸ ńOX_¤™c;ŤeÍ3ײ8¶â— Qqśmę™÷‘al0 ľŔÔgĽ‡őčó‰ÄuöÖîwcYĺZĄ_UuˇwwńÇ˝9ţµ]®:_dŃ5~Ťs‡őJŕ4(Ljb©$îZ LŔO×"Ďšu:ęÜÓöoĐ ^ďç\%l‘Ö¶°)™ ¶Ď–ĐË÷a[bú9ţ¦˝ ŰEMf_·ëřqˇ—ůđ`ý˙řžQěźĆEöV‡•ĎíęÇśľŃôµĽ·4}FC4űoŃMĐIFŘN(+\ϡĽĎ (Ľ}~ ^)éĺÜ*A]"Ň”-äÁçłHŚĘ—’çňé-¦żöˇŇÇŇ/ú®óÍ8*‰5îęśWđ›ĺ˙ąë@‡4w»>‡1Ě=“|CÚsoŢ)tŁoµČ?{úÇ÷ńţ“z3°J.ĂTe‘k]B˙@zO|őé1ő˝˘ł€v1íŘ^.^+ţűעs\ŔŚÂĽ·©?•±%ßŢ—‘Eŕ˛K?ޱˇŚ€É"8sÄYŞĆúćFB±#k25ÍSR.řGż.UUŹ”č5Ṉ̌×L`;!Ýq•iŇQ×ţ¸NRĐ˙&Yě=ŁŽ'Č;¤+Ńż«‘#Ť-uxřVß hÇ‘E üěŁ6E›˘ďç‰/ uöż|§»ţśSgÓ¶_]âuťKëTíK«{ÜgŔ~•čpÚ}ß1ߣöžůC°÷ŞKě Ţ´c˝đŻSΕţČNčćď[¨űŇ|ÖU’M{ݧŤűÉOSе´gŽËµ#· Ö•^’¶qÔHłIe—mB,>|tźkq\ë‹­ń‡ßáÁdŮ´ôĽßÜ–ŽŞ…ĄěFÔ÷­Ń­aC•µÉ:ăë’{¸m˘ë€9íĹ|ëgKßKܿͯ~×Ĺ%·ŹB7k ýcĺđz0ν€é§Gť3Ś䳼óűŔžQhŢ2če©ő|Hţ >ő°)wžÁz/'+ţŻ$–śä›”™,ýö–G«¦Yź]ŠŽő_sŽşĺÓŞi¶ź×GłýťĘu…T8Pá@…T8Pá@…T8Pá@…T8Pá@…[*zÚvąwŮÁK˝QŘ×ëavzě÷ě×öw¶„ëž¶•ýűgŻ#üü$o‘ôčC]//´Í•^fü6ř6řóÎ_•¬{ë/7§ó+9ąMĹÍ(ÖlHÄ^€ăńüđĄEXíKĚŘ_3°g5Íż4˝>®ĎĆŃ>ÚMŔVč-îmmN”Ş˛Ř÷Úué&ĚŠí}_ݞąŻŮýzł÷8zńąFdßAä™Ăó˘±Çŕ˙č·Ż:7_0 Ňź#':—çĚ˝âĐF±§xʏęđ/ěשr!Ƣü><ü|ᾊ¬}Ô­Ř5Bű¨óŘ}MÝ”ŠźŁÖúá{ű…}üY±3řpčÔąr/fe˙ Ř—QőÉűÜgĂ 1”Żl~d˙Ínx}‚±BŮŐv%©×·‡=ŤÂ @śJř))WŘZŔ_áë.řCTç‚› v“¦n]ç˘N [Ű}Łl>čë61!”oż¦=mPh?ŔşÓş‹ďĂÎJľ_ăľE|Ł9ĺo¤}¬;ř.~Öěi޵łZWéĘ}ŹvlľWd”ľ2´Ź€ţ1e WĘ5ęXěB4XúŤ ţ“±‘Á\٨VUÁĎX0šj2UH»ÇĂt_nxţťmŇçľui?Pn KÓ[î× ťëq'n‡oÍ—¨ěđiÓÉ/N¶&ŕů "×Ý®k|Ż\ ““I°PľÔZ¦ůîˇsä=جZ´ë†ş´í U·ÝÇ÷j2{ ÝřŘŔW×EYăóń9Šy őöřákaĘT›ŘĆ·8«ldtŢ—*´ĐΉţ†Ŕgđ>ś>§Ý=öááSpb`ű(íóG›‹a“ń1yo9t˘N/âđË^-mxŹ~dúŮxťíţĹ+âWC·ľah& ŚŃK_}Är—úx2t‡7łý©ŇÁţ1ÜZ{Sɨݱë„>ĘiG;ń¬;ńťâé‰]’¦Ťí…}ť˛ŤÓwË}.Ö1â=›¶Ü±Ńq×—+ôĐĄźÓ~ůS‘†B:>ď[έ,ŢăsÄ´Ťň´¦Ă·»`ŘWŕ§Űő¤Řðџ"2PŽ8׺\ös¦ýËâ‹ßľ1äJm ŕ›!e‡n2tEłEż˙ąůr~IGu5qÄ?uE[±°+}0 řZąď<ćq|ląđQçźmąˇX"/+ű÷öÎ ŇF~Ý6†ú›Ť?«:Ś_!´MĘüSňwäŢ[kϵJĆÓw ›,ÔźĘŮť8ŔcÇ&‚ťôMŞě|g2ě°SÍCçJşĽ̬ڣ ±…ů[ńř?Ě;°˙6<.·>c»Ż\ 5™mlůUy¦¤ŠZa«« Ř`đ[~ľÜżör ­ű#–]űÚňZÇ[,¦č†tsŹÇ–řěŔ–Jî;3írŽ8Iţ®ÔUŢľ=Ż6z…i–űŕXBëMě É0ţ¬ČbkôJ9Ă—@Úá`üjÄSť,Ľâ7ÔOĘOި8@üHĆĄęí62 ŚČÍs›€O»˙Ű :ÝŘ"‹8ÔÝÔ}ĺÔevý;uá-bš˘MţAhA̸úT×ď…FWŞUĘ_…éŁÎ@}:äžďW^Ňm·…?°µgę±ăŤfwGżu‡Čm,Y%éˇ+ŻĎęćo­Oö>XůÜE’?íĆčź ë3Ó.ÄŚ6Îíô˝Ť9sĚ8pÄĄç•ú2kYE›†o×˝Śë*ô!Ϋń­šPµÂÔ뗾ʾµŞmžĺ^˝Őţ±çžŢ3ä=ô˵ę3ő©Ë=ęĽOîY/ţBř|şk)Ćř+#üŽoMű.W›¶ŹÓˇ dś¨ÇŃC˝'6Ý=˛9âXŮŘ}8PÇÖC—C§4FÝŇT»ßß=+ű‹Xc”EňŚő4XŃë.“rłÉřŹ´ţf9Ö&F0ó ď[›Ú"ůľ)%4óýhv’đĘŠ)_¦şÄŔ»Y&máňô‚ÇÂ÷Ęy¨8–*Ĺx|¦™3ę< wRǧ<&ĺhŤţÓíJ=ůţ§ü[3˛Čo`űk±ď‚Ť˛¤_fÄó^8‹Ť†ŢQçĚúăřŢń[¬+y+\@řdJşŔq±ő7yąjŐIeŃcĚŹGmâx˙Pď9Ŕm<1źnžUč3ů ř$ ŔmpcÎS ´şˇŢm›’˝ Ą\´Ďć;5™w¤ÎŘŽŮçż“ňÂ'ÇĐË÷0Ż*ůÍ{<4˙űň ĎlÔą•çŻî7$ÍŽđăЉĄ-öę«ţż6q€”«#܉úĽ_ŇŚ/Áxx°dŚ’ęZşúM­/vpEßčÜ€[PR×Ôa|6ÔűI#Ń1Ć–Äkâq?úô?2ηř"ű ýË“#âˤâ÷©7í˙16•´Ęá÷Ťń|»ž'%đgňB3pĎ$}Ö×`ňam@ęó¨ÚĄéń‡-–©§„fí+Y|^U5Ł€áÄ{™ö‹€@l’}€ ü‹8’’Ć@Úéç:Şß,ęUřŕ—m,F›y=Ž }=ýTăĄŘŤ™v5×zHa`-PĘÉŘą¤ŘÂ+^S>őşĂ¶ů× Ď8‡ćđâ9o´kŚŐđěŕ®)_ĽL{µˇ‘iňĎľÁ´7ôŔş0Ż~,éÓ·†é őžá‰fď‡O`;0 >‰1ăMá}đ{GÄęVŘ|/çţ˛xg%u<ę|Ň"Óˇpi*éŇżt?Śc9‹f•Nžiy™ýS‰.#Ď—'gAçß(ea>µ‰=$űśś÷7üĐ:amłÁřˢ{A§Ô#ö ęvÎD̸˘/‚ÔßÚy÷1;źÍ(Äçő¨ł}[ŤĐY“ůĹ4ŢĆ©w Ř`­Äu0}‚16‚ßÎBĐ> řČ÷•·‚ń¶ĎĹ~ĘŹ­Ú1áÉ×/X'[SýK[ßŐbúá@äLřçj]©OÉ=¬óíŽů/b¬ů­B<űC1Żpy°ż#Ϧ¤Nyu^\®Ď ßŕs8 ďb¬‡ů÷t‰Ă‹bsTʼnf™ÔˇëG˙ŢĐsO۬Č0ćôçH^ä1Ű#×¶ăÇ@ÜŹő&ţř/SźŔ‡ÚGçT›8~çAîŰšŞoů]cgŕYĎ#]?±ôXťďc8>kšâń%wŢ <Ŕ/YHď]×8ţÄĎa|7ü1ůđ[Ę9Ď<îěß őQ.š™˘J ¸҆¨ŻŇŹ`Mo>Ökć˘çK9±Ö5-ü×>éĐR7Ŕ?X«źívµ[zo‚)ó€ěQwŞŞŞs;‰<Ź:űŤţÓĎx¦o%đŹĹ÷X˘X?ţ·MćěonŘ5ËÜA`C¨ąUÍ1»”¤źęz­ ¸»uéęÚn×"Ń=čĎŚL2Wŕęč4çjěŁá/ëžöRof^ĆűXS$Íđ5˙§ ýřÎkń€óJâYŘÓŮŘk–sŃŤ®ĎöűÁĽŔö‚Â9cúô ĂX¦kT®‹Ăßő<m:ÝU'ĺ%Í”=·B lĎčV>čýăD^€Q?řr’Ö ¤ť÷匴,kšPu°ŃYđ‡›>7°O}˘˘”›138oÖűsöy/u˘Îgͧď„^8UdĽ/ß]2žá<–ňˇ|{˘¤ —SgëŇ0Mő´úˇ7˝®Ôż¤~°&׌ńH0j]śX—ęj—2cďÂŚ˝ ëÁ’ëś8,äßXy™˝ĚđŤ/GĘZeš{Őö6‘ťSđŐeÓe-×Yř¸ݸ·ÔwkTÍé™Űđ ‹ ĺžUĐC»4=Ú5<š*mó(ś{G‘{ĐGŔÔú:0‡NÄŘőGR·±ämđ˙ŢQ®ą°ůޞB>ˇ=HľŠ:)[ą]g:}ůOH~Ŕ®•˛W©i8t‚©źă±†Üő74NInî1!Ś›@ŰŞ- ěöÄçű¤ Ü |˛›âŤ‘đzsŐÜEW$ë}±Wkđ5`HýÂsm˛Wř@ą&ý\{/·Î¶—‹xC‡ÂG{{0G€I¨đL±Ö87 ÖĆ€ąňUĂÖ˘ósŃrvSkt¶ŃQLŹó@âO(,•CŘ:뇄ݮÂKřc\v$b \µ”ŚţäţĎ<ëxđ}ĽdÚNµşîËŮ&W¸×ł'l!VC˙Şx XŻ-Ń=»w,ů˘ŕ2îçQ>S] °N>Ă[ť»¬)â8©©:ް˝«śŘďĎ+ŚeÔťI™}$oµ'8ţ2­rUůäÜ—b]›¸i3=-Ńk¤ěú{Íľŕ.i3^«MéăZĽŇµ´“Rýs_ţ§Ŕ0UءL?ůć2‘u~Ćš š3íěé§śŔż©&ÍFźŞ2Ť˙˙th+ż#w6eúzr3°r0†út ~:çď±)j®‰˝SďĎ!ćĎľW@?öśD†‰×źsŻ@Zíć=ÚČ ¤}R§ŽÜŤXż·Ç Řt2mç&ë ë×Xwű¨‘sâW˛î±–%őÎ>8l-.iË:Ť4ú^ŰűfýLá`ťřĄçyźů1˝ńÖYş ë>+Ěb>NžĐĹň|ľ€Mh˙f¤ĺśzWj:Ş]xÁ=­ko¶Ŕ2Pí©b\&ő¬űěD˙,ŕď=1Ĺ´ÚŮÓŢÔ׺>Šůö`Ď6mę{đFV1Ž®ß+vPˇżľŐG{'ÖŰ@ú`쵫µŕ5îý‘›ĺ›5îěń—ꨜű' ˝ô^1ďMyĄđ8ĺ8_É÷^ĂäÓżŘKÔý%řRÄ;[§‹ś ö‹áŰűÚuş9Đ«)éi«Î˝)ű:Ô=‡‡-Öą…ŢÁřŕoě•~és~)ýŇAŐą3÷š7ç~ŁdÍ@ɶšköć?.znó¨_MŻ>+L–MŰé'´›Đ×Ä?[ś=_dÔ®ż:T¶(ŘŰULžSfô\[żyžUrÎťsjÚöŇ#ÎÍH?Ćg—ä˝§€ytˇąŢłÜč*UŻ›“,ż·ÝzíQX7=ŃôY§»ľ:{Ú°×96±§ůĺÜIcóĽW.›çs%ďś;eÚ ŠŃ§đ*_¨§řś:|Ë«Ű÷⺢±H׺~żW[ęsŇj?Ćţ¶?«\W8Pá@…T8Pá@…T8Pá@…T8Pá@…T8°%r@Ż÷m‰e˙e¦ßlś kôŠfîI3VPi* źýěůq¶śuA·TĹ Ńti{ý›ç ó…nâ®Ëţ b@`ßZö<Ô0ŘaK5ÖÖžĆćpmßCTëóŞTË=Ś—{v˝ů%fź†ëÜ´Ýę­ťż Řó˙^ötZŁ×‰lŔ˙Ăěi*>lTŞ2č¸ÚĘgC—Kí)R–ł-{ ú9÷l;M%ńj.Oźjöut Ŕ°/jžu®|_—l•3ţ­Îçźm±äăŔÉyŚŘHÖěÁĐýφŕH˘n×é…­‡ ĽňäÜß{*č}ă“ÁĽÂ킯ťzí|ďĐÄ}图9ż„íĄÓ˛ű–ńťr¬›ęÜ~Ć©˘lGłě/Ť]ńŕXn×Ką1>Q>3=»J˝°l»:>i¦'ökîFßłí?Á»—6B?oC4Ű űšÔĺôÄ_łňbIkiú9+ţţĘÓ˝ěܲë3Ú—Ć’'řhWM˙cÍÇ}“ëŕď'ĺă=‰ęgđ‘­›”™-tĆĎ@ŮS6ŮíiłcńX±>Ě1>î}2ôŕ?äëj2*~éÄÖs†íş´)ÚŔ—;®ýŽhËú7Řôťä…M§©;´[řô/0´®«xC˝·‰=6źĹ’/‹ŢŇ4S?huú?«w&ëăjĂKČżČNôÄÝ€) |í©cIĺó•iÚč…uĺż÷lㄡ—2É´˘Ůí »#eZ_ÚŚ»čJŹŮQOunźë m]d7çţ’ČÁĐÄż=¦ž{QâÓˇó`űŇ׋´ăQç1Ťôa/äkhć‚}µÓu>‘wjŽąÎČÄěHĐč‚Ŕ;Kűó=kUËqâsÉľöŕ"óIŮÔ·­ű—o<ĆőŞŰđ/#—óEö‹Ńl=Ćüj^ sŃ·č7ÝC˝ŻďËÇá'Ö4t5¦ŔüWž4őWŕ â‚_-:«/_ 9±Ä÷r/éDł)Á¶Ňë1ú[Gn˙’ţ@ßßĐs˘_|šŞ’˝ż3:Äľž‰µŞ†n×]¨#o]GřX7d>ţ'™¶ ˙"ˇk›ÍŹvbAXŚ>c™ćϵńĄXJŚmáznȶĽ ŢÍ™Š8ÔLŘ:Sx¦×ŮŠ_müUaMGć~l‡?PéţyNpŠ'Ů›72ÉQPÁq vgÚw541 ¦©}‡ř\Źvą0ď|řJ·L^±‘mÎă«-®)ÂżVh%^čś`}ţ¶FoŮ×Îtšv.m#ń°6cy“˝sŕGˇćUĐoR˙aKaK1`rÔ:rKPż÷~ ţáWłHú=®_ëň›Cć#üŤµó>WçúęsîC„gÄAIôďŤ9ěď¤-ł}„­Vŕ6ß,żËą†@ŚWęĆżň‘ęUăîĽómá{GřŹđAź`ôT˘;`KýÁČ7ô°i쫨 ´6µĐ ´ËycľÁűŔŘÖÔ7xm҆éÄřłyF0¸ ĆygűŻÄşůTŽţ`ţáĐ?ŕß·d,^ŕ)×®•kĚ)QÝĚ)©ŁŞ*…·ţ7ŔŻŐ›»~7ř’~É˘Ż†¦—ĺóĹŢ•ö^›ŘsĎ]ĹOkž‚kĐ8ZŇÄ ßĐŢ—ßsç%lg%‡Ńě!fM­4w»n,ѱjşź/\%|‡Ż—”™y­ěO‹ľ…üą;_­~ĂěČí ŔpE쑺f»ägUË'€?űcřBždd€i`˝@ę91ů‰ş^Śm€A.˛ÝíňŔ7ó)Ěϱ~’‘o4Ţ-ż+çAYdűSë=ś©b(‡™ďR—íĺ~©%jęg¤ĺT‰QO]Ăzćub ň"tQ¨yn ÉĆ»Yć;¦Ů¦o*/ÍšWđýŽŔ‘…} ĺGŮä>›}ěSČçŮőSR_44sŚMÝÇ?®‚f‘g_l>ö>Ş«µ 8 `¸Ľ,)5ŹdľŔů1ôžćú“Č‹^WŃĺRçňÓ¬b֔żfŮ›NWř+,CK4kdT—mftŠi·Z‡‘C˝ż%k‰îiąK~_¬ą€…¬ÓQçž6+˝hźPúĆĆ˙R{äötęwżâqŹ#wş”şČŚAô{Ů–ź–č_ŢĆWöemc1GîEŕ8äę9ă;Řďöâ"`&,Äşńr÷kČ'ęčbűUşµüú‹%XűNTI˝đ Ě…ÜÁŕU éĐ[7»ŤLňYŘÚ1.ÎăŢ0Jľęç>ďŻďĐkÖŔŕ1˙–iżŔ…†Ű4ô>^{%0c~g3ă{·'¸Ň”c㢆@äKŇ~ŻHŽwćą’>”¸ń웨˨©Ď†CŹ`_¦Ř^á .ßP7đŻ#|;÷°ĆDźp<Ă^ŠŤ×šîőqnüďGk˘ÍŔźđPţPNi»ŐąçEV—'ňrÜÎy7ë´ĎŚfMůkłoá?ęD{I÷L}Óđ®5úI`PĹ:Íur×ĺ×[öĽ‹×ʶ‰ż]©›` p®)S˘yłĆ™ŞM|úíR¶K˛‡˘ŹVXüŔ óŁmĘc¤ĺ،쎾ŮÜôźë¶Đüv#?:_b°X±ořwEřdźżëwĆď\ŞËzó‡ ŽŁ}věŐmíOuÝ„2ţzîáËÜŔąR÷XóöHťÍą8Ëꋵš:ĎąoóŤ:‡cÁó†3±µĚˇ„¤@ä±MŮTz«ČÇÁsĹXÓK,Ťôq>ĄS•mHŘš XďĹ÷ŐâH]˛Ü,3÷×GťŰJ_‡uĚΖçÄäa<¨áĐiŘÓ)bÔ`ÍDxĆř0cÓŢ4żKŰRÎ}íJ¤,Ô?Üs­MÔIYžšL0x/Ôň‹;=‚ŐxŔ yÍÔ1ÖŽ0îąĘ7scŕ’ř:Çy!Ď"ë}ůôő¦ˇpÝą¨¶L…,®6v$C˝‡É:÷h€‘/ô`ŹNt٬•Rž9·jŤţÍ6žˇ~Xéey óć‡ţAxĆqĺhÖr×MÖ{Ţíi[¦úZ™oÚ_Źf÷ĂĎ=2n™ýeqę<¦d-:Ń?śÄF3Ö[}>öeÜ]˛ âř äĄT¶ěymúk–ĄGbŽaÜeä™ĺ@ĽßĐČ]%÷”\Źčî#Jm€hGń,öź0Ź„<+1Ů dz]\Utó ök…Fö'\ßÔe¶Nˇ_Sďj[ťZ ň¦i×ę^O›ÂbR´ë÷6ż3d}âˇnÔQ›8Ůϱ0”…X;•z [ŻŹúgBg4{"ÖJv5í;ďĚęvs§WSYÄâťT×sŇ§Şµ+eçĆş×xZ­Ńó$6őÚ”Ô™ uV^ťŢ–tV6ˇ鏆F?i‚ý€oJŞ‹ë˛®OüˇŢq>¸ĄÔë{ŐŠ%ɶÍ6NzU×c:Ňů…Ö±ĽĐ´é3źŰŻÇľ_ů]á@…T8Pá@…T8Pá@…T8Pá@…T8Pá@…lnPkš\ăUvuü=öĐëžöóŘw¶„ß=mýŘ«¬É b-żx¬Â^Ł}{±Ä?+µ#ĺsîýp÷ť_ť˛ÓŰL®ÄoßNËŰ|ł÷VŚÍŁÖůŠĄ_ŕ¸Ý_“ůĄěkq˙’ľěŧ›ÓUOýđ×ÇĘ;w÷?'őÉĐ·"fŔ*Ř—§˝G§b˙Í.żúZŃÁŘŐíáw…7đOň±=äÜĎ7á@źŠ5Ç÷7—CᲰ4™özÖO[4«ě>t k2'Ę~”¶Zśť({p°ď4{¶´ç^ ňŞE;qřsŔ·đ|yN@Ř–ŕč´7ýYńžu|o!ţXUU˝ń  śö=¤]Řm?ž{V™ÇYsÂV˙Ńnµ>?ńÁfČ {R±Ńpä®—=ZÚW(»ůMO)s$ §»ţ?łď ľčFW±ý˝é<eŢAě^t\]e WUĄmŞěö]źŠüÜě;ó˝Ů‘â¦LF,¶+ĄžŁŮ§ýéßJz× |Ú|nꣶăŹYÖńW#¦É—;/+ĺa)źXÓő–łYîĂo &ÓÁ‡ŽI,ůmń…ăűOglęřűý±äCÝđ~Ţ.Ď;´mŃőż fŕâX´éŃ~fşNµ_ęHč˘-EŞ«YdBżk/íříż«Ş¶’wiKéŤmSŕ«]—ŮŻKż,ďŻÄ@ŽCoĺCëăâš‹ďʸŚh˙ĆęŻÎŔŽÂŘPl˙ _› ¤Ţ9î>}™˛gzŃ]°©Ş5u›ęú|%_\KwóŢđ+íÓ?Wř}Ç9S Űëi͉ţóMűż®‘ðő˘M>‹ůN¨ş_b›Ź´”âč7ăŐbŮíĘJZô‹%Wä ±ëmv˛ę+e[[îşîĚ.úźę˛)űEú}±Q,ĺčv}QĘyŠs#nS-â~Đ®UĂ~n,.Áp¨ZčŞM¬íDzŔń‹cPí÷¨ănćaç˝8űVc]b°ˇ5ú;iś›ęv{v¤ˇćcéÚ=őzűŻňőY*f&ó©ÝŻľUÄĂÝZę€ýŰŽď¬ě÷5Ěłv6}20!ˇß·’ľĎaďëe<:ŽQýż–űđˇ%?€w«i˙ČáŔZ™ęqĄ~.$Ôś—ňĚ•č/P–%čßĎiž’~ęşa>w¨¸°z ś>ŕÜ<(ňkŶA˙®‘ŻľüۦŹ:k%?ŠXż5GK—ĺ¦ŢĺoĚĂ0›[ţ…ŹĐn´aü}±ě×4?Qň˛ăFÍŚž+¶Ńc}ÜË5·ÖéÔdö`ĽÄćwŰ®–u›˙µN5¸zvIßĚ1ÓHËn\#žč1IŘ:ëűŔú``|˛mÄŘ ľăŤµř]›z}W©÷Öčdę1ţ5ƶ/°~Ä6|&0uXÁ‰w6öP:Ö‘űąÔ'ćEţtHáY2ĺÁřaŔpŁ.N®Ő§ĂýouČ_0 €×`d•8ö’°Mčşćýn×n“>W˘›űň3¤ŤŚťcŁďv qÜꦱ®ąNÚŢޢ~±ç±ˇ×çgž`FsMŽkVÔ)Ŕţ3ňĽ®tµ?ÉHËVBCÎ= °łšwÎ%kśkëţ:š}«9˙"¦cMÍĘűŔdž9rS€ ’>Ó©>ĄŁđNlŘč~Ó—żxRC÷ńŤns brţÎĽx`| ˙ô·ć˙Xß ő†ţ>Ö/O4|˛×Ż~c¤%ąušzNô'Ś˙t˘˙ËŇÖgGT;wĄłlc™Tă$—ďĐtBöšáG#e†•Ô 0MLsŕŘIŮó`ümřöť$° żj±^±¦ă:äHŃôŐ%LöžŃT›xVÚA4ű˝éŽÜ6Ó€m38ݵéL°Ŕá)đäďÍÉŢźaç?j ś©”ëPzŚ´l‹Űçv€Oźę[rn—©[{nđĄ4őŁď#–=ü+bŤťo`>ŤřŘ]’|çj[Łw‰\÷ÎČzMf{‘g¦¶ţŇ4:ˇyizČÓxă$âi¨2ęĽĘq¦ăÚ:ÓÂŘÉ»"‡~9¶ăQ)×pč0©Wŕ]=6ßhVŤápżŤ} ×ĹőÜßţî÷kŇ× ‡&ŁŹď5é ‡N…ľ •´Ű@$ćáúďxĐĚ1‰+µü”›Ś,wÔ\ă†úyÖŮ%}˛ť^k= \7ń+Bßĺ{řż{Yk€ąĚw&e~aüůxćőŔiž— ~÷ë±(pżáŻ“>ZšY†L»ňóĂŘÉČY ˘°jăw×ě¦ú°µ¬¤®ÉüU~“fÖ+Óá±.Ý­ž¨˙µ‰0´.6˛Í»Ă!µöĹ9(GgtAůĺšéó8N2ú&QX´g9ćc,2rľŁ‰yĹŤŔc8«Ĺ˛2ŤţXAĎ«urŽebÉRśu´]“żH Í™vx®ń°¨č—:fľęčÁ|yPęű ¦Ţř,–´chpέӴmW*%¸‡l×ě«Ô\2íńöÎ÷Ńď|¦±ăµÖŮxÜ«ë1ӮƥĚx^”ĚąüŞ™f^úřĺ­j ?ęśéť”,z쓉~#w|keFďDłE<<> DVJ» ,˛­Ć´ŰĄ#Ü_Ş*®“Y1…I>ęĽCň#­śW?VÉôřČ5Ë«ŹlËGüX«–:f]`-TęÝ‘›/eiÉČŮ•şĹŰ—˙Şi§ŁÎ'MťSžu=2ÝhvoŚ«.nuŢćŮ=5jä‡ýŇ”Ô%Ŕ >TŇä»™ö­€eó8ő渌CÇÚ‡â늸Z7°?GŠ5‹×=lëŔÜ2eGŰYȶ×ď݆X?đu7uĚr ő>"2Ďý U.e“y$p`Oö^žVӔב–e¬Eś_MüĆkŤztSÉ´Î[—kÄľ4sËŽđb/×Qřó ßE…ľ$çžé™¸HčĹsĸř‚ˇ™um]V-ň0Ňň3‘}Î˙™Ćśŕ.FwSß±îŐ^Ę{óśßŹĎˇd<š=JÖ¦ {ŤŔĽl±–''ĘšE0ř°”ű¨`°Đ׼eô×ë°R" ,g·ë>ŃďzýŘZžáĐ×Á=SůŽMďť*ĺĚŠÝ ýŦ‡ó5®Vĺn:Ćçao+ŽąHq\uÚJ™CgÚď·Nw=á–f#ćVfýdQ'hş_ęN•č€÷.Ő¦x¶mčou;sĚ_)eăXMçžwÎ1í’:›2Ş×Q‰/źę:{Ôg‰lS†Á7iłÓPG7«±9ůřáÖ±¦GťUyX^Ć?ér}Á{ Ú®ýťą_M9·˛«ąý3źźÜôCö÷ą®Ęţů«‚îíŃ6'zuIćWf~K<0>Ĺšöź?#şŞ/˙3ŁĂ`?ÄľŢč*ľ‹ůaó‘Á§°ß»§`>0Iąc_0źňŞÎ)»#Ŕ Ńië9…ţ-}ćŔÇĽäBĚoţ`źKx3꼷0ćŘë·HEńJŃMşÔ_âž,—ľĂµÂn¬s´Iěąâ3ĚG 8Kö{[Ću‘vŇOťžw6bďőÓR‡KaŤ© ĄďnôýŻRŽĄ§ř›ńĘ6Őé•püžiUyŚý=~9WR®p Â *¨p Â *¨p Â *¨p Â *¨p Â *¨pŕýpŕ—Îm»Đ»»±Ç§oŇ˝gŇf›kÚöCĹŘ M ÷ś‹xëöw6÷kµNϲü `r|-`ďíyńÉŇt‡WŢązg:â¸Hö$µ=ëćK±ŠwAzăŔrÂf×¶>%t-ť˛ Söš k˙t—˛ŤŇv$±äsň-ë}¨÷b\ďä?hÂÇČƇÍUŻ#6K’č˙fŢń7L‡ÎńÓdžöĎüńT‰±gš!üŕoÚP¶É±…˝mWy ^&±ľhňô9ó7Ú{ÚŢ-˘¶o[)1ÓEoS°áRí7YĺWv?ęą–oý‹gO,éáľőŕ)7 ßô3Úm¤CgWż:ďC¤v$˝9źŮ3_{oťöOÁw,âďv}ËŚ±+Čbż]Ót2b?áľŘX°®ëůą5ĎZ?Ű^‘¦Íşl|«uJă{vĄąŚ8®–˛ÝŰűSFćÜ$Ź; ~ď4‡­ă ÷zá d `OńCyźďv„ŹŤ#㣨#çľŃżňNÚWÄ’.kizšÄ^—ŚčďĆď¬âmŃbă*)7íŰč?Äv‡~»/üŚ].߇ώwÔyĐ;ř ď ;‹źřňYř€>HĽůÍďîëý„×7uő}©Ź|Đimę3lÖD&iCi?ÍÔ0Ł|×$ż ;öG¤ĚŔśóň䥰}ýÔg˛÷%6C5™«ŻĐŐ<: öľĎÂź¶Ź@şËÜĐŻčÜ42Nß-mJć=ÚĘŻůżŞ; ßń·6÷ĺďiŚ8F ß·űeđw4{슶mś]śö›ś”9Ďđ$šťĺĄM¬zżGÚv4űeÓx<ęOđ^ňŁÝqţűîá;óKąG۵T×Órťsß Űż¸)ł˝<kÄ’?>Ř,yw0ţ{‘ŹhöZÓžm˙oSt…›y|@üă™>íÝé+ űsÍ{úĺĽÖľtŔ/íŢŰ>â¸R7y¦ËU›xÜ—˝TBďç÷^—Ą/(‰#Şqiřab ź9#Ç“{Ô‘»Lň\‡˝~Ă/ŮęxĽd\Ą‹ŘÖđó>íMůL„­.Řęľ#ĺkŤ6IüA–}8´-ě8'#†ę.Újź•T× ‹ţńY´ŕrđsGś÷Áţ2ˇ79RlgEţ±»›íVĂWŘË3_쫆'/Żĺ‡Ălüˇí3™Ňśŕó^ę,^[±­QŢ? üÍf¤|C˝_2rŞqIřĽ:w˝ő¸řG©XnĽ·0? ¸Ż ˝Đßű#ÎŘ»&ú‹q¶ă/ř`˙ ľCýÄ#ŁŤ3ű ĺZîşVŤÝ.…C;Ě·śŹ ţ箝r©đ1äš&e”í9üZëk2gŁîT›$műU‰Ăěý ĘÝ+ß×d~vĐÓč‹%ŤoßçŃ›żÇÔ±Ö}9÷7M;˝t#Q˝_ľ˙cyčł’˝ů&gfkSžŽđ"syçŐđÁohšx›Ôsü”ŹŔo˙{‚·ŁËĂzŃvżl˙ČÎ…ű]áŰ]Ŕ”‚Ýsp¦€Đ1ĂN}K*|&´wŁ/¨×Ę;N!˝=mGÁnmŃ´!–€ă¬ÎŔť°Ď?6Ú‡Á^}Ŕ Ü0á;<Ůş‘–)ŰŇô<™ö»Ą~ô¸;Ń„<˙‰Ü?Ýő.|Kúa×übJ_/é0ć¦ćUá ť_ŚĄĘq)|­ˇ˙U9ÇĽ»?9˙»ĂŚyŕgíŻ†ŻČěţĺUŐ•ßO˝Nąďź_ţMw~Ň4ÔűS°yĹýk˝Ä¦Ę;Źź¶žö—poz!FßjˇŻ/żľÎwŠßCRü/XôąÂď•ýŹ–đ@a¤ňůXYä˝ =ŕRt„˙ćYă~y _«sżń[†1}­th+ŁłS]ż9wĄ–B"ćľ.Â\¸QúšŽđÖâSÍgŔ¬@<ÜŻݧßW˛ËąĘ"ŕL*ßńËÓ!ő(ůÍ÷ôÜNł±gŽŤ™F·ëřů=ŐąłÄźźů˝ŚyN¨÷Wďęů‡Üi}cć€EťđóyÁŘ„ËĐ>®^ń7üDŹózJę\‰+JyKŕŹuŔy t¦•čvбfŮús~łń}i+ŻŽ°Ą0Főoűy ÝÓčÖčßT×®–»Jt+0)^Ε†z·3c Gî9 }pö{ }Ö& ¦¶ľtčŰ]U5Ď:^p&Ůőfä^0xÓ6|ĺ{spN L Iń}‡–xAşľöÇY¦ÝVUÝ˙üMK= ýëGçÔäČĺ çŞ…Ţ`0Ť±ÍĄ}ëňĄş^G|l……Ŕ{ŁA‡ż ň} ˙Ó~É'â8cŢš1ţ±:•Ť?«1知n(ČůŘTóžt»î–ňµFŹ6í2âxŔ·]aîĚ1őĺ”őÝ]LŮ4uÎt­Ř-uo9żźď˝›FZÂ’o·ë<`9ä¬GşžC˙ńkôc OqŢâËE˙Ť-ĎĆţ最ăú±ľÖác,_ězé<ŕçlÚ$ďÁ‡Up:ÔóűĄüvI˝®îY±>ÄżSľuîěťćřjČob2éôyîvY™Ä»[ô8î™5ű»z­q0:‡›5­n—cC6ĹŠiGł7y‘›!‹{Ö÷ĺ]F¶ůĚŽµĂ9őźţc˝'ú·óNI}Nä¶5zKmmÂ|„ÚÄ]"/ôĄďďĚť¨ĽCLBô#^úwąnô-Ä8”ů”ëXłćTř?®˛2íOźw@ęŠă¦?ˇj§,óúňrä’RfWjgńwÔc&ÝÇđ»Žđź$Mč(Ł«Ç¦gĹ.3úBc9rWAwß‚vQÎńČŘśĺwË[“9Ŕ¶b"W9÷!fśK4UçvAFĚą‡íßS¤Ľş-łďÓ¸ńčsŻYŚ_mt€=çjĚ#ý_“wć—ŻUSŕÓ‘<ËXŃţÍĆ_«8ż¤Ř3˘oÎtä„,×xçŽ-iĂĚ+RţĄ…9ơRF]ŽźD¶±ÎGA¸ÚĺyŔŇ:Qę»6±ŁgcdËçiÝawˇ™ßŻź#ieÚĆ)0čĚ3ť~9ÎşMGł;yë“… ڵл42ý)ć XK¸Äđa¨w[ńűtüFa5°ľçĽÎr‡«¶Űu úřŞ’:.—‘mŽ]96érŐIŔĚ+Ńűĺ —iз׊©ńţČÝŻaÚ§Ösą>CŰúňJôOy¤L?ÓŢč§\łoH/,©{ý=đť"ŽďçŁkÄ1©sĚQ…fčHiżś;SŞůJůĆ"ş ŻGťkš°®şÓŔ ÎX_+ŃgĹN*č0ľUŢŁő来Íí{ę±äk¦ľ°.Řy•ÔIgŕHp­©K=GŻńrlŁćʿ쇝Ŕ´€ZŇ·ń^oţI©c¬s7<ÚŞ čĎüXŰĽWu«úîń©g–an`¸ö/tuúöFÎwă8,Ŕ?ZŇ śYuŢcúź9Ás1ćú,ö,G¦‰=8Ă/ţćy¤©ßÖč ůžs ňŚcaŇĚůŮšq÷1$?{ÚNF0%ܶ>—Ąí‘úĹš‰Đ1Ďz˝1Ń[đ·ĄÜó¬<iŮNć\ëáľ#żäQ›ŠąçSŘ»Ú]ľ¶˝EhHďbčVoBÖ—¬(ČôřŐ±Î+š=BĆxŔ.“ru»Žő±ěŽÜóňűľŢY‹~2t„ˇEË> ş‹¶m˙ÄXVß×gâ{PţŐÜĺG%ߏ´Ěßă’‡~_É÷řÓLÝKyć7óvĄ&`Žw=0˘ŻÄşîáŘŻ8Xx×c qŹř˝đ×ţ!ÖŽ~gä=ç)čÁ÷.kăü#T_ŘÍĂüý c˙÷NŁČźŤąb> ·©ŔŽŔÔG¦ýŃ&ŕgú%•©±ć–%zŹiŘǟ؋­ŻK켞·=á[Ź’4őZEöîk5M=Źťďl Eďď[ŕŮşŹóÇÚMÚł^ă·ńř4S.ťV:T\ëŽ%o÷Ž´śjô.߉f«č˙Ü?ë‘óĘ·®×Ö>â˶üWtp4­WđŽ’kťĂ¦;cMÄl޵hdyj2‘áˇŢË›bɉ2F{´Ká±~ą÷U›8@ŢÁ:wž{€ż{ľĚÝ0o’şD>‡uÂsĽh3Ţ·ś§Ţá‡EŻ=ßś[­Í“Űjď qŽŇŰúP'B ćĂ"×Vl‚ôQ´)˘ăű­ŃëcľµiĽÇ~ă,^gÚŐšAaě&íĘž7ßŮ´‡˛›'e“ń|€=$4Ź}>"k=Ë&QŻ×zǕʛµP~ŰíÚ·Đź+]26˝M˙»XĆŞĐ벅rîŃ{aęuŘPĐF¦ăş.‘m]fŕ#Š<w űr[űµăs…˘ßÜΚnuf{]c›Sw„?‚ö8óę㽋zŐŢ±ÚŁŁ®JÓ[Su K­§3-upőáĘł.ÉŘs‘^â/a˙жĺU—:'?TŚ EÓ@ú3ľ‘5w^?§y㡟vE\/˝ďožôégżą"~ŹĚg3í'™ľ»ř†şâęáaµ–Ç;X#± wĘűť}±|ö&[Ž-ۆýVvŤü6âx^čŔ\ČĐOl9­·ď.ěÓQOS÷±N9×$O6÷ú]›7JÖYn®ŰÇM˙!uő ÄÝ;űŘß]öłŁH;é×ó@U‡=m*~‚ýťµą·ĺޱӵľë-—ş˙]rŇ;öX×˝±ďT~W8Pá@…T8Pá@…T8Pá@…T8Pá@…T8Pá@…T8°)9ĐÓöŮm^Çš¶˝ zŤß~oK»Ö4¨3÷k”Ť“ľo§Gě e?ŽűUÜU6Ä|wK8Šĺ×űQ´!ĘßMÓl?Ów豟¤-A‘Ţž6ÄőÓÎtóŁÜ^ţbÝp_ťvÚ†ĺ¦MŐBřĆ+ôw°›FŔâl=ü|!Ď´?ĺLřÎ d%6ŽâáćB˝ŽQÄ)€˙˛±źjŤîX'QŘÂîďcL5ř¨#N×9bOB:Ôţ+÷ÜăžD˙ŢéMô;e’»„nWłŻ`g´™ŘôGiĘŚŮ‘W­`PůTčú@ű`X aNâ<隢ĂŻNědŕo†ú˝6S^źĆř@l÷Bl,…;Ĺď‚Á•^éT6íůŻ«O1íŚ6"Ś+O:čÇĘ=vúď"óÄĆ"\©W…ákŚÜvf{µ_?0gĽaëhß»ďZŔ*ąŘĽc/żëł_´Ő­ý Ż‹şě“r˙ŽCÇÖĽíđÓžMăYĐy¤eČÄ×yfÚÄ–¸BÖ@úżŢş„Ăg÷™†=|>—•ÔăŠřaŔ±Pľ®ÔeĐóź€NŻ26†ô/%™ęÓĆWĆ_±á€„­/ř®„|’¶`Đ-ő;Ôű‚źńĹ&eţbhČąâíÍ >â3Ú^ÁxŚ>ŽÔI›Qľ}±Ă-~S›¨3ß Ć/őśé¸ßŻŰüô|Ä\łbÔŰÄ>YŽXhç‰ ©ţüč^šľŔřž®ě˙2ĺŃČťňf‰0®şőtsߊ}ŃKÚ”<(;u^wĂ 1…ÎŔOX÷ 3°WCÍ1żŮDľBý…>ě'đýŽŔ$čÁđ–ď ?BŔQ±Fńnp—W0™(qŽY蘭8cë*ĺúp(¬Űżü bđÔŔ·˙Dřk¦ĽăCsOŰ„ŞŰdLĄËם-téßú¬ňWż`“ľ–_źĐ®3âřś¤ŁőfţQAßY!ÍÝ®ĹňzĎôc|ŹĽŚ?˙ďo ˙Ç‹fŕRÎ`~Ŕë˛Âçuv·ÔË@űrÎ5í<Ź:·FÜS÷žż•Ž­Şb[„˘¤C >sĄn˙í} |$U•~ŠĐ $(ôđŇdfň誎€É ÓĐŁ‚f@pm|'€×Ä]Wm;#4HÂC¤GPč (4ŠB´QVmŔEY„ ëň˙ľsűVUg2ş»N’˙Sż_RŐU·ŞÎůîąç>ęžď˘MzřšĆۧŮíżýioÝĐ\ń•ux3=bEÁĹv&cűqmë×ÓÁ¶uµéR6ů^¬cŽöŇîN0xŢÉ…Ŕ5ňé5m”˛i×µľ‹ľţŘĄ?b»5ľ1†ř)pľĽd† úô ŕ-˛ů|ťË8Ź“śßm%żü'ĚuţťcíŕźgźÍ÷oť-GÜřůňŹüNbQO¸­…$źQĎxeüÔłßNŽG±iđÔŮ6e‹”žuŮNĄ\Ç$^đl–żťÜňśH)¶júąqđŚ´—{÷îŘ0Đ-6Î6‰•7ü‡ŕQ•ôĆ~kűí4ú´Cq/Ż Ł)<%”•ňmĺÖ¶ó¦şW#žqŰŰzú˘ßX»˘p×, ="ţĚÜeţ3.㼩»§sźč€5ëW_›ßfł8Yđ8 ­wDôč$çÂcžw »Dę7ÂŃ|ćß~l0DÜk”}úö±†­ÁşŢ'çmYčžş<űxäÖ5‘RΫŻčă#‡^Ýwtl}ŰNĘ>&?¦m;©«'űŢŽçž®ČQş c*p{Ď ťp‹Ë¶ÚJřrţízźŽź7őmĐČ<#¶l术űÇŹvgEÖbć€5hkŻ$uS*lâĹiźĚ#¶MčÓ?…:g˝äŻ˙sT<ľů2‡eu1Ę˙Íbg´o8PÁ8\ŮľV×mmۦ ńŹ/í^ť2»ődż¶™MýP”~ťţťOâxőĄěłÇ6 Ä%ćţoŐXľľy ­˝eŁhâŐX,—ö÷€3)r€× zo}ťŮv˘=Ó®/‡ĚÎŽČźÓc¬Sá}ş@>ĐŽţB;8yŰz˛_][ه«»"Ż÷rzţ(qaÔ—íE[o»=ŮrŞřůG»ďm±÷—{ݍ+3ŕţ¬űm=¸bÄŽ¦»GáĂO{¬ç—FĚÉďMÜwsůźëÚĚŁYÄXu˘>şÄ öG(+ă׹G|łŘH¤ô•ÖDę@`·;Ć$~Žú«Ý=ɉˇŻqőśúš6<ź°u7ćMą÷0w<ó]p]Ţ-şÓÖčÓě›ČC N(”ąúţpiđŐŕä Ęl˝ţşÖ.ászľ~¨`5ÝÝ$ú±ýbÇFyť}ăÓ“Ž_q'Ík[3ă[Íĺ‹ÁÁűVŘőËD‡đHŰw•Ż9m>ŽN€ŘôŢË×Zî˝\9żGŰi›ˉ­k9ĆRŮ˙ ńOSÝGH^“Ü‚îÚěëĽçÓßs\Şí’6‘Ú2‹ŰšÂn‚Ć %čcŕÚôâ.çĂg›7#ć±`úă™vŻÍoëI›&¸źě3\€6®c:’ď,źĚwć5}â`Q.âOą×s°Ř¶"ćß<÷ŘE—g;Ô•Ď ľsks} p·ë‘‡ńŚ7HŐqămůÍ©đĎÄ&‚ü™LŤ1Ϧ[ ďöĘđxćhŻ-ÇňđŮ0°›K“żőţpËoţż]yĂłqđ`{cbÉäwcvL(řıüÓĽ`b­řâµŕq—LçŰîÎ%{ĎPäUwYS,ŕ[Ý]‚ mĽµüµ)C!úlÓvĄ®öĎż>?Gć=¬8Ţcđ6oJ&Ç6“±0ňŻž>Ń9#šLîhóß«öŔřxZtĎôuFţ#Ęş‰O›iŞů Ú9żkË=ü¸<űăµowćŤ ©ły#˙Ďn“řWü#´ĄđťęCÇČ+É#ÚČŞÂ7ĐďřF‡sě:± K~ÓášÎţsBˇŐ迎€sh0ş°qŕi´=QźţčŁ+¸ÓćƸźEżyYÇÇ"'ßeč‚í˱ĽécWZLů·ľ¶'{ gý‰C1Nr‘ .Ű™iúŚŕA›6>kˇň77Ú'°Ap ‹,G'˙©óÚüľrŚüÄž*Â_çSq u×ţQrőp 4řDŰ\\;Čsě5|ŁwoÍěŠzά3VAĎM·0{ó˝|?|{ĂŘ{­?W˙fÚpsą$¶€ďŽâ—G&úđŰć“Ď;nď<äćłś[kܬä5ޱ W׺6.ܦ_Ś=ëVŽăŃć*-͢;mź¶íěsŁč {?VîÝ^ňđR\·¶M™ÁĹČŰۢÝŮ)‡m+ŰĎ<&ń´»š1Fř5ÔÄkń6ú'gľEćŠďňňÚ¶Ă’É·xş|µ¸ˇkŔ`¬żŠőP>ěZ_5–Ot˘ďčůvjcężtś<ů#'Kűgcőé€},žÎ|ł[>5Ö“}Ć@ß'\Xú»6VŹĂwŽ#çđ˝¦mĘ|ĚN='v€q}ioFJŁýľ_tă;Öxx /ßÁ>Éâj:űíĆŢF'.n†TřĎh—"ů^:öxôptbÝ›1ô/Ö9C§ľAƤíüŮOu'řÉp:ζéü}Źšýć˙íoß/±˙pmţdÉĂŇŕ…˛wr;€ëđt±u¬­!:ó{Ž} lŢkcňśőUKżÂčnëV;§`Žä{5ç}|ř{eiGĎP_¬U&s¦|˙ÎłŤľťţ€2 >ÓřH9O uóŰ$ĎŤôi™óg1XYÚ_|ý=íÄř‰F×s¶|6/1Ţu`›čĂą˘ůf[Ó)ţńČ—ÄÎý<őď›ýÄĄóŰč`ľŤ?¶.™|¸fÇć<Ú¬µ9(VWî_*[P§żtüRŃ7¨‡Ő7Úĺéctâ óń]1řN=VE@PE@PE@PE@PE@PE`6éxć’‡ćé ŹŮâw(Î/<~ʼnńekNAštü—grż”¶tśßd(»ťŁJé×f_ř6gô9hŮQń‹'n®}łL;V7ă{]—¬ĄnćRđ;OŁofţ‡™ŹidĹĽ}ůćĚy±Ů©›äŘpˤăś?„9éı&ďÄÜł-ńťčĂÚ¬Ëyí¦ż„·‰˘¬äŻC s„łŃ†řż?{óh‡wřŔ5[ň(ôÜ<#ĄCÎ÷Ĺ\˘®ĺ»1˙¤17ąŔ÷éż$ĂB]3ßÍĽ5slbxÍ1őGś°Ř.b@eŽăúÔ§js ŚÎÍĺ绾ťŕ‚yčŢśęÜź¸µNߎëZd[7zMôçržkaäüZąä\ě? _ç‰q.ęxfŔťiú-Öşpź€9čîő(·sĺ ň5Š9Ď5Ʋeb•–×Ëł§»ťy[Ë|.Yfź{˛âűVËíĐźHq>»gËĽç٦cíÍ7JŚ ç„a \ńev~ý3Xµ˙öą';µ=ÖŮݵ1,ĽßĆ‘Óó “?gćPÍU6~ž7ɧf•Ř÷ťL‚Łâv™…5ő<Ý7V/Żůl®o}ťw:şŕÂ\fł–3žC_&÷‡+7F—Wľ)±*ś§ŢüľÄ¸Ç—/îo;6Ď´őéĹóĆ‘#±tŇťč;S| ýkúH!őě4;%ułĽšíÚ†‰[@ż 6nýµ]– SąćT¸m˛o_‡ó{ç’kWŠ­#-ÚfóĂÉÂ:ţËČF|˘gsĄÁ âC˘RÎXŢšĘ;`}Ô·xńQ¬‡Mąi׌)1óyąnęŹb´mú T8¸ľůn­ąâí«'ű^|laä ÄpüDâ¶®¸a¤=źQŢ?ŮÜ/O»óŐצßěF,ś™omĐ™8BôI…'1}âFżŮ1Ý˝ÎÄVl·sŰLÓžÜh‹ü˛){­ł^ňF´1řÄ'H#üđç?Ż•Ą\]I¬%ë©đ’Ű+86a$Ű:˙éc†"Ź˘ß)}–Ip€Ë¬ ý‚ó={ćŰŢş˘Ü)˛&.=Mň|ĂŔëĐÖúĽô«‚m'ú¶ćňžÝđţŇS_Xµtëř/Ŕ-\Mü(Ópţ?9ĹŔgNłkĽ6/ŻmťMňĄÖ÷›Ű_ †ßůUo7ÚEÇd˛"y|E1ł±`ÂÇK1}&Źfů•(ădßĺ×ŘmM"uFŤ‹%!{^şěGlËĆŔ(Ř €ü­ëA]u®pgqä=[gKÇŮväłN ŻÇ»M]1ÜRs˝ŁÚôiŻ\ăzśyjâÄ|nÖDęl§Ü{bb'$_Ńf}Ć^ĎçmXßîä~&öbăeí{Öf?‚5Ć)öN>A{~ëîMä3Áw×ń\Óž¨+Ě9Äljm/ ]Ń^ ‘}tâ"‰ÇňĎđ0”Ż–úĄŇrżÜKnřü|IÁÖ‚Ř×}gšžhË_&¶ň,ř˛SIý@_h|(>\=Ζ‰9Çü§ţ_Źü5˝;Ö“ýŠŚ…điđ±ťÇ$ŢNŢa´5·±őňÔO­ĂŐŤmU´-gż•ü@¶îťî6Ľ–LXD±ipt­^^yK]™>íňHšs~~ÓüíÇ&ľË>gş;*yôăöZpż±úNŃ!‘*ÂÇî^¤ ńłäÉL¤^[çűxúR­ 2A]őţöG»7y}7űLđU ~䏠˝/Dü•›ű…'g0fŐČ»Aę®eˇ/ÖÚH˳ͶËDZ\Ż~eio)źŕÝ’űĐÎíÜŁ´ż|OkáQ¶eX·o¬^ö™Řż?ižl›qŽ'Äm[cuNaä.)O©đv°ë] ţ™j§YŻť}ÄÝĽ<áXŕp5/x±®·ńŹ´qđÄRaĂŰ„6VbK;‚dënSOÓĺ/©ż;Çňo·eÚśÜę˙ÓÝ }ůŻ{2ńŕ(®űÍş3R2íNËĄ\iąĐĺxŤyµížěĄ‚Ú3žMO}2´c÷—ç&““Îľ…Ôy]QŚżÉ9ôEĐ?}›cű&[]Uďvýfň˘?ąL»‰}Äeˇ=+·=xĎŢ*}¨ŢŻa¬ăuuíŞrďý"/óĘÚ+|ą¤A<ěšÖÂ÷ZË˝G¶FĆ8Ă9’¶ąĽ09FŇŚN|TÎsJ~ÜćËYĄů|ę}Bśýţéî_{v•L’KhYôÁŢł˘ł:|`»Z™ć˝Żi{®©ÜVî]!< –ké×XţřčsM»K˝®¬ôpňóp?\ß„qä.·9ş3WĽăýíóÖζÚÚ˝+a=9±iôűŇ5/§Ć mC‘1ůćňfřiĘ\Ľcô{yz`ě_ř•釜GĹ®'ű.ńýómgĘóxovjČi.Vî­6-ʞ?BŚĎîT÷ɱ˙ g†•űoۧăŚý¤ęK¤Üóíó˛SiP§MËop?z6Ŕëŕ“j˝v4—ŻA˙oPúTöľ•ăE=¶j}ęš6|łť‰ídßęžaÓ›˝±ąúsóő˶ýr”ťZ{Ëmö'>˛™śý‰s<˙dĄ˘]ó8Ršr†ą´Üí=ŮŤ1RĂGlÓúű˝;šĘçIľŰ>©mľŹŔ3 ™™…‘ŐRnŃ^¶ů=g] žáęÂ8oŰŽŕ·–J‹ö&Ɔ?e›^ĆŞYpoýŕĂ;–Wě·Ž?ÔřA}Ěç[[óütmüŔÔ™vĽceéXŻ,Z9@1ć•e{qţ1ÖŃŮ©łPž·—{/ŰJźeyµ>ݦ·ű{dśm!mÚľŮî}ś1>/ľČ^á~ŔůŤô#PźÖŮ:Ę­Řő…Á{Ŕěů˛Hé(g„#ăúrřLÝ…·é „č Ż‚gVí÷.´‹.ąÇňËEçńĚž˘ó©ááv~s_^y-¸ńze|–íϡȅŕOS'řÓÚĐŻźPy…ä=x‘cää;PväśíËß»đdžČŽňýäcŮÝ0°JĘ:ćItôěéĽkđMbçĂŐßBţtÜÍ=%x îik-ěĐ~kf#Ćţ|.Wč űIÇŮ?ĆqWîÂë|Ł-_ĆÖń˝4jýSŤg~l}›wÓt÷˸0O$Rőa°o)'=ŮĎi™ĽµďńłČľ<řFóŰOF,ćąý.açQP®|ŧę/~Ź·ľÝ×7˛QŽ-7źŃźcôçüŁlo*šoÉ•–ÍçĐpśĚö;¨‘ÁÍDzQ´ś[#§­żđM©ć{đŤŻ÷¬@˝•çT/Ć´ĂËĄ^š“śťĄŚűőŇÜoiĽłFď[ŃwD˙?Ú‘;H|y¤ôE¬yrĄřsÚ¬©wBˇp%é¬OĺđŤçgřďŹĺőµ4Ť§Ů_—şsĽ¬-vřŔç¤ěÖóĽy¶+é8.ÚŘĺ÷ŻklR˝Řž·őYsřc«żÁéúôĆNgm9¨Ű\ÇŤ­Ĺ˙M:«§˝Űţć^7E@PE@PE@PE@PE@PE@PE`ë!Đ˙|Kś\ů‰ĂšŮîéű;G¬ůN…9sî‰7ްŽ\4†źb)}ż2<4v^祮(ź#sĆ3ß·XűM.2\;2°óŰX˙kş{“Äó[<çQý˙ngt1˛šŘó ťróšŮ8šsyŽĽ4X'±S÷ËÚŁ“tSáaÄ"r.ÂeÎUĹŚĚ© Ţoźł¸{Ł+çsĺ`|ç¦óĎĆFažâ¨^í>Šů5\›*žÇÎŮňMžë‘Ýš‘µ`› mĚľgá}9Çk˛cýqĂM‚ůŞą2F*®'|’óźµy\ţ,™/·©xYtçňă2‡kÖË9™»ŤX"Ţśwugm>ěÂëißčçoą·_dµWěľÚT®Í‡{…C;0ůmî«´|ŢÝąüÄÍü+Ö„6é8—óĄšË7Hů·ĎALbĄG—q9w|ńlÝçUočŚő~˝9O·b]`Ę<\Ý]8h"Ą$ŇÜ&kčŐü“U s¨îňěb¸şâ<žßŚyg"ň­ÍŢ-ďčOč˛>đn^ŕdňĂ177ă\°Ân‘®r/yqĚÖ\~ŘË{ÎőN…·qĂ•»Ë`Óž7u“§3Ď1^lŞ{\Ň‚E®qÎg{­Ě`n0žM{Y¸-ČćżŐĚuĺďÄŰw¶^Ů&2cŐű—ŠüŚkËďÔµĽ˛ŇĹÚŮ’.\ińć1ŰůtĄŘu1ë˙ř\rőĚ4ý”q 2g~ˇôţă“ ŕ{0â_>çpNópő>§µ°‡—Ď”‘[vę=˘Ó%(§Śý-ěvҤă}ź·ÁѲ®=ç©3íčÄ ‘˙ žYŞ{ídS1#±T\ŚiÍf|ý5_{GńX->óĹOď¤oŠp]=®ýÄß|Áş,%eţşćÇîńô°óŐAĺŚNě)8űuBW”ôň»Üűyx{ßs›Ăü®.wVĐVL™oO{1Ôo\‡ô ó sĎ=6žŮyś/ë$Ó¶v]>ůšpup®/ĎsűÉŕCůPř-$VĄŇbř•x \JÔ“±Ą<_îíîŔů¶ďâäxkaźŘŁÝ˘[pž6ĺŕ†őÉ;×ČăDęŘ饉ŢUĘ1Ö‘”r0[N;ßĂăwxNµ+ÄvŔ±&燫 ¬Ţâ0řÉ–éšÝ̧}Űş‰Ú¶Â‹'î'w8xłÎ{Łý±.Š|ĎéÉ~It˝¸fżĽ¶;|/ËG®x|¬?Á¸@Ăé3Ů÷[Ńa,˙SÄíçEGë+Áł…ŘÉ[1řIĂçóYôĆ^ćËľ1Ç<Ŕ‚Ď—X=QŻxůD]Pu¬,­^ÇÄĆkőµŐ‘y=ŐÝçŇ&x?ĎsCÜ'b.żŽő˘_đř¦Ř>°×´Ő«&8功”}2ą‹'‡yÂÖü_oCC‘şŘ–fŰi˛ď=›˝·rŐ]ŹĽ­ýç}żŤÚ˛kcň©/Ď E"ž_Cü‰řşDę$‰m'×ÔŤ#ŁnZ+ş‘Łb¦©1Ăťî›Sżű©i7Źí2ŁóŠr{ kÜ"ôWŕů;\4•ÎÉ_ßÜA"đę´Ż*|OüPOö#knydÍÚěÁ‘ôŻ"w(tF ~ObIl¦ÜŕáÁó~ß~t˛¸e^ââłSˇšżŻĎ7Îe·óľ #ŻŻ=wţl;č{ÎťęĆsĂfĄŠ|nb!ż‰řďÄ׎g.żRbKq¬ç%Źl»lĂŔ;:+—–ŰŽNţ¬‡xst’eĂßŔÓ!ĺ‡÷  ř1?ÍÖ;2ů\üxXösÇ3Y¬ÇLžĂm¤ÜµţţÂ×%oP‡"űŤř˝w]ůöeÁ:áhǰÝͲÜZńô* Ţłzcő3^ý„ô-Ć=ܡ-ŤŽµ˝WbńL>Ě_>Űr‰8~ś8ŕDŮz+ń‹N®žKĆ×Ď?"7 Ű’\×ÜpťńÚuü˛`µa`ÉßěÔż ľö•r|jřř4ĂIpŢT7|ÇÁč·n#x^ť?żçOçG»ŕóĺ]ŕYţnŚu%őŘXmňü‘Ő2\y‹ČÍßÓÝ}uyŢ“}őĎŰ<_„r,|&đŻ WVI™÷ăęHiŤ—ç¶ äĂťęľďť?ťÁO=ż>Ίü6ßÁíôl'âŢ<­Ţ§†żâťËNµ‘1˙ŰuUZ¦cŮ©}!ďVÎłgU›Vv;Wôĺý-…7®Aßş­ŇňŘ۸l·˛,çŠäH,Dç7>'-||Ł!đ˙'lúË҇l.ân*ďĺ—Őü,’?©đA­Íď»¶ši+ –ᛟů?ľJʰíK'“˙Ü1výŢ™|ŻÔUĐUňýÔß?ă•e˙Ů;J¬(ý·[łW¶ţžc™|xhjvś§Á[Ąn†Žŕý»Ľy_őü%®>˝— mtc5ŃUzŞĹŤ”bµgy{˛ë˝ô…‘WŠľý‰)Ä‚ű\5ɶE=ya­Ď—][ü }.Űű¶ő'nčüď{'.¬C:ÁeďZ^yë×?[·Žu°~fşěÔËŰŃ]}Lâ<ďľ ˢż˝éiφ¦»Ó¨ ľ‹vîAuĽö=ółO _Ű_|ţ§Â‡{y N +ë]¬ó\čÜ0÷üp‘ź„meU:Î~„­›‡«çD?ů˝¤Ϭ‰^Q|“ä?řp…[i(˛WWWî NëCŘ_ç{,îćx>ţo¶Öožýôřr “Č\kc®O¶8 _}łÔă†k·GpžŐůs>m´+ÁĹÎPÜĎ<í}|g§rŐ=ŕP=ż˝wŕUč—~Ë1ß<N_#ßg˙Řîđ}/ĺa˙ÁrN1=yhnÍě?ExIí˝×b- |—ĆŘ€Ççúj‘|ľ]µď<ćmáĘU’ĎC‘Wąđ1Łłą¶°˙­Î°säU®řWçŘú;Wü/Éów%ż,¶my XGłM:Gl5Ţ<‰ß˙Î{äĽN>p’cĚ˙ł˘ŻŻ›}Żf!Źh{ĹĚEo.vö%^ďô˝"źů–hřn)ĎňJĽc=ux|ń„áZf^ö'^qż´7÷,ýPî§`;­?qz Ü‚›_\})?·jゥÁ ŃţWzsy,JK¶í&“šuňÔü;ĺŻßŕ»˝şyt"+<¨,×´ÓţŘüžú',Ü/ĘäśńŻb§‰ÔO$ŻXćţRąŁŤ%<ÉńůÄíů•%r¶XÜG_#ź±9-Ź«cSÂM ődWyĺ<ČU3WăkĺŢŐŕg7kýüJÚ:ćŮĆďY4gO=lY¶R Wus+ŽŤÓ†«ëbÖNm»Ü¦ĺľŇňňŰ+¦ďaő ¦hÄc#'}żC0oŮa]lÇ,.¶nŢľr±|Ă2ýKs?ÓÚőaQËÍe2rł>ËoŠ•{GĄ¬‡+»w ňű‹ą~EŃ´_x?Ë>őôűĺLł7ë|ŮSáÝ„G‹złWrč“u:XËu’Á˘QË®ŻĹ_;2ő4Ç 6\ýŮŔxŽŻůk_:úńđu¬×oöůŕ=/•ăŮ:Úß/ýTE@PE@PE@PE@PE@PE@PE@X(žľđď›rą÷™ű<༪6Ú—âśč°¶ů7eîç™pžů znzď’™gpüŠEWłĆŞůÎĘů$nîËîwďęrnýţl×aÝđřçjó-BXűé·4ř¸ť^KëcÔhGĚ#rmŚgŽöňóřd. eĎXŽ3żu}*ćĄ#׌y?ôµąT˛~§Á¨Ń´MÇçD~ÎŘ'+ĺPäwů ‹5s»ĚĽ±t|¬í OßdňQ™óÇůQÄÍĆLu·öŚtü–OůńÂöą‹·OÇemDĚQ´s2)3çIqÉT÷:™ŻÉĽŞ6]RËóúµ¤­ě‘ŇöžM fś»aî÷]QÎĎgnÓ/Ξń&ç€ě‡üĽĂynś˙ećö¦ă÷ő™¸Fę˙lÓóĐcGYs~şűikŠ ś»Ź5ędčĘŇ29ÔŹqÝLĂąĐ\sxqt …~yć)µů«ôSŕGş.ČŁPčGw ·óč1ĚL&żČ|k·± Ľg¸Ú„xâś'[V`űµ^YŕZÖľ;s×ě$˘ľ G™0ďä3rsr;"^ń]Űu®Č`c ~Ţw\mŢ®‘ĆÚ% EFŔOń&ÇĚ{ …śÜWp˙ŽĐ)-ób #ŹČŢÉÝn­.o­RŢëä~T[ëŮÄ/ĽŢ>ÎQ—ů›Ő¦ťÝţŰÍľ”±~{DlžyGżNź\›×čů«úôśŰ?%ů)-“ąýśm°ź üśŃŮ—cöý[÷7ßcćđůĎ5ďćzĹ­…mú´–Âű~8ńއ9úWÝNö%D;Ź“ńÜ…‘ˤL`MsĐ ˝§ ĺĽńаźŁ„üŕŔp¦>ąłËµĐ9OŇĚŹ]8ťţĹ”OŁ}µ©MěÚÚîxćZ=Ě+«©đŽŤĎT±Vy8úŰîť0‡y@ěÚÇ1 r ńü6˝±f.ĽźĎ ˇ7ꦉ_#ú9ćŹř/Ćů36şąÜŚ8|ŻOý1sĎ#fáŇ´˝¤®ˇ]g§^cťĆ|bĚ}<Űf…‘—ąĺ^łţ&9”ŚľéřĹ+Żó§ş±.ë'„«gs˝HmícpŠÔć˘g¶“Orö ż"ĆĽeţy%ŞMk‘Źcë)Ěí•x;oi⳦€őeY¨´\ćŮB˙ígŠ˝óÚXţťîŃÉ]°¦ěťÁzA°6qóťĎň|)ĎôCÔ“e‹{ćW¸ň€3ŃwśW·qŘl'}:ÚѢ8ĬÝ2ĎŔQNďw›¨Ňň[‰ŃĎž[Äp6–ĺ b-…ďE+-ÇH~"®\o“ăˇČ˝"g®¸OçĐCqÄü™xJ2–7kĂFľíšŘ”+Đţ.u´>‡rš—ű¦ş_hssťmŮ©Ź‰?«6˝˝s0ň ÁkŽzŚĐ/?Ł!óyţňúWh{Ý8rdtŔŮ9)}Gä*÷ć0FµµđϢ÷dßđgű#ޱqľ=5,J^¶î·ůkbLÁiăbmp´A›;¶ęŁÄFJŮŹNŚ‹ŹźiĘ{e9\Y >ĐmjżçW_‹i2ů=Ńż§»ŞĹëÓ¦{=ÄkÁöŁÝنüZ}dde^ŮXßáj±–˙µ:>sł:‹Ü<|·Tř-žţ†#tľő66Ä*'·Rä`Ü“ {ă0 Ę6\ ˇîrĽs%kźč[‡řČ3Łä='˘Ä˝ćЧÖ;Đ·çx?·=JOIś-c ÍţG?4żmÖĘś\d~ş­udt.÷šŘÖł¬sůtgź;G—B^b-zlŕjO&'%ĎZ żX=–˙o9FÝŐimś-(ŁéŽ‹'°Śn1#úµŽZ•8pČ+ ćYËÚÁą„2ő´aýX´žě‡¤ś0ÍümFg>ß¶7 üŃó-ëS×xů1žyâ'o=ÁÉ+úŚgÎG}ÔîСMŠvçť3Myv‹5ęWÍ4í-iůŽÖÂŮňěţÄzpě}AŽMĚŇőë*W ÇĘ^ĚSĎ×fÖµ6úúúómŕókĎçßÝőWOö}îᏠ|3ż[ţ·U¨wů·ş0ňIÁŔÄW‡«ďôěz­.÷^ÚţËŢÁÎÉýă+•ĤÉ}ĽcşűňYţ«^óÔ­ű߬QÎ÷w-ŻÁĂrzÇĆę6"×ěPľăDĎĘŻzŻîd]ÍóŰWžől$W|˝—†×¬­óxE­žB{ŻmtĎ–Ś óŻł˙ňł<测žlŮŻë×˸ĺśč;ł}yexÍPäŇ5ýÇ=б©xĄč‡v™S|%Úbfp®ńlükp ±đ‡uĚ4]éĺm¦úÎ(măă‘CŁ•«ÎßŃ›]S?/„ľ”ÓpѰo5sAŹ'»›;-z ;‘Ü 9OŹTř)źąâ«Łĺ^ĂIe´5}˙žěŢ3 #ç‹ďb9aš™¦!±ă SÜc\&˛Îocű¶fž7ź˙Ąď|ę*Żß}…ŮžCymK&đüpĄĺ—rÝôŤŘ~ô}ď™ęŢ© mrÁŚíµnÄ×±ÍçÔʱy˛‰­´o™ď=¸hj}+đ‰lý‰—!&ňńô/ŃŢüR”}Š™¦‹˝üG§łßüřz÷Ř ·=K;{i­&˙d-RzŞc(ň ą'XgŮtóą?'ş;â9Íx'ő[»ëÉž+ů€¶pđËúšŕŚz~'\ů˘ĂXAö+-WłóŰłőnĎż‹r°˝ Žá­6mţęw=·°e9¤Ż—=[iŮ^äg?“:Q÷rď÷ĺÜdßÉč+^fžŽŮćŠčs›ŕ®[ÓÍ·'ÄŹňŢ–ăÍßoĺż}:~řŔĎĹ~#»u8‘UíáJQ|m2y±k|z:~kfWçă‘Ď›ď{öĄë&7V{sůw^>ľ+9 žĂŤîĂ’ćxÁŚí=Ół:Ďźf[~rZĆ wî•b×ĂŐ_ŁLwrÜOxÜΛşÇ+Ó|¸H:—WŽfű ÁČvžŻgÚŇŕÇÜÇkíĚŃ+î–kĂŐ!×~+ašĹŮ ćă™®XsŮÚ­H"m+ľS‰Ýö'ţ=Úű×`'ČřŻ÷d˙„úřjp íâéśHýLpˇ~äýµśőců €ábŘ´Ő„{Łs íŮHé¤.Űç9´µáĂöö|Ťß·cŁöľŹG¶s–…&:ÁÓÓy+ĆC‰ |ÂA“ýW”wXDţ+ĄÝÜÁݱ“ýĐ6ěĽę=ž9ĺő´ż÷Š‘ÎÚg*|¸‡ŐD_«:ĂĂ?E<Í8űĄ­] ]7Yí¶´§żĘ÷3e÷]„ËŽ2ŁměNô5‰Íb,<†çE‡"Í’ŽzŹĺ÷ť+-˙î¤_w$“É´i8>„ďW/ó8Śľ‹mÓłµ7íHđֹ΍äxőĘÝĘCŹ%×kGOöRĎwóîٶ=ÓôyŚ)˝;бAĎ۲cöłßŮ(żÓńŻ˝µÖç2ů‚oyťËBŹ´CoO—JËýë𙦄›H-;ŕŘŻĺůłăůľÎŤ˘ß–ä0~ŤýĹ\ń]îňJ‹č ^H±c–ękóŽśűěا‘;Ţďź›gŮkŤż—|Ž®ĄP ď­¦~ęQ?¦'÷//‘cĂ—Čń–_ß˝źD~˙xpŻŘ´´·|,¬ ,%· ¦ŃÇÖÍ~95󇂿_úZfçă–~Űô/Ąý–tĺyÝE@PE@PE@PE@PE@PE@PE@PzNxlÝąg?8¤t|‡ăş0GčŤîOÎý€ü®OyKl<ĂX+ó]zńç±ÖK÷?ůµlÍ)ń?`žçţ0†Bâgűý ;7(0ź&ZYŠu’Ú'Ę{8˙™snŞMpł\€őˇcÝČßâÓ˛.9 ĚÜĆâ¸ÍzÖÄ óS]Ëkň“sjľZĽÇâ€XŞ7ş3MÇÉ|ŞŇŕß»+ĘďÇZ˘k±~×í±uËŽjŔ9éřµůŐ1¬Ł*2SGOĚŁ4c+:É1bísß8Ďż'{ Ü‡¸oŢźQżîlđYĽş›/Ë‹/ŢÚ1ôĐ0â·_‹őí'ť1ŠóŁřÇXĐÉľm'ôç(צ E ßçő'Ţďp^úâćŤ6ĆšĹYnżń0Çz¶2ßBg¨;űµčxfSgč‘L-O9ýM‡mâ»iÎ –O^!¶M~)ĆBrî2c‰l\ă6XÎsĹéíÁÚÇ"*z%ü1ĺ™ŘYb\—…îďśęÎD{˛ďŹýĽďvÄ‚_ľ Ě|_J]0·]ćđSnÄQamă§OUtGĽłWľyÝŹ5ń×·ś>Ľľđ›±iS·řoďÉţ.Jźťť:Klt,oÖUĺ\@ć•YĂŘŘ­ÍOŢíäľ)ó~íşˇĺŢbNĆr›Ó×]Âń+ đţ?—ĐçB·;cvnßčD>†5;éČŢťÄ/ńýX ĽÜ‡Ś=ęč'a§›Űĺ§Ă•UŐˇ·y1IđYŢł÷,î˘'źéîq‡íł…Íg#/bFĽ< Ö9w ~Ŕ“¶[óM&~›\©đ9˘3ÚcnâO˙ţ/ś[%÷¤Ă§´Ow Î4ę¨WËó#Ąוĺú$ä0˛ńJó“ŻłźšŽ[nÇÂČ ‘§48áĺku*ň±BçuŃţ˛S?§Ř/ÚżeÝlŰS•·«µ;†ž˘ßÇ#+;–Wţˇc¸zśçżODü¸i› Ť÷#¶ë‚ŰćöĽşµŽk}&ďqôcŮ)ĂeOV›ţŐµë"8gDÁʏ¦Üű bĘ.™yuź@ý ŢŃ/ţ°ÔĎĐśiw†öB<đ\GlˇŚĄĺ»ž|ňŁ Ňţ¦ß\~ʰ{ĹA©s¬žv?ŮNětt˘pPm>˘ýŔůóisoŢ?ź}çÖüm8ˇřΦ˛áUB~H^ŮNÄĂŐáŕäN[ujx™č>ĄÉeťüň…č3ě€>Řb˙C‘w?IsůŠčySűŠíPę±ü%Îxf|Ź·F2«ö3Ľ?¶ťż55űKϲ}p‹Ľ‰ÔŮL Ń€óYOďŇŕÖÜ’9DĘkâĉcÁ>·}×§Â;z¶aĎq?žIlVÖZgS­ŤéV”/ŤŇW{\`—˘u˘Č9Ýť­ń“ĽÜ+·=Ů1ńË3M­‚Ů@˙QžNŐ¦}Ýeˇ˝÷I¤NóÎń SÝ×»ŁWŐ95żČ÷×Ë`$™Ż˙¦Lb-ÚĹ7Šlě'Чs?ń9´¬opfĺa:NźÉľÄŽgšvŘ cž7És“ÉýEG¶{X&üö×Bękµ{ĎvČ]ĐťW+-ç‹Ü=YÇËăţÄѤed®‚ű`˘ďćÎţÄ«ęňŐ>ť:Ú~¸oEWiS,Ü~—[.ó¸†nÉ|Bä=|`˛ć{l<"şÂĽ<4śRé¸mł€ű°sĂ€á3 W–tŕô@ě÷ÍĺÎŰ͵˛ĎßüĘ|žyĂł2žÍ~1ÇîPŹľă™(Ęę_“)-śĄ=ŮŹ ßŢťîţ|;ꤶpĺť…‘ł˘ĂUÓ–ËďY‡ …Ö§Ţ&>ŃúĎůÔí/?ŰčViy&ş˛$üJHnĘzđ>p'µ#Îą}dâňŽc ‡ ۰۵l»úŐ\o*ď >ťřMňnôËމ>wźWżűo]l}}I‚ö6Ýť%{u˘ŻKdG;ŰócĽĆq'7ěéµ,t0ęő»Ĺ^ŔUâĺµá°ÍŤŁ3żĹPp˘‰­Ň7—žZ.Ç< }[lÚ-ڬ·6ľëĽˇ‹ůś+>ăśn¦ŕ8 ÷äz@ýNÁ_/ä ísózălĆ×ŕ;dMOřĺĚ·Ľ<´rW÷­ĺź)ř^×%Ç˝z˛?ÄřýŹęŇůěsgźŽ+ßć$“űÔľź‡B«×˘Ţąc§ÍŇßčLŮ›Ę'‹ Ü5ř¸¤G¨ěëůGËŮ’p-ë[Éá9ű:]¶Âł…éîKäxşű5˙şźÄ¦Rć›Ë{Ô¸…§üÎĄ‹Îć!9«Ď@ß÷.ô7VĘ6Sf¤¬E^‹ý#Q¶ĄŮfĺŢď/ŮçřOně##Żń=ő’ŽNÜ[ű.™ŽÇźßµk,żŕaۤÖNęďZJżl^ŐďůMb¶nţ¸Óľ¶zť}}ç:˙RĐ7¨Ăly-x.öĄt<[GűűĄ¤Łę˘(Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" ü­ŘďéÁ}ý3űźo‰›ąŕ&Í®2/śÇKm3ňs^®ť·Č9Ţ~\чksF>†5¬~ůß‘xa»s~ŤĂf)h~â Ź­+ŚüWmnłŃťóu}îsîOcöC1ÄMŐÍęčŻ˙<ŰHÇľ=®qÁčDÖáşívŽ Ź'űŽvÍuŁ7ă¤9w˝µ°Sl¸ş®n~¤?Ď37Ü Ť¤+eI Ż•*R:[ćąÝsýnł‹őkkú†+Ď:vţ=ĎŹg–Ç #ű".î±uĺŢŐq>ÓăZâZËś'G"ÚÉě8sű®ĹŮ>‡; Ł}żŤiçď`l´Ť˘ľv^6Ö>wXÎÁsáPĎŁ“_–ü.Ś#¸aM`‰˙÷רłoY¬˝¬_…µŠo Ƶ¦aŻżpF&úSóѡ†CśzQgę‰ő7ÝäŤËśJËëÝŇŕť±ľÄÄŤ~¬/íÍ[§vďJ>ť‡Ľ8Z›r‰ő4Ĺa=Wgcu“Ě_Eům-¬—Ľߊ쭌ԗś:´iĆíôd_'×+-Ĺh*Ľcť®ă™cűť+K“ř;Ę} ľĎ>gá÷F_ć™ů3PÖQąâ˱֤?o{ĂŔ/˘ËBi¬ ;ýxŹŮ #g¸ŁŻŢ)ęć†kń)Śm~¤Î—GJawűĘŁCúc8?üűísfotĄŹ …®p‡«‰@ýäK°Ľňe9ßZŘÓ)€×Â\©—ytb\WË5ËGÁ8ŞŕĽfúxp‰ˇ ˘ţ~˙mó}dtćűcc|•żĆëě·c­z±ßdňŔŔř0ÖŮfŽo(tt˛GĘ=}´Ő©µ°c,8ß—ÇÁëłß1żżŤľ•–;cŁ»Ů(“‘‘qËËE‡MĹŚ”ĎjSSŚb&ĺÜů4žy…ŕÁ4o puĆc<ĂĂÄéâ˙ŘÓ5m2+‘ѱ‘©j;( ^†X»Ý±výjÄ­lS‡Yvę.đA˛Á'uŃRgż=qíÇ»¬wG'ÖtÍ4-ÇúżďwŻ(®öęĂk5ĺ~tbwÉ'rŔń7ę6ŕuŚüÜkó?Ĺßűśń€ ¬,ý<šĎçë|=ďłeŢĎ÷˙tü)‰-…•m®Ę7ŽĺąÖu(dâ*xÄ-ŤXą/ŠďşaäÄż^.協Žm‡Ťt–_{ţŘ6ď,ŚĽZî« ż?fů"kę‚ÁéO¸ŔľŰ´­ÉaÖZh=Q^;§»ŁyďréwúŻčZQţ;ď|vŞqń§‰ĽŁ®Ü;ŕüë$çÚV¶kźč;łm(Ň.é%'s€w/qťřŚ)=%XqăµůÝŇq¶±jďÍ'AMňrŻěWźFĽöSbß–ŁÇĘ3ŕ|1/sŘfn¬ľűśáęFOŻń+ďm›îwbmK¤˝cž*Śü#|äcëPŽ<źkí^±i+źż?¸ýÉ–ŃĂ´WŘ®ú’';ÖlŻ“>OđťxűŞÉľ'VůĎ …`Km©ło–{G'Ž?É…đÝg»|˙wÇČc|.m·ĄđîÎkómŕzGÍŢ|‰‡«†űk•·v×(b);ł˙ň ŻŤ1ůxGó°ČĎ~ ň·DťöňţÍ©łŽťFBŕ ýˇ¤7ţĎČáżq!ŽČC3(uĘLÓZ´—ŁÍ÷'ƢďJ~ł3މ\qoçčä?yzQŞ_őÔę×Pťť EŢ(ůť¬ő%a‚#ÇĘçśě¦Â_‘çŚĺďsLŮZČşŠ’űg§""ŰôM÷Ě© SsKd?ÔÎ>0ři;F–++f.B÷›ÎGŽd>‹^Ś UVň˙_^ţéů>2< |‹“ËŐl1-ĽžËwĽEpłÇ#t’s¬ŘÄ€sq4\ůrĚ´›}ťÜëbÂ핯ďě”rh“ü\îß®ňáš?Xč|¦DuţŰă\ťîţ„ČĆ…‘×Ôňę6Ż|®,}ßÇm–ěÔ&ÇÍuvŽż|79ڱ¬´¬ 5_alËp,†ľÔČlŕ–BÝüQ©ŹgיםÉĂ ôťß6ů ŕíôř'<Î9űŮňÄÎpŻN…?Ř1ů“cĆúBˇŹGN—{6 ś,<Ő¦çńLóľ…Ňnî÷6 l×…ľ¤ČDÝśť]đJIůüXäÄÎd˛1˙ÉY>*˙`"%eAî(ă+qEĎHé7Čó ř_ôô\|ţ™ đŐ2¶ ±­IŮŘ×â¸ŐĘŇQpPÔŮ6ďdů4v ‘{Ý>íčäWĐňüť9oóÖîmęĹŢî8_Šty+}pĺ-ř5$ÇĽŽµ\ú#‹Ďm¬ľłť}d“—<ܬ®Ü7Öƶ5ü4ÚKçÖ8ŃCˇ|~“—g•–룳–<_^ů'řyß˙ť>WÎąiţĐRp~'cIVçĆŇ—Ň.>^KCÇą¤´:}đ[şoőićzĘŇ;WŻ“Í÷Íu^zšýu‰şŰÔsťł×^J{ęi7«łý­{E@PE@PE@PE@PE@PE@PE@PE@PţA çÚ›-;*Nţ3g¦^wžo.(sóOĽń†uw·^*|ő©–ÂŻt|Ď=÷ôć…q^ă\ë7dňoţ#5łs߉Ó\5žöéwcżÍÍpyüóÇ3Gŕś™?óĚÇN“9ŢvN,S>\›Ç˵č8onqą (Ń_ŰŇń»Ďý€ĚËeěLiđďÁÁ±ćň«"pîví\ü eŻ<°VÖ*·óm\-¸„Čćű_{űÂ_÷ç¬'Rű×ÍOe|ĆpŐĚë•XW¬+iňŢźż=žą4ćĎ“ăÜý)™Ď]y}lč˛'ĽXŕ…×kËo¤ź* îcLĹ-µŘťËďw±,â:śŇŕYŕ2qW…‘k¤ăÓ°‡ç;2Ż»4řśĚ…- ö{ĺ»Ü{Llyĺ g˛Ď®ďśW¶eyć˙ŠÉcġxĺ×·çOa-ň‘y»™ęXĐpŇX®Š]Ę_}O*óŘoĎ|Böců+ĺž•ĄeNvŞ&®l‡ă|Ű˝¶ô;‡Źţ÷­žÎ6îů••–Nú%ÎOg,ÂĘRLŇđwOök^چ}z*Ľż`ŚŐh-|Ď›ëlř™lęĹÚť}Óńrďh¬ąüuw(r¨Čoó:ú6[[_–RźpĄčśT[7vÓtśřˇjÓ]˘ăPä{˘c×fOÇńý˘C"ő“čPäDpCť]Ó‰6ʸém%}Oöž.ˇP¤ôAç›÷ňb´ëÎĘósĹ/D—Wv©ŐuĽ˛xí¤6ď„®¨Snňby6‘ZćŇ·ŤNěk-Ś´—HôBě+ô6:+OÎٸ¶ÁŘŢd ĘLÓ™‚çdß:'űú<߀¸bďţ…Ô2ŰŘ!?_ÄřmĆI˛­•ťşĐřă”äG 8䂲âOŔgq-|×ÁťĺŢ÷Ôđ)¨Ëç06”ééß*-ďŮ÷Ł›ŠűÉł†ضëÄkůlp >{~ŹÍşőô­·Öxr˘ąÓŔôNweé'uö”¸A_޵Ůyń˙`]A í˘3}YkáŹn>rÖ„Űćýwìß>{ţŹ  ůQ¶ô® žÚĹ6DâďśbćŤxĘZžĚÜÜą˘ ź~Ä 'R{ŐŮ…}>|<ÚqŰJ|©-öÚÂěÓqƸo8]ĘÜLS~39­ GJż’|OIűŁÝQÉâô3¸^}§čڏ3Äą˙\ň;W\&ţąôť÷ČµŁ“ÉŽTř´Y“ľÓťx…·vúÂč|‹±Ďě”+˛1Ď__|çvTZ®ěXYÚqŢżŠ±~šiş$z__WŔÇ™{ˇ`U|eôâ‰MíŐ¦·Ż)Śś":óMáĘU3MĎKě{2YěL»Ö/A‰âÜ(öť żókÇ·~Ż';eďLÇt÷NŃP&i›¶źĽ©řK÷9ś›ě»zď9+>b6±„äđů{×úŹ…Đo®wŘx^ÔE˘7uˇŚL›LľĄNçénđu¸oô“Óńó¦>K&ď®ůĽPhmökRîy?ëxp795^PčűgUmöĹËcĘ|?ü¬ä_*\Ď‹çő#ÔE'GK‡ĹX÷&“-1Űvžě«:çM­ól\[ŕ—‹2ßÍóÍÚł' ŐĆXSo?_ŤţŻěęÉîâLw_>­ďH>Źĺßcžĺóĺw…ęŤ[0rçŠ>_K¸r¸3».ĎšçëMű~1ő5ůlúń”#O…SâÇóůŻĂ÷,·LłŘ-ŰYÓݦ}ČżxeŇŤ%Rżň|~¸rhŤGŽĽsűIyźöćůţ>đ”E9 ĘC.·ŻGíxŹgú¦‡<˝Ćňmuerşű[bąâö˛_ó×»†"·‚ë#Ýľ˛‹—ÇŤŁ/µňu¶ţĆę:ŮgĆ|®9RĘěXţ’ZŮMŰöúŘd_«“©~^|uipw,ŁđŔŃ'žä\ď•s˙öÉŤ°÷ő¦4ŕĆ«ůq#›é˙…Bh‡‰_ÎN31ޡĐt÷ĆhĄĺ™¨ĺ3HÜvż‘o“tĺŢŁ„ĆčÜzÖË@î¶ŕxí0Ćü˘ňá×NţcŤi9Îďź ="÷nř~­ÓFÜ‚yťŽo¬Ţ.y=–"jÇËĐ&éź_”cA~« ë{¦-÷Ţ%ľovĦkĽ˝ŃýÁް>ŔŚplq›r6żďŽv´­Ł—vkg>çŠYŃmŔůfçXŢpťúe×bŘxn.‘/kiđ ^_wUˇ#†~„řfđkŐÎűw_űD“ÇĄďëí__ Gě[łÜ˛­L›%—áxf-ĆőľTóo¦?®<*ym|šÁ‹ś6KAÇąe´ynö“}÷˹٠r‰sŚ…÷Âź5@»rn-ţ÷g}˝™÷UçňĎŃŽŤŹłçţ÷ohĚ;¬>mßŇ˙mRuć“f˙ţ۞޸w[=­„ü­›" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" Ľ´HÇÝv]Ť·d®9BfŃÓ#ó _ÍRD ˙IŤ«„sŔ8‡w smڏŐčćOe8ďQtĺAĆ\16”űž›Ţ»dćP‘3ç\‰nß„]űÔhéÇ|›ß=ŮĎb˝Íť±fęjá_ńçA†BŮ©·ÄČbćÍY”ooy”F'.Źżë ţAâhRáSdŢ=c°‚ëëe§V ľ°m-MÝń*Ćěxy»‹ÇRßđ.5®Ţŕ([eů …úď‡ÎëdŢrkáşZüŚ]GëeOÜ'qI}‰čćďóžńĚŻe^óX~˘–ŢĚĄ?ŕőĆÚŇ2?ŰĆcÜ5¸bŰߍµRŻ Äη7wűđwú#˘â|Ű’É]ë{ҧ˝{ .&n¸ńň±î Í<6ůló$8WŰĆW2ÍwG&D·ÂČ Îxć­µă+˘=ŮżWĎޱěÔ/]''üqÎgo<nuMË:ą{”ü ú¬Ä «b,Ë>rlWyÖqŽÝFěqˇž]üüg[”)ż1ŚC°óĐ#%ŃáŔě‡$v kşK,uG…ÄYĎÄŤ”ö©Ů}(dă>ř¬űß/ţ\°đő_|Ť) ˱‰íLÇ'űnęmw */> Ľ2ŕ–úÇ(c¬Ö§^ä2öLâ‰IˇnîĎ^ţ2Žc<ó™.¬yŽşě(§0r¤<Ë/‹«÷×˝UĘ0â_]ęő8Ęőt÷Ź]pžŹĹ¬‡śG‘‰+ôm˘Üű8ř=Î÷t¦6|eiRĘw¦:ĽV¸¬ďy}j‹1hĽşP9•b÷—ŰĎEÉ›ł ől®xŚŘ¤›űęjăJ©˛SűÖbŠľíŮrPÚŇ áµ!źÍW‹‡Ĺšw˙yÎxćgmv ¶`l$xĎB[üÉŹ“+^aěođBOĆ@n*ŮUĽ3zmţnÉ»ţDłgŰVVÚěë¦`|·ő}ŕqq/šřµgóÖGŘűgol•6]<®ćkČAöäD{DÎŻ*üőĐwË»v6 üŘöLÓjékW6Ř0?+N˝Lü¨_.GWľ5?~ʼnâ»Čĺ`ĺ` ~0?Đ–öôńŰťéx¦ş b ÍzçŽ%ßEgOöKb lĎPOÖcáJŘĹŘîňĘi±ĹŹź´¸‡B…‘W»ă™ďB·G:6 ĽĘYź #oÓbŻ îË˝GÖěm«MOöŤ« #«–…Ňh‹5{>ÍĆř/Żl-Śß>ů\'óŰęÄ{śÜA_Ĺ}}Čý­…<ű€Î.űš6Fš÷,ćfí¸?q^ ±źžśŕ r–W~¸XĂ[Xy«\kţüţ"?eŽ”>%XŤLô!Fř6/ŹgëXq‰74m¸ŮWú·µo´EP·Śĺ›Ŕ7ňAOďÂČúÎáO\ĺů¶qđ:f§®†}Ł_0ůFͧąÇ3Ž``}—Ő†6ă×ďöěbî}˝iëwż>Ů÷O÷󦋎Nüw¸fĽň̴ĉő“á&ňuË—ßgˇM ž.bĺ§ZĚ#_gÚ98îD/äˇWĆÁWŕĺąx)űěĽ$µi:Ŕb%ú!VXô7uöbę9űÝVo˙üLÓoÁcp™Ôݬ{ĄĂx”ëkń“Ä'W|˝{b°wד}]]|ŇXţ^ľ[,sźŽ3Ţ qŢXëű^‰Ł©61ĐƢ0źŤýň\OöÉOsî:÷ÜÖfwý×§b [eä´ş‡!WśF ű­1هŐqö~÷“«DÝÜW:›ËFo­é<žůÇÉť+:3Ö>׾Ą±öF'ĆëNöqí×—§Łk°–ű§kń&&×t׎gĎÍĺ=j1(V«ŮŮóŤ´ź-c:^řÜ©]…‘Ç=űĺšĐ6ć†S”žńX©đAâóła8HĚłLĽSŮgó¸Q6+÷ˇĐ†«żěEFśÉo}Cň6W|—đ“ëÁĆżgĹYYŠu„+g¸ËB_\LL©Ťű%Ä÷ęlŁQ´5r¤ăŚůcÜch©źÔdçDő󨇎«“Ýčmî,÷FĺÚŠňé.ůlí—<'˙XąwL®Íć(j ÝÓq–OĘ2=ăóů6OĎ ŚŢ5źŘ]ĆTŃV§»ŹpÝÜ^ôW±áęő°‹íKz¨®´Hż6AČşšXľŔĆĐÖHal{Ş»[ň¨ŮFöäY1ńé&ô‡Ť—cĚěŃŕŰĹ˝ö‘ťÚ^îaJň÷2lîkĽňě—ĺHé-"wsą˝ć·Lů¦ä(ż×ćoŚ™řvĆJnŠĺóË˝Xx¦Eí÷axŽy®ői&^ÔÓ/Ţ–ŽÓ™źż‚ Ň×ţľ23tŔÉEÓ݆řŔZ˝d1 …•/{:c+zkć±(c§7 ĽĂKË6NăĹą§ăŚof{‹Üg÷ňő|‘s+ř*'‰Ôď=]śÜţž-›kďŤWßW» +‡y{Kćy2mľ/^ŢßlůúĚąJËŻÝ»á{ć˛Ĺ /Ö8HŚŤÎ4µ‰ŽŔ«cdâčöćňţ›Š™5C—Ř‘Lž­\eęv;|ëâ[%7P"őźhggkţ:úÂÔ/ťÇ…§‚Ľ;7ůvŚ2Ŕü·r#6ś,˙Ö¶>ő“5Łë:“ÉÁ•¶[śih—îŕ°ě|¶w4ÂŢ/ŁVš Oljľ§ÁŐr•óh÷˝íÎv.ëg[·1}i°ŕŮtą÷®člŹF­źmycť8 í„č<–ßŐť¨zíO‰Áő8˙x~NŇGĐ6ăďúřŕÍ1ešĹßL<3ę¤YúÉĐ.©ĺ»‘ź}éńĚ…îŞÂ?ÓáúÚŠI;žąČkĎX,϶)kZxzŤÔćżis‘KéµŇţb}fŰÔÁt…‘‰Žçp§Ňň…hşúNáě`ŰĽ^_bŐëjź{†ŇÖY>Y÷X‰M;}‘Ăîöl˘ąüď5źnSY{¶{{ľŃöFľrďŐ˘ ŰŮűĺęXY:ŞsSńĺ˘Ó˛SÖ'™~ĺýŕÜZÓIž¸JËh‹»–ĐĎçFÓ3(Ź—'¡Dť8ţaęW?ťmOúgü#ßö˝gůöČĘ:{oxx(6ۧĚËćňúŘ©á˘W§‘—hiäí\ŕ§ăôŦ2ş“'Š)+-w:†»4O&˙É+Ďć)AśćznŁź Ęo¸:ú/Ôt4× µqß\ń!ŻŤŢčZýĎä3ú±ßĎoÁ˛Ľy»ăöÄĄ‘ĘĎs٧‘:8ž°4ôřżHiu˙żÜ»”ďů˙U樂g*»" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (/5Ňń˝öÜsÝąG[łt|Eů#17÷pś§pNt÷-¤ťű Ťr¶ř©Ěş]nąlbšÝ'[ţ1#”ПϾaŕ.IóŁÁ {č¶ë–”ŢýĎ· ÖbŘ‹µ°qŢ&ľ¤^gwÂXÁâĂ´×ĹżáŮÁ%˘·ťź]ż'‡Ť§ÖłőaLŇב&ČÚ›Ţ[÷;x­qŽëődľ2ţftâr/†ÎŹ%Jc­ď»˝|m-0>…1—Ź!~üí±Ć‹mßʾ΅‘_ĆĎ/şB‰ő rńV+Ż\CvSńxŃ1třó¬Úł[zaśOÇM>ůĂnŤNöť)~¸?12G>‡B7ŽŮ9ŕőż+WYKct5ńtˇĐÖ8@@ą-`ó™˙® ˝8ź’rN‹'[ŽŹ·ÇĂhËí·ĆŃßô#‚öŽłL_QĽVôprżw®Ío’üłR‡OIĂoŹ:Ů©+Ĺ·«ĺNđuHLüLS2P_Ű;kвŁâ›Ç}¦ăąâýí6Fâ4řóŢéö'B˘gĄĺÂZ]EžĎŻĄĹhijZ/µŐ%¸·)ě9űűĄş§žş)Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (Š€" (ŠŔ˙{Ü×?Ą${>.ń6űbw륲–n}ŞĄň+¨g:>ř}‹ăË˙™}Ź•XÁáęNUř)Ňń;®{ëfk¤űw4ú‘‰źłRNw7৆OAśśŹqâ ŹŐtn’XJ÷ďÇ)Ů»—Â>çÚŢĺŢóE—‰ľŰŁ‘ŇSťw…Żł{dtrs§ §ĹRÔ٬imô(ŚÜłżĂ•ÎčÍâXĎÜ#1¤LŤčY:űř§5î˙\ńÍ^ü3cŔ»ź}ąÄË1zKůh×˙&ůgČÇŐ¸ZÖKf9ĎÎťZ-ů6ŮÖĂ€1ŢÇŻ8ń/ŽƇ"×ŘŇ%‹5\˝Dt4\Aľ}FJűä`^3ĎŰM.©•Ąc=wŢę˙ćß[Źjăý®ĹF'~-úMwßkó¬Ć—D=Ě_vŞ[ô?‰¤eśűmŕ°áő§<^–ĆÓon‰‚zmď¦ÂWu¤Îţ’3ŐÝ3ĽöşąŰÉku9Ď8Rr“°˝2÷óń¬Ő‰{ł#Ję- mŻ›k_Eţ’ź†<ĺŢO‚—ĺ:—ÜĆě}ou2ńýMüŁgßÖ®żűÔż¬xŐ&‰ĺ71ŕä&99ÚT‹Žg69żéÎÖµ_]cúeć“ĺ"ŻN(t€;\=Á%‡Ďi®©ÄR¦S¨Ľ­^Ë+gÇľpö35n{¶±÷gÔÚŃÍĺsĽr 5·zß¶Żó›±í…‘ ¸*<}ç*­‘.Ŕ_*¶Kýv/Mş›ŠwzX·1ý=Ůż«Ąĺ3lŮX ÚŮ7Ş6}Zl6(µmgů:YÝ|^ŹúkÁ»ýŘđ3łłÚô>·Üű|Żßěă{ŔWÁú©žo§ŃuśKľ-ë8[gňŕŃĎ9<ćzbăź«×yóľ±˝>y~)oľ^6o­Ď2ZÍľľ”uť-{P·ŕ5{>xNŹE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PEॊŔyëÝĽ:k··ž Ů‹%5qXK‰U…c©đąXÓţťNóűľý¦^éřAËŽňâ榺w÷c®^ ›ŃcĂ€YÓŰjdů ú{¸7Žś_‹^ÚqfŕfpĚĽËWĚĘăPh6çJą÷–@ü¬Ef)îMľĺź¸~łxhbaů:ú—F©°pv,Uű6\4Fß_|ŃI&pńďµĚóíxtbť3ąÓŐîÇu‰],ĹÜ5y•Ž“Oftâ[żlµ±úšýžŚ×ÇÁŰtKiou ĘĚsţF=ö`múé Ź©KçßŃčGFgë›)-u JM;6úĄăýĎ·ÄOĽń†-rNďkěcŁ7őú ¸fl>Z™mŮe^“kč9Ä÷żň%Pžĺz¶ÎÄ‚yo8ĹBˇ[Ŕ1dÓ[\–ŢŢ䳯űůj¨ďT÷“ࡺśu®×§ńS/•#«ł•wöďPČÚĽ©Ç6żnď\ZűtüĐm×ŐňwK:Ůóvż´4Ü\Z«÷ÜěŢŻŰcI¸„˙Y=‚ű :Áó<~©lVŻąô ^{)éL]·¤Ď–ÎĎ…ŹžSE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@PE@°ü?¨Ŕ»Ż¤•nipype-0.11.0/nipype/testing/data/tpm_01.nii.gz000066400000000000000000004220731257611314500212240ustar00rootroot00000000000000‹|†S˙normtpm_01.niiě} ś[Uµ~Ę;Ľ2…*¤ĄĄMć‘IÎÉČ#SčAĚ+ęEÍIő˘dŞ\4EČ”‡p š)ň:ĺť)ď´"š)"*™*˘yÜLĽ¤ŠW3\řŻoťě=ÉĚ´´0Żňßé/='çěł÷úľµöÚűśŮkť/O˛ŮüGÚŢ÷ł«mŽíDúN*˙«ľ`Űt>Đ1Ďf›?ŕ‹8&ľ÷-°öąp ˙?ĚÇ·źqĆ)ßm˙úíÓžö˝éţćéÍş˙“Ăü‡€eŕ#däíFÂđHő9üÇPF|€·ĘWľĺńWPżŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1°2`¦5ě„błČíNŰĚÎҦiÎlpFÜ~Ĺ´máx>ôę,ś·Źđr]WţĚ'ö?şŰEőf¦ŁQ3o{#s',îlěgőÓ™=Í%äÝÚ¶;µÉ-ÎőFľęnwľÍ×âX0ţdC‹±±Éť®ŐúŹzEą‰˛ŐĚÓFď­kw&=îô˙6¬Oţ˝>sÖAľvgXâh1NçcBnwzJ]kôo҆óˇzŮŤÂ}Ť˘\‹QúÇ&–䕲Cžă,żQŘźx8„q›™ľĆ`üŇ*ÜmÁ6©Ăš˘Iö<Ťm¸čş†ëkwΓç'ÎÁ2ôFv‘ş©ôP•ýćCWzz_—\ ĚD˙<Şgťv垪ëI¤xż6jěN9|=‰s´ÜT}.0ôŇ6Š6c?ż_âîĘ´Sčroëł&!ݝúűÝĎĎý-}—­ź;őŐsÍĚąZ]úkŢpř¨ĆohŻĽď·­v&ĘąÎŇÚúvç>Rw+đBĆtňJ¶÷‰"ďHČ‘N.ŞëŤěÁţÉ™-j®ôƸv?cv~Ą×Ě|ľÁ™= Á}řîĂúţ‘c<ëčI¬–}rlÓřDěňŹ„M ^‡źVwχş†řćžăž˙HŘyoä"©×žăľÂăuM±łľ5úLyĚžË}˝6˙&Ź]‚«ŹŇÖ(Üér§ĎśĺĚ.•óĐŢČZ_óË«¸”° ,ď˝·qö5sWŰa·»ŁÚuFáÜaí_\łłnť{Ţ}hTűůˇş9uú` F!Ív>řřGă÷•NŁłT3­î;ź`ť‹cj«P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹŔ˙ß ô$ö8 ´‡Î*şöźůQg#n˙vU,ĹÇqŠÁÝ03ÄĂw§¶4FµICâÎv¤ľŃ,ëĚúÝşyŢŚÁř]Śa{Ú·¶H»h1äřĘîT;Ç MÍÎPŘŰťwpśPMq _0RĽëLÍtI[\» cŐ’\¦-ŘďÖĚ5 ýŽŮ2ÖĘ(ŘkWÎćĄŘđ …›â>YN3s\C»ł®ľ7ň #W©ăvç Cp›™ż»&Ů«ę“lÖĘkĹţ›Žë&ö`ü¶ĹpřZç,d¬)^[…żßq0ŮűË3ŁÚm|˙¦|:Ľm1nˇÜ«=5Ĺé,űÔlŚrs<çy>Ô-±´Fű}‹ĂWů–jo0E×ĺŮ“ŹrúPľ‹ńý™„´GHRtĄ;tŘ•»§Jg•’>»žüś•Ă%i—XkóYľĆĚ4i-ĆKŚĎ(\Ż÷$VĐ·´Őú*ë‹ý~Ç©¬żpxł§Ýůc^źü'ËGyJŞ8éw|źŹkf§·ł¤7QʦăĹËjĎD3ö`ü?ôšâ+^ĘßĂeŤÂ?µ¸ý>·›w>ôĺ[™#ńí]t±l“óßôôÜ,ŻQP®†>öĹfĆĆŰpř»ä›îó™™YŢSÂ×Ňxw8sćN[1ţýŮł}Üíy[¶ăNßË2÷FľîíŤXs¨ĘňĆygĘXökÉ'wýŢśŹŰ÷ńF5łˇµţPľ>úďÝ÷Îź0:­Ä0ÜľQř"ŹŐĎ…˘÷z/ŘxőÜ é ěŢ'×ĎnQ®+w7ő‘Ő|mo$ßDcŢNŮ6?,1×ć÷äľŢď0XŔ ĽŔ ĚBďbn•í%çť‚‹ťeŰ•ë’s/şG’@~ŕ^ţŰ2/Ő^™Žm»óbţŤýŹÚ'{ýÁBŃĎ:L.r|p9ő[1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (• ô$~/cF+Ź·‡K's3( …ó9„ĂĎr Š•—1˙Ă]7ŢÇă\=‰}ëł±g‡ŤĄŞ”·ßńÔ¬|čÎăĐ UĺsmhžîÔu.¦ĐťŢSĆ ,żŮôÉ’ăŕ*ů§f^ďČ?=Dţvç]łŽŤŰ%g˝‘9&m]ęŻO—Ěą)fô Ї·ânEă±í XźŐ3†tňliËQíł,sOâ$¶MŠ…”ŘS©Tť3ŰRKH9Îç23‹|-ƧOµßÝŁ=ʱýuéŁ|ťŇ7®óď•…ĺ^ĘIEů>Vę˙$Ľ”«Ĺ'Ę Ć/ÚęŤ8<˝‘GŮĂáÇ|q{żčZ§SÎĘAq˛ŢťJ ˝U‰ć5{Ą,!÷Eˇ¸ý@îŻ= «O]Kô˙{Ĺ6OśÇ–ňŔh=‰¶qѵŁ;µKŮźZG(w ˙^n÷JăNgµ¨vĺ$ŮĹוë‘|śkĐ#ú®;˝R[żÔ÷=űY|Ýäü®e\}ü»Ýů·Švî«Ř’Śĺv>·ż˛ĐáM”Ö’˙YŶޝú«Fy¦ńŔÇúy‰·RÂD©ąĚOë>»Ě˙Ř[/Ěťm\Ąwĺľ*ąĂ5”ĎHöĄĘ:Ćjż2ż™h“l~LíÎżřŚBá]ÄçěĹg›ÄĹřŕjŠ®*˝A÷˘>±­Íź9¤^qn<¶˝‘ĽýŽ(÷ÂŤRöĄÚ]R§­Ń•ľvçQşđ?…ŔjÖÝ ä—á›Ú‚iČĂÓxqý‹0S~¶íĺöł†ôűńŔ¸µ6IN‰Ó^Dż+ŮĎQl{“f~E˝®'ߌ-ľđÓŹÓ6=%'ąęN=%ë°Úů„<·µv'ÂqÝü“śc@š“ł® gčŰ µxç1ĎÂźĂŰřB(Z5·ÎLě˙iNQ˙|čΆl캲rK™™<Ű6° ̰mü63—ĐĽňKtOqYWĺPéşr‹›ZŁ7I»ěZt‰/z•·÷2î–kd×CëťČGr‘`“nú«ćůĐÍŢĹáwŘŽ—Űçč âŻy3‰(Ď\±!ťüX“Qx•Ćş Ny'”ŹŢžŁÚĆ­ęëÁäClż4·,—™ßhÉţűî{ËhNw¸´Źíio˘”i Îkň‰rý,±ˇľłtIC‹q5ßcĐ\EŢkĽ÷Ţd«śM|;*GŰŁ.ľżj .¨o1ž¬#ťół„ř“?‘¸w´Îťˇ|‹1ÓŚ?(ź‘ě 2PÄ‹3Ű‚_âç%í·<+ú őNÄë–ď94Şůůů‚™ąfzWîÝé âź›YďJ}·Ř˙¨}şrÇ;5ó¬©íÎ=§}Ô°)<ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹŔÄb`™óâmƓԥ÷q-ÂU›˙Ęó°h§[·ż>y%ç§HĄöv‡ĂŹ×kćŹ8ľ"˛1n3sÜx‹őÉë]G7+ŞÍpż©;ó™2·ÁÄŇ^µ4-ĆE"OEő‰Š_K‚_j|0Ůá]ź|H»ęËqŻťĄ§8ö†rŃÔÍ6Č8śŠKmmÁrĽŐĆÄg†pVYn,÷)MYÖż7öŹŕX!zŻ{}:ąň‘śÖ°)˛¶îűö›ÍĚ…?ű*c¨)†ł±YĚWMqę°xăhŤţmÜă ÍĚ•óúë!ńPFá8O:©łť.?ëžš]CůulĂŰmÇAuíÎ/Ô×=2VXŰťuş+ť”ÇúGnÓ7 ćg4~Çí®¦Úü˝mÁkîô,[Éńë!ŞĹź3ŰËŰeÎgdŚŤ;ýÓ33ËÝyJú¬iůX&çŹbl”Çă¤éťŃúˇçúćÖĎđ­K=ĺ+şă[ŘŚ7µ;÷«Š˝ÜRěŁ'_:D˙íÎŤ.Š%“XăöďyČ·7ö$Ž'<—q] â»7wĺöŐń Ç[Rś­Ţ˛ěëśÓB33ĚmT;Cę_´9š[Łđö%mŹŢW–év_Ëľ'ęłŇSX3ó1­5z‘”©¸yÎV}˝ĂŢ»$ř6qó˛/|Ű[rĚfn~˛v^8ü)ýÚó70VŕyđcWËýŃÄ7\ÝČ=Ayt|ŮŘůéÁ7ÉöŞ>ŤěopyĘoŔvęĚş|}wÉÇíŇŕ3wmŚŰ˙äŃĚŐšfZ9”p]ĺőFá!źŔ(¶+JsŚź8¬m n{¤~›™źQë^R‡ä—ÓMM“ćµFgč;%ĎÍ8vćŕ(c™¶˛đ™ĺ?ůÜ2瞬wŁđ¦V©GČz*e-ş&űŃ—ő˛Mż´÷ósç…¦Ęń®˛ühî§RŤ˛ŻŚ‹†đťuž3Uď la[mŤžBűďj”ë‚q‹üë“9+صFϢ&—rYôÝÖ¨Gr)pÔĄźÖŽ˘s}}ő«+Ćxq~´·f¦™í ň{´G6îµôO'ýćC{ńyGßtäCľ¶ŕŹŽ…Ă›Ąď˝?éž'ěľżQź›Iď]ąŽ:7;'ż=„c«ôčýź(ťĚó‡č˝{rŰ}šú¸ŮŻ!ż“Ł<< /pŢ|^ĎĆţ-ńFµźČyĺ;`˝ Ěť%‡Ôµ@°T3ĺµŕ8Ş˝"‹2cµM'˙!u…6asŘB.ʧM˛-a˝ŕX¦śs*ú´×™µâŕkŠ·5FßźćrŮŘ/Ů6Ŕ!ôjfvÓ‹®€żłÔá_LąńPĎžo{‡řIËOcÚĘ#ŐLo»ó9ňa˱rŘ‹GH;„.‹®EŚËť>”ŹĘ<ˇl˘ô}Yv]j­Ü_nßGîŁÜDůăs|éä=”×í\-OPž ;)·Ěsľř‰A­;eů-Ř|€lŕOÔ˙á`ý´ŔŐ"źwиٰc{¶ĄU»űlźď4ßú‰Ô9đbŽ›Ćţóˇ€ě«4÷˘Ľ‘3gÝ©Uu”çTÎËÇËö¶ůËŘő®vç™ňžqjv)۬QŘŤ·”Ë ŚńlŢFµgř8ŤËŤťĄoHn¶·˝‰YîNĆŮÂáh\ú!ů÷•t?–őĚ9”cďE>OąhXż”ŹIö_wúŇťBĎŔVźž"ď•ń›đŐ×ćTé°;µŽňđ>Ő †ä=ךEź—ű¸ngűĐ=1ëh©fohwŢ$mťž÷±>)źmCkôPz6ÔGĎ>Ćç—<ü9ö[K‚Có˙NTü}ŰežV{ń zô¦‹ňňłPcÁ'(çĚ'›Qřx3{żäÁ~Ö•Uω/W6ćś1Qq'ٱÄŢY53^Ężkó7UŮ<®M'­ÔŘw§Ż<ŕwT›$să÷Dűt–Ţb]Qţł*ť –“ć¨3hÎ-9!-÷íĹć!ý™ž{áipťí·+}Ô4!Ó¦Č!ÓĹ>¶”§—í7QzXúç˙s,ý|eى¸ß<ší˛ßqO•†¬Ý©ă8çΑ»6żhH}¤žŃ¸f]ę ˛Ë“|'Eż-Ç×ÓNObO=Ş]$ź;|şFóZ33TÇ´˝M‘“'<ŢŠM]§P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹŔÎË€f~ÎĺĚ ×içCú6×BO4¤ş9§Ţ̬«Zw> cT®Q¦xŇ!ë´g…:wş–cÚťťŤôŞě _µÜţ9ĆÚřŤŚ)ŁőćőíÎű_>ôŻĆÍCňQ—>J–ëĘý N3oçzUq2Ɇś.ŹTŕrě÷z«Ą>Âáź{Š®[ů7Ĺ’ILŠâ+¤Í…G†Ťď„v§oó.sž őR4_ëč°q,l_`˝ű¬q]Ď]©«ÁlSĚ“3űJŁ˝ř,ĹÓ=*×á‹r=‰$'qűŐĽßťJyFęëNgÚ ÷FöĺőĚ/9˘Řm¶śăói š˛Źö;j(_Ác'¸;ĺŘčeÍŚ­É^ěô¬Í$3Ĺ Ď ‡$ő ©»Syö_Ź$Αö"иÓmţ«W­bS,´Vr\Čü2ö3o˘´aLmÝťľ¸ˇ-x7sÝ•[ˇkć;Ţ…Ń~Ĺ27Ą“—x»SVŚ{ŃuLSOâëžđµoSżÎÎ23·r< éSúé®Ü‹ĚAWnšäϙݵYŕĆö˛í®ÜŤúkŻFçÎ.çN°­ö+ËŤö~Ńő¦65ŰŔúěÜpça@›mÁ‹86A3oăs=‰w˝}o~ĎÓďHIüµů]ĄľŰť/y˛±ă¸üý÷é2ŽXQgŔŘUÇ>Îag¸,΍ŧßń°´)wúÓÚbÜÂrĽJşp§żŔÇ[ŚÓIĎ{ ‘ŻßńĆŰťş„m%=ĺ:_Wn®¬ ú„ßúń† săvŻźęńeű6/îĎŁüC\Ĺ'J9Ć÷â°]ĆJt–NfY©ßęzáÖĂ`6–sŘlWJżsžI9ćK>Âá 4`× Ě/Rť­ëćţ /°r—„Ăsü§Ą‘˝Ś:ăĄĚ¤K‰rÂ×Ř‹»7Ď&}§“9ϦČë”3KęŽrZčqű>ňÇž|hî»°ŐŤ ·,Că™~Çíy:Ŕ!UÍ}›Ć>ů7劸Sw§§HľOٱťšýŁÄ\YMq=ëÇ&Ů:Źđ·8YŹ4 ĂĆ ˇŠ~›E%n\/úřCvE6?|ť¸f$?f¦‹ĆÝϱü” Ź·É( ôÇ'˛'Čś*ffżđ?6[‡·SľA\ßYjnĆ6ţ—´a{čÇGÍüˇźßGel¶ůţ'b_=WŠŠś"ö˘‹Űýě‰ÓůŕÇśY?ź»öšÉó‚ń¬ľŞ<΢Š{ĺ±8n?Vâ¸ZŁm~Ę룉ßĐ9ĺšj.ş×,Ľ6°SÎ9¶UĘ5Zűχ MŘÚý ű8Ţb|‰űzí©3ą/š™ßÉ>ëĚ^U5‡ ‡×7™™c´dn‹v ń:đ~}ć:8łŽŘl%¬k3»ů&ż6Iú:qn¬·Đ+ÚĽúf&±Zú6ˇ3óźľŢHĐ÷|čź{g©]ęâ¤yżĹxŹĎg_'µ€ëA”ŹiĚíxkR® +jó/蔣‚ň Í2Wę×Ćíd;||Ć#č ö€~ÖÉ'§“űűČ®;ĺbâňČ=†kok2Ś˙ń—}îô۬š{S®Ŕ}ĽÝßí Ć[|Fˇ^V`ÄĽ _Š1™t]Ő?ßt<%·÷–¶3ţ«%h Ňô…p¸j<‹Ű-ç ăó„Wř*wú/UýĽşćťă=3©ŁĽQěź;K3`F˙6-ü`0~)ë´.ýcćÇyÂU o:ÜőťĄĂ†ÜkMtôfćk„áůeîŹůĐ"«É÷ꦡ7bTőWňíu›ďň=ŘDÇůŠ®kd~‚îÔ9”+1϶žŤ%*|ď­ŇĆÔ“xŘÓYšĽÓé·ĺ0¬’źĆcî“fţ ‰»¦ŘŮä§ç‡Î¬˝>n˙=[9­.7gfc­:_ÇŠŇŞĂ kŘ;K›¤ŁűčúşôO¸źŇ}÷ظ˝É}ř|ťĄ¸Çí×6uĺš=QÍÎ÷×öâm®¨v˘‹ňáFcúÎPÉűhďÇíţ:şGlč,5Öu§j\hĎť>łˇkQă®Íí!ě’!=˙Łü®ËęZŚ)ž•…ë–ŰϚٓpĚtf˙8D×”ĂiLűş#ďqmH.’męćiňůéşžž×ą;Kuß®•eâöGÝëRgT>'‘ű3¶Gćh’íÍÍ줜\·É:*ËŤÇ>őI‰ł˛ý˝Š·ŐMÍŔxčyőtś[nď¬Ň“Qx¬ęZĘUĚ8ęy¤Ę‡vO>_öěŚjW°Í†˘gVáBÓtŻ{˝¸ĎĚ~Ç©‡UŠŇÜL}ŕ¤Ćvçů^Ę5VáŰm6zÄţĎ^Ü,±µ3=4÷)űĹ/WůÇĘzG{EéÔ‡uĘ'~kSkôyž´Że9ű˙a;싨Ďzéů€˝čľë;[8ĽPÎIG×űŐďN{˝]ą÷čŐăô|»Ď·÷6Fµw·fžPĄŰ­ŐµĹŐÇvŇďx‹yŁćĽu§oň…+'Öy_+0Đóm_T‹sŚj ńܶ͢¶kr‹'ĘPţe[đôLŮĎx»^îđŐćk'v›ŤŢwŕéĘEą/Ú‹řkóú6E6ńŘ´-|Ű:G÷“Ě]od-ý­ćA®»7ŇľĚő:ł3>TýŰj{GÎýôT<§|µęo;r˝UÖ`=¦“gv=ă> ˙<=űŠÔ˙Ž×9ńŻ‡ź­żKŽS)ŹŢ<éÇ&>%ˇb@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 řh1ŚżVźYy,(~żjm/Ĺn»¦mjv’›âH¦fWU­˙˘|ôŢŃźV­›Hl­OÚX^Š…kzÓ‘¦÷Ň?Pµ.QĽą'a0+JňÚ×Ú|Ö1_&qu–.¤ëćóŕ?„žhj1ż®ßń”kE©ŮÝ“TőOŁp»N±Y°~ňs ţ»-řSy<˙žÜŻär,öÄ—ú:ěgy5łW_’m3·âHľă! 0S.ź•ŁâŹz8|4˝Çřć€r©ĐţÝ~ÍĽBÚBT;Źą ‡Ă¬§ ¤×|čN¶űňKmŰ‚ş˙ńFlú3đŁnŠ!fŚqűłUŘ…Lٱ=Ň8]ŽŤĐ)l˛ÜšIřD¬~od2cC˙ëŤ\ȲUçXůg•=ęć÷4đ&äE>7«u ±=óĐŽ°mŠŐ˘'E }Ç^důĐËşí/ľíÎ=ýŃ•WK[¤ţ,mF`?VŕĹ6Ź:{#«ütĺL@žĄłe]#ŤskőaţĽJÔ2ĐËt ¶űÄ9Č_‰ż5šc9)÷FéŠ1çC—Ž ąź®…M ĽŘőÔžşM×nĺ:ZŁ÷ú˛±_މŤ/ >ČcnŃ•b?#8f1®'~[˛‹ŘŢĚľ{K‚3_?pfě÷âöŤś·naôo:Ćí|č‹,ć#Fáš›šl»˘ď·ľúIÖúújWî]ĘÉňľ&Ş0O»óÇĺs§INĆĺÖ[Ľ˘ĐAůWŽŁSŢkî řŁÚ:ş÷š-ź#Ŕ†ĹCă+çą®­ń’Óšż–6˝3ŕŰ–Śô\€ő‡ůü0pâ‹qc0Ó|Ű”±Ľ ł3{‘‹|ŕvĹŠo«ýń:×wî•/ę+p‚ü†L”٧ěŹóăwWÝkŽ—ĚŰÓ®nfäł-«ütžg™™żň–ây}}f9ź ™ĽďĚţIˇ¬¸ý¸ÝĘűIĎčůď­2‡Ďö´?ezŤ ”W»ňR°ß ‡woĆ]ő[\ÇĐs•˝<ćśbĹ˝Ĺ߇{(G¦ ˛§“łęŠ®ďLhĚ%Ç‹¬ËîÔxëĚ^ŰŕĚľí6 “ęňˇ·ÜŮŘ‹ü,ä‰XO#=Si2 űło«)žU.˙$ó·Ď÷máđYCl<k’çÇRŻîô·=}ŮUmSnńĆÖčŤRŹöâ'ëń˙¨Ę!ÓżŞqQţƆÓS\[\_¤Ü Š_®<YĽ Ćâ5ĎĂý··:÷-ć¨5ş_UűŻéßťĄ˝äřC~•őGóEĘ‘´ÔKcsS8|ž<ďţüťU¸!Kkô=7ĺg`.9Łak˙ş®ÜUĎ»SÇłí….â÷0Ż˙.ëi<;R_gÉĘ?+®YćśGąSó.ŐnđĹí˙˘ü ×6”Gňk˘ôÖ·ÎěĎ·¬Çk(Ďú«Ţlě®&sÎőŇh¦ő|e뵌ÎĘ &m-Đ}ŰĺÉfŮÂá+<>óťĆL9Ičo4/p]Q-VĂl¶|čÎGŤ¶‚ńIüř=Vźĺö…Uí"/qeŰöâ§ŘéůČ_TYn¸ýă“\7ĆqĚߊ®ߣ˘lwjĎ]ZŚÝ%ĂŐ1šÇşr_­čkÇŃXűqşŻŘSs§§’Üéň5m¦›ĚwÖčďŚór܇`Î ]ąożă˛*űMl•uĎŢwŻ!X(6c·M÷~+x¨Ľňý÷é˝Ţ€QđîUÜĚŘčĹűůđçŠŇŁ Ý©<­Ń›?pď/Ĺö—ůš·˙ŠáJ~šůD~%ĘĚX»rČ'öŇ{(śŢ›3Ź5´;§LĽĂI˙aŽQ^!Ż3;‡˝;uU•żř0uOôk{»ů"”śťţîIç›ü‘ÔďD×’O1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1°-ŚÂtz'nŻi˘5»rŤĹůz7NŻ›m\MůHvá5˝•őäC»5QĽ Ż »¨´‰ÖŻię Ľ+ŻŻ,;QöťŮ©Ś“â*Öp-ńv–ÖĘő{•âÚÝłŤyĽľ9ŞM’ë_ń9UkGQ6ćĽŘw_y iżŁkÜÖvB–á>Ářł#h­Yďw\ÇkP]éŤZÉ‘—ăö+ř°j‰jGŇZ÷T“;ýżĺ2>ÄFb˝çpíŤ×1Â#őú×±¬ČťŇř=íĎ÷ĄR5´ţz/o»ł^Šßçőľç°MGµ»řzŕD ľ"î ۢk?żBëö«Ö¸ŹFáfąÎko!+t#ô<B–eÎ=ąo¶FOݧx~—ý¬ăëV”"ĺ›-óéĹ3VůO‰őËXÇ‹x;lkóÝţĘz ­ű]Ń´.Ő=„GŃŢhn)&ăᄌЍXwŚv)¶›–ŞÎňSÚ­+gũКv7ĺë•Nžë®=ő€*}ő$nçŔŤb¬Ý1–‡3żÇbKďqmčĘÄý6'dVĉA'8nł=ěw§÷“ş®)n¦÷ßƶ‘Ě}ťí:n7Ą®DßĹu!Ö[Ä?G5—´kZ;ĚﯴĎô×oßŢ“ř˝'¶âWńyz!pÇ6/âň+ő\©\äQ‰ŹÖ%KýĆśw?ú˝I>ď: 6 Ľ‘Ç:ŻŚźEťéäŻËtňcUń†•íŤÔţĎż—}u¶;»ąmŕ…|°mČ,|bý…ţ¶G†DéͲ‘ŕ)·źrGP®©Jś”ÓdČ·=íěh™Déxʵó'okôď3‘GąMčą,[ěŕXČ+ {i”LÚ6â3¦fď§Ř:o˝ż›b­ěKÁ9‰˛÷VŘĎŽbŮžň}4Ą“‹XFzµ÷ʎ;yş€ž!|dńŻ=‰“d~(´A±CěŻ×fnm¨ÍĎôö$~Éń%ČËbő‹WbÂĆEŢ“¸ýî*üŰaGËP° źŃáÓM·)ô +ólŕ8d…ĐÜRľ;—bI(ţő˙šO8ŔS%ľáöQ—!·›ňެͬ%[˛3ď;Še{ËG‚G7MÎ?-q·ŹÖKއɧVë:Çřú‹Űo`;ď ĽŔ>źćk\Ź;ý ľ_ŘÉŕşÄo‹W› Ág@ćpř×C˙”g{q|rôžuŮζěňČw^•>ţNďúÚv5w/¶sOâëÍŔ-rÇőrŢ:´ľ‘;’Ť]îŁw󅾌oĄ|؇ŽŃŻßŻUňA^ĘťD>ń¶Ôő?e;©¬ţ|Mn‰ş™ńÂ.î¦<%ďW÷Hź×fÄxžţÁ»đÝX1_*9ޢw“˙Đ˙şk÷űžÄĆŐüĺďxÄgfn¦ü9Né‡Đ_ŃP§đ‹ŕż/¤ąŠnŢ ő$ó's/ĘkF×űŐçN_ĚmŻ'_Ţďćď śÄ<Ü\Îyµwq!˙†}‹qsjÔK>—ń+śc˙TÎs |U6v8ÍĺţkÜđ˝~śžbX)žŽűĆS1/]Aqüš9ŐŹc° ĚŁű(ăŔ)ć6k3_f®jŠgĐŘ0[Ľ=2Śe™¸]ŁçŻČyš;ý7‡ °s~Čż…ˇo|_Ř/ľ(ß•;ž1cżĹ(Čű/üž¨Ęe@s CúiôQŕ†Ź±…®ýýż'*¦mɵ0zÝ3}MŢOXe­ĽŤŔý<á†Ć< }göx–…žńJ–9?;kA|=ů·\˘íI6+Ťř]t]^Oy¦Ý“l_l‡ďoZČí;5ë§ś ż¤Šűz#‡ůşr÷Pîńsů><Ş}Ó0vőęć[ĺL´ńa¶]ą+Y7SłÇę˝_™ď_p›}˙Ö0ÇŞ¬ß^|’í{]ę`ĘK•¸+Ëý¸}ĘŃô{qęىĐ3…źűđ[třüöë§éătę?Űyĺĸ—9‡÷fyDٵ­K˙NęQ´QS\ČÇÚťßőcÜÁqĘůŞe=ĂÚ¸¸îý¶ÇPF3;uJŻŻ˝ýÖ÷Ůď÷ö•sÓ÷«c$Îw]yÝG¬öŮ‹¦ô=šů ÖyT{Ž=˘CÖĄÚ®|lc±ݸ)Ď'—m ^íĹ|‡lďu×w$?¸×ZYx¦/‡ą-ĘĎNąQ-?żĹ•Ö[ŁĺÔĽaTű3¸H'mħş‡»–r¬ ±ůáĘŤö±îÔ©”Čú›ăhµ•5Ž:źŁ%»ŞW1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€bŔf{ď˝÷6&JrŤ[_ g«ń3´^ŢYôeą~®ß1ד5ď’ż'*źuéË$>!c6¶\®ă*¶®+9R2Žamfą†ďÍ“âµ~¸6żĘ|úÍNë•ń®7QßDŮ®Yä”kÓËÔťú´żčJWɬ™-îcăß-k]‰ő±XםşŚ×ń÷;f ĽéäŮz—ăVmepŰŁůűu×ÇXW›^śĆk÷_Ů_ “Ęx©|¨×:Í1 ň=°OÄŽ”zĆzG\0®¦wäů¨”ťpŹ»˝OŁXý¶ µö‘ŢÇ:ěú—bŤô’ŁÄëŘÜ镞©Ů}Şě˘7˛Â7Év=ó…őŔ¸žryhťĄfz7çÝ´†uľ–błÖčg%O•|ŚŃľ§łôﱇ„ýQn•&ޱG$ÖrgŻú>owÖŇ»PŻeĚĎEă8“`ÜÉ1ĹżÁÚĺwß;_k ŢK±ˇ‡R>›ßř(ż‡F/(•ú˝9“ vWČßc„•›q§Ođv§ng,"ż­Ą×K5ÖĐâŠ*í[Č?ń8î—á°˝,űż9_0#ţČŠ#·JĎL[ď¤ü>ZgIú?śô®ÓűWú('Ä뼦ř)ŠCYŔ¶—ŐóVÄB~HMďB•v 0c»1aĺĄéwä´ŢČZ­ű„çŽř«¸ý,ą1ÇÇ_µľ7ţ—/~|LôÝYZÝTSěĺ¶Ö’ťAţîTžń˘/BŻČM bĹ(ןŁřößí”#‹âîřú\äÜŹ»SŤz»s×ćĘüŘľˇ'ń+íńX«NąyhüÚÝçČߡ9ł1ŞWçş!Ă覱–Ű73ŽpřBÖĄeÇş‚®ˇw!O_ŕR.Ś/őô;RŚ›b+uřxp4\ÔaŮ€¨ńŁWęÝ©ĆKq>Ucá@©‘Ůë,}Łjmm!pˇäŮz˝…Wä¬ŔÇ…/”W‹ç.dŻŤ]ąMM-Ćĺ:¶žż:ń( Ć„×]izď&ô=zŠsóĆíçÉţIď;ćąr.Tć[¨Ü~ R9łÝKůP­»§X¸Ă)?Éfꓵz%_•×އđ‘Č•Ě Ł“˛Śęlě*;Bł|ŐÖuß űFśä˘ř ĘQq¨·72›rľĹvC}”úĘÖëzÎBjÔ1 .5“řş[ú}ł±[ýčëřR,Ű"ĺd~*ľa»pŁßÓ”±R>#šłť1޶ Ě5Ĺc)·Ó ěĂ*}VĄ.^fÁ¶”?ÍG}„ć%Ó=ý«Vis_`ÂŃÁ~¬ňúĘzŃl†âí(W\Ł65;I_ŞŤMn©vçsú÷íg1żVŚúđv Ů…ďq^Ë©™7Č9h8ÜIs.w3ĆeńVě `S« vkAüRn»'‘3ۆľ:K«h>r÷oęç¬÷Jť,&ýł‹Ń<˛\W|&çżMńŹ·Č~‚ňŔŠ-ľ–ż°ůJ'ĺś«g·Űi¬ŢLń ‰i~!ĺhwülźŔ.ćľv =ăß§®|+ë©-ŘÍXqśuXć× Oą»ü%Š[CîňůŢLbEŐx)dŹí&ŠŐíVöGč öŤ~ľ‹-ľŕöŠ}Śß(#ô ľÄ<u.Ő. y׾Łî«„üŰ»íNý†Ćž°quˇčL˙C„IŘ:t†ńÇ€O3ý~čľ-¸włŔ/úp#×fő7Vž"Ęý!ůÜ^yĆŞĺ›’~ mćC‹> ÜŔ_‡{L`úĎpĽr¸6™[1aqBľĘOOâČAĎo¬ľ‰ţ lř¦ń…=ă8ě¶Śľ/ęęwŮ´qH]âěÄ۶;oj´őµßÖ€ x€ńÂ̰sffčyjöŽin1^’÷4G“Ď '҉ÖĐ˝řUtÍĺq¸ń6Ř7°‹cŘ履\ÔžÚ|ĺH4—î;Đ)w«żô)ćÓĚüNëôüŤ·˙F9K’ĽŁ®‘ţŔÇćCîć\d6ë‰bźżełČ?ÝSÖőźč9ČęóˇO»‚ń ę(;ĺąpX»L'×VŤoöłÎht§_ⲂËHĐĘES9žă`|OÉ˙HcE}}z ůmďý€ű%ňß™™ů˘÷Ţçë řdž0Ń6ĺ¬ÂrĺOço×äzh^ÍöĐü&ăíĘÉuŇłdĆ59˙Śľ×]ßŃ[Śůôě×=,Źë˙0ż Ë4pŤü(¨§ĹŘG[l˘g±ßĺüđI+JŹ˛Ś˝‘}ĄMďh›Ý©ë|¨ Ďťës8´ůî;çUŤk;Zď-Śż¦‰¶é^G[Y2˙x¦_ŚzMĘSş#őăw±Mô;vi˘ürÚÁé¤÷ ş×Ŕ3%ş˙"{zL§{Vî7ŕB´3-{ʵł#2 .‹1m˙…dB^q¶ďČŰË9bć`Š~,ún[Đş÷m`+Ćô®ÜĽ*_XYf$÷»Sߦţ{ç®ß°ąŢČÇgüŇŹë8¦™_)ű˛o™ňH•ýRĎYŠ®ĎńSFaŻ\˙ŽJÔín ż6Đß›ZŁ÷Ň߯đEµC9§!ęę,Yy w´ŢĘň”7‹űĆ‚ŰË>+=EÓ‘whA|©Nů÷Ć oĄ\bźňhűr‘kčą^x.D™Ý>ާ{Şăi\žÁą×Ĺő°'ô#Ř<ý˝hĚqwĺľá Ć­|R‰RłŽű¤•Űá8±íĘMŁÜJďčŔk=sŞ<;¶űůĐçŮg¶;µQÁZ‰ćżCŻ6a>49¨+ĺPűŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 P (;Ć@[đ”Ć'b­´Ţř,zďĎÝĽ^­6ß㎠zďäŞÖ˘ć¶ŕĂôáă«ÖµőFváXÚ~ŕ5u;&ő+Mď´f9íô>ľ¨v"˝üZëôŽn/nć5M-ĆEUň/ݎw+>I±IÖű ĹzčôľAH@‹š‰#­É(ś;fk·y:yjC.ň­Şµ¬X·xSf7Z/ç•ď˝6 ŻŇ;(_iě,}źuMďf€křE{•ďϤ5Łr=R:ůH•-ňcżµŢŹY›˙fSg©ÝWLcąÂĺőqmÁ™¬cpŮZŁÖZkgv#­[öŃűU÷¦u÷‡7cmYĄě]ą×óË“x˛ň ŕ|wę â`­mőőË•ňTîÓ{‹©}“ÖĆ=Éö—(­Ą¸ő×|5Ĺ#蝀÷j{oÓ°kaq]˝9‡Ö±=ôţOŮŻŁÚT^7‰~ ęîN­bý¦“VކłťYć`E鿥ŢEٱڮONg[¦5ře{›Î‘»â’ËÇl¶u©UŠ5ŔůĐ%,ŻQ8ĄŞ_CfÄŁ Ě1FA^Ű•[Ańóő¨Ö0$ž–ÚńuíŃâ/.§Ř’wĽőé)žfschwB1ç7Pž”żS<çϵč3Ťś‡X`»ýŽř).ÎŰű,b>SÖY:™mqIđm«"]˙ťbĆ˙‡Źi溸FÄŇ·E,ôżĹőo?¸Ŕ[zwě¨Ű8˝Ď’mÓ(tęOÄ^ç±zxŤÖZ 9+ĺÇlČÚ•[í_LB×Zű—×zŹ+ŹĂĐě_\+¶¨×YţoŔpí;Ć9Ň»ô#ŻY›­!=…ý­fÎa_ ś•ř¬X‚ů ?0ă8ůö!ľ¨7ň(Ë‹ó° ”±Ĺqŕ‚N-Űî`Ľ8Ž8ŤĘq}4đVÖą™âŠ*e¬ŕ˛TÇ>äńA¨b˙Ľ›ĎÝÄXĂ(ĽÉ±łŔŚň•ů]p ¸{‡bĐš-_gŮlçZŚżŤŞmSn/ňYAvŕV`‚ý ¶AÝ»ÎČ×µźfĽôŢdé(ŢBő‰ëÄz¦xxĄĎĆ>Îv68äÍ8‡ŕm[ŘŞírCWGҸŰ<Ťý-˝Ë¸Ş˙-Őf0ö/c#ŕ>Q䀠9x9ç–Ífĺ°ŮN ‡«ę ĚýŽ<ĹŹMÖ 1ěŰ X>BÎł‚ńź—ç4wň6·sŚ40 Ç>|…°g1V!–)Śó{µ;K}C|Äh`u¶ír cčŤÜăo1~H±0oUőqa›Ŕ`Ů˝u%Ţ×ŢŘŤ±¶F˙Ćă4ěńlă8‡+ű_ĄŘĐĹ’7pAóň1ĹŚÇĽfćJď$۶͞ÄWË±Ś–}Cvń…ú‚üQí׌5ŞŐűÖŃü%K>~Ařđ„k± Ć˙Łą/`ř’ąi˛˙ŁŽńú<»ľrDůV”VqźŞôcWčXřXŘgţ+f9“ŘŔśŮc9˙®NôÇđsšńÂ8\»ďĆź ăŔDď>§ąđ@®$ˇ?ÄâĽč˙lĎt ă Ž‰r° ±Źzăö˘‹ěĹźË}ŃćxnÝé˝YžĄšVîs–Ť ť|0¶Ŕ‹-ľđýŘ€_č·'1›ď#6ĐřH9e?OŚ[k»¦xť×•žâ…ěb¬‚}“Ŕ…íó„ Üŕ­U÷n”łëíŞ{š­µ9žÇťŮďÉ<4ág»ŘŹŁO‹>*°#ľ‚±Ź­đÓ›ß<Ťň)•¶#>ž8·ÖöÂčQdëwrßVáź`·Ŕ†c–ç‘‹‡îÓŞúlk´­žžĄJ.·ÖŢÄ:nÝ+ôŠţýÇĐ%÷ɇ®ŻŇ˙xauf“¬—Di•ÔI0Ţ.çżµů§5š«z×'—Tĺ˝C~Ńב;k¶qşĽ.oő lg <çZćĽXÎMZŁűUq,ĘŽÔÖťţ/o8ÜÍ9”{'é5E+/ŢlăjĘť<‡ĺŸgv=‰ ,‹3{!=;*VÉ•N^βC·ĐsWÎđ·‘cQT»«±/pOCM±ł ·uźnˇA˙×Ě#hÎ{=¨őÓÜ_ň5RxQO:iĺxďÝĐ4đAűK‚?˘ü|‹9·„¸HĄžb™Űťç7"ßxWî]ÖOOâ]–/Şma[ĄüÄtÎŕsm¤`z^Äľş…ň¶ĐXÇÇŃÚť'H^?>RÄíVeÎG«¸đďŃßQXÖ·ţď{óßzBÜ9ĹöëhvŠßmÁx.A9EšŇÉżó˝De«E×tŹńKĘCłŠe ‡÷ięĘůź¸ý§ĺí”G~=#˝ACÝ˙K÷Wä+3ň\‹ś˘ŢlěĽÇ+ęÎEváxvř[´űoÂŘ×ő¦´ŐJű×hÜX5ĆFµ«xÜŮ4í–Ćvç9UśD‚űUŮ(ýÍKuöF‚”»9é·rdXĎŤâö}¤îE{#ąíĘVĹ%p˙űířĽDédýSq+§ä ‡Ď gń{ŃłÍ&ŇóţőŹÇĺ`­Ń˙r›™zú{ŐrúŰGoVČifŢ”xÓÉÖ7Ž3ę…a^‡6akďçđ(“N®©’ ÇFç3ź8î`y€Ďń,‹Ţíŕ'í33_‘Đ~gÉQĄďÁ2ă—ŇßuV“Mď&˙®2č/ÂGŕ7l]`Ĺďާků§×KŽpl$?4î4MÍĆäXşŃŻ+ýše{Čx§o‹kyUŮí‘…ţÖE>Ďú[Uľňó¦ą˙ŕ8@źuuĺ^b3âÜHlłoĹHgý-˛JŹ;Š6€;ťlf9űíÝ–ßđôFšËu‹çkxN˛‡ż’Űún5‹6ňˇuŚ»Ĺ)1ă˝k5óEkôâ=_*şţé+9~ĘeĚů9DŰ˙×˙_’Wk1jGŐ‡‰vĹöOy9Ż ç7ĺĽáČű®SÎdëݢěŽnŁÚǽłóVq=||Ć ßâşlL1CĚ•aoôNó˘™ÚÍ´ľ@Čřa·FáNĎWPϚ܋ÚŰ„9nďlî,}ŐŐŽř@}çĂĘ„ëűz‹˙ć:źňkQîĽmו2Ń\ŚűĺÚÓ­ĽCčß6[mŢ5˘íT¶9Qöéľtrµ˙¶Żž{íkéł'Š|JĹ€b@1 řč1`fÓ?z¨¶ŤČĚ,tm»ÄGďlżăŻüᣇlë¦eľ“ý]bëXÔĹ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 ř˙“Ł`ăőqű;Ť´x§}îMëSy-˘öěçé=ü“ó÷ęéäá[][Ób,ٵ(W3vhľ'qŻs‹j?—Ç&šEĐzEOŃő±&3Ó‡µ‹ž`üŘň:ĺy-ÖĺWĘÜ\)×îaí˝łr·!×ĹP<˝Wň™ ‹·;µÚÓbě:DľcăO6mŞxw*ÖłÓ;Í)>¶Í›(}µqá«3}ÝŤËüKµ°ż+7—ń~%ç5}9ĺźţ/ý⬳ôćoMnÚ¨Żűm·ĄxOŠ yΗŤýŽŢĎf±]ń®PzŹňđđz.Łđ5_»ó/RnÄ«ÇíS«Ö¶Ń{Cµµ™Ďó1Z#Ěď)¶ŇťJi›ĎµŢÝ:śLŁy¬Ĺ8F[“sł~jŠďH»ěI\ÁŘ:K×iQm†f>®µ3Ľî»/°…qP‡†¨v÷yŘöŕřVz?z3bžëŇńcMŻ/„­5ľ“ó[†p<šx‡«»5ş˛¬«7«tFď¬ćß/¨KßÁű=‰== ŁÖűŽG3Żo.Q\5Ö([kÔĹÚVk‹uŽ"@ä.é,6¦ëł1§Ô«Ŕ/tٰŢkşÍ9‰¶>8Ž˝`ü‹ÜWéý·rťąµ¦łcÍ K”ţ±E]Xă‰/Öcí4Ĺ»S Ěn˛n”­OgéY–ř ä‚ţ¬5ärá7ÖŐ‹řâČEą*<¤űĆTęŻŇw[|t°.i3cˇőťş°c\¬âť÷ nُďĘY1ĹŘŤO:iĺB¬ dX ďjÇqČż=7ľ( ůű'i«s'q?ě,Íĺ-˝oŐ‡z*uÝb\ŕďŤütą;ŰSŃuó`•±Q>?Ąľu]SţÖ3ě vYˇç¶ŕ4ĘK1Ż:NŕE9QŇŇ»Y?˝‘ôu)›źĆ%ÎA˛Â†SGď•öcM/Ţó .»SűEž ˛mĹšŹ:^Č›]饵 šČ\8.d‰j1żăşňZnËÖQFôqݬˇ5í{2f\GţZC˙w‚#ˇoŕD|ÚťuşG@]Ôťő q:ĺđúzöKŁŽëÔ…źÁ¶ł´Iţt÷ćń?˛†ĄÜdó°q|s‘‰•ň4EµÍl3krĎřaŔ-lBč±FŔśNćŘď!7ŠhÇń®ÍŤ‰ŰGsÜ~őÁE~’YâŁw—SüŢ:Ýśó]Ę•UŇË ™8 äMŚřĐśÂKóL9Ďęw¬ăş o`x±KµWôĎD_ŇnĘôqą¨ö“QĹhIiýż$˘X Y7=‰VngZŁçóľČłPŮ/E?†žQ–ú!ÍÉt˙ôŽôŮmÁ_PÂ8U^O9-š…^i'۬ô睥ËX&Ô?źv§»šĚÝH÷AµĚw>őŮ‹ëć…]CO‡A×™Äd©Š5k(ş:ůľ‘ra±˙FY|+ŻGÁřµ|ÝW‚o{ţJĚŁłşÎݱ~4ó~Ęö¶ěź(ÓY úáo+m ;č¸QŽćĎé–zĆ1śĂ勉-ćc¸cD8ü)ŽÁ\Y8śćígqź¦ľÎ\µ;ďswÔ5ź­˝3^ĚO€YôeäZśĂ·RžŢ!e…«óŃ'XçÄa!đŽ?ƸŚ/eťOÎďŢÜsëDÉ}iĺą‚Ľ•cô,Ćž˝Š.ö_t˙(ýleđĹuĐŻđá»ĺźFůöśŮiţŤšů¬ŠŢ4Ş}¸R7÷ű=U6*ÎĂ.r츠O|íĹKX_”Ł•cvp xĹ\×ŕZQŤúŠs®ÖťŮĄŇʉsă±m1~ÁľňMP~Ţ+¸ŹëćWÓŔ=ě¸ŕ{°¶Ž}ń[čUpVŃy`*ű.ż˝xĺ›|vXžÇ{e›E×^şQxŞ8„1O~lńv`ÇP\w:9ťůkŤZ1Î}ŰÉoî-}@e{ă˝ßč§Ŕ ľ•ýřńVčřQNôe`9/ć>KůKeߥ<UqÂăŤí×ćßđĐs+Š_ż™ĺč XđXsđWŕĹÜ&ż‹Ç!Ôą&w|c‹qK#ĺţĄgiVě?ŽO”Ź™qKY×fcŰ„ţ*u ݦÁŽ;~3¶Ý©§čy’uĎšŤ}ąľčúű‹®śWÎBŃOŽ©ŤS^ n»+gĺťhw&č^ëTo_ŕ*şß˝AúU’Ő'ćKŔ LآŹĆ ¬ŕ&Mâ‚)g)ÍU?OĎo‘\âx[đ|źQXWu Çł±®ĺ‚⼽ŮŘżuŃ?»SżŃKއ)ÇöYlÇĐ—5Ă˝źŐ)×c¨Ä‹ëE?¶?™Ĺ‡ž­±ěî´Ćc8é›ňŽüö$žŹˇ\_ŕE®»7rĺ ŮŁ*/¤¨g¤¶ńżSłßóß>PŁgż™óaΛuiíÎ,ËÚď8I']Ń|â»,b[˙%*'ćjĐ;Ć"ŠŐ(? óGąN°ĺ:ŚÂţţŁŚÓu\'0 ŽĽ?Č‚:`SĆ-VŽTQîĂn{#•۵ĆúŰ´cÔÝłŰC~ĚEFżDřö'śOňyzöĺI'_¦żKXůĆQ–ň'ńą`Ľ…ąŔ1wÚ˛ ěăł9°oÝ j°p)ćq8‡xkŇ˝m¦Źs5•ÇośŃÍ3xŢ >­űáľ˙hśĂ ĺű$ĘC"9ˇy”üŰ[m~ ĺĐ˙'ńđm§<ŠC˙Žeś~ŚĽíA—fća<˙Ň€}ˇłt°®ýíRmqřR*;đwŹ‘MĎŰ*dţĺ÷üˇNŻń#‡Ć"ńu§ű›»S÷°ĽFá1ŢÚ‹đĽ)ž×@ůsúݞý Ů(źµg-ÝSS®ňVĘĚ×"‡ąőÜ©cžČ'üV{6›3; VÔ7’ŰŢH7ŤŹGS>ń«´llË”ŤÝĚsL!ž}˘Í…ŃźJ›Ĺďşô”Y}ý+ţÖú ľľ6§Ľ-«=äéŮI Cž!ĘçD}ă4ĘO1űLÁ©Řż™ůéÝĘÝŽ6Fëc_x1c™dł±|&ŤÁ’] Y°Ĺ¸Ű33“ąl>4™°Ţ]GĎ/Yß•ůrÄO¤wcśCďŘ_ßâJłţł±ë©ÜtŘ?ýÍgF9?ŐK}¨Dľ >Łň} Ŕš(6ŞspřKwú'~Ź´|čeÍ‘˙ˇfŤ5ĺÜ,V.ćšâăĚK[pOO[đ„†¶ŕ±U6=ś^(_µ§;•h˘~ĂĎŕ#ŔŁŐ‡l6ŘĆö¶ ü¤Í¶ÜnůÂáęÉcĐ#ľ¨łř:=ÚLďí¸Źmăä/8_S<Ł)•J5P® ö˝760=‰ŐÝKűGÎ*úŰ%źĂuř_,îSŻÖŮę˙éďśďËgőŰ˙Ë^ô“źÉÓźJUňY5XyCŕ»áËéľH–1 m3>˛Ýů¶÷.âőÜ”ůOé/ĂáŰäóoŘ4t>\ ­îÔòťíG˛c%µ·ń\6†q_+Ç="߂ڄžEÍK‚‡Ô;łH,â¸ŘŇßt§eŹ•ç{»xjŠëąť7Ëóá3Ŕ'ęG»ÇĆ/%:t*ęé­KŁŢ·Čž1w |Rň]/Ű ľ˝v›öwWę‘açĘo~ˇOń<”řŃ»rÇëµů±Í»h”ŻvűŐAú–OYsłźť:đ7‘*«şN1 P (¶ź‹J›¶™˙qűkÚyJăź«Łg,®ťGb%éa@7ď¶Ýb¬‘sěR×ÎxMż#¸Í9řÎi[2çC˙ú¤µr[ĺÔ9Ĺ€b@1 P (ŠĹ€b@1 P (ŠĹ€b@1 ?‚ń©ő=‰Ëę˙ZGďŰ»˝ŃĚ||«Ď˛ŁÚçxM›9çřQ]Ű6l™­ű,㻯j] ˝}«¸i}8ź«Í˙”׉dż§ßÓ}{ÓšĎŃu$ëŚŰ3ĽÖ­łôŹ!˛FµWh}쌭ŸĎ/sţEŁü ĽO1Ţ'bËĺZąJąč˝÷Cę«ô„NÇxݰfţ‰űEWî|©ó±AŠü"»P™ŁÜhWJ¬}µçkćD1t÷IŰŇÍŚŻ%bp.Ř*t,đĆímĽŮf»ŽeÖĚ/˛MóĐ5pâ‹|EŕľQ ‹ŰÔĐ&ůOŻč[âÜhn{#ź Xö Í/VH»Ę‡ô>÷ ôîT#cTĺşzŁC˙+ßĐűÝ×SąkX7FáĘ‹·ÂŹ5`şĆ>pľŐÖ3O‹Ă‡ř˙Š2ÇŮ›4šx¸\®k˘8@Ęo—eąÉĎH=c,ĆýQř$ěĂviL¦|5˙ô‘ Ř˘ Ľ±žbچ]ŕka·ŮÄ86¸ČG3§oÂ×¶;Ź–ĽŹ&nĘ˝â©Í{č˝Î‡s»­Që]äöâ<6ŠÔOĚ…üĐĆ+Łp0Ĺü§˝4ä{ĆŢČ,ň»·đxn`×ŔlŮň Y1ybl®ÄÖý¶äí‰Ř îs•çGr1Ž{k1ľÍ<׋śŁP´lŔ.䇝3üo6@î,–5;FŢgbÎ…kŔ0/\WSě䱡äMŰ'yżőŐyȧH~d‰ÄÜďřľ¬KČ1Ň[ŇŤô•ÚŚŰyźň+”}”5F3ä†ţŕŹ&S| â}…,QíҲ®űä˝Ę3üxgGď®?AĂ\­‡r8‰ë±Ą9ެŻňřXěÓý>ĺ0łr Â!+äĆ‘k óÔvç-ţ•…‡$_­ŃyRWŔ{Ŕ5č­Ń{YŻBţÎŇ/Í…Şž§¸ÓwČzDůŃÜRţʆ`ü{Ü&ěńfđĂĐ3ľv;xnŃ•›Ł¸KíńŘĎ8ďcĄ[—Úŕ§ľŕ¨yeá\ćŠň“°;łJ{¶Żs}żóŢůěÓ‘ż úÜij¶üŽ5Ç€®ˇ{Ř8ô‰sBŻŘ‚áĂ ŽÂá‹›éyëšžClUŹíNMÚÍhęvkuăžË(Ľé­)çŢ…ža«°Yńŕă~Ł㋲ŘeüBÚ1Ú‚ßt§7zkógS.`ëŮŇÖd«ă”W«)Ú—ĺě,­e›3 ěZŘ*ô<8l˘ßâ¸Óqĺł±űhŽs°ÔmTű5ĺĆhôi§e˝áđ檾<š{+(oĆĺĂŘŃ}rl¤8l>ßY˛ń±¨f÷p#°UęvŤcŔŠă( Ó3Đ|čUĘK3|Ăq·ÇčŮÜß}čŻVĽ=Ť1'ĺ'ţ•ŻýV—†9r>t}•MŇŘäĂ+ú®Đ5ěńĹ}#~7Ęv§ţAţčÖ1Ĺ江h14źqz¸ĺ(¶ťâ†Ą˙‚¬­Ż¸]gvÍů˛îÔ3”cĎňŘaĹü†ĂÖs,Álľ©6˙MůqiŔ%° »†/¸Áľ(#ę[óe=t_CăÜ Ím»ĽT… ľ1רC\7Űź%ÎńDµ'}E×5ľăG|ŹŹX\`@ýšy·&bчkĺ„}ȉ-t+°cKůé9Ă=”w&É6ťN:éwŞjśŽŰ­óTŚŤŕ±ßń”ôĂÉńAŽŃ3 ®}mY¶öZ™÷˛»zŢĎĆćűçĆ/%}7Pî űXWŔ(ü–Đ·ŔŚzŽ2 t˙]ʞä›÷Ô(–›íe ë;ı|#ÎsTëŘţ~Ę­A/xGúQön»r'yW”NfĽ– 9ZQ'éEłrW ´€ś3ř55{UYŽ Í!r¸Ň|›1E‚Łśw‡I{­ÍĘaĚFbř8p,ü[wŁŃ ˝šsfđ=—™©Żň!Śěĺ­ŕ|hB×›[ČţŔĂŔrö;ľĺ×ĚęĽř˝ĺ|óíÎiŚM{ĺźűđKšú5lĎE×ZĘ‘đm?¸- rĹu–Vńsű(ǸťšťäÇ3Ątr WG:QOsŤňkÍIŇË#Cr‡ŔFZř-gĄţčŮQ==ŁV.Â&ŹSĽ™oqřćt’íăt…<{óËśZö•~îiůŚ{ą}şÇůç€đ+Ŕ;¶fł˝Îľ}Ëұ%rŔ·ŔOµ;ĎdĚE׬ŞünµôîłťżĄżű8čYą•ߥ;őŤ¦dîEćÖ™˝›ímÁ÷U¶aí#?ŰÓ”Űä îoů§/ÓěĹĄ#Ö—U|DŰđ™—(·,÷Ą7ţ~¶Ä-r>MÍ@9ô| Y5–"§3ĺěĄë:ČFëšéţ‰ţ–÷e˙!ŮIlëh«6Ň€ýmŠv¸µ$˘ńß»>ąrŮ<1âţZ`î,ĺYÖâë˙ÉaĂÖý’ĄcČ$ĆŻ'bcS®ž†tr±´]Ř€Ŕ~„oÚB÷›"›šr‘0·–ů¤Äx4€×zž ö…lŁą…ś˘}ŮňŮśłňsłÍ (™ ń䕂­bţ`q#¸Ą­í2gśőÖ<„çw˘˝á¶čCKµ«¤ŤT×4’ż,YUŕ…`Ük€ëůî€ĎŔŘüď·ăc˘çšb\łž;[9aÄüÄş_Ę+őUž3÷FۦŹůI˘Äx—93ĚMÜľrŢü™ţÎqż#5‹~Đ}Ź9ĂxFůąĺŘ0´ő‘9˘›ż&żt·IşăöďIÔŢ•űe• ­Ń›Ş|(Wą} y6­58ö}ýrháş`|Ť/^?ö\)ĄµOą‘šÚ‚ĎůpOEyaš{#÷2CK"żú‘[=‡ň´ľ˘Š«Áu4¦§4- ţÂ?–Ă,Ăâđż<ő¸×ë@ßČ5¸~GµĄţŐą?lS/íÎç¶Š™ěÉGűe{Á8áĚžřľ61śíX0ţ?Űäd˘É«äQ (h ~SţťsŕčGsŹîťč}]f]kÔNyŻ~ß±űŁĆÂÁŮcĺüôنm0ž‹J'WÝO>Ż~+vfţÇ)ňľdgơdW (ŠĹ€b@1 P (ŠĹ€b@1 P (˙?00©ăäŠ/’ąŐ·…9ŰÔŚŰ(îâzŠAÓ»ľVNřżíü!”¨ú›[mţyZ‹ą+­Ç~Ď#Ţ“ ĚŮŘ?«Ţg…řoGŚó”ß×Yôz(ă€m®7Bůńü´;ŹäxO¬yCŢČB‹Ą®śŮűyýDÜ~EC6vą'¶Ö˛™™#ĺZÄ>÷>Wb鍬ŞâłňÜxěGµŁËkŰîă÷ŠYq/S,|ŠÖ±Ncě÷çműĚŔűd+ĺěĘ­ĺ2X#5_ÖzJZ»µj­ĺkˇ¸Úmż«˛ŢŃŘŹjo°Ţ #ņř‘‹¦+÷˘ٱ®Y¬mmÇíŹËu2›˙-÷±†2ş”yKć¦Iť‹u…6›µ.Ý(8čÝIĘ‹˛pśěýV)›Ŕ$ŢŰE1B¬Š×ĺ8_¬ŃEčšÖĽú2ßß]ąß—ßY_?µbmł±‹äšHúűĽĚ‘€ÜVɱ˙ż2ö­COáđżôű/Őf0ô~PĘŃĐ#uąaăb4s!ăîĘ”ăe™·ë?Çń$ŰËôîÄłš˘šźrÄ„5áoC©'ń-=ŞÍđQN$ŠĎ‰KĽBFôsĘ uhő{ël&q;ĺ9„őXt9ý‘`·ÔéâđłdGčÂŽD}]ąŚ©Ť#‚ĆJŰp c XÂü{ĘWŕ"żőEÖµxg¨n†ů·Őo-‡ü”+Ě/bBá€Eř/ě×ćOˇ÷§ľ§Ó{Hé=ÓEťÖĽJÜéçhťţęQ_H1Uk}Üé›´ÚüýCú5¸€ĚÂŃźWř4Łp$bÔ(ßJ=÷g¬KĆÚt¬Ć÷'ĺř"q˝3Ű ý1t'ŰMŃő5®{j¶—âQo§¸ë)r,D›#ýˇx9F¦“«™9Ž÷;KqżÎđŕÁúkŕîţ“Of™im.ëÇQ[gösRŹX· ®®ˇ5áFá\>~Węű˛ż¤“'é÷,Ź4VQĹŰ4NĘő/do’Q¶ l‡dcśçxĹŘ…ř ZŻĘňS®"‰c2ň> seáă‡őÇQźŹşčŰ“řŤäB´˙Ź}ňoCdeFbŰbÔzşżq)ËJă¤F1&ăôąmGţj> xE[Đ0˙?öľ>ÎŞj?E@&@ ”=)Í2ďLLĘŇ2€( ‚Ę?ĹIĹmPQ…)`R@dĘžT٦BÂÎTAH@\\—©ú‰Iýp™*Š‘˙óś;çľď›l›¤-üg~żäÝď=çÜsĎÝÎy.ŹĽĎ?–öź˝ŕ9Ë—2á;&ö˘Şjuďľ‘ÁtŁĘŹ:>Đäł®wAâÚyŘ“ů‘ö”źµ:}bň“ős±őą+´‡“t˛ů±˙@_}îóIžÉ‹—_ŇM)ňÂkîM^ů.ʬË<ŞĚNwn‡}\lc©€/%ů_«iŕř«ŻÓś”ŻÎŠ~Ż«kč9űĄF`“`źßúúţăĽu¸ÜYňkŮV|Éú·żŹJyŠ·HĚů O” ˙ĆZć"ŢŕýŔ—»'˛]±6Â2¦nóŹ2"żŢ6Ś×ŔS˝. đ\‚ ‘µm°&Ă=ĄoĚ ßĚ]6/´MŘů—"wîËçü± E?T°¦¨«ZÖ,Wţńť¤3±?ÎI1ÂřgŐ{ʇ×|‡:QSXţěôŘÄgöń†˝wíő@˙{,mü~&'«®¦đr]’|šg‚ý[Ăľ~d-ČŻ”!ô™1ÚövÄ~lécŚËź<ň}–;éĺ~ń”_ŇI»â2+S>‹ĄzšŇŔY5¸‡ô 'и0sŠM“ďĚÄhŇv…^~_Ř'ŹŮľ1ůĐ:M>F_‹Žµ\kű`Cé%ŤNöÓĆîˇ~ó]–3iUÝĺĎ^Ců#ĺ}Ĺ{˛›č÷ÉJM0řM*Đ4ă<kOµm?ËfĹčăŔâtëóőţ÷)nlźĽ÷ő|NŐľBcGě°â¤#Ë'H}`yóĘ }Ř2ĎQÄQřUÖfj:”•žĎÖ¸ŚR‡Z3Gˇźyś•íď[ćÚóµ-«lL”ˇă6ô»>†~¤Á–i͸PʞzK»OL.ÖĚťDJÁ·[˝¨)lIlŮŞÁçl^Lźv"3Zeßť އŇ=MKâĹđ1©ń0°Gťęâ­h'%˙¤ó~iżú†‡š¶/Ö6µ'ßĺoĘa,l·ĽĂ2#]<Ň^‘·|çąÍ<ç˝|çŘzŃ 2ôńďĹăí“Ę|&xŐ4†Ň´=ůT¤1·»ä…6KŽâV棾¶Ą_xĺ÷Ô=¶ą´eĘ#ë+uĽóśíôÂ~bR@_«i×B›äłwŢŕ/Ć^ ćëď7'őżÚ“űXťá;ű+´ýÍE?c^>*:ÝSÚĺx‘ĺ‰ă˙XŞzhb[3G‹ Ć{˘ý^!ŻÚ«]¦ ´ »^–‡¶I¤µşGŕ+¶,ËE‡:’»’ClxĽ©#öMô»źÂxĺ­8~hFxfţ±Ôé–Çń ™»Z1şÔŢë>˛óηÍoXË5…ä>y$ßüS[®eĎkŽ'9§Ŕö őß]şq¦¶w-üDbű5í©Ž‹ĚĎ=©Ë]1#|Ó¦vÄÄĄRďü·ĹJR„qŕµrPşČ›ţQ·µ\É«ţ©ŢÚŢÓ\h{Nôé„ä盜ě°Őׄ3Ŕßb=ŕxéV  cΡ ÍŚŹeL5çLŃW°ýĄaCŹĄ`P°g§Ió:ŃWGBŻ×Őş±˝ąŢç„˙ŽŘ@3y&ŔV7Řňv-ŰIĐfđhÜ\\ţÉ ˙ôyĺ5ůĺß…ĺçZľä™óčg†Cůk¤Óžóľb0 “ŢŁRćĚźĺŔ{:çřŁGćN»Ś™^*°Ť/ÎďfF·Cť1zÎwĚĎĺů_(sóś5Ćö‘?ĺ™e«:ÎňőʧŞĘ`f˛üţŽ151 o&ýbíŻlŢÚW fęxíđďď;[­X“Ç•ńs]žŃŹ’rg=gÝ׹/ ĐWŚ=źůŐŽC_ůč·›±ÉÂL/ćŇÖYMg–í@˙‰˘ĎäsçQŽ[ç Ĺmě8“yťŠZ»çÍ{CĎk ‡ZZĽß˛Ěܲ61ď…6w¬«ŘSŢoęrHZwô÷/hÍü]Ú´ěŕÍrqí–^Ú#öi´ťlSąnąrÖt×¶„Ëßm?AźÍÄq8±'ňŢóŹselŕĺ™ńţŔü˛íÚÄ®›ţ7ďľá°”5ǢŢűń¨čţÄďxť}´ë} B?ĺźb·ÉŰ0ڱĂg…v—ütneŞ4fâ^ ¸VʇeJ™Sď vPCs(żÂöŐ€ou˘¬öń:‘Žš‚‹ĺ‰9ű.ú{öü‘ôŮGş7BžŁ„épl51˝Ů¸J˙Jćú€C':gÚiÎÇ~ČňÜšů€đŚö8‚Gaá"iŰŠµÇřú^úF}’ú7áŁSokÂâ|/~íÓöQÚ·»Ş™ő÷ Ěě\•7ťMqβž*čźĐ›Ü_Ę‚v(y÷ö—÷ýţďÉ^´} 3k1š±:’őcšś{Ío»B»‰^Ź÷¶şŕMs¶ÎŰ“_•üśěśI|lLž=Ą €íň˘đ‚ýmlÖĺ°ŽÝí_«~…ąÇŤÉ{vľé¶ő®Xű))Ś}z[ ď`n|ĽIËnvřĺš›ÁV÷¦ŹyÍFřŚaěr+ĆY«ĎŢw^íç#‰ĺhkź‚ýÝĆÚ:ěŃ%çč§[ž—j}ĺ˙jĺűpŘńeĽ.wQŮľ-•ú;Đ_°rxµň8™nYş,P´¶Ißy>¸­­ëzďµpĽŁ•”ăGť§E‡ëró}vęmGKyď•˙˝Őń×ßäa~î"á)’Ý ýĘíŃŻ<%Ľrř͢çŔ?~MÔă©ĘŞşřT˝“=Ż!?çŠ×,ŹSń=’Xą‚á×d=žŠ_ŢĂ~¨ż“ý˙ń» ţ@˙pZá˛"Š*¨H "Š*¨H "Š*¨H "Š*¨H "Š*xmH #öľő™×mĺ˙b×4żŐ€ý”­_Ő–. řČÚ[G¬MÖ(F9ÄOüźŹoř~8ĽOüäb©nďďđ­Ăö”NĂľj*ÖöÉwIçÎIk™[š°ż)}–‹ÔmýLĹw„ű†ż†őö}„¬ŰX,Äwŕýٰwâ›ĺýP>‹}iOЬi»ÖĘţ%ľuĚÍÍ3ö‘jl˝kgĐrÎ ĺÆď*iĘ.čo?ŤN¶~á/4!Ţ{€^ýk-÷ŢWľ%ný mŹĘőTßoî{đ“2Ţ‚čtft1bNBĽzŢ·7ÖňGß5éî }?ĘXߡtÂYÓ–”ç\żs˛—9k[öŽĐĽ<ŘęĚćć5]şńMÁ§öCw”}×!tŹĎ…]ęď[>Ců÷‹lşBoF|§Á X9űĽn˙Y#7ěµnKîdË·5ł˝ŐńÖĚýČ«-üäoîöŮM%‡3CyÄAmŹ8ómPNŰEéu¨'ŢOGÁňÍűظA§ /G§®°<źČHâ]ŃĺĄű„gÄ™"6´Ĺ~kü\#rö€ţĆSLJ&欺¸VxÁ>ŮŻĽ…qbŔ#Ů85îlbx3qńô=§O!c-čNż@Ť±čż6 ß"`”śöÇŕď~0ö(üÍf)k-ËŽXÄ–ĹXˡʹ[ô+'í—ÂwCŔ˝mŁ‘ěgÄď“<ň=–_O)&1ŁôĄ-â­%Ö…|ó9lĄČqfV/RžÍÖŽ­VŽĆśľtiĎćŁSČŃk&Żä›ţžäQËĺĘwĹť/á—ď4X.ćü‹Oڏ8I#”Zxí)}ţüµ"ăˇôÜ͢ßCéŚCús%¶µ+ôyˇ‘ĺrEüۢ™Ńľ(}r˝ţ°Ŕs°O°´IĽź \áłÍŔ¤t(Ę€x&Ŕo°úźáu~“őٰϭԧRĐŘ'îł]—űżëaO9N‚´Š˙`ůżďŞŞÁ´ě».ŮÖCÉËs~7±-{ç2 ŘëHfôÔčéÎűŔó™¶źĘgg…ŽłrŕőL˙şB—J~Ř˙´ r^hŰ™űa–ą̆ź§céJé‹1˙ÖĚW$nťü’oņJ—ţ&ßkŮă;áOq+Đ˙třîďZL< ú-“xC { r;vŇł™ŕý‘ôÎpâ4ŕNĆ4®ŁäyGه8%°QEüÓç·ú‚Ä”ŇV±,;…¶ {ĆŢ-u‚<óëĽŇiâ«®‹`os`Ý#:Îg˙.”|Ú“NÉ•rÎ4ŃňŐ Mg:ÇAŕ»yżGűh饌źĆbc´ţń}ÄŔ‹}f]&Oú§<ňČň'ßÔţń»%ńÝ_Žçós»;ósfŻV^Ź$Ţá+Ó¤ó Ä_1nĎgň·]ń›R[37–cčLęĎ Ŕ…ŮĘć·$ţ+ľÁ:JžhÓ´˝UşČ#íßŃrîţODăłĐÖ‹ł ^î:›‡“])÷3Ł.¶•¦9SG`á5T?Ô€xvÉ+Ř®y ź{ş_˸li#Ń_ĎÂoWhedyéIgŐźmÎ~%Âň$_Ŕeňé`Wčě1űN‰Łň¶Y¤›ňkąËA\úŢ/Z~•'ĘHuާ4×'g}gcŹŔrÄXöSRĆl/Xf¬Cšâ'€Wz‘Ź&íW:Ů]˘Ă‰ý§ă ˇ {˝Ęń<ě=Ď4Đ§Š˘Ż.˛$źÄ%ŕý®Đq"źľáJżkać貼ź’cOÉ´ćÝĽŻîńŢô~ÝŔâ3qŘŔ#„ßůŁŚI~ĽóWá9Uě /¶ůŤ$îłçCép„ü©& Ś[Ű2$4+M…¶OJť'Î ďÝŰ{ąČŻořK¶ěZ3‘{ě÷h—ß'ĘX+ţń»ĚčĹľtyoc}æ€öIň…ž9Ś!‹d›0¶ż®é+dlÇŤŔݏÝö#)xŐg<&´kFńH 0‹$=m“‰ŁĂů‚©čLv‘vß?\ŃĆg˛^PíÉĎDŃ6JşSĄłˇ÷´Ď@űÂĽ[3¦ĎÜžŚJŮŽµÔ‰ś‰Ń¨iç;?¸á·7%ťý…ň¬ĺľ¶ĺŁQµmNö;‘ę˘éO˘źmiÎwş8RčłIú쏳Ľ3ŁźTU™ř®n‰×>Źćż±Çńŕż`§ŢŐ˝ëÉ/ăŮ(Ą±6É·Đv¦Ą“ůŚ ®Ő늷}Ëwî!í ˔佧ô–¨Ú!Úîeł'űĚ›dEf;1-âÂňŘšŮĹg˙е— žý:jătCęŐ~ł1?ŕUIţÔeÖňI:ŮŢ2=mOs˝KĄßáÍc$k|}qDľ§ü©üc93 Ő¦Áň~éĄCšW˙ńŚ«lŔ|„ô§ů óžX†”óŁüżř‹_Ľ{ŃżţyŽĎľzéŮóRđ=Q“źsM™őj¬%. µ k::őKřgďq˛W`Îçŕfň;ž“NňÂr! Ó§[çncËr<čbwÚŞ˘ÄsH:;Éó%ńÁ&ĘĚĺĂĐĆt†‹ěŢźŢĆ·e¬(—wŇÍTs˝}eÝź:ň©}.bgňČ?bm‘Vňß{ŘSźln‹ńŠ©7L±ox‰ŹŤ÷Ř6›ŘíÓé?×ní«g|wC~ůč!áâ-_Ůb¬ě¬m¤ťúh¦Ďy4—‚{–ĺjâd™>yd}č Ýní yÖňV~É+ďSżů·®öaäqĆ,·G(ľĎz°ş÷‰‰UÚů óç;ŔĎŽ\ß̉ 'Ξ‘2ŽÇ˙#/}Ăuż˙‚č0ç*HŹúÚ›ţˇ|űÝ‹Ó?™Sxźß_ŇÎ1Ď©ďä+PĽ팉‡6zkl1mżÓvßRžš÷§ĘcI¦1?÷ú0bńņđ˝ŤýkovHeJű“tţ |+]u.×ww>„y±Ms˛ŕćvâĚvSFc‹rĐúˇô9Ůż›ůé˝N™3Ţ.ĘďŤÝT Ô3ŘkĂö"á }űŰGĐď7ôčd"lXWźrŹč9úŮ˝ý'·n3Ý\ďáŃ@ń2k‡Ř—ä}¬Ń`=¦Gć‰cKE±¦łꮹ€}#ăA;Ďw˙óŇKŤúŻ—Ć}&±ĐáćɧlĂľ,ĎOHî3­zlRs˙»ň5÷BůýĘőĆĎsWč§%ó&ÉŰÉî¤s>ô˘{‚ě/—vŘrn.”™‰›t˛‡Ü€?,1–ŔHŔ<ú›§›1$Ľß¶fŢ­Slűá}¶ˇç—ŤÎ‘tb©wŘň3m•›?icó“‰7Ăá+oĚÇŹ{«˛|8/˝Łđ lm™Ăš—ł\+MŮÁkĺŰş\±řĺü]ń5ážą±ś·?OćKý[;®qćšŢtŽ…¶»ĐÎîeßÖ+ë‰ç:ďĂĽZçžŮřxgă„ňÖĚĄ;„{˝ÍWľ UúkŮÁŹŰ÷×¶ŮŹW«}®cęüd~5öIž~{FĘŘ+'Ę’mÓ답ŔŤ9LĘŽ!š/íŞb®§śÇÇ\Â*ářuă±xÎLwŞ9ůĚč»ë{Jű ßłXąĐîißWóÓ#m¸ÚE/˝3uK]]   ĺÚÔb[ż´_Ĺňđ÷ŹÜś±Ž.<ÂĎW]ˇí9˙Ů»xĐvĹ[dŤ¶uîmVç9ţ$Oüó¶Q­™»eŚBY÷÷»‹nŽ3{vşó~ił)k¶cÔćŕdçďߌ‹€O(uöˇti~ft•ťnÍEG€Ń‚ľÖĎ…âóóűuµW‹\Vy𠇕‘ęx®wg´µr˙yŕýđ[ôŐ¬áőLý0—]˙ě@ě.“f·`đĹR˙ňÂłýďěŻ_Đžü;öřfęjCMá;¶Ü¸B±vkĚó6b[ů®ď¤ëś•ĂuŤ‡×ß×{*tú™Ćyźąßw6^^÷ĂZ—č:ŰMŽ%Kî¤ď· 3ŧ7ťbíu čű‹<Ů÷˘^±˙sú'·™wÄjäYvkđUUńřčý\hŤÇß&}fö·ů xoá±wŹÉ\‡Úľ,đvř,P|ĐéľŐ–/ć¬ĚXŹŘvîZxoYîUłRľ¤câŹc9ŕ%ÉüťÎˇÔĺŢ…1đwĐÇxŹĄ—ß…ňťÖi:Ŕ´‘{h“…öžŇcöŽ™)SÓ§­ŞÂ< ŘÂXjËľXUŐĘá/p?y¦éÎĆńţŢn+sMż.÷zKovđČIţúčóńľ˛±–jůxćXŹp÷á]Ržő{µżnîÝăKĎűŢlśc#Ľc\`u‹ó;5…Ź c-[‡cKęzÓňR˝”éHâwŘăé·vžk_MŔëvĹCĐÝIŇfĘĺߌ5ëďX™RĄŕµNÝs·iĎë›f].:Ýů,¬˝€.ł–Ę4ú˙čpĚ‹~ęůWeěÂű÷őžŃyĎ"|i€µŐĚw·Î÷řkO>belîl˙1_gëŘx°V°ö•2ťçä5ë%öÖhćŘ”¶Pßa{M;ťşä}¶|őŮ–zÄşlă@ż»ĆE~°Ď‹ĐŻc¦¤łŁĚÄăó€Őşu“é×rś±/Ö.\¬ž-•ÇW˘ ţ$ľ9íźňöeNwv‘zKŰ9Ąô¶ägíÉěxÁŕEVUŃľłśfîިŰŔăŻÔeV.íÉK·Čúş!˛^5xłĂľ˛·ľę÷Ţ{ä˙Ćó:^Őĺ¬|é‘cʑĵŘ/Ŕď/0’ŠŹ|00gňüŃţ(Í{ś—Ćęę@˙­áwĹŹľzJ«äľGŁ™łÝضĚď†Ňżľ±÷đń?˙ŚŻK]ĺoľ±?Aô]ń™ĹžÝ$±$ţ~t›“č›í$|¶%/•5XŇK˝1J?Î-Î٢ˇ¸öńČĂ_żís$ł¶5[yn®t«‹W{Ů‘†ĄŹµa­¶ú5e«§’íXËD·ůĚ;.žęÝĘ˝Š*¨H "Š*¨H "Š*¨H "Š*¨H "Š^m@śězÍá^XzrÁpbóÄöNW¦ŘKPćoÓKŕC´˝]§cşŮÁęóĎ._đhúě#ŮmÄ/Ę»żÍxđK>żą\Ü’/Çtiś‰ď m-@Ľ¤Ź?¦;LKĂg ±Đ–vđYĘ˙ᠮЉ˛6˙±›á?ć÷{ę9Ű]ל g:Ťöäů–M~ŹÂďÄŃbż\á ţ` °_§ďč‘ţ^ŮÁ8bhl= …>ç1żŢwí}¶)ĎĎąäcV«‹—YšćçÉö\)<ÄăÁäě?š¶˛I°nőIËcGě“ثΔ5Ö*á˛kůÎ_Ů9qŕzXżŤMÉ«ćŐžü‰ř4ÂďGxm–ořŽŮsľßSzqŹ{>Eâ#ČgĐ{gaćďÂcO) ,–°oß¶=óťđ«1{Ç'¶Ú¬<“^ţеߖrČŚî|…ß˙ŘKNřkÍ\eËńźű'ö»FčÎwŢlËҤä˙ć{ŢwŇÓ6-˙››îŠ{Ć}·óKâ[áďó'ŃWěSh}ÜIŃś*żÂóĺĄĎ6{}±ř ĐÁĆam^}áśě-ľË|ç/śk‡6?¦µ©~5…/cŻH§ľş¸›ŐŐ@q{čäSÖ/Š~#´Mđ‹’§šÂ˝QÄÉzśú˝ŃÇ‘ľSä—ď« öQyµf.„/ĺ5NOéŹRŢŔńiRýŮTĽN•|˙čż ŮL¨©Ţ™ź»3ň¦\ŻŻ|€5ćŰq VŹ3ŁßžŻ’üv$ßy¸<Ăz¦Mmů‚ě`ٵˇSĺ;S÷&îťĹţˇüá 2&t3©l‹şY~ę·«4ÔĺöźăJˇźeÉžgůk1±ôÔ‘ŽŘ^‘đyÖď€ß„ť–oŢď~ĺ˝őŰé“'žlő™é@ö Ł-?>;b&öqđú‡Đş>_íÉ»#»vÇ;7–Ä©ô÷}ÖŇOýď)ŐËs> `­š±{+FŃuµÄ®Ři^Ăt›Ó_«żiđŰőĹÚgäűžRó¬Řrř?ŔŻţÇ–ĆbíáöĽşXýűU¸oç7§÷¸¦eăżMÚťěŽÂâäýXĘÄńŔ—˘1ŢM§xüHtĎçöäšČíý&î†ičŹĺ Ś2[î«{0këőŮÁ;ÄÖ¬6ľ0•…ďúܦö۶“ň-ă¦<Ţůď˛^Ăo:«´˘>Łeż}ŔFsEYÄÇó9Ë·ă´ŹÂß cżőúŤµě-öJĂLűÂ2Â>˝–&¦Ý7|p4ć8G§˛ľű|VS8¬Ś3˛ýč”´WäWăr˛_”rg9óý˙ö+Ö> xLúżcL 㢯ptę°ńgO*}CŹŔÔ #.Qbů-óZW{eÔÉÖÁ·ŢŤ;` bol=ç»,Ă’ŽÔ žS~Sr:Qď©˙¤ťńŁ|wuďµÖ†Ő.„ý´`…Żýg,J±6-ř/"¦ěaŚ]ŃÇóĺÍ47ć×ß˙+»bí*ÁŹĐtĆZ¶%Zú¬Źcr†ŇĄ}ĂÇË7óá Ąďzuş=ąHžÇ㇡§”nÖňçű”Eş´Őşó5‘ÉŞÁmŁf?bM˝ŞĘű˝{wúgÔoę‘Ú¶˝Lµt±0oľ“tv‰rńˇcÚ°GđóbâÎSÚoůŢĆücoËIż§Íaś{ľó@űŚö‡ĺ|{qsŔč8Jhî ý$Z]ÜíŮŢöůŃ©wČ3`a1n#ÚŰĎę¬n3?ě=*âł#,Kĺą#Ö öŚ÷Če@űÇwKÁç$¦ŽňI<†ľú›Ęö04»=ň4ř ¬'¤Źéđ{'{†ŻßĂ{ňťlÄüň4üéŃĐç˝ç¦Š5 čÁ9~çcÔ_ľŮ3qĄL‡´˛Ž”‚ŐhßwţÖŐ>'eUh»BľĎwî …/—ÓňćkÎ);¦«ő‚çű«ËÝmećĺÓí™<‡Ň‡ÚŘ `‘Z>±¦S® ěSÍel´\ďuÜMhż–‡Cůw8ÇdFĄ?Öž<Ë ĺGŃîJž±Ô¸¤“}ë”4¨üµ?Ş<ô»ózoCŹŔVĽŤît/úËşO@¦îQó®Ë]ľŁr,Őjëć˝ě3ôĄ0w†yž’˝7‘6ŕž6˘/ÝTh{óKÇMŔ˝é^DÜ ŽŻXßhS´_?1ť ˝.‡ŕ˙~ži”oĺWŹĹÚS›c©Ő¶ś'ć›Ř°$~Ť¬} öý ô!e ĺÝ0”ľµX2ś ô˝iü:MÍ<‰ąOúâń[¬|'ć˝!×ŮÁ›±ÖtŠŘň¦uǤáŇA[†ř]´§!ü}Et¸ořăľą9¬5ůřÎrĂXË'ěÖPú.)ó\ďöÚ/IËm \i©,kŇŘ-_úÂçÄwŁŮVGíŞ>{Ľój‘ë6ĺŔçlO×¶ü¬®ĐŹ%”!pVb k Ľ·)iĘŚ^Ý;PŹuKźŚWľ3a;Hţ”ď®Đ#ÍÜ7›}ŢăśßMŢ=yľŠ÷7ć—ü˱ 08˛î÷›„×bÜâö }Ţmíć˙D—{J±3ô ´cc-őŘ#‰¶čOŔĘ `Lađ`™0AćĄçŘzNÝfŰËv›<ęřŘŰ‚ë[*c”đŰ™üaN®1–úĐaô›:f~‹S—ŔÎě úݰĽKńůŤXă0ku# !E˝ ŢőÂŘ“FŇąs©_°ĺŚ~Ćcy‘—“u÷QŕŰŞËćK3GŇZdŰ˝?Çţă…çóч ­äzÚb༯BťwšP÷¤*.çýŐ˘Ë×ĘwŔ7]ßKĘvÂÚ›ÜîóŶôŇ ›O»]ż ×+Ľë3öĂr˝·1>X‹îX\źĎä1éĽ_xL)uYŰěeŇÔžď{o]mNňŕ8śş†ůtßsÍc¶Ž´)ě3júÉ»ßoőšuŹ÷‰Q0l”rĺ5Ö##KâGŘkŢă Źü1=ÖWňcҸYô$0ľ%íÉż ü!¶ąŢZěóF[ďM*3˙żoř.‘5°˛ÂjKËxđs"s¶”‡ň­öíqv˝=yŠĺ‘ď“ę´×J­Úg¦Ł÷€˙kë:ď1­©ĆëúţlłW[ůoľ!ĎÄ(eyCIĘ3’]gËUÇž¤Řâq m—cnđ:W´'ßŘ<ţä‘Á°ŚŐŘđÚą@ńÉ{ÇL’Ólđ¸>ib­Řa]ć»ŮÁëląŹüf'éŹç;˙)ó€5ÇťśRp­ĚÉĂĆÁ$ ٶřÂűYÔaĚ™;čo`o‚ÓD~1wNp}čšéw`ż°&ŢtrüŘŁ* <Ŕ›1_чz·]ą~>¸ÇóÖ1ú`đ=ŮjÂÜĽŽąN•ďY·çĺWŠ €`mĆLó±ˇé…ňWH÷~W¬=°Ś'Ô šą'×îE2ÂvfyÉĚ›łľŞMIü|uK˝xĽóăVwYoUwĽéo çĐ[Ëw$·{Ł»×B÷"࿣UÖ+ĽuÚ{nxč^´{Wń<”˙¦čĎ mőöś×[ÚŹó ‹SgŤ±ö“:Š5äh{Ňě· 6©oř·ať'ě>ţ{˝ÉŚ“\ŽZ3Ń)űçî[ÎY ĆĹX[hJ>Q\Y'{˝3’¸ Âv~Ť"¶g]ˇ}˘ťˇ^Ż’µ-fOXęçŘ˙é˶mŘr¸›š’bmłŘšţ…˛«eË·ÍüžůŽWřÝnßŮň9śšÂˇô˛'™[â:Şë“(şřoú5p×^ő<ŻiŰşi ćśŮ·ŕz’ň¦Çx|G™Öë×ʱ§ôNŮ …üp˝^}qnﱾÇăűŘ>*ď˝Ú™Ńý±ŽtľřŔ°ŹA~Ö´=>0wJŰhřćDúű«_µvëĺʧĐÖŹľéŢÎśŞk­~ôgŕłú,Úć§^5íđËńWą_‘@E T$P‘@E T$P‘@E T$P‘@E T$ŕJ 8 {X‹xţźb}ů·‘ä݇ȜâËěş–űökçĚëű©\µÎ˝pĘőÄ`Óâ™<ćţUŘóč®WÍ<7})¸ĆĘůL„3nPć÷°ď bX®Ź7×ÚrÎw®ر|ç\ńťČw.ľs˝Ýv®P嵥;bfźyÄ’É<őxp˙IóŐĺĹţŁđ«ß§yůÓŚ/°2PžňťŹÚyĐZř#@váţm¦ÔýfScşLh^{/|µŚ?…ćĎxe=ç±üR=°ô ď¬kO®„Í8ě»·Ű$h}Ăs7;ßNöˇűąÂż˘Ý7'ßž|=âTŹ«Ďń6ě7÷łúUMŹĄžFŮęj 7ú°†Ňoń}O7ĺ5‡ýbőëx/+}g¶Ž«{ź“ýňŕ—Žxő·9K«˛bôĚH8{¬”-öęšw-\*4>’>[ŽX—žŹýşä[Ą­¦pi¤5ó-Ččf¬K|ĽĂ'Ă^n}9ň9ˇ)ßůOźß”¦ł)Ž(GźĚᆺgöyÄ•ŐCřŮ8™Ń faĎĆďv^'u™q†«{/@ů #6ďÄÁáô÷ď9ç’sŕÔě«ä{Ú[Ţ;3{kl ˝y€fËďą^ěcToiŇ÷zJW"¦rˇŘ2]§ŇgŘŐę.ď}k´uąď[»ÇÓęb}*-˙đ™’<»B_o„Oíf+kŇ›ď<ŐA\»đĽ¦ÍěůĘűúIl…Xś4öŽ;˘\/Mnwô[{YýIĘeŘôçÚŕ_ö)ń?Ŕž¸rqęm"'ŐřŰ|f’·˙–ÖP:áË73z/éŤ6ńXčOI]^ÓöVřŻ·XÝÔt˝>í±o!ÖĐÝź1˘Îę^Ó楗.žé‡âňýN‘ißđ ÖfhÚ3yŚdŻGÝz¤\~KĺX—»xg˙™ŃĄĺüź’ŽŐ˝'Á‡}wáíö’}ŇúdôCâ¨Ő7ş5ł¦\\Čłúk˙ęÓ#÷­™=¦ěéîŃŤýśź;Ĺú0'řŐ ŻŮÁź˘=ľ]ô{] ʱÔ|´c}ňÜ«›«„=^ŢYĎ!.ôľč<řmŹ$LŽ{1m`Ď\éŹuc`Y˙ÇßVÍg§”3żťÎʱ<ę—ěMÇřAÝčż!<ÚR×4’řŤ”A)xúeî„ü†ĺ¸Ká…|9aŁóVçŰŹöęÂňŢ»Ü'zľŕŮ ô|=ěé'ďjl¬ć?чNďO÷KťśŽŃ0ý~:b;;’H[ÝBQ|u …~Ĺ{›śěyöó&źíɢŐUúDQvÔS¦‰6Ožiü;|ĺ{Ä=„áC‡ż˝ťDŚ~íÝň1m O‹ĹŹőM®OŽĎlśôp¬d|ÉMŽ}ĂoAlEíoXxֺȧżkYWŹëţçć}ô?m;]S0|2?wA3ăôóťwHěűÄ}W‡ŇŐĺ}Ť˙k xĆjo†˝o‹0Fˇ+4ßĘÓä4ý˙ôŐcąd?+qîçŮ;ś°yĄźŚ˛ü mż°÷&ćśďlŚĐż“{ ¦/·äsa`ź Fň^ô9·¶ń–ÚFë÷#‰árąš¸ń±–9źtö.żgÚ6Ť öŻ=Ń46ô¨ľlîwôQ42'ź®5{ů2oĚ^b˙bé#µfDtQő€ąŢçE.óţ¶`óśzłđ«z‚¸yÔĺůe>5×{"Ôł?Ő~´u©\wLLůĺ3ľ źś ßé÷v¤/ŰÂŚóK#Sú'÷K,÷xđóÂó-•±Q/çTźa|żřÍśŞż -ă\ěÓŕHଫý°¤Áw‡ŇËa –'b0`K^'߲üu9ýăóíú‡˙î‰qŤLmă~´Ëä<˘µ9KďK ^S‹Ç‰ŇÇŤXgÁ–ńŢxđÔÍS§”w(˙„đ˛ÂňŃ…P~7źśě‹Ä8‘˛d}Ą Ńőńg>Ô5sÜýÚ?Bf&v1çSćmŢ]ż˙č+7›XĆ_†ůť7:Š;Ăs˘)9Ů]ٱ‚ŃţţląŠó&µťuąKőÄ&}ŕ7aäÄé=(íúxPń/LŮ±Ś©űWĂÎk|®ň [ ľvôŁ%Ć c#”ž =Ţőˇ¤ŕ^± d]őoę4ď!îBĘ ĘQÖţiIż)´]‡ÂßBmÔŇŘ˝± Ě;żĄ> żíÉË‘óiFž&/–őHâ.äĄy›r~ăíŁ=™xöüË>˝QÖ÷ČX oű„¸ěŰ|č‘Ę™iÍĎ+ĆŘ5Äů!Ćőź~qOd”w”ýe¶䇼ó\űĐńř;€Yń€đ«ôAŻ0G¨~ľÝ‹Ĺ€O±Î“bŢdz҇ýZďľ]Ö´Ë¬ĎśŁž—>V #ľöäQó2G#wć üy:ěpŽ‹÷ř˙TOő\učŮ×y×&čŞÔeŘÁ ĺŐ˝(őÄőíIe{bňO8â–I]˘üř÷gÄe2Ďéţ¸˙#bŽ=ň3¸L÷ič3e ńP´ájoč‡Îg”ë$yd<łž“FÚČ*t3=ĘX5|FiÚK¶ˉ%:Ĺ4ůîĽü^čł˙ÂŇĄmźměoĺđ\`'˝Cä–tVG"Ů–ÓgžZ¶Ý±¨Žv]÷ltÉęÝ›ŐÎşyv‹íĎwţŔúö˛ĽÉŰSÖ&-b!Ň&0mĘŤ¶X€ÍúŽÁ»1y;Ů;Ł#‰Ó":N~Y_RĐĄcýÎŘwb~, Ó§W^˝Ç©ÓÂ}đ‡Ä¶±śI?iâ۱$†Ž×|¦zÁg,_Ţă91ŃţTű\S(_5ă7_¦G=peĚg3ó3vŘŕD˛uóĺ5ę`409@xĸ &ş€9N©Ë”—é+™ň®)ě9!ąVƢÔ[ň˘ý=ÔOÔˇt¤-ůŕOgś•Ăw…łí’žŃ[ŢJŰ*Ö™ľa'c:Ü“^Ę’ĺ=QÖ&O“:ć:Ĺţ`~v’ 1ĺčÚ=~Á{L[y>’sa©+ ¦öEîúŠŕD*Ź”ű_ďĆ÷Ľ÷xfÖs¶no,ĎăÁ¤č ÷{Łw~yŹŹŠv…î^çĺźĹâ-Öî"¦ĚžßŃ6ę_¤1y·ÁrTť'†ŁćĘď'tŻiŰ2üb8ď/oňô¶źŹ‹ŃÚ5ŕ ÚĽ4˝Ť9_xÉ.”ąIęŞĘŰdßs2† 7ĎÓť¬´Áós?—#ę<ń}t¶dF/ń ÄË6 Í•ĽÍ|ĘŮ›˘{nÚ÷zcĎŁßÄyW~Ďú¤¶%3zđ$\µCąŢ=|şýaç8«o±T±±îŕC¤ž#íĆí‹·ČůďZ悿”Ô ć5ĐŚś›~›ňjŽČ[t˘+ôUĚ·ĽmŐpcş(pÎ0&ŰÉćĹt¦óó¶{űT-.÷—H‹ƶgb ëÄľts@Â'÷‡H:sD>±‡Ć,żĎ°óőŔMfä5Í´ŁjKĹĎ‹^+ÂĘVc/§ĂŁ÷[®·ÍClľŢ{ĽóË”íć?#Dí.0Ţ`·?jßŐox «šw*ďŇß_oű™Ŕh‚­~ŻČˇ.÷úzgż· Ď]ˇÓÂëjĎţ(Oţi[ÇôŔŁţ€ýZ–ĄŢ™ąŁ¶;ă±v‡ĺ{+×ŔzÄxđÉ?ßůĹĆěź‚–ßJ,4ŰbRƵ/Ä…/H:ç×÷ _kËY©6ýŽ_ź’ďx?×űv´gn<˘ľ;“Gěc 1Ě´[űµüĆ^ŘĂĘóYÂúčMÉżücéĂE˙8?¸r8ayçŘmšMt>Ţ™kÄ:–ĽvÇľ ›ż)x^1ş‡-_ćGşXą‡…ćOlhS÷“ĺ:×mçßQ7€GüY÷aŰC\Pöłtüß"ěµý[ö ´?ź›ÍZÖ=Ąż ďĐ=Ěł¦±żÁ§…gPO]9t/âśúŔ™˝¬,łö”;Â:~ ™Ý3– sp˛Ç†í üe«Ź×Ę\ËXűO|ŹşŔ#tVlÎ÷ G—ős§ŕOÇ*ć]÷?0jĺ»9U——őĆ}¶©ÎčĎ%y-~ŁĐ˛bôÜČ®…?I?ÉĄÁÔWÚ4ň¨râsĂ›y^—{«č1dç(Ď—Ź¶„Ů ěxÄZŠčtvđSěK"yşůĚţú čS\ŚąŮ\ö”jĽŘMŮo \sνŐ]`űË:«×^Á/AöŠ §;» >w(˙?RŢÔŕ}–żçüůÝ‚ńż9řęřçÎgźÓÉ9ô”ŔNz¦řeRós5›7űM™·]»LE[” yÔÓUĎ2ěţQyÎÜ«˙ćk`ła=ŔĹ’›LÁć˝Ó{řńÎv±iiě?GjČ#uzŐŕűĄęÚWWhô/ß*ĺjö|1¶L׿0F•ďá iŰĚb¬±ď&×é˙&ŐĚ(}S7Óę¦ę4×t –5Ç„=m8ÓkÍüň0mqˇmëćşÜ´ď܇Đŕ'NţůîşÚ«m?”×›ű—}ĽL[·-Ś…-[Ň§íŻ—Ö5mě›ő.Ţ_¸,\ŘŢő±]kśŹ}*˝ßl‰çËgX——bĐaÓ±ţzé­Ë­‰R&IçŃs`Őp˙Ńßgj¶˛ó~łĄźc‚:~jí®ę8iî)„/ŻżSk¦Gü+ üÚ-®Ţ®Ż¬s˝}B;šZY‹őö§’Nµ¬ťžtqĹ_•eűrňxóÜQ±k}æ]Ó÷¸~ˇç•cE T$P‘@E T$P‘@E T$P‘@E T$đZ’@*đÁWç<׫¸VÁą?¬µ#žĘĚç·fjěˇňŢ[Ž5ݱňţŕzwË>6eß's<)‰rN·çěń?–zÔřWm>gçŞ[3fr…9AąOŮPF\óđúám©ś«Ż±™ĂîF\Ý»ŁŔX‘ő ]“ěď7k’ĘCGě…ú@ń؆yůë#§ţ~îĽp‹•“~·%Ő/Ó»öĘą]úT“>ęůxpoře ý­™?,ŕ>||†)ěSunăpâ±ĆH¶ëşď”ő÷şÜ‰QĆ5ńť-ý§:É=˝č€íƤ¬ďD<3öĹÜoD|ŕ.ŘĐ7ü`—”l9ö›}ĘăqÓOąŃ''–ÚEćü77ďý{X}ÄÚ¬ÔeřSűćm‡ŇÜÜüşB¦˙Ľd|k !±aĐ}™Ď^ů­ĺë°áńŕÂ(ü%ö•şN=7ľ(¶éiş›ňŹ˙>!îCó°§ }JÔ' ő±ëWĂ'óHßšD ¸Ŕúx)˝ô!¨)ś˘~ěńvŤÄŞđö·LňĚ´úżşŮĘ{NŐ™ŤmÉűśöŰ›Ě5TňJÚňťŹfF_®·gÁgN÷­}Tô"ŘFx>Ýé´z˘Ľ§óDONftŰ(ăD“_żÁęŽÖ}SCůoÁ_ëűaÚ&őçŽGëĹ–>/=X›µşë˝ŻçË”ďúÍ~ËôĄ`ąňϻ޳9xÎwţŮę)öźrŘi;¤ôOu ĺłŔ7Ř™±€Ť™Ń›°gü?â<(˛SUŐ´ ţ)ŘÓĘ,„}«ŚÝflĎž¨ß÷ČšuľóâČüśÁ›*ŻŮ¸ÇöńD¸Hb Ů‡P?Fo~ĹÚ«!źťóť®~fô 0üß-_Ŕ`iúż–ąVŽŢďynâH»áwökěÉšrhĂScŔdÖ×ňú†÷jěý6¦dmHşÄ—îEˇOIúÔ™ç?đńÁ}•×´ą~É|çöţüµ/v¨Ż^ť%¦^$;2ýŚěĂpŐŚ—7űÚ§lO_KČ[ö fßÚ»˙ĽˇÂüĎŚŢć«s™Ń‡%>;’=Kř¤_#íł—ď®Đ˙Y™'~gĺAž«‹·‹r˝öśícŇy"rÓŕ­ Ľ4lěůrŕi™˛O” ü mR«Đ¦ýlÄAż{-˝ĺĽ€Ăó,üĹv–rXŮ]ú˘äÓŤ‡5o2ž”gˇüyľ23eß-mĂ@˙iňż×q żÁý‰ůňö´~NöśđŇŘČĎÄx21Ä m­™«ŇĎż…™`źîŚĐż\_óĆ‹ý˛íŘźOJąŚ$úsčĆś1íěŕ2áaYŔÄ™3ß®Đ盇Ň&mľC˝ŁžŔż®,+oČgÓů!ĆŔ's3î^ě™ćBŰăŘ›gŹ|ŤŻ°á¬}Ĺ^ă>ľ˝´/°ńÍ™QŘňÇ% ŻíčÚďf‰#ă7ę}+%mÄňŕH:ŢŽ!™Áâă{Śgáq&~ÔkSźéÇhţ´o”ë˝>ĚôĄ7>ŽĎÎĚ6hK÷BüŮËĽ.÷ébÄÇŚyKö(´2…O⿬‡9Rţ´ÓÔááÄŞČYˇK…G'űúf~ĎűĚŹőLÇÚÔő;s¤Ě§Ë3b}–/ńr˝‹Ëó.ďL˙ ‰ýu±pĽyÂ7ĚWÖÉ ×ŚmĎw&#hŁ|t˘źć{źiaC‘iëŹz€M´Łđݞç‘{›ł\&Ć-zéXźsîo]]4ţç*×ěyŠßgxf_XóV=`źĚÔ.Ü_•wŕŻ>ÉľnŹ´˙młw·¦í=2}˝Vş>:Ń'·‰i­ď5â  ›WIýožř&vÄ’´Ő–2-Ť+QÓ6ÖŘ·ľ§fîg^ţ^Ës*°˝łjđ`{Ť8Ŕ†•Cč[BůŁflęŐ-sÎ6Cý*č—®/o/÷|÷DźT¦,SÄ "îíÓvźbá9ţT9/ĄÉ¤ź}KC ¸ b‹ÜľŚćÉ}Ëô|$ńíŻÁZ9ڵ(6 ¦ď=żw¶c-_9QÇ e턦ż>Ç'߉PľĆ÷v*ü"‹aQŚ#Ú‘ÎĐ›E7ßjËŠůĄ2@}ľ]äÉÄ;ĄźM}HO}mŢSż|óÜË«9ď ĺeŚcĘĹřĎ’˙‰é­ďuWhĐUŤĆIył©Ţzi@ÜşŘ`Ř >uś1•¬ÓäýtŘăĎÔE޵YŠYÄ1šĆ×bžýí>ôŮźą±m ťP[ˇ:§GčłôKKŔŇ{L;3şń84äŤm#ç*&ËĘ•űd›ež‘GŚŻÂÄYcÝ =ĽÇ#˙ČŻ©OŔ.€Í€Ť;b±Řň`ě•7g7O>NŞŐĄĚč»wó+Ţ/6ä|$±mC±öv[ŻříXˡѡôHÔĚ‹xógśŰŰ´^‡ĹH9‹ş+}é#-,wňJ}ˇ,yÍ?ŻM “eěVUÇZĚ›±)nÓ›w·`M[Ö-şxôśc~ż!?•ćĄEÇU‡üG7EÝĎ›vźwI;ő€} ňĆ9ňÉ2ćĺÇk“ÇÉÝ";čű§§µHYűQćˇüůŢ˙ú×3­nÓ¶Ě›Đt©{ĺ3îMN|/Çč—ëä|©źC,ňÜr|Ť›6ů%?´…Ôoň<’čFßí˘/ä[y¦-řZďI"«5mĂQ]` ťL蜡ř+Ěa0}­¤ˇ8G|îdźŤťjőé§K͆žąqür*ýćý|g7ĆW¦]çővĹž(ë%íy¦ťNÜ'|ŃŽ-‰Ç%ö†Ď(b%ň;bX˛®ó| ?5ö]e_UUS8ÎÖeĚËůäúĎŻ7îÇ:Ȳŕ×ŔďÂś†Ć—( zd˝ţźČQ©ĆX—ŽYJSO‰8Ă ·'_’öĎ4ކyt…nýM|!uA˸|t€_‚y›»}ĺ‰qЕәÎo¬eHŇ"fvOéIÄ:oŰ ´Q^Z mÄ<DGqż§ôvĚô–ËÖM]çńôÖçäťXjNsľó6áxŤ­™[}cÎ=©ń[íkŹ.ęż$ŤT gR~šĎĆ“NŻČŽ1@Ŕß}ÓľýHâwa¶A¤©+tb4é\_M śÄ7šąžU¦ ˘¤iŘąů¨'sĘăRebłZ3+°VhÄśćĹ·9Đž¨-7!Ě+J˝¨)4LĐĄŤáđĺżáĽĄk݉ůx±•­ĆÄ™uą/aż€ŹbÎópřRDÁ÷ŕďZˇMí°WšćĺŻ×±ĎËl:š;|¤¬Iű!ýÚUFńxMy_UĹ}ł×¶Ľjs¦­Óš·ú î6ëË ¸Ŕ(~ˇ!0•úŹN6 ¶Ş#vTë7ďcKřH—‚rDÝ §.ąŞimK¦a ˙ßeľ _|źżB›Ž«Ě5pzDvlŰ2Ł&ŢŇ<™ů˙g… ěÖ%ŕUŤĂ†żŔűĺYˇíu˘‹Ôsę;Ű_ę%íŹc-iůcKčíĂĄ5Ř–żl3{~P>|o"őuąűťÎĐ’źĺ;ż-éxăŃ&~3“׺7ĽŤ@ńš†ĺç{ÓĽsLć°Ůç„]Ž>ś>sA˙ňî^ŘŚů%‘ ż™—7¶Ůű=ϵonî? üĄ],ż}ĂC6?µkč»ůlŢÄô¦s]—3óXóňśź2?`á4Ëż©jÉSűđq˛ÔćP˙ĘŻˇ_Ő ß¤Ţ¶3çŔ ËŹ5$ť#Ęşňć·ţĹÂÚďv˛wGN˙úVô౦ő)á}[ËűhË Ŕáş=(ž-őHó™­#âumY1Źň¸ČĘ:lÇJĂHâA×­÷xT{ĚýcŕS4Ľ}:3®ë}Řf]šýŃĚčÂg(˙M+ošłqľ±ËL7éd›JÁ ĄźOŰF›nÚ`ĄŰôY«.¸|'PĽóŔ ­5…ń¨b:Ýďt|Áű«€wjla·ř”đŢP:´IĘ—yńw?öŻ83ô.ěQsĚ5{q?M[fŢc™QĎ-uś×#‰#yĹ|÷WËeD–gËzcÖ’ÎJi·™.ĺ¤}<3|/ú^űôLs›Ícf4żž’ŐeÍ‹´1f˝§Ô-¸č䑸„c˝Â«ł|ż5ó&©ËÄßĺłěŕĺČsě}Â}Uě5ůćËşşřOÁĄcŘëj“ňîµOĚßűčW Ł«:Ěş;Ě̡(N`*đO6ď?™x ű#ĺD´íZ1ăĹŽŘdŐ˝hŐ`gtďüne]ńć>;çÄ˙gĘÔ˝®ň<§ć´ş7"tÔ8†vë'ϩھ/ÉCŻ˙=ĺSÓÜľxŤŐ©ˇô¶Ń—ţó9Űč;ły„_ćbs0–[ÝŐďĂxb'‡6Çř»kęSâ[3‘g¬“CčŃGÎĂk@Ý~r’l(—Ú\ŻČ„:­LuqŔ®ă{y¦Ý/oE}ľÚá<9đJËxâÜ?đp7©ýRɆŽŰă§'0÷÷a¬/Dź© z ˙ŽŃËĹß>`˛?‹ň¤>đ]=Iś+júÜąŽg|'XŻ9˙G{IçńSˇă¦(?S구É;ĺHŞ.ÖNńţěrLŚ•§[2bX†¤~5ÍĆ>ucߪĄŤ=q^JŞ‹˙cëcŕöXĂš¶íVŚ~q×JĽ‰úňM‹çI§5ň˶g<űĹňî¦ű_¤¦đ„ĺĹÉzýŘLť†?¤ŐYĄ,3ş8ڏi‘|OŠĎ°'xCştĄÜg™;°‹ŕJi[gřwăFSaŹĺìü4ŹŮ8®<éçBÓf˝; k2Ë‡Ű ú—¨_źćĎý2±gWyŤ¦{Đ .(ÖÖ ˝±ŹaĘ˙Č3úyg÷rý–ţ ´gZOÔ‡z mW"öşIrŐ5bźç(SŃ×Ő˝7 oIÇ`i…ň&ć™iÝ}Ě—v´22őŐĺ1ĺRźhÇ4?Úđö䟬Ž+MÓ9Ň&éŃřTć9Đv”X0nťvqRhÖŐ~PxžëĐë5´f¶÷Ů×öä—°'ř÷,ßđűŻš=g)•ŻňĚŁĘmNJѬźx"öP´n‡­§UŻSšČµĂ{—ËřĐu¦gď@WçĽôč9uÜŰ–~ôY˘ż Ďů@̰{¬Ág±,‰†Üî_Źś¶Ô™¨ŰšöÄăÄ~_)Xmó09mÜ˙Pţ|ŕˇ]^n“^‰_Ć )|Ôĺö™[Bl60[ĺřű–ŚŃ•:Ž´ĆŰPç•2ÜGěŐ•’í]4{=bwĆőÔů˛žĎ{ýw"ˇü>Y8jZĺlh0ă·ľás­íR{95 ý/ö%sq„ЦؾÚ/«ÇO&F¬žżTÎŰ“řŤnlĚx/ĆË—:ă*35ϤzÎ>˙&¶§*Ë 9˛ ňň7/ţ+–wÇL)kŕŠ}aÝŻ)ÜŹxŽńýŤĄ®i† ŚŮđ˙Ş‹kĄĽ˝m—ž»ľáF&jü)­˙ŐHb9ö_ͱ­-gÚ&ď8^iÇ/‘¶„×”7éś?ű®Äh]{ţ‚χ߄qÓÂ3Źß)<łk›§i»uv겦oˇń/ě^ô'ë ó7Ę~#v ńčÔía¶šç É=1źnţIç˝R¶Ąŕ—Ęy™gä{~n>°Oß$ĺŶ•­Ó¦Şü–ž6WäU¬˝ŢöqČ/ęq±ŃTŕi̱,~Eýâűô…^˙ťü&Ú:©c# ­OćťjÄ„u…^đĺßűĆĄpëş7!ţůŘȲŔ‹°)QÜ;8şş÷˝Íl×XG¨×üSŢéăÉrÖ1ËśŞĹKÍëöäNe˝Ů[#~7_žŞŢŁ–Ídn6ţÎËŐ«şÜüŚź‘˛ÖÔéăédŻ·tRgÉy瑼óžţ‘މńg…Nîď/DGLş®n)ݬ”)Ódú+{śŞo yšcU0˘Ä™}ĄÓîYîÎiń{ţQfä‘|ë5ë>Ď)¦Ĺë8löŞg,©ÄÓ±źtš¬Má{LcňfŚÉq˛Ô)Ć=‘˙şÜW7Ş>·fΛbĆ®|™¦ńżwď‘î;”^[3É‘t1<±xä÷Ô]ĺ™GĘiňüjüM,`^Z}a^¨çŕ_Ä-Ý‚»ŻrŚčꀴkŢ(ž™/Ű:SG\ĽGĄ‡<0ďůąŁĽ/5ßĂĽ˝ě‰K^hŻ˙Żko©ŔW"ś'&ż,cʇ˛ČwŢxĄ­>{Çn^† `”Ă–ŘnŔ¸üÓ čÎ0ńŕJçĆ żöóKztĎßežHűA[EŔżĚ$ÁXb9’ď±–O?%’2á=ÓŹ0úĘ\Ěí.:vG˙ ľňuy6ďĆRŹXŮÔö—ôâń9ĺ>ĚDz×˙úlj·Šž<ďÁëdy2Îe(˝Ľf’¦Ž¸}«_,+ę Ë’Ďꉗ…/đ.ź‰~K}ć]ó>1ĆeǡÝŢMę±±źÜ3xAłęžŃŞŞŁS—Ř>ť~?ťcGl ëßňĄKýRäďdO¸9ę$˙´Bů©ĎnľÔ óSě ^l2SËŹĺŚ)gµkä‘zôÝéóť‹l]c:\KÍő~Ű'[öY&ZMĆä:ü’Ą™w€ˇçăŰĽe°IL[`ÖÄXŹ™n${žđ|.ŕŰ×Ë9ÖQÄvŔľXi:3uě­A]t1†F»Çj+ŕ@ÝŹueŁ“¬ŰÚ–ŃÎi“ĺámç?mçřڞ˘=â7ä“éđHůˇ!Żnź|ɱ‹¨O5…źűĘc¦ře:#‰f)›‘„™sę ÍG˙Ď`€ń9t¸łi»NIú˝uŰ´g|“kô?Çş»‹ŁŚľµĚ_ňĺ[żEźZřE?Üň]—kµ˛5NýźeŔ'l+úNÚMtchŮ[@igňµ˝öcĚőôŹ-ăWň ˙ś1mB±vŚć ok–žÓ4Ör—Ś#j yřjř÷”1©ĚŢÔç˛>u—ńm˝{E¸ýR·l»­}ŕißćt/”ú¨k­5…ďóÍě;ˇ˛bEL5řbH{ÁtXgŮĘ:2/΄~Ďěń:’¸t´Ŕ¶ľswúĘTée»©çz$˝čs`n˛óB—í7Ž)w×ßHß}ĺŁú×°~lŕŮăÖ¤ ß)_ú== lUŢUÚ+Ú˘Ç;Ëřonyó˝Ţá#ËşapäŚŢ{ß1çLc*ľŐžó™Ö¦»)~ĐŰCűs;:ő.©Ób§sGý;¤ż¦´;Ůe\Á/ÚË1ŔlËĽc}WSeť®.>…ţí%ŔĄ$–…­O5…ęóňMbÇ —Ś;C—)겎§€9ĺ©gnęsĺXk`ĂŚ“ ¶űnOép‘°z#‰Ř^§éßşXŞŹöµ÷šîlÔ”ë]Ę6StlďüĹź¨.îŘĽbôÝž}\^TżŰňő™°Ţ"ăE-gę6đ*„'µ :_¨ď»>¶IĘŮ+G3G@žĚog`ÇtÄ 6šÚ'Ą‘GÚ[¶ąŮÁOMA«+›Ěč3ĺ2tďy稴oŹ˙Ă';Ąc¶ŽąŢ33OéňĚë|ç“č%ż+“–ďb]˝>ZYf*ĺÇĐmć!řŚş Á*cż{ůaNÔĹ->§J—úĘń±Ň¨ďúç–“Ţ÷Yv†G÷=Ú4—¦÷ř…9ç8Šů%ťó˘Ŕ]śBWĽ©ĎÎy±6)XJ™ŃSŁíĎßŇô5Ý˝•înřFr®ŇýaÎKúۦéľÇ7ü¶śwřśmÝŹ€#{<|Ň.6ő?l?”Ď6Ő/˛ßǬ¬ =3şCs3ć"Í–ąÇ1˙YˇůXW}s•'5 Ôdżýž‘/řaxôĹ|§ă•2®X[Š=7WŮńɦâUó‰fßăĎ`h«Ş"mÔ?ě©Qö 2´«~ňŰB[·ĺc ´EĆ?ëĺ6˝ŞŞü†ěEGÎő ď¸Tóß\Gřa϶×›öĘHűműcťęÁ'=ĹÚ? ´QíĎpÎŘ"řýbŽiďF`TŁÍ»\ęí<öއ;é˙ě}y<ĐT ¶ÜŮ\śNÎwć:е{Ś~p¤żˇč)Ëźý‘ńŕ˝5ßĂŻé¦ň~c´eđ…µŘę|cĺ$,ëÉůnąwzĂ/˝Ôą…K-ü™F[¶çš“—ö|ç7‹}ňŇ0ÝóÂö×aOÉçJÁď‰í﮵AÜ3X‘čOÇťĄ±†W=ŻÓ•UĺűŠ*¨H "Š*¨H "Š*¨H "ú1…dŚĽűůÎĎíä'żÖäĂ}śBąÝ1Ođřůś-{ŤŇ›qhy…?Xăxp»(×ý8wŤu©IďLüfKş^Űböů)Öšu«ěŕÎđ űJ„ľžşvCzŧdŢóôr<_ÖďÍţś'2óć[fĂ+É·§ôq‡óžşžß‹h)xełÎŰ{yf‰đ _\™C㼰wnó…[Ň\ç+ńmžéú°ÁŰ1k’śó5>Ý\ăˇ?T*°kÓĘáżřó˘ËŘ»+Ú‚=áu­K×çĚőĎuS˝ůĚĆŹ8×Řůj]Ă⼴)WĂ+éa9jŮ…ňĆĎ÷ąnaÖ.Ll-ËőZ÷$Ĺ|ˇČ„ţ…5…nsľkÚ–=‰µ|Hłę1÷Pŕ9üO$¸dĽ#ö|şÄ`ołčzË•üÚŇQÄŠYżC¦Ç?¦ĄkÖLcS˙NH.˛s—ŚéÄž,V'I×jŕ⨋+ăgH#×'ßKÉü未‹%ž÷uŤ†ßŞŹ”úXđ™Yo>Ř9:eÖŕůÍćú˝ ű|«Ďü¨eĆ”KUfú`ś‰˝©ŐRé$ÖÁţ9ł#}‚ŘNń™®Ů#ﺏů’ş€yr‘ź¦5ŰGĹ\`˝ÝĺĽMťÚş×Đkčk)řNŃMĘCô÷HŰX‹ńEöŇ©k÷|—őşĐvkąÎžő9Ó&Ϧđ¦0»çĹÚoËZ„Ń;®·%GIőtÁ'±Ü§Ŕlõľ2Á^…őNöěŰ·§´QIç3’ő€ľŹ\Ż‚ŻŻłş×ěŻČô( łg9ăOü1MłË-ýZhB[‚Î3d˝Ťú×j€ŻţÄx/ú¦d_ŐŐ¤“ ăŰú’ÎA°ÇóI+„obPohëX—±V]Ţ?Ň”3y–ř‘Çá"ĂžŇÂMbżCů{Ú“5Ň.Qi[ ëőqD¦ťr%O™Üß›‹ŔÖ¶e|:”®nJ˙lA]n…ŘAî!Ěr¤^łOĽ îë¨î¨}3uś)ôÉžn­™EđŤšµőž‘Ä$í•Ă7ďéˇě±Oł´AÔARĂ_{ňÁ Ňz(ŕ”ěeíĽ“Ý˝8qâłÝSú›˝jĄ”]Wč(_93mňKŢ m?•um¶‹Ô‰jě—<”žyßmĂ u±­Ľ·‰ŃąŰ@Öý}xH±ÔŻ…nÝĎ{9‹ţjz,ÖţUx†°ż×4Ú˘>‚UU_MzôÂäĹď¨ăF¶ćë‚öq4Ý™:Öĺ®;Ă~”ö™·›źŇEśµ_“sÇŢö˘+=ĄßŰş“sbY`ŻJ‡qfíÉź`ż$łż±Ë#íĺvŇ.ęŢ´ëjs"›Xę ô_żfőerÎvçŽú ö;XĘJÇ>¤őŽ{cŚ íď±ß<ŕÉcyBlđfŢŘ8?·»Ř­©rÇ~¸ôS¶eËýČÜ÷Ś8źŐšůŘ}{«ô˝už1;Ęłń×6Ľń–?ü"sĺâ»y¸<ë9ëő‚:EËóŐ˝‹-=^‰­ĎąŇřqîßä|óhŰqoşCé,ďL‹,KöářG:yŹ:<ô·Ő—Ů`4“ĘZéP>őH٬nbMÎĹśčöÍ&VŕĎĺşŕĄćżź#ž¨‰ĺĐ7|WYf“yŐĽiĂ€©&ď­íł2FżUöpWŰĆ÷Xä›|ňš,Ţ3şTUu|ňç˘_ěÓ“R';4il9‘|6ţĚ‘Q¦›ůÖE–†‰ďý·kŕ I˝`ÝұˇűÍËÉŔ”‘Ö~Ëqy"ďĘ#ËçĽÇsŇJňšĺĘń2Ďů˝ĘVŹ”ŰĽüłÄĹôµĺ.mw¶$~±m_č3NÜ2ŕG˘ľöC6¶HéĐ#çűÖ ÜxMľI;yâé'źzŹ×üÓk-{“éžZ®śKeŚŮAeLŹÖŚÁPN‹źţšĄ]ďmŘ‘ůNő3ôĄŤň÷ŇËk>'żĘ?ůÓÔ”WŐwľC=§ŚµĎG™°Ľ™.ź«>đď\TÍďnľŻÁTD;ň˛ăVÍűĺŽu˙J0#ŮËDÇłoµuŰđĘç©{Ę«ˇ•)şeDZIŁčjąŽ>ŢY/|ĆűLŹ6‹Ägf±ěŁ<§ŞJúĽŹŘ_É_ÇŻü†¶iđĽmÖ?§YĆ~i, \iű&ˇ|kc‘ó#ÝŚÓĄÝă\ŹZ6ĘżŮ3˘Ş Tň],ő˘ÁZ.ë8ůRŮ1gmËxŹş‚9Čpě…KM˙|*Ć;ߥ˝ŕqěł{o”Íć·Ţ_<~˝ĐhôŇßÇ­)ĽWćł‚ßa#ŞĽ“V~Ç2ˇÝtSç5u€G–ű­Ř7XňŁ X¦ü–v¸šÎQ©óĹnÇą,Ćř›X«şÜ˙ÍM[1ú¸¤U¬˝ąÉČł{Ѳű=>YzgÖ•mČ7ëu`¬ĺ7Nďđ­e\÷IŮhý4ÇnŘć ›­,Ęĺ¸c`bľÁ–%ĺ8ăęŤn›\éűĎÎ ô ¶ćR´?´ë1ţ7xe°ô>ˇő’GŇMýŻËť%}”žÓHëYÄÝě*2ă3ʆďQ(źě ń•řsq ĚuUĆlŔĚFěέ2ˇ~đć”=ă3}{zG“¶±ăk[–‹ kąř(y™/ŃçíÉ`ä]Üł˙üÉ s~łŚOŮ'˙bSW談Ëg vĄĚ“·'WŻK186¨ëä›m RÜ`G9eŢcYëł™>˛ †ŠcŔuÇ˙úŔż¬˝Pźů§ůŇćňQÁ‹u‰đýś}wSO)ĚŠŐMú”Ś«ůţxđVń„Öć˛ě)Cµk3ůŠ+pĽ <_ʱç"'Ö—\ďä} ”ŽŤ=ĆŻy p±ĎGĚŘU¨KŹŠµ?ó}[Ż86"żěC‘¬ĹÉłˇôrж zř9ĚKjëżĄŚťě5’NáűLJąĂü\Żđ ?"I‹:NařžL9ćĘs(“źÍÄÔĹIuc(«ź=ĄŻeĚb3Oô•„ďTŕذy";ŞťRš†Ň‰(úęVvćţÎŇćł?B˝Ö1đ­ŻÝę¦5Çöäç…oę,ÓO:ç[{ ¬Y+ĄU×O©§¦Nűűt±çű˝ŕçpžď)ŰZĂ ë7÷±ą­˙oaÄ;7:ŮyŤŔ]÷褟gĹrĹ–đĂ~éD=.ăţĚ.·nę¬_ʤ3đťąf˝ô’zČö-?s-f?"îáĹ1”¶KŞ˙í¨m5©Ů®xË„vÝĄq¦Ď༩ő»Ł_v儵X–ţr3×ć ˙w…öAźl)Öâ9o¸XĆťSăOGm?ÓP|KěsgűĽ?;żŹŰľű˝ŰIY»ö[sőÓKžĽ}°şÜ|Ű—€ľŁĽÜ÷źýë™Ň>{ďńś:ţ`úlOťĐĽ6ÇQç ÝÔý—k(›®_˝}«±ţú,|gî˛íŔD'^sžŚeMŢó0ë¶k˘$k ‡yę’[FJ§iKü÷Ů~k_ ¶ ‰ĺŢžü_ÁÓŃďôČövŮk»xNyÂ÷pł”5ú„đŤ¨-óíÎxçç”~÷XUµjđ`KoOiŞąúîEş–Ę樓Ř^©îśú_ř;Lí5±\fë:×ŰŇĚůeCĘísrË×_ŢÄ,ŮŐˇ?ź÷}~ _“|K€ŻsDxŕřżE>âśgő>˛Vfţ46ÝŰž] wń2aö#H7őĐkgµ®şM ąźÝhËŹŔŹá™ó,Sbýî‹ůzŕ˝ÚúK-hjKÎ÷ŘĎMÇăÔ9EĂ«{Ť_ź>ç8„mi{ňuRF…¶/o´m#‰·ŰrŁ=Rž“΀ř°G˛g”ËňXчyů6ěó4˛ Ú$Ą~ĂŽócEhÍőžlő°şř!9gů>aVżiŰdüÜy*ötűöřě} |śUŐţA"¨)ŠÂI Y杉iQ‹{ZĹe*˘¤¨źTüLQD4bRYdŠ&Q¦ŠBRqЏL@÷¤n8(8ĺsܧ¸Á˙yΙóľ÷ťLşeŇÖďźůý’ű.w9Ű=÷ľ÷žsîűýw;×úŢ•ç`ůx`ln9ťcKŹž%˛4ű[?ĎŢ}sˇÁŢâ^ÔG›‹Ű|mó§Ŕ<ć)0Oy ĚS`žó§Ŕ<fKÜ/ž“< ˘çf°.Ř˝ŔÎ{ď‹A;[<ÝňôÍâZ×h'Áő®“śýżNbůG'ź(¶\CâúJ[~«żŢ`yöćg`$_žľ1ţ™äÚŹí·ÄŠ şą&Č5Lě_ĹlQߣT¦UhŔ}ć‡=‰¬'š˝ŃŢŠk:}‚śJř`;.ç,¬ä­áĂłD"‘'$xî ×ő§8đ9ĎĹdĎl_„rE˙ČDżą×ńťüÓµMµ˝´=rwŤ°'—e—')ëą‚ň–ře˘—Öěd#bsnk‚nŞô`î=˙[ťşĘ_Ź%O‘ák0óž|&M¸ÖKنďöşVžWm2oe4 đă2ńvĎî Ţîľ+Řgu“˙RhÝ.ť~ŻŘĚÜK6ţëľ+m¨®öuńĐ˝-•^ŹŹ˝ gWÄ®ŃâÎł>®Ź.{ŃĄ~Ů݇©¶6Ý’O®zóa ö˘#‘•đąT;-gx§2 ’ÜŹ˛uW6ĚćŮöŻë§Vi˝u·÷íüČľ˛Vą¸ř‚äĘţ„ďE™Uţr_Â~‹€8™mŔÖ–ż Ż´ŻůxO‡žśT>tŹuł_LŔ—t·â˝btlAŞqĘ%a$ž„i=l·\śa_Üô|ňšűw°;÷ae——ÓÖĶÂ>ö5c?¨+ĽźĄ{•F«Ý“ćÎżJlضŤ).|đ>Ú¸L¨¦ú.ÇŚcBßĎc|°:őĂDµĺĎň\č‚ţĚ< "—Őúm€/Ű[XůVí9sÍýŻ-ż(NÝL™Ó>ŞzĹ•Aâ;{ŹÖä—ö{.„đíFĚ€‚+ů­2ô Ň+xfx»5ě©kÝ4śMŃ{Rb›KްŇÎŃ…~˙˘)}K|M(÷ĂŐ¶nęyÚ‘Ş®3\-ŐóßT¶ÜÚććzÁ­ËCzš­ÔËő–žgúúڏ’OCN®Jßáă ą?gR·ąP¶9ń +­W&ĆÇľ]łç4\5ĹŮÖ2R._ĚępĎm´gÍJżŃď‡l×íĂĽ¦NŤ¶ŕÇkŇd¸ÚŤsĆÎôĽűÎŔůŻ;ް¤Ó‹ŰR®×•7ĚłžËž$2Ďó÷ęŰŕ˝ĘíÜßť¬´öř¸7 O«öşˇţ¨ăeı-żß™_-ĆÝÍUń˝i{qŻ®ĹNcS÷¬őm¦LhŰÚűŤöť Mâ®´7(›“VZ÷_âđ­ř¸7{žĎ“Fôw[d$ pÎ<|z˙‰ł ‡gđZRČxüŔĘë?ćŘ4ď}öGďLď>á+ËU[™‹|»h›Ë¸sÂŕÚ_ąíĎćztRĎ"wë LŰÂ9ý‚|3¬č˙CCą#op~ˇČ/ë}vć[˘+Č_Ó*GGb˙ýëȧĽUţ|Ţ4ň#Đĺɰ=)t¶ĺß’CŢťżÖůĆTß•5OOF‡ÁCX7΋“°ő]•ä\#[>r~6âbM‚Ďč8¬8 öů‘DöÇĆ~+p"¦IüéĹ÷ň::ůiëk°ýÍŹ ů1`¬-'#Č ľQ4–âÎăŐ¸D:ýTż_˛=ĆpcN7.Ář?ľÎ¶ÚŕW?ńxoçç Ođů±*=Śúo{|źůú‘8ŤŹ˝UĘA74ĐcÚâ˘âĚ÷źb\,Łď˝4ÉńŽń̬ý]IŃ×`“ą>5Źí2¦x7nüžÚŕ}°|§oů%dńKүDZzŻě€%b{\ ?+9÷Z*»a¬=ţFÄqŞ×]:_e–'tsŽDżŽŤ„ăEN¬¦Ćmű)m +­/ŻÉ4óÖăéŢG"‹‹Sđ)şö_/Ä<ó1BoÓ1Ůň‘ťĹ#“dCűٱrűÂĘ髎W]>őyŹFĽý+Áx>2™߲mµmsć[¬Á%»ÄkĆIz őGŔWń2:Ú˝›ľĽä\‘şŐ;VüúQ‰[†>*z gJ¶Ă–¬cî|{řţÉąÂ?ď©ľŁ…¶¬ĂěIe~ĂPgNꇆéÍĽÁ|•w»ţmůNÉ5ç"F®µć_[ĹźĆáCŐŽ—Î!Ϣ«źš-#ä3Î55Ć%ç§ÉZ˘ŐËô‹gâHš¨O“â¨cŮ®ă.éҵţZsBŹÂ&˝,ľmÖÉ·•ý· NâŁ\ůő«^Xą¶ě·'Ů/­ q2<,Žś‹/Ża,ň›-żÍCż©]ol؆ßŘv.ŇX«%Ű’é•+ňŐ­k¶"×|źU9wŤýŤ1\łĺé§Ł“}đŻ‹q̸­oŕL]ř¤nyMź„éĽč´·wWuŽĘ:aĂŽuÔŹH[[Ţ5 ܵť?<đV±ßTxÂmoŇpw}(ß1ś!ŰZĂ!ŕŃ/ŔëJrOŮtç™ "× ŤÜţÁkúÖô ·ĎľÇúšéÖ—+ŘY¦.¶­<2eőá"ÎŰÖ% ád^Ę*űiB|™r~ݹ˟$†/ßëĽÎÖK- płµoí\‹ř‡đ–µ”ľ‚Χ:ăĚöńtsĐw×mĂ®mäö={g)q&śĚCş“Ä‹×ĘCýć5ănđ9S–±?7FŻŐë¦Jb^_ă}cŕŐŮřt~Sźc[÷«SKÄWĚÚ!Ě+ú?!˛· ňÇeŤsG“q–Ą\—FŇń#Yőógć©—!ľ·öëSĘ ÷Ă7‚ď7•ůo[xíŘ»Áĺ˲߀Żö×|˛8Sä۶6uŤ6čÄŹ¸/ĘďůGľSÖ 'ńä;“ •Ł@®™'Ŕťţkź•9ń™ô2z(,;†ŐLąVĄĎ߀ýĂBżjËa~W¸uó=É­-—K m7!Ä‘ S{Ćr-ĄKâ_Ŕ·¤ŃÂRć#.Ä‘¸óĎhJąČŢ,p¤2ŻśöÝÁ˛ąÂ§°>ˇq6gÂiGž/ÍŞ<Çá+ ůÉý-*Ý-φ«×‰­ůŘŘ•‚?ń®—oöĎ€gZž¸’ĚoFĘşŤŃ,kcÎZ•9 ㇱ óóŹóä[†ň)y‚Îg Č]HW§ÔżFă ›ĚMŻ0Â×OćÄ%ŔOË>“G·4źąô!oYVú=t<óľđ˙ĆW/bC몠A‚szž íÖ;›k/÷>ôă[Cs?ĚCş‚}“JćkF/Ä1®ő1Ć©a·=ݧe3îs…ŠľÔţÔj˛×®ĽT9$ꉻńŤřź™ô*ź“nĚCŮ~řˇ÷„ÖąyĎVŃ|śS™Ne™˘ć\µĺ_,ňÂF¦Wžői‘9|çË:ťč Ľ·‰7ÎĽ[ â@Z÷T¦+4Ob>ö ŁqŰP8±,öM¬+ż©›˛BśIŹń1|‚ö•řFąÂ«—y±ŕĎzłĺçO[§1Xv5ĹÚ |–_âŹŃOÄyϬkiVĎgb»„]ýč˝Ă<ä7a†ÝĎŁJk¬ ú±Ö?΀ľ˝)ą¨ô¬9<×ęĎ—¬—tť|ö¤Ő6ˇÚ÷ŕ?ŘQüÓő¨ă*‘łüĆńf{Íú!ΡżŹ±˛˙úŽŐ©rG¶¬1 R™•ň Ć>Iľ4®Fqŕç\ËžŞkđÍᯮüČw±Ćw |“Z®yőýń…•ĹËŁ±¸ŤŽ,?>¶9µf_?áxßĹňĂç<ɧgłpÎÎ]˛Ąç›KŕŁîă~l^Ďőf<“Eř,c&ů¬Ĺń9řuňĎßÎH•1w¸¨ ń±Oó9¬ßĹă ·¶Đ‡śľÍGy "ŚW©ăů\i}abŞďăXď[Ô |nЬ¬‰=ÚĆ:šůËD•6L†—fß 8>ěó/•y_M×i«”k^e˘űĂnq7uďÇÇT˙V^˙ Ä^ű¶Ç3SLWóý_jkzŻÎ”řÔ|Ş?¬« ®TgÓůjő7J©o¨+]}ą&vwçyŃ Ö0K˛Ďh<ÂţyrËÍĘ\ĹdśuƊ濬rĎgä'idshŇőĽč‡·Sýňkż"ßýŢŃÉ5±Öš»ľÍ6ÜbwJ{†3q0ľ1_*Łë—ěÓ†łÁĎ{ĎÜ:-ÇÖüV_žů|tňŁŘÇx_űŽţ\ŔĘ’>l'űUťŰóf§‡=čŐ1±_3X™şăîßZN Áíć#ś‘[˙Ž53ŤWD徯ż¦q|˘}×ĹđÍ#ăŁöÝďo6ŽŤę#Ü:÷Qý⩲>ýąĺ!mhĆz)-’y˝ŰVĘ6ëëćł@Ż7‚´YĎnł-޵ö­Ľ-Xëß±ŚNj\Ćuĺ» ·[żúďÎünfzŐ×Ĺ{úš»}«YX6®gç`#|ů‘·IlţŃÉČ'bŕů}”cY#ś¶őĚľ[Ă׼§đI_§mĆţ:3ŚŚcđlÁ•ĐŔ¶1–~Ý­\‹sp<ÄÂťÜá:ŮŻlţŰX'6_«iaĺší9Žë×Űă{$ňÄj´:ŻŔż^š]ß ćňôú¨ Fčvw/Ď‹D6ŤăÓŃęžëçXŐćßÓatyŽ1 ű7‡bú×đőľçfč;öÓŦÓô°[fúu$ňµˇ›şV"úÂĘ~ţĽ®q ×˙TÇ–uŰ8W÷ľpŚJež‘ě»QĆůEĄ/"O§đŞľOŰśĚĆ3]§á~ŔeŚY´ŰqnË˙AÎ7ŕ:•Ť[äŐĄĺ;ý5B—OšG)–NżRpDŚ8_ľ×Äľ1mżűő ¬-Ëü’qłXÇ+Ă=L˙ÝwÇo_ö3Ž[¬-˙´†cń朌z Vü¬Ď§ń±_Ęůą.ŤL7ĄÓÇJ>‹áÎ<Ócźď>|JäÓ1Éů]&—„FżETö'űnĂZĎ“;‰v'‚éćâk×fK€™Ţââ柇b/ďmIÚ‡N Ĺwë÷EcŞ&pţ”Ž·:żÖ\ë/xö'áŇŮň©oßđtçZśű¸um(ÜŽs€ľýLµ? ×´çî~řsĐI§řs ÄŕőůAއEĄ—!žóÝ]éý>Ř­Ľ+dĎľč°ëÄĆŠ¶ě8Wç§ţ:Žď(¬íţcÎľŤ›A-Č"ż';ŠÇÄŁ•ĂÎ{­ÄU3]—ĘĽKÖ­`&}Ăm“şaô”ŻÂžń÷XÇţčuŇ´‘űĄÄ•k=\ĺzI¬ŘŘ•yřÇu_řţďöőú]áĆyŃĹrÎ×·ĆÇ›®OĂNTlĘumPý´`ç‰÷°m—5S[÷ä>÷®Ŕ±;Ęl;k\'ĆiŁĚuP®eo/w~ÍŐ…âššż”>ë÷ţ-k¤ŤíŐoI=Śď—Ć­eO^ß1 q 3ůB8xtŤ—kę˙JČÚ.Ď ~\ öŐ—¶~?G÷9‚2{ęjCáQŇwé{b{,Äű—ÓÎî!‰ĺŔÖpÇÇtŻmkËf‘ •ĺ`ë†Ć{Ę mYq^N¨Oě ÜU?Ćç[®°±v­ö#ěĂä!i˘ĽŁýâshë'ţÄ‹uüůŕs|‚óUřŢĺ?ĺaaEmÉ÷®Ö¦+s´?ŕ}Ŕ›HÄ`¶sćXŽůŹ[l&Ió/äsâŕ­×ZG$2\%MöĚ:9´îLűó2‰w®™ĺ3âfôá~N"·RÎK ď ĹŹň˝ş#k‰eąÇSmYčăěĆťźk*¬+gçbÍö<űz<—f]ąß;ă¶µ>ŽäeSi ~6~ô1–˝9íŰŠ/÷úč«H9÷9ëŕ=ë#MŘO¶ô¨]÷\ă[_*3śŕިđýŃxĚűâŔŰĹÎ]ÇdĘĺŹDßE+›@§+ŕ;zBB÷±´Ö“3ëń^q'˝Ć~ű'ńw°g–RGďŰ^ »­N©ł®fŢß4rYÇÚężťtúކľťA›şgL=eřMÝS„ďűUŘ»¸JöŞĎH.{9¦LţY‡í÷ľ©ŚúŹh2¦g˘ó÷Ă‚6›{•-˙ţ­űúňkó*‰©ŤC«ŇÚ™-şţ®ÇŢÝŰßď÷Ż]¦l“>°ąéR?ŰoŁ+ÎĘ_ä…W±Ř×ăÍĆ»ßűr­˙ĽCÚ¨´źęÓJ…‹ă(u«âŘbl–r׎ń÷ä\Y†˛íÖĹ÷.- _M%V¨č•łcĎk:ް­|M6?|•ţŔ.$$Ű c$Â3\L_öEĄ7K‹Jë¤?Oöý¶ciöpăő\îLô|Ż^fLŻ…ńUť±gę˛nţJ˝ç"Č©ľnŐ§»ţż8p’왓8BÉovăh#,wC7ń…ŤčúM!@¦Ű>Ąq§|ř`(Ľ‡˙żř7Ě„§Ű}hY!ü„ö‹JÇÁî˝[Ú“†fůŹvkn{spöużöľ8płŘ9“>8ŻNčôĺH¤ÜsÄ4ŮF,˙b Š<°>ÚaÍ„?}ä§úRRĄő±#ť%šÓŠÓÇ<4ÜĄ&×ě—«ŇĎIÂßBxIŘ'†ŽLNőmŚTy˝Ä’˛R™×Ăßö1"ăé">D6?gáţČT¶ĽÂç+Ö¤]ř˝¸¸>>\=©F7keÇSŘ'ÂN'-u-ÍŞ-üTßi3ÚfŞm3ăX~ßLE)G©‡ÓéŠđ$}EÇd߆:Ľ/:sW“u·,çâ®P8ۀϷ¶ĽAęĆ˝Ňf¬¨1 vÓpNĄs$ş?Dř?črM“«» –~ď"9‡ťđ/Íľ ëŹ*\{p÷ľ ÜĆ[ĘŚé3ęÎcó‡&g:—Źet.Ô7›+öE›˙°ś1čř:t/÷LÉüs­ZśŢ໮Őôm|.âe}ě8ŚőÂç»{{BüŕĘňY:˝_M7Ďő-}6lµ¬őaŇ|dňůž©˝tşŐ×›_9Eě™—˛’ą¶›źď¬´ţµúńhţr܆‰ž eđFü"‘Í}©$Îą®éřzśÝ’<łň nę>ÝŇŁsťpŽť˝«ooú}Ły`¶|!üŕKţ¸d­®‰Ńw¨6qďĂąś÷ř:‡}Ăۆ«7'ŽE¬@Ł}@o­©ß[ŕE+ðC{Ş÷‡Ö·CŽľ+má{4ô}oíîHj}Šă-|ŰD~·ôQ[Ë ă݉yŠö}Nř•oá–ř]+üK`[ą1ąńYÜV‡ĄÇ~[ó÷uŰăŘĽ@ⵄŰú}s Ó˙–qëޱkť?çGŢ#rKűZŐĎnűŤŻM)Ý´5ÂÇżM#XËľTÖIŹt`ĘţË4ŕgăşí˝úÚiÝX_žĺY¬»ţ[?yxÁ6ő·˘˙}>?`Ů@wđ±“Oo3u/ńbĽ(¦cccńśoOüUn5vŹńÖý†4üĄŚa@čpÖ›đdMěă˝hZ_Şˇ°ÝdÓČeŔqpůPőĎóŻ„ç[Ą.ôĎcižő0oţ‘wÄ›˛nřYăÄ˙ŁxĎwĚÇq"<.Ď\?ŰcýY6[~:}¦ń}ŚĎkggRŇŰŤĺ.¬Ě$Ź„źĽ#΂7p$ž¬gb:ňűŚsň›uźëéÇ{ľ?˛’ĎtnŞPŤŹť–¸s€|šýŹ0!ŽÖsĆ˝CJźL~lŻ8p ü?żăó\ńQ޸<ćwó“źů‘?ŕđWăüző&ľä/ßł ó05Ľu<¤»Čď†Â/ałľĐé[ŚÇoţ¦łÇ—ńgX Ç“©#NđŰ=ľčp·ňđ‘·üsű$qâ=eeÚňODÜ«őđGąČŹ `2ÍĽšĎćŰę'+ľXp¶6IŁ Ű¦ÎPZYŽ]Oń]%úßŕж蓫ßÄ[[%ţ*źS~Ů>ŰvyE|‰ e„|%4•Vť70żĘ¨ÉŞáޱp);,G?˛5±B¦N©É΄‡lŢÔglsb¨%D›]ĹÜŕ'-»0íşÜow|쉽h:xâhĺxO>Ţą­›?O¸ţĂĽ;ń'řg4b˙"îlŞoŤ”ç·”Î_LĎŃ?ďËđ•ÖłkwW–[ô›‚ŰÄśGÚĂ^qHW¦âŔm˛÷ŔkŇźřňĎŇô€Źhbq1)qW7@Ď’V®\3?˙Ś·|϶'†ţWř+~Hä±=%U^«żx©÷”¦đxSnÍńŤ°ţvŠŕ\m ü-ŰUt0óR×f—gä#ďM¶ű˝k…~Fň•ý‡÷ŚÁm}…Ľ5ě›{VbÔ;&˙ř‚HDhO^łÍL”{!ÍůeË1Ś-í~}XŹî\}[Ěc"¬äż ď­y‰żEŢÔç”óýë^9>ąoţPůVVŠ] q$Ě2†Ł>^ÝX/ë"˙I;““ĂŠ×x‰ś][ŁX–}´c30ÇZż;GO91ŽŘ˛†ˇ3aáń"|ŃĘý"8ó]ěKČGíł bLĂKăĽęťß¨ţăYŘž”3šń9ýŹ ŹTfiâ˘"ěUerlH·XžąH•ţ)ßż¨«dśeź´5¶ą¶zŁăż‰T[nŚoxĆ…Ř[ë8Óé˙‘Tńˇţe< ]ă!íxO=ŔzŤż|Bú3ĺŻŇşýě¶Î ]WÓ§Íű?>ö˙;uj˙uaE×\)Łä©ůNb= ˛¦ă,ˇŘÚňÄ2ů*ü˙ľxĎňĺ°íx]oŇ} …—8łßîs±ť|¤ĐĘâ»ďćâńň}»őFöAęfâÍwĘsĺď?QxyÂŢńľŢß“ňϧ1Çłł]t\'ź) đ«:-*}LJ1i|>°ÎąţÁ§ĎC,ź_Ëüx;6O ˝÷'őÇ˝jöůTć±Iú÷’>´^Ř]8OúżÍ1€ĘXş˙Ⱦݖ˙|KŻÇSń,uĽÄ0ľĽY;s™Şěi g FăžëťÁ;˙Čk8ë3ĘÂpµqiź#qŐ›ÚÂiIŇÄđ%Mř4˝Ł6F>ß×ŐéôQ Ä’Íźá?Óš˙±…|=Iś)skb-ŔáRy^ę˝Úáńä/ ÁőíLV[ľ’ŘđŚSëb‰kN7Ż^36Q cĹM‚e´ŘÚrÎ&ř(ćšjkiĄç"ŤV~,Ľ¬´^áű´ł®‰é9.ě{.ÜĂěž°¦Ó÷ű}Aus@Ź\áŻuô‚ť¤3FéÍu!ň‘}răŘšXÓᚎËúÉ_ śĆ ŽąĆ»)ďćáZ6áČ–ŻóĺĆęmfš‰ţ;nc¦ŰţŽ\Sţ©««-WƱž˙Ř1Ä™ăůVúÓ3¦Óiűu[ s›şs‡íĂD<¨{ď{0ň¦űđ ĽŮ>Δ ÎE™ę7ŮÜâÔ~o|Uúq˛Gľ=ś âÉ ?q¦¤¤kbĹwŻű:3Ř\ ‚–‹cčż=µńŹsócç¬/[«›Ź¸LôŹęS…‰4_–ý“×ď=qšŢ%_SśńFX‡k«~˙ÍC˛·«ă°ág)÷{QF箏HyçÎb^ňě9Ç×ÚcŞs÷ ÷S^ăµ?}ogăŘŞdkţ śşçĆ|űK/şÁVóď7ăďwŘwęŞŰŇş5žéŔţQ‘>uěNÄŰźłń)Ś•Ţ-ÍţŽ0ă{jÜ{÷,Ě ârÎż!? ž×Ë»}#®‰-Óé‹ř-(0cíCđoË1„s_ęÄÄ–žĺ×B¬ď¶ĺßéωÁ¶;žR:<1\ý3â'ýKěRmľX?nSoSη޸Â_'žę»Wŕ®>rZĽ=~‹ŕ[ëę˙şďMr]“s‰ˇ+3óó»U¦]:ôě–°ŻĚç°Ś_ĺy¨ŢÚęěÁŐóś}bM¬Ś=şĎv¶ýµÍŃß=ëâú›Ń/•ů™Đf|쵡>Í|{îwä’Tćjźö´!#,úťo:ISĺ?uŮSUřkr«6ŕö©ŘŔfc/Âs:…cĹőéôSâ÷ő0^­Ůńa-ăÚß ÜÄ×ćĎĄŢ;»`;ăą{őEZý1Žs­¤źśąrŹ÷ÝéXnűÉúIµ«ż~ě´®­-ÝÂű…•kˇŁN,Ý–˙Ş<ßŇłsłŻ¬ 6*×v«^Ţ6&;óö:_ŢYŞÚr1ĆÔÇřřÂV@đ*< ů–|76‚m¸ş6q2âuŔ¶vŻ^#h;ö'Żk Cˇu_â _·ÚşW¸äTß/=î qÍŚÜ+}÷î›ÁWŰ—äzť®wŞ­€­Źp­„kFXÇ}Ĺ’./7U·bkI‘÷K¸Ç¦ĐŢqwúm§ Olý«Ń=ź‘©Ěo’\ÓÔ}ŘHä.ě/’F®ň=m†míÔüĹ÷l#‘‘ɵŇ_ąŽ7>ö&ŕ®v>´…°5Oâ:1¤g|Ń~.?ň1YÍ®Ă'W źK˝Ôöctýž}AmO”ď´ËXűË—wŘ7]qc?4ąž«|39U»GÝwU[JĘüľĺ •rQóăě®në#|főa-Ýß§ÚłwáU>†áTý¦gË’˙®.Đ=ŤFřu`˙c·ë2ÂlúČ ążçE |üvâ˝ĺZśr”řďVđ|1±•˘'ž´Ůviµ­kŇImäFęĆv¦ůi&z-Î_‰†tѶ`¤LO ý#ą¸řľ®[†đîřΆ|Gmţ“›|ű8ÖăňÝ­÷ĆőŸsŕSđ9}Xđ]WšSĽ˝ÜĎD¦t® öśŰŇ·oĄővž]ßÚŇ.ĺÇkűQäůeó5ËĎúëő‚ĘĽňĎt Úó4ź§Văé©_{„e|ěĄ>gî{Óű#u@[ţŤ‰k ‡řÂ3’ WKIţŮ=SŢłö·]řĄůđ¬ÍHáÓ ˙Ë_8căBµÂG*ZÓ%Óq4ů$ťÖV7K>Ě5Ŕďŕ\Ł‹–lk—˝,ĺ•úéŽ|fĎíٶŇ-=_©ÁŃ lµřY`l üžx­ö\‘Ć´7gĘĽępÚm·Ŕáňüť=ś‹Ů‰łE—îĹo Í/NNŻ«ľ~Ҳot®ľ>g„ęš-öśűÖ·KYkoŁÄäÎŕ±¶ű˝żËś±ó°GýOsô8ĎÁSăŃV'a ¬“Ĺ䒦ʸę¬íÓźř˛}Âm°×ŹĎ±âc;Ž(ľÄŹIrü ¶ôĽĄ'Aýëé[˙H±Iˇ.łvŘ׍ÍLí<Ózě>WřŻ-L0·¤-EŇ;ÓËů¸wź×„qKĎÂäPő‚P?Q|ř6LoŇŐýa‹ŐÁëŮüŕŇqŰĐ9ů_Ł«1®ŢžT»Ç0 „ikË kö@Á;sęË[~ä†x"÷ďĐü- ۇ«_AĚ*[и:éY…„ß»o˙§ÔăÍ{Îß˝őŹďľżç`Ěq!zlŞďŠP;ż—»{ţ_óőÂčäÁ?ÎKvj~+ú§¤Í "ćP௙‰ŔűçÂçge.jÍ–GŹĂáí+ú‹1aŁřŕŮ\öLŻÜ­ő(Ä×nZŹ7l}»«Ué«1Ď{źŔ°3xşy_%ă¨ú»ëÜÁËť•śěۧξ^ńnÇwVP^ź±ÇŠ÷%ěMřă,ÁÜäĹĎ{Ö±Ě[mů‰ŘR›žśŽs j0.çúINpµZúÖă>>Ö’lË?Yx˛®||™.w`±ňŰOžµ°fߥym>Pß^pŻůč›Ę+âK^Q˙-ÍľÉ˙,]ŇíÇb)ő%ţ°+~!ćgrÂřźôI+÷<$sˇ ť™qg[±˘Ę›Bł+˙Yżţ˘•®™Ű#M`»™ěÉ*Ľ®Ň]Ł“)Áąßű™Č6ěŰbĹÓE‡E+ßÁúžŮH|I+,? ®Éi°÷»ĽaÜ82ĆÇ,ę5ŢłŹWZŻ™•Ś[ýŰKŮ.1´~H»/›ó9ÎźcüÄÚyVZŹ élľçŹßXşţˇWc˝ÍďŮ(Î~?11uO8vŻ—ű*l‹ĎôeJkÝń˙ć÷Ě8şąÂds$ô“żxć µ=pžÄőJwÜ´řrCż‚ŹÔDçÉ™•ţÜ›¸’O:žňTO °O ý5[ľYĘçG®á‰t»Ôź7E–·¶ü{ „ŤzÚ[W>^Îë®˙ći„?ÇOţéšÇ磦É[*łsö%=©Ç|”ëé8řłúýNő] rp^ôłţ:ęń66J_(őçÓrÇąL˙ÚCCń×}©¬ď4ÂÓ}FçËQÎa«.Ľ@rŕ~k› ŻŮ¶‡ŻŐOÚ.w÷ţ:±~ň™B~ď±RŹť1myv4ťzB2l‹ů©Ěş~ĎöůÝ żëýońš´˘ś#–Ć !™7PžůG|);ÔC3áM<ݵć%.Ő–o‹ü<2Whç~Ű9ąfľŁ¸Öç{#Ösř¬ŇĘőúH$÷oý¦dßă}đ3˙×@ů]E\řÇüÄą8@;VÚÜwuĹŠQYO"íHâUżžF9áł…•;Ľá*ő˙ť€CŰ Ţ•ÖđË; ç^"őđěÚբғĄ_,Í–»0w¬Ő©óĂlůšÄ-˙¨Á˙ ń«ü`u/<#Ä™°×CQi=OřBŢgć·?Ë匧đ#“>áĺž]7nň{ţőřN}ϬńŢŚó{W§„®>Äß;Úżň,™?xą;„můu~lfÂGmś%Ü䟑ϔáüČ­W¤qŰňò~K>»<&ŤX–ő‘Ž|gx“nřţôéo´ás‹«ŔëŮü¸Źdňfă­—ű…Ż ^“_ÂGś5ć“Ę ď‰7ĎU(Ë9጗sĎťĂ2öMHxÍ2ÄxsžÁ”°ŤÍ>"ü6Ú°ĎP÷ăůl0¶ŘÇ7€zᓏ~s8ĆéĎ!&u`“Ěq¸“ä'Ű&ť8¶čëÇ<6^ăŚQ‰Mb4ł|¤ Ë«Ö'řž¸YĚ€¶ü-ě»;ĆĆJ5ÝŻg ĚËpé~O×tWô_Äřńťđ Ăúĺ»»†«mw>®÷a|ŃńÄ™Ľ ľäťőQÇϬötúo]ÄźeLެ0%ź©ÓůžőçVń™üďp•=[OăYŕ}łîÓl§«ăű^䤼ĄŮ_uf_÷_˘Ç1VO0Ű&ľä3á3=l˛NĽ‰ßě{” 3ůI|™˛®»QëĄ˙qg9®­3®vËx·3ŮĎć3ţ2Q‹×˘÷łůĎx •ÖCOŘÔűý™0ę^ă źßúéČ}Yb’Xßă3ŇyXďůÇú'ë"mřŽňŔ6Ε輬Ü㯰˝Ő©˙»f6¸˛lĄu ĆŞĚŢŔâŇĐęĽčdĎŤľAěׄ•ßţ„•0Vă%÷›]Xß·vŻ:šů Oć#݉#Ó—ĄJâŰ;›Ţ¦C_/4S8őŠ~•=·Ťf\ŻľílĐö’N|$µĂF ë&ĐżŁµ˝Ć`íť}5ý…˙=¬}Z!ř[K1YţеĄç°řĎqĆłő÷ďeNorC|5ÖŃ»eŚd ‡”~×őµ.úP®ěI.É˙Tľ_7Ť4űěäÁ# ßťĄ„ł¶ĂzÂxJ=Mľ`oÚ—}Ç{r„÷Ł“}w÷:ďů”?íď+ú÷—xd|BĽůśr?Ů÷lŘZť*‡y¬Č÷™˙Öă}ÝĆűŮţ2Ń:ďQč­ŰX[+?^‚wýNbUp?űşX=ťĹv%Č5ű«tzqG&ú+ďw­˙ŃŰj·~KÝEŘ©sŘźůßşB§EĄç;±ťyöŤÎ/‡z]éĆ;ţÔeiö§Ý©ĚőB«\ác×z3ľm»Ęžćmţě9‰ü°!öDóz´ýxiw=ÎXű©¬m_“gâkţ»W‹ůĚÝAl!Ő[xď뵥 ˝ĚĂěšujĽ–0^›F.Żż’›pŽćÜq^ű,öś¦µ…~ĺÇ&&Ľ:E"S}âăc7 >FK—_ůx«\ßfJĂHdÓÖ'KÄSB¬ŤŃ„Xž ®·#ľmCąkĆZËčä—Üă!Ţf—®u××ŔŚXWµ13xvß˝gř˛@ÜÇťq÷°Ź7ť`4aÍďŽ.ś•—ôrÚŻCCžQ®8ŕăM—]Lŕߌߍ‚źoĘońg¤’§Ĺgűc– spŕÝř™µäS݉śé©˙ĽÝ#ÎŹ|‡F"oăÄśó™a-ëĎjËyKŘśą1.†•¦îó»f_Ŕ÷|˘íř‰i}+\wsîpţFç—ř4Ą\Q×nOŇs,BŇ–˙ťŔ» ßŇ®ÎŰŃzOÇćŕµýZvŚŤŕ˙ÚĐ­WW!vbëB_q€t ĽŢ‡q­Q™đł:ŐŹˇřqÁŰć]!žěŁżV+őO®™iBܶ¶Ü*úë/{^‰µŢźaúßř~9iƵDÖo±6ű˝ü†uŤ†ëĂŐ3|ťo0ížTńlł‚đşňo°G+G ź ßTß•ř>-;±§ÓŤ}`b$Wť˘Ś¸{đÓVF&'|Íy ź"޲ŘŰ»|d‚x˝#Ż"‘ő“%é×Ő–ŰüykP–9wűî&˝2Ń•ń‰8ćo»_BC=M=’-ż}ôEľ|qÎ鎱¶¦Ă2öŰÚ˘ă­ÝkđöěŘe~žźČú°´sËĐ9]oôrMź_‡á™~—Ę|QĆčʵ‡"Žă?E—g˘ßŢ×Ű|1žŐ`q·Ď:łÍŐÉ[ĘFĄµňţ^DZ…ˇjWŁůźŐ˝»R¬Ý"î|_üěŘ+f´÷¤lćkţ4+~}?ź!ڰ zą˛ˇ2Í=Š+a#Ů%ńX:ń˝óDߣ·sq1°KŮ]xşíd_w­ô«R全żĺňËúŁĄÔŰŘ'Ŕůě[úođăŐSŹßŃÔö]‰ł9ămůżůeö$Ž3µŤ9‡ÄŰ%î¶`yŁ•ŕÜ!śýíŮ~q¤ţçz6ż[r…·H§_{ŁBĂ=z«soHa ÚąWcµĺź&ňéĺN¬Éé5]ű~Ł}Ĺu[a3t,â'ýQdß§„ťv{łá÷­?’ľ»˘lÚxš‰~çŇőb/ćcş˙9›¶ţÓĘNő˝tMţÓp‡wžó§Ŕ<ć)0Oy ĚS`žó[ đ<"¶ŕ~CßŐ{Żż6VßúٱτÖEęßď­÷ĂŐ7yŮňe ض_]'áz÷Ôlďvđ[ÚčŻ{P9Ń߇çú‘ĺŰ[q¬‡‹ëÄŐ]Çßű̵c`ëC\×t׺#×TÔ†&8ĂqëśőőďM÷=Ů/Ôä2X#î\ď)őĆ»UľŐ†@ů~•Čx¶|Ďc[Cł=‚ýŹ{7ŢC6öšőśÁ•ŘÚň±EĚařRŃf^ńć×čd·ŘŔńůČ?®Ő›że™ĽŁ Śđ™ŮË3/ëŮ›ř;:ůŹ„+Ç·ám)qÚ42 »¶Ăd}Đp€?”ŘIó˝Ęţ Î3űŘ-.ţ ˛Łű®?čS!+·§Ň­÷ĽĘŃÁa˙hĂŐRÓKË3żÁú˙ÓüuýŃÉďËZŻňRĺClfĐÇŤL­üžÂŐÚµ>ŞűpşŻ}1čÓÄ…0Ęű2ú€ŕLű±ŤiÂz\śŤNÓSkyO¦oá#>¦{ ^ň‡ř'ęfŇÇtSăËZ™F)m á?,>s»cěŃLŰo5ëń%ėω/ń¦N˛9 qf“a«g{©ćß˝cŻßÇŰúĎţuaĄ^;¤Ô+cŤę8…‘đŢÝKŰ7Ť/ĺ–ŮŃkŇ)[>Ć× s‰}©·Í#­/Ď'ykýÔú2ÎJđç–±bĆŹ“G©÷9iG{řTć]ľîtĎ l6î«ŇĎčZťúˇ—NŻ“ö¶§sű*Sżč'ú ĚK˙ŠŘS˙Ť3%:’?«ť©ßQÔč˝™ŻĺÜ*ˇÇpҵß+řtl6Î¬Ź¶Yv¦Q˙çź›TŔé°ŇO¦ľŹj_W¨¶ôLŕ,ĚÇú°ĎŚcP7eeb¨MčmăD[ţ/s&ß˲WÉžÓPµEě†Ě1YĽÇ‰ŻFlš»ĺ;ôˇĚ˛ďQ&řGXéŻEĚqţŞŚQÄ—r`ű“ŰÂßä†ylOoMěW›ŕěCĄęěţoé |Š*­ Ľ&×Ä!•ů:hŕĚÖl,"ÎÔÓÄ›)ň%ž•™î#˛ roÍŽŃ­gŰsśüČ„ÇŢkzô1ÎDUnf‡­–î÷>»üçű:OgâɲěűÄśIné©ĆÉ?ĂŰĆáý/ö÷âF'[D' I;ŐńĘ{ ×|}Ă´`>ę2/÷Dśwř7Ťú˛Ú˛Ö×±łĹýŔłţ ßcRwµĺčnĺăt8ŰQäŔl­ ű!ń0Ţ?Řň¸®Ř±×·cî-q p~a׊ţ[üXZě÷,C)żíŕaXŽ‚vk˛#gľÍG·|[ţ>íŘź˝Üoj<Ú&L”ß\á‰eŮĽç;ęؤ¬ń6ëʧ"ÎĐeKF'żíŰ°Ź¨ŽSyf,|_KLH…%ÜÖth.ś/äĂŞOvţqŕ1RǢŇxâčüW»ľ6tlŃxîm$˘ĽpaŃúłĺ#Ĺn`íMŹ/ŘËđĽâÄŇěbČĘ ý5Äh86ZąÖÇ›x¨>ćvubăŘÂî/Ž 6¤ďtśőŰËľKwÓé%8î°ĎQÖh}9ěŐďŞÓ[Ć×ë`ٷ܇“ăÚq°qZŃŻgłf|;¶1Ý42yܢŇ+»ŽÍ_^Ó_|Ş?–cŔů(Ţd_ hěŇvúµőŐ VËΧg¤ÉÉL}Řŕ‰VîëF 8Xň‹ýĽ8đ“iuY¦ŔË— QIý§ú>’)úPÂ&VňăYśýőŚZÝg$Ď‹®ďně+á¶¶ík›3’Çî7y7˝?“”Ů»aëčPŮ_Ă ÎmŇs»Ý–n:çtúqÂëŐ©GËŘĹ~Ăv CĎMn[\J”z_Ý­}< ŻÍEVĄß[ŁS$râ^¸őĎîZŰbßâ8ËXZŤĺPóŃî–´ ć\Ť8 ®0üäëㇼ® öţ2VÁF¬łÔż»3pßÚzˇđ5Ů…Ź?Ć»řĄÓĂhë»đ{zDĂ÷nŢF×?ëÝěŃO›ďІŔ´®|!Îśţüťď™q®`0wŐŤjçYŹ–ľmoIK›ĂXŤŇâŔ÷ü~R:ř}@ôÎdßí2^śŰßçżŐ˝łi©÷˛š.»0řđIŘh×üŤëéľ'Δ ŽăˇĎżčëÄ­-źëĚD`~wlőőíťű@Îf>dËL|żď—>č_G}çÖ»­kË ďBśIŤďťZÜúŠ&v©Ăţ‘żŔÜťgY‡yh÷„1?rtr3âá×ó‡tŕ¸NÂçÂH8'űôś÷‰gżHbW>őßźÖŽŤ»ú=†Ĺtš~ăb rĹúwĺ7Ő÷mÄš>׏+ÁůŁÖŻmRYo~äá•ɦÁI˝GĽI–µ1€eÖO~Ü×1”}L^XÖęajz!?˛a›>l0rźíěꯄµŚń±Ď8uťĂ5’; 7yn)iCX·é|śA(tš–ŕŔw¤Ť•á5yÎrÄ—÷[n~|ű|ťS}ĎL°ż(]‚8‘˲ONF+ű‰L?¶ôź¦a(wěţr~ź3Ú›ś2®çŚőDxŤźÄ_ĺQ׼ 3yY?ćą ¬‹ĺřg˛m)ß™ü ŁßGű˝óĹoĎęł¶WăŻîn3ĺâľÎŕí&NÄŮúó'sĎŔůĽß“ł¬ůž¸‘ŻäĹd1'ĎÓšŘkbŹ:Â×@ćÚ|gĺ؆é҉´ŕ;âWčÄąÂ/‘˛§jcř˝őuJśýXi5&;ţś8Âe˛iĄŔ{rrŽiMŘ#ńĺµÉß/‰7ËÓg×ü#nĆ+–a{¤qŕ5iŔúĆÇöńÇfÖÁr|Wmą i1'†ľéČ%síüoE˙_0¶ľ#ńđĂË}Ůb-8ë9~RćďE÷§Ű%|ĆĹĹŰčÁ˛Çćż Ć`~Łó±ŻĆ¤q&=TÎ87_áă´Ą'ëë4ć#˘•ć­Ť±}âfmŻJ„¸_—ąźńŰe>ęÂN\¬o'ÉçŚ%ĚĂ?Ă—¸YâĚk¦|ÎzŇéý0':Whż˘_鶲ťĐ€m“ž1=‹•×»ú[?ŮÖ…řk8‹ű;Ű%N¬ ë—˛ŢE<(‡|nrĘ˝7^VÂÂ÷Ä‹}ŇË]-ă˝ú`™_]p~iŔy;éf±•řŚő^..y,4ęűŁŚ-‹‹_ź•ÎvëÖëÁĺđŻđÇ­LôŰŇĺ“đ&ÂJăő ůo|¬ŻoôműÂ7ëÔ§ăijřGűSŮ×Ň[z~źŇt†–ugŇÚôw}ýłąGżÚń;=ą°kőmű}ëÔ8ó÷´Z\αëm±b-Î[ Ďař¤Ňú#źĹŹ×ů‹ëÚßÉ™wůţZ†sk-v(ëH§7 «SBzŤďšőCüŮ.Ä ‘ő,ňŇbnm9 ~Ľ?—uK~‡qlŁ~çč51]żĹŮŐEpÂ×ä{úă‹JşOŔ§´!om|ĐÔúDqgFsĺ¬ýҧ9őë(őŮUęÝ×§ePďě® ×đצ˝CăiA)ׄ×ô—Éž—{ƶ‰öZßŇĹą|¶śA ť µoĘ»jq&eľĆňě+äq´ršô'Ä1ĹyŘíqÓmlŹ4"4Ł“çŕë7MŤCcX®‰»pÖľ=ţ&ňڵKħ9ś¸Č=ő–ámş- ÇžYšM$΋.ž&“üN N$­l/ĚpÂú)Úx˘´xµľÄ~r‡·ąď°x*37gGSż'Ň~ŹěŰŢ!Ąá«ú†ÎýËáÇúĽnŐë*§„ßh•y°3[ĆzŃJÁ•c˝ŰPdReBË“v¬c¸z1lětŚE.k]ämŞďňĺÎęźMŠ>]ă aŇü]ChQg[ľ±(/ńš°ňOyÎXłOî:9Łó˙~ďcŇÇ-ö¤}~/Íľ™1}C€łŤŤÖSöĘ7ĺiâ¨GÉZş›§×kbĺš<ť"ó\ň‰űĆcŻ´vcü>~€ĎGüĘ]3Ű®ţóµ'…p­ĎĂ|ô‘uĺDóđŤţŕűŚqŞčď čÚ•ĆŢ´<ÍLéwüäüˇť¦K)sAĚÉú–gňv«˘Â8ş4qŻ9§= |žµĺ˙Ű—keYvIm_‡ůt_ÜŢ53]šŐřp¦ŁuĺĚÚ)ő>fĽ đpqÚ™kÓoá2?ŞŃÔ h~Şşg×á/ő">˝® E+9ěź8+:5šŹ6ë(bćŞ.Ţ5ś)Đď蓟—>ąú¶1™Yż ó/ÜÇ śĎ–¬´jĚż vh31ś^|Żĺ#%…‡ăi®pE¨˙Ů»F)ÖÜĄof˘Ďę|YZăať÷»ŘÚödHç<8;çŻ,*˝_d:• ÖO¦CÜś'+úç Ä~ c"b3Úá\ĸ˘ß G&úÄŽ\!‡{Cg…ůľW» ęѥ٧$nů#ÖŽ75}ľŮRŁ“ŮÜró~_äX‰}Z_źŘ÷ŁÁ<1t“đ:oKĎĹŘxĽ?ćL }ó™łëđ%?o–2VSÎË87*őŞmK#řćęÇ!–­-ÇuďŃxŽśKk»˛ľŤoż$ż+1wŠŹN>$g đý!Ąĺ Â_OźÍ}«@K®í‡ţ›ÍQئÉ8óě®ß5…+ń ó]ů^$ 㟌řř°źN©ÍÍ&&áů“+ŇéĐŐ˘Ň?ž}1\=ˇkmRt€|ł‘6ÔѰ?Á™P÷aţÓÜł›v”v‰ÜéŢ­kÓnąČŕšĆk(őŢěăLľä źë>qË­Ţ\áĺĐ…?–{ŇĚ•—ŕZsomąMöÖacš8ąck űÔę¶ÚvošČ=Kŕ^ťzł˙ťC–f?™xP~µ?(ŚĂŐ?‹îÉŹĐîńKCë)<+głĐ1ý¬óńlć;ÓűPHVřlOü°V&¶0‰Üs.Ć—"“}‡ů:Îľ7îD<}|«t.)°ŁŻălž©„~űÂľń‘É/ĘÜŽú[bw]1·ďZ[-íř.÷—98並!x›®Ł]Fq`ßšf˙ľÖ˙ľ?6`Á7$×<6z•k\¦ĄŮv®ľm÷ÇÍrqÚ±ëÁN¬㬓 ŢfWbńŇX쇖TZ% A’ű]v®Î’í>ŕë€kwĎćJeşD×Ä>ÓUmY†oĚ lŹŻđĆŰ%x,ÍţSl¦V§ĆCňŠř{؇Źű2°g±}ë +áŘşčׂ7ĎC›}íó5ĚS`žó§Ŕ<ć)0Oy ĚS`ž˙×)€Ĺň-™-')ÖKŮrŢ[•Ţď?ęqGůÄ5Yîypí.(ŁkýŢK«Sw‡đćÚí2ÇÄ_WĘí˝W-6¶ţeW×HśĂźk"ĄŢse űžŮPđ,]Ôóô*­·Ă7p¸&#VŰŢ•>ôđ{ŹjKIÎ8ć0ÖŢÜk±}™/9|çى'gËťî~#÷:z˛ĺ8SŰoGŻ`oÂĽÂYJ‰ &¸ĘńââK «şĂu@ňy‡LôXŮŁăš‘ť›`˛Ŕ2\C+őŽ&ŻCÝ+ú»dťoÁŮöá 7KO{Ĺ—ýő‹#“8÷ćEV·ô|¶ KĹFkË?|Q–垇îmD"¤%é@9áţŘžĆ~˝µuí#kýPń3ś-% űúÉGú2zFęź5yçy6Źíć{Ëď¦Äź2Î÷±M~ů=»úyž­ęÂé^sźg}‰.źä"÷ú±vřžëëéú8ü¬g Őüš¬ÔžI'†.ŘI˙`ob:ʵo®>α‹~Ú›á÷věKމŚĐ™XčľŰLupʞ@ćOş»(@YĺźËĎĆ× ‘ŤŐÔI©Ě‡E>-ƺ>ę2Ę‚ë§hő’ľěăÔń´§Ý]¸Z;<7”>Ń#NÜ,ÍRęž A{>Ę7aĄÎ¦\¨ÎÓ3öR™ż‹Źß÷ÂóâŔ1ÉúýY«wÓH§ß žąN/!4" KÉ3/“ â=Ů—J..~AxͲ¤ńŁló~|¬ť6g3ś}`GńnëĺękĽiŢlI:˘gé™c_Şâư_}?ŚD~Ö«ţ˝„͵©úżžĄ˘÷ZžňËó á˙[ÓĎA˝¤ËČdź<Çů…µŘrÖţÜĄ«SŚKA8ęl:ć|.4Žo>ßŇsH÷lśËŘ)ď-& ő_—lÁĄGř÷/˙Ś}oÝźőrżť“}\áBľ°ěŻ8w†tŻŃÁđVzŔJä •9ß{Jî]“}G'őĚAÚB~ç ·ŕL“߉%ež´4[lřó×úě­¨ßęµsşě^Ű™ë˙mů‹’ĵ~<€KíO+­C"ĹŻy˝]wěľźĺ-~ŢÉDn±Wzď#C:űë‚›ęĹç9â¬ňŁC8[;´ĂÁ÷ě8tĽk6Ţăc—u Ž3/0olXyć`#›u?°ýëa›<>vO|™cO±:ĺÉ»\á»ő¶M Ňň˙”ڙˆ|§ÍuŕĂćëmł",ŮňšäŞôŹ›&ă[zţě%júß‹Ňq.bťLSć¬*ÔŁ“ŹŻNť?Ý3ßń±Ă`Gr•żĎş°ň‘ňŤúËpelĚÝâŘ“öÍUřŚ:çdĽÔnś3$mXłIcĹdÜPą»ţj÷ůúIÇ ë_Š3x <ôş8°Qp˘Ţ" «Sßč̞޾°rGŰpuß%+ú?áÄ'1;ŔHäĺ+Ř\H7¬É¶›*­šoϬcŤú1’'Ř7N”{Ş!>«ŠDąŽřőcżÍ—Oő]€<'!Ŕ€ŕ¦ý©ĂÁ}Ćyš{żˇ0ščůré\»˛ˇ}Ť6,—ů·6q&şč@Äv=nE˙wü~Í÷«Ň­I峍IVŠi@ďó˘Ww#nOź…8')˙ŠAĐ%Ie–Â6ÚľoůdçC'HݰŐě˘MŻŐ01ôVł\XôšţźGc|ěÝG¬řaIű˝źuar\:ý$éĂ™‹z;J˝7t®N]»ľŹ„âBpţű|iŰú«µ5ŮÇłv#‘»kqő¦ů40w%ťę;§v–ĎHÓ8Z‘Č5 ă;Q˙ŕQZg@ÂäΕÔ箾ĺĽ?NáÜoźĎ›űŽyôr§ >V 6€¸·Ń“}ťŕWę˝ ţ÷-8§7|2ć»,ŰÂ?Ž4¦ľ¶ďžkđpnRď٧¨óL§XYÄ•öńµ:0&uŢ9đ±ÎTćËŇ×'††đ}ŃźäÄ:L'¸íX}Vd]Ęj^}Š%$_&-ߎ¤^îÓä…>6<WÇ­0ý]¸/ĺ“4Łžg{™čë`•m˙Tah Îao˙}ëńđSę€Îř3éµcßĺÚ6iĂńÂć넡ž&;‚«ĺyyú(ˇ_ż·2Ô'q’ “áF9>¶şşv;ć巽ἠ2رű¸Í}GăÜ˝Ţv;ń9…˙¤#qé»ŮÚuSŇÔěíH«Éľ#’g¤ÎÇzJ\`7\v6Őď$ʼnđXźĺšâŁţ‘őüá=ËŞ®ZM§×Ă×ď6ÄÜş"‡IŚf]őúĘĹĎż¬­ů0Ů»¶ü—Ç.3M>Ö·}urFű ë#ýMfr…-kşÔ÷ÇgżÎ–­ź‡ůÍrüSůĐöŕżáósFż/_űľ2,…żľŕIˇr@ŰÉűüřě–Ź)Ç»Dî|_ďlËĆoMW±Ď| m’ĎŞź¶=ޞ}â@śY‡ŃŚ­0ĆŤŰí<Ť>,c2Čy›ß#|OZÔ3íśYŐ5Aţť˝˛o5›{ÂĆ”1uÖO^éŹ-ś{“”gÂMş°źńOĺV!8±U2Ń Ź)Óś«±^–!>VÖčmkůôźf ¬—ő=ĐzđÓú„ćßY,ĂůÇĆ4&q˝ž&_˛ĺ·I{—•{â„—p0µö ;ůÄg\ăĄ|?ň;˝;a|gÝüc9ć5ů`Jú‘¶Z'mą˙ĺ÷ ľ'´ŚÇÇ4čśÓ=ÎÉÇ·;ţ»qäĺ]±çí_‹ó­0°t~ä¬ĹßŐ ß Ńą\ł3X g “Ëé/F>“Ä›gŔGĎúź8űeĎóLł.ňšĎYŻŻŔűŐ© ťú?>ß8v%ÖËź/zKu*ßĚţg<±š¶ô“lűëŐŇöo<Ć{"ž„Źä›áÍÔŕ'\—ÉśÇĹYy§ßo¬u‘V,om3Ĺ·©đńťĹWÔµ wóíęő˘ŇÓ°…0„5ž ŁŹůĽčJ“5ÖÉs;ŕ› gŃFĘ'yFY3Ľ‰ ßżeŮGt#·ô ĚÁÄ×Âú-óYź`öGśř Wb-í+˛ćÄö—fĂŐ’Ô7Őw#âž5mľÇ|;ű#ÄÁtYĄőQ҆ŐCű9á$Ź(·®¬ż§Ęß"ĎYÎę5śyV„ńź)ó¬Ný.ůt' Ď^¶öo:ăç;ä~iö–]šwZ]nʵ§2ö‹TţxűmĐô÷Ňq%ŹÉ3^gÂŞůmÜÖĽě›Ěce]Ú0?iÁ÷¬‹:ť×Ż:W#!Ýą&Ć®¦đ×`ZťúpMgŃÜßs׺âXĂ<úÎmŐ·ŹĽ1Î|†5^oă؆®ńöO%ÎôţíÓ‹zÝňqŢFýAYaʇĹűŽDÎ8ŇéĎúđFŇ„ôF?ĂZéź›Ćg®=·ĺ‹I¬eAOţZŕ=¶ F¦”Q•|f âb:(V¬Ô`ĺĽd©Ď—üOżŕďO±éĹzř§´`ŚňúeŻ)ÜîÓkřţnŤO<ę"®ŕÂ4›k¶oýš´'l™hAp^zđVI©»řŽyÉ+wĚ„~—ţÖ–÷ä»ymuˇ¤×Ú1:ąŮ#žÄŹtŁfä3é5Őw€”-*íp>Čö™ź0Ą2/KŽNţŻO“Ůŕie×Äb~}đˇń~Ö{â-í36ĚšŘ{yą|{öC‰°·ĺ€µŰ"¦ó}Č;"ë`ŮňPćííX^ňűÖ<Ňźý•·u¨…• °Góeřgöw˝ ˙˝5˙J…ŚcĽŃ4mšLŢ#8rŢČgřĆ:ô{ë%ĹşúőŤľĚ™^ŞŔ®Ľ”˛+ű˝Đşź—űęşŐ_ďÝŇóČZĽJÓy:×ZťZ$ĺS™K%ż®›dšfËW„ćđá·»~GAą:µ>8yÓhg%šťľĽsBë Ăc㙋/ĺ×`ŘróŲnk÷–ö{µ~ŁőiżŐ·CĎٲľĚ¸ţ‰ÜA{„Çö]`řś° ’u{ÎTű=÷KBś»ˇis&¬w@nú±îoKâÎ˙8ßa=Ô™°ŰxLĘ#Ć"ľ…nŁM Ö  ·Á‰ôĄĆ;§6 śź ţ8âĎt`=_ćŢS}ű`_ý•!k}&šâŚŁÚ~ľ§î8Tž+Ś„sk0’ś“/YĚ–OĄmXÇC˙ńĂuß:! [@?čGá1â=@O¶Čú+âąľßS¸˛]Řřß3 Ôµ~ň!Á­-wůmBÝěÂJŰŽw†/ew¸şŔé»nnŇÍâ…źď‰;|ăŐľ©Nńű©éĂÇRâžĘm=śk„–ź)×đąG€ŘÇ{ Ţ˲vb*ŰÚ´¦ä§­ĺŞM±]axIę`‡Oˇ¬mB§űk ¦ĂY÷„·°A č7(~e°E=yöŰ÷®5»ŰÚƸpŮžŁűŚ×ŞŹ"‘-Ś=çW ťV§ľłs8K¤×«¶üYâr^°·ŢŻčOʸV_—ÝSlŁ Ď)ˇ5ăąFŢÖčŮŽé[ÓUé<ĎRÎĹ<ĚąVŢłžµŐ—Šoů!ĄKd^bőÔ§:î±ÄîűŮń˛ô·pŢ೥?×ĂEߺËä—űÓłÔřd¸zĽ[Śóü˘•Łס ňNÇţ ZM«—űw°ť†ŹÜOĐî•r~ë‚ ÓśíCcÝ1ň–8_ä!u3˙ęÇSâČÄɬć ˙%|ĄüăĚBßFü–sś‰ ë#ľăc·ËśŚx;Ku¦ţy!ě¨ß˛˙eť7|ąa™fţ†«/•sO‚ů†î·ąp6âШ]ę«ű{ľ/ü]š=ţ鯒ó`×ŐÝwÁ©•6˝¤ę+Ő‹ěC|f2ĹľdĺnŮ÷_/6j{¶Ď`—)üł~l0Xş~ň'ň~˛ďrIÝöŘ5†Ö Čă/{ tü¦Ž`\˝ű{Ć7ß•spŕW)ď­n7Ą,PĆHśťŰtśa›{‰ŻÇ sŁ1Ô`ˇţťę{©đ’úń˛Ä—9uՙݥŢouŞC`ĂYťżčÉvľ'_ц”Ó1+QŰp¶ł&¶5y⻸´ś«kśÍ!í,ÍŢ]koúX\ß6cŃ7ľÔűűÄčd܇sKĎBśźşVĆšŃÉçvÓ'…sjŘy‹íŤĘ°Ő涉,¬ĽĂŻgqq±‹Ny‚ßRÓĆ®ń±HĚ÷ű{ĚŇ®Ú@…a Ă«păÜIÎH¤gę~´ťűĎgFóŔ¶™qX~ă?߸rEů×wn›zť+Ś"Ők›*ăć+@ů˛oDś/ĺŘÉ .?9óÄZ&ô÷ŇŘĽ®c4ď'†Žű|úBóž?‹3Ąwî˙é8ŽjËaݹ·¤Mň$ťN×ÚwËîüőT_Řţ]ů݆ţ?}ňÎOő›#ýBrAäTŘCýÝÇmb¨Ĺ÷G0Vô_„ó~_ ű+ŤX=úâ§đýśM_¸)}÷x†©•oVú@ëíť1k8ÜčXÔgś[%z(hßňńÜĺGač¦%Ů$¶aăí‡xĹŤ-2:Ů"̨ĐhE˙"?ćéÄqĄ8př=.ĽY;»k ¦öŕ'g^ ú=ŕă•™ô}ˇ±;Fó=|r“ĎŔßĺsÓú.ÖÓŕC8»ŘR^î|ˇY[ţ§đ-ZíÓQíCč%ÓdŽó„\á_ŢÖ–&č·Ě{ÎEH‹ŕw…řUŤN~_ęćĆŘ´†Ż}OţšÜš¬)çEÓë ZÍl‡…g«ŇŐxóś7(Ďfš“ä Kląůµ"—ů‘'@Ç…můO ®Wѱ˛˙“XVŰOÄ%ötLŽDT_˛śŮ;řm,Ąü ?Ŕó˛ţâ~˙„[ޱ»túý"?ś;a^+°Âî˛T“Ťiô´ą![K§Żőĺ6ERoúÇź©é çšZÖÇ_Pďö®U>‚1EËďü˙üČ$â}=k·†Ľţ<9钤ŗŐy·ÖéÎÁ 6>#\ĉŕx7üŇá_&˛3:©~-ä-׌ŐĺÖi×nĘÎä/çşv±ó¸˛bN"ľÝĹqÖĺÎ çëĘzGâld®ßąí۵}/†Ćk'‰Üt¤çĐĆ/«ÇMńžjß‘ WřÄŠŚh A«u×Rę!â=1t›Ôą*­~q¬ŤsökÂŰď…ă|~ę'ćŰzů");>öŰöÖđŢMç–žoz¤ ĺAż!\|Y‹~‹śŤxaĽăʰYÂa2•N_äçŃś;÷E˙+’ś˛TŰńʇÁGy¨¬ď’'”Űq>h»ř\‡áĺ;ëßő­f˘gv.ËŞ>#MI·F<¦ţ‡,y6fą:­“{E|7ٶúV!ć$ŻKßů.üZ7ůôŁ|“®±b$iqĆŚćL­_RĆÉoć…ž®ÓYzF7e“´1ś-e=îüťő·¬sqń";ĂŐ×b~ň±řyŃ‹dťß~Đ—ÓÚ1|¶—BF:ëĄke˙:oCA}#‡«DÇÇčcüń¤|’ŢÖ7‰‹áŚs"’đ‡KW»!+sčFoMěýâßË|Ä…8±Ě„ź<3ŮeŠńOęBlR)O|í˝+ÓÄ×hŔÔđ>/Ş1úĽ\?çéb.úž]–çzÚđĚŇVÄTtźo™ŽôéLN «ęOŐgÄźĎČG·o®­&~'&ĆS҉ä?ź)ý‚ÖĂ+$·ĹŤ›‰.Ŕ:ĚxçÖ–Óü{A©ť»»Bľs\Ţ‘7n-XĎ”Ř*Ěc8¸ůŤßÚ?Ý’AĚ Ă•)ë } gęâüČď‡ĺů!Úsüpk[Ń˙ήÔ?OźµC®Đ)sM®ĹâLđuń¤ÖâŰćľlšLSďVŇDé»řt}~5BĎ@Wi~Ę„ÉiGą¶u ŕ)|ćsŇd¸zŁW:!„{ĐÎěŻĆÇ^(8ż6Ť<qóŢíô#[/Ç[—wđă÷uBąçÓ~ź`LIʱ›—}Ăpćs}‰TZóë ,XŇk”uźű˘Ď®ăÜď-ő×ҵ­«8ńa(üKü†Č_«|qů¬e~Ö{@g´ňzďŚÔ‰µoEĆ ‰ć%=M—zAËâ[Gx\ř ř¬‘ĎCmľĎ5éĽč´Ł›Čó~âEÚR'ŤĂěÁ˛mW¶mü@ś_ÁómŽOV´ň,ŚÓKŚ)Ă›8łÖŻş\qN§umťw¤ŤµĎűÖUbol ŹY_&şRÎĄ€}ŚŘŔŻ‹‡`MfŤĎ/[Żál0÷{Ç <čţZŘřŘ›–xąw ď°ľ'Y7ë±ň¤ľ_…w±âŐ"ÔFëgCY±™B:ť°7ó·¨ôÁa|l3Úěäü>~Ó|Cá+é÷]¶ßRş$Ł„Ď¦úéëZÓ÷^ĚAßҨ# ôŮĽs˙çú}kt2Ő4ł˝5±»ÎôŇĐŻzďîíńű Ö0· é70óęOűňMź`=ëř‹:ÚňŹîZš}´”Glá ú·?¦j?úQ~ä>^¬ gĹř1ucĎ[…1Yc[2¦°¶ÔĽ˙އ§×Gýiz•oűNĺÍŤ­¤~»äěŘOEěěCř´CĚ7ÄE\ÇŮŔQqV^k›«S “Jă°¸PŔWöVô ŃĆÍł«×ÄĹú›ÁÄ”|IäţŤř":nV[Žöqć{î1U)˙üť$rnő`ßʇóäĚ™‚?çV?ű5ÎÂ&ł8/çŠü ëjOřĐżĎÇ÷¦Ć€Ôvšó1WşÎvx`p‘^îőXëÓ}#m-MŢŹLŐŕvź×_ł_ż¶¶?íľ‹DTĆÜgÁµęÍćŕبňÇý0Ľ”{hńÇZ}n5pů·˙Ś:ÍôZărVóÓ7xgbŤ[ăě¸ň׎íăÂ>QąösÝî|jgë✄巶ĽŰď#ÍÇ\k¬´n©ăĺöq$>”ĂRďq°ólK"ö¶Č;÷›qićztĽÖs®ŚďŚ=ŢesŽŻŃQç@ŚÔÝŰ–{µĹŔ™'‚+Ć®Lô˘Ó6±ż¤Űćłµ‰l[ŕÚ°;^oçćŞßű‚ŘďéX*¶;Bëz:Ôă°~2‹ď±ýýńi:t ëËÚ˝Ĺý@|µiú|z}Íy‚pČ‚_~äB¬5WďUŽl5†Ůâ’SF+_öógË7ÉF˝ÜXF$ŢŚĚAęű=âőŐdŁ9xmŻ–#Š÷uý®őŻ]}©Ă}řÉę–µń×xăÖGü`ó’He4¶°˝łůuP&|&ĆÖ5mŐ[NŰVËܧoYq\ޏ"oÚϞێkiýźż {Îť;iĚ]Ć8Á:@qYű´rbČ©- Ö`Ď“3?CŚäÝď÷Ź=’x*óŔ ¸-*=q±^»ľÖÚś+Ŕ™y¨ł«-W߸ÁŮ,Ď 9§/Šć%mFOY%ňËz8n»ăÎě¨ÉĐö ™ű÷ăcźöe•ăű÷p•6|őseîC˙XňÂvBŕgŚ(â̵¤ŤčŰ´ź’ŽŃ·áľäŮóWŻ‚±ëbç!îÝŐ°żŐŘuܧ±µęXńţ™…ÄĂl›(ë8OŔkËżŐ÷«ŞßP2{#δłµ.ÂGyü0t-~ˇ‰`ŹĆ°Đő~“KÝý+]G˝qŻěăvţë' C]ńĎÄ ŻqË®Üf±7Yš˝]úiĂ= ĘČôüZŢ]ă6Jí‰tiVĎ­jÔöęÔ›dmŰp0™ľ»÷ى…•ýäÜQÄcđ׿MŻ»Ľµ˛šâ?ô˙şňŞZ˝ŤZťűg;ËÚ>%Ç.Ęmq@ýĐ7$Ž[Gřšľă{¤_×óBá ďÓčţ¬ÚČ™n/5öť/ňăuVXOp߆ý™÷Źřţ´.ľ<™tĹŮ™‚ó-shłírxa%ěgk¶,.lÁµú—ëĘqł{ż÷oiö°˘~鲯[¶EŮиSYť‹NSŰQʆéľąľži˙‘đa=é}˝SbÉ ¶În‹ź‘úg|Qé/^ŰŰŐg©Üóńis ҇ĺY·Ę‰‹·bDšP&ŢU;/h.ńŚÁ8`|ěŰđŮŽbßż,q;8ÖśĆ ęÂaňl}˝5˙iďdśŮd0ň|;®ĺ5nëă™ ”śß}ĺâ\ËŘ_Ó™čé»EŻ1.‹ŮjâČëPĘ÷ČgÂ)vÇÜŻÄţú©‰›F&Wę5ňmĹą¨Ť˝+űżäÓ¸˛Źó—_ľłą;e|7:63}ő<ŔxnhîíĄµľ†đ=ź3&ë`"ř~-˘ů8Omä|pÄăđăÜ2tÎđYÖ ,Ćöŕ!«V˙`M7ë=ç|Úíä*‰?ޱ"Ď ~Ks…YËw®p"xůŞD¶ěÚf‡}­]ٺŠtůüňôSĺ{ ç§Š|/ .A<•öő“Źž‘·×^źčźĹGŻĆ÷i¸~Ĺźý!¶żÖeomů%⹨]ˇ=Ű•ôĽhEükUrŢ÷ ŃĄŢĆçşmÜż'^Ă2ŃkĄßMń(I čËłŕ—:#Ô{ÍŚó: gęśyťč÷ľ‡>ń8ÍeYvbpťšXWŽř˛ďÂłŁ×ýŢ}2†˛ŘvbNѶô-źđµÖ^iÝ׳yÇ-ęó‘ɸĐĚÚ§ÎRZňĚşşrďę>¤dç˙„ßYYŘĆ n·¬Ö·ˇĐ›HÖĹxWÔŁĺž#’‹Joń°g‹Ýk¶íÔ_ĺžý¸Q‘Č…ť7ŽLJ_Ć Đ}đWZoňőűřŘ‘ˇ±ßÚ!űčä§Ą,ĺ„ď'üQBt5íhŠ8"bçáĺ.uľeş«^ î&­=Vü |“ZföMâMś˛ĺ·Léôs°6t,böľç;·ĽÖR_÷ôű`.gçŮ?ßuG1ťžď]]”ĘĽÝŹĹČoś–u˝g2‹ý¸ń€)ĎĺCÜUá—Ĺ”‘± ó¦EĄKđmĄ±\Ľě›aĽýťÝiTăUGꛋ»:ŇÚV>Ź%łĺ}g…7ă*˛?f«ŰĄJ~ä$Řbľ0†áŁ Đľ±Š|YkËż3Ď%»Q§Đ}öžr=Ő÷żÝ*ŁęP_cFZ»8 ]p"\”č™dµĺM3ňLo©źĎňďLşö¦K»+Ö·eÎÔď= öˇOp^jcŽ[ËĘ i[ęýśŕÜ–ń÷|˙˛ďŹËFÓŮŕβăÓŐęJeÔ7aËąWřkó.ĽěkÔ+Ä~Ú°i˙úDQĆ‚Xq˝¤¤çžěËők{Â~ď•X'¸ŇoŹókßVôý•öS=®†É8óŔ~YúâĐűóbăó“F¬§węţJë'0'ş>µWů0,nĘ2îý®\÷Ą2B;ó‹˛8®őuśőcé2ÂÝHźQv) ü Ćhí#¦ůśrÍ6qöBŤ—÷†p\č#—…žŐø3÷=â·{”‡ó!á1ĺë ~۱řIÔÚšľCţ^ň™<_ťÚß˙‚ź¸Ě±9Ç3ą0y!Ď­Ż+oAĽž×"ćéáŢ’üˇí +×vńzKŹĆŢAߎł<ű |üf…÷˛ląťő^Ěź»Ť'y+ž‰K7ů8N•ůČ+ÂcĽ4Z݉}ń]×Ë7ß™\»uĎ´Tµĺ4ÄuB>>îk}ÜLĎYÝłMsúĘ„ő1ď·¶†łM/•vǰ6¨ßŔşŽŻr.CůäľĆ&”á;Ć9=MüńHwKš±>g^[GaŁ]qŕç‰J«úy#”ó¬ű0ëvl硇-îŁáÂu ¨ Ö &ĹKójżD,ősôĽŐyś›ôKß ,™>`9^3ŹÉ q?ń-ŮÖÇVĂ·Š±•8ŕ-ş‘ë­ůGř}Źůgóc_.ßśđŰŇľé%oKŤłD8‰·Ń€°ńžm#ö¨čźtú±9ý&Ä<Ş«Ôű`WĄőéˇ=–eăs |ě-q®pÜ´ů=ó±ÝfÉ8üWËőą ÄP,í+gÓÁéôA2Gč©8ę^‹ĆĹŇoJÍŃÉ›:Óé§ ţŐ–źwxąD^Lç3引©ň?¨ťW–o|LżETn´ż„sîęÝŁ$ľz K&SŠŹ¶wR"ZY‚yđ 1ó›Ô|”[k1ŻÄ×"Zą_Ćçń±…ţ8Í<®0YWyŃVĄ_YŁŻęĆ5±_‰L/*=BRkg.RÂŁ´ÖÚŹ±öuîgc*eŤz×Ĺą;°^+xVZSgµř¦HLÓ@W+Í8×~mę«ÔŐ~żréĎv‡ ďN‚¬ś*ňŇ śű˝$ŕű6l&„žÄ™ôż»÷ČîlůŹřöxĆŽ*ÎiżXľ; &íŹ Î9îŔţ\ÇyŃ•‚ëp5 Tx:âtĽߤϓ9¬ńXëŃňaZp­ń#>oWô/Ç~Ň«şÖV˙ěĎÁ›w&ú˝řjĐŰę:kŇĽNeľŹV>‚o‡—É=ľK*Źv+Av‹čŢüČ©‰ÉĎńë˛+»îáýÇŢž‡ń|UňŢÖ㻸ÎKšó,Ó+™Ű4}mmÚT*łkŞ·x­ů/!îŕYXŰ˙ˇ¬[ZżË–ʬŮ>ÜV¦Śë~˘w¶źč#-?>¶,9†X,±â+'´/i¶|WÇfél¶zXŚ—LmüµüŠ€3öäŔŁs~{ąň‹řTŔĂĘiJ\¸˙Ă6X/á09‘ĐŰ­Ă`hfšNű˛ëÂÇo…•űkňę‰`­a·|·[vű×ě?¤÷[š‰'ëú[KIt÷ɨ+§Ă»}řÜ2śÓ„őŇΕ7mi°wß,ܧúT'ľ«ŘÇ©Clľäâ4óuÎ6J–AŤgz‹Öŕ‰^!–6öH 3žKg¸¸ş.ťľ%žąčťň-ŤZąűŻiúËĘ1…Ľ˙Ý˝¶ú&ŚŤę/ťČľ.4—«‡­÷X›n8î/ÍjÜ:ÎúkŽ« Ă]í-őTZä|n[NÜąëé_÷CĚŰźÓžfŕęÖ‘+|kyO‘ńq­Ćɶŕĺ^<Îw€[=¬‰­­nąYš]:CĽúQg,\®4 βşvgZę=,Ď™-âlsŘ8óc… q•’ĐłÉtşKčő˙ŘűđČŞ*˙jd«“FTޤˇ“Ô« ( Č…Šš´âR­c‚J53Ś$("…c€ˇPP–jA1Ý "Ő2. V»Wă¸U 3v§u°Âč_ů˙~÷ÔyďľZ˛VŇŤ_ĺűşß«÷Ţ˝÷l÷Üí,©©·Y¶6~šéúSńáą+¶ţ8¸s˘«ö5-SĎëń©KÖZVµ!6źÓ‘~Ä“i ŁůŘě5ŇĚműqőúm/ľ‹yôG }v¶Đ†n/ĸű­÷,®ĺ°o?"śëë s}LąĹ<gsÛǯŞ2‘Ňcą‹ ŤÖ%z0?ÁŠĺXŽ{ đeĚ9ŁéżśYzEŕôşĎ;Ęqší7Tuxěôc˘ÔÇ!±[ŠÇźgÉt%“Ă·ŚC»g;Î/óđ´ŞqY'Ç#•qěGî2ŢÎL‡3 ٧'`[Áą–'«˛— ¶śÜ »°¶0FgËú˦×k—EÂĄ=0ms]bz·ŠďŔ=ć˙m:õ‰´÷-ďk§tÇXĹC®ľ2őżÝťu¤˙⎵;şŽ22LxUź)>ˇěsLżÄ ±[溉˙¸Vő›‡%daÉç^k ż;?´OŐľ§săÔÔ; Î!f®ÜŠ%ęę§Ë‹UË/˘ĺ-‰=ZŽk˝Ügd€{8„ tpúč±ÜËËö­Č%{_ě Í|*Xxž++Ë iٵhP AhP AhP AÝ«ň›}Ż"7=öQKţUÖ~u%„ßëî3TľÝ˝ź¤¦.5{•ŚŰˇgQ§ŔöTĎnĆÇT†Ű"˛'ćŮ[ÁfŁě›ÝçMăoŇýúO˝˝.ŮĽl úŘÓإ뾯Ëqţfðűm}źu÷vXž{´]©c˘ČŤčîý’Ď´P~Ă/ˇ6ž­ŤGäŃuýĹĎr” ddqc)$÷{…W§GG9gâ~ ß©˙/eźďeďOqVźqő ~Ô“Ř-öŚŇW8{ÚđxuöďÍŮôtÓŞh$Ťr/Söýž×“˙Ľ™y«ńK,ßWů·mRH;äpÝĺý;=1Nźtá€ďśą§.R}$ň%řęîtÓMƧuŰżíiľ—s Ť#%ß_±“‘ß+đ›żIçťv®†ĺ`icű·oŸsł±‰’˝kyÎx¶Ý­“‡ÚE}†”QŢó—Í[ĘżĘÖ©{ĹRrů˙§ĽM ˙´Ę"!={á źłź’7ôůâűPöůĆŹŠ÷ńřl’‡Ś_4űŔ`hştç•OOd\ý§íÜVĘ˙ľ*˙ćeëßÉŕqĆ&KĎ$żęáňs'ňeŞ«hü(Ű” ŇŠWÚ ŇźĺůNÇq[6(÷ĘcĹ9xˇńsbąĺú{Źó|ß.3ço˘ü2©0Vâ&0 ]FŠ/7üf߄ߩ±Ůć®č÷@@sĹkö•} 쇟äKŕz6lJ˘ľńq©i vYÍ7ő#OÇee2hű˘ŔßřGî˛ÂŰ Řęež#w[ićɵŤ/ďé×_*ćÜßýÓ®îÔú–âZhŮŁ‚¦’żžöwůp¦ŚSQćEތ·Ŕśµť›çcw 3Ęľš0°‹N«ŤŻâOů§ĽK_Ňď—[ŻN‘A™[đ^ăh)Lze?ULŰ[Ö09|tÎmđE8ĐĐÎIďe|‹éďŞăżÓ6´®ZWűXf©ţ`źż­ť‘íłZ°đą­Ë¶ő}ËŘv#&ěŐ÷se%áě {:±‹al@Â}\*Y’Yĺˇ˙Ú|Ƈ!™ŃE6Ť˙ą-/Ă×iIÎ1©‹F.¸Űč Ţ„c`·ç JXrĎ~weaş&?Ý+]| uľçĚŞpŽÇ}ýDëĺ\µ5s´ńGEL_]É çZ"ɢ.8CEŽ‹"ěuŢo`Q]­•Š»ÇćfęŹ}Ű…›ö5:gäËsáŐüčśKÂě Ä+á¤Ý˛•ăT °˝çW°‘?ľ“ż Ou}ĎŚŃ“ĂyŘř/Mľ‰UůŻş˛'ăi c¬‡3ńjÍběj”GĽŇžMÇ-~Ă?Řť[ó »ń‡•Żä9Ç={N€~fhG;1~YUn¤Žą˙ʤ&¶ÇRý{ĽÄŕ\mţ řÁWÚ|ŁůŘô9ůÝśŤ ď•‹çµS÷»c­‹©tĚÖňzUűIŤ·,DM{7^˙ă˘ńeŹ30Ůđ°íňß ŻČŚyCKI~=Ţq<@Ś"›âý±^ď˝÷ËCů{©ˇĐr”Ńű2Î_hCKř{-ď\)~ębŽ+ҧËa‘ß§&_AŽŐ/ĺˇ.,Üű¨ËçÖĚç*ülŘŻ·=zK¶“Në±/„ťQy;‚ł7g“ßđK‹^Řlš.ôž4ź‰Żĺ0eöídŽę‘/ťżáă\}DĽÇrâ—źď F68vüFÁKűëäp?ôóµÎL´-o—ż‰ůý–ŃܢřŚÜŰ&Ź»ňŘn‡ý{;aÄ;0ľ­ú®?vo4rřVŕ¤yEňPć´w˙šYSi9}ŻĽ e[*äž´ŻE‘ő..ŢPkFň¨éśŠđ±˙ěl9ÖŮÖ·1ĽŁ«Ďô÷55Ęů°Âź¸ű5®íŰ™±SÍ=ë ^,Ď+˙ń{}V> î¶\Ůë}ú€z.—˝ Ö5RĽ rµ¸?'ý"Ó÷(ßÔÝ›ĆðC–|§Zóäž˝FozóG…Sż3Ťc¶â]~ĺ—R>{ýv¬›Ľ1Zé̴ܻăŐężĂšĹČlŕgüÎ_jnżŕłÜń:+żÚKa“é·áSśĹ‡”s䕌 —Ö‘“ĂŻ7|§omąŮ*iżQs_އ)Ë᳏>ţgMć8W˛,ň=úx ß{~3źżćü F´f^bbž×ś+iź<1AbÉ—X??ţ› »dĘ1׫±?’šz~e˙PSö¸¤}Ăűq °ţĽńoV®ű×±ÜMĚuÉŻâń-aţ—Eé°ŐŮ k_#ŚyęÜ2s›ŮŰđÖSŔ ľ—~“6şţ!N#/5bě˝ń[>íúPZöď伝ú€üöăËúäŻ5s…3Ýt•C9.Ęąß0ţbł˝˛*ű{Ö»(ś{S>ą!ÜěŰĚ-Čö`{ ;Í5晫y8k?äsęĘřýĂë#٧?á«“řňé#ó ¤Ů7î„ď­ÄN`ĎĎŤ‰˛^ľWą›~Á˘äš8mýÁMćE â4FÓ/ďÔuq,)q:ěol^ÂÄÉŕb4Çś‰á Ú7–â{&üW _ŻÚ¸gÚAë6Äz ďlyĆŤ/ÂÎ˙^+ćh Ŕ|ťČMj`&ü ůClÄĆŘÓżŁK?Y?r®÷Ţ’~ü¤iC÷e=8…F7©—ËbţđYS†}„Ľš gŽgŚIÝźÜăßZäY˙ |rWcźč#€cČŤe0ů`›;N.gÄŤîĐ=ĺ ÖÁđĂ5xÂ_ĆŮ8±ń^fâkŽĺö.áď—KĹź0ďŕ]‘í= ¬ő˙U9!Î|W˝/K}™űţŚxך>q×ř9íýÁZŢŐQcą!ŚçW—Î4…«™Ń–čż.kc|ńÎFu)ôeŚ]Ć«ľß«¸+O_—ř%DtłÇ«úzĐŇiŐĺ„} –ĽÁśSR.H»xĽ˝±G2=ń…Ç2ť.[)‰ŘÓfO>ß^’®ÍăÜÇ‘?öIĹQ颿ůĹC!Äü¸Đč…łťŃhfôß±7źÂ™×¶Ž]_2uŰü¶ëŕ}j*^_fÎőĽzôdŤ!÷‹űż;%>‚ZKoâynŽ ĘöŽ.ŤWXť×*˙ZŢľN_göÇÇČ+éV®˙ąG ô<*˛ymŔwަË;bş‡c·°đ{ěW~"ć8bSľŢ§Ż(O”7Ö^Mws^:SË#Ĺoµ!Ʋ;G±y¨÷‚łżţŢ„”tZÍÔŇüß ^ž\+<Ľ˛˝]ź,Éą˙Ć7śnÚçq˝—ů|Ääř®«0nA®‡ĚďXň`ÓŻËő°ÝŽ}?Ý$kqb29ü §Ř´Ş“ëŰůcV˝bŹ>`/ŮŃ:Úţúř1öśaéJgĘ@°đ*ä÷~,<– »¸nëűĆh˙Ź-3ÎôHńQŁ3µţٮԌ%KŢX’{Yú°:.óyJąeýÔ·”5O٧$–­Ô&:Eđ–qŽń§&co#âÚťftŐ-WE“FĘ\3ŐĺŇCâ¨{t«†3ánz“ˇóHq-®gšzá7ďÖ3ÜŞ}‹ąI;ÎĆJzű<çůů?zŢPý^űÖľ€A`ćLçmˇĎÁ§čl'ĺ—ýˇŘ$küđ#‡ž0uŠ|z8S˛n~/úPŢ‘ÖěoäŻ]„µŰť.< W˝®­™f{âÉ˙0{ŹĘsň5ü‹O6SS×Gp¶‚đJ·`Nčábßo?Şű.f˝jăĄß÷śłW{§ßÔ 7»ácu˝výgU|ľ­x{UÝf—Ń{ĄťţžëUhaC[ż{ö#úµĘjvükÁLÜ(“3Íkk•µź+ßăńÎE­+f˘Đ–ѧîv;Öb¸v˛ßÚ°Ôş'®čs%ľKK;ş.Ż)óĺőŘsKÚ' &"Î%×GFŠŚŮS˙żm}2WšÄŮç¶ľÇ#+ď‹n˙5âÚž~Ľk§ÉĂUcµßˇŁ€ŐŐŻĘ«jßÚϨĂzšËéôČ~…‘ŇÚ™{ű,™îÚŃu{»“~ç˙†Ţů'‚*tĚĄżëşdEŕcçÉá/šuĂůí \ŞÝ_ČăcO98°¶ÚŰA‡şŽÉµ¤ĄĐ˘1Lĺ ěÎ 3yFžžš|—+Űý±fW&[1Ž•Ďwl>kůX’ů îÔ÷#z]děôě’ńXńG˙­á-<˛çý s2¸®±“ę>ę.ÄťŔ^Ç·ÖöÇÖ´_;őď̵ů¬uÉUˇYţëµSO›ÄjđřÇž©Ř1ůÖ`ˇvWç™±Ţ_‡ž?{4 -©+˝z—ßPv/+^™Ŕ¦ë+BcçóčŹÝ ›ćRż3ą oSS;¬=<?–§~ŕب´Č÷|Cűl5ŚĎ•8{üv9˙87â+cČ™#NŰą¸üx@÷\O{íľ…5–Ljů±‡;ó=Oü¸Â6ČăţŘ:SgIÜŘ|Oó˛č­rZö&Ú0f˝óĘVü;0ć@ %sS66îľ‚âB»Pö—áŐŮ˝ʦÍZíŻĎ|Řõ?¶Ęěń;éşú­˙ÉáĘ^ëŽqĺđ,×ďÉá‘ȬáůÁvG˝ŞĽŠ­í\ ›^ěśĘąě;r<îŕG®ŽOMeĘäbą°ś˝âNýĚőQfôőÚMżÜŮr}t,·çVŻ1˛9vŕă®=śâî¤qcą°®BË•Ř;{;ö®1^ĚÓRŃśżyŰrĺ’íŮ{,2W÷ `źťţžsUo~·í–OG/ľŇŽ/ć•Ű]îžly y ~íësÜCĐ=ÎIdnîA̱G×ŘđÁ2ń»SŰSýŁŘ÷čŢ%şĘnawÝ©&Řż˛ą?¦¨!ś·|6mwµgF_äŁ ěkLMM‰­ďÂZŰýJ­ü ű-׺ý˛9˙)Ł»s}{´Ý{ŹŹ»ô hP AhP AhP A–“̇Äö`+ŮÖw•oe9áXę¶Śö&nŤžŚ\vÜĎŁťŻŐěv¶ ›| ˛'lO•öů—ĘúŐżiĽÂ&Gqô®R×ĹÁ÷BßËśGžHl›Ę–ţ¤?v+lš®*ť˙{őĐţاŰ>ĄÜ1őŢŃŰ||AľđÄ*1ϤżVÖĹVáŤN^îLÄN)Ůj1Ňyný„‹żSű ťOÓ°;ĺĹ_!ţj#ˇ´(6mڞŻ"wŞńÚ4ţ Sh‘Ľŕý±OÁúQśŻźeĆŰ5Ç\«ŰśŹ±_őĹd.–ëŁĎĎÉ&‡ď`ȋӷxLĄőýz¸ď3îŘÄöýăďćŮ_ňkóóĘ[żÎťO wuÉ_JÚŕ7µt…Ň›_Â?ÄđÔIżÝĚé©H×Íă_Y4ŻCâśÄŽ7›Ć˙>ÚśOÂn8,c„'ĺëΖO8ô·w=ÔŚĂ gť WvŕźÍÚ„ň\m~R]§ }^ź¸ŰÔ3R|8J}Ź8}.-ĺ‹…ý_xčŞöÉó~ęËźVÎW'ˇAÂą7şeô¶^]8o¦l¶>%±r"{­i×ŐťZY•v­™[Ísî·(ďß˙a8;p;úŚř.kÝő»zxŘ0z÷ŇRlµOż‰Ěšîá} ?7ăůËß„lzĺY 0Őuř6s[”g/ňys|úŃ~ż{[§Öć·ÔĄÔ 1“//6™öřLtŠŕĹ>Ŕg+ '‚wż,őmDűŔŢló;ÇÇĎ /Jôzô™m}ç0fu8á<ńŠ¨ĎŁŤö)îÂN¶78÷ŤGVgWDł7™¶ó=‚;rvşí°í…ü!–Šáq5}ŰD{v T’C‰ÇjĂËľ—žxě˙NÇ8r{ëĺîT0úĘäŻ]ŮAüÇÎxüĽq(žńĹk’5×ʲÇRSŽý–Ľ‡˙‰Áą5ó[řřżń®.ńc!ŘJäwaăömâDY¤^mĘďgÚŚÇ?a®6ľĽçś‚ßr,…O†ˇMsţřfŚx2ŚéĘy[Đ<—ľčńWë”KSĹ„ř’˙ôÉËŤcâífľĂçÍů+ľ×rsąÂw9̸"úíúřA%,OdžÄýű@Uś9·".¶n!¬ŕ\$ŮÔ5!çuÇŞ­ť_—8ĹŕĂ)7đ+ŤlŻŚÄ©ő~˙ýżŠŰ}tWúóJ} űüvKéü‚÷ßĂFĐdß»Ţü’6ţ§@^ćP>dśćÓˇ“Ď#5őJř– ůtq÷pë'O(·”Ĺ/Žž9»:”1Ł*á%lĘcÂŃ_v~'|ČŇď«é,uú1 Î:&W¶é˙vľż`;^ŁĽ ]UÓí¤ Çĺé&î-Č_ˇĺ_ŚĎÉpń:ř[Žw „ŽsűF-ůÖţp|ęn=­™GěóNÂĺń^[[ĚŐË_0–űç¨_Z4§›|őMę‚ýëZť˝§í§=GµaŽÓ19|„oNb×eß«^Y–¶Žě ¦¦ĆL;¬{1;şvbŃ™ęú«Űźt-cĂR~Oo#ąľ#ÚcÉĎűxLxK±ŹGŚLcÎҵoóŠňzĘ'®ąäŻ;ő“—€ňqŰÄ#­Ďuő~3ßëúř›gÚ¦k9Ő~Űk¶;ÝôwÖŐÇÝdćç‡ŢęŇPá’2ŐĺĆ߆”X8ŇÔ!ó»˙iŤ »‚¦/gFŐGĐ“ĘÇ3.{ţ~«ůë·ë,żŻŻ®ö`ăëćÜ‹ô¬¶.äŘŤuŹoŚć¸,ô÷ęŞÔQŢ»jă]9Žú{şi-Öb'bÎî$św"GÖ=ÝĽzr‡5AÎ|ý„¸ĚĄOgFŻ2r,ś=™řGČfz_ůŽt&ý)O“ĂëÝ>ľk•éM¬čL8ŹUő­o,ůŃrąqĄ‡ZuĚöśs–‘â»|ý¦óyľłĄË'·łÁQë=âČc˝Üíň¤Ú¸^«lµçőŘ›‰:ްO2ţ5űźÎ‰ŞÁSţŚú =qâlü<Śóhkěš;Ď9˙Ĺ9áÔţI˙{U+|}o&<ćóNpöJ †\ëöŇülnpcŽmŕEl8çç]+ËöĐf®2‘„!nÚ+ŠxćL…q˘=¨ęWhyŞ‚žđY3ĂË÷Ô9“ĂÂŁPö3&Ž…®kÖyëŕř]h9ŇôŤ‘⥷Şžzb˝óŽ.w,XÂůéťćĚq.řň•Ä*oŰŢóT{Wę?ďn\ÚąÖS>î×Ç™ęŞgkóöŽ8sM™şŞuó¬e¤xl._»z\kq?”rÂoĘçwZ×R^‹M'›řáŐÇçŻWŔ.°2.cS˙Ëß™±6ŁÇă@žTÇYeDq–őćQǨ6.ZăŇ^Ë×÷¤}Âą ń‹ŹŤ–Ó‚ş}ĺw=›Őm“űµŻ*Ĺö®Ť+ăißAľśŠ1rßÂ^ť…–»–ToUŁŢŽ®pIçxo3ŁŻŚ–m«¶Q}=úľµőúqŁ{ŘÇu T٦^c\MÖŚĆ^ĽĺŘÄ>5]v| ËXî_ť±Ü¤i›0#^oô¶‰=;ňýŐ;Ű{žp’Wv…78Ź™u.rŹÁ&§ŮŐŮÄirř_¶Ă?ťł«ŽGJW—ĘË÷?Ď©‡č3Ú±ĽĘđŽó}Ä1«IňQ×AµŢžpŞŮ‰VÂż"ŔÜ »Ď×ü[ľcö_Ş“ ŢŞoT^yeź×ńŠßÂľµJ¬µ@ŕHä%ŕ{ćqŇŢ!źíN°ůÂŮěVäX]ŇËŞíxÖČÇ8đ3Ä7}öG1xeF_aľ—ń‡e؇÷6}gŹ>ßťđ%,É7Ż6ăN±i%öľr}.hÄ÷ěźĹ>čSM)韏śyÖ×›¸ŇYĂexNś7G>51Ü~őřxěÁŚĚ°üîţ—ďÉXí|bÁÂ7Ťţ%î­™ű3í7c*krä4ô˘žŁěo}Ú”OMýO]öó–^Íů+ ČŐÓŽ>Y7üoÚGŃěł!îkĹűĺ€q9ÚHMEÚşSžmŰL8ź0xcßßÝg\Xm4(Đ @ 4(Đ @ 4(Đ @ 4(°»QţY®_5[ Â;–»f—íÝÖ›^ş§-öĐ’—Žg°a7ű~ďýŔě§°]Ú1&±[ÎĽ°´gVoę_ߎ®1ś}_١{đb7„<‰'–öşy–%8G6ĽELc<ű»WJYŔ~’±¤˙~ż;^ -«J9Ş%°·Ź-ůëuź›Ľźn’|n˝‰?ÖĚU(ą•ĺ #Xpiµ;ŕ~jňłźO™ŐóGÚđňV•ö|eŻ›ßÄ’Ż-_Î6D6Ľ=ń'ZŽ-ů8ygŻ7ćÝĺ{ż˝‰»‘Kđ(äćř-đ˙‹ÍăWągÄѶ7iÍ|ßőG ż¤ż‹-¬}žÍóćf)FŘ?X÷);Ŧ=wi_ď>࿣´ođäMôTµs‘mÚĺď;ß§Â7J.ß(íjl|µđJ“‰ďI?>Ëü ga—]Ďç{rČđ^Ăaă‹ĂśĚŻ­˛9Óő®h(űsśóHţ“ÁOżÚ=“´Ë“·çĂ× 1wh#Ę|öRÄż Ťî»ĘŐůÍ—ţŽ0§8“@ľËKşą6ľ›ĆŻ2z~íĚç<“mę@Ć$ŠÇ7tę ¶ů-ť©©/Xňµô¸ÂÎȖʰŔWWňOű¶žŰ >Ëď‚ßČY®ťşÖÇď垸TÖËł÷‡űöXÖq ľL®î%ýŐ6­|ňÜăuěşŤŚ’ü§|őÎ'+qµë—6˝:—ęn¤řX„ąŮ(ÓvâWS F±×#mbÉ/ŢÜ:ń O1§°WóáTŻ‹ş›ßµf‰žšňŐᕯ˙ů!8KţPäg7qˇjÁI µ-(‡FyËçđ1ý3<·"oŚÖíůŚůäúâŕ—˙ŕą˝6Ě»Ü|% Sµ+e€q‰}p8îň~sryŁ2<Ćů:}­MÝÂĎJ^sčţXż%'¬˝~Č)îęJÍcűŕS źyzH|f©Ń—QÇéS]?2±!ŕ뉦?›¸)Ěo~eúx5»#Ĺíą0đżEž$řjy>ÉúíBŻëď†?ÔC8#pűűćťăăą́ÉE…Ş«ăL=˙çm¸Ęś‚~'´‹ ŕC ˝ý×Ţ ľĺaŘ …md -ęs,mi˙’¶Š]őr…ÚCí Ű´XřĚŘ^Ąř…Őq¬…;ź#gźÁ•vŽ÷ś]íľÖd:Śü—ŰX•×IÚÁNÁť‹ó}ą=euLć÷ô13ďc|U‰{‚ŚÚ†”ĂŁż“AĆ,őÓEőcČŔWČŕ¬>ÜĺßÎô›ă»=WŐu+ň*‡źź˙¶KËůač˙úrŘáŮ0ÎôW·ź•ßkŽwű9ű6Ç9­˝9˙c#ÇŐĆcá5żôÓÍţ-ó˛@>ĎF>úc_0W­1WÄŽ‚ťŢ÷Ť^ÄzÂ\g“żMă×G6ŹźáonęŻ|ĎO"đç0z >˙upĚŁIđRkăĚń ánŕ‘Ż‡NJ8{ÖĹvş¶Ćçv4çÓVÖ˙âě‡ MkĎżŠć<ż+‡[Ţy˙—˝:ÜÔ=\d~ç˛wU~k *ú(ŰräŐż°;ňŚ%aëüO7QgżÍaŚËňqEÖ śc|şę‹%:ůagž¶j˛Ň”§Ýg €řĄ''ZA/Ňcôůˇ'Łj+Řű±ó˛ŇśLć¬aáđYł*˙v÷Ž®k‘Sí#ó+ś wGżŽ3Ťé‰ŮcCĘôÄ7 mb?ť¤~ył"pü7ŹBí„K1:ŕ˙ţRäKżŐ’uůvľ˙çŻ}rń%äOýÖ68‡coäĄîúţľć{mľŰüKŤžZ}Úfç·łÖ’Uř˛¸ý0=qdţ>˝O}ĹľO>źúł ˇÂľŚˇ?ün9ÂĎôÉEÍC/+ĆĚľiĚölśżôçAp±Ç>ÍŚŠ= ďaógâyR.8ÎQ_{ú™ďWZ°z<¦îcyűŹípź ńB,ąÍ~Ü÷Ű.3ß{Ž3‚ź‹öŰ Î‹ĚúwrřQŰ?ŽĽIď10`vÇMŮ ¶ýőS†_ůž„{ö6Ä )áü?xîµCX ČĚ+ÇbÝCó#ßóă°ńŰ…ţ›ţ©#Xř€[GwęÍ®.%ď=ľj ¬ÄůTÄ[Ů4ţbŚOo„˙ďŢ.[3Ż…çŰo}ćwß0úës•9ŞWŰP:±ĘxąĽůńWXv˝řĆ7>Źks!raţ ŚŰéń÷—čâÁJŘÉę€îÔYČż(ľŘ\Cďčú†éŻé‰O#fΡE>f„ŇŻ Ą˙lë»Éřu7â_.sŠ]ě„©Eë0©Kđ([8F!Ć‘Ďüšíů‡Ňť}⏧ŽoŠ 6"ÖŤ5Ľ„]+|ßMY…WŻ•ř !öŚÄśnz¸Âď®Ţsíţ?uşqî˝’ŢŚ#„=îčćńń=ŇwĽ’Ď”ĂM㯋Đ72ö.ĂŕžwOä 6tPśí:ô^e›t.—ĆíYťí6üe?;:±‡™=Vm>Wň c‡‘ŮdđĆ+čŘRŠMIOçđ­vű9!­ÖWU_R–ŻŮđ¬łb-käđ0đż­ěQ^«Áe·­÷âëŔ_ÜŚˇ[>ŤXÁśß8‡dßXŇôEîhÍü˛c[ßń®ŽÔ:ě+÷†Ęů¬ď9¦!vE]ú3ĆČéJŘ®BLĺµaéCŐi­0.”mÄ1tCGwîĆ˝Ě|2}q0mľ+×ZßlWöĄÔÔŰ«,ç“›…ň{[ß=Ń%y›UWÍ$c ź®mŮ.öö|° «#_äňÚŰĚôÔúí+á!Ť±OäkÇ_ďÜeľcęŮ4~S™ěĚ ›ĐÇßĆkŁŻăńsÍţŁ/>f·›6Ş­§mÜxż>…^­ĂĘÂ^UÇﻹßálĐäwÍŚúă=Ď…ĎԳǗâÍŘ-rľbĎ;ťtë} ×˙ŇËńÔß\3j]#Ĺ߀^űD¨»eŚÓ7‹żîčşĘô˝Mă™XŹÚţ\®”·ŤĂŃřfÇňţJľb~‡\Ř·Ě+6׍Íy™dF?RÚźX<®ZĂęě#KĺóÂąŕśžXŐéĹ̮޼>Pý}­v¨'uÍŚ1ˇŁpÇľ–Ě+ô żRN9ćĎuś"śëiäĺgúÖ†µpĎsöbÓŰqČD|Áú­©”JX#`n2zv>xWĂň].ăŐľ›íÇjęňb)bvpÜ!Żgc¦÷˘÷„ŠŁąÁTěż|ö&µĘΤ/I;öŤPöşăžrmţ×ĚŹWĎŞSkÁ¬Ď _lMçŃđ WCGÎ YOkć9ľůŤÖ˝Ř+âj–ĆzŃ3şß¨řĚĺZ>žP§ĎĄśý ĎÇrß‹Ęţ‰ŘśôÇ^ś·ő=Š8n/€üÎvźž«>gܡ`áÝő™‡R&Éű°‰I®TęíĘ~żXîÍż…¸ďaętŇ‚çp »}Ĺ^7ć_—űĘ ä~ú° ç_čďÎtÓ%٧M˙uUĘ./îŚKÎ×%^⟺ÍýdăéÝ lý±{qVGß|NŐ=bŽÉÔńşfBŢŁR¬Sž}lYűńlÔÄľ}Çpńaw¬&żí=;ť+Úő¤¦ô­Éő'=ŕ“aĆ f¬W»ě®Ľ?.µˇ-?ó=S»Ë»júIűč`č­ŘëĽĎŕŔü‚* úžř v ěźnŰŮr»;?ß•xÖj;á|9L]CSďocą›ÜŘðrő]ěu°‰f,ţifNśŁśŻŻÝÖwůnŤ«ŔŤ˙sr¦IL?Gü;K‰Öů{|ŐŐCĚQŹÓěíж-˙ ĄËÝZź7«ebŽ´fηpö@wŇ/j ý·—¤9Š3Őu(b~u·ŇQÄóżCĚDł:˙’Ť 4(Đ @ 4(Đ @ 4(Đ @ üíS`[ߟ̞Hvŕzł§wqpÝłvd6n †>XÚ zď5űÓ<ÇLOŕë@Ł|Ďľ»5ţ÷žţ‘ŮÇ)_ŠŐˇ2ç;ękČóÇëK>#Ĺ={?ç±~Ű­ădwŻTźěę+üŹL%îífžÓFDÎV…żşŹËgČ5oľíŹ}Ćśó±ĚĘB öëO‹zçöŔ™°ď?ţ=Ü3ćŢń®ĆQۇÓveRüĎuz(ň–xzĘýíž[qż>3z+łrľ·Ńü¶e›eyţ±˛đŃÉá đ^ę*6]µËůÝ{|f.7pxvôqţ”áŹÂŞWĘqz˘Ë=›¤Źé'çR~‘żąľĚű˙k:#ÜRʡ>–;t—፣uŁ«vtíl[ůéçőo>»?ŐeÔcŻI8á““iŘń¦Í>¶ľSşxWžskr{Ó^gĆ–Ő9üµťˇiWOŞĚ-őu0$90+Ű!Ż9sľťŤNu˝ŢřލMmÖaăŘçwä«Ô'ĺ‚… ĄŘDň;”˝Çśyz¶ˇ•­/őžŹÂž&ň’RP^µ Q=vy‘gĆ;uÖČ/Ě˻ž_•0ßó[ĎNĘiyÍŐËţŹ3Ź%çwkćIß™Y<~WdeáJW')\zĄţÖü=z¦L^#ż»;ŁL —¨éŁ;ş^íƤb¶ÜSß}(x®s*|9H_űür)ů»˛pˇkëŞ/ĂGö…‘/•|ŻLůŁřňŞc t•)xŰm.o(§°)rńg^Q[^ěş/Řy;#ç–]GŐó0ý~1Wśwűx¬<ÉgT°ŁxÚŮ8±ĂŔ›zÄżXëŔOÄč/ňś:›WĄĆ&ř`}ÖźlĽŮżŁ\“Ďü79|‹‹˙bđ›©ěŮÎ;á+ôÍpwęáóMß łoďąĐŔ,|×đ¶Đň–Rž'ćÝËŚg6ľl7X8єѸ‰v}ŠóLđŐëÝŽ.±EŁNRÄő‚ű™s?üam¸ü÷Ě!óoĆFc˙fţ#µ­ď:łČ óyíľtÇ^{NĘ:ŹOM™r,K›|^·÷¤ĚXĆűz˙ †Î†-|Č)6a| ă mZ†kâ,ó”@€ăíťŕ˙ä Ob;rRŮN8QS–u%ŰJ6ť }ąüčsĆíys§Ž đ]Eţ®wA6ö­kżćś€~ž´ăsŇŹ@ýŞ"™źżĺđň7yůÔ!~ZĐ{ÖٺĜ©Ą±7':©/Öćň~¤ř‡¶`Ç%u9ăŢ´ňď*ä‡s˘îÔ!5ů[ v‘×@`ý‡M˙ÎĽŻ$ËŐh4ó3ÚşŽĺ0ĺ‹MçŔ†ň~¶E=ąĎ]zâ˝m_ŰłßŔG]S —jĎËż'ľŢ\K °yV­ŽZĎżÇŕÚK2"rń˝ľäż;ěj‹9…K»ôÄŐXËL{´1®ő\</“úěŽ+Kšz//^äűŽ´‚ľ›™Ď”uíÓüVčÇ9úűęÖŻÇrëÝą)ąríźĘáC\¨ČGź.áçÁN^ďlů’»®J{ďYOwę?g•wâJ}O<9FS~ç8Iʏ4­ÍĹą˝™nz“ł9ćřµ“ţ9`úşą÷ÖŹ~¸CYŤ¸żÜŢ>> }ťwĽŮ·öŇçlc,÷ߨß_§ţ¦Z<~°ˇK2¸ÚŔ±Á9%2:­˝ö—,_ŹżPv›;&ŻüsÝj°ŚĄm‹îŞöť÷lÓř ákć¤R9ďťâËůcß°^äEwń;$»ĹmKŰ\Ě5lńŮc˛żqß–íĎ4ďĚD"OĂĆśmyŐq]á·ŻÓMWEó˙´Wôáľ‹ ě çž*˛!4P=řŐá/A†®1ü†o©óĚ3űë€EáÝol“mřć~_IéjëĘŻř¤’Çö3Ň:5őä?<‚¸a+m4óĂ«×9ż§;şÎ0ôěÝzbgµ}˝˙+Únî ŰĆL,ăîÔs˘¶]÷„‰ý*° 7™hţSŞJ?ź™Úf=pÎdcö>Ä˙y Ű}Ţp®ă*†«(cV¤¦ĆÜńîüP6ÂůűH°pَĄr`}|Md¦1PqÓkąq^8ĎíçZď|®ˇ×–lĐÔÔ?c®üw+ kjö5……W;aňÚw„é_7ۢé}cçřř9.|[FsmđIÂďąń”ßŮşq;ćşťŽĺß"—kÄ«WßÎ &âśë[ʏ;ď _<·ýç]ţńťµő&DăLËČâ Î gâ­:MˇĂ3—ŽŢłůß żś®öw­™—D“Á°p€áď–ŃŁs1ÄŻĺšĹ…vÝ%O;‚ úŹ)+ăČüńłK>łNAü9ÉłŤŻÜS‡ŤŮF`ź\łťţXÖh_÷Ť-ž\ÍŽ;qĽuâmť<ďŇöp†TŃŽŤÓ\ď)? ý§N™SĚZ…mŘy3/ŢčŔЧ»Ň{"Ďě6Ć©ţłăZţ q§N”}ŕĹŰĽ#.c„sŰÂo6ry¬™ë ť÷ߎ¦iřÉ=?Žw„ożÂ-Ć«ĽŐÔíńknxWę-ĚG ež¶ĘGOÖż?Ć e9˙$ŹöňfŤ3Á9ę`HbD˛|$ýn3żÔőîa›~3 ŤË?7|mú’Çţů0[[üi¸1 öDů :¦›Î™Ł^ăšáőXç^ç\‚“ŇŹqšWž‹ŘűĎ)–SľGâj#úS+îő<ßhÎηÇŰťúěšĚY ű9ŰUřµ}˙•{™ękS›‡ńřÍ3ęIÝ+Ľ8X™„0PvĆǿ鎋ç2ă(˙9/¦qţů˝é‹XçţîÇSpóŹ~|磟Y÷ď“âAyąpśÚ)"Ö(ź/‰lĎ`áýäöxżnô„Č“—rÜoď‘ ľ|îX^¶Úoę?›^’GóÄŁęĘăm}_ŚRŽ)?\‰śyxT­Ú3Ęb0`.r™‘b>[,¶EÚVë?ş—ĚzśôsM<:Ţ×˙oţ¸*ţß`ôöů!ŮĎ€··ô}µkz‚űçś§>cd«\6(G•óĎú`-ówÁ—ĽfŰÜ÷¦>Żk­gÜŰßŃő/Fowă±Ő¦Ł_fÓ¸ěw˛ďŞ®`űĂ­>x–×bŻůIć|â®59`jáčý’ýEôSuĽ·÷lŽnśŘ±r÷3çÄUÇw»6ěřĆűÝBď3§‰Ž ˝ çf•1ŤŞĂlăŚřôĐł˙Xa÷·w¤×•b: D˘wýuP_ŤŹ0ńyt]Í~Íţ­z¬µX({ĄŃÝ Ĺm¦r ç•®nL8AÄËÁ\ăaÎ7ćÝ>š?6ĺK0űqÖ1ą[žăů^ĚĹq?L?ź îĹĽ)z>ć•v ~xmţRż’/Ô۵Úw?˛‚n"ĂÄńq'5uş‰WÁzYO°pć„/¬ËŞLŐžżÜ÷®6ΌǸqâ˛ő×ÉŕÍ.źXď`čŰĄ3±Ę:TWiűěÔź+'űęĐ÷Kw= çîjĆxµy,÷3C2Ű܆|Eś·_Í\ŰrľőóČĂČäüpaFüȵěÓťż\%˝Ľ÷ńř;ÝąĚrbƶ./6ąçĽý—ľ¬ÇĂźň荙3up<>áůŰęlÜČe±éA÷|DqĺwŦ&łß»* üŢűgüĐŐl;3úĂe–i¶ę˙łçEÓM^­ôÄ—0&Ťźxoë±u‰7 'AS„±ęő;Ř3”ô0ËÉi1˘ń;zĎĂžâ5.Íő›ĺş¦'~»×–ňÁH«ßBlŢPv±Ćo«1W NMĘŮÚĘÂFľC'^rÎÝDśM?` ĹS“EÇĽŤüg ?ďú…»W.-îŠ˙żć/ŘŹÉ{o®äń™óâ­W»ßośřâ_Q»`–KMťgúJ° 9D‹ťëůî\}°+°ś©MňJűňŤą>ÄY˝¬BVYľ9ätĘ·7{@c÷Nů—=i)X˝Ü™ÚÝď&÷ühGjęý[~+BŰ.䌴d¦aż_tcĽ©|bąířÔeCžucőěčúňńí9íi>ÝĽ*ßvÔ®Ŕg®mßt…+·Z†˛®rÎůČŤą ß›ó˙dú%Ç1™§śË<’9„yŹugÝ× ÓR\±ţ˙jđ×|f©©/ţőÇÎ2WätqâţRwęźßo$Ľłĺ-ČőôçÝ@O-Ž2×N˝Đŕ·vŤČŹP†ĎPŰäđˇň±¸ĄhP AhP AhP AhP AÝ‹˝‰Í>PjŞËŤĎ˛Łë}{¶;ş&gţűfď~.‘őń]N±*rOÎ'^iü7hOŔ=Ám}?r"é_űö -ź€ďÖŐťÜă–ł‘Ĺ´Ľüeý6-C&§…Ř…HŢI={úiϰŮëNI^ař˘–öyĹćťç•±äOwůůT9Í>ßđ >źĆţľżnśuűŚ•gîqăŻ6bąľ9Ź%ŻŚČŢ·śypOż5s7lżĹGŚgöź˙ŤŻO”ñ+~sŹÚ>·ńŐ=l=‡ă·6ŚRÎ;ăŃďŘ^‘šj§Ý›ŇÉ.·Ü÷©©oË÷l {}VâŕÜÂČ«ś? ÜÓW{öUÄq./>nd¶ÜŹßâüűÝź)ťůĐţűŽč™Ľ |Bś¦pź/7ÎÚžm?Ĺ>›ř bK=ýRđ%Ż -ű_ű¦›RËŢÇ·Ś^Ý?Č0ň$8đńwlű.=“"®‚·Ŕ®|ć5uękŤ®RJň:”]ážk±śÖĂ{äXG,Ć–VÎ0•Ësť|đ»Fv·\Üâźwr}—T±_”ÜÔŠ3ěč;xVąwjŞCu:ň‡I—ĘqÉÓc#ĹKň»P”'ŕĎîę˛ÔTÂ=˙YjěČgľňÜDͦMűńřŰ]YŹßĺ´äoęµ´KŐűCeůcŁNúT‹73ÁF?č˙2ߦ¦~búÇâóC÷šűBËf_l<âB™Áü»f\ ę°Ěč…†fÁ•nß®7®Z_zâ•FîצńŻE`‡ ~ †,ťÔ•ú_|łĆŕĚ2”uÄ—0đŇW1ąhgŽ÷ÝH“ZsĘB®ďxSc8ÚŢ^šż)„KsĄż±čZWeĚô`¶áç=ĺŹňkëç““ÁŁOM~sšŁÂ!V”Úě–—­ü„˛Q‹·"ă2/Ş7ľź2ľ ¬5;đ˙|mVÂUâśë{Üđ¨şŮčćµ!%Uk2x˛©sÓř9uÖe´Ů\(źN:hÚ±ý›ôýLWÂŹ˙źˇŮHń Ł×ćŽo9-=Ę­KĽ~—Ć®Ě{¸»±Ü¤Mâzí÷™đ«öŽcMvŕbWNćK3Ö)ó9AyŁëGŤ r}:9ü w|XĘq@Çfă7!s+ę"{Ž] ·ęĎ4ľc ŹoqÇ=Â6ßú(/ĺe‚…;`óÜşŕLŽ‚ţ`čÖ0üÂG–|ŤË×C•xöÚJçÉX+ FŐOĂU8¦‡Gîďí˛vűyů=żS˙]{Öm}ÔĹ4”}'âŁ]nÎßëÄŹoËčX§®ĘaŃßcąĎš1ę™g>ěëŢšé5±¤żĐgúLč ŻŮ÷ŢÚĘ_®łD×ăš=ÝáX*uU‡Ĺ†‹÷ÁÂę=ČőęÜĘ(¬‚Wí2č÷Ăy(}ke Gßě»Ŕ›o-ZľłýđÓ}ět_áîů̇m}MŃm}{öç"Żé‰/t".Y¸/vt\m|Ëß±Ďp-˘zf{Ďa%Ţ(zť; Lôç{ĢůĚu¬KŘvž3ëµá˙ŽýýΊ­­´ŽCłŰfĺç_S]ęÇ­%ý0z°ë{˝ÖúÎ{Îy Ű |Ż,;ŔY•OF#Ŕ˘łÖ7÷ë¶ľŤîÜ>')Űűç9sWą6ü“©c]Âq6Żý ÇOń˝f*Bű{'bř†»TßÍtť~ÔĚ‹Ś%_$}˛¸+u˙q˙QçÚ3ÁŁďwoچ˛ë >Ë ˝pŽëFýÍ]©ł`Ëűóͦń&ę=źžźé7÷·ĽĹśPç?Z˛ĺ_¶b=ůěĘg‚ˇň]µÖý1iő 'ýˇ’LÎgÝ[Ň5sËÂŹÖ•M­{>WÄ -í×ß;ŹńĆą˙ŇńýEĽŹŚ)Ţ{Ň(ń^úŘpLľąpçűEő }0'ö‹5™ç,Z‡ŤĺSśpęźćJŢzďíůâ¶ş©LˇÄÚ§?äĘ —}n^˛-±^eĎpPź)”‹ż ΑT˘ˇ‡×L8ŻG•¶„ĎÁá5eń¸ťu‰'ón¤ć7v;\Źs<Ö}%ľăĽPähńŘÚ5Ř~ß6 µî ćpáîď}Ď·w]ů=}&ď.ÉčÜčI¸čóřM†ą2nĂĽ{ÍďlÇaě]­KćĎŐá>0®PrVţýő™7TĚż+iăoÇ“#Ć{ąąn87ĘŚĆ}ăoęŚ1F?†nöť)Úp’ëĎë,—Ňb&ZŮux÷ăst°·Ńyě»ö:‡ş»?vE]ń&®ú—=ĐąvęßáëÍń”ľRűEłyđůůa?'ţ«Ńą˛°W43ú¶9ó–qçµ}řČş÷|F}(szýbq×ŢÄ“k1˙ #nA{Wę3cą=ŕkíĺžOM=eµ_Wâmű‰…˛Ź!öx¤¦ŚŘtâ=iŹż,:–ësǢ§›ľŽuř·:Fs{˙E'˝ˇ®|żéäk˙ â]ýŇóΊHě$ÄÔ˙ax¤xŔ¬}ů@:ăŐШ5sâgýz>ÔBϾ؟1ÜăL_TĘ«ŕńt¤¸Ů…Í{şđ;Ž ěדĂG›ö%[žf[ó’Wěǡ썠ŤüÍ^FżôoŹQ›Ę˙e}~áür#´ćš†đRŹú|.WĚ©Ť"TŐâǗבpţ/ş*żÉ•g–Óx™:Ż! zĆ÷őúSÝ;9ürç\ߌWaäÔ¦{9ĚţßMW꣇eď)ťŁę™{m]`ĎçÍŢăęŹBËwÂŰúţ€ýŚKëÚŹmš ]yőčź1?~±E˙Ú0oÝÄ=öoö€čsKkRiˇöz {>W^†5ěÝač<Ó^±é °«ş321|Asc ÚĹßw§˛>ý€x[Ú }»S/uĺŢĎW?4T,wërŇ ßaUăqqĚťnz||±É˙¤tQą˛ăk-ĂÚ5d$ž+üyM|Ťr=¤ç*6î\ď@.:ĺťÔ ›*wŹ;5ő §Z9©CľÇfDőöś—L–Ë1ďMÜlöŽ3Łű[ƉáOš¶uNE]ŢšÉ:cą˙ňÍ5p¶ę¨şľ˙Y熲otv¶<®…swęIWĎ«NŃud9|Ký›:›c—˝§©°Ŕ†Şě\ë=¬5¦îÔ>ľ>(ĺĽ~°łĺęž^|8őő‡0±]´®ĺşîčú«ż|_ڰó×#ěű«|Ë™×A+1o:Ă•iÂ[Ž/ËdľA|_źŽ mĂéM»µň.%ţÍgô8”3ę’j2ą*˙Ń’,{Ľ[—řŁ»ú+˝˘JL~Ňć7î7i :ËîßK‰ßluż%N;@ąÓ ŻߦqćčŃ?ď‡űƱ®8Ş“yy°w…}Ôďľµ§'LY§w <ËńüéS?u¸î{iͻ雲G!v»ěëůžÍa±!ńp&˘ďÚîÔÚ×µÄwýN1:)ßÓkđŤ¤qęµ§©µ×ăĘ˝VµQ~d`U=+<śBŮ˙0ďŘćĘÂ:˛Ű^éÚËp9ÝÄXdŻTóPň÷öo҉ýyoźîăó]ů·iüͰ‹ú0eÖČků¸íáí‡ŇÖűŰ{VE‘gsZ±ĺÇ\Ŕę#ţr»ŰŻ(úçšĚQňId^!^O_'ů3 ŃÝ;×q›_vgFÍ\ĽĐrTöekSS_ŞË™˛B±×­; ŻYwľ§ŮČăΖëÍŘĄcř©ŢŽ9÷«ĚÜŠ}s™(ě—Ăřý’C·9ě˛Ůs.–;[2f îMÜ׎x¨f\c'ĎłďÜěöçŢÄ—â{-:és‘‡ń í''˙x´÷ôŮt÷͵+ 4řO_9=ÖyKü!Čé׏.6˝iíΖ÷µOĂ• b†9Üł×Jľ „ţ­}}|uâRűäőĆ\Ř7/«,ŮxŇ @ 4(Đ @ 4(Đ @ 4(Đ @ üíP`ÇÓâSzcîŐĎš˝Ű…R˙Äźá>'Ď\ŘŠŞďČLőŃ,5rmNfúvwy—ýť‰©ííW{± ôĽIěb'}PÔ¶ĂŃsJµăŘÖ—đíî.xöÇ.Ýż/?ł!®™ŃŹąç.¤‡“ţ8÷|Ăj/áťs”öý›ň°I„wt…Ă}ć\_ľŰŕ;€đČřľćĚImµŽĚĽyĺżbÎĺ¬ÖďS§<$Ďl+Ţ,C{Ś#3Ó‘˙ó’#pŽiĘ÷€f×»tŰ•üe_ëúXĐ§Š°Ř6ŔÄx ďů–|d®ű?@ěáyގ˛ń0r˘ZÎt÷ý)©©wE//î[šý:7}íć]†w,™seMmŰ´ż§ěŔZčY źńŚ–8ëů%«đ˝ň™W>‡˙‰a„s»čńóÁľ39üo.=¤ĚňüßšąŐŕ›/Dję}>˙:•[Ú vň)–ü8ňźhňeŘ6Ń<»$MFŠŹă<ó×ĺëńCńő®€mó˙nŘ'Ţbř_7äĐřšá1}Ě„ž=l”M,&Ż®™Úá»ĺůűĆŔĎLś ŇZlCjĂEÜéëŹ_îΫt®Âüß~ú#ĹŻ:ČWY/mîśKľjěÓY·ŚíK‹÷ĘÂ)Qřž!~±}‘üŹ•đŮĽŇą ˇ śf' [3€]رČ1řóĚ®CĆq_9ó#á|޵˝Ş|»ř'ôĄW‡‹ O˛Ô5‚łôłJü{Żí$Ěv¶YŇMOsž>ŔR†ĽÓqOźyWţu‰+L۱dpYtZ<ţ7Ď–ĐľGN˙;ôWÄß’Ü˝NúJÄ‘y+ćŠŘńÇj•%Ćł&¸9´Ź ěW"}ćĂĆć7;)éŹ6ő¸{ v‹Ůväs|gŤÜT~Ëá×ůGěĎF9>Űc]ů÷öoĘĐ`Hü8§‘y€´g÷ťzŕÉ:3Ȭ}RSßńŃr6fĂĚ{őEŰŻĐbl jő…ňrŐ~ł„˛iŘg}ÄëűcÇŐÍfÁ^űľŚ€ťs“I?ď§›Žwa Ř˙~¶ßäńäđ“ßźvÉĘůB=yí¤Ĺž qđfŤĎ1ĽÔ}䍮5šó2µet¦ňúNuhftČŤa¶:»"šë{Ŕ'‹‘ńîÔs"oĂśr0ä”ômuľřÇÚjßČz+3šqůKdĆm[Ž·Ů®¤ő˙u§>áěč’qd1¸ÚeÉ '˝Éŕ<ß>¬°ËZjk)Ç W»řhTŁŃLĎĽňzç¤ ·fö cĎ­n}šs#ť˙*ł]ëÓíŻä Ç6]GR.J?ÎĺžyFrôŃFžý™°ŐłO+-gñň=K ż3ďőŞĎëyeˇÝťďüďň=b·É<Ź6l˘Gf’=ĹMŰôľĺMĽőź]WkćÂÎ…Ž_źĹř­­-öʵ č'MłĹŃ˝ćüT¤<•ňÚÖŮ…–aĂ™QOÚtWhH#ˇ}’ż˝(kťzÝŃ%öâȇhŐëńĎŹđyúMgRSO›~Íu0ůĚľ§óo-×’9d^řbmcćÚý±íÎůˇÁČ–Ń/8‡!ćöc­Ăž†żÜ[âw9ÁÂK˘ôP=řdľ˝…ÝľfFż†ŘŁßĂ8BKŮă"oŮď7u‹.cL H».űž:Ś´ăÜčüO?mxIŻFĚ—ť•ç^·¨uÖŠŔaĄň? ß\×ăXPNŕ÷fbŤN-qđDźĎÍŐS"Ƹä¶ń«uOšŃšőç×dđ\Ä´[ü>Yjjkă ç™v˙«‹ýśßďčj2ńú+qć?Ҭ|’ď ĚC¶Ĺg~¤ř5kjęBĂ']żŘÄc¤8%śÔ¤Á\đ]Eś(ÎÄźúšżőĺu®:[żóöF3÷¸:ŞóZ¶¸?ÖCx2Ł wý¨ Űbݱäß#¦éÝŢ%=9&$śÇśńqńkdýšĎFe˛Ú•z{ÝŻ~ÔŹw¸ýąÚwú y‘:·÷Üičsďh “s_Őőśw˛k_Î÷śgŃq±Kyť۵ŃĎžże\ś‰_8[ĹÜ‹ßňüŁ%3ęúŤfś˝©¸úŻÄI– ŚéD[ś„Ónćú:>‡Ó#QĆCbýőţK8_ŽŞß+ëžţ’á—ĐzfśIł™ŕ!ßü¸úëă|•uŔżß·†GĚčţKĂŘsßŕ{>S[óy7–[Ť|$Ă欛˛L\µźÍŻľ“ŘiŔç”ö§›Î0ő\\Ňw…#éUĺµ­ÇžhYeő‰ů@ľđoÇrÇ>ÓťúNř¸RĚ4Ôv„ÍçZó”bÓĘ(÷68ŻĹXóżXßś·ŚžlřSkĽ+Tźq\_Šąf9uvt=Ô¶:űK+ß©>Q>zßűĺRÇ'ľ§|Žĺň.ż¶őÝÜä[‹Łż;Ň´©ůrôgĘŐµSWGłź.­ĂĽV—ęnÝŻţł-?ŃAµ*ă“´Z.ď´Aś±ë0·=ś˝řâSvăăŻ]ŘŻP·â;„3ěżâÜţ†N”uÝ·ŘŢó«eóOżiÎ+ç‚3ímĽąŰś%̦o4çżjtlľçŘć3˛çbÔeŮÓ#™·ŢbáÍŘń¬Ć•ŹĄâi­z -˙ll l^hü$–)´dJcĄđŠcĘýĂźt¦şŢ㤦^FĽbĂŕaúIą]Á¦ńÇK2ÄÚ<~SwoşęŔčyˇłë>łĄ™ţ‹¶#–<ĹÍźhë×9Ľ„Ýí×C? o{ô¬Ž7#Ż"ĺŢŻőń‘p<ţ7nçúl#”ýudrx•3řÄ•K2ŰxĚvOú{ps/ď´ŽUůűĂŹYű Ę/{ŕĎnŕ.Üqž»/Ćz´-í7ŢšQެŹß˛$ă°¶;ŰűxWđ‡ŽĚŹß]ҡCn.ÁĐKŤü ÂoY7rÝśÍę÷ÚZ3k /ßôőÍăß2rMÚp ś>{/ßeý¸ .=˝UźŰ:•Ďp~~˘ĺXW)Îú=ŻĹë®wău,k2Ó#Lšý­Hú±0ÖN»\–mő~đÓŻqžľĺÄŰřOWöBŮŁÝ3b•U[~YÖž«“Żöű™–.Ó–vżk<~á ÇĐ_bÜ‘qHŕL8˘[BÄ»Ă\ěŁ˙$W#żË=ęŇ ¶sË6/”š§&wń@l´Hâî‡#ź?Ç)6}yTdţufěŰ.N©©ćţGiχ­ľxŮǡ…âZ­Ü¦ńW»¸ń=yʵ$âEîođ.^ę҇ﯙúwßo>ű[řsŇw`îőu3I87ŻŤ%˙öWű6«|ôů[Ŕµ÷‡ë¶—S­ţĆłhP AhP AhP AhP A]Kî_[gă罉7řö9Sg1–ţłóOrĹÉ™ ÷ą‰ňą{ô…–wáěFb‹sźß¶Uŕ9®{ž·Ł?–;ľËO8Ăv씡“V$.Î2M â3Őő%údžń­{ćÎsśÇLJ=ˇţzGˇe÷ÜĄü*śĚ?&|™ÎcôśŽWžkđüŐI§]™žęJEőÜťç›z~ă¤? ŰĐG#Íů–čµSO»ßďjÖ‡˛W:ĚČó5äĹ„üZś˙Âä~Q\yOäÉĆ3ÚQĽ¨33ú…’íŘźĐö`źŔP{wŞ6Q—¸ö,»÷dđF')n„™çăČ“ ű§k _Čż|ĎÓßq'l'?gÎ ‰wŞĹÄ­eŁŔ÷ —Ďr6éůgy6ÓŔŤČżzěR~«ü*ś„ď©)sţrqđí*nĚߛ׹:[r…”sIôťŇOm Ř˙) “°ăŐǧNvuˇ>[ęëŘÇžŹ>¶_$ᤍM“ž§2RWj?Ħ9ÔŘ>Éyó°ýla%»َţŘ”łuŕx36‘÷´ëM\‹ßC'©Ť†mżŔ˛<ăNo^Öń ¶&îá"śĺÚ(żČźĎC‡QoÁ> ýűW¦pŚâ;–ŁĽČ˝Ôů[ô‹ćü?ą8‹ýU @oÖ ź5·ż°üRü!¨«3áŻmµ'±”Ľ;ôďú©ŘŢBâż©<ˇśüť´yüt䍹ľ=ĘOě)§˙Çă«-ôi}ݎ‡‘“Ým¶VŽciKĆčrŢ‹¬RźÇ‘ .5uŚ˙`Ć'âGć{^S˛żŞ,?Őő˝Şz«7±Ź«Űę‹­Ô¦rIż»“<Úně¶>ůůžťZöŞÄ-áüÔô‹ÉÇĺ±ň”r^ţLßŃ7tĹ˙DV΄?čé†fꯚ-ÉŮ5lĹŤýšÂP~Íő==ţe—oĺďů[ěh„6cą÷¸}ľÚ·ŐžŮú0oAß‘8SĘ ©yiţŻ®»T×*ß˝k±éŻQ'}p'}cɫٰ9<~ҡ¬S¦uŢY ĎjĎXŽĎU§K'ý—şóš†ţ±Hö€­ěO ®˝‰[K1é„őřż±Ą‰Ý¦8ŐŇĎúŢľŞľVx°OĐ1\|SŘ‹íďgşçřÎţ«ësÖÍuÍÎ:Ż75vůŃ}ŔFw(f‚Ď~DzśŻe6ů~^3ž©]nö{Úß`Ć+赺ŘZmśxĄ»®gűŦIłčJOOÍńĺz„ýq© Íśô5Î%č#Ôkĺk•™ęňŢŃ^đ_î‡;şvv´f~\76Ý´±ŚČ—’u€×ţ̸gřX¸s‡|O—s$â-dFźŔîٵ ťk}ünÓřuQ¸Íú3žĂä0ýŤF1vß¶hܱ/NOĽÍťó.„'ÄYűr p˛óĐ€äŤ\Y10ëe>8ó[öąÍăŚ3'ň=W»z\źĎ÷:š\3óq.ďUgł}řԮà l«łfźl.uTű†:Śú”ă&}çÇr˛ţ™/žö÷śűPżžíĽÓ7&Ě—7„ 1<—ô2ĂŰŰ&nwů1׺[<~CçtÓźĚŘ™FîpcYs®4zŇ­×Ćc®÷˝‰ß´'î~ěnWEb©łÚvt`úä]ăkáO±żYĎUŁ}µg2žKË÷ŽŽaŹGćĚ|BzT+SíŮĺX—ŚżX¸öĺţŘŰMžtń?ś+vµżËýÂÔŤ±íÜĚ\쥶$Çi5¸Ęźýp•Ć4a|śŻ>`OĹĺÇ\ů¬őRŽ©W(\sO7]dd‡X$ßµć;µńšé ÷(ąćŐy|®ďáhc޶?—ëÓx^K\“b|1xËĽyvťAY±ç»ÔŤ˛ľ–zó=Żpéčµ´;Y}4ž žĺßزmC19ĽŢĘË”˙¦^nÎżĘíż¬ł?¶O4Ź\…‡Ś Úő/üž<@.ęsÚ˘đA6cuöâ]¨rřĘľ±Ü_#+ ŚŻăýéţaů÷Ő~“ŻŔ/:Š=_o̤<żŰA\`'–˙BŻö…ÝÁÇ9B˙rřĆEIg¶5ŐubL>ż4.Î.“„ß^÷řb8'†-ŘçVŹČ¶ŕ2zŮRĚ2ŁgÔU¶yÎF^QÇ–ÇP«Ć“ęĎčW¸ĘĐ*”]mř-q¦ç†Ż]'ĺăČĚÁf~]«ß(-z­µO`Ă1ű=q>Ň•m[Ő*›p~ŰYhyˇˇ“Ěç„>Äy¤‡źâ*¬E\ă)·Ţ…âh—KO´»ëçj°Ů°T{ŻĎd&ŢďsÖ%îËÜlf7ç7EĆÇ÷02»iü"_|n–çxrü(mxëqßś»ŮÇQŘőĘľÍ5¦ń‡}ţĽúľúŐó2đofśóČýÝšq N­đŻcé‰á »‘–ůžF×~Ńë …nşéuftĺ<€˙°¦AüŘcqő=ÄĆůŚ?ż6”ňe¤¶tMíďm}…˝Mß8Ôťâ`ę!<Ŕyđá{Žď…!×MătdFDý!Äľ®c¤ř1Ä+9­ăĆÜ`„ű˘CjĂ.Ľ ÓÄđk0ô’đT×vä{4|Ö=ŹJžlşĘĄö©Ě˝˝˙‰3łşáYNśyWÝËPęKłăŚ˝I~řOĂ·îŻF7=Ţ•‚LV–çZq[ß8ÎřÖ„ßK¶Z^mâ¶ń[×m}â‹č¤ß]ľr<ćó»?v¶7ěpĆr‡Â';ľfę…Ť+aöăAżhř:ű!ľŇe>ÄQśµ<ĺ»Đ˛§ˇŤ /ÇŽů:'¶ßŐóţâ`Ü…±9H¤˙żŽúĎ“fÇ»ä‡(ńg¶˛CFŹP®‹M_2pt§>ed¬Řô‡şé®rřô÷\Ć?ʇNŇXA ćpŻ00oo˛`śÉWŃI~$oöŃşSÍOÄréŻp-ŐgäĆŹUë÷çOýđĘ7ú®ň*¶TÎŢňLÇu>OMµ÷_˙ÔôµÉá?-zíčµ7óÝĘÂAľ¸vĺóiY|Ŕ̇9F›Ĺ>üľ®›Ţký÷F«Ď︧™*›Đo>ÎŚ~ÝŮŽóK1Lg†°ľoÓ;p&ű§Hlµ{}şéFö¨S¸ eE='ĚßÄ~âžË2Ř>–»Ľ$×~™ŘÖ÷ śm˝ŃŕŁó;ÖG=}|Şgő;82ďa›łl>¦čöĂŢÄ“č_„›yL®Ă>Ęǫέ¨ëOŹóN~‹ĽíÉŕ§śĎgcéhˇGˇĄ7 qĨëZ¶>L«ý!†g#˙í:'‡wŇď2±Ý<ÁFâý•öCŁĐŰ×d~ĽöâŕsŰ×%Vůö·eťýÄŻzĐ•>#mř/;p ©Ł<Ëől0tżaMFâă!6/â»§°~ď)ńß–]Ş5ó†p(;ĐĘžۡ_–úĄ|gÇőĂľ”Łce;á\)6ÝäĘŘráh·Ó•šrĎ>9nŢ;š3đ {…ťtU'ě‘ô^ŘOĽ¦˝7ń9_ îŽ|éâH°đn#/Edę ŽŔŢôŔ?îR|÷s§8‹śUę›ĘX[Ôĺ çĂgdžÜ-áőń[]ýŻşuöă¦Nâęí,ţLƬţwČ«čę®Aě~Ýš9ŘČB‰¶÷Ţ)qtT~U*DČMkć—°VŻovź+â4–ú¦Ŕ„yu w»Oť„sżč–]$ŚĽ§śČ>˛”ŕŇn÷ÁrvHdÝÇXÖŢ9î‘“îBśźžŠ9ĆaÄJŤx2<{ť»ëˇSŚ~ËőčňăwG2¸Úĺ]°đˇµcą˘«—6ŹŇývwĹk!peóą ÚŇż3s('wq^H}Ď–2·MěTsţŹ sŃe›?>[čÓ€łAhP AhP AhP AhPŕŮIŘžŕ,q%\Čľă$…¶Â"¦Ľ[›X=Ѳąýâ`áobvFĆĎBÎ(h{{ň|îoťłz|Ě| ńJ‚đ›ů˝9Łä9÷v÷˝Ë÷|Ĺě[#¶LÇlŤ 7ĎĚ[3w†/ >×řIó·Řä ˝‰˙ŔŢľä¦ýý­ßÂäQ[2|ąŰĘŔtÓㆯ;[®÷ť×”Ű›čYkěŁĚť`l™ĺ CĎw„ý±—ŹMăš÷m÷ă·Ú ŔÖ¶ÝćLš~_´˛}CF żŃĐfEŕë°Ťcě ÁYëáoŢw§Î2´¤ÜÜÖq×.?ç@^cłC;(ěѸ;ůßŕÂFy&Ľcą}ˇÇäܦĽżĘ¬ňŮ»në‹™zh7Ä>Aů#l,v5ÇďEŢeř3űÎŘčź+öMôĺüNýâŹĂ…–§\xm|Ď®.`N#Ň|žľîÁ’ΓĽ«|6ö»"?ďştŮűxÂA€µ†?ď:€ăPÉŽB9 Ľâ™äXnŇĺůçźŢćŮ+ĎŐYŠçńůž„é*ç™ŃWřěµů|0t¶Żmqy®‚} Ô.WlÂhżűFΙwŹşXáˇ|ňü• Tw1§y,ůZ—6*ëđ˝6Ďě>NĽm?w­{©Ż/·ě¤ż ›¡¶j_<Ô® űĄ<—ďv¶ Æć’0}·ČgâČ\„gv®O€Ř‡‰ °ŤMăßZvż/tšĎΰ9˙Ë&Jň_Źä7}?f‰!F‰›ŘZÜG–í±Äz˛%Óńý‹ŢďŇŠtZ ˙=–•7‰[ĺ=Yş;âäÁ °PW‰ [¦~]oüĽĽ÷,C%η!÷)ňÚ·›š2:MeÜÚ_NŰóÚ–/gŚwÁďľÜ˘źWK=îČ'úĄł.ÉK&°©ĺ´9ßcú .2„xQ?Â7ČQťĹ: -!řÉzń·Ů®¤e‰±_ěúXg˝˙›ŽA~¸¤%Ńa•i—ú‚ý…6°«łâo[/>#Ď Ń»ÓM7Á÷d÷™ŕńżH’Áw`^rŹżÝ©í¦On›žţ{•çŘ _14Ë˝Ă)>Z·>=R<>7§›řf˘kéż~8f†—öŘ}·ôÄ+Ă[FsGC‡ąs2řÎD~Z–S˛V}b{%4Dž+WN˛¶oČâ¸K>™lÁş_bąÉüŔŕPĂŢĽ-ŘŘájĆĽůđVi}nçƉc}qƤo3fj}ňó †®S–ÖdŽô&ú]ą–őQ5üŞ?ŁîcźŤÇďň†”(źc)n3]íX]ş^!Ścąseg1śN÷2ëÖqjňĽ‚ĺśň¦óŹ™`•wÍČ—öÇşc…ń]˝L%uަ¸‰ĚčŻĹ]›óÇ„Yß-O|‡‹×…mź‘ôÄ*Ě•?hć׳ÁNú\;ő“pâîŁá‹qai-V‰Ďlőđ=çřąľĎFŹĘć{ç«n…ʬ—n1XO=˝ŇąrŁtÄ\¸{pR¦ć*źô넿©++˛gâŐe×[~Oľn^űűŇ8,eD—zŘő&ĽµŞ÷tˇwś[ŠŻŁ7˙›¬6ě,«´›ďüKÚ ÎÝgâi˝łů1-cÖ_>˙â:*á?ŕqß–jWňEÇÖ đíÔµXµo«={Ľë_÷—ĆżŠ¸P'ę|ڏ#Ź=b—ÜT=fÓŠ0sÎ=Ú űťÎćń?Í©/ʧňYęśź¬×NúýŃŰ&$Ć1÷XŹ/Í×egCşđűŕ]‡:§áŽQĺ5͇WŞkGs‡¶ŻĘd^q†X–kK©Câ·qĽ S<ţ]WG”Ă·ĐßśQOQ—©,U“˝Ůž±h˙ŰŃőYwa¶r|Żs@Áa¨Bç“°ëŻÉ›…ŕ^ޫěÖ%ö‰–Żká |öÚźźlëüĺ/ ŢUĹ«u±w÷ŕĆLg]lWyĹß2˙ťěäłöçŐŮ?ĎY÷) Ůź±jäřLđ10\ź6‚qÝřLýý/ÄREşËM›Ś‘$tźľ 7cżć{.,Á6ż˛¬˛Â~fóś´äö}k6ˇĂÂţľ ßĚ} ®Ś1Éx #Ĺ.×/Jń™Ë•ôĂZ ĺ qn8—÷+–#ĎÓ3G©§ÎV ›.7cŢXŽ1…“´'Z>^Ď~'ÝRšKI틿Vyîď#~|Owě\÷¤ĂýĂ­Qřň™us({xÝäZ Űjpf|2ţ–9‘đcő|dĽ9ź4űD…–+Ă9ě§OüÎŚă»ĐV Đ˙µ}Ěk řńÍę¶gŔúCܚۮě?Oăě¨?– ·fnĚ4çć<›tˇ rL9&5Ő†8oČ?î\ěgňź}ćâJč -[Ů/61•Q·ŕX~µÇĹŢÄI\/Â˙îlřÝNřd±ľŽ®?ÖŔÓM/6câ3Y§<ĎÎ_Ź_´! \ů¶ĎvL_ŕž‰t§0ü.Ç—żĄĎxŘ &(â<)·”ř}X©ß - Î gpflNďo6˝kăA¶ÇUÖŇšyk©>ŹĎôeż×˛6Żµĺ•…;\8ň=Kßčő»Â0ß±jbXÎ’‰só§:ĎĎ»­ŘtUxE`Č·Ö§O4}@ö<:(ţ¶Í|M—WRm¤xyx,÷Żn^ …ŁüęÍl=şăLŔ•CYOűżĂľ(äÖ~ćݓ֬,wµ«ËĽš—îŽp–ëZ™wK|{y‡śwŹo,÷E¬ősáUůýŚNnúW퇮 žŔ4b"ô®|GŢsż5ß+r˙2ơ!,”O[¶©Ç(á ŔćĹ.ý‹ŃŐM‰gŤ†Ţ[!‹ĺ~đě;˝‰ ě+ßę{xSźń,@}Á±¶ZF˙Ň[Śţ°u6Îł“§Ł)żźyך c-˙<gň‰¶ŚoGşaÎčĘ·¬µ7Ń]ü‚1Żď3ĺ™…6 ”Ż3cŰMý_ęĆŹŻ—÷ΓÁ7G1˙ë ü 7lźÇ'ŢúŹĐ]<Ú]É~€~çÁ®4•¸§ŚçAĽîűÚÓsÇ9ď륿Kťµş=;đ;#«ŠŁ×ŞĚÉgâ¶>~ł,ś‚qű¸CŮ»|úŞ?ÖĂ3ě/¬µŞWó®żŰÚÁ|=6Ý©ýĚXcăŞ÷·0@ţ€ś…ą“‘Ďňq‰2|cîPc0Öëď2zp}|źÎţXÚyŹóAßüËn{ůV¸sÁ ,OEń¤ č:Ϩ˙Î;]ą&śţ}D?ä:?ť~xomý_íš_“Ă’·§;ő™đ™1ňZÖő•cu ßň ssţ®*ű€Śń÷ŹÎ)0„&&·MD"gĆn­Đ÷»ËÚ­:éçvźŢNŘąöű ­cŚ%ś.ěHM }ô[™Łxu#W•O&Ľ7»Ď]ﯮqÇÂĎŻpăF{R?{Íůß¶Łë8Ä̻ؕߑâĂ»Ażőŕśí®Đ’0xo+ňĐĺŤzŠăŻ‘ô:ŰĹÁs۝ßkâ=ĎVçłĺý`脊yŇ–Ń" ®Ă:Xb*صů;ý3Ď*ŢΕ#ĹXŐţ Q·O̵®gËwýlő͡ň=/vç Ďp6(Đ @ 4(Đ @ 4(Đ @ 4(Đ @ 4(0`‡ů7ąźYŽóĹÁÁś)cö±Cٽ̙1żŮŃŐçŢ——Ńß­™kgýFżÝ®ůʏ#ű—ňLŃo}ŘŃř±äцˇ—Z8˝Íř›Ň.GínťČý`ŘSYßíŘůařź®TŰİŔ>5sl•ůçËyşú¸o?Ţྲps>§nţ=ĎÜ5ĽżťÝĺWÂů€97T;•šzˇÁ ą^Ś 0hžťgžµf>‡ś5« /yžókŘNčŮ-Ż<Ż“s|9Ű‚ĎrŢmŹěčß-Î'WŽ6pĐ˙жČýgđâąůĹgzÖßËöP6 űú Ó$jöö[3ă¦č÷ĵĐňk‰çŇëĎŤLďÝÉű„óÝ]*ë[ţ«=XxżE÷ˇ“ÎŚ]ÍŚľĆ•kžÇ’ç_ŇKn0v˛|F[Ď“ń{Mć(lâĆpáwŮÍľúř¬5óĽgcĂo±ľáËó·˝gŻpľgȡ,Ç’wx)“ß/ĹĘ(†ŕ;ńÖč¶ľ#ăO[žů†NĘ,¶őˇ˝KöĚȧ?řGϢWg·™şűc/ĹUÎđŮć`čZgËč?T=÷ňj«ßÝůíǶjŰkK[”UÂnŰśóß&ëLžż¤”~Šł\i÷ˢµź ×ʲá,Đ!/ňř¸i“¶@jóAÎě=ÇE§›lűű@@ěž´4ó?cdô1ŘYĘĽgĂ+ř‘Fń¸'GZú¸ţdĘö&z–e®“ ŢcÚ#˝a;bäUńJ¶nFĎÄ’ź÷Ů®ę7Ý©—"Ä .¬ý±?»9ŘřŤú’Sgíčú;ř×·›|őÂgÁÚď_¦”XšëäđFŚ1ű›>ćÉĄä@ N6~ŇÚňŞüee±-ôŤ˙Ş9Tvçv…NĽĹŔᯭţżşS'¸í`L2vú”kčř"u™ßěż”S۶ŹţŮ÷ďą4ŘáňweˇĄ¬?Š<×™}Fű9ëCÎ3äŔŞżź¤M5ćţLMťçú#°Ż%ś7›~Wh™Ţ±üÚ<t~Ĺď’‡óŞNz/äcYTdß+căúŔ^ť™Ń]z3§ş–×ńP×óš >äă‹çĚÓ7lOçŤ6Ěě›ŰúÖÂWúŞp$ý_= Łí;Ąeuţť ^Őx]|Gú¨ťťúmú÷»2¤u.ćšąďööîă|yÓ:fô+RxËŻŮďD¦›ľeôa)®tď˝9‡źĎ‚żö?ço]·Đ›_lëűC]íQz˙VŇ[”W»ĎVË{F¨ĽżPv¤}ă‰G –éÍ^Řé˘_HĚKŻL%ž|‡ÜĽF®»Áĺë¦ńă‘óĎłöZZÜÝtÓ}ćšó#%Öęr\ fĘ6y©ăoóä« ®Ů â˝\bőďęxÚu’Î÷ÝU˙MbEyČ÷eŐł8\1žzN7˝ÇÔŮŰĎäą¶á ®ž ĎuEç˙ł÷-đŤUŐŢŢ)‚ á1ĐÓ69IEHąŻířŤHDiń‘ąŇ˘\?Z ŢE  ˇä*- H@ÓQ˘’Ž/ ^î•”ë‹oý×Ę:Ź$ťĄI;~'ż_{’söŮ{ý×Z{í}öYkmî× č™#™G~×­ăµ—˙ŔGőóďóżŮ´ko ±Üťë<Ěě{:^čçžă˙FpyÜ0sXBź’ůëĂľ\+·ž+?¦§Ń’@OÔ”1lK8pÍăß7řňŐĆińşËgsz(G1á>ŚřF{ě ÍËB”Ű©ÔÎÖh—µ`ČuJěŰd¤¸Uť^mśĘq´´Ďu™îZí”K•|Ü?VuD›˙觉ň+á#uśI#ú&ĆL;¦—ŻEź˝mŠů4çÚ[şń7ď-Ź˙Ę%şshYâ~ćłäŃ] üWËtěŚa®´QO(uśÉ÷éź+íXő;öţ"­›ŕȇµ%Ěz zÝuËËĽ[S|ç1–ëvnľ±ďđ™ÇUĽr·vđŰľć…šu>¤tmý(ô)Ł”[?Ş˝ŹÇ6ŃúظĎażtÄĂSü†)‡7†ÚăńĺÎ4ívˇ©Čzu÷ĐŠ@Ü@lăÖiu–±¨éóŁĎlý~é?Ř3ű»ŚÉiËĄľ±_SNóKgơFČksŐ~ę3Ö,ˇsN:¦ÇŰK±D¶~7}Y;?Đ>ć‚Đ5ĘŮÎňÍG^6y.c€ĹĎ7úm8űŢ’ÎXôéü˘Ď_۶q÷_Áôöůź.á¶ę´cśî;ú’âW\ĐČĹžóWŻýłÇ˘o~)~@óKIMŔ ¬Ű2S ¸g ŘŽŘ$[ĚŘ?†z%oe~É—fLŻ•Oŕ/lô‹âÜ™ŢÜ~›őÁZ rý#{’gg˝ćđ˘¦BSO 5v÷?äH›îyw[°Ç ĚkěźU!Z'˘sÓc¦Ň”sđz˙‘fýU˝€ýÔgܵů‹mvŃ^˙?÷ťžÓx¬B*źčąeše-ýĎú śK{łűŹďd [«¸ó‡ÖűˇôP«ň6<×Yd¤ąâŚÇuŔö(qĚô~b¸żáĐůépË}ÂďŽä2Z/Éńó©®?Lwźý<枣#9Cs“Ł?Ł^ZŰĹžň̸ýµh6 ˛ęWPLűW)fě©Ĺë-o ;ťúëöÝ' &<‹IžÔ™Ó<˘Ä·-é¶\“\¦Ňz¦÷~ˇ;rfć˙żŇtDŔ[ř>˝[ľOćdß˝„0$ąo}»lőŮôÍ˙ę"s®\Iáôˇű°]_j˙ťŚ4Ż;iŤnßšČô•<“mĺ”ę^*Çm=ęxŽúh­ˇmU´•ë´žŹ7ô‰ÖgHţň{ ´|ˇéÚ3č™ŔËM' MňţuŐňă-üŁůvě˛sR6ĺ[ĂxËm˘ŕ”˛j«»®uâjˇi`Fí´“:ç/ôkĄsěę6×ăŮŘňfŽOײ“‘o†)nßÔCĘGŰ`ç ľË'šřĺ ó9ęĐş`ű˘‰÷“ ůí ß;ŁkĽÚľýĚűiýkAŮ»(‹n§M±ÎS^=¶U ´ßA4±Ź-~Đ*LXcl(ÜS±n$Ď0Ď‘I× »âČŰRßĺ—2óŃ`ŽŻĎY ű#vżÁ=MŤ}´‚Nň· ëűXű|KĆ7ňŁ!™&(Çă`±/Dľ)|Âű~ĚQę¦ŰĹgL÷qăZÇ7(O ä Kď)Jzl—ŁČ…ňÓđ5ZŰn,ŢE󓻨-‡µŃÝ ň#á|xžHýÇPĂfăÚřŔÁŃ‘ ą¦_iĎóČśâďŻ_ÄLďOh~‚wŃ´7­%8iP,růaÓCŮ«¸¬}\Ćj÷ëóbjlfÖsťmlŰŻ®ř«,oŘ!y&÷Ń;CZżţă§9Ď,ö/x”őď âĆęiua8«ůrᛳ ąÍµšmٰ6Ą—ěŃÖ¤gŁkÍçkž&mbL¶cĆYř6§/dݤܽe¶Ůă95z&óýzżň-šAÂű·¶%ÉËţEéJűśô/Ĺ3ʬc9uóÇ5ĹCEßÖk±ÇÎ2č·dł#x&ď}±GÎIeýĚţôJźĽ‘e?:⣜ŐŘňźVŁŃ‰YôBĘšnděÉüÇ猜Á9ţ[ŰdŢOůŹî ¦‡Ö2ŢôĐĹF ”źFĘő/5ćkţĚ[Y7°FäÔ}y§î-¤=gÚşŁo2ÇFmc.é=ůuľŇÚ;§d—…J#uE)4rÁ=dʶŠĆ[sśź‹¶•¦)ßWXéyŘ#ů.›6^ë^±ŮČvź8r»©Ň˝µcsú-AzOE¸e_#µc‹‘zŻç¬ľýDóŞůłÂÖh¬ĹőµůHë”oC–ɵ3ľŽU ÚÝ:]¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9 ň=ĘëÚ´÷­őţ‘×»őŽwu»ąJ1$sîť”ťÖ-}Ą¬ýđn%ߔξĚď)şâ·›ď/:’˙ÓBľ2&ŕŃś–˝@#I{Ţ–-µ6»×Ľ…gM9áý$üCđ®ďń'Fňőjőž`üęg ×ńWüwgĎ–ZĄÎbY§˝Ĺݰlý(ňó´_Óďx‡÷Uö˝ż;řĄŘźíĽĘä§Ţ;ŰGĽ‡ďX¦÷-äYátSľó]ÝŘ@Ń•ö’{™üú”îžčĂĆşěÇŮWńa©×qĚĽ’4ËŰĎ×ű»·°łU»˙©ĽOŢ«ť|ÂŚW}§ţţú ćŤSőŠ#'ÉřŔíˇÔ©ä÷ô;ćÉD÷^áÉîw"ţĎş\cî+”Ďa'ÓÔ'ÚëH>ĚíC/ý™ă8ŽŘ ˇ’,ú—7=Ěď ŐWHü…ÚLď'đóżBŹr…N`?g{ĚúKGňăyňo=ßh$ořܬÉ[ű 0N»ŻłÚ%Č\ű¤öS•‘śď/áîç~@î‚$sŮďĺ{˘âł çôŢz M;žĄ=-tß8ě_BŰÓ}ôš~K2.÷Jűü™íò>H9ŐąOĘŇ»{ÚO÷b±ŞrĄ~˙'şď fz×sżż(Ę-@:ÚśţOŠĎß#“ÚůúFľ›1FŽJ,ڦËóŕI®óso.#%ąć¨ďÍý´ˇQe,wÖ­|Óv oňĄń1Îq›#_šAýľźů7ś˝s—UWŕżhďcJ—ý¨ňIĐŢdËëLű?X¬S†ňöąęz‘ňIŮmĺĆáą-Ú§ýíhŻľ3É'ĽwĆ|Żěó%šr´#÷ćIăô¬”ú÷im›bOŤyH‡Ë?"ĎęvĎ^Ö)wťźŔ.J_żqĺŚÜšJćÄŤą´#ź'(šŚ<˛ćJ8㤠×ÔŹ˛3R˙CóÔťdć~x;Űŕíó?Xˇßrň\ü8¬ßQůSô-ˇ{$ÇZž©Ö°č™uQl¦b’ ;#÷δö+ą†őOúŁÄŃÜ=t°12rFëÚ<ü ·$g\N˝DţŃ—ôHÚU;ŽűµßôDW›6MJ˝±˙´–SšG¬ˇ[ŕ7tžěgHÚU~XGéŇ6Ę\qč`{f˘Č´aţ¦íýTĎYGąmÁvß3´ÂÔcĺ%xĐç˙Ť9×y#hGFZÚ(—#ç` x¶ˇüąUę¶pZ´Š ‹7—d$rSzÔ6ć~RęçŐë°×‡ďŔ{ qâřĚĎ;Čp÷PÖ´ŤríźűJ}™žŁV…ˇ×˘OČt3Ź•2ź:µŹ•Ó‡ß* Ý#—ćŤ×Ążń’ś1ŻmťvŚFĐ+ČYő:ßĎužLó’ď‘ =rRţzFu[9=úJĘÉv‰aĎu ;eď_ĺ¸A/hÄÜśň˛Ě;’Ł´Ţ _n™“:mEąĽĄuoá]„ďýáe‰K¸Ž] ďjÇĽŘQ˘Ďż»©óJď?{ěŠ&­ő(żA3t 禗5®Ęs/ę™ň5Đ3Âąđş˛eĽ‚˙qâ+Ężh[ŰD˝Öx…_3ó)4=,n`™ ]đmŁoSlĹ1¦ y~(—ŹüŤČ˝¬}Tu$‡ÚF[™Öö•ëJµß¨ŹbÍhőw…z˘ś1+×VĆbĄ|ÉĐ!™;ˇMÁĂřY뱲1qËň‚íÝK’Ë÷u$â±_ůQn'u>‚2དjâ:ĆŽś‘9öÖx¤óµ_ Ď>÷ĆĽ öM1Čű>čű;Š—ĽňF¶9ň>Ćâ•>'[4Č5±źς̗Ťy‡íţAkˇéňš­ý††‚Ś1ř>>đîŇž6˝vŚŔ,c§\Ç3T®sUč_;ě«>[Ůď˙H÷K:+÷«M@Űôb7đťsYľK’Ö3ÚĂűŮČ7ů/s ;Ćpoác”›čCťEéÁâžć˝…¦ŻSÎ%ä˝°îŐ=q¦|űSľSc7ř~TꂝšÚ~‡ÓŢl›tŁ52ÓV•Ë}ą1·7ňrŇű/±śěş sP'Ízýąéü4Ź™ňÝjĚý§Ă&8ďšů_EßçJú©{YrZmt„‘oö@1÷€±ËĽéó˙ŤěĽäťkNO™rO( Ë2Ĺ ĚĐŁXl°â}ďĚ#›ľĆ>˙ŚYçĎ(©ĎUR¬‡:ôRqĘ7Ž1í­ÎKě}e(g5Ť˛ß~ăC> { gë÷ż#yëWÂă#đč| TĐš˝)CĹlď‹ô8T%—˘ĐŹąGWüÖÜÓMű%Můö uĺ#gópö¦¬”Óú\GďM+rËئ%ůeO Ó…&Ľ’ĆAč΢ôŚ—š>=«x•¦•±ĹŚ{˘Űz– \CĹ…ôĽŘbĐ>'¶u.äܱ|QGĺ‰Ôě-üśuGě ÇCůn+ř«4ĚÖńÉÓůť ćbk±¶đtĹ]ű3ĺ¤ÇߪX'Ń>­k«żágąŮBµĺv7Ś=˛¸×˙ ©{°o:´ĆTŮ'MűÖ‘[Ű8ŚOe¦w8ü\ç—hź«ßňţăß4ÇĽ-·Ň»ŘĂ)żĽCŢŐďtĎşp9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ëúq`tä÷/łWh řżłŮŢĎfľ×%äwOq`ߢý_.ŕw6É|¤ôާ~tľŃ–hë0Ć”đn¦†ÇŮď(ĺ=3|Ž~lľ»Ľ¨ř‚‰_}VŃľÄ= ®závńîŞĎßSAg¶»#tlbµů~¸2˝~Ć»†üä÷óFńż}íŕMź˙>ÚK;ĹţĘţĚůááěauâžŮú±ů {Ô`ďn‘Ó—Ă©żń•©c–ń{ĺžč(ËţŞŔ#áOĽżĄ=ţř\WüNSGPf¶>Ç%nĺţ§ţB|§đ‘ýČ—•iţ¸ńďĄýŕĺ*ţĂŘp„~G^Ç>˛¨WöŰđxVES>ZµÔç[Wqď{„°§–‘J…ÉÇŤő’âi ‘›ÄókŚ:í‹Nćź$ ?ČÜÉ{‘«ěÚżţě ˛Wß‘·Ç ĺkzhŁięÖj¶Iý?pVüUĺ:hTż/ŕ_+¶qQúf̸ĘÚăyď%®|ÉRţŞŤüëöăŕ)ßĺUâjĄ˝Z˙żm¤Ą…b­ĆůłÜÖeďĄĎ‘ŔÝ4.iŰŘ»Jľ[>‚Ŕ‚¸2Úµ yY_*řśep1Dŕ©ú“źřM®´GĚIáőcóë>¦ÁU}˙# |°7ăëK9 ˝…r‡ŢšŢŻ-=´rÚ}GˇďYŠ1Ö=§­z Ł#_­#ćťmăF?ů–ů÷mđĘĺ>ĹŤ”iłËŻëo‘Ż…çµoă™'óź­9n˙ńÍ6ĽÚ%źc–1ú/ů—tŰI«âŁĘßăYD>ěÝ»n5/‹Ú®XěTł}ʱÇx3˝?3ĎY5ĎÜ7äňóÖqV:¦|?0Äo­źÇYä±l’`‡Ěb±ËŰqŹÚf×[ىW™ŢĺqŁ˘_ăžBÓźJ1‰‚őbLg±nŮÇő™CYYüóíq–mĆÜj>ů1ßnČž|vY{<f´źŐ¬”×Ĺ”ŤÚs§.Č˝ężMĽŐŃ÷ő7Gî •ě¬Ů\ý6č˙ŽŽmÄÇ%ĽW0žr?uĐEyä#ĺÜácgÜŕą[ÜÇůsŞáµÎÁ‡r-ĺ×ůłAţ6¬c“‘n‡ Ůo9<}ŃŚćZšź;łµč»´Ťćȡ c?˘¶Ź/ÉIâ€1Ď*4ý´B?A7lů3?sŤĎůR +ľź9§P˙H Ł]?d\‡Ý@ ú x(}ů\ąŢJmś™3Íéĺ­ą· ćT]«F·Ě±,Č×3H{×·|ÜxĄµ3.ĎXâëÄ*öÂyµ4ĐÔÚtJü×Ψý¦=Ů«]hŰŢ·/¤±‰ňm™4)m lúĹŮţNŠ‘ôR^®3Đí ĺăíÎş¤öBÚŢŃĽŚuśž[Ăqă8.wŽ˙K3ާeţ!m˘_ă/™—üÉü[XÇđĽ|žńź–|€xp„ťĆů9‰˝‘:QV>v=‡ś)Ď#Ĺ~Jě˝NýžĚď.4˝©ÔĎ´–7~Ô\ś t—×s·”ÎSĽ«Ăľ‚¶>˙™Ú',ôČ}ZbfŹ‘>ç–¸ńËp˘ű‚ )=r´čP]ÉuŢOó›ÚQÍk¸Ę·d‹cPţĘí!‰ň€Ćŕ”ďEÚúŰíčó¤C”×`çëӔǒňZ¶Ńľ|č*¸,ńAZóÚ; şť-zĹ6A/Ć9żútŃ÷]–j‚]ŘŃ«üU,hřő·q‡…AőgaóqÔOcîÎËe/żĄďĐe˝·Ďĺ¨Óg<=;sÇ>˙Ňl†¬Xő)Ä©ă#_yŤĹ΢w0Ů`$y™©‡‚ßâŤÖ1Ýüögî4ő¤Ď˙Ę­”.Čśo>› -3÷ˇĎ°ŕ·Ě©ś4‹ľk›ökzÎzţIxßdîý]Žő”ëĘč\d8»'óÎ{Ö÷+좶4Gě8ä{5†ţ‹ľ¦XNŚíÓ>:’4ü™‹‚dŹĚçj÷‚V}˙ˇ÷ăčĎ|‹žŁÚ}·#ąŔÔ›™ŔX^Ç9ţÎkŠółŚÉWZy˙A›Ě/ś9Ô ë”Ó„ň×ýÁÔÍŐFoIFv>"·ć¦ĐHŢËY祯kâÍôJŚ)­ĎÔdśRěFJć‹˝ţoĐóÝ1Ěß cmĂYy_!7zGÁűEŘiĆwťCĐšÍKÖ´Ćb R\sPuXűĹ–ĆzÔŁcŔ”ďϲa5Źż,úX6čˢ»íĂnć_šĽ%Ůž;Śe)ůäEVSľo·w$™Oóy0ń‘űq }Ď­ŃÄ/M]‘2őü/ďUäůÎŇCŘă‰î !oáj‡~"IÂűvĘ‘ţäöÖŢçĽÔń¬)˝Č|/k¤®gzÄZCMűď–¸GďŕXFč×ĺE6Ó‡yż•ŽŔŘP¸Ú¤ą•í×ń:^ôÝjö]ťgăĽ>?ÓłvIG¶Dem®˙mz&}-á=s‡Ţ*.đt @ĎH¦íÖ1Oú󱔿f¨-áýX0ńř‡ ¬ĹPß'ü˘‹Ň“_µA´ĄZŹĺuKŘ,Đ ű$¶ŐşG±(^˝˛áÔci˙€GŰ&ş7™veÔ6i9Ś ¨_Űxͧs®‹k6Ѷ«Ź5ĺäě“RąŘËçbĹQS_éÓŤçc‹'° •ŹX¶Ëf›•ĄęsĆHÝCccuă‹ôµĎ˛®#ď§‹Č15¶‘ěŘq|Ďdä}f`-‹z†ł_ ±đoĚô;š—›&m}É~Ąľß?EqűG“ďŔŘ€•ŻAôÔ˛ĺŠ } ×ůČŤ1•Ż» Oë8n¤&‚ߌŽŚk˛ßś%}Ţ2/C© “®ÉČ$ŹU%™(vĘyv|”ő;5ö|+˝ 0Ë+OŚÔ«|˝'úĎŻ(oŃśë–‘cîŘÂşŰ7Ść?ůĂę¤÷ezűůzÂűx0á=ŢŘyź±*ú¸ąÎ«9áP>Ó{Ë,ÚiĄxŰŽ™Ţ«8?/l®ĘÇrŰŚuʹθ†˛÷†FGÚY®ÝkŚ3ŚÓZ)Żü¬Ű­mA\ôµÓ8dĺVÁĽęÖ‘–-p÷ů?Á¸Č׍çĺ”[šž=ü|ťÖch-ýáŕsťW6ŽüŔô1Ü–vg»ĚĘîŃńË€?ÓK~»ľ ľCĚuŢBşüĺ@zh0”ŘçűÜÉűDWü˙TřĂ>ÚűŐőV㊍Ďô~’ő)á=‹cůŕĎŤ>>DgWŚ3‰›rëŔŞ1*Řă®řëĚźőš…ŠŃÝ—Ňăˇ>L1÷ĄčHĄnśLöBt@îGŰöúf[µşhŻ%ňS\NűI±aÝAoá3¦ÝÁ¸"ńŔ•tŰil(H<ŮüVňC/ŮÝéî‘óÁ§Źpľ„IŠ™¤¸#ćq4aĹkUŁűŤś‹&ţťňHÍ_ů©Ź±ŢAĎś˛µcá˝&˝ţÝŤ¸q“ŮŐ˝Ú}ĺ~ÁŔ.yhÄNB?ě:đF°Mw/b•a»Ô.7íM{ ľÓ”÷}d—-:,ĚŤąË/ĂŮ5łŤ6hßpŰ8ÓOąľÇvřw(űë=~‹Ď¨ÄߦĆúYľŞç”—+ôíˇlëčČţ¶ú¦CńŹź—ą‘`źŐVŮy7:Ý>“*CČ x– ä»ă¸Ü«ĎVvŮgź ˝ţúőěŠv`'(‹ńć:żŔG©űÇńŹÝ±>9°ĚOOüů`äC±÷Ř«ťrIŚňM!Îô>€Ü*côA9őËĚú=śýf¸#ůµĺZ˛a(őc˛đ5Rß§\÷…d|´tu#÷'ZŹĹ–SŁĺĎĺ%Ňţ©?ł=Kě†}¶W€ńĐçXlA»Ě7śtA®ţĚSÂ{[`2"1wţă_,á”áÓ¬:ˇGč…}3Ďsb¸Hůśb±źłů3‡”âČ÷˘ĚÖŐíôĐ ¶±ĐĂP*`ŇJýąB>JŻýx>űp;÷6RŘŔ×|ź3uĹ~Oůw;vě‡Ý˙ź°wŤ˝gż\“ů7Ú€\ŃŻ{NŘ=Ľ$y=ţźÎ<ëř»–»±¦ó0PŢPاsç é%h@Ű“ôśëĽ¸" ®żDĽČŻĺümc_nf^čMź¦ëűwÍ»€¶(Ţžű°čŚksgëÎvŢČŻŃ‘}Č~ľÎ}HeşéŔË)ÖőtΡ6ÝüQč—–§|IÂ&ó¦‰îëZ±bŃT3ĆŻsü»†Ç0Č}‹öd5s˘Xs-1sÇ„÷n7»šÇ+ÔĽ.äyě›]>öď:§PJŠé¶ĆÜA4î­¤ř2Éáh/_í;úłÎ‡0n-ˇxáŃÍWĄ5Ďě‘Ö6xÍ|>´ţ•ĚtNTŤV=šË±k]Ş7ZÖ~Ä=xÖĐsĐ'™çJ¬}Â{~rľÖÄf 1š8®=šŔóň1oěvÖ€#')Ćoáí{ŁôB>tÍÔgZë§çĹŻĐ:ßkUç2ďCKČąľ߇xrÄŃăś?~×ę“ĚŹł^Æ€ŠGŹ+c{´#˙ţ–#Öń®é8=ĺ[ üCŽy“ôI«OĂ&ű3—p_’9ć[1Ć*ú"c…ĘĽVxQ/h±ë"xm·_¸ŽrjW3Îáł<~)ă ű¤\ÓĚ?Ĺ`ç“ňÔ^·^ݎOőŔ;Ľ˘™u:{Šž+/ Qě©§2/í§őą.SŮÇs,ÖTeŽhÉWqÍĎŤ†rťmć:±žH]őúŢ.I͸şâż0Ęu2ů–ăz>P>(˝ qôŇ_çŢČuÎŘ)/^¨Ňć[hôänńŃĽx¶s§*<4ŻĎŔ—őünmKűR%ć .YďÍuF»ý<îˇ÷Ž|žňj1­2ŹvĘ™ňe˛ţŘőzpßµí™Ţ“C”‡’ďŹ&Ö™:6Ŕ¶XrÔBÖxůAÖ/Ks?‹nŘŰÁ⒠̰ŔŤů„6âśGŁůxĎZZQŻ^,JľÓŽäĂ­”@ŽăŇôZ­ŽˇÔĆÇŤÓĎŁ#;pnCKžĎĆ‘+Iż¬ŻłZíÉ™ćžÇ”d%ü˛ŹßŕŤ]ÎVýşnr,ĺ÷ú©‹X+¬¨7™ísń"ż?JŤ}4ôbäɲµ<Źy!k§í^Asň«Xv 2—0­ŢÂfěÁĐýI JűO żh_ĽNT±Řm5›‡8[’_Ű…Ľ ‡Žä_X‡uü*_W~/r¤çpzî•g©¦ô~#úisÍKĺzÇžá:1ŃőFŐŹÔŘUuëÇvěË’Żktd7Î'ŞôęQÇËÚĘíęńĺ.¤üç˛ ,–-@Ż®,IZą–JşoLů˘ł‚ŰÎćz?q†9˝É ăąÎÍĽŐŔ˘Ľ&î Đ{tž‡ŃűGŽô‡“bO‘ś5‚¶„±_öĆůuä?j<>i›ŐŹÝf=¤uć˝<ű`®Ů ‡SĚÉĽĺ3#µZrVů}wQţ™{Myęůµů×ęb·ŞŁµÎŽČú#d$ď7ôš`tí şÜ‘\Dţ!ŻRü;rZxĺ»ÜKk˝Ő˝ťíůç8ÎkKő>ĂŢaľľ*z{h˘űŰ”`‡YŐaĐşµOsúzĘQűt…€WźÁdüBŽŻSąsމgdč>ě?l•?ófĘ|Ok»«±şçBSÇ·FC˝ŻŹîŔ ąŮÇXČýrAć)Ćp\âj>–Ż×ë¸úScňv͉><=?nťč–wGŁ#źĄő÷§8Ž˝ŻŇľ&†hâóĆĆ‘}9w:tşMď:¸ďRľ Ç3öômέ+ô-¨óµ˝ °+~ĺ|—ŁżnŽ|3@yöXö=ŃŁMľĚ-D[¦¦'z@Ű`qůPěŔv :ŚgOz~¬Ú?ى˙uđ`˵oW M°ÎRľĆLóVÖÝĆÜwv`ű@łu*ㆷu2˛ŇÄ6yŕđEé“§\ŰĄo±łÄŞčN¶,)Űwg9÷—Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕr –x˛űˇ˝Ź5ßŮL×Ĺ’pňnKĹ·«÷9ŤąĹ|x®ţÍ«˘yÚ˙ăeóÝcˇéĂm‹Ňż`˙:ř"ŕ/ů¦ůÎr8{ťŁ®éř5Űç“ůÝřÝă@ńJ3ţâ3'ÔMt?ÔÚ{”eYąż`%‚d~Ĺś“űPvaÉ żÍ 8;ěÝ‚÷ěđѸ řźön˙Ërtä«?@ą~,ĹVľ‹ŢW[ű‚ »ö™2ĎGŢËXcO]ŰÖśľiĘu>Fů„^bL'ĚďÚEr’—ß˝…ďS|ăˇmyÚËIôŢň—Âo»^ŔĎ2™?śugžgĄľú˙ŹĹţÇÔ·ôěa*z˘óÚׯ4űdKzż€ú ‘?íą~Ń˝‚Ż7ć:Ťž(öm¶0ă»řK ¦yžxX|Ę.dęú#u¶H{%˝?"˝sY^đť@Üôş+ž ł]˘ßŞÓ¬4ĺ´w®“q?:˝Ëłú ťqSčđťU?«˘ďł˘ç ďň<×§}[AĘŃBxśň˛~ ŻQ.1oAr{ĐL}=4ů‚‰ĺá¦ű *Ć)_KXýp–Ç?Eq=ş§ľ#µc®©żh˝q˙ )¶p¨"çF ·Y OlGĽŃdä`îç”§§$÷éx%çˇŰwQN-ÔÝÁďĆ\mö¬źž“ß-ůë"îxď°}˘=rSYĂű®ëXMńĘ­ąNÉO">ĘNÜđ/BYűŢmzďÄu)­ßg°ŘŻE°öS|ĹźY×(_ĺą®">(á}"MtP đ+˙ âüy^BńU”7OrnŘý>ˇÓä'Fů^^ %Éîů]ä˙ÉóŤŻÂů>˙Í9~×ęŁv±"GmÉ)+•±^Ť&§\yŁžd:ŐžKż­~ŻúKjÚâqnEě©EąÝ=5óĂé‰înÚËŃ‘kX‡a[ČŽqßVą[X-Đ_ŠnÇÜ»čű\Űş˝ŕËĽ7űbÖSěôňp2bMěYs:ĂşCůđJ6ŮňA×yQĹm7ćţâO˘ďCĐ ±ĎđYßů·<ž˘8ÉqRhş®T·ŕ8ň=ÍuNtďÖ{ý†±Ť\ľů hĽeţéµ™:®6Ţ׆¸'‰ýqÖJă“ÉkŃcˇ[äě¦)á#?ôÇ(OSĺó±Î9TÖ˘ߥýw źCűŠŁEµyZ&׹ĘÔ«ál˛&}:óʸqPzżVoa3ŰŚ—Â;ĆĘď]·Ś›´öMÝsuü–Oĺ}ŠMú=⟯ 8٧í‚:fk-3ylNO{%~Ťů=ĎÓ`ŕą×n§+ĺka@9Čq°ŘWŇŐLű‹ęŰlÝĽ§PŻŽÝ˛‡° ĘônäŘi»OřLâE]=щ`CáUsľ9Iš6 tŮm™ĘÇyŠúü·ŃőVźŢw0FG8ÇźłĽÄr=ĚôĚ$VÔ7&Lë8$úlµ4íŐÁÉ<ŰÚ9xŽ˙¶ń$Ç\–Çź”ăUl”ß3„üJŔŹ{´_•Űs‹š7ţ-Ὁs¦9iňxĐľÎ-ś×¬ľ)öy*ă¦}pŕŽ6ĘÍL±e_Łyu#Ź;ÓÝ?ĎłĹÔ®wŘA Ďí}üŤŁtÖ‹Gńřű2Ͱoi˙W¦C0Y«ŃŽňŕŹŇ7!YßkŚ ěÚĎ´>Č:¦˛Ą”$űS(ö]ňY8)žą_ë)?jnšOQ>Ż÷•r-+fz–ÎÝP!7ĐŮśţŤ)çJŠô~çü,ç©öc­Ł9ý‰ZÚ03Ƕ×ë?žpťŇ7=ž•±SߎňFęqÓÖ$>ż;ĺŕ~ÓęĎ<áźŐú ö9Pyl5ćx=Ń C/7ýÔ´5J×L)Ö‘éĆřŚńIíč”ńę»4Žď˛ööî§ 5–ĄŘ-yJxeMGű·âŃqĺ€Ěť4źűmËjă{‹ý™Łżż“° fčÁĆ‘ă+xg—1ÚŔßřŔŹř:í«Q—~lç_¶űE–ő™ó Zw4ăş MÍLĘyÖĚSh×k\KŤĄŰB”ßZÎ[ăĆÇCŤąV–ˇqȡś˙e‹'P~ЮõO –ú~H˙Z;’˙k€÷öů2äKąXw¶»=ĐuËćś öeiś§uŔóĚ~/䍾‚>ŰMËŢŕšâl×u.4>płŮŻę‹XZ‹˙Búč„,t=:ŮßťrG*ěđtĹe=žÖ„)p+ńÇŢźĺ;x×ýŮçc¤\TĚGĘ[[wť®ĆŰĆÜÜŻ»n‘|#ĂŮq’ăÉŚ·ú3µÔBąć+r®)~Ěc§|(żÍ ”ß}g®k˘űšY•±b§w°ćzΉ®ĘUŐ[̱×@Âűýv}&˘ôü<éŘo˛%˙!žÓ$ów°\éXËčHzN`UĚÓawa«O‹~u€ŢÓ˛¬ŔĘ›Gďëöc:WGů%Éë ĽçCť´hĎ×é˝P Ůůš˝ŹšŽţôüÚüýfźëóďJ寧eÜă+CsCďçő#9őrw6§ďfëąíáh¤˛-ĹŻŇ{ů›L»¬j“!n\Ką:ö1÷ž1ŢBGĽ˘gÎŰk˛Noµ2“ß.^ě-|ŹrMżÂ}]ç'°K´ODčÁfG˙DůĆĎXŻűü_´éÁLŇUźş ›éŮi!ë*pQxĆĺ-ÜtxW<ܶ,ń+ćËD÷BZCöň÷ÁâĎĚľQ*g¶•Lď;LúScĂ4—z‚1k+Ťą3M»ż6YÜűĐś·WJű¶{˘ŁôÜ}a[¦÷J“=ŃE&fň%ŞKŢĘmˇu&Ëlę^¸ň >“uşuąp9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸¨Ćä9&~Ĺď’ď’ŘöňrŤ§śf$óĂ´7¨ÁďksťŢ.ß=ŹlpĽSśýKcćđşlpĂŘ»ů˝$íĚďeŐď~Tăşil u|ŕe#á˝Őń޶ś_łý{Uô;ďŤ)ľ>1äöˇ’»E%üőń ~eâ3ęń ^ {+ă<řżš¸±Sheětó}-®Í…ĎOş˙»uelË2A\ţ@ďÝCÚŠľýÉ_¤‡ô>pO4aíeßşuنvŠCšÓr†LÔL}áG"2ÔýÎú¨żśě.{ëŐ/÷ďĆÜî,÷¸ŃQňń×ő?fzŰZ(ś˝Ť|›Xďŕďä8PHőéCÜÍşlwp˘űJ|Ńą/G×”dlů:’Ď=ărć]ňxŠľÂđ«JĆ;k˛Í×ŔX±éĹN0ýŔ yăď±Ţ’\DwAŻúCÁ?›xĺŔ¬üŃŁúűÂŹźüéŚUo˙ą®řő,Ô7[źÍ‘›IvDZţ©ż5äDąG(VűAÎIĐśŢĎÜ tŰŮ~iyĹ©ÇóĽ{”Ę‹ ÄboÁß]â™<ž cŹÔÝ®Afč·Ň'c—Ҹ*t‚~Ú@Őmi+Ĺĺk>§t(.¸]eŠ{„­Äž…ČAuÇÂV(^ś§˝‘Č_t7Óçjő™ŚČý ¶ a§Š>ŮłVh˛0«Üě´*]äIń Šutî‹{¦|żgĽŻ MŹ”úŢ)G#őóŔD÷ďŰşâFÍýqŠľ%Žůd4XĽ‹}#Žŕ‡ţžŚI1O$ąc¸ˇđ¶Đa顖͔; 2E9»śőűĺŔ7Ú—®¤KţĐâY¶ćľ‘ăg›}HezŽ˙W!ĘÄ´XöÚăqÚ^+_šśç}Ű&ďoµÉĐŇŘ*ômřaiż6¶_ř®RÎŢ\sÜË{BęÜ)ś:Ć'ąíźůŰ•xYQ¬jsÇ®qÄ,Qľ›ŞĽ} ´´µ÷b¦÷‚@2}MpŹŽĽ—íä„?Ł ÝłWôX8Ź|“‘_łż.0k_,ľČú@ĎLcGR°‘ĎŁciŚĹČiBqśKeZ~|p§vć!ĺΫ f´—űiIŃ]ÂŚüG‡(ńŔžëÜKä,”^Eş ©żŃs”µ/j4!9ÄÄ^[ú­zthz|%ý\·Ć‹ăĘ‹żp9'fîwŃ÷gó‚âs)F÷ä1d>ĂľBžĺtłÄcě9™úýŢL;ĺpŚ1¸_űý¸Ú¶+vE‚ľlńÔă!:¸N˝>“ÇŽäMű˝…¶ĹJ#ôQă ôśu%ëCëÇ(>®;<>đ{ď:’_az«ńĘşWd›7Öqľ"oá6ĘĄxLi\źI”Őë‚y96Ť‘]úśQN3~ëśąˇ0Ď”ÍĘXŚôĺ‡Ô{ѧ“ůÇ9Ş`Çěv»±ĺtŠC>Í”GuŞ˙ął©±U<.ŁOÉÜKřŻ8Ô4A„V˙„íVŢ€‚wGËč´Ę*fôť=ÖűaÇŢŘÚ—)ĆŁfĎ“‘Kąn´e—ĄbŢ[tŰç$‚±4˝,ß&˛KĘyŕšnNbŤ÷§’Ě6ĽÚŘ›Ć1iGqk]µ8bŽŻíá8:ŇĂ}Úź9¤4žZíĺđ˛o(4q~ŇÔŘG™Đ;®ň{쿏âRŘf źűÍąţŇRľ—Z`¦5ž°Ň ďYˇm±?J;híq㏔7ěͦN–ë–ףŘEt,ëĘPö…R9ŹgďÜ™Žů°–ś‰#b‡´źBF“‘÷…îŁţ«´á]µĆ§ÜÁ/𪜖Mםâq¶×g˙Ž>€ú1V˘ŽBÓa”‹ělÓ–×;Sż‹˘_J;hPşD´%'^š·„i=ćhĂLŻ–˘géĐó4ÇĐ:ŞˇŞ_¸.öDj0RźŻ™ŚŃ‚?󸩏JłĘ]×´d^)•±0«ťËv_ň˝#¸(=äxţ»’ƤjXß8ĺúD{ŮnçM­˘ŘŃMŚ•rŰÔ3ÚMćßÂm eź7Ţ?Ő;í64׹›#‡-t±dŻůrm±ŘrŠs˙/žšv1yXi»±/6ÖŹ<+WŮü0ĺc2őäŇ­¦Q^jźc×§Ëť÷î1ăŰ-ůzë3Ńí3iµ÷”Ç8—ëŚĐ»ŤÎ_>źr8Ł^č7ĘB·`÷h?i“gVÍ3ű-n|‹éD›čS#Ô?iĎnĘ…ő0räAäťĚďÄy@-ĽVn·áěisv-ÜdTŽăÚ'„v;?`żíŻŚ]lÜßcňmf‘VÖFë¶ÜVWü Ši>•ž[Ěń9n|°}y|i0ÓŰKqî›ó żÇóýŢ'‚Ô[GG®cüĺă]WüôönĘE7ľÇrNŕíŠß˘1.Üś~ÎÔďJęj{Fí—âÚ­6)‡|YľŹg8űSÎ(Y^ꢜ”#m7ÖĂÍĽŰú|‹Y9 ­–j˙-” śďwä%´ăĆŘÝśľž±Ůç©´~EkXb{Â2,—1ęAߥ÷VÇi\mĺrĹbM,ß×|5†ł/Ôlť s»żŁmřŕĹĆłťż­xąI^ąWű§u]_ëĄXXâŤUFž_ôŞĺş}\îŠ?čx×’µAążpąĘ{z˙J>5˙74>° ĺ2ýNŰňřŹ:ý|qTă~|hîS×qIZݶ˙óéŮťňÄ1Ö)ź/âŻ9ý!–íÓ†ś+dó1ooIŤůÍçq”CźÎîş"żáĎüopăČ/ç”.OÇ…U˘1줪r™ňLűĄ„]ńď3š/—Ţw ¶´‡„3÷[4ń;Ç3çtmεóFjĎÍŁ‰˝Ůö.I&Ś c—·šľŇć-˙ŹÉWă™9głţYcŹ.ëŢcYoGF~ŔřŇCĂŰEßµčßú·ÔŘŹFjžOŇ~.‡S.­¦­ßőŻQb]öşĂGG~xŃw_Óc˝eÜ´‡Ývi«ţ5$â˘p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9°}s€ö“5}ů‹~ň÷ŰÍöţY°˝L± ŠĺoNg‚±Ř‹tś d»ŁHňĐíć}tjl“V?í?7ĺ ňţ”§€}iÎńď×Jű޵EhźnřEýžţČ˙•÷K'ŕkźőŃ‘SLžÍuéĂ˙'šđ2>ĄUăŚđ;=ô]ćËgß1ě%ÜIą ~E>f—ľĹ÷™ßQfî~úY6đőRß0ń‰sRŚ|Bâ;'~ąNŮO0™„üţo0}ËěţuÎf˙×”Ż=DAݦ^ÇŤy,#őM¦}]}9šxÎÔ[řK‚/đŐÖ9ü†o+ţŽJţ†úüňĐÚüŤŽ:fµ‘’äMQżÝ©. b˙bě7šŰÉ@_}¬÷ˇ)ß‘ař>ęţ§ —öƦX(^Ľ›řcůp‹źşćpé_ YG‹©Ě/g3č&Fö˙yö/.ČFcŇQ&;‡s¬Řý[˝…˙%úçQśKJú5ĘOt$MĽ5^"odOŰŇQ¬Â¦YÇ [E{RŚÓîsrž™{E±šŢ&ŻĐK;Ľ(LąÎ[(Ć*Ě­í‹ď˝`?™ĘŔŽk9”Ĺg°¸CúBľ7Fń„·rź ŘÍşűpSnCâ߇pž#6ąÜ~Á—“â”XF”cĹěó‚ąfŽsřęCO(jŹyýˇý7)çÖ ůXŻůÚ)Fň–¶MÝZ?űXÝp“?'íĹţ0çsHłÁ6&‰Ľ˘9Ą4ĆČoČNäµĎ7ć>ĘŢ/ŕłlʎR)?j\Ő”ď˝×ŢAq—Ż›Ż`GrîżvýkN?mîŤ)şŞĚđWF|FG2Ďľľz¶ yÔě{ż«ŽOÍé‹(Vm§R-‰ą]–Xgo$ůďŢ–đÓşÚřVÍ÷ůšŚt™c húd\QdĹdÉJÎdz0ׄâń™oZŽĆ±ŽQĐĺ×_żČ´Uߢua|X@yoVĆö)ůÎÖĹ–rm0nřbCŢÍéEK÷ßFź_öíŠ_d{ŐżqľČG¤ú=>¤ýŮnXLă릵‡¶čĆ)ÄިŤ—ŘzĺŽGGÖ¶_ř-ň˛ôZĘZtŰíĆÇŢŇĽ'Ů“â±6¨Ď×Ěf+Fę˛`Cájsţi§Iç ([M†˘ëRS(uV¨|Ě^đ v\ç˘8‡şÄ6 o´ž‰˙lҡôŐâëĄgß“ąQ>D3x'ş(ŤéNÁň\L*g›)''ߏgQ;ĎP®Úx ůöůŹb]˙-ńd2ň3˛_ĺů¸jXęĚuîDĎ‚/0Ź!áűzsÜéHžCßËőUl-jhĚ-0m-­k—l¸ł<äťŢĎg%·îďó´űř]ëOÂűqWź¨Č?ű éśTč°ă°SÖĎ}°9˝c¸1wz¸š^HNIäZ<ž_®dŚčűŞ+ű¦Ćj6ß´SŠďý‹­÷ óóúŚÁV)C䌅™ćĹdלźéć_ĐŚŃ3 Ý1źźŐ–ŁĘŹYó1ĘI­ő«'şë´?łϑԎu$ď6×TĎĂH][E/-Ţ ,ú¬ň2šxÖĚzĎĐn´NúGîS”§¤ćöÚBi}ĂܲV»#kLó<ÇšcusúxĆ’ëŚÓşÁOŇg…ТĎÇe±^LkĚ/č3x…Ľć㯢#hĄ~ź)ß‹”/ý˘ŕ‚Ě„™;KÇNć•Ŕ˙eLďd«źç±u8{¬©ÝwÝhę4ů™ç·µîíˇÜ”/IrÜkqWü`ž/§ĆŢx©éÓ­ĂŮŕv©Ë[âyGrY›?ó=–3ís@ékW4ů3?eÜËă_iŮÔť[śđŢÖ´Ą:¶×k´OÂákó'7ţÉČdSćÎÚďݲ˝ňĘĄŰĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.,P )űKĽťöÜęóż746°K…ď"íÍN{W=ÚMŢ”)LűäšĺµŽŮ:®zh„e§ţ~đŰ„ěě2ZS<ű0rvLt?Ä~ë›#Aľ/Ó»ío|'ń¨éÚü_yż÷ž…kMťFĽx×oÂ÷D«çî‰îËŤňřWőWU9ř3W°…/r¶+~ëĽřőâ\?ĹR&Űpö“Śy˙ĚD©ŻŚń‘rTŘ?mŁžGŠéŘc ¤/ ńß–ď…¦Kq ’wüšÍ}WˇÓŔfÄ`ÂG]ůC9j*dŰ}۬řÎQěŤ-Ď’/ę-ňă¨l5Eř.ţĽÎs–Dhź[Ć#×-ß_­‹}b‰jóq'ĺä1Ö?2ëňţ„±®Ô˙Ägť|ŰJöŮÂńHh˙R8»Ç´ß‡$OÚmâŐ#t@í8ÎÁ¶Ńţ©”Ăi¤®~äoÝŠ}ÇŔ÷EéýĚř'Đ4ś˝—mvylěšĆUtĹżăŕ‰Ý^Ăç5×iĹíSŢŠ• Éž«{7ţ/ʼn]WY7§Hű¬C{Őnn,ľ‰m-đŰ?vŮiĽB¦7kîą©e)^Éżˇ°3ó ×iOo“đ‰ĆüÇŃ‘ÝÂfţ·˘źkťµ:věąo(bł/Fęk”§$]Ňqk˙PŃQ‹Š˘oŤ©×ÝżMtkîíŹđHúIˇé€?óg®wIňÚ3¶Ŕ÷7ćä+Ľ±n˛ŢÔ˝„óˇ‚ď7Ä{~‹Ž >»ľŽŽ\Ęň,. z ë(Ëß9?tý[d«u.ţŘď‹Ĺž -ČĽb öާD|}Sňč™|ł¸YŰo2GRą8Źsěz ŞŰă'·ňx%Ô=C|pŢ«żí<Đs8b,CŰ471őż¶HĄvŚM­ŇbŤÁOSú€°ÝĆÚcn ?üŮçg_¤u).Ô/s‰ß8rJXěźđČŢf=0ŹHÜśŇIsj–ôW†,D@‘Đ©6ŰNŁť?ZÇáěua`Ćź‘:•ë_ ‡e¬“\ ¨gmţ™:Ű1`Á^Ý'8d dzŹ,Íą Ł…sčůđŠĄ‹t2ç RZGŠÍăĽKŠ4…`].Sţ˘ ů¬çĹŠ#đ¦‡ä±9Ç×w ÷˝BúÜ =–ܰ˘…¦—MŤ˝3äéoáç·BÓĆĐ3ťg×e\VśzÎ.äůĆ$µĄ‹Ň‹ó]”_ř’ŕbzÖ´ăŐ2éË}ytdOΓi/ď˘3‚ßc±·s^Hč€U‡RQßcW\ňau$ÂĽ…Ą,‡.Ú«žžç)çVőŢŽ©č»”xr©9Ć$ĽçšůGPú¬6:1XĽ€¦¶b7ÔôůOšŰą Y@Ööy?ĹŠ}ë=¨”«Vä¦}tĘ÷í2şű)‡ń&Źd D>ćS(ŻÁ¬OÇ&VłžŰŰžíďŔ ÝÎĘz>čIćßcŘǬĹ4®S>éĺoŁçł ć±]ÖŐ–ĚźĚc¤Ś™b§(ç„ŃýZI–ú$×´¦\çgČOaé>rěR$/ ĘNtł”ĂĘăIŤY·ńXéśî|1j{ĆÎ ?0p®±aěrž/ÂöX˛łrˇ®LďaÔ1z±§ůţJÇ4ms8{YĐ+ł{„ťÁüˇč;Ą”“XöD°ĎQÁ›ńůlÇB©'č(ň§ü%Ű&c_Gň9ÓÖĄĆ"4Ü9gd .'ó·đEç„87śÝ%lĎ;«ň|¬·Í1‡Â< 6PóK9Ô€ü­Č?Ľľ­ˇ°yVćBĹ–˙7§wç#O˛| OKľz_˙RzŻÎ×é˝,óÉ^Fm‚ôĽŰ=f1Í]ć,^ Zů#Ů凸ߝă˙ŻmBŽň> %¤?7 Z·ĄçłŻpľL`^ô ť[ŁôöňˇçLóýY4qŻ{ ×ňŘ »dźKMůÎ`™—çëŘóÍ´_Ŕnm©1+żĹö‚_éŚ{3¶Ćܨ÷©±.ÓM]ŮK{ů´óu-źÜń‚9­ĎJgµăú1É?ů(ÍAâ8Ąďăs±ŘĂ”§ýµ6OöĂ~ĘM^×u€jtĎÄąá;Ţlâ]–č0óř©<÷áě‘­ţăSdŻvř—Ŕ[Î3Úżd»Î©SŽg[·¤‡¦•…ŰZŢ-çrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.ţăŔŮţă“_äáéˇĂZ‹Oš~3v>ÄŤ·˛˙Ědd|…ţ^µŚ˝ü\ýŢśţcŰ’äŽěóFţ×ě#ßóč™ß lęľĎôĄ˘¸qŽł‚˙TjlţśóUŢVţĆb_6}Q‹ľă9|ˇz˘/´R®ť`$ůµň°¨_$ü»á+ńđßţoÇ}ŰJC˝Ë5~őĎ?iĹŃaß±Ţ`(ő6‡ÓCë)ĺĆ$ľŽý´?ě˝\ĆźąŐáZo ŰŇíqIţ_÷äĎËľÉęĂ)1CR|~űü‡s~ŕë8XČ:őó+®žű<ëM,68Çúú'Y.č—ĐÍžčs!ří#,56iŘăâFŞŤü#Ů_ xQ†¶ˇç¸ŚŽdŹ™~˘¨k(űł9)ó®gn ‹Źy˙Ňćô}ˇdţ-¦˙¶ř¬ö®™´©×ąźÇb›Y/ħ}ŕţ­ýGôÄXuGwů3âCéÔ”úţŠ_đEößŐŘľuŮnîŁĹô#–DsfĘÝ lżŤÔÖkŕ}Pż}çrŻ/şĘÖ‹ďfý¤<,3ŐSŤi˙Ý~ÖOŘfíă¨é<ď1ÜG±'îl_;Žű®)ý†>4§_źU[^hú:ă…^ľŤ##¦ţBnČ#5?çĺ8P‘d‡=ź%®Ř€Qů{ţŻ÷3f´­_¶{<ś“};QO˝?Fꊶe”¦č[Âtĺ:żÉ6—ň…D‡Ą/J,ÄŃ@vdÂÚĄŻ§Ü2{±Ž&Ľ%\ŞËŮ@ŠŰ‰™6*řž'§Ü4Ąy…tőůŹĺó©±#J×+÷JF˙P˝P~Ůű;®‘^°î#·^˝ńjĽŇ¦GČNh±0C§'ş%¦×:’náާGô{ŘCűôĽňWŽőE›ĽaźŕŞčíd zhżyĘ!v8éö ađÁ˛U4ŻK‡Ë冹ŮĆ‘Ömĺä‹ďĆÂËă™pGňăŽű Mď¤XJŹÇŞ»ľý™ÁŔn…W:žä:w Ż)žAöf/Ęë÷!¶;ůȸi{U7W’¬‰”+čK,cĹ«rĹÄöśôúA1ŻŃZżťăYP^c‘ę…G´‚ćËlkä;> Ç)żZC!ĂפX}@ń+–®řRç0ßţŃ‘3Xţ:oÓrő:Šü,Ľ˝’gx MW…u~†ëĐaŘů…éý(ďئĆ5Đ[®˙qăWŽüBZ7x71ǰzaE;+c÷°śTo•&űQÇ»-‚>©ßđ˝ĐOČ«Ż˝|źúü‹LŢ!¶x°řÍPsú"Óţ×{®s·§ôB3˝uĬ˵ňĽu]ńy&Žrśú:B{ ‡'#7‡´€‡ţL8ôXď_ëţlI:ĆĎ‹ Oô{Ţîi€&ä"QşíÇhbťiŰ2˝——ÉIúµę‡ćČkĚíN2mlGF]§ÂZÜ«˙7ŐoôS{ëĺyN˝…ď…iď@ˇéX“^äHB,ĄÖL›i Ť×ÉđykQ·Úuô‰Lď—¸ŘŰ«Ç÷>LŤ˝lęčŁgĚŁĂögŕP~€^Ě+›ÓSAZaÝ,ŹîHîČg•©Ö˘z˘k ‚Ć8?a2«xAßD÷ĆĆ•ŹŇÜśţOGŽČ ë˛oâ9d(őy–1îŐ9 ®«ýRĚb·¬5ßÇz'‹Ň—Í:îŤ#EĘ›R0mĘ]CY¶Ç*;ŚŻŠ™bÖĂŹö>Oy9żn®*fĚ7FFÎu$o ©Ť†^_¤FČéŮżpĘ×Pfë•Ëő;ŇÜ -ÓűLp°řkÓkëOx?ľK>!äĹ[Áëa±ćbýKÉ>łn`mże‘r…=J}=Ľ,±:‹XßenŤ5±ŁL}ĹśĺÁ?”ř2Qmť¦ÁâC-}ţę{·čĽµ¤Ć>Ëýw¸ě=\×Ĺ÷7ŽH>ź­·6·JŻ­ß mSľź‹&$‡ĐňßZ9ČGG>Çc%0ŮnôşÇ—Ç{‹(Wĺo-4­b}¦\â-=ŃFöąX•ýM M»1ŢŽäÍŰ5^;ëýúá±§×řŔµfŽ-Ó‘|đ_27 đQ_wä'ń_´óˇˇpk“â˙WĽsč5ßĆć>ŕĘ•ą}ήÇb×r «úçÂß~žĂŮ˝MźÎÁâÂâQf~î2ć ńҾçď6ËiO´'@>ë¦oč\Aź˙>‰ť23óaęH>‚˙ňÂônŠSçđo.ú>žčŽŢ›™8w_)ľsť'›~ÝssCh(űr)–P¨Ň}ś5Ćş®ľÍĎvţ¶•0Ňţ·W™±±ŘMá†ÂŰÍߏö~ü‚Łź¦úâĎxM1ŰŘďÚ+dĄ­Đ4źběö4ăn&˝FĽśÄŕ ?ɨ1ye÷\ç{ĚröXȸԿߛŹŘ͡÷87źń/–%ž5s ­ŚťI{LîF`9–0y<ŢÂ^|†LŻŽEw%řäűUĄ|đyFĚú ô÷Q\Ö¬cŽ&vlkĚ5±ľ!¦ ’Ěsꕏ‘“ĘÁH 2˝Ş zžđšú ěŔ–Ű)¸05fÚw-Ű‘<‡rW}ËaôZ=Ź…¦I¦qŔ”Ç!ą@ľ°É—çW„$¶Ddý¦őcźä1­1w™MnRĺ˝…{Ě~‹8«|ä;Ë37ň§­)¶„&ş7ű3gżŔ±„hMćă/ú˛Uv9Lt?Ä|‚}“XJ\•8ŕNÚ}žçKśÇçôOc–â†ě7kŻŻ^ß)^“b˙Ävń«B›´.ö٢—lrűD÷˝ćŢě(Esłđů$wĹ„cŻ˙ř ¬öŘhĹ]/ŚŐÚáůb)ľ×˘ ăól‹AŁĆ>öDŹj˙ ÇIMŇŻ-ľŘ±[q’— ×ÔF,Č|™ma5zjyÎH- NF6°í‰§… ŁřłÇ‚NÄw–cĂď˘ď«śetüę‰&Lý§Ü,»@á˝zVć(ĂYkźuđ7Ó{I3pÁŽăĽČLăDqF>z¸aótlď$ÂÁaä?FJ ĹÇöiÇsHOtoc˙Lo…]׺kqL}šmЦî™ĐŚ<3Đő†Âď™Ţ[ÂGf^®r:ě庥çö~ ŮęX_^G=ŻŚíh˘śhł\źA?ú6r8,K|ó^*&ĐŹ± ÷MF®Ł}î(ŢůÜ÷µ Ž”ĂĆ‘m@ţséń<Öë7Ç2ÔUŹĎ`Qr$ˇ-Ä‚‰YY6H¨±ózż,q ÓŚrĐ;Ţjß§gqč4äO¶ŔěCőŔjo#ÓűQş ŢëłÚhĐ YëyÍAĄ1tÉüĹA`ŻŞa´óHƝ¨ íEłb·íŘ1ßR}]vÜŔś¬vMď§|Mˇ•±W+cO:á´…ňYeaą˘Ż ťžčÉł&gĐÔçoçöU~8·,ń­`Üřą!|°ěž‡ăF8Lk#¬×”C-J˝@qńç‡ë ‚GÂ3ÄaÝeÄo÷°L)?™qáťçů®‘ĘÎĘ8löđyéŮç0¶”ŰdüNŤĆ×éY#|ýŘOm6Hř˘ú¬:z ű˘Ď—PŚ˙Żh é»|_cîŰu§ěXńüł9ňcˇĚ™? ŽÇz/źAsTÜCńÁ-˛–ĐgÔNk› ďmł†UiđxŢĂtcťçĐźµď‡>?ŕů 6 瀹+ţGß›ÓC%=AÇ{˘GÓşŕ•Ľ!˛—Ö:’‡¶Qž9€ŮăéŠĘ ‡Ć0Ń˝©âAe#řŃÝHkˇÇççFŐúťg>Ŕ¦a."Ď/Ď<ϱ¦]łx>;ßHVŢ‹î–t›ó“Č: l0S.Tî ô¬Ufç„ţhâqŽďŹt¬Łµî6Ę#6g0ŇXěç%]=)Źü›™Łt‹N{<š§TőÝ.!µŐ8žaž9O§µ‚#Júożcn|ż»”‹V©Q» ŚąÎ‹Í~ű\ç-ˇ‰îĹé‡í}ô±ţŹđ<:^ĄĆć±jµq­¬¶0űGĘÉŇ6ś˝†mĺłdącÜíĂŮf3źmcîšp>ň2ë)ňĚčÜ<,ö1osG—Ƶ·r}łŹnËPuĘŁ~٨·QNšhmč ”Ă÷݆®Ą@†”łÂčľ’ůÖ1ŞůÓôškl'>?”}aNőß-Ł–«“‘űYVţĚŚaS·Źź•€/™˙,Íż 4RĽ¦€yĺr˛˙Éüá\v[ęź«e↗d|هÚb;ÍÉ|ňh&#IVE?µ]č´~O}8Lř;íur?͙逸Z“‡Ęµp*`$wÁ: 顳™˙–<˝…r.™ĽŮžđm ­Ĺo‹űýćřsĎĐđâÄă×nďŘ·cy™„÷c´ďË|ĆűÚ·ÓńşY¬Š}˘űĘËqq“ţvŹ.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\¸p9ŕrŔĺ€Ë—.\üëq 9ý-ö…úMSşb˙¦5´Ţ»hO˝öůËG‚Ál÷­úpz ßgąłýµQÎ’íĆ/°Ď˙D`đ×»›±ďäżZŠëE<Ö"‡/'ü]áÓßüŁ©\Gňtľ_îd~ßĐdÄĚu>ę}ŰşˇűdRL§-ľ4Ź\CűÖŘ9Ä0ČwěGx!é†sźŐąŤń®O’ů÷0ÝuT_uŕíĂŮ °h°#ůs˙_Ť7Dč˘ôIś˛nNźD{Ď`®Ě9=żgh=Ó´6oĎ™"±7_sÚoꆽ…›ŚŤ#źŁ~Ý_ e„ŐľKëŤ\ç-[µ(YďĎpö?8^{K¬čçD÷Š9YH{U'}™bŠX/tBăѦ|ß¶ĹÁŘÖ϶´G9'bN «%ÜÁç~řćpˇi%Óí-ěC2»#@qwmqăËÁÜßÍ|Bl‘o$}mNF.0"ÉÓ県ÇŽlMxob]ĄĽh´Gę ÇÎÄ É›%1ł˘·°ĎÉÝůúD÷‹Ś%á}–çAâ±oěÚü3ĆÝC‡2d˙$Nm[8_ż2ŻżţE–ńí{ úćÂO&qe}ţ cíH@±†ŻpôZô´ö/];5Ľ*š X”ű)>ăÖ}đ¬#ů•đÚü/眎KěŁđYbĺ,›„<ŃÄáhâ­ŚĄ$~Ý*#ýÚăA<¬öqÁCÚë;Tô]Éý@ZÝ˙»ŢýNŘÇ zł.ÔIěŁÄĆ]ĚňŇřĐyžUaÉŹfá˙ņR Źßs2˙'Gn˛ŮDśé˝s(i ¤Ćmëx;6pdI-<Ú7UÎč‹ŇO›zKąš(F˛ťň§Ýd ÄŮ‘o8w™äĚ‹Ĺ:L]™MěhsČudäŇR~ŹgĘ·ż™' 9LPîąÎßo9#¨ˇ¸†~ |ŕb€Q–bŰiďď{X§ÓC_5Č&PnŔŻĚšďó#ëÜč‰~Še4>p®qŢ%71}2ö‚j+‰ŘoĘő–^Är˛c¶÷_ĺÁD÷‘”KńUŽ–˛O4qRČ[ŘyÖ0§‡®Łx±›)gçmrŕú¨şĚö|¸¦Řq Ďbă-ÝfśXÉýr—ľ‚;<#uÖ¬a <`€”vĐXhz„ĺ=:ŇB1ż'……fÁ…ňţĚ+¬EßŢí:÷*—µýĽÔ­-Îť#dfdžď‹5§ź6sH—Ä~Kl·Ú<;^ŕł×BN—ŽdŘ´sső^É<Ż…@†b«,]U;­¸`ë@săţ'˛. §ž`{dÎ*g€UĆ·Ăc9ë:-Ty<˝~‰…ôgŢďx†~kafŕˇ÷Đ‚ĚqôĐ/ Ă3Ś7ש«‰R^rőH ŰQîßŔ`q“Ł~m¶ŽąÎÝXăÍś“Ă®›Š´%ĽËMý¤u žgĂc#ĹkYČ–äjŽĂ”›'@¶aN­—Śď$ú Za{su ř3óX§qUäéÔÔ±áÚw0^Őóůą›‚›şΩ¸J Čg OŕXvôač¶ö]‚Ç Sś§üA”“č|CňÁ91ë=]ń_„˙žđ®6yTť‹łs6š¸Ő”ě7äSÍ&Cw‘Ë#C9Ďşâk9¨Ě77l¶b¦ÜĆňŇQź˙ęĎ/šmĚJg«47jéó?ÍĎĐ ú ěČ9ürSše,öŰĘWRhJ:ö\Ö9 ř7öÇŤ{ŚóĽ±R.Tg;sí—·đ–Ăş¬č1°§‡ }KL[9‹=ę—$ұ-×yëđ†±´{ëőÎIť®Ć÷µů,ď˘ďĎĄüĎÚüÁçň•ńę˙~ˇyžţr°čłvÂűs¶éé!ä”5ŁjőĎĹscÍŽ~GąZ ëü˙kďn€Ü(ĎŽź±)–S’ŚÎnRG¤Ië»3ř¤]Q>$:*—ađť©§A. ‰Lś4‘K]r—¤e“ą€ŽC5$:pd ]I#CŞ+ĂĐĘ@ščč aš–Ü%qŰ–™T—– éűĽď˝{Ňťb2w=˙›1{Ú]IűüŢŹ]zžU×ăŇďĺ¸Őµ>żuÖ™[ŢźhG÷×ÇÖ8«ű® ÔąéŐ¬«ĺ[·¨Ú,ú[·ĆłYĎżžqŢřsg!zpŘ«˝â\X¨9üíŇß|˙đ¸şĆI—¶.ţ-řŐŢ)XŰçSOĆëc—*7üZ ŃćÁĹëÇřő±ŰőxŹ´v.n VżĚŃÄę/č>źYüýÍűşĆŔdű?BŐ—ŹĹ«}ăôHë îłéŇŞů¶Q·6;Đű±ĽVö9TŢqúö#Áú¬&?Ž@@@@@@@@@ ÜŃ8Içu]k6”ß給Ąą'Şĺw8±úóĂłąßÖßUŢŮëÇWö+>;¨żÓŰß|:ńuOčtéCj˙O†ňű˝…Čł*?˙­:N‰ÍŢŰW~ďőcrŠ–j¸Řďµ÷Ú7ë¦+ç$<•űfó.fsO©ĽŠĄxě1ďĘĽmńžĐfŤÍQ‘}Ĺ@ľ×/[fs™P|ÇYŽßćŇI.Ń3ą‡Ô=źM˝Żöű:‰IęÎH\6ďŐ,Mޑɋ•:=í„W+6nuT=Ąť$Lâ)ÍÝבwŁŰMç[HĚŇlÖ¦ę·÷›Đąî6·Ę«­U5MňŚy¦řŠžs«ĺ?ÔÇîxw饺p˘ţŇź%%żfW抮üˇÖ@ź«ňăuß·u/¤Ź|M™‰—úQ7Í=YĺÄvßŐl ÎU>·nëńŘĹzłő)¤M%?Rr`ĺh›# ·‘Ű­ $/EĆńň(ÔýUővݶYŮ,Ýuů~Çăńˇňa˙Ľ*±ÉX´±šX&Ô=»8Ó•mnżşŹ{iî ng»9ćĄMެ¬5őćSo÷ĎÇ#ľź÷ž§ŐĎŐm«˙­ź'&9 f\O\°®uę™MUłÂ>_läśÔ»Ôp˝Ót_·ńöjűÇ{)ąŽ2ďŞüO»«9˙ôőŮü@™Ă×¶NuÇTÍ ůݬ·ó¶™ŻMŚ~›'í>Ç;ľĺďŻîW­ę }Ő±÷)WůdŞ/šă~ĺg?sěÜ,ëĚŘíëł}_ÎirpyÍŮś«ęĄu˙H?ŹÝâDZ7ú9YÝ{ĽţŹĆcWůçsýdÚkŹă©i“®=çĘĽ}GĂŚË©Ć9ţzqÜX‰Íöw[‹l¦řAmńÜČsęştÎź×?ĘŢď¨ňőńŮ­7´ďvTβ?6%®™âüv´K}ą»oŰ'SŤýşýÍ­NŢůŚ?WÚ÷9Ë]™}Lr’¶˛cŘ‹Ío–ؤ–’ôuľŇsYgź—ľnű»ě+}~{ţMzľľZŐáš)>śxqŕŁţh_˙ř,L¨YúšCć%iżëŰ»Ýjy‡Ş]8é¬oŢćź—$FąFSuârfç¶^m-űĘŘ—y˛ý§:Wĺť'㱋7ki'é“»´“íźťă\rÇc«kcu÷g‰˝óZ]›1p|ZóhďęŐÎRă,¦ű¸ÄŮyÎío^‘¬žďŹkiç™âŻą®WVőââIݶ¦+~©Gi č\÷Ű•áPőţäBt‡;T˝60ó¶X¨Z”ę~ĺí-ŮěÇTÝŐ¨JiżŐŻ1$mnĽĚµvwמPµV~ŞrÝ‹şŹ…íăâÖywRĆ€Ú_[*ź@Ě_öře)×”ŁůÜ^5G$»ő1S{)ŇúTÜűé şľíTă»®ş6OÎćNrÔç}^—}§+ëü9^Ő:cşR \ŤătéâÄÖÂ%ŽŚ×ęłQ!˛W·Źx4rUďěw6÷ 3źú„Şeđ%uľ˝*)ă_âłs¶ťÓ䱪·Ł>sźí̬©ë~ \†äµ‚üłm:»2¦ößhŢÔU“żŘë09v™ŰäqçůLć¬téôdć唎Őń.ŃË ÇjŹMć_ą®’ń,sšŤ«3ćÁj]Ő´<É•ó’˝ëüŰY¦ŕ©Ú-¨ąËĆw´e­x§™Ďőß·–j˛ŘçÜ®läó—ĚŃÖŁR٨ă\ßÜŠxGó15_¦Źu4żŞ™Uu/O¨Zúś$×ŐrC÷WY'cWúý[š«†ŐßNB«m7Y:ެ˙y`>•óŹ_ú»ą>Qgóú*÷DRâ]~˝ÚůZaú]ý]ĚŹUŽ[Ő‰Ô}ü­Ő·¨ŐóŇĚšÍΕוNzŞFŻşf™.DţYőńęóVŢ÷Ź-Őł S›ľÚ±¶ÎŇ×ő—ńc}µçś(ۇŞoňÇů‰q € € € € € € € € € € éĘýýôÉöÍ+ľ§.Çßą,qxě=ÎŢ_Dĺ'µÜLá’@ĺFľVc[_EĺŔwĺÂMW&|ÉQKÉ×)–:6ţ¶×úľÇăy6VűŢ·Ě]Ţó;ë’7¸µ`ňQ–r S‹5ěłĂ°|LĹwŤĘMë8gs׸*TŐ]:Đ·­`#’ÜCÉ+“Ľ”N E??sżßóÎކL2)ýUrĆlÎŤÄ÷÷ĹĎĆweú“¦ţŽÉůM—nr§+Tţä)ÉĚLžµę2ŇZ­ăÍąyÇëŞY`óĹ ‘wŞ\ÉŐĂ·Ě=¨ŰĐ«}Ŕ]ß<|éż?|Á`őS+ús¦÷ó.w¤u‘žwĚ4ůÜ27I^¬äŽŮc.Dţw1łO¦ ÷ôž¸ 9_ĺ˙~;1űˇ3xÖÝÉgrŹ'ďśöu‚°L—~KŹUÓ¦&˙·°'íÚ¸;sÖżźúfBúĽÄj˙EZTťšwąťąĐ2®ĚÄC1®;ŰÖäÉŮŘäß%›®ěOÚ~!ąŢrľ’çJeµüfÝĆ;ł¦˙ˇ]{ä>›őŁäŢĺß§^bńj›t›M¶gt.ĽÉy6ĎşŇd´ľ±Ř§wz<—ć®qL˙ťP9ĚsÉúŘç‡Äjë9č¤ÚgU»i{“'l¶Č}íU~wb°úyë|ęw㪾A`󲆪eťďXű÷đŘ…]óÔż«š,&î§;ÚÍöw3ö­Gç9M9Ć[÷řç?»OP–í蝪}Ę:&©ç ÇeóőĄMďSůßßĘÝ­·›k4łôŤ]™—ÝÓęcţůMÚ~ş2â¬@_ŽÇÎŐcu!ZÔq©üćÄPő”3ëęzDb–ř˘_WŰŢěHMŰ·Ą];měz3.$ořOw#WŇőĄMĄťŰŃk{î’Xlż•úwv޶1JŽż\{JË?{í=]‰jCy˝ ý VĎŐç {n’ëÍőÍëŐőäM:ź]b“soµ|łÓŽ>®ă0×*¦Ź‹ŞŐ¤űĘLńr˝ś®lvÓĄĄs[Đb^~WĎŻŞÖHŇĚĹfľ><Ó5‡:ĎKŞn‡öi |TÇ&cZÚY–r ŢŽnTu6şOwúËü,Çoű¬Ä*mřC‹ě·®uďps䡞ńȵ™Ô8Qµ>ÜŮÜCŞÎˇ{ž˛1<˛W·›},ËąTI__ÔÇFŐßRqUŻeË`őçđX5)ă[®MĄfËdű!÷z,sşW{ăŠ×é|Í ýž)|L÷ŮĽó>őů)ÝŐ–éŇŁî‹?Öëfsëśmůďč1-c\ţIěvŽ RLżč±ě‹śš”:+Ň_Íg‡'ÜćČsŞ~G~ËtĺËń™â»őVôó1Žv$ßO]ęçĺmż0lS÷O]‘wŃřqüŢKnÓy°ő±żÓy7Łů[śŃü6öhÖŽwHĺ[ĺéŢŻ[ ůżťĎńj÷$lž°ä†ŞśßĐç-Ďo–ÜŃ™'VĆU-ż¨úó„ľ÷ő@µ|Lc Ó.żĎ?čšÚ~޶Ä$ůÁĺĆ÷şú­¬“Xs¦đd×ö Äs¬Ç°ÔĆ}}Ąąu;šÜ`ó “íď%ĚýĚ—ę8äťßSőĂ":f•;ëL5ˇéëéŇ»tÎ÷żŞĽg‰PKĽ’=›»NÇáŐŽÄ«g/Ćdă–}Żw$ç[ňJ«ĺçCŐć&ç»ŻŻżů´cë3Č<ĄęYč8Őúxµüý»ă=ŕ׫k5ŮľvĹ\¬ýěőŢOr~çSŹ©š+}}¶¶­±äx_ôăz2žű›Ó*ß{ŁŽ_Ő#q·ç?íţh`8Tą“Ş®ťß'mŽżßFżpăDiîsşżËv»m¦¸ÓŢëÝNżěűÍĄ*~>¬ôg3w™şhňÚ—eĎV磛ő·ńžV˙kosäKş˝˝ÚZeÎźß)Í KM‰MÎ_Ž÷q[ëŢCz ›:[Kőj¤ŻË8l:T1«yz±ÍžrĽÚz=~%f©±2Őř„«ę7čur &1?¬ŻĎĚą\ÖÉ|ĐŽnŐí––vU[ÚZ ŐżtnhG©/#sÖň$>Ű˙ÍuŚŮc{~Úźë–?'¨ŹĄý¤ŹUżâĎK¶Ë1ďqŢ©Ç|¦đ]ŻCöµ1{5[“*¨Ńő>.}]ˇĆŻś«ĆcŁŞÎßmşŻćť?îj?UĂ!!×^®w~×úŢŻ쵹Śé›é/úsŃGbuUWć7tűşŢÉ‹ź%nM,Dř}ÁD• uüłąýţç$Ç[íÇ2›»SÇľ-˙˝ěoľ¬j^nqćS—:—wčÚkÁnŐŢG7›Ű=\-_©®?SýwŹnËté*mPܵy<ö^oďg‡íÎěo&˛ŮGüv–Js? m{K‹”Ţ˙«~·ű;Ţżśˇę@®Xo·łD@@@@@@@@@@@@O`¦řî|ęŤËrMś’/+9ŔŐňż©ZˇĎ=r˝żJĘ}Ë%çwޱŰĎťělU‰Yţ9Ţd˛>–ęéҹЗx«Wwĺ´/?fÉm—üÉĄ•mŐr1Ô9…é҆äBt›csÚ—ÇkkŻô‘uÁFóŰö±-ŤÜuˇŻëКܞ¨–÷ýܶójó]&ýÍ·­0 GëvĺLńY?®íygsçÖöxe8]şB·sŢůä 3–GkÍtĆÚů»Ş+·sü„hc[¦pžßÖvK@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@×.đ˙ýP"ˤ•nipype-0.11.0/nipype/testing/data/tpm_02.nii.gz000066400000000000000000004207611257611314500212270ustar00rootroot00000000000000‹|†S˙normtpm_02.niiě˝ |\Uą÷żQy5ĐTą%@ŰĚžÉá’‚i ¨¨)^1ĘßדŔQĎ<4őxÔ)ŃiÁKBńBŞ€¦UńB ^!©7ÎpT0©ŽxIQÔţ×w­yö^3™”&ťI|ŇĎtíËÚk?żßó¬g­˝g=ĎĽiŻ H<éßÓÖŕUćłWá_ńűŰ}mApâ‰ń‡“Ď '»m[y‰ýżĚŻXóÖ·žţ®5˙ňÖ5źzÖ»N5ÜśLýC™Š»y,ńźČhËŰ †Ű‹Ď±'Ǩ#ŕí3ő‹˙Î]ž*> {Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (ĘŔ"c #&ożi`Ĺţůg¦™čÓÄ˝eŕ´ĆiKĽ§ćű mim ‚ľ¶CżEąřţ˝ö†&¤ť:jW¤żzÆU“Źü»Ĺ î{Î=kÁáÎwś‘:żf2ĎŮS’g¶?v¤‡’ĺđőľ*hZš{˙2Îu·_nŻY2ą·­»mbbŐďëi»ńK©/ݧ\k{ćX}î*ú\ŰM7޸J$řĹg¶6fŹHM6d#ÜŰk‡Ăş|‡Ý_;µqu·ôŻ W‰ĂłMúŕ>mżzč_#¬×_×mK» «DA[:üj Yůř”“uK˙”µ÷moYŐ=.)xsß}…‡uáéŘĂҶÁôÁ c›ôEđ˘7ďĽÝ\S˙ôHďő§ě°Gn}éŞ_ÜŘ/x˙űľ3Ú°ď…؇Kńřűćłľ×?Ćvw{o¸2ófۇ·µ\›8>S—Ü^űĆäťwÜŃŠžń[c٧µÝs÷Ý«ţpâ[ŁľRÚÎBÚO‡{%7 ż1\ťĂtř`„{`ôĐäk;·Ů>ű¤>Ű:;×FşÇwa#[ú/ŚŽ-$|O&ËTíźuůî°%3ľ<®Ű×öÁÇO·ýUĘŹ ¶rŢř»¦µSŻ^”Xß–ţ‹­žĂˇ+V,ÍŤŮľ‹Ž_ĐVk?ŰŹoh{ŕčcŰčĎrÍS©Ěw¤—×ç 7\uP›`/dF“ɡ“l*`6XíĽ«˝÷Nkßă-+ŤíşńçŔżt·1é­y(•Ošăë›Ú{ßUčó‹ýTí…Çë;Ţ)žŢšOěqăEúłĂçŮm:L™ąçeßÖ®smą¦ţ™áŮ\äç;ęɆ͑/^™Yáéňv;ç_oÍAIúúbÇúdň§Ă/•hYľ23nmţˇuř´§öߦ7ľäČĚřŃË6ŽĽĚżźZłŹ ˘•™;4ßńÁĂ×NŐ6ŚuŐ™żŮřS q1šˇ‘˙8$ßqŕˇKs4źŃ=e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@ř{g ×Soăh’CçĚ*¶ÄÄžEńU›†żć;ö)ŠËZĽné˙rₚçX9áŹFňgú–M6Ľt—ń_v饭áĐHrećäť§#ßqw8xÎ2v·/ŹbÍ\||źŤýţÓ㏷^U^z^7~`/çË÷xípÓX×ţM﬿~Y]ţ˘iúÎĽyď¦Gj­}óý°—ÇAâI)‰ŻÉA *ný<řŔ™6vÝÇ<ŃňÝÄĘĚ˝‰;»ÜÄA?ofęnků×$ú$÷9 Čgŕă-Ţö[ź˙í+ÖŻo%˙B©ŚČÝ˝ĹÚúŕč•‘ţWf®hÚ4|ţň-ý,öíµ#¶ÎŽ;V‘w†śđćc”|4ţ±ůGßń»=D96Šer1ÎpAŠ[ ±ě~߬™ükr«±×-ćÜc3čőꥯłř%GKśÇ#–alY™$·H9Ü™©wN}®i{톂_Źą)˝6Ć×gy+>żF·ě{’ľWxiî«Ć®fJÉ/4Ř ő¦†ČËłçţÂŻĄŁţçëEä÷±°íę8yÇ~öp/ćřLźĽľ×Ýsxął‹Óv2—úžRđ0h|soÍç͸4N´ÜSdߏxy¤D§ŇĆaÇ­±Ľ,”¸pňĹ|˙î}Úś lß+őżNďAŰÚţ~›cG° ;rĐŕë|ŰóRľű<ězaţý`ó™­` çĐ÷Mţ>HĘ|Ş.ż6ő‰ăüIřäužiő—˙JHž’Ń‚­c3čöŹ{¸ďî*ËůŽK‹ž ł_l:;¬±ÇÚ>¶ŤĎÇ ö·˝¨ˇMĆ"i{¬ëµ¶Ţ¦á˙Ó r|1”uů«]>ŠŹŻK¬ťÚÍ˝/XÁ vtzrďĄv޲d˛!Ş»pŠŚ[»ŢÖ­µĎ“ŮwDĎ˝5ßOŇgÁý̧ďXEąŢŘ6}úć-ć±®tô<&í-¦23ţ‹;~#˛ő±® CúűH˙±)ç›ŔůµbdépetMń™…˝gňîXăĎtÓđˇ“7/ĽŁçaoÍ©–ÎŻ©?Á躯í÷˙|ÖŞúܧçü\J[{ęďćĂ-F—×/–˘ńču&ŻĐ^Önë?4ěěü¨µk“+05ţŢÚ¶eß9¶­»}is|ĹSkëÔô—;·öŕ¸a~óÔ˙[7Ţż";pkä랊oč;\pmŻýŔ‘˛ýT-÷ ‚Ăł×ŇŮą·Ĺ}Őč/Ě;…'Íg»XůŘ^űĎGäz?|Mý%68ęň—¶Xń¨ÜĘ€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (óĎ@gçó›në˙µ‰ëţ—YĹX\pç‹mśÎćá§EqFc]ˢř¤ůGňäwYR/ŽťénÂĆ®NŻŰ©ě™Ă~bϧĂSÄŠ'˝ađ@—µ4wRjxxx§×?ąt•­±WpŤ‰—:5ŇÍUŁ_H}é†Z—Ľvß—ć;~µbÓđÖ(đ<Ó˧ś6±łű[Zş|定˙cŤŮ¶píÔkSÄbĂ̇śllÓĆ‹‰dŁçFřĺĄů]äPr±”âő÷]\¸ĺžŮöcú}ů‡ĽĂÄFŠTGe09xßIwńň~˛ —˛íJiuţË™ň-|ÄÁb˝5 EúIďčąŐä(zyr&ޤťŇrOĺqŘfr±,3É,śH ¬`Ą<ÎüŽű–ţ‹ ń±±Ž%/Â/–žY¤Ű8‡Ôő[«ţvîˇuQž ‘QđSúůüăč=×s·ŐůM7ŢqVj»Ňfęçü®}_ŰüĹ9iŞŹÓżĂŰĎx˘ąČ?PšcÂÇXnŰᡵľ¶÷ŽżĽH—?řÝéŃľŘú†+ęâç„_žůŘ>ë–S¬lq,kźÍT#ňĘqňŤ€Ą1űPrŰÄD¤gΗęZ®yÎK˙VTOŽĎÎŇ{HΑa&™ĺ<%ř©74˛4µ¦ţĆĆűÚĐciß•kDײ_\–JTýýR=•óc’gHdĄ\ećWuů““«ÓaÂďÓRGĘO^řĽ"ÝďÉľěłąşˇŃć9KK±k±öťî‚ŕÔt$—ß?¤~9˝“ç缥äęY #xʏÚŮn)vŃŻřź‡Lź†öńMb3âŻK1ßsîY k)ăäŤaF0a»ă-W¦Ňá^v>Ž˝n5ľ™’~šr˛ˇ?z†ŘnçÝAŔüŰÍÍŹö_vŕ4‹oŞö®d®çea®gs"ž•ŕyIôJŮ0uxŰű˘±Ęd]ýçÄxË{w27]ظÍ3d${8ÔjsTĐoki)hęň—ŰgĎěŔo—ɱĹXî\yG˘»ýEŃŚÝď[wËĺdYŚ8‘ą._gçŹú§±y«ű5őE}—zßé©7ąAëMÓ˙/ĽóÖŹDĎaś[LMŐF¶‰ŹŮMîҰ»ýŁ‘Ýsü‘†Ł“5“ÇXčóp44˛_/rýB.ź—żë(_ľ5őWX ă-™ĺk꯶}¶·ćÚűX×ďÂĚřĄÍ÷Ƥ‰–.:Ě‚·.‚ő_˛?8ú«˙Ť#ý'ąž·4őÖ|´)•ě-äű•úOµ2Ţvä–ţŻť?`ń×LŢéý©†őď ϶–X»6ůąŁÜ;GdO˛9h>4ľů)ťg˘e߆±® Q.šż'˝+Ve@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e`O10Öµ$Z“ż§dŻűŢßqFQ\ÂL÷ÝüęßŘőů“ —”Ť˙źéş…p<ßqt‘Ě5“/·9*ł—XLŁŹ6»<ű€›‡7$r=˙v?íŐÍÄť§C?qWŻď|~jh¤?ʲpú2dĆŹ´żŮÜÝ~BóŕčĎlŽ’txĹ˝2óf[ş<}mçîO®‚˘?ł/y ¦—Ä_Ţhrž]±‡w$†×—›×phi˛.ż<îĺ~Ż˝śáĐ9!ż.ńÂ~ӷ˵0żÇr=I!«|DF‰é帋Ő‚îoö”Ť™jďýjX.í”+Ą˝ůEęîf~‹ÜĆćď˘~¬-Ž®*Š'Ş™\»˘1;ţŢpSÇ$ľ˙Og˝®¤Îž@mrhűťIV˙8roŻ]’ęěĽŮb^ťţâ˛ÎÎ m'ωŕňŻń·áµůÍŻ°÷’şS·|lľű·ÍÇŕ˵łmú;9¶×~ÍÚ÷DË=;ńí3Ůɱ˙~źÍWqěí‡GĽ^÷n—Ż$ľ×üčúlťÍÇRNV±?ŃE,›óĹÇw¤ĂxxÉű mÉőrť`¤ü®ÉŻ%Çăr~03Ć–Ăô­ëţ:-ŹČWŢŢ]”{"î Čęxđőȱo–iÇçâyç×ZěeĆ»Şf‘]ô$ňűĄ/§śíĎ “˙mú8,Ǥď˛˙ŤR…~=ź™N^ěů„{±Qô+ňSŇ7ý1|ećÓ)áŤóź˝q•ĎŃ'Íľ\/i“q ;ŹŰŞšjË4ě0˸*ý97cJ©˝ŠüRÖĺłóT?'‹Ź™zľ®Ą/17ŤŹ—«Ę‡Č‘"(E®Ry}>Đ-s.­«ý‰„Ëű××v˝ç“ą¦ÔVÜ˝‚¶UďgśŢ“qn$ÁŚÝĹşű,9ˇD—ýćů8~áĚ÷ ŇŽô©Cyč·Z÷0^ÇőĂﲲK˙ôĺçcÓ/8ł•ÜŤŘĽô|ŰôWđ›ç'kď*ä|ě1ć=©Űé÷Ţ8ň;×x÷ygŘ<:Řď†ÁÁÖł¬ČśÖĺďOlyĆąÍŘ,8ů€ź}>&źA23>hç)ÝíWŰůw1©äR;věúÂô;/¬#C#/Kléż1’} fÁŠ­;W,{]ľsĹÉ˝ť&§É EóóâZ oĎÄłŻH‡©ÄöÚĽÍS‘ßmçoŕĹ·cÓl;Űuň/1Ď Éě$ę­ą79Ńň]O×AŔ3Ĺęôe)Ćą[M?Ţ4Ľ,Ňĺ¦áómݵS7Zž&Zľ°¨ŢĄeĆ÷‹°S+÷}qŃűŁŃ®oFĎÔőąUEÜČ5‹Ą<;˛9Gżlmu˛!»<׳ŢrĐýbÄĹUĆĎ™ü&7͋ڦĎpä=_ľdň­+ĚřsTr¨syoÍ—–Ťuýórăź—›÷zÖnŃ_f|‰Ő{]ţß–eĆNěź˙D“ÉgĺíYS˙†źĹ˘ďĆě˝V›†óGl~ú˛G˛…śŹŰă7śá+Ĺ´:}ŚÁ{MdűĄçţţ~ËÖŤ_jńĺ;Öĺ"19|ŁýÎÎkŹ6üǢé×ŮŔę.×ó,kŻ+3'—}/mú¶ÍĂŇÝáëjpô?±N}$Ađ›†×5Ťu˝ÚôÓKšÎ›˘ľ,µ6 ˙ú¨gMnł|ýú„«W=dsťĘŮĹ]Öĺż? o)"0—;ÚL@Oďt߉”ž[űĽÓkvvšÜs•ŤçŐ­›Ďśď÷›ł÷$—çŚY]T¦ňÉ˝Ą\;}mő/9¨b–ą•R”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e ,kę/Y–ëůř˛|ÇEkďG3MŤŮ›‡ß­e^ťîY4k¸l®çŰFćř·}Gúʵkzës*ÂŇ‘>.Úoď˝,ibţíÚďoÜ~»]×z|ćôdľăń i!”+37%żĺYźŞËß”2ńűIó»ÎÓÖ­ăďâ `˘eY!'Ž«$ŢĘŹ•5ůYŽĎ<łůČě@‘}ěIÜ“ [m¬X×ÇČKU*ŰH˙Ł–‡ŐĂ©—rNâ‰ýëe[âśřąÄS—¶6˙űŹ6ÜmrĎÄ:"®Óבśăw¬s=ǧž¬°ëńE҉–×l;nC®™©$vřäŢe6獴3_eöĆ8ůD'ĺdu<8ÉLnˇBßîńđĎŚů–/K|aqťű:F§ő›ęc/–ˇVމŢďşăŽiëí3ă‡[˙4=î·¸m±íď~çĺ…řĘľ6â©«ŹŃżC±L3áőŹ—?ŢrO˘ł3ůęŢšI0G8¨˙Ăśí VŽłÍ99ćâ­}™Ş·MŽ+ÁRΞ}]H˝XŹN®ă3ď Ďś†WęÓĆĎ Ćk?çcáܵŻ=*ş·«[=śĹ-Ϭă+Żx^¤‘_Jr‚± g[^öQ3FĹí ĎľŹQ0Ó¦ÔýË_ţR„ůđăÖsŐýűă‰o-ş§ČBůĺ|Ť_'ŢFÎb;–s~. /çK÷Ý5ŐĹ|ć-§XÎĹ/‰śĺäńýítYf®ŁJ•ö|Ü“>îŰÔ­.bŰşĹěçiđe9Ś)˛ń?śÇĆłűÍc“”ľ _±~ý*áŹ~.uh뼥ô—ůř‹çY’«âŻ^?C>ߏýäÇ?¶řEn×wťśľ,íRß×ů >=n>đĘ=ś˝‰_ňm××č]JĆ+ZŘ4||4^ůsOá‡úč÷1“7ěľg¬__Ë\tOüÉĽŔÉB/í—ľţ7ĺ’Ɇ”±ď$vB?!·‡č\x¤ÇhĂ÷G\ýď{Żă¸çŹő[äD>ôNě$Ď.ß őťßĹIż„#±á±®§Ą®2sió<rŤł w ă;q‰{Bł3ÝógUűgă§žmq®©?.aň7­ťz…éĂNŻc]ý&‡Ë{LŢš×q°°Š,ĽĎts*9“ G7őÖ|by]ľwůĐĂđÂěŔQC#ű&O±zźlřŚ9wĺňÁŃÓLîšďX0Ńň·č§Ľ#Ť[ť˙­Ń--3ůXŁ<*'÷éăц,}–w@v•řmá]®“óßÂCŽÚ8ň ŰOÇ~6jń™ĽżÖĆşŢaýÜŕč’Ź6¬Źě…w˝óŹr×îXźKEc şa>ćžAÜőŮÁđÔô)V7$Źę­ůśĺ­ć9űEśÝiŢ™1÷ôu»Ą‹ĺÍĎ·kUżÖöÚďéÔ—[îŢ[óýČfĺX‡Ţe}šĚ«™k’;ô㿲m®Ě¬ G/D÷m?uvd/ŻËŻŤxŽŰ«îÖ¶–{¬Ž¶µ¬I˝®ł3üŰŽ—„ĆŻĚt4»9cÔç®0N5ľę ;•ďćŚ{—Ů×v•ÁË;$üŘ (lžcłmçňŐE6sëő˙ú„í“qŤřW|l6[\pĆmméÚ?0®ÇϢOkžl83ęółąĂîÔ ‡~Zd§wôĽÉÚ!ß3”űÎfWîeľŁ´mŤËsK\mä̤ß?ŕŮř®´]Ť:.ç{źÉˇ˙ś9ݞnüWa{ď«Rň4Ćęt~|ćmó®Űťq5až•7n•÷˛;«ąósßż{ź6žźy'v|?|šď®ŁyÜÎ[XśgáĎ[}Öç†Ć†«Ó˙÷)ŤwqjIĄV”e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P”ż'¦j74™ß™ÜéZ® )Z·_ŽźĄą“ěú°ş|bA­űóe=>ó‹łłó»^ó&“«„Ľ*>đ@kgçŹvĘkygZßÉZîdćÍ;]ěË1ß۬kEFÖ»µźAŰx™ü$Čő·oŹp°Vű>łĆQâ%K×xĘ>íÂá|ăňď×Ţű°•[Ö¶ş5ůńúc‘•yŻ=?Ĺď¶7fʰzŻËßŐ´qä‡Ć.Ę_3óq_ŠůÝN‡gŮ)ÖTË:ÜҸŘRąďďŘlűgrhéŠîöla-ô®aĆţ%DKf<˛“ůBť/2˛»Ř™úb)^ěľłsmä“ÖN‘‡)×)­+ű3+1†Ř’[·OóýçZůJKú§ôQđ"ďęô?&ßY€ősÄέ̬KËůŇëŮ+ů9˙.w~ľPKĚDyvn§GľÖL:ż˝v/«óĚřW¬ÍĐžß7'ĺŘŹl<ř1ţrďÁÓö™óúřŮńăB"›ČA)6)Çb›tw"f°»ý¦$1Ű-u)%FXŽóoڦ뇌ϟťěs©ăyŕ_ú%qÍrÎ/]ż "ĹßSG| ź €v\N2ÇA9űŢŃ'˛f?X丏ťmâGü>,qÁś»°/°ú¤mŁŰVú3řĄmlĆooŞö5U¶ďXĎŕAV‘ą|;÷űźżŤĽ9cÓľŹóuřÓŹáÄs¶Č}L®Ë…`–qk.Ö:»kbĚČNé»ô7Ń+ۢ‹Ťí—b69‹ć"`âřŁ~wűCÖ·gn°ór´H›ÄçÉ8ŕî1;s«ípăc/÷F/Ăßoě“sČ/˛ 6`Ď­ˇŚcrܵ\KţdŰ8ň˛Űp&í€9Ł‘e>ţb]Łg‘9î×A€˛ďdŹëcŹkęsVw[ ńDĆŽíŘM;VĎ…\ŠfnjëáÇč3Ř‚Ü/öóWîă`.ŤĽ˘óĎ=‹Ťcŕ4:ЏAOůŽßXŰ˝ÇĚÁbîÚüłÉčó(Ű”´űŃ_J®8‘eţK—+%΋ű÷l]ňáEpĐâń)ÜsXĚg}nĚÎWŠÇđůÇXţŽNÎ?ËÇń í yÖÄFÁM)öÁεkęOIůcŘ÷Śçz‰±e{ˇýýhłË=ý˘[d>ą÷2ű,Ń[óů$8±Op˘_öť/ ‚öŢ÷[{ó4úX]ßYhH§ËCŢ wôDë‡Řţ™őĹnN%>ě&ŻÉűú;ݍË?=ŮÝ~B„}zË óČxËĹgcv`y{ďWí3rľăŇřü1Ś®9†]€fećę°łóĺ “Ď8Ń[óÖ°.ßq¶0ŃN—jrďŹŮ8ř\Ďż§‡ż_€ĚŚą`6W¶ýwG_r¬ëu&ŹÇEËŹĚpäöÚŤQžé-/Ě#¬=ßĆŔ‡CÇ$2ăĆ^ű¬^Á N8đ}vv`˝ĹX—˙mô^Ôä•*‰Ł_XXŹĎôFď@,3~é´÷7Ěź|żÎŘĽÁř+ę§Ă“´^Ís¤ äĺoŞv_›sŔ˝S“+ĚśĹ˙×LöÖlłýsÇŽÖÇ ŤnyÚ?˙“ďĘĚóWÜ<0şŕs ĺzę-ÉoĆřSč§ÁĐČÇ úmÚÖňš¦MĂ/L¤ź»Ńä±xÂř©Ó}xÄËDK&Úîn_ŽôOMłÇđüýżdň­+2ăgLóĄí˝ ‘]ŁgĆTŃ·H×ýcôś;ٰ¤iiÎĺŻŮ4<\°™ÇËŽQÇeĆíýL>®÷ŕ´:żĺćĎ~ÖöCîJţďÜńá;íú¸ÍĂÇGë—ÇşŚÖĘuŹ×ľ!ĺ~;^ű÷YKÇÚ0‰K‘ş ±üĄÍEËŻiă÷ŰŻ 3ă÷…ć7­ĂÍĂ?‰°‹ő‚ÄR±íŻűóŻßkZwƱ_śČ-ş’}JůťČÁŃZoŤWyލOěë=Ů.ţěLšęžkřŮŤý–Ęłó}+jâ¨ţöA»NŇ­].ľśÄ ńaMŻ|ŠďU]l3·ËĘÚ[dE73ë§°Ž=3Ĺ›¸uůĹí°~™uĽň»ď`-m—u°§¦ço3đ»ŠÂ;ňń‘XuݱÔ). yhÄęĚ·"uŔnÖkŁc‰±ôĎł-ëŰgÖIeĎMú2•81dć÷éEFgĎn-7}šţŽždŤ·`–ľKI[¬ 'îNÚ)WN´üŘó •Ĺč·V-‰0! ŘÁK\~9=S°S_âJ‡Ë˝ŰNŚ<%:G×R×/ý_ĆJn˙˘ĺ v"'şŮ?ĺl1~l8sRr~CWŽ÷ŕě ‰OâúűěµNSŻď<ĆŽĺřp±}ą–›3żĹ/URżŇ˛ńÜrtž©‡ďAFâ?%ÝI]7żŠm„ă\çh ®ăŔ¤‰S‹°¬ťŞ ±ĄR}ÓgžóÄ †Ăęý™'Ś~ážČŚ~ňż˛:ńŁăČŠfJú¶ř0p÷A¤ľ·«=ŠqŕŘ ™7/ß<üęp˝iËď+ŇžÄ^Ęő•.ŻvsalĘŹůâ>K&źc1źÔ{YÎo(ř!tčű5x‚;ß§›úĺä5żoăĐ\żqą"° ÁĽşˇŃlWóĎé‹Ě1ęăMőąC,ël‰$ľ|čÖĹ ąxC‘[ʱ®_'×Ô˙ÄÚôšúuɳÉ–}­Ţ3u}ç7Ń«‰Řµ÷Eú)}™ŹÜwećEŻá„ń¦Ä]ă|tôÖ4Y~\‘ŕî3mˇsleh䆨Oű>Ě.O‰Üu>Ę7ü#ëłîŢo”—ź'ý»–üép¨©1ű’fě\ęĐ_é ´)~îŘÇo‹m9~ćgą{ÄŘ‘ăjł^|ŚăŘ7tĺŰ%çŕŠsŕ•<⫝̸ŹbÔ¨ëbŻĘÉ1˙Ç ~¤mÂ脸/ô^Ŕ‡üČËGŽśśçĂqęÉÜFęşy¸ÖľwxČŚóŹlçwlď­IŠ ‹Ě˘S°pL8ě‚™űĺ#×úĺyçťQe߼slOvVĆ]ú©ËťăćŕĆÇű8Ń5ă.ýźţË>öL˙Ćć™ďőüń˘§ßRÎŻŠŢqNú$ąÄ7¶Mß<ŕßŮçąb˘ĺĹ©šÉÉyy^*•}®ű5“ä")ţcü±ßćgWĚĂ.ä*“ÂŽe<§ö­Ö踜_eoMë´ÜÔŃß{kF Ţ}˘üÝí *çÎń™ăŠlmiîU)ü«™[żcü°‡5F˝˝ö…ŃśŁkę›R&G@ríÔ/ěqó\főjrŮNĂë?Üa8rßÄmW{Ëĺësw!÷léĚ<‚±Ć`0ą¶"ś&÷JŘ}¨iÉäZ“‡ú‰[»^kýÔŕh—ŮżËâÜćĺˇĚUĺÝ‘ĚĎÝ~đ~­.ż©Hr]eËxnÉ|Ë˝“ŠŹ‘źŮř^ăц’ɡç$łŰÍ÷×$;;/IěŐw@ô®ą¶×ć­˙Ű?‘ÉÓç‘ç9ÜçÓĎÝŔ6ĽŇGÎl˙pUǵíµ6śĆř®2<_ş<$ĹąjťL»ÎöŮoĎ™|i »Ű_”ŘfĆhyá|ş{$óXü¸ß&Zť=‹ŃňFó|ęëy÷[ŢťŇá!)|ŐVăŇás«âC±í©!—˙ywdŐk•e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@Pö ąÇ–¦>k~·n{íďžt}ə헧X ĚÚÍÇÍšďµS/ln<úć_ĽrlŢÖşíKůŽQ»V­xŤŹ[ď3ÚŐ> éÚ˛r×±V;ű†ęŻoś-î‡ÍúĺrňĘ1Ö ˛ögpô˙4Ëď×űÍ:UY›M]ÖLĘ:8Ö>Ęő”¬µ[2yĚ.Ż—ť-†ŮÔ¬Ť\Č+ń6ţ˘°¦Í—ťmÖvűX9&qfĄuý}·Ît6ŇU¶îŕ ±‘˘í˘/·łç XťÎĄ\앳}ęłX®‡ÖĘşGÖÝâ‘Úzę/Ů#ú.Ő“ŹKâd}ŻÎ]÷›ŘYŚmâoěze©Ź=ËÚt¶ů°¶ÖýĆfeuřd­±.»tMŻČ‰ľX§‰ÎllQ‰}łv]ó‘Ř Ú·)m śÉúŃQłžSźkeŤ>÷ă7MźLÖJť'6—µŰČ*k=EďČÎď—#żđ %őe[JąîçĆg™¸ĂT“ÉQăbČťÍs^®»Ęô'üř/ŤľĹć+…i¦vęňĎMŤvýsŠűÁ;ý &rÓŃ1k_чŕbí«Č-ǸžměBä7u"˝"}[®ˇ¤-~ŮŮw_ŰľUÎ[!:DnŮďŕhcŞ.y]ąŁß{yĄ®_bËpW+3źf]pÓĘĚ·l,’áa6ŕןľ=“–*qÜŮŰô{şß§7żyžě­ů©Í[ÎŔ@L$ľělłţ×Ä…ĄúÎŚh×ć‹tSµo´Xeż>÷<®i•ą7ö·%µ«QNÇŚýç6U{|‘¬ť|ˇOó•XŘR;A~üĽ,™ĽŮ®űî­9'j'×óÝ6ąjlLó™¬ŕĺ#ř«4nł3x צßAXČŹuvř+űŔčĎš÷űTß-ó”XF×N¬'öÝßĐČhsV3™±mmy“-·×ľŃ–ŇŽŚurmuJ'«ř–'Ś~¸O{ďťV–•™‹"aל“x(ú:‘—Ňôw;˙’c“ o2ż…űOÉ\Ď™ÖFŇáQ{[ú˙39ٰOR|ŁĚWÜZvîT­żb=; î^«Ó›¬|K&O·ýą÷˛űLA^ń낍8O7§Šcl¨cr›¤ŕꋾ|]í—'ɇÍĐ6BżxÇ,ă™ü6w}Űĺ9ů]_ ‚îö/&M앍çí­™LLŐ'éřžqăŔÄ|ŐÄŤY˝…~n0ŕëĺc|™őýČ%ľ˙Ž?¤.ľa>š{É vŮ^;uŁŐíĐČÝIô‹¬ţ\ĚŮĄ°{bXźŰ‘<óiÝvŢŤËwü»í˙ŕ¶×™6 ľUĚűݢd|džî˙^°´8ĺ…śKÜkŃ!ů¦Ř6±ľv|IšśgČŽŹĄ '8b>ÎŃX9ÎG8˘ Ćvl¨ŰĽS8PéśßÓC#ß6öę|/ů9™öĎ?ŰÚ'öM?Ä÷Qň𲍽RGôKţ l‚ůu{ďÍ6F¶ŘFö4bwl ą÷YĹż-9çŇ$ö)ş–g-_żčÜWňX`;ŘCő}óîsř®o&î7şÝ;Ĺ~Á(úfn8‡-K˝ˇż>»™ç)w}ďŚęňż GĎ oX1íZu¤Ţ˝VłŮůI®çV;n)kđü­€ĚŘ5ÇÁ vt /bHĐŐ~´\»'Yő®ÎMÇg(Ě],l=ňö v9ƶŕ­Ď}ĂÄ÷˙ľ,桑šh.V=©wŻĺ­[‚ď=˙cĺEŻčl|Đ-ďŘ?çü»Öĺżĺ*ńŹ/¤ídϱ©×wŢśL‡ŮüJäóřŘčż4O6dC“ĎŔr6t,ďz/4şgźĽRŰĚ{Đşü?Úů™Źkuú‹V×§¦˙Á¶ËüĽ1{ĘĽöń;z®)Äämąž7%™ůď.ĹĎ~ŘäeYťţ_‹ahäčÄ:;›2ă-vź±lK˙ľ)ň;¸Ü1Ę«F_3~ăyąÜždţ÷µÓłŃű•¸µĘl ľŇgĆ\Ćs‘‹ąVľ#°8M>5kăŻK‡Ńsb9‰V§źő Îă÷#ĄăČÍ÷ŤŤŘ±Śç«‘[_ZÔ7ʵ=×cĚuÝ\#~ľ’ď0śÍĆDZúÜáÚ©%Můޱ·×>h1‡CöşüR“ ń“łĺ•‘Í›yó ™g —Ľwł÷7ă™đs;žÚÜóüľ p_Çłł‡r­VćŘ!^}ĂŃ˝…|1‘{pôĹ‘˝>™Ľá:ż?Ýúă+„C)ႹŞě?YŰ•9ß×ĆĽŠ{#Ó•Q^ č]Źł‹]ż#ď®3ýřşBßĹwĹďľś~ÝŽŻÜÇpRýżźú›ő׆o±s±}ѵ{ľžť<._ŹĂĹ÷xŚë±>Ý;}±}7ŽĚ®ýąÔŢ4ü=óčm¶ŹĘŘL»Čăäśý$?Ľá'é3ňÝy‡|üsátöĹWřyR|ś1qÝŮo9=ŹgiŃý5Ƈ‘_ :WNg/K|…Ě„wž“Ř^7>¸Ë~+nm¦-‡]üăz×đŤc3]UÍăb‡‚»:ß—;°|2r9¨í±jBÓ¶•e@P”e@P”e@P”e@P”e@P”e@P”e@P”e@P*ÄŔTí})Ö¶É“¸ś~ß›ßb/Ťˇ¦>׳Ü˙]ÉéWďů#˛ž)ĆčÖüřű¬ő]2ą·]Ç*뎄Y-őYĆąjŻçś sw˛R]±nQd‹lS˛ö[âňąŽó_.¬ő“µoÔc},k¤dM3ÇX§?+y ň°Ž5ʞF3q şe­ľ‘ĂĆ=‚EÖ–±ÍNXßIŚż‡ěsÁůÇÎą˝jëňwĆ8‘ ůŔ J‡'¶kđ°VđPn0'^fÖÎąz˛n’}úHĽ–ĐťÄđ(uărgŇUăś[«Śí‰N‘ЉC>‰Y9żdň~ۧE¬u§žÔŮ•ŇĹGT[ą6cŠl&¦łŚ\°ř¶ 7ńúĐŔ^çâ‚{ Ţ@>ŇţLĄă¬śŚ•;¶ňµ7–üŢtü"r“żőą`F>‰a‘:”âď/žşŇĆl‘ýŻäęôŰMţ‹Iś‚Ť1ôý"×ÉţT=ÎÝa,Ť» Č>·5$ćü3]õôbáŃŽůÝF‹]4őúÎYěŤŮRô%Ú˛ —r_©[Ť˛śžkđAĚnµëşÁÜ=ĚĘ*k°ců¦Ű†ëËA°23ž¸Ł§ľ)z>ńĂví6öţhĂ뢵ÂÄFs?°Çă`5Đş6}Ě÷™ű‚GtJ ·®:† kÚwěxźÍç ë­Ń§ďßd>Âyl‚öşŰObVČ.b/°ˇSÓ˙•/1 Ź×đW3ă±› « n$;đŰ(W`61‰ěŔI“GÇĆ{Ëúkć/ľľÁÁ¸N3mĘ|ÓŘřrŽKrďHl9B°ŤůŔltůg¸&ŽĚ‹b?ßarČ„C{Gzŕ+:– ÁîëZb)ó$Çş.L,Íő$Ĺ~ĄËuč[ü÷©Ţźű­iî çČAü zpج*Šytú+îĂÂťřlÚĂŽ‡Íď,#űTí†p˛áč°î#:.Ő99¦Ş‡—–ű˘\*·`ĚÔZť^gqgN Á\:îĎĄ‰—Ł?»8—“ÄôŁVÁ*:ĄdÜCĎČ0ąî9÷¬Čľ·”ü>0ůŤwr®dFmŢ 037ă]¦Oó|Eţ3ę‚ ű/zĹ'°]źŰËúj±mî!ó6ěC¸ Ťůůëk;oéivŽA˙[E×Ď*<+"»|Љ“1&·=+µix‰‰Ł<ĆÚ±É úąń řń Ř×úýâ.3ŻnMŤ]ó7ľËýHúľ}Jś'ňŠ]‹ŹĹ.ŃqÜ[Î7ű Nxě´Çľř/ž_öäo]‹Ü§˙é}‘­Kź3c”Í•„ŤŠţ1äĽôl–ă ǨÇ8ü#cl3oőôÝCî»0J“ÍłţCć˝2…Ccv|¶:4¸đÁŕ+Ąŕ§ÄŔK?@żf>SŹöµ9˛0P–JńąaÉiÎŻş97öÉ.ŽS‚źűĄ%úĹv·_ťúygVzź…´oúňŠ-ýĎ)š“ЧĄŹRúx…0Ă ĄóÓ Ő®ÉŇ[ł·}6bľ¸&yŁÁ*ţ »řŃ1p2Żă8sú“{϶cžÜmíÔpŃ~éë`ć>ím/”˝5M‰Ü—^ž<>ó­äufţ&ă–Ě[ÉĎV3ůü”›łseĺ˙ţdeéóžYű˘g$y&&÷&˛<ö} óÍÁŃ-Ö§Éő";8ѳۿÝňÓ}f’śk"=řĺąëĚU®Ĺ&¸§ĚE9ľ¦ţˇŠë^tĽÖäéŕ‚ÓůY7Ć^幇ů´ôÍŐéK¬O»jôiE>=ß±>™ďČD˛˘CćäÜëbó\-i—my?ţ^“?(ç)®­-z§$ĽíNąµđÔ7nżýĄ<÷ˇ'ÉcŔý±SŮGć&řśm-ż‹0ť^»|K˙`á™ëÝí/˛ršüµ¶óX0sťë‡ŚM[űs6ľŰ Ď»ióđ‹-V“ł÷ȉ–ňŃ,m:;<Éęž÷řزřf±+ŢÁˇĽç˙Í‘qf źČqƶ\O}‘ýÄRďŢÖöÚĽŃEüěĎ8Ó××gs”Hź#×učĎ”řŘ‹¦¶¦ÖNŐÉTź+ΕeňÔ¤FŚßÇvÁJ)ľĘůXá[F§ňľ‘Ľ ňěÂ}9_úüń@UKĂéYě č×FßÖŻ±ź)čšíŮćŇčůăE6g>ľOôě8rßI}Łá€1ťöůH_‰ËÝ=ţ‹7ĺ˘ńBô ÷–ś1ě“_‚r¶‘/üZ:ÂËëđ]čqKű|gשę–ĺ_ nů^UĆZúĄđ0w)FÚÁgɸhŢ•Eśďţ=f'ť{×gÄý™K[ÍرűňÄń䔣M|ךúë“ď3ţË˝¦Ţ|ţąw:ď3öVšcĘaŢ]Ynޯȸ0b0Ç|Î7^Áăä’÷U2FÉŮÝ/]űŕÄ_Ż©żĹ/wżő…ÚÂyçńÎŢaOüżcۮ޻sžíyˇ2Łr) wÖ?´laH˘R(Ę€2  ě Ks÷-şď%v—ÖQ”e@P”e@P”e@P”e@P”e@Xü t·ßf×:łN7{Ŕ!ö÷!gB5Öµ&Š—Ş™|ë“®ź›©ť={<^"ë"XŹ:ŢňšěÓëQźőV3Ż]ßłČäîťťýÍ«ízjde=¬ż¶šuů˛Ć‹ó“ ŻłkaXäŻé/ׯtĽäzŹlAî»çĘXW¬‘sk¬ó{őÚu›yłf,˛¶m·^1ľ~ŔÉďs˝[÷źŹăś9¶§˙ś\čĐ×+ű¬Ď-])zä|®gźk:eÍ=őý6¨+ęř¸YşgÇ2‰lR–ę‰ă˛Ö^ę°¦ťíRŰ–óçŔşVđR[‘5ľ÷wĽ¸Ä7T›…™ńŠĚĄĄŹŮů'·ÎŰ×k”'ěő x¤áÓ5ĎI·Ăš8Öp;î'ŐĆ)í—Ç+ş NęÇ…Ř)72ł^ÖBË:|ŽIx<˘ÖΚwëżX;ĚÚiż]‘ŞZ%ľ™űŮ 9Y/?Öő¬ćýó7%%ŽJâÖŃ®am$ľZÖľÓ߉»p||ůxÄŽ9Vî%6.ő;nM•ýšÓ1>\l€‹ĂG‡ JÖîc‹|¨‹üţZw‘†MĂ şňű€Ô‘2^Ë[jkŐŇ2íş{‘›DôYNFtJü/x©'uĺúŇ’4ÔÍŚźgbaźž‚3ę”–˘wYç+q1ŐD,˛J_ă÷.9&1Urß4pCrMý)I°c»Ä6Ëyż¤-ě[ úŢÖrY”ŁCęĘ=Ĺ/pÜÍĐC5˙Ü:uń3RŠ\”čBěß~YĎî×ó· }}q[ŘÄ–ţc“wôÄůĹüşrOĆvŃwµ»y@q?[óeÂÖĎ´9wŐG/#¦†1§¸†Ľ -_HŇĎŃ#x}ůĄ}?3ľW`çłÎGřWUn»ţ%E¶éË-2˙ôKîÚŮů|÷…ݢk‰Ý`.‚ß’ëhë6s n¨Ëőé(6©xÎ*×Ŕ…Ř8sÜʡ,×’Ósé<ËßÇ·®©Ť &ňŃblŹ’Ó†ŁqÜ,ýₚIďyŇÝ“üxđ w¶˙ŰŕşÁBžZ©Ţź‹uÎy^X(üljh$ZűfěŰú4ŁÇ‰–[íÜb¬kIs}îy.8áC}ú4ĄŃy+cc÷‚+á ěĚiî1}c>ňŚu}!9Ůđ#»y>šĘ§$–“ţčĆ-7^c§äZ‹í«ćĽčaK˙”µĄą›l‰/|78é×ŕ–±ŠóĢžŮL3âW¤Ĺů)×N]™ômZä@§Č‹üŕe®BL)ň;{(–oÇŽv-ţťëŕ ÜÎ§ąś Ňľp\ÜĘüî}Éô+±m‘ »·ĚŹÁŤ=˘/>RŹRŽ;–kŻÔ%O‘Űž_|ĄwËŤ}ÎÚ¦‹?{sĺşńŻ„"?ú+ľ‡Rl]8`źşbÓ”p üŔ‹ŕÝŇ˙‚˘ŰR™ć{˙‘†˙Hâg3É#ěŘ)ňŁkú;ř)ů€\rŚş“ !Nnăy<Ď29łj“Í+3‡-(ĽÂo:lMŽţ,üEËľ!äă÷ođó+|€źzâĂň¦o¸~+­2Ţ_”\2ůî‰Ůä?´ö~Hv  ,őŮ`á#XÁYúá<¸±ă|Ç‘É-ýď5ąO‹Ć˝–Ěx¸ÍÄÁ&‡ÖÎű»ŔË.˝Ô>óĹ‚ń–„Í™ÁśŞ»ÝĺĄuçÍüŰŕđuŠn±iřŕ8>ť}0S’Ϥpm„ן»1'1u§ÉŕËS©mó|Tđ›ÎGńwÇg›yoôůb|x:<ÄÎ7đYČN0YĽ¦Ź ^t N>č¸óGIýŇđ†Ě›‡·Z{á>´!ţ[ŢŻpźŢšĎ¤¸7\»÷k•BëÚ‘92˛ń~oŢÓ˛Ťü2‡ŕ ÉGŇÝţDĘÇ˵ҏŃ3Ďâźŕö¤Čnň›†2ĆĎÉ2_Ťóä‰ô‰?ßň± ëßé—w]~,ż=ňŚ&“×3ňW·ËőŘ6÷“<`?}{ŘśÝöłź­¨ŽĂˇÖ¤ĚsŃ©ô3rHĄ«ÓˇÁ÷7‘¤ÎĐČgkęźŮTź;Çâ»a`?3™LÔ寲öĽ—Ń+uĹp=÷tďť‚=ßä'192řs}Mň¸c•ţßÝ{áĎ乎»ôä@χȄF'™ńzűŽţÔô˝ă©éO…ćŞđŢ$đÇŚżbż\OÁ~Éů5×Z{áKÚŻn×bĚâKůŽe¬ëµćůňhkŻŚ;⇱Qę1‡ôü1ď­Ę»úĐsé÷wď-đI"ą‡d~KÉű&“»«*ół5ö{1“÷ÇÚŞĂŹnŚĽăUŁÇ†Č·iřÇvÎ ň“Ľĺ%Ńs˝ź?euúŢh>ő“Íg¶žyË)ř¶šÉkŤüîy ·dŢÜäúP_ŰšöŻpóTk˘k±ę”î;5tÉýČM28Ňoô .Ź4ňą>ěr˝ţ—É÷úý»÷i3ą•ű>qÂŞ|ň˝â żůpŇłł«~}ÂŐ«Ţx×*ůÝńĹňśâl‡»Äą}s:ü|ŐľŻC&ąOiŮůŃýSý&o}:K‘1~`pÖçN˛¶ďŽ˙źëy}¤s8’¶é2Gsöďľß?Ďž2N·Vů=÷ýűnŐŚ/í7ň>q'™‡ˇçŮäÝ19ĘW<{ň;Qź$‡)>ĚôaÚ3şL™śźMđÉľy˙ďĺ*©<Îé-ç !WsOô#¸§_łó#˙ÔţD‘Č<‡\ZčSľ'Ëť·[ÉłqŢk‡?ĆęúveîĺćńôiÁ]óĚ1eó™Uć.łiĄłóýIçoe›ÍŐ»ZWÚvĺĆ­n¸«Wk=e@P”e`¶ L66fŻ.š̶ŤĹV˘ĺŘpíÔď˘yćb“.ňžšîŽŢméżřď&żÔę´ű ˛MĂ_ŽđĎ…żĹrMfü‹s{íů©ŰúóW6ľXt¤r*Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę€2 5ś‰ĚřŐ)âÜXĎ8ѲOŮőLSµn}ŕťfm[Íä1©rkâĄÍ…XŢűµo´żČ:MÖżÉ:gÖ‚°Č­7w’ďźż+”5áśgÍ#ëëdÝ%ëcŻÍDë¨fÖŤĹë?Ýşđ±¦IÖ˙Žł^QÖN ^Ö0űëńĄ>%kHY şp0Çk\Jcż‘—ßŰňń áýúëZĺĽÄ-Č>ëÖŮžŞřZüŮ2éđ˛VŹuƲ^Qä”RÖúĘytÍşQö};`˝kĂ křmއx­_ĚíÖ® ¬o­ôłŻË€N yeťžŕ•Rú.:%®WÖ‹ľ‰‡Ą YKĘuđČ:×âµg˛ŢsöďŢ/ÁKě>ëç鿬Y#ž€¸ äukú]ýRŮńkŕ"V¸‘ŇÇîÖ·ĆKťÝðëW_eÖarOäŔ6‘9Ž#™.×—M=ň8í3–ąŻ ý–ra¸ŠęH}©#vAóĺפoŠÜĺú›ś“~üő‹ř5ú´Čo0Ú5ëđ"×H_đuLÜ,<űkČw][s«)kmʼn|;+±}l»Gôg°Šţ¸ĚÄ)/~ .\÷nX~~â[«:†ů>Vp"‹/“Ż+ü/ýĚ`çô‹­8 pďâ E kęs!üH;”b[~śěÝ6ŽÉÍ[äÚj”ÂuąńV8 Ä2ă)đ’·_.q‘Ą6Â>>ĐéŘĺ@v?Ď<Ń®źłCb®ťŞ6~ă­ŃgN)z@lÖÇŚ­ň3xEÇ~ߤ>mŘvÁ¬Ĺ—vĹžŔ(ąĹ8çúHu0Ż ßŹ[}‹­ůńifŢlűXoÍ9I0‰źÁŕ—2®Łëşüďě5ś—ëŘ–ąZż™Ç˵Le}ۢgŰ^»Ě̡ÜĆsH]ţ˙5ŁoôŚ]đ_F˝r¸ĺzş4×că®dż’%Ď~üżŻ.÷—`#žť’3 ů‘»ŢŇźhžhÉصB~ţÎ1ţ`×`înżÜĆäIŰ26ăGDßî\%ŃÍÜz+ľŻáć*ř+‘_lŰő˙ XSz8ŮpNŇÄYě ŹĚąŕ ŽŔ̸Ĺu‚Ů/]¬`_[!ľ´ŕGf–wwĎ4fášąrąľ)> ź f䆣ŘWď{}ŘŮůOvŤXŇä¬Á˙˘GéÓ`ĆÎáAÚ#ţPt ~d –T¸MŚĎ\8(Ě÷l<xäľR"óMäćCđ€›çă­]'Eď2ăg$]Ľ°‹UŁXĽžż–vŹ51ŕl3flŻ}4)ăĺy6k.Hv÷—żLĆ/0’; ]Óź±[9‡Üř„ÎΓšK߀=űc”`¦Ün|f:<)ŮÝů¬txV*3D<î.’'»ľ>7­IfĚرłEO®±SÎałśŁDŻ”đAéĚQ+ăóO™{ŕG/ńňHlľŘ¤uZqđd2Wę|®çB#ťňc—ńs7=Ł;°Éť[ŕĂ>ýžu)坌˙&oąZ{kNM}®Â±ÝsĺŮĐď.‰kDçůŽ7ŮśiŘ*öŤÁĂ6ŘřČq°Ëy|wń3Hp˝WsÎ5v|ĄäŇ:O]i}‹Ř">fpt•µ5°™ÁXŞWěšcpľ©ĂsćDËľÎgş9 ÷€ą7ĺŇÜAUyO”82%c2}’ţ—3:ĺžôařwý×É&ĎňĽŰ¶ó’Bß]bçŚáŕ3űŕ†Úä/kňF2&şąĄk—zĚ{iyüů|¸÷MîúĘü/\Á%E1©îýv*¸‰i—|2`cŽĺŰ5Ľ!?Ń5p¸ń'¶v}3¤źČĽ^ř—żÍ>ľáÓ&F•6ŘŻ Ö 8˝3gÇQyŽ%ľţ"śî>}m×Ř|îůXŽ[µ¶Ŕű0ńěNäÄ7Ăď8ĆűłÉmßI­Nßfsx˙˘-§Ľ;$?żĄ˙şflEĆ‹Ja¦ěUî-6ś‚ĎÝËŤ˝r ůL Č;|pń®Oň„ŃwÁŚľů¬ůŽj6ç¬Îđ‹Ôˇ˝~϶>i¶ÉßÁĽ^îĺJiĄ2ĄČ &§ŠőQ"ú÷spôJérŃl°sk$a|ťlč7ÓΤč«ăöű‰>{>×óĺBî÷lŤmŁC8ĆFdĂ1Ú–÷DÔ“ń»2h]+ţ3$÷svNG}m_8ÍĚOúÚF­_íkĂw±®ÎÎçFó¤ń–sk§jí\ćÔt˝2ŠCYš;+%ď|„Oúśş~‚ľÉORś…ůk:Šx­n~ďű”~°OÚďnN2ş+üôUŃ3ýˇfr›•g˘ĺËŃĽMäZSořôÉk›LT«c±'ßW ĂpčŠćěŔÓ Ü9YDďČUi=»v—Ă€\®?»űžgúÖęôŰ-–ű;ŇIňá[ĐŹČ2ÚëYŢsđüŚś2®őOMŮ<’â«áĆçŻ5÷09<¬=ĽŢQńgÜç3f Ź•+űÚŢcďן)ă÷űÝoßaýsľăŚPr>q\0üŁř2Ćç“‘Ě˝—çš~Í|FĆđňŁářĄőą!ĎF\ŰÔ•gŰĘáô[r÷á~3řbć'[»j“ćýÇ Žů6 Vú6/ăĂ|˝Á`ŢéZ› `˙śŁßeÁmcOŘŚ™ËG}uhäŰ!ÇůP‡şîy”»WăĎŘw!/ÇĐH’ů/6~Ą!{€ÉŁAÎÇ ý˛·ć ›LćGĽă źŰyŰťŚ+3…î·Üó±´Aéě)¶ô˙§y×đŁ0×óńdoÍ÷mż~´!JŞZÚ|÷yî=ł´ąÁJž§ÁŃOšw=ăÉřţîýŻÉ#•B×;vÜobaBrôÖçţ+u·±qćŤŕlď˝BćËVżŘ7XáŚ9­}ţ4üPć;6s–Đä+ÚŻ•÷G&_Zˇo‹DŐ*Ý÷j´ŽÎř­¶ýţŤĚ‡rűŹż)×ęúhĚ” éĚöŻ'Óřţ/9T#VťÍ`K,r\Ć3î_Ý?'÷E‡|ŕ]ä ,}?Ĺł~j&ą®ą!ĺžâ«Óź2óžř^lK-ůĂťŹŻ©î–“ĹäĎJ‚ąTÇţ˝G3á1&żŇ„ɇé/Ý.ĹěÎÇĹźcăř}ăOüĆü>c%±ÍÔ:AÖGř2–ö;˙ślKżĹNĄ>>ËŹe(ő \ëűiKÖĎ$gĄŽËďK2vČ˝)ĄźúÇŘ;$ž\Ą>Ť:؉Ńe+qâ¬ćC®˙zÚg;çÜłîó<»ľşR§·#÷ŚÇÖ>ęűp˘>¬±—ü2ÄbˇglyĄ-x ^)Äbáű¤ďŕ÷¸ĽâĂ›.k%ŽŔ)\»5÷®ŻĘďš#‡|°MÖďłO˙#Vü`˙-vMŽŰ1ŮčÚ·k¸cß?F}#ŘfŽćl¬Ë·AŢ7týmdřŚńÍ‚—}ŁË(öóÜśgĚpBĚź{†óŕĄOHAŻ~¤ĚwüŞšk®’ÄÍpńcČ%lĐ÷«`AÇ#‰Ü`ÄW…}ęŔ‹”Ä•P_Ú,WĆ<óěÎů$«ě1=čţť糊ýrĘp€ Nřř¶I]ÚĶůHĚŽ\/y|ě¦MSNěcXÜ^eńÖć?‘,Ä5Z˝âł«Ä—ř2‰®É‡oŘŃ+ź5ő·$Ű{ďLć;žecQĐ=ý†±})ýľĎ}¸'qŐ<§pN>•Eě·۲ŕöńŠŹ•cŕµú3ö ^lÚü®»}&~ ĺž¦Ćě˙&Ń)×Y»/ř;ą^řóÇBúk ‹m h“ß ÷ĄÝÝíúÜűmlźČC ×.‡Žă;? âVÁŤýĘuď¬?%±µëP»n˛á´”ôoě=SOl[®‘’ľLßZ‘o’¸d™çH âîâôŻß^»!$Ö\"ö˝2S‡ŢĘćđ‡Ř¨k«ĎŘöO’Ks˙×b^™ů´ńą.Ż %|I}±é?čŐô‘¨o fîÁµř_ŢJlűă˛đÎ}yźCéň˙Ķ/ú¦.çMŢ›OŠĽLC#?ôň‰p 3WüfxŚroćž§ď?]K•řż.O¬[Ś9ŕ=§żřĽą ¸ż‹ˇrsQbˇÄ˙ 3ú3%¶(ý”mŃ'śI}˙^l㣧źs뢥îuFžěŔ~~ć|&ö…ťŃ·čĎľ~ńkţĽ”y9¶‡ßĆ— Fú6 v¶©óŘżĽĚ¶I2ÇŹŻ_9îl<ÖNťg0şXúîö[’k§.®(ć j:SřOd+öCl9ú–>G‰îń'nŢ`•1Xü°ÍśšóÂmC)óÁ(ş¤„Sňüâ qyήF»ľ—:ą÷żĂá ä©!I©]ąq"8Žś`2q®»ýţ¨ż‚‹sŕćNÁË1žźŘ3úĆţá’~B;ţ|ĎÔ·ď’î3}›sŘń•ÜźűJqüĐĘÜ˙Ŕ…?bŮ^űÂäżÝŠß–~É}>ëĺęŔÝü(Ŕ,¸±mŃ+XĺĂ1ć$´3ѲÁň%X¤ä^Ča°O›Ë˝×ÄÇö›j8ĂÎćŽÖ]ů„á“¶¸§ÓCźÍźńŃÄôŰřfdýDłŻ7fşg đˇ[tĚĽKpŇŻ9‡ 0—<;J?v:ł~Ýę’}Éw‰,&ř„Ďî+u/÷rNÍ»ë»ÎgúháţApáVîŐ=Îúú7úäNŔVô^Á,:§ł{O R:[帱kÓ´Á˝đ)đož§”ءpäúż´1÷RŢŐ 6)·ôß›jĚľÁ‹×ĺŽrÄ žvoäS‘ÉöŮft+6Ž~Á-NŢÁl4mg,›ŻlśŹýJôÖ´&ĹîäľnĚ–ć^úľSć˝nľ!m:ś&[3ýśs?5˛ň|,̨Ů[sG&˛¶żžš~(ŮSŠÍ ĆyWlçfŘ 6o˘Ű\Ď>ÍűL>ń'‚UĘ‹§j+2VÉ{]dńuN|ÚöÚ_'ëňď,Ä•8üČŕx‘w… r›†—Ůś5“™D8ô|ž±§šü<áĐ'Ěg$Áp±é3`tz ‚©ÚóCgăŇŠ»ďičořKçëäüî•ŰkßfçY˘cá®/¨iŠŢQĐO}NıëMĂKŕßÚgcöógŘëňź-Š»iĚ^oű mo0s€ŢšIk«Ó_sŰX×uv_d^îÖâ«]\=ý‹ăŹ™|$Ěů-‹Ő鋌®.[qGĎĺÉO–řPdBă-[R`hi Mއfxý˛µĂŢ˦ÂĺzBůÎr:÷‰űžšţyÓDËk-/R[çęTę±UtI.ĄMĂçŰ< Wpű Ű{˙”|,Îç8ű+řú`uz  Ł —}Ą1{J3ůH2ßjµřáwÍëiÎ}ÁňúΕ¶_8ź÷#Á_)ĽŇŽ›cÄ÷aŢ®ÉiIť©Úď™4ëŁç‘CćőąĎ[{^;uˇĹN_Áϧät•ďíäZîÁxE»ŚĹܧ·ćůMŘŮoÍÇĎeőĂÍΩSŮżł“+FGG[ÍsbcŽČ*8ą·ń˝–“ÔËÝĘ1óü“3öÎ>K&ŻM‚ß}ĺî#s0ÚĹÎŽĎŚŰ\72F16ÄďJ];•˙?ĆŚÝ%†Z«Óď ·Y\îś{>ď ů·FÂřěpÉäŢ‘ŤS Ý›±ţúÔX×Ć”Ě+üç3á›úbÁg¸>ÓG>˘·ř®•Ű’q ˙¬Íťećáv.ćüt`}łG0 Ť|$‰OwĎťţYó׎KĆoŮńÍo·»ý°ÔĘĚ!–'p•ł}Ëńú«R2ç>ŤW/üři7÷¶ďL¬?ůëĎ6y…'¬ŽčĎô_Ć=řřĘéY[úÜ,ĆíoŢ~{+yżę/qů“;;;›éóŘ-ďĚđař~~ók1â+'óh×hÔĎ™cš1;ňOÎ7…q9ŢYź‹ň@–kk1Ký5Äv/¨ą<µ¦ţˇä ľXĆĆYľď‡Ĺ€gWdÜ4|hŠwD|Ç4ŮđÁ$ďĘđ»ňţŰF×…ń}Wš\4uLÓÔćá·ŮÜh[ú÷µ¶ŽŽëň˙–şËŘ»›k/8»,čŇÜ—Ě|Ł/ęŰragç'RŁ;Ď©&usąd˛!ńHá}~}1cŮŮS&_çŕhW>ĺňč=Ë®\·ëw>Eď„3–]‘˝»ýEć9âŐ¶Owv.ť6Ý•6´Ž2  (Ę€2  (Ę€2  (Ę€2  (Ę€2  (Ę@őŕ;9űť˛ů^ą°ŽďŰ–LŢ\v-uĺ;wYOAţŹ“lL}őĺťëÎďL±¶Ź54ŕä»VYGÇwŽGdR´k$j&OMŐçľ‘1żĂ5nđ˛^‚ő0¬3kĘ|ěs•©š×ˇ0ň=céú&·ÎÄ­5wß·öŮߦŰ?ż©đ˝MńšpŁwľ§të¨Ţb×#¸ßř©&Š]oůd}šŕóK?6Dľg/ţ~˝ł\+ký°×W\ŮuÉŞS“ďÎŃťčO䕲ô8:d } frďÂw˛3¶-×ůk‰Żĺ8׀ޫf×Z•ßY)±mäG÷¬ąöϱíÖxJŚ~ĐĆús·hÝý8łn:Z&m`řş=ĺŰбŻ§ÓŔbD6ż_Ł#gĎ.׎`€Ůrë:ăóÎÜ8·Îőă†Öşµ°»¦›JÔúţÝnMb©l;ŰGď`g kÇëň鿬[f[â 9&ţ@psĆ…ů´ń_oĽ+úMdîŹ}‹3rC…ě`Ř Îű}ŚÔ“ólç!ľŽăŕ–ó˛îü|V7¸>^ = ƶĄ[űÇś|~płîŚľ©+ůWüú˛=˝-gřAôĚ$·ÖxgďŢ9îĺâ_âĽ(Č'ăŠČZî±ű[Ţ~©ĄÇe_p‹_ÄO o¸Ćß9ź˛{¸fşzK˘Ůáuăă ąD6)Yź+ŰR2Ţ _±Y9.%¸¸Nú®/-éÄrćłö·Ç‘w¬ëÓÖ"Í„c6ÇéłřKr˘üwÇ‘ îëűmŃG©śěsĽb×~ťRS‡óŘm)řxł~ŮĆ>ům¸íŮ Ů•şî÷[ń»ř_řţRa=ßô{»ńĹ?N_fí5čŰrN|5çüă˛-óuęŰőĆ– :ŽÚyˇŻWîďžsϲ}űŠĽ”čÎC8VN߬݇|#%m°îýŠŽi§ÔÎą7ţ„Ň÷ýÔŤŻ«fúkĘeNěŘ5óŕłĂ÷ŰřwÖés˙RyűE§||,Č*ÇD·´ë.¶ć ÜÓÍAăăÔŹ?•ĂLKţĽŠ{ŕ;ݱŔĘá÷íX'úô±ú6K]Îa˙ţup!mr7‰óDÂ6ĺĎ n41L•@ÝÝţ–”¬ÁE&t†ÄĆüy‚/łż-1sľ›ß({M!®(¶ p–rË5›†ń˱>ĹŢ$¸ üWrđk“sŹ1‰y?÷‚ű>Ó$˛=lŽ!ş“Ź/_Ü×úÚ~`0­©?ĹÄŇ6šßŔţTŃółoŰľŹýŇ&zőë]cb­>ĺĹhVjm0÷wşqĎŕ&V4ć6ćůÄn)Ą_b ăćdvś:ęsmƮǺ~Q¤Gđ‘«ÁÔŠr4Đ–äćń9E6úEÄEßť•«­ą'ňů÷Ć_‡ńKú\°/rQÇ˝ërzňő.ľ l•ďŁh[Ú•öç’±kźĂ ąď*Öű?Ňpřnݧ”ńéĂ淼׍&‰Ő#ŽFt,ĄľZúçÄFŔ g|DfńCôcä¦>ą|(ĺľlËGúűÂĹ%…ŘŃ´)c;p­ÍĺŢsŃ>yRČSNä„SŽCú¸ďwĺ]óoA˙śçĂ5´!vĂ>úŽgÓ˝L\Cżî +“ă©Ďć({·‰_üřÇëWÝzűíVĆą`•kä>”Ä5ȶŻ# ĚŘ™ŻSß÷pžvťz´6¶±° JÎ1oˇ>óK>đĺŰŹ‹7ŹsPůvĆuü‰Ľnon˙3F‘ĘÉ/s¬ 8;t±oČ+öFĽ·Ô“Rú&}Žgă¬Áö™flśčYé3ŮAË©ďŕ .é´+ĽŇ?\ ëú€Ëg67Ľ\őG÷'îÉ8%qŢŚŹâ{¨˙Ł‚ţÁ(zÁ˙˘[ć%ň>Ľ|Ŕ*ďŔ~»yßM;Üŕ:ńÇ.ĎÍűi‹Z‚^|›ŕÜ\˙\®ëňĎÇČC»vě2śłŤśŕX7~†‰±YVâ ÔcÜă~ěËG¸âÎĎţŢŃ&÷ş(ěĆ^w_pâgą/öNéoĚÉ©ĹűěÚ騯 ›ŕ:©_ź;ĘÚ5:ă8÷<č,؉“Áś±q×A`r ť |8]Ďçô+úÚ.7íŠmŃnü®2îďxĄŤ­¨™ĽÖŘeĚ;ŰřVÇűo-i;3>Žu˝ 5UűµÔ–~—ż";ćĘĹvĹýśź ähďýśÉcňS·ř^ě żrźą—Î?‹ŽiŰńŮ×fňß„›~ýâäĘĚIÍÝíO$łG¦L?ŽěŤşčŤ÷—÷±,‰„ÉŮv·wXŢśĚĹXŚźł×rÍdĂfËÝŕ誤ř4řpíËuqësß’¶â’>(íĺzž‘zϰĺ]Ţ×;˝ÄőťNnOÖçžkuiré¬0±FËĄ ĘÎÎcš}Í5n^"µhŻř/^›"}Ać9Ĺ5vgĎÉOŰ›†ßh}ëXW{‘˝Ňşôa‡1¶ô0ÖµĚÄř>±vęƦɆŹ$Nî}U˘Ş9Š˝­˙ş”`;’včóÝí´÷ë:ĆŢ?•ysS:ÜËrřŢBN…ÝA8ýZ7‡dl9(Ébb™­]’IěÍŻĂöÎ|i]ţýɉ–gYĺć›\ŹßcüĽ¶Ů¤$š°<‘= ]ź$nZüâętŰnϵ‹±;]ó~Uć!r˙†_FĄşFÇé°ĂęČ䫵ňÖçöJ1®O´|×ęIÚ)÷?&rM™ńŁhŚb>¸ˇ0†9žĄĄĘ–’ šgaZfc>-şK]ţżRźé·şŁNv`}7×[sH*ß‘6yMS©Őé´yî%_¦É—Ä6#?)íR©ѯi×ĺB¤\W˙ť·ô´iýť{W⏹źŘ`hâe®ĎýŃĂh×7 9n+ĂĘĚÉEş¤ŢÚ©5Í&ÇE’üŠČFĘ˝‚ýšŃufĽĹćÜ«™\›Ä/ľ({€É?ăěěR3^É÷ł<ËČq®ŻĆß^AĘ\?I.7™˙`ď.'‰“Í÷C_;uĄÍÉ!ó7äăýÁŐ¦ úţ1–ßµÁľIö`×`ČX`s¦™ą ç˘ďŞ6nSžDżâ·ĘőEÁ€Ľč„ľŤoľ­˙#V÷Ň–ÔóËřÂĺš“1řJcËţ\ˇ»ý®iăG,me¶Î=ă‰iĎOČ*ăŚ/·ČÉ1gżNfžŃęr¶ÇúôŻ“msáFú“{ćt׹çűĘŕÚ•V†Fö7üş{ó;0fN#ăRŚ5ú[<_uk¸Vú…Ř-Çč#~ż`۵‡Tň<ŰĺąŘY«W§Żí^ó}żWš@|7ě÷QÁ!şĂ/ÝŰ~É|UđËůŕr6ŕpS§z8f×ňĐH¦¨o‰=KßÇ>Ą˙3>Iż¤žŹLÝí˝ÖŽÜo ÍNŽ=\ŰÚ¶ä”"—žם »wnŽęŰ6ňë7ö°ôs¸˝ä“çPú´č?λ"g§}|—o·ăľ;‡.„Kúţ`ćż}m䎦sdç/¶-ó áĺbó]ŕ^Á×Kć1 ̮ɰýrp¸gú«[ ć|úäü…ôí]ky1ÔrďŠLŢ?Ł?×e>Ç3‹řňĘ˝çŘłś`ł2Nĺ;NlŢnž%F—ŮDŕ»`}I‘ßßł’Wäî)ó\dź)Š[s¶îćYĹgžJ{›†ŹOýmÇűÚ–ć®°¶ŽľźJřJ±Č{ŔK.ľŘć·/sĎ^9VĆJŻ^|űćĹŽ}?"’óśÁüú¸ˇ‘轜{*•Ł]ż‹Ţź<•p)e@P”e@P”e@P”e@P”e`eć°°.ß6™ß?jÉĽy§ßAu¤żśŞ]’rń䋇»­ć·¬x—ËZľ{skj‚€ß0(l왬)?>s˛ů˝¶ÁVâăÁŕw3¸–mÖÖ°>IŢ /T 1DĽ›·ß?";ëüÁŽün}˝•Ţ®?ŕß»óŘřţ™ď®X—‡ďtXGÂu~|ŇBŔży¸¶Yô‚Ţ›ď\ů.†ß?FßWü†Ygr­/ ů={ÖČ÷UĽßgśŕĹ^¤¸,|ö(ldă·¦‘ ,ţoąďcÜwQţöhW{2žŽ˝řý/ś€ŚţZ®]ŁwŢýSçTłaO‚f xáß}Çć0"#¶ Říô5CAđçÚĽýîÂŕµßQÇë|žkçôÚö$fx—µMŕrř}™Ý6˛ň};v/ýŚ\ëŰŔLŰŘŃ÷|Ż ŽÁ †ďťŠĎ™If9îô--Pş5¬Ű•5¬ôű·lłŽ›W8śŻ<HyrďU¦?663á»Ä¶—¬ ¬E“ś§tëdśżbM uůČúšru± |ü]…ďő\ßG˘ę˙™xşfâŢéc|j&Ľďť-#źôOJż]ş&Ě?WşŤ]mé˙‚‰Ĺ4żŰz Ťëbí]µ›ßČKlŻÍ‡ÜÓÜËú)|®ČW®˘żŇuěÔç:úçŮ÷} =oÖ ‹=Hűż4vőjó{ąün XŃ{5müE/9ś&>}8Anp‹ľE¦])±ŤrőÄţŃgąóżËáďńkČ”ë™ÂńÝ˙svË}ř˝KćŚčŞtL-'Ż żmĺ5rKśŽśŹóŮÝKŽ‹MČWz]ućiqî §ż ÷|ŔŤ\Č(ö(6+rS^QĂ#€Ô'^ŇżŽmńŐńµ®Éľôb˛ĺŘîë´¸…«÷î´q ´ĎĽKîăúµ[» nß_ v_~|–ď·đÓčťRú|9Űć>~ŰŚUN†Ňř¦bąwgťĹëôb»óĺđmśń™ŰôWđúÇhSú±đXZâç¤=±|%öAL ń·˛nň«űmJ7ďőeá^˛ďc…ź:2ćRňą9Ç6ËĺÓ;Áä^>_ď2±(‡GOjcfŻ.ř´ÝŃ/×rO÷›¦Nżr_éŹ>Fs¬UěNt#ňú6-Çü’v%ż \÷É™EŹż*2 >áĹC•mŢř~şŘ­ôɆÚ9çLÚ0›ËęŽĎő˙xÜp28™×NmµqčFl 9٧ä#şĽ ů8^Č‘ę 9«mżoҦëmb%mßůŐäžĚ§EďĚS/¨9'Iż ®ąů€•Ű›q±çApQßű‡îeĚÁ.…KżMäbź¸Mđ#ăĎĚ1Ă‹9Î__ŰxËľ)ło±ťŹ§[«c83±9věáy [h4qΧ˙sŤŘ m:¬®}÷<éôĎíÍçôźĽÓCÂąąß*ón$µvękɱ®ŹŰşdň kű´¬Ř‹/ŁÍ¸îďűÎĺz·×yqôâ» v_°1'ßl˙'ÇĄČŕá´¶J[ɡÂďöüO?MJ]Jú}ĽßyŞvĺm{í×Âü] ›kđÔôŰ“řK±Óé>»ĎľGňd.(üή?-wżřÎłŮrĽ;Ű ‚Ë.˝Ôň(%-ÝÖ˙źÍŮí»Đřľ±ľÜ1wĎŢšŤö]VoŤÄ#L„+Íw–‚·ôz™cLŐľíVfęl^Š–Ěxbećé©˙5y3ŢižŻŻÖź‚ťű÷š Ęâş®/’‹ăŚ>Ţ|Ç6?CrhÄćV(•Yö]Ś7óŽç5M´ěß´qäËOČüum†gťdżÇ‘şR˘oć2~SWţŔčňwą#Nľľ¶úÂ{;©7·Ňékhä3ÉSÓëŠć=ŇŢşń–ż*˛–+s=÷âÚďkŽĚĺ ˇ#ŔYζÉ%őhË…±ö˙gďMŕ뺪{˙¦"Sء[Č„$ŇąW@‘ŚA)…W;}ô•(Ąr(PÚRyĄ€B‰ €20Č™( S"3”˘@ Č C«0VN  P¨J rÚ´Ź˙ú®u~gź++Á–Żd‡˙˝źĎ˝çÜsö°ć˝÷Ú{Ż˝x·úۉĄ`öů{U1–>ҶYřÄ5âŕ ÁÇ;ě+6]“mW:®Ŕí|–m{iłcßÇęźÄâ%ÝÓDä—"ËăĄ6‹2ŕsŠIFĘŕőYý[ŚŢî3ŕM«>CE ő3©sűw>W_Úż,\S€Ă+;îkmÚ§ >ÓůqXŔMú¨yvŕDOĹKÉ9¶šwú‚k˛[Ô’ŢŃĎ’ Wă=÷ŁOm˛őwŰj>Żę™Ú¨{ŕ!*ŢĹó‹ LľéŃEřęďˇéD+lý±r†Őicźöľ0wCĆĽŠááýp­ŁŞú6č[áRŢąm#5éřRz«vŕ&Ź+»šÜ;Ľ˛ç¶ý•ŹŃoŕŐuóاÝ€üŇĆ Óř»ŕźô;âU Ó×{ÚSo›÷ršµM}üí§?‘y'Ö {˙đßyŤ6şę˙ Ţ™lŻlŮMá­pą^[řWRŰ'Fż\č$ąG¶jŚ';Ą~šáé6ž4ś$˝U;Ćó˝eĚâ•@˛¶y¶ŢĎűČ7ň«±ČŰŚ·j“xG»–|A#ő/×âÖŐvĂĐs\®GÍ6c‡:g~č˙á!v Ů.íąé·Őěăúć3ćsj$k[úI•vÚřď1—Ŕ™ůH®šűáŢ­uŤ­¤Jř‘"†¸ä8ĆľY?é_I—ÁůŔGßf´¸ëŕµúcČxô7„—ŤĂĘľY¶uű`Ěőčí]űcµO׎Ϛľ¦ő&Ń·Ľkc¸ô˛ÉęCż­­r_Är9ÚĎÚhS M6ÚhS M6ÚhS M6ÚhS M6îŞ`ť>Mľ3CWřĽ“ťăt—ő[ßđíj®}Żť=Ć\ kđă2Óh<°śs+Îľ°ů)[Żkë-X/ÂşOć¶Â˙{Gµ;ĎÁ•µ̱2g쬕Ä׋o›yjÖ€ńK Ď—gčC:ćsńíŽü–B~řnůVďÁ‹5›ŕ ÁŤ÷řóÁŹ÷žĆđÄJ:Ţ‘–=ÇAöą;›ęaÎIxĽŐ;řÁ?đеN:Ë6s™f4ŕ‹ đľŰÚÝś}Ľcľ:čĹ­Łű‰ąÎű扬ŰŐdXYüđK2ě1W•e·ŮZ ń‘çđš•ö—zvá#?zx'°ĹÚµkxRť7®\Á~qţÜű×µfłš†{ž“ÖěŢ–}żWCÖˇ4Öş˘Ł…5|hŹďWáTŘ$[{đ˝űţÍçey¦ů îµĎ|/˙×"N‡hŠĽ!kČxÂ_l4`ý2°ĂoxĚzVĹ ľwő÷¬±©>ŁÉ@<Ź8]ĐřŤ–-Î{b­|•NwUÁńŽt´Š ÷’ ňsÎ4„vĽ“LTËÖ3h«ŘdâĂj^Áś€W¶>ĐÇ‚Żw¦ĎŔO:áNKyŤ.“Ň@_í}gŠđF·]ŢLĆV_ä 9ć[…+ř•eĐz€›`†oZÉ3hň·Öö\^ô/Ő†óąÖÚ7ĺ/Ö2{yŕ¬uƧ÷םWódg »­Ĺw›«µŔnGŰiˇŤ`_z…6w&JźćáŁL­?]›őżŐxÇ:/­K†ľ‚ËdĚe±ŕwůś÷ŇĄ]ĘÇ*ŢČ=:­´qÍšhٵsJ{ŤÄŹÖá¬s«<…Îč±č­ő ôODŹ ÁÁköŃEâѰ®łZ¦ÖAB'á¤2 ü3Ń\¶Ž}!Đ ÚE_ĄUxÇšÖĺ‹Îę7€0ÂkńPç nbA‰6<“Ň{®ÂŤ2Ş8sľďc]–i®tŮ®–˝kń±-9˙™µz˘/|‰}Ę’§‘­ęwÂ?ŕî‚;úă‘ú€/<NŇWJžŠŇQäZ¨¬,;»¦µÜN§őěŰôu…ŔČł€áHy­ýüˇ›W”‰ ĄŃ^ s!w͸€<”,,ĹOď«úMąŘAĹJűTvŚĎŔT™ý÷™˛ű#ůÄZ6ĘnASĘtž–uá'P˝…Ľ;—¶ÁU;•xhŠ^Rô ¸Š˙đţ&“—Ŕ*ڿؠ1ęHńnĄxÇY—’Á¨łµÁŢIö…3Wd9äŞß ĎčĂę]ő|Méx˛O2ěH–} \ă/ĽRą‹ëź]îÝX)¶Ő˝TŠ}ýXeđZJáo;éxÎXřßíůĚĐĎ×ÁŰ_íł¦Úż>qjÜ}Ôm±' cvÖȇüa'^Qî™=ó·~ű)Žm řIΨçŚáG»Oň.»‹Ťá+űZ…ĂÜž:°?m >†$Yömă'}ąčËG[=·~Đú?Y–ö3±Żź<|‚ĎŔ§:ăYĽ=ü__‡É^|o/ŞýŞł?.÷N&ůĚ2íĄ€>đ–ľYŁq“Ăţŕ ž´ĹŕÎ=ĎćűÎęÝ>{:Ę“ '®Ź(ήçž=\Oଶťw”{ř¸*GŘ~ÓÉRçCĐ!bó€[Q§Żß¬Ň9‡]‹—ő’F¸"§ş‡G”{N~·úŽţŤvÖć~ďgolňt`ýÖ$WiŻwŇgĘ€~|M˙W„·tQx‹úń,Ë%lěÝ>x÷şöCŃ®(΀|_ŘapGđŐ=0Ę&wĽ'ťĂ_č±ŢQ÷ąě©çýÚGô šP®ŕ‹4‡ţ{Ćđ|Ooäo¦'Ď6Ě˝©˘SQżŇoLâ٦©g>†;á%^ ŕĆ^#đë~˛÷ˇĐ‹č{MĄ/¤ŮŮ9S‡žćţ ÄYurߪŤpű'ä…ú€™ý|Ë‘Úď* Üďč˙x/8ŔgঽčSňźwôďđ“şđliY1®×çô‹Ŕ“%çäq[Gž“ě|yĄ:Ü«ě6qóŘíůżZś‹Ô}ÁâDľ}đ—ťÖ/í|oýűéaŔk{¦­m^ô•6Ě=Áäź~"q>6Öi{řb3¸jś€“żÚźÁn„Üf™Í ůś×ŢѲ–eĂÖV!7Ş÷pqUzµ5ČçVĂoŃz÷ě§jSăďęĚłľyěÍĺ>‹¨3ń}ĂÜĺ>Ö†Źě®=“˙YŰ4őĎŠ±K1ĆĘĘţ»Ę©^Cn:h €­sfsíU-hźŁäŕ¸Vëą‹ýĂÇŐ6Ě˝Útö`ťOĎ˛Ś˝¤Ń7‰|»gżĐʞŃćĆł ˛Ríđ<|*ÄŰz]ńw–Ö—ecóŃO‰Žä·ąllŹä3Ëć26·­Żîq¬ź˙7áZÍ0ś“_ěy^»x‰_y:·íiuµCŐĽŘâ+Ü\ÚErTËM÷Š7@Š#ů<ňń;K#KUŰrĂĐIn7vvľÖu;íyMpŔŻđăY Ŕ{ŽZLĺ·—¸VáR;ĽhĽ{öŰ^ĎăÇćOąĄďt«+âĘw°4OµÜ•Ü÷xŚëhRŮYĹVý5ť˘?‰®†ťI8Ó/Q˝ŤĆ§ëćîQ[čz‹íYßăxě™|zÍâYŘ /\–ת›Ź­›?»Ôč¤~¶>ŇŞ¶#˝&äó¤Ď!üŔ›"ř¸˘»Ă ŐMMcŠhlŹŐč˘ăľwôË.+ËÉ8ĺQ_µż”ŐÜFŚlý—«>ďmBŞńČîĎ™ÍvZb+ó‰+ťŢ”ŠüŞď|đĽř@ţŇuÎ|Ňđ ú}Éô”X¬ÁĆ ÷č±yÝ\–Ú/ňD?%Ć˲ŃʍLęhý§Ú‡اĆ_â1ˇĐsÚSěÎRúďŘÜëĚP§óض>µwăĚPmĎäXýŔú_őçč(i‘úő´Ů|)Wţ"ä+ěčČVć4(?ěNë1FîCĽŞ<ĽyŰîZ´EA‹¤_ńźwäý#6úgjĚeQŽä=ń+ňÄ˙,ëţ—{Wú•çďô8WŃßn=¦ŐÓľ7Áă(Ą©Â÷đĽšő´9˝ŢEYÍeDż(Ňď|Î,ÖŘ#đýąŽéŚ•¶:דcá NČcÄÉ2µŘ4ú¬đ’ńě+ůĆć{í<‚:yů®Ň dv¸ăý…­úďŮ=»XźŰvo‹ŃóĚZµŽ€cu°MĄ6óAőS7ü~ŮĄČ“úˇŇAáŻţťĆ¨ÄÓW=ŇŤ(?s]†çčHł<(Çę_϶!Iî‚đ[fýŽb,1˛ő<SÉcďˇ ţ®Ř¨ęĹŞßu O)m“µ,Ű7p•Ç §Ż!=•üFiÁGl: ľŠŤĹx„öVó—6>Ë'GpĆĎ}č®MĘă˛'ŐŔxé#2_‰L‹GWýdµGŕľľĚרߢţe•f¤Ý8óŕ–Ě«·‚ŹĽúš-““çŐî?5^Ć'UßňĆó\€™6š+_é·Őď68|ÉižŽx‘ŔFŰ€pŃňPďčÇ2Áo‚żhčÇç»/eůÔÇÎÓ}łłeómúüš]Ýź­ů üżěĹ€ć÷ÝşĐő#÷mjľ‚çĐ|řI_Wśwě`™ éţíޛ˲X?Ŕ;‹ąlk™ą2'ĂĽUřů3źŰb®‹uüřşIÇÜiÁwG˙ďÔŮÄGěµNu wűűní ˙e–ií°ošÚáű0¸—żś™OG´V|cn'bŻ oÖŐ$żč±€iŔ ýîŔ)>żĂźÉ|:k>yÇŢRř†üÂ[}áżžaďXľ”ië}Ź÷WXžŁŤ9|Š9 «WôŘŤ§wč]ŽY;îÂ[®Ř;x/z‘^÷”ź‘uhr´y>wŐ4×XĹ“ydÍ-‚tđ‚źPg¸ăżk=Ë÷¸îű{ĘŔ®ł&{ü˙š×ĺś5Gó;”´öíĆ&'_`ćŞMMŕ7÷±NFđ6ËGČŤöőĆ;h%ü“Ţ(˙Z]śŘ&­/xľ|ą‡ÇÁß”G˛űĄb}*ůDĄĄ}‡Ż|e˙(ëčŕś`VÚ ­ ¨Ć_ě¤á žš›ĺ|AÉĂŇ3…Éó8‘o¦\˙…˙ĄłżPĚy®.źµOě }Á˘çěGďô¬zçĎ[Ű,:VéyG{ţČĐÎÎŹúĽtC·)‡÷Să§­ęšy_§“x¬ő2}v¦Żp<Ř+éď¸'}őϵ†yM2ú!ü‘í%ęV}\/ť˝hńn®h;Ô§¬ÂëC"6ř¨÷ć>_o4ŢZ›ďó>§h§÷\—ć٦>á"h/~ęY\3Ç:'řsUŽ)Ľ«ňď÷L~®FŰ2{ u˙đ_—¶DýőVŕMýIÖҞު,Ä’ń>u±f ŕUŕ ŢÂŹľŚhĆsÎR­Ň'Ő|ĺ±Ĺ᥶ůľ±Ňî2ľŽ>8ošë¦="^,oôÉ'ŢZ.ZCmQľ3†_żÂľ8ő¦ŹĆ®ČjśĎ»Űş…w××÷׫v 8ŕ/y6ÎÔKšĄRŐć±Vě‚1p•ž<ČWęY°uÍßVčS–m|ę}Ľ<öĘ‹ľ¤‹űTĂáÝŤDłUě×8(éa¬=F7Ł ýËzřţ‚ŔJZÚM[—>Ş]"_FŐ좗ڴ˝ŁżPĘx¬[łe‘Żťť?çřłĽ(݉_‡Žwâ!yĐÓd#Bvô˙Ëćő—yťč40Đď¨Ćٶţ˛§Cy\Ücď 2ż¸~2—Í–üđžý±ţ9 żjú–|¸Ł;ß7đ]Ż“r»Ĺősµťť˙·8|‡Žk¤Ľhţĺ&GŇÝŔÚÓţŻc˙.©«q´Ţ,»qŕS®ođ»nW®|Á Ő”¬K÷ÍďĺĽÝřŘXĹá}¸R^ŠOĄ”‡~]čšę7d”!ŐýDđę¬ĆM=ë^TŘ•ŞL¤{ôń'?yµťA˙~× x ®Č _ţó ůÉ2t™ěŔ}‘Ů-á#=~gŰţpë Xśă‰kęůÄ}ëď¶őáo·ŻŤ×ň$‹‡ŽksĘfżÔěŔńŢvl|±Ĺ'yC÷ÔřIy˙đs=FP>îŁße:o°Ó¦ĂOŕQžđŐŮlĆš*KşĚđ&˝ŕűۡÎüĆ˙U?'xţ‹›˘çélu=9ôkţđNĂO{#ßş…ç—v“'g5v9źŮ7 8ťÍhv|yĽČ78 îyŻI-P?&ŐťäFĐż¬‹„2Đgő‡ŇîÚŞ bSTő–şşžPË'Î4^w8}”¶zexAyčśŕ¸n´ÇŰŹţáÍő‰é'¸LŇv]n>JÁŢ•t{҉˝ŔDl•›-® zĽażbĽ†ýŕ™ęţzVĘôÎΧr˛.ü–Úű„ÁJďÝ«í§ęS©ŤĆűkKů$Ú ôß^'ŤĆ+zűúýR&h”FăţﲭÇe™ĎYş-§Ź=ŻçŔúgçÁŰ=ĺc|\Ő~¬`Zé5âĘDnŤŰÄ‹»ăĽEć‘]âüIWů‚vĎÎŐđŹź~5ĺőřľŚ(ż*§ĘOß–8čRá7آýgJCű ú}ń ÄőnÉÇůś*–˛xJ]Ŕ®ćŢpŻ­})Ď·F?Á}*Ę»ač n÷‰WőŹ ®řžT˙cl—äOă’ĐŁ–ŕ›m;ßm‡Ęö?/öLŃ·ÄVżËŰ‘Ǧ©zžmüuď…8űäÂů>—p~EÇ‚÷)Đgô±cáÝŃ XĘoě‰ěx˝ť hll­ÁWĄh>žNLÓeš1áöď|Ńő«Ę‡*ʏG–‘Źťťj»/q»7ܱĄ†ĚÎmKńJ&¦ż_ßµx7‹Wr˛ŰŞŞo%Ú˘h˙(Smp…Î ŇV_˝ďż%é¬Ĺ¨4\Rź1ńYx§´ńŽ>Ýî§_Q»jzÔ÷’>;|ă‹~ňŤőŕyďnűĎj4rě»öÜqíozŁÓ˛ŐS·tióŘ{SŰá~šŇĂsä@.á×€=s]¶ŞíáôIéOőQb^+0ÂďDú·±ľd±ÉZŹ«JL{Őő„ýź»˙Ňe˝ś›5ś5n€‡k´wY¶gň´\öçŐ/i–Ęď󺍺cL‘ň ˘V_lŘk߯j6‡¶Ů”Ť“͡ßÎč[ł]ʲ]‹Ź¨÷Ť}ŘmAŘŰ([4I¸Äsę·ľ,˛ĎĽĽćć#]«ńl.Ź|‘KÁUícËîLLĆb‚ýŔq˛<­Áí}CÉ&ůeŹé[~;ëËóA/ćńŞkVÔŐ\C3t«÷źhŐnaËç)`ŞÖóŚČ*1yÁ ü„#cdxXĐŻ”]ŇW鲞e”ŹÜ´°ďQöďic°żŔ ,ŠűŮ?ĽĄ¦¸SârŽ\G[F‘Í}öĹőce_ô‚Ĺéşě1öŕÍfŁđ1cwv~Ąö®Ę>jʉX˙wf‹_„ŽŃN±ťľ04ía·>cÇB­®¸„;úńŮń‰Ľč@č.˙őÜâ/ďŢŐ«ľ÷ŘüËkÖWqż9kP /6#xN|–ő3„;ýiŠ ‚“ű$«Qý7™¸­ĆR8ó&ú#[;g:śó}ź)ÇMJ‡ś`·.;ľő;µ/w-®ŻiNCűµWú\¬çŚgÍ"Ł©ż–pnN•ejŁŐ÷Sůź+Ę}ŮČČéË•ż´śVýżtö7jĂ/ňľ˛l.ý%äM6>ŮćN©s¸ăëλ φ—!×\Ő® ö˝ŁO¬Ő&>ŰłaîăMă+kËĹŽ’ës‹˙˙Ľ†qYäŽčfұ°mô×äřłbm.¶,ú(™ě´ëôYŤ7YÜĎoř#źxżÓyţŃ‘r«v‚˙UYi/­śÄ3ÚÉ#|K¶‰őšßen«č Gžż‰9‡s}|5âg˘ÝS˙…6™aÜ,űŻľčęŽ+–§ŔöÁŻ”1H«mµl}0ŕMý*[RŚ›wŕ†Ž3/cpÝënqť‘O<éŁeąŹš†/hy¸Öâ)pGěŇÄwŕLň~Á"€ČyµC»N´}+ěëŮú O§Źć5ávÉâplĆ}®H'ŮP_?>4@đŤb čÓVűbŐRŽŤűçQ߇§đśë¦©?)uŰţľ{x˙ ŰOLSô3ĆË#[Ď7˙5rh&zV pžjvEřĂËΙ×Ô÷L>Äm˛Ĺ:¬Ím;ĎďÁM~&É16KmrďŤk‹ţJĄĆcŕö¸ěYuĆ;¬oě0Ăg»wľM}f[“Pžý~|Ő/#OŘÂc©‚P‡~Źlí辢ľăSSĆ'ĺ9ăńᎷ:°ÂĘŽńl»wöX\ÇúŞg5^oúÝţ´)Ц@›m ´)Ц@›m ´)Ц@›m ´)đ˙/ hŤ>-ü?ř‡b.ćŽé€żď»vÓć±kî‚~|v¶`ćCyç ëćâĂZ6|>;úc핞ŰŐ}H¬_ĆßÉ\6ľ˘OZ ęJšcň_|ř*xv6nŤyś›·ýEŤwšcŚą pMń9¸ź~—óőň‘óiűŽIÜÍÇç{«·v>űűîU/Ö(űYśg#_(üޏ±ÖJg¤Ë_–Ol¬áÖśF”xěü˘§Č"s3Gşś«Ĺ×É3­Ł`˝28ÁchD>ü¸č1:±Çć±5ćkđWçÁ.+Ö mĚńß\X™GDŽ™—xk8úĽóÓĚa°ŽMţlžA ɲ|ľ”‘ëýeLĘŘ45SÚ‡Ł»öC#xˇ·ŔŤ?[kçĐ_d@2 ŹÁ—ĽĽ ˝Ž}M¶¤ó·ńść¶}'Ź3ž°‹ń=»˙ÖŁ†7|<ŕLU>\ńqŁĂř°9?|ŕs5 ÷â9ďY‹Qµ‰Đ‘yĚŔťk÷A©=„‡â)ĽľÁÖpónéşű@GˇŹćťIÇ3ň0gĂ5Íű€SâoÂźłÎ^ľfĽŽłuô †;ά/tÝĂíuâC¤ąĚtŻŕ 43»ěó×ȷʧŔË×á6-âXÎĘĽ-1«ş&sűű>k†=Dâ:Ř?\÷=«ZcÂ;äůç*ąwÉsذhź%ŕLŘÚ©u »|oyí»ĆĎ8 ®ćŻě,6ŠŻđĎëF_¶ěţ2Ů`ŃGWňB ř\Ąď«yŽËb­8ĎŃ!t :ŞśŐÄ7Öź…ĽJ~…3ő­QeI&Uź­ëő˝Qí\î™ˇŻąěu,<´6ó(l­lz,›]ĺ±`ÄnK'…—ŕž~‡í}fţSăł=ZŽŚP~Đ3ĺ;Ľ»„3ílŔe·ô}é uZŹ{žÓ@xTŻŘ1pľâq5Íć±yŁUŘő8ó>ŐťŇô·vMu›Ţź’piN‹ľ¬<ĆďĹá{TŻÖ]FÜŞ,űşŮ)ÎVśŰÖgk­ßĎmĚ÷÷ŤőŘU·kđŢ!·ŕ źiky®=¶f‡ë»Ë°Łë˛]ä…ƢŤdĚĆ1–ţIÇ Ńx`AăŔšŇ7ä‹]‹~M˘Ęˇßýđ{§5·|xžeçvlńúűoŢŘ$o‰/Á7ř»yěÓEšđ…çQv”G™ŐĽŐ{čľwôÖşí±´uŢ÷:µŃxßžéŃĹž×ŰÚđ%¤ľKü?ś_Öó©ŹDýśJ~t:öÖ¤Ňl,ě˛IşÁüš^čŤmůŞŮ đŰŮ{ň5N¬–Ë3bňĘÎaŚÇßcqýł]h÷)űĆŹ•zµŁ˙Ą9gđĹ•¶¶o@1Ět‡~·gň•.«ČJ5NÚ‹ąmo±X†7-;–˛±|­‡Mc ¤ňôgčb{ŘťnęălţŤ Ľ~ŇIÎwôÜq´z+úLţú†ąűř>[Ň:–§¬ňCőF™KËĺ˙}Ł-UŚÚ5đć =Á}Ä/hvˇŞö»Zîţľă{7M}ĹńŢŃ˙Ë˝ܲáéÉáÝmšzŞÇXP˙‘şńł3ΩÎMPŞú‚?Ųlňc łŕî\Áťgú"ż´ýÖďň5Î*«z…—űű^Ů„+öŃřńDôŤ3Ĺże4‹<‡‡/©Ť+Ëş± fŁëÄ2:·ăE®cgÖÍžěu;&¸H˛›e¶żŮcÂĚZ žóEÖÁŰĄ˙čľß ¨÷Oí?Wëo{ýĚ稿oŕn^7ď“ý ůoÔß'Íá~ÔRż‹üÓűŮÓć|˛¶©vÁâŤÝľ‡Â°vX“îAŕ"8Á[®äGv…3WÉ÷|ź¶M>ńÍâ ”ö>ďEoµiú¸ř*=ú:’â=R&íľl÷®Ĺ˙UĘ4¦˙¨ú±ř÷Á=Ež)“8ŹĐ?1řňúHŹÉOÄU—Ü“ÉZO‡ůÇ^ÁăŘç•řĎć6…Ăá_ŁLxD=U›FY{Nţ•RÖř_ÝEzőß°”Ţ<ß÷ŤZˇëa»ˇí?ĘÁ›<ŕ€Ť>fŮ –ÓÔ3k׎÷ŮľĄÇ{ťšţĐű0ÍĘ?Šű¦~u`3f†žSg˙ đŞtî…—`á Ż°QKu} ĽCŕµöVór?6ż;Oí^ŚŮűĆć{Č‹LH®HkóM|l‡s y#Gđ<]ăt% cĺÍc—׬/|ě™í)ŰZň“}ÔB×*üĐanŰ܇¬>pzźe“ß"Ć´ŚÇ)svಲßr8xVÓî8™ţĹÖ®©q+«Šwŕ śđĎŕ.ýĐ ô°š>ݧţp<Ď”Ť«´ż&” Łóę‹©]<×öć°·CyÁ· wkîĚQžb„EúÚń‘pŃö6ČzČ~5oÚ'}bĐ`‹±m˛”,P¦úěŐ„×ěŐa=Błľ´SJan†úw<‡,Ło{ý¸i_öťń8ÚŔŘ/Ëžńj{CąČü?yÎđšűÍcgôr~tńü ÍuU+?Ő}q#[/XĽ¤^ŤÝ Ŕ…}Ă6-Ç_ŇđĚ}É$ÇzľÜ{/|Łľ'÷Ĺé]Ät(ßµäfqB~Ééýnć‘+ýxBL`Q˙Iďąbżä§}©ľă‹^řJÔ'U:ôÖâ»–ó¤çÝ®Ĺ+ű -A¸,Dř†lo›ĎĂv$˙¶^+‹ú›ĐžˇĂ»m>cĂܧsé-ď ö¨řłn§)gąömďčËjűN,ÚŁ8'%čˇ[}ÎYɟΙ}µ‚oĄ?,îϞɫ*ľĘŕ!|îXx`Żů˛Š6EeƵh'2đmÖŐx/‹ż«‹oĐďřŰO/x8˛Uń±o·6F~>ëşéÁ¸¸‚÷Ŕ‹/űKpű`[Ső4§öZíxŐž‘6ähdëZÍÇ=ëv‡Qsi›¦.¬#‡Ŕ’ô7đ]\˙űąř13ô_nßI×l«I+^‡čĎ\/…3ďŕ7ĺ€+1ŐŽZV˙·jË çéU>Żńt‹ĺřÎÚSi7ó‰FÍb÷őXüĄÚć± ˝Ś§„ŻúR´ą{GÇj˛{Kˇ·¸ÍuüćzNlTĘě„ ÔŰŐ»ŠoĐziűŠOAă Ć˝sŰî]ł}űąĹ@+űŁ´ĎĐJ°OŹţ©Ű˙Ĺőw»dkˇňwfN.}ş:=bŘ˝ę8/ĄY­;ćV€9ÉWČ%}(đ¨~×-|˝¶¸ţ´ž˝Łżć8C/Í?“]v)ËjgşLošúą’>ęŹ3–ń6ÎéC|8{€ą­µřTń"&Öy5ŁÁ’Í‘fnŰEÎ;“É2Ž.mUŕťĘÁݰ¸ţ2Ç™sčŔGý­‰”ÍZçj͵/GĂŞ/$É:©.6=áňi{Ô-žńókŇCŤOŃkőKóŽüűűľÔ-ýŻEń¤Ŕ·ŃŘU[·đ”}˝/ŘXj9[ýlj|¤Žß xÂD OűăňŤxÝrŠoëzÇŐćÂkÖiNÖâ°×,†s“톡Ý»ýfç{Đ…®łëSăçą˙:cîV˙łqćő®sŔˇ10đ?µC‡ŮŻî sß+e›tđ—tŕ‹žÂłý}ź0ęfÇGm=% ď ˛lˇ[K­>®Ő,ń.µ܇7Ö„ţeٶÁ÷tÎ|Čt5t4ô”’‚Fŕ°Đu®Ńđúž çź•ŁËÂČ= »=˛µ󫲌xŇŹ°ý<]ëĎŇ9ę,^ńú¸ě9÷â_ţąËĎăp†>„¬ÜŢéŢ'/;ž‚3s?UýqZ›~­ýGí,˛Ş6Ç přč§…+ËđťM™~“ŽöеÄeĆ~QĆĽO ü—Ť#\˙ybďÍ·~yągGósáüŐÎ?`6®ŕŽü!Ă:dĦĚ#¦±|CŘ đž_׫üOŕN~Úâ”a+(ĂCVřLŹ&ćÔ0ŞÝ©ÎéńV}‹ÚÄĄ9zŽÝâ9}*îC27ĎĄŻ*łůJ®cçsN~SN?»Ć+łú¬±Ť3†®¨ŃUKl8Ă[ĆQڱoŢöÍÜü1Ďăź {věŕ[…$Ć‹Ć[Ă_})xÉř*ž“G}щôᬖx׼źzX}÷ě{néűFOđ;đŕdčÁ—6ů> ·¶ú®‰gę6ÚhS M6ÚhS M6ÚhS MÖP@ăéłűď~ŚřtZ×rĄŕçŔďĄu›ňÜjcĺáŽÇ5Ť“7MuąDľkÎőZ®ĚcőŮŁ¦ĆKż ü\ńáë‚řţźžą]hź~qý‰uhúŽU|Íźĺk!5ź&śÁáŔúÓęŕż÷†ˇNßă^¬M÷ Ë7<·íu.ňu«ţ"|žňĺošz@1~1xwÂÜ÷ś˙Ü.YĆÜ sŘ…ż¬ôʰďęď~Í×Ô@ż«Żľú‘ůjĚđ±=•9~éđŰÂĆđĂGńyĆď©ů€đ…»źÜÖŮm¨§9©Č«2(íhŘŻ<řä?XĚGśŰńß9ë đݢ“ŕŽÂţ"×éÍźEÎ|nA<Đúö“¦ÔŤ|ĘÇĎž#ĄA¶á­b1hŤ*4Ű8óšÚĚĐĘőUČŠíĎ8•wĚ]˘”Łő“kŹy’9äPľěGĽÇ~áÇ–ě3ü”/ź˙đŹtÜC=٬=“늹«(O˛ęYý»ö¸VŐuQ¬żwŮ>Ůš(?»ůD6ˇ8É–sO[ĹŐŕwü4wOZhĚ÷ĚĐLŻťőäkjú‡_ám88CźŁ^}|نŕ…öśŘ3çS¬‡Č˛Î™'—g…9~ľqźeÄޱ˝őh«ŇţäÝ×8d›5’Đ[Î=#˝Ç‚Vń×ΆôyVŕź¶u—đJ8˝súľfßŔż•<ÇNKV‹5ĺľ×Âç,m.ú¶Txř†Ý˛>Śĺ=s0öY˛fVôţ §ĆOXőţěf;3Ź6ąEVmŞ´Mů;sŮeÉ,4A—ůݶzIvĂ&Ĺ™NäE®ůjí+|žřú§Š˝ó±Ď[vQkŘWłÍFŢDcŕŮÜŔK1d ĎŇ.Ń6…ŤËŠłcFŃD8©OFĘ…®Ëę…ţ»\Q?í‚dâşUmCČ“ÚĚ—vľ¶¦¸uŕ75~ď/‚7ücÍ÷Ř+äşŔąD–y[ž®ľž Ô{Î$/ßáŽFY.z˝Đő#˙ó¶AďëI¶Ę‚[vvÚëő˙éő.Sź=O˛Ë}S‰Ďŕe•Ž<6č€â‘©-β×ŐÇžw•Ż3!x« ŕżľłv¶g«ĐÝďgEŮÔGąśs‹|©ľkÇďoűŰŇZ?É)ďÁOň*{,»'˝ćżÖe«LĄ´O1Ö:BĄMWĄ>Ň+řfeůěÇĄDx /wö ?˘´éÂXŔ}^n ďżá´±ů2?Ď…m çWqŽţKŕ÷Á“xr¤żißIł,Ş\Űlö›žýŰ%Ěâ'°ł†_˙E‹ÄĂb}śÍ˝Ď Ĺ9Gä–Ę5Ťx;¨ZąÚŢTŻ/é@ŕýOG ô!EĚäyÓ3Ž3ŢŠ–\‰ôK®»ĆŹĘř.d™ń!6~řő˝´ż˛Ujx–O\Y?Ž©éí{ŁqqmĂÜÍKđÚ2ńÄI[٧ľđ­ěőËNÓ6ÜQ™ŰďWĆźIýn§Ťë ~˘ŘłÁúăýNâjŮXÉ×Ń7~|BČtČuVęđŰ~oŰ~üŁ Ţá{nŠ[|×ÓĂ˝:Ěž‰¶˝ákńzmŤcY7gôDÉAŁŞÉ{KűŢ;ú/Ď7ŹÝ'·84M1†:”#đ]•>Â_d”ţ´@¦uŹ<.âUd¶6ę˸;*CôçwXßvß7W‹gQÖŻ˝Ł¤•˝ ňJ0¦ŚŹ-¶ŻŰéf1ĽÎŽ…ű–t¦ěwZ»M›‰ŤE˙“Śleź´`˙'mÓrńgy'ZTŰ@äĘöľ6ńlgçkËx,sŰNr;&ÚpU;±śăĚÝŞĚÜY))ýQ‹•‚~oá>lt–X˙{ľąJî«{ôůO?š~üöÁ­u‹wÓd;ŤżąĹ8:ulţŻzŢ7ůűnCÁšŇvsMř߼˿űfĄ/ýČH×hś_®?ÝßwµÉŰ•g¬©>ô`fčľź&žÎĆËĄ},ptąpYÔą»QOř™-)gfč}ůŢŃĹS¶ľł‡ý.<Ďj{•úhËăugO»”ńťľKÓďž(dĽ6áΕĆűoëë·hRZpf_Ú_™-Ř7đ9ßIü@Ő2toý–R§ć¶]ťoŚ=řÓ)tűHżÚźţźŘc‚:B?ÓgçńîŮ?uŰÖ3±Ą°%Á#ŰGRĘ"m:J\` ,ľŚ…éĂńNžQ6üÂnŰ÷úfxF<§ęzjüť¶wé±&Ű5Ű·5çń[D])7dü§ă¸4ĹżXěř ˛L†mĎŘóĘ6ĘÎM,eĽj;•^}i«ß÷ĂgÚtŐď 'ţó…?<?l;ńnń›Vívr×bnítĎć±/:ÁŤoU—ŹD¶!‡¬3N2#ŮŚvn¤ĹÔşO>;°ł°Żiž†äř‹]Žđ{t˙&î-Íű¬/ĹxŹŚp˙Ëż¸ľßä'}€\‰q©ţ}Őć)ýˇŢť0÷ůů^okĆĹ?]ń‡q¶m”7ň0• ¬đÍbĚű\ ˙ÁŹ/}9đdÜ­˙ĐDiŔ›÷““':ó‰WtTéqĄ|ŕ@–ŹJpŃFÇ­9ϡ˙§|ÄŰt%Fšő9‹ŘQě‹z·ŻµčSďç:=ß÷6ö$9/Áą7ľ*7ďŚg.蘭´4bpĂo @ޡ‹É•ÇDwU–®´ő¤]ů'ů›«ă[Î €ŞX˘Ž43›^ň\Ŕ Ř«:Ę=ďxNy&ł[°[o÷X`á÷Ž:˛ŚwÜ#ÓQFô;Á›ú…Ě«¬crbłŐ§ŁÎťť­iź` >dť}Ř=` ű§}vYf{\sµ©äS›ŠýCľ‘{çŕQȓڲ=“=uä86ĚýNť~´˘˝×X Hą­Ŕyűŕ6×-ĘC.ŻXÉcě%ýfpTĚ ŇńîŔJ>pCn‘Mlsě {‡ đ<‚VQeR62Ŕ{앍Ĺęi WF¶~É|Ş—'­řĐ.k ô¤ÔčŰrŤą§87{đjŔyüÚ6^čňC ć´$źq%ţXj(ŮŽţá×—}?éô`Ý+𥠳EĄ­ŕ\yĹ7šgßkđ„tČ'˙Ń}p{‡éĄóÉp>ĽÇW%߼'hţU;GąĐP]qÎwÔKz˝ët?9ŽüóÝÓ/÷ú(ű -ęŽ˝Ś‚ĂčRÄd¦>Ń!®â§žÓâ;Đ]«táô :†??hř`Ë”OĽ>rL—–l2:|ăŔEĄžS7đ"Ď|Ë]éc2¶ľŁ÷*‡˝–*3łĄOőú©ÚÄűĄ0é˙¦:ł±w>ŇĺăEł[†/˛ź`¨ćI÷ÓF3ů”·'o“ÜöŃŽ›čí$~WŮĽŘg¤8.—?Ö0çŻyA‹;Ů9łXáM2PĹľDŰ—eŔ\}W˝‡Ç’kú˘zm“Íq ôçÍń–·5Ďv-ö:}•ę|†_ŠĂ¬CťŹňsj&L˙Á3t‡ctëQŰŠÍB6¤ŕ{éěŰ˝ďťę 9 :YżĎěÁĆ™'ă¸Öŕv'Ą8Íéë0»Ź‡lM 0a×óÍćÓ¸8·9Ž|ľďxóŐţA›ţ0®Ć&aŻ÷Žţ‚ɱ"µ6=zVm÷ěĹ^{ŤË c,ŢŃňáőK¦y·úź°§âQ˙đËs‡Ä“ŕW–í=ŢÇžűÎóŘvŕ(Ű+=Ţ3yYŤłŞĆćźćx ţ4§źě€Ę' }ţźýѧ Vűc|-Úáyłż´Źćďí&Ö2öf0ż_ÍbőŮ˙Ť«yËÉ‚ľObő ŕeEŞ©ń‡9Ťó”ătp#/ş1=Ęś?gľŐó“Üg2˛5üvŞĄő×Ňó˝/}Í7Sö… ]ô>Đ®EćăłaîóÝćgčŢŃ˙ТMž!§ŕ+¶ó‘źö1iŁńÇ%®cóšŰőř¦ů sŻíÝÔűP;ăŽŇ«k‘ŠęVĺňĄ?zni?wôď©IźC^›eţlšz±Ĺçţ¦ű°ÄcčE<®éY€;=ú‘S6ĚmpĽ±ŐđűGÚôͲý[ëň)ĹóUA× }Q_ÉćjýĂ÷¬ďď{¶éávç2žŕ 7ĚEüOô›9 ćŇYk!żQJźeKĺ9˝ _[´ŃY¶ÝÎ~ ›é°zXSrS\™Ĺ›?ŢćUújÄ·WÝv¶Sa“ŢŃ-{,;îE˙f{cóÎ;eĎän—‹˝Ł_-p#vđ{ó}÷˛Ms>_RĄ‡`P˝«s úĘo”Ú]Ίţ őîž˝¤„9ŕ|číZndxßg}-˙Ů7ëâÔŻfŚ ßcÍ ýčó-_ÚĘžŇ6üję?Ň/ ٦ĽŔmjüŢÖÝTúŁy#ݬگZ_&ls§ą}úáżľÄíˇŮ}—âĐź¶\ĺs]·†{ÄşţÁ}Şűŕ…uĆ{Ŕ5±ĺź|Ý9}±ý}/đóxľkń!Cçyué˝ú0¬#ˇś«¦˙ĐůőŇÎźŘůYľŁ˙ ÷ÇXüőž}ź˛ąšÉüÍć‡× wJ^»6—6'đFżl1ţ9Ű€5oí ćţŹK^Ë&;/ľKFŞöťá+ŰĹÜăUô€:ű‡MţßµÂ\c{‹9”Çx úhÔş— Yčz‹ń1äŢŞGş?·/Ň^°řgMvжÚ€«ęX«xR út'ąüóÂO9^ډmް´__¶vzlţÜ‚'3´jnݰÍoí¶ř4=Ó“NÖýn;Ĺʉ<Í×ĂŃąK0áŠůµŘ“ ;KűDÍľŐwĽż/Ömâ/’Ľ“ŰĆş"ô(ú/řŃ{Jz|ŁÖ=“Yť8±ubÇ„~ţ,ҶŤS›m ´)Ц@›m ´)Ц@›m ülP_®ĆÉqÝ}—đ¬„úř~đgâëÁg‚Ś}gřIXŁđ€ąĎ—sy»gżPcŚÍü>$ü+źY…}ź+ÁăĐó$ľůŕłćV«~b­qç从µa˙¸íŻŽŠO÷Pq•ďÜŞëá­đ‘o$|€™ŻŹĂ˙‘ó »ŻS>oä„÷G˛?îPá?ĽtÁ?›ÓqßkµńÇw<ĐăŚŘÚz;70ťí†¬łÇ y–żšŕë×ü×'F_`k,îe±É9ű$Ö‡­ŢÚ ĂĂžâëă*?-pŰS1żřŹą NĐ|‘ňkŹ\Ţ%óÔnk•K?(ĺň%rđ}›Ďe.”­J/ťÔZPÁlĂ ľ¶\[Ţ·Ň2KZůŃeÝŁČ7űoć¶=­fkšöń´ ‡Ă)'źx‘ă ç(Áâ;ř<˘žł'A>ëoŽ=uČüţ’iJĐ3ćf†NÍŻÝég€Pňݵi‡o+ŇV×t‹waĂTşlwč"8I”ľęŮÎÎ?©aŞëDB>»¸µ‡˛Ń ÉÁőkŘ–EśŔG{ É"Ý4ő?K˙}ŕgČoĎ| ¶ ľ“§J§ĄmZ–˝ĹŰ)Űŕrłaîtł…őóuT¶(Ľş×dSŤ6ĺ/J5çľĎWmM˝p\ó\ű%«óU˙ď·Ô:,ů˙ÁEűpŤďĹH’ˇŐĹ5ËŘë…mFćŕvŠ«dĐÖ·Řüř:ăs‚ yŐ˙™ˇ ęĚë°.ĂŰbÓMÍ)#ł7|Ş´Đ+Î_HkTTŽ®/µó¨WgdRőqµů?+śm}E·ú!Ě-ckh›ŕ zHzîÁulţ«ÍG:}x¦41W6~¸ăľFÖ=Ůe›2 yČV˘ëjâÍÚú’Uő•Rť:k(ćâ+ľ˛6_éníúQ~ćŕ‹mÝĹ—\'TžčIžo ŰP›xľăÎ{č#Űa4ô5Ńv>c©[ŞăHŻŕJ]Ŕ&{]µ=*ź4s¦ÇŘ)î—ňő‘Z_ üb?Ôďł“ťÓ»¸b·ßî|¶řsőslMú{JkyEË®•µ#ɆqŤ­«°5»ź÷>—pLö)­őá|‰5BŁGí·AYöµ€XăŚXw“Áś5:|íďÎ:ÉĎďç/Ö]Ĺ:경Թúpę»XÜŚú`ţÉrMq1fiŇ OđQ_SzĽżďÄú®ĹťĄ._"Ź`đk4şK{zˇ}eYc‡"®Žń’ş”†űťťÇy¬ ›˙ŞŰżFCëŐc <öUíŕ‘!>bq*F+q?ŇşÔ˝÷©d|¶\EŮFľôµVŢňź tCöÚ—}(aż€2đ”®"˛műűn*éę)­}$=4¦Ľ*­Ź ߀˛Mwś¶âťäËčagžÜs`ý_LÖň_úšěV*“÷úŢb2Ż%GŘ2˝ăşĐE\źř ćĎőş ˇh*Ú¨˝SÚĂżL‚Cůg>ç4îx´í{ŢV´›ĽŤ= ]ď©ĂGĺCFˇÎ©xLŁ—ë3rY•‘*ľČ†Öîú•y}߲2•†öúďí«ó ă9ĄŻäcű©–ě{¶?¶·ţ3E[™Ę´řN{äńß FpM&ř-[Î> É-i8“uűVZ‰Gř łŇ®˙X»ţćR—,,°Ó(XOcŹŘçű'|‡~|Ţ;ú‘:í"}Ä8ç¶ą„ÓĆ.w}§ŻěWmŹđ†ö¬ýB‘aörĂ×|bźË¬lé(CýtţÓ/ĂfV÷0Řů§~Řö¶$HVňiÜ•ŢúÝË_žÎŕî´łóouÄş{J꜉}Ő}©ôEx7ß÷2Ć6fÓÔ˝´k7ZlłÎ™-VŢkjď›üőrM¸Ú|~žő sĂůÎÎÇűţđ†Ź´YÎżÜâ”Ý×öyÜł†ü€#4ážt|ĂÖpřźý·×IńjóŘ\–:g&\ľl­ľď/ˇŹ`¶¶¬“zá5vśu©˛{@`ţ˘śxĂo˛5ţ_ŞźëľŢD?:|śá—Ö= ës›oě“Nwδ„ŽŇŇČŽq¶“R÷p Ó6–p8vvĆÚ¶íăÝSă÷đ83C'ą.Csô®ËŹúSX˙1ĎĎűd[c=,qčŰVmžđlľüÇeµrĽˇ÷Ő2őěp±Ťô!ś{řú×˝nË-†{č*ăŮg9ŻóiĂýĺ.gÔe:ęţ9ä;ÚĚ,Ăf źĄ°A'úŘ1ŇÝÚőXołČoűőęÓÉă=R¶í­w˙AçĚ»ŮŰ$¦ľe!SŃG\™lSŹ-˛ÍĂîčő˝őŕcĄ,ëţŽËşůqóu ťŹ˘-0“–±%ú…ľ/× 0źy/¸#ć\褭—,í2k){búkÎă…®+zĐäÚňE›ç‰Íá\éóŃĹÇĆóuŰWú©sóا+í3>ÚĐypƶź</xŔ;đîőś+qJČÇ—}tůÄďVlsŔ±}đ¦Sďč! ĺ,÷Ťv@úő‹_řů­3>ÖŹ<âEŞ#ž›m1;ü§ŤŮ,ʇŚďž}ŹíŰćkŮáĄhŔťňEúšĐ…4´3§±nöL^R űçq&-¶Ňń_čď˝öß@ł(ăţ[޶’>ĎŘüm%ŻcĄ”^Äů¶ŇKkk­ŻżŰc€SwÇÂMnź‘eóŐ€ÝúĄë\Ťe<p–˝'ŇŇ×”lDż3Ë&'ßö–~ÉńĹ3p]ăčoŔ ,‘FđŻä:G˙A>9ŕµq{i[h/ĐQŰ_b´q^Á;đü^×?ôOÔlŃé>Ö帑‡´˘…®ŤĆ•u|˝ŕî|Ź,§˛‹äÍ'žo1a®«×.ľośm~Чş\«yÂ˙®ńBĽIm x/ýxG?bűŕWlďĚíÎwô\řŇßwŃ€>yřR>Ď‘uúŃŕA^ĘĄ® s{LÇcPö”<Ä®áyĚńdĺń$ôYĺ„Ě«M]ŔČľŔgá§ŕ#ş ć—ôBҲżĹú¸&ËpI^t@6^Wř řjóő>Ľ„ˇJ‡#ÁsiŢh_ŇÓč§đ?ŕÇŃĆ6Ă'Ţ“<ĐIé‹ňVĺ@ĎmŢh<®2›F_ţçicŹđýČáßHpµúÎě¶óLxhî8ĺ_Řß÷§%ý±ŰÂ+6şľŮ´źwŃÇz1n·sď›üĚ©śVcuÇĺ]:űÇ{Łľ!pĐG@ľMÇýŚ›h?TNŕ€ě[ĽĽýÝ8łłwÓÔŹ{aă“’>č-¶ž1ąˇ+éŐ×ÎŃ׊r‡~|ľ§Um­ľF|®h§Ł}Č2ř°dîßăž±FŁŃČ÷ŢcŻŻ—č8\cçPÝhţ@ŇŹ•÷j›,ƶ˙ßŮůwŢÇDäǦôyó›’ú$ۡZíůŘ Ă /(ÝbkřMđĘwśPżőůűŘzÓÔ kë^ă÷Ŕ‰<ĐÎÝ”¶.ŇËÂbű‚O5˙LOs»›l„ęOďUĘj\ľČî CW8?¨Ĺ:¤=Źšú‰ű);gÎqŘ›k9•5 Đ\5^ ›€ßzŞô=LŤ­çÚńu_ŰÔřűĚĎye ZI®¬?›ůŘž5Űőć[÷/pĆĆĆš‚,Ű4őÇŃćÎJě™<Ďâ’_is:)}đŚĄƧ%í>¶ű÷Xŕ2ý'lo©ĹŤň27Ź=4ďśąŘζęô˙Ă7Ő:XżĘöšG™­ĂpiIĎhÄĆsßsľěě|T ßť7ä°žŐhřsKç·ľűľ|âŃĂfŁ‹đŹ~ň…ß _·ř&µ2ž8uďě|¦Ĺ~y°ůÂŻ,éi¶ÜËĂ®ŰY}…ý[ i«˙cwv×,ľ|ÁÇX˝:®­Ä˝ŹądđÎř¬qŤ §Ćß^ź—ÍÝýÔąmWžşĐő®’çvďxÎműŽźĄ$űŢQćÁő·öI´ŁjźUçÔř7®Q[Ëő¨©g–đFÝÉď@»lÓg”/śń×ݲ‘2ĎÄôÝ6˙wę|ßÝćgńçÂStÓő{?şµř\šúÝô™µ.™3žHipÚşă-^ô#ť÷6˙RĘuAăsfsě˙»ôad‡ÇgŚżS>?rířÓ=ŻĹ~)äşy®ýX(q->!ŁŘolvÍ| ť3?,dýÓĄî%H|ĽírL[Ë\;m–xĹU6|ßśŻę“©=6ÄŁBÂW‘J_‹;h Śř©ÔçR“¸ŹŰmpĐÖrŤ4©}…Ď©Żs”·ięOś·ő‰iËgkmś Ž˛Í´W©_NÉk÷9Ńý/á»AĎĐÇBv p˲Ĺő);gM€7ľŕgÂźôŠďˇ5ßĚŰF9áÓĆü§]ÄϬ:Ö㨉ó‘1µąń4ü·Zł lŕHśî]‹/(űŐTřďĹ7͝۹Ś.—˛S@61ýöťy¤uäGáKşł7yl"Ţ…_ßתäf3ʵܪďďfgť˙ä[‹Ź|đŞżů\lř »WM?Ňt1Öî&üB‡™›×f·\_ť4eíěüĽŰ5Ęa;Ô&¬>ĆňÓ ox…žŞíé-ř°?‹9 d[í’ň/«sé>o_^Đ Üě 3čQÎߡëĘ·úŘŞ†ÔÎWŘ›xg1h|ľ9ńÝîŠ9jŕwđÝ83Tg^RsšĚżkŹłěsrŘ·†~>ďľ»­]8Ąśď |lYĚm ®ŐąŠÇ*=âÄdŮܶÁ×,cmŻpć¬öŃŔcă} #°27É—öZówđ•sQ•źçÔŐh\ăëÁx^ŐíÔÖ ˘Ö^%ŹUű°±¦éB‹ąs7ÇY‡Ă˙aç۰,ä]†Ďś'húé}•ęúXĄźůířc{×-L»\k|bë•|nšňdŘkŰZlUZłLk ŻÚ—áŽóm_ň«jünŰďěöXĄßSăOr\á3|Ź’Łob}.[çv“ďŃĆ!ě Ř7đ϶.kˇiÝčÓĽ&Ep¶ćđ5ă¬úĐW[?t[ŕ1ň·}đďĘý˛ŔČůd@Ž"Óołu4ě%Ů_äA' Źú`ä!m`đŽ3ëS6Ź]Yę5r#üăÚ|5Ź.9RÂŮÖâŐö÷ý’­Ëü–ď%ä=ëABNˇYf1“Ś—Ď·}Ź˝ ×Y?´Ł?­÷GFú‡ßT˙ç_Üí8ŇvĺŹsy›íąÓV}WęŠ9ü¨gjĽUńR«k—›y {Gou8ö÷]ćýexSĹWvfóXW/2Mźđeý­+c AWĆŰýĂ…ňůl»{÷Ł,nŐYŤ{]o.Ú2äŻĘëčEž•˙Ž¶Ç­¤µÚĆ©ńťMcúÁüŻÝ^.Ł’ţÇ=P°7j·ź Ă?Úl#çáT× yJ“sřl{Q˝nläqŮ;ÜNVń¤Lµyč yŹě8cK×Y·A”igFZlĄwžj1-\C÷ÔJë;Ń÷„ssż›çˇ#”kŚSŘ:ç'úýx‹`qę{G%?·ăľKÚ˙$wŃVł¶ŠsĄWú‰ň¤Ď·ÉąŃ~ű`‰»JOkć#féYmŹ­Aw9 ÎôQąČg”ëű)ż°ő´Íő_.cˇŞ¦wŠĽ˛+‚/®)íáÝ%źv"ÖŠ®Q’íń-Úx^µ-Čđ –˝Ł‹Ą˝íśůP©+É6ŹlíłýÄŕKlEµč¸ť{\ç\ľ±ů,·}8Ýś ´Ő\S˙;ŕŘ;z·&˝#͡}FĘý­‚=Â&í¸Ű•¶®úß sŹń1„ü%đ{n[:§L|Î'®qŮŘ4őj‡Ól—Ă-> nĹ1°łâëÄ1řś­cŻaÇÂ×­Nëü÷©çärŮ'MŤ˙gŇëÝá]Ă^OL¦<+P´ß8󡂿Qâć±ű]%qĹvť1ÜQĆU »éóOą^7NůSlŃĚĐŐ… ¤ň°Ç¬›#÷ÜľŐóËĹů¸ä­Ú3b§ňĚlBˇ/Qߡţ>ů>SĄ\*Ϟɇđ-ş¨»řś÷Ąí·páŠînśą¶Ě»aî*öŠ9ź›4č†Ú¶j~ôÄÎLöôëçtŠv9óö™v/Ťbď“`>ĽkŚé÷ŽţZ˝ÚŢ,Ë•Ô<Ƣ_ßh‹ŔËÚ‡śów—±ní:ˇ—ö ŰFŮÄ—Łt®¶¦Őó$ťgĽí’ ¨ťât+_9b°WʵęˇĎ`qhęcóŻł˝ťú“źüSÉk`Ý÷Ť·9?]}Ż #ďŔ:ťćjĺ:O;ľčWĘť˙‹Ó[·˙2v`ýűXăëţ)úµUËSňţ8ů¤=Â;®ăt1+a"Ą­Ńďľnôߟš¶–ń?r^ŕ[•]ţ«ŹĂ=y,LO¬ N±L§ĆĎ.őÂú(NăÚÄďÖ/\ë y10lńGM>VňI8kŮŚ3kO?W»ŮâRX˙Ęší!čŮŮůsě*ű´;đ~˘«Âh®0řŔŰŚ»g_3W!6_ ĹżtúÚ¦ÜâO9Ţ”O{(›/^Řţ¬’FŐr~Ú={žˇwU›qN}äqrňcv÷­%}ŤŤŢʆw’qpäkcCŹGFy´eÔAňąl˙ÎŁfčś{&ݍ…ž«źG¬®_ŞĹŻ¤Ű ľź†Ýť˝×>‰Ô&9ÔßHű5íMÇçE¶Eă{_ń˝#˝|(¶'Ěb‹<ÂŰ7đ…żĽ‡oČWŁ‹í˝ůlË’Í—kŐ‰ąű^xŽíŇx>đ&ýJ?ACőR)ńśőňjáz ~ě•_‡<řy‘É`ÄłćMđŤ´’iđŹtYî¤áWŕ€ćŕm(ŹęVúxşňßŕ«be„ż+źX¨]4˙WąÎe‡żŔ€ S?}¨?Ë~ň“ µ'·Éˇ+Ä{ł·CĚőŔă]‹—ůüFß"ü ” j˙Á[ă‰íŔ {Ö*śˇŻŕW˝<‹š‚ß<lx›Ťé7äîŘč¶'řé‰Gf{_MgCw‚ŹÄ˘óYĐŤ/¸R.:i›x6;0–?ĂöLQ~Ŕ¶ňߏď"®dčjµÜË˝]:Ô§gŕŚ\wÎśiű;źăľ˛D/JŤ±/ô±u ¤ľŕKŚ p·jÝô»4_M]ĽF\ó‰®ŇŽRĂĘ>ˇsKëÝ4őxß_"}¦>đEĆG<Łnţónî ۰„®.tťW#z ľ\Ą+â-˙áŻ|!Să#.'ď(ÎaN4Y–ç’ĚÄ}ÂVŞäY4×Ŕ ţŘi`ĹÇ͸Kí3óŃĐDůŃwŇ+iôNrC:žłň<Ůâié?z-Ú űĘžŐG\RîÁXĄs |yÇü€'Ů—fúiž4ĐŽň¸çK~•%ţSuG¬Źĺö|¬ ÇĄąěüxóŮ˙egÂćÝÇipxýđ‡/x‰ß˘°ĂGúˇ<űNqĺ>üWĐ Ë  8Wó/4ŕů{Ś˙z‡|3ţ¦LćŔĐďx·ňÖýżĹpŽŇĎ€ťNÁĆ5ţ“:ĄE7€;t3ĆéĎőSéí˘ýőľŠ ´;«ŃµBßHµ¤ć{kG ˙›Ď‰{ź0Ů”Ŕ€§ ®ŕáRÝ@>šűMě…||yî9ůĄ7 ]˙•Ë6ó;Âüă Űďď6Ú|äšanŐżÁü7k»o¬Ă#âĐh ŚČ1điż$<®îźfhBčĹ|G•>F‹&zYÜI—_äG¶"Ć; ńNvô?Űűć­Âoąr sŐ'Qµß‚ßÖ!8ÝĎ)beë9zI #«Uţ‘şí{űĽ>5~^ŃÎĆóŞÎśŐxJN?8Ťi‹ đë-h“—Ă6žĹĽyć:‹}V杄י!âŞér˙·Cot}CěŤÇ㊳mHi¸bóW›ďü{Ţ'«ľ‹ű¨[Ď‘óůçĚ|¬Î‡ąS|/O32ß,~E-|TFŮg8Î3CĐ|âł}đ˝•˙áϦżůó ]+‰´WY R[üâS">mĐ ţ¦ä>S÷C~ůÁFóŐůŔcęQ|Zßš8¦ĄĘź%/Łă[űfú¬˝ŢJ[ĄĎÄôţî|âMĺšŢ…Ď,úÁEśrĎjľ¤UÔé 9:¬Xń´Ë‚yÝÂ[kÇe_0żŐ©ť3űJ?ŮîŮŹ”s.ŕ,š ljér‹±’Űžßeaďśyß’ç1‰Ąm~č*ň±ˇˇ“ÉgŃ?ü¸h»şŢŇ˝w4ćŃ ĂBWŹÍ?ŻűĄťß+ŰspÖř9ˇ[Ľä*ú/ â÷{IŮ>NNžě4śżßcŤţ›ŕĚo^6*éHîž”˛}đB§żĹG*a«–~áü—κŵ ż­~:¨± WtZ’÷‚Ĺ÷śR-Łz?·í/lÍAśÉÇs›÷®Ř‡jĘÖÝ×㟨ornç‘Ôn[˙GĆǧ›Oč˙8żó‰+î=“wë›ZWÄjoĐŹč‡eel–ąm'ňŔ\ÔűOm4ľn<˝ľ{búçÍ·|}ío‡:= mň‘Ú÷Öá¸|IŃBÎ×â˝Ë>ßŢQč;cÁc«ňŚŢ©˙<Î2Úń[|V~®»Ż*ô8čúß|üí§—ö¤š·•÷·­żÄŕ>˛—{ýeŹ`‘g1¶k® ş,×oQ_›q`´=)ßŢŃŻyŁéµ•O|M­őäÜMÎ:«‘Ö]¤Ü«u'Q˘9A;ßw˛ëíýMF3Í]C'Í9Ú<¬ë‘ň¬öő+ďKíqđ"Ť c<¬[xJn>źôX‘eŕÎ'ş]nł>ŽÍ%—ýrĺÎm}éuň/żÇ|!řŤx&Y:©Xß°Ú¸.-_şë¦«Ź¤v{G˙X?rëz‹˝’ /Íűhč:8Ů|ťŮĺđgi|ťŔőbókVÇ—KaY«˙{&ÝúÁ3ń>Đ9śĆß*,g÷ĽŚÇĎÓşłĎĺYTKűÄ·PůŐňŽć˝ÍS•m },őÇiŹw-~¬ľnážőĹőďŞmś™(cÂw,ü®ë¬é˛űýŔ yAĐcł÷%žcóW[Ú—6ühbş|ÝŢóŰuĹB[ę+@Ţ“ ŰOúź>fT{M{Îč{ČI*żsćKš¦§Çäťó)lŽt8®vvŽůh{%ŰŮÖKŤ··LŤźT¶óÇ$f?¨áŽ[ň >˛Ż6;p^säÍěl·’‡ŤĆŹËűćT?{˙¬źąlýgÓ6Fm ´)Ц@›m ´)Ц@›m ´)p$˙Kcdb´°îxfhô ±â>ŰĂ˝}đőG˝ůł«6Çx$¸ÜYŢţá׸˙±qŁqS9ď Ľń‹ČʧrX“Ăz@{çëNbŽWoŹő«Ö¦ĹÜ!ţN ­ŔW‚Ďżń\7Ź}Ďi$Zm˘^ČŔČVöu…ŹřŘĂűmł˙Żb>Jk~™ĎJńđ‡Ć\…ÍŘú |ř‚X' =řâ'ąjú±ľ\ˇ{ y·¸ţĽrľäX rËMĚÍÄ:ÖBŘÜjΚ&ኼďăşgr°ŽĎoľ)ÎĹĽPř{Cňížý…ŁŽ÷Řü/öÂŻ1[ăk8—¶‡őśý:·-ήjř,ź ëŞ ř .Š×sĆđc śF¶˘ßm¬i–nčŮŃ»ŽŘşÚó lř÷€íŔú?«]39Ů˝óŠ>ź_±ő=~¦¦ÖźŔGłu˝ŕëë3ʵFËc]‘!hĆšŕĺS­ŐS[;?zVÝöH¸ÎK|łě´±7°Ţ {|öŽ7r*ąvż·­Ó€>šźł9l÷˙íZ<Ď}cć,çŁĚ–ľnÍW­†Ş'öÄ&l˛}}. |áEçĚĂMŹO¨ÂĽťŽůśăÁďĎ˙©ńý6ýěÜć©s;Ç曟ä÷ošąă>·íYeŰ'ů>¶YCgĂN‹·1§ĆshsüԸϻkż¬ć^Wk˝°ßđ[°ď—>ă:ô ęÚܣ㽳óÁî˙Ort${ĺÄąCżŇžłěQŐgş~dë ö;¬ý7űUűcH+ůf~ąć?xÂó±ů{Řľ×Zţ·äűNĚ?<>kk‡¶t÷_kě%ń_€!Öćééę] ľR·Dwŕž:Ż6>űöRž-ÎH~k×˝św’iě4yÔ˙P†}Š4·ŐagĹ~<;'ÄÎľ:Ói§úT†ÚĆŐÂöď=¦Qȱp€ÖČgçS_gűtŹë™ú×îěIÝ3ć|·GÄd±}µ>G#xC>˛LxSFđ^ŹřŢJ·Ł˙ó†óqľżCeH§R; Ľ­ľjďMŇ_drˇëŕsxŤŽ˘ýJ0`€9úśűçůUă];~§tŕ;óĂ…r.‡˙”>PďŢŃď×g†¶;=馚Zs§y」o+ű¢9×}ëÇý}włýě“>öţľ?ŞI&BÍÖ}[O:oźI븋ýyËŤ38?›÷'Ěý‰íI»ĐÖ¶>Ý÷¶C¬9ĺí‘^Úąˇ°™Úă•e¶ż©?ůŰ…ŤVmť6ĎŚĚcñU’ă7ÚšMS3ůîŮs˝ĎéCn‹ö]‹ź*čo·^^čr–Ýb{PĎjtçĐu¬]PKÇj‚ee×čű’w×bđ“{d mßwŻť#fzű—CäŽ÷ŔĂm.ÖsýzăŕÓ‹ěĐěč?ż©Şö±íü9—™k&»cÓÔ‹íYĐ uéuëÚíĐăąm7xýŕ“Y|”ęąO÷îŮ»ŐÁ—ú>ď™ěUěCÇ9bČo–=ręA5ÖĚZ|0ďs «–ßŰ­ý[Ëşú‡XôÁŮ“÷ębŤ`ŕŚ-Ťd/(űH>ŇcŃ•łŞŮ~éě7ňÁüąÎW‹GQ®e%ťřÜ?ü×őÔ·Śąőťťç{ܰ"ťÓa×â/5ń™łoŤ]F‡—Ô Ű9ůŁKś… c”ęD𵢽glv‘őhčLČ4{2źŰ™x§vĽč e›Śľ ®¸¦őNŃË2ä™wŔÇ^ĽFă‹~&TŔťe¬}†»g˙_ýRgŞśÝłÇ;ďY3ËłúÄ'+űň‚ď”1îűű"×áţľÄâĐ_¬ËŹ2‘=đ?Os‰fŁ{ˇ q˘xłaî;.łvv—_)‹8ľ·­˙Xý=fŻhĂny9NKpĄ`W96Na}¸ĹűŤÚB×nÇ·ř⢠¸ ßg‹=_˘]3t‡ú/ʓ͕͢LŤ…(Éâ,ŘÔý6¶ŠXŞó}“ŹőxŤŃvĆ] »îSg\Y… ěNŘ č)ű‹ŻpßŔU5Ú¤ CĘ5Üń­Üú¤Ţ<XuýäőׯpĽ™|ŕ­ţ€őAŚoé3żĆiżT÷ N÷éŃ>3mV>qSÍöţ;¬ën±«ÖŤ¦ułŘűý§”:Î9e”am±ŤąfËv ®?­ľŁ˙wl-Öj¶v°\‡%ýIPęńvŮ«_Ą!q­žçú{Nţä¦ú“ݬ¦ŻĘJÎ%˝ö Ľ&GoŔÉhb|ńX*MăRžEąËìţ2H{ÁŤa–ĎńÓž öH·yěť.“»gYJ[űvôoł±Ď«rÉ>|‚ÎčĽúĹA·Tßş…7Ř:˘Oő÷Ťö«cáľ¶O6䪰®×ŃŃřqEW\µţ2ęg+ő+|Âö=ß8°·—ö‚ňBĎŞőeŮPçĚ);úŐmëx]^‰f×YĽ1lmU3˙łŚ=˛áv{Kô{a![q`ý{üťţŰš˛B®´¦¬ K3|śµś(|8w&kv&(ř^VŮß 4ć±˝ęÝćtX†;žŰcëŞKygśČWľ ĘÁ7bë$}/eLLßđ ŘI‡ GŰżâ4´űű~Ăőigçësů ”O˛¤ő–ĐxG˙SjÓUÖť_cşâ-{˙ÂŕB†é·cˇ6žm»Ź÷QĐQäś|!݉/ůo÷Ę^Waßu 7™­ţAŮćSćŽţa§ĺŽţËý9´QľĄWh`ű¸VŚsˇ[Vk‚W÷·Ř9ő˛ŘõSö†üŠťý|™ďíݎU’s0‰XăÔśđZ‚÷ž“Ď)ËŠ”53ô–šéŹ3 WéőŹmE8?ęňęúáŔYöÂ| Ţ.˝}ŹjÔ­3RĘţáŹQ.|W8sž{¤Š¶ ÚAřÇXlăĚç}żô«Ţ ›â“K|BŢćÇŤGł9Ę‹~¬Ęޏlŕ_íűŔź°ÝŹóמ8Wőš;’‡/éŃUĘỸ>âŇ“ŻŠŰą·6€x^ϱ=l_ő¶]ŃÝúâ+´aYFüنh ÖÇEż6čźLwK5z ®ËÎרúŃ’ őĎŔ‰üâ15°çdżéď ď4^D†ÍîxrŢ9éăm]Č’ž­ô:âç˙žhm)z¬¶G˛ uÔľ’_ŕgö¨F{ć±w7ĎĎ…2Émb–őďôńţh!špĺ4 ?:uRxbÂĎŽě#şI7M=łn{V˝ Sý‚K}!úč 0 ćöv‡˝~ŕ ň€|ĹcA‰Lßpv:ňž´ˇ7Ň/á5˛ŐâbćKŰ•µňkÔcgx÷ÚŮŰ˙ą{÷LNćđ\cęu»kĽ_x'ť¦îťťăŚŹxnqĄÎđľřC'Ňo{łŰyőK,ťďYąÝŢS¸#סŤčĆ?ʆý§Wä=Ňî/ëç) ˝Ţh,đůÄt®¶~ń…ßęó'pß-ípšůáCLŻ–íwů$8ŔgżZYŕIąüOzˇ1ą019/úŠŔąkń»eź^)÷z\vQ­zVŹÁ ¬Üŕ?ó¨Ř'd^p‚ŕfę…äCÎ?ZŔÉł=“ßőľ*ôâ?_ĘSY<çK\ɱµŃŕ†î:O¨/`˘¦V}GÚ„Ď7ŤĎcÎí[&§đXĹw`Ö€8(CW‹OmçCóŚ3!ČKzbןç<G®üW˙ ®+ĎŐFqĺ·ć™†_ÓW”úbg–—}Hŕ%48٧˛yŘpη7ß´Űzăá–!3˛őS>¶Ůşnˇ+'†«d<%7ŕűáćŃ÷Nń śwôß˝×bô5őÓ•ęH®·Ů>~úq6%Eťđţ`§%{zG*âÉë?rrćŕ<.5ďôś»o}ř/z·ůCzB7˘.ŢCt,Ũ±ţćlËńeî ¸¨‡ŘŃ,>­Ôé°kŃfnš:˝|2I®/żŚß´TgŐw¦~úˇÔŢczH›#\Şíď«Ő,ĆŹ…±OUY ą Úáď5_O9čđ|ßX˝Š/:uTkhÍým}›ů#§ÔUépÁ±ţ˛ě¶őďë}]eťOÇÂsëWMŹÖŹ*T¬÷ëśéx ëăÔ–ó~ˇ‹yH‹ź`ý˝źüä'úˇK|R\ůřßú_átŐšŽ'#žŇfť“Ëy$»W…¤sćžĺx~G˙oąÚüŹůF{m?»Ź—®šţŐ|×bż—‘řHÜŘ“kü‡ß|ő.ô«ZKëî«2 ŢÔ+ż6öŠš¦GÖM?Š%Ş}búTNľTNĽµó ç~‹uz톡¸ýÝ7đsÝ»źŐ=şxIécŰ3ů¶Zµ­í-Ćů*Ůlŕ ű,¦-1Ľ]N×-tÔXëÔhÜóTś<3ôľS8…\Ćo‹»ńăd čCńŘ>1'bçŘśôťçűÎó< ]Ď8yóا=ö)­\ŰK»ľ®řěVď2˛NĘVBŹöŽnňľý€‰i;Ëáě3>1ý5÷ýŮú>óaʦć‰é©%ńU<żőžžËČX Ą~VcÁ|Ý÷ě¶ł?ýŇÎ÷z”cmDŃ͡şd{Ák±n’T«ő‰y%ř«>.đţn˙íΛý}_¶¸ĚóožŇh4NŢ={UΤĹ&0ˇľ3đó =A€|ĂÜkMžĎ¶8î˙ăÔÝł÷rŮVß ýpÇ›ęčG˛ź«…ŻĘŤqĄpy'6Đi˝ŘÜ…®ĎŘ:ľ˙f~şÔCÉ?c é#°ĂkľôËŔ9l’ęI×Áüő=ňkS‡bŠŻ|^*•}(w¶¦±lŻčco|±÷-ä;ű%MĽęřZôC' Źúe˛ A3›Ł3\šë§?ů!ÓßjÄ<&źč…ÝŚúšs¬îżG˙CcĽĚűČ Ľ¸ąĽKz(/µąx«˙cóŐó‰)m;ňž´wf7ęÍres+ĺ|üębŞŇű‡ďëí(đj,+řŃIúŽćÂGcc*‡W~‡đ»¨¤D őßö <ŰeCsýV®óů—Ý‹w*cí®Ä|„Řť7F_zŇâÍ[\ýÚŘ|í­ó ¦ř©ëľMµŞS˙kăĚ5žľĘŻ~I7\;Ţ];měî«2¦8ęuM=łgÝÂX»őU×ń˘˝vľ,®ź¬?rjüT[_TČkZ_޶–•<>V@7ĎîuŮ?ł5á5ě:Ďü´čdg:­bßăP0NiÎîßPSß ^ŻÚťÁü“ĆďŻř:}Án9˝ż¬±¤xlrĚĽžŹŁé×ĹóeŹżśŹMuí»3Żs˙¸Ńv‚»ÚUžÉ¶'8#ţÚ†ą7ř1Đ _§Ú]dż•kS˝­ż[:&_ô“8RV[1&˘Ţ°aŕ*|Č÷pÇkŕ%?WćQĹcřKnňhľ“ôüG~¦ŐL{íř=Ü×s±áëąvśąíŁŤěě«~ľšË Ť|ţř±ń…íěśéćľ"|D¤Me“ăč~&}íyěi¶řłąíµ(öó%¸Ö-4lžőM~Ďäű"]Ěç€3_›Ď­á7' ~ü[lż“t"ÎűJeť»´Źu¬M<q§Ű¦ă˛ëmţyáTŰŁbqÖOw•Ď/®±nťy6d^n{ŠËkfĐéŔ5ÖŻ†ď9:z|íŃeYؤXωî ć÷˛ů÷řĽ$¸Ŕ?đ@vĄËś!PŐőß„Źé‚ĎULL5ß;ú+ąöÁ×]¦tkwz żv-~Ůůj“ď~FÝ”éëž_˙zĎ汿wśář‚¶ú®™_Ĺż E` ýKŰĹË@oŁ>é˙Úáj{ l~ Ř9Ůü•ő˝Ł/¨Y[›_;~¶ďçß1'}%ĆSÚ [«_îÜŇ÷ Ć¤¬ŞľXŰg ‹2ôkßËątXo‰Ů<”ÖśaK{“CďQXĂň?wÉŢĆE¶UöWKü&ďxl¶ďYĺ ü¦“x#ůp>ŰëňŹĆ2#±®z6ĽĺĎÇ ç­Ĺ'ĺ›qgç I~4áSzźT˛fÎyÎÇJîťË”ŕ\#ł>ö"Ŕ*ňĹ]űYĂAŤ(s«ä•)†–=ě"ăW†ëJw§řnąZ\o¸Íâx7ĎĆ:\¦ŤĄpą6zKßj['rů@W1´śŤ>î‚3¶#x»˝™>;Áç_i~Ë™|rFÎ÷˛›Zźť™ÂyîKüŐ ú,ÁŐÖ1­7B˝ĐoŤç®îđDÎl—|?{čŘ\žřŚě»?;·yć“ÝéóŠŕźăíă°ěËAâťdŻ–”÷3’ BÓńĆ{~#ć­sD®člä‘2讫Çú´śť™-ą;˘ł)é3Đ}Op1»Ü°l­ŚŮ{J®ˇ4—‘ěaŠbuPýâtYȵ2ňÔöđě8%ŁmcŤ6fÁ}—ćîčËë\Ëc`lŽ8¸ţ»b7ÂGŢe®H˝ěI§Ź€+5Zż1úÂKtÄ™—]ß]ńsy“v%¦]ů> ®äíůÜ%üeŚđ±ĹxAî—®™úóđV±ĎĽVďĎ ŞăΕ#wă@ć;Ľ”˘ łŰéŰ>.Ď˝µ§Kß“ńPůĽµçÇ*ß»>}§Ďëés‹Ť ´qĹl'čźĚ FŕôŹŤąţÍ~đ™m?HNí •‘#rreĂyŔĽO9ňüxmĹđÔî3Â-]WŹ]ˇřŰŻić4f^çôó˛óą˛˙Â}ÔC˝ŘŘÔqLéY˛×üHŮ>xÄÚ Ĺ'DýŚóă?¤}őĂ"“7­Đ{ô5˛1ýÝŽĄßűľá§ę‡5?đWZß2“XŇí7Ŕ$ň 6żI¤ěÝ˝÷ -×ß´ś,”™‰me`ŁţîűÇXźÔŰ~˝ö«#S«Ş[˛§G9¬źâ˙ažů·Ž®r[Č~ö%ö8µűÇű”gŹ÷jďP˙cý!‹ ·Ămo3uĂăČsÉV}é>, Ű8; tÓCŇ/±5‘yĎäĐ·WŢŘ){çâq‡>¬.Łi|ĐoĹpBűB¦ţ†Đlżąq†ÎüŮ٬ŢÚ|®ÔkěĆYđ6^Çm*,ţžŹMč``ťŤ1’ů=Â3ÂsĂűzşdŚłüxŽŁŰ8UŃďÖź5^°»ľ@媵z”žĆ>2pórŤăJ ńŔߏeĘa۱«Ű –ivźŐ$óZĺłś‡¬°ĺ>źŐs#E>.®č29k3KŚriúÉ•ÄEC/·aJÓŁą•µŰ•ž^g{ĺ˛gCă%ęL×ď4&ľzÇpśýV"§ézą·ůş¬ :m ónÉ}x˛â˝­ĺÉÓ{c–± ŮpÝí8ŹN•d~tŠs°­hČű>NK|¬Ö·_­wm¦ľ[ÇţµŰS1˙foR‡˙Y=îGťŤËŽ~ŹĺWé/9ă±AćJĚó„ă˛ßő*ĹďĚÖ“c˝–-?7 ěčl—WÇŤ«ä\ɲ‡>ďĎá‘Ű5óăq_Z™gĹßĹ/¦íx˝Śĺ.ۉ=łŁ86ľGŢ÷Ń8çNăor¶|6˝_•vÍ_e9 7µ®Ő}úŚ%ŕ|#8b“ŔÇ—\ÝĐÇÇžűz^•ÝtŮƆ>îRÇ2.źţäţn3TÍĐýWŤĐîř7öž3¦Ň°0G°úŕä,5ËÇ7¨1ÖĐ™÷MoAʨ݌ż‹uŞôśŔă˝ÁŮÇÖ¦/đWíßM×ęä …pŞď7â+úfśçšńÜúŠ·bW;[Őć%Ŕ({ťbš4ľůÇż•'N’ľ—ȸÝ{ą$ĎĎáx7ríWčŔshć:?m뀿!^†{čL9dŔdŢú0şúşÝ€Íigź'ëPÎ÷şµçÍ3ŕxß×ÓŢť-ż&ń^eşúŮľŔśô+ë[A€<3˛ëú,˝÷‘ş(ÇźË¶Ś‰Šż1—4ů1™Bő{}܇ĺŰ®FľĚc{ßű <ŕ ßé‹n7҆ŹËČ1đ!מ“ĹeZ€ﻝÉ=póĺ"»'pÝ ť ż9~”ń=ăÎkŻÇh¦ü^˛Q)p„OŔn´‡}…íäs_žCk`cŢľÜ{ĂüFź~đf/prϸńŽżO{ŘŁČ-÷ŚŤVźĹ˝›ŻĹÖą?`şzM »†ĺ‡sô!÷ă+Ŕâąŕ ňč|áĘ3Ç›˝†Ü“_…˛ĚŁÓrBΠ;D÷LÓW 14˘t…É™µMnbń!‰ž29)Ţ®ľř3ÓňŞë/§äÓĐşáźď9§-·ËW^pň ÁÝűč%SŻÓqÜdTćA⡯ó^~`?9C÷ëš{ËË€3÷\‘ëă†3rć0¬¨Gő,móěvÝłâĐ/ćjm?89Ź€|éł.·Ŕ ÎČ,° żÓşă;>ö‘ă9{Ĺx¦ĺ»šóŽwˇűĺ¨CëŹčG}Ž—Ű ŕČźĂcßgş¬ŐmOŁńŔźŮř€ X‘1ţŔ§śŘ0YĆ(öGrBD®’ż[íQh ß˝źűşPĆůk¸Y†Ö®ßš»_%Áťë~ŹOŠď|\Źr®ŔĽ[|}č«ŕÂwćóä ~°í9Ýäd©‰?ţJţłüŔmRźűţ¬čŕ8Ł7ń?0n¸ŻŤ÷ťď¦SbńbśĽ˙ŇĽä*đDxÍŮĂ Îčqţx‡Öm rşv{'-Wi˝…Ľok1_Ýbńl,oűéÁÉeҶ3ßÁqµě٤l:·á§öěFÁ'ŢIçQä×í·ő˙O×ä- yh+źŹąŚ/~¸Ňôo›Ęc`3ť'öÝčÎcŢaN ~ µ Śç–Óă2̬‹|Zˇţ—©?Đ=;7×ÖžßKLÁËÄŻ:ÔÇÓ|§¦ăoúŽË~Rc3ď’qđ>‘Yă“áÎčNK$w–čŕČŢеďnĚßś3;§µÚß%ůç•6VŽ,űw#'ŠęóŇôGu\–ě'…§´ĺĽFgJú(ÇORwłî>ôéÚ/]—z~©»~>-y*eě ářÂs’ű_ĺXVÔ‡Uîß7ó29ߤ3ö Ď´Jnf>ČRúă˛eWđEľ y{ĺęnhí0ĄK5ăţűTgh»ˇ¸^uót ôwŮ™TŃf{ĄSů<<óĄ\ţXÖĺ÷ŽúÜ#ŮBÁrsNőý[Ś·ä8Ö˛™L×áĄ×ŻÎ–?$9Ü˙EÖ¤-¦:#Ď•‘·5č@|:ÍŔqî:Üçmżnků[‰˛[K·â5:u—úđVÖ.’őäODxýW<6Á+·%Ľleäžmé{ÝšBá;]ŇW´.žť g`»ä~­í¸=ĘoKóqŔjßzý“•Ţ…Âá!ůĂgZ.lĎÚ°<ĽFrjY›î˝ţ łŰ&ŁSç¦{öŐ<č9ë—ŰC\oű—8/Kz¬@¦°×«ý–ËúΫ“µ­íkYÜÉ·Ü w‰-ńţwd´nŘZ=PüľŻÜÎű[á‹őIÉ;•æńď~ĄŹžćâľ´WŹ]óŢń&fÚËŘuqxýń҉Naě°qޱűšý‰Ä/+ţĚ=–ŽMácWů=¦ź—őë¦Ö$÷x›Î’qd'ĹAN÷pSó8L9Ł!nÚ›;Ô\Í>7űjPóaW$}zPć\ä¶µśéą„¶”–|;ú[Óç+µŢ›RşŚ·–ň3¸ţNťßĄŰHÖ™}ü_|ěCt›ŰuĽă üĐgCń˝9rjŤN˝Eű€żç˛+ăš,Ż[üŠËxşőĄľ[ë¨ţ…ćŚŔ€ćŹx*i?–Óź>n'šÍnĐąľ5;ŠŘ 5qp<í:¨ţohăex^žxţNäqš˘iů3ŮĄź‚;půYÜ“SŰqÇîň974»vä…_ÖG:+#Ć ŁÇâ<Ľăřľ'5čą4D;ëľÖűgšSĘáJć0kÁ|;řůc­˝‘†ĺyŔ/€śĂeń)D1f*˙ľgř»Ć¸ŚĄ…ţµ[,$ňë>Üɡ}Ĺ×áľ­ (Mď­yá1~2ó{Ú^A|F¬ÓUFÎ =.\öYeÝ—D,Ť÷ŤůĂÖüľT|Ó˛oyŤěY85םecń$¬łŤu"»¬IÁwâ?gđđ5 ~ß·ú­ˇ >1|IřĹé.'ÍÇ`~5şŹZJIśRż®ŻSĂ@ć ±˙gcţźă3TťWľg×ű,ĎŤIűßÎSdÜi”Ľ±óď<žĹaYW:4Ć9 qOľżľănWóÝÓ'ľĹI¦ËóŽÇ€ˇßń#7ţľłľ™˙úŰZÝŕzŮ?™]%9˛ĺăÔ§GĚ}“±‰u ŕNóŮčÄ9ô›Z-.a·`rÖyPq,Uü®—YÚ«í °u Îw9"»®´RűˇçLIÚ7ľčf×IŕŠî†çŕĚžRb>ýwüÚ›~rQ—,DĆ1ÄĽăgĚOh—´´´w†‡ű¤Ă˛Ĺ·dËĘ_Ń·ş÷ ¸&eďÄť˛#<ŐńU—E± .çŚKÜ3fŰzŽ®÷WëĽswôťëčĺű˛$GĆśý©Ůř_¦ýÉÇ ďk‡)ź˝-dŔxf±ž|ç^ł˙ůZ.rŽţć»ÓŇĆć¬Ö+cB„ł•Ĺvszy¬´·ÝĚky‚\uÖ&űĚŽ˛ďrQĽž$y‡ÎÁőÓbs°OŘ .{×í-Ţ|Č-ńdżĚ‚§ëFôŐ@†ý‘A0:őł.[ď±|!”uúŃF3ńL×ĺëţC3-ŠSçUróĘÚJĹ=.çcĘ˝áČĽyîúŰĺ—ßxF˙ĄŚÓĂŰâ{iúÉaůÍą.îť'JŚ!e©»Vö`6ČYî…Ţ{>8dOö‰Č9'Ą(śáUą\Űl­ţXaá,Ă9еH‡ŐíŹë·đ¬Ú˙[ÝKkĺz d>ă^řŔoäű“ÔĆîŚ •‘ćźS–ŢÇ„n"GpWF˛Ůéžß§×ÓâśvŔ‚Í\ôQ;óÔqŃÜo]<ÎŢr8Ŕc_»6›»őE)f{¨“łÜ ŐéřĘ„¦ ˝;, ȦËĽŔÖÜ}*Ď^óGtŤmPĎńgćśÁŢ7—g_{–W‰äěY‹oCţ±Y„—©XJŻYâM~ž“¸3b_Óg‹ á?Ď3u;>)µĐ;çŤ]=‰=¶:·öÜăî}»Š18ÝďˇÁčÔ¤śŃó>}˙îŢóTF™7›ž¶§ŹÄvÓný¶1żŹňZöęčžQžc‡Űن[tćČBM•ł8tú2´äąx#ép$ŻăаP8eÖXińÇ“ެŘ:·5ŕµěSzmËŰÉÇ÷ľó„}_\ťÖÜ/ţc˛×ZýpŽ8>÷e€;ĎÚ"=TëÝ_r-ĺ˛GT~“3U‘Wä™ĆĆäěDᵜOř ÉyÚ©ůóś–ŚéĽ7»ď;óŹí˛m-—6Äł»|/vż‘ʉŔäńhŢľ_7üeFÎ|†äx{Iw˝íBĺżm,'+ĺ‰3™+VŃçŰĽĂyˇĐČi@=…Âe±üŚŹť×`›$ď™üm?.PĂü>ź“6¬>®ž#ŤZŠa&›-Ý%ľśŽ‰ˇ‹ăX~łţÎťL73†M](ŰËöľpm86ÖŤÎŹń´óć‚@ĆkÉQ\Ő>oăÜ7$ĚUťŇ§S:,HŃ&Ńŕővç{MדŔĺ4°ľGť75äVđ}Łţ^újă¶Á–ßÚĽĐÚ±řWň žśeŚ˘Źó&s‹Ő•5"GźędĎCş>îŃ-Ȇő{«ë^ńˇZ+óýßçńiÜížv¬m«óÓ')މIĘ ?/i|űÓvČ|Dâ»'»$Ć;ŽťŤ ßÁEb[µżH›H–ćŢ[Ćűô ®’ë#îcóĂ:Ń×>ÇKĂĺ|ľdę®{>…}ÍřÍűé˛Ř™GUf2OÖr#±ÍftBżË8ü5±ľl„:]úÝaJëVłiËíŘ7ÁĺYó6lÜ žÉ®Ôőň½ ýś‘5ĆÜ4,ŔG~5Éă+zŕ]é\Ľ˝wP'újcŢƲá™îŽLý…Ń\ő±-ŔřĚx-k˝{+,ĐÄtµĚ÷“śu ¬“Čě )kÎ!ž›Ď:6Ź‘qú“qß~da6Î@QoűżĘc[×0ÚBGęşj_”Ďń¸Ô^ůJ,KrünVň‘ +»éëä耾F+«ktę[±®źÖí•OĹ6ŘCäÍ’Čű,6„ácămĎĽGr0]){e†şř,łqĆ6Kŕ0ť¦f‹%żú]{ĺ‚ěđYˇäÉýđŇĘdËďŰl Ë\`¦Xůź¶öŘľölÇ˙—B[ę7?|şńÜp·ś ‰n#z9•?áąĂęu¦żCđµ91~Ó6ŮWł_Şż~ĆîHŰ 6kÍzŽś-}_Ź|â;Žçě77ËĽČu}FÚÓ9>mó®]Ń“/R™đňr˛śi|@śs:Ň4Khd<ăwßçާ‘s™»ĹňťÓŇrŚ,­¬ýPűňŠúžş—Ř× žů\Ý4?‡•´ţ›ÍákOó ŰŢpCü\<ăĎçiţrŹéűQ_V|)K›ř­UËűŕ6x§ëĂć>=˙ąxNź©· ţL[#SJăHOË›ĎŐz_”/é¸]ŕ®Ţ'árČ3Ţ/đs~ű•şůnŢĄ]—qčÇş úpo92­ĎĄéG™•µ䍺ćűą^Ď*}ĘmŇcÍM6y–8J÷íň2InýĘČ-!ëPđŮńć]lpF6 tâ—iŕ„×ŕJ}Śőüî8Ú™Ŕş·Gźůů»‰ľś/¦łßo´+ÜĎCűĹđ^‘ˇÁő× źŔyFřfşĆü!ŔOnp.ł+ÍćqśÉł´­ĺťÚ/‘kę .hEyÇ×®’ UčÎ=żC?t¶¬ť/;‡ů}wřĽMdČűRZľńµ#ňéy˘GŠáą:ÎňřQă•÷Mx ÜÄěK.o]ۢmř8ű| źˇë@ÇŰaă·żŇ÷óĂ5yŰ|˛ŕŠNşvdJǰÄćV?žâ ěŔ ŹŔĹe•qľ;:•ßžC řZ(Ü©ö•ëdç?WŢqĽŔ3Y´=Ů«Şucß%|ˇw ’ÎIBMI?ö{pu}Ĺ=8»ox¦Eń1^™Ow6µ~Jm đ”ůylSB ~‡†Ž;íxő|E˛Î‘s]ČďćK^(¦łË9Ž–›ú±ÉŕşĚó[…ĺSu|Nçáúv﬷mŐ3`čkŮňďÄFťýJ~ˇµYú ¸y‹ĚŃÁY äś{‘ő)ҶăleL/Îw}îµ-ćę{€÷äŠ úŤˇł„G:źrXá3kŤ§çfoU,›7jN–k%çă˙Č_EĎ<ˇ¬ë<ĘA/ęáĎń˘ŢăĎćMŽźĺóßecY[—Bé×ä36Ú÷S2ž°÷Xáď:ĚÓL ľNű]ŰĎ&·AŔ8OYrtD|Vzą,QŹĐ'Ę·“äq¦?ËXŞ÷˝ţĹ\Óóú¤ëŻDĆŚţŔ-{áÔ‚&äđ4^%rAţĂ[űżˇ}WÎBlűÝt•ŮđČřčÔcš¸ž·Ľ[öľ÷®ĐbK~Çć}|¬ ˙ŇľŻ‡Ňý>ř"ţsdŹXNĽŰZýľĚW)l¦Űzđ»ëz —üßŰá ~Ž#4B(­݉ĺ§yX<đ-­Ł“?ç=÷ăcż!_RCŚżŹ~)Ó=>Vӹ𖾯ŞM<Ó‚>kÄ›ąc·ý†NĆV Qc–ä‘ýĂßÖü”–c")Őś;Úöţ“ä»÷ńÇá†ćëJ7Ë:ĺCĎą+ůŞc›?SşÚnĽokŮ]Ł}aĎLřd¸ÓÇ˝-®đ´]ł?>gNrW>Ž×ŮŇ}ľ˝ň>™Ó™•ó#şŃIŇÇ•·łýTaů5Ůń±#"Ľ&·vď8§éa8Űď­’˙ÚîŚv߼˙W+ŰäÁ¶WçČĺʸčýËu«ähç^(°×•scx¶ěëŽe¶2ň%µe.Ű" ˙đ“滜¦Ř¸nŁł­ÎU9bĐl i®^ÓŰţňQĺ©ë˛Zďů9ňsŚN]ť·g˛ç~y/ÇUü}Űé—3Ă{;7µ~$W>®»ßęm—=¦Í<9tŤřP2{÷SŐo‰I·ŘĚ{ĂËř!Iü…ĎÂŹp|왢ł2ÂŰ×E|ĽPÖs>˛¦pýHĺšÜDaą.ń2g5:őçk'†Î:ňśĚÖ–¦ĎŽńÇ.÷1_rŹ)Ή>i&žéşĚÎg)Ëś#ÝżîëůúşSöôŻÉÔ_çSI×’_Ő׌Ř5Řź­Ő‡ĂbŘ/g9ť˛¦î·fCqŻÎm-ŻŠp6?6¨×ayS%§I9Ő?[[ě7±é•¶ÄVЇÓzËyOŐţ/uĘüKýľµŢĂ$GÁS»VÖ>¨e͆<]s#QýäýĹűiźäŢ–´ärÇýR~¬ť˘őC÷/ßÝ{knUőµbo®ň](´‰ßwĎŽM— G<0˙pbÓ°>‹g. ÎnC ®řpĄŻŰą0Ľß^yJÜç2ďRÚńśłłD§,ŹťŠ›ZßÚmkކű¦Öçî‰ň Éů5Q./~łŹäˇ ]~ťźĆź ŘíÇ~C/3ÎRŞŢöBő™ňžÓ‚çř%dĎt¬×ÁóťôŃ>…}ÝZ}zwˇđ®¬ś˝Ô§ëŕ©K.X·%ď–ZŻž-N>Őz‘8J;oĂćFWĘü“ś'Ă|śz›Ü6ßIřj3Ä´¶HÜ<*†É™;śM’äýi4†ŠßUużů8~j1”łÍ>—5_^ ö¤ů6 Óó7Äň M<öŠ8-ăďŕz3ä~ç~¶ô=SŰtÚĂźS:\ÄÚTÖ‡˝wZá€s;|l…o—O|[m5ŢßÖrŚâ/Ńkî Šě‘¸ßě\Ś“ÖF§O˛qdxfŤä·3yäšřqĚ‹ôś2ídĚ™:B^'p»sŕÜî\#-“¶ď»­=Oˢ“gß—\ay•Řßg‰m}iś Ýy‡|06—¦-‡±PV%MfËý9‹?âŮ®ő‘Ľh /xŕb.Śl"“Ţ_݆6ČM>ŔMĆ‘mĹqý%‘ďšď+kďÎŢÚßşäăŃb) O\?Ł·Ň:Řđ"é$íż®łžžźˇ8Š-ŹË‹…ig–'W˛Ű‹âÇšS˙¸śG|Ţ™ŕíô¶ä.ÉÉ2Ď!v:Ë .S`™ËX¦Ŕ2–)°Le ,S`™rj §$߆ĚŹ›îy˘®]ýÉ!±_1qµú‹;ăĂĂg€AüşÖö·Ľ6žSŢĺ…·÷+í@#»Đ+ż_˝ű;Ë™‰ŠżűAŔß8njý\ßľ>ó‰ZÜ4ď¸?lBmNP<.Đ}Ŕţ೥ď߲řBłqż qw‹ď? ďINŤE!FfSëëŐG‚ŻLžďrţŹ#ä%`˝ˇ2ňţµ)_›€HŕË™ľŕgô0ľ˛Ög~2Ű+ľóëś7]śóµ€Zď'w)Ľ~9k[}\ć˙µ= đp|lE > Ρ㼋łňđű1ĄéÎLýwˇě9aĎ™úýě?[Ă™SĽvęĂč,kĺ›đ5ć ü¬·ő(_Z«eŤ!Â÷‹ŚÓw_®ŕJ߆n+k_QßůÖAÄúx¬×Đ{ü=nź´_Ót–bq'Š×)üîŰ%î‚5TŹűv=MßőňčvŮ_ ë[úş»VČţt€Ç“$ëŢÖλ:ľ¶Ömq=¦—‚ŕá–W)®ś×ň`Ű“â¸[wNr0 ‰śĂ[đ`mÖ×îé˙wô­ř›*Żý,sd‚~ďçÚkş”ŘÓŻŘGpDt‰ÇkŽŢîĘÚ± /řH\\·ëq[ŁG>uź|<¦ą>ëo^Ź\;©îfŢlq¬yż0˙pęÍ%˝MbŠťřN٧ź…Lż?Ü*ç´Ó<ürż5kqČđž#禗Ľż&q.ëłŃ`ŤÝű8uŤŹ}}§Řu.Łű ĺ‰űł˛–¨¸'}Đň†>¬±ůxfř$xňüˇuQ–g†[‚µ­7ÇlgݸXWúĹ’Ťaź×ü„¦źŕ!ş™?Ó+Äfîăěc0°;Ż}śMôĹ kYŕ®â;x#Śó ÖF'×ä“ó:“wš}g0b_z˝ěß<1Çú[zý‘Ůő¬Ż/ËăČiĚ9aăşím€>ČeŃ[ěY˛?˛Sň[tŇzı˘/ˇç)çĎšm”G‘­ăVÖÎÉţ•­+&>­Á4ľg0ŮúŁÉ«ÁČŘeç9Y )üKtď=µwĎl˝NcÖ•4‰˘†, 3é:›‰s{…ÜQÖÇQ÷9‹Gós‚ţÜ!}—w]żz˙ä6WÉ{ şÇr†ÉyARŽçüąĽ"&'ł1±÷Đa¬w»ž°¸ËŮď.ć»Ň;† ŘfZ»˙‚顸/+N˘§‡ôŮe˛1ß«˛áńˇč׍ôłŃ5ž ¨E¶%FŚséűFşn»_ Žé˛Ö߀ËŰptýuZáĂ’{Ăr@Yź3^řű\á WúëĺrfSŇÂöď:ŻU—‹\mĚ?Şď#˙ö›—>!Ç\Ěľą˝ăż-ćj0™=dő¸î‡ń±·(Ďiůş^ß'{dßľĆq"›~›ó‘lŹ–Őĺ´H~·öü9mŞuSâîŢÁ\KíµőřÍË%<±z÷żí{sűÁę&WÇH¶4}B Ëě62ő¶ś÷W‡‹ëŞę—$¶äiŰńŮAüÝßË™”Đ ů°í¤ě©Ĺ—tDgľIěĄŕ m•ďÓ<;¦´ľ vŠŐmmx. â™^Ą}x 3˛¶2r|Ş?“‹€¸’ôÇxg°ŮóöĘuYd×ëMĂŃUćYąt™áÓľó—rNŻ«í_N·=ż{ě ć?Ţ˝nlz[˛ghrŹ"ś•>q#Äčó…1›ľo0úĎFŻÓô{Č~ńîŤůŐÝ™S•nŚES$ń‡wŤľÔüL‘>×\żnËSő/ĆgĎ 6#vˇµ‘ŔĐ×á·+ţ_ĺŔ[)Ý÷kCń)ąŇôőˇĺ˛1Ť¸şéŰ[Ç|ZBỏ˙k·o’ۤ Ýîőcşď ç*ůÇź=|ÂTO~:d,›†M2»ćČDšöNŢ˝»·8Kć­—qÇ}émI¬hnCń•ržîmq‹3ÂsUŹpNeÚ–ĄĽŰ¦łaŰ‘ď3ĺ\Ü×ŕ38{źĂç–§đoíyO·äxŠűłëOĆÁ˙ř±CĐM2–uoíą1»íöp¦Ą&ńÜĎ‹őßŃĄ›Ct¤Ë“č?Ťďľ%Š ŰŇwLG~ŕ/´ bú2· »ż§ĺKÓď—łá?Şľ'đoł}vËĆwö}ôXťëŔç<ó>jv¶É»ůeËó 8ď(ű(ąĄúĎWZť“ŮOěÖ“#ýků›°ÝŇóŠĘȆHgÁđĚĆ ş„&’;duvóĚy2Ěč^zř‹-ĂŐ|1ŤđěČ·öĘŃBG›+Ă/ĘH ÁĹmú:ďx}ĹđDz?¤ {4®ĐćVaůíJ?ć]Ôéôů!Űđ¶ŐŽ˙'|­žłćşŚúÁdŔŢ;łµš˝`ú pU5®+=šă7ďßΧM"#†3|v“űNrăuní9&D˙Ł‘öOz{čŐĆ:ÍF†~'Ţ0ëŠtvŕ ´óz§“9şůoÇkţö'ć.žú˝ň†>PšľJeś~šĽ›äĽ˘ ¸¸śeż‰ú†orčAÍ÷ei›w©ŢBo8ýřÝúŃ ÷ŻHŢďδţBnó]Ö˝-‡˝†|â·ńľ źgă,ĽjŕďÓ\Ü ďč^*É9"}¶q>^ô÷0Ń×h‡çčýÇ@éŹ>®î7,¶çdMú0TűÉÝh|˘-Ç‘+{gŕđ2íťć5eůF~§ă_P®µúĺ,udÂWŃb3ö?-7&ľ_· ËgÚë?Ăg}§/2ŕýŠ1yN·Ç$ßîëwٵîĆ}ĂŕëżC'Ů,ë6u݇é4ŕšĆ[rfÝfáJżCŃŻ‘? ńiäŻăk¦xq\ÁŰęKŔ„˙<ŁĽ·ÉŐ鿇ÁÓç«Ô»{;iÝ|ť´ }ĺyʇźĚmŔ“weäŰecžüÉř9Îa©®W7krČ'÷ŕ n’»Sö.¬Ń÷©™ŕ96;řóľŻű¤i€Í•©ż]ěSóËmkYˇcv˙BîlíĐűŹŐ ľ­fx„í|ŘŕŔĘ3ţÎąd7ö`ČţÉg+.Ŕ*¶—ę›WÖ ~”—ü¦ěCé”ý‰!2Á>čČ»® Ľ/Ńü, ĆĎ» g—9ýş“ɡtćQŮ#cöˇŽ‡:s=,k+]ŕ ĽŚ·˛N'9@*y9?.8 ľÇćţJuß·ô]¬shř(ö¸ň§<ń[]ă˘ę*OTrüÎűţ‡OUŰ–¶¨‡:Ú+ďP{m›Řę™/Hţ‚=ô;¶˛®ľç:K%Q]Zá"ţ#Üőq?hk~ß„ţĐ~‹ŕBŰĽC[{ľźábĽ‚÷‹Ď¬˝˛WVdSsŮđÜx…Ďŕ ĺ+u`s™m–řťźŚŢ>q+ţ|HÎ*ę±~ĺgĂ>yc<{Oś+:±©şpFUkős2ţZĘ–¶ßéżÂKÝ[Í¤Ż„čú+ňlm<ľ`şGć3Ž÷h.ŢÎnDťéůXW®ŕę~zN_—~ś˛w|f?7ÄZiüťE,‰ĎŤŔ×ýŹ. Ţżů=6č™­GDzŘÁüżá˙`ěgL4zÚ5ű܇ÍÎcÖś&®Ě{˝uňŃpź¶_yľ^0ýR}Ďü˘ë¤mדĽ“¶OřÎfőxíÍąš~hä íч]Ż"ŘŘÝäjĄ?ňŽý‘ßÎ0Nōs%’÷eţtżčűă:XŰöçćŁŃ3’rngň›÷+oŁ9Řz-¦g&‡ľ«pJlŹ^}ÜFţ]Đ/»ĘÚĺŁŮË/?ě8ÖqYçą Ę<2*ţśśőQÎż8>·ż¬÷‘kë^áóTߎçđ3éÇN»íŻď žż8›K{Ťô‰ó"‘?ç\µ?®^"ľÎGr+ęĂěĹWZń†ä\ďťzZ¶PîfŤţHŮ3Ť7^\m ŘlĚß­ĺëm‡JüŘLWŁśű[Íşźmě¸\ůUš~Ryjiˇ­’äؾńVŠ˙)sĂł’sLüZĘ:Ěí’§bĽKdYy{GßĎs­U|Fäs}AČď>8ž±^Ç•O­·¨cµÉş=kţ˙&W&Ď´˙¦g´µˇXVZĂDW d‚x.Űßzr4>Yě}}Pí$·ÉGş†g6)>’‹¶Cb%×Ç·Őż;:ő٬ä.çQŮŚío—üîYlłÇš6gäĎçpÔ=:ő‘ËkObýŇíŤNýţČňÄk7µ®W<Ĺöęt9´1FňÎŚĂŇ'$?ä×r™zAxźćř(†»Ő^ąVq= ąősއďW·ą›ľ„ -GaH·ß¬űłĎţKŐÁ¬«Ł“Ĺ÷ĄxδĽJm'“ű ČÔ“s§Ľmɱzľ pőĽ¸ŕẏwוžŐUš~iśÓÚ˻΀nĐŚ±‚?ě†Í‘|$ď6ďîvŤµ6ůg×ŮŔĂa¶`śz˙1]ő¶'ĹëŇďşö©żCří>ž HôqŰ@ş[0—› r3ÝN_ěŮsµ±ý3Ăřn·E’w_ˇ˛&vdG1|~ÎćIÎHŢ“|žš«zŔĂe„ßdmBrîś"2dmÁ[ú-y+dü‹tç¤ÄŇ~$IŽśĚ/&»šO›{·%'M¤ł:9źfŰ_>'‘u •ë+&^çrO·ă~ ž…ĺź.Y?ž›Šć{Vř¸Ąos7üöľFÉŰ r žČDÚ>NdĂčÁ;G—¦;d®¨e6ćĆ—Źýŕ.?7LKűźpÔŰN’őâżz[ţt)÷´^o»^ů,ńęç¶ç'g¶dÂl7?KaUµżSôbČ9ť&3É{Ô±Đ5¸&QDń^· ŔĹä7ia.¸ˇăžă^(Ľ!’Ó˙ұ`[KMű­Űňî7lŽ_3m!w‰_.€ËüVV“Ř™wż%Ő§ťÁ'pr¸íe»©ÝÂ< đśzmŹŰR—9¦ô^•oĆ0÷Ů ‡Îóń±]S694â×Ń>bëĆô ú9sVĘ22vK>®śĚŤc›ÓKď WÉèx§u 8Ŕpw?ĄŔşŢÎ×2ź*~pgř,óĐ,ĺv9ž]ÓóZŕ÷ĽřË÷‰ËŘł]é[Óp_đ|wX}Ż/ßÝOo±Ęĺ βL>¬_ť4đWę?‚.ćCJ~ĽîN-®ÎąoM#Žß}š[ú~ĹZ:1źYŹC Ż r€.ŁŕŰG·!#™ú÷ǰ|®”[#{’Č·nůlqó‡?^ز'ňŃ˝Ć+÷Ăű÷ä›g^§1˝č*ňÖä^Ü ß|Í0˛Nľ_›ĽŁowŐŰrž€Ň*±5Ô‹őńĂzp=şČĺwJřŕ¸Özm->”}~éuD˙ťó'ˇ|f €çÔĂ=x“ż`¦Ą;>뉩u:0MúĂÎĆř6ć9ĂŔ>ȦéWŐŬGĘYżŤĎŢ‹ňĆ(M( o‘ebŃ]Č9ý‚Ř×iRóáÔ^(”×wô˝Gu:x˙m-ď¬˙míAÎôVXhUúźúçÁ%[¶5q`794:Źŕ/ď!ŰĐJŠëÚ4°ďűN˝™úş| Űb‡ŚĎ¬˙ĐźäĚń˝G™fAľ]ÚsřŁÖű?Y‰ß«ýż +#'HÜémşź•uxŠüň>kn|÷˛ľÎČw?c{äÜ%Ś,–ŁĂŮđńîž{î‘qré>éCp8qŕ1\›Z9Ŕ?8ŹżˇăŤóŢq癯e}l˝Îe\ö„Fń%V'1+Č„—Ż·M-Ż}­ĐŰl-‡Ó±e\fLqžÂ3đ´¸`Űëö´X|…Ëö ¬Őí—;=żRεú~LĎŃ©>ô„žˇkv ńţY9—c)> Ľđ<ś?­Ő¶ÖČż{ě<ř!ÇégŹůfţś÷_–˙5‹AúŰOT˝ŃYšÖó°ä,Ťĺ‡VČ}ÁhŘ\ś'†ţQu”őˇ ÜăS9ú2űFŇ-}ĺŔOę^ äXlźNB+p7{EęĐqÖôx3>C+ŁŁśő-ř‚wşţ+äÜQ{–Ôé2s‡äMż»ř{kĂsóŃNÂG«}Sëu,Iúš=Fô´ĂÖČ·E­~—óBażn⡡…ě§S>WFR( Ű{I݋ǔ|OŃtĎľ©ł©’žÉˇ©śÄg†­ď[©˛@™Báʜ拏:$‡}‰­áý•wř´WnĚ%gÜn§˙ËYv3(ĺDn`SëÍ‚·ĺŁóx ÇÓho4óĘ,ćśzývőÚ¬ľUűźŻĽ°Ü^AđÉ-Âsö̸.cţLyä@âWU'yŚXB‹Áő’0'vşÄö~8ç9¨+™Z»čĘF¸xxˇź™–ďFĽłúÜÖ‚‡ĹĐd®ŢÖ5ľć(Ĺ{CöéýWuNě-› ÓWe~ŰĘąf+ł§ȉ`s2‡ßě;ĂŢKűµć$®÷wń>>·ŮíjsqwˇWp†4¶ŞäŘŇ÷Źq>Ť[úß$¸BűČU9‰ĺ—8‰)kb˙·ňEÎUUźŽ˝pŔžCb"3ő/ë;'Ę9’ÔF̶śe¸öśĚkôś7dĎă•\8\Qó‹¸,nݶ‡Ug {śnDÎKTXÝ®@ľ}¬ý«ô^h±®dgâ¶E9I[˝vä09ËěhÉÍr§âOý«ŞRąH÷ićĄŢőąŢOĂ3ż{“iębśBŹÎEĎwfľßŃZÝMđřRNbĘ…żßUśÁ•3ŘlŽô79;0Ç9eI]f‡$ą0‚`˙ÚEa:ľDl•©ěŻź×=›&'Ť1´óĂ3yŰÁűpźčň©.É…óů,z%,óa¦%źŤćő± ˛1żW7úĽźQŇú{’ßŘ«aăvň{ún¦ĺŞ+äÜh9«ďL•3đe_%ďąľ”ßcŇĺwäž1†=©Ž/uĘ޸¬Ďqśé<[ä bÎăżąl€łÉ ńŰmwöníi×ý±ŢŽŹrv¶âĺ°şťB=ć7´_d^Ł8zß^ĚĽĂć©f+óđĚrfćCRżÁÍąÖ*ß“ĎŐc§i†´ úŮ^śť3QÎn×e¦3“úěÎűFr…Č×éĺg—śßwG|Ţćuse|p»y`üEÉ>Fíwđťźč.ŁKúŚ`ÉÇĄ2A}ĽK;ä-­Fç˝ëäФę§źŹO‹ŤmF·˙/R?ěü0M޶şw˝ŤŮWä‰vĹu ĺße±± vŐíbsě'ůNl˙ü'ŢGž$ŽYé¶ęĆw¨žć7čę´÷=ňéz]fco­®oč >;~–żÜ°_ʶ ©ëŚdě°:óOWŢ  Ŕxü]3<'»ĂÍ{Čƶ–ÄW ąÄBĘŇç)í1ľď&>ř ˘ŘPÍU˛1Ń‚qö=šWú O™SűĽxĺě°ôú™ěLË3ĹźQĽďőO—•Ü;9ç´_ęÇiN´W†»L×›­ť®é˛ĚsĘ»Ę=ŘVŃKŰť}†ňčWV{š{hř‘—Í3-ˇŰżÔá~4ŮŹ”=;ó.ˇi˛×ťzđ«Qďb>á׋ÚÎ܆cź(tű^¸śÁ+äąt}tÝĐó:ś/î/2űÍ ’śJĘÇt ,uP÷-ý—鼓¶]®°ďgZŢ™“\˝2ŻÎâ_˘<2ncŕb0‚ěS‰ĺv­ďßÝh`2ćxÓ8˘ż7ćs!W÷Yýňž{d>>€ýc¸=5§ôy´A¶ůŽ^Wi“9Îäy‚­_#˛ďVżżYsČĐĘÂ?ĎĽů8µ ÷«őĆ}łŢf{ÍÉúq˛_”–śgS2gBŢś6č˘j˙ßl źřwđô_o±ÍC·IĽ®r^:óS•;dĆőˇ˝ă5,öją…Ľ]ŕńů$ĎA˙ÍÇTđFď¦q6ŘaIó™ń›2™ű»Ço•˝íßËúÜ"ŤOů¸Ď«ý#9ałF_“űďŞĚ4ÖżĐo˛¶ŞşÂńRŁ:ËäšçČň Ž“C+¦´7 łĂQé‰l·¤p ~ÇŰ´9Ł?MÚó¶ý—f]3őáČ‘Ŕć°°•ôe˙ÝZ6Ř“g¬{H.€0,×UľeěŐţ⺉:M.ČŤđÖČżč.oÓcŻ·ířmŰuGóůć`î2†ý$ň·>˝ž€l{żc5ą÷vĺÜËKΓÖęmqL†ż!yÎş]ĆŃĄé)Î5ę¨ĘWzĆX•¦‘ÓÁu«×ŮŚ«é*ÎÁŘ=Öą+ęoĽă×wů\Z0ď˙zŰP×Öž?—=eĎ‹ßwÝ–†'?đÝGÉ™&äp´ßţ˝«˝bgKÔĎŐ/iaý‡RČSł?.ŁčÍ+6â>ĽŁłżăOŕRľŰÇĚZďSs˛7_íŽ-}wdŻ8BűóĆ<űůÜëJ'ĆőĘžh™[­Ń÷Ž)˝^źO÷”$Ç͡úLu‹ĐÁËZ=Íűßű-üş`úÂPÎč m\ÜľŤ°ü‰n~ÝÔşWVüiŠ/ß±iĐŃ“C›MŹ ľípÉ•Ż÷Ąé ZgçÍ ŘŇ÷­kÓoOŠÇËj˙«ĺ]ł=Íźhď6˙‹GÜżöwşç:ÄĆ*kÍĎŰ’q$ηAţ ńD482Í%(¸Ä±FV6,ż&¦ÉlŘ%ĎĽú h‹żŇô‹T6{Żov™f|7Ü|>asě úqZ¶d® |şüČŮmJ^ĺŤÉK ¶ĽĆ¶™îůŞä—cś7×ë{R‡÷›ÄKJşÝäÝćßąťoí,ŕ Íe]Oä滋Iʤ` ­ď_ű`G{eµĆDP†wÓ¶“÷™ŮĘşU×…ÓgwTűá©ĺ6ůŤĚIŇzŰs\Î.ŰĚďîßMă‹-l߉oj Ż[Ó!ăkĚ3oßÖ‡ŤF>7ü¬É‰Ú‘’2·ş2Ň!sÖ¸?‹Ľ« —'ľťµ9ŠäÍ•±ÁüĺŚ#OŤű¸·Óě+tv|ÓcĺşŇC9‰?oh_úv„·á)8«Ť ľĚ‡€Íe†ą„ä@ÍĘ:¦ęń±>ĺ­·Eś–ݩ٫™[ĄçgÍĆsv}’CDáMtůQŢ%8[ÎF‡sXrżS6-‹ü†\ř3ĆÚ­=ďď.Oü‹¬·NŻ•3!$dň_˛>˙ô÷(—ôŁá#-kTfĂ·ß->wćřÁ‘3ٶř[`Łż2G;&â»Écćt cyâs <ö~`ďą-:»ÔÎúnô†WČ­űőŚĎC{ĺńěřyeěŽňâ%yzÄÎX–÷ëš*IěłĹ7pţôCţɉM<čäĐWúĎÎÂÔŰń/›?úą+"«˙0KćË\%‰ŃyMxgxoíůvŚ ľ7ćÇô[—qoóSß‹ßóg;űęö˙ĆüWTG§ŚóëŢĄľ]ÖŮÎR]†ýf~ÁőčBäť`ţż/JްѸ/¨AôłÓ ĽîčűAm·łqť»=ł€›Űg_1»:ź3 FS}–1ÇěN‘eŐíĐb±çőĚ csźţ˛íůą´žuÝçăř¬¬ťLnOĹ™y'¶ ĐĘćo~ćfsá[ęÚŚŹí‘«·íźó1Ľ C˝m]w1|­Úˇ|‡§®Ó‘éS‹?śĄ–ÚćÖ/:¸k|¬n¸˙ŕ,}ßĺťV†g>«±4'Ü+¶öďd.>*çÎ]ý¸ë¨ćR`ą¶e ,S`™ËX¦Ŕ2–)°Le ,S`™Ël;˛[|e:gȰ§Řcnşé¦¦®™?vKÍ˙…8üířżX‹˛ÔŻx«řGÄźé1 \)wđˇOOĹWřŰ»ćŐÖEŐ·ůď8Ĺź«ĽvüXłň˝tÇŔ™÷‡röąîŁÂg’”ŢőîĆÇ,Ďú­‘Ż’xŔ[bż%ńˇ•.ü·Ä»ąo5'|ăľŢ)kUńľ"÷óÍ$glěJăÓrIÜĽc‹áđ ży\>@Ą…Ć Á =ű(‰ĄIâ(v lŃ9Äk‚«űđÜo‰ľrćęĘ„â˙ÖX.xGeťü-†Ňđ‘ó_â5=äuÝń±ßĚ#öxP Ú_‰×%ĽO‚'ĽôţĘw9C}zĐ‚u|ÁrŐxzüˇĐ€5JŁ•ůôÁţN÷üL×ř¨‡ďcúxŕ+|Rý‹N†Wé\IŹAćç™ý–?âu}Íž{żĺťĘČ_*žČ>rÂ~bĘ´Vż {čÁßú˙ÎĆÜsĆűÚ”­C™ĎŢ`‘Ř®.ú±ó†ő6ŕ5˙ţŕúźÉo|Opcż:oŞďuŠ3{řÝ1ó<[öLřľÄ9:Ľ]®ÄÂAgÁG×X€YEfY7ßôü§Äţi÷á#·ěó_ôWŢ÷=ˇüžŚăIkđź¶,6ŽçF[ÖąvćyśmD۬ż9]ňĹdG§ö—˝…ŃQo»G÷e€›Éˇ­Ĺřšłëbö[°†kcsrV|1śPşť“yaÔź€ţŕëBč?Űă”Đg©î|ýÔlŁąÓž6G§níZQ'Ç›ź_ĚÝöďŐz÷ÎÁ'ęńómY›lŻüt-/{5ľJâî4¶ú+0řHÝí4˙ăk®i »·żˇXÍŽ˙ü§]™ęţPú)1‘Č;eţ]Ömî­łÎÜCŹ3'±E’ĺĘۉˇ™8ŽĆ±áĽ\äÝb·ŕÚ‘§ęŘńq±müťć^]o™m<şŚž“ů€®©méŰ]âR‘up–}‘jC:ťŕ 8˙4Ň_”‡nŘl~Îő 7Ć2˝­ĺýťĂ3?׫4>6¶Ąe(ýëâď3ő˝ş±9Ľ?!gĂE —LMvÜÝű µ)l|f îyÇÖ™s .‹rZl%ćę…áĘÚ±á1’¦˝ňźťŁS›ł–#Ťgú~ńx6Öŕc˘ĹüÜf'śV¸/¶‘ĺ<˝.bJŐ¤Ľť?ŽmJ˙Ĺ.±ßľ”ĺlE_§Mă=<ó˛x-vEýľN‘ů,±QČż€ú¸ÚěI«‹ą[WZÍ{-Ęu5mӶö–ó%ýCŞk%Ż9*$ö÷•߂ڀ7ĺ$>7ÜP$EÂ'ú‚ŰŕŻŰ+Şň’~ź{tLZţĽÜâŻWăYöAđEťFcěM qěµgĚN·ŤŢńqkă·ž“łŻ#›Ăęű®Äz??ć/4@VÔWĺŠáŮK’:b›Ŕń‡–nëßč1Âé†çy/g Ş^¤˙z\ŻQ|9çřĐX®©úîŢ·IüŔ‡•żČ÷ůÓäQ{†ňßőťŤďŹ×Ôé4’üq^â‡xSÎdÓväśĐăă)“îśC}jńÝúľŐľ°˙}ďç})žI‡JěKç#®Ş>]á:OÎľ->&x~#—ř{ĺ۰ä~„ČĽC’Ä’ÁĆü{ÖöĘÁŮÓó­çĂě\Ö˝ň'ßš“żč!‰űk©˙0í©śT¦;’ÁuĄŹÇ˛âmÍďšô7tńá2§g|¤OwTFÖĘX,i˝*r^űł:οܕÎ31<óśčÜn±?ň“@GŮS¦gšĂ+`Ć.ö¤ ÓôS٧ťmk•¦ÚLÖ·(eůɸ›Ť<_čÇôµË]R‹ťu+ůwTn`ďPÎĐlčÓĽk{“­”Ď/™wl(~QčqsÖ÷±Č¬r–ćžČŹö×>Ż2CNĚĚwdßčÉqÝëJĎ–˝OÎmé;^ƲŹăGęšşŘŘ®ďD1: ś ął˝‚Ŕ›čW™©őţHuŤ÷Oč ¬ÉůEđ!VWľ"11gKÜĐ‹žŤŤÂ;đĐ÷SŽď·ö_&{nĎU|y/?°[÷şŇ§#ZÁWG¦:F§éÜÚó Íő Ͱ{&‡ÚăwhĎdĹÚćű">Ş»ŘGĂÉ«ŞýxĄNoíŢçÖ˛9Ór^.íKpĽ‘ećdĆSŰ;Ě3Éxj¤‡›[‘˙ۧuZڶŮÔézÚç&Ŕ :[űú\{ő揿ÉwŁî”Ž/ö•ń/©?ϱż°5éÇđŐůťľ2ÎS=śŘ—JltQÄ~Ź.×S6ľÓ¶}\ďSXŚŽ‹ăµĺ_ĄŁ1m€CâĎ4»’y2öŻŮŔ˛WřGOĐ~ŔśŘňňX+ř3®˘ŁDŽsľ ś=FTÎvÖ>,xgsëäŚEćdŔ‚]ľđÝÇ~ă·´Đ«Á‹ŤŻązźLç†bNŢôV¦{ţ<çök~ŕ°Ţö7’{9źł=ÚÉcϹƛµŢ}ăł Ý˙ŕ˛Ĺ‰\ «‘+h8[×;<óą:˝-äýĺ}Ęä+dÝjŢ˙x'Ľ6ŽsÚ®,ý÷g´ĎL˝Ôw‘Đ“şKÓ­ú›ěcŹć’’wBÇ(ÚtyvxŇW‘‰čÜ»ů`Řř®ĎŤ˝^ŕn”ˇ$VÓú;űążÔµĺg'«ý źyŽ®qś=g g "ăŕË2Âűř{EßÇsghF_ň9ťĂ•zůÝäËě˛öĘÚŻ1™Ď7“k·ő­¤=Kt&OMĎÉľŔN±%tlőVŔśßčŐÄ—eúşđŢĘÚ—sL˙HË×Ű^ŹÉާËßá)×Hß+ ’˙¦Ű|8ŢúüŻž˙*McxB[´Oň>mýÍÚË_>˙XÎ*˙Vc;z ĽĽ¬CÂwhç8űs®™)ŻëmźÉ¦ýŤöŽŃ=+Ů bôI×4żűĽĺµęcv­>kĎďlŞŤů rWČŘ2»`NĎAŃ3.'\ˇ }ŮËIž·ÎőCĂ^Öz/׾L{űKž-oŮĂ×Äř$űŞsçdčó|€oáźłWŮY^lĘöËY˝2ź />ú«ŹÚá`\ţJÎťa9›úÉKmyŃgČ.}Ů®·˝‚łŘŐÎDćůÍŰýŃ]ä“â»čÂ,¶Śó3źô úÚź;ýŻkáWčvBě×b/[˝­Cĺ ŢzOí•[˛+ĺLŃO1ŻežŃLĚŁ—XłĂÇ ®<»qhßwĄé„VâOx‰ŕ|kvrčgŠ»Ëz=’®iŰő,}Ëmú…ăę%mOč¶h˙ÜLËoRz1‘súdiÚÖ]ŕkOéő1ŢN‰_—yÁ/˛–{ßëOÎv‡ß+ęeĹ3˝WŢ÷ ÂWÚń’Ă3—eť.îW¦%Ďb$Ű>f¦űd˝íG ;ňî8“Ł($‡‡^ąw‹wŔ‡~š8Jű&ňB†§Ńü%Ç~6[ţ€îG.OüßNj]ÜçÁ6ęôúŇ× (>e(‡˙Úűň•8#Ň%Ön2żlXźY]yĘśň"{%Źë}1MČę8S?ţ9ŮĂ 0ą­@nţ¬ź-_JĎ”s:6WeäýąÖ˝Ö6ŕÄ;Ţ6´‘|µ ď–>;ײ4Ź˝<ýĂË5ϹꚍŻó|Kß1˛Ţ¸—ś·Ä}=]^`U]Ź}>—•uZł˝­Ä¦Ö]»yćUť«+ďeÝuóo;ňźÓ±>ÝNłďWÖ^’ĂÖÖ\=%íĎܧ®•|JĎ”µ†‹ĺě®sTžÁŤą‰ó¸]^Üľ8#,ËÜüAí»[úľ"óďŻ)í¤o¬}uţď:ÇĆÖD´´>%znÉdz6ÝÖ•Ţ‹®UąÚŢĆ5xčßâ[ú·çWµß Ç p;ÄĺóŽľKců@ßM÷ü@âjĚÖz{˛¬Éˇ+©×ŕ}şd±3ł1&÷€ĺJBŻG™7^XšîLě!ĂŤç¶Ž•äuYvŮFÉůL:^ÝÝëą%Í®3[šąçy҆Ě_Ćóň¶ľG ;óckźäf>yşřqLŹ%±'@sZá§ŃŘ*Ľ1Á7)öV¤úôţÝĆ@tśŰôĐżŮń;; k‰űSÚ;Ý^ěrĆp÷+TFÎěČäu^ŕďâ€ęŢw~zÖ_®—žŮ·{Eýc;­ĎEËŤůë™EŔ?Ě·l㦬Ceż0¶&ŻÁ }őĺ(‡Ź±ô7…ŰZěl$äÝÇcęöţ/yâúć‚gg=[Qďl8CsőŠ~öx!ăQ”¦/TýŤľg¬rś •Ř2Ń9Q@mtK.=vË|äqĺďcŃ“*ß“\ެSŔSç;şmrčů„8'3k¬Ľă>Lx‰>@ŕłő ÉÍÔog&?V›Ź÷óÓ ‰)ą_ő¸ŻoĐ7ťçĚ GË3k±Ţá±őmʉ9/ž<޸ý±öWU_÷;·«MĆ]'˙„ŹËżŰŐǢfćÝýc°.ŐďŮň»´/îěÓ`'ŇŞý?‘ó°ďÎĘ:ŤÄnpŰňg™ËX¦Ŕ2–)°Le ,S`™ËX¦Ŕ2–)@ŚŔIą»{WČZńŮ{^´ĺ1bJţô)•-_«ţ/üŘîűâĘ:ĆÝWł†cÖB.•y4~!öśŕG˝G ólwW˝~ţŞ«ÖŕX‹ŔŹçk¬×şoäçÇ~\×#<–„řčÁŢn÷ĺ4&mWĹÔá˛5)đÂ÷ĹĽáŔ;ć‚Ä’řZ{y¶µ§KĎŔŕMâÝńţJăy˛k}ÜçE\ktřůđŰăŰw1ţLü›Č;ż ŇgžŃ÷÷ťĎN#®w,úlĐćŃĚűŞÇľPłç¤g[‡ Yk‹|]_Ď:´ÇýÔŰjrŢęob_}ľł‰Ń‚çřĆ›ůük^¨ě&Ľh¬Ch |d=QâMdŹáőěĘÉľŤyßŕ\ž8h;}ťŔq¶°^ŕĎ[Ű9ßXgň59Z$–íŤaą!ÖĺÁ¶WČľŘĂ"ţădńk\á%¸ÁCĘ[˙‚+&l˝Ţ×8‘ógU”8“O©ď”˛śqO™ťůÁŤŢˇ}‹ r?u#+kźî ŚřŹ™xĽ9Ú÷Očú=9JÓ=ęŻös®ą­MJyĹQößtą˙˙Şh|hlqiľ _T¦-†VňĐ>ľÎâ-J|E'g ŚNMę>WŮK#g˛qnđ ®i ăč›ŕ*±˙ňo˙çÄĎ|„łÉ:¤oŻ]WşUß·> Mí#űKă5_¶ÔWÖ fǦ۬ŚÜ´vř¬DĆ'‡®Ń‘ÝxOxČw=S:@?örűů*Ô'1qÂoű*#vîŠě9n8Ĺc'Óí7ű>ˇąË˛]‡fŽ‘3®ďR™ýĹű IĽßůYx ě>žqŹlK]ěQ=%ńÚQ_5%&Łc|Śs!g`ť¶Cő14ŢĎďYńµŻfăéő dʢ_EL}2'çPK|Đ>Ý´/pź©“ó.ůdę?Ś×«xęăĺůcýnCńÇŮKe,C÷;č4Ć9ß»BŮ Ĺ˝:7Ľh<>˙Kâ:r‰î´xSŢ[ŠO2vĽŐzß㹪şźŹ­k%ţ@á«öď‘ÚľÝK÷ę+|ĹA˙y®5Ź+‰~—=Łg*o3ő7DcŔčQµŢ“:$6?¦Łë1Ę 3\—gŻße›acŢÎc*žŰ)ç·kĽc1\ĂVżrCĽöč1pÔC>Ć&ěÉ…żcň°=ô§>Őirb8Ú=úĹôéöĺó„±”v°ą¦y.gNĹüŢÚcĽXWúgĺ;±5[ú>˘}" 'ą+Z«ßT˝ĚsÎń¸)úKˇđ÷ ýŰ`Oó4ÁÝynü^ –ŤeÝ6Ć$^ ý¬GŔŰËĺgt±ň˛FyčşĆěPáłŕ|íČŰbZř¸çu2–Ëú­Ä3ĘÄźvδk`{’q1ÁŰőZ#Ô‹ůćuQżá»}h?‰Qc~đ&ćEQÜĽżeW—`_WzA÷ÄĐÓç´>âĂÉĘH2•ˇŤůokÎ{j±Ĺ~O}ŘąFW{ş˙ݦöń†úé—¶wÝj–¸ő{ó걟gWÔ ą ĹNÄĺ×!ggJ´˛Ř¬ Lšc >Yö‹ŘvZ'¸°ŹPňŠĹ1źÔ§eĂĺÇÎŤKj_ř]ăx_ …Šxv¬«Ľn‰‰Ě2—ZUý°î•Ű,ă¶ť+‰Ý̸¬›ZoŚôĽŐŤ­áup]YëUzß%OŹŇ`ue•Ę8ĎÁ“ľvG_KÜGxľX›»\‡9 Ŕ‘ţ”'ŽčxůŽbxIöAáA1ĽYΖ{–śß|ĄÂ.8tĄűá)ĹśmN Źá§č‰†™úť’cč\±>×-ů¸”>Cg­}këÉń8˝áţ=âs˛LvŚMĐá©><¸žý™L÷H>‘۲đ›|2†űýťWLlU^Đć„Ř›<ź=˙AŹ3AKâŞĚKS/nýĆ“ZďUÚ—ő׺Ön »î5ÚŢşŇJŮo¶JôŰső©GÇ˝fč2`b,?ô ÷ŢwŚç¦ßÎl˝Qâo_óiUők ›Ä%«,J rü›ě7=/ŚâÝb|•F–Ť=Ŕ×é÷•µgĺnčżLÇýM‡=CVl—Ódś·ťß·á™CfkOĆR·ź mˇ%§ŚÂJ%ĆskĎ[˘ţ™´Cô»ď×a_ ńCĽqĹúzPü "9 ‚tßp8üŠ® \ňßţ7lţŔ5±őlŢ‹<™Śę!ó‰ ™:$wőš»TîlOˇď˝gľÔ˘xl(nĚÉ™Ęzď~)*űoV|Ó»l%˛ëy´dŻQ*ľŮi.;ß{ŹŐKę2Y¶ď‰,Ńźč§ČC˝í”żŔ)ą‘şń]“oÍóNGűG˘:Ô§˝1˙ěnĆ@rązÝ«÷)ě"ß{27<6&ů!Ľ†ů]}>äv‡ś¨|‘="ĂŤ¶ 2€lµVČ®®°˙ß\âż\ýd.¨2Řßz˛Ň}Ç‹üDŚ ŕĹ<[ň–Č~÷ŹwBËj˙Ďfžśćçcé•„óĂ3ý6űlđ¤ç+k7äč?ľ„v|Ţ!ů„eŹU%¶főĎ»lŇO¨kóL‹Đě•}ĘbĂB/Éá$g¨ž$ů±n–q`(Ş'-[vO}i»ÎqővŇ8Ě˙>ńŃ{˝V‡µ NÉsžŮŹä§ ±­ŔĹu ř¬Ö=ö•>Á^"ćYÔđĆđpŐŐĄé˝E®ż!sąt{µŢ[e 8Cr‘‘G M›] ŹŇôA9ÁCĺú´Â'É/:ȧó|Cń úŽä°ë,O|]rĎNęşďş]ív±äÖG—ëřO‚Ĺ0—űn˙7„żvJ>„5˛ç;ŇýŤçÍz]†§#fąbźůoóąZńF¦é9¨ąŤ|Ü’˝B Łř˛cůz©ýâşAdCń”ÍÂ}L–č/ř~ÄG"¶Í Ú[[új’×ć\ĺ5´Ą0~Đźťç˛78gú& ×|pśý.ľ }ulĹV†_¬»ÁäÖd1iëÄŰ"ľX=śliľ «$ď_Ž˝+č=t9<ŕ?:‹’˛×5¶1­¦ôľłŃmL>!˘›˝ĺ樂Í÷ţôëNV™,†ß”ĽWf÷®+˝\uŹ×ĺó!h˝­ĄÖ)±Éđ)Üżv»ę]“e›3?­·/62cÓŤń9 î“Ŕ;VíŘŰŽčş`úÝ;Nđy»Ů] yą’q¡[č>ÚX·ńccţ "[żµçx±?OŤüžĄébhyć]Ú×:©ć”Oř'ô˘ä«Ôç˛vˇ¸'%Gs§Oěöőäě’·cEýaµ˙¨9NňţBďlO 2č}qc~<ű`ŰsTŽ™1F¸\¦[±g Îâ3m}—ńŮqF6-µč9ú]ťä6Ý˙śčŃ_ŲĚĺ·ô˝Nö˙YĽ˙Ç|:^ó®Ć`˝¬…ŘT×-}ĎÔvŰ+×é5,żP`;¸sŞ//yNß ąÖý}ł)ŘSy˘ň$?đ1‰ĎďUxÎKŢĹ&ŇŇ{ŹQoĚ_ÔµO˝Mđ~ö©m-wÄůBMŹQg7ů‹ŕoxětr^%WĆSÉíÉţ' ľ7(›ZŹVxM­Ěţđ‡ăۢsNÄ˙§zQd…3Üł>ÖłŮŢn?µ®ÉˇôgŰ+é¶:›Ý^y[ SRËüîŠáť¬± ýLĆ˝ôi…çÎŞ{oĺCyâ¦X~ÓsĘ•¦ź«ň09t|wˇ°Jńćą­Ám(ĂŢŇj˙=˛×ű¬x4ď5~ě}`c4}Ćłf}¬~đŢ*çtśžżAń•ýťŹ´Ľ*–5Ćłt‹n™S‘…Źď%bťâźâg<·?{‹˙ĹWŇ Ç2oÖ±eÍúĽŹÓڬ$%{g<óuĺAţŕĎu}uä©GÉąG‰}¤vsĺ•ßŃßEpfžP뽩›+ß[«‡*M¨GtÚZÉÓ«y:¶ötÇ<ć7>ÉYć&Ňľ=”üýĎŽű…=[ü˙Ďşů¸ŘçéţdŕőűŐ•+Üăcďé(O¬yŕ• 7-ź8đ5‘űwE<˛u.˙ŕ3ďLNŤfĎÉ<<‹Źü’óSq÷,ôĺŃ+K'×Ö68ň‡-`ö@ň J޸đ× |‘łÖŽ˝¬ýšśĎŔ Ü®üĚŁCÄoî-Iţ鸜?k­>źß…/’9,>Ö3Â×ĆĺüÝf]Ź)=[ëvŢ‚?tţq´˙×ÚŮă-ů“ć„Č%°ú\šňŕďöĺĂň›·ÓSkµ_Ö®F˛>îcËČzh4ľű[ÍżZ~ ß§lő‡ĺd˙6Ľ7Ćuxć®Yp›|ŔWďŹčsú3ô㻑ÚNĎ{îŠóĺĚ—•uć1ĐÇä$ű®ůř=vŤ¦?|ý€÷ĆÇ6Eň~ö‘9§¤kUř€Ű˙Ö•”?Ě=Ügľ­ĺ¤ÜÖëoő=µÜ*9űËgéeŽłČ†Ň jf']lŚ®·%yŔÚ›?é‘–c˛2§X3>Vë4Ýžř†é‡é9ÚtĎ)˛&w]ö‘–—Ųm’>DĽhFiT ;ĺę´ŰIčĆÍ0^-ă·źřo|ŽÇ«˛Váa6vĘVTž#ë&ďäzą\ňzĽY϶ˇ^d`mŢ26™íJž=–ĽǨĆ7 ®ŢGm Áž#kg„/Pś-g|R;–>ě2lů¸ÎUŐ_w:Nŕś>űď>.‰/xÉôtŚŢcŢ'2Kţd Ŕ níąFb!ź•}§đĐçAö‹Ó€ó@ÇohÁą^¬} iYzLPvâ>î0çŕžued}366¦xÜÚ˙˝Ňç]&|ÎŚu|MklC1n9ÍĐíâĚAžŐzŹ|äynbbKąĘ}Ýɛɜ» z ĎîOtBń›äřÍqć7Ă’úvť»Lýḏ§ËpdŻôEäßăSXľ(Ö[c ĺDVĐŮĐg|ě» o‹Ú[˘ö6!z ßĹŞę_ĺŕ?ăąë!+oý9Gě+—ýÇŞ˙Oá9zhem­,ŐX\›Ůb›żűŐYó…ÚÜäĐÓr~v |ţSŔmG`”śÍ±üűű•‘W¨ě¤rbúoË×e ,S`™ËX¦Ŕ2–)°Le ,S`™ËX¦Ŕ˙ pźţA|[kńX¸svôcý¶«?߯Ŕîľ?[gšęűUČz†­÷ŕ ‚ď}ďIę Ä/toD|ćÝŐ±4řXcÄďĺ~_óűŮk˛·Püž‰O3đ•RĆ}źÔÂąí|Çgn>Ô]w?c<#_<«>”‰âYgíŚňl®ż]üd‚MďSíuĘż9Ş9  ô3şě:¸Ă;ŕBfńăţn‹l8#™u§/‹Ďž2~^ç˙ ď Éłc}Ţń’ń›â#]U-çđ}ă^]ą=öýű›;űz•đŃĺRbµCÁS×HY›¸djwŤ•óXgÎzâ]ĂmPămí\Ͻ֜D/Č©ź߸űÇá5±+ŕŹěŘ>ĆťŤ©·gľiü÷…Â"—¦—4¶Fř-95âóädýEÖn‡µ2‰Ž2ýfë]ě ˝˝ă‘–wĆë±îëćwdä9˛ŽGNG‡dg\? cJ˛öJvś˝}9O+†ýĘ»äĚšÎ3[‰µ”óËßśłX`ŁÁ¶‹9˘¬äčĐ5wĂkPădč ´áçL˘/®űVŞ˙{«K}5zŰÚżÁî-Ę~™8¶Bâçă{đvôţ|ëó^ŠŘĹx8Ź}-źł5VÔŻ ˝o̦qRKóďXňń|·öôu|¬§nîj­ľ9ZSµ¶+#OÉqf:Ţ™®g]¸Ykő˝Fż óV;Z6â°ů¬ótO eYĎjüµůßΗLŁŻŻš|łţ?>6¦k­Ő/Ż•ó!e?ô>˛ć| ćŢńłbśVÔ1>vJ7řŇOˇG#_ öŇô ‰}oLĂbhńĄéGbĽ—R§ŤiN#ł˝ŻŃĎ€ßěúâÓčĂkŻxÓÚŰNŤ`Ô˝:fźxHbK¨Cö&uŰŢLp”}9‡ç¤OÄúŔ(pO*®SbÔDÖťţöű’üŻřÁts1,äŹŮztżÚß©ŞöaŹÄăŽä u7đ:oą÷ş¸w‹éž}×H BGˇpm”Ç!ˇďZlĆ’ŕD2”Šĺq{š|ĺ‰ěY31tWżWí}KśĘ×Ř}ÜŢôźÇđĚÖk·Ç”d-·±üöo/îIz/}ř“Ř=Ú&SâsלţZÎĚ{…ě9\ăÂ|wč`ú4q›Ôá:»ÚĎagč"ńŚŞď'‡6wŢ'gl§é“ľwzśĂâ0MJ›~4Ü$ßUwăľ){ÎŰ+kĘ.9Só—]ŘcŔ÷ią&ó)łµÉEĂo˛>Â'ćSĆ?ĎPë}¬x]iµÚźô§˙l{Žě­ş6˛‡8Čzg0ŘÇrM”'ě ŰĘČGăńÔk—}žŞż%.ÚóŘ"{đ~ĄxéśCx7e‰łěUöősĎźĹ9˛oęť]-QÜ»Är‡ő¶óeÝ~ʬźĹ—–× Í›ę>]ŕߎ;Ľ–ńFĺ|ĺܡTĚbBóű$NJ`ír¸ · ČÔź¬ç!ńýŚp?Ąç ČţŰxlÚÖ2×ď4e|g<—ľ ´őţˇvšŘţŢBŻRżÚ bJ®ÝërÄő Łđć>Ů+¸˛ö±)÷‹p=([ŢÖ–‹ç?ăcĎÔçôçdŻ(9úT‡›ťen(RßáYÎĐ˝]bLxşWý/ď ¦÷=q™ŇăÓrniz¬rťýĚ.^(ĆÄŢ_šę+&{Ô Îó? k˝I¬âßwČXŞr|őŘäůęQúÓŞńÖÚ7ć‡>¶ü·ĚM\KürNÎC’ýĄ–ďdUőËé>#yH WŹ]ˇăÁĆü^J„~×řŘ í+6>,gJş/Ăâ´ĽÁÝ÷¬Ź­-rđp7:ő–îzŰS»%§Śäöě‘ý*çiücqĎke¶ôµ+.•‘“˝*·ueꨬHĽ¶Ö=yuçáá*SŰZžf4ďś&,şLÎăîF_&t°:ň˙7uźn‚§ëoĆ›_¶ýŹŔh>BáÍŠăşŇýzćĽä]ĘĘ~PÉu6xč8Tí˙FLú¤Ô!{AOŽdâł’”ĽAĐ©$űO?“ő¸2‡{]éCjÇ&űЏ<>˛8[{IÝ®'°اM[čĆ ·Ĺ2Ë"ż˛Ź¤ë =?öňśďłúžÚ%g–ËŮs»+_'d˛µÚ÷ žßדÚť¦´ňy¤ă˝çú[lÜ`zŽKýŘĆncóÝěE łö…wř¸>˙.9yîŰ|ŻŚ´¦đ“şŰö—>|ŚIżŐqoç¨YµP® Î-°Ă—mÂăö‹n;ŽXöÍ:ŢŰ~çgTR=íđ[ąÄż7Óň ŐއŃÉŁSż×}F.s’?Nrü”Río‡ĂłăׄfŚ-érŹĘÜÇqEWÎÖQĽKźÝ"Ľ:®Px±ŘĎWńr"ßąŇ4g†7Gă˘ă“nËßçJźZ]±übĽC»ČŚlÎÉ%}ľ±ôüľŮĽŽľ&ům´˙|vh¦ăĺ…B7ă¤ái´5}Ć\ÚňÁg·łh3,LńÍÔßžł˝ÉđĚé*/ő¶ç¨U»ý}ŮÓî|Kd‡śŞĽvYcŢČšW1ü„–ˇ†¤ ס ꬅůýďóxĆĆ»{ÉýÓř‘˝şJ‡Ć§ČţÁŞs]ŻŻ¬«rěv'ü"WˇäpŽë´ß$Wµđqă·ľ*vŘžŠďřŘ-!ľ]Ę@cđ˝GÎvŮű^móĚ?Fő,^¶>ôé*żäB’üŮ:N"ŻäÜ–=51ľűÔżßE>]Ů -{ßîXĂ^hč`{ýíÜćm˛ßJňú*lŠ/ÉýSęL€©ľŹH]ŻřĹsçd>&u]şFtsĽ÷0#ç#;đŮ|Lč’ź„+k×ĹcuÔzlőŮěŘÁďäR'Á ć÷z@ĆJčť•<sU°­ĺܵĚ}éw.wŚŻí•CU¶Ĺoz_·Ůµé g×…ÂÁ˛ď*Ů“v…ŇĎß”óGeßř5á¦ÖGĹ^}S89Uć:Ą8§ÂŞTţH/3˙«Ë‹]­Ů˝Ö©łÚ˙ŰN±űcľđĚç¶f»řD:ו.Ęî_PYçťä“n˙ţޱ}nďÜ‚<Ëł˘ŇzóĚ…ą­=? …“TŢyh<Ó˛{¤'“šç{ÇŢ_kuůó+ç­KŢř®“Ä/)ăr牙ž¸ŽĂ.Ü<ó˛X.’ő*ÖÎČîś˶ϧ[«7 }¦uµś» őĘňŹäJxŇłißíđ‘ÜQůůb7÷űÉMľ°d­Üř]%ߌŇXle™7şŻ€\ş®/g—\Č÷m×]¬>Jű°˝÷©Gáźę{f8Ő÷-ɟҊżDqŢÖrZG­÷©Ę—ňÄGŁ\«Ö˛ă*91UţŘč|;O×ăÇÇÖ6Č˝Đ{MeÄň‘m¸˙"ńů]©í$óF›ë¸L-ÇąËoYgąŁď=Ę[Ţ›iéŽď'†ž§÷Ąé/u Ďü¶crčâ®IÎëúÇĹg¦¸†ĺße'‡ľŰŘ®#6ůý¸/î ĆąVÖľ&~ˇ=:6?%ö_©ëĚÖŐ!çÉcĂ9î˛öĂ27ó}j¶ ¶/cĄäÜäsş6ć“<“C·Š)4·+ş^ýα K_?h>–s ŮPüWÉăly[îţŕ{E'˙÷ÚM­oT_PXŢ3{PĺŔ=Áą*Č }>Gßć{yÂň˙Ě»ąŢgśĆf°ą©Ů ›ZÇcü îôl­·§sŐÇŇÇ$~G˙Î~OđZCÉęËkźŹö^fę–Cr¶d±•Đ+Ę ±!f×±ŘďŚ;¦“kšę;-†wcţf«ęmçčU|žâŰ˙ŚäL4{‰|xŚŐä7-†ŻŐ<¦éü»ŐţżŃ©ľX®i Ľ¸ĘX%ą­“ś¸–SĂjĆß(ç´(’#OúăG%—Ě+×Jz…[b)ÚÉ˙Şý‘ń„1†1;Ĺě4{«Px»ěďż$î ŐţŠč¬·vméűą¶!ëŰŃo¦O]ß;Źďî=ˇ&ŢöâŻ2g;NňI}Ľť±ď+=Ď—ś:Šskuż5÷őř™(A ëđšË\ÉË}‹¬áŻőkĂctę.…[ň·hů‡˛Śăí•tN&{÷2ő{Ů=úkń¸=V ć§`|€Gn["÷Ě=d©Ľő%Őgĺ‰Ýׄĺ§t›ĺ&›M÷qSľ#źÜ‹-­cŐÖž¬âlP^ŘŐţÓ$öfDă4xß{ss†mŹ÷¦çź›ĂOäöí&äF?(–ÍK¦IŤ/öžűkÁ_0˙»Č‹Ëy­7÷KÉA¤´âĚ/oýěůnyfçImgłźČÚLś ~_;2ăŮţś‡â{owemĄđNýJď’*ć5żÓW$ĎaŚł—·«­â t{ĐčĐřÖR~sYtż¨·•-_ú#®<žîą4š°ŽŘëXw÷lç›ęP¤őU´l1ş¬÷˛ö]9żűUŕĂŢŚÇTvŢĆäÜgŹ*ÜÉŤ/±§Äz'1"LNgĄčg‰°ß÷ĆúÄ~]ěđÄ\BhNÜžË49ü×ŐsÁk|áőZ“˙fş¶yÍÄCČ QÎçŤ]Ú۲u>Öë±e±w“ß›ń˝ô ‡ŘżuüÉMŻ·ťÝsdŢ9?€ ^\ş@L§źŰ еk“hˇÜ_ŰŻr9Žg€Řß;îśTT ĺl÷5“i ëżđŘď%÷”gŽĚ+ż—J !tą:ňÄúž»âÔ‰C÷WŘ2ʵq<ăůŘßi­*–óĚśŢú}Čm#±íΫbćMÎا€î±˙â0x^řŚxźą]fo5ĆiĆ$âK&ç~h¶ą*Xôr10ě±î|FßĂNĆ˝‡Źż”ƵĐw#Î^3i‡ę°p_đłX»Ýh6=Î1÷Ďnłą—Xĺ5Őr{yÓbË*ť˙ţÎrśŐ‹ÍĚĆö¸ëP\Ą=–=–Ç6ś˝ď}ő ű6™8/ěRěŁÇ3ő ĐÝ ĐŁµ¶ŁUŢŢŃgńlńLv†é·ĺ Á?xźŮ§ oÚŹWuäÉVżűkl[đzĎ÷żźú˛q˙Ę\x{¬Ž‹·®ś0‹Ű8ţ©ýâ˛LÜ{ĐŘľÄccݶôyěěŢ–UĆsčK<`<ßx],Ł•á)±Iy˝BľŔfâęŇí˝ž›ŻŘÖŐÜéşbî&“G~go<†×u‚ďÁŮĺ%xë¶_.ď“n'ÖŔĂÎ!ŰođÚĎĂ —wýp˝¶Rô]ÝŇ×_ÎűIÉÔcmĽˇ'ĹCźWĎ?7=‡ ÜGŕ ý ťľżęDLd^ľ·Oź­›uu١>BFŢ{.=ú÷˛w+諾˛5´ť·5o–ś­ťy®ň»n2ąŁw^׍-ZěvűĚ»vŽyÎł˙’Álxßp\9ł‰>ľů}…BĄx?µ;ŢyÖŕ-©žŤ‘—óŠ5Ĺ›qf—·I{í3ղΣn€%Ú;đk6. Źô_ářsfšďĄÓîŤ/;Ç:Ę·|Ĺü°™‰méžzřžg Wń·RůT® ­ŐcĘŐ‘gĄ˛LŰĘ‘YŻóÎbóąźřýůţ'«vÚé%đÍĆ-Ő>|đlľĆÚŇ8¬1iŘčłµőÄƧ[ű×Ůçu3ýk·ôÍŢŽK&3Áë°‹kţ9ĆĎh7%NżP¸:ˇľ×§&Ő±sěľÓ.ŐU‰9í¨v^ÝďÎŕÜÚza9ô´)—¶O{ÜcFŰ+Ě÷^S}JguäŢ ô¤]dťZŢ«SúŃVý,vľ^Ö‹ą0ů´GLü¶â'EĂ3ľ_ŞKścÎ÷˛çéśa`ř8[¨ŰšÍ7Iť†čďK“K®íŠu–ęČ™©]úćÇ)‡đ´çŇÔŰ,G€ą xb·3ůń3N¦˝†_śçqĽw;KŽÉyÝ;¦Wź5V%ŘbTé“qĄ:ň*ĂXĺŐóď´:€/÷¬©®7Y¸ŁmGĎĚÄCěąBá"Ő°9©4ľĐjňťŐtńř|hĎ_VŰŚ–VŞnśËdř–čeډôˇŠekĚůĘ㣎¦Ë…Â%u\ěüëîĹ–‹íłÎŃĚÉ>5ČžźčĽúT>Ŕ$^Ř-o;Ó“ŔskëqV«Ďu&ž8đëĚÄ.ńÇë*$S/4^ąľů<Źő‘UµŻ×aÎÚźšý©ĺ7_5űô7ĆőJń–ŇĚÄ“-§—<)ŐçIńÝŰrGůŐ­ď·ĎŚaĚĹKS˙%]öš=í3—Úoy9üŁö/źc<É 9°wč,ö¨µúľşlzn(­ ¶©F†ÇĽá'ÍL\¤üÇcşĎé›5˝ö\]řö„î“ćߪq§đŰ#Ľ÷…€Ü“Ç—WŐŢ‘P‡ek돬Ż}ď˾ɯ=ŢĐ?|›ěΗ÷A˘mhđɉgá$g ßU|[ĘËčaMő[‰űV3©›Ü0jóűeŇŤÝC?.ëś{É/2J~Ü_jLóüĆţŠ|ľ/Ö¶)ů=ÉÄÜź+ë4Ő0űÎ>}qß­ýWÚ÷äýG›|0ݰ_ř‰Ś qN3öRőC¬ź­­˙©\ŐOÚ{Ĺäw _żAë<ą±4ëů´Ę‡M‡ŃË“˛_ýťŹŤß*ź«Žë.ŤŤ'™©ÖV™1ůáŐ‘ÔNřłNÇĆäSÄ »Í@֡㮑ק6F5Z»v=5í7Zg>4W}5Ő´Íb?ý{‡Ť±Z5öş†˙'ëvŽ˝˝Ž#5>ţ¤ţţÉÉ–ľí=őĂč{Şs;­oä/ó׊ąŽn¦öžęÖĺ°‘†·ĽJµ®~Ws^ŐVůĹ2ßśňWă°á<5ëµßč=™ş¦żĆŤ÷:×ŕUî«ňĄ?š,Í—ššý±ĺĚ«>Wý9Çáe˛ĽŰ ź>l:Á_ŘżóŔ˙{ýwç1O“ł»zţĺŇ˝aŤ5S͇erÎë&´ĎüŤÍ ÚgŽ—ŚW'ą†oKe" đą`ˇđŮ„ł«Pî/ÚěsżKëg gĺͧ8k¬űŇ…Ţ:mÝNWŠ~>r67Źžîľç6Ő`Ř9öĘň‹µ®ÁÁ‡ :k<ĺ«Öv;U·%ő—¦f˙\szZËÖ×BéĹkóđn9/ć.ČỎhűÓWń:«űk{rn•ńŤ{§Ü§Úâu˝÷µˇŇÉ6.‰wu>fşÓ=ő"ŐéýĘ:‘5Ą#m¨V˘rŞwĄşĎwŚ]Ŕîřf|·Ľ—×yĚŹ[Ř'ĺé&Ą©ŹßżľZ˝ôóáé'§0bß}ţÉ<ó‰ňk gě đižŘ ÷|70ü„2g˘OÍNnÚŢű­ń.m[µ¬ v+渌ĹÚÓÚ<Üó¸2ćVGîkçż7Ž˙VŞkŃţŔđ›»6žđ)Ë ŰwýÂr'7Ť/\TożĺDŐ ýŞé‚jxîă“HŻ7´[}úŰ”;îµŘUE9ď÷6˛—™ůĂĹrŻîk‚'ŘG®ŞˇQ.Mąź uŤtMCą~ä´t«®0™ßˇ\J?óˇ÷نSř,‘ŰŻ±¬‡ńµRüOĺĐ˙u]72¸‡“sŃg=;ş9ň”bŽŁš¶żżkŃ#ăr¶Wáx3‘[s‹dË}ľBaÇô…]Ę˝IĺŹç}˝“wś˙ţmăËÔě™vĺŰx…Ţď»1•›Éą/§tTőągřÔ>‡BY Ť±1Ú[ÎuáŐşoáĽĆV8owpę4l•˙55{ߎŐóo5ĽĂ/ţˇü¸ÖjY{ł ŞÓq•Ćô;l®Ą\ Ăť#ŐÓkĐCŐ.ęPmzĺ÷˙žjĹNY-úâ9v?Î?3& Ů^Š'}gcDˇÔ>óýM¤ăKĐßź÷ŞÁ˘yĆ}Ëáb_}=‡5µżPť­“K[úţ=i=ýŮĺÇÔë÷,ß Ą±ĹOšťž™ř`űÇB[EŐ?Śůe¶=/÷ę9°¬—P‡ÁĺĚŰ,MůZßţz(Ş®XöýŰŻo ÎxĆ™±yAvďTĂęVđžľ -úÝ'gXţnw2ő@«ëÍfŤb%u™~rŐWá•ɵł•+%ž·ŹNĘö¤|nźyNGkőĄf‹^§ú—Ęk—žş,ž›ŁÚ®˙cąĄđŤ>TK˝łRĽÝôWy…9›ŕűań,ň¶ŘÂ:ŻżĐźđ?㻕ş†Ť¤=ÖLKčŹlUŠď)Ż©ľĎxŞ|ߎŖqW§fżĄšqÇPűLsɧ&‹-=ÜŹÝŹů íµĎüžŮ-ĹbLďéíHqŮÍÖÂ]źĂĎäwÖßf±´¶’/ͱ„«jŕł9Lľ†­÷—|~Â`n“ĎüşÔöÂ+dřůcţ‚.¶Vż˛ŹÜĚ÷^ßyÜö™>ák¦»^wo%±Ě·ĄĘ66şMňőĹŘqąËß ďž+|÷š^jŻ­.ó™/ú#ákŇŕďvíłň?¬Z6Ýé™ ÜójęX _Ř1­)MVj}·˙”—/ĎQwýÜÎu~}\ç ¤cúţŕ^ţwy<ł÷çÜŘaăk—j^1÷Ý9E&YŠ1•›ďú|×pÉĂ68¸1ů'É|ř|ŕ µî–žuć÷ß_Ďúľ…z±xLľß«ąőş˛öéĚžQĎnŰkYăuÚ`obżaľW‰1{˛ ô«j·¤| ż&âR¸/tâĐcšőŔŘ Ţ·ż§÷ OťńŁ5ś?RíżLávśą/“ ę Ĺgř­Ď÷wjžţr“Í%­Ťđ†>řłĐ6ž9L×Ţ€»Rü…Éó¶Ĺ{«>Ô;mL˘ÍöéźZ tSk֗ظ,Ó¸›­:ÇkŰâ%Ąé韦c;uînď˝wеK/?Ă ŮÂ&&\Ón¨mřúUë¸ć_řyÎ;řęŻř ÜŻ"Ö"öG¸ëŞŮGĄ¶şvű‹ę:Ný•‡—h/žËÎ@Ş7~.ľ^çňÍůZíŮ×–Źn^U›§;Ł–^^N—ŇěŐ­Ué‡ËżâšS;:Ť=ó=‹Ă„ä~ş cNĂ8 \Ě;±Çř„¬öUn˛9śŕw„N śUkÂŞó[—Ǟ# Üç{­~ČÉ~Ŕ8ě_Q󛵯ăĺóM΋Ě|Ą ¤ś_lg-ţîG ™=ş4^ÇŇ0ßĚZ>’ďF­žjÔcFgç_ŔÎ:>挗±^âPűŚügľí§Ě–­©Ž¤6íHbď[ń+ÉŮSđŠ1Ř× ł3¸OěóľťŇ¸wr® ţ5ÖÚâľ|űGëű®©ďtł^üäŠ"ýÔxîµćłßřĆçHAŁř żR몊·ř»}ÖĹxęh| ľ´Ś}…ĎŮś1ÓM|O­›•đÁϸÖĎP8Ń:`ňg›ĹŃČŁglv˝:ňĹŁNgĆćµI&šhR I&šhR I&šhR I&šX"ţűGZߊ} ˙.k•=(Ö‘X'^eągVg-Ţw¬ő ?¸‡µ~ĺŃŘ/k¬Ńsőµ/ĹŃ_öžŘźŚő0âEXçöý‚Ă ÷öVk{™­×‚C¶vŻ\Ë‘Öu8WŹG…çÄIĂWö,ň{ůŕ>9×ŇĂZ)÷íţî}ŹĘ5˛-}Ď1^˛|íÖĎřÔ9VÔ·8đaOÎăG7çsŔ}o¦P8§ďx;•{Ń ®¬ď‹>GŃz·Żá‚g쥱wŹvŽ]¦xô3m/6čŔ™{±ž­üpŁ•?—IÖÔěmźŮ`/„«ďwĐב{qî-<řöáG¬gĂóZۤ­á"§±G{RľÎ?j±š{îěÖžőÉĄęČ{“Űu/íň1'ńٱ=rxsưÄţ1y¬đă=˛KŁCČwč·é´đ_¸ÖÎťŠ=M=.ŢăĎOígXţ'zňáqŢţáú{ďGÍ^ÜŘ"ę`Ń왂«Ă#;&ů >GĽ'ß Ź'í;Ëä¶“­:_ݵúü„vŔsŕęűZ_ěëqÄjĺĎŇ:ÓxĽ´o÷S‘™B!ä|çűź®Z Ż—-x¤jTÜSçgţ×Ć‘d1ĂYžWđ~ĺüłĐăQ‹»Ţ©Ůß±z ĽWmŐ-gđ|#ÇvVĎWępŢ`sgŐ”îúK5j:ÔG{|î±ń›¶Ý§ͤ´MŚ•üőĂ9Ć×€Űe¬PPÍ+Ő†»aĂp˛~ě»ë9=ĂÉť9ź˝°őú´Źť=k°Xň±Ś{]ç …+;ď·áΖk;îhóś|nl<Ĺ–˘ĂĚ7đ{XS{óâe)ýł^ěv•1?|ÝbíMfUS#‰sťwŤřyĎ´|Ĺ\·őŮWy¨ńĘ׺ěüH}˙(űMu,”úµó}űĽ¦ę珪¦’=^Ă××ý”WŮxµmńÝ)M÷t9~C«•°c!ËĐ6Ćâˇ{\g°ć©wéÂcRZ«'S›&Őçńüý˛Ďő6ž\Ç-x[*o}ď}z¦6y˝–íÓďîŘ1ýLło3 ýVG®. ‰vň˝ýćď˝Ţ\cSłżdM#ĹgoĎË ŽţáżIq¦ěÔ¶Ĺť¦[sC?Đůrß•ŹzŁ}VLŁjŃŚác5ŕŔsŰ/NŰćóBď_u®©ľ°«4őF»Wçđ6ôĂ=·ö_­9ÝXOč5ßě 9ÉÚ÷ĚÇ˝fâăň5ŢŇĄóĺMö”CµA‹_뇓 ¦j?Q`ÓIóǬ¬‡J¦Mv'çţ[~Ěي뾥ĽĐűŻĺČöěľwŹüŃ„zSă ŁÔĹKqS»Şť6S§Źë5üŐü$7F9|™-88¬‰)§ l0ëzaÇÂfWŠgt«VšŤÉ#­?JÇשŮ=]Şk—L«–ŕöé Lv×ÎPS'_Ç/`r9R]µäÔń…ntąX+ěc{wŽýˇŃ@5t+u2Ü'Áގw|^‰1ÚóÓ<6;ÁöhWŐîU×C‡}ăř)“ró7lm}k×5ŞŐX©–ńÚą˝r™1™1ű»úěšćŢÔ-ő×s;ë<-Î~~ç«ZŹëĽ`ůa^~*µ|Ô÷C$3Î[ŕÂ/‰u”z3u‰Ř{Ö˛TăJuž^XJ¦Ţ×€kľáá¤ŘˇZś©/ć~‡ßqG›Żkń ąW~•j5ĽŻŚěŚ/<ĘtxrîA:7ýą=»‡V%WĚ}˛Sóu•âńňŶvÎLÜż«X+v)ź|Ö ˙ŕőMSü—ą† 5Ň;öh`_¸Źjü]Ę2ßUpŁá*]Ż\É:Ź]nůť0ú»üÎĄţíľżÁ~ĺďúěÄśĺťFży;ăąĎ™ź—îŕŢŹnÖ©m1;D[ŞágxĎ ]ĄĽÎOwhž z"éüYĂŽÝŮ’ĺ"ÓüÁkÚpyDf祧;¬íźµ]§<ťÇwlźľjťrŕë9¶“ÎśŢ@çŔű‚Ü Ď+“—㼓źň¬ńę«\Ů9śĽÉŕŇŮ®kŹŻm[?5ëulĂŹľ`ńdxvěµĺëµ.Ş»’l~‰5CŮęÚ>^k>Gő–ĺżw¨öEęsŞvyņ3{}ŚÇ˘Ű&ŃĘtŤ9řţĺ( =«Ű ü1č98řg&;Ǣƛ·Ą}Hńá¸uµŰßlřó-öjlń|ă]Řú|Ďí3'Ş6{pŁŇé×۵úóc{еO™ “o˝v8ůĎ óýŹę¬µ=ZőwľÖŮZťŇ·[xúă)ă k/+µć-źĎ`ńqŔ!ţ`ݧ§ßş˙¬ş:ľ>µ*Ĺ÷YÍń+gżÚcž]d 7©Žü5É®‘_ŮoŞŤŐłŔü ÷ÝFźĹ–>ăçîˇßMeą}ćFkÚ`]éÜäIěěOţ¸ď`_Ôę@f˛=2§/ăNô:©=‰ÎKnHőŮeŰ×hU+'…™ĚĎĺo7ŚĘ—Ô:ËďĘF—ŽYô•_…1Ď7üî•đµiËĎiqůŽu÷Ŕ•kĚ=|Ý•'ö}méŁ~ vůyVk"˙ü9}ď±ßTćŁtZĺˇÝ{[žm6ăřRßŘ·AżýlÇ~iěIőň޶=i,ę©Iě-łžÎn˛Ř ­—¦6ß!÷¶®a7öČ 'UíČóÓWkŞ/í©ŻHű_ĚG5î?B4˙ť2súÇŽ0Nj_Mő˛_©żť¦‹ň•ŚÇ;ÇVu¨>N]/}uř}ÝÓ} ‡NsůvÇá«×}KëĎexÇ3}ňň>9÷޲6~Ż ŞőV˛ńŐí6óŻE<şů»˘ű|˙|˙sR»Ł}Ťu3Ăë†kňYd{N:íöftóĆńĎ•°ďšŰ=Ĺšű3w´=ÎÚşfbĚj ݧCĚřmđŹOýĂ•CÜëGEßآĽM‹~¶-úťĆPÓK-¬ß=ô†„}&Ć7t™ł0m§ŁďQ˘×ă ŹÓ^îµ÷Ó!;6Şşˇg…ťÄ§Ä÷ţăę¶;z_Ů«j$‹Ž™ś1ÄîŢĂ›Í~‰ÖC/HçX@ăgŤÎŃVĐ9ťš=%ŐÇ-}_µ}ЍC‚-.ŞYf/săřĺĺ,'üę´]űŇ-Ć'`Ć@Ż‹µ3Ę}•gh­űÍĺŘ_űłâWä+^«˝Ęă’Ëu÷Çž"xÂsĆ@Îâ7lÄŇŢ4_ŃŘť­ÍĐvÝŽĄ~űFKź\ąĎŐ‘_©~öń‡ű˘Î÷Kdőr9×Čkőyď™|„/%ľn /đüët<ç9ŃQüsűÁ5lJ̧ÎMFJÄź¬†űoI~rŠ3ňć5Á¬NĹ@0nKŘVoEkBź€;ţSÁo>Ăť#őč÷ÝŢ{B‰q)žaý›öcĚĚî?裂;=j­Űbšř.“‡%löŰĹŐe2ö ü>ĹQu­ťaÝŔ×ŕţń™ź4:hNŇňÁs“VĆź9\˙§<® [ú«ýĄŇÚ™×Őe3ř™‡(ľókŕ¬ë=ößŮ»Őţ®É-z°ĐŰ#ZđRŤd[›ôO‡ó?v;d.» ß©Ëbć›ćˇĘđVÝŰžěľgżó<ă1íÝŢű ô=ź±—üń~rîCuüómľ÷á7ŁcŞéhv;dű[Ąîřź'Z#ŁŢgóK dž~Íőc”†_gxҦ|{c˛Űkęm˝ââ ÜáOĺ÷€áľzĽµőeŇÉŻĺěqĚ?yÚůú>$cűůÎ×B*O_?B2 ¤K_Ě ?Ć]ŢĂb·ą÷ÔqbťăňÍçX`ţd«Ł†OŤO™—{ľóą{´qt\U;‰}Źŕ|Bćá9ß)ž¨>–ú^1ßĹZc>kâĐąWý1ÍM·«îÔه| >X*Ş>býLíÉj<ÁÎ{̇´Ć1bóÁąŹXF|Ú÷ńč`ńŽç:§6um[|dŰý'ô=| ćZ·ß|»üiŮ»Ł–Żßţ®óýß2»®ŕ͸ęlÓqž ›żslgůĽâŰěűJń·Ňß÷×îÝé;ÖUJSż(ímy]ŠÓř±Ą;Ú®»[ňôîDű&¬M 4)Ф@“M 4)Ф@“M 4)Ф@“M 4)pôPŕÄ»ž`k™ľFtôŔµŇ°ÖE,{ެó±/Çž9ëüŹţÂ&­Ź /úôé–;{ušřşđ»‰}>ú_¬ń±gžůs›bßĹ÷%|=Đ×Âă¤őúŘ·U ¬­ë| Ëm€Ç˙ý¨\/«+¶·ÄZ.{9đRy5Ę-źůŘ[,F‚uúŘ›`_•µ]Ö¸á=gßNÍţGŠŰ‹—Y{â˛Î&Ľ©äů¸GĎ#^ś¸ řHí?W ~z­řžÚwł5ObG  ńCÁăŘ6žŤŘˇh«·©ş%-Ť{ďÁď;Ú_MöăF^9źÉiďĐĆ^úç6šď]~‘ű,źĹă‚ąŹ˝ćĐo%ţM˝Ť1ŠŚh7î>´×Ƹ—Ř/Ľĺ i˝(çĄCzŚlŞ~G™3cţŕ%đ‡,ěĐP¬»ĹĆ3Đ2öŔ|'ŐŐă:h]{ÉöŰtÖxVgĂ{µíł’űčůnÁ›|ž·Ç,ş 0f…mFn¶¶ţžňľc{|+:ŇúHł‰kUĹűá?çKoËíçgż¬Ü;—7ŕ‚Öä(NY{âźÔß/׹Ź7<;¦/)ĎŽ-ve±‰ţ\Ţ&/<Óą„eíK[ŚAČxč…rǺǪŘ}ĎiŠ;~ʱýPĘxŔCČ©÷ĺ¸TŠ_))‡Hg“ŻâŻKë50ü~ŐjąŇjl±äÇ@łřN±¤őúŻ>ęgťťVyKçę‡=±äă¸÷—ď›ýyĹóçx¬ÄŐó&=Âr ę9ÄňĚŞţÝ‹Kŕ131Yşµ˙!‰h°ańFŻĹŚś«ńž|ýtř>äß8ľZg•ý­ňçďgńĚÉÔĆmžîa|¬[ ŰČĂčöŮëŃŚ/ŕ'úkőüçĘ{zw(Gř3i÷žŢż×YmWÔu7v'`u|]˙oďí6^-¶ÜÔŔł;ÚŽUěěDÎŤsçEžvĎÁ^ož›Ű~r\ißm'ů'&ďWîo´ż·ĹëîTŠo[§ZS ±Ěnă=®‘6źócm(†¬óÂ×:t6ě:ťmo1ű·_Űe24žË.ę¬áłkŢrż2/|bú }B‹Á§†ßÉÔĹ+ŤŻ«jŹ4ÜÉŹ˘÷s“ÎO_°ď‘[lřąÉSlÝü\L‡UvŢÚůYŰcÖm˙Ŕşu3¶ÜÁ=˝˙Đ™LÝšěé='•)µ“Ćľ-¦f_’ţľ<ěłó·ľ÷Mećî;šNŰDűŠgĘĹ˝e=VG>’~?ߏ>şůŠś2ľ0gĽÚxÂďwďR.ń[;_Łz?iŐeŮ09÷h;—.pT/Ćh ŻWnĽöx&úÁćöUnK.U]+ťąÖ w`9ľŐvśű«î;[ţ;•yže|ÁGń|-·ÁřŞäřWG®ÓYíW›|čĽcĺ'íJmmëlzŁAŘPŕÁW.ŕČŰsî^îk´^ó%ÚUĽŁâ|ň­NÎu×çÔ\úŚńŤßwŤ|TçzßCg]?ĘňB>ĐŤ<ś^)k‘ŔáQNĆ\‡jUĄ9KqÇíĘń~ŘXŹ =o7îZÎŐlN cŘěéë«\aô_=źß§fłÜ9ĺë|É×+ź˝VźK9Ý÷ Ű}›dčT?Đt Öv¬jÁťRZlů¬ÉH­í:łcĘyW͡ĺČ®3ľşW°ą5c ±‘Řslîr°őgN|çSc‹YͰääwţ{z¦WŐsVü~ř>4<ˇ=č§Zµňa?ź¨Ž‡®»…ëtYůűZ79Eµ*ĆMÖŁGľSÝÓ4~ťvĐôŘĐé• Íű_•"ç\úkjö’.Ť% vFő7Ś'3{8W­Ěŕüń§Ů\—s'ç~·Ś˝U/ţ¦ÉEÔn8cx»Î¨üdÚľr×”—ő9k/úT~FŞăĘWîôÇ•źINĆéŞ0UfťÉu&ž8ŘkfźU'Ää/?oj­ţśH)?vŽý ó4ťŤëy‚ô‰ś µ{Ý»<0|©ĹwwîüaۤżÉšŞ×fNĂŹ”sąj8|ŇpŢ1ÝŃ€»úë<ݏĆě†Ö# &÷b‰îĹZWG6ĚŰuŰáíŞny°éąó3“€‹b·Ĺ‹U=Čźň™ßH]A«[±Iµ>ŕąr˙Wç-µޢ÷Ł›uV¶rFËpY=O٧Ö} }cÝF:<ŕřňěҚ懹ăŻíĽ#ňéĄGTGŇńH9­Ćʉąďv˘żŃ´gümÖ÷Đ=üď{«ťt­§Żňs{żVg}Ë—µö´vŘQůł7™\+‡Z8?#ţ=ăGôy°×ťcśÇ›µ—ůŠţÝŢňüunrŚÁ§śŢTÇ·wślđOÎÝd÷#ĽEďŔĆg®Oč˛{‹µs{ćűGŤÇŃöŔđs¬MŐ3éÚ=ôÓůÝ´ĺ65jIĹĽ%ž:¸ë)ß˝¤îßq>ű…ĄGÍ<¸ řX>QxxÍMŐĚéXlyáĽzţŹLSđS˝gŻ{ś<~,ř.…ŚZŞQa8k™ŽÍŠoNíĎ€/~óQďgtó1ć—-mń >Ű8 ř°9Łô×ôrikGRůŤűeăĚ~Sëśůg·±Ţ>ë •â5©Śomý^*/ŃĎ®‘gi>~OëÁ3üĆ4›kĹÝËą"ÇĽÜďĆ^@c|FľU­‘nĺÄmÖ_9;fsľç•­“PŻâńfłŃgxŤŤá[&w?’¶‹µ˛éAudG]^ŢžÚFůÜŞ;ř}›cµĎlO×ßB˙ Ămß˙~jGŠ˙O;±ĆěöŃk‚/­ízJŞ{ŞÁŮ€3÷Ç3ÜË3ČKŕ î:s”Ú,Ć»kÇ^›¶ĹýĽŞ#Ł©Lď9»n/ÝžĐ÷pňÇçĺľđëb-YN`đ Ôk×MÎ=ByŁ› ®«f?Ř€3}cč“ňąź't:a\G¦© €=ôu‡°mfÂđÝsů…ÖľÖ×Ě>O81÷¤”ŞÉ•ÜĄçc._źźÚÚśó{ą ×i-/ä:Z ˙žţzYŰlíÖĽÇđî«üţÚöÇüĄĆë'¤cj®Ř _i+ź/ň˘±)Ĺ‹~¶˝ö’”żĐ:t)`ŮŁ=ě|YŮ3Ď]§˝ćL66Ň_̉TóPüą1ŐżÁÁ·¨6ë‹ë|›·qUđoöó°]>Á'đ[Ľl»Eü…m­žNÝ7ÉÎĘŽuĂho9W|÷ł…śßMŞÎůşµ¶óä[^¨#^7gćÁC˛A[4Oř«˙ţŕ3r‚ę°=«Kµ Ín5ÂęĎĐ_ĚĹ‚\Ů#_(XýŠoî¶[8¸OYżˇGů~ł÷ŘńŹ_]?ŕ ÎĐÎĺÓďl­RmÆ=˝5ĽU74W§=öÎRޱ8jă`żö~ú]˶Ů·rŮĘő¸űŠąż¬ç λ‡~™ĘŰîˇŐf¶ô˝Çô’óx9$Ď"ă<§Üv{f÷Đe]ZIů¬y™é÷@'lÁűU+2lk-ŘWć$ŚÍ^Ă" ^‰kĆçlLđďĐ3Ö—‘Í›Tżňß5š_Ż%í˛k†÷ŘbŹáű‚ČÖ‡°=ěaˇě€jß¶AőŔ:Tű˘®YżŕŽ.…>ă#0¸oĂ}+˙˘Ź qđ5®ĐAëűŇžeł7lźţiwř›<Ź9ă‡÷Ś[\Ă)ÖîerqĹÜ#ę2Ó·Ú7ů źźy^{gűí)<öŮűfŽ”ßSĄż°Ýâłj›}Ń`žś{’Ůŕ5ŐŰTŹü4[Wx‹†ćyüh <—Ó1îÖţ]Ćď[ű‡Ků5÷9=—çýďŔ°ůÍîö¶Ł®˛Śoďűný´|©™t<-ÖŢ”ÚęgŚż¸>vÝ_|ČĎ}Ľ=âc"źvŰâŞ~ĎweűµJ4ôYł…îÇqoÁükě_Ţ~ŁÇ3ŻkIýôß —ßü.ě|ćŽuŁ/V«ă@‹“sŻěŢÓűÓ”gŕ1Řžw^{ýq|óÖęî”VŐŰKŘĽú~”ń3ěă::5źÎÝ~s<äNŮÓ1l%8„=Ńe}|rŢ ^ŁšOďH&ę5š3dŮex4ÍëÎĆ>ć!§k]˙µfŻą/öfč+äy©MŮ>ý‡@Ź÷Ą : üI‡µ'ůđś®Báú±Çiże•íĹro~-?|ddľźµ Ćö=şz»|ÎüŞĚ÷CÖŃ+h@íHî;âţöQň52C¶ˇUŘ…Ő󗛬/«#/(…Żßk(>"8źVyF ëcŔ­µmł?đřňóă XŚ=Z/ÜN+l0żĂGęŻń=qeÄčÄśą˝‹–ŽĚ•ó/cĽNí«™Ś#ŻaŻ\>öqąĎdZőkŮ·ňq(d™ű\? Mřh|Ç_¬lł^oůVÝvş?zľ °Î÷k÷ŔOlÜŕŕ˝Ę;¦'S9ÁçLo5b˘vÖ¨Ů>÷ý˛~ʆw1~2ÇÉŰWdsˇ÷„şŚfg"©Ćľé~EŔŹţĆřýĺÔFÇŻGőŐřżż$żÂ÷3LvM>CNÁ˙;ď“8ţ.ĂWÍž˘u´QťWđâşŐ8n:ż”÷‰ń©ózŹľłÖ™á>ťô@˛ż§÷ĺ-}żU—őŁ×ýA·qü9Ą°gˇë™Źě¶)xŹNh}t‰Ď˝żVŹţďŁs0°ĂüIž7_q˙ňŢ– :Ăîĺľ»ţ´g`řtéĂ˙Ť×9}Ůzđ˙ Ś›X6)Ф@“M 4)Ф@“M 4)Ф@“M 4)Ф@“˙7(đ°G>Ôö,Xżĺ/™zkś±—®gC‰ěĚ©l=đ6ťŤv÷Ł’çd)/097)–YçÖYóżSq\ĘeH"~€ýťUŕ>öŻŮ§_‰Ú;TŻ8 €uěŘsôľ<~ŹýYö4˛8˙5pŤ˝8Ö}ŮËá{_?T|»â‘í#"żě˝Dě8|ZU»=öاăJ¬#ëÜ\ă^đä3g°żű7±ÄďőŰÁCąrO*GĘöiśG´›ĺŔ_ŕ ŽŕÁŢFěMr79=ÎçĐeovbχçřăÜMö´[«ÓÎť‡űuÖ`%Ý?Ü?°?žß‹Ťýd‡Or.ą đă>sĎ–>ŻŐ@Ľ˛M{Ü—Ż˙p¸qÍúó8LĺéóV^ëĂřcŻ<"ŢQąéŢ+÷ÄąT!żŠůV;÷,Cż…Ţn‹-`? ýGb?h”Áq¸Ţ…,z|…ď'Ňwö=źŘov{ćż…ť†&ů=<ö'á}ČóąÉ&«EE{wmcűyxc¦6x¦RÜVZ=˙đRţ|XŹ5˘ŻCűB&‘Cd”ń6öŹu~f‰şpYî¨ă-Ţärń-łÇĽ‡§ČżCíϸě’Ă6ѡÜ÷ú"v`OC|¬ëyüľ˛×Đ5l2đĆăMŔĚţ1öćo'žec©r´-Ţó5­Ő.ňŕ˝ăĺ´ĎTKđ";ď臊©äÍ‹ŽťSłW*_öR ™‹ôľópşó¬˛ŘŻŕ˛=ś|Xö–<ˇě¬<§ăŽÇčyäźşzt.Ę1?ă9čţż0=…nŚó|§3:»”«WŹ.ŮŐő(Łu´×S.˙ĘŠúčŠa´xěń«Ŕ·Şö ĹźŻsś?’ĆűĐ˙% ݞß÷¶Ü#Ó‹Îż­NÔřđx9«i‹W­í‰ĘyţU]>>`9 Ęĺ±ëĆń-‰rÓ¸ŃŔ“+z}htŰéc)4'Ţiőü—r¶ËƦMŰOLc^’©.ťŃ~oł±Ŕç69Ć™z9ŤżŚă;ÇŢnĎ]?Ön±îEť‘îÔ .ÄŚµ¶§Ú=ř5ĘAi°iN‡xb%®qΔź{ČŘŠý ˙«ŻňÂ4/Ş:rl—|Ňu[[O4™t˙ŞQ&#Ö:řx–Á©˙őĂÉĹşĎ[íR®žµżJ2Ď]!çŚġaGVr>27Ôgrľ>!v*ł·Ô›R®ýl§â;×Tßaü‘mÚ°·çJŐš:ÓřĚs'`Í|;ëÖuńÉ©ŐÇÖ·V˙Ńdz`řMëeżŇ\§ŠÓť6"–6d{ĄlxČsĄ8Ř|-®¬×K0=í>Żř%“=ŮëTçűoĐĐ}ĆĆ0ńŰĆgdĐyń~črv†2x©žKЧňpÚK´~`řáĆchŽ>'-˘F řű<Í)łĽ˙žăŁqĂňĺ\o<&s÷POIůŢ”›ü ÷†·řŰ`»č»¬y ä˘~.ŁŹ±´Ľ'ł ˛˙ÝkgŽKuDń­ë’©˙Ji¨ś3ĺúżŐôE5ŽR›A;á'xüáň°ő§6éT˝Ď]„Öďš+ë<Á·¦vlpđâÎÉą ®Z[vŢ-cs#ׇlľ Îč3żµVżbíĚ ÝĂhGßŐ‘NťűÝbí&Šwî~ÔĚ„čę6™‰/~ViÜąś«ăĽkÄ󢯙‰7+˙””§Ę“ëěR®ŃX*—ôŞ"]đ8žă˛ßůyጻ‡nVí“v(ŁcOď ˘ă#:•W¨ď<ĎďĚě"|űp‰bŤł–î]>ÖxçŘ-·?Iůś)?~]Ë}ŻďµgrX°ÝáKí/λRÜÔˇzCëçűďźŇUý(÷ĂĎ1ŰÚş+ť»Ć\ ™qűóë ú˙˙ţŠą'Őײ{ű*ĆçHőIÇy7ŕ>0üéT?0{l’Lí6%l6ĽĹÇś™řx:nçůÜ;ţę†ö˘îÚŔđ7ěűťcďNű*lkRŘWƧcďľ“/ĐĂŘtŚ1¸i8ąTg!>?Q=ZÉô{Íţ¨6ĄÉöα—~>Đňđµ™KcgŞőĽÁmć˘[đ1>sÝÚú\ă5úĎÄüŚĎ1ž0n»Śçź>÷®7ň©­vBŘHú‚Ş-c|TN¤áÜWySŞĎŞťdżŃkŘ/žűę’ZZžŁ‚Íú'»_sdŤßîß˝vpp|]kő][nŚ3&}†9v\ć¸ĐŔýĽÁ±ń™÷‘ü|řë?ۧ?ZV~•jśf8k·¨®ťż?§ďůĺű*g˙#;6Ôם~;ÇÎJĺ 3g ţ—Î “j/M$ۧ/6ş):­ý18řŻ&۬ÂWl=pż‰qÇöĚ­P--ĆšĽ\ëłĆŐö '4Ýę«”S;Ł"XíŞÝ–ŽłçĎ(˙Ëu/ŞűmŮř®ń‡ˇ:6ŞöÇ©\ źĐqGŰ?Î3çh^9“ +!Çuٱ10ÚQ®˝éQ#×üÓ»ě«`÷Ă{“Éąť%÷ŹÝg6ě7ôvZĐ:áş§÷6kGăÁÚĘW\Ż˝˙ď<ÎôÂż59¬Ż1çď>ř÷’oöŮOl,úMk­ŐOLF-)Í _Í Úř=ÖIÎľ]véÔrČsĚ[ ö‹{O±Ů€WýqjVŐ޶!™zGIg›~Čö)7Úk!‚ÇlBČřĘÖ4^ óýW§ş§:Zx´Á13‘ůK•âýÖÍ÷·×LÜ Ů®vźV) nçOŘ|x&RőŃ^Üť÷«·ÜřµtĽ‹g¸ GٵrřşÁ†ŽđűôŐW/Űď„ţţĘřÁçŐó3ş«†Ą]ż´N`˛Y€zśš˙µu.¶|’9żŮ·÷±\ăť1ü'ŞGüJ­ý|˘óŐ­—Ş~Íq©'Ţěuś'Á ;˛mŃëcŕŰ1ž°Ţä9ŮŃűJ\łµ«áäM†çŢ–ů†şN^[Ćű¸úúőw¶|6[ů¶µúN{¸«?ztB6·¶&6ľH~Ś·ă ˝k†˙b˝jxtE­<žá/ö{ ÷:Ďi;hŮ>“ÔűŕŰ徼–4tE–ňňđ@ďö˙ř`iŰk××mQ·­í¨ŽźjŃVÄËł¬ć#÷ĺőČN˙‚ň¤ĎěRÝĚ­ˇ­ŻŽ\mrö*ÖÓďĆ<=ľËŕY.žŮóßłX§5: ?ÔÚ:ýŐm‰ęĎţ§ŃX:žú#´pLáwbÜ6^ń m°_ɸu^ńv[ËŰ5ňAŐ©ď®ß[PŽű3ŐިÉmŚŹ|ćůŽą2:<´+÷ÎiY¨ÇxM•€ÁŻŤ}ÉÖj-ë©·öOßVČ3k8wďxžßňO«¦‰jŐ˙ťÍe“7ű™çŽ/ţőó u<ĎĽbőü+(׍÷‰Íŧg\ŕ<Ż-Éo¬Ť5ƨָńĽřőKĚw€_ŕĚYóÜůý Z+I*Ĺ7jş©ż/pC'°g|Ćg`ĚŹsHd˙Wçź\őŐ}j±Đ·űCÇö¨e˘9…ęN,¦ňXkŹUťbęÔ8ÝřÜůăÖp˛ľÁWľjö‹&;Ç”ŽŤČrťĺgíE_+}…?Ŕ‰-SmFŁ«| íg<:9c×'ş“©GŞžÖőĄbíĄňAÜĎŢ!ľ¸˙á6'Ö°\]N¨çŠÝ·U5·óçô=7Q]WÓí 2‚|Í÷_”ÎI˘ź•ľ^5ű-“Ńč›k]Ď 'Í÷§pÉFk_mLëe÷-+—Űr%C–ăYô"ŢG,ő1ĂVűoŽAŚEáSťhScÝŠËôRşý*W?‹u¬Öęż—ÚgN7:Ź—űŃÔĘş%Á‡ř=ôšďĐËŐó'–wŽ}TuĚÜ}•éĄď÷9®Á¨ŐŔ‰6ň4‰;í5ô(óU€űÉřëë~ŹjdÉ=0ŐeÖţŘŁ‹2Öm‹µ?- 'ďĐžOÉd%đbÚ ;ë4^çů¦ßďĐâ\(`C} ]ük›1™żł.Z+×Ú^S:i~ŻÉÝęů˙®ďťçh%úźaÍj˙Ĺ÷?‘˝g(Öěß#˝Ř=tŇ!×ĺč?»:üâ…ä{Ęř“ŹgB¶oďý]Ăykë­ö»Ë㨍uđ)řék˘Ţ2íq_ĐłŻň«ßŚÄś6á𾓯ڠŔ%ÓS`&¬é_dňçë™)ť”ż˙¸r~Ě©ŽÜ·¤úĽ6_âYl#ş=tÖFę¸NĐň‘yÍ÷O–cO"ÖM×ěę°iÝŘĆŮĐK˙ÖýHÍ/LËĐuěsČ÷a#–¶çĎ™˙7çjnPCĹm °dóO­}'µ¶¦ÓذíÓÔAő{˛űžśP— |×ÎĽYţ‰Ż%‡¬ëĚŚÔ7ńgŹě˙ÝC?l¨Sˇó[RýĄ¦T@wçł_f¶ĽřŽš•đ3ŻĎ๯çÂçw‹NŃĆŃtýĆЕٓ¦Jń ţxÄŤě[e˛ŰZýŞŰűrŁţřÄzŘĂŹěaţ yµŮ0Úń9'ďŽî×™Íb‚Łç·ö˙Řđڵpťśűo;§Ť÷ü… Çg°ě»ë<ŁŐŃŤqÝĆńĎ%““©óĚń‚ďű«ńgg‚/¶şRüÇŁJw3¬~Ówo/=µňŚ”_Z#U Ü;´'đ!ÍI<ÎJ±Xeź_ý¦mŢ˝ď[=߸÷z÷Ʀ }“M 4)Ф@“M 4)Ф@“M 4)Ф@“M 4)ФŔ˙e ,¶śÚł8UŢ|Ó+_¤˝ËSŇuŔĄ4ŃzřŻýmé˝G÷çŃÍäDűŨjLw/_ó ¸ˇEÔë=MžiÜÓŠ»ŹľëÎn°x/ĹGő(/ÝÎĹ%Ś=UjއÖíÓĽ˛łß™°ćďtđ5ěc7ű}ţűч+Ĺ^{đ4đŕ7öT[¦i?w=ĎCÎ9cď†= ă\—oĺű×c;ŮŹô˝-äăčyĹ޸ď‡W˙Ä{bb#˛ďÂvqěMr/t^GĽ ‚óBﻬOâI7Öźř›â;s4pcp :Äý\á/6 ťĄ=ÇÚ;[(Ś-Ţlç*|OmđYů“Ę]óó¨ŮÇă»Ăő?Mn•Sd6‡1Ż˘ş_˛G» ďýüđ \á|&nŐe;]V¸ę»MČşňńұ ľëĽkť9°Ĺú ]â¬až>”ŻUµ/ĄpśäÓ¨–C™qőŇ…ëJy•{˘Ř°wZĚ ßsYŘöŘ‹†ĎĐĚy7Şśŕ§ô@—ÁÁ6ň©,NZ*çŘúćľ596Íă2ž€7đTG>]dxCN‰-zĚÔl§ÓˇP ^;ÄsCŕmíé}„ť}ŠŚ€ÓĄ ÔčĘÎNž¤óÎ_•žÝĹóč c¤ÇNOţëe×’Ď礧ůŻŢßŕËëxŕuGŰkózi«‡LĆo™XmÓáě»}qPÜ‘ť™íż4Ň}%ι޷GľOŧk ŰÂ/—šĹ4y|×ÍC—&Šg¬ŹAgÜq„ah‡\ČíÓO-kgë<á˘ĹDë<Ň”fÜsLáţ–C,‘óíńŰʿܿ1ú$YŕS09W<ŻňEYžďźËÁšŐČ`läŐĆń7›}ÚxÂÍö\_ĺ+–“2ő‹Śfňăě÷čúŻ©VKaăű•ş.= ž;ěä z.ßą xŻWĚ YŚţÖÖµeä>/ű™ ;-ëüܶ âZŰ·:«#˙‘ś5xM˘ú+)}·-ŢĂh Ú%řŚľ„ěeOŻÄ;Żi^Śźa7iYg¦yo[[_¦Z<Íń—úP× ^ŹcĆ>ą˝ćIçsĚ3€»RôZ4;Çg<žś+(^˝Gu´ŢŞłˇżŢą}ú—Ý,ţ›Őçâyh…-†+iËÜ>¸.űxę2žŐ± ¦sWçŢ–ó ÷áä1¶¶V×éśÍŽůţçŐń÷x h…ţ*¦Ýěaŕă”ŕU9/—GçßńżŻň>«9„-đ¸ĎL? Ý šŰewü»|0†?€¬ú{o»:˛ŐđSŚúşö™o§ç›űŻźŚĎé6«`ăU^Â=˝}ŞCŇżNy űŕ=9wSęD~ϡŰNżheyWd'owB/‹±+Ç/O0_1WŠä (ÇhŹĺ˙ÍLŚęä-°}1n#‹´ߡ›ęS¨ŢÝsućh«µ#±~KßëTŁcgçžŢ{«®Ö“ ˙djݵ…?Ľ:Ň]šz_)Ć>`¬Ósyëiŕ‹vˇeČá–ľÓĘřeŚSŕď5-˝;Ő2]_këTţÜéűäŕĐFŁ˙ŤnĽŢpQÎťęőśşaoË=ÍţÍLşµndżť4«}·zţ«öŮsłń`eíXŘc×h9#ގŻüżt,‘˙°~rîéťJDŮ ř·očÝ ]ôŢBaMőĂf‹•OŐY¬}Důż›Ö«fDš+ŞĽoĺÍž_J¦Î°>ú*?I˘6 íą\‡n/›Ír¸›ŚŽ´­ůţb‹ÁÉo®×7ýůmϵźčŘ>˝ŐätçŘ»tćő+ÍŹmlľĐ—źBˇmćÖĎNOßdüä=/ů߉괕–ÖÜŰrv’Ď7Cv ĺ7V¨†ÎĘLNÇđ=km/IÇLâxőg8*wn­ěŹôq{ÝŹ:=Ąţ´CŹ÷Ôó-Éźš.)WĐžOŐFĐówµďůYĘkžĺśZŕŔ_z.sŔW(ś“ĘmÜËůęőXłb~ä}ů÷É×N“ž¬µ¶QăźôŇ®đąźÄŰđgWĎ{˝D>‰· ĽVÝŠîUµ®ňśc­Ś~±‰Ě[xĆířJĺ}‡žř5/çyß„~Ż™xÚ†c OWîň˝ĚÎ*×N9v7¦ücžź=hüây^Ű;RąXU»f­ňwŇ1+üLÖQńořC걫1&x+ËűOě9vKő~ʬŮůxŃ!Ď+zRM1ŐEÚµNµd VŐ–1^ÝzzÂڱ.ÄłŞ ú=w]VĎŁĺź·çTd­ÖKëyăO¶ÚTä>@·Ĺ–w—Ć h‡ĚcwÜ6._ÚÖńlŤ #K{on3]ŢÓŰmWô]cuwűĚZÓá˝-·văř7ű}RžUGZbŚFnče2őNÍG¤üĘ—w©ţŚęe­ę\č}ćú olČ“×3ćwÄłaó]Ú¶Řcuë|Nľ|ś·-úY¶ř:ŰÇÍ>¨Î@âőŻśßá©–[*Çô¬š˝—.ük×đÇĽ¦VŚ©ü†^Ś/Ľ¤!¶X«u-ôŽ›.+vířÂećĎŐÚľßµ·ĺIř Č2|ŤµÚßžÇáź–űßuĹŰĄß°ô|UGŢk6j米”'ÚÚÖęO6ÜŃvß®ęďUÁgô9üš€«Żň™”Vc‹—­W ŚuŞ·Ňľú쏤ĽNľÓt®Żš\;˙6Ť‹éXmĚuăxą'ěůüŔKź¬m˙ř¦r2Ő8ŻŢlü‘¬Ď†·Mľ¬Ľ1ĆňźwMKn®´ßň°É—9%˙yoË»Ť&í3ď±52Ú ďsj,ć×0ňĎěű™‰“ćAaݱŁÔ®Ł6ÉŔđ§47¸§á:ľPP-†Y{źL˝qĂIó_•?v›é6ôó<ôÂ_{z7›Î¨W‡ÖEě9~Ů9ö‡ť«j÷Şű\ő›ë—°áčpđ¤ńŽĺ}Ę`Ěěucž®üł?Ń˝ĺĆ+ÓqUó„T.éý¬Á_Čw®‰§ľľżtŚÖÚ‚ę®˝$}žgvL»^˙®`rŚ ĺ{^Ů\Ę×Ęëňî?®Ŕ˙€xůs{Ăč'r¶§÷ŐĘďö37¤cŞj.¬Ńűž#Ęű[á—®Ş 6Čřž;Źł1 ň˝é7d9ëßd%Ą·ż2˙3›Ă9ĺ÷ŃŘňt;·Ýyć5;Ü禎ÝăU{fŢěŘÖÖk6Ś/<ĐĆeč‚ R»ÝöGÝbďeăřĚ]5{¬jă}ŻCőĆ׫ŽEN?}Ţűsŕ~|ż˝÷gö¶¬JçžSŞź‘mäĂ÷C … aĐneń]ÚšăŹß)fUăĺÖţ§«ű]ʡ/3NĐr ţwiĎJŽQŞY;+öÎús»Á:–Ď!zU›9ßĂţ}ÇxcČ{Ć\íW*‡ň)éą|ß>łŮčŮZý|—ö=ÍźN~nó”h_umSšçű_ů÷iţů¦-÷Le*ěő[€ŰanÝ–gëuČfČ'±5ĂŞs©:]g Oíąľűóý:ť/˛Ąo"]oä7~ĺ±Ű_‹?ţg‹Ęűa1^,µ/y¸yŹ˝÷5ˇB!îuY'Žŕ‹Đ¦ŰőŘ×W‘cŐŻTÝ’‹Ť¶î@Ë‚ň§˙<Ą÷ţŕ\ůŕşĐűJéÚçŚ?řEý«3ßYŇ™&őyt&ß1ŢqŻë¨C8GŚ\u¤µÄýŽR§Uľ˘Ú7źËů+ŹáţZĚŹŤáďcS€?ŕfŚÉ?K˝«oŻÓŘľŚYŇ…'©`Şćă`ŐčI´·żśń|‡ú}ŔĎš đcCąŇ/~Ľ‰ZXÉÔ+đAí>źłp—ó}rîŁZ÷Ľ¸>¶…®şźUk»oĂśÎűäŮ#ó ~ěEČ/{’ď¶j-lMµśüSζ˝[ńN.ľç7ŇzşáŚ?ďó§Qť±rź:ľ´śµ{d°m앺bč'~~ľn\ű̉V‹"› 1>ÓBčlŢŻ ÜhžúZ€ă«şS‡Ůn5â™˙´}zŃt8đxUëŹÖ˙c,Ťűń»$ďőquÔćYÇ·éů,qčgm3¶W4Řń†÷¦±8 ýÍ®řÄÜ îđ“qZ{F`ß¶ř°ž[ŤAÝŘ/ľßÚúéëÔŁŠßi™‰š'|>š_Ś]1çö=% uůÔ>—Ń`këD˝VßgżÇ}ţÝÝç˙ŕŕÓl<Žů=>6śqĚi@M–JVť>>×ţÝs'lcĄŘ)ÚÜ=_ŚĂ1w ˝^ĄăťâwlřÔ¦~Ůé¬ňÝăýCÝW9×ä`PsÎýßńżë[Ő˙kXűůß…]›&šhR I&šhR I&šhR I&šhR I&ţďP€ř‰XŰ ¬‰)笠řWöą¨ŐÍľ]|wwąŢ\Ďya-ö Ů‡Ź¸‹ Áťź~—áĆ^yŰě×°ÎÍ_ě/łŻ“íŮťđ3đ|_‚őyö"·čPUö¬Ën{ßLă¤|ż†ß 1H·öß™ž•±saůÝórŹĽ/¶sµ=ţ4ř95{f{‹‘;FÎűvŔ1ŕ»qüß-ö‰Ř‰8Çžý,~s9O§#ו9˙vy´S_ń?ŔDn[~~ń˛‹Śs®q‹ŕŹLG~ ř±źĹýwé=mp#qcÔnˇmߣvůXÔ˙ô1…c{<¦¤`üóş ΓŘcŹýuô\‘ř.t!ö/ťź…®úyŘ:F1 –˙b1*“sCéžîĘžťy 4đ\ ŕ‚/í3bűŚüppŹăFűţ2Ľ›ďéż‘ÇLśoűĚă Gâr\/ĽMčĎí˝÷Ö~ŢáyťrůWĚîDĽ6˝NĚťP&.U5* ođAV‰ŁAWOľw~ż@ű­đ|:WWŚ=YpFźi—řPžďO)_xçŘżĺöä®Üyh_ť_‚ďI·IfŮO…'°ŢŮrv÷ŽéךŚF+{Ë๏äŇ\?vť[± ő3  QĐ˱ÝĚţ´ďĺśó<‹áäÍ=䙹ü9€Ľ"6fMuw7±^Đ…xĆ`Ĺ•=Á¶EL!÷Dţ ö+b/ĺăĄú1W˘ĂćW(ź˙×KŠă„ţş-*8§{ńpÁî.§Uv§±nŘ2ĆZp |ÜďpžÝ<ÔŇ'ł}ú öYgŞZ:çŻţ»ÇŇE_żŢĺý縬č%ăIÄ2#|Ĺż€ČüfÇş”+Ő‰\ Ź ŽĐ(×é¨|¤ŇŔđÇş’©/Ů~|çÔ¦tźzOďNł‰ły¬boBO˘Ťbí)‡ÄžE|DČkÄ…8%3™WŐÚ0ľě}yWWűĚ÷ĚżBOŃeä›@nkŔĚą®čĚě }•ŐĘ©˝,9uüŹĚ.ćďÍżŻÓWm­ü+x±×÷•őöĆďËľç]ŚIč®űa…8#+f“ĹwôŕÂ%ćŁĆÓůř|ç­˙‚ýŔsĐGĄCÇ4čE´q°×g ^c_§§_^~xőçݍ:–ŠŻ~úüZ skőç©l&Skx58řŇt!řŵvfÂdš::?Űr•źýÁă4íŔ‡•ź“yĽ©É r%”żiç]#Ç{[.R|ý…Ęޢ3S=/RçîľWĚíéÚ8ţ)ł·î“¸ Ó3ö!h¸éś» Ém÷čڶ赆K$łpfťŹŢFŘ— ›_Ł…ąO"Ž‹öC&WĎź¦óowŹżŘĄz*)©[ÁŁČ6ĎFĚ9Ď6Âęxěú¬Ů©Ů÷v(Oiź˘á$ńĽç,ćźv\Îice^o©Ď›ň|ŠqŞÖöEŐzOÂř Ďó=ŞţŽÉçöéwwÎ|űňDůSĄ9ĎăüŽgu&cCn‡ęÚ¤ú23q~©:rmrŐě ËĐ:˶׎™î|x…Î°ŻŽŚX ˝ß-E1s»G}’‘úîĎ÷ßix«®R˝–^ˇ `˛$ßÜîUlYJ‹s“)}7şyQcĐn9Wü)Ú ~ŔSŐŹJóÜ™ň;4Çż¦/Ĺ™+÷±Ąăš‰± ŰţţĎĎ fëŔ|ńyf©íĎĂŮZ=YyţťĆżď¨]čĂýŚ ‰rRň÷ćýÝü÷ű>pFţđ9˛¶FsąžŮ·ĘcNsÝĺO(úľĺˇľ»ş#·?Ż'ń”ćQĆGŐŻIeű´Ę5Ćżč›ń#bHwŽŤĄ~HŚ“Ś˙ŃŢň®Ž«Ú0ś·O¶ÜW)Z /ĆL|pĺ}Ąr¦±&•éĹ–7?f&˘z˝kë÷řš c5|g eľ˙Ź“óŠ5Ăů´Ę‡íyĺâĄt3ŇüܱaçɉP¦tô:˛ËĂÖźvŢbŁ8×8ľCcm{˛ŘrŹoî™|Ö# öUµ¶nĺ˝Ű8łĐËŮĹf_ ~ätűt%}?Óđ–—â[)gß oJóWĐŹ?|™KzŐ†ôËƇpy˙#¨®łuzĂ'úńş śŁůŤľ”ăŢŢ63ŃŢWů°Ť7“sď¶ZwŞ®ăśÍŞ#/HqŢŰ2ß5ľp§Ńjjö5Ş[q˝W{FkôVů¶V!Ú/ Ž—‡«?}“|c˝S»÷·žČtŽńF0tŻQÍ ;[~i8ßŮrĂłRüŽĺ?×ÚžŞ3­ŻImşŚżąCywh\«Ž|ŃxÜ>łW5YnRÍą »ckŠŚ÷qž|ŕÎŐ×Îň-ÜűJńBËigťůűéąOÇ•€Ž-}źJZ«ÇtťW<¶C9 k=oýçťäÂŃ{uä:óßĐă·ř^ů˙‰Ö;»VŐ¶Éďě1ŢĘmç·xˇ»ŚĹčvO~WŢV}ť8î^ţ5č+źł®Ďůó‰ŃOwTç­´sě•)O“©Żw(o]vxŔd`rî»f‡«°ཱུő1Ąźµ}F5h¶š˝ŢŇ—Î@-;¶nűôżuěZemnmý†Ő¶ üu‹ő ÝńżŰmÝjůřz ®Ë»‡Vö±ĘńÄ~0fć}0ŐĐÚp{o÷úbm›Éöp˛&{h‹g¨ ľáĎÉu+ÇŐđRŤÇuň_SëLűő;¦W©Č\JKä á…l†ĺ39ďW _Úqź;śč$WüÜťcç«Vk!Ů8ţę&ž ·ź+Ż+ć.×ZŔgşµ7a6 X±»´ |­Çď•nĎ©~CG_ĺaf¤Ű]Şăc˛˘úM’•«K1&ǸµŇ8W%‹đú¶ŇőĘáä˙9}ź3™,Ö^”Ęfö«żsű;j9X´Ç_săÝ«j÷łv¦fßžřzB¦CÜYT­–¨Ĺž¬ôţŽtŇh~(ř'o±17 mźy]źă{®µ¶űMľŚé3ţó]lŘŠ¸oË©)Íd?¬_xčă‡ăŤ\hΞ ÇČ íě~C:ćE[Ë˝~YĽF‡Ţ!ůηĹúűÜĐůÖ_Ąř>ĂMľÇ†-}Oč”nPíËNŐşłšPŘ~ÚXş.äµţ ޵sę>öt|xz:Ő ú/äÁ}Ëđ …̆ç!Z™÷7ďđš(Ě]%ź¬ÇŮĽÂuČiĎűÁÁŻ—ŞźXmĽŮ5ŇÚ17Ô§ş•O˛:ĘčCřNqĹţÝŃÖ­4/µń }ć}fď*ĹsŤv­Őw¤öZŃGřBčsŔáß­ ®ůVč›ĹżSőW,Ů |Ü®PĂđáŞApu箑'vŞĆŐŔâlQ»<đpÚyoÇ.2|Oš™Î‡~c§j婞ړŤ&jĂćcaŔŮ÷/GŹ×ĚĂĽÜ÷Ô˘¶Đi‡3ă1>Éîˇ{+ç÷éúµ†X3 od$˙LŘ0hŔ÷Ş!U>79ŮđŐxe8ĚĚlj7¸_5@ÓüÄw˘ř„+ggŇúśô=ß~ioËĂö±“sŇúĐë`öééSmŻ Ř™µnđć=Ľ’ߦ:ă^s#ěq2ĹY Ľ|ţÎýŘhŐą./¶t—´Ćźäk%ű˝+ý?öŰŐ~ąé°j›Ő}©Š}EuĹŮ=0ěő€=ţ_ź0ž˙6őë´ňů&6ŠłBö¶<ÚpŹýo:ÍëÓ9t#D+÷ií{ţ8­µ¤ÚR%ö”X_ř‡äú±gkýóúîęŻmWuä599đą/zŤýĹŽą> ׍-šLď˝™:.ÎÓ°sĘů/S33ŹEČ ßi.Óđ[ţľ•{ďĽÂŇú«ęPßš?ŔúFNc^}Î÷źj¸`ďbMÜÁOó&ăá–>ź/Ćx ^kŞŮ:=űDÎßŃÍY\JôpčŻč"ýă­ž~™52Ţ ˙T6>͉í»l,ÝĽWku]F7˙…Ć ®×d5Z`“ů.xë†Ńčsék`ř/,'ťľ±Ő\±˝Á7řěµńCwó-Äw\ žËpˇ^«­±^ŚŤîďzLľ żN|óĐŽáëc“bÜ®lLËžŇ\2çϨ6śÖ¸7Ćuî ó{´|Ď|.ĆóďŮ8Í·‡÷µ§·Ýx±7ú+[_v0ăk˙¸î7ŁóZkkĺ°S˛Ů=Ň Í'żlzĎ=˙ó?˙c2T(<Ş÷óýWçěâáĹ9z ÝNěSđ[„ďĎŢEĄřűĄgpňő-ś…ÂńµaÓ{äÇ÷Ű|ÜFŻů9[±µÜ€ţŕ®;Çî]ö:Ë {ŢWyŠ­-`ۆ˙¤´{č}‰jŇš?ćr©żŰ„dę…uŰç0 ·Č4¤˝°cáˇyj{Çq6ŢŔ[ŕ ťtş,ű>ý»żAíˇ°ÝŐ‘Kěů€îŇ…ü⏾6•őříhşžV٨uĽgç`tűĘúćŽéŻö·zĎęٶ¸µs…5Ő˙נٱF°Ąďůĺ¨yr4áş­OĄľžĎÔÖĘb|¬âwd˘ÍÖ}\°áahű)w˝©Aî—öw4}n´QÎsřsżs/=­Çyč¶ę'ú­ń™Ł ›%â2ŕi>6€ő«üoÄŤyË'5čöővôÜ}Öŕ+JŘipćň:cźĆˇM§Žź¦sČž~·‘ᥬΙk°Wú|óţ&šhR I&šhR I&šhR I&šhR I&šhRŕHR€łM&çţ»Äď7W§óţ×^ńq6ÚŹŠ8(hˇ|˘tß–ýę’°‡ Ř«túˇÇjpőxŤŁkĎr^ř~ę©ĘFt2tŐă²X#ęĐpOüĹ^ôžŢ›Ś;Ç.¶Zy:!Kľźdđbo•Ľ·Ač¸đrśĐgî'ÎŃuÔ÷fy6öšá+q…ÜG®÷ŞÚíĘ9KĎćٱđřďáđţžŮF–k±Îŕ…]:7yFYµFŇzQĆ?CÓžÇŮ>óŁrčÁbËĹÄÓšÍ şéĚÍ\ś±â/Mí˙áŔ^x\Z¦—Ř`dC–ÂřrOÜ =~7‹wćÉLîá+±ľ.ŮoÇ×'ŢÎc`P,}ą™ÍëźĂí#›-˛ÜAlĽźńä÷e˙=ö˝ |Źťó ,–2{âPľ »´Ąď_ĚV1€ŘđGOá_gźńŽĎŕ-é“ćŻLžV)n87ąMgz?LqÍ?Qţí?Űx63ńödľ˙bŰ“źšÝQŢ=Ôgăt<¤ńĚí3q†–Ç;…ţĺńÉb˘śę,žmqĘů{B&řÎůč÷*Ć7ÍżP.™=×Wą±žëž?ʰ‘v‡’żjŰx§IıăžÔ: ĽT`űâ´X «ÇĎ+ÜĘ´¸9j˛đ_†s„ŁÝ¸"S1–űwÜ˝ňŻdę~eěNıVŠ]’˝+ ·=˝Ü1F3ćŕ‹ÔÚ~Ö-żĂpX=˙ŁŇ•Š; űŔKĽ6?K1ůu™ĐŮĐC[mśćް]ŰO,Mε÷ÜZ±ľcüZyŚ ňwé÷ôţ.µ EUŠżHőÚĺ=~É®láOe6ŞŻň_yXFŁxŠx2pŽqĽRüšŐ«~Ç•xpĹOš¬ÄłË˝^˛đĽRřĐ!Łč$sJńm%ěV^ĆŽŻ˝Đř55űTĺŁlOë ń ÷1ÎE]‚€»X{cąÖöÄî­­~ľwkőÖ†óŘu‚Ç<ĂĽ-ĆË|ßËŵńů}u‘ßKS5ŐÚ"[úlŁóŕŕ^ĺő^gđîyČ›í ź YČ6cVÔĘjŇxo:›®sjöS]÷J[^nĎóKČÉęů[M&°÷ŕ˛ďsWocą˙7Ž_XŠXlčĽTv‹µăz¨gř]ŃŰâ'Sůj­ţ{çŕŕ'6LÍžj±ŰŘ:ř ڧŽŔt5x|ńŽzŚŘh'9U>“+ţ‚îm‹gŰ3ĐOůŕĘĹťKőÉ}px˛’/?—{Çﹼř!áo(żĽzľŇ=5űĺĐÝŇąĄďąX·#€Ďř¤x1ăůžűBśéţŇßÂ?Av2ů_z×ÁŽ8ĚÁÁµ=ů19âŐÝžąěŻťyN™Z ô63qU·řk9Ę{#oŇt‘q&t±X{G.ŹĽP8¦peçY/ݰűŻŠv®yč}đď9ńńäŕq\ú¤ÇbŽÚĽh|aR|ăÜeץűxfçŘßšíÝ=ôÓş v¸ĐGÎ]äJ ĂđQ}](ß~^q“r#˙Ížk­ľ¨žĎŕý Gř\ł±Ů{ »ćń¤Éň®Đ8üMZ‚×Čp†Ź‰ţ ~¤{věËćOě{’ÁŽţŰw¶^ć°qď¶ô=\şŰ˛a|á÷Użçüî-}_Mő–ľ°)Đš;4T˝±ůvYđö–ó?dĘuF§Ô«mŹÇu}tűCú¸Ć™mÝÇžµAăĚúęČ€áŚ<÷Éw1ř±c|†vŰťâ´¦ú˝÷—ň×msę‹Î÷?$ý-đŽućÝĐĂő%Z8ř+ţđ16d¶Âk¨ůXímŁc­ŐĎ<*ď1ÍUźďź6y¦A~-ťČĆ—ĐKoK>Žĺ|o˙¦á\)ÎÚś ĽB %źˇçĽ|Q`tűrđ¸Ć“×>gf2 o©±ç6;­ …i{M76 zÜÚżNľá“şjm珕cdWęn#íc¬w'ý`—|ĽŤ^ …óŠ/îNnëî«ü§ÉAč‡?4ň\>pçű¨˙ťµ˛śwî'Ňv䍽iüÁ^oź~¦Ůěń…ŃułcŻ5śÎ÷‡._&Z +ŕ;śüąÎ^×UłWĄ2R¬ýÂř,?ÜÖM°!ĐżŹ>Ă7ĚĆ«ĺŕŘřlŕ©5Ş<ĂçĎŇÚžčý6>Eľű„Á ŚŔşĚ„݆÷ŞM¤|ö­]OXLőwf⤆š´}ýŘb.7MkR©ÝZ9ąÎă úÖ×™Ý_†wôýţĂW˙+µ1“s=©Ď¸µőň.Ď vy$§>±»áoŃßöéĂU~zŠłě¸jS=/mźűň,p0˙v|ż’/d Ůö\6_ă ý©3îWRÝ.óµTÓŁC甾Ě^]Ż ¨:qÝȰŰĎŁ†Ŕľ méüó”V|V˝˘®§V~búQk«ŰÇO—f&v”T×Čü·Đeî_éň/ÜČöUłOMjO»—Ń~zú™ĘuĽŹ|ëcS]Ü·Ď+Or!áwŚcÚ×0śŠµ§uÜ<ôŰŞŮŃBý‡TÖťŹ9Ű%#cč7mnmťj}ű?đođIBgĎ+ţ$ŃůëVc©ź¬uăů–ľ U3ěá)ßÂŢŔ—ŔXýo_xf&vŮłă ×ÖŰđ{#? »‡ťď_×Ćľ­č7Á§BáÜäEÝԖض8]ę«ěÖzČkő÷·Ć§Ú¶żęž™¸XóË÷ ÷ď§6ś=ŻŇaŰí5–Ĺ–ůµĽ›śűV÷Ţ–KÓg÷ô~¶äôögĂßÍĆűĹĺ7˝ßuxoËsLŹÚg^f×3†oKej`xCúľŻ˛±űÎŻŮĂ<8żZŻ[„‡Ý©Ž·É‡A3zźň–ľ[ gŐŃ7}–Ě›oD;§vxNrm×ß˝ďĎ^˙<łačłď§†\f×°żí3źîâŚgŐŢ0ąÔş‚đÉîĂ~…í ?x¶¶ľ)Ő>S 2pćs¬;Ň–űżŢćtZS€»Vîőź:»˙ [Ź'„/ř,¶Ľ[낟‘?˛Ľ·ĺŞcń ăŃ–ľt×nżŰă a#2ÝÎ`eîÂşÓ1…ŹËŻ{„čđĚ$üŐ>N÷©Á{89÷ Tľ˛VVćťöŇMľčřc |ŚE­ŐÝÉřÂżZŤBŃFöô“ďÝ×°Đkä$d›9ËŕÓŢVR}DŐ |@ZŰ1řŘW)—¶ôÝek¦Ř€ă||§VÇc3ťX4ZůŹ'ż´ľÖç2…˙Y9÷ą†×Şšź[?ß­ÁŔ‚Ť®µýXç|(‰µjŚ-ľ«sSćD3×5Ŕís—XS9Ĺö)X{BžŔŮXPí Ő|‘Í8;µu Ŕ®č‡L/踯WyGá{¸Ěăk“ę40ÇłqOkµÜ­˝ŻRV{DsäëžX§ń™˛ioMŘ«„ˇSÇ˙çÉôľ$sĽ}.äďcŤö7Ŕ]ç o•űŻZŹéÚÚşúŠüp# ă וvŤüŞ»nÓ}îăwęˡGůń*d{_ŘÍ7µ¶Ók­_—ĂV«6rťćŁ›Ăopm„!pĺŰĚţ žľŮÖÁUűVíř>8‚sČ ň­˙_ÎN4¶h?ůşAĚÂG ż(dwËŤ茔“RťËŰíŔßuŐĎ=Ůß<{Ç÷Ě%/»řáÔtą&ě)ř„üĹščwúÜĄzŹÝµ¶oٸxFţ·Ý?úĂcjö?ŚÇŘç·óú ˙Łç#uŤ9°ŕ!{ŚEĂŰ­ŽŠăWPťż×źwî̧8EëóŞ-žÚmě=÷`Ŕ›=«? éHa›ő{Ţ[îQF/9ł§Őjk<‘=ËtuT6č#uyô=dj8ĆX…”żĄ¸°›’ľĘ…čk{ôávľŻŞ…˝Čú>Ňď¨ ‡ÎÁěNđ3lÜŞÚ˝4/ů·rčsŕ,ľŠ÷ţšÔůHřćţlÁdćK¶ţräe:`Ě_×TOLb}±µřjÜ“édVCIă—xďó–đW‚NQżť˙µđŇúůŹ®÷żPͰŕcŕÁśż-đbôŮvYp{÷s-ÖˇÇĎZ>ýv}ČlR_ĺĄiöĹÁc»ÎOqĽčÇ×jýs#ΓwŢîŹR«jďkđ c­٧ú„ä6đÝÚúíôŢń…GÔmŢţZ˝{|79W+Ý®µŽ<´¨–wud¬Ěye™ymę»äď˝;żßx‡×oĽ`Ńëîúe˘3ş9ËîîŚWö&šhR I&šhR I&šhR I&šhR I&šhR I˙=xŐóîÚô“«ľjq۱Wńč/lRľČdĂÚţ–ľ÷”9·Ś¸öśďűqKą¤\Ĺs}ˇçz°?É_ÄŰăTŮnkřmí›ç†8OŘó=<öß÷4Ééň¸ˇĄ==źOú»Îžl¦qż-ř ´ěW’×±mńß’Š·ń[ä‘mŕ{ěUźp×lO÷hÁ6™zKiľ]}ŻŃqŤ8źŔ'â.üÜ^żgjvŹń—Xhđ$>Ů&~•?öî©iďŮłĺŮM?ą<Ýź?’ř+NÍâŰ‚'Ž'yĚžĂćx~Uxe1%~1’:GÓň©Á9pšů“´K|TĐoiĽ¸ßuxţsÎ$päqföÖ]>ő«böŕv*`včt.¦xÇłÄĚř™{~~.ĽŽWžĺŹ6‰×ľöôΡ˝Z·5YÜřčć8#/`$V„šIŕq%Łî|'6–߸\&ďˇ<ćgw&S'[ľ:÷{ÄË}ř^8¤vI9ňť˘OwčqÄŹrńŰ>&¸lĹűCuF]kőštĽˇľ—ÎŁ6^şÝ†Î¸68xŤdą~o™8Đřť+>FÄaĎĄ«ĺávkŻXűSĺOÍćĺă×ÉÓŚóic đëčfüşCÁi|ôČ}·YĄ©/YŢ<đÁ~Ő~ńłT¦ëyŔ 8ă—#çxąŽ O_čţÚą÷â['2ýrĹçiĹ{ŐHiă1Ä.^l4[IÜóşYĚţŕŕő)ďv]–ň×c …8C»¦|Ňô^ŕXîKăgŹĂuQąőEßł1QgČ^ÄŻž9ř@ë/j@őUÖôlé[ťvĺŞ>Á¦!˙ˇřWđŢ‘w#»‡±˝4őHk»}ćcjĎi ]Ç.*í˛ł6Á*Ë«ÝŰrWů´[Ż2š-ß™‰Ue|Éű)˝Ž±y Śýuą/†“)“Qü-đgě,úă»ÉkŰ™ߎnzý˘Wtk¬3>3ćn’™žľĘÇĘĘ×P®Úéu{áyĹNźĺbš=ýŘ/ěăLŚô10ü/&kŕäńóž3–—so%«ÇsČŁűĚžgíÂVśVy†üÎź¦ůîŹgx…źçsŤBú˝=˙#{ąďWéQ’L]drďéŹyp3^=uiŕÇĹÔf·Ďśú‘‚!µëaˇAŢ…^+6´K>¦ĺ>Çďóů$çĚ9ď9çy~Ďĺ}ß3ĎóĽŚKx&ş-±oľtv`ůÖ,D–Ę\–Řjđ6ÚńM' %&ăk˝Őéľ}´ú;éýtělö]ť®vMLä:¦ÂőťłďKőÜđ“śŰäsoLóÓ,§)ŁĎZŢż­áÉ}‘´kť4˝ŻŮ٦ڷd=Ü/ńť™ ź0&ÇVĚŚîvjĽOšĎż{x˙˙NčV«ĺřH‘w‰Z‡gąyfN şµ•1ž>Wy­M~8¦Ż¶ą˛`#µhţHęTţkZ×{0}°ńËŢřUůë}ů_ý…Ôď¸8řoę(.­cvă3łłěúű»żöLúV/r_0@÷ŮÎ  ďy uâŠRĎáIGRwBź­có±č űö‡Ü;g©ŁF­ŽŻKmĄCÂTę´ěđ‡Ý2źf‹naßÜĽw}Úrü?ăŚ3Â{HžËłĐłđ'ýX@łľ'˘…ŽźôŚ\}’Ô*193h6^kޕ̑…V®eL‚~”s˙Ŕ<űÉRŻ"ťOnŞ=_ňÜ+R7áÔ?š14ţ۶Yžő–/lMîlˇăʉ§¦}ÔŇgÎ÷ýO°;łeóÝ­ó¦Ę)ť˝;f®˝xÔ‘Ąřě`ÓµÉG7ëKf>ça#řűRü¶fýĚHúŤ-ń#K©řőżóžËdMá«™S>whhŃł¨mw—ůd‹Ëç_ÔŠňć~Ř ým)>OĆX‡Ĺ2fÝ<ß÷wé<#®ţ%c×đFgîěxVÂ{5Ž#k˝Ż=uů¶<}‚×®Ú¤ÔŽúłä©•SňĽÇÔq´>ëâéďŽQ+zcAjŃ<ĐĂ -ťO«o‹"©ű°Yj¸>Yjh? uMăĂjuj vËď<č˛ůýV —ŹÓěNôřč,'l±ľ•â­ažaö†ŤnhěĎ÷íŰÔ,Ď›÷·řră5{ >ěUÁl_xFaçÔ[“'ŐNű.ż|Ht ź…/DO¶TŢ·¶,ëmďW ~?†ĽÁ[ǤĹÔ¤ä|†żžŰÓ±3ŚWUľQ “wú´S Ł(×xyOeîc©Nsxß”Ú wÓ±v–WË=d đÎ(Yž˝ŤŹ{tŕ™»I’”s—Çgν9ĐĂňS“Źë?~ojŰŚÔÖ¨g0-Çő˝úŇč>Ľ×úlô‚~xKĺC)ż´5lÔ?¶>ü çř“±i°!îsĹäűWDÎúlő™FňfűRZ´•Ž/Ć›ď‘ĐׯÄó˘ëÚFiÎć ăR·ĽQß‚z¶/|!赓úÎÓťSωoi^fŚÄîCŢ0ë1.+µŤ«ďMxĎas÷¬Ď…—(2{FÎŻoę\îříŮüGçć×xĎ˝{řâŘěÂúúýÝůúčeůˇˇ? >-}©Ě}łŔ˝[1^)^łűŞś3›?[Ľ†ľ„¦łĄoi˝ٲŽ;Vo„vŤî/H-—;{ŕżdzĎ9™»H˙uWŰĆ–í71ÎË_Z;ÎhÖ=ő[Ę7Gč§„NÁ]ę˝áě`ĎꏵÍěŔţáÝ(çˇÓţvMśŢŹ`óR{>ňÎŽOÇĽ°ëɧf˙óo9ë»pCÇXCDďąň˙‡†*ď2fÓşĹřăůšŃo|^¨§clűťuS­_jlÍ$6†xRíůé:@ĄŹ\ÄO…ëMÇ _Ćĺ\wă2& z˝š<ę`éa©Ż±ń$¶)µŢz™/š,ŮnŞ}Mj_x‘ńiAý1ňćŁr·>Źqrä]0úÍX-óuYŽĽÓ;¬î}o‰Ď‚fü“ÍżXŁ~Ś—-•7žŤGđ±w`ÖfSíŕô=Rë{QîĎ\]Űi˝ĂŐĺséÓTNÖsVtOdű×ÁV—JMżŔďĆúŰB˙ŠŚ‡˛şł:Ćh˝ďx¨źdsrĂ ą˙—řľˇˇ×$_=műăVZîľ?ß·!­Ĺ»µëěý˝č´Řţů‰ÔĽ }•ő1ĐO}_řÁďů ôIZQű)}ßĹył…µÓç»ó]˝0đcňĐů±ţžNë\ăm‹ú“¬Źć¬Ú{CCż'ľ»3ôŃÖ}¶ńŤÖˇe{~l¬a8dTŞ-č¸-ŠĐ_닥Żję«ţn©×h{Ţ%e÷hŻ˝±˝µĐĘŻń?>ęYµŕ×8o­ů5ôÜ~—¦Ż"îďÔřÉé<­ÝxÜ=‡Ő.µ%ůýCěVĆ­ň‡×˦•s޶ĺ7ą±®ţäĚąő]łcSíŐÁŻ Ý’§&ąţ&Â{ ­üS±ü’‰Í:Ç{Ăo˝cýbů5˙RĽ]ŢëţíşŇŰű»,"™ľż¶űěšxAËÜËŽúÖpGŔpGŔpGŔpGŔpGŔX[FţŽWtOT”â?Yôő=µ[Ç%†-đÂď5Ä l_ŘŐüŤy1őú{ť¬-żWo§q)‹Ű´ë· łyâÝ Or2żÄŽđ;2ńťłŻ<ż2~B|Zî˝!ÎÄb'řMş™?´uˇăż%çň»á7ĽC$δÝříŞ_ŢŚ­Đś~űÝŕÓbaŕMk×ß"ÝŹjĘ\㠹ή˝N~‹ĺwéÖ^‰lýŻŹľ§×rő‰ €nYO4ÄŻ…¸zᕸ"x –Ěň‘µ‰¬B±ś ±üüö¬ń$ˇ®A/Xˇ+Ä,l©ö±'@lňE†Ř#Ľđ»Ć6Ůoęz59'÷{«´oĹŠ=·+±q‰Ä»†\q‹›ă^Č{íůÖ8'â9->Ş•©ŹT€fňNúylůË˙e9ß\cq2wt?%FĆŘ:Îq0˛kXsŃ0[*Őů®ąG“}Ąăz±Ýrî©Î˨Ro…ú §oö¬|fńîťłź >ĘâÁZń›¸.Ř|I?âI5&iu8•śŻŢĹz«ëp™OVžŚ–ÇK~öGeťd]ç„xôóńç­XŰšM曑ś¸T.âŹC_†ü,÷_cJĚÖµn‰Ń-6±ů–ľ×ĘšeŻ ľ?ŠŢKŽöl6Ä3XŰJcaíĘ•ŮjĚô¸ôE 6fú9XúTkŚrďÝR96?Öu¦Äq~8č9ŘŻč űv˝PŰ“ŘńbŞŐL¶řHö±l›í˙_ąĽß´ţĺ9Uć. ňÄ‹śMěź\<2•3χ·ó…gŰ7Ý€bUG”ŇÚä†|Ş“‹ŹIČ}°q mÁyzâCĂb%ă"ÇşX6ÓGöĄ6XŕŤńöü­=ޫӱ™r˘6Źlłµ¸ô^ťł‡f~°(†¨ľKžšä> cúj°ł:ôśű±gĎş˘#®O\®˙<“çŰ>tQţ&Çööś;şż"ţGëă “ÜCíPsKŐďßýJxŰ'Oů0Ýâ^ČźľĎt@ôd‰]Üý~żŮő]Ř“¬eťÜ,<š>Űý Óčď[HΛylS~aL­ö(ą3äHüíLJźht˙,¬Kř)ÖÍ©WŚhĎźöŮ•űÉśkŮů†>Ë{2˝SŮdňŮĐčNmJĆGtŐG7ź8ô‘ĽŤ‘ŤWÓMG.˝ĽË|4ÍćýĽŁćĂą[)程Âú¬g›3Üîď¶sv(Ü—g W•‰Ö)Qzł'ś»yvŕš”ŢĘÜć´–öĄ™?Ëć‘*»¸úO!î3×xhđ×#Ĺ×ĆŰC6M9=ńÔĐđDĂt–Ńq÷$×>ř0lŠçĚ‹ÉÖ×»·Ö3<5ž <ź–űNłŻŮű ZÍž-Zr굲†hŠ›ŮŽńqĺÄ»CŤDěĆt~ąÇˇőQĆ[* ¶đ.}­ä-Ź…üF;'Ďßv|é{=óźýşÔęxĆőŃ—ĹčYxëş©@-óizŽ<„÷?°{ř­GÄU­i€Ncóđg> ýf_b„{Îżn×&˵­Ź2źő"©Ś§Žťľđś`kđ;ß÷,É寄Üm雏ltď›?¶|iĐh4]dLżĐžÍŃ”Ň3˙“Ösáö_:Ž3™b[\k~Oő`ą8ÍîîđŢ ˙ÍćOy‡Ă3ńoÍŢšŽ›˛+łśhřăZĆŢ‹e<.µČŻIök”ĺ=É›Ž8ąřěTŻí>Ô«`<Äwí·2˝[)9s_ü/¸‡1HsüĎś.EŃX×ůφŻrçťµůo“—ÝKÇ•QTν¸Gj"9×&ĎÎ3ŢćłuřEźtś+ľ0ŚwÇW¬6;cyÓ3ĹUýůŢĐ1;đşx°tfĐsĂ}rfWŕ·(yűC’»ťÉę39aăz.ŠöśóJÉń?(–zpyt[F7¬=só{Ć˙JŐcżlj*¶wrč5ö c]ź r[NÇÖ"S›üTŽź‹}{†f“3űĐi}-|`»‡Ď ý»ÔWZTOҰ˘˝Ý‡:‘č˛VźŽ+ńÉęŢŘÝÉÁď›ö/<ďý ´Ň«ŹµV:¶ÎüUÖGźbEťłLkW¦ÜŰîŇ9«ďőÁšëL·µvżµZî­ęŁů_Ăěo”ľd×ĶŕŰoµÚ8ďřiĂ×0.^R}íúé 2ź:9ćÜńGŽu}FÖ}ďLŰGŃE…fňĎW§{˝×ęÔâÎü†ń€NŽŹ+Ô&OhŽw•ÎÓ§–ž’Ô&“Tď9Ž}"GěŢń‰µÉ«šm“ŢluĽ«9îลrt ň»žÜgą%Űz?Ö·€žMľłŃĆ1ÚÉÚÝn{źËů®z!ű«ě•‡jźÇo];Zú9mL·/ĺ÷ĽźĐŞWŞ'­Ô­Ěţ×/Óş*Ř‘Ťąío}ô÷  tŰ9Ĺ$Фž~Ŕ‚1™ńmö!´o•=ĺÜűÓq*×™ŻÎ56Š\íŁ~@y·c«·ĄŽk:€·ÉYřŢ2ÝîśýśÔŤ+§:ËśŘüŽPšÚ3To_xk¨—hsK°Á?ęZÇTř˝jMy†'~›0ž7‹ť†>ą®ńÇyü¸ô;ˇ/äČqb. üťö{Vű.’¸Šůđ~›ľŃڵöśëIűŤ•Ędcüę<4«“$ăł0†´ţ92öŽ>ŘüKę^öʱ°ľS±¬őšŰ_ŁÁ쬫ţ Öf ˛Fnđ´sęËAńŐf—ňn46ťŔ÷IěMlc ôĂjX`Ôłç´ă¶«^•Z_Oc čÓŕi×Äw.¨ŻŹ˘¤ú—ażźŰoĘü6ÇďSFçwâËhCěä-ďFÄ[sZßÚ·çöÍa] ‹E%¦†|Hâ%™gţ#µeKg‡8@Ť9iĺ†6|´-ż˝ =˘-ëíëďëŰ+ń^Č‹ßŮĺ7ć–µtŁHcG”YctQ< \rŢâ}Ź—zü^­ĽGŃ[rŤT?h»ÖŤ[#ÎţÚćú'JQknM}ô/ #¤˙qôk;T›JsbÇűšë3AÉö…źIúů§ľ±ţ á[Ď[żÍZˇfŻląŽŘ©í ńÔÔ‹ĺÚ˘K¦ßč2¶ü*®-Ţ5» |k˙Âó5Öë!Aîö‰YźüJQ͉ Ł’ÔĚËěůěů« ď­1 §úň‚Ś=‚^Hm€”lť‚ož14ÄşÇz?h¨ĚtśWâcńÇöüÓr=óŃřa|6ĎíŞ˙ł¬!xdJweî¬4ozmmIö·/âęIwŁ]–¦lŢCó؉EΚ«ůiJËJp«÷¤Î6E<¶Ô ˛˛|níGěٶćš~·ÚaĐG^‚ĹegרÜrŤK“Órű9’óˇxDAöŚSô»¶eĚbń˛Ą…6öôĺÝň<Í?fĽMşšŹQzăÎÓÎ 6ŤăŻĚžŃodĚő6޲8ޱ®‚N–'ťę˛éôŢjHś“w¶|ź‘â;â…Žw‡gS†găOyĽ-—ŞönOG/úhqŮĆł]g[©{‘Úł­Őá˛ďşĺ)*‡Ó:šą=öäű·)>·gOÇQÔZ´ć´=_b1É.ăČžÝĂ řX;t?¨±\$;G."9(qUk%ˇ<ĎÎł5ź·§ŁXxnČ'S˝:ľDĺňČS¸·Ž‘ˇć˙D1çöÔ-•ʦ9˝O;€:¦ęoĐoÍeĐ{ Ű?–?Îď9çŮ÷H·Ť9łĽ–,çk÷]ż_‹Ž%÷okůŢ&Oü'¶Ř1{¤¬ű‚ćZěŮ3ú*siMÚ™‡?ęz˛µżÖ~=»CXcx+zc±ÜćĂđč6ĂźbŃzĺň쫏Q:gf6©óŢĚ—$ëJnŰËř_ŻŐ±4µ~WP™{ć"Y~[Ú2†{bíŕp_ö[íIďµ<|Ú]ćúžÉłšr±Ł˘ß2^č“\úü[É{쉫_Ú,kަ|Ł›Ě Ńł_AŻę1żŻHŻŮÓq@Řżr♉ڱbdO—ű¤şcc|;·ś[ëkäâ«…ZŃ;ĹXéöň»âTV“|©Î ˘Pw9_<ýyy·đ˛‹„̸—Ô9Ś%Ź6őRŻčÉ’+Nî]ŕ ąň,řçšO ľ\§}ňX™ĎÚT«rÍ>Ą«ţ–đţ&[čsGŠďĚŹ˙ćČŮ_Ë)“—˝S€É-KÄö­?YňUR_ ëK§¶ßŕŢôý!o¶iS+Âóö…OöZíBëoµv‚b‡Ôśă;;Î_ÔO.t|włäRĹôĎ`f~Hój”0»bňq’+ý˝ÍĄ»N2&_tźÁŇa :,öúů9ń)Ęűx˙ńĄËîŃçß_éËó‚~!řf‹]ęř—úWÇ„~‰ăáY˙6*uUŢÖł©öŁEămülkżŁíŃź'ÄÇ–źĽyˇă¨ÍűFăAÖčę‰R?±Đęl"oä®s€űËŮ˝]ż¸Ćĺ¬~rň›Rî‰Ú¦ĘNňőă3çµyçÔľňŰ•/ÍŽ˘‡uŕńksb×ôUŠ!sĐ}7Ďő˝ >ŞrS,ɶçĐsÚÓŻŰwłí{Łü7=G}8ëłÂüFćőâc‚?㞦·ĐĄţMź„L˛ľMçHš˙8žÖ€lúąpŢS±ËúnźŰ}°Ó5}ĘĘý‡¶V>éCM·y*ŘSsZ,ŹĆ•ą3ů d[,ż-ýŤv­÷ă†czűă8cÚňLó‹67áüJ}đđ•a¬ř#ŰRü„çX‹ťó;fňiżĄľ]e‡¬L_Őđb÷I­ˇbůÔ'Ăc¬ëÖtl o`O(ĹŹX1˙Պᵢă­k“9óž‘âÓ­­>™ëęŁç¶ř`{Ë;‘„vŚąÍGí]Ő죳#©‡ëŃg®Î˙F÷ ׋-šž›¬éź,×|XmOR”8TáÓ>!ăĆ56Ž@_ÔF”nô€ďđ‹^۸ľś{MđŤ†çwNu¬ŠďjETt0ŘclÓüo°3±E¶ü©.fµ í¸ÍÇÍqoöŃyóé´•çl5›Ŕ?ü°ű ńΩ©tţŐJÓJďK­>‘źÎ{µŇ'ZÝĺŤcđÎúwÄř[ëłLGZŻĄŘ™ÍÚxÚxć^Ľgéś=şiK\±ş[×:ˇ ™@ů!±żŕéo“ęÖyÇźö9´ł9 űúďŃß=˘ČŢůŮ{ĹNńłÖkµĄf6c+Óő‘âµÁ·­ö>Ŕę3ěś*Ćşü•Žą”úăK_ ¶?Xúóý°éś űYŤöµâvŃs›ţDëţYߍފ¬bJLNÖŹQ”cčĆ• =]őÓÚâÖVyĄćk¤ÖóW ‡ŐNß),zúš~Qż…ŻÁďÚř™k˝Ĺž’*żYjťřÓŢžöqŕVŘűé?—÷•5ńW÷Fh˝~¸hÄ˙ŕĎůłţMÎzĎńţÉ™˙ ż­cĽĎ4ŰnzâŤmÍłał§ă±‰Ť-éSůí^[}˛ńĚqüąő˝Ky¶{¶ű–±â®‰ě˝]ó=]:G4úͦ±Ą©éP ÖŐčď˝Vä¦ő‚ĐŰRüÁÎ9FŽ6[ű3™ŽvŐ{S7 9ßę˙Ś_ę^hśż=me·ď:ăŚŕSńMđŚoš<@Ó¦Z¶ž{}ô˛ Ż'VĘt\)TžéĎ8ľcćłAn#ĹŁVđkqÜ–ÇĐęĎ8ß9űŃ`+ËqŮó[ăɡEăřôéĄö’ =Xúx3ľ-“)´ÚłŘ¸ť%±ßńÍď :~Ĺäö\ܬéŇč>(™ë{)ąˇÁ?¶Ę]ˇ¶E±Ľńn¶±Ü^j|5wďż®™'őÝĐŻę1ňwĚ\Kť¤lă ü}¶Ĺws˝ţ‘‡µ9˙µáŻ…<“ņя¸ú ÂěŔÁđ–«Á5ę —›ĂĹ÷›úŘÇ‚^““‹nc×<{Ť«ß)T§ç Č-Ëߌ˘±®˙É'Ŕ_Ń–<ŚŮs›}•ňË1ÓYg5ś3߲n[°ËQ03¬SąĽßč‘č3˛ÜĐxqŕ“çŁčc2oßáĽé¦Ů‡ŇLMąGmłÜ2(&ż ¦Ö?Y[¶ôőÜ ? ú˛Ľ|¶ŢMdŐ´[•ŹőĂ<ßĆ&Č ¸iŕ…}"ĆÚ ŔďäżINC'ąq\ŹlŞäŮčţyž{F–[nřqŽöč—Ţż•ĘĺÝß13ĽH'±KpŔżBtÔ&OJ?V5~?“ŻŹ~;OΕٮęd$|KŽ«Äî꟣¨cv瑇Ö&çüç&đ:[řŁťÝśáY|Esś…q×,÷gc˝ ąsëC Eraă+&?ÖlnÍ Ž˘§Ęń™fţ„ĘÚxdüfůU«˝Ń;ßw=k(ÇIę2üDępGrđ„&ä-닞^ Ţ‰ÎA”Ň}˘7H˝Źg¦kpÂŰΩ˙ĎcYŰXŽű%ŐăE˙Vî›’ńCŕ»3šˇ =Yż^ÖÉÜć"řzÆ5‘Çŕ›ÍfsŤgşKńĄA7¶–źśçY`hvlxÂ¶Ś®ÔGO*”sY ľśÜcS<Ëž-9ş1óť¬ĎÔ§m_řtÂDćUb×Ç =/ 6Á‹±$}µŤÉŕGut1Ął‡‡µUí(Ď´>ęJÉKë:3±ĽłÚäżť˛¶ËµÝX˙“żĽ©6)µS¬žŃx¨˘sDlVj“6¶JžúWeüuŐ"ěÍŻG'ѱĺ­_Ý_Ö˝1Íť)jmYoWt|k˵őqôeâ*ń‘o^1ŕ|ßż'Ô(Á_ę\Csą9'4…1‘˝ăĺŘ™swąY-&xĺÁX×›’ÖţÝ©Ěő%»&ąČpŹĹu}łů%>¤uľNŰ•řTć’0_güe2BßĆş.j©­Cż«ąźč{ç ^śÖ§NƨR×5Č ˝6Űä>2ö‰nČůĚŢ3™ŤÇ˛ó+ÁivĎ˦.Ič/°Iú˘Ë¦Ž¦'řZÉŘ4᜵ɮdOç:wÖďF·ÍKgöĎË˙gnfç¸s ¶č7¶„^ŕ÷ÔF?eążĺ Ď4›2ÚŘB~™~Řć†Ĺ˛Ž°Yk«ďúUŽđWýŔAîRomóö…·ć«ÓßLĺĚ=yď}Zn:ÁÓođ|3–›Ë˝ßĎćŚĆŤ/´µęµť‹«ŹëÝ9u{°SyxÁ6ŁŮü›ńvmňń-¶¬xŘ{#ř„_kĎ˝ő™{§oĄŽZżWoLÇşĐnĽÂ})ňÝľĐ+}Ů3D˙µV±ôÉĺýŞĚ”ĘťS‡6}đ8„9śŤsą>‹ß~č#ń źźú±R<.˝/¶:żÔłb‹üîň~áŹ1 6°}ˇ/©ľĘ~¨“GüýĆú·‚ŚĄWţÖľz°]ĂߦwĎ|ߥî‰_ť˙c˛Ć‡˝ÇĂ~Żś8+Čş«ľ=ť Ůܡ•"ěRí\káQWEsGłV6žäzúEĺ]Ď›™żyf׬ĆŢ|ß“Zާk͸ ŤŤal=ĽűŔŻ^<=źĘBkuËŘXŢů–â˙*H  »đôú®zóö…sŢĄŕ'[ű'އaÓ&{¬§‹źŃ9űľXĆ•§0Ż ¶L›ń´>|ďüăôvמúh䄍óľĚŢźÚ]ĹFš>l<ĽOłţ‰ó­~ÂÚŻŐÖtŢ a°ô˙böńo#ĹÇŕĎtóâé7·Řs6ÎVů)^Ó+úŁ~ őwŽ­f ©_…§Đü v¸sŞWk3 ßřŘÁRAßcew±9’ŃÜ÷F÷iqRýeÚWˇřsî]Óŕ3™ŰdwZ۽ֱ(zźb>bcďÝĂWZ[ëĄéźěýŠęúfü6cÓpŰ-żý­-—‹źľ{¸–ßÓŃÁÚÁwA+őńŘ"סˇżżCNpÜćgVł=Aľlmśe㎡ˇă ĹW??ŐĹO_Űođ-–~7řdú1{G¦6Nf\2'ŤĂ|1ř­‡©sŹ(ÚÓńĚć8emy»·§źÖ\ą"ľWeń>%Ä!cp9oć± ţžßĄ8:żÔ»Ó_i|oOkżsYÔ:†âýëđoľ/ĺwř—…÷ \#k.„1޶Y˙Őo/ćٸŘ#ý4|gQ$őĐ’MµŻµ•ż2zť-ýt6®Š˘Ňźď 6jďľ©_ËýŠĺóäĘăÚŇWý:üZ۱®Jwůö}KĺŐáť}˙mŢ^3úíůM:Čň˛©iy/úşž Ť×üźá˙·Y¶Î›#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#°ÚŚžt—ä?˙¨ů[ňâßŐ[i‰˙±”Ć‘kFśAQęt=îŃÍ8ĎÖÖíą?÷˘şÄhľŠÄ|+Čďë͵ĺ4ĆďŽîďĘújĎ 5>‹ŇVÉohĆĐXL(kďŐGżţfÝŽCâ ›´g1ş~¬ĹIŽVXËZĎĂ z`[Ő‰fMŽ~ÖďÔsíő˙bYç“X bź,®śbĂ.šž·Tţ&ŤgŐ¸1ĺĎbůiKĚńQč¶ĆRilm¶/týÂÖ&.kĎ;uE-1ŠÄŤŚď*@3ĽłV®Ĺ&+Ąf×!n5Ťť!¦™ś[bµÉ;“őúdmĺSB,89kZF×\]{ŽŁ¸.rÔ-ßY#sŤÓ|;tţ-‡WbĆĹ !ăÚäĂ“ăKŹé•ő×x3Ó¶´á>7Č}ÖŠďm·˝o+qP•ą(č-ňśď{VÁjŻ ďĐN^ń~—®Cűîá‹Ĺ/ŤKüßC ĄÉ°ßŞÜ]KÖËÖüH­UÂuCCOn‰_M$Ż é«$‡®_ęŁZiP}$/ ~­}k¬śĹúuÎţMžuQńá!Zâ[×*ĺ8Ęšö…ÖxÁÖ§­ä~uZëNX,*µ: ˝69‘ČÚŻó_ĐĐčŢ\ tŮaűřä&ŻÍ©q©1öąű'k2㉠Fžäú˘?\ěÁęäâÁjv¬$Kď˝OtŚřá%ÄÚ«˝eýڬébÝîˇŮ®Őţ×üWV,°Ť[Ž"É…ďŮľpľÜ㪼®ŹzPŔú$ř07b¤ÁPÖ$\µľ5=5ßbt#żLwɇ~yX3ŐÚĂ§ĺ ‚íµNV]1ůđÍłŻ ëá‚™ĹrţŘň+C>Ş>OŃěśť‹š-7sP áĺß[~IČhĘ1řÖRüăPG ~”7ž;.¶÷˘ Ë9CG9Nź†śđŘ(ąRř©\ă#yt™8PĺWsP©ă`śXž•}_é­Śźň‹®ĎĘüc0äÄ-ßü›®y ýč7ĽĂ+עŁ|ÇF jÖĽ2¦ö¸1žůĹ"űÉlC.ŘaăűD•Ąiy˙Ëzzń>ň_t^±7X.yŔČSőBé.ç›Ţ˘«čx®qAšß?R<ţ$2`žküs˛ă„Ł$&ů%éĽę|é{ [s͸÷x?2eíďrîr‰çÝ“ĆóJ}‚°o¸)%Z«HöµDłźĽTj ť߼Â6=ę†Í<5éŞ˙8aýzĄMq0:KÄc>>Ř3xŕă :nkZc˙ôK2^Mýď±ĺŰň¬—»{řĐxzb!Żăĺ|Ń lÁüŕ|ß®ŕ۵Ĺň˙ß*c/čÎÖo×ÚŘ%ľĹô^ř®ăQěôÖü~ŤŹMę\Óľk_¦ôîymO®gCa¬ëC1ýłń†×1kkŽŮňó¸ôŽ[*ď ăŤÚäYImň˘l\ű‡†67şkAŻ7Ösí“2rM+fĄ¸ó.k[?Č×t]ç>řüÚäŽT?ZŰ/÷~çěďľ,}„ů!äa¸7u.đ>4ô®»ůĂĄŮ.RżkăŃ\hÍhWŕŁŐNěľŕ‰ËŹNΜ۷·żkUxCúTĄ‰Ľ·˝Ĺ˙"#dbőGŠ7ĹqőýM˙”É—yÓ7›ď·ŕÇîeň©N1&ÇßĆkÖ‡cű¦+ÚGÚ+»ÍÉ|ŘŢo1NZ*č˛9ĹĽÓ<˛žÝĂ,ňPž‘U·Ôjć;ďşx×mźľpCŹř¤·‡÷DvŤŮ¶ůrŽkŽ˝]ąňŰŰ.ľv›ľ×”9r3EAźˇ ýÍ5¶‡96clë?ëŁďŽm¬AťćĆ–tŽqTĺ”lÖ°äťöĹ´RܨČ·µř@ţÔĆ#ú®„Ú;¶R‹Ii‚NýĐşŻ,đî×x Ďµ6ş•ÚDϸ5ĽWäžVłKŰ/nąúß´¶rŮT{pxwŤŘÜ{ħWćúłÓr—Çs}Ěím ¦>AűŰ(’ńw¨Ńk%µŇ1‹Ţłýţă‡3ŞĆĂü7®NóT7Ş h®Đ:űÍÂö«Ó?“ú™ú1»_űîíéŘęB?şn6Ęwě [ËDýśÎ­2ůň}÷đ&ůťv ąłă¤¶—óI4+Źúg†ßž,t̶řđ(ÂÓ'&şîŹŢA~ӸۼlÉ˝Űö+ż›˘×ŘďŇyĘ;«gxâĐůÁŇqëM®{Ĺ^Ţ ćO.–{{Íő•RFc­wË»ŃçK˝çÉü§'ĎZŐ÷{%x™ňű[)~xŞŻ•ąŇ‘;§ŠA×e<žżłă¨EzżLŹm‹ŰČďç=Ç—Ž ú»§ăÝGT§˙vóX×Ó¤NI×oŤ|Űh'ÂpGŔpGŔpGŔpGŔpGŔpGŔpßľzÝţý׿ö%RgăĐÂmG_âyźř´±4Ć7cScg6ŐúĂďńÄHŽE\ýaúű|Ö¶=÷îüĚą[‰!fŠ [§*‹‡‹ú«ÓşÖ*qDÄĚ]"±Ŕ´#ţ™vŽŰź$d¶5ďÄ5’KŘŚmLé¶xM‘qů!ŇbâČa—ř±3J;â¤,ÜbÉöżëč–łöu±|¶ČBó*,î ţ‹ĺKĂq•´šüB>aȶ<Yß)Öś3ĺ‰űpNă›Çű“*÷jŹĎńĄgľ[ŻN_dH|#2".—lâ5YsŇňčXC°U‡‰'b}=âŇŤGYąwKĄsQ즸ţÔäLLíŁe°ôědFÖËŰRy˘ÄD!W>ă’4š®m9eč2±íš;Ą±űäY^k<™?hć}číÖđ˙íÁGyA!ţ¦™6.ëĘźň†á·óż˙!č‚ńÂ:ěÇaßČź¸9bŔŃbÔŮÎ7sMJńC{ŃôÁjú¬Űó}˝AŽô-ä ć‡2GÇ}CVčűX×Ăz%¦»ąöäx?k^O,t¤ńaCCÓaź=Ë©ÔűŤ÷ĂűiąŤkR{ç1ˇŽ›ĆÝ«ą®3|[N4núâI_e®g®ď€źbý•ćä?ÓŘ_‰ZoƵzQÔUMŕŮü8gÔGfmVkoOÇďĐ1t}Íňź @mÚ:6H‡w&˛pŚ_Ëň*´±řťłź+XNp).„u(M¦ęç´vÇćűţ±€Î“ËDnŰjńkϡ®îg5, ‹Ř\╡m°ôńř¨Ęd/˛ý·¶Q„žsŚ~=GÝ»˙Ŕô„č¶Ć9s/đ#&űg+~OrŤ÷k>ß(ZŮíńÂKe.bóulEl‘‹Đě™–âO4mTcҡź6[*źJĚwg±ŰQôú®=!ĂěöÍqĘVb„-…Ú(–kĽ˛ÜęÝ_'5Áťwd‚\-gţ±ĂŚ–ńţke|f˛ă8˛rO‹m©|-ŕĂ=NË} ϬëoŇ×ó<®§gl v§ĺzĹgĎ[Ţ=j‰@ŻŚ›‚nQß­Ńý˛°_—Ľ~rËŕżsö_âÝĂo 6‡Ľ14ë4ŤKÎţÍ…R|v~űÂďçĄK“χ'VsiűBľ…§cú2žŤ] çĺĺěŢ零Ő6čťő»đ!¶–ŇBŢ,­ÝďţŮ뚣­9YřčKśá«iłAOÄV‚|Ő˙EѱâyćjŻMľw±üŘŢ\ă¶ćXk<ä»[_„,řC˙fB<éŁEŹé›łńT–g‹?ZÓÂň-çÎú;~^š·µřęĺţ¦řJżĽĐřel„,¤Î×G»‚ ˇúbÉoť8TrGóđĚŘ=çxgßř(çKŢ`ęóĚ~9Ź˝°ĹÇŁŰţýŚ3ÎhńËÍiv?r—yţ‹‹Ż6 ÝćŻdNÎ1ľ!mŕýŠÉ÷ęŁ;d}č߉Oş1†ämö€Î`˙wtßďé8_ň˝›hľN«ť@z/›Pß=ʨZŮ=|ö„Ěšň 6KN¬=y×D>Qůéřdvŕrî ©Đ¬=|ďš ľ*©n ±úĄ¸;9of[˛ű»ŻÚ·OŘ–sŻ 5yx&üâdÝűpΞ»R[™ăÚ:ŽęU˙˘Ob_q`n|d¸‹Z;ťłď ü –>ü=4ŰšçSSÔţÓĎ`©ř­Ěť°Ăw[?Č5c]“±<#Ô§b~Şý»]˝ň[ć~<>ĄŢj ú,§ŮÍżů}IRm¤˛‡*p@ľčI«Ľ*sß ¸ĐFő×ú4Ýj{ÎJÍąrĆ'Śu=;˝NĎ®Üć6§ĆęĹ6ËąăĄÖ×ĹÍ:_Śîeć?Nĺ’z§Í:IOĽ7;\ę8ä7¦ăđŕŢŘú?R<:č 1ďDŻáyĺ8ĽűťĄRJ˛)~.Ů6®:™]wĺÄ+$ĎýŹúV9rŤůż¬µŽÉ+súÎ…óęŻô¸íÓžŮu+ż‡¬‘Çö…b:‡`, ßđ,µŔ¤ĆŘ1ůÝĂ—ż—Ç]ő·I­’÷¦ďJ ţ›{Ŕ;ß©Čw¶rźpłiü<:θ–ş?»&ÎMukWçŁýÉ®‰ĂÜ]†^ř ?Ăn74®oľÚĆ”aHpŮľpNđ…|·wKÔ®]¬#Ňż ʦ?Ü“ö­y•«Ă«>eˇZ}F°ąfż=ü•â›?CCŰĄĎ9 ř1ëŰěÝ|ŔĂŽ™ÇJ˙úîTfzěĄißosIdo÷htď»jľ«Óąěä­Şďď{ŕŐä íĆűËą(Ě÷ťžÄŐă›ţŰ|—ÔçhÖ'ŹF÷u µjŃgôwűąĎMm@}•ŤÍŰ#Ç>‘µő?ĽçŇüWĺ˙+㕸Ńýő<ľlxďOn?ţťż“Ĺr|űÂí…ÝĂŻ őŃÔÖAĎęIm±i©ęD« VcźšNđiăöM÷ĐGY;ý }ôH­ŻÔ~ůŻŘ1´Ú6ßygŻř¶üŮ»‰SăÝ‹ú|ćÎ<ýĂ÷NIťy|ch›/ËďmˇŹ’Ú˝á\ _ęĐ›ÎV§ß ýűé"»ń´f'÷¤_6~[ű'εĂGúÉđîîŽî§,’ŹÔ&-ŕ{î>\xëM¬ďAż•§(*ýč=˘*OĆj7 ś”úxŢ÷qűß 5ŚŰ_hĐßäÔĎ |3r?¶|^ĐńMÂ_íéxUú^ÓäĚqtĂô‚ďf#ěsśyçHń‚U™OđĚűţ±±ňâŁc ö¨ Ĺö›?:Ě~®ŃögáµË®Ą ýíF÷ŰíŁűÂT?ëŁßŽńçĚËą‡¦ÇKß ű;f¬Ć®ľ+Ů9őöpÜĆc\k5ZŁ“/\3?}_0f-©ń&ëµě_Ŕ/ŁçČŃúí‘â{Íž/›:"đ .ś‡_Ú›żŇůć}yęÚ·‘:-~Ć~—Q˙„Ýš­V§yoŞÇ?!ý.ý1[ě|hčRwg°‡µçčף@ß÷)_Ć[Ö=Ń;eç°çb9'ż{ü¨­uůW!péÔ[ĄvúĽĚŻ.ëĺE®Q$|…wŕٵĘ75ÉwĚü]‹Žd-ÖóžÔ¦>»bu÷Ďy3Ď şWF[Ąk˙nń6Ť’KÄ˙X~rnt×Â9•żŇ],ź*qíS‰ĺ;߆ĆĺRĎŕááŢVĎAl!Ô€XMn%2Oţ4ńÜ,7LsŤđURł#™ďű4ăçt-ěSă'Äëň«^ßőŕ^ň­Gľ¦ăŕ€8µĄ˙©ţ Pä™ďŐŕ˝>ú$jÁ…ś(|’­Ş2Óú@¶ćÜ››µâ˘ľ†ă`$ńúxÜX/HŽÎ…Á7ŔxIlwęűZ|^Ŕ×pÎĆ´«Á±>-˛IsBˇMň^C>«ŮśÎŁ$—Uř /ÖĆ”Š÷Oë±đíĽ™ß :\,˙i°żÓĎ1Ţ1ţążŐôáşŐúÜ!>´é[BŤž;XŠĄľV_üŢąĎć‘>…ޡˇóWNÜÓ/áÓł +¦đ1ß÷?ůťS_ź÷ŮŔłň¨Ë/I—€łÎGĆűwNťŐô «Ăµ®K5ç Ů3ÇşŢč8¬öÂăi㕸úšx×ÄcłŮkF»B Ćhđ»}ácR/nçf©rfvHř!rl Ô$°ŰRyv¸/Ď×*ŐÝɸ‹˘K¤ĎT=Ž"ő-6žÖVzÎrßíJ]Ă^ż)vfľď©ńđËÍĄ©ÁŐ+v~xł>‡ř+çPqhčŠĐ‡ă˙ŽŞ|(Ř‚]żZ[líÔřćů ˛@çń3řáÇÔÜ‹î-;6Ç‘z¬śűj2ÖőŃ4GÚôž>Ž}ú»ĘÜ˙„zzLujµx­Ź^×ÄXç <;ťď«dÎř'‡˝6yIh·CjA·Ő0Đü:®ď§6(Ř5şÚ2WÁfńyěÓ†{ŁKü5}vđăÜa5?׌ľ ř*ž }S2¦€FĆŰ[*qZSǢŞçfÓ:nÖ|a‘q^r®šůU*wě—űj˝T=fp|­>Ě‘Éa‡«ą ĎçÍ|ĄPťÖń“ńKä¤s(x~d(oZ{Šëíű|ß ŘňŽ™G®ÚxÄh˶Z>ł÷šŞŻÖßĚźÔ!ę±9}ď–á·Bws™LąŹé ×÷ĺýsI}·bw^›-s(ä‡|ô˝´Öí„nĆ ŚżŁčđ¦íCŁň´sjLřŐ±*˛żař'ˇ ţŹ>]u!«ăŔshßNďÄČIgśW6~˛ÚŤ:ö: 2ކnÍáWţŃYxćă ă ˝ˇń‚ŮEë»3Ú®ĺgKĺĚ$~ŰůÁoAď¦Úq˝Ę»Ž+áăČÚäfÓ]ńëyăCéVąŰ>6`ďS菹gçěµ…bů‰pťď{j‹Î¬%çQ¤ţKçCĽÓa!ü¶ř§qńㇱ|LŠ}Z˝•`禸Y? 81Ć|•śkżO±üqVwŮńŃÚ6)ľ0ŐUü‘á4Öuśäń??đlőą¸Ţývrj|Řúiĺfo˙ď ďlTWéo¬o‚~ţÔ^ĹŢeüÁwóKv/řËj–¨ďç]ŇäLĄ-ĺ Ý"Ď­ĽłÔů‡ŽKŕŰxÖý¬ŢźŮ}óÚ€<â×hËřrľď|™OÝÜ|÷fč´ç–ß6›Ž%TÎĘ{é;«‰ĄăJú(ű 6»¦=y»'ޤľečMĆČŹ±ňclÍďtąĆ{Ă: ´Á_łem»fOÇ?¶­Nßßz\eüßéű٬^‰ľoŐËŹ˝ëĽ÷{·ďYdĘokŤîgߌ·”s׆±'硞÷ Ű^[¨M–Ö©|ď.}˘ÇÇ›jOëŐßŇŁHމ˻ݫÇ–o‹Çş^Ů6㍻S˙›ąŁ;˙{],ő›c|{çěۤNŕwň•ąĎ'ÇĘ»íŹLO¤u,~ł'¬ź«¨K­ęőCńoFé`éÖTŹgf6oŞ˝ň˙ŚŚ3Äü*GŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔřmD ‘śđoĘÚ›Üuô¶ŰĄţĘŢxüŹp\ăÄ»7ővÁŇš{»ŞýŽ]1yVá-oÖŘO‰U/×(1®!6}f¸7Ť%ŮR!^Wă‰Í'NĐbßÁ©6ů¶ŚçmEüâéĂ›ő‚˛µ?‰9'î‘ř>ŤkÔ+:żđÄß'ĆŰbb‰ŐŘGÉopâć8?4ô{iţNëłÚa˙ŔŮkă'=m,đE,3q«Ë ?ÄyÂ3±ŰŐéŕ#mCś;ń€’+XhŤ'˙˘ť×ĄVË#’uŞŇő‘‘—Ĺ­łOڶ¬Ížż­1ĽHLň“$N®6ů‡˝`Ĺ»¦©˛~đőmyř)hC–3"›…ŽCš1ůšKą§ă°~˝Ĺ)–ţ4č+ú`ą\O,,ßĹ$FNýšŮ9ßÇşľĐ|Ďü"č#ńČčň®‰W4횣hhhß÷MNĄú1‰ÁoɆ—ęô~R;ě¸BČÁ8üďžŔu;N¸9őo*űńţŰŹľ`Żľźö«ő‘ZRézjfŻ<›)x$ßß…˝Z.y7YŢĹżĄr;5®†řGäL^!|’ŤśŃ®łŕŐâooĎ©N8đ Ť­¶‰-îé8)Či~‰LŃ[_|V§÷ ›@#~h×Ä7Ź_P™«>\?üö`ĂĺÜ_›•uDÍŢ(öŤŢç‰U¬żÖűK=„ĐÎpYŤ­ÔuŚł|o©˙&|óG>čX×Szđm63şě;öľˇ1ę˘Ë!çWĆ5Ś7ÁĎtgOdžµgł€ź·ű­Ö¶śë‰ˇŃt™@+y’ڵŕ‹s§ĺŢß«ąžQdůŹś‡NµwĄŘ|<ˇ7äIsOôGy¤^ë¬jţp9םâşZ<óĆäbc_ĐLťhTÝ?v‘ŚM´6EŁű)Á¦ÁEűiĺyKĺRr©ÝP‰ŃŹMXÍ=p Żç\ĎwçÔ†5á˙J­ËoîśÝ/ŮT{r …ü(j80†:·‘oQÎmM źľjfxWˇ57^GŠ?Iy+Ĺ/ФĆRÂ3°î…Źéo®/tƧϩN_Ř”“ŽĎđÍfżŞ+VŻaĽ˙:é ě~lwȨ̌z±V|=ô±'}'Ś—[űˇcËONkÇ:Ç€bťož\|ač§9V´ü„éł^IÍęŐŹ@WëÇř¨ŹţYč›lܤmTŽŘ#üˇŰĆ“ťź+'N”śÂJţ¬Vş#÷nú,ņůk ·>-ö[çńM{:t×ć耍żŕą)ßć–÷ź‰wĚ<+ÔUłZ{Ô7±w ť/xOAć—Ů·­z?uď¸ęaSíŁ©_Ý5±Ďč;[“Ű\µmž¨wä™Ú„ę>Ť±HëXs䥟n~«Óů¸ş3FFČqSí_ĎĆ#üá›ěűç'Ţú\Ú8űÂEţ ÝF_ćçŮ6uâޡ^Łł»&^”ŇŽ- i­KtšţĹtŰôťqśňŁxX=p ß¶ńă®Rü–¶‘o+ĽsR{'{—ˇsj{' ď±ÔÁ'c4ú,ě<“Łę4~ WŚôš=źKß»µ>s­÷e\üéě€Ő&ÔÚĐÎśR}TJŤW™źŘŘŐĆžŘ-żŰĐÖäoó‘µćíW=zâÓÍľDĺĆś“y!<Éď‰ŐBÎđ†ëxdĽ°taó=ńŻzJ{ť—:¦ůÖő .®únx3ţ”jť3®„©u)5¨SEWLž°ćý°Ňxß˙3·Ćn™# łV˰ŐŰ~ńiRw*řŞs¤¦Í}R{µśŘż÷©E}lůrńé3ň§ú®sIĄőˢ÷_~Ľ˝č_j¨mřëřrď–ĘE¦Ô©Ž"ő[Ëń„öąÇBÇěÝlł6©5ó*sĺdźčRĂô¬¶ěď/Ч/Ľ;đθíţŢk=]Ăđˇů\ăěćŤ5O~§-Çë S§ŐpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔhGĆ~ţŽm UÍ“\Jß–Ę\›=é®ďxŰ=Ô«Yz];~błV ´×MŚŁć´gÔú…­÷IţĐ_$’`¶ŹyÜŁ%îw}|¨™C,ŁĹ˛’ă­9šCŘĘmŰ'¶[ss4ŇÚ]j€4şßůT­T/ŢĎôRă롽ąŽjŔ€¸|â|ő*ŤÝ¶;h.BÔŚi>´‰SQwIň€Ó:kß.[tUrA›ń»Qđ˝©vX“f]Ź^jT„6Íśą/+1Ż!‡Rcu˝křúwŃüA»đŘJńŮ{ĎQ•3{–K˘Ç4–™ă­mN_xfŔ¤Xţç°,Ť4őYďCěó¦7TŰNÇ5˙MąŃX|•Uk¬¶­—JN0<×G»R>Đ r‘FŠGĘ1ÍąkާźŘöĚnôký_j*Ĺ[*Ý…]’7EÎ : ˝ÂC3Ţ^ĺ _zŚ| r‹4Eĺj:Pý÷Âö…?˛—\ř¶‰užřb ĄŃ}PĽkâŹĂz¨a}[±ĂÝĂ—Ąu˘¨í ą7¬}J^yלpRą©|©µtúkO†ÚDÁŻďyÎĆŢٓچoěÝ)ŢęI™ ĂK®qKÂ6˱RY˘č‡ĺÖiĚľžÓyÝĎňŚÇۦ–ŘOŹyů¶¤ú y`đďôą;§Ž:)őňÖéłĘąŰ¤®Śú"ô\â÷ăÚäIÍvW…úTĘcf­č†ĺ\iZvn­öW0nBÉăoŇtU}yŻď uuT‡Ńíą€ŃĐĐűţJžŤÔŮą#đä†ROî,9nr#ž1;đ‡©ß[ žÁźţ×r ­†>LÖM,Ňh;Ž‘›Ôĺ5Ĺ8ŽP˙ŽśJü[ó}ÜÇ|Ű''OHÚ!WeçÔÇlĐix7ąšŤŹNľ!:oV“žNŤoNyžďűnŚ\ąţŕ—ď\cąâŠG¤–ÚĚż§ú GV↓Iť˙ţ‹ęˇF‰ĺ‹ˇ{Bs°?©Mô  Uý¤ćČ ±®ëΙ™Ôo¬ż3ě|ŇŹˇ¦×í“?©µf¨=ę-‰¬¨64tK‚L9g|ĐUxŻMŽ8‡/hŽłµAó?öŤ/äqxęßU)F‹.ZĹ/&?Ł]ĺŞëµK-CˇOó›÷thž‘µ×q[Đ ©yřę4÷hCc{Ř—űý>Şrl½'e®ŮŞă«ČâÝe~™]äˇM öŤ>§]ď†~tÖô~¬«3)çţ ľl* 5=T®QÄŘ=çzĆ0ŮÎî¶v[ćDÔd6őUŘ웥ľŰk›5/u|…ř:¶ćĐqŐY®™ 5YĚwq?0˘ťÖvŕʵ˙T§ź!S†}ŤY>$}t«lˇrKĺřPçţvM|ZÖúޱ•>ŢmÜU,…OăŐcËď*ĎbľŐN<·˘Žž#ÓMÉ ýŠŚ?]#żkDfŐéZÂ>mńɊϸÔäyPČůć¸Ü·)˙ńţ3ç•Öli}ŢZî/t|%ČZń=j×Z·@őÖęü©ď5˙eş°Đ±)[5ďj[Żő¨·ő˘Ô×­%ż<{S-<-~ ˙?j»2Onć8›L͆‡o_8wŃk4:«íW?–Žl»ĽĘ-•ťÉ¬ŚÇđßČź<±đś”źťS—4÷ĄN’زệŻňŁO‚g«ˇů=őwÁçý^e.Ô[ků¶>ÇĚ®@74Łźđ_Čř›‚˛§=çđM:Ńú‰Ôş3=6ť0©ĚŤ§zßúĽvŮßľĐ+ó€—…1“Ń,ňîżiŕ ‘ń¸Ô­¸+1e>Ţú6Î aŽa×RŹĄ]x»7:«=ż@FűQ•ÎđŽkľďÄňÔľ™»h]ÓÚä1ˇ®…Ě-C;ŽÓś–ű¶–±á0RĽ<ř3­Ź®~šsđĎ{/t;CjÝŐű g»MT™C7Öß'®>˘0Öu\껟Ů9Ü˙ć8ýW}ô´¦˙_ĽĹ•ąbr¬@îšsÇLî›jÝ ţľµżcĎÍvízŢĘZůętWÜčţ·PC_x ţ{=ót_ißX/„1…Ôşľ§ă=2ŽÇ64±.m÷ľňľŹ”şŻm˝ť#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ´?Ôă ¶W·íOď˝Pň˘GŠwI¬ăxżÖśYŁýŐëöď˙™äŚsžż±®{K˙VáÍY;y˝},f™uą?Öˇ.–đ˘í4ĂrětÍI0¸ó3ç¦ůĄíŚŔ•Č;Ňř{“ô§O~‰ĺĆqŽ}rčČG!Vľď=IWýćŹBűÁŇ•…îÚ§Ú>&–uŞˇßré,w™\”˙ýß˙MsJŕ žáť#b×Ů.tĽ*Ä5“›Ć9ɡLŽ«śŇvąUČqˇŁ#ĐJmt•řXĐă´)î—ć”Ŕ398äaqîÖf®¨Ä¸Ŕíf9ŻzÂŮöýÔGź.9»MZíÖGYZókڇÚä‰ä®ß±é(Ň5ľu {0»ař“)>íʱԢ8Ú¶TŽ,h= ľeë—#SţČąéśÝ/±ś2ňsЉMµCŤÍĎâÚ¨ąľ¨bR,ďÓ–v=Öő¸BS_·!·ú'ę®ä#˝äňRëĽŘ…Ž‹{Ő^Łhba,čÁvŮâĎ Ő­ńőŇĽćű®.sVÝż·ś{h°Ecí˙×Gżťŕ“É%#‡Fkw\c—ČPr<_MJř|ńÎ9]'śú%oJâ'<Ą×rěÚ)ż˝měżËöÜ޶IŁŽŻzpăĺ1űZ“CýveîÎ ÇF÷ľÉHńőr,ń‡\Kmź±f˝ŔÖg¶Ă>őEFŠ_HeŠßľVôTpŘş©ö°¸X>ľ 9e™Ď˘OŁ.@ćĎ4żLůŃ’kV(çľÚ6ö\™;!ř×ĂjO uŢ6Ö/-T§ß.ÇČá?·€ě‡†>˙BęwpŚüöĘÜŁB­†=‡>¨çŽ›ľ+˙QT,źZ0ź¦9í YĄß„ŹB©e7'ľř°ÚÁ±ĺ‚ĆŐËóäJ/R3(ÔßŘ»&ľtźPν&äôS[‹¶;§No YŹ]řč<##É[µľęŁOę-–ę Áë ĂWK]O-~Ëę–X}˘=˙ťŕçu}{©iŃýłť·üZ] |o­Ý1ü*rÁ/ˇËřč,ĹAÇŃ[¨Ă®[çćŰ874ôő`#ÂżćŽ7}>öoúB»vúPYďČé.Á~IÇŐJ-ú@ź¤ăp©Ł$:Ŕ§äŻ)Ľ;Ôť˛Ú.]őBĐ ôHű»vâŘhŃ1¦ÉUŹę|qÇĚ3CäL=Wi“Ž=ŤÚ#WüăqŹŽ‡4ö„vŮÖGżg¬ëŻĽ4ź[k ^;¸Gůď?o橝kéXÚÉď·ÓyŽŁ+–ĽsŞWjË==ř5εŰçşćř*®ţ2ëúh sűÂ9±ä@'j»żŚŰ´Ż5ł¬Ö<µ¶Ý1sIR,źoŞŐŰr>I ěŐrő“h˙4Ţ›ěÓźiť8Óůü™ĎfCăź‚džÝĎ~ŤÖíú,=,ĚŚO¶č:öÉ>ľ ŮZm űŢZc żO[j'Ë˙tEú÷¶Î/ç¨á0žÖ˘ÁžńiđĹžmÎ`¶O&}uĐ|׼|/ç¶&;§´¦O»Ęx ]A¶đÄś‚ţ^hlçC ľ)6ĚżĐođ0ݧ^âeSŹl[ßőöéśXTÉęlÁ2˙— ŰóaŢÁ1x c8Á¤Ç[ĆׯÚîţ~Â…~čŽîZčĂěÝ&rVÍ]îą>ÉŻzĆz8oý4|J*©g|n|ľÔâ»ţ­.~=›µą›>[ŻeÜŃU?»pĂđQ‚A{Ě™~=®îąuWýK›+sĹ Gl|Eëv­wwĎśüúgNŤźlű׿rý_ń©É÷´őcý#ě8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕ8Ž€#ŕü*Ţňć“ÂZ¨÷ÜnĽ˙Ź^˙¤,/éâkC~ĺ=·oĎ3ÔÚY¨š2Ţż±ţă»Ĺ2 Ý(ëś?*äd'IľůĄŁ?ÇşâűéűŐBÎńJ~Ő‰˛ţí5Ł›ĺŃä*OGŢ kŠ’ŹŇšĂđŐË´vI{J5ŁŞśËĄąo]ő\/|q¶&97şn®¶˝1đ3ŢO=€é‰…ś;ÚC^ąxŹyܣׅ¬Kź‘ü«ąů7äM‘WFÎŤˇsâë[=Ą(‚OYóľWsĆűď ąíÇÄoÉ˝¦-ó$Ť¶Ç—'<]tXëQplOÇ BţśćOFŃôÄójŻăÍšKăý?ýĎץą˙\ó4©1TÎ}ŔÖĺP[~6ŐŢ“¦6©$˘«Őé—°ŐĹ9EăýIuZňĎŽ ňÖÖYެćÓ…ş©n´%ÓBT9÷â´‡ćôF|C/úkµ´¬^KçěHžŃÓÜ;r®đi#ĹS‚Ŕš}Ç"ß×NĽßÖŇŻJŢTČé­Źţ˘ ąÁFéx˙Q•ąÍ·ŇĽYôb÷đęy|T|-ÉĹhwńôóîÖÇŮÝÖ~«9ź©ÝJŽ(ůČ{ľo[“nÉy—cä7“÷Î9«Ođ‡Ř=ŕi°ôŁTÖžÇĹ0ćťS©Ťž#ßăęĆ|}ěůżšµFŘëúQ’TkţłćŢ)çĄćÇVjOInlŰę´qNž;őSTnQDžłř©@7uJĐ]ę7ĚőýUŠI]ú"µ}ÍťÔ>m<äZn°=ŁÝ¶ÂăΩ Á÷ěšX6k~ěi•ÎÍ6ĆB·Ł5ş?đ@7Ä~Ă8•}řú”`Äřm¤8Pčś˝©m卜ˇwOş­ňľĹGo;5~Il˛´:i»‡©¦yŕÔ’ú˛öűDęŻŕż[ęŹQ¬y»¶Űp×Ńۨ#…nšL!’qŘeţLjC}*±±ý>ě[ üěéíˇ˙˘_ðqînWćž×¶r¦'së›o6Ç!ýß_<4tEluHtě­yîÔŇŁ‚Ő/á\§őóÚN´w#¨(µH ×jQŕŻŃoę/™n·^ÔjÇôÉč3ş€Ě[۵ó>ófř„~Ł^‘á—„ęIď|Őß…üiü3ţŹÚpĚźŃotş:}rW_Üö9´ĹćÜYuÚňöuŰčţba¬k2©MžĐś+éĽJǦY?…OGÎ#Ĺé¶ő]&O¶;§ţ^tűÎDęúč“vĚR`ŚmµH¨©¦íßôíR›&đŢôqäüŻ ~Ť÷=ď–2Ňk5<‘ü¨˙ď~¬-úźöN…ův•ÚÖOgtßóŢ˙ţď_7çŔ:‡Ç]ˇćˇ]3žňK Ź3×% qŰŽŻŤę˝mĄ>RĐÍĂj–Ú•ý‰őMđLšˇˇ—‡:źf÷ÚźďíNëďŘžs.ěµÚŤŚÓđĎĆĹ–Ęź„:ťµó•ąNËýeŰż2Úďm»ĄňľüÉŶ/\lt÷đOŮꏺkëRŹďŤçĄç.›şhĎKĎűwGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔ¸w$şg÷đK÷š/E ’7o<ˇż69“°=ě‚? µîýŽí|v<͵Xś_¤4źü™ăúó/|j˙'%Vó&ŁčgÇĽ|›ĺ·3g{ŁmçÔ[c­Q!yrÍş–kíżzÝţÍu쵦uX¶/©~d­Ű{Ź|8rcăęă äŠń}¬ë”¤U‡•ń ×šW–ńÜWyGČłÚ$xµ7§­Ô©>×&˙>&{!­UEäŠÖ&ŇKëďIĺ†Ć-Á·uŐß•ŘúßÔ$ÁľÉ+n˝k;ďS›™RŁŕ˛©©PŁ˘>za¨g/s/އÜčçIí0“±ňtĽ%g4Z7<Ă9ß’Ű.yŰ·ö’ó-2OČaďŞW Ô€GdNn7µ¤¬^ÇÁ ˙¶}áëĆźYÎo\}yŻŐ6 ¶ 2Î5>‹O ú,ß·Y=–F÷’YÉsżMęíŔ79ß·ôť•ÖżŕX»f÷ű@ˇ:ý¶Ţď7sü­>ĂuR×ÚëŁ]Á¦9Żç”ŁŁ*§Äřrj“¬—šiP>;P }MeîQjďĚő˝6ŰÍŁżVWŠvČ~©c@}ËÇ6´v­ÖϧsvgĐß %ż_ô4Ôp ˙2şüČ`ĂäżS«®M^”P›ÄjŤÉÂ÷릟ľEü2r˘®auzC‚/CžôŐř6«ĹrţwMś›pžcřë_ű’ţÓrÔĎ[ĆŃZ‹a\jČtşá źE &¸(çv÷Â#ü™ĎFľ*ö>ßw}rTĺ{ëĆgĂr„GÓѸşUč2ĺ|ëľÁ‡¶Şű:mmłö™ÁÖőÎŔk}ôŰżU<Ď÷%żőtLNľuGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpGŔpG`­ř˙ „v̤•nipype-0.11.0/nipype/testing/data/tpms_msk.nii.gz000066400000000000000000000500171257611314500217540ustar00rootroot00000000000000‹+†S˙tpms_msk.niií›˝®îJv]ŻŕĚ‘ˇs'–`Ŕ€GNť8C8Ó#ů ěGsónX$‹äúŻúö7(ôaý¬5ל§»uö=ýßţćŃóŻţřüçżţëoţĺ˙ŽM˙揿üyđĎ˙Ç˙đűż¶Ăí¬ýë˙üÇźőźĹ˙úĎ_żü§úÇüŻ˙ëźţÇ?ţÓ_ţË˙ßůŰżűËßý»żý÷BçŃ–ešÇ?ß˙÷Żţßńn۵ł­¦=[Ţţkýńůź˙öoŹě @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @Gŕź˙ţŹ?Úż>Îü_ 7ďíý”ˇŐśßO=«Ţőž<öuçőSߌ»łż¶yiwÚ÷HkÖŮ›÷ćë­îéľi¬ô~ňq·RÖć%"×HŁéŻúyöž­šµ÷ĺÍŘ÷÷ş«Ż7ßŰÓű×®>ë×–Ń’ýł’ŽÝ¶üŇ÷XĺsNĄ9űşĎI7vÚ˛l·mýö+}ÎiË÷M™[Öö•»w«űmﻼŰůo}î2˙ĆĽwYŰůoĚĽejůÎďßš—\€ @€ @€ @€ @€ @€ čxţ7[o{šNŰŻún>ďŢߣ^Iߌšł×ÍCö橯}ZżéTÝ?yÝť}ŤjžÎÎý3öOţFwgŹŁš·łłFĺţÍ[Ö}eĆó¬¬Loşg•ű7oY÷•Ďł˛2˝éž}Tî߼eÜWćÍĘČô¦9ňQ}öć1ęľ:—t^Tľ^G:{f]ď×»ž™C3»ĺÜzÚÚňÖĚś]Űň}SćĆĽe·ľ›Î§Ľ­9űľOÉÚ|6ďŰ~[·§ťKŢ­ç“ß’ś=źOÎÚ{ĘÝ×ý¶ő(÷oËŘňڞ¶łVóŰŢ-_{oůúőoËK@€ @€ @€ @€ @€ @'Đţúö–>}Ďy-ŐQ×2¶÷ćˇ÷˙䩯»[?őWßÝy|:?{|Ş=ßť{«÷g?š}óŞéŮjg?ZżgĎ–ţłF5‹çŢŁĄżőô:Uë6{Ö»*g›3+g?·y©z÷łg­«˛¶9łrös›—Ęw?Ćş2k›5#g›Ů<Ěx7•ď9G3+2Źć®p–•}…lO"s?ÍYí."÷j™$~Ľą%3V«é3oŢú˝d˝Zž7?-SËÚŢí\ň~›±Ú}ź©ĺmďţîi˝Z&©ź-ÓöçćŻíŰşíGŮĎ5Ű~{ZíĎîs~mľűws>kűvżú{ó»=ÍwŰ÷g<üŇ÷´˛¦×ö«Ľ›ŻţíńÖël땟ćŐë±éôoŻ&ý€ @€ @€ @€ @€ @@J ˙;ŚŰşÎwç}_»âúÎďů|ŰoĎčüîě§cť_ď|fśŻ:#×›ćĚÜoŢîî7ĎwwŇóąĄŢ2ë*sgćĐh“9Ź€ć;d×ćĄ<*gçĐęÝĹď´~*ęăS+2hgĆď´~*ęăS^+rHg\ÝĺťH=eÖ奻WÎĚó¦}ď*˙ćÍ[ô}~"ů„čl#=ą›ÚĘ‘WďYmű4oÎľßł÷±®snź‘ł×°;©ďě}{ÖőÎĺ[®­Ł­#Ţrő•ůî4Îi¶şĘ§ůj3űůí.úÝfÍz·<çůí|ôŢjGçí¬iµýönO[·»vľ˝Ű]Vąî=őëć­ťő>űł»ő¨żi´wuÎ;OÍĎ9ËťżsÝŰţN'ëĽĎó”ą÷-ńŇ×KÖÍČš–»iŢyl÷’÷ťĆÝąD3ş¦ĺŽňt§swťG«×űŇööő˝ÎyÝ×ý¶ő–u{ľ)óOb~… @€ @€ @€ @€ °&»żĎuwľĄ8ßť÷k&}÷}αí·gt~wöӱƯwłÎg¦ödÚ|{ű«ł{üFő~cćŤ]Őőť"tľ1sŐ·Žř>‘Ůß:Ňk”Ö7fŢŘe>Qß&R'3ď¦é5J+;óŠąż-sEŢ6#ę÷ĄG§y™ńöř¶ôÎČ8šiń®íÍ]áL›CZżB¶'ŇŇş§Y«ÜIłHëVÉ%ń!ÍôV'™µJÍ[éý*yF>¶ í‘ćy«kz+Ľű|ÍĎ›ë}Ó_íÝXsťű¶|ýYËŰć´}Ĺ{äc›ŰźG­[ž'˝V“ýŢ˝ÖÓÚŞŮçÉ9ň±zޑ稳sö(]t @€ @€ @€ @€ ?óßďyÚ·iO5í®Ő®önţ¤ďÍż´¶Ż[%wďIş¶fnúł˛·ůłŢ3rĎĘÚĎ­ĚÝĎťą®Ę<3ăhvEîŃÜ™gŮ™gf»›ýŤ™7™ĎëŮçdŽ%0ű{ŢÍŹMyT»›9űüč2~7;_??>Ý˝b?wÖúŢ]îÍŚĽą‰äęUŮĺŽj*łsפ°MÉČnsRםąÎą}RtćMoĹgä+2ű–ąé­šżůóľű|›ÖŞŹ7gëßňŤrŽÎ2Yô~ÚśvůnÚí=ŇnwŮďŃ쌳–CŞÝęłŢROu˝·§:é]Ż˝–z¸«{ňs×#9ŇőŢIćŹj¤sG˝ogRmOÝ›‡Ń˝tިWr&Ő·ÖI<ô5š9}źf­™a©Íô˘Ńnµ– žž6wô¶ęŽ´îά3Ľ}#?šs,>G>¶ł¨'[ßęóěËŞóÔ×ĎxŞă€ @€ @€ @€ @`Mýß˙č×#·ýýy=Ş_éěě÷iżů~şÝ}jÖQíŮěěZżQőłrGů·ęTç¶úŚî«ĚíÝŁW‘Űă/Ł7;s†çÍĚÜţ24ČK ăEhƦ<ŞEřËĐ8şŚÝeřŤĐŚMyT‹đ—ˇqtżËđěŃŚO8VôxŚě»Ë=ŤôŻŃĘM%S×řőÔĘÜÔUy˛Hzë’č&IĽ[jt.ę«-™žzęč'>ů·Ţé]ÔvXs=őm ¶űUź'ďÚ»sĆYąGsµYŢę[Ö6kTßj˛ßŁŮg}©~ßą–ÎźQ™ł×š‘E2ł÷˝–Ě«9{z«—Üź5#÷’ůw5O>îz¤çOÚŢ;©‡ľN:łďŃ®Ą3,uZ/[˝ć±čkghü´Z­ŻÖ'}gëK}ôuO}źt­Ńßj+ź7o/oÚíŢ3ĂŇŰćŽŢ˝QĎH»?ődźőóŰ:zfÓ=żŁç @€ @€ @€ @€ Cŕü÷>Îű~ęůn´ďëW[ŹüFž­”72—Dkvv‰Ç¬šŮł˛Hu«3K}e×UĺÎΡŐĎέőSUź™»*v™c hůWŐǦ<ŞUeĐÎ9şŚÝi˝TŐǦ<ŞUeĐÎ9şŚÝi˝TŐǦĽŞUĺÎą:Ě9‘úɬËIö®š™éIűÝYnĹ“·Ś»Ü4:őŚ|˝¦ÎM]uď1r]—@?)2gÓŇ»ÓŃüFľç$ŃMŤČŰOlzýYŐz›}~šźó]®]÷3F˝ý}ćz4{•łŚÜ«d{ňťűiÖ*wź–yóëať×ëÇ“EÚű ™Ł9fd¶zěűž|Iżç]Ý“¶çînŢÓąfŢ“ÎÓťf†¶öiîÝÝŠ32=iµ[ýżŃyëÉ~ŹfŹÎ¬>FZwgÖ–ľ;íܢŮ÷4ť§w__µľó5˙N;˙ÍĎ(÷oÎK6|ßţźAźö=đGŕo“9î÷ĎĘJßřťWţx @€ @€ ťŔö3ěţ_űÍqŐ×´ő±bý]ó}÷îÜŐôç}ýJëŢcćz•Ě™ď´gfżóTq>#wE®·•ąßĽTÝWe®Ę#ť“ť[꣺.3wué<2ÇrŻ®‹MyT«Î"ťwt·“ÎźQ—ň¨4#‹tćŃiěN꡺.6ĺQ­:‹tŢŃeüN꣢.>ÝłbE¦§ĎîňnźŁĎkŇüLiŢĎ3Űyĺűě!c_™Ç3+2»ÇGe/™}*ż•u–/áµŰꣲďęÚ~RéŰ:ËžîľÓꥪďŢąý&Úűć$RÓžěľ3Ň_ÓjÓÚŢónZŃoʧ»ŢÍăÝťć<:kÓÓxŘjŰÓúÚţüîďŰZó>ëEď-^ZĎť—ó}ŰKßwş‘ç/çy[ĎÓsľ—Ě8÷<éGÜ=yŠĐß4žfTçm™ÎžÚyäűé;y˝~{ćoů}ŢçoĘĽýűŁĎîý÷ ý€ @€ @€ C ý,·Ź&ő÷m=Ş[ő¬y~{oţßjúűóöţ2׫dĎĚx§=3űť§Šóą+r=ͨÎüäĄú®"{u¦·yŮ™ßćϸ˙ĆĚçĚgĆw”Ě$s ďY5q)ŹJłňHćťĆí$łgÖÄ%=*ÍĚô6űč4n÷6wć}\ĘŁŇĚLołŹNcwołgÝǦ<ŞÍĘô6÷č2o÷ć#óľĄj3ÚľęÝćV˝«r=Í©ĘÚć÷oĎÚň}[ć>ď7üžnß™7 @€ @€ O"pţYîyÎrľ?ďĎő+íĎ^#÷+ĺl^"ó=iµyłßO3îľ-oc83wó0ă=#÷Śśç™•ąĎłgí«2ĎĘw7·"÷Ýě™ç™ągćzšť•ůić wąWČőä!:óÓ¬•î"sŻ”ëÉ ™}žŘ®vçKúÓ˝Z¦7?d¶xăşâ˝-é޵b¦7O»{ýęM{Ő{}Ň˝cŐLoľöúŐ›öŞ÷ú¤{ÇŞ™Ţ|í ô«7íUďőI÷ŽU3˝ůÚčWoÚ«Ţë“;VÍuçëč޶»Ó^őÜ–ňصj¶;_G÷öÝťţŠçö”ÇÎłÝy::÷íîf¬tîKxí^)Űť—«k˙ÉݬÎýéĆ +dy»Ť;Íś}—n¬4;ßyţŘeüéyî¬}|2ťbunť»Ľę¬ÜyŽă”ٞÇ9ŞQňć®q;ĺ3o­ącé׫is×;ŚźřŤ™7ŠŇÜńÄç*JrĎu?ý3oűÜŁ}<é5·Üíi Úž7 @€ @€>™@űyW{?ei5íýT»Ň]óý^)cóťq¤×f­đůË<›ť93Ű“öĚÜOľ2ďľ1óĆsĆ“ůĄÚUąĄ~*ęľ1óĆ5ű©řv–Yą-^*{2rWú·ĚŠÎlńPÝóŤ™7Ć‘Oő7óĚ‹Čí™?Ł—Ě63ľ•w¦-éO—wö¬~2ëĚúNŢąş”ÇjďěYýÇşÝ,ĎŢąş”{µwîěţ=‰|5Űłwľ<é±Ň;wV˙1…n7Ëłw®.ĺ±Ú;{V˙1…n7Ëłw®.ĺµÚ;F˙5…îd†gďL]Âkµw~u˙5í¤Ú·gž-áµË㡲÷ęÜwRéÝ:Ë—pÜmőRŃ7vě?­đn™áOö¬`ń”ÝóěŘ›í_«ďO$SĐúĘŞ—ąŤŻĘĘó¦źD®řć-ú^î,Ż2:Ó›^^˝ň›×{˝«šŽl˝FŤkß”ŢoÄÚ禮{Ëş=ŢĚ?*źőë7fö|ëĎúşG·–o}TřĚť6÷g¦<ş–f>v}ţî-÷ç'”'ŘXđ@€ @€ ßL`ôł -ďoüąČ(ëů¬}ëóůyßęV~ź=GíWĚ•íMg•ěo>ŁďgçŽÎ#Ő›•[ę/«nFî¬,RÝęĚR_ŮuUąłshőłskýTÔcćŤkÖSńͬ322[˝TöEç®ôŰ㡺÷3oŚ#žęoĺťçÍěť?«ß“{–gď\2Ë xYĎě—§&Đď¬sgőéŽ;fů·Ě'°ťZćW÷Ř’ÝwUű·Ě»wo»±x¨ě±ĄzďŞĚ ťőîŢVˇőQUoK#ďŞĘ!ť#wî«”úÉ®óĄĐuggŃčëśŰ«5ž˛kí)tťŮ94ú:ç¶jŤźŠZ[ ]WEÍ ť{{µĆSv­=…®3;‡T_çÚ_-ő•YçOˇWČĚó¦­w×ńć-ă>ν])#ם¦Ýe|çťÇČóx×~ĹČ|MËďŞ^ˇy׼ë]ćNܲ·ç̡ťó† @€ lú?CţV"ç?÷ű»Ě’š»Ţ™ç˝ď·uóůT×jV}?y÷Ţ­Ů›IŇżRn‰ß¨šrGeŃčĚĚ­ń];#wt­^uf­ż¬úŞÜYţ-ş™-ľ2{ľ1óĆ3óÉü^^íŚÜ^OýŃą+ݸŁÂkÄŚ±{űi„§l {şqg¶ßý±sßi„Ż, _˛űî,ż^Ý{Ç17^Ńý1©žU˘={őžÝĆÜz=F÷ǤzV‰öěŐ{vsëőÝ“ęY%ÚłWďŮmĚ­×ctLŞg•hĎ^˝g·q·^ź‘ýq©Ţ•"}[µŢ]ĆVX}FöĹ&’©Eú×jÉĆWi}FŐÇ'Ń)FĺęčÜĺVK=[ërÝűÔ­™Î}>ó»Ďy¶ýöÜť˙Üň+ @€ |+óź3‡sÖóľĎ~ľŰöźôŚü{ÎVĎîÉöÖ»Zö7ż‘÷+dŹĚ#Őš™[ę1şnVćčZ˝ąµŁë+3G{÷čUĺöxŚî­Čí9B/;w„Ç Ť¬Ü^#5ŁsGzËŇúĆĚ˨'ë»dč~cćoťń-*4­ß»Â[Ö 2Ë d}*]yŇ˝˛Ę[Öś=‰|•ĺĄJWžtݬň–5gO"_ey©Ň•'Ý+«ĽeÍŮ“ČWY^ŞtĺI÷Ę*oYsö$ňU–—*]yŇ˝˛Ę[Öś=‰n•ĺ§BW—tŻ®đ–1cO`[exĘÖ´%Ý»˛ýEëďÎ}«h_™zľ¤{w¦Çhíݵoí+KĎ—ňÚťĺ3R÷ęÚwé-KË—đÚťĺ3J÷ę8ć$Ę_´NLş{•hż^˝{§q7^ŹýqéĆJž˝šc§1§^oYý1éĆ*Yž˝şc·1§^oYý1éîU˛|{tďÝĆÜxĽeőĆ$»WÉňmŐ˝w{cőÝ›ę]-ÚżEďÝel…ĹcdOląZd­–Üe|ĄÖkD}| ˝bD‰†ŢYM‡Ä»´¦Ćqüiľľ.ŢĹZŠ-ëZ®p@€ @` íĎLç÷îâ]śsŽömęčn;ű”çÎ˙Ýů–ëî®ťŻš˝ůË|Ż”=3çY{…ÜgOű™ą+ňŤfĚĘ<ňRyVť»2ŰÓ¬ŞÜOŞďČśC ú;Jćĺ$ÝU%fÔěcW3˛hfƦ}˙˙‡5޲jż1óĆ2ęÉú.ş™3|ekzsgűËĐ÷dÎđSĄiÍ]ĺ/cÎ7fŢ8Zž ţ•šd–¨ü&łd)ŹU>*5Źid»Jłd)ŹU>*5Źid»Jłd)ŹU>*5Źiä»JŹ‘łä Ż•‘>*µ®It'•^Łfé^«Ł|Tę\SčN*˝FÍŇ%ĽVGů¨Ňą&°ťTůŤcKxíŠđRĄquo;©ňëťcKwßĺőSŃďŢvSáŮ;Ă–ěąËë)«˙ٵď6ËłW×—ęąŰë-«˙ٵď6ËłW×—ęąŰë-«˙ٵď6ËłW×—ęąŰë-«˙ٵď6ËłW×—ę˝Űë/Ł˙ݵŻ"ĂłGÓ—FŢíńÝ+wí«ŚömŐóĄĐu[=FöéÇTGú·hŤЫXĽFôčťĆvDdjÄ:ŹQ“z×ÖŸËWŃć:×ç;Ěťp—ç|ľíy @€ @ŕ‡ŔčĎLíěŽŃ§ţąŞĺz{÷ąďjűšU×wŢ˝ç+ćőf’ôŻ”[â7˛fvöČ,­™ą5>#kgeŽĚ`ŃŞÎmńŃS•;Ă»Uó3o¬˛ë÷ČěűĆĚ™ß:ó[EhGďOQą+ĽFÍřĆĚ;ďĹżR‡Ěz•ß'r–>éOG¤‡j­oĚĽ1¶<Őß&z™e˘ąWëÉR«Ş=FĎ;¦‘í˘=TëÉR«Ş=FĎ;¦‘í˘=TëÉR«Ş=FÎ;&Ńí"}TjéR«+}FÎ:¦Đď"˝TiéS;Ş|FÎ9&Đď"˝TiéS;Ş|FÍ9ş·ď˘üTčŘS;+ĽFÍ8:·ď˘üdëŘŽ;łýF菝ŰO#»Ť»µú‹î‹Kô®íÝŞ÷î4¶Âę3Ş/6Ť\-ĘżVGî0ŻRëŮSź—¦ěÉňÖksT×őć_z_ç8nŇ]¶6atßî~ó»ĺţÍÉ@€ Äh~˝ĎúšóÝęűŢűŰşeą«k÷+żďĽ{ĎWĚěÍ$í_%»ÔoTÝěÜQ94:ßyă3ëŃ|›čÚ™Ł3Xô*s[üeőTĺÎňoŐÍÎmő•Ý—•;Ű·G˙3oĽ˘Ď7¨ěŤĘ]éŮ;ë3oĚ"/űę~oćjżóľ1óĆÍúD0źĄńŤ™­ßzÖ7ŠškůÖQłgéYF`Ö÷‰š+Ky¬Šš=KçF¶›ĺ5j®,ĺ±*jö,ťcŮn–×¨ą˛”×Ş¨ů3t®id'3ĽFĚ”Ą»ŻŠđP­qźFvSí7bž,Ů}U„‡jŤű4˛›jżódÉî«"Ń{‡ÇOEď{}E…oĎ }"Y‡ÇSvŻ,ľ*Ű·G_źFÖáń”Ů+so«ĘôíѶĄ‘wyĽeőĘÝŰ*ł|[um)ô]VŃ}zçöŽhďV={[§ŐgTźÍµż+ĘżVÇďÜŻ őě©÷»ŤUđdyëŤu«öć]{ë.Wí)Ű6ůí>×Ý\ő>ű\'L‡ @€V'Đ˙ůáĽ>{ďďĎw«ď{ďoë–宮ݯüľóî=_1ł7“´•ěRżu+dŽČˇŐť[ë7˘~fć˙VŤą­^#ű*sGúöjUĺöúŚîĎÎí7J/+w”ż ťoĚĽqŚ~2ľM´fdćho™zQą3=fhGäÎđ•©éÍśé-Kű3o,=OÖ·ČÖµfÎö•­oÉťí)[źĚ2Ůß![_–ňX•í)[˙F¶Ëö”­/Ky¬Ęö”­L#Űe{ĘÖ—Ą˙”ý9ßÝ~Ësw·ťÂóäßs·jvO&Iďją%ž#jVÉ‘EŁ1;·ĆkTíĚĚQ,:3r[|F÷TćŽöîŃ«ĘíńŃ›ť;Ăs„fVîoYßycýd}źHÝoĚů­#żE…VÄ÷®đ9Ă›9ŇK•Ö7fŢŘzžŞo=‡ĚrŃě«őäI÷ĘjŹŃóö$ňU´‡j=yŇ˝˛ÚcôĽ=‰|íˇZOžtݬö=oO"_E{¨Ö“'=VVűŚśwL"ßEz¨Ö’§{Yg¦w‹¶ĚµżĘâ-ŁÇźD®áߢ)wSińŮ“¦™C˘esß%ńQďÜŻ‘ëNĂď.OáÎłő<ĎiĽňSĆmÚŰ}ĽŁ5Ďą×p… @€ @`eç?GlűßřŚržĎZîóyŰ·űOx7ĎQď•3GeĽÓY-űťĎčóUrGçzŇ[!󓿬»™ął2Itgä–řĘ®©ĚťťEŁ_•[㩢6;wEËŚ¬Ü/U=ßyc›ńT}3ëśčĚVŐ}Qą«}{ć}cćŤWÄăá>Ł×›y†ç™žÜóghYN`Ć÷‰š)Oy¬Śš?KçF¶›ĺ5j®,ĺ±*jö,ťcŮn–×¨ą˛”ÇŞ¨ŮłtŽiä»Y~#ćĘS+#fĎŇ8&‘ďfůŤ+Oy¬Ś=CăB·›á7b¦.ĺµ:ÂCµĆ5…î¤ÚoÄ<]Âku„‡jŤk ÝIµßyş„×ęŐ×ú“jĎžyútăʇęŢqýiµoĎ<}şq‡ÇCeďŘ˝ý´Ň»u–=ݸÓꣲoěÜ~ZéÝ:ËžnÜiőQŐ7ví;­ňnťăKwßmőSŃwďÚwSáÝ:Ă—ěľŰę'»ďŢqĚM¶­~LŞg­§ěúg·q·Ů9¤úq‰dJR_Yu2—ńUYyŢtă“čßüEßëÜĺUGçşÓËK`Wľóę=·;Şëôfěűë\ÇLę˝÷ëM˝ßź×1Ó×Téł®éW€ @€Ŕę¶?WüÖ§˙3ÓhÝrŹî>ŤË]†Ńů–{tŢź56«ľ{Ż‘ëóFć»ÓZ-÷ťĎčórGg’čÍĚ-ń—U3#wVŤnenŤŻěÚŞÜŮ9´úŮąµ~Şę3sWeĐÎÉʬőQ]ź‘»:v^tfíüYő‘ągeĐ΍ʬť;»>"÷ě ÚůŢĚÚy+Ôc捻çYá»YŽ ô;ͬUjő)Ź«äĐř8&Đď4łV©Ő§oűv˙ ďć9ę˝r樌#ťsŹ|fś­’=#Ű“ćĚÜOľ˛ďfĺÎÎő¦_ťűÍOŐ}UîŞ<’9ßyă’ýHŘϨÉĘ=#‹ffFnÍüµdöńÝ,3ýI,łgő|c捵÷™ő˝Ý¸c†wëĚqŰ©ŐCeź-Ů}WĄwë¬{÷¶«ŹĘ>[˛ű®Jď–Y÷Î}7/U=ľd÷ÝUţµsîÇÜhýd×ǤzVÉΠŐvw«ő•U—č])+V÷Ýil…Ö_t}ląZt©žÜaNĄÔgT]N ˝jTž'˝«üŽ'żŢ»|÷ľ Ţ|ç~ź›şîłoëľÎqü¤sć6áîĽÝó† @€ |óźŹŰľĎŢÎÚ»żű¤uó˙ôŢň<ÝowźđĽe°ÜŻšŰ’EŰłRv­woýěě^˙ÖţYą­~ŁúŞsGůöęTćözŤęŻĘĺ7J';w”Ďhť¬ÜŃ>#őľ1óĆ/ă‰ü.ZŃ™3#uďÝŰn"˝eiŮ’ÝweůŚÔ˝wo»‰ô–ˇeKőŢ•á5BóÝą˝"Â_††=‘¬3ĂłGSćÚ_ĺńŮëO"WôíŃ’;Ž©ôxŤčŤIˇS‰đmŐĐ9Ť­¶zööŦЫyýkűős:´ľ-ő9Î}Ş–’ź«šnIiMŤă¸)Ň\wuqNć)őŮš‹vÖöĽ!@€ @ßJ ýą˙V}ĆŃşĺÝmgźňÜů÷śŻšÝ“IÚ»Rv©ç¨şŮŮŁrhufĺÖúڬ˙ĆĚżę'ň›y´Şr{ĺŢ‘ĺ)[wO _e{ËŇ×'Ý;˛]ĘcőlďÖůÇşťućě>]ĘcőlďÖůÇşťućě>]ĘcőlďÖůÇşťućě>]Ękől˙–ů׺ËĚŮ=ş„×ęŮţµóŻ ô'Ú™łëő Żł3hç_čO´3g×ë^;fgĐÎż&°ťhçά·%ĽvÍĚ ť}uo?ŃΞQoO7îś‘A;sěÜ~Şť_]oOvßYťA;ďŢąďF룪ޗ깻*vÎłk˙­ÖOv˝?‘L!;‡T_ć6¦Ję)ł.&‰N%3ŹD[ç6®Zâ-Ł&.M)#Ó“¦Íe|דÇČ»xç>ĹČl#-ź»Ľî‘WďYžŰ8eoĆľ?ÎUŤRď]»®q?ĺś{›ŘÎň§3€ @€ Ě'Đ~ҿϮ¶»Oú|wë-ăÝ];˙Íkô{ĹěŃďôVÉ~ç/ë|vî¬\oşłrżůĘľŻÎťťGŞ_•[ꧢî3o\łźŠog™‘•Ű⥪ç3ol3žŞoć™™Ű㣲7*sĄgď¬oĚĽ1‹xĽě«űÉl#PýťĽól)Ź]^3úŹ ô»ž˝3ő)÷ďěYý{ýj–gď\}Ň˝Ă;{V˙ž@żšĺŮ;WźtďđΞտ'ĐŻfyöÎŐ'=vxçĎč?&ĐďfxöÎÔ§ŞúĆ®ý§UţµsüÉî´^ŞęďÇÜTĺΉIő®"ő“]÷î4®";‹D?.ŤLIâ)»Fć4¶*;Ó“~lťÚ“ݬ;ťĂśę¬l#ÝśvŐ‘ÇČ3»łÜÎČŚ˝V®kżzďŐ»ö»©Uđä­uš3Mš?gúZŞ @€ @€ ßGŕég`}Ú»şľfőő]ëůĘy­™¤}+e—zލ[!wD‹Ć¬ěŻ‘=Őą#˝[µ*3[=fôUĺÎđîŃĚÎíń–ŐűŤ™7–YOÖwŠŇÍČĺ-S'2w¦ĎHm2Ű D~‡ -{Ň˝łÂgäŚÝą}é§BËžtď¬đ9cwn_Eú©Đ˛'Ý;+|FĎŘÝŰVŃ~*ôlIş*üeĚ łŽ@Ć7¨ĐÔĄĽVWxŚžqMˇ;‰ö“­§K7®Îö­?Nˇ;Ťö”­§K7®Îö­?Nˇ;Ťö”­§Kw_ťí3R˙>…î&ŇS¦–.Ősu¦Ďhíç$ňŰh_™zňTĎ•™#µźSčo#˝eiéS=wdůŚÔ}N żŤô–ˇĄO$ëČđˇ)so«Šđ—ˇaK#ďĘđěŃ”;·WzüeôÚ“č:3Ľ[4u®ýŐŹ‘=ţz…H˙Z-˝Ű¸­×ú8÷vĄR »ËřN©gO]Ľkż˘'Ď[Żß]®Â›í}®ŰXum¶s}¬›Zµs–·}­»üiwyó'3€ @€ @ů$?˙j5››~ťď.vBóţôî3ŢŐĹşŠW»óqďÖŻ‘K˘áwŁ ńYăÚ®™EŁewěëÔx̨őą×wgd°hęťŰ:,Ţ2{l)ä]™Ţ­Úr÷¶J«Żě>[š÷®lß^ý÷ú ݧě~}˘çŽlżQúĎ)t·Qž˛ut©ž«ł˝Fé?§ßFů©Ň‘'»Ż¬ň5ç>‰ü&ĘK•Ž<Ů}e•ר9÷Iä7Q^ŞtäÉî+«ĽFÎąO#»‰ôRĄ%Kv_Uĺ3rÎ}ŮM¤— -YŞçŞ ź‘3žÓČn#ýThÉR=WUřŚśńśFvé§BK–깪ÂgäŚç4ňŰHO™ZňDď•™>#µß“Č+"}ejÉ˝WfúŚÔ~O"Żô•©%O$«ĚôĄ-K"ŻŠň•©#O#«Ěôˇ-KˇŻŠđ–ĄˇO#ëČňëŐ•ą·WyýE÷Ű“Č;Ł={őäÎ}•^źQýľúî(ßV˝c‡ŐkDźß˝]!ÂżEĂî8¦ÓâŮÓăÚŻâÉ éő;ŤUĐx·ÔĆşŤUłäyę‰u—§ö”As—ç0OY“ŻŻÍsT«Ügş[×:Ş›¶ĺíźóľżc @€ @€ O$Đ~ć÷‰Ţ5ž[ÎŃ»×ÝogźňÜůťo™Fççł•łź˝FďWĘťíMovö7Y÷łrgĺ‘ęVç–úĘ®«ĘťťCŁ˙Ť™7>ŮŹćTÖfć®Ěˇ™••YăaFmFî943ż1óĆ'ňŃđžYKf™ßN3Ű—rďÖĚ\ˇvwn_­CăÁžtďÔĚ[ˇvwn_­CăÁžtďÔĚ[ˇvwn_­CăÁžtďÔĚ[ˇvwn_­CăÁžtďÔĚ[ˇvwî[­EęÁ—tď–Λ]·;öŻfg‘Î÷'ݤ3g×íŽý«ŮY¤óýIwéĚŮu»c˙jvé|ŇŁ‚tîĚşŁc˙nfélĘŁ‚tŁŰ¸Ý¬?g߲´łOÎ…w@€ @€ @ŕ{´źiöďsúţ®­Ď5ź°oŢďŢ-ĂÝ}ŢjW}÷^#×+ćŤĚ÷¤µJö'Źwłsgd’hÎĘ-ń–YSť;3‹F»2·ĆWvmEîě ZýěĚZ?UőYą«ü[ć|cćŤSôca_ÝťyÓ«Î`™™Ű2F™íf|/ďL{Ú˝Ó롪wě_UyŽăOű˙yÝł"łŤ@ĎđÖ¶”Ç®OČŮ{<ş·íz˝OXŰR^»>!ëć1ň!óş˙ýĹwöř„ßßţ”G2Ż÷ďéăŠŮńťůÎ+üůÝ|UY!ŰČĂŐiÜÉhŢ gq ÇJ+dě=Ś]ĆžöófŻc“Ý«ÍÎŮĎżwÓĎťµŽOő®8+ë6wć3#÷ĚĽmvuî6wö»*÷ěśçůŮąĎóVÚgd_)ßť—¨Üwú+ź{˛ŻśKâM“]˘÷I5}öÍ÷y˙IYđ @€ @€ @ż“@˙łëóşO|ľkűľfőuóüöŢrĽŐl÷+?˙žš•˛{rXzgg·xŽč™•;»GcFnŹßŢęĚž#4*sGřŤŇ¨Čĺ5J';s”ĎhťĚÜŃ^#ő2rGúËĐúĆĚÇČ'ă»DkFćÝ´˘ýeéEĺÎň—Ą‘;Ë[†nDŢM#Ă[–fTćOĘýŤ™·ß?QOÖďĹhݨĽ›N´·,=2űd}—h]_Ęcw´·,˝Łk˙.Ëg¤®?ĺ®é+Kkw·ĘňĄ—tWŠň–Ął;Ť[eyŤŇŤKş+EyËŇٝƮ˛üzucSռ޲úŹ.ăwYľ=şń)ŹŠo˝Gw9» ßVÍś„cU«Çčľ±»ĽÓh˙Z˝Ľd÷ĘZŹŃő÷Îro˘sHőrS˝«K}FÔ˝»©«Č#ѨK$›$ńě©‘ąSĺÉu×;'‰nęťwËąnňÜjKľľg®{ßô>‡dí›¶V÷·ĺíéoŮĎĎčě\Ă€ @€ @€ PI ý,˙i¦¤ć©…»–áîÝ{Ľ«ŮÎ?áyňďą[-»'‹¶w•ěZßŢúŮą˝ţ­ýłr[ýFőÍČĺÝŁS™Űă3ş·"w´ç˝ěÜŁ523G{ŤÔËĘé1Z+#s´Ç ˝čÜŁ5Éě#ý=˛ô|)ŹÝYŁuŹ®}»hoYzľ”Çî,ŹŃşG׾]´·,=_Ęcw–ÇhÝŁkß.Ú[–ž/ĺµ;Ëg¤îŐµď$Ň[†–/ݸ;Ăg¤ćصď4Ň_†–/ݸ;Ăg¤ćص˙4Ňc´–?ÝX!Úg¤Ţر˙4Ňc¤–?Ů˝B¤ĎH­{Çţ›Hź‘ZţdĎ ‘^Ł´žűoŁ|Féř˝+DyŤĐywWá׫—F®äőěí—;Ť­ôú¶öǦЩY={űt.ă«˝ţ5ýńîíŠßžZ»ĂśNOIoŽëU‰mMŚł\m¦»ú\—ńęw9¤çńŽęĄűş:wą“úLOë\sÔ[Ţmz[·÷GL… @€ @€ @ŕ ´>ŃŢw Ú}˙ľ«]ńĽ÷}·nľďîűóV»ę»÷˝^-stľ;˝rßyË<ź™;3×›ö¬Üoľ*Wdz›Q™ůÍKĺ}EîĘ<ŇYŮąĄ>*ë23WćĐÎĘĘ­őQYź‘ąŇżeÖ7fŢ8E>î3zČě#0ă›YfúR^»-*{®Žý'•ţ-łü Ź 3zŽ®ý»43ý Ż šů3jŻŽý'3rhfú^4ógÔ^ÇśĚČ"ť“đŞ"ť_]wuwRťE:/.áUI꡺îę4î¤:‹t^\±’ÔGUÝŘeěiUéśŘtc5©—Şş±ËřӪ׹oş%·oâ:ÝŇěë8ŽsҲ7ŶßŢ<€ @€ @€ @$Đ˙ł¨¶>ë·óŃű\»ę~ä}t¶ůťźĎVÍ)őÎŁŮŻ”]ăŰ[»BnoK˙ĚÜż‘=3˛Gú·h}cćŤSĺců.Y=ąłĽ{tłs{ĽeőffÎňěŐýĆĚłŚÇű-˛űż-sFŢM3ű;yő3r{=e÷“9†@öwňęǤ<Şx=e÷ÝĆě˛={őcRUĽž˛űŹncvŮž=ú1 Ç*_™˝c·1§™ľ=Ú1éĆ*_™˝c·1§™ľ­Ú1ÉîU¬ľ2űîÝĆÝdú×jÇĄzWŇzˬwS‘™A«“č]Eë+«ţÝi\EVŤn\ą’Ć_F­ÜileF‰fl ˝šÄcdŤŢaNGd¦'­÷6Ő'ź‘w6wą]‘ůz­\×~őŢkÄÚď¨F!"ë¦ń‰Ź'ű'ćmž-ą[ď§żĄŮ?=çČ˙]öQ-g€ @€ @€ @€žH˙ůă]Ývţ)ĎSëÝĘŮ­™$}«ĺ–xލY%wDŤĆěÜŻ‘µłrGf°hÍČmńÝS™;Ú»GŻ"·Ç_Fď7fŢ8f?ßĘ«™™Ůë-«źĚ±˛ľS„nlŇ]-Â[–Ćî2v•ĺ׫›ň¨ćő–Ůt·ËôěŃŽKxUňřĘě˝:Ť;ÉôíŃŽKxUňřĘě˝:Ť=ÉônŐŽMxUłúĘę»:Ś?ÉňnŐŤOxU´zË軺Ë9ÉđnŐĚI8VµzŚî»Ë;ŤöoŃËK7V¶xŚě»Ę=ŤôoŃĘMwŻnńŃsď(˙&ÂżV#?Őű­gOý»›ş OMo]˘÷IßÖÚws*¬yŢú椑O}óoą—Oź[iÉvî™›Ŕ6ýśAł·M\§K“u«ý-Ź4÷oÉŰçxĘŢ×±† @€ @€ @€ l¤˙śYZ·2Ő§ Ö»UóZóHűVË-őí­[%·7‡¶…ÜZĎő3sGř·jĚČmőŐ÷Ť™7v•OÔ·ňę9—€÷űDöç&ÝŐ#={µvWy+ŻÇčţĽ¤»r´gŻŢî,oĺőÝź—tWŽöěŐŰťĺ­ĽŁűó’îĘŃž˝z»łĽ•×ct^Ň]9ÚłWow–»ňúŚěĎMş«Gzöjí®rW^źQýą)ŻęQľ­:WGů'VŻQ}ů Ż˘Ľ[u®ŽjN¬~˝}5é®SĽľ=ýW7u'ßÖŢştĎ“¬ţ-}ĎNęn-Ţ-=u‰Ţ'Yük{Ţ]ÔWh3hęëÓČ'jrHkĺÓçUJłHëć%ŃM–ćyŞÓM\§ú)ÓÓÝ: ěNžňťďěSÖěĺëĎÖtíwuÎŘö~e @€ @€ @€ @ż‡@űçéýűś®żë×çşŐ÷˝÷ŃşůÝťĎZíĘďłçýŞy#˛=i¬–űÉkäÝ*ą#3I´fç–xŚ®ůĆĚĂYOô÷ÓęÍČ­ő]Oć|Ńß̢—źň8Áâ1Łçč*w—áߢ™›rW·xËęŮ]宲ü[ts“îęoY=»«ÜU–‹nnŇ]Ýâ-«gw•»ĘňoŐÍM{T·zŚě;:ĘÝEú¶jĺ&«[˝FöŤťĺťFz·hĺ%{V¶xŤčyv•{áߢ‘›ęYÝâ7˘çŮUîm„­Fn"™şÖł·^ć*żĘ›CÚźźD7AęŰZ§sSSmÍ"é«I`›"ńŻ­±9©íŇfzŞŻuî›ö”Csçs1§[“ď\;ÇqĚÔsÉ>fň\Iέć7>}ö–otÖî~Ó»˙¦-óoĘG@€ @€ @€ @€ !ĐţŢD˙>÷őwýú\·úľ÷>Z7˙Ł»óY«]ő}ö{·ßüßÝŤÎ?=ď(“älµÜĎ5+ĺŽČ#ŐX!·ÔkTÝěĚQ94:ßyă3óŃ|źČZ2×ün­ş¤ű$‹ĎČžÝIÍ*Ň»U«&é>Ĺę3şow”żŠönŐËOşO°zŚěŰÝÔ¬"˝[µj’§X˝FőÝÔí˘ükuę^'i˝FŐ_ťÔťDe°čÔĄ)2×›Ö»›šŠ7źQ÷5idS˘2˝éČÜÔT˝yŤ¸ŻI˘›‘k¤ˇs1§zäŰs6'…nŞ'ßąW7ynőŮ»e?7mş%çÖóMöß·Ď𖽯ýMë>wËő[~?·<Ľ!@€ @€ @€ @€ @ßF`ô÷?‘AźŁ_÷YúóŃşŻ]}=ňßÎzďíěéÝׯş~ňßî6ďm-yŻšU›C’µŻY1wď/cMć5d|ŰłćI\ś˝eíÉ<—@Öw=ëÎMyś~ö–µ?Nť·ËĘw§;/é>ůÎ[Öů>yŢ*+۝űä;oçűÔą«Ślwšs“§ßyŚ>?Nť»‹Îv§77ĺuúťĎČóëÔą'‘Ůî´ć&Ożóq>ž8˙4"ŰHc~˛{#żŢłűiëÜx3¶ţuÉś4ßž·lŇZUÖĽkĄ°ąąËľ©ťďlÖěşË¶ť˙ö§e˙í9Ďůľ5÷™{@€ @€ @€ @€ @€ yÚßi˝ű{Ëý}żžçŘ>ą÷߯{Ĺţ|´îkW_Źü·łŢ{;{z÷ő«®źü·»Í{[ż˝WÍŮ|˝ů·Ţ7ýßÖLo}+fmžŢĽ[ď›ţŠok&Iߊy7OďÖ2ŻCŔú %}ë¤<:‘x·Ö'­łłć‘ô­“ňčDâÝZsś´ÎΚGŇ·NĘŁ‰wkÍqŇ:;kIß:)ŻN$ţµ5×)kťhóĽŐŻ•něć-ö~ĎéďÚú\ó)űć˙üîýźďú}_÷)ëŢ˙yÝ2śĎĎűV÷ ďł÷óľe8źź÷­îŢgďç}Ëp>í[íęď‘wëŮęY›?kľQ_Ó\ý=ňn=[=kógÍ7ękš«żGŢ­g«gmţ¬ůF}Mső÷Č»őlő¬Íź5ߨŻi®ţy·ś­žł÷gÉ7ęé5W_Źü[ÎVĎŮűłä;÷ôzź˛>gĐî?%gďS›±Żďu>mÝçč×-G¶­ÓÓgësµóţŚ5 @€ @€ @€ @€ @€ @€ đ{ ´˙MŃčCŐßµő§“h9Ú»ĎÓÎÎďľćÓÖç,ŰľF÷í¬Żű¤uóßż{˙ýůyÝ×}ŇúścŰ÷Ďčľťőuź˛nŢĎďŢ˙ů®ß÷uź˛îý÷ëćż?­[Ý'˝G9¶łţŐl÷çşľgĺő(Ď9Ë]ÍąnĺśgoŁL}Íčľťőuź˛nŢĎďŢ˙ů®ß÷uź´î3´uďżťťß}ͧ­[–ćűĽßÎŰY˙nőźúnYú|ç,­¦˝Ď÷ź¶o9¶÷ö´w[÷÷mýgá˙Ňrôď>Nľ­ËÓrŤňôwż)ó–ő.ĎÝůg€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @€ @ŤŔ˙GÉJ¤•nipype-0.11.0/nipype/testing/data/track1.trk000066400000000000000000000000001257611314500206710ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/track2.trk000066400000000000000000000000001257611314500206720ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tracks.tck000066400000000000000000000000001257611314500207540ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tracks.trk000066400000000000000000000000001257611314500207730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tract_data.Bfloat000066400000000000000000000000001257611314500222210ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tracts.Bdouble000066400000000000000000000000001257611314500215600ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/trans.mat000066400000000000000000000000001257611314500206140ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tst_class0.nii000066400000000000000000000000001257611314500215420ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/tst_class1.nii000066400000000000000000000000001257611314500215430ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/u_rc1s1_Template.nii000066400000000000000000000000001257611314500225730ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/u_rc1s2_Template.nii000066400000000000000000000000001257611314500225740ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/u_rc1s3_Template.nii000066400000000000000000000000001257611314500225750ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/varcope.nii.gz000066400000000000000000000000001257611314500215410ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/varcope1run1.nii.gz000066400000000000000000000000001257611314500224300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/varcope1run2.nii.gz000066400000000000000000000000001257611314500224310ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/varcope2run1.nii.gz000066400000000000000000000000001257611314500224310ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/varcope2run2.nii.gz000066400000000000000000000000001257611314500224320ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/voxel-order_data.Bfloat000066400000000000000000000000001257611314500233520ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/vsm.nii000066400000000000000000000000001257611314500202700ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/warpfield.nii000066400000000000000000000000001257611314500214400ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/weights.txt000066400000000000000000000000001257611314500211750ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/wm.mgz000066400000000000000000000000001257611314500201240ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/wm_mask.mif000066400000000000000000000000001257611314500211150ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/wm_undersampled.nii000066400000000000000000000000001257611314500226510ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/data/zstat1.nii.gz000066400000000000000000000000001257611314500213300ustar00rootroot00000000000000nipype-0.11.0/nipype/testing/decorators.py000066400000000000000000000044201257611314500206020ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Extend numpy's decorators to use nipype's gui and data labels. """ from numpy.testing.decorators import * from nipype.external import six from nibabel.data import DataError def make_label_dec(label, ds=None): """Factory function to create a decorator that applies one or more labels. Parameters ---------- label : str or sequence One or more labels that will be applied by the decorator to the functions it decorates. Labels are attributes of the decorated function with their value set to True. ds : str An optional docstring for the resulting decorator. If not given, a default docstring is auto-generated. Returns ------- ldec : function A decorator. Examples -------- >>> slow = make_label_dec('slow') >>> print slow.__doc__ Labels a test as 'slow' >>> rare = make_label_dec(['slow','hard'], ... "Mix labels 'slow' and 'hard' for rare tests") >>> @rare ... def f(): pass ... >>> >>> f.slow True >>> f.hard True """ if isinstance(label,six.string_types): labels = [label] else: labels = label # Validate that the given label(s) are OK for use in setattr() by doing a # dry run on a dummy function. tmp = lambda : None for label in labels: setattr(tmp,label,True) # This is the actual decorator we'll return def decor(f): for label in labels: setattr(f,label,True) return f # Apply the user's docstring if ds is None: ds = "Labels a test as %r" % label decor.__doc__ = ds return decor # For tests that need further review def needs_review(msg): """ Skip a test that needs further review. Parameters ---------- msg : string msg regarding the review that needs to be done """ def skip_func(func): return skipif(True, msg)(func) return skip_func # Easier version of the numpy knownfailure def knownfailure(f): return knownfailureif(True)(f) def if_datasource(ds, msg): try: ds.get_filename() except DataError: return skipif(True, msg) return lambda f : f nipype-0.11.0/nipype/testing/utils.py000066400000000000000000000011651257611314500176000ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Additional handy utilities for testing """ __docformat__ = 'restructuredtext' from ..utils.misc import package_check from nose import SkipTest def skip_if_no_package(*args, **kwargs): """Raise SkipTest if package_check fails Parameters ---------- *args Positional parameters passed to `package_check` *kwargs Keyword parameters passed to `package_check` """ package_check(exc_failed_import=SkipTest, exc_failed_check=SkipTest, *args, **kwargs) nipype-0.11.0/nipype/utils/000077500000000000000000000000001257611314500155465ustar00rootroot00000000000000nipype-0.11.0/nipype/utils/README.txt000066400000000000000000000003701257611314500172440ustar00rootroot00000000000000================== Nipype Utilities ================== This directory contains various utilities used in nipype. Some of them have been copied from nipy. Any changes to these should be done upstream. * From nipy: * onetime.py * tmpdirs.py nipype-0.11.0/nipype/utils/__init__.py000066400000000000000000000001641257611314500176600ustar00rootroot00000000000000 from onetime import OneTimeProperty, setattr_on_read from tmpdirs import TemporaryDirectory, InTemporaryDirectory nipype-0.11.0/nipype/utils/config.py000066400000000000000000000125451257611314500173740ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: ''' Created on 20 Apr 2010 logging options : INFO, DEBUG hash_method : content, timestamp @author: Chris Filo Gorgolewski ''' import ConfigParser from json import load, dump import os import shutil import errno from StringIO import StringIO from warnings import warn from ..external import portalocker # Get home directory in platform-agnostic way homedir = os.path.expanduser('~') default_cfg = """ [logging] workflow_level = INFO filemanip_level = INFO interface_level = INFO log_to_file = false log_directory = %s log_size = 16384000 log_rotate = 4 [execution] create_report = true crashdump_dir = %s display_variable = :1 hash_method = timestamp job_finished_timeout = 5 keep_inputs = false local_hash_check = true matplotlib_backend = Agg plugin = Linear remove_node_directories = false remove_unnecessary_outputs = true try_hard_link_datasink = true single_thread_matlab = true stop_on_first_crash = false stop_on_first_rerun = false use_relative_paths = false stop_on_unknown_version = false write_provenance = false parameterize_dirs = true poll_sleep_duration = 60 xvfb_max_wait = 10 [check] interval = 1209600 """ % (homedir, os.getcwd()) def mkdir_p(path): try: os.makedirs(path) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise class NipypeConfig(object): """Base nipype config class """ def __init__(self, *args, **kwargs): self._config = ConfigParser.ConfigParser() config_dir = os.path.expanduser('~/.nipype') mkdir_p(config_dir) old_config_file = os.path.expanduser('~/.nipype.cfg') new_config_file = os.path.join(config_dir, 'nipype.cfg') # To be deprecated in two releases if os.path.exists(old_config_file): if os.path.exists(new_config_file): msg=("Detected presence of both old (%s, used by versions " "< 0.5.2) and new (%s) config files. This version will " "proceed with the new one. We advise to merge settings " "and remove old config file if you are not planning to " "use previous releases of nipype.") % (old_config_file, new_config_file) warn(msg) else: warn("Moving old config file from: %s to %s" % (old_config_file, new_config_file)) shutil.move(old_config_file, new_config_file) self.data_file = os.path.join(config_dir, 'nipype.json') self._config.readfp(StringIO(default_cfg)) self._config.read([new_config_file, old_config_file, 'nipype.cfg']) def set_default_config(self): self._config.readfp(StringIO(default_cfg)) def enable_debug_mode(self): """Enables debug configuration """ self._config.set('execution', 'stop_on_first_crash', 'true') self._config.set('execution', 'remove_unnecessary_outputs', 'false') self._config.set('execution', 'keep_inputs', 'true') self._config.set('logging', 'workflow_level', 'DEBUG') self._config.set('logging', 'interface_level', 'DEBUG') def set_log_dir(self, log_dir): """Sets logging directory This should be the first thing that is done before any nipype class with logging is imported. """ self._config.set('logging', 'log_directory', log_dir) def get(self, section, option): return self._config.get(section, option) def set(self, section, option, value): return self._config.set(section, option, value) def getboolean(self, section, option): return self._config.getboolean(section, option) def has_option(self, section, option): return self._config.has_option(section, option) @property def _sections(self): return self._config._sections def get_data(self, key): if not os.path.exists(self.data_file): return None with open(self.data_file, 'rt') as file: portalocker.lock(file, portalocker.LOCK_EX) datadict = load(file) if key in datadict: return datadict[key] return None def save_data(self, key, value): datadict = {} if os.path.exists(self.data_file): with open(self.data_file, 'rt') as file: portalocker.lock(file, portalocker.LOCK_EX) datadict = load(file) with open(self.data_file, 'wt') as file: portalocker.lock(file, portalocker.LOCK_EX) datadict[key] = value dump(datadict, file) def update_config(self, config_dict): for section in ['execution', 'logging', 'check']: if section in config_dict: for key, val in config_dict[section].items(): if not key.startswith('__'): self._config.set(section, key, str(val)) def update_matplotlib(self): import matplotlib matplotlib.use(self.get('execution', 'matplotlib_backend')) def enable_provenance(self): self._config.set('execution', 'write_provenance', 'true') self._config.set('execution', 'hash_method', 'content') nipype-0.11.0/nipype/utils/docparse.py000066400000000000000000000254661257611314500177350ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Utilities to pull in documentation from command-line tools. Examples -------- # Instantiate bet object from nipype.interfaces import fsl from nipype.utils import docparse better = fsl.Bet() docstring = docparse.get_doc(better.cmd, better.opt_map) """ import subprocess from nipype.interfaces.base import CommandLine from nipype.utils.misc import is_container from nipype.external import six def grab_doc(cmd, trap_error=True): """Run cmd without args and grab documentation. Parameters ---------- cmd : string Command line string trap_error : boolean Ensure that returncode is 0 Returns ------- doc : string The command line documentation """ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout, stderr = proc.communicate() if trap_error and proc.returncode: msg = 'Attempting to run %s. Returned Error: %s'%(cmd,stderr) raise IOError(msg) if stderr: # A few programs, like fast and fnirt, send their help to # stderr instead of stdout. # XXX: Test for error vs. doc in stderr return stderr return stdout def reverse_opt_map(opt_map): """Reverse the key/value pairs of the option map in the interface classes. Parameters ---------- opt_map : dict Dictionary mapping the attribute name to a command line flag. Each interface class defines these for the command it wraps. Returns ------- rev_opt_map : dict Dictionary mapping the flags to the attribute name. """ # For docs, we only care about the mapping from our attribute # names to the command-line flags. The 'v.split()[0]' below # strips off the string format characters. # if (k != 'flags' and v) , key must not be flags as it is generic, # v must not be None or it cannot be parsed by this line revdict = {} for key, value in opt_map.items(): if is_container(value): # The value is a tuple where the first element is the # format string and the second element is a docstring. value = value[0] if (key != 'flags' and value is not None): revdict[value.split()[0]] = key return revdict def format_params(paramlist, otherlist=None): """Format the parameters according to the nipy style conventions. Since the external programs do not conform to any conventions, the resulting docstrings are not ideal. But at a minimum the Parameters section is reasonably close. Parameters ---------- paramlist : list List of strings where each list item matches exactly one parameter and it's description. These items will go into the 'Parameters' section of the docstring. otherlist : list List of strings, similar to paramlist above. These items will go into the 'Other Parameters' section of the docstring. Returns ------- doc : string The formatted docstring. """ hdr = 'Parameters' delim = '----------' paramlist.insert(0, delim) paramlist.insert(0, hdr) params = '\n'.join(paramlist) otherparams = [] doc = ''.join(params) if otherlist: hdr = 'Others Parameters' delim = '-----------------' otherlist.insert(0, delim) otherlist.insert(0, hdr) otherlist.insert(0, '\n') otherparams = '\n'.join(otherlist) doc = ''.join([doc, otherparams]) return doc def insert_doc(doc, new_items): """Insert ``new_items`` into the beginning of the ``doc`` Docstrings in ``new_items`` will be inserted right after the *Parameters* header but before the existing docs. Parameters ---------- doc : str The existing docstring we're inserting docmentation into. new_items : list List of strings to be inserted in the ``doc``. Examples -------- >>> from nipype.utils.docparse import insert_doc >>> doc = '''Parameters ... ---------- ... outline : ... something about an outline''' >>> new_items = ['infile : str', ' The name of the input file'] >>> new_items.extend(['outfile : str', ' The name of the output file']) >>> newdoc = insert_doc(doc, new_items) >>> print newdoc Parameters ---------- infile : str The name of the input file outfile : str The name of the output file outline : something about an outline """ # Insert new_items after the Parameters header doclist = doc.split('\n') tmpdoc = doclist[:2] # Add new_items tmpdoc.extend(new_items) # Add rest of documents tmpdoc.extend(doclist[2:]) # Insert newlines newdoc = [] for line in tmpdoc: newdoc.append(line) newdoc.append('\n') # We add one too many newlines, remove it. newdoc.pop(-1) return ''.join(newdoc) def build_doc(doc, opts): """Build docstring from doc and options Parameters ---------- rep_doc : string Documentation string opts : dict Dictionary of option attributes and keys. Use reverse_opt_map to reverse flags and attrs from opt_map class attribute. Returns ------- newdoc : string The docstring with flags replaced with attribute names and formated to match nipy standards (as best we can). """ # Split doc into line elements. Generally, each line is an # individual flag/option. doclist = doc.split('\n') newdoc = [] flags_doc = [] for line in doclist: linelist = line.split() if not linelist: # Probably an empty line continue # For lines we care about, the first item is the flag if ',' in linelist[0]: #sometimes flags are only seperated by comma flag = linelist[0].split(',')[0] else: flag = linelist[0] attr = opts.get(flag) if attr is not None: #newline = line.replace(flag, attr) # Replace the flag with our attribute name linelist[0] = '%s :' % str(attr) # Add some line formatting linelist.insert(1, '\n ') newline = ' '.join(linelist) newdoc.append(newline) else: if line[0].isspace(): # For all the docs I've looked at, the flags all have # indentation (spaces) at the start of the line. # Other parts of the docs, like 'usage' statements # start with alpha-numeric characters. We only care # about the flags. flags_doc.append(line) return format_params(newdoc, flags_doc) def get_doc(cmd, opt_map, help_flag=None, trap_error=True): """Get the docstring from our command and options map. Parameters ---------- cmd : string The command whose documentation we are fetching opt_map : dict Dictionary of flags and option attributes. help_flag : string Provide additional help flag. e.g., -h trap_error : boolean Override if underlying command returns a non-zero returncode Returns ------- doc : string The formated docstring """ res = CommandLine('which %s' % cmd.split(' ')[0], terminal_output='allatonce').run() cmd_path = res.runtime.stdout.strip() if cmd_path == '': raise Exception('Command %s not found'%cmd.split(' ')[0]) if help_flag: cmd = ' '.join((cmd,help_flag)) doc = grab_doc(cmd,trap_error) opts = reverse_opt_map(opt_map) return build_doc(doc, opts) def _parse_doc(doc, style=['--']): """Parses a help doc for inputs Parameters ---------- doc : string Documentation string style : string default ['--'] The help command style (--, -) Returns ------- optmap : dict of input parameters """ # Split doc into line elements. Generally, each line is an # individual flag/option. doclist = doc.split('\n') optmap = {} if isinstance(style,six.string_types): style = [style] for line in doclist: linelist = line.split() flag =[item for i,item in enumerate(linelist) if i<2 and \ any([item.startswith(s) for s in style]) and \ len(item)>1] if flag: if len(flag)==1: style_idx = [flag[0].startswith(s) for s in style].index(True) flag = flag[0] else: style_idx = [] for f in flag: for i,s in enumerate(style): if f.startswith(s): style_idx.append(i) break flag = flag[style_idx.index(min(style_idx))] style_idx = min(style_idx) optmap[flag.split(style[style_idx])[1]] = '%s %%s'%flag return optmap def get_params_from_doc(cmd, style='--', help_flag=None, trap_error=True): """Auto-generate option map from command line help Parameters ---------- cmd : string The command whose documentation we are fetching style : string default ['--'] The help command style (--, -). Multiple styles can be provided in a list e.g. ['--','-']. help_flag : string Provide additional help flag. e.g., -h trap_error : boolean Override if underlying command returns a non-zero returncode Returns ------- optmap : dict Contains a mapping from input to command line variables """ res = CommandLine('which %s' % cmd.split(' ')[0], terminal_output='allatonce').run() cmd_path = res.runtime.stdout.strip() if cmd_path == '': raise Exception('Command %s not found'%cmd.split(' ')[0]) if help_flag: cmd = ' '.join((cmd,help_flag)) doc = grab_doc(cmd,trap_error) return _parse_doc(doc,style) def replace_opts(rep_doc, opts): """Replace flags with parameter names. This is a simple operation where we replace the command line flags with the attribute names. Parameters ---------- rep_doc : string Documentation string opts : dict Dictionary of option attributes and keys. Use reverse_opt_map to reverse flags and attrs from opt_map class attribute. Returns ------- rep_doc : string New docstring with flags replaces with attribute names. Examples -------- doc = grab_doc('bet') opts = reverse_opt_map(fsl.Bet.opt_map) rep_doc = replace_opts(doc, opts) """ # Replace flags with attribute names for key, val in opts.items(): rep_doc = rep_doc.replace(key, val) return rep_doc nipype-0.11.0/nipype/utils/filemanip.py000066400000000000000000000314271257611314500200730ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Miscellaneous file manipulation functions """ import cPickle from glob import glob import gzip import hashlib from hashlib import md5 import json import os import re import shutil import numpy as np from ..interfaces.traits_extension import isdefined from .misc import is_container from .config import mkdir_p from .. import logging, config fmlogger = logging.getLogger("filemanip") class FileNotFoundError(Exception): pass def nipype_hardlink_wrapper(raw_src, raw_dst): """Attempt to use hard link instead of file copy. The intent is to avoid unnnecessary duplication of large files when using a DataSink. Hard links are not supported on all file systems or os environments, and will not succeed if the src and dst are not on the same physical hardware partition. If the hardlink fails, then fall back to using a standard copy. """ src = os.path.normpath(raw_src) dst = os.path.normpath(raw_dst) del raw_src del raw_dst if src != dst and os.path.exists(dst): os.unlink(dst) # First remove destination try: os.link(src, dst) # Reference same inode to avoid duplication except: shutil.copyfile(src, dst) # Fall back to traditional copy def split_filename(fname): """Split a filename into parts: path, base filename and extension. Parameters ---------- fname : str file or path name Returns ------- pth : str base path from fname fname : str filename from fname, without extension ext : str file extension from fname Examples -------- >>> from nipype.utils.filemanip import split_filename >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') >>> pth '/home/data' >>> fname 'subject' >>> ext '.nii.gz' """ special_extensions = [".nii.gz", ".tar.gz"] pth = os.path.dirname(fname) fname = os.path.basename(fname) ext = None for special_ext in special_extensions: ext_len = len(special_ext) if (len(fname) > ext_len) and \ (fname[-ext_len:].lower() == special_ext.lower()): ext = fname[-ext_len:] fname = fname[:-ext_len] break if not ext: fname, ext = os.path.splitext(fname) return pth, fname, ext def fname_presuffix(fname, prefix='', suffix='', newpath=None, use_ext=True): """Manipulates path and name of input filename Parameters ---------- fname : string A filename (may or may not include path) prefix : string Characters to prepend to the filename suffix : string Characters to append to the filename newpath : string Path to replace the path of the input fname use_ext : boolean If True (default), appends the extension of the original file to the output name. Returns ------- Absolute path of the modified filename >>> from nipype.utils.filemanip import fname_presuffix >>> fname = 'foo.nii.gz' >>> fname_presuffix(fname,'pre','post','/tmp') '/tmp/prefoopost.nii.gz' """ pth, fname, ext = split_filename(fname) if not use_ext: ext = '' if newpath and isdefined(newpath): pth = os.path.abspath(newpath) return os.path.join(pth, prefix + fname + suffix + ext) def fnames_presuffix(fnames, prefix='', suffix='', newpath=None, use_ext=True): """Calls fname_presuffix for a list of files. """ f2 = [] for fname in fnames: f2.append(fname_presuffix(fname, prefix, suffix, newpath, use_ext)) return f2 def hash_rename(filename, hashvalue): """renames a file given original filename and hash and sets path to output_directory """ path, name, ext = split_filename(filename) newfilename = ''.join((name, '_0x', hashvalue, ext)) return os.path.join(path, newfilename) def check_forhash(filename): """checks if file has a hash in its filename""" if isinstance(filename, list): filename = filename[0] path, name = os.path.split(filename) if re.search('(_0x[a-z0-9]{32})', name): hashvalue = re.findall('(_0x[a-z0-9]{32})', name) return True, hashvalue else: return False, None def hash_infile(afile, chunk_len=8192, crypto=hashlib.md5): """ Computes hash of a file using 'crypto' module""" hex = None if os.path.isfile(afile): crypto_obj = crypto() fp = file(afile, 'rb') while True: data = fp.read(chunk_len) if not data: break crypto_obj.update(data) fp.close() hex = crypto_obj.hexdigest() return hex def hash_timestamp(afile): """ Computes md5 hash of the timestamp of a file """ md5hex = None if os.path.isfile(afile): md5obj = md5() stat = os.stat(afile) md5obj.update(str(stat.st_size)) md5obj.update(str(stat.st_mtime)) md5hex = md5obj.hexdigest() return md5hex def copyfile(originalfile, newfile, copy=False, create_new=False, hashmethod=None, use_hardlink=False): """Copy or symlink ``originalfile`` to ``newfile``. Parameters ---------- originalfile : str full path to original file newfile : str full path to new file copy : Bool specifies whether to copy or symlink files (default=False) but only for POSIX systems Returns ------- None """ newhash = None orighash = None fmlogger.debug(newfile) if create_new: while os.path.exists(newfile): base, fname, ext = split_filename(newfile) s = re.search('_c[0-9]{4,4}$', fname) i = 0 if s: i = int(s.group()[2:])+1 fname = fname[:-6] + "_c%04d" % i else: fname += "_c%04d" % i newfile = base + os.sep + fname + ext if hashmethod is None: hashmethod = config.get('execution', 'hash_method').lower() elif os.path.exists(newfile): if hashmethod == 'timestamp': newhash = hash_timestamp(newfile) elif hashmethod == 'content': newhash = hash_infile(newfile) fmlogger.debug("File: %s already exists,%s, copy:%d" % (newfile, newhash, copy)) #the following seems unnecessary #if os.name is 'posix' and copy: # if os.path.lexists(newfile) and os.path.islink(newfile): # os.unlink(newfile) # newhash = None if os.name is 'posix' and not copy: if os.path.lexists(newfile): if hashmethod == 'timestamp': orighash = hash_timestamp(originalfile) elif hashmethod == 'content': orighash = hash_infile(originalfile) fmlogger.debug('Original hash: %s, %s' % (originalfile, orighash)) if newhash != orighash: os.unlink(newfile) if (newhash is None) or (newhash != orighash): os.symlink(originalfile, newfile) else: if newhash: if hashmethod == 'timestamp': orighash = hash_timestamp(originalfile) elif hashmethod == 'content': orighash = hash_infile(originalfile) if (newhash is None) or (newhash != orighash): try: fmlogger.debug("Copying File: %s->%s" % (newfile, originalfile)) if use_hardlink: nipype_hardlink_wrapper(originalfile, newfile) else: shutil.copyfile(originalfile, newfile) except shutil.Error, e: fmlogger.warn(e.message) else: fmlogger.debug("File: %s already exists, not overwriting, copy:%d" % (newfile, copy)) if originalfile.endswith(".img"): hdrofile = originalfile[:-4] + ".hdr" hdrnfile = newfile[:-4] + ".hdr" matofile = originalfile[:-4] + ".mat" if os.path.exists(matofile): matnfile = newfile[:-4] + ".mat" copyfile(matofile, matnfile, copy) copyfile(hdrofile, hdrnfile, copy) elif originalfile.endswith(".BRIK"): hdrofile = originalfile[:-5] + ".HEAD" hdrnfile = newfile[:-5] + ".HEAD" copyfile(hdrofile, hdrnfile, copy) return newfile def get_related_files(filename): """Returns a list of related files for Nifti-Pair, Analyze (SPM) and AFNI files """ related_files = [] if filename.endswith(".img") or filename.endswith(".hdr"): path, name, ext = split_filename(filename) for ext in ['.hdr', '.img', '.mat']: related_files.append(os.path.join(path, name + ext)) elif filename.endswith(".BRIK") or filename.endswith(".HEAD"): path, name, ext = split_filename(filename) for ext in ['.BRIK', '.HEAD']: related_files.append(os.path.join(path, name + ext)) if not len(related_files): related_files = [filename] return related_files def copyfiles(filelist, dest, copy=False, create_new=False): """Copy or symlink files in ``filelist`` to ``dest`` directory. Parameters ---------- filelist : list List of files to copy. dest : path/files full path to destination. If it is a list of length greater than 1, then it assumes that these are the names of the new files. copy : Bool specifies whether to copy or symlink files (default=False) but only for posix systems Returns ------- None """ outfiles = filename_to_list(dest) newfiles = [] for i, f in enumerate(filename_to_list(filelist)): if isinstance(f, list): newfiles.insert(i, copyfiles(f, dest, copy=copy, create_new=create_new)) else: if len(outfiles) > 1: destfile = outfiles[i] else: destfile = fname_presuffix(f, newpath=outfiles[0]) destfile = copyfile(f, destfile, copy, create_new=create_new) newfiles.insert(i, destfile) return newfiles def filename_to_list(filename): """Returns a list given either a string or a list """ if isinstance(filename, (str, unicode)): return [filename] elif isinstance(filename, list): return filename elif is_container(filename): return [x for x in filename] else: return None def list_to_filename(filelist): """Returns a list if filelist is a list of length greater than 1, otherwise returns the first element """ if len(filelist) > 1: return filelist else: return filelist[0] def save_json(filename, data): """Save data to a json file Parameters ---------- filename : str Filename to save data in. data : dict Dictionary to save in json file. """ fp = file(filename, 'w') json.dump(data, fp, sort_keys=True, indent=4) fp.close() def load_json(filename): """Load data from a json file Parameters ---------- filename : str Filename to load data from. Returns ------- data : dict """ fp = file(filename, 'r') data = json.load(fp) fp.close() return data def loadcrash(infile, *args): if '.pkl' in infile: return loadpkl(infile) elif '.npz' in infile: DeprecationWarning(('npz files will be deprecated in the next ' 'release. you can use numpy to open them.')) data = np.load(infile) out = {} for k in data.files: out[k] = [f for f in data[k].flat] if len(out[k]) == 1: out[k] = out[k].pop() return out else: raise ValueError('Only pickled crashfiles are supported') def loadpkl(infile): """Load a zipped or plain cPickled file """ if infile.endswith('pklz'): pkl_file = gzip.open(infile, 'rb') else: pkl_file = open(infile) return cPickle.load(pkl_file) def savepkl(filename, record): if filename.endswith('pklz'): pkl_file = gzip.open(filename, 'wb') else: pkl_file = open(filename, 'wb') cPickle.dump(record, pkl_file) pkl_file.close() rst_levels = ['=', '-', '~', '+'] def write_rst_header(header, level=0): return '\n'.join((header, ''.join([rst_levels[level] for _ in header]))) + '\n\n' def write_rst_list(items, prefix=''): out = [] for item in items: out.append(prefix + ' ' + str(item)) return '\n'.join(out)+'\n\n' def write_rst_dict(info, prefix=''): out = [] for key, value in sorted(info.items()): out.append(prefix + '* ' + key + ' : ' + str(value)) return '\n'.join(out)+'\n\n' nipype-0.11.0/nipype/utils/logger.py000066400000000000000000000113221257611314500173760ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import logging import os import sys try: from ..external.cloghandler import ConcurrentRotatingFileHandler as \ RFHandler except ImportError: # Next 2 lines are optional: issue a warning to the user from warnings import warn warn("ConcurrentLogHandler not installed. Using builtin log handler") from logging.handlers import RotatingFileHandler as RFHandler from .misc import str2bool from .config import NipypeConfig class Logging(object): """Nipype logging class """ fmt = ('%(asctime)s,%(msecs)d %(name)-2s ' '%(levelname)-2s:\n\t %(message)s') datefmt = '%y%m%d-%H:%M:%S' def __init__(self, config): self._config = config logging.basicConfig(format=self.fmt, datefmt=self.datefmt, stream=sys.stdout) #logging.basicConfig(stream=sys.stdout) self._logger = logging.getLogger('workflow') self._fmlogger = logging.getLogger('filemanip') self._iflogger = logging.getLogger('interface') self.loggers = {'workflow': self._logger, 'filemanip': self._fmlogger, 'interface': self._iflogger} self._hdlr = None self.update_logging(self._config) def enable_file_logging(self): config = self._config LOG_FILENAME = os.path.join(config.get('logging', 'log_directory'), 'pypeline.log') hdlr = RFHandler(LOG_FILENAME, maxBytes=int(config.get('logging', 'log_size')), backupCount=int(config.get('logging', 'log_rotate'))) formatter = logging.Formatter(fmt=self.fmt, datefmt=self.datefmt) hdlr.setFormatter(formatter) self._logger.addHandler(hdlr) self._fmlogger.addHandler(hdlr) self._iflogger.addHandler(hdlr) self._hdlr = hdlr def disable_file_logging(self): if self._hdlr: self._logger.removeHandler(self._hdlr) self._fmlogger.removeHandler(self._hdlr) self._iflogger.removeHandler(self._hdlr) self._hdlr = None def update_logging(self, config): self._config = config self.disable_file_logging() self._logger.setLevel(logging.getLevelName(config.get('logging', 'workflow_level'))) self._fmlogger.setLevel(logging.getLevelName(config.get('logging', 'filemanip_level'))) self._iflogger.setLevel(logging.getLevelName(config.get('logging', 'interface_level'))) if str2bool(config.get('logging', 'log_to_file')): self.enable_file_logging() def getLogger(self, name): if name in self.loggers: return self.loggers[name] return None def getLevelName(self, name): return logging.getLevelName(name) def logdebug_dict_differences(self, dold, dnew, prefix=""): """Helper to log what actually changed from old to new values of dictionaries. typical use -- log difference for hashed_inputs """ # Compare against hashed_inputs # Keys: should rarely differ new_keys = set(dnew.keys()) old_keys = set(dold.keys()) if len(new_keys - old_keys): self._logger.debug("%s not previously seen: %s" % (prefix, new_keys - old_keys)) if len(old_keys - new_keys): self._logger.debug("%s not presently seen: %s" % (prefix, old_keys - new_keys)) # Values in common keys would differ quite often, # so we need to join the messages together msgs = [] for k in new_keys.intersection(old_keys): same = False try: new, old = dnew[k], dold[k] same = new == old if not same: # Since JSON does not discriminate between lists and # tuples, we might need to cast them into the same type # as the last resort. And lets try to be more generic same = old.__class__(new) == old except Exception, e: same = False if not same: msgs += ["%s: %r != %r" % (k, dnew[k], dold[k])] if len(msgs): self._logger.debug("%s values differ in fields: %s" % (prefix, ", ".join(msgs))) nipype-0.11.0/nipype/utils/matlabtools.py000066400000000000000000000042071257611314500204440ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Useful Functions for working with matlab""" # Stdlib imports import os import re import tempfile # Functions, classes and other top-level code def fltcols(vals): ''' Trivial little function to make 1xN float vector ''' return np.atleast_2d(np.array(vals, dtype=float)) def mlab_tempfile(dir=None): """Returns a temporary file-like object with valid matlab name. The file name is accessible as the .name attribute of the returned object. The caller is responsible for closing the returned object, at which time the underlying file gets deleted from the filesystem. Parameters ---------- dir : str A path to use as the starting directory. Note that this directory must already exist, it is NOT created if it doesn't (in that case, OSError is raised instead). Returns ------- f : A file-like object. Examples -------- >>> fn = mlab_tempfile() >>> import os >>> filename = os.path.basename(fn.name) >>> '-' not in filename True >>> fn.close() """ valid_name = re.compile(r'^\w+$') # Make temp files until we get one whose name is a valid matlab identifier, # since matlab imposes that constraint. Since the temp file routines may # return names that aren't valid matlab names, but we can't control that # directly, we just keep trying until we get a valid name. To avoid an # infinite loop for some strange reason, we only try 100 times. for n in range(100): f = tempfile.NamedTemporaryFile(suffix='.m',prefix='tmp_matlab_', dir=dir) # Check the file name for matlab compilance fname = os.path.splitext(os.path.basename(f.name))[0] if valid_name.match(fname): break # Close the temp file we just made if its name is not valid; the # tempfile module then takes care of deleting the actual file on disk. f.close() else: raise ValueError("Could not make temp file after 100 tries") return f nipype-0.11.0/nipype/utils/misc.py000066400000000000000000000156071257611314500170640ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Miscellaneous utility functions """ from cPickle import dumps, loads import inspect from distutils.version import LooseVersion import numpy as np from textwrap import dedent import sys import re from nipype.external.six import Iterator def human_order_sorted(l): """Sorts string in human order (i.e. 'stat10' will go after 'stat2')""" def atoi(text): return int(text) if text.isdigit() else text def natural_keys(text): if isinstance(text, tuple): text = text[0] return [ atoi(c) for c in re.split('(\d+)', text) ] return sorted(l, key=natural_keys) def trim(docstring, marker=None): if not docstring: return '' # Convert tabs to spaces (following the normal Python rules) # and split into a list of lines: lines = docstring.expandtabs().splitlines() # Determine minimum indentation (first line doesn't count): indent = sys.maxint for line in lines[1:]: stripped = line.lstrip() if stripped: indent = min(indent, len(line) - len(stripped)) # Remove indentation (first line is special): trimmed = [lines[0].strip()] if indent < sys.maxint: for line in lines[1:]: # replace existing REST marker with doc level marker stripped = line.lstrip().strip().rstrip() if marker is not None and stripped and \ all([s==stripped[0] for s in stripped]) and \ stripped[0] not in [':']: line = line.replace(stripped[0], marker) trimmed.append(line[indent:].rstrip()) # Strip off trailing and leading blank lines: while trimmed and not trimmed[-1]: trimmed.pop() while trimmed and not trimmed[0]: trimmed.pop(0) # Return a single string: return '\n'.join(trimmed) def getsource(function): """Returns the source code of a function""" src = dumps(dedent(inspect.getsource(function))) return src def create_function_from_source(function_source, imports=None): """Return a function object from a function source Parameters ---------- function_source : pickled string string in pickled form defining a function imports : list of strings list of import statements in string form that allow the function to be executed in an otherwise empty namespace """ ns = {} import_keys = [] try: if imports is not None: for statement in imports: exec statement in ns import_keys = ns.keys() exec loads(function_source) in ns except Exception, msg: msg = str(msg) + '\nError executing function:\n %s\n'%function_source msg += '\n'.join(["Functions in connection strings have to be standalone.", "They cannot be declared either interactively or inside", "another function or inline in the connect string. Any", "imports should be done inside the function" ]) raise RuntimeError(msg) ns_funcs = list(set(ns) - set(import_keys + ['__builtins__'])) assert len(ns_funcs) == 1, "Function or inputs are ill-defined" funcname = ns_funcs[0] func = ns[funcname] return func def find_indices(condition): "Return the indices where ravel(condition) is true" res, = np.nonzero(np.ravel(condition)) return res def is_container(item): """Checks if item is a container (list, tuple, dict, set) Parameters ---------- item : object object to check for .__iter__ Returns ------- output : Boolean True if container False if not (eg string) """ if hasattr(item, '__iter__'): return True else: return False def container_to_string(cont): """Convert a container to a command line string. Elements of the container are joined with a space between them, suitable for a command line parameter. If the container `cont` is only a sequence, like a string and not a container, it is returned unmodified. Parameters ---------- cont : container A container object like a list, tuple, dict, or a set. Returns ------- cont_str : string Container elements joined into a string. """ if hasattr(cont, '__iter__'): return ' '.join(cont) else: return str(cont) # Dependency checks. Copied this from Nipy, with some modificiations # (added app as a parameter). def package_check(pkg_name, version=None, app=None, checker=LooseVersion, exc_failed_import=ImportError, exc_failed_check=RuntimeError): """Check that the minimal version of the required package is installed. Parameters ---------- pkg_name : string Name of the required package. version : string, optional Minimal version number for required package. app : string, optional Application that is performing the check. For instance, the name of the tutorial being executed that depends on specific packages. Default is *Nipype*. checker : object, optional The class that will perform the version checking. Default is distutils.version.LooseVersion. exc_failed_import : Exception, optional Class of the exception to be thrown if import failed. exc_failed_check : Exception, optional Class of the exception to be thrown if version check failed. Examples -------- package_check('numpy', '1.3') package_check('networkx', '1.0', 'tutorial1') """ if app: msg = '%s requires %s' % (app, pkg_name) else: msg = 'Nipype requires %s' % pkg_name if version: msg += ' with version >= %s' % (version,) try: mod = __import__(pkg_name) except ImportError: raise exc_failed_import(msg) if not version: return try: have_version = mod.__version__ except AttributeError: raise exc_failed_check('Cannot find version for %s' % pkg_name) if checker(have_version) < checker(version): raise exc_failed_check(msg) def str2bool(v): if isinstance(v, bool): return v lower = v.lower() if lower in ("yes", "true", "t", "1"): return True elif lower in ("no", "false", "n", "f", "0"): return False else: raise ValueError("%s cannot be converted to bool"%v) def flatten(S): if S == []: return S if isinstance(S[0], list): return flatten(S[0]) + flatten(S[1:]) return S[:1] + flatten(S[1:]) def unflatten(in_list, prev_structure): if not isinstance(in_list, Iterator): in_list = iter(in_list) if not isinstance(prev_structure, list): return in_list.next() else: out = [] for item in prev_structure: out.append(unflatten(in_list, item)) return out nipype-0.11.0/nipype/utils/nipype2boutiques.py000066400000000000000000000265621257611314500214620ustar00rootroot00000000000000# This tool exports a Nipype interface in the Boutiques (https://github.com/boutiques) JSON format. # Boutiques tools can be imported in CBRAIN (https://github.com/aces/cbrain) among other platforms. # # Limitations: # * List outputs are not supported. # * Default values are not extracted from the documentation of the Nipype interface. # * The following input types must be ignored for the output path template creation (see option -t): # ** String restrictions, i.e. String inputs that accept only a restricted set of values. # ** mutually exclusive inputs. # * Path-templates are wrong when output files are not created in the execution directory (e.g. when a sub-directory is created). # * Optional outputs, i.e. outputs that not always produced, may not be detected. import os import argparse import inspect import sys import json import tempfile from nipype.interfaces.base import Interface def main(argv): # Parses arguments parser = argparse.ArgumentParser(description='Nipype Boutiques exporter. See Boutiques specification at https://github.com/boutiques/schema.', prog=argv[0]) parser.add_argument("-i" , "--interface" , type=str, help="Name of the Nipype interface to export." , required=True) parser.add_argument("-m" , "--module" , type=str, help="Module where the interface is defined." , required=True) parser.add_argument("-o" , "--output" , type=str, help="JSON file name where the Boutiques descriptor will be written.", required=True) parser.add_argument("-t" , "--ignored-template-inputs" , type=str, help="Interface inputs ignored in path template creations.", nargs='+') parser.add_argument("-d" , "--docker-image" , type=str, help="Name of the Docker image where the Nipype interface is available.") parser.add_argument("-r" , "--docker-index" , type=str, help="Docker index where the Docker image is stored (e.g. http://index.docker.io).") parser.add_argument("-n" , "--ignore-template-numbers" , action='store_true', default=False, help="Ignore all numbers in path template creations.") parser.add_argument("-v" , "--verbose" , action='store_true', default=False, help="Enable verbose output.") parsed = parser.parse_args() # Generates JSON string json_string = generate_boutiques_descriptor(parsed.module, parsed.interface, parsed.ignored_template_inputs, parsed.docker_image,parsed.docker_index, parsed.verbose, parsed.ignore_template_numbers) # Writes JSON string to file f = open(parsed.output,'w') f.write(json_string) f.close() def generate_boutiques_descriptor(module, interface_name, ignored_template_inputs,docker_image,docker_index,verbose,ignore_template_numbers): ''' Returns a JSON string containing a JSON Boutiques description of a Nipype interface. Arguments: * module: module where the Nipype interface is declared. * interface: Nipype interface. * ignored_template_inputs: a list of input names that should be ignored in the generation of output path templates. * ignore_template_numbers: True if numbers must be ignored in output path creations. ''' if not module: raise Exception("Undefined module.") # Retrieves Nipype interface __import__(module) interface = getattr(sys.modules[module],interface_name)() inputs = interface.input_spec() outputs = interface.output_spec() # Tool description tool_desc = {} tool_desc['name'] = interface_name tool_desc['command-line'] = "nipype_cmd "+str(module)+" "+interface_name+" " tool_desc['description'] = interface_name+", as implemented in Nipype (module: "+str(module)+", interface: "+interface_name+")." tool_desc['inputs'] = [] tool_desc['outputs'] = [] tool_desc['tool-version'] = interface.version tool_desc['schema-version'] = '0.2-snapshot' if docker_image: tool_desc['docker-image'] = docker_image if docker_index: tool_desc['docker-index'] = docker_index # Generates tool inputs for name, spec in sorted(interface.inputs.traits(transient=None).items()): input = get_boutiques_input(inputs, interface, name, spec,ignored_template_inputs,verbose,ignore_template_numbers) tool_desc['inputs'].append(input) tool_desc['command-line']+= input['command-line-key']+" " if verbose: print "-> Adding input "+input['name'] # Generates tool outputs for name,spec in sorted(outputs.traits(transient=None).items()): output = get_boutiques_output(name,interface,tool_desc['inputs'],verbose) if output['path-template'] != "": tool_desc['outputs'].append(output) if verbose: print "-> Adding output "+output['name'] elif verbose: print "xx Skipping output "+output['name']+" with no path template." if tool_desc['outputs'] == []: raise Exception("Tool has no output.") # Removes all temporary values from inputs (otherwise they will # appear in the JSON output) for input in tool_desc['inputs']: del input['tempvalue'] return json.dumps(tool_desc, indent=4, separators=(',', ': ')) def get_boutiques_input(inputs,interface,input_name,spec,ignored_template_inputs,verbose,ignore_template_numbers): """ Returns a dictionary containing the Boutiques input corresponding to a Nipype intput. Args: * inputs: inputs of the Nipype interface. * interface: Nipype interface. * input_name: name of the Nipype input. * spec: Nipype input spec. * ignored_template_inputs: input names for which no temporary value must be generated. * ignore_template_numbers: True if numbers must be ignored in output path creations. Assumes that: * Input names are unique. """ if not spec.desc: spec.desc = "No description provided." spec_info = spec.full_info(inputs, input_name, None) input = {} input['id'] = input_name input['name'] = input_name.replace('_',' ').capitalize() input['type'] = get_type_from_spec_info(spec_info) input['list'] = is_list(spec_info) input['command-line-key'] = "["+input_name.upper()+"]" # assumes that input names are unique input['command-line-flag'] = ("--%s"%input_name+" ").strip() input['tempvalue'] = None input['description'] = spec_info.capitalize()+". "+spec.desc.capitalize() if not input['description'].endswith('.'): input['description'] += '.' if not ( hasattr(spec, "mandatory") and spec.mandatory ): input['optional'] = True else: input['optional'] = False if spec.usedefault: input['default-value'] = spec.default_value()[1] # Create unique, temporary value. temp_value = must_generate_value(input_name,input['type'],ignored_template_inputs,spec_info,spec,ignore_template_numbers) if temp_value: tempvalue = get_unique_value(input['type'],input_name) setattr(interface.inputs,input_name,tempvalue) input['tempvalue'] = tempvalue if verbose: print "oo Path-template creation using "+input['id']+"="+str(tempvalue) # Now that temp values have been generated, set Boolean types to # Number (there is no Boolean type in Boutiques) if input['type'] == "Boolean": input['type'] = "Number" return input def get_boutiques_output(name,interface,tool_inputs,verbose=False): """ Returns a dictionary containing the Boutiques output corresponding to a Nipype output. Args: * name: name of the Nipype output. * interface: Nipype interface. * tool_inputs: list of tool inputs (as produced by method get_boutiques_input). Assumes that: * Output names are unique. * Input values involved in the path template are defined. * Output files are written in the current directory. * There is a single output value (output lists are not supported). """ output = {} output['name'] = name.replace('_',' ').capitalize() output['id'] = name output['type'] = "File" output['path-template'] = "" output['optional'] = True # no real way to determine if an output is always produced, regardless of the input values. # Path template creation. output_value = interface._list_outputs()[name] if output_value != "" and isinstance(output_value,str): # FIXME: this crashes when there are multiple output values. # Go find from which input value it was built for input in tool_inputs: if not input['tempvalue']: continue input_value = input['tempvalue'] if input['type'] == "File": # Take the base name input_value = os.path.splitext(os.path.basename(input_value))[0] if str(input_value) in output_value: output_value = os.path.basename(output_value.replace(input_value,input['command-line-key'])) # FIXME: this only works if output is written in the current directory output['path-template'] = os.path.basename(output_value) return output def get_type_from_spec_info(spec_info): ''' Returns an input type from the spec info. There must be a better way to get an input type in Nipype than to parse the spec info. ''' if ("an existing file name" in spec_info) or ("input volumes" in spec_info): return "File" elif ("an integer" in spec_info or "a float" in spec_info) : return "Number" elif "a boolean" in spec_info: return "Boolean" return "String" def is_list(spec_info): ''' Returns True if the spec info looks like it describes a list parameter. There must be a better way in Nipype to check if an input is a list. ''' if "a list" in spec_info: return True return False def get_unique_value(type,id): ''' Returns a unique value of type 'type', for input with id 'id', assuming id is unique. ''' return { "File": os.path.abspath(create_tempfile()), "Boolean": True, "Number": abs(hash(id)), # abs in case input param must be positive... "String": id }[type] def create_tempfile(): ''' Creates a temp file and returns its name. ''' fileTemp = tempfile.NamedTemporaryFile(delete = False) fileTemp.write("hello") fileTemp.close() return fileTemp.name def must_generate_value(name,type,ignored_template_inputs,spec_info,spec,ignore_template_numbers): ''' Return True if a temporary value must be generated for this input. Arguments: * name: input name. * type: input_type. * ignored_template_inputs: a list of inputs names for which no value must be generated. * spec_info: spec info of the Nipype input . * ignore_template_numbers: True if numbers must be ignored. ''' # Return false when type is number and numbers must be ignored. if ignore_template_numbers and type == "Number": return False # Only generate value for the first element of mutually exclusive inputs. if spec.xor and spec.xor[0]!=name: return False # Directory types are not supported if "an existing directory name" in spec_info: return False # Don't know how to generate a list. if "a list" in spec_info or "a tuple" in spec_info: return False # Don't know how to generate a dictionary. if "a dictionary" in spec_info: return False # Best guess to detect string restrictions... if "' or '" in spec_info: return False if not ignored_template_inputs: return True return not (name in ignored_template_inputs) nipype-0.11.0/nipype/utils/nipype_cmd.py000066400000000000000000000062251257611314500202540ustar00rootroot00000000000000import os import argparse import inspect import sys from nipype.interfaces.base import Interface, InputMultiPath, traits from nipype.utils.misc import str2bool def listClasses(module=None): if module: __import__(module) pkg = sys.modules[module] print "Available Interfaces:" for k,v in pkg.__dict__.items(): if inspect.isclass(v) and issubclass(v, Interface): print "\t%s"%k def add_options(parser=None, module=None, function=None): interface = None if parser and module and function: __import__(module) interface = getattr(sys.modules[module],function)() inputs = interface.input_spec() for name, spec in sorted(interface.inputs.traits(transient=None).items()): desc = "\n".join(interface._get_trait_desc(inputs, name, spec))[len(name)+2:] args = {} if spec.is_trait_type(traits.Bool): args["action"] = 'store_true' if hasattr(spec, "mandatory") and spec.mandatory: if spec.is_trait_type(InputMultiPath): args["nargs"]="+" parser.add_argument(name, help=desc, **args) else: if spec.is_trait_type(InputMultiPath): args["nargs"]="*" parser.add_argument("--%s"%name, dest=name, help=desc, **args) return parser, interface def run_instance(interface, options): if interface: print "setting function inputs" for input_name, _ in interface.inputs.items(): if getattr(options, input_name) != None: value = getattr(options, input_name) if not isinstance(value, bool): #traits cannot cast from string to float or int try: value = float(value) except: pass #try to cast string input to boolean try: value = str2bool(value) except: pass try: setattr(interface.inputs, input_name, value) except ValueError, e: print "Error when setting the value of %s: '%s'"%(input_name, str(e)) print interface.inputs res = interface.run() print res.outputs def main(argv): if len(argv) == 2 and not argv[1].startswith("-"): listClasses(argv[1]) sys.exit(0) parser = argparse.ArgumentParser(description='Nipype interface runner', prog=argv[0]) parser.add_argument("module", type=str, help="Module name") parser.add_argument("interface", type=str, help="Interface name") parsed = parser.parse_args(args=argv[1:3]) _, prog = os.path.split(argv[0]) interface_parser = argparse.ArgumentParser(description="Run %s"%parsed.interface, prog=" ".join([prog] + argv[1:3])) interface_parser, interface = add_options(interface_parser, parsed.module, parsed.interface) args = interface_parser.parse_args(args=argv[3:]) run_instance(interface, args) nipype-0.11.0/nipype/utils/onetime.py000066400000000000000000000047641257611314500175730ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Descriptor support for NIPY. Utilities to support special Python descriptors [1,2], in particular the use of a useful pattern for properties we call 'one time properties'. These are object attributes which are declared as properties, but become regular attributes once they've been read the first time. They can thus be evaluated later in the object's life cycle, but once evaluated they become normal, static attributes with no function call overhead on access or any other constraints. References ---------- [1] How-To Guide for Descriptors, Raymond Hettinger. http://users.rcn.com/python/download/Descriptor.htm [2] Python data model, http://docs.python.org/reference/datamodel.html """ class OneTimeProperty(object): """A descriptor to make special properties that become normal attributes. """ def __init__(self, func): """Create a OneTimeProperty instance. Parameters ---------- func : method The method that will be called the first time to compute a value. Afterwards, the method's name will be a standard attribute holding the value of this computation. """ self.getter = func self.name = func.func_name def __get__(self, obj, type=None): """ Called on attribute access on the class or instance. """ if obj is None: # Being called on the class, return the original function. This way, # introspection works on the class. return self.getter val = self.getter(obj) #print "** setattr_on_read - loading '%s'" % self.name # dbg setattr(obj, self.name, val) return val def setattr_on_read(func): # XXX - beetter names for this? # - cor_property (copy on read property) # - sor_property (set on read property) # - prop2attr_on_read #... ? """Decorator to create OneTimeProperty attributes. Parameters ---------- func : method The method that will be called the first time to compute a value. Afterwards, the method's name will be a standard attribute holding the value of this computation. Examples -------- >>> class MagicProp(object): ... @setattr_on_read ... def a(self): ... return 99 ... >>> x = MagicProp() >>> 'a' in x.__dict__ False >>> x.a 99 >>> 'a' in x.__dict__ True """ return OneTimeProperty(func) nipype-0.11.0/nipype/utils/provenance.py000066400000000000000000000372541257611314500202730ustar00rootroot00000000000000from cPickle import dumps import json import os import getpass from socket import getfqdn from uuid import uuid1 from nipype.external import six import numpy as np try: from collections import OrderedDict except ImportError: from ordereddict import OrderedDict try: import prov.model as pm except ImportError: from ..external import provcopy as pm from .. import get_info from .filemanip import (md5, hashlib, hash_infile) from .. import logging iflogger = logging.getLogger('interface') foaf = pm.Namespace("foaf", "http://xmlns.com/foaf/0.1/") dcterms = pm.Namespace("dcterms", "http://purl.org/dc/terms/") nipype_ns = pm.Namespace("nipype", "http://nipy.org/nipype/terms/") niiri = pm.Namespace("niiri", "http://iri.nidash.org/") crypto = pm.Namespace("crypto", ("http://id.loc.gov/vocabulary/preservation/" "cryptographicHashFunctions/")) get_id = lambda: niiri[uuid1().hex] def get_attr_id(attr, skip=None): dictwithhash, hashval = get_hashval(attr, skip=skip) return niiri[hashval] max_text_len = 1024000 def get_hashval(inputdict, skip=None): """Return a dictionary of our items with hashes for each file. Searches through dictionary items and if an item is a file, it calculates the md5 hash of the file contents and stores the file name and hash value as the new key value. However, the overall bunch hash is calculated only on the hash value of a file. The path and name of the file are not used in the overall hash calculation. Returns ------- dict_withhash : dict Copy of our dictionary with the new file hashes included with each file. hashvalue : str The md5 hash value of the traited spec """ dict_withhash = {} dict_nofilename = OrderedDict() keys = {} for key in inputdict: if skip is not None and key in skip: continue keys[key.get_uri()] = key for key in sorted(keys): val = inputdict[keys[key]] outname = key try: if isinstance(val, pm.URIRef): val = val.decode() except AttributeError: pass if isinstance(val, pm.QName): val = val.get_uri() if isinstance(val, pm.Literal): val = val.get_value() dict_nofilename[outname] = _get_sorteddict(val) dict_withhash[outname] = _get_sorteddict(val, True) return (dict_withhash, md5(str(dict_nofilename)).hexdigest()) def _get_sorteddict(object, dictwithhash=False): if isinstance(object, dict): out = OrderedDict() for key, val in sorted(object.items()): if val: out[key] = _get_sorteddict(val, dictwithhash) elif isinstance(object, (list, tuple)): out = [] for val in object: if val: out.append(_get_sorteddict(val, dictwithhash)) if isinstance(object, tuple): out = tuple(out) else: if isinstance(object, six.string_types) and os.path.isfile(object): hash = hash_infile(object) if dictwithhash: out = (object, hash) else: out = hash elif isinstance(object, float): out = '%.10f' % object else: out = object return out def safe_encode(x, as_literal=True): """Encodes a python value for prov """ if x is None: value = "Unknown" if as_literal: return pm.Literal(value, pm.XSD['string']) else: return value try: if isinstance(x, (str, unicode)): if os.path.exists(x): value = 'file://%s%s' % (getfqdn(), x) if not as_literal: return value try: return pm.URIRef(value) except AttributeError: return pm.Literal(value, pm.XSD['anyURI']) else: if len(x) > max_text_len: value = x[:max_text_len - 13] + ['...Clipped...'] else: value = x if not as_literal: return value return pm.Literal(value, pm.XSD['string']) if isinstance(x, (int,)): if not as_literal: return x return pm.Literal(int(x), pm.XSD['integer']) if isinstance(x, (float,)): if not as_literal: return x return pm.Literal(x, pm.XSD['float']) if isinstance(x, dict): outdict = {} for key, value in x.items(): encoded_value = safe_encode(value, as_literal=False) if isinstance(encoded_value, (pm.Literal,)): outdict[key] = encoded_value.json_representation() else: outdict[key] = encoded_value if not as_literal: return json.dumps(outdict) return pm.Literal(json.dumps(outdict), pm.XSD['string']) if isinstance(x, list): try: nptype = np.array(x).dtype if nptype == np.dtype(object): raise ValueError('dtype object') except ValueError, e: outlist = [] for value in x: encoded_value = safe_encode(value, as_literal=False) if isinstance(encoded_value, (pm.Literal,)): outlist.append(encoded_value.json_representation()) else: outlist.append(encoded_value) else: outlist = x if not as_literal: return json.dumps(outlist) return pm.Literal(json.dumps(outlist), pm.XSD['string']) if not as_literal: return dumps(x) return pm.Literal(dumps(x), nipype_ns['pickle']) except TypeError, e: iflogger.info(e) value = "Could not encode: " + str(e) if not as_literal: return value return pm.Literal(value, pm.XSD['string']) def prov_encode(graph, value, create_container=True): if isinstance(value, list) and create_container: if len(value) == 0: encoded_literal = safe_encode(value) attr = {pm.PROV['value']: encoded_literal} id = get_attr_id(attr) entity = graph.entity(id, attr) elif len(value) > 1: try: entities = [] for item in value: item_entity = prov_encode(graph, item) entities.append(item_entity) if isinstance(item, list): continue if not isinstance(item_entity.get_value()[0], basestring): raise ValueError('Not a string literal') if 'file://' not in item_entity.get_value()[0]: raise ValueError('No file found') id = get_id() entity = graph.collection(identifier=id) for item_entity in entities: graph.hadMember(id, item_entity) except ValueError, e: iflogger.debug(e) entity = prov_encode(graph, value, create_container=False) else: entity = prov_encode(graph, value[0]) else: encoded_literal = safe_encode(value) attr = {pm.PROV['value']: encoded_literal} if isinstance(value, six.string_types) and os.path.exists(value): attr.update({pm.PROV['location']: encoded_literal}) if not os.path.isdir(value): sha512 = hash_infile(value, crypto=hashlib.sha512) attr.update({crypto['sha512']: pm.Literal(sha512, pm.XSD['string'])}) id = get_attr_id(attr, skip=[pm.PROV['location'], pm.PROV['value']]) else: id = get_attr_id(attr, skip=[pm.PROV['location']]) else: id = get_attr_id(attr) entity = graph.entity(id, attr) return entity def write_provenance(results, filename='provenance', format='turtle'): ps = ProvStore() ps.add_results(results) return ps.write_provenance(filename=filename, format=format) class ProvStore(object): def __init__(self): self.g = pm.ProvBundle(identifier=get_id()) self.g.add_namespace(foaf) self.g.add_namespace(dcterms) self.g.add_namespace(nipype_ns) self.g.add_namespace(niiri) def add_results(self, results): if results.provenance: try: self.g.add_bundle(results.provenance) except pm.ProvException: self.g.add_bundle(results.provenance, get_id()) return self.g runtime = results.runtime interface = results.interface inputs = results.inputs outputs = results.outputs classname = interface.__name__ modulepath = "{0}.{1}".format(interface.__module__, interface.__name__) activitytype = ''.join([i.capitalize() for i in modulepath.split('.')]) a0_attrs = {nipype_ns['module']: interface.__module__, nipype_ns["interface"]: classname, pm.PROV["type"]: nipype_ns[activitytype], pm.PROV["label"]: classname, nipype_ns['duration']: safe_encode(runtime.duration), nipype_ns['workingDirectory']: safe_encode(runtime.cwd), nipype_ns['returnCode']: safe_encode(runtime.returncode), nipype_ns['platform']: safe_encode(runtime.platform), nipype_ns['version']: safe_encode(runtime.version), } try: a0_attrs[foaf["host"]] = pm.URIRef(runtime.hostname) except AttributeError: a0_attrs[foaf["host"]] = pm.Literal(runtime.hostname, pm.XSD['anyURI']) try: a0_attrs.update({nipype_ns['command']: safe_encode(runtime.cmdline)}) a0_attrs.update({nipype_ns['commandPath']: safe_encode(runtime.command_path)}) a0_attrs.update({nipype_ns['dependencies']: safe_encode(runtime.dependencies)}) except AttributeError: pass a0 = self.g.activity(get_id(), runtime.startTime, runtime.endTime, a0_attrs) # environment id = get_id() env_collection = self.g.collection(id) env_collection.add_extra_attributes({pm.PROV['type']: nipype_ns['Environment'], pm.PROV['label']: "Environment"}) self.g.used(a0, id) # write environment entities for idx, (key, val) in enumerate(sorted(runtime.environ.items())): if key not in ['PATH', 'FSLDIR', 'FREESURFER_HOME', 'ANTSPATH', 'CAMINOPATH', 'CLASSPATH', 'LD_LIBRARY_PATH', 'DYLD_LIBRARY_PATH', 'FIX_VERTEX_AREA', 'FSF_OUTPUT_FORMAT', 'FSLCONFDIR', 'FSLOUTPUTTYPE', 'LOGNAME', 'USER', 'MKL_NUM_THREADS', 'OMP_NUM_THREADS']: continue in_attr = {pm.PROV["label"]: key, nipype_ns["environmentVariable"]: key, pm.PROV["value"]: safe_encode(val)} id = get_attr_id(in_attr) self.g.entity(id, in_attr) self.g.hadMember(env_collection, id) # write input entities if inputs: id = get_id() input_collection = self.g.collection(id) input_collection.add_extra_attributes({pm.PROV['type']: nipype_ns['Inputs'], pm.PROV['label']: "Inputs"}) # write input entities for idx, (key, val) in enumerate(sorted(inputs.items())): in_entity = prov_encode(self.g, val).get_identifier() self.g.hadMember(input_collection, in_entity) used_attr = {pm.PROV["label"]: key, nipype_ns["inPort"]: key} self.g.used(activity=a0, entity=in_entity, other_attributes=used_attr) # write output entities if outputs: id = get_id() output_collection = self.g.collection(id) if not isinstance(outputs, dict): outputs = outputs.get_traitsfree() output_collection.add_extra_attributes({pm.PROV['type']: nipype_ns['Outputs'], pm.PROV['label']: "Outputs"}) self.g.wasGeneratedBy(output_collection, a0) # write output entities for idx, (key, val) in enumerate(sorted(outputs.items())): out_entity = prov_encode(self.g, val).get_identifier() self.g.hadMember(output_collection, out_entity) gen_attr = {pm.PROV["label"]: key, nipype_ns["outPort"]: key} self.g.generation(out_entity, activity=a0, other_attributes=gen_attr) # write runtime entities id = get_id() runtime_collection = self.g.collection(id) runtime_collection.add_extra_attributes({pm.PROV['type']: nipype_ns['Runtime'], pm.PROV['label']: "RuntimeInfo"}) self.g.wasGeneratedBy(runtime_collection, a0) for key, value in sorted(runtime.items()): if not value: continue if key not in ['stdout', 'stderr', 'merged']: continue attr = {pm.PROV["label"]: key, nipype_ns[key]: safe_encode(value)} id = get_id() self.g.entity(get_id(), attr) self.g.hadMember(runtime_collection, id) # create agents user_attr = {pm.PROV["type"]: pm.PROV["Person"], pm.PROV["label"]: getpass.getuser(), foaf["name"]: safe_encode(getpass.getuser())} user_agent = self.g.agent(get_attr_id(user_attr), user_attr) agent_attr = {pm.PROV["type"]: pm.PROV["SoftwareAgent"], pm.PROV["label"]: "Nipype", foaf["name"]: safe_encode("Nipype")} for key, value in get_info().items(): agent_attr.update({nipype_ns[key]: safe_encode(value)}) software_agent = self.g.agent(get_attr_id(agent_attr), agent_attr) self.g.wasAssociatedWith(a0, user_agent, None, None, {pm.PROV["hadRole"]: nipype_ns["LoggedInUser"]}) self.g.wasAssociatedWith(a0, software_agent) return self.g def write_provenance(self, filename='provenance', format='turtle'): try: if format in ['turtle', 'all']: self.g.rdf().serialize(filename + '.ttl', format='turtle') except (ImportError, NameError): format = 'all' finally: if format in ['provn', 'all']: with open(filename + '.provn', 'wt') as fp: fp.writelines(self.g.get_provn()) if format in ['json', 'all']: with open(filename + '.json', 'wt') as fp: pm.json.dump(self.g, fp, cls=pm.ProvBundle.JSONEncoder) return self.g nipype-0.11.0/nipype/utils/spm_docs.py000066400000000000000000000033121257611314500177260ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Grab documentation from spm.""" import os from nipype.interfaces import matlab def grab_doc(task_name): """Grab the SPM documentation for the given SPM task named `task_name` Parameters ---------- task_name : string Task name for which we are grabbing documentation. Example task names are ``Realign: Estimate & Reslice``, ``Normalise: Estimate & Write``. See Also -------- spm_flat_config.m : This function can print out all the possible task names. """ cmd = matlab.MatlabCommandLine() # We need to tell Matlab where to find our spm_get_doc.m file. cwd = os.path.dirname(__file__) # Build matlab command mcmd = "addpath('%s');spm_get_doc('%s')" % (cwd, task_name) cmd.inputs.script_lines = mcmd # Run the command and get the documentation out of the result. out = cmd.run() return _strip_header(out.runtime.stdout) def _strip_header(doc): """Strip Matlab header and splash info off doc. Searches for the tag 'NIPYPE' in the doc and returns everyting after that. """ hdr = 'NIPYPE' cruft = '\x1b' # There's some weird cruft at the end of the # docstring, almost looks like the hex for the # escape character 0x1b. try: index = doc.index(hdr) index += len(hdr) index += 1 doc = doc[index:] try: index = doc.index(cruft) except ValueError: index = len(doc) return doc[:index] except KeyError: raise IOError('This docstring was not generated by Nipype!\n') nipype-0.11.0/nipype/utils/spm_flat_config.m000066400000000000000000000021011257611314500210500ustar00rootroot00000000000000function cfgstruct = spm_flat_config(print_names) % Get a flat spm_config structure, with option to print out names % % This calls spm_config() to get the the nested configuration % structure from spm. We use this to fetch documentation, the % flattened structure is much easier to search through. If % print_names is true (value of 1) it will print out the configuration % names. If print_names is false (value of 0), it will only return % the flattened structure. if strcmp(spm('ver'),'SPM5') cfg = spm_config(); else cfgstruct = []; return; end cfgstruct = spm_cfg_list(cfg, {}); if print_names [rows, cols] = size(cfgstruct); for i = 1:cols fprintf(1, '%d : %s\n', i, cfgstruct{i}.name) end end end function objlist = spm_cfg_list(astruct, objlist) % Flatten the nested structure in 'astruct'. % Returns a cell array. % Usage: objlist = spm_cfg_list(astruct, {}) if isfield(astruct, 'values') [rows, cols] = size(astruct.values); for i = 1:cols objlist = spm_cfg_list(astruct.values{i}, objlist); end else objlist = {objlist{:} astruct}; end endnipype-0.11.0/nipype/utils/spm_get_doc.m000066400000000000000000000011641257611314500202110ustar00rootroot00000000000000function doc = spm_get_doc(docname) % Get the documentation from SPM for the functionality named % docname. % % This will search through the spm_config() object and grab the % documentation whose name matches docname. cfgstruct = spm_flat_config(0); [rows, cols] = size(cfgstruct); docstruct.help={'None'}; % Loop over cell array and search for the docname for i = 1:cols if strcmp(cfgstruct{i}.name, docname) docstruct = cfgstruct{i}; break end end % Add a tag so we can strip off the Matlab header information and % only print out the SPM documentation. tag = 'NIPYPE\n'; doc = strcat(tag, docstruct.help{:}); end nipype-0.11.0/nipype/utils/tests/000077500000000000000000000000001257611314500167105ustar00rootroot00000000000000nipype-0.11.0/nipype/utils/tests/__init__.py000066400000000000000000000022521257611314500210220ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """ Please write tests for all code submitted to the repository. The code will be used by many people, and will in due course be used in live analyses, so we need to make sure that we have the best possible defenses against bugs. It also helps us think about code interfaces, and gives examples of code use that can be useful for others using the code. Python's unit testing framework (the U{unittest} module) is used to implement project tests. We use the convention that each package contains a subpackage called tests which contains modules defining test cases (subclasses of U{unittest.TestCase}) for that package. The nipy.utils.tests package contains an example test case called L{test_template.TemplateTest} to get you started writing your tests. Please try to include working test cases for all functions and classes that you contribute. Often, writing tests for your code before the code is written helps to frame your thoughts about what the code should look like. """ nipype-0.11.0/nipype/utils/tests/test_cmd.py000066400000000000000000000102201257611314500210570ustar00rootroot00000000000000#!/usr/bin/env python from StringIO import StringIO import unittest, sys from nipype.utils import nipype_cmd from contextlib import contextmanager @contextmanager def capture_sys_output(): caputure_out, capture_err = StringIO(), StringIO() current_out, current_err = sys.stdout, sys.stderr try: sys.stdout, sys.stderr = caputure_out, capture_err yield caputure_out, capture_err finally: sys.stdout, sys.stderr = current_out, current_err class TestNipypeCMD(unittest.TestCase): def test_main_returns_2_on_empty(self): with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd']) exit_exception = cm.exception self.assertEqual(exit_exception.code, 2) self.assertEqual(stderr.getvalue(), """usage: nipype_cmd [-h] module interface nipype_cmd: error: too few arguments """) self.assertEqual(stdout.getvalue(), '') def test_main_returns_0_on_help(self): with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd', '-h']) exit_exception = cm.exception self.assertEqual(exit_exception.code, 0) self.assertEqual(stderr.getvalue(), '') self.assertEqual(stdout.getvalue(), """usage: nipype_cmd [-h] module interface Nipype interface runner positional arguments: module Module name interface Interface name optional arguments: -h, --help show this help message and exit """) def test_list_nipy_interfacesp(self): with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy']) # repeat twice in case nipy raises warnings with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy']) exit_exception = cm.exception self.assertEqual(exit_exception.code, 0) self.assertEqual(stderr.getvalue(), '') self.assertEqual(stdout.getvalue(), """Available Interfaces: SpaceTimeRealigner Similarity ComputeMask FitGLM EstimateContrast FmriRealign4d """) def test_run_4d_realign_without_arguments(self): with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy', 'FmriRealign4d']) exit_exception = cm.exception self.assertEqual(exit_exception.code, 2) self.assertEqual(stderr.getvalue(), """usage: nipype_cmd nipype.interfaces.nipy FmriRealign4d [-h] [--between_loops [BETWEEN_LOOPS [BETWEEN_LOOPS ...]]] [--ignore_exception] [--loops [LOOPS [LOOPS ...]]] [--slice_order SLICE_ORDER] [--speedup [SPEEDUP [SPEEDUP ...]]] [--start START] [--time_interp TIME_INTERP] [--tr_slices TR_SLICES] in_file [in_file ...] tr nipype_cmd nipype.interfaces.nipy FmriRealign4d: error: too few arguments """) self.assertEqual(stdout.getvalue(), '') def test_run_4d_realign_help(self): with self.assertRaises(SystemExit) as cm: with capture_sys_output() as (stdout, stderr): nipype_cmd.main(['nipype_cmd', 'nipype.interfaces.nipy', 'FmriRealign4d', '-h']) exit_exception = cm.exception self.assertEqual(exit_exception.code, 0) self.assertEqual(stderr.getvalue(), '') self.assertTrue("Run FmriRealign4d" in stdout.getvalue()) if __name__ == '__main__': unittest.main() nipype-0.11.0/nipype/utils/tests/test_docparse.py000066400000000000000000000026611257611314500221260ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from nipype.testing import * from nipype.utils.docparse import reverse_opt_map, build_doc, insert_doc class Foo(object): opt_map = {'outline': '-o', 'fun': '-f %.2f', 'flags': '%s'} foo_doc = """Usage: foo infile outfile [opts] Bunch of options: -o something about an outline -f intensity of fun factor Other stuff: -v verbose """ fmtd_doc = """Parameters ---------- outline : something about an outline fun : intensity of fun factor Others Parameters ----------------- -v verbose""" def test_rev_opt_map(): map = {'-f': 'fun', '-o': 'outline'} rev_map = reverse_opt_map(Foo.opt_map) assert_equal(rev_map, map) def test_build_doc(): opts = reverse_opt_map(Foo.opt_map) doc = build_doc(foo_doc, opts) assert_equal(doc, fmtd_doc) inserted_doc = """Parameters ---------- infile : str The name of the input file outfile : str The name of the output file outline : something about an outline fun : intensity of fun factor Others Parameters ----------------- -v verbose""" def test_insert_doc(): new_items = ['infile : str', ' The name of the input file'] new_items.extend(['outfile : str', ' The name of the output file']) newdoc = insert_doc(fmtd_doc, new_items) assert_equal(newdoc, inserted_doc) nipype-0.11.0/nipype/utils/tests/test_filemanip.py000066400000000000000000000146351257611314500222760ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from tempfile import mkstemp, mkdtemp from nipype.testing import assert_equal, assert_true, assert_false from nipype.utils.filemanip import (save_json, load_json, fname_presuffix, fnames_presuffix, hash_rename, check_forhash, copyfile, copyfiles, filename_to_list, list_to_filename, split_filename, get_related_files) import numpy as np def test_split_filename(): res = split_filename('foo.nii') yield assert_equal, res, ('', 'foo', '.nii') res = split_filename('foo.nii.gz') yield assert_equal, res, ('', 'foo', '.nii.gz') res = split_filename('/usr/local/foo.nii.gz') yield assert_equal, res, ('/usr/local', 'foo', '.nii.gz') res = split_filename('../usr/local/foo.nii') yield assert_equal, res, ('../usr/local', 'foo', '.nii') res = split_filename('/usr/local/foo.a.b.c.d') yield assert_equal, res, ('/usr/local', 'foo.a.b.c', '.d') res = split_filename('/usr/local/') yield assert_equal, res, ('/usr/local', '', '') def test_fname_presuffix(): fname = 'foo.nii' pth = fname_presuffix(fname, 'pre_', '_post', '/tmp') yield assert_equal, pth, '/tmp/pre_foo_post.nii' fname += '.gz' pth = fname_presuffix(fname, 'pre_', '_post', '/tmp') yield assert_equal, pth, '/tmp/pre_foo_post.nii.gz' pth = fname_presuffix(fname, 'pre_', '_post', '/tmp', use_ext=False) yield assert_equal, pth, '/tmp/pre_foo_post' def test_fnames_presuffix(): fnames = ['foo.nii', 'bar.nii'] pths = fnames_presuffix(fnames, 'pre_', '_post', '/tmp') yield assert_equal, pths, ['/tmp/pre_foo_post.nii', '/tmp/pre_bar_post.nii'] def test_hash_rename(): new_name = hash_rename('foobar.nii', 'abc123') yield assert_equal, new_name, 'foobar_0xabc123.nii' new_name = hash_rename('foobar.nii.gz', 'abc123') yield assert_equal, new_name, 'foobar_0xabc123.nii.gz' def test_check_forhash(): fname = 'foobar' orig_hash = '_0x4323dbcefdc51906decd8edcb3327943' hashed_name = ''.join((fname, orig_hash, '.nii')) result, hash = check_forhash(hashed_name) yield assert_true, result yield assert_equal, hash, [orig_hash] result, hash = check_forhash('foobar.nii') yield assert_false, result yield assert_equal, hash, None def _temp_analyze_files(): """Generate temporary analyze file pair.""" fd, orig_img = mkstemp(suffix = '.img') orig_hdr = orig_img[:-4] + '.hdr' fp = file(orig_hdr, 'w+') fp.close() return orig_img, orig_hdr def test_copyfile(): orig_img, orig_hdr = _temp_analyze_files() pth, fname = os.path.split(orig_img) new_img = os.path.join(pth, 'newfile.img') new_hdr = os.path.join(pth, 'newfile.hdr') copyfile(orig_img, new_img) yield assert_true, os.path.exists(new_img) yield assert_true, os.path.exists(new_hdr) os.unlink(new_img) os.unlink(new_hdr) # final cleanup os.unlink(orig_img) os.unlink(orig_hdr) def test_copyfile_true(): orig_img, orig_hdr = _temp_analyze_files() pth, fname = os.path.split(orig_img) new_img = os.path.join(pth, 'newfile.img') new_hdr = os.path.join(pth, 'newfile.hdr') # Test with copy=True copyfile(orig_img, new_img, copy=True) yield assert_true, os.path.exists(new_img) yield assert_true, os.path.exists(new_hdr) os.unlink(new_img) os.unlink(new_hdr) # final cleanup os.unlink(orig_img) os.unlink(orig_hdr) def test_copyfiles(): orig_img1, orig_hdr1 = _temp_analyze_files() orig_img2, orig_hdr2 = _temp_analyze_files() pth, fname = os.path.split(orig_img1) new_img1 = os.path.join(pth, 'newfile.img') new_hdr1 = os.path.join(pth, 'newfile.hdr') pth, fname = os.path.split(orig_img2) new_img2 = os.path.join(pth, 'secondfile.img') new_hdr2 = os.path.join(pth, 'secondfile.hdr') newfiles = copyfiles([orig_img1, orig_img2], [new_img1, new_img2]) yield assert_true, os.path.exists(new_img1) yield assert_true, os.path.exists(new_hdr1) yield assert_true, os.path.exists(new_img2) yield assert_true, os.path.exists(new_hdr2) # cleanup os.unlink(orig_img1) os.unlink(orig_hdr1) os.unlink(orig_img2) os.unlink(orig_hdr2) os.unlink(new_img1) os.unlink(new_hdr1) os.unlink(new_img2) os.unlink(new_hdr2) def test_filename_to_list(): x = filename_to_list('foo.nii') yield assert_equal, x, ['foo.nii'] x = filename_to_list(['foo.nii']) yield assert_equal, x, ['foo.nii'] x = filename_to_list(('foo', 'bar')) yield assert_equal, x, ['foo', 'bar'] x = filename_to_list(12.34) yield assert_equal, x, None def test_list_to_filename(): x = list_to_filename(['foo.nii']) yield assert_equal, x, 'foo.nii' x = list_to_filename(['foo', 'bar']) yield assert_equal, x, ['foo', 'bar'] def test_json(): # Simple roundtrip test of json files, just a sanity check. adict = dict(a='one', c='three', b='two') fd, name = mkstemp(suffix='.json') save_json(name, adict) # save_json closes the file new_dict = load_json(name) os.unlink(name) yield assert_equal, sorted(adict.items()), sorted(new_dict.items()) def test_related_files(): file1 = '/path/test.img' file2 = '/path/test.hdr' file3 = '/path/test.BRIK' file4 = '/path/test.HEAD' file5 = '/path/foo.nii' spm_files1 = get_related_files(file1) spm_files2 = get_related_files(file2) afni_files1 = get_related_files(file3) afni_files2 = get_related_files(file4) yield assert_equal, len(spm_files1), 3 yield assert_equal, len(spm_files2), 3 yield assert_equal, len(afni_files1), 2 yield assert_equal, len(afni_files2), 2 yield assert_equal, len(get_related_files(file5)), 1 yield assert_true, '/path/test.hdr' in spm_files1 yield assert_true, '/path/test.img' in spm_files1 yield assert_true, '/path/test.mat' in spm_files1 yield assert_true, '/path/test.hdr' in spm_files2 yield assert_true, '/path/test.img' in spm_files2 yield assert_true, '/path/test.mat' in spm_files2 yield assert_true, '/path/test.BRIK' in afni_files1 yield assert_true, '/path/test.HEAD' in afni_files1 yield assert_true, '/path/test.BRIK' in afni_files2 yield assert_true, '/path/test.HEAD' in afni_files2 nipype-0.11.0/nipype/utils/tests/test_misc.py000066400000000000000000000041361257611314500212600ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from nipype.testing import assert_equal, assert_true, assert_false from nipype.utils.misc import (container_to_string, getsource, create_function_from_source, str2bool, flatten, unflatten) def test_cont_to_str(): # list x = ['a', 'b'] yield assert_equal, container_to_string(x), 'a b' # tuple x = tuple(x) yield assert_equal, container_to_string(x), 'a b' # set x = set(x) y = container_to_string(x) yield assert_true, (y == 'a b') or (y == 'b a') # dict x = dict(a='a', b='b') y = container_to_string(x) yield assert_true, (y == 'a b') or (y == 'b a') # string yield assert_equal, container_to_string('foobar'), 'foobar' # int. Integers are not the main intent of this function, but see # no reason why they shouldn't work. yield assert_equal, container_to_string(123), '123' def _func1(x): return x**3 def test_func_to_str(): def func1(x): return x**2 # Should be ok with both functions! for f in _func1, func1: f_src = getsource(f) f_recreated = create_function_from_source(f_src) yield assert_equal, f(2.3), f_recreated(2.3) def test_str2bool(): yield assert_true, str2bool("yes") yield assert_true, str2bool("true") yield assert_true, str2bool("t") yield assert_true, str2bool("1") yield assert_false, str2bool("no") yield assert_false, str2bool("false") yield assert_false, str2bool("n") yield assert_false, str2bool("f") yield assert_false, str2bool("0") def test_flatten(): in_list = [[1,2,3],[4],[[5,6],7],8] flat = flatten(in_list) yield assert_equal, flat, [1,2,3,4,5,6,7,8] back = unflatten(flat, in_list) yield assert_equal, in_list, back new_list = [2,3,4,5,6,7,8,9] back = unflatten(new_list, in_list) yield assert_equal, back, [[2,3,4],[5],[[6,7],8],9] flat = flatten([]) yield assert_equal, flat, [] back = unflatten([], []) yield assert_equal, back, [] nipype-0.11.0/nipype/utils/tmpdirs.py000066400000000000000000000023561257611314500176100ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import shutil from tempfile import template, mkdtemp class TemporaryDirectory(object): """Create and return a temporary directory. This has the same behavior as mkdtemp but can be used as a context manager. For example: with TemporaryDirectory() as tmpdir: ... Upon exiting the context, the directory and everthing contained in it are removed. """ def __init__(self, suffix="", prefix=template, dir=None): self.name = mkdtemp(suffix, prefix, dir) self._closed = False def __enter__(self): return self.name def cleanup(self): if not self._closed: shutil.rmtree(self.name) self._closed = True def __exit__(self, exc, value, tb): self.cleanup() return False class InTemporaryDirectory(TemporaryDirectory): def __enter__(self): self._pwd = os.getcwd() os.chdir(self.name) return super(InTemporaryDirectory, self).__enter__() def __exit__(self, exc, value, tb): os.chdir(self._pwd) return super(InTemporaryDirectory, self).__exit__(exc, value, tb) nipype-0.11.0/nipype/workflows/000077500000000000000000000000001257611314500164435ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/__init__.py000066400000000000000000000001621257611314500205530ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/workflows/data/000077500000000000000000000000001257611314500173545ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/data/__init__.py000066400000000000000000000007501257611314500214670ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os.path as op def get_flirt_schedule(name): if name == 'ecc': return op.abspath(op.join(op.dirname(__file__), 'ecc.sch')) elif name == 'hmc': return op.abspath(op.join(op.dirname(__file__), 'hmc.sch')) else: raise RuntimeError('Requested file does not exist.') nipype-0.11.0/nipype/workflows/data/ecc.sch000066400000000000000000000036641257611314500206160ustar00rootroot00000000000000# 4mm scale setscale 4 setoption smoothing 6 setoption paramsubset 1 0 0 0 0 0 0 1 1 1 1 1 1 clear U clear UA clear UB clear US clear UP # try the identity transform as a starting point at this resolution clear UQ setrow UQ 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 7 UQ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 rel 4 sort U copy U UA # select best 4 optimised solutions and try perturbations of these clear U copy UA:1-4 U optimise 7 UA:1-4 1.0 0.0 0.0 0.0 0.0 0.0 0.0 rel 4 optimise 7 UA:1-4 -1.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 1.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 -1.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 1.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 -1.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 0.1 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 -0.1 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 0.2 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 -0.2 abs 4 sort U copy U UB # 2mm scale setscale 2 setoption smoothing 4 setoption paramsubset 1 0 0 0 0 0 0 1 1 1 1 1 1 clear U clear UC clear UD clear UE clear UF # remeasure costs at this scale measurecost 7 UB 0 0 0 0 0 0 rel sort U copy U UC clear U optimise 7 UC:1-3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 2 copy U UD sort U copy U UF # also try the identity transform as a starting point at this resolution sort U clear U UG clear U setrow UG 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 7 UG 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 2 sort U copy U UG # 1mm scale setscale 1 setoption smoothing 2 setoption boundguess 1 setoption paramsubset 1 0 0 0 0 0 0 1 1 1 1 1 1 clear U #also try the identity transform as a starting point at this resolution setrow UK 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 12 UK:1-2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 1 sort U nipype-0.11.0/nipype/workflows/data/hmc.sch000066400000000000000000000034411257611314500206240ustar00rootroot00000000000000# 4mm scale setscale 4 setoption smoothing 6 clear U clear UA clear UB clear US clear UP # try the identity transform as a starting point at this resolution clear UQ setrow UQ 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 7 UQ 0.0 0.0 0.0 0.0 0.0 0.0 0.0 rel 4 sort U copy U UA # select best 4 optimised solutions and try perturbations of these clear U copy UA:1-4 U optimise 7 UA:1-4 1.0 0.0 0.0 0.0 0.0 0.0 0.0 rel 4 optimise 7 UA:1-4 -1.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 1.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 -1.0 0.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 1.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 -1.0 0.0 0.0 0.0 0.0 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 0.1 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 -0.1 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 0.2 abs 4 optimise 7 UA:1-4 0.0 0.0 0.0 0.0 0.0 0.0 -0.2 abs 4 sort U copy U UB # 2mm scale setscale 2 setoption smoothing 4 clear U clear UC clear UD clear UE clear UF # remeasure costs at this scale measurecost 7 UB 0 0 0 0 0 0 rel sort U copy U UC clear U optimise 7 UC:1-3 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 2 copy U UD sort U copy U UF # also try the identity transform as a starting point at this resolution sort U clear U UG clear U setrow UG 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 7 UG 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 2 sort U copy U UG # 1mm scale setscale 1 setoption smoothing 2 setoption boundguess 1 clear U #also try the identity transform as a starting point at this resolution setrow UK 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 optimise 12 UK:1-2 0.0 0.0 0.0 0.0 0.0 0.0 0.0 abs 1 sort U nipype-0.11.0/nipype/workflows/dmri/000077500000000000000000000000001257611314500173765ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/__init__.py000066400000000000000000000000411257611314500215020ustar00rootroot00000000000000import camino, mrtrix, fsl, dipy nipype-0.11.0/nipype/workflows/dmri/camino/000077500000000000000000000000001257611314500206445ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/camino/__init__.py000066400000000000000000000002621257611314500227550ustar00rootroot00000000000000from diffusion import create_camino_dti_pipeline from connectivity_mapping import create_connectivity_pipeline from group_connectivity import create_group_connectivity_pipeline nipype-0.11.0/nipype/workflows/dmri/camino/connectivity_mapping.py000066400000000000000000000607641257611314500254640ustar00rootroot00000000000000import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.camino as camino import nipype.interfaces.fsl as fsl import nipype.interfaces.camino2trackvis as cam2trk import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.cmtk as cmtk import nipype.algorithms.misc as misc import inspect import os.path as op from ...misc.utils import (get_affine, get_data_dims, get_vox_dims, select_aparc, select_aparc_annot) def create_connectivity_pipeline(name="connectivity"): """Creates a pipeline that does the same connectivity processing as in the :ref:`example_dmri_connectivity` example script. Given a subject id (and completed Freesurfer reconstruction) diffusion-weighted image, b-values, and b-vectors, the workflow will return the subject's connectome as a Connectome File Format (CFF) file for use in Connectome Viewer (http://www.cmtk.org). Example ------- >>> from nipype.workflows.dmri.camino.connectivity_mapping import create_connectivity_pipeline >>> conmapper = create_connectivity_pipeline("nipype_conmap") >>> conmapper.inputs.inputnode.subjects_dir = '.' >>> conmapper.inputs.inputnode.subject_id = 'subj1' >>> conmapper.inputs.inputnode.dwi = 'data.nii.gz' >>> conmapper.inputs.inputnode.bvecs = 'bvecs' >>> conmapper.inputs.inputnode.bvals = 'bvals' >>> conmapper.run() # doctest: +SKIP Inputs:: inputnode.subject_id inputnode.subjects_dir inputnode.dwi inputnode.bvecs inputnode.bvals inputnode.resolution_network_file Outputs:: outputnode.connectome outputnode.cmatrix outputnode.gpickled_network outputnode.fa outputnode.struct outputnode.trace outputnode.tracts outputnode.tensors """ inputnode_within = pe.Node(interface=util.IdentityInterface(fields=["subject_id", "dwi", "bvecs", "bvals", "subjects_dir", "resolution_network_file", ]), name="inputnode_within") FreeSurferSource = pe.Node(interface=nio.FreeSurferSource(), name='fssource') FreeSurferSourceLH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceLH') FreeSurferSourceLH.inputs.hemi = 'lh' FreeSurferSourceRH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceRH') FreeSurferSourceRH.inputs.hemi = 'rh' """ Since the b values and b vectors come from the FSL course, we must convert it to a scheme file for use in Camino. """ fsl2scheme = pe.Node(interface=camino.FSL2Scheme(), name="fsl2scheme") fsl2scheme.inputs.usegradmod = True """ FSL's Brain Extraction tool is used to create a mask from the b0 image """ b0Strip = pe.Node(interface=fsl.BET(mask = True), name = 'bet_b0') """ FSL's FLIRT function is used to coregister the b0 mask and the structural image. A convert_xfm node is then used to obtain the inverse of the transformation matrix. FLIRT is used once again to apply the inverse transformation to the parcellated brain image. """ coregister = pe.Node(interface=fsl.FLIRT(dof=6), name = 'coregister') coregister.inputs.cost = ('normmi') convertxfm = pe.Node(interface=fsl.ConvertXFM(), name = 'convertxfm') convertxfm.inputs.invert_xfm = True inverse = pe.Node(interface=fsl.FLIRT(), name = 'inverse') inverse.inputs.interp = ('nearestneighbour') inverse_AparcAseg = pe.Node(interface=fsl.FLIRT(), name = 'inverse_AparcAseg') inverse_AparcAseg.inputs.interp = ('nearestneighbour') """ A number of conversion operations are required to obtain NIFTI files from the FreesurferSource for each subject. Nodes are used to convert the following: * Original structural image to NIFTI * Parcellated white matter image to NIFTI * Parcellated whole-brain image to NIFTI * Pial, white, inflated, and spherical surfaces for both the left and right hemispheres are converted to GIFTI for visualization in ConnectomeViewer * Parcellated annotation files for the left and right hemispheres are also converted to GIFTI """ mri_convert_Brain = pe.Node(interface=fs.MRIConvert(), name='mri_convert_Brain') mri_convert_Brain.inputs.out_type = 'nii' mri_convert_AparcAseg = mri_convert_Brain.clone('mri_convert_AparcAseg') mris_convertLH = pe.Node(interface=fs.MRIsConvert(), name='mris_convertLH') mris_convertLH.inputs.out_datatype = 'gii' mris_convertRH = mris_convertLH.clone('mris_convertRH') mris_convertRHwhite = mris_convertLH.clone('mris_convertRHwhite') mris_convertLHwhite = mris_convertLH.clone('mris_convertLHwhite') mris_convertRHinflated = mris_convertLH.clone('mris_convertRHinflated') mris_convertLHinflated = mris_convertLH.clone('mris_convertLHinflated') mris_convertRHsphere = mris_convertLH.clone('mris_convertRHsphere') mris_convertLHsphere = mris_convertLH.clone('mris_convertLHsphere') mris_convertLHlabels = mris_convertLH.clone('mris_convertLHlabels') mris_convertRHlabels = mris_convertLH.clone('mris_convertRHlabels') """ In this section we create the nodes necessary for diffusion analysis. First, the diffusion image is converted to voxel order, since this is the format in which Camino does its processing. """ image2voxel = pe.Node(interface=camino.Image2Voxel(), name="image2voxel") """ Second, diffusion tensors are fit to the voxel-order data. If desired, these tensors can be converted to a Nifti tensor image using the DT2NIfTI interface. """ dtifit = pe.Node(interface=camino.DTIFit(),name='dtifit') """ Next, a lookup table is generated from the schemefile and the signal-to-noise ratio (SNR) of the unweighted (q=0) data. """ dtlutgen = pe.Node(interface=camino.DTLUTGen(), name="dtlutgen") dtlutgen.inputs.snr = 16.0 dtlutgen.inputs.inversion = 1 """ In this tutorial we implement probabilistic tractography using the PICo algorithm. PICo tractography requires an estimate of the fibre direction and a model of its uncertainty in each voxel; this probabilitiy distribution map is produced using the following node. """ picopdfs = pe.Node(interface=camino.PicoPDFs(), name="picopdfs") picopdfs.inputs.inputmodel = 'dt' """ Finally, tractography is performed. In this tutorial, we will use only one iteration for time-saving purposes. It is important to note that we use the TrackPICo interface here. This interface now expects the files required for PICo tracking (i.e. the output from picopdfs). Similar interfaces exist for alternative types of tracking, such as Bayesian tracking with Dirac priors (TrackBayesDirac). """ track = pe.Node(interface=camino.TrackPICo(), name="track") track.inputs.iterations = 1 """ Currently, the best program for visualizing tracts is TrackVis. For this reason, a node is included to convert the raw tract data to .trk format. Solely for testing purposes, another node is added to perform the reverse. """ camino2trackvis = pe.Node(interface=cam2trk.Camino2Trackvis(), name="camino2trackvis") camino2trackvis.inputs.min_length = 30 camino2trackvis.inputs.voxel_order = 'LAS' trk2camino = pe.Node(interface=cam2trk.Trackvis2Camino(), name="trk2camino") """ Tracts can also be converted to VTK and OOGL formats, for use in programs such as GeomView and Paraview, using the following two nodes. """ vtkstreamlines = pe.Node(interface=camino.VtkStreamlines(), name="vtkstreamlines") procstreamlines = pe.Node(interface=camino.ProcStreamlines(), name="procstreamlines") """ We can easily produce a variety of scalar values from our fitted tensors. The following nodes generate the fractional anisotropy and diffusivity trace maps and their associated headers, and then merge them back into a single .nii file. """ fa = pe.Node(interface=camino.ComputeFractionalAnisotropy(),name='fa') trace = pe.Node(interface=camino.ComputeTensorTrace(),name='trace') dteig = pe.Node(interface=camino.ComputeEigensystem(), name='dteig') analyzeheader_fa = pe.Node(interface=camino.AnalyzeHeader(),name='analyzeheader_fa') analyzeheader_fa.inputs.datatype = 'double' analyzeheader_trace = pe.Node(interface=camino.AnalyzeHeader(),name='analyzeheader_trace') analyzeheader_trace.inputs.datatype = 'double' fa2nii = pe.Node(interface=misc.CreateNifti(),name='fa2nii') trace2nii = fa2nii.clone("trace2nii") """ This section adds the Connectome Mapping Toolkit (CMTK) nodes. These interfaces are fairly experimental and may not function properly. In order to perform connectivity mapping using CMTK, the parcellated structural data is rewritten using the indices and parcellation scheme from the connectome mapper (CMP). This process has been written into the ROIGen interface, which will output a remapped aparc+aseg image as well as a dictionary of label information (i.e. name, display colours) pertaining to the original and remapped regions. These label values are input from a user-input lookup table, if specified, and otherwise the default Freesurfer LUT (/freesurfer/FreeSurferColorLUT.txt). """ roigen = pe.Node(interface=cmtk.ROIGen(), name="ROIGen") roigen_structspace = roigen.clone("ROIGen_structspace") """ The CreateMatrix interface takes in the remapped aparc+aseg image as well as the label dictionary and fiber tracts and outputs a number of different files. The most important of which is the connectivity network itself, which is stored as a 'gpickle' and can be loaded using Python's NetworkX package (see CreateMatrix docstring). Also outputted are various NumPy arrays containing detailed tract information, such as the start and endpoint regions, and statistics on the mean and standard deviation for the fiber length of each connection. These matrices can be used in the ConnectomeViewer to plot the specific tracts that connect between user-selected regions. """ createnodes = pe.Node(interface=cmtk.CreateNodes(), name="CreateNodes") creatematrix = pe.Node(interface=cmtk.CreateMatrix(), name="CreateMatrix") creatematrix.inputs.count_region_intersections = True """ Here we define the endpoint of this tutorial, which is the CFFConverter node, as well as a few nodes which use the Nipype Merge utility. These are useful for passing lists of the files we want packaged in our CFF file. """ CFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="CFFConverter") giftiSurfaces = pe.Node(interface=util.Merge(8), name="GiftiSurfaces") giftiLabels = pe.Node(interface=util.Merge(2), name="GiftiLabels") niftiVolumes = pe.Node(interface=util.Merge(3), name="NiftiVolumes") fiberDataArrays = pe.Node(interface=util.Merge(4), name="FiberDataArrays") gpickledNetworks = pe.Node(interface=util.Merge(1), name="NetworkFiles") """ Since we have now created all our nodes, we can define our workflow and start making connections. """ mapping = pe.Workflow(name='mapping') """ First, we connect the input node to the early conversion functions. FreeSurfer input nodes: """ mapping.connect([(inputnode_within, FreeSurferSource,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSource,[("subject_id","subject_id")])]) mapping.connect([(inputnode_within, FreeSurferSourceLH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSourceLH,[("subject_id","subject_id")])]) mapping.connect([(inputnode_within, FreeSurferSourceRH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSourceRH,[("subject_id","subject_id")])]) """ Required conversions for processing in Camino: """ mapping.connect([(inputnode_within, image2voxel, [("dwi", "in_file")]), (inputnode_within, fsl2scheme, [("bvecs", "bvec_file"), ("bvals", "bval_file")]), (image2voxel, dtifit,[['voxel_order','in_file']]), (fsl2scheme, dtifit,[['scheme','scheme_file']]) ]) """ Nifti conversions for the subject's stripped brain image from Freesurfer: """ mapping.connect([(FreeSurferSource, mri_convert_Brain,[('brain','in_file')])]) """ Surface conversions to GIFTI (pial, white, inflated, and sphere for both hemispheres) """ mapping.connect([(FreeSurferSourceLH, mris_convertLH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHsphere,[('sphere','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHsphere,[('sphere','in_file')])]) """ The annotation files are converted using the pial surface as a map via the MRIsConvert interface. One of the functions defined earlier is used to select the lh.aparc.annot and rh.aparc.annot files specifically (rather than i.e. rh.aparc.a2009s.annot) from the output list given by the FreeSurferSource. """ mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) """ This section coregisters the diffusion-weighted and parcellated white-matter / whole brain images. At present the conmap node connection is left commented, as there have been recent changes in Camino code that have presented some users with errors. """ mapping.connect([(inputnode_within, b0Strip,[('dwi','in_file')])]) mapping.connect([(inputnode_within, b0Strip,[('dwi','t2_guided')])]) # Added to improve damaged brain extraction mapping.connect([(b0Strip, coregister,[('out_file','in_file')])]) mapping.connect([(mri_convert_Brain, coregister,[('out_file','reference')])]) mapping.connect([(coregister, convertxfm,[('out_matrix_file','in_file')])]) mapping.connect([(b0Strip, inverse,[('out_file','reference')])]) mapping.connect([(convertxfm, inverse,[('out_file','in_matrix_file')])]) mapping.connect([(mri_convert_Brain, inverse,[('out_file','in_file')])]) """ The tractography pipeline consists of the following nodes. Further information about the tractography can be found in nipype/examples/dmri_camino_dti.py. """ mapping.connect([(b0Strip, track,[("mask_file","seed_file")])]) mapping.connect([(fsl2scheme, dtlutgen,[("scheme","scheme_file")])]) mapping.connect([(dtlutgen, picopdfs,[("dtLUT","luts")])]) mapping.connect([(dtifit, picopdfs,[("tensor_fitted","in_file")])]) mapping.connect([(picopdfs, track,[("pdfs","in_file")])]) """ Connecting the Fractional Anisotropy and Trace nodes is simple, as they obtain their input from the tensor fitting. This is also where our voxel- and data-grabbing functions come in. We pass these functions, along with the original DWI image from the input node, to the header-generating nodes. This ensures that the files will be correct and readable. """ mapping.connect([(dtifit, fa,[("tensor_fitted","in_file")])]) mapping.connect([(fa, analyzeheader_fa,[("fa","in_file")])]) mapping.connect([(inputnode_within, analyzeheader_fa,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) mapping.connect([(fa, fa2nii,[('fa','data_file')])]) mapping.connect([(inputnode_within, fa2nii,[(('dwi', get_affine), 'affine')])]) mapping.connect([(analyzeheader_fa, fa2nii,[('header', 'header_file')])]) mapping.connect([(dtifit, trace,[("tensor_fitted","in_file")])]) mapping.connect([(trace, analyzeheader_trace,[("trace","in_file")])]) mapping.connect([(inputnode_within, analyzeheader_trace,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) mapping.connect([(trace, trace2nii,[('trace','data_file')])]) mapping.connect([(inputnode_within, trace2nii,[(('dwi', get_affine), 'affine')])]) mapping.connect([(analyzeheader_trace, trace2nii,[('header', 'header_file')])]) mapping.connect([(dtifit, dteig,[("tensor_fitted","in_file")])]) """ The output tracts are converted to Trackvis format (and back). Here we also use the voxel- and data-grabbing functions defined at the beginning of the pipeline. """ mapping.connect([(track, camino2trackvis, [('tracked','in_file')]), (track, vtkstreamlines,[['tracked','in_file']]), (camino2trackvis, trk2camino,[['trackvis','in_file']]) ]) mapping.connect([(inputnode_within, camino2trackvis,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) """ Here the CMTK connectivity mapping nodes are connected. The original aparc+aseg image is converted to NIFTI, then registered to the diffusion image and delivered to the ROIGen node. The remapped parcellation, original tracts, and label file are then given to CreateMatrix. """ mapping.connect(inputnode_within, 'resolution_network_file', createnodes, 'resolution_network_file') mapping.connect(createnodes, 'node_network', creatematrix, 'resolution_network_file') mapping.connect([(FreeSurferSource, mri_convert_AparcAseg, [(('aparc_aseg', select_aparc), 'in_file')])]) mapping.connect([(b0Strip, inverse_AparcAseg,[('out_file','reference')])]) mapping.connect([(convertxfm, inverse_AparcAseg,[('out_file','in_matrix_file')])]) mapping.connect([(mri_convert_AparcAseg, inverse_AparcAseg,[('out_file','in_file')])]) mapping.connect([(mri_convert_AparcAseg, roigen_structspace,[('out_file','aparc_aseg_file')])]) mapping.connect([(roigen_structspace, createnodes,[("roi_file","roi_file")])]) mapping.connect([(inverse_AparcAseg, roigen,[("out_file","aparc_aseg_file")])]) mapping.connect([(roigen, creatematrix,[("roi_file","roi_file")])]) mapping.connect([(camino2trackvis, creatematrix,[("trackvis","tract_file")])]) mapping.connect([(inputnode_within, creatematrix,[("subject_id","out_matrix_file")])]) mapping.connect([(inputnode_within, creatematrix,[("subject_id","out_matrix_mat_file")])]) """ The merge nodes defined earlier are used here to create lists of the files which are destined for the CFFConverter. """ mapping.connect([(mris_convertLH, giftiSurfaces,[("converted","in1")])]) mapping.connect([(mris_convertRH, giftiSurfaces,[("converted","in2")])]) mapping.connect([(mris_convertLHwhite, giftiSurfaces,[("converted","in3")])]) mapping.connect([(mris_convertRHwhite, giftiSurfaces,[("converted","in4")])]) mapping.connect([(mris_convertLHinflated, giftiSurfaces,[("converted","in5")])]) mapping.connect([(mris_convertRHinflated, giftiSurfaces,[("converted","in6")])]) mapping.connect([(mris_convertLHsphere, giftiSurfaces,[("converted","in7")])]) mapping.connect([(mris_convertRHsphere, giftiSurfaces,[("converted","in8")])]) mapping.connect([(mris_convertLHlabels, giftiLabels,[("converted","in1")])]) mapping.connect([(mris_convertRHlabels, giftiLabels,[("converted","in2")])]) mapping.connect([(roigen, niftiVolumes,[("roi_file","in1")])]) mapping.connect([(inputnode_within, niftiVolumes,[("dwi","in2")])]) mapping.connect([(mri_convert_Brain, niftiVolumes,[("out_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file","in1")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file_mm","in2")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_length_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_label_file","in4")])]) """ This block actually connects the merged lists to the CFF converter. We pass the surfaces and volumes that are to be included, as well as the tracts and the network itself. The currently running pipeline (dmri_connectivity.py) is also scraped and included in the CFF file. This makes it easy for the user to examine the entire processing pathway used to generate the end product. """ CFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) mapping.connect([(giftiSurfaces, CFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, CFFConverter,[("out","gifti_labels")])]) mapping.connect([(creatematrix, CFFConverter,[("matrix_files","gpickled_networks")])]) mapping.connect([(niftiVolumes, CFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, CFFConverter,[("out","data_files")])]) mapping.connect([(camino2trackvis, CFFConverter,[("trackvis","tract_files")])]) mapping.connect([(inputnode_within, CFFConverter,[("subject_id","title")])]) """ Finally, we create another higher-level workflow to connect our mapping workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial can is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["subject_id", "dwi", "bvecs", "bvals", "subjects_dir", "resolution_network_file"]), name="inputnode") outputnode = pe.Node(interface = util.IdentityInterface(fields=["fa", "struct", "trace", "tracts", "connectome", "cmatrix", "networks", "rois", "mean_fiber_length", "fiber_length_std", "tensors"]), name="outputnode") connectivity = pe.Workflow(name="connectivity") connectivity.base_output_dir=name connectivity.connect([(inputnode, mapping, [("dwi", "inputnode_within.dwi"), ("bvals", "inputnode_within.bvals"), ("bvecs", "inputnode_within.bvecs"), ("subject_id", "inputnode_within.subject_id"), ("subjects_dir", "inputnode_within.subjects_dir"), ("resolution_network_file", "inputnode_within.resolution_network_file")]) ]) connectivity.connect([(mapping, outputnode, [("camino2trackvis.trackvis", "tracts"), ("CFFConverter.connectome_file", "connectome"), ("CreateMatrix.matrix_mat_file", "cmatrix"), ("CreateMatrix.mean_fiber_length_matrix_mat_file", "mean_fiber_length"), ("CreateMatrix.fiber_length_std_matrix_mat_file", "fiber_length_std"), ("fa2nii.nifti_file", "fa"), ("CreateMatrix.matrix_files", "networks"), ("ROIGen.roi_file", "rois"), ("mri_convert_Brain.out_file", "struct"), ("trace2nii.nifti_file", "trace"), ("dtifit.tensor_fitted", "tensors")]) ]) return connectivity nipype-0.11.0/nipype/workflows/dmri/camino/diffusion.py000066400000000000000000000243531257611314500232130ustar00rootroot00000000000000import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.camino as camino import nipype.interfaces.fsl as fsl import nipype.interfaces.camino2trackvis as cam2trk import nipype.algorithms.misc as misc from ...misc.utils import get_affine, get_data_dims, get_vox_dims def create_camino_dti_pipeline(name="dtiproc"): """Creates a pipeline that does the same diffusion processing as in the :doc:`../../users/examples/dmri_camino_dti` example script. Given a diffusion-weighted image, b-values, and b-vectors, the workflow will return the tractography computed from diffusion tensors and from PICo probabilistic tractography. Example ------- >>> import os >>> nipype_camino_dti = create_camino_dti_pipeline("nipype_camino_dti") >>> nipype_camino_dti.inputs.inputnode.dwi = os.path.abspath('dwi.nii') >>> nipype_camino_dti.inputs.inputnode.bvecs = os.path.abspath('bvecs') >>> nipype_camino_dti.inputs.inputnode.bvals = os.path.abspath('bvals') >>> nipype_camino_dti.run() # doctest: +SKIP Inputs:: inputnode.dwi inputnode.bvecs inputnode.bvals Outputs:: outputnode.fa outputnode.trace outputnode.tracts_pico outputnode.tracts_dt outputnode.tensors """ inputnode1 = pe.Node(interface=util.IdentityInterface(fields=["dwi", "bvecs", "bvals"]), name="inputnode1") """ Setup for Diffusion Tensor Computation -------------------------------------- In this section we create the nodes necessary for diffusion analysis. First, the diffusion image is converted to voxel order. """ image2voxel = pe.Node(interface=camino.Image2Voxel(), name="image2voxel") fsl2scheme = pe.Node(interface=camino.FSL2Scheme(), name="fsl2scheme") fsl2scheme.inputs.usegradmod = True """ Second, diffusion tensors are fit to the voxel-order data. """ dtifit = pe.Node(interface=camino.DTIFit(),name='dtifit') """ Next, a lookup table is generated from the schemefile and the signal-to-noise ratio (SNR) of the unweighted (q=0) data. """ dtlutgen = pe.Node(interface=camino.DTLUTGen(), name="dtlutgen") dtlutgen.inputs.snr = 16.0 dtlutgen.inputs.inversion = 1 """ In this tutorial we implement probabilistic tractography using the PICo algorithm. PICo tractography requires an estimate of the fibre direction and a model of its uncertainty in each voxel; this is produced using the following node. """ picopdfs = pe.Node(interface=camino.PicoPDFs(), name="picopdfs") picopdfs.inputs.inputmodel = 'dt' """ An FSL BET node creates a brain mask is generated from the diffusion image for seeding the PICo tractography. """ bet = pe.Node(interface=fsl.BET(), name="bet") bet.inputs.mask = True """ Finally, tractography is performed. First DT streamline tractography. """ trackdt = pe.Node(interface=camino.TrackDT(), name="trackdt") """ Now camino's Probablistic Index of connectivity algorithm. In this tutorial, we will use only 1 iteration for time-saving purposes. """ trackpico = pe.Node(interface=camino.TrackPICo(), name="trackpico") trackpico.inputs.iterations = 1 """ Currently, the best program for visualizing tracts is TrackVis. For this reason, a node is included to convert the raw tract data to .trk format. Solely for testing purposes, another node is added to perform the reverse. """ cam2trk_dt = pe.Node(interface=cam2trk.Camino2Trackvis(), name="cam2trk_dt") cam2trk_dt.inputs.min_length = 30 cam2trk_dt.inputs.voxel_order = 'LAS' cam2trk_pico = pe.Node(interface=cam2trk.Camino2Trackvis(), name="cam2trk_pico") cam2trk_pico.inputs.min_length = 30 cam2trk_pico.inputs.voxel_order = 'LAS' """ Tracts can also be converted to VTK and OOGL formats, for use in programs such as GeomView and Paraview, using the following two nodes. """ #vtkstreamlines = pe.Node(interface=camino.VtkStreamlines(), name="vtkstreamlines") #procstreamlines = pe.Node(interface=camino.ProcStreamlines(), name="procstreamlines") #procstreamlines.inputs.outputtracts = 'oogl' """ We can also produce a variety of scalar values from our fitted tensors. The following nodes generate the fractional anisotropy and diffusivity trace maps and their associated headers. """ fa = pe.Node(interface=camino.ComputeFractionalAnisotropy(),name='fa') #md = pe.Node(interface=camino.MD(),name='md') trace = pe.Node(interface=camino.ComputeTensorTrace(),name='trace') dteig = pe.Node(interface=camino.ComputeEigensystem(), name='dteig') analyzeheader_fa = pe.Node(interface= camino.AnalyzeHeader(), name = "analyzeheader_fa") analyzeheader_fa.inputs.datatype = "double" analyzeheader_trace = analyzeheader_fa.clone('analyzeheader_trace') #analyzeheader_md = pe.Node(interface= camino.AnalyzeHeader(), name = "analyzeheader_md") #analyzeheader_md.inputs.datatype = "double" #analyzeheader_trace = analyzeheader_md.clone('analyzeheader_trace') fa2nii = pe.Node(interface=misc.CreateNifti(),name='fa2nii') trace2nii = fa2nii.clone("trace2nii") """ Since we have now created all our nodes, we can now define our workflow and start making connections. """ tractography = pe.Workflow(name='tractography') tractography.connect([(inputnode1, bet,[("dwi","in_file")])]) """ File format conversion """ tractography.connect([(inputnode1, image2voxel, [("dwi", "in_file")]), (inputnode1, fsl2scheme, [("bvecs", "bvec_file"), ("bvals", "bval_file")]) ]) """ Tensor fitting """ tractography.connect([(image2voxel, dtifit,[['voxel_order','in_file']]), (fsl2scheme, dtifit,[['scheme','scheme_file']]) ]) """ Workflow for applying DT streamline tractogpahy """ tractography.connect([(bet, trackdt,[("mask_file","seed_file")])]) tractography.connect([(dtifit, trackdt,[("tensor_fitted","in_file")])]) """ Workflow for applying PICo """ tractography.connect([(bet, trackpico,[("mask_file","seed_file")])]) tractography.connect([(fsl2scheme, dtlutgen,[("scheme","scheme_file")])]) tractography.connect([(dtlutgen, picopdfs,[("dtLUT","luts")])]) tractography.connect([(dtifit, picopdfs,[("tensor_fitted","in_file")])]) tractography.connect([(picopdfs, trackpico,[("pdfs","in_file")])]) # Mean diffusivity still appears broken #tractography.connect([(dtifit, md,[("tensor_fitted","in_file")])]) #tractography.connect([(md, analyzeheader_md,[("md","in_file")])]) #tractography.connect([(inputnode, analyzeheader_md,[(('dwi', get_vox_dims), 'voxel_dims'), #(('dwi', get_data_dims), 'data_dims')])]) #This line is commented out because the ProcStreamlines node keeps throwing memory errors #tractography.connect([(track, procstreamlines,[("tracked","in_file")])]) """ Connecting the Fractional Anisotropy and Trace nodes is simple, as they obtain their input from the tensor fitting. This is also where our voxel- and data-grabbing functions come in. We pass these functions, along with the original DWI image from the input node, to the header-generating nodes. This ensures that the files will be correct and readable. """ tractography.connect([(dtifit, fa,[("tensor_fitted","in_file")])]) tractography.connect([(fa, analyzeheader_fa,[("fa","in_file")])]) tractography.connect([(inputnode1, analyzeheader_fa,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(fa, fa2nii,[('fa','data_file')])]) tractography.connect([(inputnode1, fa2nii,[(('dwi', get_affine), 'affine')])]) tractography.connect([(analyzeheader_fa, fa2nii,[('header', 'header_file')])]) tractography.connect([(dtifit, trace,[("tensor_fitted","in_file")])]) tractography.connect([(trace, analyzeheader_trace,[("trace","in_file")])]) tractography.connect([(inputnode1, analyzeheader_trace,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(trace, trace2nii,[('trace','data_file')])]) tractography.connect([(inputnode1, trace2nii,[(('dwi', get_affine), 'affine')])]) tractography.connect([(analyzeheader_trace, trace2nii,[('header', 'header_file')])]) tractography.connect([(dtifit, dteig,[("tensor_fitted","in_file")])]) tractography.connect([(trackpico, cam2trk_pico, [('tracked','in_file')])]) tractography.connect([(trackdt, cam2trk_dt, [('tracked','in_file')])]) tractography.connect([(inputnode1, cam2trk_pico,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) tractography.connect([(inputnode1, cam2trk_dt,[(('dwi', get_vox_dims), 'voxel_dims'), (('dwi', get_data_dims), 'data_dims')])]) inputnode= pe.Node(interface = util.IdentityInterface(fields=["dwi", "bvecs", "bvals"]), name="inputnode") outputnode = pe.Node(interface = util.IdentityInterface(fields=["fa", "trace", "tracts_pico", "tracts_dt", "tensors"]), name="outputnode") workflow = pe.Workflow(name=name) workflow.base_output_dir=name workflow.connect([(inputnode, tractography, [("dwi", "inputnode1.dwi"), ("bvals", "inputnode1.bvals"), ("bvecs", "inputnode1.bvecs")])]) workflow.connect([(tractography, outputnode, [("cam2trk_dt.trackvis", "tracts_dt"), ("cam2trk_pico.trackvis", "tracts_pico"), ("fa2nii.nifti_file", "fa"), ("trace2nii.nifti_file", "trace"), ("dtifit.tensor_fitted", "tensors")]) ]) return workflow nipype-0.11.0/nipype/workflows/dmri/camino/group_connectivity.py000066400000000000000000000122541257611314500251540ustar00rootroot00000000000000import os.path as op # system functions import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine from .connectivity_mapping import create_connectivity_pipeline def create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, template_args_dict=0): """Creates a pipeline that performs basic Camino structural connectivity processing on groups of subjects. Given a diffusion-weighted image, and text files containing the associated b-values and b-vectors, the workflow will return each subjects' connectomes in a Connectome File Format (CFF) file, for use in Connectome Viewer (http://www.cmtk.org). Example ------- >>> import nipype.interfaces.freesurfer as fs >>> import nipype.workflows.dmri.camino.group_connectivity as groupwork >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> fs.FSCommand.set_default_subjects_dir(subjects_dir) >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> template_args = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id', 'bvecs']], bvals=[['subject_id', 'bvals']]) >>> group_id = 'group1' >>> l1pipeline = groupwork.create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, template_args) >>> l1pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name group_id: String containing the group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files template_args_dict: Dictionary of template arguments for the connectivity pipeline datasource e.g. info = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) """ group_infosource = pe.Node(interface=util.IdentityInterface(fields=['group_id']), name="group_infosource") group_infosource.inputs.group_id = group_id subject_list = group_list[group_id] subj_infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="subj_infosource") subj_infosource.iterables = ('subject_id', subject_list) if template_args_dict == 0: info = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) else: info = template_args_dict datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" datasource.inputs.base_directory = data_dir datasource.inputs.field_template = dict(dwi='%s/%s.nii') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Create a connectivity mapping workflow """ conmapper = create_connectivity_pipeline("nipype_conmap") conmapper.inputs.inputnode.subjects_dir = subjects_dir conmapper.base_dir = op.abspath('conmapper') datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = output_dir datasink.inputs.container = group_id l1pipeline = pe.Workflow(name="l1pipeline_"+group_id) l1pipeline.base_dir = output_dir l1pipeline.base_output_dir = group_id l1pipeline.connect([(subj_infosource, datasource,[('subject_id', 'subject_id')])]) l1pipeline.connect([(subj_infosource, conmapper,[('subject_id', 'inputnode.subject_id')])]) l1pipeline.connect([(datasource, conmapper, [("dwi", "inputnode.dwi"), ("bvals", "inputnode.bvals"), ("bvecs", "inputnode.bvecs"), ])]) l1pipeline.connect([(conmapper, datasink, [("outputnode.connectome", "@l1output.cff"), ("outputnode.fa", "@l1output.fa"), ("outputnode.tracts", "@l1output.tracts"), ("outputnode.trace", "@l1output.trace"), ("outputnode.cmatrix", "@l1output.cmatrix"), ("outputnode.rois", "@l1output.rois"), ("outputnode.struct", "@l1output.struct"), ("outputnode.networks", "@l1output.networks"), ("outputnode.mean_fiber_length", "@l1output.mean_fiber_length"), ("outputnode.fiber_length_std", "@l1output.fiber_length_std"), ])]) l1pipeline.connect([(group_infosource, datasink,[('group_id','@group_id')])]) return l1pipeline nipype-0.11.0/nipype/workflows/dmri/connectivity/000077500000000000000000000000001257611314500221145ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/connectivity/__init__.py000066400000000000000000000006771257611314500242370ustar00rootroot00000000000000from nx import (create_networkx_pipeline, create_cmats_to_csv_pipeline) from group_connectivity import (create_merge_networks_by_group_workflow, create_merge_network_results_by_group_workflow, create_merge_group_networks_workflow, create_merge_group_network_results_workflow, create_average_networks_by_group_workflow) nipype-0.11.0/nipype/workflows/dmri/connectivity/group_connectivity.py000066400000000000000000000565431257611314500264350ustar00rootroot00000000000000import os.path as op import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.interfaces.cmtk as cmtk import nipype.algorithms.misc as misc import nipype.pipeline.engine as pe # pypeline engine from nipype.interfaces.utility import Function from nipype.utils.misc import package_check have_cmp = True try: package_check('cmp') except Exception, e: have_cmp = False else: import cmp def pullnodeIDs(in_network, name_key='dn_name'): """ This function will return the values contained, for each node in a network, given an input key. By default it will return the node names """ import networkx as nx import numpy as np from nipype.interfaces.base import isdefined if not isdefined(in_network): raise ValueError return None try: ntwk = nx.read_graphml(in_network) except: ntwk = nx.read_gpickle(in_network) nodedata = ntwk.node ids = [] integer_nodelist = [] for node in nodedata.keys(): integer_nodelist.append(int(node)) for node in np.sort(integer_nodelist): try: nodeid = nodedata[node][name_key] except KeyError: nodeid = nodedata[str(node)][name_key] ids.append(nodeid) return ids def concatcsv(in_files): """ This function will contatenate two "comma-separated value" text files, but remove the first row (usually column headers) from all but the first file. """ import os.path as op from nipype.utils.filemanip import split_filename if not isinstance(in_files, list): return in_files if isinstance(in_files[0], list): in_files = in_files[0] first = open(in_files[0], 'r') path, name, ext = split_filename(in_files[0]) out_name = op.abspath('concat.csv') out_file = open(out_name, 'w') out_file.write(first.readline()) first.close() for in_file in in_files: file_to_read = open(in_file, 'r') scrap_first_line = file_to_read.readline() for line in file_to_read: out_file.write(line) return out_name def create_merge_networks_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir): """Creates a second-level pipeline to merge the Connectome File Format (CFF) outputs from the group-level MRtrix structural connectivity processing pipeline into a single CFF file for each group. Example ------- >>> import nipype.workflows.dmri.connectivity.group_connectivity as groupwork >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> group_id = 'group1' >>> l2pipeline = groupwork.create_merge_networks_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir) >>> l2pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name group_id: String containing the group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files """ group_infosource = pe.Node(interface=util.IdentityInterface( fields=['group_id']), name="group_infosource") group_infosource.inputs.group_id = group_id l2infosource = pe.Node(interface=util.IdentityInterface( fields=['group_id']), name='l2infosource') l2source = pe.Node(nio.DataGrabber( infields=['group_id'], outfields=['CFFfiles']), name='l2source') l2source.inputs.template_args = dict(CFFfiles=[['group_id']]) l2source.inputs.template = op.join(output_dir, '%s/cff/*/connectome.cff') l2source.inputs.base_directory = data_dir l2source.inputs.sort_filelist = True l2inputnode = pe.Node(interface=util.IdentityInterface( fields=['CFFfiles']), name='l2inputnode') MergeCNetworks = pe.Node( interface=cmtk.MergeCNetworks(), name="MergeCNetworks") l2datasink = pe.Node(interface=nio.DataSink(), name="l2datasink") l2datasink.inputs.base_directory = output_dir l2datasink.inputs.container = group_id l2pipeline = pe.Workflow(name="l2output_" + group_id) l2pipeline.base_dir = op.join(output_dir, 'l2output') l2pipeline.connect( [(group_infosource, l2infosource, [('group_id', 'group_id')])]) l2pipeline.connect([ (l2infosource, l2source, [('group_id', 'group_id')]), (l2source, l2inputnode, [('CFFfiles', 'CFFfiles')]), ]) l2pipeline.connect( [(l2inputnode, MergeCNetworks, [('CFFfiles', 'in_files')])]) l2pipeline.connect( [(group_infosource, MergeCNetworks, [('group_id', 'out_file')])]) l2pipeline.connect( [(MergeCNetworks, l2datasink, [('connectome_file', '@l2output')])]) l2pipeline.connect( [(group_infosource, l2datasink, [('group_id', '@group_id')])]) return l2pipeline def create_merge_network_results_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir): """Creates a second-level pipeline to merge the Connectome File Format (CFF) outputs from the group-level MRtrix structural connectivity processing pipeline into a single CFF file for each group. Example ------- >>> import nipype.workflows.dmri.connectivity.group_connectivity as groupwork >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> group_id = 'group1' >>> l2pipeline = groupwork.create_merge_network_results_by_group_workflow(group_list, group_id, data_dir, subjects_dir, output_dir) >>> l2pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name group_id: String containing the group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files """ group_infosource = pe.Node(interface=util.IdentityInterface( fields=['group_id']), name="group_infosource") group_infosource.inputs.group_id = group_id l2infosource = pe.Node(interface=util.IdentityInterface(fields=['group_id', 'merged', ]), name='l2infosource') l2source = pe.Node( nio.DataGrabber( infields=['group_id'], outfields=['CFFfiles', 'CSVmatrices', 'CSVfibers', 'CSVnodal', 'CSVglobal']), name='l2source') l2source.inputs.template_args = dict( CFFfiles=[['group_id']], CSVmatrices=[['group_id']], CSVnodal=[['group_id']], CSVglobal=[['group_id']], CSVfibers=[['group_id']]) l2source.inputs.base_directory = data_dir l2source.inputs.template = '%s/%s' l2source.inputs.field_template = dict( CFFfiles=op.join(output_dir, '%s/cff/*/connectome.cff'), CSVmatrices=op.join(output_dir, '%s/cmatrices_csv/*/*.csv'), CSVnodal=op.join(output_dir, '%s/nxcsv/*/*nodal*.csv'), CSVglobal=op.join(output_dir, '%s/nxcsv/*/*global*.csv'), CSVfibers=op.join(output_dir, '%s/fiber_csv/*/*fibers*.csv')) l2source.inputs.sort_filelist = True l2inputnode = pe.Node(interface=util.IdentityInterface(fields=['CFFfiles', 'CSVfibers', 'CSVmatrices', 'CSVnodal', 'CSVglobal', 'network_file']), name='l2inputnode') MergeCNetworks = pe.Node( interface=cmtk.MergeCNetworks(), name="MergeCNetworks") l2datasink = pe.Node(interface=nio.DataSink(), name="l2datasink") l2datasink.inputs.base_directory = output_dir l2datasink.inputs.container = group_id l2pipeline = pe.Workflow(name="l2output_" + group_id) l2pipeline.base_dir = op.join(output_dir, 'l2output') l2pipeline.connect( [(group_infosource, l2infosource, [('group_id', 'group_id')])]) l2pipeline.connect([ (l2infosource, l2source, [('group_id', 'group_id')]), (l2source, l2inputnode, [('CFFfiles', 'CFFfiles')]), (l2source, l2inputnode, [( 'CSVmatrices', 'CSVmatrices')]), (l2source, l2inputnode, [('CSVnodal', 'CSVnodal')]), (l2source, l2inputnode, [('CSVglobal', 'CSVglobal')]), (l2source, l2inputnode, [('CSVfibers', 'CSVfibers')]), ]) l2pipeline.connect( [(l2inputnode, MergeCNetworks, [('CFFfiles', 'in_files')])]) l2pipeline.connect( [(group_infosource, MergeCNetworks, [('group_id', 'out_file')])]) l2pipeline.connect( [(MergeCNetworks, l2datasink, [('connectome_file', '@l2output')])]) AddCSVColumn_node = pe.Node( interface=misc.AddCSVColumn(), name="AddCSVColumn_node") AddCSVColumn_node.inputs.extra_column_heading = 'group' AddCSVColumn_global = AddCSVColumn_node.clone(name="AddCSVColumn_global") AddCSVColumn_matrices = AddCSVColumn_node.clone( name="AddCSVColumn_matrices") AddCSVColumn_fibers = AddCSVColumn_node.clone(name="AddCSVColumn_fibers") concat_csv_interface = Function( input_names=["in_files"], output_names=["out_name"], function=concatcsv) concat_node_csvs = pe.Node( interface=concat_csv_interface, name='concat_node_csvs') concat_global_csvs = pe.Node( interface=concat_csv_interface, name='concat_global_csvs') concat_matrix_csvs = pe.Node( interface=concat_csv_interface, name='concat_matrix_csvs') concat_fiber_csvs = pe.Node( interface=concat_csv_interface, name='concat_fiber_csvs') l2pipeline.connect( [(l2inputnode, concat_node_csvs, [('CSVnodal', 'in_files')])]) l2pipeline.connect( [(concat_node_csvs, AddCSVColumn_node, [('out_name', 'in_file')])]) l2pipeline.connect([( group_infosource, AddCSVColumn_node, [('group_id', 'extra_field')])]) l2pipeline.connect([( AddCSVColumn_node, l2datasink, [('csv_file', '@l2output.node_csv')])]) l2pipeline.connect( [(group_infosource, l2datasink, [('group_id', '@group_id')])]) l2pipeline.connect( [(l2inputnode, concat_global_csvs, [('CSVglobal', 'in_files')])]) l2pipeline.connect([( concat_global_csvs, AddCSVColumn_global, [('out_name', 'in_file')])]) l2pipeline.connect([(group_infosource, AddCSVColumn_global, [( 'group_id', 'extra_field')])]) l2pipeline.connect([(AddCSVColumn_global, l2datasink, [('csv_file', '@l2output.global_csv')])]) l2pipeline.connect( [(l2inputnode, concat_matrix_csvs, [('CSVmatrices', 'in_files')])]) l2pipeline.connect([(concat_matrix_csvs, AddCSVColumn_matrices, [( 'out_name', 'in_file')])]) l2pipeline.connect([(group_infosource, AddCSVColumn_matrices, [( 'group_id', 'extra_field')])]) l2pipeline.connect([(AddCSVColumn_matrices, l2datasink, [( 'csv_file', '@l2output.cmatrices_csv')])]) l2pipeline.connect( [(l2inputnode, concat_fiber_csvs, [('CSVmatrices', 'in_files')])]) l2pipeline.connect( [(concat_fiber_csvs, AddCSVColumn_fibers, [('out_name', 'in_file')])]) l2pipeline.connect([(group_infosource, AddCSVColumn_fibers, [( 'group_id', 'extra_field')])]) l2pipeline.connect([(AddCSVColumn_fibers, l2datasink, [('csv_file', '@l2output.fibers_csv')])]) return l2pipeline def create_merge_group_networks_workflow(group_list, data_dir, subjects_dir, output_dir, title='group'): """Creates a third-level pipeline to merge the Connectome File Format (CFF) outputs from each group and combines them into a single CFF file for each group. Example ------- >>> import nipype.workflows.dmri.connectivity.group_connectivity as groupwork >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> l3pipeline = groupwork.create_merge_group_networks_workflow(group_list, data_dir, subjects_dir, output_dir) >>> l3pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files title: String to use as a title for the output merged CFF file (default 'group') """ l3infosource = pe.Node(interface=util.IdentityInterface( fields=['group_id']), name='l3infosource') l3infosource.inputs.group_id = group_list.keys() l3source = pe.Node(nio.DataGrabber( infields=['group_id'], outfields=['CFFfiles']), name='l3source') l3source.inputs.template_args = dict(CFFfiles=[['group_id', 'group_id']]) l3source.inputs.template = op.join(output_dir, '%s/%s.cff') l3source.inputs.sort_filelist = True l3inputnode = pe.Node(interface=util.IdentityInterface( fields=['Group_CFFs']), name='l3inputnode') MergeCNetworks_grp = pe.Node( interface=cmtk.MergeCNetworks(), name="MergeCNetworks_grp") MergeCNetworks_grp.inputs.out_file = title l3datasink = pe.Node(interface=nio.DataSink(), name="l3datasink") l3datasink.inputs.base_directory = output_dir l3pipeline = pe.Workflow(name="l3output") l3pipeline.base_dir = output_dir l3pipeline.connect([ (l3infosource, l3source, [('group_id', 'group_id')]), (l3source, l3inputnode, [('CFFfiles', 'Group_CFFs')]), ]) l3pipeline.connect( [(l3inputnode, MergeCNetworks_grp, [('Group_CFFs', 'in_files')])]) l3pipeline.connect([( MergeCNetworks_grp, l3datasink, [('connectome_file', '@l3output')])]) return l3pipeline def create_merge_group_network_results_workflow(group_list, data_dir, subjects_dir, output_dir, title='group'): """Creates a third-level pipeline to merge the Connectome File Format (CFF) outputs from each group and combines them into a single CFF file for each group. This version of the third-level pipeline also concatenates the comma-separated value files for the NetworkX metrics and the connectivity matrices into single files. Example ------- >>> import nipype.workflows.dmri.connectivity.group_connectivity as groupwork >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> l3pipeline = groupwork.create_merge_group_network_results_workflow(group_list, data_dir, subjects_dir, output_dir) >>> l3pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files title: String to use as a title for the output merged CFF file (default 'group') """ l3infosource = pe.Node(interface=util.IdentityInterface( fields=['group_id']), name='l3infosource') l3infosource.inputs.group_id = group_list.keys() l3source = pe.Node(nio.DataGrabber(infields=['group_id'], outfields=['CFFfiles', 'CSVnodemetrics', 'CSVglobalmetrics', 'CSVmatrices']), name='l3source') l3source.inputs.template_args = dict(CFFfiles=[['group_id']], CSVnodemetrics=[['group_id']], CSVglobalmetrics=[['group_id']], CSVmatrices=[['group_id']]) l3source.inputs.template = op.join(output_dir, '%s/%s') l3source.inputs.sort_filelist = True l3source.inputs.field_template = dict( CFFfiles=op.join(output_dir, '%s/*.cff'), CSVnodemetrics=op.join(output_dir, '%s/node_csv/*.csv'), CSVglobalmetrics=op.join(output_dir, '%s/global_csv/*.csv'), CSVmatrices=op.join(output_dir, '%s/cmatrices_csv/*/*.csv')) l3inputnode = pe.Node(interface=util.IdentityInterface(fields=['Group_CFFs', 'Group_CSVnodemetrics', 'Group_CSVglobalmetrics', 'Group_CSVmatrices']), name='l3inputnode') MergeCNetworks_grp = pe.Node(interface=cmtk.MergeCNetworks(), name="MergeCNetworks_grp") MergeCNetworks_grp.inputs.out_file = title l3datasink = pe.Node(interface=nio.DataSink(), name="l3datasink") l3datasink.inputs.base_directory = output_dir l3pipeline = pe.Workflow(name="l3output") l3pipeline.base_dir = output_dir l3pipeline.connect([ (l3infosource, l3source, [('group_id', 'group_id')]), (l3source, l3inputnode, [('CFFfiles', 'Group_CFFs')]), (l3source, l3inputnode, [('CSVnodemetrics', 'Group_CSVnodemetrics')]), (l3source, l3inputnode, [('CSVglobalmetrics', 'Group_CSVglobalmetrics')]), (l3source, l3inputnode, [('CSVmatrices', 'Group_CSVmatrices')]), ]) l3pipeline.connect([(l3inputnode, MergeCNetworks_grp, [('Group_CFFs', 'in_files')])]) l3pipeline.connect([(MergeCNetworks_grp, l3datasink, [('connectome_file', '@l3output')])]) concat_csv_interface = Function(input_names=["in_files"], output_names=["out_name"], function=concatcsv) concat_node_csvs = pe.Node(interface=concat_csv_interface, name='concat_node_csvs') concat_global_csvs = pe.Node(interface=concat_csv_interface, name='concat_global_csvs') concat_matrix_csvs = pe.Node(interface=concat_csv_interface, name='concat_matrix_csvs') l3pipeline.connect([(l3inputnode, concat_node_csvs, [('Group_CSVnodemetrics', 'in_files')])]) l3pipeline.connect([(concat_node_csvs, l3datasink, [('out_name', '@l3output.nodal_csv')])]) l3pipeline.connect([(l3inputnode, concat_global_csvs, [('Group_CSVglobalmetrics', 'in_files')])]) l3pipeline.connect([(concat_global_csvs, l3datasink, [('out_name', '@l3output.global_csv')])]) l3pipeline.connect([(l3inputnode, concat_matrix_csvs, [('Group_CSVmatrices', 'in_files')])]) l3pipeline.connect([(concat_matrix_csvs, l3datasink, [('out_name', '@l3output.csvmatrices')])]) return l3pipeline def create_average_networks_by_group_workflow(group_list, data_dir, subjects_dir, output_dir, title='group_average'): """Creates a fourth-level pipeline to average the networks for two groups and merge them into a single CFF file. This pipeline will also output the average networks in .gexf format, for visualization in other graph viewers, such as Gephi. Example ------- >>> import nipype.workflows.dmri.connectivity.group_connectivity as groupwork >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> l4pipeline = groupwork.create_average_networks_by_group_workflow(group_list, data_dir, subjects_dir, output_dir) >>> l4pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files title: String to use as a title for the output merged CFF file (default 'group') """ l4infosource = pe.Node(interface=util.IdentityInterface(fields=['group_id1', 'group_id2']), name='l4infosource') try: l4infosource.inputs.group_id1 = group_list.keys()[0] l4infosource.inputs.group_id2 = group_list.keys()[1] except IndexError: print 'The create_average_networks_by_group_workflow requires 2 groups' raise Exception l4info = dict(networks=[['group_id', '']], CMatrices=[['group_id', '']], fibmean=[['group_id', 'mean_fiber_length']], fibdev=[['group_id', 'fiber_length_std']]) l4source_grp1 = pe.Node(nio.DataGrabber(infields=['group_id'], outfields=l4info.keys()), name='l4source_grp1') l4source_grp1.inputs.template = '%s/%s' l4source_grp1.inputs.field_template = dict(networks=op.join(output_dir, '%s/networks/*/*%s*intersections*.pck'), CMatrices=op.join(output_dir, '%s/cmatrix/*/*%s*.mat'), fibmean=op.join(output_dir, '%s/mean_fiber_length/*/*%s*.mat'), fibdev=op.join(output_dir, '%s/fiber_length_std/*/*%s*.mat')) l4source_grp1.inputs.base_directory = output_dir l4source_grp1.inputs.template_args = l4info l4source_grp1.inputs.sort_filelist = True l4source_grp2 = l4source_grp1.clone(name='l4source_grp2') l4inputnode = pe.Node(interface=util.IdentityInterface(fields=['networks_grp1', 'networks_grp2', 'CMatrices_grp1', 'CMatrices_grp2', 'fibmean_grp1', 'fibmean_grp2', 'fibdev_grp1', 'fibdev_grp2']), name='l4inputnode') average_networks_grp1 = pe.Node(interface=cmtk.AverageNetworks(), name='average_networks_grp1') average_networks_grp2 = average_networks_grp1.clone('average_networks_grp2') averagecff = pe.Node(interface=cmtk.CFFConverter(), name="averagecff") averagecff.inputs.out_file = title merge_gpickled_averages = pe.Node(interface=util.Merge(2), name='merge_gpickled_averages') merge_gexf_averages = merge_gpickled_averages.clone('merge_gexf_averages') l4datasink = pe.Node(interface=nio.DataSink(), name="l4datasink") l4datasink.inputs.base_directory = output_dir l4pipeline = pe.Workflow(name="l4output") l4pipeline.base_dir = output_dir l4pipeline.connect([ (l4infosource, l4source_grp1, [('group_id1', 'group_id')]), (l4infosource, l4source_grp2, [('group_id2', 'group_id')]), (l4source_grp1, l4inputnode, [('CMatrices', 'CMatrices_grp1')]), (l4source_grp2, l4inputnode, [('CMatrices', 'CMatrices_grp2')]), (l4source_grp1, l4inputnode, [('networks', 'networks_grp1')]), (l4source_grp2, l4inputnode, [('networks', 'networks_grp2')]), (l4source_grp1, l4inputnode, [('fibmean', 'fibmean_grp1')]), (l4source_grp2, l4inputnode, [('fibmean', 'fibmean_grp2')]), (l4source_grp1, l4inputnode, [('fibdev', 'fibdev_grp1')]), (l4source_grp2, l4inputnode, [('fibdev', 'fibdev_grp2')]), ]) l4pipeline.connect([(l4inputnode, average_networks_grp1, [('networks_grp1', 'in_files')])]) l4pipeline.connect([(l4infosource, average_networks_grp1, [('group_id1', 'group_id')])]) l4pipeline.connect([(l4inputnode, average_networks_grp2, [('networks_grp2', 'in_files')])]) l4pipeline.connect([(l4infosource, average_networks_grp2, [('group_id2', 'group_id')])]) l4pipeline.connect([(average_networks_grp1, merge_gpickled_averages, [('gpickled_groupavg', 'in1')])]) l4pipeline.connect([(average_networks_grp2, merge_gpickled_averages, [('gpickled_groupavg', 'in2')])]) l4pipeline.connect([(average_networks_grp1, merge_gexf_averages, [('gexf_groupavg', 'in1')])]) l4pipeline.connect([(average_networks_grp2, merge_gexf_averages, [('gexf_groupavg', 'in2')])]) l4pipeline.connect([(merge_gpickled_averages, l4datasink, [('out', '@l4output.gpickled')])]) l4pipeline.connect([(merge_gpickled_averages, averagecff, [('out', 'gpickled_networks')])]) l4pipeline.connect([(averagecff, l4datasink, [('connectome_file', '@l4output.averagecff')])]) l4pipeline.connect([(merge_gexf_averages, l4datasink, [('out', '@l4output.gexf')])]) return l4pipeline nipype-0.11.0/nipype/workflows/dmri/connectivity/nx.py000066400000000000000000000143461257611314500231230ustar00rootroot00000000000000import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.cmtk as cmtk import nipype.algorithms.misc as misc from .group_connectivity import pullnodeIDs from nipype.algorithms.misc import remove_identical_paths def add_global_to_filename(in_file): from nipype.utils.filemanip import split_filename path, name, ext = split_filename(in_file) return name + '_global' + ext def add_nodal_to_filename(in_file): from nipype.utils.filemanip import split_filename path, name, ext = split_filename(in_file) return name + '_nodal' + ext def create_networkx_pipeline(name="networkx", extra_column_heading="subject"): """Creates a workflow to calculate various graph measures (via NetworkX) on an input network. The output measures are then converted to comma-separated value text files, and an extra column / field is also added. Typically, the user would connect the subject name to this field. Example ------- >>> from nipype.workflows.dmri.connectivity.nx import create_networkx_pipeline >>> nx = create_networkx_pipeline("networkx", "subject_id") >>> nx.inputs.inputnode.extra_field = 'subj1' >>> nx.inputs.inputnode.network_file = 'subj1.pck' >>> nx.run() # doctest: +SKIP Inputs:: inputnode.extra_field inputnode.network_file Outputs:: outputnode.network_files outputnode.csv_files outputnode.matlab_files """ inputnode = pe.Node(interface = util.IdentityInterface(fields=["extra_field", "network_file"]), name="inputnode") pipeline = pe.Workflow(name=name) ntwkMetrics = pe.Node(interface=cmtk.NetworkXMetrics(), name="NetworkXMetrics") Matlab2CSV_node = pe.Node(interface=misc.Matlab2CSV(), name="Matlab2CSV_node") MergeCSVFiles_node = pe.Node(interface=misc.MergeCSVFiles(), name="MergeCSVFiles_node") MergeCSVFiles_node.inputs.extra_column_heading = extra_column_heading Matlab2CSV_global = Matlab2CSV_node.clone(name="Matlab2CSV_global") MergeCSVFiles_global = MergeCSVFiles_node.clone(name="MergeCSVFiles_global") MergeCSVFiles_global.inputs.extra_column_heading = extra_column_heading mergeNetworks = pe.Node(interface=util.Merge(2), name="mergeNetworks") mergeCSVs = mergeNetworks.clone("mergeCSVs") pipeline.connect([(inputnode, ntwkMetrics,[("network_file","in_file")])]) pipeline.connect([(ntwkMetrics, Matlab2CSV_node,[("node_measures_matlab","in_file")])]) pipeline.connect([(ntwkMetrics, Matlab2CSV_global,[("global_measures_matlab","in_file")])]) pipeline.connect([(Matlab2CSV_node, MergeCSVFiles_node,[("csv_files","in_files")])]) pipeline.connect([(inputnode, MergeCSVFiles_node, [(("extra_field", add_nodal_to_filename), "out_file")])]) pipeline.connect([(inputnode, MergeCSVFiles_node,[("extra_field","extra_field")])]) pipeline.connect([(inputnode, MergeCSVFiles_node, [(("network_file", pullnodeIDs), "row_headings")])]) pipeline.connect([(Matlab2CSV_global, MergeCSVFiles_global,[("csv_files","in_files")])]) pipeline.connect([(Matlab2CSV_global, MergeCSVFiles_global, [(("csv_files", remove_identical_paths), "column_headings")])]) #MergeCSVFiles_global.inputs.row_heading_title = 'metric' #MergeCSVFiles_global.inputs.column_headings = ['average'] pipeline.connect([(inputnode, MergeCSVFiles_global, [(("extra_field", add_global_to_filename), "out_file")])]) pipeline.connect([(inputnode, MergeCSVFiles_global,[("extra_field","extra_field")])]) pipeline.connect([(inputnode, mergeNetworks,[("network_file","in1")])]) pipeline.connect([(ntwkMetrics, mergeNetworks,[("gpickled_network_files","in2")])]) outputnode = pe.Node(interface = util.IdentityInterface(fields=["network_files", "csv_files", "matlab_files", "node_csv", "global_csv"]), name="outputnode") pipeline.connect([(MergeCSVFiles_node, outputnode, [("csv_file", "node_csv")])]) pipeline.connect([(MergeCSVFiles_global, outputnode, [("csv_file", "global_csv")])]) pipeline.connect([(MergeCSVFiles_node, mergeCSVs, [("csv_file", "in1")])]) pipeline.connect([(MergeCSVFiles_global, mergeCSVs, [("csv_file", "in2")])]) pipeline.connect([(mergeNetworks, outputnode, [("out", "network_files")])]) pipeline.connect([(mergeCSVs, outputnode, [("out", "csv_files")])]) pipeline.connect([(ntwkMetrics, outputnode,[("matlab_matrix_files", "matlab_files")])]) return pipeline def create_cmats_to_csv_pipeline(name="cmats_to_csv", extra_column_heading="subject"): """Creates a workflow to convert the outputs from CreateMatrix into a single comma-separated value text file. An extra column / field is also added to the text file. Typically, the user would connect the subject name to this field. Example ------- >>> from nipype.workflows.dmri.connectivity.nx import create_cmats_to_csv_pipeline >>> csv = create_cmats_to_csv_pipeline("cmats_to_csv", "subject_id") >>> csv.inputs.inputnode.extra_field = 'subj1' >>> csv.inputs.inputnode.matlab_matrix_files = ['subj1_cmatrix.mat', 'subj1_mean_fiber_length.mat', 'subj1_median_fiber_length.mat', 'subj1_fiber_length_std.mat'] >>> csv.run() # doctest: +SKIP Inputs:: inputnode.extra_field inputnode.matlab_matrix_files Outputs:: outputnode.csv_file """ inputnode = pe.Node(interface = util.IdentityInterface(fields=["extra_field", "matlab_matrix_files"]), name="inputnode") pipeline = pe.Workflow(name=name) Matlab2CSV = pe.MapNode(interface=misc.Matlab2CSV(), name="Matlab2CSV", iterfield=["in_file"]) MergeCSVFiles = pe.Node(interface=misc.MergeCSVFiles(), name="MergeCSVFiles") MergeCSVFiles.inputs.extra_column_heading = extra_column_heading pipeline.connect([(inputnode, Matlab2CSV,[("matlab_matrix_files","in_file")])]) pipeline.connect([(Matlab2CSV, MergeCSVFiles,[("csv_files","in_files")])]) pipeline.connect([(inputnode, MergeCSVFiles,[("extra_field","extra_field")])]) outputnode = pe.Node(interface = util.IdentityInterface(fields=["csv_file"]), name="outputnode") pipeline.connect([(MergeCSVFiles, outputnode, [("csv_file", "csv_file")])]) return pipeline nipype-0.11.0/nipype/workflows/dmri/dipy/000077500000000000000000000000001257611314500203435ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/dipy/__init__.py000066400000000000000000000002501257611314500224510ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: from denoise import nlmeans_pipeline nipype-0.11.0/nipype/workflows/dmri/dipy/denoise.py000066400000000000000000000076221257611314500223520ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu from nipype.interfaces import fsl from nipype.interfaces import dipy def nlmeans_pipeline(name='Denoise', params={'patch_radius': 1, 'block_radius': 5}): """ Workflow that performs nlmeans denoising Example ------- >>> from nipype.workflows.dmri.dipy.denoise import nlmeans_pipeline >>> denoise = nlmeans_pipeline() >>> denoise.inputs.inputnode.in_file = 'diffusion.nii' >>> denoise.inputs.inputnode.in_mask = 'mask.nii' >>> denoise.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_mask']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']), name='outputnode') nmask = pe.Node(niu.Function(input_names=['in_file', 'in_mask'], output_names=['out_file'], function=bg_mask), name='NoiseMsk') nlmeans = pe.Node(dipy.Denoise(**params), name='NLMeans') wf = pe.Workflow(name=name) wf.connect([ (inputnode, nmask, [('in_file', 'in_file'), ('in_mask', 'in_mask')]) ,(inputnode, nlmeans, [('in_file', 'in_file'), ('in_mask', 'in_mask')]) ,(nmask, nlmeans, [('out_file', 'noise_mask')]) ,(nlmeans, outputnode, [('out_file', 'out_file')]) ]) return wf def csf_mask(in_file, in_mask, out_file=None): """ Artesanal mask of csf in T2w-like images """ import nibabel as nb import numpy as np from scipy.ndimage import binary_erosion, binary_opening, label import scipy.ndimage as nd import os.path as op if out_file is None: fname,ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname,ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_csfmask%s" % (fname, ext)) im = nb.load(in_file) hdr = im.get_header().copy() hdr.set_data_dtype(np.uint8) hdr.set_xyzt_units('mm') imdata = im.get_data() msk = nb.load(in_mask).get_data() msk = binary_erosion(msk, structure=np.ones((15, 15, 10))).astype(np.uint8) thres = np.percentile(imdata[msk > 0].reshape(-1), 90.0) imdata[imdata < thres] = 0 imdata = imdata * msk imdata[imdata > 0] = 1 imdata = binary_opening(imdata, structure=np.ones((2, 2, 2))).astype(np.uint8) label_im, nb_labels = label(imdata) sizes = nd.sum(imdata, label_im, range(nb_labels + 1)) mask_size = sizes != sizes.max() remove_pixel = mask_size[label_im] label_im[remove_pixel] = 0 label_im[label_im > 0] = 1 nb.Nifti1Image(label_im.astype(np.uint8), im.get_affine(), hdr).to_filename(out_file) return out_file def bg_mask(in_file, in_mask, out_file=None): """ Rough mask of background from brain masks """ import nibabel as nb import numpy as np from scipy.ndimage import binary_dilation import scipy.ndimage as nd import os.path as op if out_file is None: fname,ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname,ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_bgmask%s" % (fname, ext)) im = nb.load(in_file) hdr = im.get_header().copy() hdr.set_data_dtype(np.uint8) hdr.set_xyzt_units('mm') imdata = im.get_data() msk = nb.load(in_mask).get_data() msk = 1 - binary_dilation(msk, structure=np.ones((20, 20, 20))) nb.Nifti1Image(msk.astype(np.uint8), im.get_affine(), hdr).to_filename(out_file) return out_file nipype-0.11.0/nipype/workflows/dmri/fsl/000077500000000000000000000000001257611314500201625ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/fsl/__init__.py000066400000000000000000000011271257611314500222740ustar00rootroot00000000000000from dti import create_bedpostx_pipeline, bedpostx_parallel from artifacts import (all_fmb_pipeline, all_peb_pipeline, all_fsl_pipeline, hmc_pipeline, ecc_pipeline, sdc_fmb, sdc_peb, remove_bias) from epi import (fieldmap_correction, topup_correction, create_eddy_correct_pipeline, create_epidewarp_pipeline, create_dmri_preprocessing) from tbss import (create_tbss_1_preproc, create_tbss_2_reg, create_tbss_3_postreg, create_tbss_4_prestats, create_tbss_all, create_tbss_non_FA) nipype-0.11.0/nipype/workflows/dmri/fsl/artifacts.py000066400000000000000000001153261257611314500225240ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import nipype.pipeline.engine as pe from nipype.interfaces.io import JSONFileGrabber from nipype.interfaces import utility as niu from nipype.interfaces import freesurfer as fs from nipype.interfaces import ants from nipype.interfaces import fsl from .utils import * def all_fmb_pipeline(name='hmc_sdc_ecc', fugue_params=dict(smooth3d=2.0)): """ Builds a pipeline including three artifact corrections: head-motion correction (HMC), susceptibility-derived distortion correction (SDC), and Eddy currents-derived distortion correction (ECC). The displacement fields from each kind of distortions are combined. Thus, only one interpolation occurs between input data and result. .. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_. Examples -------- >>> from nipype.workflows.dmri.fsl.artifacts import all_fmb_pipeline >>> allcorr = all_fmb_pipeline() >>> allcorr.inputs.inputnode.in_file = 'epi.nii' >>> allcorr.inputs.inputnode.in_bval = 'diffusion.bval' >>> allcorr.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> allcorr.inputs.inputnode.bmap_mag = 'magnitude.nii' >>> allcorr.inputs.inputnode.bmap_pha = 'phase.nii' >>> allcorr.inputs.inputnode.epi_param = 'epi_param.txt' >>> allcorr.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bvec', 'in_bval', 'bmap_pha', 'bmap_mag', 'epi_param']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_mask', 'out_bvec']), name='outputnode') list_b0 = pe.Node(niu.Function( input_names=['in_bval'], output_names=['out_idx'], function=b0_indices), name='B0indices') avg_b0_0 = pe.Node(niu.Function( input_names=['in_file', 'index'], output_names=['out_file'], function=time_avg), name='b0_avg_pre') avg_b0_1 = pe.Node(niu.Function( input_names=['in_file', 'index'], output_names=['out_file'], function=time_avg), name='b0_avg_post') bet_dwi0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_pre') bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_post') hmc = hmc_pipeline() sdc = sdc_fmb(fugue_params=fugue_params) ecc = ecc_pipeline() unwarp = apply_all_corrections() wf = pe.Workflow(name=name) wf.connect([ (inputnode, hmc, [('in_file', 'inputnode.in_file'), ('in_bvec', 'inputnode.in_bvec'), ('in_bval', 'inputnode.in_bval')]), (inputnode, list_b0, [('in_bval', 'in_bval')]), (inputnode, avg_b0_0, [('in_file', 'in_file')]), (list_b0, avg_b0_0, [('out_idx', 'index')]), (avg_b0_0, bet_dwi0, [('out_file', 'in_file')]), (bet_dwi0, hmc, [('mask_file', 'inputnode.in_mask')]), (hmc, sdc, [ ('outputnode.out_file', 'inputnode.in_file')]), (bet_dwi0, sdc, [('mask_file', 'inputnode.in_mask')]), (inputnode, sdc, [('bmap_pha', 'inputnode.bmap_pha'), ('bmap_mag', 'inputnode.bmap_mag'), ('epi_param', 'inputnode.settings')]), (list_b0, sdc, [('out_idx', 'inputnode.in_ref')]), (hmc, ecc, [ ('outputnode.out_xfms', 'inputnode.in_xfms')]), (inputnode, ecc, [('in_file', 'inputnode.in_file'), ('in_bval', 'inputnode.in_bval')]), (bet_dwi0, ecc, [('mask_file', 'inputnode.in_mask')]), (ecc, avg_b0_1, [('outputnode.out_file', 'in_file')]), (list_b0, avg_b0_1, [('out_idx', 'index')]), (avg_b0_1, bet_dwi1, [('out_file', 'in_file')]), (inputnode, unwarp, [('in_file', 'inputnode.in_dwi')]), (hmc, unwarp, [('outputnode.out_xfms', 'inputnode.in_hmc')]), (ecc, unwarp, [('outputnode.out_xfms', 'inputnode.in_ecc')]), (sdc, unwarp, [('outputnode.out_warp', 'inputnode.in_sdc')]), (hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')]), (unwarp, outputnode, [('outputnode.out_file', 'out_file')]), (bet_dwi1, outputnode, [('mask_file', 'out_mask')]) ]) return wf def all_peb_pipeline(name='hmc_sdc_ecc', epi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y-', epi_factor=1), altepi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y', epi_factor=1)): """ Builds a pipeline including three artifact corrections: head-motion correction (HMC), susceptibility-derived distortion correction (SDC), and Eddy currents-derived distortion correction (ECC). .. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_. Examples -------- >>> from nipype.workflows.dmri.fsl.artifacts import all_peb_pipeline >>> allcorr = all_peb_pipeline() >>> allcorr.inputs.inputnode.in_file = 'epi.nii' >>> allcorr.inputs.inputnode.alt_file = 'epi_rev.nii' >>> allcorr.inputs.inputnode.in_bval = 'diffusion.bval' >>> allcorr.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> allcorr.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bvec', 'in_bval', 'alt_file']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_mask', 'out_bvec']), name='outputnode') avg_b0_0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg_pre') avg_b0_1 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg_post') bet_dwi0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_pre') bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_post') hmc = hmc_pipeline() sdc = sdc_peb(epi_params=epi_params, altepi_params=altepi_params) ecc = ecc_pipeline() unwarp = apply_all_corrections() wf = pe.Workflow(name=name) wf.connect([ (inputnode, hmc, [('in_file', 'inputnode.in_file'), ('in_bvec', 'inputnode.in_bvec'), ('in_bval', 'inputnode.in_bval')]), (inputnode, avg_b0_0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (avg_b0_0, bet_dwi0, [('out_file', 'in_file')]), (bet_dwi0, hmc, [('mask_file', 'inputnode.in_mask')]), (hmc, sdc, [ ('outputnode.out_file', 'inputnode.in_file')]), (bet_dwi0, sdc, [('mask_file', 'inputnode.in_mask')]), (inputnode, sdc, [('in_bval', 'inputnode.in_bval'), ('alt_file', 'inputnode.alt_file')]), (inputnode, ecc, [('in_file', 'inputnode.in_file'), ('in_bval', 'inputnode.in_bval')]), (bet_dwi0, ecc, [('mask_file', 'inputnode.in_mask')]), (hmc, ecc, [ ('outputnode.out_xfms', 'inputnode.in_xfms')]), (ecc, avg_b0_1, [('outputnode.out_file', 'in_dwi')]), (inputnode, avg_b0_1, [('in_bval', 'in_bval')]), (avg_b0_1, bet_dwi1, [('out_file', 'in_file')]), (inputnode, unwarp, [('in_file', 'inputnode.in_dwi')]), (hmc, unwarp, [('outputnode.out_xfms', 'inputnode.in_hmc')]), (ecc, unwarp, [('outputnode.out_xfms', 'inputnode.in_ecc')]), (sdc, unwarp, [('outputnode.out_warp', 'inputnode.in_sdc')]), (hmc, outputnode, [('outputnode.out_bvec', 'out_bvec')]), (unwarp, outputnode, [('outputnode.out_file', 'out_file')]), (bet_dwi1, outputnode, [('mask_file', 'out_mask')]) ]) return wf def all_fsl_pipeline(name='fsl_all_correct', epi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y-'), altepi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y')): """ Workflow that integrates FSL ``topup`` and ``eddy``. .. warning:: this workflow rotates the gradients table (*b*-vectors) [Leemans09]_. .. warning:: this workflow does not perform jacobian modulation of each *DWI* [Jones10]_. Examples -------- >>> from nipype.workflows.dmri.fsl.artifacts import all_fsl_pipeline >>> allcorr = all_fsl_pipeline() >>> allcorr.inputs.inputnode.in_file = 'epi.nii' >>> allcorr.inputs.inputnode.alt_file = 'epi_rev.nii' >>> allcorr.inputs.inputnode.in_bval = 'diffusion.bval' >>> allcorr.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> allcorr.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bvec', 'in_bval', 'alt_file']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_mask', 'out_bvec']), name='outputnode') def _gen_index(in_file): import numpy as np import nibabel as nb import os out_file = os.path.abspath('index.txt') vols = nb.load(in_file).get_data().shape[-1] np.savetxt(out_file, np.ones((vols,)).T) return out_file avg_b0_0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg_pre') bet_dwi0 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_pre') sdc = sdc_peb(epi_params=epi_params, altepi_params=altepi_params) ecc = pe.Node(fsl.Eddy(method='jac'), name='fsl_eddy') rot_bvec = pe.Node(niu.Function( input_names=['in_bvec', 'eddy_params'], output_names=['out_file'], function=eddy_rotate_bvecs), name='Rotate_Bvec') avg_b0_1 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg_post') bet_dwi1 = pe.Node(fsl.BET(frac=0.3, mask=True, robust=True), name='bet_dwi_post') wf = pe.Workflow(name=name) wf.connect([ (inputnode, avg_b0_0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (avg_b0_0, bet_dwi0, [('out_file', 'in_file')]), (bet_dwi0, sdc, [('mask_file', 'inputnode.in_mask')]), (inputnode, sdc, [('in_file', 'inputnode.in_file'), ('alt_file', 'inputnode.alt_file'), ('in_bval', 'inputnode.in_bval')]), (sdc, ecc, [('topup.out_enc_file', 'in_acqp'), ('topup.out_fieldcoef', 'in_topup_fieldcoef'), ('topup.out_movpar', 'in_topup_movpar')]), (bet_dwi0, ecc, [('mask_file', 'in_mask')]), (inputnode, ecc, [('in_file', 'in_file'), (('in_file', _gen_index), 'in_index'), ('in_bval', 'in_bval'), ('in_bvec', 'in_bvec')]), (inputnode, rot_bvec, [('in_bvec', 'in_bvec')]), (ecc, rot_bvec, [('out_parameter', 'eddy_params')]), (ecc, avg_b0_1, [('out_corrected', 'in_dwi')]), (inputnode, avg_b0_1, [('in_bval', 'in_bval')]), (avg_b0_1, bet_dwi1, [('out_file', 'in_file')]), (ecc, outputnode, [('out_corrected', 'out_file')]), (rot_bvec, outputnode, [('out_file', 'out_bvec')]), (bet_dwi1, outputnode, [('mask_file', 'out_mask')]) ]) return wf def hmc_pipeline(name='motion_correct'): """ HMC stands for head-motion correction. Creates a pipeline that corrects for head motion artifacts in dMRI sequences. It takes a series of diffusion weighted images and rigidly co-registers them to one reference image. Finally, the `b`-matrix is rotated accordingly [Leemans09]_ making use of the rotation matrix obtained by FLIRT. Search angles have been limited to 4 degrees, based on results in [Yendiki13]_. A list of rigid transformation matrices is provided, so that transforms can be chained. This is useful to correct for artifacts with only one interpolation process (as previously discussed `here `_), and also to compute nuisance regressors as proposed by [Yendiki13]_. .. warning:: This workflow rotates the `b`-vectors, so please be advised that not all the dicom converters ensure the consistency between the resulting nifti orientation and the gradients table (e.g. dcm2nii checks it). .. admonition:: References .. [Leemans09] Leemans A, and Jones DK, `The B-matrix must be rotated when correcting for subject motion in DTI data `_, Magn Reson Med. 61(6):1336-49. 2009. doi: 10.1002/mrm.21890. .. [Yendiki13] Yendiki A et al., `Spurious group differences due to head motion in a diffusion MRI study `_. Neuroimage. 21(88C):79-90. 2013. doi: 10.1016/j.neuroimage.2013.11.027 Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import hmc_pipeline >>> hmc = hmc_pipeline() >>> hmc.inputs.inputnode.in_file = 'diffusion.nii' >>> hmc.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> hmc.inputs.inputnode.in_bval = 'diffusion.bval' >>> hmc.inputs.inputnode.in_mask = 'mask.nii' >>> hmc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range in [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bvec - gradients file (b-vectors) inputnode.ref_num (optional, default=0) index of the b0 volume that \ should be taken as reference Outputs:: outputnode.out_file - corrected dwi file outputnode.out_bvec - rotated gradient vectors table outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict(dof=6, bgvalue=0, save_log=True, no_search=True, # cost='mutualinfo', cost_func='mutualinfo', bins=64, schedule=get_flirt_schedule('hmc')) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'ref_num', 'in_bvec', 'in_bval', 'in_mask']), name='inputnode') split = pe.Node(niu.Function( output_names=['out_ref', 'out_mov', 'out_bval', 'volid'], input_names=['in_file', 'in_bval', 'ref_num'], function=hmc_split), name='SplitDWI') flirt = dwi_flirt(flirt_param=params) insmat = pe.Node(niu.Function(input_names=['inlist', 'volid'], output_names=['out'], function=insert_mat), name='InsertRefmat') rot_bvec = pe.Node(niu.Function( function=rotate_bvecs, input_names=['in_bvec', 'in_matrix'], output_names=['out_file']), name='Rotate_Bvec') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_bvec', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, split, [('in_file', 'in_file'), ('in_bval', 'in_bval'), ('ref_num', 'ref_num')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask')]), (split, flirt, [('out_ref', 'inputnode.reference'), ('out_mov', 'inputnode.in_file'), ('out_bval', 'inputnode.in_bval')]), (flirt, insmat, [('outputnode.out_xfms', 'inlist')]), (split, insmat, [('volid', 'volid')]), (inputnode, rot_bvec, [('in_bvec', 'in_bvec')]), (insmat, rot_bvec, [('out', 'in_matrix')]), (rot_bvec, outputnode, [('out_file', 'out_bvec')]), (flirt, outputnode, [('outputnode.out_file', 'out_file')]), (insmat, outputnode, [('out', 'out_xfms')]) ]) return wf def ecc_pipeline(name='eddy_correct'): """ ECC stands for Eddy currents correction. Creates a pipeline that corrects for artifacts induced by Eddy currents in dMRI sequences. It takes a series of diffusion weighted images and linearly co-registers them to one reference image (the average of all b0s in the dataset). DWIs are also modulated by the determinant of the Jacobian as indicated by [Jones10]_ and [Rohde04]_. A list of rigid transformation matrices can be provided, sourcing from a :func:`.hmc_pipeline` workflow, to initialize registrations in a *motion free* framework. A list of affine transformation matrices is available as output, so that transforms can be chained (discussion `here `_). .. admonition:: References .. [Jones10] Jones DK, `The signal intensity must be modulated by the determinant of the Jacobian when correcting for eddy currents in diffusion MRI `_, Proc. ISMRM 18th Annual Meeting, (2010). .. [Rohde04] Rohde et al., `Comprehensive Approach for Correction of Motion and Distortion in Diffusion-Weighted MRI `_, MRM 51:103-114 (2004). Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import ecc_pipeline >>> ecc = ecc_pipeline() >>> ecc.inputs.inputnode.in_file = 'diffusion.nii' >>> ecc.inputs.inputnode.in_bval = 'diffusion.bval' >>> ecc.inputs.inputnode.in_mask = 'mask.nii' >>> ecc.run() # doctest: +SKIP Inputs:: inputnode.in_file - input dwi file inputnode.in_mask - weights mask of reference image (a file with data \ range sin [0.0, 1.0], indicating the weight of each voxel when computing the \ metric. inputnode.in_bval - b-values table inputnode.in_xfms - list of matrices to initialize registration (from \ head-motion correction) Outputs:: outputnode.out_file - corrected dwi file outputnode.out_xfms - list of transformation matrices """ from nipype.workflows.data import get_flirt_schedule params = dict(dof=12, no_search=True, interp='spline', bgvalue=0, schedule=get_flirt_schedule('ecc')) # cost='normmi', cost_func='normmi', bins=64, inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask', 'in_xfms']), name='inputnode') avg_b0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg') pick_dws = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval', 'b'], output_names=['out_file'], function=extract_bval), name='ExtractDWI') pick_dws.inputs.b = 'diff' flirt = dwi_flirt(flirt_param=params, excl_nodiff=True) mult = pe.MapNode(fsl.BinaryMaths(operation='mul'), name='ModulateDWIs', iterfield=['in_file', 'operand_value']) thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') get_mat = pe.Node(niu.Function( input_names=['in_bval', 'in_xfms'], output_names=['out_files'], function=recompose_xfm), name='GatherMatrices') merge = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval', 'in_corrected'], output_names=['out_file'], function=recompose_dwi), name='MergeDWIs') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, avg_b0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, pick_dws, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, merge, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (inputnode, flirt, [('in_mask', 'inputnode.ref_mask'), ('in_xfms', 'inputnode.in_xfms'), ('in_bval', 'inputnode.in_bval')]), (inputnode, get_mat, [('in_bval', 'in_bval')]), (avg_b0, flirt, [('out_file', 'inputnode.reference')]), (pick_dws, flirt, [('out_file', 'inputnode.in_file')]), (flirt, get_mat, [('outputnode.out_xfms', 'in_xfms')]), (flirt, mult, [(('outputnode.out_xfms', _xfm_jacobian), 'operand_value')]), (flirt, split, [('outputnode.out_file', 'in_file')]), (split, mult, [('out_files', 'in_file')]), (mult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_corrected')]), (get_mat, outputnode, [('out_files', 'out_xfms')]), (merge, outputnode, [('out_file', 'out_file')]) ]) return wf def sdc_fmb(name='fmb_correction', interp='Linear', fugue_params=dict(smooth3d=2.0)): """ SDC stands for susceptibility distortion correction. FMB stands for fieldmap-based. The fieldmap based (FMB) method implements SDC by using a mapping of the B0 field as proposed by [Jezzard95]_. This workflow uses the implementation of FSL (`FUGUE `_). Phase unwrapping is performed using `PRELUDE `_ [Jenkinson03]_. Preparation of the fieldmap is performed reproducing the script in FSL `fsl_prepare_fieldmap `_. Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import sdc_fmb >>> fmb = sdc_fmb() >>> fmb.inputs.inputnode.in_file = 'diffusion.nii' >>> fmb.inputs.inputnode.in_ref = range(0, 30, 6) >>> fmb.inputs.inputnode.in_mask = 'mask.nii' >>> fmb.inputs.inputnode.bmap_mag = 'magnitude.nii' >>> fmb.inputs.inputnode.bmap_pha = 'phase.nii' >>> fmb.inputs.inputnode.settings = 'epi_param.txt' >>> fmb.run() # doctest: +SKIP .. warning:: Only SIEMENS format fieldmaps are supported. .. admonition:: References .. [Jezzard95] Jezzard P, and Balaban RS, `Correction for geometric distortion in echo planar images from B0 field variations `_, MRM 34(1):65-73. (1995). doi: 10.1002/mrm.1910340111. .. [Jenkinson03] Jenkinson M., `Fast, automated, N-dimensional phase-unwrapping algorithm `_, MRM 49(1):193-197, 2003, doi: 10.1002/mrm.10354. """ epi_defaults = {'delta_te': 2.46e-3, 'echospacing': 0.77e-3, 'acc_factor': 2, 'enc_dir': u'AP'} inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_ref', 'in_mask', 'bmap_pha', 'bmap_mag', 'settings']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_vsm', 'out_warp']), name='outputnode') r_params = pe.Node(JSONFileGrabber(defaults=epi_defaults), name='SettingsGrabber') eff_echo = pe.Node(niu.Function(function=_eff_t_echo, input_names=['echospacing', 'acc_factor'], output_names=['eff_echo']), name='EffEcho') firstmag = pe.Node(fsl.ExtractROI(t_min=0, t_size=1), name='GetFirst') n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='Bias') bet = pe.Node(fsl.BET(frac=0.4, mask=True), name='BrainExtraction') dilate = pe.Node(fsl.maths.MathsCommand( nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') pha2rads = pe.Node(niu.Function( input_names=['in_file'], output_names=['out_file'], function=siemens2rads), name='PreparePhase') prelude = pe.Node(fsl.PRELUDE(process3d=True), name='PhaseUnwrap') rad2rsec = pe.Node(niu.Function( input_names=['in_file', 'delta_te'], output_names=['out_file'], function=rads2radsec), name='ToRadSec') baseline = pe.Node(niu.Function( input_names=['in_file', 'index'], output_names=['out_file'], function=time_avg), name='Baseline') fmm2b0 = pe.Node(ants.Registration(output_warped_image=True), name="FMm_to_B0") fmm2b0.inputs.transforms = ['Rigid'] * 2 fmm2b0.inputs.transform_parameters = [(1.0,)] * 2 fmm2b0.inputs.number_of_iterations = [[50], [20]] fmm2b0.inputs.dimension = 3 fmm2b0.inputs.metric = ['Mattes', 'Mattes'] fmm2b0.inputs.metric_weight = [1.0] * 2 fmm2b0.inputs.radius_or_number_of_bins = [64, 64] fmm2b0.inputs.sampling_strategy = ['Regular', 'Random'] fmm2b0.inputs.sampling_percentage = [None, 0.2] fmm2b0.inputs.convergence_threshold = [1.e-5, 1.e-8] fmm2b0.inputs.convergence_window_size = [20, 10] fmm2b0.inputs.smoothing_sigmas = [[6.0], [2.0]] fmm2b0.inputs.sigma_units = ['vox'] * 2 fmm2b0.inputs.shrink_factors = [[6], [1]] # ,[1] ] fmm2b0.inputs.use_estimate_learning_rate_once = [True] * 2 fmm2b0.inputs.use_histogram_matching = [True] * 2 fmm2b0.inputs.initial_moving_transform_com = 0 fmm2b0.inputs.collapse_output_transforms = True fmm2b0.inputs.winsorize_upper_quantile = 0.995 applyxfm = pe.Node(ants.ApplyTransforms( dimension=3, interpolation=interp), name='FMp_to_B0') pre_fugue = pe.Node(fsl.FUGUE(save_fmap=True), name='PreliminaryFugue') demean = pe.Node(niu.Function( input_names=['in_file', 'in_mask'], output_names=['out_file'], function=demean_image), name='DemeanFmap') cleanup = cleanup_edge_pipeline() addvol = pe.Node(niu.Function( input_names=['in_file'], output_names=['out_file'], function=add_empty_vol), name='AddEmptyVol') vsm = pe.Node(fsl.FUGUE(save_shift=True, **fugue_params), name="ComputeVSM") split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs') unwarp = pe.MapNode(fsl.FUGUE(icorr=True, forward_warping=False), iterfield=['in_file'], name='UnwarpDWIs') thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') vsm2dfm = vsm2warp() vsm2dfm.inputs.inputnode.scaling = 1.0 wf = pe.Workflow(name=name) wf.connect([ (inputnode, r_params, [('settings', 'in_file')]), (r_params, eff_echo, [('echospacing', 'echospacing'), ('acc_factor', 'acc_factor')]), (inputnode, pha2rads, [('bmap_pha', 'in_file')]), (inputnode, firstmag, [('bmap_mag', 'in_file')]), (inputnode, baseline, [('in_file', 'in_file'), ('in_ref', 'index')]), (firstmag, n4, [('roi_file', 'input_image')]), (n4, bet, [('output_image', 'in_file')]), (bet, dilate, [('mask_file', 'in_file')]), (pha2rads, prelude, [('out_file', 'phase_file')]), (n4, prelude, [('output_image', 'magnitude_file')]), (dilate, prelude, [('out_file', 'mask_file')]), (r_params, rad2rsec, [('delta_te', 'delta_te')]), (prelude, rad2rsec, [('unwrapped_phase_file', 'in_file')]), (baseline, fmm2b0, [('out_file', 'fixed_image')]), (n4, fmm2b0, [('output_image', 'moving_image')]), (inputnode, fmm2b0, [('in_mask', 'fixed_image_mask')]), (dilate, fmm2b0, [('out_file', 'moving_image_mask')]), (baseline, applyxfm, [('out_file', 'reference_image')]), (rad2rsec, applyxfm, [('out_file', 'input_image')]), (fmm2b0, applyxfm, [ ('forward_transforms', 'transforms'), ('forward_invert_flags', 'invert_transform_flags')]), (applyxfm, pre_fugue, [('output_image', 'fmap_in_file')]), (inputnode, pre_fugue, [('in_mask', 'mask_file')]), (pre_fugue, demean, [('fmap_out_file', 'in_file')]), (inputnode, demean, [('in_mask', 'in_mask')]), (demean, cleanup, [('out_file', 'inputnode.in_file')]), (inputnode, cleanup, [('in_mask', 'inputnode.in_mask')]), (cleanup, addvol, [('outputnode.out_file', 'in_file')]), (inputnode, vsm, [('in_mask', 'mask_file')]), (addvol, vsm, [('out_file', 'fmap_in_file')]), (r_params, vsm, [('delta_te', 'asym_se_time')]), (eff_echo, vsm, [('eff_echo', 'dwell_time')]), (inputnode, split, [('in_file', 'in_file')]), (split, unwarp, [('out_files', 'in_file')]), (vsm, unwarp, [('shift_out_file', 'shift_in_file')]), (r_params, unwarp, [ (('enc_dir', _fix_enc_dir), 'unwarp_direction')]), (unwarp, thres, [('unwarped_file', 'in_file')]), (thres, merge, [('out_file', 'in_files')]), (r_params, vsm2dfm, [ (('enc_dir', _fix_enc_dir), 'inputnode.enc_dir')]), (merge, vsm2dfm, [('merged_file', 'inputnode.in_ref')]), (vsm, vsm2dfm, [('shift_out_file', 'inputnode.in_vsm')]), (merge, outputnode, [('merged_file', 'out_file')]), (vsm, outputnode, [('shift_out_file', 'out_vsm')]), (vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')]) ]) return wf def sdc_peb(name='peb_correction', epi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y-', epi_factor=1), altepi_params=dict(echospacing=0.77e-3, acc_factor=3, enc_dir='y', epi_factor=1)): """ SDC stands for susceptibility distortion correction. PEB stands for phase-encoding-based. The phase-encoding-based (PEB) method implements SDC by acquiring diffusion images with two different enconding directions [Andersson2003]_. The most typical case is acquiring with opposed phase-gradient blips (e.g. *A>>>P* and *P>>>A*, or equivalently, *-y* and *y*) as in [Chiou2000]_, but it is also possible to use orthogonal configurations [Cordes2000]_ (e.g. *A>>>P* and *L>>>R*, or equivalently *-y* and *x*). This workflow uses the implementation of FSL (`TOPUP `_). Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import sdc_peb >>> peb = sdc_peb() >>> peb.inputs.inputnode.in_file = 'epi.nii' >>> peb.inputs.inputnode.alt_file = 'epi_rev.nii' >>> peb.inputs.inputnode.in_bval = 'diffusion.bval' >>> peb.inputs.inputnode.in_mask = 'mask.nii' >>> peb.run() # doctest: +SKIP .. admonition:: References .. [Andersson2003] Andersson JL et al., `How to correct susceptibility distortions in spin-echo echo-planar images: application to diffusion tensor imaging `_. Neuroimage. 2003 Oct;20(2):870-88. doi: 10.1016/S1053-8119(03)00336-7 .. [Cordes2000] Cordes D et al., Geometric distortion correction in EPI using two images with orthogonal phase-encoding directions, in Proc. ISMRM (8), p.1712, Denver, US, 2000. .. [Chiou2000] Chiou JY, and Nalcioglu O, A simple method to correct off-resonance related distortion in echo planar imaging, in Proc. ISMRM (8), p.1712, Denver, US, 2000. """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask', 'alt_file', 'ref_num']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['out_file', 'out_vsm', 'out_warp']), name='outputnode') b0_ref = pe.Node(fsl.ExtractROI(t_size=1), name='b0_ref') b0_alt = pe.Node(fsl.ExtractROI(t_size=1), name='b0_alt') b0_comb = pe.Node(niu.Merge(2), name='b0_list') b0_merge = pe.Node(fsl.Merge(dimension='t'), name='b0_merged') topup = pe.Node(fsl.TOPUP(), name='topup') topup.inputs.encoding_direction = [epi_params['enc_dir'], altepi_params['enc_dir']] readout = compute_readout(epi_params) topup.inputs.readout_times = [readout, compute_readout(altepi_params)] unwarp = pe.Node(fsl.ApplyTOPUP(in_index=[1], method='jac'), name='unwarp') # scaling = pe.Node(niu.Function(input_names=['in_file', 'enc_dir'], # output_names=['factor'], function=_get_zoom), # name='GetZoom') # scaling.inputs.enc_dir = epi_params['enc_dir'] vsm2dfm = vsm2warp() vsm2dfm.inputs.inputnode.enc_dir = epi_params['enc_dir'] vsm2dfm.inputs.inputnode.scaling = readout wf = pe.Workflow(name=name) wf.connect([ (inputnode, b0_ref, [('in_file', 'in_file'), (('ref_num', _checkrnum), 't_min')]), (inputnode, b0_alt, [('alt_file', 'in_file'), (('ref_num', _checkrnum), 't_min')]), (b0_ref, b0_comb, [('roi_file', 'in1')]), (b0_alt, b0_comb, [('roi_file', 'in2')]), (b0_comb, b0_merge, [('out', 'in_files')]), (b0_merge, topup, [('merged_file', 'in_file')]), (topup, unwarp, [('out_fieldcoef', 'in_topup_fieldcoef'), ('out_movpar', 'in_topup_movpar'), ('out_enc_file', 'encoding_file')]), (inputnode, unwarp, [('in_file', 'in_files')]), (unwarp, outputnode, [('out_corrected', 'out_file')]), # (b0_ref, scaling, [('roi_file', 'in_file')]), # (scaling, vsm2dfm, [('factor', 'inputnode.scaling')]), (b0_ref, vsm2dfm, [('roi_file', 'inputnode.in_ref')]), (topup, vsm2dfm, [('out_field', 'inputnode.in_vsm')]), (topup, outputnode, [('out_field', 'out_vsm')]), (vsm2dfm, outputnode, [('outputnode.out_warp', 'out_warp')]) ]) return wf def remove_bias(name='bias_correct'): """ This workflow estimates a single multiplicative bias field from the averaged *b0* image, as suggested in [Jeurissen2014]_. .. admonition:: References .. [Jeurissen2014] Jeurissen B. et al., `Multi-tissue constrained spherical deconvolution for improved analysis of multi-shell diffusion MRI data `_. NeuroImage (2014). doi: 10.1016/j.neuroimage.2014.07.061 Example ------- >>> from nipype.workflows.dmri.fsl.artifacts import remove_bias >>> bias = remove_bias() >>> bias.inputs.inputnode.in_file = 'epi.nii' >>> bias.inputs.inputnode.in_bval = 'diffusion.bval' >>> bias.inputs.inputnode.in_mask = 'mask.nii' >>> bias.run() # doctest: +SKIP """ inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bval', 'in_mask']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']), name='outputnode') avg_b0 = pe.Node(niu.Function( input_names=['in_dwi', 'in_bval'], output_names=['out_file'], function=b0_average), name='b0_avg') n4 = pe.Node(ants.N4BiasFieldCorrection( dimension=3, save_bias=True, bspline_fitting_distance=600), name='Bias_b0') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') mult = pe.MapNode(fsl.MultiImageMaths(op_string='-div %s'), iterfield=['in_file'], name='RemoveBiasOfDWIs') thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') merge = pe.Node(fsl.utils.Merge(dimension='t'), name='MergeDWIs') wf = pe.Workflow(name=name) wf.connect([ (inputnode, avg_b0, [('in_file', 'in_dwi'), ('in_bval', 'in_bval')]), (avg_b0, n4, [('out_file', 'input_image')]), (inputnode, n4, [('in_mask', 'mask_image')]), (inputnode, split, [('in_file', 'in_file')]), (n4, mult, [('bias_image', 'operand_files')]), (split, mult, [('out_files', 'in_file')]), (mult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_files')]), (merge, outputnode, [('merged_file', 'out_file')]) ]) return wf def _eff_t_echo(echospacing, acc_factor): eff_echo = echospacing / (1.0 * acc_factor) return eff_echo def _fix_enc_dir(enc_dir): enc_dir = enc_dir.lower() if enc_dir == 'lr': return 'x-' if enc_dir == 'rl': return 'x' if enc_dir == 'ap': return 'y-' if enc_dir == 'pa': return 'y' return enc_dir def _checkrnum(ref_num): from nipype.interfaces.base import isdefined if (ref_num is None) or not isdefined(ref_num): return 0 return ref_num def _nonb0(in_bval): import numpy as np bvals = np.loadtxt(in_bval) return np.where(bvals != 0)[0].tolist() def _xfm_jacobian(in_xfm): import numpy as np from math import fabs return [fabs(np.linalg.det(np.loadtxt(xfm))) for xfm in in_xfm] def _get_zoom(in_file, enc_dir): import nibabel as nb zooms = nb.load(in_file).get_header().get_zooms() if 'y' in enc_dir: return zooms[1] elif 'x' in enc_dir: return zooms[0] elif 'z' in enc_dir: return zooms[2] else: raise ValueError('Wrong encoding direction string') nipype-0.11.0/nipype/workflows/dmri/fsl/dti.py000066400000000000000000000234731257611314500213250ustar00rootroot00000000000000# coding: utf-8 import nipype.pipeline.engine as pe from nipype.interfaces import utility as niu from nipype.interfaces import fsl from nipype.algorithms import misc import os #backwards compatibility from epi import create_eddy_correct_pipeline def transpose(samples_over_fibres): import numpy as np a = np.array(samples_over_fibres) return np.squeeze(a.T).tolist() def create_bedpostx_pipeline(name='bedpostx', params={'n_fibres':2, 'fudge':1, 'burn_in':1000, 'n_jumps':1250, 'sample_every':25, 'model':1, 'cnlinear':True}): """ Creates a pipeline that does the same as bedpostx script from FSL - calculates diffusion model parameters (distributions not MLE) voxelwise for the whole volume (by splitting it slicewise). Example ------- >>> from nipype.workflows.dmri.fsl.dti import create_bedpostx_pipeline >>> params = dict(n_fibres = 2, fudge = 1, burn_in = 1000, ... n_jumps = 1250, sample_every = 25) >>> bpwf = create_bedpostx_pipeline('nipype_bedpostx', params) >>> bpwf.inputs.inputnode.dwi = 'diffusion.nii' >>> bpwf.inputs.inputnode.mask = 'mask.nii' >>> bpwf.inputs.inputnode.bvecs = 'bvecs' >>> bpwf.inputs.inputnode.bvals = 'bvals' >>> bpwf.run() # doctest: +SKIP Inputs:: inputnode.dwi inputnode.mask inputnode.bvecs inputnode.bvals Outputs:: outputnode wraps all XFibres outputs """ inputnode = pe.Node(niu.IdentityInterface(fields=['dwi', 'mask', 'bvecs', 'bvals']), name='inputnode') slice_dwi = pe.Node(fsl.Split(dimension='z'), name='slice_dwi') slice_msk = pe.Node(fsl.Split(dimension='z'), name='slice_msk') mask_dwi = pe.MapNode(fsl.ImageMaths(op_string='-mas'), iterfield=['in_file', 'in_file2'], name='mask_dwi') xfib_if = fsl.XFibres(**params) xfibres = pe.MapNode(xfib_if, name='xfibres', iterfield=['dwi', 'mask']) make_dyads = pe.MapNode(fsl.MakeDyadicVectors(), name="make_dyads", iterfield=['theta_vol', 'phi_vol']) out_fields = ['dyads', 'dyads_disp', 'thsamples', 'phsamples', 'fsamples', 'mean_thsamples', 'mean_phsamples', 'mean_fsamples'] outputnode = pe.Node(niu.IdentityInterface(fields=out_fields), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, slice_dwi, [('dwi', 'in_file')]), (inputnode, slice_msk, [('mask', 'in_file')]), (slice_dwi, mask_dwi, [('out_files', 'in_file')]), (slice_msk, mask_dwi, [('out_files', 'in_file2')]), (slice_dwi, xfibres, [('out_files', 'dwi')]), (mask_dwi, xfibres, [('out_file', 'mask')]), (inputnode, xfibres, [('bvecs', 'bvecs'), ('bvals', 'bvals')]), (inputnode, make_dyads, [('mask', 'mask')]) ]) mms = {} for k in ['thsamples', 'phsamples', 'fsamples']: mms[k] = merge_and_mean(k) wf.connect([ (xfibres, mms[k], [(k, 'inputnode.in_files')]), (mms[k], outputnode, [('outputnode.merged', k), ('outputnode.mean', 'mean_%s' % k)]) ]) # m_mdsamples = pe.Node(fsl.Merge(dimension="z"), # name="merge_mean_dsamples") wf.connect([ (mms['thsamples'], make_dyads, [('outputnode.merged', 'theta_vol')]), (mms['phsamples'], make_dyads, [('outputnode.merged', 'phi_vol')]), #(xfibres, m_mdsamples, [('mean_dsamples', 'in_files')]), (make_dyads, outputnode, [('dyads', 'dyads'), ('dispersion', 'dyads_disp')]) ]) return wf def merge_and_mean(name='mm'): inputnode = pe.Node(niu.IdentityInterface(fields=['in_files']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['merged', 'mean']), name='outputnode') merge = pe.MapNode(fsl.Merge(dimension='z'), name='Merge', iterfield=['in_files']) mean = pe.MapNode(fsl.ImageMaths(op_string='-Tmean'), name='Mean', iterfield=['in_file']) wf = pe.Workflow(name=name) wf.connect([ (inputnode, merge, [(('in_files', transpose), 'in_files')]), (merge, mean, [('merged_file', 'in_file')]), (merge, outputnode, [('merged_file', 'merged')]), (mean, outputnode, [('out_file', 'mean')]) ]) return wf def bedpostx_parallel(name='bedpostx_parallel', compute_all_outputs=True, params={'n_fibres':2, 'fudge':1, 'burn_in':1000, 'n_jumps':1250, 'sample_every':25, 'model':1, 'cnlinear':True}): """ Does the same as :func:`.create_bedpostx_pipeline` by splitting the input dMRI in small ROIs that are better suited for parallel processing). Example ------- >>> from nipype.workflows.dmri.fsl.dti import bedpostx_parallel >>> params = dict(n_fibres = 2, fudge = 1, burn_in = 1000, ... n_jumps = 1250, sample_every = 25) >>> bpwf = bedpostx_parallel('nipype_bedpostx_parallel', params) >>> bpwf.inputs.inputnode.dwi = 'diffusion.nii' >>> bpwf.inputs.inputnode.mask = 'mask.nii' >>> bpwf.inputs.inputnode.bvecs = 'bvecs' >>> bpwf.inputs.inputnode.bvals = 'bvals' >>> bpwf.run(plugin='CondorDAGMan') # doctest: +SKIP Inputs:: inputnode.dwi inputnode.mask inputnode.bvecs inputnode.bvals Outputs:: outputnode wraps all XFibres outputs """ inputnode = pe.Node(niu.IdentityInterface(fields=['dwi', 'mask', 'bvecs', 'bvals']), name='inputnode') slice_dwi = pe.Node(misc.SplitROIs(roi_size=(5, 5, 1)), name='slice_dwi') if params is not None: xfib_if = fsl.XFibres5(**params) else: xfib_if = fsl.XFibres5() xfibres = pe.MapNode(xfib_if, name='xfibres', iterfield=['dwi', 'mask']) mrg_dyads = pe.MapNode(misc.MergeROIs(), name='Merge_dyads', iterfield=['in_files']) mrg_fsamp = pe.MapNode(misc.MergeROIs(), name='Merge_mean_fsamples', iterfield=['in_files']) out_fields = ['dyads', 'fsamples'] if compute_all_outputs: out_fields += ['dyads_disp', 'thsamples', 'phsamples', 'mean_fsamples', 'mean_thsamples', 'mean_phsamples', 'merged_fsamples', 'merged_thsamples', 'merged_phsamples'] outputnode = pe.Node(niu.IdentityInterface(fields=out_fields), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, slice_dwi, [('dwi', 'in_file'), ('mask', 'in_mask')]), (slice_dwi, xfibres, [('out_files', 'dwi'), ('out_masks', 'mask')]), (inputnode, xfibres, [('bvecs', 'bvecs'), ('bvals', 'bvals')]), (inputnode, mrg_dyads, [('mask', 'in_reference')]), (xfibres, mrg_dyads, [(('dyads', transpose), 'in_files')]), (slice_dwi, mrg_dyads, [('out_index', 'in_index')]), (inputnode, mrg_fsamp, [('mask', 'in_reference')]), (xfibres, mrg_fsamp, [(('mean_fsamples', transpose), 'in_files')]), (slice_dwi, mrg_fsamp, [('out_index', 'in_index')]), (mrg_dyads, outputnode, [('merged_file', 'dyads')]), (mrg_fsamp, outputnode, [('merged_file', 'fsamples')]) ]) if compute_all_outputs: make_dyads = pe.MapNode(fsl.MakeDyadicVectors(), name="Make_dyads", iterfield=['theta_vol', 'phi_vol']) wf.connect([(inputnode, make_dyads, [('mask', 'mask')])]) mms = {} for k in ['thsamples', 'phsamples', 'fsamples']: mms[k] = merge_and_mean_parallel(k) wf.connect([ (slice_dwi, mms[k], [('out_index', 'inputnode.in_index')]), (inputnode, mms[k], [('mask', 'inputnode.in_reference')]), (xfibres, mms[k], [(k, 'inputnode.in_files')]), (mms[k], outputnode, [('outputnode.merged', 'merged_%s' % k), ('outputnode.mean', 'mean_%s' % k)]) ]) # m_mdsamples = pe.Node(fsl.Merge(dimension="z"), # name="merge_mean_dsamples") wf.connect([ (mms['thsamples'], make_dyads, [('outputnode.merged', 'theta_vol')]), (mms['phsamples'], make_dyads, [('outputnode.merged', 'phi_vol')]), #(xfibres, m_mdsamples, [('mean_dsamples', 'in_files')]), (make_dyads, outputnode, [('dispersion', 'dyads_disp')]) ]) return wf def merge_and_mean_parallel(name='mm'): inputnode = pe.Node(niu.IdentityInterface(fields=['in_files', 'in_reference', 'in_index']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['merged', 'mean']), name='outputnode') merge = pe.MapNode(misc.MergeROIs(), name='Merge', iterfield=['in_files']) mean = pe.MapNode(fsl.ImageMaths(op_string='-Tmean'), name='Mean', iterfield=['in_file']) wf = pe.Workflow(name=name) wf.connect([ (inputnode, merge, [(('in_files', transpose), 'in_files'), ('in_reference', 'in_reference'), ('in_index', 'in_index')]), (merge, mean, [('merged_file', 'in_file')]), (merge, outputnode, [('merged_file', 'merged')]), (mean, outputnode, [('out_file', 'mean')]) ]) return wf nipype-0.11.0/nipype/workflows/dmri/fsl/epi.py000066400000000000000000001070751257611314500213230ustar00rootroot00000000000000# coding: utf-8 import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu import nipype.interfaces.fsl as fsl import os import warnings def create_dmri_preprocessing(name='dMRI_preprocessing', use_fieldmap=True, fieldmap_registration=False): """ Creates a workflow that chains the necessary pipelines to correct for motion, eddy currents, and, if selected, susceptibility artifacts in EPI dMRI sequences. .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.all_fmb_pipeline` or :func:`nipype.workflows.dmri.preprocess.epi.all_peb_pipeline` instead. .. warning:: This workflow rotates the b-vectors, so please be advised that not all the dicom converters ensure the consistency between the resulting nifti orientation and the b matrix table (e.g. dcm2nii checks it). Example ------- >>> nipype_dmri_preprocess = create_dmri_preprocessing('nipype_dmri_prep') >>> nipype_dmri_preprocess.inputs.inputnode.in_file = 'diffusion.nii' >>> nipype_dmri_preprocess.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> nipype_dmri_preprocess.inputs.inputnode.ref_num = 0 >>> nipype_dmri_preprocess.inputs.inputnode.fieldmap_mag = 'magnitude.nii' >>> nipype_dmri_preprocess.inputs.inputnode.fieldmap_pha = 'phase.nii' >>> nipype_dmri_preprocess.inputs.inputnode.te_diff = 2.46 >>> nipype_dmri_preprocess.inputs.inputnode.epi_echospacing = 0.77 >>> nipype_dmri_preprocess.inputs.inputnode.epi_rev_encoding = False >>> nipype_dmri_preprocess.inputs.inputnode.pi_accel_factor = True >>> nipype_dmri_preprocess.run() # doctest: +SKIP Inputs:: inputnode.in_file - The diffusion data inputnode.in_bvec - The b-matrix file, in FSL format and consistent with the in_file orientation inputnode.ref_num - The reference volume (a b=0 volume in dMRI) inputnode.fieldmap_mag - The magnitude of the fieldmap inputnode.fieldmap_pha - The phase difference of the fieldmap inputnode.te_diff - TE increment used (in msec.) on the fieldmap acquisition (generally 2.46ms for 3T scanners) inputnode.epi_echospacing - The EPI EchoSpacing parameter (in msec.) inputnode.epi_rev_encoding - True if reverse encoding was used (generally False) inputnode.pi_accel_factor - Parallel imaging factor (aka GRAPPA acceleration factor) inputnode.vsm_sigma - Sigma (in mm.) of the gaussian kernel used for in-slice smoothing of the deformation field (voxel shift map, vsm) Outputs:: outputnode.dmri_corrected outputnode.bvec_rotated Optional arguments:: use_fieldmap - True if there are fieldmap files that should be used (default True) fieldmap_registration - True if registration to fieldmap should be performed (default False) """ warnings.warn(('This workflow is deprecated from v.1.0.0, use of available ' 'nipype.workflows.dmri.preprocess.epi.all_*'), DeprecationWarning) pipeline = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_bvec', 'ref_num', 'fieldmap_mag', 'fieldmap_pha', 'te_diff', 'epi_echospacing', 'epi_rev_encoding', 'pi_accel_factor', 'vsm_sigma']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface( fields=['dmri_corrected', 'bvec_rotated']), name='outputnode') motion = create_motion_correct_pipeline() eddy = create_eddy_correct_pipeline() if use_fieldmap: # we have a fieldmap, so lets use it (yay!) susceptibility = create_epidewarp_pipeline( fieldmap_registration=fieldmap_registration) pipeline.connect([ (inputnode, motion, [('in_file', 'inputnode.in_file'), ('in_bvec', 'inputnode.in_bvec'), ('ref_num', 'inputnode.ref_num')]), (inputnode, eddy, [('ref_num', 'inputnode.ref_num')]), (motion, eddy, [('outputnode.motion_corrected', 'inputnode.in_file')]), (eddy, susceptibility, [('outputnode.eddy_corrected', 'inputnode.in_file')]), (inputnode, susceptibility, [('ref_num', 'inputnode.ref_num'), ('fieldmap_mag', 'inputnode.fieldmap_mag'), ('fieldmap_pha', 'inputnode.fieldmap_pha'), ('te_diff', 'inputnode.te_diff'), ('epi_echospacing', 'inputnode.epi_echospacing'), ('epi_rev_encoding', 'inputnode.epi_rev_encoding'), ('pi_accel_factor', 'inputnode.pi_accel_factor'), ('vsm_sigma', 'inputnode.vsm_sigma')]), (motion, outputnode, [('outputnode.out_bvec', 'bvec_rotated')]), (susceptibility, outputnode, [('outputnode.epi_corrected', 'dmri_corrected')]) ]) else: # we don't have a fieldmap, so we just carry on without it :( pipeline.connect([ (inputnode, motion, [('in_file', 'inputnode.in_file'), ('in_bvec', 'inputnode.in_bvec'), ('ref_num', 'inputnode.ref_num')]), (inputnode, eddy, [('ref_num', 'inputnode.ref_num')]), (motion, eddy, [('outputnode.motion_corrected', 'inputnode.in_file')]), (motion, outputnode, [('outputnode.out_bvec', 'bvec_rotated')]), (eddy, outputnode, [('outputnode.eddy_corrected', 'dmri_corrected')]) ]) return pipeline def create_motion_correct_pipeline(name='motion_correct'): """Creates a pipeline that corrects for motion artifact in dMRI sequences. It takes a series of diffusion weighted images and rigidly co-registers them to one reference image. Finally, the b-matrix is rotated accordingly (Leemans et al. 2009 - http://www.ncbi.nlm.nih.gov/pubmed/19319973), making use of the rotation matrix obtained by FLIRT. .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.hmc_pipeline` instead. .. warning:: This workflow rotates the b-vectors, so please be adviced that not all the dicom converters ensure the consistency between the resulting nifti orientation and the b matrix table (e.g. dcm2nii checks it). Example ------- >>> nipype_motioncorrect = create_motion_correct_pipeline('nipype_motioncorrect') >>> nipype_motioncorrect.inputs.inputnode.in_file = 'diffusion.nii' >>> nipype_motioncorrect.inputs.inputnode.in_bvec = 'diffusion.bvec' >>> nipype_motioncorrect.inputs.inputnode.ref_num = 0 >>> nipype_motioncorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file inputnode.ref_num inputnode.in_bvec Outputs:: outputnode.motion_corrected outputnode.out_bvec """ warnings.warn(('This workflow is deprecated from v.1.0.0, use ' 'nipype.workflows.dmri.preprocess.epi.hmc_pipeline instead'), DeprecationWarning) inputnode = pe.Node( niu.IdentityInterface( fields=['in_file', 'ref_num', 'in_bvec']), name='inputnode') pipeline = pe.Workflow(name=name) split = pe.Node(fsl.Split(dimension='t'), name='split') pick_ref = pe.Node(niu.Select(), name='pick_ref') coregistration = pe.MapNode(fsl.FLIRT(no_search=True, interp='spline', padding_size=1, dof=6), name='coregistration', iterfield=['in_file']) rotate_bvecs = pe.Node(niu.Function(input_names=['in_bvec', 'in_matrix'], output_names=[ 'out_file'], function=_rotate_bvecs), name='rotate_b_matrix') merge = pe.Node(fsl.Merge(dimension='t'), name='merge') outputnode = pe.Node( niu.IdentityInterface( fields=['motion_corrected', 'out_bvec']), name='outputnode') pipeline.connect([ (inputnode, split, [('in_file', 'in_file')]) ,(split, pick_ref, [('out_files', 'inlist')]) ,(inputnode, pick_ref, [('ref_num', 'index')]) ,(split, coregistration, [('out_files', 'in_file')]) ,(inputnode, rotate_bvecs, [('in_bvec', 'in_bvec')]) ,(coregistration, rotate_bvecs, [('out_matrix_file', 'in_matrix')]) ,(pick_ref, coregistration, [('out', 'reference')]) ,(coregistration, merge, [('out_file', 'in_files')]) ,(merge, outputnode, [('merged_file', 'motion_corrected')]) ,(rotate_bvecs, outputnode, [('out_file', 'out_bvec')]) ]) return pipeline def create_eddy_correct_pipeline(name='eddy_correct'): """ .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.ecc_pipeline` instead. Creates a pipeline that replaces eddy_correct script in FSL. It takes a series of diffusion weighted images and linearly co-registers them to one reference image. No rotation of the B-matrix is performed, so this pipeline should be executed after the motion correction pipeline. Example ------- >>> nipype_eddycorrect = create_eddy_correct_pipeline('nipype_eddycorrect') >>> nipype_eddycorrect.inputs.inputnode.in_file = 'diffusion.nii' >>> nipype_eddycorrect.inputs.inputnode.ref_num = 0 >>> nipype_eddycorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file inputnode.ref_num Outputs:: outputnode.eddy_corrected """ warnings.warn(('This workflow is deprecated from v.1.0.0, use ' 'nipype.workflows.dmri.preprocess.epi.ecc_pipeline instead'), DeprecationWarning) inputnode = pe.Node( niu.IdentityInterface(fields=['in_file', 'ref_num']), name='inputnode') pipeline = pe.Workflow(name=name) split = pe.Node(fsl.Split(dimension='t'), name='split') pick_ref = pe.Node(niu.Select(), name='pick_ref') coregistration = pe.MapNode(fsl.FLIRT(no_search=True, padding_size=1, interp='trilinear'), name='coregistration', iterfield=['in_file']) merge = pe.Node(fsl.Merge(dimension='t'), name='merge') outputnode = pe.Node( niu.IdentityInterface(fields=['eddy_corrected']), name='outputnode') pipeline.connect([ (inputnode, split, [('in_file', 'in_file')]) ,(split, pick_ref, [('out_files', 'inlist')]) ,(inputnode, pick_ref, [('ref_num', 'index')]) ,(split, coregistration, [('out_files', 'in_file')]) ,(pick_ref, coregistration, [('out', 'reference')]) ,(coregistration, merge, [('out_file', 'in_files')]) ,(merge, outputnode, [('merged_file', 'eddy_corrected')]) ]) return pipeline def fieldmap_correction(name='fieldmap_correction', nocheck=False): """ .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.sdc_fmb` instead. Fieldmap-based retrospective correction of EPI images for the susceptibility distortion artifact (Jezzard et al., 1995). Fieldmap images are assumed to be already registered to EPI data, and a brain mask is required. Replaces the former workflow, still available as create_epidewarp_pipeline(). The difference with respect the epidewarp pipeline is that now the workflow uses the new fsl_prepare_fieldmap available as of FSL 5.0. Example ------- >>> nipype_epicorrect = fieldmap_correction('nipype_epidewarp') >>> nipype_epicorrect.inputs.inputnode.in_file = 'diffusion.nii' >>> nipype_epicorrect.inputs.inputnode.in_mask = 'brainmask.nii' >>> nipype_epicorrect.inputs.inputnode.fieldmap_pha = 'phase.nii' >>> nipype_epicorrect.inputs.inputnode.fieldmap_mag = 'magnitude.nii' >>> nipype_epicorrect.inputs.inputnode.te_diff = 2.46 >>> nipype_epicorrect.inputs.inputnode.epi_echospacing = 0.77 >>> nipype_epicorrect.inputs.inputnode.encoding_direction = 'y' >>> nipype_epicorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file - The volume acquired with EPI sequence inputnode.in_mask - A brain mask inputnode.fieldmap_pha - The phase difference map from the fieldmapping, registered to in_file inputnode.fieldmap_mag - The magnitud maps (usually 4D, one magnitude per GRE scan) from the fieldmapping, registered to in_file inputnode.te_diff - Time difference in msec. between TE in ms of the fieldmapping (usually a GRE sequence). inputnode.epi_echospacing - The effective echo spacing (aka dwell time) in msec. of the EPI sequence. If EPI was acquired with parallel imaging, then the effective echo spacing is eff_es = es / acc_factor. inputnode.encoding_direction - The phase encoding direction in EPI acquisition (default y) inputnode.vsm_sigma - Sigma value of the gaussian smoothing filter applied to the vsm (voxel shift map) Outputs:: outputnode.epi_corrected outputnode.out_vsm """ warnings.warn(('This workflow is deprecated from v.1.0.0, use ' 'nipype.workflows.dmri.preprocess.epi.sdc_fmb instead'), DeprecationWarning) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file', 'in_mask', 'fieldmap_pha', 'fieldmap_mag', 'te_diff', 'epi_echospacing', 'vsm_sigma', 'encoding_direction' ]), name='inputnode' ) pipeline = pe.Workflow(name=name) # Keep first frame from magnitude select_mag = pe.Node(fsl.utils.ExtractROI( t_size=1, t_min=0), name='select_magnitude') # Mask magnitude (it is required by PreparedFieldMap) mask_mag = pe.Node( fsl.maths.ApplyMask(), name='mask_magnitude' ) # Run fsl_prepare_fieldmap fslprep = pe.Node( fsl.PrepareFieldmap(), name='prepare_fieldmap' ) if nocheck: fslprep.inputs.nocheck = True # Use FUGUE to generate the voxel shift map (vsm) vsm = pe.Node(fsl.FUGUE(save_shift=True), name='generate_vsm') # VSM demean is not anymore present in the epi_reg script #vsm_mean = pe.Node(niu.Function(input_names=['in_file', 'mask_file', 'in_unwarped'], output_names=[ # 'out_file'], function=_vsm_remove_mean), name='vsm_mean_shift') # fugue_epi dwi_split = pe.Node(niu.Function(input_names=[ 'in_file'], output_names=['out_files'], function=_split_dwi), name='dwi_split') # 'fugue -i %s -u %s --loadshift=%s --mask=%s' % ( vol_name, out_vol_name, vsm_name, mask_name ) dwi_applyxfm = pe.MapNode(fsl.FUGUE( icorr=True, save_shift=False), iterfield=['in_file'], name='dwi_fugue') # Merge back all volumes dwi_merge = pe.Node(fsl.utils.Merge( dimension='t'), name='dwi_merge') outputnode = pe.Node( niu.IdentityInterface(fields=['epi_corrected','out_vsm']), name='outputnode') pipeline.connect([ (inputnode, select_mag, [('fieldmap_mag', 'in_file')]) ,(inputnode, fslprep, [('fieldmap_pha', 'in_phase'),('te_diff', 'delta_TE') ]) ,(inputnode, mask_mag, [('in_mask', 'mask_file' )]) ,(select_mag, mask_mag, [('roi_file', 'in_file')]) ,(mask_mag, fslprep, [('out_file', 'in_magnitude')]) ,(fslprep, vsm, [('out_fieldmap', 'phasemap_in_file')]) ,(inputnode, vsm, [('fieldmap_mag', 'in_file'), ('encoding_direction','unwarp_direction'), (('te_diff', _ms2sec), 'asym_se_time'), ('vsm_sigma', 'smooth2d'), (('epi_echospacing', _ms2sec), 'dwell_time')]) ,(mask_mag, vsm, [('out_file', 'mask_file')]) ,(inputnode, dwi_split, [('in_file', 'in_file')]) ,(dwi_split, dwi_applyxfm, [('out_files', 'in_file')]) ,(mask_mag, dwi_applyxfm, [('out_file', 'mask_file')]) ,(vsm, dwi_applyxfm, [('shift_out_file', 'shift_in_file')]) ,(inputnode, dwi_applyxfm, [('encoding_direction','unwarp_direction')]) ,(dwi_applyxfm, dwi_merge, [('unwarped_file', 'in_files')]) ,(dwi_merge, outputnode, [('merged_file', 'epi_corrected')]) ,(vsm, outputnode, [('shift_out_file','out_vsm') ]) ]) return pipeline def topup_correction( name='topup_correction' ): """ .. deprecated:: 0.9.3 Use :func:`nipype.workflows.dmri.preprocess.epi.sdc_peb` instead. Corrects for susceptibilty distortion of EPI images when one reverse encoding dataset has been acquired Example ------- >>> nipype_epicorrect = topup_correction('nipype_topup') >>> nipype_epicorrect.inputs.inputnode.in_file_dir = 'epi.nii' >>> nipype_epicorrect.inputs.inputnode.in_file_rev = 'epi_rev.nii' >>> nipype_epicorrect.inputs.inputnode.encoding_direction = ['y', 'y-'] >>> nipype_epicorrect.inputs.inputnode.ref_num = 0 >>> nipype_epicorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file_dir - EPI volume acquired in 'forward' phase encoding inputnode.in_file_rev - EPI volume acquired in 'reversed' phase encoding inputnode.encoding_direction - Direction encoding of in_file_dir inputnode.ref_num - Identifier of the reference volumes (usually B0 volume) Outputs:: outputnode.epi_corrected """ warnings.warn(('This workflow is deprecated from v.1.0.0, use ' 'nipype.workflows.dmri.preprocess.epi.sdc_peb instead'), DeprecationWarning) pipeline = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface( fields=['in_file_dir', 'in_file_rev', 'encoding_direction', 'readout_times', 'ref_num' ]), name='inputnode' ) outputnode = pe.Node( niu.IdentityInterface( fields=['out_fieldcoef', 'out_movpar', 'out_enc_file', 'epi_corrected' ]), name='outputnode' ) b0_dir = pe.Node( fsl.ExtractROI( t_size=1 ), name='b0_1' ) b0_rev = pe.Node( fsl.ExtractROI( t_size=1 ), name='b0_2' ) combin = pe.Node( niu.Merge(2), name='merge' ) combin2 = pe.Node( niu.Merge(2), name='merge2' ) merged = pe.Node( fsl.Merge( dimension='t' ), name='b0_comb' ) topup = pe.Node( fsl.TOPUP(), name='topup' ) applytopup = pe.Node( fsl.ApplyTOPUP(in_index=[1,2] ), name='applytopup' ) pipeline.connect([ (inputnode, b0_dir, [('in_file_dir','in_file'),('ref_num','t_min')] ) ,(inputnode, b0_rev, [('in_file_rev','in_file'),('ref_num','t_min')] ) ,(inputnode, combin2, [('in_file_dir','in1'),('in_file_rev','in2') ] ) ,(b0_dir, combin, [('roi_file','in1')] ) ,(b0_rev, combin, [('roi_file','in2')] ) ,(combin, merged, [('out', 'in_files')] ) ,(merged, topup, [('merged_file','in_file')]) ,(inputnode, topup, [('encoding_direction','encoding_direction'),('readout_times','readout_times') ]) ,(topup, applytopup, [('out_fieldcoef','in_topup_fieldcoef'),('out_movpar','in_topup_movpar'), ('out_enc_file','encoding_file')]) ,(combin2, applytopup, [('out','in_files')] ) ,(topup, outputnode, [('out_fieldcoef','out_fieldcoef'),('out_movpar','out_movpar'), ('out_enc_file','out_enc_file') ]) ,(applytopup,outputnode, [('out_corrected','epi_corrected')]) ]) return pipeline def create_epidewarp_pipeline(name='epidewarp', fieldmap_registration=False): """ Replaces the epidewarp.fsl script (http://www.nmr.mgh.harvard.edu/~greve/fbirn/b0/epidewarp.fsl) for susceptibility distortion correction of dMRI & fMRI acquired with EPI sequences and the fieldmap information (Jezzard et al., 1995) using FSL's FUGUE. The registration to the (warped) fieldmap (strictly following the original script) is available using fieldmap_registration=True. .. warning:: This workflow makes use of ``epidewarp.fsl`` a script of FSL deprecated long time ago. The use of this workflow is not recommended, use :func:`nipype.workflows.dmri.preprocess.epi.sdc_fmb` instead. Example ------- >>> nipype_epicorrect = create_epidewarp_pipeline('nipype_epidewarp', fieldmap_registration=False) >>> nipype_epicorrect.inputs.inputnode.in_file = 'diffusion.nii' >>> nipype_epicorrect.inputs.inputnode.fieldmap_mag = 'magnitude.nii' >>> nipype_epicorrect.inputs.inputnode.fieldmap_pha = 'phase.nii' >>> nipype_epicorrect.inputs.inputnode.te_diff = 2.46 >>> nipype_epicorrect.inputs.inputnode.epi_echospacing = 0.77 >>> nipype_epicorrect.inputs.inputnode.epi_rev_encoding = False >>> nipype_epicorrect.inputs.inputnode.ref_num = 0 >>> nipype_epicorrect.inputs.inputnode.pi_accel_factor = 1.0 >>> nipype_epicorrect.run() # doctest: +SKIP Inputs:: inputnode.in_file - The volume acquired with EPI sequence inputnode.fieldmap_mag - The magnitude of the fieldmap inputnode.fieldmap_pha - The phase difference of the fieldmap inputnode.te_diff - Time difference between TE in ms. inputnode.epi_echospacing - The echo spacing (aka dwell time) in the EPI sequence inputnode.epi_ph_encoding_dir - The phase encoding direction in EPI acquisition (default y) inputnode.epi_rev_encoding - True if it is acquired with reverse encoding inputnode.pi_accel_factor - Acceleration factor used for EPI parallel imaging (GRAPPA) inputnode.vsm_sigma - Sigma value of the gaussian smoothing filter applied to the vsm (voxel shift map) inputnode.ref_num - The reference volume (B=0 in dMRI or a central frame in fMRI) Outputs:: outputnode.epi_corrected Optional arguments:: fieldmap_registration - True if registration to fieldmap should be done (default False) """ warnings.warn(('This workflow reproduces a deprecated FSL script.'), DeprecationWarning) inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'fieldmap_mag', 'fieldmap_pha', 'te_diff', 'epi_echospacing', 'epi_ph_encoding_dir', 'epi_rev_encoding', 'pi_accel_factor', 'vsm_sigma', 'ref_num', 'unwarp_direction' ]), name='inputnode') pipeline = pe.Workflow(name=name) # Keep first frame from magnitude select_mag = pe.Node(fsl.utils.ExtractROI( t_size=1, t_min=0), name='select_magnitude') # mask_brain mask_mag = pe.Node(fsl.BET(mask=True), name='mask_magnitude') mask_mag_dil = pe.Node(niu.Function(input_names=[ 'in_file'], output_names=['out_file'], function=_dilate_mask), name='mask_dilate') # Compute dwell time dwell_time = pe.Node(niu.Function(input_names=['dwell_time', 'pi_factor', 'is_reverse_encoding'], output_names=[ 'dwell_time'], function=_compute_dwelltime), name='dwell_time') # Normalize phase diff to be [-pi, pi) norm_pha = pe.Node(niu.Function(input_names=['in_file'], output_names=[ 'out_file'], function=_prepare_phasediff), name='normalize_phasediff') # Execute FSL PRELUDE: prelude -p %s -a %s -o %s -f -v -m %s prelude = pe.Node(fsl.PRELUDE( process3d=True), name='phase_unwrap') fill_phase = pe.Node(niu.Function(input_names=['in_file'], output_names=[ 'out_file'], function=_fill_phase), name='fill_phasediff') # to assure that vsm is same dimension as mag. The input only affects the output dimension. # The content of the input has no effect on the vsm. The de-warped mag volume is # meaningless and will be thrown away # fugue -i %s -u %s -p %s --dwell=%s --asym=%s --mask=%s --saveshift=%s % # ( mag_name, magdw_name, ph_name, esp, tediff, mask_name, vsmmag_name) vsm = pe.Node(fsl.FUGUE(save_shift=True), name='generate_vsm') vsm_mean = pe.Node(niu.Function(input_names=['in_file', 'mask_file', 'in_unwarped'], output_names=[ 'out_file'], function=_vsm_remove_mean), name='vsm_mean_shift') # fugue_epi dwi_split = pe.Node(niu.Function(input_names=[ 'in_file'], output_names=['out_files'], function=_split_dwi), name='dwi_split') # 'fugue -i %s -u %s --loadshift=%s --mask=%s' % ( vol_name, out_vol_name, vsm_name, mask_name ) dwi_applyxfm = pe.MapNode(fsl.FUGUE( icorr=True, save_shift=False), iterfield=['in_file'], name='dwi_fugue') # Merge back all volumes dwi_merge = pe.Node(fsl.utils.Merge( dimension='t'), name='dwi_merge') outputnode = pe.Node( niu.IdentityInterface(fields=['epi_corrected']), name='outputnode') pipeline.connect([ (inputnode, dwell_time, [('epi_echospacing', 'dwell_time'), ('pi_accel_factor', 'pi_factor'), ('epi_rev_encoding', 'is_reverse_encoding')]) ,(inputnode, select_mag, [('fieldmap_mag', 'in_file')]) ,(inputnode, norm_pha, [('fieldmap_pha', 'in_file')]) ,(select_mag, mask_mag, [('roi_file', 'in_file')]) ,(mask_mag, mask_mag_dil, [('mask_file', 'in_file')]) ,(select_mag, prelude, [('roi_file', 'magnitude_file')]) ,(norm_pha, prelude, [('out_file', 'phase_file')]) ,(mask_mag_dil, prelude, [('out_file', 'mask_file')]) ,(prelude, fill_phase, [('unwrapped_phase_file', 'in_file')]) ,(inputnode, vsm, [('fieldmap_mag', 'in_file')]) ,(fill_phase, vsm, [('out_file', 'phasemap_in_file')]) ,(inputnode, vsm, [(('te_diff', _ms2sec), 'asym_se_time'), ('vsm_sigma', 'smooth2d')]) ,(dwell_time, vsm, [(('dwell_time', _ms2sec), 'dwell_time')]) ,(mask_mag_dil, vsm, [('out_file', 'mask_file')]) ,(mask_mag_dil, vsm_mean, [('out_file', 'mask_file')]) ,(vsm, vsm_mean, [('unwarped_file', 'in_unwarped'), ('shift_out_file', 'in_file')]) ,(inputnode, dwi_split, [('in_file', 'in_file')]) ,(dwi_split, dwi_applyxfm, [('out_files', 'in_file')]) ,(dwi_applyxfm, dwi_merge, [('unwarped_file', 'in_files')]) ,(dwi_merge, outputnode, [('merged_file', 'epi_corrected')]) ]) if fieldmap_registration: """ Register magfw to example epi. There are some parameters here that may need to be tweaked. Should probably strip the mag Pre-condition: forward warp the mag in order to reg with func. What does mask do here? """ # Select reference volume from EPI (B0 in dMRI and a middle frame in # fMRI) select_epi = pe.Node(fsl.utils.ExtractROI( t_size=1), name='select_epi') # fugue -i %s -w %s --loadshift=%s --mask=%s % ( mag_name, magfw_name, # vsmmag_name, mask_name ), log ) # Forward Map vsm_fwd = pe.Node(fsl.FUGUE( forward_warping=True), name='vsm_fwd') vsm_reg = pe.Node(fsl.FLIRT(bins=256, cost='corratio', dof=6, interp='spline', searchr_x=[ -10, 10], searchr_y=[-10, 10], searchr_z=[-10, 10]), name='vsm_registration') # 'flirt -in %s -ref %s -out %s -init %s -applyxfm' % ( vsmmag_name, ref_epi, vsmmag_name, magfw_mat_out ) vsm_applyxfm = pe.Node(fsl.ApplyXfm( interp='spline'), name='vsm_apply_xfm') # 'flirt -in %s -ref %s -out %s -init %s -applyxfm' % ( mask_name, ref_epi, mask_name, magfw_mat_out ) msk_applyxfm = pe.Node(fsl.ApplyXfm( interp='nearestneighbour'), name='msk_apply_xfm') pipeline.connect([ (inputnode, select_epi, [('in_file', 'in_file'), ('ref_num', 't_min')]) ,(select_epi, vsm_reg, [('roi_file', 'reference')]) ,(vsm, vsm_fwd, [('shift_out_file', 'shift_in_file')]) ,(mask_mag_dil, vsm_fwd, [('out_file', 'mask_file')]) ,(inputnode, vsm_fwd, [('fieldmap_mag', 'in_file')]) ,(vsm_fwd, vsm_reg, [('warped_file', 'in_file')]) ,(vsm_reg, msk_applyxfm, [('out_matrix_file', 'in_matrix_file')]) ,(select_epi, msk_applyxfm, [('roi_file', 'reference')]) ,(mask_mag_dil, msk_applyxfm, [('out_file', 'in_file')]) ,(vsm_reg, vsm_applyxfm, [('out_matrix_file', 'in_matrix_file')]) ,(select_epi, vsm_applyxfm, [('roi_file', 'reference')]) ,(vsm_mean, vsm_applyxfm, [('out_file', 'in_file')]) ,(msk_applyxfm, dwi_applyxfm, [('out_file', 'mask_file')]) ,(vsm_applyxfm, dwi_applyxfm, [('out_file', 'shift_in_file')]) ]) else: pipeline.connect([ (mask_mag_dil, dwi_applyxfm, [('out_file', 'mask_file')]) ,( vsm_mean, dwi_applyxfm, [('out_file', 'shift_in_file')]) ]) return pipeline def _rotate_bvecs(in_bvec, in_matrix): import os import numpy as np name, fext = os.path.splitext(os.path.basename(in_bvec)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_rotated.bvec' % name) bvecs = np.loadtxt(in_bvec) new_bvecs = np.zeros(shape=bvecs.T.shape) #pre-initialise array, 3 col format for i, vol_matrix in enumerate(in_matrix[0::]): #start index at 0 bvec = np.matrix(bvecs[:, i]) rot = np.matrix(np.loadtxt(vol_matrix)[0:3, 0:3]) new_bvecs[i] = (np.array(rot * bvec.T).T)[0] #fill each volume with x,y,z as we go along np.savetxt(out_file, np.array(new_bvecs).T, fmt='%0.15f') return out_file def _cat_logs(in_files): import shutil import os name, fext = os.path.splitext(os.path.basename(in_files[0])) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_ecclog.log' % name) out_str = '' with open(out_file, 'wb') as totallog: for i, fname in enumerate(in_files): totallog.write('\n\npreprocessing %d\n' % i) with open(fname) as inlog: for line in inlog: totallog.write(line) return out_file def _compute_dwelltime(dwell_time=0.68, pi_factor=1.0, is_reverse_encoding=False): dwell_time *= (1.0/pi_factor) if is_reverse_encoding: dwell_time *= -1.0 return dwell_time def _effective_echospacing( dwell_time, pi_factor=1.0 ): dwelltime = 1.0e-3 * dwell_time * ( 1.0/pi_factor ) return dwelltime def _prepare_phasediff(in_file): import nibabel as nib import os import numpy as np img = nib.load(in_file) max_diff = np.max(img.get_data().reshape(-1)) min_diff = np.min(img.get_data().reshape(-1)) A = (2.0 * np.pi)/(max_diff-min_diff) B = np.pi - (A * max_diff) diff_norm = img.get_data() * A + B name, fext = os.path.splitext(os.path.basename(in_file)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_2pi.nii.gz' % name) nib.save(nib.Nifti1Image( diff_norm, img.get_affine(), img.get_header()), out_file) return out_file def _dilate_mask(in_file, iterations=4): import nibabel as nib import scipy.ndimage as ndimage import os img = nib.load(in_file) img._data = ndimage.binary_dilation(img.get_data(), iterations=iterations) name, fext = os.path.splitext(os.path.basename(in_file)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_dil.nii.gz' % name) nib.save(img, out_file) return out_file def _fill_phase(in_file): import nibabel as nib import os import numpy as np img = nib.load(in_file) dumb_img = nib.Nifti1Image(np.zeros( img.get_shape()), img.get_affine(), img.get_header()) out_nii = nib.funcs.concat_images((img, dumb_img)) name, fext = os.path.splitext(os.path.basename(in_file)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_fill.nii.gz' % name) nib.save(out_nii, out_file) return out_file def _vsm_remove_mean(in_file, mask_file, in_unwarped): import nibabel as nib import os import numpy as np import numpy.ma as ma img = nib.load(in_file) msk = nib.load(mask_file).get_data() img_data = img.get_data() img_data[msk == 0] = 0 vsmmag_masked = ma.masked_values(img_data.reshape(-1), 0.0) vsmmag_masked = vsmmag_masked - vsmmag_masked.mean() img._data = vsmmag_masked.reshape(img.get_shape()) name, fext = os.path.splitext(os.path.basename(in_file)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('./%s_demeaned.nii.gz' % name) nib.save(img, out_file) return out_file def _ms2sec(val): return val*1e-3; def _split_dwi(in_file): import nibabel as nib import os out_files = [] frames = nib.funcs.four_to_three(nib.load(in_file)) name, fext = os.path.splitext(os.path.basename(in_file)) if fext == '.gz': name, _ = os.path.splitext(name) for i, frame in enumerate(frames): out_file = os.path.abspath('./%s_%03d.nii.gz' % (name, i)) nib.save(frame, out_file) out_files.append(out_file) return out_files nipype-0.11.0/nipype/workflows/dmri/fsl/tbss.py000066400000000000000000000567111257611314500215210ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from warnings import warn import nipype.pipeline.engine as pe import nipype.interfaces.utility as util import nipype.interfaces.fsl as fsl def tbss1_op_string(in_files): import nibabel as nib op_strings = [] for infile in in_files: img = nib.load(infile) dimtup = tuple([d - 2 for d in img.get_shape()]) dimtup = dimtup[0:3] op_str = '-min 1 -ero -roi 1 %d 1 %d 1 %d 0 1' % dimtup op_strings.append(op_str) return op_strings def create_tbss_1_preproc(name='tbss_1_preproc'): """Preprocess FA data for TBSS: erodes a little and zero end slicers and creates masks(for use in FLIRT & FNIRT from FSL). A pipeline that does the same as tbss_1_preproc script in FSL Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss1 = tbss.create_tbss_1_preproc() >>> tbss1.inputs.inputnode.fa_list = ['s1_FA.nii', 's2_FA.nii', 's3_FA.nii'] Inputs:: inputnode.fa_list Outputs:: outputnode.fa_list outputnode.mask_list outputnode.slices """ # Define the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=["fa_list"]), name="inputnode") # Prep the FA images prepfa = pe.MapNode(fsl.ImageMaths(suffix="_prep"), name="prepfa", iterfield=['in_file', 'op_string']) # Slicer slicer = pe.MapNode(fsl.Slicer(all_axial=True, image_width=1280), name='slicer', iterfield=['in_file']) # Create a mask getmask1 = pe.MapNode(fsl.ImageMaths(op_string="-bin", suffix="_mask"), name="getmask1", iterfield=['in_file']) getmask2 = pe.MapNode(fsl.MultiImageMaths(op_string="-dilD -dilD -sub 1 -abs -add %s"), name="getmask2", iterfield=['in_file', 'operand_files']) # $FSLDIR/bin/fslmaths FA/${f}_FA_mask -dilD -dilD -sub 1 -abs -add FA/${f}_FA_mask FA/${f}_FA_mask -odt char # Define the tbss1 workflow tbss1 = pe.Workflow(name=name) tbss1.connect([ (inputnode, prepfa, [("fa_list", "in_file")]), (inputnode, prepfa, [(("fa_list", tbss1_op_string), "op_string")]), (prepfa, getmask1, [("out_file", "in_file")]), (getmask1, getmask2, [("out_file", "in_file"), ("out_file", "operand_files")]), (prepfa, slicer, [('out_file', 'in_file')]), ]) # Define the outputnode outputnode = pe.Node(interface=util.IdentityInterface(fields=["fa_list", "mask_list", "slices"]), name="outputnode") tbss1.connect([ (prepfa, outputnode, [("out_file", "fa_list")]), (getmask2, outputnode, [("out_file", "mask_list")]), (slicer, outputnode, [('out_file', 'slices')]) ]) return tbss1 def create_tbss_2_reg(name="tbss_2_reg"): """TBSS nonlinear registration: A pipeline that does the same as 'tbss_2_reg -t' script in FSL. '-n' option is not supported at the moment. Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss2 = create_tbss_2_reg(name="tbss2") >>> tbss2.inputs.inputnode.target = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz") # doctest: +SKIP >>> tbss2.inputs.inputnode.fa_list = ['s1_FA.nii', 's2_FA.nii', 's3_FA.nii'] >>> tbss2.inputs.inputnode.mask_list = ['s1_mask.nii', 's2_mask.nii', 's3_mask.nii'] Inputs:: inputnode.fa_list inputnode.mask_list inputnode.target Outputs:: outputnode.field_list """ # Define the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=["fa_list", "mask_list", "target"]), name="inputnode") # Flirt the FA image to the target flirt = pe.MapNode(interface=fsl.FLIRT(dof=12), iterfield=['in_file', 'in_weight'], name="flirt") fnirt = pe.MapNode(interface=fsl.FNIRT(fieldcoeff_file=True), iterfield=['in_file', 'inmask_file', 'affine_file'], name="fnirt") # Fnirt the FA image to the target if fsl.no_fsl(): warn('NO FSL found') else: config_file = os.path.join(os.environ["FSLDIR"], "etc/flirtsch/FA_2_FMRIB58_1mm.cnf") fnirt.inputs.config_file=config_file # Define the registration workflow tbss2 = pe.Workflow(name=name) # Connect up the registration workflow tbss2.connect([ (inputnode, flirt, [("fa_list", "in_file"), ("target", "reference"), ("mask_list", "in_weight")]), (inputnode, fnirt, [("fa_list", "in_file"), ("mask_list", "inmask_file"), ("target", "ref_file")]), (flirt, fnirt, [("out_matrix_file", "affine_file")]), ]) # Define the outputnode outputnode = pe.Node(interface=util.IdentityInterface(fields=['field_list']), name="outputnode") tbss2.connect([ (fnirt, outputnode, [('fieldcoeff_file', 'field_list')]) ]) return tbss2 def create_tbss_3_postreg(name='tbss_3_postreg', estimate_skeleton=True): """Post-registration processing: derive mean_FA and mean_FA_skeleton from mean of all subjects in study. Target is assumed to be FMRIB58_FA_1mm. A pipeline that does the same as 'tbss_3_postreg -S' script from FSL Setting 'estimate_skeleton to False will use precomputed FMRIB58_FA-skeleton_1mm skeleton (same as 'tbss_3_postreg -T'). Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss3 = tbss.create_tbss_3_postreg() >>> tbss3.inputs.inputnode.fa_list = ['s1_wrapped_FA.nii', 's2_wrapped_FA.nii', 's3_wrapped_FA.nii'] Inputs:: inputnode.field_list inputnode.fa_list Outputs:: outputnode.groupmask outputnode.skeleton_file outputnode.meanfa_file outputnode.mergefa_file """ # Create the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=['field_list', 'fa_list']), name='inputnode') # Apply the warpfield to the masked FA image applywarp = pe.MapNode(interface=fsl.ApplyWarp(), iterfield=['in_file', 'field_file'], name="applywarp") if fsl.no_fsl(): warn('NO FSL found') else: applywarp.inputs.ref_file = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz") # Merge the FA files into a 4D file mergefa = pe.Node(fsl.Merge(dimension="t"), name="mergefa") # Get a group mask groupmask = pe.Node(fsl.ImageMaths(op_string="-max 0 -Tmin -bin", out_data_type="char", suffix="_mask"), name="groupmask") maskgroup = pe.Node(fsl.ImageMaths(op_string="-mas", suffix="_masked"), name="maskgroup") tbss3 = pe.Workflow(name=name) tbss3.connect([ (inputnode, applywarp, [("fa_list", "in_file"), ("field_list", "field_file")]), (applywarp, mergefa, [("out_file", "in_files")]), (mergefa, groupmask, [("merged_file", "in_file")]), (mergefa, maskgroup, [("merged_file", "in_file")]), (groupmask, maskgroup, [("out_file", "in_file2")]), ]) # Create outputnode outputnode = pe.Node(interface=util.IdentityInterface(fields=['groupmask', 'skeleton_file', 'meanfa_file', 'mergefa_file']), name='outputnode') if estimate_skeleton: # Take the mean over the fourth dimension meanfa = pe.Node(fsl.ImageMaths(op_string="-Tmean", suffix="_mean"), name="meanfa") # Use the mean FA volume to generate a tract skeleton makeskeleton = pe.Node(fsl.TractSkeleton(skeleton_file=True), name="makeskeleton") tbss3.connect([ (maskgroup, meanfa, [("out_file", "in_file")]), (meanfa, makeskeleton, [("out_file", "in_file")]), (groupmask, outputnode, [('out_file', 'groupmask')]), (makeskeleton, outputnode, [('skeleton_file', 'skeleton_file')]), (meanfa, outputnode, [('out_file', 'meanfa_file')]), (maskgroup, outputnode, [('out_file', 'mergefa_file')]) ]) else: #$FSLDIR/bin/fslmaths $FSLDIR/data/standard/FMRIB58_FA_1mm -mas mean_FA_mask mean_FA maskstd = pe.Node(fsl.ImageMaths(op_string="-mas", suffix="_masked"), name="maskstd") maskstd.inputs.in_file = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz") #$FSLDIR/bin/fslmaths mean_FA -bin mean_FA_mask binmaskstd = pe.Node(fsl.ImageMaths(op_string="-bin"), name="binmaskstd") #$FSLDIR/bin/fslmaths all_FA -mas mean_FA_mask all_FA maskgroup2 = pe.Node(fsl.ImageMaths(op_string="-mas", suffix="_masked"), name="maskgroup2") tbss3.connect([ (groupmask, maskstd, [("out_file", "in_file2")]), (maskstd, binmaskstd, [("out_file", "in_file")]), (maskgroup, maskgroup2, [("out_file", "in_file")]), (binmaskstd, maskgroup2, [("out_file", "in_file2")]) ]) outputnode.inputs.skeleton_file = fsl.Info.standard_image("FMRIB58_FA-skeleton_1mm.nii.gz") tbss3.connect([ (binmaskstd, outputnode, [('out_file', 'groupmask')]), (maskstd, outputnode, [('out_file', 'meanfa_file')]), (maskgroup2, outputnode, [('out_file', 'mergefa_file')]) ]) return tbss3 def tbss4_op_string(skeleton_thresh): op_string = "-thr %.1f -bin" % skeleton_thresh return op_string def create_tbss_4_prestats(name='tbss_4_prestats'): """Post-registration processing:Creating skeleton mask using a threshold projecting all FA data onto skeleton. A pipeline that does the same as tbss_4_prestats script from FSL Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss4 = tbss.create_tbss_4_prestats(name='tbss4') >>> tbss4.inputs.inputnode.skeleton_thresh = 0.2 Inputs:: inputnode.skeleton_thresh inputnode.groupmask inputnode.skeleton_file inputnode.meanfa_file inputnode.mergefa_file Outputs:: outputnode.all_FA_skeletonised outputnode.mean_FA_skeleton_mask outputnode.distance_map outputnode.skeleton_file """ # Create inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=['groupmask', 'skeleton_file', 'meanfa_file', 'mergefa_file', 'skeleton_thresh']), name='inputnode') # Mask the skeleton at the threshold skeletonmask = pe.Node(fsl.ImageMaths( suffix="_mask"), name="skeletonmask") # Invert the brainmask then add in the tract skeleton invertmask = pe.Node(fsl.ImageMaths(suffix="_inv", op_string="-mul -1 -add 1 -add"), name="invertmask") # Generate a distance map with the tract skeleton distancemap = pe.Node(fsl.DistanceMap(), name="distancemap") # Project the FA values onto the skeleton projectfa = pe.Node(fsl.TractSkeleton(project_data=True, skeleton_file=True, use_cingulum_mask=True), name="projectfa") # Create tbss4 workflow tbss4 = pe.Workflow(name=name) tbss4.connect([ (inputnode, invertmask, [("groupmask", "in_file")]), (inputnode, skeletonmask, [("skeleton_file", "in_file"), (('skeleton_thresh', tbss4_op_string), 'op_string')]), (inputnode, projectfa, [('skeleton_thresh', 'threshold'), ("meanfa_file", "in_file"), ("mergefa_file", "data_file")]), (skeletonmask, invertmask, [("out_file", "in_file2")]), (invertmask, distancemap, [("out_file", "in_file")]), (distancemap, projectfa, [("distance_map", "distance_map")]), ]) # Create the outputnode outputnode = pe.Node(interface=util.IdentityInterface(fields=['projectedfa_file', 'skeleton_mask', 'distance_map', 'skeleton_file']), name='outputnode') tbss4.connect([ (projectfa, outputnode, [('projected_data', 'projectedfa_file'), ('skeleton_file', 'skeleton_file') ]), (distancemap, outputnode, [('distance_map', 'distance_map')]), (skeletonmask, outputnode, [('out_file', 'skeleton_mask')]) ]) return tbss4 def create_tbss_all(name='tbss_all', estimate_skeleton=True): """Create a pipeline that combines create_tbss_* pipelines Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss = tbss.create_tbss_all('tbss') >>> tbss.inputs.inputnode.skeleton_thresh = 0.2 Inputs:: inputnode.fa_list inputnode.skeleton_thresh Outputs:: outputnode.meanfa_file outputnode.projectedfa_file outputnode.skeleton_file outputnode.skeleton_mask """ # Define the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=['fa_list', 'skeleton_thresh']), name='inputnode') tbss1 = create_tbss_1_preproc(name='tbss1') tbss2 = create_tbss_2_reg(name='tbss2') if fsl.no_fsl(): warn('NO FSL found') else: tbss2.inputs.inputnode.target = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz") tbss3 = create_tbss_3_postreg(name='tbss3', estimate_skeleton=estimate_skeleton) tbss4 = create_tbss_4_prestats(name='tbss4') tbss_all = pe.Workflow(name=name) tbss_all.connect([ (inputnode, tbss1, [('fa_list', 'inputnode.fa_list')]), (inputnode, tbss4, [('skeleton_thresh', 'inputnode.skeleton_thresh')]), (tbss1, tbss2, [('outputnode.fa_list', 'inputnode.fa_list'), ('outputnode.mask_list', 'inputnode.mask_list')]), (tbss1, tbss3, [('outputnode.fa_list', 'inputnode.fa_list')]), (tbss2, tbss3, [('outputnode.field_list', 'inputnode.field_list')]), (tbss3, tbss4, [ ('outputnode.groupmask', 'inputnode.groupmask'), ('outputnode.skeleton_file', 'inputnode.skeleton_file'), ('outputnode.meanfa_file', 'inputnode.meanfa_file'), ('outputnode.mergefa_file', 'inputnode.mergefa_file') ]) ]) # Define the outputnode outputnode = pe.Node(interface=util.IdentityInterface(fields=['groupmask', 'skeleton_file3', 'meanfa_file', 'mergefa_file', 'projectedfa_file', 'skeleton_file4', 'skeleton_mask', 'distance_map']), name='outputnode') outputall_node = pe.Node(interface=util.IdentityInterface( fields=['fa_list1', 'mask_list1', 'field_list2', 'groupmask3', 'skeleton_file3', 'meanfa_file3', 'mergefa_file3', 'projectedfa_file4', 'skeleton_mask4', 'distance_map4']), name='outputall_node') tbss_all.connect([ (tbss3, outputnode, [('outputnode.meanfa_file', 'meanfa_file'), ('outputnode.mergefa_file', 'mergefa_file'), ('outputnode.groupmask', 'groupmask'), ('outputnode.skeleton_file', 'skeleton_file3'), ]), (tbss4, outputnode, [('outputnode.projectedfa_file', 'projectedfa_file'), ('outputnode.skeleton_file', 'skeleton_file4'), ('outputnode.skeleton_mask', 'skeleton_mask'), ('outputnode.distance_map', 'distance_map'), ]), (tbss1, outputall_node, [('outputnode.fa_list', 'fa_list1'), ('outputnode.mask_list', 'mask_list1'), ]), (tbss2, outputall_node, [('outputnode.field_list', 'field_list2'), ]), (tbss3, outputall_node, [ ('outputnode.meanfa_file', 'meanfa_file3'), ('outputnode.mergefa_file', 'mergefa_file3'), ('outputnode.groupmask', 'groupmask3'), ('outputnode.skeleton_file', 'skeleton_file3'), ]), (tbss4, outputall_node, [ ('outputnode.projectedfa_file', 'projectedfa_file4'), ('outputnode.skeleton_mask', 'skeleton_mask4'), ('outputnode.distance_map', 'distance_map4'), ]), ]) return tbss_all def create_tbss_non_FA(name='tbss_non_FA'): """ A pipeline that implement tbss_non_FA in FSL Example ------- >>> from nipype.workflows.dmri.fsl import tbss >>> tbss_MD = tbss.create_tbss_non_FA() >>> tbss_MD.inputs.inputnode.file_list = [] >>> tbss_MD.inputs.inputnode.field_list = [] >>> tbss_MD.inputs.inputnode.skeleton_thresh = 0.2 >>> tbss_MD.inputs.inputnode.groupmask = './xxx' >>> tbss_MD.inputs.inputnode.meanfa_file = './xxx' >>> tbss_MD.inputs.inputnode.distance_map = [] >>> tbss_MD.inputs.inputnode.all_FA_file = './xxx' Inputs:: inputnode.file_list inputnode.field_list inputnode.skeleton_thresh inputnode.groupmask inputnode.meanfa_file inputnode.distance_map inputnode.all_FA_file Outputs:: outputnode.projected_nonFA_file """ # Define the inputnode inputnode = pe.Node(interface=util.IdentityInterface(fields=['file_list', 'field_list', 'skeleton_thresh', 'groupmask', 'meanfa_file', 'distance_map', 'all_FA_file']), name='inputnode') # Apply the warpfield to the non FA image applywarp = pe.MapNode(interface=fsl.ApplyWarp(), iterfield=['in_file', 'field_file'], name="applywarp") if fsl.no_fsl(): warn('NO FSL found') else: applywarp.inputs.ref_file = fsl.Info.standard_image("FMRIB58_FA_1mm.nii.gz") # Merge the non FA files into a 4D file merge = pe.Node(fsl.Merge(dimension="t"), name="merge") #merged_file="all_FA.nii.gz" maskgroup = pe.Node(fsl.ImageMaths(op_string="-mas", suffix="_masked"), name="maskgroup") projectfa = pe.Node(fsl.TractSkeleton(project_data=True, #projected_data = 'test.nii.gz', use_cingulum_mask=True ), name="projectfa") tbss_non_FA = pe.Workflow(name=name) tbss_non_FA.connect([ (inputnode, applywarp, [('file_list', 'in_file'), ('field_list', 'field_file'), ]), (applywarp, merge, [("out_file", "in_files")]), (merge, maskgroup, [("merged_file", "in_file")]), (inputnode, maskgroup, [('groupmask', 'in_file2')]), (maskgroup, projectfa, [('out_file', 'alt_data_file')]), (inputnode, projectfa, [('skeleton_thresh', 'threshold'), ("meanfa_file", "in_file"), ("distance_map", "distance_map"), ("all_FA_file", 'data_file') ]), ]) # Define the outputnode outputnode = pe.Node(interface=util.IdentityInterface( fields=['projected_nonFA_file']), name='outputnode') tbss_non_FA.connect([ (projectfa, outputnode, [('projected_data', 'projected_nonFA_file'), ]), ]) return tbss_non_FA nipype-0.11.0/nipype/workflows/dmri/fsl/tests/000077500000000000000000000000001257611314500213245ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/fsl/tests/__init__.py000066400000000000000000000001621257611314500234340ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/workflows/dmri/fsl/tests/test_dti.py000066400000000000000000000066341257611314500235260ustar00rootroot00000000000000import os from nipype.testing import skipif import nipype.interfaces.fsl as fsl import nipype.interfaces.utility as util from nipype.interfaces.fsl import no_fsl, no_fsl_course_data import nipype.pipeline.engine as pe import warnings import tempfile import shutil from nipype.workflows.dmri.fsl.dti import create_bedpostx_pipeline from nipype.utils.filemanip import list_to_filename @skipif(no_fsl) @skipif(no_fsl_course_data) def test_create_bedpostx_pipeline(): fsl_course_dir = os.path.abspath(os.environ['FSL_COURSE_DATA']) mask_file = os.path.join(fsl_course_dir, "fdt2/subj1.bedpostX/nodif_brain_mask.nii.gz") bvecs_file = os.path.join(fsl_course_dir, "fdt2/subj1/bvecs") bvals_file = os.path.join(fsl_course_dir, "fdt2/subj1/bvals") dwi_file = os.path.join(fsl_course_dir, "fdt2/subj1/data.nii.gz") z_min = 62 z_size = 2 slice_mask = pe.Node(fsl.ExtractROI(x_min=0, x_size=-1, y_min=0, y_size=-1, z_min=z_min, z_size=z_size), name="slice_mask") slice_mask.inputs.in_file = mask_file slice_dwi = pe.Node(fsl.ExtractROI(x_min=0, x_size=-1, y_min=0, y_size=-1, z_min=z_min, z_size=z_size), name="slice_dwi") slice_dwi.inputs.in_file = dwi_file nipype_bedpostx = create_bedpostx_pipeline("nipype_bedpostx") nipype_bedpostx.inputs.inputnode.bvecs = bvecs_file nipype_bedpostx.inputs.inputnode.bvals = bvals_file nipype_bedpostx.inputs.xfibres.n_fibres = 1 nipype_bedpostx.inputs.xfibres.fudge = 1 nipype_bedpostx.inputs.xfibres.burn_in = 0 nipype_bedpostx.inputs.xfibres.n_jumps = 1 nipype_bedpostx.inputs.xfibres.sample_every = 1 nipype_bedpostx.inputs.xfibres.cnlinear = True nipype_bedpostx.inputs.xfibres.seed = 0 with warnings.catch_warnings(): warnings.simplefilter("ignore") original_bedpostx = pe.Node(interface=fsl.BEDPOSTX(), name="original_bedpostx") original_bedpostx.inputs.bvecs = bvecs_file original_bedpostx.inputs.bvals = bvals_file original_bedpostx.inputs.environ['FSLPARALLEL'] = "" original_bedpostx.inputs.n_fibres = 1 original_bedpostx.inputs.fudge = 1 original_bedpostx.inputs.burn_in = 0 original_bedpostx.inputs.n_jumps = 1 original_bedpostx.inputs.sample_every = 1 original_bedpostx.inputs.seed = 0 test_f1 = pe.Node(util.AssertEqual(), name="mean_f1_test") pipeline = pe.Workflow(name="test_bedpostx") pipeline.base_dir = tempfile.mkdtemp(prefix="nipype_test_bedpostx_") pipeline.connect([(slice_mask, original_bedpostx, [("roi_file", "mask")]), (slice_mask, nipype_bedpostx, [("roi_file", "inputnode.mask")]), (slice_dwi, original_bedpostx, [("roi_file", "dwi")]), (slice_dwi, nipype_bedpostx, [("roi_file", "inputnode.dwi")]), (nipype_bedpostx, test_f1, [(("outputnode.mean_fsamples",list_to_filename), "volume1")]), (original_bedpostx, test_f1, [("mean_fsamples", "volume2")]), ]) pipeline.run(plugin='Linear') shutil.rmtree(pipeline.base_dir) nipype-0.11.0/nipype/workflows/dmri/fsl/tests/test_epi.py000066400000000000000000000033411257611314500235130ustar00rootroot00000000000000import os from nipype.testing import (skipif) import nipype.workflows.fmri.fsl as fsl_wf import nipype.interfaces.fsl as fsl import nipype.interfaces.utility as util from nipype.interfaces.fsl import no_fsl, no_fsl_course_data import nipype.pipeline.engine as pe import warnings import tempfile import shutil from nipype.workflows.dmri.fsl.epi import create_eddy_correct_pipeline @skipif(no_fsl) @skipif(no_fsl_course_data) def test_create_eddy_correct_pipeline(): fsl_course_dir = os.path.abspath(os.environ['FSL_COURSE_DATA']) dwi_file = os.path.join(fsl_course_dir, "fdt1/subj1/data.nii.gz") trim_dwi = pe.Node(fsl.ExtractROI(t_min=0, t_size=2), name="trim_dwi") trim_dwi.inputs.in_file = dwi_file nipype_eddycorrect = create_eddy_correct_pipeline("nipype_eddycorrect") nipype_eddycorrect.inputs.inputnode.ref_num = 0 with warnings.catch_warnings(): warnings.simplefilter("ignore") original_eddycorrect = pe.Node(interface=fsl.EddyCorrect(), name="original_eddycorrect") original_eddycorrect.inputs.ref_num = 0 test = pe.Node(util.AssertEqual(), name="eddy_corrected_dwi_test") pipeline = pe.Workflow(name="test_eddycorrect") pipeline.base_dir = tempfile.mkdtemp(prefix="nipype_test_eddycorrect_") pipeline.connect([(trim_dwi, original_eddycorrect, [("roi_file", "in_file")]), (trim_dwi, nipype_eddycorrect, [("roi_file", "inputnode.in_file")]), (nipype_eddycorrect, test, [("outputnode.eddy_corrected", "volume1")]), (original_eddycorrect, test, [("eddy_corrected", "volume2")]), ]) pipeline.run(plugin='Linear') shutil.rmtree(pipeline.base_dir) nipype-0.11.0/nipype/workflows/dmri/fsl/tests/test_tbss.py000066400000000000000000000157171257611314500237230ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os from nipype.interfaces.fsl.base import no_fsl, no_fsl_course_data import nipype.pipeline.engine as pe import nipype.interfaces.utility as util from nipype.testing import skipif import tempfile import shutil from subprocess import call from nipype.workflows.dmri.fsl.tbss import create_tbss_all import nipype.interfaces.io as nio from nipype.interfaces import fsl def _tbss_test_helper(estimate_skeleton): fsl_course_dir = os.path.abspath(os.environ['FSL_COURSE_DATA']) fsl.FSLCommand.set_default_output_type('NIFTI_GZ') test_dir = tempfile.mkdtemp(prefix="nipype_test_tbss_") tbss_orig_dir = os.path.join(test_dir, "tbss_all_original") os.mkdir(tbss_orig_dir) old_dir = os.getcwd() os.chdir(tbss_orig_dir) subjects = ['1260', '1549'] FA_list = [os.path.join(fsl_course_dir, 'tbss', subject_id + '.nii.gz') for subject_id in subjects] for f in FA_list: shutil.copy(f, os.getcwd()) call(['tbss_1_preproc'] + [subject_id + '.nii.gz' for subject_id in subjects], env=os.environ.update({'FSLOUTPUTTYPE': 'NIFTI_GZ'})) tbss1_orig_dir = os.path.join(test_dir, "tbss1_original") shutil.copytree(tbss_orig_dir, tbss1_orig_dir) call(['tbss_2_reg', '-T'], env=os.environ.update({'FSLOUTPUTTYPE': 'NIFTI_GZ'})) tbss2_orig_dir = os.path.join(test_dir, "tbss2_original") shutil.copytree(tbss_orig_dir, tbss2_orig_dir) if estimate_skeleton: call(['tbss_3_postreg', '-S'], env=os.environ.update({'FSLOUTPUTTYPE': 'NIFTI_GZ'})) else: call(['tbss_3_postreg', '-T'], env=os.environ.update({'FSLOUTPUTTYPE': 'NIFTI_GZ'})) tbss3_orig_dir = os.path.join(test_dir, "tbss3_original") shutil.copytree(tbss_orig_dir, tbss3_orig_dir) call(['tbss_4_prestats', '0.2'], env=os.environ.update({'FSLOUTPUTTYPE': 'NIFTI_GZ'})) tbss4_orig_dir = os.path.join(test_dir, "tbss4_original") shutil.copytree(tbss_orig_dir, tbss4_orig_dir) pipeline = pe.Workflow(name="test_tbss") pipeline.base_dir = os.path.join(test_dir, "tbss_nipype") tbss = create_tbss_all(estimate_skeleton=estimate_skeleton) tbss.inputs.inputnode.fa_list = FA_list tbss.inputs.inputnode.skeleton_thresh = 0.2 tbss1_original_datasource = pe.Node(nio.DataGrabber(outfields=['fa_list', 'mask_list'], sort_filelist=False), name='tbss1_original_datasource') tbss1_original_datasource.inputs.base_directory = tbss1_orig_dir tbss1_original_datasource.inputs.template = 'FA/%s_FA%s.nii.gz' tbss1_original_datasource.inputs.template_args = dict(fa_list=[[subjects, '']], mask_list=[[subjects, '_mask']]) tbss1_test_fa = pe.MapNode(util.AssertEqual(), name="tbss1_fa_test", iterfield=['volume1', 'volume2']) tbss1_test_mask = pe.MapNode(util.AssertEqual(), name="tbss1_mask_test", iterfield=['volume1', 'volume2']) pipeline.connect(tbss, 'tbss1.outputnode.fa_list', tbss1_test_fa, 'volume1') pipeline.connect(tbss, 'tbss1.outputnode.mask_list', tbss1_test_mask, 'volume1') pipeline.connect(tbss1_original_datasource, 'fa_list', tbss1_test_fa, 'volume2') pipeline.connect(tbss1_original_datasource, 'mask_list', tbss1_test_mask, 'volume2') tbss2_original_datasource = pe.Node(nio.DataGrabber(outfields=['field_list'], sort_filelist=False), name='tbss2_original_datasource') tbss2_original_datasource.inputs.base_directory = tbss2_orig_dir tbss2_original_datasource.inputs.template = 'FA/%s_FA%s.nii.gz' tbss2_original_datasource.inputs.template_args = dict(field_list=[[subjects, '_to_target_warp']]) tbss2_test_field = pe.MapNode(util.AssertEqual(), name="tbss2_test_field", iterfield=['volume1', 'volume2']) pipeline.connect(tbss, 'tbss2.outputnode.field_list', tbss2_test_field, 'volume1') pipeline.connect(tbss2_original_datasource, 'field_list', tbss2_test_field, 'volume2') tbss3_original_datasource = pe.Node(nio.DataGrabber(outfields=['groupmask', 'skeleton_file', 'meanfa_file', 'mergefa_file'], sort_filelist=False), name='tbss3_original_datasource') tbss3_original_datasource.inputs.base_directory = tbss3_orig_dir tbss3_original_datasource.inputs.template = 'stats/%s.nii.gz' tbss3_original_datasource.inputs.template_args = dict(groupmask=[['mean_FA_mask']], skeleton_file=[['mean_FA_skeleton']], meanfa_file=[['mean_FA']], mergefa_file=[['all_FA']]) tbss3_test_groupmask = pe.Node(util.AssertEqual(), name="tbss3_test_groupmask") tbss3_test_skeleton_file = pe.Node(util.AssertEqual(), name="tbss3_test_skeleton_file") tbss3_test_meanfa_file = pe.Node(util.AssertEqual(), name="tbss3_test_meanfa_file") tbss3_test_mergefa_file = pe.Node(util.AssertEqual(), name="tbss3_test_mergefa_file") pipeline.connect(tbss, 'tbss3.outputnode.groupmask', tbss3_test_groupmask, 'volume1') pipeline.connect(tbss3_original_datasource, 'groupmask', tbss3_test_groupmask, 'volume2') pipeline.connect(tbss, 'tbss3.outputnode.skeleton_file', tbss3_test_skeleton_file, 'volume1') pipeline.connect(tbss3_original_datasource, 'skeleton_file', tbss3_test_skeleton_file, 'volume2') pipeline.connect(tbss, 'tbss3.outputnode.meanfa_file', tbss3_test_meanfa_file, 'volume1') pipeline.connect(tbss3_original_datasource, 'meanfa_file', tbss3_test_meanfa_file, 'volume2') pipeline.connect(tbss, 'tbss3.outputnode.mergefa_file', tbss3_test_mergefa_file, 'volume1') pipeline.connect(tbss3_original_datasource, 'mergefa_file', tbss3_test_mergefa_file, 'volume2') tbss4_original_datasource = pe.Node(nio.DataGrabber(outfields=['all_FA_skeletonised', 'mean_FA_skeleton_mask'], sort_filelist=False), name='tbss4_original_datasource') tbss4_original_datasource.inputs.base_directory = tbss4_orig_dir tbss4_original_datasource.inputs.template = 'stats/%s.nii.gz' tbss4_original_datasource.inputs.template_args = dict(all_FA_skeletonised=[['all_FA_skeletonised']], mean_FA_skeleton_mask=[['mean_FA_skeleton_mask']]) tbss4_test_all_FA_skeletonised = pe.Node(util.AssertEqual(), name="tbss4_test_all_FA_skeletonised") tbss4_test_mean_FA_skeleton_mask = pe.Node(util.AssertEqual(), name="tbss4_test_mean_FA_skeleton_mask") pipeline.connect(tbss, 'tbss4.outputnode.projectedfa_file', tbss4_test_all_FA_skeletonised, 'volume1') pipeline.connect(tbss4_original_datasource, 'all_FA_skeletonised', tbss4_test_all_FA_skeletonised, 'volume2') pipeline.connect(tbss, 'tbss4.outputnode.skeleton_mask', tbss4_test_mean_FA_skeleton_mask, 'volume1') pipeline.connect(tbss4_original_datasource, 'mean_FA_skeleton_mask', tbss4_test_mean_FA_skeleton_mask, 'volume2') pipeline.run(plugin='Linear') os.chdir(old_dir) shutil.rmtree(test_dir) @skipif(no_fsl) @skipif(no_fsl_course_data) def test_tbss_est_skeleton(): _tbss_test_helper(True) @skipif(no_fsl) @skipif(no_fsl_course_data) def test_tbss_est_skeleton_use_precomputed_skeleton(): _tbss_test_helper(False) nipype-0.11.0/nipype/workflows/dmri/fsl/utils.py000066400000000000000000000652211257611314500217020ustar00rootroot00000000000000# coding: utf-8 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.pipeline.engine as pe import nipype.interfaces.utility as niu from nipype.interfaces import fsl from nipype.interfaces import ants def cleanup_edge_pipeline(name='Cleanup'): """ Perform some de-spiking filtering to clean up the edge of the fieldmap (copied from fsl_prepare_fieldmap) """ inputnode = pe.Node(niu.IdentityInterface(fields=['in_file', 'in_mask']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file']), name='outputnode') fugue = pe.Node(fsl.FUGUE(save_fmap=True, despike_2dfilter=True, despike_threshold=2.1), name='Despike') erode = pe.Node(fsl.maths.MathsCommand(nan2zeros=True, args='-kernel 2D -ero'), name='MskErode') newmsk = pe.Node(fsl.MultiImageMaths(op_string='-sub %s -thr 0.5 -bin'), name='NewMask') applymsk = pe.Node(fsl.ApplyMask(nan2zeros=True), name='ApplyMask') join = pe.Node(niu.Merge(2), name='Merge') addedge = pe.Node(fsl.MultiImageMaths(op_string='-mas %s -add %s'), name='AddEdge') wf = pe.Workflow(name=name) wf.connect([ (inputnode, fugue, [('in_file', 'fmap_in_file'), ('in_mask', 'mask_file')]), (inputnode, erode, [('in_mask', 'in_file')]), (inputnode, newmsk, [('in_mask', 'in_file')]), (erode, newmsk, [('out_file', 'operand_files')]), (fugue, applymsk, [('fmap_out_file', 'in_file')]), (newmsk, applymsk, [('out_file', 'mask_file')]), (erode, join, [('out_file', 'in1')]), (applymsk, join, [('out_file', 'in2')]), (inputnode, addedge, [('in_file', 'in_file')]), (join, addedge, [('out', 'operand_files')]), (addedge, outputnode, [('out_file', 'out_file')]) ]) return wf def vsm2warp(name='Shiftmap2Warping'): """ Converts a voxel shift map (vsm) to a displacements field (warp). """ inputnode = pe.Node(niu.IdentityInterface(fields=['in_vsm', 'in_ref', 'scaling', 'enc_dir']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_warp']), name='outputnode') fixhdr = pe.Node(niu.Function(input_names=['in_file', 'in_file_hdr'], output_names=['out_file'], function=copy_hdr), name='Fix_hdr') vsm = pe.Node(fsl.maths.BinaryMaths(operation='mul'), name='ScaleField') vsm2dfm = pe.Node(fsl.ConvertWarp(relwarp=True, out_relwarp=True), name='vsm2dfm') wf = pe.Workflow(name=name) wf.connect([ (inputnode, fixhdr, [('in_vsm', 'in_file'), ('in_ref', 'in_file_hdr')]), (inputnode, vsm, [('scaling', 'operand_value')]), (fixhdr, vsm, [('out_file', 'in_file')]), (vsm, vsm2dfm, [('out_file', 'shift_in_file')]), (inputnode, vsm2dfm, [('in_ref', 'reference'), ('enc_dir', 'shift_direction')]), (vsm2dfm, outputnode, [('out_file', 'out_warp')]) ]) return wf def dwi_flirt(name='DWICoregistration', excl_nodiff=False, flirt_param={}): """ Generates a workflow for linear registration of dwi volumes """ inputnode = pe.Node(niu.IdentityInterface(fields=['reference', 'in_file', 'ref_mask', 'in_xfms', 'in_bval']), name='inputnode') initmat = pe.Node(niu.Function(input_names=['in_bval', 'in_xfms', 'excl_nodiff'], output_names=['init_xfms'], function=_checkinitxfm), name='InitXforms') initmat.inputs.excl_nodiff = excl_nodiff dilate = pe.Node(fsl.maths.MathsCommand(nan2zeros=True, args='-kernel sphere 5 -dilM'), name='MskDilate') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') pick_ref = pe.Node(niu.Select(), name='Pick_b0') n4 = pe.Node(ants.N4BiasFieldCorrection(dimension=3), name='Bias') enhb0 = pe.Node(niu.Function(input_names=['in_file', 'in_mask', 'clip_limit'], output_names=['out_file'], function=enhance), name='B0Equalize') enhb0.inputs.clip_limit = 0.015 enhdw = pe.MapNode(niu.Function(input_names=['in_file', 'in_mask'], output_names=['out_file'], function=enhance), name='DWEqualize', iterfield=['in_file']) flirt = pe.MapNode(fsl.FLIRT(**flirt_param), name='CoRegistration', iterfield=['in_file', 'in_matrix_file']) thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_xfms']), name='outputnode') wf = pe.Workflow(name=name) wf.connect([ (inputnode, split, [('in_file', 'in_file')]), (inputnode, dilate, [('ref_mask', 'in_file')]), (inputnode, enhb0, [('ref_mask', 'in_mask')]), (inputnode, initmat, [('in_xfms', 'in_xfms'), ('in_bval', 'in_bval')]), (inputnode, n4, [('reference', 'input_image'), ('ref_mask', 'mask_image')]), (dilate, flirt, [('out_file', 'ref_weight'), ('out_file', 'in_weight')]), (n4, enhb0, [('output_image', 'in_file')]), (split, enhdw, [('out_files', 'in_file')]), (dilate, enhdw, [('out_file', 'in_mask')]), (enhb0, flirt, [('out_file', 'reference')]), (enhdw, flirt, [('out_file', 'in_file')]), (initmat, flirt, [('init_xfms', 'in_matrix_file')]), (flirt, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_files')]), (merge, outputnode, [('merged_file', 'out_file')]), (flirt, outputnode, [('out_matrix_file', 'out_xfms')]) ]) return wf def apply_all_corrections(name='UnwarpArtifacts'): """ Combines two lists of linear transforms with the deformation field map obtained typically after the SDC process. Additionally, computes the corresponding bspline coefficients and the map of determinants of the jacobian. """ inputnode = pe.Node(niu.IdentityInterface(fields=['in_sdc', 'in_hmc', 'in_ecc', 'in_dwi']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['out_file', 'out_warp', 'out_coeff', 'out_jacobian']), name='outputnode') warps = pe.MapNode(fsl.ConvertWarp(relwarp=True), iterfield=['premat', 'postmat'], name='ConvertWarp') selref = pe.Node(niu.Select(index=[0]), name='Reference') split = pe.Node(fsl.Split(dimension='t'), name='SplitDWIs') unwarp = pe.MapNode(fsl.ApplyWarp(), iterfield=['in_file', 'field_file'], name='UnwarpDWIs') coeffs = pe.MapNode(fsl.WarpUtils(out_format='spline'), iterfield=['in_file'], name='CoeffComp') jacobian = pe.MapNode(fsl.WarpUtils(write_jacobian=True), iterfield=['in_file'], name='JacobianComp') jacmult = pe.MapNode(fsl.MultiImageMaths(op_string='-mul %s'), iterfield=['in_file', 'operand_files'], name='ModulateDWIs') thres = pe.MapNode(fsl.Threshold(thresh=0.0), iterfield=['in_file'], name='RemoveNegative') merge = pe.Node(fsl.Merge(dimension='t'), name='MergeDWIs') wf = pe.Workflow(name=name) wf.connect([ (inputnode, warps, [('in_sdc', 'warp1'), ('in_hmc', 'premat'), ('in_ecc', 'postmat'), ('in_dwi', 'reference')]), (inputnode, split, [('in_dwi', 'in_file')]), (split, selref, [('out_files', 'inlist')]), (warps, unwarp, [('out_file', 'field_file')]), (split, unwarp, [('out_files', 'in_file')]), (selref, unwarp, [('out', 'ref_file')]), (selref, coeffs, [('out', 'reference')]), (warps, coeffs, [('out_file', 'in_file')]), (selref, jacobian, [('out', 'reference')]), (coeffs, jacobian, [('out_file', 'in_file')]), (unwarp, jacmult, [('out_file', 'in_file')]), (jacobian, jacmult, [('out_jacobian', 'operand_files')]), (jacmult, thres, [('out_file', 'in_file')]), (thres, merge, [('out_file', 'in_files')]), (warps, outputnode, [('out_file', 'out_warp')]), (coeffs, outputnode, [('out_file', 'out_coeff')]), (jacobian, outputnode, [('out_jacobian', 'out_jacobian')]), (merge, outputnode, [('merged_file', 'out_file')]) ]) return wf def extract_bval(in_dwi, in_bval, b=0, out_file=None): """ Writes an image containing only the volumes with b-value specified at input """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_tsoi%s" % (fname, ext)) im = nb.load(in_dwi) dwidata = im.get_data() bvals = np.loadtxt(in_bval) if b == 'diff': selection = np.where(bvals != 0) elif b == 'nodiff': selection = np.where(bvals == 0) else: selection = np.where(bvals == b) extdata = np.squeeze(dwidata.take(selection, axis=3)) hdr = im.get_header().copy() hdr.set_data_shape(extdata.shape) nb.Nifti1Image(extdata, im.get_affine(), hdr).to_filename(out_file) return out_file def hmc_split(in_file, in_bval, ref_num=0, lowbval=5.0): """ Selects the reference and moving volumes from a dwi dataset for the purpose of HMC. """ import numpy as np import nibabel as nb import os.path as op from nipype.interfaces.base import isdefined im = nb.load(in_file) data = im.get_data() hdr = im.get_header().copy() bval = np.loadtxt(in_bval) lowbs = np.where(bval <= lowbval)[0] volid = lowbs[0] if (isdefined(ref_num) and (ref_num < len(lowbs))): volid = [ref_num] if volid == 0: data = data[..., 1:] bval = bval[1:] elif volid == (data.shape[-1] - 1): data = data[..., :-1] bval = bval[:-1] else: data = np.concatenate((data[..., :volid], data[..., (volid + 1):]), axis=3) bval = np.hstack((bval[:volid], bval[(volid + 1):])) out_ref = op.abspath('hmc_ref.nii.gz') out_mov = op.abspath('hmc_mov.nii.gz') out_bval = op.abspath('bval_split.txt') hdr.set_data_shape(refdata.shape) refdata = data[..., volid] nb.Nifti1Image(refdata, im.get_affine(), hdr).to_filename(out_ref) hdr.set_data_shape(data.shape) nb.Nifti1Image(data, im.get_affine(), hdr).to_filename(out_mov) np.savetxt(out_bval, bval) return [out_ref, out_mov, out_bval, volid] def remove_comp(in_file, in_bval, volid=0, out_file=None): """ Removes the volume ``volid`` from the 4D nifti file """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_extract%s" % (fname, ext)) im = nb.load(in_file) data = im.get_data() hdr = im.get_header().copy() bval = np.loadtxt(in_bval) if volid == 0: data = data[..., 1:] bval = bval[1:] elif volid == (data.shape[-1] - 1): data = data[..., :-1] bval = bval[:-1] else: data = np.concatenate((data[..., :volid], data[..., (volid + 1):]), axis=3) bval = np.hstack((bval[:volid], bval[(volid + 1):])) hdr.set_data_shape(data.shape) nb.Nifti1Image(data, im.get_affine(), hdr).to_filename(out_file) out_bval = op.abspath('bval_extract.txt') np.savetxt(out_bval, bval) return out_file, out_bval def insert_mat(inlist, volid=0): import numpy as np import os.path as op idfname = op.abspath('identity.mat') out = inlist np.savetxt(idfname, np.eye(4)) out.insert(volid, idfname) return out def recompose_dwi(in_dwi, in_bval, in_corrected, out_file=None): """ Recompose back the dMRI data accordingly the b-values table after EC correction """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_eccorrect%s" % (fname, ext)) im = nb.load(in_dwi) dwidata = im.get_data() bvals = np.loadtxt(in_bval) dwis = np.where(bvals != 0)[0].tolist() if len(dwis) != len(in_corrected): raise RuntimeError(('Length of DWIs in b-values table and after' 'correction should match')) for bindex, dwi in zip(dwis, in_corrected): dwidata[..., bindex] = nb.load(dwi).get_data() nb.Nifti1Image(dwidata, im.get_affine(), im.get_header()).to_filename(out_file) return out_file def recompose_xfm(in_bval, in_xfms): """ Insert identity transformation matrices in b0 volumes to build up a list """ import numpy as np import os.path as op bvals = np.loadtxt(in_bval) out_matrix = np.array([np.eye(4)] * len(bvals)) xfms = iter([np.loadtxt(xfm) for xfm in in_xfms]) out_files = [] for i, b in enumerate(bvals): if b == 0.0: mat = np.eye(4) else: mat = xfms.next() out_name = op.abspath('eccor_%04d.mat' % i) out_files.append(out_name) np.savetxt(out_name, mat) return out_files def time_avg(in_file, index=[0], out_file=None): """ Average the input time-series, selecting the indices given in index .. warning:: time steps should be already registered (corrected for head motion artifacts). """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_baseline%s" % (fname, ext)) index = np.atleast_1d(index).tolist() imgs = np.array(nb.four_to_three(nb.load(in_file)))[index] if len(index) == 1: data = imgs[0].get_data().astype(np.float32) else: data = np.average(np.array([im.get_data().astype(np.float32) for im in imgs]), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(data.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(data, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file def b0_indices(in_bval, max_b=10.0): """ Extract the indices of slices in a b-values file with a low b value """ import numpy as np bval = np.loadtxt(in_bval) return np.argwhere(bval <= max_b).flatten().tolist() def b0_average(in_dwi, in_bval, max_b=10.0, out_file=None): """ A function that averages the *b0* volumes from a DWI dataset. As current dMRI data are being acquired with all b-values > 0.0, the *lowb* volumes are selected by specifying the parameter max_b. .. warning:: *b0* should be already registered (head motion artifact should be corrected). """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_avg_b0%s" % (fname, ext)) imgs = np.array(nb.four_to_three(nb.load(in_dwi))) index = b0_indices(in_bval, max_b=max_b) b0s = [im.get_data().astype(np.float32) for im in imgs[index]] b0 = np.average(np.array(b0s), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file def rotate_bvecs(in_bvec, in_matrix): """ Rotates the input bvec file accordingly with a list of matrices. .. note:: the input affine matrix transforms points in the destination image to their corresponding coordinates in the original image. Therefore, this matrix should be inverted first, as we want to know the target position of :math:`\\vec{r}`. """ import os import numpy as np name, fext = os.path.splitext(os.path.basename(in_bvec)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('%s_rotated.bvec' % name) bvecs = np.loadtxt(in_bvec).T new_bvecs = [] if len(bvecs) != len(in_matrix): raise RuntimeError(('Number of b-vectors (%d) and rotation ' 'matrices (%d) should match.') % (len(bvecs), len(in_matrix))) for bvec, mat in zip(bvecs, in_matrix): if np.all(bvec == 0.0): new_bvecs.append(bvec) else: invrot = np.linalg.inv(np.loadtxt(mat))[:3, :3] newbvec = invrot.dot(bvec) new_bvecs.append((newbvec/np.linalg.norm(newbvec))) np.savetxt(out_file, np.array(new_bvecs).T, fmt='%0.15f') return out_file def eddy_rotate_bvecs(in_bvec, eddy_params): """ Rotates the input bvec file accordingly with a list of parameters sourced from ``eddy``, as explained `here `_. """ import os import numpy as np from math import sin, cos name, fext = os.path.splitext(os.path.basename(in_bvec)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('%s_rotated.bvec' % name) bvecs = np.loadtxt(in_bvec).T new_bvecs = [] params = np.loadtxt(eddy_params) if len(bvecs) != len(params): raise RuntimeError(('Number of b-vectors and rotation ' 'matrices should match.')) for bvec, row in zip(bvecs, params): if np.all(bvec == 0.0): new_bvecs.append(bvec) else: ax = row[3] ay = row[4] az = row[5] Rx = np.array([[1.0, 0.0, 0.0], [0.0, cos(ax), -sin(ax)], [0.0, sin(ax), cos(ax)]]) Ry = np.array([[cos(ay), 0.0, sin(ay)], [0.0, 1.0, 0.0], [-sin(ay), 0.0, cos(ay)]]) Rz = np.array([[cos(az), -sin(az), 0.0], [sin(az), cos(az), 0.0], [0.0, 0.0, 1.0]]) R = Rx.dot(Ry).dot(Rz) invrot = np.linalg.inv(R) newbvec = invrot.dot(bvec) new_bvecs.append((newbvec/np.linalg.norm(newbvec))) np.savetxt(out_file, np.array(new_bvecs).T, fmt='%0.15f') return out_file def compute_readout(params): """ Computes readout time from epi params (see `eddy documentation `_). .. warning:: ``params['echospacing']`` should be in *sec* units. """ epi_factor = 1.0 acc_factor = 1.0 try: if params['epi_factor'] > 1: epi_factor = float(params['epi_factor'] - 1) except: pass try: if params['acc_factor'] > 1: acc_factor = 1.0 / params['acc_factor'] except: pass return acc_factor * epi_factor * params['echospacing'] def siemens2rads(in_file, out_file=None): """ Converts input phase difference map to rads """ import numpy as np import nibabel as nb import os.path as op import math if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_rads.nii.gz' % fname) in_file = np.atleast_1d(in_file).tolist() im = nb.load(in_file[0]) data = im.get_data().astype(np.float32) hdr = im.get_header().copy() if len(in_file) == 2: data = nb.load(in_file[1]).get_data().astype(np.float32) - data elif (data.ndim == 4) and (data.shape[-1] == 2): data = np.squeeze(data[..., 1] - data[..., 0]) hdr.set_data_shape(data.shape[:3]) imin = data.min() imax = data.max() data = (2.0 * math.pi * (data - imin)/(imax-imin)) - math.pi hdr.set_data_dtype(np.float32) hdr.set_xyzt_units('mm') hdr['datatype'] = 16 nb.Nifti1Image(data, im.get_affine(), hdr).to_filename(out_file) return out_file def rads2radsec(in_file, delta_te, out_file=None): """ Converts input phase difference map to rads """ import numpy as np import nibabel as nb import os.path as op import math if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_radsec.nii.gz' % fname) im = nb.load(in_file) data = im.get_data().astype(np.float32) * (1.0/delta_te) nb.Nifti1Image(data, im.get_affine(), im.get_header()).to_filename(out_file) return out_file def demean_image(in_file, in_mask=None, out_file=None): """ Demean image data inside mask """ import numpy as np import nibabel as nb import os.path as op import math if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_demean.nii.gz' % fname) im = nb.load(in_file) data = im.get_data().astype(np.float32) msk = np.ones_like(data) if in_mask is not None: msk = nb.load(in_mask).get_data().astype(np.float32) msk[msk > 0] = 1.0 msk[msk < 1] = 0.0 mean = np.median(data[msk == 1].reshape(-1)) data[msk == 1] = data[msk == 1] - mean nb.Nifti1Image(data, im.get_affine(), im.get_header()).to_filename(out_file) return out_file def add_empty_vol(in_file, out_file=None): """ Adds an empty vol to the phase difference image """ import nibabel as nb import os.path as op import numpy as np import math if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_4D.nii.gz' % fname) im = nb.load(in_file) zim = nb.Nifti1Image(np.zeros_like(im.get_data()), im.get_affine(), im.get_header()) nb.funcs.concat_images([im, zim]).to_filename(out_file) return out_file def reorient_bvecs(in_dwi, old_dwi, in_bvec): """ Checks reorientations of ``in_dwi`` w.r.t. ``old_dwi`` and reorients the in_bvec table accordingly. """ import os import numpy as np import nibabel as nb name, fext = os.path.splitext(os.path.basename(in_bvec)) if fext == '.gz': name, _ = os.path.splitext(name) out_file = os.path.abspath('%s_reorient.bvec' % name) bvecs = np.loadtxt(in_bvec).T new_bvecs = [] N = nb.load(in_dwi).get_affine() O = nb.load(old_dwi).get_affine() RS = N.dot(np.linalg.inv(O))[:3, :3] sc_idx = np.where((np.abs(RS) != 1) & (RS != 0)) S = np.ones_like(RS) S[sc_idx] = RS[sc_idx] R = RS/S new_bvecs = [R.dot(b) for b in bvecs] np.savetxt(out_file, np.array(new_bvecs).T, fmt='%0.15f') return out_file def copy_hdr(in_file, in_file_hdr, out_file=None): import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_fixhdr.nii.gz' % fname) imref = nb.load(in_file_hdr) hdr = imref.get_header().copy() hdr.set_data_dtype(np.float32) vsm = nb.load(in_file).get_data().astype(np.float32) hdr.set_data_shape(vsm.shape) hdr.set_xyzt_units('mm') nii = nb.Nifti1Image(vsm, imref.get_affine(), hdr) nii.to_filename(out_file) return out_file def enhance(in_file, clip_limit=0.010, in_mask=None, out_file=None): import numpy as np import nibabel as nb import os.path as op from skimage import exposure, img_as_int if out_file is None: fname, fext = op.splitext(op.basename(in_file)) if fext == '.gz': fname, _ = op.splitext(fname) out_file = op.abspath('./%s_enh.nii.gz' % fname) im = nb.load(in_file) imdata = im.get_data() imshape = im.get_shape() if in_mask is not None: msk = nb.load(in_mask).get_data() msk[msk > 0] = 1 msk[msk < 1] = 0 imdata = imdata * msk immin = imdata.min() imdata = (imdata - immin).astype(np.uint16) adapted = exposure.equalize_adapthist(imdata.reshape(imshape[0], -1), clip_limit=clip_limit) nb.Nifti1Image(adapted.reshape(imshape), im.get_affine(), im.get_header()).to_filename(out_file) return out_file def _checkinitxfm(in_bval, excl_nodiff, in_xfms=None): from nipype.interfaces.base import isdefined import numpy as np import os.path as op bvals = np.loadtxt(in_bval) gen_id = ((in_xfms is None) or (not isdefined(in_xfms)) or (len(in_xfms) != len(bvals))) init_xfms = [] if excl_nodiff: dws = np.where(bvals != 0)[0].tolist() else: dws = range(len(bvals)) if gen_id: for i in dws: xfm_file = op.abspath('init_%04d.mat' % i) np.savetxt(xfm_file, np.eye(4)) init_xfms.append(xfm_file) else: init_xfms = [in_xfms[i] for i in dws] return init_xfms nipype-0.11.0/nipype/workflows/dmri/mrtrix/000077500000000000000000000000001257611314500207235ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/dmri/mrtrix/__init__.py000066400000000000000000000002631257611314500230350ustar00rootroot00000000000000from diffusion import create_mrtrix_dti_pipeline from connectivity_mapping import create_connectivity_pipeline from group_connectivity import (create_group_connectivity_pipeline) nipype-0.11.0/nipype/workflows/dmri/mrtrix/connectivity_mapping.py000066400000000000000000000702301257611314500255300ustar00rootroot00000000000000import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.mrtrix as mrtrix import nipype.interfaces.cmtk as cmtk import nipype.interfaces.dipy as dipy import nipype.algorithms.misc as misc import inspect import os, os.path as op # system functions from ..fsl.epi import create_eddy_correct_pipeline from ..connectivity.nx import create_networkx_pipeline, create_cmats_to_csv_pipeline from nipype.interfaces.utility import Function from ...misc.utils import select_aparc_annot def create_connectivity_pipeline(name="connectivity", parcellation_name='scale500'): """Creates a pipeline that does the same connectivity processing as in the :ref:`example_dmri_connectivity_advanced` example script. Given a subject id (and completed Freesurfer reconstruction) diffusion-weighted image, b-values, and b-vectors, the workflow will return the subject's connectome as a Connectome File Format (CFF) file for use in Connectome Viewer (http://www.cmtk.org). Example ------- >>> from nipype.workflows.dmri.mrtrix.connectivity_mapping import create_connectivity_pipeline >>> conmapper = create_connectivity_pipeline("nipype_conmap") >>> conmapper.inputs.inputnode.subjects_dir = '.' >>> conmapper.inputs.inputnode.subject_id = 'subj1' >>> conmapper.inputs.inputnode.dwi = 'data.nii.gz' >>> conmapper.inputs.inputnode.bvecs = 'bvecs' >>> conmapper.inputs.inputnode.bvals = 'bvals' >>> conmapper.run() # doctest: +SKIP Inputs:: inputnode.subject_id inputnode.subjects_dir inputnode.dwi inputnode.bvecs inputnode.bvals inputnode.resolution_network_file Outputs:: outputnode.connectome outputnode.cmatrix outputnode.networks outputnode.fa outputnode.struct outputnode.tracts outputnode.rois outputnode.odfs outputnode.filtered_tractography outputnode.tdi outputnode.nxstatscff outputnode.nxcsv outputnode.cmatrices_csv outputnode.mean_fiber_length outputnode.median_fiber_length outputnode.fiber_length_std """ inputnode_within = pe.Node(util.IdentityInterface(fields=["subject_id", "dwi", "bvecs", "bvals", "subjects_dir", "resolution_network_file"]), name="inputnode_within") FreeSurferSource = pe.Node(interface=nio.FreeSurferSource(), name='fssource') FreeSurferSourceLH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceLH') FreeSurferSourceLH.inputs.hemi = 'lh' FreeSurferSourceRH = pe.Node(interface=nio.FreeSurferSource(), name='fssourceRH') FreeSurferSourceRH.inputs.hemi = 'rh' """ Creating the workflow's nodes ============================= """ """ Conversion nodes ---------------- """ """ A number of conversion operations are required to obtain NIFTI files from the FreesurferSource for each subject. Nodes are used to convert the following: * Original structural image to NIFTI * Pial, white, inflated, and spherical surfaces for both the left and right hemispheres are converted to GIFTI for visualization in ConnectomeViewer * Parcellated annotation files for the left and right hemispheres are also converted to GIFTI """ mri_convert_Brain = pe.Node(interface=fs.MRIConvert(), name='mri_convert_Brain') mri_convert_Brain.inputs.out_type = 'nii' mri_convert_ROI_scale500 = mri_convert_Brain.clone('mri_convert_ROI_scale500') mris_convertLH = pe.Node(interface=fs.MRIsConvert(), name='mris_convertLH') mris_convertLH.inputs.out_datatype = 'gii' mris_convertRH = mris_convertLH.clone('mris_convertRH') mris_convertRHwhite = mris_convertLH.clone('mris_convertRHwhite') mris_convertLHwhite = mris_convertLH.clone('mris_convertLHwhite') mris_convertRHinflated = mris_convertLH.clone('mris_convertRHinflated') mris_convertLHinflated = mris_convertLH.clone('mris_convertLHinflated') mris_convertRHsphere = mris_convertLH.clone('mris_convertRHsphere') mris_convertLHsphere = mris_convertLH.clone('mris_convertLHsphere') mris_convertLHlabels = mris_convertLH.clone('mris_convertLHlabels') mris_convertRHlabels = mris_convertLH.clone('mris_convertRHlabels') """ Diffusion processing nodes -------------------------- .. seealso:: dmri_mrtrix_dti.py Tutorial that focuses solely on the MRtrix diffusion processing http://www.brain.org.au/software/mrtrix/index.html MRtrix's online documentation """ """ b-values and b-vectors stored in FSL's format are converted into a single encoding file for MRTrix. """ fsl2mrtrix = pe.Node(interface=mrtrix.FSL2MRTrix(),name='fsl2mrtrix') """ Distortions induced by eddy currents are corrected prior to fitting the tensors. The first image is used as a reference for which to warp the others. """ eddycorrect = create_eddy_correct_pipeline(name='eddycorrect') eddycorrect.inputs.inputnode.ref_num = 1 """ Tensors are fitted to each voxel in the diffusion-weighted image and from these three maps are created: * Major eigenvector in each voxel * Apparent diffusion coefficient * Fractional anisotropy """ dwi2tensor = pe.Node(interface=mrtrix.DWI2Tensor(),name='dwi2tensor') tensor2vector = pe.Node(interface=mrtrix.Tensor2Vector(),name='tensor2vector') tensor2adc = pe.Node(interface=mrtrix.Tensor2ApparentDiffusion(),name='tensor2adc') tensor2fa = pe.Node(interface=mrtrix.Tensor2FractionalAnisotropy(),name='tensor2fa') MRconvert_fa = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert_fa') MRconvert_fa.inputs.extension = 'nii' """ These nodes are used to create a rough brain mask from the b0 image. The b0 image is extracted from the original diffusion-weighted image, put through a simple thresholding routine, and smoothed using a 3x3 median filter. """ MRconvert = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert') MRconvert.inputs.extract_at_axis = 3 MRconvert.inputs.extract_at_coordinate = [0] threshold_b0 = pe.Node(interface=mrtrix.Threshold(),name='threshold_b0') median3d = pe.Node(interface=mrtrix.MedianFilter3D(),name='median3d') """ The brain mask is also used to help identify single-fiber voxels. This is done by passing the brain mask through two erosion steps, multiplying the remaining mask with the fractional anisotropy map, and thresholding the result to obtain some highly anisotropic within-brain voxels. """ erode_mask_firstpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_firstpass') erode_mask_secondpass = pe.Node(interface=mrtrix.Erode(),name='erode_mask_secondpass') MRmultiply = pe.Node(interface=mrtrix.MRMultiply(),name='MRmultiply') MRmult_merge = pe.Node(interface=util.Merge(2), name='MRmultiply_merge') threshold_FA = pe.Node(interface=mrtrix.Threshold(),name='threshold_FA') threshold_FA.inputs.absolute_threshold_value = 0.7 """ For whole-brain tracking we also require a broad white-matter seed mask. This is created by generating a white matter mask, given a brainmask, and thresholding it at a reasonably high level. """ bet = pe.Node(interface=fsl.BET(mask = True), name = 'bet_b0') gen_WM_mask = pe.Node(interface=mrtrix.GenerateWhiteMatterMask(),name='gen_WM_mask') threshold_wmmask = pe.Node(interface=mrtrix.Threshold(),name='threshold_wmmask') threshold_wmmask.inputs.absolute_threshold_value = 0.4 """ The spherical deconvolution step depends on the estimate of the response function in the highly anisotropic voxels we obtained above. .. warning:: For damaged or pathological brains one should take care to lower the maximum harmonic order of these steps. """ estimateresponse = pe.Node(interface=mrtrix.EstimateResponseForSH(),name='estimateresponse') estimateresponse.inputs.maximum_harmonic_order = 6 csdeconv = pe.Node(interface=mrtrix.ConstrainedSphericalDeconvolution(),name='csdeconv') csdeconv.inputs.maximum_harmonic_order = 6 """ Finally, we track probabilistically using the orientation distribution functions obtained earlier. The tracts are then used to generate a tract-density image, and they are also converted to TrackVis format. """ probCSDstreamtrack = pe.Node(interface=mrtrix.ProbabilisticSphericallyDeconvolutedStreamlineTrack(),name='probCSDstreamtrack') probCSDstreamtrack.inputs.inputmodel = 'SD_PROB' probCSDstreamtrack.inputs.desired_number_of_tracks = 150000 tracks2prob = pe.Node(interface=mrtrix.Tracks2Prob(),name='tracks2prob') tracks2prob.inputs.colour = True MRconvert_tracks2prob = MRconvert_fa.clone(name='MRconvert_tracks2prob') tck2trk = pe.Node(interface=mrtrix.MRTrix2TrackVis(),name='tck2trk') trk2tdi = pe.Node(interface=dipy.TrackDensityMap(),name='trk2tdi') """ Structural segmentation nodes ----------------------------- """ """ The following node identifies the transformation between the diffusion-weighted image and the structural image. This transformation is then applied to the tracts so that they are in the same space as the regions of interest. """ coregister = pe.Node(interface=fsl.FLIRT(dof=6), name = 'coregister') coregister.inputs.cost = ('normmi') """ Parcellation is performed given the aparc+aseg image from Freesurfer. The CMTK Parcellation step subdivides these regions to return a higher-resolution parcellation scheme. The parcellation used here is entitled "scale500" and returns 1015 regions. """ parcellate = pe.Node(interface=cmtk.Parcellate(), name="Parcellate") parcellate.inputs.parcellation_name = parcellation_name """ The CreateMatrix interface takes in the remapped aparc+aseg image as well as the label dictionary and fiber tracts and outputs a number of different files. The most important of which is the connectivity network itself, which is stored as a 'gpickle' and can be loaded using Python's NetworkX package (see CreateMatrix docstring). Also outputted are various NumPy arrays containing detailed tract information, such as the start and endpoint regions, and statistics on the mean and standard deviation for the fiber length of each connection. These matrices can be used in the ConnectomeViewer to plot the specific tracts that connect between user-selected regions. Here we choose the Lausanne2008 parcellation scheme, since we are incorporating the CMTK parcellation step. """ creatematrix = pe.Node(interface=cmtk.CreateMatrix(), name="CreateMatrix") creatematrix.inputs.count_region_intersections = True """ Next we define the endpoint of this tutorial, which is the CFFConverter node, as well as a few nodes which use the Nipype Merge utility. These are useful for passing lists of the files we want packaged in our CFF file. The inspect.getfile command is used to package this script into the resulting CFF file, so that it is easy to look back at the processing parameters that were used. """ CFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="CFFConverter") CFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) giftiSurfaces = pe.Node(interface=util.Merge(8), name="GiftiSurfaces") giftiLabels = pe.Node(interface=util.Merge(2), name="GiftiLabels") niftiVolumes = pe.Node(interface=util.Merge(3), name="NiftiVolumes") fiberDataArrays = pe.Node(interface=util.Merge(4), name="FiberDataArrays") """ We also create a node to calculate several network metrics on our resulting file, and another CFF converter which will be used to package these networks into a single file. """ networkx = create_networkx_pipeline(name='networkx') cmats_to_csv = create_cmats_to_csv_pipeline(name='cmats_to_csv') nfibs_to_csv = pe.Node(interface=misc.Matlab2CSV(), name='nfibs_to_csv') merge_nfib_csvs = pe.Node(interface=misc.MergeCSVFiles(), name='merge_nfib_csvs') merge_nfib_csvs.inputs.extra_column_heading = 'Subject' merge_nfib_csvs.inputs.out_file = 'fibers.csv' NxStatsCFFConverter = pe.Node(interface=cmtk.CFFConverter(), name="NxStatsCFFConverter") NxStatsCFFConverter.inputs.script_files = op.abspath(inspect.getfile(inspect.currentframe())) """ Connecting the workflow ======================= Here we connect our processing pipeline. """ """ Connecting the inputs, FreeSurfer nodes, and conversions -------------------------------------------------------- """ mapping = pe.Workflow(name='mapping') """ First, we connect the input node to the FreeSurfer input nodes. """ mapping.connect([(inputnode_within, FreeSurferSource,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSource,[("subject_id","subject_id")])]) mapping.connect([(inputnode_within, FreeSurferSourceLH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSourceLH,[("subject_id","subject_id")])]) mapping.connect([(inputnode_within, FreeSurferSourceRH,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, FreeSurferSourceRH,[("subject_id","subject_id")])]) mapping.connect([(inputnode_within, parcellate,[("subjects_dir","subjects_dir")])]) mapping.connect([(inputnode_within, parcellate,[("subject_id","subject_id")])]) mapping.connect([(parcellate, mri_convert_ROI_scale500,[('roi_file','in_file')])]) """ Nifti conversion for subject's stripped brain image from Freesurfer: """ mapping.connect([(FreeSurferSource, mri_convert_Brain,[('brain','in_file')])]) """ Surface conversions to GIFTI (pial, white, inflated, and sphere for both hemispheres) """ mapping.connect([(FreeSurferSourceLH, mris_convertLH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRH,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHwhite,[('white','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHinflated,[('inflated','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHsphere,[('sphere','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHsphere,[('sphere','in_file')])]) """ The annotation files are converted using the pial surface as a map via the MRIsConvert interface. One of the functions defined earlier is used to select the lh.aparc.annot and rh.aparc.annot files specifically (rather than e.g. rh.aparc.a2009s.annot) from the output list given by the FreeSurferSource. """ mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels,[('pial','in_file')])]) mapping.connect([(FreeSurferSourceLH, mris_convertLHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) mapping.connect([(FreeSurferSourceRH, mris_convertRHlabels, [(('annot', select_aparc_annot), 'annot_file')])]) """ Diffusion Processing -------------------- Now we connect the tensor computations: """ mapping.connect([(inputnode_within, fsl2mrtrix, [("bvecs", "bvec_file"), ("bvals", "bval_file")])]) mapping.connect([(inputnode_within, eddycorrect,[("dwi","inputnode.in_file")])]) mapping.connect([(eddycorrect, dwi2tensor,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(fsl2mrtrix, dwi2tensor,[("encoding_file","encoding_file")])]) mapping.connect([(dwi2tensor, tensor2vector,[['tensor','in_file']]), (dwi2tensor, tensor2adc,[['tensor','in_file']]), (dwi2tensor, tensor2fa,[['tensor','in_file']]), ]) mapping.connect([(tensor2fa, MRmult_merge,[("FA","in1")])]) mapping.connect([(tensor2fa, MRconvert_fa,[("FA","in_file")])]) """ This block creates the rough brain mask to be multiplied, mulitplies it with the fractional anisotropy image, and thresholds it to get the single-fiber voxels. """ mapping.connect([(eddycorrect, MRconvert,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(MRconvert, threshold_b0,[("converted","in_file")])]) mapping.connect([(threshold_b0, median3d,[("out_file","in_file")])]) mapping.connect([(median3d, erode_mask_firstpass,[("out_file","in_file")])]) mapping.connect([(erode_mask_firstpass, erode_mask_secondpass,[("out_file","in_file")])]) mapping.connect([(erode_mask_secondpass, MRmult_merge,[("out_file","in2")])]) mapping.connect([(MRmult_merge, MRmultiply,[("out","in_files")])]) mapping.connect([(MRmultiply, threshold_FA,[("out_file","in_file")])]) """ Here the thresholded white matter mask is created for seeding the tractography. """ mapping.connect([(eddycorrect, bet,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(eddycorrect, gen_WM_mask,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(bet, gen_WM_mask,[("mask_file","binary_mask")])]) mapping.connect([(fsl2mrtrix, gen_WM_mask,[("encoding_file","encoding_file")])]) mapping.connect([(gen_WM_mask, threshold_wmmask,[("WMprobabilitymap","in_file")])]) """ Next we estimate the fiber response distribution. """ mapping.connect([(eddycorrect, estimateresponse,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(fsl2mrtrix, estimateresponse,[("encoding_file","encoding_file")])]) mapping.connect([(threshold_FA, estimateresponse,[("out_file","mask_image")])]) """ Run constrained spherical deconvolution. """ mapping.connect([(eddycorrect, csdeconv,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(gen_WM_mask, csdeconv,[("WMprobabilitymap","mask_image")])]) mapping.connect([(estimateresponse, csdeconv,[("response","response_file")])]) mapping.connect([(fsl2mrtrix, csdeconv,[("encoding_file","encoding_file")])]) """ Connect the tractography and compute the tract density image. """ mapping.connect([(threshold_wmmask, probCSDstreamtrack,[("out_file","seed_file")])]) mapping.connect([(csdeconv, probCSDstreamtrack,[("spherical_harmonics_image","in_file")])]) mapping.connect([(probCSDstreamtrack, tracks2prob,[("tracked","in_file")])]) mapping.connect([(eddycorrect, tracks2prob,[("outputnode.eddy_corrected","template_file")])]) mapping.connect([(tracks2prob, MRconvert_tracks2prob,[("tract_image","in_file")])]) """ Structural Processing --------------------- First, we coregister the diffusion image to the structural image """ mapping.connect([(eddycorrect, coregister,[("outputnode.eddy_corrected","in_file")])]) mapping.connect([(mri_convert_Brain, coregister,[('out_file','reference')])]) """ The MRtrix-tracked fibers are converted to TrackVis format (with voxel and data dimensions grabbed from the DWI). The connectivity matrix is created with the transformed .trk fibers and the parcellation file. """ mapping.connect([(eddycorrect, tck2trk,[("outputnode.eddy_corrected","image_file")])]) mapping.connect([(mri_convert_Brain, tck2trk,[("out_file","registration_image_file")])]) mapping.connect([(coregister, tck2trk,[("out_matrix_file","matrix_file")])]) mapping.connect([(probCSDstreamtrack, tck2trk,[("tracked","in_file")])]) mapping.connect([(tck2trk, creatematrix,[("out_file","tract_file")])]) mapping.connect([(tck2trk, trk2tdi,[("out_file","in_file")])]) mapping.connect(inputnode_within, 'resolution_network_file', creatematrix, 'resolution_network_file') mapping.connect([(inputnode_within, creatematrix,[("subject_id","out_matrix_file")])]) mapping.connect([(inputnode_within, creatematrix,[("subject_id","out_matrix_mat_file")])]) mapping.connect([(parcellate, creatematrix,[("roi_file","roi_file")])]) """ The merge nodes defined earlier are used here to create lists of the files which are destined for the CFFConverter. """ mapping.connect([(mris_convertLH, giftiSurfaces,[("converted","in1")])]) mapping.connect([(mris_convertRH, giftiSurfaces,[("converted","in2")])]) mapping.connect([(mris_convertLHwhite, giftiSurfaces,[("converted","in3")])]) mapping.connect([(mris_convertRHwhite, giftiSurfaces,[("converted","in4")])]) mapping.connect([(mris_convertLHinflated, giftiSurfaces,[("converted","in5")])]) mapping.connect([(mris_convertRHinflated, giftiSurfaces,[("converted","in6")])]) mapping.connect([(mris_convertLHsphere, giftiSurfaces,[("converted","in7")])]) mapping.connect([(mris_convertRHsphere, giftiSurfaces,[("converted","in8")])]) mapping.connect([(mris_convertLHlabels, giftiLabels,[("converted","in1")])]) mapping.connect([(mris_convertRHlabels, giftiLabels,[("converted","in2")])]) mapping.connect([(parcellate, niftiVolumes,[("roi_file","in1")])]) mapping.connect([(eddycorrect, niftiVolumes,[("outputnode.eddy_corrected","in2")])]) mapping.connect([(mri_convert_Brain, niftiVolumes,[("out_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file","in1")])]) mapping.connect([(creatematrix, fiberDataArrays,[("endpoint_file_mm","in2")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_length_file","in3")])]) mapping.connect([(creatematrix, fiberDataArrays,[("fiber_label_file","in4")])]) """ This block actually connects the merged lists to the CFF converter. We pass the surfaces and volumes that are to be included, as well as the tracts and the network itself. The currently running pipeline (dmri_connectivity_advanced.py) is also scraped and included in the CFF file. This makes it easy for the user to examine the entire processing pathway used to generate the end product. """ mapping.connect([(giftiSurfaces, CFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, CFFConverter,[("out","gifti_labels")])]) mapping.connect([(creatematrix, CFFConverter,[("matrix_files","gpickled_networks")])]) mapping.connect([(niftiVolumes, CFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, CFFConverter,[("out","data_files")])]) mapping.connect([(creatematrix, CFFConverter,[("filtered_tractography","tract_files")])]) mapping.connect([(inputnode_within, CFFConverter,[("subject_id","title")])]) """ The graph theoretical metrics which have been generated are placed into another CFF file. """ mapping.connect([(inputnode_within, networkx,[("subject_id","inputnode.extra_field")])]) mapping.connect([(creatematrix, networkx,[("intersection_matrix_file","inputnode.network_file")])]) mapping.connect([(networkx, NxStatsCFFConverter,[("outputnode.network_files","gpickled_networks")])]) mapping.connect([(giftiSurfaces, NxStatsCFFConverter,[("out","gifti_surfaces")])]) mapping.connect([(giftiLabels, NxStatsCFFConverter,[("out","gifti_labels")])]) mapping.connect([(niftiVolumes, NxStatsCFFConverter,[("out","nifti_volumes")])]) mapping.connect([(fiberDataArrays, NxStatsCFFConverter,[("out","data_files")])]) mapping.connect([(inputnode_within, NxStatsCFFConverter,[("subject_id","title")])]) mapping.connect([(inputnode_within, cmats_to_csv,[("subject_id","inputnode.extra_field")])]) mapping.connect([(creatematrix, cmats_to_csv,[("matlab_matrix_files","inputnode.matlab_matrix_files")])]) mapping.connect([(creatematrix, nfibs_to_csv,[("stats_file","in_file")])]) mapping.connect([(nfibs_to_csv, merge_nfib_csvs,[("csv_files","in_files")])]) mapping.connect([(inputnode_within, merge_nfib_csvs,[("subject_id","extra_field")])]) """ Create a higher-level workflow -------------------------------------- Finally, we create another higher-level workflow to connect our mapping workflow with the info and datagrabbing nodes declared at the beginning. Our tutorial can is now extensible to any arbitrary number of subjects by simply adding their names to the subject list and their data to the proper folders. """ inputnode = pe.Node(interface=util.IdentityInterface(fields=["subject_id", "dwi", "bvecs", "bvals", "subjects_dir"]), name="inputnode") outputnode = pe.Node(interface = util.IdentityInterface(fields=["fa", "struct", "tracts", "tracks2prob", "connectome", "nxstatscff", "nxmatlab", "nxcsv", "fiber_csv", "cmatrices_csv", "nxmergedcsv", "cmatrix", "networks", "filtered_tracts", "rois", "odfs", "tdi", "mean_fiber_length", "median_fiber_length", "fiber_length_std"]), name="outputnode") connectivity = pe.Workflow(name="connectivity") connectivity.base_output_dir=name connectivity.base_dir=name connectivity.connect([(inputnode, mapping, [("dwi", "inputnode_within.dwi"), ("bvals", "inputnode_within.bvals"), ("bvecs", "inputnode_within.bvecs"), ("subject_id", "inputnode_within.subject_id"), ("subjects_dir", "inputnode_within.subjects_dir")]) ]) connectivity.connect([(mapping, outputnode, [("tck2trk.out_file", "tracts"), ("CFFConverter.connectome_file", "connectome"), ("NxStatsCFFConverter.connectome_file", "nxstatscff"), ("CreateMatrix.matrix_mat_file", "cmatrix"), ("CreateMatrix.mean_fiber_length_matrix_mat_file", "mean_fiber_length"), ("CreateMatrix.median_fiber_length_matrix_mat_file", "median_fiber_length"), ("CreateMatrix.fiber_length_std_matrix_mat_file", "fiber_length_std"), ("CreateMatrix.matrix_files", "networks"), ("CreateMatrix.filtered_tractographies", "filtered_tracts"), ("merge_nfib_csvs.csv_file", "fiber_csv"), ("mri_convert_ROI_scale500.out_file", "rois"), ("trk2tdi.out_file", "tdi"), ("csdeconv.spherical_harmonics_image", "odfs"), ("mri_convert_Brain.out_file", "struct"), ("MRconvert_fa.converted", "fa"), ("MRconvert_tracks2prob.converted", "tracks2prob")]) ]) connectivity.connect([(cmats_to_csv, outputnode,[("outputnode.csv_file","cmatrices_csv")])]) connectivity.connect([(networkx, outputnode,[("outputnode.csv_files","nxcsv")])]) return connectivity nipype-0.11.0/nipype/workflows/dmri/mrtrix/diffusion.py000066400000000000000000000166401257611314500232720ustar00rootroot00000000000000import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.fsl as fsl import nipype.interfaces.mrtrix as mrtrix def create_mrtrix_dti_pipeline(name="dtiproc", tractography_type = 'probabilistic'): """Creates a pipeline that does the same diffusion processing as in the :doc:`../../users/examples/dmri_mrtrix_dti` example script. Given a diffusion-weighted image, b-values, and b-vectors, the workflow will return the tractography computed from spherical deconvolution and probabilistic streamline tractography Example ------- >>> dti = create_mrtrix_dti_pipeline("mrtrix_dti") >>> dti.inputs.inputnode.dwi = 'data.nii' >>> dti.inputs.inputnode.bvals = 'bvals' >>> dti.inputs.inputnode.bvecs = 'bvecs' >>> dti.run() # doctest: +SKIP Inputs:: inputnode.dwi inputnode.bvecs inputnode.bvals Outputs:: outputnode.fa outputnode.tdi outputnode.tracts_tck outputnode.tracts_trk outputnode.csdeconv """ inputnode = pe.Node(interface = util.IdentityInterface(fields=["dwi", "bvecs", "bvals"]), name="inputnode") bet = pe.Node(interface=fsl.BET(), name="bet") bet.inputs.mask = True fsl2mrtrix = pe.Node(interface=mrtrix.FSL2MRTrix(),name='fsl2mrtrix') fsl2mrtrix.inputs.invert_y = True dwi2tensor = pe.Node(interface=mrtrix.DWI2Tensor(),name='dwi2tensor') tensor2vector = pe.Node(interface=mrtrix.Tensor2Vector(), name='tensor2vector') tensor2adc = pe.Node(interface=mrtrix.Tensor2ApparentDiffusion(), name='tensor2adc') tensor2fa = pe.Node(interface=mrtrix.Tensor2FractionalAnisotropy(), name='tensor2fa') erode_mask_firstpass = pe.Node(interface=mrtrix.Erode(), name='erode_mask_firstpass') erode_mask_secondpass = pe.Node(interface=mrtrix.Erode(), name='erode_mask_secondpass') threshold_b0 = pe.Node(interface=mrtrix.Threshold(),name='threshold_b0') threshold_FA = pe.Node(interface=mrtrix.Threshold(),name='threshold_FA') threshold_FA.inputs.absolute_threshold_value = 0.7 threshold_wmmask = pe.Node(interface=mrtrix.Threshold(), name='threshold_wmmask') threshold_wmmask.inputs.absolute_threshold_value = 0.4 MRmultiply = pe.Node(interface=mrtrix.MRMultiply(),name='MRmultiply') MRmult_merge = pe.Node(interface=util.Merge(2), name='MRmultiply_merge') median3d = pe.Node(interface=mrtrix.MedianFilter3D(),name='median3D') MRconvert = pe.Node(interface=mrtrix.MRConvert(),name='MRconvert') MRconvert.inputs.extract_at_axis = 3 MRconvert.inputs.extract_at_coordinate = [0] csdeconv = pe.Node(interface=mrtrix.ConstrainedSphericalDeconvolution(), name='csdeconv') gen_WM_mask = pe.Node(interface=mrtrix.GenerateWhiteMatterMask(), name='gen_WM_mask') estimateresponse = pe.Node(interface=mrtrix.EstimateResponseForSH(), name='estimateresponse') if tractography_type == 'probabilistic': CSDstreamtrack = pe.Node(interface=mrtrix.ProbabilisticSphericallyDeconvolutedStreamlineTrack(), name='CSDstreamtrack') else: CSDstreamtrack = pe.Node(interface=mrtrix.SphericallyDeconvolutedStreamlineTrack(), name='CSDstreamtrack') CSDstreamtrack.inputs.desired_number_of_tracks = 15000 tracks2prob = pe.Node(interface=mrtrix.Tracks2Prob(),name='tracks2prob') tracks2prob.inputs.colour = True tck2trk = pe.Node(interface=mrtrix.MRTrix2TrackVis(),name='tck2trk') workflow = pe.Workflow(name=name) workflow.base_output_dir=name workflow.connect([(inputnode, fsl2mrtrix, [("bvecs", "bvec_file"), ("bvals", "bval_file")])]) workflow.connect([(inputnode, dwi2tensor,[("dwi","in_file")])]) workflow.connect([(fsl2mrtrix, dwi2tensor,[("encoding_file","encoding_file")])]) workflow.connect([(dwi2tensor, tensor2vector,[['tensor','in_file']]), (dwi2tensor, tensor2adc,[['tensor','in_file']]), (dwi2tensor, tensor2fa,[['tensor','in_file']]), ]) workflow.connect([(inputnode, MRconvert,[("dwi","in_file")])]) workflow.connect([(MRconvert, threshold_b0,[("converted","in_file")])]) workflow.connect([(threshold_b0, median3d,[("out_file","in_file")])]) workflow.connect([(median3d, erode_mask_firstpass,[("out_file","in_file")])]) workflow.connect([(erode_mask_firstpass, erode_mask_secondpass,[("out_file","in_file")])]) workflow.connect([(tensor2fa, MRmult_merge,[("FA","in1")])]) workflow.connect([(erode_mask_secondpass, MRmult_merge,[("out_file","in2")])]) workflow.connect([(MRmult_merge, MRmultiply,[("out","in_files")])]) workflow.connect([(MRmultiply, threshold_FA,[("out_file","in_file")])]) workflow.connect([(threshold_FA, estimateresponse,[("out_file","mask_image")])]) workflow.connect([(inputnode, bet,[("dwi","in_file")])]) workflow.connect([(inputnode, gen_WM_mask,[("dwi","in_file")])]) workflow.connect([(bet, gen_WM_mask,[("mask_file","binary_mask")])]) workflow.connect([(fsl2mrtrix, gen_WM_mask,[("encoding_file","encoding_file")])]) workflow.connect([(inputnode, estimateresponse,[("dwi","in_file")])]) workflow.connect([(fsl2mrtrix, estimateresponse,[("encoding_file","encoding_file")])]) workflow.connect([(inputnode, csdeconv,[("dwi","in_file")])]) workflow.connect([(gen_WM_mask, csdeconv,[("WMprobabilitymap","mask_image")])]) workflow.connect([(estimateresponse, csdeconv,[("response","response_file")])]) workflow.connect([(fsl2mrtrix, csdeconv,[("encoding_file","encoding_file")])]) workflow.connect([(gen_WM_mask, threshold_wmmask,[("WMprobabilitymap","in_file")])]) workflow.connect([(threshold_wmmask, CSDstreamtrack,[("out_file","seed_file")])]) workflow.connect([(csdeconv, CSDstreamtrack,[("spherical_harmonics_image","in_file")])]) if tractography_type == 'probabilistic': workflow.connect([(CSDstreamtrack, tracks2prob,[("tracked","in_file")])]) workflow.connect([(inputnode, tracks2prob,[("dwi","template_file")])]) workflow.connect([(CSDstreamtrack, tck2trk,[("tracked","in_file")])]) workflow.connect([(inputnode, tck2trk,[("dwi","image_file")])]) output_fields = ["fa", "tracts_trk", "csdeconv", "tracts_tck"] if tractography_type == 'probabilistic': output_fields.append("tdi") outputnode = pe.Node(interface = util.IdentityInterface(fields=output_fields), name="outputnode") workflow.connect([(CSDstreamtrack, outputnode, [("tracked", "tracts_tck")]), (csdeconv, outputnode, [("spherical_harmonics_image", "csdeconv")]), (tensor2fa, outputnode, [("FA", "fa")]), (tck2trk, outputnode, [("out_file", "tracts_trk")]) ]) if tractography_type == 'probabilistic': workflow.connect([(tracks2prob, outputnode, [("tract_image", "tdi")])]) return workflow nipype-0.11.0/nipype/workflows/dmri/mrtrix/group_connectivity.py000066400000000000000000000146431257611314500252370ustar00rootroot00000000000000import os.path as op import nipype.interfaces.io as nio # Data i/o import nipype.interfaces.utility as util # utility import nipype.interfaces.cmtk as cmtk import nipype.algorithms.misc as misc import nipype.pipeline.engine as pe # pypeline engine from .connectivity_mapping import create_connectivity_pipeline from nipype.utils.misc import package_check import warnings try: package_check('cmp') except Exception, e: warnings.warn('cmp not installed') else: import cmp def create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, template_args_dict=0): """Creates a pipeline that performs MRtrix structural connectivity processing on groups of subjects. Given a diffusion-weighted image, and text files containing the associated b-values and b-vectors, the workflow will return each subjects' connectomes in a Connectome File Format (CFF) file, for use in Connectome Viewer (http://www.cmtk.org). Example ------- >>> import nipype.interfaces.freesurfer as fs >>> import nipype.workflows.dmri.mrtrix.group_connectivity as groupwork >>> import cmp # doctest: +SKIP >>> from nipype.testing import example_data >>> subjects_dir = '.' >>> data_dir = '.' >>> output_dir = '.' >>> fs.FSCommand.set_default_subjects_dir(subjects_dir) >>> group_list = {} >>> group_list['group1'] = ['subj1', 'subj2'] >>> group_list['group2'] = ['subj3', 'subj4'] >>> template_args = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id', 'bvecs']], bvals=[['subject_id', 'bvals']]) >>> group_id = 'group1' >>> l1pipeline = groupwork.create_group_connectivity_pipeline(group_list, group_id, data_dir, subjects_dir, output_dir, template_args) >>> parcellation_name = 'scale500' >>> l1pipeline.inputs.connectivity.mapping.Parcellate.parcellation_name = parcellation_name >>> cmp_config = cmp.configuration.PipelineConfiguration() # doctest: +SKIP >>> cmp_config.parcellation_scheme = "Lausanne2008" # doctest: +SKIP >>> l1pipeline.inputs.connectivity.mapping.inputnode_within.resolution_network_file = cmp_config._get_lausanne_parcellation('Lausanne2008')[parcellation_name]['node_information_graphml'] # doctest: +SKIP >>> l1pipeline.run() # doctest: +SKIP Inputs:: group_list: Dictionary of subject lists, keyed by group name group_id: String containing the group name data_dir: Path to the data directory subjects_dir: Path to the Freesurfer 'subjects' directory output_dir: Path for the output files template_args_dict: Dictionary of template arguments for the connectivity pipeline datasource e.g. info = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) """ group_infosource = pe.Node(interface=util.IdentityInterface(fields=['group_id']), name="group_infosource") group_infosource.inputs.group_id = group_id subject_list = group_list[group_id] subj_infosource = pe.Node(interface=util.IdentityInterface(fields=['subject_id']), name="subj_infosource") subj_infosource.iterables = ('subject_id', subject_list) if template_args_dict == 0: info = dict(dwi=[['subject_id', 'dwi']], bvecs=[['subject_id','bvecs']], bvals=[['subject_id','bvals']]) else: info = template_args_dict datasource = pe.Node(interface=nio.DataGrabber(infields=['subject_id'], outfields=info.keys()), name = 'datasource') datasource.inputs.template = "%s/%s" datasource.inputs.base_directory = data_dir datasource.inputs.field_template = dict(dwi='%s/%s.nii') datasource.inputs.template_args = info datasource.inputs.sort_filelist = True """ Create a connectivity mapping workflow """ conmapper = create_connectivity_pipeline("nipype_conmap") conmapper.inputs.inputnode.subjects_dir = subjects_dir conmapper.base_dir = op.abspath('conmapper') datasink = pe.Node(interface=nio.DataSink(), name="datasink") datasink.inputs.base_directory = output_dir datasink.inputs.container = group_id l1pipeline = pe.Workflow(name="l1pipeline_"+group_id) l1pipeline.base_dir = output_dir l1pipeline.base_output_dir = group_id l1pipeline.connect([(subj_infosource, conmapper,[('subject_id', 'inputnode.subject_id')])]) l1pipeline.connect([(subj_infosource, datasource,[('subject_id', 'subject_id')])]) l1pipeline.connect([(datasource, conmapper, [("dwi", "inputnode.dwi"), ("bvals", "inputnode.bvals"), ("bvecs", "inputnode.bvecs"), ])]) l1pipeline.connect([(conmapper, datasink, [("outputnode.connectome", "@l1output.cff"), ("outputnode.nxstatscff", "@l1output.nxstatscff"), ("outputnode.nxmatlab", "@l1output.nxmatlab"), ("outputnode.nxcsv", "@l1output.nxcsv"), ("outputnode.fiber_csv", "@l1output.fiber_csv"), ("outputnode.cmatrices_csv", "@l1output.cmatrices_csv"), ("outputnode.fa", "@l1output.fa"), ("outputnode.filtered_tracts", "@l1output.filtered_tracts"), ("outputnode.cmatrix", "@l1output.cmatrix"), ("outputnode.rois", "@l1output.rois"), ("outputnode.odfs", "@l1output.odfs"), ("outputnode.struct", "@l1output.struct"), ("outputnode.networks", "@l1output.networks"), ("outputnode.mean_fiber_length", "@l1output.mean_fiber_length"), ("outputnode.fiber_length_std", "@l1output.fiber_length_std"), ])]) l1pipeline.connect([(group_infosource, datasink,[('group_id','@group_id')])]) return l1pipeline nipype-0.11.0/nipype/workflows/fmri/000077500000000000000000000000001257611314500174005ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/fmri/__init__.py000066400000000000000000000000271257611314500215100ustar00rootroot00000000000000from . import fsl, spm nipype-0.11.0/nipype/workflows/fmri/fsl/000077500000000000000000000000001257611314500201645ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/fmri/fsl/__init__.py000066400000000000000000000005351257611314500223000ustar00rootroot00000000000000from .preprocess import (create_susan_smooth, create_fsl_fs_preproc, create_parallelfeat_preproc, create_featreg_preproc, create_reg_workflow) from .estimate import create_modelfit_workflow, create_fixed_effects_flow #backwards compatibility from ...rsfmri.fsl.resting import create_resting_preprocnipype-0.11.0/nipype/workflows/fmri/fsl/estimate.py000066400000000000000000000303521257611314500223540ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine from nipype import LooseVersion def create_modelfit_workflow(name='modelfit', f_contrasts=False): """Create an FSL individual modelfitting workflow Example ------- >>> modelfit = create_modelfit_workflow() >>> modelfit.base_dir = '.' >>> info = dict() >>> modelfit.inputs.inputspec.session_info = info >>> modelfit.inputs.inputspec.interscan_interval = 3. >>> modelfit.inputs.inputspec.film_threshold = 1000 >>> modelfit.run() #doctest: +SKIP Inputs:: inputspec.session_info : info generated by modelgen.SpecifyModel inputspec.interscan_interval : interscan interval inputspec.contrasts : list of contrasts inputspec.film_threshold : image threshold for FILM estimation inputspec.model_serial_correlations inputspec.bases Outputs:: outputspec.copes outputspec.varcopes outputspec.dof_file outputspec.pfiles outputspec.zfiles outputspec.parameter_estimates """ version = 0 if fsl.Info.version() and \ LooseVersion(fsl.Info.version()) > LooseVersion('5.0.6'): version = 507 modelfit = pe.Workflow(name=name) """ Create the nodes """ inputspec = pe.Node(util.IdentityInterface(fields=['session_info', 'interscan_interval', 'contrasts', 'film_threshold', 'functional_data', 'bases', 'model_serial_correlations']), name='inputspec') level1design = pe.Node(interface=fsl.Level1Design(), name="level1design") modelgen = pe.MapNode(interface=fsl.FEATModel(), name='modelgen', iterfield=['fsf_file', 'ev_files']) if version < 507: modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True, mask_size=5), name='modelestimate', iterfield=['design_file', 'in_file']) else: if f_contrasts: iterfield = ['design_file', 'in_file', 'tcon_file', 'fcon_file'] else: iterfield = ['design_file', 'in_file', 'tcon_file'] modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True, mask_size=5), name='modelestimate', iterfield=iterfield) if version < 507: if f_contrasts: iterfield = ['tcon_file', 'fcon_file', 'param_estimates', 'sigmasquareds', 'corrections', 'dof_file'] else: iterfield = ['tcon_file', 'param_estimates', 'sigmasquareds', 'corrections', 'dof_file'] conestimate = pe.MapNode(interface=fsl.ContrastMgr(), name='conestimate', iterfield=['tcon_file', 'fcon_file', 'param_estimates', 'sigmasquareds', 'corrections', 'dof_file']) if f_contrasts: iterfield = ['in1', 'in2'] else: iterfield = ['in1'] merge_contrasts = pe.MapNode(interface=util.Merge(2), name='merge_contrasts', iterfield=iterfield) ztopval = pe.MapNode(interface=fsl.ImageMaths(op_string='-ztop', suffix='_pval'), nested=True, name='ztop', iterfield=['in_file']) outputspec = pe.Node(util.IdentityInterface(fields=['copes', 'varcopes', 'dof_file', 'pfiles', 'zfiles', 'parameter_estimates']), name='outputspec') """ Setup the connections """ modelfit.connect([ (inputspec, level1design, [('interscan_interval', 'interscan_interval'), ('session_info', 'session_info'), ('contrasts', 'contrasts'), ('bases', 'bases'), ('model_serial_correlations', 'model_serial_correlations')]), (inputspec, modelestimate, [('film_threshold', 'threshold'), ('functional_data', 'in_file')]), (level1design, modelgen, [('fsf_files', 'fsf_file'), ('ev_files', 'ev_files')]), (modelgen, modelestimate, [('design_file', 'design_file')]), (merge_contrasts, ztopval,[('out', 'in_file')]), (ztopval, outputspec, [('out_file', 'pfiles')]), (merge_contrasts, outputspec,[('out', 'zfiles')]), (modelestimate, outputspec, [('param_estimates', 'parameter_estimates'), ('dof_file', 'dof_file')]), ]) if version < 507: modelfit.connect([ (modelgen, conestimate, [('con_file', 'tcon_file'), ('fcon_file', 'fcon_file')]), (modelestimate, conestimate, [('param_estimates', 'param_estimates'), ('sigmasquareds', 'sigmasquareds'), ('corrections', 'corrections'), ('dof_file', 'dof_file')]), (conestimate, merge_contrasts, [('zstats', 'in1'), ('zfstats', 'in2')]), (conestimate, outputspec, [('copes', 'copes'), ('varcopes', 'varcopes')]), ]) else: modelfit.connect([ (modelgen, modelestimate, [('con_file', 'tcon_file'), ('fcon_file', 'fcon_file')]), (modelestimate, merge_contrasts, [('zstats', 'in1'), ('zfstats', 'in2')]), (modelestimate, outputspec, [('copes', 'copes'), ('varcopes', 'varcopes')]), ]) return modelfit def create_overlay_workflow(name='overlay'): """Setup overlay workflow """ overlay = pe.Workflow(name='overlay') overlaystats = pe.MapNode(interface=fsl.Overlay(), name="overlaystats", iterfield=['stat_image']) overlaystats.inputs.show_negative_stats = True overlaystats.inputs.auto_thresh_bg = True slicestats = pe.MapNode(interface=fsl.Slicer(), name="slicestats", iterfield=['in_file']) slicestats.inputs.all_axial = True slicestats.inputs.image_width = 512 overlay.connect(overlaystats, 'out_file', slicestats, 'in_file') return overlay def create_fixed_effects_flow(name='fixedfx'): """Create a fixed-effects workflow This workflow is used to combine registered copes and varcopes across runs for an individual subject Example ------- >>> fixedfx = create_fixed_effects_flow() >>> fixedfx.base_dir = '.' >>> fixedfx.inputs.inputspec.copes = [['cope1run1.nii.gz', 'cope1run2.nii.gz'], ['cope2run1.nii.gz', 'cope2run2.nii.gz']] # per contrast >>> fixedfx.inputs.inputspec.varcopes = [['varcope1run1.nii.gz', 'varcope1run2.nii.gz'], ['varcope2run1.nii.gz', 'varcope2run2.nii.gz']] # per contrast >>> fixedfx.inputs.inputspec.dof_files = ['dofrun1', 'dofrun2'] # per run >>> fixedfx.run() #doctest: +SKIP Inputs:: inputspec.copes : list of list of cope files (one list per contrast) inputspec.varcopes : list of list of varcope files (one list per contrast) inputspec.dof_files : degrees of freedom files for each run Outputs:: outputspec.res4d : 4d residual time series outputspec.copes : contrast parameter estimates outputspec.varcopes : variance of contrast parameter estimates outputspec.zstats : z statistics of contrasts outputspec.tstats : t statistics of contrasts """ fixed_fx = pe.Workflow(name=name) inputspec = pe.Node(util.IdentityInterface(fields=['copes', 'varcopes', 'dof_files' ]), name='inputspec') """ Use :class:`nipype.interfaces.fsl.Merge` to merge the copes and varcopes for each condition """ copemerge = pe.MapNode(interface=fsl.Merge(dimension='t'), iterfield=['in_files'], name="copemerge") varcopemerge = pe.MapNode(interface=fsl.Merge(dimension='t'), iterfield=['in_files'], name="varcopemerge") """ Use :class:`nipype.interfaces.fsl.L2Model` to generate subject and condition specific level 2 model design files """ level2model = pe.Node(interface=fsl.L2Model(), name='l2model') """ Use :class:`nipype.interfaces.fsl.FLAMEO` to estimate a second level model """ flameo = pe.MapNode(interface=fsl.FLAMEO(run_mode='fe'), name="flameo", iterfield=['cope_file', 'var_cope_file']) def get_dofvolumes(dof_files, cope_files): import os import nibabel as nb import numpy as np img = nb.load(cope_files[0]) if len(img.get_shape()) > 3: out_data = np.zeros(img.get_shape()) else: out_data = np.zeros(list(img.get_shape()) + [1]) for i in range(out_data.shape[-1]): dof = np.loadtxt(dof_files[i]) out_data[:, :, :, i] = dof filename = os.path.join(os.getcwd(), 'dof_file.nii.gz') newimg = nb.Nifti1Image(out_data, None, img.get_header()) newimg.to_filename(filename) return filename gendof = pe.Node(util.Function(input_names=['dof_files', 'cope_files'], output_names=['dof_volume'], function=get_dofvolumes), name='gendofvolume') outputspec = pe.Node(util.IdentityInterface(fields=['res4d', 'copes', 'varcopes', 'zstats', 'tstats']), name='outputspec') fixed_fx.connect([(inputspec, copemerge, [('copes', 'in_files')]), (inputspec, varcopemerge, [('varcopes', 'in_files')]), (inputspec, gendof, [('dof_files', 'dof_files')]), (copemerge, gendof, [('merged_file', 'cope_files')]), (copemerge, flameo, [('merged_file', 'cope_file')]), (varcopemerge, flameo, [('merged_file', 'var_cope_file')]), (level2model, flameo, [('design_mat', 'design_file'), ('design_con', 't_con_file'), ('design_grp', 'cov_split_file')]), (gendof, flameo, [('dof_volume', 'dof_var_cope_file')]), (flameo, outputspec, [('res4d', 'res4d'), ('copes', 'copes'), ('var_copes', 'varcopes'), ('zstats', 'zstats'), ('tstats', 'tstats') ]) ]) return fixed_fx nipype-0.11.0/nipype/workflows/fmri/fsl/preprocess.py000066400000000000000000001413521257611314500227310ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import nipype.interfaces.fsl as fsl # fsl import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine import nipype.interfaces.freesurfer as fs # freesurfer import nipype.interfaces.spm as spm from nipype import LooseVersion from ...smri.freesurfer.utils import create_getmask_flow def getthreshop(thresh): return ['-thr %.10f -Tmin -bin'%(0.1*val[1]) for val in thresh] def pickfirst(files): if isinstance(files, list): return files[0] else: return files def pickmiddle(files): from nibabel import load import numpy as np middlevol = [] for f in files: middlevol.append(int(np.ceil(load(f).get_shape()[3]/2))) return middlevol def pickvol(filenames, fileidx, which): from nibabel import load import numpy as np if which.lower() == 'first': idx = 0 elif which.lower() == 'middle': idx = int(np.ceil(load(filenames[fileidx]).get_shape()[3]/2)) elif which.lower() == 'last': idx = load(filenames[fileidx]).get_shape()[3]-1 else: raise Exception('unknown value for volume selection : %s' % which) return idx def getbtthresh(medianvals): return [0.75*val for val in medianvals] def chooseindex(fwhm): if fwhm<1: return [0] else: return [1] def getmeanscale(medianvals): return ['-mul %.10f'%(10000./val) for val in medianvals] def getusans(x): return [[tuple([val[0],0.75*val[1]])] for val in x] tolist = lambda x: [x] highpass_operand = lambda x:'-bptf %.10f -1'%x def create_parallelfeat_preproc(name='featpreproc', highpass=True): """Preprocess each run with FSL independently of the others Parameters ---------- :: name : name of workflow (default: featpreproc) highpass : boolean (default: True) Inputs:: inputspec.func : functional runs (filename or list of filenames) inputspec.fwhm : fwhm for smoothing with SUSAN inputspec.highpass : HWHM in TRs (if created with highpass=True) Outputs:: outputspec.reference : volume to which runs are realigned outputspec.motion_parameters : motion correction parameters outputspec.realigned_files : motion corrected files outputspec.motion_plots : plots of motion correction parameters outputspec.mask : mask file used to mask the brain outputspec.smoothed_files : smoothed functional data outputspec.highpassed_files : highpassed functional data (if highpass=True) outputspec.mean : mean file Example ------- >>> preproc = create_parallelfeat_preproc() >>> preproc.inputs.inputspec.func = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.inputs.inputspec.highpass = 128./(2*2.5) >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP >>> preproc = create_parallelfeat_preproc(highpass=False) >>> preproc.inputs.inputspec.func = 'f3.nii' >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP """ featpreproc = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ if highpass: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'highpass']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'highpassed_files', 'mean']), name='outputspec') else: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'mean']), name='outputspec') """ Set up a node to define outputs for the preprocessing workflow """ """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') featpreproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the first volume of the first run as the reference """ extract_ref = pe.MapNode(interface=fsl.ExtractROI(t_size=1), iterfield=['in_file', 't_min'], name = 'extractref') featpreproc.connect(img2float, 'out_file', extract_ref, 'in_file') featpreproc.connect(img2float, ('out_file', pickmiddle), extract_ref, 't_min') featpreproc.connect(extract_ref, 'roi_file', outputnode, 'reference') """ Realign the functional runs to the reference (1st volume of first run) """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True), name='realign', iterfield = ['in_file', 'ref_file']) featpreproc.connect(img2float, 'out_file', motion_correct, 'in_file') featpreproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') featpreproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') featpreproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) featpreproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') featpreproc.connect(plot_motion, 'out_file', outputnode, 'motion_plots') """ Extract the mean volume of the first functional run """ meanfunc = pe.MapNode(interface=fsl.ImageMaths(op_string = '-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc') featpreproc.connect(motion_correct, 'out_file', meanfunc, 'in_file') """ Strip the skull from the mean functional to generate a mask """ meanfuncmask = pe.MapNode(interface=fsl.BET(mask = True, no_output=True, frac = 0.3), iterfield=['in_file'], name = 'meanfuncmask') featpreproc.connect(meanfunc, 'out_file', meanfuncmask, 'in_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file', 'in_file2'], name = 'maskfunc') featpreproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') featpreproc.connect(meanfuncmask, 'mask_file', maskfunc, 'in_file2') """ Determine the 2nd and 98th percentile intensities of each functional run """ getthresh = pe.MapNode(interface=fsl.ImageStats(op_string='-p 2 -p 98'), iterfield = ['in_file'], name='getthreshold') featpreproc.connect(maskfunc, 'out_file', getthresh, 'in_file') """ Threshold the first run of the functional data at 10% of the 98th percentile """ threshold = pe.MapNode(interface=fsl.ImageMaths(out_data_type='char', suffix='_thresh'), iterfield=['in_file', 'op_string'], name='threshold') featpreproc.connect(maskfunc, 'out_file', threshold, 'in_file') """ Define a function to get 10% of the intensity """ featpreproc.connect(getthresh, ('out_stat', getthreshop), threshold, 'op_string') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file', 'mask_file'], name='medianval') featpreproc.connect(motion_correct, 'out_file', medianval, 'in_file') featpreproc.connect(threshold, 'out_file', medianval, 'mask_file') """ Dilate the mask """ dilatemask = pe.MapNode(interface=fsl.ImageMaths(suffix='_dil', op_string='-dilF'), iterfield=['in_file'], name='dilatemask') featpreproc.connect(threshold, 'out_file', dilatemask, 'in_file') featpreproc.connect(dilatemask, 'out_file', outputnode, 'mask') """ Mask the motion corrected functional runs with the dilated mask """ maskfunc2 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc2') featpreproc.connect(motion_correct, 'out_file', maskfunc2, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc2, 'in_file2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask consituting the mean functional """ smooth = create_susan_smooth() featpreproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm') featpreproc.connect(maskfunc2, 'out_file', smooth, 'inputnode.in_files') featpreproc.connect(dilatemask, 'out_file', smooth, 'inputnode.mask_file') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc3') featpreproc.connect(smooth, 'outputnode.smoothed_files', maskfunc3, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc3, 'in_file2') concatnode = pe.Node(interface=util.Merge(2), name='concat') featpreproc.connect(maskfunc2,('out_file', tolist), concatnode, 'in1') featpreproc.connect(maskfunc3,('out_file', tolist), concatnode, 'in2') """ The following nodes select smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ selectnode = pe.Node(interface=util.Select(),name='select') featpreproc.connect(concatnode, 'out', selectnode, 'inlist') featpreproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index') featpreproc.connect(selectnode, 'out', outputnode, 'smoothed_files') """ Scale the median value of the run is set to 10000 """ meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file','op_string'], name='meanscale') featpreproc.connect(selectnode, 'out', meanscale, 'in_file') """ Define a function to get the scaling factor for intensity normalization """ featpreproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') """ Perform temporal highpass filtering on the data """ if highpass: highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') featpreproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') featpreproc.connect(meanscale, 'out_file', highpass, 'in_file') featpreproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') """ Generate a mean functional image from the first run """ meanfunc3 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc3') if highpass: featpreproc.connect(highpass, 'out_file', meanfunc3, 'in_file') else: featpreproc.connect(meanscale, 'out_file', meanfunc3, 'in_file') featpreproc.connect(meanfunc3, 'out_file', outputnode, 'mean') return featpreproc def create_featreg_preproc(name='featpreproc', highpass=True, whichvol='middle'): """Create a FEAT preprocessing workflow with registration to one volume of the first run Parameters ---------- :: name : name of workflow (default: featpreproc) highpass : boolean (default: True) whichvol : which volume of the first run to register to ('first', 'middle', 'last', 'mean') Inputs:: inputspec.func : functional runs (filename or list of filenames) inputspec.fwhm : fwhm for smoothing with SUSAN inputspec.highpass : HWHM in TRs (if created with highpass=True) Outputs:: outputspec.reference : volume to which runs are realigned outputspec.motion_parameters : motion correction parameters outputspec.realigned_files : motion corrected files outputspec.motion_plots : plots of motion correction parameters outputspec.mask : mask file used to mask the brain outputspec.smoothed_files : smoothed functional data outputspec.highpassed_files : highpassed functional data (if highpass=True) outputspec.mean : mean file Example ------- >>> preproc = create_featreg_preproc() >>> preproc.inputs.inputspec.func = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.inputs.inputspec.highpass = 128./(2*2.5) >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP >>> preproc = create_featreg_preproc(highpass=False, whichvol='mean') >>> preproc.inputs.inputspec.func = 'f3.nii' >>> preproc.inputs.inputspec.fwhm = 5 >>> preproc.base_dir = '/tmp' >>> preproc.run() # doctest: +SKIP """ version = 0 if fsl.Info.version() and \ LooseVersion(fsl.Info.version()) > LooseVersion('5.0.6'): version = 507 featpreproc = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ if highpass: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'highpass']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'highpassed_files', 'mean']), name='outputspec') else: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask', 'smoothed_files', 'mean']), name='outputspec') """ Set up a node to define outputs for the preprocessing workflow """ """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') featpreproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the middle (or what whichvol points to) volume of the first run as the reference """ if whichvol != 'mean': extract_ref = pe.Node(interface=fsl.ExtractROI(t_size=1), iterfield=['in_file'], name = 'extractref') featpreproc.connect(img2float, ('out_file', pickfirst), extract_ref, 'in_file') featpreproc.connect(img2float, ('out_file', pickvol, 0, whichvol), extract_ref, 't_min') featpreproc.connect(extract_ref, 'roi_file', outputnode, 'reference') """ Realign the functional runs to the reference (`whichvol` volume of first run) """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True, interpolation = 'spline'), name='realign', iterfield = ['in_file']) featpreproc.connect(img2float, 'out_file', motion_correct, 'in_file') if whichvol != 'mean': featpreproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') else: motion_correct.inputs.mean_vol = True featpreproc.connect(motion_correct, ('mean_img', pickfirst), outputnode, 'reference') featpreproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') featpreproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) featpreproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') featpreproc.connect(plot_motion, 'out_file', outputnode, 'motion_plots') """ Extract the mean volume of the first functional run """ meanfunc = pe.Node(interface=fsl.ImageMaths(op_string = '-Tmean', suffix='_mean'), name='meanfunc') featpreproc.connect(motion_correct, ('out_file', pickfirst), meanfunc, 'in_file') """ Strip the skull from the mean functional to generate a mask """ meanfuncmask = pe.Node(interface=fsl.BET(mask = True, no_output=True, frac = 0.3), name = 'meanfuncmask') featpreproc.connect(meanfunc, 'out_file', meanfuncmask, 'in_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file'], name = 'maskfunc') featpreproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') featpreproc.connect(meanfuncmask, 'mask_file', maskfunc, 'in_file2') """ Determine the 2nd and 98th percentile intensities of each functional run """ getthresh = pe.MapNode(interface=fsl.ImageStats(op_string='-p 2 -p 98'), iterfield = ['in_file'], name='getthreshold') featpreproc.connect(maskfunc, 'out_file', getthresh, 'in_file') """ Threshold the first run of the functional data at 10% of the 98th percentile """ threshold = pe.MapNode(interface=fsl.ImageMaths(out_data_type='char', suffix='_thresh'), iterfield=['in_file', 'op_string'], name='threshold') featpreproc.connect(maskfunc, 'out_file', threshold, 'in_file') """ Define a function to get 10% of the intensity """ featpreproc.connect(getthresh, ('out_stat', getthreshop), threshold, 'op_string') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file', 'mask_file'], name='medianval') featpreproc.connect(motion_correct, 'out_file', medianval, 'in_file') featpreproc.connect(threshold, 'out_file', medianval, 'mask_file') """ Dilate the mask """ dilatemask = pe.MapNode(interface=fsl.ImageMaths(suffix='_dil', op_string='-dilF'), iterfield=['in_file'], name='dilatemask') featpreproc.connect(threshold, 'out_file', dilatemask, 'in_file') featpreproc.connect(dilatemask, 'out_file', outputnode, 'mask') """ Mask the motion corrected functional runs with the dilated mask """ maskfunc2 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc2') featpreproc.connect(motion_correct, 'out_file', maskfunc2, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc2, 'in_file2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask constituting the mean functional """ smooth = create_susan_smooth() featpreproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm') featpreproc.connect(maskfunc2, 'out_file', smooth, 'inputnode.in_files') featpreproc.connect(dilatemask, 'out_file', smooth, 'inputnode.mask_file') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='maskfunc3') featpreproc.connect(smooth, 'outputnode.smoothed_files', maskfunc3, 'in_file') featpreproc.connect(dilatemask, 'out_file', maskfunc3, 'in_file2') concatnode = pe.Node(interface=util.Merge(2), name='concat') featpreproc.connect(maskfunc2,('out_file', tolist), concatnode, 'in1') featpreproc.connect(maskfunc3,('out_file', tolist), concatnode, 'in2') """ The following nodes select smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ selectnode = pe.Node(interface=util.Select(),name='select') featpreproc.connect(concatnode, 'out', selectnode, 'inlist') featpreproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index') featpreproc.connect(selectnode, 'out', outputnode, 'smoothed_files') """ Scale the median value of the run is set to 10000 """ meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file','op_string'], name='meanscale') featpreproc.connect(selectnode, 'out', meanscale, 'in_file') """ Define a function to get the scaling factor for intensity normalization """ featpreproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') """ Generate a mean functional image from the first run """ meanfunc3 = pe.Node(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc3') featpreproc.connect(meanscale, ('out_file', pickfirst), meanfunc3, 'in_file') featpreproc.connect(meanfunc3, 'out_file', outputnode, 'mean') """ Perform temporal highpass filtering on the data """ if highpass: highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') featpreproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') featpreproc.connect(meanscale, 'out_file', highpass, 'in_file') if version < 507: featpreproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') else: """ Add back the mean removed by the highpass filter operation as of FSL 5.0.7 """ meanfunc4 = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc4') featpreproc.connect(meanscale, 'out_file', meanfunc4, 'in_file') addmean = pe.MapNode(interface=fsl.BinaryMaths(operation='add'), iterfield=['in_file', 'operand_file'], name='addmean') featpreproc.connect(highpass, 'out_file', addmean, 'in_file') featpreproc.connect(meanfunc4, 'out_file', addmean, 'operand_file') featpreproc.connect(addmean, 'out_file', outputnode, 'highpassed_files') return featpreproc def create_susan_smooth(name="susan_smooth", separate_masks=True): """Create a SUSAN smoothing workflow Parameters ---------- :: name : name of workflow (default: susan_smooth) separate_masks : separate masks for each run Inputs:: inputnode.in_files : functional runs (filename or list of filenames) inputnode.fwhm : fwhm for smoothing with SUSAN inputnode.mask_file : mask used for estimating SUSAN thresholds (but not for smoothing) Outputs:: outputnode.smoothed_files : functional runs (filename or list of filenames) Example ------- >>> smooth = create_susan_smooth() >>> smooth.inputs.inputnode.in_files = 'f3.nii' >>> smooth.inputs.inputnode.fwhm = 5 >>> smooth.inputs.inputnode.mask_file = 'mask.nii' >>> smooth.run() # doctest: +SKIP """ susan_smooth = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ inputnode = pe.Node(interface=util.IdentityInterface(fields=['in_files', 'fwhm', 'mask_file']), name='inputnode') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask consituting the mean functional """ smooth = pe.MapNode(interface=fsl.SUSAN(), iterfield=['in_file', 'brightness_threshold','usans'], name='smooth') """ Determine the median value of the functional runs using the mask """ if separate_masks: median = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file', 'mask_file'], name='median') else: median = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file'], name='median') susan_smooth.connect(inputnode, 'in_files', median, 'in_file') susan_smooth.connect(inputnode, 'mask_file', median, 'mask_file') """ Mask the motion corrected functional runs with the dilated mask """ if separate_masks: mask = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file', 'in_file2'], name='mask') else: mask = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file'], name='mask') susan_smooth.connect(inputnode, 'in_files', mask, 'in_file') susan_smooth.connect(inputnode, 'mask_file', mask, 'in_file2') """ Determine the mean image from each functional run """ meanfunc = pe.MapNode(interface=fsl.ImageMaths(op_string='-Tmean', suffix='_mean'), iterfield=['in_file'], name='meanfunc2') susan_smooth.connect(mask, 'out_file', meanfunc, 'in_file') """ Merge the median values with the mean functional images into a coupled list """ merge = pe.Node(interface=util.Merge(2, axis='hstack'), name='merge') susan_smooth.connect(meanfunc,'out_file', merge, 'in1') susan_smooth.connect(median,'out_stat', merge, 'in2') """ Define a function to get the brightness threshold for SUSAN """ susan_smooth.connect(inputnode, 'fwhm', smooth, 'fwhm') susan_smooth.connect(inputnode, 'in_files', smooth, 'in_file') susan_smooth.connect(median, ('out_stat', getbtthresh), smooth, 'brightness_threshold') susan_smooth.connect(merge, ('out', getusans), smooth, 'usans') outputnode = pe.Node(interface=util.IdentityInterface(fields=['smoothed_files']), name='outputnode') susan_smooth.connect(smooth, 'smoothed_file', outputnode, 'smoothed_files') return susan_smooth def create_fsl_fs_preproc(name='preproc', highpass=True, whichvol='middle'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- :: name : name of workflow (default: preproc) highpass : boolean (default: True) whichvol : which volume of the first run to register to ('first', 'middle', 'mean') Inputs:: inputspec.func : functional runs (filename or list of filenames) inputspec.fwhm : fwhm for smoothing with SUSAN inputspec.highpass : HWHM in TRs (if created with highpass=True) inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects dir Outputs:: outputspec.reference : volume to which runs are realigned outputspec.motion_parameters : motion correction parameters outputspec.realigned_files : motion corrected files outputspec.motion_plots : plots of motion correction parameters outputspec.mask_file : mask file used to mask the brain outputspec.smoothed_files : smoothed functional data outputspec.highpassed_files : highpassed functional data (if highpass=True) outputspec.reg_file : bbregister registration files outputspec.reg_cost : bbregister registration cost files Example ------- >>> preproc = create_fsl_fs_preproc(whichvol='first') >>> preproc.inputs.inputspec.highpass = 128./(2*2.5) >>> preproc.inputs.inputspec.func = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.subjects_dir = '.' >>> preproc.inputs.inputspec.subject_id = 's1' >>> preproc.inputs.inputspec.fwhm = 6 >>> preproc.run() # doctest: +SKIP """ featpreproc = pe.Workflow(name=name) """ Set up a node to define all inputs required for the preprocessing workflow """ if highpass: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'subject_id', 'subjects_dir', 'highpass']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask_file', 'smoothed_files', 'highpassed_files', 'reg_file', 'reg_cost' ]), name='outputspec') else: inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'fwhm', 'subject_id', 'subjects_dir' ]), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['reference', 'motion_parameters', 'realigned_files', 'motion_plots', 'mask_file', 'smoothed_files', 'reg_file', 'reg_cost' ]), name='outputspec') """ Set up a node to define outputs for the preprocessing workflow """ """ Convert functional images to float representation. Since there can be more than one functional run we use a MapNode to convert each run. """ img2float = pe.MapNode(interface=fsl.ImageMaths(out_data_type='float', op_string = '', suffix='_dtype'), iterfield=['in_file'], name='img2float') featpreproc.connect(inputnode, 'func', img2float, 'in_file') """ Extract the first volume of the first run as the reference """ if whichvol != 'mean': extract_ref = pe.Node(interface=fsl.ExtractROI(t_size=1), iterfield=['in_file'], name = 'extractref') featpreproc.connect(img2float, ('out_file', pickfirst), extract_ref, 'in_file') featpreproc.connect(img2float, ('out_file', pickvol, 0, whichvol), extract_ref, 't_min') featpreproc.connect(extract_ref, 'roi_file', outputnode, 'reference') """ Realign the functional runs to the reference (1st volume of first run) """ motion_correct = pe.MapNode(interface=fsl.MCFLIRT(save_mats = True, save_plots = True, interpolation = 'sinc'), name='realign', iterfield = ['in_file']) featpreproc.connect(img2float, 'out_file', motion_correct, 'in_file') if whichvol != 'mean': featpreproc.connect(extract_ref, 'roi_file', motion_correct, 'ref_file') else: motion_correct.inputs.mean_vol = True featpreproc.connect(motion_correct, 'mean_img', outputnode, 'reference') featpreproc.connect(motion_correct, 'par_file', outputnode, 'motion_parameters') featpreproc.connect(motion_correct, 'out_file', outputnode, 'realigned_files') """ Plot the estimated motion parameters """ plot_motion = pe.MapNode(interface=fsl.PlotMotionParams(in_source='fsl'), name='plot_motion', iterfield=['in_file']) plot_motion.iterables = ('plot_type', ['rotations', 'translations']) featpreproc.connect(motion_correct, 'par_file', plot_motion, 'in_file') featpreproc.connect(plot_motion, 'out_file', outputnode, 'motion_plots') """Get the mask from subject for each run """ maskflow = create_getmask_flow() featpreproc.connect([(inputnode, maskflow, [('subject_id','inputspec.subject_id'), ('subjects_dir', 'inputspec.subjects_dir')])]) maskflow.inputs.inputspec.contrast_type = 't2' if whichvol != 'mean': featpreproc.connect(extract_ref, 'roi_file', maskflow, 'inputspec.source_file') else: featpreproc.connect(motion_correct, ('mean_img', pickfirst), maskflow, 'inputspec.source_file') """ Mask the functional runs with the extracted mask """ maskfunc = pe.MapNode(interface=fsl.ImageMaths(suffix='_bet', op_string='-mas'), iterfield=['in_file'], name = 'maskfunc') featpreproc.connect(motion_correct, 'out_file', maskfunc, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), maskfunc, 'in_file2') """ Smooth each run using SUSAN with the brightness threshold set to 75% of the median value for each run and a mask consituting the mean functional """ smooth = create_susan_smooth(separate_masks=False) featpreproc.connect(inputnode, 'fwhm', smooth, 'inputnode.fwhm') featpreproc.connect(maskfunc, 'out_file', smooth, 'inputnode.in_files') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), smooth, 'inputnode.mask_file') """ Mask the smoothed data with the dilated mask """ maskfunc3 = pe.MapNode(interface=fsl.ImageMaths(suffix='_mask', op_string='-mas'), iterfield=['in_file'], name='maskfunc3') featpreproc.connect(smooth, 'outputnode.smoothed_files', maskfunc3, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), maskfunc3, 'in_file2') concatnode = pe.Node(interface=util.Merge(2), name='concat') featpreproc.connect(maskfunc, ('out_file', tolist), concatnode, 'in1') featpreproc.connect(maskfunc3, ('out_file', tolist), concatnode, 'in2') """ The following nodes select smooth or unsmoothed data depending on the fwhm. This is because SUSAN defaults to smoothing the data with about the voxel size of the input data if the fwhm parameter is less than 1/3 of the voxel size. """ selectnode = pe.Node(interface=util.Select(),name='select') featpreproc.connect(concatnode, 'out', selectnode, 'inlist') featpreproc.connect(inputnode, ('fwhm', chooseindex), selectnode, 'index') featpreproc.connect(selectnode, 'out', outputnode, 'smoothed_files') """ Scale the median value of the run is set to 10000 """ meanscale = pe.MapNode(interface=fsl.ImageMaths(suffix='_gms'), iterfield=['in_file','op_string'], name='meanscale') featpreproc.connect(selectnode, 'out', meanscale, 'in_file') """ Determine the median value of the functional runs using the mask """ medianval = pe.MapNode(interface=fsl.ImageStats(op_string='-k %s -p 50'), iterfield = ['in_file'], name='medianval') featpreproc.connect(motion_correct, 'out_file', medianval, 'in_file') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), medianval, 'mask_file') """ Define a function to get the scaling factor for intensity normalization """ featpreproc.connect(medianval, ('out_stat', getmeanscale), meanscale, 'op_string') """ Perform temporal highpass filtering on the data """ if highpass: highpass = pe.MapNode(interface=fsl.ImageMaths(suffix='_tempfilt'), iterfield=['in_file'], name='highpass') featpreproc.connect(inputnode, ('highpass', highpass_operand), highpass, 'op_string') featpreproc.connect(meanscale, 'out_file', highpass, 'in_file') featpreproc.connect(highpass, 'out_file', outputnode, 'highpassed_files') featpreproc.connect(maskflow, ('outputspec.mask_file', pickfirst), outputnode, 'mask_file') featpreproc.connect(maskflow, 'outputspec.reg_file', outputnode, 'reg_file') featpreproc.connect(maskflow, 'outputspec.reg_cost', outputnode, 'reg_cost') return featpreproc def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow Parameters ---------- :: name : name of workflow (default: 'registration') Inputs:: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target Outputs:: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space Example ------- """ register = pe.Workflow(name=name) inputnode = pe.Node(interface=util.IdentityInterface(fields=['source_files', 'mean_image', 'anatomical_image', 'target_image', 'target_image_brain', 'config_file']), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=['func2anat_transform', 'anat2target_transform', 'transformed_files', 'transformed_mean', ]), name='outputspec') """ Estimate the tissue classes from the anatomical image. But use spm's segment as FSL appears to be breaking. """ stripper = pe.Node(fsl.BET(), name='stripper') register.connect(inputnode, 'anatomical_image', stripper, 'in_file') fast = pe.Node(fsl.FAST(), name='fast') register.connect(stripper, 'out_file', fast, 'in_files') """ Binarize the segmentation """ binarize = pe.Node(fsl.ImageMaths(op_string='-nan -thr 0.5 -bin'), name='binarize') pickindex = lambda x, i: x[i] register.connect(fast, ('partial_volume_files', pickindex, 2), binarize, 'in_file') """ Calculate rigid transform from mean image to anatomical image """ mean2anat = pe.Node(fsl.FLIRT(), name='mean2anat') mean2anat.inputs.dof = 6 register.connect(inputnode, 'mean_image', mean2anat, 'in_file') register.connect(stripper, 'out_file', mean2anat, 'reference') """ Now use bbr cost function to improve the transform """ mean2anatbbr = pe.Node(fsl.FLIRT(), name='mean2anatbbr') mean2anatbbr.inputs.dof = 6 mean2anatbbr.inputs.cost = 'bbr' mean2anatbbr.inputs.schedule = os.path.join(os.getenv('FSLDIR'), 'etc/flirtsch/bbr.sch') register.connect(inputnode, 'mean_image', mean2anatbbr, 'in_file') register.connect(binarize, 'out_file', mean2anatbbr, 'wm_seg') register.connect(inputnode, 'anatomical_image', mean2anatbbr, 'reference') register.connect(mean2anat, 'out_matrix_file', mean2anatbbr, 'in_matrix_file') """ Calculate affine transform from anatomical to target """ anat2target_affine = pe.Node(fsl.FLIRT(), name='anat2target_linear') anat2target_affine.inputs.searchr_x = [-180, 180] anat2target_affine.inputs.searchr_y = [-180, 180] anat2target_affine.inputs.searchr_z = [-180, 180] register.connect(stripper, 'out_file', anat2target_affine, 'in_file') register.connect(inputnode, 'target_image_brain', anat2target_affine, 'reference') """ Calculate nonlinear transform from anatomical to target """ anat2target_nonlinear = pe.Node(fsl.FNIRT(), name='anat2target_nonlinear') anat2target_nonlinear.inputs.fieldcoeff_file=True register.connect(anat2target_affine, 'out_matrix_file', anat2target_nonlinear, 'affine_file') register.connect(inputnode, 'anatomical_image', anat2target_nonlinear, 'in_file') register.connect(inputnode, 'config_file', anat2target_nonlinear, 'config_file') register.connect(inputnode, 'target_image', anat2target_nonlinear, 'ref_file') """ Transform the mean image. First to anatomical and then to target """ warpmean = pe.Node(fsl.ApplyWarp(interp='spline'), name='warpmean') register.connect(inputnode, 'mean_image', warpmean, 'in_file') register.connect(mean2anatbbr, 'out_matrix_file', warpmean, 'premat') register.connect(inputnode, 'target_image', warpmean, 'ref_file') register.connect(anat2target_nonlinear, 'fieldcoeff_file', warpmean, 'field_file') """ Transform the remaining images. First to anatomical and then to target """ warpall = pe.MapNode(fsl.ApplyWarp(interp='spline'), iterfield=['in_file'], nested=True, name='warpall') register.connect(inputnode, 'source_files', warpall, 'in_file') register.connect(mean2anatbbr, 'out_matrix_file', warpall, 'premat') register.connect(inputnode, 'target_image', warpall, 'ref_file') register.connect(anat2target_nonlinear, 'fieldcoeff_file', warpall, 'field_file') """ Assign all the output files """ register.connect(warpmean, 'out_file', outputnode, 'transformed_mean') register.connect(warpall, 'out_file', outputnode, 'transformed_files') register.connect(mean2anatbbr, 'out_matrix_file', outputnode, 'func2anat_transform') register.connect(anat2target_nonlinear, 'fieldcoeff_file', outputnode, 'anat2target_transform') return register nipype-0.11.0/nipype/workflows/fmri/fsl/tests/000077500000000000000000000000001257611314500213265ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/fmri/fsl/tests/__init__.py000066400000000000000000000000251257611314500234340ustar00rootroot00000000000000__author__ = 'satra' nipype-0.11.0/nipype/workflows/fmri/spm/000077500000000000000000000000001257611314500201775ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/fmri/spm/__init__.py000066400000000000000000000001611257611314500223060ustar00rootroot00000000000000from .preprocess import (create_spm_preproc, create_vbm_preproc, create_DARTEL_template)nipype-0.11.0/nipype/workflows/fmri/spm/estimate.py000066400000000000000000000001621257611314500223630ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: nipype-0.11.0/nipype/workflows/fmri/spm/preprocess.py000066400000000000000000000317671257611314500227540ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import os import nipype.algorithms.rapidart as ra import nipype.interfaces.spm as spm import nipype.interfaces.utility as niu import nipype.pipeline.engine as pe logger = pe.logger from ....interfaces.matlab import no_matlab from ...smri.freesurfer.utils import create_getmask_flow def create_spm_preproc(name='preproc'): """Create an spm preprocessing workflow with freesurfer registration and artifact detection. The workflow realigns and smooths and registers the functional images with the subject's freesurfer space. Example ------- >>> preproc = create_spm_preproc() >>> preproc.base_dir = '.' >>> preproc.inputs.inputspec.fwhm = 6 >>> preproc.inputs.inputspec.subject_id = 's1' >>> preproc.inputs.inputspec.subjects_dir = '.' >>> preproc.inputs.inputspec.functionals = ['f3.nii', 'f5.nii'] >>> preproc.inputs.inputspec.norm_threshold = 1 >>> preproc.inputs.inputspec.zintensity_threshold = 3 Inputs:: inputspec.functionals : functional runs use 4d nifti inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects dir inputspec.fwhm : smoothing fwhm inputspec.norm_threshold : norm threshold for outliers inputspec.zintensity_threshold : intensity threshold in z-score Outputs:: outputspec.realignment_parameters : realignment parameter files outputspec.smoothed_files : smoothed functional files outputspec.outlier_files : list of outliers outputspec.outlier_stats : statistics of outliers outputspec.outlier_plots : images of outliers outputspec.mask_file : binary mask file in reference image space outputspec.reg_file : registration file that maps reference image to freesurfer space outputspec.reg_cost : cost of registration (useful for detecting misalignment) """ """ Initialize the workflow """ workflow = pe.Workflow(name=name) """ Define the inputs to this workflow """ inputnode = pe.Node(niu.IdentityInterface(fields=['functionals', 'subject_id', 'subjects_dir', 'fwhm', 'norm_threshold', 'zintensity_threshold']), name='inputspec') """ Setup the processing nodes and create the mask generation and coregistration workflow """ poplist = lambda x: x.pop() realign = pe.Node(spm.Realign(), name='realign') workflow.connect(inputnode, 'functionals', realign, 'in_files') maskflow = create_getmask_flow() workflow.connect([(inputnode, maskflow, [('subject_id','inputspec.subject_id'), ('subjects_dir', 'inputspec.subjects_dir')])]) maskflow.inputs.inputspec.contrast_type = 't2' workflow.connect(realign, 'mean_image', maskflow, 'inputspec.source_file') smooth = pe.Node(spm.Smooth(), name='smooth') workflow.connect(inputnode, 'fwhm', smooth, 'fwhm') workflow.connect(realign, 'realigned_files', smooth, 'in_files') artdetect = pe.Node(ra.ArtifactDetect(mask_type='file', parameter_source='SPM', use_differences=[True,False], use_norm=True, save_plot=True), name='artdetect') workflow.connect([(inputnode, artdetect,[('norm_threshold', 'norm_threshold'), ('zintensity_threshold', 'zintensity_threshold')])]) workflow.connect([(realign, artdetect, [('realigned_files', 'realigned_files'), ('realignment_parameters', 'realignment_parameters')])]) workflow.connect(maskflow, ('outputspec.mask_file', poplist), artdetect, 'mask_file') """ Define the outputs of the workflow and connect the nodes to the outputnode """ outputnode = pe.Node(niu.IdentityInterface(fields=["realignment_parameters", "smoothed_files", "mask_file", "reg_file", "reg_cost", 'outlier_files', 'outlier_stats', 'outlier_plots' ]), name="outputspec") workflow.connect([ (maskflow, outputnode, [("outputspec.reg_file", "reg_file")]), (maskflow, outputnode, [("outputspec.reg_cost", "reg_cost")]), (maskflow, outputnode, [(("outputspec.mask_file", poplist), "mask_file")]), (realign, outputnode, [('realignment_parameters', 'realignment_parameters')]), (smooth, outputnode, [('smoothed_files', 'smoothed_files')]), (artdetect, outputnode,[('outlier_files', 'outlier_files'), ('statistic_files','outlier_stats'), ('plot_files','outlier_plots')]) ]) return workflow def create_vbm_preproc(name='vbmpreproc'): """Create a vbm workflow that generates DARTEL-based warps to MNI space Based on: http://www.fil.ion.ucl.ac.uk/~john/misc/VBMclass10.pdf Example ------- >>> preproc = create_vbm_preproc() >>> preproc.inputs.inputspec.fwhm = 8 >>> preproc.inputs.inputspec.structural_files = [os.path.abspath('s1.nii'), os.path.abspath('s3.nii')] >>> preproc.inputs.inputspec.template_prefix = 'Template' >>> preproc.run() # doctest: +SKIP Inputs:: inputspec.structural_files : structural data to be used to create templates inputspec.fwhm: single of triplet for smoothing when normalizing to MNI space inputspec.template_prefix : prefix for dartel template Outputs:: outputspec.normalized_files : normalized gray matter files outputspec.template_file : DARTEL template outputspec.icv : intracranial volume (cc - assuming dimensions in mm) """ workflow = pe.Workflow(name=name) """ Define the inputs to this workflow """ inputnode = pe.Node(niu.IdentityInterface(fields=['structural_files', 'fwhm', 'template_prefix']), name='inputspec') dartel_template = create_DARTEL_template() workflow.connect(inputnode, 'template_prefix', dartel_template, 'inputspec.template_prefix') workflow.connect(inputnode, 'structural_files', dartel_template, 'inputspec.structural_files') norm2mni = pe.Node(spm.DARTELNorm2MNI(modulate=True), name='norm2mni') workflow.connect(dartel_template, 'outputspec.template_file', norm2mni, 'template_file') workflow.connect(dartel_template, 'outputspec.flow_fields', norm2mni, 'flowfield_files') def getclass1images(class_images): class1images = [] for session in class_images: class1images.extend(session[0]) return class1images workflow.connect(dartel_template, ('segment.native_class_images', getclass1images), norm2mni, 'apply_to_files') workflow.connect(inputnode, 'fwhm', norm2mni, 'fwhm') def compute_icv(class_images): from nibabel import load from numpy import prod icv = [] for session in class_images: voxel_volume = prod(load(session[0][0]).get_header().get_zooms()) img = load(session[0][0]).get_data() + \ load(session[1][0]).get_data() + \ load(session[2][0]).get_data() img_icv = (img>0.5).astype(int).sum()*voxel_volume*1e-3 icv.append(img_icv) return icv calc_icv = pe.Node(niu.Function(function=compute_icv, input_names=['class_images'], output_names=['icv']), name='calc_icv') workflow.connect(dartel_template, 'segment.native_class_images', calc_icv, 'class_images') """ Define the outputs of the workflow and connect the nodes to the outputnode """ outputnode = pe.Node(niu.IdentityInterface(fields=["normalized_files", "template_file", "icv" ]), name="outputspec") workflow.connect([(dartel_template, outputnode, [('outputspec.template_file','template_file')]), (norm2mni, outputnode, [("normalized_files", "normalized_files")]), (calc_icv, outputnode, [("icv", "icv")]), ]) return workflow def create_DARTEL_template(name='dartel_template'): """Create a vbm workflow that generates DARTEL-based template Example ------- >>> preproc = create_DARTEL_template() >>> preproc.inputs.inputspec.structural_files = [os.path.abspath('s1.nii'), os.path.abspath('s3.nii')] >>> preproc.inputs.inputspec.template_prefix = 'Template' >>> preproc.run() # doctest: +SKIP Inputs:: inputspec.structural_files : structural data to be used to create templates inputspec.template_prefix : prefix for dartel template Outputs:: outputspec.template_file : DARTEL template outputspec.flow_fields : warps from input struct files to the template """ workflow = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['structural_files', 'template_prefix']), name='inputspec') segment = pe.MapNode(spm.NewSegment(), iterfield=['channel_files'], name='segment') workflow.connect(inputnode, 'structural_files', segment, 'channel_files') version = spm.Info.version() if version: spm_path = version['path'] if version['name'] == 'SPM8': tissue1 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 1), 2, (True,True), (False, False)) tissue2 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 2), 2, (True,True), (False, False)) tissue3 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 3), 2, (True,False), (False, False)) tissue4 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 4), 3, (False,False), (False, False)) tissue5 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 5), 4, (False,False), (False, False)) tissue6 = ((os.path.join(spm_path,'toolbox/Seg/TPM.nii'), 6), 2, (False,False), (False, False)) elif version['name'] == 'SPM12': spm_path = version['path'] tissue1 = ((os.path.join(spm_path,'tpm/TPM.nii'), 1), 1, (True,True), (False, False)) tissue2 = ((os.path.join(spm_path,'tpm/TPM.nii'), 2), 1, (True,True), (False, False)) tissue3 = ((os.path.join(spm_path,'tpm/TPM.nii'), 3), 2, (True,False), (False, False)) tissue4 = ((os.path.join(spm_path,'tpm/TPM.nii'), 4), 3, (False,False), (False, False)) tissue5 = ((os.path.join(spm_path,'tpm/TPM.nii'), 5), 4, (False,False), (False, False)) tissue6 = ((os.path.join(spm_path,'tpm/TPM.nii'), 6), 2, (False,False), (False, False)) else: logger.critical('Unsupported version of SPM') segment.inputs.tissues = [tissue1, tissue2, tissue3, tissue4, tissue5, tissue6] else: logger.critical('SPM not found') dartel = pe.Node(spm.DARTEL(), name='dartel') """Get the gray and white segmentation classes generated by NewSegment """ def get2classes(dartel_files): class1images = [] class2images = [] for session in dartel_files: class1images.extend(session[0]) class2images.extend(session[1]) return [class1images, class2images] workflow.connect(segment, ('dartel_input_images', get2classes), dartel, 'image_files') workflow.connect(inputnode, 'template_prefix', dartel, 'template_prefix') outputnode = pe.Node(niu.IdentityInterface(fields=["template_file", "flow_fields" ]), name="outputspec") workflow.connect([ (dartel, outputnode, [('final_template_file','template_file'), ('dartel_flow_fields', 'flow_fields')]), ]) return workflow nipype-0.11.0/nipype/workflows/fmri/spm/tests/000077500000000000000000000000001257611314500213415ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/fmri/spm/tests/__init__.py000066400000000000000000000000251257611314500234470ustar00rootroot00000000000000__author__ = 'satra' nipype-0.11.0/nipype/workflows/graph/000077500000000000000000000000001257611314500175445ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/graph/__init__.py000066400000000000000000000000011257611314500216440ustar00rootroot00000000000000 nipype-0.11.0/nipype/workflows/misc/000077500000000000000000000000001257611314500173765ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/misc/__init__.py000066400000000000000000000000011257611314500214760ustar00rootroot00000000000000 nipype-0.11.0/nipype/workflows/misc/utils.py000066400000000000000000000043141257611314500211120ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: def get_vox_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() voxdims = hdr.get_zooms() return [float(voxdims[0]), float(voxdims[1]), float(voxdims[2])] def get_data_dims(volume): import nibabel as nb if isinstance(volume, list): volume = volume[0] nii = nb.load(volume) hdr = nii.get_header() datadims = hdr.get_data_shape() return [int(datadims[0]), int(datadims[1]), int(datadims[2])] def get_affine(volume): import nibabel as nb nii = nb.load(volume) return nii.get_affine() def select_aparc(list_of_files): for in_file in list_of_files: if 'aparc+aseg.mgz' in in_file: idx = list_of_files.index(in_file) return list_of_files[idx] def select_aparc_annot(list_of_files): for in_file in list_of_files: if '.aparc.annot' in in_file: idx = list_of_files.index(in_file) return list_of_files[idx] def region_list_from_volume(in_file): import nibabel as nb import numpy as np segmentation = nb.load(in_file) segmentationdata = segmentation.get_data() rois = np.unique(segmentationdata) region_list = list(rois) region_list.sort() region_list.remove(0) region_list = map(int, region_list) return region_list def id_list_from_lookup_table(lookup_file, region_list): import numpy as np LUTlabelsRGBA = np.loadtxt(lookup_file, skiprows=4, usecols=[0,1,2,3,4,5], comments='#', dtype={'names': ('index', 'label', 'R', 'G', 'B', 'A'),'formats': ('int', '|S30', 'int', 'int', 'int', 'int')}) numLUTLabels = np.size(LUTlabelsRGBA) LUTlabelDict = {} for labels in range(0,numLUTLabels): LUTlabelDict[LUTlabelsRGBA[labels][0]] = [LUTlabelsRGBA[labels][1], LUTlabelsRGBA[labels][2], LUTlabelsRGBA[labels][3], LUTlabelsRGBA[labels][4], LUTlabelsRGBA[labels][5]] id_list = [] for region in region_list: label = LUTlabelDict[region][0] id_list.append(label) id_list = map(str, id_list) return id_list nipype-0.11.0/nipype/workflows/rsfmri/000077500000000000000000000000001257611314500177455ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/rsfmri/__init__.py000066400000000000000000000000221257611314500220500ustar00rootroot00000000000000from . import fsl nipype-0.11.0/nipype/workflows/rsfmri/fsl/000077500000000000000000000000001257611314500205315ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/rsfmri/fsl/__init__.py000066400000000000000000000000541257611314500226410ustar00rootroot00000000000000from .resting import create_resting_preproc nipype-0.11.0/nipype/workflows/rsfmri/fsl/resting.py000066400000000000000000000173611257611314500225660ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.interfaces.fsl as fsl # fsl from nipype.algorithms.misc import TSNR import nipype.interfaces.utility as util # utility import nipype.pipeline.engine as pe # pypeline engine def extract_noise_components(realigned_file, noise_mask_file, num_components): """Derive components most reflective of physiological noise """ import os from nibabel import load import numpy as np import scipy as sp imgseries = load(realigned_file) components = None mask = load(noise_mask_file).get_data() voxel_timecourses = imgseries.get_data()[mask > 0] voxel_timecourses[np.isnan(np.sum(voxel_timecourses, axis=1)), :] = 0 # remove mean and normalize by variance # voxel_timecourses.shape == [nvoxels, time] X = voxel_timecourses.T stdX = np.std(X, axis=0) stdX[stdX == 0] = 1. stdX[np.isnan(stdX)] = 1. stdX[np.isinf(stdX)] = 1. X = (X - np.mean(X, axis=0))/stdX u, _, _ = sp.linalg.svd(X, full_matrices=False) if components is None: components = u[:, :num_components] else: components = np.hstack((components, u[:, :num_components])) components_file = os.path.join(os.getcwd(), 'noise_components.txt') np.savetxt(components_file, components, fmt="%.10f") return components_file def select_volume(filename, which): """Return the middle index of a file """ from nibabel import load import numpy as np if which.lower() == 'first': idx = 0 elif which.lower() == 'middle': idx = int(np.ceil(load(filename).get_shape()[3]/2)) else: raise Exception('unknown value for volume selection : %s'%which) return idx def create_realign_flow(name='realign'): """Realign a time series to the middle volume using spline interpolation Uses MCFLIRT to realign the time series and ApplyWarp to apply the rigid body transformations using spline interpolation (unknown order). Example ------- >>> wf = create_realign_flow() >>> wf.inputs.inputspec.func = 'f3.nii' >>> wf.run() # doctest: +SKIP """ realignflow = pe.Workflow(name=name) inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', ]), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=[ 'realigned_file', ]), name='outputspec') realigner = pe.Node(fsl.MCFLIRT(save_mats=True, stats_imgs=True), name='realigner') splitter = pe.Node(fsl.Split(dimension='t'), name='splitter') warper = pe.MapNode(fsl.ApplyWarp(interp='spline'), iterfield=['in_file', 'premat'], name='warper') joiner = pe.Node(fsl.Merge(dimension='t'), name='joiner') realignflow.connect(inputnode, 'func', realigner, 'in_file') realignflow.connect(inputnode, ('func', select_volume, 'middle'), realigner, 'ref_vol') realignflow.connect(realigner, 'out_file', splitter, 'in_file') realignflow.connect(realigner, 'mat_file', warper, 'premat') realignflow.connect(realigner, 'variance_img', warper, 'ref_file') realignflow.connect(splitter, 'out_files', warper, 'in_file') realignflow.connect(warper, 'out_file', joiner, 'in_files') realignflow.connect(joiner, 'merged_file', outputnode, 'realigned_file') return realignflow def create_resting_preproc(name='restpreproc'): """Create a "resting" time series preprocessing workflow The noise removal is based on Behzadi et al. (2007) Parameters ---------- name : name of workflow (default: restpreproc) Inputs:: inputspec.func : functional run (filename or list of filenames) Outputs:: outputspec.noise_mask_file : voxels used for PCA to derive noise components outputspec.filtered_file : bandpass filtered and noise-reduced time series Example ------- >>> TR = 3.0 >>> wf = create_resting_preproc() >>> wf.inputs.inputspec.func = 'f3.nii' >>> wf.inputs.inputspec.num_noise_components = 6 >>> wf.inputs.inputspec.highpass_sigma = 100/(2*TR) >>> wf.inputs.inputspec.lowpass_sigma = 12.5/(2*TR) >>> wf.run() # doctest: +SKIP """ restpreproc = pe.Workflow(name=name) # Define nodes inputnode = pe.Node(interface=util.IdentityInterface(fields=['func', 'num_noise_components', 'highpass_sigma', 'lowpass_sigma' ]), name='inputspec') outputnode = pe.Node(interface=util.IdentityInterface(fields=[ 'noise_mask_file', 'filtered_file', ]), name='outputspec') slicetimer = pe.Node(fsl.SliceTimer(), name='slicetimer') realigner = create_realign_flow() tsnr = pe.Node(TSNR(regress_poly=2), name='tsnr') getthresh = pe.Node(interface=fsl.ImageStats(op_string='-p 98'), name='getthreshold') threshold_stddev = pe.Node(fsl.Threshold(), name='threshold') compcor = pe.Node(util.Function(input_names=['realigned_file', 'noise_mask_file', 'num_components'], output_names=['noise_components'], function=extract_noise_components), name='compcorr') remove_noise = pe.Node(fsl.FilterRegressor(filter_all=True), name='remove_noise') bandpass_filter = pe.Node(fsl.TemporalFilter(), name='bandpass_filter') # Define connections restpreproc.connect(inputnode, 'func', slicetimer, 'in_file') restpreproc.connect(slicetimer, 'slice_time_corrected_file', realigner, 'inputspec.func') restpreproc.connect(realigner, 'outputspec.realigned_file', tsnr, 'in_file') restpreproc.connect(tsnr, 'stddev_file', threshold_stddev, 'in_file') restpreproc.connect(tsnr, 'stddev_file', getthresh, 'in_file') restpreproc.connect(getthresh, 'out_stat', threshold_stddev, 'thresh') restpreproc.connect(realigner, 'outputspec.realigned_file', compcor, 'realigned_file') restpreproc.connect(threshold_stddev, 'out_file', compcor, 'noise_mask_file') restpreproc.connect(inputnode, 'num_noise_components', compcor, 'num_components') restpreproc.connect(tsnr, 'detrended_file', remove_noise, 'in_file') restpreproc.connect(compcor, 'noise_components', remove_noise, 'design_file') restpreproc.connect(inputnode, 'highpass_sigma', bandpass_filter, 'highpass_sigma') restpreproc.connect(inputnode, 'lowpass_sigma', bandpass_filter, 'lowpass_sigma') restpreproc.connect(remove_noise, 'out_file', bandpass_filter, 'in_file') restpreproc.connect(threshold_stddev, 'out_file', outputnode, 'noise_mask_file') restpreproc.connect(bandpass_filter, 'out_file', outputnode, 'filtered_file') return restpreprocnipype-0.11.0/nipype/workflows/smri/000077500000000000000000000000001257611314500174155ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/smri/__init__.py000066400000000000000000000000531257611314500215240ustar00rootroot00000000000000from . import freesurfer from . import antsnipype-0.11.0/nipype/workflows/smri/ants/000077500000000000000000000000001257611314500203625ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/smri/ants/ANTSBuildTemplate.py000066400000000000000000000402231257611314500241560ustar00rootroot00000000000000################################################################################# ## Program: Build Template Parallel ## Language: Python ## ## Authors: Jessica Forbes, Grace Murray, and Hans Johnson, University of Iowa ## ## This software is distributed WITHOUT ANY WARRANTY; without even ## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ## PURPOSE. ## ################################################################################# import nipype.pipeline.engine as pe import nipype.interfaces.utility as util from nipype.interfaces.utility import Function from nipype.interfaces.ants import ( ANTS, WarpImageMultiTransform, AverageImages, MultiplyImages, AverageAffineTransform) def GetFirstListElement(this_list): return this_list[0] def MakeTransformListWithGradientWarps(averageAffineTranform, gradientStepWarp): return [averageAffineTranform, gradientStepWarp, gradientStepWarp, gradientStepWarp, gradientStepWarp] def RenestDeformedPassiveImages(deformedPassiveImages,flattened_image_nametypes): import os """ Now make a list of lists of images where the outter list is per image type, and the inner list is the same size as the number of subjects to be averaged. In this case, the first element will be a list of all the deformed T2's, and the second element will be a list of all deformed POSTERIOR_AIR, etc.. """ all_images_size=len(deformedPassiveImages) image_dictionary_of_lists=dict() nested_imagetype_list=list() outputAverageImageName_list=list() image_type_list=list() ## make empty_list, this is not efficient, but it works for name in flattened_image_nametypes: image_dictionary_of_lists[name]=list() for index in range(0,all_images_size): curr_name=flattened_image_nametypes[index] curr_file=deformedPassiveImages[index] image_dictionary_of_lists[curr_name].append(curr_file) for image_type,image_list in image_dictionary_of_lists.items(): nested_imagetype_list.append(image_list) outputAverageImageName_list.append('AVG_'+image_type+'.nii.gz') image_type_list.append('WARP_AVG_'+image_type) print "\n"*10 print "HACK: ", nested_imagetype_list print "HACK: ", outputAverageImageName_list print "HACK: ", image_type_list return nested_imagetype_list,outputAverageImageName_list,image_type_list ## Utility Function ## This will make a list of list pairs for defining the concatenation of transforms ## wp=['wp1.nii','wp2.nii','wp3.nii'] ## af=['af1.mat','af2.mat','af3.mat'] ## ll=map(list,zip(af,wp)) ## ll ##[['af1.mat', 'wp1.nii'], ['af2.mat', 'wp2.nii'], ['af3.mat', 'wp3.nii']] def MakeListsOfTransformLists(warpTransformList, AffineTransformList): return map(list, zip(warpTransformList,AffineTransformList)) ## Flatten and return equal length transform and images lists. def FlattenTransformAndImagesList(ListOfPassiveImagesDictionaries,transformation_series): import sys print("HACK: DEBUG: ListOfPassiveImagesDictionaries\n{lpi}\n".format(lpi=ListOfPassiveImagesDictionaries)) subjCount=len(ListOfPassiveImagesDictionaries) tranCount=len(transformation_series) if subjCount != tranCount: print "ERROR: subjCount must equal tranCount {0} != {1}".format(subjCount,tranCount) sys.exit(-1) flattened_images=list() flattened_image_nametypes=list() flattened_transforms=list() passiveImagesCount = len(ListOfPassiveImagesDictionaries[0]) for subjIndex in range(0,subjCount): #if passiveImagesCount != len(ListOfPassiveImagesDictionaries[subjIndex]): # print "ERROR: all image lengths must be equal {0} != {1}".format(passiveImagesCount,len(ListOfPassiveImagesDictionaries[subjIndex])) # sys.exit(-1) subjImgDictionary=ListOfPassiveImagesDictionaries[subjIndex] subjToAtlasTransform=transformation_series[subjIndex] for imgname,img in subjImgDictionary.items(): flattened_images.append(img) flattened_image_nametypes.append(imgname) flattened_transforms.append(subjToAtlasTransform) print("HACK: flattened images {0}\n".format(flattened_images)) print("HACK: flattened nametypes {0}\n".format(flattened_image_nametypes)) print("HACK: flattened txfms {0}\n".format(flattened_transforms)) return flattened_images,flattened_transforms,flattened_image_nametypes def ANTSTemplateBuildSingleIterationWF(iterationPhasePrefix=''): """ Inputs:: inputspec.images : inputspec.fixed_image : inputspec.ListOfPassiveImagesDictionaries : Outputs:: outputspec.template : outputspec.transforms_list : outputspec.passive_deformed_templates : """ TemplateBuildSingleIterationWF = pe.Workflow(name = 'ANTSTemplateBuildSingleIterationWF_'+str(str(iterationPhasePrefix)) ) inputSpec = pe.Node(interface=util.IdentityInterface(fields=['images', 'fixed_image', 'ListOfPassiveImagesDictionaries']), run_without_submitting=True, name='inputspec') ## HACK: TODO: Need to move all local functions to a common untility file, or at the top of the file so that ## they do not change due to re-indenting. Otherwise re-indenting for flow control will trigger ## their hash to change. ## HACK: TODO: REMOVE 'transforms_list' it is not used. That will change all the hashes ## HACK: TODO: Need to run all python files through the code beutifiers. It has gotten pretty ugly. outputSpec = pe.Node(interface=util.IdentityInterface(fields=['template','transforms_list', 'passive_deformed_templates']), run_without_submitting=True, name='outputspec') ### NOTE MAP NODE! warp each of the original images to the provided fixed_image as the template BeginANTS=pe.MapNode(interface=ANTS(), name = 'BeginANTS', iterfield=['moving_image']) BeginANTS.inputs.dimension = 3 BeginANTS.inputs.output_transform_prefix = str(iterationPhasePrefix)+'_tfm' BeginANTS.inputs.metric = ['CC'] BeginANTS.inputs.metric_weight = [1.0] BeginANTS.inputs.radius = [5] BeginANTS.inputs.transformation_model = 'SyN' BeginANTS.inputs.gradient_step_length = 0.25 BeginANTS.inputs.number_of_iterations = [50, 35, 15] BeginANTS.inputs.number_of_affine_iterations = [10000,10000,10000,10000,10000] BeginANTS.inputs.use_histogram_matching = True BeginANTS.inputs.mi_option = [32, 16000] BeginANTS.inputs.regularization = 'Gauss' BeginANTS.inputs.regularization_gradient_field_sigma = 3 BeginANTS.inputs.regularization_deformation_field_sigma = 0 TemplateBuildSingleIterationWF.connect(inputSpec, 'images', BeginANTS, 'moving_image') TemplateBuildSingleIterationWF.connect(inputSpec, 'fixed_image', BeginANTS, 'fixed_image') MakeTransformsLists = pe.Node(interface=util.Function(function=MakeListsOfTransformLists, input_names=['warpTransformList', 'AffineTransformList'], output_names=['out']), run_without_submitting=True, name='MakeTransformsLists') MakeTransformsLists.inputs.ignore_exception = True TemplateBuildSingleIterationWF.connect(BeginANTS, 'warp_transform', MakeTransformsLists, 'warpTransformList') TemplateBuildSingleIterationWF.connect(BeginANTS, 'affine_transform', MakeTransformsLists, 'AffineTransformList') ## Now warp all the input_images images wimtdeformed = pe.MapNode(interface = WarpImageMultiTransform(), iterfield=['transformation_series', 'input_image'], name ='wimtdeformed') TemplateBuildSingleIterationWF.connect(inputSpec, 'images', wimtdeformed, 'input_image') TemplateBuildSingleIterationWF.connect(MakeTransformsLists, 'out', wimtdeformed, 'transformation_series') ## Shape Update Next ===== ## Now Average All input_images deformed images together to create an updated template average AvgDeformedImages=pe.Node(interface=AverageImages(), name='AvgDeformedImages') AvgDeformedImages.inputs.dimension = 3 AvgDeformedImages.inputs.output_average_image = str(iterationPhasePrefix)+'.nii.gz' AvgDeformedImages.inputs.normalize = True TemplateBuildSingleIterationWF.connect(wimtdeformed, "output_image", AvgDeformedImages, 'images') ## Now average all affine transforms together AvgAffineTransform = pe.Node(interface=AverageAffineTransform(), name = 'AvgAffineTransform') AvgAffineTransform.inputs.dimension = 3 AvgAffineTransform.inputs.output_affine_transform = 'Avererage_'+str(iterationPhasePrefix)+'_Affine.mat' TemplateBuildSingleIterationWF.connect(BeginANTS, 'affine_transform', AvgAffineTransform, 'transforms') ## Now average the warp fields togther AvgWarpImages=pe.Node(interface=AverageImages(), name='AvgWarpImages') AvgWarpImages.inputs.dimension = 3 AvgWarpImages.inputs.output_average_image = str(iterationPhasePrefix)+'warp.nii.gz' AvgWarpImages.inputs.normalize = True TemplateBuildSingleIterationWF.connect(BeginANTS, 'warp_transform', AvgWarpImages, 'images') ## Now average the images together ## TODO: For now GradientStep is set to 0.25 as a hard coded default value. GradientStep = 0.25 GradientStepWarpImage=pe.Node(interface=MultiplyImages(), name='GradientStepWarpImage') GradientStepWarpImage.inputs.dimension = 3 GradientStepWarpImage.inputs.second_input = -1.0 * GradientStep GradientStepWarpImage.inputs.output_product_image = 'GradientStep0.25_'+str(iterationPhasePrefix)+'_warp.nii.gz' TemplateBuildSingleIterationWF.connect(AvgWarpImages, 'output_average_image', GradientStepWarpImage, 'first_input') ## Now create the new template shape based on the average of all deformed images UpdateTemplateShape = pe.Node(interface = WarpImageMultiTransform(), name = 'UpdateTemplateShape') UpdateTemplateShape.inputs.invert_affine = [1] TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', UpdateTemplateShape, 'reference_image') TemplateBuildSingleIterationWF.connect(AvgAffineTransform, 'affine_transform', UpdateTemplateShape, 'transformation_series') TemplateBuildSingleIterationWF.connect(GradientStepWarpImage, 'output_product_image', UpdateTemplateShape, 'input_image') ApplyInvAverageAndFourTimesGradientStepWarpImage = pe.Node(interface=util.Function(function=MakeTransformListWithGradientWarps, input_names=['averageAffineTranform', 'gradientStepWarp'], output_names=['TransformListWithGradientWarps']), run_without_submitting=True, name='MakeTransformListWithGradientWarps') ApplyInvAverageAndFourTimesGradientStepWarpImage.inputs.ignore_exception = True TemplateBuildSingleIterationWF.connect(AvgAffineTransform, 'affine_transform', ApplyInvAverageAndFourTimesGradientStepWarpImage, 'averageAffineTranform') TemplateBuildSingleIterationWF.connect(UpdateTemplateShape, 'output_image', ApplyInvAverageAndFourTimesGradientStepWarpImage, 'gradientStepWarp') ReshapeAverageImageWithShapeUpdate = pe.Node(interface = WarpImageMultiTransform(), name = 'ReshapeAverageImageWithShapeUpdate') ReshapeAverageImageWithShapeUpdate.inputs.invert_affine = [1] ReshapeAverageImageWithShapeUpdate.inputs.out_postfix = '_Reshaped' TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', ReshapeAverageImageWithShapeUpdate, 'input_image') TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', ReshapeAverageImageWithShapeUpdate, 'reference_image') TemplateBuildSingleIterationWF.connect(ApplyInvAverageAndFourTimesGradientStepWarpImage, 'TransformListWithGradientWarps', ReshapeAverageImageWithShapeUpdate, 'transformation_series') TemplateBuildSingleIterationWF.connect(ReshapeAverageImageWithShapeUpdate, 'output_image', outputSpec, 'template') ###### ###### ###### Process all the passive deformed images in a way similar to the main image used for registration ###### ###### ###### ############################################## ## Now warp all the ListOfPassiveImagesDictionaries images FlattenTransformAndImagesListNode = pe.Node( Function(function=FlattenTransformAndImagesList, input_names = ['ListOfPassiveImagesDictionaries','transformation_series'], output_names = ['flattened_images','flattened_transforms','flattened_image_nametypes']), run_without_submitting=True, name="99_FlattenTransformAndImagesList") TemplateBuildSingleIterationWF.connect( inputSpec,'ListOfPassiveImagesDictionaries', FlattenTransformAndImagesListNode, 'ListOfPassiveImagesDictionaries' ) TemplateBuildSingleIterationWF.connect( MakeTransformsLists ,'out', FlattenTransformAndImagesListNode, 'transformation_series' ) wimtPassivedeformed = pe.MapNode(interface = WarpImageMultiTransform(), iterfield=['transformation_series', 'input_image'], name ='wimtPassivedeformed') TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image',wimtPassivedeformed,'reference_image') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_images', wimtPassivedeformed, 'input_image') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_transforms', wimtPassivedeformed, 'transformation_series') RenestDeformedPassiveImagesNode = pe.Node( Function(function=RenestDeformedPassiveImages, input_names = ['deformedPassiveImages','flattened_image_nametypes'], output_names = ['nested_imagetype_list','outputAverageImageName_list','image_type_list']), run_without_submitting=True, name="99_RenestDeformedPassiveImages") TemplateBuildSingleIterationWF.connect(wimtPassivedeformed, 'output_image', RenestDeformedPassiveImagesNode, 'deformedPassiveImages') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_image_nametypes', RenestDeformedPassiveImagesNode, 'flattened_image_nametypes') ## Now Average All passive input_images deformed images together to create an updated template average AvgDeformedPassiveImages=pe.MapNode(interface=AverageImages(), iterfield=['images','output_average_image'], name='AvgDeformedPassiveImages') AvgDeformedPassiveImages.inputs.dimension = 3 AvgDeformedPassiveImages.inputs.normalize = False TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, "nested_imagetype_list", AvgDeformedPassiveImages, 'images') TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, "outputAverageImageName_list", AvgDeformedPassiveImages, 'output_average_image') ## -- TODO: Now neeed to reshape all the passive images as well ReshapeAveragePassiveImageWithShapeUpdate = pe.MapNode(interface = WarpImageMultiTransform(), iterfield=['input_image','reference_image','out_postfix'], name = 'ReshapeAveragePassiveImageWithShapeUpdate') ReshapeAveragePassiveImageWithShapeUpdate.inputs.invert_affine = [1] TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, "image_type_list", ReshapeAveragePassiveImageWithShapeUpdate, 'out_postfix') TemplateBuildSingleIterationWF.connect(AvgDeformedPassiveImages, 'output_average_image', ReshapeAveragePassiveImageWithShapeUpdate, 'input_image') TemplateBuildSingleIterationWF.connect(AvgDeformedPassiveImages, 'output_average_image', ReshapeAveragePassiveImageWithShapeUpdate, 'reference_image') TemplateBuildSingleIterationWF.connect(ApplyInvAverageAndFourTimesGradientStepWarpImage, 'TransformListWithGradientWarps', ReshapeAveragePassiveImageWithShapeUpdate, 'transformation_series') TemplateBuildSingleIterationWF.connect(ReshapeAveragePassiveImageWithShapeUpdate, 'output_image', outputSpec, 'passive_deformed_templates') return TemplateBuildSingleIterationWF nipype-0.11.0/nipype/workflows/smri/ants/__init__.py000066400000000000000000000002331257611314500224710ustar00rootroot00000000000000from .ANTSBuildTemplate import ANTSTemplateBuildSingleIterationWF from .antsRegistrationBuildTemplate import antsRegistrationTemplateBuildSingleIterationWFnipype-0.11.0/nipype/workflows/smri/ants/antsRegistrationBuildTemplate.py000066400000000000000000000556231257611314500267630ustar00rootroot00000000000000################################################################################# ## Program: Build Template Parallel ## Language: Python ## ## Authors: Jessica Forbes, Grace Murray, and Hans Johnson, University of Iowa ## ## This software is distributed WITHOUT ANY WARRANTY; without even ## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ## PURPOSE. ## ################################################################################# import nipype.pipeline.engine as pe import nipype.interfaces.utility as util from nipype.interfaces.utility import Function from nipype.interfaces.ants import ( Registration, ApplyTransforms, AverageImages, MultiplyImages, AverageAffineTransform) def makeListOfOneElement(inputFile): outputList=[inputFile] return outputList def GetFirstListElement(this_list): return this_list[0] def MakeTransformListWithGradientWarps(averageAffineTranform, gradientStepWarp): return [averageAffineTranform, gradientStepWarp, gradientStepWarp, gradientStepWarp, gradientStepWarp] def RenestDeformedPassiveImages(deformedPassiveImages,flattened_image_nametypes,interpolationMapping): import os """ Now make a list of lists of images where the outter list is per image type, and the inner list is the same size as the number of subjects to be averaged. In this case, the first element will be a list of all the deformed T2's, and the second element will be a list of all deformed POSTERIOR_AIR, etc.. """ all_images_size=len(deformedPassiveImages) image_dictionary_of_lists=dict() nested_imagetype_list=list() outputAverageImageName_list=list() image_type_list=list() nested_interpolation_type=list() ## make empty_list, this is not efficient, but it works for name in flattened_image_nametypes: image_dictionary_of_lists[name]=list() for index in range(0,all_images_size): curr_name=flattened_image_nametypes[index] curr_file=deformedPassiveImages[index] image_dictionary_of_lists[curr_name].append(curr_file) for image_type,image_list in image_dictionary_of_lists.items(): nested_imagetype_list.append(image_list) outputAverageImageName_list.append('AVG_'+image_type+'.nii.gz') image_type_list.append('WARP_AVG_'+image_type) if interpolationMapping.has_key(image_type): nested_interpolation_type.append(interpolationMapping[image_type]) else: nested_interpolation_type.append('Linear') #Linear is the default. print "\n"*10 print "HACK: ", nested_imagetype_list print "HACK: ", outputAverageImageName_list print "HACK: ", image_type_list print "HACK: ", nested_interpolation_type return nested_imagetype_list,outputAverageImageName_list,image_type_list,nested_interpolation_type def SplitAffineAndWarpComponents(list_of_transforms_lists): ### Nota bene: The outputs will include the initial_moving_transform from Registration (which depends on what ### the invert_initial_moving_transform is set to) affine_component_list = [] warp_component_list = [] for transform in list_of_transforms_lists: affine_component_list.append(transform[0]) warp_component_list.append(transform[1]) print "HACK ", affine_component_list, " ", warp_component_list return affine_component_list, warp_component_list ## Flatten and return equal length transform and images lists. def FlattenTransformAndImagesList(ListOfPassiveImagesDictionaries,transforms,invert_transform_flags,interpolationMapping): import sys print("HACK: DEBUG: ListOfPassiveImagesDictionaries\n{lpi}\n".format(lpi=ListOfPassiveImagesDictionaries)) subjCount=len(ListOfPassiveImagesDictionaries) tranCount=len(transforms) if subjCount != tranCount: print "ERROR: subjCount must equal tranCount {0} != {1}".format(subjCount,tranCount) sys.exit(-1) invertTfmsFlagsCount=len(invert_transform_flags) if subjCount != invertTfmsFlagsCount: print "ERROR: subjCount must equal invertTfmsFlags {0} != {1}".format(subjCount,invertTfmsFlagsCount) sys.exit(-1) flattened_images=list() flattened_image_nametypes=list() flattened_transforms=list() flattened_invert_transform_flags=list() flattened_interpolation_type=list() passiveImagesCount = len(ListOfPassiveImagesDictionaries[0]) for subjIndex in range(0,subjCount): #if passiveImagesCount != len(ListOfPassiveImagesDictionaries[subjIndex]): # print "ERROR: all image lengths must be equal {0} != {1}".format(passiveImagesCount,len(ListOfPassiveImagesDictionaries[subjIndex])) # sys.exit(-1) subjImgDictionary=ListOfPassiveImagesDictionaries[subjIndex] subjToAtlasTransform=transforms[subjIndex] subjToAtlasInvertFlags=invert_transform_flags[subjIndex] for imgname,img in subjImgDictionary.items(): flattened_images.append(img) flattened_image_nametypes.append(imgname) flattened_transforms.append(subjToAtlasTransform) flattened_invert_transform_flags.append(subjToAtlasInvertFlags) if interpolationMapping.has_key(imgname): flattened_interpolation_type.append(interpolationMapping[imgname]) else: flattened_interpolation_type.append('Linear') #Linear is the default. print("HACK: flattened images {0}\n".format(flattened_images)) print("HACK: flattened nametypes {0}\n".format(flattened_image_nametypes)) print("HACK: flattened txfms {0}\n".format(flattened_transforms)) print("HACK: flattened txfmsFlags{0}\n".format(flattened_invert_transform_flags)) return flattened_images,flattened_transforms,flattened_invert_transform_flags,flattened_image_nametypes,flattened_interpolation_type def GetMovingImages(ListOfImagesDictionaries,registrationImageTypes,interpolationMapping): """ This currently ONLY works when registrationImageTypes has length of exactly 1. When the new multi-variate registration is introduced, it will be expanded. """ if len(registrationImageTypes) !=1: print("ERROR: Multivariate imageing not supported yet!") return [] moving_images=[ mdict[ registrationImageTypes[0] ] for mdict in ListOfImagesDictionaries ] moving_interpolation_type=interpolationMapping[ registrationImageTypes[0] ] return moving_images,moving_interpolation_type def GetPassiveImages(ListOfImagesDictionaries,registrationImageTypes): if len(registrationImageTypes) !=1: print("ERROR: Multivariate imageing not supported yet!") return [dict()] passive_images=list() for mdict in ListOfImagesDictionaries: ThisSubjectPassiveImages=dict() for key,value in mdict.items(): if key not in registrationImageTypes: ThisSubjectPassiveImages[key]=value passive_images.append(ThisSubjectPassiveImages) return passive_images ## ## NOTE: The modes can be either 'SINGLE_IMAGE' or 'MULTI' ## 'SINGLE_IMAGE' is quick shorthand when you are building an atlas with a single subject, then registration can ## be short-circuted ## any other string indicates the normal mode that you would expect and replicates the shell script build_template_parallel.sh def antsRegistrationTemplateBuildSingleIterationWF(iterationPhasePrefix=''): """ Inputs:: inputspec.images : inputspec.fixed_image : inputspec.ListOfPassiveImagesDictionaries : inputspec.interpolationMapping : Outputs:: outputspec.template : outputspec.transforms_list : outputspec.passive_deformed_templates : """ TemplateBuildSingleIterationWF = pe.Workflow(name = 'antsRegistrationTemplateBuildSingleIterationWF_'+str(iterationPhasePrefix) ) inputSpec = pe.Node(interface=util.IdentityInterface(fields=[ 'ListOfImagesDictionaries', 'registrationImageTypes', 'interpolationMapping','fixed_image']), run_without_submitting=True, name='inputspec') ## HACK: TODO: Need to move all local functions to a common untility file, or at the top of the file so that ## they do not change due to re-indenting. Otherwise re-indenting for flow control will trigger ## their hash to change. ## HACK: TODO: REMOVE 'transforms_list' it is not used. That will change all the hashes ## HACK: TODO: Need to run all python files through the code beutifiers. It has gotten pretty ugly. outputSpec = pe.Node(interface=util.IdentityInterface(fields=['template','transforms_list', 'passive_deformed_templates']), run_without_submitting=True, name='outputspec') ### NOTE MAP NODE! warp each of the original images to the provided fixed_image as the template BeginANTS=pe.MapNode(interface=Registration(), name = 'BeginANTS', iterfield=['moving_image']) BeginANTS.inputs.dimension = 3 BeginANTS.inputs.output_transform_prefix = str(iterationPhasePrefix)+'_tfm' BeginANTS.inputs.transforms = ["Affine", "SyN"] BeginANTS.inputs.transform_parameters = [[0.9], [0.25,3.0,0.0]] BeginANTS.inputs.metric = ['Mattes', 'CC'] BeginANTS.inputs.metric_weight = [1.0, 1.0] BeginANTS.inputs.radius_or_number_of_bins = [32, 5] BeginANTS.inputs.number_of_iterations = [[1000, 1000, 1000], [50, 35, 15]] BeginANTS.inputs.use_histogram_matching = [True, True] BeginANTS.inputs.use_estimate_learning_rate_once = [False, False] BeginANTS.inputs.shrink_factors = [[3,2,1], [3,2,1]] BeginANTS.inputs.smoothing_sigmas = [[3,2,0], [3,2,0]] BeginANTS.inputs.sigma_units = ["vox"]*2 GetMovingImagesNode = pe.Node(interface=util.Function(function=GetMovingImages, input_names=['ListOfImagesDictionaries','registrationImageTypes','interpolationMapping'], output_names=['moving_images','moving_interpolation_type']), run_without_submitting=True, name='99_GetMovingImagesNode') TemplateBuildSingleIterationWF.connect(inputSpec, 'ListOfImagesDictionaries', GetMovingImagesNode, 'ListOfImagesDictionaries') TemplateBuildSingleIterationWF.connect(inputSpec, 'registrationImageTypes', GetMovingImagesNode, 'registrationImageTypes') TemplateBuildSingleIterationWF.connect(inputSpec, 'interpolationMapping',GetMovingImagesNode,'interpolationMapping') TemplateBuildSingleIterationWF.connect(GetMovingImagesNode, 'moving_images', BeginANTS, 'moving_image') TemplateBuildSingleIterationWF.connect(GetMovingImagesNode, 'moving_interpolation_type', BeginANTS, 'interpolation') TemplateBuildSingleIterationWF.connect(inputSpec, 'fixed_image', BeginANTS, 'fixed_image') ## Now warp all the input_images images wimtdeformed = pe.MapNode(interface = ApplyTransforms(), iterfield=['transforms','invert_transform_flags','input_image'], name ='wimtdeformed') wimtdeformed.inputs.interpolation = 'Linear' wimtdeformed.default_value = 0 TemplateBuildSingleIterationWF.connect(BeginANTS,'forward_transforms',wimtdeformed,'transforms') TemplateBuildSingleIterationWF.connect(BeginANTS,'forward_invert_flags',wimtdeformed,'invert_transform_flags') TemplateBuildSingleIterationWF.connect(GetMovingImagesNode, 'moving_images', wimtdeformed, 'input_image') TemplateBuildSingleIterationWF.connect(inputSpec, 'fixed_image', wimtdeformed, 'reference_image') ## Shape Update Next ===== ## Now Average All input_images deformed images together to create an updated template average AvgDeformedImages=pe.Node(interface=AverageImages(), name='AvgDeformedImages') AvgDeformedImages.inputs.dimension = 3 AvgDeformedImages.inputs.output_average_image = str(iterationPhasePrefix)+'.nii.gz' AvgDeformedImages.inputs.normalize = True TemplateBuildSingleIterationWF.connect(wimtdeformed, "output_image", AvgDeformedImages, 'images') ## Now average all affine transforms together AvgAffineTransform = pe.Node(interface=AverageAffineTransform(), name = 'AvgAffineTransform') AvgAffineTransform.inputs.dimension = 3 AvgAffineTransform.inputs.output_affine_transform = 'Avererage_'+str(iterationPhasePrefix)+'_Affine.mat' SplitAffineAndWarpsNode = pe.Node(interface=util.Function(function=SplitAffineAndWarpComponents, input_names=['list_of_transforms_lists'], output_names=['affine_component_list', 'warp_component_list']), run_without_submitting=True, name='99_SplitAffineAndWarpsNode') TemplateBuildSingleIterationWF.connect(BeginANTS, 'forward_transforms',SplitAffineAndWarpsNode,'list_of_transforms_lists') TemplateBuildSingleIterationWF.connect(SplitAffineAndWarpsNode, 'affine_component_list', AvgAffineTransform, 'transforms') ## Now average the warp fields togther AvgWarpImages=pe.Node(interface=AverageImages(), name='AvgWarpImages') AvgWarpImages.inputs.dimension = 3 AvgWarpImages.inputs.output_average_image = str(iterationPhasePrefix)+'warp.nii.gz' AvgWarpImages.inputs.normalize = True TemplateBuildSingleIterationWF.connect(SplitAffineAndWarpsNode, 'warp_component_list', AvgWarpImages, 'images') ## Now average the images together ## TODO: For now GradientStep is set to 0.25 as a hard coded default value. GradientStep = 0.25 GradientStepWarpImage=pe.Node(interface=MultiplyImages(), name='GradientStepWarpImage') GradientStepWarpImage.inputs.dimension = 3 GradientStepWarpImage.inputs.second_input = -1.0 * GradientStep GradientStepWarpImage.inputs.output_product_image = 'GradientStep0.25_'+str(iterationPhasePrefix)+'_warp.nii.gz' TemplateBuildSingleIterationWF.connect(AvgWarpImages, 'output_average_image', GradientStepWarpImage, 'first_input') ## Now create the new template shape based on the average of all deformed images UpdateTemplateShape = pe.Node(interface = ApplyTransforms(), name = 'UpdateTemplateShape') UpdateTemplateShape.inputs.invert_transform_flags = [True] UpdateTemplateShape.inputs.interpolation = 'Linear' UpdateTemplateShape.default_value = 0 TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', UpdateTemplateShape, 'reference_image') TemplateBuildSingleIterationWF.connect( [ (AvgAffineTransform, UpdateTemplateShape, [(('affine_transform', makeListOfOneElement ), 'transforms')] ), ]) TemplateBuildSingleIterationWF.connect(GradientStepWarpImage, 'output_product_image', UpdateTemplateShape, 'input_image') ApplyInvAverageAndFourTimesGradientStepWarpImage = pe.Node(interface=util.Function(function=MakeTransformListWithGradientWarps, input_names=['averageAffineTranform', 'gradientStepWarp'], output_names=['TransformListWithGradientWarps']), run_without_submitting=True, name='99_MakeTransformListWithGradientWarps') ApplyInvAverageAndFourTimesGradientStepWarpImage.inputs.ignore_exception = True TemplateBuildSingleIterationWF.connect(AvgAffineTransform, 'affine_transform', ApplyInvAverageAndFourTimesGradientStepWarpImage, 'averageAffineTranform') TemplateBuildSingleIterationWF.connect(UpdateTemplateShape, 'output_image', ApplyInvAverageAndFourTimesGradientStepWarpImage, 'gradientStepWarp') ReshapeAverageImageWithShapeUpdate = pe.Node(interface = ApplyTransforms(), name = 'ReshapeAverageImageWithShapeUpdate') ReshapeAverageImageWithShapeUpdate.inputs.invert_transform_flags = [ True, False, False, False, False ] ReshapeAverageImageWithShapeUpdate.inputs.interpolation = 'Linear' ReshapeAverageImageWithShapeUpdate.default_value = 0 ReshapeAverageImageWithShapeUpdate.inputs.output_image = 'ReshapeAverageImageWithShapeUpdate.nii.gz' TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', ReshapeAverageImageWithShapeUpdate, 'input_image') TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image', ReshapeAverageImageWithShapeUpdate, 'reference_image') TemplateBuildSingleIterationWF.connect(ApplyInvAverageAndFourTimesGradientStepWarpImage, 'TransformListWithGradientWarps', ReshapeAverageImageWithShapeUpdate, 'transforms') TemplateBuildSingleIterationWF.connect(ReshapeAverageImageWithShapeUpdate, 'output_image', outputSpec, 'template') ###### ###### ###### Process all the passive deformed images in a way similar to the main image used for registration ###### ###### ###### ############################################## ## Now warp all the ListOfPassiveImagesDictionaries images FlattenTransformAndImagesListNode = pe.Node( Function(function=FlattenTransformAndImagesList, input_names = ['ListOfPassiveImagesDictionaries','transforms', 'invert_transform_flags','interpolationMapping'], output_names = ['flattened_images','flattened_transforms','flattened_invert_transform_flags', 'flattened_image_nametypes','flattened_interpolation_type']), run_without_submitting=True, name="99_FlattenTransformAndImagesList") GetPassiveImagesNode = pe.Node(interface=util.Function(function=GetPassiveImages, input_names=['ListOfImagesDictionaries','registrationImageTypes'], output_names=['ListOfPassiveImagesDictionaries']), run_without_submitting=True, name='99_GetPassiveImagesNode') TemplateBuildSingleIterationWF.connect(inputSpec, 'ListOfImagesDictionaries', GetPassiveImagesNode, 'ListOfImagesDictionaries') TemplateBuildSingleIterationWF.connect(inputSpec, 'registrationImageTypes', GetPassiveImagesNode, 'registrationImageTypes') TemplateBuildSingleIterationWF.connect( GetPassiveImagesNode,'ListOfPassiveImagesDictionaries', FlattenTransformAndImagesListNode, 'ListOfPassiveImagesDictionaries' ) TemplateBuildSingleIterationWF.connect( inputSpec,'interpolationMapping', FlattenTransformAndImagesListNode, 'interpolationMapping' ) TemplateBuildSingleIterationWF.connect( BeginANTS,'forward_transforms', FlattenTransformAndImagesListNode, 'transforms' ) TemplateBuildSingleIterationWF.connect( BeginANTS,'forward_invert_flags', FlattenTransformAndImagesListNode, 'invert_transform_flags' ) wimtPassivedeformed = pe.MapNode(interface = ApplyTransforms(), iterfield=['transforms','invert_transform_flags', 'input_image','interpolation'], name ='wimtPassivedeformed') wimtPassivedeformed.default_value = 0 TemplateBuildSingleIterationWF.connect(AvgDeformedImages, 'output_average_image',wimtPassivedeformed,'reference_image') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_interpolation_type', wimtPassivedeformed, 'interpolation') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_images', wimtPassivedeformed, 'input_image') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_transforms', wimtPassivedeformed, 'transforms') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_invert_transform_flags', wimtPassivedeformed, 'invert_transform_flags') RenestDeformedPassiveImagesNode = pe.Node( Function(function=RenestDeformedPassiveImages, input_names = ['deformedPassiveImages','flattened_image_nametypes','interpolationMapping'], output_names = ['nested_imagetype_list','outputAverageImageName_list', 'image_type_list','nested_interpolation_type']), run_without_submitting=True, name="99_RenestDeformedPassiveImages") TemplateBuildSingleIterationWF.connect(inputSpec, 'interpolationMapping', RenestDeformedPassiveImagesNode, 'interpolationMapping') TemplateBuildSingleIterationWF.connect(wimtPassivedeformed, 'output_image', RenestDeformedPassiveImagesNode, 'deformedPassiveImages') TemplateBuildSingleIterationWF.connect(FlattenTransformAndImagesListNode, 'flattened_image_nametypes', RenestDeformedPassiveImagesNode, 'flattened_image_nametypes') ## Now Average All passive input_images deformed images together to create an updated template average AvgDeformedPassiveImages=pe.MapNode(interface=AverageImages(), iterfield=['images','output_average_image'], name='AvgDeformedPassiveImages') AvgDeformedPassiveImages.inputs.dimension = 3 AvgDeformedPassiveImages.inputs.normalize = False TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, "nested_imagetype_list", AvgDeformedPassiveImages, 'images') TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, "outputAverageImageName_list", AvgDeformedPassiveImages, 'output_average_image') ## -- TODO: Now neeed to reshape all the passive images as well ReshapeAveragePassiveImageWithShapeUpdate = pe.MapNode(interface = ApplyTransforms(), iterfield=['input_image','reference_image','output_image','interpolation'], name = 'ReshapeAveragePassiveImageWithShapeUpdate') ReshapeAveragePassiveImageWithShapeUpdate.inputs.invert_transform_flags = [ True, False, False, False, False ] ReshapeAveragePassiveImageWithShapeUpdate.default_value = 0 TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, 'nested_interpolation_type', ReshapeAveragePassiveImageWithShapeUpdate, 'interpolation') TemplateBuildSingleIterationWF.connect(RenestDeformedPassiveImagesNode, 'outputAverageImageName_list', ReshapeAveragePassiveImageWithShapeUpdate, 'output_image') TemplateBuildSingleIterationWF.connect(AvgDeformedPassiveImages, 'output_average_image', ReshapeAveragePassiveImageWithShapeUpdate, 'input_image') TemplateBuildSingleIterationWF.connect(AvgDeformedPassiveImages, 'output_average_image', ReshapeAveragePassiveImageWithShapeUpdate, 'reference_image') TemplateBuildSingleIterationWF.connect(ApplyInvAverageAndFourTimesGradientStepWarpImage, 'TransformListWithGradientWarps', ReshapeAveragePassiveImageWithShapeUpdate, 'transforms') TemplateBuildSingleIterationWF.connect(ReshapeAveragePassiveImageWithShapeUpdate, 'output_image', outputSpec, 'passive_deformed_templates') return TemplateBuildSingleIterationWF nipype-0.11.0/nipype/workflows/smri/freesurfer/000077500000000000000000000000001257611314500215655ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/smri/freesurfer/__init__.py000066400000000000000000000002561257611314500237010ustar00rootroot00000000000000from .utils import (create_getmask_flow, create_get_stats_flow, create_tessellation_flow) from .bem import create_bem_flow from .recon import create_skullstripped_recon_flow nipype-0.11.0/nipype/workflows/smri/freesurfer/bem.py000066400000000000000000000047641257611314500227150ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.pipeline.engine as pe import nipype.interfaces.mne as mne import nipype.interfaces.freesurfer as fs import nipype.interfaces.utility as niu def create_bem_flow(name='bem', out_format='stl'): """Uses MNE's Watershed algorithm to create Boundary Element Meshes (BEM) for a subject's brain, inner/outer skull, and skin. The surfaces are returned in the desired (by default, stereolithic .stl) format. Example ------- >>> from nipype.workflows.smri.freesurfer import create_bem_flow >>> bemflow = create_bem_flow() >>> bemflow.inputs.inputspec.subject_id = 'subj1' >>> bemflow.inputs.inputspec.subjects_dir = '.' >>> bemflow.run() # doctest: +SKIP Inputs:: inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects directory Outputs:: outputspec.meshes : output boundary element meshes in (by default) stereolithographic (.stl) format """ """ Initialize the workflow """ bemflow = pe.Workflow(name=name) """ Define the inputs to the workflow. """ inputnode = pe.Node(niu.IdentityInterface(fields=['subject_id', 'subjects_dir']), name='inputspec') """ Define all the nodes of the workflow: fssource: used to retrieve aseg.mgz mri_convert : converts aseg.mgz to aseg.nii tessellate : tessellates regions in aseg.mgz surfconvert : converts regions to stereolithographic (.stl) format """ watershed_bem = pe.Node(interface=mne.WatershedBEM(), name='WatershedBEM') surfconvert = pe.MapNode(fs.MRIsConvert(out_datatype=out_format), iterfield=['in_file'], name='surfconvert') """ Connect the nodes """ bemflow.connect([ (inputnode, watershed_bem, [('subject_id', 'subject_id'), ('subjects_dir', 'subjects_dir')]), (watershed_bem, surfconvert, [('mesh_files', 'in_file')]), ]) """ Setup an outputnode that defines relevant inputs of the workflow. """ outputnode = pe.Node(niu.IdentityInterface(fields=["meshes"]), name="outputspec") bemflow.connect([ (surfconvert, outputnode, [("converted", "meshes")]), ]) return bemflow nipype-0.11.0/nipype/workflows/smri/freesurfer/recon.py000066400000000000000000000065011257611314500232470ustar00rootroot00000000000000import nipype.pipeline.engine as pe import nipype.interfaces.freesurfer as fs import nipype.interfaces.utility as niu def create_skullstripped_recon_flow(name="skullstripped_recon_all"): """Performs recon-all on voulmes that are already skull stripped. FreeSurfer failes to perform skullstrippig on some volumes (especially MP2RAGE). This can be avoided by doing skullstripping before runnig recon-all (using for example SPECTRE algorithm) Example ------- >>> from nipype.workflows.smri.freesurfer import create_skullstripped_recon_flow >>> recon_flow = create_skullstripped_recon_flow() >>> recon_flow.inputs.inputspec.subject_id = 'subj1' >>> recon_flow.inputs.inputspec.T1_files = 'T1.nii.gz' >>> recon_flow.run() # doctest: +SKIP Inputs:: inputspec.T1_files : skullstripped T1_files (mandatory) inputspec.subject_id : freesurfer subject id (optional) inputspec.subjects_dir : freesurfer subjects directory (optional) Outputs:: outputspec.subject_id : freesurfer subject id outputspec.subjects_dir : freesurfer subjects directory """ wf = pe.Workflow(name=name) inputnode = pe.Node(niu.IdentityInterface(fields=['subject_id', 'subjects_dir', 'T1_files']), name='inputspec') autorecon1 = pe.Node(fs.ReconAll(), name="autorecon1") autorecon1.plugin_args={'submit_specs': 'request_memory = 2500'} autorecon1.inputs.directive = "autorecon1" autorecon1.inputs.args = "-noskullstrip" autorecon1._interface._can_resume = False wf.connect(inputnode, "T1_files", autorecon1, "T1_files") wf.connect(inputnode, "subjects_dir", autorecon1, "subjects_dir") wf.connect(inputnode, "subject_id", autorecon1, "subject_id") def link_masks(subjects_dir, subject_id): import os os.symlink(os.path.join(subjects_dir, subject_id, "mri", "T1.mgz"), os.path.join(subjects_dir, subject_id, "mri", "brainmask.auto.mgz")) os.symlink(os.path.join(subjects_dir, subject_id, "mri", "brainmask.auto.mgz"), os.path.join(subjects_dir, subject_id, "mri", "brainmask.mgz")) return subjects_dir, subject_id masks = pe.Node(niu.Function(input_names=['subjects_dir', 'subject_id'], output_names=['subjects_dir', 'subject_id'], function=link_masks), name="link_masks") wf.connect(autorecon1, "subjects_dir", masks, "subjects_dir") wf.connect(autorecon1, "subject_id", masks, "subject_id") autorecon_resume = pe.Node(fs.ReconAll(), name="autorecon_resume") autorecon_resume.plugin_args={'submit_specs': 'request_memory = 2500'} autorecon_resume.inputs.args = "-no-isrunning" wf.connect(masks, "subjects_dir", autorecon_resume, "subjects_dir") wf.connect(masks, "subject_id", autorecon_resume, "subject_id") outputnode = pe.Node(niu.IdentityInterface(fields=['subject_id', 'subjects_dir']), name='outputspec') wf.connect(autorecon_resume, "subjects_dir", outputnode, "subjects_dir") wf.connect(autorecon_resume, "subject_id", outputnode, "subject_id") return wf nipype-0.11.0/nipype/workflows/smri/freesurfer/utils.py000066400000000000000000000322551257611314500233060ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: import nipype.pipeline.engine as pe import nipype.interfaces.fsl as fsl import nipype.interfaces.freesurfer as fs import nipype.interfaces.meshfix as mf import nipype.interfaces.io as nio import nipype.interfaces.utility as niu import nipype.algorithms.misc as misc from nipype.interfaces.utility import Function from nipype.workflows.misc.utils import region_list_from_volume, id_list_from_lookup_table import os, os.path as op def get_aparc_aseg(files): """Return the aparc+aseg.mgz file""" for name in files: if 'aparc+aseg' in name: return name raise ValueError('aparc+aseg.mgz not found') def create_getmask_flow(name='getmask', dilate_mask=True): """Registers a source file to freesurfer space and create a brain mask in source space Requires fsl tools for initializing registration Parameters ---------- name : string name of workflow dilate_mask : boolean indicates whether to dilate mask or not Example ------- >>> getmask = create_getmask_flow() >>> getmask.inputs.inputspec.source_file = 'mean.nii' >>> getmask.inputs.inputspec.subject_id = 's1' >>> getmask.inputs.inputspec.subjects_dir = '.' >>> getmask.inputs.inputspec.contrast_type = 't2' Inputs:: inputspec.source_file : reference image for mask generation inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects directory inputspec.contrast_type : MR contrast of reference image Outputs:: outputspec.mask_file : binary mask file in reference image space outputspec.reg_file : registration file that maps reference image to freesurfer space outputspec.reg_cost : cost of registration (useful for detecting misalignment) """ """ Initialize the workflow """ getmask = pe.Workflow(name=name) """ Define the inputs to the workflow. """ inputnode = pe.Node(niu.IdentityInterface(fields=['source_file', 'subject_id', 'subjects_dir', 'contrast_type']), name='inputspec') """ Define all the nodes of the workflow: fssource: used to retrieve aseg.mgz threshold : binarize aseg register : coregister source file to freesurfer space voltransform: convert binarized aseg to source file space """ fssource = pe.Node(nio.FreeSurferSource(), name = 'fssource') threshold = pe.Node(fs.Binarize(min=0.5, out_type='nii'), name='threshold') register = pe.MapNode(fs.BBRegister(init='fsl'), iterfield=['source_file'], name='register') voltransform = pe.MapNode(fs.ApplyVolTransform(inverse=True), iterfield=['source_file', 'reg_file'], name='transform') """ Connect the nodes """ getmask.connect([ (inputnode, fssource, [('subject_id','subject_id'), ('subjects_dir','subjects_dir')]), (inputnode, register, [('source_file', 'source_file'), ('subject_id', 'subject_id'), ('subjects_dir', 'subjects_dir'), ('contrast_type', 'contrast_type')]), (inputnode, voltransform, [('subjects_dir', 'subjects_dir'), ('source_file', 'source_file')]), (fssource, threshold, [(('aparc_aseg', get_aparc_aseg), 'in_file')]), (register, voltransform, [('out_reg_file','reg_file')]), (threshold, voltransform, [('binary_file','target_file')]) ]) """ Add remaining nodes and connections dilate : dilate the transformed file in source space threshold2 : binarize transformed file """ threshold2 = pe.MapNode(fs.Binarize(min=0.5, out_type='nii'), iterfield=['in_file'], name='threshold2') if dilate_mask: threshold2.inputs.dilate = 1 getmask.connect([ (voltransform, threshold2, [('transformed_file', 'in_file')]) ]) """ Setup an outputnode that defines relevant inputs of the workflow. """ outputnode = pe.Node(niu.IdentityInterface(fields=["mask_file", "reg_file", "reg_cost" ]), name="outputspec") getmask.connect([ (register, outputnode, [("out_reg_file", "reg_file")]), (register, outputnode, [("min_cost_file", "reg_cost")]), (threshold2, outputnode, [("binary_file", "mask_file")]), ]) return getmask def create_get_stats_flow(name='getstats', withreg=False): """Retrieves stats from labels Parameters ---------- name : string name of workflow withreg : boolean indicates whether to register source to label Example ------- Inputs:: inputspec.source_file : reference image for mask generation inputspec.label_file : label file from which to get ROIs (optionally with registration) inputspec.reg_file : bbreg file (assumes reg from source to label inputspec.inverse : boolean whether to invert the registration inputspec.subjects_dir : freesurfer subjects directory Outputs:: outputspec.stats_file : stats file """ """ Initialize the workflow """ getstats = pe.Workflow(name=name) """ Define the inputs to the workflow. """ if withreg: inputnode = pe.Node(niu.IdentityInterface(fields=['source_file', 'label_file', 'reg_file', 'subjects_dir']), name='inputspec') else: inputnode = pe.Node(niu.IdentityInterface(fields=['source_file', 'label_file']), name='inputspec') statnode = pe.MapNode(fs.SegStats(), iterfield=['segmentation_file','in_file'], name='segstats') """ Convert between source and label spaces if registration info is provided """ if withreg: voltransform = pe.MapNode(fs.ApplyVolTransform(inverse=True), iterfield=['source_file', 'reg_file'], name='transform') getstats.connect(inputnode, 'reg_file', voltransform, 'reg_file') getstats.connect(inputnode, 'source_file', voltransform, 'source_file') getstats.connect(inputnode, 'label_file', voltransform, 'target_file') getstats.connect(inputnode, 'subjects_dir', voltransform, 'subjects_dir') def switch_labels(inverse, transform_output, source_file, label_file): if inverse: return transform_output, source_file else: return label_file, transform_output chooser = pe.MapNode(niu.Function(input_names = ['inverse', 'transform_output', 'source_file', 'label_file'], output_names = ['label_file', 'source_file'], function=switch_labels), iterfield=['transform_output','source_file'], name='chooser') getstats.connect(inputnode,'source_file', chooser, 'source_file') getstats.connect(inputnode,'label_file', chooser, 'label_file') getstats.connect(inputnode,'inverse', chooser, 'inverse') getstats.connect(voltransform, 'transformed_file', chooser, 'transform_output') getstats.connect(chooser, 'label_file', statnode, 'segmentation_file') getstats.connect(chooser, 'source_file', statnode, 'in_file') else: getstats.connect(inputnode, 'label_file', statnode, 'segmentation_file') getstats.connect(inputnode, 'source_file', statnode, 'in_file') """ Setup an outputnode that defines relevant inputs of the workflow. """ outputnode = pe.Node(niu.IdentityInterface(fields=["stats_file" ]), name="outputspec") getstats.connect([ (statnode, outputnode, [("summary_file", "stats_file")]), ]) return getstats def create_tessellation_flow(name='tessellate', out_format='stl'): """Tessellates the input subject's aseg.mgz volume and returns the surfaces for each region in stereolithic (.stl) format Example ------- >>> from nipype.workflows.smri.freesurfer import create_tessellation_flow >>> tessflow = create_tessellation_flow() >>> tessflow.inputs.inputspec.subject_id = 'subj1' >>> tessflow.inputs.inputspec.subjects_dir = '.' >>> tessflow.inputs.inputspec.lookup_file = 'FreeSurferColorLUT.txt' # doctest: +SKIP >>> tessflow.run() # doctest: +SKIP Inputs:: inputspec.subject_id : freesurfer subject id inputspec.subjects_dir : freesurfer subjects directory inputspec.lookup_file : lookup file from freesurfer directory Outputs:: outputspec.meshes : output region meshes in (by default) stereolithographic (.stl) format """ """ Initialize the workflow """ tessflow = pe.Workflow(name=name) """ Define the inputs to the workflow. """ inputnode = pe.Node(niu.IdentityInterface(fields=['subject_id', 'subjects_dir', 'lookup_file']), name='inputspec') """ Define all the nodes of the workflow: fssource: used to retrieve aseg.mgz mri_convert : converts aseg.mgz to aseg.nii tessellate : tessellates regions in aseg.mgz surfconvert : converts regions to stereolithographic (.stl) format smoother: smooths the tessellated regions """ fssource = pe.Node(nio.FreeSurferSource(), name = 'fssource') volconvert = pe.Node(fs.MRIConvert(out_type='nii'), name = 'volconvert') tessellate = pe.MapNode(fs.MRIMarchingCubes(), iterfield=['label_value','out_file'], name='tessellate') surfconvert = pe.MapNode(fs.MRIsConvert(out_datatype='stl'), iterfield=['in_file'], name='surfconvert') smoother = pe.MapNode(mf.MeshFix(), iterfield=['in_file1'], name='smoother') if out_format == 'gii': stl_to_gifti = pe.MapNode(fs.MRIsConvert(out_datatype=out_format), iterfield=['in_file'], name='stl_to_gifti') smoother.inputs.save_as_stl = True smoother.inputs.laplacian_smoothing_steps = 1 region_list_from_volume_interface = Function(input_names=["in_file"], output_names=["region_list"], function=region_list_from_volume) id_list_from_lookup_table_interface = Function(input_names=["lookup_file", "region_list"], output_names=["id_list"], function=id_list_from_lookup_table) region_list_from_volume_node = pe.Node(interface=region_list_from_volume_interface, name='region_list_from_volume_node') id_list_from_lookup_table_node = pe.Node(interface=id_list_from_lookup_table_interface, name='id_list_from_lookup_table_node') """ Connect the nodes """ tessflow.connect([ (inputnode, fssource, [('subject_id','subject_id'), ('subjects_dir','subjects_dir')]), (fssource, volconvert, [('aseg', 'in_file')]), (volconvert, region_list_from_volume_node, [('out_file', 'in_file')]), (region_list_from_volume_node, tessellate, [('region_list', 'label_value')]), (region_list_from_volume_node, id_list_from_lookup_table_node, [('region_list', 'region_list')]), (inputnode, id_list_from_lookup_table_node, [('lookup_file', 'lookup_file')]), (id_list_from_lookup_table_node, tessellate, [('id_list', 'out_file')]), (fssource, tessellate, [('aseg', 'in_file')]), (tessellate, surfconvert, [('surface','in_file')]), (surfconvert, smoother, [('converted','in_file1')]), ]) """ Setup an outputnode that defines relevant inputs of the workflow. """ outputnode = pe.Node(niu.IdentityInterface(fields=["meshes"]), name="outputspec") if out_format == 'gii': tessflow.connect([ (smoother, stl_to_gifti, [("mesh_file", "in_file")]), ]) tessflow.connect([ (stl_to_gifti, outputnode, [("converted", "meshes")]), ]) else: tessflow.connect([ (smoother, outputnode, [("mesh_file", "meshes")]), ]) return tessflow nipype-0.11.0/nipype/workflows/warp/000077500000000000000000000000001257611314500174145ustar00rootroot00000000000000nipype-0.11.0/nipype/workflows/warp/__init__.py000066400000000000000000000000011257611314500215140ustar00rootroot00000000000000 nipype-0.11.0/requirements.txt000066400000000000000000000001411257611314500163620ustar00rootroot00000000000000numpy>=1.6.2 scipy>=0.11 networkx>=1.7 traits>=4.3 python-dateutil>=1.5 nibabel>=2.0.1 nose>=1.2 nipype-0.11.0/setup.py000077500000000000000000000464151257611314500146310ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Nipype : Neuroimaging in Python pipelines and interfaces package. Nipype intends to create python interfaces to other neuroimaging packages and create an API for specifying a full analysis pipeline in python. Much of the machinery at the beginning of this file has been copied over from nibabel denoted by ## START - COPIED FROM NIBABEL and a corresponding ## END """ """Build helper.""" import os from os.path import join as pjoin from glob import glob import sys from functools import partial # BEFORE importing distutils, remove MANIFEST. distutils doesn't properly # update it when the contents of directories change. if os.path.exists('MANIFEST'): os.remove('MANIFEST') # For some commands, use setuptools. if len(set(('develop', 'bdist_egg', 'bdist_rpm', 'bdist', 'bdist_dumb', 'install_egg_info', 'egg_info', 'easy_install', 'bdist_wheel', 'bdist_mpkg')).intersection(sys.argv)) > 0: # setup_egg imports setuptools setup, thus monkeypatching distutils. import setup_egg from distutils.core import setup # Commit hash writing, and dependency checking ''' Distutils / setuptools helpers from nibabel.nisext''' import os from os.path import join as pjoin, split as psplit, splitext import sys PY3 = sys.version_info[0] >= 3 if PY3: string_types = str, else: string_types = basestring, try: from ConfigParser import ConfigParser except ImportError: from configparser import ConfigParser from distutils.version import LooseVersion from distutils.command.build_py import build_py from distutils.command.install_scripts import install_scripts from distutils import log def get_comrec_build(pkg_dir, build_cmd=build_py): """ Return extended build command class for recording commit The extended command tries to run git to find the current commit, getting the empty string if it fails. It then writes the commit hash into a file in the `pkg_dir` path, named ``COMMIT_INFO.txt``. In due course this information can be used by the package after it is installed, to tell you what commit it was installed from if known. To make use of this system, you need a package with a COMMIT_INFO.txt file - e.g. ``myproject/COMMIT_INFO.txt`` - that might well look like this:: # This is an ini file that may contain information about the code state [commit hash] # The line below may contain a valid hash if it has been substituted during 'git archive' archive_subst_hash=$Format:%h$ # This line may be modified by the install process install_hash= The COMMIT_INFO file above is also designed to be used with git substitution - so you probably also want a ``.gitattributes`` file in the root directory of your working tree that contains something like this:: myproject/COMMIT_INFO.txt export-subst That will cause the ``COMMIT_INFO.txt`` file to get filled in by ``git archive`` - useful in case someone makes such an archive - for example with via the github 'download source' button. Although all the above will work as is, you might consider having something like a ``get_info()`` function in your package to display the commit information at the terminal. See the ``pkg_info.py`` module in the nipy package for an example. """ class MyBuildPy(build_cmd): ''' Subclass to write commit data into installation tree ''' def run(self): build_cmd.run(self) import subprocess proc = subprocess.Popen('git rev-parse --short HEAD', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) repo_commit, _ = proc.communicate() # Fix for python 3 repo_commit = str(repo_commit) # We write the installation commit even if it's empty cfg_parser = ConfigParser() cfg_parser.read(pjoin(pkg_dir, 'COMMIT_INFO.txt')) cfg_parser.set('commit hash', 'install_hash', repo_commit) out_pth = pjoin(self.build_lib, pkg_dir, 'COMMIT_INFO.txt') cfg_parser.write(open(out_pth, 'wt')) return MyBuildPy def _add_append_key(in_dict, key, value): """ Helper for appending dependencies to setuptools args """ # If in_dict[key] does not exist, create it # If in_dict[key] is a string, make it len 1 list of strings # Append value to in_dict[key] list if key not in in_dict: in_dict[key] = [] elif isinstance(in_dict[key], string_types): in_dict[key] = [in_dict[key]] in_dict[key].append(value) # Dependency checks def package_check(pkg_name, version=None, optional=False, checker=LooseVersion, version_getter=None, messages=None, setuptools_args=None ): ''' Check if package `pkg_name` is present and has good enough version Has two modes of operation. If `setuptools_args` is None (the default), raise an error for missing non-optional dependencies and log warnings for missing optional dependencies. If `setuptools_args` is a dict, then fill ``install_requires`` key value with any missing non-optional dependencies, and the ``extras_requires`` key value with optional dependencies. This allows us to work with and without setuptools. It also means we can check for packages that have not been installed with setuptools to avoid installing them again. Parameters ---------- pkg_name : str name of package as imported into python version : {None, str}, optional minimum version of the package that we require. If None, we don't check the version. Default is None optional : bool or str, optional If ``bool(optional)`` is False, raise error for absent package or wrong version; otherwise warn. If ``setuptools_args`` is not None, and ``bool(optional)`` is not False, then `optional` should be a string giving the feature name for the ``extras_require`` argument to setup. checker : callable, optional callable with which to return comparable thing from version string. Default is ``distutils.version.LooseVersion`` version_getter : {None, callable}: Callable that takes `pkg_name` as argument, and returns the package version string - as in:: ``version = version_getter(pkg_name)`` If None, equivalent to:: mod = __import__(pkg_name); version = mod.__version__`` messages : None or dict, optional dictionary giving output messages setuptools_args : None or dict If None, raise errors / warnings for missing non-optional / optional dependencies. If dict fill key values ``install_requires`` and ``extras_require`` for non-optional and optional dependencies. ''' setuptools_mode = not setuptools_args is None optional_tf = bool(optional) if version_getter is None: def version_getter(pkg_name): mod = __import__(pkg_name) return mod.__version__ if messages is None: messages = {} msgs = { 'missing': 'Cannot import package "%s" - is it installed?', 'missing opt': 'Missing optional package "%s"', 'opt suffix' : '; you may get run-time errors', 'version too old': 'You have version %s of package "%s"' ' but we need version >= %s', } msgs.update(messages) status, have_version = _package_status(pkg_name, version, version_getter, checker) if status == 'satisfied': return if not setuptools_mode: if status == 'missing': if not optional_tf: raise RuntimeError(msgs['missing'] % pkg_name) log.warn(msgs['missing opt'] % pkg_name + msgs['opt suffix']) return elif status == 'no-version': raise RuntimeError('Cannot find version for %s' % pkg_name) assert status == 'low-version' if not optional_tf: raise RuntimeError(msgs['version too old'] % (have_version, pkg_name, version)) log.warn(msgs['version too old'] % (have_version, pkg_name, version) + msgs['opt suffix']) return # setuptools mode if optional_tf and not isinstance(optional, string_types): raise RuntimeError('Not-False optional arg should be string') dependency = pkg_name if version: dependency += '>=' + version if optional_tf: if not 'extras_require' in setuptools_args: setuptools_args['extras_require'] = {} _add_append_key(setuptools_args['extras_require'], optional, dependency) return #_add_append_key(setuptools_args, 'install_requires', dependency) return def _package_status(pkg_name, version, version_getter, checker): try: __import__(pkg_name) except ImportError: return 'missing', None if not version: return 'satisfied', None try: have_version = version_getter(pkg_name) except AttributeError: return 'no-version', None if checker(have_version) < checker(version): return 'low-version', have_version return 'satisfied', have_version cmdclass = {'build_py': get_comrec_build('nipype')} # Get version and release info, which is all stored in nipype/info.py ver_file = os.path.join('nipype', 'info.py') exec(open(ver_file).read()) # Prepare setuptools args if 'setuptools' in sys.modules: extra_setuptools_args = dict( tests_require=['nose'], test_suite='nose.collector', zip_safe=False, extras_require = dict( doc='Sphinx>=0.3', test='nose>=0.10.1'), ) pkg_chk = partial(package_check, setuptools_args = extra_setuptools_args) else: extra_setuptools_args = {} pkg_chk = package_check # Do dependency checking pkg_chk('networkx', NETWORKX_MIN_VERSION) pkg_chk('nibabel', NIBABEL_MIN_VERSION) pkg_chk('numpy', NUMPY_MIN_VERSION) pkg_chk('scipy', SCIPY_MIN_VERSION) pkg_chk('traits', TRAITS_MIN_VERSION) pkg_chk('nose', NOSE_MIN_VERSION) custom_dateutil_messages = {'missing opt': ('Missing optional package "%s"' ' provided by package ' '"python-dateutil"')} pkg_chk('dateutil', DATEUTIL_MIN_VERSION, messages = custom_dateutil_messages) def main(**extra_args): setup(name=NAME, maintainer=MAINTAINER, maintainer_email=MAINTAINER_EMAIL, description=DESCRIPTION, long_description=LONG_DESCRIPTION, url=URL, download_url=DOWNLOAD_URL, license=LICENSE, classifiers=CLASSIFIERS, author=AUTHOR, author_email=AUTHOR_EMAIL, platforms=PLATFORMS, version=VERSION, install_requires=REQUIRES, provides=PROVIDES, packages = [ 'nipype', 'nipype.algorithms', 'nipype.algorithms.tests', 'nipype.caching', 'nipype.caching.tests', 'nipype.external', 'nipype.fixes', 'nipype.fixes.numpy', 'nipype.fixes.numpy.testing', 'nipype.interfaces', 'nipype.interfaces.afni', 'nipype.interfaces.afni.tests', 'nipype.interfaces.ants', 'nipype.interfaces.ants.tests', 'nipype.interfaces.camino', 'nipype.interfaces.camino.tests', 'nipype.interfaces.camino2trackvis', 'nipype.interfaces.camino2trackvis.tests', 'nipype.interfaces.cmtk', 'nipype.interfaces.cmtk.tests', 'nipype.interfaces.diffusion_toolkit', 'nipype.interfaces.diffusion_toolkit.tests', 'nipype.interfaces.dipy', 'nipype.interfaces.dipy.tests', 'nipype.interfaces.elastix', 'nipype.interfaces.elastix.tests', 'nipype.interfaces.freesurfer', 'nipype.interfaces.freesurfer.tests', 'nipype.interfaces.fsl', 'nipype.interfaces.fsl.tests', 'nipype.interfaces.mipav', 'nipype.interfaces.mipav.tests', 'nipype.interfaces.mne', 'nipype.interfaces.mne.tests', 'nipype.interfaces.mrtrix', 'nipype.interfaces.mrtrix.tests', 'nipype.interfaces.nipy', 'nipype.interfaces.nipy.tests', 'nipype.interfaces.nitime', 'nipype.interfaces.nitime.tests', 'nipype.interfaces.script_templates', 'nipype.interfaces.semtools', 'nipype.interfaces.semtools.brains', 'nipype.interfaces.semtools.brains.tests', 'nipype.interfaces.semtools.diffusion', 'nipype.interfaces.semtools.diffusion.tests', 'nipype.interfaces.semtools.diffusion.tractography', 'nipype.interfaces.semtools.diffusion.tractography.tests', 'nipype.interfaces.semtools.filtering', 'nipype.interfaces.semtools.filtering.tests', 'nipype.interfaces.semtools.legacy', 'nipype.interfaces.semtools.legacy.tests', 'nipype.interfaces.semtools.registration', 'nipype.interfaces.semtools.registration.tests', 'nipype.interfaces.semtools.segmentation', 'nipype.interfaces.semtools.segmentation.tests', 'nipype.interfaces.semtools.testing', 'nipype.interfaces.semtools.tests', 'nipype.interfaces.semtools.utilities', 'nipype.interfaces.semtools.utilities.tests', 'nipype.interfaces.slicer', 'nipype.interfaces.slicer.diffusion', 'nipype.interfaces.slicer.diffusion.tests', 'nipype.interfaces.slicer.filtering', 'nipype.interfaces.slicer.filtering.tests', 'nipype.interfaces.slicer.legacy', 'nipype.interfaces.slicer.legacy.diffusion', 'nipype.interfaces.slicer.legacy.diffusion.tests', 'nipype.interfaces.slicer.legacy.tests', 'nipype.interfaces.slicer.quantification', 'nipype.interfaces.slicer.quantification.tests', 'nipype.interfaces.slicer.registration', 'nipype.interfaces.slicer.registration.tests', 'nipype.interfaces.slicer.segmentation', 'nipype.interfaces.slicer.segmentation.tests', 'nipype.interfaces.slicer.tests', 'nipype.interfaces.spm', 'nipype.interfaces.spm.tests', 'nipype.interfaces.tests', 'nipype.interfaces.vista', 'nipype.interfaces.vista.tests', 'nipype.pipeline', 'nipype.pipeline.plugins', 'nipype.pipeline.plugins.tests', 'nipype.pipeline.tests', 'nipype.testing', 'nipype.testing.data', 'nipype.testing.data.bedpostxout', 'nipype.testing.data.dicomdir', 'nipype.testing.data.tbss_dir', 'nipype.utils', 'nipype.utils.tests', 'nipype.workflows', 'nipype.workflows.data', 'nipype.workflows.dmri', 'nipype.workflows.dmri.camino', 'nipype.workflows.dmri.connectivity', 'nipype.workflows.dmri.dipy', 'nipype.workflows.dmri.fsl', 'nipype.workflows.dmri.fsl.tests', 'nipype.workflows.dmri.mrtrix', 'nipype.workflows.fmri', 'nipype.workflows.fmri.fsl', 'nipype.workflows.fmri.fsl.tests', 'nipype.workflows.fmri.spm', 'nipype.workflows.fmri.spm.tests', 'nipype.workflows.graph', 'nipype.workflows.misc', 'nipype.workflows.rsfmri', 'nipype.workflows.rsfmri.fsl', 'nipype.workflows.smri', 'nipype.workflows.smri.ants', 'nipype.workflows.smri.freesurfer', 'nipype.workflows.warp'], # The package_data spec has no effect for me (on python 2.6) -- even # changing to data_files doesn't get this stuff included in the source # distribution -- not sure if it has something to do with the magic # above, but distutils is surely the worst piece of code in all of # python -- duplicating things into MANIFEST.in but this is admittedly # only a workaround to get things started -- not a solution package_data = {'nipype': [pjoin('testing', 'data', '*'), pjoin('testing', 'data', 'dicomdir', '*'), pjoin('testing', 'data', 'bedpostxout', '*'), pjoin('testing', 'data', 'tbss_dir', '*'), pjoin('workflows', 'data', '*'), pjoin('pipeline', 'report_template.html'), pjoin('external', 'd3.js'), pjoin('interfaces', 'script_templates', '*'), pjoin('interfaces', 'tests', 'realign_json.json') ]}, scripts = glob('bin/*'), cmdclass = cmdclass, **extra_args ) if __name__ == "__main__": main(**extra_setuptools_args) nipype-0.11.0/setup_egg.py000077500000000000000000000013101257611314500154340ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Wrapper to run setup.py using setuptools.""" from setuptools import setup ################################################################################ # Call the setup.py script, injecting the setuptools-specific arguments. extra_setuptools_args = dict(tests_require=['nose'], test_suite='nose.collector', zip_safe=False, ) if __name__ == '__main__': execfile('setup.py', dict(__name__='__main__', extra_setuptools_args=extra_setuptools_args)) nipype-0.11.0/tools/000077500000000000000000000000001257611314500142425ustar00rootroot00000000000000nipype-0.11.0/tools/README000066400000000000000000000006601257611314500151240ustar00rootroot00000000000000============== Nipype Tools ============== This directory contains various tools used by the nipype developers. Only install tools here that are unique to the nipype project. Any tools shared with our parent project, nipy, should go in the nipy/tools directory. Exceptions ---------- * apigen.py: This is not importable from nipy, so I copied it. * build_modref_templates.py: This was copied and modified to work with nipype. nipype-0.11.0/tools/apigen.py000066400000000000000000000370501257611314500160640ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Attempt to generate templates for module reference with Sphinx XXX - we exclude extension modules To include extension modules, first identify them as valid in the ``_uri2path`` method, then handle them in the ``_parse_module`` script. We get functions and classes by parsing the text of .py files. Alternatively we could import the modules for discovery, and we'd have to do that for extension modules. This would involve changing the ``_parse_module`` method to work via import and introspection, and might involve changing ``discover_modules`` (which determines which files are modules, and therefore which module URIs will be passed to ``_parse_module``). NOTE: this is a modified version of a script originally shipped with the PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed project.""" # Stdlib imports from __future__ import print_function import os import re # Functions and classes class ApiDocWriter(object): ''' Class for automatic detection and parsing of API docs to Sphinx-parsable reST format''' # only separating first two levels rst_section_levels = ['*', '=', '-', '~', '^'] def __init__(self, package_name, rst_extension='.rst', package_skip_patterns=None, module_skip_patterns=None, ): ''' Initialize package for parsing Parameters ---------- package_name : string Name of the top-level package. *package_name* must be the name of an importable package rst_extension : string, optional Extension for reST files, default '.rst' package_skip_patterns : None or sequence of {strings, regexps} Sequence of strings giving URIs of packages to be excluded Operates on the package path, starting at (including) the first dot in the package path, after *package_name* - so, if *package_name* is ``sphinx``, then ``sphinx.util`` will result in ``.util`` being passed for earching by these regexps. If is None, gives default. Default is: ['\.tests$'] module_skip_patterns : None or sequence Sequence of strings giving URIs of modules to be excluded Operates on the module name including preceding URI path, back to the first dot after *package_name*. For example ``sphinx.util.console`` results in the string to search of ``.util.console`` If is None, gives default. Default is: ['\.setup$', '\._'] ''' if package_skip_patterns is None: package_skip_patterns = ['\\.tests$'] if module_skip_patterns is None: module_skip_patterns = ['\\.setup$', '\\._'] self.package_name = package_name self.rst_extension = rst_extension self.package_skip_patterns = package_skip_patterns self.module_skip_patterns = module_skip_patterns def get_package_name(self): return self._package_name def set_package_name(self, package_name): ''' Set package_name >>> docwriter = ApiDocWriter('sphinx') >>> import sphinx >>> docwriter.root_path == sphinx.__path__[0] True >>> docwriter.package_name = 'docutils' >>> import docutils >>> docwriter.root_path == docutils.__path__[0] True ''' # It's also possible to imagine caching the module parsing here self._package_name = package_name self.root_module = __import__(package_name) self.root_path = self.root_module.__path__[0] self.written_modules = None package_name = property(get_package_name, set_package_name, None, 'get/set package_name') def _get_object_name(self, line): ''' Get second token in line >>> docwriter = ApiDocWriter('sphinx') >>> docwriter._get_object_name(" def func(): ") 'func' >>> docwriter._get_object_name(" class Klass(object): ") 'Klass' >>> docwriter._get_object_name(" class Klass: ") 'Klass' ''' name = line.split()[1].split('(')[0].strip() # in case we have classes which are not derived from object # ie. old style classes return name.rstrip(':') def _uri2path(self, uri): ''' Convert uri to absolute filepath Parameters ---------- uri : string URI of python module to return path for Returns ------- path : None or string Returns None if there is no valid path for this URI Otherwise returns absolute file system path for URI Examples -------- >>> docwriter = ApiDocWriter('sphinx') >>> import sphinx >>> modpath = sphinx.__path__[0] >>> res = docwriter._uri2path('sphinx.builder') >>> res == os.path.join(modpath, 'builder.py') True >>> res = docwriter._uri2path('sphinx') >>> res == os.path.join(modpath, '__init__.py') True >>> docwriter._uri2path('sphinx.does_not_exist') ''' if uri == self.package_name: return os.path.join(self.root_path, '__init__.py') path = uri.replace('.', os.path.sep) path = path.replace(self.package_name + os.path.sep, '') path = os.path.join(self.root_path, path) # XXX maybe check for extensions as well? if os.path.exists(path + '.py'): # file path += '.py' elif os.path.exists(os.path.join(path, '__init__.py')): path = os.path.join(path, '__init__.py') else: return None return path def _path2uri(self, dirpath): ''' Convert directory path to uri ''' relpath = dirpath.replace(self.root_path, self.package_name) if relpath.startswith(os.path.sep): relpath = relpath[1:] return relpath.replace(os.path.sep, '.') def _parse_module(self, uri): ''' Parse module defined in *uri* ''' filename = self._uri2path(uri) if filename is None: # nothing that we could handle here. return ([], []) f = open(filename, 'rt') functions, classes = self._parse_lines(f) f.close() return functions, classes def _parse_lines(self, linesource): ''' Parse lines of text for functions and classes ''' functions = [] classes = [] for line in linesource: if line.startswith('def ') and line.count('('): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_'): functions.append(name) elif line.startswith('class '): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_'): classes.append(name) else: pass functions.sort() classes.sort() return functions, classes def generate_api_doc(self, uri): '''Make autodoc documentation template string for a module Parameters ---------- uri : string python location of module - e.g 'sphinx.builder' Returns ------- S : string Contents of API doc ''' # get the names of all classes and functions functions, classes = self._parse_module(uri) if not len(functions) and not len(classes): print(('WARNING: Empty -', uri)) # dbg return '' # Make a shorter version of the uri that omits the package name for # titles uri_short = re.sub(r'^%s\.' % self.package_name, '', uri) ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n' chap_title = uri_short ad += (chap_title + '\n' + self.rst_section_levels[1] * len(chap_title) + '\n\n') # Set the chapter title to read 'module' for all modules except for the # main packages if '.' in uri: title = 'Module: :mod:`' + uri_short + '`' else: title = ':mod:`' + uri_short + '`' ad += title + '\n' + self.rst_section_levels[2] * len(title) if len(classes): ad += '\nInheritance diagram for ``%s``:\n\n' % uri ad += '.. inheritance-diagram:: %s \n' % uri ad += ' :parts: 2\n' ad += '\n.. automodule:: ' + uri + '\n' ad += '\n.. currentmodule:: ' + uri + '\n' multi_class = len(classes) > 1 multi_fx = len(functions) > 1 if multi_class: ad += '\n' + 'Classes' + '\n' + \ self.rst_section_levels[2] * 7 + '\n' elif len(classes) and multi_fx: ad += '\n' + 'Class' + '\n' + \ self.rst_section_levels[2] * 5 + '\n' for c in classes: ad += '\n:class:`' + c + '`\n' \ + self.rst_section_levels[multi_class + 2] * \ (len(c) + 9) + '\n\n' ad += '\n.. autoclass:: ' + c + '\n' # must NOT exclude from index to keep cross-refs working ad += ' :members:\n' \ ' :undoc-members:\n' \ ' :show-inheritance:\n' \ ' :inherited-members:\n' \ '\n' \ ' .. automethod:: __init__\n' if multi_fx: ad += '\n' + 'Functions' + '\n' + \ self.rst_section_levels[2] * 9 + '\n\n' elif len(functions) and multi_class: ad += '\n' + 'Function' + '\n' + \ self.rst_section_levels[2] * 8 + '\n\n' for f in functions: # must NOT exclude from index to keep cross-refs working ad += '\n.. autofunction:: ' + uri + '.' + f + '\n\n' return ad def _survives_exclude(self, matchstr, match_type): ''' Returns True if *matchstr* does not match patterns ``self.package_name`` removed from front of string if present Examples -------- >>> dw = ApiDocWriter('sphinx') >>> dw._survives_exclude('sphinx.okpkg', 'package') True >>> dw.package_skip_patterns.append('^\\.badpkg$') >>> dw._survives_exclude('sphinx.badpkg', 'package') False >>> dw._survives_exclude('sphinx.badpkg', 'module') True >>> dw._survives_exclude('sphinx.badmod', 'module') True >>> dw.module_skip_patterns.append('^\\.badmod$') >>> dw._survives_exclude('sphinx.badmod', 'module') False ''' if match_type == 'module': patterns = self.module_skip_patterns elif match_type == 'package': patterns = self.package_skip_patterns else: raise ValueError('Cannot interpret match type "%s"' % match_type) # Match to URI without package name L = len(self.package_name) if matchstr[:L] == self.package_name: matchstr = matchstr[L:] for pat in patterns: #print (pat, matchstr, match_type) #dbg try: pat.search except AttributeError: pat = re.compile(pat) #print (pat.search(matchstr)) #dbg if pat.search(matchstr): return False return True def discover_modules(self): ''' Return module sequence discovered from ``self.package_name`` Parameters ---------- None Returns ------- mods : sequence Sequence of module names within ``self.package_name`` Examples -------- >>> dw = ApiDocWriter('sphinx') >>> mods = dw.discover_modules() >>> 'sphinx.util' in mods True >>> dw.package_skip_patterns.append('\.util$') >>> 'sphinx.util' in dw.discover_modules() False >>> ''' modules = [] # raw directory parsing for dirpath, dirnames, filenames in os.walk(self.root_path): # Check directory names for packages root_uri = self._path2uri(os.path.join(self.root_path, dirpath)) for dirname in dirnames[:]: # copy list - we modify inplace package_uri = '.'.join((root_uri, dirname)) if (self._uri2path(package_uri) and self._survives_exclude(package_uri, 'package')): modules.append(package_uri) else: dirnames.remove(dirname) # Check filenames for modules for filename in filenames: module_name = filename[:-3] module_uri = '.'.join((root_uri, module_name)) if (self._uri2path(module_uri) and self._survives_exclude(module_uri, 'module')): modules.append(module_uri) #print sorted(modules) #dbg return sorted(modules) def write_modules_api(self, modules, outdir): # write the list written_modules = [] for m in modules: api_str = self.generate_api_doc(m) if not api_str: continue # write out to file outfile = os.path.join(outdir, m + self.rst_extension) fileobj = open(outfile, 'wt') fileobj.write(api_str) fileobj.close() written_modules.append(m) self.written_modules = written_modules def write_api_docs(self, outdir): """Generate API reST files. Parameters ---------- outdir : string Directory name in which to store files We create automatic filenames for each module Returns ------- None Notes ----- Sets self.written_modules to list of written modules """ if not os.path.exists(outdir): os.mkdir(outdir) # compose list of modules modules = self.discover_modules() self.write_modules_api(modules, outdir) def write_index(self, outdir, froot='gen', relative_to=None): """Make a reST API index file from written files Parameters ---------- path : string Filename to write index to outdir : string Directory to which to write generated index file froot : string, optional root (filename without extension) of filename to write to Defaults to 'gen'. We add ``self.rst_extension``. relative_to : string path to which written filenames are relative. This component of the written file path will be removed from outdir, in the generated index. Default is None, meaning, leave path as it is. """ if self.written_modules is None: raise ValueError('No modules written') # Get full filename path path = os.path.join(outdir, froot + self.rst_extension) # Path written into index is relative to rootpath if relative_to is not None: relpath = outdir.replace(relative_to + os.path.sep, '') else: relpath = outdir idx = open(path, 'wt') w = idx.write w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') w('.. toctree::\n\n') for f in self.written_modules: w(' %s\n' % os.path.join(relpath, f)) idx.close() nipype-0.11.0/tools/build_interface_docs.py000077500000000000000000000052301257611314500207460ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Script to auto-generate interface docs. """ # stdlib imports import os import sys #***************************************************************************** if __name__ == '__main__': nipypepath = os.path.abspath('..') sys.path.insert(1,nipypepath) # local imports from interfacedocgen import InterfaceHelpWriter package = 'nipype' outdir = os.path.join('interfaces','generated') docwriter = InterfaceHelpWriter(package) # Packages that should not be included in generated API docs. docwriter.package_skip_patterns += ['\.external$', '\.fixes$', '\.utils$', '\.pipeline', '\.testing', '\.caching', ] # Modules that should not be included in generated API docs. docwriter.module_skip_patterns += ['\.version$', '\.interfaces\.base$', '\.interfaces\.matlab$', '\.interfaces\.rest$', '\.interfaces\.pymvpa$', '\.interfaces\.slicer\.generate_classes$', '\.interfaces\.spm\.base$', '\.interfaces\.traits', '\.pipeline\.alloy$', '\.pipeline\.s3_node_wrapper$', '.\testing', ] docwriter.class_skip_patterns += ['AFNI', 'ANTS', 'FSL', 'FS', 'Info', '^SPM', 'Tester', 'Spec$', 'Numpy' # NipypeTester raises an # exception when instantiated in # InterfaceHelpWriter.generate_api_doc 'NipypeTester', ] docwriter.write_api_docs(outdir) docwriter.write_index(outdir, 'gen', relative_to='interfaces') print '%d files written' % len(docwriter.written_modules) nipype-0.11.0/tools/build_modref_templates.py000077500000000000000000000033451257611314500213350ustar00rootroot00000000000000#!/usr/bin/env python # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Script to auto-generate our API docs. """ # stdlib imports import os import sys #***************************************************************************** if __name__ == '__main__': nipypepath = os.path.abspath('..') sys.path.insert(1, nipypepath) package = 'nipype' # local imports from apigen import ApiDocWriter outdir = os.path.join('api', 'generated') docwriter = ApiDocWriter(package) # Packages that should not be included in generated API docs. docwriter.package_skip_patterns += ['\.external$', '\.utils$', '\.interfaces\.', '\.workflows$', '\.pipeline\.plugins$', '\.testing$', '\.fixes$', '\.algorithms$', ] # Modules that should not be included in generated API docs. docwriter.module_skip_patterns += ['\.version$', 'info', '\.interfaces\.(?!(base|matlab))', '\.pipeline\.utils$', '\.interfaces\.slicer\.generate_classes$', '\.interfaces\.pymvpa$', ] docwriter.write_api_docs(outdir) docwriter.write_index(outdir, 'gen', relative_to='api') print '%d files written' % len(docwriter.written_modules) nipype-0.11.0/tools/checkspecs.py000066400000000000000000000417271257611314500167420ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Attempt to check each interface in nipype """ # Stdlib imports import inspect import os import re import sys import tempfile import warnings from nipype.external import six from nipype.interfaces.base import BaseInterface # Functions and classes class InterfaceChecker(object): """Class for checking all interface specifications """ def __init__(self, package_name, package_skip_patterns=None, module_skip_patterns=None, class_skip_patterns=None ): ''' Initialize package for parsing Parameters ---------- package_name : string Name of the top-level package. *package_name* must be the name of an importable package package_skip_patterns : None or sequence of {strings, regexps} Sequence of strings giving URIs of packages to be excluded Operates on the package path, starting at (including) the first dot in the package path, after *package_name* - so, if *package_name* is ``sphinx``, then ``sphinx.util`` will result in ``.util`` being passed for earching by these regexps. If is None, gives default. Default is: ['\.tests$'] module_skip_patterns : None or sequence Sequence of strings giving URIs of modules to be excluded Operates on the module name including preceding URI path, back to the first dot after *package_name*. For example ``sphinx.util.console`` results in the string to search of ``.util.console`` If is None, gives default. Default is: ['\.setup$', '\._'] class_skip_patterns : None or sequence Sequence of strings giving classes to be excluded Default is: None ''' if package_skip_patterns is None: package_skip_patterns = ['\\.tests$'] if module_skip_patterns is None: module_skip_patterns = ['\\.setup$', '\\._'] if class_skip_patterns: self.class_skip_patterns = class_skip_patterns else: self.class_skip_patterns = [] self.package_name = package_name self.package_skip_patterns = package_skip_patterns self.module_skip_patterns = module_skip_patterns def get_package_name(self): return self._package_name def set_package_name(self, package_name): """Set package_name""" # It's also possible to imagine caching the module parsing here self._package_name = package_name self.root_module = __import__(package_name) self.root_path = self.root_module.__path__[0] package_name = property(get_package_name, set_package_name, None, 'get/set package_name') def _get_object_name(self, line): name = line.split()[1].split('(')[0].strip() # in case we have classes which are not derived from object # ie. old style classes return name.rstrip(':') def _uri2path(self, uri): """Convert uri to absolute filepath Parameters ---------- uri : string URI of python module to return path for Returns ------- path : None or string Returns None if there is no valid path for this URI Otherwise returns absolute file system path for URI """ if uri == self.package_name: return os.path.join(self.root_path, '__init__.py') path = uri.replace('.', os.path.sep) path = path.replace(self.package_name + os.path.sep, '') path = os.path.join(self.root_path, path) # XXX maybe check for extensions as well? if os.path.exists(path + '.py'): # file path += '.py' elif os.path.exists(os.path.join(path, '__init__.py')): path = os.path.join(path, '__init__.py') else: return None return path def _path2uri(self, dirpath): ''' Convert directory path to uri ''' relpath = dirpath.replace(self.root_path, self.package_name) if relpath.startswith(os.path.sep): relpath = relpath[1:] return relpath.replace(os.path.sep, '.') def _parse_module(self, uri): ''' Parse module defined in *uri* ''' filename = self._uri2path(uri) if filename is None: # nothing that we could handle here. return ([],[]) f = open(filename, 'rt') functions, classes = self._parse_lines(f, uri) f.close() return functions, classes def _parse_lines(self, linesource, module): ''' Parse lines of text for functions and classes ''' functions = [] classes = [] for line in linesource: if line.startswith('def ') and line.count('('): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_'): functions.append(name) elif line.startswith('class '): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_') and \ self._survives_exclude('.'.join((module, name)), 'class'): classes.append(name) else: pass functions.sort() classes.sort() return functions, classes def test_specs(self, uri): """Check input and output specs in an uri Parameters ---------- uri : string python location of module - e.g 'sphinx.builder' Returns ------- """ # get the names of all classes and functions _, classes = self._parse_module(uri) if not classes: #print 'WARNING: Empty -',uri # dbg return None # Make a shorter version of the uri that omits the package name for # titles uri_short = re.sub(r'^%s\.' % self.package_name, '', uri) allowed_keys = ['desc', 'genfile', 'xor', 'requires', 'desc', 'nohash', 'argstr', 'position', 'mandatory', 'copyfile', 'usedefault', 'sep', 'hash_files', 'deprecated', 'new_name', 'min_ver', 'max_ver', 'name_source', 'name_template', 'keep_extension', 'units', 'output_name'] in_built = ['type', 'copy', 'parent', 'instance_handler', 'comparison_mode', 'array', 'default', 'editor'] bad_specs = [] for c in classes: __import__(uri) try: with warnings.catch_warnings(): warnings.simplefilter("ignore") classinst = sys.modules[uri].__dict__[c] except Exception as inst: continue if not issubclass(classinst, BaseInterface): continue testdir = os.path.join(*(uri.split('.')[:-1] + ['tests'])) if not os.path.exists(testdir): os.makedirs(testdir) nonautotest = os.path.join(testdir, 'test_%s.py' % c) testfile = os.path.join(testdir, 'test_auto_%s.py' % c) if os.path.exists(testfile): os.unlink(testfile) if not os.path.exists(nonautotest): with open(testfile, 'wt') as fp: cmd = ['# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT', 'from nipype.testing import assert_equal', 'from %s import %s' % (uri, c), ''] cmd.append('def test_%s_inputs():' % c) input_fields = '' for traitname, trait in sorted(classinst.input_spec().traits(transient=None).items()): input_fields += '%s=dict(' % traitname for key, value in sorted(trait.__dict__.items()): if key in in_built or key == 'desc': continue if isinstance(value, six.string_types): quote = "'" if "'" in value: quote = '"' input_fields += "%s=%s%s%s,\n " % (key, quote, value, quote) else: input_fields += "%s=%s,\n " % (key, value) input_fields += '),\n ' cmd += [' input_map = dict(%s)' % input_fields] cmd += [' inputs = %s.input_spec()' % c] cmd += [""" for key, metadata in input_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(inputs.traits()[key], metakey), value"""] fp.writelines('\n'.join(cmd) + '\n\n') else: print('%s has nonautotest' % c) for traitname, trait in sorted(classinst.input_spec().traits(transient=None).items()): for key in sorted(trait.__dict__): if key in in_built: continue parent_metadata = [] if 'parent' in trait.__dict__: parent_metadata = getattr(trait, 'parent').__dict__.keys() if key not in allowed_keys + classinst._additional_metadata\ + parent_metadata: bad_specs.append([uri, c, 'Inputs', traitname, key]) if key == 'mandatory' and trait.mandatory is not None and not trait.mandatory: bad_specs.append([uri, c, 'Inputs', traitname, 'mandatory=False']) if not classinst.output_spec: continue if not os.path.exists(nonautotest): with open(testfile, 'at') as fp: cmd = ['def test_%s_outputs():' % c] input_fields = '' for traitname, trait in sorted(classinst.output_spec().traits(transient=None).items()): input_fields += '%s=dict(' % traitname for key, value in sorted(trait.__dict__.items()): if key in in_built or key == 'desc': continue if isinstance(value, six.string_types): quote = "'" if "'" in value: quote = '"' input_fields += "%s=%s%s%s,\n " % (key, quote, value, quote) else: input_fields += "%s=%s,\n " % (key, value) input_fields += '),\n ' cmd += [' output_map = dict(%s)' % input_fields] cmd += [' outputs = %s.output_spec()' % c] cmd += [""" for key, metadata in output_map.items(): for metakey, value in metadata.items(): yield assert_equal, getattr(outputs.traits()[key], metakey), value"""] fp.writelines('\n'.join(cmd) + '\n\n') for traitname, trait in sorted(classinst.output_spec().traits(transient=None).items()): for key in sorted(trait.__dict__): if key in in_built: continue parent_metadata = [] if 'parent' in trait.__dict__: parent_metadata = getattr(trait, 'parent').__dict__.keys() if key not in allowed_keys + classinst._additional_metadata\ + parent_metadata: bad_specs.append([uri, c, 'Outputs', traitname, key]) return bad_specs def _survives_exclude(self, matchstr, match_type): ''' Returns True if *matchstr* does not match patterns ``self.package_name`` removed from front of string if present Examples -------- >>> dw = ApiDocWriter('sphinx') >>> dw._survives_exclude('sphinx.okpkg', 'package') True >>> dw.package_skip_patterns.append('^\\.badpkg$') >>> dw._survives_exclude('sphinx.badpkg', 'package') False >>> dw._survives_exclude('sphinx.badpkg', 'module') True >>> dw._survives_exclude('sphinx.badmod', 'module') True >>> dw.module_skip_patterns.append('^\\.badmod$') >>> dw._survives_exclude('sphinx.badmod', 'module') False ''' if match_type == 'module': patterns = self.module_skip_patterns elif match_type == 'package': patterns = self.package_skip_patterns elif match_type == 'class': patterns = self.class_skip_patterns else: raise ValueError('Cannot interpret match type "%s"' % match_type) # Match to URI without package name L = len(self.package_name) if matchstr[:L] == self.package_name: matchstr = matchstr[L:] for pat in patterns: try: pat.search except AttributeError: pat = re.compile(pat) if pat.search(matchstr): return False return True def discover_modules(self): ''' Return module sequence discovered from ``self.package_name`` Parameters ---------- None Returns ------- mods : sequence Sequence of module names within ``self.package_name`` Examples -------- ''' modules = [self.package_name] # raw directory parsing for dirpath, dirnames, filenames in os.walk(self.root_path): # Check directory names for packages root_uri = self._path2uri(os.path.join(self.root_path, dirpath)) for dirname in dirnames[:]: # copy list - we modify inplace package_uri = '.'.join((root_uri, dirname)) if (self._uri2path(package_uri) and self._survives_exclude(package_uri, 'package')): modules.append(package_uri) else: dirnames.remove(dirname) # Check filenames for modules for filename in filenames: module_name = filename[:-3] module_uri = '.'.join((root_uri, module_name)) if (self._uri2path(module_uri) and self._survives_exclude(module_uri, 'module')): modules.append(module_uri) return sorted(modules) def check_modules(self): # write the list modules = self.discover_modules() checked_modules = [] for m in modules: bad_specs = self.test_specs(m) if bad_specs: checked_modules.extend(bad_specs) for bad_spec in checked_modules: print ':'.join(bad_spec) if __name__ == "__main__": package = 'nipype' ic = InterfaceChecker(package) # Packages that should not be included in generated API docs. ic.package_skip_patterns += ['\.external$', '\.fixes$', '\.utils$', '\.pipeline', '\.testing', '\.caching', '\.workflows', ] """ # Modules that should not be included in generated API docs. ic.module_skip_patterns += ['\.version$', '\.interfaces\.base$', '\.interfaces\.matlab$', '\.interfaces\.rest$', '\.interfaces\.pymvpa$', '\.interfaces\.slicer\.generate_classes$', '\.interfaces\.spm\.base$', '\.interfaces\.traits', '\.pipeline\.alloy$', '\.pipeline\.s3_node_wrapper$', '.\testing', ] ic.class_skip_patterns += ['AFNI', 'ANTS', 'FSL', 'FS', 'Info', '^SPM', 'Tester', 'Spec$', 'Numpy', 'NipypeTester', ] """ ic.check_modules() nipype-0.11.0/tools/ex2rst000077500000000000000000000222241257611314500154210ustar00rootroot00000000000000#!/usr/bin/env python # # Note: this file is copied (possibly with minor modifications) from the # sources of the PyMVPA project - http://pymvpa.org. It remains licensed as # the rest of PyMVPA (MIT license as of October 2010). # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## # # See COPYING file distributed along with the PyMVPA package for the # copyright and license terms. # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## """Helper to automagically generate ReST versions of examples""" __docformat__ = 'restructuredtext' import os import sys import re import glob from optparse import OptionParser def auto_image(line): """Automatically replace generic image markers with ones that have full size (width/height) info, plus a :target: link to the original png, to be used in the html docs. """ img_re = re.compile(r'(\s*)\.\. image::\s*(.*)$') m = img_re.match(line) if m is None: # Not an image declaration, leave the line alone and return unmodified return line # Match means it's an image spec, we rewrite it with extra tags ini_space = m.group(1) lines = [line, ini_space + ' :width: 500\n', #ini_space + ' :height: 350\n' ] fspec = m.group(2) if fspec.endswith('.*'): fspec = fspec.replace('.*', '.png') fspec = fspec.replace('fig/', '../_images/') lines.append(ini_space + (' :target: %s\n' % fspec) ) lines.append('\n') return ''.join(lines) def exfile2rst(filename): """Open a Python script and convert it into an ReST string. """ # output string s = '' # open source file xfile = open(filename) # parser status vars inheader = True indocs = False doc2code = False code2doc = False # an empty line found in the example enables the check for a potentially # indented docstring starting on the next line (as an attempt to exclude # function or class docstrings) last_line_empty = False # indentation of indented docstring, which is removed from the RsT output # since we typically do not want an indentation there. indent_level = 0 for line in xfile: # skip header if inheader and \ not (line.startswith('"""') or line.startswith("'''")): continue # determine end of header if inheader and (line.startswith('"""') or line.startswith("'''")): inheader = False # strip comments and remove trailing whitespace if not indocs and last_line_empty: # first remove leading whitespace and store indent level cleanline = line[:line.find('#')].lstrip() indent_level = len(line) - len(cleanline) - 1 cleanline = cleanline.rstrip() else: cleanline = line[:line.find('#')].rstrip() if not indocs and line == '\n': last_line_empty = True else: last_line_empty = False # if we have something that should go into the text if indocs \ or (cleanline.startswith('"""') or cleanline.startswith("'''")): proc_line = None # handle doc start if not indocs: # guarenteed to start with """ if len(cleanline) > 3 \ and (cleanline.endswith('"""') \ or cleanline.endswith("'''")): # single line doc code2doc = True doc2code = True proc_line = cleanline[3:-3] else: # must be start of multiline block indocs = True code2doc = True # rescue what is left on the line proc_line = cleanline[3:] # strip """ else: # we are already in the docs # handle doc end if cleanline.endswith('"""') or cleanline.endswith("'''"): indocs = False doc2code = True # rescue what is left on the line proc_line = cleanline[:-3] # reset the indentation indent_level = 0 else: # has to be documentation # if the indentation is whitespace remove it, other wise # keep it (accounts for some variation in docstring # styles real_indent = \ indent_level - len(line[:indent_level].lstrip()) proc_line = line[real_indent:] if code2doc: code2doc = False s += '\n' proc_line = auto_image(proc_line) if proc_line: s += proc_line.rstrip() + '\n' else: if doc2code: doc2code = False s += '\n::\n' # has to be code s += ' %s' % line xfile.close() return s def exfile2rstfile(filename, opts): """ """ # doc filename dfilename = os.path.basename(filename[:-3]) + '.rst' # open dest file dfile = open(os.path.join(opts.outdir, os.path.basename(dfilename)), 'w') # place header dfile.write('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') # place cross-ref target dfile.write('.. _example_' + dfilename[:-4] + ':\n\n') # write converted ReST dfile.write(exfile2rst(filename)) links = """ .. include:: ../../links_names.txt """ dfile.write(links) if opts.sourceref: # write post example see also box msg = """ .. admonition:: Example source code You can download :download:`the full source code of this example <%s>`. This same script is also included in the %s source distribution under the :file:`examples` directory. """ % (filename, opts.project) dfile.write(msg) dfile.close() def main(): parser = OptionParser( \ usage="%prog [options] [...]", \ version="%prog 0.1", description="""\ %prog converts Python scripts into restructered text (ReST) format suitable for integration into the Sphinx documentation framework. Its key feature is that it extracts stand-alone (unassigned) single, or multiline triple-quote docstrings and moves them out of the code listing so that they are rendered as regular ReST, while at the same time maintaining their position relative to the listing. The detection of such docstrings is exclusively done by parsing the raw code so it is never actually imported into a running Python session. Docstrings have to be written using triple quotes (both forms " and ' are possible). It is recommend that such docstrings are preceded and followed by an empty line. Intended docstring can make use of the full linewidth from the second docstring line on. If the indentation of multiline docstring is maintained for all lines, the respective indentation is removed in the ReST output. The parser algorithm automatically excludes file headers and starts with the first (module-level) docstring instead. """ ) #' # define options parser.add_option('--verbose', action='store_true', dest='verbose', default=False, help='print status messages') parser.add_option('-x', '--exclude', action='append', dest='excluded', help="""\ Use this option to exclude single files from the to be parsed files. This is especially useful to exclude files when parsing complete directories. This option can be specified multiple times. """) parser.add_option('-o', '--outdir', action='store', dest='outdir', type='string', default=None, help="""\ Target directory to write the ReST output to. This is a required option. """) parser.add_option('--no-sourceref', action='store_false', default=True, dest='sourceref', help="""\ If specified, the source reference section will be suppressed. """) parser.add_option('--project', type='string', action='store', default='', dest='project', help="""\ Name of the project that contains the examples. This name is used in the 'seealso' source references. Default: '' """) # parse options (opts, args) = parser.parse_args() # read sys.argv[1:] by default # check for required options if opts.outdir is None: print('Required option -o, --outdir not specified.') sys.exit(1) # build up list of things to parse toparse = [] for t in args: # expand dirs if os.path.isdir(t): # add all python files in that dir toparse += glob.glob(os.path.join(t, '*.py')) else: toparse.append(t) # filter parse list if not opts.excluded is None: toparse = [t for t in toparse if not t in opts.excluded] toparse_list = toparse toparse = set(toparse) if len(toparse) != len(toparse_list): print('Ignoring duplicate parse targets.') if not os.path.exists(opts.outdir): os.mkdir(outdir) # finally process all examples for t in toparse: exfile2rstfile(t, opts) if __name__ == '__main__': main() nipype-0.11.0/tools/github.py000066400000000000000000000054141257611314500161020ustar00rootroot00000000000000import httplib import inspect import json import os from subprocess import Popen, PIPE import nipype def is_git_repo(): """Does the current nipype module have a git folder """ sourcepath = os.path.realpath(os.path.join(os.path.dirname(nipype.__file__), os.path.pardir)) gitpathgit = os.path.join(sourcepath, '.git') if os.path.exists(gitpathgit): return True else: return False def get_local_branch(): """Determine current branch """ if is_git_repo(): o, _ = Popen('git branch | grep "\* "', shell=True, stdout=PIPE, cwd=os.path.dirname(nipype.__file__)).communicate() return o.strip()[2:] else: return None def get_remote_branch(): """Get remote branch for current branch """ pass def create_hash_map(): """Create a hash map for all objects """ hashmap = {} from base64 import encodestring as base64 import pwd login_name = pwd.getpwuid(os.geteuid())[0] conn = httplib.HTTPSConnection("api.github.com") conn.request("GET", "/repos/nipy/nipype", headers={'Authorization': 'Basic %s' % base64(login_name)}) try: conn.request("GET", "/repos/nipy/nipype/git/trees/master?recursive=1") except: pass else: r1 = conn.getresponse() if r1.reason != 'OK': raise Exception('HTTP Response %s:%s' % (r1.status, r1.reason)) payload = json.loads(r1.read()) for infodict in payload['tree']: if infodict['type'] == "blob": hashmap[infodict['sha']] = infodict['path'] return hashmap def get_repo_url(force_github=False): """Returns github url or local url Returns ------- URI: str filesystem path or github repo url """ sourcepath = os.path.realpath(os.path.join(os.path.dirname(nipype.__file__), os.path.pardir)) gitpathgit = os.path.join(sourcepath, '.git') if not os.path.exists(gitpathgit) and not force_github: uri = 'file://%s' % sourcepath else: uri = 'http://github.com/nipy/nipype/blob/master' return uri def get_file_url(object): """Returns local or remote url for an object """ filename = inspect.getsourcefile(object) lines = inspect.getsourcelines(object) uri = 'file://%s#L%d' % (filename, lines[1]) if is_git_repo(): info = nipype.get_info() shortfile = os.path.join('nipype', filename.split('nipype/')[-1]) uri = 'http://github.com/nipy/nipype/tree/%s/%s#L%d' % \ (info['commit_hash'], shortfile, lines[1]) return uri nipype-0.11.0/tools/gitwash_dumper.py000077500000000000000000000172501257611314500176460ustar00rootroot00000000000000#!/usr/bin/env python ''' Checkout gitwash repo into directory and do search replace on name ''' import os from os.path import join as pjoin import shutil import sys import re import glob import fnmatch import tempfile from subprocess import call from optparse import OptionParser verbose = False def clone_repo(url, branch): cwd = os.getcwd() tmpdir = tempfile.mkdtemp() try: cmd = 'git clone %s %s' % (url, tmpdir) call(cmd, shell=True) os.chdir(tmpdir) cmd = 'git checkout %s' % branch call(cmd, shell=True) except: shutil.rmtree(tmpdir) raise finally: os.chdir(cwd) return tmpdir def cp_files(in_path, globs, out_path): try: os.makedirs(out_path) except OSError: pass out_fnames = [] for in_glob in globs: in_glob_path = pjoin(in_path, in_glob) for in_fname in glob.glob(in_glob_path): out_fname = in_fname.replace(in_path, out_path) pth, _ = os.path.split(out_fname) if not os.path.isdir(pth): os.makedirs(pth) shutil.copyfile(in_fname, out_fname) out_fnames.append(out_fname) return out_fnames def filename_search_replace(sr_pairs, filename, backup=False): ''' Search and replace for expressions in files ''' in_txt = open(filename, 'rt').read(-1) out_txt = in_txt[:] for in_exp, out_exp in sr_pairs: in_exp = re.compile(in_exp) out_txt = in_exp.sub(out_exp, out_txt) if in_txt == out_txt: return False open(filename, 'wt').write(out_txt) if backup: open(filename + '.bak', 'wt').write(in_txt) return True def copy_replace(replace_pairs, repo_path, out_path, cp_globs=('*',), rep_globs=('*',), renames = ()): out_fnames = cp_files(repo_path, cp_globs, out_path) renames = [(re.compile(in_exp), out_exp) for in_exp, out_exp in renames] fnames = [] for rep_glob in rep_globs: fnames += fnmatch.filter(out_fnames, rep_glob) if verbose: print '\n'.join(fnames) for fname in fnames: filename_search_replace(replace_pairs, fname, False) for in_exp, out_exp in renames: new_fname, n = in_exp.subn(out_exp, fname) if n: os.rename(fname, new_fname) break def make_link_targets(proj_name, user_name, repo_name, known_link_fname, out_link_fname, url=None, ml_url=None): """ Check and make link targets If url is None or ml_url is None, check if there are links present for these in `known_link_fname`. If not, raise error. The check is: Look for a target `proj_name`. Look for a target `proj_name` + ' mailing list' Also, look for a target `proj_name` + 'github'. If this exists, don't write this target into the new file below. If we are writing any of the url, ml_url, or github address, then write new file with these links, of form: .. _`proj_name` .. _`proj_name`: url .. _`proj_name` mailing list: url """ link_contents = open(known_link_fname, 'rt').readlines() have_url = not url is None have_ml_url = not ml_url is None have_gh_url = None for line in link_contents: if not have_url: match = re.match(r'..\s+_%s:\s+' % proj_name, line) if match: have_url = True if not have_ml_url: match = re.match(r'..\s+_`%s mailing list`:\s+' % proj_name, line) if match: have_ml_url = True if not have_gh_url: match = re.match(r'..\s+_`%s github`:\s+' % proj_name, line) if match: have_gh_url = True if not have_url or not have_ml_url: raise RuntimeError('Need command line or known project ' 'and / or mailing list URLs') lines = [] if not url is None: lines.append('.. _%s: %s\n' % (proj_name, url)) if not have_gh_url: gh_url = 'http://github.com/%s/%s\n' % (user_name, repo_name) lines.append('.. _`%s github`: %s\n' % (proj_name, gh_url)) if not ml_url is None: lines.append('.. _`%s mailing list`: %s\n' % (proj_name, ml_url)) if len(lines) == 0: # Nothing to do return # A neat little header line lines = ['.. %s\n' % proj_name] + lines out_links = open(out_link_fname, 'wt') out_links.writelines(lines) out_links.close() USAGE = ''' If not set with options, the repository name is the same as the If not set with options, the main github user is the same as the repository name.''' GITWASH_CENTRAL = 'git://github.com/matthew-brett/gitwash.git' GITWASH_BRANCH = 'master' def main(): parser = OptionParser() parser.set_usage(parser.get_usage().strip() + USAGE) parser.add_option("--repo-name", dest="repo_name", help="repository name - e.g. nitime", metavar="REPO_NAME") parser.add_option("--github-user", dest="main_gh_user", help="github username for main repo - e.g fperez", metavar="MAIN_GH_USER") parser.add_option("--gitwash-url", dest="gitwash_url", help="URL to gitwash repository - default %s" % GITWASH_CENTRAL, default=GITWASH_CENTRAL, metavar="GITWASH_URL") parser.add_option("--gitwash-branch", dest="gitwash_branch", help="branch in gitwash repository - default %s" % GITWASH_BRANCH, default=GITWASH_BRANCH, metavar="GITWASH_BRANCH") parser.add_option("--source-suffix", dest="source_suffix", help="suffix of ReST source files - default '.rst'", default='.rst', metavar="SOURCE_SUFFIX") parser.add_option("--project-url", dest="project_url", help="URL for project web pages", default=None, metavar="PROJECT_URL") parser.add_option("--project-ml-url", dest="project_ml_url", help="URL for project mailing list", default=None, metavar="PROJECT_ML_URL") (options, args) = parser.parse_args() if len(args) < 2: parser.print_help() sys.exit() out_path, project_name = args if options.repo_name is None: options.repo_name = project_name if options.main_gh_user is None: options.main_gh_user = options.repo_name repo_path = clone_repo(options.gitwash_url, options.gitwash_branch) try: copy_replace((('PROJECTNAME', project_name), ('REPONAME', options.repo_name), ('MAIN_GH_USER', options.main_gh_user)), repo_path, out_path, cp_globs=(pjoin('gitwash', '*'),), rep_globs=('*.rst',), renames=(('\.rst$', options.source_suffix),)) make_link_targets(project_name, options.main_gh_user, options.repo_name, pjoin(out_path, 'gitwash', 'known_projects.inc'), pjoin(out_path, 'gitwash', 'this_project.inc'), options.project_url, options.project_ml_url) finally: shutil.rmtree(repo_path) if __name__ == '__main__': main() nipype-0.11.0/tools/install_spm_mcr.sh000066400000000000000000000015541257611314500177710ustar00rootroot00000000000000if [ ! -d $HOME/mcr ] then echo "destinationFolder=$HOME/mcr" > $HOME/mcr_options.txt echo "agreeToLicense=yes" >> $HOME/mcr_options.txt echo "outputFile=/tmp/matlabinstall_log" >> $HOME/mcr_options.txt echo "mode=silent" >> $HOME/mcr_options.txt mkdir -p $HOME/matlab_installer wget -nc http://www.mathworks.com/supportfiles/downloads/R2015a/deployment_files/R2015a/installers/glnxa64/MCR_R2015a_glnxa64_installer.zip -O $HOME/matlab_installer/installer.zip unzip $HOME/matlab_installer/installer.zip -d $HOME/matlab_installer/ $HOME/matlab_installer/install -inputFile $HOME/mcr_options.txt rm -rf $HOME/matlab_installer $HOME/mcr_options.txt fi if [ ! -d $HOME/spm12 ] then wget http://www.fil.ion.ucl.ac.uk/spm/download/restricted/utopia/dev/spm12_r6472_Linux_R2015a.zip -O $HOME/spm12.zip unzip $HOME/spm12.zip -d $HOME rm -rf $HOME/spm12.zip fi nipype-0.11.0/tools/interfacedocgen.py000066400000000000000000000432711257611314500177430ustar00rootroot00000000000000# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Attempt to generate templates for module reference with Sphinx XXX - we exclude extension modules To include extension modules, first identify them as valid in the ``_uri2path`` method, then handle them in the ``_parse_module`` script. We get functions and classes by parsing the text of .py files. Alternatively we could import the modules for discovery, and we'd have to do that for extension modules. This would involve changing the ``_parse_module`` method to work via import and introspection, and might involve changing ``discover_modules`` (which determines which files are modules, and therefore which module URIs will be passed to ``_parse_module``). NOTE: this is a modified version of a script originally shipped with the PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed project.""" # Stdlib imports import inspect import os import re import sys import tempfile import warnings from nipype.interfaces.base import BaseInterface from nipype.pipeline.engine import Workflow from nipype.utils.misc import trim from github import get_file_url # Functions and classes class InterfaceHelpWriter(object): ''' Class for automatic detection and parsing of API docs to Sphinx-parsable reST format''' # only separating first two levels rst_section_levels = ['*', '=', '-', '~', '^'] def __init__(self, package_name, rst_extension='.rst', package_skip_patterns=None, module_skip_patterns=None, class_skip_patterns=None ): ''' Initialize package for parsing Parameters ---------- package_name : string Name of the top-level package. *package_name* must be the name of an importable package rst_extension : string, optional Extension for reST files, default '.rst' package_skip_patterns : None or sequence of {strings, regexps} Sequence of strings giving URIs of packages to be excluded Operates on the package path, starting at (including) the first dot in the package path, after *package_name* - so, if *package_name* is ``sphinx``, then ``sphinx.util`` will result in ``.util`` being passed for earching by these regexps. If is None, gives default. Default is: ['\.tests$'] module_skip_patterns : None or sequence Sequence of strings giving URIs of modules to be excluded Operates on the module name including preceding URI path, back to the first dot after *package_name*. For example ``sphinx.util.console`` results in the string to search of ``.util.console`` If is None, gives default. Default is: ['\.setup$', '\._'] class_skip_patterns : None or sequence Sequence of strings giving classes to be excluded Default is: None ''' if package_skip_patterns is None: package_skip_patterns = ['\\.tests$'] if module_skip_patterns is None: module_skip_patterns = ['\\.setup$', '\\._'] if class_skip_patterns: self.class_skip_patterns = class_skip_patterns else: self.class_skip_patterns = [] self.package_name = package_name self.rst_extension = rst_extension self.package_skip_patterns = package_skip_patterns self.module_skip_patterns = module_skip_patterns def get_package_name(self): return self._package_name def set_package_name(self, package_name): ''' Set package_name >>> docwriter = ApiDocWriter('sphinx') >>> import sphinx >>> docwriter.root_path == sphinx.__path__[0] True >>> docwriter.package_name = 'docutils' >>> import docutils >>> docwriter.root_path == docutils.__path__[0] True ''' # It's also possible to imagine caching the module parsing here self._package_name = package_name self.root_module = __import__(package_name) self.root_path = self.root_module.__path__[0] self.written_modules = None package_name = property(get_package_name, set_package_name, None, 'get/set package_name') def _get_object_name(self, line): ''' Get second token in line >>> docwriter = ApiDocWriter('sphinx') >>> docwriter._get_object_name(" def func(): ") 'func' >>> docwriter._get_object_name(" class Klass(object): ") 'Klass' >>> docwriter._get_object_name(" class Klass: ") 'Klass' ''' name = line.split()[1].split('(')[0].strip() # in case we have classes which are not derived from object # ie. old style classes return name.rstrip(':') def _uri2path(self, uri): ''' Convert uri to absolute filepath Parameters ---------- uri : string URI of python module to return path for Returns ------- path : None or string Returns None if there is no valid path for this URI Otherwise returns absolute file system path for URI Examples -------- >>> docwriter = ApiDocWriter('sphinx') >>> import sphinx >>> modpath = sphinx.__path__[0] >>> res = docwriter._uri2path('sphinx.builder') >>> res == os.path.join(modpath, 'builder.py') True >>> res = docwriter._uri2path('sphinx') >>> res == os.path.join(modpath, '__init__.py') True >>> docwriter._uri2path('sphinx.does_not_exist') ''' if uri == self.package_name: return os.path.join(self.root_path, '__init__.py') path = uri.replace('.', os.path.sep) path = path.replace(self.package_name + os.path.sep, '') path = os.path.join(self.root_path, path) # XXX maybe check for extensions as well? if os.path.exists(path + '.py'): # file path += '.py' elif os.path.exists(os.path.join(path, '__init__.py')): path = os.path.join(path, '__init__.py') else: return None return path def _path2uri(self, dirpath): ''' Convert directory path to uri ''' relpath = dirpath.replace(self.root_path, self.package_name) if relpath.startswith(os.path.sep): relpath = relpath[1:] return relpath.replace(os.path.sep, '.') def _parse_module(self, uri): ''' Parse module defined in *uri* ''' filename = self._uri2path(uri) if filename is None: # nothing that we could handle here. return ([],[]) f = open(filename, 'rt') functions, classes = self._parse_lines(f, uri) f.close() return functions, classes def _parse_lines(self, linesource, module): ''' Parse lines of text for functions and classes ''' functions = [] classes = [] for line in linesource: if line.startswith('def ') and line.count('('): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_'): functions.append(name) elif line.startswith('class '): # exclude private stuff name = self._get_object_name(line) if not name.startswith('_') and \ self._survives_exclude('.'.join((module, name)), 'class'): classes.append(name) else: pass functions.sort() classes.sort() return functions, classes def _write_graph_section(self, fname, title): ad = '\n%s\n%s\n\n' % (title, self.rst_section_levels[3] * len(title)) ad += '.. graphviz::\n\n' fhandle = open(fname) for line in fhandle: ad += '\t' + line + '\n' fhandle.close() os.remove(fname) os.remove(fname + ".png") return ad def generate_api_doc(self, uri): '''Make autodoc documentation template string for a module Parameters ---------- uri : string python location of module - e.g 'sphinx.builder' Returns ------- S : string Contents of API doc ''' # get the names of all classes and functions functions, classes = self._parse_module(uri) workflows = [] helper_functions = [] for function in functions: try: __import__(uri) finst = sys.modules[uri].__dict__[function] except TypeError: continue try: workflow = finst() except Exception: helper_functions.append((function, finst)) continue if isinstance(workflow, Workflow): workflows.append((workflow,function, finst)) if not classes and not workflows and not helper_functions: print 'WARNING: Empty -',uri # dbg return '' # Make a shorter version of the uri that omits the package name for # titles uri_short = re.sub(r'^%s\.' % self.package_name, '', uri) #uri_short = uri ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n' chap_title = uri_short ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title) + '\n\n') # Set the chapter title to read 'module' for all modules except for the # main packages #if '.' in uri: # title = 'Module: :mod:`' + uri_short + '`' #else: # title = ':mod:`' + uri_short + '`' #ad += title + '\n' + self.rst_section_levels[2] * len(title) #ad += '\n' + 'Classes' + '\n' + \ # self.rst_section_levels[2] * 7 + '\n' for c in classes: __import__(uri) print c try: with warnings.catch_warnings(): warnings.simplefilter("ignore") classinst = sys.modules[uri].__dict__[c] except Exception as inst: print inst continue if not issubclass(classinst, BaseInterface): continue label = uri + '.' + c + ':' ad += '\n.. _%s\n\n' % label ad += '\n.. index:: %s\n\n' % c ad += c + '\n' + self.rst_section_levels[2] * len(c) + '\n\n' ad += "`Link to code <%s>`__\n\n" % get_file_url(classinst) ad += trim(classinst.help(returnhelp=True), self.rst_section_levels[3]) + '\n' if workflows or helper_functions: ad += '\n.. module:: %s\n\n' % uri for workflow, name, finst in workflows: label = ':func:`' + name + '`' ad += '\n.. _%s:\n\n' % (uri + '.' + name) ad += '\n'.join((label, self.rst_section_levels[2] * len(label))) ad += "\n\n`Link to code <%s>`__\n\n" % get_file_url(finst) helpstr = trim(finst.__doc__, self.rst_section_levels[3]) ad += '\n\n' + helpstr + '\n\n' """ # use sphinx autodoc for function signature ad += '\n.. _%s:\n\n' % (uri + '.' + name) ad += '.. autofunction:: %s\n\n' % name """ (_,fname) = tempfile.mkstemp(suffix=".dot") workflow.write_graph(dotfilename=fname, graph2use='hierarchical') ad += self._write_graph_section(fname, 'Graph') + '\n' for name, finst in helper_functions: label = ':func:`' + name + '`' ad += '\n.. _%s:\n\n' % (uri + '.' + name) ad += '\n'.join((label, self.rst_section_levels[2] * len(label))) ad += "\n\n`Link to code <%s>`__\n\n" % get_file_url(finst) helpstr = trim(finst.__doc__, self.rst_section_levels[3]) ad += '\n\n' + helpstr + '\n\n' return ad def _survives_exclude(self, matchstr, match_type): ''' Returns True if *matchstr* does not match patterns ``self.package_name`` removed from front of string if present Examples -------- >>> dw = ApiDocWriter('sphinx') >>> dw._survives_exclude('sphinx.okpkg', 'package') True >>> dw.package_skip_patterns.append('^\\.badpkg$') >>> dw._survives_exclude('sphinx.badpkg', 'package') False >>> dw._survives_exclude('sphinx.badpkg', 'module') True >>> dw._survives_exclude('sphinx.badmod', 'module') True >>> dw.module_skip_patterns.append('^\\.badmod$') >>> dw._survives_exclude('sphinx.badmod', 'module') False ''' if match_type == 'module': patterns = self.module_skip_patterns elif match_type == 'package': patterns = self.package_skip_patterns elif match_type == 'class': patterns = self.class_skip_patterns else: raise ValueError('Cannot interpret match type "%s"' % match_type) # Match to URI without package name L = len(self.package_name) if matchstr[:L] == self.package_name: matchstr = matchstr[L:] for pat in patterns: try: pat.search except AttributeError: pat = re.compile(pat) if pat.search(matchstr): return False return True def discover_modules(self): ''' Return module sequence discovered from ``self.package_name`` Parameters ---------- None Returns ------- mods : sequence Sequence of module names within ``self.package_name`` Examples -------- >>> dw = ApiDocWriter('sphinx') >>> mods = dw.discover_modules() >>> 'sphinx.util' in mods True >>> dw.package_skip_patterns.append('\.util$') >>> 'sphinx.util' in dw.discover_modules() False >>> ''' modules = [self.package_name] # raw directory parsing for dirpath, dirnames, filenames in os.walk(self.root_path): # Check directory names for packages root_uri = self._path2uri(os.path.join(self.root_path, dirpath)) for dirname in dirnames[:]: # copy list - we modify inplace package_uri = '.'.join((root_uri, dirname)) if (self._uri2path(package_uri) and self._survives_exclude(package_uri, 'package')): modules.append(package_uri) else: dirnames.remove(dirname) # Check filenames for modules for filename in filenames: module_name = filename[:-3] module_uri = '.'.join((root_uri, module_name)) if (self._uri2path(module_uri) and self._survives_exclude(module_uri, 'module')): modules.append(module_uri) return sorted(modules) def write_modules_api(self, modules,outdir): # write the list written_modules = [] for m in modules: api_str = self.generate_api_doc(m) if not api_str: continue # write out to file outfile = os.path.join(outdir, m + self.rst_extension) fileobj = open(outfile, 'wt') fileobj.write(api_str) fileobj.close() written_modules.append(m) self.written_modules = written_modules def write_api_docs(self, outdir): """Generate API reST files. Parameters ---------- outdir : string Directory name in which to store files We create automatic filenames for each module Returns ------- None Notes ----- Sets self.written_modules to list of written modules """ if not os.path.exists(outdir): os.mkdir(outdir) # compose list of modules modules = self.discover_modules() self.write_modules_api(modules,outdir) def write_index(self, outdir, froot='gen', relative_to=None): """Make a reST API index file from written files Parameters ---------- path : string Filename to write index to outdir : string Directory to which to write generated index file froot : string, optional root (filename without extension) of filename to write to Defaults to 'gen'. We add ``self.rst_extension``. relative_to : string path to which written filenames are relative. This component of the written file path will be removed from outdir, in the generated index. Default is None, meaning, leave path as it is. """ if self.written_modules is None: raise ValueError('No modules written') # Get full filename path path = os.path.join(outdir, froot+self.rst_extension) # Path written into index is relative to rootpath if relative_to is not None: relpath = outdir.replace(relative_to + os.path.sep, '') else: relpath = outdir idx = open(path,'wt') w = idx.write w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n') w('.. toctree::\n') w(' :maxdepth: 2\n\n') for f in self.written_modules: w(' %s\n' % os.path.join(relpath,f)) idx.close() nipype-0.11.0/tools/make_examples.py000077500000000000000000000054531257611314500174410ustar00rootroot00000000000000#!/usr/bin/env python """Run the py->rst conversion and run all examples. This also creates the index.rst file appropriately, makes figures, etc. """ #----------------------------------------------------------------------------- # Library imports #----------------------------------------------------------------------------- # Stdlib imports import os import sys from glob import glob # Third-party imports # We must configure the mpl backend before making any further mpl imports import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib._pylab_helpers import Gcf # Local tools from toollib import * #----------------------------------------------------------------------------- # Globals #----------------------------------------------------------------------------- examples_header = """ .. _examples: Examples ======== .. note_about_examples """ #----------------------------------------------------------------------------- # Function defintions #----------------------------------------------------------------------------- # These global variables let show() be called by the scripts in the usual # manner, but when generating examples, we override it to write the figures to # files with a known name (derived from the script name) plus a counter figure_basename = None # We must change the show command to save instead def show(): allfm = Gcf.get_all_fig_managers() for fcount, fm in enumerate(allfm): fm.canvas.figure.savefig('%s_%02i.png' % (figure_basename, fcount+1)) _mpl_show = plt.show plt.show = show #----------------------------------------------------------------------------- # Main script #----------------------------------------------------------------------------- # Work in examples directory cd('users/examples') if not os.getcwd().endswith('users/examples'): raise OSError('This must be run from doc/examples directory') # Run the conversion from .py to rst file sh('../../../tools/ex2rst --project Nipype --outdir . ../../../examples') sh('../../../tools/ex2rst --project Nipype --outdir . ../../../examples/frontiers_paper') # Make the index.rst file """ index = open('index.rst', 'w') index.write(examples_header) for name in [os.path.splitext(f)[0] for f in glob('*.rst')]: #Don't add the index in there to avoid sphinx errors and don't add the #note_about examples again (because it was added at the top): if name not in(['index','note_about_examples']): index.write(' %s\n' % name) index.close() """ # Execute each python script in the directory. if '--no-exec' in sys.argv: pass else: if not os.path.isdir('fig'): os.mkdir('fig') for script in glob('*.py'): figure_basename = pjoin('fig', os.path.splitext(script)[0]) execfile(script) plt.close('all') nipype-0.11.0/tools/nipype_nightly.py000066400000000000000000000050701257611314500176600ustar00rootroot00000000000000#!/usr/bin/env python """Simple script to update the trunk nightly, build the docs and push to sourceforge. """ import os import sys import subprocess dirname = '/home/cburns/src/nipy-sf/nipype/trunk/' def run_cmd(cmd): print cmd proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=os.environ, shell=True) output, error = proc.communicate() returncode = proc.returncode if returncode: msg = 'Running cmd: %s\n Error: %s' % (cmd, error) raise StandardError(msg) print output def update_repos(): """Update svn repository.""" os.chdir(dirname) cmd = 'svn update' run_cmd(cmd) def build_docs(): """Build the sphinx documentation.""" os.chdir(os.path.join(dirname, 'doc')) cmd = 'make html' run_cmd(cmd) def push_to_sf(): """Push documentation to sourceforge.""" os.chdir(dirname + 'doc') cmd = 'make sf_cburns' run_cmd(cmd) def setup_paths(): # Cron has no PYTHONPATH defined, so we need to add the paths to # all libraries we need. pkg_path = '/home/cburns/local/lib/python2.6/site-packages/' pkg_path_64 = '/home/cburns/local/lib64/python2.6/site-packages/' # Add the current directory to path sys.path.insert(0, os.curdir) # Add our local path, where we install nipype, to sys.path sys.path.insert(0, pkg_path) # Needed to add this to my path at one point otherwise import of # apigen failed. #sys.path.insert(2, '/home/cburns/src/nipy-sf/nipype/trunk/tools') # Add networkx, twisted, zope.interface and foolscap. # Basically we need to add all the packages we need that are # installed via setyptools, since it's uses the .pth files for # this. nx_path = os.path.join(pkg_path, 'networkx-0.99-py2.6.egg') sys.path.insert(2, nx_path) twisted_path = os.path.join(pkg_path_64, 'Twisted-8.2.0-py2.6-linux-x86_64.egg') sys.path.insert(2, twisted_path) zope_path = os.path.join(pkg_path_64, 'zope.interface-3.5.2-py2.6-linux-x86_64.egg') sys.path.insert(2, zope_path) foolscap_path = os.path.join(pkg_path, 'foolscap-0.2.9-py2.6.egg') sys.path.insert(2, foolscap_path) # Define our PYTHONPATH variable os.environ['PYTHONPATH'] = ':'.join(sys.path) if __name__ == '__main__': setup_paths() prev_dir = os.path.abspath(os.curdir) update_repos() build_docs() #push_to_sf() os.chdir(prev_dir) nipype-0.11.0/tools/report_coverage.py000066400000000000000000000026721257611314500200110ustar00rootroot00000000000000#!/usr/bin/env python import subprocess def run_tests(cmd): proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) stdout, stderr = proc.communicate() if proc.returncode: msg = 'Running cmd: %s\n Error: %s' % (cmd, error) raise StandardError(msg) # Nose returns the output in stderr return stderr def grab_coverage(output): """Grab coverage lines from nose output.""" output = output.split('\n') covout = [] header = None tcount = None for line in output: if line.startswith('nipype.interfaces.') or \ line.startswith('nipype.pipeline.') or \ line.startswith('nipype.utils.'): # Remove the Missing lines, too noisy percent_index = line.find('%') percent_index += 1 covout.append(line[:percent_index]) if line.startswith('Name '): header = line if line.startswith('Ran '): tcount = line covout.insert(0, header) covout.insert(1, '-'*70) covout.append('-'*70) covout.append(tcount) return '\n'.join(covout) def main(): cmd = 'nosetests --with-coverage --cover-package=nipype' print 'From current directory, running cmd:' print cmd, '\n' output = run_tests(cmd) report = grab_coverage(output) print report main() nipype-0.11.0/tools/run_examples.py000066400000000000000000000024631257611314500173230ustar00rootroot00000000000000import os import sys from shutil import rmtree def run_examples(example, pipelines, plugin): print 'running example: %s with plugin: %s'%(example, plugin) from nipype import config config.enable_debug_mode() from nipype.interfaces.base import CommandLine CommandLine.set_default_terminal_output("stream") __import__(example) for pipeline in pipelines: wf = getattr(sys.modules[example], pipeline) wf.base_dir = os.path.join(os.getcwd(), 'output', example, plugin) if os.path.exists(wf.base_dir): rmtree(wf.base_dir) wf.config = {'execution' :{'hash_method': 'timestamp', 'stop_on_first_rerun': 'true'}} wf.run(plugin=plugin, plugin_args={'n_procs': 4}) #run twice to check if nothing is rerunning wf.run(plugin=plugin) if __name__ == '__main__': path, file = os.path.split(__file__) sys.path.insert(0, os.path.realpath(os.path.join(path, '..', 'examples'))) examples = {'fmri_fsl_reuse':['level1_workflow'], 'fmri_spm_nested':['level1','l2pipeline'], #'fmri_spm_dartel':['level1','l2pipeline'], #'fmri_fsl_feeds':['l1pipeline'] } example = sys.argv[1] plugin = sys.argv[2] pipelines = sys.argv[3:] run_examples(example, pipelines, plugin) nipype-0.11.0/tools/setup.py000066400000000000000000000005541257611314500157600ustar00rootroot00000000000000#!/usr/bin/env python from distutils.core import setup setup(name='Nipype Tools', version='0.1', description='Utilities used in nipype development', author='Nipype Developers', author_email='nipy-devel@neuroimaging.scipy.org', url='http://nipy.sourceforge.net', scripts=['./nipype_nightly.py', './report_coverage.py'] ) nipype-0.11.0/tools/toollib.py000066400000000000000000000017711257611314500162660ustar00rootroot00000000000000"""Various utilities common to IPython release and maintenance tools. """ # Library imports import os import sys from subprocess import Popen, PIPE, CalledProcessError, check_call from distutils.dir_util import remove_tree # Useful shorthands pjoin = os.path.join cd = os.chdir # Utility functions #----------------------------------------------------------------------------- # Functions #----------------------------------------------------------------------------- def sh(cmd): """Execute command in a subshell, return status code.""" return check_call(cmd, shell=True) def compile_tree(): """Compile all Python files below current directory.""" vstr = '.'.join(map(str,sys.version_info[:2])) stat = os.system('python %s/lib/python%s/compileall.py .' % (sys.prefix,vstr)) if stat: msg = '*** ERROR: Some Python files in tree do NOT compile! ***\n' msg += 'See messages above for the actual file that produced it.\n' raise SystemExit(msg)