#define _CRT_SECURE_NO_WARNINGS #define SCANANDOBS_EXPORT #include "runtime.h" #include #include #include #include "Atmcd32d.h" #include "CCD.h" #include "gratfocus.h" #include "scanobs.h" #include int take; int Scanpos_CCDframe; int Scanning; int take_thread = 0; void RunLink(ScanInfo* ScanI); int OpenScript(char *filename, unsigned long dwDevice); void DualBandScan(CCDInfo* CCD1, CCDInfo* CCD2, ScanInfo* ScanI); //----------------------------------------------- //STEP 1. ESTABLISH A LINK WITH PMAC (PMAC 컨트롤러를 OPEN하고 필요한 구동 변수를 초기화) SCANANDOBS_API int ScanOpen(ScanInfo* ScanI, char* str) { char strTemp[512], vs[30], ds[30], buff[128]; // Initialize ScanI->status = -1; // not operated ScanI->DriverOpen = 0; ScanI->PmacLib = NULL; ScanI->dwDevice = 0; ScanI->PmacAccessible = 0; RunLink(ScanI); ScanI->DriverOpen = DeviceOpen(ScanI->dwDevice);//OPEN PMAC if (ScanI->DriverOpen) { //Print string 'Device is opened' //Get Pmac info & print DeviceGetRomVersion(ScanI->dwDevice, vs, 30); DeviceGetRomDate(ScanI->dwDevice, ds, 30); //Set environment parameters & display the result DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i900=3"); sprintf(str, "i900 set status: "); strcat(str, strTemp); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i125=$80C000"); strcat(str, "\ni125 set status: "); strcat(str, strTemp); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i117=0.5"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i130=40000"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i131=1800"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i132=1800"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i133=40000"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "i135=0"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255,"i900"); strcat(str,"\ni900 = "); strcat(str, strTemp); DeviceGetResponse(ScanI->dwDevice, strTemp, 255,"i125"); strcat(str,"\ni125 = "); strcat(str, strTemp); // DeviceGetResponse((*ScanI).dwDevice, strTemp, 255,"/a"); // DeviceGetResponse((*ScanI).dwDevice, strTemp, 255,"j-"); // DeviceGetResponse((*ScanI).dwDevice, strTemp, 255,"hm"); //Read CURRENT position ScanI->PmacAccessible = 1; //1 IF (*ScanI).DriverOpen=1 ScanI->status = 1; //turn on scanner } else return ERR_OpnDevice; return 1; } //스캐너가 구동하는데 있어 필요한 dll 파일과, 자주 쓰는 함수를 로드함. void RunLink(ScanInfo* ScanI) { ScanI->PmacLib = LoadLibrary(L"PComm64.dll"); DeviceOpen = (OPENPMACDEVICE)GetProcAddress(ScanI->PmacLib,"OpenPmacDevice"); DeviceClose = (CLOSEPMACDEVICE)GetProcAddress(ScanI->PmacLib,"ClosePmacDevice"); DeviceGetRomVersion = (GETROMVERSIONA)GetProcAddress(ScanI->PmacLib,"PmacGetRomVersionA"); DeviceGetRomDate = (GETROMDATEA)GetProcAddress(ScanI->PmacLib,"PmacGetRomDateA"); DeviceGetResponse = (GETRESPONSEA)GetProcAddress(ScanI->PmacLib,"PmacGetResponseA"); DeviceDownload = (DOWNLOADA)GetProcAddress(ScanI->PmacLib, "PmacDownloadA"); DeviceGetBuffer = (GETBUFFERA)GetProcAddress(ScanI->PmacLib, "PmacGetBufferA"); DeviceSetQuickGather = (SETQUICKGATHER)GetProcAddress(ScanI->PmacLib,"PmacSetQuickGather"); DeviceCollectGatherData = (COLLECTGATHERDATA)GetProcAddress(ScanI->PmacLib,"PmacCollectGatherData"); DeviceGetGatherSamples = (GETGATHERSAMPLES)GetProcAddress(ScanI->PmacLib, "PmacGetGatherSamples"); DeviceGetIVariableLong = (GETIVARIABLELONG)GetProcAddress(ScanI->PmacLib, "PmacGetIVariableLong"); Sleep(1000); } SCANANDOBS_API char* CloseDevice(ScanInfo* ScanI) { char str[50]; ScanI->PmacAccessible = 0; //end of Thread if (ScanI->DriverOpen) { ScanI->DriverOpen = !DeviceClose(ScanI->dwDevice); sprintf(str, "Device is Closed! %d \n ", ScanI->DriverOpen); } if (ScanI->PmacLib) { FreeLibrary(ScanI->PmacLib);//FREEING HANDLE ScanI->PmacLib = NULL; } ScanI->status=0; //turn off scanner return str; } SCANANDOBS_API int ScanCommandWrite(ScanInfo* ScanI, int exptime) { //extern char ccd_path[256]; char Buff1[300] = "fiss.head"; char Buff2[300] = "fiss.tail"; char Buff[300] = "FISS.pmc"; char* Script1; char* Script2; unsigned n_byte1; unsigned n_byte2; int resOS; int ta = 30; int ts = 15; int dwell; FILE *fp1; FILE *fp2; FILE *fp3; if((fp1=fopen(Buff1, "rb")) != NULL && (fp2=fopen(Buff2, "rb")) != NULL) { fseek(fp1, 0, SEEK_END); n_byte1 = ftell( fp1 ); Script1 = (char*)malloc( n_byte1+1 ); fseek(fp1, 0, SEEK_SET); fread(Script1, n_byte1, 1, fp1); Script1[n_byte1] = 0; fclose(fp1); fseek(fp2, 0, SEEK_END); n_byte2 = ftell( fp2 ); Script2 = (char *)malloc( n_byte2+1 ); fseek(fp2, 0, SEEK_SET); fread(Script2, n_byte2, 1, fp2); Script2[n_byte2] = 0; fclose(fp2); fp3 = fopen( Buff, "wb"); fwrite(Script1, n_byte1, 1, fp3); fputs("\r\n", fp3); if( (ScanI->scanSpeed == 0.) && (ScanI->scanDist == 0)) //spectrograph mode { /* fprintf(fp3, "i130=120000\r\ni131=4000\r\ni132=4000\r\ni133=40000\r\ni134=0\r\ni135=20000\r\ninc\r\nta%3.f\r\nts%3.f\r\np1=0\r\nWhile(p1<%4d)\r\nx%4.f\r\ndwell%3.f\r\np1=p1+1\r\nEndWhile\r\n" , 0.350*ScanI->stepTime, 0.170*ScanI->stepTime, ScanI->number, ScanI->stepSize, 0.300*ScanI->stepTime); */ dwell = 10; ScanI->stepTime = 26 * 2 + exptime + dwell; fprintf(fp3, "i130=120000\r\ni131=4000\r\ni132=4000\r\ni133=40000\r\ni134=0\r\ni135=20000\r\ninc\r\nta%3.f\r\nts%3.f\r\np1=0\r\nWhile(p1<%4d)\r\nx%4.f\r\ndwell%3.f\r\np1=p1+1\r\nEndWhile\r\n" , 26., 13., ScanI->number+1, ScanI->stepSize, (float)(exptime+dwell)); } if((ScanI->stepTime == 0) && (ScanI->stepSize == 0)) //imaging mode { ScanI->stepSize = ScanI->scanDist/(float)ScanI->number+1; fprintf(fp3, "i130=40000\r\ni131=1800\r\ni132=1800\r\ni133=40000\r\ni134=0\r\ni135=0\r\nabs\r\nta100\r\nts50\r\nf%2.f\r\nx%5.f\r\n", ScanI->scanSpeed, ScanI->scanDist); } fputs("\r\n", fp3); fwrite(Script2, n_byte2, 1, fp3); fclose(fp3); resOS = OpenScript(Buff, ScanI->dwDevice); free(Script1); free(Script2); } return resOS; } int OpenScript(char *filename, unsigned long dwDevice) { static FILE *fp; int macro = 1; int map = 1; int log = 1; int dnld = 1; long result; // 1. File open if((fp=fopen(filename, "rt")) == NULL) return ERR_OpenScript; fclose(fp); Sleep(1000); result = DeviceDownload(dwDevice, NULL, NULL, NULL, filename, macro, map, log, dnld); //DOWNLOAD (PCHAR) Sleep(1000); if(result != 0){ return 1; } return ERR_dwDevice; } SCANANDOBS_API char* KillMotor(unsigned long dwDevice) { static char strTemp[255]; DeviceGetResponse( dwDevice, strTemp, 255, "#1k"); return strTemp; } SCANANDOBS_API void ReadScanPosition(ScanInfo* ScanI) { static char strTemp[255]; // DeviceGetResponse( (*ScanI).dwDevice, strTemp, 255, "m101"); DeviceGetResponse(ScanI->dwDevice, strTemp, 255, "#1P"); ScanI->position = atof(strTemp); ScanI->scanpos = ScanI->position/10; } //STEP 2. TURNING ON THE MOTOR AMP (모터에 전원을 인가한다.) SCANANDOBS_API void ampon(int* AmpOnSeq, int* zeroStep, unsigned long dwDevice, char* resStr) { char strTemp[255]; char strTemp2[255]; char target[255]; switch(*AmpOnSeq) { case 0: //전원 인가 DeviceGetResponse( dwDevice, strTemp, 255,"#1o0"); DeviceGetResponse( dwDevice, strTemp, 255,"#1j/"); //positive limit? Sleep(100); //AMP작동 여부 확인 DeviceGetResponse( dwDevice, strTemp, 255,"m139->Y:$814,14"); DeviceGetResponse( dwDevice, strTemp, 255,"m138->X:$3D,18"); DeviceGetResponse( dwDevice, strTemp, 255,"m139"); DeviceGetResponse( dwDevice, strTemp2, 255,"m138"); if (*strTemp == '0' || *strTemp2 == '1') { sprintf(resStr, "Amp is not powered.\n"); break; } else sprintf(resStr, "Amp is turned ON\n"); DeviceGetResponse( dwDevice, strTemp, 255,"m132->X:$3D,22"); DeviceGetResponse( dwDevice, strTemp, 255,"j-"); //negative limit *AmpOnSeq = 10; break; case 10: DeviceGetResponse( dwDevice, strTemp, 255,"m132"); if( *strTemp!='0' ) { //DeviceGetResponse( dwDevice, strTemp, 255,"#1j/"); Sleep(100); DeviceGetResponse( dwDevice, strTemp, 255,"hm"); //homing *AmpOnSeq = 20; break; } break; case 20: DeviceGetResponse( dwDevice, strTemp, 255,"m145->Y:$814,10"); *AmpOnSeq = 21; break; case 21: DeviceGetResponse( dwDevice, strTemp, 255,"m145"); if( *strTemp!='0') { *AmpOnSeq = 22; break; } break; case 22: //////////////////////////////////////////////// DeviceGetResponse( dwDevice, strTemp, 255,"m140"); if( *strTemp!='0') { *zeroStep+=75000; sprintf(target,"#1J=%d",*zeroStep); DeviceGetResponse(dwDevice, strTemp, 255, target); *AmpOnSeq = 23; break; } break; case 23: DeviceGetResponse( dwDevice, strTemp, 255, "m140"); if( *strTemp!='0') { GetScanResponse("HMZ", dwDevice, resStr); *zeroStep = 0; *AmpOnSeq = 30; } break; } } SCANANDOBS_API void GetScanResponse(char *string, unsigned long dwDevice, char* strRes) { DeviceGetResponse( dwDevice, strRes, 255, string); } //DISPLAY SCANNER CONDITION SCANANDOBS_API void Monitor(ScanStat* ScanS, unsigned long dwDevice) { char strTemp[255]; DeviceGetResponse( dwDevice, strTemp, 255, "m140"); ScanS->inPosition = atoi(strTemp); DeviceGetResponse( dwDevice, strTemp, 255, "m137"); ScanS->motorRun = atoi(strTemp); DeviceGetResponse( dwDevice, strTemp, 255, "m131"); ScanS->pLimit = atoi(strTemp); DeviceGetResponse( dwDevice, strTemp, 255, "m132"); ScanS->nLimit=atoi(strTemp); } //GATHERING-RELATED FUNCTION(모터 구동 데이터를 Gathering한 후 그래프로 출력.) SCANANDOBS_API int UploadQuickGather(int bSaveFile, unsigned long dwDevice) { char response[256] = ""; int i; long nMotor; UINT nNumSources, nNumSamples; long Ix08; double dSFactor0, dSFactor1, dSFactor2; // 읽어 온 값의 Scale Factor double *pRdData0, *pRdData1, *pRdData2; double *m_pGatData0; double *m_pGatData1; double *m_pGatData2; double *m_pGatTime;//put for x axis drawing nMotor = 1; // 1번 모터에 대해서 설정하였으므로... // Data Gathering된 Source의 개수와 Sample 개수를 얻어온다. // 이 함수에서 내부적으로 "LIST GAT"에 의한 Gathering 데이터를 가지고 옵니다. if ( DeviceCollectGatherData(dwDevice, &nNumSources, &nNumSamples)==0 ) return 0; m_pGatData0 = (double *)calloc (nNumSamples, sizeof(double)); m_pGatData1 = (double *)calloc (nNumSamples, sizeof(double)); m_pGatData2 = (double *)calloc (nNumSamples, sizeof(double)); m_pGatTime = (double *)calloc (nNumSamples, sizeof(double)); pRdData0 = (double *)calloc (nNumSamples, sizeof(double)); pRdData1 = (double *)calloc (nNumSamples, sizeof(double)); pRdData2 = (double *)calloc (nNumSamples, sizeof(double)); // 이미 Gathering된 데이터에서 각 해당 Source 별의 데이터를 nNumSamples 개수만큼 가져옵니다.. if ( DeviceGetGatherSamples(dwDevice, 0, &nNumSamples, pRdData0, nNumSamples)==0 ) // 첫번째 소스에 해당하는 데이터를 가져옵니다. goto error_ret; if ( DeviceGetGatherSamples(dwDevice, 1, &nNumSamples, pRdData1, nNumSamples)==0 ) // 두번째 소스에 해당하는 데이터를 가져옵니다. goto error_ret; if ( DeviceGetGatherSamples(dwDevice, 2, &nNumSamples, pRdData2, nNumSamples)==0 ) // 세번째 소스에 해당하는 데이터를 가져옵니다. goto error_ret; Ix08 = DeviceGetIVariableLong(dwDevice, nMotor*100+8, 96); // Ix08을 읽어 와서 Scale을 계산하는데 사용합니다. dSFactor0 = 1.0/(Ix08*32.0); // Commanded Position ( 1/(Ix08*32) cts ) dSFactor1 = 1.0/(Ix08*32.0); // Actual Position ( 1/(Ix08*32) cts ) dSFactor2 = 1.0/256.0; // DAC ( 1/256 ) for ( i = 0; i<(int)nNumSamples; i++ ) { m_pGatData0[i] = pRdData0[i] * dSFactor0; // Commanded Pos m_pGatData1[i] = pRdData1[i] * dSFactor1; // Actual Pos m_pGatData2[i] = pRdData2[i] * dSFactor2; // DAC Output m_pGatTime[i]= (float)i*5.*3703707./8388608./1000.; } if ( bSaveFile ) { FILE *pfp; char chrFilename[50] = "GatherResult.txt"; //char Buff[300]="FISS.pmc"; if ( (pfp=fopen(chrFilename, "wt+"))==NULL ) goto error_ret; fprintf(pfp, "Quick Gathering Sample Data File\n"); fprintf(pfp, "[Commanded Position]\t[Actual Position]\t[DAC Output]\n"); for ( i = 0; i<(int)nNumSamples; i++ ) { fprintf(pfp, "%20.3lf\t%20.3lf\t%20.3lf\t%20.3lf\n", m_pGatData0[i], m_pGatData1[i], m_pGatData2[i], m_pGatTime[i]); } fclose(pfp); } free(pRdData0); free(pRdData1); free(pRdData2); free(m_pGatData0); free(m_pGatData1); free(m_pGatData2); free(m_pGatTime); return 1; error_ret: free(pRdData0); free(pRdData1); free(pRdData2); free(m_pGatData0); free(m_pGatData1); free(m_pGatData2); free(m_pGatTime); return 0; } SCANANDOBS_API void StructTestScanner(ScanInfo* ScanI, ScanStat* ScanS) { ScanI->stepSize = 32.578; ScanI->DriverOpen = -1; ScanI->PmacLib = LoadLibrary("PComm64.dll"); ScanI->dwDevice = 1234; ScanI->scanDist = 37.543; ScanI->scanSpeed = 0.22; ScanI->number = 120; ScanI->PmacAccessible = 1; ScanS->nLimit = 23; ScanS->inPosition = 852; ScanS->pLimit = 160; ScanS->motorRun = 22; ScanI->scanpos = 23.4; ScanI->status = 1; ScanI->position = 254.88; ScanI->stepTime = 0.023; } // Observation SCANANDOBS_API int TakeFlat(CCDInfo* CCD1, CCDInfo* CCD2, ScanInfo* ScanI, ScanStat* ScanS, int step, int camMode, int* run) // will be moved to other source code. { int shift[7]={-110,-90,-30,0,20,80,115}; int ii,j,k,startpoint1,startpoint2; int flatstart1,flatstart2; int errorValue, nStatus; int scanmod=-1; int ptemp=0; int p1=0; int currentPosition, targetPosition; float* FlatData1; float* FlatData2; char response[255]; LARGE_INTEGER gStart, gEnd; unsigned short* dumpD1; unsigned short* dumpD2; dumpD1 = (unsigned short*)malloc(CCD1->nx * CCD1->ny * sizeof(unsigned short)); dumpD2 = (unsigned short*)malloc(CCD2->nx * CCD2->ny * sizeof(unsigned short)); CCD1->FlatCube = (float*)malloc(CCD1->nx * CCD1->ny * 7 * sizeof(float)); CCD2->FlatCube = (float*)malloc(CCD2->nx * CCD2->ny * 7 * sizeof(float)); FlatData1 = (float*)malloc(CCD1->nx * CCD1->ny * sizeof(float)); FlatData2 = (float*)malloc(CCD2->nx * CCD2->ny * sizeof(float)); if (camMode == 0) { if ((CCD1->status != 1) || (ScanI->status != 1)) return ERR_TakeFlat; scanmod = CCD1->ScanMode; } else if (camMode == 1) { if ((CCD2->status != 1) || (ScanI->status != 1)) return ERR_TakeFlat; scanmod = CCD2->ScanMode; } else if (camMode == 2) { scanmod = CCD1->ScanMode; if((CCD1->status != 1) || (ScanI->status != 1) || (CCD2->status != 1)) return ERR_TakeFlat; } for(ii=0; ii<7; ii++) //number of moving grating { targetPosition = step + shift[ii]; MoveGrating(targetPosition); do{ currentPosition = -1*ReadPosition(1); Sleep(50); } while(abs(targetPosition-currentPosition) > 5); Sleep(50); if (camMode == 0) { memset(CCD1->RawData, 0, CCD1->nx * CCD1->ny * CCD1->ScanNum * sizeof(WORD)); memset(FlatData1, 0, CCD1->nx * CCD1->ny * sizeof(float)); } else if (camMode == 1) { memset(CCD2->RawData, 0, CCD2->nx * CCD2->ny * CCD2->ScanNum * sizeof(WORD)); memset(FlatData2, 0, CCD2->nx * CCD2->ny * sizeof(float)); } else if (camMode == 2) { memset(CCD1->RawData, 0, CCD1->nx * CCD1->ny * CCD1->ScanNum * sizeof(WORD)); memset(CCD2->RawData, 0, CCD2->nx * CCD2->ny * CCD2->ScanNum * sizeof(WORD)); memset(FlatData1, 0, CCD1->nx * CCD1->ny * sizeof(float)); memset(FlatData2, 0, CCD2->nx * CCD2->ny * sizeof(float)); } do { Monitor(ScanS, ScanI->dwDevice); ReadScanPosition(ScanI); }while(!((ScanI->scanpos < 1) && (ScanI->scanpos > -1) && (ScanS->inPosition==1))) ; //Check the scanner position before start acquisition marktime(CCD1->stTime, &gStart); if (camMode == 0) { SetCurrentCamera(CCD1->camera); errorValue = StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue != DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); } else if (camMode == 1) { SetCurrentCamera(CCD2->camera); errorValue=StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue!=DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); } else if (camMode == 2) { SetCurrentCamera(CCD1->camera); errorValue = StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue != DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); SetCurrentCamera(CCD2->camera); errorValue=StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue!=DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); } // start scanning if(DeviceSetQuickGather(ScanI->dwDevice, GATHER_COM1|GATHER_ENC1|GATHER_DAC1, 1) == 0) return ERR_QuickGather; DeviceGetResponse(ScanI->dwDevice, response, 255, "I19=5");// Data Gathering Selection Mask 설정 ( I21 ~ I44 에 해당하는 24 Source에 대한 Mask Bit 설정) DeviceGetResponse(ScanI->dwDevice, response, 255, "I20=7"); // I21,22,23 소스만 Gathering하도록 설정 DeviceGetResponse(ScanI->dwDevice, response, 255, "CLOSE"); DeviceGetResponse(ScanI->dwDevice, response, 255, "END GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEL GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEF GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "GAT &1 b1 r"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m180->X:$818,0"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m145->Y:$814,10"); Scanning=1; while(1) { DeviceGetResponse(ScanI->dwDevice, response, 255, "m180"); if (*response=='0') { Scanning=0; break; } switch(scanmod) { case 0: //spectrograph DeviceGetResponse(ScanI->dwDevice, response, 255, "p1"); ReadScanPosition(ScanI); p1=atoi(response); if ((p1-ptemp)>0 && (ScanI->position - (double)p1 * (double)ScanI->stepSize*10) >=0 ) { Scanpos_CCDframe = p1; SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD1, 0); else DataDump(CCD1, Scanpos_CCDframe-1); SetCurrentCamera(CCD2->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD2, 0); else DataDump(CCD2, Scanpos_CCDframe-1); } break; case 1: //imaging sprintf(response, "%d", p1); p1=atoi(response); if (ScanI->position - (double)p1 * (double)ScanI->stepSize*10 >= (double)ScanI->stepSize*5 ) { p1++; Scanpos_CCDframe=p1; SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD1, 0); else DataDump(CCD1, Scanpos_CCDframe-1); SetCurrentCamera(CCD2->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD2, 0); else DataDump(CCD2, Scanpos_CCDframe-1); } break; } *run = ii; } marktime(CCD1->edTime, &gEnd); CCD1->elapseTime = time_difference(gStart, gEnd); strcpy(CCD2->stTime, CCD1->stTime); strcpy(CCD2->edTime, CCD1->edTime); CCD2->elapseTime = CCD1->elapseTime; switch (camMode) { case 0: for(k = 0; k < CCD1->ScanNum; k++) //number of frame { startpoint1 = CCD1->nx * CCD1->ny * k; for(j = 0; j < CCD1->nx * CCD1->ny; j++) FlatData1[j] += CCD1->RawData[j+startpoint1]; } flatstart1 = CCD1->nx * CCD1->ny * ii; for(k = 0; k < CCD1->nx * CCD1->ny; k++) { FlatData1[k] = FlatData1[k] / (float)(CCD1->ScanNum) - (float)CCD1->BiasDark[k]; CCD1->FlatCube[k+flatstart1] = FlatData1[k]; } break; case 1: for(k = 0; k < CCD2->ScanNum; k++) //number of frame { startpoint1 = CCD2->nx * CCD2->ny * k; for(j = 0; j < CCD2->nx * CCD2->ny; j++) FlatData1[j] += CCD2->RawData[j+startpoint1]; } flatstart1 = CCD2->nx * CCD2->ny * ii; for(k = 0; k < CCD2->nx * CCD2->ny; k++) { FlatData1[k] = FlatData1[k] / (float)(CCD2->ScanNum) - (float)CCD2->BiasDark[k]; CCD1->FlatCube[k+flatstart1] = FlatData1[k]; } break; case 2: for(k = 0; k < CCD1->ScanNum; k++) //number of frame { startpoint1 = CCD1->nx * CCD1->ny * k; for(j = 0; j < CCD1->nx * CCD1->ny; j++) FlatData1[j] += CCD1->RawData[j+startpoint1]; startpoint2 = CCD2->nx * CCD2->ny * k; for(j = 0; j < CCD2->nx * CCD2->ny; j++) FlatData2[j] += CCD2->RawData[j+startpoint2]; } flatstart1 = CCD1->nx * CCD1->ny * ii; flatstart2 = CCD2->nx * CCD2->ny * ii; for(k = 0; k < CCD1->nx * CCD1->ny; k++) { FlatData1[k] = FlatData1[k] / (float)(CCD1->ScanNum) - (float)CCD1->BiasDark[k]; CCD1->FlatCube[k+flatstart1] = FlatData1[k]; } for(k = 0; k < CCD2->nx * CCD2->ny; k++) { FlatData2[k] = FlatData2[k] / (float)(CCD2->ScanNum) - (float)CCD2->BiasDark[k]; CCD2->FlatCube[k+flatstart2] = FlatData2[k]; } break; } } switch (camMode) { case 0: SaveFlatFits(*CCD1, 7); free(CCD1->FlatCube); break; case 1: SaveFlatFits(*CCD2, 7); free(CCD2->FlatCube); break; case 2: SaveFlatFits(*CCD1, 7); SaveFlatFits(*CCD2, 7); free(CCD1->FlatCube); free(CCD2->FlatCube); break; } targetPosition = step; //return original position MoveGrating(targetPosition); do{ currentPosition = -1*ReadPosition(1); Sleep(50); } while(abs(targetPosition-currentPosition) > 5); Sleep(50); return 1; } SCANANDOBS_API int SingleBandObservation(CCDInfo* CCD, ScanInfo* ScanI, ScanStat* ScanS, int nRun, int* obsThread, int* run) { LARGE_INTEGER gStart, gEnd; int errorValue, nStatus; char response[255]; int ptemp=0; int p1=0; int i; unsigned short* dumpD; dumpD = (unsigned short*)malloc(CCD->nx * CCD->ny * sizeof(unsigned short)); SetCurrentCamera(CCD->camera); if(CCD->ScanNum <= 0) { return ERR_ScanNum; } else if (CCD->ScanNum == 1) // single mode, 스캔하지 않고 찍는다. { for(i=0; istTime, &gStart); memset(CCD->RawData, 0, CCD->nx * CCD->ny * sizeof(unsigned short)); TakeImage(); DataDump(CCD, 0); marktime(CCD->edTime, &gEnd); CCD->elapseTime = time_difference(gStart, gEnd); SaveFits(*CCD); *run = i; } } else if (CCD->ScanNum > 1) { if(CCD->AcqMode == 1) //scan (step) { // observation start for(i=0; iRawData, 0, CCD->nx * CCD->ny * CCD->ScanNum * sizeof(unsigned short)); memset(dumpD, 0, CCD->nx * CCD->ny * sizeof(unsigned short)); do { Monitor(ScanS, ScanI->dwDevice); ReadScanPosition(ScanI); }while(!((ScanI->scanpos < 1) && (ScanI->scanpos > -1) && (ScanS->inPosition==1))) ; //Check the scanner position before start acquisition // acqusition at the home position. marktime(CCD->stTime, &gStart); errorValue = StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue != DRV_SUCCESS) return ERR_initialize; }while (nStatus != DRV_IDLE); // run scanner if(DeviceSetQuickGather(ScanI->dwDevice, GATHER_COM1|GATHER_ENC1|GATHER_DAC1, 1) == 0) return ERR_QuickGather; DeviceGetResponse(ScanI->dwDevice, response, 255, "I19=5");// Data Gathering Selection Mask 설정 ( I21 ~ I44 에 해당하는 24 Source에 대한 Mask Bit 설정) DeviceGetResponse(ScanI->dwDevice, response, 255, "I20=7"); // I21,22,23 소스만 Gathering하도록 설정 DeviceGetResponse(ScanI->dwDevice, response, 255, "CLOSE"); DeviceGetResponse(ScanI->dwDevice, response, 255, "END GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEL GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEF GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "GAT &1 b1 r"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m180->X:$818,0"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m145->Y:$814,10"); while(1) { DeviceGetResponse(ScanI->dwDevice, response, 255, "m180"); if (*response=='0') { Scanning=0; break; } // scanning complete switch(CCD->ScanMode) { case 0: //spectrograph DeviceGetResponse(ScanI->dwDevice, response, 255, "p1"); ReadScanPosition(ScanI); p1 = atoi(response); if ((p1-ptemp)>0 && (ScanI->position - (double)p1 * (double)ScanI->stepSize*10) >=0 ) { Scanpos_CCDframe=p1; TakeImage(); if (Scanpos_CCDframe == CCD->ScanNum) DataDump(dumpD, 0); else DataDump(CCD, Scanpos_CCDframe-1); } break; case 1: //imaging sprintf(response, "%d", p1); p1=atoi(response); if (ScanI->position - (double)p1 * (double)ScanI->stepSize*10 >= (double)ScanI->stepSize*5 ) { p1++; Scanpos_CCDframe=p1; TakeImage(); if (Scanpos_CCDframe > CCD->ScanNum) DataDump(dumpD, 0); else DataDump(CCD, Scanpos_CCDframe-1); } break; } } Sleep(30); marktime(CCD->edTime, &gEnd); CCD->elapseTime = time_difference(gStart, gEnd); SaveFits(*CCD); *run = i; } } else if (CCD->AcqMode == 6) { for (i=0; iRawData, 0, CCD->nx * CCD->ny * CCD->ScanNum * sizeof(unsigned short)); marktime(CCD->stTime, &gStart); TakeImage_FTmode(CCD); marktime(CCD->edTime, &gEnd); CCD->elapseTime = time_difference(gStart, gEnd); SaveFits(*CCD); *run = i; } } } return 1; } SCANANDOBS_API int DualBandObservation(CCDInfo* CCD1, CCDInfo* CCD2, ScanInfo* ScanI, ScanStat* ScanS, int nRun, int* obsThread, int* run) { LARGE_INTEGER gStart, gEnd; char response[255]; int i; if (CCD1->ScanNum <= 0) return ERR_ScanNum; else if (CCD1->ScanNum == 1) // single mode, 스캔하지 않고 찍는다. { for(i=0; iRawData, 0, CCD1->nx * CCD1->ny * sizeof(unsigned short)); memset(CCD2->RawData, 0, CCD2->nx * CCD2->ny * sizeof(unsigned short)); marktime(CCD1->stTime, &gStart); SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); DataDump(CCD1, 0); SetCurrentCamera(CCD2->camera); DataDump(CCD2, 0); marktime(CCD1->edTime, &gEnd); CCD1->elapseTime = time_difference(gStart, gEnd); strcpy(CCD2->stTime, CCD1->stTime); strcpy(CCD2->edTime, CCD1->edTime); CCD2->elapseTime = CCD1->elapseTime; SaveFits(*CCD1); SaveFits(*CCD2); *run=i; } } else if (CCD1->ScanNum > 1) { if(CCD1->AcqMode == 1) //scan (step) { //observation start for(i=0; iRawData, 0, CCD1->nx * CCD1->ny * CCD1->ScanNum * sizeof(unsigned short)); memset(CCD2->RawData, 0, CCD2->nx * CCD2->ny * CCD2->ScanNum * sizeof(unsigned short)); do { Monitor(ScanS, ScanI->dwDevice); ReadScanPosition(ScanI); }while(!((ScanI->scanpos < 1) && (ScanI->scanpos > -1) && (ScanS->inPosition==1))) ; //Check the scanner position before start acquisition // acqusition at the scanner home position. reducing frame loss marktime(CCD1->stTime, &gStart); DualBandScan(CCD1, CCD2, ScanI); Sleep(30); marktime(CCD1->edTime, &gEnd); CCD1->elapseTime = time_difference(gStart, gEnd); strcpy(CCD2->stTime, CCD1->stTime); strcpy(CCD2->edTime, CCD1->edTime); CCD2->elapseTime = CCD1->elapseTime; SaveFits(*CCD1); SaveFits(*CCD2); *run = i; } } else if (CCD1->AcqMode == 6) { for (i=0; iRawData, 0, CCD1->nx * CCD1->ny * CCD1->ScanNum * sizeof(unsigned short)); memset(CCD2->RawData, 0, CCD2->nx * CCD2->ny * CCD2->ScanNum * sizeof(unsigned short)); marktime(CCD1->stTime, &gStart); TakeImage_FTmode(CCD1); marktime(CCD1->edTime, &gEnd); CCD1->elapseTime = time_difference(gStart, gEnd); strcpy(CCD2->stTime, CCD1->stTime); strcpy(CCD2->edTime, CCD1->edTime); CCD2->elapseTime = CCD1->elapseTime; SaveFits(*CCD1); SaveFits(*CCD2); *run = i; } } } return 1; } void DualBandScan(CCDInfo* CCD1, CCDInfo* CCD2, ScanInfo* ScanI) { int errorValue, nStatus; int ptemp=0; int p1=0; char response[255]; unsigned short* dumpD1; unsigned short* dumpD2; dumpD1 = (unsigned short*)malloc(CCD1->nx * CCD1->ny * sizeof(unsigned short)); dumpD2 = (unsigned short*)malloc(CCD2->nx * CCD2->ny * sizeof(unsigned short)); SetCurrentCamera(CCD1->camera); errorValue = StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue != DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); SetCurrentCamera(CCD2->camera); errorValue=StartAcquisition(); do { errorValue = GetStatus(&nStatus); if(errorValue!=DRV_SUCCESS) return ERR_initialize; } while (nStatus != DRV_IDLE); if(DeviceSetQuickGather(ScanI->dwDevice, GATHER_COM1|GATHER_ENC1|GATHER_DAC1, 1) == 0) return ERR_QuickGather; DeviceGetResponse(ScanI->dwDevice, response, 255, "I19=5");// Data Gathering Selection Mask 설정 ( I21 ~ I44 에 해당하는 24 Source에 대한 Mask Bit 설정) DeviceGetResponse(ScanI->dwDevice, response, 255, "I20=7"); // I21,22,23 소스만 Gathering하도록 설정 DeviceGetResponse(ScanI->dwDevice, response, 255, "CLOSE"); DeviceGetResponse(ScanI->dwDevice, response, 255, "END GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEL GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "DEF GAT"); DeviceGetResponse(ScanI->dwDevice, response, 255, "GAT &1 b1 r"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m180->X:$818,0"); DeviceGetResponse(ScanI->dwDevice, response, 255, "m145->Y:$814,10"); while(1) { DeviceGetResponse(ScanI->dwDevice, response, 255, "m180"); if (*response=='0') { break; } switch(CCD1->ScanMode) { case 0: //spectrograph DeviceGetResponse(ScanI->dwDevice, response, 255, "p1"); ReadScanPosition(ScanI); p1=atoi(response); if ((p1-ptemp)>0 && (ScanI->position - (double)p1 * (double)ScanI->stepSize*10) >=0 ) { Scanpos_CCDframe = p1; SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD1, 0); else DataDump(CCD1, Scanpos_CCDframe-1); SetCurrentCamera(CCD2->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD2, 0); else DataDump(CCD2, Scanpos_CCDframe-1); } break; case 1: //imaging sprintf(response, "%d", p1); p1=atoi(response); if (ScanI->position - (double)p1 * (double)ScanI->stepSize*10 >= (double)ScanI->stepSize*5 ) { p1++; Scanpos_CCDframe=p1; SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD1, 0); else DataDump(CCD1, Scanpos_CCDframe-1); SetCurrentCamera(CCD2->camera); if (Scanpos_CCDframe > CCD1->ScanNum) DataDump(dumpD2, 0); else DataDump(CCD2, Scanpos_CCDframe-1); } break; } } } SCANANDOBS_API void SingleBandVideo(CCDInfo* CCD, int* obsThread) { SetCurrentCamera(CCD->camera); while(1) { if(*obsThread == 1) { TakeImage(); DataDump(CCD, 0); } if(!*obsThread) break; } } SCANANDOBS_API void DualBandVideo(CCDInfo* CCD1, CCDInfo* CCD2, int* obsThread) { while(1) { if(*obsThread == 1) { SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); DataDump(CCD1, 0); SetCurrentCamera(CCD2->camera); DataDump(CCD2, 0); } if(!*obsThread) break; } } SCANANDOBS_API void testTaking(CCDInfo* CCD) { SetCurrentCamera(CCD->camera); TakeImage(); DataDump(CCD, 0); } SCANANDOBS_API void testTaking2(CCDInfo* CCD1, CCDInfo* CCD2, int* resDD) { SetCurrentCamera(CCD1->camera); TakeImage(); SetCurrentCamera(CCD2->camera); TakeImage(); SetCurrentCamera(CCD1->camera); DataDump(CCD1, 0); SetCurrentCamera(CCD2->camera); DataDump(CCD2, 0); }