28 const char *IMAGE_SETTINGS_TAB =
"Image Settings";
29 const char *IMAGE_INFO_TAB =
"Image Info";
30 const char *GUIDE_HEAD_TAB =
"Guide Head";
31 const char *GUIDE_CONTROL_TAB =
"Guider Control";
43 FrameType=LIGHT_FRAME;
63 delete AbortExposureSP;
65 delete ImageExposureNP;
67 delete ImagePixelSizeNP;
72 int CCDChip::setFrameType(CCD_FRAME t)
79 void CCDChip::setResolutoin(
int x,
int y)
84 ImagePixelSizeN[0].value=x;
85 ImagePixelSizeN[1].value=y;
89 ImageFrameN[FRAME_W].max = x;
90 ImageFrameN[FRAME_H].max = y;
94 void CCDChip::setFrame(
int subx,
int suby,
int subw,
int subh)
101 ImageFrameN[FRAME_X].value = SubX;
102 ImageFrameN[FRAME_Y].value = SubY;
103 ImageFrameN[FRAME_W].value = SubW;
104 ImageFrameN[FRAME_H].value = SubH;
109 void CCDChip::setBin(
int hor,
int ver)
114 ImageBinN[BIN_W].value = BinX;
115 ImageBinN[BIN_H].value = BinY;
120 void CCDChip::setPixelSize(
float x,
float y)
125 ImagePixelSizeN[2].value=x;
126 ImagePixelSizeN[3].value=x;
127 ImagePixelSizeN[4].value=y;
133 void CCDChip::setBPP(
int bbp)
137 ImagePixelSizeN[5].value = BPP;
142 void CCDChip::setFrameBufferSize(
int nbuf)
144 if (nbuf == RawFrameSize)
147 if (RawFrame != NULL)
153 RawFrame =
new char[nbuf];
156 void CCDChip::setExposureLeft(
double duration)
158 ImageExposureN[0].value = duration;
163 void CCDChip::setExposureDuration(
double duration)
165 exposureDuration = duration;
166 gettimeofday(&startExposureTime,NULL);
169 const char * CCDChip::getExposureStartTime()
173 time_t t = (time_t) startExposureTime.tv_sec;
177 strftime (ts,
sizeof(ts),
"%Y-%m-%dT%H:%M:%S", tp);
181 void CCDChip::setInterlaced(
bool intr)
186 void CCDChip::setExposureFailed()
203 delete ActiveDeviceTP;
206 bool INDI::CCD::initProperties()
212 IUFillNumber(&PrimaryCCD.ImageFrameN[0],
"X",
"Left ",
"%4.0f",0,1392.0,0,0);
213 IUFillNumber(&PrimaryCCD.ImageFrameN[1],
"Y",
"Top",
"%4.0f",0,1040,0,0);
214 IUFillNumber(&PrimaryCCD.ImageFrameN[2],
"WIDTH",
"Width",
"%4.0f",0,1392.0,0,1392.0);
215 IUFillNumber(&PrimaryCCD.ImageFrameN[3],
"HEIGHT",
"Height",
"%4.0f",0,1040,0,1040);
222 IUFillSwitchVector(PrimaryCCD.FrameTypeSP,PrimaryCCD.FrameTypeS,4,getDeviceName(),
"CCD_FRAME_TYPE",
"FrameType",IMAGE_SETTINGS_TAB,
IP_RW,
ISR_1OFMANY,60,
IPS_IDLE);
224 IUFillNumber(&PrimaryCCD.ImageExposureN[0],
"CCD_EXPOSURE_VALUE",
"Duration (s)",
"%5.2f",0,36000,0,1.0);
228 IUFillSwitchVector(PrimaryCCD.AbortExposureSP,PrimaryCCD.AbortExposureS,1,getDeviceName(),
"CCD_ABORT_EXPOSURE",
"Expose Abort",MAIN_CONTROL_TAB,
IP_RW,
ISR_1OFMANY,60,
IPS_IDLE);
230 IUFillNumber(&PrimaryCCD.ImageBinN[0],
"HOR_BIN",
"X",
"%2.0f",1,4,1,1);
231 IUFillNumber(&PrimaryCCD.ImageBinN[1],
"VER_BIN",
"Y",
"%2.0f",1,4,1,1);
234 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[0],
"CCD_MAX_X",
"Resolution x",
"%4.0f",1,40,0,6.45);
235 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[1],
"CCD_MAX_Y",
"Resolution y",
"%4.0f",1,40,0,6.45);
236 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[2],
"CCD_PIXEL_SIZE",
"Pixel size (um)",
"%5.2f",1,40,0,6.45);
237 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[3],
"CCD_PIXEL_SIZE_X",
"Pixel size X",
"%5.2f",1,40,0,6.45);
238 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[4],
"CCD_PIXEL_SIZE_Y",
"Pixel size Y",
"%5.2f",1,40,0,6.45);
239 IUFillNumber(&PrimaryCCD.ImagePixelSizeN[5],
"CCD_BITSPERPIXEL",
"Bits per pixel",
"%3.0f",1,40,0,6.45);
240 IUFillNumberVector(PrimaryCCD.ImagePixelSizeNP,PrimaryCCD.ImagePixelSizeN,6,getDeviceName(),
"CCD_INFO",
"CCD Information",IMAGE_INFO_TAB,
IP_RO,60,
IPS_IDLE);
244 IUFillSwitchVector(PrimaryCCD.CompressSP,PrimaryCCD.CompressS,2,getDeviceName(),
"COMPRESSION",
"Image",IMAGE_SETTINGS_TAB,
IP_RW,
ISR_1OFMANY,60,
IPS_IDLE);
246 IUFillBLOB(&PrimaryCCD.FitsB,
"CCD1",
"Image",
"");
251 IUFillNumber(&GuideCCD.ImageFrameN[0],
"X",
"Left ",
"%4.0f",0,1392.0,0,0);
252 IUFillNumber(&GuideCCD.ImageFrameN[1],
"Y",
"Top",
"%4.0f",0,1040,0,0);
253 IUFillNumber(&GuideCCD.ImageFrameN[2],
"WIDTH",
"Width",
"%4.0f",0,1392.0,0,1392.0);
254 IUFillNumber(&GuideCCD.ImageFrameN[3],
"HEIGHT",
"Height",
"%4.0f",0,1040,0,1040);
257 IUFillNumber(&GuideCCD.ImagePixelSizeN[0],
"CCD_MAX_X",
"Resolution x",
"%4.0f",1,40,0,6.45);
258 IUFillNumber(&GuideCCD.ImagePixelSizeN[1],
"CCD_MAX_Y",
"Resolution y",
"%4.0f",1,40,0,6.45);
259 IUFillNumber(&GuideCCD.ImagePixelSizeN[2],
"CCD_PIXEL_SIZE",
"Pixel size (um)",
"%5.2f",1,40,0,6.45);
260 IUFillNumber(&GuideCCD.ImagePixelSizeN[3],
"CCD_PIXEL_SIZE_X",
"Pixel size X",
"%5.2f",1,40,0,6.45);
261 IUFillNumber(&GuideCCD.ImagePixelSizeN[4],
"CCD_PIXEL_SIZE_Y",
"Pixel size Y",
"%5.2f",1,40,0,6.45);
262 IUFillNumber(&GuideCCD.ImagePixelSizeN[5],
"CCD_BITSPERPIXEL",
"Bits per pixel",
"%3.0f",1,40,0,6.45);
265 IUFillNumber(&GuideCCD.ImageExposureN[0],
"GUIDER_EXPOSURE_VALUE",
"Duration (s)",
"%5.2f",0,36000,0,1.0);
269 IUFillSwitchVector(GuideCCD.AbortExposureSP,GuideCCD.AbortExposureS,1,getDeviceName(),
"GUIDER_ABORT_EXPOSURE",
"Guide Abort",MAIN_CONTROL_TAB,
IP_RW,
ISR_1OFMANY,60,
IPS_IDLE);
273 IUFillSwitchVector(GuideCCD.CompressSP,GuideCCD.CompressS,2,getDeviceName(),
"GCOMPRESSION",
"Image",GUIDE_HEAD_TAB,
IP_RW,
ISR_1OFMANY,60,
IPS_IDLE);
275 IUFillBLOB(&GuideCCD.FitsB,
"CCD2",
"Guider Image",
"");
280 IUFillText(&ActiveDeviceT[0],
"ACTIVE_TELESCOPE",
"Telescope",
"Telescope Simulator");
281 IUFillText(&ActiveDeviceT[1],
"ACTIVE_FOCUSER",
"Focuser",
"Focuser Simulator");
284 IUFillNumber(&EqN[0],
"RA",
"Ra (hh:mm:ss)",
"%010.6m",0,24,0,0);
285 IUFillNumber(&EqN[1],
"DEC",
"Dec (dd:mm:ss)",
"%010.6m",-90,90,0,0);
294 initGuiderProperties(getDeviceName(), GUIDE_CONTROL_TAB);
310 bool INDI::CCD::updateProperties()
315 defineNumber(PrimaryCCD.ImageExposureNP);
316 defineSwitch(PrimaryCCD.AbortExposureSP);
317 defineNumber(PrimaryCCD.ImageFrameNP);
318 defineNumber(PrimaryCCD.ImageBinNP);
323 defineNumber(GuideCCD.ImageExposureNP);
324 defineSwitch(GuideCCD.AbortExposureSP);
325 defineNumber(GuideCCD.ImageFrameNP);
328 defineNumber(PrimaryCCD.ImagePixelSizeNP);
331 defineNumber(GuideCCD.ImagePixelSizeNP);
333 defineSwitch(PrimaryCCD.CompressSP);
334 defineBLOB(PrimaryCCD.FitsBP);
337 defineSwitch(GuideCCD.CompressSP);
338 defineBLOB(GuideCCD.FitsBP);
342 defineNumber(&GuideNSP);
343 defineNumber(&GuideEWP);
345 defineSwitch(PrimaryCCD.FrameTypeSP);
346 defineText(ActiveDeviceTP);
350 deleteProperty(PrimaryCCD.ImageFrameNP->name);
351 deleteProperty(PrimaryCCD.ImageBinNP->name);
352 deleteProperty(PrimaryCCD.ImagePixelSizeNP->name);
353 deleteProperty(PrimaryCCD.ImageExposureNP->name);
354 deleteProperty(PrimaryCCD.AbortExposureSP->name);
355 deleteProperty(PrimaryCCD.FitsBP->name);
356 deleteProperty(PrimaryCCD.CompressSP->name);
359 deleteProperty(GuideCCD.ImageExposureNP->name);
360 deleteProperty(GuideCCD.AbortExposureSP->name);
361 deleteProperty(GuideCCD.ImageFrameNP->name);
362 deleteProperty(GuideCCD.ImagePixelSizeNP->name);
363 deleteProperty(GuideCCD.FitsBP->name);
364 deleteProperty(GuideCCD.CompressSP->name);
368 deleteProperty(GuideNSP.name);
369 deleteProperty(GuideEWP.name);
372 deleteProperty(PrimaryCCD.FrameTypeSP->name);
373 deleteProperty(ActiveDeviceTP->name);
386 if((newra != RA)||(newdec != Dec))
402 bool INDI::CCD::ISNewText (
const char *dev,
const char *name,
char *texts[],
char *names[],
int n)
407 if(strcmp(dev,getDeviceName())==0)
411 if(strcmp(name,ActiveDeviceTP->name)==0)
439 if(strcmp(dev,getDeviceName())==0)
443 if(strcmp(name,
"CCD_EXPOSURE")==0)
450 PrimaryCCD.ImageExposureN[0].value=n;
452 if (PrimaryCCD.ImageExposureNP->s==
IPS_BUSY)
455 PrimaryCCD.ImageExposureNP->s=
IPS_BUSY;
464 PrimaryCCD.ImageExposureNP->s=
IPS_BUSY;
467 PrimaryCCD.ImageExposureNP->s=
IPS_OK;
477 if(strcmp(name,
"GUIDER_EXPOSURE")==0)
484 GuideCCD.ImageExposureN[0].value=n;
485 GuideCCD.ImageExposureNP->s=
IPS_BUSY;
492 rc=StartGuideExposure(n);
496 GuideCCD.ImageExposureNP->s=
IPS_BUSY;
499 GuideCCD.ImageExposureNP->s=
IPS_OK;
509 if(strcmp(name,
"CCD_BINNING")==0)
512 PrimaryCCD.ImageBinNP->s=
IPS_OK;
516 if (updateCCDBin(PrimaryCCD.ImageBinN[0].value, PrimaryCCD.ImageBinN[1].value) ==
false)
526 if(strcmp(name,
"CCD_FRAME")==0)
529 PrimaryCCD.ImageFrameNP->s=
IPS_OK;
532 if (updateCCDFrame(PrimaryCCD.ImageFrameN[0].value, PrimaryCCD.ImageFrameN[1].value, PrimaryCCD.ImageFrameN[2].value,
533 PrimaryCCD.ImageFrameN[3].value) ==
false)
542 if(strcmp(name,
"GUIDER_FRAME")==0)
545 GuideCCD.ImageFrameNP->s=
IPS_OK;
551 IDLog(
"GuiderFrame set to %4.0f,%4.0f %4.0f x %4.0f\n",
552 GuideCCD.ImageFrameN[0].value,GuideCCD.ImageFrameN[1].value,GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
557 GuideCCD.setFrame(GuideCCD.ImageFrameN[0].value, GuideCCD.ImageFrameN[1].value,
558 GuideCCD.ImageFrameN[2].value,GuideCCD.ImageFrameN[3].value);
563 if (!strcmp(name,GuideNSP.name) || !strcmp(name,GuideEWP.name))
565 processGuiderProperties(name, values, names, n);
578 if(strcmp(dev,getDeviceName())==0)
582 if(strcmp(name,PrimaryCCD.AbortExposureSP->name)==0)
588 PrimaryCCD.AbortExposureSP->s =
IPS_OK;
589 PrimaryCCD.ImageExposureNP->s =
IPS_IDLE;
590 PrimaryCCD.ImageExposureN[0].value = 0;
594 PrimaryCCD.AbortExposureSP->s =
IPS_ALERT;
595 PrimaryCCD.ImageExposureNP->s =
IPS_ALERT;
605 if(strcmp(name,GuideCCD.AbortExposureSP->name)==0)
609 if (AbortGuideExposure())
611 GuideCCD.AbortExposureSP->s =
IPS_OK;
612 GuideCCD.ImageExposureNP->s =
IPS_IDLE;
613 GuideCCD.ImageExposureN[0].value = 0;
628 if(strcmp(name,PrimaryCCD.CompressSP->name)==0)
634 if(PrimaryCCD.CompressS[0].s==
ISS_ON )
636 PrimaryCCD.SendCompressed=
true;
639 PrimaryCCD.SendCompressed=
false;
644 if(strcmp(name,GuideCCD.CompressSP->name)==0)
650 if(GuideCCD.CompressS[0].s==
ISS_ON )
652 GuideCCD.SendCompressed=
true;
655 GuideCCD.SendCompressed=
false;
660 if(strcmp(name,PrimaryCCD.FrameTypeSP->name)==0)
664 PrimaryCCD.FrameTypeSP->s=
IPS_OK;
665 if(PrimaryCCD.FrameTypeS[0].s==
ISS_ON) PrimaryCCD.setFrameType(CCDChip::LIGHT_FRAME);
666 else if(PrimaryCCD.FrameTypeS[1].s==
ISS_ON) PrimaryCCD.setFrameType(CCDChip::BIAS_FRAME);
667 else if(PrimaryCCD.FrameTypeS[2].s==
ISS_ON) PrimaryCCD.setFrameType(CCDChip::DARK_FRAME);
668 else if(PrimaryCCD.FrameTypeS[3].s==
ISS_ON) PrimaryCCD.setFrameType(CCDChip::FLAT_FRAME);
670 if (updateCCDFrameType(PrimaryCCD.getFrameType()) ==
false)
687 IDLog(
"INDI::CCD::StartExposure %4.2f - Should never get here\n",duration);
693 IDLog(
"INDI::CCD::StartGuide Exposure %4.2f - Should never get here\n",duration);
699 IDLog(
"INDI::CCD::AbortExposure - Should never get here\n");
706 PrimaryCCD.setFrame(x, y, w, h);
713 PrimaryCCD.setBin(hor, ver);
730 double min_val, max_val;
731 double exposureDuration;
732 double pixSize1,pixSize2;
733 unsigned int xbin, ybin;
735 getMinMax(&min_val, &max_val, targetChip);
737 xbin = targetChip->getBinX();
738 ybin = targetChip->getBinY();
741 switch (targetChip->getFrameType())
743 case CCDChip::LIGHT_FRAME:
744 strcpy(frame_s,
"Light");
746 case CCDChip::BIAS_FRAME:
747 strcpy(frame_s,
"Bias");
749 case CCDChip::FLAT_FRAME:
750 strcpy(frame_s,
"Flat Field");
752 case CCDChip::DARK_FRAME:
753 strcpy(frame_s,
"Dark");
757 exposureDuration = targetChip->getExposureDuration();
759 pixSize1 = targetChip->getPixelSizeX();
760 pixSize2 = targetChip->getPixelSizeY();
762 strncpy(dev_name, getDeviceName(), 32);
763 strncpy(exp_start, targetChip->getExposureStartTime(), 32);
765 fits_update_key_s(fptr, TDOUBLE,
"EXPTIME", &(exposureDuration),
"Total Exposure Time (s)", &status);
767 if(targetChip->getFrameType() == CCDChip::DARK_FRAME)
768 fits_update_key_s(fptr, TDOUBLE,
"DARKTIME", &(exposureDuration),
"Total Exposure Time (s)", &status);
770 fits_update_key_s(fptr, TDOUBLE,
"PIXSIZE1", &(pixSize1),
"Pixel Size 1 (microns)", &status);
771 fits_update_key_s(fptr, TDOUBLE,
"PIXSIZE2", &(pixSize2),
"Pixel Size 2 (microns)", &status);
772 fits_update_key_s(fptr, TUINT,
"XBINNING", &(xbin) ,
"Binning factor in width", &status);
773 fits_update_key_s(fptr, TUINT,
"YBINNING", &(ybin),
"Binning factor in height", &status);
774 fits_update_key_s(fptr, TSTRING,
"FRAME", frame_s,
"Frame Type", &status);
775 fits_update_key_s(fptr, TDOUBLE,
"DATAMIN", &min_val,
"Minimum value", &status);
776 fits_update_key_s(fptr, TDOUBLE,
"DATAMAX", &max_val,
"Maximum value", &status);
777 fits_update_key_s(fptr, TSTRING,
"INSTRUME", dev_name,
"CCD Name", &status);
778 fits_update_key_s(fptr, TSTRING,
"DATE-OBS", exp_start,
"UTC start date of observation", &status);
783 void INDI::CCD::fits_update_key_s(fitsfile* fptr,
int type, std::string name,
void* p, std::string explanation,
int* status)
786 fits_update_key(fptr,type,name.c_str(),p,
const_cast<char*
>(explanation.c_str()), status);
802 naxes[0]=targetChip->getSubW()/targetChip->getBinX();
803 naxes[1]=targetChip->getSubH()/targetChip->getBinY();
805 switch (targetChip->getBPP())
814 img_type = USHORT_IMG;
819 img_type = ULONG_IMG;
823 IDLog(
"Unsupported bits per pixel value %d\n", targetChip->getBPP() );
829 nelements = naxes[0] * naxes[1];
833 memptr=malloc(memsize);
836 IDLog(
"Error: failed to allocate memory: %lu\n",(
unsigned long)memsize);
839 fits_create_memfile(&fptr,&memptr,&memsize,2880,realloc,&status);
843 IDLog(
"Error: Failed to create FITS image\n");
844 fits_report_error(stderr, status);
848 fits_create_img(fptr, img_type , naxis, naxes, &status);
852 IDLog(
"Error: Failed to create FITS image\n");
853 fits_report_error(stderr, status);
857 addFITSKeywords(fptr, targetChip);
859 fits_write_img(fptr,byte_type,1,nelements,targetChip->getFrameBuffer(),&status);
863 IDLog(
"Error: Failed to write FITS image\n");
864 fits_report_error(stderr, status);
868 fits_close_file(fptr,&status);
870 targetChip->ImageExposureNP->s=
IPS_OK;
874 targetChip->FitsB.blob=memptr;
875 targetChip->FitsB.bloblen=memsize;
876 targetChip->FitsB.size=memsize;
877 strcpy(targetChip->FitsB.format,
".fits");
878 targetChip->FitsBP->s=
IPS_OK;
888 PrimaryCCD.setResolutoin(x, y);
889 PrimaryCCD.setFrame(0, 0, x, y);
890 PrimaryCCD.setBin(1,1);
891 PrimaryCCD.setPixelSize(xf, yf);
892 PrimaryCCD.setBPP(bpp);
900 GuideCCD.setResolutoin(x, y);
901 GuideCCD.setFrame(0, 0, x, y);
902 GuideCCD.setPixelSize(xf, yf);
903 GuideCCD.setBPP(bpp);
912 bool INDI::CCD::saveConfigItems(FILE *fp)
936 void INDI::CCD::getMinMax(
double *min,
double *max, CCDChip *targetChip)
939 int imageHeight = targetChip->getSubH() / targetChip->getBinY();
940 int imageWidth = targetChip->getSubW() / targetChip->getBinX();
943 switch (targetChip->getBPP())
947 unsigned char *imageBuffer = (
unsigned char *) targetChip->getFrameBuffer();
948 lmin = lmax = imageBuffer[0];
951 for (i= 0; i < imageHeight ; i++)
952 for (j= 0; j < imageWidth; j++)
954 ind = (i * imageWidth) + j;
955 if (imageBuffer[ind] < lmin) lmin = imageBuffer[ind];
956 else if (imageBuffer[ind] > lmax) lmax = imageBuffer[ind];
964 unsigned short *imageBuffer = (
unsigned short* ) targetChip->getFrameBuffer();
965 lmin = lmax = imageBuffer[0];
967 for (i= 0; i < imageHeight ; i++)
968 for (j= 0; j < imageWidth; j++)
970 ind = (i * imageWidth) + j;
971 if (imageBuffer[ind] < lmin) lmin = imageBuffer[ind];
972 else if (imageBuffer[ind] > lmax) lmax = imageBuffer[ind];
980 unsigned int *imageBuffer = (
unsigned int* ) targetChip->getFrameBuffer();
981 lmin = lmax = imageBuffer[0];
983 for (i= 0; i < imageHeight ; i++)
984 for (j= 0; j < imageWidth; j++)
986 ind = (i * imageWidth) + j;
987 if (imageBuffer[ind] < lmin) lmin = imageBuffer[ind];
988 else if (imageBuffer[ind] > lmax) lmax = imageBuffer[ind];