From f4c1a42812cabe4c5afdc649ebf7a64fceb3c5f4 Mon Sep 17 00:00:00 2001 From: "Phares Mike (CSC FI SPS MESLEO)" Date: Tue, 20 May 2025 21:27:19 +0200 Subject: [PATCH] Merged PR 15667: process-data-standard-format prep without making any changes process-data-standard-format prep without making any changes --- LSL2/STPROC/METROLOGY_SERVICES.txt | 909 ++++++++++++++++++----------- 1 file changed, 579 insertions(+), 330 deletions(-) diff --git a/LSL2/STPROC/METROLOGY_SERVICES.txt b/LSL2/STPROC/METROLOGY_SERVICES.txt index 24b770e..52a33b9 100644 --- a/LSL2/STPROC/METROLOGY_SERVICES.txt +++ b/LSL2/STPROC/METROLOGY_SERVICES.txt @@ -99,6 +99,7 @@ Declare function Work_Order_Services, SRP_JSON, Logging_Services, Environment Declare function QA_Services, SRP_Join_Arrays, Get_Status, Obj_Clean_Insp, Datetime, SRP_Datetime Declare function Httpclient_Services, PM_Services, Signature_Services, SRP_Array, Math_Services Declare function Tool_Class_Services, obj_wo_mat +Declare function SRP_String LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\Metrology' LogDate = Oconv(Date(), 'D4/') @@ -173,11 +174,211 @@ Return Response else '' // Launches the metrology viewer URL with the client's default browser. //---------------------------------------------------------------------------------------------------------------------- Service LaunchMetrologyViewer - + MetrologyURL = Environment_Services('GetMetrologyViewerURL') Command = 'start ':MetrologyURL SRP_Run_Command(Command) - + +end service + + +Service GetJsonFromProcessDataStandardFormat(Text) + json = ''; + HeaderId = -1; + SubgroupId = -1; + FoundEndOfFile = False$; + SWAP '|' WITH @VM IN Text; + SWAP CRLF$ WITH @FM IN Text; + LineCount = DCOUNT(Text, @FM); + FOR LineLoopIndex = 1 TO LineCount + Line = Text; + IF FoundEndOfFile EQ True$ THEN + json = json:Line; + END + IF Line EQ 'EOF' THEN + FoundEndOfFile = True$; + Line = Text; + Convert Tab$ to @FM IN Line + SWAP '=' WITH @VM IN Line; + SWAP ';' WITH @FM IN Line; + IF Line<2, 1> EQ 'B_HeaderId' THEN + HeaderId = Line<2, 2> + END + IF Line<3, 1> EQ 'B_SubgroupId' THEN + SubgroupId = Line<3, 2> + END + END + NEXT LineLoopIndex + Response = json; +end service + + +Service GetStratus(Handle) + Result = ''; // Service ImportStratusData( + Offset = 1 + FieldPosition = 13 + FieldPositionIncrement = 2 + Result<1, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<1, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<1, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<1, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<1, 1> + IF RecordIndex EQ 1 THEN + Result<2> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DateTime'); // Timestamp + Result<3> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].MesEntity'); // Tool + Result<4> = 'FQA Thickness'; // DataType + Result<5> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Employee'); // Operator + Result<6> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Recipe'); // Recipe + Result<7> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Reactor'); // Reactor + Result<8> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSNo + Result<9> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].PSN'); // PSN + Result<10> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Batch'); // BatchID + Result<11> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Cassette'); // Cassette + Result<12> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].GradeMean'); // ThickAvg + END + ForOffset = (RecordIndex - 1) * FieldPositionIncrement; + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Slot'); // Position + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Mean'); // DataPoint + NEXT RecordIndex + Response = Result; +end service + + +Service GetBioRad(Handle) + Result = ''; // Service ImportBioRadData( + Offset = 1 + FieldPosition = 13 + FieldPositionIncrement = 2 + Result<1, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<1, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<1, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<1, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<1, 1> + IF RecordIndex EQ 1 THEN + Result<2> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DateTime'); // TimeStamp + Result<4> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Recipe'); // ScanRecipe + Result<5> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Reactor'); // ReactorID + Result<5> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Reactor'); // ToolID + Result<6> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSKeyID + Result<7> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].PSN'); // PSN + Result<8> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Layer'); // RunDataLayer + Result<9> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Zone'); // RunDataZone + Result<11> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Wafer'); // DataSlotId + END + ForOffset = (RecordIndex - 1) * FieldPositionIncrement; + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Position'); // Position + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Thickness'); // DataPoint + NEXT RecordIndex + Response = Result; +end service + + +Service GetCDE(Handle) + Result = ''; // Service ImportCDEData( + Offset = 3 + FieldPosition = 23 + FieldPositionIncrement = 5 + Result<1, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<1, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<1, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<1, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<1, 1> + IF RecordIndex EQ 1 THEN + Result<3> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Date'); // Timestamp + Result<5> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RecipeName'); // ScanRecip + Result<6> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Reactor'); // ReactorID + Result<7> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSKeyID + Result<8> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].PSN'); // PSN + Result<9> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Layer'); // RunDataLayer + Result<10> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Zone'); // RunDataZo + END + ForOffset = (RecordIndex - 1) * FieldPositionIncrement; + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].InferredPoint'); // Position + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Data'); // DataPoint + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].MeritGOF'); // N/A + NEXT RecordIndex + Response = Result; +end service + + +Service GetHgCV(Handle) + Result = ''; // Service ImportHgCVData( + Offset = 5 + PhaseOffset = 7 + FieldPosition = 53 + FieldPositionIncrement = 9 + Result<1, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<1, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<1, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<1, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<1, 1> + IF RecordIndex EQ 1 THEN + Result<2> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].MesEntity'); // ToolID + Result<3> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Reactor'); // ReactorID + Result<4> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSKeyID + Result<5> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].PSN'); // PSN + Result<8> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Wafer'); // LayerZonePair + Result<11> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Date'); // Timestamp + END + ForOffset = (RecordIndex - 1) * FieldPositionIncrement; + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Site'); // Position + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RhoAvg'); // HgCVDataPoint + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Phase'); // PhaseDataPoint + Result = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Grade'); // N/A + NEXT RecordIndex + Response = Result; +end service + + +Service GetTencor(Handle) + Result = ''; // Service ImportTencorData( + Result<1, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<1, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<1, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<1, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<1, 1> + IF RecordIndex EQ 1 THEN + Result<9> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Date'); // Timestamp + Result<10> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].HazeAverageAvg'); // HazeAvg + Result<28> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSKeyID + Result<30> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].WaferRecipe'); // ScanRecipe + Result<39> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].SumOfDefectsAvg'); // SoDAvg + Result<40> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].SumOfDefectsMax'); // SoDMax + Result<41> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].SumOfDefectsMin'); // SoDMin + Result<43> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].MesEntity'); // ScanTool + END + NEXT RecordIndex + Response = Result; +end service + + +Service GetSP1(Handle) + Result = ''; // Service ImportSP1Data( + Result<5, 1> = SRP_JSON(Handle, 'GETVALUE', 'Count'); + Result<5, 2> = SRP_JSON(Handle, 'GETVALUE', 'Sequence'); + Result<5, 3> = SRP_JSON(Handle, 'GETVALUE', 'HeaderId'); + Result<5, 4> = SRP_JSON(Handle, 'GETVALUE', 'SubgroupId'); + FOR RecordIndex = 1 TO Result<5, 1> + IF RecordIndex EQ 1 THEN + Result<9> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Date'); // Timestamp + Result<10> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnHazeAvgMean'); // HazeAvg + Result<28> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].RDS'); // RDSKeyID + Result<30> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].Session'); // ScanRecipe + IsMisfit = IndexC(Result<30>, 'MISFIT', 1) + IF IsMisfit THEN + Result<3> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMean'); // SoDAvg + Result<2> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMax'); // SoDMax + Result<1> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMin'); // SoDMin + END ELSE + Result<39> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMean'); // SoDAvg + Result<40> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMax'); // SoDMax + Result<41> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAllMin'); // SoDMin + END + Result<43> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].MesEntity'); // ScanTool + Result<44> = SRP_JSON(Handle, 'GETVALUE', 'Records[':RecordIndex:'].DcnAreaMean'); // DCNMM2 + END + NEXT RecordIndex + Response = Result; end service @@ -194,37 +395,46 @@ Service ImportMetrologyFiles(Machine) ******************************** * Verify Metrology data folder * ******************************** - + Begin Case Case Machine _EQC 'Tencor' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08DDUPSFS6420\Source\MET08DDUPSFS6420\' Case Machine _EQC 'HgCV' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08RESIHGCV\Source\MET08RESIHGCV\' Case Machine _EQC 'CDE' + SearchPattern = '*.pdsf'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08RESIMAPCDE\Source\MET08RESIMAPCDE\' Case Machine _EQC 'Biorad' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08THFTIRQS408M\Source\MET08THFTIRQS408M\' Case Machine _EQC 'Stratus' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08THFTIRSTRATUS\Source\MET08THFTIRSTRATUS\' Case Machine _EQC 'SP1' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08DDUPSP1TBI\Source\MET08DDUPSP1TBI\' Case Machine _EQC 'SPV' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08RESISRP2100\Source\MET08RESISRP2100\' Case Machine _EQC 'SRP' + SearchPattern = '*.txt'; DataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\MET08ANLYSDIFAAST230\Source\MET08ANLYSDIFAAST230\' Case Otherwise$ + SearchPattern = '*.txt'; Error_Services('Add', 'Error in ':Service:' service. Unsupported Machine "':Machine:'" passed into service') End Case - + If Error_Services('NoError') then - - InitDir DataPath:'*.txt' + + InitDir DataPath:SearchPattern FileList = DirList() FileNames = '' LOOP FileName = FileList[1,@FM] FileList[1,Col2()] = "" - + LOCATE FileName IN FileNames BY 'AR' USING @FM SETTING Pos ELSE FileNames = INSERT(FileNames,Pos,0,0,FileName) END @@ -233,10 +443,10 @@ Service ImportMetrologyFiles(Machine) IF FileNames[-1,1] = @FM THEN FileNames[-1,1] = '' END - + FileCnt = COUNT(FileNames,@FM) + (FileNames NE '') FOR FileLoopIndex = 1 TO FileCnt - + *********************** * Read metrology file * *********************** @@ -263,109 +473,119 @@ Service ImportMetrologyFiles(Machine) ImportAttemptCounts = ImportAttempts ImportAttemptDTMs = CurrDTM end - + If ProcessNow then - + FileInfo = Dir(DataPath:FileName) FileSize = FileInfo<1> Metrology_Services('LogResults', '', Machine, 'UID000', 'Dir : ' : FileName : ', Size : ' : FileSize) - + ImportStartTime = Time() - - OSREAD RunData FROM DataPath:FileName THEN - Metrology_Services('LogResults', '', Machine, 'UID000', 'Read : ' : FileName : ', Size : ' : FileSize) - - // Copy Run Data files to repository for troubleshooting purposes - Begin Case - Case Machine _EQC 'Tencor' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08DDUPSFS6420\Source\MET08DDUPSFS6420\' - Case Machine _EQC 'HgCV' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESIHGCV\Source\MET08RESIHGCV\' - Case Machine _EQC 'CDE' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESIMAPCDE\Source\MET08RESIMAPCDE\' - Case Machine _EQC 'Biorad' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08THFTIRQS408M\Source\MET08THFTIRQS408M\' - Case Machine _EQC 'Stratus' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08THFTIRSTRATUS\Source\MET08THFTIRSTRATUS\' - Case Machine _EQC 'SP1' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08DDUPSP1TBI\Source\MET08DDUPSP1TBI\' - Case Machine _EQC 'SPV' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESISRP2100\Source\MET08RESISRP2100\' - Case Machine _EQC 'SRP' - RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08ANLYSDIFAAST230\Source\MET08ANLYSDIFAAST230\' - End Case - - Set_Status(0) - OSWrite RunData to RepoPath:FileName - status_code = '' - If Get_Status(status_code) then - ErrorMessage = 'Error writing run data file to repository: status_code = ' : status_code - Metrology_Services('LogResults', '', Machine, 'UID001', Service : ' : ' : ErrorMessage) - Set_Status(0) - end - - SWAP '|' WITH @VM IN RunData - SWAP CRLF$ WITH @FM IN RunData - - LOOP - LastChar = RunData[-1,1] - UNTIL LastChar NE @FM - RunData[-1,1] = '' - REPEAT - - ************************* - * Import metrology data * - ************************* - - Metrology_Services('ImportMetrologyRunData', RunData, FileName, Machine) - - If Error_Services('NoError') then - Continue = True$ - end else - ErrorMessage = Error_Services('GetMessage') - FQAError = IndexC(ErrorMessage, 'FQA has already been signed', 1) - If ( Index(ErrorMessage, 'UID002', 1) and (ImportAttempts LE RETRY_ATTEMPTS$) and Not(FQAError) ) then - Continue = False$ - end else - Continue = True$ - end - end - - ****************************** - * Delete metrology data file * - ****************************** - If (Continue) then - Status() = 0 - OSDELETE DataPath:FileName ;* Deletes local copy of data file - ImportFileList = Delete(ImportFileList, FilePos, 0, 0) - ImportAttemptCounts = Delete(ImportAttemptCounts, FilePos, 0, 0) - ImportAttemptDTMs = Delete(ImportAttemptDTMs, FilePos, 0, 0) - ErrCode = Status() - If ErrCode EQ 0 then - Metrology_Services('LogResults', '', Machine, 'UID000', 'Delete : ' : FileName : ', Size : ' : FileSize) - end else - Metrology_Services('LogResults', '', Machine, 'UID001', 'Delete : ' : FileName : ', Size : ' : FileSize : ', Error : ' : ErrCode) - end + + Metrology_Services('LogResults', '', Machine, 'UID000', 'Read : ' : FileName : ', Size : ' : FileSize) + + // Copy Run Data files to repository for troubleshooting purposes + Begin Case + Case Machine _EQC 'Tencor' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08DDUPSFS6420\Source\MET08DDUPSFS6420\' + Case Machine _EQC 'HgCV' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESIHGCV\Source\MET08RESIHGCV\' + Case Machine _EQC 'CDE' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESIMAPCDE\Source\MET08RESIMAPCDE\' + Case Machine _EQC 'Biorad' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08THFTIRQS408M\Source\MET08THFTIRQS408M\' + Case Machine _EQC 'Stratus' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08THFTIRSTRATUS\Source\MET08THFTIRSTRATUS\' + Case Machine _EQC 'SP1' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08DDUPSP1TBI\Source\MET08DDUPSP1TBI\' + Case Machine _EQC 'SPV' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08RESISRP2100\Source\MET08RESISRP2100\' + Case Machine _EQC 'SRP' + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\MET08ANLYSDIFAAST230\Source\MET08ANLYSDIFAAST230\' + End Case + + IF SearchPattern = '*.pdsf' THEN + OSREAD Text FROM DataPath:FileName THEN + json = Metrology_Services('GetJsonFromProcessDataStandardFormat', Text); + END ELSE + json = ''; + END + IF LEN(json) GT 0 THEN + RunData = Metrology_Services('GetRunData', Machine, json); + END ELSE + Metrology_Services('LogResults', PSN, Machine, 'UID002', Service : ' : ' : 'Failed to get PDSF json'); + END + END ELSE + + OSREAD RunData FROM DataPath:FileName THEN + SWAP '|' WITH @VM IN RunData + SWAP CRLF$ WITH @FM IN RunData + + LOOP + LastChar = RunData[-1,1] + UNTIL LastChar NE @FM + RunData[-1,1] = '' + REPEAT + Convert Tab$ to @FM in RunData END else - - ErrorMessage = Error_Services('GetMessage') - MetrologyLog = Database_Services('ReadDataRow', 'SYSLISTS', UCase(Machine):'_METROLOGY_LOG') - MetrologyLog := ErrorMessage : @FM - Database_Services('WriteDataRow', 'SYSLISTS', UCase(Machine):'_METROLOGY_LOG', MetrologyLog, True$) + Metrology_Services('LogResults', '', Machine, 'UID001', 'Read : ' : FileName : ', Size : ' : FileSize) + end + END + + ************************* + * Import metrology data * + ************************* + + IF RunData NE '' then + Metrology_Services('ImportMetrologyRunData', Machine, DataPath, FileName, RunData) + END ELSE + Error_Services('Add', 'RunData argument was missing') + Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) + END + + If Error_Services('NoError') then + Continue = True$ + end else + ErrorMessage = Error_Services('GetMessage') + FQAError = IndexC(ErrorMessage, 'FQA has already been signed', 1) + If ( Index(ErrorMessage, 'UID002', 1) and (ImportAttempts LE RETRY_ATTEMPTS$) and Not(FQAError) ) then + Continue = False$ + end else + Continue = True$ end - - END else - Metrology_Services('LogResults', '', Machine, 'UID001', 'Read : ' : FileName : ', Size : ' : FileSize) end - + + ****************************** + * Delete metrology data file * + ****************************** + If (Continue) then + Status() = 0 + OSDELETE DataPath:FileName ;* Deletes local copy of data file + ImportFileList = Delete(ImportFileList, FilePos, 0, 0) + ImportAttemptCounts = Delete(ImportAttemptCounts, FilePos, 0, 0) + ImportAttemptDTMs = Delete(ImportAttemptDTMs, FilePos, 0, 0) + ErrCode = Status() + If ErrCode EQ 0 then + Metrology_Services('LogResults', '', Machine, 'UID000', 'Delete : ' : FileName : ', Size : ' : FileSize) + end else + Metrology_Services('LogResults', '', Machine, 'UID001', 'Delete : ' : FileName : ', Size : ' : FileSize : ', Error : ' : ErrCode) + end + END else + + ErrorMessage = Error_Services('GetMessage') + MetrologyLog = Database_Services('ReadDataRow', 'SYSLISTS', UCase(Machine):'_METROLOGY_LOG') + MetrologyLog := ErrorMessage : @FM + Database_Services('WriteDataRow', 'SYSLISTS', UCase(Machine):'_METROLOGY_LOG', MetrologyLog, True$) + end + Database_Services('WriteDataRow', 'APP_INFO', UCase(Machine):'_FILE_LIST', ImportFileList) Database_Services('WriteDataRow', 'APP_INFO', UCase(Machine):'_ATTEMPT_COUNTS', ImportAttemptCounts) Database_Services('WriteDataRow', 'APP_INFO', UCase(Machine):'_ATTEMPT_DTMS', ImportAttemptDTMs) - + end - + NEXT FileLoopIndex - + end else Metrology_Services('LogResults', '', '', 'UID001', Error_Services('GetMessage')) end @@ -374,7 +594,44 @@ Service ImportMetrologyFiles(Machine) end else Metrology_Services('LogResults', '', '', 'UID001', 'Null Machine passed into service') end - + +end service + + +Service GetRunData(Machine, json) + + Result = ''; + Handle = ''; + If Assigned(Handle) else Handle = 0 + If Handle LE 0 then + ParseError = SRP_JSON(Handle, 'PARSE', json); + IF ParseError EQ '' THEN + Begin Case + Case Machine _EQC 'Stratus' + Result = Metrology_Services('GetStratus', Handle); + + Case Machine _EQC 'Biorad' + Result = Metrology_Services('GetBiorad', Handle); + + Case Machine _EQC 'CDE' + Result = Metrology_Services('GetCDE', Handle); + + Case Machine _EQC 'HgCV' + Result = Metrology_Services('GetHgCV', Handle); + + Case Machine _EQC 'SP1' + Result = Metrology_Services('GetSP1', Handle); + + Case Machine _EQC 'Tencor' + Result = Metrology_Services('GetTencor', Handle); + + End Case + SRP_JSON(Handle, 'RELEASE'); + END ELSE + Metrology_Services('LogResults', PSN, Machine, 'UID002', Service : ' : ' : 'Failed to parse PDSF json'); + END + END + Response = Result; end service @@ -386,65 +643,57 @@ end service // Imports the metrology run data into the RDS_TEST database table. Returns True$ if successful and False$ if // unsuccessful. //---------------------------------------------------------------------------------------------------------------------- -Service ImportMetrologyRunData(RunData, FileName, Machine) - - If RunData NE '' then - - Convert Tab$ to @FM in RunData +Service ImportMetrologyRunData(Machine, DataPath, FileName, RunData) + // Scan the run data for machine specific information. Then call the relevant update service for the specific // machine. Begin Case - Case IndexC(RunData, 'Stratus', 1) + Case Machine _EQC 'Stratus' Metrology_Services('ImportStratusData', RunData) MachineType@ = 'Stratus' - - Case IndexC(RunData, 'Bio-Rad', 1) + + Case Machine _EQC 'Biorad' Metrology_Services('ImportBioRadData', RunData, FileName) MachineType@ = 'Bio-Rad' - - Case IndexC(RunData, 'ResMap', 1) OR IndexC(RunData, 'CDE', 1) + + Case Machine _EQC 'CDE' Metrology_Services('ImportCDEData', RunData, FileName) MachineType@ = 'CDE' - - Case IndexC(RunData, 'PROBE', 1) OR IndexC(RunData, 'HgProbe', 1) OR IndexC(RunData, 'HGCV', 1) + + Case Machine _EQC 'HgCV' Metrology_Services('ImportHgCVData', RunData, FileName) MachineType@ = 'HgProbe' - - Case IndexC(RunData, 'SP1', 1) + + Case Machine _EQC 'SP1' Metrology_Services('ImportSP1Data', RunData) MachineType@ = 'SP1' - - Case IndexC(RunData, 'TENCOR', 1) OR IndexC(RunData, 'ROTR', 1) + + Case Machine _EQC 'Tencor' Metrology_Services('ImportTencorData', RunData) MachineType@ = 'TENCOR' - + Case Machine _EQC 'SRP' Error_Services('Add', 'SRP data import is currently disabled.') - Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) + Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) MachineType@ = 'SRP' - + Case Machine _EQC 'SPV' Error_Services('Add', 'SPV data import is currently disabled.') - Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) + Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) MachineType@ = 'SPV' - + Case Otherwise$ Error_Services('Add', 'Unrecognized machine used to create metrology run data') Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) MachineType@ = 'Unrecognized' - - End Case - - end else - Error_Services('Add', 'RunData argument was missing') - Metrology_Services('LogResults', '', '', 'UID001', Service : ' : ' : Error_Services('GetMessage')) - end - + + End Case + end service Service ImportStratusData(RunData) - + Machine = 'Stratus' ParseArray = '' FieldPos = 13 @@ -464,7 +713,7 @@ Service ImportStratusData(RunData) ThickAvg = RunData<12> Positions = '' DataPoints = '' - + Loop Position = Trim(RunData) DataPoint = Trim(RunData) @@ -474,13 +723,13 @@ Service ImportStratusData(RunData) FieldPos += FieldPosIncrement Repeat Positions[-1, 1] = '' ; // Strip final @VM - DataPoints[-1, 1] = '' ; // Strip final @VM - + DataPoints[-1, 1] = '' ; // Strip final @VM + // Clean the cassette user input. Swap '.' with '*' in Cassette Swap 'o' with '' in Cassette Swap 'O' with '' in Cassette - + // Determine if the key ID is an RDS or WM_OUT key IsEpiPro = false$ Begin Case @@ -497,9 +746,9 @@ Service ImportStratusData(RunData) Case Otherwise$ Error_Services('Add', 'Unrecognized cassette ID ':Cassette:'.') End Case - + If Error_Services('NoError') then - + // Update WO_MAT record StdDev = '' WOMatKey = WorkOrderNo : '*' : CassNo @@ -552,8 +801,8 @@ Service ImportStratusData(RunData) StdDev = OConv(IConv(StdDev, 'MD3'), 'MD3') end Database_Services('WriteDataRow', 'WM_OUT', RDSNo@, WMORec, True$, False$, True$) - end - + end + // Update WO_MAT_QA record StdDevMax = '' WOMatQAID = WorkOrderNo : '*' : CassNo @@ -594,7 +843,7 @@ Service ImportStratusData(RunData) Case Slot EQ 'A' WaferIndex = 1 Case Otherwise$ - WaferIndex = Slot + WaferIndex = Slot End Case Locate WaferIndex in Positions using @VM setting dPos then WOMatQARec = DataPoints<0, dPos> @@ -609,11 +858,11 @@ Service ImportStratusData(RunData) end end else Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) - end + end end else Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + end service @@ -686,7 +935,7 @@ Service ImportBioRadData(RunData, FileName) RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID) If Error_Services('NoError') then WorkOrderNo = RDSRec - + // HgCV Project Development Code ------------------------------------------------------------------------------- DevelopmentFlag = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') If (DevelopmentFlag EQ True$) then @@ -698,30 +947,30 @@ Service ImportBioRadData(RunData, FileName) WorkOrder = Work_Order_Services('GetWorkOrder', WorkOrderNo, False$) GoSub ParseWorkOrder IsEpiPro = (WOReactorType _EQC 'EpiPro') OR (WOReactorType _EQC 'EPP') - + RunDataZone = Metrology_Services('FormatZoneKeyID', RunDataZone) ; // 1, 2 RunDataLayer = Metrology_Services('FormatLayerKeyID', RunDataLayer) ; // L1, L2, 2 - + ZoneForValidation = RunDataZone LayerForValidation = RunDataLayer If LayerForValidation EQ '' then LayerForValidation = 'L1' end - + CalculatedZone = Metrology_Services('GetCalculatedZone', RDSKeyID, IsEpiPro, RunDataZone) If RunDataZone NE CalculatedZone then Error_Services('Add', 'Entered Zone [' : RunDataZone : '] and calculated Zone [' : CalculatedZone : '] do not match.') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedZone to RunDataZone - + CalculatedLayer = Metrology_Services('GetCalculatedLayer', RDSKeyID, Machine, RunDataZone, IsEpiPro, RunDataLayer) If (RunDataLayer NE CalculatedLayer) then Error_Services('Add', 'Entered Layer [' : RunDataLayer : '] and calculated Layer [' : CalculatedLayer : '] do not match for the Zone [' : RunDataZone : '].') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedLayer to RunDataLayer - + ReactorRec = Database_Services('ReadDataRow', 'REACTOR', ReactorID) If Error_Services('NoError') then ReactorType = ReactorRec @@ -742,7 +991,7 @@ Service ImportBioRadData(RunData, FileName) Error_Services('Add', Message) end end - + If Error_Services('NoError') then Positions = '' DataPoints = '' @@ -758,7 +1007,7 @@ Service ImportBioRadData(RunData, FileName) DataPoints[-1, 1] = '' ; // Strip final @VM RawDataPoints = DataPoints DataPoints = Iconv(DataPoints, 'MD' : Decimals) - + Swap ' AM' with 'AM' in Timestamp Swap ' PM' with 'PM' in Timestamp Timestamp = IConv(Timestamp,'DT') @@ -785,11 +1034,11 @@ Service ImportBioRadData(RunData, FileName) Error_Services('Add', 'Unable to obtain a valid Metrology Test Key ID.') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + // If not found this is because there was no zone. However, if this is not EpiPro, this is still a valid // test so set the found flag to true. If Not(Found) AND Not(IsEpiPro) then Found = True$ - + If (Found EQ True$) then // Check if QA Metrology run or conventional RDS Metrology run. // Recipe name match requirement has been turned off per Tom Tillery. djs 10/03/18 @@ -818,7 +1067,7 @@ Service ImportBioRadData(RunData, FileName) // Log this as it is unexpected NotesLog = Logging_Services('NewLog', LogPath2, 'Thickness_Points_Error.txt', CRLF$, Comma$, '', '', False$, False$) End Case - + LogData = '' LogData<1> = Oconv(Timestamp, 'DT/^HS') ; // Metrology date/time stamp LogData<2> = ReactorID ; // Reactor @@ -843,7 +1092,7 @@ Service ImportBioRadData(RunData, FileName) WOMatQAID = WorkOrderNo : '*' : CassNo WOMatQARec = Database_Services('ReadDataRow', 'WO_MAT_QA', WOMatQAID) SpecRecipes = WOMatQARec - + WOStepNo = RDSRec[-1, 'B*'] ProfSteps = '' ProfileCnt = DCount(WOMatQARec, @VM) @@ -873,19 +1122,19 @@ Service ImportBioRadData(RunData, FileName) Error_Services('Add', ErrMsg) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + // verify number of points is correct WoMatQaToolClass = WOMatQARec WoMatQaRecipePattern = WOMatQARec NumDataPointsInSpec = Tool_Class_Services('GetNumberOfPointsForPattern', WoMatQaToolClass, WoMatQaRecipePattern) WoMatQaRecipePatternNumPointsMatchesScanNumDataPoints = NumDataPointsInSpec EQ NumDataPoints - + If WoMatQaRecipePatternNumPointsMatchesScanNumDataPoints EQ False$ then ErrMsg = 'Scan data point count [ ' : NumDataPoints : ' ] does not match WoMatQa recipe pattern data point count [ ' : NumDataPointsInSpec : ' ] for RDS [ ' : RDSKeyID : ' ] layer [ ' : CalculatedLayer : ' ].' Error_Services('Add', ErrMsg) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + If (WOMatQARec EQ '' OR IsViewerFile) then If WoMatQaRecipeMatchesScanRecipe and WoMatQaRecipePatternNumPointsMatchesScanNumDataPoints then WOMatQARec = Average @@ -927,12 +1176,12 @@ Service ImportBioRadData(RunData, FileName) end Case Otherwise$ // If not an above case, then the run is a conventional THICK_ONLY RDS metrology test. - + RDSLayerKeyID = RDSKeyID : '*' : LayerForValidation RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID) If Error_Services('NoError') then RDSTestKeyIDs = RDSLayerRec - + // Verify the scan recipe matches the spec recipe RecipeMatches = Metrology_Services('ScanRecipeMatchesRdsTestSpecThickMrecipe', RDSKeyID, LayerForValidation, ScanRecipe, RDSTestKeyIDs, ZoneForValidation) If RecipeMatches EQ False$ then @@ -940,7 +1189,7 @@ Service ImportBioRadData(RunData, FileName) Error_Services('Add', ErrMsg) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + // Verfiy the scan number of points matches the spec number of points NumPointsMatches = Metrology_Services('ScanNumDataPointsMatchesRdsTestSpecThickMPattern', RDSKeyID, LayerForValidation, NumDataPoints, RDSTestKeyIDs, 'FTIR', ZoneForValidation) If NumPointsMatches EQ False$ then @@ -948,7 +1197,7 @@ Service ImportBioRadData(RunData, FileName) Error_Services('Add', ErrMsg) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + If RecipeMatches and NumPointsMatches then GoSub LoadRunDataToDatabase end @@ -974,12 +1223,12 @@ Service ImportBioRadData(RunData, FileName) end end end - + end service Service ImportCDEData(RunData, FileName) - + Machine = 'CDE' ParseArray = '' FieldPos = 23 @@ -1022,7 +1271,7 @@ Service ImportCDEData(RunData, FileName) end else Metrology_Services('LogResults', PSN, Machine, 'UID002', Service : ' : ' : 'Null response from IQS API.') end - + end else // Regular metrology file IsViewerFile = Index(FileName, 'Viewer', 1) @@ -1035,7 +1284,7 @@ Service ImportCDEData(RunData, FileName) RDSNo@ = RDSKeyID RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID) If Error_Services('NoError') then - + // HgCV Project Development Code ------------------------------------------------------------------------------- DevelopmentFlag = Xlate('DEVELOPMENT', 'HGCV', 'STATUS', 'X') If (DevelopmentFlag EQ True$) then @@ -1043,30 +1292,30 @@ Service ImportCDEData(RunData, FileName) If IsProdTest EQ True$ then Metrology_Services('LogResults',RDSKeyID,Machine,'HgCV','Product test recognized. Recipe name: ':ScanRecipe) end // ------------------------------------------------------------------------------------------------------------- - + WorkOrderNo = RDSRec CassNo = RDSRec WorkOrder = Work_Order_Services('GetWorkOrder', WorkOrderNo, False$) GoSub ParseWorkOrder IsEpiPro = (WOReactorType _EQC 'EpiPro') OR (WOReactorType _EQC 'EPP') - + RunDataZone = Metrology_Services('FormatZoneKeyID', RunDataZone) ; // 1, 2 RunDataLayer = Metrology_Services('FormatLayerKeyID', RunDataLayer) ; // L1, L2, 2 - + CalculatedZone = Metrology_Services('GetCalculatedZone', RDSKeyID, IsEpiPro, RunDataZone) If RunDataZone NE CalculatedZone then Error_Services('Add', 'Entered Zone [' : RunDataZone : '] and calculated Zone [' : CalculatedZone : '] do not match.') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedZone to RunDataZone - + CalculatedLayer = Metrology_Services('GetCalculatedLayer', RDSKeyID, Machine, RunDataZone) If RunDataLayer NE CalculatedLayer then Error_Services('Add', 'Entered Layer [' : RunDataLayer : '] and calculated Layer [' : CalculatedLayer : '] do not match for the Zone [' : RunDataZone : '].') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedLayer to RunDataLayer - + ReactorRec = Database_Services('ReadDataRow', 'REACTOR', ReactorID) If Error_Services('NoError') then ReactorType = ReactorRec @@ -1087,7 +1336,7 @@ Service ImportCDEData(RunData, FileName) Error_Services('Add', Message) end end - + If Error_Services('NoError') then Positions = '' DataPoints = '' @@ -1103,11 +1352,11 @@ Service ImportCDEData(RunData, FileName) Positions[-1, 1] = '' ; // Strip final @VM DataPoints[-1, 1] = '' ; // Strip final @VM DataPoints = Iconv(DataPoints, 'MD' : Decimals) - + Swap ' AM' with 'AM' in Timestamp Swap ' PM' with 'PM' in Timestamp Timestamp = IConv(Timestamp,'DT') - + RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer NumDataPoints = DCount(DataPoints, @VM) RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID) @@ -1131,11 +1380,11 @@ Service ImportCDEData(RunData, FileName) Error_Services('Add', 'Unable to obtain a valid Metrology Test Key ID.') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + // If not found this is because there was no zone. However, if this is not EpiPro, this is still a valid // test so set the found flag to true. If Not(Found) AND Not(IsEpiPro) then Found = True$ - + If (Found EQ True$) then If (IsProdTest EQ True$) then // QA Metrology test (i.e. not RDS Metrology test) @@ -1221,12 +1470,12 @@ Service ImportCDEData(RunData, FileName) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end end - + end service Service ImportHgCVData(RunData, FileName) - + Machine = 'HgCV' /* Resistivity */ FieldPos = 53 FieldPosIncrement = 9 @@ -1274,7 +1523,7 @@ Service ImportHgCVData(RunData, FileName) PatternNameIndex = RDS_TEST_SPEC_RES_MPATTERN$ ToolClassIndex = RDS_TEST_SPEC_RES_MTOOL$ DataIndex = RDS_TEST_READ_HGCV1_RES$ - DTMIndex = RDS_TEST_TEST_RUN_HGCV_DTM$ + DTMIndex = RDS_TEST_TEST_RUN_HGCV_DTM$ Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : ' : 'Beginning ImportHgCVData') RDSNo@ = RDSKeyID RDSRec = Database_Services('ReadDataRow', 'RDS', RDSKeyID) @@ -1284,7 +1533,7 @@ Service ImportHgCVData(RunData, FileName) WorkOrder = Work_Order_Services('GetWorkOrder', WorkOrderNo, False$) GoSub ParseWorkOrder IsEpiPro = (WOReactorType _EQC 'EpiPro') OR (WOReactorType _EQC 'EPP') - + Convert @Lower_Case to @Upper_Case in LayerZonePair Convert 'Z' to '-' in LayerZonePair Swap '--' with '-' in LayerZonePair @@ -1292,21 +1541,21 @@ Service ImportHgCVData(RunData, FileName) RunDataZone = Field(LayerZonePair, '-', 2) RunDataZone = Metrology_Services('FormatZoneKeyID', RunDataZone) ; // 1, 2 RunDataLayer = Metrology_Services('FormatLayerKeyID', RunDataLayer) ; // L1, L2, 2 - + CalculatedZone = Metrology_Services('GetCalculatedZone', RDSKeyID, IsEpiPro, RunDataZone) If RunDataZone NE CalculatedZone then Error_Services('Add', 'Entered Zone [' : RunDataZone : '] and calculated Zone [' : CalculatedZone : '] do not match.') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedZone to RunDataZone - + CalculatedLayer = Metrology_Services('GetCalculatedLayer', RDSKeyID, Machine, RunDataZone) If RunDataLayer NE CalculatedLayer then Error_Services('Add', 'Entered Layer [' : RunDataLayer : '] and calculated Layer [' : CalculatedLayer : '] do not match for the Zone [' : RunDataZone : '].') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end Transfer CalculatedLayer to RunDataLayer - + ReactorRec = Database_Services('ReadDataRow', 'REACTOR', ReactorID) If Error_Services('NoError') then ReactorType = ReactorRec @@ -1327,7 +1576,7 @@ Service ImportHgCVData(RunData, FileName) Error_Services('Add', Message) end end - + If Error_Services('NoError') then Position = '' Positions = '' @@ -1343,13 +1592,13 @@ Service ImportHgCVData(RunData, FileName) Repeat Positions[-1, 1] = '' ; // Strip final @VM HgCVDataPoints[-1, 1] = '' ; // Strip final @VM - + HgCVDataPoints = Iconv(HgCVDataPoints, 'MD' : Decimals) - + Swap ' AM' with 'AM' in Timestamp Swap ' PM' with 'PM' in Timestamp Timestamp = IConv(Timestamp,'DT') - + RDSLayerKeyID = RDSKeyID : '*' : RunDataLayer NumDataPoints = DCount(HgCVDataPoints, @VM) RDSLayerRec = Database_Services('ReadDataRow', 'RDS_LAYER', RDSLayerKeyID) @@ -1411,7 +1660,7 @@ Service ImportHgCVData(RunData, FileName) Avg9Point = Response<0, 7> EdgeMean10mm = Response<0, 8> ResStdDev = Response<0, 9> - + DataPoints = PhaseDataPoints Response = QA_Services('CalculateHgCVData', Datapoints) * GoSub CalculateQAData @@ -1469,7 +1718,7 @@ Service ImportHgCVData(RunData, FileName) WOMatQARec = DataRow Next Index // ------------------------------------------------------------------------------------------------------------ - + // Send data to SPC ------------------------------------------------------------------------------------------- LogPath = Environment_Services('GetSpcFilesharePath') SpcFileDtm = OConv(Datetime(), 'DT2^HS ') @@ -1506,9 +1755,9 @@ Service ImportHgCVData(RunData, FileName) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : Successfully updated SPC file with metrology data.') end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : Failed to update SPC file with metrology data. Error message: ':Error_Services('GetMessage')) - end + end // ------------------------------------------------------------------------------------------------------------ - + WOMatQARec = '' WOMatQARec = '' Database_Services('WriteDataRow', 'WO_MAT_QA', WOMatQAID, WOMatQARec, True$, False$, True$) @@ -1525,7 +1774,7 @@ Service ImportHgCVData(RunData, FileName) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end // We know it is a CRES test, so we can now safely import the Phase Angle data - + end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : UID001 - Data for this metrology test already exists and is not from the metrology viewer.') end @@ -1564,14 +1813,14 @@ Service ImportHgCVData(RunData, FileName) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end end - + end service Service ImportTencorData(RunData) - + ErrorMessage = '' - Machine = 'Tencor' + Machine = 'Tencor' Timestamp = RunData<9> HazeAvg = RunData<10> RDSKeyID = RunData<28> @@ -1583,11 +1832,11 @@ Service ImportTencorData(RunData) Swap '%' with ' ' in ScanTool RDSNo@ = RDSKeyID Convert @Lower_Case to @Upper_Case in ScanTool - + Swap ' AM' with 'AM' in Timestamp Swap ' PM' with 'PM' in Timestamp Timestamp = IConv(Timestamp,'DT') - + If RowExists('RDS', RDSKeyID) then // Try to read the CleanInsp datarow. Use this to identify the RDSKeyID. ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSKeyID) @@ -1603,7 +1852,7 @@ Service ImportTencorData(RunData) StageFound = True$ Stage = Field(PRSStageKey, '*', 2, 1) end - Next PRSStageKey + Next PRSStageKey CIKeyStages = ReactRunRec CIKeyIDs = ReactRunRec Locate Stage in CIKeyStages using @VM setting vPos then @@ -1633,7 +1882,7 @@ Service ImportTencorData(RunData) LogData<3> = RDSNo@ LogData<4> = 'Time taken to import SOD data: ':TimeTaken:' seconds.' Logging_Services('AppendLog', objSODPerfLog, LogData, @RM, @FM) - If SODWaferArray NE '' then + If SODWaferArray NE '' then WaferNos = SODWaferArray<1> SODVals = SODWaferArray<2> SortVals = SODWaferArray<3> @@ -1667,7 +1916,7 @@ Service ImportTencorData(RunData) CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_SCAN_SIG_DTM$, NumRecipes, 0, '') CleanInspRec = Insert(CleanInspRec, CLEAN_INSP_INSP_TEST_RUN_DTM$, NumRecipes, 0, Timestamp) // Save results (this will trigger an ROTR_REQUEST via CLEAN_INSP_ACTIONS) - Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) + Database_Services('WriteDataRow', 'CLEAN_INSP', CIKeyID, CleanInspRec, True$, False$, True$) end else ErrorMessage = 'Tencor recipe ' : ScanRecipe : ' not found in SurfScan recipe list.' Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) @@ -1697,7 +1946,7 @@ Service ImportTencorData(RunData) // If statement to gate from production below PostStartTime = Time() if Indexc(ScanRecipe, 'POST', 1) then - //Locate 'POST' in ScanRecipe Using "" setting pPos then + //Locate 'POST' in ScanRecipe Using "" setting pPos then ReactRunRec = Xlate('REACT_RUN',RDSKeyID, '', 'X') WONo = ReactRunRec;//WONo WOStep = ReactRunRec;//WOStep @@ -1750,8 +1999,8 @@ Service ImportTencorData(RunData) //Here I am attempting to create the scan details. SODWaferArray = '' SODWaferArray = QA_Services('GetSODPerWafer', RDSKeyID, ScanRecipe, Timestamp) - - If SODWaferArray NE '' then + + If SODWaferArray NE '' then WaferNos = SODWaferArray<1> SODVals = SODWaferArray<2> SortVals = SODWaferArray<3> @@ -1767,7 +2016,7 @@ Service ImportTencorData(RunData) QA_Services('PostWaferImageRequest', RDSKeyID, WaferNo, ScanRecipe) end Next Wafer - end + end if exists Eq False$ then oCIParms := CleanInspRec ; CINo = obj_Clean_Insp('Create',oCIParms) @@ -1818,14 +2067,14 @@ Service ImportTencorData(RunData) Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : ErrorMessage) end If ErrorMessage NE '' then Error_Services('Add', ErrorMessage) - + end service Service ImportSP1Data(RunData) - + Machine = 'SP1' - + Timestamp = RunData<9> HazeAvg = RunData<10> RDSKeyID = RunData<28> @@ -1851,7 +2100,7 @@ Service ImportSP1Data(RunData) Convert @Lower_Case to @Upper_Case in ScanTool Convert @Lower_Case to @Upper_Case in CompareScanRecipe * Convert ' ' to '' in CompareScanRecipe - + Swap ' AM' with 'AM' in Timestamp Swap ' PM' with 'PM' in Timestamp Timestamp = IConv(Timestamp,'DT') @@ -1862,7 +2111,7 @@ Service ImportSP1Data(RunData) CassNo = RDSRec WorkOrder = Work_Order_Services('GetWorkOrder', WorkOrderNo, True$) GoSub ParseWorkOrder - + If RowExists('RDS', RDSKeyID) then // Try to read the CleanInsp datarow. Use this to identify the RDSKeyID. ReactRunRec = Database_Services('ReadDataRow', 'REACT_RUN', RDSKeyID) @@ -1950,14 +2199,14 @@ Service ImportSP1Data(RunData) end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + end service Service FormatLayerKeyID(RunDataLayer) - + If RunDataLayer NE '' then - + // Development code OriginalRunDataLayer = RunDataLayer CONVERT @LOWER_CASE TO @UPPER_CASE IN RunDataLayer @@ -1976,32 +2225,32 @@ Service FormatLayerKeyID(RunDataLayer) Error_Services('Add', 'Invalid RunDataLayer [' : OriginalRunDataLayer : '].') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) End Case - + end - + Response = RunDataLayer - + end service Service FormatZoneKeyID(RunDataZone) - + If RunDataZone NE '' then - + CONVERT @LOWER_CASE TO @UPPER_CASE IN RunDataZone Convert 'ABCDEFGHIJKLMNOPQRSTUVWXYZ- ' to '' in RunDataZone - + End - + Response = RunDataZone - + end service Service GetCalculatedZone(RDSKeyID, IsEpiPro, RunDataZone) - + CalculatedZone = '' - + If (RDSKeyID NE '') AND (IsEpiPro NE '') then If IsEpiPro then // This is Epi Pro, so there must be a zone. If a zone is specified then verify that there are RDS_TEST Keys @@ -2009,11 +2258,11 @@ Service GetCalculatedZone(RDSKeyID, IsEpiPro, RunDataZone) // RDS_TEST Key IDs. If so, then use that zone. If neither zone has RDS_TEST Key IDs then set an error. If // no zone is specified then verify if one and only one zone has RDS_TEST KeyIDS. If so, use the zone found. // If not, set an error. - + // Check for the RDS_TEST Key IDS for both zones first. Zone2RDSTestKeyIDs = XLATE('REACT_RUN', RDSKeyID, 'MET_KEYS_Z2', 'X') Zone1RDSTestKeyIDs = XLATE('REACT_RUN', RDSKeyID, 'MET_KEYS_Z1', 'X') - + // Run the tests. Begin Case Case (RunDataZone EQ 1) AND (Zone1RDSTestKeyIDs NE '') @@ -2036,16 +2285,16 @@ Service GetCalculatedZone(RDSKeyID, IsEpiPro, RunDataZone) end else Error_Services('Add', 'The RDSKeyID or IsEpiPro argument is missing.') end - + Response = CalculatedZone - + end service Service GetCalculatedLayer(RDSKeyID, Machine, RunDataZone, WoIsEpiPro, ScannedLayer) - + CalculatedLayer = '' - + If (RDSKeyID NE '') AND (Machine NE '') then Begin Case Case RunDataZone EQ 2 @@ -2063,16 +2312,16 @@ Service GetCalculatedLayer(RDSKeyID, Machine, RunDataZone, WoIsEpiPro, ScannedLa Case Machine _EQC 'BioRad' // Just get the last RDS Test Key ID whether there is one or multiple Key IDs. RDSTestKeyID = RDSTestKeyIDs[-1, 'B' : @VM] - + RDSTestRow = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKeyID) If Error_Services('NoError') then CalculatedLayer = RDSTestRow end - + If Dcount(RDSTestKeyIDs, @VM) GT 1 and WoIsEpiPro = False$ and (ScannedLayer _EQC 'L1' or ScannedLayer _EQC 'L2' or ScannedLayer _EQC '2') then CalculatedLayer = ScannedLayer end - + Case Machine _EQC 'CDE' ToolClassID = Metrology_Services('GetToolClassID', Machine) ToolMatch = False$ ; // Assume no match for now. @@ -2088,7 +2337,7 @@ Service GetCalculatedLayer(RDSKeyID, Machine, RunDataZone, WoIsEpiPro, ScannedLa end else Error_Services('Add', 'Unable to find the RDS Key ID [' : RDSKeyID : '] layer that has this Tool Class ID [' : ToolClassID : '].') end - + Case Machine _EQC 'HgCV' ToolClassID = Metrology_Services('GetToolClassID', Machine) ToolMatch = False$ ; // Assume no match for now. @@ -2104,7 +2353,7 @@ Service GetCalculatedLayer(RDSKeyID, Machine, RunDataZone, WoIsEpiPro, ScannedLa end else Error_Services('Add', 'Unable to find the RDS Key ID [' : RDSKeyID : '] layer that has this Tool Class ID [' : ToolClassID : '].') end - + End Case end else Error_Services('Add', 'No RDS Test Key IDS were found for RDS Key ID [' : RDSKeyID : '] and Zone Key ID [' : RunDataZone : '] in the [' : Service : '] service.') @@ -2113,16 +2362,16 @@ Service GetCalculatedLayer(RDSKeyID, Machine, RunDataZone, WoIsEpiPro, ScannedLa end else Error_Services('Add', 'The RDSKeyID or Machine argument is missing in the [' : Service : '] service.') end - + Response = CalculatedLayer - + end service Service GetToolClassID(Machine) - + ToolClassID = '' - + If Machine NE '' then Begin Case Case Machine _EQC 'BioRad' ; ToolClassID = 'FTIR' @@ -2133,14 +2382,14 @@ Service GetToolClassID(Machine) end else Error_Services('Add', 'The Machine argument is missing in the [' : Service : '] service.') end - + Response = ToolClassID - + end service Service LogResults(RDSKeyID, Machine, UID, Results) - + Begin Case Case Machine _EQC 'Tencor' LogHandle = objTencorLog @@ -2161,7 +2410,7 @@ Service LogResults(RDSKeyID, Machine, UID, Results) Case Otherwise$ LogHandle = objLog End Case - + LogData = '' LogData<1> = LoggingDTM LogData<2> = RDSKeyID ; // RDS Key ID @@ -2169,11 +2418,11 @@ Service LogResults(RDSKeyID, Machine, UID, Results) LogData<4> = UID ; // UID000=Success, UID001=Failure LogData<5> = Results Logging_Services('AppendLog', LogHandle, LogData, @RM, @FM) - + If UID NE 'UID000' then Error_Services('Add', UID:' ':Results) end - + end service //---------------------------------------------------------------------------------------------------------------------- @@ -2185,7 +2434,7 @@ end service // leaves as much history as possible in the system for as long as possible. //---------------------------------------------------------------------------------------------------------------------- Service RemoveOldMetrology() - + NextRDSNo = Database_Services('ReadDataRow', 'DICT.RDS', '%SK%') If Error_Services('NoError') then Flag = '' @@ -2225,7 +2474,7 @@ Service RemoveOldMetrology() end end end - + end service /* @@ -2247,7 +2496,7 @@ The service does the following actions: 5. Determines the spec slot by reading the WO_MAT_QA record -> SLOT field 6. If the detected RunDataSlot matches the spec slot, writes the datapoint to the WO_MAT_QA record - > RESULT field in the same @VM that the iterator is currently set to. */ -Service ImportBioRadEPPFQAData(RunData) +Service ImportBioRadEPPFQAData(RunData, FileName) Timestamp = RunData<2> WMOKeyID = RunData<6> @@ -2265,7 +2514,7 @@ Service ImportBioRadEPPFQAData(RunData) Decimals = 2 Positions = '' DataPoints = '' - + WMORec = Database_Services('ReadDataRow', 'WM_OUT', WMOKeyID) WOMatQAKey = Field(WMOKeyID, '*', 1) : '*' : Field(WMOKeyID, '*', 3) Loop @@ -2278,8 +2527,8 @@ Service ImportBioRadEPPFQAData(RunData) FieldPos += FieldPosIncrement Repeat Positions[-1, 1] = '' ; // Strip final @VM - DataPoints[-1, 1] = '' ; // Strip final @VM - + DataPoints[-1, 1] = '' ; // Strip final @VM + If Error_Services('NoError') then If Error_Services('HasError') then Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) @@ -2322,7 +2571,7 @@ Service ImportBioRadEPPFQAData(RunData) Case Slot EQ 'A' WaferIndex = 1 Case Otherwise$ - WaferIndex = Slot + WaferIndex = Slot End Case If DataSlotId EQ WaferIndex then WOMatQARec = DataPoints @@ -2338,7 +2587,7 @@ Service ImportBioRadEPPFQAData(RunData) end else Metrology_Services('LogResults', RDSNo@, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + end service @@ -2350,7 +2599,7 @@ end service // Removes rundata files from the Run Data Repository folder that are more than the desired number of days old. //---------------------------------------------------------------------------------------------------------------------- Service CleanRepository(NumDays) - + RepoPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Run Data Repository\' InitDir RepoPath:'*.txt' FileList = DirList() @@ -2363,7 +2612,7 @@ Service CleanRepository(NumDays) OSDelete RepoPath:Filename end Next Filename - + end service @@ -2377,7 +2626,7 @@ end service // Once the queue drops back down below the NumFiles variable, then the restriction will be put back into place. //---------------------------------------------------------------------------------------------------------------------- Service MonitorQueue(NumFiles) - + RunDataPath = Environment_Services('GetApplicationRootPath') : '\Metrology\Data\' InitDir RunDataPath:'*.txt' FileList = DirList() @@ -2386,7 +2635,7 @@ Service MonitorQueue(NumFiles) // Enable manual entry restriction - check current status to avoid unnecessary writes. CurrLockStatus = Database_Services('ReadDataRow', 'APP_INFO', 'ROTR_DATA_ENTRY_LOCK') If CurrLockStatus EQ False$ then - Database_Services('WriteDataRow', 'APP_INFO', 'ROTR_DATA_ENTRY_LOCK', True$) + Database_Services('WriteDataRow', 'APP_INFO', 'ROTR_DATA_ENTRY_LOCK', True$) end end else // Lift manual entry restriction - check current status to avoid unnecessary writes. @@ -2395,12 +2644,12 @@ Service MonitorQueue(NumFiles) Database_Services('WriteDataRow', 'APP_INFO', 'ROTR_DATA_ENTRY_LOCK', False$) end end - + end service Service GetIQSViolations() - + hSysLists = Database_Services('GetTableHandle', 'SYSLISTS') Lock hSysLists, ServiceKeyID then Response = 0 @@ -2414,10 +2663,10 @@ Service GetIQSViolations() PublishDateStart = Indexc(IQSResponse, 'Published: ', 1) + 11 PublishDateCnt = Indexc(IQSResponse, '

', 1) - PublishDateStart PublishDate = IQSResponse[PublishDateStart, PublishDateCnt] - + swap ' AM' with 'AM' in PublishDate swap ' PM' with 'PM' in PublishDate - + ConvDateTime = IConv(PublishDate, 'DT') DataTableBegin = Indexc(IQSResponse, '', 1) + 7 @@ -2429,7 +2678,7 @@ Service GetIQSViolations() swap '' with '' in DataTable DataTable = Delete(DataTable, 1,0,0) DataTable = Delete(DataTable, 1,0,0) - + FilteredData = '' for i = 1 to DCount(DataTable, @FM) if Indexc(DataTable, '', 1) then @@ -2442,7 +2691,7 @@ Service GetIQSViolations() FilteredData = Delete(FilteredData, i,1,0) //Delete useuless Entire Database column FilteredData = Delete(FilteredData, i,1,0) - + ParsedIQSData = FilteredData ParsedIQSData = FilteredData ParsedIQSData = FilteredData @@ -2458,7 +2707,7 @@ Service GetIQSViolations() Next i LastWriteTime = IConv(PublishDate, 'DT') ParsedIQSData = LastWriteTime - + Database_Services('WriteDataRow', 'CONFIG', 'IQS_VIOL_DATA', ParsedIQSData, True$, False$, True$) //Send status of last write time If SRP_Datetime('MinuteSpan', LastWriteTime, SRP_Datetime('Now')) GT 10 then @@ -2466,19 +2715,19 @@ Service GetIQSViolations() end else Mona_Services('SendBufferedStatus', 'IQS_VIOLATION_DATA', 'LastDataTimestamp', 'OK') end - + Reactor_Services('UpdateReactorIQSViolations') - + Unlock hSysLists, ServiceKeyID else Null end - + end service Service ScanRecipeMatchesRdsTestSpecThickMrecipe(RdsNo, RecipeLayer, RecipeInScan, RdsTestKeysFromRdsLayer, Zone='') If Unassigned(RecipeLayer) or RecipeLayer EQ '' then RecipeLayer = 'L1' end - + MatchFound = False$ ValidArgs = Assigned(RdsNo) and RdsNo NE '' and Assigned(RecipeInScan) and RecipeInScan NE '' ValidArgs = ValidArgs and Assigned(RdsTestKeysFromRdsLayer) and Dcount(RdsTestKeysFromRdsLayer, @VM) GT 0 @@ -2509,7 +2758,7 @@ Service ScanRecipeMatchesRdsTestSpecThickMrecipe(RdsNo, RecipeLayer, RecipeInSca Until MatchFound Next RDSTestKeyID end - + Response = MatchFound end service @@ -2517,13 +2766,13 @@ Service ScanNumDataPointsMatchesRdsTestSpecThickMPattern(RdsNo, RecipeLayer, Sca If Unassigned(RecipeLayer) or RecipeLayer EQ '' then RecipeLayer = 'L1' end - + MatchFound = False$ - + ValidArgs = Assigned(RdsNo) and RdsNo NE '' and Assigned(ScanNumDataPoints) and Num(ScanNumDataPoints) ValidArgs = ValidArgs and Assigned(RdsTestKeysFromRdsLayer) and Dcount(RdsTestKeysFromRdsLayer, @VM) GT 0 ValidArgs = ValidArgs and Assigned(ToolClass) and ToolClass NE '' - + If ValidArgs then For Each RDSTestKeyID in RdsTestKeysFromRdsLayer using @VM setting mkPos RdsTestRec = Database_Services('ReadDataRow', 'RDS_TEST', RDSTestKeyID) @@ -2552,7 +2801,7 @@ Service ScanNumDataPointsMatchesRdsTestSpecThickMPattern(RdsNo, RecipeLayer, Sca Until MatchFound Next RDSTestKeyID end - + Response = MatchFound end service @@ -2563,16 +2812,16 @@ end service ClearCursors: - + For Cursor = 1 to 8 ClearSelect Cursor Next Cursor - + return CalculateQAData: - + // Find the Min, Max, Average, Edge Mean Delta, and Range % values Sum = 0 Min = DataPoints<0,1> @@ -2617,15 +2866,15 @@ CalculateQAData: // Average NumDataPoints = DCount(DataPoints, @VM) Average = Sum / NumDataPoints - + return CalculateResults: - + If IsEpiPro then // Using logic adapted from COMM_DIALOG_EPI_PRO_MET > Done event handler. - + MetRec = RDSTestRec TestPointMap = BaseMapID MetNo = RDSTestKeyID @@ -2633,72 +2882,72 @@ CalculateResults: LSId = MetRec Zone = MetRec TestPointMap = MetRec - + IF Zone = '' THEN MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS','X') IF Zone = 1 THEN MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS_Z1','X') IF Zone = 2 THEN MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS_Z2','X') - + RdsLSKeys = XLATE('RDS',RDSNo,RDS_RDS_LAYER_KEYS$,'X') ReactorNo = XLATE('REACT_RUN',RDSNo,REACT_RUN_REACTOR$,'X') ReactType = XLATE('REACTOR',ReactorNo,REACTOR_REACT_TYPE$,'X') - + Continue = True$ ; // Assue we will continue for now. - + IF INDEX(RdsLSKeys,@VM,1) THEN * Multiple layers - + DepTimeTargets = '' LSCnt = COUNT(RdsLSKeys,@VM) + (RdsLSKeys NE '') - + DepTimeTargets = XLATE('RDS_LAYER',RdsLSKeys,RDS_LAYER_EPI_TIME$,'X') DepTimeTargets = OCONV(DepTimeTargets,'MD1') - + LS1DepTime = '' LS2DepTime = '' - + FOR I = 1 TO LSCnt RdsLSKey = RdsLSKeys<1,I> IF INDEX(RdsLSKey,'L1',1) THEN LS1DepTime = DepTimeTargets<1,I> IF INDEX(RdsLSKey,'L2',1) THEN LS2DepTime = DepTimeTargets<1,I> NEXT I - + IF LS1DepTime NE '' AND LS2DepTime NE '' THEN - + TotDepTime = LS1DepTime + LS2DepTime LS1Ratio = LS1DepTime/TotDepTime MetReadings = '' - + FOR I = 1 TO COUNT(MetKeys,@VM) + (MetKeys NE '') MetKey = MetKeys<1,I> LMetReadings = obj_RDS_Test('GetReadSet',MetKey) - + IF I = 1 THEN MetReadings<1> = LMetReadings<1> ;* Line Numbers MetReadings<3> = LMetReadings<3> ;* SheetRho MetReadings<4> = LMetReadings<4> ;* Hgcv END - + IF I = 2 THEN MetReadings<5> = LMetReadings<4> ;* Hgcv END - + IF I = 3 THEN MetReadings<2> = LMetReadings<2> ;* Thickness readings END - + NEXT I - + end else Continue = False$ end - + END ELSE LS1Ratio = 1 MetReadings = obj_RDS_Test('GetReadSet',MetNo) END - + if Continue then - + CONVERT @FM TO @RM IN MetReadings oTPM_Parms = TestPointMap:@RM:MetReadings Results = obj_Test_Point_Map('PointToResult',oTPM_Parms) @@ -2708,24 +2957,24 @@ CalculateResults: HgCV1ResReads = ThicknessArray<3> HgCV2ResReads = ThicknessArray<4> L1Ratio = LS1Ratio - + ReadingNos = '' - + FOR I = 1 TO 9 ReadingNos<1,I> = I NEXT I - + oTPM_Parms = TestPointMap:@RM:ReadingNos:@RM:ThickReads:@RM:SheetRhoReads:@RM:HgCV1ResReads:@RM:HgCV2ResReads - + EpiReads = obj_Test_Point_Map('ResultToPoint',oTPM_Parms) - + BEGIN CASE CASE Zone = '1' ; MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS_Z1','X') CASE Zone = '2' ; MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS_Z2','X') CASE 1 ; MetKeys = XLATE('REACT_RUN',RDSNo,'MET_KEYS','X') END CASE - - + + IF INDEX(MetKeys,@VM,1) THEN // MetNo might be from a layer other than the last one. Get the last layer and assign it to the MetNo // variable. @@ -2735,50 +2984,50 @@ CalculateResults: END oRTParms_L1 = '' oRTParms_L2 = '' - + FOR J = 1 TO COUNT(EpiReads<1>,@VM) + (EpiReads<1> NE '') oRTParms_L1 = OCONV(ICONV(EpiReads * L1Ratio, 'MD2'),'MD2') oRTParms_L2 = EpiReads - oRTParms_L1 - + IF EpiReads NE '' THEN - + oRTParms_L1 = EpiReads oRTParms_L2 = '' EpiReads = '' - + END ELSE oRTParms_L1 = '' oRTParms_L2 = '' END - + IF EpiReads NE '' THEN oRTParms_L1 = EpiReads END - + IF EpiReads NE '' THEN oRTParms_L2 = EpiReads END - + NEXT J - + CONVERT @FM TO @RM IN oRTParms_L1 CONVERT @FM TO @RM IN oRTParms_L2 - + obj_RDS_Test('SetReadSet',MetKeys<1,1>:@RM:oRTParms_L1) - + obj_RDS_Test('SetReadSet',MetKeys<1,2>:@RM:oRTParms_L2) - + END - + oRTParms = '' oRTParms = EpiReads oRTParms = EpiReads oRTParms = EpiReads - + CONVERT @FM TO @RM IN oRTParms - + obj_RDS_Test('SetReadSet',MetNo:@RM:oRTParms) - + end end else // Non-Epi Pro calculations. Using logic from adapted from COMM_RDS_TEST > ReadingsPC method. @@ -2797,7 +3046,7 @@ CalculateResults: Stats<5> = Iconv(Stats<5>, Conversion) Stats<6> = Iconv(Stats<6>, Conversion) Stats<7> = Iconv(Stats<7>, 'MD4') - + Begin Case Case Machine _EQC 'BioRad' RDSTestRec = Stats<1> @@ -2832,12 +3081,12 @@ CalculateResults: Readings = Oconv(Readings, Conversion) rv = Set_Status(0) Stats = obj_RDS_Test('CalcStats', Readings : @RM : Conversion) - + //JRO Logging StatsToLog = Stats swap @RM with @FM in StatsToLog Metrology_Services('LogResults', RDSKeyID, Machine, '', Service : ' : Stats: ' : StatsToLog) - + If Get_Status(ErrorCode) EQ 0 then Convert @RM to @FM in Stats Stats<1> = Iconv(Stats<1>, Conversion) @@ -2857,9 +3106,9 @@ CalculateResults: //JRO Logging Metrology_Services('LogResults', RDSKeyID, Machine, '', Service : ' : Stats To Write: ' : Stats) end - + Database_Services('WriteDataRow', 'RDS_TEST', RDSTestKeyID, RDSTestRec, True$, False$, True$) - + If Error_Services('NoError') then Metrology_Services('LogResults', RDSKeyID, Machine, 'UID000', Service : ' : Success - Calculated Results.') end else @@ -2867,12 +3116,12 @@ CalculateResults: end end end - + return ParseWorkOrder: - + If Assigned(objWorkOrder) else objWorkOrder = 0 If objWorkOrder LE 0 then SRP_JSON(objWorkOrder, 'PARSE', WorkOrder) @@ -2902,12 +3151,12 @@ ParseWorkOrder: PercentComplete = '' CustNameShort = '' end - + return LoadRunDataToDatabase: - + // Thickness OR Resistivity OR Hg Resistivity Section Read the tool class base map BaseMapID = RDSTestRec Convert @Lower_Case to @Upper_Case in BaseMapID @@ -2918,7 +3167,7 @@ LoadRunDataToDatabase: end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + // Read the metrology tool map PatternName = Trim(RDSTestRec) Convert @Lower_Case to @Upper_Case in PatternName @@ -2931,7 +3180,7 @@ LoadRunDataToDatabase: end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + ToolClassRow = Database_Services('ReadDataRow', 'TOOL_CLASS', ToolClassID) If Error_Services('NoError') then PatternNames = ToolClassRow @@ -2972,7 +3221,7 @@ LoadRunDataToDatabase: RDSTestRec = DataPoint Next ReadingCnt RDSTestRec = Timestamp - + // Save results if Not(ExistingData) OR IsViewerFile then Database_Services('WriteDataRow', 'RDS_TEST', RDSTestKeyID, RDSTestRec, True$, False$, True$) @@ -2993,11 +3242,11 @@ LoadRunDataToDatabase: Error_Services('Add', 'Unable to locate the pattern name [' : PatternName : '].') Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + end else Metrology_Services('LogResults', RDSKeyID, Machine, 'UID001', Service : ' : ' : Error_Services('GetMessage')) end - + return