DAFNEStatWrite.c
INPUT
Il primo ingresso è dato dall'argomento della funzione elaborate, che viene chiamata dallo Storer.
elaborate(char* what).
La composizione di questa stringa di input, è quindi piena responsabilità dello Storer Labview.
La funzione elaborate prima di tutto acquisisce i dati della stringa, interpretandoli.
I dati che acquisisce sono descritti da questa porzione di codice.
strcpy(dafne[0,0] ,b0); /* UNIX format */ strcpy(dafne[0,1] ,b1); /* e- current */ strcpy(dafne[0,2] ,b2); /* e+ current */ strcpy(dafne[0,3] ,b3); /* IP1 lum */ strcpy(dafne[0,4] ,b4); /* IP1 limInt */ strcpy(dafne[0,5] ,b5); /* IP2 lum */ strcpy(dafne[0,6] ,b6); /* IP2 lumInt */ strcpy(dafne[0,7] ,b7); /* bumch 1-32 */ strcpy(dafne[0,8] ,b8); /* bunch 33-64 */ strcpy(dafne[0,9] ,b9); /* bunch 65-96 */ strcpy(dafne[0,10],b10); /* bunch 97-120 */ strcpy(dafne[0,11],b11); /* timing word */ strcpy(dafne[0,12],b12); /* acc pulse */ strcpy(dafne[0,13],b13); /* L0 IP1 */ strcpy(dafne[0,14],b14); /* I0 e+ IP1 cur */ strcpy(dafne[0,15],b15); /* I0 e- IP1 cur */ strcpy(dafne[0,16],b16); /* L0 IP2 */ strcpy(dafne[0,17],b17); /* I0 e+ IP2 cur */ strcpy(dafne[0,18],b18); /* I0 e- IP2 cur */ strcpy(dafne[0,19],b19); /* tick count */ strcpy(dafne[0,20],b20); /* RF frequency */ strcpy(dafne[0,23],b21); /* KLOE field */ strcpy(dafne[0,24],b22); /* BPMEL204 X */ strcpy(dafne[0,25],b23); /* BPMEL204 Y */ strcpy(dafne[0,26],b24); /* BPMEL205 X */ strcpy(dafne[0,27],b25); /* BPMEL205 Y */ strcpy(dafne[0,28],b26); /* BPMEL206 X */ strcpy(dafne[0,29],b27); /* BPMEL206 Y */ strcpy(dafne[0,30],b28); /* BPMEL207 X */ strcpy(dafne[0,31],b29); /* BPMEL207 Y */ strcpy(dafne[0,32],b30); /* DHSTB001 Amp */ strcpy(dafne[0,33],b31); /* DHSTB001 Pola */ strcpy(dafne[0,34],b32); /* DHSTB002 Amp */ strcpy(dafne[0,39],b33); /* DHRTB101 Amp */ strcpy(dafne[0,52],b46); /* 4TEM1001 [C] */ strcpy(dafne[0,53],b47); /* 4TEM1002 [C] */ strcpy(dafne[0,54],b48); /* 4TEM1003 [C] */ strcpy(dafne[0,55],b49); /* 4TEM1004 [C] */ strcpy(dafne[0,56],b50); /* BPMEL202 X */ strcpy(dafne[0,57],b51); /* BPMEL202 Y */ strcpy(dafne[0,58],b52); /* BPMEL203 X */ strcpy(dafne[0,59],b53); /* BPMEL203 Y */
Successivamente il codice intende scrivere "newdafne.stat" : il file testuale che leggiamo tramite la CU
All'interno della funzione di scrittura però i progettisti leggono gli altri quattro input. Tutti da file
fillfile = "/u2/data/temp/dafnefill.dat"
Il file è composto da una riga di questo tipo:
265413 7 103 FFF00007 FFFFFFFF FFFFFFFF FFFFFF00 103 FFF00007 FFFFFFFF FFFFFFFF FFFFFF00
I dati riempiono le seguenti variabili
fillnumber,laststatus, nbunche,bunch1e,bunch2e,bunch3e,bunch4e, nbunchp,bunch1p,bunch2p,bunch3p,bunch4p
QUESTO FILE VIENE SCRITTO dalla stessa procedura, che legge i dati vecchi, li modifica e li riscrive aggiornati.
currfile = "/u2/data/temp/current.dat"
Questo file viene usato nel calcolo del lifetime, sempre all'interno della procedura che dovrebbe soltanto scrivere.
1627403116 0.30 0 -0.45 0
1627403131 0.30 0 -0.45 0
1627403146 0.29 0 -0.45 0
Anche QUESTO FILE VIENE SCRITTO dalla stessa procedura, che legge i dati vecchi e poi li riscrive aggiornati
machinefile = "/u2/data/temp/machineStatus.dat"
Il file è composto da un solo valore, ed è fermo al 2006
1
Il dato finisce nella variabile generalStatus.
OUTPUT
textfile = "/u2/data/temp/dafne.txt"
estimated = /u2/data/temp/estimeted.dat
Questi file sono output generati dalla stessa routine. Se non li legge nessuno, possono essere eliminati.
CALCOLO LIFETIME
Chiamata:
status=lifeTime(fcurr, nowthere, curre, statuse, currp, statusp, &eLifeTime, &pLifeTime, &DeLT, &DpLT)
int lifeTime(char *where, int timeIn, double eCurrIn, int eStatusIn, double pCurrIn, int pStatusIn, double *eLifeTime, double *pLifeTime, double *DeLT, double *DpLT) { char b0[20], b1[20], b2[20], b3[20], b4[20]; char buffer[128]; FILE *fileStatus; char *status; int time[FIFOSIZE+1]; double eCurr[FIFOSIZE+1]; int eStatus[FIFOSIZE+1]; double pCurr[FIFOSIZE+1]; int pStatus[FIFOSIZE+1]; int bufferNumber = 0; int i, size, test, eIndex, pIndex; double dummyLT; fileStatus = fopen(where,"r") ; if(fileStatus==NULL) { printf("Can't open file %s\n", where); return 1; } /* read previous buffer */ do{ status = fgets(buffer, 128, fileStatus); test = sscanf(buffer, " %s %s %s %s %s", b0, b1, b2, b3, b4); switch (test) { case 5: if(status==NULL) break; bufferNumber++; time[bufferNumber] = atoi(b0); eCurr[bufferNumber] = atof(b1); eStatus[bufferNumber] = atoi(b2); pCurr[bufferNumber] = atof(b3); pStatus[bufferNumber] = atoi(b4); break; default: break; } }while (status != NULL); fclose(fileStatus);/* append new value or shift data and append new value */ if (bufferNumber<FIFOSIZE){ time[bufferNumber+1] = timeIn; eCurr[bufferNumber+1] = eCurrIn; eStatus[bufferNumber+1] = eStatusIn; pCurr[bufferNumber+1] = pCurrIn; pStatus[bufferNumber+1] = pStatusIn; size = bufferNumber + 1; }else{ for(i=1; i<FIFOSIZE; i++){ time[i] = time[i+1]; eCurr[i] = eCurr[i+1]; eStatus[i] = eStatus[i+1]; pCurr[i] = pCurr[i+1]; pStatus[i] = pStatus[i+1]; } time[FIFOSIZE] = timeIn; eCurr[FIFOSIZE] = eCurrIn; eStatus[FIFOSIZE] = eStatusIn; pCurr[FIFOSIZE] = pCurrIn; pStatus[FIFOSIZE] = pStatusIn; size = FIFOSIZE; }/* update data in file */ fileStatus = fopen(where,"w") ; if(fileStatus==NULL) { printf("Can't open file %s\n", where); return 1; } for (i=1; i<=size; i++){ fprintf(fileStatus, " %15d %7.2f %d %7.2f %d\n", time[i],eCurr[i],eStatus[i], pCurr[i],pStatus[i]); } fclose(fileStatus);
Porzione relativa ai calcoli
*eLifeTime = -1.0; *pLifeTime = -1.0; dummyLT = -1; if(eStatus[FIFOSIZE-1]>=3 && eStatus[FIFOSIZE]>=3){ i=FIFOSIZE; while (i>1){ i--; if(eStatus[i]>=3){ *eLifeTime = -1.0*(time[FIFOSIZE]-time[i])*(eCurr[i]/(eCurr[FIFOSIZE]-eCurr[i])); *DeLT = 5*( 0.01*(*eLifeTime)/eCurr[i]); /* five sigma */ eIndex=(FIFOSIZE-((*DeLT/FIFOSIZE)+1)); if (eIndex >= 1 && eIndex < FIFOSIZE){ dummyLT = -1.0*(time[FIFOSIZE]-time[eIndex])*(eCurr[eIndex]/(eCurr[FIFOSIZE]-eCurr[eIndex])); }else{ dummyLT = 0; } } } } *DeLT = dummyLT; dummyLT = -1; if(pStatus[FIFOSIZE-1]>=3 && pStatus[FIFOSIZE]>=3){ i=FIFOSIZE; while (i>1){ i--; if (pStatus[i]>=3){ *pLifeTime = -1.0*(time[FIFOSIZE]-time[i])*(pCurr[i]/(pCurr[FIFOSIZE]-pCurr[i])); *DpLT =5*( 0.01*(*pLifeTime)/pCurr[i]); /* five sigma */ pIndex=(FIFOSIZE-((*DpLT/FIFOSIZE)+1)); if (pIndex >= 1 && pIndex < FIFOSIZE){ dummyLT = -1.0*(time[FIFOSIZE]-time[pIndex])*(pCurr[pIndex]/(pCurr[FIFOSIZE]-pCurr[pIndex])); }else{ dummyLT = 0; } } } } *DpLT = dummyLT; /* life time limitated at 3 hours */ if (*eLifeTime > 10800 || *eLifeTime < -1) *eLifeTime = 0; if (*pLifeTime > 10800 || *pLifeTime < -1) *pLifeTime = 0; if (*DeLT > 36000 || *DeLT < -1) *DeLT = 0; if (*DpLT > 36000 || *DpLT < -1) *DpLT = 0; return 0;
Per replicare la funzione ho bisogno di
statuse : dipende da mode, storee, run, curre
statusp : dipende da storep mode run currp ENTRAMBI dipendono pure da statusBTF e da tick
curre: corrente Elettroni (la abbiamo via DB
currp: corrente Positroni (la abbiamo via DB
statusBTF vale 1 o 0. 1 se (atof(dafne[0,39]) >= 50)
dafne[0,39] deriva dal "what" dello Storer Labview e questo codice gli assegna il significato seguente:
strcpy(dafne[0,39],b33); /* DHRTB101 Amp */
tick deriva dal "what" dello Storer Labivew, definisce la collisione negli IP è un intero
strcpy(dafne[0,19],b19); /* tick count */
mode e run sono definiti così
sscanf(dafne[0,11],"%x",&status1);
mode = (status1 & 0x00080) >> 7; /* linac mode e+ e- */
run = (status1 & 0x10000) >>16; /* linac run standby */
dafne[0,11] deriva dal "what" dello Storer Labview e questo codice gli assegna il significato seguente:
strcpy(dafne[0,11],b11); /* timing word */
storee e storep
derivano semplicemente da mode run e le correnti. Le abbiamo una volta risolto il punto precedente.
Dopodiché possiamo calcolare la lifetime
CONSIDERAZIONI
Sostanzialmente nonostante la funzione elaborate abbia 4 ingressi, in realtà gli unici dati di input necessari, sono quelli dell'input dallo storer. Gli altri tre infatti sono
1)file di correnti, che viene scritto dalla stessa funzione.
2)file di fill che viene scritto dalla stessa funzione.
3) file di machinestatus che è ad 1 dal 2006 e può essere sostituito da una costante.
Le uniche preoccupazioni possono venire dai due file di output, che in teoria, potrebbero essere letti da qualcuno.
Attualmente i dati che SONO NECESSARI per la comunicazione con Siddharta, ancora letti tramite newdafne.stat sono:
*p_dafne_status
*p_nbunch_ele
*p_nbunch_pos
*p_fill_pattern_ele
*p_fill_pattern_pos
*p_lifetime_ele
*p_lifetime_pos
*p_rf
*p_ty_ele
*p_ty_pos