Message Boards Message Boards

0
|
14918 Views
|
11 Replies
|
1 Total Likes
View groups...
Share
Share this post:
GROUPS:

How can I import this unsupported "Touchstone" file format?

Posted 10 years ago

I'm trying to read a file which is in "Touchstone" format. In at least the version of Mathematica I am using (7), the Import[] command does not know about Touchstone format files. This is used by electronics engineers. A typical file is this. ! This is a Touchstone .s1p format file ! HEWLETT PACKARD,8720D,0,7.74 ! Date = 8 Jan 2015 ! Time = 23:00:59 ! Start frequency = 0.050000000 GHz ! Stop frequency = 20.049999872 GHz ! Port extensions = OFF ! Port extension 1 = 0.000000 ps ! Port extension 2 = 0.000000 ps # MHz S DB R 50 50.00000 0.07349 179.64844 62.50000 -0.00239 179.21094

It contains 3 types of lines

1) Those that begin with an exclamation mark (!) are comments, and for the moment at least I am going to ignore them.

2) The line beginning with a hash character (#) contains information about the format of the numerical data in the rest of the file. Again I can ignore that for now, as all mine are in the same format.

3) The numerical values, which are in the form of frequency in the first column, an amplitude in the second column and a phase in the third column.

I've taken to pre-processing the file in a Unix shell script to remove the things I don't want, and to add some commas to make it a comma separated list, so Mathematica can handle it. That is incredibly simple on Unix using the "awk" and "grep" tools.

grep -v "#" | grep -v \! | awk '{print $1,",",$2,",",$3}'

so I get an output like

50.00000 , 0.07349 , 179.64844 62.50000 , -0.00239 , 179.21094

Then I can use Import[], and do things with the data.

But rather than pre-process the file on a Unix system, which would obviously break if I used Mathematica on Windows, I'd like Mathematica to strip out all the irrelevant things, before putting the data in a list.

POSTED BY: David Kirkby
11 Replies

Hi, David, THANKS A LOT for the kind assistance ! As soon as I come back from vacation at sea, I will put in operation your notebook, but I have no doubt that you solved my problem. :-) I will post again in case I will make some additional discover/improvement to the code. Best regards

POSTED BY: Enrico Calandra
Posted 1 year ago

Hello Enrico,

I don't know how to find any of the attachments, however I found a sample S2P file here. I used the first file in their list. I attach a notebook which reads this file and extracts the s parameter data. I could not attach the file I used since both s2p and zip are not allowed as attachments.

Kind regards, David

Attachments:
POSTED BY: David Keith

I do not know if it's related to the long time elapsed from above posts, but I do not see any attachment ... attached. If some one is reading this message and has at his disposal the missing attachment(s), I'd be gratefully indebted if he can share with the community. Personally, I have the same import problem (of a Touchstone S2P file), and having at my disposal the code developed by the above fellow members would be very useful.

POSTED BY: Enrico Calandra
Posted 4 years ago

I've been working with files of the touchstone format. When I was surfing for related resources, I found this post. I wrote an import function for the touchstone files of 1.0 version as follows. I hope it can help someone who searches for it.

readsnp[filename_] /; 
  StringContainsQ[filename, ".s" ~~ NumberString ~~ "p"] :=
 Module[{raw, format, complex, nports, sparameters},
  raw = Import[filename, "Table"];
  (*The option line is formatted as: # <frequency unit> <parameter> <
  format> R <n>.*)
  format = Cases[raw, {"#", __}][[1, 4]];
  (*DB for dB-angle(dB=20*lg|magnitude|), MA for magnitude-angle, 
  RI for real-imaginary. Angles are given in degrees.*)
  complex[a_, b_] := 
   Switch[format, "MA", a E^(I \[Pi] b/180), "RI", a + I b, "DB", 
    10^(a/20) E^(I \[Pi] b/180)];
  nports = 
   StringCases[filename, ".s" ~~ n : NumberString ~~ "p" :> n][[1]] //
     FromDigits;
  sparameters = Which[
    nports == 1, 
    Cases[raw, {freq : (_Real | _Integer), 
       s : Repeated[_Real, {2}]} :> {freq, complex@s}],
    (*S-parameters are listed in the order S11, S21, S12, and S22.*)
    nports == 2, 
    Cases[raw, {freq : (_Real | _Integer), 
       s : Repeated[_Real, {8}]} :> {freq, 
       Transpose@Partition[complex @@@ Partition[{s}, 2], 2]}],
    (*The content per line is limited to 4 pairs of parameter data.*)  
    nports > 2,
    SequenceCases[
     raw, {{freq : (_Real | _Integer), sline1 : Repeated[_Real, {8}]},
        srem : Repeated[_List, {Ceiling[nports/4] nports - 
           1}]} :> {freq, 
       Partition[complex @@@ Partition[Flatten@{sline1, srem}, 2], 
        nports]}]
    ]
  ]
POSTED BY: Chi Zhang
Posted 10 years ago

For attaching, you might try changing the file extension to ".txt" -- the specification "Table" in the Import function will interpret the file as a table no matter the extension, so code that works with the text file will also work with ".s1p". Also you might look at lower level input functions, especially ReadList with the option RecordLists->True.

--David

Edit: I've attached a short notebook. It's in version 10 -- which I highly recommend -- but I think the functionality in use was available much earlier.

Attachments:
POSTED BY: David Keith
Posted 10 years ago

Thank you Isaac. That is quite clear with the verbose presentation. I might be able to make snippets of it available.

FWIW, the line beginning with a hash is not a comment in a Touchstone file - it must have one, and only one of those lines. I realize that point is nothing to do with the solution though.

Dave

POSTED BY: David Kirkby
Posted 10 years ago

Thank you David. That done the trick. I did try to attach the file twice, but gave up in the end.

1) I tried to attach it with the correct extension (.s1p). That failed as the uploader did not support the file type.

2) I compressed the file and put it in a zip file. Again I got some message about an unsupported file type.

At that point I gave up!

POSTED BY: David Kirkby

I wish to attach my second attempt which will read in the textual touchstone file.

  1. strips out "!" and "#" as comment lines (expandable to other comment characters)
  2. accomodates an arbitrary number of comments,
  3. leaves behind the numeric data with any number of rows and columns.
  4. No check is done (yet) for any imaginary or missing data like "none" or blanks.

The code can certainly be compressed for brevity. I hope to have made the algorithm readable with the verbose presentation. Thank you.

Attachments:
POSTED BY: Isaac Abraham
Posted 10 years ago

You could select all lines which contain 3 numbers. I also copied your data as shown, with white space as word separators and newlines as record separators. The code below imports the data then selects lines which contain exactly 3 Reals.

In[16]:= SetDirectory[NotebookDirectory[]];

In[17]:= dataAll = Import["touchstone.txt", "Table"] // N;

In[18]:= dataNum = Cases[dataAll, {_Real, _Real, _Real}]

Out[18]= {{50., 0.07349, 179.648}, {62.5, -0.00239, 179.211}}

(For future reference, it would be useful to attach a sample data file to such questions.)

Kind regards,

David

Edit: The code shown assumes the data file is in the same directory as the notebook. It also assumes no pre-processing.

Attachments:
POSTED BY: David Keith
Posted 10 years ago

Thank you. The problem with that is that there can be an arbitrary number of comment lines. Also there can be an arbitrary number of data lines. So relying on the data being on lines 11 and 12 is not possible.

POSTED BY: David Kirkby

I copied your data file into a "touchstone.txt", and the following sequence produces a usable list-of-(numeric)lists.

(*Import the data from $HomeDirectory/touchstone.txt*)
dataAll = Import["touchstone.txt", "CSV"];

(* From the simple example, we can tell by visual inspection that the \
numbers are in lines 11 and 12. Extract them. *)
dataNum = Take[dataAll, {11, 12}]

The numbers however come up with no commas in between them as follows. We need to post-process.

{{"50.00000 0.07349 179.64844"}, {"62.50000 -0.00239 179.21094"}}

(*Add commas in between the numbers to create a usable list-of-lists \
and convert the numbers back into expressions rather than the strings \
that were read-in. *)
dataList = ToExpression[Flatten[StringSplit[#, " "] & /@ dataNum, 1]]

The result is,

{{50., 0.07349, 179.648}, {62.5, -0.00239, 179.211}}

Check to see if the numbers are real numbers or still strings by taking one and multiplying it.

In[42]:= {dataList[[1, 2]], dataList[[1, 2]]*2}

Out[42]= {0.07349, 0.14698}

The output is a list-of-(numeric)lists as desired.

POSTED BY: Isaac Abraham
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract