09-19-2014 06:34 AM
Hallo zusammen,
bin ein Neuling was DIAdem-Scripte angeht und bin auf ein Problem gestoßen, welches ich auch durch eine intensive Websuche nicht lösen konnte, vielleicht hat hier jemand einen Tip, wie ich das angehen könnte und ob es eine einfache Möglichkeit gibt?
Ich habe Messergebnisse in TDM- und TDMS-Dateien. In jeder Datei sind ein Haufen Gruppen und Kanäle vorhanden, ich benötige jedoch nur einen ganz kleinen Teil und möchte daher die benötigten Kanäle mit dem Befehl "DataFileLoadSel" laden. Das funktioniert soweit auch, jedoch habe ich nun das Problem, dass die zu ladenen Kanäle sich im Namen und auch in der Kanalnummer unterscheiden, d.h. ich kann diese weder im Namen noch in der Kanalnummer eindeutig ansprechen. Die möglichen Namen kenne ich.
Jetzt wollte ich diese möglichen Kanäle in ein Array schreiben und nun in einer Schleife prüfen, ob diese in der Datei vorhanden sind, ohne diese komplett ins DIAdem zu laden und im Anschluss den vorhandenen Namen nutzen, um die Datei zu laden. Und genau an dieser Prüfung scheitere ich, da ich bisher nur Möglichkeiten gefunden habe Kanäle zu prüfen, welche bereits ins DIAdem geladen wurden.
Ich habe mir erstmal beholfen, indem ich alle Möglichkeiten lade und den Fehler und Scriptabbruch durch nicht vorhandene Kanäle mit "on error resume next" abfange. Das ist natürlich extrem unschön und die Laufzeit meines Programms ist verhältnismäßig lang.
Daher meine Frage: Hat jemand einen Tip oder eine Möglichkeit, wie ich Kanäle in Dateien, welche nicht geladen wurde auf Existenz vor dem Laden überprüfen kann?
Viele Dank schonmal.
Gruß Gerd
Solved! Go to Solution.
09-19-2014 09:08 AM
Hi Gerd,
The simplest solution is to reference load the whole TDM or TDMS file, then check your possible channel list against the reference loaded channels in the Data Portal and delete the channels that don't match. I'd recommend a Dictionary object for that lookup task.
There are a couple of different ways of reference loading these files. For the particular case of TDM and TDMS files, and with DIAdem 2011 and later, the default behavior of DIAdem is to reference load TDM and TDMS files. So if you've got DIAdem 2011 or later you can just use DataFileLoad normally. If you have an older DIAdem version, or if you've configured DIAdem to NOT reference load TDM or TDMS files, then you will need to explicitly reference load the file like this:
Call DataFileLoad(DataFilePath, DataPluginName, "Register")
Brad Turpin
DIAdem Product Support Engineer
National Instruments
09-19-2014 10:35 AM - edited 09-19-2014 10:37 AM
If you really have a huge amount of channels in your file and can not use Brads approach you could try two additional approaches.
DataFinder: If your files are index by datafinder you can just search the channels (using or condition) and load them.
DataStore: Use code like the following one that allows you to extract information without having to multiple reopen the file.
Option Explicit dim filenamePath : fileNamePath = "C:\temp\example.tdm" dim store : set store = navigator.ConnectDataStoreByParameter("TDM", filenamePath) dim group : set group = store.RootElements(1).Children("Example") if group.Children.Exists("Time") then navigator.LoadData group.Children("Time"), "Load" , nothing elseif group.Children.Exists("Revs") then navigator.LoadData group.Children("Revs"), "Load" , nothing end if
09-29-2014 03:53 AM
Hi Brad,
thanks for your reply.
The Problem is, that I have a lot of channels and groups in my files. When I load (or register) them all it'll be tricky to find out which one to delete an which not. Because all the channels I loaded I arrange in Groups with new names. It's possible for sure but I think it's not the simplest solution.
Gerd
09-29-2014 05:01 AM
Hi Andreas,
thanks for your reply.
After one week holyday I tried your solution with the DataStore. I think this is the solution I was looking for. But I don't know if i understand what happens exactely so it does not work correct.
dim filenamePath : fileNamePath = "C:\temp\example.tdm"
-> no problem, my variable has another name so i just exchanged it. It already exists.
dim store : set store = navigator.ConnectDataStoreByParameter("TDM", filenamePath)
-> also no problem
dim group : set group = store.RootElements(1).Children("Example")
-> here i don't know for what "1" and "Example" stands. Perhaps 1 is the number of the group (group index) in my file?
-> Or is "Example" the name of the group? Iguess so, but what is the "1"?
if group.Children.Exists("Time") then
-> in which group does the function search the channel "Time"? In The group "Example"?
navigator.LoadData group.Children("Time"), "Load" , nothing
-> And I guess when the channel was found it's loaded? But this seems to be the part where my script loads something wrong. When i exchange this line with:
->call DataFileLoadSel(fileNamePath, "TDM" , "Example/Time", "Load")
-> it works and loads the channel i want, but else it loads a channel with the same name but different values. And in the data portal ist not a "~" in front of the channel, ther is a "123"
my code looks like this:
"Richtung" is variable with the group name in my file where the channel is located
"oResult" is the result of the file search (the file whith the data)
"v_Fahrzeug", "GPS_Speed" and "Geschwindikgeit" are the possibilities for the channel names.
dim store : set store = navigator.ConnectDataStoreByParameter(Right(oResult.name, (len(oResult.name) - inStrRev(oResult.name, "."))), "D:\DIADEM_Auswertung\Auswertung_Daten\Messung\" & oResult.name)
dim group : set group = store.RootElements(1).Children(Richtung)
if group.Children.Exists("v_Fahrzeug") then
call DataFileLoadSel("D:\DIADEM_Auswertung\Auswertung_Daten\Messung\" & oResult.name,Right(oResult.name, (len(oResult.name) - inStrRev(oResult.name, "."))) , Richtung & "/v_Fahrzeug", "Load")
'navigator.LoadData group.Children("v_Fahrzeug"), "Load" , nothing
elseif group.Children.Exists("GPS_Speed") then
navigator.LoadData group.Children("GPS_Speed"), "Load" , nothing
elseif group.Children.Exists("Geschwindikgeit") then
navigator.LoadData group.Children("Geschwindikgeit"), "Load" , nothing
end if
So where is the mistake?
Could you please explain me the function of your code an the expression "navigator.LoadData group.Children("Time"), "Load" , nothing"?
Sorry if it's not clear what I want to know, my english is not the best and a bit "rusty".
Gerd
09-29-2014 10:00 AM
If you already use datafinder to determine oResult you shoult try to determine the channels you want to load by extending the query.
If you want to load using datastore I expanded the example with some extra lines and comments. Trying to answer your questions.
Option Explicit dim filenamePath : fileNamePath = "C:\temp\example.tdm" dim storeType : storeType = UCase(Right(filenamePath, (len(filenamePath) - inStrRev(filenamePath, ".")))) ' open the file Readonly, storetype must be TDM or TDMS dim store : set store = navigator.ConnectDataStoreByParameter(storeType, "<filename readonly=""yes"">" & replace(filenamePath, "&", "&") & "</filename>") dim root : set root = store.RootElements(1) ' tdm datastores do always have exactly one root dim group : set group = root.Children("Example") ' get the group by name if group.Children.Exists("Time") then navigator.LoadData group.Children("Time"), "Load" , nothing elseif group.Children.Exists("Revs") then navigator.LoadData group.Children("Revs"), "Load" , nothing end if store.Close ' closes the access to the file. Will happen automatically if script finishes
I am not aware of any case where DataFileLoadSel loads something different than the channel loaded using the datastore API. So if you have such files I would be very interested to get one of them.
(What does different values mean?)
I have also no idea what " ist not a "~" in front of the channel, ther is a "123"" refers to. If DIAdem loads to channels named Time by default the second one gets 1 atatched.
The navigator.LoadData returns the result channels/channels so it is possible to change the name to your needs.
09-30-2014 02:32 AM - edited 09-30-2014 02:36 AM
Okay, I think I have to explain my problem detailed that you understand what I'm doing.
I have a folder "D:\DIADEM_Auswertung\Auswertung_Daten". In this folder there are two diffrent folders called "Messung" and "Simulation" where are files created out of measurements in one folder and files created out of simulations in the other folder. Sometimes just one measurement file and one simulation file but probably sometimes more than one.
Now we have to compare the simulation and the measurement to find out if the measurement was okay. The problem now is, that the files out of the measurement contain a lot of data (goups and channels) which are not interesting for us. One file has about 500 mb. So I don't want to load the whole file but just the few channels we need. In addition in one file there are more than one measurement (4-6). This different data is stored in groups. So I have 4 to 6 groups in one file which i have to look through. Unfortunately this are not all the groups in the file and the group index is not always the same. Also the names of the channels and the index of the channels are not the same.
Now the task is to find the channels, load them, rename them, and probably change the unit or convert them to another unit. Furthermore I have to organize the loaded channels in Groups named after the files.
First of all I use the navigator to find my files in the folder "Messungen". For each one I call a function which loads all of my 10 channels if they are existing. Moreover I have a function call for each measurement in one file.
Afterwards I have to do the same with the files out the simulation but this is no problem because the channels are named always the same so I can load them directly.
Here is a bigger part of my code:
sub LoadData
.
.
.
i = 1
Rueckgabe = 0
For Each oResult In oResult.Elements
Richtung = "Beschl_Richtung 1 - Nord-Sued_01"
Rueckgabe = Messung (i, Richtung, oResult)
i=i+1-Rueckgabe
Richtung = "Beschl_Richtung 1 - Nord-Sued_02"
Rueckgabe = Messung (i, Richtung, oResult)
i=i+1-Rueckgabe
.
.
.
end sub
function Messung (byval i, Richtung, oResult)
dim filenamePath : filenamePath = "D:\DIADEM_Auswertung\Auswertung_Daten\Messung\" & oResult.name
dim storeType : storeType = UCase(Right(filenamePath, (len(filenamePath) - inStrRev(filenamePath, "."))))
dim store : set store = navigator.ConnectDataStoreByParameter(storeType, filenamePath)
dim root : set root = store.RootElements(1)
if root.Children.Exists(Richtung) then
Dim KanalGeschFahr : KanalGeschFahr = Array("v_Fahrzeug", "GPS_Speed", "Geschwindikgeit")
Dim KanalBeschleunigung : KanalBeschleunigung = Array("GS2_Acceleration", "a_Fahrzeug_x", "Beschleunigung")
.
.
.
dim m
Call GroupCreate(left(oResult.name, inStrRev(oResult.name, ".")-1)& ": " & Richtung,i)
data.Root.ChannelGroups(left(oResult.name, inStrRev(oResult.name, ".")-1)& ": " & Richtung).Activate
dim group : set group = root.Children(Richtung)
for m=0 to ubound (KanalGeschFahr)
if group.Children.Exists(KanalGeschFahr(m)) then
'navigator.LoadData group.Children(KanalGeschFahr(m)), "Load" , nothing
call DataFileLoadSel(filenamePath, storeType, Richtung & "/" & KanalGeschFahr(m), "Load")
Call ChnPropSet(KanalGeschFahr(m),"unit_string", "km/h")
Call ChnPropSet(KanalGeschFahr(m),"name", "GeschwindigkeitFahrzeug")
exit for
end if
next
for m=0 to ubound (KanalBeschleunigung)
if group.Children.Exists(KanalBeschleunigung(m)) then
call DataFileLoadSel(filenamePath, storeType, Richtung & "/" & KanalBeschleunigung(m), "Load")
Call ChnPropSet(KanalBeschleunigung(m),"unit_string", "m/s")
Call ChnPropSet(KanalBeschleunigung(m),"name", "Beschleunigung")
exit for
end if
next
.
.
.
if cno(left(oResult.name, inStrRev(oResult.name, ".")-1)& ": " & Richtung & "/GeschwindigkeitFahrzeug") = 0 _
and cno(left(oResult.name, inStrRev(oResult.name, ".")-1)& ": " & Richtung & "/Beschleunigung") = 0 _
.
.
. then
Messung="1"
else
Messung="0"
end if
else
Messung="1"
end if
end function
Is that code okay in your opinion?
To your last question about the loading by DataFileLoadSel and the channel loaded using the datastore API:
The channels in the file out of the measurement are chanels in wave form. When I'm using the DataFileLoadSel the loaded channel is also in wave form, otherwise I use the channel loaded using the datastore API I get channels loaded in numeric form. I hope this is explained right. Here is also a picture where you probably see what I mean. The marked channels.
09-30-2014 05:31 AM
First I want to add a datafinder example which I think might solve your issue with less code:
option explicit dim filenamePath : fileNamePath = "C:\Users\Public\Documents\National Instruments\DIAdem 2012\Data\Example.tdm" dim targetGroupName : targetGroupName = Right(filenamePath, (len(filenamePath) - inStrRev(filenamePath, "\"))) dim targetGroup : set targetGroup = data.Root.ChannelGroups.Add(targetGroupName) ' create a target group call targetGroup.Activate() ' set this group as target for load events '--- Search without GUI Dim oMyDataFinder, oMyQuery, oMyResults Set oMyDataFinder = Navigator.ConnectDataFinder("My DataFinder") Set oMyQuery = oMyDataFinder.CreateQuery(eAdvancedQuery) oMyQuery.ReturnType = eSearchChannel Set oMyConditions = oMyQuery.Conditions Dim oMyConditions '--- Fill the query Call oMyConditions.Add(eSearchFile,"fullpath","=",fileNamePath) Call oMyConditions.Add(eSearchChannelGroup,"name","=","Noise data") Call oMyConditions.Add(eSearchChannel,"name","=",Array("Noise_1", "Schall_1", "Noise_2", "NotContained")) oMyConditions.Logic = "C1 AND C2 AND C3" '--- Search without GUI Call oMyDataFinder.Search(oMyQuery) Set oMyResults = oMyDataFinder.Results if oMyResults.Count > 0 then call navigator.LoadData(oMyResults, "Load", nothing) end if
The different names are just part of the query. They are used as an array.
Second I extend the datastore example to load meta data which will also import the waveform properties.
Option Explicit dim filenamePath : fileNamePath = "C:\Users\Public\Documents\National Instruments\DIAdem 2012\Data\Example.tdm" dim storeType : storeType = UCase(Right(filenamePath, (len(filenamePath) - inStrRev(filenamePath, ".")))) dim targetGroupName : targetGroupName = Right(filenamePath, (len(filenamePath) - inStrRev(filenamePath, "\"))) ' open the file Readonly, storetype must be TDM or TDMS dim store : set store = navigator.ConnectDataStoreByParameter(storeType, "<filename readonly=""yes"">" & replace(filenamePath, "&", "&") & "</filename>") ' we want to load meta data also. So we craete a load configuration dim loadconfig : set loadconfig = navigator.Settings.CreatePropertyImportSet(store) Call loadconfig.Properties.Add("tdm_channel","<InstanceProperties>") ' also add all custom properties dim root : set root = store.RootElements(1) ' tdm datastores do always have exactly one root dim group : set group = root.Children("Noise data") ' get the group by name dim targetGroup : set targetGroup = data.Root.ChannelGroups.Add(targetGroupName) ' create a target group call targetGroup.Activate() ' set this group as target for load events dim sourceChannel : set sourceChannel = nothing if group.Children.Exists("Noise_1") then set sourceChannel = group.Children("Noise_1") elseif group.Children.Exists("Revs") then set sourceChannel = group.Children("Revs") end if call navigator.LoadData(sourceChannel, "Load" , loadconfig) call store.Close() ' closes the access to the file. Will happen automatically if script finishes
In both cases the result of LoadData can be used to do post processing steps.
09-30-2014 06:52 AM
Thanks a lot!