Looking for the latest version? Download teem-1.11.0-src.tar.gz (3.0 MB)
Home / teem / 1.10.0
Name Modified Size Downloads / Week Status
Parent folder
Totals: 2 Items   1.6 MB 2
README.txt 2012-12-20 21.5 kB 11 weekly downloads
teem-1.10.0-src.tar.gz 2008-12-10 1.6 MB 11 weekly downloads
It has been about three years since the last release 1.9. Since that time, Gordon has been working on getting publications and a job (bye Red Sox, hello White Sox), but Teem development has continued. Here is a summary of the changes that people might notice since Teem 1.9. The major API changes are likely to affect Teem-using software, the smaller API changes less so. Only the most important API additions are listed. It is unlikely that there are functionality changes that are not accompanied by an API change. So teem-using code should break first because of failures to link, not because of subtler behavioral chages. Best of luck, and remember to email teem-users: http://lists.sourceforge.net/lists/listinfo/teem-users in case of problems or questions. ==================================================================== Over-all Changes =================================================== ==================================================================== Thanks to the efforts of James Bigler and Andy Cedilnik, The CMake build system for Teem is mature, and should most certainly be used instead of the old GNUMakefiles. In particular, CMake now builds for Teem a single "mega" library that puts all the sub-libraries (air, biff, hest, etc) into a single place. There is currently no single "mega" *header* file. Thanks to Steve Pieper, there's a new demo of how CMake projects can use Teem in teem/UseTeemCMakeDemo Also thanks to Steve Pieper, Teem can now link with VTK's name-mangled versions of the PNG and zlib libraries, via the TEEM_VTK_* options in CMakeLists.txt Teem's CMake now generally refers to Teem as "Teem" instead of "TEEM". This may break existing things that used CMake to build and use Teem. Teem now optionally uses the "levmar" library from http://www.ics.forth.gr/~lourakis/levmar/ as a new "external" for non-linear least-squares fitting. Anticipating the eventual removal of the GNUMakefile-based system for building Teem, all the architecture-specific directories (darwin.32, irix6.64, linux.32, linux.ia64, cygwin, darwin.64, irix6.n32, linux.amd64, solaris) have beem moved from the top-level teem directory into a new teem/arch subdirectory. Perhaps confusingly, this includes the win32 directory, even though that was (directly) handled by GNUMake. ==================================================================== Major API Change ==================================================- ==================================================================== gage --------- gage_t is gone. Use "double" instead. GAGE_ITEM_PREREQ_NUM changed from 5 to 6, then to 8, and also renamed to GAGE_ITEM_PREREQ_MAXNUM If a volume doesn't identify itself as cell- or node-centered, gage now assumes cell-centered (in Teem 1.9 gaged assumed node-centered). GAGE_KERNEL_NUM #define gone, now GAGE_KERNEL_MAX+1 plays its role rename GAGE_PERVOLUME_NUM --> GAGE_PERVOLUME_MAXNUM rename GAGE_ITEM_PREREQ_NUM --> GAGE_ITEM_PREREQ_MAXNUM rename GAGE_KERNEL_NUM --> GAGE_KERNEL_MAX rename GAGE_CTX_FLAG_NUM --> GAGE_CTX_FLAG_MAX rename GAGE_PVL_FLAG_NUM --> GAGE_PVL_FLAG_MAX The GAGE_PERVOLUME_MAXNUM (called GAGE_PERVOLUME_NUM in Teem-1.9) #define compile-time limit on the number of pervolumes in a context is gone. The pvl[] array (and ctx->pvlNum) is now dynamically managed with an airArray (ctx->pvlArr). As a result, the stackFslw[] array is now also allocated dynamically (whenever the stack is attached) FIXED long-standing bug (how long I don't know) in how the derivatives were normalized in volumes with only per-axis spacing (that is, lacking full orientation info)- some users have noticed this change added matrices ItoWSubInvTransp and ItoWSubInv to gageShape, to handle more general transforms from index to world space (now gage correctly handles shear from gantry tilt, for example). Thus, REMOVED fwScale[] from gageShape, because its role has been taken over by ItoWSubInvTransp and ItoWSubInv. gageScl3PFilter2, gageScl3PFilter4, and gageScl3PFilterN now take a gageShape* as a mandatory first argument, because this stores the ItoWSubInvTransp and ItoWSubInv matrices used to transform gradients and hessians from index space to world space. Note that this also shifts the responsibility for this transform from something that is strictly internal to gage, to something that is not strictly internal: each gageKind is now responsible for doing this transform as part of its filter() callback. In practice, there is no real change, because all existing kinds ended calling the same gageScl3PFilter2, gageScl3PFilter4, and gageScl3PFilterN functions, since they all operate per-component. ten ----------- renamed enum value tenEstimateMethod* -> tenEstimate1Method* tenFiberTypeEvec1 now refers to the medium eigenvector NOT the principal one (that's tenFiberTypeEvec0) tenInvariantGradients_d() gone, replaced by more specific tenInvariantGradientsK_d() and tenInvariantGradientsR_d() The tenAnisoCalc_f function has been removed. It was one of the earliest and stupidest functions in the ten library, it was incapable of high accuracy for mode-related invariants, and it has been superceded by other functions. Specifically, use tenAnisoEval_f() or tenAnisoEval_d() to go from pre-computed eigenvalues to a particular anisotropy value, or use tenAnisoTen_f() or tenAnisoTen_d() to go from the full tensor value to an anisotropy value. Some functions (like tenAniso_Cl1 and related) make more sense computed from the individual eigenvalues, but others (like tenAniso_FA) can be quickly computed directly from the tensor value, no eigensolution required. The tenAniso_* enum and tenAniso airEnum are alive and well, and are used with the tenAniso{Eval,Ten}_{f,d} to identify which anisotropy to compute. ==================================================================== Minor API change, no one probably notices ========================== ==================================================================== air --------- airRandMTStateGlobal is no longer allocated at compile time. Now it is both allocated and initialized as needed at run time. This will create a memory-in-use-at-exit situation in valgrind. renames airBesselI0Scaled --> airBesselI0ExpScaled airBesselI1Scaled --> airBesselI1ExpScaled airBesselInScaled --> airBesselInExpScaled nrrd ------ removed nrrdSpaceGet() (or its public declaration)- Teem's structs are open for reading. changed nrrdResample_t from float to double; whatever is released should use higher precision by default; other people can make it lower precision for their own builds if they want. changed NrrdIoState->byteSkip from int to long int, in keeping with type of offset argument to fseek changed _nrrdContainsPercentDAndMore(const char *str) to the slightly more general purpose: _nrrdContainsPercentThisAndMore(const char *str, char this) The only reason this was a public function was so that unrrdu/dice could use it, but unrrdu/dice should be changed to use the new nrrdSaveMulti anyway. As part of cleaning up kernels, some single-letter kernel identifications were removed from _nrrdKernelStrToKern(), because they were too clever, and too apt to be confused: - if (!strcmp("z", str)) return nrrdKernelZero; - if (!strcmp("b", str)) return nrrdKernelBox; - if (!strcmp("t", str)) return nrrdKernelTent; - if (!strcmp("c", str)) return nrrdKernelBCCubic; - if (!strcmp("cd", str)) return nrrdKernelBCCubicD; - if (!strcmp("cdd", str)) return nrrdKernelBCCubicDD; - if (!strcmp("q", str)) return nrrdKernelAQuartic; - if (!strcmp("qd", str)) return nrrdKernelAQuarticD; - if (!strcmp("qdd", str)) return nrrdKernelAQuarticDD; - if (!strcmp("g", str)) return nrrdKernelGaussian; unrrdu / unu ------- nrrdStateKeyValuePairsPropagate is now set to AIR_TRUE if user hasn't already tried to set it via environment variable NRRD_STATE_KEYVALUEPAIRS_PROPAGATE gage -------- GAGE_QUERY_BYTES_NUM changed from 8 to 16, then to 24 Some variables in the gageContext that were "int" have now been changed to "unsigned int"; should have been done a lot time ago. * gageContext->fd * gagePoint->xi, yi, zi removed gageShapeUnitWtoI() and gageShapeUnitItoW() (the latter is still used internally as _gageShapeUnitItoW) because they were never outside of gage tweaked the logic of how continuous index-space space positions are mapped to discrete index space and offsets (in _gageLocationSet), and added test/indx function for debugging it. nixed the _gageStandardPadder() and _gageStandardNixer() functions that have long since been made obsolete (ever since gage stopped doing its own padding prior to probing) limn --------- limnPolyData completely reorganized to have multiple per-attribute arrays, but hopefully no one is using this as yet. limn now depends on gage. In previous Teem versions, this was because of how the feaure extraction needed gage, but now it is simply because there is some plan of having more gage-specific per-vertex attribute information stored in the limnPolyData renames: limnObjectOFFRead -> limnObjectReadOFF limnObjectOFFWrite -> limnObjectWriteOFF limnPolyDataIVWrite -> limnPolyDataWriteIV limnPolyDataLMPDRead -> limnPolyDataReadLMPD limnPolyDataLMPDWrite -> limnPolyDataWriteLMPD limnPolyDataVTKWrite -> limnPolyDataWriteVTK limnPolyDataOFFRead -> limnPolyDataReadOFF ten --------- tenGradientParm no longer has "srand" flag, and now has an explicit "seed" value, to allow reproducible results. "tend grads" has different command-line options accordingly tenAnisoPlot(Nrrd *nout, int aniso, unsigned int res, int hflip, int whole, int nanout) now has the "hflip" horizontal flip flag. Removed the tenAniso_Cz anisotropy measure. It was never used in Teem, its not used in the literature, and its odd because its unbounded. renames: tenEvqOne --> tenEvqSingle tenMakeOne_f --> tenMakeSingle_f tenMakeOne_d --> tenMakeSingle_d tenSimulateOne_f --> tenSimulateSingle_f various tenPath... -> tenInterp... push ------- The whole library is still under major revision, may get nixed entirely if "pull" does everythings its supposed to ==================================================================== Major API New ====================================================== ==================================================================== nrrd ------- negative byteskip now compatible with gzip encoding. Functionality contributed by Katharina Quintus nrrdDistanceL2() and nrrdDistanceL2Signed() are fast separable Euclidean distance transforms, based on code by Pedro Felzenszwalb, accessible in "unu dist" added nrrdKernelDiscreteGaussian, which implements the discrete Gaussian described by Lindeberg. Thanks to Raul San Jose. added nrrdKernelSpecSprint(), which is like the opposite of nrrdKernelSpecParse(): it prints the kernel specification to a string. New code added to test/tkernel.c to demo this (as well as adding airMop use). To make the sprinted result parse'able, it was discovered that sometimes the kernel's self-identification wasn't actually recognized as identifying that kernel by nrrdKernelParse(). This has been fixed gage ------- added the ability to probe in "stacks"- where a single volume is replaced by an array of volumes, with some kind of kernel-based interpolation between volumes. This could be used for generic 4-D volumes, but more importantly it allows probing in scale-space. Implementing this functionality was made possibly only because gage has always allowed multiple per-volumes to be probed simultaneously in a single context. This needs to be documented elsewhere in detail, but briefly: gageStackBlur() pre-computes the stack with different blurring levels, gageStackPerVolumeNew() allocates the per-volume array gageStackPerVolumeAttach() attaches the per-volume array gageStackProbe() does the probing at given 4-D position gageStackProbeSpace() does 4-D probing, with extra tricks Internal change that shouldn't be much of an API change if at all: the value of the first, unknown, item (e.g. gageSclUnknown) changes from -1 to 0, and gageKinds have a new dynamicAlloc member to indicate if the kind is dynamically allocated. The semantics of other gageKind members has been clarified relative to this, and the initialization of the item tables (e.g. _gageSclTable in teem/src/gage/scl.c) is simpler now that the pre-requisite lists don't have to be filled out with -1s (because C guarantees that uninitialized struct members will be zero). If gage users assumed that the unknown item had value -1 (and in fact, vprobe and pprobe stupidly did make this assumption), then your code has to change. The reason that gageSclUnknown used to be -1 was that in the earliest days of gage (when its brains were actually part of the bane library), queries were represented by bitflags stored in int or a long long int, and I didn't want to waste a bit (the first one) on representing an item value that would never be used. limn ---------- limnPolyDataSave() does auto-magic format detection based on filename suffix. ten -------- tenDwiGageKind is the first dynamic gageKind, meaning that information is actually allocated in the gageKind, rather than being completely set at compile time (as is gageKindScl, gageKindScl, and tenGage). This is because the number of DWIs is set at run-time. You currently create a tenDwiGageKind with tenDwiGageKindNew() and kill it with tenDwiGageKindNix(). You set all the stuff that needs to be set at run-time with tenDwiGageKindSet(), but the API of this function is pretty much guaranteed to change in future releases. tenDwiGageKind also represents the first use of gageKind->data and gagePerVolume->data, which were added to gage long ago, but never exploited until now. added tenFiberSingle, a new struct (based on a class previously in Deft) for handling all information about a single tractography result (following a single direction from a single seedpoint). Also added functions for this: tenFiberSingleInit(), tenFiberSingleDone(), tenFiberSingleNew(), tenFiberSingleNix(), and most importantly, tenFiberSingleTrace(), which actually does tractography. added tenFiberMulti, a new struct for containing an array of tenFiberSingles (basically an airArray), which is the output of tenFiberMultiTrace(). The main purpose of this function is to break the existing one-to-one correspondance between seed points and fibers, which happens with multi-fiber tractography. added tenFiberMultiPolyData(), which converts an airArray of tenFiberSingle's into limnPolyData. Like the tenFiberSingle, this is another example of code moving from Deft into Teem. "tend fiber" has been enhanced to make more of this functionality available, so it is finally able to do multiple tracts from a given list of seedpoints, instead of being merely a one-track-pony. There are many, many more tenGage items now, including some from Thomas Schultz, see teem/src/ten/ten.h for the full details. The proliferation of these has actually led to some changes in gage's compile-time limits, and in the future we may have to move to a more modular system where items are added dynamically at run-time. How to do this without breaking the existing API will be tricky. seek -------- New library for doing things like isosurfacing and ridge surface extraction. API will be in flux for some time. pull -------- New library for particle systems. API will be in flux. ==================================================================== Minor API New, not such a big deal ================================= ==================================================================== air --------- addded airRandMTSanity() to check return of airUIrandMT_r against sequence of known values airInsane_AIR_NAN_f, and airInsane_AIR_NAN_d represent new ways that airSanity() can fail airMode3_d() returns the "mode" of three values- really the skewness scaled to fit in [-1,1] airEqvAdd() and airEqvSettle() might be useful for managing information about equivalence classes airIntPow(v,p) == pow(v,p), but optimized for integral p airEnumLast() returns the last (valid) value in an airEnum airFastExp(), a fast but crude (and buggy?) approximation to exp() nrrd -------- added nrrdUnaryOpIf and "unu 1op if" nrrdFormatEPS (an output-only format) now understands 4-channel images as CMYK, exploiting the same implicit semantics as the PostScript colorimage operator, it turns out. nrrdClampConvert() is like nrrdConvert() (which is essentially per-value casting), but now values are clamped so that they don't wrap-around due to casting. "unu convert -clamp" calls this. Fixed memory leak in nrrdProject(): scan-line buffer wasn't being freed (reported by Jorik Blaas) added nrrdKernelC4Hexic, nrrdKernelC4HexicD, nrrdKernelC4HexicDD- the unique 6-sample support C4 3rd-order accurate 6th-order polynomial added nrrdSaveMulti(), which is like nrrdSave(), but saves an array of Nrrds to some set of files, based on a sprintf-style formatted string. Eventually "unu dice" will use this. added nrrdBinaryOpNormalRandScaleAdd, for adding scaled gaussian noise to given data. Accessible with "unu 2op nrand" gage -------- gageDeconvolve is a super-dumb way to deconvolve a given volume (of any gageKind) with a given kernel. Can be used to pre-sharpen an image so that convolution with, e.g., cubic:1,0 is interpolating. "vprobe" program now has TEEM_VPROBE_HACK_ZI environmental variable hack which allows probing to only be done on a single Z slice added gageScl3PFilter_t typedef, which simplifies the declaration of gageScl3PFilter2 and gageScl3PFilter4 and: added gageScl3PFilter6, gageScl3PFilter8, which were easy to implement now that the body of these functions is in the new file scl3pfilterbody.c, which is included as if its a macro (bad hack!) added gageErr airEnum, and now gage's ctx->errNum takes values from the gageErr* enum ell -------- added ell_3v_angle_f() and ell_3v_angle_d() for properly measuring angle between two unit vectors more stupid macros ELL_3V_SCALE_ADD2_TT, ELL_3V_SCALE_ADD3_TT, ELL_3M_SCALE_INCR ELL_3M_SCALE_ADD3, ELL_3MV_SCALE_OUTER_INCR, ELL_2V_COPY, ELL_4V_INCR, ELL_3M_LERP, ELL_3MV_CONTR added ell_6m_mul_d, and ell_6ms_eigensolve_d for doing Jacobi-based eigensolves of symmetric 6-by-6 matrices limn -------- limnPolyDataVertexWindingFix() might work to fix vertex winding problems limnPolyDataVertexNormals() might compute per-vertex normals limnPolyDataCCFind() might find connected components in polydata limnPolyDataWriteIV() can kind of save polydata to Inventor files limnPolyDataLMPDRead() and limnPolyDataLMPDWrite() read and write a stupid new "LMPD" polydata format, which will probably change a lot, but I needed a way of saving limnPolyData that took a long time to compute limnPolyDataVTKWrite() is mostly a VTK writer for limnPolyData limnPolyDataOFFRead() is mostly a OFF reader of limnPolyData limnPolyDataClip(), limnPolyDataVertexWindingSplit() do what the names suggest, but badly limnPolyDataSpiralTubeWrap() is new Teem home for the clever single tri-strip tube wrapping that used to be in Deft. ten --------- "tend grads" is now based on a much faster gradient descent algorithm added teem/src/ten/test/tensorDotDat, which is designed to generate the information that can replace GE's broken tensor.dat DWI gradient list file tenEstimateContext functionality can now handle skipping some of the data various strings associated with key/value pairs in DWMRI headers TEN_EXPORT const char *tenDWMRIModalityKey; TEN_EXPORT const char *tenDWMRIModalityVal; TEN_EXPORT const char *tenDWMRIBValueKey; TEN_EXPORT const char *tenDWMRIGradKeyFmt; TEN_EXPORT const char *tenDWMRIBmatKeyFmt; TEN_EXPORT const char *tenDWMRINexKeyFmt; tenFiber: added tenFiberStopRadius termination criterion based on radius of curvature of fiber tracks, and tenFiberStopStub to represent the fact that although the seedpoint was okay, neither direction of the fiber went far enough to matter. Added midpoint integration (AKA 2nd order Runge-Kutta) tenFiberIntgMidpoint, and an airEnum for tenFiberIntg "tend satin" teem/src/ten/tendSatin.c now uses full orientation, instead of just axis-aligned spacing tenExp() and tenLog() take exp() and log() of tensors added enum values tenEstimate2Method* more macros: TEN_T_SUB, TEN_T_AFFINE, TEN_T_ADD, TEN_T_LERP, and TEN_T_INCR Added the _tenAnisoTen_f[] and _tenAnisoTen_d[] arrays of functions, and the associated tenAnisoTen_f() and tenAnisoTen_d() function wrappers, to complement tenAnisoEval_{f,d}(): these provide a way of evaluating a given anisotropy measure given the tensor, whereas tenAnisoEval_{f,d}() provide a way of evaluating a given aniosotropy given the soted eigenvalues. added tenPath* functions and enums, including geodesic-loxodrome functionality. All still very much under construction... tenFiberContextDwiNew() returns a fiber context wrapped around a DWI volume, instead of a tensor volume, for some new functionality of deterministic tractography on DWIs instead of single tensors. added tenTripleConvert_d() and tenTripleConvert_f() for converting between the various triples of scalars that come up in DTI (J, R, and K invariants, eigenvalues) tenDoubleContract_d() for double contraction of a fourth-order tensor with two 2nd-order tensors added tenFiberStopAnisoSet(), tenFiberStopDoubleSet(), tenFiberStopUIntSet() so that stop criteria can be set without using var-args
Source: README.txt, updated 2012-12-20