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
|