1

I have a hdf5 file containing some numbers in an attribute like this:

1.0:2.0,2.0:3.0,3.0:4.0

(More precisely the exact attribute:

ATTRIBUTE "azangles" {
            DATATYPE  H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
            DATASPACE  SCALAR
            DATA {
            (0): "81.1615:82.76,82.2382:83.8202,83.2983:84.9133,84.375:86.0175,85.4736:87.1545,86.5997:88.2697,87.7258:89.4012,88.83:90.5164,89.989:91.5985,91.0602:92.6752,92.1533:93.7408,93.2025:94.8175,94.2957:95.8777,95.3448:96.9653,96.427:98.053,97.5146:99.1901,98.6298:100.289,99.7504:101.404,100.849:102.53,101.981:103.629,103.079:104.711,104.178:105.782,105.266:106.88,106.337:107.974,107.441:109.072,108.528:110.193,109.644:111.313,110.753:112.467,111.901:113.577,113.033:114.686,114.142:115.79,115.269:116.878,116.34:117.944,117.427:119.004,118.471:120.097,119.564:121.179,120.641:122.294,121.75:123.371,122.838:124.519,123.959:125.623,125.09:126.738,126.183:127.82,127.299:128.908,128.375:129.996,129.457:131.05,130.523:132.144,131.6:133.248,132.709:134.352,133.808:135.467,134.923:136.588,136.033:137.703,137.164:138.801,138.263:139.894,139.356:140.96,140.444:142.042,141.509:143.091,142.581:144.168,143.63:145.261,144.728:146.354,145.811:147.491,146.937:148.568,148.046:149.711,149.161:150.793,150.266:151.886,151.353:152.952,152.446:154.028,153.495:155.11,154.589:156.171,155.649:157.264,156.731:158.373,157.83:159.505,158.95:160.609,160.065:161.724,161.18:162.823,162.285:163.905,163.361:164.938,164.432:165.948,165.454:166.992,166.476:168.014,167.531:169.036,168.53:170.096,169.579:171.129,170.623:172.205,171.672:173.243,172.744:174.287,173.76:175.342,174.825:176.369,175.864:177.413,176.907:178.407,177.913:179.451,178.929:180.478,179.984:181.538,181.016:182.631,182.098:183.702,183.17:184.801,184.268:185.861,185.356:186.949,186.422:187.987,187.487:189.047,188.52:190.069,189.575:191.096,190.585:192.14,191.64:193.2,192.689:194.277,193.749:195.342,194.821:196.397,195.881:197.485,196.952:198.523,198.018:199.572,199.061:200.605,200.11:201.616,201.11:202.643,202.143:203.632,203.143:204.675,204.159:205.714,205.208:206.796,206.246:207.861,207.339:208.927,208.394:210.02,209.487:211.042,210.531:212.102,211.586:213.102,212.624:214.124,213.607:215.129,214.634:216.14,215.634:217.183,216.672:218.216,217.7:219.298,218.771:220.364,219.842:221.413,220.897:222.462,221.94:223.511,223.006:224.55,224.033:225.549,225.06:226.555,226.055:227.609,227.098:228.615,228.115:229.669,229.147:230.729,230.219:231.812,231.273:232.888,232.361:233.937,233.421:235.009,234.481:236.025,235.525:237.052,236.547:238.052,237.568:239.068,238.568:240.101,239.601:241.122,240.617:242.199,241.677:243.248,242.743:244.325,243.787:245.413,244.885:246.462,245.934:247.495,246.984:248.522,248.022:249.549,249.044:250.543,250.06:251.554,251.054:252.587,252.076:253.619,253.098:254.658,254.141:255.701,255.19:256.778,256.245:257.855,257.327:258.898,258.387:259.942,259.426:260.953,260.458:261.996,261.48:263.024,262.524:264.045,263.546:265.1,264.6:266.144,265.627:267.242,266.699:268.297,267.781:269.379,268.841:270.456,269.94:271.489,270.983:272.527,272.021:273.543,273.038:274.565,274.065:275.548,275.059:276.575,276.07:277.614,277.108:278.646,278.124:279.712,279.185:280.767,280.25:281.816,281.299:282.87,282.349:283.909,283.403:284.936,284.431:285.941,285.441:286.968,286.458:288.018,287.507:289.067,288.534:290.127,289.6:291.182,290.66:292.291,291.747:293.346,292.83:294.412,293.884:295.466,294.955:296.488,295.988:297.515,297.015:298.499,298.015:299.515,299.02:300.531,300.048:301.575,301.053:302.624,302.113:303.668,303.14:304.75,304.222:305.81,305.294:306.865,306.354:307.903,307.408:308.941,308.43:309.952,309.463:310.963,310.479:311.995,311.484:313.05,312.534:314.105,313.594:315.17,314.648:316.225,315.703:317.313,316.78:318.356,317.845:319.4,318.889:320.444,319.938:321.454,320.944:322.487,321.976:323.481,322.998:324.52,324.003:325.541,325.047:326.602,326.074:327.673,327.156:328.722,328.195:329.804,329.271:330.842,330.337:331.913,331.386:332.935,332.435:333.968,333.457:334.995,334.49:336.011,335.5:337.066,336.544:338.104,337.593:339.192,338.659:340.263,339.736:341.334,340.807:342.411,341.884:343.46,342.944:344.504,343.993:345.542,345.042:346.564,346.053:347.602,347.091:348.629,348.118:349.706,349.173:350.75,350.239:351.854,351.304:352.936,352.414:353.985,353.463:355.051,354.529:356.078,355.583:357.116,356.605:358.116,357.638:359.138,358.632:0.170288,359.67:1.18652,0.686646:2.25769,1.73584:3.31238,2.79602:4.40002,3.87817:5.4657,4.95483:6.53687,6.01501:7.58057,7.0697:8.61877,8.10242:9.65149,9.14612:10.6732,10.1788:11.7004,11.2006:12.7496,12.2443:13.7988,13.277:14.87,14.3427:15.9027,15.3864:16.9958,16.452:18.0615,17.5452:19.0887,18.5834:20.116,19.6106:21.1212,20.6268:22.1265,21.6321:23.1207,22.6483:24.1315,23.6316:25.1642,24.6643:26.1914,25.686:27.2626,26.7407:28.3008,27.7899:29.3829,28.8501:30.4376,29.9487:31.4868,30.965:32.525,32.0251:33.5248,33.0304:34.563,34.0576:35.5737,35.0739:36.6229,36.1176:37.6721,37.1558:38.7488,38.2104:39.8474,39.3146:40.8966,40.3912:41.9568,41.4349:43.0115,42.5006:44.0332,43.5333:45.0494,44.5551:46.0437,45.5493:47.0654,46.5656:48.0542,47.5763:49.0759,48.5651:50.1251,49.6143:51.1578,50.6525:52.229,51.7072:53.2837,52.7673:54.3384,53.822:55.3986,54.9042:56.4203,55.9149:57.4475,56.9476:58.4363,57.9529:59.491,58.9691:60.5182,60.0183:61.5894,61.062:62.6715,62.1552:63.7482,63.2098:64.8358,64.314:65.907,65.3961:66.9781,66.4563:68.0109,67.511:69.0436,68.5437:70.0488,69.5654:71.0431,70.5542:72.0648,71.5594:73.0865,72.5812:74.1357,73.6194:75.174,74.6686:76.2067,75.6958:77.2833,76.756:78.3215,77.8162:79.3652,78.8489:80.3925,79.8926:81.4197,80.9088:82.4634,81.958:83.4741,82.9688:84.5233,83.996:85.589,85.0671:86.6766,86.1328:87.7588,87.2314:88.8354,88.2971:89.9396,89.4067:90.9668,90.4724:92.0105,91.4996:93.0157,92.5323:94.0375,93.5376:95.0262,94.5428:96.026,95.5261:97.0367,96.5479:98.064,97.5696:99.1351,98.6023:100.184,99.6735:101.217,100.712:102.294,101.766:103.343,102.832:104.365,103.87:105.403"
            }
         }

)

so there is always a start number separated from an end number with :

The datatype is H5T_STRING.

I want to read the Strings, separate them at the : and then convert them to double. I tried this by using QString this way:

QString data[];
double start[];
double end[];

DataAttribute->read(*Datatype, &data);

for (i=0 ; i<LengthData ; i++) {

    QStringList parts = data[i].split(":");

    QString startstr = parts.first();
    QString Stopstr = parts.last();

    start[i]=startstr.toDouble();
    end[i]=Stopstr.toDouble();

}

But it seams that I don't read anything into my data - QString So is it possible to read QString from HDF5?

Or do you have another idea how I can manage this?

EDIT:

I found an example in C but I can't fix the problem in C++

Can someone tell my what the C++ expression for:

H5Tget_size(type)

is? With type an an H5::DataType of an H5 Attribute

Thanks!

EDIT2:

Trying to run the example from Timothy Brown:

I can step through the code BUT there is nothing read in in my string called r. I use std::string r and StrType str_type(PredType::C_S1, H5T_VARIABLE); Result is:

Name : r
    Details:""
    Default:""
    Decimal:""
    Hex:""
    Binary:""
    Octal:""
smaica
  • 723
  • 2
  • 11
  • 26
  • Im not familiar with C++ (so not with QString) and HDF5, but what happens when you make `data` a string, and then split? That you can check if `data` actually contains the `H5T_STRING` (as it should be) and locate the error – Mathias711 Apr 17 '14 at 08:12
  • I'm not quite sure how I can split the string in C++ without QString and the split() command. – smaica Apr 17 '14 at 08:30
  • Maybe you can do something like [this](http://www.cplusplus.com/reference/string/string/substr/) – Mathias711 Apr 17 '14 at 08:34
  • Sounds like a good idea, thank you! But now I have trouble reading a string in general from hdf5. Its a String with variable length so I can't so it like this: [link] (http://stackoverflow.com/questions/13814027/reading-a-string-from-hdf5-in-c) – smaica Apr 17 '14 at 08:54
  • I think something like `getSpace()` or `getStorageSize()` from [here](http://www.hdfgroup.org/HDF5/doc/cpplus_RM/classH5_1_1Attribute.html) should work, or is that only for lists? – Mathias711 Apr 17 '14 at 09:05
  • I thought that would mean the bits and bytes for the whole attribute but this does not tell me how long a single entry is in it – smaica Apr 17 '14 at 09:17
  • You're right. I always use the size (but in Python/C) to determine the amount of entries. I am not working with text in HDF5. What if you create an empty string which is longer than the attribute? If the attribute consist of `n` chars, the first `n` chars of the string should be written to the empty string, and after that you can determine how many chars there have been written. – Mathias711 Apr 17 '14 at 09:22
  • I tried to do this but it does not read the exact values to the first positions. Don't know why. – smaica Apr 17 '14 at 09:28
  • That's very strange. No idea at the moment to resolve it then. Cant you create multiple attributes with the doubles as value, instead of putting them all in one string? Sorry for not giving a clear answer :/ – Mathias711 Apr 17 '14 at 09:31
  • The data is created by someone else, very huge files. I just use it ): – smaica Apr 17 '14 at 10:09
  • Maybe you can ask him/her how he reads out the attribute? – Mathias711 Apr 17 '14 at 10:13

1 Answers1

2

I am unfamiliar with QString (and C++ for that matter!). However this could be one way that you can tackle it.

Lets create a program to write the test attribute in a file called string.h5. Note that you can use either H5std_string or std::string.

#include <iostream>
#include <string>
#ifndef H5_NO_NAMESPACE
#ifndef H5_NO_STD
using std::cout;
using std::endl;
#endif // H5_NO_STD
#endif
#include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE
using namespace H5;
#endif

const H5std_string FILE_NAME ("string.h5");
const H5std_string ATT_NAME("test");

int main (void)
{

        H5std_string test("1.0:2.0,2.0:3.0,3.0:4.0");
        /* std::string test = "1.0:2.0,2.0:3.0,3.0:4.0"; */

        H5File *file = new H5File(FILE_NAME, H5F_ACC_TRUNC);

        DataSpace att_space(H5S_SCALAR);
        StrType str_type(PredType::C_S1, H5T_VARIABLE);
        Attribute *att = new Attribute(file->createAttribute(ATT_NAME,
                                str_type, att_space));
        att->write(str_type, test);

        att->close();
        delete att;
        file->close();
        delete file;

        return 0;

}

Compile and run the program:

$h5c++ -o att_w att_w.cpp && ./att_w

Look at the file to check that the attribute is there:

$ h5dump string.h5
HDF5 "string.h5" {
GROUP "/" {
   ATTRIBUTE "test" {
      DATATYPE  H5T_STRING {
         STRSIZE H5T_VARIABLE;
         STRPAD H5T_STR_NULLTERM;
         CSET H5T_CSET_ASCII;
         CTYPE H5T_C_S1;
      }
      DATASPACE  SCALAR
      DATA {
      (0): "1.0:2.0,2.0:3.0,3.0:4.0"
      }
   }
}
}

Now lets try and read the string attribute in and parse it into the start and end vectors.

#include <iostream>
#include <string>
#include <vector>
#ifndef H5_NO_NAMESPACE
#ifndef H5_NO_STD
using std::cout;
using std::endl;
#endif // H5_NO_STD
#endif
#include "H5Cpp.h"
#ifndef H5_NO_NAMESPACE
using namespace H5;
#endif

const H5std_string FILE_NAME ("string.h5");
const H5std_string ATT_NAME("test");

int main (void)
{

    size_t pos = 0;
    size_t sz  = 0;
    std::string r;
    std::string delimiter = ",";
    std::string token;
    std::vector<double> start;
    std::vector<double> end;
    std::vector<double>::iterator it;

    H5File    *file = new H5File(FILE_NAME, H5F_ACC_RDONLY);
    Attribute *att  = new Attribute(file->openAttribute(ATT_NAME));

    StrType str_type(PredType::C_S1, H5T_VARIABLE);

    att->read(str_type, r);
    /* cout << r << endl; */

    while ((pos = r.find(delimiter)) != std::string::npos) {
        token = r.substr(0, pos);
        start.push_back(std::stod(token, &sz));
        end.push_back(std::stod(token.substr(sz+1)));
        r.erase(0, pos + delimiter.length());
    }
    start.push_back(std::stod(r, &sz));
    end.push_back(std::stod(r.substr(sz+1)));

    att->close();
    delete att;
    file->close();
    delete file;

    return 0;

}

Hope this helps you out.

Timothy Brown
  • 2,220
  • 18
  • 22
  • Hey, thanks for your help and sorry for answering so late! I tried to run your example with my Problem but I got an error message (see edits in the question) – smaica Apr 23 '14 at 07:32
  • To be more precisely, maybe it helps, I added the exact contents of the attribute I want to read. – smaica Apr 23 '14 at 09:28
  • Oh - your example works! I'm sorry. I wrote a "&" in front of the r. Tanks alot! One thing does not work: I cant use std::stod with my data?! – smaica Apr 23 '14 at 11:25
  • Okay, seams to be a compiler-problem: http://stackoverflow.com/questions/20145488/cygwin-g-stdstoi-error-stoi-is-not-a-member-of-std – smaica Apr 23 '14 at 11:34