UltraScan III
us_experiment_ra.cpp
Go to the documentation of this file.
1 
3 #include <QtCore>
4 
5 #include "us_settings.h"
6 #include "us_db2.h"
7 #include "us_passwd.h"
8 #include "us_investigator.h"
9 #include "us_util.h"
10 #include "us_experiment_ra.h"
11 
13 {
14  // Experiment types
15  experimentTypes.clear();
16  experimentTypes << "Velocity"
17  << "Equilibrium"
18  << "Diffusion"
19  << "Buoyancy"
20  << "Calibration"
21  << "other";
22 }
23 
24 // Function to see if the current runID already exists in the database
26 {
27  // Let's see if we can find the run ID
28  expID = 0;
29  QStringList q( "get_experiment_info_by_runID" );
30  q << runID
31  << QString::number( US_Settings::us_inv_ID() );
32  db->query( q );
33  if ( db->lastErrno() == US_DB2::NOROWS )
34  return US_DB2::NOROWS;
35 
36  // Ok, let's update the experiment ID
37  db->next();
38  expID = db->value( 1 ).toString().toInt();
39  return US_DB2::OK;
40 }
41 
42 int US_ExperimentRa::saveToDB( bool update, US_DB2* db )
43 {
44  // Let's see if the project is in the db already
45  int status = project.saveToDB( db );
46  if ( status == US_DB2::NO_PROJECT )
47  return status;
48 
49  else if ( status != US_DB2::OK )
50  return status;
51 
52 
53  // Check for experiment runID in database
54  int saveStatus = 0;
55  QStringList q;
56  status = checkRunID( db );
57  if ( status == US_DB2::OK && ! update )
58  {
59  // Then the runID exists already, and we're not updating
60  return US_DB2::DUPFIELD;
61  }
62 
63  if ( status == US_DB2::OK )
64  {
65  // It's ok to update the existing experiment entry
66  q.clear();
67  q << "update_experiment"
68  << QString::number( expID )
69  << QString( expGUID )
70  << QString::number( project.projectID )
71  << runID
72  << QString::number( labID )
73  << QString::number( instrumentID )
74  << QString::number( operatorID )
75  << QString::number( rotorID )
76  << QString::number( calibrationID )
77  << expType
78  << opticalSystem
79  << runTemp
80  << label
81  << comments
83 
84  saveStatus = db->statusQuery( q );
85  }
86 
87  else if ( status == US_DB2::NOROWS )
88  {
89  // Create new experiment entry
90  q.clear();
91  q << "new_experiment"
92  << expGUID
93  << QString::number( project.projectID )
94  << runID
95  << QString::number( labID )
96  << QString::number( instrumentID )
97  << QString::number( operatorID )
98  << QString::number( rotorID )
99  << QString::number( calibrationID )
100  << expType
101  << opticalSystem
102  << runTemp
103  << label
104  << comments
106  << QString::number( US_Settings::us_inv_ID() );
107 
108  saveStatus = db->statusQuery( q );
109  expID = db->lastInsertID();
110  }
111 
112  if ( expID == 0 ) // double check
113  {
114  qDebug() << "Error saving experiment: " << saveStatus
115  << " " << db->lastError();
116  return saveStatus;
117  }
118 
119  // Let's get some info after db update
120  q.clear();
121  q << "get_experiment_info"
122  << QString::number( expID );
123  db->query( q );
124  db->next();
125 
126  date = db->value( 12 ).toString();
127 
128  return US_DB2::OK;
129 }
130 
131 // Function to read an experiment from DB
132 int US_ExperimentRa::readFromDB( QString runID,
133  US_DB2* db )
134 {
135  QStringList q( "get_experiment_info_by_runID" );
136  q << runID
137  << QString::number( US_Settings::us_inv_ID() );
138  db->query( q );
139 
140  QByteArray xmlFile;
141 
142  if ( db->next() )
143  {
144  this->runID = runID;
145  project.projectID = db->value( 0 ).toInt();
146  expID = db->value( 1 ).toInt();
147  expGUID = db->value( 2 ).toString();
148  labID = db->value( 3 ).toInt();
149  instrumentID = db->value( 4 ).toInt();
150  operatorID = db->value( 5 ).toInt();
151  rotorID = db->value( 6 ).toInt();
152  calibrationID = db->value( 7 ).toInt();
153  expType = db->value( 8 ).toString();
154  runTemp = db->value( 9 ).toString();
155  label = db->value( 10 ).toString();
156  comments = db->value( 11 ).toString();
157  centrifugeProtocol = db->value( 12 ).toString();
158  date = db->value( 13 ).toString();
159  invID = db->value( 14 ).toInt();
160  opticalSystem = db->value( 15 ).toString().toAscii();
161  xmlFile = db->value( 16 ).toString().toAscii();
162  }
163 
164  else if ( db->lastErrno() == US_DB2::NOROWS )
165  return US_DB2::NO_EXPERIMENT;
166 
167  else
168  return( db->lastErrno() );
169 
170  // Get the rest of the info we need
171  q.clear();
172  q << QString( "get_person_info" )
173  << QString::number( invID );
174  db->query( q );
175  if ( db->next() )
176  invGUID = db->value( 9 ).toString();
177 
179 
180  // Hardware info
181  operatorGUID = QString( "" );
182  q.clear();
183  q << QString( "get_person_info" )
184  << QString::number( operatorID );
185  db->query( q );
186  if ( db->next() )
187  operatorGUID = db->value( 9 ).toString();
188 
189  instrumentSerial = QString( "" );
190  q.clear();
191  q << QString( "get_instrument_info" )
192  << QString::number( instrumentID );
193  db->query( q );
194  if ( db->next() )
195  instrumentSerial = db->value( 1 ).toString();
196 
197  rotorGUID = QString( "" );
198  q.clear();
199  q << QString( "get_rotor_info" )
200  << QString::number( rotorID );
201  db->query( q );
202  if ( db->next() )
203  {
204  rotorGUID = db->value( 0 ).toString();
205  rotorName = db->value( 1 ).toString();
206  rotorSerial = db->value( 2 ).toString();
207  }
208 
209  if ( calibrationID == 0 ) // In this case, get the first one
210  {
211  q.clear();
212  q << QString( "get_rotor_calibration_profiles" )
213  << QString::number( rotorID );
214  db->query( q );
215  if ( db->next() )
216  calibrationID = db->value( 0 ).toInt();
217  }
218 
219  // Now get more calibration info
220  q.clear();
221  q << QString( "get_rotor_calibration_info" )
222  << QString::number( calibrationID );
223  db->query( q );
224  if ( db->next() )
225  {
226  rotorCoeff1 = db->value( 4 ).toString().toFloat();
227  rotorCoeff2 = db->value( 5 ).toString().toFloat();
228  QStringList dateParts = db->value( 7 ).toString().split( " " );
229  rotorUpdated = QDate::fromString( dateParts[ 0 ], "yyyy-MM-dd" );
230  }
231 
232 
233  return US_DB2::OK;
234 }
235 
237  QVector< US_mwlRamp::RampRawData* >& data,
238  QList< US_Ramp::TripleInfo >& triples,
239  QString runType,
240  QString runID,
241  QString dirname )
242 {
243  QRegExp rx( "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$" );
244 
245 
246  if ( this->expGUID.isEmpty() || ! rx.exactMatch( this->expGUID ) )
247  this->expGUID = US_Util::new_guid();
248 
249  if ( dirname.right( 1 ) != "/" ) dirname += "/"; // Ensure trailing /
250  QString writeFile = runID + "." + "xml";
251  QFile file( dirname + writeFile );
252  if ( !file.open( QIODevice::WriteOnly | QIODevice::Text) )
253  return( US_Ramp::CANTOPEN );
254 
255 qDebug() << " EsTD: writeFile" << writeFile;
256  QXmlStreamWriter xml;
257  xml.setDevice( &file );
258  xml.setAutoFormatting( true );
259 
260  xml.writeStartDocument();
261  xml.writeDTD("<!DOCTYPE US_Rampdata>");
262  xml.writeStartElement("US_Rampdata");
263  xml.writeAttribute("version", "1.0");
264 
265  // elements
266  xml.writeStartElement( "experiment" );
267  xml.writeAttribute ( "id", QString::number( this->expID ) );
268  xml.writeAttribute ( "guid", this->expGUID );
269 // xml.writeAttribute ( "type", this->expType );
270  xml.writeAttribute ( "runID", this->runID );
271 
272  xml.writeStartElement( "investigator" );
273  xml.writeAttribute ( "id", QString::number( this->invID ) );
274  xml.writeAttribute ( "guid", this->invGUID );
275  xml.writeEndElement ();
276 
277  xml.writeStartElement( "name" );
278  xml.writeAttribute ( "value", this->name );
279  xml.writeEndElement ();
280 
281  xml.writeStartElement( "project" );
282  xml.writeAttribute ( "id", QString::number( this->project.projectID ) );
283  xml.writeAttribute ( "guid", this->project.projectGUID );
284  xml.writeAttribute ( "desc", this->project.projectDesc );
285  xml.writeEndElement ();
286 
287  xml.writeStartElement( "lab" );
288  xml.writeAttribute ( "id", QString::number( this->labID ) );
289  xml.writeEndElement ();
290 
291  xml.writeStartElement( "instrument" );
292  xml.writeAttribute ( "id", QString::number( this->instrumentID ) );
293  xml.writeAttribute ( "serial", this->instrumentSerial );
294  xml.writeEndElement ();
295 
296  xml.writeStartElement( "operator" );
297  xml.writeAttribute ( "id", QString::number( this->operatorID ) );
298  xml.writeAttribute ( "guid", this->operatorGUID );
299  xml.writeEndElement ();
300 
301  xml.writeStartElement( "rotor" );
302  xml.writeAttribute ( "id", QString::number( this->rotorID ) );
303  xml.writeAttribute ( "guid", this->rotorGUID );
304  xml.writeAttribute ( "serial", this->rotorSerial );
305  xml.writeAttribute ( "name", this->rotorName );
306  xml.writeEndElement ();
307 
308  xml.writeStartElement( "calibration" );
309  xml.writeAttribute ( "id", QString::number( this->calibrationID ) );
310  xml.writeAttribute ( "coeff1", QString::number( this->rotorCoeff1 ) );
311  xml.writeAttribute ( "coeff2", QString::number( this->rotorCoeff2 ) );
312  xml.writeAttribute( "date", this->rotorUpdated.toString( "yyyy-MM-dd" ) );
313  xml.writeEndElement ();
314  int psolID = -1;
315  QString psolGUID = "";
316  QString psolDesc = "";
317 qDebug() << " EsTD: triples loop" << triples.size();
318 
319  // loop through the following for c/c/w combinations
320  for ( int trx = 0; trx < triples.size(); trx++ )
321  {
322  US_Ramp::TripleInfo* trp = &triples[ trx ];
323  if ( trp->excluded ) continue;
324 
325 // QString triple = trp->tripleDesc;
326 // QStringList parts = triple.split(" / ");
327 //
328 // QString cell = parts[ 0 ];
329 // QString channel = parts[ 1 ];
330 // QString wl = parts[ 2 ];
331 
332  QString uuidc = US_Util::uuid_unparse( (unsigned char*)trp->tripleGUID );
333 
334  xml.writeStartElement( "dataset" );
335  xml.writeAttribute ( "id", QString::number( trp->tripleID ) );
336  xml.writeAttribute ( "cell", data[trx]->cell );
337  xml.writeAttribute ( "channel", data[trx]->chan );
338  xml.writeStartElement( "centerpiece" );
339  xml.writeAttribute ( "id", QString::number( trp->centerpiece ) );
340  xml.writeEndElement ();
341 
342  int csolID = trp->solution.solutionID;
343  QString csolGUID = trp->solution.solutionGUID;
344  QString csolDesc = trp->solution.solutionDesc;
345 
346  if ( csolID == psolID || ( csolID < 0 && csolGUID == psolGUID ) )
347  {
348  csolID = psolID;
349  csolGUID = psolGUID;
350  csolDesc = psolDesc;
351  }
352 
353  psolID = csolID;
354  psolGUID = csolGUID;
355  psolDesc = csolDesc;
356  xml.writeStartElement( "solution" );
357  xml.writeAttribute ( "id", QString::number( csolID ) );
358  xml.writeAttribute ( "guid", csolGUID );
359  xml.writeAttribute ( "desc", csolDesc );
360  xml.writeEndElement ();
361 
362 
363 
364 
365  for (int lambda = 0; lambda < data[trx]->wl_array.size(); lambda++)
366  {
367  xml.writeStartElement( "subset" );
368  QString wl = QString::number(data[trx]->wl_array.at(lambda));
369  xml.writeAttribute( "wavelength", wl );
370  xml.writeAttribute( "guid", uuidc );
371  xml.writeEndElement ();
372  }
373  xml.writeEndElement ();
374  }
375 
376 // xml.writeStartElement( "opticalSystem" );
377 // xml.writeAttribute ( "value", this->opticalSystem );
378 // xml.writeEndElement ();
379 
380  xml.writeStartElement( "date" );
381  xml.writeAttribute ( "value", this->date );
382  xml.writeEndElement ();
383 
384  xml.writeStartElement( "runTemp" );
385  xml.writeAttribute ( "value", this->runTemp );
386  xml.writeEndElement ();
387 
388  xml.writeTextElement ( "label", this->label );
389  xml.writeTextElement ( "comments", this->comments );
390  xml.writeTextElement ( "centrifugeProtocol", this->centrifugeProtocol );
391 
392  xml.writeEndElement(); // US_Scandata
393  xml.writeEndDocument();
394 
395  // Make sure the project is saved to disk too
396 qDebug() << " EsTD: call proj saveToDisk";
397  this->project.saveToDisk();
398 
399  return( US_Ramp::OK );
400 }
401 
403  QList< US_Ramp::TripleInfo >& triples,
404  QString runType,
405  QString runID,
406  QString dirname )
407 {
408  // First figure out the xml file name, and try to open it
409  QString filename = runID + "." + "xml";
410 
411  QFile f( dirname + filename );
412  if ( ! f.open( QIODevice::ReadOnly ) ) return US_Ramp::CANTOPEN;
413  QTextStream ds( &f );
414 
415  QXmlStreamReader xml( &f );
416 
417  while ( ! xml.atEnd() )
418  {
419  xml.readNext();
420 
421  if ( xml.isStartElement() )
422  {
423  if ( xml.name() == "experiment" )
424  {
425  QXmlStreamAttributes a = xml.attributes();
426  this->expID = a.value("id").toString().toInt();
427  this->expGUID = a.value( "guid" ).toString();
428  this->expType = a.value( "type" ).toString();
429  this->runID = a.value( "runID" ).toString();
430  readExperiment ( xml, triples, runType, runID );
431 // qDebug()<< "expID expGUID expType runID" <<expID <<expGUID<< expType<<runID;
432  }
433  }
434  }
435 
436  bool error = xml.hasError();
437 qDebug() << "readFromDisk() error" << error;
438  f.close();
439 
440 // if ( error ) return US_Ramp::BADXML;
441 
442  return US_Ramp::OK;
443 }
444 
446  QXmlStreamReader& xml,
447  QList< US_Ramp::TripleInfo >& triples,
448  QString runType,
449  QString runID )
450 {
451  while ( ! xml.atEnd() )
452  {
453  xml.readNext();
454 
455  if ( xml.isEndElement() && xml.name() == "experiment" ) return;
456 
457  if ( xml.isStartElement() )
458  {
459  if ( xml.name() == "investigator" )
460  {
461  QXmlStreamAttributes a = xml.attributes();
462  this->invID = a.value( "id" ).toString().toInt();
463  this->invGUID = a.value( "guid" ).toString();
464  }
465 
466  else if ( xml.name() == "name" )
467  {
468  QXmlStreamAttributes a = xml.attributes();
469  this->name = a.value( "value" ).toString();
470  }
471 
472  else if ( xml.name() == "project" )
473  {
474  QXmlStreamAttributes a = xml.attributes();
475  this->project.projectID = a.value( "id" ).toString().toInt();
476  this->project.projectGUID = a.value( "guid" ).toString();
477  this->project.projectDesc = a.value( "desc" ).toString();
478  }
479 
480  else if ( xml.name() == "lab" )
481  {
482  QXmlStreamAttributes a = xml.attributes();
483  this->labID = a.value( "id" ) .toString().toInt();
484  }
485 
486  else if ( xml.name() == "instrument" )
487  {
488  QXmlStreamAttributes a = xml.attributes();
489  this->instrumentID = a.value( "id" ) .toString().toInt();
490  this->instrumentSerial = a.value( "serial" ).toString();
491  }
492 
493  else if ( xml.name() == "operator" )
494  {
495  QXmlStreamAttributes a = xml.attributes();
496  this->operatorID = a.value( "id" ).toString().toInt();
497  this->operatorGUID = a.value( "guid" ).toString();
498  }
499 
500  else if ( xml.name() == "rotor" )
501  {
502  QXmlStreamAttributes a = xml.attributes();
503  this->rotorID = a.value( "id" ).toString().toInt();
504  this->rotorGUID = a.value( "guid" ).toString();
505  this->rotorSerial = a.value( "serial" ).toString();
506  this->rotorName = a.value( "name" ).toString();
507  this->calibrationID = a.value( "calibrationID" ).toString().toInt();
508  }
509 
510  else if ( xml.name() == "calibration" )
511  {
512  QXmlStreamAttributes a = xml.attributes();
513  this->calibrationID = a.value( "id" ).toString().toInt();
514  this->rotorCoeff1 = a.value( "coeff1" ).toString().toFloat();
515  this->rotorCoeff2 = a.value( "coeff2" ).toString().toFloat();
516  this->rotorUpdated =
517  QDate::fromString( a.value( "date" ).toString(), "yyyy-MM-dd" );
518  qDebug()<<"_____calib_________calib"<<calibrationID;
519  }
520 
521  else if ( xml.name() == "dataset" )
522  {
523  QXmlStreamAttributes a = xml.attributes();
524  QString qid = a.value( "id" ).toString();
525  QString cell = a.value( "cell" ).toString();
526  QString channel = a.value( "channel" ).toString();
527 
528 // QString wl;
529 // if ( runType == "WA" )
530 // wl = a.value( "radius" ).toString();
531 //
532 // else
533 // wl = a.value( "wavelength" ).toString();
534 
535  // Find the index of this triple
536  QString triple = cell + " / " + channel;
537  bool found = false;
538  int ndx = 0;
539  for ( int i = 0; i < triples.size(); i++ )
540  {
541  if ( triples[ i ].excluded ) continue;
542 
543  if ( triple == triples[ i ].tripleDesc )
544  {
545  found = true;
546  ndx = i;
547  break;
548  }
549  }
550 
551  if ( found )
552  {
553  triples[ ndx ].tripleID = a.value( "id" ).toString().toInt();
554  QString uuidc = a.value( "guid" ).toString();
555  US_Util::uuid_parse( uuidc,
556  (unsigned char*) triples[ ndx ].tripleGUID );
557  triples[ ndx ].tripleFilename = runID + "."
558  + cell + "."
559  + channel + ".auc";
560 
561  triples[ ndx ].excluded = false;
562 
563  readDataset( xml, triples[ ndx ] );
564  }
565 
566  }
567 
568 // else if ( xml.name() == "opticalSystem" )
569 // {
570 // QXmlStreamAttributes a = xml.attributes();
571 // this->opticalSystem = a.value( "value" ).toString().toAscii();
572 // }
573 
574  else if ( xml.name() == "date" )
575  {
576  QXmlStreamAttributes a = xml.attributes();
577  this->date = a.value( "value" ).toString();
578  }
579 
580  else if ( xml.name() == "runTemp" )
581  {
582  QXmlStreamAttributes a = xml.attributes();
583  this->runTemp = a.value( "value" ).toString();
584  }
585 
586  else if ( xml.name() == "label" )
587  {
588  xml.readNext();
589  this->label = xml.text().toString();
590  }
591 
592  else if ( xml.name() == "comments" )
593  {
594  xml.readNext();
595  this->comments = xml.text().toString();
596  }
597 
598  else if ( xml.name() == "centrifugeProtocol" )
599  {
600  xml.readNext();
601  this->centrifugeProtocol = xml.text().toString();
602  }
603  }
604  }
605  show();
606 }
607 
608 void US_ExperimentRa::readDataset( QXmlStreamReader& xml,
609  US_Ramp::TripleInfo& triple )
610 {
611  while ( ! xml.atEnd() )
612  {
613  xml.readNext();
614 
615  if ( xml.isEndElement() && xml.name() == "dataset" ) return;
616 
617  if ( xml.isStartElement() )
618  {
619  if ( xml.name() == "centerpiece" )
620  {
621  QXmlStreamAttributes a = xml.attributes();
622  triple.centerpiece = a.value( "id" ).toString().toInt();
623  qDebug()<<"_______________cp"<<triple.centerpiece;
624  }
625 
626  else if ( xml.name() == "solution" )
627  {
628  QXmlStreamAttributes a = xml.attributes();
629  triple.solution.solutionID = a.value( "id" ).toString().toInt();
630  triple.solution.solutionGUID = a.value( "guid" ).toString();
631  triple.solution.solutionDesc = a.value( "desc" ).toString();
632  }
633 
634  else if ( xml.name() == "subset" )
635  {
636  QXmlStreamAttributes a = xml.attributes();
637  int tempwl = a.value( "wavelength" ).toString().toInt();
638  QString tripleGUID = a.value( "guid" ).toString();
639  }
640 
641  }
642  }
643 }
644 
645 
646 
647 // Zero out all data structures
649 {
651  invGUID = QString( "" );
653  expID = 0;
654  expGUID = QString( "" );
655  project.clear();
656  runID = QString( "" );
657  labID = 0;
658  instrumentID = 0;
659  instrumentSerial = QString( "" );
660  operatorID = 0;
661  operatorGUID = QString( "" );
662  rotorID = 0;
663  calibrationID = 0;
664  rotorCoeff1 = 0.0;
665  rotorCoeff2 = 0.0;
666  rotorGUID = QString( "" );
667  rotorSerial = QString( "" );
668  rotorName = QString( "" );
669  expType = QString( "" );
670  opticalSystem = QByteArray( " " );
671  runTemp = QString( "" );
672  label = QString( "" );
673  comments = QString( "" );
674  centrifugeProtocol = QString( "" );
675  date = QString( "" );
676  syncOK = false;
677 
678 }
679 
681 {
682  QString syncOK_text = ( syncOK ) ? "true" : "false";
683 
684  qDebug() << "invID = " << invID << '\n'
685  << "invGUID = " << invGUID << '\n'
686  << "name = " << name << '\n'
687  << "expID = " << expID << '\n'
688  << "expGUID = " << expGUID << '\n'
689  << "projectID = " << project.projectID << '\n'
690  << "projectGUID = " << project.projectGUID << '\n'
691  << "projectDesc = " << project.projectDesc << '\n'
692  << "runID = " << runID << '\n'
693  << "labID = " << labID << '\n'
694  << "instrumentID = " << instrumentID << '\n'
695  << "instrumentSerial = " << instrumentSerial << '\n'
696  << "operatorID = " << operatorID << '\n'
697  << "operatorGUID = " << operatorGUID << '\n'
698  << "rotorID = " << rotorID << '\n'
699  << "rotorGUID = " << rotorGUID << '\n'
700  << "rotorSerial = " << rotorSerial << '\n'
701  << "rotorName = " << rotorName << '\n'
702  << "calibrationID = " << calibrationID << '\n'
703  << "rotorCoeff1 = " << rotorCoeff1 << '\n'
704  << "rotorCoeff2 = " << rotorCoeff2 << '\n'
705  << "rotorUpdated = " << rotorUpdated.toString( "yyyy-MM-dd" ) << '\n'
706  << "opticalSystem = " << opticalSystem << '\n'
707  << "runTemp = " << runTemp << '\n'
708  << "label = " << label << '\n'
709  << "comments = " << comments << '\n'
710  << "centrifugeProtocol = " << centrifugeProtocol << '\n'
711  << "date = " << date << '\n'
712  << "syncOK = " << syncOK_text << '\n';
713 
714 }
715