問題なく約1年間使用されているPythonコードがあります(データの読み取り、解凍/解凍、ウィンドウの選択、Numpy/Matplotplibを使用したプロット)。
最近、実際の問題ではない 32 ビット エンコーディングではなく、64 ビット エンコーディング形式でデータを格納する新しいマシンを入手しました。これに対処するためにコードを数行書き直しましたが (関心のある両方の関数を以下に示します)、よく理解できないエラーが発生し続けます。
エラー:
Traceback (most recent call last):
File "./3D_Visualizer.py", line 238, in <module>
File "./3D_Visualizer.py", line 232, in main
main()
File "./3D_Visualizer.py", line 93, in plot_data
ax.set_ylabel('Time (s)',color='r')
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 170, in reshape
return _wrapit(a, 'reshape', newshape, order=order)
File "/usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.py", line 37, in _wrapit
result = getattr(asarray(obj),method)(*args, **kwds)
ValueError: total size of new array must be unchanged
numpy reshape 関数が実際のサイズ変更のために入力配列のサイズを取ることを理解しているので、このエラーが発生する理由を誰かが私に説明できれば幸いです。このエラーの原因となった 2 つの関数のコードを以下に示します。
読み取り機能:
def numpy_array(data, peaks):
"""Fills the NumPy array 'data' with m/z-intensity values acquired
from b64 decoding and unpacking the binary string read from the
mzXML file, which is stored in the list 'peaks'.
The m/z values are assumed to be ordered without validating this
assumption.
Note: This function is the performance bottleneck
"""
rt_counter=0
for x in peaks:
if rt_counter %(len(peaks)/20) == 0:
update_progress()
peak_counter=0
data_buff=base64.b64decode(x)
endian = '!'
precision = 'd'
buff_size = len(data_buff) / struct.calcsize(endian + precision)
index=0
for y in struct.unpack(endian + precision * buff_size, data_buff[0:len(data_buff)]):
if (index % 2 == 0):
data[rt_counter][1][peak_counter][0]= y
else:
data[rt_counter][1][peak_counter][1]= y
peak_counter+=1
index+=1
rt_counter+=1
プロット機能:
def plot_data(X,Y,Z):
"""Plots a 3D wireframe based on the x, y and z datapoints passed
to this function in the python lists 'X', 'Y' and 'Z'. Custom
labels are created for the Y (m/z) axis since matplotlib creates
'ugly' labels by default (TODO: labelling goes wrong).
"""
fig=plt.figure()
x=sorted(set(X))
y=sorted(set(Y))
labels=['%.2f'%k for k in y]
XX,YY=np.meshgrid(y,x)
ZZ=np.reshape(Z,XX.shape)
ax=fig.add_subplot(111,projection='3d')
ax.plot_wireframe(XX,YY,ZZ)
ax.set_title('3D projection of LC-MS region',size='large',color='r')
ax.set_xlabel('m/z',color='r',style='italic')
ax.set_xticklabels(labels)
ax.set_ylabel('Time (s)',color='r')
ax.set_zlabel('Intensity',color='r')
plt.show()
-- 30/07/13 2:10 --
このエラーをスローするテスト ケースでは、X、Y、および Z はすべて同じ長さ (つまり 184) です。x と y の長さはset
、エラー テスト ケースの行の後ではそれぞれ 18 と 20 ですset
が、動作中のテスト ケースでは行の後では 18 と 11 でした。
エラーの場合の内容の例y
(64 ビット エンコード):
[1398.51513671875, 1398.5152587890625, 1398.5225830078125, 1398.522705078125, 1398.530029296875, 1398.5301513671875, 1398.5374755859375, 1398.53759765625, 1398.5447998046875, 1398.544921875, 1398.55224609375, 1398.5523681640625, 1398.5596923828125, 1398.559814453125, 1398.567138671875, 1398.5672607421875, 1398.5745849609375, 1398.5819091796875, 1398.58203125, 1398.58935546875]
作業ケースでの「y」の内容の例 (32 ビットエンコード):
[1398.51171875, 1398.5191650390625, 1398.526611328125, 1398.533935546875, 1398.5413818359375, 1398.548828125, 1398.5562744140625, 1398.5635986328125, 1398.571044921875, 1398.5784912109375, 1398.5859375]
これは、エラーの場合、デコードに値のフィッティングに関する問題があることを示しています。
-- 31/07/13 10:20 --
実際のマシンから取得した生データに戻って調べたところ、測定座標がすべての時点で同じではないことがわかりました (マシン + 制御ソフトウェアのすべての以前のバージョンの場合)。これにより、特定の座標が少しだけシフトされ (つまり、1398.5152... vs 1398.5151)、形状変更が失敗するという効果があります。
現在、各座標を整数値(1、2 ...)に割り当てて、これを「ホットフィックス」する作業を行っています。