Changeset 175 for drsdaq/HVFeedback.cc
- Timestamp:
- 03/10/10 09:11:58 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
drsdaq/HVFeedback.cc
r140 r175 12 12 #include "PixelMap.h" 13 13 14 #include <sys/socket.h>15 #include <netdb.h>16 #include <signal.h>17 18 14 #define PIXMAP_LOCATION "../config/PixelMap.txt" 19 15 16 static const char* FBState_Description[] = { 17 "Feedback off", 18 "Feedback active", 19 "Feedback acquiring new targets", 20 "Feedback measuring response with first voltage", 21 "Feedback measuring response with second voltage" 22 }; 23 20 24 // 21 25 // Constructor: Initialise feedback 22 26 // 23 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile) {24 struct sockaddr_in SocketAddress; 27 HVFeedback::HVFeedback(DAQReadout* DAQClass, char* Configfile): 28 EvidenceServer(SERVER_NAME){ 25 29 26 30 m = DAQClass; 31 //fNumberOfChannels = m->fNumberOfChannels; 32 //fNumberOfChips = m->fNumberOfChips; 33 fNumberOfChannels = 10; 34 fNumberOfChips = 2; 35 27 36 PixMap = new PixelMap(PIXMAP_LOCATION, false); 28 37 29 // Create instance of slow data class for feedback30 SlowDataClass = new SlowData("HVFB", m->fSlowDataPath);31 if (SlowDataClass->ErrorCode != 0) {32 m->PrintMessage("Warning: Could not open feedback slowdata file (%s)\n", strerror(SlowDataClass->ErrorCode));33 }34 SlowDataClass->NewEntry("Average-Info", "Feedback regulation occurred: Board Chip Channel Average Sigma Correction-Value");35 SlowDataClass->NewEntry("Target-Info", "New Target values acquired: Board Chip Channel Target Sigma");36 SlowDataClass->NewEntry("Response-Info", "New response measurement: Board Chip Channel Response");37 38 38 // Initialise with zero content 39 Average = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 40 Sigma = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 41 Response = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 42 Target = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 43 Buffer = new float [m->NumBoards][kNumberOfChips][kNumberOfChannels](); 39 Average = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 40 Sigma = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 41 Response = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 42 Target = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 43 Buffer = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 44 45 DIMAverage = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 46 DIMSigma = new float [m->NumBoards][kNumberOfChipsMax][kNumberOfChannelsMax](); 44 47 45 48 // Read configuration file … … 59 62 ReadCard("IntHalfWidth", &fIntHalfWidth, 'U', File); 60 63 ReadCard("DefaultNumAverage", &fDefaultNumAverage, 'I', File); 61 ReadCard("HVControlServer", fHVControlServer, 's', File); 62 ReadCard("HVControlPort", &fHVControlPort, 'I', File); 63 ReadCard("MaxCmdAckDelay", &fMaxCmdAckDelay, 'I', File); 64 ReadCard("DefaultResponse", Response, 'f', File, m->NumBoards*kNumberOfChips*kNumberOfChannels); 65 ReadCard("DefaultTarget", Target, 'f', File, m->NumBoards*kNumberOfChips*kNumberOfChannels); 64 ReadCard("DefaultResponse", Response, 'f', File, m->NumBoards*fNumberOfChips*fNumberOfChannels); 65 ReadCard("DefaultTarget", Target, 'f', File, m->NumBoards*fNumberOfChips*fNumberOfChannels); 66 66 // Add also initial gain to configuration parameters 67 67 fclose(File); 68 68 } 69 69 PrintConfig(MsgToLog); 70 70 71 // Provide DIM services 72 FeedbackAverage = new DimService (SERVER_NAME"/Average", "F", DIMAverage, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float)); 73 FeedbackSigma = new DimService (SERVER_NAME"/Sigma", "F", DIMSigma, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float)); 74 FeedbackResponse = new DimService (SERVER_NAME"/Response", "F", Response, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float)); 75 FeedbackTarget = new DimService (SERVER_NAME"/Target", "F", Target, m->NumBoards*kNumberOfChipsMax*kNumberOfChannelsMax*sizeof(float)); 76 CountService = new DimService (SERVER_NAME"/Count", Count); 77 71 78 // Initial state 72 79 Gain = 0.2; 73 80 SetFBMode(FB_Off); 74 81 SetNumAverages(fDefaultNumAverage); 75 76 // Opening socket client to HV control program 77 if ((SocketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) == -1) 78 m->PrintMessage("Could not open client socket, no HV control available.\n"); 79 80 // Resolve hostname and try to connect to server 81 struct hostent *hostent = gethostbyname(fHVControlServer); 82 if (hostent==0) 83 m->PrintMessage("Could not resolve HV server host name \"%s\".\n", fHVControlServer); 84 else { 85 SocketAddress.sin_family = PF_INET; 86 SocketAddress.sin_port = htons((unsigned short) fHVControlPort); 87 SocketAddress.sin_addr = *(struct in_addr*) hostent->h_addr; 88 89 if (connect(SocketDescriptor, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress))==-1) 90 m->PrintMessage("Could not connect to HV server %s at port %d (%s)\n", fHVControlServer, fHVControlPort, strerror(errno)); 91 else m->PrintMessage("\nFeedback connected to HV server %s (port %d).\n", fHVControlServer, fHVControlPort); 92 signal(SIGPIPE,SIG_IGN); // Do not kill process if writing to closed socket 93 } 82 LastServiceUpdate = 0; 94 83 } 95 84 … … 98 87 // 99 88 HVFeedback::~HVFeedback() { 100 if (SocketDescriptor!=-1) { 101 close(SocketDescriptor); 102 m->PrintMessage("Feedback socket closed.\n"); 103 } 89 90 delete CountService; 91 delete FeedbackAverage; 92 delete FeedbackSigma; 93 delete FeedbackResponse; 94 delete FeedbackTarget; 95 104 96 delete[] Average; delete[] Response; 105 97 delete[] Target; delete[] Buffer; 106 delete SlowDataClass; deletePixMap;98 delete PixMap; 107 99 } 108 100 … … 113 105 bool HVFeedback::ProcessEvent() { 114 106 int i,j,k,q; 115 float Correction, Integral , Difference;107 float Correction, Integral; 116 108 117 109 // Check for LED trigger channel on given channel and if feedback running 118 if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][(fLedTrigSample+m->TriggerCell[fLedTrigBoard][fLedTrigChip])%kNumberOfBins] < fLedTrigThreshold) 110 if (FBMode==FB_Off || m->WaveForm[fLedTrigBoard][fLedTrigChip][fLedTrigChannel][(fLedTrigSample+m->TriggerCell[fLedTrigBoard][fLedTrigChip])%kNumberOfBins] < fLedTrigThreshold) { 119 111 return false; 112 } 120 113 121 114 // Calculate average signal of LED pulse as integral of signal 122 for (i=m->FirstBoard; i<=m->LastBoard; i++) 123 for (j=0; j<kNumberOfChips; j++) 124 for (k=0; k<kNumberOfChannels; k++) {125 for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++)115 for (i=m->FirstBoard; i<=m->LastBoard; i++) { 116 for (j=0; j<fNumberOfChips; j++) { 117 for (k=0; k<fNumberOfChannels; k++) { 118 for (Integral=0, q=-fIntHalfWidth; q<=(int) fIntHalfWidth; q++) { 126 119 Integral += (m->WaveForm[i][j][k][(fLedSignalSample+q+m->TriggerCell[i][j])%kNumberOfBins] - m->WaveForm[i][j][k][(fLedBaselineSample+q+m->TriggerCell[i][j])%kNumberOfBins])*m->drs->GetBoard(i)->GetPrecision(); 120 } 127 121 Integral /= 2*fIntHalfWidth+1; 128 Average[i][j][k] += Integral;122 Average[i][j][k] += Integral; 129 123 Sigma[i][j][k] += pow(Integral,2); 130 124 } 131 125 } 126 } 127 128 // Update DIM service regularly 129 if (time(NULL)-LastServiceUpdate > 2) { 130 LastServiceUpdate = time(NULL); 131 CountService->updateService(); 132 } 132 133 // Check if acquired number of event requires action 133 134 if (++Count<NumAverages) return false; 134 135 135 // Make entry in slow data file136 switch (FBMode) {137 case FB_Active: SlowDataClass->NewEntry("Average");138 break;139 case FB_Targets: SlowDataClass->NewEntry("Target");140 break;141 case FB_ResponseSecond: SlowDataClass->NewEntry("Response");142 SlowDataClass->AddToEntry("%.3f ",DiffVoltage);143 break;144 default: break; // to suppress warning abount not handled enumeration value145 }146 147 136 // Feedback action 148 137 for (i=m->FirstBoard; i<=m->LastBoard; i++) { 149 for (j=0; j<kNumberOfChips; j++) { 150 for (k=0; k<kNumberOfChannels; k++) { 138 for (j=0; j<fNumberOfChips; j++) { 139 for (k=0; k<fNumberOfChannels; k++) { 140 // Calculate average 151 141 Average[i][j][k] /= Count; 152 142 Sigma[i][j][k] = sqrt(Sigma[i][j][k]/Count-pow(Average[i][j][k],2))/sqrt(Count); 143 DIMAverage[i][j][k] = Average[i][j][k]; 144 DIMSigma[i][j][k] = Sigma[i][j][k]; 145 153 146 switch (FBMode) { 154 147 case FB_Active: // Determine correction from response maxtrix and change voltages 155 Difference = Target[i][j][k] - Average[i][j][k];156 Correction = -Difference*Response[i][j][k]*Gain; 157 //if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1; // Limit changes to 100 mV158 if(Correction!=0 && Target[i][j][k]!=0 && !PixMap->DRS_to_Pixel(i,j,k).empty()) { 159 160 SlowDataClass->AddToEntry("%d %d %d %.3f %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k],Correction); 161 162 else WriteHVCommand("hvdiff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(),Correction);163 } 148 Correction = -(Target[i][j][k] - Average[i][j][k])*Response[i][j][k]*Gain; 149 if (fabs(Correction) > 0.1) Correction = fabs(Correction)/Correction*0.1; // Limit changes to 100 mV 150 if(Correction==0 || Target[i][j][k] ==0 || PixMap->DRS_to_Pixel(i,j,k).empty()) break; 151 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 154 if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n"); 155 else WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), Correction); 156 164 157 break; 158 165 159 case FB_Targets: // Take average as new targets 166 160 Target[i][j][k] = Average[i][j][k]; 167 SlowDataClass->AddToEntry("%d %d %d %.3f %.3f ", i,j,k,Average[i][j][k],Sigma[i][j][k]);168 161 break; 169 case FB_ResponseFirst: // First point of response measurement done 162 163 case FB_ResponseFirst: // First point of response measurement done 170 164 Buffer[i][j][k] = Average[i][j][k]; 171 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv diff %s %f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);165 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage); 172 166 break; 173 case FB_ResponseSecond: // Determine response from signal variation 167 168 case FB_ResponseSecond: // Determine response from signal variation 174 169 if(Buffer[i][j][k] == Average[i][j][k]) { 175 170 m->PrintMessage("HV Feedback: Warning, response singular for board %d, chip %d, channel %d.\n",i,j,k); … … 177 172 } 178 173 else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]); 179 SlowDataClass->AddToEntry("%d %d %d %.3f ", i,j,k,Response[i][j][k]); 180 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 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2); 181 175 break; 176 182 177 default: break; // to suppress warning abount not handled enumeration value 183 178 } 184 } 185 } 186 } 187 179 } // for() channels 180 } // for() chips 181 } // for() boards 182 183 // Update DIM service 184 FeedbackAverage->updateService(); 185 FeedbackSigma->updateService(); 186 188 187 switch (FBMode) { 189 188 case FB_Targets: 189 FeedbackTarget->updateService(); 190 190 m->PrintMessage("HV Feedback: New targets set, switching off.\n"); 191 FBMode = FB_Off;191 SetFBMode(FB_Off, true); 192 192 break; 193 193 case FB_ResponseFirst: 194 FBMode = FB_ResponseSecond;194 SetFBMode(FB_ResponseSecond, true); 195 195 m->PrintMessage("HV Feedback: Increasing voltages by %f for response measurement, acquiring data.\n", DiffVoltage); 196 196 break; 197 197 case FB_ResponseSecond: 198 FeedbackResponse->updateService(); 198 199 m->PrintMessage("HV Feedback: Response measurements finished, original voltages set, switching off.\n"); 199 FBMode = FB_Off;200 SetFBMode(FB_Off, true); 200 201 break; 201 202 default: break; // to suppress warning abount not handled enumeration value 202 203 } 203 204 if(m->SlowDataClass->ErrorCode != 0) {205 m->PrintMessage("Error, could not write feedback slow data to file (%s), file closed.\n", strerror(m->SlowDataClass->ErrorCode));206 }207 204 ClearAverages(); 208 205 … … 215 212 void HVFeedback::ClearAverages() { 216 213 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 217 for (int j=0; j< kNumberOfChips; j++)218 for (int k=0; k< kNumberOfChannels; k++) {214 for (int j=0; j<fNumberOfChips; j++) 215 for (int k=0; k<fNumberOfChannels; k++) { 219 216 Average[i][j][k] = 0.0; 220 Sigma[i][j][k] = 0.0;217 Sigma[i][j][k] = 0.0; 221 218 } 222 219 Count = 0; 220 CountService->updateService(); 223 221 } 224 222 … … 254 252 // Set feedback mode and clear averages 255 253 // 256 void HVFeedback::SetFBMode(FBState Mode ) {257 if( Mode==FB_ResponseFirst || Mode==FB_ResponseFirst)254 void HVFeedback::SetFBMode(FBState Mode, bool Internal) { 255 if((Mode==FB_ResponseFirst || Mode==FB_ResponseFirst) && !Internal) 258 256 m->PrintMessage("Start reponse measurement by calling MeasureResponse().\n"); 259 257 else { 260 258 FBMode = Mode; 259 if (Mode != FB_ResponseFirst) State(INFO, "%s", FBState_Description[FBMode]); 260 else State(INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage); 261 261 ClearAverages(); 262 262 } … … 267 267 // 268 268 FBState HVFeedback::GetFBMode() { 269 switch (FBMode) { 270 case FB_Off: m->PrintMessage("Feedback off.\n"); break; 271 case FB_Active: m->PrintMessage("Feedback active.\n"); break; 272 case FB_Targets: m->PrintMessage("Feedback acquiring new targets.\n"); break; 273 case FB_ResponseFirst: m->PrintMessage("Feedback measuring response with first voltage.\n"); break; 274 case FB_ResponseSecond: m->PrintMessage("Feedback measuring response with second voltage.\n"); break; 275 } 276 return FBMode; 269 270 m->PrintMessage("%s.\n", FBState_Description[FBMode]); 271 return FBMode; 277 272 } 278 273 … … 288 283 // 289 284 void HVFeedback::SetTarget(int Board, int Chip, int Channel, float TargetVal) { 290 if(Board<m->NumBoards && Chip< kNumberOfChips && Channel<kNumberOfChannels)285 if(Board<m->NumBoards && Chip<fNumberOfChips && Channel<fNumberOfChannels) { 291 286 Target[Board][Chip][Channel] = TargetVal; 287 FeedbackTarget->updateService(); 288 } 292 289 else printf("Invalid board, chip or channel number.\n"); 293 290 } … … 298 295 void HVFeedback::GetTargets() { 299 296 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 300 for (int j=0; j< kNumberOfChips; j++) {297 for (int j=0; j<fNumberOfChips; j++) { 301 298 m->PrintMessage("Board %d, chip %d:",i,j); 302 for (int k=0; k< kNumberOfChannels; k++) m->PrintMessage(" %.2f",Target[i][j][k]);299 for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.2f",Target[i][j][k]); 303 300 m->PrintMessage("\n\r"); 304 301 } … … 316 313 317 314 for (int i=m->FirstBoard; i<=m->LastBoard; i++) 318 for (int j=0; j< kNumberOfChips; j++)319 for (int k=0; k< kNumberOfChannels; k++) {320 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {321 WriteHVCommand("hv diff %s %f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);315 for (int j=0; j<fNumberOfChips; j++) 316 for (int k=0; k<fNumberOfChannels; k++) { 317 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) { 318 WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2); 322 319 } 323 320 } 324 321 DiffVoltage = U; 325 FBMode = FB_ResponseFirst; 326 ClearAverages(); 322 SetFBMode(FB_ResponseFirst, true); 327 323 m->PrintMessage("HV Feedback: Decreasing voltages by %f for response measurement, acquiring data.\n",DiffVoltage/2); 328 324 } … … 333 329 void HVFeedback::GetResponse() { 334 330 for (int i=m->FirstBoard; i<=m->LastBoard; i++) { 335 for (int j=0; j< kNumberOfChips; j++) {331 for (int j=0; j<fNumberOfChips; j++) { 336 332 m->PrintMessage("Board %d, chip %d:",i,j); 337 for (int k=0; k< kNumberOfChannels; k++) m->PrintMessage(" %.3f",Response[i][j][k]);333 for (int k=0; k<fNumberOfChannels; k++) m->PrintMessage(" %.3f",Response[i][j][k]); 338 334 m->PrintMessage("\n\r"); 339 335 } … … 342 338 343 339 // 344 // Write commmand to socket340 // Write bias voltage commmand 345 341 // 346 342 bool HVFeedback::WriteHVCommand(const char *Format, ...) { 343 347 344 char Textbuffer[MAX_COM_SIZE]; 348 fd_set SelectDescriptor;349 345 350 346 va_list ArgumentPointer; va_start(ArgumentPointer, Format); 351 347 vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer); 352 348 353 // Write command to socket 354 if(write(SocketDescriptor, Textbuffer, strlen(Textbuffer)+1)!=(int) strlen(Textbuffer)+1) { 355 m->PrintMessage("Error: Could not write (entire) command to HV socket (%s)\n", strerror(errno)); 356 return false; 357 } 358 359 // Wait for command acknowledge from hvcontrol program 360 FD_ZERO(&SelectDescriptor); FD_SET(SocketDescriptor, &SelectDescriptor); 361 struct timeval WaitTime = {fMaxCmdAckDelay, 0}; 362 if (select(((int) SocketDescriptor)+1, &SelectDescriptor, NULL, NULL, &WaitTime)==-1) { 363 m->PrintMessage("Error with select() in command acknowledge (%s)\n", strerror(errno)); 364 return false; 365 } 366 367 // Evaluate response 368 if (!FD_ISSET(SocketDescriptor, &SelectDescriptor)) { // Time-out 369 m->PrintMessage("Time-out of %d seconds expired before receiving acknowledge from HV socket.\n", fMaxCmdAckDelay); 370 return false; 371 } 372 if (read(SocketDescriptor, Textbuffer, MAX_COM_SIZE) == -1) { // Could not read 373 m->PrintMessage("Error reading acknowledge from HV socket (%s)\n", strerror(errno)); 374 return false; 375 } 376 if (strncmp(Textbuffer, "OK", 2) != 0) { // ERROR response 377 m->PrintMessage("Did not received OK from hvcontrol.\n"); 378 return false; 379 } 349 DimClient::sendCommand("Bias/Command", Textbuffer); 350 380 351 return true; 381 352 } … … 385 356 // 386 357 void HVFeedback::PrintConfig(int Target) { 358 387 359 m->PrintMessage(Target, "LedTrigBoard: %d\t\tLedTrigChip: %d\t\tLedTrigChannel: %d\n" 388 360 "LedTrigSample: %d\tLedTrigThreshold: %.2f\n" 389 361 "LedSignalSample: %d\tLedBaselineSample: %d\tDefaultNumAverage: %d\n" 390 "IntHalfWidth:%u\tHVControlServer: %s\tHVControlPort: %d\n" 391 "MaxCmdAckDelay: %d\n", 362 "IntHalfWidth:%u\n", 392 363 fLedTrigBoard, fLedTrigChip, fLedTrigChannel, fLedTrigSample, 393 364 fLedTrigThreshold, fLedSignalSample, fLedBaselineSample, 394 fDefaultNumAverage, fIntHalfWidth , fHVControlServer, fHVControlPort, fMaxCmdAckDelay);395 } 365 fDefaultNumAverage, fIntHalfWidth); 366 }
Note:
See TracChangeset
for help on using the changeset viewer.