#include #include #include #include #include #include #include #include "camlib.h" #define TIME_CORRECTION -21*60-5 #define FILE_WRITING_RATE 1 #define LOG_MAX 100 #define FILENAME_LENGTH 100 #define CHANNEL_MAX 16 #define RACK_MAX 25 #define IDOLING 1000 #define YEAR_LIMIT 2100 #define READ 0 #define RECALL 2 #define LAM 8 #define ENLAM 8 #define CLR 9 #define WRITE 16 struct data_taking{ long l_events; long l_time; int rack[RACK_MAX]; int channel[RACK_MAX][CHANNEL_MAX]; int NumberOfRack; int NumberOfChannel[RACK_MAX]; int data[RACK_MAX][FILE_WRITING_RATE][CHANNEL_MAX]; long NumberOfData[RACK_MAX]; int pace; char filename[FILENAME_LENGTH+10]; time_t startTime, currentTime, endTime, lastTime, log[LOG_MAX]; FILE *datafile; FILE *logfile; }; void printhelp(void); void checkarg(int argc, char *arg1); void getmethod(struct data_taking *property, char *arg1, char *arg2); void getfileinfo(struct data_taking *property, char *arg3); void getADCinfo(struct data_taking *property, int argc, char *arg4); void initi_CAMAC(void); void startmessage(struct data_taking *property); void endmessage(struct data_taking *property); void getdata(struct data_taking *property, int *q, int *x, int currentmodule, long events); void taketimelog(struct data_taking *property, long events); void writedata(struct data_taking *property, int currentmodule, int k); void writelog(struct data_taking *property, long events); int endjudge(struct data_taking *property, long events); long getseconds(char *arg2); time_t Date2Time(char *givenDate, time_t start); int readtime(char **readstart, int date_min, int date_max); void printDate(time_t *time); void printTime(time_t *time); void printHour(long seconds); void fprintDate(FILE *file, time_t *time); void fprintTime(FILE *file, time_t *time); void fprintHour(FILE *file, long seconds); int main(int argc, char *argv[]){ long i, j; int dumy, q = 0, x = 0; int check_idoling[RACK_MAX] = { 0 }; struct data_taking property = { 0 }; checkarg( argc, argv[1] ); /* get ADC information */ getADCinfo( &property, argc, argv[4] ); /* check the length of filename and open data file */ getfileinfo( &property, argv[3] ); /* get the number of data to take or time of data taking */ getmethod( &property, argv[1], argv[2] ); /* preparation of CAMAC */ if( CAMOPN() ){ printf("CAMAC open error.\n"); exit(1); } initi_CAMAC(); for( i=0 ; i= IDOLING ){ initi_CAMAC(); CAMAC(NAF(property.rack[j], 0, CLR), &dumy, &q, &x); check_idoling[j] = 0; } } } if( endjudge( &property, i ) ) break; } CAM_Close(); for( i=0 ; i>\n"); printf(" (excutive file name) events/for/until (number/time/date) (filename) (rack number):(channel...)...\n"); printf("\n"); printf("events/for/until :\n"); printf(" When take data of fixed number, input \"events\" and the number.\n"); printf(" When fix data taking time, input \"for\" and the time(second).\n"); printf(" When fix the finish time, input \"until\" followed by the data and time.\n"); printf(" (In inputting the data and time, all of the year, month, day, hour, minute\n"); printf(" and second are needed. Year, month and hour can be omitted.\n"); printf(" Each itme must be seprated by one letter except numbers and space.)\n"); printf("filename :\n"); printf(" Input the file name of data and log file.\n"); printf(" Period and extention are not needed.\n"); printf(" (\".dat\" and \".log\" automatically added.)\n"); printf("rack and channle number :\n"); printf(" Input the CAMAC rack number where the ADC modules are inserted followed by the channels\n"); printf(" The rack number and each of channel numbers must be divided by one letter except numbers and space."); printf("\n"); printf("input anykey to see next..."); c = getchar(); printf("\n"); printf("<>\n"); printf("More detail setting is available by editting the source code of this program.\n"); printf("There list constans and their explanations defined in the head of this program.\n"); printf("\n"); printf("TIME_CORRECTION :\n"); printf(" If the clock of the computer is not correct, adjust it by this value.\n"); printf("FILE_WRITING_RATE :\n"); printf(" Set per how many events to write the data and the log to the file.\n"); printf(" (Default 1)\n"); printf("LOG_MAX :\n"); printf(" Set the maxium number of how many times to record time when data can be gained.\n"); printf(" (Default 100)\n"); printf("FILENAME_LENGTH :\n"); printf(" Set the maximum length of the data and log file including its pass.\n"); printf(" (Default 100)\n"); printf("CHANNEL_MAX :\n"); printf(" Set the number of channels of the ADC module. \n"); printf("RACK_MIN,RACK_MAX :\n"); printf(" Set the possible maximum number of CAMAC modules which can be inserted in the rack at once.\n"); printf("IDOLING :\n"); printf(" If data can\'t be gained as many times successively as set in this value, initilize CAMAC.\n"); printf(" (Default 1000)\n"); printf("YEAR_LIMIT :\n"); printf(" Caution is made when the year over this value is input.\n"); printf(" (when fix the data taking finish time, default 2100)\n"); printf("\n"); printf("completed at 2008/ 1/15, by Maeda Yosuke\n"); return; } void checkarg(int argc, char *arg1){ if( (argc == 1) || (strcmp(arg1, "?") == 0) || (strcmp(arg1, "help") == 0) ){ printhelp(); exit(0); } if( argc < 5 ){ printf("The number of argments is incorrect!!\n"); exit(1); } return; } void getmethod(struct data_taking *property, char *arg1, char *arg2){ property->startTime = time( NULL ) + TIME_CORRECTION; property->pace = 1; if( strcmp(arg1,"events") == 0 ){ property->l_events = atoi( arg2 ); while( 1 ){ if( property->l_events / property->pace > LOG_MAX ) property->pace *= 10; else break; } } else if( strcmp(arg1,"for") == 0 ){ property->l_time = getseconds( arg2 ); property->endTime = property->startTime + property->l_time; } else if( strcmp(arg1,"until") == 0 ){ property->endTime = Date2Time( arg2, property->startTime ); property->l_time = property->endTime - property->startTime; } else{ printf("Invalid arguments : \"%s\"\n", arg1); printf("First argument must be \"events\", \"for\" or \"until\".\n"); exit(1); } return; } void getfileinfo(struct data_taking *property, char *arg3){ int i,j,c; char name[FILENAME_LENGTH+10]; FILE *file; if( strlen(arg3) >= FILENAME_LENGTH ){ printf("Filename or path is too long : \"%s\"\n", arg3); exit(1); } strcpy(property->filename, arg3); for( i=0 ; i<2 ; i++ ){ for( j=0 ; jNumberOfRack ; j++ ){ if( i==0 ) sprintf(name, "%s_%02d.dat", property->filename, j); else{ sprintf(name, "%s.log", property->filename); j = property->NumberOfRack; } if( (file = fopen(name, "r")) != NULL ){ printf("File \"%s\" already exists. Replace?(y/n)", name); c = getchar(); if( c != 'y' ){ printf("Please retry with another file name.\n"); fclose( file ); exit(1); } fclose( file ); } } if( (file = fopen(name,"w")) == NULL ){ printf("File: %s open error!!\n", name); exit(1); } fclose( file ); } return; } void getADCinfo(struct data_taking *property, int argc, char *arg4){ int i, j=0; char *readstart, *partition; property->NumberOfModule = argc - 1; readstart = arg4; for( i=0 ; iNumberOfModule ; i++ ){ property->rack[i] = strtol(readstart, &partition, 10); if( property->rack[i] <= 0 || property->rack[i] > RACK_MAX ){ printf("Invalid rack number : %d\n", property->rack[i]); exit(1); } while( *partition != NULL ){ readstart = partition + 1; property->channel[i][j] = strtol(readstart, &partition, 10); if( (readstart == partition) || (property->channel[i][j] < 0 || property->channel[i][j] >= CHANNEL_MAX) ){ printf("Invalid channel number : %d\n", property->channel[i][j]); exit(1); } j++; } property->NumberOfChannel[i] = j; j = 0; readstart = partition + 1; } return; } void initi_CAMAC(void){ CSETCR(0); CGENZ(); CGENC(); CREMI(); return; } void startmessage(struct data_taking *property){ int i,j; printf("----- ADC data taking -----\n"); printf("***"); if( (long)property->endTime == 0 ) printf("the number of data"); else printf("data taking time"); printf(" is fixed***\n"); printf(" CAMAC rack No. and ADC channel No.\n"); for( i=0 ; iNumberOfRack ; i++ ){ printf(" %2d : ", property->rack[i]); for( j=0 ; jNumberOfChannel[i] ; j++ ) printf( ( j==property->NumberOfChannel[i]-1 ) ? "%2d\n" : "%2d, " , property->channel[i][j] ); } printf(" start time : "); printDate( &property->startTime ); printf(" "); printTime( &property->startTime ); printf("\n"); if( (long)property->endTime == 0 ) printf(" number of total data : %d events\n",property->l_events); else{ printf(" data taking time : %d seconds (", property->l_time); printHour( property->l_time ); printf("), until " ); printDate( &property->endTime ); printf(" "); printTime( &property->endTime ); printf("\n"); } printf("---------------------------\n"); printf("Start datataking...\n"); return; } void endmessage(struct data_taking *property){ int i; printf("---------------------------\n"); printf("\aData taking has successfully finished (at "); printDate( &property->currentTime ); printf(" "); printTime( &property->currentTime ); printf(").\n"); printf("Get total %d events for %d seconds(", property->l_events, property->l_time); printHour( property->l_time ); printf(").\n"); for( i= 0 ; iNumberOfRack ; i++ ){ printf(" module%02d (Rack No. %2d) : %d\n", i, property->rack[i], property->NumberOfData[i]); } printf("Data is recorded in \"%s.dat\", ", property->filename); printf("and its log is recorded in \"%s.log\".\n\n", property->filename); return; } void getdata(struct data_taking *property, int *q, int *x, int currentmodule, long events){ int i; static int j[RACK_MAX] = { 0 }; int ref; printf("%2d : ", property->rack[currentmodule]); for( i=0 ; iNumberOfChannel[currentmodule] ; i++ ){ CAMAC(NAF(property->rack[currentmodule], property->channel[currentmodule][i], READ), &ref, q, x); printf("%6d ", ref); property->data[ currentmodule ][ j[currentmodule] ][ i ] = ref; } j[currentmodule]++; if( j[currentmodule] == FILE_WRITING_RATE ){ writedata( property, currentmodule, j[currentmodule] ); writelog( property, events ); printf(" %5dth data,", events); printHour( (long)difftime(property->currentTime, property->startTime) ); printf(", "); printTime( &property->currentTime ); j[currentmodule] = 0; } printf("\n"); return; } void taketimelog(struct data_taking *property, long events){ if( events % property->pace == 0 ){ if( (events / property->pace) <= LOG_MAX ) property->log[ events/property->pace - 1 ] = property->currentTime; if( (long)property->endTime != 0 ){ if( ( property->currentTime == property->startTime ) || ( (property->l_time / (long)difftime(property->currentTime, property->startTime) ) > LOG_MAX) ) property->pace *= 10; } } property->lastTime = property->currentTime; return; } void writedata(struct data_taking *property, int currentmodule, int k){ int i,j; char name[FILENAME_LENGTH+10]; sprintf(name, "%s_%2d.dat", property->filename, currentmodule); if( (property->datafile = fopen(name,"a")) == NULL ){ printf("File: %s open error!!\n", name); exit(1); } for( i=0 ; iNumberOfChannel[currentmodule]-1 ; j++ ) fprintf(property->datafile, "%6d ", property->data[ currentmodule ][i][j]); fprintf(property->datafile, "%6d\n", property->data[currentmodule][i][j]); } fclose(property->datafile); for( i=0 ; iNumberOfChannel[currentmodule] ; j++ ) property->data[currentmodule][i][j] = 0; return; } void writelog(struct data_taking *property, long events){ int i,j; long timediff; char name[FILENAME_LENGTH+10]; sprintf(name, "%s.log", property->filename); if( (property->logfile = fopen(name,"w")) == NULL ){ printf("File: %s open error!!\n", name); exit(1); } timediff = (long)difftime(property->currentTime, property->startTime); fprintf(property->logfile, "The log of \"%s_", property->filename); for( i=0 ; iNumberfRack-1 ; i++ ) fprintf(property->logfile, "%02d, ", i); fprintf(property->logfile, "%02.dat\".\n\n", i); fprintf(property->logfile, "-----ADC data taking by %d modules-----\n", property->NumberOfRack); if( (long)property->endTime == 0 ) fprintf(property->logfile, " (the number of data is fixed)\n"); else fprintf(property->logfile, " (data taking time is fixed)\n\n"); fprintf(property->logfile, "used CAMAC Rack No. and ADC channels\n"); for( i=0 ; iNumberOfRack ; i++){ fprintf(property->logfile, " %2d : ", property->rack[i]); for( j=0 ; jNumberOfChannel[i]-1 ; i++ ){ fprintf(property->logfile, ( j==property->NumberOfChannel[i]-1 ) ? "%2d\n" : "%2d, " , property->channel[i][j]); } } fprintf(property->logfile, "\n"); fprintf(property->logfile, "start time : "); fprintDate( property->logfile, &property->startTime ); fprintf(property->logfile, " "); fprintTime( property->logfile, &property->startTime ); fprintf(property->logfile, "\n"); fprintf(property->logfile, "end time : "); fprintDate( property->logfile, &property->currentTime ); fprintf(property->logfile, " "); fprintTime( property->logfile, &property->currentTime ); fprintf(property->logfile, "\n\n"); fprintf(property->logfile, "number of total data : %d events\n", events); for( i=0 ; iNumberOfRack ; i++ ){ fprintf(property->logfile, " module%02d (Rack No. %2d) : %d\n", i, property->rack[i], property->NumberOfData[i]); } fprintf(property->logfile, "data taking time : %d seconds (", timediff); fprintHour( property->logfile, timediff); fprintf(property->logfile, ")\n"); if( (long)property->endTime == 0 ){ if( events != property->l_events ){ fprintf(property->logfile, "*This data taking was discontinued halfway.\n"); fprintf(property->logfile, " Originally intended number of total data was %d events.\n", property->l_events); } } else{ if( property->currentTime < property->endTime ){ fprintf(property->logfile, "*This data taking was discontinued halfway.\n"); fprintf(property->logfile, " Originally intended data taking time was %d seconds (", property->l_time); fprintHour( property->logfile, property->l_time ); fprintf(property->logfile, "), until "); fprintDate( property->logfile, &property->endTime ); fprintf(property->logfile, " "); fprintTime( property->logfile, &property->endTime ); fprintf(property->logfile, ".\n"); } } fprintf(property->logfile, "\n"); fprintf(property->logfile, "-----time log of data taking\n"); fprintf(property->logfile, " start time : 0 seconds ( 0h 0m 0s), "); fprintTime( property->logfile, &property->startTime ); fprintf(property->logfile, "\n"); for( i=0 ; (i < events/property->pace) && (i < LOG_MAX) ; i++ ){ if( (i == events/property->pace-1) && property->log[i] == 0 ) property->log[i] = property->currentTime; timediff = (long)difftime(property->log[i], property->startTime); fprintf(property->logfile, "%5dth data : %6d seconds (", (i+1)*property->pace, timediff); fprintHour( property->logfile, timediff ); fprintf(property->logfile, "), "); fprintTime( property->logfile, &property->log[i] ); fprintf(property->logfile, "\n"); } if( events != i*property->pace ){ timediff = (long)(property->lastTime - property->startTime); fprintf(property->logfile, "%5dth data : %6d seconds (", events, timediff); fprintHour( property->logfile, timediff); fprintf(property->logfile, "), "); fprintTime( property->logfile, &property->lastTime ); fprintf(property->logfile, "\n"); } fclose(property->logfile); return; } int endjudge(struct data_taking *property, long events){ if( (long)property->endTime == 0 ) if( events == property->l_events ){ property->l_time = (long)difftime(property->currentTime, property->startTime); return 1; } if( (long)property->endTime != 0 ) if( property->currentTime >= property->endTime ){ property->l_events = events; return 1; } return 0; } long getseconds(char *arg2){ long seconds; char last; char *partition; last = arg2[ strlen(arg2) - 1 ]; if( last == 'h' ) seconds = 3600 * strtod( argv[1], partition ); else if( last == 'm' ) seconds = 60 * strtod( argv[1], partition ); else seconds = atoi(argv[1]); return seconds; } time_t Date2Time(char *givenDate, time_t start){ int length; char *readstart; time_t end; struct tm *current,gain; current = localtime( &start ); gain = *current; readstart = givenDate; length = strlen( readstart ); if( (length <= 19) && (length >= 14) ){ gain.tm_year = readtime( &readstart, 1900, YEAR_LIMIT ) - 1900; gain.tm_mon = readtime( &readstart, 1, 12 ) - 1; gain.tm_mday = readtime( &readstart, 1, 31 ); length = strlen( readstart ); } if( (length <= 8) && (length >= 5) ){ gain.tm_hour = readtime( &readstart, 0, 23 ); gain.tm_min = readtime( &readstart, 0, 59 ); gain.tm_sec = readtime( &readstart, 0, 61 ); } else{ printf("Invalid date or time : %s\n",readstart); exit(1); } end = mktime( &gain ); if( end < start ) end += 24*60*60; if( end < start ){ printf("Invalid date : %s\n",givenDate); exit(0); } return end; } int readtime(char **readstart, int date_min, int date_max){ int get; char *partition; get = strtol( *readstart, &partition, 10 ); if( ( get < date_min ) || ( get > date_max ) ){ printf("Invalid date or time : %s\n",*readstart); printf(" ^\n"); exit(1); } *readstart = partition + 1; return get; } void printDate(time_t *time){ struct tm *calendar; calendar = localtime( time ); printf("%d/%2d/%2d", calendar->tm_year + 1900, calendar->tm_mon + 1, calendar->tm_mday); return; } void printTime(time_t *time){ struct tm *calendar; calendar = localtime( time ); printf("%2d:%2d:%2d", calendar->tm_hour, calendar->tm_min, calendar->tm_sec); return; } void printHour(long seconds){ printf("%2dh%2dm%2ds", seconds / 3600, (seconds % 3600) / 60, seconds % 60 ); return; } void fprintDate(FILE *file, time_t *time){ struct tm *calendar; calendar = localtime( time ); fprintf(file, "%d/%2d/%2d", calendar->tm_year + 1900, calendar->tm_mon + 1, calendar->tm_mday); return; } void fprintTime(FILE *file, time_t *time){ struct tm *calendar; calendar = localtime( time ); fprintf(file, "%2d:%2d:%2d", calendar->tm_hour, calendar->tm_min, calendar->tm_sec); return; } void fprintHour(FILE *file, long seconds){ fprintf(file, "%2dh%2dm%2ds", seconds / 3600, (seconds % 3600) / 60, seconds % 60 ); return; }