CMeasure.cs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. using System.Collections.Generic;
  2. using OTSDataType;
  3. using System;
  4. using System.Drawing;
  5. using static OTSDataType.otsdataconst;
  6. using OTSModelSharp.ImageProcess;
  7. using OTSModelSharp.ServiceInterface;
  8. using System.Threading;
  9. namespace OTSModelSharp
  10. {
  11. // enum and struct used for send message to App
  12. public enum ENUM_MSG_TYPE
  13. {
  14. MTHREADSTATUS = 1001,
  15. MSAMPLESTATUS = 1002,
  16. MSAMPLERESULT = 1003
  17. };
  18. public enum MSAMPLE_RET
  19. {
  20. BSE_DATA = 0,
  21. FIELD_DATA = 1,
  22. START_MSR_FIELD = 2
  23. };
  24. public struct SMSR_COMPLETE_DATA
  25. {
  26. public OTS_MSR_THREAD_STATUS MsrStatus;
  27. public string csMsrStartTime;
  28. public int iMsrCompleteSampleCount;
  29. public int iMsrCompleteFieldCount;
  30. public int iParticleCount;
  31. public TimeSpan MsrUsedTime;
  32. public string csMsrEndTime;
  33. };
  34. public struct STMThreadStatus
  35. {
  36. public OTS_MSR_THREAD_STATUS iMsrStatu; //OTS_MSR_THREAD_STATUS
  37. public string csMsrStartTime; //MSR_START_TIME
  38. public string csMsrEndTime; //MSR_END_TIME
  39. public SMSR_COMPLETE_DATA SMsrCompleteData;
  40. };
  41. public struct STMSampleStatus
  42. {
  43. public OTS_MSR_SAMPLE_STATUS iMsrSampleStatu; //OTS_MSR_SAMPLE_STATUS
  44. public string cSampleName;
  45. public string csSampleMsrStartTime;
  46. public List<PointF> BCompleteFieldList;
  47. };
  48. public struct STMSampleResultData
  49. {
  50. public MSAMPLE_RET iRetDataType; //ENUM_MEASURE_SAMPLE_RESULT
  51. public struct RBSEDATA
  52. {
  53. public System.Drawing.Point pos;
  54. public int iBSEDataHeight;
  55. public int iBSEDataWidth;
  56. public byte[] lpBSEData;
  57. };
  58. public struct SAMPLEFIELDDATA
  59. {
  60. public System.Drawing.Point FieldPos;
  61. public int iMeasureFieldCount;
  62. public int iCompleteFieldCount;
  63. public int iSParticleCount; // Field particle count
  64. public TimeSpan TUsedTime;
  65. };
  66. public struct StartToMsrField
  67. {
  68. public System.Drawing.Point FieldPos;
  69. };
  70. public RBSEDATA BSEData;
  71. public SAMPLEFIELDDATA SFieldData;
  72. public StartToMsrField SMsrField;
  73. };
  74. public struct ST_MSTMsg
  75. {
  76. public ENUM_MSG_TYPE iMsgType;
  77. public STMThreadStatus STMThreadStu;
  78. public STMSampleStatus STMSampleStu;
  79. public STMSampleResultData STMSampleRetData;
  80. };
  81. public class CMeasure
  82. {
  83. private const string UNTITLED_FILE_NAME = "Untitled";
  84. public delegate void ProgressEventHandler(ST_MSTMsg msg);
  85. public event ProgressEventHandler ProgressEvent;
  86. COTSMsrPrjResultData m_pProjData;
  87. List< COTSSample> m_listMeasurableSamples=new List<COTSSample>();
  88. string m_strWorkingFolder;
  89. CMsrThreadStatus m_ThreadStatus;
  90. SemController m_SemController;// there is no correspondense clr,so use this instead temporarilly
  91. protected static NLog.Logger loger = NLog.LogManager.GetCurrentClassLogger();
  92. public SortedDictionary<string, CSmplMeasure> mapSmplMsr = new SortedDictionary<string, CSmplMeasure>();//use this map to hold all the smplMeasure object
  93. public List<COTSSample> GetListMeasurableSamples()
  94. {
  95. return m_listMeasurableSamples;
  96. }
  97. public void SetListMeasurableSamples(List<COTSSample> value)
  98. {
  99. m_listMeasurableSamples = value;
  100. }
  101. public CMeasure()
  102. {
  103. m_strWorkingFolder = "";
  104. m_ThreadStatus = new CMsrThreadStatus();
  105. m_SemController = SemController.GetSEMController();
  106. }
  107. public COTSMsrPrjResultData GetProjResultData()
  108. {
  109. return m_pProjData;
  110. }
  111. public ISemController GetSEMController()
  112. {
  113. // get SEM, scanner and x-ray controller via hardware manager
  114. return m_SemController;
  115. }
  116. public CMsrThreadStatus GetMsrThreadStatus() { return m_ThreadStatus; }
  117. public void Init(COTSMsrPrjResultData a_pProjMgrFile)
  118. {
  119. m_pProjData = a_pProjMgrFile;
  120. SetListMeasurableSamples(a_pProjMgrFile.GetSampleList());
  121. return ;
  122. }
  123. void ThreadOver()
  124. {
  125. DateTime timeEnd = m_ThreadStatus.GetEndTime();
  126. ST_MSTMsg MsrMsg = new ST_MSTMsg();
  127. MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  128. MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
  129. MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
  130. ProgressEvent(MsrMsg);
  131. }
  132. void ThreadOverWithoutDisConnect()
  133. {
  134. DateTime timeEnd = m_ThreadStatus.GetEndTime();
  135. ST_MSTMsg MsrMsg = new ST_MSTMsg();
  136. MsrMsg.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  137. MsrMsg.STMThreadStu.iMsrStatu = m_ThreadStatus.GetStatus();
  138. MsrMsg.STMThreadStu.csMsrEndTime = timeEnd.ToString("yyyy-MM-dd HH:mm:ss");
  139. ProgressEvent(MsrMsg);
  140. }
  141. void SetWorkingFolderStrAndSaveCurrentSettings()
  142. {
  143. // get project file pathname
  144. string strSettingFilePathName = m_pProjData.GetPathName();
  145. strSettingFilePathName.Trim();
  146. if (strSettingFilePathName == "")
  147. {
  148. loger .Error("SetWorkingFolderStr: project file pathname is an empty string");
  149. return ;
  150. }
  151. else if (strSettingFilePathName==UNTITLED_FILE_NAME)
  152. {
  153. loger .Error ("SetWorkingFolderStr: project file pathname is an invalid string");
  154. return ;
  155. }
  156. // working folder string
  157. m_strWorkingFolder = FileHelper.GetFolderName(strSettingFilePathName);
  158. m_pProjData.Save();
  159. return ;
  160. }
  161. public void SendMessageToMeasureApp(ST_MSTMsg msg)
  162. {
  163. ProgressEvent(msg);
  164. }
  165. public bool IsMeasureStopped()
  166. {
  167. return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED;
  168. }
  169. public bool IsMeasureRunning() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.INPROCESS; }
  170. public bool IsMeasureFailed() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.FAILED; }
  171. public bool IsMeasureCompleted() { return m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.COMPLETED; }
  172. public void DoMeasure()
  173. {
  174. // start measurement, creat thread measure status class, let the main thread know that measurement started
  175. m_ThreadStatus.SetStartTime(System.DateTime.Now);
  176. DateTime timeStart = m_ThreadStatus.GetStartTime();
  177. ST_MSTMsg MsgMsrStart=new ST_MSTMsg();
  178. MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  179. MsgMsrStart.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.INPROCESS;
  180. MsgMsrStart.STMThreadStu.csMsrStartTime = timeStart.ToShortDateString();
  181. ProgressEvent (MsgMsrStart);
  182. loger.Info("Measurement started!");
  183. // connect hardware
  184. loger.Info("Connect SEM!");
  185. if (!m_SemController.Connect())
  186. {
  187. loger .Error("DoMeasure: failed to connect hardware.");
  188. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
  189. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  190. ThreadOver();
  191. return;
  192. }
  193. // set working directory which is the same directory of the setting file
  194. SetWorkingFolderStrAndSaveCurrentSettings();
  195. List <string > listMeasuredSamples = m_ThreadStatus.GetCompletedSamples();
  196. // got through measure list
  197. foreach (var pSample in GetListMeasurableSamples())
  198. {// check and break if stop button is clicked
  199. if (m_ThreadStatus.GetStatus()== OTS_MSR_THREAD_STATUS.STOPPED )
  200. {
  201. // stop button clicked
  202. loger .Info("DoMeasure: stop button is clicked.");
  203. // record end time
  204. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  205. ThreadOver();
  206. return;
  207. }
  208. if (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)
  209. {
  210. // stop button clicked
  211. loger.Info("DoMeasure: stop button is clicked.");
  212. // record end time
  213. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  214. while (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.PAUSED)
  215. {
  216. Thread.Sleep(300);
  217. }
  218. //return;
  219. }
  220. if (!pSample.GetSwitch())
  221. {
  222. continue;
  223. }
  224. var sta = pSample.GetMsrStatus().GetStatus();
  225. if (sta == OTS_MSR_SAMPLE_STATUS.SUCCESSED || sta == OTS_MSR_SAMPLE_STATUS.STOPPED)
  226. {
  227. continue;
  228. }
  229. CSmplMeasure pSmplMeasure;
  230. if (!mapSmplMsr.ContainsKey(pSample.GetName()))
  231. {// create a sample measure object for the sample
  232. switch (m_pProjData.m_nPackId)
  233. {
  234. case OTS_SysType_ID.IncA:
  235. pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  236. break;
  237. case OTS_SysType_ID.CleannessA:
  238. pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
  239. break;
  240. default:
  241. pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  242. break;
  243. }
  244. // set measure thread
  245. pSmplMeasure.SetMsrThread(this);
  246. mapSmplMsr[pSample.GetName()] = pSmplMeasure;
  247. }
  248. else
  249. {
  250. pSmplMeasure = mapSmplMsr[pSample.GetName()];
  251. pSample.GetMsrStatus().SetStatus(OTS_MSR_SAMPLE_STATUS.INPROCESS);
  252. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.INPROCESS);
  253. }
  254. pSmplMeasure.DoMeasureForOneSample();
  255. // check if measurement is successful
  256. if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.PAUSED)
  257. {// record end time
  258. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.PAUSED);
  259. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  260. // update thread measure status class, let the main thread know that this sample measurement stopped
  261. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  262. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  263. MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
  264. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.PAUSED;
  265. MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime.Now.ToShortDateString();
  266. MsgSmpStop.STMThreadStu.iMsrStatu = OTS_MSR_THREAD_STATUS.PAUSED;
  267. ProgressEvent(MsgSmpStop);
  268. ThreadOver();
  269. return;
  270. }else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
  271. {// record end time
  272. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.STOPPED);
  273. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  274. // update thread measure status class, let the main thread know that this sample measurement stopped
  275. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  276. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  277. MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
  278. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
  279. MsgSmpStop.STMThreadStu.csMsrEndTime = DateTime .Now .ToShortDateString();
  280. MsgSmpStop.STMThreadStu.iMsrStatu= OTS_MSR_THREAD_STATUS.STOPPED;
  281. ProgressEvent(MsgSmpStop);
  282. ThreadOver();
  283. break;
  284. }
  285. else if (pSample.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
  286. {
  287. // measurement failed
  288. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.FAILED);
  289. // record end time
  290. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  291. // update thread measure status class, let the main thread know that this sample measurement failed
  292. ST_MSTMsg MsgSmpFailed=new ST_MSTMsg();
  293. MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  294. MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
  295. ProgressEvent(MsgSmpFailed);
  296. ThreadOver();
  297. return;
  298. }
  299. // update thread measure status class, let the main thread know that this sample measurement successes
  300. ST_MSTMsg MsgSmpSuccess = new ST_MSTMsg();
  301. MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  302. MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
  303. ProgressEvent(MsgSmpSuccess);
  304. // continue to the next sample
  305. listMeasuredSamples.Add(pSample.GetName());
  306. }
  307. // measurement completed
  308. m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
  309. // record end time
  310. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  311. ThreadOver();
  312. }
  313. //public bool DoReMeasure(List<Particle> particles, int imgscanspeed_index, int xrayscanmode_index, int scantime_count)
  314. //{
  315. // // got through measure list
  316. // foreach (var pSample in m_listMeasurableSamples)
  317. // {
  318. // // check and break if stop button is clicked
  319. // if (m_ThreadStatus.GetStatus() == OTS_MSR_THREAD_STATUS.STOPPED)
  320. // {
  321. // // stop button clicked
  322. // loger.Info("DoMeasure: stop button is clicked.");
  323. // // record end time
  324. // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  325. // ThreadOver();
  326. // return false;
  327. // }
  328. // CSmplMeasure pSmplMeasure;
  329. // // create a sample measure object for the sample
  330. // switch (m_pProjData.m_nPackId)
  331. // {
  332. // case OTS_SysType_ID.IncA:
  333. // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  334. // break;
  335. // case OTS_SysType_ID.CleannessA:
  336. // pSmplMeasure = new CSmplMeasureCleanliness(m_strWorkingFolder, pSample);
  337. // break;
  338. // default:
  339. // pSmplMeasure = new CSmplMeasureInclution(m_strWorkingFolder, pSample);
  340. // break;
  341. // }
  342. // // set measure thread
  343. // pSmplMeasure.SetMsrThread(this);
  344. // pSmplMeasure.DoMeasureForOneSample();
  345. // }
  346. // // measurement completed
  347. // m_ThreadStatus.SetStatus(OTS_MSR_THREAD_STATUS.COMPLETED);
  348. // // record end time
  349. // m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  350. // ThreadOver();
  351. // return true;
  352. //}
  353. // hole preview
  354. public void DoHolePreview()
  355. {
  356. // start measurement, creat thread measure status class, let the main thread know that measurement started
  357. // set measure status to in-process
  358. //record time
  359. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.START);
  360. DateTime timeStart = m_ThreadStatus.GetStartTime();
  361. ST_MSTMsg MsgMsrStart = new ST_MSTMsg();
  362. MsgMsrStart.iMsgType = ENUM_MSG_TYPE.MTHREADSTATUS;
  363. MsgMsrStart.STMThreadStu.iMsrStatu =OTS_MSR_THREAD_STATUS.INPROCESS;
  364. SendMessageToMeasureApp(MsgMsrStart);
  365. // connect hardware
  366. if (!m_SemController.Connect())
  367. {
  368. // failed to connect hardware
  369. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
  370. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  371. ThreadOverWithoutDisConnect();
  372. }
  373. var a_pMeasureArea = m_pProjData.GetWorkingSample().GetMsrDomain();
  374. COTSSample pSampleHole = CreateHoleSample(a_pMeasureArea);
  375. var sample = m_pProjData.GetWorkingSample();
  376. // create a sample measure object for the sample
  377. CSmplMeasure pSmplMeasure = new CSmplMeasure(m_strWorkingFolder, sample);
  378. // set measure thread
  379. pSmplMeasure.SetMsrThread(this);
  380. // update thread measure status class, let the main thread know that this sample measurement starts
  381. // set working folder string
  382. pSmplMeasure.SetSample(sample);
  383. pSmplMeasure.SetHolePreviewSample(pSampleHole);
  384. pSmplMeasure.SetWorkingFolder(m_strWorkingFolder);
  385. // do measure
  386. pSmplMeasure.DoHolePreview();
  387. // check if measurement is successful
  388. if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.STOPPED)
  389. {
  390. // record end time
  391. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  392. // measurement stopped
  393. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.STOPPED);
  394. // update thread measure status class, let the main thread know that this sample measurement stopped
  395. ST_MSTMsg MsgSmpStop = new ST_MSTMsg();
  396. MsgSmpStop.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  397. MsgSmpStop.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.STOPPED;
  398. SendMessageToMeasureApp(MsgSmpStop);
  399. ThreadOverWithoutDisConnect();
  400. return;
  401. }
  402. else if (pSampleHole.GetMsrStatus().GetStatus() == OTS_MSR_SAMPLE_STATUS.FAILED)
  403. {
  404. // measurement failed
  405. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.FAILED);
  406. // record end time
  407. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  408. // update thread measure status class, let the main thread know that this sample measurement failed
  409. ST_MSTMsg MsgSmpFailed = new ST_MSTMsg();
  410. MsgSmpFailed.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  411. MsgSmpFailed.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.FAILED;
  412. SendMessageToMeasureApp(MsgSmpFailed);
  413. ThreadOverWithoutDisConnect();
  414. return;
  415. }
  416. // record end time
  417. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  418. // update thread measure status class, let the main thread know that this sample measurement successes
  419. ST_MSTMsg MsgSmpSuccess = new ST_MSTMsg();
  420. MsgSmpSuccess.iMsgType = ENUM_MSG_TYPE.MSAMPLESTATUS;
  421. MsgSmpSuccess.STMSampleStu.iMsrSampleStatu = OTS_MSR_SAMPLE_STATUS.SUCCESSED;
  422. SendMessageToMeasureApp(MsgSmpSuccess);
  423. // measurement completed
  424. SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS.COMPLETED);
  425. // record end time
  426. m_ThreadStatus.ComputeTime(OTS_THREAD_TIME_TYPE.STOPPED);
  427. ThreadOverWithoutDisConnect();
  428. }
  429. public COTSSample CreateHoleSample(CDomain a_pMsrArea)
  430. {
  431. COTSSample pHoleSample = new COTSSample();
  432. pHoleSample.SetMsrDomain(a_pMsrArea);
  433. // get min magnification
  434. CSEMStageData pSEMStageData = m_pProjData.GetSEMStageData();
  435. double dMinMag = pSEMStageData.GetMinMag();
  436. // get scan field size 100
  437. int nScanFieldSize100 = pSEMStageData.GetScanFieldSize100();
  438. // get working distance
  439. double dWorkingDistance = 0.0;
  440. if (!GetSEMWorkingDistanceFromHW(ref dWorkingDistance))
  441. {
  442. return null;
  443. }
  444. CSEMDataMsr poSEMDataMsr = new CSEMDataMsr();
  445. poSEMDataMsr.SetScanFieldSize100(nScanFieldSize100);
  446. poSEMDataMsr.SetWorkingDistance(dWorkingDistance);
  447. poSEMDataMsr.SetMagnification(dMinMag);
  448. pHoleSample.SetSEMDataMsr(poSEMDataMsr);
  449. // Set image scan param
  450. COTSImgScanPrm poImageScanParam = new COTSImgScanPrm();
  451. poImageScanParam.SetStopMode(((int)OTS_MEASURE_STOP_MODE.CoverMode).ToString());
  452. poImageScanParam.SetStartImageMode(OTS_GET_IMAGE_MODE.FROM_CENTER);
  453. poImageScanParam.SetScanImageSpeed(OTS_IMAGE_SCANSPEED_OPTIONS.low);
  454. //poImageScanParam.SetImagePixelSize(OTS_FIVE_TIES_OPTIONS.TIE1);
  455. CSampleParam poMsrParams = pHoleSample.GetMsrParams();
  456. poImageScanParam.SetImageResulotion(GetListMeasurableSamples()[0].GetMsrParams().GetImageScanParam().GetImageResulotion());//由于各样品分辨率应该一致,故此处没有读取选取的特定样品孔样品
  457. poMsrParams.SetImageScanParam(poImageScanParam);
  458. pHoleSample.SetMsrParams(poMsrParams);
  459. return pHoleSample;
  460. }
  461. public bool GetSEMWorkingDistanceFromHW(ref double a_dWorkingDistance)
  462. {
  463. m_SemController.GetWorkingDistance(ref a_dWorkingDistance);
  464. return true;
  465. }
  466. // measure status
  467. public void SetMsrLoopStatus(otsdataconst.OTS_MSR_THREAD_STATUS a_nMsrLoopStatus)
  468. {
  469. m_ThreadStatus.SetStatus( a_nMsrLoopStatus);
  470. }
  471. }
  472. }