[Ifeffit] rebinning and sampling
Grant Bunker
bunker at biocat1.phys.iit.edu
Wed Mar 12 11:50:05 CST 2003
Hi, Matt - I think the essential point is that sampling at 1 eV at k=12
A^(-1) is greatly oversampled. Suppose you want to sample data out to
R=10A (just to make sure you get everything). Then the period of those
oscillations in k-space is 2 Pi/(2 10A) ~ .3 A^(-1). Nyquist's theorem
says you should sample at least twice per cycle, so you need delta K of
0.15 A^(-1) or smaller (you don't want higher frequency noise to alias
down to low frequencies0. The 0.05 grid historically used in the UW
programs therefore is pretty conservative. Attempting to preserve a 1 eV
resolution at k=12 A^(-1) would imply a sampling of about 0.01 A^(-1), which
is quite unnecessary.
So I think the box-car average is ok when you are far enough above the edge.
I implemented something like in my own mathematica programs a couple of
years ago and it works fine, and Nick Dimakis built it into the tcl/tk
based APEX package last year.
thanks - grant
On Wed, 12 Mar 2003 ifeffit-request at millenia.cars.aps.anl.gov wrote:
> Send Ifeffit mailing list submissions to
> ifeffit at millenia.cars.aps.anl.gov
>
> To subscribe or unsubscribe via the World Wide Web, visit
> http://millenia.cars.aps.anl.gov/mailman/listinfo/ifeffit
> or, via email, send a message with subject or body 'help' to
> ifeffit-request at millenia.cars.aps.anl.gov
>
> You can reach the person managing the list at
> ifeffit-owner at millenia.cars.aps.anl.gov
>
> When replying, please edit your Subject line so it is more specific
> than "Re: Contents of Ifeffit digest..."
>
>
> Today's Topics:
>
> 1. Re: fourier transforms and k grids (Matt Newville)
> 2. Rebinning (Carlo U. Segre)
> 3. Re: Rebinning (Bruce Ravel)
> 4. Re: Rebinning (Matt Newville)
> 5. Re: Rebinning (Carlo U. Segre)
> 6. Re: Rebinning (Carlo U. Segre)
> 7. Re: Rebinning (Matt Newville)
>
>
> ----------------------------------------------------------------------
>
> Message: 1
> Date: Tue, 11 Mar 2003 12:04:57 -0600 (CST)
> From: Matt Newville <newville at cars.uchicago.edu>
> Subject: Re: [Ifeffit] fourier transforms and k grids
> To: XAFS Analysis using Ifeffit <ifeffit at millenia.cars.aps.anl.gov>
> Message-ID:
> <Pine.LNX.4.44.0303111110060.24069-100000 at millenia.cars.aps.anl.gov>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> Hi Peter,
>
> Thanks for the report. I've verified your findings that feffit()
> is doing the wrong thing for the Fourier transforms for data on
> grids other than k-grid of 0.05Ang^-1. Here's what is happening:
>
> feffit() really is interpolating data internally onto the 0.05
> grid for the fit. The fit _should_ procede correctly for data on
> any grid.
>
> Anyway, at the end of feffit() command it sends the data off to
> the fftf() command to make the chir_mag, etc arrays. It is at
> this point that the k-array in ***NOT*** being sent to the FFT.
> I've verified in my own tests that including the k-array in the
> FFT works, giving the right FFT. hopefully I will get a fixed
> version posted this week. But currently, the r-space data (data
> only, not the fits) from feffit() are wrong when a non-0.05
> k-grid is used. Simply doing
> fftf(real=data.chi, k = data.k)
>
> will give the correct r-space data.
>
> I also noticed another wart and small inconsistency between
> feffit() and fftf() from your example, which has the 'data' over
> a smaller range than the FFT window.
>
> Thanks, and sorry for the trouble,
>
> --Matt
>
>
>
> ------------------------------
>
> Message: 2
> Date: Tue, 11 Mar 2003 12:16:24 -0600 (CST)
> From: "Carlo U. Segre" <segre at iit.edu>
> Subject: [Ifeffit] Rebinning
> To: IFEFFIT Mailing List <ifeffit at millenia.cars.aps.anl.gov>
> Message-ID:
> <Pine.LNX.4.44.0303111214010.702-200000 at boride.phys.iit.edu>
> Content-Type: text/plain; charset="us-ascii"
>
>
> Matt and Bruce:
>
> Following our previous discussion of rebinning continuous scan data, I am
> attaching a python code fragment which we use to perform this function.
> You are free to use it as you like. It was written by Ken McIvor, a
> student at IIT as part of a larger project to manipulate and preview
> MR-CAT XAFS data. We simply pulled out the code and annotated it
> somewhat.
>
> Carlo
>
> --
> Carlo U. Segre -- Professor of Physics
> Associate Dean for Research, Armour College
> Illinois Institute of Technology
> Voice: 312.567.3498 Fax: 312.567.3494
> Carlo.Segre at iit.edu http://www.iit.edu/~segre
> -------------- next part --------------
> # Name: rebin-alg.py
> # Purpose: An algorithm to perform XAFS data reduction.
> # Author: Ken McIvor <mcivken at iit.edu>
> #
> # Copyright 2003 Illinois Institute of Technology
> #
> # 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 ILLINOIS INSTITUTE OF TECHNOLOGY 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.
> #
> # Except as contained in this notice, the name of Illinois Institute
> # of Technology shall not be used in advertising or otherwise to promote
> # the sale, use or other dealings in this Software without prior written
> # authorization from Illinois Institute of Technology.
>
>
> import math
> import bisect
> import Numeric
>
>
> def grid(start, stop, stepSize):
> """Create an array which can be used as an abscissa for interpolation.
>
> Returns an array of regular values, increasing by 'stepSize', which go from
> 'start' to 'stop' inclusively.
> """
> r = Numeric.arange(start, stop + stepSize, stepSize)
> while r[-1] > stop:
> r = r[:-1]
> if r[-1] < stop:
> r = Numeric.resize(r, (r.shape[0]+1, ) )
> r[-1] = stop
> return r
>
>
> def rebin(data, eColumn, Eo, after, kstep, file='', msgStream=None):
> """XAFS data reduction.
>
> 'data' is a Numerical Python matrix (rank 2 array) which contains the XAFS
> data to be reduced. 'eColumn' is the column index of the energy values of
> each point. 'Eo' is the edge energy of the data.
>
> All points for which the energy is greater than 'Eo'+'after' are
> reduced to a new set of points in which the energy varies in
> equally-spaced steps in k-space, defined by 'kstep'.
>
> 'file' is the file name corresponding to this data set, and if specified
> will be used in any exceptions raised by this functions.
>
> If 'msgStream' is specified it must be an output stream (an object
> implementing a write() method), which will used to print status
> information.
> """
>
> # if file is specified, reformat it for use in error messages
> if file:
> file = '[%s] ' % file
>
> # acquire the energy vector of the data and find its minimum and maximum
> E = data[:,eColumn]
> Min, Max = min(E), max(E)
>
> if Max <= Eo:
> raise RebinError, (
> '%sno energy values larger than Eo (incomplete data set?)'
> % file)
>
> # start rebinning points at Eo+after
> start = Eo + after
>
> if Max <= start:
> raise RebinError, '%sthe value of "after" is too large' % file
>
> # find the index of the energy vector which corresponds to the start point
> startPoint = bisect.bisect_left(E, start)
>
> # slice the energy vector and data matrix to get the points for rebinning
> eRange = E[startPoint:]
> dataRange = data[startPoint:, :]
>
> if msgStream:
> msgStream.write('%s%d points in E from %.4f to %.4f (Eo = %.4f)\n' %
> (file, eRange.shape[0], start, Max, Eo))
>
> def k(E, Eo=Eo):
> """Calculate K for some energy level E, using the edge energy argument
> passed to rebin().
> """
> return 0.512 * math.sqrt(E - Eo)
>
> # Generate the regular k-space abscissa that will be rebined to.
> # grid(start, end, step) returns a vector of values from 'start' to 'end'
> # by 'step', inclusive.
> kgrid = grid(k(start), k(Max), kstep)
>
> if msgStream:
> msgStream.write(
> '%srebinning to %d points in k-space from %.4f to %.4f\n'
> % (file, kgrid.shape[0], kgrid[0], kgrid[-1]))
>
> # newData is matrix which is BINCOUNT-1 rows long and contains the same
> # number of columns as the data matrix. It accumulates the sums of the
> # points which fall in each bin
> newData = Numeric.zeros((kgrid.shape[0]-1, data.shape[1]), data.typecode())
>
> # binCounts is a vector of BINCOUNT elements, which accumulates the number
> # of points that fall in each bin
> binCounts = Numeric.zeros( (newData.shape[0],) , data.typecode())
>
> for i in range(0, eRange.shape[0]):
> # locate the index of the bin in which the current energy level falls
> where = bisect.bisect_right(kgrid, k(eRange[i])) - 1
> if where == newData.shape[0]:
> where = where - 1
>
> # bin the data
> newData[where] += dataRange[i]
> binCounts[where] += 1
>
> # check that all of the bins contain data
> for i in range(0, newData.shape[0]):
> if binCounts[i] == 0:
> raise RebinError, ('%sbin %d (%.4f < k < %.4f) is empty'
> % (file, i, kgrid[i], kgrid[i+1]))
>
> # average the binned points
> for i in range(0, newData.shape[0]):
> newData[i,:] /= binCounts[i]
>
> # The length of E[0:startPoint] is the number of points which were not
> # rebinned. The result matrix will contain that many rows plus one row for
> # each bin.
> Len = E[0:startPoint].shape[0] + newData.shape[0]
>
> # create a new matrix to hold the final result
> result = Numeric.zeros((Len, data.shape[1]), data.typecode())
>
> # copy unrebinned and rebinned data into the result matrix
> result[0:startPoint, :] = data[0:startPoint, :]
> result[startPoint:, :] = newData
>
> return result
>
> ------------------------------
>
> Message: 3
> Date: Tue, 11 Mar 2003 14:24:23 -0500
> From: Bruce Ravel <ravel at phys.washington.edu>
> Subject: Re: [Ifeffit] Rebinning
> To: Carlo.Segre at iit.edu, XAFS Analysis using Ifeffit
> <ifeffit at millenia.cars.aps.anl.gov>
> Cc: Ken McIvor <mcivken at iit.edu>
> Message-ID: <200303111424.23646.ravel at phys.washington.edu>
> Content-Type: text/plain; charset="iso-8859-1"
>
> On Tuesday 11 March 2003 01:16 pm, Carlo U. Segre wrote:
>
> > Following our previous discussion of rebinning continuous scan data, I am
> > attaching a python code fragment which we use to perform this function.
> > You are free to use it as you like. It was written by Ken McIvor, a
> > student at IIT as part of a larger project to manipulate and preview
> > MR-CAT XAFS data. We simply pulled out the code and annotated it
> > somewhat.
>
> Very cool! I will be very happy to add rebinning to Athena.
>
> I must say that I am very pleased to see our mailing list working so
> well. To receive not just a suggestion but a fleshed out algorithm
> suggests that our little community here is starting to work very well.
>
> I was also pleased that Ken did such a good job commenting the code.
> It was very easy to read and to understand what was going on. Thanks!
>
> B
>
>
> --
> Bruce Ravel ----------------------------------- ravel at phys.washington.edu
> Code 6134, Building 3, Room 222
> Naval Research Laboratory phone: (1) 202 767 5947
> Washington DC 20375, USA fax: (1) 202 767 1697
>
> NRL Synchrotron Radiation Consortium (NRL-SRC)
> Beamlines X11a, X11b, X23b, X24c, U4b
> National Synchrotron Light Source
> Brookhaven National Laboratory, Upton, NY 11973
>
> My homepage: http://feff.phys.washington.edu/~ravel
> EXAFS software: http://feff.phys.washington.edu/~ravel/software/exafs/
>
>
> ------------------------------
>
> Message: 4
> Date: Tue, 11 Mar 2003 14:08:29 -0600 (CST)
> From: Matt Newville <newville at cars.uchicago.edu>
> Subject: Re: [Ifeffit] Rebinning
> To: Carlo.Segre at iit.edu, XAFS Analysis using Ifeffit
> <ifeffit at millenia.cars.aps.anl.gov>
> Message-ID:
> <Pine.LNX.4.44.0303111344190.26587-100000 at millenia.cars.aps.anl.gov>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> Hi Carlo,
>
> Thanks!! That's wonderful. It seems like this should be an
> option in spline() and bkg_cl(), and possibly in pre_edge(). I
> admit to being still a little confused by the goal of the
> rebinning, especially with respect to loss of resolution. It
> seems like to use this script, you need to do two things:
> 1. select an E0. The data will be put at energies that
> will give an even k-grid with this e0. I think it's
> inevitable that if e0 changes, you might want to re-bin.
>
> 2. assume that the k-grid is small enough that the
> measurements at independent energies are within the
> acceptable energy resolution that they can be
> simply summed.
>
> Is that right?
>
> Would it be OK with you (and everyone else) to have a weighted
> average replace the boxcar average? For example, at k=12,
> [E(k+0.05) - E(k)] = 5eV, which is larger than normal energy
> resolutions, so the boxcar average might wash out the high-k
> EXAFS, no? It might be better to convolve the spectra with a
> lorenztian reflecting the incident energy resolution (probably
> defaulting to 1eV). Does that seem OK or is there something eles
> going on?
>
> Anyway, thanks!!
>
> --Matt
>
>
> ------------------------------
>
> Message: 5
> Date: Tue, 11 Mar 2003 17:04:36 -0600 (CST)
> From: "Carlo U. Segre" <segre at iit.edu>
> Subject: Re: [Ifeffit] Rebinning
> To: XAFS Analysis using Ifeffit <ifeffit at millenia.cars.aps.anl.gov>
> Cc: "Carlo.Segre at iit.edu" <Carlo.Segre at iit.edu>
> Message-ID:
> <Pine.LNX.4.44.0303111523271.702-100000 at boride.phys.iit.edu>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
>
> Matt:
>
> Let me see if I can explain my reasoning adequately
>
> The reason we want to rebin continuous scan data is because in our
> continuous scan, we oversample the data significantly so reducing it to a
> step size in k of 0.05 really costs nothing. With the rebinning, it is
> possible to make use of the statistical weight of all the data. A simnple
> interpolation would throw this away. I know that you have a spline fit in
> IFEFFIT and perhaps that is an equivalent method to make use of all the
> counts in the data but this is slightly different. We have been using
> this for a while with MR-CAT data and it seems to work well for us.
>
> Yes, for this algorithm, we select an E0 and a distance above that at
> which to begin rebinning. You could just as well just set an energy at
> which to begin rebinning but the conventional idea of using energies
> relative to E0 make sense to me. The bin size just starts at this
> E0+Offset, whatever it is. There is no regard for an even value in
> k-space since the data needs to be kept in terms of energy anyway. (If
> you have suggestions about this, please let me know).
>
> If E0 changes, interpolation will be required for analysis but this is
> something that has to be done anyway when summing multiple spectra where
> there could be a small shift in E0 from one to the next. We just have to
> live with that, I suppose. This code fragment is also incorporated in a
> bigger "filter" that Ken has written which fits multiple spectra to each
> other to determine shifts, then interpolates the spectra to a common grid,
> sums or averages them and then performs the rebinning on the final
> product. We plan to use this in a GUI to assess the quality of data as we
> take it in order to figure out when to stop collecting on a sample.
>
> I suppose that it is possible to do what you suggest in "2" below but the
> boxcar gives a better representation of where the center of mass of the
> actual data is. As I mentioned before, the goal is not to get data on an
> even grid but just to remove the oversampling without losing statistics.
> Interpolation to an even grid is left for later, in the analysis software.
>
>
> Typically, in a step scan you would set the delta-k to some value like
> 0.05 or more so your original data would be no better than the rebinned
> data. If it is important to have smaller steps then perhaps the default
> should be smaller than 0.05k? The way I see it, we have not yet pushed
> the data collection as far as we will eventually go. Right now we have an
> EPICS limitation of no more than 4000 data points in a scan but once we
> break past this limit, I expect that there is plenty of flux at APS to
> take data even more densely.
>
> Your question about weighted averaging is a good one. I would have to
> think about the convolution a bit more. What do others think?
>
> Carlo
>
> On Tue, 11 Mar 2003, Matt Newville wrote:
>
> >Hi Carlo,
> >
> >Thanks!! That's wonderful. It seems like this should be an
> >option in spline() and bkg_cl(), and possibly in pre_edge(). I
> >admit to being still a little confused by the goal of the
> >rebinning, especially with respect to loss of resolution. It
> >seems like to use this script, you need to do two things:
> > 1. select an E0. The data will be put at energies that
> > will give an even k-grid with this e0. I think it's
> > inevitable that if e0 changes, you might want to re-bin.
> >
> > 2. assume that the k-grid is small enough that the
> > measurements at independent energies are within the
> > acceptable energy resolution that they can be
> > simply summed.
> >
> >Is that right?
> >
> >Would it be OK with you (and everyone else) to have a weighted
> >average replace the boxcar average? For example, at k=12,
> >[E(k+0.05) - E(k)] = 5eV, which is larger than normal energy
> >resolutions, so the boxcar average might wash out the high-k
> >EXAFS, no? It might be better to convolve the spectra with a
> >lorenztian reflecting the incident energy resolution (probably
> >defaulting to 1eV). Does that seem OK or is there something eles
> >going on?
> >
> >Anyway, thanks!!
> >
> >--Matt
> >
> >_______________________________________________
> >Ifeffit mailing list
> >Ifeffit at millenia.cars.aps.anl.gov
> >http://millenia.cars.aps.anl.gov/mailman/listinfo/ifeffit
> >
>
> --
> Carlo U. Segre -- Professor of Physics
> Associate Dean for Research, Armour College
> Illinois Institute of Technology
> Voice: 312.567.3498 Fax: 312.567.3494
> Carlo.Segre at iit.edu http://www.iit.edu/~segre
>
>
> ------------------------------
>
> Message: 6
> Date: Tue, 11 Mar 2003 18:26:57 -0600 (CST)
> From: "Carlo U. Segre" <segre at iit.edu>
> Subject: Re: [Ifeffit] Rebinning
> To: Matt Newville <newville at cars.uchicago.edu>
> Cc: XAFS Analysis using Ifeffit <ifeffit at millenia.cars.aps.anl.gov>
> Message-ID:
> <Pine.LNX.4.44.0303111824520.3090-100000 at oxide.phys.iit.edu>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
>
> Matt:
>
> Jeff Terry mentioned that perhaps I did not explain myself adequately with
> the last message.
>
> The algorithm averages BOTH counts and Energy. We do not just place the
> average number of counts at the center of the bin. Because of this, there
> should be no distortion and no need to weight.
>
> Carlo
>
>
> On Tue, 11 Mar 2003, Matt Newville wrote:
>
> >Hi Carlo,
> >
> >Thanks!! That's wonderful. It seems like this should be an
> >option in spline() and bkg_cl(), and possibly in pre_edge(). I
> >admit to being still a little confused by the goal of the
> >rebinning, especially with respect to loss of resolution. It
> >seems like to use this script, you need to do two things:
> > 1. select an E0. The data will be put at energies that
> > will give an even k-grid with this e0. I think it's
> > inevitable that if e0 changes, you might want to re-bin.
> >
> > 2. assume that the k-grid is small enough that the
> > measurements at independent energies are within the
> > acceptable energy resolution that they can be
> > simply summed.
> >
> >Is that right?
> >
> >Would it be OK with you (and everyone else) to have a weighted
> >average replace the boxcar average? For example, at k=12,
> >[E(k+0.05) - E(k)] = 5eV, which is larger than normal energy
> >resolutions, so the boxcar average might wash out the high-k
> >EXAFS, no? It might be better to convolve the spectra with a
> >lorenztian reflecting the incident energy resolution (probably
> >defaulting to 1eV). Does that seem OK or is there something eles
> >going on?
> >
> >Anyway, thanks!!
> >
> >--Matt
> >
> >_______________________________________________
> >Ifeffit mailing list
> >Ifeffit at millenia.cars.aps.anl.gov
> >http://millenia.cars.aps.anl.gov/mailman/listinfo/ifeffit
> >
>
> --
> Carlo U. Segre -- Professor of Physics
> Associate Dean for Research, Armour College
> Illinois Institute of Technology
> Voice: 312.567.3498 Fax: 312.567.3494
> Carlo.Segre at iit.edu http://www.iit.edu/~segre
>
>
> ------------------------------
>
> Message: 7
> Date: Wed, 12 Mar 2003 10:38:32 -0600 (CST)
> From: Matt Newville <newville at cars.uchicago.edu>
> Subject: Re: [Ifeffit] Rebinning
> To: XAFS Analysis using Ifeffit <ifeffit at millenia.cars.aps.anl.gov>
> Message-ID:
> <Pine.LNX.4.44.0303111829330.30280-100000 at millenia.cars.aps.anl.gov>
> Content-Type: TEXT/PLAIN; charset=US-ASCII
>
> Hi Carlo,
>
> On Tue, 11 Mar 2003, Carlo U. Segre wrote:
>
> > Matt:
> >
> > Jeff Terry mentioned that perhaps I did not explain myself adequately with
> > the last message.
> >
> > The algorithm averages BOTH counts and Energy. We do not just place the
> > average number of counts at the center of the bin. Because of this, there
> > should be no distortion and no need to weight.
> >
> > Carlo
>
> I'm not sure I see that at first glance, but I'll take your word
> for it. That isn't what I'm concerned about.
>
> Let me explain where I get stuck: let's say you have data
> collected in energy steps of 0.25eV -- could be QEXAFS, could be
> step scan. For the sake of argument, lets' set the energy
> resolution to 1eV. You have to get the data on the 0.25eV grid
> to an even k-grid for the analysis (at least in ifeffit). For
> the sake of argument, we'll say dk = 0.05Ang^-1, No matter what
> the details are, you need to get values of mu(E) for the data
> onto a gridded set E={E_i}.
>
> At k=4, E~=61.0, and k=0.05 corresponds to 1.5eV. A boxcar
> average will average the original data between 60.25 and 61.75
> and call that the new data for E=61. Seems reasonable, though
> giving equal weight to the data at 61.0 and 61.75 could be
> questioned for 1eV resolution.
>
> At k=16, E~=975.0 eV, k=0.05 corresponds to 6eV. So here, you
> average of data between E=972.0 and 978.0eV and call that the
> data for E=975.0eV. Giving equal weight to the data at 972.0 and
> 975.0 when the resolution is 1eV is what worries me. The simple
> average of mu(E) between 972.0 and 978.0 is definitely not the
> same as mu(E) at E=975.0. It would probably be better to average
> the original data between 974.0 and 976.0 for the new data at
> 975.0, and might be preferrable to just do a convolution with a
> 1eV point spread function for all the data.
>
> Certainly, if you were to re-bin data collected in 0.25eV steps
> to a grid of 10eV there would be real problems. By 'using all
> the data', one can use too much data and spoil the resolution.
>
> I don't claim that the boxcar average is wrong, or that
> convolution is definitely the right thing to do, just that I'm
> confused by this.
>
> --Matt
>
>
> ------------------------------
>
> _______________________________________________
> Ifeffit mailing list
> Ifeffit at millenia.cars.aps.anl.gov
> http://millenia.cars.aps.anl.gov/mailman/listinfo/ifeffit
>
>
> End of Ifeffit Digest, Vol 1, Issue 119
> ***************************************
>
More information about the Ifeffit
mailing list