Please Help: working with text waves

I have two tasks I need to complete with text waves (which I've never figured out how to work with very well in Igor). They seem simple, but they have foiled me all morning. I am working in Igor Pro 6.37.

Task 1: I have 11 separate text waves that contain different molecular formulas. I need to create one master text wave that concatenates all 11 text waves and removes the duplicates. I know how to do this for numeric waves, but can't figure out how to do it for a text wave. Please help!

 

Task 2: A little trickier. Now that I have created my master text wave with all the formulas identified in each of my samples, I need to populate 11 numeric waves (one for each sample) with the abundance associated with the formula. Normally I would use FindValue, but I am struggling because of the text wave. FindValue/TEXT= is asking me to put in the actual string I want it to search for, but I want it to index through the master text wave (in a for loop) and look for one string at a time. I have created a string variable and assigned it to index [i] of my master text wave, but it keeps giving me an error when I use that string variable as the FindValue TEXT. For example, if I have something like

 

string store

For(i=0;i<numpnts(masterwave);i+=1)

store = masterwave[i]

FindValue/TEXT=store sample

 

I get an error using the store string variable, but if I put parentheses around "store" won't it just look for the word "store" and not the indexed string value from the text wave?

Any assistance for either of these problems is greatly appreciated. Thank you.

 

For task 1 I would create a semicolon separated string that is a list containing the name of each of the text waves you want to concatenate. Then use the Concatenate operation (with /NP=0) to concatenate all of the waves into one.

To get all of the unique values, I would first sort the wave and then use Extract/INDX to get a wave containing the indexes into the text wave that are unique. Then create a new text wave with that many points and assign the values.

Here's some example code that creates some fake data and finds the unique string values:

make/n=100/T tw = num2istr(enoise(15))
edit tw
Sort tw, tw
Extract/INDX/O tw, twUniqueIndexes, ((p == 0) || CmpStr(tw[p], tw[p-1], 0) != 0)
edit twUniqueIndexes
Make/O/N=(numpnts(twUniqueIndexes))/T uniqueStrings
uniqueStrings = tw[twUniqueIndexes[p]]
edit uniqueStrings

Note that if you were using Igor 8 or later you could replace the sort, extract, and wave assignment with a simple call to FindDuplicates/RT

Also note that if you want to treat molecular formulas that use different cases as different (eg. h2o and H2O are different) you'll need to change the 3rd parameter to CmpStr from 0 to 1.

For your second task I don't understand what you're trying to do. The sample code you provided looks ok if the wave named sample is a text wave. It might help if you provided enough code so we could actually execute the code. We'd also need the data waves (or some way to generate fake data).

If you had access to the Igor Pro 9 beta, it's possible that the new TextHistogram operation would be useful here.

Here is a function to remove duplicates. It has some additional functionality, but could be simplified to do only what you need by removing the wave reference wave.

// RemoveDuplicates(w) removes duplicates from textwave w
// RemoveDuplicates(w, wrefs={w1}) removes duplicates from textwave w
// and corresponding points in waves referenced in wrefs
threadsafe function RemoveDuplicates(wave /T w, [wave /Z/wave wrefs])
    int i,j
    for (i=numpnts(w)-1;i>=0;i-=1)
        FindValue /TEXT=w[i] w
        if (V_value>-1 && V_value<i)
            DeletePoints i, 1, w
            if (WaveExists(wrefs))
                for (j=0;j<numpnts(wrefs);j+=1)
                    DeletePoints i, 1, wrefs[j]
                endfor
            endif
        endif
    endfor
    return numpnts(w)
end

 

In reply to by aclight

This was very helpful. Thank you. I now have a concatenated master list with unique formula names. Step 1, check.

A little further clarification on the second part. I now need to create a "sample abundance" wave for each sample with the same number of points as my unique master list of formulas. I need to fill in the abundance values for each formula in that sample. This should be simple using FindValue, but I am again getting an error because of the text wave. It's like Igor doesn't know my "uniqueStrings" wave in the function is a text wave, and I don't know why. How can I get it to recognize it is a text wave!?

 

Here is the code I am trying. This would be used to generate one complete sample wave with abundances filled in for each formula. Wave Key: SampleForm is the wave with all chemical formulas identified in that sample; SampleAbund is the corresponding abundance of that formula in the sample; unique strings is the "master" list of all unique formulas identified in all samples; SampleAbund_master is the wave I am trying to fill in. 

I am getting an error with this code at the point, "store=uniqueStrings[i]" because Igor says it needs a string value. I was trying this approach because when I tried "FindValue/TEXT=uniqueStrings[i] sampleForm" I was getting the same error.

 

Function SampleFill(SampleForm, SampleAbund)

wave SampleForm
wave SampleAbund

wave uniqueStrings
wave SampleAbund_master
variable i
string store

make/O/N=(numpnts(uniqueStrings)) SampleAbund_master

For(i=0;i<(numpnts(uniqueStrings));i+=1)

    store=uniqueStrings[i]

    FindValue/TEXT=store sampleForm
    
    If(V_Value>-1)
    
    SampleAbund_master[i]=sampleAbund[V_Value]
    
    Else
    
    SampleAbund_master[i]=NaN
        
    EndIf
EndFor

edit SampleAbund_master
End

Your input text wave needs to be declared using the /T flag:

Wave/T sampleForm

Your uniqueStrings wave also needs Wave/T.

At compile time, Igor doesn't know the type of the wave that will be passed in. By default, the compiler assumes numeric.

YES! It worked. Thank you. I didn't realize I could assign it as a text wave with just wave/T. This will make my life so much easier in the future. 

Now that you've been through some of these problems, and successfully solved them, this help section may make more sense that it did the first time through: DisplayHelpTopic "Accessing Global Variables And Waves"