楼主: 
KSJ (阿真)   
2013-12-22 04:44:39※ 引述《captdavince (走自己的路)》之铭言:
: 各位好
: 此文文长含程式码
: 小弟我是新手,因为目前实验上的需求急于生出一个可以收data做数据处理的GUI
: 所以就使用PyQT跟matplotlib, numpy, scipy来做
: 我自认自己逻辑、coding什么都不好,需要的功能多少借网络上的一些范例兜起来了
: 描述一下我的实验系统
: 我是用Mightex 的线性CCD module TCN1034-U,原厂有附SDK(dll)..但是我不知道要怎
: 么使用DLL..但是它另外也可以有USB protocol去做data的传输
: 因为看到Github上国外有人已经把它的USB protocol写好一个script来call..
: 所以这个方式我权衡一下是对我比较简单的..只是目前看起来只能在linux上才顺利的
: 抓到这个CCD
: http://www.mightexsystems.com/images/File/ccd_line_camera_software_package.zip
: 这个是原厂的程式
: 包含一个稍完整的控制程式,但是不够我的实验使用
: 另外SDK中有各式的dll与examples和SDK的说明文件
: https://github.com/bgamari/mightex-line-ccd
: 这个是国外的先进在Github上面写好的script,camera.py
: 我先描述一下我的问题.
: 是利用一个read_frame()去读取CCD的data(会是3648的1D array)
: 后面再做后续的
: 目前的read_frame()是如下
: def read_frame(self):
:   try: frame = self.ccd.get_frame()  #self.ccd是前面initialize过的camera.py
:   except: return None
:   if frame is not None:
:     return frame.image - np.mean(frame.dark)
:   else:
:     return None
  这个read_frame函式  的回传值
  可以是 None 或是 "有用的值"
  但是下面的函式在使用时  并没有做判断
: 这个部份的live数据的读取会是 (我是用一个100ms的counter,到时后就call下面)
: def updateposition(self):
:   self.ccd.set_exposure_time(self.ui.ExpSlide.value()) #把快门设成使用者所要的
:   self.data = self.read_frame() #读取data
:   x = np.arange(len(self.data)) #取得data长度
    读取后就直接用了??  是None怎么辨??
:   self.currentview.plot(x, self.data) #用matplotlib widget plot出来
:   self.currentcanvas.draw()
: 不过后面还有单次读取data的时候用的也是类似的方式
: 设快门后,用read_frame()读data
: 我利用print(frame)的方式来看读取得顺不顺利
: 目前看起来是使用者的快门设超过300ms之后就可能会拿到None..
  另外还有一个问题是 这个None是从哪来的??
  是从try来  还是后面的if判断式??
  虽然结果不影响  但是无法判定程式出错的地方在哪里
  观念上还蛮可怕的
: read_frame()不会等到取得ccd的data就会先feed None
: 在后面需要单次读取data的时候就会造成
:   File "project.py", line 206, in acqpos
:     a = np.arange(len(self.posframe))
: TypeError: object of type 'NoneType' has no len()
: 的错误
  这是因为你每100ms 就去抓一次frame
  可是exposure time (似乎是指多久会产生一张frame??)
  在大于100ms时  理论上是抓不到frame的(还没产生
  (当然还要加上一点其它程式码运行的时间)
: 这个部份是我真的一点头绪都没有不知道该怎么解决的部份
: 希望各位先进可以帮帮我是不是有简单的fix,像是改写read_frame()里try的判断
: 式内容,还是难道要连原本国外的那个script里都需要改写呢?
   原则上你可以更改counter的更新时间
   跟exposure time相同即可
   不过我看了一下github的if __name__ == __main_:底下的程式码
   while True:
        time.sleep(1e-2)
        count = c.get_buffered_frames_count()
        if count == 0: continue
        c._prepare_frames(1)
        frame = c._read_frames(1)
        print frame.timestamp, frame.dark
  似乎有 get_buffered_frames_count() 这个方法去看frame产生了没
  你也可以直接看看ccd的get_frame 它是怎么实作的
  也有用到get_buffered_frames_count哦~
: 是不是应该要写得让他会等CCD的方式,因为CCD的exposure是0.1ms~6500ms
: 我会希望可以取得6500ms的data
  能是最好  不过用while ccd.get_frame()也不为过
  不过因为你是用ui
  while ccd.get_frame 在 exposure time 较大时
  可能造成你ui画面的freeze哦~(像当机一样)
  但先别急  把问题一个一个解决吧
: 因为后面的function有部份是希望依使用者设定取得x次特定快门时间的data把它加起来
: (这个部份我还有点问题就是用
: for i in range(1, step+1):
:   self.ccd.set_exposure_time(self.ui.ExpSpin.value())
:   self.postframe = self.read_frame()
:   self.accum += self.posframe
: 其实在这个step>100的时候很容易当掉..改用while loop会比较不容易当掉吗?
  可否说明何为当掉??  (是加到None吗??)
  另外  你的x是指step吗?? (在程式里很怕看到不知从何而来的变量)
  改用while loop 会不会比较不容易当掉  这个你应该可以自己先试试的说 :)
  小建议  set_exposure_time 如果没有即时随ui里的值变动的话
  可以不用放进for里  以减少程式的负担
: 感谢各位看完这么长的内容
: 希望我有把我的问题描述清楚
: 谢谢各位大德
  加油
  本人不是很懂ccd  有什么误解还是方向错误
  还请一拼指正