Read and extract values of variables and waves' name using multithread function from mass # of waves
Thanks for the help about extracting value of center of mass. I have tried to extract X axis peak position and center of mass using demo procedure - Thread-at-a-Time Demo
I am also interested in displaying each wave name from the variables. However, I have tried and failed.
I have learned that the I need to introduce string to extract wave name, but I don't know how to put the string with variables.
Please helps!
Here is the modified version to replace min and max value.
#pragma rtGlobals=3 // Use modern global access method. Menu "Macros" "Thread-at-a-Time Demo", ThreadAtATimeDemo() End // These control various troubleshooting items and other aspects of the demonstration Constant kNumDatasetsToProcess = 400 // Number of sample input waves to create and process Constant kSampleWaveNumPoints = 10000 // Number of points in each sample input wave Constant kPrintStartThreadMessage = 1 Constant kPrintGotThreadDFMessage = 1 Constant kSimulateVaryingComputationTime = 1 ThreadSafe Function ThreadWorker(wIn, waveIndex) WAVE wIn Variable waveIndex ////// //// String namewave = nameofwave(wIn) <---I introduce string here Wavestats/q wIn variable xPeak = V_maxloc Variable i,n=numpnts(wIn), massTimesX=0 for(i=0; i<n; i+=1) massTimesX += wIn[i]*pnt2x(wIn,i) endfor Variable totalMass=sum(wIn) Variable centerOfMass= massTimesX/totalMass // printf "Center of Mass: %g", centerofMass //return centerOfMass // This is used to simulate varying computation time if (kSimulateVaryingComputationTime > 0) Variable randomSecs = abs(enoise(kSimulateVaryingComputationTime)) Sleep/S randomSecs endif //Variable wMin = WaveMin(wIn) //Variable wMax = WaveMax(wIn) // Create data folder to return to calling thread NewDataFolder/S output // Create output variables // Variable/G gMin = wMin Variable/G gcenterOfMass =centerOfMass Variable/G gxPeak = xPeak // String/G gnamewave=namewave ( I tried to add this but it did not work) // This tells the calling thread which wave was processed Variable/G gWaveIndex = waveIndex // Send data back to main thread ThreadGroupPutDF 0, : return 0 // Success End Function ThreadAtATimeDemo() if (IgorVersion() < 6.23) Abort "This demo requires Igor Pro 6.23 or later." endif Variable t0 = StopMSTimer(-2) // Used to time the function DFREF originalDFR = GetDataFolderDFR() DFREF outputDFR = GetDataFolderDFR() Variable numDatasetsToProcess = kNumDatasetsToProcess Variable numDatasetsProcessed = 0 // Make output wave Make/O/D/N=(numDatasetsToProcess,3) outputDFR:results = NaN Wave results = outputDFR:results SetDimLabel 1,0,CenterOfMass,results SetDimLabel 1,1,Peak,results SetDimLabel 1,2,Name,results ///<----Third column I added for wavename // Create output table DoWindow /F OutputTable if (V_flag == 0) Edit /N=OutputTable /W=(466,49,906,652) results.ld endif // Look for sample data Variable numPointsInSampleData = kSampleWaveNumPoints // NewDataFolder /O :SampleData DFREF inputDFR = : String name Variable i for(i=0; i<numDatasetsToProcess; i+=1) sprintf name, "(%d)", i // wave0, wave1 // Make/O/D/N=(numPointsInSampleData) inputDFR:$name = gnoise(1) (disabled) SetDimLabel 0,i,$name,results endfor // Create threads Variable numThreads = ThreadProcessorCount Variable threadGroupID = ThreadGroupCreate(numThreads) SetDataFolder inputDFR // Needed for WaveRefIndexed // Dispatch threads and collect output Variable threadIndex Variable waveIndex = 0 do // Start any free threads do if (waveIndex >= numDatasetsToProcess) break // No more input data to dispatch to a thread endif // Find a free thread threadIndex = ThreadGroupWait(threadGroupID, -2) // Requires Igor Pro 6.23 threadIndex -= 1 // Because ThreadGroupWait returns threadIndex+1 if (threadIndex < 0) break // No free threads endif // Start thread Wave wIn = WaveRefIndexed("", waveIndex, 4) ThreadStart threadGroupID, threadIndex, ThreadWorker(wIn, waveIndex) if (kPrintStartThreadMessage) Printf "Started thread %d\r", threadIndex // For debugging only endif waveIndex += 1 while(1) // See if thread output is available DFREF dfr = ThreadGroupGetDFR(threadGroupID, 0) if (DataFolderRefStatus(dfr) != 0) // Process results NVAR gcenterOfMass = dfr:gcenterOfMass NVAR gxPeak = dfr:gxPeak NVAR gWaveIndex = dfr:gWaveIndex // NVAR gnamewave= dfr:$namewave <---- I tried this but it did not work because of string function I believe. results[gWaveIndex][0] = gcenterOfMass results[gWaveIndex][1] = gxPeak // results[gWaveIndex][2] = $namewave <-----It did not work // Update the output table DoUpdate // For debugging only if (kPrintGotThreadDFMessage) Printf "Got data for wave %d: CenterOfMass=%g, Peak=%g\r", gWaveIndex, gcenterOfMass, gxPeak endif numDatasetsProcessed += 1 // This is a free data folder that would be killed automatically by Igor. // Nonetheless we explicitly kill it here and now. KillDataFolder dfr endif while(numDatasetsProcessed < numDatasetsToProcess) Variable dummy = ThreadGroupRelease(threadGroupID) Variable t1 = StopMSTimer(-2) Variable elapsedTime = (t1 - t0) / 1E6 Printf "Finished ThreadAtATimeDemo in %.2f seconds.\r", elapsedTime SetDataFolder originalDFR End Function CleanupExperiment() // We call this to prepare the experiment for shipping DoWindow /K OutputTable // The table is recreated by the demo KillWaves/Z results // Output wave is recreated by the demo KillDataFolder /Z root:SampleData // Sample data is recreated by the demo End
Thank you very much!
needs to be:
--Jim Prouty
Software Engineer, WaveMetrics, Inc.
January 17, 2014 at 09:19 am - Permalink
needs to be:
--Jim Prouty
Software Engineer, WaveMetrics, Inc.[/quote]
Thanks, I just learned the function of SVAR.
Here is what I added to:
In the function of
ThreadSafe Function ThreadWorker(wIn, waveIndex)I introduced
string NameWave =NameofWave(wIn)String/G gNameWave=NameWaveThen, in the function of
Function ThreadAtATimeDemo()I added one column to the table
And introduced SVAR for wave name
But, I received error saying
results[gWaveIndex][2] = gNameWaveunknown/inappropriate name or symbol...
with my current knowledge, I don't know where is the error and I need your help.
Thank you!
Here is the code:
January 17, 2014 at 10:25 am - Permalink
Thanks, I just learned the function of SVAR.
Here is what I added to:
In the function of
ThreadSafe Function ThreadWorker(wIn, waveIndex)I introduced
string NameWave =NameofWave(wIn)String/G gNameWave=NameWaveThen, in the function of
Function ThreadAtATimeDemo()I added one column to the table
And introduced SVAR for wave name
But, I received error saying
results[gWaveIndex][2] = gNameWaveunknown/inappropriate name or symbol...
with my current knowledge, I don't know where is the error and I need your help.
[/quote]
Note that the results wave is numeric.
The string is not.
You can't assign a string to a number.
--Jim Prouty
Software Engineer, WaveMetrics, Inc.
January 17, 2014 at 11:58 am - Permalink
Thanks, I just learned the function of SVAR.
Here is what I added to:
In the function of
ThreadSafe Function ThreadWorker(wIn, waveIndex)I introduced
string NameWave =NameofWave(wIn)String/G gNameWave=NameWaveThen, in the function of
Function ThreadAtATimeDemo()I added one column to the table
And introduced SVAR for wave name
But, I received error saying
results[gWaveIndex][2] = gNameWaveunknown/inappropriate name or symbol...
with my current knowledge, I don't know where is the error and I need your help.
[/quote]
Note that the results wave is numeric.
The string is not.
You can't assign a string to a number.
--Jim Prouty
Software Engineer, WaveMetrics, Inc.[/quote]
Thank you.
Are there any ways to extract wave name as well as the two variables to the table using this algorithm? If so, you are welcome to make changes.
I guess the problem is the
gWaveIndex? I noticed that gWaveIndex was assigned as variable. But I don't know how to convert it to string.Please bear in mind, I am new to IGOR and I try my best to understand programming syntax as a biologist. I need your advices and suggestions.
Thank you again.
January 17, 2014 at 12:47 pm - Permalink
Thanks, I just learned the function of SVAR.
Here is what I added to:
In the function of
ThreadSafe Function ThreadWorker(wIn, waveIndex)I introduced
string NameWave =NameofWave(wIn)String/G gNameWave=NameWaveThen, in the function of
Function ThreadAtATimeDemo()I added one column to the table
And introduced SVAR for wave name
But, I received error saying
results[gWaveIndex][2] = gNameWaveunknown/inappropriate name or symbol...
with my current knowledge, I don't know where is the error and I need your help.
[/quote]
Note that the results wave is numeric.
The string is not.
You can't assign a string to a number.
--Jim Prouty
Software Engineer, WaveMetrics, Inc.[/quote]
Hello Jim,
Thank you for pointing out the error again. I have fixed the incomparability (text vs. numeric)
I got what I want with the minimal knowledge of programming.
Here is the code, just in case someone is interested in trimming it.
January 17, 2014 at 03:28 pm - Permalink
January 17, 2014 at 05:06 pm - Permalink
Hi jtigor,
Obtaining such values have made my life so much easier!!!
I see your point. I will try to change the output into string using num2str. If I got stuck in doing such changes, I will seek help here.
Thanks!
January 17, 2014 at 08:08 pm - Permalink
This can be a good technique. I think it's worth pointing out that when transmitting values via text you have to be *very* careful that you preserve the necessary precision of the numbers. A round-trip through num2str/str2num will truncate the values to 6 digits.
The num-string-num conversions are also slow. Since you are going to the trouble of writing threaded code, I presume speed is important to you.
As jtigor says, how you use the results is a crucial consideration.
John Weeks
WaveMetrics, Inc.
support@wavemetrics.com
January 20, 2014 at 09:37 am - Permalink
... becomes this ...
Your processing afterward is then a case of extracting the keyword=value set from gListInfo.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
January 20, 2014 at 10:57 am - Permalink