/*===========================================================================*/ /* gainCalib.C */ /* ------------------------------------------------------------------------- */ /* ISDCRoot script to calibrate SPI detector gains. */ /* ------------------------------------------------------------------------- */ /* Author : Jurgen KNODLSEDER (CESR) (C) (all rights reserved) */ /* Date : 11-Sep-2003 */ /* Version : 1.5.0 */ /* ------------------------------------------------------------------------- */ /* History : */ /* 1.0.0 10-Nov-2002 first version */ /* 1.1.0 4-Dec-2002 corrected time calculation */ /* 1.2.0 17-Mar-2003 use 3 deg for PHA0 conversion */ /* 1.3.0 24-Mar-2003 use 2 deg for PHA0 conversion (version 0003) */ /* 1.4.0 9-Sep-2003 adapt to new ISDCROOT (no OBTime anymore) */ /* 1.5.0 11-Sep-2003 new calibration functions POLY_1/C and POLY_1/C2 */ /*===========================================================================*/ #define ISDC_OK 0 #define DAL_SAVE 0 #define IJD_OFFSET (-1020.0) // 17-Oct-2002 #define OBT_OFFSET (+6053/86400.0) // days in day IJD1020 of OBT=0 #define OBT_T0 74565.40444444444437976927 #define OBT_T1 1.13777777777777777679 #define OBT_T2 0.00001736111111111111 #define OBT_T3 0.00000000026490953234 void gainCalib(int argc = -2, char** argv = 0) { // Script parameters char gainAscii[] = "std_calib.gain"; char gainDOL[] = "spi_gain_coeff.fits"; int chkevdeg0 = 4; int kevchdeg0 = 4; int chkevdeg1 = 2; int kevchdeg1 = 2; int calfct0 = 1; // 0=POLY, 1=POLY_1/C, 2,3=POLY_1/C2 int calfct1 = 0; // 0=POLY, 1=POLY_1/C, 2,3=POLY_1/C2 char fitopt[] = "Q"; // ""=verbose, "Q"=quite int tstdmp = 0; double engerr = 0.05; // Energy uncertainty // Declare variables int status = ISDC_OK; int i; int j; int k; int inx; int idete; int irange; int ndete; int nrange; int obt_first[4]; int obt_last[4]; int n_pha0; int n_pha1; int n_lines; int id; int det_num; int deg; int version; int num_lines[100]; int num; int numerr; int chkevdeg; int kevchdeg; int calfct; long numRows; float ontime_in; float e0_line[100]; float e1_line[100]; float pha_line[100][38]; float pha_err[100][38]; float vstart; float vstop; float tstart; float tstop; float telapse; double e_line; double eng; double pha; double phaerr; double chi_sqr; double ck_p0[38]; double ck_p1[38]; double ck_p2[38]; double ck_p3[38]; double ck_p4[38]; double kc_p0[38]; double kc_p1[38]; double kc_p2[38]; double kc_p3[38]; double kc_p4[38]; double chan_kev[38*5]; double kev_chan[38*5]; char name[256]; char type[256]; char add[256]; char comm[256]; char cobt_start[256]; char cobt_stop[256]; unsigned long long obt_start_att; unsigned long long obt_stop_att; unsigned long *det_id; unsigned char *e_range; unsigned short *obt_start; unsigned short *obt_end; unsigned long *ontime; dal_element *gain; FILE *fptr; TGraphErrors *ck_graph[38]; TGraphErrors *kc_graph[38]; TF1 *ck_poly[38]; TF1 *kc_poly[38]; // Initialise memory pointers det_id = NULL; e_range = NULL; obt_start = NULL; obt_end = NULL; ontime = NULL; // Main loop do { // Initialise version = 1; nrange = 2; ndete = 19; numRows = nrange * ndete; det_num = ndete; // Read ASCII file fptr = fopen(gainAscii, "r"); if (fptr == NULL) { printf("Error while opening ASCII file %s.\n", gainAscii); continue; } fscanf(fptr, "%d %d %d %d", &(obt_first[0]), &(obt_first[1]), &(obt_first[2]), &(obt_first[3])); fscanf(fptr, "%d %d %d %d", &(obt_last[0]), &(obt_last[1]), &(obt_last[2]), &(obt_last[3])); fscanf(fptr, "%f", &ontime_in); fscanf(fptr, "%d %d", &n_pha0, &n_pha1); if (n_pha0 > 0) { for (i = 0; i < n_pha0; i++) fscanf(fptr, "%f", &(e0_line[i])); for (idete = 0; idete < ndete; idete++) { fscanf(fptr, "%d", &id); if (idete != id) printf("Expected detector ID %d but found ID %d\n", idete, id); for (i = 0; i < n_pha0; i++) fscanf(fptr, "%f %f", &(pha_line[i][idete]), &(pha_err[i][idete])); } } if (n_pha1 > 0) { for (i = 0; i < n_pha1; i++) fscanf(fptr, "%f", &(e1_line[i])); for (idete = 0; idete < ndete; idete++) { fscanf(fptr, "%d", &id); if (idete != id) printf("Expected detector ID %d but found ID %d\n", idete, id); for (i = 0; i < n_pha1; i++) fscanf(fptr, "%f %f", &(pha_line[i][idete+19]), &(pha_err[i][idete+19])); } } fclose (fptr); // Build OBT_START and OBT_STOP obt_start_att = 0; obt_start_att += obt_first[0]; obt_start_att = obt_start_att << 16; obt_start_att += obt_first[1]; obt_start_att = obt_start_att << 16; obt_start_att += obt_first[2]; obt_start_att = obt_start_att << 16; obt_start_att += obt_first[3]; obt_stop_att = 0; obt_stop_att += obt_last[0]; obt_stop_att = obt_stop_att << 16; obt_stop_att += obt_last[1]; obt_stop_att = obt_stop_att << 16; obt_stop_att += obt_last[2]; obt_stop_att = obt_stop_att << 16; obt_stop_att += obt_last[3]; vstart = double(obt_first[0]) * OBT_T0 + double(obt_first[1]) * OBT_T1 + double(obt_first[2]) * OBT_T2 + double(obt_first[3]) * OBT_T3; vstop = double(obt_last[0]) * OBT_T0 + double(obt_last[1]) * OBT_T1 + double(obt_last[2]) * OBT_T2 + double(obt_last[3]) * OBT_T3; vstart = vstart / 24.0 - IJD_OFFSET + OBT_OFFSET; vstop = vstop / 24.0 - IJD_OFFSET + OBT_OFFSET; tstart = vstart; tstop = vstop; telapse = (tstop - tstart) * 86400.0; // Dump input if (tstdmp) { printf("OBT start : %d %d %d %d\n", obt_first[0], obt_first[1], obt_first[2], obt_first[3]); printf("OBT stop : %d %d %d %d\n", obt_last[0], obt_last[1], obt_last[2], obt_last[3]); printf("OBT start : %s\n", cobt_start); printf("OBT stop : %s\n", cobt_stop); printf("ONTIME : %.3f\n", ontime_in); printf("# of lines: %d %d\n", n_pha0, n_pha1); if (n_pha0 > 0) { printf("Lines keV :"); for (i = 0; i < n_pha0; i++) printf(" %8.2f ", e0_line[i]); printf("\n"); for (idete = 0; idete < ndete; idete++) { printf("PHA0-%2.2d :", idete); for (i = 0; i < n_pha0; i++) printf(" %8.2f ", pha_line[i][idete]); printf("\n"); } } if (n_pha1 > 0) { for (i = 0; i < n_pha1; i++) printf(" %8.2f ", e1_line[i]); printf("\n"); for (idete = 0; idete < ndete; idete++) { printf("PHA1-%2.2d :", idete); for (i = 0; i < n_pha1; i++) printf(" %8.2f ", pha_line[i][idete+19]); printf("\n"); } } } // Fit linear relations to line for (idete = 0; idete < 2*ndete; idete++) { // Initialise results ck_p0[idete] = 0.0; ck_p1[idete] = 0.0; ck_p2[idete] = 0.0; ck_p3[idete] = 0.0; ck_p4[idete] = 0.0; kc_p0[idete] = 0.0; kc_p1[idete] = 0.0; kc_p2[idete] = 0.0; kc_p3[idete] = 0.0; kc_p4[idete] = 0.0; ck_graph[idete] = NULL; kc_graph[idete] = NULL; // Get number of lines if (idete < 19) { n_lines = n_pha0; chkevdeg = chkevdeg0; kevchdeg = kevchdeg0; calfct = calfct0; } else { n_lines = n_pha1; chkevdeg = chkevdeg1; kevchdeg = kevchdeg1; calfct = calfct1; } // Allocate graphs sprintf(name,"CK_DETE%2.2d", idete); ck_graph[idete] = new TGraphErrors(n_lines); ck_graph[idete]->SetTitle(name); ck_graph[idete]->SetMarkerSize(0.5); ck_graph[idete]->SetMarkerStyle(2); sprintf(name,"KC_DETE%2.2d", idete); kc_graph[idete] = new TGraphErrors(n_lines); kc_graph[idete]->SetTitle(name); kc_graph[idete]->SetMarkerSize(0.5); kc_graph[idete]->SetMarkerStyle(2); // Fill graph num = 0; for (i = 0; i < n_lines; i++) { if (pha_line[i][idete] > 0.0) { e_line = (idete < 19) ? e0_line[i] : e1_line[i]; eng = e_line; pha = pha_line[i][idete]; if (pha_err[i][idete] > 0.0) phaerr = pha_err[i][idete]; else { phaerr = 0.0; numerr = 0; for (k = 0; k < 19; k++) { if (pha_err[i][k] > 0.0) { phaerr += pha_err[i][k]; numerr++; } } if (numerr > 0) phaerr /= numerr; printf("Line %d detector %d: estimated error from other detectors" " to %.4f\n", i, idete, phaerr); } ck_graph[idete]->SetPoint(num, pha, eng); ck_graph[idete]->SetPointError(num, phaerr, engerr); kc_graph[idete]->SetPoint(num, eng, pha); kc_graph[idete]->SetPointError(num, engerr, phaerr); num++; } } // Fit channel->keV graph if (num >= 2) { // Define fit function dependent on function type deg = (chkevdeg > num) ? num : chkevdeg; sprintf(name, "ck%2.2d%2.2d", idete, deg-1); switch (calfct) { case 0: // Case POLY sprintf(type, "pol%d", deg-1); ck_poly[idete] = new TF1(name, type, 0.0, 8000.0); break; case 1: // Case POLY_1/C sprintf(type, "[0]/x+[1]"); if (deg > 2) { for (k = 2; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 2; j <= k; j++) strcat(type, "*x"); } } ck_poly[idete] = new TF1(name, type, 0.0, 8000.0); ck_poly[idete]->SetParameter(0, -400.0); ck_poly[idete]->SetParameter(1, 1.0); ck_poly[idete]->SetParameter(2, 0.14); ck_poly[idete]->SetParameter(3, -1.0e-8); ck_poly[idete]->SetParameter(4, 1.0e-16); break; case 2: // Case POLY_1/C2 if (num >= 3) { sprintf(type, "[0]/x/x+[1]/x+[2]"); if (deg > 3) { for (k = 3; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 3; j <= k; j++) strcat(type, "*x"); } } ck_poly[idete] = new TF1(name, type, 0.0, 8000.0); ck_poly[idete]->SetParameter(0, 4.0e4); ck_poly[idete]->SetParameter(1, -400.0); ck_poly[idete]->SetParameter(2, 1.0); ck_poly[idete]->SetParameter(3, 0.14); ck_poly[idete]->SetParameter(4, -1.0e-8); } break; case 3: // Case POLY_1/C2 w/o 1/C term sprintf(type, "[0]/x/x+[1]"); if (deg > 2) { for (k = 2; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 2; j <= k; j++) strcat(type, "*x"); } } ck_poly[idete] = new TF1(name, type, 0.0, 8000.0); ck_poly[idete]->SetParameter(0, -1.0e4); ck_poly[idete]->SetParameter(1, 1.0); ck_poly[idete]->SetParameter(2, 0.14); ck_poly[idete]->SetParameter(3, -1.0e-8); ck_poly[idete]->SetParameter(4, 1.0e-16); break; default: break; } // endswitch // Perform fit if (ck_poly[idete] != NULL) { ck_poly[idete]->SetLineWidth(0.5); ck_poly[idete]->SetLineColor(2); ck_graph[idete]->Set(num); ck_graph[idete]->Fit(name, fitopt); ck_p0[idete] = ck_poly[idete]->GetParameter(0); ck_p1[idete] = ck_poly[idete]->GetParameter(1); if (deg > 2) ck_p2[idete] = ck_poly[idete]->GetParameter(2); if (deg > 3) ck_p3[idete] = ck_poly[idete]->GetParameter(3); if (deg > 4) ck_p4[idete] = ck_poly[idete]->GetParameter(4); chi_sqr = ck_poly[idete]->GetChisquare(); if (idete < 19) printf("C->E: D%2.2d-R0: Chi-sqr=%.3f\n", idete, chi_sqr); else printf("C->E: D%2.2d-R1: Chi-sqr=%.3f\n", idete-19, chi_sqr); } // Treat fit function 3 if (calfct == 3) { ck_p4[idete] = ck_p3[idete]; ck_p3[idete] = ck_p2[idete]; ck_p2[idete] = ck_p1[idete]; ck_p1[idete] = 0.0; } } // endif else { delete ck_graph[idete]; ck_graph[idete] = NULL; } // Fit keV->channel graph if (num >= 2) { // Define fit function dependent on function type deg = (kevchdeg > num) ? num : kevchdeg; sprintf(name, "kc%2.2d%2.2d", idete, deg-1); switch (calfct) { case 0: // Case POLY sprintf(type, "pol%d", deg-1); kc_poly[idete] = new TF1(name, type, 0.0, 8000.0); break; case 1: // Case POLY_1/C sprintf(type, "[0]/x+[1]"); if (deg > 2) { for (k = 2; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 2; j <= k; j++) strcat(type, "*x"); } } kc_poly[idete] = new TF1(name, type, 0.0, 8000.0); kc_poly[idete]->SetParameter(0, 400.0); kc_poly[idete]->SetParameter(1, -8.0); kc_poly[idete]->SetParameter(2, 8.0); kc_poly[idete]->SetParameter(3, 1.0e-6); kc_poly[idete]->SetParameter(4, 1.0e-12); break; case 2: // Case POLY_1/C2 if (num >= 3) { sprintf(type, "[0]/x/x+[1]/x+[2]"); if (deg > 3) { for (k = 3; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 3; j <= k; j++) strcat(type, "*x"); } } kc_poly[idete] = new TF1(name, type, 0.0, 8000.0); kc_poly[idete]->SetParameter(0, -4.0e4); kc_poly[idete]->SetParameter(1, 400.0); kc_poly[idete]->SetParameter(2, -8.0); kc_poly[idete]->SetParameter(3, 8.0); kc_poly[idete]->SetParameter(4, 1.0e-6); } break; case 3: // Case POLY_1/C2 w/o 1/C sprintf(type, "[0]/x/x+[1]"); if (deg > 2) { for (k = 2; k < deg; k++) { sprintf(add, "+[%d]", k); strcat(type, add); for (j = 2; j <= k; j++) strcat(type, "*x"); } } kc_poly[idete] = new TF1(name, type, 0.0, 8000.0); kc_poly[idete]->SetParameter(0, 1.0e4); kc_poly[idete]->SetParameter(1, -8.0); kc_poly[idete]->SetParameter(2, 8.0); kc_poly[idete]->SetParameter(3, 1.0e-6); kc_poly[idete]->SetParameter(4, 1.0e-12); break; default: break; } // endswitch // Perform fit if (kc_poly[idete] != NULL) { kc_poly[idete]->SetLineWidth(0.5); kc_poly[idete]->SetLineColor(2); kc_graph[idete]->Set(num); kc_graph[idete]->Fit(name, fitopt); kc_p0[idete] = kc_poly[idete]->GetParameter(0); kc_p1[idete] = kc_poly[idete]->GetParameter(1); if (deg > 2) kc_p2[idete] = kc_poly[idete]->GetParameter(2); if (deg > 3) kc_p3[idete] = kc_poly[idete]->GetParameter(3); if (deg > 4) kc_p4[idete] = kc_poly[idete]->GetParameter(4); chi_sqr = ck_poly[idete]->GetChisquare(); if (idete < 19) printf("E->C: D%2.2d-R0: Chi-sqr=%.3f\n", idete, chi_sqr); else printf("E->C: D%2.2d-R1: Chi-sqr=%.3f\n", idete-19, chi_sqr); } // Treat fit function 3 if (calfct == 3) { kc_p4[idete] = kc_p3[idete]; kc_p3[idete] = kc_p2[idete]; kc_p2[idete] = kc_p1[idete]; kc_p1[idete] = 0.0; } } else { delete kc_graph[idete]; kc_graph[idete] = NULL; } } // endfor: Looped over detectors // Allocate temporary memory for SPI.-COEF-CAL HDU det_id = new unsigned long[numRows]; e_range = new unsigned char[numRows]; obt_start = new unsigned short[numRows*4]; obt_end = new unsigned short[numRows*4]; ontime = new unsigned long[numRows]; if (det_id == NULL || e_range == NULL || obt_start == NULL || obt_end == NULL || ontime == NULL) { printf("Error while allocating buffers.\n"); continue; } // Fill the SPI.-COEF-CAL data for (irange = 0; irange < nrange; irange++) { for (idete = 0; idete < ndete; idete++) { inx = irange*ndete + idete; det_id[inx] = idete; e_range[inx] = irange; for (i = 0; i < 4; i++) { obt_start[inx*4+i] = obt_first[i]; obt_end[inx*4+i] = obt_last[i]; } ontime[inx] = ontime_in; chan_kev[inx*5+0] = ck_p0[inx]; chan_kev[inx*5+1] = ck_p1[inx]; chan_kev[inx*5+2] = ck_p2[inx]; chan_kev[inx*5+3] = ck_p3[inx]; chan_kev[inx*5+4] = ck_p4[inx]; kev_chan[inx*5+0] = kc_p0[inx]; kev_chan[inx*5+1] = kc_p1[inx]; kev_chan[inx*5+2] = kc_p2[inx]; kev_chan[inx*5+3] = kc_p3[inx]; kev_chan[inx*5+4] = kc_p4[inx]; } // endfor: Looped over detector } // endfor: Looped over energy range // Create SPI.-COEF-CAL HDU status = DALobjectCreate(gainDOL, DAL_DISK, "SPI.-COEF-CAL.tpl", &gain, status); if (status != ISDC_OK) { printf("%d : Error while creating file %s.\n", status, gainDOL); continue; } // Add rows status = DALtableAddRows(gain, -1, numRows, status); if (status != ISDC_OK) { printf("%d : Error while adding rows to %s.\n", status, gainDOL); continue; } // Fill columns status = DALtablePutCol(gain, "DET_ID", 0, DAL_ULONG, numRows, det_id, status); status = DALtablePutCol(gain, "E_RANGE", 0, DAL_BYTE, numRows, e_range, status); status = DALtablePutCol(gain, "OBT_START", 0, DAL_USHORT, numRows*4, obt_start, status); status = DALtablePutCol(gain, "OBT_END", 0, DAL_USHORT, numRows*4, obt_end, status); status = DALtablePutCol(gain, "ONTIME", 0, DAL_ULONG, numRows, ontime, status); status = DALtablePutCol(gain, "CHAN_KEV", 0, DAL_DOUBLE, numRows*5, chan_kev, status); status = DALtablePutCol(gain, "KEV_CHAN", 0, DAL_DOUBLE, numRows*5, kev_chan, status); if (status != ISDC_OK) { printf("%d : Error while filling columns of %s.\n", status, gainDOL); continue; } // Set attributes status = DALattributePut(gain, "VSTART", DAL_FLOAT, (void*)&vstart, NULL, NULL, status); status = DALattributePut(gain, "VSTOP", DAL_FLOAT, (void*)&vstop, NULL, NULL, status); status = DALattributePut(gain, "TSTART", DAL_FLOAT, (void*)&tstart, NULL, NULL, status); status = DALattributePut(gain, "TSTOP", DAL_FLOAT, (void*)&tstop, NULL, NULL, status); status = DALattributePut(gain, "TELAPSE", DAL_FLOAT, (void*)&telapse, NULL, NULL, status); status = DALattributePut(gain, "DET_NUM", DAL_INT, (void*)&det_num, NULL, NULL, status); status = DALattributePut(gain, "CHKEVDEG", DAL_INT, (void*)&chkevdeg, NULL, NULL, status); status = DALattributePut(gain, "KEVCHDEG", DAL_INT, (void*)&kevchdeg, NULL, NULL, status); status = DALattributePut(gain, "CAL_ID", DAL_CHAR, (void*)gainAscii, NULL, NULL, status); status = DALattributePut(gain, "VERSION", DAL_INT, (void*)&version, NULL, NULL, status); status = DAL3GENattributePutOBT(gain, "OBTFIRST", obt_start_att, NULL, status); status = DAL3GENattributePutOBT(gain, "OBTLAST", obt_stop_att, NULL, status); if (status != ISDC_OK) { printf("%d : Error while writing keywords of %s.\n", status, gainDOL); continue; } // Set calibration function types switch (calfct0) { case 0: status = DALattributePut(gain, "CAL_FCT0", DAL_CHAR, "POLY", NULL, "Low range fit function", status); break; case 1: status = DALattributePut(gain, "CAL_FCT0", DAL_CHAR, "POLY_1/C", NULL, "Low range fit function", status); break; case 2: case 3: status = DALattributePut(gain, "CAL_FCT0", DAL_CHAR, "POLY_1/C2", NULL, "Low range fit function", status); break; default: status = DALattributePut(gain, "CAL_FCT0", DAL_CHAR, "UNKNOWN", NULL, "Low range fit function", status); break; } switch (calfct1) { case 0: status = DALattributePut(gain, "CAL_FCT1", DAL_CHAR, "POLY", NULL, "High range fit function", status); break; case 1: status = DALattributePut(gain, "CAL_FCT1", DAL_CHAR, "POLY_1/C", NULL, "High range fit function", status); break; case 2: case 3: status = DALattributePut(gain, "CAL_FCT1", DAL_CHAR, "POLY_1/C2", NULL, "High range fit function", status); break; default: status = DALattributePut(gain, "CAL_FCT1", DAL_CHAR, "UNKNOWN", NULL, "High range fit function", status); break; } if (status != ISDC_OK) { printf("%d : Error while writing fit function of %s.\n", status, gainDOL); continue; } // Dump input lines into header comments sprintf(comm, "==================================================" "======================"); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "SPI gain calibration file created using isdcroot" " script gainCalib.C"); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "Author ...: Jurgen Knodlseder (CESR)"); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "Version ..: 1.5.0"); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "Date .....: 11-Sep-2003"); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, " "); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "%d calibration lines for low range (PHA0)", n_pha0); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); if (n_pha0 > 0) { for (i = 0; i < n_pha0; i++) { sprintf(comm, "* %8.3f keV", e0_line[i]); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); } } sprintf(comm, " "); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); sprintf(comm, "%d calibration lines for high range (PHA1)", n_pha1); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); if (n_pha1 > 0) { for (i = 0; i < n_pha1; i++) { sprintf(comm, "* %8.3f keV", e1_line[i]); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); } } sprintf(comm, " "); status = DALattributePut(gain, NULL, DAL_CHAR, NULL, NULL, (void*)comm, status); if (status != ISDC_OK) { printf("%d : Error while adding comments in %s.\n", status, gainDOL); continue; } // Close SPI.-COEF-CAL HDU status = DALobjectClose(gain, DAL_SAVE, status); if (status != ISDC_OK) { printf("%d : Error while closing %s.\n", status, gainDOL); continue; } // Free temporary memory delete [] det_id; delete [] e_range; delete [] obt_start; delete [] obt_end; delete [] ontime; } while(0); }