Concatenate two waveforms

Discussion in 'Cadence' started by mm77, Jan 8, 2009.

  1. mm77

    mm77 Guest

    Hi all,

    I have a waveform representing an output noise spectrum (taken with VN
    ()), and from this I want to get a waveform of the spectrum with added
    replica as caused by sampling, to reproduce the effect of aliasing.
    I'm working in SKILL/OCEAN.
    What's the best function or approach for that?

    I am trying using these step to compute each replica
    1) flip() to get the negative frequency
    2) concatenate the flipped version with the original spectrum. To get
    the complete baseband spectrum
    2) rshift() to the sampling frequency to get a replica
    3) finally clip() to the frequencies I'm interested in and plot and
    integrate to get rms value.

    However I do not know how to perform step 2).
    How can I concatenate two waveforms?
    Using a simple sum:
    spectrum + flip(spectrum)
    does not work as I expected (seems to sum the value with same x-vector
    index, not with the same x-vector value).

    Thanks for any suggestion,
    Marco
     
    mm77, Jan 8, 2009
    #1
  2. mm77 wrote, on 01/08/09 11:17:
    Hi Marco,

    The trouble with adding the waveform is that it will extrapolate the waveforms
    being added when there is a point that does not exist in one waveform that is in
    the other. It's not doing what you're suggesting - you'll see that the waveform
    gets shifted because of this.

    Anyway, the solution would be to use this function that I just wrote. An example
    would be to do:

    abConcatWaveforms(flip(spectrum) spectrum)

    or

    abConcatWaveforms(
    flip(spectrum) spectrum rshift(flip(spectrum) 2G) rshift(spectrum 2G)
    )

    which will concatenate the spectrum with a flipped version, a flipped version
    shifted by 2G, and an unflipped version shifted by 2G.

    Hope this helps!

    Regards,

    Andrew.


    /* abConcatWaveforms.il

    Author A.D.Beckett
    Group Custom IC (UK), Cadence Design Systems Ltd.
    Language SKILL
    Date Jan 08, 2009
    Modified
    By

    Function to concatenate waveforms.

    For example:

    new=abConcatWaveforms(flip(sig) sig)

    will produce a new waveform made out of a flipped version of
    the input signal, glued to the original input signal.

    ***************************************************

    SCCS Info: @(#) abConcatWaveforms.il 01/08/09.15:41:29 1.1

    */

    /*****************************************************************
    * *
    * (abConcatWaveforms (wave1 [waves...])) *
    * *
    * Function to concatenate a number of waveforms. The function *
    * takes an arbitrary number of waveforms (assumed to all be *
    * waveforms or families of the same number of dimensions), and *
    * concatenates the axes together. Note that care should be taken *
    * if the x-axes overlap, because this merely concatenates the *
    * vectors without any checking at all. *
    * *
    *****************************************************************/

    (defun abConcatWaveforms (wave1 @rest waves)
    (let (xVec yVec newX newY newLen len)
    (cond
    ((drIsWaveform wave1)
    (setq newLen (drVectorLength (drGetWaveformXVec wave1)))
    (foreach wave waves
    (setq newLen (plus newLen
    (drVectorLength (drGetWaveformXVec wave))))
    )
    (setq newX (drCreateVec (drGetWaveformXType wave1) newLen))
    (setq newY (drCreateVec (drGetWaveformYType wave1) newLen))
    (foreach wave (cons wave1 waves)
    (setq xVec (drGetWaveformXVec wave))
    (setq yVec (drGetWaveformYVec wave))
    (setq len (drVectorLength xVec))
    (for pos 0 (sub1 len)
    (drAddElem newX (drGetElem xVec pos))
    (drAddElem newY (drGetElem yVec pos))
    )
    )
    (drCreateWaveform newX newY)
    ) ; is waveform
    ((famIsFamily wave1)
    (apply 'famMap (constar 'abConcatWaveforms wave1 waves))
    ) ; is family
    (t
    (error "abConcatWaveforms - can't handle %L\n" wave1)
    )
    ) ; cond
    ) ; let
    ) ; defun
     
    Andrew Beckett, Jan 8, 2009
    #2
  3. mm77

    mm77 Guest


    Hi Andrew, thanks for your reply.
    Is there a particular reason why the behavior for the sum is that?

    I also started this function meanwhile, but it's less generic and
    probably much less efficient.
    I'll use yours from now on.


    -----------------------------------------------------------
    procedure( mbWaveConcatenate(wave1 wave2)

    xType = drGetWaveformXType(wave1)
    yType = drGetWaveformYType(wave1)
    xVec1 = drGetWaveformXVec(wave1)
    yVec1 = drGetWaveformYVec(wave1)
    len1 = drVectorLength(xVec1)

    when(not(xType == drGetWaveformXType(wave2)) error("Waveforms must
    have same data types"))
    when(not(yType == drGetWaveformYType(wave2)) error("Waveforms must
    have same data types"))
    xVec2 = drGetWaveformXVec(wave2)
    yVec2 = drGetWaveformYVec(wave2)
    len2 = drVectorLength(xVec2)

    newLen = sub1(len1) + sub1(len2)
    xNewVec = drCreateVec(xType newLen)
    yNewVec = drCreateVec(yType newLen)

    offset = 0
    for( i 0 sub1(len1)
    ; printf("adding to elem number %L\n" i+offset)
    drSetElem(xNewVec i+offset drGetElem(xVec1 i))
    drSetElem(yNewVec i+offset drGetElem(yVec1 i))
    )

    offset = len1
    for( i 0 sub1(len2)
    ; printf("adding to elem number %L\n" i+offset)
    drSetElem(xNewVec i+offset drGetElem(xVec2 i))
    drSetElem(yNewVec i+offset drGetElem(yVec2 i))
    )

    ;printf("length(wave1) = %L\tlength(wave2) = %L\tlength(newWave) =
    %L"
    ; drVectorLength(xVec1) drVectorLength(xVec2) drVectorLength
    (xNewVec)
    ;)
    drCreateWaveform(xNewVec yNewVec)
    )
     
    mm77, Jan 8, 2009
    #3
  4. mm77 wrote, on 01/08/09 22:52:
    Marco,

    History, mainly. I can see that if the axis ranges were overlapping and slightly
    different, you could want them to extrapolate when you add (in the same way that
    you'd want points which are different to interpolate), otherwise you'd get
    glitches at the ends. Once you start doing that, I guess it's just a matter of
    definition - do you want a signal to be the extrapolated end points outside the
    range, or do you want it to be 0.

    I'm currently discussing the behaviour of the clip function with R&D, because
    that also currently extrapolates if you clip outside the range of the axis.
    There are people that want it to error out if you do that, but I can see
    arguments to:

    a) do what it does right now (extrapolate)
    b) error out
    c) clip to either the data limits, or the clip limits, provided that the
    clip limits are within the data limits
    d) pad with 0.

    Given the behaviour has been like a) for years, I think this would have to be
    via an optional argument to clip - but perhaps we can add a variety of options.
    That said, padding with 0 is a bit complicated, because how sharp would you make
    the transition from the 0 to the valid point... (I was thinking that padding
    with 0 would allow you then to add up "clipped" signals, which would have the
    same effect as concatenating them).

    Regards,

    Andrew.
     
    Andrew Beckett, Jan 9, 2009
    #4
  5. mm77

    mm77 Guest

    I see.
    Could also be the case that padding with 0 may cause some problems
    when e.g. plotting a quantity in dB that's always positive?


    The concatenate function is nice tool.
    However I noticed a little problem:
    The information about the x-axis and y-axis labels is lost. For
    example, if in both the original waveforms I had "freq (Hz)" in the x-
    axis, that' lost in the concatenated one.
    What's also lost if the information that tells the wavescan plotter to
    display that in log scale by default.
    How can I set that information into the waveform?

    Kind regards,
    Marco
     
    mm77, Jan 9, 2009
    #5
  6. mm77 wrote, on 01/09/09 17:59:
    I don't think so - the point of padding with 0 would be that when you add, the 0
    makes no contribution. I'm not convinced this is a good idea though, because of
    the problem with having to make a very sharp transition at the edges.
    I'll fix this in the morning, and re-post the code.

    Regards,

    Andrew.
     
    Andrew Beckett, Jan 11, 2009
    #6
  7. Andrew Beckett wrote, on 01/11/09 21:04:
    OK - here it is. I've also added a function to register it as a special function
    with the calculator.

    Regards,

    Andrew.

    /* abConcatWaveforms.il

    Author A.D.Beckett
    Group Custom IC (UK), Cadence Design Systems Ltd.
    Language SKILL
    Date Jan 08, 2009
    Modified Jan 12, 2009
    By A.D.Beckett

    Function to concatenate waveforms.

    For example:

    new=abConcatWaveforms(flip(sig) sig)

    will produce a new waveform made out of a flipped version of
    the input signal, glued to the original input signal.

    Copies units and name attributes from the first x and y vector it can find
    them on. Other attributes (e.g. expression) are ignored, because they're
    unlikely to be valid for the concatenated waveform. Also copies plotStyle,
    xScale and barBase waveform attributes.

    Can also register as a special function:

    abRegConcatWaveformsSpecialFunction()

    This will add abConcatWaveforms as a calculator special function.

    ***************************************************

    SCCS Info: @(#) abConcatWaveforms.il 01/12/09.10:29:05 1.2

    */

    /*****************************************************************
    * *
    * (abConcatWaveforms (wave1 [waves...])) *
    * *
    * Function to concatenate a number of waveforms. The function *
    * takes an arbitrary number of waveforms (assumed to all be *
    * waveforms or families of the same number of dimensions), and *
    * concatenates the axes together. Note that care should be taken *
    * if the x-axes overlap, because this merely concatenates the *
    * vectors without any checking at all. *
    * *
    *****************************************************************/

    (defun abConcatWaveforms (wave1 @rest waves)
    (let (xVec yVec newX newY newLen len xName xUnits yName yUnits
    newWave (attribs (makeTable 'attribs nil)))
    (cond
    ((drIsWaveform wave1)
    (setq newLen (drVectorLength (drGetWaveformXVec wave1)))
    (foreach wave waves
    (setq newLen (plus newLen
    (drVectorLength (drGetWaveformXVec wave))))
    )
    (setq newX (drCreateVec (drGetWaveformXType wave1) newLen))
    (setq newY (drCreateVec (drGetWaveformYType wave1) newLen))
    (foreach wave (cons wave1 waves)
    (setq xVec (drGetWaveformXVec wave))
    (setq yVec (drGetWaveformYVec wave))
    (setq len (drVectorLength xVec))
    (for pos 0 (sub1 len)
    (drAddElem newX (drGetElem xVec pos))
    (drAddElem newY (drGetElem yVec pos))
    )
    ;--------------------------------------------------------
    ; Record attributes
    ;--------------------------------------------------------
    (unless xName (setq xName (getq xVec name)))
    (unless xUnits (setq xUnits (getq xVec units)))
    (unless yName (setq yName (getq yVec name)))
    (unless yUnits (setq yUnits (getq yVec units)))
    (foreach attrib '(plotStyle xScale barBase)
    (unless (and
    (arrayref attribs attrib)
    (get wave attrib))
    (setarray attribs attrib (get wave attrib))
    ))
    )
    ;-----------------------------------------------------------------
    ; Store found attributes
    ;-----------------------------------------------------------------
    (when xName (putpropq newX xName name))
    (when xUnits (putpropq newX xUnits units))
    (when yName (putpropq newY yName name))
    (when yUnits (putpropq newY yUnits units))
    ;-----------------------------------------------------------------
    ; Finally create the new waveform
    ;-----------------------------------------------------------------
    (setq newWave (drCreateWaveform newX newY))
    (foreach attrib attribs
    (putprop newWave (arrayref attribs attrib) attrib)
    )
    newWave
    ) ; is waveform
    ((famIsFamily wave1)
    (apply 'famMap (constar 'abConcatWaveforms wave1 waves))
    ) ; is family
    (t
    (error "abConcatWaveforms - can't handle %L\n" wave1)
    )
    ) ; cond
    ) ; let
    ) ; defun

    /******************************************************************
    * *
    * (abConcatWaveformsSpecialFunctionCB) *
    * *
    * Callback function for the abConcatWaveforms special function *
    * Just takes the buffer and one stack item and concatenates them. *
    * *
    ******************************************************************/

    (defun abConcatWaveformsSpecialFunctionCB ()
    (calSpecialFunctionInput 'abConcatWaveforms '(STACK))
    )

    /*******************************************************************
    * *
    * (abRegConcatWaveformsSpecialFunction) *
    * *
    * Register abConcatWaveforms as a special function. Note that this *
    * only uses abConcatWaveforms with two arguments - otherwise would *
    * need a form to indicate how many values to concatenate - so this *
    * keeps it simple! *
    * *
    *******************************************************************/

    (defun abRegConcatWaveformsSpecialFunction ()
    (calRegisterSpecialFunction
    (list "abConcatWaveforms" 'abConcatWaveformsSpecialFunctionCB))
    t
    )
     
    Andrew Beckett, Jan 12, 2009
    #7
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.