Пример #1
0
const Char_t *KVINDRAIDTelescope::GetArrayName()
{
   // Name of telescope given in the form Det1_Det2_Ring-numberTelescope-number
   //where ring and telescope numbers are those of the smallest (in angular terms)
   //detector of the telescope (if both are the same size, either one will do).
   // The detectors are signified by their TYPE names i.e. KVDetector::GetType

   //in order to access angular dimensions of detectors, we need their KVTelescopes
   KVINDRATelescope *de_det = dynamic_cast<KVINDRADetector*>(GetDetector(1))->GetTelescope();
   KVINDRATelescope *e_det = 0;
   if (GetSize() > 1)
      e_det = dynamic_cast<KVINDRADetector*>(GetDetector(2))->GetTelescope();
   UInt_t ring, mod;
   if (!e_det || de_det->IsSmallerThan(e_det)) {
      ring = de_det->GetRingNumber();
      mod = de_det->GetNumber();
   } else {
      ring = e_det->GetRingNumber();
      mod = e_det->GetNumber();
   }
   SetName(GetDetector(1)->GetType());
   if (e_det) {
      fName.Append("_");
      fName.Append(GetDetector(2)->GetType());
   }
   SetType(fName.Data());
   fName.Append("_");
   TString num;
   num.Form("%02d%02d", ring, mod);
   fName += num;

   return fName.Data();
}
Пример #2
0
//___________________________________________________________________________
Double_t KVChannelVolt::Invert(Double_t volts)
{
   //Given the calibrated (or simulated) signal amplitude in volts,
   //calculate the corresponding channel number according to the
   //calibration parameters (useful for filtering simulations).

   Double_t gain = 1.;
   KVDetector* det = GetDetector();
   if (det)
      gain = det->GetGain();
   Int_t channel = 0;

   if (fReady) {
      if (fPar[2]) {
         // quadratic transfer function
         Double_t c;
         c = fPar[1] * fPar[1] - 4. * fPar[2] * (fPar[0] - gain / gain_ref * volts);
         if (c < 0.0)
            return -1;
         c = (-fPar[1] + TMath::Sqrt(c)) / (2.0 * fPar[2]);
         if (c < 0.0
               && ((-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2])) > 0.0) {
            c = (-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2]);
         }
         channel = (Int_t)(c + 0.5);
      } else {
         // linear transfer function
         channel = (Int_t)(0.5 + (gain / gain_ref * volts - fPar[0]) / fPar[1]);
      }
   } else {
      Warning("Compute", "Parameters not correctly initialized");
   }
   return (Double_t) channel;
}
Пример #3
0
//___________________________________________________________________________
Double_t KVChannelVolt::InvertDouble(Double_t volts)
{
   Double_t gain = 1.;
   KVDetector* det = GetDetector();
   if (det)
      gain = det->GetGain();
   Double_t channel = 0;

   if (fReady) {
      if (fPar[2]) {
         // quadratic transfer function
         Double_t c;
         c = fPar[1] * fPar[1] - 4. * fPar[2] * (fPar[0] - gain / gain_ref * volts);
         if (c < 0.0)
            return -1;
         c = (-fPar[1] + TMath::Sqrt(c)) / (2.0 * fPar[2]);
         if (c < 0.0
               && ((-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2])) > 0.0) {
            c = (-fPar[1] - TMath::Sqrt(c)) / (2.0 * fPar[2]);
         }
         channel = c;
      }
      else {
         // linear transfer function
         channel = (gain / gain_ref * volts - fPar[0]) / fPar[1];
      }
   }
   else {
      Warning("Compute", "Parameters not correctly initialized");
   }
   return (Double_t) channel;
}
Пример #4
0
const Char_t *KVIDCsI::GetArrayName()
{
   // Name of telescope given in the form CSI_R_L_Ring-numberTelescope-number
   //where ring and telescope numbers are those of the smallest (in angular terms)
   //detector of the telescope (if both are the same size, either one will do).
   // The detectors are signified by their TYPE names i.e. KVDetector::GetType

   //in order to access angular dimensions of detectors, we need their KVTelescopes
   KVINDRATelescope *de_det = dynamic_cast<KVINDRADetector*>(GetDetector(1))->GetTelescope();
   UInt_t ring, mod;
   ring = de_det->GetRingNumber();
   mod = de_det->GetNumber();
   TString dummy;
   dummy.Form("%s_R_L", GetDetector(1)->GetType());
   SetType(dummy.Data());
   dummy.Form("%s_%02d%02d", GetType(), ring, mod);
   SetName(dummy.Data());

   return fName.Data();
}
Пример #5
0
TF1* KVRecombination::GetParlogPHDFunction(Int_t Z, Int_t A){
    // Create TF1* fParlog if not already done

    if(!fParlog) {
        fParlog = new TF1(Form("ParlogPHD:%s", GetDetector()->GetName()),
            	this, &KVRecombination::PHDParlog, 0., 1.e+04, 1, "KVRecombination", "PHDParlog");
        fParlog->SetNpx(500);
    }
    fParlog->SetParameter(0,Z);
    fParlog->SetParameter(1,A);
    return fParlog;
}
Пример #6
0
 TF1* KVPulseHeightDefect::GetMoultonPHDFunction(Int_t Z)
 {
    // Create TF1* fMoulton if not already done
 
    if(!fMoulton) {
       fMoulton = new TF1(Form("MoultonPHD:%s", GetDetector()->GetName()),
          this, &KVPulseHeightDefect::PHDMoulton, 0., 1.e+04, 1, "KVPulseHeightDefect", "PHDMoulton");
       fMoulton->SetNpx(500);
    }
    fMoulton->SetParameter(0,Z);
    return fMoulton;
 }
Пример #7
0
void KVIDChIoCorrCsI::Initialize()
{
    // Initialize telescope for current run.

	fChIo = 0;
    fChIo = (KVChIo *) GetDetector(1);

	fCsI = 0;
    fCsI = (KVCsI *) GetDetector(2);

    fGrid = 0;
    fGrid = (KVIDZAGrid*) GetIDGrid();

    if (fChIo && fCsI && fGrid) {
        fGrid->Initialize();
        fGrid->SetOnlyZId(kTRUE);
        SetBit(kReadyForID);
    }
	else ResetBit(kReadyForID);

}
Пример #8
0
void KVFAZIA::Build(Int_t)
{
   // Build the combined INDRA & FAZIA arrays
   GetGeometryParameters();
   GenerateCorrespondanceFile();

   if (!gGeoManager) {
      new TGeoManager("FAZIA", Form("FAZIA geometry for dataset %s", gDataSet->GetName()));

      TGeoMaterial* matVacuum = gGeoManager->GetMaterial("Vacuum");
      if (!matVacuum) {
         matVacuum = new TGeoMaterial("Vacuum", 0, 0, 0);
         matVacuum->SetTitle("Vacuum");
      }
      TGeoMedium* Vacuum = gGeoManager->GetMedium("Vacuum");
      if (!Vacuum) Vacuum = new TGeoMedium("Vacuum", 1, matVacuum);
      TGeoVolume* top = gGeoManager->MakeBox("WORLD", Vacuum,  500, 500, 500);
      gGeoManager->SetTopVolume(top);
   }

   BuildFAZIA();
   if (fBuildTarget)
      BuildTarget();

   KVGeoImport imp(gGeoManager, KVMaterial::GetRangeTable(), this, kTRUE);
   imp.SetDetectorPlugin(ClassName());
   imp.SetNameCorrespondanceList(fCorrespondanceFile.Data());
   // any additional structure name formatting definitions
   DefineStructureFormats(imp);

   // the following parameters are optimized for a 12-block compact
   // geometry placed at 80cm with rings 1-5 of INDRA removed.
   // make sure that the expected number of detectors get imported!
   imp.ImportGeometry(fImport_dTheta, fImport_dPhi, fImport_ThetaMin, fImport_PhiMin, fImport_ThetaMax, fImport_PhiMax);

   /*
   KVFAZIADetector* det=0;
   TIter next_d(GetDetectors());
   while ( det = (KVFAZIADetector* )next_d() ){
      printf("%s %s %d %d %d\n",det->GetName(),det->GetFAZIAType(),det->GetBlockNumber(),det->GetQuartetNumber(),det->GetTelescopeNumber());
   }
   */
   SetIdentifications();
   SortIDTelescopes();
   KVDetector* det = GetDetector("SI2-T1-Q1-B001");
   det->GetIDTelescopes()->ls();



   SetDetectorThicknesses();
   SetBit(kIsBuilt);
}
Пример #9
0
//___________________________________________________________________________
Double_t KVChannelVolt::Compute(Double_t chan) const
{
   Double_t gain = 1.;
   KVDetector* det = GetDetector();
   if (det)
      gain = det->GetGain();
   //Calculate the calibrated signal strength in volts for a given channel number.
   if (fReady) {
      return (fPar[0] + fPar[1] * chan + fPar[2] * chan * chan) * gain_ref / gain;
   } else {
      return 0.;
   }
}
Пример #10
0
void KVIDSiLiCsI_camp5::Initialize()
{
   // Initialize telescope for current run.
   // Pointers to grids for run are set, and if there is at least 1 (GG) grid,
   // we set IsReadyForID = kTRUE

   fSiLi = GetDetector(1);
   fCsI = GetDetector(2);
   fGGgrid = fPGgrid = 0;
   TIter next(fIDGrids);
   KVIDGrid* grid = 0;
   while ((grid = (KVIDGrid*)next())) {
      if (!strcmp(grid->GetVarY(), "SILI_GG")) fGGgrid = (KVIDZAGrid*)grid;
      else if (!strcmp(grid->GetVarY(), "SILI_PG")) fPGgrid = (KVIDZAGrid*)grid;
   }
   if (fGGgrid) {
      SetBit(kReadyForID);
      fGGgrid->Initialize();
      if (fPGgrid) fPGgrid->Initialize();
   } else
      ResetBit(kReadyForID);
}
Пример #11
0
TF1* KVRecombination::GetELossFunction(Int_t Z, Int_t A, Bool_t Wrong){
   	// Return pointer to TF1 giving energy loss in active layer of detector minus
   	// the pulse height defect for a given nucleus (Z,A).
    //
    // If Wrong=kTRUE (default:kFALSE) this will be calculated incorrectly
    // (if the particle does not stop in the detector) by using the Parlog formula
    // with the incident energy of the particle instead of the calculated energy
    // loss of the particle.

    wrong=Wrong;

   	if(!fDeltaEphd){
      	fDeltaEphd = new TF1(Form("KVRecombination:%s:ELossActive", GetDetector()->GetName()),
           		this, &KVRecombination::ELossActive, 0., 1.e+04, 2, "KVRecombination", "ELossActive");
      	fDeltaEphd->SetNpx( gEnv->GetValue("KVPulseHeightDefect.EnergyLoss.Npx", 20) );
   	}
   	fDeltaEphd->SetParameters((Double_t)Z, (Double_t)A);
   	fDeltaEphd->SetRange(0., GetDetector()->GetSmallestEmaxValid(Z,A));
   	fDeltaEphd->SetTitle(Form("PHD dependent energy loss [MeV] in detector %s for Z=%d A=%d", GetDetector()->GetName(), Z, A));
   	GetParlogPHDFunction(Z,A);
   	return fDeltaEphd;
}
Пример #12
0
Double_t KVRecombination::ELossActive(Double_t *x, Double_t *par){
   	// Calculate energy lost in active layer of detector minus the Parlog PHD
   	// x[0] = incident energy
   	// par[0] = Z
   	// par[1] = A

   	Double_t e = x[0];
   	TIter next(GetDetector()->GetListOfAbsorbers()); KVMaterial* mat;
   	while( (mat = (KVMaterial*)next()) != GetDetector()->GetActiveLayer() ){
      	// calculate energy losses in absorbers before active layer
        e = mat->GetERes(par[0], par[1], e);     //residual energy after layer
        if (e <= 0.)
            return 0.;          // return 0 if particle stops in layers before active layer
   	}
   	// calculate energy loss in active layer
   	Double_t dE = mat->GetDeltaE(par[0], par[1], e);
   	// calculate Parlog PHD corresponding to energy lost in active layer
   	Double_t phd;
   	if(wrong) phd = PHDParlog(&e, par);//incorrect calculation using incident energy
   	else phd = PHDParlog(&dE, par);

   	return dE - phd; 
}
Пример #13
0
float ThermometerFa::Read()
{
    float val = GetDetector()->Read();

    std::vector<float> &histData = GetHistData();

    if(histData.size() < 3)
        histData.push_back(val);
    histData[0] = histData[1];
    histData[1] = histData[2];
    histData[2] = val;

    return val;
}
Пример #14
0
void KVIDChIoCsI_camp5::Initialize()
{
   // Initialize telescope for current run.
   // If there is at least 1 grid, we set fCanIdentify = kTRUE
   // "Natural" line widths are calculated for KVIDZAGrids.

   fChIo = (KVChIo*) GetDetector(1);
   fCsI = (KVCsI*) GetDetector(2);
   fCsIRPedestal = fCsI->GetPedestal("R");
   fCsILPedestal = fCsI->GetPedestal("L");
   fGGgrid = fPGgrid = 0;
   TIter next(GetListOfIDGrids());
   KVIDGraph* grid;
   while ((grid = (KVIDGraph*)next())) {
      if (!strcmp(grid->GetVarY(), "CHIO-GG")) fGGgrid = (KVIDZAGrid*)grid;
      else if (!strcmp(grid->GetVarY(), "CHIO-PG")) fPGgrid = (KVIDZAGrid*)grid;
   }
   if (fGGgrid) {
      SetBit(kReadyForID);
      fGGgrid->Initialize();
      if (fPGgrid) fPGgrid->Initialize();
   } else ResetBit(kReadyForID);
}
Пример #15
0
void KVIDCsI::Initialize()
{
   // Override default initialization method
   // If telescope has 1 CsI detector and at least 1 grid
   // then it is ready to identify particles, after we initialise
   // the grid

   if (GetDetectors()->GetEntries() == 1 && GetDetector(1)->IsType("CsI") && GetIDGrid()) {
      GetIDGrid()->Initialize();
      SetBit(kReadyForID);
   }
   else
      ResetBit(kReadyForID);
}
Пример #16
0
void KVIDCsI::Initialize()
{
   // Initialisation of telescope before identification.
   // This method MUST be called once before any identification is attempted.
   // Initialisation of grid is performed here.
   // IsReadyForID() will return kTRUE if a grid is associated to this telescope for the current run.

   CsIGrid = (KVIDGCsI *) GetIDGrid();
	fCsI = GetDetector(1);
   if( CsIGrid ) {
      CsIGrid->Initialize();
      SetBit(kReadyForID);
   }
   else
      ResetBit(kReadyForID);
}
Пример #17
0
int main(int argc, char *argv[])
{
  int minX=0, minY=0, binX=1, binY=1, sizeX, sizeY;
  char model[256];
  float temperature;
  int status;

  checkStatus(Initialize("/usr/local/etc/andor"));
  printf("Intialize(/usr/local/etc/andor) OK\n");
  checkStatus(GetDetector(&sizeX, &sizeY));
  printf("GetDetector() OK, sizeX=%d, sizeY=%d\n", sizeX, sizeY);
  checkStatus(GetHeadModel(model));
  printf("GetHeadModel() OK, model=%s\n", model);
  checkStatus(SetReadMode(4));
  printf("SetReadMode(4) OK\n");
  checkStatus(SetImage(binX, binY, minX+1, minX+sizeX, minY+1, minY+sizeY));
  printf("SetImage OK\n");
  status = GetTemperatureF(&temperature);
  printf("GetTemperature OK, temperature=%f, status=%d\n", temperature, status);
  return 0;
}
Пример #18
0
void KVFAZIA::GetDetectorEvent(KVDetectorEvent* detev, TSeqCollection* signals)
{
   // First step in event reconstruction based on current status of detectors in array.
   // Fills the given KVDetectorEvent with the list of all groups which have fired.
   // i.e. loop over all groups of the array and test whether KVGroup::Fired() returns true or false.
   //
   // If the list of fired acquisition parameters 'signals' is given, KVMultiDetArray::GetDetectorEvent
   // is called
   //

   if (signals) {
      // list of fired acquisition parameters given
      TIter next_par(signals);

      KVSignal* par = 0;
      KVDetector* det = 0;
      KVGroup* grp = 0;
      while ((par = (KVSignal*)next_par())) {
         if (!(par->GetN() > 0))
            Info("GetDetectorEvent", "%s empty", par->GetName());
         par->DeduceFromName();
         if ((det = GetDetector(par->GetDetectorName()))) {
            ((KVFAZIADetector*)det)->SetSignal(par, par->GetType());
            if ((!(((KVFAZIADetector*)det)->GetSignal(par->GetType())->GetN() > 0)))
               Warning("Error", "%s %s empty signal is returned", det->GetName(), par->GetType());
            if ((grp = det->GetGroup())  && !detev->GetGroups()->FindObject(grp)) {
               detev->AddGroup(grp);
            }
         } else {
            Error("GetDetectedEvent", "Unknown detector %s !!!", par->GetDetectorName());
         }
      }
   } else {
      KVMultiDetArray::GetDetectorEvent(detev, 0);
   }

}
Пример #19
0
void Features::Detect(const Mat& image, vector<cv::KeyPoint>& keys) const {
   cv::FeatureDetector* detector = GetDetector(this->flag);
   detector->detect(image, keys);
}
Пример #20
0
/* Detection is for single scale detection
   Input:
           1. im: A grayscale image in height x width.
           2. ext: The pre-defined HOG extractor.
           3. threshold: The constant threshold to control the prediction.
   Output:
           1. bbox: The predicted bounding boxes in this format (n x 5 matrix):
                                    x11 y11 x12 y12 s1
                                    ... ... ... ... ...
                                    xi1 yi1 xi2 yi2 si
                                    ... ... ... ... ...
                                    xn1 yn1 xn2 yn2 sn
                    where n is the number of bounding boxes. For the ith 
                    bounding box, (xi1,yi1) and (xi2, yi2) correspond to its
                    top-left and bottom-right coordinates, and si is the score
                    of convolution. Please note that these coordinates are
                    in the input image im.
*/
Mat Detector::Detection(const Mat& im, HOGExtractor& ext, const float threshold) {

	/* TODO 4: 
       Obtain the HOG descriptor of the input im. And then convolute the linear
	   detector on the HOG descriptor. You may put the score of convolution in 
	   the structure "convolutionScore".
	*/
	Mat HOGDes = ext.ExtractHOG(im);
	Mat convolutionScore(HOGDes.size[0], HOGDes.size[1], CV_32FC1, Scalar(0));

	// Begin TODO 4
	Mat detector = GetDetector();
	vector<cv::Mat> channels_HOGDes(36);
	vector<cv::Mat> channels_detector(36);

	split(HOGDes, channels_HOGDes);
	split(detector, channels_detector);

	vector<cv::Mat>::iterator iter1;
	vector<cv::Mat>::iterator iter2;
	for (iter1 = channels_HOGDes.begin(), iter2 = channels_detector.begin();
		iter1 != channels_HOGDes.end(),iter2!=channels_detector.end(); iter1++, iter2++)
	{
		Mat t_res(HOGDes.size[0], HOGDes.size[1], CV_32FC1, Scalar(0));
		filter2D( (*iter1), t_res, (*iter1).depth(), (*iter2) );
		convolutionScore += t_res;
	}
//	cout << "HoGsize= " << HOGDes.size[0] << ", " << HOGDes.size[1] << endl;
//	cout << "Detectorsize= " << detector.size[0] << ", " << detector.size[1] << endl;
/*	for (int i; i < HOGDes.size[0]; i++)
	{
		for (int j; j < HOGDes.size[0]; j++)
		{
			cout << convolutionScore.at<float>(i,j) << ", ";
		}
		cout << endl;
	}
	cout << endl;*/
	// End TODO 4
	
	/* TODO 5: 
       Select out those positions where the score is above the threshold. Here,
	   the positions are in ConvolutionScore. To output the coordinates of the
	   bounding boxes, please remember to recover the positions to those in the
	   input image. Please put the predicted bounding boxes and their scores in
	   the below structure "bbox".
	*/
	Mat bbox;
	
	// Begin TODO 5
	float cells = ext.GetCells();
	float blocks = ext.GetBlocks();
	float maxScore = -5.0;
	for ( int i = 0; i < convolutionScore.size[0]; i++ )
	{
		for ( int j = 0; j < convolutionScore.size[1]; j++ )
		{
			if (convolutionScore.at<float>(i, j)>maxScore)
			{
				maxScore = convolutionScore.at<float>(i, j);
			}
			if (convolutionScore.at<float>(i, j) > threshold)
			{
				float x1, y1, x2, y2, score;
				score = convolutionScore.at<float>(i, j);
				x1 = (int)((float)i - ((float)detector.size[0] / 2)+0.5) * cells;
				y1 = (int)((float)j - ((float)detector.size[1] / 2) + 0.5) * cells;
				x2 = (int)((float)i + ((float)detector.size[0] / 2) + 0.5) * cells;
				y2 = (int)((float)j + ((float)detector.size[1] / 2) + 0.5) * cells;
				Mat t_bbox = (Mat_<float>(1, 5) << x1, y1, x2, y2, score);

				if (bbox.size[0]!=0)
				{
					vconcat(bbox, t_bbox, bbox);
				}
				else
				{
					bbox = t_bbox;	
					//bbox = Mat(t_bbox);
				}
			}
		}
	}
	cout << "Max Score = " << maxScore << endl;
	// End TODO 5
//	cout << "Here bbox = " <<bbox.rows<<", "<<bbox.cols<< endl;
	return bbox;
}
Пример #21
0
Double_t KVIDChIoSi_e475s::GetIDMapY(Option_t *)
{
   //Y coordinate for ChIo-Si identification is chio pedestal-corrected 'PG' channel
   //return  GetDetector(1)->GetACQData("PG") - GetDetector(1)->GetPedestal("PG");
	return GetDetector(1)->GetEnergy();
}
Пример #22
0
void AngularCorrelationSelector::FillHistograms() {
	//without addback
	for(auto g1 = 0; g1 < fGrif->GetMultiplicity(); ++g1) {
		auto grif1 = fGrif->GetGriffinHit(g1);
		//check for coincident betas
		bool coincBeta = false;
		for(auto s = 0; s < fScep->GetMultiplicity(); ++s) {
			auto scep = fScep->GetSceptarHit(s);
			if(!coincBeta && gbLow <= grif1->GetTime()-scep->GetTime() && grif1->GetTime()-scep->GetTime() <= gbHigh) coincBeta = true;
			fH1["betaGammaTiming"]->Fill(scep->GetTime()-grif1->GetTime());
			fH2["betaGammaHP"]->Fill(scep->GetDetector(), grif1->GetArrayNumber());
		}
		fH1["gammaEnergy"]->Fill(grif1->GetEnergy());
		if(coincBeta) fH1["gammaEnergyBeta"]->Fill(grif1->GetEnergy());
		for(auto g2 = 0; g2 < fGrif->GetMultiplicity(); ++g2) {
			if(g1 == g2) continue;
			auto grif2 = fGrif->GetGriffinHit(g2);
			double angle = grif1->GetPosition().Angle(grif2->GetPosition())*180./TMath::Pi();
			if(angle < 0.0001) continue;
			auto angleIndex = fAngleMap.lower_bound(angle-0.0005);
			double ggTime = TMath::Abs(grif1->GetTime()-grif2->GetTime());
			fH1["gammaGammaTiming"]->Fill(ggTime);
			fH2["gammaGammaHP"]->Fill(grif1->GetArrayNumber(), grif2->GetArrayNumber());

			if(ggTime < ggHigh) {
				fH2["gammaGamma"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("gammaGamma%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				if(coincBeta) {
					fH2["gammaGammaBeta"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
					fH2[Form("gammaGammaBeta%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				}
			} else if(bgLow < ggTime && ggTime < bgHigh) {
				fH2["gammaGammaBG"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("gammaGammaBG%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				if(coincBeta) {
					fH2["gammaGammaBetaBG"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
					fH2[Form("gammaGammaBetaBG%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				}
			}
		}
		//event mixing, we use the last event as second griffin
		for(auto g2 = 0; g2 < fLastGrif.GetMultiplicity(); ++g2) {
			if(g1 == g2) continue;
			auto grif2 = fLastGrif.GetGriffinHit(g2);
			double angle = grif1->GetPosition().Angle(grif2->GetPosition())*180./TMath::Pi();
			if(angle < 0.0001) continue;
			auto angleIndex = fAngleMap.lower_bound(angle-0.0005);
			double ggTime = TMath::Abs(grif1->GetTime()-grif2->GetTime());
			fH2["gammaGammaHPMixed"]->Fill(grif1->GetArrayNumber(), grif2->GetArrayNumber());

			fH2["gammaGammaMixed"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			fH2[Form("gammaGammaMixed%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			if(coincBeta) {
				fH2["gammaGammaBetaMixed"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("gammaGammaBetaMixed%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			}
		}
	}
	//with addback
	for(auto g1 = 0; g1 < fGrif->GetAddbackMultiplicity(); ++g1) {
		auto grif1 = fGrif->GetAddbackHit(g1);
		//check for coincident betas
		bool coincBeta = false;
		for(auto s = 0; s < fScep->GetMultiplicity(); ++s) {
			auto scep = fScep->GetSceptarHit(s);
			if(!coincBeta && gbLow <= grif1->GetTime()-scep->GetTime() && grif1->GetTime()-scep->GetTime() <= gbHigh) coincBeta = true;
			fH1["betaAddbackTiming"]->Fill(scep->GetTime()-grif1->GetTime());
			fH2["betaAddbackHP"]->Fill(scep->GetDetector(), grif1->GetArrayNumber());
		}
		fH1["addbackEnergy"]->Fill(grif1->GetEnergy());
		if(coincBeta) fH1["addbackEnergyBeta"]->Fill(grif1->GetEnergy());
		for(auto g2 = 0; g2 < fGrif->GetAddbackMultiplicity(); ++g2) {
			if(g1 == g2) continue;
			auto grif2 = fGrif->GetAddbackHit(g2);
			double angle = grif1->GetPosition().Angle(grif2->GetPosition())*180./TMath::Pi();
			if(angle < 0.0001) continue;
			auto angleIndex = fAngleMapAddback.lower_bound(angle-0.0005);
			double ggTime = TMath::Abs(grif1->GetTime()-grif2->GetTime());
			fH1["addbackAddbackTiming"]->Fill(ggTime);
			fH2["addbackAddbackHP"]->Fill(grif1->GetArrayNumber(), grif2->GetArrayNumber());

			if(ggTime < ggHigh) {
				fH2["addbackAddback"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("addbackAddback%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				if(coincBeta) {
					fH2["addbackAddbackBeta"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
					fH2[Form("addbackAddbackBeta%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				}
			} else if(bgLow < ggTime && ggTime < bgHigh) {
				fH2["addbackAddbackBG"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("addbackAddbackBG%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				if(coincBeta) {
					fH2["addbackAddbackBetaBG"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
					fH2[Form("addbackAddbackBetaBG%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				}
			}
		}
		//event mixing, we use the last event as second griffin
		for(auto g2 = 0; g2 < fLastGrif.GetAddbackMultiplicity(); ++g2) {
			if(g1 == g2) continue;
			auto grif2 = fLastGrif.GetAddbackHit(g2);
			double angle = grif1->GetPosition().Angle(grif2->GetPosition())*180./TMath::Pi();
			if(angle < 0.0001) continue;
			auto angleIndex = fAngleMapAddback.lower_bound(angle-0.0005);
			double ggTime = TMath::Abs(grif1->GetTime()-grif2->GetTime());
			fH2["addbackAddbackHPMixed"]->Fill(grif1->GetArrayNumber(), grif2->GetArrayNumber());

			fH2["addbackAddbackMixed"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			fH2[Form("addbackAddbackMixed%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			if(coincBeta) {
				fH2["addbackAddbackBetaMixed"]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
				fH2[Form("addbackAddbackBetaMixed%d", angleIndex->second)]->Fill(grif1->GetEnergy(), grif2->GetEnergy());
			}
		}
	}

	//update "last" event
	fLastGrif = *fGrif;
	fLastScep = *fScep;
}
Пример #23
0
int main(int argc, char **argv)
{
	int	status;
	int	bitdepth;
	int	width, height;
	int	min, max;
	int	i, j, numgains;
	float	gain;
	int	num_ad;
	int	num_vspeeds;
	int	num_hspeeds;
	float	speed;
	AndorCapabilities caps;
	at_32 lNumCameras;
	at_32 lCameraHandle;
	int	start_n, stop_n;
	int	npix;

	/* Check command line */

	npix = 90;

	if (argc > 1) sscanf(argv[1], "%d", &npix);
	
	/* FIRST, FIND OUT WHAT WE NEED TO KNOW ABOUT THIS CAMERA. */

	printf("Initializing Andor Camera.\n");

	/* How many cameras are connected */

	printf("GetAvailableCameras = %d\n", GetAvailableCameras(&lNumCameras));
	if (lNumCameras == 1)
		printf("There is %d camera connected.\n", lNumCameras);
	else
		printf("There are %d cameras connected.\n", lNumCameras);

	if (lNumCameras <= 0) exit(0);

	/* Get the camera we are working with. */

	printf("GetCameraHandle = %d\n", GetCameraHandle(0, &lCameraHandle));

	printf("SetCurrentCamera = %d\n", SetCurrentCamera(lCameraHandle));

	/* Initialize the CCD */

	printf("Initialize = %d\n", Initialize("/usr/local/etc/andor"));

	/* Wait for this to happen */

	sleep(2);

	/* What Capabilities do we have? */

	caps.ulSize = sizeof(caps);
	printf("GetCapabilities = %d\n", GetCapabilities(&caps));

	if (caps.ulCameraType & AC_CAMERATYPE_IXON)
		printf("Camera is an iXon.\n");
	else
		printf("Camera is not an iXon.\n");

	if (caps.ulAcqModes & AC_ACQMODE_FRAMETRANSFER)
		printf("Frame transfer is available.\n");
	else
		printf("Frame transfer is not available.\n");

	if (caps.ulSetFunctions & AC_SETFUNCTION_CROPMODE)
		printf("Crop mode is available.\n");
	else
		printf("Crop mode is not available.\n");

	/* Find out what the width and height are */

	printf("GetDetector = %d\n", GetDetector(&width, &height));
	printf("Andor full size %dx%d.\n", width, height);

	/* What is the allowable temperature range? */

	printf("GetTemperatureRange = %d\n", GetTemperatureRange(&min, &max));
	printf("Andor temperature range is %d to %d C.\n", min, max);
	
	/* How many preamp gains do we have? */

	printf("GetNumberPreAmpGains = %d\n", GetNumberPreAmpGains(&numgains));
	printf("Andor number of preamp gains is %d.\n", numgains);

	/* Let's find out what these gains are */

	for (i=0; i<numgains; i++)
	{
		printf("GetPreAmpGain = %d\n", GetPreAmpGain(i, &gain));
		printf("Andor Preamp Gain %d is %f.\n", i, gain);
	}

	/* How many vertical speeds do we have? */

	printf("GetNumberVSSpeeds = %d\n", GetNumberVSSpeeds(&num_vspeeds));
	printf("Andor number of Vertical Speeds is %d.\n", num_vspeeds);

	/* Let's find out what these VSpeeds are */

	for (i=0; i<num_vspeeds; i++)
	{
		printf("GetVSSpeed = %d\n", GetVSSpeed(i, &speed));
		printf("Andor Vertical Speed %d is %.2f uS.\n",
				i, speed);
	}

	for(j = 0; j < 1; j++)
	{
	    if (j == 0)
		    printf("For EMCCD output:\n");
	    else
		    printf("For CCD output:\n");

	    /* How many horizontal speeds do we have? */

	    printf("GetNumberHSSpeeds = %d\n",
		GetNumberHSSpeeds(0, j, &num_hspeeds));
	    printf("Andor number of Horizontal Speeds is %d.\n", num_hspeeds);

	    /* Let's find out what these speeds are */

	    for (i=0; i<num_hspeeds; i++)
	    {
		printf("GetHSSpeed = %d\n", GetHSSpeed(0, j, i, &speed));
		printf("Andor Horizontal Speed %d is %.2f MHz.\n", i, speed);
	    }

	}

	/* What is the range of gain settings - This is always wrong  */

	printf("GetEMGainRange = %d\n", GetEMGainRange(&min, &max));
	printf("Andor EM Gain range is %d to %d.\n", min, max);

	/* How many AD channels are there? */

	printf("GetNumberADChannels = %d\n", GetNumberADChannels(&num_ad));
	printf("Number of AD channels = %d\n", num_ad);

	/* What are the bit depths? */

	for(i=0; i < num_ad; i++)
	{
	    printf("GetBitDepth = %d\n", GetBitDepth(i, &bitdepth));
	    printf("AD channel %d has bit depth %d\n", i, bitdepth);
	}

	/* NOW WE START TO SET THINGS UP THE WAY WE WANT THEM */

	/* Turn on Cameralink mode */

	printf("SetCameraLinkMode = %d\n", SetCameraLinkMode(1));

	/* Put us in Frame Transfer Mode */

	printf( "Turning on Frame Transfer Mode.\n");
	printf("SetFrameTransferMode = %d\n", SetFrameTransferMode(1));

        /* Set output amplifier to EMCCD */

	printf("SetOutputAmplifier = %d\n", SetOutputAmplifier(0));

	/* Turn on advanced EM settings */

	printf("SetEMAdvanced = %d\n", SetEMAdvanced(1));

	/* Let's see if that worked... we should get 1000 as maximum */

	printf("GetEMGainRange = %d\n", GetEMGainRange(&min, &max));
	printf("Andor EM Gain range is %d to %d.\n", min, max);

	/* Set EM gain */

	printf("SetEMCCDGain = %d\n", SetEMCCDGain(300));

	/* Set our horizontal speed to the desired one. */

        printf("SetHSSpeed = %d\n", SetHSSpeed(0, 0));

	/* Set our vertical speed to the desired one. */

        printf("SetVSSpeed = %d\n", SetVSSpeed(0));

	/* Set our gain to the desired one. */

	printf("SetPreAmpGain = %d\n", SetPreAmpGain(2));

        /* Setup the read mode. I suspect this is the problem */

        printf("SetReadMode = %d\n", SetReadMode(4));

	/* Try to get frames like this */

        printf("SetAcquisitionMode = %d\n", SetAcquisitionMode(5));
	printf("PrepareAcquisition = %d\n", PrepareAcquisition());
	printf("StartAcquisition %d\n", StartAcquisition());
	sleep(1);
	printf("AbortAcquisition %d\n", AbortAcquisition());

	/* This sequence seemed to work with the server */

        //printf("SetHSSpeed = %d\n", SetHSSpeed(0, 1));

	/* DO we get the right gain range now? */

	printf("GetEMGainRange = %d\n", GetEMGainRange(&min, &max));
	printf("Andor EM Gain range is %d to %d.\n", min, max);

        /* We wish to use Cropped mode */

        printf("SetIsolatedCropMode = %d\n",
		SetIsolatedCropMode(1,npix,npix,1,1));

        /* Set the image to read the full area of cropped region */

        printf("SetImage = %d\n", SetImage(1, 1, 1, npix, 1, npix));

        /* Set exposure time to 1mS */

        printf("SetExposureTime = %d\n", SetExposureTime(0.001));

	/* Set Kinetic Cycle time to the smallest possible value */

	printf("SetKineticCycleTime = %d\n",SetKineticCycleTime(0.0));

	/* OK, let's see what the frame rate is */

        printf("SetAcquisitionMode = %d\n", SetAcquisitionMode(5));
	printf("StartAcquisition %d\n", StartAcquisition());
	sleep(1);
	printf("GetTotalNumberImagesAcquired = %d\n",
			GetTotalNumberImagesAcquired(&start_n));
	sleep(5);
	printf("GetTotalNumberImagesAcquired = %d\n",
			GetTotalNumberImagesAcquired(&stop_n));
	printf("Frame rate seems to be %.2f Hz\n",
			(double)(stop_n - start_n)/5.0);
	printf("AbortAcquisition = %d\n",AbortAcquisition());


	/* Get one frame... it seems things work better after this */

	GetStatus(&status);
	while(status==DRV_ACQUIRING) GetStatus(&status);
	printf("SaveAsFITS %d\n", SaveAsFITS("./image.fit", 4));

	/* That is all */

	printf("ShutDown = %d\n", ShutDown());

	exit(0);
}
Пример #24
0
//------------------------------------------------------------------------------
//	FUNCTION NAME:	InitializeCamera()
//
//  RETURNS:				If the function terminates before entering the message loop,
//      						return FALSE.
//    							Otherwise, return the WPARAM value sent by the WM_QUIT
//									message.
//
//  LAST MODIFIED:	PMcK	11/11/98
//
//  DESCRIPTION:		calls initialization function, processes message loop
//
//                  Windows recognizes this function by name as the initial
//									entry point for the program.  This function calls the
//									application initialization routine, if no other instance of
//									the program is running, and always calls the instance
//									initialization routine.  It then executes a	message
//									retrieval and dispatch loop that is the top-level control
//    							structure for the remainder of execution.  The loop is
//									terminated when a WM_QUIT  message is received, at which
//									time this function exits the application instance by
//									returning the value passed by PostQuitMessage().
//
//    							If the function must abort before entering the message loop,
//									it returns the conventional value NULL.
//
//
//	ARGUMENTS: 			hInstance - The handle to the instance of this application
//									that is currently being executed.
//
//    							hPrevInstance - The handle to the instance of this
//									application that was last executed.  If this is the only
//									instance of this application executing, hPrevInstance is
//									NULL. In Win32 applications, this parameter is always NULL.
//
//    							lpCmdLine - A pointer to a null terminated string specifying
//									the command line of the application.
//
//    							nCmdShow - Specifies how the main window is to be diplayed.
//------------------------------------------------------------------------------
bool ANDOR885_Camera::InitializeCamera()
{
	AndorCapabilities	caps;
	char 				aBuffer[256];
	int					errorValue;
	bool				errorFlag = false;
//	int 				test,test2; //need to pause while camera initializes

	float				speed, STemp, gain;
	int					iSpeed, nAD, nAmp, nPreAmp, index, IsPreAmpAvailable;

	int i;


	caps.ulSize = sizeof(AndorCapabilities);

	long numCameras;
	GetAvailableCameras(&numCameras);

    GetCurrentDirectoryA(256,aBuffer);// Look in current working directory
                                    // for driver files. Note: had to override usual mapping of GetCurrentDirectory to
									// GetCurrentDirectoryW because of mismatch of argument types.

    errorValue=Initialize(aBuffer);  // Initialize driver in current directory
	printError(errorValue, "Initialize error", &errorFlag, ANDOR_ERROR);
	if (errorFlag)
		return true;

    // Get camera capabilities
    errorValue=GetCapabilities(&caps);
	printError(errorValue, "Get Andor Capabilities information Error", &errorFlag, ANDOR_ERROR);

    // Get Head Model
    errorValue=GetHeadModel(model);
	printError(errorValue, "Get Head Model information Error", &errorFlag, ANDOR_ERROR);

    // Get detector information
    errorValue=GetDetector(&imageWidth,&imageHeight);
	printError(errorValue, "Get Detector information Error", &errorFlag, ANDOR_ERROR);

	// Set frame transfer mode
	errorValue=SetFrameTransferMode((frameTransfer == ANDOR_ON) ? 1 : 0);
	printError(errorValue, "Set Frame Transfer Mode Error", &errorFlag, ANDOR_ERROR);

    // Set acquisition mode to required setting specified in xxxxWndw.c
    errorValue=SetAcquisitionMode(acquisitionMode);
	printError(errorValue, "Set Acquisition Mode Error", &errorFlag, ANDOR_ERROR);

	
	if(caps.ulGetFunctions > 32)
	{
		GetEMCCDGain(&EMCCDGain);
	}

	if(readMode == READMODE_IMAGE) {
    	// This function only needs to be called when acquiring an image. It sets
		// the horizontal and vertical binning and the area of the image to be
		// captured. In this example it is set to 1x1 binning and is acquiring the
		// whole image
  		SetImage(1,1,1,imageWidth,1,imageHeight);
	}

    // Set read mode to required setting specified in xxxxWndw.c
    errorValue=SetReadMode(readMode);
	printError(errorValue, "Set Read Mode Error", &errorFlag, ANDOR_ERROR);

    // Set Vertical speed to max
/*    STemp = 0;
    VSnumber = 0;
    GetNumberVSSpeeds(&index);
    for(iSpeed=0; iSpeed<index; iSpeed++){
      GetVSSpeed(iSpeed, &speed);
      if(speed > STemp){
        STemp = speed;
        VSnumber = iSpeed;
      }
    }
    errorValue=SetVSSpeed(VSnumber);
	printError(errorValue, "Set Vertical Speed Error", &errorFlag, ANDOR_ERROR);
*/
	
	if (!notDestructed){
		STemp = 0;
		GetNumberVSSpeeds(&index);
		for(iSpeed=0; iSpeed < index; iSpeed++){
			GetVSSpeed(iSpeed, &speed);
			verticalShiftSpeed_t.choices[iSpeed] = STI::Utils::valueToString(speed);
			if(speed > STemp){
				STemp = speed;
				verticalShiftSpeed = iSpeed;
			}
		}
		verticalShiftSpeed_t.initial = (--verticalShiftSpeed_t.choices.end())->second;
	}
    errorValue = SetVSSpeed(verticalShiftSpeed);
	printError(errorValue, "Set Vertical Speed Error", &errorFlag, ANDOR_ERROR);

	/* Set Vertical Clock Voltage; 
		note: only the fastest vertical shift speeds will benefit from the higher clock voltage;
			  increasing clock voltage adds noise.
	*/
	if (!notDestructed) {
		index = 0;
		errorValue = GetNumberVSAmplitudes(&index);
		if (errorValue == DRV_SUCCESS) {
			for (i = 0; i < index; i++){
				if (i == 0){
					verticalClockVoltage_t.choices[i] = "Normal";
				} else {
					verticalClockVoltage_t.choices[i] = STI::Utils::valueToString(i);
				}
			}
			verticalClockVoltage_t.initial = (verticalClockVoltage_t.choices.begin())->second;
		}
	}
	errorValue = SetVSAmplitude(0);
	printError(errorValue, "Set Vertical Clock Voltage Error", &errorFlag, ANDOR_ERROR);

    // Set Horizontal Speed to max and check bit depth
	//(scan over all possible AD channels; although, the 885 has only one 14-bit channel)
		STemp = 0;
	//    HSnumber = 0;
		ADnumber = 0;
	if (!notDestructed) {
		errorValue = GetNumberADChannels(&nAD);
		if (errorValue != DRV_SUCCESS){
		  std::cerr << "Get number AD Channel Error\n";
		  errorFlag = true;
		}
		else if (nAD != 1) {
			std::cerr << "Expect 1 AD channel for this camera. The following code will miss channels\n";
			errorFlag = true;
		}
		else {
			errorValue = GetNumberHSSpeeds(0, 0, &index);
			if(errorValue == DRV_SUCCESS){
				for (iSpeed = 0; iSpeed < index; iSpeed++) {
				  GetHSSpeed(0, 0, iSpeed, &speed);
				  horizontalShiftSpeed_t.choices[iSpeed] = STI::Utils::valueToString(speed);
				  if(speed < STemp){
					STemp = speed;
					horizontalShiftSpeed = iSpeed;
				  }
				}
				horizontalShiftSpeed_t.initial = horizontalShiftSpeed_t.choices.find(horizontalShiftSpeed)->second;
			}
			//getBitDepth
			if (DRV_SUCCESS != GetBitDepth(0, &bitDepth))
				return true;
		}

		errorValue = GetNumberAmp(&nAmp);
		printError(errorValue, "Get Number Amplifiers Error", &errorFlag, ANDOR_ERROR);

		errorValue = GetNumberPreAmpGains(&nPreAmp);
		printError(errorValue, "Get Number Preamplifiers Error", &errorFlag, ANDOR_ERROR);

		if (nAmp == 1 && nAD == 1) {
			for (i = 0; i < nPreAmp; i++) {
				errorValue = GetPreAmpGain(i, &gain);
				errorValue = IsPreAmpGainAvailable(0,0,horizontalShiftSpeed,i,&IsPreAmpAvailable);
				if (IsPreAmpAvailable == 1) {
					preAmpGain_t.choices[i] = STI::Utils::valueToString(gain);
				}
			}
			if (!preAmpGain_t.choices.empty()) {
				preAmpGain = preAmpGain_t.choices.begin()->first;
				//preAmpGainPos = 0;
				preAmpGain_t.initial = (preAmpGain_t.choices.begin())->second; // set the initial condition for the preamplifier gain
				errorValue = SetPreAmpGain(preAmpGain);
				printError(errorValue, "Set AD Channel Error", &errorFlag, ANDOR_ERROR);
			} else {
				std::cerr << "No gains available at this speed. Weird.";
				errorFlag = true;
			}
		} else {
			std::cerr << "Unexpected number of A/D's or output amps" << std::endl;
			std::cerr << "Expected A/D's:       1 \t Measured: " << nAD << std::endl;
			std::cerr << "Expected output Amps: 1 \t Measured: " << nAmp << std::endl;
			errorFlag = true;
		}
	}
	else {
		errorValue = SetPreAmpGain(preAmpGain);
		printError(errorValue, "Set AD Channel Error", &errorFlag, ANDOR_ERROR);
	}
	

    errorValue=SetADChannel(ADnumber);
	printError(errorValue, "Set AD Channel Error", &errorFlag, ANDOR_ERROR);


    errorValue=SetHSSpeed(0,horizontalShiftSpeed);
	printError(errorValue, "Set Horizontal Speed Error", &errorFlag, ANDOR_ERROR);

    if(errorFlag)
    	//MessageBox(GetActiveWindow(),aBuffer,"Error!",MB_OK); SMD
	    std::cerr<<aBuffer<<std::endl;


  // Wait for 2 seconds to allow MCD to calibrate fully before allowing an
  // acquisition to begin
//  test=GetTickCount();
//  do{
//  	test2=GetTickCount()-test;
//  }while(test2<2000);

	Sleep(2000);

	errorValue = SetExposureTime(exposureTime);
	printError(errorValue, "Exposure time error", &errorFlag, ANDOR_ERROR);

	// It is necessary to get the actual times as the system will calculate the
	// nearest possible time. eg if you set exposure time to be 0, the system
	// will use the closest value (around 0.01s)
	  GetAcquisitionTimings(&exposureTime,&accumulateTime,&kineticTime);
	  std::cerr << "Actual Exposure Time is " << exposureTime << " s.\n";

  // Set Shutter is made up of ttl level, shutter and open close time

  //Check Get open close time
	if(openTime==0)
		openTime=1;
	if(closeTime==0)
		closeTime=1;

	// Set shutter
	errorValue=SetShutter(ttl,shutterMode,closeTime,openTime);
	if(errorValue!=DRV_SUCCESS){
		std::cerr << "Shutter error\n";
		errorFlag = true;  
	}
	else
		std::cerr << "Shutter set to specifications\n";

	/*// Determine availability of trigger option and set trigger selection
	std::map<int,std::string>::iterator it;
	std::vector<int> triggerKeys;
	for (it = triggerMode_t.choices.begin(); it != triggerMode_t.choices.end(); it++)
	{
		errorValue = SetTriggerMode(it->first);
		if (errorValue != DRV_SUCCESS)
			triggerKeys.push_back(it->first);
	}
	for (int i = 0; i < triggerKeys.size(); i++)
		triggerMode_t.choices.erase(triggerKeys.at(i));

	if (triggerMode_t.choices.empty()) {
		std::cerr << "No triggerModes found" << std::endl;
		return true;
	}
	else if (triggerMode_t.choices.find(TRIGGERMODE_EXTERNAL_EXPOSURE) != 
		triggerMode_t.choices.end()) 
		triggerMode = TRIGGERMODE_EXTERNAL_EXPOSURE;
	else if (triggerMode_t.choices.find(TRIGGERMODE_EXTERNAL) != 
		triggerMode_t.choices.end())
		triggerMode = TRIGGERMODE_EXTERNAL;
	else
		triggerMode = triggerMode_t.choices.begin()->first;

	errorValue=SetTriggerMode(triggerMode);
	printError(errorValue, "Set Trigger Mode Error", &errorFlag, ANDOR_ERROR);
	triggerMode_t.initial = triggerMode_t.choices.find(triggerMode)->second;
*/

	// Determine availability of trigger option and set trigger selection
	std::map<int,std::string>::iterator it;
	std::vector<int> triggerKeys;
	for (it = triggerMode_t.choices.begin(); it != triggerMode_t.choices.end(); it++)
	{
		errorValue = SetTriggerMode(it->first);
		if (errorValue != DRV_SUCCESS)
			triggerKeys.push_back(it->first);
	}
	for (int i = 0; i < triggerKeys.size(); i++)
		triggerMode_t.choices.erase(triggerKeys.at(i));

	if (triggerMode_t.choices.empty()) {
		std::cerr << "No triggerModes found" << std::endl;
		return true;
	}
	else if (triggerMode_t.choices.find(TRIGGERMODE_EXTERNAL_EXPOSURE) != 
		triggerMode_t.choices.end()) 
		triggerMode = TRIGGERMODE_EXTERNAL_EXPOSURE;
	else if (triggerMode_t.choices.find(TRIGGERMODE_EXTERNAL) != 
		triggerMode_t.choices.end())
		triggerMode = TRIGGERMODE_EXTERNAL;
	else
		triggerMode = triggerMode_t.choices.begin()->first;

	errorValue=SetTriggerMode(triggerMode);
	printError(errorValue, "Set Trigger Mode Error", &errorFlag, ANDOR_ERROR);
	triggerMode_t.initial = triggerMode_t.choices.find(triggerMode)->second;


	errorValue = GetTemperatureRange(&minTemp, &maxTemp);
	if (errorValue != DRV_SUCCESS){
		std::cerr << "Error finding temperature range or camera is not on" << std::endl;
		errorFlag = true;
	}
	else {
		std::cerr << "Temperature must be between " << minTemp << " and " << maxTemp << std::endl;
		std::cerr << "Warning: Water cooling is required for temperatures < -58 deg C" << std::endl;

		//Set temperature
		if (coolerSetpt > maxTemp || coolerSetpt < minTemp) {
			std::cerr << "Chosen temperature out of range." << std::endl;
			if (coolerSetpt > maxTemp)
				coolerSetpt = maxTemp;
			else
				coolerSetpt = minTemp;
			std::cerr << "Resetting temp to nearest acceptable value " << std::endl;
		} 

		errorValue = SetTemperature(coolerSetpt);
		printError(errorValue, "Error setting cooler temperature", &errorFlag, ANDOR_ERROR);

		int i;
		errorValue = IsCoolerOn(&i);
		if (i == 0) {
			// if it's off and it's supposed to be on, turn it on
			if (coolerStat == ANDOR_ON) {
				std::cerr << "Turning on cooler." << std::endl;
				errorValue = CoolerON();
				printError(errorValue, "Error turning on cooler", &errorFlag, ANDOR_ERROR);
			}
			
		} else if (i == 1) {
			std::cerr << "Cooler is on." << std::endl;
			//if it's on and it's supposed to be off, turn it off
			if (coolerStat == ANDOR_OFF)
			{
				errorValue = CoolerOFF();
				printError(errorValue, "Error turning off cooler", &errorFlag, ANDOR_ERROR);
			} else {
				errorValue = GetTemperature(&i);
				switch(errorValue){
					case DRV_TEMP_STABILIZED:
						std::cerr << "Cooler temp has stabilized at " << i << " deg C" << std::endl;
						break;
					case DRV_TEMP_NOT_REACHED:
						std::cerr << "Cooler temp is " << i << " deg C" << std::endl;
						std::cerr << "Cooler setpoint has not been reached." << std::endl;
						std::cerr << "This may be because water cooling is required for setpoints < -58 deg C" << std::endl;
						std::cerr << "Either wait or try resetting cooler setpoint" << std::endl;
						break;
					case DRV_TEMP_DRIFT:
						std::cerr << "Cooler temp is " << i << " deg C" << std::endl;
						std::cerr << "Cooler temperature has drifted. Try resetting setpoint" << std::endl;
						break;
					case DRV_TEMP_NOT_STABILIZED:
						std::cerr << "Cooler temp is " << i << " deg C" << std::endl;
						std::cerr << "Temperature has been reached, but cooler has not stabilized" << std::endl;
						std::cerr << "Either wait or try resetting cooler setpoint" << std::endl;
						break;
					default:
						std::cerr << "Unrecognized error sequence. Camera may be off or acquiring" << std::endl;
						break;
				}
			}
		}
		
		
		if(!errorFlag){
			std::cerr << "Cooler temperature set to: " << coolerSetpt << std::endl;
		}
	
	}




	errorValue = SetSpool(0,0,NULL,10);  //Disable spooling
	printError(errorValue, "Spool mode error", &errorFlag, ANDOR_ERROR);

	// Returns the value from PostQuitMessage
	return errorFlag;
}