[pymvpa] Pkg-ExpPsy-PyMVPA Digest, Vol 18, Issue 10
Yaroslav Halchenko
debian at onerussian.com
Fri Aug 21 20:27:28 UTC 2009
On Fri, 21 Aug 2009, Johan Carlin wrote:
just a quick hint:
> roi_ds = ds.copy()
> roi_ds = roi_ds.selectFeatures(feats)
imho there is no need for .copy() since selectFeatures creates a new
dataset anyways... or am I wrong? ;)
> Which seems similar to what you're suggesting.
seems to be ;)
> The problem with doing
> this on masked data is that you get an error whenever the center
> coordinate is outside the mask (even if the sphere contains other
> in-mask voxels).
rright -- it seems we did not foresee such usecase, or just we were
wrong in our assumptions of its usefulness ;)
> To get around this, I make the ROI based on unmasked
> data, and then I apply the mask to the ROI dataset.
makes sense... I might suggest alternative solution (not sure if we
should implement a helper for it within pymvpa).
So, if you load a single full (or ROI-surround mask, or just
full-brain) volume (lets load it into dataset ds_full), and then
you load your ROI dataset within ds_roi, then for voxel which is
outside of ROI but has features within sphere in the ROI you could use
ds_full.mapper to figure out 3D coordinates for the neighbors, and then
just select the ones which are valid for ds_roi. Here is a snippet
which I've added to unittests (resides under
mvpa.tests.test_niftidataset:NiftiDatasetTests.testNiftiDatasetROIMaskNeighbors)
ids_out = []
for id_in in ds_full.mapper.getNeighborIn( (12, 20, 37), radius=20):
try:
ids_out.append(ds_roi.mapper.getOutId(id_in))
except ValueError:
pass
so, at the end in ids_out you got list of feature ids within ds_roi which
are within 20mm of that voxel... may be there is even better way -- but
don't have it in mind atm ;)
is that smth like what you need? ;)
> >> lmap = dict(zip(ds.labels_map.values(),ds.labels_map.keys()))
> > whenever creating a new dataset? (may be I got confused...)
> If you just put in the ds.labels_map as it is, you get something like this:
> m_ds = MaskedDataset(samples=ds.samples_original, labels=ds.L,
> chunks=ds.C, labels_map=ds.labels_map)
> ValueError: Provided labels_map {'212': 5, '211': 4, '121': 2, '122':
> 3, '111': 0, '112': 1, '222': 7, '221': 6} is insufficient to map all
> the labels. Mapping for label 5 is missing
> The 3-digit stringed values are my original labels. So it looks like
> the ds.labels_map is stored with key=original label, value=mapped
> label, but the opposite structure is needed when definining a new
> dataset.
I see it now ;) Sorry for too much "magic" behind labels_map.
Since it had evolved over time, docstring was not reflecting
actual behavior I guess, so I adjusted docstring to be:
Map original labels into numeric labels. If True, the
mapping is computed if labels are literal. If is False,
no mapping is computed. If dict instance -- provided
mapping is verified and applied.
So, what was happening -- since your labels are numeric already and you
provided original labels_map as dict, it tried to remap already numeric labels
using mapping of literal to numeric. Obviously it failed ;) With your
'reverse' mapping it has done somewhat more evil thing, mapped numerical labels
back into literal (which is not strictly forbidden, but I guess worth a
warning, I've added it -- ie, if now resultant labels are literal).
After such mapping, some classifiers (which remap labels internally anyways,
such as SMLR, or just don't care much about type of labels, such as kNN I
believe) might still perform as fine, but YMMV ;)
back to your issue, to at least document a 'workaround' whenever labels_map
should not be provided to constructor but rather assigned later on, I've
added another piece of documentation to labels_map keyword argument:
If you want to have labels_map just be present given already
numeric labels, just assign labels_map dictionary to existing dataset
instance
so, just define m_ds without providing labels_map argument, and then
assign it afterwards:
m_ds.labels_map = ds.labels_map
> > in your code instead of MaskedDataset you could use NiftiDataset where
> > samples... but before getting in details lets first figure out if above snippet
> > was what you were looking for
> That sounds very useful, please tell me more. :)
Well... I guess with the above getIn/getOut magic you could simply work on
NiftiDatasets as is, without reverting to MaskedDataset ;)
in general, if your original space of MaskedDataset is actually the same
as NiftiDataset but used mask was different, you could simply
construct a new NiftiImage using header information only from existing
NiftiDataset... smth like
NiftiImage(maskeddataset.O, header=niftidataset.niftihdr).save('bugi.nii.gz')
--
.-.
=------------------------------ /v\ ----------------------------=
Keep in touch // \\ (yoh@|www.)onerussian.com
Yaroslav Halchenko /( )\ ICQ#: 60653192
Linux User ^^-^^ [175555]
More information about the Pkg-ExpPsy-PyMVPA
mailing list