Changeset 36 for drsdaq/HVFeedback.cc
- Timestamp:
- 05/07/09 09:16:29 (16 years ago)
- Location:
- drsdaq
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq
- Property svn:ignore
-
old new 2 2 DRSDAQ.log 3 3 Dep.d 4 4 calib
-
- Property svn:ignore
-
drsdaq/HVFeedback.cc
r27 r36 17 17 18 18 #define MAX_RETRY 5 19 19 #define PIXMAP_LOCATION "../config/PixelMap.txt" 20 21 // 20 22 // Constructor: Initialise feedback 23 // 21 24 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) { 22 25 struct sockaddr_in SocketAddress; 23 26 char Filename[MAX_PATH]; 27 24 28 m = DAQClass; 25 PixMap = new PixelMap("../config/PixelMap.txt", false); 26 29 PixMap = new PixelMap(PIXMAP_LOCATION, false); 30 31 snprintf(Filename,sizeof(Filename),"%s/SlowData/", m->fRawDataPath); 32 SlowDataClass = new SlowData(m, "HVFB", Filename); 33 27 34 // Read configuration file 28 35 FILE *File; … … 32 39 else { 33 40 printf("Reading feedback configuration file %s\n", Configfile); 34 ReadCard("LedTrigBoard", &fLedTrigBoard, 'I', File); 35 ReadCard("LedTrigChannel", &fLedTrigChannel, 'I', File); 36 ReadCard("LedTrigChip", &fLedTrigChip, 'I', File); 37 ReadCard("LedTrigSample", &fLedTrigSample, 'I', File); 38 ReadCard("LedTrigThreshold", &fLedTrigThreshold, 'f', File); 39 ReadCard("LedSignalSample", &fLedSignalSample, 'I', File); 40 ReadCard("LedBaselineSample", &fLedBaselineSample, 'I', File); 41 ReadCard("DefaultNumAverage", &fDefaultNumAverage, 'I', File); 42 ReadCard("HVControlServer", fHVControlServer, 's', File); 43 ReadCard("HVControlPort", &fHVControlPort, 'I', File); 44 ReadCard("MaxCmdAckDelay", &fMaxCmdAckDelay, 'I', File); 41 ReadCard("TrigBoard", &fLedTrigBoard, 'I', File); 42 ReadCard("TrigChannel", &fLedTrigChannel, 'I', File); 43 ReadCard("TrigChip", &fLedTrigChip, 'I', File); 44 ReadCard("TrigSample", &fLedTrigSample, 'I', File); 45 ReadCard("TrigThreshold", &fLedTrigThreshold, 'f', File); 46 ReadCard("SignalSample", &fLedSignalSample, 'I', File); 47 ReadCard("BaselineSample", &fLedBaselineSample, 'I', File); 48 ReadCard("IntHalfWidth", &fIntHalfWidth, 'U', File); 49 ReadCard("DefaultNumAverage", &fDefaultNumAverage, 'I', File); 50 ReadCard("HVControlServer", fHVControlServer, 's', File); 51 ReadCard("HVControlPort", &fHVControlPort, 'I', File); 52 ReadCard("MaxCmdAckDelay", &fMaxCmdAckDelay, 'I', File); 45 53 fclose(File); 46 54 } … … 48 56 49 57 // Initialise 50 Average = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 51 Response = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 52 Target = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 53 Buffer = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels]; 54 58 Average = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 59 Sigma = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 60 Response = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 61 Target = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 62 Buffer = new float [m->NumCMCBoards][kNumberOfChips][kNumberOfChannels](); 63 64 /* for (int i=m->FirstBoard; i<=m->LastBoard; i++) 65 for (int j=0; j<kNumberOfChips; j++) 66 for (int k=0; k<kNumberOfChannels; k++) { 67 Response[i][j][k] = 0.0; 68 Target[i][j][k] = 0.0; 69 } 70 */ 55 71 Gain = 1; 56 72 SetFBMode(FB_Off); … … 77 93 } 78 94 95 // 79 96 // Destructor 97 // 80 98 HVFeedback::~HVFeedback() { 81 99 if (SocketDescriptor!=-1) { … … 85 103 delete[] Average; delete[] Response; 86 104 delete[] Target; delete[] Buffer; 87 delete PixMap;88 } 89 90 105 delete SlowDataClass; delete PixMap; 106 } 107 108 // 91 109 // Check if LED trigger present, if yes accumulate feedback data and 92 110 // calculate new high voltages if the required number of events is reached. 111 // 93 112 bool HVFeedback::ProcessEvent() { 94 float Correction; 113 int i,j,k,q; 114 float Correction, Integral, Difference, EffectiveGain; 95 115 96 116 // Check for LED trigger channel on given channel and if feedback running 97 117 if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][fLedTrigSample] < fLedTrigThreshold) 98 118 return false; 99 Count++;100 119 101 // Add signal at LED bin for all channels 102 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 103 for (int j=0; j<kNumberOfChips; j++) 104 for (int k=0; k<kNumberOfChannels; k++) 105 Average[i][j][k] += (m->WaveForm[i][j][k][fLedSignalSample] - m->WaveForm[i][j][k][fLedBaselineSample])*m->BStruct[i].ScaleFactor; 106 120 // Calculate average signal of LED pulse as integral of signal 121 for (i=m->FirstBoard; i<=m->LastBoard; i++) 122 for (j=0; j<kNumberOfChips; j++) 123 for (k=0; k<kNumberOfChannels; k++) { 124 for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) 125 Integral += (m->WaveForm[i][j][k][fLedSignalSample+q] - m->WaveForm[i][j][k][fLedBaselineSample+q])*m->BStruct[i].ScaleFactor; 126 Integral /= 2*fIntHalfWidth+1; 127 Average[i][j][k] += Integral; 128 Sigma[i][j][k] += pow(Integral,2); 129 } 130 131 if (++Count<NumAverages) return false; 132 107 133 // Acquired number of event requires action 108 if (Count==NumAverages) { 109 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 110 for (int j=0; j<kNumberOfChips; j++) 111 for (int k=0; k<kNumberOfChannels; k++) { 112 Average[i][j][k] /= Count; 113 switch (FBMode) { 114 case FB_Active: // Determine correction from response maxtrix and change voltages 115 Correction = (Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain; 116 if(Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) 117 WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction); 118 break; 119 case FB_Targets: // Take average as new targets 120 Target[i][j][k] = Average[i][j][k]; 121 break; 122 case FB_ResponseFirst: // First point of response measurement done 123 Buffer[i][j][k] = Average[i][j][k]; 124 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), Voltage2); 125 break; 126 case FB_ResponseSecond: // Determine response from signal variation 127 if(Buffer[i][j][k] == Average[i][j][k]) { 128 m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k); 129 Response[i][j][k] = 0; 130 } 131 else Response[i][j][k] = Voltage2/(Buffer[i][j][k]-Average[i][j][k]); 132 break; 133 default: break; // to suppress warning abount not handled enumeration value 134 } 135 } 136 switch (FBMode) { 137 case FB_Active: 138 m->PrintMessage("HV Feedback: Acted.\n"); 139 break; 140 case FB_Targets: 141 m->PrintMessage("HV Feedback: New targets set, switching off.\n"); 142 FBMode = FB_Off; 143 break; 144 case FB_ResponseFirst: 145 FBMode = FB_ResponseSecond; 146 m->PrintMessage("HV Feedback: Setting second voltage %f for response measurement, acquiring data.\n", Voltage2); 147 break; 148 case FB_ResponseSecond: 149 m->PrintMessage("HV Feedback: Response measurements finished, switching off.\n"); 150 FBMode = FB_Off; 151 break; 152 default: break; // to suppress warning abount not handled enumeration value 153 } 154 ClearAverages(); 155 return true; 156 } 157 else return false; 158 } 159 134 switch (FBMode) { 135 case FB_Active: SlowDataClass->NewEntry("Average"); break; 136 case FB_Targets: SlowDataClass->NewEntry("Target"); break; 137 case FB_ResponseSecond: SlowDataClass->NewEntry("Response"); SlowDataClass->AddToEntry("%.3f ",DiffVoltage); break; 138 default: break; // to suppress warning abount not handled enumeration value 139 } 140 141 for (i=m->FirstBoard; i<=m->LastBoard; i++) 142 for (j=0; j<kNumberOfChips; j++) 143 for (k=0; k<kNumberOfChannels; k++) { 144 Average[i][j][k] /= Count; 145 Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count); 146 switch (FBMode) { 147 case FB_Active: // Determine correction from response maxtrix and change voltages 148 Difference = Target[i][j][k] - Average[i][j][k]; 149 EffectiveGain = Gain*pow(0.5*(1+(Difference/Sigma[i][j][k]-1)/(Difference/Sigma[i][j][k]+1)),2); 150 Correction = -Difference*Response[i][j][k]*EffectiveGain; 151 if(Correction!=0 && Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) { 152 printf("Average of board %d, chip %d, channel %d is %.2f +/- %.2f Correction %.3f\n",i,j,k,Average[i][j][k],Sigma[i][j][k],Correction); 153 SlowDataClass->AddToEntry("%d %d %d %.3f %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k],Correction); 154 if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n"); 155 else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction); 156 } 157 break; 158 case FB_Targets: // Take average as new targets 159 Target[i][j][k] = Average[i][j][k]; 160 SlowDataClass->AddToEntry("%d %d %d %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k]); 161 break; 162 case FB_ResponseFirst: // First point of response measurement done 163 Buffer[i][j][k] = Average[i][j][k]; 164 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage); 165 break; 166 case FB_ResponseSecond: // Determine response from signal variation 167 if(Buffer[i][j][k] == Average[i][j][k]) { 168 m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k); 169 Response[i][j][k] = 0; 170 } 171 else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]); 172 SlowDataClass->AddToEntry("%d %d %d %.3f ", i,j,k,Response[i][j][k]); 173 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hvdiff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2); 174 break; 175 default: break; // to suppress warning abount not handled enumeration value 176 } 177 } 178 179 switch (FBMode) { 180 case FB_Targets: 181 m->PrintMessage("HV Feedback: New targets set, switching off.\n"); 182 FBMode = FB_Off; 183 break; 184 case FB_ResponseFirst: 185 FBMode = FB_ResponseSecond; 186 m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage); 187 break; 188 case FB_ResponseSecond: 189 m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n"); 190 FBMode = FB_Off; 191 break; 192 default: break; // to suppress warning abount not handled enumeration value 193 } 194 ClearAverages(); 195 return true; 196 } 197 198 // 160 199 // Clear average values and event counter 200 // 161 201 void HVFeedback::ClearAverages() { 162 202 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 163 203 for (int j=0; j<kNumberOfChips; j++) 164 for (int k=0; k<kNumberOfChannels; k++) Average[i][j][k] = 0; 204 for (int k=0; k<kNumberOfChannels; k++) { 205 Average[i][j][k] = 0.0; 206 Sigma[i][j][k] = 0.0; 207 } 165 208 Count = 0; 166 209 } 167 210 211 // 168 212 // Number of events to accumulate before correction acts 213 // 169 214 void HVFeedback::SetNumAverages(unsigned int Averages) { 170 215 NumAverages = Averages; 171 216 } 172 217 218 // 173 219 // Get requested number of events 220 // 174 221 unsigned int HVFeedback::GetNumAverages() { 175 222 return NumAverages; 176 223 } 177 224 225 // 178 226 // Set feedback gain 227 // 179 228 void HVFeedback::SetGain(float FBGain) { 180 229 Gain = FBGain; 181 230 } 182 231 232 // 183 233 // Get feedback gain 234 // 184 235 float HVFeedback::GetGain() { 185 236 return Gain; 186 237 } 187 238 239 // 188 240 // Set feedback mode and clear averages 241 // 189 242 void HVFeedback::SetFBMode(FBState Mode) { 190 243 if(Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) … … 196 249 } 197 250 251 // 198 252 // Set feedback mode and clear averages 253 // 199 254 FBState HVFeedback::GetFBMode() { 200 255 switch (FBMode) { … … 208 263 } 209 264 265 // 210 266 // Return current number of events 267 // 211 268 unsigned int HVFeedback::GetCurrentCount() { 212 269 return Count; 213 270 } 214 271 272 // 215 273 // Set target values 274 // 216 275 void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) { 217 276 if(Board<m->NumCMCBoards && Chip<kNumberOfChips && Channel<kNumberOfChannels) … … 220 279 } 221 280 281 // 222 282 // Print target values 283 // 223 284 void HVFeedback::GetTargets() { 224 285 for (int i=m->FirstBoard; i<=m->LastBoard; i++) … … 228 289 } 229 290 291 // 230 292 // Measure response matrix 231 void HVFeedback::MeasureResponse(float U1, float U2) { 232 233 if (U2 == 0) 234 m->PrintMessage("HV Feedback: Error, econd voltage must not bezero.\n");293 // 294 void HVFeedback::MeasureResponse(float U) { 295 296 if (U==0) m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n"); 235 297 else { 236 298 for (int i=m->FirstBoard; i<=m->LastBoard; i++) … … 238 300 for (int k=0; k<kNumberOfChannels-2; k++) { 239 301 if(PixMap->DRS_to_Pixel(i,j,k).empty()) m->PrintMessage("Could not find pixel ID of board %d, chip %d, channel %d\n",i,j,k); 240 else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), U1);302 else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2); 241 303 } 242 Voltage1 = U1; Voltage2 = U2;304 DiffVoltage = U; 243 305 FBMode = FB_ResponseFirst; 244 306 ClearAverages(); 245 m->PrintMessage("HV Feedback: Setting first voltage %f for response measurement, acquiring data.\n",U1); 246 } 247 } 248 307 m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2); 308 } 309 } 310 311 // 249 312 // Print response values 313 // 250 314 void HVFeedback::GetResponse() { 251 315 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 252 316 for (int j=0; j<kNumberOfChips; j++) 253 317 for (int k=0; k<kNumberOfChannels; k++) 254 m->PrintMessage("Board %d, chip %d, channel %d: %f\n",i,j,k,Response[i][j][k]); 255 } 256 318 m->PrintMessage("Board %d, chip %d, channel %d: %.3f\n",i,j,k,Response[i][j][k]); 319 } 320 321 // 257 322 // Write commmand to socket 323 // 258 324 bool HVFeedback::WriteHVCommand(const char *Format, ...) { 259 325 char Textbuffer[MAX_COM_SIZE]; … … 263 329 do { 264 330 va_list ArgumentPointer; va_start(ArgumentPointer, Format); 265 vsprintf(Textbuffer, Format, ArgumentPointer); 266 267 printf("%s", Textbuffer); 331 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer); 332 268 333 // Write command to socket 269 334 if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) { … … 295 360 } 296 361 362 // 297 363 // Print feedback configuration 364 // 298 365 void HVFeedback::PrintConfig() { 299 366 m->PrintMessage("LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n" 300 367 "LedTrigSample: %d\tLedTrigThreshold: %.2f\n" 301 368 "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n" 302 " HVControlServer: %s\tHVControlPort: %d\n"369 "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n" 303 370 "MaxCmdAckDelay: %d\n", 304 371 fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample, 305 372 fLedTrigThreshold, fLedSignalSample, fLedBaselineSample, 306 fDefaultNumAverage, f HVControlServer, fHVControlPort, fMaxCmdAckDelay);307 } 373 fDefaultNumAverage, fIntHalfWidth, fHVControlServer, fHVControlPort, fMaxCmdAckDelay); 374 }
Note:
See TracChangeset
for help on using the changeset viewer.